lib Library API Documentation

koTemplates.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2000 Werner Trobin <trobin@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include <koTemplates.h>
00021 
00022 #include <qdir.h>
00023 #include <qimage.h>
00024 
00025 #include <kdesktopfile.h>
00026 #include <ksimpleconfig.h>
00027 #include <kdebug.h>
00028 #include <kdeversion.h>
00029 #include <kinstance.h>
00030 #include <ksavefile.h>
00031 #include <kstandarddirs.h>
00032 #include <kiconloader.h>
00033 #include <kio/netaccess.h>
00034 
00035 #include <stdlib.h>
00036 
00037 
00038 KoTemplate::KoTemplate(const QString &name, const QString &description, const QString &file,
00039                        const QString &picture, const QString &fileName, bool hidden,
00040                        bool touched) :
00041     m_name(name), m_descr(description), m_file(file), m_picture(picture), m_fileName(fileName),
00042     m_hidden(hidden), m_touched(touched), m_cached(false) {
00043 }
00044 
00045 const QPixmap &KoTemplate::loadPicture( KInstance* instance ) {
00046 
00047     if(m_cached)
00048         return m_pixmap;
00049     m_cached=true;
00050     if ( m_picture[ 0 ] == '/' )
00051     {
00052         // ### TODO: use the class KoPicture instead of QImage to support non-image pictures
00053         QImage img( m_picture );
00054         if (img.isNull()) {
00055             kdWarning() << "Couldn't find icon " << m_picture << endl;
00056             m_pixmap=QPixmap();
00057             return m_pixmap;
00058         }
00059         const int maxHeightWidth = 64; // ### TODO: some people would surely like to have 128x128
00060         if (img.width() > maxHeightWidth || img.height() > maxHeightWidth) {
00061             img = img.smoothScale( maxHeightWidth, maxHeightWidth, QImage::ScaleMax );
00062         }
00063         m_pixmap.convertFromImage(img);
00064         return m_pixmap;
00065     } else { // relative path
00066         m_pixmap = instance->iconLoader()->loadIcon( m_picture, KIcon::Desktop, KIcon::SizeLarge /*48*/ );
00067         return m_pixmap;
00068     }
00069 }
00070 
00071 
00072 KoTemplateGroup::KoTemplateGroup(const QString &name, const QString &dir,
00073                                  bool touched) :
00074     m_name(name), m_touched(touched) {
00075     m_dirs.append(dir);
00076     m_templates.setAutoDelete(true);
00077 }
00078 
00079 bool KoTemplateGroup::isHidden() const {
00080 
00081     QPtrListIterator<KoTemplate> it(m_templates);
00082     bool hidden=true;
00083     while(it.current()!=0L && hidden) {
00084         hidden=it.current()->isHidden();
00085         ++it;
00086     }
00087     return hidden;
00088 }
00089 
00090 void KoTemplateGroup::setHidden(bool hidden) const {
00091 
00092     QPtrListIterator<KoTemplate> it(m_templates);
00093     for( ; it.current()!=0L; ++it)
00094         it.current()->setHidden(hidden);
00095     m_touched=true;
00096 }
00097 
00098 bool KoTemplateGroup::add(KoTemplate *t, bool force, bool touch) {
00099 
00100     KoTemplate *myTemplate=find(t->name());
00101     if(myTemplate==0L) {
00102         m_templates.append(t);
00103         m_touched=touch;
00104         return true;
00105     }
00106     else if(myTemplate && force) {
00107         //kdDebug() << "removing :" << myTemplate->fileName() << endl;
00108         QFile::remove( myTemplate->fileName()  );
00109         QFile::remove( myTemplate->picture() );
00110         QFile::remove( myTemplate->file() );
00111         m_templates.removeRef(myTemplate);
00112         m_templates.append(t);
00113         m_touched=touch;
00114         return true;
00115     }
00116     return false;
00117 }
00118 
00119 KoTemplate *KoTemplateGroup::find(const QString &name) const {
00120 
00121     QPtrListIterator<KoTemplate> it(m_templates);
00122     while(it.current() && it.current()->name()!=name)
00123         ++it;
00124     return it.current();
00125 }
00126 
00127 
00128 KoTemplateTree::KoTemplateTree(const QCString &templateType,
00129                                KInstance *instance, bool readTree) :
00130     m_templateType(templateType), m_instance(instance), m_defaultGroup(0L),
00131     m_defaultTemplate(0L) {
00132 
00133     m_groups.setAutoDelete(true);
00134     if(readTree)
00135         readTemplateTree();
00136 }
00137 
00138 void KoTemplateTree::readTemplateTree() {
00139 
00140     readGroups();
00141     readTemplates();
00142 }
00143 
00144 void KoTemplateTree::writeTemplateTree() {
00145     QString localDir=m_instance->dirs()->saveLocation(m_templateType);
00146 
00147     for(KoTemplateGroup *group=m_groups.first(); group!=0L; group=m_groups.next()) {
00148         //kdDebug() << "---------------------------------" << endl;
00149         //kdDebug() << "group: " << group->name() << endl;
00150 
00151         bool touched=false;
00152         for(KoTemplate *t=group->first(); t!=0L && !touched && !group->touched(); t=group->next())
00153             touched=t->touched();
00154 
00155         if(group->touched() || touched) {
00156             //kdDebug() << "touched" << endl;
00157             if(!group->isHidden()) {
00158                 //kdDebug() << "not hidden" << endl;
00159                 KStandardDirs::makeDir(localDir+group->name()); // create the local group dir
00160             }
00161             else {
00162                 //kdDebug() << "hidden" << endl;
00163                 if(group->dirs().count()==1 && !group->dirs().grep(localDir).isEmpty()) {
00164                     //kdDebug() << "local only" << endl;
00165                     KIO::NetAccess::del(group->dirs().first(), 0);
00166                     //kdDebug() << "removing: " << group->dirs().first() << endl;
00167                 }
00168                 else {
00169                     //kdDebug() << "global" << endl;
00170                     KStandardDirs::makeDir(localDir+group->name());
00171                 }
00172             }
00173         }
00174         for(KoTemplate *t=group->first(); t!=0L; t=group->next()) {
00175             if(t->touched()) {
00176                 //kdDebug() << "++template: " << t->name() << endl;
00177                 writeTemplate(t, group, localDir);
00178             }
00179             if(t->isHidden() && t->touched() ) {
00180                 //kdDebug() << "+++ delete local template ##############" << endl;
00181                 writeTemplate(t, group, localDir);
00182                 QFile::remove(t->file());
00183                 QFile::remove(t->picture());
00184             }
00185         }
00186     }
00187 }
00188 
00189 void KoTemplateTree::add(KoTemplateGroup *g) {
00190 
00191     KoTemplateGroup *group=find(g->name());
00192     if(group==0L)
00193         m_groups.append(g);
00194     else
00195         group->addDir(g->dirs().first()); // "...there can be only one..." (Queen)
00196 }
00197 
00198 KoTemplateGroup *KoTemplateTree::find(const QString &name) const {
00199 
00200     QPtrListIterator<KoTemplateGroup> it(m_groups);
00201     while(it.current() && it.current()->name()!=name)
00202         ++it;
00203     return it.current();
00204 }
00205 
00206 void KoTemplateTree::readGroups() {
00207 
00208     QStringList dirs = m_instance->dirs()->resourceDirs(m_templateType);
00209     for(QStringList::ConstIterator it=dirs.begin(); it!=dirs.end(); ++it) {
00210         //kdDebug() << "dir: " << *it << endl;
00211         QDir dir(*it);
00212         // avoid the annoying warning
00213         if(!dir.exists())
00214             continue;
00215         dir.setFilter(QDir::Dirs);
00216         QStringList templateDirs=dir.entryList();
00217         for(QStringList::ConstIterator tdirIt=templateDirs.begin(); tdirIt!=templateDirs.end(); ++tdirIt) {
00218             if(*tdirIt=="." || *tdirIt=="..") // we don't want to check those dirs :)
00219                 continue;
00220             QDir templateDir(*it+*tdirIt);
00221             QString name=*tdirIt;
00222             QString defaultTab;
00223             if(templateDir.exists(".directory")) {
00224                 KSimpleConfig config(templateDir.absPath()+"/.directory", true);
00225                 config.setDesktopGroup();
00226                 name=config.readEntry("Name");
00227                 defaultTab=config.readEntry("X-KDE-DefaultTab");
00228                 //kdDebug() << "name: " << name <<endl;
00229             }
00230             KoTemplateGroup *g=new KoTemplateGroup(name, *it+*tdirIt+QChar('/'));
00231             add(g);
00232             if(defaultTab=="true")
00233                 m_defaultGroup=g;
00234         }
00235     }
00236 }
00237 
00238 void KoTemplateTree::readTemplates() {
00239 
00240     QPtrListIterator<KoTemplateGroup> groupIt(m_groups);
00241     for( ; groupIt.current()!=0L; ++groupIt) {
00242         QStringList dirs=groupIt.current()->dirs();
00243         for(QStringList::ConstIterator it=dirs.begin(); it!=dirs.end(); ++it) {
00244             QDir d(*it);
00245             if( !d.exists() )
00246                 continue;
00247             QStringList files=d.entryList( QDir::Files | QDir::Readable, QDir::Name );
00248             for(unsigned int i=0; i<files.count(); ++i) {
00249                 QString filePath = *it + files[i];
00250                 //kdDebug() << "filePath: " << filePath << endl;
00251                 QString icon;
00252                 QString text;
00253                 QString description;
00254                 QString hidden_str;
00255                 QString fileName;
00256                 bool hidden=false;
00257                 bool defaultTemplate = false;
00258                 QString templatePath;
00259                 // If a desktop file, then read the name from it.
00260                 // Otherwise (or if no name in it?) use file name
00261                 if (KDesktopFile::isDesktopFile(filePath)) {
00262                     KSimpleConfig config(filePath, true);
00263                     config.setDesktopGroup();
00264                     if (config.readEntry("Type")=="Link") {
00265                         text=config.readEntry("Name");
00266                         hidden=config.readBoolEntry("X-KDE-Hidden", false);
00267                         fileName=filePath;
00268                         description=config.readEntry("Comment");
00269                         //kdDebug() << "name: " << text << endl;
00270                         icon=config.readEntry("Icon");
00271                         if(icon[0]!='/' && // allow absolute paths for icons
00272                            QFile::exists(*it+icon)) // allow icons from icontheme
00273                             icon=*it+icon;
00274                         //kdDebug() << "icon2: " << icon << endl;
00275                         hidden=config.readBoolEntry("X-KDE-Hidden", false);
00276                         defaultTemplate = config.readBoolEntry("X-KDE-DefaultTemplate", false);
00277                         //kdDebug() << "hidden: " << hidden_str << endl;
00278                         templatePath=config.readPathEntry("URL");
00279                         //kdDebug() << "Link to : " << templatePath << endl;
00280                         if(templatePath[0]!='/') {
00281                             if(templatePath.left(6)=="file:/") // I doubt this will happen
00282                                 templatePath=templatePath.right(templatePath.length()-6);
00283                             //else
00284                             //  kdDebug() << "dirname=" << *it << endl;
00285                             templatePath=*it+templatePath;
00286                             //kdDebug() << "templatePath: " << templatePath << endl;
00287                         }
00288                     } else
00289                         continue; // Invalid
00290                 }
00291                 // The else if and the else branch are here for compat. with the old system
00292                 else if ( files[i].right(4) != ".png" )
00293                     // Ignore everything that is not a PNG file
00294                     continue;
00295                 else {
00296                     // Found a PNG file - the template must be here in the same dir.
00297                     icon = filePath;
00298                     QFileInfo fi(filePath);
00299                     text = fi.baseName();
00300                     templatePath = filePath; // Note that we store the .png file as the template !
00301                     // That's the way it's always been done. Then the app replaces the extension...
00302                 }
00303                 KoTemplate *t=new KoTemplate(text, description, templatePath, icon, fileName, hidden);
00304                 groupIt.current()->add(t, false, false); // false -> we aren't a "user", false -> don't
00305                                                          // "touch" the group to avoid useless
00306                                                          // creation of dirs in .kde/blah/...
00307                 if ( defaultTemplate )
00308                     m_defaultTemplate = t;
00309             }
00310         }
00311     }
00312 }
00313 
00314 void KoTemplateTree::writeTemplate(KoTemplate *t, KoTemplateGroup *group,
00315                                    const QString &localDir) {
00316     QString fileName;
00317     if ( t->isHidden() )
00318     {
00319         fileName = t->fileName();
00320         // try to remove the file
00321         if ( QFile::remove(fileName) || !QFile::exists(fileName) )
00322         {
00323             QFile::remove( t->name() );
00324             QFile::remove( t->picture() );
00325             return;
00326         }
00327     }
00328     // be sure that the template's file name is unique so we don't overwrite an other
00329     QString const path = localDir + group->name() + '/';
00330     QString const name = KoTemplates::stripWhiteSpace( t->name() );
00331     fileName = path + name + ".desktop";
00332     if ( t->isHidden() && QFile::exists(fileName) )
00333         return;
00334     QString fill;
00335     while ( KIO::NetAccess::exists( fileName, true, 0 ) )
00336     {
00337         fill += '_';
00338         fileName = path + fill + name + ".desktop";
00339     }
00340 
00341     KSimpleConfig config( fileName );
00342     config.setDesktopGroup();
00343     config.writeEntry("Type", "Link");
00344     config.writePathEntry("URL", t->file());
00345     config.writeEntry("Name", t->name());
00346     config.writeEntry("Icon", t->picture());
00347     config.writeEntry("X-KDE-Hidden", t->isHidden());
00348 }
00349 
00350 namespace KoTemplates {
00351 QString stripWhiteSpace(const QString &string) {
00352 
00353     QString ret;
00354     for(unsigned int i=0; i<string.length(); ++i) {
00355         QChar tmp(string[i]);
00356         if(!tmp.isSpace())
00357             ret+=tmp;
00358     }
00359     return ret;
00360 }
00361 }
KDE Logo
This file is part of the documentation for lib Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:40:08 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003