Warning, file /office/calligra/libs/main/KoTemplateTree.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002    Copyright (C) 2000 Werner Trobin <trobin@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "KoTemplateTree.h"
0021 
0022 #include <QDir>
0023 #include <QPrinter>
0024 #include <QUrl>
0025 
0026 #include <kdesktopfile.h>
0027 #include <kconfig.h>
0028 #include <MainDebug.h>
0029 #include <klocalizedstring.h>
0030 #include <kconfiggroup.h>
0031 
0032 #include <KoNetAccess.h>
0033 #include <KoResourcePaths.h>
0034 #include <KoTemplate.h>
0035 #include <KoTemplateGroup.h>
0036 #include <KoTemplates.h>
0037 
0038 KoTemplateTree::KoTemplateTree(const QString &templatesResourcePath, bool readTree) :
0039         m_templatesResourcePath(templatesResourcePath), m_defaultGroup(0),
0040         m_defaultTemplate(0)
0041 {
0042     if (readTree)
0043         readTemplateTree();
0044 }
0045 
0046 KoTemplateTree::~KoTemplateTree()
0047 {
0048     qDeleteAll(m_groups);
0049 }
0050 
0051 void KoTemplateTree::readTemplateTree()
0052 {
0053 
0054     readGroups();
0055     readTemplates();
0056 }
0057 
0058 void KoTemplateTree::writeTemplateTree()
0059 {
0060 
0061     const QString localDir = KoResourcePaths::saveLocation("data", m_templatesResourcePath);
0062 
0063     foreach (KoTemplateGroup *group, m_groups) {
0064         //kDebug( 30003 ) <<"---------------------------------";
0065         //kDebug( 30003 ) <<"group:" << group->name();
0066 
0067         bool touched = false;
0068         const QList<KoTemplate*> templates = group->templates();
0069         QList<KoTemplate*>::ConstIterator it = templates.begin();
0070         for (; it != templates.end() && !touched && !group->touched(); ++it)
0071             touched = (*it)->touched();
0072 
0073         if (group->touched() || touched) {
0074             //kDebug( 30003 ) <<"touched";
0075             if (!group->isHidden()) {
0076                 //kDebug( 30003 ) <<"not hidden";
0077                 QDir().mkpath(localDir + group->name()); // create the local group dir
0078             } else {
0079                 //kDebug( 30003 ) <<"hidden";
0080                 if (group->dirs().count() == 1 && group->dirs().contains(localDir)) {
0081                     //kDebug( 30003 ) <<"local only";
0082                     KIO::NetAccess::del(QUrl::fromLocalFile(group->dirs().first()), 0);
0083                     //kDebug( 30003 ) <<"removing:" << group->dirs().first();
0084                 } else {
0085                     //kDebug( 30003 ) <<"global";
0086                     QDir().mkpath(localDir + group->name());
0087                 }
0088             }
0089         }
0090         foreach (KoTemplate *t, templates) {
0091             if (t->touched()) {
0092                 //kDebug( 30003 ) <<"++template:" << t->name();
0093                 writeTemplate(t, group, localDir);
0094             }
0095             if (t->isHidden() && t->touched()) {
0096                 //kDebug( 30003 ) <<"+++ delete local template ##############";
0097                 writeTemplate(t, group, localDir);
0098                 QFile::remove(t->file());
0099                 QFile::remove(t->picture());
0100             }
0101         }
0102     }
0103 }
0104 
0105 void KoTemplateTree::add(KoTemplateGroup *g)
0106 {
0107 
0108     KoTemplateGroup *group = find(g->name());
0109     if (group == nullptr)
0110         m_groups.append(g);
0111     else {
0112         group->addDir(g->dirs().first()); // "...there can be only one..." (Queen)
0113         delete g;
0114         g = nullptr;
0115     }
0116 }
0117 
0118 KoTemplateGroup *KoTemplateTree::find(const QString &name) const
0119 {
0120     QList<KoTemplateGroup*>::const_iterator it = m_groups.begin();
0121     KoTemplateGroup* ret = nullptr;
0122 
0123     while (it != m_groups.end()) {
0124         if ((*it)->name() == name) {
0125             ret = *it;
0126             break;
0127         }
0128 
0129         ++it;
0130     }
0131 
0132     return ret;
0133 }
0134 
0135 void KoTemplateTree::readGroups()
0136 {
0137 
0138     const QStringList dirs = KoResourcePaths::findDirs("data", m_templatesResourcePath);
0139     foreach(const QString & dirName, dirs) {
0140         //kDebug( 30003 ) <<"dir:" << *it;
0141         QDir dir(dirName);
0142         // avoid the annoying warning
0143         if (!dir.exists())
0144             continue;
0145         QStringList templateDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
0146         foreach(const QString & templateDirName, templateDirs) {
0147             QDir templateDir(dirName + templateDirName);
0148             QString name = templateDirName;
0149             QString defaultTab;
0150             int sortingWeight = 1000;
0151             if (templateDir.exists(".directory")) {
0152                 KDesktopFile config(templateDir.absoluteFilePath(".directory"));
0153                 KConfigGroup dg = config.desktopGroup();
0154                 name = dg.readEntry("Name");
0155                 defaultTab = dg.readEntry("X-KDE-DefaultTab");
0156                 sortingWeight = dg.readEntry("X-KDE-SortingWeight", 1000);
0157                 //kDebug( 30003 ) <<"name:" << name;
0158             }
0159             KoTemplateGroup *g = new KoTemplateGroup(name, templateDir.absolutePath() + QDir::separator(), sortingWeight);
0160             add(g);
0161             if (defaultTab == "true")
0162                 m_defaultGroup = g;
0163         }
0164     }
0165 }
0166 
0167 void KoTemplateTree::readTemplates()
0168 {
0169     QString dontShow = "hide nothing at all - show all the templates, please, and let the user make the choice";
0170 
0171     foreach (KoTemplateGroup* group, m_groups) {
0172         QStringList dirs = group->dirs();
0173         for (QStringList::ConstIterator it = dirs.constBegin(); it != dirs.constEnd(); ++it) {
0174             QDir d(*it);
0175             if (!d.exists())
0176                 continue;
0177             QStringList files = d.entryList(QDir::Files | QDir::Readable, QDir::Name);
0178             for (int i = 0; i < files.count(); ++i) {
0179                 QString filePath = *it + files[i];
0180                 //kDebug( 30003 ) <<"filePath:" << filePath;
0181                 QString icon;
0182                 QString text;
0183                 QString description;
0184                 QString hidden_str;
0185                 QString fileName;
0186                 QString color;
0187                 QString swatch;
0188                 QString variantName;
0189                 QString thumbnail;
0190                 bool wide = false;
0191                 bool hidden = false;
0192                 bool defaultTemplate = false;
0193                 QString templatePath;
0194                 QString measureSystem;
0195                 // If a desktop file, then read the name from it.
0196                 // Otherwise (or if no name in it?) use file name
0197                 if (KDesktopFile::isDesktopFile(filePath)) {
0198                     KConfig _config(filePath, KConfig::SimpleConfig);
0199                     KConfigGroup config(&_config, "Desktop Entry");
0200                     if (config.readEntry("Type") == "Link") {
0201                         text = config.readEntry("Name");
0202                         fileName = filePath;
0203                         description = config.readEntry("Comment");
0204                         //kDebug( 30003 ) <<"name:" << text;
0205                         icon = config.readEntry("Icon");
0206                         if (icon[0] != '/' && // allow absolute paths for icons
0207                                 QFile::exists(*it + icon)) // allow icons from icontheme
0208                             icon = *it + icon;
0209                         //kDebug( 30003 ) <<"icon2:" << icon;
0210                         color = config.readEntry("X-KDE-Color");
0211                         swatch = config.readEntry("X-KDE-Swatch");
0212                         wide = config.readEntry("X-KDE-TemplateIsWideFormat", false);
0213                         variantName = config.readEntry("X-KDE-VariantName");
0214                         thumbnail = config.readEntry("X-KDE-Thumbnail");
0215                         hidden = config.readEntry("X-KDE-Hidden", false);
0216                         defaultTemplate = config.readEntry("X-KDE-DefaultTemplate", false);
0217                         measureSystem = config.readEntry("X-KDE-MeasureSystem").toLower();
0218 
0219                         // Don't add a template that is for the wrong measure system
0220                         if (measureSystem == dontShow)
0221                             continue;
0222 
0223                         //kDebug( 30003 ) <<"hidden:" << hidden_str;
0224                         templatePath = config.readPathEntry("URL", QString());
0225                         //kDebug( 30003 ) <<"Link to :" << templatePath;
0226                         if (templatePath[0] != '/') {
0227                             if (templatePath.left(6) == "file:/") // I doubt this will happen
0228                                 templatePath = templatePath.right(templatePath.length() - 6);
0229                             //else
0230                             //  kDebug( 30003 ) <<"dirname=" << *it;
0231                             templatePath = *it + templatePath;
0232                             //kDebug( 30003 ) <<"templatePath:" << templatePath;
0233                         }
0234                     } else
0235                         continue; // Invalid
0236                 }
0237                 // The else if and the else branch are here for compat. with the old system
0238                 else if (files[i].right(4) != ".png")
0239                     // Ignore everything that is not a PNG file
0240                     continue;
0241                 else {
0242                     // Found a PNG file - the template must be here in the same dir.
0243                     icon = filePath;
0244                     QFileInfo fi(filePath);
0245                     text = fi.baseName();
0246                     templatePath = filePath; // Note that we store the .png file as the template !
0247                     // That's the way it's always been done. Then the app replaces the extension...
0248                 }
0249                 KoTemplate *t = new KoTemplate(text, description, templatePath, icon, fileName,
0250                                                measureSystem, color, swatch, variantName, wide, hidden);
0251                 if (!thumbnail.isEmpty())
0252                     t->setThumbnail(*it + thumbnail);
0253                 group->add(t, false, false); // false -> we aren't a "user", false -> don't
0254                 // "touch" the group to avoid useless
0255                 // creation of dirs in .kde/blah/...
0256                 if (defaultTemplate)
0257                     m_defaultTemplate = t;
0258             }
0259         }
0260     }
0261 }
0262 
0263 void KoTemplateTree::writeTemplate(KoTemplate *t, KoTemplateGroup *group,
0264                                    const QString &localDir)
0265 {
0266     QString fileName;
0267     if (t->isHidden()) {
0268         fileName = t->fileName();
0269         // try to remove the file
0270         if (QFile::remove(fileName) || !QFile::exists(fileName)) {
0271             QFile::remove(t->name());
0272             QFile::remove(t->picture());
0273             return;
0274         }
0275     }
0276     // be sure that the template's file name is unique so we don't overwrite an other
0277     QString const path = localDir + group->name() + '/';
0278     QString const name = KoTemplates::trimmed(t->name());
0279     fileName = path + name + ".desktop";
0280     if (t->isHidden() && QFile::exists(fileName))
0281         return;
0282     QString fill;
0283     while (QFile(fileName).exists()) {
0284         fill += '_';
0285         fileName = path + fill + name + ".desktop";
0286     }
0287 
0288     KConfig _config(fileName, KConfig::SimpleConfig);
0289     KConfigGroup config(&_config, "Desktop Entry");
0290     config.writeEntry("Type", "Link");
0291     config.writePathEntry("URL", t->file());
0292     config.writeEntry("Name", t->name());
0293     config.writeEntry("Icon", t->picture());
0294     config.writeEntry("X-KDE-Hidden", t->isHidden());
0295 }