diff options
Diffstat (limited to 'kwin/kcmkwin/kwindecoration')
-rw-r--r-- | kwin/kcmkwin/kwindecoration/Makefile.am | 18 | ||||
-rw-r--r-- | kwin/kcmkwin/kwindecoration/buttons.cpp | 883 | ||||
-rw-r--r-- | kwin/kcmkwin/kwindecoration/buttons.h | 227 | ||||
-rw-r--r-- | kwin/kcmkwin/kwindecoration/kwindecoration.cpp | 613 | ||||
-rw-r--r-- | kwin/kcmkwin/kwindecoration/kwindecoration.desktop | 231 | ||||
-rw-r--r-- | kwin/kcmkwin/kwindecoration/kwindecoration.h | 135 | ||||
-rw-r--r-- | kwin/kcmkwin/kwindecoration/kwindecorationIface.h | 44 | ||||
-rw-r--r-- | kwin/kcmkwin/kwindecoration/pixmaps.h | 110 | ||||
-rw-r--r-- | kwin/kcmkwin/kwindecoration/preview.cpp | 507 | ||||
-rw-r--r-- | kwin/kcmkwin/kwindecoration/preview.h | 150 |
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 <sandro@giessl.com> + Copyright (c) 2001 + Karol Szwed <gallium@kde.org> + 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) <rik@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#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 <sandro@giessl.com> + Copyright (c) 2001 + Karol Szwed <gallium@kde.org> + 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) <rik@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#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 <gallium@kde.org> + 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) <rik@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#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, "gallium@kde.org"); + 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 <gallium@kde.org> + 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) <rik@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#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) <karlmail@usa.net> + 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) <rik@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#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 <sandro@giessl.com> + Copyright (c) 2001 + Karol Szwed <gallium@kde.org> + 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) <rik@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +// 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 <l.lunak@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#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 <l.lunak@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#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 |