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
WidgetPainter(void)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
~WidgetPainter(void)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
drawStyledWidget(QWidget * pWidget,ControlState nState,const ImplControlValue & aValue,Display * dpy,XLIB_Window drawable,int nScreen,int nDepth,GC gc,ControlPart nPart)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
pushButton(const Rectangle & rControlRegion,sal_Bool bDefault)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 consistent 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
radioButton(const Rectangle & rControlRegion)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
checkBox(const Rectangle & rControlRegion)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
comboBox(const Rectangle & rControlRegion,sal_Bool bEditable)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
lineEdit(const Rectangle & rControlRegion)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
spinWidget(const Rectangle & rControlRegion)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
tabBar(const Rectangle & rControlRegion)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
tabWidget(const Rectangle & rControlRegion)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
listView(const Rectangle & rControlRegion)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
scrollBar(const Rectangle & rControlRegion,sal_Bool bHorizontal,const ImplControlValue & aValue)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
toolBar(const Rectangle & rControlRegion,sal_Bool bHorizontal)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
toolButton(const Rectangle & rControlRegion)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
menuBar(const Rectangle & rControlRegion)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
popupMenu(const Rectangle & rControlRegion)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
progressBar(const Rectangle & rControlRegion)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
vclStateValue2SFlags(ControlState nState,const ImplControlValue & aValue)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
region2QRect(const Rectangle & rControlRegion)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:
KDESalGraphics()1162 KDESalGraphics() {}
~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 */
IsNativeControlSupported(ControlType nType,ControlPart nPart)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 */
hitTestNativeControl(ControlType nType,ControlPart nPart,const Rectangle & rControlRegion,const Point & rPos,sal_Bool & rIsInside)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 */
drawNativeControl(ControlType nType,ControlPart nPart,const Rectangle & rControlRegion,ControlState nState,const ImplControlValue & aValue,const OUString &)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 */
drawNativeControlText(ControlType,ControlPart,const Rectangle &,ControlState,const ImplControlValue &,const OUString &)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 */
getNativeControlRegion(ControlType nType,ControlPart nPart,const Rectangle & rControlRegion,ControlState nState,const ImplControlValue &,const OUString &,Rectangle & rNativeBoundingRegion,Rectangle & rNativeContentRegion)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
KDESalFrame(SalFrame * pParent,sal_uLong nStyle)1702 KDESalFrame::KDESalFrame( SalFrame* pParent, sal_uLong nStyle ) :
1703 X11SalFrame( pParent, nStyle )
1704 {
1705 }
1706
Show(sal_Bool bVisible,sal_Bool bNoActivate)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 */
toColor(const QColor & rColor)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 */
readEntryUntranslated(KConfig * pConfig,const char * pKey)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 */
readColor(KConfig * pConfig,const char * pKey)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 */
toFont(const QFont & rQFont,const::com::sun::star::lang::Locale & rLocale)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 */
UpdateSettings(AllSettings & rSettings)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
GetGraphics()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
ReleaseGraphics(SalGraphics * pGraphics)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
updateGraphics(bool bClear)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
~KDESalFrame()2061 KDESalFrame::~KDESalFrame()
2062 {
2063 }
2064
~GraphicsHolder()2065 KDESalFrame::GraphicsHolder::~GraphicsHolder()
2066 {
2067 delete pGraphics;
2068 }
2069
2070 // -----------------------------------------------------------------------
2071 // KDESalInstance implementation
2072 // -----------------------------------------------------------------------
2073
2074 SalFrame *
CreateFrame(SalFrame * pParent,sal_uLong nStyle)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
initNWF()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
deInitNWF()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