xref: /AOO41X/main/vcl/unx/kde/salnativewidgets-kde.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
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 consistant with Qt built-in styles. Aargh!
799     if ( bDefault )
800     {
801     QSize qContentsSize( 50, 50 );
802     m_pPushButton->setDefault( false );
803     QSize qNormalSize = kapp->style().sizeFromContents( QStyle::CT_PushButton,
804         m_pPushButton, qContentsSize );
805     m_pPushButton->setDefault( true );
806     QSize qDefSize = kapp->style().sizeFromContents( QStyle::CT_PushButton,
807         m_pPushButton, qContentsSize );
808 
809     int nIndicatorSize = kapp->style().pixelMetric(
810         QStyle::PM_ButtonDefaultIndicator, m_pPushButton );
811     if ( qNormalSize.width() == qDefSize.width() )
812         qRect.addCoords( nIndicatorSize, 0, -nIndicatorSize, 0 );
813     if ( qNormalSize.height() == qDefSize.height() )
814         qRect.addCoords( 0, nIndicatorSize, 0, -nIndicatorSize );
815     }
816 
817     m_pPushButton->move( qRect.topLeft() );
818     m_pPushButton->resize( qRect.size() );
819     m_pPushButton->setDefault( bDefault );
820 
821     return m_pPushButton;
822 }
823 
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