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