summaryrefslogtreecommitdiffstats
path: root/kwin/kcmkwin/kwindecoration
diff options
context:
space:
mode:
Diffstat (limited to 'kwin/kcmkwin/kwindecoration')
-rw-r--r--kwin/kcmkwin/kwindecoration/Makefile.am18
-rw-r--r--kwin/kcmkwin/kwindecoration/buttons.cpp883
-rw-r--r--kwin/kcmkwin/kwindecoration/buttons.h227
-rw-r--r--kwin/kcmkwin/kwindecoration/kwindecoration.cpp613
-rw-r--r--kwin/kcmkwin/kwindecoration/kwindecoration.desktop231
-rw-r--r--kwin/kcmkwin/kwindecoration/kwindecoration.h135
-rw-r--r--kwin/kcmkwin/kwindecoration/kwindecorationIface.h44
-rw-r--r--kwin/kcmkwin/kwindecoration/pixmaps.h110
-rw-r--r--kwin/kcmkwin/kwindecoration/preview.cpp507
-rw-r--r--kwin/kcmkwin/kwindecoration/preview.h150
10 files changed, 2918 insertions, 0 deletions
diff --git a/kwin/kcmkwin/kwindecoration/Makefile.am b/kwin/kcmkwin/kwindecoration/Makefile.am
new file mode 100644
index 000000000..4d908001f
--- /dev/null
+++ b/kwin/kcmkwin/kwindecoration/Makefile.am
@@ -0,0 +1,18 @@
+INCLUDES = -I$(srcdir)/../../lib $(all_includes)
+
+kde_module_LTLIBRARIES = kcm_kwindecoration.la
+
+kcm_kwindecoration_la_SOURCES = kwindecoration.cpp buttons.cpp kwindecorationIface.skel preview.cpp
+noinst_HEADERS = kwindecoration.h kwindecorationIface.h buttons.h preview.h
+
+kcm_kwindecoration_la_LDFLAGS = \
+ -module -avoid-version $(all_libraries) -no-undefined
+
+kcm_kwindecoration_la_LIBADD = $(LIB_KDEUI) ../../lib/libkdecorations.la
+
+METASOURCES = AUTO
+
+messages:
+ $(XGETTEXT) *.cpp -o $(podir)/kcmkwindecoration.pot
+
+xdg_apps_DATA = kwindecoration.desktop
diff --git a/kwin/kcmkwin/kwindecoration/buttons.cpp b/kwin/kcmkwin/kwindecoration/buttons.cpp
new file mode 100644
index 000000000..888e092e7
--- /dev/null
+++ b/kwin/kcmkwin/kwindecoration/buttons.cpp
@@ -0,0 +1,883 @@
+/*
+ This is the new kwindecoration kcontrol module
+
+ Copyright (c) 2004, Sandro Giessl <[email protected]>
+ Copyright (c) 2001
+ Karol Szwed <[email protected]>
+ http://gallium.n3.net/
+
+ 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) <[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 <qheader.h>
+#include <qpainter.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qstyle.h>
+
+#include <kdebug.h>
+
+#include <kdialog.h>
+#include <klocale.h>
+#include <kglobalsettings.h>
+
+#include <kdecorationfactory.h>
+
+#include "buttons.h"
+#include "pixmaps.h"
+
+
+#define BUTTONDRAGMIMETYPE "application/x-kde_kwindecoration_buttons"
+ButtonDrag::ButtonDrag( Button btn, QWidget* parent, const char* name)
+ : QStoredDrag( BUTTONDRAGMIMETYPE, parent, name)
+{
+ QByteArray data;
+ QDataStream stream(data, IO_WriteOnly);
+ stream << btn.name;
+ stream << btn.icon;
+ stream << btn.type.unicode();
+ stream << (int) btn.duplicate;
+ stream << (int) btn.supported;
+ setEncodedData( data );
+}
+
+
+bool ButtonDrag::canDecode( QDropEvent* e )
+{
+ return e->provides( BUTTONDRAGMIMETYPE );
+}
+
+bool ButtonDrag::decode( QDropEvent* e, Button& btn )
+{
+ QByteArray data = e->data( BUTTONDRAGMIMETYPE );
+ if ( data.size() )
+ {
+ e->accept();
+ QDataStream stream(data, IO_ReadOnly);
+ stream >> btn.name;
+ stream >> btn.icon;
+ ushort type;
+ stream >> type;
+ btn.type = QChar(type);
+ int duplicate;
+ stream >> duplicate;
+ btn.duplicate = duplicate;
+ int supported;
+ stream >> supported;
+ btn.supported = supported;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+Button::Button()
+{
+}
+
+Button::Button(const QString& n, const QBitmap& i, QChar t, bool d, bool s)
+ : name(n),
+ icon(i),
+ type(t),
+ duplicate(d),
+ supported(s)
+{
+}
+
+Button::~Button()
+{
+}
+
+// helper function to deal with the Button's bitmaps more easily...
+QPixmap bitmapPixmap(const QBitmap& bm, const QColor& color)
+{
+ QPixmap pm(bm.size() );
+ pm.setMask(bm);
+ QPainter p(&pm);
+ p.setPen(color);
+ p.drawPixmap(0,0,bm);
+ p.end();
+ return pm;
+}
+
+
+ButtonSource::ButtonSource(QWidget *parent, const char* name)
+ : KListView(parent, name)
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ setResizeMode(QListView::AllColumns);
+ setDragEnabled(true);
+ setAcceptDrops(true);
+ setDropVisualizer(false);
+ setSorting(-1);
+ header()->setClickEnabled(false);
+ header()->hide();
+
+ addColumn(i18n("Buttons") );
+}
+
+ButtonSource::~ButtonSource()
+{
+}
+
+QSize ButtonSource::sizeHint() const
+{
+ // make the sizeHint height a bit smaller than the one of QListView...
+
+ if ( cachedSizeHint().isValid() )
+ return cachedSizeHint();
+
+ constPolish();
+
+ QSize s( header()->sizeHint() );
+
+ if ( verticalScrollBar()->isVisible() )
+ s.setWidth( s.width() + style().pixelMetric(QStyle::PM_ScrollBarExtent) );
+ s += QSize(frameWidth()*2,frameWidth()*2);
+
+ // size hint: 4 lines of text...
+ s.setHeight( s.height() + fontMetrics().lineSpacing()*3 );
+
+ setCachedSizeHint( s );
+
+ return s;
+}
+
+void ButtonSource::hideAllButtons()
+{
+ QListViewItemIterator it(this);
+ while (it.current() ) {
+ it.current()->setVisible(false);
+ ++it;
+ }
+}
+
+void ButtonSource::showAllButtons()
+{
+ QListViewItemIterator it(this);
+ while (it.current() ) {
+ it.current()->setVisible(true);
+ ++it;
+ }
+}
+
+void ButtonSource::showButton( QChar btn )
+{
+ QListViewItemIterator it(this);
+ while (it.current() ) {
+ ButtonSourceItem *item = dynamic_cast<ButtonSourceItem*>(it.current() );
+ if (item && item->button().type == btn) {
+ it.current()->setVisible(true);
+ return;
+ }
+ ++it;
+ }
+}
+
+void ButtonSource::hideButton( QChar btn )
+{
+ QListViewItemIterator it(this);
+ while (it.current() ) {
+ ButtonSourceItem *item = dynamic_cast<ButtonSourceItem*>(it.current() );
+ if (item && item->button().type == btn && !item->button().duplicate) {
+ it.current()->setVisible(false);
+ return;
+ }
+ ++it;
+ }
+}
+
+bool ButtonSource::acceptDrag(QDropEvent* e) const
+{
+ return acceptDrops() && ButtonDrag::canDecode(e);
+}
+
+QDragObject *ButtonSource::dragObject()
+{
+ ButtonSourceItem *i = dynamic_cast<ButtonSourceItem*>(selectedItem() );
+
+ if (i) {
+ ButtonDrag *bd = new ButtonDrag(i->button(), viewport(), "button_drag");
+ bd->setPixmap(bitmapPixmap(i->button().icon, colorGroup().foreground() ));
+ return bd;
+ }
+
+ return 0;
+}
+
+ButtonDropSiteItem::ButtonDropSiteItem(const Button& btn)
+ : m_button(btn)
+{
+}
+
+ButtonDropSiteItem::~ButtonDropSiteItem()
+{
+}
+
+Button ButtonDropSiteItem::button()
+{
+ return m_button;
+}
+
+int ButtonDropSiteItem::width()
+{
+// return m_button.icon.width();
+ return 20;
+}
+
+int ButtonDropSiteItem::height()
+{
+// return m_button.icon.height();
+ return 20;
+}
+
+void ButtonDropSiteItem::draw(QPainter *p, const QColorGroup& cg, QRect r)
+{
+// p->fillRect(r, cg.base() );
+ if (m_button.supported)
+ p->setPen(cg.foreground() );
+ else
+ p->setPen(cg.mid() );
+ QBitmap &i = m_button.icon;
+ p->drawPixmap(r.left()+(r.width()-i.width())/2, r.top()+(r.height()-i.height())/2, i);
+}
+
+
+ButtonDropSite::ButtonDropSite( QWidget* parent, const char* name )
+ : QFrame( parent, name ),
+ m_selected(0)
+{
+ setAcceptDrops( TRUE );
+ setFrameShape( WinPanel );
+ setFrameShadow( Raised );
+ setMinimumHeight( 26 );
+ setMaximumHeight( 26 );
+ setMinimumWidth( 250 ); // Ensure buttons will fit
+}
+
+ButtonDropSite::~ButtonDropSite()
+{
+ clearLeft();
+ clearRight();
+}
+
+void ButtonDropSite::clearLeft()
+{
+ while (!buttonsLeft.isEmpty() ) {
+ ButtonDropSiteItem *item = buttonsLeft.first();
+ if (removeButton(item) ) {
+ emit buttonRemoved(item->button().type);
+ delete item;
+ }
+ }
+}
+
+void ButtonDropSite::clearRight()
+{
+ while (!buttonsRight.isEmpty() ) {
+ ButtonDropSiteItem *item = buttonsRight.first();
+ if (removeButton(item) ) {
+ emit buttonRemoved(item->button().type);
+ delete item;
+ }
+ }
+}
+
+void ButtonDropSite::dragMoveEvent( QDragMoveEvent* e )
+{
+ QPoint p = e->pos();
+ if (leftDropArea().contains(p) || rightDropArea().contains(p) || buttonAt(p) ) {
+ e->accept();
+
+ // 2 pixel wide drop visualizer...
+ QRect r = contentsRect();
+ int x = -1;
+ if (leftDropArea().contains(p) ) {
+ x = leftDropArea().left();
+ } else if (rightDropArea().contains(p) ) {
+ x = rightDropArea().right()+1;
+ } else {
+ ButtonDropSiteItem *item = buttonAt(p);
+ if (item) {
+ if (p.x() < item->rect.left()+item->rect.width()/2 ) {
+ x = item->rect.left();
+ } else {
+ x = item->rect.right()+1;
+ }
+ }
+ }
+ if (x != -1) {
+ QRect tmpRect(x, r.y(), 2, r.height() );
+ if (tmpRect != m_oldDropVisualizer) {
+ cleanDropVisualizer();
+ m_oldDropVisualizer = tmpRect;
+ update(tmpRect);
+ }
+ }
+
+ } else {
+ e->ignore();
+
+ cleanDropVisualizer();
+ }
+}
+
+void ButtonDropSite::cleanDropVisualizer()
+{
+ if (m_oldDropVisualizer.isValid())
+ {
+ QRect rect = m_oldDropVisualizer;
+ m_oldDropVisualizer = QRect(); // rect is invalid
+ update(rect);
+ }
+}
+
+void ButtonDropSite::dragEnterEvent( QDragEnterEvent* e )
+{
+ if ( ButtonDrag::canDecode( e ) )
+ e->accept();
+}
+
+void ButtonDropSite::dragLeaveEvent( QDragLeaveEvent* /* e */ )
+{
+ cleanDropVisualizer();
+}
+
+void ButtonDropSite::dropEvent( QDropEvent* e )
+{
+ cleanDropVisualizer();
+
+ QPoint p = e->pos();
+
+ // collect information where to insert the dropped button
+ ButtonList *buttonList = 0;
+ ButtonList::iterator buttonPosition;
+
+ if (leftDropArea().contains(p) ) {
+ buttonList = &buttonsLeft;
+ buttonPosition = buttonsLeft.end();
+ } else if (rightDropArea().contains(p) ) {
+ buttonList = &buttonsRight;
+ buttonPosition = buttonsRight.begin();
+ } else {
+ ButtonDropSiteItem *aboveItem = buttonAt(p);
+ if (!aboveItem)
+ return; // invalid drop. hasn't occured _over_ a button (or left/right dropArea), return...
+
+ ButtonList::iterator it;
+ if (!getItemIterator(aboveItem, buttonList, it) ) {
+ // didn't find the aboveItem. unlikely to happen since buttonAt() already seems to have found
+ // something valid. anyway...
+ return;
+ }
+
+ // got the list and the aboveItem position. now determine if the item should be inserted
+ // before aboveItem or after aboveItem.
+ QRect aboveItemRect = aboveItem->rect;
+ if (!aboveItemRect.isValid() )
+ return;
+
+ if (p.x() < aboveItemRect.left()+aboveItemRect.width()/2 ) {
+ // insert before the item
+ buttonPosition = it;
+ } else {
+ if (it != buttonList->end() )
+ buttonPosition = ++it;
+ else
+ buttonPosition = it; // already at the end(), can't increment the iterator!
+ }
+ }
+
+ // know where to insert the button. now see if we can use an existing item (drag within the widget = move)
+ // orneed to create a new one
+ ButtonDropSiteItem *buttonItem = 0;
+ if (e->source() == this && m_selected) {
+ ButtonList *oldList = 0;
+ ButtonList::iterator oldPos;
+ if (getItemIterator(m_selected, oldList, oldPos) ) {
+ if (oldPos == buttonPosition)
+ return; // button didn't change its position during the drag...
+
+ oldList->remove(oldPos);
+ buttonItem = m_selected;
+ } else {
+ return; // m_selected not found, return...
+ }
+ } else {
+ // create new button from the drop object...
+ Button btn;
+ if (ButtonDrag::decode(e, btn) ) {
+ buttonItem = new ButtonDropSiteItem(btn);
+ } else {
+ return; // something has gone wrong while we were trying to decode the drop event
+ }
+ }
+
+ // now the item can actually be inserted into the list! :)
+ (*buttonList).insert(buttonPosition, buttonItem);
+ emit buttonAdded(buttonItem->button().type);
+ emit changed();
+ recalcItemGeometry();
+ update();
+}
+
+bool ButtonDropSite::getItemIterator(ButtonDropSiteItem *item, ButtonList* &list, ButtonList::iterator &iterator)
+{
+ if (!item)
+ return false;
+
+ ButtonList::iterator it = buttonsLeft.find(item); // try the left list first...
+ if (it == buttonsLeft.end() ) {
+ it = buttonsRight.find(item); // try the right list...
+ if (it == buttonsRight.end() ) {
+ return false; // item hasn't been found in one of the list, return...
+ } else {
+ list = &buttonsRight;
+ iterator = it;
+ }
+ } else {
+ list = &buttonsLeft;
+ iterator = it;
+ }
+
+ return true;
+}
+
+QRect ButtonDropSite::leftDropArea()
+{
+ // return a 10 pixel drop area...
+ QRect r = contentsRect();
+
+ int leftButtonsWidth = calcButtonListWidth(buttonsLeft);
+ return QRect(r.left()+leftButtonsWidth, r.top(), 10, r.height() );
+}
+
+QRect ButtonDropSite::rightDropArea()
+{
+ // return a 10 pixel drop area...
+ QRect r = contentsRect();
+
+ int rightButtonsWidth = calcButtonListWidth(buttonsRight);
+ return QRect(r.right()-rightButtonsWidth-10, r.top(), 10, r.height() );
+}
+
+void ButtonDropSite::mousePressEvent( QMouseEvent* e )
+{
+ // TODO: only start the real drag after some drag distance
+ m_selected = buttonAt(e->pos() );
+ if (m_selected) {
+ ButtonDrag *bd = new ButtonDrag(m_selected->button(), this);
+ bd->setPixmap(bitmapPixmap(m_selected->button().icon, colorGroup().foreground() ) );
+ bd->dragMove();
+ }
+}
+
+void ButtonDropSite::resizeEvent(QResizeEvent*)
+{
+ recalcItemGeometry();
+}
+
+void ButtonDropSite::recalcItemGeometry()
+{
+ QRect r = contentsRect();
+
+ // update the geometry of the items in the left button list
+ int offset = r.left();
+ for (ButtonList::const_iterator it = buttonsLeft.begin(); it != buttonsLeft.end(); ++it) {
+ int w = (*it)->width();
+ (*it)->rect = QRect(offset, r.top(), w, (*it)->height() );
+ offset += w;
+ }
+
+ // the right button list...
+ offset = r.right() - calcButtonListWidth(buttonsRight);
+ for (ButtonList::const_iterator it = buttonsRight.begin(); it != buttonsRight.end(); ++it) {
+ int w = (*it)->width();
+ (*it)->rect = QRect(offset, r.top(), w, (*it)->height() );
+ offset += w;
+ }
+}
+
+ButtonDropSiteItem *ButtonDropSite::buttonAt(QPoint p) {
+ // try to find the item in the left button list
+ for (ButtonList::const_iterator it = buttonsLeft.begin(); it != buttonsLeft.end(); ++it) {
+ if ( (*it)->rect.contains(p) ) {
+ return *it;
+ }
+ }
+
+ // try to find the item in the right button list
+ for (ButtonList::const_iterator it = buttonsRight.begin(); it != buttonsRight.end(); ++it) {
+ if ( (*it)->rect.contains(p) ) {
+ return *it;
+ }
+ }
+
+ return 0;
+}
+
+bool ButtonDropSite::removeButton(ButtonDropSiteItem *item) {
+ if (!item)
+ return false;
+
+ // try to remove the item from the left button list
+ if (buttonsLeft.remove(item) >= 1) {
+ return true;
+ }
+
+ // try to remove the item from the right button list
+ if (buttonsRight.remove(item) >= 1) {
+ return true;
+ }
+
+ return false;
+}
+
+int ButtonDropSite::calcButtonListWidth(const ButtonList& btns)
+{
+ int w = 0;
+ for (ButtonList::const_iterator it = btns.begin(); it != btns.end(); ++it) {
+ w += (*it)->width();
+ }
+
+ return w;
+}
+
+bool ButtonDropSite::removeSelectedButton()
+{
+ bool succ = removeButton(m_selected);
+ if (succ) {
+ emit buttonRemoved(m_selected->button().type);
+ emit changed();
+ delete m_selected;
+ m_selected = 0;
+ recalcItemGeometry();
+ update(); // repaint...
+ }
+
+ return succ;
+}
+
+void ButtonDropSite::drawButtonList(QPainter *p, const ButtonList& btns, int offset)
+{
+ for (ButtonList::const_iterator it = btns.begin(); it != btns.end(); ++it) {
+ QRect itemRect = (*it)->rect;
+ if (itemRect.isValid() ) {
+ (*it)->draw(p, colorGroup(), itemRect);
+ }
+ offset += (*it)->width();
+ }
+}
+
+void ButtonDropSite::drawContents( QPainter* p )
+{
+ int leftoffset = calcButtonListWidth( buttonsLeft );
+ int rightoffset = calcButtonListWidth( buttonsRight );
+ int offset = 3;
+
+ QRect r = contentsRect();
+
+ // Shrink by 1
+ r.moveBy(1 + leftoffset, 1);
+ r.setWidth( r.width() - 2 - leftoffset - rightoffset );
+ r.setHeight( r.height() - 2 );
+
+ drawButtonList( p, buttonsLeft, offset );
+
+ QColor c1( 0x0A, 0x5F, 0x89 ); // KDE 2 titlebar default colour
+ p->fillRect( r, c1 );
+ p->setPen( Qt::white );
+ p->setFont( QFont( KGlobalSettings::generalFont().family(), 12, QFont::Bold) );
+ p->drawText( r, AlignLeft | AlignVCenter, i18n("KDE") );
+
+ offset = geometry().width() - 3 - rightoffset;
+ drawButtonList( p, buttonsRight, offset );
+
+ if (m_oldDropVisualizer.isValid() )
+ {
+ p->fillRect(m_oldDropVisualizer, Dense4Pattern);
+ }
+}
+
+ButtonSourceItem::ButtonSourceItem(QListView * parent, const Button& btn)
+ : QListViewItem(parent),
+ m_button(btn),
+ m_dirty(true)
+{
+ setButton(btn);
+}
+
+ButtonSourceItem::~ButtonSourceItem()
+{
+}
+
+void ButtonSourceItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align)
+{
+ // we need the color group cg, so to the work here, not in setButton...
+ if (m_dirty) {
+ if (m_button.supported) {
+ setPixmap(0, bitmapPixmap(m_button.icon, cg.foreground() ) );
+ } else {
+ setPixmap(0, bitmapPixmap(m_button.icon, cg.mid() ) );
+ }
+ m_dirty = false;
+ }
+
+ if (m_button.supported) {
+ QListViewItem::paintCell(p,cg,column,width,align);
+ } else {
+ // grey out unsupported buttons
+ QColorGroup cg2 = cg;
+ cg2.setColor(QColorGroup::Text, cg.mid() );
+ QListViewItem::paintCell(p,cg2,column,width,align);
+ }
+}
+
+void ButtonSourceItem::setButton(const Button& btn)
+{
+ m_button = btn;
+ m_dirty = true; // update the pixmap when in paintCell()...
+ if (btn.supported) {
+ setText(0, btn.name);
+ } else {
+ setText(0, i18n("%1 (unavailable)").arg(btn.name) );
+ }
+}
+
+Button ButtonSourceItem::button() const
+{
+ return m_button;
+}
+
+
+ButtonPositionWidget::ButtonPositionWidget(QWidget *parent, const char* name)
+ : QWidget(parent,name),
+ m_factory(0)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() );
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
+
+ QLabel* label = new QLabel( this );
+ m_dropSite = new ButtonDropSite( this );
+ label->setAlignment( int( QLabel::WordBreak ) );
+ label->setText( i18n( "To add or remove titlebar buttons, simply <i>drag</i> items "
+ "between the available item list and the titlebar preview. Similarly, "
+ "drag items within the titlebar preview to re-position them.") );
+ m_buttonSource = new ButtonSource(this, "button_source");
+
+ layout->addWidget(label);
+ layout->addWidget(m_dropSite);
+ layout->addWidget(m_buttonSource);
+
+ connect( m_dropSite, SIGNAL(buttonAdded(QChar)), m_buttonSource, SLOT(hideButton(QChar)) );
+ connect( m_dropSite, SIGNAL(buttonRemoved(QChar)), m_buttonSource, SLOT(showButton(QChar)) );
+ connect( m_buttonSource, SIGNAL(dropped(QDropEvent*, QListViewItem*)), m_dropSite, SLOT(removeSelectedButton()) );
+
+ connect( m_dropSite, SIGNAL(changed()), SIGNAL(changed()) );
+
+ // insert all possible buttons into the source (backwards to keep the preferred order...)
+ bool dummy;
+ new ButtonSourceItem(m_buttonSource, getButton('R', dummy) );
+ new ButtonSourceItem(m_buttonSource, getButton('L', dummy) );
+ new ButtonSourceItem(m_buttonSource, getButton('B', dummy) );
+ new ButtonSourceItem(m_buttonSource, getButton('F', dummy) );
+ new ButtonSourceItem(m_buttonSource, getButton('X', dummy) );
+ new ButtonSourceItem(m_buttonSource, getButton('A', dummy) );
+ new ButtonSourceItem(m_buttonSource, getButton('I', dummy) );
+ new ButtonSourceItem(m_buttonSource, getButton('H', dummy) );
+ new ButtonSourceItem(m_buttonSource, getButton('S', dummy) );
+ new ButtonSourceItem(m_buttonSource, getButton('M', dummy) );
+ new ButtonSourceItem(m_buttonSource, getButton('_', dummy) );
+}
+
+ButtonPositionWidget::~ButtonPositionWidget()
+{
+}
+
+void ButtonPositionWidget::setDecorationFactory(KDecorationFactory *factory)
+{
+ if (!factory)
+ return;
+
+ m_factory = factory;
+
+ // get the list of supported buttons
+ if (m_factory->supports(KDecorationDefines::AbilityAnnounceButtons) ) {
+ QString supportedButtons;
+
+ if (m_factory->supports(KDecorationDefines::AbilityButtonMenu) )
+ supportedButtons.append('M');
+ if (m_factory->supports(KDecorationDefines::AbilityButtonOnAllDesktops) )
+ supportedButtons.append('S');
+ if (m_factory->supports(KDecorationDefines::AbilityButtonSpacer) )
+ supportedButtons.append('_');
+ if (m_factory->supports(KDecorationDefines::AbilityButtonHelp) )
+ supportedButtons.append('H');
+ if (m_factory->supports(KDecorationDefines::AbilityButtonMinimize) )
+ supportedButtons.append('I');
+ if (m_factory->supports(KDecorationDefines::AbilityButtonMaximize) )
+ supportedButtons.append('A');
+ if (m_factory->supports(KDecorationDefines::AbilityButtonClose) )
+ supportedButtons.append('X');
+ if (m_factory->supports(KDecorationDefines::AbilityButtonAboveOthers) )
+ supportedButtons.append('F');
+ if (m_factory->supports(KDecorationDefines::AbilityButtonBelowOthers) )
+ supportedButtons.append('B');
+ if (m_factory->supports(KDecorationDefines::AbilityButtonShade) )
+ supportedButtons.append('L');
+ if (m_factory->supports(KDecorationDefines::AbilityButtonResize) )
+ supportedButtons.append('R');
+
+ m_supportedButtons = supportedButtons;
+ } else {
+ // enable only buttons available before AbilityButton* introduction
+ m_supportedButtons = "MSHIAX_";
+ }
+
+ // update the button lists...
+ // 1. set status on the source items...
+ QListViewItemIterator it(m_buttonSource);
+ while (it.current() ) {
+ ButtonSourceItem *i = dynamic_cast<ButtonSourceItem*>(it.current() );
+ if (i) {
+ Button b = i->button();
+ b.supported = m_supportedButtons.contains(b.type);
+ i->setButton(b);
+ }
+ ++it;
+ }
+ // 2. rebuild the drop site items...
+ setButtonsLeft(buttonsLeft() );
+ setButtonsRight(buttonsRight() );
+}
+
+Button ButtonPositionWidget::getButton(QChar type, bool& success) {
+ success = true;
+
+ if (type == 'R') {
+ QBitmap bmp(resize_width, resize_height, resize_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("Resize"), bmp, 'R', false, m_supportedButtons.contains('R') );
+ } else if (type == 'L') {
+ QBitmap bmp(shade_width, shade_height, shade_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("Shade"), bmp, 'L', false, m_supportedButtons.contains('L') );
+ } else if (type == 'B') {
+ QBitmap bmp(keepbelowothers_width, keepbelowothers_height, keepbelowothers_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("Keep Below Others"), bmp, 'B', false, m_supportedButtons.contains('B') );
+ } else if (type == 'F') {
+ QBitmap bmp(keepaboveothers_width, keepaboveothers_height, keepaboveothers_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("Keep Above Others"), bmp, 'F', false, m_supportedButtons.contains('F') );
+ } else if (type == 'X') {
+ QBitmap bmp(close_width, close_height, close_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("Close"), bmp, 'X', false, m_supportedButtons.contains('X') );
+ } else if (type == 'A') {
+ QBitmap bmp(maximize_width, maximize_height, maximize_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("Maximize"), bmp, 'A', false, m_supportedButtons.contains('A') );
+ } else if (type == 'I') {
+ QBitmap bmp(minimize_width, minimize_height, minimize_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("Minimize"), bmp, 'I', false, m_supportedButtons.contains('I') );
+ } else if (type == 'H') {
+ QBitmap bmp(help_width, help_height, help_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("Help"), bmp, 'H', false, m_supportedButtons.contains('H') );
+ } else if (type == 'S') {
+ QBitmap bmp(onalldesktops_width, onalldesktops_height, onalldesktops_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("On All Desktops"), bmp, 'S', false, m_supportedButtons.contains('S') );
+ } else if (type == 'M') {
+ QBitmap bmp(menu_width, menu_height, menu_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("Menu"), bmp, 'M', false, m_supportedButtons.contains('M') );
+ } else if (type == '_') {
+ QBitmap bmp(spacer_width, spacer_height, spacer_bits, true);
+ bmp.setMask(bmp);
+ return Button(i18n("--- spacer ---"), bmp, '_', true, m_supportedButtons.contains('_') );
+ } else {
+ success = false;
+ return Button();
+ }
+}
+
+QString ButtonPositionWidget::buttonsLeft() const
+{
+ ButtonList btns = m_dropSite->buttonsLeft;
+ QString btnString = "";
+ for (ButtonList::const_iterator it = btns.begin(); it != btns.end(); ++it) {
+ btnString.append( (*it)->button().type );
+ }
+ return btnString;
+}
+
+QString ButtonPositionWidget::buttonsRight() const
+{
+ ButtonList btns = m_dropSite->buttonsRight;
+ QString btnString = "";
+ for (ButtonList::const_iterator it = btns.begin(); it != btns.end(); ++it) {
+ btnString.append( (*it)->button().type );
+ }
+ return btnString;
+}
+
+void ButtonPositionWidget::setButtonsLeft(const QString &buttons)
+{
+ // to keep the button lists consistent, first remove all left buttons, then add buttons again...
+ m_dropSite->clearLeft();
+
+ for (uint i = 0; i < buttons.length(); ++i) {
+ bool succ = false;
+ Button btn = getButton(buttons[i], succ);
+ if (succ) {
+ m_dropSite->buttonsLeft.append(new ButtonDropSiteItem(btn) );
+ m_buttonSource->hideButton(btn.type);
+ }
+ }
+ m_dropSite->recalcItemGeometry();
+ m_dropSite->update();
+}
+
+void ButtonPositionWidget::setButtonsRight(const QString &buttons)
+{
+ // to keep the button lists consistent, first remove all left buttons, then add buttons again...
+ m_dropSite->clearRight();
+
+ for (uint i = 0; i < buttons.length(); ++i) {
+ bool succ = false;
+ Button btn = getButton(buttons[i], succ);
+ if (succ) {
+ m_dropSite->buttonsRight.append(new ButtonDropSiteItem(btn) );
+ m_buttonSource->hideButton(btn.type);
+ }
+ }
+ m_dropSite->recalcItemGeometry();
+ m_dropSite->update();
+}
+
+#include "buttons.moc"
+// vim: ts=4
+// kate: space-indent off; tab-width 4;
diff --git a/kwin/kcmkwin/kwindecoration/buttons.h b/kwin/kcmkwin/kwindecoration/buttons.h
new file mode 100644
index 000000000..a3db6266e
--- /dev/null
+++ b/kwin/kcmkwin/kwindecoration/buttons.h
@@ -0,0 +1,227 @@
+/*
+ This is the new kwindecoration kcontrol module
+
+ Copyright (c) 2004, Sandro Giessl <[email protected]>
+ Copyright (c) 2001
+ Karol Szwed <[email protected]>
+ http://gallium.n3.net/
+
+ 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) <[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 __BUTTONS_H_
+#define __BUTTONS_H_
+
+#include <qbitmap.h>
+#include <qevent.h>
+#include <qdragobject.h>
+#include <qlistbox.h>
+
+#include <klistview.h>
+
+class KDecorationFactory;
+
+/**
+ * This class holds the button data.
+ */
+class Button
+{
+ public:
+ Button();
+ Button(const QString& name, const QBitmap& icon, QChar type, bool duplicate, bool supported);
+ virtual ~Button();
+
+ QString name;
+ QBitmap icon;
+ QChar type;
+ bool duplicate;
+ bool supported;
+};
+
+class ButtonDrag : public QStoredDrag
+{
+ public:
+ ButtonDrag( Button btn, QWidget* parent, const char* name=0 );
+ ~ButtonDrag() {};
+
+ static bool canDecode( QDropEvent* e );
+ static bool decode( QDropEvent* e, Button& btn );
+};
+
+/**
+ * This is plugged into ButtonDropSite
+ */
+class ButtonDropSiteItem
+{
+ public:
+ ButtonDropSiteItem(const Button& btn);
+ ~ButtonDropSiteItem();
+
+ Button button();
+
+ QRect rect;
+ int width();
+ int height();
+
+ void draw(QPainter *p, const QColorGroup& cg, QRect rect);
+
+ private:
+ Button m_button;
+};
+
+/**
+ * This is plugged into ButtonSource
+ */
+class ButtonSourceItem : public QListViewItem
+{
+ public:
+ ButtonSourceItem(QListView * parent, const Button& btn);
+ virtual ~ButtonSourceItem();
+
+ void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align);
+
+ void setButton(const Button& btn);
+ Button button() const;
+ private:
+ Button m_button;
+ bool m_dirty;
+};
+
+/**
+ * Implements the button drag source list view
+ */
+class ButtonSource : public KListView
+{
+ Q_OBJECT
+
+ public:
+ ButtonSource(QWidget *parent = 0, const char* name = 0);
+ virtual ~ButtonSource();
+
+ QSize sizeHint() const;
+
+ void hideAllButtons();
+ void showAllButtons();
+
+ public slots:
+ void hideButton(QChar btn);
+ void showButton(QChar btn);
+
+ protected:
+ bool acceptDrag(QDropEvent* e) const;
+ virtual QDragObject *dragObject();
+};
+
+typedef QValueList<ButtonDropSiteItem*> ButtonList;
+
+/**
+ * This class renders and handles the demo titlebar dropsite
+ */
+class ButtonDropSite: public QFrame
+{
+ Q_OBJECT
+
+ public:
+ ButtonDropSite( QWidget* parent=0, const char* name=0 );
+ ~ButtonDropSite();
+
+ // Allow external classes access our buttons - ensure buttons are
+ // not duplicated however.
+ ButtonList buttonsLeft;
+ ButtonList buttonsRight;
+ void clearLeft();
+ void clearRight();
+
+ signals:
+ void buttonAdded(QChar btn);
+ void buttonRemoved(QChar btn);
+ void changed();
+
+ public slots:
+ bool removeSelectedButton(); ///< This slot is called after we drop on the item listbox...
+ void recalcItemGeometry(); ///< Call this whenever the item list changes... updates the items' rect property
+
+ protected:
+ void resizeEvent(QResizeEvent*);
+ void dragEnterEvent( QDragEnterEvent* e );
+ void dragMoveEvent( QDragMoveEvent* e );
+ void dragLeaveEvent( QDragLeaveEvent* e );
+ void dropEvent( QDropEvent* e );
+ void mousePressEvent( QMouseEvent* e ); ///< Starts dragging a button...
+
+ void drawContents( QPainter* p );
+ ButtonDropSiteItem *buttonAt(QPoint p);
+ bool removeButton(ButtonDropSiteItem *item);
+ int calcButtonListWidth(const ButtonList& buttons); ///< Computes the total space the buttons will take in the titlebar
+ void drawButtonList(QPainter *p, const ButtonList& buttons, int offset);
+
+ QRect leftDropArea();
+ QRect rightDropArea();
+
+ private:
+ /**
+ * Try to find the item. If found, set its list and iterator and return true, else return false
+ */
+ bool getItemIterator(ButtonDropSiteItem *item, ButtonList* &list, ButtonList::iterator &iterator);
+
+ void cleanDropVisualizer();
+ QRect m_oldDropVisualizer;
+
+ ButtonDropSiteItem *m_selected;
+};
+
+class ButtonPositionWidget : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ ButtonPositionWidget(QWidget *parent = 0, const char* name = 0);
+ ~ButtonPositionWidget();
+
+ /**
+ * set the factory, so the class e.g. knows which buttons are supported by the client
+ */
+ void setDecorationFactory(KDecorationFactory *factory);
+
+ QString buttonsLeft() const;
+ QString buttonsRight() const;
+ void setButtonsLeft(const QString &buttons);
+ void setButtonsRight(const QString &buttons);
+
+ signals:
+ void changed();
+
+ private:
+ void clearButtonList(const ButtonList& btns);
+ Button getButton(QChar type, bool& success);
+
+ ButtonDropSite* m_dropSite;
+ ButtonSource *m_buttonSource;
+
+ KDecorationFactory *m_factory;
+ QString m_supportedButtons;
+};
+
+
+#endif
+// vim: ts=4
+// kate: space-indent off; tab-width 4;
diff --git a/kwin/kcmkwin/kwindecoration/kwindecoration.cpp b/kwin/kcmkwin/kwindecoration/kwindecoration.cpp
new file mode 100644
index 000000000..7435781bc
--- /dev/null
+++ b/kwin/kcmkwin/kwindecoration/kwindecoration.cpp
@@ -0,0 +1,613 @@
+/*
+ This is the new kwindecoration kcontrol module
+
+ Copyright (c) 2001
+ Karol Szwed <[email protected]>
+ http://gallium.n3.net/
+
+ 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) <[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 <assert.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <qlayout.h>
+#include <qwhatsthis.h>
+#include <qgroupbox.h>
+#include <qcheckbox.h>
+#include <qtabwidget.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qfile.h>
+#include <qslider.h>
+
+#include <kapplication.h>
+#include <kcombobox.h>
+#include <kdebug.h>
+#include <kdesktopfile.h>
+#include <kstandarddirs.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kdialog.h>
+#include <kgenericfactory.h>
+#include <kaboutdata.h>
+#include <dcopclient.h>
+
+#include "kwindecoration.h"
+#include "preview.h"
+#include <kdecoration_plugins_p.h>
+#include <kdecorationfactory.h>
+
+// KCModule plugin interface
+// =========================
+typedef KGenericFactory<KWinDecorationModule, QWidget> KWinDecoFactory;
+K_EXPORT_COMPONENT_FACTORY( kcm_kwindecoration, KWinDecoFactory("kcmkwindecoration") )
+
+KWinDecorationModule::KWinDecorationModule(QWidget* parent, const char* name, const QStringList &)
+ : DCOPObject("KWinClientDecoration"),
+ KCModule(KWinDecoFactory::instance(), parent, name),
+ kwinConfig("kwinrc"),
+ pluginObject(0)
+{
+ kwinConfig.setGroup("Style");
+ plugins = new KDecorationPreviewPlugins( &kwinConfig );
+
+ QVBoxLayout* layout = new QVBoxLayout(this, 0, KDialog::spacingHint());
+
+// Save this for later...
+// cbUseMiniWindows = new QCheckBox( i18n( "Render mini &titlebars for all windows"), checkGroup );
+// QWhatsThis::add( cbUseMiniWindows, i18n( "Note that this option is not available on all styles yet!" ) );
+
+ tabWidget = new QTabWidget( this );
+ layout->addWidget( tabWidget );
+
+ // Page 1 (General Options)
+ QWidget *pluginPage = new QWidget( tabWidget );
+
+ QVBoxLayout* pluginLayout = new QVBoxLayout(pluginPage, KDialog::marginHint(), KDialog::spacingHint());
+
+ // decoration chooser
+ decorationList = new KComboBox( pluginPage );
+ QString whatsThis = i18n("Select the window decoration. This is the look and feel of both "
+ "the window borders and the window handle.");
+ QWhatsThis::add(decorationList, whatsThis);
+ pluginLayout->addWidget(decorationList);
+
+ QGroupBox *pluginSettingsGrp = new QGroupBox( i18n("Decoration Options"), pluginPage );
+ pluginSettingsGrp->setColumnLayout( 0, Vertical );
+ pluginSettingsGrp->setFlat( true );
+ pluginSettingsGrp->layout()->setMargin( 0 );
+ pluginSettingsGrp->layout()->setSpacing( KDialog::spacingHint() );
+ pluginLayout->addWidget( pluginSettingsGrp );
+
+ pluginLayout->addStretch();
+
+ // Border size chooser
+ lBorder = new QLabel (i18n("B&order size:"), pluginSettingsGrp);
+ cBorder = new QComboBox(pluginSettingsGrp);
+ lBorder->setBuddy(cBorder);
+ QWhatsThis::add( cBorder, i18n( "Use this combobox to change the border size of the decoration." ));
+ lBorder->hide();
+ cBorder->hide();
+ QHBoxLayout *borderSizeLayout = new QHBoxLayout(pluginSettingsGrp->layout() );
+ borderSizeLayout->addWidget(lBorder);
+ borderSizeLayout->addWidget(cBorder);
+ borderSizeLayout->addStretch();
+
+ pluginConfigWidget = new QVBox(pluginSettingsGrp);
+ pluginSettingsGrp->layout()->add( pluginConfigWidget );
+
+ // Page 2 (Button Selector)
+ QWidget* buttonPage = new QWidget( tabWidget );
+ QVBoxLayout* buttonLayout = new QVBoxLayout(buttonPage, KDialog::marginHint(), KDialog::spacingHint());
+
+ cbShowToolTips = new QCheckBox(
+ i18n("&Show window button tooltips"), buttonPage );
+ QWhatsThis::add( cbShowToolTips,
+ i18n( "Enabling this checkbox will show window button tooltips. "
+ "If this checkbox is off, no window button tooltips will be shown."));
+
+ cbUseCustomButtonPositions = new QCheckBox(
+ i18n("Use custom titlebar button &positions"), buttonPage );
+ QWhatsThis::add( cbUseCustomButtonPositions,
+ i18n( "The appropriate settings can be found in the \"Buttons\" Tab; "
+ "please note that this option is not available on all styles yet." ) );
+
+ buttonLayout->addWidget( cbShowToolTips );
+ buttonLayout->addWidget( cbUseCustomButtonPositions );
+
+ // Add nifty dnd button modification widgets
+ buttonPositionWidget = new ButtonPositionWidget(buttonPage, "button_position_widget");
+ buttonPositionWidget->setDecorationFactory(plugins->factory() );
+ QHBoxLayout* buttonControlLayout = new QHBoxLayout(buttonLayout);
+ buttonControlLayout->addSpacing(20);
+ buttonControlLayout->addWidget(buttonPositionWidget);
+// buttonLayout->addStretch();
+
+ // preview
+ QVBoxLayout* previewLayout = new QVBoxLayout(layout, KDialog::spacingHint() );
+ previewLayout->setMargin( KDialog::marginHint() );
+
+ preview = new KDecorationPreview( this );
+ previewLayout->addWidget(preview);
+
+ preview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ tabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
+
+ // Load all installed decorations into memory
+ // Set up the decoration lists and other UI settings
+ findDecorations();
+ createDecorationList();
+ readConfig( &kwinConfig );
+ resetPlugin( &kwinConfig );
+
+ tabWidget->insertTab( pluginPage, i18n("&Window Decoration") );
+ tabWidget->insertTab( buttonPage, i18n("&Buttons") );
+
+ connect( buttonPositionWidget, SIGNAL(changed()), this, SLOT(slotButtonsChanged()) ); // update preview etc.
+ connect( buttonPositionWidget, SIGNAL(changed()), this, SLOT(slotSelectionChanged()) ); // emit changed()...
+ connect( decorationList, SIGNAL(activated(const QString&)), SLOT(slotSelectionChanged()) );
+ connect( decorationList, SIGNAL(activated(const QString&)),
+ SLOT(slotChangeDecoration(const QString&)) );
+ connect( cbUseCustomButtonPositions, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
+ connect(cbUseCustomButtonPositions, SIGNAL(toggled(bool)), buttonPositionWidget, SLOT(setEnabled(bool)));
+ connect(cbUseCustomButtonPositions, SIGNAL(toggled(bool)), this, SLOT(slotButtonsChanged()) );
+ connect( cbShowToolTips, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
+ connect( cBorder, SIGNAL( activated( int )), SLOT( slotBorderChanged( int )));
+// connect( cbUseMiniWindows, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
+
+ // Allow kwin dcop signal to update our selection list
+ connectDCOPSignal("kwin", 0, "dcopResetAllClients()", "dcopUpdateClientList()", false);
+
+ KAboutData *about =
+ new KAboutData(I18N_NOOP("kcmkwindecoration"),
+ I18N_NOOP("Window Decoration Control Module"),
+ 0, 0, KAboutData::License_GPL,
+ I18N_NOOP("(c) 2001 Karol Szwed"));
+ about->addAuthor("Karol Szwed", 0, "[email protected]");
+ setAboutData(about);
+}
+
+
+KWinDecorationModule::~KWinDecorationModule()
+{
+ delete preview; // needs to be destroyed before plugins
+ delete plugins;
+}
+
+
+// Find all theme desktop files in all 'data' dirs owned by kwin.
+// And insert these into a DecorationInfo structure
+void KWinDecorationModule::findDecorations()
+{
+ QStringList dirList = KGlobal::dirs()->findDirs("data", "kwin");
+ QStringList::ConstIterator it;
+
+ for (it = dirList.begin(); it != dirList.end(); it++)
+ {
+ QDir d(*it);
+ if (d.exists())
+ for (QFileInfoListIterator it(*d.entryInfoList()); it.current(); ++it)
+ {
+ QString filename(it.current()->absFilePath());
+ if (KDesktopFile::isDesktopFile(filename))
+ {
+ KDesktopFile desktopFile(filename);
+ QString libName = desktopFile.readEntry("X-KDE-Library");
+
+ if (!libName.isEmpty() && libName.startsWith( "kwin3_" ))
+ {
+ DecorationInfo di;
+ di.name = desktopFile.readName();
+ di.libraryName = libName;
+ decorations.append( di );
+ }
+ }
+ }
+ }
+}
+
+
+// Fills the decorationList with a list of available kwin decorations
+void KWinDecorationModule::createDecorationList()
+{
+ QValueList<DecorationInfo>::ConstIterator it;
+
+ // Sync with kwin hardcoded KDE2 style which has no desktop item
+ QStringList decorationNames;
+ decorationNames.append( i18n("KDE 2") );
+ for (it = decorations.begin(); it != decorations.end(); ++it)
+ {
+ decorationNames.append((*it).name);
+ }
+ decorationNames.sort();
+ decorationList->insertStringList(decorationNames);
+}
+
+
+// Reset the decoration plugin to what the user just selected
+void KWinDecorationModule::slotChangeDecoration( const QString & text)
+{
+ KConfig kwinConfig("kwinrc");
+ kwinConfig.setGroup("Style");
+
+ // Let the user see config options for the currently selected decoration
+ resetPlugin( &kwinConfig, text );
+}
+
+
+// This is the selection handler setting
+void KWinDecorationModule::slotSelectionChanged()
+{
+ emit KCModule::changed(true);
+}
+
+static const char* const border_names[ KDecorationDefines::BordersCount ] =
+ {
+ I18N_NOOP( "Tiny" ),
+ I18N_NOOP( "Normal" ),
+ I18N_NOOP( "Large" ),
+ I18N_NOOP( "Very Large" ),
+ I18N_NOOP( "Huge" ),
+ I18N_NOOP( "Very Huge" ),
+ I18N_NOOP( "Oversized" )
+ };
+
+int KWinDecorationModule::borderSizeToIndex( BorderSize size, QValueList< BorderSize > sizes )
+{
+ int pos = 0;
+ for( QValueList< BorderSize >::ConstIterator it = sizes.begin();
+ it != sizes.end();
+ ++it, ++pos )
+ if( size <= *it )
+ break;
+ return pos;
+}
+
+KDecorationDefines::BorderSize KWinDecorationModule::indexToBorderSize( int index,
+ QValueList< BorderSize > sizes )
+{
+ QValueList< BorderSize >::ConstIterator it = sizes.begin();
+ for(;
+ it != sizes.end();
+ ++it, --index )
+ if( index == 0 )
+ break;
+ return *it;
+}
+
+void KWinDecorationModule::slotBorderChanged( int size )
+{
+ if( lBorder->isHidden())
+ return;
+ emit KCModule::changed( true );
+ QValueList< BorderSize > sizes;
+ if( plugins->factory() != NULL )
+ sizes = plugins->factory()->borderSizes();
+ assert( sizes.count() >= 2 );
+ border_size = indexToBorderSize( size, sizes );
+
+ // update preview
+ preview->setTempBorderSize(plugins, border_size);
+}
+
+void KWinDecorationModule::slotButtonsChanged()
+{
+ // update preview
+ preview->setTempButtons(plugins, cbUseCustomButtonPositions->isChecked(), buttonPositionWidget->buttonsLeft(), buttonPositionWidget->buttonsRight() );
+}
+
+QString KWinDecorationModule::decorationName( QString& libName )
+{
+ QString decoName;
+
+ QValueList<DecorationInfo>::Iterator it;
+ for( it = decorations.begin(); it != decorations.end(); ++it )
+ if ( (*it).libraryName == libName )
+ {
+ decoName = (*it).name;
+ break;
+ }
+
+ return decoName;
+}
+
+
+QString KWinDecorationModule::decorationLibName( const QString& name )
+{
+ QString libName;
+
+ // Find the corresponding library name to that of
+ // the current plugin name
+ QValueList<DecorationInfo>::Iterator it;
+ for( it = decorations.begin(); it != decorations.end(); ++it )
+ if ( (*it).name == name )
+ {
+ libName = (*it).libraryName;
+ break;
+ }
+
+ if (libName.isEmpty())
+ libName = "kwin_default"; // KDE 2
+
+ return libName;
+}
+
+
+// Loads/unloads and inserts the decoration config plugin into the
+// pluginConfigWidget, allowing for dynamic configuration of decorations
+void KWinDecorationModule::resetPlugin( KConfig* conf, const QString& currentDecoName )
+{
+ // Config names are "kwin_icewm_config"
+ // for "kwin3_icewm" kwin client
+
+ QString oldName = styleToConfigLib( oldLibraryName );
+
+ QString currentName;
+ if (!currentDecoName.isEmpty())
+ currentName = decorationLibName( currentDecoName ); // Use what the user selected
+ else
+ currentName = currentLibraryName; // Use what was read from readConfig()
+
+ if( plugins->loadPlugin( currentName )
+ && preview->recreateDecoration( plugins ))
+ preview->enablePreview();
+ else
+ preview->disablePreview();
+ plugins->destroyPreviousPlugin();
+
+ checkSupportedBorderSizes();
+
+ // inform buttonPositionWidget about the new factory...
+ buttonPositionWidget->setDecorationFactory(plugins->factory() );
+
+ currentName = styleToConfigLib( currentName );
+
+ // Delete old plugin widget if it exists
+ delete pluginObject;
+ pluginObject = 0;
+
+ // Use klibloader for library manipulation
+ KLibLoader* loader = KLibLoader::self();
+
+ // Free the old library if possible
+ if (!oldLibraryName.isNull())
+ loader->unloadLibrary( QFile::encodeName(oldName) );
+
+ KLibrary* library = loader->library( QFile::encodeName(currentName) );
+ if (library != NULL)
+ {
+ void* alloc_ptr = library->symbol("allocate_config");
+
+ if (alloc_ptr != NULL)
+ {
+ allocatePlugin = (QObject* (*)(KConfig* conf, QWidget* parent))alloc_ptr;
+ pluginObject = (QObject*)(allocatePlugin( conf, pluginConfigWidget ));
+
+ // connect required signals and slots together...
+ connect( pluginObject, SIGNAL(changed()), this, SLOT(slotSelectionChanged()) );
+ connect( this, SIGNAL(pluginLoad(KConfig*)), pluginObject, SLOT(load(KConfig*)) );
+ connect( this, SIGNAL(pluginSave(KConfig*)), pluginObject, SLOT(save(KConfig*)) );
+ connect( this, SIGNAL(pluginDefaults()), pluginObject, SLOT(defaults()) );
+ pluginConfigWidget->show();
+ return;
+ }
+ }
+
+ pluginConfigWidget->hide();
+}
+
+
+// Reads the kwin config settings, and sets all UI controls to those settings
+// Updating the config plugin if required
+void KWinDecorationModule::readConfig( KConfig* conf )
+{
+ // General tab
+ // ============
+ cbShowToolTips->setChecked( conf->readBoolEntry("ShowToolTips", true ));
+// cbUseMiniWindows->setChecked( conf->readBoolEntry("MiniWindowBorders", false));
+
+ // Find the corresponding decoration name to that of
+ // the current plugin library name
+
+ oldLibraryName = currentLibraryName;
+ currentLibraryName = conf->readEntry("PluginLib",
+ ((QPixmap::defaultDepth() > 8) ? "kwin_plastik" : "kwin_quartz"));
+ QString decoName = decorationName( currentLibraryName );
+
+ // If we are using the "default" kde client, use the "default" entry.
+ if (decoName.isEmpty())
+ decoName = i18n("KDE 2");
+
+ int numDecos = decorationList->count();
+ for (int i = 0; i < numDecos; ++i)
+ {
+ if (decorationList->text(i) == decoName)
+ {
+ decorationList->setCurrentItem(i);
+ break;
+ }
+ }
+
+ // Buttons tab
+ // ============
+ bool customPositions = conf->readBoolEntry("CustomButtonPositions", false);
+ cbUseCustomButtonPositions->setChecked( customPositions );
+ buttonPositionWidget->setEnabled( customPositions );
+ // Menu and onAllDesktops buttons are default on LHS
+ buttonPositionWidget->setButtonsLeft( conf->readEntry("ButtonsOnLeft", "MS") );
+ // Help, Minimize, Maximize and Close are default on RHS
+ buttonPositionWidget->setButtonsRight( conf->readEntry("ButtonsOnRight", "HIAX") );
+
+ int bsize = conf->readNumEntry( "BorderSize", BorderNormal );
+ if( bsize >= BorderTiny && bsize < BordersCount )
+ border_size = static_cast< BorderSize >( bsize );
+ else
+ border_size = BorderNormal;
+ checkSupportedBorderSizes();
+
+ emit KCModule::changed(false);
+}
+
+
+// Writes the selected user configuration to the kwin config file
+void KWinDecorationModule::writeConfig( KConfig* conf )
+{
+ QString name = decorationList->currentText();
+ QString libName = decorationLibName( name );
+
+ KConfig kwinConfig("kwinrc");
+ kwinConfig.setGroup("Style");
+
+ // General settings
+ conf->writeEntry("PluginLib", libName);
+ conf->writeEntry("CustomButtonPositions", cbUseCustomButtonPositions->isChecked());
+ conf->writeEntry("ShowToolTips", cbShowToolTips->isChecked());
+// conf->writeEntry("MiniWindowBorders", cbUseMiniWindows->isChecked());
+
+ // Button settings
+ conf->writeEntry("ButtonsOnLeft", buttonPositionWidget->buttonsLeft() );
+ conf->writeEntry("ButtonsOnRight", buttonPositionWidget->buttonsRight() );
+ conf->writeEntry("BorderSize", border_size );
+
+ oldLibraryName = currentLibraryName;
+ currentLibraryName = libName;
+
+ // We saved, so tell kcmodule that there have been no new user changes made.
+ emit KCModule::changed(false);
+}
+
+
+void KWinDecorationModule::dcopUpdateClientList()
+{
+ // Changes the current active ListBox item, and
+ // Loads a new plugin configuration tab if required.
+ KConfig kwinConfig("kwinrc");
+ kwinConfig.setGroup("Style");
+
+ readConfig( &kwinConfig );
+ resetPlugin( &kwinConfig );
+}
+
+
+// Virutal functions required by KCModule
+void KWinDecorationModule::load()
+{
+ KConfig kwinConfig("kwinrc");
+ kwinConfig.setGroup("Style");
+
+ // Reset by re-reading the config
+ readConfig( &kwinConfig );
+ resetPlugin( &kwinConfig );
+}
+
+
+void KWinDecorationModule::save()
+{
+ KConfig kwinConfig("kwinrc");
+ kwinConfig.setGroup("Style");
+
+ writeConfig( &kwinConfig );
+ emit pluginSave( &kwinConfig );
+
+ kwinConfig.sync();
+ resetKWin();
+ // resetPlugin() will get called via the above DCOP function
+}
+
+
+void KWinDecorationModule::defaults()
+{
+ // Set the KDE defaults
+ cbUseCustomButtonPositions->setChecked( false );
+ buttonPositionWidget->setEnabled( false );
+ cbShowToolTips->setChecked( true );
+// cbUseMiniWindows->setChecked( false);
+// Don't set default for now
+// decorationList->setSelected(
+// decorationList->findItem( i18n("KDE 2") ), true ); // KDE classic client
+
+ buttonPositionWidget->setButtonsLeft("MS");
+ buttonPositionWidget->setButtonsRight("HIAX");
+
+ border_size = BorderNormal;
+ checkSupportedBorderSizes();
+
+ // Set plugin defaults
+ emit pluginDefaults();
+}
+
+void KWinDecorationModule::checkSupportedBorderSizes()
+{
+ QValueList< BorderSize > sizes;
+ if( plugins->factory() != NULL )
+ sizes = plugins->factory()->borderSizes();
+ if( sizes.count() < 2 ) {
+ lBorder->hide();
+ cBorder->hide();
+ } else {
+ cBorder->clear();
+ for (QValueList<BorderSize>::const_iterator it = sizes.begin(); it != sizes.end(); ++it) {
+ BorderSize size = *it;
+ cBorder->insertItem(i18n(border_names[size]), borderSizeToIndex(size,sizes) );
+ }
+ int pos = borderSizeToIndex( border_size, sizes );
+ lBorder->show();
+ cBorder->show();
+ cBorder->setCurrentItem(pos);
+ slotBorderChanged( pos );
+ }
+}
+
+QString KWinDecorationModule::styleToConfigLib( QString& styleLib )
+{
+ if( styleLib.startsWith( "kwin3_" ))
+ return "kwin_" + styleLib.mid( 6 ) + "_config";
+ else
+ return styleLib + "_config";
+}
+
+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 in the \"Configure [...]\" tab. There are different options specific for each theme.</p>"
+ "<p>In \"General Options (if available)\" you can activate the \"Buttons\" tab by checking the \"Use custom titlebar button positions\" box."
+ " In the \"Buttons\" tab you can change the positions of the buttons to your liking.</p>" );
+}
+
+
+void KWinDecorationModule::resetKWin()
+{
+ bool ok = kapp->dcopClient()->send("kwin*", "KWinInterface",
+ "reconfigure()", QByteArray());
+ if (!ok)
+ kdDebug() << "kcmkwindecoration: Could not reconfigure kwin" << endl;
+}
+
+#include "kwindecoration.moc"
+// vim: ts=4
+// kate: space-indent off; tab-width 4;
+
diff --git a/kwin/kcmkwin/kwindecoration/kwindecoration.desktop b/kwin/kcmkwin/kwindecoration/kwindecoration.desktop
new file mode 100644
index 000000000..3c5f12e6f
--- /dev/null
+++ b/kwin/kcmkwin/kwindecoration/kwindecoration.desktop
@@ -0,0 +1,231 @@
+[Desktop Entry]
+Exec=kcmshell kwindecoration
+Icon=kcmkwm
+Type=Application
+DocPath=kcontrol/kwindecoration/index.html
+
+X-KDE-ModuleType=Library
+X-KDE-Library=kwindecoration
+X-KDE-FactoryName=kwindecoration
+
+Name=Window Decorations
+Name[af]=Venster Versierings
+Name[ar]=زخرفة النافذة
+Name[be]=Дэкарацыі вокнаў
+Name[bg]=Декорация
+Name[bn]=উইণ্ডো সাজসজ্জা
+Name[br]=Kinkladur ar prenester
+Name[bs]=Ukrasi prozora
+Name[ca]=Decoració de les finestres
+Name[cs]=Dekorace oken
+Name[csb]=Dekòracëje òkna
+Name[cy]=Addurniadau Ffenestr
+Name[da]=Vinduesdekorationer
+Name[de]=Fensterdekorationen
+Name[el]=Διακοσμήσεις παραθύρων
+Name[eo]=Fenestro-ornamaĵo
+Name[es]=Decoración de ventanas
+Name[et]=Akna dekoratsioonid
+Name[eu]=Leihoaren dekorazioak
+Name[fa]=تزئینات پنجره
+Name[fi]=Ikkunoiden kehykset
+Name[fr]=Décoration des fenêtres
+Name[fy]=Finsterdekoraasjes
+Name[gl]=Decoracións das Fiestras
+Name[he]=קישוטי חלונות
+Name[hi]=विंडो सजावट
+Name[hr]=Ukrasi prozora
+Name[hu]=Ablakkeret-stílus
+Name[id]=Dekorasi Jendela
+Name[is]=Gluggaskreytingar
+Name[it]=Decorazioni finestra
+Name[ja]=ウィンドウ装飾
+Name[ka]=ფანჯრის დეკორაცია
+Name[kk]=Терезе безендіруі
+Name[km]=ការ​តុបតែង​បង្អួច
+Name[ko]=창 종료 도구
+Name[lo]=ການຕົກແຕ່ງຫນ້າຕ່າງ
+Name[lt]=Langų išvaizda
+Name[lv]=Loga Dekorācijas
+Name[mk]=Декорации на прозорците
+Name[mn]=Цонхны засал
+Name[mt]=Dekorazzjoni tal-Windows
+Name[nb]=Vinduspynt
+Name[nds]=Finsterdekoratschoon
+Name[ne]=सञ्झ्याल सजावट
+Name[nl]=Vensterdecoraties
+Name[nn]=Vindaugsdekorasjonar
+Name[nso]=Dikgabiso tsa Window
+Name[pa]=ਝਰੋਖਾ ਸਜਾਵਟ
+Name[pl]=Dekoracje okna
+Name[pt]=Decorações das Janelas
+Name[pt_BR]=Decorações da Janela
+Name[ro]=Decorări
+Name[ru]=Декорации окон
+Name[rw]=Imitako y'Idirishya
+Name[se]=Lásehearvvat
+Name[sk]=Dekorácie okien
+Name[sl]=Okraski oken
+Name[sr]=Декорација прозора
+Name[sr@Latn]=Dekoracija prozora
+Name[ss]=Kuhlotjiswa kweliwindi
+Name[sv]=Fönsterdekoration
+Name[ta]=சாளர அலங்கரிப்புகள்
+Name[tg]=Декоратсияҳои тиреза
+Name[th]=ตกแต่งหน้าต่าง
+Name[tr]=Pencere Dekorasyonları
+Name[tt]=Täräzä Bizäge
+Name[uk]=Обрамлення вікон
+Name[uz]=Oynaning bezaklari
+Name[uz@cyrillic]=Ойнанинг безаклари
+Name[ven]=U khavhisedza ha windo
+Name[vi]=Trang trí Cửa sổ
+Name[wa]=Gåliotaedjes des purneas
+Name[xh]=Izihombiso zeWindow
+Name[zh_CN]=窗口装饰
+Name[zh_TW]=視窗裝飾
+Name[zu]=Imihlobiso ye-window
+
+Comment=Configure the look and feel of window titles
+Comment[af]=Stel die uitdrukking en gevoek van venster titels op
+Comment[ar]=إعداد شكل و ملمس عنوان النافذة
+Comment[be]=Настаўленні вонкавага выгляду загалоўкаў вокнаў
+Comment[bg]=Настройване външния вид на прозорците
+Comment[bn]=উইণ্ডো শিরোনামের চেহারা কনফিগার করুন
+Comment[br]=Kefluniañ neuz ha feson titloù ar prenester
+Comment[bs]=Ovdje možete podesiti izgled i ponašanje naslova prozora
+Comment[ca]=Configura l'aspecte i efecte dels títols de la finestra
+Comment[cs]=Nastavení vzhledu a dekorací oken
+Comment[csb]=Kònfigùracëjô wëzdrzatkù ë ùchòwaniô titlowi lëstwë òknów
+Comment[cy]=Ffurfweddu golwg a theimlad teitlau ffenestri
+Comment[da]=Indstil udseendet af vinduestitler
+Comment[de]=Das Erscheinungsbild von Fenstertiteln festlegen
+Comment[el]=Ρυθμίστε την εμφάνιση και την αίσθηση των τίτλων παραθύρου
+Comment[eo]=Agordu la fenestrajn titolojn
+Comment[es]=Configuración del aspecto y comportamiento de los títulos de las ventanas
+Comment[et]=Akna tiitliribade välimuse ja tunnetuse seadistamine
+Comment[eu]=Konfiguratu leihoaren izenburuen itxura
+Comment[fa]=پیکربندی ظاهر و احساس عنوان پنجره‌ها
+Comment[fi]=Muokkaa ikkunoiden kehysten ulkonäköä
+Comment[fr]=Configuration de l'apparence du titre des fenêtres
+Comment[fy]=Hjir kinne jo it uterlik en gedrach fan finstertitels ynstelle
+Comment[gl]=Configurar a apariencia dos títulos das fiestras
+Comment[he]=שינוי הגדרות המראה והתחושה של כותרות חלונות
+Comment[hi]=विंडो शीर्षकों के रूप आकार को कॉन्फ़िगर करें
+Comment[hr]=Konfiguriranje izgleda naslova prozora
+Comment[hu]=Az ablakok címsorának megjelenési beállításai
+Comment[is]=Stilla viðmót gluggatitla
+Comment[it]=Configura l'aspetto e il comportamento dei titoli delle finestre
+Comment[ja]=ウィンドウのタイトルバーの外観を設定
+Comment[ka]=ფანჯრის სათაურის იერსახის კონფიგურაცია
+Comment[kk]=Терезе айдарының безендіруін баптау
+Comment[km]=កំណត់​រចនាសម្ព័ន្ធ​រូបរាង​របស់​ចំណងជើង​បង្អួច
+Comment[ko]=창 제목 표시줄의 모습과 느낌 설정
+Comment[lo]=ປັດແຕ່ງລັກສະນະແລະຄວາມຮູ້ສືກໃນການໃຊ້ງານຂອງບາວເຊີ Konqueror
+Comment[lt]=Konfigūruoti langų antraščių išvaizdą ir elgseną
+Comment[lv]=Konfigurē loga virsrakstu izskatu un izturēšanos
+Comment[mk]=Конфигурирајте го изгледот и чувството на насловите на прозорците
+Comment[mn]=Цонхны толгойн харагдалтыг тохируулах
+Comment[mt]=Ikkonfigura d-dehra u l-użu tat-titli tal-windows
+Comment[nb]=Her kan du sette opp hvordan nettleseren Konqueror skal virke og se ut
+Comment[nds]=Dat Utsehn vun de Finstertiteln instellen
+Comment[ne]=सञ्झ्याल शीर्षकहरूको हेराइ र बुझाइ कन्फिगर गर्नुहोस्
+Comment[nl]=Hier kunt u het uiterlijk en gedrag van venstertitels instellen
+Comment[nn]=Set opp utsjånaden på vindaugstitlar
+Comment[nso]=Beakanya pogego le maikutlo a maina a window
+Comment[pa]=ਝਰੋਖਾ ਸਿਰਲੇਖਾਂ ਦੇ ਰੰਗ-ਰੂਪ ਦੀ ਸੰਰਚਨਾ
+Comment[pl]=Konfiguracja wyglądu i zachowania belek tytułowych okien
+Comment[pt]=Configuração da aparência e comportamento dos títulos das janelas
+Comment[pt_BR]=Configura a aparência dos títulos de janelas
+Comment[ro]=Configurează aspectul titlului ferestrelor
+Comment[ru]=Настройка внешнего вида заголовков окон
+Comment[rw]=Kuboneza imboneko n'ukumva kw'imitwe y'idirishya
+Comment[se]=Heivet lásenamahusaid fárdda
+Comment[sk]=Nastavenie vzhľadu titulkov okien
+Comment[sl]=Nastavite videz in delovanje naslovnih vrstic okna.
+Comment[sr]=Подешавање изгледа и осећаја насловних линија прозора
+Comment[sr@Latn]=Podešavanje izgleda i osećaja naslovnih linija prozora
+Comment[sv]=Anpassa namnlisternas utseende och känsla
+Comment[ta]=சாளரம் மற்றும் தலைப்பின் காட்சிவகையை மாற்று
+Comment[tg]=Танзими намо ва ҳиси унвони тиреза
+Comment[th]=ปรับแต่งลักษณะรูปแบบและสัมผัสสึกของแถบหัวเรื่องหน้าต่าง
+Comment[tr]=Pencere başlıklarını görünümlerini yapılandır
+Comment[tt]=Täräzä başlığınıñ küreneşen caylaw
+Comment[uk]=Налаштування вигляду та поведінки заголовків вікон
+Comment[uz]=Oyna sarlavhasining tashqi koʻrinishini moslash
+Comment[uz@cyrillic]=Ойна сарлавҳасининг ташқи кўринишини мослаш
+Comment[ven]=Dzudzanyani mbonalelo na zwipfi zwa buronza ya inithanete ino pfi Konqueror
+Comment[vi]=Cấu hình cảm nhận cho tên cửa sổ
+Comment[wa]=Apontyî li rivnance eyet l' dujhance des tites des purneas
+Comment[xh]=Qwalasela inkangeleko nemvakalelo yezihloko zeWindow
+Comment[zh_CN]=配置窗口标题的观感
+Comment[zh_TW]=設定視窗標題列的外觀與感覺
+Comment[zu]=Hlanganisela ukubona kanye nokuzwa kwezihloko zama-window
+
+Keywords=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration
+Keywords[ar]=kwin,نافذة,مسيير,الحافة,الشكل,سمة,مظهر,ملمس,تصميم,زر,معامل,مدبر,kwm,زخرفات
+Keywords[az]=kwin,pəncərə,idarəçi,kənar,tərz,örtü,görünüş,toxuma,yer,düymə,applet,kənar,kwm,dekorasiya,bəzək
+Keywords[be]=Акно,Кіраўнік,Мяжа,Стыль,Тэма,Вонкавы выгляд,Кнопкі,Апрацоўшчык,Край,Дэкарацыя,kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration
+Keywords[bg]=прозорец, декорация, заглавие, бутони, меню, kwin, window, manager, border, style, theme, look, feel, layout, button, handle, edge, kwm, decoration
+Keywords[ca]=kwin,finestra,gestor,vora,estil,tema,aspecte,comportament,disposició,botó,nansa,marges,kwm,decoració
+Keywords[cs]=kwin,okno,správce,okraj,styl,motiv,vzhled,rozvržení,tlačítko,úchytka,hrana,kwm,dekorace
+Keywords[csb]=kwin,òkno,menedżer,zberk,sztél,téma,wëzdrzatk,ùchòwanié,ùstôw,knąpa,ùchwët,rańt,kwm,dekòracëjô
+Keywords[cy]=kwin,ffenestr,trefnydd,ymyl,arddull,thema,golwg,teimlad,haenlun,botwm,carn,kwm,addurniad
+Keywords[da]=kwin,vindue,håndtering,kant,stil,tema,udseende,fornemmelse,layout,knap,håndtag,kant,kwm,dekoration
+Keywords[de]=KWin,Kwm,Fenster,Manager,Rahmen,Design,Stile,Themes,Optik,Erscheinungsbild,Layout,Knöpfe,Ränder,Dekorationen
+Keywords[el]=kwin,παράθυρο,διαχειριστής,περίγραμμα,στυλ,θέμα,εμφάνιση,αίσθηση,διάταξη,κουμπί,χειρισμός,άκρο,kwm,διακόσμηση
+Keywords[eo]=kwin,fenestro,administrilo,rando,stilo,etoso,aspekto,konduto,aranĝo,butono,eĝo,kwm,ornamo
+Keywords[es]=kwin,ventana,gestor,borde,estilo,tema,aspecto,comportamiento,disposición,botón,asa,esquina,kwm,decoración
+Keywords[et]=kwin,aken,haldur,piire,stiil,teema,välimus,kasutamine,nupud,serv,kwm,dekoratsioon
+Keywords[eu]=kwin,leihoa,kudeatzailea,ertza,estiloa,gaia,itxura,antolaketa,botoia, maneiatzailea,ertzea,kwm,dekorazioa
+Keywords[fa]=kwin، پنجره، مدیر، لبه، سبک، چهره، ظاهر، احساس، طرح‌بندی، دکمه، گرداندن، لبه، kwm، تزئین
+Keywords[fi]=kwin,ikkuna,ikkunaohjelma,ikkunoinnin hallintaohjelma,tausta,tyyli,teema,ulkonäkö,tuntuma,ulkoasu,painike,kahva,kulma,kwm,kehys
+Keywords[fr]=kwin,fenêtre,gestionnaire,bordure,style,thème,apparence,ergonomie,disposition,bouton,poignée,bord,kwm,décoration
+Keywords[fy]=kwin,window,manager,rand,stijl,theme,tema,look,uiterlijk,gedrag,feel,layout,opmaak,button,knoppen,handle,rand,kwm,decoratie,windowmanager,venster,vensterbeheer,finster,râne,kader,styltema,uterlik,gedrach,finsterbehear
+Keywords[ga]=kwin,fuinneog,bainisteoir,imlíne,stíl,téama,leagan amach,cnaipe,hanla,ciumhais,kwm,maisiúchán
+Keywords[gl]=kwin,fiestra,xestor,beira,estilo,tema,apariencia,formato,botón,xestión,esquina,kwm,decoración
+Keywords[he]=מנהל חלונות,חלונות,מנהל,גבול,מסגרת,סגנון,ערכה,ערכת נושא,מראה,תחושה,פריסה,תצוגה,כפתור,ידית,קצה,קישוט, kwin,window,manager,border,style,theme,look,feel,layout,button,handle, edge,kwm,decoration
+Keywords[hi]=के-विन,विंडो,प्रबंधक,बार्डर,शैली,प्रसंग,रूप,अनुभव,ले-आउट,बटन,हैंडल,किनारा,केडबल्यूएम,सजावट
+Keywords[hr]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,prozor,upravljanje,obrub,stil,tema,izgled,raspored,gumb,rukovanje,rub,ukras
+Keywords[hu]=KWin,ablak,kezelő,szegély,stílus,téma,kinézet,megjelenés,elrendezés,nyomógomb,fogantyú,perem,kwm,ablakstílus
+Keywords[is]=kwin,gluggi,gluggastjóri,gluggar,kantar,rammi,skreyting,þema,stíll,útlit,takki,kwm,skraut
+Keywords[it]=kwin,finestra,window manager,bordo,stile,tema,aspetto,pulsante,maniglia,bordo,kwm,decorazione
+Keywords[ja]=kwin,ウィンドウ,マネージャ,枠,スタイル,テーマ,ルック,外観,レイアウト,ボタン,ハンドル,エッジ,kwm,装飾
+Keywords[km]=kwin,បង្អួច,កម្មវិធី​គ្រប់គ្រង,ស៊ុម,រចនាប័ទ្ម,ស្បែក,មុខងារ,ប្លង់,ប៊ូតុង,ការ​ប្រើ,គែម,kwm,ការ​តុបតែង
+Keywords[lt]=kwin,window,manager,border,style,theme,look,feel,layout,buttons,handle,edge,kwm,decoration,langas,tvarkyklė,rėmelis,stilius,tema,žiūrėti,jausti,išdėstymas,mygtukai,kraštas,dekoracija
+Keywords[lv]=kwin, logs, menedžeris, rāmis, stils, tēma, skats, gars, izkārtojums, poga, rokturis, stūris, kwm, dekorācija
+Keywords[mk]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,прозорец,менаџер,граница,стил,тема,изглед,чувство,распоред,копче,рачка,раб,декорација
+Keywords[mn]=KWin,Kwm,Цонх,Manager,Хүрээ,Design,Хэлбэр,Загвар, Optik,Харагдалт,Layout,Товч,Өнцөг,Засал
+Keywords[mt]=kwin, window, manager, border, bordura, stil, tema, apparenza, style, theme, look, feel, layout, tqassim, użu, button, handle, edge, kwm, decoration
+Keywords[nb]=kwin,vindu,vindusstyring,styrer,ramme,stil,tema,utseende,layout,knapp,kant,kwm,pynt,dekorasjon
+Keywords[nds]=kwin,Finster,Finsterpleger,manager,Rahmen,Stil,Muster,look,feel,layout,Knoop,Greep,Rand,kwm,Dekoratschoon
+Keywords[ne]=के विन,सञ्झ्याल, प्रबन्धक, किनारा, शैली, विषयवस्तु, हेराइ, बुझाइ, सजावट, बटन, ह्यान्डल, छेउ,kwm, सजावट
+Keywords[nl]=kwin,window,manager,rand,stijl,theme,thema,look,uiterlijk,gedrag,feel, layout,opmaak,button,knoppen,handle,rand,kwm,decoratie,windowmanager,venster,vensterbeheer
+Keywords[nn]=kwin,vindauge,kant,bord,stil,tema,utsjånad,bunad,knapp,handtak,kwm,dekorasjon
+Keywords[nso]=kwin,window,molaodi,mollwane,mokgwa,molaetsa,tebelego,maikutlo,peakanyo,setobetswa,moswaro,nthla,kwm,kgabiso
+Keywords[pa]=kwin,handle,edge,kwm,decoration,ਝਰੋਖਾ,ਮੈਨੇਜਰ,ਹਾਸ਼ੀਆ,ਸ਼ੈਲੀ,ਸਰੂਪ,ਦਿੱਖ,ਖਾਕਾ,ਬਟਨ,ਹੈਂਡਲ,ਸਜਾਵਟ
+Keywords[pl]=kwin,okno,menedżer,brzeg,styl,motyw,wygląd,zachowanie,układ,przycisk,uchwyt,krawędź,kwm,dekoracja
+Keywords[pt]=kwin,janela,gestor,contorno,estilo,tema,aparência,comportamento,visual,botão,pega,extremo,kwm,decoração
+Keywords[pt_BR]=kwin,janela,gerenciador,borda,estilo,tema,aparência,aparência,botão, gerenciador,borda,kwm,decoração
+Keywords[ro]=kwin,fereastră,manager,margine,stil,tematică,aspect,comportament,format,buton,kwm,decorare
+Keywords[rw]=kwin,idirishya,muyobozi,impera,imisusire,insanganyamatsiko,imboneko,kumva,imigaragarire,buto,ikirindi,impera,kwm,ugutaaka
+Keywords[se]=kwin,láse,gieđahalli,ravda,stiila,fáddá,fárda,dovdu,hápmi,boallu,geavja,ravda,kwm,hearva
+Keywords[sk]=kwin,okno,správa,okraj,štýl,téma,vzhľad,rozloženie,tlačidlo,hrana,kwm,dekorácia,oblasť
+Keywords[sl]=kwin,okno,upravitelj,rob,meja,slog,stil,tema,pogled,občutek,gumb,ročaj,rob,kwm,okrasek
+Keywords[sr]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,прозор,менаџер,оквир,стил,тема,изглед,дугме,хватаљка,декорација
+Keywords[sr@Latn]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,prozor,menadžer,okvir,stil,tema,izgled,dugme,hvataljka,dekoracija
+Keywords[sv]=kwin,fönster,hanterare,kant,stil,tema,utseende,känsla,layout,knapp,hantera,kant,kwm,dekoration
+Keywords[ta]=kwin,சாளரம்,மேலாளர்,விளிம்பு,பாணி,தலைப்பு,பார்வை,உணர்தல்,உருவரை,விசை,கையாள்,முனை,kwm,அலங்கரிப்பு
+Keywords[th]=kwin,หน้าต่าง,ตัวจัดการ,กรอบ,ลักษณะ,ชุดตกแต่ง,มองเห็น,รู้สึก,การจัดวาง,ปุ่ม,ที่จับ,ขอบ,kwm,การตกแต่ง
+Keywords[tr]=kwin,pencere,yönetici,kenar,stil,tema,görünüş,doku,yerleşim,düğme,tutamaç,kenar,kwm,dekorasyon
+Keywords[uk]=kwin,вікно,менеджер,границя,стиль,тема,вигляд,поведінка,розклад,кнопка,handle,край,kwm,обрамлення
+Keywords[uz]=kwin,kwm,bezak,oyna,boshqaruvchi,usul,tashqi koʻrinish
+Keywords[uz@cyrillic]=kwin,kwm,безак,ойна,бошқарувчи,усул,ташқи кўриниш
+Keywords[ven]=kwin,windo,mulanguli,mukanoni,tshitaela,thero,sedza,upfa,vhuvha,bathene,fara,mafhedziselo,kwn,u khavhisedza
+Keywords[vi]=kwin,cửa sổ,quản lý,bờ,kiểu,sắc thái,ngoại hình,cảm nhận,sắp xếp,nút,điều khiển,cạnh,kwm,trang trí
+Keywords[wa]=kwin,kpurnea,purnea,manaedjeu,boird,stîle,tinme,rivnance,layout;loukance,boton,apougnî,costé,kwm,gåliotaedje
+Keywords[xh]=kwin,window,umphathi,umda,uhlobo,umxholo wokuxoxwa,jonga,yiva,beka,iqhosha,umqheba,umda,kwm,uhombiso
+Keywords[zh_CN]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,窗口,管理器,边框,样式,主题,观感,布局,按钮,处理,边缘,装饰
+Keywords[zh_TW]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,視窗,管理員,邊框,風格,佈景主題,外觀,感覺,佈局,按鈕,邊緣,裝飾
+Keywords[zu]=kwin,i-window,imenenja,umngcele,isitayela,bona,izwa, isendlalelo,inkinobho,isibambo,unqenqema,kwm,umhlobiso
+Categories=Qt;KDE;X-KDE-settings-looknfeel;
diff --git a/kwin/kcmkwin/kwindecoration/kwindecoration.h b/kwin/kcmkwin/kwindecoration/kwindecoration.h
new file mode 100644
index 000000000..eea091ebc
--- /dev/null
+++ b/kwin/kcmkwin/kwindecoration/kwindecoration.h
@@ -0,0 +1,135 @@
+/*
+ This is the new kwindecoration kcontrol module
+
+ Copyright (c) 2001
+ Karol Szwed <[email protected]>
+ http://gallium.n3.net/
+
+ 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) <[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 KWINDECORATION_H
+#define KWINDECORATION_H
+
+#include <kcmodule.h>
+#include <dcopobject.h>
+#include <buttons.h>
+#include <kconfig.h>
+#include <klibloader.h>
+
+#include <kdecoration.h>
+
+#include "kwindecorationIface.h"
+
+class KComboBox;
+class QCheckBox;
+class QLabel;
+class QTabWidget;
+class QVBox;
+class QSlider;
+
+class KDecorationPlugins;
+class KDecorationPreview;
+
+// Stores themeName and its corresponding library Name
+struct DecorationInfo
+{
+ QString name;
+ QString libraryName;
+};
+
+
+class KWinDecorationModule : public KCModule, virtual public KWinDecorationIface, public KDecorationDefines
+{
+ Q_OBJECT
+
+ public:
+ KWinDecorationModule(QWidget* parent, const char* name, const QStringList &);
+ ~KWinDecorationModule();
+
+ virtual void load();
+ virtual void save();
+ virtual void defaults();
+
+ QString quickHelp() const;
+
+ virtual void dcopUpdateClientList();
+
+ signals:
+ void pluginLoad( KConfig* conf );
+ void pluginSave( KConfig* conf );
+ void pluginDefaults();
+
+ protected slots:
+ // Allows us to turn "save" on
+ void slotSelectionChanged();
+ void slotChangeDecoration( const QString & );
+ void slotBorderChanged( int );
+ void slotButtonsChanged();
+
+ private:
+ void readConfig( KConfig* conf );
+ void writeConfig( KConfig* conf );
+ void findDecorations();
+ void createDecorationList();
+ void updateSelection();
+ QString decorationLibName( const QString& name );
+ QString decorationName ( QString& libName );
+ static QString styleToConfigLib( QString& styleLib );
+ void resetPlugin( KConfig* conf, const QString& currentDecoName = QString::null );
+ void resetKWin();
+ void checkSupportedBorderSizes();
+ static int borderSizeToIndex( BorderSize size, QValueList< BorderSize > sizes );
+ static BorderSize indexToBorderSize( int index, QValueList< BorderSize > sizes );
+
+ QTabWidget* tabWidget;
+
+ // Page 1
+ KComboBox* decorationList;
+ QValueList<DecorationInfo> decorations;
+
+ KDecorationPreview* preview;
+ KDecorationPlugins* plugins;
+ KConfig kwinConfig;
+
+ QCheckBox* cbUseCustomButtonPositions;
+ // QCheckBox* cbUseMiniWindows;
+ QCheckBox* cbShowToolTips;
+ QLabel* lBorder;
+ QComboBox* cBorder;
+ BorderSize border_size;
+
+ QObject* pluginObject;
+ QWidget* pluginConfigWidget;
+ QString currentLibraryName;
+ QString oldLibraryName;
+ QObject* (*allocatePlugin)( KConfig* conf, QWidget* parent );
+
+ // Page 2
+ ButtonPositionWidget *buttonPositionWidget;
+ QVBox* buttonPage;
+};
+
+
+#endif
+// vim: ts=4
+// kate: space-indent off; tab-width 4;
diff --git a/kwin/kcmkwin/kwindecoration/kwindecorationIface.h b/kwin/kcmkwin/kwindecoration/kwindecorationIface.h
new file mode 100644
index 000000000..f45be6b7b
--- /dev/null
+++ b/kwin/kcmkwin/kwindecoration/kwindecorationIface.h
@@ -0,0 +1,44 @@
+/*
+ This is the new kwindecoration kcontrol module
+
+ Copyright (c) 2001
+ Karol Szwed (gallium) <[email protected]>
+ http://gallium.n3.net/
+
+ 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) <[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 __KWINDECORATIONIFACE_H
+#define __KWINDECORATIONIFACE_H
+
+#include <dcopobject.h>
+
+class KWinDecorationIface: virtual public DCOPObject
+{
+ K_DCOP
+ public:
+
+ k_dcop:
+ virtual void dcopUpdateClientList()=0;
+};
+
+#endif
diff --git a/kwin/kcmkwin/kwindecoration/pixmaps.h b/kwin/kcmkwin/kwindecoration/pixmaps.h
new file mode 100644
index 000000000..76f60b3e9
--- /dev/null
+++ b/kwin/kcmkwin/kwindecoration/pixmaps.h
@@ -0,0 +1,110 @@
+/*
+ This is the new kwindecoration kcontrol module
+
+ Copyright (c) 2004, Sandro Giessl <[email protected]>
+ Copyright (c) 2001
+ Karol Szwed <[email protected]>
+ http://gallium.n3.net/
+
+ 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) <[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.
+
+*/
+
+// Button icon bitmap data which is hopefully generic enough to be recognized by everyone.
+
+// close.xbm:
+#define close_width 12
+#define close_height 12
+static unsigned char close_bits[] = {
+ 0x00, 0x00, 0x06, 0x06, 0x0e, 0x07, 0x9c, 0x03, 0xf8, 0x01, 0xf0, 0x00,
+ 0xf0, 0x00, 0xf8, 0x01, 0x9c, 0x03, 0x0e, 0x07, 0x06, 0x06, 0x00, 0x00 };
+
+// help.xbm:
+#define help_width 12
+#define help_height 12
+static unsigned char help_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xfc, 0x01, 0x8c, 0x01, 0xc0, 0x01,
+ 0xe0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00 };
+
+// keepaboveothers.xbm:
+#define keepaboveothers_width 12
+#define keepaboveothers_height 12
+static unsigned char keepaboveothers_bits[] = {
+ 0x00, 0x00, 0x60, 0x00, 0xf0, 0x00, 0xf8, 0x01, 0x60, 0x00, 0xfe, 0x07,
+ 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+// keepbelowothers.xbm:
+#define keepbelowothers_width 12
+#define keepbelowothers_height 12
+static unsigned char keepbelowothers_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07,
+ 0xfe, 0x07, 0x60, 0x00, 0xf8, 0x01, 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00 };
+
+// maximize.xbm:
+#define maximize_width 12
+#define maximize_height 12
+static unsigned char maximize_bits[] = {
+ 0x00, 0x00, 0xfe, 0x07, 0xfe, 0x07, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04,
+ 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0xfe, 0x07, 0x00, 0x00 };
+
+// menu.xbm:
+#define menu_width 12
+#define menu_height 12
+static unsigned char menu_bits[] = {
+ 0x00, 0x00, 0xfc, 0x03, 0xf4, 0x02, 0x04, 0x02, 0xf4, 0x02, 0x04, 0x02,
+ 0xf4, 0x02, 0x04, 0x02, 0xf4, 0x02, 0x04, 0x02, 0xfc, 0x03, 0x00, 0x00 };
+
+// minimize.xbm:
+#define minimize_width 12
+#define minimize_height 12
+static unsigned char minimize_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0xfe, 0x07, 0x00, 0x00 };
+
+// onalldesktops.xbm:
+#define onalldesktops_width 12
+#define onalldesktops_height 12
+static unsigned char onalldesktops_bits[] = {
+ 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xfe, 0x07,
+ 0xfe, 0x07, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00 };
+
+// resize.xbm:
+#define resize_width 12
+#define resize_height 12
+static unsigned char resize_bits[] = {
+ 0x00, 0x00, 0xfe, 0x07, 0x42, 0x04, 0x42, 0x04, 0x42, 0x04, 0x42, 0x04,
+ 0x7e, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0xfe, 0x07, 0x00, 0x00 };
+
+// shade.xbm:
+#define shade_width 12
+#define shade_height 12
+static unsigned char shade_bits[] = {
+ 0x00, 0x00, 0xfe, 0x07, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+// spacer.xbm:
+#define spacer_width 12
+#define spacer_height 12
+static unsigned char spacer_bits[] = {
+ 0x00, 0x00, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x54, 0x03,
+ 0xac, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x00, 0x00 };
+
+// vim: ts=4
diff --git a/kwin/kcmkwin/kwindecoration/preview.cpp b/kwin/kcmkwin/kwindecoration/preview.cpp
new file mode 100644
index 000000000..8c88a3604
--- /dev/null
+++ b/kwin/kcmkwin/kwindecoration/preview.cpp
@@ -0,0 +1,507 @@
+/*
+ *
+ * Copyright (c) 2003 Lubos Lunak <[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 "preview.h"
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <qlabel.h>
+#include <qstyle.h>
+#include <kiconloader.h>
+
+#include <X11/Xlib.h>
+#include <X11/extensions/shape.h>
+
+#include <kdecorationfactory.h>
+#include <kdecoration_plugins_p.h>
+
+// FRAME the preview doesn't update to reflect the changes done in the kcm
+
+KDecorationPreview::KDecorationPreview( QWidget* parent, const char* name )
+ : QWidget( parent, name )
+ {
+ options = new KDecorationPreviewOptions;
+
+ bridge[Active] = new KDecorationPreviewBridge( this, true );
+ bridge[Inactive] = new KDecorationPreviewBridge( this, false );
+
+ deco[Active] = deco[Inactive] = NULL;
+
+ no_preview = new QLabel( i18n( "No preview available.\n"
+ "Most probably there\n"
+ "was a problem loading the plugin." ), this );
+
+ no_preview->setAlignment( AlignCenter );
+
+ setMinimumSize( 100, 100 );
+ no_preview->resize( size());
+ }
+
+KDecorationPreview::~KDecorationPreview()
+ {
+ for ( int i = 0; i < NumWindows; i++ )
+ {
+ delete deco[i];
+ delete bridge[i];
+ }
+ delete options;
+ }
+
+bool KDecorationPreview::recreateDecoration( KDecorationPlugins* plugins )
+ {
+ for ( int i = 0; i < NumWindows; i++ )
+ {
+ delete deco[i]; // deletes also window
+ deco[i] = plugins->createDecoration( bridge[i] );
+ deco[i]->init();
+ }
+
+ if( deco[Active] == NULL || deco[Inactive] == NULL )
+ {
+ return false;
+ }
+
+ positionPreviews();
+ deco[Inactive]->widget()->show();
+ deco[Active]->widget()->show();
+
+ return true;
+ }
+
+void KDecorationPreview::enablePreview()
+ {
+ no_preview->hide();
+ }
+
+void KDecorationPreview::disablePreview()
+ {
+ delete deco[Active];
+ delete deco[Inactive];
+ deco[Active] = deco[Inactive] = NULL;
+ no_preview->show();
+ }
+
+void KDecorationPreview::resizeEvent( QResizeEvent* e )
+ {
+ QWidget::resizeEvent( e );
+ positionPreviews();
+ }
+
+void KDecorationPreview::positionPreviews()
+ {
+ int titleBarHeight, leftBorder, rightBorder, xoffset,
+ dummy1, dummy2, dummy3;
+ QRect geometry;
+ QSize size;
+
+ no_preview->resize( this->size() );
+
+ if ( !deco[Active] || !deco[Inactive] )
+ return;
+
+ // don't have more than one reference to the same dummy variable in one borders() call.
+ deco[Active]->borders( dummy1, dummy2, titleBarHeight, dummy3 );
+ deco[Inactive]->borders( leftBorder, rightBorder, dummy1, dummy2 );
+
+ titleBarHeight = kMin( int( titleBarHeight * .9 ), 30 );
+ xoffset = kMin( kMax( 10, QApplication::reverseLayout()
+ ? leftBorder : rightBorder ), 30 );
+
+ // Resize the active window
+ size = QSize( width() - xoffset, height() - titleBarHeight )
+ .expandedTo( deco[Active]->minimumSize() );
+ geometry = QRect( QPoint( 0, titleBarHeight ), size );
+ deco[Active]->widget()->setGeometry( QStyle::visualRect( geometry, this ) );
+
+ // Resize the inactive window
+ size = QSize( width() - xoffset, height() - titleBarHeight )
+ .expandedTo( deco[Inactive]->minimumSize() );
+ geometry = QRect( QPoint( xoffset, 0 ), size );
+ deco[Inactive]->widget()->setGeometry( QStyle::visualRect( geometry, this ) );
+ }
+
+void KDecorationPreview::setPreviewMask( const QRegion& reg, int mode, bool active )
+ {
+ QWidget *widget = active ? deco[Active]->widget() : deco[Inactive]->widget();
+
+ // FRAME duped from client.cpp
+ if( mode == Unsorted )
+ {
+ XShapeCombineRegion( qt_xdisplay(), widget->winId(), ShapeBounding, 0, 0,
+ reg.handle(), ShapeSet );
+ }
+ else
+ {
+ QMemArray< QRect > rects = reg.rects();
+ XRectangle* xrects = new XRectangle[ rects.count() ];
+ for( unsigned int i = 0;
+ i < rects.count();
+ ++i )
+ {
+ xrects[ i ].x = rects[ i ].x();
+ xrects[ i ].y = rects[ i ].y();
+ xrects[ i ].width = rects[ i ].width();
+ xrects[ i ].height = rects[ i ].height();
+ }
+ XShapeCombineRectangles( qt_xdisplay(), widget->winId(), ShapeBounding, 0, 0,
+ xrects, rects.count(), ShapeSet, mode );
+ delete[] xrects;
+ }
+ if( active )
+ mask = reg; // keep shape of the active window for unobscuredRegion()
+ }
+
+QRect KDecorationPreview::windowGeometry( bool active ) const
+ {
+ QWidget *widget = active ? deco[Active]->widget() : deco[Inactive]->widget();
+ return widget->geometry();
+ }
+
+void KDecorationPreview::setTempBorderSize(KDecorationPlugins* plugin, KDecorationDefines::BorderSize size)
+ {
+ options->setCustomBorderSize(size);
+ if (plugin->factory()->reset(KDecorationDefines::SettingBorder) )
+ {
+ // can't handle the change, recreate decorations then
+ recreateDecoration(plugin);
+ }
+ else
+ {
+ // handles the update, only update position...
+ positionPreviews();
+ }
+ }
+
+void KDecorationPreview::setTempButtons(KDecorationPlugins* plugin, bool customEnabled, const QString &left, const QString &right)
+ {
+ options->setCustomTitleButtonsEnabled(customEnabled);
+ options->setCustomTitleButtons(left, right);
+ if (plugin->factory()->reset(KDecorationDefines::SettingButtons) )
+ {
+ // can't handle the change, recreate decorations then
+ recreateDecoration(plugin);
+ }
+ else
+ {
+ // handles the update, only update position...
+ positionPreviews();
+ }
+ }
+
+QRegion KDecorationPreview::unobscuredRegion( bool active, const QRegion& r ) const
+ {
+ if( active ) // this one is not obscured
+ return r;
+ else
+ {
+ // copied from KWin core's code
+ QRegion ret = r;
+ QRegion r2 = mask;
+ if( r2.isEmpty())
+ r2 = QRegion( windowGeometry( true ));
+ r2.translate( windowGeometry( true ).x() - windowGeometry( false ).x(),
+ windowGeometry( true ).y() - windowGeometry( false ).y());
+ ret -= r2;
+ return ret;
+ }
+ }
+
+KDecorationPreviewBridge::KDecorationPreviewBridge( KDecorationPreview* p, bool a )
+ : preview( p ), active( a )
+ {
+ }
+
+QWidget* KDecorationPreviewBridge::initialParentWidget() const
+ {
+ return preview;
+ }
+
+Qt::WFlags KDecorationPreviewBridge::initialWFlags() const
+ {
+ return 0;
+ }
+
+bool KDecorationPreviewBridge::isActive() const
+ {
+ return active;
+ }
+
+bool KDecorationPreviewBridge::isCloseable() const
+ {
+ return true;
+ }
+
+bool KDecorationPreviewBridge::isMaximizable() const
+ {
+ return true;
+ }
+
+KDecoration::MaximizeMode KDecorationPreviewBridge::maximizeMode() const
+ {
+ return KDecoration::MaximizeRestore;
+ }
+
+bool KDecorationPreviewBridge::isMinimizable() const
+ {
+ return true;
+ }
+
+bool KDecorationPreviewBridge::providesContextHelp() const
+ {
+ return true;
+ }
+
+int KDecorationPreviewBridge::desktop() const
+ {
+ return 1;
+ }
+
+bool KDecorationPreviewBridge::isModal() const
+ {
+ return false;
+ }
+
+bool KDecorationPreviewBridge::isShadeable() const
+ {
+ return true;
+ }
+
+bool KDecorationPreviewBridge::isShade() const
+ {
+ return false;
+ }
+
+bool KDecorationPreviewBridge::isSetShade() const
+ {
+ return false;
+ }
+
+bool KDecorationPreviewBridge::keepAbove() const
+ {
+ return false;
+ }
+
+bool KDecorationPreviewBridge::keepBelow() const
+ {
+ return false;
+ }
+
+bool KDecorationPreviewBridge::isMovable() const
+ {
+ return true;
+ }
+
+bool KDecorationPreviewBridge::isResizable() const
+ {
+ return true;
+ }
+
+NET::WindowType KDecorationPreviewBridge::windowType( unsigned long ) const
+ {
+ return NET::Normal;
+ }
+
+QIconSet KDecorationPreviewBridge::icon() const
+ {
+ return QIconSet( KGlobal::iconLoader()->loadIcon( "xapp", KIcon::NoGroup, 16 ),
+ KGlobal::iconLoader()->loadIcon( "xapp", KIcon::NoGroup, 32 ));
+ }
+
+QString KDecorationPreviewBridge::caption() const
+ {
+ return active ? i18n( "Active Window" ) : i18n( "Inactive Window" );
+ }
+
+void KDecorationPreviewBridge::processMousePressEvent( QMouseEvent* )
+ {
+ }
+
+void KDecorationPreviewBridge::showWindowMenu( const QRect &)
+ {
+ }
+
+void KDecorationPreviewBridge::showWindowMenu( QPoint )
+ {
+ }
+
+void KDecorationPreviewBridge::performWindowOperation( WindowOperation )
+ {
+ }
+
+void KDecorationPreviewBridge::setMask( const QRegion& reg, int mode )
+ {
+ preview->setPreviewMask( reg, mode, active );
+ }
+
+bool KDecorationPreviewBridge::isPreview() const
+ {
+ return true;
+ }
+
+QRect KDecorationPreviewBridge::geometry() const
+ {
+ return preview->windowGeometry( active );
+ }
+
+QRect KDecorationPreviewBridge::iconGeometry() const
+ {
+ return QRect();
+ }
+
+QRegion KDecorationPreviewBridge::unobscuredRegion( const QRegion& r ) const
+ {
+ return preview->unobscuredRegion( active, r );
+ }
+
+QWidget* KDecorationPreviewBridge::workspaceWidget() const
+ {
+ return preview;
+ }
+
+WId KDecorationPreviewBridge::windowId() const
+ {
+ return 0; // no decorated window
+ }
+
+void KDecorationPreviewBridge::closeWindow()
+ {
+ }
+
+void KDecorationPreviewBridge::maximize( MaximizeMode )
+ {
+ }
+
+void KDecorationPreviewBridge::minimize()
+ {
+ }
+
+void KDecorationPreviewBridge::showContextHelp()
+ {
+ }
+
+void KDecorationPreviewBridge::setDesktop( int )
+ {
+ }
+
+void KDecorationPreviewBridge::titlebarDblClickOperation()
+ {
+ }
+
+void KDecorationPreviewBridge::titlebarMouseWheelOperation( int )
+ {
+ }
+
+void KDecorationPreviewBridge::setShade( bool )
+ {
+ }
+
+void KDecorationPreviewBridge::setKeepAbove( bool )
+ {
+ }
+
+void KDecorationPreviewBridge::setKeepBelow( bool )
+ {
+ }
+
+int KDecorationPreviewBridge::currentDesktop() const
+ {
+ return 1;
+ }
+
+void KDecorationPreviewBridge::helperShowHide( bool )
+ {
+ }
+
+void KDecorationPreviewBridge::grabXServer( bool )
+ {
+ }
+
+KDecorationPreviewOptions::KDecorationPreviewOptions()
+ {
+ customBorderSize = BordersCount; // invalid
+ customButtonsChanged = false; // invalid
+ customButtons = true;
+ customTitleButtonsLeft = QString::null; // invalid
+ customTitleButtonsRight = QString::null; // invalid
+
+ d = new KDecorationOptionsPrivate;
+ d->defaultKWinSettings();
+ updateSettings();
+ }
+
+KDecorationPreviewOptions::~KDecorationPreviewOptions()
+ {
+ delete d;
+ }
+
+unsigned long KDecorationPreviewOptions::updateSettings()
+ {
+ KConfig cfg( "kwinrc", true );
+ unsigned long changed = 0;
+ changed |= d->updateKWinSettings( &cfg );
+
+ // set custom border size/buttons
+ if (customBorderSize != BordersCount)
+ d->border_size = customBorderSize;
+ if (customButtonsChanged)
+ d->custom_button_positions = customButtons;
+ if (customButtons) {
+ if (!customTitleButtonsLeft.isNull() )
+ d->title_buttons_left = customTitleButtonsLeft;
+ if (!customTitleButtonsRight.isNull() )
+ d->title_buttons_right = customTitleButtonsRight;
+ } else {
+ d->title_buttons_left = "MS";
+ d->title_buttons_right = "HIAX";
+ }
+
+ return changed;
+ }
+
+void KDecorationPreviewOptions::setCustomBorderSize(BorderSize size)
+ {
+ customBorderSize = size;
+
+ updateSettings();
+ }
+
+void KDecorationPreviewOptions::setCustomTitleButtonsEnabled(bool enabled)
+{
+ customButtonsChanged = true;
+ customButtons = enabled;
+
+ updateSettings();
+}
+
+void KDecorationPreviewOptions::setCustomTitleButtons(const QString &left, const QString &right)
+ {
+ customTitleButtonsLeft = left;
+ customTitleButtonsRight = right;
+
+ updateSettings();
+ }
+
+bool KDecorationPreviewPlugins::provides( Requirement )
+ {
+ return false;
+ }
+
+#include "preview.moc"
diff --git a/kwin/kcmkwin/kwindecoration/preview.h b/kwin/kcmkwin/kwindecoration/preview.h
new file mode 100644
index 000000000..1c1943486
--- /dev/null
+++ b/kwin/kcmkwin/kwindecoration/preview.h
@@ -0,0 +1,150 @@
+/*
+ *
+ * Copyright (c) 2003 Lubos Lunak <[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 KWINDECORATION_PREVIEW_H
+#define KWINDECORATION_PREVIEW_H
+
+#include <qwidget.h>
+#include <kdecoration_p.h>
+#include <kdecoration_plugins_p.h>
+
+class QLabel;
+
+class KDecorationPreviewBridge;
+class KDecorationPreviewOptions;
+
+class KDecorationPreview
+ : public QWidget
+ {
+ Q_OBJECT
+ public:
+ // Note: Windows can't be added or removed without making changes to
+ // the code, since parts of it assume there's just an active
+ // and an inactive window.
+ enum Windows { Inactive = 0, Active, NumWindows };
+
+ KDecorationPreview( QWidget* parent = NULL, const char* name = NULL );
+ virtual ~KDecorationPreview();
+ bool recreateDecoration( KDecorationPlugins* plugin );
+ void enablePreview();
+ void disablePreview();
+ void setPreviewMask( const QRegion&, int, bool );
+ QRegion unobscuredRegion( bool, const QRegion& ) const;
+ QRect windowGeometry( bool ) const;
+ void setTempBorderSize(KDecorationPlugins* plugin, KDecorationDefines::BorderSize size);
+ void setTempButtons(KDecorationPlugins* plugin, bool customEnabled, const QString &left, const QString &right);
+ protected:
+ virtual void resizeEvent( QResizeEvent* );
+ private:
+ void positionPreviews();
+ KDecorationPreviewOptions* options;
+ KDecorationPreviewBridge* bridge[NumWindows];
+ KDecoration* deco[NumWindows];
+ QLabel* no_preview;
+ QRegion mask;
+ };
+
+class KDecorationPreviewBridge
+ : public KDecorationBridge
+ {
+ public:
+ KDecorationPreviewBridge( KDecorationPreview* preview, bool active );
+ virtual bool isActive() const;
+ virtual bool isCloseable() const;
+ virtual bool isMaximizable() const;
+ virtual MaximizeMode maximizeMode() const;
+ virtual bool isMinimizable() const;
+ virtual bool providesContextHelp() const;
+ virtual int desktop() const;
+ virtual bool isModal() const;
+ virtual bool isShadeable() const;
+ virtual bool isShade() const;
+ virtual bool isSetShade() const;
+ virtual bool keepAbove() const;
+ virtual bool keepBelow() const;
+ virtual bool isMovable() const;
+ virtual bool isResizable() const;
+ virtual NET::WindowType windowType( unsigned long supported_types ) const;
+ virtual QIconSet icon() const;
+ virtual QString caption() const;
+ virtual void processMousePressEvent( QMouseEvent* );
+ virtual void showWindowMenu( const QRect &);
+ virtual void showWindowMenu( QPoint );
+ virtual void performWindowOperation( WindowOperation );
+ virtual void setMask( const QRegion&, int );
+ virtual bool isPreview() const;
+ virtual QRect geometry() const;
+ virtual QRect iconGeometry() const;
+ virtual QRegion unobscuredRegion( const QRegion& r ) const;
+ virtual QWidget* workspaceWidget() const;
+ virtual WId windowId() const;
+ virtual void closeWindow();
+ virtual void maximize( MaximizeMode mode );
+ virtual void minimize();
+ virtual void showContextHelp();
+ virtual void setDesktop( int desktop );
+ virtual void titlebarDblClickOperation();
+ virtual void titlebarMouseWheelOperation( int delta );
+ virtual void setShade( bool set );
+ virtual void setKeepAbove( bool );
+ virtual void setKeepBelow( bool );
+ virtual int currentDesktop() const;
+ virtual QWidget* initialParentWidget() const;
+ virtual Qt::WFlags initialWFlags() const;
+ virtual void helperShowHide( bool show );
+ virtual void grabXServer( bool grab );
+ private:
+ KDecorationPreview* preview;
+ bool active;
+ };
+
+class KDecorationPreviewOptions
+ : public KDecorationOptions
+ {
+ public:
+ KDecorationPreviewOptions();
+ virtual ~KDecorationPreviewOptions();
+ virtual unsigned long updateSettings();
+
+ void setCustomBorderSize(BorderSize size);
+ void setCustomTitleButtonsEnabled(bool enabled);
+ void setCustomTitleButtons(const QString &left, const QString &right);
+
+ private:
+ BorderSize customBorderSize;
+ bool customButtonsChanged;
+ bool customButtons;
+ QString customTitleButtonsLeft;
+ QString customTitleButtonsRight;
+ };
+
+class KDecorationPreviewPlugins
+ : public KDecorationPlugins
+ {
+ public:
+ KDecorationPreviewPlugins( KConfig* cfg );
+ virtual bool provides( Requirement );
+ };
+
+inline KDecorationPreviewPlugins::KDecorationPreviewPlugins( KConfig* cfg )
+ : KDecorationPlugins( cfg )
+ {
+ }
+
+#endif