File indexing completed on 2024-05-12 05:13:29

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