1
// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
2
/* Copyright (C) 2003 Lukas Tinkl <lukas@kde.org>
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
#include <QPushButton>
23
#include <QToolButton>
26
#include <QDragEnterEvent>
27
#include <QVBoxLayout>
31
#include <kaboutdata.h>
32
#include <kapplication.h>
35
#include <kemailsettings.h>
36
#include <kfiledialog.h>
38
#include <kiconloader.h>
39
#include <k3listview.h>
41
#include <kmessagebox.h>
42
#include <kservicegroup.h>
43
#include <kstandarddirs.h>
44
#include <k3urldrag.h>
47
#include "kthememanager.h"
48
#include "knewthemedlg.h"
49
#include <config-workspace.h>
50
#include <kpluginfactory.h>
51
#include <kpluginloader.h>
54
K_PLUGIN_FACTORY(kthememanagerFactory, registerPlugin<kthememanager>();)
55
K_EXPORT_PLUGIN(kthememanagerFactory("kthememanager"))
58
kthememanager::kthememanager( QWidget *parent, const QVariantList & )
59
: KCModule( kthememanagerFactory::componentData(), parent ), m_theme( 0 ), m_origTheme( 0 )
62
KAboutData *about = new KAboutData("kthememanager", 0, ki18n("KDE Theme Manager"),
63
"0.4", ki18n("This control module handles installing, removing and "
64
"creating visual KDE themes."),
65
KAboutData::License_GPL, ki18n("(c) 2003, 2004 Lukáš Tinkl"), KLocalizedString(),
66
"http://developer.kde.org/~lukas/kthememanager");
67
setAboutData( about );
69
setQuickHelp( i18n("This control module handles installing, removing and "
70
"creating visual KDE themes."));
72
setButtons( KCModule::Default|KCModule::Apply );
74
setAcceptDrops( true );
77
QBoxLayout *top = new QVBoxLayout(this);
79
top->setSpacing(KDialog::spacingHint());
81
dlg = new KThemeDlg(this);
82
top->addWidget( dlg );
84
dlg->lvThemes->setColumnWidthMode( 0, Q3ListView::Maximum );
86
connect( ( QObject * )dlg->btnInstall, SIGNAL( clicked() ),
87
this, SLOT( slotInstallTheme() ) );
89
connect( ( QObject * )dlg->btnRemove, SIGNAL( clicked() ),
90
this, SLOT( slotRemoveTheme() ) );
92
connect( ( QObject * )dlg->btnCreate, SIGNAL( clicked() ),
93
this, SLOT( slotCreateTheme() ) );
95
connect( ( QObject * )dlg->lvThemes, SIGNAL( clicked( Q3ListViewItem * ) ),
96
this, SLOT( slotThemeChanged( Q3ListViewItem * ) ) );
98
connect( this, SIGNAL( filesDropped( const KUrl::List& ) ),
99
this, SLOT( updateButton() ) );
101
connect( ( QObject * )dlg->lvThemes, SIGNAL( clicked( Q3ListViewItem * ) ),
102
this, SLOT( updateButton() ) );
104
connect( dlg->lbGet, SIGNAL(leftClickedUrl(QString)),SLOT(startKonqui(QString) ) );
105
connect( dlg->btnBackground, SIGNAL(clicked()),SLOT(startBackground()) );
106
connect( dlg->btnColors, SIGNAL(clicked()),SLOT(startColors()) );
107
connect( dlg->btnStyle, SIGNAL(clicked()),SLOT(startStyle()) );
108
connect( dlg->btnIcons, SIGNAL(clicked()),SLOT(startIcons()) );
109
connect( dlg->btnFonts, SIGNAL(clicked()),SLOT(startFonts()) );
110
connect( dlg->btnSaver, SIGNAL(clicked()),SLOT(startSaver()) );
112
m_origTheme = new KTheme( this, true ); // stores the defaults to get back to
113
m_origTheme->setName( ORIGINAL_THEME );
114
m_origTheme->createYourself();
120
kthememanager::~kthememanager()
127
void kthememanager::startKonqui( const QString & url )
129
(void) new KRun(url,this);
132
void kthememanager::startBackground()
134
KRun::runCommand("kcmshell4 background", this);
137
void kthememanager::startColors()
139
KRun::runCommand("kcmshell4 colors", this);
142
void kthememanager::startStyle()
144
KRun::runCommand("kcmshell4 style", this);
147
void kthememanager::startIcons()
149
KRun::runCommand("kcmshell4 icons", this);
152
void kthememanager::startFonts()
154
KRun::runCommand("kcmshell4 fonts", this);
157
void kthememanager::startSaver()
159
KRun::runCommand("kcmshell4 screensaver", this);
162
void kthememanager::init()
164
KGlobal::dirs()->addResourceType( "themes", "data", "kthememanager/themes/" );
167
void kthememanager::updateButton()
169
Q3ListViewItem * cur = dlg->lvThemes->currentItem();
170
bool enable = (cur != 0);
172
enable = QFile(KGlobal::dirs()->saveLocation( "themes", cur->text( 0 ) + '/'+ cur->text( 0 )+ ".xml" ,false/*don't create dir*/ )).exists();
174
dlg->btnRemove->setEnabled(enable);
178
void kthememanager::load()
182
// Load the current theme name
183
KConfig _conf("kcmthememanagerrc", KConfig::NoGlobals);
184
KConfigGroup conf(&_conf, "General" );
185
QString themeName = conf.readEntry( "CurrentTheme" );
186
Q3ListViewItem * cur = dlg->lvThemes->findItem( themeName, 0 );
189
dlg->lvThemes->setSelected( cur, true );
190
dlg->lvThemes->ensureItemVisible( cur );
191
slotThemeChanged( cur );
195
void kthememanager::defaults()
198
m_origTheme->apply();
201
void kthememanager::save()
203
Q3ListViewItem * cur = dlg->lvThemes->currentItem();
207
QString themeName = cur->text( 0 );
209
m_theme = new KTheme( this, KGlobal::dirs()->findResource( "themes", themeName + '/' + themeName + ".xml") );
212
// Save the current theme name
213
KConfig _conf("kcmthememanagerrc", KConfig::NoGlobals);
214
KConfigGroup conf(&_conf, "General" );
215
conf.writeEntry( "CurrentTheme", themeName );
224
void kthememanager::listThemes()
226
dlg->lvThemes->clear();
227
dlg->lbPreview->setPixmap( QPixmap() );
229
QStringList themes = KGlobal::dirs()->findAllResources( "themes", "*.xml", KStandardDirs::Recursive );
231
QStringList::const_iterator it;
233
for ( it = themes.begin(); it != themes.end(); ++it )
235
KTheme theme( this, ( *it ) );
236
QString name = theme.name();
237
if ( name != ORIGINAL_THEME ) // skip the "original" theme
238
( void ) new Q3ListViewItem( dlg->lvThemes, name, theme.comment() );
241
kDebug() << "Available themes: " << themes;
244
float kthememanager::getThemeVersion( const QString & themeName )
246
QStringList themes = KGlobal::dirs()->findAllResources( "themes", "*.xml", KStandardDirs::Recursive );
248
QStringList::const_iterator it;
250
for ( it = themes.begin(); it != themes.end(); ++it )
252
KTheme theme( 0L, ( *it ) );
253
QString name = theme.name();
255
float version = theme.version().toFloat( &ok );
256
if ( name == themeName && ok )
263
void kthememanager::slotInstallTheme()
265
addNewTheme( KFileDialog::getOpenUrl( KUrl::fromPath(":themes"), "*.kth|" + i18n("Theme Files"), this,
266
i18n( "Select Theme File" ) ) );
269
void kthememanager::addNewTheme( const KUrl & url )
273
QString themeName = QFileInfo( url.fileName() ).baseName();
274
if ( getThemeVersion( themeName ) != -1 ) // theme exists already
276
KTheme::remove( themeName ); // remove first
279
m_theme = new KTheme(this);
280
if ( m_theme->load( url ) )
283
emit changed( true );
292
void kthememanager::slotRemoveTheme()
294
// get the selected item from the listview
295
Q3ListViewItem * cur = dlg->lvThemes->currentItem();
299
QString themeName = cur->text( 0 );
300
if ( KMessageBox::warningContinueCancel( this, "<qt>" + i18n( "Do you really want to remove the theme <b>%1</b>?", themeName ),
301
i18n( "Remove Theme" ),KStandardGuiItem::remove() )
302
== KMessageBox::Continue )
304
KTheme::remove( themeName );
311
bool kthememanager::themeExist(const QString &_themeName)
313
return ( dlg->lvThemes->findItem( _themeName, 0 )!=0 );
316
void kthememanager::slotCreateTheme()
318
KNewThemeDlg dlg( this );
321
es.setProfile( es.defaultProfileName() );
323
dlg.setName( i18n( "My Theme" ) );
324
dlg.setAuthor( es.getSetting( KEMailSettings::RealName ) ) ;
325
dlg.setEmail( es.getSetting( KEMailSettings::EmailAddress ) );
326
dlg.setVersion( "0.1" );
328
if ( dlg.exec() == QDialog::Accepted )
331
QString themeName = dlg.getName();
332
if ( themeExist(themeName) )
334
KMessageBox::information( this, i18n( "Theme %1 already exists.", themeName ) );
338
if ( getThemeVersion( themeName ) != -1 ) // remove the installed theme first
340
KTheme::remove( themeName );
342
m_theme = new KTheme( this, true );
343
m_theme->setName( dlg.getName() );
344
m_theme->setAuthor( dlg.getAuthor() );
345
m_theme->setEmail( dlg.getEmail() );
346
m_theme->setHomepage( dlg.getHomepage() );
347
m_theme->setComment( dlg.getComment().replace( "\n", "" ) );
348
m_theme->setVersion( dlg.getVersion() );
350
QString result = m_theme->createYourself( true );
351
m_theme->addPreview();
353
if ( !result.isEmpty() )
354
KMessageBox::information( this, i18nc( "%1 is theme archive name", "Your theme has been successfully created in %1.", result ),
355
i18n( "Theme Created" ), "theme_created_ok" );
357
KMessageBox::error( this, i18n( "An error occurred while creating your theme." ),
358
i18n( "Theme Not Created" ) );
367
void kthememanager::slotThemeChanged( Q3ListViewItem * item )
371
QString themeName = item->text(0);
372
kDebug() << "Activated theme: " << themeName ;
374
QString themeDir = KGlobal::dirs()->findResourceDir( "themes", themeName + '/' + themeName + ".xml") + themeName + '/';
376
QString pixFile = themeDir + themeName + ".preview.png";
378
if ( QFile::exists( pixFile ) )
380
updatePreview( pixFile );
384
dlg->lbPreview->setPixmap( QPixmap() );
385
dlg->lbPreview->setText( i18n( "This theme does not contain a preview." ) );
388
KTheme theme( this, themeDir + themeName + ".xml" );
389
dlg->lbPreview->setToolTip( "<qt>" + i18n( "Author: %1<br />Email: %2<br />Version: %3<br />Homepage: %4" ,
390
theme.author(), theme.email() ,
391
theme.version(), theme.homepage() ) + "</qt>");
393
emit changed( true );
397
void kthememanager::dragEnterEvent( QDragEnterEvent * ev )
399
ev->setAccepted( K3URLDrag::canDecode( ev ) );
402
void kthememanager::dropEvent( QDropEvent * ev )
405
if ( K3URLDrag::decode( ev, urls ) )
407
emit filesDropped( urls );
411
void kthememanager::slotFilesDropped( const KUrl::List & urls )
413
for ( KUrl::List::ConstIterator it = urls.begin(); it != urls.end(); ++it )
417
void kthememanager::queryLNFModules()
419
/*KServiceGroup::Ptr settings = KServiceGroup::group( "Settings/LookNFeel/" );
420
if ( !settings || !settings->isValid() )
423
KServiceGroup::List list = settings->entries();
425
// Iterate over all entries in the group
426
for( KServiceGroup::List::ConstIterator it = list.begin();
427
it != list.end(); it++ )
429
KSycocaEntry *p = ( *it );
430
if ( p->isType( KST_KService ) )
432
KService *s = static_cast<KService *>( p );
433
( void ) new KThemeDetailsItem( dlg->lvDetails, s->name(), s->pixmap( KIconLoader::Desktop ), s->exec() );
437
dlg->lvDetails->sort();*/
439
// For now use a static list
440
dlg->btnBackground->setIcon( KIcon( "preferences-desktop-wallpaper" ) );
441
dlg->btnColors->setIcon( KIcon( "preferences-desktop-color" ) );
442
dlg->btnStyle->setIcon( KIcon( "preferences-desktop-theme-style" ) );
443
dlg->btnIcons->setIcon( KIcon( "preferences-desktop-icons" ) );
444
dlg->btnFonts->setIcon( KIcon( "preferences-desktop-font" ) );
445
dlg->btnSaver->setIcon( KIcon( "preferences-desktop-wallpaper" ) );
448
void kthememanager::updatePreview( const QString & pixFile )
450
kDebug() << "Preview is in file: " << pixFile;
451
QImage preview( pixFile, "PNG" );
452
if (preview.width()>dlg->lbPreview->contentsRect().width() ||
453
preview.height()>dlg->lbPreview->contentsRect().height() )
454
preview = preview.scaled( dlg->lbPreview->contentsRect().size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
455
QPixmap pix = QPixmap::fromImage( preview );
456
dlg->lbPreview->setPixmap( pix );
459
#include "kthememanager.moc"