|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2000 Werner Trobin <trobin@kde.org>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <KoTemplates.h>
|
|
|
|
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqimage.h>
|
|
|
|
#include <tqprinter.h>
|
|
|
|
|
|
|
|
#include <kdesktopfile.h>
|
|
|
|
#include <ksimpleconfig.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tdeversion.h>
|
|
|
|
#include <kinstance.h>
|
|
|
|
#include <ksavefile.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <tdeio/netaccess.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
|
|
KoTemplate::KoTemplate(const TQString &name, const TQString &description, const TQString &file,
|
|
|
|
const TQString &picture, const TQString &fileName, const TQString &_measureSystem,
|
|
|
|
bool hidden, bool touched) :
|
|
|
|
m_name(name), m_descr(description), m_file(file), m_picture(picture), m_fileName(fileName),
|
|
|
|
m_hidden(hidden), m_touched(touched), m_cached(false), m_measureSystem(_measureSystem)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
const TQPixmap &KoTemplate::loadPicture( TDEInstance* instance ) {
|
|
|
|
|
|
|
|
if(m_cached)
|
|
|
|
return m_pixmap;
|
|
|
|
m_cached=true;
|
|
|
|
if ( m_picture[ 0 ] == '/' )
|
|
|
|
{
|
|
|
|
// ### TODO: use the class KoPicture instead of TQImage to support non-image pictures
|
|
|
|
TQImage img( m_picture );
|
|
|
|
if (img.isNull()) {
|
|
|
|
kdWarning() << "Couldn't find icon " << m_picture << endl;
|
|
|
|
m_pixmap=TQPixmap();
|
|
|
|
return m_pixmap;
|
|
|
|
}
|
|
|
|
const int maxHeightWidth = 128; // ### TODO: some people would surely like to have 128x128
|
|
|
|
if (img.width() > maxHeightWidth || img.height() > maxHeightWidth) {
|
|
|
|
img = img.smoothScale( maxHeightWidth, maxHeightWidth, TQ_ScaleMax );
|
|
|
|
}
|
|
|
|
m_pixmap.convertFromImage(img);
|
|
|
|
return m_pixmap;
|
|
|
|
} else { // relative path
|
|
|
|
m_pixmap = instance->iconLoader()->loadIcon( m_picture, KIcon::Desktop, 128 );
|
|
|
|
return m_pixmap;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
KoTemplateGroup::KoTemplateGroup(const TQString &name, const TQString &dir,
|
|
|
|
int _sortingWeight, bool touched) :
|
|
|
|
m_name(name), m_touched(touched), m_sortingWeight(_sortingWeight)
|
|
|
|
{
|
|
|
|
m_dirs.append(dir);
|
|
|
|
m_templates.setAutoDelete(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KoTemplateGroup::isHidden() const {
|
|
|
|
|
|
|
|
TQPtrListIterator<KoTemplate> it(m_templates);
|
|
|
|
bool hidden=true;
|
|
|
|
while(it.current()!=0L && hidden) {
|
|
|
|
hidden=it.current()->isHidden();
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
return hidden;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoTemplateGroup::setHidden(bool hidden) const {
|
|
|
|
|
|
|
|
TQPtrListIterator<KoTemplate> it(m_templates);
|
|
|
|
for( ; it.current()!=0L; ++it)
|
|
|
|
it.current()->setHidden(hidden);
|
|
|
|
m_touched=true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KoTemplateGroup::add(KoTemplate *t, bool force, bool touch) {
|
|
|
|
|
|
|
|
KoTemplate *myTemplate=find(t->name());
|
|
|
|
if(myTemplate==0L) {
|
|
|
|
m_templates.append(t);
|
|
|
|
m_touched=touch;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if(myTemplate && force) {
|
|
|
|
//kdDebug() << "removing :" << myTemplate->fileName() << endl;
|
|
|
|
TQFile::remove( myTemplate->fileName() );
|
|
|
|
TQFile::remove( myTemplate->picture() );
|
|
|
|
TQFile::remove( myTemplate->file() );
|
|
|
|
m_templates.removeRef(myTemplate);
|
|
|
|
m_templates.append(t);
|
|
|
|
m_touched=touch;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
KoTemplate *KoTemplateGroup::find(const TQString &name) const {
|
|
|
|
|
|
|
|
TQPtrListIterator<KoTemplate> it(m_templates);
|
|
|
|
while(it.current() && it.current()->name()!=name)
|
|
|
|
++it;
|
|
|
|
return it.current();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
KoTemplateTree::KoTemplateTree(const TQCString &templateType,
|
|
|
|
TDEInstance *instance, bool readTree) :
|
|
|
|
m_templateType(templateType), m_instance(instance), m_defaultGroup(0L),
|
|
|
|
m_defaultTemplate(0L) {
|
|
|
|
|
|
|
|
m_groups.setAutoDelete(true);
|
|
|
|
if(readTree)
|
|
|
|
readTemplateTree();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoTemplateTree::readTemplateTree() {
|
|
|
|
|
|
|
|
readGroups();
|
|
|
|
readTemplates();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoTemplateTree::writeTemplateTree() {
|
|
|
|
TQString localDir=m_instance->dirs()->saveLocation(m_templateType);
|
|
|
|
|
|
|
|
for(KoTemplateGroup *group=m_groups.first(); group!=0L; group=m_groups.next()) {
|
|
|
|
//kdDebug() << "---------------------------------" << endl;
|
|
|
|
//kdDebug() << "group: " << group->name() << endl;
|
|
|
|
|
|
|
|
bool touched=false;
|
|
|
|
for(KoTemplate *t=group->first(); t!=0L && !touched && !group->touched(); t=group->next())
|
|
|
|
touched=t->touched();
|
|
|
|
|
|
|
|
if(group->touched() || touched) {
|
|
|
|
//kdDebug() << "touched" << endl;
|
|
|
|
if(!group->isHidden()) {
|
|
|
|
//kdDebug() << "not hidden" << endl;
|
|
|
|
TDEStandardDirs::makeDir(localDir+group->name()); // create the local group dir
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
//kdDebug() << "hidden" << endl;
|
|
|
|
if(group->dirs().count()==1 && !group->dirs().grep(localDir).isEmpty()) {
|
|
|
|
//kdDebug() << "local only" << endl;
|
|
|
|
TDEIO::NetAccess::del(group->dirs().first(), 0);
|
|
|
|
//kdDebug() << "removing: " << group->dirs().first() << endl;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
//kdDebug() << "global" << endl;
|
|
|
|
TDEStandardDirs::makeDir(localDir+group->name());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(KoTemplate *t=group->first(); t!=0L; t=group->next()) {
|
|
|
|
if(t->touched()) {
|
|
|
|
//kdDebug() << "++template: " << t->name() << endl;
|
|
|
|
writeTemplate(t, group, localDir);
|
|
|
|
}
|
|
|
|
if(t->isHidden() && t->touched() ) {
|
|
|
|
//kdDebug() << "+++ delete local template ##############" << endl;
|
|
|
|
writeTemplate(t, group, localDir);
|
|
|
|
TQFile::remove(t->file());
|
|
|
|
TQFile::remove(t->picture());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoTemplateTree::add(KoTemplateGroup *g) {
|
|
|
|
|
|
|
|
KoTemplateGroup *group=find(g->name());
|
|
|
|
if(group==0L)
|
|
|
|
m_groups.append(g);
|
|
|
|
else
|
|
|
|
group->addDir(g->dirs().first()); // "...there can be only one..." (Queen)
|
|
|
|
}
|
|
|
|
|
|
|
|
KoTemplateGroup *KoTemplateTree::find(const TQString &name) const {
|
|
|
|
|
|
|
|
TQPtrListIterator<KoTemplateGroup> it(m_groups);
|
|
|
|
while(it.current() && it.current()->name()!=name)
|
|
|
|
++it;
|
|
|
|
return it.current();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoTemplateTree::readGroups() {
|
|
|
|
|
|
|
|
TQStringList dirs = m_instance->dirs()->resourceDirs(m_templateType);
|
|
|
|
for(TQStringList::ConstIterator it=dirs.begin(); it!=dirs.end(); ++it) {
|
|
|
|
//kdDebug() << "dir: " << *it << endl;
|
|
|
|
TQDir dir(*it);
|
|
|
|
// avoid the annoying warning
|
|
|
|
if(!dir.exists())
|
|
|
|
continue;
|
|
|
|
dir.setFilter(TQDir::Dirs);
|
|
|
|
TQStringList templateDirs=dir.entryList();
|
|
|
|
for(TQStringList::ConstIterator tdirIt=templateDirs.begin(); tdirIt!=templateDirs.end(); ++tdirIt) {
|
|
|
|
if(*tdirIt=="." || *tdirIt=="..") // we don't want to check those dirs :)
|
|
|
|
continue;
|
|
|
|
TQDir templateDir(*it+*tdirIt);
|
|
|
|
TQString name=*tdirIt;
|
|
|
|
TQString defaultTab;
|
|
|
|
int sortingWeight = 1000;
|
|
|
|
if(templateDir.exists(".directory")) {
|
|
|
|
KSimpleConfig config(templateDir.absPath()+"/.directory", true);
|
|
|
|
config.setDesktopGroup();
|
|
|
|
name=config.readEntry("Name");
|
|
|
|
defaultTab=config.readEntry("X-TDE-DefaultTab");
|
|
|
|
sortingWeight=config.readNumEntry("X-TDE-SortingWeight", 1000);
|
|
|
|
//kdDebug() << "name: " << name <<endl;
|
|
|
|
}
|
|
|
|
KoTemplateGroup *g=new KoTemplateGroup(name, *it+*tdirIt+TQChar('/'), sortingWeight);
|
|
|
|
add(g);
|
|
|
|
if(defaultTab=="true")
|
|
|
|
m_defaultGroup=g;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoTemplateTree::readTemplates() {
|
|
|
|
TQString dontShow = "imperial";
|
|
|
|
|
|
|
|
if(TDEGlobal::locale()->pageSize() == TQPrinter::Letter) {
|
|
|
|
dontShow = "metric";
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPtrListIterator<KoTemplateGroup> groupIt(m_groups);
|
|
|
|
for( ; groupIt.current()!=0L; ++groupIt) {
|
|
|
|
TQStringList dirs=groupIt.current()->dirs();
|
|
|
|
for(TQStringList::ConstIterator it=dirs.begin(); it!=dirs.end(); ++it) {
|
|
|
|
TQDir d(*it);
|
|
|
|
if( !d.exists() )
|
|
|
|
continue;
|
|
|
|
TQStringList files=d.entryList( TQDir::Files | TQDir::Readable, TQDir::Name );
|
|
|
|
for(unsigned int i=0; i<files.count(); ++i) {
|
|
|
|
TQString filePath = *it + files[i];
|
|
|
|
//kdDebug() << "filePath: " << filePath << endl;
|
|
|
|
TQString icon;
|
|
|
|
TQString text;
|
|
|
|
TQString description;
|
|
|
|
TQString hidden_str;
|
|
|
|
TQString fileName;
|
|
|
|
bool hidden=false;
|
|
|
|
bool defaultTemplate = false;
|
|
|
|
TQString templatePath;
|
|
|
|
TQString measureSystem;
|
|
|
|
// If a desktop file, then read the name from it.
|
|
|
|
// Otherwise (or if no name in it?) use file name
|
|
|
|
if (KDesktopFile::isDesktopFile(filePath)) {
|
|
|
|
KSimpleConfig config(filePath, true);
|
|
|
|
config.setDesktopGroup();
|
|
|
|
if (config.readEntry("Type")=="Link") {
|
|
|
|
text=config.readEntry("Name");
|
|
|
|
fileName=filePath;
|
|
|
|
description=config.readEntry("Comment");
|
|
|
|
//kdDebug() << "name: " << text << endl;
|
|
|
|
icon=config.readEntry("Icon");
|
|
|
|
if(icon[0]!='/' && // allow absolute paths for icons
|
|
|
|
TQFile::exists(*it+icon)) // allow icons from icontheme
|
|
|
|
icon=*it+icon;
|
|
|
|
//kdDebug() << "icon2: " << icon << endl;
|
|
|
|
hidden=config.readBoolEntry("X-TDE-Hidden", false);
|
|
|
|
defaultTemplate = config.readBoolEntry("X-TDE-DefaultTemplate", false);
|
|
|
|
measureSystem=config.readEntry("X-TDE-MeasureSystem").lower();
|
|
|
|
|
|
|
|
// Don't add a template that is for the wrong measure system
|
|
|
|
if(measureSystem == dontShow)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
//kdDebug() << "hidden: " << hidden_str << endl;
|
|
|
|
templatePath=config.readPathEntry("URL");
|
|
|
|
//kdDebug() << "Link to : " << templatePath << endl;
|
|
|
|
if(templatePath[0]!='/') {
|
|
|
|
if(templatePath.left(6)=="file:/") // I doubt this will happen
|
|
|
|
templatePath=templatePath.right(templatePath.length()-6);
|
|
|
|
//else
|
|
|
|
// kdDebug() << "dirname=" << *it << endl;
|
|
|
|
templatePath=*it+templatePath;
|
|
|
|
//kdDebug() << "templatePath: " << templatePath << endl;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
continue; // Invalid
|
|
|
|
}
|
|
|
|
// The else if and the else branch are here for compat. with the old system
|
|
|
|
else if ( files[i].right(4) != ".png" )
|
|
|
|
// Ignore everything that is not a PNG file
|
|
|
|
continue;
|
|
|
|
else {
|
|
|
|
// Found a PNG file - the template must be here in the same dir.
|
|
|
|
icon = filePath;
|
|
|
|
TQFileInfo fi(filePath);
|
|
|
|
text = fi.baseName();
|
|
|
|
templatePath = filePath; // Note that we store the .png file as the template !
|
|
|
|
// That's the way it's always been done. Then the app replaces the extension...
|
|
|
|
}
|
|
|
|
KoTemplate *t=new KoTemplate(text, description, templatePath, icon, fileName,
|
|
|
|
measureSystem, hidden);
|
|
|
|
groupIt.current()->add(t, false, false); // false -> we aren't a "user", false -> don't
|
|
|
|
// "touch" the group to avoid useless
|
|
|
|
// creation of dirs in .kde/blah/...
|
|
|
|
if ( defaultTemplate )
|
|
|
|
m_defaultTemplate = t;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KoTemplateTree::writeTemplate(KoTemplate *t, KoTemplateGroup *group,
|
|
|
|
const TQString &localDir) {
|
|
|
|
TQString fileName;
|
|
|
|
if ( t->isHidden() )
|
|
|
|
{
|
|
|
|
fileName = t->fileName();
|
|
|
|
// try to remove the file
|
|
|
|
if ( TQFile::remove(fileName) || !TQFile::exists(fileName) )
|
|
|
|
{
|
|
|
|
TQFile::remove( t->name() );
|
|
|
|
TQFile::remove( t->picture() );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// be sure that the template's file name is unique so we don't overwrite an other
|
|
|
|
TQString const path = localDir + group->name() + '/';
|
|
|
|
TQString const name = KoTemplates::stripWhiteSpace( t->name() );
|
|
|
|
fileName = path + name + ".desktop";
|
|
|
|
if ( t->isHidden() && TQFile::exists(fileName) )
|
|
|
|
return;
|
|
|
|
TQString fill;
|
|
|
|
while ( TDEIO::NetAccess::exists( fileName, true, 0 ) )
|
|
|
|
{
|
|
|
|
fill += '_';
|
|
|
|
fileName = path + fill + name + ".desktop";
|
|
|
|
}
|
|
|
|
|
|
|
|
KSimpleConfig config( fileName );
|
|
|
|
config.setDesktopGroup();
|
|
|
|
config.writeEntry("Type", "Link");
|
|
|
|
config.writePathEntry("URL", t->file());
|
|
|
|
config.writeEntry("Name", t->name());
|
|
|
|
config.writeEntry("Icon", t->picture());
|
|
|
|
config.writeEntry("X-TDE-Hidden", t->isHidden());
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace KoTemplates {
|
|
|
|
TQString stripWhiteSpace(const TQString &string) {
|
|
|
|
|
|
|
|
TQString ret;
|
|
|
|
for(unsigned int i=0; i<string.length(); ++i) {
|
|
|
|
TQChar tmp(string[i]);
|
|
|
|
if(!tmp.isSpace())
|
|
|
|
ret+=tmp;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|