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