File indexing completed on 2024-04-21 03:51:08
0001 /* 0002 SPDX-FileCopyrightText: 2007 Mauricio Piacentini <mauricio@tabuleiro.com> 0003 SPDX-FileCopyrightText: 2007 Matt Williams <matt@milliams.com> 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kgamethemeselector.h" 0008 0009 #include <KConfigSkeleton> 0010 #include <KLocalizedString> 0011 #include <QDirIterator> 0012 0013 #include "kgametheme.h" 0014 #include "ui_kgamethemeselector.h" 0015 0016 class KGameThemeSelectorPrivate 0017 { 0018 KGameThemeSelector *q_ptr; 0019 Q_DECLARE_PUBLIC(KGameThemeSelector) 0020 0021 public: 0022 KGameThemeSelectorPrivate(KGameThemeSelector *parent) 0023 : q_ptr(parent) 0024 { 0025 } 0026 ~KGameThemeSelectorPrivate() 0027 { 0028 qDeleteAll(themeMap); 0029 } 0030 0031 QMap<QString, KGameTheme *> themeMap; 0032 Ui::KGameThemeSelectorBase ui; 0033 QString lookupDirectory; 0034 QString groupName; 0035 0036 void setupData(KConfigSkeleton *config, KGameThemeSelector::NewStuffState knsflags); 0037 void findThemes(const QString &initialSelection); 0038 0039 // private slots 0040 void _k_updatePreview(); 0041 void _k_updateThemeList(const QString &strTheme); 0042 }; 0043 0044 KGameThemeSelector::KGameThemeSelector(QWidget *parent, 0045 KConfigSkeleton *aconfig, 0046 KGameThemeSelector::NewStuffState knsflags, 0047 const QString &groupName, 0048 const QString &directory) 0049 : QWidget(parent) 0050 , d_ptr(new KGameThemeSelectorPrivate(this)) 0051 { 0052 d_func()->lookupDirectory = directory; 0053 d_func()->groupName = groupName; 0054 d_func()->setupData(aconfig, knsflags); 0055 } 0056 0057 KGameThemeSelector::~KGameThemeSelector() 0058 { 0059 delete d_ptr; 0060 } 0061 0062 void KGameThemeSelectorPrivate::setupData(KConfigSkeleton *aconfig, KGameThemeSelector::NewStuffState knsflags) 0063 { 0064 ui.setupUi(q_ptr); 0065 ui.getNewButton->setConfigFile(QStringLiteral("parley-themes.knsrc")); 0066 0067 // The lineEdit widget holds our theme path for automatic connection via KConfigXT. 0068 // But the user should not manipulate it directly, so we hide it. 0069 ui.kcfg_Theme->hide(); 0070 q_func()->connect(ui.kcfg_Theme, SIGNAL(textChanged(QString)), q_ptr, SLOT(_k_updateThemeList(QString))); 0071 0072 // Disable KNS button? 0073 if (knsflags == KGameThemeSelector::NewStuffDisableDownload) { 0074 ui.getNewButton->hide(); 0075 } 0076 0077 // Get the last used theme path from the KConfigSkeleton 0078 KConfigSkeletonItem *configItem = aconfig->findItem(QStringLiteral("Theme")); 0079 QString lastUsedTheme = configItem->property().toString(); 0080 0081 // Now get our themes into the list widget 0082 findThemes(lastUsedTheme); 0083 0084 q_func()->connect(ui.getNewButton, &KNSWidgets::Button::dialogFinished, q_ptr, [&](const QList<KNSCore::Entry> &changedEntries) { 0085 if (!changedEntries.isEmpty()) { 0086 findThemes(ui.kcfg_Theme->text()); 0087 } 0088 }); 0089 } 0090 0091 void KGameThemeSelectorPrivate::findThemes(const QString &initialSelection) 0092 { 0093 qDeleteAll(themeMap); 0094 themeMap.clear(); 0095 0096 // Disconnect the themeList as we are going to clear it and do not want previews generated 0097 ui.themeList->disconnect(); 0098 ui.themeList->clear(); 0099 ui.themeList->setSortingEnabled(true); 0100 0101 QStringList themesAvailable; 0102 QStringList themePaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, 0103 QCoreApplication::applicationName() + '/' + lookupDirectory + '/', 0104 QStandardPaths::LocateDirectory); 0105 for (const QString &dir : qAsConst(themePaths)) { 0106 QDirIterator it(dir, QStringList() << QStringLiteral("*.desktop"), QDir::NoFilter, QDirIterator::Subdirectories); 0107 while (it.hasNext()) { 0108 it.next(); 0109 themesAvailable.append(it.fileName()); 0110 } 0111 } 0112 0113 bool initialFound = false; 0114 for (const QString &file : qAsConst(themesAvailable)) { 0115 QString themePath = lookupDirectory + '/' + file; 0116 KGameTheme *atheme = new KGameTheme(groupName); 0117 0118 if (atheme->load(themePath)) { 0119 QString themeName = atheme->themeProperty(QStringLiteral("Name")); 0120 // Add underscores to avoid duplicate names. 0121 while (themeMap.contains(themeName)) 0122 themeName += '_'; 0123 themeMap.insert(themeName, atheme); 0124 QListWidgetItem *item = new QListWidgetItem(themeName, ui.themeList); 0125 0126 // Find if this is our currently configured theme 0127 if (themePath == initialSelection) { 0128 initialFound = true; 0129 ui.themeList->setCurrentItem(item); 0130 _k_updatePreview(); 0131 } 0132 } else { 0133 delete atheme; 0134 } 0135 } 0136 0137 if (!initialFound) { 0138 // TODO change this if we ever change KGameTheme::loadDefault 0139 QString defaultPath = QStringLiteral("themes/default.desktop"); 0140 for (KGameTheme *theme : qAsConst(themeMap)) { 0141 if (theme->path().endsWith(defaultPath)) { 0142 const QList<QListWidgetItem *> itemList = ui.themeList->findItems(theme->themeProperty(QStringLiteral("Name")), Qt::MatchExactly); 0143 // never can be != 1 but better safe than sorry 0144 if (itemList.count() == 1) { 0145 ui.themeList->setCurrentItem(itemList.first()); 0146 _k_updatePreview(); 0147 } 0148 } 0149 } 0150 } 0151 0152 // Reconnect the themeList 0153 q_func()->connect(ui.themeList, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), q_ptr, SLOT(_k_updatePreview())); 0154 } 0155 0156 void KGameThemeSelectorPrivate::_k_updatePreview() 0157 { 0158 KGameTheme *seltheme = themeMap.value(ui.themeList->currentItem()->text()); 0159 // Sanity checkings. Should not happen. 0160 if (!seltheme) 0161 return; 0162 if (seltheme->path() == ui.kcfg_Theme->text()) { 0163 return; 0164 } 0165 ui.kcfg_Theme->setText(seltheme->fileName()); 0166 0167 QString authstr(QStringLiteral("Author")); 0168 QString contactstr(QStringLiteral("AuthorEmail")); 0169 QString descstr(QStringLiteral("Description")); 0170 QString emailstr; 0171 if (!seltheme->themeProperty(contactstr).isEmpty()) { 0172 emailstr = QStringLiteral("<a href=\"mailto:%1\">%1</a>").arg(seltheme->themeProperty(contactstr)); 0173 } 0174 0175 ui.themeAuthor->setText(seltheme->themeProperty(authstr)); 0176 ui.themeContact->setText(emailstr); 0177 ui.themeDescription->setText(seltheme->themeProperty(descstr)); 0178 0179 // Draw the preview 0180 QPixmap pix(seltheme->preview()); 0181 ui.themePreview->setPixmap(pix.scaled(ui.themePreview->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); 0182 } 0183 0184 void KGameThemeSelectorPrivate::_k_updateThemeList(const QString &strTheme) 0185 { 0186 // find theme and set selection to the current theme; happens when pressing "Default" 0187 QListWidgetItem *currentItem = ui.themeList->currentItem(); 0188 0189 QString currentGameThemeFileName; 0190 if (currentItem) { 0191 KGameTheme *currentGameTheme = themeMap.value(currentItem->text()); 0192 if (currentGameTheme) { 0193 currentGameThemeFileName = currentGameTheme->fileName(); 0194 } 0195 } 0196 0197 if (!currentItem || (currentGameThemeFileName != strTheme)) { 0198 for (int i = 0; i < ui.themeList->count(); i++) { 0199 KGameTheme *listItemGameTheme = themeMap.value(ui.themeList->item(i)->text()); 0200 if (listItemGameTheme && (listItemGameTheme->fileName() == strTheme)) { 0201 ui.themeList->setCurrentItem(ui.themeList->item(i)); 0202 break; 0203 } 0204 } 0205 } 0206 } 0207 0208 #include "moc_kgamethemeselector.cpp"