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 <qapplication.h>
00026 #include <qcursor.h>
00027 #include <qdatetime.h>
00028 #include <qlabel.h>
00029 #include <qtooltip.h>
00030 #include <qwidget.h>
00031
00032 #include <kdebug.h>
00033
00034 #include <kapplication.h>
00035 #include <kdecorationfactory.h>
00036 #include <klocale.h>
00037
00038 #include "kcommondecoration.h"
00039 #include "kcommondecoration.moc"
00040
00041 KCommonDecoration::KCommonDecoration(KDecorationBridge* bridge, KDecorationFactory* factory)
00042 : KDecoration (bridge, factory),
00043 m_previewWidget(0),
00044 btnHideMinWidth(200),
00045 btnHideLastWidth(0),
00046 closing(false)
00047 {
00048
00049 memset(m_button, 0, sizeof(KCommonDecorationButton *) * NumButtons);
00050 }
00051
00052 KCommonDecoration::~KCommonDecoration()
00053 {
00054 for (int n=0; n<NumButtons; n++) {
00055 if (m_button[n]) delete m_button[n];
00056 }
00057 delete m_previewWidget;
00058 }
00059
00060 bool KCommonDecoration::decorationBehaviour(DecorationBehaviour behaviour) const
00061 {
00062 switch (behaviour) {
00063 case DB_MenuClose:
00064 return false;
00065
00066 case DB_WindowMask:
00067 return false;
00068
00069 case DB_ButtonHide:
00070 return true;
00071 }
00072
00073 return false;
00074 }
00075
00076 int KCommonDecoration::layoutMetric(LayoutMetric lm, bool, const KCommonDecorationButton *) const
00077 {
00078 switch (lm) {
00079 case LM_BorderLeft:
00080 case LM_BorderRight:
00081 case LM_BorderBottom:
00082 case LM_TitleEdgeTop:
00083 case LM_TitleEdgeBottom:
00084 case LM_TitleEdgeLeft:
00085 case LM_TitleEdgeRight:
00086 case LM_TitleBorderLeft:
00087 case LM_TitleBorderRight:
00088 return 5;
00089
00090
00091 case LM_ButtonWidth:
00092 case LM_ButtonHeight:
00093 case LM_TitleHeight:
00094 return 20;
00095
00096 case LM_ButtonSpacing:
00097 return 5;
00098
00099 case LM_ButtonMarginTop:
00100 return 0;
00101
00102 case LM_ExplicitButtonSpacer:
00103 return 5;
00104
00105 default:
00106 return 0;
00107 }
00108 }
00109
00110 void KCommonDecoration::init()
00111 {
00112 createMainWidget(WNoAutoErase);
00113
00114
00115 widget()->setBackgroundMode(NoBackground);
00116
00117 widget()->installEventFilter( this );
00118
00119 resetLayout();
00120
00121 connect(this, SIGNAL(keepAboveChanged(bool) ), SLOT(keepAboveChange(bool) ) );
00122 connect(this, SIGNAL(keepBelowChanged(bool) ), SLOT(keepBelowChange(bool) ) );
00123
00124 updateCaption();
00125 }
00126
00127 void KCommonDecoration::reset( unsigned long changed )
00128 {
00129 if (changed & SettingButtons) {
00130 resetLayout();
00131 widget()->update();
00132 }
00133 }
00134
00135 QRegion KCommonDecoration::cornerShape(WindowCorner)
00136 {
00137 return QRegion();
00138 }
00139
00140 void KCommonDecoration::updateCaption()
00141 {
00142
00143 widget()->update();
00144 }
00145
00146 void KCommonDecoration::borders( int& left, int& right, int& top, int& bottom ) const
00147 {
00148 left = layoutMetric(LM_BorderLeft);
00149 right = layoutMetric(LM_BorderRight);
00150 bottom = layoutMetric(LM_BorderBottom);
00151 top = layoutMetric(LM_TitleHeight) +
00152 layoutMetric(LM_TitleEdgeTop) +
00153 layoutMetric(LM_TitleEdgeBottom);
00154
00155 updateLayout();
00156 }
00157
00158 void KCommonDecoration::updateLayout() const
00159 {
00160 QRect r = widget()->rect();
00161 int r_x, r_y, r_x2, r_y2;
00162 r.coords(&r_x, &r_y, &r_x2, &r_y2);
00163
00164
00165 if (m_previewWidget) {
00166 const int borderLeft = layoutMetric(LM_BorderLeft);
00167 const int borderRight = layoutMetric(LM_BorderRight);
00168 const int borderBottom = layoutMetric(LM_BorderBottom);
00169 const int titleHeight = layoutMetric(LM_TitleHeight);
00170 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
00171 const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
00172
00173 int left = r_x+borderLeft;
00174 int top = r_y+titleEdgeTop+titleHeight+titleEdgeBottom;
00175 int width = r_x2-borderRight-left+1;
00176 int height = r_y2-borderBottom-top+1;
00177 m_previewWidget->setGeometry(left, top, width, height);
00178 moveWidget(left,top, m_previewWidget);
00179 resizeWidget(width, height, m_previewWidget);
00180 }
00181
00182
00183 for (int n=0; n<NumButtons; n++) {
00184 if (m_button[n]) {
00185 QSize newSize = QSize(layoutMetric(LM_ButtonWidth, true, m_button[n]),
00186 layoutMetric(LM_ButtonHeight, true, m_button[n]) );
00187 if (newSize != m_button[n]->size() )
00188 m_button[n]->setSize(newSize);
00189 }
00190 }
00191
00192
00193 int y = r_y + layoutMetric(LM_TitleEdgeTop) + layoutMetric(LM_ButtonMarginTop);
00194 if (m_buttonsLeft.count() > 0) {
00195 const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
00196 int x = r_x + layoutMetric(LM_TitleEdgeLeft);
00197 for (ButtonContainer::const_iterator it = m_buttonsLeft.begin(); it != m_buttonsLeft.end(); ++it) {
00198 bool elementLayouted = false;
00199 if (*it) {
00200 if (!(*it)->isHidden() ) {
00201 moveWidget(x,y, *it);
00202 x += layoutMetric(LM_ButtonWidth, true, ::qt_cast<KCommonDecorationButton*>(*it) );
00203 elementLayouted = true;
00204 }
00205 } else {
00206 x+= layoutMetric(LM_ExplicitButtonSpacer);
00207 elementLayouted = true;
00208 }
00209 if (elementLayouted && it != m_buttonsLeft.end() )
00210 x += buttonSpacing;
00211 }
00212 }
00213
00214 if (m_buttonsRight.count() > 0) {
00215 const int titleEdgeRightLeft = r_x2-layoutMetric(LM_TitleEdgeRight)+1;
00216
00217 const int buttonSpacing = layoutMetric(LM_ButtonSpacing);
00218 int x = titleEdgeRightLeft - buttonContainerWidth(m_buttonsRight);
00219 for (ButtonContainer::const_iterator it = m_buttonsRight.begin(); it != m_buttonsRight.end(); ++it) {
00220 bool elementLayouted = false;
00221 if (*it) {
00222 if (!(*it)->isHidden() ) {
00223 moveWidget(x,y, *it);
00224 x += layoutMetric(LM_ButtonWidth, true, ::qt_cast<KCommonDecorationButton*>(*it) );;
00225 elementLayouted = true;
00226 }
00227 } else {
00228 x += layoutMetric(LM_ExplicitButtonSpacer);
00229 elementLayouted = true;
00230 }
00231 if (elementLayouted && it != m_buttonsRight.end() )
00232 x += buttonSpacing;
00233 }
00234 }
00235 }
00236
00237 void KCommonDecoration::updateButtons() const
00238 {
00239 for (int n=0; n<NumButtons; n++)
00240 if (m_button[n]) m_button[n]->update();
00241 }
00242
00243 void KCommonDecoration::resetButtons() const
00244 {
00245 for (int n=0; n<NumButtons; n++)
00246 if (m_button[n]) m_button[n]->reset(KCommonDecorationButton::ManualReset);
00247 }
00248
00249 void KCommonDecoration::resetLayout()
00250 {
00251 for (int n=0; n<NumButtons; n++) {
00252 if (m_button[n]) {
00253 delete m_button[n];
00254 m_button[n] = 0;
00255 }
00256 }
00257 m_buttonsLeft.clear();
00258 m_buttonsRight.clear();
00259
00260 delete m_previewWidget;
00261 m_previewWidget = 0;
00262
00263
00264 if(isPreview() ) {
00265 m_previewWidget = new QLabel(i18n("%1 is the name of window decoration style", "<center><b>%1 preview</b></center>").arg(visibleName() ), widget());
00266 m_previewWidget->show();
00267 }
00268
00269 addButtons(m_buttonsLeft,
00270 options()->customButtonPositions() ? options()->titleButtonsLeft() : defaultButtonsLeft(),
00271 true);
00272 addButtons(m_buttonsRight,
00273 options()->customButtonPositions() ? options()->titleButtonsRight() : defaultButtonsRight(),
00274 false);
00275
00276 updateLayout();
00277
00278 const int minTitleBarWidth = 35;
00279 btnHideMinWidth = buttonContainerWidth(m_buttonsLeft,true) + buttonContainerWidth(m_buttonsRight,true) +
00280 layoutMetric(LM_TitleEdgeLeft,false) + layoutMetric(LM_TitleEdgeRight,false) +
00281 layoutMetric(LM_TitleBorderLeft,false) + layoutMetric(LM_TitleBorderRight,false) +
00282 minTitleBarWidth;
00283 btnHideLastWidth = 0;
00284 }
00285
00286 int KCommonDecoration::buttonsLeftWidth() const
00287 {
00288 return buttonContainerWidth(m_buttonsLeft);
00289 }
00290
00291 int KCommonDecoration::buttonsRightWidth() const
00292 {
00293 return buttonContainerWidth(m_buttonsRight);
00294 }
00295
00296 int KCommonDecoration::buttonContainerWidth(const ButtonContainer &btnContainer, bool countHidden) const
00297 {
00298 int explicitSpacer = layoutMetric(LM_ExplicitButtonSpacer);
00299
00300 int shownElementsCount = 0;
00301
00302 int w = 0;
00303 for (ButtonContainer::const_iterator it = btnContainer.begin(); it != btnContainer.end(); ++it) {
00304 if (*it) {
00305 if (countHidden || !(*it)->isHidden() ) {
00306 w += (*it)->width();
00307 ++shownElementsCount;
00308 }
00309 } else {
00310 w += explicitSpacer;
00311 ++shownElementsCount;
00312 }
00313 }
00314 w += layoutMetric(LM_ButtonSpacing)*(shownElementsCount-1);
00315
00316 return w;
00317 }
00318
00319 void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QString& s, bool isLeft)
00320 {
00321 if (s.length() > 0) {
00322 for (unsigned n=0; n < s.length(); n++) {
00323 KCommonDecorationButton *btn = 0;
00324 switch (s[n]) {
00325 case 'M':
00326 if (!m_button[MenuButton]){
00327 btn = createButton(MenuButton);
00328 if (!btn) break;
00329 btn->setTipText(i18n("Menu") );
00330 btn->setRealizeButtons(LeftButton|RightButton);
00331 connect(btn, SIGNAL(pressed()), SLOT(menuButtonPressed()));
00332 connect(btn, SIGNAL(released()), this, SLOT(menuButtonReleased()));
00333
00334 m_button[MenuButton] = btn;
00335 }
00336 break;
00337 case 'S':
00338 if (!m_button[OnAllDesktopsButton]){
00339 btn = createButton(OnAllDesktopsButton);
00340 if (!btn) break;
00341 const bool oad = isOnAllDesktops();
00342 btn->setTipText(oad?i18n("Not on all desktops"):i18n("On all desktops") );
00343 btn->setToggleButton(true);
00344 btn->setOn( oad );
00345 connect(btn, SIGNAL(clicked()), SLOT(toggleOnAllDesktops()));
00346
00347 m_button[OnAllDesktopsButton] = btn;
00348 }
00349 break;
00350 case 'H':
00351 if ((!m_button[HelpButton]) && providesContextHelp()){
00352 btn = createButton(HelpButton);
00353 if (!btn) break;
00354 btn->setTipText(i18n("Help") );
00355 connect(btn, SIGNAL(clicked()), SLOT(showContextHelp()));
00356
00357 m_button[HelpButton] = btn;
00358 }
00359 break;
00360 case 'I':
00361 if ((!m_button[MinButton]) && isMinimizable()){
00362 btn = createButton(MinButton);
00363 if (!btn) break;
00364 btn->setTipText(i18n("Minimize") );
00365 connect(btn, SIGNAL(clicked()), SLOT(minimize()));
00366
00367 m_button[MinButton] = btn;
00368 }
00369 break;
00370 case 'A':
00371 if ((!m_button[MaxButton]) && isMaximizable()){
00372 btn = createButton(MaxButton);
00373 if (!btn) break;
00374 btn->setRealizeButtons(LeftButton|MidButton|RightButton);
00375 const bool max = maximizeMode()==MaximizeFull;
00376 btn->setTipText(max?i18n("Restore"):i18n("Maximize") );
00377 btn->setToggleButton(true);
00378 btn->setOn( max );
00379 connect(btn, SIGNAL(clicked()), SLOT(slotMaximize()));
00380
00381 m_button[MaxButton] = btn;
00382 }
00383 break;
00384 case 'X':
00385 if ((!m_button[CloseButton]) && isCloseable()){
00386 btn = createButton(CloseButton);
00387 if (!btn) break;
00388 btn->setTipText(i18n("Close") );
00389 connect(btn, SIGNAL(clicked()), SLOT(closeWindow()));
00390
00391 m_button[CloseButton] = btn;
00392 }
00393 break;
00394 case 'F':
00395 if (!m_button[AboveButton]){
00396 btn = createButton(AboveButton);
00397 if (!btn) break;
00398 bool above = keepAbove();
00399 btn->setTipText(above?i18n("Do not keep above others"):i18n("Keep above others") );
00400 btn->setToggleButton(true);
00401 btn->setOn( above );
00402 connect(btn, SIGNAL(clicked()), SLOT(slotKeepAbove()));
00403
00404 m_button[AboveButton] = btn;
00405 }
00406 break;
00407 case 'B':
00408 if (!m_button[BelowButton]){
00409 btn = createButton(BelowButton);
00410 if (!btn) break;
00411 bool below = keepBelow();
00412 btn->setTipText(below?i18n("Do not keep below others"):i18n("Keep below others") );
00413 btn->setToggleButton(true);
00414 btn->setOn( below );
00415 connect(btn, SIGNAL(clicked()), SLOT(slotKeepBelow()));
00416
00417 m_button[BelowButton] = btn;
00418 }
00419 break;
00420 case 'L':
00421 if ((!m_button[ShadeButton]) && isShadeable()){
00422 btn = createButton(ShadeButton);
00423 if (!btn) break;
00424 bool shaded = isSetShade();
00425 btn->setTipText(shaded?i18n("Unshade"):i18n("Shade") );
00426 btn->setToggleButton(true);
00427 btn->setOn( shaded );
00428 connect(btn, SIGNAL(clicked()), SLOT(slotShade()));
00429
00430 m_button[ShadeButton] = btn;
00431 }
00432 break;
00433 case '_':
00434 btnContainer.append(0);
00435 }
00436
00437
00438 if (btn) {
00439 btn->setLeft(isLeft);
00440 btn->setSize(QSize(layoutMetric(LM_ButtonWidth, true, btn),layoutMetric(LM_ButtonHeight, true, btn)) );
00441 btn->show();
00442 btnContainer.append(btn);
00443 }
00444
00445 }
00446 }
00447 }
00448
00449 void KCommonDecoration::calcHiddenButtons()
00450 {
00451 if (width() == btnHideLastWidth)
00452 return;
00453
00454 btnHideLastWidth = width();
00455
00456
00457 KCommonDecorationButton* btnArray[] = { m_button[HelpButton], m_button[ShadeButton], m_button[BelowButton],
00458 m_button[AboveButton], m_button[OnAllDesktopsButton], m_button[MaxButton],
00459 m_button[MinButton], m_button[MenuButton], m_button[CloseButton] };
00460 const int buttonsCount = sizeof( btnArray ) / sizeof( btnArray[ 0 ] );
00461
00462 int current_width = width();
00463 int count = 0;
00464
00465
00466 while (current_width < btnHideMinWidth && count < buttonsCount)
00467 {
00468 if (btnArray[count] ) {
00469 current_width += btnArray[count]->width();
00470 if (btnArray[count]->isVisible() )
00471 btnArray[count]->hide();
00472 }
00473 count++;
00474 }
00475
00476 for(int i = count; i < buttonsCount; i++)
00477 {
00478 if (btnArray[i] ) {
00479
00480 if (! btnArray[i]->isHidden() )
00481 break;
00482
00483 btnArray[i]->show();
00484 }
00485 }
00486 }
00487
00488 void KCommonDecoration::show()
00489 {
00490 if (decorationBehaviour(DB_ButtonHide) )
00491 calcHiddenButtons();
00492 widget()->show();
00493 }
00494
00495 void KCommonDecoration::resize( const QSize& s )
00496 {
00497 widget()->resize( s );
00498 }
00499
00500 QSize KCommonDecoration::minimumSize() const
00501 {
00502 const int minWidth = QMAX(layoutMetric(LM_TitleEdgeLeft), layoutMetric(LM_BorderLeft))
00503 +QMAX(layoutMetric(LM_TitleEdgeRight), layoutMetric(LM_BorderRight))
00504 +layoutMetric(LM_TitleBorderLeft)+layoutMetric(LM_TitleBorderRight);
00505 return QSize(minWidth,
00506 layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)
00507 +layoutMetric(LM_TitleEdgeBottom)
00508 +layoutMetric(LM_BorderBottom) );
00509 }
00510
00511 void KCommonDecoration::maximizeChange()
00512 {
00513 if( m_button[MaxButton] ) {
00514 m_button[MaxButton]->setOn( maximizeMode()==MaximizeFull);
00515 m_button[MaxButton]->setTipText( (maximizeMode()!=MaximizeFull) ?
00516 i18n("Maximize")
00517 : i18n("Restore"));
00518 m_button[MaxButton]->reset(KCommonDecorationButton::StateChange);
00519 }
00520 updateWindowShape();
00521 widget()->update();
00522 }
00523
00524 void KCommonDecoration::desktopChange()
00525 {
00526 if ( m_button[OnAllDesktopsButton] ) {
00527 m_button[OnAllDesktopsButton]->setOn( isOnAllDesktops() );
00528 m_button[OnAllDesktopsButton]->setTipText( isOnAllDesktops() ?
00529 i18n("Not on all desktops")
00530 : i18n("On all desktops"));
00531 m_button[OnAllDesktopsButton]->reset(KCommonDecorationButton::StateChange);
00532 }
00533 }
00534
00535 void KCommonDecoration::shadeChange()
00536 {
00537 if ( m_button[ShadeButton] ) {
00538 bool shaded = isSetShade();
00539 m_button[ShadeButton]->setOn( shaded );
00540 m_button[ShadeButton]->setTipText( shaded ?
00541 i18n("Unshade")
00542 : i18n("Shade"));
00543 m_button[ShadeButton]->reset(KCommonDecorationButton::StateChange);
00544 }
00545 }
00546
00547 void KCommonDecoration::iconChange()
00548 {
00549 if (m_button[MenuButton])
00550 {
00551 m_button[MenuButton]->update();
00552 m_button[MenuButton]->reset(KCommonDecorationButton::IconChange);
00553 }
00554 }
00555
00556 void KCommonDecoration::activeChange()
00557 {
00558 updateButtons();
00559 widget()->update();
00560 }
00561
00562 void KCommonDecoration::captionChange()
00563 {
00564 updateCaption();
00565 }
00566
00567 void KCommonDecoration::keepAboveChange(bool above)
00568 {
00569 if (m_button[AboveButton])
00570 {
00571 m_button[AboveButton]->setOn(above);
00572 m_button[AboveButton]->setTipText( above?i18n("Do not keep above others"):i18n("Keep above others") );
00573 m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
00574 }
00575
00576 if (m_button[BelowButton] && m_button[BelowButton]->isOn())
00577 {
00578 m_button[BelowButton]->setOn(false);
00579 m_button[BelowButton]->setTipText( i18n("Keep below others") );
00580 m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
00581 }
00582 }
00583
00584 void KCommonDecoration::keepBelowChange(bool below)
00585 {
00586 if (m_button[BelowButton])
00587 {
00588 m_button[BelowButton]->setOn(below);
00589 m_button[BelowButton]->setTipText( below?i18n("Do not keep below others"):i18n("Keep below others") );
00590 m_button[BelowButton]->reset(KCommonDecorationButton::StateChange);
00591 }
00592
00593 if (m_button[AboveButton] && m_button[AboveButton]->isOn())
00594 {
00595 m_button[AboveButton]->setOn(false);
00596 m_button[AboveButton]->setTipText( i18n("Keep above others") );
00597 m_button[AboveButton]->reset(KCommonDecorationButton::StateChange);
00598 }
00599 }
00600
00601 void KCommonDecoration::slotMaximize()
00602 {
00603 if (m_button[MaxButton])
00604 {
00605 maximize(m_button[MaxButton]->lastMousePress() );
00606 }
00607 }
00608
00609 void KCommonDecoration::slotShade()
00610 {
00611 setShade( !isSetShade() );
00612 }
00613
00614 void KCommonDecoration::slotKeepAbove()
00615 {
00616 setKeepAbove(!keepAbove() );
00617 }
00618
00619 void KCommonDecoration::slotKeepBelow()
00620 {
00621 setKeepBelow(!keepBelow() );
00622 }
00623
00624 void KCommonDecoration::menuButtonPressed()
00625 {
00626 static QTime* t = NULL;
00627 static KCommonDecoration* lastClient = NULL;
00628 if (t == NULL)
00629 t = new QTime;
00630 bool dbl = (lastClient==this && t->elapsed() <= QApplication::doubleClickInterval());
00631 lastClient = this;
00632 t->start();
00633 if (!dbl || !decorationBehaviour(DB_MenuClose) ) {
00634 QRect menuRect = m_button[MenuButton]->rect();
00635 QPoint menutop = m_button[MenuButton]->mapToGlobal(menuRect.topLeft());
00636 QPoint menubottom = m_button[MenuButton]->mapToGlobal(menuRect.bottomRight())+QPoint(0,2);
00637 KDecorationFactory* f = factory();
00638 showWindowMenu(QRect(menutop, menubottom));
00639 if( !f->exists( this ))
00640 return;
00641 m_button[MenuButton]->setDown(false);
00642 }
00643 else
00644 closing = true;
00645 }
00646
00647 void KCommonDecoration::menuButtonReleased()
00648 {
00649 if(closing)
00650 closeWindow();
00651 }
00652
00653 void KCommonDecoration::resizeEvent(QResizeEvent *)
00654 {
00655 if (decorationBehaviour(DB_ButtonHide) )
00656 calcHiddenButtons();
00657
00658 updateLayout();
00659
00660 updateWindowShape();
00661
00662
00663
00664 }
00665
00666 void KCommonDecoration::moveWidget(int x, int y, QWidget *widget) const
00667 {
00668 QPoint p = widget->pos();
00669 int oldX = p.y();
00670 int oldY = p.x();
00671
00672 if (x!=oldX || y!=oldY)
00673 widget->move(x,y);
00674 }
00675
00676 void KCommonDecoration::resizeWidget(int w, int h, QWidget *widget) const
00677 {
00678 QSize s = widget->size();
00679 int oldW = s.width();
00680 int oldH = s.height();
00681
00682 if (w!=oldW || h!=oldH)
00683 widget->resize(w,h);
00684 }
00685
00686 void KCommonDecoration::mouseDoubleClickEvent(QMouseEvent *e)
00687 {
00688 if( e->button() != LeftButton )
00689 return;
00690
00691 int tb = layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)+layoutMetric(LM_TitleEdgeBottom);
00692
00693
00694 if (isSetShade() || e->pos().y() <= tb )
00695 titlebarDblClickOperation();
00696 }
00697
00698 void KCommonDecoration::wheelEvent(QWheelEvent *e)
00699 {
00700 int tb = layoutMetric(LM_TitleEdgeTop)+layoutMetric(LM_TitleHeight)+layoutMetric(LM_TitleEdgeBottom);
00701 if (isSetShade() || e->pos().y() <= tb )
00702 titlebarMouseWheelOperation( e->delta());
00703 }
00704
00705 KCommonDecoration::Position KCommonDecoration::mousePosition(const QPoint &point) const
00706 {
00707 const int corner = 18+3*layoutMetric(LM_BorderBottom, false)/2;
00708 Position pos = PositionCenter;
00709
00710 QRect r = widget()->rect();
00711 int r_x, r_y, r_x2, r_y2;
00712 r.coords(&r_x, &r_y, &r_x2, &r_y2);
00713 int p_x = point.x();
00714 int p_y = point.y();
00715 const int borderLeft = layoutMetric(LM_BorderLeft);
00716
00717 const int borderBottom = layoutMetric(LM_BorderBottom);
00718 const int titleHeight = layoutMetric(LM_TitleHeight);
00719 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
00720 const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
00721 const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
00722 const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
00723
00724 const int borderBottomTop = r_y2-borderBottom+1;
00725 const int borderLeftRight = r_x+borderLeft-1;
00726
00727 const int titleEdgeLeftRight = r_x+titleEdgeLeft-1;
00728 const int titleEdgeRightLeft = r_x2-titleEdgeRight+1;
00729 const int titleEdgeBottomBottom = r_y+titleEdgeTop+titleHeight+titleEdgeBottom-1;
00730 const int titleEdgeTopBottom = r_y+titleEdgeTop-1;
00731
00732 if (p_y <= titleEdgeTopBottom) {
00733 if (p_x <= r_x+corner)
00734 pos = PositionTopLeft;
00735 else if (p_x >= r_x2-corner)
00736 pos = PositionTopRight;
00737 else
00738 pos = PositionTop;
00739 } else if (p_y <= titleEdgeBottomBottom) {
00740 if (p_x <= titleEdgeLeftRight)
00741 pos = PositionTopLeft;
00742 else if (p_x >= titleEdgeRightLeft)
00743 pos = PositionTopRight;
00744 else
00745 pos = PositionCenter;
00746 } else if (p_y < borderBottomTop) {
00747 if (p_y < r_y2-corner) {
00748 if (p_x <= borderLeftRight)
00749 pos = PositionLeft;
00750 else
00751 pos = PositionRight;
00752 } else {
00753 if (p_x <= borderLeftRight)
00754 pos = PositionBottomLeft;
00755 else
00756 pos = PositionBottomRight;
00757 }
00758 } else if(p_y >= borderBottomTop) {
00759 if (p_x <= r_x+corner)
00760 pos = PositionBottomLeft;
00761 else if (p_x >= r_x2-corner)
00762 pos = PositionBottomRight;
00763 else
00764 pos = PositionBottom;
00765 }
00766
00767 return pos;
00768 }
00769
00770 void KCommonDecoration::updateWindowShape()
00771 {
00772
00773 if (!decorationBehaviour(DB_WindowMask) )
00774 return;
00775
00776 int w = widget()->width();
00777 int h = widget()->height();
00778
00779 bool tl=true,tr=true,bl=true,br=true;
00780
00781 QDesktopWidget *desktop=KApplication::desktop();
00782
00783 for(int screen=0; screen < desktop->numScreens(); ++screen)
00784 {
00785 QRect fullscreen(desktop->screenGeometry(screen));
00786 QRect window = geometry();
00787
00788 if(window.topLeft() == fullscreen.topLeft() ) tl = false;
00789 if(window.topRight() == fullscreen.topRight() ) tr = false;
00790 if(window.bottomLeft() == fullscreen.bottomLeft() ) bl = false;
00791 if(window.bottomRight()== fullscreen.bottomRight() ) br = false;
00792 }
00793
00794 QRegion mask(0, 0, w, h);
00795
00796
00797 if(tl)
00798 {
00799 mask -= cornerShape(WC_TopLeft);
00800 }
00801
00802 if(tr)
00803 {
00804 mask -= cornerShape(WC_TopRight);
00805 }
00806
00807 if(bl)
00808 {
00809 mask -= cornerShape(WC_BottomLeft);
00810 }
00811
00812 if(br)
00813 {
00814 mask -= cornerShape(WC_BottomRight);
00815 }
00816
00817 setMask( mask );
00818 }
00819
00820 bool KCommonDecoration::eventFilter( QObject* o, QEvent* e )
00821 {
00822 if( o != widget())
00823 return false;
00824 switch( e->type())
00825 {
00826 case QEvent::Resize:
00827 resizeEvent(static_cast<QResizeEvent*>(e) );
00828 return true;
00829 case QEvent::Paint:
00830 paintEvent( static_cast< QPaintEvent* >( e ));
00831 return true;
00832 case QEvent::MouseButtonDblClick:
00833 mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ));
00834 return true;
00835 case QEvent::MouseButtonPress:
00836 processMousePressEvent( static_cast< QMouseEvent* >( e ));
00837 return true;
00838 case QEvent::Wheel:
00839 wheelEvent( static_cast< QWheelEvent* >( e ));
00840 return true;
00841 default:
00842 return false;
00843 }
00844 }
00845
00846 const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
00847 | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::TopMenuMask
00848 | NET::UtilityMask | NET::SplashMask;
00849
00850 bool KCommonDecoration::isToolWindow() const
00851 {
00852 NET::WindowType type = windowType( SUPPORTED_WINDOW_TYPES_MASK );
00853 return ((type==NET::Toolbar)||(type==NET::Utility)||(type==NET::Menu));
00854 }
00855
00856 QRect KCommonDecoration::titleRect() const
00857 {
00858 int r_x, r_y, r_x2, r_y2;
00859 widget()->rect().coords(&r_x, &r_y, &r_x2, &r_y2);
00860 const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
00861 const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
00862 const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
00863 const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
00864 const int titleBorderLeft = layoutMetric(LM_TitleBorderLeft);
00865 const int titleBorderRight = layoutMetric(LM_TitleBorderRight);
00866 const int ttlHeight = layoutMetric(LM_TitleHeight);
00867 const int titleEdgeBottomBottom = r_y+titleEdgeTop+ttlHeight+titleEdgeBottom-1;
00868 return QRect(r_x+titleEdgeLeft+buttonsLeftWidth()+titleBorderLeft, r_y+titleEdgeTop,
00869 r_x2-titleEdgeRight-buttonsRightWidth()-titleBorderRight-(r_x+titleEdgeLeft+buttonsLeftWidth()+titleBorderLeft),
00870 titleEdgeBottomBottom-(r_y+titleEdgeTop) );
00871 }
00872
00873
00874 KCommonDecorationButton::KCommonDecorationButton(ButtonType type, KCommonDecoration *parent, const char *name)
00875 : QButton(parent->widget(), name),
00876 m_decoration(parent),
00877 m_type(type),
00878 m_realizeButtons(LeftButton),
00879 m_lastMouse(NoButton),
00880 m_isLeft(true)
00881 {
00882 setCursor(ArrowCursor);
00883 }
00884
00885 KCommonDecorationButton::~KCommonDecorationButton()
00886 {
00887 }
00888
00889 KCommonDecoration *KCommonDecorationButton::decoration() const
00890 {
00891 return m_decoration;
00892 }
00893
00894 ButtonType KCommonDecorationButton::type() const
00895 {
00896 return m_type;
00897 }
00898
00899 bool KCommonDecorationButton::isLeft() const
00900 {
00901 return m_isLeft;
00902 }
00903
00904 void KCommonDecorationButton::setLeft(bool left)
00905 {
00906 m_isLeft = left;
00907 }
00908
00909 void KCommonDecorationButton::setRealizeButtons(int btns)
00910 {
00911 m_realizeButtons = btns;
00912 }
00913
00914 void KCommonDecorationButton::setSize(const QSize &s)
00915 {
00916 if (!m_size.isValid() || s != size() ) {
00917 m_size = s;
00918
00919 setFixedSize(m_size);
00920 reset(SizeChange);
00921 }
00922 }
00923
00924 QSize KCommonDecorationButton::sizeHint() const
00925 {
00926 return m_size;
00927 }
00928
00929 void KCommonDecorationButton::setTipText(const QString &tip) {
00930 QToolTip::remove(this );
00931 QToolTip::add(this, tip );
00932 }
00933
00934 void KCommonDecorationButton::setToggleButton(bool toggle)
00935 {
00936 QButton::setToggleButton(toggle);
00937 reset(ToggleChange);
00938 }
00939
00940 void KCommonDecorationButton::setOn(bool on)
00941 {
00942 if (on != isOn() ) {
00943 QButton::setOn(on);
00944 reset(StateChange);
00945 }
00946 }
00947
00948 void KCommonDecorationButton::mousePressEvent(QMouseEvent* e)
00949 {
00950 m_lastMouse = e->button();
00951
00952 QMouseEvent me(e->type(), e->pos(), e->globalPos(),
00953 (e->button()&m_realizeButtons)?LeftButton:NoButton, e->state());
00954
00955 QButton::mousePressEvent(&me);
00956 }
00957
00958 void KCommonDecorationButton::mouseReleaseEvent(QMouseEvent* e)
00959 {
00960 m_lastMouse = e->button();
00961
00962 QMouseEvent me(e->type(), e->pos(), e->globalPos(),
00963 (e->button()&m_realizeButtons)?LeftButton:NoButton, e->state());
00964
00965 QButton::mouseReleaseEvent(&me);
00966 }