~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kstyles/oxygen/oxygenstyle.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// krazy:excludeall=qclasses
 
2
 
 
3
//////////////////////////////////////////////////////////////////////////////
 
4
// oxygenstyle.cpp
 
5
// Oxygen widget style for KDE 4
 
6
// -------------------
 
7
//
 
8
// Copyright ( C ) 2009-2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
 
9
// Copyright ( C ) 2008 Long Huynh Huu <long.upcase@googlemail.com>
 
10
// Copyright ( C ) 2007-2008 Casper Boemann <cbr@boemann.dk>
 
11
// Copyright ( C ) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
 
12
// Copyright ( C ) 2003-2005 Sandro Giessl <sandro@giessl.com>
 
13
//
 
14
// based on the KDE style "dotNET":
 
15
// Copyright ( C ) 2001-2002, Chris Lee <clee@kde.org>
 
16
// Carsten Pfeiffer <pfeiffer@kde.org>
 
17
// Karol Szwed <gallium@kde.org>
 
18
// Drawing routines completely reimplemented from KDE3 HighColor, which was
 
19
// originally based on some stuff from the KDE2 HighColor.
 
20
//
 
21
// based on drawing routines of the style "Keramik":
 
22
// Copyright ( c ) 2002 Malte Starostik <malte@kde.org>
 
23
// ( c ) 2002,2003 Maksim Orlovich <mo002j@mail.rochester.edu>
 
24
// based on the KDE3 HighColor Style
 
25
// Copyright ( C ) 2001-2002 Karol Szwed <gallium@kde.org>
 
26
// ( C ) 2001-2002 Fredrik Höglund <fredrik@kde.org>
 
27
// Drawing routines adapted from the KDE2 HCStyle,
 
28
// Copyright ( C ) 2000 Daniel M. Duley <mosfet@kde.org>
 
29
// ( C ) 2000 Dirk Mueller <mueller@kde.org>
 
30
// ( C ) 2001 Martijn Klingens <klingens@kde.org>
 
31
// Progressbar code based on KStyle,
 
32
// Copyright ( C ) 2001-2002 Karol Szwed <gallium@kde.org>
 
33
//
 
34
// This library is free software; you can redistribute it and/or
 
35
// modify it under the terms of the GNU Library General Public
 
36
// License version 2 as published by the Free Software Foundation.
 
37
//
 
38
// This library is distributed in the hope that it will be useful,
 
39
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
40
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
41
// Library General Public License for more details.
 
42
//
 
43
// You should have received a copy of the GNU Library General Public License
 
44
// along with this library; see the file COPYING.LIB.  If not, write to
 
45
// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
46
// Boston, MA 02110-1301, USA.
 
47
//////////////////////////////////////////////////////////////////////////////
 
48
 
 
49
#include "oxygenstyle.h"
 
50
#include "oxygenstyle.moc"
 
51
 
 
52
#include "oxygenanimations.h"
 
53
#include "oxygenframeshadow.h"
 
54
#include "oxygenmdiwindowshadow.h"
 
55
#include "oxygenshadowhelper.h"
 
56
#include "oxygenstyleconfigdata.h"
 
57
#include "oxygentransitions.h"
 
58
#include "oxygenwidgetexplorer.h"
 
59
#include "oxygenwindowmanager.h"
 
60
 
 
61
#include <QtCore/QDebug>
 
62
#include <QtGui/QAbstractButton>
 
63
#include <QtGui/QAbstractItemView>
 
64
#include <QtGui/QApplication>
 
65
#include <QtGui/QCheckBox>
 
66
#include <QtGui/QComboBox>
 
67
#include <QtGui/QDial>
 
68
#include <QtGui/QDialogButtonBox>
 
69
#include <QtGui/QDockWidget>
 
70
#include <QtGui/QDoubleSpinBox>
 
71
#include <QtGui/QFormLayout>
 
72
#include <QtGui/QFrame>
 
73
#include <QtGui/QGraphicsView>
 
74
#include <QtGui/QGroupBox>
 
75
#include <QtGui/QLayout>
 
76
#include <QtGui/QLineEdit>
 
77
#include <QtGui/QMainWindow>
 
78
#include <QtGui/QMdiSubWindow>
 
79
#include <QtGui/QPushButton>
 
80
#include <QtGui/QRadioButton>
 
81
#include <QtGui/QScrollBar>
 
82
#include <QtGui/QSpinBox>
 
83
#include <QtGui/QSplitterHandle>
 
84
#include <QtGui/QStylePlugin>
 
85
#include <QtGui/QStyleOption>
 
86
#include <QtGui/QTextEdit>
 
87
#include <QtGui/QToolBar>
 
88
#include <QtGui/QToolBox>
 
89
#include <QtGui/QToolButton>
 
90
 
 
91
#include <QtDBus/QDBusConnection>
 
92
 
 
93
#include <KColorUtils>
 
94
#include <KGlobal>
 
95
#include <KGlobalSettings>
 
96
#include <KIconLoader>
 
97
#include <KIcon>
 
98
#include <kdeversion.h>
 
99
 
 
100
#include <cmath>
 
101
 
 
102
/* These are to link libkio even if 'smart' linker is used */
 
103
#include <kio/authinfo.h>
 
104
extern "C" KIO::AuthInfo* _oxygen_init_kio() { return new KIO::AuthInfo(); }
 
105
 
 
106
 
 
107
//_____________________________________________
 
108
// style plugin
 
109
namespace Oxygen
 
110
{
 
111
    //! style plugin
 
112
    class StylePlugin : public QStylePlugin
 
113
    {
 
114
        public:
 
115
 
 
116
        //! returns list of valid keys
 
117
        QStringList keys() const
 
118
        { return QStringList( QLatin1String( "Oxygen" ) ); }
 
119
 
 
120
        //! create style
 
121
        QStyle *create( const QString &key )
 
122
        {
 
123
 
 
124
            if( key.toLower() == QLatin1String( "oxygen" ) ) return new Style;
 
125
            else return NULL;
 
126
        }
 
127
    };
 
128
 
 
129
}
 
130
 
 
131
Q_EXPORT_PLUGIN2( oxygen-qt, Oxygen::StylePlugin )
 
132
 
 
133
namespace Oxygen
 
134
{
 
135
 
 
136
    // hardcoded index offsets for custom widgets
 
137
    // copied from e.g. kstyle.cxx
 
138
    static const QStyle::StyleHint SH_KCustomStyleElement = ( QStyle::StyleHint )0xff000001;
 
139
    static const int X_KdeBase = 0xff000000;
 
140
 
 
141
    //_____________________________________________________________________
 
142
    bool TopLevelManager::eventFilter( QObject *object, QEvent *event )
 
143
    {
 
144
 
 
145
        // cast to QWidget
 
146
        QWidget *widget = static_cast<QWidget*>( object );
 
147
        if( event->type() == QEvent::Show && _helper.hasDecoration( widget ) )
 
148
        {
 
149
            _helper.setHasBackgroundGradient( widget->winId(), true );
 
150
            _helper.setHasBackgroundPixmap( widget->winId(), _helper.hasBackgroundPixmap() );
 
151
        }
 
152
 
 
153
        return false;
 
154
    }
 
155
 
 
156
    //______________________________________________________________
 
157
    Style::Style( void ):
 
158
        _kGlobalSettingsInitialized( false ),
 
159
        _addLineButtons( DoubleButton ),
 
160
        _subLineButtons( SingleButton ),
 
161
        _singleButtonHeight( 14 ),
 
162
        _doubleButtonHeight( 28 ),
 
163
        _showMnemonics( true ),
 
164
        _helper( new StyleHelper( "oxygen" ) ),
 
165
        _shadowHelper( new ShadowHelper( this, *_helper ) ),
 
166
        _animations( new Animations( this ) ),
 
167
        _transitions( new Transitions( this ) ),
 
168
        _windowManager( new WindowManager( this ) ),
 
169
        _topLevelManager( new TopLevelManager( this, *_helper ) ),
 
170
        _frameShadowFactory( new FrameShadowFactory( this ) ),
 
171
        _mdiWindowShadowFactory( new MdiWindowShadowFactory( this, *_helper ) ),
 
172
        _widgetExplorer( new WidgetExplorer( this ) ),
 
173
        _tabBarData( new TabBarData( this ) ),
 
174
        _frameFocusPrimitive( 0 ),
 
175
        _tabBarTabShapeControl( 0 ),
 
176
        _hintCounter( X_KdeBase+1 ),
 
177
        _controlCounter( X_KdeBase ),
 
178
        _subElementCounter( X_KdeBase ),
 
179
        CE_CapacityBar( newControlElement( "CE_CapacityBar" ) )
 
180
 
 
181
    {
 
182
 
 
183
        // use DBus connection to update on oxygen configuration change
 
184
        QDBusConnection dbus = QDBusConnection::sessionBus();
 
185
        dbus.connect( QString(), "/OxygenStyle", "org.kde.Oxygen.Style", "reparseConfiguration", this, SLOT( oxygenConfigurationChanged( void ) ) );
 
186
 
 
187
        // call the slot directly; this initial call will set up things that also
 
188
        // need to be reset when the system palette changes
 
189
        oxygenConfigurationChanged();
 
190
 
 
191
    }
 
192
 
 
193
    //______________________________________________________________
 
194
    Style::~Style( void )
 
195
    { delete _helper; }
 
196
 
 
197
    //______________________________________________________________
 
198
    void Style::polish( QWidget* widget )
 
199
    {
 
200
        if( !widget ) return;
 
201
 
 
202
        // register widget to animations
 
203
        animations().registerWidget( widget );
 
204
        transitions().registerWidget( widget );
 
205
        windowManager().registerWidget( widget );
 
206
        frameShadowFactory().registerWidget( widget, helper() );
 
207
        mdiWindowShadowFactory().registerWidget( widget );
 
208
        shadowHelper().registerWidget( widget );
 
209
 
 
210
        // scroll areas
 
211
        if( QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>( widget ) )
 
212
        {
 
213
 
 
214
            polishScrollArea( scrollArea );
 
215
 
 
216
        } else if( widget->inherits( "Q3ListView" ) ) {
 
217
 
 
218
            addEventFilter( widget );
 
219
            widget->setAttribute( Qt::WA_Hover );
 
220
 
 
221
        }
 
222
 
 
223
        // several widgets set autofill background to false, which effectively breaks the background
 
224
        // gradient rendering. Instead of patching all concerned applications,
 
225
        // we change the background here
 
226
        if( widget->inherits( "MessageList::Core::Widget" ) )
 
227
        { widget->setAutoFillBackground( false ); }
 
228
 
 
229
        // KTextEdit frames
 
230
        // static cast is safe here, since isKTextEdit already checks that widget inherits from QFrame
 
231
        if( isKTextEditFrame( widget ) && static_cast<QFrame*>( widget )->frameStyle() == ( QFrame::StyledPanel | QFrame::Sunken ) )
 
232
        {
 
233
 
 
234
            widget->setAttribute( Qt::WA_Hover );
 
235
            animations().lineEditEngine().registerWidget( widget, AnimationHover|AnimationFocus );
 
236
 
 
237
        }
 
238
 
 
239
        // adjust layout for K3B themed headers
 
240
        // FIXME: to be removed when fixed upstream
 
241
        if( widget->inherits( "K3b::ThemedHeader" ) && widget->layout() )
 
242
        {
 
243
            widget->layout()->setMargin( 0 );
 
244
            frameShadowFactory().setHasContrast( widget, true );
 
245
        }
 
246
 
 
247
        // adjust flags for windows and dialogs
 
248
        switch( widget->windowFlags() & Qt::WindowType_Mask )
 
249
        {
 
250
 
 
251
            case Qt::Window:
 
252
            case Qt::Dialog:
 
253
 
 
254
            // set background as styled
 
255
            widget->setAttribute( Qt::WA_StyledBackground );
 
256
            widget->installEventFilter( _topLevelManager );
 
257
 
 
258
            // initialize connections to kGlobalSettings
 
259
            /*
 
260
            this musts be done in ::polish and not before,
 
261
            in order to be able to detect Qt-KDE vs Qt-only applications
 
262
            */
 
263
            if( !_kGlobalSettingsInitialized ) initializeKGlobalSettings();
 
264
 
 
265
            break;
 
266
 
 
267
            default: break;
 
268
 
 
269
        }
 
270
 
 
271
        if(
 
272
            qobject_cast<QAbstractItemView*>( widget )
 
273
            || qobject_cast<QAbstractSpinBox*>( widget )
 
274
            || qobject_cast<QCheckBox*>( widget )
 
275
            || qobject_cast<QComboBox*>( widget )
 
276
            || qobject_cast<QDial*>( widget )
 
277
            || qobject_cast<QLineEdit*>( widget )
 
278
            || qobject_cast<QPushButton*>( widget )
 
279
            || qobject_cast<QRadioButton*>( widget )
 
280
            || qobject_cast<QScrollBar*>( widget )
 
281
            || qobject_cast<QSlider*>( widget )
 
282
            || qobject_cast<QSplitterHandle*>( widget )
 
283
            || qobject_cast<QTabBar*>( widget )
 
284
            || qobject_cast<QTextEdit*>( widget )
 
285
            || qobject_cast<QToolButton*>( widget )
 
286
            )
 
287
        { widget->setAttribute( Qt::WA_Hover ); }
 
288
 
 
289
        // transparent tooltips
 
290
        if( widget->inherits( "QTipLabel" ) )
 
291
        {
 
292
            widget->setAttribute( Qt::WA_TranslucentBackground );
 
293
 
 
294
            #ifdef Q_WS_WIN
 
295
            //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly
 
296
            widget->setWindowFlags( widget->windowFlags() | Qt::FramelessWindowHint );
 
297
            #endif
 
298
        }
 
299
 
 
300
        // also enable hover effects in itemviews' viewport
 
301
        if( QAbstractItemView *itemView = qobject_cast<QAbstractItemView*>( widget ) )
 
302
        { itemView->viewport()->setAttribute( Qt::WA_Hover ); }
 
303
 
 
304
        // checkable group boxes
 
305
        if( QGroupBox* groupBox = qobject_cast<QGroupBox*>( widget ) )
 
306
        {
 
307
 
 
308
            if( groupBox->isCheckable() )
 
309
            { groupBox->setAttribute( Qt::WA_Hover ); }
 
310
 
 
311
        } else if( qobject_cast<QAbstractButton*>( widget ) && qobject_cast<QDockWidget*>( widget->parent() ) ) {
 
312
 
 
313
            widget->setAttribute( Qt::WA_Hover );
 
314
 
 
315
        } else if( qobject_cast<QAbstractButton*>( widget ) && qobject_cast<QToolBox*>( widget->parent() ) ) {
 
316
 
 
317
            widget->setAttribute( Qt::WA_Hover );
 
318
 
 
319
        }
 
320
 
 
321
        /*
 
322
        add extra margins for widgets in toolbars
 
323
        this allows to preserve alignment with respect to actions
 
324
        */
 
325
        if( qobject_cast<QToolBar*>( widget->parent() ) )
 
326
        { widget->setContentsMargins( 0,0,0,1 ); }
 
327
 
 
328
        if( qobject_cast<QToolButton*>( widget ) )
 
329
        {
 
330
            if( qobject_cast<QToolBar*>( widget->parent() ) )
 
331
            {
 
332
                // this hack is needed to have correct text color
 
333
                // rendered in toolbars. This does not really update nicely when changing styles
 
334
                // but is the best I can do for now since setting the palette color at painting
 
335
                // time is not doable
 
336
                QPalette palette( widget->palette() );
 
337
                palette.setColor( QPalette::Disabled, QPalette::ButtonText, palette.color( QPalette::Disabled, QPalette::WindowText ) );
 
338
                palette.setColor( QPalette::Active, QPalette::ButtonText, palette.color( QPalette::Active, QPalette::WindowText ) );
 
339
                palette.setColor( QPalette::Inactive, QPalette::ButtonText, palette.color( QPalette::Inactive, QPalette::WindowText ) );
 
340
                widget->setPalette( palette );
 
341
            }
 
342
 
 
343
            widget->setBackgroundRole( QPalette::NoRole );
 
344
 
 
345
        } else if( qobject_cast<QMenuBar*>( widget ) ) {
 
346
 
 
347
            widget->setBackgroundRole( QPalette::NoRole );
 
348
 
 
349
        } else if( widget->inherits( "KMultiTabBar" ) ) {
 
350
 
 
351
            // kMultiTabBar margins are set to unity for alignment
 
352
            // with ( usually sunken ) neighbor frames
 
353
            widget->setContentsMargins( 1, 1, 1, 1 );
 
354
 
 
355
        } else if( widget->inherits( "Q3ToolBar" ) || qobject_cast<QToolBar*>( widget ) ) {
 
356
 
 
357
            widget->setBackgroundRole( QPalette::NoRole );
 
358
            widget->setAttribute( Qt::WA_TranslucentBackground );
 
359
            addEventFilter( widget );
 
360
 
 
361
            #ifdef Q_WS_WIN
 
362
            //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly
 
363
            widget->setWindowFlags( widget->windowFlags() | Qt::FramelessWindowHint );
 
364
            #endif
 
365
 
 
366
        } else if( qobject_cast<QTabBar*>( widget ) ) {
 
367
 
 
368
            addEventFilter( widget );
 
369
 
 
370
        } else if( widget->inherits( "QTipLabel" ) ) {
 
371
 
 
372
            widget->setBackgroundRole( QPalette::NoRole );
 
373
            widget->setAttribute( Qt::WA_TranslucentBackground );
 
374
 
 
375
            #ifdef Q_WS_WIN
 
376
            //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly
 
377
            widget->setWindowFlags( widget->windowFlags() | Qt::FramelessWindowHint );
 
378
            #endif
 
379
 
 
380
        } else if( qobject_cast<QScrollBar*>( widget ) ) {
 
381
 
 
382
            widget->setAttribute( Qt::WA_OpaquePaintEvent, false );
 
383
 
 
384
            // when painted in konsole, one needs to paint the window background below
 
385
            // the scrollarea, otherwise an ugly flat background is used
 
386
            if( widget->parent() && widget->parent()->inherits( "Konsole::TerminalDisplay" ) )
 
387
            { addEventFilter( widget ); }
 
388
 
 
389
        } else if( qobject_cast<QDockWidget*>( widget ) ) {
 
390
 
 
391
            widget->setBackgroundRole( QPalette::NoRole );
 
392
            widget->setAttribute( Qt::WA_TranslucentBackground );
 
393
            widget->setContentsMargins( 3,3,3,3 );
 
394
            addEventFilter( widget );
 
395
 
 
396
        } else if( qobject_cast<QMdiSubWindow*>( widget ) ) {
 
397
 
 
398
            widget->setAutoFillBackground( false );
 
399
            addEventFilter( widget );
 
400
 
 
401
        } else if( qobject_cast<QToolBox*>( widget ) ) {
 
402
 
 
403
            widget->setBackgroundRole( QPalette::NoRole );
 
404
            widget->setAutoFillBackground( false );
 
405
            widget->setContentsMargins( 5,5,5,5 );
 
406
            addEventFilter( widget );
 
407
 
 
408
        } else if( widget->parentWidget() && widget->parentWidget()->parentWidget() && qobject_cast<QToolBox*>( widget->parentWidget()->parentWidget()->parentWidget() ) ) {
 
409
 
 
410
            widget->setBackgroundRole( QPalette::NoRole );
 
411
            widget->setAutoFillBackground( false );
 
412
            widget->parentWidget()->setAutoFillBackground( false );
 
413
 
 
414
        } else if( qobject_cast<QMenu*>( widget ) ) {
 
415
 
 
416
            widget->setAttribute( Qt::WA_TranslucentBackground );
 
417
            #ifdef Q_WS_WIN
 
418
            //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly
 
419
            widget->setWindowFlags( widget->windowFlags() | Qt::FramelessWindowHint );
 
420
            #endif
 
421
 
 
422
        } else if( widget->inherits( "QComboBoxPrivateContainer" ) ) {
 
423
 
 
424
            addEventFilter( widget );
 
425
            widget->setAttribute( Qt::WA_TranslucentBackground );
 
426
            #ifdef Q_WS_WIN
 
427
            //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly
 
428
            widget->setWindowFlags( widget->windowFlags() | Qt::FramelessWindowHint );
 
429
            #endif
 
430
 
 
431
        } else if( widget->inherits( "KWin::GeometryTip" ) ) {
 
432
 
 
433
            // special handling of kwin geometry tip widget
 
434
            addEventFilter( widget );
 
435
            widget->setAttribute( Qt::WA_NoSystemBackground );
 
436
            widget->setAttribute( Qt::WA_TranslucentBackground );
 
437
            if( QLabel* label = qobject_cast<QLabel*>( widget ) )
 
438
            {
 
439
                label->setFrameStyle( QFrame::NoFrame );
 
440
                label->setMargin( 5 );
 
441
            }
 
442
 
 
443
            #ifdef Q_WS_WIN
 
444
            widget->setWindowFlags( widget->windowFlags() | Qt::FramelessWindowHint );
 
445
            #endif
 
446
 
 
447
        } else if( qobject_cast<QFrame*>( widget ) && widget->parent() && widget->parent()->inherits( "KTitleWidget" ) ) {
 
448
 
 
449
            widget->setAutoFillBackground( false );
 
450
            widget->setBackgroundRole( QPalette::Window );
 
451
 
 
452
        }
 
453
 
 
454
        // base class polishing
 
455
        QCommonStyle::polish( widget );
 
456
 
 
457
    }
 
458
 
 
459
    //_______________________________________________________________
 
460
    void Style::unpolish( QWidget* widget )
 
461
    {
 
462
 
 
463
        // register widget to animations
 
464
        animations().unregisterWidget( widget );
 
465
        transitions().unregisterWidget( widget );
 
466
        windowManager().unregisterWidget( widget );
 
467
        frameShadowFactory().unregisterWidget( widget );
 
468
        mdiWindowShadowFactory().unregisterWidget( widget );
 
469
        shadowHelper().unregisterWidget( widget );
 
470
 
 
471
        if( isKTextEditFrame( widget ) )
 
472
        { widget->setAttribute( Qt::WA_Hover, false  ); }
 
473
 
 
474
        if( widget && widget->inherits( "Q3ListView" ) ) {
 
475
 
 
476
            widget->removeEventFilter( this );
 
477
            widget->setAttribute( Qt::WA_Hover, false );
 
478
 
 
479
        }
 
480
 
 
481
        // event filters
 
482
        switch ( widget->windowFlags() & Qt::WindowType_Mask )
 
483
        {
 
484
 
 
485
            case Qt::Window:
 
486
            case Qt::Dialog:
 
487
            widget->removeEventFilter( this );
 
488
            widget->setAttribute( Qt::WA_StyledBackground, false );
 
489
            break;
 
490
 
 
491
            default:
 
492
            break;
 
493
 
 
494
        }
 
495
 
 
496
        // checkable group boxes
 
497
        if( QGroupBox* groupBox = qobject_cast<QGroupBox*>( widget ) )
 
498
        {
 
499
            if( groupBox->isCheckable() )
 
500
            { groupBox->setAttribute( Qt::WA_Hover, false ); }
 
501
        }
 
502
 
 
503
        // hover flags
 
504
        if(
 
505
            qobject_cast<QAbstractItemView*>( widget )
 
506
            || qobject_cast<QAbstractSpinBox*>( widget )
 
507
            || qobject_cast<QCheckBox*>( widget )
 
508
            || qobject_cast<QComboBox*>( widget )
 
509
            || qobject_cast<QDial*>( widget )
 
510
            || qobject_cast<QLineEdit*>( widget )
 
511
            || qobject_cast<QPushButton*>( widget )
 
512
            || qobject_cast<QRadioButton*>( widget )
 
513
            || qobject_cast<QScrollBar*>( widget )
 
514
            || qobject_cast<QSlider*>( widget )
 
515
            || qobject_cast<QSplitterHandle*>( widget )
 
516
            || qobject_cast<QTabBar*>( widget )
 
517
            || qobject_cast<QTextEdit*>( widget )
 
518
            || qobject_cast<QToolButton*>( widget )
 
519
            )
 
520
        { widget->setAttribute( Qt::WA_Hover, false ); }
 
521
 
 
522
        // checkable group boxes
 
523
        if( QGroupBox* groupBox = qobject_cast<QGroupBox*>( widget ) )
 
524
        {
 
525
            if( groupBox->isCheckable() )
 
526
            { groupBox->setAttribute( Qt::WA_Hover, false ); }
 
527
        }
 
528
 
 
529
        if( qobject_cast<QMenuBar*>( widget )
 
530
            || ( widget && widget->inherits( "Q3ToolBar" ) )
 
531
            || qobject_cast<QToolBar*>( widget )
 
532
            || ( widget && qobject_cast<QToolBar *>( widget->parent() ) )
 
533
            || qobject_cast<QToolBox*>( widget ) )
 
534
        {
 
535
            widget->setBackgroundRole( QPalette::Button );
 
536
            widget->removeEventFilter( this );
 
537
            widget->clearMask();
 
538
        }
 
539
 
 
540
        if( qobject_cast<QTabBar*>( widget ) )
 
541
        {
 
542
 
 
543
            widget->removeEventFilter( this );
 
544
 
 
545
        } else if( widget->inherits( "QTipLabel" ) ) {
 
546
 
 
547
            widget->setAttribute( Qt::WA_PaintOnScreen, false );
 
548
            widget->setAttribute( Qt::WA_NoSystemBackground, false );
 
549
            widget->clearMask();
 
550
 
 
551
        } else if( qobject_cast<QScrollBar*>( widget ) ) {
 
552
 
 
553
            widget->setAttribute( Qt::WA_OpaquePaintEvent );
 
554
 
 
555
        } else if( qobject_cast<QDockWidget*>( widget ) ) {
 
556
 
 
557
            widget->setContentsMargins( 0,0,0,0 );
 
558
            widget->clearMask();
 
559
 
 
560
        } else if( qobject_cast<QToolBox*>( widget ) ) {
 
561
 
 
562
            widget->setBackgroundRole( QPalette::Button );
 
563
            widget->setContentsMargins( 0,0,0,0 );
 
564
            widget->removeEventFilter( this );
 
565
 
 
566
        } else if( qobject_cast<QMenu*>( widget ) ) {
 
567
 
 
568
            widget->setAttribute( Qt::WA_PaintOnScreen, false );
 
569
            widget->setAttribute( Qt::WA_NoSystemBackground, false );
 
570
            widget->clearMask();
 
571
 
 
572
        } else if( widget->inherits( "QComboBoxPrivateContainer" ) ) widget->removeEventFilter( this );
 
573
 
 
574
        QCommonStyle::unpolish( widget );
 
575
 
 
576
    }
 
577
 
 
578
    //______________________________________________________________
 
579
    int Style::pixelMetric( PixelMetric metric, const QStyleOption* option, const QWidget* widget ) const
 
580
    {
 
581
 
 
582
        // handle special cases
 
583
        switch( metric )
 
584
        {
 
585
 
 
586
            // rely on QCommonStyle here
 
587
            case PM_SmallIconSize:
 
588
            case PM_ButtonIconSize:
 
589
            return KIconLoader::global()->currentSize( KIconLoader::Small );
 
590
 
 
591
            case PM_ToolBarIconSize:
 
592
            return KIconLoader::global()->currentSize( KIconLoader::Toolbar );
 
593
 
 
594
            case PM_LargeIconSize:
 
595
            return KIconLoader::global()->currentSize( KIconLoader::Dialog );
 
596
 
 
597
            case PM_MessageBoxIconSize:
 
598
            return KIconLoader::SizeHuge;
 
599
 
 
600
            case PM_DefaultFrameWidth:
 
601
            {
 
602
 
 
603
                if( qobject_cast<const QLineEdit*>( widget ) ) return LineEdit_FrameWidth;
 
604
                else if( qobject_cast<const QComboBox*>( widget ) ) return ComboBox_FrameWidth;
 
605
                else if( qobject_cast<const QFrame*>( widget ) )
 
606
                {
 
607
 
 
608
                    // special case for KTitleWidget: frameWidth is set to zero, since
 
609
                    // no frame, nor background is painted for these
 
610
                    if( widget->parent() && widget->parent()->inherits( "KTitleWidget" ) ) return 0;
 
611
                    else return Frame_FrameWidth;
 
612
 
 
613
                }
 
614
                else if( qstyleoption_cast<const QStyleOptionGroupBox *>( option ) ) return GroupBox_FrameWidth;
 
615
                else return 1;
 
616
 
 
617
            }
 
618
 
 
619
            case PM_LayoutLeftMargin:
 
620
            case PM_LayoutTopMargin:
 
621
            case PM_LayoutRightMargin:
 
622
            case PM_LayoutBottomMargin:
 
623
            {
 
624
                // use either Child margin or TopLevel margin, depending on
 
625
                // widget type
 
626
                if( ( option && ( option->state & QStyle::State_Window ) ) || ( widget && widget->isWindow() ) )
 
627
                {
 
628
 
 
629
                    return pixelMetric( PM_DefaultTopLevelMargin, option, widget );
 
630
 
 
631
                } else {
 
632
 
 
633
                    return pixelMetric( PM_DefaultChildMargin, option, widget );
 
634
 
 
635
                }
 
636
 
 
637
            }
 
638
 
 
639
            // push buttons
 
640
            /* HACK: needs special case for kcalc buttons, to prevent the application to set too small margins */
 
641
            case PM_ButtonMargin:
 
642
            { return ( widget && widget->inherits( "KCalcButton" ) ) ? 8:5; }
 
643
 
 
644
            case PM_MenuButtonIndicator:
 
645
            {
 
646
                if( qstyleoption_cast<const QStyleOptionToolButton*>( option ) ) return ToolButton_MenuIndicatorSize;
 
647
                else return PushButton_MenuIndicatorSize;
 
648
            }
 
649
 
 
650
            case PM_ScrollBarExtent:
 
651
            return StyleConfigData::scrollBarWidth() + 2;
 
652
 
 
653
            case PM_ScrollBarSliderMin: return ScrollBar_MinimumSliderHeight;
 
654
 
 
655
            // tooltip label
 
656
            case PM_ToolTipLabelFrameWidth:
 
657
            {
 
658
                if( StyleConfigData::toolTipDrawStyledFrames() ) return 3;
 
659
                else break;
 
660
            }
 
661
 
 
662
            case PM_DefaultChildMargin: return 4;
 
663
            case PM_DefaultTopLevelMargin: return 11;
 
664
            case PM_DefaultLayoutSpacing: return 4;
 
665
            case PM_LayoutHorizontalSpacing: return -1;
 
666
            case PM_LayoutVerticalSpacing: return -1;
 
667
 
 
668
            // buttons
 
669
            case PM_ButtonDefaultIndicator: return 0;
 
670
            case PM_ButtonShiftHorizontal: return 0;
 
671
            case PM_ButtonShiftVertical: return 0;
 
672
 
 
673
            // checkboxes: return radiobutton sizes
 
674
            case PM_IndicatorWidth: return CheckBox_Size;
 
675
            case PM_IndicatorHeight: return CheckBox_Size;
 
676
            case PM_ExclusiveIndicatorWidth: return CheckBox_Size;
 
677
            case PM_ExclusiveIndicatorHeight: return CheckBox_Size;
 
678
            case PM_CheckListControllerSize: return CheckBox_Size;
 
679
            case PM_CheckListButtonSize: return CheckBox_Size;
 
680
 
 
681
            // splitters and dock widgets
 
682
            case PM_SplitterWidth: return Splitter_Width;
 
683
            case PM_DockWidgetFrameWidth: return DockWidget_FrameWidth;
 
684
            case PM_DockWidgetSeparatorExtent: return DockWidget_SeparatorExtend;
 
685
            case PM_DockWidgetTitleMargin: return DockWidget_TitleMargin;
 
686
 
 
687
            // progress bar
 
688
            case PM_ProgressBarChunkWidth: return 1;
 
689
 
 
690
            // menu bars
 
691
            case PM_MenuBarPanelWidth: return 0;
 
692
            case PM_MenuBarHMargin: return 0;
 
693
            case PM_MenuBarVMargin: return 0;
 
694
            case PM_MenuBarItemSpacing: return 0;
 
695
            case PM_MenuDesktopFrameWidth: return 0;
 
696
            case PM_MenuPanelWidth: return 5;
 
697
 
 
698
            case PM_MenuScrollerHeight: return 10;
 
699
            case PM_MenuTearoffHeight: return 10;
 
700
 
 
701
            // tabbars
 
702
            case PM_TabBarTabHSpace: return 0;
 
703
            case PM_TabBarTabVSpace: return 0;
 
704
            case PM_TabBarBaseHeight: return TabBar_BaseHeight;
 
705
            case PM_TabBarBaseOverlap: return TabBar_BaseOverlap;
 
706
            case PM_TabBarTabOverlap: return 0;
 
707
            case PM_TabBarScrollButtonWidth: return TabBar_ScrollButtonWidth;
 
708
 
 
709
            /*
 
710
            disable shifts: return because last time I checked it did not work well
 
711
            for South and East tabs. Instead the shifts are added directly in
 
712
            drawTabBarTabLabel. ( Hugo )
 
713
            */
 
714
            case PM_TabBarTabShiftVertical: return 0;
 
715
            case PM_TabBarTabShiftHorizontal: return 0;
 
716
 
 
717
            // sliders
 
718
            case PM_SliderThickness: return 23;
 
719
            case PM_SliderControlThickness: return 23;
 
720
            case PM_SliderLength: return 21;
 
721
 
 
722
            // spinboxes
 
723
            case PM_SpinBoxFrameWidth: return SpinBox_FrameWidth;
 
724
 
 
725
            // comboboxes
 
726
            case PM_ComboBoxFrameWidth: return ComboBox_FrameWidth;
 
727
 
 
728
            // tree view header
 
729
            case PM_HeaderMarkSize: return 9;
 
730
            case PM_HeaderMargin: return 3;
 
731
 
 
732
            // toolbars
 
733
            case PM_ToolBarFrameWidth: return 0;
 
734
            case PM_ToolBarHandleExtent: return 6;
 
735
            case PM_ToolBarSeparatorExtent: return 6;
 
736
 
 
737
            case PM_ToolBarExtensionExtent: return 16;
 
738
            case PM_ToolBarItemMargin: return 1;
 
739
            case PM_ToolBarItemSpacing: return 1;
 
740
 
 
741
            // MDI windows titlebars
 
742
            case PM_TitleBarHeight: return 20;
 
743
 
 
744
            // spacing between widget and scrollbars
 
745
            case PM_ScrollView_ScrollBarSpacing:
 
746
            if( const QFrame* frame = qobject_cast<const QFrame*>( widget ) )
 
747
            {
 
748
 
 
749
                const bool framed( frame->frameShape() != QFrame::NoFrame );
 
750
                return framed ? -2:0;
 
751
 
 
752
            } else return -2;
 
753
 
 
754
            default: break;
 
755
        }
 
756
 
 
757
        // fallback
 
758
        return QCommonStyle::pixelMetric( metric, option, widget );
 
759
 
 
760
    }
 
761
 
 
762
    //______________________________________________________________
 
763
    int Style::styleHint( StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData ) const
 
764
    {
 
765
 
 
766
        // handles SH_KCustomStyleElement out of switch statement,
 
767
        // to avoid warning at compilation
 
768
        if( hint == SH_KCustomStyleElement )
 
769
        {
 
770
            if( widget ) return _styleElements.value( widget->objectName(), 0 );
 
771
            else return 0;
 
772
        }
 
773
 
 
774
        /*
 
775
        special cases, that cannot be registered in styleHint map,
 
776
        because of conditional statements
 
777
        */
 
778
        switch( hint )
 
779
        {
 
780
 
 
781
            case SH_DialogButtonBox_ButtonsHaveIcons:
 
782
            return KGlobalSettings::showIconsOnPushButtons();
 
783
 
 
784
            case SH_GroupBox_TextLabelColor:
 
785
            if( option ) return option->palette.color( QPalette::WindowText ).rgba();
 
786
            else return qApp->palette().color( QPalette::WindowText ).rgba();
 
787
 
 
788
            case SH_ItemView_ActivateItemOnSingleClick:
 
789
            return helper().config()->group( "KDE" ).readEntry( "SingleClick", KDE_DEFAULT_SINGLECLICK );
 
790
            return false;
 
791
 
 
792
            case SH_RubberBand_Mask:
 
793
            {
 
794
 
 
795
                const QStyleOptionRubberBand *opt = qstyleoption_cast<const QStyleOptionRubberBand *>( option );
 
796
                if( !opt ) return false;
 
797
 
 
798
                if( QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>( returnData ) )
 
799
                {
 
800
 
 
801
                    mask->region = option->rect;
 
802
 
 
803
                    // need to check on widget before removing inner region
 
804
                    // in order to still preserve rubberband in MainWindow and QGraphicsView
 
805
                    // in QMainWindow because it looks better
 
806
                    // in QGraphicsView because the painting fails completely otherwise
 
807
                    if( !( widget && (
 
808
                        qobject_cast<const QGraphicsView*>( widget->parent() ) ||
 
809
                        qobject_cast<const QMainWindow*>( widget->parent() ) ) ) )
 
810
                        { mask->region -= option->rect.adjusted( 1,1,-1,-1 ); }
 
811
 
 
812
                        return true;
 
813
                }
 
814
                return false;
 
815
            }
 
816
 
 
817
            case SH_ToolTip_Mask:
 
818
            case SH_Menu_Mask:
 
819
            {
 
820
 
 
821
                if( !helper().hasAlphaChannel( widget ) && ( !widget || widget->isWindow() ) )
 
822
                {
 
823
 
 
824
                    // mask should be set only if compositing is disabled
 
825
                    if( QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>( returnData ) )
 
826
                    { mask->region = helper().roundedMask( option->rect ); }
 
827
 
 
828
                }
 
829
 
 
830
                return true;
 
831
 
 
832
            }
 
833
 
 
834
            // mouse tracking
 
835
            case SH_ComboBox_ListMouseTracking: return true;
 
836
            case SH_MenuBar_MouseTracking: return true;
 
837
            case SH_Menu_MouseTracking: return true;
 
838
 
 
839
            case SH_Menu_SubMenuPopupDelay: return 150;
 
840
 
 
841
            case SH_TitleBar_NoBorder: return 0;
 
842
            case SH_GroupBox_TextLabelVerticalAlignment: return Qt::AlignVCenter;
 
843
            case SH_DialogButtonLayout: return QDialogButtonBox::KdeLayout;
 
844
            case SH_ScrollBar_MiddleClickAbsolutePosition: return true;
 
845
            case SH_ItemView_ShowDecorationSelected: return false;
 
846
            case SH_ItemView_ArrowKeysNavigateIntoChildren: return true;
 
847
            case SH_ScrollView_FrameOnlyAroundContents: return true;
 
848
            case SH_FormLayoutFormAlignment: return Qt::AlignLeft | Qt::AlignTop;
 
849
            case SH_FormLayoutLabelAlignment: return Qt::AlignRight;
 
850
            case SH_FormLayoutFieldGrowthPolicy: return QFormLayout::ExpandingFieldsGrow;
 
851
            case SH_FormLayoutWrapPolicy: return QFormLayout::DontWrapRows;
 
852
            case SH_MessageBox_TextInteractionFlags: return true;
 
853
            case SH_WindowFrame_Mask: return false;
 
854
 
 
855
            default: return QCommonStyle::styleHint( hint, option, widget, returnData );
 
856
        }
 
857
 
 
858
    }
 
859
 
 
860
    //______________________________________________________________
 
861
    QRect Style::subElementRect( SubElement element, const QStyleOption* option, const QWidget* widget ) const
 
862
    {
 
863
 
 
864
 
 
865
        switch( element )
 
866
        {
 
867
 
 
868
            // push buttons
 
869
            case SE_PushButtonContents: return pushButtonContentsRect( option, widget );
 
870
            case SE_PushButtonFocusRect: return defaultSubElementRect( option, widget );
 
871
 
 
872
            // checkboxes
 
873
            case SE_CheckBoxContents: return checkBoxContentsRect( option, widget );
 
874
            case SE_CheckBoxFocusRect: return defaultSubElementRect( option, widget );
 
875
 
 
876
            // progress bars
 
877
            case SE_ProgressBarGroove: return defaultSubElementRect( option, widget );
 
878
            case SE_ProgressBarContents: return progressBarContentsRect( option, widget );
 
879
            case SE_ProgressBarLabel: return defaultSubElementRect( option, widget );
 
880
 
 
881
            // radio buttons
 
882
            case SE_RadioButtonContents: return checkBoxContentsRect( option, widget );
 
883
            case SE_RadioButtonFocusRect: return defaultSubElementRect( option, widget );
 
884
 
 
885
            // tab widget
 
886
            case SE_TabBarTabLeftButton: return tabBarTabLeftButtonRect( option, widget );
 
887
            case SE_TabBarTabRightButton: return tabBarTabRightButtonRect( option, widget );
 
888
            case SE_TabBarTabText: return tabBarTabTextRect( option, widget );
 
889
            case SE_TabWidgetTabContents: return tabWidgetTabContentsRect( option, widget );
 
890
            case SE_TabWidgetTabPane: return tabWidgetTabPaneRect( option, widget );
 
891
            case SE_TabWidgetLeftCorner: return tabWidgetLeftCornerRect( option, widget );
 
892
            case SE_TabWidgetRightCorner: return tabWidgetRightCornerRect( option, widget );
 
893
 
 
894
            // toolboxes
 
895
            case SE_ToolBoxTabContents: return toolBoxTabContentsRect( option, widget );
 
896
 
 
897
            default: return QCommonStyle::subElementRect( element, option, widget );
 
898
 
 
899
        }
 
900
 
 
901
    }
 
902
 
 
903
    //______________________________________________________________
 
904
    QRect Style::subControlRect( ComplexControl element, const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const
 
905
    {
 
906
 
 
907
        switch( element )
 
908
        {
 
909
 
 
910
            case CC_GroupBox: return groupBoxSubControlRect( option, subControl, widget );
 
911
            case CC_ComboBox: return comboBoxSubControlRect( option, subControl, widget );
 
912
            case CC_Slider: return sliderSubControlRect( option, subControl, widget );
 
913
            case CC_ScrollBar: return scrollBarSubControlRect( option, subControl, widget );
 
914
            case CC_SpinBox: return spinBoxSubControlRect( option, subControl, widget );
 
915
            default: return QCommonStyle::subControlRect( element, option, subControl, widget );
 
916
        }
 
917
 
 
918
    }
 
919
 
 
920
    //______________________________________________________________
 
921
    QSize Style::sizeFromContents( ContentsType element, const QStyleOption* option, const QSize& size, const QWidget* widget ) const
 
922
    {
 
923
 
 
924
        switch( element )
 
925
        {
 
926
            case CT_CheckBox: return checkBoxSizeFromContents( option, size, widget );
 
927
            case CT_ComboBox: return comboBoxSizeFromContents( option, size, widget );
 
928
            case CT_HeaderSection: return headerSectionSizeFromContents( option, size, widget );
 
929
            case CT_PushButton: return pushButtonSizeFromContents( option, size, widget );
 
930
            case CT_MenuBar: return menuBarSizeFromContents( option, size, widget );
 
931
            case CT_MenuBarItem: return menuBarItemSizeFromContents( option, size, widget );
 
932
            case CT_MenuItem: return menuItemSizeFromContents( option, size, widget );
 
933
            case CT_RadioButton: return checkBoxSizeFromContents( option, size, widget );
 
934
            case CT_TabBarTab: return tabBarTabSizeFromContents( option, size, widget );
 
935
            case CT_TabWidget: return tabWidgetSizeFromContents( option, size, widget );
 
936
            case CT_ToolButton: return toolButtonSizeFromContents( option, size, widget );
 
937
            default: return QCommonStyle::sizeFromContents( element, option, size, widget );
 
938
        }
 
939
 
 
940
    }
 
941
 
 
942
    //______________________________________________________________
 
943
    QStyle::SubControl Style::hitTestComplexControl( ComplexControl control, const QStyleOptionComplex* option, const QPoint& point, const QWidget* widget ) const
 
944
    {
 
945
        switch( control )
 
946
        {
 
947
            case CC_ScrollBar:
 
948
            {
 
949
 
 
950
                QRect groove = scrollBarSubControlRect( option, SC_ScrollBarGroove, widget );
 
951
                if ( groove.contains( point ) )
 
952
                {
 
953
                    //Must be either page up/page down, or just click on the slider.
 
954
                    //Grab the slider to compare
 
955
                    QRect slider = scrollBarSubControlRect( option, SC_ScrollBarSlider, widget );
 
956
 
 
957
                    if( slider.contains( point ) ) return SC_ScrollBarSlider;
 
958
                    else if( preceeds( point, slider, option ) ) return SC_ScrollBarSubPage;
 
959
                    else return SC_ScrollBarAddPage;
 
960
 
 
961
                }
 
962
 
 
963
                //This is one of the up/down buttons. First, decide which one it is.
 
964
                if( preceeds( point, groove, option ) )
 
965
                {
 
966
 
 
967
                    if( _subLineButtons == DoubleButton )
 
968
                    {
 
969
                        QRect buttonRect = scrollBarInternalSubControlRect( option, SC_ScrollBarSubLine );
 
970
                        return scrollBarHitTest( buttonRect, point, option );
 
971
                    } else return SC_ScrollBarSubLine;
 
972
 
 
973
                }
 
974
 
 
975
                if( _addLineButtons == DoubleButton )
 
976
                {
 
977
 
 
978
                    QRect buttonRect = scrollBarInternalSubControlRect( option, SC_ScrollBarAddLine );
 
979
                    return scrollBarHitTest( buttonRect, point, option );
 
980
 
 
981
                } else return SC_ScrollBarAddLine;
 
982
            }
 
983
 
 
984
            default: return QCommonStyle::hitTestComplexControl( control, option, point, widget );
 
985
        }
 
986
 
 
987
    }
 
988
 
 
989
    //______________________________________________________________
 
990
    void Style::drawPrimitive( PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
991
    {
 
992
 
 
993
        painter->save();
 
994
 
 
995
        StylePrimitive fcn( 0 );
 
996
        switch( element )
 
997
        {
 
998
 
 
999
            // register primitives for which nothing is done
 
1000
            case PE_FrameStatusBar: fcn = &Style::emptyPrimitive; break;
 
1001
 
 
1002
            case PE_Frame: fcn = &Style::drawFramePrimitive; break;
 
1003
 
 
1004
            // frame focus primitive is set at run time, in oxygenConfigurationChanged
 
1005
            case PE_FrameFocusRect: fcn = _frameFocusPrimitive; break;
 
1006
 
 
1007
            case PE_FrameGroupBox: fcn = &Style::drawFrameGroupBoxPrimitive; break;
 
1008
            case PE_FrameLineEdit: fcn = &Style::drawFramePrimitive; break;
 
1009
            case PE_FrameMenu: fcn = &Style::drawFrameMenuPrimitive; break;
 
1010
 
 
1011
            // TabBar
 
1012
            case PE_FrameTabBarBase: fcn = &Style::drawFrameTabBarBasePrimitive; break;
 
1013
            case PE_FrameTabWidget: fcn = &Style::drawFrameTabWidgetPrimitive; break;
 
1014
 
 
1015
            case PE_FrameWindow: fcn = &Style::drawFrameWindowPrimitive; break;
 
1016
 
 
1017
            // arrows
 
1018
            case PE_IndicatorArrowUp: fcn = &Style::drawIndicatorArrowUpPrimitive; break;
 
1019
            case PE_IndicatorArrowDown: fcn = &Style::drawIndicatorArrowDownPrimitive; break;
 
1020
            case PE_IndicatorArrowLeft: fcn = &Style::drawIndicatorArrowLeftPrimitive; break;
 
1021
            case PE_IndicatorArrowRight: fcn = &Style::drawIndicatorArrowRightPrimitive; break;
 
1022
 
 
1023
            case PE_IndicatorDockWidgetResizeHandle: fcn = &Style::drawIndicatorDockWidgetResizeHandlePrimitive; break;
 
1024
            case PE_IndicatorHeaderArrow: fcn = &Style::drawIndicatorHeaderArrowPrimitive; break;
 
1025
 
 
1026
            case PE_PanelButtonCommand: fcn = &Style::drawPanelButtonCommandPrimitive; break;
 
1027
            case PE_PanelButtonTool: fcn = &Style::drawPanelButtonToolPrimitive; break;
 
1028
 
 
1029
            case PE_PanelItemViewItem: fcn = &Style::drawPanelItemViewItemPrimitive; break;
 
1030
            case PE_PanelLineEdit: fcn = &Style::drawPanelLineEditPrimitive; break;
 
1031
            case PE_PanelMenu: fcn = &Style::drawPanelMenuPrimitive; break;
 
1032
            case PE_PanelScrollAreaCorner: fcn = &Style::drawPanelScrollAreaCornerPrimitive; break;
 
1033
            case PE_PanelTipLabel: fcn = &Style::drawPanelTipLabelPrimitive; break;
 
1034
 
 
1035
            case PE_IndicatorMenuCheckMark: fcn = &Style::drawIndicatorMenuCheckMarkPrimitive; break;
 
1036
            case PE_Q3CheckListIndicator: fcn = &Style::drawQ3CheckListIndicatorPrimitive; break;
 
1037
            case PE_Q3CheckListExclusiveIndicator: fcn = &Style::drawQ3CheckListExclusiveIndicatorPrimitive; break;
 
1038
            case PE_IndicatorBranch: fcn = &Style::drawIndicatorBranchPrimitive; break;
 
1039
            case PE_IndicatorButtonDropDown: fcn = &Style::drawIndicatorButtonDropDownPrimitive; break;
 
1040
            case PE_IndicatorCheckBox: fcn = &Style::drawIndicatorCheckBoxPrimitive; break;
 
1041
            case PE_IndicatorRadioButton: fcn = &Style::drawIndicatorRadioButtonPrimitive; break;
 
1042
            case PE_IndicatorTabTear: fcn = &Style::drawIndicatorTabTearPrimitive; break;
 
1043
            case PE_IndicatorToolBarHandle: fcn = &Style::drawIndicatorToolBarHandlePrimitive; break;
 
1044
            case PE_IndicatorToolBarSeparator: fcn = &Style::drawIndicatorToolBarSeparatorPrimitive; break;
 
1045
 
 
1046
            case PE_Widget: fcn = &Style::drawWidgetPrimitive; break;
 
1047
 
 
1048
            default: break;
 
1049
 
 
1050
        }
 
1051
 
 
1052
        // try find primitive in map, and run.
 
1053
        // exit if result is true, otherwise fallback to generic case
 
1054
        if( !( fcn && ( this->*fcn )( option, painter, widget ) ) )
 
1055
        { QCommonStyle::drawPrimitive( element, option, painter, widget ); }
 
1056
 
 
1057
        painter->restore();
 
1058
 
 
1059
    }
 
1060
 
 
1061
    //______________________________________________________________
 
1062
    void Style::drawControl( ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
1063
    {
 
1064
 
 
1065
        painter->save();
 
1066
 
 
1067
        StyleControl fcn( 0 );
 
1068
        if( element == CE_CapacityBar )
 
1069
        {
 
1070
 
 
1071
            fcn = &Style::drawCapacityBarControl;
 
1072
 
 
1073
        } else switch( element ) {
 
1074
 
 
1075
            case CE_ComboBoxLabel: fcn = &Style::drawComboBoxLabelControl; break;
 
1076
            case CE_DockWidgetTitle: fcn = &Style::drawDockWidgetTitleControl; break;
 
1077
            case CE_HeaderEmptyArea: fcn = &Style::drawHeaderEmptyAreaControl; break;
 
1078
            case CE_HeaderLabel: fcn = &Style::drawHeaderLabelControl; break;
 
1079
            case CE_HeaderSection: fcn = &Style::drawHeaderSectionControl; break;
 
1080
            case CE_MenuBarEmptyArea: fcn = &Style::emptyControl; break;
 
1081
            case CE_MenuBarItem: fcn = &Style::drawMenuBarItemControl; break;
 
1082
            case CE_MenuItem: fcn = &Style::drawMenuItemControl; break;
 
1083
            case CE_ProgressBar: fcn = &Style::drawProgressBarControl; break;
 
1084
            case CE_ProgressBarContents: fcn = &Style::drawProgressBarContentsControl; break;
 
1085
            case CE_ProgressBarGroove: fcn = &Style::drawProgressBarGrooveControl; break;
 
1086
            case CE_ProgressBarLabel: fcn = &Style::drawProgressBarLabelControl; break;
 
1087
 
 
1088
            /*
 
1089
            for CE_PushButtonBevel the only thing that is done is draw the PanelButtonCommand primitive
 
1090
            since the prototypes are identical we register the second directly in the control map: fcn = without
 
1091
            using an intermediate function
 
1092
            */
 
1093
            case CE_PushButtonBevel: fcn = &Style::drawPanelButtonCommandPrimitive; break;
 
1094
            case CE_PushButtonLabel: fcn = &Style::drawPushButtonLabelControl; break;
 
1095
 
 
1096
            case CE_RubberBand: fcn = &Style::drawRubberBandControl; break;
 
1097
            case CE_ScrollBarSlider: fcn = &Style::drawScrollBarSliderControl; break;
 
1098
            case CE_ScrollBarAddLine: fcn = &Style::drawScrollBarAddLineControl; break;
 
1099
            case CE_ScrollBarAddPage: fcn = &Style::drawScrollBarAddPageControl; break;
 
1100
            case CE_ScrollBarSubLine: fcn = &Style::drawScrollBarSubLineControl; break;
 
1101
            case CE_ScrollBarSubPage: fcn = &Style::drawScrollBarSubPageControl; break;
 
1102
 
 
1103
            case CE_ShapedFrame: fcn = &Style::drawShapedFrameControl; break;
 
1104
            case CE_SizeGrip: fcn = &Style::drawSizeGripControl; break;
 
1105
            case CE_Splitter: fcn = &Style::drawSplitterControl; break;
 
1106
            case CE_TabBarTabLabel: fcn = &Style::drawTabBarTabLabelControl; break;
 
1107
 
 
1108
            // default tab style is 'SINGLE'
 
1109
            case CE_TabBarTabShape: fcn = _tabBarTabShapeControl; break;
 
1110
 
 
1111
            case CE_ToolBar: fcn = &Style::drawToolBarControl; break;
 
1112
            case CE_ToolBoxTabLabel: fcn = &Style::drawToolBoxTabLabelControl; break;
 
1113
            case CE_ToolBoxTabShape: fcn = &Style::drawToolBoxTabShapeControl; break;
 
1114
            case CE_ToolButtonLabel: fcn = &Style::drawToolButtonLabelControl; break;
 
1115
 
 
1116
            default: break;
 
1117
 
 
1118
        }
 
1119
 
 
1120
        if( !( fcn && ( this->*fcn )( option, painter, widget ) ) )
 
1121
        { QCommonStyle::drawControl( element, option, painter, widget ); }
 
1122
 
 
1123
        painter->restore();
 
1124
 
 
1125
    }
 
1126
 
 
1127
    //______________________________________________________________
 
1128
    void Style::drawComplexControl( ComplexControl element, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const
 
1129
    {
 
1130
 
 
1131
        painter->save();
 
1132
 
 
1133
        StyleComplexControl fcn( 0 );
 
1134
        switch( element )
 
1135
        {
 
1136
 
 
1137
            case CC_ComboBox: fcn = &Style::drawComboBoxComplexControl; break;
 
1138
            case CC_Dial: fcn = &Style::drawDialComplexControl; break;
 
1139
            case CC_GroupBox: fcn = &Style::drawGroupBoxComplexControl; break;
 
1140
            case CC_Q3ListView: fcn = &Style::drawQ3ListViewComplexControl; break;
 
1141
            case CC_Slider: fcn = &Style::drawSliderComplexControl; break;
 
1142
            case CC_SpinBox: fcn = &Style::drawSpinBoxComplexControl; break;
 
1143
            case CC_TitleBar: fcn = &Style::drawTitleBarComplexControl; break;
 
1144
            case CC_ToolButton: fcn = &Style::drawToolButtonComplexControl; break;
 
1145
            default: break;
 
1146
 
 
1147
        }
 
1148
 
 
1149
        if( !( fcn && ( this->*fcn )( option, painter, widget ) ) )
 
1150
        { QCommonStyle::drawComplexControl( element, option, painter, widget ); }
 
1151
 
 
1152
        painter->restore();
 
1153
 
 
1154
    }
 
1155
 
 
1156
 
 
1157
    //___________________________________________________________________________________
 
1158
    void Style::drawItemText(
 
1159
        QPainter* painter, const QRect& r, int flags, const QPalette& palette, bool enabled,
 
1160
        const QString &text, QPalette::ColorRole textRole ) const
 
1161
    {
 
1162
 
 
1163
        // hide mnemonics if requested
 
1164
        if( (!_showMnemonics) && ( flags & Qt::TextShowMnemonic ) && !( flags&Qt::TextHideMnemonic ) )
 
1165
        {
 
1166
            flags &= ~Qt::TextShowMnemonic;
 
1167
            flags |= Qt::TextHideMnemonic;
 
1168
        }
 
1169
 
 
1170
        if( animations().widgetEnabilityEngine().enabled() )
 
1171
        {
 
1172
 
 
1173
            /*
 
1174
            check if painter engine is registered to WidgetEnabilityEngine, and animated
 
1175
            if yes, merge the palettes. Note: a static_cast is safe here, since only the address
 
1176
            of the pointer is used, not the actual content.
 
1177
            */
 
1178
            const QWidget* widget( static_cast<const QWidget*>( painter->device() ) );
 
1179
            if( animations().widgetEnabilityEngine().isAnimated( widget, AnimationEnable ) )
 
1180
            {
 
1181
 
 
1182
                const QPalette pal = helper().mergePalettes( palette, animations().widgetEnabilityEngine().opacity( widget, AnimationEnable )  );
 
1183
                return QCommonStyle::drawItemText( painter, r, flags, pal, enabled, text, textRole );
 
1184
 
 
1185
            }
 
1186
 
 
1187
        }
 
1188
 
 
1189
        return QCommonStyle::drawItemText( painter, r, flags, palette, enabled, text, textRole );
 
1190
 
 
1191
    }
 
1192
 
 
1193
 
 
1194
    //_____________________________________________________________________
 
1195
    bool Style::eventFilter( QObject *object, QEvent *event )
 
1196
    {
 
1197
 
 
1198
        if( QTabBar* tabBar = qobject_cast<QTabBar*>( object ) ) { return eventFilterTabBar( tabBar, event ); }
 
1199
        if( QToolBar* toolBar = qobject_cast<QToolBar*>( object ) ) { return eventFilterToolBar( toolBar, event ); }
 
1200
        if( QDockWidget* dockWidget = qobject_cast<QDockWidget*>( object ) ) { return eventFilterDockWidget( dockWidget, event ); }
 
1201
        if( QToolBox* toolBox = qobject_cast<QToolBox*>( object ) ) { return eventFilterToolBox( toolBox, event ); }
 
1202
        if( QMdiSubWindow* subWindow = qobject_cast<QMdiSubWindow*>( object ) ) { return eventFilterMdiSubWindow( subWindow, event ); }
 
1203
        if( QScrollBar* scrollBar = qobject_cast<QScrollBar*>( object ) ) { return eventFilterScrollBar( scrollBar, event ); }
 
1204
 
 
1205
        // cast to QWidget
 
1206
        QWidget *widget = static_cast<QWidget*>( object );
 
1207
 
 
1208
        if( widget->inherits( "Q3ListView" ) ) { return eventFilterQ3ListView( widget, event ); }
 
1209
        if( widget->inherits( "QComboBoxPrivateContainer" ) ) { return eventFilterComboBoxContainer( widget, event ); }
 
1210
        if( widget->inherits( "KWin::GeometryTip" ) ) { return eventFilterGeometryTip( widget, event ); }
 
1211
 
 
1212
        return QCommonStyle::eventFilter( object, event );
 
1213
 
 
1214
    }
 
1215
 
 
1216
    //_________________________________________________________
 
1217
    bool Style::eventFilterComboBoxContainer( QWidget* widget, QEvent* event )
 
1218
    {
 
1219
        switch( event->type() )
 
1220
        {
 
1221
 
 
1222
            case QEvent::Show:
 
1223
            case QEvent::Resize:
 
1224
            {
 
1225
                if( !helper().hasAlphaChannel( widget ) ) widget->setMask( helper().roundedMask( widget->rect() ) );
 
1226
                else widget->clearMask();
 
1227
                return false;
 
1228
            }
 
1229
 
 
1230
            case QEvent::Paint:
 
1231
            {
 
1232
 
 
1233
                QPainter painter( widget );
 
1234
                QPaintEvent *paintEvent = static_cast<QPaintEvent*>( event );
 
1235
                painter.setClipRegion( paintEvent->region() );
 
1236
 
 
1237
                const QRect r( widget->rect() );
 
1238
                const QColor color( widget->palette().color( widget->window()->backgroundRole() ) );
 
1239
                const bool hasAlpha( helper().hasAlphaChannel( widget ) );
 
1240
 
 
1241
                if( hasAlpha )
 
1242
                {
 
1243
 
 
1244
                    TileSet *tileSet( helper().roundCorner( color ) );
 
1245
                    tileSet->render( r, &painter );
 
1246
                    painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
 
1247
                    painter.setClipRegion( helper().roundedMask( r.adjusted( 1, 1, -1, -1 ) ), Qt::IntersectClip );
 
1248
 
 
1249
                }
 
1250
 
 
1251
                // background
 
1252
                helper().renderMenuBackground( &painter, paintEvent->rect(), widget, widget->palette() );
 
1253
 
 
1254
                // frame
 
1255
                if( hasAlpha ) painter.setClipping( false );
 
1256
 
 
1257
                helper().drawFloatFrame( &painter, r, color, !hasAlpha );
 
1258
                return false;
 
1259
 
 
1260
            }
 
1261
            default: return false;
 
1262
        }
 
1263
    }
 
1264
 
 
1265
    //____________________________________________________________________________
 
1266
    bool Style::eventFilterDockWidget( QDockWidget* dockWidget, QEvent* event )
 
1267
    {
 
1268
        switch( event->type() )
 
1269
        {
 
1270
            case QEvent::Show:
 
1271
            case QEvent::Resize:
 
1272
            {
 
1273
                // make sure mask is appropriate
 
1274
                if( dockWidget->isFloating() && !helper().hasAlphaChannel( dockWidget ) )
 
1275
                {
 
1276
 
 
1277
                    dockWidget->setMask( helper().roundedMask( dockWidget->rect() ) );
 
1278
 
 
1279
                } else dockWidget->clearMask();
 
1280
 
 
1281
                return false;
 
1282
            }
 
1283
 
 
1284
            case QEvent::Paint:
 
1285
            {
 
1286
                QPainter painter( dockWidget );
 
1287
                QPaintEvent *paintEvent = static_cast<QPaintEvent*>( event );
 
1288
                painter.setClipRegion( paintEvent->region() );
 
1289
 
 
1290
                const QColor color( dockWidget->palette().color( QPalette::Window ) );
 
1291
                const QRect r( dockWidget->rect() );
 
1292
                if( dockWidget->isWindow() )
 
1293
                {
 
1294
 
 
1295
                    #ifndef Q_WS_WIN
 
1296
                    bool hasAlpha( helper().hasAlphaChannel( dockWidget ) );
 
1297
                    if( hasAlpha )
 
1298
                    {
 
1299
                        painter.setCompositionMode( QPainter::CompositionMode_Source );
 
1300
                        TileSet *tileSet( helper().roundCorner( color ) );
 
1301
                        tileSet->render( r, &painter );
 
1302
 
 
1303
                        // set clip region
 
1304
                        painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
 
1305
                        painter.setClipRegion( helper().roundedMask( r.adjusted( 1, 1, -1, -1 ) ), Qt::IntersectClip );
 
1306
                    }
 
1307
                    #endif
 
1308
 
 
1309
                    helper().renderWindowBackground( &painter, r, dockWidget, color );
 
1310
 
 
1311
                    #ifndef Q_WS_WIN
 
1312
                    if( hasAlpha ) painter.setClipping( false );
 
1313
 
 
1314
                    helper().drawFloatFrame( &painter, r, color, !hasAlpha );
 
1315
                    #endif
 
1316
 
 
1317
                } else {
 
1318
 
 
1319
                    // need to draw window background for autoFilled dockWidgets for better rendering
 
1320
                    if( dockWidget->autoFillBackground() )
 
1321
                    { helper().renderWindowBackground( &painter, r, dockWidget, color ); }
 
1322
 
 
1323
                    // adjust color
 
1324
                    QColor top( helper().backgroundColor( color, dockWidget, r.topLeft() ) );
 
1325
                    QColor bottom( helper().backgroundColor( color, dockWidget, r.bottomLeft() ) );
 
1326
                    TileSet *tileSet = helper().dockFrame( top, bottom );
 
1327
                    tileSet->render( r, &painter );
 
1328
 
 
1329
                }
 
1330
 
 
1331
                return false;
 
1332
            }
 
1333
 
 
1334
            default: return false;
 
1335
 
 
1336
        }
 
1337
 
 
1338
    }
 
1339
 
 
1340
    //____________________________________________________________________________
 
1341
    bool Style::eventFilterGeometryTip( QWidget* widget, QEvent* event )
 
1342
    {
 
1343
        switch( event->type() )
 
1344
        {
 
1345
 
 
1346
            case QEvent::Show:
 
1347
            case QEvent::Resize:
 
1348
            {
 
1349
 
 
1350
                // make sure mask is appropriate
 
1351
                if( !helper().hasAlphaChannel( widget ) ) widget->setMask( helper().roundedMask( widget->rect() ) );
 
1352
                else widget->clearMask();
 
1353
                return false;
 
1354
            }
 
1355
 
 
1356
            case QEvent::Paint:
 
1357
            {
 
1358
 
 
1359
                const QColor color( widget->palette().window().color() );
 
1360
                const QRect r( widget->rect() );
 
1361
 
 
1362
                QPainter painter( widget );
 
1363
                QPaintEvent *paintEvent = static_cast<QPaintEvent*>( event );
 
1364
                painter.setClipRegion( paintEvent->region() );
 
1365
 
 
1366
                const bool hasAlpha( helper().hasAlphaChannel( widget ) );
 
1367
                if( hasAlpha )
 
1368
                {
 
1369
 
 
1370
                    painter.setCompositionMode( QPainter::CompositionMode_Source );
 
1371
                    TileSet *tileSet( helper().roundCorner( color ) );
 
1372
                    tileSet->render( r, &painter );
 
1373
 
 
1374
                    painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
 
1375
                    painter.setClipRegion( helper().roundedMask( r.adjusted( 1, 1, -1, -1 ) ), Qt::IntersectClip );
 
1376
 
 
1377
                }
 
1378
 
 
1379
                helper().renderMenuBackground( &painter, r, widget,color );
 
1380
 
 
1381
                // frame
 
1382
                if( hasAlpha ) painter.setClipping( false );
 
1383
                helper().drawFloatFrame( &painter, r, color, !hasAlpha );
 
1384
 
 
1385
            }
 
1386
 
 
1387
            return false;
 
1388
 
 
1389
            default: return false;
 
1390
 
 
1391
        }
 
1392
 
 
1393
        // continue with normal painting
 
1394
        return false;
 
1395
 
 
1396
    }
 
1397
 
 
1398
    //____________________________________________________________________________
 
1399
    bool Style::eventFilterMdiSubWindow( QMdiSubWindow* subWindow, QEvent* event )
 
1400
    {
 
1401
 
 
1402
        if( event->type() == QEvent::Paint )
 
1403
        {
 
1404
 
 
1405
            QPainter painter( subWindow );
 
1406
            QRect clip( static_cast<QPaintEvent*>( event )->rect() );
 
1407
            if( subWindow->isMaximized() ) helper().renderWindowBackground( &painter, clip, subWindow, subWindow->palette() );
 
1408
            else {
 
1409
 
 
1410
                painter.setClipRect( clip );
 
1411
 
 
1412
                const QRect r( subWindow->rect() );
 
1413
                TileSet *tileSet( helper().roundCorner( subWindow->palette().color( subWindow->backgroundRole() ) ) );
 
1414
                tileSet->render( r, &painter );
 
1415
 
 
1416
                painter.setClipRegion( helper().roundedMask( r.adjusted( 1, 1, -1, -1 ) ), Qt::IntersectClip );
 
1417
                helper().renderWindowBackground( &painter, clip, subWindow, subWindow, subWindow->palette(), 0, 58 );
 
1418
 
 
1419
            }
 
1420
 
 
1421
        }
 
1422
 
 
1423
        // continue with normal painting
 
1424
        return false;
 
1425
 
 
1426
    }
 
1427
 
 
1428
    //__________________________________________________________________________________
 
1429
    bool Style::eventFilterQ3ListView( QWidget* widget, QEvent* event )
 
1430
    {
 
1431
        // this apparently fixes a Qt bug with Q3ListView, consisting in
 
1432
        // the fact that Focus events do not trigger repaint of these
 
1433
        switch( event->type() )
 
1434
        {
 
1435
            case QEvent::FocusIn: widget->update(); return false;
 
1436
            case QEvent::FocusOut: widget->update(); return false;
 
1437
            default: return false;
 
1438
        }
 
1439
 
 
1440
    }
 
1441
 
 
1442
    //_________________________________________________________
 
1443
    bool Style::eventFilterScrollBar( QWidget* widget, QEvent* event )
 
1444
    {
 
1445
 
 
1446
        if( event->type() == QEvent::Paint )
 
1447
        {
 
1448
            QPainter painter( widget );
 
1449
            painter.setClipRegion( static_cast<QPaintEvent*>( event )->region() );
 
1450
            helper().renderWindowBackground( &painter, widget->rect(), widget,widget->palette() );
 
1451
        }
 
1452
 
 
1453
        return false;
 
1454
    }
 
1455
 
 
1456
    //_____________________________________________________________________
 
1457
    bool Style::eventFilterTabBar( QWidget* widget, QEvent* event )
 
1458
    {
 
1459
        if( event->type() == QEvent::Paint && tabBarData().locks( widget ) )
 
1460
        {
 
1461
            /*
 
1462
            this makes sure that tabBar base is drawn ( and drawn only once )
 
1463
            every time a replaint is triggered by dragging a tab around
 
1464
            */
 
1465
            tabBarData().setDirty();
 
1466
        }
 
1467
 
 
1468
        return false;
 
1469
    }
 
1470
 
 
1471
    //_____________________________________________________________________
 
1472
    bool Style::eventFilterToolBar( QToolBar* toolBar, QEvent* event )
 
1473
    {
 
1474
        switch( event->type() )
 
1475
        {
 
1476
            case QEvent::Show:
 
1477
            case QEvent::Resize:
 
1478
            {
 
1479
                // make sure mask is appropriate
 
1480
                if( toolBar->isFloating() && !helper().hasAlphaChannel( toolBar ) )
 
1481
                {
 
1482
 
 
1483
                    toolBar->setMask( helper().roundedMask( toolBar->rect() ) );
 
1484
 
 
1485
                } else  toolBar->clearMask();
 
1486
                return false;
 
1487
            }
 
1488
 
 
1489
            case QEvent::Paint:
 
1490
            {
 
1491
 
 
1492
                QPainter painter( toolBar );
 
1493
                QPaintEvent *paintEvent = static_cast<QPaintEvent*>( event );
 
1494
                painter.setClipRegion( paintEvent->region() );
 
1495
 
 
1496
                const QRect r( toolBar->rect() );
 
1497
                const QColor color( toolBar->palette().window().color() );
 
1498
 
 
1499
                // default painting when not qrealing
 
1500
                if( !toolBar->isFloating() )
 
1501
                {
 
1502
 
 
1503
                    // background has to be rendered explicitly
 
1504
                    // when one of the parent has autofillBackground set to true
 
1505
                    if( helper().checkAutoFillBackground( toolBar ) )
 
1506
                    { helper().renderWindowBackground( &painter, r, toolBar, color ); }
 
1507
 
 
1508
                    return false;
 
1509
 
 
1510
                }
 
1511
 
 
1512
                const bool hasAlpha( helper().hasAlphaChannel( toolBar ) );
 
1513
                if( hasAlpha )
 
1514
                {
 
1515
                    painter.setCompositionMode( QPainter::CompositionMode_Source );
 
1516
                    TileSet *tileSet( helper().roundCorner( color ) );
 
1517
                    tileSet->render( r, &painter );
 
1518
 
 
1519
                    painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
 
1520
                    painter.setClipRegion( helper().roundedMask( r.adjusted( 1, 1, -1, -1 ) ), Qt::IntersectClip );
 
1521
                }
 
1522
 
 
1523
                // background
 
1524
                helper().renderWindowBackground( &painter, r, toolBar, color );
 
1525
 
 
1526
                if( toolBar->isMovable() )
 
1527
                {
 
1528
                    // remaining painting: need to add handle
 
1529
                    // this is copied from QToolBar::paintEvent
 
1530
                    QStyleOptionToolBar opt;
 
1531
                    opt.initFrom( toolBar );
 
1532
                    if( toolBar->orientation() == Qt::Horizontal )
 
1533
                    {
 
1534
 
 
1535
                        opt.rect = handleRTL( &opt, QRect( r.topLeft(), QSize( 8, r.height() ) ) );
 
1536
                        opt.state |= QStyle::State_Horizontal;
 
1537
 
 
1538
                    } else {
 
1539
 
 
1540
                        opt.rect = handleRTL( &opt, QRect( r.topLeft(), QSize( r.width(), 8 ) ) );
 
1541
 
 
1542
                    }
 
1543
 
 
1544
                    drawIndicatorToolBarHandlePrimitive( &opt, &painter, toolBar );
 
1545
 
 
1546
                }
 
1547
 
 
1548
                // frame
 
1549
                if( hasAlpha ) painter.setClipping( false );
 
1550
                helper().drawFloatFrame( &painter, r, color, !hasAlpha );
 
1551
 
 
1552
                return true;
 
1553
 
 
1554
            }
 
1555
            default: return false;
 
1556
        }
 
1557
 
 
1558
    }
 
1559
 
 
1560
    //____________________________________________________________________________
 
1561
    bool Style::eventFilterToolBox( QToolBox* toolBox, QEvent* event )
 
1562
    {
 
1563
 
 
1564
        if( event->type() == QEvent::Paint )
 
1565
        {
 
1566
            if( toolBox->frameShape() != QFrame::NoFrame )
 
1567
            {
 
1568
 
 
1569
                const QRect r( toolBox->rect() );
 
1570
                const StyleOptions opts( NoFill );
 
1571
 
 
1572
                QPainter painter( toolBox );
 
1573
                painter.setClipRegion( static_cast<QPaintEvent*>( event )->region() );
 
1574
                renderSlab( &painter, r, toolBox->palette().color( QPalette::Button ), opts );
 
1575
 
 
1576
            }
 
1577
        }
 
1578
 
 
1579
        return false;
 
1580
    }
 
1581
 
 
1582
    //____________________________________________________________________
 
1583
    QRect Style::progressBarContentsRect( const QStyleOption* option, const QWidget* ) const
 
1584
    {
 
1585
        const QRect out( insideMargin( option->rect, ProgressBar_GrooveMargin ) );
 
1586
        const QStyleOptionProgressBarV2 *pbOpt( qstyleoption_cast<const QStyleOptionProgressBarV2 *>( option ) );
 
1587
        if( pbOpt && pbOpt->orientation == Qt::Vertical ) return out.adjusted( 0, 1, 0, -1 );
 
1588
        else return out.adjusted( 1, 0, -1, 0 );
 
1589
    }
 
1590
 
 
1591
    //____________________________________________________________________
 
1592
    QRect Style::tabBarTabButtonRect( SubElement element, const QStyleOption* option, const QWidget* widget ) const
 
1593
    {
 
1594
 
 
1595
        const QStyleOptionTab* tabOpt( qstyleoption_cast<const QStyleOptionTab*>( option ) );
 
1596
        if ( !tabOpt ) return QRect();
 
1597
 
 
1598
        QRect r( QCommonStyle::subElementRect( element, option, widget ) );
 
1599
        const bool selected( option->state&State_Selected );
 
1600
 
 
1601
        switch( tabOpt->shape )
 
1602
        {
 
1603
 
 
1604
            case QTabBar::RoundedNorth:
 
1605
            case QTabBar::TriangularNorth:
 
1606
            r.translate( 0, -1 );
 
1607
            if( selected ) r.translate( 0, -1 );
 
1608
            break;
 
1609
 
 
1610
            case QTabBar::RoundedSouth:
 
1611
            case QTabBar::TriangularSouth:
 
1612
            r.translate( 0, -1 );
 
1613
            if( selected ) r.translate( 0, 1 );
 
1614
            break;
 
1615
 
 
1616
            case QTabBar::RoundedWest:
 
1617
            case QTabBar::TriangularWest:
 
1618
            r.translate( 0, 1 );
 
1619
            if( selected )  r.translate( -1, 0 );
 
1620
            break;
 
1621
 
 
1622
            case QTabBar::RoundedEast:
 
1623
            case QTabBar::TriangularEast:
 
1624
            r.translate( 0, -2 );
 
1625
            if( selected ) r.translate( 1, 0 );
 
1626
            break;
 
1627
 
 
1628
            default: break;
 
1629
 
 
1630
        }
 
1631
        return r;
 
1632
    }
 
1633
 
 
1634
    //____________________________________________________________________
 
1635
    QRect Style::tabWidgetTabContentsRect( const QStyleOption* option, const QWidget* widget ) const
 
1636
    {
 
1637
 
 
1638
        // cast option and check
 
1639
        const QStyleOptionTabWidgetFrame* tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>( option );
 
1640
        if( !tabOpt ) return option->rect;
 
1641
 
 
1642
        // do nothing if tabbar is hidden
 
1643
        if( tabOpt->tabBarSize.isEmpty() ) return option->rect;
 
1644
 
 
1645
        QRect r( option->rect );
 
1646
 
 
1647
 
 
1648
        // include margins
 
1649
        r = tabWidgetTabPaneRect( option, widget );
 
1650
 
 
1651
        // document mode
 
1652
        const bool documentMode( tabOpt->lineWidth == 0 );
 
1653
 
 
1654
        if( !documentMode )
 
1655
        {
 
1656
            r = insideMargin( r, TabWidget_ContentsMargin );
 
1657
            r.translate( 0, -1 );
 
1658
        }
 
1659
 
 
1660
        return r;
 
1661
 
 
1662
    }
 
1663
 
 
1664
    //____________________________________________________________________
 
1665
    QRect Style::tabWidgetTabPaneRect( const QStyleOption* option, const QWidget* ) const
 
1666
    {
 
1667
 
 
1668
 
 
1669
        const QStyleOptionTabWidgetFrame* tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>( option );
 
1670
        if( !tabOpt ) return option->rect;
 
1671
 
 
1672
        QRect r( option->rect );
 
1673
        const bool documentMode( tabOpt->lineWidth == 0 );
 
1674
        int overlap( TabBar_BaseOverlap );
 
1675
        if( documentMode ) overlap -= TabWidget_ContentsMargin;
 
1676
 
 
1677
        switch( tabOpt->shape )
 
1678
        {
 
1679
            case QTabBar::RoundedNorth:
 
1680
            case QTabBar::TriangularNorth:
 
1681
            {
 
1682
                if( documentMode ) overlap++;
 
1683
                r.setTop( r.top() + qMax( tabOpt->tabBarSize.height() - overlap, 0 ) );
 
1684
                break;
 
1685
            }
 
1686
 
 
1687
            case QTabBar::RoundedSouth:
 
1688
            case QTabBar::TriangularSouth:
 
1689
            {
 
1690
                if( documentMode ) overlap--;
 
1691
                r.setBottom( r.bottom() - qMax( tabOpt->tabBarSize.height() - overlap, 0 ) );
 
1692
                break;
 
1693
            }
 
1694
 
 
1695
            case QTabBar::RoundedWest:
 
1696
            case QTabBar::TriangularWest:
 
1697
            {
 
1698
                r.setLeft( r.left() + qMax( tabOpt->tabBarSize.width() - overlap, 0 ) );
 
1699
                break;
 
1700
            }
 
1701
 
 
1702
            case QTabBar::RoundedEast:
 
1703
            case QTabBar::TriangularEast:
 
1704
            {
 
1705
                r.setRight( r.right() - qMax( tabOpt->tabBarSize.width() - overlap, 0 ) );
 
1706
                break;
 
1707
            }
 
1708
 
 
1709
        }
 
1710
 
 
1711
        return r;
 
1712
 
 
1713
    }
 
1714
 
 
1715
    //____________________________________________________________________
 
1716
    QRect Style::tabWidgetLeftCornerRect( const QStyleOption* option, const QWidget* widget ) const
 
1717
    {
 
1718
 
 
1719
        const QStyleOptionTabWidgetFrame *tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>( option );
 
1720
        if( !tabOpt ) return QRect();
 
1721
 
 
1722
        QRect r( option->rect );
 
1723
        const QRect paneRect( subElementRect( SE_TabWidgetTabPane, option, widget ) );
 
1724
 
 
1725
        const QTabWidget* tabWidget( qobject_cast<const QTabWidget*>( widget ) );
 
1726
        const bool documentMode( tabWidget ? tabWidget->documentMode() : false );
 
1727
 
 
1728
        const QSize& size( tabOpt->leftCornerWidgetSize );
 
1729
        const int h( size.height() );
 
1730
        const int w( size.width() );
 
1731
 
 
1732
        switch( tabOpt->shape )
 
1733
        {
 
1734
            case QTabBar::RoundedNorth:
 
1735
            case QTabBar::TriangularNorth:
 
1736
            r = QRect( QPoint( paneRect.x(), paneRect.y() - h ), size );
 
1737
            r = visualRect( tabOpt->direction, tabOpt->rect, r );
 
1738
            if( !documentMode ) r.translate( 0, 3 );
 
1739
            break;
 
1740
 
 
1741
            case QTabBar::RoundedSouth:
 
1742
            case QTabBar::TriangularSouth:
 
1743
            r = QRect( QPoint( paneRect.x(), paneRect.height() ), size );
 
1744
            r = visualRect( tabOpt->direction, tabOpt->rect, r );
 
1745
            if( !documentMode ) r.translate( 0, -3 );
 
1746
            else r.translate( 0, 2 );
 
1747
            break;
 
1748
 
 
1749
            case QTabBar::RoundedWest:
 
1750
            case QTabBar::TriangularWest:
 
1751
            r = QRect( QPoint( paneRect.x() - w, paneRect.y() ), size );
 
1752
            r = visualRect( tabOpt->direction, tabOpt->rect, r );
 
1753
            if( !documentMode ) r.translate( 2, 0 );
 
1754
            else r.translate( -2, 0 );
 
1755
            break;
 
1756
 
 
1757
            case QTabBar::RoundedEast:
 
1758
            case QTabBar::TriangularEast:
 
1759
            r = QRect( QPoint( paneRect.x() + paneRect.width(), paneRect.y() ), size );
 
1760
            r = visualRect( tabOpt->direction, tabOpt->rect, r );
 
1761
            if( !documentMode ) r.translate( -2, 0 );
 
1762
            else r.translate( 2, 0 );
 
1763
            break;
 
1764
 
 
1765
            default:
 
1766
            break;
 
1767
        }
 
1768
 
 
1769
        return r;
 
1770
 
 
1771
    }
 
1772
 
 
1773
    //____________________________________________________________________
 
1774
    QRect Style::tabWidgetRightCornerRect( const QStyleOption* option, const QWidget* widget ) const
 
1775
    {
 
1776
 
 
1777
        const QStyleOptionTabWidgetFrame *tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>( option );
 
1778
        if( !tabOpt ) return QRect();
 
1779
 
 
1780
        QRect r( option->rect );
 
1781
        const QRect paneRect( subElementRect( SE_TabWidgetTabPane, option, widget ) );
 
1782
 
 
1783
        const QTabWidget* tabWidget( qobject_cast<const QTabWidget*>( widget ) );
 
1784
        const bool documentMode( tabWidget ? tabWidget->documentMode() : false );
 
1785
 
 
1786
        const QSize& size( tabOpt->rightCornerWidgetSize );
 
1787
        const int h( size.height() );
 
1788
        const int w( size.width() );
 
1789
 
 
1790
        switch( tabOpt->shape )
 
1791
        {
 
1792
            case QTabBar::RoundedNorth:
 
1793
            case QTabBar::TriangularNorth:
 
1794
            r = QRect( QPoint( paneRect.right() - w + 1, paneRect.y() - h ), size );
 
1795
            r = visualRect( tabOpt->direction, tabOpt->rect, r );
 
1796
            if( !documentMode ) r.translate( 0, 3 );
 
1797
            break;
 
1798
 
 
1799
            case QTabBar::RoundedSouth:
 
1800
            case QTabBar::TriangularSouth:
 
1801
            r = QRect( QPoint( paneRect.right() - w + 1, paneRect.height() ), size );
 
1802
            r = visualRect( tabOpt->direction, tabOpt->rect, r );
 
1803
            if( !documentMode ) r.translate( 0, -3 );
 
1804
            else r.translate( 0, 2 );
 
1805
            break;
 
1806
 
 
1807
            case QTabBar::RoundedWest:
 
1808
            case QTabBar::TriangularWest:
 
1809
            r = QRect( QPoint( paneRect.x() - w, paneRect.bottom() - h + 1 ), size );
 
1810
            r = visualRect( tabOpt->direction, tabOpt->rect, r );
 
1811
            if( !documentMode ) r.translate( 2, 0 );
 
1812
            else r.translate( -2, 0 );
 
1813
            break;
 
1814
 
 
1815
            case QTabBar::RoundedEast:
 
1816
            case QTabBar::TriangularEast:
 
1817
            r = QRect( QPoint( paneRect.x() + paneRect.width(), paneRect.bottom() - h + 1 ), size );
 
1818
            r = visualRect( tabOpt->direction, tabOpt->rect, r );
 
1819
            if( !documentMode ) r.translate( -2, 0 );
 
1820
            else r.translate( 2, 0 );
 
1821
            break;
 
1822
 
 
1823
            default:
 
1824
            break;
 
1825
        }
 
1826
 
 
1827
        return r;
 
1828
 
 
1829
    }
 
1830
 
 
1831
    //______________________________________________________________
 
1832
    QRect Style::groupBoxSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const
 
1833
    {
 
1834
 
 
1835
        QRect r = option->rect;
 
1836
 
 
1837
        //
 
1838
        switch ( subControl )
 
1839
        {
 
1840
 
 
1841
            case SC_GroupBoxFrame: return r.adjusted( -1, -2, 1, 0 );
 
1842
 
 
1843
            case SC_GroupBoxContents:
 
1844
            {
 
1845
 
 
1846
                // cast option and check
 
1847
                const QStyleOptionGroupBox *gbOpt = qstyleoption_cast<const QStyleOptionGroupBox *>( option );
 
1848
                if( !gbOpt ) break;
 
1849
 
 
1850
                const bool isFlat( gbOpt->features & QStyleOptionFrameV2::Flat );
 
1851
                const int th( gbOpt->fontMetrics.height() + 8 );
 
1852
                const QRect cr( subElementRect( SE_CheckBoxIndicator, option, widget ) );
 
1853
                const int fw( pixelMetric( PM_DefaultFrameWidth, option, widget ) );
 
1854
                const bool checkable( gbOpt->subControls & QStyle::SC_GroupBoxCheckBox );
 
1855
                const bool emptyText( gbOpt->text.isEmpty() );
 
1856
 
 
1857
                r.adjust( fw, fw, -fw, -fw );
 
1858
                if( checkable && !emptyText ) r.adjust( 0, qMax( th, cr.height() ), 0, 0 );
 
1859
                else if( checkable ) r.adjust( 0, cr.height(), 0, 0 );
 
1860
                else if( !emptyText ) r.adjust( 0, th, 0, 0 );
 
1861
 
 
1862
                // add additional indentation to flat group boxes
 
1863
                if( isFlat )
 
1864
                {
 
1865
                    const int leftMarginExtension( 16 );
 
1866
                    r = visualRect( option->direction, r, r.adjusted( leftMarginExtension,0,0,0 ) );
 
1867
                }
 
1868
 
 
1869
                return r;
 
1870
            }
 
1871
 
 
1872
            case SC_GroupBoxCheckBox:
 
1873
            case SC_GroupBoxLabel:
 
1874
            {
 
1875
                // cast option and check
 
1876
                const QStyleOptionGroupBox *gbOpt = qstyleoption_cast<const QStyleOptionGroupBox *>( option );
 
1877
                if( !gbOpt ) break;
 
1878
 
 
1879
                const bool isFlat( gbOpt->features & QStyleOptionFrameV2::Flat );
 
1880
                QFont font = widget->font();
 
1881
 
 
1882
                // calculate text width assuming bold text in flat group boxes
 
1883
                if( isFlat ) font.setBold( true );
 
1884
 
 
1885
                QFontMetrics fontMetrics = QFontMetrics( font );
 
1886
                const int h( fontMetrics.height() );
 
1887
                const int tw( fontMetrics.size( Qt::TextShowMnemonic, gbOpt->text + QLatin1String( "  " ) ).width() );
 
1888
                r.setHeight( h );
 
1889
 
 
1890
                // translate down by 6 pixels in non flat mode,
 
1891
                // to avoid collision with groupbox frame
 
1892
                if( !isFlat ) r.moveTop( 6 );
 
1893
 
 
1894
                QRect cr;
 
1895
                if( gbOpt->subControls & QStyle::SC_GroupBoxCheckBox )
 
1896
                {
 
1897
                    cr = subElementRect( SE_CheckBoxIndicator, option, widget );
 
1898
                    QRect gcr( ( gbOpt->rect.width() - tw -cr.width() )/2 , ( h-cr.height() )/2+r.y(), cr.width(), cr.height() );
 
1899
                    if( subControl == SC_GroupBoxCheckBox )
 
1900
                    {
 
1901
                        if( !isFlat ) return visualRect( option->direction, option->rect, gcr );
 
1902
                        else return visualRect( option->direction, option->rect, QRect( 0,0,cr.width(),cr.height() ) );
 
1903
                    }
 
1904
                }
 
1905
 
 
1906
                // left align labels in flat group boxes, center align labels in framed group boxes
 
1907
                if( isFlat ) r = QRect( cr.width(),r.y(),tw,r.height() );
 
1908
                else r = QRect( ( gbOpt->rect.width() - tw - cr.width() )/2 + cr.width(), r.y(), tw, r.height() );
 
1909
 
 
1910
                return visualRect( option->direction, option->rect, r );
 
1911
            }
 
1912
 
 
1913
            default: break;
 
1914
 
 
1915
        }
 
1916
 
 
1917
        return QCommonStyle::subControlRect( CC_GroupBox, option, subControl, widget );
 
1918
    }
 
1919
 
 
1920
    //___________________________________________________________________________________________________________________
 
1921
    QRect Style::comboBoxSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const
 
1922
    {
 
1923
 
 
1924
        const QRect& r( option->rect );
 
1925
        const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>( option );
 
1926
        if( !cb ) return QCommonStyle::subControlRect( CC_ComboBox, option, subControl, widget );
 
1927
 
 
1928
        switch( subControl )
 
1929
        {
 
1930
            case SC_ComboBoxFrame:
 
1931
            { return cb->frame ? r : QRect(); }
 
1932
 
 
1933
            case SC_ComboBoxListBoxPopup:
 
1934
            { return r.adjusted( 1,0,-1,0 ); }
 
1935
 
 
1936
            case SC_ComboBoxArrow:
 
1937
            case SC_ComboBoxEditField:
 
1938
            {
 
1939
                // frame width
 
1940
                int fw = ComboBox_FrameWidth;
 
1941
 
 
1942
                // button width
 
1943
                int bw = ComboBox_ButtonWidth;
 
1944
 
 
1945
                // button margin
 
1946
                int bm = ComboBox_ButtonMargin;
 
1947
                int bml = bm + ComboBox_ButtonMargin_Left;
 
1948
                int bmr = bm + ComboBox_ButtonMargin_Right;
 
1949
                int bmt = bm + ComboBox_ButtonMargin_Top;
 
1950
                int bmb = bm + ComboBox_ButtonMargin_Bottom;
 
1951
 
 
1952
                // ComboBox without a frame, set the corresponding layout values to 0, reduce button width.
 
1953
                if( !cb->frame )
 
1954
                {
 
1955
                    bw = bw - bmr; // reduce button with as the right button margin will be ignored.
 
1956
                    fw = 0;
 
1957
 
 
1958
                    // TODO: why is bml not also set to 0
 
1959
                    bmt = bmb = 0;
 
1960
                }
 
1961
 
 
1962
                if( subControl == SC_ComboBoxArrow )
 
1963
                {
 
1964
 
 
1965
                    return
 
1966
                        handleRTL( option,
 
1967
                        QRect( r.right()-bw+bml+1, r.top()+bmt, bw-bml-bmr, r.height()-bmt-bmb ) );
 
1968
 
 
1969
                } else {
 
1970
 
 
1971
                    QRect labelRect( r.left()+fw, r.top()+fw, r.width()-fw-bw, r.height()-2*fw );
 
1972
                    labelRect = insideMargin( labelRect,
 
1973
                        ComboBox_ContentsMargin,
 
1974
                        ComboBox_ContentsMargin_Left,
 
1975
                        ComboBox_ContentsMargin_Top,
 
1976
                        ComboBox_ContentsMargin_Right,
 
1977
                        ComboBox_ContentsMargin_Bottom );
 
1978
                    return handleRTL( option, labelRect );
 
1979
 
 
1980
                }
 
1981
 
 
1982
            }
 
1983
 
 
1984
            default: break;
 
1985
 
 
1986
        }
 
1987
 
 
1988
        return QCommonStyle::subControlRect( CC_ComboBox, option, subControl, widget );
 
1989
 
 
1990
    }
 
1991
 
 
1992
    //___________________________________________________________________________________________________________________
 
1993
    QRect Style::scrollBarInternalSubControlRect( const QStyleOptionComplex* option, SubControl subControl ) const
 
1994
    {
 
1995
 
 
1996
        const QRect& r = option->rect;
 
1997
        const State& flags( option->state );
 
1998
        const bool horizontal( flags&State_Horizontal );
 
1999
 
 
2000
        switch ( subControl )
 
2001
        {
 
2002
 
 
2003
            case SC_ScrollBarSubLine:
 
2004
            {
 
2005
                int majorSize( scrollBarButtonHeight( _subLineButtons ) );
 
2006
                if( horizontal ) return handleRTL( option, QRect( r.x(), r.y(), majorSize, r.height() ) );
 
2007
                else return handleRTL( option, QRect( r.x(), r.y(), r.width(), majorSize ) );
 
2008
 
 
2009
            }
 
2010
 
 
2011
            case SC_ScrollBarAddLine:
 
2012
            {
 
2013
                int majorSize( scrollBarButtonHeight( _addLineButtons ) );
 
2014
                if( horizontal ) return handleRTL( option, QRect( r.right() - majorSize, r.y(), majorSize, r.height() ) );
 
2015
                else return handleRTL( option, QRect( r.x(), r.bottom() - majorSize, r.width(), majorSize ) );
 
2016
            }
 
2017
 
 
2018
            default: return QRect();
 
2019
 
 
2020
        }
 
2021
    }
 
2022
 
 
2023
    //___________________________________________________________________________________________________________________
 
2024
    QRect Style::sliderSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const
 
2025
    {
 
2026
        switch( subControl )
 
2027
        {
 
2028
            case SC_SliderHandle:
 
2029
            return QCommonStyle::subControlRect( CC_Slider, option, subControl, widget );
 
2030
 
 
2031
            case SC_SliderGroove:
 
2032
            {
 
2033
                QRect groove( QCommonStyle::subControlRect( CC_Slider, option, subControl, widget ) );
 
2034
                if( const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>( option ) )
 
2035
                {
 
2036
                    const bool horizontal( slider->orientation == Qt::Horizontal );
 
2037
                    if( horizontal )
 
2038
                    {
 
2039
 
 
2040
                        const int center( groove.center().y() );
 
2041
                        groove = QRect( groove.left(), center-Slider_GrooveWidth/2, groove.width(), Slider_GrooveWidth  ).adjusted( 3, 0, -3, 0 );
 
2042
                        groove.adjust( 2, 1, -2, 0 );
 
2043
 
 
2044
                    } else {
 
2045
 
 
2046
                        const int center( groove.center().x() );
 
2047
                        groove = QRect( center-Slider_GrooveWidth/2, groove.top(), Slider_GrooveWidth, groove.height() ).adjusted( 0, 3, 0, -3 );
 
2048
                        groove.adjust( 0, 2, 0, -2 );
 
2049
 
 
2050
                    }
 
2051
 
 
2052
                }
 
2053
 
 
2054
                return groove;
 
2055
 
 
2056
            }
 
2057
 
 
2058
            default:
 
2059
            return QCommonStyle::subControlRect( CC_Slider, option, subControl, widget );
 
2060
 
 
2061
        }
 
2062
 
 
2063
    }
 
2064
 
 
2065
    //___________________________________________________________________________________________________________________
 
2066
    QRect Style::scrollBarSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const
 
2067
    {
 
2068
        const QRect& r = option->rect;
 
2069
        const State& flags( option->state );
 
2070
        const bool horizontal( flags&State_Horizontal );
 
2071
 
 
2072
        switch ( subControl )
 
2073
        {
 
2074
            //For both arrows, we return -everything-,
 
2075
            //to get stuff to repaint right. See scrollBarInternalSubControlRect
 
2076
            //for the real thing
 
2077
            case SC_ScrollBarSubLine:
 
2078
            case SC_ScrollBarAddLine:
 
2079
            if( horizontal ) return r.adjusted( 0, 1, 0, -1 );
 
2080
            else return r.adjusted( 1, 0, -1, 0 );
 
2081
 
 
2082
            //The main groove area. This is used to compute the others...
 
2083
            case SC_ScrollBarGroove:
 
2084
            {
 
2085
                QRect top = handleRTL( option, scrollBarInternalSubControlRect( option, SC_ScrollBarSubLine ) );
 
2086
                QRect bot = handleRTL( option, scrollBarInternalSubControlRect( option, SC_ScrollBarAddLine ) );
 
2087
 
 
2088
                QPoint topLeftCorner;
 
2089
                QPoint botRightCorner;
 
2090
 
 
2091
                if( horizontal )
 
2092
                {
 
2093
 
 
2094
                    topLeftCorner  = QPoint( top.right() + 1, top.top() );
 
2095
                    botRightCorner = QPoint( bot.left()  - 1, top.bottom() );
 
2096
 
 
2097
                } else {
 
2098
                    topLeftCorner  = QPoint( top.left(),  top.bottom() + 1 );
 
2099
                    botRightCorner = QPoint( top.right(), bot.top()    - 1 );
 
2100
                }
 
2101
 
 
2102
                // define rect, and reduce margins
 
2103
                QRect r( topLeftCorner, botRightCorner );
 
2104
                if( horizontal ) r.adjust( 0, 1, 0, -1 );
 
2105
                else r.adjust( 1, 0, -1, 0 );
 
2106
 
 
2107
                return handleRTL( option, r );
 
2108
            }
 
2109
 
 
2110
            case SC_ScrollBarSlider:
 
2111
            {
 
2112
                const QStyleOptionSlider* slOpt = qstyleoption_cast<const QStyleOptionSlider*>( option );
 
2113
                if( !slOpt ) return QRect();
 
2114
 
 
2115
                //We do handleRTL here to unreflect things if need be
 
2116
                QRect groove = handleRTL( option, scrollBarSubControlRect( option, SC_ScrollBarGroove, widget ) );
 
2117
 
 
2118
                if ( slOpt->minimum == slOpt->maximum ) return groove;
 
2119
 
 
2120
                //Figure out how much room we have..
 
2121
                int space( horizontal ? groove.width() : groove.height() );
 
2122
 
 
2123
                //Calculate the portion of this space that the slider should take up.
 
2124
                int sliderSize = space * qreal( slOpt->pageStep ) / ( slOpt->maximum - slOpt->minimum + slOpt->pageStep );
 
2125
                sliderSize = qMax( sliderSize, ( int )ScrollBar_MinimumSliderHeight );
 
2126
                sliderSize = qMin( sliderSize, space );
 
2127
 
 
2128
                space -= sliderSize;
 
2129
                if( space <= 0 ) return groove;
 
2130
 
 
2131
                int pos = qRound( qreal( slOpt->sliderPosition - slOpt->minimum )/ ( slOpt->maximum - slOpt->minimum )*space );
 
2132
                if( slOpt->upsideDown ) pos = space - pos;
 
2133
                if( horizontal ) return handleRTL( option, QRect( groove.x() + pos, groove.y(), sliderSize, groove.height() ) );
 
2134
                else return handleRTL( option, QRect( groove.x(), groove.y() + pos, groove.width(), sliderSize ) );
 
2135
            }
 
2136
 
 
2137
            case SC_ScrollBarSubPage:
 
2138
            {
 
2139
 
 
2140
                //We do handleRTL here to unreflect things if need be
 
2141
                QRect slider = handleRTL( option, scrollBarSubControlRect( option, SC_ScrollBarSlider, widget ) );
 
2142
                QRect groove = handleRTL( option, scrollBarSubControlRect( option, SC_ScrollBarGroove, widget ) );
 
2143
 
 
2144
                if( horizontal ) return handleRTL( option, QRect( groove.x(), groove.y(), slider.x() - groove.x(), groove.height() ) );
 
2145
                else return handleRTL( option, QRect( groove.x(), groove.y(), groove.width(), slider.y() - groove.y() ) );
 
2146
            }
 
2147
 
 
2148
            case SC_ScrollBarAddPage:
 
2149
            {
 
2150
 
 
2151
                //We do handleRTL here to unreflect things if need be
 
2152
                QRect slider = handleRTL( option, scrollBarSubControlRect( option, SC_ScrollBarSlider, widget ) );
 
2153
                QRect groove = handleRTL( option, scrollBarSubControlRect( option, SC_ScrollBarGroove, widget ) );
 
2154
 
 
2155
                if( horizontal ) return handleRTL( option, QRect( slider.right() + 1, groove.y(), groove.right() - slider.right(), groove.height() ) );
 
2156
                else return handleRTL( option, QRect( groove.x(), slider.bottom() + 1, groove.width(), groove.bottom() - slider.bottom() ) );
 
2157
 
 
2158
            }
 
2159
 
 
2160
            default: return QRect();
 
2161
        }
 
2162
    }
 
2163
 
 
2164
    //___________________________________________________________________________________________________________________
 
2165
    QRect Style::spinBoxSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const
 
2166
    {
 
2167
 
 
2168
        const QRect& r( option->rect );
 
2169
        const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>( option );
 
2170
        if( !sb ) return r;
 
2171
 
 
2172
        int fw = SpinBox_FrameWidth;
 
2173
        int bw = SpinBox_ButtonWidth;
 
2174
        int bm = SpinBox_ButtonMargin;
 
2175
        int bml = bm + SpinBox_ButtonMargin_Left;
 
2176
        int bmt = bm + SpinBox_ButtonMargin_Top;
 
2177
        int bmr = bm + SpinBox_ButtonMargin_Right;
 
2178
        int bmb = bm + SpinBox_ButtonMargin_Bottom;
 
2179
        int bs = 0 ;
 
2180
 
 
2181
        if( !sb->frame )
 
2182
        {
 
2183
            bw = bw - bmr;
 
2184
            fw = 0;
 
2185
 
 
2186
            // TODO: why is bml not also set to 0
 
2187
            bmt = bmb = bmr = 0;
 
2188
        }
 
2189
 
 
2190
        const int buttonsWidth = bw-bml-bmr;
 
2191
        const int buttonsLeft = r.right()-bw+bml+1;
 
2192
 
 
2193
        // compute the height of each button...
 
2194
        const int availableButtonHeight = r.height()-bmt-bmb - bs;
 
2195
        const int heightUp = availableButtonHeight / 2;
 
2196
        const int heightDown = availableButtonHeight - heightUp;
 
2197
 
 
2198
        switch ( subControl )
 
2199
        {
 
2200
 
 
2201
            case SC_SpinBoxUp:
 
2202
            return handleRTL( option, QRect( buttonsLeft, r.top()+bmt, buttonsWidth, heightUp ) );
 
2203
 
 
2204
            case SC_SpinBoxDown:
 
2205
            return handleRTL( option, QRect( buttonsLeft, r.bottom()-bmb-heightDown, buttonsWidth, heightDown ) );
 
2206
 
 
2207
            case SC_SpinBoxEditField:
 
2208
            {
 
2209
                const QRect labelRect( r.left()+fw, r.top()+fw, r.width()-fw-bw, r.height()-2*fw );
 
2210
                return handleRTL( option, labelRect );
 
2211
            }
 
2212
 
 
2213
            case SC_SpinBoxFrame:
 
2214
            return sb->frame ? r : QRect();
 
2215
 
 
2216
            default:
 
2217
            break;
 
2218
 
 
2219
        }
 
2220
 
 
2221
        return QCommonStyle::subControlRect( CC_SpinBox, option, subControl, widget );
 
2222
 
 
2223
   }
 
2224
 
 
2225
    //______________________________________________________________
 
2226
    QSize Style::checkBoxSizeFromContents( const QStyleOption*, const QSize& contentsSize, const QWidget* ) const
 
2227
    {
 
2228
 
 
2229
        //Add size for indicator
 
2230
        const int indicator( CheckBox_Size );
 
2231
 
 
2232
        //Make sure we can fit the indicator
 
2233
        QSize size( contentsSize );
 
2234
        size.setHeight( qMax( size.height(), indicator ) );
 
2235
 
 
2236
        //Add space for the indicator and the icon
 
2237
        const int spacer( CheckBox_BoxTextSpace );
 
2238
        size.rwidth() += indicator + spacer;
 
2239
 
 
2240
        return size;
 
2241
 
 
2242
    }
 
2243
 
 
2244
    //______________________________________________________________
 
2245
    QSize Style::comboBoxSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const
 
2246
    {
 
2247
 
 
2248
        QSize size = expandSize( contentsSize,
 
2249
            ComboBox_ContentsMargin,
 
2250
            ComboBox_ContentsMargin_Left,
 
2251
            ComboBox_ContentsMargin_Top,
 
2252
            ComboBox_ContentsMargin_Right,
 
2253
            ComboBox_ContentsMargin_Bottom );
 
2254
 
 
2255
        // add frame width
 
2256
        size = expandSize( size, ComboBox_FrameWidth );
 
2257
 
 
2258
        // Add the button width
 
2259
        size.rwidth() += ComboBox_ButtonWidth;
 
2260
 
 
2261
        // TODO: For some reason the size is not right in the following configurations
 
2262
        // this is still to be understood and might reveal some deeper issue.
 
2263
        // notably, should compare to zhqt is done for PushButtons
 
2264
        const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>( option );
 
2265
        if( cb && !cb->editable && ( !cb->currentIcon.isNull() || cb->fontMetrics.height() > 13 ) ) size.rheight()+=1;
 
2266
 
 
2267
        // also expand to account for scrollbar
 
2268
        size.rwidth() += StyleConfigData::scrollBarWidth() - 6;
 
2269
        return size;
 
2270
 
 
2271
    }
 
2272
 
 
2273
    //______________________________________________________________
 
2274
    QSize Style::headerSectionSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const
 
2275
    {
 
2276
 
 
2277
        const QStyleOptionHeader* headerOpt( qstyleoption_cast<const QStyleOptionHeader *>( option ) );
 
2278
        if( !headerOpt ) return contentsSize;
 
2279
 
 
2280
        //TODO: check if hardcoded icon size is the right thing to do
 
2281
        QSize iconSize = headerOpt->icon.isNull() ? QSize( 0,0 ) : QSize( 22,22 );
 
2282
        QSize textSize = headerOpt->fontMetrics.size( 0, headerOpt->text );
 
2283
 
 
2284
        int iconSpacing = Header_TextToIconSpace;
 
2285
        int w = iconSize.width() + iconSpacing + textSize.width();
 
2286
        int h = qMax( iconSize.height(), textSize.height() );
 
2287
 
 
2288
        return expandSize( QSize( w, h ), Header_ContentsMargin );
 
2289
 
 
2290
    }
 
2291
 
 
2292
    //______________________________________________________________
 
2293
    QSize Style::menuItemSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* widget ) const
 
2294
    {
 
2295
        const QStyleOptionMenuItem* menuItemOption = qstyleoption_cast<const QStyleOptionMenuItem*>( option );
 
2296
        if( !menuItemOption ) return contentsSize;
 
2297
 
 
2298
        // First, we calculate the intrinsic size of the item.
 
2299
        // this must be kept consistent with what's in drawMenuItemContol
 
2300
        QSize insideSize;
 
2301
 
 
2302
        switch ( menuItemOption->menuItemType )
 
2303
        {
 
2304
            case QStyleOptionMenuItem::Normal:
 
2305
            case QStyleOptionMenuItem::DefaultItem:
 
2306
            case QStyleOptionMenuItem::SubMenu:
 
2307
            {
 
2308
                int iconColW = qMax( menuItemOption->maxIconWidth, ( int ) MenuItem_IconWidth );
 
2309
                int leftColW = iconColW;
 
2310
                if( menuItemOption->menuHasCheckableItems )
 
2311
                { leftColW += MenuItem_CheckWidth + MenuItem_CheckSpace; }
 
2312
 
 
2313
                leftColW += MenuItem_IconSpace;
 
2314
 
 
2315
                int rightColW = MenuItem_ArrowSpace + MenuItem_ArrowWidth;
 
2316
 
 
2317
                QFontMetrics fm( menuItemOption->font );
 
2318
                int textW;
 
2319
                int tabPos = menuItemOption->text.indexOf( QLatin1Char( '\t' ) );
 
2320
                if( tabPos == -1 ) textW = contentsSize.width();
 
2321
                else {
 
2322
 
 
2323
                    // The width of the accelerator is not included here since
 
2324
                    // Qt will add that on separately after obtaining the
 
2325
                    // sizeFromContents() for each menu item in the menu to be shown
 
2326
                    // ( see QMenuPrivate::calcActionRects() )
 
2327
                    textW = contentsSize.width() + MenuItem_AccelSpace;
 
2328
 
 
2329
                }
 
2330
 
 
2331
                int h = qMax( contentsSize.height(), ( int ) MenuItem_MinHeight );
 
2332
                insideSize = QSize( leftColW + textW + rightColW, h );
 
2333
                break;
 
2334
            }
 
2335
 
 
2336
            case QStyleOptionMenuItem::Separator:
 
2337
            {
 
2338
 
 
2339
                // separator can have a title and an icon
 
2340
                // in that case they are rendered as menubar 'title', which
 
2341
                // corresponds to checked toolbuttons.
 
2342
                // a rectangle identical to the one of normal items is returned.
 
2343
                if( !( menuItemOption->text.isEmpty() && menuItemOption->icon.isNull() ) )
 
2344
                {
 
2345
 
 
2346
                    QStyleOptionMenuItem local( *menuItemOption );
 
2347
                    local.menuItemType = QStyleOptionMenuItem::Normal;
 
2348
                    return menuItemSizeFromContents( &local, contentsSize, widget );
 
2349
 
 
2350
                } else {
 
2351
 
 
2352
                    insideSize = QSize( 10, 0 );
 
2353
                    break;
 
2354
 
 
2355
                }
 
2356
 
 
2357
            }
 
2358
 
 
2359
            case QStyleOptionMenuItem::Scroller:
 
2360
            case QStyleOptionMenuItem::TearOff:
 
2361
            case QStyleOptionMenuItem::Margin:
 
2362
            case QStyleOptionMenuItem::EmptyArea:
 
2363
            return contentsSize;
 
2364
        }
 
2365
 
 
2366
        // apply the outermost margin.
 
2367
        return expandSize( insideSize, MenuItem_Margin );
 
2368
 
 
2369
    }
 
2370
 
 
2371
    //______________________________________________________________
 
2372
    QSize Style::pushButtonSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const
 
2373
    {
 
2374
 
 
2375
        const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>( option );
 
2376
        if( !bOpt ) return contentsSize;
 
2377
 
 
2378
        // adjust to handle button margins
 
2379
        QSize size = expandSize( contentsSize,
 
2380
            PushButton_ContentsMargin,
 
2381
            PushButton_ContentsMargin_Left,
 
2382
            PushButton_ContentsMargin_Top,
 
2383
            PushButton_ContentsMargin_Right,
 
2384
            PushButton_ContentsMargin_Bottom );
 
2385
 
 
2386
        if( bOpt->features & QStyleOptionButton::HasMenu )
 
2387
        { size.rwidth() += PushButton_TextToIconSpace; }
 
2388
 
 
2389
        if( !bOpt->text.isEmpty() && !bOpt->icon.isNull() )
 
2390
        {
 
2391
 
 
2392
            // Incorporate the spacing between the icon and text. Qt sticks 4 there,
 
2393
            // but we use PushButton::TextToIconSpace.
 
2394
            size.rwidth() += PushButton_TextToIconSpace -4;
 
2395
        }
 
2396
 
 
2397
        return size;
 
2398
 
 
2399
    }
 
2400
 
 
2401
    //______________________________________________________________
 
2402
    QSize Style::tabBarTabSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* widget ) const
 
2403
    {
 
2404
 
 
2405
        const QStyleOptionTab *tabOpt( qstyleoption_cast<const QStyleOptionTab*>( option ) );
 
2406
 
 
2407
        QSize size;
 
2408
        const bool verticalTabs( tabOpt && isVerticalTab( tabOpt ) );
 
2409
        if( verticalTabs )
 
2410
        {
 
2411
 
 
2412
            size = expandSize( contentsSize,
 
2413
                TabBar_TabContentsMargin,
 
2414
                TabBar_TabContentsMargin_Top,
 
2415
                TabBar_TabContentsMargin_Right,
 
2416
                TabBar_TabContentsMargin_Bottom,
 
2417
                TabBar_TabContentsMargin_Left );
 
2418
 
 
2419
        } else {
 
2420
 
 
2421
            size = expandSize( contentsSize,
 
2422
                TabBar_TabContentsMargin,
 
2423
                TabBar_TabContentsMargin_Left,
 
2424
                TabBar_TabContentsMargin_Top,
 
2425
                TabBar_TabContentsMargin_Right,
 
2426
                TabBar_TabContentsMargin_Bottom );
 
2427
 
 
2428
        }
 
2429
 
 
2430
        // need to add extra size to match corner buttons
 
2431
        // try cast parent for tabWidget
 
2432
        const QTabWidget* tabWidget( widget ? qobject_cast<const QTabWidget*>( widget->parent() ):0 );
 
2433
        if( !tabWidget ) return size;
 
2434
 
 
2435
        // try get corner widgets
 
2436
        const QWidget* leftWidget( tabWidget->cornerWidget( Qt::TopLeftCorner ) );
 
2437
        const QWidget* rightWidget( tabWidget->cornerWidget( Qt::TopRightCorner ) );
 
2438
        QSize cornerSize;
 
2439
        if( leftWidget && leftWidget->isVisible() ) cornerSize = leftWidget->minimumSizeHint();
 
2440
        if( rightWidget && rightWidget->isVisible() ) cornerSize = cornerSize.expandedTo( rightWidget->minimumSizeHint() );
 
2441
        if( !cornerSize.isValid() ) return size;
 
2442
 
 
2443
        // expand size
 
2444
        // note: the extra pixels added to the relevant dimension are fine-tuned.
 
2445
        if( verticalTabs ) size.setWidth( qMax( size.width(), cornerSize.width() + 6 ) );
 
2446
        else size.setHeight( qMax( size.height(), cornerSize.height() + 4 ) );
 
2447
 
 
2448
        return size;
 
2449
 
 
2450
    }
 
2451
 
 
2452
    //______________________________________________________________
 
2453
    QSize Style::toolButtonSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* widget ) const
 
2454
    {
 
2455
 
 
2456
        QSize size = contentsSize;
 
2457
        const QStyleOptionToolButton* tbOpt = qstyleoption_cast<const QStyleOptionToolButton*>( option );
 
2458
        if( tbOpt && !tbOpt->icon.isNull() && !tbOpt->text.isEmpty() && tbOpt->toolButtonStyle == Qt::ToolButtonTextUnderIcon )
 
2459
        { size.rheight() -= 5; }
 
2460
 
 
2461
        // We want to avoid super-skiny buttons, for things like "up" when icons + text
 
2462
        // For this, we would like to make width >= height.
 
2463
        // However, once we get here, QToolButton may have already put in the menu area
 
2464
        // ( PM_MenuButtonIndicator ) into the width. So we may have to take it out, fix things
 
2465
        // up, and add it back in. So much for class-independent rendering...
 
2466
        int menuAreaWidth = 0;
 
2467
        if( tbOpt )
 
2468
        {
 
2469
 
 
2470
            if( tbOpt->features & QStyleOptionToolButton::MenuButtonPopup )
 
2471
            {
 
2472
 
 
2473
                menuAreaWidth = pixelMetric( QStyle::PM_MenuButtonIndicator, option, widget );
 
2474
 
 
2475
            } else if( tbOpt->features & QStyleOptionToolButton::HasMenu ) {
 
2476
 
 
2477
                // TODO: something wrong here: The size is not properly accounted for
 
2478
                // when drawing the slab.
 
2479
                size.rwidth() += ToolButton_InlineMenuIndicatorSize;
 
2480
 
 
2481
            }
 
2482
 
 
2483
        }
 
2484
 
 
2485
        size.rwidth() -= menuAreaWidth;
 
2486
        if( size.width() < size.height() ) size.setWidth( size.height() );
 
2487
 
 
2488
        size.rwidth() += menuAreaWidth;
 
2489
 
 
2490
        const QToolButton* t( qobject_cast<const QToolButton*>( widget ) );
 
2491
        if( t && t->autoRaise() ) return expandSize( size, ToolButton_ContentsMargin ); // these are toolbutton margins
 
2492
        else return expandSize( size,
 
2493
            PushButton_ContentsMargin, 0,
 
2494
            PushButton_ContentsMargin_Top, 0,
 
2495
            PushButton_ContentsMargin_Bottom );
 
2496
 
 
2497
    }
 
2498
 
 
2499
    //___________________________________________________________________________________
 
2500
    bool Style::drawFramePrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
2501
    {
 
2502
        const State& flags( option->state );
 
2503
        const QRect& r( option->rect );
 
2504
        const QPalette& palette( option->palette );
 
2505
 
 
2506
        const bool enabled( flags & State_Enabled );
 
2507
        const bool isInputWidget( widget && widget->testAttribute( Qt::WA_Hover ) );
 
2508
        const bool hoverHighlight( enabled && isInputWidget && ( flags&State_MouseOver ) );
 
2509
 
 
2510
 
 
2511
        //const bool focusHighlight( enabled && isInputWidget && ( flags&State_HasFocus ) );
 
2512
        bool focusHighlight( false );
 
2513
        if( enabled && isInputWidget && ( flags&State_HasFocus ) ) focusHighlight = true;
 
2514
        else if( isKTextEditFrame( widget ) && widget->parentWidget()->hasFocus() )
 
2515
        { focusHighlight = true; }
 
2516
 
 
2517
        // assume focus takes precedence over hover
 
2518
        animations().lineEditEngine().updateState( widget, AnimationFocus, focusHighlight );
 
2519
        animations().lineEditEngine().updateState( widget, AnimationHover, hoverHighlight && !focusHighlight );
 
2520
 
 
2521
        if( flags & State_Sunken )
 
2522
        {
 
2523
            const QRect local( r.adjusted( 1, 1, -1, -1 ) );
 
2524
            qreal opacity( -1 );
 
2525
            AnimationMode mode = AnimationNone;
 
2526
            if( enabled && animations().lineEditEngine().isAnimated( widget, AnimationFocus ) )
 
2527
            {
 
2528
 
 
2529
                opacity = animations().lineEditEngine().opacity( widget, AnimationFocus  );
 
2530
                mode = AnimationFocus;
 
2531
 
 
2532
            } else if( enabled && animations().lineEditEngine().isAnimated( widget, AnimationHover ) ) {
 
2533
 
 
2534
                opacity = animations().lineEditEngine().opacity( widget, AnimationHover );
 
2535
                mode = AnimationHover;
 
2536
 
 
2537
            }
 
2538
 
 
2539
            if( frameShadowFactory().isRegistered( widget ) )
 
2540
            {
 
2541
 
 
2542
                frameShadowFactory().updateState( widget, focusHighlight, hoverHighlight, opacity, mode );
 
2543
 
 
2544
            } else {
 
2545
 
 
2546
                HoleOptions options( 0 );
 
2547
                if( focusHighlight ) options |= HoleFocus;
 
2548
                if( hoverHighlight ) options |= HoleHover;
 
2549
 
 
2550
                helper().renderHole(
 
2551
                    painter, palette.color( QPalette::Window ), local, options,
 
2552
                    opacity, mode, TileSet::Ring );
 
2553
 
 
2554
            }
 
2555
 
 
2556
        } else if( flags & State_Raised ) {
 
2557
 
 
2558
            const QRect local( r.adjusted( -1, -1, 1, 1 ) );
 
2559
            renderSlab( painter, local, palette.color( QPalette::Background ), NoFill );
 
2560
 
 
2561
        }
 
2562
 
 
2563
        return true;
 
2564
    }
 
2565
 
 
2566
    //___________________________________________________________________________________
 
2567
    bool Style::drawFrameFocusRectPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
2568
    {
 
2569
 
 
2570
        if( !widget ) return true;
 
2571
 
 
2572
        // focus indicators are painted only in Q3ListView and QAbstractItemView
 
2573
        if( !( qobject_cast<const QAbstractItemView*>( widget ) || widget->inherits( "Q3ListView" ) ) ) return true;
 
2574
 
 
2575
        const State& flags( option->state );
 
2576
        const QRect r( option->rect.adjusted( 0, 0, 0, -1 ) );
 
2577
        const QPalette& palette( option->palette );
 
2578
 
 
2579
        if( r.width() < 10 ) return true;
 
2580
 
 
2581
        QLinearGradient lg( r.bottomLeft(), r.bottomRight() );
 
2582
 
 
2583
        lg.setColorAt( 0.0, Qt::transparent );
 
2584
        lg.setColorAt( 1.0, Qt::transparent );
 
2585
        if( flags & State_Selected )
 
2586
        {
 
2587
 
 
2588
            lg.setColorAt( 0.2, palette.color( QPalette::BrightText ) );
 
2589
            lg.setColorAt( 0.8, palette.color( QPalette::BrightText ) );
 
2590
 
 
2591
        } else {
 
2592
 
 
2593
            lg.setColorAt( 0.2, palette.color( QPalette::Text ) );
 
2594
            lg.setColorAt( 0.8, palette.color( QPalette::Text ) );
 
2595
 
 
2596
        }
 
2597
 
 
2598
        painter->setRenderHint( QPainter::Antialiasing, false );
 
2599
        painter->setPen( QPen( lg, 1 ) );
 
2600
        painter->drawLine( r.bottomLeft(), r.bottomRight() );
 
2601
 
 
2602
        return true;
 
2603
 
 
2604
    }
 
2605
 
 
2606
    //______________________________________________________________
 
2607
    bool Style::drawFrameGroupBoxPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
2608
    {
 
2609
 
 
2610
        // cast option and check
 
2611
        const QStyleOptionFrame *fOpt = qstyleoption_cast<const QStyleOptionFrame *>( option );
 
2612
        if( !fOpt ) return true;
 
2613
 
 
2614
        // no frame for flat groupboxes
 
2615
        QStyleOptionFrameV2 fOpt2( *fOpt );
 
2616
        if( fOpt2.features & QStyleOptionFrameV2::Flat ) return true;
 
2617
 
 
2618
        // normal frame
 
2619
        const QPalette& palette( option->palette );
 
2620
        const QRect& r( option->rect );
 
2621
        const QColor base( helper().backgroundColor( palette.color( QPalette::Window ), widget, r.center() ) );
 
2622
 
 
2623
        painter->save();
 
2624
        painter->setRenderHint( QPainter::Antialiasing );
 
2625
        painter->setPen( Qt::NoPen );
 
2626
 
 
2627
        QLinearGradient innerGradient( 0, r.top()-r.height()+12, 0, r.bottom()+r.height()-19 );
 
2628
        QColor light( helper().calcLightColor( base ) );
 
2629
        light.setAlphaF( 0.4 ); innerGradient.setColorAt( 0.0, light );
 
2630
        light.setAlphaF( 0.0 ); innerGradient.setColorAt( 1.0, light );
 
2631
        painter->setBrush( innerGradient );
 
2632
        painter->setClipRect( r.adjusted( 0, 0, 0, -19 ) );
 
2633
        helper().fillSlab( *painter, r );
 
2634
 
 
2635
        painter->setClipping( false );
 
2636
        helper().slope( base, 0.0 )->render( r, painter );
 
2637
 
 
2638
        painter->restore();
 
2639
        return true;
 
2640
 
 
2641
    }
 
2642
 
 
2643
    //___________________________________________________________________________________
 
2644
    bool Style::drawFrameMenuPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
2645
    {
 
2646
        // only draw frame for ( expanded ) toolbars
 
2647
        // do nothing for other cases
 
2648
        if( qobject_cast<const QToolBar*>( widget ) )
 
2649
        {
 
2650
            helper().renderWindowBackground( painter, option->rect, widget, option->palette );
 
2651
            helper().drawFloatFrame( painter, option->rect, option->palette.window().color(), true );
 
2652
        }
 
2653
 
 
2654
        return true;
 
2655
 
 
2656
    }
 
2657
 
 
2658
    //___________________________________________________________________________________
 
2659
    bool Style::drawFrameTabBarBasePrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
2660
    {
 
2661
 
 
2662
        // cast option and check
 
2663
        const QStyleOptionTabBarBase* tabOpt( qstyleoption_cast<const QStyleOptionTabBarBase*>( option ) );
 
2664
        if( !tabOpt ) return true;
 
2665
 
 
2666
        if( tabOpt->tabBarRect.isValid() )
 
2667
        {
 
2668
 
 
2669
            // if tabBar rect is valid, all the frame is handled in tabBarTabShapeControl
 
2670
            // nothing to be done here.
 
2671
            // on the other hand, invalid tabBarRect corresponds to buttons in tabbars ( e.g. corner buttons ),
 
2672
            // and the appropriate piece of frame needs to be drawn
 
2673
            return true;
 
2674
 
 
2675
        }
 
2676
 
 
2677
        // store palette and rect
 
2678
        const QPalette& palette( option->palette );
 
2679
        const QRect& r( option->rect );
 
2680
 
 
2681
        QRect frameRect( r );
 
2682
        SlabRect slab;
 
2683
        switch( tabOpt->shape )
 
2684
        {
 
2685
            case QTabBar::RoundedNorth:
 
2686
            case QTabBar::TriangularNorth:
 
2687
            {
 
2688
                frameRect.adjust( -7, -GlowWidth, 7, GlowWidth );
 
2689
                frameRect.translate( 0, 4 );
 
2690
                slab = SlabRect( frameRect, TileSet::Top );
 
2691
                break;
 
2692
            }
 
2693
 
 
2694
            case QTabBar::RoundedSouth:
 
2695
            case QTabBar::TriangularSouth:
 
2696
            {
 
2697
                frameRect.adjust( -7, -GlowWidth, 7, GlowWidth );
 
2698
                frameRect.translate( 0, -4 );
 
2699
                slab = SlabRect( frameRect, TileSet::Bottom );
 
2700
                break;
 
2701
            }
 
2702
 
 
2703
            case QTabBar::RoundedWest:
 
2704
            case QTabBar::TriangularWest:
 
2705
            {
 
2706
                frameRect.adjust( -GlowWidth, -7, GlowWidth, 7 + 1 );
 
2707
                frameRect.translate( 5, 0 );
 
2708
                slab = SlabRect( frameRect, TileSet::Left );
 
2709
                break;
 
2710
            }
 
2711
 
 
2712
            case QTabBar::RoundedEast:
 
2713
            case QTabBar::TriangularEast:
 
2714
            {
 
2715
                frameRect.adjust( -GlowWidth, -7, GlowWidth, 7 + 1 );
 
2716
                frameRect.translate( -5, 0 );
 
2717
                slab = SlabRect( frameRect, TileSet::Right );
 
2718
                break;
 
2719
            }
 
2720
 
 
2721
            default: return true;
 
2722
        }
 
2723
 
 
2724
        // render registered slabs
 
2725
        renderSlab( painter, slab, palette.color( QPalette::Window ), NoFill );
 
2726
 
 
2727
        return true;
 
2728
    }
 
2729
 
 
2730
    //___________________________________________________________________________________
 
2731
    bool Style::drawFrameTabWidgetPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
2732
    {
 
2733
 
 
2734
        // cast option and check
 
2735
        const QStyleOptionTabWidgetFrame* tabOpt( qstyleoption_cast<const QStyleOptionTabWidgetFrame*>( option ) );
 
2736
        if( !tabOpt ) return true;
 
2737
 
 
2738
        const QRect& r( option->rect );
 
2739
        const QPalette& palette( option->palette );
 
2740
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
2741
 
 
2742
        /*
 
2743
        no frame is drawn when tabbar is empty.
 
2744
        this is consistent with the tabWidgetTabContents subelementRect
 
2745
        */
 
2746
        if( tabOpt->tabBarSize.isEmpty() ) return true;
 
2747
 
 
2748
        // get tabbar dimentions
 
2749
        const int w( tabOpt->tabBarSize.width() );
 
2750
        const int h( tabOpt->tabBarSize.height() );
 
2751
 
 
2752
        // left corner widget
 
2753
        const int lw( tabOpt->leftCornerWidgetSize.width() );
 
2754
        const int lh( tabOpt->leftCornerWidgetSize.height() );
 
2755
 
 
2756
        // right corner
 
2757
        const int rw( tabOpt->rightCornerWidgetSize.width() );
 
2758
        const int rh( tabOpt->rightCornerWidgetSize.height() );
 
2759
 
 
2760
        // list of slabs to be drawn
 
2761
        SlabRectList slabs;
 
2762
 
 
2763
        // expand rect by glow width.
 
2764
        QRect baseSlabRect( insideMargin( r, -GlowWidth ) );
 
2765
 
 
2766
        // render the three free sides
 
2767
        switch( tabOpt->shape )
 
2768
        {
 
2769
            case QTabBar::RoundedNorth:
 
2770
            case QTabBar::TriangularNorth:
 
2771
            {
 
2772
                // main slab
 
2773
                slabs << SlabRect( baseSlabRect, ( TileSet::Ring & ~TileSet::Top ) );
 
2774
 
 
2775
                // top
 
2776
                if( reverseLayout )
 
2777
                {
 
2778
 
 
2779
                    // left side
 
2780
                    QRect slabRect( baseSlabRect );
 
2781
                    slabRect.setRight( qMax( slabRect.right() - w - lw, slabRect.left() + rw ) + 7 );
 
2782
                    slabRect.setHeight( 7 );
 
2783
                    slabs << SlabRect( slabRect, TileSet::TopLeft );
 
2784
 
 
2785
                    // right side
 
2786
                    if( rw > 0 )
 
2787
                    {
 
2788
                        QRect slabRect( baseSlabRect );
 
2789
                        slabRect.setLeft( slabRect.right() - rw - 7 );
 
2790
                        slabRect.setHeight( 7 );
 
2791
                        slabs << SlabRect( slabRect, TileSet::TopRight );
 
2792
                    }
 
2793
 
 
2794
                } else {
 
2795
 
 
2796
                    // left side
 
2797
                    if( lw > 0 )
 
2798
                    {
 
2799
 
 
2800
                        QRect slabRect( baseSlabRect );
 
2801
                        slabRect.setRight( baseSlabRect.left() + lw + 7 );
 
2802
                        slabRect.setHeight( 7 );
 
2803
                        slabs << SlabRect( slabRect, TileSet::TopLeft );
 
2804
 
 
2805
                    }
 
2806
 
 
2807
 
 
2808
                    // right side
 
2809
                    QRect slabRect( baseSlabRect );
 
2810
                    slabRect.setLeft( qMin( slabRect.left() + w + lw + 1, slabRect.right() - rw ) -7 );
 
2811
                    slabRect.setHeight( 7 );
 
2812
                    slabs << SlabRect( slabRect, TileSet::TopRight );
 
2813
 
 
2814
                }
 
2815
                break;
 
2816
            }
 
2817
 
 
2818
            case QTabBar::RoundedSouth:
 
2819
            case QTabBar::TriangularSouth:
 
2820
            {
 
2821
 
 
2822
                slabs << SlabRect( baseSlabRect, TileSet::Ring & ~TileSet::Bottom );
 
2823
 
 
2824
                if( reverseLayout )
 
2825
                {
 
2826
 
 
2827
                    // left side
 
2828
                    QRect slabRect( baseSlabRect );
 
2829
                    slabRect.setRight( qMax( slabRect.right() - w - lw, slabRect.left() + rw ) + 7 );
 
2830
                    slabRect.setTop( slabRect.bottom() - 7 );
 
2831
                    slabs << SlabRect( slabRect, TileSet::BottomLeft );
 
2832
 
 
2833
                    // right side
 
2834
                    if( rw > 0 )
 
2835
                    {
 
2836
                        QRect slabRect( baseSlabRect );
 
2837
                        slabRect.setLeft( slabRect.right() - rw - 7 );
 
2838
                        slabRect.setTop( slabRect.bottom() - 7 );
 
2839
                        slabs << SlabRect( slabRect, TileSet::BottomRight );
 
2840
                    }
 
2841
 
 
2842
                } else {
 
2843
 
 
2844
                    // left side
 
2845
                    if( lw > 0 )
 
2846
                    {
 
2847
 
 
2848
                        QRect slabRect( baseSlabRect );
 
2849
                        slabRect.setRight( baseSlabRect.left() + lw + 7 );
 
2850
                        slabRect.setTop( slabRect.bottom() - 7 );
 
2851
                        slabs << SlabRect( slabRect, TileSet::BottomLeft );
 
2852
 
 
2853
                    }
 
2854
 
 
2855
                    // right side
 
2856
                    QRect slabRect( baseSlabRect );
 
2857
                    slabRect.setLeft( qMin( slabRect.left() + w + lw + 1, slabRect.right() - rw ) -7 );
 
2858
                    slabRect.setTop( slabRect.bottom() - 7 );
 
2859
                    slabs << SlabRect( slabRect, TileSet::BottomRight );
 
2860
 
 
2861
                }
 
2862
 
 
2863
                break;
 
2864
            }
 
2865
 
 
2866
            case QTabBar::RoundedWest:
 
2867
            case QTabBar::TriangularWest:
 
2868
            {
 
2869
                slabs << SlabRect( baseSlabRect, TileSet::Ring & ~TileSet::Left );
 
2870
 
 
2871
                // top side
 
2872
                if( lh > 0 )
 
2873
                {
 
2874
 
 
2875
                    QRect slabRect( baseSlabRect );
 
2876
                    slabRect.setBottom( baseSlabRect.top() + lh + 7 + 1 );
 
2877
                    slabRect.setWidth( 7 );
 
2878
                    slabs << SlabRect( slabRect, TileSet::TopLeft );
 
2879
 
 
2880
                }
 
2881
 
 
2882
                // bottom side
 
2883
                QRect slabRect( baseSlabRect );
 
2884
                slabRect.setTop( qMin( slabRect.top() + h + lh, slabRect.bottom() - rh ) -7 + 1 );
 
2885
                slabRect.setWidth( 7 );
 
2886
                slabs << SlabRect( slabRect, TileSet::BottomLeft );
 
2887
 
 
2888
                break;
 
2889
            }
 
2890
 
 
2891
            case QTabBar::RoundedEast:
 
2892
            case QTabBar::TriangularEast:
 
2893
            {
 
2894
                slabs << SlabRect( baseSlabRect, TileSet::Ring & ~TileSet::Right );
 
2895
 
 
2896
                // top side
 
2897
                if( lh > 0 )
 
2898
                {
 
2899
 
 
2900
                    QRect slabRect( baseSlabRect );
 
2901
                    slabRect.setBottom( baseSlabRect.top() + lh + 7 + 1 );
 
2902
                    slabRect.setLeft( slabRect.right()-7 );
 
2903
                    slabs << SlabRect( slabRect, TileSet::TopRight );
 
2904
 
 
2905
                }
 
2906
 
 
2907
                // bottom side
 
2908
                QRect slabRect( baseSlabRect );
 
2909
                slabRect.setTop( qMin( slabRect.top() + h + lh, slabRect.bottom() - rh ) -7 + 1 );
 
2910
                slabRect.setLeft( slabRect.right()-7 );
 
2911
                slabs << SlabRect( slabRect, TileSet::BottomRight );
 
2912
                break;
 
2913
            }
 
2914
 
 
2915
            break;
 
2916
 
 
2917
            default: break;
 
2918
        }
 
2919
 
 
2920
        // render registered slabs
 
2921
        foreach( const SlabRect& slab, slabs )
 
2922
        { renderSlab( painter, slab, palette.color( QPalette::Window ), NoFill ); }
 
2923
 
 
2924
        return true;
 
2925
 
 
2926
    }
 
2927
 
 
2928
    //___________________________________________________________________________________
 
2929
    bool Style::drawFrameWindowPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
2930
    {
 
2931
 
 
2932
        const QRect& r( option->rect );
 
2933
        const QPalette& palette( option->palette );
 
2934
        helper().drawFloatFrame( painter, r, palette.window().color(), false );
 
2935
 
 
2936
        return true;
 
2937
 
 
2938
    }
 
2939
 
 
2940
    //___________________________________________________________________________________
 
2941
    bool Style::drawIndicatorArrowPrimitive( ArrowOrientation orientation, const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
2942
    {
 
2943
        QRect r( option->rect );
 
2944
        const QPalette& palette( option->palette );
 
2945
        const State& flags( option->state );
 
2946
        const bool enabled( flags & State_Enabled );
 
2947
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
2948
 
 
2949
        // define gradient and polygon for drawing arrow
 
2950
        const QPolygonF a = genericArrow( orientation, ArrowNormal );
 
2951
 
 
2952
        const qreal penThickness = 1.6;
 
2953
        const qreal offset( qMin( penThickness, qreal( 1.0 ) ) );
 
2954
 
 
2955
        QColor color;
 
2956
        const QToolButton* toolButton( qobject_cast<const QToolButton*>( widget ) );
 
2957
        if( toolButton && toolButton->arrowType() != Qt::NoArrow )
 
2958
        {
 
2959
 
 
2960
            /*
 
2961
            arrows painted in toolbutton need a re-centered rect,
 
2962
            and have no highlight
 
2963
            */
 
2964
 
 
2965
            r.translate( 1, 0 );
 
2966
 
 
2967
            // set color properly
 
2968
            color = (toolButton->autoRaise() ? palette.color( QPalette::WindowText ):palette.color( QPalette::ButtonText ) );
 
2969
 
 
2970
        } else if( mouseOver ) {
 
2971
 
 
2972
            color = helper().viewHoverBrush().brush( palette ).color();
 
2973
 
 
2974
        } else {
 
2975
 
 
2976
            color = palette.color( QPalette::WindowText );
 
2977
 
 
2978
        }
 
2979
 
 
2980
        painter->translate( r.center() );
 
2981
        painter->setRenderHint( QPainter::Antialiasing );
 
2982
 
 
2983
        painter->translate( 0,offset );
 
2984
        const QColor background = palette.color( QPalette::Window );
 
2985
        painter->setPen( QPen( helper().calcLightColor( background ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
2986
        painter->drawPolyline( a );
 
2987
        painter->translate( 0,-offset );
 
2988
 
 
2989
        painter->setPen( QPen( helper().decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
2990
        painter->drawPolyline( a );
 
2991
 
 
2992
        return true;
 
2993
    }
 
2994
 
 
2995
    //___________________________________________________________________________________
 
2996
    bool Style::drawIndicatorHeaderArrowPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
2997
    {
 
2998
        const QStyleOptionHeader *headerOpt = qstyleoption_cast<const QStyleOptionHeader *>( option );
 
2999
        const State& flags( option->state );
 
3000
 
 
3001
        // arrow orientation
 
3002
        ArrowOrientation orientation( ArrowNone );
 
3003
        if( flags&State_UpArrow || ( headerOpt && headerOpt->sortIndicator==QStyleOptionHeader::SortUp ) ) orientation = ArrowUp;
 
3004
        else if( flags&State_DownArrow || ( headerOpt && headerOpt->sortIndicator==QStyleOptionHeader::SortDown ) ) orientation = ArrowDown;
 
3005
        if( orientation == ArrowNone ) return true;
 
3006
 
 
3007
        // flags, rect and palette
 
3008
        const QRect& r( option->rect );
 
3009
        const QPalette& palette( option->palette );
 
3010
        const bool enabled( flags & State_Enabled );
 
3011
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
3012
 
 
3013
        animations().headerViewEngine().updateState( widget, r.topLeft(), mouseOver );
 
3014
        const bool animated( enabled && animations().headerViewEngine().isAnimated( widget, r.topLeft() ) );
 
3015
 
 
3016
        // define gradient and polygon for drawing arrow
 
3017
        const QPolygonF a = genericArrow( orientation, ArrowNormal );
 
3018
        QColor color = palette.color( QPalette::WindowText );
 
3019
        const QColor background = palette.color( QPalette::Window );
 
3020
        const QColor highlight( helper().viewHoverBrush().brush( palette ).color() );
 
3021
        const qreal penThickness = 1.6;
 
3022
        const qreal offset( qMin( penThickness, qreal( 1.0 ) ) );
 
3023
 
 
3024
        if( animated )
 
3025
        {
 
3026
 
 
3027
            const qreal opacity( animations().headerViewEngine().opacity( widget, r.topLeft() ) );
 
3028
            color = KColorUtils::mix( color, highlight, opacity );
 
3029
 
 
3030
        } else if( mouseOver ) color = highlight;
 
3031
 
 
3032
        painter->translate( r.center() );
 
3033
        painter->translate( 0, 1 );
 
3034
        painter->setRenderHint( QPainter::Antialiasing );
 
3035
 
 
3036
        painter->translate( 0,offset );
 
3037
        painter->setPen( QPen( helper().calcLightColor( background ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
3038
        painter->drawPolyline( a );
 
3039
        painter->translate( 0,-offset );
 
3040
 
 
3041
        painter->setPen( QPen( helper().decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
3042
        painter->drawPolyline( a );
 
3043
 
 
3044
        return true;
 
3045
    }
 
3046
 
 
3047
    //______________________________________________________________
 
3048
    bool Style::drawPanelButtonCommandPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
3049
    {
 
3050
        const State& flags( option->state );
 
3051
        const bool enabled( flags & State_Enabled );
 
3052
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
3053
        const bool hasFocus( enabled && ( flags & State_HasFocus ) );
 
3054
        const QPalette& palette( option->palette );
 
3055
 
 
3056
        StyleOptions opts = 0;
 
3057
        if( flags & ( State_On|State_Sunken ) ) opts |= Sunken;
 
3058
        if( flags & State_HasFocus ) opts |= Focus;
 
3059
        if( enabled && ( flags & State_MouseOver ) ) opts |= Hover;
 
3060
 
 
3061
        // update animation state
 
3062
        animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
 
3063
        animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );
 
3064
 
 
3065
        // store animation state
 
3066
        const bool hoverAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationHover ) );
 
3067
        const bool focusAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) );
 
3068
        const qreal hoverOpacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
 
3069
        const qreal focusOpacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );
 
3070
 
 
3071
        // decide if widget must be rendered flat.
 
3072
        /*
 
3073
        The decision is made depending on
 
3074
        - whether the "flat" flag is set in the option
 
3075
        - whether the widget is hight enough to render both icons and normal margins
 
3076
        Note: in principle one should also check for the button text height
 
3077
        */
 
3078
 
 
3079
        const QRect& r( option->rect );
 
3080
        const QStyleOptionButton* bOpt( qstyleoption_cast< const QStyleOptionButton* >( option ) );
 
3081
        bool flat = ( bOpt && (
 
3082
            bOpt->features.testFlag( QStyleOptionButton::Flat ) ||
 
3083
            ( ( !bOpt->icon.isNull() ) && sizeFromContents( CT_PushButton, option, bOpt->iconSize, widget ).height() > r.height() ) ) );
 
3084
 
 
3085
        if( flat )
 
3086
        {
 
3087
 
 
3088
            QRect slitRect( r );
 
3089
            if( !( opts & Sunken ) )
 
3090
            {
 
3091
                // hover rect
 
3092
                if( enabled && hoverAnimated )
 
3093
                {
 
3094
 
 
3095
                    QColor glow( helper().alphaColor( helper().viewFocusBrush().brush( QPalette::Active ).color(), hoverOpacity ) );
 
3096
                    helper().slitFocused( glow )->render( slitRect, painter );
 
3097
 
 
3098
                } else if( mouseOver ) {
 
3099
 
 
3100
                    helper().slitFocused( helper().viewFocusBrush().brush( QPalette::Active ).color() )->render( slitRect, painter );
 
3101
 
 
3102
                }
 
3103
 
 
3104
            } else {
 
3105
 
 
3106
                slitRect.adjust( 0, 0, 0, -1 );
 
3107
 
 
3108
                HoleOptions options( 0 );
 
3109
                if( mouseOver ) options |= HoleHover;
 
3110
 
 
3111
                // flat pressed-down buttons do not get focus effect,
 
3112
                // consistently with tool buttons
 
3113
                if( enabled && hoverAnimated )
 
3114
                {
 
3115
 
 
3116
                    helper().renderHole( painter, palette.color( QPalette::Window ), slitRect, options, hoverOpacity, AnimationHover, TileSet::Ring );
 
3117
 
 
3118
                } else {
 
3119
 
 
3120
                    helper().renderHole( painter, palette.color( QPalette::Window ), slitRect, options );
 
3121
 
 
3122
                }
 
3123
 
 
3124
            }
 
3125
 
 
3126
        } else {
 
3127
 
 
3128
            const QRect slabRect( r.adjusted( -1, 0, 1, 0 ) );
 
3129
 
 
3130
            // match color to the window background
 
3131
            const QColor buttonColor( helper().backgroundColor( palette.color( QPalette::Button ), widget, r.center() ) );
 
3132
 
 
3133
            if( enabled && hoverAnimated && !( opts & Sunken ) )
 
3134
            {
 
3135
 
 
3136
                renderButtonSlab( painter, slabRect, buttonColor, opts, hoverOpacity, AnimationHover, TileSet::Ring );
 
3137
 
 
3138
            } else if( enabled && !mouseOver && focusAnimated && !( opts & Sunken ) ) {
 
3139
 
 
3140
                renderButtonSlab( painter, slabRect, buttonColor, opts, focusOpacity, AnimationFocus, TileSet::Ring );
 
3141
 
 
3142
            } else {
 
3143
 
 
3144
                renderButtonSlab( painter, slabRect, buttonColor, opts );
 
3145
 
 
3146
            }
 
3147
 
 
3148
        }
 
3149
 
 
3150
        return true;
 
3151
 
 
3152
    }
 
3153
 
 
3154
    //______________________________________________________________
 
3155
    bool Style::drawPanelButtonToolPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
3156
    {
 
3157
 
 
3158
        /*
 
3159
        For toolbutton in TabBars, corresponding to expanding arrows, no frame is drawn
 
3160
        However one needs to draw the window background, because the button rect might
 
3161
        overlap with some tab below. ( this is a Qt bug )
 
3162
        */
 
3163
        const bool isInTabBar( widget && qobject_cast<const QTabBar*>( widget->parent() ) );
 
3164
        if( isInTabBar )
 
3165
        {
 
3166
 
 
3167
            const QPalette& palette( option->palette );
 
3168
            QRect r( option->rect );
 
3169
 
 
3170
            // adjust rect depending on shape
 
3171
            const QTabBar* tabBar( static_cast<const QTabBar*>( widget->parent() ) );
 
3172
            switch( tabBar->shape() )
 
3173
            {
 
3174
                case QTabBar::RoundedNorth:
 
3175
                case QTabBar::TriangularNorth:
 
3176
                r.setBottom( r.bottom()-6 );
 
3177
                break;
 
3178
 
 
3179
                case QTabBar::RoundedSouth:
 
3180
                case QTabBar::TriangularSouth:
 
3181
                r.setTop( r.top() + 6 );
 
3182
                break;
 
3183
 
 
3184
                case QTabBar::RoundedWest:
 
3185
                case QTabBar::TriangularWest:
 
3186
                r.setRight( r.right() - 6 );
 
3187
                break;
 
3188
 
 
3189
                case QTabBar::RoundedEast:
 
3190
                case QTabBar::TriangularEast:
 
3191
                r.setLeft( r.left() + 6 );
 
3192
                break;
 
3193
 
 
3194
                default: break;
 
3195
 
 
3196
            }
 
3197
 
 
3198
            const QPalette local( widget->parentWidget() ? widget->parentWidget()->palette() : palette );
 
3199
 
 
3200
            // check whether parent has autofill background flag
 
3201
            const QWidget* parent = helper().checkAutoFillBackground( widget );
 
3202
            if( parent && !qobject_cast<const QDockWidget*>( parent ) ) painter->fillRect( r, parent->palette().color( parent->backgroundRole() ) );
 
3203
            else helper().renderWindowBackground( painter, r, widget, local );
 
3204
 
 
3205
            return true;
 
3206
 
 
3207
        }
 
3208
 
 
3209
        const QRect& r( option->rect );
 
3210
        const State& flags( option->state );
 
3211
        const QPalette& palette( option->palette );
 
3212
 
 
3213
        const bool enabled( flags & State_Enabled );
 
3214
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
3215
        const bool hasFocus( enabled && ( flags & State_HasFocus ) );
 
3216
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
3217
        const bool autoRaised( flags & State_AutoRaise );
 
3218
 
 
3219
        // check whether toolbutton is in toolbar
 
3220
        const bool isInToolBar( widget && qobject_cast<const QToolBar*>( widget->parent() ) );
 
3221
 
 
3222
        // toolbar engine
 
3223
        const bool toolBarAnimated( isInToolBar && widget && ( animations().toolBarEngine().isAnimated( widget->parentWidget() ) || animations().toolBarEngine().isFollowMouseAnimated( widget->parentWidget() ) ) );
 
3224
        const QRect animatedRect( ( isInToolBar && widget ) ? animations().toolBarEngine().animatedRect( widget->parentWidget() ):QRect() );
 
3225
        const QRect childRect( ( widget && widget->parentWidget() ) ? r.translated( widget->mapToParent( QPoint( 0,0 ) ) ):QRect() );
 
3226
        const QRect currentRect(  widget ? animations().toolBarEngine().currentRect( widget->parentWidget() ):QRect() );
 
3227
        const bool current( isInToolBar && widget && widget->parentWidget() && currentRect.intersects( r.translated( widget->mapToParent( QPoint( 0,0 ) ) ) ) );
 
3228
        const bool toolBarTimerActive( isInToolBar && widget && animations().toolBarEngine().isTimerActive( widget->parentWidget() ) );
 
3229
        const qreal toolBarOpacity( ( isInToolBar && widget ) ? animations().toolBarEngine().opacity( widget->parentWidget() ):0 );
 
3230
 
 
3231
        // toolbutton engine
 
3232
        if( isInToolBar && !toolBarAnimated )
 
3233
        {
 
3234
 
 
3235
            animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
 
3236
 
 
3237
        } else {
 
3238
 
 
3239
            // mouseOver has precedence over focus
 
3240
            animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
 
3241
            animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );
 
3242
 
 
3243
        }
 
3244
 
 
3245
        bool hoverAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationHover ) );
 
3246
        bool focusAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) );
 
3247
 
 
3248
        qreal hoverOpacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
 
3249
        qreal focusOpacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );
 
3250
 
 
3251
        // slit rect
 
3252
        QRect slitRect( r );
 
3253
 
 
3254
        // non autoraised tool buttons get same slab as regular buttons
 
3255
        if( widget && !autoRaised )
 
3256
        {
 
3257
 
 
3258
            StyleOptions opts = 0;
 
3259
            slitRect.adjust( -1, 0, 1, 0 );
 
3260
 
 
3261
            // "normal" parent, and non "autoraised" ( that is: always raised ) buttons
 
3262
            if( flags & ( State_On|State_Sunken ) ) opts |= Sunken;
 
3263
            if( flags & State_HasFocus ) opts |= Focus;
 
3264
            if( enabled && ( flags & State_MouseOver ) ) opts |= Hover;
 
3265
 
 
3266
            TileSet::Tiles tiles( TileSet::Ring );
 
3267
 
 
3268
            // adjust tiles and rect in case of menubutton
 
3269
            const QToolButton* t = qobject_cast<const QToolButton*>( widget );
 
3270
            if( t && t->popupMode()==QToolButton::MenuButtonPopup )
 
3271
            {
 
3272
                if( reverseLayout )
 
3273
                {
 
3274
 
 
3275
                    tiles = TileSet::Bottom | TileSet::Top | TileSet::Right;
 
3276
                    slitRect.adjust( -4, 0, 0, 0 );
 
3277
 
 
3278
                } else {
 
3279
                    tiles = TileSet::Bottom | TileSet::Top | TileSet::Left;
 
3280
                    slitRect.adjust( 0, 0, 4, 0 );
 
3281
                }
 
3282
            }
 
3283
 
 
3284
            // adjust opacity and animation mode
 
3285
            qreal opacity( -1 );
 
3286
            AnimationMode mode( AnimationNone );
 
3287
            if( enabled && hoverAnimated )
 
3288
            {
 
3289
                opacity = hoverOpacity;
 
3290
                mode = AnimationHover;
 
3291
 
 
3292
            } else if( enabled && !hasFocus && focusAnimated ) {
 
3293
 
 
3294
                opacity = focusOpacity;
 
3295
                mode = AnimationFocus;
 
3296
 
 
3297
            }
 
3298
 
 
3299
            // match button color to window background
 
3300
            const QColor buttonColor( helper().backgroundColor( palette.color( QPalette::Button ), widget, r.center() ) );
 
3301
 
 
3302
            // render slab
 
3303
            renderButtonSlab( painter, slitRect, buttonColor, opts, opacity, mode, tiles );
 
3304
 
 
3305
            return true;
 
3306
 
 
3307
        }
 
3308
 
 
3309
        //! fine tuning of slitRect geometry
 
3310
        if( widget && widget->inherits( "QDockWidgetTitleButton" ) ) slitRect.adjust( 1, 0, 0, 0 );
 
3311
        else if( widget && widget->inherits( "QToolBarExtension" ) ) slitRect.adjust( 1, 1, -1, -1 );
 
3312
        else if( widget && widget->objectName() == "qt_menubar_ext_button" ) slitRect.adjust( -1, -1, 0, 0 );
 
3313
 
 
3314
        // normal ( auto-raised ) toolbuttons
 
3315
        if( flags & ( State_Sunken|State_On ) )
 
3316
        {
 
3317
 
 
3318
            {
 
3319
 
 
3320
                // fill hole
 
3321
                qreal opacity = 1.0;
 
3322
                const qreal bias = 0.75;
 
3323
                if( enabled && hoverAnimated )
 
3324
                {
 
3325
 
 
3326
                    opacity = 1.0 - bias*hoverOpacity;
 
3327
 
 
3328
                } else if( toolBarAnimated && enabled && animatedRect.isNull() && current  ) {
 
3329
 
 
3330
                    opacity = 1.0 - bias*toolBarOpacity;
 
3331
 
 
3332
                } else if( enabled && (( toolBarTimerActive && current ) || mouseOver ) ) {
 
3333
 
 
3334
                    opacity = 1.0 - bias;
 
3335
 
 
3336
                }
 
3337
 
 
3338
                if( opacity > 0 )
 
3339
                {
 
3340
                    QColor color( helper().backgroundColor( helper().calcMidColor( palette.color( QPalette::Window ) ), widget, slitRect.center() ) );
 
3341
                    color = helper().alphaColor( color, opacity );
 
3342
                    painter->save();
 
3343
                    painter->setRenderHint( QPainter::Antialiasing );
 
3344
                    painter->setPen( Qt::NoPen );
 
3345
                    painter->setBrush( color );
 
3346
                    painter->drawRoundedRect( slitRect.adjusted( 1, 1, -1, -1 ), 3.5, 3.5 );
 
3347
                    painter->restore();
 
3348
                }
 
3349
 
 
3350
            }
 
3351
 
 
3352
 
 
3353
            HoleOptions options( HoleContrast );
 
3354
            if( hasFocus && enabled ) options |= HoleFocus;
 
3355
            if( mouseOver && enabled ) options |= HoleHover;
 
3356
 
 
3357
            if( enabled && hoverAnimated )
 
3358
            {
 
3359
 
 
3360
                helper().renderHole( painter, palette.color( QPalette::Window ), slitRect, options, hoverOpacity, AnimationHover, TileSet::Ring );
 
3361
 
 
3362
            } else if( toolBarAnimated ) {
 
3363
 
 
3364
                if( enabled && animatedRect.isNull() && current  )
 
3365
                {
 
3366
 
 
3367
                    helper().renderHole( painter, palette.color( QPalette::Window ), slitRect, options, toolBarOpacity, AnimationHover, TileSet::Ring );
 
3368
 
 
3369
                } else {
 
3370
 
 
3371
                    helper().renderHole( painter, palette.color( QPalette::Window ), slitRect, HoleContrast );
 
3372
 
 
3373
                }
 
3374
 
 
3375
            } else if( toolBarTimerActive && current ) {
 
3376
 
 
3377
                helper().renderHole( painter, palette.color( QPalette::Window ), slitRect, options | HoleHover );
 
3378
 
 
3379
            } else {
 
3380
 
 
3381
                helper().renderHole( painter, palette.color( QPalette::Window ), slitRect, options );
 
3382
 
 
3383
            }
 
3384
 
 
3385
        } else {
 
3386
 
 
3387
            if( enabled && hoverAnimated )
 
3388
            {
 
3389
 
 
3390
                QColor glow( helper().alphaColor( helper().viewFocusBrush().brush( QPalette::Active ).color(), hoverOpacity ) );
 
3391
                helper().slitFocused( glow )->render( slitRect, painter );
 
3392
 
 
3393
            } else if( toolBarAnimated ) {
 
3394
 
 
3395
                if( enabled && animatedRect.isNull() && current )
 
3396
                {
 
3397
                    QColor glow( helper().alphaColor( helper().viewFocusBrush().brush( QPalette::Active ).color(), toolBarOpacity ) );
 
3398
                    helper().slitFocused( glow )->render( slitRect, painter );
 
3399
                }
 
3400
 
 
3401
            } else if( hasFocus || mouseOver || ( toolBarTimerActive && current ) ) {
 
3402
 
 
3403
                helper().slitFocused( helper().viewFocusBrush().brush( QPalette::Active ).color() )->render( slitRect, painter );
 
3404
 
 
3405
            }
 
3406
 
 
3407
        }
 
3408
 
 
3409
        return true;
 
3410
    }
 
3411
 
 
3412
    //___________________________________________________________________________________
 
3413
    bool Style::drawPanelItemViewItemPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
3414
    {
 
3415
 
 
3416
        const QStyleOptionViewItemV4 *opt = qstyleoption_cast<const QStyleOptionViewItemV4*>( option );
 
3417
        const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>( widget );
 
3418
        const bool hover = ( option->state & State_MouseOver ) && ( !view || view->selectionMode() != QAbstractItemView::NoSelection );
 
3419
 
 
3420
        const bool hasCustomBackground = opt->backgroundBrush.style() != Qt::NoBrush && !( option->state & State_Selected );
 
3421
        const bool hasSolidBackground = !hasCustomBackground || opt->backgroundBrush.style() == Qt::SolidPattern;
 
3422
 
 
3423
        if( !hover && !( option->state & State_Selected ) && !hasCustomBackground && !( opt->features & QStyleOptionViewItemV2::Alternate ) )
 
3424
        { return true; }
 
3425
 
 
3426
        QPalette::ColorGroup cg;
 
3427
        if( option->state & State_Enabled ) cg = ( option->state & State_Active ) ? QPalette::Normal : QPalette::Inactive;
 
3428
        else cg = QPalette::Disabled;
 
3429
 
 
3430
        QColor color;
 
3431
        if( hasCustomBackground && hasSolidBackground ) color = opt->backgroundBrush.color();
 
3432
        else color = option->palette.color( cg, QPalette::Highlight );
 
3433
 
 
3434
        if( hover && !hasCustomBackground )
 
3435
        {
 
3436
            if( !( option->state & State_Selected ) ) color.setAlphaF( 0.2 );
 
3437
            else color = color.lighter( 110 );
 
3438
        }
 
3439
 
 
3440
        if( opt && ( opt->features & QStyleOptionViewItemV2::Alternate ) )
 
3441
        { painter->fillRect( option->rect, option->palette.brush( cg, QPalette::AlternateBase ) ); }
 
3442
 
 
3443
        if( !hover && !( option->state & State_Selected ) && !hasCustomBackground )
 
3444
        { return true; }
 
3445
 
 
3446
        if( hasCustomBackground && !hasSolidBackground )
 
3447
        {
 
3448
 
 
3449
            const QPointF oldBrushOrigin = painter->brushOrigin();
 
3450
            painter->setBrushOrigin( opt->rect.topLeft() );
 
3451
            painter->setBrush( opt->backgroundBrush );
 
3452
            painter->setPen( Qt::NoPen );
 
3453
            painter->drawRect( opt->rect );
 
3454
            painter->setBrushOrigin( oldBrushOrigin );
 
3455
 
 
3456
        } else {
 
3457
 
 
3458
            // get selection tileset
 
3459
            QRect r = option->rect;
 
3460
            TileSet *tileSet( helper().selection( color, r.height(), hasCustomBackground ) );
 
3461
 
 
3462
            bool roundedLeft  = false;
 
3463
            bool roundedRight = false;
 
3464
            if( opt )
 
3465
            {
 
3466
 
 
3467
                roundedLeft  = ( opt->viewItemPosition == QStyleOptionViewItemV4::Beginning );
 
3468
                roundedRight = ( opt->viewItemPosition == QStyleOptionViewItemV4::End );
 
3469
                if( opt->viewItemPosition == QStyleOptionViewItemV4::OnlyOne ||
 
3470
                    opt->viewItemPosition == QStyleOptionViewItemV4::Invalid ||
 
3471
                    ( view && view->selectionBehavior() != QAbstractItemView::SelectRows ) )
 
3472
                {
 
3473
                    roundedLeft  = true;
 
3474
                    roundedRight = true;
 
3475
                }
 
3476
 
 
3477
            }
 
3478
 
 
3479
            const bool reverseLayout( option->direction == Qt::RightToLeft );
 
3480
 
 
3481
            TileSet::Tiles tiles( TileSet::Center );
 
3482
            if( !reverseLayout ? roundedLeft : roundedRight ) tiles |= TileSet::Left;
 
3483
            else r.adjust( -8, 0, 0, 0 );
 
3484
 
 
3485
            if( !reverseLayout ? roundedRight : roundedLeft ) tiles |= TileSet::Right;
 
3486
            else r.adjust( 0, 0, 8, 0 );
 
3487
 
 
3488
            if( r.isValid() ) tileSet->render( r, painter, tiles );
 
3489
        }
 
3490
 
 
3491
        return true;
 
3492
    }
 
3493
 
 
3494
    //___________________________________________________________________________________
 
3495
    bool Style::drawPanelLineEditPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
3496
    {
 
3497
 
 
3498
        const QRect& r( option->rect );
 
3499
        const QPalette& palette( option->palette );
 
3500
 
 
3501
        // cast option and check
 
3502
        const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame*>( option );
 
3503
        if( !panel ) return true;
 
3504
 
 
3505
        const QBrush inputBrush( palette.base() );
 
3506
        const int lineWidth( panel->lineWidth );
 
3507
 
 
3508
        if( lineWidth > 0 )
 
3509
        {
 
3510
            painter->save();
 
3511
            painter->setRenderHint( QPainter::Antialiasing );
 
3512
            painter->setPen( Qt::NoPen );
 
3513
            painter->setBrush( inputBrush );
 
3514
 
 
3515
            helper().fillHole( *painter, r.adjusted( 0, -1, 0, 0 ) );
 
3516
            drawFramePrimitive( panel, painter, widget );
 
3517
 
 
3518
            painter->restore();
 
3519
 
 
3520
        } else  {
 
3521
 
 
3522
            painter->fillRect( r.adjusted( 2,2,-2,-2 ), inputBrush );
 
3523
 
 
3524
        }
 
3525
 
 
3526
        return true;
 
3527
 
 
3528
    }
 
3529
 
 
3530
    //___________________________________________________________________________________
 
3531
    bool Style::drawPanelMenuPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
3532
    {
 
3533
 
 
3534
        // do nothing if menu is embedded in another widget
 
3535
        // this corresponds to having a transparent background
 
3536
        if( widget && !widget->isWindow() ) return true;
 
3537
 
 
3538
        const QStyleOptionMenuItem* mOpt( qstyleoption_cast<const QStyleOptionMenuItem*>( option ) );
 
3539
        if( !( mOpt && widget ) ) return true;
 
3540
        const QRect& r = mOpt->rect;
 
3541
        const QColor color = mOpt->palette.color( widget->window()->backgroundRole() );
 
3542
 
 
3543
        const bool hasAlpha( helper().hasAlphaChannel( widget ) );
 
3544
        if( hasAlpha )
 
3545
        {
 
3546
 
 
3547
            painter->setCompositionMode( QPainter::CompositionMode_Source );
 
3548
            TileSet *tileSet( helper().roundCorner( color ) );
 
3549
            tileSet->render( r, painter );
 
3550
 
 
3551
            painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
 
3552
            painter->setClipRegion( helper().roundedMask( r.adjusted( 1, 1, -1, -1 ) ), Qt::IntersectClip );
 
3553
 
 
3554
        }
 
3555
 
 
3556
        helper().renderMenuBackground( painter, r, widget, mOpt->palette );
 
3557
 
 
3558
        if( hasAlpha ) painter->setClipping( false );
 
3559
        helper().drawFloatFrame( painter, r, color, !hasAlpha );
 
3560
 
 
3561
        return true;
 
3562
 
 
3563
    }
 
3564
 
 
3565
    //___________________________________________________________________________________
 
3566
    bool Style::drawPanelScrollAreaCornerPrimitive( const QStyleOption*, QPainter*, const QWidget* widget ) const
 
3567
    {
 
3568
        // disable painting of PE_PanelScrollAreaCorner
 
3569
        // the default implementation fills the rect with the window background color
 
3570
        // which does not work for windows that have gradients.
 
3571
        // unfortunately, this does not work when scrollbars are children of QWebView,
 
3572
        // in which case, false is returned, in order to fall back to the parent style implementation
 
3573
        return !( widget && widget->inherits( "QWebView" ) );
 
3574
    }
 
3575
 
 
3576
    //___________________________________________________________________________________
 
3577
    bool Style::drawPanelTipLabelPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
3578
    {
 
3579
 
 
3580
        // force registration of widget
 
3581
        if( widget && widget->window() )
 
3582
        { shadowHelper().registerWidget( widget->window(), true ); }
 
3583
 
 
3584
        // parent style painting if frames should not be styled
 
3585
        if( !StyleConfigData::toolTipDrawStyledFrames() ) return false;
 
3586
 
 
3587
        const QRect& r( option->rect );
 
3588
        const QColor color( option->palette.brush( QPalette::ToolTipBase ).color() );
 
3589
        QColor topColor( helper().backgroundTopColor( color ) );
 
3590
        QColor bottomColor( helper().backgroundBottomColor( color ) );
 
3591
 
 
3592
        // make tooltip semi transparents when possible
 
3593
        // alpha is copied from "kdebase/apps/dolphin/tooltips/filemetadatatooltip.cpp"
 
3594
        const bool hasAlpha( helper().hasAlphaChannel( widget ) );
 
3595
        if(  hasAlpha && StyleConfigData::toolTipTransparent() )
 
3596
        {
 
3597
            topColor.setAlpha( 220 );
 
3598
            bottomColor.setAlpha( 220 );
 
3599
        }
 
3600
 
 
3601
        QLinearGradient gr( 0, r.top(), 0, r.bottom() );
 
3602
        gr.setColorAt( 0, topColor );
 
3603
        gr.setColorAt( 1, bottomColor );
 
3604
 
 
3605
        // contrast pixmap
 
3606
        QLinearGradient gr2( 0, r.top(), 0, r.bottom() );
 
3607
        gr2.setColorAt( 0.5, helper().calcLightColor( bottomColor ) );
 
3608
        gr2.setColorAt( 0.9, bottomColor );
 
3609
 
 
3610
        painter->save();
 
3611
 
 
3612
        if( hasAlpha )
 
3613
        {
 
3614
            painter->setRenderHint( QPainter::Antialiasing );
 
3615
 
 
3616
            QRectF local( r );
 
3617
            local.adjust( 0.5, 0.5, -0.5, -0.5 );
 
3618
 
 
3619
            painter->setPen( Qt::NoPen );
 
3620
            painter->setBrush( gr );
 
3621
            painter->drawRoundedRect( local, 4, 4 );
 
3622
 
 
3623
            painter->setBrush( Qt::NoBrush );
 
3624
            painter->setPen( QPen( gr2, 1.1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
3625
            painter->drawRoundedRect( local, 3.5, 3.5 );
 
3626
 
 
3627
        } else {
 
3628
 
 
3629
            painter->setPen( Qt::NoPen );
 
3630
            painter->setBrush( gr );
 
3631
            painter->drawRect( r );
 
3632
 
 
3633
            painter->setBrush( Qt::NoBrush );
 
3634
            painter->setPen( QPen( gr2, 1.1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
3635
            painter->drawRect( r );
 
3636
 
 
3637
        }
 
3638
 
 
3639
        painter->restore();
 
3640
 
 
3641
        return true;
 
3642
 
 
3643
    }
 
3644
 
 
3645
    //___________________________________________________________________________________
 
3646
    bool Style::drawIndicatorMenuCheckMarkPrimitive( const QStyleOption *option, QPainter *painter, const QWidget * ) const
 
3647
    {
 
3648
        const QRect& r( option->rect );
 
3649
        const State& flags( option->state );
 
3650
        const QPalette& palette( option->palette );
 
3651
        const bool enabled( flags & State_Enabled );
 
3652
 
 
3653
        StyleOptions opts( NoFill );
 
3654
        if( !enabled ) opts |= Disabled;
 
3655
        CheckBoxState state = CheckOn;
 
3656
 
 
3657
        renderCheckBox( painter, r, palette, opts, state );
 
3658
        return true;
 
3659
 
 
3660
    }
 
3661
 
 
3662
    //___________________________________________________________________________________
 
3663
    bool Style::drawQ3CheckListIndicatorPrimitive( const QStyleOption *option, QPainter *painter, const QWidget *widget ) const
 
3664
    {
 
3665
        const QStyleOptionQ3ListView* listViewOpt( qstyleoption_cast<const QStyleOptionQ3ListView*>( option ) );
 
3666
        if( !listViewOpt || listViewOpt->items.isEmpty() ) return true;
 
3667
 
 
3668
        QStyleOptionButton buttonOption;
 
3669
        buttonOption.QStyleOption::operator=( *option );
 
3670
 
 
3671
        QSize size( CheckBox_Size, CheckBox_Size );
 
3672
        buttonOption.rect = centerRect( option->rect, size ).translated( 0, 4 );
 
3673
        drawIndicatorCheckBoxPrimitive( &buttonOption, painter, widget );
 
3674
        return true;
 
3675
    }
 
3676
 
 
3677
    //___________________________________________________________________________________
 
3678
    bool Style::drawQ3CheckListExclusiveIndicatorPrimitive( const QStyleOption *option, QPainter *painter, const QWidget *widget ) const
 
3679
    {
 
3680
        const QStyleOptionQ3ListView* listViewOpt( qstyleoption_cast<const QStyleOptionQ3ListView*>( option ) );
 
3681
        if( !listViewOpt || listViewOpt->items.isEmpty() ) return true;
 
3682
 
 
3683
        QStyleOptionButton buttonOption;
 
3684
        buttonOption.QStyleOption::operator=( *option );
 
3685
 
 
3686
        QSize size( CheckBox_Size, CheckBox_Size );
 
3687
        buttonOption.rect = centerRect( option->rect, size ).translated( 0, 4 );
 
3688
        drawIndicatorRadioButtonPrimitive( &buttonOption, painter, widget );
 
3689
        return true;
 
3690
    }
 
3691
 
 
3692
    //___________________________________________________________________________________
 
3693
    bool Style::drawIndicatorBranchPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
3694
    {
 
3695
 
 
3696
        const State& flags( option->state );
 
3697
        const QRect& r( option->rect );
 
3698
        const QPalette& palette( option->palette );
 
3699
        const QPoint center( r.center() );
 
3700
 
 
3701
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
3702
 
 
3703
        const int centerX = center.x();
 
3704
        const int centerY = center.y();
 
3705
 
 
3706
        int expanderAdjust = 0;
 
3707
 
 
3708
        //draw expander
 
3709
        if ( flags & State_Children )
 
3710
        {
 
3711
 
 
3712
            int sizeLimit = qMin( qMin( r.width(), r.height() ), ( int ) Tree_MaxExpanderSize );
 
3713
            const bool expanderOpen( flags & State_Open );
 
3714
 
 
3715
            // make sure size limit is odd
 
3716
            if( !( sizeLimit&1 ) ) --sizeLimit;
 
3717
            expanderAdjust = sizeLimit/2 + 1;
 
3718
 
 
3719
            QRect expanderRect = centerRect( r, sizeLimit, sizeLimit );
 
3720
            const int radius( ( expanderRect.width() - 4 ) / 2 );
 
3721
 
 
3722
            // flags
 
3723
            const bool enabled( flags & State_Enabled );
 
3724
            const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
3725
 
 
3726
            // color
 
3727
            const QColor expanderColor( mouseOver ? helper().viewHoverBrush().brush( palette ).color():palette.color( QPalette::Text ) );
 
3728
 
 
3729
            if( !StyleConfigData::viewDrawTriangularExpander() )
 
3730
            {
 
3731
 
 
3732
                // plus or minus sign used for expanders
 
3733
                painter->save();
 
3734
                painter->setPen( expanderColor );
 
3735
                painter->drawLine( center - QPoint( radius, 0 ), center + QPoint( radius, 0 ) );
 
3736
 
 
3737
                if( !expanderOpen )
 
3738
                { painter->drawLine( center - QPoint( 0, radius ), center + QPoint( 0, radius ) ); }
 
3739
 
 
3740
                painter->restore();
 
3741
 
 
3742
            } else {
 
3743
 
 
3744
                // arrows
 
3745
                painter->save();
 
3746
                painter->translate( center );
 
3747
 
 
3748
                // get size from option
 
3749
                QPolygonF a;
 
3750
                ArrowSize size = ArrowSmall;
 
3751
                qreal penThickness( 1.2 );
 
3752
                qreal offset( 0.5 );
 
3753
 
 
3754
                switch( StyleConfigData::viewTriangularExpanderSize() )
 
3755
                {
 
3756
                    case StyleConfigData::TE_TINY:
 
3757
                    size = ArrowTiny;
 
3758
                    break;
 
3759
 
 
3760
                    default:
 
3761
                    case StyleConfigData::TE_SMALL:
 
3762
                    size = ArrowSmall;
 
3763
                    break;
 
3764
 
 
3765
                    case StyleConfigData::TE_NORMAL:
 
3766
                    penThickness = 1.6;
 
3767
                    offset = 0.0;
 
3768
                    size = ArrowNormal;
 
3769
                    break;
 
3770
 
 
3771
                }
 
3772
 
 
3773
                if( expanderOpen )
 
3774
                {
 
3775
 
 
3776
                    painter->translate( 0, offset );
 
3777
                    a = genericArrow( ArrowDown, size );
 
3778
 
 
3779
                } else {
 
3780
 
 
3781
                    painter->translate( offset, 0 );
 
3782
                    a = genericArrow( reverseLayout ? ArrowLeft:ArrowRight, size );
 
3783
 
 
3784
                }
 
3785
 
 
3786
                painter->setPen( QPen( expanderColor, penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
3787
                painter->setRenderHint( QPainter::Antialiasing );
 
3788
                painter->drawPolyline( a );
 
3789
                painter->restore();
 
3790
            }
 
3791
 
 
3792
        }
 
3793
 
 
3794
 
 
3795
        // tree branches
 
3796
        if( !StyleConfigData::viewDrawTreeBranchLines() ) return true;
 
3797
 
 
3798
        painter->setPen( KColorUtils::mix( palette.color( QPalette::Text ), palette.color( QPalette::Background ), 0.8 ) );
 
3799
        if ( flags & ( State_Item | State_Children | State_Sibling ) )
 
3800
        {
 
3801
            const QLine line( QPoint( centerX, r.top() ), QPoint( centerX, centerY - expanderAdjust ) );
 
3802
            painter->drawLine( line );
 
3803
        }
 
3804
 
 
3805
        //The right/left ( depending on dir ) line gets drawn if we have an item
 
3806
        if ( flags & State_Item )
 
3807
        {
 
3808
            const QLine line = reverseLayout ?
 
3809
                QLine( QPoint( r.left(), centerY ), QPoint( centerX - expanderAdjust, centerY ) ):
 
3810
                QLine( QPoint( centerX + expanderAdjust, centerY ), QPoint( r.right(), centerY ) );
 
3811
            painter->drawLine( line );
 
3812
 
 
3813
        }
 
3814
 
 
3815
        //The bottom if we have a sibling
 
3816
        if ( flags & State_Sibling )
 
3817
        {
 
3818
            const QLine line( QPoint( centerX, centerY + expanderAdjust ), QPoint( centerX, r.bottom() ) );
 
3819
            painter->drawLine( line );
 
3820
        }
 
3821
 
 
3822
        return true;
 
3823
    }
 
3824
 
 
3825
    //___________________________________________________________________________________
 
3826
    bool Style::drawIndicatorButtonDropDownPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
3827
    {
 
3828
 
 
3829
        const QPalette& palette( option->palette );
 
3830
        const QRect& r( option->rect );
 
3831
        const State& flags( option->state );
 
3832
 
 
3833
        const bool enabled( flags & State_Enabled );
 
3834
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
3835
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
3836
        const bool autoRaise( flags & State_AutoRaise );
 
3837
        const bool sunken( enabled && ( flags & State_Sunken ) );
 
3838
 
 
3839
        // match button color to window background
 
3840
        const QColor highlight( helper().viewHoverBrush().brush( palette ).color() );
 
3841
        QColor color = palette.color( autoRaise ? QPalette::WindowText:QPalette::ButtonText );
 
3842
        QColor background = palette.color( QPalette::Window );
 
3843
        StyleOptions opts = 0;
 
3844
 
 
3845
        // define gradient and polygon for drawing arrow
 
3846
        QPolygonF a = genericArrow( ArrowDown, ArrowNormal );
 
3847
 
 
3848
        qreal penThickness = 1.6;
 
3849
 
 
3850
        // toolbuttons
 
3851
        const QToolButton *tool( qobject_cast<const QToolButton *>( widget ) );
 
3852
        if( tool && tool->popupMode()==QToolButton::MenuButtonPopup )
 
3853
        {
 
3854
 
 
3855
            if( !autoRaise )
 
3856
            {
 
3857
 
 
3858
                const bool hasFocus( enabled && ( flags & State_HasFocus ) );
 
3859
 
 
3860
                // handle animations
 
3861
                // mouseOver has precedence over focus
 
3862
                animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
 
3863
                animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );
 
3864
 
 
3865
                const bool hoverAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationHover ) );
 
3866
                const bool focusAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) );
 
3867
 
 
3868
                const qreal hoverOpacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
 
3869
                const qreal focusOpacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );
 
3870
 
 
3871
                color = palette.color( QPalette::ButtonText );
 
3872
                background = helper().backgroundColor( palette.color( QPalette::Button ), widget, r.center() );
 
3873
 
 
3874
                if( hasFocus ) opts |= Focus;
 
3875
                if( mouseOver ) opts |= Hover;
 
3876
 
 
3877
                // adjust opacity and animation mode
 
3878
                qreal opacity( -1 );
 
3879
                AnimationMode mode( AnimationNone );
 
3880
                if( enabled && hoverAnimated )
 
3881
                {
 
3882
 
 
3883
                    opacity = hoverOpacity;
 
3884
                    mode = AnimationHover;
 
3885
 
 
3886
                } else if( enabled && !hasFocus && focusAnimated ) {
 
3887
 
 
3888
                    opacity = focusOpacity;
 
3889
                    mode = AnimationFocus;
 
3890
 
 
3891
                }
 
3892
 
 
3893
                // paint frame
 
3894
                painter->save();
 
3895
                if( reverseLayout )
 
3896
                {
 
3897
 
 
3898
                    QRect frameRect( r.adjusted( 0, 0, 10, 0 ) );
 
3899
                    if( flags & ( State_On|State_Sunken ) ) opts |= Sunken;
 
3900
 
 
3901
                    painter->setClipRect( frameRect.adjusted( 0, 0, -8, 0 ), Qt::IntersectClip );
 
3902
                    renderButtonSlab( painter, frameRect, background, opts, opacity, mode, TileSet::Bottom | TileSet::Top | TileSet::Left );
 
3903
 
 
3904
                } else {
 
3905
 
 
3906
 
 
3907
                    QRect frameRect( r.adjusted( -10,0,0,0 ) );
 
3908
                    if( flags & ( State_On|State_Sunken ) ) opts |= Sunken;
 
3909
 
 
3910
                    painter->setClipRect( frameRect.adjusted( 8, 0, 0, 0 ), Qt::IntersectClip );
 
3911
                    renderButtonSlab( painter, frameRect, background, opts, opacity, mode, TileSet::Bottom | TileSet::Top | TileSet::Right );
 
3912
 
 
3913
                }
 
3914
 
 
3915
                painter->restore();
 
3916
 
 
3917
                // draw separating vertical line
 
3918
                const QColor color( palette.color( QPalette::Button ) );
 
3919
                QColor light =helper().alphaColor( helper().calcLightColor( color ), 0.6 );
 
3920
                QColor dark = helper().calcDarkColor( color );
 
3921
                dark.setAlpha( 200 );
 
3922
 
 
3923
                int yTop( r.top()+2 );
 
3924
                if( sunken ) yTop += 1;
 
3925
 
 
3926
                const int yBottom( r.bottom()-4 );
 
3927
                painter->setPen( QPen( light,1 ) );
 
3928
 
 
3929
                if( reverseLayout )
 
3930
                {
 
3931
 
 
3932
                    painter->drawLine( r.right()+5, yTop+1, r.right()+5, yBottom );
 
3933
                    painter->drawLine( r.right()+3, yTop+2, r.right()+3, yBottom );
 
3934
                    painter->setPen( QPen( dark,1 ) );
 
3935
                    painter->drawLine( r.right()+4, yTop, r.right()+4, yBottom );
 
3936
 
 
3937
                    a.translate( 3, 1 );
 
3938
 
 
3939
                } else {
 
3940
 
 
3941
                    painter->drawLine( r.x()-5, yTop+1, r.x()-5, yBottom-1 );
 
3942
                    painter->drawLine( r.x()-3, yTop+1, r.x()-3, yBottom-1 );
 
3943
                    painter->setPen( QPen( dark,1 ) );
 
3944
                    painter->drawLine( r.x()-4, yTop, r.x()-4, yBottom );
 
3945
 
 
3946
                    a.translate( -3,1 );
 
3947
 
 
3948
                }
 
3949
 
 
3950
            } else if( const QStyleOptionToolButton *tbOption = qstyleoption_cast<const QStyleOptionToolButton *>( option ) ) {
 
3951
 
 
3952
                // handle arrow over animation
 
3953
                const bool arrowHover( enabled && mouseOver && ( tbOption->activeSubControls & SC_ToolButtonMenu ) );
 
3954
                animations().toolButtonEngine().updateState( widget, AnimationHover, arrowHover );
 
3955
 
 
3956
                const bool animated( enabled && animations().toolButtonEngine().isAnimated( widget, AnimationHover ) );
 
3957
                const qreal opacity( animations().toolButtonEngine().opacity( widget, AnimationHover ) );
 
3958
 
 
3959
                if( animated ) color = KColorUtils::mix( color, highlight, opacity );
 
3960
                else if( arrowHover ) color = highlight;
 
3961
                else color = palette.color( autoRaise ? QPalette::WindowText:QPalette::ButtonText );
 
3962
 
 
3963
            }
 
3964
 
 
3965
        } else {
 
3966
 
 
3967
            color = palette.color( autoRaise ? QPalette::WindowText:QPalette::ButtonText );
 
3968
 
 
3969
            // smaller down arrow for menu indication on toolbuttons
 
3970
            penThickness = 1.4;
 
3971
            a = genericArrow( ArrowDown, ArrowSmall );
 
3972
 
 
3973
        }
 
3974
 
 
3975
        painter->translate( r.center() );
 
3976
        painter->setRenderHint( QPainter::Antialiasing );
 
3977
 
 
3978
        // white reflection
 
3979
        const qreal offset( qMin( penThickness, qreal( 1.0 ) ) );
 
3980
        painter->translate( 0,offset );
 
3981
        painter->setPen( QPen( helper().calcLightColor( background ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
3982
        painter->drawPolyline( a );
 
3983
        painter->translate( 0,-offset );
 
3984
 
 
3985
        painter->setPen( QPen( helper().decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
3986
        painter->drawPolyline( a );
 
3987
 
 
3988
        return true;
 
3989
 
 
3990
    }
 
3991
    //___________________________________________________________________________________
 
3992
    bool Style::drawIndicatorCheckBoxPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
3993
    {
 
3994
 
 
3995
        // get rect
 
3996
        const QRect& r( option->rect );
 
3997
        const State& flags( option->state );
 
3998
        const bool enabled( flags & State_Enabled );
 
3999
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
4000
        const bool hasFocus( flags & State_HasFocus );
 
4001
 
 
4002
        StyleOptions opts( 0 );
 
4003
        if( !enabled ) opts |= Disabled;
 
4004
        if( mouseOver ) opts |= Hover;
 
4005
        if( hasFocus ) opts |= Focus;
 
4006
 
 
4007
        // get checkbox state
 
4008
        CheckBoxState state;
 
4009
        if( flags & State_NoChange ) state = CheckTriState;
 
4010
        else if( flags & State_On ) state = CheckOn;
 
4011
        else state = CheckOff;
 
4012
 
 
4013
        // match button color to window background
 
4014
        QPalette palette( option->palette );
 
4015
        palette.setColor(
 
4016
            QPalette::Button,
 
4017
            helper().backgroundColor(
 
4018
            palette.color( QPalette::Button ), widget, r.center() ) );
 
4019
 
 
4020
        // mouseOver has precedence over focus
 
4021
        animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
 
4022
        animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus&&!mouseOver );
 
4023
 
 
4024
        if( enabled && animations().widgetStateEngine().isAnimated( widget, AnimationHover ) )
 
4025
        {
 
4026
 
 
4027
            const qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
 
4028
            renderCheckBox( painter, r, palette, opts, state, opacity, AnimationHover );
 
4029
 
 
4030
        } else if( enabled && !hasFocus && animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) ) {
 
4031
 
 
4032
            const qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );
 
4033
            renderCheckBox( painter, r, palette, opts, state, opacity, AnimationFocus );
 
4034
 
 
4035
        } else renderCheckBox( painter, r, palette, opts, state );
 
4036
 
 
4037
        return true;
 
4038
    }
 
4039
 
 
4040
    //___________________________________________________________________________________
 
4041
    bool Style::drawIndicatorRadioButtonPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4042
    {
 
4043
 
 
4044
        // get rect
 
4045
        const QRect& r( option->rect );
 
4046
        const State& flags( option->state );
 
4047
        const bool enabled( flags & State_Enabled );
 
4048
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
4049
        const bool hasFocus( flags & State_HasFocus );
 
4050
 
 
4051
        StyleOptions opts( 0 );
 
4052
        if( !enabled ) opts |= Disabled;
 
4053
        if( mouseOver ) opts |= Hover;
 
4054
        if( hasFocus ) opts |= Focus;
 
4055
 
 
4056
        // match button color to window background
 
4057
        QPalette palette( option->palette );
 
4058
        palette.setColor( QPalette::Button, helper().backgroundColor( palette.color( QPalette::Button ), widget, r.center() ) );
 
4059
 
 
4060
        // mouseOver has precedence over focus
 
4061
        animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
 
4062
        animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );
 
4063
 
 
4064
        const CheckBoxState state( ( flags & State_On ) ? CheckOn:CheckOff );
 
4065
        if( enabled && animations().widgetStateEngine().isAnimated( widget, AnimationHover ) )
 
4066
        {
 
4067
 
 
4068
            const qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
 
4069
            renderRadioButton( painter, r, palette, opts, state, opacity, AnimationHover );
 
4070
 
 
4071
        } else if(  enabled && animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) ) {
 
4072
 
 
4073
            const qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );
 
4074
            renderRadioButton( painter, r, palette, opts, state, opacity, AnimationFocus );
 
4075
 
 
4076
        } else renderRadioButton( painter, r, palette, opts, state );
 
4077
 
 
4078
        return true;
 
4079
 
 
4080
    }
 
4081
 
 
4082
    //___________________________________________________________________________________
 
4083
    bool Style::drawIndicatorTabTearPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4084
    {
 
4085
 
 
4086
        const QStyleOptionTab* tabOpt( qstyleoption_cast<const QStyleOptionTab*>( option ) );
 
4087
        if( !tabOpt ) return true;
 
4088
 
 
4089
        const QRect& r( option->rect );
 
4090
        const QPalette& palette( option->palette );
 
4091
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
4092
 
 
4093
        // in fact with current version of Qt ( 4.6.0 ) the cast fails and document mode is always false
 
4094
        // this will hopefully be fixed in later versions
 
4095
        const QStyleOptionTabV3* tabOptV3( qstyleoption_cast<const QStyleOptionTabV3*>( option ) );
 
4096
        bool documentMode( tabOptV3 ? tabOptV3->documentMode : false );
 
4097
 
 
4098
        const QTabWidget *tabWidget = ( widget && widget->parentWidget() ) ? qobject_cast<const QTabWidget *>( widget->parentWidget() ) : NULL;
 
4099
        documentMode |= ( tabWidget ? tabWidget->documentMode() : true );
 
4100
 
 
4101
        QRect gradientRect( r );
 
4102
        switch( tabOpt->shape )
 
4103
        {
 
4104
 
 
4105
            case QTabBar::TriangularNorth:
 
4106
            case QTabBar::RoundedNorth:
 
4107
            gradientRect.adjust( 0, 0, 0, -5 );
 
4108
            if( !reverseLayout ) gradientRect.translate( -GlowWidth,0 );
 
4109
            break;
 
4110
 
 
4111
            case QTabBar::TriangularSouth:
 
4112
            case QTabBar::RoundedSouth:
 
4113
            gradientRect.adjust( 0, 5, 0, 0 );
 
4114
            if( !reverseLayout ) gradientRect.translate( -GlowWidth,0 );
 
4115
            break;
 
4116
 
 
4117
            case QTabBar::TriangularWest:
 
4118
            case QTabBar::RoundedWest:
 
4119
            gradientRect.adjust( 0, 0, -5, 0 );
 
4120
            gradientRect.translate( 0,-GlowWidth );
 
4121
            break;
 
4122
 
 
4123
            case QTabBar::TriangularEast:
 
4124
            case QTabBar::RoundedEast:
 
4125
            gradientRect.adjust( 5, 0, 0, 0 );
 
4126
            gradientRect.translate( 0,-GlowWidth );
 
4127
            break;
 
4128
 
 
4129
            default: return true;
 
4130
        }
 
4131
 
 
4132
        // fade tabbar
 
4133
        QPixmap pm( gradientRect.size() );
 
4134
        pm.fill( Qt::transparent );
 
4135
        QPainter pp( &pm );
 
4136
 
 
4137
        const bool verticalTabs( isVerticalTab( tabOpt ) );
 
4138
 
 
4139
        int w = 0, h = 0;
 
4140
        if( verticalTabs ) h = gradientRect.height();
 
4141
        else w = gradientRect.width();
 
4142
 
 
4143
        QLinearGradient grad;
 
4144
        if( reverseLayout && !verticalTabs ) grad = QLinearGradient( 0, 0, w, h );
 
4145
        else grad = QLinearGradient( w, h, 0, 0 );
 
4146
 
 
4147
        grad.setColorAt( 0, Qt::transparent );
 
4148
        grad.setColorAt( 0.6, Qt::black );
 
4149
 
 
4150
        helper().renderWindowBackground( &pp, pm.rect(), widget, palette );
 
4151
        pp.setCompositionMode( QPainter::CompositionMode_DestinationAtop );
 
4152
        pp.fillRect( pm.rect(), QBrush( grad ) );
 
4153
        pp.end();
 
4154
 
 
4155
        // draw pixmap
 
4156
        painter->drawPixmap( gradientRect.topLeft()+QPoint( 0,-1 ),pm );
 
4157
 
 
4158
        return true;
 
4159
    }
 
4160
 
 
4161
    //___________________________________________________________________________________
 
4162
    bool Style::drawIndicatorToolBarHandlePrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
4163
    {
 
4164
        const State& flags( option->state );
 
4165
        const bool horizontal( flags & State_Horizontal );
 
4166
        const QRect& r( option->rect );
 
4167
        const QPalette& palette( option->palette );
 
4168
        int counter( 1 );
 
4169
 
 
4170
        if( horizontal )
 
4171
        {
 
4172
 
 
4173
            const int center( r.left()+r.width()/2 );
 
4174
            for( int j = r.top()+2; j <= r.bottom()-3; j+=3, ++counter )
 
4175
            {
 
4176
                if( counter%2 == 0 ) helper().renderDot( painter, QPoint( center+1, j ), palette.color( QPalette::Background ) );
 
4177
                else helper().renderDot( painter, QPoint( center-2, j ), palette.color( QPalette::Background ) );
 
4178
            }
 
4179
 
 
4180
        } else {
 
4181
 
 
4182
            const int center( r.top()+r.height()/2 );
 
4183
            for( int j = r.left()+2; j <= r.right()-3; j+=3, ++counter )
 
4184
            {
 
4185
                if( counter%2 == 0 ) helper().renderDot( painter, QPoint( j, center+1 ), palette.color( QPalette::Background ) );
 
4186
                else helper().renderDot( painter, QPoint( j, center-2 ), palette.color( QPalette::Background ) );
 
4187
            }
 
4188
        }
 
4189
 
 
4190
        return true;
 
4191
 
 
4192
    }
 
4193
 
 
4194
    //___________________________________________________________________________________
 
4195
    bool Style::drawIndicatorToolBarSeparatorPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
4196
    {
 
4197
 
 
4198
        const State& flags( option->state );
 
4199
        const QRect& r( option->rect );
 
4200
        const QPalette& palette( option->palette );
 
4201
        if( StyleConfigData::toolBarDrawItemSeparator() )
 
4202
        {
 
4203
            const QColor color( palette.color( QPalette::Window ) );
 
4204
            if( flags & State_Horizontal ) helper().drawSeparator( painter, r, color, Qt::Vertical );
 
4205
            else helper().drawSeparator( painter, r, color, Qt::Horizontal );
 
4206
        }
 
4207
 
 
4208
        return true;
 
4209
    }
 
4210
 
 
4211
    //___________________________________________________________________________________
 
4212
    bool Style::drawWidgetPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4213
    {
 
4214
 
 
4215
        // check widget and attributes
 
4216
        if( !widget || !widget->testAttribute( Qt::WA_StyledBackground ) || widget->testAttribute( Qt::WA_NoSystemBackground ) ) return false;
 
4217
        if( !( ( widget->windowFlags() & Qt::WindowType_Mask ) & ( Qt::Window|Qt::Dialog ) ) ) return false;
 
4218
        if( !widget->isWindow() ) return false;
 
4219
 
 
4220
        // normal "window" background
 
4221
        const QPalette& palette( option->palette );
 
4222
 
 
4223
        // do not render background if palette brush has a texture (pixmap or image)
 
4224
        const QBrush brush( palette.brush( widget->backgroundRole() ) );
 
4225
        if( !( brush.texture().isNull() && brush.textureImage().isNull() ) )
 
4226
        { return false; }
 
4227
 
 
4228
        helper().renderWindowBackground( painter, option->rect, widget, palette );
 
4229
        return true;
 
4230
 
 
4231
    }
 
4232
 
 
4233
    //___________________________________________________________________________________
 
4234
    bool Style::drawCapacityBarControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4235
    {
 
4236
 
 
4237
        // cast option
 
4238
        const QStyleOptionProgressBar* cbOption( qstyleoption_cast<const QStyleOptionProgressBar*>( option ) );
 
4239
        if( !cbOption ) return true;
 
4240
 
 
4241
        // draw container
 
4242
        QStyleOptionProgressBarV2 sub_opt( *cbOption );
 
4243
        sub_opt.rect = subElementRect( QStyle::SE_ProgressBarGroove, cbOption, widget );
 
4244
        drawProgressBarGrooveControl( &sub_opt, painter, widget );
 
4245
 
 
4246
        // draw bar
 
4247
        sub_opt.rect = subElementRect( QStyle::SE_ProgressBarContents, cbOption, widget );
 
4248
        drawProgressBarContentsControl( &sub_opt, painter, widget );
 
4249
 
 
4250
        // draw label
 
4251
        sub_opt.rect = subElementRect( QStyle::SE_ProgressBarLabel, cbOption, widget );
 
4252
        drawProgressBarLabelControl( &sub_opt, painter, widget );
 
4253
 
 
4254
        return true;
 
4255
 
 
4256
    }
 
4257
 
 
4258
    //___________________________________________________________________________________
 
4259
    bool Style::drawComboBoxLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4260
    {
 
4261
 
 
4262
        //same as CommonStyle, except for filling behind icon
 
4263
        if( const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>( option ) )
 
4264
        {
 
4265
 
 
4266
            QRect editRect( subControlRect( CC_ComboBox, cb, SC_ComboBoxEditField, widget ) );
 
4267
 
 
4268
            painter->save();
 
4269
            if( !cb->currentIcon.isNull() )
 
4270
            {
 
4271
 
 
4272
                QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
 
4273
                QPixmap pixmap( cb->currentIcon.pixmap( cb->iconSize, mode ) );
 
4274
                QRect iconRect( editRect );
 
4275
                iconRect.setWidth( cb->iconSize.width() + 4 );
 
4276
                iconRect = alignedRect(
 
4277
                    cb->direction,
 
4278
                    Qt::AlignLeft | Qt::AlignVCenter,
 
4279
                    iconRect.size(), editRect );
 
4280
 
 
4281
                drawItemPixmap( painter, iconRect, Qt::AlignCenter, pixmap );
 
4282
 
 
4283
                if( cb->direction == Qt::RightToLeft ) editRect.translate( -4 - cb->iconSize.width(), 0 );
 
4284
                else editRect.translate( cb->iconSize.width() + 4, 0 );
 
4285
            }
 
4286
 
 
4287
            if( !cb->currentText.isEmpty() && !cb->editable )
 
4288
            {
 
4289
                const bool& hasFrame( cb->frame );
 
4290
                const QPalette::ColorRole role( hasFrame ? QPalette::ButtonText : QPalette::WindowText );
 
4291
                drawItemText(
 
4292
                    painter, editRect.adjusted( 1, 0, -1, 0 ),
 
4293
                    visualAlignment( cb->direction, Qt::AlignLeft | Qt::AlignVCenter ),
 
4294
                    cb->palette, cb->state & State_Enabled, cb->currentText, role );
 
4295
            }
 
4296
            painter->restore();
 
4297
            return true;
 
4298
 
 
4299
        } else return false;
 
4300
 
 
4301
    }
 
4302
 
 
4303
    //___________________________________________________________________________________
 
4304
    bool Style::drawDockWidgetTitleControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4305
    {
 
4306
 
 
4307
        // cast option and check
 
4308
        const QStyleOptionDockWidget* dwOpt = ::qstyleoption_cast<const QStyleOptionDockWidget*>( option );
 
4309
        if ( !dwOpt ) return true;
 
4310
 
 
4311
        const QPalette& palette( option->palette );
 
4312
        const State& flags( option->state );
 
4313
        const bool enabled( flags & State_Enabled );
 
4314
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
4315
 
 
4316
        // cast to v2 to check vertical bar
 
4317
        const QStyleOptionDockWidgetV2 *v2 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>( option );
 
4318
        const bool verticalTitleBar( v2 ? v2->verticalTitleBar : false );
 
4319
 
 
4320
        const QRect btnr( subElementRect( dwOpt->floatable ? SE_DockWidgetFloatButton : SE_DockWidgetCloseButton, option, widget ) );
 
4321
 
 
4322
        // get rectangle and adjust to properly accounts for buttons
 
4323
        QRect r( insideMargin( dwOpt->rect, DockWidget_TitleMargin ) );
 
4324
        if( verticalTitleBar )
 
4325
        {
 
4326
 
 
4327
            if( btnr.isValid() ) r.setTop( btnr.bottom()+1 );
 
4328
 
 
4329
        } else if( reverseLayout ) {
 
4330
 
 
4331
            if( btnr.isValid() ) r.setLeft( btnr.right()+1 );
 
4332
            r.adjust( 0,0,-4,0 );
 
4333
 
 
4334
        } else {
 
4335
 
 
4336
            if( btnr.isValid() ) r.setRight( btnr.left()-1 );
 
4337
            r.adjust( 4,0,0,0 );
 
4338
 
 
4339
        }
 
4340
 
 
4341
        QString title( dwOpt->title );
 
4342
        QString tmpTitle = title;
 
4343
 
 
4344
        // this is quite suboptimal
 
4345
        // and does not really work
 
4346
        if( tmpTitle.contains( "&" ) )
 
4347
        {
 
4348
            int pos = tmpTitle.indexOf( "&" );
 
4349
            if( !( tmpTitle.size()-1 > pos && tmpTitle.at( pos+1 ) == QChar( '&' ) ) ) tmpTitle.remove( pos, 1 );
 
4350
 
 
4351
        }
 
4352
 
 
4353
        int tw = dwOpt->fontMetrics.width( tmpTitle );
 
4354
        int width = verticalTitleBar ? r.height() : r.width();
 
4355
        if( width < tw ) title = dwOpt->fontMetrics.elidedText( title, Qt::ElideRight, width, Qt::TextShowMnemonic );
 
4356
 
 
4357
        if( verticalTitleBar )
 
4358
        {
 
4359
 
 
4360
            QSize s = r.size();
 
4361
            s.transpose();
 
4362
            r.setSize( s );
 
4363
 
 
4364
            painter->save();
 
4365
            painter->translate( r.left(), r.top() + r.width() );
 
4366
            painter->rotate( -90 );
 
4367
            painter->translate( -r.left(), -r.top() );
 
4368
            drawItemText( painter, r, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette, enabled, title, QPalette::WindowText );
 
4369
            painter->restore();
 
4370
 
 
4371
 
 
4372
        } else {
 
4373
 
 
4374
            drawItemText( painter, r, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette, enabled, title, QPalette::WindowText );
 
4375
 
 
4376
        }
 
4377
 
 
4378
        return true;
 
4379
 
 
4380
 
 
4381
    }
 
4382
 
 
4383
    //___________________________________________________________________________________
 
4384
    bool Style::drawHeaderEmptyAreaControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4385
    {
 
4386
 
 
4387
        // use the same background as in drawHeaderPrimitive
 
4388
        QPalette palette( option->palette );
 
4389
 
 
4390
        if( widget && animations().widgetEnabilityEngine().isAnimated( widget, AnimationEnable ) )
 
4391
        { palette = helper().mergePalettes( palette, animations().widgetEnabilityEngine().opacity( widget, AnimationEnable )  ); }
 
4392
 
 
4393
        const bool horizontal( option->state & QStyle::State_Horizontal );
 
4394
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
4395
        renderHeaderBackground( option->rect, palette, painter, widget, horizontal, reverseLayout );
 
4396
 
 
4397
        return true;
 
4398
 
 
4399
    }
 
4400
 
 
4401
    //___________________________________________________________________________________
 
4402
    bool Style::drawHeaderLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
4403
    {
 
4404
        const QStyleOptionHeader* headerOpt( qstyleoption_cast<const QStyleOptionHeader *>( option ) );
 
4405
        if( !headerOpt ) return true;
 
4406
 
 
4407
        QRect rect( headerOpt->rect );
 
4408
 
 
4409
        if ( !headerOpt->icon.isNull() )
 
4410
        {
 
4411
            const QPixmap pixmap( headerOpt->icon.pixmap(
 
4412
                pixelMetric( PM_SmallIconSize ),
 
4413
                ( headerOpt->state & State_Enabled ) ? QIcon::Normal : QIcon::Disabled ) );
 
4414
 
 
4415
            int pixw = pixmap.width();
 
4416
 
 
4417
            QRect aligned = alignedRect( headerOpt->direction, QFlag( headerOpt->iconAlignment ), pixmap.size(), rect );
 
4418
            QRect inter = aligned.intersected( rect );
 
4419
            painter->drawPixmap( inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height() );
 
4420
 
 
4421
            if ( headerOpt->direction == Qt::LeftToRight ) rect.setLeft( rect.left() + pixw + 2 );
 
4422
            else rect.setRight( rect.right() - pixw - 2 );
 
4423
 
 
4424
        }
 
4425
 
 
4426
        drawItemText(
 
4427
            painter, rect, headerOpt->textAlignment, headerOpt->palette,
 
4428
            ( headerOpt->state & State_Enabled ), headerOpt->text, QPalette::WindowText );
 
4429
 
 
4430
        return true;
 
4431
    }
 
4432
 
 
4433
    //___________________________________________________________________________________
 
4434
    bool Style::drawHeaderSectionControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4435
    {
 
4436
 
 
4437
        const QRect& r( option->rect );
 
4438
        const QPalette& palette( option->palette );
 
4439
 
 
4440
        const QStyleOptionHeader* headerOpt( qstyleoption_cast<const QStyleOptionHeader *>( option ) );
 
4441
        if( !headerOpt ) return true;
 
4442
 
 
4443
        const bool horizontal( headerOpt->orientation == Qt::Horizontal );
 
4444
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
4445
        const bool isFirst( horizontal && ( headerOpt->position == QStyleOptionHeader::Beginning ) );
 
4446
        const bool isCorner( widget && widget->inherits( "QTableCornerButton" ) );
 
4447
 
 
4448
        // corner header lines
 
4449
        if( isCorner )
 
4450
        {
 
4451
 
 
4452
            if( widget ) helper().renderWindowBackground( painter, r, widget, palette );
 
4453
            else painter->fillRect( r, palette.color( QPalette::Window ) );
 
4454
            if( reverseLayout ) renderHeaderLines( r, palette, painter, TileSet::BottomLeft );
 
4455
            else renderHeaderLines( r, palette, painter, TileSet::BottomRight );
 
4456
 
 
4457
        } else renderHeaderBackground( r, palette, painter, widget, horizontal, reverseLayout );
 
4458
 
 
4459
        // dots
 
4460
        const QColor color( palette.color( QPalette::Window ) );
 
4461
        if( horizontal )
 
4462
        {
 
4463
 
 
4464
            if( headerOpt->section != 0 || isFirst )
 
4465
            {
 
4466
                const int center( r.center().y() );
 
4467
                const int pos( reverseLayout ? r.left()+1 : r.right()-1 );
 
4468
                helper().renderDot( painter, QPoint( pos, center-3 ), color );
 
4469
                helper().renderDot( painter, QPoint( pos, center ), color );
 
4470
                helper().renderDot( painter, QPoint( pos, center+3 ), color );
 
4471
            }
 
4472
 
 
4473
        } else {
 
4474
 
 
4475
            const int center( r.center().x() );
 
4476
            const int pos( r.bottom()-1 );
 
4477
            helper().renderDot( painter, QPoint( center-3, pos ), color );
 
4478
            helper().renderDot( painter, QPoint( center, pos ), color );
 
4479
            helper().renderDot( painter, QPoint( center+3, pos ), color );
 
4480
 
 
4481
        }
 
4482
 
 
4483
        return true;
 
4484
 
 
4485
    }
 
4486
 
 
4487
    //___________________________________________________________________________________
 
4488
    bool Style::drawMenuBarItemControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4489
    {
 
4490
 
 
4491
        const QStyleOptionMenuItem* menuOpt = ::qstyleoption_cast<const QStyleOptionMenuItem*>( option );
 
4492
        if ( !menuOpt ) return true;
 
4493
 
 
4494
        const State& flags( option->state );
 
4495
        const bool enabled( flags & State_Enabled );
 
4496
 
 
4497
        const QRect& r( option->rect );
 
4498
        const QPalette& palette( option->palette );
 
4499
 
 
4500
        if( enabled )
 
4501
        {
 
4502
            const bool active( flags & State_Selected );
 
4503
            const bool animated( animations().menuBarEngine().isAnimated( widget, r.topLeft() ) );
 
4504
            const qreal opacity( animations().menuBarEngine().opacity( widget, r.topLeft() ) );
 
4505
            const QRect currentRect( animations().menuBarEngine().currentRect( widget, r.topLeft() ) );
 
4506
            const QRect animatedRect( animations().menuBarEngine().animatedRect( widget ) );
 
4507
 
 
4508
            const bool intersected( animatedRect.intersects( r ) );
 
4509
            const bool current( currentRect.contains( r.topLeft() ) );
 
4510
            const bool timerIsActive( animations().menuBarEngine().isTimerActive( widget ) );
 
4511
 
 
4512
            // do nothing in case of empty intersection between animated rect and current
 
4513
            if( ( intersected || !animated || animatedRect.isNull() ) && ( active || animated || timerIsActive ) )
 
4514
            {
 
4515
 
 
4516
                QColor color( helper().calcMidColor( palette.color( QPalette::Window ) ) );
 
4517
                if( StyleConfigData::menuHighlightMode() != StyleConfigData::MM_DARK )
 
4518
                {
 
4519
 
 
4520
                    if( flags & State_Sunken )
 
4521
                    {
 
4522
 
 
4523
                        if( StyleConfigData::menuHighlightMode() == StyleConfigData::MM_STRONG ) color = palette.color( QPalette::Highlight );
 
4524
                        else color = KColorUtils::mix( color, KColorUtils::tint( color, palette.color( QPalette::Highlight ), 0.6 ) );
 
4525
 
 
4526
                    } else {
 
4527
 
 
4528
                        if( StyleConfigData::menuHighlightMode() == StyleConfigData::MM_STRONG ) color = KColorUtils::tint( color, helper().viewHoverBrush().brush( palette ).color() );
 
4529
                        else color = KColorUtils::mix( color, KColorUtils::tint( color, helper().viewHoverBrush().brush( palette ).color() ) );
 
4530
                    }
 
4531
 
 
4532
                } else color = helper().backgroundColor( color, widget, r.center() );
 
4533
 
 
4534
                // drawing
 
4535
                if( animated && intersected )
 
4536
                {
 
4537
 
 
4538
                    helper().holeFlat( color, 0.0 )->render( animatedRect.adjusted( 1,1,-1,-1 ), painter, TileSet::Full );
 
4539
 
 
4540
                } else if( timerIsActive && current ) {
 
4541
 
 
4542
                    helper().holeFlat( color, 0.0 )->render( r.adjusted( 1,1,-1,-1 ), painter, TileSet::Full );
 
4543
 
 
4544
                } else if( animated && current ) {
 
4545
 
 
4546
                    color.setAlphaF( opacity );
 
4547
                    helper().holeFlat( color, 0.0 )->render( r.adjusted( 1,1,-1,-1 ), painter, TileSet::Full );
 
4548
 
 
4549
                } else if( active ) {
 
4550
 
 
4551
                    helper().holeFlat( color, 0.0 )->render( r.adjusted( 1,1,-1,-1 ), painter, TileSet::Full );
 
4552
 
 
4553
                }
 
4554
 
 
4555
            }
 
4556
 
 
4557
        }
 
4558
 
 
4559
        // text
 
4560
        QPalette::ColorRole role( QPalette::WindowText );
 
4561
        if( StyleConfigData::menuHighlightMode() == StyleConfigData::MM_STRONG && ( flags & State_Sunken ) && enabled )
 
4562
        { role = QPalette::HighlightedText; }
 
4563
 
 
4564
        drawItemText( painter, r, Qt::AlignCenter | Qt::TextShowMnemonic, palette, enabled, menuOpt->text, role );
 
4565
 
 
4566
        return true;
 
4567
 
 
4568
    }
 
4569
 
 
4570
    //___________________________________________________________________________________
 
4571
    bool Style::drawMenuItemControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4572
    {
 
4573
        const QRect& r( option->rect );
 
4574
        const QPalette& palette( option->palette );
 
4575
        const State& flags( option->state );
 
4576
        const bool active( flags & State_Selected );
 
4577
        const bool enabled( flags & State_Enabled );
 
4578
        const bool hasFocus( enabled && ( flags & State_HasFocus ) );
 
4579
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
4580
 
 
4581
        //First of all,render the background.
 
4582
        renderMenuItemBackground( option, painter, widget );
 
4583
 
 
4584
        // do nothing if invalid option, or empty area
 
4585
        const QStyleOptionMenuItem* menuItemOption = qstyleoption_cast<const QStyleOptionMenuItem*>( option );
 
4586
        if( !menuItemOption || menuItemOption->menuItemType == QStyleOptionMenuItem::EmptyArea ) return true;
 
4587
 
 
4588
        //First, figure out the left column width.
 
4589
        const int iconColW = qMax( menuItemOption->maxIconWidth, ( int )MenuItem_IconWidth );
 
4590
        const int checkColW = MenuItem_CheckWidth;
 
4591
        const int checkSpace = MenuItem_CheckSpace;
 
4592
 
 
4593
        int leftColW = iconColW;
 
4594
 
 
4595
        // only use the additional check row if the menu has checkable menuItems.
 
4596
        bool hasCheckableItems = menuItemOption->menuHasCheckableItems;
 
4597
        if( hasCheckableItems ) leftColW += checkColW + checkSpace;
 
4598
 
 
4599
        // right arrow column...
 
4600
        int rightColW = MenuItem_ArrowSpace + MenuItem_ArrowWidth;
 
4601
 
 
4602
        //Separators: done with the bg, can paint them and bail them out.
 
4603
        if( menuItemOption->menuItemType == QStyleOptionMenuItem::Separator )
 
4604
        {
 
4605
            // check text and icon
 
4606
            // separators with non empty text are rendered as checked toolbuttons
 
4607
            if( !menuItemOption->text.isEmpty() )
 
4608
            {
 
4609
 
 
4610
                QStyleOptionToolButton toolButtonOpt;
 
4611
                toolButtonOpt.features = QStyleOptionToolButton::None;
 
4612
                toolButtonOpt.state = State_On|State_Sunken|State_Enabled;
 
4613
                toolButtonOpt.rect = r.adjusted( 0, 0, 0, 1 );
 
4614
                toolButtonOpt.subControls = SC_ToolButton;
 
4615
                toolButtonOpt.icon =  menuItemOption->icon;
 
4616
 
 
4617
                toolButtonOpt.font = widget->font();
 
4618
                toolButtonOpt.font.setBold( true );
 
4619
 
 
4620
                toolButtonOpt.iconSize = QSize(
 
4621
                    pixelMetric( QStyle::PM_SmallIconSize,0,0 ),
 
4622
                    pixelMetric( QStyle::PM_SmallIconSize,0,0 ) );
 
4623
 
 
4624
                // for now menu size is not calculated properly
 
4625
                // ( meaning it doesn't account for titled separators width
 
4626
                // as a fallback, we elide the text to be displayed
 
4627
                int width( r.width() );
 
4628
                if( !menuItemOption->icon.isNull() )
 
4629
                { width -= toolButtonOpt.iconSize.width() + 2; }
 
4630
                width -= 2*ToolButton_ContentsMargin;
 
4631
                toolButtonOpt.text = QFontMetrics( toolButtonOpt.font ).elidedText( menuItemOption->text, Qt::ElideRight, width );
 
4632
 
 
4633
                toolButtonOpt.toolButtonStyle = Qt::ToolButtonTextBesideIcon;
 
4634
                drawToolButtonComplexControl( &toolButtonOpt, painter, widget );
 
4635
                return true;
 
4636
 
 
4637
            } else {
 
4638
 
 
4639
                // in all other cases draw regular separator
 
4640
                const QColor color( helper().menuBackgroundColor( palette.color( QPalette::Window ), widget, r.center() ) );
 
4641
                helper().drawSeparator( painter, r, color, Qt::Horizontal );
 
4642
                return true;
 
4643
 
 
4644
            }
 
4645
 
 
4646
        }
 
4647
 
 
4648
        //Remove the margin ( for everything but the column background )
 
4649
        const QRect ir( insideMargin( r, MenuItem_Margin ) );
 
4650
 
 
4651
        //Active indicator...
 
4652
        if( active && enabled )
 
4653
        {
 
4654
 
 
4655
            // check if there is a 'sliding' animation in progress, in which case, do nothing
 
4656
            const QRect animatedRect( animations().menuEngine().animatedRect( widget ) );
 
4657
            if( animatedRect.isNull() )
 
4658
            {
 
4659
 
 
4660
                const bool animated( animations().menuEngine().isAnimated( widget, Current ) );
 
4661
                const QRect currentRect( animations().menuEngine().currentRect( widget, Current ) );
 
4662
                const bool intersected( currentRect.contains( r.topLeft() ) );
 
4663
 
 
4664
                const QColor color( helper().menuBackgroundColor( helper().calcMidColor( palette.color( QPalette::Window ) ), widget, r.center() ) );
 
4665
 
 
4666
                if( animated && intersected ) renderMenuItemRect( option, r, color, palette, painter, animations().menuEngine().opacity( widget, Current ) );
 
4667
                else renderMenuItemRect( option, r, color, palette, painter );
 
4668
 
 
4669
            }
 
4670
 
 
4671
        }
 
4672
 
 
4673
        // color
 
4674
        QPalette::ColorRole textRole( ( active && enabled && StyleConfigData::menuHighlightMode() == StyleConfigData::MM_STRONG ) ?
 
4675
            QPalette::HighlightedText:
 
4676
            QPalette::WindowText );
 
4677
 
 
4678
        //Readjust the column rectangle back to proper height
 
4679
        QRect leftColRect( ir.x(), ir.y(), leftColW, ir.height() );
 
4680
 
 
4681
        // paint a normal check- resp. radiomark.
 
4682
        const QRect checkColRect(
 
4683
            leftColRect.x(), leftColRect.y(),
 
4684
            checkColW, leftColRect.height() );
 
4685
 
 
4686
        const CheckBoxState checkBoxState( menuItemOption->checked ? CheckOn:CheckOff );
 
4687
        if( menuItemOption->checkType == QStyleOptionMenuItem::NonExclusive )
 
4688
        {
 
4689
 
 
4690
            StyleOptions opts( 0 );
 
4691
            opts |= Sunken;
 
4692
            if( !enabled ) opts |= Disabled;
 
4693
            if( mouseOver ) opts |= Hover;
 
4694
            if( hasFocus ) opts |= Focus;
 
4695
 
 
4696
            const QRect r( handleRTL( option, checkColRect ) );
 
4697
            QPalette localPalette( palette );
 
4698
            localPalette.setColor( QPalette::Window, helper().menuBackgroundColor( palette.color( QPalette::Window ), widget, r.topLeft() ) );
 
4699
            renderCheckBox( painter, r.adjusted( 2,-2,2,2 ), localPalette, opts, checkBoxState );
 
4700
 
 
4701
        } else if( menuItemOption->checkType == QStyleOptionMenuItem::Exclusive ) {
 
4702
 
 
4703
            StyleOptions opts( 0 );
 
4704
            if( !enabled ) opts |= Disabled;
 
4705
            if( mouseOver ) opts |= Hover;
 
4706
            if( hasFocus ) opts |= Focus;
 
4707
 
 
4708
            const QRect r( handleRTL( option, checkColRect ) );
 
4709
            QPalette localPalette( palette );
 
4710
            localPalette.setColor( QPalette::Window, helper().menuBackgroundColor( palette.color( QPalette::Window ), widget, r.topLeft() ) );
 
4711
            renderRadioButton( painter, r.adjusted( 2,-2,2,2 ), localPalette, opts, checkBoxState );
 
4712
 
 
4713
        }
 
4714
 
 
4715
        // Paint the menu icon.
 
4716
        if( !menuItemOption->icon.isNull() )
 
4717
        {
 
4718
 
 
4719
            QRect iconColRect;
 
4720
 
 
4721
            if( hasCheckableItems )
 
4722
            {
 
4723
 
 
4724
                iconColRect = QRect(
 
4725
                    leftColRect.x()+checkColW+checkSpace, leftColRect.y(),
 
4726
                    leftColRect.width()-( checkColW+checkSpace ), leftColRect.height() );
 
4727
 
 
4728
            } else iconColRect = leftColRect;
 
4729
 
 
4730
            // icon mode
 
4731
            QIcon::Mode mode;
 
4732
            if( enabled ) mode = active ? QIcon::Active: QIcon::Normal;
 
4733
            else mode = QIcon::Disabled;
 
4734
 
 
4735
            // icon state
 
4736
            const QIcon::State iconState(
 
4737
                ( ( flags & State_On ) || ( flags & State_Sunken ) ) ?
 
4738
                QIcon::On:QIcon::Off );
 
4739
 
 
4740
            // icon size
 
4741
            const QSize size( pixelMetric( PM_SmallIconSize ), pixelMetric( PM_SmallIconSize ) );
 
4742
            const QRect r( handleRTL( option, centerRect( iconColRect, size ) ) );
 
4743
            const QPixmap icon = menuItemOption->icon.pixmap( size, mode, iconState );
 
4744
            painter->drawPixmap( centerRect( r, size ), icon );
 
4745
 
 
4746
        }
 
4747
 
 
4748
 
 
4749
        //Now include the spacing when calculating the next columns
 
4750
        leftColW += MenuItem_IconSpace;
 
4751
 
 
4752
        //Render the text, including any accel.
 
4753
        QString text = menuItemOption->text;
 
4754
        const QRect textRect( handleRTL( option, QRect( ir.x() + leftColW, ir.y(), ir.width() - leftColW - rightColW, ir.height() ) ) );
 
4755
 
 
4756
        painter->setFont( menuItemOption->font );
 
4757
 
 
4758
        int tabPos = menuItemOption->text.indexOf( QLatin1Char( '\t' ) );
 
4759
        if( tabPos != -1 )
 
4760
        {
 
4761
 
 
4762
            text = menuItemOption->text.left( tabPos );
 
4763
            QString accl = menuItemOption->text.mid( tabPos + 1 );
 
4764
 
 
4765
            drawItemText(
 
4766
                painter, textRect, Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::AlignRight, palette,
 
4767
                enabled, accl, textRole );
 
4768
 
 
4769
        }
 
4770
 
 
4771
        //Draw the text.
 
4772
        drawItemText(
 
4773
            painter, textRect, Qt::AlignVCenter | Qt::TextShowMnemonic, palette,
 
4774
            enabled, text, textRole );
 
4775
 
 
4776
        //Render arrow, if need be.
 
4777
        if( menuItemOption->menuItemType == QStyleOptionMenuItem::SubMenu )
 
4778
        {
 
4779
 
 
4780
            const qreal penThickness = 1.6;
 
4781
            const QColor color = palette.color( textRole );
 
4782
            const QColor background = palette.color( QPalette::Window );
 
4783
 
 
4784
            const int aw = MenuItem_ArrowWidth;
 
4785
            QRect arrowRect = handleRTL( option, QRect( ir.x() + ir.width() - aw, ir.y(), aw, ir.height() ) );
 
4786
 
 
4787
            // get arrow shape
 
4788
            QPolygonF a = genericArrow( option->direction == Qt::LeftToRight ? ArrowRight : ArrowLeft, ArrowNormal );
 
4789
 
 
4790
            painter->translate( arrowRect.center() );
 
4791
            painter->setRenderHint( QPainter::Antialiasing );
 
4792
 
 
4793
            // white reflection
 
4794
            const qreal offset( qMin( penThickness, qreal( 1.0 ) ) );
 
4795
            painter->translate( 0,offset );
 
4796
            painter->setPen( QPen( helper().calcLightColor( background ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
4797
            painter->drawPolyline( a );
 
4798
            painter->translate( 0,-offset );
 
4799
 
 
4800
            painter->setPen( QPen( helper().decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
4801
            painter->drawPolyline( a );
 
4802
 
 
4803
 
 
4804
        }
 
4805
 
 
4806
        return true;
 
4807
    }
 
4808
 
 
4809
    //___________________________________________________________________________________
 
4810
    bool Style::drawProgressBarControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4811
    {
 
4812
 
 
4813
        if( const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>( option ) )
 
4814
        {
 
4815
 
 
4816
            // same as QCommonStyle::drawControl, except that it handles animations
 
4817
            QStyleOptionProgressBarV2 subopt = *pb;
 
4818
            subopt.rect = subElementRect( SE_ProgressBarGroove, pb, widget );
 
4819
            drawProgressBarGrooveControl( &subopt, painter, widget );
 
4820
 
 
4821
            if( animations().progressBarEngine().busyIndicatorEnabled() && pb->maximum == 0 && pb->minimum == 0 )
 
4822
            { animations().progressBarEngine().startBusyTimer(); }
 
4823
 
 
4824
            if( animations().progressBarEngine().isAnimated( widget ) )
 
4825
            { subopt.progress = animations().progressBarEngine().value( widget ); }
 
4826
 
 
4827
            subopt.rect = subElementRect( SE_ProgressBarContents, &subopt, widget );
 
4828
            drawProgressBarContentsControl( &subopt, painter, widget );
 
4829
 
 
4830
            if( pb->textVisible )
 
4831
            {
 
4832
                subopt.rect = subElementRect( SE_ProgressBarLabel, pb, widget );
 
4833
                drawProgressBarLabelControl( &subopt, painter, widget );
 
4834
            }
 
4835
 
 
4836
        }
 
4837
 
 
4838
        return true;
 
4839
 
 
4840
    }
 
4841
 
 
4842
    //___________________________________________________________________________________
 
4843
    bool Style::drawProgressBarContentsControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
4844
    {
 
4845
 
 
4846
        const QStyleOptionProgressBar* pbOpt = qstyleoption_cast<const QStyleOptionProgressBar*>( option );
 
4847
        if ( !pbOpt ) return true;
 
4848
 
 
4849
        const QStyleOptionProgressBarV2* pbOpt2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>( option );
 
4850
 
 
4851
        const QRect& r( option->rect );
 
4852
        const QPalette& palette( option->palette );
 
4853
 
 
4854
        // check if anything is to be drawn
 
4855
        qreal progress = pbOpt->progress - pbOpt->minimum;
 
4856
        const bool busyIndicator = ( pbOpt->minimum == 0 && pbOpt->maximum == 0 );
 
4857
        if( busyIndicator && widget )
 
4858
        {
 
4859
            // load busy value from widget property
 
4860
            QVariant busyValue( widget->property( ProgressBarEngine::busyValuePropertyName ) );
 
4861
            if( busyValue.isValid() ) progress = busyValue.toReal();
 
4862
        }
 
4863
 
 
4864
        if( !( progress || busyIndicator ) ) return true;
 
4865
 
 
4866
        const int steps = qMax( pbOpt->maximum  - pbOpt->minimum, 1 );
 
4867
        const bool horizontal = !pbOpt2 || pbOpt2->orientation == Qt::Horizontal;
 
4868
 
 
4869
        //Calculate width fraction
 
4870
        qreal widthFrac( busyIndicator ?  ProgressBar_BusyIndicatorSize/100.0 : progress/steps );
 
4871
        widthFrac = qMin( (qreal)1.0, widthFrac );
 
4872
 
 
4873
        // And now the pixel width
 
4874
        const int indicatorSize( widthFrac*( horizontal ? r.width():r.height() ) );
 
4875
 
 
4876
        // do nothing if indicator size is too small
 
4877
        if( indicatorSize < 4 ) return true;
 
4878
 
 
4879
        QRect indicatorRect;
 
4880
        if ( busyIndicator )
 
4881
        {
 
4882
 
 
4883
            // The space around which we move around...
 
4884
            int remSize = ( ( 1.0 - widthFrac )*( horizontal ? r.width():r.height() ) );
 
4885
            remSize = qMax( remSize, 1 );
 
4886
 
 
4887
            int pstep =  int( progress )%( 2*remSize );
 
4888
            if ( pstep > remSize )
 
4889
            {
 
4890
                // Bounce about.. We're remWidth + some delta, we want to be remWidth - delta...
 
4891
                // - ( ( remWidth + some delta ) - 2* remWidth )  = - ( some delta - remWidth ) = remWidth - some delta..
 
4892
                pstep = -( pstep - 2*remSize );
 
4893
            }
 
4894
 
 
4895
            if ( horizontal ) indicatorRect = QRect( r.x() + pstep, r.y(), indicatorSize, r.height() );
 
4896
            else indicatorRect = QRect( r.x(), r.y() + pstep, r.width(), indicatorSize );
 
4897
 
 
4898
        } else {
 
4899
 
 
4900
            if ( horizontal ) indicatorRect = QRect( r.x(), r.y(), indicatorSize, r.height() );
 
4901
            else indicatorRect = QRect( r.x(), r.bottom()- indicatorSize + 1, r.width(), indicatorSize );
 
4902
 
 
4903
        }
 
4904
 
 
4905
        // handle right to left
 
4906
        indicatorRect = handleRTL( option, indicatorRect );
 
4907
        indicatorRect.adjust( 1, 0, -1, -1 );
 
4908
 
 
4909
        if( indicatorRect.isValid() )
 
4910
        {
 
4911
            QPixmap pixmap( helper().progressBarIndicator( palette, indicatorRect ) );
 
4912
            painter->drawPixmap( indicatorRect.topLeft(), pixmap );
 
4913
        }
 
4914
 
 
4915
        return true;
 
4916
 
 
4917
    }
 
4918
 
 
4919
    //___________________________________________________________________________________
 
4920
    bool Style::drawProgressBarGrooveControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
4921
    {
 
4922
 
 
4923
        const QStyleOptionProgressBarV2 *pbOpt = qstyleoption_cast<const QStyleOptionProgressBarV2 *>( option );
 
4924
        const Qt::Orientation orientation( pbOpt? pbOpt->orientation : Qt::Horizontal );
 
4925
 
 
4926
        // ajust rect for alignment
 
4927
        QRect rect( option->rect );
 
4928
        if( orientation == Qt::Horizontal ) rect.adjust( 1, 0, -1, 0 );
 
4929
        else rect.adjust( 0, 1, 0, -1 );
 
4930
 
 
4931
        renderScrollBarHole( painter, rect, option->palette.color( QPalette::Window ), orientation );
 
4932
 
 
4933
        return true;
 
4934
    }
 
4935
 
 
4936
    //___________________________________________________________________________________
 
4937
    bool Style::drawProgressBarLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
4938
    {
 
4939
        const QStyleOptionProgressBar* pbOpt = qstyleoption_cast<const QStyleOptionProgressBar*>( option );
 
4940
        if( !pbOpt ) return true;
 
4941
 
 
4942
        const QRect& r( option->rect );
 
4943
        const QPalette& palette( option->palette );
 
4944
        const State& flags( option->state );
 
4945
        const bool enabled( flags&State_Enabled );
 
4946
 
 
4947
        const QStyleOptionProgressBarV2* pbOpt2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>( option );
 
4948
        const bool horizontal = !pbOpt2 || pbOpt2->orientation == Qt::Horizontal;
 
4949
        const bool reverseLayout = ( option->direction == Qt::RightToLeft );
 
4950
 
 
4951
        // rotate label for vertical layout
 
4952
        if( ! ( horizontal || reverseLayout ) )
 
4953
        {
 
4954
 
 
4955
            painter->translate( r.topRight() );
 
4956
            painter->rotate( 90.0 );
 
4957
 
 
4958
        } else if( !horizontal ) {
 
4959
 
 
4960
            painter->translate( r.bottomLeft() );
 
4961
            painter->rotate( -90.0 );
 
4962
 
 
4963
        }
 
4964
 
 
4965
        Qt::Alignment hAlign( ( pbOpt->textAlignment == Qt::AlignLeft ) ? Qt::AlignHCenter : pbOpt->textAlignment );
 
4966
 
 
4967
        /*
 
4968
        Figure out the geometry of the indicator.
 
4969
        This is copied from drawProgressBarContentsControl
 
4970
        */
 
4971
        QRect progressRect;
 
4972
        const QRect textRect( horizontal? r : QRect( 0, 0, r.height(), r.width() ) );
 
4973
        const qreal progress = pbOpt->progress - pbOpt->minimum;
 
4974
        const int steps = qMax( pbOpt->maximum  - pbOpt->minimum, 1 );
 
4975
        const bool busyIndicator = ( steps <= 1 );
 
4976
 
 
4977
        int indicatorSize( 0 );
 
4978
        if( !busyIndicator )
 
4979
        {
 
4980
            const qreal widthFrac = qMin( (qreal)1.0, progress / steps );
 
4981
            indicatorSize = widthFrac*( horizontal ? r.width() : r.height() );
 
4982
        }
 
4983
 
 
4984
        if( indicatorSize )
 
4985
        {
 
4986
            if ( horizontal ) painter->setClipRect( handleRTL( option, QRect( r.x(), r.y(), indicatorSize, r.height() ) ) );
 
4987
            else if ( !reverseLayout )  painter->setClipRect( QRect( r.height()-indicatorSize, 0, r.height(), r.width() ) );
 
4988
            else painter->setClipRect( QRect( 0, 0, indicatorSize, r.width() ) );
 
4989
 
 
4990
            // first pass ( highlighted )
 
4991
            drawItemText( painter, textRect, Qt::AlignVCenter | hAlign, palette, enabled, pbOpt->text, QPalette::HighlightedText );
 
4992
 
 
4993
            // second pass ( normal )
 
4994
            if( horizontal ) painter->setClipRect( handleRTL( option, QRect( r.x() + indicatorSize, r.y(), r.width() - indicatorSize, r.height() ) ) );
 
4995
            else if( !reverseLayout ) painter->setClipRect( QRect( 0, 0, r.height() - indicatorSize, r.width() ) );
 
4996
            else painter->setClipRect( QRect( indicatorSize, 0, r.height()- indicatorSize, r.width() ) );
 
4997
            drawItemText( painter, textRect, Qt::AlignVCenter | hAlign, palette, enabled, pbOpt->text, QPalette::WindowText );
 
4998
 
 
4999
        } else {
 
5000
 
 
5001
            drawItemText( painter, textRect, Qt::AlignVCenter | hAlign, palette, enabled, pbOpt->text, QPalette::WindowText );
 
5002
 
 
5003
        }
 
5004
 
 
5005
        return true;
 
5006
    }
 
5007
 
 
5008
    //___________________________________________________________________________________
 
5009
    bool Style::drawPushButtonLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
5010
    {
 
5011
 
 
5012
        // cast option and check
 
5013
        const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>( option );
 
5014
        if ( !bOpt ) return true;
 
5015
 
 
5016
        const QRect& r( option->rect );
 
5017
        const QPalette& palette( option->palette );
 
5018
        const State& flags( option->state );
 
5019
        const bool active( ( flags & State_On ) || ( flags & State_Sunken ) );
 
5020
        const bool enabled( flags & State_Enabled );
 
5021
        const bool hasFocus( flags & State_HasFocus );
 
5022
        const bool flat( bOpt->features.testFlag( QStyleOptionButton::Flat ) );
 
5023
 
 
5024
        //Extract out coordinates for easier manipulation
 
5025
        int x, y, w, h;
 
5026
        r.getRect( &x, &y, &w, &h );
 
5027
 
 
5028
        //Layout the stuff.
 
5029
        if ( bOpt->features & QStyleOptionButton::HasMenu )
 
5030
        {
 
5031
 
 
5032
            const int indicatorWidth( PushButton_MenuIndicatorSize );
 
5033
            const int indicatorSpacing = PushButton_TextToIconSpace;
 
5034
            w -= indicatorWidth + indicatorSpacing;
 
5035
 
 
5036
            // arrow
 
5037
            const QRect arrowRect( x + w + indicatorSpacing, y+1, indicatorWidth, h );
 
5038
            const qreal penThickness = 1.6;
 
5039
            QPolygonF a = genericArrow( ArrowDown, ArrowNormal );
 
5040
 
 
5041
            const QColor color = palette.color( flat ? QPalette::WindowText:QPalette::ButtonText );
 
5042
            const QColor background = palette.color( flat ? QPalette::Window:QPalette::Button );
 
5043
 
 
5044
            painter->save();
 
5045
            painter->translate( arrowRect.center() );
 
5046
            painter->setRenderHint( QPainter::Antialiasing );
 
5047
 
 
5048
            const qreal offset( qMin( penThickness, qreal( 1.0 ) ) );
 
5049
            painter->translate( 0,offset );
 
5050
            painter->setPen( QPen( helper().calcLightColor(  background ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
5051
            painter->drawPolyline( a );
 
5052
            painter->translate( 0,-offset );
 
5053
 
 
5054
            painter->setPen( QPen( helper().decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
5055
            painter->drawPolyline( a );
 
5056
            painter->restore();
 
5057
 
 
5058
        }
 
5059
 
 
5060
        // Draw the icon if there is one
 
5061
        if( !bOpt->icon.isNull() )
 
5062
        {
 
5063
 
 
5064
            if ( !bOpt->text.isEmpty() )
 
5065
            {
 
5066
 
 
5067
                const int margin = PushButton_TextToIconSpace;
 
5068
                const int length = bOpt->iconSize.width() + margin + painter->fontMetrics().size( Qt::TextShowMnemonic, bOpt->text ).width();
 
5069
 
 
5070
                //Calculate offset.
 
5071
                const int offset = ( w - length )/2;
 
5072
 
 
5073
                const QRect iconRect( handleRTL( bOpt, QRect( QPoint( x + offset, y + h/2 - bOpt->iconSize.height()/2 ), bOpt->iconSize ) ) );
 
5074
 
 
5075
                QIcon::Mode mode;
 
5076
                if( enabled ) mode = ( hasFocus ) ? QIcon::Active: QIcon::Normal;
 
5077
                else mode = QIcon::Disabled;
 
5078
 
 
5079
                QIcon::State iconState = active ? QIcon::On : QIcon::Off;
 
5080
 
 
5081
                QSize size = bOpt->iconSize;
 
5082
                if( !size.isValid() ) size = QSize( pixelMetric( PM_SmallIconSize ), pixelMetric( PM_SmallIconSize ) );
 
5083
                QPixmap icon = bOpt->icon.pixmap( size, mode, iconState );
 
5084
                painter->drawPixmap( centerRect( iconRect, icon.size() ), icon );
 
5085
 
 
5086
                //new bounding rect for the text
 
5087
                x += offset + bOpt->iconSize.width() + margin;
 
5088
                w =  length - bOpt->iconSize.width() - margin;
 
5089
 
 
5090
            } else {
 
5091
 
 
5092
                const QRect iconRect( x, y, w, h );
 
5093
                QIcon::Mode mode;
 
5094
                if( enabled ) mode = ( hasFocus ) ? QIcon::Active: QIcon::Normal;
 
5095
                else mode = QIcon::Disabled;
 
5096
 
 
5097
                QIcon::State iconState = active ? QIcon::On : QIcon::Off;
 
5098
 
 
5099
                QSize size = bOpt->iconSize;
 
5100
                if( !size.isValid() ) size = QSize( pixelMetric( PM_SmallIconSize ), pixelMetric( PM_SmallIconSize ) );
 
5101
                QPixmap icon = bOpt->icon.pixmap( size, mode, iconState );
 
5102
                painter->drawPixmap( centerRect( iconRect, icon.size() ), icon );
 
5103
 
 
5104
            }
 
5105
 
 
5106
        } else {
 
5107
 
 
5108
            //Center the text
 
5109
            int textW = painter->fontMetrics().size( Qt::TextShowMnemonic, bOpt->text ).width();
 
5110
            x += ( w - textW )/2;
 
5111
            w =  textW;
 
5112
 
 
5113
        }
 
5114
 
 
5115
        QRect textRect( handleRTL( bOpt, QRect( x, y, w, h ) ) );
 
5116
        if( !bOpt->icon.isNull() ) textRect.adjust( 0, 0, 0, 1 );
 
5117
 
 
5118
        const QPalette::ColorRole role( flat ? QPalette::WindowText : QPalette::ButtonText );
 
5119
        drawItemText( painter, textRect, Qt::AlignCenter | Qt::TextShowMnemonic, palette, enabled, bOpt->text, role );
 
5120
 
 
5121
        return true;
 
5122
    }
 
5123
 
 
5124
    //___________________________________________________________________________________
 
5125
    bool Style::drawRubberBandControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
5126
    {
 
5127
 
 
5128
        if( const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>( option ) )
 
5129
        {
 
5130
 
 
5131
            painter->save();
 
5132
            QColor color = rbOpt->palette.color( QPalette::Highlight );
 
5133
            painter->setPen( KColorUtils::mix( color, rbOpt->palette.color( QPalette::Active, QPalette::WindowText ) ) );
 
5134
            color.setAlpha( 50 );
 
5135
            painter->setBrush( color );
 
5136
            painter->setClipRegion( rbOpt->rect );
 
5137
            painter->drawRect( rbOpt->rect.adjusted( 0,0,-1,-1 ) );
 
5138
            painter->restore();
 
5139
            return true;
 
5140
 
 
5141
        } else return false;
 
5142
 
 
5143
    }
 
5144
 
 
5145
    //___________________________________________________________________________________
 
5146
    bool Style::drawScrollBarSliderControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
5147
    {
 
5148
 
 
5149
        // cast option and check
 
5150
        const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>( option );
 
5151
        if( !slider ) return true;
 
5152
 
 
5153
        const QRect& r( option->rect );
 
5154
        const QPalette& palette( option->palette );
 
5155
 
 
5156
        const State& flags( option->state );
 
5157
        const bool horizontal( flags & State_Horizontal );
 
5158
        const bool enabled( flags&State_Enabled );
 
5159
        const bool mouseOver( enabled && ( flags&State_MouseOver ) );
 
5160
 
 
5161
        // enable animation state
 
5162
        animations().scrollBarEngine().updateState( widget, enabled && slider && ( slider->activeSubControls & SC_ScrollBarSlider ) );
 
5163
 
 
5164
        const bool animated( enabled && animations().scrollBarEngine().isAnimated( widget, SC_ScrollBarSlider ) );
 
5165
 
 
5166
        if( horizontal )
 
5167
        {
 
5168
            if( animated ) renderScrollBarHandle( painter, r, palette, Qt::Horizontal, mouseOver, animations().scrollBarEngine().opacity( widget, SC_ScrollBarSlider ) );
 
5169
            else renderScrollBarHandle( painter, r, palette, Qt::Horizontal, mouseOver );
 
5170
 
 
5171
        } else {
 
5172
 
 
5173
            if( animated ) renderScrollBarHandle( painter, r, palette, Qt::Vertical, mouseOver, animations().scrollBarEngine().opacity( widget, SC_ScrollBarSlider ) );
 
5174
            else renderScrollBarHandle( painter, r, palette, Qt::Vertical, mouseOver );
 
5175
 
 
5176
        }
 
5177
 
 
5178
        return true;
 
5179
    }
 
5180
 
 
5181
    //___________________________________________________________________________________
 
5182
    bool Style::drawScrollBarAddLineControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
5183
    {
 
5184
 
 
5185
        // cast option and check
 
5186
        const QStyleOptionSlider* slOpt = qstyleoption_cast<const QStyleOptionSlider*>( option );
 
5187
        if ( !slOpt ) return true;
 
5188
 
 
5189
        const State& flags( option->state );
 
5190
        const bool horizontal( flags & State_Horizontal );
 
5191
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
5192
 
 
5193
        // colors
 
5194
        const QPalette& palette( option->palette );
 
5195
        const QColor background( palette.color( QPalette::Window ) );
 
5196
 
 
5197
        // adjust rect, based on number of buttons to be drawn
 
5198
        const QRect r( scrollBarInternalSubControlRect( slOpt, SC_ScrollBarAddLine ) );
 
5199
 
 
5200
        // draw the end of the scrollbar groove
 
5201
        if( horizontal )
 
5202
        {
 
5203
 
 
5204
            if( reverseLayout ) renderScrollBarHole( painter, QRect( r.right()+1, r.top(), 5, r.height() ), background, Qt::Horizontal, TileSet::Vertical | TileSet::Left );
 
5205
            else renderScrollBarHole( painter, QRect( r.left()-5, r.top(), 5, r.height() ), background, Qt::Horizontal, TileSet::Vertical | TileSet::Right );
 
5206
 
 
5207
        } else renderScrollBarHole( painter, QRect( r.left(), r.top()-5, r.width(), 5 ), background, Qt::Vertical, TileSet::Bottom | TileSet::Horizontal );
 
5208
 
 
5209
        // stop here if no buttons are defined
 
5210
        if( _addLineButtons == NoButton ) return true;
 
5211
 
 
5212
        QColor color;
 
5213
        QStyleOption localOption( *option );
 
5214
        if( _addLineButtons == DoubleButton )
 
5215
        {
 
5216
 
 
5217
            if( horizontal )
 
5218
            {
 
5219
 
 
5220
                //Draw the arrows
 
5221
                const QSize halfSize( r.width()/2, r.height() );
 
5222
                const QRect leftSubButton( r.topLeft(), halfSize );
 
5223
                const QRect rightSubButton( leftSubButton.topRight() + QPoint( 1, 0 ), halfSize );
 
5224
 
 
5225
                localOption.rect = leftSubButton;
 
5226
                color = scrollBarArrowColor( &localOption,  reverseLayout ? SC_ScrollBarAddLine:SC_ScrollBarSubLine, widget );
 
5227
                renderScrollBarArrow( painter, leftSubButton, color, background, ArrowLeft );
 
5228
 
 
5229
                localOption.rect = rightSubButton;
 
5230
                color = scrollBarArrowColor( &localOption,  reverseLayout ? SC_ScrollBarSubLine:SC_ScrollBarAddLine, widget );
 
5231
                renderScrollBarArrow( painter, rightSubButton, color, background, ArrowRight );
 
5232
 
 
5233
            } else {
 
5234
 
 
5235
                const QSize halfSize( r.width(), r.height()/2 );
 
5236
                const QRect topSubButton( r.topLeft(), halfSize );
 
5237
                const QRect botSubButton( topSubButton.bottomLeft() + QPoint( 0, 1 ), halfSize );
 
5238
 
 
5239
                localOption.rect = topSubButton;
 
5240
                color = scrollBarArrowColor( &localOption, SC_ScrollBarSubLine, widget );
 
5241
                renderScrollBarArrow( painter, topSubButton, color, background, ArrowUp );
 
5242
 
 
5243
                localOption.rect = botSubButton;
 
5244
                color = scrollBarArrowColor( &localOption, SC_ScrollBarAddLine, widget );
 
5245
                renderScrollBarArrow( painter, botSubButton, color, background, ArrowDown );
 
5246
 
 
5247
            }
 
5248
 
 
5249
        } else if( _addLineButtons == SingleButton ) {
 
5250
 
 
5251
            localOption.rect = r;
 
5252
            color = scrollBarArrowColor( &localOption,  SC_ScrollBarAddLine, widget );
 
5253
            if( horizontal ) renderScrollBarArrow( painter, r, color, background, reverseLayout ? ArrowLeft : ArrowRight );
 
5254
            else renderScrollBarArrow( painter, r, color, background, ArrowDown );
 
5255
 
 
5256
        }
 
5257
 
 
5258
        return true;
 
5259
    }
 
5260
 
 
5261
    //___________________________________________________________________________________
 
5262
    bool Style::drawScrollBarAddPageControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
5263
    {
 
5264
 
 
5265
        // cast option and check
 
5266
        const QStyleOptionSlider* slOpt = qstyleoption_cast<const QStyleOptionSlider*>( option );
 
5267
        if ( !slOpt ) return true;
 
5268
 
 
5269
        const QRect& r( option->rect );
 
5270
        const QPalette& palette( option->palette );
 
5271
        const QColor color( palette.color( QPalette::Window ) );
 
5272
 
 
5273
        const State& flags( option->state );
 
5274
        const bool horizontal( flags & State_Horizontal );
 
5275
        const bool reverseLayout( slOpt->direction == Qt::RightToLeft );
 
5276
 
 
5277
        if( horizontal )
 
5278
        {
 
5279
            if( reverseLayout ) renderScrollBarHole( painter, r.adjusted( 0,0,10,0 ), color, Qt::Horizontal, TileSet::Vertical );
 
5280
            else renderScrollBarHole( painter, r.adjusted( -10, 0,0,0 ), color, Qt::Horizontal, TileSet::Vertical );
 
5281
        } else renderScrollBarHole( painter, r.adjusted( 0,-10,0,0 ), color, Qt::Vertical, TileSet::Horizontal );
 
5282
 
 
5283
        return true;
 
5284
 
 
5285
    }
 
5286
 
 
5287
    //___________________________________________________________________________________
 
5288
    bool Style::drawScrollBarSubLineControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
5289
    {
 
5290
 
 
5291
        // cast option and check
 
5292
        const QStyleOptionSlider* slOpt = qstyleoption_cast<const QStyleOptionSlider*>( option );
 
5293
        if ( !slOpt ) return true;
 
5294
 
 
5295
        const State& flags( option->state );
 
5296
        const bool horizontal( flags & State_Horizontal );
 
5297
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
5298
 
 
5299
        // colors
 
5300
        const QPalette& palette( option->palette );
 
5301
        const QColor background( palette.color( QPalette::Window ) );
 
5302
 
 
5303
 
 
5304
        // adjust rect, based on number of buttons to be drawn
 
5305
        QRect r( scrollBarInternalSubControlRect( slOpt, SC_ScrollBarSubLine ) );
 
5306
 
 
5307
        // draw the end of the scrollbar groove
 
5308
        if( horizontal )
 
5309
        {
 
5310
 
 
5311
            if( reverseLayout ) renderScrollBarHole( painter, QRect( r.left()-5, r.top(), 5, r.height() ), background, Qt::Horizontal, TileSet::Vertical | TileSet::Right );
 
5312
            else renderScrollBarHole( painter, QRect( r.right()+1, r.top(), 5, r.height() ), background, Qt::Horizontal, TileSet::Vertical | TileSet::Left );
 
5313
 
 
5314
            r.translate( 1, 0 );
 
5315
 
 
5316
        } else {
 
5317
 
 
5318
            renderScrollBarHole( painter, QRect( r.left(), r.bottom()+3, r.width(), 5 ), background, Qt::Vertical, TileSet::Top | TileSet::Horizontal );
 
5319
            r.translate( 0, 2 );
 
5320
 
 
5321
        }
 
5322
 
 
5323
        // stop here if no buttons are defined
 
5324
        if( _subLineButtons == NoButton ) return true;
 
5325
 
 
5326
        QColor color;
 
5327
        QStyleOption localOption( *option );
 
5328
        if( _subLineButtons == DoubleButton )
 
5329
        {
 
5330
 
 
5331
            if( horizontal )
 
5332
            {
 
5333
 
 
5334
                //Draw the arrows
 
5335
                const QSize halfSize( r.width()/2, r.height() );
 
5336
                const QRect leftSubButton( r.topLeft(), halfSize );
 
5337
                const QRect rightSubButton( leftSubButton.topRight() + QPoint( 1, 0 ), halfSize );
 
5338
 
 
5339
                localOption.rect = leftSubButton;
 
5340
                color = scrollBarArrowColor( &localOption,  reverseLayout ? SC_ScrollBarAddLine:SC_ScrollBarSubLine, widget );
 
5341
                renderScrollBarArrow( painter, leftSubButton, color, background, ArrowLeft );
 
5342
 
 
5343
                localOption.rect = rightSubButton;
 
5344
                color = scrollBarArrowColor( &localOption,  reverseLayout ? SC_ScrollBarSubLine:SC_ScrollBarAddLine, widget );
 
5345
                renderScrollBarArrow( painter, rightSubButton, color, background, ArrowRight );
 
5346
 
 
5347
            } else {
 
5348
 
 
5349
                const QSize halfSize( r.width(), r.height()/2 );
 
5350
                const QRect topSubButton( r.topLeft(), halfSize );
 
5351
                const QRect botSubButton( topSubButton.bottomLeft() + QPoint( 0, 1 ), halfSize );
 
5352
 
 
5353
                localOption.rect = topSubButton;
 
5354
                color = scrollBarArrowColor( &localOption, SC_ScrollBarSubLine, widget );
 
5355
                renderScrollBarArrow( painter, topSubButton, color, background, ArrowUp );
 
5356
 
 
5357
                localOption.rect = botSubButton;
 
5358
                color = scrollBarArrowColor( &localOption, SC_ScrollBarAddLine, widget );
 
5359
                renderScrollBarArrow( painter, botSubButton, color, background, ArrowDown );
 
5360
 
 
5361
            }
 
5362
 
 
5363
        } else if( _subLineButtons == SingleButton ) {
 
5364
 
 
5365
            localOption.rect = r;
 
5366
            color = scrollBarArrowColor( &localOption,  SC_ScrollBarSubLine, widget );
 
5367
            if( horizontal ) renderScrollBarArrow( painter, r, color, background, reverseLayout ? ArrowRight : ArrowLeft );
 
5368
            else renderScrollBarArrow( painter, r, color, background, ArrowUp );
 
5369
 
 
5370
        }
 
5371
 
 
5372
        return true;
 
5373
    }
 
5374
 
 
5375
    //___________________________________________________________________________________
 
5376
    bool Style::drawScrollBarSubPageControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
5377
    {
 
5378
 
 
5379
        // cast option and check
 
5380
        const QStyleOptionSlider* slOpt = qstyleoption_cast<const QStyleOptionSlider*>( option );
 
5381
        if ( !slOpt ) return true;
 
5382
 
 
5383
        const QRect& r( option->rect );
 
5384
        const QPalette& palette( option->palette );
 
5385
        const QColor color( palette.color( QPalette::Window ) );
 
5386
 
 
5387
        const State& flags( option->state );
 
5388
        const bool horizontal( flags & State_Horizontal );
 
5389
        const bool reverseLayout( slOpt->direction == Qt::RightToLeft );
 
5390
 
 
5391
        if( horizontal )
 
5392
        {
 
5393
            if( reverseLayout ) renderScrollBarHole( painter, r.adjusted( -10, 0,0,0 ), color, Qt::Horizontal, TileSet::Vertical );
 
5394
            else renderScrollBarHole( painter, r.adjusted( 0,0,10,0 ), color, Qt::Horizontal, TileSet::Vertical );
 
5395
        } else renderScrollBarHole( painter, r.adjusted( 0,2,0,12 ), color, Qt::Vertical, TileSet::Horizontal );
 
5396
 
 
5397
        return true;
 
5398
 
 
5399
    }
 
5400
 
 
5401
    //___________________________________________________________________________________
 
5402
    bool Style::drawShapedFrameControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
5403
    {
 
5404
 
 
5405
        // cast option and check
 
5406
        const QStyleOptionFrameV3* frameOpt = qstyleoption_cast<const QStyleOptionFrameV3*>( option );
 
5407
        if( !frameOpt ) return false;
 
5408
 
 
5409
        switch( frameOpt->frameShape )
 
5410
        {
 
5411
 
 
5412
            case QFrame::Box:
 
5413
            {
 
5414
                if( option->state & State_Sunken ) return true;
 
5415
                else break;
 
5416
            }
 
5417
 
 
5418
            case QFrame::HLine:
 
5419
            {
 
5420
                const QColor color( helper().backgroundColor( option->palette.color( QPalette::Window ), widget, option->rect.center() ) );
 
5421
                helper().drawSeparator( painter, option->rect, color, Qt::Horizontal );
 
5422
                return true;
 
5423
            }
 
5424
 
 
5425
            case QFrame::VLine:
 
5426
            {
 
5427
                const QColor color( helper().backgroundColor( option->palette.color( QPalette::Window ), widget, option->rect.center() ) );
 
5428
                helper().drawSeparator( painter, option->rect, color, Qt::Vertical );
 
5429
                return true;
 
5430
            }
 
5431
 
 
5432
            default: break;
 
5433
 
 
5434
        }
 
5435
 
 
5436
        return false;
 
5437
 
 
5438
    }
 
5439
 
 
5440
    //___________________________________________________________________________________
 
5441
    bool Style::drawTabBarTabLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const
 
5442
    {
 
5443
 
 
5444
        const QStyleOptionTab *tabOpt = qstyleoption_cast< const QStyleOptionTab* >( option );
 
5445
        if( !tabOpt ) return true;
 
5446
 
 
5447
        // add extra offset for selected tas
 
5448
        QStyleOptionTabV3 tabOptV3( *tabOpt );
 
5449
 
 
5450
        const bool selected( option->state&State_Selected );
 
5451
 
 
5452
        // get rect
 
5453
        QRect r( option->rect );
 
5454
 
 
5455
        // handle selection and orientation
 
5456
        /*
 
5457
        painter is rotated and translated to deal with various orientations
 
5458
        rect is translated to 0,0, and possibly transposed
 
5459
        */
 
5460
        switch( tabOptV3.shape )
 
5461
        {
 
5462
 
 
5463
 
 
5464
            case QTabBar::RoundedNorth:
 
5465
            case QTabBar::TriangularNorth:
 
5466
            {
 
5467
                if( selected ) r.translate( 0, -1 );
 
5468
                painter->translate( r.topLeft() );
 
5469
                r.moveTopLeft( QPoint( 0,0 ) );
 
5470
                break;
 
5471
 
 
5472
            }
 
5473
 
 
5474
            case QTabBar::RoundedSouth:
 
5475
            case QTabBar::TriangularSouth:
 
5476
            {
 
5477
                if( selected ) r.translate( 0, 1 );
 
5478
                painter->translate( r.topLeft() );
 
5479
                r.moveTopLeft( QPoint( 0,0 ) );
 
5480
                break;
 
5481
 
 
5482
            }
 
5483
 
 
5484
            case QTabBar::RoundedWest:
 
5485
            case QTabBar::TriangularWest:
 
5486
            {
 
5487
 
 
5488
                if( selected ) r.translate( -1, 0 );
 
5489
                painter->translate( r.bottomLeft() );
 
5490
                painter->rotate( -90 );
 
5491
                r = QRect( QPoint( 0, 0 ), QSize( r.height(), r.width() ) );
 
5492
                break;
 
5493
 
 
5494
            }
 
5495
 
 
5496
            case QTabBar::RoundedEast:
 
5497
            case QTabBar::TriangularEast:
 
5498
            {
 
5499
 
 
5500
                if( selected ) r.translate( 1, 0 );
 
5501
                painter->translate( r.topRight() );
 
5502
                painter->rotate( 90 );
 
5503
                r = QRect( QPoint( 0, 0 ), QSize( r.height(), r.width() ) );
 
5504
                break;
 
5505
 
 
5506
            }
 
5507
 
 
5508
            default: break;
 
5509
 
 
5510
        }
 
5511
 
 
5512
        // make room for left and right widgets
 
5513
        // left widget
 
5514
        const bool verticalTabs( isVerticalTab( tabOpt ) );
 
5515
        const bool hasLeftButton( !( option->direction == Qt::RightToLeft ? tabOptV3.rightButtonSize.isEmpty():tabOptV3.leftButtonSize.isEmpty() ) );
 
5516
        const bool hasRightButton( !( option->direction == Qt::RightToLeft ? tabOptV3.leftButtonSize.isEmpty():tabOptV3.rightButtonSize.isEmpty() ) );
 
5517
 
 
5518
        if( hasLeftButton )
 
5519
        { r.setLeft( r.left() + 4 + ( verticalTabs ? tabOptV3.leftButtonSize.height() : tabOptV3.leftButtonSize.width() ) ); }
 
5520
 
 
5521
        // make room for left and right widgets
 
5522
        // left widget
 
5523
        if( hasRightButton )
 
5524
        { r.setRight( r.right() - 4 - ( verticalTabs ? tabOptV3.rightButtonSize.height() : tabOptV3.rightButtonSize.width() ) ); }
 
5525
 
 
5526
        // compute textRect and iconRect
 
5527
        // now that orientation is properly dealt with, everything is handled as a 'north' orientation
 
5528
        QRect textRect;
 
5529
        QRect iconRect;
 
5530
 
 
5531
        if( tabOptV3.icon.isNull() )
 
5532
        {
 
5533
 
 
5534
            textRect = r.adjusted( 6, 0, -6, 0 );
 
5535
 
 
5536
        } else {
 
5537
 
 
5538
            const QSize& iconSize( tabOptV3.iconSize );
 
5539
            iconRect = centerRect( r, iconSize );
 
5540
            if( !tabOptV3.text.isEmpty() )
 
5541
            {
 
5542
 
 
5543
                iconRect.moveLeft( r.left() + 8 );
 
5544
                textRect = r;
 
5545
                textRect.setLeft( iconRect.right()+3 );
 
5546
                textRect.setRight( r.right() - 6 );
 
5547
            }
 
5548
 
 
5549
        }
 
5550
 
 
5551
        if( !verticalTabs )
 
5552
        {
 
5553
            textRect = visualRect(option->direction, r, textRect );
 
5554
            iconRect = visualRect(option->direction, r, iconRect );
 
5555
        }
 
5556
 
 
5557
        // render icon
 
5558
        if( !iconRect.isNull() )
 
5559
        {
 
5560
 
 
5561
            // not sure why this is necessary
 
5562
            if( tabOptV3.shape == QTabBar::RoundedNorth || tabOptV3.shape == QTabBar::TriangularNorth )
 
5563
            { iconRect.translate( 0, -1 ); }
 
5564
 
 
5565
            const QPixmap tabIcon = tabOptV3.icon.pixmap(
 
5566
                tabOptV3.iconSize,
 
5567
                ( tabOptV3.state & State_Enabled ) ? QIcon::Normal : QIcon::Disabled,
 
5568
                ( tabOptV3.state & State_Selected ) ? QIcon::On : QIcon::Off );
 
5569
 
 
5570
            painter->drawPixmap( iconRect.x(), iconRect.y(), tabIcon );
 
5571
        }
 
5572
 
 
5573
        // render text
 
5574
        if( !textRect.isNull() )
 
5575
        {
 
5576
 
 
5577
            const QPalette& palette( option->palette );
 
5578
            const QString& text( tabOptV3.text );
 
5579
            const bool enabled( option->state & State_Enabled );
 
5580
            const int alignment( Qt::AlignCenter|Qt::TextShowMnemonic );
 
5581
            drawItemText( painter, textRect, alignment, palette, enabled, text, QPalette::WindowText );
 
5582
 
 
5583
        }
 
5584
 
 
5585
        return true;
 
5586
 
 
5587
    }
 
5588
 
 
5589
    //___________________________________________________________________________________
 
5590
    bool Style::drawTabBarTabShapeControl_Single( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
5591
    {
 
5592
 
 
5593
        const QStyleOptionTab* tabOpt( qstyleoption_cast<const QStyleOptionTab*>( option ) );
 
5594
        if( !tabOpt ) return true;
 
5595
 
 
5596
        const State& flags( option->state );
 
5597
        const QRect& r( option->rect );
 
5598
        const QPalette& palette( option->palette );
 
5599
 
 
5600
        const bool enabled( flags & State_Enabled );
 
5601
        const bool selected( flags&State_Selected );
 
5602
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
5603
 
 
5604
        // this is needed to complete the base frame when there are widgets in tabbar
 
5605
        const QTabBar* tabBar( qobject_cast<const QTabBar*>( widget ) );
 
5606
        const QRect tabBarRect( tabBar ? insideMargin( tabBar->rect(), -GlowWidth ):QRect() );
 
5607
 
 
5608
        // check if tab is being dragged
 
5609
        const bool isDragged( selected && painter->device() != tabBar );
 
5610
 
 
5611
        // hover and animation flags
 
5612
        /* all are disabled when tabBar is locked ( drag in progress ) */
 
5613
        const bool tabBarLocked( tabBarData().locks( tabBar ) );
 
5614
        const bool mouseOver( enabled && !tabBarLocked && ( flags & State_MouseOver ) );
 
5615
 
 
5616
        // animation state
 
5617
        animations().tabBarEngine().updateState( widget, r.topLeft(), mouseOver );
 
5618
        const bool animated( enabled && !selected && !tabBarLocked && animations().tabBarEngine().isAnimated( widget, r.topLeft() ) );
 
5619
 
 
5620
        // handle base frame painting, for tabbars in which tab is being dragged
 
5621
        tabBarData().drawTabBarBaseControl( tabOpt, painter, widget );
 
5622
        if( selected && tabBar && isDragged ) tabBarData().lock( tabBar );
 
5623
        else if( selected  && tabBarData().locks( tabBar ) ) tabBarData().release();
 
5624
 
 
5625
        // tab position and flags
 
5626
        const QStyleOptionTab::TabPosition& position = tabOpt->position;
 
5627
        const bool isFirst( position == QStyleOptionTab::OnlyOneTab || position == QStyleOptionTab::Beginning );
 
5628
        const bool isRightOfSelected( tabOpt->selectedPosition == QStyleOptionTab::PreviousIsSelected );
 
5629
 
 
5630
        // document mode
 
5631
        const QStyleOptionTabV3 *tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3 *>( option );
 
5632
        bool documentMode = tabOptV3 ? tabOptV3->documentMode : false;
 
5633
        const QTabWidget *tabWidget = ( widget && widget->parentWidget() ) ? qobject_cast<const QTabWidget *>( widget->parentWidget() ) : NULL;
 
5634
        documentMode |= ( tabWidget ? tabWidget->documentMode() : true );
 
5635
 
 
5636
        const bool verticalTabs( isVerticalTab( tabOpt ) );
 
5637
        const QRect tabWidgetRect( tabWidget ?
 
5638
            insideMargin( tabWidget->rect(), -GlowWidth ).translated( -widget->geometry().topLeft() ) :
 
5639
            QRect() );
 
5640
 
 
5641
        // corner widgets
 
5642
        const bool hasLeftCornerWidget( tabOpt->cornerWidgets & QStyleOptionTab::LeftCornerWidget );
 
5643
        const bool hasRightCornerWidget( tabOpt->cornerWidgets & QStyleOptionTab::RightCornerWidget );
 
5644
 
 
5645
        // true if widget is aligned to the frame
 
5646
        /* need to check for 'isRightOfSelected' because for some reason the isFirst flag is set when active tab is being moved */
 
5647
        const bool isFrameAligned( !documentMode && isFirst && !hasLeftCornerWidget && !isRightOfSelected && !isDragged );
 
5648
        bool fillBackground( selected && isDragged );
 
5649
 
 
5650
        bool isLeftFrameAligned( false );
 
5651
        bool isRightFrameAligned( false );
 
5652
        if( verticalTabs )
 
5653
        {
 
5654
 
 
5655
            /*
 
5656
            for vertical tabs:
 
5657
            1/ leftFrameAligned corresponds to top side
 
5658
            2/ rightFrameAligned corresponds to the bottom side
 
5659
            3/ their value does not depend on reverseLayout
 
5660
            */
 
5661
            isLeftFrameAligned = isFrameAligned;
 
5662
            isRightFrameAligned = (!documentMode) && tabWidget && ( r.bottom() >= tabWidgetRect.bottom() - 2 );;
 
5663
            fillBackground |= selected && isRightFrameAligned;
 
5664
 
 
5665
        } else if( reverseLayout ) {
 
5666
 
 
5667
            isLeftFrameAligned = (!documentMode) && tabWidget && ( r.left() <= tabWidgetRect.left() + 2 );
 
5668
            isRightFrameAligned = isFrameAligned;
 
5669
            fillBackground |= selected && isLeftFrameAligned;
 
5670
 
 
5671
        } else {
 
5672
 
 
5673
            isLeftFrameAligned = isFrameAligned;
 
5674
            isRightFrameAligned = (!documentMode) && tabWidget && ( r.right() >= tabWidgetRect.right() - 2 );
 
5675
            fillBackground |= selected && isRightFrameAligned;
 
5676
 
 
5677
        }
 
5678
 
 
5679
        // part of the tab in which the text is drawn
 
5680
        QRect tabRect( r );
 
5681
 
 
5682
        // connection to the frame
 
5683
        SlabRectList slabs;
 
5684
 
 
5685
        switch( tabOpt->shape )
 
5686
        {
 
5687
            case QTabBar::RoundedNorth:
 
5688
            case QTabBar::TriangularNorth:
 
5689
            {
 
5690
 
 
5691
                // part of the tab in which the text is drawn
 
5692
                // larger tabs when selected
 
5693
                if( selected ) tabRect.adjust( 0, -1, 0, 2 );
 
5694
                else tabRect.adjust( 0, 1, 0, 2 );
 
5695
 
 
5696
                // reduces the space between tabs
 
5697
                tabRect.adjust( -GlowWidth,0,GlowWidth,0 );
 
5698
 
 
5699
                // connection to the main frame
 
5700
                if( selected )
 
5701
                {
 
5702
 
 
5703
                    // do nothing if dragged
 
5704
                    if( isDragged ) break;
 
5705
 
 
5706
                    // left side
 
5707
                    if( isLeftFrameAligned )
 
5708
                    {
 
5709
 
 
5710
                        QRect frameRect( r );
 
5711
                        frameRect.setLeft( frameRect.left() - GlowWidth );
 
5712
                        frameRect.setRight( tabRect.left() + 7 );
 
5713
                        frameRect.setTop( tabRect.bottom() - 13 );
 
5714
                        frameRect.setBottom( frameRect.bottom() + 7 - 1 );
 
5715
                        slabs << SlabRect( frameRect, TileSet::Left );
 
5716
 
 
5717
                    } else {
 
5718
 
 
5719
                        QRect frameRect( r );
 
5720
                        frameRect.setLeft( frameRect.left() - 7 );
 
5721
                        frameRect.setRight( tabRect.left() + 7 + 3 );
 
5722
                        frameRect.setTop( r.bottom() - 7 );
 
5723
                        slabs << SlabRect( frameRect, TileSet::Top );
 
5724
                    }
 
5725
 
 
5726
                    // right side
 
5727
                    if( isRightFrameAligned )
 
5728
                    {
 
5729
 
 
5730
                        QRect frameRect( r );
 
5731
                        frameRect.setLeft( tabRect.right() - 7 );
 
5732
                        frameRect.setRight( frameRect.right() + GlowWidth );
 
5733
                        frameRect.setTop( tabRect.bottom() - 13 );
 
5734
                        frameRect.setBottom( frameRect.bottom() + 7 - 1 );
 
5735
                        slabs << SlabRect( frameRect, TileSet::Right );
 
5736
 
 
5737
                    } else {
 
5738
 
 
5739
                        QRect frameRect( r );
 
5740
                        frameRect.setLeft( tabRect.right() - 7 - 3 );
 
5741
                        frameRect.setRight( frameRect.right() + 7 );
 
5742
                        frameRect.setTop( r.bottom() - 7 );
 
5743
                        slabs << SlabRect( frameRect, TileSet::Top );
 
5744
 
 
5745
                    }
 
5746
 
 
5747
                    // extra base, to extend below inactive tabs and buttons
 
5748
                    if( tabBar )
 
5749
                    {
 
5750
                        if( r.left() > tabBarRect.left() + 1 )
 
5751
                        {
 
5752
                            QRect frameRect( r );
 
5753
                            frameRect.setLeft( tabBarRect.left() - 7 + 1 );
 
5754
                            frameRect.setRight( r.left() + 7 - 1 );
 
5755
                            frameRect.setTop( r.bottom() - 7 );
 
5756
                            if( documentMode || reverseLayout ) slabs << SlabRect( frameRect, TileSet::Top );
 
5757
                            else slabs << SlabRect( frameRect, TileSet::TopLeft );
 
5758
 
 
5759
                        }
 
5760
 
 
5761
                        if( r.right() < tabBarRect.right() - 1 )
 
5762
                        {
 
5763
 
 
5764
                            QRect frameRect( r );
 
5765
                            frameRect.setLeft( r.right() - 7 + 1 );
 
5766
                            frameRect.setRight( tabBarRect.right() + 7 - 1 );
 
5767
                            frameRect.setTop( r.bottom() - 7 );
 
5768
                            if( documentMode || !reverseLayout ) slabs << SlabRect( frameRect, TileSet::Top );
 
5769
                            else slabs << SlabRect( frameRect, TileSet::TopRight );
 
5770
                        }
 
5771
                    }
 
5772
 
 
5773
                } else {
 
5774
 
 
5775
                    if( isRightFrameAligned )
 
5776
                    {
 
5777
 
 
5778
                        QRect frameRect( r );
 
5779
                        frameRect.setLeft( tabRect.right() - 7 );
 
5780
                        frameRect.setRight( frameRect.right() + GlowWidth );
 
5781
                        frameRect.setTop( tabRect.bottom() - 13 );
 
5782
                        frameRect.setBottom( frameRect.bottom() + 7 - 2 );
 
5783
                        slabs << SlabRect( frameRect, TileSet::Right );
 
5784
 
 
5785
                    }
 
5786
 
 
5787
                    if( isLeftFrameAligned )
 
5788
                    {
 
5789
 
 
5790
                        QRect frameRect( r );
 
5791
                        frameRect.setLeft( frameRect.left() - GlowWidth );
 
5792
                        frameRect.setRight( tabRect.left() + 7 );
 
5793
                        frameRect.setTop( tabRect.bottom() - 13 );
 
5794
                        frameRect.setBottom( frameRect.bottom() + 7 - 2 );
 
5795
                        slabs << SlabRect( frameRect, TileSet::Left );
 
5796
 
 
5797
                    }
 
5798
 
 
5799
                }
 
5800
 
 
5801
                break;
 
5802
 
 
5803
            }
 
5804
 
 
5805
            case QTabBar::RoundedSouth:
 
5806
            case QTabBar::TriangularSouth:
 
5807
            {
 
5808
 
 
5809
                // larger tabs when selected
 
5810
                if( selected ) tabRect.adjust( 0, -2, 0, 1 );
 
5811
                else tabRect.adjust( 0, -2, 0, -1 );
 
5812
 
 
5813
                // reduces the space between tabs
 
5814
                tabRect.adjust( -GlowWidth,0,GlowWidth,0 );
 
5815
 
 
5816
                // connection to the main frame
 
5817
                if( selected )
 
5818
                {
 
5819
 
 
5820
                    // do nothing if dragged
 
5821
                    if( isDragged ) break;
 
5822
 
 
5823
                    // left side
 
5824
                    if( isLeftFrameAligned )
 
5825
                    {
 
5826
 
 
5827
                        QRect frameRect( r );
 
5828
                        frameRect.setLeft( frameRect.left() - GlowWidth );
 
5829
                        frameRect.setRight( tabRect.left() + 7 );
 
5830
                        frameRect.setTop( frameRect.top() - 7 + 1 );
 
5831
                        frameRect.setBottom( tabRect.top() + 13 );
 
5832
                        slabs << SlabRect( frameRect, TileSet::Left );
 
5833
 
 
5834
                    } else {
 
5835
 
 
5836
                        QRect frameRect( r );
 
5837
                        frameRect.setLeft( frameRect.left() - 7 );
 
5838
                        frameRect.setRight( tabRect.left() + 7 + 3 );
 
5839
                        frameRect.setBottom( r.top() + 7 );
 
5840
                        slabs << SlabRect( frameRect, TileSet::Bottom );
 
5841
                    }
 
5842
 
 
5843
                    // right side
 
5844
                    if( isRightFrameAligned )
 
5845
                    {
 
5846
 
 
5847
                        QRect frameRect( r );
 
5848
                        frameRect.setLeft( tabRect.right() - 7 );
 
5849
                        frameRect.setRight( frameRect.right() + GlowWidth );
 
5850
                        frameRect.setTop( frameRect.top() - 7 + 1 );
 
5851
                        frameRect.setBottom( tabRect.top() + 13 );
 
5852
                        slabs << SlabRect( frameRect, TileSet::Right );
 
5853
 
 
5854
                    } else {
 
5855
 
 
5856
                        QRect frameRect( r );
 
5857
                        frameRect.setLeft( tabRect.right() - 7 - 3 );
 
5858
                        frameRect.setRight( frameRect.right() + 7 );
 
5859
                        frameRect.setBottom( r.top() + 7 );
 
5860
                        slabs << SlabRect( frameRect, TileSet::Bottom );
 
5861
 
 
5862
                    }
 
5863
 
 
5864
                    // extra base, to extend below tabbar buttons
 
5865
                    if( tabBar )
 
5866
                    {
 
5867
                        if( r.left() > tabBarRect.left() + 1 )
 
5868
                        {
 
5869
                            QRect frameRect( r );
 
5870
                            frameRect.setLeft( tabBarRect.left() - 7 + 1 );
 
5871
                            frameRect.setRight( r.left() + 7 - 1 );
 
5872
                            frameRect.setBottom( r.top() + 7 );
 
5873
                            if( documentMode || reverseLayout ) slabs << SlabRect( frameRect, TileSet::Bottom );
 
5874
                            else slabs << SlabRect( frameRect, TileSet::BottomLeft );
 
5875
                        }
 
5876
 
 
5877
                        if( r.right() < tabBarRect.right() - 1 )
 
5878
                        {
 
5879
 
 
5880
                            QRect frameRect( r );
 
5881
                            frameRect.setLeft( r.right() - 7 + 1 );
 
5882
                            frameRect.setRight( tabBarRect.right() + 7 - 1 );
 
5883
                            frameRect.setBottom( r.top() + 7 );
 
5884
                            if( documentMode || !reverseLayout ) slabs << SlabRect( frameRect, TileSet::Bottom );
 
5885
                            else slabs << SlabRect( frameRect, TileSet::BottomRight );
 
5886
                        }
 
5887
 
 
5888
                    }
 
5889
 
 
5890
                } else {
 
5891
 
 
5892
                    if( isRightFrameAligned )
 
5893
                    {
 
5894
 
 
5895
                        QRect frameRect( r );
 
5896
                        frameRect.setLeft( tabRect.right() - 7 );
 
5897
                        frameRect.setRight( frameRect.right() + GlowWidth );
 
5898
                        frameRect.setTop( frameRect.top() - 7 + 2 );
 
5899
                        frameRect.setBottom( tabRect.top() + 13 );
 
5900
                        slabs << SlabRect( frameRect, TileSet::Right );
 
5901
 
 
5902
                    }
 
5903
 
 
5904
                    if( isLeftFrameAligned )
 
5905
                    {
 
5906
 
 
5907
                        QRect frameRect( r );
 
5908
                        frameRect.setLeft( frameRect.left() - GlowWidth );
 
5909
                        frameRect.setRight( tabRect.left() + 7 );
 
5910
                        frameRect.setTop( frameRect.top() - 7 + 2 );
 
5911
                        frameRect.setBottom( tabRect.top() + 13 );
 
5912
                        slabs << SlabRect( frameRect, TileSet::Left );
 
5913
 
 
5914
                    }
 
5915
 
 
5916
                }
 
5917
 
 
5918
                break;
 
5919
 
 
5920
            }
 
5921
 
 
5922
            case QTabBar::RoundedWest:
 
5923
            case QTabBar::TriangularWest:
 
5924
            {
 
5925
 
 
5926
                // larger tabs when selected
 
5927
                if( selected ) tabRect.adjust( -1, 0, 2, 0 );
 
5928
                else tabRect.adjust( 1, 0, 2, 0 );
 
5929
 
 
5930
                // reduces the space between tabs
 
5931
                tabRect.adjust( 0, -GlowWidth,0,GlowWidth );
 
5932
 
 
5933
                // connection to the main frame
 
5934
                if( selected )
 
5935
                {
 
5936
 
 
5937
                    // do nothing if dragged
 
5938
                    if( isDragged ) break;
 
5939
 
 
5940
                    // top side
 
5941
                    if( isLeftFrameAligned )
 
5942
                    {
 
5943
 
 
5944
                        QRect frameRect( r );
 
5945
                        frameRect.setLeft( tabRect.right() - 13 );
 
5946
                        frameRect.setRight( frameRect.right() + 7 - 1 );
 
5947
                        frameRect.setTop( frameRect.top() - GlowWidth );
 
5948
                        frameRect.setBottom( tabRect.top() + 7 );
 
5949
                        slabs << SlabRect( frameRect, TileSet::Top );
 
5950
 
 
5951
                    } else {
 
5952
 
 
5953
                        QRect frameRect( r );
 
5954
                        frameRect.setLeft( r.right() - 7 );
 
5955
                        frameRect.setTop( frameRect.top() - 7 );
 
5956
                        frameRect.setBottom( tabRect.top() + 7 + 3 );
 
5957
                        slabs << SlabRect( frameRect, TileSet::Left );
 
5958
                    }
 
5959
 
 
5960
                    // bottom side
 
5961
                    if( isRightFrameAligned )
 
5962
                    {
 
5963
 
 
5964
                        // FIXME:
 
5965
                        QRect frameRect( r );
 
5966
                        frameRect.setLeft( tabRect.right() - 13 );
 
5967
                        frameRect.setRight( frameRect.right() + 7 - 1 );
 
5968
                        frameRect.setTop( tabRect.bottom() - 7 );
 
5969
                        frameRect.setBottom( frameRect.bottom() + GlowWidth );
 
5970
                        slabs << SlabRect( frameRect, TileSet::Bottom );
 
5971
 
 
5972
                    } else {
 
5973
 
 
5974
                        QRect frameRect( r );
 
5975
                        frameRect.setLeft( r.right() - 7 );
 
5976
                        frameRect.setTop( tabRect.bottom() - 7 - 3 );
 
5977
                        frameRect.setBottom( frameRect.bottom() + 7 );
 
5978
                        slabs << SlabRect( frameRect, TileSet::Left );
 
5979
 
 
5980
                    }
 
5981
 
 
5982
                    // extra base, to extend below tabbar buttons
 
5983
                    if( tabBar )
 
5984
                    {
 
5985
                        if( r.top() > tabBarRect.top() + 1 )
 
5986
                        {
 
5987
 
 
5988
                            QRect frameRect( r );
 
5989
                            frameRect.setTop( tabBarRect.top() - 7 + 1 );
 
5990
                            frameRect.setBottom( r.top() + 7 - 1 );
 
5991
                            frameRect.setLeft( r.right() - 7 );
 
5992
                            if( documentMode ) slabs << SlabRect( frameRect, TileSet::Left );
 
5993
                            else slabs << SlabRect( frameRect, TileSet::TopLeft );
 
5994
                        }
 
5995
 
 
5996
                        if( r.bottom() < tabBarRect.bottom() - 1 )
 
5997
                        {
 
5998
 
 
5999
                            QRect frameRect( r );
 
6000
                            frameRect.setTop( r.bottom() - 7 + 1 );
 
6001
                            if( hasRightCornerWidget && documentMode ) frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
 
6002
                            else frameRect.setBottom( tabBarRect.bottom() + 7 );
 
6003
                            frameRect.setLeft( r.right() - 7 );
 
6004
                            slabs << SlabRect( frameRect, TileSet::Left );
 
6005
 
 
6006
                        }
 
6007
                    }
 
6008
 
 
6009
                } else {
 
6010
 
 
6011
                    if( isLeftFrameAligned )
 
6012
                    {
 
6013
 
 
6014
                        QRect frameRect( r );
 
6015
                        frameRect.setLeft( tabRect.right() - 13 );
 
6016
                        frameRect.setRight( frameRect.right() + 7 - 2 );
 
6017
                        frameRect.setTop( frameRect.top() - GlowWidth );
 
6018
                        frameRect.setBottom( tabRect.top() + 7 );
 
6019
                        slabs << SlabRect( frameRect, TileSet::Top );
 
6020
 
 
6021
                    }
 
6022
 
 
6023
                    if( isRightFrameAligned )
 
6024
                    {
 
6025
 
 
6026
                        // FIXME:
 
6027
                        QRect frameRect( r );
 
6028
                        frameRect.setLeft( tabRect.right() - 13 );
 
6029
                        frameRect.setRight( frameRect.right() + 7 - 2 );
 
6030
                        frameRect.setTop( tabRect.bottom() - 7 );
 
6031
                        frameRect.setBottom( frameRect.bottom() + GlowWidth );
 
6032
                        slabs << SlabRect( frameRect, TileSet::Bottom );
 
6033
 
 
6034
                    }
 
6035
                }
 
6036
 
 
6037
                break;
 
6038
            }
 
6039
 
 
6040
            case QTabBar::RoundedEast:
 
6041
            case QTabBar::TriangularEast:
 
6042
            {
 
6043
 
 
6044
                // larger tabs when selected
 
6045
                if( selected ) tabRect.adjust( -2, 0, 1, 0 );
 
6046
                else tabRect.adjust( -2, 0, -1, 0 );
 
6047
 
 
6048
                // reduces the space between tabs
 
6049
                tabRect.adjust( 0, -GlowWidth,0,GlowWidth );
 
6050
 
 
6051
                // connection to the main frame
 
6052
                if( selected )
 
6053
                {
 
6054
 
 
6055
                    // do nothing if dragged
 
6056
                    if( isDragged ) break;
 
6057
 
 
6058
                    // top side
 
6059
                    if( isLeftFrameAligned )
 
6060
                    {
 
6061
 
 
6062
                        QRect frameRect( r );
 
6063
                        frameRect.setLeft( frameRect.left() - 7 + 1 );
 
6064
                        frameRect.setRight( tabRect.left() + 13 );
 
6065
                        frameRect.setTop( frameRect.top() - GlowWidth );
 
6066
                        frameRect.setBottom( tabRect.top() + 7 );
 
6067
                        slabs << SlabRect( frameRect, TileSet::Top );
 
6068
 
 
6069
                    } else {
 
6070
 
 
6071
                        QRect frameRect( r );
 
6072
                        frameRect.setRight( r.left() + 7 );
 
6073
                        frameRect.setTop( frameRect.top() - 7 );
 
6074
                        frameRect.setBottom( tabRect.top() + 7 + 3 );
 
6075
                        slabs << SlabRect( frameRect, TileSet::Right );
 
6076
                    }
 
6077
 
 
6078
                    // bottom side
 
6079
                    if( isRightFrameAligned )
 
6080
                    {
 
6081
 
 
6082
                        // FIXME:
 
6083
                        QRect frameRect( r );
 
6084
                        frameRect.setLeft( frameRect.left() - 7 + 1 );
 
6085
                        frameRect.setRight( tabRect.left() + 13 );
 
6086
                        frameRect.setTop( tabRect.bottom() - 7 );
 
6087
                        frameRect.setBottom( frameRect.bottom() + GlowWidth );
 
6088
                        slabs << SlabRect( frameRect, TileSet::Bottom );
 
6089
 
 
6090
                    } else {
 
6091
 
 
6092
                        QRect frameRect( r );
 
6093
                        frameRect.setRight( r.left() + 7 );
 
6094
                        frameRect.setTop( tabRect.bottom() - 7 - 3 );
 
6095
                        frameRect.setBottom( frameRect.bottom() + 7 );
 
6096
                        slabs << SlabRect( frameRect, TileSet::Right );
 
6097
 
 
6098
                    }
 
6099
 
 
6100
                    // extra base, to extend below tabbar buttons
 
6101
                    if( tabBar )
 
6102
                    {
 
6103
                        if( r.top() > tabBarRect.top() + 1 )
 
6104
                        {
 
6105
 
 
6106
                            QRect frameRect( r );
 
6107
                            frameRect.setTop( tabBarRect.top() - 7 + 1 );
 
6108
                            frameRect.setBottom( r.top() + 7 - 1 );
 
6109
                            frameRect.setRight( r.left() + 7 );
 
6110
                            if( documentMode ) slabs << SlabRect( frameRect, TileSet::Right );
 
6111
                            else slabs << SlabRect( frameRect, TileSet::TopRight );
 
6112
                        }
 
6113
 
 
6114
                        if( r.bottom() < tabBarRect.bottom() - 1 )
 
6115
                        {
 
6116
 
 
6117
                            QRect frameRect( r );
 
6118
                            frameRect.setTop( r.bottom() - 7 + 1 );
 
6119
                            if( hasRightCornerWidget && documentMode ) frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
 
6120
                            else frameRect.setBottom( tabBarRect.bottom() + 7 );
 
6121
                            frameRect.setRight( r.left() + 7 );
 
6122
                            slabs << SlabRect( frameRect, TileSet::Right );
 
6123
 
 
6124
                        }
 
6125
                    }
 
6126
 
 
6127
                } else {
 
6128
 
 
6129
                    if( isLeftFrameAligned )
 
6130
                    {
 
6131
 
 
6132
                        QRect frameRect( r );
 
6133
                        frameRect.setLeft( frameRect.left() - 7 + 2 );
 
6134
                        frameRect.setRight( tabRect.left() + 13 );
 
6135
                        frameRect.setTop( frameRect.top() - GlowWidth );
 
6136
                        frameRect.setBottom( tabRect.top() + 7 );
 
6137
                        slabs << SlabRect( frameRect, TileSet::Top );
 
6138
 
 
6139
                    }
 
6140
 
 
6141
                    if( isRightFrameAligned )
 
6142
                    {
 
6143
 
 
6144
                        // FIXME:
 
6145
                        QRect frameRect( r );
 
6146
                        frameRect.setLeft( frameRect.left() - 7 + 2 );
 
6147
                        frameRect.setRight( tabRect.left() + 13 );
 
6148
                        frameRect.setTop( tabRect.bottom() - 7 );
 
6149
                        frameRect.setBottom( frameRect.bottom() + GlowWidth );
 
6150
                        slabs << SlabRect( frameRect, TileSet::Bottom );
 
6151
 
 
6152
                    }
 
6153
 
 
6154
                }
 
6155
 
 
6156
                break;
 
6157
            }
 
6158
 
 
6159
            default: break;
 
6160
        }
 
6161
 
 
6162
 
 
6163
        // slab options
 
6164
        StyleOptions slabOptions( NoFill );
 
6165
        if( StyleConfigData::tabSubtleShadow() ) slabOptions |= SubtleShadow;
 
6166
        if( ( !selected ) && ( mouseOver || animated ) ) slabOptions |= Hover;
 
6167
 
 
6168
        // color
 
6169
        const QColor color( palette.color( QPalette::Window ) );
 
6170
 
 
6171
        // render connections to frame
 
6172
        // extra care must be taken care of so that no slab
 
6173
        // extends beyond tabWidget frame, if any
 
6174
        foreach( SlabRect slab, slabs ) // krazy:exclude=foreach
 
6175
        {
 
6176
            adjustSlabRect( slab, tabWidgetRect, documentMode, verticalTabs );
 
6177
            if( selected || !animated ) renderSlab( painter, slab, color, slabOptions );
 
6178
            else {
 
6179
 
 
6180
                const qreal opacity( animations().tabBarEngine().opacity( widget, r.topLeft() ) );
 
6181
                renderSlab( painter, slab, color, slabOptions, opacity, AnimationHover );
 
6182
 
 
6183
            }
 
6184
 
 
6185
        }
 
6186
 
 
6187
        //  adjust clip rect and render tabs
 
6188
        if( tabBar )
 
6189
        {
 
6190
            painter->save();
 
6191
            painter->setClipRegion( tabBarClipRegion( tabBar ) );
 
6192
        }
 
6193
 
 
6194
        // draw tab
 
6195
        TileSet::Tiles tiles( tilesByShape( tabOpt->shape ) );
 
6196
        if( selected )
 
6197
        {
 
6198
 
 
6199
            // render window background first, if needed
 
6200
            if( fillBackground ) fillTabBackground( painter, tabRect, color, tabOpt->shape, widget );
 
6201
 
 
6202
            // render window background in case of dragged tabwidget
 
6203
            renderSlab( painter, tabRect, color, slabOptions, tiles );
 
6204
 
 
6205
        } else if( animated ) {
 
6206
 
 
6207
            const qreal opacity( animations().tabBarEngine().opacity( widget, r.topLeft() ) );
 
6208
            renderSlab( painter, tabRect, color, slabOptions, opacity, AnimationHover, tiles );
 
6209
 
 
6210
        } else renderSlab( painter, tabRect, color, slabOptions, tiles );
 
6211
 
 
6212
        // fill tab
 
6213
        fillTab( painter, tabRect, color, tabOpt->shape, selected );
 
6214
 
 
6215
        // restore clip region
 
6216
        if( tabBar ) painter->restore();
 
6217
 
 
6218
        return true;
 
6219
 
 
6220
    }
 
6221
 
 
6222
    //___________________________________________________________________________________
 
6223
    bool Style::drawTabBarTabShapeControl_Plain( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
6224
    {
 
6225
 
 
6226
        const QStyleOptionTab* tabOpt( qstyleoption_cast<const QStyleOptionTab*>( option ) );
 
6227
        if( !tabOpt ) return true;
 
6228
 
 
6229
        const State& flags( option->state );
 
6230
        const QRect& r( option->rect );
 
6231
        const QPalette& palette( option->palette );
 
6232
 
 
6233
        const bool enabled( flags & State_Enabled );
 
6234
        const bool selected( flags&State_Selected );
 
6235
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
6236
 
 
6237
        // tab position and flags
 
6238
        const QStyleOptionTab::TabPosition& position = tabOpt->position;
 
6239
        bool isFirst( position == QStyleOptionTab::OnlyOneTab || position == QStyleOptionTab::Beginning );
 
6240
        bool isLast( position == QStyleOptionTab::OnlyOneTab || position == QStyleOptionTab::End );
 
6241
        bool isLeftOfSelected( tabOpt->selectedPosition == QStyleOptionTab::NextIsSelected );
 
6242
        bool isRightOfSelected( tabOpt->selectedPosition == QStyleOptionTab::PreviousIsSelected );
 
6243
 
 
6244
        // document mode
 
6245
        const QStyleOptionTabV3 *tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3 *>( option );
 
6246
        bool documentMode = tabOptV3 ? tabOptV3->documentMode : false;
 
6247
        const QTabWidget *tabWidget = ( widget && widget->parentWidget() ) ? qobject_cast<const QTabWidget *>( widget->parentWidget() ) : NULL;
 
6248
        documentMode |= ( tabWidget ? tabWidget->documentMode() : true );
 
6249
 
 
6250
        // this is needed to complete the base frame when there are widgets in tabbar
 
6251
        const QTabBar* tabBar( qobject_cast<const QTabBar*>( widget ) );
 
6252
        const QRect tabBarRect( tabBar ? insideMargin( tabBar->rect(), -GlowWidth ):QRect() );
 
6253
 
 
6254
        // check if tab is being dragged
 
6255
        const bool isDragged( selected && painter->device() != tabBar );
 
6256
 
 
6257
        // hover and animation flags
 
6258
        /* all are disabled when tabBar is locked ( drag in progress ) */
 
6259
        const bool tabBarLocked( tabBarData().locks( tabBar ) );
 
6260
        const bool mouseOver( enabled && !tabBarLocked && ( flags & State_MouseOver ) );
 
6261
 
 
6262
        // animation state
 
6263
        animations().tabBarEngine().updateState( widget, r.topLeft(), mouseOver );
 
6264
        const bool animated( enabled && !selected && !tabBarLocked && animations().tabBarEngine().isAnimated( widget, r.topLeft() ) );
 
6265
 
 
6266
        // handle base frame painting, for tabbars in which tab is being dragged
 
6267
        tabBarData().drawTabBarBaseControl( tabOpt, painter, widget );
 
6268
        if( selected && tabBar && isDragged ) tabBarData().lock( tabBar );
 
6269
        else if( selected  && tabBarData().locks( tabBar ) ) tabBarData().release();
 
6270
 
 
6271
        // corner widgets
 
6272
        const bool hasLeftCornerWidget( tabOpt->cornerWidgets & QStyleOptionTab::LeftCornerWidget );
 
6273
        const bool hasRightCornerWidget( tabOpt->cornerWidgets & QStyleOptionTab::RightCornerWidget );
 
6274
 
 
6275
        // true if widget is aligned to the frame
 
6276
        /* need to check for 'isRightOfSelected' because for some reason the isFirst flag is set when active tab is being moved */
 
6277
        const bool isFrameAligned( !documentMode && isFirst && !hasLeftCornerWidget && !isRightOfSelected && !isDragged );
 
6278
        isFirst &= !isRightOfSelected;
 
6279
        isLast &= !isLeftOfSelected;
 
6280
 
 
6281
        // swap flags based on reverse layout, so that they become layout independent
 
6282
        const bool verticalTabs( isVerticalTab( tabOpt ) );
 
6283
        if( reverseLayout && !verticalTabs )
 
6284
        {
 
6285
            qSwap( isFirst, isLast );
 
6286
            qSwap( isLeftOfSelected, isRightOfSelected );
 
6287
        }
 
6288
 
 
6289
        const qreal radius = 5;
 
6290
 
 
6291
        // part of the tab in which the text is drawn
 
6292
        QRect tabRect( r );
 
6293
        QPainterPath path;
 
6294
 
 
6295
        // connection to the frame
 
6296
        SlabRectList slabs;
 
6297
 
 
6298
        // highlighted slab ( if any )
 
6299
        SlabRect highlightSlab;
 
6300
 
 
6301
        switch( tabOpt->shape )
 
6302
        {
 
6303
            case QTabBar::RoundedNorth:
 
6304
            case QTabBar::TriangularNorth:
 
6305
            {
 
6306
 
 
6307
                // part of the tab in which the text is drawn
 
6308
                // larger tabs when selected
 
6309
                if( selected ) tabRect.adjust( 0, -1, 0, 2 );
 
6310
                else tabRect.adjust( 0, 3, 1, -7 + 1 );
 
6311
 
 
6312
                // connection to the main frame
 
6313
                if( selected )
 
6314
                {
 
6315
 
 
6316
                    // reduces the space between tabs
 
6317
                    tabRect.adjust( -GlowWidth,0,GlowWidth,0 );
 
6318
 
 
6319
                    // do nothing if dragged
 
6320
                    if( isDragged ) break;
 
6321
 
 
6322
                    // left side
 
6323
                    if( isFrameAligned && !reverseLayout )
 
6324
                    {
 
6325
 
 
6326
                        QRect frameRect( r );
 
6327
                        frameRect.setLeft( frameRect.left() - GlowWidth );
 
6328
                        frameRect.setRight( tabRect.left() + 7 );
 
6329
                        frameRect.setTop( tabRect.bottom() - 13 );
 
6330
                        frameRect.setBottom( frameRect.bottom() + 7 - 1 );
 
6331
                        slabs << SlabRect( frameRect, TileSet::Left );
 
6332
 
 
6333
                    } else {
 
6334
 
 
6335
                        QRect frameRect( r );
 
6336
                        frameRect.setLeft( frameRect.left() - 7 );
 
6337
                        frameRect.setRight( tabRect.left() + 7 + 3 );
 
6338
                        frameRect.setTop( r.bottom() - 7 );
 
6339
                        slabs << SlabRect( frameRect, TileSet::Top );
 
6340
                    }
 
6341
 
 
6342
                    // right side
 
6343
                    if( isFrameAligned && reverseLayout )
 
6344
                    {
 
6345
 
 
6346
                        QRect frameRect( r );
 
6347
                        frameRect.setLeft( tabRect.right() - 7 );
 
6348
                        frameRect.setRight( frameRect.right() + GlowWidth );
 
6349
                        frameRect.setTop( tabRect.bottom() - 13 );
 
6350
                        frameRect.setBottom( frameRect.bottom() + 7 - 1 );
 
6351
                        slabs << SlabRect( frameRect, TileSet::Right );
 
6352
 
 
6353
                    } else {
 
6354
 
 
6355
                        QRect frameRect( r );
 
6356
                        frameRect.setLeft( tabRect.right() - 7 - 3 );
 
6357
                        frameRect.setRight( frameRect.right() + 7 );
 
6358
                        frameRect.setTop( r.bottom() - 7 );
 
6359
                        slabs << SlabRect( frameRect, TileSet::Top );
 
6360
 
 
6361
                    }
 
6362
 
 
6363
                    // extra base, to extend below inactive tabs and buttons
 
6364
                    if( tabBar )
 
6365
                    {
 
6366
                        if( r.left() > tabBarRect.left() + 1 )
 
6367
                        {
 
6368
                            QRect frameRect( r );
 
6369
                            frameRect.setLeft( tabBarRect.left() - 7 + 1 );
 
6370
                            frameRect.setRight( r.left() + 7 - 1 );
 
6371
                            frameRect.setTop( r.bottom() - 7 );
 
6372
                            if( documentMode || reverseLayout ) slabs << SlabRect( frameRect, TileSet::Top );
 
6373
                            else slabs << SlabRect( frameRect, TileSet::TopLeft );
 
6374
 
 
6375
                        }
 
6376
 
 
6377
                        if( r.right() < tabBarRect.right() - 1 )
 
6378
                        {
 
6379
 
 
6380
                            QRect frameRect( r );
 
6381
                            frameRect.setLeft( r.right() - 7 + 1 );
 
6382
                            frameRect.setRight( tabBarRect.right() + 7 - 1 );
 
6383
                            frameRect.setTop( r.bottom() - 7 );
 
6384
                            if( documentMode || !reverseLayout ) slabs << SlabRect( frameRect, TileSet::Top );
 
6385
                            else slabs << SlabRect( frameRect, TileSet::TopRight );
 
6386
                        }
 
6387
                    }
 
6388
 
 
6389
                } else {
 
6390
 
 
6391
                    // adjust sides when slab is adjacent to selected slab
 
6392
                    if( isLeftOfSelected ) tabRect.setRight( tabRect.right() + 2 );
 
6393
                    else if( isRightOfSelected ) tabRect.setLeft( tabRect.left() - 2 );
 
6394
 
 
6395
                    if( isFirst )
 
6396
                    {
 
6397
 
 
6398
                        tabRect.adjust( GlowWidth, 0, 0, 0 );
 
6399
                        if( isFrameAligned ) path.moveTo( tabRect.bottomLeft() + QPoint( 0, 2 ) );
 
6400
                        else path.moveTo( tabRect.bottomLeft() );
 
6401
                        path.lineTo( tabRect.topLeft() + QPointF( 0, radius ) );
 
6402
                        path.quadTo( tabRect.topLeft(), tabRect.topLeft() + QPoint( radius, 0 ) );
 
6403
                        path.lineTo( tabRect.topRight() );
 
6404
                        path.lineTo( tabRect.bottomRight() );
 
6405
 
 
6406
 
 
6407
                    } else if( isLast ) {
 
6408
 
 
6409
                        tabRect.adjust( 0, 0, -GlowWidth-1, 0 );
 
6410
                        path.moveTo( tabRect.bottomLeft() );
 
6411
                        path.lineTo( tabRect.topLeft() );
 
6412
                        path.lineTo( tabRect.topRight() - QPointF( radius, 0 ) );
 
6413
                        path.quadTo( tabRect.topRight(), tabRect.topRight() + QPointF( 0, radius ) );
 
6414
                        if( isFrameAligned ) path.lineTo( tabRect.bottomRight() + QPointF( 0, 2 ) );
 
6415
                        else path.lineTo( tabRect.bottomRight() );
 
6416
 
 
6417
                    } else {
 
6418
 
 
6419
                        path.moveTo( tabRect.bottomLeft() );
 
6420
                        path.lineTo( tabRect.topLeft() );
 
6421
                        path.lineTo( tabRect.topRight() );
 
6422
                        path.lineTo( tabRect.bottomRight() );
 
6423
 
 
6424
                    }
 
6425
 
 
6426
                    // highlight
 
6427
                    QRect highlightRect( tabRect.left(), tabRect.bottom()-1, tabRect.width(), 7 );
 
6428
                    if( isFrameAligned && isFirst ) highlightSlab = SlabRect( highlightRect.adjusted( -2, 0, 7 + 1, 0 ), TileSet::TopLeft );
 
6429
                    else if( isFrameAligned && isLast ) highlightSlab = SlabRect( highlightRect.adjusted( -7, 0, 2, 0 ), TileSet::TopRight );
 
6430
                    else highlightSlab = SlabRect( highlightRect.adjusted( -7, 0, 7, 0 ), TileSet::Top );
 
6431
 
 
6432
                }
 
6433
 
 
6434
                break;
 
6435
 
 
6436
            }
 
6437
 
 
6438
            case QTabBar::RoundedSouth:
 
6439
            case QTabBar::TriangularSouth:
 
6440
            {
 
6441
 
 
6442
                // larger tabs when selected
 
6443
                if( selected ) tabRect.adjust( 0, -2, 0, 1 );
 
6444
                else tabRect.adjust( 0, 7 - 1, 1, -3 );
 
6445
 
 
6446
                // connection to the main frame
 
6447
                if( selected )
 
6448
                {
 
6449
 
 
6450
                    // reduces the space between tabs
 
6451
                    tabRect.adjust( -GlowWidth,0,GlowWidth,0 );
 
6452
 
 
6453
                    // do nothing if dragged
 
6454
                    if( isDragged ) break;
 
6455
 
 
6456
                    // left side
 
6457
                    if( isFrameAligned && !reverseLayout )
 
6458
                    {
 
6459
 
 
6460
                        QRect frameRect( r );
 
6461
                        frameRect.setLeft( frameRect.left() - GlowWidth );
 
6462
                        frameRect.setRight( tabRect.left() + 7 );
 
6463
                        frameRect.setTop( frameRect.top() - 7 + 1 );
 
6464
                        frameRect.setBottom( tabRect.top() + 13 );
 
6465
                        slabs << SlabRect( frameRect, TileSet::Left );
 
6466
 
 
6467
                    } else {
 
6468
 
 
6469
                        QRect frameRect( r );
 
6470
                        frameRect.setLeft( frameRect.left() - 7 );
 
6471
                        frameRect.setRight( tabRect.left() + 7 + 3 );
 
6472
                        frameRect.setBottom( r.top() + 7 );
 
6473
                        slabs << SlabRect( frameRect, TileSet::Bottom );
 
6474
                    }
 
6475
 
 
6476
                    // right side
 
6477
                    if( isFrameAligned && reverseLayout )
 
6478
                    {
 
6479
 
 
6480
                        QRect frameRect( r );
 
6481
                        frameRect.setLeft( tabRect.right() - 7 );
 
6482
                        frameRect.setRight( frameRect.right() + GlowWidth );
 
6483
                        frameRect.setTop( frameRect.top() - 7 + 1 );
 
6484
                        frameRect.setBottom( tabRect.top() + 13 );
 
6485
                        slabs << SlabRect( frameRect, TileSet::Right );
 
6486
 
 
6487
                    } else {
 
6488
 
 
6489
                        QRect frameRect( r );
 
6490
                        frameRect.setLeft( tabRect.right() - 7 - 3 );
 
6491
                        frameRect.setRight( frameRect.right() + 7 );
 
6492
                        frameRect.setBottom( r.top() + 7 );
 
6493
                        slabs << SlabRect( frameRect, TileSet::Bottom );
 
6494
 
 
6495
                    }
 
6496
 
 
6497
                    // extra base, to extend below tabbar buttons
 
6498
                    if( tabBar )
 
6499
                    {
 
6500
                        if( r.left() > tabBarRect.left() + 1 )
 
6501
                        {
 
6502
                            QRect frameRect( r );
 
6503
                            frameRect.setLeft( tabBarRect.left() - 7 + 1 );
 
6504
                            frameRect.setRight( r.left() + 7 - 1 );
 
6505
                            frameRect.setBottom( r.top() + 7 );
 
6506
                            if( documentMode || reverseLayout ) slabs << SlabRect( frameRect, TileSet::Bottom );
 
6507
                            else slabs << SlabRect( frameRect, TileSet::BottomLeft );
 
6508
                        }
 
6509
 
 
6510
                        if( r.right() < tabBarRect.right() - 1 )
 
6511
                        {
 
6512
 
 
6513
                            QRect frameRect( r );
 
6514
                            frameRect.setLeft( r.right() - 7 + 1 );
 
6515
                            frameRect.setRight( tabBarRect.right() + 7 - 1 );
 
6516
                            frameRect.setBottom( r.top() + 7 );
 
6517
                            if( documentMode || !reverseLayout ) slabs << SlabRect( frameRect, TileSet::Bottom );
 
6518
                            else slabs << SlabRect( frameRect, TileSet::BottomRight );
 
6519
                        }
 
6520
 
 
6521
                    }
 
6522
 
 
6523
                } else {
 
6524
 
 
6525
                    // adjust sides when slab is adjacent to selected slab
 
6526
                    if( isLeftOfSelected ) tabRect.setRight( tabRect.right() + 2 );
 
6527
                    else if( isRightOfSelected ) tabRect.setLeft( tabRect.left() - 2 );
 
6528
 
 
6529
                    if( isFirst )
 
6530
                    {
 
6531
 
 
6532
                        tabRect.adjust( GlowWidth, 0, 0, 0 );
 
6533
                        if( isFrameAligned ) path.moveTo( tabRect.topLeft() - QPoint( 0, 2 ) );
 
6534
                        else path.moveTo( tabRect.topLeft() );
 
6535
                        path.lineTo( tabRect.bottomLeft() - QPointF( 0, radius ) );
 
6536
                        path.quadTo( tabRect.bottomLeft(), tabRect.bottomLeft() + QPoint( radius, 0 ) );
 
6537
                        path.lineTo( tabRect.bottomRight() );
 
6538
                        path.lineTo( tabRect.topRight() );
 
6539
 
 
6540
                    } else if( isLast ) {
 
6541
 
 
6542
                        tabRect.adjust( 0, 0, -GlowWidth-1, 0 );
 
6543
                        path.moveTo( tabRect.topLeft() );
 
6544
                        path.lineTo( tabRect.bottomLeft() );
 
6545
                        path.lineTo( tabRect.bottomRight() - QPointF( radius, 0 ) );
 
6546
                        path.quadTo( tabRect.bottomRight(), tabRect.bottomRight() - QPointF( 0, radius ) );
 
6547
                        if( isFrameAligned ) path.lineTo( tabRect.topRight() - QPointF( 0, 2 ) );
 
6548
                        else path.lineTo( tabRect.topRight() );
 
6549
 
 
6550
                    } else {
 
6551
 
 
6552
                        path.moveTo( tabRect.topLeft() );
 
6553
                        path.lineTo( tabRect.bottomLeft() );
 
6554
                        path.lineTo( tabRect.bottomRight() );
 
6555
                        path.lineTo( tabRect.topRight() );
 
6556
 
 
6557
                    }
 
6558
 
 
6559
                    // highlight
 
6560
                    QRect highlightRect( tabRect.left(), tabRect.top()-5, tabRect.width(), 7 );
 
6561
                    if( isFrameAligned && isFirst ) highlightSlab = SlabRect( highlightRect.adjusted( -2, 0, 7 + 1, 0 ), TileSet::BottomLeft );
 
6562
                    else if( isFrameAligned && isLast ) highlightSlab = SlabRect( highlightRect.adjusted( -7, 0, 2, 0 ), TileSet::BottomRight );
 
6563
                    else highlightSlab = SlabRect( highlightRect.adjusted( -7, 0, 7, 0 ), TileSet::Bottom );
 
6564
 
 
6565
                }
 
6566
 
 
6567
                break;
 
6568
 
 
6569
            }
 
6570
 
 
6571
            case QTabBar::RoundedWest:
 
6572
            case QTabBar::TriangularWest:
 
6573
            {
 
6574
 
 
6575
                // larger tabs when selected
 
6576
                if( selected ) tabRect.adjust( -1, 0, 2, 0 );
 
6577
                else tabRect.adjust( 3, 0, -7 + 1, 1 );
 
6578
 
 
6579
                // connection to the main frame
 
6580
                if( selected )
 
6581
                {
 
6582
 
 
6583
                    // reduces the space between tabs
 
6584
                    tabRect.adjust( 0, -GlowWidth,0,GlowWidth );
 
6585
 
 
6586
                    // do nothing if dragged
 
6587
                    if( isDragged ) break;
 
6588
 
 
6589
                    // top side
 
6590
                    if( isFrameAligned )
 
6591
                    {
 
6592
 
 
6593
                        QRect frameRect( r );
 
6594
                        frameRect.setLeft( tabRect.right() - 13 );
 
6595
                        frameRect.setRight( frameRect.right() + 7 - 1 );
 
6596
                        frameRect.setTop( frameRect.top() - GlowWidth );
 
6597
                        frameRect.setBottom( tabRect.top() + 7 );
 
6598
                        slabs << SlabRect( frameRect, TileSet::Top );
 
6599
 
 
6600
                    } else {
 
6601
 
 
6602
                        QRect frameRect( r );
 
6603
                        frameRect.setLeft( r.right() - 7 );
 
6604
                        frameRect.setTop( frameRect.top() - 7 );
 
6605
                        frameRect.setBottom( tabRect.top() + 7 + 3 );
 
6606
                        slabs << SlabRect( frameRect, TileSet::Left );
 
6607
                    }
 
6608
 
 
6609
                    // bottom side
 
6610
                    QRect frameRect( r );
 
6611
                    frameRect.setLeft( r.right() - 7 );
 
6612
                    frameRect.setTop( tabRect.bottom() - 7 - 3 );
 
6613
                    frameRect.setBottom( frameRect.bottom() + 7 );
 
6614
                    slabs << SlabRect( frameRect, TileSet::Left );
 
6615
 
 
6616
                    // extra base, to extend below tabbar buttons
 
6617
                    if( tabBar )
 
6618
                    {
 
6619
                        if( r.top() > tabBarRect.top() + 1 )
 
6620
                        {
 
6621
 
 
6622
                            QRect frameRect( r );
 
6623
                            frameRect.setTop( tabBarRect.top() - 7 + 1 );
 
6624
                            frameRect.setBottom( r.top() + 7 - 1 );
 
6625
                            frameRect.setLeft( r.right() - 7 );
 
6626
                            if( documentMode ) slabs << SlabRect( frameRect, TileSet::Left );
 
6627
                            else slabs << SlabRect( frameRect, TileSet::TopLeft );
 
6628
                        }
 
6629
 
 
6630
                        if( r.bottom() < tabBarRect.bottom() - 1 )
 
6631
                        {
 
6632
 
 
6633
                            QRect frameRect( r );
 
6634
                            frameRect.setTop( r.bottom() - 7 + 1 );
 
6635
                            if( hasRightCornerWidget && documentMode ) frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
 
6636
                            else frameRect.setBottom( tabBarRect.bottom() + 7 );
 
6637
                            frameRect.setLeft( r.right() - 7 );
 
6638
                            slabs << SlabRect( frameRect, TileSet::Left );
 
6639
 
 
6640
                        }
 
6641
                    }
 
6642
 
 
6643
                } else {
 
6644
 
 
6645
                    // adjust sides when slab is adjacent to selected slab
 
6646
                    if( isLeftOfSelected ) tabRect.setBottom( tabRect.bottom() + 2 );
 
6647
                    else if( isRightOfSelected ) tabRect.setTop( tabRect.top() - 2 );
 
6648
 
 
6649
                    if( isFirst )
 
6650
                    {
 
6651
 
 
6652
                        tabRect.adjust( 0, GlowWidth, 0, 0 );
 
6653
                        if( isFrameAligned ) path.moveTo( tabRect.topRight() + QPoint( 2, 0 ) );
 
6654
                        else path.moveTo( tabRect.topRight() );
 
6655
                        path.lineTo( tabRect.topLeft() + QPointF( radius, 0 ) );
 
6656
                        path.quadTo( tabRect.topLeft(), tabRect.topLeft() + QPoint( 0, radius ) );
 
6657
                        path.lineTo( tabRect.bottomLeft() );
 
6658
                        path.lineTo( tabRect.bottomRight() );
 
6659
 
 
6660
                    } else if( isLast ) {
 
6661
 
 
6662
                        tabRect.adjust( 0, 0, 0, -GlowWidth );
 
6663
                        path.moveTo( tabRect.topRight() );
 
6664
                        path.lineTo( tabRect.topLeft() );
 
6665
                        path.lineTo( tabRect.bottomLeft() - QPointF( 0, radius ) );
 
6666
                        path.quadTo( tabRect.bottomLeft(), tabRect.bottomLeft() + QPointF( radius, 0 ) );
 
6667
                        path.lineTo( tabRect.bottomRight() );
 
6668
 
 
6669
                    } else {
 
6670
 
 
6671
                        path.moveTo( tabRect.topRight() );
 
6672
                        path.lineTo( tabRect.topLeft() );
 
6673
                        path.lineTo( tabRect.bottomLeft() );
 
6674
                        path.lineTo( tabRect.bottomRight() );
 
6675
 
 
6676
                    }
 
6677
 
 
6678
                    // highlight
 
6679
                    QRect highlightRect( tabRect.right()-1, tabRect.top(), 7, tabRect.height() );
 
6680
                    if( isFrameAligned && isFirst ) highlightSlab = SlabRect( highlightRect.adjusted( 0, -2, 0, 7 + 1 ), TileSet::TopLeft );
 
6681
                    else if( isFrameAligned && isLast ) highlightSlab = SlabRect( highlightRect.adjusted( 0, -7, 0, 2 ), TileSet::BottomLeft );
 
6682
                    else highlightSlab = SlabRect( highlightRect.adjusted( 0, -7 + 1, 0, 7 + 1 ), TileSet::Left );
 
6683
 
 
6684
                }
 
6685
 
 
6686
                break;
 
6687
            }
 
6688
 
 
6689
            case QTabBar::RoundedEast:
 
6690
            case QTabBar::TriangularEast:
 
6691
            {
 
6692
 
 
6693
                // larger tabs when selected
 
6694
                if( selected ) tabRect.adjust( -2, 0, 1, 0 );
 
6695
                else tabRect.adjust( 7 - 1, 0, -3, 1 );
 
6696
 
 
6697
                // connection to the main frame
 
6698
                if( selected )
 
6699
                {
 
6700
 
 
6701
                    // reduces the space between tabs
 
6702
                    tabRect.adjust( 0, -GlowWidth,0,GlowWidth );
 
6703
 
 
6704
                    // do nothing if dragged
 
6705
                    if( isDragged ) break;
 
6706
 
 
6707
                    // top side
 
6708
                    if( isFrameAligned )
 
6709
                    {
 
6710
 
 
6711
                        QRect frameRect( r );
 
6712
                        frameRect.setLeft( frameRect.left() - 7 + 1 );
 
6713
                        frameRect.setRight( tabRect.left() + 13 );
 
6714
                        frameRect.setTop( frameRect.top() - GlowWidth );
 
6715
                        frameRect.setBottom( tabRect.top() + 7 );
 
6716
                        slabs << SlabRect( frameRect, TileSet::Top );
 
6717
 
 
6718
                    } else {
 
6719
 
 
6720
                        QRect frameRect( r );
 
6721
                        frameRect.setRight( r.left() + 7 );
 
6722
                        frameRect.setTop( frameRect.top() - 7 );
 
6723
                        frameRect.setBottom( tabRect.top() + 7 + 3 );
 
6724
                        slabs << SlabRect( frameRect, TileSet::Right );
 
6725
                    }
 
6726
 
 
6727
                    // bottom side
 
6728
                    QRect frameRect( r );
 
6729
                    frameRect.setRight( r.left() + 7 );
 
6730
                    frameRect.setTop( tabRect.bottom() - 7 - 3 );
 
6731
                    frameRect.setBottom( frameRect.bottom() + 7 );
 
6732
                    slabs << SlabRect( frameRect, TileSet::Right );
 
6733
 
 
6734
                    // extra base, to extend below tabbar buttons
 
6735
                    if( tabBar )
 
6736
                    {
 
6737
                        if( r.top() > tabBarRect.top() + 1 )
 
6738
                        {
 
6739
 
 
6740
                            QRect frameRect( r );
 
6741
                            frameRect.setTop( tabBarRect.top() - 7 + 1 );
 
6742
                            frameRect.setBottom( r.top() + 7 - 1 );
 
6743
                            frameRect.setRight( r.left() + 7 );
 
6744
                            if( documentMode ) slabs << SlabRect( frameRect, TileSet::Right );
 
6745
                            else slabs << SlabRect( frameRect, TileSet::TopRight );
 
6746
                        }
 
6747
 
 
6748
                        if( r.bottom() < tabBarRect.bottom() - 1 )
 
6749
                        {
 
6750
 
 
6751
                            QRect frameRect( r );
 
6752
                            frameRect.setTop( r.bottom() - 7 + 1 );
 
6753
                            if( hasRightCornerWidget && documentMode ) frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
 
6754
                            else frameRect.setBottom( tabBarRect.bottom() + 7 );
 
6755
                            frameRect.setRight( r.left() + 7 );
 
6756
                            slabs << SlabRect( frameRect, TileSet::Right );
 
6757
 
 
6758
                        }
 
6759
                    }
 
6760
 
 
6761
                } else {
 
6762
 
 
6763
                    // adjust sides when slab is adjacent to selected slab
 
6764
                    if( isLeftOfSelected ) tabRect.setBottom( tabRect.bottom() + 2 );
 
6765
                    else if( isRightOfSelected ) tabRect.setTop( tabRect.top() - 2 );
 
6766
 
 
6767
                    if( isFirst )
 
6768
                    {
 
6769
 
 
6770
                        tabRect.adjust( 0, GlowWidth, 0, 0 );
 
6771
                        if( isFrameAligned ) path.moveTo( tabRect.topLeft() - QPoint( 2, 0 ) );
 
6772
                        else path.moveTo( tabRect.topLeft() );
 
6773
                        path.lineTo( tabRect.topRight() - QPointF( radius, 0 ) );
 
6774
                        path.quadTo( tabRect.topRight(), tabRect.topRight() + QPoint( 0, radius ) );
 
6775
                        path.lineTo( tabRect.bottomRight() );
 
6776
                        path.lineTo( tabRect.bottomLeft() );
 
6777
 
 
6778
                    } else if( isLast ) {
 
6779
 
 
6780
                        tabRect.adjust( 0, 0, 0, -GlowWidth );
 
6781
                        path.moveTo( tabRect.topLeft() );
 
6782
                        path.lineTo( tabRect.topRight() );
 
6783
                        path.lineTo( tabRect.bottomRight() - QPointF( 0, radius ) );
 
6784
                        path.quadTo( tabRect.bottomRight(), tabRect.bottomRight() - QPointF( radius, 0 ) );
 
6785
                        path.lineTo( tabRect.bottomLeft() );
 
6786
 
 
6787
                    } else {
 
6788
 
 
6789
                        path.moveTo( tabRect.topLeft() );
 
6790
                        path.lineTo( tabRect.topRight() );
 
6791
                        path.lineTo( tabRect.bottomRight() );
 
6792
                        path.lineTo( tabRect.bottomLeft() );
 
6793
 
 
6794
                    }
 
6795
 
 
6796
                    // highlight
 
6797
                    QRect highlightRect( tabRect.left()-5, tabRect.top(), 7, tabRect.height() );
 
6798
                    if( isFrameAligned && isFirst ) highlightSlab = SlabRect( highlightRect.adjusted( 0, -2, 0, 7 + 1 ), TileSet::TopRight );
 
6799
                    else if( isFrameAligned && isLast ) highlightSlab = SlabRect( highlightRect.adjusted( 0, -7, 0, 2 ), TileSet::BottomRight );
 
6800
                    else highlightSlab = SlabRect( highlightRect.adjusted( 0, -7 + 1, 0, 7 + 1 ), TileSet::Right );
 
6801
 
 
6802
                }
 
6803
 
 
6804
                break;
 
6805
            }
 
6806
 
 
6807
            default: break;
 
6808
        }
 
6809
 
 
6810
        const QColor color( palette.color( QPalette::Window ) );
 
6811
 
 
6812
        // render connections to frame
 
6813
        // extra care must be taken care of so that no slab
 
6814
        // extends beyond tabWidget frame, if any
 
6815
        const QRect tabWidgetRect( tabWidget ?
 
6816
            insideMargin( tabWidget->rect(), -GlowWidth ).translated( -widget->geometry().topLeft() ) :
 
6817
            QRect() );
 
6818
 
 
6819
        foreach( SlabRect slab, slabs ) // krazy:exclude=foreach
 
6820
        {
 
6821
            adjustSlabRect( slab, tabWidgetRect, documentMode, verticalTabs );
 
6822
            renderSlab( painter, slab, color, NoFill );
 
6823
        }
 
6824
 
 
6825
        //  adjust clip rect and render tab
 
6826
        if( tabBar )
 
6827
        {
 
6828
            painter->save();
 
6829
            painter->setClipRegion( tabBarClipRegion( tabBar ) );
 
6830
        }
 
6831
 
 
6832
        // fill tab
 
6833
        if( selected )
 
6834
        {
 
6835
 
 
6836
            // render window background in case of dragged tabwidget
 
6837
            if( isDragged ) fillTabBackground( painter, tabRect, color, tabOpt->shape, widget );
 
6838
 
 
6839
            // slab options
 
6840
            StyleOptions selectedTabOpts( NoFill );
 
6841
            if( StyleConfigData::tabSubtleShadow() ) selectedTabOpts |= SubtleShadow;
 
6842
 
 
6843
            TileSet::Tiles tiles( tilesByShape( tabOpt->shape ) );
 
6844
            renderSlab( painter, tabRect, color, selectedTabOpts, tiles );
 
6845
            fillTab( painter, tabRect, color, tabOpt->shape, selected );
 
6846
 
 
6847
        } else {
 
6848
 
 
6849
            const QColor backgroundColor = helper().backgroundColor( color, widget, r.center() );
 
6850
            const QColor midColor = helper().alphaColor( helper().calcDarkColor( backgroundColor ), 0.4 );
 
6851
            const QColor darkColor = helper().alphaColor( helper().calcDarkColor( backgroundColor ), 0.6 );
 
6852
 
 
6853
            painter->save();
 
6854
            painter->translate( 0.5, 0.5 );
 
6855
            painter->setRenderHints( QPainter::Antialiasing );
 
6856
            painter->setPen( darkColor );
 
6857
            painter->setBrush( midColor );
 
6858
            painter->drawPath( path );
 
6859
            painter->restore();
 
6860
 
 
6861
        }
 
6862
 
 
6863
        // restore clip region
 
6864
        if( tabBar ) painter->restore();
 
6865
 
 
6866
        // hovered highlight
 
6867
        if( ( animated || mouseOver ) && highlightSlab._r.isValid() )
 
6868
        {
 
6869
 
 
6870
            const qreal opacity( animations().tabBarEngine().opacity( widget, r.topLeft() ) );
 
6871
            const StyleOptions hoverTabOpts( NoFill | Hover );
 
6872
            adjustSlabRect( highlightSlab, tabWidgetRect, documentMode, verticalTabs );
 
6873
 
 
6874
            // pass an invalid color to have only the glow painted
 
6875
            if( animated ) renderSlab( painter, highlightSlab, QColor(), hoverTabOpts, opacity, AnimationHover );
 
6876
            else renderSlab( painter, highlightSlab, QColor(), hoverTabOpts );
 
6877
 
 
6878
        }
 
6879
 
 
6880
 
 
6881
        return true;
 
6882
 
 
6883
    }
 
6884
 
 
6885
    //___________________________________________________________________________________
 
6886
    void Style::TabBarData::drawTabBarBaseControl( const QStyleOptionTab* tabOpt, QPainter* painter, const QWidget* widget )
 
6887
    {
 
6888
 
 
6889
        // check parent
 
6890
        if( !_style ) return;
 
6891
 
 
6892
        // make sure widget is locked
 
6893
        if( !locks( widget ) ) return;
 
6894
 
 
6895
        // make sure dirty flag is set
 
6896
        if( !_dirty ) return;
 
6897
 
 
6898
        // cast to TabBar and check
 
6899
        const QTabBar* tabBar( qobject_cast<const QTabBar*>( widget ) );
 
6900
        if( !tabBar ) return;
 
6901
 
 
6902
        // get reverseLayout flag
 
6903
        const bool reverseLayout( tabOpt->direction == Qt::RightToLeft );
 
6904
 
 
6905
        // get documentMode flag
 
6906
        const QStyleOptionTabV3 *tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3 *>( tabOpt );
 
6907
        bool documentMode = tabOptV3 ? tabOptV3->documentMode : false;
 
6908
        const QTabWidget *tabWidget = ( widget && widget->parentWidget() ) ? qobject_cast<const QTabWidget *>( widget->parentWidget() ) : NULL;
 
6909
        documentMode |= ( tabWidget ? tabWidget->documentMode() : true );
 
6910
 
 
6911
        const QRect tabBarRect( _style.data()->insideMargin( tabBar->rect(), -GlowWidth ) );
 
6912
 
 
6913
        // define slab
 
6914
        Style::SlabRect slab;
 
6915
 
 
6916
        // switch on tab shape
 
6917
        switch( tabOpt->shape )
 
6918
        {
 
6919
            case QTabBar::RoundedNorth:
 
6920
            case QTabBar::TriangularNorth:
 
6921
            {
 
6922
                TileSet::Tiles tiles( TileSet::Top );
 
6923
                QRect frameRect;
 
6924
                frameRect.setLeft( tabBarRect.left() - 7 + 1 );
 
6925
                frameRect.setRight( tabBarRect.right() + 7 - 1 );
 
6926
                frameRect.setTop( tabBarRect.bottom() - 8 );
 
6927
                frameRect.setHeight( 4 );
 
6928
                if( !( documentMode || reverseLayout ) ) tiles |= TileSet::Left;
 
6929
                if( !documentMode && reverseLayout ) tiles |= TileSet::Right;
 
6930
                slab = SlabRect( frameRect, tiles );
 
6931
                break;
 
6932
            }
 
6933
 
 
6934
            case QTabBar::RoundedSouth:
 
6935
            case QTabBar::TriangularSouth:
 
6936
            {
 
6937
                TileSet::Tiles tiles( TileSet::Bottom );
 
6938
                QRect frameRect;
 
6939
                frameRect.setLeft( tabBarRect.left() - 7 + 1 );
 
6940
                frameRect.setRight( tabBarRect.right() + 7 - 1 );
 
6941
                frameRect.setBottom( tabBarRect.top() + 8 );
 
6942
                frameRect.setTop( frameRect.bottom() - 4 );
 
6943
                if( !( documentMode || reverseLayout ) ) tiles |= TileSet::Left;
 
6944
                if( !documentMode && reverseLayout ) tiles |= TileSet::Right;
 
6945
                slab = SlabRect( frameRect, tiles );
 
6946
                break;
 
6947
            }
 
6948
 
 
6949
            case QTabBar::RoundedWest:
 
6950
            case QTabBar::TriangularWest:
 
6951
            {
 
6952
                TileSet::Tiles tiles( TileSet::Left );
 
6953
                QRect frameRect;
 
6954
                frameRect.setTop( tabBarRect.top() - 7 + 1 );
 
6955
                frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
 
6956
                frameRect.setLeft( tabBarRect.right() - 8 );
 
6957
                frameRect.setWidth( 4 );
 
6958
                if( !( documentMode || reverseLayout ) ) tiles |= TileSet::Top;
 
6959
                if( !documentMode && reverseLayout ) tiles |= TileSet::Bottom;
 
6960
                slab = SlabRect( frameRect, tiles );
 
6961
                break;
 
6962
            }
 
6963
 
 
6964
            case QTabBar::RoundedEast:
 
6965
            case QTabBar::TriangularEast:
 
6966
            {
 
6967
                TileSet::Tiles tiles( TileSet::Right );
 
6968
                QRect frameRect;
 
6969
                frameRect.setTop( tabBarRect.top() - 7 + 1 );
 
6970
                frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
 
6971
                frameRect.setRight( tabBarRect.left() + 8 );
 
6972
                frameRect.setLeft( frameRect.right() - 4 );
 
6973
                if( !( documentMode || reverseLayout ) ) tiles |= TileSet::Top;
 
6974
                if( !documentMode && reverseLayout ) tiles |= TileSet::Bottom;
 
6975
                slab = SlabRect( frameRect, tiles );
 
6976
                break;
 
6977
            }
 
6978
 
 
6979
            default:
 
6980
            break;
 
6981
        }
 
6982
 
 
6983
        const bool verticalTabs( _style.data()->isVerticalTab( tabOpt ) );
 
6984
        const QRect tabWidgetRect( tabWidget ?
 
6985
            _style.data()->insideMargin( tabWidget->rect(), -GlowWidth ).translated( -widget->geometry().topLeft() ) :
 
6986
            QRect() );
 
6987
 
 
6988
        const QPalette& palette( tabOpt->palette );
 
6989
        const QColor color( palette.color( QPalette::Window ) );
 
6990
        _style.data()->adjustSlabRect( slab, tabWidgetRect, documentMode, verticalTabs );
 
6991
        _style.data()->renderSlab( painter, slab, color, NoFill );
 
6992
 
 
6993
        setDirty( false );
 
6994
        return;
 
6995
 
 
6996
    }
 
6997
 
 
6998
    //___________________________________________________________________________________
 
6999
    bool Style::drawToolBarControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
7000
    {
 
7001
 
 
7002
        const QRect& r( option->rect );
 
7003
 
 
7004
        // when timeLine is running draw border event if not hovered
 
7005
        const bool toolBarAnimated( animations().toolBarEngine().isFollowMouseAnimated( widget ) );
 
7006
        const QRect animatedRect( animations().toolBarEngine().animatedRect( widget ) );
 
7007
        const bool toolBarIntersected( toolBarAnimated && animatedRect.intersects( r ) );
 
7008
        if( toolBarIntersected )
 
7009
        { helper().slitFocused( helper().viewFocusBrush().brush( QPalette::Active ).color() )->render( animatedRect, painter ); }
 
7010
 
 
7011
        // draw nothing otherwise ( toolbars are transparent )
 
7012
 
 
7013
        return true;
 
7014
 
 
7015
    }
 
7016
 
 
7017
    //___________________________________________________________________________________
 
7018
    bool Style::drawToolBoxTabLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
7019
    {
 
7020
 
 
7021
        const QStyleOptionToolBox* toolBoxOption( qstyleoption_cast<const QStyleOptionToolBox *>( option ) );
 
7022
        const bool enabled( toolBoxOption->state & State_Enabled );
 
7023
        const bool selected( toolBoxOption->state & State_Selected );
 
7024
        QPixmap pm(
 
7025
            toolBoxOption->icon.pixmap( pixelMetric( QStyle::PM_SmallIconSize, toolBoxOption, widget ),
 
7026
            enabled ? QIcon::Normal : QIcon::Disabled ) );
 
7027
 
 
7028
        const QRect cr( toolBoxTabContentsRect( toolBoxOption, widget ) );
 
7029
        QRect tr;
 
7030
        QRect ir;
 
7031
        int ih( 0 );
 
7032
 
 
7033
        if( pm.isNull() )  tr = cr.adjusted( -1, 0, -8, 0 );
 
7034
        else {
 
7035
 
 
7036
            int iw = pm.width() + 4;
 
7037
            ih = pm.height();
 
7038
            ir = QRect( cr.left() - 1, cr.top(), iw + 2, ih );
 
7039
            tr = QRect( ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height() );
 
7040
 
 
7041
        }
 
7042
 
 
7043
        if( selected )
 
7044
        {
 
7045
            QFont f( painter->font() );
 
7046
            f.setBold( true );
 
7047
            painter->setFont( f );
 
7048
        }
 
7049
 
 
7050
        QString txt( toolBoxOption->fontMetrics.elidedText( toolBoxOption->text, Qt::ElideRight, tr.width() ) );
 
7051
 
 
7052
        if( ih ) painter->drawPixmap( ir.left(), ( toolBoxOption->rect.height() - ih ) / 2, pm );
 
7053
 
 
7054
        int alignment( Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic );
 
7055
        drawItemText( painter, tr, alignment, toolBoxOption->palette, enabled, txt, QPalette::WindowText );
 
7056
 
 
7057
        return true;
 
7058
    }
 
7059
 
 
7060
    //___________________________________________________________________________________
 
7061
    bool Style::drawToolBoxTabShapeControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
7062
    {
 
7063
 
 
7064
        const QRect& r( option->rect );
 
7065
        const QPalette& palette( option->palette );
 
7066
        const State& flags( option->state );
 
7067
 
 
7068
        const bool enabled( flags&State_Enabled );
 
7069
        const bool selected( flags&State_Selected );
 
7070
        const bool mouseOver( enabled && !selected && ( flags&State_MouseOver ) );
 
7071
        const bool reverseLayout( option->direction == Qt::RightToLeft );
 
7072
 
 
7073
 
 
7074
        // cast to v2 and disable paint is tab is first
 
7075
        const QStyleOptionToolBoxV2 *v2 = qstyleoption_cast<const QStyleOptionToolBoxV2 *>( option );
 
7076
        if( v2 && v2->position == QStyleOptionToolBoxV2::Beginning && selected ) return true;
 
7077
 
 
7078
        /*
 
7079
        the proper widget ( the toolbox tab ) is not passed as argument by Qt.
 
7080
        What is passed is the toolbox directly. To implement animations properly,
 
7081
        the painter->device() is used instead
 
7082
        */
 
7083
        bool animated( false );
 
7084
        qreal opacity( AnimationData::OpacityInvalid );
 
7085
        if( enabled )
 
7086
        {
 
7087
            // try retrieve button from painter device.
 
7088
            if( QPaintDevice* device = painter->device() )
 
7089
            {
 
7090
                animations().toolBoxEngine().updateState( device, mouseOver );
 
7091
                animated = animations().toolBoxEngine().isAnimated( device );
 
7092
                opacity = animations().toolBoxEngine().opacity( device );
 
7093
            }
 
7094
 
 
7095
        }
 
7096
 
 
7097
        // save colors for shadow
 
7098
        /* important: option returns a wrong color. We use the widget's palette when widget is set */
 
7099
        const QColor color( widget ? widget->palette().color( widget->backgroundRole() ) : palette.color( QPalette::Window ) );
 
7100
        const QColor dark( helper().calcDarkColor( color ) );
 
7101
        QList<QColor> colors;
 
7102
        colors.push_back( helper().calcLightColor( color ) );
 
7103
 
 
7104
        if( mouseOver || animated )
 
7105
        {
 
7106
 
 
7107
            QColor highlight = helper().viewHoverBrush().brush( palette ).color();
 
7108
            if( animated )
 
7109
            {
 
7110
 
 
7111
                colors.push_back( KColorUtils::mix( dark, highlight, opacity ) );
 
7112
                colors.push_back( helper().alphaColor( highlight, 0.2*opacity ) );
 
7113
 
 
7114
            } else {
 
7115
 
 
7116
                colors.push_back( highlight );
 
7117
                colors.push_back( helper().alphaColor( highlight, 0.2 ) );
 
7118
 
 
7119
            }
 
7120
 
 
7121
        } else colors.push_back( dark );
 
7122
 
 
7123
        // create path
 
7124
        painter->save();
 
7125
        QPainterPath path;
 
7126
        const int y( r.height()*15/100 );
 
7127
        if( reverseLayout )
 
7128
        {
 
7129
 
 
7130
            path.moveTo( r.left()+52, r.top() );
 
7131
            path.cubicTo( QPointF( r.left()+50-8, r.top() ), QPointF( r.left()+50-10, r.top()+y ), QPointF( r.left()+50-10, r.top()+y ) );
 
7132
            path.lineTo( r.left()+18+9, r.bottom()-y );
 
7133
            path.cubicTo( QPointF( r.left()+18+9, r.bottom()-y ), QPointF( r.left()+19+6, r.bottom()-1-0.3 ), QPointF( r.left()+19, r.bottom()-1-0.3 ) );
 
7134
            painter->setClipRect( QRect( r.left()+21, r.top(), 28, r.height() ) );
 
7135
 
 
7136
        } else {
 
7137
 
 
7138
            path.moveTo( r.right()-52, r.top() );
 
7139
            path.cubicTo( QPointF( r.right()-50+8, r.top() ), QPointF( r.right()-50+10, r.top()+y ), QPointF( r.right()-50+10, r.top()+y ) );
 
7140
            path.lineTo( r.right()-18-9, r.bottom()-y );
 
7141
            path.cubicTo( QPointF( r.right()-18-9, r.bottom()-y ), QPointF( r.right()-19-6, r.bottom()-1-0.3 ), QPointF( r.right()-19, r.bottom()-1-0.3 ) );
 
7142
            painter->setClipRect( QRect( r.right()-48, r.top(), 32, r.height() ) );
 
7143
 
 
7144
        }
 
7145
 
 
7146
 
 
7147
        // paint
 
7148
        painter->setRenderHint( QPainter::Antialiasing, true );
 
7149
        painter->translate( 0,2 );
 
7150
        foreach( const QColor& color, colors )
 
7151
        {
 
7152
            painter->setPen( color );
 
7153
            painter->drawPath( path );
 
7154
            painter->translate( 0,-1 );
 
7155
        }
 
7156
        painter->restore();
 
7157
 
 
7158
        painter->save();
 
7159
        painter->setRenderHint( QPainter::Antialiasing, false );
 
7160
        painter->translate( 0,2 );
 
7161
        foreach( const QColor& color, colors )
 
7162
        {
 
7163
            painter->setPen( color );
 
7164
            if( reverseLayout ) {
 
7165
                painter->drawLine( r.left()+50-1, r.top(), r.right(), r.top() );
 
7166
                painter->drawLine( r.left()+20, r.bottom()-2, r.left(), r.bottom()-2 );
 
7167
            } else {
 
7168
                painter->drawLine( r.left(), r.top(), r.right()-50+1, r.top() );
 
7169
                painter->drawLine( r.right()-20, r.bottom()-2, r.right(), r.bottom()-2 );
 
7170
            }
 
7171
            painter->translate( 0,-1 );
 
7172
        }
 
7173
 
 
7174
        painter->restore();
 
7175
        return true;
 
7176
 
 
7177
    }
 
7178
 
 
7179
    //___________________________________________________________________________________
 
7180
    bool Style::drawToolButtonLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
7181
    {
 
7182
 
 
7183
        // need to customize palettes to deal with autoraised buttons
 
7184
        const State& flags( option->state );
 
7185
 
 
7186
        // normal processing if not autoRaised
 
7187
        if( flags & State_AutoRaise )
 
7188
        {
 
7189
 
 
7190
            const QStyleOptionToolButton* toolButtonOpt( qstyleoption_cast<const QStyleOptionToolButton*>( option ) );
 
7191
            if( !toolButtonOpt ) return true;
 
7192
 
 
7193
            QStyleOptionToolButton localOption( *toolButtonOpt );
 
7194
            localOption.palette.setColor( QPalette::ButtonText, option->palette.color( QPalette::WindowText ) );
 
7195
 
 
7196
            QCommonStyle::drawControl( CE_ToolButtonLabel, &localOption, painter, widget );
 
7197
 
 
7198
        } else {
 
7199
 
 
7200
            QCommonStyle::drawControl( CE_ToolButtonLabel, option, painter, widget );
 
7201
 
 
7202
        }
 
7203
 
 
7204
        return true;
 
7205
 
 
7206
    }
 
7207
 
 
7208
    //______________________________________________________________
 
7209
    bool Style::drawComboBoxComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const
 
7210
    {
 
7211
 
 
7212
        // cast option and check
 
7213
        const QStyleOptionComboBox* cb( qstyleoption_cast<const QStyleOptionComboBox *>( option ) );
 
7214
        if( !cb ) return true;
 
7215
 
 
7216
        const State& flags( option->state );
 
7217
        const QRect& r( option->rect );
 
7218
        const QPalette& palette( option->palette );
 
7219
        const bool enabled( flags & State_Enabled );
 
7220
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
7221
        const bool hasFocus( flags & State_HasFocus );
 
7222
        const bool& editable( cb->editable );
 
7223
        const bool& hasFrame( cb->frame );
 
7224
 
 
7225
        // frame
 
7226
        if( cb->subControls & SC_ComboBoxFrame )
 
7227
        {
 
7228
 
 
7229
 
 
7230
            // style options
 
7231
            StyleOptions opts = 0;
 
7232
            if( mouseOver ) opts |= Hover;
 
7233
            if( hasFocus ) opts |= Focus;
 
7234
            if( ( flags & ( State_Sunken|State_On ) ) && !editable ) opts |= Sunken;
 
7235
 
 
7236
            const QColor inputColor( palette.color( QPalette::Base ) );
 
7237
            const QRect editField( subControlRect( CC_ComboBox, cb, SC_ComboBoxEditField, widget ) );
 
7238
 
 
7239
            if( editable )
 
7240
            {
 
7241
 
 
7242
                // editable combobox. Make it look like a LineEdit
 
7243
                // focus takes precedence over hover
 
7244
                animations().lineEditEngine().updateState( widget, AnimationFocus, hasFocus );
 
7245
                animations().lineEditEngine().updateState( widget, AnimationHover, mouseOver && !hasFocus );
 
7246
 
 
7247
                const QRect fr( r.adjusted( 1,1,-1,-1 ) );
 
7248
 
 
7249
                // input area
 
7250
                painter->save();
 
7251
                painter->setRenderHint( QPainter::Antialiasing );
 
7252
                painter->setPen( Qt::NoPen );
 
7253
                painter->setBrush( inputColor );
 
7254
 
 
7255
                if( !hasFrame )
 
7256
                {
 
7257
 
 
7258
                    // adjust rect to match frameLess editors
 
7259
                    painter->fillRect( r, inputColor );
 
7260
                    painter->restore();
 
7261
 
 
7262
                } else {
 
7263
 
 
7264
                    helper().fillHole( *painter, r.adjusted( 0, -1, 0, 0 ) );
 
7265
                    painter->restore();
 
7266
 
 
7267
                    HoleOptions options( 0 );
 
7268
                    if( hasFocus && enabled ) options |= HoleFocus;
 
7269
                    if( mouseOver && enabled ) options |= HoleHover;
 
7270
 
 
7271
                    const QColor color( palette.color( QPalette::Window ) );
 
7272
                    if( enabled && animations().lineEditEngine().isAnimated( widget, AnimationFocus ) )
 
7273
                    {
 
7274
 
 
7275
                        helper().renderHole( painter, color, fr, options, animations().lineEditEngine().opacity( widget, AnimationFocus ), AnimationFocus, TileSet::Ring );
 
7276
 
 
7277
                    } else if( enabled && animations().lineEditEngine().isAnimated( widget, AnimationHover ) ) {
 
7278
 
 
7279
                        helper().renderHole( painter, color, fr, options, animations().lineEditEngine().opacity( widget, AnimationHover ), AnimationHover, TileSet::Ring );
 
7280
 
 
7281
                    } else {
 
7282
 
 
7283
                        helper().renderHole( painter, color, fr, options );
 
7284
 
 
7285
                    }
 
7286
 
 
7287
                }
 
7288
 
 
7289
            } else {
 
7290
 
 
7291
                // non editable combobox. Make it look like a PushButton
 
7292
                // hover takes precedence over focus
 
7293
                animations().lineEditEngine().updateState( widget, AnimationHover, mouseOver );
 
7294
                animations().lineEditEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );
 
7295
 
 
7296
                // store animation state
 
7297
                const bool hoverAnimated( animations().lineEditEngine().isAnimated( widget, AnimationHover ) );
 
7298
                const bool focusAnimated( animations().lineEditEngine().isAnimated( widget, AnimationFocus ) );
 
7299
                const qreal hoverOpacity( animations().lineEditEngine().opacity( widget, AnimationHover ) );
 
7300
                const qreal focusOpacity( animations().lineEditEngine().opacity( widget, AnimationFocus ) );
 
7301
 
 
7302
                // blend button color to the background
 
7303
                const QColor buttonColor( helper().backgroundColor( palette.color( QPalette::Button ), widget, r.center() ) );
 
7304
                const QRect slabRect( r.adjusted( -1, 0, 1, 0 ) );
 
7305
 
 
7306
                if( !hasFrame )
 
7307
                {
 
7308
 
 
7309
                    QRect slitRect( r );
 
7310
                    if( !( opts & Sunken ) )
 
7311
                    {
 
7312
                        // hover rect
 
7313
                        if( enabled && hoverAnimated )
 
7314
                        {
 
7315
 
 
7316
                            QColor glow( helper().alphaColor( helper().viewFocusBrush().brush( QPalette::Active ).color(), hoverOpacity ) );
 
7317
                            helper().slitFocused( glow )->render( slitRect, painter );
 
7318
 
 
7319
                        } else if( mouseOver ) {
 
7320
 
 
7321
                            helper().slitFocused( helper().viewFocusBrush().brush( QPalette::Active ).color() )->render( slitRect, painter );
 
7322
 
 
7323
                        }
 
7324
 
 
7325
                    } else {
 
7326
 
 
7327
                        slitRect.adjust( 0, 0, 0, -1 );
 
7328
 
 
7329
                        HoleOptions options( HoleContrast );
 
7330
                        if( mouseOver && enabled ) options |= HoleHover;
 
7331
 
 
7332
                        // flat pressed-down buttons do not get focus effect,
 
7333
                        // consistently with tool buttons
 
7334
                        if( enabled && hoverAnimated )
 
7335
                        {
 
7336
 
 
7337
                            helper().renderHole( painter, palette.color( QPalette::Window ), slitRect, options, hoverOpacity, AnimationHover, TileSet::Ring );
 
7338
 
 
7339
                        } else {
 
7340
 
 
7341
                            helper().renderHole( painter, palette.color( QPalette::Window ), slitRect, options );
 
7342
 
 
7343
                        }
 
7344
 
 
7345
                    }
 
7346
 
 
7347
                } else {
 
7348
 
 
7349
                    if( enabled && hoverAnimated )
 
7350
                    {
 
7351
 
 
7352
                        renderButtonSlab( painter, slabRect, buttonColor, opts, hoverOpacity, AnimationHover, TileSet::Ring );
 
7353
 
 
7354
                    } else if( enabled && focusAnimated ) {
 
7355
 
 
7356
                        renderButtonSlab( painter, slabRect, buttonColor, opts, focusOpacity, AnimationFocus, TileSet::Ring );
 
7357
 
 
7358
                    } else {
 
7359
 
 
7360
                        renderButtonSlab( painter, slabRect, buttonColor, opts );
 
7361
 
 
7362
                    }
 
7363
 
 
7364
                }
 
7365
 
 
7366
            }
 
7367
 
 
7368
        }
 
7369
 
 
7370
        if( cb->subControls & SC_ComboBoxArrow )
 
7371
        {
 
7372
 
 
7373
            const QComboBox* comboBox = qobject_cast<const QComboBox*>( widget );
 
7374
            const bool empty( comboBox && !comboBox->count() );
 
7375
 
 
7376
            QColor color;
 
7377
            QColor background;
 
7378
            bool drawContrast( true );
 
7379
 
 
7380
            if( cb->editable )
 
7381
            {
 
7382
 
 
7383
                if( enabled && empty ) color = palette.color( QPalette::Disabled,  QPalette::Text );
 
7384
                else {
 
7385
 
 
7386
                    // check animation state
 
7387
                    const bool subControlHover( enabled && mouseOver && cb->activeSubControls&SC_ComboBoxArrow );
 
7388
                    animations().comboBoxEngine().updateState( widget, AnimationHover, subControlHover  );
 
7389
 
 
7390
                    const bool animated( enabled && animations().comboBoxEngine().isAnimated( widget, AnimationHover ) );
 
7391
                    const qreal opacity( animations().comboBoxEngine().opacity( widget, AnimationHover ) );
 
7392
 
 
7393
                    if( animated )
 
7394
                    {
 
7395
 
 
7396
                        QColor highlight = helper().viewHoverBrush().brush( palette ).color();
 
7397
                        color = KColorUtils::mix( palette.color( QPalette::Text ), highlight, opacity );
 
7398
 
 
7399
                    } else if( subControlHover ) {
 
7400
 
 
7401
                        color = helper().viewHoverBrush().brush( palette ).color();
 
7402
 
 
7403
                    } else {
 
7404
 
 
7405
                        color = palette.color( QPalette::Text );
 
7406
 
 
7407
                    }
 
7408
 
 
7409
                }
 
7410
 
 
7411
                background = palette.color( QPalette::Background );
 
7412
 
 
7413
                if( enabled ) drawContrast = false;
 
7414
 
 
7415
            } else {
 
7416
 
 
7417
                // foreground color
 
7418
                const QPalette::ColorRole role( hasFrame ? QPalette::ButtonText : QPalette::WindowText );
 
7419
                if( enabled && empty ) color = palette.color( QPalette::Disabled,  role );
 
7420
                else color  = palette.color( role );
 
7421
 
 
7422
                // background color
 
7423
                background = palette.color( hasFrame ? QPalette::Button : QPalette::Window );
 
7424
 
 
7425
            }
 
7426
 
 
7427
            // draw the arrow
 
7428
            QRect arrowRect = comboBoxSubControlRect( option, SC_ComboBoxArrow, widget );
 
7429
 
 
7430
            const QPolygonF a( genericArrow( ArrowDown, ArrowNormal ) );
 
7431
            const qreal penThickness = 1.6;
 
7432
 
 
7433
            painter->save();
 
7434
            painter->translate( arrowRect.center() );
 
7435
            painter->setRenderHint( QPainter::Antialiasing );
 
7436
 
 
7437
            if( drawContrast )
 
7438
            {
 
7439
 
 
7440
                const qreal offset( qMin( penThickness, qreal( 1.0 ) ) );
 
7441
                painter->translate( 0,offset );
 
7442
                painter->setPen( QPen( helper().calcLightColor( palette.color( QPalette::Window ) ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
7443
                painter->drawPolyline( a );
 
7444
                painter->translate( 0,-offset );
 
7445
 
 
7446
            }
 
7447
 
 
7448
            painter->setPen( QPen( helper().decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
7449
            painter->drawPolyline( a );
 
7450
            painter->restore();
 
7451
 
 
7452
        }
 
7453
 
 
7454
        return true;
 
7455
 
 
7456
    }
 
7457
 
 
7458
    //______________________________________________________________
 
7459
    bool Style::drawDialComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const
 
7460
    {
 
7461
 
 
7462
        const State& flags( option->state );
 
7463
        const bool enabled = flags & State_Enabled;
 
7464
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
7465
        const bool hasFocus( enabled && ( flags & State_HasFocus ) );
 
7466
        const bool sunken( flags & ( State_On|State_Sunken ) );
 
7467
 
 
7468
        StyleOptions opts = 0;
 
7469
        if( sunken ) opts |= Sunken;
 
7470
        if( hasFocus ) opts |= Focus;
 
7471
        if( mouseOver ) opts |= Hover;
 
7472
 
 
7473
        // mouseOver has precedence over focus
 
7474
        animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
 
7475
        animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );
 
7476
 
 
7477
        const QRect rect( option->rect );
 
7478
        const QPalette &palette( option->palette );
 
7479
        const QColor buttonColor( helper().backgroundColor( palette.color( QPalette::Button ), widget, rect.center() ) );
 
7480
 
 
7481
        if( enabled && animations().widgetStateEngine().isAnimated( widget, AnimationHover ) && !( opts & Sunken ) )
 
7482
        {
 
7483
 
 
7484
            qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
 
7485
            renderDialSlab( painter, rect, buttonColor, option, opts, opacity, AnimationHover );
 
7486
 
 
7487
        } else if( enabled && !mouseOver && animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) && !( opts & Sunken ) ) {
 
7488
 
 
7489
            qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );
 
7490
            renderDialSlab( painter, rect, buttonColor, option, opts, opacity, AnimationFocus );
 
7491
 
 
7492
        } else {
 
7493
 
 
7494
            renderDialSlab( painter, rect, buttonColor, option, opts );
 
7495
 
 
7496
        }
 
7497
 
 
7498
        return true;
 
7499
 
 
7500
    }
 
7501
 
 
7502
    //______________________________________________________________
 
7503
    bool Style::drawGroupBoxComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const
 
7504
    {
 
7505
        const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>( option );
 
7506
        if( groupBox && groupBox->features & QStyleOptionFrameV2::Flat )
 
7507
        {
 
7508
 
 
7509
            // for flat groupboxes, the groupBox title is rendered bold
 
7510
            /*
 
7511
            TODO: talk to pinheiro. This is not an optimal design
 
7512
            I would rather
 
7513
            1/ keep the font unchanged
 
7514
            2/ add an horizontal separator next to the title
 
7515
            ( Hugo )
 
7516
            */
 
7517
            const QFont oldFont = painter->font();
 
7518
            QFont font = oldFont;
 
7519
            font.setBold( true );
 
7520
            painter->setFont( font );
 
7521
            QCommonStyle::drawComplexControl( CC_GroupBox, option, painter, widget );
 
7522
            painter->setFont( oldFont );
 
7523
            return true;
 
7524
 
 
7525
        } else return false;
 
7526
    }
 
7527
 
 
7528
    //______________________________________________________________
 
7529
    bool Style::drawQ3ListViewComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const
 
7530
    {
 
7531
 
 
7532
        const QStyleOptionQ3ListView* optListView( qstyleoption_cast<const QStyleOptionQ3ListView*>( option ) );
 
7533
        if( !optListView ) return true;
 
7534
 
 
7535
        // this is copied from skulpture code
 
7536
        // Copyright ( c ) 2007-2010 Christoph Feck <christoph@maxiom.de>
 
7537
        if( optListView->subControls & QStyle::SC_Q3ListView )
 
7538
        {
 
7539
            painter->fillRect(
 
7540
                optListView->rect,
 
7541
                optListView->viewportPalette.brush( optListView->viewportBGRole ) );
 
7542
        }
 
7543
 
 
7544
        if( optListView->subControls & QStyle::SC_Q3ListViewBranch )
 
7545
        {
 
7546
 
 
7547
            QStyleOption opt = *static_cast<const QStyleOption*>( option );
 
7548
            int y = optListView->rect.y();
 
7549
 
 
7550
            for ( int i = 1; i < optListView->items.size(); ++i )
 
7551
            {
 
7552
                QStyleOptionQ3ListViewItem item = optListView->items.at( i );
 
7553
                if( y + item.totalHeight > 0 && y < optListView->rect.height() )
 
7554
                {
 
7555
                    opt.state = QStyle::State_Item;
 
7556
                    if ( i + 1 < optListView->items.size() )
 
7557
                    { opt.state |= QStyle::State_Sibling; }
 
7558
 
 
7559
                    if(
 
7560
                        item.features & QStyleOptionQ3ListViewItem::Expandable
 
7561
                        || ( item.childCount > 0 && item.height > 0 ) )
 
7562
                    { opt.state |= QStyle::State_Children | ( item.state & QStyle::State_Open ); }
 
7563
 
 
7564
                    opt.rect = QRect( optListView->rect.left(), y, optListView->rect.width(), item.height );
 
7565
                    drawIndicatorBranchPrimitive( &opt, painter, widget );
 
7566
 
 
7567
                    if( ( opt.state & QStyle::State_Sibling ) && item.height < item.totalHeight )
 
7568
                    {
 
7569
                        opt.state = QStyle::State_Sibling;
 
7570
                        opt.rect = QRect(
 
7571
                            optListView->rect.left(), y + item.height,
 
7572
                            optListView->rect.width(), item.totalHeight - item.height );
 
7573
                        drawIndicatorBranchPrimitive( &opt, painter, widget );
 
7574
                    }
 
7575
                }
 
7576
 
 
7577
                y += item.totalHeight;
 
7578
            }
 
7579
        }
 
7580
 
 
7581
        return true;
 
7582
 
 
7583
    }
 
7584
 
 
7585
    //______________________________________________________________
 
7586
    bool Style::drawSliderComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const
 
7587
    {
 
7588
        const QStyleOptionSlider *slider( qstyleoption_cast<const QStyleOptionSlider *>( option ) );
 
7589
        if( !slider ) return true;
 
7590
 
 
7591
        const QPalette& palette( option->palette );
 
7592
        const State& flags( option->state );
 
7593
        const bool enabled( flags & State_Enabled );
 
7594
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
7595
        const bool hasFocus( flags & State_HasFocus );
 
7596
 
 
7597
        if( slider->subControls & SC_SliderTickmarks ) { renderSliderTickmarks( painter, slider, widget ); }
 
7598
 
 
7599
        // groove
 
7600
        if( slider->subControls & SC_SliderGroove )
 
7601
        {
 
7602
            const QRect groove = sliderSubControlRect( slider, SC_SliderGroove, widget );
 
7603
            const Qt::Orientation orientation( groove.width() > groove.height() ? Qt::Horizontal : Qt::Vertical );
 
7604
            if( groove.isValid() ) helper().scrollHole( palette.color( QPalette::Window ), orientation, true )->render( groove, painter, TileSet::Full );
 
7605
        }
 
7606
 
 
7607
        // handle
 
7608
        if ( slider->subControls & SC_SliderHandle )
 
7609
        {
 
7610
            const QRect handle = sliderSubControlRect( slider, SC_SliderHandle, widget );
 
7611
            const QRect r = centerRect( handle, 21, 21 );
 
7612
 
 
7613
            const bool handleActive( slider->activeSubControls & SC_SliderHandle );
 
7614
            StyleOptions opts( 0 );
 
7615
            if( hasFocus ) opts |= Focus;
 
7616
            if( handleActive && mouseOver ) opts |= Hover;
 
7617
 
 
7618
            animations().sliderEngine().updateState( widget, enabled && handleActive );
 
7619
            const qreal opacity( animations().sliderEngine().opacity( widget ) );
 
7620
 
 
7621
            const QColor color( helper().backgroundColor( palette.color( QPalette::Button ), widget, handle.center() ) );
 
7622
            const QColor glow( slabShadowColor( color, opts, opacity, AnimationHover ) );
 
7623
 
 
7624
            const bool sunken( flags & (State_On|State_Sunken) );
 
7625
            painter->drawPixmap( r.topLeft(), helper().sliderSlab( color, glow, sunken, 0.0 ) );
 
7626
 
 
7627
        }
 
7628
 
 
7629
        return true;
 
7630
    }
 
7631
 
 
7632
    //______________________________________________________________
 
7633
    bool Style::drawSpinBoxComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const
 
7634
    {
 
7635
        const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>( option );
 
7636
        if( !sb ) return true;
 
7637
 
 
7638
        const QRect& r( option->rect );
 
7639
        const QPalette& palette( option->palette );
 
7640
 
 
7641
        const State& flags( option->state );
 
7642
        const bool enabled( flags & State_Enabled );
 
7643
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
7644
        const bool hasFocus( flags & State_HasFocus );
 
7645
        const QColor inputColor( palette.color( QPalette::Base ) );
 
7646
 
 
7647
        if( sb->subControls & SC_SpinBoxFrame )
 
7648
        {
 
7649
 
 
7650
            QRect fr( r.adjusted( 1,1,-1,-1 ) );
 
7651
            painter->save();
 
7652
            painter->setRenderHint( QPainter::Antialiasing );
 
7653
            painter->setPen( Qt::NoPen );
 
7654
            painter->setBrush( inputColor );
 
7655
 
 
7656
            if( !sb->frame )
 
7657
            {
 
7658
                // frameless spinbox
 
7659
                // frame is adjusted to have the same dimensions as a frameless editor
 
7660
                painter->fillRect( r, inputColor );
 
7661
                painter->restore();
 
7662
 
 
7663
            } else {
 
7664
 
 
7665
                // normal spinbox
 
7666
                helper().fillHole( *painter, r.adjusted( 0, -1, 0, 0 ) );
 
7667
                painter->restore();
 
7668
 
 
7669
                HoleOptions options( 0 );
 
7670
                if( hasFocus && enabled ) options |= HoleFocus;
 
7671
                if( mouseOver && enabled ) options |= HoleHover;
 
7672
 
 
7673
                QColor local( palette.color( QPalette::Window ) );
 
7674
                animations().lineEditEngine().updateState( widget, AnimationHover, mouseOver );
 
7675
                animations().lineEditEngine().updateState( widget, AnimationFocus, hasFocus );
 
7676
                if( enabled && animations().lineEditEngine().isAnimated( widget, AnimationFocus ) )
 
7677
                {
 
7678
 
 
7679
                    helper().renderHole( painter, local, fr, options, animations().lineEditEngine().opacity( widget, AnimationFocus ), AnimationFocus, TileSet::Ring );
 
7680
 
 
7681
                } else if( enabled && animations().lineEditEngine().isAnimated( widget, AnimationHover ) ) {
 
7682
 
 
7683
                    helper().renderHole( painter, local, fr, options, animations().lineEditEngine().opacity( widget, AnimationHover ), AnimationHover, TileSet::Ring );
 
7684
 
 
7685
                } else {
 
7686
 
 
7687
                    helper().renderHole( painter, local, fr, options );
 
7688
 
 
7689
                }
 
7690
 
 
7691
            }
 
7692
        }
 
7693
 
 
7694
        if( sb->subControls & SC_SpinBoxUp ) renderSpinBoxArrow( painter, sb, widget, SC_SpinBoxUp );
 
7695
        if( sb->subControls & SC_SpinBoxDown ) renderSpinBoxArrow( painter, sb, widget, SC_SpinBoxDown );
 
7696
 
 
7697
        return true;
 
7698
 
 
7699
    }
 
7700
 
 
7701
    //______________________________________________________________
 
7702
    bool Style::drawTitleBarComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const
 
7703
    {
 
7704
        const QStyleOptionTitleBar *tb( qstyleoption_cast<const QStyleOptionTitleBar *>( option ) );
 
7705
        if( !tb ) return true;
 
7706
 
 
7707
        const State& flags( option->state );
 
7708
        const bool enabled( flags & State_Enabled );
 
7709
        const bool active( enabled && ( tb->titleBarState & Qt::WindowActive ) );
 
7710
 
 
7711
        // draw title text
 
7712
        {
 
7713
            QRect textRect = subControlRect( CC_TitleBar, tb, SC_TitleBarLabel, widget );
 
7714
 
 
7715
            // enable state transition
 
7716
            animations().widgetEnabilityEngine().updateState( widget, AnimationEnable, active );
 
7717
 
 
7718
            // make sure palette has the correct color group
 
7719
            QPalette palette( option->palette );
 
7720
 
 
7721
            if( animations().widgetEnabilityEngine().isAnimated( widget, AnimationEnable ) )
 
7722
            { palette = helper().mergePalettes( palette, animations().widgetEnabilityEngine().opacity( widget, AnimationEnable )  ); }
 
7723
 
 
7724
            palette.setCurrentColorGroup( active ? QPalette::Active: QPalette::Disabled );
 
7725
            QCommonStyle::drawItemText( painter, textRect, Qt::AlignCenter, palette, active, tb->text, QPalette::WindowText );
 
7726
 
 
7727
        }
 
7728
 
 
7729
 
 
7730
        // menu button
 
7731
        if( ( tb->subControls & SC_TitleBarSysMenu ) && ( tb->titleBarFlags & Qt::WindowSystemMenuHint ) && !tb->icon.isNull() )
 
7732
        {
 
7733
 
 
7734
            const QRect br = subControlRect( CC_TitleBar, tb, SC_TitleBarSysMenu, widget );
 
7735
            tb->icon.paint( painter, br );
 
7736
 
 
7737
        }
 
7738
 
 
7739
        if( ( tb->subControls & SC_TitleBarMinButton ) && ( tb->titleBarFlags & Qt::WindowMinimizeButtonHint ) )
 
7740
        { renderTitleBarButton( painter, tb, widget, SC_TitleBarMinButton ); }
 
7741
 
 
7742
        if( ( tb->subControls & SC_TitleBarMaxButton ) && ( tb->titleBarFlags & Qt::WindowMaximizeButtonHint ) )
 
7743
        { renderTitleBarButton( painter, tb, widget, SC_TitleBarMaxButton ); }
 
7744
 
 
7745
        if( ( tb->subControls & SC_TitleBarCloseButton ) )
 
7746
        { renderTitleBarButton( painter, tb, widget, SC_TitleBarCloseButton ); }
 
7747
 
 
7748
        if( ( tb->subControls & SC_TitleBarNormalButton ) &&
 
7749
            ( ( ( tb->titleBarFlags & Qt::WindowMinimizeButtonHint ) &&
 
7750
            ( tb->titleBarState & Qt::WindowMinimized ) ) ||
 
7751
            ( ( tb->titleBarFlags & Qt::WindowMaximizeButtonHint ) &&
 
7752
            ( tb->titleBarState & Qt::WindowMaximized ) ) ) )
 
7753
        { renderTitleBarButton( painter, tb, widget, SC_TitleBarNormalButton ); }
 
7754
 
 
7755
        if( tb->subControls & SC_TitleBarShadeButton )
 
7756
        { renderTitleBarButton( painter, tb, widget, SC_TitleBarShadeButton ); }
 
7757
 
 
7758
        if( tb->subControls & SC_TitleBarUnshadeButton )
 
7759
        { renderTitleBarButton( painter, tb, widget, SC_TitleBarUnshadeButton ); }
 
7760
 
 
7761
        if( ( tb->subControls & SC_TitleBarContextHelpButton ) && ( tb->titleBarFlags & Qt::WindowContextHelpButtonHint ) )
 
7762
        { renderTitleBarButton( painter, tb, widget, SC_TitleBarContextHelpButton ); }
 
7763
 
 
7764
        return true;
 
7765
    }
 
7766
 
 
7767
 
 
7768
    //______________________________________________________________
 
7769
    bool Style::drawToolButtonComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const
 
7770
    {
 
7771
 
 
7772
        // check autoRaise state
 
7773
        const State flags( option->state );
 
7774
        const bool isInToolBar( widget && qobject_cast<QToolBar*>( widget->parent() ) );
 
7775
 
 
7776
        // get rect and palette
 
7777
        const QRect& rect( option->rect );
 
7778
        const QStyleOptionToolButton *tool( qstyleoption_cast<const QStyleOptionToolButton *>( option ) );
 
7779
        if( !tool ) return true;
 
7780
 
 
7781
        const bool enabled( flags & State_Enabled );
 
7782
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
7783
        const bool hasFocus( enabled && ( flags&State_HasFocus ) );
 
7784
        const bool sunken( flags & ( State_Sunken|State_On ) );
 
7785
 
 
7786
        if( isInToolBar )
 
7787
        {
 
7788
 
 
7789
            animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
 
7790
 
 
7791
        } else {
 
7792
 
 
7793
            // mouseOver has precedence over focus
 
7794
            animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
 
7795
            animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus&&!mouseOver );
 
7796
 
 
7797
        }
 
7798
 
 
7799
        // toolbar animation
 
7800
        QWidget* parent( widget ? widget->parentWidget():0 );
 
7801
        const bool toolBarAnimated( isInToolBar && animations().toolBarEngine().isAnimated( parent ) );
 
7802
        const QRect animatedRect( animations().toolBarEngine().animatedRect( parent ) );
 
7803
        const QRect currentRect( animations().toolBarEngine().currentRect( parent ) );
 
7804
        const bool current( isInToolBar && currentRect.intersects( rect.translated( widget->mapToParent( QPoint( 0,0 ) ) ) ) );
 
7805
        const bool toolBarTimerActive( isInToolBar && animations().toolBarEngine().isTimerActive( widget->parentWidget() ) );
 
7806
 
 
7807
        // normal toolbutton animation
 
7808
        const bool hoverAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationHover ) );
 
7809
        const bool focusAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) );
 
7810
 
 
7811
        /* FIXME: this all logic is messy. The conditions to trigger the call to drawPrimitive can likely be simplified */
 
7812
 
 
7813
        // local copy of option
 
7814
        QStyleOptionToolButton tOpt( *tool );
 
7815
        tOpt.palette = option->palette;
 
7816
 
 
7817
        const QRect buttonRect( subControlRect( CC_ToolButton, tool, SC_ToolButton, widget ) );
 
7818
 
 
7819
        bool drawn(false);
 
7820
        if( enabled && !( mouseOver || hasFocus || sunken ) )
 
7821
        {
 
7822
 
 
7823
            if( hoverAnimated || ( focusAnimated && !hasFocus ) || ( ( ( toolBarAnimated && animatedRect.isNull() )||toolBarTimerActive ) && current ) )
 
7824
            {
 
7825
                tOpt.rect = buttonRect;
 
7826
                tOpt.state = flags;
 
7827
                drawPanelButtonToolPrimitive( &tOpt, painter, widget );
 
7828
                drawn = true;
 
7829
            }
 
7830
 
 
7831
        }
 
7832
 
 
7833
        // State_AutoRaise: only draw button when State_MouseOver
 
7834
        State bflags = tool->state;
 
7835
        if( bflags & State_AutoRaise && !( bflags & State_MouseOver ) )
 
7836
        { bflags &= ~State_Raised; }
 
7837
 
 
7838
        tOpt.state = bflags;
 
7839
 
 
7840
        if( tool->subControls & SC_ToolButton && ( bflags & ( State_Sunken | State_On | State_Raised ) ) && !drawn )
 
7841
        {
 
7842
            tOpt.rect = buttonRect;
 
7843
            drawPanelButtonToolPrimitive( &tOpt, painter, widget );
 
7844
        }
 
7845
 
 
7846
        if( tool->subControls & SC_ToolButtonMenu )
 
7847
        {
 
7848
 
 
7849
            tOpt.rect = subControlRect( CC_ToolButton, tool, SC_ToolButtonMenu, widget );
 
7850
            painter->save();
 
7851
            drawIndicatorButtonDropDownPrimitive( &tOpt, painter, widget );
 
7852
            painter->restore();
 
7853
 
 
7854
        } else if( tool->features & QStyleOptionToolButton::HasMenu ) {
 
7855
 
 
7856
            // This is requesting KDE3-style arrow indicator, per Qt 4.4 behavior. Qt 4.3 prefers to hide
 
7857
            // the fact of the menu's existence. Whee! Since we don't know how to paint this right,
 
7858
            // though, we have to have some metrics set for it to look nice.
 
7859
            const int size( ToolButton_InlineMenuIndicatorSize );
 
7860
            if( size )
 
7861
            {
 
7862
 
 
7863
                const int xOff( ToolButton_InlineMenuIndicatorXOff );
 
7864
                const int yOff( ToolButton_InlineMenuIndicatorYOff );
 
7865
 
 
7866
                tOpt.rect = QRect( buttonRect.right() + xOff + 1, buttonRect.bottom() + yOff + 1, size, size );
 
7867
                painter->save();
 
7868
                drawIndicatorButtonDropDownPrimitive( &tOpt, painter, widget );
 
7869
                painter->restore();
 
7870
 
 
7871
            }
 
7872
 
 
7873
        }
 
7874
 
 
7875
        // CE_ToolButtonLabel expects a readjusted rect, for the button area proper
 
7876
        QStyleOptionToolButton labelOpt = *tool;
 
7877
        labelOpt.rect = buttonRect;
 
7878
        drawToolButtonLabelControl( &labelOpt, painter, widget );
 
7879
 
 
7880
        return true;
 
7881
 
 
7882
    }
 
7883
 
 
7884
    //_____________________________________________________________________
 
7885
    void Style::oxygenConfigurationChanged( void )
 
7886
    {
 
7887
 
 
7888
        // reset helper configuration
 
7889
        helper().reloadConfig();
 
7890
 
 
7891
        // background pixmap
 
7892
        helper().setBackgroundPixmap( StyleConfigData::backgroundPixmap() );
 
7893
 
 
7894
        // reset config
 
7895
        StyleConfigData::self()->readConfig();
 
7896
 
 
7897
        // update caches size
 
7898
        int cacheSize( StyleConfigData::cacheEnabled() ?
 
7899
            StyleConfigData::maxCacheSize():0 );
 
7900
 
 
7901
        helper().setMaxCacheSize( cacheSize );
 
7902
 
 
7903
        // reinitialize engines
 
7904
        animations().setupEngines();
 
7905
        transitions().setupEngines();
 
7906
        windowManager().initialize();
 
7907
        shadowHelper().reloadConfig();
 
7908
 
 
7909
        // widget explorer
 
7910
        widgetExplorer().setEnabled( StyleConfigData::widgetExplorerEnabled() );
 
7911
        widgetExplorer().setDrawWidgetRects( StyleConfigData::drawWidgetRects() );
 
7912
 
 
7913
        // scrollbar button dimentions.
 
7914
        /* it has to be reinitialized here because scrollbar width might have changed */
 
7915
        _noButtonHeight = 0;
 
7916
        _singleButtonHeight = qMax( StyleConfigData::scrollBarWidth() * 7 / 10, 14 );
 
7917
        _doubleButtonHeight = 2*_singleButtonHeight;
 
7918
 
 
7919
        _showMnemonics = StyleConfigData::showMnemonics();
 
7920
 
 
7921
        // scrollbar buttons
 
7922
        switch( StyleConfigData::scrollBarAddLineButtons() )
 
7923
        {
 
7924
            case 0: _addLineButtons = NoButton; break;
 
7925
            case 1: _addLineButtons = SingleButton; break;
 
7926
 
 
7927
            default:
 
7928
            case 2: _addLineButtons = DoubleButton; break;
 
7929
        }
 
7930
 
 
7931
        switch( StyleConfigData::scrollBarSubLineButtons() )
 
7932
        {
 
7933
            case 0: _subLineButtons = NoButton; break;
 
7934
            case 1: _subLineButtons = SingleButton; break;
 
7935
 
 
7936
            default:
 
7937
            case 2: _subLineButtons = DoubleButton; break;
 
7938
        }
 
7939
 
 
7940
        // tabbar shape
 
7941
        switch( StyleConfigData::tabStyle() )
 
7942
        {
 
7943
            case StyleConfigData::TS_PLAIN:
 
7944
            _tabBarTabShapeControl = &Style::drawTabBarTabShapeControl_Plain;
 
7945
            break;
 
7946
 
 
7947
            default:
 
7948
            case StyleConfigData::TS_SINGLE:
 
7949
            _tabBarTabShapeControl = &Style::drawTabBarTabShapeControl_Single;
 
7950
            break;
 
7951
        }
 
7952
 
 
7953
        // frame focus
 
7954
        if( StyleConfigData::viewDrawFocusIndicator() ) _frameFocusPrimitive = &Style::drawFrameFocusRectPrimitive;
 
7955
        else _frameFocusPrimitive = &Style::emptyPrimitive;
 
7956
 
 
7957
    }
 
7958
 
 
7959
    //_____________________________________________________________________
 
7960
    void Style::globalPaletteChanged( void )
 
7961
    {
 
7962
        helper().reloadConfig();
 
7963
        helper().invalidateCaches();
 
7964
    }
 
7965
 
 
7966
    //____________________________________________________________________
 
7967
    QIcon Style::standardIconImplementation(
 
7968
        StandardPixmap standardIcon,
 
7969
        const QStyleOption *option,
 
7970
        const QWidget *widget ) const
 
7971
    {
 
7972
 
 
7973
        switch( standardIcon )
 
7974
        {
 
7975
 
 
7976
            // copied from kstyle
 
7977
            case SP_DesktopIcon: return KIcon( "user-desktop" );
 
7978
            case SP_TrashIcon: return KIcon( "user-trash" );
 
7979
            case SP_ComputerIcon: return KIcon( "computer" );
 
7980
            case SP_DriveFDIcon: return KIcon( "media-floppy" );
 
7981
            case SP_DriveHDIcon: return KIcon( "drive-harddisk" );
 
7982
            case SP_DriveCDIcon: return KIcon( "drive-optical" );
 
7983
            case SP_DriveDVDIcon: return KIcon( "drive-optical" );
 
7984
            case SP_DriveNetIcon: return KIcon( "folder-remote" );
 
7985
            case SP_DirHomeIcon: return KIcon( "user-home" );
 
7986
            case SP_DirOpenIcon: return KIcon( "document-open-folder" );
 
7987
            case SP_DirClosedIcon: return KIcon( "folder" );
 
7988
            case SP_DirIcon: return KIcon( "folder" );
 
7989
 
 
7990
            //TODO: generate ( !? ) folder with link emblem
 
7991
            case SP_DirLinkIcon: return KIcon( "folder" );
 
7992
 
 
7993
            //TODO: look for a better icon
 
7994
            case SP_FileIcon: return KIcon( "text-plain" );
 
7995
 
 
7996
            //TODO: generate ( !? ) file with link emblem
 
7997
            case SP_FileLinkIcon: return KIcon( "text-plain" );
 
7998
 
 
7999
            //TODO: find correct icon
 
8000
            case SP_FileDialogStart: return KIcon( "media-playback-start" );
 
8001
 
 
8002
            //TODO: find correct icon
 
8003
            case SP_FileDialogEnd: return KIcon( "media-playback-stop" );
 
8004
 
 
8005
            case SP_FileDialogToParent: return KIcon( "go-up" );
 
8006
            case SP_FileDialogNewFolder: return KIcon( "folder-new" );
 
8007
            case SP_FileDialogDetailedView: return KIcon( "view-list-details" );
 
8008
            case SP_FileDialogInfoView: return KIcon( "document-properties" );
 
8009
            case SP_FileDialogContentsView: return KIcon( "view-list-icons" );
 
8010
            case SP_FileDialogListView: return KIcon( "view-list-text" );
 
8011
            case SP_FileDialogBack: return KIcon( "go-previous" );
 
8012
            case SP_MessageBoxInformation: return KIcon( "dialog-information" );
 
8013
            case SP_MessageBoxWarning: return KIcon( "dialog-warning" );
 
8014
            case SP_MessageBoxCritical: return KIcon( "dialog-error" );
 
8015
            case SP_MessageBoxQuestion: return KIcon( "dialog-information" );
 
8016
            case SP_DialogOkButton: return KIcon( "dialog-ok" );
 
8017
            case SP_DialogCancelButton: return KIcon( "dialog-cancel" );
 
8018
            case SP_DialogHelpButton: return KIcon( "help-contents" );
 
8019
            case SP_DialogOpenButton: return KIcon( "document-open" );
 
8020
            case SP_DialogSaveButton: return KIcon( "document-save" );
 
8021
            case SP_DialogCloseButton: return KIcon( "dialog-close" );
 
8022
            case SP_DialogApplyButton: return KIcon( "dialog-ok-apply" );
 
8023
            case SP_DialogResetButton: return KIcon( "document-revert" );
 
8024
            case SP_DialogDiscardButton: return KIcon( "dialog-cancel" );
 
8025
            case SP_DialogYesButton: return KIcon( "dialog-ok-apply" );
 
8026
            case SP_DialogNoButton: return KIcon( "dialog-cancel" );
 
8027
            case SP_ArrowUp: return KIcon( "go-up" );
 
8028
            case SP_ArrowDown: return KIcon( "go-down" );
 
8029
            case SP_ArrowLeft: return KIcon( "go-previous-view" );
 
8030
            case SP_ArrowRight: return KIcon( "go-next-view" );
 
8031
            case SP_ArrowBack: return KIcon( "go-previous" );
 
8032
            case SP_ArrowForward: return KIcon( "go-next" );
 
8033
            case SP_BrowserReload: return KIcon( "view-refresh" );
 
8034
            case SP_BrowserStop: return KIcon( "process-stop" );
 
8035
            case SP_MediaPlay: return KIcon( "media-playback-start" );
 
8036
            case SP_MediaStop: return KIcon( "media-playback-stop" );
 
8037
            case SP_MediaPause: return KIcon( "media-playback-pause" );
 
8038
            case SP_MediaSkipForward: return KIcon( "media-skip-forward" );
 
8039
            case SP_MediaSkipBackward: return KIcon( "media-skip-backward" );
 
8040
            case SP_MediaSeekForward: return KIcon( "media-seek-forward" );
 
8041
            case SP_MediaSeekBackward: return KIcon( "media-seek-backward" );
 
8042
            case SP_MediaVolume: return KIcon( "audio-volume-medium" );
 
8043
            case SP_MediaVolumeMuted: return KIcon( "audio-volume-muted" );
 
8044
 
 
8045
            default: break;
 
8046
 
 
8047
        }
 
8048
 
 
8049
        // MDI windows buttons
 
8050
        // get button color ( unfortunately option and widget might not be set )
 
8051
        QColor buttonColor;
 
8052
        QColor iconColor;
 
8053
        if( option )
 
8054
        {
 
8055
 
 
8056
            buttonColor = option->palette.window().color();
 
8057
            iconColor   = option->palette.windowText().color();
 
8058
 
 
8059
        } else if( widget ) {
 
8060
 
 
8061
            buttonColor = widget->palette().window().color();
 
8062
            iconColor   = widget->palette().windowText().color();
 
8063
 
 
8064
        } else if( qApp ) {
 
8065
 
 
8066
            // might not have a QApplication
 
8067
            buttonColor = qApp->palette().window().color();
 
8068
            iconColor   = qApp->palette().windowText().color();
 
8069
 
 
8070
        } else {
 
8071
 
 
8072
            // KCS is always safe
 
8073
            buttonColor = KColorScheme( QPalette::Active, KColorScheme::Window, helper().config() ).background().color();
 
8074
            iconColor   = KColorScheme( QPalette::Active, KColorScheme::Window, helper().config() ).foreground().color();
 
8075
 
 
8076
        }
 
8077
 
 
8078
        switch( standardIcon )
 
8079
        {
 
8080
 
 
8081
            case SP_TitleBarNormalButton:
 
8082
            {
 
8083
                QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize,0,0 ), pixelMetric( QStyle::PM_SmallIconSize,0,0 ) );
 
8084
                realpm.fill( Qt::transparent );
 
8085
                QPixmap pm = helper().windecoButton( buttonColor, false, 15 );
 
8086
                QPainter painter( &realpm );
 
8087
                painter.drawPixmap( 1,1,pm );
 
8088
                painter.setRenderHints( QPainter::Antialiasing );
 
8089
 
 
8090
                // should use the same icons as in the deco
 
8091
                QPointF points[4] = {QPointF( 8.5, 6 ), QPointF( 11, 8.5 ), QPointF( 8.5, 11 ), QPointF( 6, 8.5 )};
 
8092
                {
 
8093
 
 
8094
                    const qreal width( 1.1 );
 
8095
                    painter.translate( 0, 0.5 );
 
8096
                    painter.setBrush( Qt::NoBrush );
 
8097
                    painter.setPen( QPen( helper().calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8098
                    painter.drawPolygon( points, 4 );
 
8099
                }
 
8100
 
 
8101
                {
 
8102
                    const qreal width( 1.1 );
 
8103
                    painter.translate( 0,-1 );
 
8104
                    painter.setBrush( Qt::NoBrush );
 
8105
                    painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8106
                    painter.drawPolygon( points, 4 );
 
8107
                }
 
8108
                painter.end();
 
8109
 
 
8110
                return QIcon( realpm );
 
8111
            }
 
8112
 
 
8113
            case SP_TitleBarShadeButton:
 
8114
            {
 
8115
                QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize,0,0 ), pixelMetric( QStyle::PM_SmallIconSize,0,0 ) );
 
8116
                realpm.fill( Qt::transparent );
 
8117
                QPixmap pm = helper().windecoButton( buttonColor, false, 15 );
 
8118
                QPainter painter( &realpm );
 
8119
                painter.drawPixmap( 1,1,pm );
 
8120
                painter.setRenderHints( QPainter::Antialiasing );
 
8121
                {
 
8122
 
 
8123
                    qreal width( 1.1 );
 
8124
                    painter.translate( 0, 0.5 );
 
8125
                    painter.setBrush( Qt::NoBrush );
 
8126
                    painter.setPen( QPen( helper().calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8127
                    painter.drawLine( QPointF( 6.5,6.5 ), QPointF( 8.75,8.75 ) );
 
8128
                    painter.drawLine( QPointF( 8.75,8.75 ), QPointF( 11.0,6.5 ) );
 
8129
                    painter.drawLine( QPointF( 6.5,11.0 ), QPointF( 11.0,11.0 ) );
 
8130
                }
 
8131
 
 
8132
                {
 
8133
                    qreal width( 1.1 );
 
8134
                    painter.translate( 0,-1 );
 
8135
                    painter.setBrush( Qt::NoBrush );
 
8136
                    painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8137
                    painter.drawLine( QPointF( 6.5,6.5 ), QPointF( 8.75,8.75 ) );
 
8138
                    painter.drawLine( QPointF( 8.75,8.75 ), QPointF( 11.0,6.5 ) );
 
8139
                    painter.drawLine( QPointF( 6.5,11.0 ), QPointF( 11.0,11.0 ) );
 
8140
                }
 
8141
 
 
8142
                painter.end();
 
8143
 
 
8144
                return QIcon( realpm );
 
8145
            }
 
8146
 
 
8147
            case SP_TitleBarUnshadeButton:
 
8148
            {
 
8149
                QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize,0,0 ), pixelMetric( QStyle::PM_SmallIconSize,0,0 ) );
 
8150
                realpm.fill( Qt::transparent );
 
8151
                QPixmap pm = helper().windecoButton( buttonColor, false, 15 );
 
8152
                QPainter painter( &realpm );
 
8153
                painter.drawPixmap( 1,1,pm );
 
8154
                painter.setRenderHints( QPainter::Antialiasing );
 
8155
 
 
8156
                {
 
8157
 
 
8158
                    qreal width( 1.1 );
 
8159
                    painter.translate( 0, 0.5 );
 
8160
                    painter.setBrush( Qt::NoBrush );
 
8161
                    painter.setPen( QPen( helper().calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8162
                    painter.drawLine( QPointF( 6.5,8.75 ), QPointF( 8.75,6.5 ) );
 
8163
                    painter.drawLine( QPointF( 8.75,6.5 ), QPointF( 11.0,8.75 ) );
 
8164
                    painter.drawLine( QPointF( 6.5,11.0 ), QPointF( 11.0,11.0 ) );
 
8165
                }
 
8166
 
 
8167
                {
 
8168
                    qreal width( 1.1 );
 
8169
                    painter.translate( 0,-1 );
 
8170
                    painter.setBrush( Qt::NoBrush );
 
8171
                    painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8172
                    painter.drawLine( QPointF( 6.5,8.75 ), QPointF( 8.75,6.5 ) );
 
8173
                    painter.drawLine( QPointF( 8.75,6.5 ), QPointF( 11.0,8.75 ) );
 
8174
                    painter.drawLine( QPointF( 6.5,11.0 ), QPointF( 11.0,11.0 ) );
 
8175
                }
 
8176
                painter.end();
 
8177
 
 
8178
                return QIcon( realpm );
 
8179
            }
 
8180
 
 
8181
            case SP_TitleBarCloseButton:
 
8182
            case SP_DockWidgetCloseButton:
 
8183
            {
 
8184
                QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize,0,0 ), pixelMetric( QStyle::PM_SmallIconSize,0,0 ) );
 
8185
                realpm.fill( Qt::transparent );
 
8186
                QPixmap pm = helper().windecoButton( buttonColor, false, 15 );
 
8187
                QPainter painter( &realpm );
 
8188
                painter.drawPixmap( 1,1,pm );
 
8189
                painter.setRenderHints( QPainter::Antialiasing );
 
8190
                painter.setBrush( Qt::NoBrush );
 
8191
                {
 
8192
 
 
8193
                    qreal width( 1.1 );
 
8194
                    painter.translate( 0, 0.5 );
 
8195
                    painter.setBrush( Qt::NoBrush );
 
8196
                    painter.setPen( QPen( helper().calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8197
                    painter.drawLine( QPointF( 6.5,6.5 ), QPointF( 11.0,11.0 ) );
 
8198
                    painter.drawLine( QPointF( 11.0,6.5 ), QPointF( 6.5,11.0 ) );
 
8199
                }
 
8200
 
 
8201
                {
 
8202
                    qreal width( 1.1 );
 
8203
                    painter.translate( 0,-1 );
 
8204
                    painter.setBrush( Qt::NoBrush );
 
8205
                    painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8206
                    painter.drawLine( QPointF( 6.5,6.5 ), QPointF( 11.0,11.0 ) );
 
8207
                    painter.drawLine( QPointF( 11.0,6.5 ), QPointF( 6.5,11.0 ) );
 
8208
                }
 
8209
 
 
8210
                painter.end();
 
8211
 
 
8212
                return QIcon( realpm );
 
8213
            }
 
8214
 
 
8215
            case SP_ToolBarHorizontalExtensionButton:
 
8216
            {
 
8217
 
 
8218
                QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize,0,0 ), pixelMetric( QStyle::PM_SmallIconSize,0,0 ) );
 
8219
                realpm.fill( Qt::transparent );
 
8220
                QPainter painter( &realpm );
 
8221
                painter.setRenderHints( QPainter::Antialiasing );
 
8222
                painter.setBrush( Qt::NoBrush );
 
8223
 
 
8224
                painter.translate( qreal( realpm.width() )/2.0, qreal( realpm.height() )/2.0 );
 
8225
 
 
8226
                const bool reverseLayout( option && option->direction == Qt::RightToLeft );
 
8227
                QPolygonF a = genericArrow( reverseLayout ? ArrowLeft:ArrowRight, ArrowTiny );
 
8228
                {
 
8229
                    qreal width( 1.1 );
 
8230
                    painter.translate( 0, 0.5 );
 
8231
                    painter.setBrush( Qt::NoBrush );
 
8232
                    painter.setPen( QPen( helper().calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8233
                    painter.drawPolyline( a );
 
8234
                }
 
8235
 
 
8236
                {
 
8237
                    qreal width( 1.1 );
 
8238
                    painter.translate( 0,-1 );
 
8239
                    painter.setBrush( Qt::NoBrush );
 
8240
                    painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8241
                    painter.drawPolyline( a );
 
8242
                }
 
8243
 
 
8244
                return QIcon( realpm );
 
8245
            }
 
8246
 
 
8247
            case SP_ToolBarVerticalExtensionButton:
 
8248
            {
 
8249
                QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize,0,0 ), pixelMetric( QStyle::PM_SmallIconSize,0,0 ) );
 
8250
                realpm.fill( Qt::transparent );
 
8251
                QPainter painter( &realpm );
 
8252
                painter.setRenderHints( QPainter::Antialiasing );
 
8253
                painter.setBrush( Qt::NoBrush );
 
8254
 
 
8255
                QPolygonF a = genericArrow( ArrowDown, ArrowTiny );
 
8256
                {
 
8257
                    qreal width( 1.1 );
 
8258
                    painter.translate( 0, 0.5 );
 
8259
                    painter.setBrush( Qt::NoBrush );
 
8260
                    painter.setPen( QPen( helper().calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8261
                    painter.drawPolyline( a );
 
8262
                }
 
8263
 
 
8264
                {
 
8265
                    qreal width( 1.1 );
 
8266
                    painter.translate( 0,-1 );
 
8267
                    painter.setBrush( Qt::NoBrush );
 
8268
                    painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8269
                    painter.drawPolyline( a );
 
8270
                }
 
8271
 
 
8272
                return QIcon( realpm );
 
8273
            }
 
8274
 
 
8275
            default:
 
8276
            return QCommonStyle::standardIconImplementation( standardIcon, option, widget );
 
8277
        }
 
8278
    }
 
8279
 
 
8280
    //_____________________________________________________________
 
8281
    void Style::initializeKGlobalSettings( void )
 
8282
    {
 
8283
 
 
8284
        if( qApp && !qApp->inherits( "KApplication" ) )
 
8285
        {
 
8286
            /*
 
8287
            for Qt, non-KDE applications, needs to explicitely activate KGlobalSettings.
 
8288
            On the other hand, it is done internally in kApplication constructor,
 
8289
            so no need to duplicate here.
 
8290
            */
 
8291
            KGlobalSettings::self()->activate( KGlobalSettings::ListenForChanges );
 
8292
        }
 
8293
 
 
8294
        // connect palette changes to local slot, to make sure caches are cleared
 
8295
        connect( KGlobalSettings::self(), SIGNAL( kdisplayPaletteChanged( void ) ), this, SLOT( globalPaletteChanged( void ) ) );
 
8296
 
 
8297
        // update flag
 
8298
        _kGlobalSettingsInitialized = true;
 
8299
 
 
8300
    }
 
8301
 
 
8302
    //______________________________________________________________
 
8303
    void Style::polishScrollArea( QAbstractScrollArea* scrollArea ) const
 
8304
    {
 
8305
 
 
8306
        if( !scrollArea ) return;
 
8307
 
 
8308
        // HACK: add exception for KPIM transactionItemView, which is an overlay widget
 
8309
        // and must have filled background. This is a temporary workaround until a more
 
8310
        // robust solution is found.
 
8311
        if( scrollArea->inherits( "KPIM::TransactionItemView" ) )
 
8312
        {
 
8313
            // also need to make the scrollarea background plain ( using autofill background )
 
8314
            // so that optional vertical scrollbar background is not transparent either.
 
8315
            // TODO: possibly add an event filter to use the "normal" window background
 
8316
            // instead of something flat.
 
8317
            scrollArea->setAutoFillBackground( true );
 
8318
            return;
 
8319
        }
 
8320
 
 
8321
        // check frame style and background role
 
8322
        if( !(scrollArea->frameShape() == QFrame::NoFrame || scrollArea->backgroundRole() == QPalette::Window ) )
 
8323
        { return; }
 
8324
 
 
8325
        // get viewport and check background role
 
8326
        QWidget* viewport( scrollArea->viewport() );
 
8327
        if( !( viewport && viewport->backgroundRole() == QPalette::Window ) ) return;
 
8328
 
 
8329
        // change viewport autoFill background.
 
8330
        // do the same for children if the background role is QPalette::Window
 
8331
        viewport->setAutoFillBackground( false );
 
8332
        QList<QWidget*> children( viewport->findChildren<QWidget*>() );
 
8333
        foreach( QWidget* child, children )
 
8334
        {
 
8335
            if( child->parent() == viewport && child->backgroundRole() == QPalette::Window )
 
8336
            { child->setAutoFillBackground( false ); }
 
8337
        }
 
8338
 
 
8339
    }
 
8340
 
 
8341
    //_______________________________________________________________
 
8342
    QRegion Style::tabBarClipRegion( const QTabBar* tabBar ) const
 
8343
    {
 
8344
        // need to mask-out arrow buttons, if visible.
 
8345
        QRegion mask( tabBar->rect() );
 
8346
        foreach( const QObject* child, tabBar->children() )
 
8347
        {
 
8348
            const QToolButton* toolButton( qobject_cast<const QToolButton*>( child ) );
 
8349
            if( toolButton && toolButton->isVisible() ) mask -= toolButton->geometry();
 
8350
        }
 
8351
 
 
8352
        return mask;
 
8353
 
 
8354
    }
 
8355
 
 
8356
    //_________________________________________________________________________________
 
8357
    void Style::renderDialSlab( QPainter *painter, const QRect& r, const QColor &color, const QStyleOption *option, StyleOptions opts, qreal opacity, AnimationMode mode ) const
 
8358
    {
 
8359
 
 
8360
        // cast option
 
8361
        const QStyleOptionSlider* sliderOption( qstyleoption_cast<const QStyleOptionSlider*>( option ) );
 
8362
        if( !sliderOption ) return;
 
8363
 
 
8364
        // adjust rect to be square, and centered
 
8365
        const int dimension( qMin( r.width(), r.height() ) );
 
8366
        const QRect rect( centerRect( r, dimension, dimension ) );
 
8367
 
 
8368
        // calculate glow color
 
8369
        const QColor glow( slabShadowColor( color, opts, opacity, mode ) );
 
8370
 
 
8371
        // get main slab
 
8372
        QPixmap pix( helper().dialSlab( color, glow, 0.0, dimension ) );
 
8373
        const qreal baseOffset( 3.5 );
 
8374
 
 
8375
        const QColor light( helper().calcLightColor( color ) );
 
8376
        const QColor shadow( helper().calcShadowColor( color ) );
 
8377
 
 
8378
        QPainter p( &pix );
 
8379
        p.setPen( Qt::NoPen );
 
8380
        p.setRenderHints( QPainter::Antialiasing );
 
8381
 
 
8382
        // indicator
 
8383
        qreal angle( 0 );
 
8384
        if( sliderOption->maximum == sliderOption->minimum ) angle = M_PI / 2;
 
8385
        else {
 
8386
 
 
8387
            qreal fraction( qreal( sliderOption->sliderPosition - sliderOption->minimum )/qreal( sliderOption->maximum - sliderOption->minimum ) );
 
8388
            if( !sliderOption->upsideDown ) fraction = 1.0 - fraction;
 
8389
 
 
8390
            if( sliderOption->dialWrapping ) angle = 1.5*M_PI - fraction*2*M_PI;
 
8391
            else  angle = ( M_PI*8 - fraction*10*M_PI )/6;
 
8392
        }
 
8393
 
 
8394
        QPointF center( pix.rect().center() );
 
8395
        const int sliderWidth( dimension/6 );
 
8396
        const qreal radius( 0.5*( dimension - 2*sliderWidth ) );
 
8397
        center += QPointF( radius*cos( angle ), -radius*sin( angle ) );
 
8398
 
 
8399
        QRectF sliderRect( 0, 0, sliderWidth, sliderWidth );
 
8400
        sliderRect.moveCenter( center );
 
8401
 
 
8402
        // outline circle
 
8403
        const qreal offset( 0.3 );
 
8404
        QLinearGradient lg( 0, baseOffset, 0, baseOffset + 2*sliderRect.height() );
 
8405
        p.setBrush( light );
 
8406
        p.setPen( Qt::NoPen );
 
8407
        p.drawEllipse( sliderRect.translated( 0, offset ) );
 
8408
 
 
8409
        // mask
 
8410
        p.setPen( Qt::NoPen );
 
8411
        p.save();
 
8412
        p.setCompositionMode( QPainter::CompositionMode_DestinationOut );
 
8413
        p.setBrush( QBrush( Qt::black ) );
 
8414
        p.drawEllipse( sliderRect );
 
8415
        p.restore();
 
8416
 
 
8417
        // shadow
 
8418
        p.translate( sliderRect.topLeft() );
 
8419
        helper().drawInverseShadow( p, shadow.darker( 200 ), 0.0, sliderRect.width(), 0.0 );
 
8420
 
 
8421
        // glow
 
8422
        if( glow.isValid() ) helper().drawInverseGlow( p, glow, 0.0, sliderRect.width(),  sliderRect.width() );
 
8423
 
 
8424
        p.end();
 
8425
 
 
8426
        painter->drawPixmap( rect.topLeft(), pix );
 
8427
 
 
8428
        return;
 
8429
 
 
8430
    }
 
8431
 
 
8432
    //____________________________________________________________________________________
 
8433
    void Style::renderButtonSlab( QPainter *painter, QRect r, const QColor &color, StyleOptions options, qreal opacity,
 
8434
        AnimationMode mode,
 
8435
        TileSet::Tiles tiles ) const
 
8436
    {
 
8437
        if( ( r.width() <= 0 ) || ( r.height() <= 0 ) ) return;
 
8438
 
 
8439
        r.translate( 0,-1 );
 
8440
        if( !painter->clipRegion().isEmpty() ) painter->setClipRegion( painter->clipRegion().translated( 0,-1 ) );
 
8441
 
 
8442
        // fill
 
8443
        if( !( options & NoFill ) ) helper().fillButtonSlab( *painter, r, color, options&Sunken );
 
8444
 
 
8445
        // edges
 
8446
        // for slabs, hover takes precedence over focus ( other way around for holes )
 
8447
        // but in any case if the button is sunken we don't show focus nor hover
 
8448
        TileSet *tile(0L);
 
8449
        if( options & Sunken )
 
8450
        {
 
8451
            tile = helper().slabSunken( color );
 
8452
 
 
8453
        } else {
 
8454
 
 
8455
            QColor glow = slabShadowColor( color, options, opacity, mode );
 
8456
            tile = helper().slab( color, glow, 0.0 );
 
8457
 
 
8458
        }
 
8459
 
 
8460
        if( tile )
 
8461
        { tile->render( r, painter, tiles ); }
 
8462
 
 
8463
    }
 
8464
 
 
8465
    //____________________________________________________________________________________
 
8466
    void Style::renderSlab(
 
8467
        QPainter *painter, QRect r,
 
8468
        const QColor &color,
 
8469
        StyleOptions options, qreal opacity,
 
8470
        AnimationMode mode,
 
8471
        TileSet::Tiles tiles ) const
 
8472
    {
 
8473
 
 
8474
        // check rect
 
8475
        if( !r.isValid() ) return;
 
8476
 
 
8477
        // this is needed for button vertical alignment
 
8478
        r.translate( 0,-1 );
 
8479
        if( !painter->clipRegion().isEmpty() ) painter->setClipRegion( painter->clipRegion().translated( 0,-1 ) );
 
8480
 
 
8481
        // additional adjustment for sunken frames
 
8482
        if( options & Sunken ) r.adjust( -1,0,1,2 );
 
8483
 
 
8484
        // fill
 
8485
        if( !( options & NoFill ) )
 
8486
        {
 
8487
            painter->save();
 
8488
            painter->setRenderHint( QPainter::Antialiasing );
 
8489
            painter->setPen( Qt::NoPen );
 
8490
 
 
8491
            if( helper().calcShadowColor( color ).value() > color.value() && ( options & Sunken ) )
 
8492
            {
 
8493
 
 
8494
                QLinearGradient innerGradient( 0, r.top(), 0, r.bottom() + r.height() );
 
8495
                innerGradient.setColorAt( 0.0, color );
 
8496
                innerGradient.setColorAt( 1.0, helper().calcLightColor( color ) );
 
8497
                painter->setBrush( innerGradient );
 
8498
 
 
8499
            } else {
 
8500
 
 
8501
                QLinearGradient innerGradient( 0, r.top() - r.height(), 0, r.bottom() );
 
8502
                innerGradient.setColorAt( 0.0, helper().calcLightColor( color ) );
 
8503
                innerGradient.setColorAt( 1.0, color );
 
8504
                painter->setBrush( innerGradient );
 
8505
 
 
8506
            }
 
8507
 
 
8508
            helper().fillSlab( *painter, r );
 
8509
 
 
8510
            painter->restore();
 
8511
        }
 
8512
 
 
8513
        // edges
 
8514
        // for slabs, hover takes precedence over focus ( other way around for holes )
 
8515
        // but in any case if the button is sunken we don't show focus nor hover
 
8516
        TileSet *tile( 0 );
 
8517
        if( ( options & Sunken ) && color.isValid() )
 
8518
        {
 
8519
            tile = helper().slabSunken( color );
 
8520
 
 
8521
        } else {
 
8522
 
 
8523
            // calculate proper glow color based on current settings and opacity
 
8524
            const QColor glow( slabShadowColor( color, options, opacity, mode ) );
 
8525
            if( color.isValid() || glow.isValid() ) tile = helper().slab( color, glow , 0.0 );
 
8526
            else return;
 
8527
 
 
8528
        }
 
8529
 
 
8530
        // render tileset
 
8531
        if( tile ) tile->render( r, painter, tiles );
 
8532
 
 
8533
    }
 
8534
 
 
8535
    //______________________________________________________________________________________________________________________________
 
8536
    void Style::fillTabBackground( QPainter* painter, const QRect &r, const QColor &color, QTabBar::Shape shape, const QWidget* widget ) const
 
8537
    {
 
8538
 
 
8539
        // filling
 
8540
        QRect fillRect( r );
 
8541
        switch( shape )
 
8542
        {
 
8543
            case QTabBar::RoundedNorth:
 
8544
            case QTabBar::TriangularNorth:
 
8545
            fillRect.adjust( 4, 4, -4, -6 );
 
8546
            break;
 
8547
 
 
8548
            case QTabBar::RoundedSouth:
 
8549
            case QTabBar::TriangularSouth:
 
8550
            fillRect.adjust( 4, 4, -4, -4 );
 
8551
            break;
 
8552
 
 
8553
            case QTabBar::RoundedWest:
 
8554
            case QTabBar::TriangularWest:
 
8555
            fillRect.adjust( 4, 3, -5, -5 );
 
8556
            break;
 
8557
 
 
8558
            case QTabBar::RoundedEast:
 
8559
            case QTabBar::TriangularEast:
 
8560
            fillRect.adjust( 5, 3, -4, -5 );
 
8561
            break;
 
8562
 
 
8563
            default: return;
 
8564
 
 
8565
        }
 
8566
 
 
8567
        if( widget ) helper().renderWindowBackground( painter, fillRect, widget, color );
 
8568
        else painter->fillRect( fillRect, color );
 
8569
 
 
8570
    }
 
8571
 
 
8572
    //______________________________________________________________________________________________________________________________
 
8573
    void Style::fillTab( QPainter* painter, const QRect &r, const QColor &color, QTabBar::Shape shape, bool active ) const
 
8574
    {
 
8575
 
 
8576
        const QColor dark( helper().calcDarkColor( color ) );
 
8577
        const QColor shadow( helper().calcShadowColor( color ) );
 
8578
        const QColor light( helper().calcLightColor( color ) );
 
8579
        const QRect fillRect( r.adjusted( 4, 3,-4,-5 ) );
 
8580
 
 
8581
        QLinearGradient highlight;
 
8582
        switch( shape )
 
8583
        {
 
8584
            case QTabBar::RoundedNorth:
 
8585
            case QTabBar::TriangularNorth:
 
8586
            highlight = QLinearGradient( fillRect.topLeft(), fillRect.bottomLeft() );
 
8587
            break;
 
8588
 
 
8589
            case QTabBar::RoundedSouth:
 
8590
            case QTabBar::TriangularSouth:
 
8591
            highlight = QLinearGradient( fillRect.bottomLeft(), fillRect.topLeft() );
 
8592
            break;
 
8593
 
 
8594
            case QTabBar::RoundedEast:
 
8595
            case QTabBar::TriangularEast:
 
8596
            highlight = QLinearGradient( fillRect.topRight(), fillRect.topLeft() );
 
8597
            break;
 
8598
 
 
8599
            case QTabBar::RoundedWest:
 
8600
            case QTabBar::TriangularWest:
 
8601
            highlight = QLinearGradient( fillRect.topLeft(), fillRect.topRight() );
 
8602
            break;
 
8603
 
 
8604
            default: return;
 
8605
 
 
8606
        }
 
8607
 
 
8608
        if( active ) {
 
8609
 
 
8610
            highlight.setColorAt( 0.0, helper().alphaColor( light, 0.5 ) );
 
8611
            highlight.setColorAt( 0.1, helper().alphaColor( light, 0.5 ) );
 
8612
            highlight.setColorAt( 0.25, helper().alphaColor( light, 0.3 ) );
 
8613
            highlight.setColorAt( 0.5, helper().alphaColor( light, 0.2 ) );
 
8614
            highlight.setColorAt( 0.75, helper().alphaColor( light, 0.1 ) );
 
8615
            highlight.setColorAt( 0.9, Qt::transparent );
 
8616
 
 
8617
        } else {
 
8618
 
 
8619
            // inactive
 
8620
            highlight.setColorAt( 0.0, helper().alphaColor( light, 0.1 ) );
 
8621
            highlight.setColorAt( 0.4, helper().alphaColor( dark, 0.5 ) );
 
8622
            highlight.setColorAt( 0.8, helper().alphaColor( dark, 0.4 ) );
 
8623
            highlight.setColorAt( 0.9, Qt::transparent );
 
8624
 
 
8625
        }
 
8626
 
 
8627
        painter->setRenderHints( QPainter::Antialiasing );
 
8628
        painter->setPen( Qt::NoPen );
 
8629
 
 
8630
        painter->setBrush( highlight );
 
8631
        painter->drawRoundedRect( fillRect, 2, 2 );
 
8632
 
 
8633
    }
 
8634
 
 
8635
    //____________________________________________________________________________________________________
 
8636
    void Style::renderSpinBoxArrow( QPainter* painter, const QStyleOptionSpinBox* option, const QWidget* widget, const SubControl& subControl ) const
 
8637
    {
 
8638
 
 
8639
        const QPalette& palette( option->palette );
 
8640
 
 
8641
        const State& flags( option->state );
 
8642
 
 
8643
        bool enabled( flags & State_Enabled );
 
8644
        bool atLimit( false );
 
8645
        if( enabled )
 
8646
        {
 
8647
 
 
8648
            if( const QSpinBox* spinbox = qobject_cast<const QSpinBox*>( widget ) )
 
8649
            {
 
8650
 
 
8651
                // cast to spinbox and check if at limit
 
8652
                const int value( spinbox->value() );
 
8653
                if( !spinbox->wrapping() && (( subControl == SC_SpinBoxUp && value == spinbox->maximum() ) ||
 
8654
                    ( subControl == SC_SpinBoxDown && value == spinbox->minimum() ) ) )
 
8655
                    { atLimit = true; }
 
8656
 
 
8657
            } else if( const QDoubleSpinBox* spinbox = qobject_cast<const QDoubleSpinBox*>( widget ) ) {
 
8658
 
 
8659
                // cast to spinbox and check if at limit
 
8660
                const double value( spinbox->value() );
 
8661
                if( !spinbox->wrapping() && (( subControl == SC_SpinBoxUp && value == spinbox->maximum() ) ||
 
8662
                    ( subControl == SC_SpinBoxDown && value == spinbox->minimum() ) ) )
 
8663
                    { atLimit = true; }
 
8664
 
 
8665
            }
 
8666
 
 
8667
        }
 
8668
 
 
8669
        enabled &= !atLimit;
 
8670
        const bool mouseOver( enabled && ( flags & State_MouseOver ) );
 
8671
 
 
8672
        // check animation state
 
8673
        const bool subControlHover( enabled && mouseOver && ( option->activeSubControls & subControl ) );
 
8674
        animations().spinBoxEngine().updateState( widget, subControl, subControlHover );
 
8675
 
 
8676
        const bool animated( enabled && animations().spinBoxEngine().isAnimated( widget, subControl ) );
 
8677
        const qreal opacity( animations().spinBoxEngine().opacity( widget, subControl ) );
 
8678
 
 
8679
        QColor color;
 
8680
        if( animated )
 
8681
        {
 
8682
 
 
8683
            QColor highlight = helper().viewHoverBrush().brush( palette ).color();
 
8684
            color = KColorUtils::mix( palette.color( QPalette::Text ), highlight, opacity );
 
8685
 
 
8686
        } else if( subControlHover ) {
 
8687
 
 
8688
            color = helper().viewHoverBrush().brush( palette ).color();
 
8689
 
 
8690
        } else if( atLimit ) {
 
8691
 
 
8692
            color = palette.color( QPalette::Disabled, QPalette::Text );
 
8693
 
 
8694
        } else {
 
8695
 
 
8696
            color = palette.color( QPalette::Text );
 
8697
 
 
8698
        }
 
8699
 
 
8700
        const qreal penThickness = 1.6;
 
8701
        const QColor background = palette.color( QPalette::Background );
 
8702
 
 
8703
        const QPolygonF a( genericArrow( ( subControl == SC_SpinBoxUp ) ? ArrowUp:ArrowDown, ArrowNormal ) );
 
8704
        const QRect arrowRect( subControlRect( CC_SpinBox, option, subControl, widget ) );
 
8705
 
 
8706
        painter->save();
 
8707
        painter->translate( arrowRect.center() );
 
8708
        painter->setRenderHint( QPainter::Antialiasing );
 
8709
 
 
8710
        painter->setPen( QPen( helper().decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8711
        painter->drawPolyline( a );
 
8712
        painter->restore();
 
8713
 
 
8714
        return;
 
8715
 
 
8716
    }
 
8717
 
 
8718
    //___________________________________________________________________________________
 
8719
    void Style::renderSplitter( const QStyleOption* option, QPainter* painter, const QWidget* widget, bool horizontal ) const
 
8720
    {
 
8721
 
 
8722
        const QPalette& palette( option->palette );
 
8723
        const QRect& r( option->rect );
 
8724
        const State& flags( option->state );
 
8725
        const bool enabled( flags & State_Enabled );
 
8726
        const bool mouseOver( enabled && ( flags & ( State_MouseOver|State_Sunken ) ) );
 
8727
 
 
8728
        // get orientation
 
8729
        const Qt::Orientation orientation( horizontal ? Qt::Horizontal : Qt::Vertical );
 
8730
 
 
8731
        bool animated( false );
 
8732
        qreal opacity( AnimationData::OpacityInvalid );
 
8733
 
 
8734
        if( enabled )
 
8735
        {
 
8736
            if( qobject_cast<const QMainWindow*>( widget ) )
 
8737
            {
 
8738
 
 
8739
                animations().dockSeparatorEngine().updateRect( widget, r, orientation, mouseOver );
 
8740
                animated = animations().dockSeparatorEngine().isAnimated( widget, r, orientation );
 
8741
                opacity = animated ? animations().dockSeparatorEngine().opacity( widget, orientation ) : AnimationData::OpacityInvalid;
 
8742
 
 
8743
            } else if(  QPaintDevice* device = painter->device() ) {
 
8744
 
 
8745
                /*
 
8746
                try update QSplitterHandle using painter device, because Qt passes
 
8747
                QSplitter as the widget to the QStyle primitive.
 
8748
                */
 
8749
                animations().splitterEngine().updateState( device, mouseOver );
 
8750
                animated = animations().splitterEngine().isAnimated( device );
 
8751
                opacity = animations().splitterEngine().opacity( device );
 
8752
 
 
8753
            }
 
8754
        }
 
8755
 
 
8756
        // get base color
 
8757
        const QColor color = palette.color( QPalette::Background );
 
8758
 
 
8759
        if( horizontal )
 
8760
        {
 
8761
            const int h = r.height();
 
8762
 
 
8763
            if( animated || mouseOver )
 
8764
            {
 
8765
                const QColor highlight = helper().alphaColor( helper().calcLightColor( color ),0.5*( animated ? opacity:1.0 ) );
 
8766
                const qreal a( r.height() > 30 ? 10.0/r.height():0.1 );
 
8767
                QLinearGradient lg( 0, r.top(), 0, r.bottom() );
 
8768
                lg.setColorAt( 0, Qt::transparent );
 
8769
                lg.setColorAt( a, highlight );
 
8770
                lg.setColorAt( 1.0-a, highlight );
 
8771
                lg.setColorAt( 1, Qt::transparent );
 
8772
                painter->fillRect( r, lg );
 
8773
            }
 
8774
 
 
8775
            const int ngroups( qMax( 1,h / 250 ) );
 
8776
            int center( ( h - ( ngroups-1 ) * 250 ) /2 + r.top() );
 
8777
            for( int k = 0; k < ngroups; k++, center += 250 )
 
8778
            {
 
8779
                helper().renderDot( painter, QPoint( r.left()+1, center-3 ), color );
 
8780
                helper().renderDot( painter, QPoint( r.left()+1, center ), color );
 
8781
                helper().renderDot( painter, QPoint( r.left()+1, center+3 ), color );
 
8782
            }
 
8783
 
 
8784
        } else {
 
8785
 
 
8786
            const int w( r.width() );
 
8787
            if( animated || mouseOver )
 
8788
            {
 
8789
                const QColor highlight( helper().alphaColor( helper().calcLightColor( color ),0.5*( animated ? opacity:1.0 ) ) );
 
8790
                const qreal a( r.width() > 30 ? 10.0/r.width():0.1 );
 
8791
                QLinearGradient lg( r.left(), 0, r.right(), 0 );
 
8792
                lg.setColorAt( 0, Qt::transparent );
 
8793
                lg.setColorAt( a, highlight );
 
8794
                lg.setColorAt( 1.0-a, highlight );
 
8795
                lg.setColorAt( 1, Qt::transparent );
 
8796
                painter->fillRect( r, lg );
 
8797
 
 
8798
            }
 
8799
 
 
8800
            const int ngroups( qMax( 1, w / 250 ) );
 
8801
            int center = ( w - ( ngroups-1 ) * 250 ) /2 + r.left();
 
8802
            for( int k = 0; k < ngroups; k++, center += 250 )
 
8803
            {
 
8804
                helper().renderDot( painter, QPoint( center-3, r.top()+1 ), color );
 
8805
                helper().renderDot( painter, QPoint( center, r.top()+1 ), color );
 
8806
                helper().renderDot( painter, QPoint( center+3, r.top()+1 ), color );
 
8807
            }
 
8808
 
 
8809
        }
 
8810
 
 
8811
    }
 
8812
 
 
8813
    //____________________________________________________________________________________________________
 
8814
    void Style::renderTitleBarButton( QPainter* painter, const QStyleOptionTitleBar* option, const QWidget* widget, const SubControl& subControl ) const
 
8815
    {
 
8816
 
 
8817
        const QRect r = subControlRect( CC_TitleBar, option, subControl, widget );
 
8818
        if( !r.isValid() ) return;
 
8819
 
 
8820
        QPalette palette = option->palette;
 
8821
 
 
8822
        painter->save();
 
8823
        painter->drawPixmap( r, helper().windecoButton( palette.window().color(), true, r.height() ) );
 
8824
        painter->setRenderHints( QPainter::Antialiasing );
 
8825
        painter->setBrush( Qt::NoBrush );
 
8826
 
 
8827
        const State& flags( option->state );
 
8828
        const bool enabled( flags & State_Enabled );
 
8829
        const bool active( enabled && ( option->titleBarState & Qt::WindowActive ) );
 
8830
 
 
8831
        // enable state transition
 
8832
        animations().widgetEnabilityEngine().updateState( widget, AnimationEnable, active );
 
8833
        if( animations().widgetEnabilityEngine().isAnimated( widget, AnimationEnable ) )
 
8834
        { palette = helper().mergePalettes( palette, animations().widgetEnabilityEngine().opacity( widget, AnimationEnable )  ); }
 
8835
 
 
8836
        const bool sunken( flags&State_Sunken );
 
8837
        const bool mouseOver( ( !sunken ) && widget && r.translated( widget->mapToGlobal( QPoint( 0,0 ) ) ).contains( QCursor::pos() ) );
 
8838
 
 
8839
        animations().mdiWindowEngine().updateState( widget, subControl, enabled && mouseOver );
 
8840
        const bool animated( enabled && animations().mdiWindowEngine().isAnimated( widget, subControl ) );
 
8841
        const qreal opacity( animations().mdiWindowEngine().opacity( widget, subControl ) );
 
8842
 
 
8843
        {
 
8844
 
 
8845
            // contrast pixel
 
8846
            const QColor contrast = helper().calcLightColor( option->palette.color( QPalette::Active, QPalette::Window ) );
 
8847
            const qreal width( 1.1 );
 
8848
            painter->translate( 0, 0.5 );
 
8849
            painter->setPen( QPen( contrast, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8850
            renderTitleBarIcon( painter, QRectF( r ).adjusted( -2.5,-2.5,0,0 ), subControl );
 
8851
 
 
8852
        }
 
8853
 
 
8854
        {
 
8855
 
 
8856
            // button color
 
8857
            QColor color;
 
8858
            if( animated )
 
8859
            {
 
8860
 
 
8861
                const QColor base( palette.color( active ? QPalette::Active : QPalette::Disabled, QPalette::WindowText ) );
 
8862
                const QColor glow( subControl == SC_TitleBarCloseButton ?
 
8863
                    helper().viewNegativeTextBrush().brush( palette ).color():
 
8864
                    helper().viewHoverBrush().brush( palette ).color() );
 
8865
 
 
8866
                color = KColorUtils::mix( base, glow, opacity );
 
8867
 
 
8868
            } else if( mouseOver ) {
 
8869
 
 
8870
                color = ( subControl == SC_TitleBarCloseButton ) ?
 
8871
                    helper().viewNegativeTextBrush().brush( palette ).color():
 
8872
                    helper().viewHoverBrush().brush( palette ).color();
 
8873
 
 
8874
            } else {
 
8875
 
 
8876
                color = palette.color( active ? QPalette::Active : QPalette::Disabled, QPalette::WindowText );
 
8877
 
 
8878
            }
 
8879
 
 
8880
            // main icon painting
 
8881
            const qreal width( 1.1 );
 
8882
            painter->translate( 0,-1 );
 
8883
            painter->setPen( QPen( color, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
8884
            renderTitleBarIcon( painter, QRectF( r ).adjusted( -2.5,-2.5,0,0 ), subControl );
 
8885
 
 
8886
        }
 
8887
 
 
8888
        painter->restore();
 
8889
 
 
8890
    }
 
8891
 
 
8892
    //____________________________________________________________________________________
 
8893
    void Style::renderTitleBarIcon( QPainter *painter, const QRectF &r, const SubControl& subControl ) const
 
8894
    {
 
8895
 
 
8896
        painter->save();
 
8897
        painter->translate( r.topLeft() );
 
8898
        switch( subControl )
 
8899
        {
 
8900
            case SC_TitleBarContextHelpButton:
 
8901
            {
 
8902
                painter->translate( 1.5, 1.5 );
 
8903
                painter->drawArc( 7,5,4,4,135*16, -180*16 );
 
8904
                painter->drawArc( 9,8,4,4,135*16,45*16 );
 
8905
                painter->drawPoint( 9,12 );
 
8906
                break;
 
8907
            }
 
8908
            case SC_TitleBarMinButton:
 
8909
            {
 
8910
                painter->drawLine( QPointF( 7.5, 9.5 ), QPointF( 10.5,12.5 ) );
 
8911
                painter->drawLine( QPointF( 10.5,12.5 ), QPointF( 13.5, 9.5 ) );
 
8912
                break;
 
8913
            }
 
8914
            case SC_TitleBarNormalButton:
 
8915
            {
 
8916
                painter->translate( 1.5, 1.5 );
 
8917
                QPoint points[4] = {QPoint( 9, 6 ), QPoint( 12, 9 ), QPoint( 9, 12 ), QPoint( 6, 9 )};
 
8918
                painter->drawPolygon( points, 4 );
 
8919
                break;
 
8920
            }
 
8921
            case SC_TitleBarMaxButton:
 
8922
            {
 
8923
                painter->drawLine( QPointF( 7.5,11.5 ), QPointF( 10.5, 8.5 ) );
 
8924
                painter->drawLine( QPointF( 10.5, 8.5 ), QPointF( 13.5,11.5 ) );
 
8925
                break;
 
8926
            }
 
8927
            case SC_TitleBarCloseButton:
 
8928
            {
 
8929
                painter->drawLine( QPointF( 7.5,7.5 ), QPointF( 13.5,13.5 ) );
 
8930
                painter->drawLine( QPointF( 13.5,7.5 ), QPointF( 7.5,13.5 ) );
 
8931
                break;
 
8932
            }
 
8933
            case SC_TitleBarShadeButton:
 
8934
            {
 
8935
                painter->drawLine( QPointF( 7.5, 13.5 ), QPointF( 13.5, 13.5 ) );
 
8936
                painter->drawLine( QPointF( 7.5, 7.5 ), QPointF( 10.5,10.5 ) );
 
8937
                painter->drawLine( QPointF( 10.5,10.5 ), QPointF( 13.5, 7.5 ) );
 
8938
                break;
 
8939
            }
 
8940
            case SC_TitleBarUnshadeButton:
 
8941
            {
 
8942
                painter->drawLine( QPointF( 7.5,10.5 ), QPointF( 10.5, 7.5 ) );
 
8943
                painter->drawLine( QPointF( 10.5, 7.5 ), QPointF( 13.5,10.5 ) );
 
8944
                painter->drawLine( QPointF( 7.5,13.0 ), QPointF( 13.5,13.0 ) );
 
8945
                break;
 
8946
            }
 
8947
            default:
 
8948
            break;
 
8949
        }
 
8950
        painter->restore();
 
8951
    }
 
8952
 
 
8953
    //__________________________________________________________________________
 
8954
    void Style::renderHeaderBackground( const QRect& r, const QPalette& palette, QPainter* painter, const QWidget* widget, bool horizontal, bool reverse ) const
 
8955
    {
 
8956
 
 
8957
        // use window background for the background
 
8958
        if( widget ) helper().renderWindowBackground( painter, r, widget, palette );
 
8959
        else painter->fillRect( r, palette.color( QPalette::Window ) );
 
8960
 
 
8961
        if( horizontal ) renderHeaderLines( r, palette, painter, TileSet::Bottom );
 
8962
        else if( reverse ) renderHeaderLines( r, palette, painter, TileSet::Left );
 
8963
        else renderHeaderLines( r, palette, painter, TileSet::Right );
 
8964
 
 
8965
    }
 
8966
 
 
8967
    //__________________________________________________________________________
 
8968
    void Style::renderHeaderLines( const QRect& r, const QPalette& palette, QPainter* painter, TileSet::Tiles tiles ) const
 
8969
    {
 
8970
 
 
8971
        // add horizontal lines
 
8972
        const QColor color( palette.color( QPalette::Window ) );
 
8973
        const QColor dark( helper().calcDarkColor( color ) );
 
8974
        const QColor light( helper().calcLightColor( color ) );
 
8975
 
 
8976
        painter->save();
 
8977
        QRect rect( r );
 
8978
        if( tiles & TileSet::Bottom  )
 
8979
        {
 
8980
 
 
8981
            painter->setPen( dark );
 
8982
            if( tiles & TileSet::Left ) painter->drawPoint( rect.bottomLeft() );
 
8983
            else if( tiles& TileSet::Right ) painter->drawPoint( rect.bottomRight() );
 
8984
            else painter->drawLine( rect.bottomLeft(), rect.bottomRight() );
 
8985
 
 
8986
            rect.adjust( 0,0,0,-1 );
 
8987
            painter->setPen( light );
 
8988
            if( tiles & TileSet::Left )
 
8989
            {
 
8990
                painter->drawLine( rect.bottomLeft(), rect.bottomLeft()+QPoint( 1, 0 ) );
 
8991
                painter->drawLine( rect.bottomLeft()+ QPoint( 1, 0 ), rect.bottomLeft()+QPoint( 1, 1 ) );
 
8992
 
 
8993
            } else if( tiles & TileSet::Right ) {
 
8994
 
 
8995
                painter->drawLine( rect.bottomRight(), rect.bottomRight() - QPoint( 1, 0 ) );
 
8996
                painter->drawLine( rect.bottomRight() - QPoint( 1, 0 ), rect.bottomRight() - QPoint( 1, -1 ) );
 
8997
 
 
8998
            } else {
 
8999
 
 
9000
                painter->drawLine( rect.bottomLeft(), rect.bottomRight() );
 
9001
            }
 
9002
        } else if( tiles & TileSet::Left ) {
 
9003
 
 
9004
            painter->setPen( dark );
 
9005
            painter->drawLine( rect.topLeft(), rect.bottomLeft() );
 
9006
 
 
9007
            rect.adjust( 1,0,0,0 );
 
9008
            painter->setPen( light );
 
9009
            painter->drawLine( rect.topLeft(), rect.bottomLeft() );
 
9010
 
 
9011
        } else if( tiles & TileSet::Right ) {
 
9012
 
 
9013
            painter->setPen( dark );
 
9014
            painter->drawLine( rect.topRight(), rect.bottomRight() );
 
9015
 
 
9016
            rect.adjust( 0,0,-1,0 );
 
9017
            painter->setPen( light );
 
9018
            painter->drawLine( rect.topRight(), rect.bottomRight() );
 
9019
 
 
9020
        }
 
9021
 
 
9022
        painter->restore();
 
9023
 
 
9024
        return;
 
9025
 
 
9026
    }
 
9027
 
 
9028
    //__________________________________________________________________________
 
9029
    void Style::renderMenuItemBackground( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
 
9030
    {
 
9031
        const QRect& r( option->rect );
 
9032
        const QPalette& palette( option->palette );
 
9033
        const QRect animatedRect( animations().menuEngine().animatedRect( widget ) );
 
9034
        if( !animatedRect.isNull() )
 
9035
        {
 
9036
 
 
9037
            if( animatedRect.intersects( r ) )
 
9038
            {
 
9039
                const QColor color( helper().menuBackgroundColor( helper().calcMidColor( palette.color( QPalette::Window ) ), widget, animatedRect.center() ) );
 
9040
                renderMenuItemRect( option, animatedRect, color, palette, painter );
 
9041
            }
 
9042
 
 
9043
        } else if( animations().menuEngine().isTimerActive( widget ) ) {
 
9044
 
 
9045
            const QRect previousRect( animations().menuEngine().currentRect( widget, Previous ) );
 
9046
            if( previousRect.intersects( r ) )
 
9047
            {
 
9048
 
 
9049
                const QColor color( helper().menuBackgroundColor( helper().calcMidColor( palette.color( QPalette::Window ) ), widget, previousRect.center() ) );
 
9050
                renderMenuItemRect( option, previousRect, color, palette, painter );
 
9051
            }
 
9052
 
 
9053
        } else if( animations().menuEngine().isAnimated( widget, Previous ) ) {
 
9054
 
 
9055
            QRect previousRect( animations().menuEngine().currentRect( widget, Previous ) );
 
9056
            if( previousRect.intersects( r ) )
 
9057
            {
 
9058
                const qreal opacity(  animations().menuEngine().opacity( widget, Previous ) );
 
9059
                const QColor color( helper().menuBackgroundColor( helper().calcMidColor( palette.color( QPalette::Window ) ), widget, previousRect.center() ) );
 
9060
                renderMenuItemRect( option, previousRect, color, palette, painter, opacity );
 
9061
            }
 
9062
 
 
9063
        }
 
9064
 
 
9065
        return;
 
9066
    }
 
9067
 
 
9068
    //__________________________________________________________________________
 
9069
    void Style::renderMenuItemRect( const QStyleOption* opt, const QRect& r, const QColor& base, const QPalette& palette, QPainter* painter, qreal opacity ) const
 
9070
    {
 
9071
 
 
9072
        if( opacity == 0 ) return;
 
9073
 
 
9074
        // get relevant color
 
9075
        // TODO: this is inconsistent with MenuBar color.
 
9076
        // this should change to properly account for 'sunken' state
 
9077
        QColor color( base );
 
9078
        if( StyleConfigData::menuHighlightMode() == StyleConfigData::MM_STRONG )
 
9079
        {
 
9080
 
 
9081
            color = palette.color( QPalette::Highlight );
 
9082
 
 
9083
        } else if( StyleConfigData::menuHighlightMode() == StyleConfigData::MM_SUBTLE ) {
 
9084
 
 
9085
            color = KColorUtils::mix( color, KColorUtils::tint( color, palette.color( QPalette::Highlight ), 0.6 ) );
 
9086
 
 
9087
        }
 
9088
 
 
9089
        // special painting for items with submenus
 
9090
        const QStyleOptionMenuItem* menuItemOption = qstyleoption_cast<const QStyleOptionMenuItem*>( opt );
 
9091
        if( menuItemOption && menuItemOption->menuItemType == QStyleOptionMenuItem::SubMenu )
 
9092
        {
 
9093
 
 
9094
            QPixmap pm( r.size() );
 
9095
            pm.fill( Qt::transparent );
 
9096
            QPainter pp( &pm );
 
9097
            QRect rr( QPoint( 0,0 ), r.size() );
 
9098
 
 
9099
            pp.setRenderHint( QPainter::Antialiasing );
 
9100
            pp.setPen( Qt::NoPen );
 
9101
 
 
9102
            pp.setBrush( color );
 
9103
            helper().fillHole( pp, rr );
 
9104
 
 
9105
            helper().holeFlat( color, 0.0 )->render( rr.adjusted( 1, 2, -2, -1 ), &pp );
 
9106
 
 
9107
            QRect maskr( visualRect( opt->direction, rr, QRect( rr.width()-40, 0, 40,rr.height() ) ) );
 
9108
            QLinearGradient gradient(
 
9109
                visualPos( opt->direction, maskr, QPoint( maskr.left(), 0 ) ),
 
9110
                visualPos( opt->direction, maskr, QPoint( maskr.right()-4, 0 ) ) );
 
9111
            gradient.setColorAt( 0.0, Qt::black );
 
9112
            gradient.setColorAt( 1.0, Qt::transparent );
 
9113
            pp.setBrush( gradient );
 
9114
            pp.setCompositionMode( QPainter::CompositionMode_DestinationIn );
 
9115
            pp.drawRect( maskr );
 
9116
 
 
9117
            if( opacity >= 0 && opacity < 1 )
 
9118
            {
 
9119
                pp.setCompositionMode( QPainter::CompositionMode_DestinationIn );
 
9120
                pp.fillRect( pm.rect(), helper().alphaColor( Qt::black, opacity ) );
 
9121
            }
 
9122
 
 
9123
            pp.end();
 
9124
 
 
9125
            painter->drawPixmap( handleRTL( opt, r ), pm );
 
9126
 
 
9127
        } else {
 
9128
 
 
9129
            if( opacity >= 0 && opacity < 1 )
 
9130
            { color.setAlphaF( opacity ); }
 
9131
 
 
9132
            helper().holeFlat( color, 0.0 )->render( r.adjusted( 1,2,-2,-1 ), painter, TileSet::Full );
 
9133
 
 
9134
        }
 
9135
 
 
9136
    }
 
9137
 
 
9138
    //________________________________________________________________________
 
9139
    void Style::renderCheckBox(
 
9140
        QPainter *painter, const QRect &rect, const QPalette &palette,
 
9141
        StyleOptions options, CheckBoxState state,
 
9142
        qreal opacity,
 
9143
        AnimationMode mode ) const
 
9144
    {
 
9145
 
 
9146
        const int s( qMin( rect.width(), rect.height() ) );
 
9147
        const QRect r( centerRect( rect, s, s ) );
 
9148
 
 
9149
        if( !( options & NoFill ) )
 
9150
        {
 
9151
            if( options & Sunken ) helper().holeFlat( palette.color( QPalette::Window ), 0.0, false )->render( r, painter, TileSet::Full );
 
9152
            else renderSlab( painter, r, palette.color( QPalette::Button ), options, opacity, mode, TileSet::Ring );
 
9153
        }
 
9154
 
 
9155
        // check mark
 
9156
        const qreal x( r.center().x() - 3.5 );
 
9157
        const qreal y( r.center().y() - 2.5 );
 
9158
 
 
9159
        if( state != CheckOff )
 
9160
        {
 
9161
 
 
9162
            qreal penThickness( 2.0 );
 
9163
            const QColor color( palette.color( ( options&Sunken ) ? QPalette::WindowText:QPalette::ButtonText ) );
 
9164
            const QColor background( palette.color( ( options&Sunken ) ? QPalette::Window:QPalette::Button ) );
 
9165
            QPen pen( helper().decoColor( background, color ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );
 
9166
            QPen contrastPen( helper().calcLightColor( background ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );
 
9167
            if( state == CheckTriState )
 
9168
            {
 
9169
                QVector<qreal> dashes;
 
9170
                if( StyleConfigData::checkBoxStyle() == StyleConfigData::CS_CHECK )
 
9171
                {
 
9172
 
 
9173
                    dashes << 1.0 << 2.0;
 
9174
                    penThickness = 1.3;
 
9175
                    pen.setWidthF( penThickness );
 
9176
                    contrastPen.setWidthF( penThickness );
 
9177
 
 
9178
                } else {
 
9179
 
 
9180
                    dashes << 0.4 << 2.0;
 
9181
 
 
9182
                }
 
9183
                pen.setDashPattern( dashes );
 
9184
                contrastPen.setDashPattern( dashes );
 
9185
            }
 
9186
 
 
9187
            painter->save();
 
9188
            if( !( options&Sunken ) ) painter->translate( 0, -1 );
 
9189
            painter->setRenderHint( QPainter::Antialiasing );
 
9190
 
 
9191
            const qreal offset( qMin( penThickness, qreal( 1.0 ) ) );
 
9192
            if( StyleConfigData::checkBoxStyle() == StyleConfigData::CS_CHECK )
 
9193
            {
 
9194
 
 
9195
                painter->setPen( contrastPen );
 
9196
                painter->translate( 0, offset );
 
9197
                painter->drawLine( QPointF( x+9, y ), QPointF( x+3,y+7 ) );
 
9198
                painter->drawLine( QPointF( x, y+4 ), QPointF( x+3,y+7 ) );
 
9199
 
 
9200
                painter->setPen( pen );
 
9201
                painter->translate( 0, -offset );
 
9202
                painter->drawLine( QPointF( x+9, y ), QPointF( x+3,y+7 ) );
 
9203
                painter->drawLine( QPointF( x, y+4 ), QPointF( x+3,y+7 ) );
 
9204
 
 
9205
            } else {
 
9206
 
 
9207
                if( options&Sunken )
 
9208
                {
 
9209
 
 
9210
                    painter->setPen( contrastPen );
 
9211
                    painter->translate( 0, offset );
 
9212
                    painter->drawLine( QPointF( x+8, y ), QPointF( x+1,y+7 ) );
 
9213
                    painter->drawLine( QPointF( x+8, y+7 ), QPointF( x+1,y ) );
 
9214
 
 
9215
                    painter->setPen( pen );
 
9216
                    painter->translate( 0, -offset );
 
9217
                    painter->drawLine( QPointF( x+8, y ), QPointF( x+1,y+7 ) );
 
9218
                    painter->drawLine( QPointF( x+8, y+7 ), QPointF( x+1,y ) );
 
9219
 
 
9220
                } else {
 
9221
 
 
9222
                    painter->setPen( contrastPen );
 
9223
                    painter->translate( 0, offset );
 
9224
                    painter->drawLine( QPointF( x+8, y-1 ), QPointF( x,y+7 ) );
 
9225
                    painter->drawLine( QPointF( x+8, y+7 ), QPointF( x,y-1 ) );
 
9226
 
 
9227
                    painter->setPen( pen );
 
9228
                    painter->translate( 0, -offset );
 
9229
                    painter->drawLine( QPointF( x+8, y-1 ), QPointF( x,y+7 ) );
 
9230
                    painter->drawLine( QPointF( x+8, y+7 ), QPointF( x,y-1 ) );
 
9231
 
 
9232
                }
 
9233
            }
 
9234
            painter->restore();
 
9235
        }
 
9236
 
 
9237
        return;
 
9238
 
 
9239
    }
 
9240
 
 
9241
    //___________________________________________________________________
 
9242
    void Style::renderRadioButton(
 
9243
        QPainter* painter, const QRect& rect,
 
9244
        const QPalette& palette,
 
9245
        StyleOptions options,
 
9246
        CheckBoxState state,
 
9247
        qreal opacity,
 
9248
        AnimationMode mode ) const
 
9249
    {
 
9250
 
 
9251
        const int s( CheckBox_Size );
 
9252
        const QRect r( centerRect( rect, s, s ) );
 
9253
        const int x = r.x();
 
9254
        const int y = r.y();
 
9255
 
 
9256
        const QColor color( palette.color( QPalette::Button ) );
 
9257
        const QColor glow( slabShadowColor( color, options, opacity, mode ) );
 
9258
        painter->drawPixmap( x, y, helper().roundSlab( color, glow, 0.0 ) );
 
9259
 
 
9260
        // draw the radio mark
 
9261
        if( state == CheckOn )
 
9262
        {
 
9263
            const qreal radius( 2.6 );
 
9264
            const qreal dx( 0.5*r.width() - radius );
 
9265
            const qreal dy( 0.5*r.height() - radius );
 
9266
 
 
9267
            painter->save();
 
9268
            painter->setRenderHints( QPainter::Antialiasing );
 
9269
            painter->setPen( Qt::NoPen );
 
9270
 
 
9271
            const QColor background( palette.color( QPalette::Button ) );
 
9272
            const QColor color( palette.color( QPalette::ButtonText ) );
 
9273
 
 
9274
            painter->setBrush( helper().calcLightColor( background ) );
 
9275
            painter->translate( 0, radius/2 );
 
9276
            painter->drawEllipse( QRectF( r ).adjusted( dx, dy, -dx, -dy ) );
 
9277
 
 
9278
            painter->setBrush( helper().decoColor( background, color ) );
 
9279
            painter->translate( 0, -radius/2 );
 
9280
            painter->drawEllipse( QRectF( r ).adjusted( dx, dy, -dx, -dy ) );
 
9281
            painter->restore();
 
9282
 
 
9283
        }
 
9284
 
 
9285
        return;
 
9286
    }
 
9287
 
 
9288
    //______________________________________________________________________________
 
9289
    void Style::renderScrollBarHole(
 
9290
        QPainter *painter, const QRect &r, const QColor &color,
 
9291
        const Qt::Orientation& orientation, const TileSet::Tiles& tiles ) const
 
9292
    {
 
9293
 
 
9294
        if( !r.isValid() ) return;
 
9295
 
 
9296
        // one need to make smaller shadow
 
9297
        // notably on the size when rect height is too high
 
9298
        const bool smallShadow( orientation == Qt::Horizontal ? r.height() < 10 : r.width() < 10 );
 
9299
        helper().scrollHole( color, orientation, smallShadow )->render( r, painter, tiles );
 
9300
 
 
9301
    }
 
9302
 
 
9303
    //______________________________________________________________________________
 
9304
    void Style::renderScrollBarHandle(
 
9305
        QPainter* painter, const QRect& r, const QPalette& palette,
 
9306
        const Qt::Orientation& orientation, const bool& hover, const qreal& opacity ) const
 
9307
    {
 
9308
 
 
9309
        if( !r.isValid() ) return;
 
9310
 
 
9311
        painter->save();
 
9312
        painter->setRenderHints( QPainter::Antialiasing );
 
9313
 
 
9314
        // draw the hole as background
 
9315
        const bool horizontal( orientation == Qt::Horizontal );
 
9316
        const QRect holeRect( horizontal ? r.adjusted( -4,0,4,0 ) : r.adjusted( 0,-3,0,4 ) );
 
9317
        renderScrollBarHole( painter, holeRect, palette.color( QPalette::Window ), orientation, horizontal ? TileSet::Vertical : TileSet::Horizontal );
 
9318
 
 
9319
        // draw the slider itself
 
9320
        QRectF rect( horizontal ? r.adjusted( 3, 2, -3, -3 ):r.adjusted( 3, 4, -3, -3 ) );
 
9321
 
 
9322
        if( !rect.isValid() )
 
9323
        {
 
9324
            // e.g. not enough height
 
9325
            painter->restore();
 
9326
            return;
 
9327
        }
 
9328
 
 
9329
        const QColor color( palette.color( QPalette::Button ) );
 
9330
 
 
9331
        // draw the slider
 
9332
        const qreal radius = 3.5;
 
9333
 
 
9334
        // glow / shadow
 
9335
        QColor glow;
 
9336
        const QColor shadow( helper().alphaColor( helper().calcShadowColor( color ), 0.4 ) );
 
9337
        const QColor hovered( helper().viewHoverBrush().brush( QPalette::Active ).color() );
 
9338
 
 
9339
        if( opacity >= 0 ) glow = KColorUtils::mix( shadow, hovered, opacity );
 
9340
        else if( hover ) glow = hovered;
 
9341
        else glow = shadow;
 
9342
 
 
9343
        helper().scrollHandle( color, glow )->
 
9344
            render( rect.adjusted( -3, -3, 3, 3 ).toRect(),
 
9345
            painter, TileSet::Full );
 
9346
 
 
9347
        // contents
 
9348
        const QColor mid( helper().calcMidColor( color ) );
 
9349
        QLinearGradient lg( 0, rect.top(), 0, rect.bottom() );
 
9350
        lg.setColorAt(0, color );
 
9351
        lg.setColorAt(1, mid );
 
9352
        painter->setPen( Qt::NoPen );
 
9353
        painter->setBrush( lg );
 
9354
        painter->drawRoundedRect( rect.adjusted( 1, 1, -1, -1), radius - 2, radius - 2 );
 
9355
 
 
9356
        // bevel pattern
 
9357
        const QColor light( helper().calcLightColor( color ) );
 
9358
 
 
9359
        QLinearGradient patternGradient( 0, 0, horizontal ? 30:0, horizontal? 0:30 );
 
9360
        patternGradient.setSpread( QGradient::ReflectSpread );
 
9361
        patternGradient.setColorAt( 0.0, Qt::transparent );
 
9362
        patternGradient.setColorAt( 1.0, helper().alphaColor( light, 0.1 ) );
 
9363
 
 
9364
        QRectF bevelRect( rect );
 
9365
        if( horizontal ) bevelRect.adjust( 0, 3, 0, -3 );
 
9366
        else bevelRect.adjust( 3, 0, -3, 0 );
 
9367
 
 
9368
        if( bevelRect.isValid() )
 
9369
        {
 
9370
            painter->setBrush( patternGradient );
 
9371
            painter->drawRect( bevelRect );
 
9372
        }
 
9373
 
 
9374
        painter->restore();
 
9375
 
 
9376
    }
 
9377
 
 
9378
    //______________________________________________________________________________
 
9379
    void Style::renderScrollBarArrow(
 
9380
        QPainter* painter, const QRect& r, const QColor& color, const QColor& background,
 
9381
        ArrowOrientation orientation ) const
 
9382
    {
 
9383
 
 
9384
        const qreal penThickness = 1.6;
 
9385
        QPolygonF a( genericArrow( orientation, ArrowNormal ) );
 
9386
 
 
9387
        const QColor contrast( helper().calcLightColor( background ) );
 
9388
        const QColor base( helper().decoColor( background, color ) );
 
9389
 
 
9390
        painter->save();
 
9391
        painter->translate( r.center() );
 
9392
        painter->setRenderHint( QPainter::Antialiasing );
 
9393
 
 
9394
        const qreal offset( qMin( penThickness, qreal( 1.0 ) ) );
 
9395
        painter->translate( 0,offset );
 
9396
        painter->setPen( QPen( contrast, penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
9397
        painter->drawPolyline( a );
 
9398
        painter->translate( 0,-offset );
 
9399
 
 
9400
        painter->setPen( QPen( base, penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
 
9401
        painter->drawPolyline( a );
 
9402
        painter->restore();
 
9403
 
 
9404
        return;
 
9405
 
 
9406
    }
 
9407
 
 
9408
    //______________________________________________________________________________
 
9409
    QColor Style::scrollBarArrowColor( const QStyleOption* option, const SubControl& control, const QWidget* widget ) const
 
9410
    {
 
9411
        const QRect& r( option->rect );
 
9412
        const QPalette& palette( option->palette );
 
9413
        QColor color( palette.color( QPalette::WindowText ) );
 
9414
 
 
9415
        // check enabled state
 
9416
        const bool enabled( option->state & State_Enabled );
 
9417
        if( !enabled ) return color;
 
9418
 
 
9419
        if( const QAbstractSlider* slider = qobject_cast<const QAbstractSlider*>( widget ) )
 
9420
        {
 
9421
            const int value( slider->value() );
 
9422
            if(
 
9423
                ( control == SC_ScrollBarSubLine && value == slider->minimum() ) ||
 
9424
                ( control == SC_ScrollBarAddLine && value == slider->maximum() ) ) {
 
9425
 
 
9426
                // manually disable arrow, to indicate that scrollbar is at limit
 
9427
                return palette.color( QPalette::Disabled, QPalette::WindowText );
 
9428
            }
 
9429
        }
 
9430
 
 
9431
 
 
9432
        const bool hover( animations().scrollBarEngine().isHovered( widget, control ) );
 
9433
        const bool animated( animations().scrollBarEngine().isAnimated( widget, control ) );
 
9434
        const qreal opacity( animations().scrollBarEngine().opacity( widget, control ) );
 
9435
 
 
9436
        QPoint position( hover ? widget->mapFromGlobal( QCursor::pos() ) : QPoint( -1, -1 ) );
 
9437
        if( hover && r.contains( position ) )
 
9438
        {
 
9439
            // we need to update the arrow controlRect on fly because there is no
 
9440
            // way to get it from the styles directly, outside of repaint events
 
9441
            animations().scrollBarEngine().setSubControlRect( widget, control, r );
 
9442
        }
 
9443
 
 
9444
 
 
9445
        if( r.intersects(  animations().scrollBarEngine().subControlRect( widget, control ) ) )
 
9446
        {
 
9447
 
 
9448
            QColor highlight = helper().viewHoverBrush().brush( palette ).color();
 
9449
            if( animated )
 
9450
            {
 
9451
                color = KColorUtils::mix( color, highlight, opacity );
 
9452
 
 
9453
            } else if( hover ) {
 
9454
 
 
9455
                color = highlight;
 
9456
 
 
9457
            }
 
9458
 
 
9459
        }
 
9460
 
 
9461
        return color;
 
9462
 
 
9463
    }
 
9464
 
 
9465
    //______________________________________________________________________________
 
9466
    void Style::renderSliderTickmarks( QPainter* painter, const QStyleOptionSlider* option,  const QWidget* widget ) const
 
9467
    {
 
9468
 
 
9469
        const int& ticks( option->tickPosition );
 
9470
        const int available( pixelMetric( PM_SliderSpaceAvailable, option, widget ) );
 
9471
        int interval = option->tickInterval;
 
9472
        if( interval < 1 ) interval = option->pageStep;
 
9473
        if( interval < 1 ) return;
 
9474
 
 
9475
        const QRect& r( option->rect );
 
9476
        const QPalette& palette( option->palette );
 
9477
 
 
9478
        const int fudge( pixelMetric( PM_SliderLength, option, widget ) / 2 );
 
9479
        int current( option->minimum );
 
9480
 
 
9481
        // Since there is no subrect for tickmarks do a translation here.
 
9482
        painter->save();
 
9483
        painter->translate( r.x(), r.y() );
 
9484
 
 
9485
        if( option->orientation == Qt::Horizontal )
 
9486
        {
 
9487
            QColor base( helper().backgroundColor( palette.color( QPalette::Window ), widget, r.center() ) );
 
9488
            painter->setPen( helper().calcDarkColor( base ) );
 
9489
        }
 
9490
 
 
9491
        int tickSize( option->orientation == Qt::Horizontal ? r.height()/3:r.width()/3 );
 
9492
 
 
9493
        while( current <= option->maximum )
 
9494
        {
 
9495
 
 
9496
            const int position( sliderPositionFromValue( option->minimum, option->maximum, current, available ) + fudge );
 
9497
 
 
9498
            // calculate positions
 
9499
            if( option->orientation == Qt::Horizontal )
 
9500
            {
 
9501
                if( ticks == QSlider::TicksAbove ) painter->drawLine( position, 0, position, tickSize );
 
9502
                else if( ticks == QSlider::TicksBelow ) painter->drawLine( position, r.height()-tickSize, position, r.height() );
 
9503
                else {
 
9504
                    painter->drawLine( position, 0, position, tickSize );
 
9505
                    painter->drawLine( position, r.height()-tickSize, position, r.height() );
 
9506
                }
 
9507
 
 
9508
            } else {
 
9509
 
 
9510
                QColor base( helper().backgroundColor( palette.color( QPalette::Window ), widget, QPoint( r.center().x(), position ) ) );
 
9511
                painter->setPen( helper().calcDarkColor( base ) );
 
9512
 
 
9513
                if( ticks == QSlider::TicksAbove ) painter->drawLine( 0, position, tickSize, position );
 
9514
                else if( ticks == QSlider::TicksBelow ) painter->drawLine( r.width()-tickSize, position, r.width(), position );
 
9515
                else {
 
9516
                    painter->drawLine( 0, position, tickSize, position );
 
9517
                    painter->drawLine( r.width()-tickSize, position, r.width(), position );
 
9518
                }
 
9519
            }
 
9520
 
 
9521
            // go to next position
 
9522
            current += interval;
 
9523
 
 
9524
        }
 
9525
 
 
9526
        painter->restore();
 
9527
    }
 
9528
 
 
9529
    //____________________________________________________________________________________
 
9530
    QColor Style::slabShadowColor( QColor color, StyleOptions options, qreal opacity, AnimationMode mode ) const
 
9531
    {
 
9532
 
 
9533
        QColor glow;
 
9534
        if( mode == AnimationNone || opacity < 0 )
 
9535
        {
 
9536
 
 
9537
            if( options & Hover ) glow = helper().viewHoverBrush().brush( QPalette::Active ).color();
 
9538
            else if( options & Focus ) glow = helper().viewFocusBrush().brush( QPalette::Active ).color();
 
9539
            else if( ( options & SubtleShadow ) && color.isValid() ) glow = helper().alphaColor( helper().calcShadowColor( color ), 0.15 );
 
9540
 
 
9541
 
 
9542
        } else if( mode == AnimationHover ) {
 
9543
 
 
9544
            // animated color, hover
 
9545
            if( options & Focus ) glow = helper().viewFocusBrush().brush( QPalette::Active ).color();
 
9546
            else if( ( options & SubtleShadow ) && color.isValid() ) glow = helper().alphaColor( helper().calcShadowColor( color ), 0.15 );
 
9547
 
 
9548
            if( glow.isValid() ) glow = KColorUtils::mix( glow,  helper().viewHoverBrush().brush( QPalette::Active ).color(), opacity );
 
9549
            else glow = helper().alphaColor(  helper().viewHoverBrush().brush( QPalette::Active ).color(), opacity );
 
9550
 
 
9551
        } else if( mode == AnimationFocus ) {
 
9552
 
 
9553
            if( options & Hover ) glow = helper().viewHoverBrush().brush( QPalette::Active ).color();
 
9554
            else if( ( options & SubtleShadow ) && color.isValid() ) glow = helper().alphaColor( helper().calcShadowColor( color ), 0.15 );
 
9555
 
 
9556
            if( glow.isValid() ) glow = KColorUtils::mix( glow,  helper().viewFocusBrush().brush( QPalette::Active ).color(), opacity );
 
9557
            else glow = helper().alphaColor(  helper().viewFocusBrush().brush( QPalette::Active ).color(), opacity );
 
9558
 
 
9559
        }
 
9560
 
 
9561
        return glow;
 
9562
    }
 
9563
 
 
9564
    //____________________________________________________________________________________
 
9565
    QPolygonF Style::genericArrow( Style::ArrowOrientation orientation, Style::ArrowSize size ) const
 
9566
    {
 
9567
 
 
9568
        QPolygonF a;
 
9569
        switch( orientation )
 
9570
        {
 
9571
            case ArrowUp:
 
9572
            {
 
9573
                if( size == ArrowTiny ) a << QPointF( -1.75, 1.125 ) << QPointF( 0.5, -1.125 ) << QPointF( 2.75, 1.125 );
 
9574
                else if( size == ArrowSmall ) a << QPointF( -2,1.5 ) << QPointF( 0.5, -1.5 ) << QPointF( 3,1.5 );
 
9575
                else a << QPointF( -3,2.5 ) << QPointF( 0.5, -1.5 ) << QPointF( 4,2.5 );
 
9576
                break;
 
9577
            }
 
9578
 
 
9579
            case ArrowDown:
 
9580
            {
 
9581
                if( size == ArrowTiny ) a << QPointF( -1.75, -1.125 ) << QPointF( 0.5, 1.125 ) << QPointF( 2.75, -1.125 );
 
9582
                else if( size == ArrowSmall ) a << QPointF( -2,-1.5 ) << QPointF( 0.5, 1.5 ) << QPointF( 3,-1.5 );
 
9583
                else a << QPointF( -3,-1.5 ) << QPointF( 0.5, 2.5 ) << QPointF( 4,-1.5 );
 
9584
                break;
 
9585
            }
 
9586
 
 
9587
            case ArrowLeft:
 
9588
            {
 
9589
                if( size == ArrowTiny ) a << QPointF( 1.125, -1.75 ) << QPointF( -1.125, 0.5 ) << QPointF( 1.125, 2.75 );
 
9590
                else if( size == ArrowSmall ) a << QPointF( 1.5,-2 ) << QPointF( -1.5, 0.5 ) << QPointF( 1.5,3 );
 
9591
                else a << QPointF( 2.5,-3 ) << QPointF( -1.5, 0.5 ) << QPointF( 2.5,4 );
 
9592
                break;
 
9593
            }
 
9594
 
 
9595
            case ArrowRight:
 
9596
            {
 
9597
                if( size == ArrowTiny ) a << QPointF( -1.125, -1.75 ) << QPointF( 1.125, 0.5 ) << QPointF( -1.125, 2.75 );
 
9598
                else if( size == ArrowSmall ) a << QPointF( -1.5,-2 ) << QPointF( 1.5, 0.5 ) << QPointF( -1.5,3 );
 
9599
                else a << QPointF( -1.5,-3 ) << QPointF( 2.5, 0.5 ) << QPointF( -1.5,4 );
 
9600
                break;
 
9601
            }
 
9602
 
 
9603
            default: break;
 
9604
 
 
9605
        }
 
9606
 
 
9607
        return a;
 
9608
 
 
9609
    }
 
9610
 
 
9611
}