kwin Library API Documentation

buttons.cpp

00001 /*
00002     This is the new kwindecoration kcontrol module
00003 
00004     Copyright (c) 2004,  Sandro Giessl <sandro@giessl.com>
00005     Copyright (c) 2001
00006         Karol Szwed <gallium@kde.org>
00007         http://gallium.n3.net/
00008 
00009     Supports new kwin configuration plugins, and titlebar button position
00010     modification via dnd interface.
00011 
00012     Based on original "kwintheme" (Window Borders)
00013     Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
00014 
00015     This program is free software; you can redistribute it and/or modify
00016     it under the terms of the GNU General Public License as published by
00017     the Free Software Foundation; either version 2 of the License, or
00018     (at your option) any later version.
00019   
00020     This program is distributed in the hope that it will be useful,
00021     but WITHOUT ANY WARRANTY; without even the implied warranty of
00022     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023     GNU General Public License for more details.
00024   
00025     You should have received a copy of the GNU General Public License
00026     along with this program; if not, write to the Free Software
00027     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00028 
00029 */
00030 
00031 #include <qheader.h>
00032 #include <qpainter.h>
00033 #include <qlabel.h>
00034 #include <qlayout.h>
00035 #include <qstyle.h>
00036 
00037 #include <kdebug.h>
00038 
00039 #include <kdialog.h>
00040 #include <klocale.h>
00041 #include <kglobalsettings.h>
00042 
00043 #include <kdecorationfactory.h>
00044 
00045 #include "buttons.h"
00046 #include "pixmaps.h"
00047 
00048 
00049 #define BUTTONDRAGMIMETYPE "application/x-kde_kwindecoration_buttons"
00050 ButtonDrag::ButtonDrag( Button btn, QWidget* parent, const char* name)
00051     : QStoredDrag( BUTTONDRAGMIMETYPE, parent, name)
00052 {
00053     QByteArray data;
00054     QDataStream stream(data, IO_WriteOnly);
00055     stream << btn.name;
00056     stream << btn.icon;
00057     stream << btn.type.unicode();
00058     stream << (int) btn.duplicate;
00059     stream << (int) btn.supported;
00060     setEncodedData( data );
00061 }
00062 
00063 
00064 bool ButtonDrag::canDecode( QDropEvent* e )
00065 {
00066     return e->provides( BUTTONDRAGMIMETYPE );
00067 }
00068 
00069 bool ButtonDrag::decode( QDropEvent* e, Button& btn )
00070 {
00071     QByteArray data = e->data( BUTTONDRAGMIMETYPE );
00072     if ( data.size() )
00073     {
00074         e->accept();
00075         QDataStream stream(data, IO_ReadOnly);
00076         stream >> btn.name;
00077         stream >> btn.icon;
00078         ushort type;
00079         stream >> type;
00080         btn.type = QChar(type);
00081         int duplicate;
00082         stream >> duplicate;
00083         btn.duplicate = duplicate;
00084         int supported;
00085         stream >> supported;
00086         btn.supported = supported;
00087         return TRUE;
00088     }
00089     return FALSE;
00090 }
00091 
00092 
00093 Button::Button()
00094 {
00095 }
00096 
00097 Button::Button(const QString& n, const QBitmap& i, QChar t, bool d, bool s)
00098     : name(n),
00099       icon(i),
00100       type(t),
00101       duplicate(d),
00102       supported(s)
00103 {
00104 }
00105 
00106 Button::~Button()
00107 {
00108 }
00109 
00110 // helper function to deal with the Button's bitmaps more easily...
00111 QPixmap bitmapPixmap(const QBitmap& bm, const QColor& color)
00112 {
00113     QPixmap pm(bm.size() );
00114     pm.setMask(bm);
00115     QPainter p(&pm);
00116     p.setPen(color);
00117     p.drawPixmap(0,0,bm);
00118     p.end();
00119     return pm;
00120 }
00121 
00122 
00123 ButtonSource::ButtonSource(QWidget *parent, const char* name)
00124     : KListView(parent, name)
00125 {
00126     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00127 
00128     setResizeMode(QListView::AllColumns);
00129     setDragEnabled(true);
00130     setAcceptDrops(true);
00131     setDropVisualizer(false);
00132     setSorting(-1);
00133     header()->setClickEnabled(false);
00134     header()->hide();
00135 
00136     addColumn(i18n("Buttons") );
00137 }
00138 
00139 ButtonSource::~ButtonSource()
00140 {
00141 }
00142 
00143 QSize ButtonSource::sizeHint() const
00144 {
00145     // make the sizeHint height a bit smaller than the one of QListView...
00146 
00147     if ( cachedSizeHint().isValid() )
00148         return cachedSizeHint();
00149 
00150     constPolish();
00151 
00152     QSize s( header()->sizeHint() );
00153 
00154     if ( verticalScrollBar()->isVisible() )
00155         s.setWidth( s.width() + style().pixelMetric(QStyle::PM_ScrollBarExtent) );
00156     s += QSize(frameWidth()*2,frameWidth()*2);
00157 
00158     // size hint: 4 lines of text...
00159     s.setHeight( s.height() + fontMetrics().lineSpacing()*3 );
00160 
00161     setCachedSizeHint( s );
00162 
00163     return s;
00164 }
00165 
00166 void ButtonSource::hideAllButtons()
00167 {
00168     QListViewItemIterator it(this);
00169     while (it.current() ) {
00170         it.current()->setVisible(false);
00171         ++it;
00172     }
00173 }
00174 
00175 void ButtonSource::showAllButtons()
00176 {
00177     QListViewItemIterator it(this);
00178     while (it.current() ) {
00179         it.current()->setVisible(true);
00180         ++it;
00181     }
00182 }
00183 
00184 void ButtonSource::showButton( QChar btn )
00185 {
00186     QListViewItemIterator it(this);
00187     while (it.current() ) {
00188         ButtonSourceItem *item = dynamic_cast<ButtonSourceItem*>(it.current() );
00189         if (item && item->button().type == btn) {
00190             it.current()->setVisible(true);
00191             return;
00192         }
00193         ++it;
00194     }
00195 }
00196 
00197 void ButtonSource::hideButton( QChar btn )
00198 {
00199     QListViewItemIterator it(this);
00200     while (it.current() ) {
00201         ButtonSourceItem *item = dynamic_cast<ButtonSourceItem*>(it.current() );
00202         if (item && item->button().type == btn && !item->button().duplicate) {
00203             it.current()->setVisible(false);
00204             return;
00205         }
00206         ++it;
00207     }
00208 }
00209 
00210 bool ButtonSource::acceptDrag(QDropEvent* e) const
00211 {
00212     return acceptDrops() && ButtonDrag::canDecode(e);
00213 }
00214 
00215 QDragObject *ButtonSource::dragObject()
00216 {
00217     ButtonSourceItem *i = dynamic_cast<ButtonSourceItem*>(selectedItem() );
00218 
00219     if (i) {
00220         ButtonDrag *bd = new ButtonDrag(i->button(), viewport(), "button_drag");
00221         bd->setPixmap(bitmapPixmap(i->button().icon, colorGroup().foreground() ));
00222         return bd;
00223     }
00224 
00225     return 0;
00226 }
00227 
00228 ButtonDropSiteItem::ButtonDropSiteItem(const Button& btn)
00229     : m_button(btn)
00230 {
00231 }
00232 
00233 ButtonDropSiteItem::~ButtonDropSiteItem()
00234 {
00235 }
00236 
00237 Button ButtonDropSiteItem::button()
00238 {
00239     return m_button;
00240 }
00241 
00242 int ButtonDropSiteItem::width()
00243 {
00244 //  return m_button.icon.width();
00245     return 20;
00246 }
00247 
00248 int ButtonDropSiteItem::height()
00249 {
00250 //  return m_button.icon.height();
00251     return 20;
00252 }
00253 
00254 void ButtonDropSiteItem::draw(QPainter *p, const QColorGroup& cg, QRect r)
00255 {
00256 //  p->fillRect(r, cg.base() );
00257     if (m_button.supported)
00258         p->setPen(cg.foreground() );
00259     else
00260         p->setPen(cg.mid() );
00261     QBitmap &i = m_button.icon;
00262     p->drawPixmap(r.left()+(r.width()-i.width())/2, r.top()+(r.height()-i.height())/2, i);
00263 }
00264 
00265 
00266 ButtonDropSite::ButtonDropSite( QWidget* parent, const char* name )
00267     : QFrame( parent, name ),
00268       m_selected(0)
00269 {
00270     setAcceptDrops( TRUE );
00271     setFrameShape( WinPanel );
00272     setFrameShadow( Raised );
00273     setMinimumHeight( 26 );
00274     setMaximumHeight( 26 );
00275     setMinimumWidth( 250 );     // Ensure buttons will fit
00276 }
00277 
00278 ButtonDropSite::~ButtonDropSite()
00279 {
00280     clearLeft();
00281     clearRight();
00282 }
00283 
00284 void ButtonDropSite::clearLeft()
00285 {
00286     while (!buttonsLeft.isEmpty() ) {
00287         ButtonDropSiteItem *item = buttonsLeft.first();
00288         if (removeButton(item) ) {
00289             emit buttonRemoved(item->button().type);
00290             delete item;
00291         }
00292     }
00293 }
00294 
00295 void ButtonDropSite::clearRight()
00296 {
00297     while (!buttonsRight.isEmpty() ) {
00298         ButtonDropSiteItem *item = buttonsRight.first();
00299         if (removeButton(item) ) {
00300             emit buttonRemoved(item->button().type);
00301             delete item;
00302         }
00303     }
00304 }
00305 
00306 void ButtonDropSite::dragMoveEvent( QDragMoveEvent* e )
00307 {
00308     QPoint p = e->pos();
00309     if (leftDropArea().contains(p) || rightDropArea().contains(p) || buttonAt(p) ) {
00310         e->accept();
00311 
00312         // 2 pixel wide drop visualizer...
00313         QRect r = contentsRect();
00314         int x = -1;
00315         if (leftDropArea().contains(p) ) {
00316             x = leftDropArea().left();
00317         } else if (rightDropArea().contains(p) ) {
00318             x = rightDropArea().right()+1;
00319         } else {
00320             ButtonDropSiteItem *item = buttonAt(p);
00321             if (item) {
00322                 if (p.x() < item->rect.left()+item->rect.width()/2 ) {
00323                     x = item->rect.left();
00324                 } else {
00325                     x = item->rect.right()+1;
00326                 }
00327             }
00328         }
00329         if (x != -1) {
00330             QRect tmpRect(x, r.y(), 2, r.height() );
00331             if (tmpRect != m_oldDropVisualizer) {
00332                 cleanDropVisualizer();
00333                 m_oldDropVisualizer = tmpRect;
00334                 update(tmpRect);
00335             }
00336         }
00337 
00338     } else {
00339         e->ignore();
00340 
00341         cleanDropVisualizer();
00342     }
00343 }
00344 
00345 void ButtonDropSite::cleanDropVisualizer()
00346 {
00347     if (m_oldDropVisualizer.isValid())
00348     {
00349         QRect rect = m_oldDropVisualizer;
00350         m_oldDropVisualizer = QRect(); // rect is invalid
00351         update(rect);
00352     }
00353 }
00354 
00355 void ButtonDropSite::dragEnterEvent( QDragEnterEvent* e )
00356 {
00357     if ( ButtonDrag::canDecode( e ) )
00358         e->accept();
00359 }
00360 
00361 void ButtonDropSite::dragLeaveEvent( QDragLeaveEvent* /* e */ )
00362 {
00363     cleanDropVisualizer();
00364 }
00365 
00366 void ButtonDropSite::dropEvent( QDropEvent* e )
00367 {
00368     cleanDropVisualizer();
00369 
00370     QPoint p = e->pos();
00371 
00372     // collect information where to insert the dropped button
00373     ButtonList *buttonList = 0;
00374     ButtonList::iterator buttonPosition;
00375 
00376     if (leftDropArea().contains(p) ) {
00377         buttonList = &buttonsLeft;
00378         buttonPosition = buttonsLeft.end();
00379     } else if (rightDropArea().contains(p) ) {
00380         buttonList = &buttonsRight;
00381         buttonPosition = buttonsRight.begin();
00382     } else {
00383         ButtonDropSiteItem *aboveItem = buttonAt(p);
00384         if (!aboveItem)
00385             return; // invalid drop. hasn't occured _over_ a button (or left/right dropArea), return...
00386 
00387         ButtonList::iterator it;
00388         if (!getItemIterator(aboveItem, buttonList, it) ) {
00389             // didn't find the aboveItem. unlikely to happen since buttonAt() already seems to have found
00390             // something valid. anyway...
00391             return;
00392         }
00393 
00394         // got the list and the aboveItem position. now determine if the item should be inserted
00395         // before aboveItem or after aboveItem.
00396         QRect aboveItemRect = aboveItem->rect;
00397         if (!aboveItemRect.isValid() )
00398             return;
00399 
00400         if (p.x() < aboveItemRect.left()+aboveItemRect.width()/2 ) {
00401             // insert before the item
00402             buttonPosition = it;
00403         } else {
00404             if (it != buttonList->end() )
00405                 buttonPosition = ++it;
00406             else
00407                 buttonPosition = it; // already at the end(), can't increment the iterator!
00408         }
00409     }
00410 
00411     // know where to insert the button. now see if we can use an existing item (drag within the widget = move)
00412     // orneed to create a new one
00413     ButtonDropSiteItem *buttonItem = 0;
00414     if (e->source() == this && m_selected) {
00415         ButtonList *oldList = 0;
00416         ButtonList::iterator oldPos;
00417         if (getItemIterator(m_selected, oldList, oldPos) ) {
00418             if (oldPos == buttonPosition)
00419                 return; // button didn't change its position during the drag...
00420 
00421             oldList->remove(oldPos);
00422             buttonItem = m_selected;
00423         } else {
00424             return; // m_selected not found, return...
00425         }
00426     } else {
00427         // create new button from the drop object...
00428         Button btn;
00429         if (ButtonDrag::decode(e, btn) ) {
00430             buttonItem = new ButtonDropSiteItem(btn);
00431         } else {
00432             return; // something has gone wrong while we were trying to decode the drop event
00433         }
00434     }
00435 
00436     // now the item can actually be inserted into the list! :)
00437     (*buttonList).insert(buttonPosition, buttonItem);
00438     emit buttonAdded(buttonItem->button().type);
00439     emit changed();
00440     recalcItemGeometry();
00441     update();
00442 }
00443 
00444 bool ButtonDropSite::getItemIterator(ButtonDropSiteItem *item, ButtonList* &list, ButtonList::iterator &iterator)
00445 {
00446     if (!item)
00447         return false;
00448 
00449     ButtonList::iterator it = buttonsLeft.find(item); // try the left list first...
00450     if (it == buttonsLeft.end() ) {
00451         it = buttonsRight.find(item); // try the right list...
00452         if (it == buttonsRight.end() ) {
00453             return false; // item hasn't been found in one of the list, return...
00454         } else {
00455             list = &buttonsRight;
00456             iterator = it;
00457         }
00458     } else {
00459         list = &buttonsLeft;
00460         iterator = it;
00461     }
00462 
00463     return true;
00464 }
00465 
00466 QRect ButtonDropSite::leftDropArea()
00467 {
00468     // return a 10 pixel drop area...
00469     QRect r = contentsRect();
00470 
00471     int leftButtonsWidth = calcButtonListWidth(buttonsLeft);
00472     return QRect(r.left()+leftButtonsWidth, r.top(), 10, r.height() );
00473 }
00474 
00475 QRect ButtonDropSite::rightDropArea()
00476 {
00477     // return a 10 pixel drop area...
00478     QRect r = contentsRect();
00479 
00480     int rightButtonsWidth = calcButtonListWidth(buttonsRight);
00481     return QRect(r.right()-rightButtonsWidth-10, r.top(), 10, r.height() );
00482 }
00483 
00484 void ButtonDropSite::mousePressEvent( QMouseEvent* e )
00485 {
00486     // TODO: only start the real drag after some drag distance
00487     m_selected = buttonAt(e->pos() );
00488     if (m_selected) {
00489         ButtonDrag *bd = new ButtonDrag(m_selected->button(), this);
00490         bd->setPixmap(bitmapPixmap(m_selected->button().icon, colorGroup().foreground() ) );
00491         bd->dragMove();
00492     }
00493 }
00494 
00495 void ButtonDropSite::resizeEvent(QResizeEvent*)
00496 {
00497     recalcItemGeometry();
00498 }
00499 
00500 void ButtonDropSite::recalcItemGeometry()
00501 {
00502     QRect r = contentsRect();
00503 
00504     // update the geometry of the items in the left button list
00505     int offset = r.left();
00506     for (ButtonList::const_iterator it = buttonsLeft.begin(); it != buttonsLeft.end(); ++it) {
00507         int w = (*it)->width();
00508         (*it)->rect = QRect(offset, r.top(), w, (*it)->height() );
00509         offset += w;
00510     }
00511 
00512     // the right button list...
00513     offset = r.right() - calcButtonListWidth(buttonsRight);
00514     for (ButtonList::const_iterator it = buttonsRight.begin(); it != buttonsRight.end(); ++it) {
00515         int w = (*it)->width();
00516         (*it)->rect = QRect(offset, r.top(), w, (*it)->height() );
00517         offset += w;
00518     }
00519 }
00520 
00521 ButtonDropSiteItem *ButtonDropSite::buttonAt(QPoint p) {
00522     // try to find the item in the left button list
00523     for (ButtonList::const_iterator it = buttonsLeft.begin(); it != buttonsLeft.end(); ++it) {
00524         if ( (*it)->rect.contains(p) ) {
00525             return *it;
00526         }
00527     }
00528 
00529     // try to find the item in the right button list
00530     for (ButtonList::const_iterator it = buttonsRight.begin(); it != buttonsRight.end(); ++it) {
00531         if ( (*it)->rect.contains(p) ) {
00532             return *it;
00533         }
00534     }
00535 
00536     return 0;
00537 }
00538 
00539 bool ButtonDropSite::removeButton(ButtonDropSiteItem *item) {
00540     if (!item)
00541         return false;
00542 
00543     // try to remove the item from the left button list
00544     if (buttonsLeft.remove(item) >= 1) {
00545         return true;
00546     }
00547 
00548     // try to remove the item from the right button list
00549     if (buttonsRight.remove(item) >= 1) {
00550         return true;
00551     }
00552 
00553     return false;
00554 }
00555 
00556 int ButtonDropSite::calcButtonListWidth(const ButtonList& btns)
00557 {
00558     int w = 0;
00559     for (ButtonList::const_iterator it = btns.begin(); it != btns.end(); ++it) {
00560         w += (*it)->width();
00561     }
00562 
00563     return w;
00564 }
00565 
00566 bool ButtonDropSite::removeSelectedButton()
00567 {
00568     bool succ = removeButton(m_selected);
00569     if (succ) {
00570         emit buttonRemoved(m_selected->button().type);
00571         emit changed();
00572         delete m_selected;
00573         m_selected = 0;
00574         recalcItemGeometry();
00575         update(); // repaint...
00576     }
00577 
00578     return succ;
00579 }
00580 
00581 void ButtonDropSite::drawButtonList(QPainter *p, const ButtonList& btns, int offset)
00582 {
00583     for (ButtonList::const_iterator it = btns.begin(); it != btns.end(); ++it) {
00584         QRect itemRect = (*it)->rect;
00585         if (itemRect.isValid() ) {
00586             (*it)->draw(p, colorGroup(), itemRect);
00587         }
00588         offset += (*it)->width();
00589     }
00590 }
00591 
00592 void ButtonDropSite::drawContents( QPainter* p )
00593 {
00594     int leftoffset = calcButtonListWidth( buttonsLeft );
00595     int rightoffset = calcButtonListWidth( buttonsRight );
00596     int offset = 3;
00597 
00598     QRect r = contentsRect();
00599 
00600     // Shrink by 1
00601     r.moveBy(1 + leftoffset, 1);
00602     r.setWidth( r.width() - 2 - leftoffset - rightoffset );
00603     r.setHeight( r.height() - 2 );
00604 
00605     drawButtonList( p, buttonsLeft, offset );
00606 
00607     QColor c1( 0x0A, 0x5F, 0x89 );      // KDE 2 titlebar default colour
00608     p->fillRect( r, c1 );
00609     p->setPen( Qt::white );
00610     p->setFont( QFont( KGlobalSettings::generalFont().family(), 12, QFont::Bold) );
00611     p->drawText( r, AlignLeft | AlignVCenter, i18n("KDE") );
00612 
00613     offset = geometry().width() - 3 - rightoffset;
00614     drawButtonList( p, buttonsRight, offset );
00615 
00616     if (m_oldDropVisualizer.isValid() )
00617     {
00618         p->fillRect(m_oldDropVisualizer, Dense4Pattern);
00619     }
00620 }
00621 
00622 ButtonSourceItem::ButtonSourceItem(QListView * parent, const Button& btn)
00623     : QListViewItem(parent),
00624       m_button(btn),
00625       m_dirty(true)
00626 {
00627     setButton(btn);
00628 }
00629 
00630 ButtonSourceItem::~ButtonSourceItem()
00631 {
00632 }
00633 
00634 void ButtonSourceItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align)
00635 {
00636     // we need the color group cg, so to the work here, not in setButton...
00637     if (m_dirty) {
00638         if (m_button.supported) {
00639             setPixmap(0, bitmapPixmap(m_button.icon, cg.foreground() ) );
00640         } else {
00641             setPixmap(0, bitmapPixmap(m_button.icon, cg.mid() ) );
00642         }
00643         m_dirty = false;
00644     }
00645 
00646     if (m_button.supported) {
00647         QListViewItem::paintCell(p,cg,column,width,align);
00648     } else {
00649         // grey out unsupported buttons
00650         QColorGroup cg2 = cg;
00651         cg2.setColor(QColorGroup::Text, cg.mid() );
00652         QListViewItem::paintCell(p,cg2,column,width,align);
00653     }
00654 }
00655 
00656 void ButtonSourceItem::setButton(const Button& btn)
00657 {
00658     m_button = btn;
00659     m_dirty = true; // update the pixmap when in paintCell()...
00660     if (btn.supported) {
00661         setText(0, btn.name);
00662     } else {
00663         setText(0, i18n("%1 (unavailable)").arg(btn.name) );
00664     }
00665 }
00666 
00667 Button ButtonSourceItem::button() const
00668 {
00669     return m_button;
00670 }
00671 
00672 
00673 ButtonPositionWidget::ButtonPositionWidget(QWidget *parent, const char* name)
00674     : QWidget(parent,name),
00675       m_factory(0)
00676 {
00677     QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() );
00678     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
00679 
00680     QLabel* label = new QLabel( this );
00681     m_dropSite = new ButtonDropSite( this );
00682     label->setAlignment( int( QLabel::WordBreak ) );
00683     label->setText( i18n( "To add or remove titlebar buttons, simply <i>drag</i> items "
00684         "between the available item list and the titlebar preview. Similarly, "
00685         "drag items within the titlebar preview to re-position them.") );
00686     m_buttonSource = new ButtonSource(this, "button_source");
00687 
00688     layout->addWidget(label);
00689     layout->addWidget(m_dropSite);
00690     layout->addWidget(m_buttonSource);
00691 
00692     connect( m_dropSite, SIGNAL(buttonAdded(QChar)), m_buttonSource, SLOT(hideButton(QChar)) );
00693     connect( m_dropSite, SIGNAL(buttonRemoved(QChar)), m_buttonSource, SLOT(showButton(QChar)) );
00694     connect( m_buttonSource, SIGNAL(dropped(QDropEvent*, QListViewItem*)), m_dropSite, SLOT(removeSelectedButton()) );
00695 
00696     connect( m_dropSite, SIGNAL(changed()), SIGNAL(changed()) );
00697 
00698     // insert all possible buttons into the source (backwards to keep the preferred order...)
00699     bool dummy;
00700     new ButtonSourceItem(m_buttonSource, getButton('R', dummy) );
00701     new ButtonSourceItem(m_buttonSource, getButton('L', dummy) );
00702     new ButtonSourceItem(m_buttonSource, getButton('B', dummy) );
00703     new ButtonSourceItem(m_buttonSource, getButton('F', dummy) );
00704     new ButtonSourceItem(m_buttonSource, getButton('X', dummy) );
00705     new ButtonSourceItem(m_buttonSource, getButton('A', dummy) );
00706     new ButtonSourceItem(m_buttonSource, getButton('I', dummy) );
00707     new ButtonSourceItem(m_buttonSource, getButton('H', dummy) );
00708     new ButtonSourceItem(m_buttonSource, getButton('S', dummy) );
00709     new ButtonSourceItem(m_buttonSource, getButton('M', dummy) );
00710     new ButtonSourceItem(m_buttonSource, getButton('_', dummy) );
00711 }
00712 
00713 ButtonPositionWidget::~ButtonPositionWidget()
00714 {
00715 }
00716 
00717 void ButtonPositionWidget::setDecorationFactory(KDecorationFactory *factory)
00718 {
00719     if (!factory)
00720         return;
00721 
00722     m_factory = factory;
00723 
00724     // get the list of supported buttons
00725     if (m_factory->supports(KDecorationDefines::AbilityAnnounceButtons) ) {
00726         QString supportedButtons;
00727 
00728         if (m_factory->supports(KDecorationDefines::AbilityButtonMenu) )
00729             supportedButtons.append('M');
00730         if (m_factory->supports(KDecorationDefines::AbilityButtonOnAllDesktops) )
00731             supportedButtons.append('S');
00732         if (m_factory->supports(KDecorationDefines::AbilityButtonSpacer) )
00733             supportedButtons.append('_');
00734         if (m_factory->supports(KDecorationDefines::AbilityButtonHelp) )
00735             supportedButtons.append('H');
00736         if (m_factory->supports(KDecorationDefines::AbilityButtonMinimize) )
00737             supportedButtons.append('I');
00738         if (m_factory->supports(KDecorationDefines::AbilityButtonMaximize) )
00739             supportedButtons.append('A');
00740         if (m_factory->supports(KDecorationDefines::AbilityButtonClose) )
00741             supportedButtons.append('X');
00742         if (m_factory->supports(KDecorationDefines::AbilityButtonAboveOthers) )
00743             supportedButtons.append('F');
00744         if (m_factory->supports(KDecorationDefines::AbilityButtonBelowOthers) )
00745             supportedButtons.append('B');
00746         if (m_factory->supports(KDecorationDefines::AbilityButtonShade) )
00747             supportedButtons.append('L');
00748         if (m_factory->supports(KDecorationDefines::AbilityButtonResize) )
00749             supportedButtons.append('R');
00750 
00751         m_supportedButtons = supportedButtons;
00752     } else {
00753         // enable all buttons!
00754         m_supportedButtons = "RLBFXAIHSM_";
00755     }
00756 
00757     // update the button lists...
00758     // 1. set status on the source items...
00759     QListViewItemIterator it(m_buttonSource);
00760     while (it.current() ) {
00761         ButtonSourceItem *i = dynamic_cast<ButtonSourceItem*>(it.current() );
00762         if (i) {
00763             Button b = i->button();
00764             b.supported = m_supportedButtons.contains(b.type);
00765             i->setButton(b);
00766         }
00767         ++it;
00768     }
00769     // 2. rebuild the drop site items...
00770     setButtonsLeft(buttonsLeft() );
00771     setButtonsRight(buttonsRight() );
00772 }
00773 
00774 Button ButtonPositionWidget::getButton(QChar type, bool& success) {
00775     success = true;
00776 
00777     if (type == 'R') {
00778         QBitmap bmp(resize_width, resize_height, resize_bits, true);
00779         bmp.setMask(bmp);
00780         return Button(i18n("Resize"), bmp, 'R', false, m_supportedButtons.contains('R') );
00781     } else if (type == 'L') {
00782         QBitmap bmp(shade_width, shade_height, shade_bits, true);
00783         bmp.setMask(bmp);
00784         return Button(i18n("Shade"), bmp, 'L', false, m_supportedButtons.contains('L') );
00785     } else if (type == 'B') {
00786         QBitmap bmp(keepbelowothers_width, keepbelowothers_height, keepbelowothers_bits, true);
00787         bmp.setMask(bmp);
00788         return Button(i18n("Keep Below Others"), bmp, 'B', false, m_supportedButtons.contains('B') );
00789     } else if (type == 'F') {
00790         QBitmap bmp(keepaboveothers_width, keepaboveothers_height, keepaboveothers_bits, true);
00791         bmp.setMask(bmp);
00792         return Button(i18n("Keep Above Others"), bmp, 'F', false, m_supportedButtons.contains('F') );
00793     } else if (type == 'X') {
00794         QBitmap bmp(close_width, close_height, close_bits, true);
00795         bmp.setMask(bmp);
00796         return Button(i18n("Close"), bmp, 'X', false,  m_supportedButtons.contains('X') );
00797     } else if (type == 'A') {
00798         QBitmap bmp(maximize_width, maximize_height, maximize_bits, true);
00799         bmp.setMask(bmp);
00800         return Button(i18n("Maximize"), bmp, 'A', false, m_supportedButtons.contains('A') );
00801     } else if (type == 'I') {
00802         QBitmap bmp(minimize_width, minimize_height, minimize_bits, true);
00803         bmp.setMask(bmp);
00804         return Button(i18n("Minimize"), bmp, 'I', false, m_supportedButtons.contains('I') );
00805     } else if (type == 'H') {
00806         QBitmap bmp(help_width, help_height, help_bits, true);
00807         bmp.setMask(bmp);
00808         return Button(i18n("Help"), bmp, 'H', false, m_supportedButtons.contains('H') );
00809     } else if (type == 'S') {
00810         QBitmap bmp(onalldesktops_width, onalldesktops_height, onalldesktops_bits, true);
00811         bmp.setMask(bmp);
00812         return Button(i18n("On All Desktops"), bmp, 'S', false, m_supportedButtons.contains('S') );
00813     } else if (type == 'M') {
00814         QBitmap bmp(menu_width, menu_height, menu_bits, true);
00815         bmp.setMask(bmp);
00816         return Button(i18n("Menu"), bmp, 'M', false, m_supportedButtons.contains('M') );
00817     } else if (type == '_') {
00818         QBitmap bmp(spacer_width, spacer_height, spacer_bits, true);
00819         bmp.setMask(bmp);
00820         return Button(i18n("--- spacer ---"), bmp, '_', true, m_supportedButtons.contains('_') );
00821     } else {
00822         return Button();
00823         success = false;
00824     }
00825 }
00826 
00827 QString ButtonPositionWidget::buttonsLeft() const
00828 {
00829     ButtonList btns = m_dropSite->buttonsLeft;
00830     QString btnString = "";
00831     for (ButtonList::const_iterator it = btns.begin(); it != btns.end(); ++it) {
00832         btnString.append( (*it)->button().type );
00833     }
00834     return btnString;
00835 }
00836 
00837 QString ButtonPositionWidget::buttonsRight() const
00838 {
00839     ButtonList btns = m_dropSite->buttonsRight;
00840     QString btnString = "";
00841     for (ButtonList::const_iterator it = btns.begin(); it != btns.end(); ++it) {
00842         btnString.append( (*it)->button().type );
00843     }
00844     return btnString;
00845 }
00846 
00847 void ButtonPositionWidget::setButtonsLeft(const QString &buttons)
00848 {
00849     // to keep the button lists consistent, first remove all left buttons, then add buttons again...
00850     m_dropSite->clearLeft();
00851 
00852     for (uint i = 0; i < buttons.length(); ++i) {
00853         bool succ = false;
00854         Button btn = getButton(buttons[i], succ);
00855         if (succ) {
00856             m_dropSite->buttonsLeft.append(new ButtonDropSiteItem(btn) );
00857             m_buttonSource->hideButton(btn.type);
00858         }
00859     }
00860     m_dropSite->recalcItemGeometry();
00861     m_dropSite->update();
00862 }
00863     
00864 void ButtonPositionWidget::setButtonsRight(const QString &buttons)
00865 {
00866     // to keep the button lists consistent, first remove all left buttons, then add buttons again...
00867     m_dropSite->clearRight();
00868 
00869     for (uint i = 0; i < buttons.length(); ++i) {
00870         bool succ = false;
00871         Button btn = getButton(buttons[i], succ);
00872         if (succ) {
00873             m_dropSite->buttonsRight.append(new ButtonDropSiteItem(btn) );
00874             m_buttonSource->hideButton(btn.type);
00875         }
00876     }
00877     m_dropSite->recalcItemGeometry();
00878     m_dropSite->update();
00879 }
00880 
00881 #include "buttons.moc"
00882 // vim: ts=4
00883 // kate: space-indent off; tab-width 4;
KDE Logo
This file is part of the documentation for kwin Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Jun 13 19:28:00 2006 by doxygen 1.4.3 written by Dimitri van Heesch, © 1997-2003