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 #include <QDesktopWidget>
00041
00042 #include "kcommondecoration.moc"
00043
00047 KCommonDecoration::KCommonDecoration(KDecorationBridge* bridge, KDecorationFactory* factory)
00048 : m_previewWidget(0),
00049 btnHideMinWidth(200),
00050 btnHideLastWidth(0),
00051 closing(false),
00052 wrapper( new KCommonDecorationWrapper( this, bridge, factory ))
00053
00054 {
00055
00056 memset(m_button, 0, sizeof(KCommonDecorationButton *) * NumButtons);
00057 connect( wrapper, SIGNAL( keepAboveChanged( bool )), this, SIGNAL( keepAboveChanged( bool )));
00058 connect( wrapper, SIGNAL( keepBelowChanged( bool )), this, SIGNAL( keepBelowChanged( bool )));
00059 }
00060
00061 KCommonDecoration::~KCommonDecoration()
00062 {
00063 for (int n=0; n<NumButtons; n++) {
00064 if (m_button[n]) delete m_button[n];
00065 }
00066 delete m_previewWidget;
00067
00068 }
00069
00070 QString KCommonDecoration::defaultButtonsLeft() const
00071 {
00072 return KDecorationOptions::defaultTitleButtonsLeft();
00073 }
00074
00075 QString KCommonDecoration::defaultButtonsRight() const
00076 {
00077 return KDecorationOptions::defaultTitleButtonsRight();
00078 }
00079
00080 bool KCommonDecoration::decorationBehaviour(DecorationBehaviour behaviour) const
00081 {
00082 switch (behaviour) {
00083 case DB_MenuClose:
00084 return false;
00085
00086 case DB_WindowMask:
00087 return false;
00088
00089 case DB_ButtonHide:
00090 return true;
00091 }
00092
00093 return false;
00094 }
00095
00096 int KCommonDecoration::layoutMetric(LayoutMetric lm, bool respectWindowState, const KCommonDecorationButton *button) const
00097 {
00098 switch (lm) {
00099 case LM_BorderLeft:
00100 case LM_BorderRight:
00101 case LM_BorderBottom:
00102 case LM_TitleEdgeTop:
00103 case LM_TitleEdgeBottom:
00104 case LM_TitleEdgeLeft:
00105 case LM_TitleEdgeRight:
00106 case LM_TitleBorderLeft:
00107 case LM_TitleBorderRight:
00108 return 5;
00109
00110
00111 case LM_ButtonWidth:
00112 case LM_ButtonHeight:
00113 case LM_TitleHeight:
00114 return 20;
00115
00116 case LM_ButtonSpacing:
00117 return 5;
00118
00119 case LM_ButtonMarginTop:
00120 return 0;
00121
00122 case LM_ExplicitButtonSpacer:
00123 return layoutMetric(LM_ButtonWidth, respectWindowState, button )/2;
00124
00125 default:
00126 return 0;
00127 }
00128 }
00129
00130 void KCommonDecoration::init()
00131 {
00132 createMainWidget();
00133
00134
00135 widget()->setAttribute(Qt::WA_NoSystemBackground);
00136
00137 widget()->installEventFilter( this );
00138
00139 resetLayout();
00140
00141 connect(this, SIGNAL(keepAboveChanged(bool) ), SLOT(keepAboveChange(bool) ) );
00142 connect(this, SIGNAL(keepBelowChanged(bool) ), SLOT(keepBelowChange(bool) ) );
00143
00144 updateCaption();
00145 }
00146
00147 void KCommonDecoration::reset( unsigned long changed )
00148 {
00149 if (changed & SettingButtons) {
00150 resetLayout();
00151 widget()->update();
00152 }
00153 }
00154
00155 QRegion KCommonDecoration::cornerShape(WindowCorner)
00156 {
00157 return QRegion();
00158 }
00159
00160 void KCommonDecoration::updateCaption()
00161 {
00162
00163 widget()->update();
00164 }
00165
00166 void KCommonDecoration::borders( int& left, int& right, int& top, int& bottom ) const
00167 {
00168 left = layoutMetric(LM_BorderLeft);
00169 right = layoutMetric(LM_BorderRight);
00170 bottom = layoutMetric(LM_BorderBottom);
00171 top = layoutMetric(LM_TitleHeight) +
00172 layoutMetric(LM_TitleEdgeTop) +
00173 layoutMetric(LM_TitleEdgeBottom);
00174
00175 updateLayout();
00176 }
00177
00178 void KCommonDecoration::updateLayout() const
00179 {
00180 QRect r = widget()->rect();
00181 int r_x, r_y, r_x2, r_y2;
00182 r.getCoords(&r_x, &r_y, &r_x2, &r_y2);
00183
00184
00185 if (m_previewWidget) {
00186 const int borderLeft = layoutMetric(LM_BorderLeft);
00187 const int borderRight = layoutMetric(LM_BorderRight);
00188 const int borderBottom = layoutMetric(LM_BorderBottom);
00189 const int titleHeight = layoutMetric(LM_TitleHeight);
00190 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
00191 const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
00192
00193 int left = r_x+borderLeft;
00194 int top = r_y+titleEdgeTop+titleHeight+titleEdgeBottom;
00195 int width = r_x2-borderRight-left+1;
00196 int height = r_y2-borderBottom-top+1;
00197 m_previewWidget->setGeometry(left, top, width, height);
00198 moveWidget(left,top, m_previewWidget);
00199 resizeWidget(width, height, m_previewWidget);
00200 }
00201
00202
00203 for (int n=0; n<NumButtons; n++) {
00204 if (m_button[n]) {
00205 QSize newSize = QSize(layoutMetric(LM_ButtonWidth, true, m_button[n]),
00206 layoutMetric(LM_ButtonHeight, true, m_button[n]) );
00207 if (newSize != m_button[n]->size() )
00208 m_button[n]->setSize(newSize);
00209 }
00210 }
00211
00212
00213 int y = r_y + layoutMetric(LM_TitleEdgeTop) + layoutMetric(LM_ButtonMarginTop);
00214 if (m_buttonsLeft.count() > 0) {
00215 const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
00216 int x = r_x + layoutMetric(LM_TitleEdgeLeft);
00217 for (ButtonContainer::const_iterator it = m_buttonsLeft.begin(); it != m_buttonsLeft.end(); ++it) {
00218 bool elementLayouted = false;
00219 if (*it) {
00220 if (!(*it)->isHidden() ) {
00221 moveWidget(x,y, *it);
00222 x += layoutMetric(LM_ButtonWidth, true, qobject_cast<KCommonDecorationButton*>(*it) );
00223 elementLayouted = true;
00224 }
00225 } else {
00226 x+= layoutMetric(LM_ExplicitButtonSpacer);
00227 elementLayouted = true;
00228 }
00229 if (elementLayouted && it != m_buttonsLeft.end() )
00230 x += buttonSpacing;
00231 }
00232 }
00233
00234 if (m_buttonsRight.count() > 0) {
00235 const int titleEdgeRightLeft = r_x2-layoutMetric(LM_TitleEdgeRight)+1;
00236
00237 const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
00238 int x = titleEdgeRightLeft - buttonContainerWidth(m_buttonsRight);
00239 for (ButtonContainer::const_iterator it = m_buttonsRight.begin(); it != m_buttonsRight.end(); ++it) {
00240 bool elementLayouted = false;
00241 if (*it) {
00242 if (!(*it)->isHidden() ) {
00243 moveWidget(x,y, *it);
00244 x += layoutMetric(LM_ButtonWidth, true, qobject_cast<KCommonDecorationButton*>(*it) );;
00245 elementLayouted = true;
00246 }
00247 } else {
00248 x += layoutMetric(LM_ExplicitButtonSpacer);
00249 elementLayouted = true;
00250 }
00251 if (elementLayouted && it != m_buttonsRight.end() )
00252 x += buttonSpacing;
00253 }
00254 }
00255 }
00256
00257 void KCommonDecoration::updateButtons() const
00258 {
00259 for (int n=0; n<NumButtons; n++)
00260 if (m_button[n]) m_button[n]->update();
00261 }
00262
00263 void KCommonDecoration::resetButtons() const
00264 {
00265 for (int n=0; n<NumButtons; n++)
00266 if (m_button[n]) m_button[n]->reset(KCommonDecorationButton::ManualReset);
00267 }
00268
00269 void KCommonDecoration::resetLayout()
00270 {
00271 for (int n=0; n<NumButtons; n++) {
00272 if (m_button[n]) {
00273 delete m_button[n];
00274 m_button[n] = 0;
00275 }
00276 }
00277 m_buttonsLeft.clear();
00278 m_buttonsRight.clear();
00279
00280 delete m_previewWidget;
00281 m_previewWidget = 0;
00282
00283
00284 if(isPreview() ) {
00285 m_previewWidget = new QLabel(i18n("<center><b>%1 preview</b></center>", visibleName() ), widget());
00286 m_previewWidget->setAutoFillBackground(true);
00287 m_previewWidget->show();
00288 }
00289
00290 addButtons(m_buttonsLeft,
00291 options()->customButtonPositions() ? options()->titleButtonsLeft() : defaultButtonsLeft(),
00292 true);
00293 addButtons(m_buttonsRight,
00294 options()->customButtonPositions() ? options()->titleButtonsRight() : defaultButtonsRight(),
00295 false);
00296
00297 updateLayout();
00298
00299 const int minTitleBarWidth = 35;
00300 btnHideMinWidth = buttonContainerWidth(m_buttonsLeft,true) + buttonContainerWidth(m_buttonsRight,true) +
00301 layoutMetric(LM_TitleEdgeLeft,false) + layoutMetric(LM_TitleEdgeRight,false) +
00302 layoutMetric(LM_TitleBorderLeft,false) + layoutMetric(LM_TitleBorderRight,false) +
00303 minTitleBarWidth;
00304 btnHideLastWidth = 0;
00305 }
00306
00307 int KCommonDecoration::buttonsLeftWidth() const
00308 {
00309 return buttonContainerWidth(m_buttonsLeft);
00310 }
00311
00312 int KCommonDecoration::buttonsRightWidth() const
00313 {
00314 return buttonContainerWidth(m_buttonsRight);
00315 }
00316
00317 int KCommonDecoration::buttonContainerWidth(const ButtonContainer &btnContainer, bool countHidden) const
00318 {
00319 int explicitSpacer = layoutMetric(LM_ExplicitButtonSpacer);
00320
00321 int shownElementsCount = 0;
00322
00323 int w = 0;
00324 for (ButtonContainer::const_iterator it = btnContainer.begin(); it != btnContainer.end(); ++it) {
00325 if (*it) {
00326 if (countHidden || !(*it)->isHidden() ) {
00327 w += (*it)->width();
00328 ++shownElementsCount;
00329 }
00330 } else {
00331 w += explicitSpacer;
00332 ++shownElementsCount;
00333 }
00334 }
00335 w += layoutMetric(LM_ButtonSpacing)*(shownElementsCount-1);
00336
00337 return w;
00338 }
00339
00340 void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QString& s, bool isLeft)
00341 {
00342 if (s.length() > 0) {
00343 for (int n=0; n < s.length(); n++) {
00344 KCommonDecorationButton *btn = 0;
00345 switch (s[n].toAscii()) {
00346 case 'M':
00347 if (!m_button[MenuButton]){
00348 btn = createButton(MenuButton);
00349 if (!btn) break;
00350 btn->setTipText(i18n("Menu") );
00351 btn->setRealizeButtons(Qt::LeftButton|Qt::RightButton);
00352 connect(btn, SIGNAL(pressed()), SLOT(menuButtonPressed()));
00353 connect(btn, SIGNAL(released()), this, SLOT(menuButtonReleased()));
00354
00355 m_button[MenuButton] = btn;
00356 }
00357 break;
00358 case 'S':
00359 if (!m_button[OnAllDesktopsButton]){
00360 btn = createButton(OnAllDesktopsButton);
00361 if (!btn) break;
00362 const bool oad = isOnAllDesktops();
00363 btn->setTipText(oad?i18n("Not on all desktops"):i18n("On all desktops") );
00364 btn->setToggleButton(true);
00365 btn->setOn( oad );
00366 connect(btn, SIGNAL(clicked()), SLOT(toggleOnAllDesktops()));
00367
00368 m_button[OnAllDesktopsButton] = btn;
00369 }
00370 break;
00371 case 'H':
00372 if ((!m_button[HelpButton]) && providesContextHelp()){
00373 btn = createButton(HelpButton);
00374 if (!btn) break;
00375 btn->setTipText(i18n("Help") );
00376 connect(btn, SIGNAL(clicked()), SLOT(showContextHelp()));
00377
00378 m_button[HelpButton] = btn;
00379 }
00380 break;
00381 case 'I':
00382 if ((!m_button[MinButton]) && isMinimizable()){
00383 btn = createButton(MinButton);
00384 if (!btn) break;
00385 btn->setTipText(i18n("Minimize") );
00386 connect(btn, SIGNAL(clicked()), SLOT(minimize()));
00387
00388 m_button[MinButton] = btn;
00389 }
00390 break;
00391 case 'A':
00392 if ((!m_button[MaxButton]) && isMaximizable()){
00393 btn = createButton(MaxButton);
00394 if (!btn) break;
00395 btn->setRealizeButtons(Qt::LeftButton|Qt::MidButton|Qt::RightButton);
00396 const bool max = maximizeMode()==MaximizeFull;
00397 btn->setTipText(max?i18n("Restore"):i18n("Maximize") );
00398 btn->setToggleButton(true);
00399 btn->setOn( max );
00400 connect(btn, SIGNAL(clicked()), SLOT(slotMaximize()));
00401
00402 m_button[MaxButton] = btn;
00403 }
00404 break;
00405 case 'X':
00406 if ((!m_button[CloseButton]) && isCloseable()){
00407 btn = createButton(CloseButton);
00408 if (!btn) break;
00409 btn->setTipText(i18n("Close") );
00410 connect(btn, SIGNAL(clicked()), SLOT(closeWindow()));
00411
00412 m_button[CloseButton] = btn;
00413 }
00414 break;
00415 case 'F':
00416 if (!m_button[AboveButton]){
00417 btn = createButton(AboveButton);
00418 if (!btn) break;
00419 bool above = keepAbove();
00420 btn->setTipText(above?i18n("Do not keep above others"):i18n("Keep above others") );
00421 btn->setToggleButton(true);
00422 btn->setOn( above );
00423 connect(btn, SIGNAL(clicked()), SLOT(slotKeepAbove()));
00424
00425 m_button[AboveButton] = btn;
00426 }
00427 break;
00428 case 'B':
00429 if (!m_button[BelowButton]){
00430 btn = createButton(BelowButton);
00431 if (!btn) break;
00432 bool below = keepBelow();
00433 btn->setTipText(below?i18n("Do not keep below others"):i18n("Keep below others") );
00434 btn->setToggleButton(true);
00435 btn->setOn( below );
00436 connect(btn, SIGNAL(clicked()), SLOT(slotKeepBelow()));
00437
00438 m_button[BelowButton] = btn;
00439 }
00440 break;
00441 case 'L':
00442 if ((!m_button[ShadeButton]) && isShadeable()){
00443 btn = createButton(ShadeButton);
00444 if (!btn) break;
00445 bool shaded = isSetShade();
00446 btn->setTipText(shaded?i18n("Unshade"):i18n("Shade") );
00447 btn->setToggleButton(true);
00448 btn->setOn( shaded );
00449 connect(btn, SIGNAL(clicked()), SLOT(slotShade()));
00450
00451 m_button[ShadeButton] = btn;
00452 }
00453 break;
00454 case '_':
00455 btnContainer.append(0);
00456 }
00457
00458
00459 if (btn) {
00460 btn->setLeft(isLeft);
00461 btn->setSize(QSize(layoutMetric(LM_ButtonWidth, true, btn),layoutMetric(LM_ButtonHeight, true, btn)) );
00462 btn->show();
00463 btnContainer.append(btn);
00464 }
00465
00466 }
00467 }
00468 }
00469
00470 void KCommonDecoration::calcHiddenButtons()
00471 {
00472 if (width() == btnHideLastWidth)
00473 return;
00474
00475 btnHideLastWidth = width();
00476
00477
00478 KCommonDecorationButton* btnArray[] = { m_button[HelpButton], m_button[ShadeButton], m_button[BelowButton],
00479 m_button[AboveButton], m_button[OnAllDesktopsButton], m_button[MaxButton],
00480 m_button[MinButton], m_button[MenuButton], m_button[CloseButton] };
00481 const int buttonsCount = sizeof( btnArray ) / sizeof( btnArray[ 0 ] );
00482
00483 int current_width = width();
00484 int count = 0;
00485
00486
00487 while (current_width < btnHideMinWidth && count < buttonsCount)
00488 {
00489 if (btnArray[count] ) {
00490 current_width += btnArray[count]->width();
00491 if (btnArray[count]->isVisible() )
00492 btnArray[count]->hide();
00493 }
00494 count++;
00495 }
00496
00497 for(int i = count; i < buttonsCount; i++)
00498 {
00499 if (btnArray[i] ) {
00500
00501 if (! btnArray[i]->isHidden() )
00502 break;
00503
00504 btnArray[i]->show();
00505 }
00506 }
00507 }
00508
00509 void KCommonDecoration::show()
00510 {
00511 if (decorationBehaviour(DB_ButtonHide) )
00512 calcHiddenButtons();
00513 widget()->show();
00514 }
00515
00516 void KCommonDecoration::resize( const QSize& s )
00517 {
00518 widget()->resize( s );
00519 }
00520
00521 QSize KCommonDecoration::minimumSize() const
00522 {
00523 const int minWidth = qMax(layoutMetric(LM_TitleEdgeLeft), layoutMetric(LM_BorderLeft))
00524 +qMax(layoutMetric(LM_TitleEdgeRight), layoutMetric(LM_BorderRight))
00525 +layoutMetric(LM_TitleBorderLeft)+layoutMetric(LM_TitleBorderRight);
00526 return QSize(minWidth,
00527 layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)
00528 +layoutMetric(LM_TitleEdgeBottom)
00529 +layoutMetric(LM_BorderBottom) );
00530 }
00531
00532 void KCommonDecoration::maximizeChange()
00533 {
00534 if( m_button[MaxButton] ) {
00535 m_button[MaxButton]->setOn( maximizeMode()==MaximizeFull);
00536 m_button[MaxButton]->setTipText( (maximizeMode()!=MaximizeFull) ?
00537 i18n("Maximize")
00538 : i18n("Restore"));
00539 m_button[MaxButton]->reset(KCommonDecorationButton::StateChange);
00540 }
00541 updateWindowShape();
00542 widget()->update();
00543 }
00544
00545 void KCommonDecoration::desktopChange()
00546 {
00547 if ( m_button[OnAllDesktopsButton] ) {
00548 m_button[OnAllDesktopsButton]->setOn( isOnAllDesktops() );
00549 m_button[OnAllDesktopsButton]->setTipText( isOnAllDesktops() ?
00550 i18n("Not on all desktops")
00551 : i18n("On all desktops"));
00552 m_button[OnAllDesktopsButton]->reset(KCommonDecorationButton::StateChange);
00553 }
00554 }
00555
00556 void KCommonDecoration::shadeChange()
00557 {
00558 if ( m_button[ShadeButton] ) {
00559 bool shaded = isSetShade();
00560 m_button[ShadeButton]->setOn( shaded );
00561 m_button[ShadeButton]->setTipText( shaded ?
00562 i18n("Unshade")
00563 : i18n("Shade"));
00564 m_button[ShadeButton]->reset(KCommonDecorationButton::StateChange);
00565 }
00566 }
00567
00568 void KCommonDecoration::iconChange()
00569 {
00570 if (m_button[MenuButton])
00571 {
00572 m_button[MenuButton]->update();
00573 m_button[MenuButton]->reset(KCommonDecorationButton::IconChange);
00574 }
00575 }
00576
00577 void KCommonDecoration::activeChange()
00578 {
00579 updateButtons();
00580 widget()->update();
00581 }
00582
00583 void KCommonDecoration::captionChange()
00584 {
00585 updateCaption();
00586 }
00587
00588 void KCommonDecoration::keepAboveChange(bool above)
00589 {
00590 if (m_button[AboveButton])
00591 {
00592 m_button[AboveButton]->setOn(above);
00593 m_button[AboveButton]->setTipText( above?i18n("Do not keep above others"):i18n("Keep above others") );
00594 m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
00595 }
00596
00597 if (m_button[BelowButton] && m_button[BelowButton]->isChecked())
00598 {
00599 m_button[BelowButton]->setOn(false);
00600 m_button[BelowButton]->setTipText( i18n("Keep below others") );
00601 m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
00602 }
00603 }
00604
00605 void KCommonDecoration::keepBelowChange(bool below)
00606 {
00607 if (m_button[BelowButton])
00608 {
00609 m_button[BelowButton]->setOn(below);
00610 m_button[BelowButton]->setTipText( below?i18n("Do not keep below others"):i18n("Keep below others") );
00611 m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
00612 }
00613
00614 if (m_button[AboveButton] && m_button[AboveButton]->isChecked())
00615 {
00616 m_button[AboveButton]->setOn(false);
00617 m_button[AboveButton]->setTipText( i18n("Keep above others") );
00618 m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
00619 }
00620 }
00621
00622 void KCommonDecoration::slotMaximize()
00623 {
00624 if (m_button[MaxButton])
00625 {
00626 maximize(m_button[MaxButton]->lastMousePress() );
00627 }
00628 }
00629
00630 void KCommonDecoration::slotShade()
00631 {
00632 setShade( !isSetShade() );
00633 }
00634
00635 void KCommonDecoration::slotKeepAbove()
00636 {
00637 setKeepAbove(!keepAbove() );
00638 }
00639
00640 void KCommonDecoration::slotKeepBelow()
00641 {
00642 setKeepBelow(!keepBelow() );
00643 }
00644
00645 void KCommonDecoration::menuButtonPressed()
00646 {
00647 static QTime* t = NULL;
00648 static KCommonDecoration* lastClient = NULL;
00649 if (t == NULL)
00650 t = new QTime;
00651 bool dbl = (lastClient==this && t->elapsed() <= QApplication::doubleClickInterval());
00652 lastClient = this;
00653 t->start();
00654 if (!dbl || !decorationBehaviour(DB_MenuClose) ) {
00655 QRect menuRect = m_button[MenuButton]->rect();
00656 QPoint menutop = m_button[MenuButton]->mapToGlobal(menuRect.topLeft());
00657 QPoint menubottom = m_button[MenuButton]->mapToGlobal(menuRect.bottomRight())+QPoint(0,2);
00658 KDecorationFactory* f = factory();
00659 showWindowMenu(QRect(menutop, menubottom));
00660 if( !f->exists( decoration()))
00661 return;
00662 m_button[MenuButton]->setDown(false);
00663 }
00664 else
00665 closing = true;
00666 }
00667
00668 void KCommonDecoration::menuButtonReleased()
00669 {
00670 if(closing)
00671 closeWindow();
00672 }
00673
00674 void KCommonDecoration::resizeEvent(QResizeEvent *)
00675 {
00676 if (decorationBehaviour(DB_ButtonHide) )
00677 calcHiddenButtons();
00678
00679 updateLayout();
00680
00681 updateWindowShape();
00682
00683
00684
00685 }
00686
00687 void KCommonDecoration::moveWidget(int x, int y, QWidget *widget) const
00688 {
00689 QPoint p = widget->pos();
00690 int oldX = p.y();
00691 int oldY = p.x();
00692
00693 if (x!=oldX || y!=oldY)
00694 widget->move(x,y);
00695 }
00696
00697 void KCommonDecoration::resizeWidget(int w, int h, QWidget *widget) const
00698 {
00699 QSize s = widget->size();
00700 int oldW = s.width();
00701 int oldH = s.height();
00702
00703 if (w!=oldW || h!=oldH)
00704 widget->resize(w,h);
00705 }
00706
00707 void KCommonDecoration::mouseDoubleClickEvent(QMouseEvent *e)
00708 {
00709 if( e->button() != Qt::LeftButton )
00710 return;
00711
00712 int tb = layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)+layoutMetric(LM_TitleEdgeBottom);
00713
00714
00715 if (isSetShade() || e->pos().y() <= tb )
00716 titlebarDblClickOperation();
00717 }
00718
00719 void KCommonDecoration::wheelEvent(QWheelEvent *e)
00720 {
00721 int tb = layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)+layoutMetric(LM_TitleEdgeBottom);
00722 if (isSetShade() || e->pos().y() <= tb )
00723 titlebarMouseWheelOperation( e->delta());
00724 }
00725
00726 KCommonDecoration::Position KCommonDecoration::mousePosition(const QPoint &point) const
00727 {
00728 const int corner = 18+3*layoutMetric(LM_BorderBottom, false)/2;
00729 Position pos = PositionCenter;
00730
00731 QRect r = widget()->rect();
00732 int r_x, r_y, r_x2, r_y2;
00733 r.getCoords(&r_x, &r_y, &r_x2, &r_y2);
00734 int p_x = point.x();
00735 int p_y = point.y();
00736 const int borderLeft = layoutMetric(LM_BorderLeft);
00737
00738 const int borderBottom = layoutMetric(LM_BorderBottom);
00739 const int titleHeight = layoutMetric(LM_TitleHeight);
00740 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
00741 const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
00742 const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
00743 const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
00744
00745 const int borderBottomTop = r_y2-borderBottom+1;
00746 const int borderLeftRight = r_x+borderLeft-1;
00747
00748 const int titleEdgeLeftRight = r_x+titleEdgeLeft-1;
00749 const int titleEdgeRightLeft = r_x2-titleEdgeRight+1;
00750 const int titleEdgeBottomBottom = r_y+titleEdgeTop+titleHeight+titleEdgeBottom-1;
00751 const int titleEdgeTopBottom = r_y+titleEdgeTop-1;
00752
00753 if (p_y <= titleEdgeTopBottom) {
00754 if (p_x <= r_x+corner)
00755 pos = PositionTopLeft;
00756 else if (p_x >= r_x2-corner)
00757 pos = PositionTopRight;
00758 else
00759 pos = PositionTop;
00760 } else if (p_y <= titleEdgeBottomBottom) {
00761 if (p_x <= titleEdgeLeftRight)
00762 pos = PositionTopLeft;
00763 else if (p_x >= titleEdgeRightLeft)
00764 pos = PositionTopRight;
00765 else
00766 pos = PositionCenter;
00767 } else if (p_y < borderBottomTop) {
00768 if (p_y < r_y2-corner) {
00769 if (p_x <= borderLeftRight)
00770 pos = PositionLeft;
00771 else
00772 pos = PositionRight;
00773 } else {
00774 if (p_x <= borderLeftRight)
00775 pos = PositionBottomLeft;
00776 else
00777 pos = PositionBottomRight;
00778 }
00779 } else if(p_y >= borderBottomTop) {
00780 if (p_x <= r_x+corner)
00781 pos = PositionBottomLeft;
00782 else if (p_x >= r_x2-corner)
00783 pos = PositionBottomRight;
00784 else
00785 pos = PositionBottom;
00786 }
00787
00788 return pos;
00789 }
00790
00791 void KCommonDecoration::updateWindowShape()
00792 {
00793
00794 if (!decorationBehaviour(DB_WindowMask) )
00795 return;
00796
00797 int w = widget()->width();
00798 int h = widget()->height();
00799
00800 bool tl=true,tr=true,bl=true,br=true;
00801
00802 QDesktopWidget *desktop=KApplication::desktop();
00803
00804 for(int screen=0; screen < desktop->numScreens(); ++screen)
00805 {
00806 QRect fullscreen(desktop->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