00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
#include <assert.h>
00033
#include <qdir.h>
00034
#include <qfileinfo.h>
00035
#include <qlayout.h>
00036
#include <qwhatsthis.h>
00037
#include <qgroupbox.h>
00038
#include <qcheckbox.h>
00039
#include <qtabwidget.h>
00040
#include <qvbox.h>
00041
#include <qlabel.h>
00042
#include <qfile.h>
00043
#include <qslider.h>
00044
00045
#include <kapplication.h>
00046
#include <kcombobox.h>
00047
#include <kdebug.h>
00048
#include <kdesktopfile.h>
00049
#include <kstandarddirs.h>
00050
#include <kglobal.h>
00051
#include <klocale.h>
00052
#include <kdialog.h>
00053
#include <kgenericfactory.h>
00054
#include <kaboutdata.h>
00055
#include <dcopclient.h>
00056
00057
#include "kwindecoration.h"
00058
#include "preview.h"
00059
#include <kdecoration_plugins_p.h>
00060
#include <kdecorationfactory.h>
00061
00062
00063
00064
typedef KGenericFactory<KWinDecorationModule, QWidget> KWinDecoFactory;
00065 K_EXPORT_COMPONENT_FACTORY( kcm_kwindecoration, KWinDecoFactory(
"kcmkwindecoration") )
00066
00067 KWinDecorationModule::KWinDecorationModule(QWidget* parent, const
char* name, const QStringList &)
00068 : DCOPObject("KWinClientDecoration"),
00069 KCModule(KWinDecoFactory::instance(), parent, name),
00070 kwinConfig("kwinrc"),
00071 pluginObject(0)
00072 {
00073 kwinConfig.setGroup(
"Style");
00074 plugins =
new KDecorationPreviewPlugins( &kwinConfig );
00075
00076 QVBoxLayout* layout =
new QVBoxLayout(
this);
00077 tabWidget =
new QTabWidget(
this );
00078 layout->addWidget( tabWidget );
00079
00080
00081 QWidget *pluginPage =
new QWidget( tabWidget );
00082
00083 QHBox *hbox =
new QHBox(pluginPage);
00084 hbox->setSpacing(KDialog::spacingHint());
00085
00086 decorationList =
new KComboBox( hbox );
00087
00088 QString whatsThis = i18n(
"Select the window decoration. This is the look and feel of both "
00089
"the window borders and the window handle.");
00090
00091 QWhatsThis::add(decorationList, whatsThis);
00092
00093 QVBoxLayout* pluginLayout =
new QVBoxLayout(pluginPage, KDialog::marginHint(), KDialog::spacingHint());
00094 pluginLayout->addWidget(hbox);
00095
00096
00097
00098
00099
00100 QFrame* preview_frame =
new QFrame( pluginPage );
00101 preview_frame->setFrameShape( QFrame::NoFrame );
00102 QVBoxLayout* preview_layout =
new QVBoxLayout( preview_frame, 0 );
00103 preview =
new KDecorationPreview( preview_frame );
00104 preview_layout->addWidget( preview );
00105 pluginLayout->addWidget( preview_frame );
00106 pluginLayout->setStretchFactor( preview_frame, 10 );
00107
00108 pluginSettingsGrp =
new QGroupBox( i18n(
"Decoration Options"), pluginPage );
00109 pluginSettingsGrp->setColumnLayout( 0, Vertical );
00110 pluginSettingsGrp->setFlat(
true );
00111 pluginSettingsGrp->layout()->setMargin( 0 );
00112 pluginSettingsGrp->layout()->setSpacing( KDialog::spacingHint() );
00113 pluginLayout->addWidget( pluginSettingsGrp );
00114
00115 pluginConfigWidget =
new QVBox(pluginSettingsGrp);
00116 pluginSettingsGrp->layout()->add( pluginConfigWidget );
00117
00118
00119 QVBox* buttonPage =
new QVBox( tabWidget );
00120 buttonPage->setSpacing( KDialog::spacingHint() );
00121 buttonPage->setMargin( KDialog::marginHint() );
00122
00123 cbShowToolTips =
new QCheckBox(
00124 i18n(
"&Show window button tooltips"), buttonPage );
00125 QWhatsThis::add( cbShowToolTips,
00126 i18n(
"Enabling this checkbox will show window button tooltips. "
00127
"If this checkbox is off, no window button tooltips will be shown."));
00128
00129 lBorder =
new QLabel( buttonPage );
00130 slBorder =
new QSlider( Horizontal, buttonPage );
00131 slBorder->setPageStep(1);
00132 QWhatsThis::add( slBorder, i18n(
"This slider shows all border sizes supported by this decoration." ));
00133 lBorder->setBuddy( slBorder );
00134 lBorder->hide();
00135 slBorder->hide();
00136
00137 cbUseCustomButtonPositions =
new QCheckBox(
00138 i18n(
"Use custom titlebar button &positions"), buttonPage );
00139 QWhatsThis::add( cbUseCustomButtonPositions,
00140 i18n(
"The appropriate settings can be found in the \"Buttons\" Tab. "
00141
"Please note that this option is not available on all styles yet!" ) );
00142
00143 buttonBox =
new QGroupBox( 1, Qt::Horizontal,
00144 i18n(
"Titlebar Button Positions"), buttonPage );
00145
00146
00147 QLabel* label =
new QLabel( buttonBox );
00148 dropSite =
new ButtonDropSite( buttonBox );
00149 label->setAlignment(
int( QLabel::WordBreak ) );
00150 label->setText( i18n(
"To add or remove titlebar buttons, simply <i>drag</i> items "
00151
"between the available item list and the titlebar preview. Similarly, "
00152
"drag items within the titlebar preview to re-position them.") );
00153 buttonSource =
new ButtonSource( buttonBox );
00154
00155
00156
00157 findDecorations();
00158 createDecorationList();
00159 readConfig( &kwinConfig );
00160 resetPlugin( &kwinConfig );
00161
00162 tabWidget->insertTab( pluginPage, i18n(
"&Window Decoration") );
00163 tabWidget->insertTab( buttonPage, i18n(
"&Buttons") );
00164
00165 connect( dropSite, SIGNAL(buttonAdded(
char)), buttonSource, SLOT(hideButton(
char)) );
00166 connect( dropSite, SIGNAL(buttonRemoved(
char)), buttonSource, SLOT(showButton(
char)) );
00167 connect( buttonSource, SIGNAL(buttonDropped()), dropSite, SLOT(removeClickedButton()) );
00168 connect( dropSite, SIGNAL(changed()),
this, SLOT(slotSelectionChanged()) );
00169 connect( buttonSource, SIGNAL(selectionChanged()),
this, SLOT(slotSelectionChanged()) );
00170 connect( decorationList, SIGNAL(activated(
const QString&)), SLOT(slotSelectionChanged()) );
00171 connect( decorationList, SIGNAL(activated(
const QString&)),
00172 SLOT(slotChangeDecoration(
const QString&)) );
00173 connect( cbUseCustomButtonPositions, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
00174 connect(cbUseCustomButtonPositions, SIGNAL(toggled(
bool)), buttonBox, SLOT(setEnabled(
bool)));
00175 connect( cbShowToolTips, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
00176 connect( slBorder, SIGNAL( valueChanged(
int )), SLOT( slotBorderChanged(
int )));
00177
00178
00179
00180 connectDCOPSignal(
"kwin", 0,
"dcopResetAllClients()",
"dcopUpdateClientList()",
false);
00181 }
00182
00183
00184 KWinDecorationModule::~KWinDecorationModule()
00185 {
00186
delete preview;
00187
delete plugins;
00188 }
00189
00190
00191
00192
00193
void KWinDecorationModule::findDecorations()
00194 {
00195 QStringList dirList = KGlobal::dirs()->findDirs(
"data",
"kwin");
00196 QStringList::ConstIterator it;
00197
00198
for (it = dirList.begin(); it != dirList.end(); it++)
00199 {
00200 QDir d(*it);
00201
if (d.exists())
00202
for (QFileInfoListIterator it(*d.entryInfoList()); it.current(); ++it)
00203 {
00204 QString filename(it.current()->absFilePath());
00205
if (KDesktopFile::isDesktopFile(filename))
00206 {
00207 KDesktopFile desktopFile(filename);
00208 QString libName = desktopFile.readEntry(
"X-KDE-Library");
00209
00210
if (!libName.isEmpty() && libName.startsWith(
"kwin3_" ))
00211 {
00212 DecorationInfo di;
00213 di.name = desktopFile.readName();
00214 di.libraryName = libName;
00215 decorations.append( di );
00216 }
00217 }
00218 }
00219 }
00220 }
00221
00222
00223
00224
void KWinDecorationModule::createDecorationList()
00225 {
00226 QValueList<DecorationInfo>::ConstIterator it;
00227
00228
00229 QStringList decorationNames;
00230 decorationNames.append( i18n(
"KDE 2") );
00231
for (it = decorations.begin(); it != decorations.end(); ++it)
00232 {
00233 decorationNames.append((*it).name);
00234 }
00235 decorationNames.sort();
00236 decorationList->insertStringList(decorationNames);
00237 }
00238
00239
00240
00241
void KWinDecorationModule::slotChangeDecoration(
const QString & text)
00242 {
00243 KConfig kwinConfig(
"kwinrc");
00244 kwinConfig.setGroup(
"Style");
00245
00246
00247 resetPlugin( &kwinConfig, text );
00248 }
00249
00250
00251
00252
void KWinDecorationModule::slotSelectionChanged()
00253 {
00254 emit KCModule::changed(
true);
00255 }
00256
00257
static const char*
const border_names[ KDecorationDefines::BordersCount ] =
00258 {
00259 I18N_NOOP(
"Border size: Tiny" ),
00260 I18N_NOOP(
"Border size: Normal" ),
00261 I18N_NOOP(
"Border size: Large" ),
00262 I18N_NOOP(
"Border size: Very Large" ),
00263 I18N_NOOP(
"Border size: Huge" ),
00264 I18N_NOOP(
"Border size: Very Huge" ),
00265 I18N_NOOP(
"Border size: Oversized" )
00266 };
00267
00268
int KWinDecorationModule::borderSizeToIndex( BorderSize size, QValueList< BorderSize > sizes )
00269 {
00270
int pos = 0;
00271
for( QValueList< BorderSize >::ConstIterator it = sizes.begin();
00272 it != sizes.end();
00273 ++it, ++pos )
00274
if( size <= *it )
00275
break;
00276
return pos;
00277 }
00278
00279
KDecorationDefines::BorderSize KWinDecorationModule::indexToBorderSize(
int index,
00280 QValueList< BorderSize > sizes )
00281 {
00282 QValueList< BorderSize >::ConstIterator it = sizes.begin();
00283
for(;
00284 it != sizes.end();
00285 ++it, --index )
00286
if( index == 0 )
00287
break;
00288
return *it;
00289 }
00290
00291
void KWinDecorationModule::slotBorderChanged(
int size )
00292 {
00293
if( lBorder->isHidden())
00294
return;
00295 emit KCModule::changed(
true );
00296 QValueList< BorderSize > sizes;
00297
if( plugins->factory() != NULL )
00298 sizes = plugins->factory()->borderSizes();
00299 assert( sizes.count() >= 2 );
00300 border_size = indexToBorderSize( size, sizes );
00301 lBorder->setText( i18n( border_names[ border_size ] ));
00302 }
00303
00304 QString KWinDecorationModule::decorationName( QString& libName )
00305 {
00306 QString decoName;
00307
00308 QValueList<DecorationInfo>::Iterator it;
00309
for( it = decorations.begin(); it != decorations.end(); ++it )
00310
if ( (*it).libraryName == libName )
00311 {
00312 decoName = (*it).name;
00313
break;
00314 }
00315
00316
return decoName;
00317 }
00318
00319
00320 QString KWinDecorationModule::decorationLibName(
const QString& name )
00321 {
00322 QString libName;
00323
00324
00325
00326 QValueList<DecorationInfo>::Iterator it;
00327
for( it = decorations.begin(); it != decorations.end(); ++it )
00328
if ( (*it).name == name )
00329 {
00330 libName = (*it).libraryName;
00331
break;
00332 }
00333
00334
if (libName.isEmpty())
00335 libName =
"kwin_default";
00336
00337
return libName;
00338 }
00339
00340
00341
00342
00343
void KWinDecorationModule::resetPlugin( KConfig* conf,
const QString& currentDecoName )
00344 {
00345
00346
00347
00348 QString oldName = styleToConfigLib( oldLibraryName );
00349
00350 QString currentName;
00351
if (!currentDecoName.isEmpty())
00352 currentName = decorationLibName( currentDecoName );
00353
else
00354 currentName = currentLibraryName;
00355
00356
if( plugins->loadPlugin( currentName )
00357 && preview->recreateDecoration( plugins ))
00358 preview->enablePreview();
00359
else
00360 preview->disablePreview();
00361 plugins->destroyPreviousPlugin();
00362
00363 checkSupportedBorderSizes();
00364
00365 currentName = styleToConfigLib( currentName );
00366
00367
00368
delete pluginObject;
00369 pluginObject = 0;
00370
00371
00372 KLibLoader* loader = KLibLoader::self();
00373
00374
00375
if (!oldLibraryName.isNull())
00376 loader->unloadLibrary( QFile::encodeName(oldName) );
00377
00378 KLibrary* library = loader->library( QFile::encodeName(currentName) );
00379
if (library != NULL)
00380 {
00381
void* alloc_ptr = library->symbol(
"allocate_config");
00382
00383
if (alloc_ptr != NULL)
00384 {
00385 allocatePlugin = (QObject* (*)(KConfig* conf, QWidget* parent))alloc_ptr;
00386 pluginObject = (QObject*)(allocatePlugin( conf, pluginConfigWidget ));
00387
00388
00389 connect( pluginObject, SIGNAL(changed()),
this, SLOT(slotSelectionChanged()) );
00390 connect(
this, SIGNAL(pluginLoad(KConfig*)), pluginObject, SLOT(load(KConfig*)) );
00391 connect(
this, SIGNAL(pluginSave(KConfig*)), pluginObject, SLOT(save(KConfig*)) );
00392 connect(
this, SIGNAL(pluginDefaults()), pluginObject, SLOT(defaults()) );
00393 pluginSettingsGrp->show();
00394
return;
00395 }
00396 }
00397
00398 pluginSettingsGrp->hide();
00399 }
00400
00401
00402
00403
00404
void KWinDecorationModule::readConfig( KConfig* conf )
00405 {
00406
00407
00408 cbShowToolTips->setChecked( conf->readBoolEntry(
"ShowToolTips",
true ));
00409
00410
00411
00412
00413
00414 oldLibraryName = currentLibraryName;
00415 currentLibraryName = conf->readEntry(
"PluginLib",
00416 ((QPixmap::defaultDepth() > 8) ?
"kwin_keramik" :
"kwin_quartz"));
00417 QString decoName = decorationName( currentLibraryName );
00418
00419
00420
if (decoName.isEmpty())
00421 decoName = i18n(
"KDE 2");
00422
00423
int numDecos = decorationList->count();
00424
for (
int i = 0; i < numDecos; ++i)
00425 {
00426
if (decorationList->text(i) == decoName)
00427 {
00428 decorationList->setCurrentItem(i);
00429
break;
00430 }
00431 }
00432
00433
00434
00435
bool customPositions = conf->readBoolEntry(
"CustomButtonPositions",
false);
00436 cbUseCustomButtonPositions->setChecked( customPositions );
00437 buttonBox->setEnabled( customPositions );
00438
00439 dropSite->buttonsLeft = conf->readEntry(
"ButtonsOnLeft",
"MS");
00440
00441 dropSite->buttonsRight = conf->readEntry(
"ButtonsOnRight",
"HIAX");
00442 dropSite->repaint(
false);
00443
00444 buttonSource->showAllButtons();
00445
00446
00447
unsigned int i;
00448
for(i = 0; i < dropSite->buttonsLeft.length(); i++)
00449 buttonSource->hideButton( dropSite->buttonsLeft[i].latin1() );
00450
for(i = 0; i < dropSite->buttonsRight.length(); i++)
00451 buttonSource->hideButton( dropSite->buttonsRight[i].latin1() );
00452
00453
int bsize = conf->readNumEntry(
"BorderSize", BorderNormal );
00454
if( bsize >=
BorderTiny && bsize < BordersCount )
00455 border_size = static_cast< BorderSize >( bsize );
00456
else
00457 border_size =
BorderNormal;
00458 checkSupportedBorderSizes();
00459
00460 emit KCModule::changed(
false);
00461 }
00462
00463
00464
00465
void KWinDecorationModule::writeConfig( KConfig* conf )
00466 {
00467 QString name = decorationList->currentText();
00468 QString libName = decorationLibName( name );
00469
00470 KConfig kwinConfig(
"kwinrc");
00471 kwinConfig.setGroup(
"Style");
00472
00473
00474 conf->writeEntry(
"PluginLib", libName);
00475 conf->writeEntry(
"CustomButtonPositions", cbUseCustomButtonPositions->isChecked());
00476 conf->writeEntry(
"ShowToolTips", cbShowToolTips->isChecked());
00477
00478
00479
00480 conf->writeEntry(
"ButtonsOnLeft", dropSite->buttonsLeft );
00481 conf->writeEntry(
"ButtonsOnRight", dropSite->buttonsRight );
00482 conf->writeEntry(
"BorderSize", border_size );
00483
00484 oldLibraryName = currentLibraryName;
00485 currentLibraryName = libName;
00486
00487
00488 emit KCModule::changed(
false);
00489 }
00490
00491
00492
void KWinDecorationModule::dcopUpdateClientList()
00493 {
00494
00495
00496 KConfig kwinConfig(
"kwinrc");
00497 kwinConfig.setGroup(
"Style");
00498
00499 readConfig( &kwinConfig );
00500 resetPlugin( &kwinConfig );
00501 }
00502
00503
00504
00505
void KWinDecorationModule::load()
00506 {
00507 KConfig kwinConfig(
"kwinrc");
00508 kwinConfig.setGroup(
"Style");
00509
00510
00511
00512 readConfig( &kwinConfig );
00513 emit pluginLoad( &kwinConfig );
00514 }
00515
00516
00517
void KWinDecorationModule::save()
00518 {
00519 KConfig kwinConfig(
"kwinrc");
00520 kwinConfig.setGroup(
"Style");
00521
00522 writeConfig( &kwinConfig );
00523 emit pluginSave( &kwinConfig );
00524
00525 kwinConfig.sync();
00526 resetKWin();
00527
00528 }
00529
00530
00531
void KWinDecorationModule::defaults()
00532 {
00533
00534 cbUseCustomButtonPositions->setChecked(
false );
00535 buttonBox->setEnabled(
false );
00536 cbShowToolTips->setChecked(
true );
00537
00538
00539
00540
00541
00542 dropSite->buttonsLeft =
"MS";
00543 dropSite->buttonsRight=
"HIAX";
00544 dropSite->repaint(
false);
00545
00546 buttonSource->showAllButtons();
00547 buttonSource->hideButton(
'M');
00548 buttonSource->hideButton(
'S');
00549 buttonSource->hideButton(
'H');
00550 buttonSource->hideButton(
'I');
00551 buttonSource->hideButton(
'A');
00552 buttonSource->hideButton(
'X');
00553
00554 border_size =
BorderNormal;
00555 checkSupportedBorderSizes();
00556
00557
00558 emit pluginDefaults();
00559 }
00560
00561
void KWinDecorationModule::checkSupportedBorderSizes()
00562 {
00563 QValueList< BorderSize > sizes;
00564 slBorder->hide();
00565 lBorder->hide();
00566
if( plugins->factory() != NULL )
00567 sizes = plugins->factory()->borderSizes();
00568
if( sizes.count() < 2 )
00569
return;
00570 slBorder->setRange( 0, sizes.count() - 1 );
00571
int pos = borderSizeToIndex( border_size, sizes );
00572 lBorder->show();
00573 slBorder->show();
00574 slBorder->setValue( pos );
00575 slotBorderChanged( pos );
00576 }
00577
00578 QString KWinDecorationModule::styleToConfigLib( QString& styleLib )
00579 {
00580
if( styleLib.startsWith(
"kwin3_" ))
00581
return "kwin_" + styleLib.mid( 6 ) +
"_config";
00582
else
00583
return styleLib +
"_config";
00584 }
00585
00586 QString KWinDecorationModule::quickHelp()
const
00587
{
00588
return i18n(
"<h1>Window Manager Decoration</h1>"
00589
"<p>This module allows you to choose the window border decorations, "
00590
"as well as titlebar button positions and custom decoration options.</p>"
00591
"To choose a theme for your window decoration click on its name and apply your choice by clicking the \"Apply\" button below."
00592
" If you don't want to apply your choice you can click the \"Reset\" button to discard your changes."
00593
"<p>You can configure each theme in the \"Configure [...]\" tab. There are different options specific for each theme.</p>"
00594
"<p>In \"General Options (if available)\" you can activate the \"Buttons\" tab by checking the \"Use custom titlebar button positions\" box."
00595
" In the \"Buttons\" tab you can change the positions of the buttons to your liking.</p>" );
00596 }
00597
00598
00599
const KAboutData* KWinDecorationModule::aboutData()
const
00600
{
00601 KAboutData* about =
00602
new KAboutData(I18N_NOOP(
"kcmkwindecoration"),
00603 I18N_NOOP(
"Window Decoration Control Module"),
00604 0, 0, KAboutData::License_GPL,
00605 I18N_NOOP(
"(c) 2001 Karol Szwed"));
00606 about->addAuthor(
"Karol Szwed", 0,
"gallium@kde.org");
00607
return about;
00608 }
00609
00610
00611
void KWinDecorationModule::resetKWin()
00612 {
00613
bool ok = kapp->dcopClient()->send(
"kwin",
"KWinInterface",
00614
"reconfigure()", QByteArray());
00615
if (!ok)
00616 kdDebug() <<
"kcmkwindecoration: Could not reconfigure kwin" << endl;
00617 }
00618
00619
#include "kwindecoration.moc"
00620
00621