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 // }