add more spacing
[personal-kdebase.git] / workspace / plasma / tools / desktopthemedetails / desktopthemedetails.cpp
blob0bdd5d3bfbe94c19673a296683e8a168761be06d
1 /*
2 Copyright (c) 2008 Andrew Lake <jamboarder@yahoo.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 */
10 #include "desktopthemedetails.h"
12 #include <QPainter>
13 #include <QFile>
14 #include <QAbstractItemView>
15 #include <QtGui/QHeaderView>
17 #include <KIcon>
18 #include <KAboutData>
19 #include <KFileDialog>
20 #include <KMessageBox>
21 #include <KStandardDirs>
22 #include <KDesktopFile>
23 #include <KColorScheme>
24 #include <KNS/Engine>
25 #include <KUrl>
26 #include <KZip>
27 #include <kio/netaccess.h>
28 #include <kio/copyjob.h>
29 #include <kio/deletejob.h>
30 #include <kio/job.h>
31 #include <kgenericfactory.h>
33 #include <Plasma/FrameSvg>
34 #include <Plasma/Theme>
36 //Theme selector code by Andre Duffeck (modified to add package description)
37 class ThemeInfo
39 public:
40 QString package;
41 Plasma::FrameSvg *svg;
42 QString description;
43 QString author;
44 QString version;
45 QString themeRoot;
48 class ThemeModel : public QAbstractListModel
50 public:
51 enum { PackageNameRole = Qt::UserRole,
52 SvgRole = Qt::UserRole + 1,
53 PackageDescriptionRole = Qt::UserRole + 2,
54 PackageAuthorRole = Qt::UserRole + 3,
55 PackageVersionRole = Qt::UserRole + 4
58 ThemeModel(QObject *parent = 0);
59 virtual ~ThemeModel();
61 virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
62 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
63 int indexOf(const QString &path) const;
64 void reload();
65 void clearThemeList();
66 private:
67 QMap<QString, ThemeInfo> m_themes;
70 ThemeModel::ThemeModel( QObject *parent )
71 : QAbstractListModel( parent )
73 reload();
76 ThemeModel::~ThemeModel()
78 clearThemeList();
81 void ThemeModel::clearThemeList()
83 foreach (const QString& key, m_themes.keys()) {
84 delete m_themes[key].svg;
86 m_themes.clear();
89 void ThemeModel::reload()
91 reset();
92 clearThemeList();
94 // get all desktop themes
95 KStandardDirs dirs;
96 QStringList themes = dirs.findAllResources("data", "desktoptheme/*/metadata.desktop",
97 KStandardDirs::NoDuplicates);
98 foreach (const QString &theme, themes) {
99 kDebug() << theme;
100 int themeSepIndex = theme.lastIndexOf('/', -1);
101 QString themeRoot = theme.left(themeSepIndex);
102 int themeNameSepIndex = themeRoot.lastIndexOf('/', -1);
103 QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1);
105 KDesktopFile df(theme);
106 QString name = df.readName();
107 if (name.isEmpty()) {
108 name = packageName;
110 QString comment = df.readComment();
111 QString author = df.desktopGroup().readEntry("X-KDE-PluginInfo-Author",QString());
112 QString version = df.desktopGroup().readEntry("X-KDE-PluginInfo-Version",QString());
115 Plasma::FrameSvg *svg = new Plasma::FrameSvg(this);
116 QString svgFile = themeRoot + "/widgets/background.svg";
117 if (QFile::exists(svgFile)) {
118 svg->setImagePath(svgFile);
119 } else {
120 svg->setImagePath(svgFile + "z");
122 svg->setEnabledBorders(Plasma::FrameSvg::AllBorders);
123 ThemeInfo info;
124 info.package = packageName;
125 info.description = comment;
126 info.author = author;
127 info.version = version;
128 info.svg = svg;
129 info.themeRoot = themeRoot;
130 m_themes[name] = info;
133 beginInsertRows(QModelIndex(), 0, m_themes.size());
134 endInsertRows();
137 int ThemeModel::rowCount(const QModelIndex &) const
139 return m_themes.size();
142 QVariant ThemeModel::data(const QModelIndex &index, int role) const
144 if (!index.isValid()) {
145 return QVariant();
148 if (index.row() >= m_themes.size()) {
149 return QVariant();
152 QMap<QString, ThemeInfo>::const_iterator it = m_themes.constBegin();
153 for (int i = 0; i < index.row(); ++i) {
154 ++it;
157 switch (role) {
158 case Qt::DisplayRole:
159 return it.key();
160 case PackageNameRole:
161 return (*it).package;
162 case SvgRole:
163 return qVariantFromValue((void*)(*it).svg);
164 case PackageDescriptionRole:
165 return (*it).description;
166 case PackageAuthorRole:
167 return (*it).author;
168 case PackageVersionRole:
169 return (*it).version;
170 default:
171 return QVariant();
175 int ThemeModel::indexOf(const QString &name) const
177 QMapIterator<QString, ThemeInfo> it(m_themes);
178 int i = -1;
179 while (it.hasNext()) {
180 ++i;
181 if (it.next().value().package == name) {
182 return i;
186 return -1;
190 class ThemeDelegate : public QAbstractItemDelegate
192 public:
193 ThemeDelegate(QObject * parent = 0);
195 virtual void paint(QPainter *painter,
196 const QStyleOptionViewItem &option,
197 const QModelIndex &index) const;
198 virtual QSize sizeHint(const QStyleOptionViewItem &option,
199 const QModelIndex &index) const;
200 private:
201 static const int MARGIN = 5;
204 ThemeDelegate::ThemeDelegate(QObject* parent)
205 : QAbstractItemDelegate(parent)
209 void ThemeDelegate::paint(QPainter *painter,
210 const QStyleOptionViewItem &option,
211 const QModelIndex &index) const
213 QString title = index.model()->data(index, Qt::DisplayRole).toString();
214 QString package = index.model()->data(index, ThemeModel::PackageNameRole).toString();
216 // highlight selected item
217 painter->save();
218 if (option.state & QStyle::State_Selected) {
219 painter->setBrush(option.palette.color(QPalette::Highlight));
220 } else {
221 painter->setBrush(Qt::gray);
223 painter->drawRect(option.rect);
224 painter->restore();
226 // draw image
227 Plasma::FrameSvg *svg = static_cast<Plasma::FrameSvg *>(
228 index.model()->data(index, ThemeModel::SvgRole).value<void *>());
229 svg->resizeFrame(QSize(option.rect.width() - (2 * MARGIN), 100 - (2 * MARGIN)));
230 QRect imgRect = QRect(option.rect.topLeft(),
231 QSize(option.rect.width() - (2 * MARGIN), 100 - (2 * MARGIN)))
232 .translated(MARGIN, MARGIN);
233 svg->paintFrame(painter, QPoint(option.rect.left() + MARGIN, option.rect.top() + MARGIN));
235 // draw text
236 painter->save();
237 QFont font = painter->font();
238 font.setWeight(QFont::Bold);
239 QString colorFile = KStandardDirs::locate("data", "desktoptheme/" + package + "/colors");
240 if (!colorFile.isEmpty()) {
241 KSharedConfigPtr colors = KSharedConfig::openConfig(colorFile);
242 KColorScheme colorScheme(QPalette::Active, KColorScheme::Window, colors);
243 painter->setPen(colorScheme.foreground(KColorScheme::NormalText).color());
245 painter->setFont(font);
246 painter->drawText(option.rect, Qt::AlignCenter | Qt::TextWordWrap, title);
247 painter->restore();
250 QSize ThemeDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const
252 return QSize(200, 100);
255 K_PLUGIN_FACTORY(DesktopThemeDetailsFactory, registerPlugin<DesktopThemeDetails>();)
256 K_EXPORT_PLUGIN(DesktopThemeDetailsFactory("desktopthemedetails", "kcm_desktopthemedetails"))
260 struct ThemeItemNameType {
261 const char* m_type;
262 const char* m_displayItemName;
263 const char* m_widgetType;
264 const char* m_iconName;
267 const ThemeItemNameType themeCollectionName[] = {
268 { "Color Scheme", I18N_NOOP2("plasma name", "Color Scheme"),"colors", "preferences-desktop-color"},
269 { "Panel Background", I18N_NOOP2("plasma name", "Panel Background"),"widgets/panel-background", "plasma"},
270 { "Kickoff", I18N_NOOP2("plasma name", "Kickoff"), "dialogs/kickoff", "kde"},
271 { "Task Items", I18N_NOOP2("plasma name", "Task Items"), "widgets/tasks", "preferences-system-windows"},
272 { "Widget Background", I18N_NOOP2("plasma name", "Widget Background"), "widgets/background", "plasma"},
273 { "Translucent Background", I18N_NOOP2("plasma name", "Translucent Background"), "widgets/translucentbackground", "plasma"},
274 { "Dialog Background", I18N_NOOP2("plasma name", "Dialog Background"), "dialogs/background", "plasma"},
275 { "Analog Clock", I18N_NOOP2("plasma name", "Analog Clock"), "widgets/clock", "chronometer"},
276 { "Notes", I18N_NOOP2("plasma name", "Notes"), "widgets/notes", "view-pim-notes"},
277 { "Tooltip", I18N_NOOP2("plasma name", "Tooltip"), "widgets/tooltip", "plasma"},
278 { "Pager", I18N_NOOP2("plasma name", "Pager"), "widgets/pager", "plasma"},
279 { "Run Command Dialog", I18N_NOOP2("plasma name", "Run Command Dialog"), "dialogs/krunner", "system-run"},
280 { "Shutdown Dialog", I18N_NOOP2("plasma name", "Shutdown Dialog"), "dialogs/shutdowndialog", "system-shutdown"},
281 { 0, 0,0,0 } // end of data
285 DesktopThemeDetails::DesktopThemeDetails(QWidget* parent, const QVariantList &args)
286 : KCModule(DesktopThemeDetailsFactory::componentData(), parent, args),
287 m_themeModel(0)
290 KAboutData *about = new KAboutData("kcm_desktopthemedetails", 0, ki18n("Desktop Theme Details"), "1.0");
291 setAboutData(about);
292 setButtons(Apply);
293 setWindowIcon(KIcon("preferences-desktop"));
294 setupUi(this);
295 m_newThemeButton->setIcon(KIcon("get-hot-new-stuff"));
297 connect(m_newThemeButton, SIGNAL(clicked()), this, SLOT(getNewThemes()));
298 //connect(this, SIGNAL(finished(int)), this, SLOT(cleanup()));
300 m_themeModel = new ThemeModel(this);
301 m_theme->setModel(m_themeModel);
302 m_theme->setItemDelegate(new ThemeDelegate(m_theme->view()));
303 m_theme->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
305 connect(m_theme, SIGNAL(currentIndexChanged(int)), this, SLOT(resetThemeDetails()));
306 connect(m_enableAdvanced, SIGNAL(toggled(bool)), this, SLOT(toggleAdvancedVisible()));
307 connect(m_removeThemeButton, SIGNAL(clicked()), this, SLOT(removeTheme()));
308 connect(m_exportThemeButton, SIGNAL(clicked()), this, SLOT(exportTheme()));
309 resetThemeDetails();
310 m_themeCustomized = false;
311 m_baseTheme = "default";
312 reloadConfig();
313 adjustSize();
316 DesktopThemeDetails::~DesktopThemeDetails()
318 cleanup();
321 void DesktopThemeDetails::cleanup()
325 void DesktopThemeDetails::getNewThemes()
327 KNS::Engine engine(this);
328 if (engine.init("plasma-themes.knsrc")) {
329 KNS::Entry::List entries = engine.downloadDialogModal(this);
331 if (entries.size() > 0) {
332 m_themeModel->reload();
333 reloadConfig();
338 void DesktopThemeDetails::reloadConfig()
340 // Theme
341 //QString theme = Plasma::Theme::defaultTheme()->themeName();
342 KConfigGroup cfg = KConfigGroup(KSharedConfig::openConfig("plasmarc"), "Theme");
343 QString theme = cfg.readEntry("name", "default");
344 m_theme->setCurrentIndex(m_themeModel->indexOf(theme));
348 void DesktopThemeDetails::save()
350 QString theme;
351 if (m_newThemeName->text().isEmpty()) {
352 theme = ".customized";
353 } else {
354 theme = m_newThemeName->text().replace(' ',"_").remove(QRegExp("[^A-Za-z0-9_]"));
357 //Customized Theme
358 bool newThemeExists = false;
359 KStandardDirs dirs;
360 QFile customSettingsFile;
361 bool customSettingsFileOpen = false;
362 if (m_themeCustomized || !m_newThemeName->text().isEmpty()) {
363 //Toggle theme directory name to ensure theme reload
364 if (QDir(dirs.locateLocal("data", "desktoptheme/" + theme + '/', false)).exists()) {
365 theme = theme + '1';
367 clearCustomized();
369 //Copy all files from the base theme
370 QString baseSource = dirs.locate("data", "desktoptheme/" + m_baseTheme + '/');
371 KIO::CopyJob *copyBaseTheme = KIO::copyAs(KUrl(baseSource), KUrl(dirs.locateLocal("data", "desktoptheme/" + theme, true)), KIO::HideProgressInfo);
372 KIO::NetAccess::synchronousRun(copyBaseTheme, this);
374 //Prepare settings file for customized theme
375 if (isCustomized(theme)) {
376 customSettingsFile.setFileName(dirs.locateLocal("data", "desktoptheme/" + theme + "/settings"));
377 customSettingsFileOpen = customSettingsFile.open(QFile::WriteOnly);
378 if (customSettingsFileOpen) {
379 QTextStream out(&customSettingsFile);
380 out << "baseTheme=" + m_baseTheme + "\r\n";;
385 //Copy each theme file to new theme folder
386 QHashIterator<QString, QString> i(m_themeReplacements);
387 while (i.hasNext()) {
388 i.next();
389 QString source = i.value();
390 QString itemDir = "desktoptheme/" + theme + '/' + m_themeItems[i.key()];
391 if (source.right(4).toLower() == ".svg") {
392 itemDir.append(".svg");
393 } else if (source.right(5).toLower() == ".svgz") {
394 itemDir.append(".svgz");
396 QString dest = dirs.locateLocal("data", itemDir, true);
397 if (QFile::exists(source)) {
398 QFile::remove(dirs.locateLocal("data", "desktoptheme/" + theme + '/' + m_themeItems[i.key()] + ".svg"));
399 QFile::remove(dirs.locateLocal("data", "desktoptheme/" + theme + '/' + m_themeItems[i.key()] + ".svgz"));
400 KIO::file_copy(KUrl(source), KUrl(dest), -1, KIO::HideProgressInfo);
402 //Save setting for this theme item
403 if (customSettingsFileOpen) {
404 QTextStream out(&customSettingsFile);
405 if (m_dropListFiles.key(source).startsWith("File:") || m_dropListFiles.key(source).startsWith(i18n("(Customized)"))) {
406 out << i.key() + "=" + dest +"\r\n";
407 } else {
408 out << i.key() + "=" + source +"\r\n";
413 if (customSettingsFileOpen) customSettingsFile.close();
415 // Create new theme FDO desktop file
416 QFile::remove(dirs.locateLocal("data", "desktoptheme/" + theme + "/metadata.desktop", false));
417 QFile desktopFile(dirs.locateLocal("data", "desktoptheme/" + theme +"/metadata.desktop"));
418 QString desktopFileData;
419 if (isCustomized(theme)) {
420 desktopFileData = QString("Name=%1 \r\nComment=%2 \r\nX-KDE-PluginInfo-Name=%3\r\n").arg(i18n("(Customized)")).arg(i18n("User customized theme")).arg(theme);
421 } else {
422 desktopFileData = "Name=" + m_newThemeName->text() + " \r\n Comment=" + m_newThemeDescription->text() + " \r\n X-KDE-PluginInfo-Author=" + m_newThemeAuthor->text() + " \r\n X-KDE-PluginInfo-Name=" + theme + " \r\n X-KDE-PluginInfo-Version=" + m_newThemeVersion->text();
424 if (desktopFile.open(QFile::WriteOnly)) {
425 QTextStream out(&desktopFile);
426 out << "[Desktop Entry] \r\n" + desktopFileData +" \r\n";
427 desktopFile.close();
428 newThemeExists = true;
429 } else {
430 KMessageBox::error(this, i18n("Unable to save theme."), i18n("Desktop Theme Details"));
432 m_themeCustomized = false;
435 // Plasma Theme
436 //Plasma::Theme::defaultTheme()->setThemeName(theme);
438 if (newThemeExists) {
439 m_themeModel->reload();
440 m_theme->setCurrentIndex(m_themeModel->indexOf(theme));
441 //FIXME: should say "Appearance Settings" instead of "Desktop Settings"
442 KMessageBox::information(this,i18n("To change your desktop theme to \"%1\", open\nDesktop Settings and select \"%2\" from the droplist.",m_theme->currentText(),m_theme->currentText() ), i18n("How to Change Desktop Theme"), "HowToChangeDesktopTheme");
444 resetThemeDetails();
447 void DesktopThemeDetails::removeTheme()
449 bool removeTheme = true;
450 QString theme = m_theme->itemData(m_theme->currentIndex(),
451 ThemeModel::PackageNameRole).toString();
452 if (m_themeCustomized) {
453 if(KMessageBox::questionYesNo(this, i18n("Theme items have been changed. Do you still wish remove the \"%1\" theme?", m_theme->currentText()), i18n("Remove Desktop Theme")) == KMessageBox::No) {
454 removeTheme = false;
456 } else {
457 if (theme == "default") {
458 KMessageBox::information(this, i18n("Removal of the default KDE theme is not allowed."), i18n("Remove Desktop Theme"));
459 removeTheme = false;
460 } else {
461 if(KMessageBox::questionYesNo(this, i18n("Are you sure you wish remove the \"%1\" theme?", m_theme->currentText()), i18n("Remove Desktop Theme")) == KMessageBox::No) {
462 removeTheme = false;
467 KStandardDirs dirs;
468 if (removeTheme) {
469 if (QDir(dirs.locateLocal("data", "desktoptheme/" + theme, false)).exists()) {
470 KIO::DeleteJob *deleteTheme = KIO::del(KUrl(dirs.locateLocal("data", "desktoptheme/" + theme, false)), KIO::HideProgressInfo);
471 KIO::NetAccess::synchronousRun(deleteTheme, this);
474 m_themeModel->reload();
475 reloadConfig();
478 void DesktopThemeDetails::exportTheme()
480 if (m_themeCustomized ||
481 (m_theme->currentText() == i18n("(Customized)") && m_newThemeName->text() == "")) {
482 KMessageBox::information(this, i18n("Please apply theme item changes (with a new theme name) before attempting to export theme."), i18n("Export Desktop Theme"));
483 } else {
484 QString themeStoragePath = m_theme->itemData(m_theme->currentIndex(),
485 ThemeModel::PackageNameRole).toString();
486 KStandardDirs dirs;
487 kDebug()<<" themeStoragePath "<<themeStoragePath;
489 if ( themeStoragePath == "default")
491 KConfigGroup cfg = KConfigGroup(KSharedConfig::openConfig("plasmarc"), "Theme");
492 themeStoragePath = cfg.readEntry("name", "default");
495 QString themePath = dirs.findResource("data", "desktoptheme/" + themeStoragePath + "/metadata.desktop");
496 if (!themePath.isEmpty())
498 QString expFileName = KFileDialog::getSaveFileName(KUrl(), "*.zip", this, i18n("Export theme to file"));
499 if (!expFileName.endsWith(".zip"))
500 expFileName = expFileName + ".zip";
501 if (!expFileName.isEmpty()) {
502 KUrl path(themePath);
503 KZip expFile(expFileName);
504 expFile.open(QIODevice::WriteOnly);
505 expFile.addLocalDirectory(path.directory (), themeStoragePath);
506 expFile.close();
513 void DesktopThemeDetails::loadThemeItems()
515 QStringList themeItemList;
516 QStringList themeItemIconList;
517 m_themeItems.clear();
518 m_themeReplacements.clear();
519 m_themeItemList->clear();
520 m_dropListFiles.clear();
523 for (int i = 0; themeCollectionName[i].m_type; ++i) {
524 m_themeItems[themeCollectionName[i].m_type] = themeCollectionName[i].m_widgetType;
525 themeItemList.append(i18nc("plasma name", themeCollectionName[i].m_displayItemName));
526 m_themeReplacements[i18nc("plasma name", themeCollectionName[i].m_displayItemName)] = "";
527 themeItemIconList.append(themeCollectionName[i].m_iconName);
531 m_themeItemList->setRowCount(themeItemList.size());
532 m_themeItemList->setColumnCount(2);
533 m_themeItemList->setHorizontalHeaderLabels(QStringList()<< i18n("Theme Item")<<i18n("Source"));
534 QString item;
535 QStringListIterator i(themeItemList);
536 int row = 0;
537 while (i.hasNext()) {
538 item = i.next();
539 m_themeItemList->setItem(row, 0, new QTableWidgetItem(item));
540 m_themeItemList->item(row,0)->setIcon(KIcon(themeItemIconList.at(row)));
541 m_themeItemList->setCellWidget(row, 1, new QComboBox());
542 updateReplaceItemList(item);
543 m_themeItemList->resizeColumnToContents(1);
544 row++;
546 m_themeItemList->setSelectionBehavior(QAbstractItemView::SelectRows);
547 m_themeItemList->verticalHeader()->hide();
548 m_themeItemList->horizontalHeader()->setStretchLastSection(true);
549 m_themeItemList->horizontalHeader()->setMinimumSectionSize(120);
550 m_themeItemList->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents);;
551 m_themeItemList->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);;
552 m_themeItemList->setCurrentCell(0, 1);
555 void DesktopThemeDetails::updateReplaceItemList(const QString& item)
557 QString currentReplacement = m_themeReplacements[item];
558 QString replacementDropListItem;
559 QStringList dropList;
560 if ((currentReplacement.isEmpty() && m_theme->currentText() != i18n("(Customized)"))){
561 replacementDropListItem = m_theme->currentText() + " " + item;
564 // Repopulate combobox droplist
565 int itemRow = m_themeItemList->row(m_themeItemList->findItems(item, Qt::MatchExactly).at(0));
566 QComboBox *currentComboBox = static_cast<QComboBox*>(m_themeItemList->cellWidget(itemRow,1));
567 disconnect(currentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged()));
568 currentComboBox->clear();
569 KStandardDirs dirs;
570 QStringList themes = dirs.findAllResources("data", "desktoptheme/*/metadata.desktop",
571 KStandardDirs::NoDuplicates);
572 themes.sort();
573 foreach (const QString &theme, themes) {
574 int themeSepIndex = theme.lastIndexOf('/', -1);
575 QString themeRoot = theme.left(themeSepIndex);
576 int themeNameSepIndex = themeRoot.lastIndexOf('/', -1);
577 QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1);
579 KDesktopFile df(theme);
580 QString name = df.readName();
581 if (name.isEmpty()) {
582 name = packageName;
585 QString themeItemFile = themeRoot + '/' + m_themeItems[item];
586 //Get correct extension for svg files
587 if (QFile::exists(themeItemFile + ".svg")) {
588 themeItemFile = themeRoot + '/' + m_themeItems[item] + ".svg";
590 if (QFile::exists(themeItemFile + ".svgz")) {
591 themeItemFile = themeRoot + '/' + m_themeItems[item] + ".svgz";
593 if ((name != i18n("(Customized)")) || (name == i18n("(Customized)") && themeItemFile == currentReplacement)) {
594 QString dropListItem = i18n("%1 %2",name,item);
595 if (themeItemFile == currentReplacement) {
596 replacementDropListItem = dropListItem;
598 dropList << dropListItem;
599 m_dropListFiles[dropListItem] = themeItemFile;
602 if (currentReplacement.isEmpty()) m_themeReplacements[item] = m_dropListFiles[replacementDropListItem];
603 currentComboBox->addItems(dropList << i18n("File..."));
604 currentComboBox->setCurrentIndex(currentComboBox->findText(replacementDropListItem));
605 connect(currentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged()));
608 void DesktopThemeDetails::replacementItemChanged()
610 //Check all items to see if theme has been customized
611 m_themeCustomized=false;
612 int i;
613 for (i = 0; i < m_themeItemList->rowCount(); i++) {
614 QComboBox *currentComboBox = static_cast<QComboBox*>(m_themeItemList->cellWidget(i, 1));
615 QString currentReplacement = currentComboBox->currentText();
617 QString currentItem = m_themeItemList->item(i, 0)->text();
618 QString originalValue = m_dropListFiles.key(m_themeReplacements[currentItem]);
619 QString changedValue;
621 if (currentReplacement == i18n("File...")) {
622 //Get the filename for the replacement item
623 changedValue = KFileDialog::getOpenFileName(KUrl(), QString(), this, i18n("Select File to Use for %1",currentItem));
624 if (!changedValue.isEmpty()) {
625 //TODO need a i18n ?
626 currentReplacement = "File:" + changedValue;
627 m_dropListFiles[currentReplacement]=changedValue;
628 int index = currentComboBox->findText("File:",Qt::MatchStartsWith);
629 if (index != -1) currentComboBox->removeItem(index);
630 currentComboBox->addItem(currentReplacement);
631 } else {
632 currentReplacement = originalValue;
634 disconnect(currentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged()));
635 int index = currentComboBox->findText(currentReplacement);
636 if (index != -1) currentComboBox->setCurrentIndex(index);
637 connect(currentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged()));
638 } else {
639 //Get the filename for the drop list replacement item
640 changedValue = m_dropListFiles[currentReplacement];
643 kDebug() << changedValue;
644 if (changedValue != originalValue) {
645 m_themeCustomized = true;
646 m_themeReplacements[currentItem] = changedValue;
649 if (m_themeCustomized) emit changed();
652 void DesktopThemeDetails::resetThemeDetails()
654 m_themeInfoName->setText(m_theme->currentText());
655 m_themeInfoDescription->setText(m_theme->itemData(m_theme->currentIndex(),
656 ThemeModel::PackageDescriptionRole).toString());
657 QString author = m_theme->itemData(m_theme->currentIndex(),
658 ThemeModel::PackageAuthorRole).toString();
659 if (!author.isEmpty()) {
660 m_themeInfoAuthor->setText(i18n(" Author: %1",author));
661 } else {
662 m_themeInfoAuthor->setText("");
664 QString version = m_theme->itemData(m_theme->currentIndex(),
665 ThemeModel::PackageVersionRole).toString();
666 if (!version.isEmpty()) {
667 m_themeInfoVersion->setText(i18n("Version: %1",version));
668 } else {
669 m_themeInfoVersion->setText("");
671 KStandardDirs dirs;
672 QString theme = m_theme->itemData(m_theme->currentIndex(),
673 ThemeModel::PackageNameRole).toString();
674 m_baseTheme = theme;
675 loadThemeItems();
676 // Load customized theme settings
677 if (isCustomized(theme)) {
678 QFile customSettingsFile(dirs.locateLocal("data", "desktoptheme/" + theme +"/settings"));
679 if (customSettingsFile.open(QFile::ReadOnly)) {
680 QTextStream in(&customSettingsFile);
681 QString line;
682 QStringList settingsPair;
683 QMap<QString, QString>lst;
684 //cache it
685 for (int i = 0; themeCollectionName[i].m_type; ++i) {
686 lst.insert(themeCollectionName[i].m_type, i18nc("plasma name", themeCollectionName[i].m_displayItemName));
689 while (!in.atEnd()) {
690 line = in.readLine();
691 settingsPair = line.split('=');
692 if (settingsPair.at(0) == "baseTheme") {
693 m_baseTheme = settingsPair.at(1);
694 } else {
695 m_themeReplacements[lst[settingsPair.at(0)]] = settingsPair.at(1);
696 updateReplaceItemList(lst[settingsPair.at(0)]);
699 customSettingsFile.close();
703 m_newThemeName->clear();
704 m_newThemeAuthor->clear();
705 m_newThemeVersion->clear();
706 m_newThemeDescription->clear();
707 m_enableAdvanced->setChecked(false);
708 toggleAdvancedVisible();
709 m_themeCustomized = false;
712 void DesktopThemeDetails::toggleAdvancedVisible()
714 m_newThemeNameLabel->setVisible(m_enableAdvanced->isChecked());
715 m_newThemeName->setVisible(m_enableAdvanced->isChecked());
716 m_newThemeAuthor->setVisible(m_enableAdvanced->isChecked());
717 m_newThemeAuthorLabel->setVisible(m_enableAdvanced->isChecked());
718 m_newThemeVersion->setVisible(m_enableAdvanced->isChecked());
719 m_newThemeVersionLabel->setVisible(m_enableAdvanced->isChecked());
720 m_newThemeDescriptionLabel->setVisible(m_enableAdvanced->isChecked());
721 m_newThemeDescription->setVisible(m_enableAdvanced->isChecked());
722 m_exportThemeButton->setVisible(m_enableAdvanced->isChecked());
723 m_removeThemeButton->setVisible(m_enableAdvanced->isChecked());
724 m_advancedLine->setVisible(m_enableAdvanced->isChecked());
727 bool DesktopThemeDetails::isCustomized(const QString& theme) {
728 if (theme == ".customized" || theme == ".customized1") {
729 return true;
730 } else {
731 return false;
735 void DesktopThemeDetails::clearCustomized() {
736 KStandardDirs dirs;
737 if (QDir(dirs.locateLocal("data", "desktoptheme/.customized", false)).exists()) {
738 KIO::DeleteJob *clearCustom = KIO::del(KUrl(dirs.locateLocal("data", "desktoptheme/.customized", false)), KIO::HideProgressInfo);
739 KIO::NetAccess::synchronousRun(clearCustom, this);
741 if (QDir(dirs.locateLocal("data", "desktoptheme/.customized1", false)).exists()) {
742 KIO::DeleteJob *clearCustom1 = KIO::del(KUrl(dirs.locateLocal("data", "desktoptheme/.customized1", false)), KIO::HideProgressInfo);
743 KIO::NetAccess::synchronousRun(clearCustom1, this);