diff options
Diffstat (limited to 'lib/kofficecore/KoTemplates.cpp')
-rw-r--r-- | lib/kofficecore/KoTemplates.cpp | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/lib/kofficecore/KoTemplates.cpp b/lib/kofficecore/KoTemplates.cpp new file mode 100644 index 00000000..7fbf3a99 --- /dev/null +++ b/lib/kofficecore/KoTemplates.cpp @@ -0,0 +1,379 @@ +/* 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 <qdir.h> +#include <qimage.h> +#include <qprinter.h> + +#include <kdesktopfile.h> +#include <ksimpleconfig.h> +#include <kdebug.h> +#include <kdeversion.h> +#include <kinstance.h> +#include <ksavefile.h> +#include <kstandarddirs.h> +#include <kiconloader.h> +#include <kio/netaccess.h> +#include <klocale.h> + +#include <stdlib.h> + + +KoTemplate::KoTemplate(const QString &name, const QString &description, const QString &file, + const QString &picture, const QString &fileName, const QString &_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 QPixmap &KoTemplate::loadPicture( KInstance* instance ) { + + if(m_cached) + return m_pixmap; + m_cached=true; + if ( m_picture[ 0 ] == '/' ) + { + // ### TODO: use the class KoPicture instead of QImage to support non-image pictures + QImage img( m_picture ); + if (img.isNull()) { + kdWarning() << "Couldn't find icon " << m_picture << endl; + m_pixmap=QPixmap(); + 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, QImage::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 QString &name, const QString &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 { + + QPtrListIterator<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 { + + QPtrListIterator<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; + QFile::remove( myTemplate->fileName() ); + QFile::remove( myTemplate->picture() ); + QFile::remove( myTemplate->file() ); + m_templates.removeRef(myTemplate); + m_templates.append(t); + m_touched=touch; + return true; + } + return false; +} + +KoTemplate *KoTemplateGroup::find(const QString &name) const { + + QPtrListIterator<KoTemplate> it(m_templates); + while(it.current() && it.current()->name()!=name) + ++it; + return it.current(); +} + + +KoTemplateTree::KoTemplateTree(const QCString &templateType, + KInstance *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() { + QString 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; + KStandardDirs::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; + KIO::NetAccess::del(group->dirs().first(), 0); + //kdDebug() << "removing: " << group->dirs().first() << endl; + } + else { + //kdDebug() << "global" << endl; + KStandardDirs::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); + QFile::remove(t->file()); + QFile::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 QString &name) const { + + QPtrListIterator<KoTemplateGroup> it(m_groups); + while(it.current() && it.current()->name()!=name) + ++it; + return it.current(); +} + +void KoTemplateTree::readGroups() { + + QStringList dirs = m_instance->dirs()->resourceDirs(m_templateType); + for(QStringList::ConstIterator it=dirs.begin(); it!=dirs.end(); ++it) { + //kdDebug() << "dir: " << *it << endl; + QDir dir(*it); + // avoid the annoying warning + if(!dir.exists()) + continue; + dir.setFilter(QDir::Dirs); + QStringList templateDirs=dir.entryList(); + for(QStringList::ConstIterator tdirIt=templateDirs.begin(); tdirIt!=templateDirs.end(); ++tdirIt) { + if(*tdirIt=="." || *tdirIt=="..") // we don't want to check those dirs :) + continue; + QDir templateDir(*it+*tdirIt); + QString name=*tdirIt; + QString defaultTab; + int sortingWeight = 1000; + if(templateDir.exists(".directory")) { + KSimpleConfig config(templateDir.absPath()+"/.directory", true); + config.setDesktopGroup(); + name=config.readEntry("Name"); + defaultTab=config.readEntry("X-KDE-DefaultTab"); + sortingWeight=config.readNumEntry("X-KDE-SortingWeight", 1000); + //kdDebug() << "name: " << name <<endl; + } + KoTemplateGroup *g=new KoTemplateGroup(name, *it+*tdirIt+QChar('/'), sortingWeight); + add(g); + if(defaultTab=="true") + m_defaultGroup=g; + } + } +} + +void KoTemplateTree::readTemplates() { + QString dontShow = "imperial"; + + if(KGlobal::locale()->pageSize() == QPrinter::Letter) { + dontShow = "metric"; + } + + QPtrListIterator<KoTemplateGroup> groupIt(m_groups); + for( ; groupIt.current()!=0L; ++groupIt) { + QStringList dirs=groupIt.current()->dirs(); + for(QStringList::ConstIterator it=dirs.begin(); it!=dirs.end(); ++it) { + QDir d(*it); + if( !d.exists() ) + continue; + QStringList files=d.entryList( QDir::Files | QDir::Readable, QDir::Name ); + for(unsigned int i=0; i<files.count(); ++i) { + QString filePath = *it + files[i]; + //kdDebug() << "filePath: " << filePath << endl; + QString icon; + QString text; + QString description; + QString hidden_str; + QString fileName; + bool hidden=false; + bool defaultTemplate = false; + QString templatePath; + QString 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 + QFile::exists(*it+icon)) // allow icons from icontheme + icon=*it+icon; + //kdDebug() << "icon2: " << icon << endl; + hidden=config.readBoolEntry("X-KDE-Hidden", false); + defaultTemplate = config.readBoolEntry("X-KDE-DefaultTemplate", false); + measureSystem=config.readEntry("X-KDE-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; + QFileInfo 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 QString &localDir) { + QString fileName; + if ( t->isHidden() ) + { + fileName = t->fileName(); + // try to remove the file + if ( QFile::remove(fileName) || !QFile::exists(fileName) ) + { + QFile::remove( t->name() ); + QFile::remove( t->picture() ); + return; + } + } + // be sure that the template's file name is unique so we don't overwrite an other + QString const path = localDir + group->name() + '/'; + QString const name = KoTemplates::stripWhiteSpace( t->name() ); + fileName = path + name + ".desktop"; + if ( t->isHidden() && QFile::exists(fileName) ) + return; + QString fill; + while ( KIO::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-KDE-Hidden", t->isHidden()); +} + +namespace KoTemplates { +QString stripWhiteSpace(const QString &string) { + + QString ret; + for(unsigned int i=0; i<string.length(); ++i) { + QChar tmp(string[i]); + if(!tmp.isSpace()) + ret+=tmp; + } + return ret; +} +} |