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