summaryrefslogtreecommitdiffstats
path: root/kcontrol/icons/iconthemes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kcontrol/icons/iconthemes.cpp')
-rw-r--r--kcontrol/icons/iconthemes.cpp452
1 files changed, 452 insertions, 0 deletions
diff --git a/kcontrol/icons/iconthemes.cpp b/kcontrol/icons/iconthemes.cpp
new file mode 100644
index 000000000..fe0a59ee7
--- /dev/null
+++ b/kcontrol/icons/iconthemes.cpp
@@ -0,0 +1,452 @@
+/**
+ * Copyright (c) 2000 Antonio Larrosa <larrosa@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <tqfileinfo.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqpushbutton.h>
+
+#include <kdebug.h>
+#include <tdeapplication.h>
+#include <kstandarddirs.h>
+#include <kservice.h>
+#include <tdelocale.h>
+#include <ksimpleconfig.h>
+#undef Unsorted
+#include <kipc.h>
+
+#include <tdelistview.h>
+#include <kurlrequesterdlg.h>
+#include <tdemessagebox.h>
+#include <kprogress.h>
+#include <kiconloader.h>
+
+#include <tdeio/job.h>
+#include <tdeio/netaccess.h>
+#include <ktar.h>
+
+#ifdef HAVE_LIBART
+#include <ksvgiconengine.h>
+#endif
+
+#include "iconthemes.h"
+
+IconThemesConfig::IconThemesConfig(TQWidget *parent, const char *name)
+ : TDECModule(parent, name)
+{
+ TQVBoxLayout *topLayout = new TQVBoxLayout(this, KDialog::marginHint(),
+ KDialog::spacingHint());
+
+ TQFrame *m_preview=new TQFrame(this);
+ m_preview->setMinimumHeight(50);
+
+ TQHBoxLayout *lh2=new TQHBoxLayout( m_preview );
+ m_previewExec=new TQLabel(m_preview);
+ m_previewExec->setPixmap(DesktopIcon("exec"));
+ m_previewFolder=new TQLabel(m_preview);
+ m_previewFolder->setPixmap(DesktopIcon("folder"));
+ m_previewDocument=new TQLabel(m_preview);
+ m_previewDocument->setPixmap(DesktopIcon("document"));
+
+ lh2->addStretch(10);
+ lh2->addWidget(m_previewExec);
+ lh2->addStretch(1);
+ lh2->addWidget(m_previewFolder);
+ lh2->addStretch(1);
+ lh2->addWidget(m_previewDocument);
+ lh2->addStretch(10);
+
+
+ m_iconThemes=new TDEListView(this,"IconThemeList");
+ m_iconThemes->addColumn(i18n("Name"));
+ m_iconThemes->addColumn(i18n("Description"));
+ m_iconThemes->setAllColumnsShowFocus( true );
+ m_iconThemes->setFullWidth(true);
+ connect(m_iconThemes,TQT_SIGNAL(selectionChanged(TQListViewItem *)),
+ TQT_SLOT(themeSelected(TQListViewItem *)));
+
+ TQPushButton *installButton=new TQPushButton( i18n("Install New Theme..."),
+ this, "InstallNewTheme");
+ connect(installButton,TQT_SIGNAL(clicked()),TQT_SLOT(installNewTheme()));
+ m_removeButton=new TQPushButton( i18n("Remove Theme"),
+ this, "RemoveTheme");
+ connect(m_removeButton,TQT_SIGNAL(clicked()),TQT_SLOT(removeSelectedTheme()));
+
+ topLayout->addWidget(
+ new TQLabel(i18n("Select the icon theme you want to use:"), this));
+ topLayout->addWidget(m_preview);
+ topLayout->addWidget(m_iconThemes);
+ TQHBoxLayout *lg = new TQHBoxLayout(topLayout, KDialog::spacingHint());
+ lg->addWidget(installButton);
+ lg->addWidget(m_removeButton);
+
+ loadThemes();
+
+ load();
+
+ m_iconThemes->setFocus();
+}
+
+IconThemesConfig::~IconThemesConfig()
+{
+}
+
+TQListViewItem *IconThemesConfig::iconThemeItem(const TQString &name)
+{
+ TQListViewItem *item;
+ for ( item=m_iconThemes->firstChild(); item ; item=item->nextSibling() )
+ if (m_themeNames[item->text(0)]==name) return item;
+
+ return 0L;
+}
+
+void IconThemesConfig::loadThemes()
+{
+ m_iconThemes->clear();
+ m_themeNames.clear();
+ TQStringList themelist(TDEIconTheme::list());
+ TQString name;
+ TQString tname;
+ TQStringList::Iterator it;
+ for (it=themelist.begin(); it != themelist.end(); ++it)
+ {
+ TDEIconTheme icontheme(*it);
+ if (!icontheme.isValid()) kdDebug() << "notvalid\n";
+ if (icontheme.isHidden()) continue;
+
+ name=icontheme.name();
+ tname=name;
+
+ // Just in case we have duplicated icon theme names on separate directories
+ for (int i=2; m_themeNames.find(tname)!=m_themeNames.end() ; i++)
+ tname=TQString("%1-%2").arg(name).arg(i);
+
+ m_iconThemes->insertItem(new TQListViewItem(m_iconThemes,name,
+ icontheme.description()));
+
+ m_themeNames.insert(name,*it);
+
+ }
+}
+
+void IconThemesConfig::installNewTheme()
+{
+ KURL themeURL = KURLRequesterDlg::getURL(TQString::null, this,
+ i18n("Drag or Type Theme URL"));
+ kdDebug() << themeURL.prettyURL() << endl;
+
+ if (themeURL.url().isEmpty()) return;
+
+ TQString themeTmpFile;
+ // themeTmpFile contains the name of the downloaded file
+
+ if (!TDEIO::NetAccess::download(themeURL, themeTmpFile, this)) {
+ TQString sorryText;
+ if (themeURL.isLocalFile())
+ sorryText = i18n("Unable to find the icon theme archive %1.");
+ else
+ sorryText = i18n("Unable to download the icon theme archive;\n"
+ "please check that address %1 is correct.");
+ KMessageBox::sorry(this, sorryText.arg(themeURL.prettyURL()));
+ return;
+ }
+
+ TQStringList themesNames = findThemeDirs(themeTmpFile);
+ if (themesNames.isEmpty()) {
+ TQString invalidArch(i18n("The file is not a valid icon theme archive."));
+ KMessageBox::error(this, invalidArch);
+
+ TDEIO::NetAccess::removeTempFile(themeTmpFile);
+ return;
+ }
+
+ if (!installThemes(themesNames, themeTmpFile)) {
+ //FIXME: make me able to know what is wrong....
+ // TQStringList instead of bool?
+ TQString somethingWrong =
+ i18n("A problem occurred during the installation process; "
+ "however, most of the themes in the archive have been installed");
+ KMessageBox::error(this, somethingWrong);
+ }
+
+ TDEIO::NetAccess::removeTempFile(themeTmpFile);
+
+ TDEGlobal::instance()->newIconLoader();
+ loadThemes();
+
+ TQListViewItem *item=iconThemeItem(TDEIconTheme::current());
+ m_iconThemes->setSelected(item, true);
+ updateRemoveButton();
+}
+
+bool IconThemesConfig::installThemes(const TQStringList &themes, const TQString &archiveName)
+{
+ bool everythingOk = true;
+ TQString localThemesDir(locateLocal("icon", "./"));
+
+ KProgressDialog progressDiag(this, "themeinstallprogress",
+ i18n("Installing icon themes"),
+ TQString::null,
+ true);
+ progressDiag.setAutoClose(true);
+ progressDiag.progressBar()->setTotalSteps(themes.count());
+ progressDiag.show();
+
+ KTar archive(archiveName);
+ archive.open(IO_ReadOnly);
+ kapp->processEvents();
+
+ const KArchiveDirectory* rootDir = archive.directory();
+
+ KArchiveDirectory* currentTheme;
+ for (TQStringList::ConstIterator it = themes.begin();
+ it != themes.end();
+ ++it) {
+ progressDiag.setLabel(
+ i18n("<qt>Installing <strong>%1</strong> theme</qt>")
+ .arg(*it));
+ kapp->processEvents();
+
+ if (progressDiag.wasCancelled())
+ break;
+
+ currentTheme = dynamic_cast<KArchiveDirectory*>(
+ const_cast<KArchiveEntry*>(
+ rootDir->entry(*it)));
+ if (currentTheme == NULL) {
+ // we tell back that something went wrong, but try to install as much
+ // as possible
+ everythingOk = false;
+ continue;
+ }
+
+ currentTheme->copyTo(localThemesDir + *it);
+ progressDiag.progressBar()->advance(1);
+ }
+
+ archive.close();
+ return everythingOk;
+}
+
+TQStringList IconThemesConfig::findThemeDirs(const TQString &archiveName)
+{
+ TQStringList foundThemes;
+
+ KTar archive(archiveName);
+ archive.open(IO_ReadOnly);
+ const KArchiveDirectory* themeDir = archive.directory();
+
+ KArchiveEntry* possibleDir = 0L;
+ KArchiveDirectory* subDir = 0L;
+
+ // iterate all the dirs looking for an index.theme or index.desktop file
+ TQStringList entries = themeDir->entries();
+ for (TQStringList::Iterator it = entries.begin();
+ it != entries.end();
+ ++it) {
+ possibleDir = const_cast<KArchiveEntry*>(themeDir->entry(*it));
+ if (possibleDir->isDirectory()) {
+ subDir = dynamic_cast<KArchiveDirectory*>( possibleDir );
+ if (subDir && (subDir->entry("index.theme") != NULL ||
+ subDir->entry("index.desktop") != NULL))
+ foundThemes.append(subDir->name());
+ }
+ }
+
+ archive.close();
+ return foundThemes;
+}
+
+void IconThemesConfig::removeSelectedTheme()
+{
+ TQListViewItem *selected = m_iconThemes->selectedItem();
+ if (!selected)
+ return;
+
+ TQString question=i18n("<qt>Are you sure you want to remove the "
+ "<strong>%1</strong> icon theme?<br>"
+ "<br>"
+ "This will delete the files installed by this theme.</qt>").
+ arg(selected->text(0));
+
+ bool deletingCurrentTheme=(selected==iconThemeItem(TDEIconTheme::current()));
+
+ int r=KMessageBox::warningContinueCancel(this,question,i18n("Confirmation"),KStdGuiItem::del());
+ if (r!=KMessageBox::Continue) return;
+
+ TDEIconTheme icontheme(m_themeNames[selected->text(0)]);
+
+ // delete the index file before the async TDEIO::del so loadThemes() will
+ // ignore that dir.
+ unlink(TQFile::encodeName(icontheme.dir()+"/index.theme").data());
+ unlink(TQFile::encodeName(icontheme.dir()+"/index.desktop").data());
+ TDEIO::del(KURL( icontheme.dir() ));
+
+ TDEGlobal::instance()->newIconLoader();
+
+ loadThemes();
+
+ TQListViewItem *item=0L;
+ //Fallback to the default if we've deleted the current theme
+ if (!deletingCurrentTheme)
+ item=iconThemeItem(TDEIconTheme::current());
+ if (!item)
+ item=iconThemeItem(TDEIconTheme::defaultThemeName());
+
+ m_iconThemes->setSelected(item, true);
+ updateRemoveButton();
+
+ if (deletingCurrentTheme) // Change the configuration
+ save();
+}
+
+void IconThemesConfig::updateRemoveButton()
+{
+ TQListViewItem *selected = m_iconThemes->selectedItem();
+ bool enabled = false;
+ if (selected)
+ {
+ TDEIconTheme icontheme(m_themeNames[selected->text(0)]);
+ TQFileInfo fi(icontheme.dir());
+ enabled = fi.isWritable();
+ // Don't let users remove the current theme.
+ if(m_themeNames[selected->text(0)] == TDEIconTheme::current() ||
+ m_themeNames[selected->text(0)] == TDEIconTheme::defaultThemeName())
+ enabled = false;
+ }
+ m_removeButton->setEnabled(enabled);
+}
+
+void IconThemesConfig::themeSelected(TQListViewItem *item)
+{
+#ifdef HAVE_LIBART
+ KSVGIconEngine engine;
+#endif
+ TQString dirName(m_themeNames[item->text(0)]);
+ TDEIconTheme icontheme(dirName);
+ if (!icontheme.isValid()) kdDebug() << "notvalid\n";
+
+ updateRemoveButton();
+ const int size = icontheme.defaultSize(TDEIcon::Desktop);
+
+ TDEIcon icon=icontheme.iconPath("exec.png", size, TDEIcon::MatchBest);
+ if (!icon.isValid()) {
+#ifdef HAVE_LIBART
+ icon=icontheme.iconPath("exec.svg", size, TDEIcon::MatchBest);
+ if(engine.load(size, size, icon.path))
+ m_previewExec->setPixmap(*engine.image());
+ else {
+ icon=icontheme.iconPath("exec.svgz", size, TDEIcon::MatchBest);
+ if(engine.load(size, size, icon.path))
+ m_previewExec->setPixmap(*engine.image());
+ }
+#endif
+ }
+ else
+ m_previewExec->setPixmap(TQPixmap(icon.path));
+
+ icon=icontheme.iconPath("folder.png",size,TDEIcon::MatchBest);
+ if (!icon.isValid()) {
+#ifdef HAVE_LIBART
+ icon=icontheme.iconPath("folder.svg", size, TDEIcon::MatchBest);
+ if(engine.load(size, size, icon.path))
+ m_previewFolder->setPixmap(*engine.image());
+ else {
+ icon=icontheme.iconPath("folder.svgz", size, TDEIcon::MatchBest);
+ if(engine.load(size, size, icon.path))
+ m_previewFolder->setPixmap(*engine.image());
+ }
+#endif
+ }
+ else
+ m_previewFolder->setPixmap(TQPixmap(icon.path));
+
+ icon=icontheme.iconPath("txt.png",size,TDEIcon::MatchBest);
+ if (!icon.isValid()) {
+#ifdef HAVE_LIBART
+ icon=icontheme.iconPath("txt.svg", size, TDEIcon::MatchBest);
+ if(engine.load(size, size, icon.path))
+ m_previewDocument->setPixmap(*engine.image());
+ else {
+ icon=icontheme.iconPath("txt.svgz", size, TDEIcon::MatchBest);
+ if(engine.load(size, size, icon.path))
+ m_previewDocument->setPixmap(*engine.image());
+ }
+#endif
+ }
+ else
+ m_previewDocument->setPixmap(TQPixmap(icon.path));
+
+ emit changed(true);
+ m_bChanged = true;
+}
+
+void IconThemesConfig::load()
+{
+ m_defaultTheme=iconThemeItem(TDEIconTheme::current());
+ m_iconThemes->setSelected(m_defaultTheme, true);
+ updateRemoveButton();
+
+ emit changed(false);
+ m_bChanged = false;
+}
+
+void IconThemesConfig::save()
+{
+ if (!m_bChanged)
+ return;
+ TQListViewItem *selected = m_iconThemes->selectedItem();
+ if (!selected)
+ return;
+
+ KSimpleConfig *config = new KSimpleConfig("kdeglobals", false);
+ config->setGroup("Icons");
+ config->writeEntry("Theme", m_themeNames[selected->text(0)]);
+ delete config;
+
+ TDEIconTheme::reconfigure();
+ emit changed(false);
+
+ for (int i=0; i<TDEIcon::LastGroup; i++)
+ {
+ KIPC::sendMessageAll(KIPC::IconChanged, i);
+ }
+
+ KService::rebuildKSycoca(this);
+
+ m_bChanged = false;
+ m_removeButton->setEnabled(false);
+}
+
+void IconThemesConfig::defaults()
+{
+ if (m_iconThemes->currentItem()==m_defaultTheme) return;
+
+ m_iconThemes->setSelected(m_defaultTheme, true);
+ updateRemoveButton();
+
+ emit changed(true);
+ m_bChanged = true;
+}
+
+#include "iconthemes.moc"