File indexing completed on 2024-10-13 04:54:49
0001 /* 0002 SPDX-FileCopyrightText: 2020 Michail Vourlakos <mvourlakos@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "templatesmanager.h" 0007 0008 // local 0009 #include "../layout/abstractlayout.h" 0010 #include "../layout/centrallayout.h" 0011 #include "../layouts/importer.h" 0012 #include "../layouts/manager.h" 0013 #include "../layouts/storage.h" 0014 #include "../tools/commontools.h" 0015 #include "../view/view.h" 0016 0017 // Qt 0018 #include <QDir> 0019 0020 // KDE 0021 #include <KDirWatch> 0022 #include <KLocalizedString> 0023 0024 namespace Latte { 0025 namespace Templates { 0026 0027 Manager::Manager(Latte::Corona *corona) 0028 : QObject(corona), 0029 m_corona(corona) 0030 { 0031 KDirWatch::self()->addDir(Latte::configPath() + "/latte/templates", KDirWatch::WatchFiles); 0032 connect(KDirWatch::self(), &KDirWatch::created, this, &Manager::onCustomTemplatesCountChanged); 0033 connect(KDirWatch::self(), &KDirWatch::deleted, this, &Manager::onCustomTemplatesCountChanged); 0034 connect(KDirWatch::self(), &KDirWatch::dirty, this, &Manager::onCustomTemplatesCountChanged); 0035 } 0036 0037 Manager::~Manager() 0038 { 0039 } 0040 0041 void Manager::init() 0042 { 0043 connect(this, &Manager::viewTemplatesChanged, m_corona->layoutsManager(), &Latte::Layouts::Manager::viewTemplatesChanged); 0044 0045 initLayoutTemplates(); 0046 initViewTemplates(); 0047 } 0048 0049 void Manager::initLayoutTemplates() 0050 { 0051 m_layoutTemplates.clear(); 0052 initLayoutTemplates(m_corona->kPackage().filePath("templates")); 0053 initLayoutTemplates(Latte::configPath() + "/latte/templates"); 0054 emit layoutTemplatesChanged(); 0055 } 0056 0057 void Manager::initViewTemplates() 0058 { 0059 m_viewTemplates.clear(); 0060 initViewTemplates(m_corona->kPackage().filePath("templates")); 0061 initViewTemplates(Latte::configPath() + "/latte/templates"); 0062 emit viewTemplatesChanged(); 0063 } 0064 0065 void Manager::initLayoutTemplates(const QString &path) 0066 { 0067 QDir templatesDir(path); 0068 QStringList filter; 0069 filter.append(QString("*.layout.latte")); 0070 QStringList templates = templatesDir.entryList(filter, QDir::Files | QDir::Hidden | QDir::NoSymLinks); 0071 0072 for (int i=0; i<templates.count(); ++i) { 0073 QString templatePath = templatesDir.path() + "/" + templates[i]; 0074 if (!m_layoutTemplates.containsId(templatePath)) { 0075 CentralLayout layouttemplate(this, templatePath); 0076 0077 Data::Layout tdata = layouttemplate.data(); 0078 tdata.isTemplate = true; 0079 0080 if (tdata.name == DEFAULTLAYOUTTEMPLATENAME || tdata.name == EMPTYLAYOUTTEMPLATENAME) { 0081 QByteArray templateNameChars = tdata.name.toUtf8(); 0082 tdata.name = i18n(templateNameChars); 0083 } 0084 0085 m_layoutTemplates << tdata; 0086 } 0087 } 0088 } 0089 0090 void Manager::initViewTemplates(const QString &path) 0091 { 0092 bool istranslated = (m_corona->kPackage().filePath("templates") == path); 0093 0094 QDir templatesDir(path); 0095 QStringList filter; 0096 filter.append(QString("*.view.latte")); 0097 QStringList templates = templatesDir.entryList(filter, QDir::Files | QDir::Hidden | QDir::NoSymLinks); 0098 0099 for (int i=0; i<templates.count(); ++i) { 0100 QString templatePath = templatesDir.path() + "/" + templates[i]; 0101 0102 if (!m_viewTemplates.containsId(templatePath)) { 0103 Data::Generic vdata; 0104 vdata.id = templatePath; 0105 QString tname = QFileInfo(templatePath).baseName(); 0106 0107 if (istranslated) { 0108 QByteArray tnamechars = tname.toUtf8(); 0109 vdata.name = i18nc("view template name", tnamechars); 0110 } else { 0111 vdata.name = tname; 0112 } 0113 0114 m_viewTemplates << vdata; 0115 } 0116 } 0117 } 0118 0119 Data::Layout Manager::layoutTemplateForName(const QString &layoutName) 0120 { 0121 if (m_layoutTemplates.containsName(layoutName)) { 0122 QString layoutid = m_layoutTemplates.idForName(layoutName); 0123 return m_layoutTemplates[layoutid]; 0124 } 0125 0126 return Data::Layout(); 0127 } 0128 0129 Data::LayoutsTable Manager::layoutTemplates() 0130 { 0131 Data::LayoutsTable templates; 0132 0133 QString id = m_layoutTemplates.idForName(i18n(DEFAULTLAYOUTTEMPLATENAME)); 0134 templates << m_layoutTemplates[id]; 0135 id = m_layoutTemplates.idForName(i18n(EMPTYLAYOUTTEMPLATENAME)); 0136 templates << m_layoutTemplates[id]; 0137 0138 for (int i=0; i<m_layoutTemplates.rowCount(); ++i) { 0139 if ( m_layoutTemplates[i].name != i18n(DEFAULTLAYOUTTEMPLATENAME) 0140 && m_layoutTemplates[i].name != i18n(EMPTYLAYOUTTEMPLATENAME) 0141 && m_layoutTemplates[i].name != Layout::MULTIPLELAYOUTSHIDDENNAME) { 0142 templates << m_layoutTemplates[i]; 0143 } 0144 } 0145 0146 return templates; 0147 } 0148 0149 Data::GenericBasicTable Manager::viewTemplates() 0150 { 0151 return m_viewTemplates; 0152 } 0153 0154 QString Manager::newLayout(QString layoutName, QString layoutTemplate) 0155 { 0156 if (!m_layoutTemplates.containsName(layoutTemplate)) { 0157 return QString(); 0158 } 0159 0160 if (layoutName.isEmpty()) { 0161 layoutName = Layouts::Importer::uniqueLayoutName(layoutTemplate); 0162 } else { 0163 layoutName = Layouts::Importer::uniqueLayoutName(layoutName); 0164 } 0165 0166 QString newLayoutPath = Layouts::Importer::layoutUserFilePath(layoutName); 0167 0168 Data::Layout dlayout = layoutTemplateForName(layoutTemplate); 0169 QFile(dlayout.id).copy(newLayoutPath); 0170 qDebug() << "adding layout : " << layoutName << " based on layout template:" << layoutTemplate; 0171 0172 emit newLayoutAdded(newLayoutPath); 0173 0174 return newLayoutPath; 0175 } 0176 0177 bool Manager::exportTemplate(const QString &originFile, const QString &destinationFile, const Data::AppletsTable &approvedApplets) 0178 { 0179 return Latte::Layouts::Storage::self()->exportTemplate(originFile, destinationFile, approvedApplets); 0180 } 0181 0182 bool Manager::exportTemplate(const Latte::View *view, const QString &destinationFile, const Data::AppletsTable &approvedApplets) 0183 { 0184 return Latte::Layouts::Storage::self()->exportTemplate(view->layout(), view->containment(), destinationFile, approvedApplets); 0185 } 0186 0187 void Manager::onCustomTemplatesCountChanged(const QString &file) 0188 { 0189 if (file.startsWith(Latte::configPath() + "/latte/templates")) { 0190 if (file.endsWith(".layout.latte")) { 0191 initLayoutTemplates(); 0192 } else if (file.endsWith(".view.latte")) { 0193 initViewTemplates(); 0194 } 0195 } 0196 } 0197 0198 void Manager::importSystemLayouts() 0199 { 0200 for (int i=0; i<m_layoutTemplates.rowCount(); ++i) { 0201 if (m_layoutTemplates[i].isSystemTemplate()) { 0202 QString userLayoutPath = Layouts::Importer::layoutUserFilePath(m_layoutTemplates[i].name); 0203 0204 if (!QFile(userLayoutPath).exists()) { 0205 QFile(m_layoutTemplates[i].id).copy(userLayoutPath); 0206 qDebug() << "adding layout : " << userLayoutPath << " based on layout template:" << m_layoutTemplates[i].name; 0207 } 0208 } 0209 } 0210 } 0211 0212 QString Manager::proposedTemplateAbsolutePath(QString templateFilename) 0213 { 0214 QString tempfilename = templateFilename; 0215 0216 if (tempfilename.endsWith(".layout.latte")) { 0217 QString clearedname = tempfilename.chopped(QString(".layout.latte").size()); 0218 tempfilename = uniqueLayoutTemplateName(clearedname) + ".layout.latte"; 0219 } else if (tempfilename.endsWith(".view.latte")) { 0220 QString clearedname = tempfilename.chopped(QString(".view.latte").size()); 0221 tempfilename = uniqueViewTemplateName(clearedname) + ".view.latte"; 0222 } 0223 0224 return QString(Latte::configPath() + "/latte/templates/" + tempfilename); 0225 } 0226 0227 bool Manager::hasCustomLayoutTemplate(const QString &templateName) const 0228 { 0229 for (int i=0; i<m_layoutTemplates.rowCount(); ++i) { 0230 if (m_layoutTemplates[i].name == templateName && !m_layoutTemplates[i].isSystemTemplate()) { 0231 return true; 0232 } 0233 } 0234 0235 return false; 0236 } 0237 0238 bool Manager::hasLayoutTemplate(const QString &templateName) const 0239 { 0240 return m_layoutTemplates.containsName(templateName); 0241 } 0242 0243 bool Manager::hasViewTemplate(const QString &templateName) const 0244 { 0245 return m_viewTemplates.containsName(templateName); 0246 } 0247 0248 QString Manager::viewTemplateFilePath(const QString templateName) const 0249 { 0250 if (m_viewTemplates.containsName(templateName)) { 0251 return m_viewTemplates.idForName(templateName); 0252 } 0253 0254 return QString(); 0255 } 0256 0257 void Manager::installCustomLayoutTemplate(const QString &templateFilePath) 0258 { 0259 if (!templateFilePath.endsWith(".layout.latte")) { 0260 return; 0261 } 0262 0263 QString layoutName = QFileInfo(templateFilePath).baseName(); 0264 0265 QString destinationFilePath = Latte::configPath() + "/latte/templates/" + layoutName + ".layout.latte"; 0266 0267 if (hasCustomLayoutTemplate(layoutName)) { 0268 QFile(destinationFilePath).remove(); 0269 } 0270 0271 QFile(templateFilePath).copy(destinationFilePath); 0272 } 0273 0274 QString Manager::uniqueLayoutTemplateName(QString name) const 0275 { 0276 int pos_ = name.lastIndexOf(QRegExp(QString(" - [0-9]+"))); 0277 0278 if (hasLayoutTemplate(name) && pos_ > 0) { 0279 name = name.left(pos_); 0280 } 0281 0282 int i = 2; 0283 0284 QString namePart = name; 0285 0286 while (hasLayoutTemplate(name)) { 0287 name = namePart + " - " + QString::number(i); 0288 i++; 0289 } 0290 0291 return name; 0292 } 0293 0294 QString Manager::uniqueViewTemplateName(QString name) const 0295 { 0296 int pos_ = name.lastIndexOf(QRegExp(QString(" - [0-9]+"))); 0297 0298 if (hasViewTemplate(name) && pos_ > 0) { 0299 name = name.left(pos_); 0300 } 0301 0302 int i = 2; 0303 0304 QString namePart = name; 0305 0306 while (hasViewTemplate(name)) { 0307 name = namePart + " - " + QString::number(i); 0308 i++; 0309 } 0310 0311 return name; 0312 } 0313 0314 QString Manager::templateName(const QString &filePath) 0315 { 0316 int lastSlash = filePath.lastIndexOf("/"); 0317 QString tempFilePath = filePath; 0318 QString templatename = tempFilePath.remove(0, lastSlash + 1); 0319 0320 QString extension(".layout.latte"); 0321 int ext = templatename.lastIndexOf(extension); 0322 if (ext>0) { 0323 templatename = templatename.remove(ext, extension.size()); 0324 } else { 0325 extension = ".view.latte"; 0326 ext = templatename.lastIndexOf(extension); 0327 templatename = templatename.remove(ext,extension.size()); 0328 } 0329 0330 return templatename; 0331 } 0332 0333 //! it is used in order to provide translations for system templates 0334 void Manager::exposeTranslatedTemplateNames() 0335 { 0336 //! layout templates default names 0337 i18nc("default layout template name", "Default"); 0338 i18nc("empty layout template name", "Empty"); 0339 0340 //! dock/panel templates default names 0341 i18nc("view template name", "Default Dock"); 0342 i18nc("view template name", "Default Panel"); 0343 i18nc("view template name", "Empty Panel"); 0344 } 0345 0346 } 0347 }