00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "kcommondecoration.h"
00026 #include "kcommondecoration_p.h"
00027
00028 #include <QApplication>
00029 #include <QCursor>
00030 #include <QDateTime>
00031 #include <QLabel>
00032
00033 #include <QWidget>
00034
00035 #include <kdebug.h>
00036
00037 #include <kapplication.h>
00038 #include "kdecorationfactory.h"
00039 #include <klocale.h>
00040
00041 #include <kephal/screens.h>
00042
00043 #include "kcommondecoration.moc"
00044
00048 KCommonDecoration::KCommonDecoration(KDecorationBridge* bridge, KDecorationFactory* factory)
00049 : m_previewWidget(0),
00050 btnHideMinWidth(200),
00051 btnHideLastWidth(0),
00052 closing(false),
00053 wrapper( new KCommonDecorationWrapper( this, bridge, factory ))
00054
00055 {
00056
00057 memset(m_button, 0, sizeof(KCommonDecorationButton *) * NumButtons);
00058 connect( wrapper, SIGNAL( keepAboveChanged( bool )), this, SIGNAL( keepAboveChanged( bool )));
00059 connect( wrapper, SIGNAL( keepBelowChanged( bool )), this, SIGNAL( keepBelowChanged( bool )));
00060 }
00061
00062 KCommonDecoration::~KCommonDecoration()
00063 {
00064 for (int n=0; n<NumButtons; n++) {
00065 if (m_button[n]) delete m_button[n];
00066 }
00067 delete m_previewWidget;
00068
00069 }
00070
00071 QString KCommonDecoration::defaultButtonsLeft() const
00072 {
00073 return KDecorationOptions::defaultTitleButtonsLeft();
00074 }
00075
00076 QString KCommonDecoration::defaultButtonsRight() const
00077 {
00078 return KDecorationOptions::defaultTitleButtonsRight();
00079 }
00080
00081 bool KCommonDecoration::decorationBehaviour(DecorationBehaviour behaviour) const
00082 {
00083 switch (behaviour) {
00084 case DB_MenuClose:
00085 return false;
00086
00087 case DB_WindowMask:
00088 return false;
00089
00090 case DB_ButtonHide:
00091 return true;
00092 }
00093
00094 return false;
00095 }
00096
00097 int KCommonDecoration::layoutMetric(LayoutMetric lm, bool respectWindowState, const KCommonDecorationButton *button) const
00098 {
00099 switch (lm) {
00100 case LM_BorderLeft:
00101 case LM_BorderRight:
00102 case LM_BorderBottom:
00103 case LM_TitleEdgeTop:
00104 case LM_TitleEdgeBottom:
00105 case LM_TitleEdgeLeft:
00106 case LM_TitleEdgeRight:
00107 case LM_TitleBorderLeft:
00108 case LM_TitleBorderRight:
00109 return 5;
00110
00111
00112 case LM_ButtonWidth:
00113 case LM_ButtonHeight:
00114 case LM_TitleHeight:
00115 return 20;
00116
00117 case LM_ButtonSpacing:
00118 return 5;
00119
00120 case LM_ButtonMarginTop:
00121 return 0;
00122
00123 case LM_ExplicitButtonSpacer:
00124 return layoutMetric(LM_ButtonWidth, respectWindowState, button )/2;
00125
00126 default:
00127 return 0;
00128 }
00129 }
00130
00131 void KCommonDecoration::init()
00132 {
00133 createMainWidget();
00134
00135
00136 widget()->setAttribute(Qt::WA_NoSystemBackground);
00137
00138 widget()->installEventFilter( this );
00139
00140 resetLayout();
00141
00142 connect(this, SIGNAL(keepAboveChanged(bool) ), SLOT(keepAboveChange(bool) ) );
00143 connect(this, SIGNAL(keepBelowChanged(bool) ), SLOT(keepBelowChange(bool) ) );
00144
00145 updateCaption();
00146 }
00147
00148 void KCommonDecoration::reset( unsigned long changed )
00149 {
00150 if (changed & SettingButtons) {
00151 resetLayout();
00152 widget()->update();
00153 }
00154 }
00155
00156 QRegion KCommonDecoration::cornerShape(WindowCorner)
00157 {
00158 return QRegion();
00159 }
00160
00161 void KCommonDecoration::updateCaption()
00162 {
00163
00164 widget()->update();
00165 }
00166
00167 void KCommonDecoration::borders( int& left, int& right, int& top, int& bottom ) const
00168 {
00169 left = layoutMetric(LM_BorderLeft);
00170 right = layoutMetric(LM_BorderRight);
00171 bottom = layoutMetric(LM_BorderBottom);
00172 top = layoutMetric(LM_TitleHeight) +
00173 layoutMetric(LM_TitleEdgeTop) +
00174 layoutMetric(LM_TitleEdgeBottom);
00175
00176 updateLayout();
00177 }
00178
00179 void KCommonDecoration::updateLayout() const
00180 {
00181 QRect r = widget()->rect();
00182 int r_x, r_y, r_x2, r_y2;
00183 r.getCoords(&r_x, &r_y, &r_x2, &r_y2);
00184
00185
00186 if (m_previewWidget) {
00187 const int borderLeft = layoutMetric(LM_BorderLeft);
00188 const int borderRight = layoutMetric(LM_BorderRight);
00189 const int borderBottom = layoutMetric(LM_BorderBottom);
00190 const int titleHeight = layoutMetric(LM_TitleHeight);
00191 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
00192 const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
00193
00194 int left = r_x+borderLeft;
00195 int top = r_y+titleEdgeTop+titleHeight+titleEdgeBottom;
00196 int width = r_x2-borderRight-left+1;
00197 int height = r_y2-borderBottom-top+1;
00198 m_previewWidget->setGeometry(left, top, width, height);
00199 moveWidget(left,top, m_previewWidget);
00200 resizeWidget(width, height, m_previewWidget);
00201 }
00202
00203
00204 for (int n=0; n<NumButtons; n++) {
00205 if (m_button[n]) {
00206 QSize newSize = QSize(layoutMetric(LM_ButtonWidth, true, m_button[n]),
00207 layoutMetric(LM_ButtonHeight, true, m_button[n]) );
00208 if (newSize != m_button[n]->size() )
00209 m_button[n]->setSize(newSize);
00210 }
00211 }
00212
00213
00214 int y = r_y + layoutMetric(LM_TitleEdgeTop) + layoutMetric(LM_ButtonMarginTop);
00215 if (m_buttonsLeft.count() > 0) {
00216 const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
00217 int x = r_x + layoutMetric(LM_TitleEdgeLeft);
00218 for (ButtonContainer::const_iterator it = m_buttonsLeft.begin(); it != m_buttonsLeft.end(); ++it) {
00219 bool elementLayouted = false;
00220 if (*it) {
00221 if (!(*it)->isHidden() ) {
00222 moveWidget(x,y, *it);
00223 x += layoutMetric(LM_ButtonWidth, true, qobject_cast<KCommonDecorationButton*>(*it) );
00224 elementLayouted = true;
00225 }
00226 } else {
00227 x+= layoutMetric(LM_ExplicitButtonSpacer);
00228 elementLayouted = true;
00229 }
00230 if (elementLayouted && it != m_buttonsLeft.end() )
00231 x += buttonSpacing;
00232 }
00233 }
00234
00235 if (m_buttonsRight.count() > 0) {
00236 const int titleEdgeRightLeft = r_x2-layoutMetric(LM_TitleEdgeRight)+1;
00237
00238 const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
00239 int x = titleEdgeRightLeft - buttonContainerWidth(m_buttonsRight);
00240 for (ButtonContainer::const_iterator it = m_buttonsRight.begin(); it != m_buttonsRight.end(); ++it) {
00241 bool elementLayouted = false;
00242 if (*it) {
00243 if (!(*it)->isHidden() ) {
00244 moveWidget(x,y, *it);
00245 x += layoutMetric(LM_ButtonWidth, true, qobject_cast<KCommonDecorationButton*>(*it) );;
00246 elementLayouted = true;
00247 }
00248 } else {
00249 x += layoutMetric(LM_ExplicitButtonSpacer);
00250 elementLayouted = true;
00251 }
00252 if (elementLayouted && it != m_buttonsRight.end() )
00253 x += buttonSpacing;
00254 }
00255 }
00256 }
00257
00258 void KCommonDecoration::updateButtons() const
00259 {
00260 for (int n=0; n<NumButtons; n++)
00261 if (m_button[n]) m_button[n]->update();
00262 }
00263
00264 void KCommonDecoration::resetButtons() const
00265 {
00266 for (int n=0; n<NumButtons; n++)
00267 if (m_button[n]) m_button[n]->reset(KCommonDecorationButton::ManualReset);
00268 }
00269
00270 void KCommonDecoration::resetLayout()
00271 {
00272 for (int n=0; n<NumButtons; n++) {
00273 if (m_button[n]) {
00274 delete m_button[n];
00275 m_button[n] = 0;
00276 }
00277 }
00278 m_buttonsLeft.clear();
00279 m_buttonsRight.clear();
00280
00281 delete m_previewWidget;
00282 m_previewWidget = 0;
00283
00284
00285 if(isPreview() ) {
00286 m_previewWidget = new QLabel(i18n("<center><b>%1 preview</b></center>", visibleName() ), widget());
00287 m_previewWidget->setAutoFillBackground(true);
00288 m_previewWidget->show();
00289 }
00290
00291 addButtons(m_buttonsLeft,
00292 options()->customButtonPositions() ? options()->titleButtonsLeft() : defaultButtonsLeft(),
00293 true);
00294 addButtons(m_buttonsRight,
00295 options()->customButtonPositions() ? options()->titleButtonsRight() : defaultButtonsRight(),
00296 false);
00297
00298 updateLayout();
00299
00300 const int minTitleBarWidth = 35;
00301 btnHideMinWidth = buttonContainerWidth(m_buttonsLeft,true) + buttonContainerWidth(m_buttonsRight,true) +
00302 layoutMetric(LM_TitleEdgeLeft,false) + layoutMetric(LM_TitleEdgeRight,false) +
00303 layoutMetric(LM_TitleBorderLeft,false) + layoutMetric(LM_TitleBorderRight,false) +
00304 minTitleBarWidth;
00305 btnHideLastWidth = 0;
00306 }
00307
00308 int KCommonDecoration::buttonsLeftWidth() const
00309 {
00310 return buttonContainerWidth(m_buttonsLeft);
00311 }
00312
00313 int KCommonDecoration::buttonsRightWidth() const
00314 {
00315 return buttonContainerWidth(m_buttonsRight);
00316 }
00317
00318 int KCommonDecoration::buttonContainerWidth(const ButtonContainer &btnContainer, bool countHidden) const
00319 {
00320 int explicitSpacer = layoutMetric(LM_ExplicitButtonSpacer);
00321
00322 int shownElementsCount = 0;
00323
00324 int w = 0;
00325 for (ButtonContainer::const_iterator it = btnContainer.begin(); it != btnContainer.end(); ++it) {
00326 if (*it) {
00327 if (countHidden || !(*it)->isHidden() ) {
00328 w += (*it)->width();
00329 ++shownElementsCount;
00330 }
00331 } else {
00332 w += explicitSpacer;
00333 ++shownElementsCount;
00334 }
00335 }
00336 w += layoutMetric(LM_ButtonSpacing)*(shownElementsCount-1);
00337
00338 return w;
00339 }
00340
00341 void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QString& s, bool isLeft)
00342 {
00343 if (s.length() > 0) {
00344 for (int n=0; n < s.length(); n++) {
00345 KCommonDecorationButton *btn = 0;
00346 switch (s[n].toAscii()) {
00347 case 'M':
00348 if (!m_button[MenuButton]){
00349 btn = createButton(MenuButton);
00350 if (!btn) break;
00351 btn->setTipText(i18n("Menu") );
00352 btn->setRealizeButtons(Qt::LeftButton|Qt::RightButton);
00353 connect(btn, SIGNAL(pressed()), SLOT(menuButtonPressed()));
00354 connect(btn, SIGNAL(released()), this, SLOT(menuButtonReleased()));
00355
00356 m_button[MenuButton] = btn;
00357 }
00358 break;
00359 case 'S':
00360 if (!m_button[OnAllDesktopsButton]){
00361 btn = createButton(OnAllDesktopsButton);
00362 if (!btn) break;
00363 const bool oad = isOnAllDesktops();
00364 btn->setTipText(oad?i18n("Not on all desktops"):i18n("On all desktops") );
00365 btn->setToggleButton(true);
00366 btn->setOn( oad );
00367 connect(btn, SIGNAL(clicked()), SLOT(toggleOnAllDesktops()));
00368
00369 m_button[OnAllDesktopsButton] = btn;
00370 }
00371 break;
00372 case 'H':
00373 if ((!m_button[HelpButton]) && providesContextHelp()){
00374 btn = createButton(HelpButton);
00375 if (!btn) break;
00376 btn->setTipText(i18n("Help") );
00377 connect(btn, SIGNAL(clicked()), SLOT(showContextHelp()));
00378
00379 m_button[HelpButton] = btn;
00380 }
00381 break;
00382 case 'I':
00383 if ((!m_button[MinButton]) && isMinimizable()){
00384 btn = createButton(MinButton);
00385 if (!btn) break;
00386 btn->setTipText(i18n("Minimize") );
00387 connect(btn, SIGNAL(clicked()), SLOT(minimize()));
00388
00389 m_button[MinButton] = btn;
00390 }
00391 break;
00392 case 'A':
00393 if ((!m_button[MaxButton]) && isMaximizable()){
00394 btn = createButton(MaxButton);
00395 if (!btn) break;
00396 btn->setRealizeButtons(Qt::LeftButton|Qt::MidButton|Qt::RightButton);
00397 const bool max = maximizeMode()==MaximizeFull;
00398 btn->setTipText(max?i18n("Restore"):i18n("Maximize") );
00399 btn->setToggleButton(true);
00400 btn->setOn( max );
00401 connect(btn, SIGNAL(clicked()), SLOT(slotMaximize()));
00402
00403 m_button[MaxButton] = btn;
00404 }
00405 break;
00406 case 'X':
00407 if ((!m_button[CloseButton]) && isCloseable()){
00408 btn = createButton(CloseButton);
00409 if (!btn) break;
00410 btn->setTipText(i18n("Close") );
00411 connect(btn, SIGNAL(clicked()), SLOT(closeWindow()));
00412
00413 m_button[CloseButton] = btn;
00414 }
00415 break;
00416 case 'F':
00417 if (!m_button[AboveButton]){
00418 btn = createButton(AboveButton);
00419 if (!btn) break;
00420 bool above = keepAbove();
00421 btn->setTipText(above?i18n("Do not keep above others"):i18n("Keep above others") );
00422 btn->setToggleButton(true);
00423 btn->setOn( above );
00424 connect(btn, SIGNAL(clicked()), SLOT(slotKeepAbove()));
00425
00426 m_button[AboveButton] = btn;
00427 }
00428 break;
00429 case 'B':
00430 if (!m_button[BelowButton]){
00431 btn = createButton(BelowButton);
00432 if (!btn) break;
00433 bool below = keepBelow();
00434 btn->setTipText(below?i18n("Do not keep below others"):i18n("Keep below others") );
00435 btn->setToggleButton(true);
00436 btn->setOn( below );
00437 connect(btn, SIGNAL(clicked()), SLOT(slotKeepBelow()));
00438
00439 m_button[BelowButton] = btn;
00440 }
00441 break;
00442 case 'L':
00443 if ((!m_button[ShadeButton]) && isShadeable()){
00444 btn = createButton(ShadeButton);
00445 if (!btn) break;
00446 bool shaded = isSetShade();
00447 btn->setTipText(shaded?i18n("Unshade"):i18n("Shade") );
00448 btn->setToggleButton(true);
00449 btn->setOn( shaded );
00450 connect(btn, SIGNAL(clicked()), SLOT(slotShade()));
00451
00452 m_button[ShadeButton] = btn;
00453 }
00454 break;
00455 case '_':
00456 btnContainer.append(0);
00457 }
00458
00459
00460 if (btn) {
00461 btn->setLeft(isLeft);
00462 btn->setSize(QSize(layoutMetric(LM_ButtonWidth, true, btn),layoutMetric(LM_ButtonHeight, true, btn)) );
00463 btn->show();
00464 btnContainer.append(btn);
00465 }
00466
00467 }
00468 }
00469 }
00470
00471 void KCommonDecoration::calcHiddenButtons()
00472 {
00473 if (width() == btnHideLastWidth)
00474 return;
00475
00476 btnHideLastWidth = width();
00477
00478
00479 KCommonDecorationButton* btnArray[] = { m_button[HelpButton], m_button[ShadeButton], m_button[BelowButton],
00480 m_button[AboveButton], m_button[OnAllDesktopsButton], m_button[MaxButton],
00481 m_button[MinButton], m_button[MenuButton], m_button[CloseButton] };
00482 const int buttonsCount = sizeof( btnArray ) / sizeof( btnArray[ 0 ] );
00483
00484 int current_width = width();
00485 int count = 0;
00486
00487
00488 while (current_width < btnHideMinWidth && count < buttonsCount)
00489 {
00490 if (btnArray[count] ) {
00491 current_width += btnArray[count]->width();
00492 if (btnArray[count]->isVisible() )
00493 btnArray[count]->hide();
00494 }
00495 count++;
00496 }
00497
00498 for(int i = count; i < buttonsCount; i++)
00499 {
00500 if (btnArray[i] ) {
00501
00502 if (! btnArray[i]->isHidden() )
00503 break;
00504
00505 btnArray[i]->show();
00506 }
00507 }
00508 }
00509
00510 void KCommonDecoration::show()
00511 {
00512 if (decorationBehaviour(DB_ButtonHide) )
00513 calcHiddenButtons();
00514 widget()->show();
00515 }
00516
00517 void KCommonDecoration::resize( const QSize& s )
00518 {
00519 widget()->resize( s );
00520 }
00521
00522 QSize KCommonDecoration::minimumSize() const
00523 {
00524 const int minWidth = qMax(layoutMetric(LM_TitleEdgeLeft), layoutMetric(LM_BorderLeft))
00525 +qMax(layoutMetric(LM_TitleEdgeRight), layoutMetric(LM_BorderRight))
00526 +layoutMetric(LM_TitleBorderLeft)+layoutMetric(LM_TitleBorderRight);
00527 return QSize(minWidth,
00528 layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)
00529 +layoutMetric(LM_TitleEdgeBottom)
00530 +layoutMetric(LM_BorderBottom) );
00531 }
00532
00533 void KCommonDecoration::maximizeChange()
00534 {
00535 if( m_button[MaxButton] ) {
00536 m_button[MaxButton]->setOn( maximizeMode()==MaximizeFull);
00537 m_button[MaxButton]->setTipText( (maximizeMode()!=MaximizeFull) ?
00538 i18n("Maximize")
00539 : i18n("Restore"));
00540 m_button[MaxButton]->reset(KCommonDecorationButton::StateChange);
00541 }
00542 updateWindowShape();
00543 widget()->update();
00544 }
00545
00546 void KCommonDecoration::desktopChange()
00547 {
00548 if ( m_button[OnAllDesktopsButton] ) {
00549 m_button[OnAllDesktopsButton]->setOn( isOnAllDesktops() );
00550 m_button[OnAllDesktopsButton]->setTipText( isOnAllDesktops() ?
00551 i18n("Not on all desktops")
00552 : i18n("On all desktops"));
00553 m_button[OnAllDesktopsButton]->reset(KCommonDecorationButton::StateChange);
00554 }
00555 }
00556
00557 void KCommonDecoration::shadeChange()
00558 {
00559 if ( m_button[ShadeButton] ) {
00560 bool shaded = isSetShade();
00561 m_button[ShadeButton]->setOn( shaded );
00562 m_button[ShadeButton]->setTipText( shaded ?
00563 i18n("Unshade")
00564 : i18n("Shade"));
00565 m_button[ShadeButton]->reset(KCommonDecorationButton::StateChange);
00566 }
00567 }
00568
00569 void KCommonDecoration::iconChange()
00570 {
00571 if (m_button[MenuButton])
00572 {
00573 m_button[MenuButton]->update();
00574 m_button[MenuButton]->reset(KCommonDecorationButton::IconChange);
00575 }
00576 }
00577
00578 void KCommonDecoration::activeChange()
00579 {
00580 updateButtons();
00581 widget()->update();
00582 }
00583
00584 void KCommonDecoration::captionChange()
00585 {
00586 updateCaption();
00587 }
00588
00589 void KCommonDecoration::keepAboveChange(bool above)
00590 {
00591 if (m_button[AboveButton])
00592 {
00593 m_button[AboveButton]->setOn(above);
00594 m_button[AboveButton]->setTipText( above?i18n("Do not keep above others"):i18n("Keep above others") );
00595 m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
00596 }
00597
00598 if (m_button[BelowButton] && m_button[BelowButton]->isChecked())
00599 {
00600 m_button[BelowButton]->setOn(false);
00601 m_button[BelowButton]->setTipText( i18n("Keep below others") );
00602 m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
00603 }
00604 }
00605
00606 void KCommonDecoration::keepBelowChange(bool below)
00607 {
00608 if (m_button[BelowButton])
00609 {
00610 m_button[BelowButton]->setOn(below);
00611 m_button[BelowButton]->setTipText( below?i18n("Do not keep below others"):i18n("Keep below others") );
00612 m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
00613 }
00614
00615 if (m_button[AboveButton] && m_button[AboveButton]->isChecked())
00616 {
00617 m_button[AboveButton]->setOn(false);
00618 m_button[AboveButton]->setTipText( i18n("Keep above others") );
00619 m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
00620 }
00621 }
00622
00623 void KCommonDecoration::slotMaximize()
00624 {
00625 if (m_button[MaxButton])
00626 {
00627 maximize(m_button[MaxButton]->lastMousePress() );
00628 }
00629 }
00630
00631 void KCommonDecoration::slotShade()
00632 {
00633 setShade( !isSetShade() );
00634 }
00635
00636 void KCommonDecoration::slotKeepAbove()
00637 {
00638 setKeepAbove(!keepAbove() );
00639 }
00640
00641 void KCommonDecoration::slotKeepBelow()
00642 {
00643 setKeepBelow(!keepBelow() );
00644 }
00645
00646 void KCommonDecoration::menuButtonPressed()
00647 {
00648 static QTime* t = NULL;
00649 static KCommonDecoration* lastClient = NULL;
00650 if (t == NULL)
00651 t = new QTime;
00652 bool dbl = (lastClient==this && t->elapsed() <= QApplication::doubleClickInterval());
00653 lastClient = this;
00654 t->start();
00655 if (!dbl || !decorationBehaviour(DB_MenuClose) ) {
00656 QRect menuRect = m_button[MenuButton]->rect();
00657 QPoint menutop = m_button[MenuButton]->mapToGlobal(menuRect.topLeft());
00658 QPoint menubottom = m_button[MenuButton]->mapToGlobal(menuRect.bottomRight())+QPoint(0,2);
00659 KDecorationFactory* f = factory();
00660 showWindowMenu(QRect(menutop, menubottom));
00661 if( !f->exists( decoration()))
00662 return;
00663 m_button[MenuButton]->setDown(false);
00664 }
00665 else
00666 closing = true;
00667 }
00668
00669 void KCommonDecoration::menuButtonReleased()
00670 {
00671 if(closing)
00672 closeWindow();
00673 }
00674
00675 void KCommonDecoration::resizeEvent(QResizeEvent *)
00676 {
00677 if (decorationBehaviour(DB_ButtonHide) )
00678 calcHiddenButtons();
00679
00680 updateLayout();
00681
00682 updateWindowShape();
00683
00684
00685
00686 }
00687
00688 void KCommonDecoration::moveWidget(int x, int y, QWidget *widget) const
00689 {
00690 QPoint p = widget->pos();
00691 int oldX = p.y();
00692 int oldY = p.x();
00693
00694 if (x!=oldX || y!=oldY)
00695 widget->move(x,y);
00696 }
00697
00698 void KCommonDecoration::resizeWidget(int w, int h, QWidget *widget) const
00699 {
00700 QSize s = widget->size();
00701 int oldW = s.width();
00702 int oldH = s.height();
00703
00704 if (w!=oldW || h!=oldH)
00705 widget->resize(w,h);
00706 }
00707
00708 void KCommonDecoration::mouseDoubleClickEvent(QMouseEvent *e)
00709 {
00710 if( e->button() != Qt::LeftButton )
00711 return;
00712
00713 int tb = layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)+layoutMetric(LM_TitleEdgeBottom);
00714
00715
00716 if (isSetShade() || e->pos().y() <= tb )
00717 titlebarDblClickOperation();
00718 }
00719
00720 void KCommonDecoration::wheelEvent(QWheelEvent *e)
00721 {
00722 int tb = layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)+layoutMetric(LM_TitleEdgeBottom);
00723 if (isSetShade() || e->pos().y() <= tb )
00724 titlebarMouseWheelOperation( e->delta());
00725 }
00726
00727 KCommonDecoration::Position KCommonDecoration::mousePosition(const QPoint &point) const
00728 {
00729 const int corner = 18+3*layoutMetric(LM_BorderBottom, false)/2;
00730 Position pos = PositionCenter;
00731
00732 QRect r = widget()->rect();
00733 int r_x, r_y, r_x2, r_y2;
00734 r.getCoords(&r_x, &r_y, &r_x2, &r_y2);
00735 int p_x = point.x();
00736 int p_y = point.y();
00737 const int borderLeft = layoutMetric(LM_BorderLeft);
00738
00739 const int borderBottom = layoutMetric(LM_BorderBottom);
00740 const int titleHeight = layoutMetric(LM_TitleHeight);
00741 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
00742 const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
00743 const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
00744 const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
00745
00746 const int borderBottomTop = r_y2-borderBottom+1;
00747 const int borderLeftRight = r_x+borderLeft-1;
00748
00749 const int titleEdgeLeftRight = r_x+titleEdgeLeft-1;
00750 const int titleEdgeRightLeft = r_x2-titleEdgeRight+1;
00751 const int titleEdgeBottomBottom = r_y+titleEdgeTop+titleHeight+titleEdgeBottom-1;
00752 const int titleEdgeTopBottom = r_y+titleEdgeTop-1;
00753
00754 if (p_y <= titleEdgeTopBottom) {
00755 if (p_x <= r_x+corner)
00756 pos = PositionTopLeft;
00757 else if (p_x >= r_x2-corner)
00758 pos = PositionTopRight;
00759 else
00760 pos = PositionTop;
00761 } else if (p_y <= titleEdgeBottomBottom) {
00762 if (p_x <= titleEdgeLeftRight)
00763 pos = PositionTopLeft;
00764 else if (p_x >= titleEdgeRightLeft)
00765 pos = PositionTopRight;
00766 else
00767 pos = PositionCenter;
00768 } else if (p_y < borderBottomTop) {
00769 if (p_y < r_y2-corner) {
00770 if (p_x <= borderLeftRight)
00771 pos = PositionLeft;
00772 else
00773 pos = PositionRight;
00774 } else {
00775 if (p_x <= borderLeftRight)
00776 pos = PositionBottomLeft;
00777 else
00778 pos = PositionBottomRight;
00779 }
00780 } else if(p_y >= borderBottomTop) {
00781 if (p_x <= r_x+corner)
00782 pos = PositionBottomLeft;
00783 else if (p_x >= r_x2-corner)
00784 pos = PositionBottomRight;
00785 else
00786 pos = PositionBottom;
00787 }
00788
00789 return pos;
00790 }
00791
00792 void KCommonDecoration::updateWindowShape()
00793 {
00794
00795 if (!decorationBehaviour(DB_WindowMask) )
00796 return;
00797
00798 int w = widget()->width();
00799 int h = widget()->height();
00800
00801 bool tl=true,tr=true,bl=true,br=true;
00802
00803
00804 for(int screen=0; screen < Kephal::ScreenUtils::numScreens(); ++screen)
00805 {
00806 QRect fullscreen(Kephal::ScreenUtils::screenGeometry(screen));
00807 QRect window = geometry();
00808
00809 if(window.topLeft() == fullscreen.topLeft() ) tl = false;
00810 if(window.topRight() == fullscreen.topRight() ) tr = false;
00811 if(window.bottomLeft() == fullscreen.bottomLeft() ) bl = false;
00812 if(window.bottomRight()== fullscreen.bottomRight() ) br = false;
00813 }
00814
00815 QRegion mask(0, 0, w, h);
00816
00817
00818 if(tl)
00819 {
00820 mask -= cornerShape(WC_TopLeft);
00821 }
00822
00823 if(tr)
00824 {
00825 mask -= cornerShape(WC_TopRight);
00826 }
00827
00828 if(bl)
00829 {
00830 mask -= cornerShape(WC_BottomLeft);
00831 }
00832
00833 if(br)
00834 {
00835 mask -= cornerShape(WC_BottomRight);
00836 }
00837
00838 setMask( mask );
00839 }
00840
00841 bool KCommonDecoration::eventFilter( QObject* o, QEvent* e )
00842 {
00843 if( o != widget())
00844 return false;
00845 switch( e->type())
00846 {
00847 case QEvent::Resize:
00848 resizeEvent(static_cast<QResizeEvent*>(e) );
00849 return true;
00850 case QEvent::Paint:
00851 paintEvent( static_cast< QPaintEvent* >( e ));
00852 return true;
00853 case QEvent::MouseButtonDblClick:
00854 mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ));
00855 return true;
00856 case QEvent::MouseButtonPress:
00857 processMousePressEvent( static_cast< QMouseEvent* >( e ));
00858 return true;
00859 case QEvent::Wheel:
00860 wheelEvent( static_cast< QWheelEvent* >( e ));
00861 return true;
00862 default:
00863 return false;
00864 }
00865 }
00866
00867 const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
00868 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::TopMenuMask
00869 | NET::UtilityMask | NET::SplashMask;
00870
00871 bool KCommonDecoration::isToolWindow() const
00872 {
00873 NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
00874 return ((type==NET::Toolbar)||(type==NET::Utility)||(type==NET::Menu));
00875 }
00876
00877 QRect KCommonDecoration::titleRect() const
00878 {
00879 int r_x, r_y, r_x2, r_y2;
00880 widget()->rect().getCoords(&r_x, &r_y, &r_x2, &r_y2);
00881 const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
00882 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
00883 const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
00884 const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
00885 const int titleBorderLeft = layoutMetric(LM_TitleBorderLeft);
00886 const int titleBorderRight = layoutMetric(LM_TitleBorderRight);
00887 const int ttlHeight = layoutMetric(LM_TitleHeight);
00888 const int titleEdgeBottomBottom = r_y+titleEdgeTop+ttlHeight+titleEdgeBottom-1;
00889 return QRect(r_x+titleEdgeLeft+buttonsLeftWidth()+titleBorderLeft, r_y+titleEdgeTop,
00890 r_x2-titleEdgeRight-buttonsRightWidth()-titleBorderRight-(r_x+titleEdgeLeft+buttonsLeftWidth()+titleBorderLeft),
00891 titleEdgeBottomBottom-(r_y+titleEdgeTop) );
00892 }
00893
00894
00895 KCommonDecorationButton::KCommonDecorationButton(ButtonType type, KCommonDecoration *parent)
00896 : QAbstractButton(parent->widget() ),
00897 m_decoration(parent),
00898 m_type(type),
00899 m_realizeButtons(Qt::LeftButton),
00900 m_lastMouse(Qt::NoButton),
00901 m_isLeft(true)
00902 {
00903 setCursor(Qt::ArrowCursor);
00904 }
00905
00906 KCommonDecorationButton::~KCommonDecorationButton()
00907 {
00908 }
00909
00910 KCommonDecoration *KCommonDecorationButton::decoration() const
00911 {
00912 return m_decoration;
00913 }
00914
00915 ButtonType KCommonDecorationButton::type() const
00916 {
00917 return m_type;
00918 }
00919
00920 bool KCommonDecorationButton::isLeft() const
00921 {
00922 return m_isLeft;
00923 }
00924
00925 void KCommonDecorationButton::setLeft(bool left)
00926 {
00927 m_isLeft = left;
00928 }
00929
00930 void KCommonDecorationButton::setRealizeButtons(int btns)
00931 {
00932 m_realizeButtons = btns;
00933 }
00934
00935 void KCommonDecorationButton::setSize(const QSize &s)
00936 {
00937 if (!m_size.isValid() || s != size() ) {
00938 m_size = s;
00939
00940 setFixedSize(m_size);
00941 reset(SizeChange);
00942 }
00943 }
00944
00945 QSize KCommonDecorationButton::sizeHint() const
00946 {
00947 return m_size;
00948 }
00949
00950 void KCommonDecorationButton::setTipText(const QString &tip) {
00951 this->setToolTip( tip );
00952 }
00953
00954 void KCommonDecorationButton::setToggleButton(bool toggle)
00955 {
00956 QAbstractButton::setCheckable(toggle);
00957 reset(ToggleChange);
00958 }
00959
00960 void KCommonDecorationButton::setOn(bool on)
00961 {
00962 if (on != isChecked() ) {
00963 QAbstractButton::setChecked(on);
00964 reset(StateChange);
00965 }
00966 }
00967
00968 void KCommonDecorationButton::mousePressEvent(QMouseEvent* e)
00969 {
00970 m_lastMouse = e->button();
00971
00972 QMouseEvent me(e->type(), e->pos(), (e->button()&m_realizeButtons)?Qt::LeftButton : Qt::NoButton, e->buttons(), e->modifiers() );
00973
00974 QAbstractButton::mousePressEvent(&me);
00975 }
00976
00977 void KCommonDecorationButton::mouseReleaseEvent(QMouseEvent* e)
00978 {
00979 m_lastMouse = e->button();
00980
00981 QMouseEvent me(e->type(), e->pos(), (e->button()&m_realizeButtons)?Qt::LeftButton : Qt::NoButton, e->buttons(), e->modifiers() );
00982
00983 QAbstractButton::mouseReleaseEvent(&me);
00984 }
00985
00986
00987
00988
00989 bool KCommonDecoration::drawbound( const QRect&, bool )
00990 {
00991 return false;
00992 }
00993 bool KCommonDecoration::windowDocked( Position )
00994 {
00995 return false;
00996 }
00997 const KDecorationOptions* KCommonDecoration::options()
00998 {
00999 return KDecoration::options();
01000 }
01001 bool KCommonDecoration::isActive() const
01002 {
01003 return wrapper->isActive();
01004 }
01005 bool KCommonDecoration::isCloseable() const
01006 {
01007 return wrapper->isCloseable();
01008 }
01009 bool KCommonDecoration::isMaximizable() const
01010 {
01011 return wrapper->isMaximizable();
01012 }
01013 KCommonDecoration::MaximizeMode KCommonDecoration::maximizeMode() const
01014 {
01015 return wrapper->maximizeMode();
01016 }
01017 bool KCommonDecoration::isMinimizable() const
01018 {
01019 return wrapper->isMinimizable();
01020 }
01021 bool KCommonDecoration::providesContextHelp() const
01022 {
01023 return wrapper->providesContextHelp();
01024 }
01025 int KCommonDecoration::desktop() const
01026 {
01027 return wrapper->desktop();
01028 }
01029 bool KCommonDecoration::isOnAllDesktops() const
01030 {
01031 return wrapper->isOnAllDesktops();
01032 }
01033 bool KCommonDecoration::isModal() const
01034 {
01035 return wrapper->isModal();
01036 }
01037 bool KCommonDecoration::isShadeable() const
01038 {
01039 return wrapper->isShadeable();
01040 }
01041 bool KCommonDecoration::isShade() const
01042 {
01043 return wrapper->isShade();
01044 }
01045 bool KCommonDecoration::isSetShade() const
01046 {
01047 return wrapper->isSetShade();
01048 }
01049 bool KCommonDecoration::keepAbove() const
01050 {
01051 return wrapper->keepAbove();
01052 }
01053 bool KCommonDecoration::keepBelow() const
01054 {
01055 return wrapper->keepBelow();
01056 }
01057 bool KCommonDecoration::isMovable() const
01058 {
01059 return wrapper->isMovable();
01060 }
01061 bool KCommonDecoration::isResizable() const
01062 {
01063 return wrapper->isResizable();
01064 }
01065 NET::WindowType KCommonDecoration::windowType( unsigned long supported_types ) const
01066 {
01067 return wrapper->windowType( supported_types );
01068 }
01069 QIcon KCommonDecoration::icon() const
01070 {
01071 return wrapper->icon();
01072 }
01073 QString KCommonDecoration::caption() const
01074 {
01075 return wrapper->caption();
01076 }
01077 void KCommonDecoration::showWindowMenu( const QRect &pos )
01078 {
01079 return wrapper->showWindowMenu( pos );
01080 }
01081 void KCommonDecoration::showWindowMenu( QPoint pos )
01082 {
01083 return wrapper->showWindowMenu( pos );
01084 }
01085 void KCommonDecoration::performWindowOperation( WindowOperation op )
01086 {
01087 return wrapper->performWindowOperation( op );
01088 }
01089 void KCommonDecoration::setMask( const QRegion& reg, int mode )
01090 {
01091 return wrapper->setMask( reg, mode );
01092 }
01093 void KCommonDecoration::clearMask()
01094 {
01095 return wrapper->clearMask();
01096 }
01097 bool KCommonDecoration::isPreview() const
01098 {
01099 return wrapper->isPreview();
01100 }
01101 QRect KCommonDecoration::geometry() const
01102 {
01103 return wrapper->geometry();
01104 }
01105 QRect KCommonDecoration::iconGeometry() const
01106 {
01107 return wrapper->iconGeometry();
01108 }
01109 QRegion KCommonDecoration::unobscuredRegion( const QRegion& r ) const
01110 {
01111 return wrapper->unobscuredRegion( r );
01112 }
01113 WId KCommonDecoration::windowId() const
01114 {
01115 return wrapper->windowId();
01116 }
01117 int KCommonDecoration::width() const
01118 {
01119 return wrapper->width();
01120 }
01121 int KCommonDecoration::height() const
01122 {
01123 return wrapper->height();
01124 }
01125 void KCommonDecoration::processMousePressEvent( QMouseEvent* e )
01126 {
01127 return wrapper->processMousePressEvent( e );
01128 }
01129 void KCommonDecoration::setMainWidget( QWidget* w )
01130 {
01131 return wrapper->setMainWidget( w );
01132 }
01133 void KCommonDecoration::createMainWidget( Qt::WFlags flags )
01134 {
01135 return wrapper->createMainWidget( flags );
01136 }
01137 QWidget* KCommonDecoration::initialParentWidget() const
01138 {
01139 return wrapper->initialParentWidget();
01140 }
01141 Qt::WFlags KCommonDecoration::initialWFlags() const
01142 {
01143 return wrapper->initialWFlags();
01144 }
01145 QWidget* KCommonDecoration::widget()
01146 {
01147 return wrapper->widget();
01148 }
01149 const QWidget* KCommonDecoration::widget() const
01150 {
01151 return wrapper->widget();
01152 }
01153 KDecorationFactory* KCommonDecoration::factory() const
01154 {
01155 return wrapper->factory();
01156 }
01157 void KCommonDecoration::grabXServer()
01158 {
01159 return wrapper->grabXServer();
01160 }
01161 void KCommonDecoration::ungrabXServer()
01162 {
01163 return wrapper->ungrabXServer();
01164 }
01165 void KCommonDecoration::closeWindow()
01166 {
01167 return wrapper->closeWindow();
01168 }
01169 void KCommonDecoration::maximize( Qt::MouseButtons button )
01170 {
01171 return wrapper->maximize( button );
01172 }
01173 void KCommonDecoration::maximize( MaximizeMode mode )
01174 {
01175 return wrapper->maximize( mode );
01176 }
01177 void KCommonDecoration::minimize()
01178 {
01179 return wrapper->minimize();
01180 }
01181 void KCommonDecoration::showContextHelp()
01182 {
01183 return wrapper->showContextHelp();
01184 }
01185 void KCommonDecoration::setDesktop( int desktop )
01186 {
01187 return wrapper->setDesktop( desktop );
01188 }
01189 void KCommonDecoration::toggleOnAllDesktops()
01190 {
01191 return wrapper->toggleOnAllDesktops();
01192 }
01193 void KCommonDecoration::titlebarDblClickOperation()
01194 {
01195 return wrapper->titlebarDblClickOperation();
01196 }
01197 void KCommonDecoration::titlebarMouseWheelOperation( int delta )
01198 {
01199 return wrapper->titlebarMouseWheelOperation( delta );
01200 }
01201 void KCommonDecoration::setShade( bool set )
01202 {
01203 return wrapper->setShade( set );
01204 }
01205 void KCommonDecoration::setKeepAbove( bool set )
01206 {
01207 return wrapper->setKeepAbove( set );
01208 }
01209 void KCommonDecoration::setKeepBelow( bool set )
01210 {
01211 return wrapper->setKeepBelow( set );
01212 }
01213
01214
01215 const KDecoration* KCommonDecoration::decoration() const
01216 {
01217 return wrapper;
01218 }
01219 KDecoration* KCommonDecoration::decoration()
01220 {
01221 return wrapper;
01222 }
01223
01224
01225 KCommonDecorationUnstable::KCommonDecorationUnstable(KDecorationBridge* bridge, KDecorationFactory* factory)
01226 : KCommonDecoration( bridge, factory )
01227 {
01228 Q_ASSERT( dynamic_cast<const KDecorationUnstable*>( decoration() ));
01229 }
01230
01231 KCommonDecorationUnstable::~KCommonDecorationUnstable()
01232 {
01233 }
01234
01235
01236 QList<QRect> KCommonDecorationUnstable::shadowQuads( ShadowType type ) const
01237 {
01238 Q_UNUSED( type );
01239 return QList<QRect>();
01240 }
01241 double KCommonDecorationUnstable::shadowOpacity( ShadowType type ) const
01242 {
01243 if( isActive() && type == ShadowBorderedActive )
01244 return 1.0;
01245 else if( !isActive() && type == ShadowBorderedInactive )
01246 return 1.0;
01247 return 0.0;
01248 }
01249 double KCommonDecorationUnstable::shadowBrightness( ShadowType type ) const
01250 {
01251 Q_UNUSED( type );
01252 return 1.0;
01253 }
01254 double KCommonDecorationUnstable::shadowSaturation( ShadowType type ) const
01255 {
01256 Q_UNUSED( type );
01257 return 1.0;
01258 }
01259
01260 void KCommonDecorationUnstable::repaintShadow()
01261 {
01262 return static_cast<const KDecorationUnstable*>( decoration() )->repaintShadow();
01263 }
01264 bool KCommonDecorationUnstable::compositingActive() const
01265 {
01266 return static_cast<const KDecorationUnstable*>( decoration() )->compositingActive();
01267 }
01268 bool KCommonDecorationUnstable::shadowsActive() const
01269 {
01270 return static_cast<const KDecorationUnstable*>( decoration() )->shadowsActive();
01271 }
01272 double KCommonDecorationUnstable::opacity() const
01273 {
01274 return static_cast<const KDecorationUnstable*>( decoration() )->opacity();
01275 }
01276
01277
01278