5a820681aa
svn path=/trunk/KDE/kdebase/workspace/; revision=1118062
355 lines
14 KiB
C++
355 lines
14 KiB
C++
/*
|
|
This is the new kwindecoration kcontrol module
|
|
|
|
Copyright (c) 2001
|
|
Karol Szwed <gallium@kde.org>
|
|
http://gallium.n3.net/
|
|
Copyright 2009, 2010 Martin Gräßlin <kde@martin-graesslin.com>
|
|
|
|
Supports new kwin configuration plugins, and titlebar button position
|
|
modification via dnd interface.
|
|
|
|
Based on original "kwintheme" (Window Borders)
|
|
Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
// own
|
|
#include "kwindecoration.h"
|
|
#include "buttonsconfigdialog.h"
|
|
#include "configdialog.h"
|
|
#include "decorationdelegate.h"
|
|
#include "decorationmodel.h"
|
|
// Qt
|
|
#include <QtDBus/QtDBus>
|
|
#include <QtGui/QSortFilterProxyModel>
|
|
// KDE
|
|
#include <KAboutData>
|
|
#include <KDialog>
|
|
#include <KLocale>
|
|
#include <KNS3/DownloadDialog>
|
|
#include <KPluginFactory>
|
|
|
|
// KCModule plugin interface
|
|
// =========================
|
|
K_PLUGIN_FACTORY(KWinDecoFactory,
|
|
registerPlugin<KWin::KWinDecorationModule>();
|
|
)
|
|
K_EXPORT_PLUGIN(KWinDecoFactory("kcmkwindecoration"))
|
|
|
|
namespace KWin
|
|
{
|
|
|
|
KWinDecorationForm::KWinDecorationForm( QWidget* parent )
|
|
: QWidget( parent )
|
|
{
|
|
setupUi( this );
|
|
}
|
|
|
|
|
|
KWinDecorationModule::KWinDecorationModule(QWidget* parent, const QVariantList &)
|
|
: KCModule(KWinDecoFactory::componentData(), parent)
|
|
, kwinConfig(KSharedConfig::openConfig("kwinrc"))
|
|
, m_showTooltips( false )
|
|
, m_customPositions( false )
|
|
, m_leftButtons( QString() )
|
|
, m_rightButtons( QString() )
|
|
, m_configLoaded( false )
|
|
{
|
|
m_ui = new KWinDecorationForm( this );
|
|
DecorationDelegate* delegate = new DecorationDelegate( this );
|
|
m_ui->decorationList->setItemDelegate( delegate );
|
|
m_ui->configureDecorationButton->setIcon( KIcon( "configure" ) );
|
|
m_ui->configureButtonsButton->setIcon( KIcon( "configure" ) );
|
|
m_ui->ghnsButton->setIcon( KIcon( "get-hot-new-stuff" ) );
|
|
QVBoxLayout* layout = new QVBoxLayout( this );
|
|
layout->addWidget( m_ui );
|
|
|
|
KConfigGroup style( kwinConfig, "Style");
|
|
|
|
// Set up the decoration lists and other UI settings
|
|
m_model = new DecorationModel( kwinConfig, this );
|
|
m_proxyModel = new QSortFilterProxyModel( this );
|
|
m_proxyModel->setSourceModel( m_model );
|
|
m_proxyModel->setFilterCaseSensitivity( Qt::CaseInsensitive );
|
|
m_ui->decorationList->setModel( m_proxyModel );
|
|
|
|
readConfig( style );
|
|
|
|
connect( m_ui->decorationList->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), SLOT(slotSelectionChanged()) );
|
|
connect( m_ui->configureButtonsButton, SIGNAL(clicked(bool)), this, SLOT(slotConfigureButtons()));
|
|
connect( m_ui->ghnsButton, SIGNAL(clicked(bool)), SLOT(slotGHNSClicked()) );
|
|
connect( m_ui->searchEdit, SIGNAL(textChanged(QString)), m_proxyModel, SLOT(setFilterFixedString(QString)));
|
|
connect( delegate, SIGNAL(regeneratePreview(QModelIndex,QSize)),
|
|
m_model, SLOT(regeneratePreview(QModelIndex,QSize)));
|
|
connect( m_ui->configureDecorationButton, SIGNAL(clicked(bool)), SLOT(slotConfigureDecoration()));
|
|
|
|
KAboutData *about =
|
|
new KAboutData(I18N_NOOP("kcmkwindecoration"), 0,
|
|
ki18n("Window Decoration Control Module"),
|
|
0, KLocalizedString(), KAboutData::License_GPL,
|
|
ki18n("(c) 2001 Karol Szwed"));
|
|
about->addAuthor(ki18n("Karol Szwed"), KLocalizedString(), "gallium@kde.org");
|
|
setAboutData(about);
|
|
}
|
|
|
|
|
|
KWinDecorationModule::~KWinDecorationModule()
|
|
{
|
|
}
|
|
|
|
// This is the selection handler setting
|
|
void KWinDecorationModule::slotSelectionChanged()
|
|
{
|
|
emit KCModule::changed(true);
|
|
}
|
|
|
|
// Reads the kwin config settings, and sets all UI controls to those settings
|
|
// Updating the config plugin if required
|
|
void KWinDecorationModule::readConfig( const KConfigGroup & conf )
|
|
{
|
|
m_showTooltips = conf.readEntry("ShowToolTips", true);
|
|
|
|
// Find the corresponding decoration name to that of
|
|
// the current plugin library name
|
|
|
|
QString libraryName = conf.readEntry("PluginLib",
|
|
((QPixmap::defaultDepth() > 8) ? "kwin3_oxygen" : "kwin3_plastik"));
|
|
|
|
if( libraryName.isEmpty() )
|
|
{ // Selected decoration doesn't exist, use the default
|
|
libraryName = ( ( QPixmap::defaultDepth() > 8 ) ? "kwin3_oxygen" : "kwin3_plastik" );
|
|
}
|
|
|
|
const int bsize = conf.readEntry( "BorderSize", (int)BorderNormal );
|
|
BorderSize borderSize = BorderNormal;
|
|
if( bsize >= BorderTiny && bsize < BordersCount )
|
|
borderSize = static_cast< BorderSize >( bsize );
|
|
if( libraryName == "kwin3_aurorae" )
|
|
{
|
|
KConfig auroraeConfig( "auroraerc" );
|
|
KConfigGroup group( &auroraeConfig, "Engine");
|
|
const QString themeName = group.readEntry( "ThemeName", "example-deco" );
|
|
const QModelIndex index = m_proxyModel->mapFromSource( m_model->indexOfAuroraeName( themeName ) );
|
|
if( index.isValid() )
|
|
{
|
|
m_ui->decorationList->setCurrentIndex( index );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const QModelIndex index = m_proxyModel->mapFromSource( m_model->indexOfLibrary( libraryName ) );
|
|
if( index.isValid() )
|
|
{
|
|
m_model->setBorderSize( index, borderSize );
|
|
m_ui->decorationList->setCurrentIndex( index );
|
|
}
|
|
}
|
|
|
|
// Buttons tab
|
|
// ============
|
|
m_customPositions = conf.readEntry("CustomButtonPositions", false);
|
|
// Menu and onAllDesktops buttons are default on LHS
|
|
m_leftButtons = conf.readEntry("ButtonsOnLeft", KDecorationOptions::defaultTitleButtonsLeft());
|
|
// Help, Minimize, Maximize and Close are default on RHS
|
|
m_rightButtons = conf.readEntry("ButtonsOnRight", KDecorationOptions::defaultTitleButtonsRight());
|
|
if( m_configLoaded )
|
|
m_model->changeButtons( m_customPositions, m_leftButtons, m_rightButtons );
|
|
else
|
|
{
|
|
m_configLoaded = true;
|
|
m_model->setButtons( m_customPositions, m_leftButtons, m_rightButtons );
|
|
}
|
|
|
|
emit KCModule::changed(false);
|
|
}
|
|
|
|
|
|
// Writes the selected user configuration to the kwin config file
|
|
void KWinDecorationModule::writeConfig( KConfigGroup & conf )
|
|
{
|
|
const QModelIndex index = m_proxyModel->mapToSource( m_ui->decorationList->currentIndex() );
|
|
const QString libName = m_model->data( index, DecorationModel::LibraryNameRole ).toString();
|
|
|
|
// General settings
|
|
conf.writeEntry("PluginLib", libName);
|
|
conf.writeEntry("CustomButtonPositions", m_customPositions );
|
|
conf.writeEntry("ShowToolTips", m_showTooltips );
|
|
|
|
// Button settings
|
|
conf.writeEntry("ButtonsOnLeft", m_leftButtons );
|
|
conf.writeEntry("ButtonsOnRight", m_rightButtons );
|
|
conf.writeEntry( "BorderSize",
|
|
static_cast<int>( m_model->data( index, DecorationModel::BorderSizeRole ).toInt()));
|
|
|
|
if( m_model->data( index, DecorationModel::TypeRole ).toInt() == DecorationModelData::AuroraeDecoration )
|
|
{
|
|
KConfig auroraeConfig( "auroraerc" );
|
|
KConfigGroup group( &auroraeConfig, "Engine");
|
|
group.writeEntry( "ThemeName", m_model->data( index, DecorationModel::AuroraeNameRole ).toString() );
|
|
group.sync();
|
|
}
|
|
|
|
// We saved, so tell kcmodule that there have been no new user changes made.
|
|
emit KCModule::changed(false);
|
|
}
|
|
|
|
|
|
// Virutal functions required by KCModule
|
|
void KWinDecorationModule::load()
|
|
{
|
|
const KConfigGroup config( kwinConfig, "Style" );
|
|
|
|
// Reset by re-reading the config
|
|
readConfig( config );
|
|
}
|
|
|
|
|
|
void KWinDecorationModule::save()
|
|
{
|
|
KConfigGroup config( kwinConfig, "Style" );
|
|
writeConfig( config );
|
|
config.sync();
|
|
|
|
// Send signal to all kwin instances
|
|
QDBusMessage message =
|
|
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
|
QDBusConnection::sessionBus().send(message);
|
|
}
|
|
|
|
|
|
void KWinDecorationModule::defaults()
|
|
{
|
|
// Set the KDE defaults
|
|
m_customPositions = false;
|
|
m_showTooltips = true;
|
|
const QModelIndex index = m_proxyModel->mapFromSource( m_model->indexOfName( i18n("Oxygen") ) );
|
|
if( index.isValid() )
|
|
m_ui->decorationList->setCurrentIndex( index );
|
|
|
|
m_leftButtons = KDecorationOptions::defaultTitleButtonsLeft();
|
|
m_rightButtons = KDecorationOptions::defaultTitleButtonsRight();
|
|
|
|
m_model->changeButtons( m_customPositions, m_leftButtons, m_rightButtons );
|
|
|
|
emit changed( true );
|
|
}
|
|
|
|
QString KWinDecorationModule::quickHelp() const
|
|
{
|
|
return i18n( "<h1>Window Manager Decoration</h1>"
|
|
"<p>This module allows you to choose the window border decorations, "
|
|
"as well as titlebar button positions and custom decoration options.</p>"
|
|
"To choose a theme for your window decoration click on its name and apply your choice by clicking the \"Apply\" button below."
|
|
" If you do not want to apply your choice you can click the \"Reset\" button to discard your changes."
|
|
"<p>You can configure each theme. There are different options specific for each theme.</p>"
|
|
"<p>On the \"Buttons\" tab check the \"Use custom titlebar button positions\" box "
|
|
"and you can change the positions of the buttons to your liking.</p>" );
|
|
}
|
|
|
|
void KWinDecorationModule::slotConfigureButtons()
|
|
{
|
|
QPointer< KWinDecorationButtonsConfigDialog > configDialog = new KWinDecorationButtonsConfigDialog( m_customPositions, m_showTooltips, m_leftButtons, m_rightButtons, this );
|
|
if( configDialog->exec() == KDialog::Accepted )
|
|
{
|
|
m_customPositions = configDialog->customPositions();
|
|
m_showTooltips = configDialog->showTooltips();
|
|
m_leftButtons = configDialog->buttonsLeft();
|
|
m_rightButtons = configDialog->buttonsRight();
|
|
m_model->changeButtons( m_customPositions, m_leftButtons, m_rightButtons );
|
|
emit changed( true );
|
|
}
|
|
|
|
delete configDialog;
|
|
}
|
|
|
|
void KWinDecorationModule::slotGHNSClicked()
|
|
{
|
|
QPointer<KNS3::DownloadDialog> downloadDialog = new KNS3::DownloadDialog( "aurorae.knsrc", this );
|
|
if( downloadDialog->exec() == KDialog::Accepted )
|
|
{
|
|
if( !downloadDialog->changedEntries().isEmpty() )
|
|
{
|
|
const QModelIndex index = m_proxyModel->mapToSource( m_ui->decorationList->currentIndex() );
|
|
const QString libraryName = m_model->data( index, DecorationModel::LibraryNameRole ).toString();
|
|
bool aurorae = m_model->data( index, DecorationModel::TypeRole ).toInt() == DecorationModelData::AuroraeDecoration;
|
|
const QString auroraeName = m_model->data( index, DecorationModel::AuroraeNameRole ).toString();
|
|
m_model->reload();
|
|
if( aurorae )
|
|
{
|
|
const QModelIndex proxyIndex = m_proxyModel->mapFromSource( m_model->indexOfAuroraeName( auroraeName ) );
|
|
if( proxyIndex.isValid() )
|
|
m_ui->decorationList->setCurrentIndex( proxyIndex );
|
|
}
|
|
else
|
|
{
|
|
const QModelIndex proxyIndex = m_proxyModel->mapFromSource( m_model->indexOfLibrary( libraryName ) );
|
|
if( proxyIndex.isValid() )
|
|
m_ui->decorationList->setCurrentIndex( proxyIndex );
|
|
}
|
|
}
|
|
}
|
|
delete downloadDialog;
|
|
}
|
|
|
|
void KWinDecorationModule::slotConfigureDecoration()
|
|
{
|
|
const QModelIndex index = m_proxyModel->mapToSource( m_ui->decorationList->currentIndex() );
|
|
bool reload = false;
|
|
if( index.data( DecorationModel::TypeRole ).toInt() == DecorationModelData::AuroraeDecoration )
|
|
{
|
|
QPointer< KDialog > dlg = new KDialog( this );
|
|
dlg->setCaption( i18n( "Decoration Options" ) );
|
|
dlg->setButtons( KDialog::Ok | KDialog::Cancel );
|
|
KWinAuroraeConfigForm *form = new KWinAuroraeConfigForm( dlg );
|
|
dlg->setMainWidget( form );
|
|
form->borderSizesCombo->setCurrentIndex( index.data( DecorationModel::BorderSizeRole ).toInt() );
|
|
form->buttonSizesCombo->setCurrentIndex( index.data( DecorationModel::ButtonSizeRole ).toInt() );
|
|
if( dlg->exec() == KDialog::Accepted )
|
|
{
|
|
m_model->setData( index, form->borderSizesCombo->currentIndex(), DecorationModel::BorderSizeRole );
|
|
m_model->setData( index, form->buttonSizesCombo->currentIndex(), DecorationModel::ButtonSizeRole );
|
|
reload = true;
|
|
}
|
|
delete dlg;
|
|
}
|
|
else
|
|
{
|
|
QString name = index.data( DecorationModel::LibraryNameRole ).toString();
|
|
QList< QVariant > borderSizes = index.data( DecorationModel::BorderSizesRole ).toList();
|
|
const KDecorationDefines::BorderSize size =
|
|
static_cast<KDecorationDefines::BorderSize>( index.data( DecorationModel::BorderSizeRole ).toInt() );
|
|
QPointer< KWinDecorationConfigDialog > configDialog =
|
|
new KWinDecorationConfigDialog( name, borderSizes, size, this );
|
|
if( configDialog->exec() == KDialog::Accepted )
|
|
{
|
|
m_model->setData( index, configDialog->borderSize(), DecorationModel::BorderSizeRole );
|
|
reload = true;
|
|
}
|
|
|
|
delete configDialog;
|
|
}
|
|
if( reload )
|
|
{
|
|
// Send signal to all kwin instances
|
|
QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
|
QDBusConnection::sessionBus().send(message);
|
|
}
|
|
}
|
|
|
|
} // namespace KWin
|
|
|
|
#include "kwindecoration.moc"
|