diff options
Diffstat (limited to 'kcontrol/kthememanager')
-rw-r--r-- | kcontrol/kthememanager/CMakeLists.txt | 38 | ||||
-rw-r--r-- | kcontrol/kthememanager/Makefile.am | 21 | ||||
-rw-r--r-- | kcontrol/kthememanager/NEWS | 26 | ||||
-rw-r--r-- | kcontrol/kthememanager/README | 99 | ||||
-rw-r--r-- | kcontrol/kthememanager/TODO | 9 | ||||
-rw-r--r-- | kcontrol/kthememanager/installktheme.desktop | 78 | ||||
-rwxr-xr-x | kcontrol/kthememanager/kdeinstallktheme | 14 | ||||
-rw-r--r-- | kcontrol/kthememanager/knewthemedlg.cpp | 96 | ||||
-rw-r--r-- | kcontrol/kthememanager/knewthemedlg.h | 58 | ||||
-rw-r--r-- | kcontrol/kthememanager/ktheme.cpp | 900 | ||||
-rw-r--r-- | kcontrol/kthememanager/ktheme.h | 224 | ||||
-rw-r--r-- | kcontrol/kthememanager/kthemedlg.ui | 518 | ||||
-rw-r--r-- | kcontrol/kthememanager/kthemedlg.ui.h | 49 | ||||
-rw-r--r-- | kcontrol/kthememanager/kthememanager.cpp | 425 | ||||
-rw-r--r-- | kcontrol/kthememanager/kthememanager.desktop | 221 | ||||
-rw-r--r-- | kcontrol/kthememanager/kthememanager.h | 157 | ||||
-rw-r--r-- | kcontrol/kthememanager/newthemewidget.ui | 130 | ||||
-rw-r--r-- | kcontrol/kthememanager/x-ktheme.desktop | 84 |
18 files changed, 3147 insertions, 0 deletions
diff --git a/kcontrol/kthememanager/CMakeLists.txt b/kcontrol/kthememanager/CMakeLists.txt new file mode 100644 index 000000000..b3d000aa5 --- /dev/null +++ b/kcontrol/kthememanager/CMakeLists.txt @@ -0,0 +1,38 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + +##### other data ################################ + +install( FILES kthememanager.desktop installktheme.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) +install( FILES x-ktheme.desktop DESTINATION ${MIME_INSTALL_DIR}/application ) +install( PROGRAMS kdeinstallktheme DESTINATION ${BIN_INSTALL_DIR} ) + + +##### kcm_kthememanager (module) ################ + +tde_add_kpart( kcm_kthememanager AUTOMOC + SOURCES + kthemedlg.ui newthemewidget.ui knewthemedlg.cpp + ktheme.cpp kthememanager.cpp + LINK tdeio-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/kcontrol/kthememanager/Makefile.am b/kcontrol/kthememanager/Makefile.am new file mode 100644 index 000000000..cbc241dd9 --- /dev/null +++ b/kcontrol/kthememanager/Makefile.am @@ -0,0 +1,21 @@ +AM_CPPFLAGS = $(all_includes) +METASOURCES = AUTO + +kde_module_LTLIBRARIES = kcm_kthememanager.la + +kcm_kthememanager_la_SOURCES = kthemedlg.ui newthemewidget.ui knewthemedlg.cpp ktheme.cpp kthememanager.cpp +kcm_kthememanager_la_LIBADD = $(LIB_TDEIO) +kcm_kthememanager_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module + +noinst_HEADERS = kthememanager.h ktheme.h knewthemedlg.h kthemedlg.ui.h + +xdg_apps_DATA = kthememanager.desktop installktheme.desktop + +# MIME type +kthememime_DATA = x-ktheme.desktop +kthememimedir = $(kde_mimedir)/application + +bin_SCRIPTS = kdeinstallktheme + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kthememanager.pot diff --git a/kcontrol/kthememanager/NEWS b/kcontrol/kthememanager/NEWS new file mode 100644 index 000000000..23cd860ee --- /dev/null +++ b/kcontrol/kthememanager/NEWS @@ -0,0 +1,26 @@ +Version 0.4 +=========== +- added support for screensaver +- fixed Kicker transparency not being saved correctly + +Version 0.3 +=========== +- the theme manager now correctly handles installing and creating + new themes over existing ones +- support for widget styles (or the name thereof) +- added new details buttons to launch idividual kcm style-related + modules +- write/read the current theme and preselect it at startup +- the preview pixmap is now generated dynamically + and taken at full size + +Version 0.2 +=========== +- support for colorizing the Kicker background +- support for relative URLs, as the README states +- installing themes via DnD, even remote ones +- installing themes via context (service) menu from Konqueror + +Version 0.1 +=========== +- first release diff --git a/kcontrol/kthememanager/README b/kcontrol/kthememanager/README new file mode 100644 index 000000000..cd32a528a --- /dev/null +++ b/kcontrol/kthememanager/README @@ -0,0 +1,99 @@ +This theme manager should handle installing, removing +and creating global visual KDE themes. It's written +from scratch, totally unrelated to the old kthememgr +which was not maintained and obsolete. + +*** WARNING *** +The XML file format is still subject to change! +*** WARNING *** + +(c) 2003, 2004 Lukas Tinkl <[email protected]> + + +A KDE theme consists of: +======================== +- wallpapers or bg colors +- icons +- sounds +- color scheme +- cursor theme +- window decorations +- screensaver +- name of the widget theme +- themed apps (mainly Konqueror and Kicker) + + +Sample XML theme config file: +============================= +<ktheme version="1"> +<general> + <author value="Me" /> + <email value="[email protected]" /> + <homepage value="http://me.home.com" /> + <version value="0.1" /> + <comment value="this is a nice theme, bla bla" /> +</general> +<desktop number="0" common="true|false"> + <mode id="Flat|Pattern|*Gradient" /> + <color1 rgb="#123456" /> + <color2 rgb="#123456" /> + <blending mode="" balance="" reverse="true|false" /> + <pattern name="fish" /> + <wallpaper url="theme:/wallpapers/desktop/image.jpg" + mode="Centred|Tiled|CenterTiled|CentredMaxpect|TiledMaxpect|Scaled|CentredAutoFit" /> +</desktop> +<icons name="crystalsvg" /> +<sounds> + <event object="global|twin" name="eventname" url="theme:/sounds/file.wav" /> + ... +</sounds> +<colors contrast="7"> + <alternateBackground rgb="#123456" object="global|twin"/> + ... +</colors> +<cursors name="theme_name" /> +<wm type="builtin|custom" name="twin_lib_name"> + <buttons left="M" right="HIAX" /> + <border size="number" /> +</wm> +<konqueror> + <wallpaper url="" /> + <bgcolor rgb="#123456" /> +</konqueror> +<panel> + <background url="theme:/wallpapers/panel.png" colorize="true|false" /> + <!-- or --> + <transparent value="true|false" /> +</panel> +<widgets name="Style Name" /> +<screensaver name="saver.desktop" /> +</kdetheme> + + +Theme storage: +============== +- a gzipped tarball, directory tree based (e.g. theme.kth) + + +Sample dir tree: +================ +-- mytheme.kth + - mytheme.xml + - mytheme.preview.png + - sounds/ + - wallpapers/ + - konqueror/ + - desktop/ + - panel/ + + +The notion of "url" here: +========================= +- local: points to an already installed file in the system + (must be a sole filename, e.g. "background.png"); this differs + according to the theme part (ie. can be different for sounds + and/or wallpapers) +- theme: relative to the root of the theme tarball or directory + (e.g. theme:/wallpapers/desktop/image.png) +- other URLs are not allowed, the file must be contained + either in the theme or in the target system diff --git a/kcontrol/kthememanager/TODO b/kcontrol/kthememanager/TODO new file mode 100644 index 000000000..59bea20c7 --- /dev/null +++ b/kcontrol/kthememanager/TODO @@ -0,0 +1,9 @@ +- use KHotNewStuff for directly downloading themes from kde-look.org +- custom pixmap twin themes (requires kwmtheme to be ported first) +- write user and theme developer documentation + +Handle: +- splash screen (+ copying?) +- TDE Menu sidebar pixmap +- bundling the cursor theme +- slideshow and "active" background program diff --git a/kcontrol/kthememanager/installktheme.desktop b/kcontrol/kthememanager/installktheme.desktop new file mode 100644 index 000000000..52674fa80 --- /dev/null +++ b/kcontrol/kthememanager/installktheme.desktop @@ -0,0 +1,78 @@ +[Desktop Entry] +Name=Install TDE Theme +Name[af]=Installeer TDE temas +Name[ar]=ثبِت سمة TDE +Name[az]=TDE Örtüyünü Qur +Name[be]=Устаноўка тэмы TDE +Name[bg]=Инсталиране на тема +Name[bn]=কে.ডি.ই. থীম ইনস্টল করো +Name[br]=Staliañ ar c'hiz TDE +Name[bs]=Instaliraj TDE temu +Name[ca]=Instal·la tema TDE +Name[cs]=Instalovat TDE motiv +Name[csb]=Instalëjë témã TDE +Name[cy]=Gosod Thema TDE +Name[da]=Installér TDE-tema +Name[de]=TDE-Design installieren +Name[el]=Εγκατάσταση θέματος του TDE +Name[eo]=Instali TDEan etoson +Name[es]=Instalar tema de TDE +Name[et]=TDE teema paigaldamine +Name[eu]=Instalatu TDE gaia +Name[fa]=نصب چهرۀ TDE +Name[fi]=Asenna TDE-teema +Name[fr]=Installer des thèmes TDE +Name[fy]=TDE-tema ynstallearje +Name[ga]=Suiteáil Téama TDE +Name[gl]=Instalar tema de TDE +Name[he]=התקנה של ערכת נושא עבור TDE +Name[hi]=केडीई प्रसंग संस्थापित करें +Name[hr]=Instaliranje TDE teme +Name[hu]=TDE-téma telepítése +Name[is]=Setja inn TDE þemu +Name[it]=Installa tema di TDE +Name[ja]=TDE テーマのインストール +Name[ka]=TDE-ს თემების დაყენება +Name[kk]=TDE нақыштарын орнату +Name[km]=ដំឡើងស្បែក TDE +Name[ko]=TDE 테마 설치 +Name[lt]=Įdiegti TDE temą +Name[lv]=Instalēt TDE tēmu +Name[mk]=Инсталирај TDE Тема +Name[ms]=Pasang Tema TDE +Name[mt]=Installa Tema TDE +Name[nb]=Legg inn TDE-tema +Name[nds]=TDE-Muster installeren +Name[ne]=TDE विषयवस्तु स्थापना गर्नुहोस् +Name[nl]=TDE-thema installeren +Name[nn]=Installer TDE-tema +Name[pa]=TDE ਸਰੂਪ ਇੰਸਟਾਲ +Name[pl]=Instaluj motyw TDE +Name[pt]=Instalar um Tema do TDE +Name[pt_BR]=Instalar Tema do TDE +Name[ro]=Instalează tematică TDE +Name[ru]=Установка тем TDE +Name[rw]=Kwinjiza Insanganyamatsiko TDE +Name[se]=Sajáiduhte TDE-fáttá +Name[sk]=Inštalovať tému TDE +Name[sl]=Namesti temo TDE +Name[sr]=Инсталирај TDE тему +Name[sr@Latn]=Instaliraj TDE temu +Name[sv]=Installera TDE-tema +Name[ta]=TDE பொருளை நிறுவு +Name[tg]=Мавзӯъи TDE сабт кунед +Name[th]=ติดตั้งชุดตกแต่ง TDE +Name[tr]=TDE Teması Yükle +Name[tt]=TDE Tışlaw quyu +Name[uk]=Встановлення теми TDE +Name[uz]=TDE mavzusini oʻrnatish +Name[uz@cyrillic]=TDE мавзусини ўрнатиш +Name[vi]=Cài đặt Sắc thái TDE +Name[wa]=Astaler on tinme TDE +Name[zh_CN]=安装 TDE 主题 +Name[zh_TW]=安裝 TDE 佈景 +MimeType=application/x-ktheme; +Icon=kthememgr +Type=Application +NoDisplay=true +Exec=kdeinstallktheme %f diff --git a/kcontrol/kthememanager/kdeinstallktheme b/kcontrol/kthememanager/kdeinstallktheme new file mode 100755 index 000000000..95b40eec6 --- /dev/null +++ b/kcontrol/kthememanager/kdeinstallktheme @@ -0,0 +1,14 @@ +#!/bin/sh +# Installs a KDE theme (into the user's theme dir) +appsdir=`tde-config --path data | sed -e 's/:.*//'` +themedir=$appsdir"/kthememanager/themes/"`basename "$1" ".kth"` +if test -n "$appsdir"; then + test -d "$themedir" || mkdir -p "$themedir" + #echo "$themedir" + cp -f "$1" "$themedir" + cd "$themedir" + tarball=`basename "$1"` + #echo $tarball + tar xzf "$tarball" + rm -f "$tarball" +fi diff --git a/kcontrol/kthememanager/knewthemedlg.cpp b/kcontrol/kthememanager/knewthemedlg.cpp new file mode 100644 index 000000000..ee18c31c7 --- /dev/null +++ b/kcontrol/kthememanager/knewthemedlg.cpp @@ -0,0 +1,96 @@ +// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*- +/* Copyright (C) 2003 Lukas Tinkl <[email protected]> + + 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 "knewthemedlg.h" +#include "newthemewidget.h" + +#include <tqlineedit.h> +#include <tqtextedit.h> + +#include <tdelocale.h> + +KNewThemeDlg::KNewThemeDlg( TQWidget * parent, const char * name ) + : KDialogBase(parent, name, true, i18n("New Theme"), Ok|Cancel, Ok) +{ + m_base = new NewThemeWidget( this, "new_theme_base" ); + setMainWidget( m_base ); + connect( m_base->leName, TQT_SIGNAL( textChanged ( const TQString & ) ), this, TQT_SLOT( slotThemeNameChanged( const TQString & ) ) ); + slotThemeNameChanged( m_base->leName->text() ); +} + +KNewThemeDlg::~KNewThemeDlg() +{ + delete m_base; +} + +void KNewThemeDlg::slotThemeNameChanged( const TQString &_text ) +{ + enableButtonOK( !_text.isEmpty() ); +} + +TQString KNewThemeDlg::getName() const +{ + return m_base->leName->text(); +} + +TQString KNewThemeDlg::getAuthor() const +{ + return m_base->leAuthor->text(); +} + +TQString KNewThemeDlg::getEmail() const +{ + return m_base->leEmail->text(); +} + +TQString KNewThemeDlg::getHomepage() const +{ + return m_base->leHomepage->text(); +} + +TQString KNewThemeDlg::getComment() const +{ + return m_base->teComment->text(); +} + +TQString KNewThemeDlg::getVersion() const +{ + return m_base->leVersion->text(); +} + +void KNewThemeDlg::setAuthor( const TQString & author ) +{ + m_base->leAuthor->setText( author ); +} + +void KNewThemeDlg::setEmail( const TQString & email ) +{ + m_base->leEmail->setText( email ); +} + +void KNewThemeDlg::setVersion( const TQString & version ) +{ + m_base->leVersion->setText( version ); +} + +void KNewThemeDlg::setName( const TQString & name ) +{ + m_base->leName->setText( name ); +} + +#include "knewthemedlg.moc" diff --git a/kcontrol/kthememanager/knewthemedlg.h b/kcontrol/kthememanager/knewthemedlg.h new file mode 100644 index 000000000..5a0df045a --- /dev/null +++ b/kcontrol/kthememanager/knewthemedlg.h @@ -0,0 +1,58 @@ +// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*- +/* Copyright (C) 2003 Lukas Tinkl <[email protected]> + + 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 +*/ + +#ifndef KNEWTHEMEDLG_H +#define KNEWTHEMEDLG_H + +#include <tqstring.h> + +#include <kdialogbase.h> + +class NewThemeWidget; + +/** + * Dialog for creating new themes, contains just + * getters and setters used for the theme general properties + * @author Lukas Tinkl <[email protected]> + */ +class KNewThemeDlg: public KDialogBase +{ + Q_OBJECT +public: + KNewThemeDlg( TQWidget * parent = 0, const char * name = 0); + ~KNewThemeDlg(); + + TQString getName() const; + TQString getAuthor() const; + TQString getEmail() const; + TQString getHomepage() const; + TQString getComment() const; + TQString getVersion() const; + + void setName( const TQString & name ); + void setAuthor( const TQString & author ); + void setEmail( const TQString & email ); + void setVersion( const TQString & version ); +private: + NewThemeWidget * m_base; + +private slots: + void slotThemeNameChanged( const TQString &_text ); +}; + +#endif diff --git a/kcontrol/kthememanager/ktheme.cpp b/kcontrol/kthememanager/ktheme.cpp new file mode 100644 index 000000000..0dcee8105 --- /dev/null +++ b/kcontrol/kthememanager/ktheme.cpp @@ -0,0 +1,900 @@ +// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*- +/* Copyright (C) 2003 Lukas Tinkl <[email protected]> + +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 "ktheme.h" + +#include <tqfile.h> +#include <tqfileinfo.h> +#include <tqimage.h> +#include <tqpixmap.h> +#include <tqregexp.h> +#include <tqtextstream.h> +#include <tqdir.h> + +#include <dcopclient.h> +#include <tdeapplication.h> +#include <tdeconfig.h> +#include <kdatastream.h> +#include <kdebug.h> +#include <tdeglobal.h> +#include <kiconloader.h> +#include <tdeio/job.h> +#include <tdeio/netaccess.h> +#include <kipc.h> +#include <tdelocale.h> +#include <kservice.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <ktar.h> +#include <tdestyle.h> + +KTheme::KTheme( TQWidget *parent, const TQString & xmlFile ) + : m_parent(parent) +{ + TQFile file( xmlFile ); + file.open( IO_ReadOnly ); + m_dom.setContent( TQByteArray(file.readAll()) ); + file.close(); + + //kdDebug() << m_dom.toString( 2 ) << endl; + + setName( TQFileInfo( file ).baseName() ); + m_kgd = TDEGlobal::dirs(); +} + +KTheme::KTheme( TQWidget *parent, bool create ) + : m_parent(parent) +{ + if ( create ) + { + m_dom = TQDomDocument( "ktheme" ); + + m_root = m_dom.createElement( "ktheme" ); + m_root.setAttribute( "version", SYNTAX_VERSION ); + m_dom.appendChild( m_root ); + + m_general = m_dom.createElement( "general" ); + m_root.appendChild( m_general ); + } + + m_kgd = TDEGlobal::dirs(); +} + +KTheme::~KTheme() +{ +} + +void KTheme::setName( const TQString & name ) +{ + m_name = name; +} + +bool KTheme::load( const KURL & url ) +{ + kdDebug() << "Loading theme from URL: " << url << endl; + + TQString tmpFile; + if ( !TDEIO::NetAccess::download( url, tmpFile, 0L ) ) + return false; + + kdDebug() << "Theme is in temp file: " << tmpFile << endl; + + // set theme's name + setName( TQFileInfo( url.fileName() ).baseName() ); + + // unpack the tarball + TQString location = m_kgd->saveLocation( "themes", m_name + "/" ); + KTar tar( tmpFile ); + tar.open( IO_ReadOnly ); + tar.directory()->copyTo( location ); + tar.close(); + + // create the DOM + TQFile file( location + m_name + ".xml" ); + file.open( IO_ReadOnly ); + m_dom.setContent( TQByteArray(file.readAll()) ); + file.close(); + + // remove the temp file + TDEIO::NetAccess::removeTempFile( tmpFile ); + + return true; +} + +TQString KTheme::createYourself( bool pack ) +{ + // start with empty dir for orig theme + if ( !pack ) + KTheme::remove( name() ); + + // 1. General stuff set by methods setBlah() + + // 2. Background theme + TDEConfig * globalConf = TDEGlobal::config(); + + TDEConfig twinConf( "twinrc", true ); + twinConf.setGroup( "Desktops" ); + uint numDesktops = twinConf.readUnsignedNumEntry( "Number", 4 ); + + TDEConfig desktopConf( "kdesktoprc", true ); + desktopConf.setGroup( "Background Common" ); + bool common = desktopConf.readBoolEntry( "CommonDesktop", true ); + + for ( uint i=0; i < numDesktops-1; i++ ) + { + TQDomElement desktopElem = m_dom.createElement( "desktop" ); + desktopElem.setAttribute( "number", i ); + desktopElem.setAttribute( "common", common ); + + desktopConf.setGroup( "Desktop" + TQString::number( i ) ); + + TQDomElement modeElem = m_dom.createElement( "mode" ); + modeElem.setAttribute( "id", desktopConf.readEntry( "BackgroundMode", "Flat" ) ); + desktopElem.appendChild( modeElem ); + + TQDomElement c1Elem = m_dom.createElement( "color1" ); + c1Elem.setAttribute( "rgb", desktopConf.readColorEntry( "Color1" ).name() ); + desktopElem.appendChild( c1Elem ); + + TQDomElement c2Elem = m_dom.createElement( "color2" ); + c2Elem.setAttribute( "rgb", desktopConf.readColorEntry( "Color2" ).name() ); + desktopElem.appendChild( c2Elem ); + + TQDomElement blendElem = m_dom.createElement( "blending" ); + blendElem.setAttribute( "mode", desktopConf.readEntry( "BlendMode", TQString( "NoBlending" ) ) ); + blendElem.setAttribute( "balance", desktopConf.readEntry( "BlendBalance", TQString::number( 100 ) ) ); + blendElem.setAttribute( "reverse", desktopConf.readBoolEntry( "ReverseBlending", false ) ); + desktopElem.appendChild( blendElem ); + + TQDomElement patElem = m_dom.createElement( "pattern" ); + patElem.setAttribute( "name", desktopConf.readEntry( "Pattern" ) ); + desktopElem.appendChild( patElem ); + + TQDomElement wallElem = m_dom.createElement( "wallpaper" ); + wallElem.setAttribute( "url", processFilePath( "desktop", desktopConf.readPathEntry( "Wallpaper" ) ) ); + wallElem.setAttribute( "mode", desktopConf.readEntry( "WallpaperMode" ) ); + desktopElem.appendChild( wallElem ); + + // TODO handle multi wallpapers (aka slideshow) + + m_root.appendChild( desktopElem ); + + if ( common ) // generate only one node + break; + } + + // 11. Screensaver + desktopConf.setGroup( "ScreenSaver" ); + TQDomElement saverElem = m_dom.createElement( "screensaver" ); + saverElem.setAttribute( "name", desktopConf.readEntry( "Saver" ) ); + m_root.appendChild( saverElem ); + + // 3. Icons + globalConf->setGroup( "Icons" ); + TQDomElement iconElem = m_dom.createElement( "icons" ); + iconElem.setAttribute( "name", globalConf->readEntry( "Theme",TDEIconTheme::current() ) ); + createIconElems( "DesktopIcons", "desktop", iconElem, globalConf ); + createIconElems( "MainToolbarIcons", "mainToolbar", iconElem, globalConf ); + createIconElems( "PanelIcons", "panel", iconElem, globalConf ); + createIconElems( "SmallIcons", "small", iconElem, globalConf ); + createIconElems( "ToolbarIcons", "toolbar", iconElem, globalConf ); + m_root.appendChild( iconElem ); + + // 4. Sounds + // 4.1 Global sounds + TDEConfig * soundConf = new TDEConfig( "knotify.eventsrc", true ); + TQStringList stdEvents; + stdEvents << "cannotopenfile" << "catastrophe" << "exitkde" << "fatalerror" + << "notification" << "printerror" << "starttde" << "warning" + << "messageCritical" << "messageInformation" << "messageWarning" + << "messageboxQuestion"; + + // 4.2 KWin sounds + TDEConfig * twinSoundConf = new TDEConfig( "twin.eventsrc", true ); + TQStringList twinEvents; + twinEvents << "activate" << "close" << "delete" << + "desktop1" << "desktop2" << "desktop3" << "desktop4" << + "desktop5" << "desktop6" << "desktop7" << "desktop8" << + "maximize" << "minimize" << "moveend" << "movestart" << + "new" << "not_on_all_desktops" << "on_all_desktops" << + "resizeend" << "resizestart" << "shadedown" << "shadeup" << + "transdelete" << "transnew" << "unmaximize" << "unminimize"; + + TQDomElement soundsElem = m_dom.createElement( "sounds" ); + createSoundList( stdEvents, "global", soundsElem, soundConf ); + createSoundList( twinEvents, "twin", soundsElem, twinSoundConf ); + m_root.appendChild( soundsElem ); + delete soundConf; + delete twinSoundConf; + + + // 5. Colors + TQDomElement colorsElem = m_dom.createElement( "colors" ); + globalConf->setGroup( "KDE" ); + colorsElem.setAttribute( "contrast", globalConf->readNumEntry( "contrast", 7 ) ); + TQStringList stdColors; + stdColors << "background" << "selectBackground" << "foreground" << "windowForeground" + << "windowBackground" << "selectForeground" << "buttonBackground" + << "buttonForeground" << "linkColor" << "visitedLinkColor" << "alternateBackground"; + + globalConf->setGroup( "General" ); + for ( TQStringList::Iterator it = stdColors.begin(); it != stdColors.end(); ++it ) + createColorElem( ( *it ), "global", colorsElem, globalConf ); + + TQStringList twinColors; + twinColors << "activeForeground" << "inactiveBackground" << "inactiveBlend" << "activeBackground" + << "activeBlend" << "inactiveForeground" << "activeTitleBtnBg" << "inactiveTitleBtnBg" + << "frame" << "inactiveFrame" << "handle" << "inactiveHandle"; + globalConf->setGroup( "WM" ); + for ( TQStringList::Iterator it = twinColors.begin(); it != twinColors.end(); ++it ) + createColorElem( ( *it ), "twin", colorsElem, globalConf ); + + m_root.appendChild( colorsElem ); + + // 6. Cursors + TDEConfig* mouseConf = new TDEConfig( "kcminputrc", true ); + mouseConf->setGroup( "Mouse" ); + TQDomElement cursorsElem = m_dom.createElement( "cursors" ); + cursorsElem.setAttribute( "name", mouseConf->readEntry( "cursorTheme" ) ); + m_root.appendChild( cursorsElem ); + delete mouseConf; + // TODO copy the cursor theme? + + // 7. KWin + twinConf.setGroup( "Style" ); + TQDomElement wmElem = m_dom.createElement( "wm" ); + wmElem.setAttribute( "name", twinConf.readEntry( "PluginLib" ) ); + wmElem.setAttribute( "type", "builtin" ); // TODO support pixmap themes when the twin client gets ported + if ( twinConf.readBoolEntry( "CustomButtonPositions" ) ) + { + TQDomElement buttonsElem = m_dom.createElement( "buttons" ); + buttonsElem.setAttribute( "left", twinConf.readEntry( "ButtonsOnLeft" ) ); + buttonsElem.setAttribute( "right", twinConf.readEntry( "ButtonsOnRight" ) ); + wmElem.appendChild( buttonsElem ); + } + TQDomElement borderElem = m_dom.createElement( "border" ); + borderElem.setAttribute( "size", twinConf.readNumEntry( "BorderSize", 1 ) ); + wmElem.appendChild( borderElem ); + m_root.appendChild( wmElem ); + + // 8. Konqueror + TDEConfig konqConf( "konquerorrc", true ); + konqConf.setGroup( "Settings" ); + TQDomElement konqElem = m_dom.createElement( "konqueror" ); + TQDomElement konqWallElem = m_dom.createElement( "wallpaper" ); + TQString bgImagePath = konqConf.readPathEntry( "BgImage" ); + konqWallElem.setAttribute( "url", processFilePath( "konqueror", bgImagePath ) ); + konqElem.appendChild( konqWallElem ); + TQDomElement konqBgColorElem = m_dom.createElement( "bgcolor" ); + konqBgColorElem.setAttribute( "rgb", konqConf.readColorEntry( "BgColor" ).name() ); + konqElem.appendChild( konqBgColorElem ); + m_root.appendChild( konqElem ); + + // 9. Kicker (aka TDE Panel) + TDEConfig kickerConf( "kickerrc", true ); + kickerConf.setGroup( "General" ); + + TQDomElement panelElem = m_dom.createElement( "panel" ); + + if ( kickerConf.readBoolEntry( "UseBackgroundTheme" ) ) + { + TQDomElement backElem = m_dom.createElement( "background" ); + TQString kbgPath = kickerConf.readPathEntry( "BackgroundTheme" ); + backElem.setAttribute( "url", processFilePath( "panel", kbgPath ) ); + backElem.setAttribute( "colorize", kickerConf.readBoolEntry( "ColorizeBackground" ) ); + panelElem.appendChild( backElem ); + } + + TQDomElement transElem = m_dom.createElement( "transparent" ); + transElem.setAttribute( "value", kickerConf.readBoolEntry( "Transparent" ) ); + panelElem.appendChild( transElem ); + + TQDomElement posElem = m_dom.createElement( "position" ); + posElem.setAttribute( "value", kickerConf.readEntry( "Position" ) ); + panelElem.appendChild( posElem ); + + + TQDomElement showLeftHideButtonElem = m_dom.createElement( "showlefthidebutton" ); + showLeftHideButtonElem.setAttribute( "value", kickerConf.readBoolEntry( "ShowLeftHideButton" ) ); + panelElem.appendChild( showLeftHideButtonElem ); + + TQDomElement showRightHideButtonElem = m_dom.createElement( "showrighthidebutton" ); + showRightHideButtonElem.setAttribute( "value", kickerConf.readBoolEntry( "ShowRightHideButton" ) ); + panelElem.appendChild( showRightHideButtonElem ); + + + + m_root.appendChild( panelElem ); + + // 10. Widget style + globalConf->setGroup( "General" ); + TQDomElement widgetsElem = m_dom.createElement( "widgets" ); + widgetsElem.setAttribute( "name", globalConf->readEntry( "widgetStyle",TDEStyle::defaultStyle() ) ); + m_root.appendChild( widgetsElem ); + + // 12. + TQDomElement fontsElem = m_dom.createElement( "fonts" ); + TQStringList fonts; + fonts << "General" << "font" + << "General" << "fixed" + << "General" << "toolBarFont" + << "General" << "menuFont" + << "WM" << "activeFont" + << "General" << "taskbarFont" + << "FMSettings" << "StandardFont"; + + for ( TQStringList::Iterator it = fonts.begin(); it != fonts.end(); ++it ) { + TQString group = *it; ++it; + TQString key = *it; + TQString value; + + if ( group == "FMSettings" ) { + desktopConf.setGroup( group ); + value = desktopConf.readEntry( key ); + } + else { + globalConf->setGroup( group ); + value = globalConf->readEntry( key ); + } + TQDomElement fontElem = m_dom.createElement( key ); + fontElem.setAttribute( "object", group ); + fontElem.setAttribute( "value", value ); + fontsElem.appendChild( fontElem ); + } + m_root.appendChild( fontsElem ); + + // Save the XML + TQFile file( m_kgd->saveLocation( "themes", m_name + "/" ) + m_name + ".xml" ); + if ( file.open( IO_WriteOnly ) ) { + TQTextStream stream( &file ); + m_dom.save( stream, 2 ); + file.close(); + } + + TQString result; + if ( pack ) + { + // Pack the whole theme + KTar tar( m_kgd->saveLocation( "themes" ) + m_name + ".kth", "application/x-gzip" ); + tar.open( IO_WriteOnly ); + + kdDebug() << "Packing everything under: " << m_kgd->saveLocation( "themes", m_name + "/" ) << endl; + + if ( tar.addLocalDirectory( m_kgd->saveLocation( "themes", m_name + "/" ), TQString::null ) ) + result = tar.fileName(); + + tar.close(); + } + + //kdDebug() << m_dom.toString( 2 ) << endl; + + return result; +} + +void KTheme::apply() +{ + kdDebug() << "Going to apply theme: " << m_name << endl; + + TQString themeDir = m_kgd->findResourceDir( "themes", m_name + "/" + m_name + ".xml") + m_name + "/"; + kdDebug() << "Theme dir: " << themeDir << endl; + + // 2. Background theme + + TQDomNodeList desktopList = m_dom.elementsByTagName( "desktop" ); + TDEConfig desktopConf( "kdesktoprc" ); + desktopConf.setGroup( "Background Common" ); + + for ( uint i = 0; i <= desktopList.count(); i++ ) + { + TQDomElement desktopElem = desktopList.item( i ).toElement(); + if ( !desktopElem.isNull() ) + { + // TODO optimize, don't write several times the common section + bool common = static_cast<bool>( desktopElem.attribute( "common", "true" ).toUInt() ); + desktopConf.writeEntry( "CommonDesktop", common ); + desktopConf.writeEntry( "DeskNum", desktopElem.attribute( "number", "0" ).toUInt() ); + + desktopConf.setGroup( TQString( "Desktop%1" ).arg( i ) ); + if (getProperty( desktopElem, "mode", "id" ) != TQString::null) desktopConf.writeEntry( "BackgroundMode", getProperty( desktopElem, "mode", "id" ) ); + if (getProperty( desktopElem, "color1", "rgb" ) != TQString::null) desktopConf.writeEntry( "Color1", TQColor( getProperty( desktopElem, "color1", "rgb" ) ) ); + if (getProperty( desktopElem, "color2", "rgb" ) != TQString::null) desktopConf.writeEntry( "Color2", TQColor( getProperty( desktopElem, "color2", "rgb" ) ) ); + if (getProperty( desktopElem, "blending", "mode" ) != TQString::null) desktopConf.writeEntry( "BlendMode", getProperty( desktopElem, "blending", "mode" ) ); + if (getProperty( desktopElem, "blending", "balance" ) != TQString::null) desktopConf.writeEntry( "BlendBalance", getProperty( desktopElem, "blending", "balance" ) ); + if (getProperty( desktopElem, "blending", "reverse" ) != TQString::null) desktopConf.writeEntry( "ReverseBlending", static_cast<bool>( getProperty( desktopElem, "blending", "reverse" ).toUInt() ) ); + if (getProperty( desktopElem, "pattern", "name" ) != TQString::null) desktopConf.writeEntry( "Pattern", getProperty( desktopElem, "pattern", "name" ) ); + if (getProperty( desktopElem, "wallpaper", "url" ) != TQString::null) desktopConf.writeEntry( "Wallpaper", unprocessFilePath( "desktop", getProperty( desktopElem, "wallpaper", "url" ) ) ); + if (getProperty( desktopElem, "wallpaper", "mode" ) != TQString::null) desktopConf.writeEntry( "WallpaperMode", getProperty( desktopElem, "wallpaper", "mode" ) ); + + if ( common ) { + break; // stop here + } + } + } + + // 11. Screensaver + TQDomElement saverElem = m_dom.elementsByTagName( "screensaver" ).item( 0 ).toElement(); + + if ( !saverElem.isNull() ) + { + desktopConf.setGroup( "ScreenSaver" ); + desktopConf.writeEntry( "Saver", saverElem.attribute( "name" ) ); + } + + desktopConf.sync(); // TODO sync and signal only if <desktop> elem present + // reconfigure kdesktop. kdesktop will notify all clients + DCOPClient *client = kapp->dcopClient(); + if ( !client->isAttached() ) { + client->attach(); + } + client->send("kdesktop", "KBackgroundIface", "configure()", TQString("")); + // FIXME Xinerama + + // 3. Icons + TQDomElement iconElem = m_dom.elementsByTagName( "icons" ).item( 0 ).toElement(); + if ( !iconElem.isNull() ) + { + TDEConfig * iconConf = TDEGlobal::config(); + iconConf->setGroup( "Icons" ); + iconConf->writeEntry( "Theme", iconElem.attribute( "name", "crystalsvg" ), true, true ); + + TQDomNodeList iconList = iconElem.childNodes(); + for ( uint i = 0; i < iconList.count(); i++ ) + { + TQDomElement iconSubElem = iconList.item( i ).toElement(); + TQString object = iconSubElem.attribute( "object" ); + if ( object == "desktop" ) { + iconConf->setGroup( "DesktopIcons" ); + } + else if ( object == "mainToolbar" ) { + iconConf->setGroup( "MainToolbarIcons" ); + } + else if ( object == "panel" ) { + iconConf->setGroup( "PanelIcons" ); + } + else if ( object == "small" ) { + iconConf->setGroup( "SmallIcons" ); + } + else if ( object == "toolbar" ) { + iconConf->setGroup( "ToolbarIcons" ); + } + + TQString iconName = iconSubElem.tagName(); + if ( iconName.contains( "Color" ) ) { + TQColor iconColor = TQColor( iconSubElem.attribute( "rgb" ) ); + iconConf->writeEntry( iconName, iconColor, true, true ); + } + else if ( iconName.contains( "Value" ) || iconName == "Size" ) { + iconConf->writeEntry( iconName, iconSubElem.attribute( "value" ).toUInt(), true, true ); + } + else if ( iconName.contains( "Effect" ) ) { + iconConf->writeEntry( iconName, iconSubElem.attribute( "name" ), true, true ); + } + else { + iconConf->writeEntry( iconName, static_cast<bool>( iconSubElem.attribute( "value" ).toUInt() ), true, true ); + } + } + iconConf->sync(); + + for ( int i = 0; i < TDEIcon::LastGroup; i++ ) + KIPC::sendMessageAll( KIPC::IconChanged, i ); + KService::rebuildKSycoca( m_parent ); + } + + // 4. Sounds + TQDomElement soundsElem = m_dom.elementsByTagName( "sounds" ).item( 0 ).toElement(); + if ( !soundsElem.isNull() ) + { + TDEConfig soundConf( "knotify.eventsrc" ); + TDEConfig twinSoundConf( "twin.eventsrc" ); + TQDomNodeList eventList = soundsElem.elementsByTagName( "event" ); + for ( uint i = 0; i < eventList.count(); i++ ) + { + TQDomElement eventElem = eventList.item( i ).toElement(); + TQString object = eventElem.attribute( "object" ); + + if ( object == "global" ) + { + soundConf.setGroup( eventElem.attribute( "name" ) ); + soundConf.writeEntry( "soundfile", unprocessFilePath( "sounds", eventElem.attribute( "url" ) ) ); + soundConf.writeEntry( "presentation", soundConf.readNumEntry( "presentation" ) | 1 ); + } + else if ( object == "twin" ) + { + twinSoundConf.setGroup( eventElem.attribute( "name" ) ); + twinSoundConf.writeEntry( "soundfile", unprocessFilePath( "sounds", eventElem.attribute( "url" ) ) ); + twinSoundConf.writeEntry( "presentation", soundConf.readNumEntry( "presentation" ) | 1 ); + } + } + + soundConf.sync(); + twinSoundConf.sync(); + client->send("knotify", "", "reconfigure()", TQString("")); + // TODO signal twin sounds change? + } + + // 5. Colors + TQDomElement colorsElem = m_dom.elementsByTagName( "colors" ).item( 0 ).toElement(); + + if ( !colorsElem.isNull() ) + { + TQDomNodeList colorList = colorsElem.childNodes(); + TDEConfig * colorConf = TDEGlobal::config(); + + TQString sCurrentScheme = locateLocal("data", "tdedisplay/color-schemes/thememgr.kcsrc"); + KSimpleConfig *colorScheme = new KSimpleConfig( sCurrentScheme ); + colorScheme->setGroup("Color Scheme" ); + + for ( uint i = 0; i < colorList.count(); i++ ) + { + TQDomElement colorElem = colorList.item( i ).toElement(); + TQString object = colorElem.attribute( "object" ); + if ( object == "global" ) + colorConf->setGroup( "General" ); + else if ( object == "twin" ) + colorConf->setGroup( "WM" ); + + TQString colName = colorElem.tagName(); + TQColor curColor = TQColor( colorElem.attribute( "rgb" ) ); + colorConf->writeEntry( colName, curColor, true, true ); // kdeglobals + colorScheme->writeEntry( colName, curColor ); // thememgr.kcsrc + } + + colorConf->setGroup( "KDE" ); + colorConf->writeEntry( "colorScheme", "thememgr.kcsrc", true, true ); + colorConf->writeEntry( "contrast", colorsElem.attribute( "contrast", "7" ), true, true ); + colorScheme->writeEntry( "contrast", colorsElem.attribute( "contrast", "7" ) ); + colorConf->sync(); + delete colorScheme; + + KIPC::sendMessageAll( KIPC::PaletteChanged ); + } + + // 6.Cursors + TQDomElement cursorsElem = m_dom.elementsByTagName( "cursors" ).item( 0 ).toElement(); + + if ( !cursorsElem.isNull() ) + { + TDEConfig mouseConf( "kcminputrc" ); + mouseConf.setGroup( "Mouse" ); + mouseConf.writeEntry( "cursorTheme", cursorsElem.attribute( "name" )); + // FIXME is there a way to notify KDE of cursor changes? + } + + // 7. KWin + TQDomElement wmElem = m_dom.elementsByTagName( "wm" ).item( 0 ).toElement(); + + if ( !wmElem.isNull() ) + { + TDEConfig twinConf( "twinrc" ); + twinConf.setGroup( "Style" ); + TQString type = wmElem.attribute( "type" ); + if ( type == "builtin" ) { + twinConf.writeEntry( "PluginLib", wmElem.attribute( "name" ) ); + } + //else // TODO support custom themes + TQDomNodeList buttons = wmElem.elementsByTagName ("buttons"); + if ( buttons.count() > 0 ) + { + twinConf.writeEntry( "CustomButtonPositions", true ); + if (getProperty( wmElem, "buttons", "left" ) != TQString::null) twinConf.writeEntry( "ButtonsOnLeft", getProperty( wmElem, "buttons", "left" ) ); + if (getProperty( wmElem, "buttons", "right" ) != TQString::null) twinConf.writeEntry( "ButtonsOnRight", getProperty( wmElem, "buttons", "right" ) ); + } + else + { + twinConf.writeEntry( "CustomButtonPositions", false ); + } + if (getProperty( wmElem, "border", "size" ) != TQString::null) twinConf.writeEntry( "BorderSize", getProperty( wmElem, "border", "size" ) ); + + twinConf.sync(); + client->send( "twin", "", "reconfigure()", TQString("") ); + } + + // 8. Konqueror + TQDomElement konqElem = m_dom.elementsByTagName( "konqueror" ).item( 0 ).toElement(); + + if ( !konqElem.isNull() ) + { + TDEConfig konqConf( "konquerorrc" ); + konqConf.setGroup( "Settings" ); + if (getProperty( konqElem, "wallpaper", "url" ) != TQString::null) konqConf.writeEntry( "BgImage", unprocessFilePath( "konqueror", getProperty( konqElem, "wallpaper", "url" ) ) ); + if (getProperty( konqElem, "bgcolor", "rgb" ) != TQString::null) konqConf.writeEntry( "BgColor", TQColor( getProperty( konqElem, "bgcolor", "rgb" ) ) ); + + konqConf.sync(); + client->send("konqueror*", "KonquerorIface", "reparseConfiguration()", TQString("")); // FIXME seems not to work :( + } + + // 9. Kicker + TQDomElement panelElem = m_dom.elementsByTagName( "panel" ).item( 0 ).toElement(); + + if ( !panelElem.isNull() ) + { + TDEConfig kickerConf( "kickerrc" ); + kickerConf.setGroup( "General" ); + TQString kickerBgUrl = getProperty( panelElem, "background", "url" ); + if ( !kickerBgUrl.isEmpty() ) + { + kickerConf.writeEntry( "UseBackgroundTheme", true ); + if (getProperty( panelElem, "panel", kickerBgUrl ) != TQString::null) kickerConf.writeEntry( "BackgroundTheme", unprocessFilePath( "panel", kickerBgUrl ) ); + if (getProperty( panelElem, "background", "colorize" ) != TQString::null) kickerConf.writeEntry( "ColorizeBackground", static_cast<bool>( getProperty( panelElem, "background", "colorize" ).toUInt() ) ); + } + if (getProperty( panelElem, "transparent", "value" ) != TQString::null) kickerConf.writeEntry( "Transparent", static_cast<bool>( getProperty( panelElem, "transparent", "value" ).toUInt() ) ); + if (getProperty( panelElem, "position", "value" ) != TQString::null) kickerConf.writeEntry( "Position", static_cast<int> (getProperty( panelElem, "position", "value" ).toUInt() )); + if (getProperty( panelElem, "showlefthidebutton", "value" ) != TQString::null) kickerConf.writeEntry( "ShowLeftHideButton", static_cast<bool>( getProperty( panelElem, "showlefthidebutton", "value").toInt())); + if (getProperty( panelElem, "showrighthidebutton", "value" ) != TQString::null) kickerConf.writeEntry( "ShowRightHideButton", static_cast<bool>( getProperty( panelElem, "showrighthidebutton", "value").toInt())); + + kickerConf.sync(); + client->send("kicker", "Panel", "configure()", TQString("")); + } + + // 10. Widget style + TQDomElement widgetsElem = m_dom.elementsByTagName( "widgets" ).item( 0 ).toElement(); + + if ( !widgetsElem.isNull() ) + { + TDEConfig * widgetConf = TDEGlobal::config(); + widgetConf->setGroup( "General" ); + widgetConf->writeEntry( "widgetStyle", widgetsElem.attribute( "name" ), true, true ); + widgetConf->sync(); + KIPC::sendMessageAll( KIPC::StyleChanged ); + } + + // 12. Fonts + TQDomElement fontsElem = m_dom.elementsByTagName( "fonts" ).item( 0 ).toElement(); + if ( !fontsElem.isNull() ) + { + TDEConfig * fontsConf = TDEGlobal::config(); + TDEConfig * kde1xConf = new KSimpleConfig( TQDir::homeDirPath() + "/.tderc" ); + kde1xConf->setGroup( "General" ); + + TQDomNodeList fontList = fontsElem.childNodes(); + for ( uint i = 0; i < fontList.count(); i++ ) + { + TQDomElement fontElem = fontList.item( i ).toElement(); + TQString fontName = fontElem.tagName(); + TQString fontValue = fontElem.attribute( "value" ); + TQString fontObject = fontElem.attribute( "object" ); + + if ( fontObject == "FMSettings" ) { + desktopConf.setGroup( fontObject ); + desktopConf.writeEntry( fontName, fontValue, true, true ); + desktopConf.sync(); + } + else { + fontsConf->setGroup( fontObject ); + fontsConf->writeEntry( fontName, fontValue, true, true ); + } + kde1xConf->writeEntry( fontName, fontValue, true, true ); + } + + fontsConf->sync(); + kde1xConf->sync(); + KIPC::sendMessageAll( KIPC::FontChanged ); + } + +} + +bool KTheme::remove( const TQString & name ) +{ + kdDebug() << "Going to remove theme: " << name << endl; + return TDEIO::NetAccess::del( TDEGlobal::dirs()->saveLocation( "themes", name + "/" ), 0L ); +} + +void KTheme::setProperty( const TQString & name, const TQString & value, TQDomElement parent ) +{ + TQDomElement tmp = m_dom.createElement( name ); + tmp.setAttribute( "value", value ); + parent.appendChild( tmp ); +} + +TQString KTheme::getProperty( const TQString & name ) const +{ + TQDomNodeList _list = m_dom.elementsByTagName( name ); + if ( _list.count() != 0 ) + return _list.item( 0 ).toElement().attribute( "value" ); + else + { + kdWarning() << "Found no such property: " << name << endl; + return TQString::null; + } +} + +TQString KTheme::getProperty( TQDomElement parent, const TQString & tag, + const TQString & attr ) const +{ + TQDomNodeList _list = parent.elementsByTagName( tag ); + + if ( _list.count() != 0 ) + return _list.item( 0 ).toElement().attribute( attr ); + else + { + kdWarning() << TQString( "No such property found: %1->%2->%3" ) + .arg( parent.tagName() ).arg( tag ).arg( attr ) << endl; + return TQString::null; + } +} + +void KTheme::createIconElems( const TQString & group, const TQString & object, + TQDomElement parent, TDEConfig * cfg ) +{ + cfg->setGroup( group ); + TQStringList elemNames; + elemNames << "Animated" << "DoublePixels" << "Size" + << "ActiveColor" << "ActiveColor2" << "ActiveEffect" + << "ActiveSemiTransparent" << "ActiveValue" + << "DefaultColor" << "DefaultColor2" << "DefaultEffect" + << "DefaultSemiTransparent" << "DefaultValue" + << "DisabledColor" << "DisabledColor2" << "DisabledEffect" + << "DisabledSemiTransparent" << "DisabledValue"; + for ( TQStringList::ConstIterator it = elemNames.begin(); it != elemNames.end(); ++it ) { + if ( (*it).contains( "Color" ) ) + createColorElem( *it, object, parent, cfg ); + else + { + TQDomElement tmpCol = m_dom.createElement( *it ); + tmpCol.setAttribute( "object", object ); + + if ( (*it).contains( "Value" ) || *it == "Size" ) + tmpCol.setAttribute( "value", cfg->readNumEntry( *it, 1 ) ); + else if ( (*it).contains( "DisabledEffect" ) ) + tmpCol.setAttribute( "name", cfg->readEntry( *it, "togray" ) ); + else if ( (*it).contains( "Effect" ) ) + tmpCol.setAttribute( "name", cfg->readEntry( *it, "none" ) ); + else + tmpCol.setAttribute( "value", cfg->readBoolEntry( *it, false ) ); + parent.appendChild( tmpCol ); + } + } +} + +void KTheme::createColorElem( const TQString & name, const TQString & object, + TQDomElement parent, TDEConfig * cfg ) +{ + TQColor color = cfg->readColorEntry( name ); + if ( color.isValid() ) + { + TQDomElement tmpCol = m_dom.createElement( name ); + tmpCol.setAttribute( "rgb", color.name() ); + tmpCol.setAttribute( "object", object ); + parent.appendChild( tmpCol ); + } +} + +void KTheme::createSoundList( const TQStringList & events, const TQString & object, + TQDomElement parent, TDEConfig * cfg ) +{ + for ( TQStringList::ConstIterator it = events.begin(); it != events.end(); ++it ) + { + TQString group = ( *it ); + if ( cfg->hasGroup( group ) ) + { + cfg->setGroup( group ); + TQString soundURL = cfg->readPathEntry( "soundfile" ); + int pres = cfg->readNumEntry( "presentation", 0 ); + if ( !soundURL.isEmpty() && ( ( pres & 1 ) == 1 ) ) + { + TQDomElement eventElem = m_dom.createElement( "event" ); + eventElem.setAttribute( "object", object ); + eventElem.setAttribute( "name", group ); + eventElem.setAttribute( "url", processFilePath( "sounds", soundURL ) ); + parent.appendChild( eventElem ); + } + } + } +} + +TQString KTheme::processFilePath( const TQString & section, const TQString & path ) +{ + TQFileInfo fi( path ); + + if ( fi.isRelative() ) + fi.setFile( findResource( section, path ) ); + + kdDebug() << "Processing file: " << fi.absFilePath() << ", " << fi.fileName() << endl; + + if ( section == "desktop" ) + { + if ( copyFile( fi.absFilePath(), m_kgd->saveLocation( "themes", m_name + "/wallpapers/desktop/" ) + "/" + fi.fileName() ) ) + return "theme:/wallpapers/desktop/" + fi.fileName(); + } + else if ( section == "sounds" ) + { + if ( copyFile( fi.absFilePath(), m_kgd->saveLocation( "themes", m_name + "/sounds/" ) + "/" + fi.fileName() ) ) + return "theme:/sounds/" + fi.fileName(); + } + else if ( section == "konqueror" ) + { + if ( copyFile( fi.absFilePath(), m_kgd->saveLocation( "themes", m_name + "/wallpapers/konqueror/" ) + "/" + fi.fileName() ) ) + return "theme:/wallpapers/konqueror/" + fi.fileName(); + } + else if ( section == "panel" ) + { + if ( copyFile( fi.absFilePath(), m_kgd->saveLocation( "themes", m_name + "/wallpapers/panel/" ) + "/" + fi.fileName() ) ) + return "theme:/wallpapers/panel/" + fi.fileName(); + } + else + kdWarning() << "Unsupported theme resource type" << endl; + + return TQString::null; // an error occured or the resource doesn't exist +} + +TQString KTheme::unprocessFilePath( const TQString & section, TQString path ) +{ + if ( path.startsWith( "theme:/" ) ) + return path.replace( TQRegExp( "^theme:/" ), m_kgd->findResourceDir( "themes", m_name + "/" + m_name + ".xml") + m_name + "/" ); + + if ( TQFile::exists( path ) ) + return path; + else // try to find it in the system + return findResource( section, path ); +} + +void KTheme::setAuthor( const TQString & author ) +{ + setProperty( "author", author, m_general ); +} + +void KTheme::setEmail( const TQString & email ) +{ + setProperty( "email", email, m_general ); +} + +void KTheme::setHomepage( const TQString & homepage ) +{ + setProperty( "homepage", homepage, m_general ); +} + +void KTheme::setComment( const TQString & comment ) +{ + setProperty( "comment", comment, m_general ); +} + +void KTheme::setVersion( const TQString & version ) +{ + setProperty( "version", version, m_general ); +} + +void KTheme::addPreview() +{ + TQString file = m_kgd->saveLocation( "themes", m_name + "/" ) + m_name + ".preview.png"; + kdDebug() << "Adding preview: " << file << endl; + TQPixmap snapshot = TQPixmap::grabWindow( tqt_xrootwin() ); + snapshot.save( file, "PNG" ); +} + +bool KTheme::copyFile( const TQString & from, const TQString & to ) +{ + // we overwrite b/c of restoring the "original" theme + return TDEIO::NetAccess::file_copy( from, to, -1, true /*overwrite*/ ); +} + +TQString KTheme::findResource( const TQString & section, const TQString & path ) +{ + if ( section == "desktop" ) + return m_kgd->findResource( "wallpaper", path ); + else if ( section == "sounds" ) + return m_kgd->findResource( "sound", path ); + else if ( section == "konqueror" ) + return m_kgd->findResource( "data", "konqueror/tiles/" + path ); + else if ( section == "panel" ) + return m_kgd->findResource( "data", "kicker/wallpapers/" + path ); + else + { + kdWarning() << "Requested unknown resource: " << section << endl; + return TQString::null; + } +} diff --git a/kcontrol/kthememanager/ktheme.h b/kcontrol/kthememanager/ktheme.h new file mode 100644 index 000000000..11fa6b056 --- /dev/null +++ b/kcontrol/kthememanager/ktheme.h @@ -0,0 +1,224 @@ +// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*- +/* Copyright (C) 2003 Lukas Tinkl <[email protected]> + + 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 +*/ + +#ifndef KTHEME_H +#define KTHEME_H + +#include <tqdom.h> +#include <tqguardedptr.h> +#include <tqstring.h> +#include <tqstringlist.h> +#include <tqwidget.h> + +#include <kurl.h> + +class TDEStandardDirs; +class TDEConfig; + +/// defines the syntax version used by the XML +#define SYNTAX_VERSION 1 + +/** + * The base class representing a KDE theme. The data are stored internally + * in a DOM tree and accessed using the member methods. + * + * @brief Class representing a theme + * @author Lukas Tinkl <[email protected]> + */ +class KTheme +{ +public: + /** + * Constructs KTheme using an installed theme + * @param xmlFile The theme's XML file + */ + KTheme( TQWidget *parent, const TQString & xmlFile ); + + /** + * Constructs an empty theme, to be used with + * #createYourself() + * @param create Whether to start the DOM tree + */ + KTheme( TQWidget *parent, bool create = false ); + + /** + * Destructor + */ + ~KTheme(); + + /** + * Download from @p url, unpack the tarball and load the theme definition + * + * @return true on success + */ + bool load( const KURL & url ); + + /** + * Creates a snapshot of the current configuration in the work directory + * (used for getting the defaults or to create a new user theme). + * @param pack Whether to also pack the theme in tar.gz format + * @return The path to the newly created tarball with theme (if @p pack == true) + */ + TQString createYourself( bool pack = false ); + + /** + * Apply the theme to the system, ie. set the config variables and + * adjust file paths + */ + void apply(); + + /** + * Uninstall the theme from the system + * @param name The name of the theme + * @return true on success + */ + static bool remove( const TQString & name ); + + /** + * @return the theme name + */ + TQString name() const { return m_name; } + /** + * Set the theme name + */ + void setName( const TQString & name ); + + TQString author() const { + return getProperty( "author" ); + } + void setAuthor( const TQString & author ); + + TQString email() const { + return getProperty( "email" ); + } + void setEmail( const TQString & email ); + + TQString homepage() const { + return getProperty( "homepage" ); + } + void setHomepage( const TQString & homepage ); + + TQString comment() const { + return getProperty( "comment" ); + } + void setComment ( const TQString & comment ); + + TQString version() const { + return getProperty( "version" ); + } + void setVersion ( const TQString & version ); + + /** + * Creates a preview file called theme_name.preview.png + * (i.e. takes a snapshot of the current desktop) + */ + void addPreview(); + +private: + /** + * Create a property with @p name, value @p value + * and append it to @p parent element + */ + void setProperty( const TQString & name, + const TQString & value, + TQDomElement parent ); + /** + * Get a simple property from the "general" section of the DOM tree + */ + TQString getProperty( const TQString & name ) const; + + /** + * Get a property from the DOM tree, based on: + * @param parent Parent tag + * @param tag From the this tag + * @param attr From this attribute + */ + TQString getProperty( TQDomElement parent, const TQString & tag, + const TQString & attr ) const; + + /** + * Creates a list of "icon" elements based on: + * @param group The group in the TDEConfig object @p cfg + * @param object Specifier (similiar, but not identical to @p group) + * @param parent Parent element to append to + * @param cfg The TDEConfig object to work with + */ + void createIconElems( const TQString & group, const TQString & object, + TQDomElement parent, TDEConfig * cfg ); + + /** + * Creates a color DOM element @p name, with a specifier @p object, + * appends it to @p parent; used when creating themes + * @param cfg The TDEConfig object to work with + */ + void createColorElem( const TQString & name, const TQString & object, + TQDomElement parent, TDEConfig * cfg ); + /** + * Creates a list of "event" elements based on: + * @param events The list of events to work on + * @param object Specifier (currently "global" or "twin") + * @param parent Parent element to append to + * @param cfg The TDEConfig object to work with + */ + void createSoundList( const TQStringList & events, const TQString & object, + TQDomElement parent, TDEConfig * cfg ); + + /** + * Tries to find out absolute path to a resource and copy it to the theme's temp dir; + * used when creating themes + * @param section The theme section to work on, corresponds to toplevel XML tags + * @param path The original path, relative or absolute + * @return an internal path suitable for writing into the XML file or TQString::null + * in case the resource couldn't be found + */ + TQString processFilePath( const TQString & section, const TQString & path ); + + /** + * Converts an internal theme:/ representation of a resource + * to a real path + */ + TQString unprocessFilePath( const TQString & section, TQString path ); + + /** + * Wrapper around TDEIO::NetAccess::file_copy + */ + bool copyFile( const TQString & from, const TQString & to ); + + /** + * Wrapper around TDEGlobal::dirs()->findResource() + * @param section Section to work on (desktop, sounds, panel etc) + * @param path The file to find + */ + TQString findResource( const TQString & section, const TQString & path ); + + /// name of the theme + TQString m_name; + + /// DOM holding the theme + TQDomDocument m_dom; + /// the DOM root element + TQDomElement m_root; + /// "general" section + TQDomElement m_general; + + TDEStandardDirs * m_kgd; + + TQGuardedPtr<TQWidget> m_parent; +}; + +#endif diff --git a/kcontrol/kthememanager/kthemedlg.ui b/kcontrol/kthememanager/kthemedlg.ui new file mode 100644 index 000000000..68e176eef --- /dev/null +++ b/kcontrol/kthememanager/kthemedlg.ui @@ -0,0 +1,518 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KThemeDlg</class> +<author>Lukas Tinkl <[email protected]></author> +<widget class="TQWidget"> + <property name="name"> + <cstring>KThemeDlg</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>687</width> + <height>382</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="TQLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="text"> + <string>Choose your visual TDE theme:</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>170</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KURLLabel"> + <property name="name"> + <cstring>lbGet</cstring> + </property> + <property name="text"> + <string>Get new themes...</string> + </property> + <property name="url" stdset="0"> + <string>http://themes.kde.org</string> + </property> + <property name="tipText"> + <string>Go to the TDE themes website</string> + </property> + <property name="useTips"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="TQLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="1" rowspan="4" colspan="1"> + <property name="name"> + <cstring>lbPreview</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>Box</enum> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="TQPushButton" row="2" column="0"> + <property name="name"> + <cstring>btnRemove</cstring> + </property> + <property name="text"> + <string>&Remove Theme</string> + </property> + </widget> + <widget class="TQPushButton" row="3" column="0"> + <property name="name"> + <cstring>btnCreate</cstring> + </property> + <property name="text"> + <string>Create &New Theme...</string> + </property> + </widget> + <widget class="TQPushButton" row="1" column="0"> + <property name="name"> + <cstring>btnInstall</cstring> + </property> + <property name="text"> + <string>&Install New Theme...</string> + </property> + </widget> + <widget class="TQListView" row="0" column="0"> + <column> + <property name="text"> + <string>Theme</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>false</bool> + </property> + </column> + <property name="name"> + <cstring>lvThemes</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="showSortIndicator"> + <bool>true</bool> + </property> + <property name="resizeMode"> + <enum>AllColumns</enum> + </property> + </widget> + </grid> + </widget> + <widget class="Line" row="2" column="0"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="TQLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Customize your theme:</string> + </property> + </widget> + <widget class="TQLayoutWidget" row="4" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQToolButton"> + <property name="name"> + <cstring>btnBackground</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>60</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>60</height> + </size> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="usesTextLabel"> + <bool>true</bool> + </property> + <property name="textLabel"> + <string>Background</string> + </property> + <property name="toolTip" stdset="0"> + <string>Customize the desktop background</string> + </property> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>btnColors</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>60</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>60</height> + </size> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="usesTextLabel"> + <bool>true</bool> + </property> + <property name="textLabel"> + <string>Colors</string> + </property> + <property name="toolTip" stdset="0"> + <string>Customize colors</string> + </property> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>btnStyle</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>60</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>60</height> + </size> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="usesTextLabel"> + <bool>true</bool> + </property> + <property name="textLabel"> + <string>Style</string> + </property> + <property name="toolTip" stdset="0"> + <string>Customize the widget style</string> + </property> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>btnIcons</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>60</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>60</height> + </size> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="usesTextLabel"> + <bool>true</bool> + </property> + <property name="textLabel"> + <string>Icons</string> + </property> + <property name="toolTip" stdset="0"> + <string>Customize the icon theme</string> + </property> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>btnFonts</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>60</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>60</height> + </size> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="usesTextLabel"> + <bool>true</bool> + </property> + <property name="textLabel"> + <string>Fonts</string> + </property> + <property name="toolTip" stdset="0"> + <string>Customize the font theme</string> + </property> + </widget> + <widget class="TQToolButton"> + <property name="name"> + <cstring>btnSaver</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>60</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>60</height> + </size> + </property> + <property name="focusPolicy"> + <enum>TabFocus</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="usesTextLabel"> + <bool>true</bool> + </property> + <property name="textLabel"> + <string>Screen Saver</string> + </property> + <property name="toolTip" stdset="0"> + <string>Customize the screen saver</string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>lbGet</sender> + <signal>leftClickedURL(const TQString&)</signal> + <receiver>KThemeDlg</receiver> + <slot>startKonqui(const TQString&)</slot> + </connection> + <connection> + <sender>btnBackground</sender> + <signal>clicked()</signal> + <receiver>KThemeDlg</receiver> + <slot>startBackground()</slot> + </connection> + <connection> + <sender>btnColors</sender> + <signal>clicked()</signal> + <receiver>KThemeDlg</receiver> + <slot>startColors()</slot> + </connection> + <connection> + <sender>btnStyle</sender> + <signal>clicked()</signal> + <receiver>KThemeDlg</receiver> + <slot>startStyle()</slot> + </connection> + <connection> + <sender>btnIcons</sender> + <signal>clicked()</signal> + <receiver>KThemeDlg</receiver> + <slot>startIcons()</slot> + </connection> + <connection> + <sender>btnFonts</sender> + <signal>clicked()</signal> + <receiver>KThemeDlg</receiver> + <slot>startFonts()</slot> + </connection> + <connection> + <sender>btnSaver</sender> + <signal>clicked()</signal> + <receiver>KThemeDlg</receiver> + <slot>startSaver()</slot> + </connection> +</connections> +<tabstops> + <tabstop>lvThemes</tabstop> + <tabstop>btnInstall</tabstop> + <tabstop>btnRemove</tabstop> + <tabstop>btnCreate</tabstop> + <tabstop>btnBackground</tabstop> + <tabstop>btnColors</tabstop> + <tabstop>btnStyle</tabstop> + <tabstop>btnIcons</tabstop> + <tabstop>btnFonts</tabstop> + <tabstop>btnSaver</tabstop> +</tabstops> +<includes> + <include location="local" impldecl="in implementation">kthemedlg.ui.h</include> +</includes> +<Q_SLOTS> + <slot specifier="non virtual">startKonqui( const TQString & url )</slot> + <slot specifier="non virtual">startBackground()</slot> + <slot specifier="non virtual">startColors()</slot> + <slot specifier="non virtual">startStyle()</slot> + <slot specifier="non virtual">startIcons()</slot> + <slot specifier="non virtual">startFonts()</slot> + <slot specifier="non virtual">startSaver()</slot> +</Q_SLOTS> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kurllabel.h</includehint> +</includehints> +</UI> diff --git a/kcontrol/kthememanager/kthemedlg.ui.h b/kcontrol/kthememanager/kthemedlg.ui.h new file mode 100644 index 000000000..78e0e48e1 --- /dev/null +++ b/kcontrol/kthememanager/kthemedlg.ui.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions or slots use +** Qt Designer which will update this file, preserving your code. Create an +** init() function in place of a constructor, and a destroy() function in +** place of a destructor. +*****************************************************************************/ +#include <krun.h> + +void KThemeDlg::startKonqui( const TQString & url ) +{ + (void) new KRun(url); +} + + +void KThemeDlg::startBackground() +{ + KRun::runCommand("tdecmshell tde-background"); +} + + +void KThemeDlg::startColors() +{ + KRun::runCommand("tdecmshell tde-colors"); +} + + +void KThemeDlg::startStyle() +{ + KRun::runCommand("tdecmshell tde-style"); +} + + +void KThemeDlg::startIcons() +{ + KRun::runCommand("tdecmshell tde-icons"); +} + +void KThemeDlg::startFonts() +{ + KRun::runCommand("tdecmshell tde-fonts"); +} + + +void KThemeDlg::startSaver() +{ + KRun::runCommand("tdecmshell tde-screensaver"); +} diff --git a/kcontrol/kthememanager/kthememanager.cpp b/kcontrol/kthememanager/kthememanager.cpp new file mode 100644 index 000000000..969e377ce --- /dev/null +++ b/kcontrol/kthememanager/kthememanager.cpp @@ -0,0 +1,425 @@ +// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*- +/* Copyright (C) 2003 Lukas Tinkl <[email protected]> + + 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 <tqlabel.h> +#include <tqlayout.h> +#include <tqpixmap.h> +#include <tqpushbutton.h> +#include <tqtoolbutton.h> +#include <tqtooltip.h> + +#include <tdeaboutdata.h> +#include <tdeapplication.h> +#include <kdebug.h> +#include <kdialog.h> +#include <tdeemailsettings.h> +#include <tdefiledialog.h> +#include <tdeglobal.h> +#include <kiconloader.h> +#include <tdelistview.h> +#include <tdelocale.h> +#include <tdemessagebox.h> +#include <kservicegroup.h> +#include <kstandarddirs.h> +#include <kurldrag.h> + +#include "kthememanager.h" +#include "knewthemedlg.h" +#include "config.h" + +kthememanager::kthememanager( TQWidget *parent, const char *name ) + : TDECModule( parent, name ), m_theme( 0 ), m_origTheme( 0 ) +{ + + TDEAboutData *about = new TDEAboutData("kthememanager", I18N_NOOP("TDE Theme Manager"), + "0.4", I18N_NOOP("This control module handles installing, removing and " + "creating visual TDE themes."), + TDEAboutData::License_GPL, "(c) 2003, 2004, 2006 Lukáš Tinkl", 0, + "http://developer.kde.org/~lukas/kthememanager"); + setAboutData( about ); + + setQuickHelp( i18n("This control module handles installing, removing and " + "creating visual TDE themes.")); + + setButtons( TDECModule::Default|TDECModule::Apply|TDECModule::Help ); + + setAcceptDrops( true ); + init(); + + TQBoxLayout *top = new TQVBoxLayout(this, 0, KDialog::spacingHint()); + + dlg = new KThemeDlg(this); + top->addWidget( dlg ); + + dlg->lvThemes->setColumnWidthMode( 0, TQListView::Maximum ); + + connect( ( TQObject * )dlg->btnInstall, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( slotInstallTheme() ) ); + + connect( ( TQObject * )dlg->btnRemove, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( slotRemoveTheme() ) ); + + connect( ( TQObject * )dlg->btnCreate, TQT_SIGNAL( clicked() ), + this, TQT_SLOT( slotCreateTheme() ) ); + + connect( ( TQObject * )dlg->lvThemes, TQT_SIGNAL( clicked( TQListViewItem * ) ), + this, TQT_SLOT( slotThemeChanged( TQListViewItem * ) ) ); + + connect( ( TQObject * )dlg->lvThemes, TQT_SIGNAL( currentChanged( TQListViewItem * ) ), + this, TQT_SLOT( slotThemeChanged( TQListViewItem * ) ) ); + + connect( this, TQT_SIGNAL( filesDropped( const KURL::List& ) ), + this, TQT_SLOT( updateButton() ) ); + + connect( ( TQObject * )dlg->lvThemes, TQT_SIGNAL( clicked( TQListViewItem * ) ), + this, TQT_SLOT( updateButton() ) ); + + m_origTheme = new KTheme( this, true ); // stores the defaults to get back to + m_origTheme->setName( ORIGINAL_THEME ); + m_origTheme->createYourself(); + + load(); + queryLNFModules(); + updateButton(); +} + +kthememanager::~kthememanager() +{ + delete m_theme; + delete m_origTheme; +} + +void kthememanager::init() +{ + TDEGlobal::dirs()->addResourceType( "themes", TDEStandardDirs::kde_default("data") + + "kthememanager/themes/" ); +} + +void kthememanager::updateButton() +{ + TQListViewItem * cur = dlg->lvThemes->currentItem(); + bool enable = (cur != 0); + if (enable) { + enable = TQFile(TDEGlobal::dirs()->saveLocation( "themes", cur->text( 0 ) + "/"+ cur->text( 0 )+ ".xml" ,false)).exists() ; + } + dlg->btnRemove->setEnabled(enable); +} + +void kthememanager::load() +{ + load( false ); +} + +void kthememanager::load(bool useDefaults) +{ + listThemes(); + + // Load the current theme name + TDEConfig conf("kcmthememanagerrc", false, false); + + conf.setReadDefaults( useDefaults ); + + conf.setGroup( "General" ); + TQString themeName = conf.readEntry( "CurrentTheme" ); + TQListViewItem * cur = dlg->lvThemes->findItem( themeName, 0 ); + if ( cur ) + { + dlg->lvThemes->setSelected( cur, true ); + dlg->lvThemes->ensureItemVisible( cur ); + slotThemeChanged( cur ); + } + + emit changed( true ); +} + +void kthememanager::defaults() +{ + load( true ); +} + +void kthememanager::save() +{ + TQListViewItem * cur = dlg->lvThemes->currentItem(); + + if ( cur ) + { + TQString themeName = cur->text( 0 ); + + m_theme = new KTheme( this, TDEGlobal::dirs()->findResource( "themes", themeName + "/" + themeName + ".xml") ); + m_theme->apply(); + + // Save the current theme name + TDEConfig conf("kcmthememanagerrc", false, false); + conf.setGroup( "General" ); + conf.writeEntry( "CurrentTheme", themeName ); + conf.sync(); + + delete m_theme; + m_theme = 0; + + } +} + +void kthememanager::listThemes() +{ + dlg->lvThemes->clear(); + dlg->lbPreview->setPixmap( TQPixmap() ); + + TQStringList themes = TDEGlobal::dirs()->findAllResources( "themes", "*.xml", true /*recursive*/ ); + + TQStringList::const_iterator it; + + for ( it = themes.begin(); it != themes.end(); ++it ) + { + KTheme theme( this, ( *it ) ); + TQString name = theme.name(); + if ( name != ORIGINAL_THEME ) // skip the "original" theme + ( void ) new TQListViewItem( dlg->lvThemes, name, theme.comment() ); + } + + kdDebug() << "Available themes: " << themes << endl; +} + +float kthememanager::getThemeVersion( const TQString & themeName ) +{ + TQStringList themes = TDEGlobal::dirs()->findAllResources( "themes", "*.xml", true /*recursive*/ ); + + TQStringList::const_iterator it; + + for ( it = themes.begin(); it != themes.end(); ++it ) + { + KTheme theme( 0L, ( *it ) ); + TQString name = theme.name(); + bool ok = false; + float version = theme.version().toFloat( &ok ); + if ( name == themeName && ok ) + return version; + } + + return -1; +} + +void kthememanager::slotInstallTheme() +{ + addNewTheme( KFileDialog::getOpenURL( ":themes", "*.kth|" + i18n("Theme Files"), this, + i18n( "Select Theme File" ) ) ); +} + +void kthememanager::addNewTheme( const KURL & url ) +{ + if ( url.isValid() ) + { + TQString themeName = TQFileInfo( url.fileName() ).baseName(); + if ( getThemeVersion( themeName ) != -1 ) // theme exists already + { + KTheme::remove( themeName ); // remove first + } + + m_theme = new KTheme(this); + if ( m_theme->load( url ) ) + { + listThemes(); + emit changed( true ); + } + + delete m_theme; + m_theme = 0; + updateButton(); + } +} + +void kthememanager::slotRemoveTheme() +{ + // get the selected item from the listview + TQListViewItem * cur = dlg->lvThemes->currentItem(); + // ask and remove it + if ( cur ) + { + TQString themeName = cur->text( 0 ); + if ( KMessageBox::warningContinueCancel( this, "<qt>" + i18n( "Do you really want to remove the theme <b>%1</b>?" ).arg( themeName ), + i18n( "Remove Theme" ), KGuiItem( i18n( "&Remove" ), "edit-delete" ) ) + == KMessageBox::Continue ) + { + KTheme::remove( themeName ); + listThemes(); + } + updateButton(); + } +} + +bool kthememanager::themeExist(const TQString &_themeName) +{ + return ( dlg->lvThemes->findItem( _themeName, 0 )!=0 ); +} + +void kthememanager::slotCreateTheme() +{ + KNewThemeDlg dlg( this ); + + KEMailSettings es; + es.setProfile( es.defaultProfileName() ); + + dlg.setName( i18n( "My Theme" ) ); + dlg.setAuthor( es.getSetting( KEMailSettings::RealName ) ) ; + dlg.setEmail( es.getSetting( KEMailSettings::EmailAddress ) ); + dlg.setVersion( "0.1" ); + + if ( dlg.exec() == TQDialog::Accepted ) + { + + TQString themeName = dlg.getName(); + if ( themeExist(themeName) ) + { + KMessageBox::information( this, i18n( "Theme %1 already exists." ).arg( themeName ) ); + } + else + { + if ( getThemeVersion( themeName ) != -1 ) // remove the installed theme first + { + KTheme::remove( themeName ); + } + m_theme = new KTheme( this, true ); + m_theme->setName( dlg.getName() ); + m_theme->setAuthor( dlg.getAuthor() ); + m_theme->setEmail( dlg.getEmail() ); + m_theme->setHomepage( dlg.getHomepage() ); + m_theme->setComment( dlg.getComment().replace( "\n", "" ) ); + m_theme->setVersion( dlg.getVersion() ); + + TQString result = m_theme->createYourself( true ); + m_theme->addPreview(); + + if ( !result.isEmpty() ) + KMessageBox::information( this, i18n( "Your theme has been successfully created in %1." ).arg( result ), + i18n( "Theme Created" ), "theme_created_ok" ); + else + KMessageBox::error( this, i18n( "An error occurred while creating your theme." ), + i18n( "Theme Not Created" ) ); + delete m_theme; + m_theme = 0; + + listThemes(); + } + } +} + +void kthememanager::slotThemeChanged( TQListViewItem * item ) +{ + if ( item ) + { + TQString themeName = item->text(0); + kdDebug() << "Activated theme: " << themeName << endl; + + TQString themeDir = TDEGlobal::dirs()->findResourceDir( "themes", themeName + "/" + themeName + ".xml") + themeName + "/"; + + TQString pixFile = themeDir + themeName + ".preview.png"; + + if ( TQFile::exists( pixFile ) ) + { + updatePreview( pixFile ); + } + else + { + dlg->lbPreview->setPixmap( TQPixmap() ); + dlg->lbPreview->setText( i18n( "This theme does not contain a preview." ) ); + } + + KTheme theme( this, themeDir + themeName + ".xml" ); + TQToolTip::remove( dlg->lbPreview ); + TQToolTip::add( dlg->lbPreview, "<qt>" + i18n( "Author: %1<br>Email: %2<br>Version: %3<br>Homepage: %4" ) + .arg( theme.author() ).arg( theme.email() ) + .arg( theme.version() ).arg( theme.homepage() ) + "</qt>"); + + emit changed( true ); + } +} + +void kthememanager::dragEnterEvent( TQDragEnterEvent * ev ) +{ + ev->accept( KURLDrag::canDecode( ev ) ); +} + +void kthememanager::dropEvent( TQDropEvent * ev ) +{ + KURL::List urls; + if ( KURLDrag::decode( ev, urls ) ) + { + emit filesDropped( urls ); + } +} + +void kthememanager::slotFilesDropped( const KURL::List & urls ) +{ + for ( KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it ) + addNewTheme( *it ); +} + +void kthememanager::queryLNFModules() +{ + /*KServiceGroup::Ptr settings = KServiceGroup::group( "Settings/LookNFeel/" ); + if ( !settings || !settings->isValid() ) + return; + + KServiceGroup::List list = settings->entries(); + + // Iterate over all entries in the group + for( KServiceGroup::List::ConstIterator it = list.begin(); + it != list.end(); it++ ) + { + KSycocaEntry *p = ( *it ); + if ( p->isType( KST_KService ) ) + { + KService *s = static_cast<KService *>( p ); + ( void ) new KThemeDetailsItem( dlg->lvDetails, s->name(), s->pixmap( TDEIcon::Desktop ), s->exec() ); + } + } + + dlg->lvDetails->sort();*/ + + // For now use a static list + TDEIconLoader * il = TDEGlobal::iconLoader(); + dlg->btnBackground->setIconSet( il->loadIconSet( "background", TDEIcon::Desktop, 32 ) ); + dlg->btnColors->setIconSet( il->loadIconSet( "application-x-kcsrc", TDEIcon::Desktop, 32 ) ); + dlg->btnStyle->setIconSet( il->loadIconSet( "style", TDEIcon::Desktop, 32 ) ); + dlg->btnIcons->setIconSet( il->loadIconSet( "icons", TDEIcon::Desktop, 32 ) ); + dlg->btnFonts->setIconSet( il->loadIconSet( "fonts", TDEIcon::Desktop, 32 ) ); + dlg->btnSaver->setIconSet( il->loadIconSet( "tdescreensaver", TDEIcon::Desktop, 32 ) ); +} + +void kthememanager::updatePreview( const TQString & pixFile ) +{ + kdDebug() << "Preview is in file: " << pixFile << endl; + TQImage preview( pixFile, "PNG" ); + if (preview.width()>dlg->lbPreview->contentsRect().width() || + preview.height()>dlg->lbPreview->contentsRect().height() ) + preview = preview.smoothScale( dlg->lbPreview->contentsRect().size(), TQ_ScaleMin ); + TQPixmap pix; + pix.convertFromImage( preview ); + dlg->lbPreview->setPixmap( pix ); +} + +extern "C" +{ + KDE_EXPORT TDECModule *create_kthememanager(TQWidget *parent, const char *) + { + TDEGlobal::locale()->insertCatalogue( "kthememanager" ); + return new kthememanager( parent, "kthememanager" ); + } +} + +#include "kthememanager.moc" diff --git a/kcontrol/kthememanager/kthememanager.desktop b/kcontrol/kthememanager/kthememanager.desktop new file mode 100644 index 000000000..b44e215d4 --- /dev/null +++ b/kcontrol/kthememanager/kthememanager.desktop @@ -0,0 +1,221 @@ +[Desktop Entry] +Comment=Manage global TDE visual themes +Comment[af]=Bestuurder TDE se globale visuele temas +Comment[az]=Qlobal TDE əyani örtüklərini idarə et +Comment[be]=Кіраванне глабальнымі візуальнымі тэмамі TDE +Comment[bg]=Управление на темите +Comment[bn]=গ্লোবাল কে.ডি.ই. ভিসুয়াল থীম ব্যবস্থাপনা +Comment[bs]=Upravljanje globalnim TDE vizuelnim temama +Comment[ca]=Gestiona els temes visuals globals del TDE +Comment[cs]=Správce motivů pracovní plochy +Comment[csb]=Sprôwiôj témą TDE +Comment[cy]=Rheoli themau gweledol TDE eang +Comment[da]=Håndtering af globale visuelle temaer for TDE +Comment[de]=Globale TDE-Designs verwalten +Comment[el]=Διαχειριστής καθολικών οπτικών θεμάτων του TDE +Comment[eo]=Administras mondan TDEan etosoj +Comment[es]=Gestión global de los temas visuales de TDE +Comment[et]=TDE globaalsete teemade haldur +Comment[eu]=Kudeatu TDEren gai bisual orokorrak +Comment[fa]=مدیریت چهرههای مرئی TDE سراسری +Comment[fi]=Ylläpidä TDE:n teemoja +Comment[fr]=Gestionnaire de thèmes visuels globaux de TDE +Comment[fy]=Algemiene fisuele tema's fan TDE beheare +Comment[gl]=Xestionar temas visuais globais de TDE +Comment[he]=מנהל ערכות נושא גלובליות עבור TDE +Comment[hi]=वैश्विक केडीई दृश्यमय प्रसंग प्रबंधित करें +Comment[hr]=Upravljanje općim TDE vizualnim temama +Comment[hu]=TDE-témák kezelése +Comment[is]=Stjórna víðværum TDE þemum +Comment[it]=Gestore dei temi globali di TDE +Comment[ja]=グローバル TDE 外観テーマの管理 +Comment[ka]=TDE-ს ვიზუალური თემბის გლობალური მენეჯმენტი +Comment[kk]=TDE жалпы көрініс нақыштарын басқару +Comment[km]=គ្រប់គ្រងស្បែករូបភាព TDE ទាំងអស់ +Comment[ko]=전역 TDE 시각 테마 관리 +Comment[lt]=Globaliai tvarkyti TDE vizualines temas +Comment[lv]=TDE izskata tēmu pārvaldīšana +Comment[mk]=Менаџирајте ги глобалните TDE визуелни теми +Comment[ms]=Urus tema visual TDE global +Comment[mt]=Immaniġġja temi viżwali globali tal-TDE +Comment[nb]=Velg blant TDE-temaer for hele brukerflaten +Comment[nds]=Globale TDE-Muster instellen +Comment[ne]=विश्वव्यापी TDE दृश्य विषयवस्तु व्यवस्थापन गर्नुहोस् +Comment[nl]=Algemene visuele thema's van TDE beheren +Comment[nn]=Vel mellom TDE-tema for heile brukarflata +Comment[pa]=ਮੁੱਢਲੇ TDE ਦਿੱਖ ਸਰੂਪ ਪਰਬੰਧ +Comment[pl]=Zarządzaj motywami TDE +Comment[pt]=Gestão global de temas visuais do TDE +Comment[pt_BR]=Gerencia temas globais do TDE +Comment[ro]=Administrează tematicile vizuale TDE globale +Comment[ru]=Менеджер глобальных визуальных тем TDE +Comment[rw]=Kuyobora insanganyamatsiko igaragara TDE rusange +Comment[se]=Hálddaš oppalaš visuella TDE-fáttáid +Comment[sk]=Globálny správca tém +Comment[sl]=Upravitelj vizualnih tem za TDE +Comment[sr]=Управљање TDE-овим визуелним темама +Comment[sr@Latn]=Upravljanje TDE-ovim vizuelnim temama +Comment[sv]=Hantera TDE:s allmänna visuella teman +Comment[ta]=பொது TDE காட்சி பொருளை மேல்பார்வையிடு +Comment[tg]=Мудири мавзӯъҳои визуалии TDE дар шабака +Comment[th]=จัดการชุดตกแต่งของ TDE +Comment[tr]=Evrensel TDE ekran temalarını yönet +Comment[tt]=TDE'nıñ tışlaw törlären caylaw idäräse +Comment[uk]=Керування глобальними темами TDE +Comment[vi]=Trình quản lý các sắc thái của TDE +Comment[wa]=Manaedjî tinmes pol rivnance globåle di TDE +Comment[zh_CN]=管理全局 TDE 视觉主题 +Comment[zh_TW]=管理全域 TDE 視覺佈景 +Exec=tdecmshell kthememanager +Icon=kthememgr +Keywords=themes;look and feel; +Keywords[af]=themes;look and feel;temas; +Keywords[ar]=سمات;المظهر و الإحساس; +Keywords[az]=örtüklər;görünüş;örtük;theme;look; +Keywords[be]=Тэмы;Вонкавы выгляд;themes;look and feel; +Keywords[bg]=теми; вид; themes; look and feel; +Keywords[br]=gizioù;Neuz ha feson; +Keywords[bs]=themes;look and feel;teme;izgled;osjećaj; +Keywords[ca]=temes;aspecte i efecte; +Keywords[cs]=motivy;vzhled a chování; +Keywords[csb]=téma;wëzdrzatk; +Keywords[cy]=themau;golwg a theimlad; +Keywords[da]=temaer;udseende; +Keywords[de]=Designs;Themes;Erscheinungsbild; +Keywords[el]=θέματα;εμφάνιση και αίσθηση; +Keywords[eo]=etoso;etosoj;videbleco;uzebleco; +Keywords[es]=temas;aspecto y comportamiento; +Keywords[et]=teemad;välimus; +Keywords[eu]=gaiak;itxura eta portaera; +Keywords[fa]=چهرهها، ظاهر و احساس; +Keywords[fi]=teemat;ulkonäkö ja tuntuma; +Keywords[fr]=thèmes;apparence et ergonomie; +Keywords[fy]=tema's;úterlik en gedrach; +Keywords[ga]=téamaí;cuma; +Keywords[gl]=temas;apariencia; +Keywords[he]=ערכות; מראה ותחושה; themes;look and feel; +Keywords[hi]=प्रसंग; रूप तथा आकार; +Keywords[hr]=themes;look and feel;izgled i osjećaj;teme; +Keywords[hu]=témák;megjelenés; +Keywords[it]=temi;aspetto; +Keywords[ja]=テーマ;look and feel;外観;ルックアンドフィール; +Keywords[km]=ស្បែក;រូបរាង និងមុខងារ; +Keywords[lt]=themes;look and feel;temos;išvaizda ir jausena; +Keywords[lv]=tēmas;izskats un sajūtas; +Keywords[mk]=themes;look and feel;теми;изглед и чувство; +Keywords[ms]=tema; rupa dan rasa; +Keywords[mt]=themes;look and feel;temi;dehra; +Keywords[nb]=temaer;utseende og oppførsel; +Keywords[nds]=Muster;themes;Themas;look and feel;Achtergrund;Klören;Klöörschemas;Schemas;Klöörschema; +Keywords[ne]=विषयवस्तु; हेराइ र बुझाइ; +Keywords[nl]=thema's;uiterlijk en gedrag; +Keywords[nn]=tema;utsjånad og åtferd; +Keywords[pa]=ਸਰੂਪ;ਦਿੱਖ ਅਤੇ ਛੋਹ; +Keywords[pl]=motywy;wygląd; +Keywords[pt]=temas;aparência e comportamento; +Keywords[pt_BR]=temas;aparência; +Keywords[ro]=tematici;apect;grafică; +Keywords[rw]=Insanganyamatsiko;imboneko n'ukumva; +Keywords[se]=fáttát;fárda ja láhtten; +Keywords[sk]=témy;vzhľad; +Keywords[sl]=teme;videz in občutek; +Keywords[sr]=themes;look and feel;теме;изглед и осећај;изглед; +Keywords[sr@Latn]=themes;look and feel;teme;izgled i osećaj;izgled; +Keywords[sv]=teman;utseende och känsla; +Keywords[ta]=உரைபொருள்;பார் மற்றும் உணர்ணர்; +Keywords[th]=ชุดตกแต่ง;รูปแบบและสัมผัส; +Keywords[tr]=temalar;görünüm ve hisset; +Keywords[uk]=теми;вигляд та поведінка; +Keywords[uz]=mavzular;tashqi koʻrinishi; +Keywords[uz@cyrillic]=мавзулар;ташқи кўриниши; +Keywords[vi]=sắc thái;cảm nhận; +Keywords[wa]=tinmes;rivnance; +Keywords[zh_CN]=themes;look and feel;主题;观感; +Keywords[zh_TW]=themes;look and feel;主題;外觀與感覺; +Name=Theme Manager +Name[af]=Tema Bestuurder +Name[ar]=مسيير السمات +Name[az]=Örtük İdarəcisi +Name[be]=Кіраванне тэмамі +Name[bg]=Мениджър на теми +Name[bn]=থীম ম্যানেজার +Name[br]=Merour gwiskadoù +Name[bs]=Upravitelj temama +Name[ca]=Gestor de temes +Name[cs]=Správce motivů +Name[csb]=Menedżer témów +Name[cy]=Rheolwr Thema +Name[da]=Temahåndtering +Name[de]=Designverwaltung +Name[el]=Διαχειριστής θεμάτων +Name[eo]=Etosadministrilo +Name[es]=Gestor de temas +Name[et]=Teemahaldur +Name[eu]=Gai kudeatzailea +Name[fa]=مدیر چهره +Name[fi]=Teemanhallinta +Name[fr]=Gestionnaire de thèmes +Name[fy]=Temabehearder +Name[ga]=Bainisteoir na dTéamaí +Name[gl]=Xestor de Temas +Name[he]=מנהל ערכות נושא +Name[hi]=प्रसंग प्रबंधक +Name[hr]=Upravljanje temama +Name[hu]=Témák +Name[id]=Manajer Theme +Name[is]=Þemustjóri +Name[it]=Gestore dei temi +Name[ja]=テーママネージャ +Name[ka]=თემების მენეჯერი +Name[kk]=Нақыштар менеджері +Name[km]=កម្មវិធីគ្រប់គ្រងស្បែក +Name[ko]=테마 관리자 +Name[lo]=ເຄື່ອງມືຈັດການ ທີມ +Name[lt]=Temų tvarkyklė +Name[lv]=Tēmu Menedžeris +Name[mk]=Менаџер на теми +Name[mn]=Загвар-Удирлагч +Name[ms]=Pengurus Tema +Name[mt]=Manager tat-Temi +Name[nb]=Temabehandler +Name[nds]=Musterpleger +Name[ne]=विषयवस्तु प्रबन्धक +Name[nl]=Themabeheerder +Name[nn]=Temahandsamar +Name[nso]=Molaodi wa Molaetsa +Name[oc]=Gestionari de temes +Name[pa]=ਸਰੂਪ ਮੈਨੇਜਰ +Name[pl]=Menedżer motywów +Name[pt]=Gestor de Temas +Name[pt_BR]=Gerenciador de Temas +Name[ro]=Managerul de tematică +Name[ru]=Менеджер тем +Name[rw]=Mugenga Insanganyamatsiko +Name[se]=Fáddagieđahalli +Name[sk]=Správca tém +Name[sl]=Upravitelj tem +Name[sr]=Менаџер тема +Name[sr@Latn]=Menadžer tema +Name[ss]=Siphatsi sendzikimba +Name[sv]=Temahanterare +Name[ta]=பொருள் மேலாளர் +Name[tg]=Мудири мавзӯъ +Name[th]=เครื่องมือจัดการชุดตกแต่ง +Name[tr]=Tema Yöneticisi +Name[tt]=Tışlaw İdäräçe +Name[uk]=Менеджер тем +Name[uz]=Mavzu boshqaruvchisi +Name[uz@cyrillic]=Мавзу бошқарувчиси +Name[ven]=Mulanguli wa thero +Name[vi]=Trình quản lí sắc thái +Name[wa]=Manaedjeu di tinmes +Name[xh]=Umphathi Womxholo +Name[zh_CN]=主题管理器 +Name[zh_TW]=佈景管理程式 +Name[zu]=Imenenja Yengqikithi +Terminal=false +Type=Application +X-TDE-FactoryName=kthememanager +X-TDE-Library=kthememanager +Categories=Qt;TDE;X-TDE-settings-looknfeel; +X-DocPath=kcontrol/kthememanager/index.html diff --git a/kcontrol/kthememanager/kthememanager.h b/kcontrol/kthememanager/kthememanager.h new file mode 100644 index 000000000..2c5e494f4 --- /dev/null +++ b/kcontrol/kthememanager/kthememanager.h @@ -0,0 +1,157 @@ +// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*- +/* Copyright (C) 2003 Lukas Tinkl <[email protected]> + + 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 +*/ + +#ifndef KTHEMEMANAGER_H +#define KTHEMEMANAGER_H + +#include <tdecmodule.h> +#include <krun.h> +#include <kservice.h> +#include <kurl.h> + +#include "kthemedlg.h" +#include "ktheme.h" + +class TQString; + +class TDEAboutData; + +#define ORIGINAL_THEME "original" // no i18n() here!!! + +/* +class TDEIconViewItem; + +class KThemeDetailsItem: public TDEIconViewItem +{ +public: + KThemeDetailsItem( TDEIconView * parent, const TQString & text, const TQPixmap & icon, const TQString & execString ) + : TDEIconViewItem( parent, text, icon ) { m_exec = execString; } + virtual ~KThemeDetailsItem() { }; + + void exec() { + ( void ) new KRun( m_exec ); + } +private: + TQString m_exec; +}; +*/ + +/** + * + * This is the for KControl config module for installing, + * creating and removing visual themes. + * + * @brief The Theme Manager config module. + * @author Lukas Tinkl <[email protected]> + */ +class kthememanager: public TDECModule +{ + Q_OBJECT +public: + kthememanager( TQWidget *parent=0, const char *name=0 ); + virtual ~kthememanager(); + + /** + * Called on module startup + */ + virtual void load(); + virtual void load(bool useDefaults); + /** + * Called when applying the changes + */ + virtual void save(); + /** + * Called when the user requests the default values + */ + virtual void defaults(); + +protected: + void dragEnterEvent ( TQDragEnterEvent * ev ); + void dropEvent ( TQDropEvent * ev ); + +signals: + /** + * Emitted when some @p urls are dropped onto the kcm + */ + void filesDropped(const KURL::List &urls); + +private slots: + /** + * Install a theme from a tarball (*.kth) + */ + void slotInstallTheme(); + + /** + * Remove an installed theme + */ + void slotRemoveTheme(); + + /** + * Create a new theme + */ + void slotCreateTheme(); + + /** + * Update the theme's info and preview + */ + void slotThemeChanged( TQListViewItem * item ); + + /** + * Invoked when one drag and drops @p urls onto the kcm + * @see signal filesDropped + */ + void slotFilesDropped( const KURL::List & urls ); + void updateButton(); + +private: + /** + * List themes available in the system and insert them into the listview. + */ + void listThemes(); + + /** + * Performs the actual theme installation. + */ + void addNewTheme( const KURL & url ); + + /** + * Perform internal initialization of paths. + */ + void init(); + + /** + * Try to find out whether a theme is installed and get its version number + * @param themeName The theme name + * @return The theme's version number or -1 if not installed + */ + static float getThemeVersion( const TQString & themeName ); + + void queryLNFModules(); + + /** + * Updates the preview widget + */ + void updatePreview( const TQString & pixFile ); + bool themeExist(const TQString &_themeName); + KThemeDlg * dlg; + + KTheme * m_theme; + KTheme * m_origTheme; +}; + +#endif diff --git a/kcontrol/kthememanager/newthemewidget.ui b/kcontrol/kthememanager/newthemewidget.ui new file mode 100644 index 000000000..e84f1efa8 --- /dev/null +++ b/kcontrol/kthememanager/newthemewidget.ui @@ -0,0 +1,130 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>NewThemeWidget</class> +<author>Lukas Tinkl <[email protected]></author> +<widget class="TQWidget"> + <property name="name"> + <cstring>NewThemeWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>537</width> + <height>431</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&Theme name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>leName</cstring> + </property> + </widget> + <widget class="TQLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>&Author:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>leAuthor</cstring> + </property> + </widget> + <widget class="TQLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>&Email:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>leEmail</cstring> + </property> + </widget> + <widget class="TQLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>&Homepage:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>leHomepage</cstring> + </property> + </widget> + <widget class="TQLineEdit" row="2" column="1"> + <property name="name"> + <cstring>leEmail</cstring> + </property> + </widget> + <widget class="TQLineEdit" row="0" column="1"> + <property name="name"> + <cstring>leName</cstring> + </property> + </widget> + <widget class="TQLineEdit" row="3" column="1"> + <property name="name"> + <cstring>leHomepage</cstring> + </property> + </widget> + <widget class="TQLineEdit" row="1" column="1"> + <property name="name"> + <cstring>leAuthor</cstring> + </property> + </widget> + <widget class="TQLabel" row="5" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>Co&mment:</string> + </property> + <property name="alignment"> + <set>AlignTop</set> + </property> + <property name="buddy" stdset="0"> + <cstring>teComment</cstring> + </property> + </widget> + <widget class="TQTextEdit" row="5" column="1"> + <property name="name"> + <cstring>teComment</cstring> + </property> + </widget> + <widget class="TQLineEdit" row="4" column="1"> + <property name="name"> + <cstring>leVersion</cstring> + </property> + </widget> + <widget class="TQLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel6</cstring> + </property> + <property name="text"> + <string>&Version:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>leVersion</cstring> + </property> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>leName</tabstop> + <tabstop>leAuthor</tabstop> + <tabstop>leEmail</tabstop> + <tabstop>leHomepage</tabstop> + <tabstop>leVersion</tabstop> + <tabstop>teComment</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kcontrol/kthememanager/x-ktheme.desktop b/kcontrol/kthememanager/x-ktheme.desktop new file mode 100644 index 000000000..8db7d86b5 --- /dev/null +++ b/kcontrol/kthememanager/x-ktheme.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +MimeType=application/x-ktheme +Comment=TDE Theme +Comment[af]=TDE Tema +Comment[ar]=سمة TDE +Comment[az]=TDE Örtüyü +Comment[be]=Тэма TDE +Comment[bg]=Тема за TDE +Comment[bn]=কে.ডি.ই. থীম +Comment[br]=Giz TDE +Comment[bs]=TDE tema +Comment[ca]=Tema TDE +Comment[cs]=TDE motiv +Comment[csb]=Téma TDE +Comment[cy]=Thema TDE +Comment[da]=TDE-tema +Comment[de]=TDE-Design +Comment[el]=Θέμα του TDE +Comment[eo]=TDEa etoso +Comment[es]=Tema de TDE +Comment[et]=TDE teema +Comment[fa]=چهرۀ TDE +Comment[fi]=TDE-teema +Comment[fr]=Thème TDE +Comment[fy]=TDE-tema +Comment[ga]=Téama TDE +Comment[gl]=Tema de TDE +Comment[he]=ערכת נושא של TDE +Comment[hi]=केडीई प्रसंग +Comment[hr]=TDE tema +Comment[hu]=TDE-téma +Comment[id]=Tema TDE +Comment[is]=TDE þema +Comment[it]=Tema TDE +Comment[ja]=TDE テーマ +Comment[ka]=TDE-ს თემა +Comment[kk]=TDE нақышы +Comment[km]=ស្បែក TDE +Comment[ko]=TDE 테마 설치 +Comment[lo]=ທີມຂອງ TDE +Comment[lt]=TDE Tema +Comment[lv]=TDE Tēma +Comment[mk]=TDE-тема +Comment[mn]=КДЭ-Хэлбэр +Comment[ms]=Tema TDE +Comment[mt]=Tema TDE +Comment[nb]=TDE-tema +Comment[nds]=TDE Muster +Comment[ne]=TDE विषयवस्तु +Comment[nl]=TDE-thema +Comment[nn]=TDE-tema +Comment[nso]=Molaetsa wa TDE +Comment[pa]=TDE ਸਰੂਪ +Comment[pl]=Motywy TDE +Comment[pt]=Tema do TDE +Comment[pt_BR]=Tema do TDE +Comment[ro]=Tematică TDE +Comment[ru]=Тема TDE +Comment[rw]=Insanganyamatsiko za TDE +Comment[se]=TDE-fáddá +Comment[sk]=Téma TDE +Comment[sl]=Tema TDE +Comment[sr]=TDE тема +Comment[sr@Latn]=TDE tema +Comment[sv]=TDE-tema +Comment[ta]=TDE பொருள் +Comment[tg]=Мавзӯъи TDE +Comment[th]=ชุดตกแต่ง TDE +Comment[tr]=TDE Teması +Comment[tt]=TDE Tışlawı +Comment[uk]=Тема TDE +Comment[uz]=TDE mavzusi +Comment[uz@cyrillic]=TDE мавзуси +Comment[ven]=Thero ya TDE +Comment[vi]=Sắc thái TDE +Comment[wa]=Tinme TDE +Comment[xh]=Umxholo we TDE +Comment[zh_CN]=TDE 主题 +Comment[zh_TW]=TDE 主題 +Comment[zu]=Ingqikithi ye-TDE +Icon=kthememgr +Type=MimeType +Patterns=*.kth; +X-TDE-AutoEmbed=false |