File indexing completed on 2024-04-28 15:14:03

0001 /***************************************************************************
0002     File                 : ThemeHandler.cpp
0003     Project              : LabPlot
0004     Description          : Widget for handling saving and loading of themes
0005     --------------------------------------------------------------------
0006     Copyright            : (C) 2016 Prakriti Bhardwaj (p_bhardwaj14@informatik.uni-kl.de)
0007     Copyright            : (C) 2016-2017 Alexander Semke (alexander.semke@web.de)
0008     Copyright            : (C) 2018 Stefan Gerlach (stefan.gerlach@uni.kn)
0009 
0010  ***************************************************************************/
0011 
0012 /***************************************************************************
0013  *                                                                         *
0014  *  This program is free software; you can redistribute it and/or modify   *
0015  *  it under the terms of the GNU General Public License as published by   *
0016  *  the Free Software Foundation; either version 2 of the License, or      *
0017  *  (at your option) any later version.                                    *
0018  *                                                                         *
0019  *  This program is distributed in the hope that it will be useful,        *
0020  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0021  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0022  *  GNU General Public License for more details.                           *
0023  *                                                                         *
0024  *   You should have received a copy of the GNU General Public License     *
0025  *   along with this program; if not, write to the Free Software           *
0026  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0027  *   Boston, MA  02110-1301  USA                                           *
0028  *                                                                         *
0029  ***************************************************************************/
0030 
0031 #include "ThemeHandler.h"
0032 #include "widgets/ThemesWidget.h"
0033 #include "backend/lib/macros.h"
0034 
0035 #include <QDir>
0036 #include <QDirIterator>
0037 #include <QFileInfo>
0038 #include <QHBoxLayout>
0039 #include <QMenu>
0040 #include <QPushButton>
0041 #include <QWidgetAction>
0042 
0043 #include <KConfig>
0044 #include <KConfigGroup>
0045 #include <KLocalizedString>
0046 
0047 #include <KMessageBox>
0048 // #include <KNS3/UploadDialog>
0049 
0050 /*!
0051   \class ThemeHandler
0052   \brief Provides a widget with buttons for loading of themes.
0053 
0054   Emits \c loadConfig() signal that have to be connected
0055   to the appropriate slots in the backend (plot widgets)
0056 
0057   \ingroup kdefrontend
0058 */
0059 
0060 ThemeHandler::ThemeHandler(QWidget* parent) : QWidget(parent) {
0061     auto* horizontalLayout = new QHBoxLayout(this);
0062     horizontalLayout->setSpacing(0);
0063     horizontalLayout->setMargin(0);
0064 
0065     m_pbLoadTheme = new QPushButton(this);
0066     horizontalLayout->addWidget(m_pbLoadTheme);
0067     m_pbLoadTheme->setText(i18n("Apply Theme"));
0068 
0069 //  pbSaveTheme = new QPushButton(this);
0070 //  horizontalLayout->addWidget(pbSaveTheme);
0071 //  pbSaveTheme->setText(i18n("Save Theme"));
0072 
0073     /*
0074         pbPublishTheme = new QPushButton(this);
0075         horizontalLayout->addWidget(pbPublishTheme);
0076         pbPublishTheme->setText("Publish Theme");
0077         pbPublishTheme->setEnabled(false);
0078     */
0079 
0080     connect(m_pbLoadTheme, &QPushButton::clicked, this, &ThemeHandler::showPanel);
0081 //  connect( pbSaveTheme, SIGNAL(clicked()), this, SLOT(saveMenu()));
0082 //  connect( pbPublishTheme, SIGNAL(clicked()), this, SLOT(publishThemes()));
0083 
0084     m_themeList = themeList();
0085 
0086     m_pbLoadTheme->setEnabled(!m_themeList.isEmpty());
0087 }
0088 
0089 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0090 
0091 /*!
0092  * get list of all theme files (full path)
0093  */
0094 QStringList ThemeHandler::themeList() {
0095     DEBUG("ThemeHandler::themeList()");
0096     // find all available themes files (system wide and user specific local files)
0097     QStringList dirs = QStandardPaths::locateAll(QStandardPaths::DataLocation, "themes", QStandardPaths::LocateDirectory);
0098 
0099     QStringList themes;
0100     for (const auto& dir : dirs) {
0101         QDirIterator it(dir, QStringList() << QStringLiteral("*"), QDir::Files);
0102         while (it.hasNext())
0103             themes.append(it.next());
0104     }
0105 
0106     if (!themes.isEmpty())
0107         DEBUG(" first theme path: " << STDSTRING(themes.first()));
0108 
0109     return themes;
0110 }
0111 
0112 /*!
0113  * get list of all theme names
0114  */
0115 QStringList ThemeHandler::themes() {
0116     DEBUG("ThemeHandler::themes()");
0117     QStringList themePaths = themeList();
0118 
0119     QStringList themes;
0120     for (int i = 0; i < themePaths.size(); ++i) {
0121         QFileInfo fileinfo(themePaths.at(i));
0122         themes.append(fileinfo.fileName().split('.').at(0));
0123     }
0124 
0125     if (!themes.isEmpty()) {
0126         DEBUG(" first theme: " << STDSTRING(themes.first()));
0127         QDEBUG("    themes = " << themes);
0128     }
0129 
0130     return themes;
0131 }
0132 
0133 /*!
0134  * get path for theme of name 'name'
0135  */
0136 const QString ThemeHandler::themeFilePath(const QString& name) {
0137     DEBUG("ThemeHandler::themeFilePath() name = " << STDSTRING(name));
0138     QStringList themePaths = themeList();
0139 
0140     for (int i = 0; i < themePaths.size(); ++i) {
0141         const QString& path = themePaths.at(i);
0142         const QString& fileName = QFileInfo(path).fileName();
0143         if (fileName == name) {
0144             DEBUG(" theme \"" << STDSTRING(name) << "\" path: " << STDSTRING(path));
0145             return path;
0146         }
0147     }
0148 
0149     return QString();
0150 }
0151 
0152 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0153 
0154 void ThemeHandler::setCurrentTheme(const QString& name) {
0155     if (!name.isEmpty()) {
0156         m_pbLoadTheme->setText(i18n("Apply theme [active '%1']", name));
0157         m_pbLoadTheme->setToolTip(i18n("Theme '%1' is active. Click on the button to change the theme.", name));
0158     } else {
0159         m_pbLoadTheme->setText(i18n("Apply Theme"));
0160         m_pbLoadTheme->setToolTip(i18n("No theme is active. Click on the button to select a theme."));
0161     }
0162 
0163     m_currentTheme = name;
0164 }
0165 
0166 void ThemeHandler::loadSelected(const QString& name) {
0167     emit loadThemeRequested(name);
0168     this->setCurrentTheme(name);
0169 
0170     if (!name.isEmpty())
0171         emit info( i18n("Theme \"%1\" was loaded.", name) );
0172     else
0173         emit info( i18n("Theming deactivated.") );
0174 
0175     //in case a local theme file was loaded (we have write access), allow to publish it
0176     //TODO: activate this later
0177 //  if (KStandardDirs::checkAccess(themeFilePath, W_OK)) {
0178 //      pbPublishTheme->setEnabled(true);
0179 //      m_currentLocalTheme = themeFilePath.right(themeFilePath.length() - themeFilePath.lastIndexOf(QLatin1String("/")) - 1);
0180 //  } else {
0181 //      pbPublishTheme->setEnabled(false);
0182 //      m_currentLocalTheme.clear();
0183 //  }
0184 }
0185 
0186 void ThemeHandler::showPanel() {
0187     QMenu menu;
0188     ThemesWidget themeWidget(&menu);
0189     themeWidget.setFixedMode();
0190     connect(&themeWidget, &ThemesWidget::themeSelected, this, &ThemeHandler::loadSelected);
0191     connect(&themeWidget, &ThemesWidget::themeSelected, &menu, &QMenu::close);
0192     connect(&themeWidget, &ThemesWidget::canceled, &menu, &QMenu::close);
0193 
0194     auto* widgetAction = new QWidgetAction(this);
0195     widgetAction->setDefaultWidget(&themeWidget);
0196     menu.addAction(widgetAction);
0197 
0198     QPoint pos(-menu.sizeHint().width()+m_pbLoadTheme->width(),-menu.sizeHint().height());
0199     menu.exec(m_pbLoadTheme->mapToGlobal(pos));
0200 }
0201 
0202 // void ThemeHandler::saveMenu() {
0203 //  QMenu menu;
0204 //  menu.addSection(i18n("Save As"));
0205 //
0206 //  // add editable action
0207 //  QWidgetAction* widgetAction = new QWidgetAction(this);
0208 //  QFrame* frame = new QFrame(this);
0209 //  QHBoxLayout* layout = new QHBoxLayout(frame);
0210 //
0211 //  QLabel* label = new QLabel(i18n("Enter name:"), frame);
0212 //  layout->addWidget(label);
0213 //
0214 //  QLineEdit* leFilename = new QLineEdit(QString(), frame);
0215 //  layout->addWidget(leFilename);
0216 //  connect(leFilename, SIGNAL(returnPressed(QString)), this, SLOT(saveNewSelected(QString)));
0217 //  connect(leFilename, SIGNAL(returnPressed(QString)), &menu, SLOT(close()));
0218 //
0219 //  widgetAction->setDefaultWidget(frame);
0220 //  menu.addAction(widgetAction);
0221 //
0222 //     QPoint pos(-menu.sizeHint().width() + m_pbSaveTheme->width(), -menu.sizeHint().height());
0223 //     menu.exec(m_pbSaveTheme->mapToGlobal(pos));
0224 //  leFilename->setFocus();
0225 // }
0226 
0227 // void ThemeHandler::saveNewSelected(const QString& filename) {
0228 //  KConfig config(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + '/' + "themes" + '/' + filename, KConfig::SimpleConfig);
0229 //  emit saveThemeRequested(config);
0230 //  emit info( i18n("New theme \"%1\" was saved.", filename) );
0231 //
0232 //  m_currentLocalTheme = filename;
0233 //  m_themeList.append(config.name());
0234 //
0235 //  //enable the publish button so the newly created theme can be published
0236 //  //TODO: enable this later
0237 // //   pbPublishTheme->setEnabled(true);
0238 // }
0239 
0240 /*!
0241     opens the dialog to upload the currently selected local theme.
0242     The publish button is only enabled if a local theme was loaded or one of the themes was modified and saved locally.
0243  */
0244 // void ThemeHandler::publishThemes() {
0245 //  int ret = KMessageBox::questionYesNo(this,
0246 //          i18n("Do you want to upload your theme %1 to public web server?", m_currentLocalTheme),
0247 //          i18n("Publish Theme"));
0248 //  if (ret != KMessageBox::Yes)
0249 //      return;
0250 //
0251 //  // creating upload dialog
0252 //  KNS3::UploadDialog dialog("labplot2_themes.knsrc", this);
0253 //  dialog.setUploadFile(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + '/' + "themes" + '/' + m_currentLocalTheme);
0254 //  dialog.setUploadName(m_currentLocalTheme);
0255 //  //dialog.setDescription(); TODO: allow the user to provide a short description for the theme to be uploaded
0256 //  dialog.exec();
0257 // }