F:/KPlato/koffice/libs/kofficecore/KoTemplates.cpp

Aller à la documentation de ce fichier.
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., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include <KoTemplates.h>
00021 
00022 #include <QDir>
00023 #include <QImage>
00024 #include <QPixmap>
00025 #include <QPrinter>
00026 
00027 #include <kdesktopfile.h>
00028 #include <ksimpleconfig.h>
00029 #include <kdebug.h>
00030 #include <kdeversion.h>
00031 #include <kinstance.h>
00032 #include <ksavefile.h>
00033 #include <kstandarddirs.h>
00034 #include <kiconloader.h>
00035 #include <kio/netaccess.h>
00036 #include <klocale.h>
00037 
00038 #include <stdlib.h>
00039 
00040 
00041 KoTemplate::KoTemplate(const QString &name, const QString &description, const QString &file,
00042                        const QString &picture, const QString &fileName, const QString &_measureSystem,
00043                        bool hidden, bool touched) :
00044     m_name(name), m_descr(description), m_file(file), m_picture(picture), m_fileName(fileName),
00045     m_hidden(hidden), m_touched(touched), m_cached(false), m_measureSystem(_measureSystem)
00046 {
00047 }
00048 
00049 const QPixmap &KoTemplate::loadPicture( KInstance* instance ) {
00050 
00051     if(m_cached)
00052         return m_pixmap;
00053     m_cached=true;
00054     if ( m_picture[ 0 ] == '/' )
00055     {
00056         // ### TODO: use the class KoPicture instead of QImage to support non-image pictures
00057         QImage img( m_picture );
00058         if (img.isNull()) {
00059             kWarning() << "Couldn't find icon " << m_picture << endl;
00060             m_pixmap=QPixmap();
00061             return m_pixmap;
00062         }
00063         const int maxHeightWidth = 128; // ### TODO: some people would surely like to have 128x128
00064         if (img.width() > maxHeightWidth || img.height() > maxHeightWidth) {
00065             img = img.scaled( maxHeightWidth, maxHeightWidth, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation );
00066         }
00067         m_pixmap = QPixmap::fromImage(img);
00068         return m_pixmap;
00069     } else { // relative path
00070         m_pixmap = instance->iconLoader()->loadIcon( m_picture, K3Icon::Desktop, 128 );
00071         return m_pixmap;
00072     }
00073 }
00074 
00075 
00076 KoTemplateGroup::KoTemplateGroup(const QString &name, const QString &dir,
00077                                  int _sortingWeight, bool touched) :
00078     m_name(name), m_touched(touched), m_sortingWeight(_sortingWeight)
00079 {
00080     m_dirs.append(dir);
00081     m_templates.setAutoDelete(true);
00082 }
00083 
00084 bool KoTemplateGroup::isHidden() const {
00085 
00086     Q3PtrListIterator<KoTemplate> it(m_templates);
00087     bool hidden=true;
00088     while(it.current()!=0L && hidden) {
00089         hidden=it.current()->isHidden();
00090         ++it;
00091     }
00092     return hidden;
00093 }
00094 
00095 void KoTemplateGroup::setHidden(bool hidden) const {
00096 
00097     Q3PtrListIterator<KoTemplate> it(m_templates);
00098     for( ; it.current()!=0L; ++it)
00099         it.current()->setHidden(hidden);
00100     m_touched=true;
00101 }
00102 
00103 bool KoTemplateGroup::add(KoTemplate *t, bool force, bool touch) {
00104 
00105     KoTemplate *myTemplate=find(t->name());
00106     if(myTemplate==0L) {
00107         m_templates.append(t);
00108         m_touched=touch;
00109         return true;
00110     }
00111     else if(myTemplate && force) {
00112         //kDebug() << "removing :" << myTemplate->fileName() << endl;
00113         QFile::remove( myTemplate->fileName()  );
00114         QFile::remove( myTemplate->picture() );
00115         QFile::remove( myTemplate->file() );
00116         m_templates.removeRef(myTemplate);
00117         m_templates.append(t);
00118         m_touched=touch;
00119         return true;
00120     }
00121     return false;
00122 }
00123 
00124 KoTemplate *KoTemplateGroup::find(const QString &name) const {
00125 
00126     Q3PtrListIterator<KoTemplate> it(m_templates);
00127     while(it.current() && it.current()->name()!=name)
00128         ++it;
00129     return it.current();
00130 }
00131 
00132 
00133 KoTemplateTree::KoTemplateTree(const QByteArray &templateType,
00134                                KInstance *instance, bool readTree) :
00135     m_templateType(templateType), m_instance(instance), m_defaultGroup(0L),
00136     m_defaultTemplate(0L) {
00137 
00138     m_groups.setAutoDelete(true);
00139     if(readTree)
00140         readTemplateTree();
00141 }
00142 
00143 void KoTemplateTree::readTemplateTree() {
00144 
00145     readGroups();
00146     readTemplates();
00147 }
00148 
00149 void KoTemplateTree::writeTemplateTree() {
00150     QString localDir=m_instance->dirs()->saveLocation(m_templateType);
00151 
00152     for(KoTemplateGroup *group=m_groups.first(); group!=0L; group=m_groups.next()) {
00153         //kDebug() << "---------------------------------" << endl;
00154         //kDebug() << "group: " << group->name() << endl;
00155 
00156         bool touched=false;
00157         for(KoTemplate *t=group->first(); t!=0L && !touched && !group->touched(); t=group->next())
00158             touched=t->touched();
00159 
00160         if(group->touched() || touched) {
00161             //kDebug() << "touched" << endl;
00162             if(!group->isHidden()) {
00163                 //kDebug() << "not hidden" << endl;
00164                 KStandardDirs::makeDir(localDir+group->name()); // create the local group dir
00165             }
00166             else {
00167                 //kDebug() << "hidden" << endl;
00168                 if(group->dirs().count()==1 && group->dirs().contains(localDir)) {
00169                     //kDebug() << "local only" << endl;
00170                     KIO::NetAccess::del(group->dirs().first(), 0);
00171                     //kDebug() << "removing: " << group->dirs().first() << endl;
00172                 }
00173                 else {
00174                     //kDebug() << "global" << endl;
00175                     KStandardDirs::makeDir(localDir+group->name());
00176                 }
00177             }
00178         }
00179         for(KoTemplate *t=group->first(); t!=0L; t=group->next()) {
00180             if(t->touched()) {
00181                 //kDebug() << "++template: " << t->name() << endl;
00182                 writeTemplate(t, group, localDir);
00183             }
00184             if(t->isHidden() && t->touched() ) {
00185                 //kDebug() << "+++ delete local template ##############" << endl;
00186                 writeTemplate(t, group, localDir);
00187                 QFile::remove(t->file());
00188                 QFile::remove(t->picture());
00189             }
00190         }
00191     }
00192 }
00193 
00194 void KoTemplateTree::add(KoTemplateGroup *g) {
00195 
00196     KoTemplateGroup *group=find(g->name());
00197     if(group==0L)
00198         m_groups.append(g);
00199     else
00200         group->addDir(g->dirs().first()); // "...there can be only one..." (Queen)
00201 }
00202 
00203 KoTemplateGroup *KoTemplateTree::find(const QString &name) const {
00204 
00205     Q3PtrListIterator<KoTemplateGroup> it(m_groups);
00206     while(it.current() && it.current()->name()!=name)
00207         ++it;
00208     return it.current();
00209 }
00210 
00211 void KoTemplateTree::readGroups() {
00212 
00213     QStringList dirs = m_instance->dirs()->resourceDirs(m_templateType);
00214     for(QStringList::ConstIterator it=dirs.begin(); it!=dirs.end(); ++it) {
00215         //kDebug() << "dir: " << *it << endl;
00216         QDir dir(*it);
00217         // avoid the annoying warning
00218         if(!dir.exists())
00219             continue;
00220         dir.setFilter(QDir::Dirs);
00221         QStringList templateDirs=dir.entryList();
00222         for(QStringList::ConstIterator tdirIt=templateDirs.begin(); tdirIt!=templateDirs.end(); ++tdirIt) {
00223             if(*tdirIt=="." || *tdirIt=="..") // we don't want to check those dirs :)
00224                 continue;
00225             QDir templateDir(*it+*tdirIt);
00226             QString name=*tdirIt;
00227             QString defaultTab;
00228             int sortingWeight = 1000;
00229             if(templateDir.exists(".directory")) {
00230                 KSimpleConfig config(templateDir.absolutePath()+"/.directory", true);
00231                 config.setDesktopGroup();
00232                 name=config.readEntry("Name");
00233                 defaultTab=config.readEntry("X-KDE-DefaultTab");
00234                 sortingWeight=config.readEntry("X-KDE-SortingWeight", 1000);
00235                 //kDebug() << "name: " << name <<endl;
00236             }
00237             KoTemplateGroup *g=new KoTemplateGroup(name, *it+*tdirIt+QChar('/'), sortingWeight);
00238             add(g);
00239             if(defaultTab=="true")
00240                 m_defaultGroup=g;
00241         }
00242     }
00243 }
00244 
00245 void KoTemplateTree::readTemplates() {
00246     QString dontShow = "imperial";
00247 
00248     if(KGlobal::locale()->pageSize() == QPrinter::Letter) {
00249         dontShow = "metric";
00250     }
00251 
00252     Q3PtrListIterator<KoTemplateGroup> groupIt(m_groups);
00253     for( ; groupIt.current()!=0L; ++groupIt) {
00254         QStringList dirs=groupIt.current()->dirs();
00255         for(QStringList::ConstIterator it=dirs.begin(); it!=dirs.end(); ++it) {
00256             QDir d(*it);
00257             if( !d.exists() )
00258                 continue;
00259             QStringList files=d.entryList( QDir::Files | QDir::Readable, QDir::Name );
00260             for(int i = 0; i < files.count(); ++i) {
00261                 QString filePath = *it + files[i];
00262                 //kDebug() << "filePath: " << filePath << endl;
00263                 QString icon;
00264                 QString text;
00265                 QString description;
00266                 QString hidden_str;
00267                 QString fileName;
00268                 bool hidden=false;
00269                 bool defaultTemplate = false;
00270                 QString templatePath;
00271                 QString measureSystem;
00272                 // If a desktop file, then read the name from it.
00273                 // Otherwise (or if no name in it?) use file name
00274                 if (KDesktopFile::isDesktopFile(filePath)) {
00275                     KSimpleConfig config(filePath, true);
00276                     config.setDesktopGroup();
00277                     if (config.readEntry("Type")=="Link") {
00278                         text=config.readEntry("Name");
00279                         fileName=filePath;
00280                         description=config.readEntry("Comment");
00281                         //kDebug() << "name: " << text << endl;
00282                         icon=config.readEntry("Icon");
00283                         if(icon[0]!='/' && // allow absolute paths for icons
00284                            QFile::exists(*it+icon)) // allow icons from icontheme
00285                             icon=*it+icon;
00286                         //kDebug() << "icon2: " << icon << endl;
00287                         hidden=config.readEntry("X-KDE-Hidden", false);
00288                         defaultTemplate = config.readEntry("X-KDE-DefaultTemplate", false);
00289                         measureSystem=config.readEntry("X-KDE-MeasureSystem").toLower();
00290 
00291                         // Don't add a template that is for the wrong measure system
00292                         if(measureSystem == dontShow)
00293                             continue;
00294 
00295                         //kDebug() << "hidden: " << hidden_str << endl;
00296                         templatePath=config.readPathEntry("URL");
00297                         //kDebug() << "Link to : " << templatePath << endl;
00298                         if(templatePath[0]!='/') {
00299                             if(templatePath.left(6)=="file:/") // I doubt this will happen
00300                                 templatePath=templatePath.right(templatePath.length()-6);
00301                             //else
00302                             //  kDebug() << "dirname=" << *it << endl;
00303                             templatePath=*it+templatePath;
00304                             //kDebug() << "templatePath: " << templatePath << endl;
00305                         }
00306                     } else
00307                         continue; // Invalid
00308                 }
00309                 // The else if and the else branch are here for compat. with the old system
00310                 else if ( files[i].right(4) != ".png" )
00311                     // Ignore everything that is not a PNG file
00312                     continue;
00313                 else {
00314                     // Found a PNG file - the template must be here in the same dir.
00315                     icon = filePath;
00316                     QFileInfo fi(filePath);
00317                     text = fi.baseName();
00318                     templatePath = filePath; // Note that we store the .png file as the template !
00319                     // That's the way it's always been done. Then the app replaces the extension...
00320                 }
00321                 KoTemplate *t=new KoTemplate(text, description, templatePath, icon, fileName,
00322                                              measureSystem, hidden);
00323                 groupIt.current()->add(t, false, false); // false -> we aren't a "user", false -> don't
00324                                                          // "touch" the group to avoid useless
00325                                                          // creation of dirs in .kde/blah/...
00326                 if ( defaultTemplate )
00327                     m_defaultTemplate = t;
00328             }
00329         }
00330     }
00331 }
00332 
00333 void KoTemplateTree::writeTemplate(KoTemplate *t, KoTemplateGroup *group,
00334                                    const QString &localDir) {
00335     QString fileName;
00336     if ( t->isHidden() )
00337     {
00338         fileName = t->fileName();
00339         // try to remove the file
00340         if ( QFile::remove(fileName) || !QFile::exists(fileName) )
00341         {
00342             QFile::remove( t->name() );
00343             QFile::remove( t->picture() );
00344             return;
00345         }
00346     }
00347     // be sure that the template's file name is unique so we don't overwrite an other
00348     QString const path = localDir + group->name() + '/';
00349     QString const name = KoTemplates::trimmed( t->name() );
00350     fileName = path + name + ".desktop";
00351     if ( t->isHidden() && QFile::exists(fileName) )
00352         return;
00353     QString fill;
00354     while ( KIO::NetAccess::exists( fileName, true, 0 ) )
00355     {
00356         fill += '_';
00357         fileName = path + fill + name + ".desktop";
00358     }
00359 
00360     KSimpleConfig config( fileName );
00361     config.setDesktopGroup();
00362     config.writeEntry("Type", "Link");
00363     config.writePathEntry("URL", t->file());
00364     config.writeEntry("Name", t->name());
00365     config.writeEntry("Icon", t->picture());
00366     config.writeEntry("X-KDE-Hidden", t->isHidden());
00367 }
00368 
00369 namespace KoTemplates {
00370 QString trimmed(const QString &string) {
00371 
00372     QString ret;
00373     for(int i = 0; i < string.length(); ++i) {
00374         QChar tmp(string[i]);
00375         if(!tmp.isSpace())
00376             ret+=tmp;
00377     }
00378     return ret;
00379 }
00380 }

Généré le Wed Nov 22 23:41:04 2006 pour KPlato par  doxygen 1.5.1-p1