1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_vcl.hxx" 26 27 #define _SV_SALNATIVEWIDGETS_KDE_CXX 28 #include <shell/kde_headers.h> 29 30 #include <unx/salunx.h> 31 #include <unx/saldata.hxx> 32 #include <unx/saldisp.hxx> 33 #include <unx/salgdi.h> 34 #include <unx/pspgraphics.h> 35 #include <unx/kde/kdedata.hxx> 36 37 #include <vcl/settings.hxx> 38 #include <rtl/ustrbuf.hxx> 39 40 41 using namespace ::rtl; 42 43 /** Cached native widgets. 44 45 A class which caches and paints the native widgets. 46 */ 47 class WidgetPainter 48 { 49 protected: 50 /** Cached push button. 51 52 It is necessary for the QStyle::drawControl(). The buttons are created 53 on demand and they are still hidden (no QWidget::show() is called). 54 */ 55 QPushButton *m_pPushButton; 56 57 /** Cached radio button. 58 59 @see m_pPushButton 60 */ 61 QRadioButton *m_pRadioButton; 62 63 /** Cached check box. 64 65 @see m_pPushButton 66 */ 67 QCheckBox *m_pCheckBox; 68 69 /** Cached combo box. 70 71 @see m_pPushButton 72 */ 73 QComboBox *m_pComboBox; 74 75 /** Cached editable combo box. 76 77 Needed, because some styles do not like dynamic changes 78 (QComboBox::setEditable()). 79 80 @see m_pPushButton 81 */ 82 QComboBox *m_pEditableComboBox; 83 84 /** Cached line edit box. 85 86 @see m_pPushButton 87 */ 88 QLineEdit *m_pLineEdit; 89 90 /** Cached spin box. 91 92 @see m_pPushButton 93 */ 94 QSpinWidget *m_pSpinWidget; 95 96 /** Cached spin box'es line edit. 97 98 @see m_pPushButton 99 */ 100 QLineEdit *m_pSpinEdit; 101 102 /** Cached tab. 103 104 Left, middle, right tab and a tab which is alone. 105 106 @see m_pPushButton 107 */ 108 QTab *m_pTabLeft, *m_pTabMiddle, *m_pTabRight, *m_pTabAlone; 109 110 /** Cached tab bar's parent widget. 111 112 Needed, because the Qt windows style checks for the availability 113 of tab bar's parent. We cannot use m_pTabWidget, because 114 TabWidget::setTabBar() and TabWidget::tabBar() methods are 115 protected. 116 117 @see m_pPushButton, m_pTabWidget 118 */ 119 QWidget *m_pTabBarParent; 120 121 /** Cached tab bar widget. 122 123 @see m_pPushButton 124 */ 125 QTabBar *m_pTabBar; 126 127 /** Cached tab widget. 128 129 We need it to draw the tab page. It cannot be used to draw the 130 tabs themselves, because the drawing has to be tweaked a little 131 due to not enough information from VCL. 132 133 @see m_pPushButton, m_pTabBarParent 134 */ 135 QTabWidget *m_pTabWidget; 136 137 /** Cached list view. 138 139 @see m_pPushButton 140 */ 141 QListView *m_pListView; 142 143 /** Cached scroll bar. 144 145 @see m_pPushButton 146 */ 147 QScrollBar *m_pScrollBar; 148 149 /** Cached dock area. Needed for proper functionality of tool bars. 150 151 @see m_pPushButton 152 */ 153 QMainWindow *m_pMainWindow; 154 155 /** Cached tool bar. 156 157 @see m_pPushButton 158 */ 159 QToolBar *m_pToolBarHoriz, *m_pToolBarVert; 160 161 /** Cached tool button. 162 163 @see m_pPushButton 164 */ 165 QToolButton *m_pToolButton; 166 167 /** Cached menu bar. 168 169 @see m_pPushButton 170 */ 171 QMenuBar *m_pMenuBar; 172 173 /** Identifiers of menu bar items. 174 */ 175 int m_nMenuBarEnabledItem, m_nMenuBarDisabledItem; 176 177 /** Cached popup menu. 178 179 @see m_pPushButton 180 */ 181 QPopupMenu *m_pPopupMenu; 182 183 /** Identifiers of popup menu items. 184 */ 185 int m_nPopupMenuEnabledItem, m_nPopupMenuDisabledItem; 186 187 /** cached progress bar 188 */ 189 QProgressBar *m_pProgressBar; 190 191 // TODO other widgets 192 193 public: 194 /** Implicit constructor. 195 196 It creates an empty WidgetPainter with all the cached widgets initialized 197 to NULL. The widgets are created on demand and they are still hidden 198 (no QWidget::show()), because they are needed just as a parameter for 199 QStyle::drawControl(). 200 201 @see m_pPushButton 202 */ 203 WidgetPainter( void ); 204 205 /** Destructor. 206 207 Destruct all the cached widgets. 208 */ 209 virtual ~WidgetPainter( void ); 210 211 /** Paints the specified widget to the X window. 212 213 Use X calls to bitblt (bit block transfer) the widget qWidget to 214 the window specified by drawable with the style defined by nStyle. 215 216 @param qWidget 217 A pointer to the cached widget. 218 219 @param nState 220 The state of the control (focused, on/off, ...) 221 222 @param aValue 223 The value (true/false, ...) 224 225 @param dpy 226 The display to be used by the X calls. 227 228 @param drawable 229 The destination X window. 230 231 @param gc 232 The graphics context. 233 */ 234 sal_Bool drawStyledWidget( QWidget *pWidget, 235 ControlState nState, const ImplControlValue& aValue, 236 Display *dpy, XLIB_Window drawable, int nScreen, int nDepth, GC gc, 237 ControlPart nPart = PART_ENTIRE_CONTROL ); 238 239 /** 'Get' method for push button. 240 241 The method returns the cached push button. It is constructed if it 242 does not exist. It has NULL as a parent and it stays hidden, but it 243 is necessary for the drawStyledWidget() method. 244 245 @return valid push button. 246 */ 247 QPushButton *pushButton( const Rectangle& rControlRegion, sal_Bool bDefault ); 248 249 /** 'Get' method for radio button. 250 251 @see pushButton() 252 */ 253 QRadioButton *radioButton( const Rectangle& rControlRegion ); 254 255 /** 'Get' method for check box. 256 257 @see pushButton() 258 */ 259 QCheckBox *checkBox( const Rectangle& rControlRegion ); 260 261 /** 'Get' method for combo box. 262 263 It returns m_pComboBox or m_pEditableComboBox according to 264 bEditable. 265 266 @see pushButton(), m_pEditableComboBox 267 */ 268 QComboBox *comboBox( const Rectangle& rControlRegion, sal_Bool bEditable ); 269 270 /** 'Get' method for line edit box. 271 272 @see pushButton() 273 */ 274 QLineEdit *lineEdit( const Rectangle& rControlRegion ); 275 276 /** 'Get' method for spin box. 277 278 @see pushButton() 279 */ 280 QSpinWidget *spinWidget( const Rectangle& rControlRegion ); 281 282 /** 'Get' method for tab bar. 283 284 @see pushButton() 285 */ 286 QTabBar *tabBar( const Rectangle& rControlRegion ); 287 288 /** 'Get' method for tab widget. 289 290 @see pushButton() 291 */ 292 QTabWidget *tabWidget( const Rectangle& rControlRegion ); 293 294 /** 'Get' method for list view. 295 296 @see pushButton() 297 */ 298 QListView *listView( const Rectangle& rControlRegion ); 299 300 /** 'Get' method for scroll bar. 301 302 @see pushButton() 303 */ 304 QScrollBar *scrollBar( const Rectangle& rControlRegion, 305 sal_Bool bHorizontal, const ImplControlValue& aValue ); 306 307 /** 'Get' method for tool bar. 308 309 @see pushButton() 310 */ 311 QToolBar *toolBar( const Rectangle& rControlRegion, sal_Bool bHorizontal ); 312 313 /** 'Get' method for tool button. 314 315 @see pushButton() 316 */ 317 QToolButton *toolButton( const Rectangle& rControlRegion ); 318 319 /** 'Get' method for menu bar. 320 321 @see pushButton() 322 */ 323 QMenuBar *menuBar( const Rectangle& rControlRegion ); 324 325 /** 'Get' method for popup menu. 326 327 @see pushButton() 328 */ 329 QPopupMenu *popupMenu( const Rectangle& rControlRegion ); 330 331 /** 'Get' method for progress bar 332 333 @see pushButton() 334 */ 335 QProgressBar *progressBar( const Rectangle& rControlRegion ); 336 337 // TODO other widgets 338 339 protected: 340 /** Style conversion function. 341 342 Conversion function between VCL ControlState together with 343 ImplControlValue and Qt state flags. 344 345 @param nState 346 State of the widget (default, focused, ...) as defined in Native 347 Widget Framework. 348 349 @param aValue 350 Value held by the widget (on, off, ...) 351 */ 352 QStyle::SFlags vclStateValue2SFlags( ControlState nState, const ImplControlValue& aValue ); 353 354 public: 355 /** Convert VCL Rectangle to QRect. 356 357 @param rControlRegion 358 The region to convert. 359 360 @return 361 The bounding box of the region. 362 */ 363 static QRect region2QRect( const Rectangle& rControlRegion ); 364 }; 365 366 WidgetPainter::WidgetPainter( void ) 367 : m_pPushButton( NULL ), 368 m_pRadioButton( NULL ), 369 m_pCheckBox( NULL ), 370 m_pComboBox( NULL ), 371 m_pEditableComboBox( NULL ), 372 m_pLineEdit( NULL ), 373 m_pSpinWidget( NULL ), 374 m_pSpinEdit( NULL ), 375 m_pTabLeft( NULL ), 376 m_pTabMiddle( NULL ), 377 m_pTabRight( NULL ), 378 m_pTabAlone( NULL ), 379 m_pTabBarParent( NULL ), 380 m_pTabBar( NULL ), 381 m_pTabWidget( NULL ), 382 m_pListView( NULL ), 383 m_pScrollBar( NULL ), 384 m_pMainWindow( NULL ), 385 m_pToolBarHoriz( NULL ), 386 m_pToolBarVert( NULL ), 387 m_pToolButton( NULL ), 388 m_pMenuBar( NULL ), 389 m_pPopupMenu( NULL ), 390 m_pProgressBar( NULL ) 391 { 392 } 393 394 WidgetPainter::~WidgetPainter( void ) 395 { 396 delete m_pPushButton, m_pPushButton = NULL; 397 delete m_pRadioButton, m_pRadioButton = NULL; 398 delete m_pCheckBox, m_pCheckBox = NULL; 399 delete m_pComboBox, m_pComboBox = NULL; 400 delete m_pEditableComboBox, m_pEditableComboBox = NULL; 401 delete m_pLineEdit, m_pLineEdit = NULL; 402 delete m_pSpinWidget, m_pSpinWidget = NULL; 403 m_pSpinEdit = NULL; // Deleted in m_pSpinWidget's destructor 404 delete m_pTabAlone, m_pTabAlone = NULL; 405 delete m_pTabBarParent, m_pTabBarParent = NULL; 406 m_pTabBar = NULL; // Deleted in m_pTabBarParent's destructor 407 m_pTabLeft = NULL; 408 m_pTabMiddle = NULL; 409 m_pTabRight = NULL; 410 delete m_pTabWidget, m_pTabWidget = NULL; 411 delete m_pListView, m_pListView = NULL; 412 delete m_pScrollBar, m_pScrollBar = NULL; 413 delete m_pToolBarHoriz, m_pToolBarHoriz = NULL; 414 delete m_pToolBarVert, m_pToolBarVert = NULL; 415 delete m_pMainWindow, m_pMainWindow = NULL; 416 delete m_pToolButton, m_pToolButton = NULL; 417 delete m_pMenuBar, m_pMenuBar = NULL; 418 delete m_pPopupMenu, m_pPopupMenu = NULL; 419 delete m_pProgressBar, m_pProgressBar = NULL; 420 } 421 422 sal_Bool WidgetPainter::drawStyledWidget( QWidget *pWidget, 423 ControlState nState, const ImplControlValue& aValue, 424 Display *dpy, XLIB_Window drawable, int nScreen, int nDepth, GC gc, 425 ControlPart nPart ) 426 { 427 if ( !pWidget ) 428 return sal_False; 429 430 // Normalize the widget 431 QPoint qWidgetPos( pWidget->pos() ); 432 pWidget->move( 0, 0 ); 433 434 // Enable/disable the widget 435 pWidget->setEnabled( nState & CTRL_STATE_ENABLED ); 436 437 // Create pixmap to paint to 438 QPixmap qPixmap( pWidget->width(), pWidget->height() ); 439 QPainter qPainter( &qPixmap ); 440 QRect qRect( 0, 0, pWidget->width(), pWidget->height() ); 441 442 // Use the background of the widget 443 qPixmap.fill( pWidget, QPoint(0, 0) ); 444 445 // Convert the flags 446 QStyle::SFlags nStyle = vclStateValue2SFlags( nState, aValue ); 447 448 // Store the widget class 449 const char *pClassName = pWidget->className(); 450 451 // Draw the widget to the pixmap 452 if ( strcmp( "QPushButton", pClassName ) == 0 ) 453 { 454 // Workaround for the Platinum style. 455 // Platinum takes the state directly from the widget, not from SFlags. 456 QPushButton *pPushButton = static_cast<QPushButton *>( pWidget->qt_cast( "QPushButton" ) ); 457 if ( pPushButton ) 458 { 459 pPushButton->setDown ( nStyle & QStyle::Style_Down ); 460 pPushButton->setOn ( nStyle & QStyle::Style_On ); 461 pPushButton->setEnabled( nStyle & QStyle::Style_Enabled ); 462 } 463 464 kapp->style().drawControl( QStyle::CE_PushButton, 465 &qPainter, pWidget, qRect, 466 pWidget->colorGroup(), nStyle ); 467 } 468 else if ( strcmp( "QRadioButton", pClassName ) == 0 ) 469 { 470 // Bitblt from the screen, because the radio buttons are usually not 471 // rectangular, and there could be a bitmap under them 472 GC aTmpGC = XCreateGC( dpy, qPixmap.handle(), 0, NULL ); 473 X11SalGraphics::CopyScreenArea( dpy, 474 drawable, nScreen, nDepth, 475 qPixmap.handle(), qPixmap.x11Screen(), qPixmap.x11Depth(), 476 aTmpGC, 477 qWidgetPos.x(), qWidgetPos.y(), qRect.width(), qRect.height(), 478 0, 0 ); 479 XFreeGC( dpy, aTmpGC ); 480 481 kapp->style().drawControl( QStyle::CE_RadioButton, 482 &qPainter, pWidget, qRect, 483 pWidget->colorGroup(), nStyle ); 484 } 485 else if ( strcmp( "QCheckBox", pClassName ) == 0 ) 486 { 487 kapp->style().drawControl( QStyle::CE_CheckBox, 488 &qPainter, pWidget, qRect, 489 pWidget->colorGroup(), nStyle ); 490 } 491 else if ( strcmp( "QComboBox", pClassName ) == 0 ) 492 { 493 kapp->style().drawComplexControl( QStyle::CC_ComboBox, 494 &qPainter, pWidget, qRect, 495 pWidget->colorGroup(), nStyle ); 496 497 // Editable combo box uses the background of the associated edit box 498 QComboBox *pComboBox = static_cast<QComboBox *>( pWidget->qt_cast( "QComboBox" ) ); 499 if ( pComboBox && pComboBox->editable() && pComboBox->lineEdit() ) 500 { 501 QColorGroup::ColorRole eColorRole = ( pComboBox->isEnabled() )? 502 QColorGroup::Base: QColorGroup::Background; 503 qPainter.fillRect( 504 kapp->style().querySubControlMetrics( QStyle::CC_ComboBox, 505 pComboBox, QStyle::SC_ComboBoxEditField ), 506 pComboBox->lineEdit()->colorGroup().brush( eColorRole ) ); 507 } 508 } 509 else if ( strcmp( "QLineEdit", pClassName ) == 0 ) 510 { 511 kapp->style().drawPrimitive( QStyle::PE_PanelLineEdit, 512 &qPainter, qRect, 513 pWidget->colorGroup(), nStyle | QStyle::Style_Sunken ); 514 } 515 else if ( strcmp( "QSpinWidget", pClassName ) == 0 ) 516 { 517 const SpinbuttonValue* pValue = (aValue.getType() == CTRL_SPINBUTTONS) ? static_cast<const SpinbuttonValue*>(&aValue) : NULL; 518 519 // Is any of the buttons pressed? 520 QStyle::SCFlags eActive = QStyle::SC_None; 521 if ( pValue ) 522 { 523 if ( pValue->mnUpperState & CTRL_STATE_PRESSED ) 524 eActive = QStyle::SC_SpinWidgetUp; 525 else if ( pValue->mnLowerState & CTRL_STATE_PRESSED ) 526 eActive = QStyle::SC_SpinWidgetDown; 527 528 // Update the enable/disable state of the widget 529 if ( ( nState & CTRL_STATE_ENABLED ) || 530 ( pValue->mnUpperState & CTRL_STATE_ENABLED ) || 531 ( pValue->mnLowerState & CTRL_STATE_ENABLED ) ) 532 { 533 pWidget->setEnabled( true ); 534 nStyle |= QStyle::Style_Enabled; 535 } 536 else 537 pWidget->setEnabled( false ); 538 539 // Mouse-over effect 540 if ( (pValue->mnUpperState & CTRL_STATE_ROLLOVER) || 541 (pValue->mnLowerState & CTRL_STATE_ROLLOVER) ) 542 nStyle |= QStyle::Style_MouseOver; 543 } 544 545 // Spin widget uses the background of the associated edit box 546 QSpinWidget *pSpinWidget = static_cast<QSpinWidget *>( pWidget->qt_cast( "QSpinWidget" ) ); 547 if ( pSpinWidget && pSpinWidget->editWidget() ) 548 { 549 QColorGroup::ColorRole eColorRole = ( pSpinWidget->isEnabled() )? 550 QColorGroup::Base: QColorGroup::Background; 551 qPainter.fillRect( 552 kapp->style().querySubControlMetrics( QStyle::CC_SpinWidget, 553 pSpinWidget, QStyle::SC_SpinWidgetEditField ), 554 pSpinWidget->editWidget()->colorGroup().brush( eColorRole ) ); 555 } 556 557 // Adjust the frame (needed for Motif Plus style) 558 QRect qFrameRect = kapp->style().querySubControlMetrics( QStyle::CC_SpinWidget, 559 pWidget, QStyle::SC_SpinWidgetFrame ); 560 561 kapp->style().drawComplexControl( QStyle::CC_SpinWidget, 562 &qPainter, pWidget, qFrameRect, 563 pWidget->colorGroup(), nStyle, 564 QStyle::SC_All, eActive ); 565 } 566 else if ( strcmp( "QTabBar", pClassName ) == 0 ) 567 { 568 const TabitemValue *pValue = static_cast<const TabitemValue *> ( &aValue ); 569 570 QTab *pTab = NULL; 571 if ( pValue ) 572 { 573 if ( ( pValue->isFirst() || pValue->isLeftAligned() ) && ( pValue->isLast() || pValue->isRightAligned() ) ) 574 pTab = m_pTabAlone; 575 else if ( pValue->isFirst() || pValue->isLeftAligned() ) 576 pTab = m_pTabLeft; 577 else if ( pValue->isLast() || pValue->isRightAligned() ) 578 pTab = m_pTabRight; 579 else 580 pTab = m_pTabMiddle; 581 } 582 if ( !pTab ) 583 return sal_False; 584 585 pTab->setRect( qRect ); 586 587 kapp->style().drawControl( QStyle::CE_TabBarTab, 588 &qPainter, pWidget, qRect, 589 pWidget->colorGroup(), nStyle, 590 QStyleOption( pTab ) ); 591 } 592 else if ( strcmp( "QTabWidget", pClassName ) == 0 ) 593 { 594 kapp->style().drawPrimitive( QStyle::PE_PanelTabWidget, 595 &qPainter, qRect, 596 pWidget->colorGroup(), nStyle ); 597 } 598 else if ( strcmp( "QListView", pClassName ) == 0 ) 599 { 600 kapp->style().drawPrimitive( QStyle::PE_Panel, 601 &qPainter, qRect, 602 pWidget->colorGroup(), nStyle | QStyle::Style_Sunken ); 603 } 604 else if ( strcmp( "QScrollBar", pClassName ) == 0 ) 605 { 606 const ScrollbarValue* pScrollbarVal = (aValue.getType() == CTRL_SCROLLBAR) ? static_cast<const ScrollbarValue*>(&aValue) : NULL; 607 608 QStyle::SCFlags eActive = QStyle::SC_None; 609 if ( pValue ) 610 { 611 // Workaround for Style_MouseOver-aware themes. 612 // Quite ugly, but I do not know about a better solution. 613 const char *pStyleName = kapp->style().className(); 614 if ( strcmp( "QMotifPlusStyle", pStyleName ) == 0 ) 615 { 616 nStyle |= QStyle::Style_MouseOver; 617 if ( pValue->mnThumbState & CTRL_STATE_ROLLOVER ) 618 eActive = QStyle::SC_ScrollBarSlider; 619 } 620 else if ( strcmp( "QSGIStyle", pStyleName ) == 0 ) 621 { 622 nStyle |= QStyle::Style_MouseOver; 623 if ( pValue->mnButton1State & CTRL_STATE_ROLLOVER ) 624 eActive = QStyle::SC_ScrollBarSubLine; 625 else if ( pValue->mnButton2State & CTRL_STATE_ROLLOVER ) 626 eActive = QStyle::SC_ScrollBarAddLine; 627 else if ( pValue->mnThumbState & CTRL_STATE_ROLLOVER ) 628 eActive = QStyle::SC_ScrollBarSlider; 629 } 630 631 if ( pValue->mnButton1State & CTRL_STATE_PRESSED ) 632 eActive = QStyle::SC_ScrollBarSubLine; 633 else if ( pValue->mnButton2State & CTRL_STATE_PRESSED ) 634 eActive = QStyle::SC_ScrollBarAddLine; 635 else if ( pValue->mnThumbState & CTRL_STATE_PRESSED ) 636 eActive = QStyle::SC_ScrollBarSlider; 637 else if ( pValue->mnPage1State & CTRL_STATE_PRESSED ) 638 eActive = QStyle::SC_ScrollBarSubPage; 639 else if ( pValue->mnPage2State & CTRL_STATE_PRESSED ) 640 eActive = QStyle::SC_ScrollBarAddPage; 641 642 // Update the enable/disable state of the widget 643 if ( ( nState & CTRL_STATE_ENABLED ) || 644 ( pValue->mnButton1State & CTRL_STATE_ENABLED ) || 645 ( pValue->mnButton2State & CTRL_STATE_ENABLED ) || 646 ( pValue->mnThumbState & CTRL_STATE_ENABLED ) || 647 ( pValue->mnPage1State & CTRL_STATE_ENABLED ) || 648 ( pValue->mnPage2State & CTRL_STATE_ENABLED ) ) 649 { 650 pWidget->setEnabled( true ); 651 nStyle |= QStyle::Style_Enabled; 652 } 653 else 654 pWidget->setEnabled( false ); 655 } 656 657 // Is it a horizontal scroll bar? 658 QScrollBar *pScrollBar = static_cast<QScrollBar *> ( pWidget->qt_cast( "QScrollBar" ) ); 659 QStyle::StyleFlags eHoriz = QStyle::Style_Default; 660 if ( pScrollBar && pScrollBar->orientation() == Qt::Horizontal ) 661 eHoriz = QStyle::Style_Horizontal; 662 663 kapp->style().drawComplexControl( QStyle::CC_ScrollBar, 664 &qPainter, pWidget, qRect, 665 pWidget->colorGroup(), nStyle | eHoriz, 666 QStyle::SC_All, eActive ); 667 } 668 else if ( strcmp( "QToolBar", pClassName ) == 0 ) 669 { 670 QToolBar *pToolBar = static_cast< QToolBar * >( pWidget->qt_cast( "QToolBar" ) ); 671 bool bIsHorizontal = false; 672 if ( pToolBar && pToolBar->orientation() == Qt::Horizontal ) 673 { 674 nStyle |= QStyle::Style_Horizontal; 675 bIsHorizontal = true; 676 } 677 678 kapp->style().drawControl( QStyle::CE_DockWindowEmptyArea, 679 &qPainter, pWidget, qRect, 680 pWidget->colorGroup(), nStyle ); 681 682 kapp->style().drawPrimitive( QStyle::PE_PanelDockWindow, 683 &qPainter, qRect, pWidget->colorGroup(), nStyle ); 684 685 if ( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT ) 686 { 687 const ToolbarValue *pValue = static_cast< const ToolbarValue * >( &aValue ); 688 689 QRect qThumbRect = region2QRect( pValue->maGripRect ); 690 qThumbRect.moveBy( -qWidgetPos.x(), -qWidgetPos.y() ); 691 if ( bIsHorizontal ) 692 qThumbRect.addCoords( 0, 2, 0, -3 ); // make the thumb a bit nicer 693 else 694 qThumbRect.addCoords( 2, 0, -3, 0 ); // make the thumb a bit nicer 695 696 if ( kapp->style().inherits( "HighColorStyle" ) || 697 kapp->style().inherits( "HighContrastStyle" ) || 698 kapp->style().inherits( "KeramikStyle" ) || 699 kapp->style().inherits( "KThemeStyle" ) || 700 kapp->style().inherits( "ThinKeramikStyle" ) ) 701 { 702 // Workaround for the workaround in KStyle::drawPrimitive() 703 KStyle *pStyle = static_cast< KStyle * >( &kapp->style() ); 704 pStyle->drawKStylePrimitive( KStyle::KPE_ToolBarHandle, 705 &qPainter, pToolBar, qThumbRect, 706 pWidget->colorGroup(), nStyle ); 707 } 708 else 709 kapp->style().drawPrimitive( QStyle::PE_DockWindowHandle, 710 &qPainter, qThumbRect, pWidget->colorGroup(), nStyle ); 711 } 712 } 713 else if ( strcmp( "QToolButton", pClassName ) == 0 ) 714 { 715 if( (nStyle & QStyle::Style_MouseOver) ) 716 nStyle &= ~QStyle::Style_Off; 717 kapp->style().drawComplexControl( QStyle::CC_ToolButton, 718 &qPainter, pWidget, qRect, 719 pWidget->colorGroup(), nStyle, 720 QStyle::SC_ToolButton ); 721 } 722 else if ( strcmp( "QMenuBar", pClassName ) == 0 ) 723 { 724 if ( nPart == PART_ENTIRE_CONTROL ) 725 { 726 kapp->style().drawControl( QStyle::CE_MenuBarEmptyArea, 727 &qPainter, pWidget, qRect, 728 pWidget->colorGroup(), nStyle ); 729 } 730 else if ( nPart == PART_MENU_ITEM ) 731 { 732 int nMenuItem = ( nStyle & QStyle::Style_Enabled )? m_nMenuBarEnabledItem: m_nMenuBarDisabledItem; 733 QMenuItem *pMenuItem = static_cast<QMenuBar*>( pWidget )->findItem( nMenuItem ); 734 735 if ( nStyle & QStyle::Style_Selected ) 736 nStyle |= QStyle::Style_Active | QStyle::Style_Down | QStyle::Style_HasFocus; 737 738 kapp->style().drawControl( QStyle::CE_MenuBarItem, 739 &qPainter, pWidget, qRect, 740 pWidget->colorGroup(), nStyle, 741 QStyleOption( pMenuItem ) ); 742 } 743 } 744 else if ( strcmp( "QPopupMenu", pClassName ) == 0 ) 745 { 746 int nMenuItem = ( nStyle & QStyle::Style_Enabled )? m_nPopupMenuEnabledItem: m_nPopupMenuDisabledItem; 747 QMenuItem *pMenuItem = static_cast<QPopupMenu*>( pWidget )->findItem( nMenuItem ); 748 749 if ( nStyle & QStyle::Style_Selected ) 750 nStyle |= QStyle::Style_Active; 751 752 kapp->style().drawControl( QStyle::CE_PopupMenuItem, 753 &qPainter, pWidget, qRect, 754 pWidget->colorGroup(), nStyle, 755 QStyleOption( pMenuItem, 0, 0 ) ); 756 } 757 else if ( strcmp( "QProgressBar", pClassName ) == 0 ) 758 { 759 long nProgressWidth = aValue.getNumericVal(); 760 QProgressBar* pProgress = static_cast<QProgressBar*>(pWidget); 761 pProgress->setProgress( nProgressWidth, qRect.width() ); 762 763 kapp->style().drawControl( QStyle::CE_ProgressBarGroove, 764 &qPainter, pWidget, qRect, 765 pWidget->colorGroup(), nStyle ); 766 kapp->style().drawControl( QStyle::CE_ProgressBarContents, 767 &qPainter, pWidget, qRect, 768 pWidget->colorGroup(), nStyle ); 769 } 770 else 771 return sal_False; 772 773 // Bitblt it to the screen 774 X11SalGraphics::CopyScreenArea( dpy, 775 qPixmap.handle(), qPixmap.x11Screen(), qPixmap.x11Depth(), 776 drawable, nScreen, nDepth, 777 gc, 778 0, 0, qRect.width(), qRect.height(), 779 qWidgetPos.x(), qWidgetPos.y() ); 780 781 // Restore widget's position 782 pWidget->move( qWidgetPos ); 783 784 return sal_True; 785 } 786 787 QPushButton *WidgetPainter::pushButton( const Rectangle& rControlRegion, 788 sal_Bool bDefault ) 789 { 790 if ( !m_pPushButton ) 791 m_pPushButton = new QPushButton( NULL, "push_button" ); 792 793 QRect qRect = region2QRect( rControlRegion ); 794 795 // Workaround for broken styles which do not add 796 // QStyle::PM_ButtonDefaultIndicator to the size of the default button 797 // (for example Keramik) 798 // FIXME Fix Keramik style to be consistant with Qt built-in styles. Aargh! 799 if ( bDefault ) 800 { 801 QSize qContentsSize( 50, 50 ); 802 m_pPushButton->setDefault( false ); 803 QSize qNormalSize = kapp->style().sizeFromContents( QStyle::CT_PushButton, 804 m_pPushButton, qContentsSize ); 805 m_pPushButton->setDefault( true ); 806 QSize qDefSize = kapp->style().sizeFromContents( QStyle::CT_PushButton, 807 m_pPushButton, qContentsSize ); 808 809 int nIndicatorSize = kapp->style().pixelMetric( 810 QStyle::PM_ButtonDefaultIndicator, m_pPushButton ); 811 if ( qNormalSize.width() == qDefSize.width() ) 812 qRect.addCoords( nIndicatorSize, 0, -nIndicatorSize, 0 ); 813 if ( qNormalSize.height() == qDefSize.height() ) 814 qRect.addCoords( 0, nIndicatorSize, 0, -nIndicatorSize ); 815 } 816 817 m_pPushButton->move( qRect.topLeft() ); 818 m_pPushButton->resize( qRect.size() ); 819 m_pPushButton->setDefault( bDefault ); 820 821 return m_pPushButton; 822 } 823 824 QRadioButton *WidgetPainter::radioButton( const Rectangle& rControlRegion ) 825 { 826 if ( !m_pRadioButton ) 827 m_pRadioButton = new QRadioButton( NULL, "radio_button" ); 828 829 QRect qRect = region2QRect( rControlRegion ); 830 831 // Workaround for broken themes which do not honor the given size. 832 // Quite ugly, but I do not know about a better solution. 833 const char *pStyleName = kapp->style().className(); 834 if ( strcmp( "KThemeStyle", pStyleName ) == 0 ) 835 { 836 QRect qOldRect( qRect ); 837 838 qRect.setWidth( kapp->style().pixelMetric( 839 QStyle::PM_ExclusiveIndicatorWidth, m_pRadioButton ) ); 840 qRect.setHeight( kapp->style().pixelMetric( 841 QStyle::PM_ExclusiveIndicatorHeight, m_pRadioButton ) ); 842 843 qRect.moveBy( ( qOldRect.width() - qRect.width() ) / 2, 844 ( qOldRect.height() - qRect.height() ) / 2 ); 845 } 846 847 m_pRadioButton->move( qRect.topLeft() ); 848 m_pRadioButton->resize( qRect.size() ); 849 850 return m_pRadioButton; 851 } 852 853 QCheckBox *WidgetPainter::checkBox( const Rectangle& rControlRegion ) 854 { 855 if ( !m_pCheckBox ) 856 m_pCheckBox = new QCheckBox( NULL, "check_box" ); 857 858 QRect qRect = region2QRect( rControlRegion ); 859 860 // Workaround for broken themes which do not honor the given size. 861 // Quite ugly, but I do not know about a better solution. 862 const char *pStyleName = kapp->style().className(); 863 if ( strcmp( "KThemeStyle", pStyleName ) == 0 ) 864 { 865 QRect qOldRect( qRect ); 866 867 qRect.setWidth( kapp->style().pixelMetric( 868 QStyle::PM_IndicatorWidth, m_pCheckBox ) ); 869 qRect.setHeight( kapp->style().pixelMetric( 870 QStyle::PM_IndicatorHeight, m_pCheckBox ) ); 871 872 qRect.moveBy( ( qOldRect.width() - qRect.width() ) / 2, 873 ( qOldRect.height() - qRect.height() ) / 2 ); 874 } 875 876 m_pCheckBox->move( qRect.topLeft() ); 877 m_pCheckBox->resize( qRect.size() ); 878 879 return m_pCheckBox; 880 } 881 882 QComboBox *WidgetPainter::comboBox( const Rectangle& rControlRegion, 883 sal_Bool bEditable ) 884 { 885 QComboBox *pComboBox = NULL; 886 if ( bEditable ) 887 { 888 if ( !m_pEditableComboBox ) 889 m_pEditableComboBox = new QComboBox( true, NULL, "combo_box_edit" ); 890 pComboBox = m_pEditableComboBox; 891 } 892 else 893 { 894 if ( !m_pComboBox ) 895 m_pComboBox = new QComboBox( false, NULL, "combo_box" ); 896 pComboBox = m_pComboBox; 897 } 898 899 QRect qRect = region2QRect( rControlRegion ); 900 901 pComboBox->move( qRect.topLeft() ); 902 pComboBox->resize( qRect.size() ); 903 904 return pComboBox; 905 } 906 907 QLineEdit *WidgetPainter::lineEdit( const Rectangle& rControlRegion ) 908 { 909 if ( !m_pLineEdit ) 910 m_pLineEdit = new QLineEdit( NULL, "line_edit" ); 911 912 QRect qRect = region2QRect( rControlRegion ); 913 914 m_pLineEdit->move( qRect.topLeft() ); 915 m_pLineEdit->resize( qRect.size() ); 916 917 return m_pLineEdit; 918 } 919 920 QSpinWidget *WidgetPainter::spinWidget( const Rectangle& rControlRegion ) 921 { 922 if ( !m_pSpinWidget ) 923 { 924 m_pSpinWidget = new QSpinWidget( NULL, "spin_widget" ); 925 926 m_pSpinEdit = new QLineEdit( NULL, "line_edit_spin" ); 927 m_pSpinWidget->setEditWidget( m_pSpinEdit ); 928 } 929 930 QRect qRect = region2QRect( rControlRegion ); 931 932 m_pSpinWidget->move( qRect.topLeft() ); 933 m_pSpinWidget->resize( qRect.size() ); 934 m_pSpinWidget->arrange(); 935 936 return m_pSpinWidget; 937 } 938 939 QTabBar *WidgetPainter::tabBar( const Rectangle& rControlRegion ) 940 { 941 if ( !m_pTabBar ) 942 { 943 if ( !m_pTabBarParent ) 944 m_pTabBarParent = new QWidget( NULL, "tab_bar_parent" ); 945 946 m_pTabBar = new QTabBar( m_pTabBarParent, "tab_bar" ); 947 948 m_pTabLeft = new QTab(); 949 m_pTabMiddle = new QTab(); 950 m_pTabRight = new QTab(); 951 m_pTabAlone = new QTab(); 952 953 m_pTabBar->addTab( m_pTabLeft ); 954 m_pTabBar->addTab( m_pTabMiddle ); 955 m_pTabBar->addTab( m_pTabRight ); 956 } 957 958 QRect qRect = region2QRect( rControlRegion ); 959 960 m_pTabBar->move( qRect.topLeft() ); 961 m_pTabBar->resize( qRect.size() ); 962 963 m_pTabBar->setShape( QTabBar::RoundedAbove ); 964 965 return m_pTabBar; 966 } 967 968 QTabWidget *WidgetPainter::tabWidget( const Rectangle& rControlRegion ) 969 { 970 if ( !m_pTabWidget ) 971 m_pTabWidget = new QTabWidget( NULL, "tab_widget" ); 972 973 QRect qRect = region2QRect( rControlRegion ); 974 --qRect.rTop(); 975 976 m_pTabWidget->move( qRect.topLeft() ); 977 m_pTabWidget->resize( qRect.size() ); 978 979 return m_pTabWidget; 980 } 981 982 QListView *WidgetPainter::listView( const Rectangle& rControlRegion ) 983 { 984 if ( !m_pListView ) 985 m_pListView = new QListView( NULL, "list_view" ); 986 987 QRect qRect = region2QRect( rControlRegion ); 988 989 m_pListView->move( qRect.topLeft() ); 990 m_pListView->resize( qRect.size() ); 991 992 return m_pListView; 993 } 994 995 QScrollBar *WidgetPainter::scrollBar( const Rectangle& rControlRegion, 996 sal_Bool bHorizontal, const ImplControlValue& aValue ) 997 { 998 if ( !m_pScrollBar ) 999 { 1000 m_pScrollBar = new QScrollBar( NULL, "scroll_bar" ); 1001 m_pScrollBar->setTracking( false ); 1002 m_pScrollBar->setLineStep( 1 ); 1003 } 1004 1005 QRect qRect = region2QRect( rControlRegion ); 1006 1007 m_pScrollBar->move( qRect.topLeft() ); 1008 m_pScrollBar->resize( qRect.size() ); 1009 m_pScrollBar->setOrientation( bHorizontal? Qt::Horizontal: Qt::Vertical ); 1010 1011 const ScrollbarValue* pScrollbarVal = (aValue.getType() == CTRL_SCROLLBAR) ? static_cast<const ScrollbarValue*>(&aValue) : NULL; 1012 if ( pValue ) 1013 { 1014 m_pScrollBar->setMinValue( pValue->mnMin ); 1015 m_pScrollBar->setMaxValue( pValue->mnMax - pValue->mnVisibleSize ); 1016 m_pScrollBar->setValue( pValue->mnCur ); 1017 m_pScrollBar->setPageStep( pValue->mnVisibleSize ); 1018 } 1019 1020 return m_pScrollBar; 1021 } 1022 1023 QToolBar *WidgetPainter::toolBar( const Rectangle& rControlRegion, sal_Bool bHorizontal ) 1024 { 1025 if ( !m_pMainWindow ) 1026 m_pMainWindow = new QMainWindow( NULL, "main_window" ); 1027 1028 QToolBar *pToolBar; 1029 if ( bHorizontal ) 1030 { 1031 if ( !m_pToolBarHoriz ) 1032 { 1033 m_pToolBarHoriz = new QToolBar( m_pMainWindow, "tool_bar_horiz" ); 1034 m_pMainWindow->moveDockWindow( m_pToolBarHoriz, Qt::DockTop ); 1035 } 1036 pToolBar = m_pToolBarHoriz; 1037 } 1038 else 1039 { 1040 if ( !m_pToolBarVert ) 1041 { 1042 m_pToolBarVert = new QToolBar( m_pMainWindow, "tool_bar_horiz" ); 1043 m_pMainWindow->moveDockWindow( m_pToolBarVert, Qt::DockLeft ); 1044 } 1045 pToolBar = m_pToolBarVert; 1046 } 1047 1048 QRect qRect = region2QRect( rControlRegion ); 1049 1050 pToolBar->move( qRect.topLeft() ); 1051 pToolBar->resize( qRect.size() ); 1052 1053 return pToolBar; 1054 } 1055 1056 QToolButton *WidgetPainter::toolButton( const Rectangle& rControlRegion) 1057 { 1058 if ( !m_pToolButton ) 1059 m_pToolButton = new QToolButton( NULL, "tool_button" ); 1060 1061 QRect qRect = region2QRect( rControlRegion ); 1062 1063 m_pToolButton->move( qRect.topLeft() ); 1064 m_pToolButton->resize( qRect.size() ); 1065 1066 return m_pToolButton; 1067 } 1068 1069 QMenuBar *WidgetPainter::menuBar( const Rectangle& rControlRegion) 1070 { 1071 if ( !m_pMenuBar ) 1072 { 1073 m_pMenuBar = new QMenuBar( NULL, "menu_bar" ); 1074 1075 m_nMenuBarEnabledItem = m_pMenuBar->insertItem( "" ); 1076 m_nMenuBarDisabledItem = m_pMenuBar->insertItem( "" ); 1077 1078 m_pMenuBar->setItemEnabled( m_nMenuBarEnabledItem, true ); 1079 m_pMenuBar->setItemEnabled( m_nMenuBarDisabledItem, false ); 1080 } 1081 1082 QRect qRect = region2QRect( rControlRegion ); 1083 1084 m_pMenuBar->move( qRect.topLeft() ); 1085 m_pMenuBar->resize( qRect.size() ); 1086 1087 return m_pMenuBar; 1088 } 1089 1090 QPopupMenu *WidgetPainter::popupMenu( const Rectangle& rControlRegion) 1091 { 1092 if ( !m_pPopupMenu ) 1093 { 1094 m_pPopupMenu = new QPopupMenu( NULL, "popup_menu" ); 1095 1096 m_nPopupMenuEnabledItem = m_pPopupMenu->insertItem( "" ); 1097 m_nPopupMenuDisabledItem = m_pPopupMenu->insertItem( "" ); 1098 1099 m_pPopupMenu->setItemEnabled( m_nPopupMenuEnabledItem, true ); 1100 m_pPopupMenu->setItemEnabled( m_nPopupMenuDisabledItem, false ); 1101 } 1102 1103 QRect qRect = region2QRect( rControlRegion ); 1104 1105 m_pPopupMenu->move( qRect.topLeft() ); 1106 m_pPopupMenu->resize( qRect.size() ); 1107 1108 return m_pPopupMenu; 1109 } 1110 1111 QProgressBar *WidgetPainter::progressBar( const Rectangle& rControlRegion ) 1112 { 1113 if ( !m_pProgressBar ) 1114 m_pProgressBar = new QProgressBar( NULL, "progress_bar" ); 1115 1116 QRect qRect = region2QRect( rControlRegion ); 1117 1118 m_pProgressBar->move( qRect.topLeft() ); 1119 m_pProgressBar->resize( qRect.size() ); 1120 1121 return m_pProgressBar; 1122 } 1123 1124 QStyle::SFlags WidgetPainter::vclStateValue2SFlags( ControlState nState, 1125 const ImplControlValue& aValue ) 1126 { 1127 QStyle::SFlags nStyle = 1128 ( (nState & CTRL_STATE_DEFAULT)? QStyle::Style_ButtonDefault: QStyle::Style_Default ) | 1129 ( (nState & CTRL_STATE_ENABLED)? QStyle::Style_Enabled: QStyle::Style_Default ) | 1130 ( (nState & CTRL_STATE_FOCUSED)? QStyle::Style_HasFocus: QStyle::Style_Default ) | 1131 ( (nState & CTRL_STATE_PRESSED)? QStyle::Style_Down: QStyle::Style_Raised ) | 1132 ( (nState & CTRL_STATE_SELECTED)? QStyle::Style_Selected : QStyle::Style_Default ) | 1133 ( (nState & CTRL_STATE_ROLLOVER)? QStyle::Style_MouseOver: QStyle::Style_Default ); 1134 //TODO ( (nState & CTRL_STATE_HIDDEN)? QStyle::Style_: QStyle::Style_Default ) | 1135 1136 switch ( aValue.getTristateVal() ) 1137 { 1138 case BUTTONVALUE_ON: nStyle |= QStyle::Style_On; break; 1139 case BUTTONVALUE_OFF: nStyle |= QStyle::Style_Off; break; 1140 case BUTTONVALUE_MIXED: nStyle |= QStyle::Style_NoChange; break; 1141 default: break; 1142 } 1143 1144 return nStyle; 1145 } 1146 1147 QRect WidgetPainter::region2QRect( const Rectangle& rControlRegion ) 1148 { 1149 return QRect( QPoint( rControlRegion.Left(), rControlRegion.Top() ), 1150 QPoint( rControlRegion.Right(), rControlRegion.Bottom() ) ); 1151 } 1152 1153 /** Instance of WidgetPainter. 1154 1155 It is used to paint the widgets requested by NWF. 1156 */ 1157 static WidgetPainter *pWidgetPainter; 1158 1159 class KDESalGraphics : public X11SalGraphics 1160 { 1161 public: 1162 KDESalGraphics() {} 1163 virtual ~KDESalGraphics() {} 1164 virtual sal_Bool IsNativeControlSupported( ControlType nType, ControlPart nPart ); 1165 virtual sal_Bool hitTestNativeControl( ControlType nType, ControlPart nPart, 1166 const Rectangle& rControlRegion, const Point& aPos, 1167 sal_Bool& rIsInside ); 1168 virtual sal_Bool drawNativeControl( ControlType nType, ControlPart nPart, 1169 const Rectangle& rControlRegion, ControlState nState, 1170 const ImplControlValue& aValue, 1171 const OUString& aCaption ); 1172 virtual sal_Bool drawNativeControlText( ControlType nType, ControlPart nPart, 1173 const Rectangle& rControlRegion, ControlState nState, 1174 const ImplControlValue& aValue, 1175 const OUString& aCaption ); 1176 virtual sal_Bool getNativeControlRegion( ControlType nType, ControlPart nPart, 1177 const Rectangle& rControlRegion, ControlState nState, 1178 const ImplControlValue& aValue, 1179 const OUString& aCaption, 1180 Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ); 1181 }; 1182 1183 /** What widgets can be drawn the native way. 1184 1185 @param nType 1186 Type of the widget. 1187 1188 @param nPart 1189 Specification of the widget's part if it consists of more than one. 1190 1191 @return sal_True if the platform supports native drawing of the widget nType 1192 defined by nPart. 1193 */ 1194 sal_Bool KDESalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart ) 1195 { 1196 return 1197 ( (nType == CTRL_PUSHBUTTON) && (nPart == PART_ENTIRE_CONTROL) ) || 1198 ( (nType == CTRL_RADIOBUTTON) && (nPart == PART_ENTIRE_CONTROL) ) || 1199 ( (nType == CTRL_CHECKBOX) && (nPart == PART_ENTIRE_CONTROL) ) || 1200 ( (nType == CTRL_COMBOBOX) && (nPart == PART_ENTIRE_CONTROL || nPart == HAS_BACKGROUND_TEXTURE) ) || 1201 ( (nType == CTRL_EDITBOX) && (nPart == PART_ENTIRE_CONTROL || nPart == HAS_BACKGROUND_TEXTURE) ) || 1202 ( (nType == CTRL_LISTBOX) && (nPart == PART_ENTIRE_CONTROL || nPart == PART_WINDOW || nPart == HAS_BACKGROUND_TEXTURE ) ) || 1203 ( (nType == CTRL_SPINBOX) && (nPart == PART_ENTIRE_CONTROL || nPart == HAS_BACKGROUND_TEXTURE) ) || 1204 // no CTRL_SPINBUTTONS for KDE 1205 ( (nType == CTRL_TAB_ITEM) && (nPart == PART_ENTIRE_CONTROL) ) || 1206 ( (nType == CTRL_TAB_PANE) && (nPart == PART_ENTIRE_CONTROL) ) || 1207 // no CTRL_TAB_BODY for KDE 1208 ( (nType == CTRL_SCROLLBAR) && (nPart == PART_ENTIRE_CONTROL || nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT) ) || 1209 ( (nType == CTRL_SCROLLBAR) && (nPart == HAS_THREE_BUTTONS) ) || // TODO small optimization is possible here: return this only if the style really has 3 buttons 1210 // CTRL_GROUPBOX not supported 1211 // CTRL_FIXEDLINE not supported 1212 // CTRL_FIXEDBORDER not supported 1213 ( (nType == CTRL_TOOLBAR) && (nPart == PART_ENTIRE_CONTROL || 1214 nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT || 1215 nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT || 1216 nPart == PART_BUTTON) ) || 1217 ( (nType == CTRL_MENUBAR) && (nPart == PART_ENTIRE_CONTROL || nPart == PART_MENU_ITEM) ) || 1218 ( (nType == CTRL_MENU_POPUP) && (nPart == PART_ENTIRE_CONTROL || nPart == PART_MENU_ITEM) ) || 1219 ( (nType == CTRL_PROGRESS) && (nPart == PART_ENTIRE_CONTROL) ) 1220 ; 1221 } 1222 1223 1224 /** Test whether the position is in the native widget. 1225 1226 If the return value is sal_True, bIsInside contains information whether 1227 aPos was or was not inside the native widget specified by the 1228 nType/nPart combination. 1229 */ 1230 sal_Bool KDESalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart, 1231 const Rectangle& rControlRegion, const Point& rPos, 1232 sal_Bool& rIsInside ) 1233 { 1234 if ( nType == CTRL_SCROLLBAR ) 1235 { 1236 // make position relative to rControlRegion 1237 Point aPos = rPos - rControlRegion.TopLeft(); 1238 rIsInside = sal_False; 1239 1240 sal_Bool bHorizontal = ( nPart == PART_BUTTON_LEFT || nPart == PART_BUTTON_RIGHT ); 1241 1242 QScrollBar *pScrollBar = pWidgetPainter->scrollBar( rControlRegion, 1243 bHorizontal, ImplControlValue() ); 1244 QRect qRectSubLine = kapp->style().querySubControlMetrics( 1245 QStyle::CC_ScrollBar, pScrollBar, QStyle::SC_ScrollBarSubLine ); 1246 QRect qRectAddLine = kapp->style().querySubControlMetrics( 1247 QStyle::CC_ScrollBar, pScrollBar, QStyle::SC_ScrollBarAddLine ); 1248 1249 // There are 2 buttons on the right/bottom side of the scrollbar 1250 sal_Bool bTwoSubButtons = sal_False; 1251 1252 // It is a Platinum style scroll bar 1253 sal_Bool bPlatinumStyle = sal_False; 1254 1255 // Workaround for Platinum and 3 button style scroll bars. 1256 // It makes the right/down button bigger. 1257 if ( bHorizontal ) 1258 { 1259 qRectAddLine.setLeft( kapp->style().querySubControlMetrics( 1260 QStyle::CC_ScrollBar, pScrollBar, 1261 QStyle::SC_ScrollBarAddPage ).right() + 1 ); 1262 if ( qRectAddLine.width() > qRectSubLine.width() ) 1263 bTwoSubButtons = sal_True; 1264 if ( qRectSubLine.left() > kapp->style().querySubControlMetrics( QStyle::CC_ScrollBar, pScrollBar, QStyle::SC_ScrollBarSubPage ).left() ) 1265 bPlatinumStyle = sal_True; 1266 } 1267 else 1268 { 1269 qRectAddLine.setTop( kapp->style().querySubControlMetrics( 1270 QStyle::CC_ScrollBar, pScrollBar, 1271 QStyle::SC_ScrollBarAddPage ).bottom() + 1 ); 1272 if ( qRectAddLine.height() > qRectSubLine.height() ) 1273 bTwoSubButtons = sal_True; 1274 if ( qRectSubLine.top() > kapp->style().querySubControlMetrics( QStyle::CC_ScrollBar, pScrollBar, QStyle::SC_ScrollBarSubPage ).top() ) 1275 bPlatinumStyle = sal_True; 1276 } 1277 1278 switch ( nPart ) 1279 { 1280 case PART_BUTTON_LEFT: 1281 if ( !bPlatinumStyle && qRectSubLine.contains( aPos.getX(), aPos.getY() ) ) 1282 rIsInside = sal_True; 1283 else if ( bTwoSubButtons ) 1284 { 1285 qRectAddLine.setWidth( qRectAddLine.width() / 2 ); 1286 rIsInside = qRectAddLine.contains( aPos.getX(), aPos.getY() ); 1287 } 1288 break; 1289 1290 case PART_BUTTON_UP: 1291 if ( !bPlatinumStyle && qRectSubLine.contains( aPos.getX(), aPos.getY() ) ) 1292 rIsInside = sal_True; 1293 else if ( bTwoSubButtons ) 1294 { 1295 qRectAddLine.setHeight( qRectAddLine.height() / 2 ); 1296 rIsInside = qRectAddLine.contains( aPos.getX(), aPos.getY() ); 1297 } 1298 break; 1299 1300 case PART_BUTTON_RIGHT: 1301 if ( bTwoSubButtons ) 1302 qRectAddLine.setLeft( qRectAddLine.left() + qRectAddLine.width() / 2 ); 1303 1304 rIsInside = qRectAddLine.contains( aPos.getX(), aPos.getY() ); 1305 break; 1306 1307 case PART_BUTTON_DOWN: 1308 if ( bTwoSubButtons ) 1309 qRectAddLine.setTop( qRectAddLine.top() + qRectAddLine.height() / 2 ); 1310 1311 rIsInside = qRectAddLine.contains( aPos.getX(), aPos.getY() ); 1312 break; 1313 1314 // cases PART_TRACK_HORZ_AREA and PART_TRACK_VERT_AREA 1315 default: 1316 return sal_False; 1317 } 1318 1319 return sal_True; 1320 } 1321 1322 return sal_False; 1323 } 1324 1325 1326 /** Draw the requested control described by nPart/nState. 1327 1328 @param rControlRegion 1329 The bounding region of the complete control in VCL frame coordinates. 1330 1331 @param aValue 1332 An optional value (tristate/numerical/string). 1333 1334 @param aCaption 1335 A caption or title string (like button text etc.) 1336 */ 1337 sal_Bool KDESalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, 1338 const Rectangle& rControlRegion, ControlState nState, 1339 const ImplControlValue& aValue, 1340 const OUString& ) 1341 { 1342 sal_Bool bReturn = sal_False; 1343 1344 Display *dpy = GetXDisplay(); 1345 XLIB_Window drawable = GetDrawable(); 1346 GC gc = SelectPen(); //SelectFont(); // GC with current clipping region set 1347 1348 if ( (nType == CTRL_PUSHBUTTON) && (nPart == PART_ENTIRE_CONTROL) ) 1349 { 1350 bReturn = pWidgetPainter->drawStyledWidget( 1351 pWidgetPainter->pushButton( rControlRegion, (nState & CTRL_STATE_DEFAULT) ), 1352 nState, aValue, 1353 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1354 } 1355 else if ( (nType == CTRL_RADIOBUTTON) && (nPart == PART_ENTIRE_CONTROL) ) 1356 { 1357 bReturn = pWidgetPainter->drawStyledWidget( 1358 pWidgetPainter->radioButton( rControlRegion ), 1359 nState, aValue, 1360 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1361 } 1362 else if ( (nType == CTRL_CHECKBOX) && (nPart == PART_ENTIRE_CONTROL) ) 1363 { 1364 bReturn = pWidgetPainter->drawStyledWidget( 1365 pWidgetPainter->checkBox( rControlRegion ), 1366 nState, aValue, 1367 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1368 } 1369 else if ( (nType == CTRL_COMBOBOX) && (nPart == PART_ENTIRE_CONTROL) ) 1370 { 1371 bReturn = pWidgetPainter->drawStyledWidget( 1372 pWidgetPainter->comboBox( rControlRegion, sal_True ), 1373 nState, aValue, 1374 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1375 } 1376 else if ( (nType == CTRL_EDITBOX) && (nPart == PART_ENTIRE_CONTROL) ) 1377 { 1378 bReturn = pWidgetPainter->drawStyledWidget( 1379 pWidgetPainter->lineEdit( rControlRegion ), 1380 nState, aValue, 1381 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1382 } 1383 else if ( (nType == CTRL_LISTBOX) && (nPart == PART_ENTIRE_CONTROL) ) 1384 { 1385 bReturn = pWidgetPainter->drawStyledWidget( 1386 pWidgetPainter->comboBox( rControlRegion, sal_False ), 1387 nState, aValue, 1388 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1389 } 1390 else if ( (nType == CTRL_LISTBOX) && (nPart == PART_WINDOW) ) 1391 { 1392 bReturn = pWidgetPainter->drawStyledWidget( 1393 pWidgetPainter->listView( rControlRegion ), 1394 nState, aValue, 1395 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1396 } 1397 else if ( (nType == CTRL_SPINBOX) && (nPart == PART_ENTIRE_CONTROL) ) 1398 { 1399 bReturn = pWidgetPainter->drawStyledWidget( 1400 pWidgetPainter->spinWidget( rControlRegion ), 1401 nState, aValue, 1402 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1403 } 1404 else if ( (nType==CTRL_TAB_ITEM) && (nPart == PART_ENTIRE_CONTROL) ) 1405 { 1406 bReturn = pWidgetPainter->drawStyledWidget( 1407 pWidgetPainter->tabBar( rControlRegion ), 1408 nState, aValue, 1409 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1410 } 1411 else if ( (nType==CTRL_TAB_PANE) && (nPart == PART_ENTIRE_CONTROL) ) 1412 { 1413 bReturn = pWidgetPainter->drawStyledWidget( 1414 pWidgetPainter->tabWidget( rControlRegion ), 1415 nState, aValue, 1416 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1417 } 1418 else if ( (nType == CTRL_SCROLLBAR) && (nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT) ) 1419 { 1420 bReturn = pWidgetPainter->drawStyledWidget( 1421 pWidgetPainter->scrollBar( rControlRegion, nPart == PART_DRAW_BACKGROUND_HORZ, aValue ), 1422 nState, aValue, 1423 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1424 } 1425 else if ( (nType == CTRL_TOOLBAR) && (nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT || nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT) ) 1426 { 1427 bReturn = pWidgetPainter->drawStyledWidget( 1428 pWidgetPainter->toolBar( rControlRegion, nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_THUMB_VERT ), 1429 nState, aValue, 1430 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc, nPart ); 1431 } 1432 else if ( (nType == CTRL_TOOLBAR) && (nPart == PART_BUTTON) ) 1433 { 1434 bReturn = pWidgetPainter->drawStyledWidget( 1435 pWidgetPainter->toolButton( rControlRegion ), 1436 nState, aValue, 1437 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc, nPart ); 1438 } 1439 else if ( (nType == CTRL_MENUBAR) && (nPart == PART_ENTIRE_CONTROL || nPart == PART_MENU_ITEM) ) 1440 { 1441 bReturn = pWidgetPainter->drawStyledWidget( 1442 pWidgetPainter->menuBar( rControlRegion ), 1443 nState, aValue, 1444 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc, nPart ); 1445 } 1446 else if ( (nType == CTRL_MENU_POPUP) && (nPart == PART_ENTIRE_CONTROL || nPart == PART_MENU_ITEM) ) 1447 { 1448 bReturn = pWidgetPainter->drawStyledWidget( 1449 pWidgetPainter->popupMenu( rControlRegion ), 1450 nState, aValue, 1451 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1452 } 1453 else if ( (nType == CTRL_PROGRESS) && (nPart == PART_ENTIRE_CONTROL) ) 1454 { 1455 bReturn = pWidgetPainter->drawStyledWidget( 1456 pWidgetPainter->progressBar( rControlRegion ), 1457 nState, aValue, 1458 dpy, drawable, GetScreenNumber(), GetVisual().GetDepth(), gc ); 1459 } 1460 1461 return bReturn; 1462 } 1463 1464 1465 /** Draw text on the widget. 1466 1467 OPTIONAL. Draws the requested text for the control described by nPart/nState. 1468 Used if text is not drawn by DrawNativeControl(). 1469 1470 @param rControlRegion 1471 The bounding region of the complete control in VCL frame coordinates. 1472 1473 @param aValue 1474 An optional value (tristate/numerical/string) 1475 1476 @param aCaption 1477 A caption or title string (like button text etc.) 1478 */ 1479 sal_Bool KDESalGraphics::drawNativeControlText( ControlType, ControlPart, 1480 const Rectangle&, ControlState, 1481 const ImplControlValue&, 1482 const OUString& ) 1483 { 1484 return sal_False; 1485 } 1486 1487 /** Check if the bounding regions match. 1488 1489 If the return value is sal_True, rNativeBoundingRegion 1490 contains the true bounding region covered by the control 1491 including any adornment, while rNativeContentRegion contains the area 1492 within the control that can be safely drawn into without drawing over 1493 the borders of the control. 1494 1495 @param rControlRegion 1496 The bounding region of the control in VCL frame coordinates. 1497 1498 @param aValue 1499 An optional value (tristate/numerical/string) 1500 1501 @param aCaption 1502 A caption or title string (like button text etc.) 1503 */ 1504 sal_Bool KDESalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, 1505 const Rectangle& rControlRegion, ControlState nState, 1506 const ImplControlValue&, 1507 const OUString&, 1508 Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ) 1509 { 1510 sal_Bool bReturn = sal_False; 1511 QRect qBoundingRect = WidgetPainter::region2QRect( rControlRegion ); 1512 QRect qRect; 1513 1514 QWidget *pWidget = NULL; 1515 switch ( nType ) 1516 { 1517 // Metrics of the push button 1518 case CTRL_PUSHBUTTON: 1519 pWidget = pWidgetPainter->pushButton( rControlRegion, ( nState & CTRL_STATE_DEFAULT ) ); 1520 1521 switch ( nPart ) 1522 { 1523 case PART_ENTIRE_CONTROL: 1524 qRect = qBoundingRect; 1525 1526 if ( nState & CTRL_STATE_DEFAULT ) 1527 { 1528 int nIndicatorSize = kapp->style().pixelMetric( 1529 QStyle::PM_ButtonDefaultIndicator, pWidget ); 1530 qBoundingRect.addCoords( -nIndicatorSize, -nIndicatorSize, 1531 nIndicatorSize, nIndicatorSize ); 1532 bReturn = sal_True; 1533 } 1534 break; 1535 } 1536 break; 1537 1538 // Metrics of the radio button 1539 case CTRL_RADIOBUTTON: 1540 pWidget = pWidgetPainter->radioButton( rControlRegion ); 1541 1542 if ( nPart == PART_ENTIRE_CONTROL ) 1543 { 1544 qRect.setWidth( kapp->style().pixelMetric( QStyle::PM_ExclusiveIndicatorWidth, pWidget ) ); 1545 qRect.setHeight( kapp->style().pixelMetric( QStyle::PM_ExclusiveIndicatorHeight, pWidget ) ); 1546 1547 bReturn = sal_True; 1548 } 1549 break; 1550 1551 // Metrics of the check box 1552 case CTRL_CHECKBOX: 1553 pWidget = pWidgetPainter->checkBox( rControlRegion ); 1554 1555 if ( nPart == PART_ENTIRE_CONTROL ) 1556 { 1557 qRect.setWidth( kapp->style().pixelMetric( QStyle::PM_IndicatorWidth, pWidget ) ); 1558 qRect.setHeight( kapp->style().pixelMetric( QStyle::PM_IndicatorHeight, pWidget ) ); 1559 1560 bReturn = sal_True; 1561 } 1562 break; 1563 1564 // Metrics of the combo box 1565 case CTRL_COMBOBOX: 1566 case CTRL_LISTBOX: 1567 pWidget = pWidgetPainter->comboBox( rControlRegion, ( nType == CTRL_COMBOBOX ) ); 1568 switch ( nPart ) 1569 { 1570 case PART_BUTTON_DOWN: 1571 qRect = kapp->style().querySubControlMetrics( 1572 QStyle::CC_ComboBox, pWidget, QStyle::SC_ComboBoxArrow ); 1573 qRect.setLeft( kapp->style().querySubControlMetrics( 1574 QStyle::CC_ComboBox, pWidget, 1575 QStyle::SC_ComboBoxEditField ).right() + 1 ); 1576 qRect.moveBy( qBoundingRect.left(), qBoundingRect.top() ); 1577 bReturn = sal_True; 1578 break; 1579 1580 case PART_SUB_EDIT: 1581 qRect = kapp->style().querySubControlMetrics( 1582 QStyle::CC_ComboBox, pWidget, QStyle::SC_ComboBoxEditField ); 1583 qRect.moveBy( qBoundingRect.left(), qBoundingRect.top() ); 1584 bReturn = sal_True; 1585 break; 1586 } 1587 break; 1588 1589 // Metrics of the spin box 1590 case CTRL_SPINBOX: 1591 pWidget = pWidgetPainter->spinWidget( rControlRegion ); 1592 switch ( nPart ) 1593 { 1594 case PART_BUTTON_UP: 1595 qRect = kapp->style().querySubControlMetrics( 1596 QStyle::CC_SpinWidget, pWidget, QStyle::SC_SpinWidgetUp ); 1597 bReturn = sal_True; 1598 qRect.moveBy( qBoundingRect.left(), qBoundingRect.top() ); 1599 break; 1600 1601 case PART_BUTTON_DOWN: 1602 qRect = kapp->style().querySubControlMetrics( 1603 QStyle::CC_SpinWidget, pWidget, QStyle::SC_SpinWidgetDown ); 1604 bReturn = sal_True; 1605 qRect.moveBy( qBoundingRect.left(), qBoundingRect.top() ); 1606 break; 1607 1608 case PART_SUB_EDIT: 1609 qRect = kapp->style().querySubControlMetrics( 1610 QStyle::CC_SpinWidget, pWidget, QStyle::SC_SpinWidgetEditField ); 1611 qRect.moveBy( qBoundingRect.left(), qBoundingRect.top() ); 1612 bReturn = sal_True; 1613 break; 1614 } 1615 break; 1616 1617 // Metrics of the scroll bar 1618 case CTRL_SCROLLBAR: 1619 pWidget = pWidgetPainter->scrollBar( rControlRegion, 1620 ( nPart == PART_BUTTON_LEFT || nPart == PART_BUTTON_RIGHT ), 1621 ImplControlValue() ); 1622 switch ( nPart ) 1623 { 1624 case PART_BUTTON_LEFT: 1625 case PART_BUTTON_UP: 1626 qRect = kapp->style().querySubControlMetrics( 1627 QStyle::CC_ScrollBar, pWidget, QStyle::SC_ScrollBarSubLine ); 1628 1629 // Workaround for Platinum style scroll bars. It makes the 1630 // left/up button invisible. 1631 if ( nPart == PART_BUTTON_LEFT ) 1632 { 1633 if ( qRect.left() > kapp->style().querySubControlMetrics( 1634 QStyle::CC_ScrollBar, pWidget, 1635 QStyle::SC_ScrollBarSubPage ).left() ) 1636 { 1637 qRect.setLeft( 0 ); 1638 qRect.setRight( 0 ); 1639 } 1640 } 1641 else 1642 { 1643 if ( qRect.top() > kapp->style().querySubControlMetrics( 1644 QStyle::CC_ScrollBar, pWidget, 1645 QStyle::SC_ScrollBarSubPage ).top() ) 1646 { 1647 qRect.setTop( 0 ); 1648 qRect.setBottom( 0 ); 1649 } 1650 } 1651 1652 qRect.moveBy( qBoundingRect.left(), qBoundingRect.top() ); 1653 1654 bReturn = sal_True; 1655 break; 1656 1657 case PART_BUTTON_RIGHT: 1658 case PART_BUTTON_DOWN: 1659 qRect = kapp->style().querySubControlMetrics( 1660 QStyle::CC_ScrollBar, pWidget, QStyle::SC_ScrollBarAddLine ); 1661 1662 // Workaround for Platinum and 3 button style scroll bars. 1663 // It makes the right/down button bigger. 1664 if ( nPart == PART_BUTTON_RIGHT ) 1665 qRect.setLeft( kapp->style().querySubControlMetrics( 1666 QStyle::CC_ScrollBar, pWidget, 1667 QStyle::SC_ScrollBarAddPage ).right() + 1 ); 1668 else 1669 qRect.setTop( kapp->style().querySubControlMetrics( 1670 QStyle::CC_ScrollBar, pWidget, 1671 QStyle::SC_ScrollBarAddPage ).bottom() + 1 ); 1672 1673 qRect.moveBy( qBoundingRect.left(), qBoundingRect.top() ); 1674 1675 bReturn = sal_True; 1676 break; 1677 } 1678 break; 1679 } 1680 1681 // Fill rNativeBoundingRegion and rNativeContentRegion 1682 if ( bReturn ) 1683 { 1684 // Bounding region 1685 Point aBPoint( qBoundingRect.x(), qBoundingRect.y() ); 1686 Size aBSize( qBoundingRect.width(), qBoundingRect.height() ); 1687 rNativeBoundingRegion = Rectangle( aBPoint, aBSize ); 1688 1689 // Region of the content 1690 Point aPoint( qRect.x(), qRect.y() ); 1691 Size aSize( qRect.width(), qRect.height() ); 1692 rNativeContentRegion = Rectangle( aPoint, aSize ); 1693 } 1694 1695 return bReturn; 1696 } 1697 1698 // ----------------------------------------------------------------------- 1699 // KDESalFrame implementation 1700 // ----------------------------------------------------------------------- 1701 1702 KDESalFrame::KDESalFrame( SalFrame* pParent, sal_uLong nStyle ) : 1703 X11SalFrame( pParent, nStyle ) 1704 { 1705 } 1706 1707 void KDESalFrame::Show( sal_Bool bVisible, sal_Bool bNoActivate ) 1708 { 1709 if ( !GetParent() && ! (GetStyle() & SAL_FRAME_STYLE_INTRO) ) 1710 { 1711 KDEXLib* pXLib = static_cast<KDEXLib*>(GetDisplay()->GetXLib()); 1712 pXLib->doStartup(); 1713 } 1714 X11SalFrame::Show( bVisible, bNoActivate ); 1715 } 1716 1717 /** Helper function to convert colors. 1718 */ 1719 static Color toColor( const QColor &rColor ) 1720 { 1721 return Color( rColor.red(), rColor.green(), rColor.blue() ); 1722 } 1723 1724 /** Helper function to read untranslated text entry from KConfig configuration repository. 1725 */ 1726 static OUString readEntryUntranslated( KConfig *pConfig, const char *pKey ) 1727 { 1728 return OUString::createFromAscii( pConfig->readEntryUntranslated( pKey ).ascii() ); 1729 } 1730 1731 /** Helper function to read color from KConfig configuration repository. 1732 */ 1733 static Color readColor( KConfig *pConfig, const char *pKey ) 1734 { 1735 return toColor( pConfig->readColorEntry( pKey ) ); 1736 } 1737 1738 /** Helper function to add information to Font from QFont. 1739 1740 Mostly grabbed from the Gtk+ vclplug (salnativewidgets-gtk.cxx). 1741 */ 1742 static Font toFont( const QFont &rQFont, const ::com::sun::star::lang::Locale& rLocale ) 1743 { 1744 psp::FastPrintFontInfo aInfo; 1745 QFontInfo qFontInfo( rQFont ); 1746 1747 // set family name 1748 aInfo.m_aFamilyName = String( rQFont.family().utf8(), RTL_TEXTENCODING_UTF8 ); 1749 1750 // set italic 1751 aInfo.m_eItalic = ( qFontInfo.italic()? psp::italic::Italic: psp::italic::Upright ); 1752 1753 // set weight 1754 int nWeight = qFontInfo.weight(); 1755 if ( nWeight <= QFont::Light ) 1756 aInfo.m_eWeight = psp::weight::Light; 1757 else if ( nWeight <= QFont::Normal ) 1758 aInfo.m_eWeight = psp::weight::Normal; 1759 else if ( nWeight <= QFont::DemiBold ) 1760 aInfo.m_eWeight = psp::weight::SemiBold; 1761 else if ( nWeight <= QFont::Bold ) 1762 aInfo.m_eWeight = psp::weight::Bold; 1763 else 1764 aInfo.m_eWeight = psp::weight::UltraBold; 1765 1766 // set width 1767 int nStretch = rQFont.stretch(); 1768 if ( nStretch <= QFont::UltraCondensed ) 1769 aInfo.m_eWidth = psp::width::UltraCondensed; 1770 else if ( nStretch <= QFont::ExtraCondensed ) 1771 aInfo.m_eWidth = psp::width::ExtraCondensed; 1772 else if ( nStretch <= QFont::Condensed ) 1773 aInfo.m_eWidth = psp::width::Condensed; 1774 else if ( nStretch <= QFont::SemiCondensed ) 1775 aInfo.m_eWidth = psp::width::SemiCondensed; 1776 else if ( nStretch <= QFont::Unstretched ) 1777 aInfo.m_eWidth = psp::width::Normal; 1778 else if ( nStretch <= QFont::SemiExpanded ) 1779 aInfo.m_eWidth = psp::width::SemiExpanded; 1780 else if ( nStretch <= QFont::Expanded ) 1781 aInfo.m_eWidth = psp::width::Expanded; 1782 else if ( nStretch <= QFont::ExtraExpanded ) 1783 aInfo.m_eWidth = psp::width::ExtraExpanded; 1784 else 1785 aInfo.m_eWidth = psp::width::UltraExpanded; 1786 1787 #if OSL_DEBUG_LEVEL > 1 1788 fprintf( stderr, "font name BEFORE system match: \"%s\"\n", OUStringToOString( aInfo.m_aFamilyName, RTL_TEXTENCODING_ISO_8859_1 ).getStr() ); 1789 #endif 1790 1791 // match font to e.g. resolve "Sans" 1792 psp::PrintFontManager::get().matchFont( aInfo, rLocale ); 1793 1794 #if OSL_DEBUG_LEVEL > 1 1795 fprintf( stderr, "font match %s, name AFTER: \"%s\"\n", 1796 aInfo.m_nID != 0 ? "succeeded" : "failed", 1797 OUStringToOString( aInfo.m_aFamilyName, RTL_TEXTENCODING_ISO_8859_1 ).getStr() ); 1798 #endif 1799 1800 // font height 1801 int nPointHeight = qFontInfo.pointSize(); 1802 if ( nPointHeight <= 0 ) 1803 nPointHeight = rQFont.pointSize(); 1804 1805 // Create the font 1806 Font aFont( aInfo.m_aFamilyName, Size( 0, nPointHeight ) ); 1807 if( aInfo.m_eWeight != psp::weight::Unknown ) 1808 aFont.SetWeight( PspGraphics::ToFontWeight( aInfo.m_eWeight ) ); 1809 if( aInfo.m_eWidth != psp::width::Unknown ) 1810 aFont.SetWidthType( PspGraphics::ToFontWidth( aInfo.m_eWidth ) ); 1811 if( aInfo.m_eItalic != psp::italic::Unknown ) 1812 aFont.SetItalic( PspGraphics::ToFontItalic( aInfo.m_eItalic ) ); 1813 if( aInfo.m_ePitch != psp::pitch::Unknown ) 1814 aFont.SetPitch( PspGraphics::ToFontPitch( aInfo.m_ePitch ) ); 1815 1816 return aFont; 1817 } 1818 1819 /** Implementation of KDE integration's main method. 1820 */ 1821 void KDESalFrame::UpdateSettings( AllSettings& rSettings ) 1822 { 1823 StyleSettings aStyleSettings( rSettings.GetStyleSettings() ); 1824 bool bSetTitleFont = false; 1825 1826 // WM settings 1827 KConfig *pConfig = KGlobal::config(); 1828 if ( pConfig ) 1829 { 1830 pConfig->setGroup( "WM" ); 1831 const char *pKey; 1832 1833 pKey = "activeBackground"; 1834 if ( pConfig->hasKey( pKey ) ) 1835 aStyleSettings.SetActiveColor( readColor( pConfig, pKey ) ); 1836 1837 pKey = "activeBlend"; 1838 if ( pConfig->hasKey( pKey ) ) 1839 aStyleSettings.SetActiveColor2( readColor( pConfig, pKey ) ); 1840 1841 pKey = "inactiveBackground"; 1842 if ( pConfig->hasKey( pKey ) ) 1843 aStyleSettings.SetDeactiveColor( readColor( pConfig, pKey ) ); 1844 1845 pKey = "inactiveBlend"; 1846 if ( pConfig->hasKey( pKey ) ) 1847 aStyleSettings.SetDeactiveColor2( readColor( pConfig, pKey ) ); 1848 1849 pKey = "inactiveForeground"; 1850 if ( pConfig->hasKey( pKey ) ) 1851 aStyleSettings.SetDeactiveTextColor( readColor( pConfig, pKey ) ); 1852 1853 pKey = "activeForeground"; 1854 if ( pConfig->hasKey( pKey ) ) 1855 aStyleSettings.SetActiveTextColor( readColor( pConfig, pKey ) ); 1856 1857 pKey = "titleFont"; 1858 if ( pConfig->hasKey( pKey ) ) 1859 { 1860 Font aFont = toFont( pConfig->readFontEntry( pKey ), rSettings.GetUILocale() ); 1861 aStyleSettings.SetTitleFont( aFont ); 1862 bSetTitleFont = true; 1863 } 1864 1865 pConfig->setGroup( "Icons" ); 1866 1867 pKey = "Theme"; 1868 if ( pConfig->hasKey( pKey ) ) 1869 aStyleSettings.SetPreferredSymbolsStyleName( readEntryUntranslated( pConfig, pKey ) ); 1870 } 1871 1872 // General settings 1873 QColorGroup qColorGroup = kapp->palette().active(); 1874 1875 Color aFore = toColor( qColorGroup.foreground() ); 1876 Color aBack = toColor( qColorGroup.background() ); 1877 Color aText = toColor( qColorGroup.text() ); 1878 Color aBase = toColor( qColorGroup.base() ); 1879 1880 // Foreground 1881 aStyleSettings.SetRadioCheckTextColor( aFore ); 1882 aStyleSettings.SetLabelTextColor( aFore ); 1883 aStyleSettings.SetInfoTextColor( aFore ); 1884 aStyleSettings.SetDialogTextColor( aFore ); 1885 aStyleSettings.SetGroupTextColor( aFore ); 1886 1887 // Text 1888 aStyleSettings.SetFieldTextColor( aText ); 1889 aStyleSettings.SetFieldRolloverTextColor( aText ); 1890 aStyleSettings.SetWindowTextColor( aText ); 1891 aStyleSettings.SetHelpTextColor( aText ); 1892 1893 // Base 1894 aStyleSettings.SetFieldColor( aBase ); 1895 aStyleSettings.SetHelpColor( aBase ); 1896 aStyleSettings.SetWindowColor( aBase ); 1897 aStyleSettings.SetActiveTabColor( aBase ); 1898 1899 // Buttons 1900 aStyleSettings.SetButtonTextColor( toColor( qColorGroup.buttonText() ) ); 1901 aStyleSettings.SetButtonRolloverTextColor( toColor( qColorGroup.buttonText() ) ); 1902 1903 // Disable color 1904 aStyleSettings.SetDisableColor( toColor( qColorGroup.mid() ) ); 1905 1906 // Workspace 1907 aStyleSettings.SetWorkspaceColor( toColor( qColorGroup.mid() ) ); 1908 1909 // Background 1910 aStyleSettings.Set3DColors( aBack ); 1911 aStyleSettings.SetFaceColor( aBack ); 1912 aStyleSettings.SetInactiveTabColor( aBack ); 1913 aStyleSettings.SetDialogColor( aBack ); 1914 if( aBack == COL_LIGHTGRAY ) 1915 aStyleSettings.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) ); 1916 else 1917 { 1918 Color aColor2 = aStyleSettings.GetLightColor(); 1919 aStyleSettings. 1920 SetCheckedColor( Color( (sal_uInt8)(((sal_uInt16)aBack.GetRed()+(sal_uInt16)aColor2.GetRed())/2), 1921 (sal_uInt8)(((sal_uInt16)aBack.GetGreen()+(sal_uInt16)aColor2.GetGreen())/2), 1922 (sal_uInt8)(((sal_uInt16)aBack.GetBlue()+(sal_uInt16)aColor2.GetBlue())/2) 1923 ) ); 1924 } 1925 1926 // Selection 1927 aStyleSettings.SetHighlightColor( toColor( qColorGroup.highlight() ) ); 1928 aStyleSettings.SetHighlightTextColor( toColor( qColorGroup.highlightedText() ) ); 1929 1930 // Font 1931 Font aFont = toFont( kapp->font(), rSettings.GetUILocale() ); 1932 1933 aStyleSettings.SetAppFont( aFont ); 1934 aStyleSettings.SetHelpFont( aFont ); 1935 if( !bSetTitleFont ) 1936 aStyleSettings.SetTitleFont( aFont ); 1937 aStyleSettings.SetFloatTitleFont( aFont ); 1938 aStyleSettings.SetMenuFont( aFont ); // will be changed according to pMenuBar 1939 aStyleSettings.SetToolFont( aFont ); // will be changed according to pToolBar 1940 aStyleSettings.SetLabelFont( aFont ); 1941 aStyleSettings.SetInfoFont( aFont ); 1942 aStyleSettings.SetRadioCheckFont( aFont ); 1943 aStyleSettings.SetPushButtonFont( aFont ); 1944 aStyleSettings.SetFieldFont( aFont ); 1945 aStyleSettings.SetIconFont( aFont ); 1946 aStyleSettings.SetGroupFont( aFont ); 1947 int flash_time = QApplication::cursorFlashTime(); 1948 aStyleSettings.SetCursorBlinkTime( flash_time != 0 ? flash_time/2 : STYLE_CURSOR_NOBLINKTIME ); 1949 1950 KMainWindow qMainWindow; 1951 qMainWindow.createGUI( "/dev/null" ); // hack 1952 1953 // Menu 1954 aStyleSettings.SetSkipDisabledInMenus( sal_True ); 1955 KMenuBar *pMenuBar = qMainWindow.menuBar(); 1956 if ( pMenuBar ) 1957 { 1958 // Color 1959 QColorGroup qMenuCG = pMenuBar->colorGroup(); 1960 1961 // Menu text and background color, theme specific 1962 Color aMenuFore = toColor( qMenuCG.foreground() ); 1963 Color aMenuBack = toColor( qMenuCG.background() ); 1964 if ( kapp->style().inherits( "LightStyleV2" ) || 1965 kapp->style().inherits( "LightStyleV3" ) || 1966 ( kapp->style().inherits( "QMotifStyle" ) && !kapp->style().inherits( "QSGIStyle" ) ) || 1967 kapp->style().inherits( "QWindowsStyle" ) ) 1968 { 1969 aMenuFore = toColor( qMenuCG.buttonText() ); 1970 aMenuBack = toColor( qMenuCG.button() ); 1971 } 1972 1973 aStyleSettings.SetMenuTextColor( aMenuFore ); 1974 aStyleSettings.SetMenuBarTextColor( aMenuFore ); 1975 aStyleSettings.SetMenuColor( aMenuBack ); 1976 aStyleSettings.SetMenuBarColor( aMenuBack ); 1977 1978 aStyleSettings.SetMenuHighlightColor( toColor ( qMenuCG.highlight() ) ); 1979 1980 // Menu items higlight text color, theme specific 1981 if ( kapp->style().inherits( "HighContrastStyle" ) || 1982 kapp->style().inherits( "KeramikStyle" ) || 1983 kapp->style().inherits( "QWindowsStyle" ) || 1984 kapp->style().inherits( "ThinKeramikStyle" ) || 1985 kapp->style().inherits( "PlastikStyle" ) ) 1986 { 1987 aStyleSettings.SetMenuHighlightTextColor( toColor ( qMenuCG.highlightedText() ) ); 1988 } 1989 else 1990 aStyleSettings.SetMenuHighlightTextColor( aMenuFore ); 1991 1992 // set special menubar higlight text color 1993 if ( kapp->style().inherits( "HighContrastStyle" ) ) 1994 ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor = toColor( qMenuCG.highlightedText() ); 1995 else 1996 ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor = aMenuFore; 1997 1998 // Font 1999 aFont = toFont( pMenuBar->font(), rSettings.GetUILocale() ); 2000 aStyleSettings.SetMenuFont( aFont ); 2001 } 2002 2003 // Tool bar 2004 KToolBar *pToolBar = qMainWindow.toolBar(); 2005 if ( pToolBar ) 2006 { 2007 aFont = toFont( pToolBar->font(), rSettings.GetUILocale() ); 2008 aStyleSettings.SetToolFont( aFont ); 2009 } 2010 2011 // Scroll bar size 2012 aStyleSettings.SetScrollBarSize( kapp->style().pixelMetric( QStyle::PM_ScrollBarExtent ) ); 2013 2014 rSettings.SetStyleSettings( aStyleSettings ); 2015 } 2016 2017 SalGraphics* KDESalFrame::GetGraphics() 2018 { 2019 if( GetWindow() ) 2020 { 2021 for( int i = 0; i < nMaxGraphics; i++ ) 2022 { 2023 if( ! m_aGraphics[i].bInUse ) 2024 { 2025 m_aGraphics[i].bInUse = true; 2026 if( ! m_aGraphics[i].pGraphics ) 2027 { 2028 m_aGraphics[i].pGraphics = new KDESalGraphics(); 2029 m_aGraphics[i].pGraphics->Init( this, GetWindow(), GetScreenNumber() ); 2030 } 2031 return m_aGraphics[i].pGraphics; 2032 } 2033 } 2034 } 2035 2036 return NULL; 2037 } 2038 2039 void KDESalFrame::ReleaseGraphics( SalGraphics *pGraphics ) 2040 { 2041 for( int i = 0; i < nMaxGraphics; i++ ) 2042 { 2043 if( m_aGraphics[i].pGraphics == pGraphics ) 2044 { 2045 m_aGraphics[i].bInUse = false; 2046 break; 2047 } 2048 } 2049 } 2050 2051 void KDESalFrame::updateGraphics( bool bClear ) 2052 { 2053 Drawable aDrawable = bClear ? None : GetWindow(); 2054 for( int i = 0; i < nMaxGraphics; i++ ) 2055 { 2056 if( m_aGraphics[i].bInUse ) 2057 m_aGraphics[i].pGraphics->SetDrawable( aDrawable, GetScreenNumber() ); 2058 } 2059 } 2060 2061 KDESalFrame::~KDESalFrame() 2062 { 2063 } 2064 2065 KDESalFrame::GraphicsHolder::~GraphicsHolder() 2066 { 2067 delete pGraphics; 2068 } 2069 2070 // ----------------------------------------------------------------------- 2071 // KDESalInstance implementation 2072 // ----------------------------------------------------------------------- 2073 2074 SalFrame * 2075 KDESalInstance::CreateFrame( SalFrame *pParent, sal_uLong nStyle ) 2076 { 2077 return new KDESalFrame( pParent, nStyle ); 2078 } 2079 2080 // ----------------------------------------------------------------------- 2081 // KDESalData pieces 2082 // ----------------------------------------------------------------------- 2083 2084 // Create the widget painter so we have some control over 2085 // the destruction sequence, so Qt doesn't die in action. 2086 2087 void KDEData::initNWF() 2088 { 2089 ImplSVData *pSVData = ImplGetSVData(); 2090 // draw toolbars on separate lines 2091 pSVData->maNWFData.mbDockingAreaSeparateTB = true; 2092 2093 pWidgetPainter = new WidgetPainter(); 2094 } 2095 2096 void KDEData::deInitNWF() 2097 { 2098 delete pWidgetPainter; 2099 pWidgetPainter = NULL; 2100 2101 // We have to destroy the style early 2102 kapp->setStyle( NULL ); 2103 } 2104