00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "desktopthemedetails.h"
00011
00012 #include <QPainter>
00013 #include <QFile>
00014 #include <QAbstractItemView>
00015 #include <QtGui/QHeaderView>
00016
00017 #include <KIcon>
00018 #include <KAboutData>
00019 #include <KFileDialog>
00020 #include <KMessageBox>
00021 #include <KStandardDirs>
00022 #include <KDesktopFile>
00023 #include <KColorScheme>
00024 #include <KNS/Engine>
00025 #include <KUrl>
00026 #include <KZip>
00027 #include <kio/netaccess.h>
00028 #include <kio/copyjob.h>
00029 #include <kio/deletejob.h>
00030 #include <kio/job.h>
00031 #include <kgenericfactory.h>
00032
00033 #include <Plasma/FrameSvg>
00034 #include <Plasma/Theme>
00035
00036
00037 class ThemeInfo
00038 {
00039 public:
00040 QString package;
00041 Plasma::FrameSvg *svg;
00042 QString description;
00043 QString author;
00044 QString version;
00045 QString themeRoot;
00046 };
00047
00048 class ThemeModel : public QAbstractListModel
00049 {
00050 public:
00051 enum { PackageNameRole = Qt::UserRole,
00052 SvgRole = Qt::UserRole + 1,
00053 PackageDescriptionRole = Qt::UserRole + 2,
00054 PackageAuthorRole = Qt::UserRole + 3,
00055 PackageVersionRole = Qt::UserRole + 4
00056 };
00057
00058 ThemeModel(QObject *parent = 0);
00059 virtual ~ThemeModel();
00060
00061 virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
00062 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
00063 int indexOf(const QString &path) const;
00064 void reload();
00065 void clearThemeList();
00066 private:
00067 QMap<QString, ThemeInfo> m_themes;
00068 };
00069
00070 ThemeModel::ThemeModel( QObject *parent )
00071 : QAbstractListModel( parent )
00072 {
00073 reload();
00074 }
00075
00076 ThemeModel::~ThemeModel()
00077 {
00078 clearThemeList();
00079 }
00080
00081 void ThemeModel::clearThemeList()
00082 {
00083 foreach (const QString& key, m_themes.keys()) {
00084 delete m_themes[key].svg;
00085 }
00086 m_themes.clear();
00087 }
00088
00089 void ThemeModel::reload()
00090 {
00091 reset();
00092 clearThemeList();
00093
00094
00095 KStandardDirs dirs;
00096 QStringList themes = dirs.findAllResources("data", "desktoptheme/*/metadata.desktop",
00097 KStandardDirs::NoDuplicates);
00098 foreach (const QString &theme, themes) {
00099 kDebug() << theme;
00100 int themeSepIndex = theme.lastIndexOf('/', -1);
00101 QString themeRoot = theme.left(themeSepIndex);
00102 int themeNameSepIndex = themeRoot.lastIndexOf('/', -1);
00103 QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1);
00104
00105 KDesktopFile df(theme);
00106 QString name = df.readName();
00107 if (name.isEmpty()) {
00108 name = packageName;
00109 }
00110 QString comment = df.readComment();
00111 QString author = df.desktopGroup().readEntry("X-KDE-PluginInfo-Author",QString());
00112 QString version = df.desktopGroup().readEntry("X-KDE-PluginInfo-Version",QString());
00113
00114
00115 Plasma::FrameSvg *svg = new Plasma::FrameSvg(this);
00116 QString svgFile = themeRoot + "/widgets/background.svg";
00117 if (QFile::exists(svgFile)) {
00118 svg->setImagePath(svgFile);
00119 } else {
00120 svg->setImagePath(svgFile + "z");
00121 }
00122 svg->setEnabledBorders(Plasma::FrameSvg::AllBorders);
00123 ThemeInfo info;
00124 info.package = packageName;
00125 info.description = comment;
00126 info.author = author;
00127 info.version = version;
00128 info.svg = svg;
00129 info.themeRoot = themeRoot;
00130 m_themes[name] = info;
00131 }
00132
00133 beginInsertRows(QModelIndex(), 0, m_themes.size());
00134 endInsertRows();
00135 }
00136
00137 int ThemeModel::rowCount(const QModelIndex &) const
00138 {
00139 return m_themes.size();
00140 }
00141
00142 QVariant ThemeModel::data(const QModelIndex &index, int role) const
00143 {
00144 if (!index.isValid()) {
00145 return QVariant();
00146 }
00147
00148 if (index.row() >= m_themes.size()) {
00149 return QVariant();
00150 }
00151
00152 QMap<QString, ThemeInfo>::const_iterator it = m_themes.constBegin();
00153 for (int i = 0; i < index.row(); ++i) {
00154 ++it;
00155 }
00156
00157 switch (role) {
00158 case Qt::DisplayRole:
00159 return it.key();
00160 case PackageNameRole:
00161 return (*it).package;
00162 case SvgRole:
00163 return qVariantFromValue((void*)(*it).svg);
00164 case PackageDescriptionRole:
00165 return (*it).description;
00166 case PackageAuthorRole:
00167 return (*it).author;
00168 case PackageVersionRole:
00169 return (*it).version;
00170 default:
00171 return QVariant();
00172 }
00173 }
00174
00175 int ThemeModel::indexOf(const QString &name) const
00176 {
00177 QMapIterator<QString, ThemeInfo> it(m_themes);
00178 int i = -1;
00179 while (it.hasNext()) {
00180 ++i;
00181 if (it.next().value().package == name) {
00182 return i;
00183 }
00184 }
00185
00186 return -1;
00187 }
00188
00189
00190 class ThemeDelegate : public QAbstractItemDelegate
00191 {
00192 public:
00193 ThemeDelegate(QObject * parent = 0);
00194
00195 virtual void paint(QPainter *painter,
00196 const QStyleOptionViewItem &option,
00197 const QModelIndex &index) const;
00198 virtual QSize sizeHint(const QStyleOptionViewItem &option,
00199 const QModelIndex &index) const;
00200 private:
00201 static const int MARGIN = 5;
00202 };
00203
00204 ThemeDelegate::ThemeDelegate(QObject* parent)
00205 : QAbstractItemDelegate(parent)
00206 {
00207 }
00208
00209 void ThemeDelegate::paint(QPainter *painter,
00210 const QStyleOptionViewItem &option,
00211 const QModelIndex &index) const
00212 {
00213 QString title = index.model()->data(index, Qt::DisplayRole).toString();
00214 QString package = index.model()->data(index, ThemeModel::PackageNameRole).toString();
00215
00216
00217 painter->save();
00218 if (option.state & QStyle::State_Selected) {
00219 painter->setBrush(option.palette.color(QPalette::Highlight));
00220 } else {
00221 painter->setBrush(Qt::gray);
00222 }
00223 painter->drawRect(option.rect);
00224 painter->restore();
00225
00226
00227 Plasma::FrameSvg *svg = static_cast<Plasma::FrameSvg *>(
00228 index.model()->data(index, ThemeModel::SvgRole).value<void *>());
00229 svg->resizeFrame(QSize(option.rect.width() - (2 * MARGIN), 100 - (2 * MARGIN)));
00230 QRect imgRect = QRect(option.rect.topLeft(),
00231 QSize(option.rect.width() - (2 * MARGIN), 100 - (2 * MARGIN)))
00232 .translated(MARGIN, MARGIN);
00233 svg->paintFrame(painter, QPoint(option.rect.left() + MARGIN, option.rect.top() + MARGIN));
00234
00235
00236 painter->save();
00237 QFont font = painter->font();
00238 font.setWeight(QFont::Bold);
00239 QString colorFile = KStandardDirs::locate("data", "desktoptheme/" + package + "/colors");
00240 if (!colorFile.isEmpty()) {
00241 KSharedConfigPtr colors = KSharedConfig::openConfig(colorFile);
00242 KColorScheme colorScheme(QPalette::Active, KColorScheme::Window, colors);
00243 painter->setPen(colorScheme.foreground(KColorScheme::NormalText).color());
00244 }
00245 painter->setFont(font);
00246 painter->drawText(option.rect, Qt::AlignCenter | Qt::TextWordWrap, title);
00247 painter->restore();
00248 }
00249
00250 QSize ThemeDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const
00251 {
00252 return QSize(200, 100);
00253 }
00254
00255 K_PLUGIN_FACTORY(DesktopThemeDetailsFactory, registerPlugin<DesktopThemeDetails>();)
00256 K_EXPORT_PLUGIN(DesktopThemeDetailsFactory("desktopthemedetails", "kcm_desktopthemedetails"))
00257
00258
00259
00260 struct ThemeItemNameType {
00261 const char* m_type;
00262 const char* m_displayItemName;
00263 const char* m_widgetType;
00264 const char* m_iconName;
00265 };
00266
00267 const ThemeItemNameType themeCollectionName[] = {
00268 { "Color Scheme", I18N_NOOP2("plasma name", "Color Scheme"),"colors", "preferences-desktop-color"},
00269 { "Panel Background", I18N_NOOP2("plasma name", "Panel Background"),"widgets/panel-background", "plasma"},
00270 { "Kickoff", I18N_NOOP2("plasma name", "Kickoff"), "dialogs/kickoff", "kde"},
00271 { "Task Items", I18N_NOOP2("plasma name", "Task Items"), "widgets/tasks", "preferences-system-windows"},
00272 { "Widget Background", I18N_NOOP2("plasma name", "Widget Background"), "widgets/background", "plasma"},
00273 { "Translucent Background", I18N_NOOP2("plasma name", "Translucent Background"), "widgets/translucentbackground", "plasma"},
00274 { "Dialog Background", I18N_NOOP2("plasma name", "Dialog Background"), "dialogs/background", "plasma"},
00275 { "Analog Clock", I18N_NOOP2("plasma name", "Analog Clock"), "widgets/clock", "chronometer"},
00276 { "Notes", I18N_NOOP2("plasma name", "Notes"), "widgets/notes", "view-pim-notes"},
00277 { "Tooltip", I18N_NOOP2("plasma name", "Tooltip"), "widgets/tooltip", "plasma"},
00278 { "Pager", I18N_NOOP2("plasma name", "Pager"), "widgets/pager", "plasma"},
00279 { "Run Command Dialog", I18N_NOOP2("plasma name", "Run Command Dialog"), "dialogs/krunner", "system-run"},
00280 { "Shutdown Dialog", I18N_NOOP2("plasma name", "Shutdown Dialog"), "dialogs/shutdowndialog", "system-shutdown"},
00281 { 0, 0,0,0 }
00282 };
00283
00284
00285 DesktopThemeDetails::DesktopThemeDetails(QWidget* parent, const QVariantList &args)
00286 : KCModule(DesktopThemeDetailsFactory::componentData(), parent, args),
00287 m_themeModel(0)
00288
00289 {
00290 KAboutData *about = new KAboutData("kcm_desktopthemedetails", 0, ki18n("Desktop Theme Details"), "1.0");
00291 setAboutData(about);
00292 setButtons(Apply);
00293 setWindowIcon(KIcon("preferences-desktop"));
00294 setupUi(this);
00295 m_newThemeButton->setIcon(KIcon("get-hot-new-stuff"));
00296
00297 connect(m_newThemeButton, SIGNAL(clicked()), this, SLOT(getNewThemes()));
00298
00299
00300 m_themeModel = new ThemeModel(this);
00301 m_theme->setModel(m_themeModel);
00302 m_theme->setItemDelegate(new ThemeDelegate(m_theme->view()));
00303 m_theme->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
00304
00305 connect(m_theme, SIGNAL(currentIndexChanged(int)), this, SLOT(resetThemeDetails()));
00306 connect(m_enableAdvanced, SIGNAL(toggled(bool)), this, SLOT(toggleAdvancedVisible()));
00307 connect(m_removeThemeButton, SIGNAL(clicked()), this, SLOT(removeTheme()));
00308 connect(m_exportThemeButton, SIGNAL(clicked()), this, SLOT(exportTheme()));
00309 resetThemeDetails();
00310 m_themeCustomized = false;
00311 m_baseTheme = "default";
00312 reloadConfig();
00313 adjustSize();
00314 }
00315
00316 DesktopThemeDetails::~DesktopThemeDetails()
00317 {
00318 cleanup();
00319 }
00320
00321 void DesktopThemeDetails::cleanup()
00322 {
00323 }
00324
00325 void DesktopThemeDetails::getNewThemes()
00326 {
00327 KNS::Engine engine(this);
00328 if (engine.init("plasma-themes.knsrc")) {
00329 KNS::Entry::List entries = engine.downloadDialogModal(this);
00330
00331 if (entries.size() > 0) {
00332 m_themeModel->reload();
00333 reloadConfig();
00334 }
00335 }
00336 }
00337
00338 void DesktopThemeDetails::reloadConfig()
00339 {
00340
00341
00342 KConfigGroup cfg = KConfigGroup(KSharedConfig::openConfig("plasmarc"), "Theme");
00343 QString theme = cfg.readEntry("name", "default");
00344 m_theme->setCurrentIndex(m_themeModel->indexOf(theme));
00345
00346 }
00347
00348 void DesktopThemeDetails::save()
00349 {
00350 QString theme;
00351 if (m_newThemeName->text().isEmpty()) {
00352 theme = ".customized";
00353 } else {
00354 theme = m_newThemeName->text().replace(' ',"_").remove(QRegExp("[^A-Za-z0-9_]"));
00355 }
00356
00357
00358 bool newThemeExists = false;
00359 KStandardDirs dirs;
00360 QFile customSettingsFile;
00361 bool customSettingsFileOpen = false;
00362 if (m_themeCustomized || !m_newThemeName->text().isEmpty()) {
00363
00364 if (QDir(dirs.locateLocal("data", "desktoptheme/" + theme + '/', false)).exists()) {
00365 theme = theme + '1';
00366 }
00367 clearCustomized();
00368
00369
00370 QString baseSource = dirs.locate("data", "desktoptheme/" + m_baseTheme + '/');
00371 KIO::CopyJob *copyBaseTheme = KIO::copyAs(KUrl(baseSource), KUrl(dirs.locateLocal("data", "desktoptheme/" + theme, true)), KIO::HideProgressInfo);
00372 KIO::NetAccess::synchronousRun(copyBaseTheme, this);
00373
00374
00375 if (isCustomized(theme)) {
00376 customSettingsFile.setFileName(dirs.locateLocal("data", "desktoptheme/" + theme + "/settings"));
00377 customSettingsFileOpen = customSettingsFile.open(QFile::WriteOnly);
00378 if (customSettingsFileOpen) {
00379 QTextStream out(&customSettingsFile);
00380 out << "baseTheme=" + m_baseTheme + "\r\n";;
00381 }
00382 }
00383
00384
00385
00386 QHashIterator<QString, QString> i(m_themeReplacements);
00387 while (i.hasNext()) {
00388 i.next();
00389 QString source = i.value();
00390 QString itemDir = "desktoptheme/" + theme + '/' + m_themeItems[i.key()];
00391 if (source.right(4).toLower() == ".svg") {
00392 itemDir.append(".svg");
00393 } else if (source.right(5).toLower() == ".svgz") {
00394 itemDir.append(".svgz");
00395 }
00396 QString dest = dirs.locateLocal("data", itemDir, true);
00397 if (QFile::exists(source)) {
00398 QFile::remove(dirs.locateLocal("data", "desktoptheme/" + theme + '/' + m_themeItems[i.key()] + ".svg"));
00399 QFile::remove(dirs.locateLocal("data", "desktoptheme/" + theme + '/' + m_themeItems[i.key()] + ".svgz"));
00400 KIO::file_copy(KUrl(source), KUrl(dest), -1, KIO::HideProgressInfo);
00401 }
00402
00403 if (customSettingsFileOpen) {
00404 QTextStream out(&customSettingsFile);
00405 if (m_dropListFiles.key(source).startsWith("File:") || m_dropListFiles.key(source).startsWith(i18n("(Customized)"))) {
00406 out << i.key() + "=" + dest +"\r\n";
00407 } else {
00408 out << i.key() + "=" + source +"\r\n";
00409 }
00410 }
00411
00412 }
00413 if (customSettingsFileOpen) customSettingsFile.close();
00414
00415
00416 QFile::remove(dirs.locateLocal("data", "desktoptheme/" + theme + "/metadata.desktop", false));
00417 QFile desktopFile(dirs.locateLocal("data", "desktoptheme/" + theme +"/metadata.desktop"));
00418 QString desktopFileData;
00419 if (isCustomized(theme)) {
00420 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);
00421 } else {
00422 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();
00423 }
00424 if (desktopFile.open(QFile::WriteOnly)) {
00425 QTextStream out(&desktopFile);
00426 out << "[Desktop Entry] \r\n" + desktopFileData +" \r\n";
00427 desktopFile.close();
00428 newThemeExists = true;
00429 } else {
00430 KMessageBox::error(this, i18n("Unable to save theme."), i18n("Desktop Theme Details"));
00431 }
00432 m_themeCustomized = false;
00433 }
00434
00435
00436
00437
00438 if (newThemeExists) {
00439 m_themeModel->reload();
00440 m_theme->setCurrentIndex(m_themeModel->indexOf(theme));
00441
00442 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");
00443 }
00444 resetThemeDetails();
00445 }
00446
00447 void DesktopThemeDetails::removeTheme()
00448 {
00449 bool removeTheme = true;
00450 QString theme = m_theme->itemData(m_theme->currentIndex(),
00451 ThemeModel::PackageNameRole).toString();
00452 if (m_themeCustomized) {
00453 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) {
00454 removeTheme = false;
00455 }
00456 } else {
00457 if (theme == "default") {
00458 KMessageBox::information(this, i18n("Removal of the default KDE theme is not allowed."), i18n("Remove Desktop Theme"));
00459 removeTheme = false;
00460 } else {
00461 if(KMessageBox::questionYesNo(this, i18n("Are you sure you wish remove the \"%1\" theme?", m_theme->currentText()), i18n("Remove Desktop Theme")) == KMessageBox::No) {
00462 removeTheme = false;
00463 }
00464 }
00465
00466 }
00467 KStandardDirs dirs;
00468 if (removeTheme) {
00469 if (QDir(dirs.locateLocal("data", "desktoptheme/" + theme, false)).exists()) {
00470 KIO::DeleteJob *deleteTheme = KIO::del(KUrl(dirs.locateLocal("data", "desktoptheme/" + theme, false)), KIO::HideProgressInfo);
00471 KIO::NetAccess::synchronousRun(deleteTheme, this);
00472 }
00473 }
00474 m_themeModel->reload();
00475 reloadConfig();
00476 }
00477
00478 void DesktopThemeDetails::exportTheme()
00479 {
00480 if (m_themeCustomized ||
00481 (m_theme->currentText() == i18n("(Customized)") && m_newThemeName->text() == "")) {
00482 KMessageBox::information(this, i18n("Please apply theme item changes (with a new theme name) before attempting to export theme."), i18n("Export Desktop Theme"));
00483 } else {
00484 QString themeStoragePath = m_theme->itemData(m_theme->currentIndex(),
00485 ThemeModel::PackageNameRole).toString();
00486 KStandardDirs dirs;
00487 kDebug()<<" themeStoragePath "<<themeStoragePath;
00488
00489 if ( themeStoragePath == "default")
00490 {
00491 KConfigGroup cfg = KConfigGroup(KSharedConfig::openConfig("plasmarc"), "Theme");
00492 themeStoragePath = cfg.readEntry("name", "default");
00493 }
00494
00495 QString themePath = dirs.findResource("data", "desktoptheme/" + themeStoragePath + "/metadata.desktop");
00496 if (!themePath.isEmpty())
00497 {
00498 QString expFileName = KFileDialog::getSaveFileName(KUrl(), "*.zip", this, i18n("Export theme to file"));
00499 if (!expFileName.endsWith(".zip"))
00500 expFileName = expFileName + ".zip";
00501 if (!expFileName.isEmpty()) {
00502 KUrl path(themePath);
00503 KZip expFile(expFileName);
00504 expFile.open(QIODevice::WriteOnly);
00505 expFile.addLocalDirectory(path.directory (), themeStoragePath);
00506 expFile.close();
00507 }
00508 }
00509 }
00510
00511 }
00512
00513 void DesktopThemeDetails::loadThemeItems()
00514 {
00515 QStringList themeItemList;
00516 QStringList themeItemIconList;
00517 m_themeItems.clear();
00518 m_themeReplacements.clear();
00519 m_themeItemList->clear();
00520 m_dropListFiles.clear();
00521
00522
00523 for (int i = 0; themeCollectionName[i].m_type; ++i) {
00524 m_themeItems[themeCollectionName[i].m_type] = themeCollectionName[i].m_widgetType;
00525 themeItemList.append(i18nc("plasma name", themeCollectionName[i].m_displayItemName));
00526 m_themeReplacements[i18nc("plasma name", themeCollectionName[i].m_displayItemName)] = "";
00527 themeItemIconList.append(themeCollectionName[i].m_iconName);
00528 }
00529
00530
00531 m_themeItemList->setRowCount(themeItemList.size());
00532 m_themeItemList->setColumnCount(2);
00533 m_themeItemList->setHorizontalHeaderLabels(QStringList()<< i18n("Theme Item")<<i18n("Source"));
00534 QString item;
00535 QStringListIterator i(themeItemList);
00536 int row = 0;
00537 while (i.hasNext()) {
00538 item = i.next();
00539 m_themeItemList->setItem(row, 0, new QTableWidgetItem(item));
00540 m_themeItemList->item(row,0)->setIcon(KIcon(themeItemIconList.at(row)));
00541 m_themeItemList->setCellWidget(row, 1, new QComboBox());
00542 updateReplaceItemList(item);
00543 m_themeItemList->resizeColumnToContents(1);
00544 row++;
00545 }
00546 m_themeItemList->setSelectionBehavior(QAbstractItemView::SelectRows);
00547 m_themeItemList->verticalHeader()->hide();
00548 m_themeItemList->horizontalHeader()->setStretchLastSection(true);
00549 m_themeItemList->horizontalHeader()->setMinimumSectionSize(120);
00550 m_themeItemList->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents);;
00551 m_themeItemList->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);;
00552 m_themeItemList->setCurrentCell(0, 1);
00553 }
00554
00555 void DesktopThemeDetails::updateReplaceItemList(const QString& item)
00556 {
00557 QString currentReplacement = m_themeReplacements[item];
00558 QString replacementDropListItem;
00559 QStringList dropList;
00560 if ((currentReplacement.isEmpty() && m_theme->currentText() != i18n("(Customized)"))){
00561 replacementDropListItem = m_theme->currentText() + " " + item;
00562 }
00563
00564
00565 int itemRow = m_themeItemList->row(m_themeItemList->findItems(item, Qt::MatchExactly).at(0));
00566 QComboBox *currentComboBox = static_cast<QComboBox*>(m_themeItemList->cellWidget(itemRow,1));
00567 disconnect(currentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged()));
00568 currentComboBox->clear();
00569 KStandardDirs dirs;
00570 QStringList themes = dirs.findAllResources("data", "desktoptheme/*/metadata.desktop",
00571 KStandardDirs::NoDuplicates);
00572 themes.sort();
00573 foreach (const QString &theme, themes) {
00574 int themeSepIndex = theme.lastIndexOf('/', -1);
00575 QString themeRoot = theme.left(themeSepIndex);
00576 int themeNameSepIndex = themeRoot.lastIndexOf('/', -1);
00577 QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1);
00578
00579 KDesktopFile df(theme);
00580 QString name = df.readName();
00581 if (name.isEmpty()) {
00582 name = packageName;
00583 }
00584
00585 QString themeItemFile = themeRoot + '/' + m_themeItems[item];
00586
00587 if (QFile::exists(themeItemFile + ".svg")) {
00588 themeItemFile = themeRoot + '/' + m_themeItems[item] + ".svg";
00589 }
00590 if (QFile::exists(themeItemFile + ".svgz")) {
00591 themeItemFile = themeRoot + '/' + m_themeItems[item] + ".svgz";
00592 }
00593 if ((name != i18n("(Customized)")) || (name == i18n("(Customized)") && themeItemFile == currentReplacement)) {
00594 QString dropListItem = i18n("%1 %2",name,item);
00595 if (themeItemFile == currentReplacement) {
00596 replacementDropListItem = dropListItem;
00597 }
00598 dropList << dropListItem;
00599 m_dropListFiles[dropListItem] = themeItemFile;
00600 }
00601 }
00602 if (currentReplacement.isEmpty()) m_themeReplacements[item] = m_dropListFiles[replacementDropListItem];
00603 currentComboBox->addItems(dropList << i18n("File..."));
00604 currentComboBox->setCurrentIndex(currentComboBox->findText(replacementDropListItem));
00605 connect(currentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged()));
00606 }
00607
00608 void DesktopThemeDetails::replacementItemChanged()
00609 {
00610
00611 m_themeCustomized=false;
00612 int i;
00613 for (i = 0; i < m_themeItemList->rowCount(); i++) {
00614 QComboBox *currentComboBox = static_cast<QComboBox*>(m_themeItemList->cellWidget(i, 1));
00615 QString currentReplacement = currentComboBox->currentText();
00616
00617 QString currentItem = m_themeItemList->item(i, 0)->text();
00618 QString originalValue = m_dropListFiles.key(m_themeReplacements[currentItem]);
00619 QString changedValue;
00620
00621 if (currentReplacement == i18n("File...")) {
00622
00623 changedValue = KFileDialog::getOpenFileName(KUrl(), QString(), this, i18n("Select File to Use for %1",currentItem));
00624 if (!changedValue.isEmpty()) {
00625
00626 currentReplacement = "File:" + changedValue;
00627 m_dropListFiles[currentReplacement]=changedValue;
00628 int index = currentComboBox->findText("File:",Qt::MatchStartsWith);
00629 if (index != -1) currentComboBox->removeItem(index);
00630 currentComboBox->addItem(currentReplacement);
00631 } else {
00632 currentReplacement = originalValue;
00633 }
00634 disconnect(currentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged()));
00635 int index = currentComboBox->findText(currentReplacement);
00636 if (index != -1) currentComboBox->setCurrentIndex(index);
00637 connect(currentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(replacementItemChanged()));
00638 } else {
00639
00640 changedValue = m_dropListFiles[currentReplacement];
00641 }
00642
00643 kDebug() << changedValue;
00644 if (changedValue != originalValue) {
00645 m_themeCustomized = true;
00646 m_themeReplacements[currentItem] = changedValue;
00647 }
00648 }
00649 if (m_themeCustomized) emit changed();
00650 }
00651
00652 void DesktopThemeDetails::resetThemeDetails()
00653 {
00654 m_themeInfoName->setText(m_theme->currentText());
00655 m_themeInfoDescription->setText(m_theme->itemData(m_theme->currentIndex(),
00656 ThemeModel::PackageDescriptionRole).toString());
00657 QString author = m_theme->itemData(m_theme->currentIndex(),
00658 ThemeModel::PackageAuthorRole).toString();
00659 if (!author.isEmpty()) {
00660 m_themeInfoAuthor->setText(i18n(" Author: %1",author));
00661 } else {
00662 m_themeInfoAuthor->setText("");
00663 }
00664 QString version = m_theme->itemData(m_theme->currentIndex(),
00665 ThemeModel::PackageVersionRole).toString();
00666 if (!version.isEmpty()) {
00667 m_themeInfoVersion->setText(i18n("Version: %1",version));
00668 } else {
00669 m_themeInfoVersion->setText("");
00670 }
00671 KStandardDirs dirs;
00672 QString theme = m_theme->itemData(m_theme->currentIndex(),
00673 ThemeModel::PackageNameRole).toString();
00674 m_baseTheme = theme;
00675 loadThemeItems();
00676
00677 if (isCustomized(theme)) {
00678 QFile customSettingsFile(dirs.locateLocal("data", "desktoptheme/" + theme +"/settings"));
00679 if (customSettingsFile.open(QFile::ReadOnly)) {
00680 QTextStream in(&customSettingsFile);
00681 QString line;
00682 QStringList settingsPair;
00683 QMap<QString, QString>lst;
00684
00685 for (int i = 0; themeCollectionName[i].m_type; ++i) {
00686 lst.insert(themeCollectionName[i].m_type, i18nc("plasma name", themeCollectionName[i].m_displayItemName));
00687 }
00688
00689 while (!in.atEnd()) {
00690 line = in.readLine();
00691 settingsPair = line.split('=');
00692 if (settingsPair.at(0) == "baseTheme") {
00693 m_baseTheme = settingsPair.at(1);
00694 } else {
00695 m_themeReplacements[lst[settingsPair.at(0)]] = settingsPair.at(1);
00696 updateReplaceItemList(lst[settingsPair.at(0)]);
00697 }
00698 }
00699 customSettingsFile.close();
00700 }
00701 }
00702
00703 m_newThemeName->clear();
00704 m_newThemeAuthor->clear();
00705 m_newThemeVersion->clear();
00706 m_newThemeDescription->clear();
00707 m_enableAdvanced->setChecked(false);
00708 toggleAdvancedVisible();
00709 m_themeCustomized = false;
00710 }
00711
00712 void DesktopThemeDetails::toggleAdvancedVisible()
00713 {
00714 m_newThemeNameLabel->setVisible(m_enableAdvanced->isChecked());
00715 m_newThemeName->setVisible(m_enableAdvanced->isChecked());
00716 m_newThemeAuthor->setVisible(m_enableAdvanced->isChecked());
00717 m_newThemeAuthorLabel->setVisible(m_enableAdvanced->isChecked());
00718 m_newThemeVersion->setVisible(m_enableAdvanced->isChecked());
00719 m_newThemeVersionLabel->setVisible(m_enableAdvanced->isChecked());
00720 m_newThemeDescriptionLabel->setVisible(m_enableAdvanced->isChecked());
00721 m_newThemeDescription->setVisible(m_enableAdvanced->isChecked());
00722 m_exportThemeButton->setVisible(m_enableAdvanced->isChecked());
00723 m_removeThemeButton->setVisible(m_enableAdvanced->isChecked());
00724 m_advancedLine->setVisible(m_enableAdvanced->isChecked());
00725 }
00726
00727 bool DesktopThemeDetails::isCustomized(const QString& theme) {
00728 if (theme == ".customized" || theme == ".customized1") {
00729 return true;
00730 } else {
00731 return false;
00732 }
00733 }
00734
00735 void DesktopThemeDetails::clearCustomized() {
00736 KStandardDirs dirs;
00737 if (QDir(dirs.locateLocal("data", "desktoptheme/.customized", false)).exists()) {
00738 KIO::DeleteJob *clearCustom = KIO::del(KUrl(dirs.locateLocal("data", "desktoptheme/.customized", false)), KIO::HideProgressInfo);
00739 KIO::NetAccess::synchronousRun(clearCustom, this);
00740 }
00741 if (QDir(dirs.locateLocal("data", "desktoptheme/.customized1", false)).exists()) {
00742 KIO::DeleteJob *clearCustom1 = KIO::del(KUrl(dirs.locateLocal("data", "desktoptheme/.customized1", false)), KIO::HideProgressInfo);
00743 KIO::NetAccess::synchronousRun(clearCustom1, this);
00744 }
00745 }
00746
00747