File indexing completed on 2024-05-12 05:13:28
0001 /* 0002 SPDX-FileCopyrightText: 2015-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "themeeditormainwindow.h" 0008 #include "contactprintthemeconfiguredialog.h" 0009 #include "managethemes.h" 0010 #include "newthemedialog.h" 0011 #include "themeeditorpage.h" 0012 0013 #include <KActionCollection> 0014 #include <KConfigGroup> 0015 #include <KLocalizedString> 0016 #include <KMessageBox> 0017 #include <KRecentFilesAction> 0018 #include <KStandardAction> 0019 #include <QAction> 0020 #include <QFileDialog> 0021 0022 #include <KAuthorized> 0023 #include <KSharedConfig> 0024 #include <QApplication> 0025 #include <QCloseEvent> 0026 #include <QPointer> 0027 #include <QStandardPaths> 0028 0029 ThemeEditorMainWindow::ThemeEditorMainWindow() 0030 : KXmlGuiWindow() 0031 { 0032 setupActions(); 0033 setupGUI(); 0034 updateActions(); 0035 readConfig(); 0036 } 0037 0038 ThemeEditorMainWindow::~ThemeEditorMainWindow() = default; 0039 0040 void ThemeEditorMainWindow::writeConfig() 0041 { 0042 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0043 0044 KConfigGroup group = config->group(QStringLiteral("ThemeEditorMainWindow")); 0045 group.writeEntry("Size", size()); 0046 mRecentFileAction->saveEntries(group); 0047 } 0048 0049 void ThemeEditorMainWindow::readConfig() 0050 { 0051 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0052 KConfigGroup group = KConfigGroup(config, QStringLiteral("ThemeEditorMainWindow")); 0053 const QSize sizeDialog = group.readEntry("Size", QSize(600, 400)); 0054 if (sizeDialog.isValid()) { 0055 resize(sizeDialog); 0056 } 0057 } 0058 0059 void ThemeEditorMainWindow::updateActions() 0060 { 0061 const bool projectDirectoryIsEmpty = (mThemeEditor != nullptr); 0062 mAddExtraPage->setEnabled(projectDirectoryIsEmpty); 0063 mCloseAction->setEnabled(projectDirectoryIsEmpty); 0064 if (mUploadTheme) { 0065 mUploadTheme->setEnabled(projectDirectoryIsEmpty); 0066 } 0067 mSaveAction->setEnabled(projectDirectoryIsEmpty); 0068 mInstallTheme->setEnabled(projectDirectoryIsEmpty); 0069 mInsertFile->setEnabled(projectDirectoryIsEmpty); 0070 mUpdateView->setEnabled(projectDirectoryIsEmpty); 0071 mSaveAsAction->setEnabled(projectDirectoryIsEmpty); 0072 } 0073 0074 void ThemeEditorMainWindow::setupActions() 0075 { 0076 mRecentFileAction = new KRecentFilesAction(i18n("Load Recent Theme..."), this); 0077 connect(mRecentFileAction, &KRecentFilesAction::urlSelected, this, &ThemeEditorMainWindow::slotThemeSelected); 0078 actionCollection()->addAction(QStringLiteral("load_recent_theme"), mRecentFileAction); 0079 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0080 KConfigGroup groupConfig = config->group(QStringLiteral("ThemeEditorMainWindow")); 0081 mRecentFileAction->loadEntries(groupConfig); 0082 0083 mAddExtraPage = new QAction(i18n("Add Extra Page..."), this); 0084 connect(mAddExtraPage, &QAction::triggered, this, &ThemeEditorMainWindow::slotAddExtraPage); 0085 actionCollection()->addAction(QStringLiteral("add_extra_page"), mAddExtraPage); 0086 if (KAuthorized::authorize(QStringLiteral("ghns"))) { 0087 mUploadTheme = new QAction(QIcon::fromTheme(QStringLiteral("get-hot-new-stuff")), i18n("Upload theme..."), this); 0088 connect(mUploadTheme, &QAction::triggered, this, &ThemeEditorMainWindow::slotUploadTheme); 0089 actionCollection()->addAction(QStringLiteral("upload_theme"), mUploadTheme); 0090 } 0091 0092 mNewThemeAction = KStandardAction::openNew(this, &ThemeEditorMainWindow::slotNewTheme, actionCollection()); 0093 mNewThemeAction->setText(i18n("New theme...")); 0094 0095 mOpenAction = KStandardAction::open(this, &ThemeEditorMainWindow::slotOpenTheme, actionCollection()); 0096 mOpenAction->setText(i18n("Open theme...")); 0097 mSaveAction = KStandardAction::save(this, &ThemeEditorMainWindow::slotSaveTheme, actionCollection()); 0098 mSaveAction->setText(i18n("Save theme")); 0099 0100 mSaveAsAction = KStandardAction::saveAs(this, &ThemeEditorMainWindow::slotSaveAsTheme, actionCollection()); 0101 mSaveAsAction->setText(i18n("Save theme as...")); 0102 0103 mCloseAction = KStandardAction::close(this, &ThemeEditorMainWindow::slotCloseTheme, actionCollection()); 0104 KStandardAction::quit(this, &ThemeEditorMainWindow::slotQuitApp, actionCollection()); 0105 KStandardAction::preferences(this, &ThemeEditorMainWindow::slotConfigure, actionCollection()); 0106 0107 mInstallTheme = new QAction(i18n("Install theme"), this); 0108 actionCollection()->addAction(QStringLiteral("install_theme"), mInstallTheme); 0109 connect(mInstallTheme, &QAction::triggered, this, &ThemeEditorMainWindow::slotInstallTheme); 0110 0111 mInsertFile = new QAction(i18n("Insert File..."), this); 0112 actionCollection()->addAction(QStringLiteral("insert_file"), mInsertFile); 0113 connect(mInsertFile, &QAction::triggered, this, &ThemeEditorMainWindow::slotInsertFile); 0114 0115 mManageTheme = new QAction(i18n("Manage themes..."), this); 0116 connect(mManageTheme, &QAction::triggered, this, &ThemeEditorMainWindow::slotManageTheme); 0117 actionCollection()->addAction(QStringLiteral("manage_themes"), mManageTheme); 0118 0119 mUpdateView = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), i18n("Update view"), this); 0120 actionCollection()->setDefaultShortcut(mUpdateView, QKeySequence(Qt::Key_F5)); 0121 connect(mUpdateView, &QAction::triggered, this, &ThemeEditorMainWindow::slotUpdateView); 0122 actionCollection()->addAction(QStringLiteral("update_view"), mUpdateView); 0123 } 0124 0125 void ThemeEditorMainWindow::slotManageTheme() 0126 { 0127 QPointer<GrantleeThemeEditor::ManageThemes> dialog = new GrantleeThemeEditor::ManageThemes(QStringLiteral("kaddressbook/printing/themes/"), this); 0128 dialog->exec(); 0129 delete dialog; 0130 } 0131 0132 void ThemeEditorMainWindow::slotInsertFile() 0133 { 0134 mThemeEditor->insertFile(); 0135 } 0136 0137 void ThemeEditorMainWindow::slotConfigure() 0138 { 0139 QPointer<ContactPrintThemeConfigureDialog> dialog = new ContactPrintThemeConfigureDialog(this); 0140 if (dialog->exec()) { 0141 if (mThemeEditor) { 0142 mThemeEditor->reloadConfig(); 0143 } 0144 } 0145 delete dialog; 0146 } 0147 0148 void ThemeEditorMainWindow::slotInstallTheme() 0149 { 0150 // Save before installing :) 0151 if (slotSaveTheme()) { 0152 const QString localThemePath = 0153 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/kaddressbook/printing/themes"); 0154 if (QDir().mkpath(localThemePath)) { 0155 mThemeEditor->installTheme(localThemePath); 0156 } 0157 } 0158 } 0159 0160 void ThemeEditorMainWindow::slotUploadTheme() 0161 { 0162 // Save before upload :) 0163 if (slotSaveTheme()) { 0164 mThemeEditor->uploadTheme(); 0165 } 0166 } 0167 0168 bool ThemeEditorMainWindow::slotSaveTheme() 0169 { 0170 bool result = false; 0171 if (mThemeEditor) { 0172 result = mThemeEditor->saveTheme(false); 0173 mSaveAction->setEnabled(!result); 0174 } 0175 return result; 0176 } 0177 0178 void ThemeEditorMainWindow::slotCloseTheme() 0179 { 0180 saveCurrentProject(SaveAndCloseTheme); 0181 } 0182 0183 void ThemeEditorMainWindow::slotOpenTheme() 0184 { 0185 if (!saveCurrentProject(SaveOnly)) { 0186 return; 0187 } 0188 0189 const QString directory = QFileDialog::getExistingDirectory(this, i18n("Select theme directory")); 0190 if (directory.isEmpty()) { 0191 return; 0192 } 0193 closeThemeEditor(); 0194 if (loadTheme(directory)) { 0195 mRecentFileAction->addUrl(QUrl::fromLocalFile(directory)); 0196 } 0197 mSaveAction->setEnabled(false); 0198 } 0199 0200 bool ThemeEditorMainWindow::loadTheme(const QString &directory) 0201 { 0202 if (!directory.isEmpty()) { 0203 const QString filename = directory + QLatin1StringView("/theme.themerc"); 0204 if (!QFileInfo::exists(filename)) { 0205 KMessageBox::error(this, i18n("Directory does not contain a theme file. We cannot load theme.")); 0206 return false; 0207 } 0208 0209 mThemeEditor = new ThemeEditorPage(QString(), QString()); 0210 connect(mThemeEditor, &ThemeEditorPage::changed, mSaveAction, &QAction::setEnabled); 0211 connect(mThemeEditor, &ThemeEditorPage::canInsertFile, this, &ThemeEditorMainWindow::slotCanInsertFile); 0212 mThemeEditor->loadTheme(filename); 0213 setCentralWidget(mThemeEditor); 0214 updateActions(); 0215 } 0216 return true; 0217 } 0218 0219 void ThemeEditorMainWindow::slotAddExtraPage() 0220 { 0221 if (mThemeEditor) { 0222 mThemeEditor->addExtraPage(); 0223 } 0224 } 0225 0226 void ThemeEditorMainWindow::closeThemeEditor() 0227 { 0228 delete mThemeEditor; 0229 mThemeEditor = nullptr; 0230 setCentralWidget(nullptr); 0231 updateActions(); 0232 } 0233 0234 bool ThemeEditorMainWindow::saveCurrentProject(ActionSaveTheme act) 0235 { 0236 if (mThemeEditor) { 0237 if (!mThemeEditor->saveTheme()) { 0238 return false; 0239 } 0240 } 0241 switch (act) { 0242 case SaveOnly: 0243 break; 0244 case SaveAndCloseTheme: 0245 closeThemeEditor(); 0246 break; 0247 case SaveAndCreateNewTheme: { 0248 delete mThemeEditor; 0249 mThemeEditor = nullptr; 0250 QPointer<GrantleeThemeEditor::NewThemeDialog> dialog = new GrantleeThemeEditor::NewThemeDialog(this); 0251 QString newTheme; 0252 QString projectDirectory; 0253 if (dialog->exec()) { 0254 newTheme = dialog->themeName(); 0255 projectDirectory = dialog->directory(); 0256 } 0257 if (!projectDirectory.isEmpty()) { 0258 mRecentFileAction->addUrl(QUrl::fromLocalFile(projectDirectory)); 0259 mThemeEditor = new ThemeEditorPage(projectDirectory, newTheme); 0260 connect(mThemeEditor, &ThemeEditorPage::changed, mSaveAction, &QAction::setEnabled); 0261 connect(mThemeEditor, &ThemeEditorPage::canInsertFile, this, &ThemeEditorMainWindow::slotCanInsertFile); 0262 setCentralWidget(mThemeEditor); 0263 } else { 0264 setCentralWidget(nullptr); 0265 } 0266 delete dialog; 0267 updateActions(); 0268 break; 0269 } 0270 } 0271 0272 return true; 0273 } 0274 0275 void ThemeEditorMainWindow::slotNewTheme() 0276 { 0277 saveCurrentProject(SaveAndCreateNewTheme); 0278 } 0279 0280 void ThemeEditorMainWindow::closeEvent(QCloseEvent *e) 0281 { 0282 if (!saveCurrentProject(SaveAndCloseTheme)) { 0283 e->ignore(); 0284 } else { 0285 writeConfig(); 0286 e->accept(); 0287 } 0288 } 0289 0290 void ThemeEditorMainWindow::slotQuitApp() 0291 { 0292 if (saveCurrentProject(SaveAndCloseTheme)) { 0293 writeConfig(); 0294 qApp->quit(); 0295 } 0296 } 0297 0298 void ThemeEditorMainWindow::slotUpdateView() 0299 { 0300 if (mThemeEditor) { 0301 mThemeEditor->saveTheme(false); 0302 mThemeEditor->updatePreview(); 0303 } 0304 } 0305 0306 void ThemeEditorMainWindow::slotCanInsertFile(bool b) 0307 { 0308 mInsertFile->setEnabled(b); 0309 } 0310 0311 void ThemeEditorMainWindow::slotThemeSelected(const QUrl &url) 0312 { 0313 if (!saveCurrentProject(SaveAndCloseTheme)) { 0314 return; 0315 } 0316 loadTheme(url.path()); 0317 mSaveAction->setEnabled(false); 0318 } 0319 0320 void ThemeEditorMainWindow::slotSaveAsTheme() 0321 { 0322 const QString directory = QFileDialog::getExistingDirectory(this, i18n("Select theme directory")); 0323 if (!directory.isEmpty()) { 0324 if (mThemeEditor) { 0325 mThemeEditor->saveThemeAs(directory); 0326 } 0327 } 0328 } 0329 0330 #include "moc_themeeditormainwindow.cpp"