//=============================================================================
//  MuseScore
//  Linux Music Score Editor
//  $Id:$
//
//  Copyright (C) 2010 Werner Schweer and others
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License version 2.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================

#include <math.h>

#include "mstyle.h"
#include "colorutils.h"
#include "frameshadow.h"
#include "animations.h"
#include "menubarengine.h"
#include "widgetstateengine.h"
#include "transitions.h"
#include "mconfig.h"
#include "../mscore/paletteBoxButton.h"
#include "../mscore/miconengine.h"

#define MgStyleConfigData_toolTipTransparent            true
#define MgStyleConfigData_toolBarDrawItemSeparator      true
#define MgStyleConfigData_viewDrawTriangularExpander    true
#define MgStyleConfigData_viewTriangularExpanderSize    ArrowNormal
#define MgStyleConfigData_viewDrawTreeBranchLines       true
#define MgStyleConfigData_checkBoxStyle_CS_CHECK        true
#define MgStyleConfigData_scrollBarColored              false
#define MgStyleConfigData_scrollBarBevel                false

//---------------------------------------------------------
//   MgStyle
//---------------------------------------------------------

MgStyle::MgStyle()
      : QCommonStyle() {
      _addLineButtons = DoubleButton;
      _subLineButtons = SingleButton;
      _singleButtonHeight = 14;
      _doubleButtonHeight = 28;
      _mnemonic           = Qt::TextShowMnemonic;
      _tabBarData         = new TabBarData(this);
      _frameFocusPrimitive = 0;
      _tabBarTabShapeControl = 0;
      _hintCounter       = QStyle::SH_CustomBase;
      _controlCounter    = QStyle::CE_CustomBase;
      _subElementCounter = QStyle::SE_CustomBase;
      CE_CapacityBar     = newControlElement("CE_CapacityBar");

      _animations    = new Animations(this);
      _transitions   = new Transitions(this);
      _frameShadowFactory = new FrameShadowFactory(this);
      configurationChanged();
      }

//---------------------------------------------------------
//   drawMenuBarItem
//---------------------------------------------------------

bool MgStyle::drawMenuBarItem(const QStyleOption* option, QPainter* painter,
                              const QWidget* widget) const {
      const QStyleOptionMenuItem* menuOpt = ::qstyleoption_cast<const QStyleOptionMenuItem*>(option);
      if (!menuOpt)
            return true;

      const State& flags(option->state);
      const bool enabled(flags & State_Enabled);
      const QRect& r(option->rect);
      const QPalette& palette(option->palette);

      if(!widget)
            widget = QApplication::activeWindow();

      if (enabled) {
            const bool active(flags & State_Selected);
            const bool animated(animations().menuBarEngine().isAnimated(widget, r.topLeft()));
            const qreal opacity(animations().menuBarEngine().opacity(widget, r.topLeft()));
            const QRect currentRect(animations().menuBarEngine().currentRect(widget, r.topLeft()));
            const QRect animatedRect(animations().menuBarEngine().animatedRect(widget));

            const bool intersected(animatedRect.intersects(r));
            const bool current(currentRect.contains(r.topLeft()));
            const bool timerIsActive(animations().menuBarEngine().isTimerActive(widget));

            // do nothing in case of empty intersection between animated rect and current
            if ((intersected || !animated || animatedRect.isNull()) && (active || animated || timerIsActive)) {
                  QColor color(palette.color(QPalette::Window));
                  if (MgStyleConfigData::menuHighlightMode != MgStyleConfigData::MM_DARK) {
                        if (flags & State_Sunken) {
                              if (MgStyleConfigData::menuHighlightMode == MgStyleConfigData::MM_STRONG)
                                    color = palette.color(QPalette::Highlight);
                              else
                                    color = ColorUtils::mix(color, ColorUtils::tint(color, palette.color(QPalette::Highlight), 0.6));
                              }
                        else {
                              if (MgStyleConfigData::menuHighlightMode == MgStyleConfigData::MM_STRONG)
                                    color = ColorUtils::tint(color, _helper.viewHoverBrush().brush(palette).color());
                              else
                                    color = ColorUtils::mix(color, ColorUtils::tint(color, _helper.viewHoverBrush().brush(palette).color()));
                              }
                        }
                  else
                        color = _helper.calcMidColor(_helper.backgroundColor(color, widget, r.center()));

                  // drawing
                  if (animated && intersected)
                        _helper.holeFlat(color, 0.0)->render(animatedRect.adjusted(1, 1, -1, -1), painter, TileSet::Full);
                  else if (timerIsActive && current)
                        _helper.holeFlat(color, 0.0)->render(r.adjusted(1, 1, -1, -1), painter, TileSet::Full);
                  else if (animated && current) {
                        color.setAlphaF(opacity);
                        _helper.holeFlat(color, 0.0)->render(r.adjusted(1, 1, -1, -1), painter, TileSet::Full);
                        }
                  else if (active )
                        _helper.holeFlat(color, 0.0)->render(r.adjusted(1, 1, -1, -1), painter, TileSet::Full);
                  }
            }

      // text
      QPalette::ColorRole role(QPalette::WindowText);
      if (MgStyleConfigData::menuHighlightMode == MgStyleConfigData::MM_STRONG && (flags & State_Sunken) && enabled)
            role = QPalette::HighlightedText;
      drawItemText(painter, r, Qt::AlignCenter | Qt::TextShowMnemonic, palette, enabled, menuOpt->text, role);
      return true;
      }

//---------------------------------------------------------
//   pixelMetric
//---------------------------------------------------------

int MgStyle::pixelMetric(PixelMetric metric, const QStyleOption* option, const QWidget* widget ) const {
      if(!widget)
            widget = QApplication::activeWindow();

      switch (metric) {
                  // rely on QCommonStyle here
            case PM_SmallIconSize:
            case PM_ButtonIconSize:
                  return 16;
            case PM_ToolBarIconSize:
                  return 22;
            case PM_LargeIconSize:
                  return 32;              //??
            case PM_MessageBoxIconSize:
                  return 48;              //??

            case PM_DefaultFrameWidth: {
                  if ( qobject_cast<const QLineEdit*>(widget) )
                        return LineEdit_FrameWidth;
                  else if ( qobject_cast<const QComboBox*>(widget))
                        return ComboBox_FrameWidth;
                  else if ( qobject_cast<const QFrame*>(widget) )
                        return Frame_FrameWidth;
                  else if ( qstyleoption_cast<const QStyleOptionGroupBox*>(option) )
                        return GroupBox_FrameWidth;
                  else
                        return 1;
                  }

            case PM_LayoutLeftMargin:
            case PM_LayoutTopMargin:
            case PM_LayoutRightMargin:
            case PM_LayoutBottomMargin: {
                  // use either Child margin or TopLevel margin, depending on
                  // widget type
                  if ((option && (option->state & QStyle::State_Window)) || (widget && widget->isWindow())) {
                        return pixelMetric(PM_DefaultTopLevelMargin, option, widget);
                        }
                  else {
                        return pixelMetric(PM_DefaultChildMargin, option, widget);
                        // return 0;
                        }
                  }

            // push buttons
            case PM_ButtonMargin:
                  return 5;

            case PM_MenuButtonIndicator:
                  if (qstyleoption_cast<const QStyleOptionToolButton*>(option))
                        return ToolButton_MenuIndicatorSize;
                  else
                        return PushButton_MenuIndicatorSize;

            case PM_ScrollBarExtent:
                  return MgStyleConfigData::scrollBarWidth + 2;

                  // tooltip label
            case PM_ToolTipLabelFrameWidth:
                  if (MgStyleConfigData::toolTipDrawStyledFrames)
                        return 3;
                  else
                        break;

            case PM_DefaultChildMargin:
                  return 4;
            case PM_DefaultTopLevelMargin:
                  return 11;
            case PM_DefaultLayoutSpacing:
                  return 4;
//            case PM_LayoutHorizontalSpacing: return -1;   // this crashes qt4.8
//            case PM_LayoutVerticalSpacing: return -1;
            case PM_LayoutHorizontalSpacing:
                  return 0;
            case PM_LayoutVerticalSpacing:
                  return 0;

                  // buttons
            case PM_ButtonDefaultIndicator:
                  return 0;
            case PM_ButtonShiftHorizontal:
                  return 0;
            case PM_ButtonShiftVertical:
                  return 0;

                  // checkboxes: return radiobutton sizes
            case PM_IndicatorWidth:
                  return CheckBox_Size;
            case PM_IndicatorHeight:
                  return CheckBox_Size;
            case PM_ExclusiveIndicatorWidth:
                  return CheckBox_Size;
            case PM_ExclusiveIndicatorHeight:
                  return CheckBox_Size;
//            case PM_CheckListControllerSize: return CheckBox_Size;
//            case PM_CheckListButtonSize: return CheckBox_Size;

                  // splitters and dock widgets
            case PM_SplitterWidth:
                  return Splitter_Width;
            case PM_DockWidgetFrameWidth:
                  return DockWidget_FrameWidth;
            case PM_DockWidgetSeparatorExtent:
                  return DockWidget_SeparatorExtend;
            case PM_DockWidgetTitleMargin:
                  return DockWidget_TitleMargin;

                  // progress bar
            case PM_ProgressBarChunkWidth:
                  return 1;

                  // menu bars
            case PM_MenuBarPanelWidth:
                  return 0;
            case PM_MenuBarHMargin:
                  return 0;
            case PM_MenuBarVMargin:
                  return 0;
            case PM_MenuBarItemSpacing:
                  return 0;
            case PM_MenuDesktopFrameWidth:
                  return 0;
            case PM_MenuPanelWidth:
                  return 5;

            case PM_MenuScrollerHeight:
                  return 10;
            case PM_MenuTearoffHeight:
                  return 10;

                  //! tabbar
            case PM_TabBarTabHSpace:
                  return 0;
            case PM_TabBarTabVSpace:
                  return 0;
            case PM_TabBarBaseHeight:
                  return TabBar_BaseHeight;
            case PM_TabBarBaseOverlap:
                  return TabBar_BaseOverlap;
            case PM_TabBarTabOverlap:
                  return 0;
            case PM_TabBarScrollButtonWidth:
                  return TabBar_ScrollButtonWidth;

                  /*
                  disable shifts: return because last time I checked it did not work well
                  for South and East tabs. Instead the shifts are added directly in
                  drawTabBarTabLabel. (Hugo)
                  */
            case PM_TabBarTabShiftVertical:
                  return 0;
            case PM_TabBarTabShiftHorizontal:
                  return 0;

                  // sliders
            case PM_SliderThickness:
                  return 23;
            case PM_SliderControlThickness:
                  return 23;
            case PM_SliderLength:
                  return 13;

                  // spinboxes
            case PM_SpinBoxFrameWidth:
                  return SpinBox_FrameWidth;

                  // comboboxes
            case PM_ComboBoxFrameWidth:
                  return ComboBox_FrameWidth;

                  // tree view header
            case PM_HeaderMarkSize:
                  return 9;
            case PM_HeaderMargin:
                  return 3;

                  // toolbars
            case PM_ToolBarFrameWidth:
                  return 0;
            case PM_ToolBarHandleExtent:
                  return 6;
            case PM_ToolBarSeparatorExtent:
                  return 6;

            case PM_ToolBarExtensionExtent:
                  return 16;
            case PM_ToolBarItemMargin:
                  return 1;
            case PM_ToolBarItemSpacing:
                  return 1;

                  // MDI windows titlebars
            case PM_TitleBarHeight:
                  return 20;

                  // spacing between widget and scrollbars
            case PM_ScrollView_ScrollBarSpacing:
                  if (const QFrame* frame = qobject_cast<const QFrame*>(widget)) {
                        const bool framed(frame->frameShape() != QFrame::NoFrame);
                        return framed ? -2 : 0;
                        }
                  else
                        return -2;

            default:
                  break;
            }
      return QCommonStyle::pixelMetric(metric, option, widget);
      }

//---------------------------------------------------------
//   expandSize
//    expand size based on margins
//---------------------------------------------------------

QSize MgStyle::expandSize(const QSize& size, int main, int left, int top, int right, int bottom) const {
      return size + QSize(2 * main + left + right, 2 * main + top + bottom);
      }

//---------------------------------------------------------
//   sizeFromContents
//---------------------------------------------------------

QSize MgStyle::sizeFromContents(ContentsType element, const QStyleOption* option,
                                const QSize& size, const QWidget* widget) const {
      if(!widget)
            widget = QApplication::activeWindow();

      switch (element) {
            case CT_CheckBox:
                  return checkBoxSizeFromContents(option, size, widget);
            case CT_ComboBox:
                  return comboBoxSizeFromContents(option, size, widget);
            case CT_HeaderSection:
                  return headerSectionSizeFromContents(option, size, widget);
            case CT_PushButton:
                  return pushButtonSizeFromContents(option, size, widget);
            case CT_MenuBar:
                  return size;
            case CT_MenuBarItem:
                  return expandSize(size, MenuBarItem_Margin, MenuBarItem_Margin_Left, 0, MenuBarItem_Margin_Right, 0);

            case CT_MenuItem:
                  return menuItemSizeFromContents(option, size, widget);
            case CT_RadioButton:
                  return checkBoxSizeFromContents(option, size, widget);
            case CT_TabBarTab:
                  return tabBarTabSizeFromContents(option, size, widget);
            case CT_TabWidget:
                  return expandSize(size, TabWidget_ContentsMargin);

            case CT_ToolButton:
                  return toolButtonSizeFromContents(option, size, widget);
            default:
                  return QCommonStyle::sizeFromContents(element, option, size, widget);
            }
      }

//---------------------------------------------------------
//   checkBoxSizeFromContents
//---------------------------------------------------------

QSize MgStyle::checkBoxSizeFromContents(const QStyleOption*, const QSize& contentsSize, const QWidget*) const {
      //Add size for indicator
      const int indicator( CheckBox_Size );

      //Make sure we can fit the indicator
      QSize size( contentsSize );
      size.setHeight(qMax(size.height(), indicator));

      //Add space for the indicator and the icon
      const int spacer = CheckBox_BoxTextSpace;
      size.rwidth() += indicator + spacer;

      return size;
      }

//---------------------------------------------------------
//   comboBoxSizeFromContents
//---------------------------------------------------------

QSize MgStyle::comboBoxSizeFromContents( const QStyleOption* option, const QSize& contentsSize,
            const QWidget*) const {
      QSize size = expandSize( contentsSize,
                               ComboBox_ContentsMargin,
                               ComboBox_ContentsMargin_Left,
                               ComboBox_ContentsMargin_Top,
                               ComboBox_ContentsMargin_Right,
                               ComboBox_ContentsMargin_Bottom );

      // add frame width
      size = expandSize(size, ComboBox_FrameWidth);

      // Add the button width
      size.rwidth() += ComboBox_ButtonWidth;

      // TODO: For some reason the size is not right in the following configurations
      // this is still to be understood and might reveal some deeper issue.
      // notably, should compare to zhqt is done for PushButtons
      const QStyleOptionComboBox* cb = qstyleoption_cast<const QStyleOptionComboBox*>(option);
      if (cb && !cb->editable && (!cb->currentIcon.isNull() || cb->fontMetrics.height() > 13))
            size.rheight() += 1;

      // also expand to account for scrollbar
      size.rwidth() += MgStyleConfigData::scrollBarWidth - 6;
      return size;
      }

//---------------------------------------------------------
//   headerSectionSizeFromContents
//---------------------------------------------------------

QSize MgStyle::headerSectionSizeFromContents(const QStyleOption* option, const QSize& contentsSize, const QWidget*) const {
      const QStyleOptionHeader* headerOpt( qstyleoption_cast<const QStyleOptionHeader*>( option ));
      if ( !headerOpt )
            return contentsSize;

      //TODO: check if hardcoded icon size is the right thing to do
      QSize iconSize = headerOpt->icon.isNull() ? QSize(0, 0) : QSize(22, 22);
      QSize textSize = headerOpt->fontMetrics.size(0, headerOpt->text);

      int iconSpacing = Header_TextToIconSpace;
      int w = iconSize.width() + iconSpacing + textSize.width();
      int h = qMax(iconSize.height(), textSize.height() );

      return expandSize( QSize(w, h), Header_ContentsMargin );
      }

//---------------------------------------------------------
//   menuItemSizeFromContents
//---------------------------------------------------------

QSize MgStyle::menuItemSizeFromContents(const QStyleOption* option, const QSize& contentsSize, const QWidget* widget) const {
      const QStyleOptionMenuItem* menuItemOption = qstyleoption_cast<const QStyleOptionMenuItem*>(option);
      if ( !menuItemOption)
            return contentsSize;

      if(!widget)
            widget = QApplication::activeWindow();

      // First, we calculate the intrinsic size of the item.
      // this must be kept consistent with what's in drawMenuItemContol
      QSize insideSize;

      switch (menuItemOption->menuItemType) {
            case QStyleOptionMenuItem::Normal:
            case QStyleOptionMenuItem::DefaultItem:
            case QStyleOptionMenuItem::SubMenu: {
                  int iconColW = qMax( menuItemOption->maxIconWidth, (int) MenuItem_IconWidth );
                  int leftColW = iconColW;
                  if ( menuItemOption->menuHasCheckableItems ) {
                        leftColW += MenuItem_CheckWidth + MenuItem_CheckSpace;
                        }
                  leftColW += MenuItem_IconSpace;
                  int rightColW = MenuItem_ArrowSpace + MenuItem_ArrowWidth;

                  QFontMetrics fm(menuItemOption->font);
                  int textW;
                  int tabPos = menuItemOption->text.indexOf(QLatin1Char('\t'));
                  if ( tabPos == -1)
                        textW = contentsSize.width();
                  else {
                        // The width of the accelerator is not included here since
                        // Qt will add that on separately after obtaining the
                        // sizeFromContents() for each menu item in the menu to be shown
                        // ( see QMenuPrivate::calcActionRects() )
                        textW = contentsSize.width() + MenuItem_AccelSpace;
                        }

                  int h = qMax(contentsSize.height(), (int) MenuItem_MinHeight );
                  insideSize = QSize(leftColW + textW + rightColW, h);
                  break;
                  }

            case QStyleOptionMenuItem::Separator: {
                  // separator can have a title and an icon
                  // in that case they are rendered as menubar 'title', which
                  // corresponds to checked toolbuttons.
                  // a rectangle identical to the one of normal items is returned.
                  if ( !( menuItemOption->text.isEmpty() && menuItemOption->icon.isNull() ) ) {
                        QStyleOptionMenuItem local( *menuItemOption );
                        local.menuItemType = QStyleOptionMenuItem::Normal;
                        return menuItemSizeFromContents( &local, contentsSize, widget );
                        }
                  else {
                        insideSize = QSize(10, 0);
                        break;
                        }
                  }
            case QStyleOptionMenuItem::Scroller:
            case QStyleOptionMenuItem::TearOff:
            case QStyleOptionMenuItem::Margin:
            case QStyleOptionMenuItem::EmptyArea:
                  return contentsSize;
            }

      // apply the outermost margin.
      return expandSize(insideSize, MenuItem_Margin );
      }

//---------------------------------------------------------
//   pushButtonSizeFromContents
//---------------------------------------------------------

QSize MgStyle::pushButtonSizeFromContents(const QStyleOption* option, const QSize& contentsSize, const QWidget*) const {
      const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
      if (!bOpt)
            return contentsSize;

      // adjust to handle button margins
      QSize size = expandSize(contentsSize,
                              PushButton_ContentsMargin,
                              PushButton_ContentsMargin_Left,
                              PushButton_ContentsMargin_Top,
                              PushButton_ContentsMargin_Right,
                              PushButton_ContentsMargin_Bottom);

      if ( bOpt->features & QStyleOptionButton::HasMenu)
            size.rwidth() += PushButton_TextToIconSpace;

      if ( !bOpt->text.isEmpty() && !bOpt->icon.isNull()) {
            // Incorporate the spacing between the icon and text. Qt sticks 4 there,
            // but we use PushButton::TextToIconSpace.
            size.rwidth() += PushButton_TextToIconSpace - 4;
            }
      return size;
      }

//---------------------------------------------------------
//   tabBarTabSizeFromContents
//---------------------------------------------------------

QSize MgStyle::tabBarTabSizeFromContents(const QStyleOption* option, const QSize& contentsSize, const QWidget* widget) const {
      const QStyleOptionTab* tabOpt( qstyleoption_cast<const QStyleOptionTab*>(option) );

      if(!widget)
            widget = QApplication::activeWindow();

      QSize size;
      const bool verticalTabs(tabOpt && isVerticalTab(tabOpt));
      if ( verticalTabs ) {
            size = expandSize( contentsSize,
                               TabBar_TabContentsMargin,
                               TabBar_TabContentsMargin_Top,
                               TabBar_TabContentsMargin_Right,
                               TabBar_TabContentsMargin_Bottom,
                               TabBar_TabContentsMargin_Left );
            }
      else {
            size = expandSize( contentsSize,
                               TabBar_TabContentsMargin,
                               TabBar_TabContentsMargin_Left,
                               TabBar_TabContentsMargin_Top,
                               TabBar_TabContentsMargin_Right,
                               TabBar_TabContentsMargin_Bottom );
            }

      // need to add extra size to match corner buttons
      // try cast parent for tabWidget
      const QTabWidget* tabWidget( widget ? qobject_cast<const QTabWidget*>( widget->parent() ) : 0 );
      if ( !tabWidget )
            return size;

      // try get corner widgets
      const QWidget* leftWidget( tabWidget->cornerWidget( Qt::TopLeftCorner ) );
      const QWidget* rightWidget( tabWidget->cornerWidget( Qt::TopRightCorner ) );
      QSize cornerSize;
      if ( leftWidget && leftWidget->isVisible() )
            cornerSize = leftWidget->minimumSizeHint();
      if ( rightWidget && rightWidget->isVisible() )
            cornerSize = cornerSize.expandedTo( rightWidget->minimumSizeHint() );
      if ( !cornerSize.isValid() )
            return size;

      // expand size
      // note: the extra pixels added to the relevant dimension are fine-tuned.
      if ( verticalTabs )
            size.setWidth( qMax( size.width(), cornerSize.width() + 6 ) );
      else
            size.setHeight( qMax( size.height(), cornerSize.height() + 4 ) );
      return size;
      }

//---------------------------------------------------------
//   toolButtonSizeFromContents
//---------------------------------------------------------

QSize MgStyle::toolButtonSizeFromContents(const QStyleOption* option, const QSize& contentsSize, const QWidget* widget) const {
      QSize size = contentsSize;
      const QStyleOptionToolButton* tbOpt = qstyleoption_cast<const QStyleOptionToolButton*>(option);
      if ( tbOpt && !tbOpt->icon.isNull() && !tbOpt->text.isEmpty() && tbOpt->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
            size.rheight() -= 5;
            }

      if(!widget)
            widget = QApplication::activeWindow();

      // We want to avoid super-skiny buttons, for things like "up" when icons + text
      // For this, we would like to make width >= height.
      // However, once we get here, QToolButton may have already put in the menu area
      // (PM_MenuButtonIndicator) into the width. So we may have to take it out, fix things
      // up, and add it back in. So much for class-independent rendering...
      int menuAreaWidth = 0;
      if ( tbOpt ) {
            if ( tbOpt->features & QStyleOptionToolButton::MenuButtonPopup) {
                  menuAreaWidth = pixelMetric(QStyle::PM_MenuButtonIndicator, option, widget);
                  }
            else if ( tbOpt->features & QStyleOptionToolButton::HasMenu) {
                  // TODO: something wrong here: The size is not properly accounted for
                  // when drawing the slab.
                  size.rwidth() += ToolButton_InlineMenuIndicatorSize;
                  }
            }
      size.rwidth() -= menuAreaWidth;
      if ( size.width() < size.height())
            size.setWidth(size.height());

      size.rwidth() += menuAreaWidth;

      const QToolButton* t( qobject_cast<const QToolButton*>(widget) );
      if ( t && t->autoRaise() )
            return expandSize( size, ToolButton_ContentsMargin ); // these are toolbutton margins
      else
            return expandSize( size, PushButton_ContentsMargin, 0, PushButton_ContentsMargin_Top, 0,
                               PushButton_ContentsMargin_Bottom );
      }

//---------------------------------------------------------
//   isVerticalTab
//---------------------------------------------------------

bool MgStyle::isVerticalTab( const QTabBar::Shape& shape ) const {
      return shape == QTabBar::RoundedEast
             || shape == QTabBar::RoundedWest
             || shape == QTabBar::TriangularEast
             || shape == QTabBar::TriangularWest;
      }

//---------------------------------------------------------
//   polish
//---------------------------------------------------------

void MgStyle::polish(QWidget* widget) {

      if(!widget)
            widget = QApplication::activeWindow();

      if (!widget)
            return;

      // register widget to animations
      animations().registerWidget(widget);
      transitions().registerWidget(widget);
      frameShadowFactory().registerWidget(widget, _helper);

      // scroll areas
      if (QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>(widget))
            polishScrollArea(scrollArea );

      // several widgets set autofill background to false, which effectively breaks the background
      // gradient rendering. Instead of patching all concerned applications,
      // we change the background here
      if (widget->inherits( "MessageList::Core::Widget")) {
            widget->setAutoFillBackground(false);
            }

      // adjust flags for windows and dialogs
      switch (widget->windowFlags() & Qt::WindowType_Mask) {
            case Qt::Window:
            case Qt::Dialog:
                  widget->setAttribute(Qt::WA_StyledBackground);
                  break;

            case Qt::ToolTip:
                  if (!widget->autoFillBackground() ) {
#ifndef Q_OS_MAC
                        widget->setAttribute(Qt::WA_TranslucentBackground);
#endif

#ifdef Q_OS_WIN
                        //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly
                        widget->setWindowFlags(widget->windowFlags() | Qt::FramelessWindowHint);
#endif
                        }

                  break;

            default:
                  break;
            }

      if (qobject_cast<QAbstractItemView*>(widget)
                  || qobject_cast<QAbstractSpinBox*>(widget)
                  || qobject_cast<QCheckBox*>(widget)
                  || qobject_cast<QComboBox*>(widget)
                  || qobject_cast<QDial*>(widget)
                  || qobject_cast<QLineEdit*>(widget)
                  || qobject_cast<QPushButton*>(widget)
                  || qobject_cast<QRadioButton*>(widget)
                  || qobject_cast<QScrollBar*>(widget)
                  || qobject_cast<QSlider*>(widget)
                  || qobject_cast<QSplitterHandle*>(widget)
                  || qobject_cast<QTabBar*>(widget)
                  || qobject_cast<QTextEdit*>(widget)
                  || qobject_cast<QToolButton*>(widget)
         ) {
            widget->setAttribute(Qt::WA_Hover);
            }

      // also enable hover effects in itemviews' viewport
      if ( QAbstractItemView* itemView = qobject_cast<QAbstractItemView*>(widget)) {
            itemView->viewport()->setAttribute(Qt::WA_Hover);
            }

      // checkable group boxes
      if ( QGroupBox* groupBox = qobject_cast<QGroupBox*>(widget)) {
            if (groupBox->isCheckable())
                  groupBox->setAttribute(Qt::WA_Hover);
            }
      else if ( qobject_cast<QAbstractButton*>(widget) && qobject_cast<QDockWidget*>( widget->parent() ) ) {
            widget->setAttribute(Qt::WA_Hover);
            }
      else if ( qobject_cast<QAbstractButton*>(widget) && qobject_cast<QToolBox*>( widget->parent() ) ) {
            widget->setAttribute(Qt::WA_Hover);
            }
      /*
      add extra margins for widgets in toolbars
      this allows to preserve alignment with respect to actions
      */
      if (qobject_cast<QToolBar*>(widget->parent()))
            widget->setContentsMargins(0, 0, 0, 1);

      if (qobject_cast<QToolButton*>(widget)) {
            if (qobject_cast<QToolBar*>( widget->parent() ) ) {
                  // this hack is needed to have correct text color
                  // rendered in toolbars. This does not really update nicely when changing styles
                  // but is the best I can do for now since setting the palette color at painting
                  // time is not doable
                  QPalette palette( widget->palette() );
                  palette.setColor( QPalette::Disabled, QPalette::ButtonText, palette.color( QPalette::Disabled, QPalette::WindowText ) );
                  palette.setColor( QPalette::Active, QPalette::ButtonText, palette.color( QPalette::Active, QPalette::WindowText ) );
                  palette.setColor( QPalette::Inactive, QPalette::ButtonText, palette.color( QPalette::Inactive, QPalette::WindowText ) );
                  widget->setPalette( palette );
                  }
            widget->setBackgroundRole(QPalette::NoRole);
            }
      else if (qobject_cast<QMenuBar*>(widget)) {
            widget->setBackgroundRole(QPalette::NoRole);
            }
      else if (qobject_cast<QToolBar*>(widget)) {
            widget->setBackgroundRole(QPalette::NoRole);
#ifndef Q_OS_MAC
//WS            widget->setAttribute(Qt::WA_TranslucentBackground);
#endif
            widget->installEventFilter(this);
#ifdef Q_OS_WIN
            //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly
            widget->setWindowFlags(widget->windowFlags() | Qt::FramelessWindowHint);
#endif
            }
      else if ( qobject_cast<QTabBar*>(widget) ) {
            widget->installEventFilter( this );
            }
      else if ( widget->inherits( "QTipLabel" ) ) {
            widget->setBackgroundRole(QPalette::NoRole);
#ifndef Q_OS_MAC
            widget->setAttribute(Qt::WA_TranslucentBackground);
#endif

#ifdef Q_OS_WIN
            //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly
            widget->setWindowFlags(widget->windowFlags() | Qt::FramelessWindowHint);
#endif
            }
      else if ( qobject_cast<QScrollBar*>(widget) ) {
            widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
            // when painted in konsole, one needs to paint the window background below
            // the scrollarea, otherwise an ugly flat background is used
            if ( widget->parent() && widget->parent()->inherits( "Konsole::TerminalDisplay" ) ) {
                  widget->installEventFilter( this );
                  }
            }
      else if ( qobject_cast<QDockWidget*>(widget)) {
            widget->setBackgroundRole(QPalette::NoRole);
#ifndef Q_OS_MAC
//WS            widget->setAttribute(Qt::WA_TranslucentBackground);
#endif
            widget->setContentsMargins(3, 3, 3, 3);
            widget->installEventFilter(this);
            }

      else if ( qobject_cast<QMdiSubWindow*>(widget) ) {
            widget->setAutoFillBackground( false );
            widget->installEventFilter( this );
            }
      else if ( qobject_cast<QToolBox*>(widget)) {
            widget->setBackgroundRole(QPalette::NoRole);
            widget->setAutoFillBackground(false);
            widget->setContentsMargins(5, 5, 5, 5);
            widget->installEventFilter(this);
            }
      else if (widget->parentWidget() && widget->parentWidget()->parentWidget() && qobject_cast<QToolBox*>(widget->parentWidget()->parentWidget()->parentWidget())) {
            widget->setBackgroundRole(QPalette::NoRole);
            widget->setAutoFillBackground(false);
            widget->parentWidget()->setAutoFillBackground(false);
            }
      else if (qobject_cast<QMenu*>(widget)) {
#ifndef Q_OS_MAC
            // does not work on MAC
            widget->setAttribute(Qt::WA_TranslucentBackground);
#endif
#ifdef Q_OS_WIN
            //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly
            widget->setWindowFlags(widget->windowFlags() | Qt::FramelessWindowHint);
#endif
            }
      else if ( widget->inherits("QComboBoxPrivateContainer")) {
            widget->installEventFilter(this);
#ifndef Q_OS_MAC
            widget->setAttribute(Qt::WA_TranslucentBackground);
#endif
#ifdef Q_OS_WIN
            //FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly
            widget->setWindowFlags(widget->windowFlags() | Qt::FramelessWindowHint);
#endif
            }
      // base class polishing
      QCommonStyle::polish(widget);
      }

//---------------------------------------------------------
//   unpolish
//---------------------------------------------------------

void MgStyle::unpolish(QWidget* widget) {
      // register widget to animations

      animations().unregisterWidget(widget);
      transitions().unregisterWidget(widget);

      frameShadowFactory().unregisterWidget( widget );

      // event filters
      switch (widget->windowFlags() & Qt::WindowType_Mask) {
            case Qt::Window:
            case Qt::Dialog:
                  widget->removeEventFilter(this);
                  widget->setAttribute(Qt::WA_StyledBackground, false);
                  break;
            default:
                  break;
            }

      // checkable group boxes
      if (QGroupBox* groupBox = qobject_cast<QGroupBox*>(widget)) {
            if (groupBox->isCheckable())
                  groupBox->setAttribute(Qt::WA_Hover, false);
            }

      // hover flags
      if (
            qobject_cast<QAbstractItemView*>(widget)
            || qobject_cast<QAbstractSpinBox*>(widget)
            || qobject_cast<QCheckBox*>(widget)
            || qobject_cast<QComboBox*>(widget)
            || qobject_cast<QDial*>(widget)
            || qobject_cast<QLineEdit*>(widget)
            || qobject_cast<QPushButton*>(widget)
            || qobject_cast<QRadioButton*>(widget)
            || qobject_cast<QScrollBar*>(widget)
            || qobject_cast<QSlider*>(widget)
            || qobject_cast<QSplitterHandle*>(widget)
            || qobject_cast<QTabBar*>(widget)
            || qobject_cast<QTextEdit*>(widget)
            || qobject_cast<QToolButton*>(widget)
      ) {
            widget->setAttribute(Qt::WA_Hover, false);
            }

      // checkable group boxes
      if (QGroupBox* groupBox = qobject_cast<QGroupBox*>(widget)) {
            if (groupBox->isCheckable())
                  groupBox->setAttribute(Qt::WA_Hover, false);
            }

      if ( qobject_cast<QMenuBar*>(widget)
                  || (widget && widget->inherits("Q3ToolBar"))
                  || qobject_cast<QToolBar*>(widget)
                  || (widget && qobject_cast<QToolBar*>(widget->parent()))
                  || qobject_cast<QToolBox*>(widget)) {
            widget->setBackgroundRole(QPalette::Button);
            widget->removeEventFilter(this);
            widget->clearMask();
            }

      if ( qobject_cast<QTabBar*>(widget) ) {
            widget->removeEventFilter( this );
            }
      else if ( widget->inherits( "QTipLabel" ) ) {
            widget->setAttribute(Qt::WA_PaintOnScreen, false);
            widget->setAttribute(Qt::WA_NoSystemBackground, false);
            widget->clearMask();
            }
      else if ( qobject_cast<QScrollBar*>(widget) ) {
            widget->setAttribute(Qt::WA_OpaquePaintEvent);
            }
      else if ( qobject_cast<QDockWidget*>(widget) ) {
            widget->setContentsMargins(0, 0, 0, 0);
            widget->clearMask();
            }
      else if ( qobject_cast<QToolBox*>(widget) ) {
            widget->setBackgroundRole(QPalette::Button);
            widget->setContentsMargins(0, 0, 0, 0);
            widget->removeEventFilter(this);
            }
      else if ( qobject_cast<QMenu*>(widget) ) {
            widget->setAttribute(Qt::WA_PaintOnScreen, false);
            widget->setAttribute(Qt::WA_NoSystemBackground, false);
            widget->clearMask();
            }
      else if ( widget->inherits("QComboBoxPrivateContainer") )
            widget->removeEventFilter(this);
      QCommonStyle::unpolish(widget);
      }

//---------------------------------------------------------
//   polishScrollArea
//---------------------------------------------------------

void MgStyle::polishScrollArea( QAbstractScrollArea* scrollArea ) const {
      if (!scrollArea)
            return;

      // check frame style and background role
      if ( scrollArea->frameShape() != QFrame::NoFrame )
            return;
      if ( scrollArea->backgroundRole() != QPalette::Window )
            return;

      // get viewport and check background role
      QWidget* viewport( scrollArea->viewport() );
      if ( !( viewport && viewport->backgroundRole() == QPalette::Window ) )
            return;

      // change viewport autoFill background.
      // do the same for children if the background role is QPalette::Window
      viewport->setAutoFillBackground( false );
      QList<QWidget*> children( viewport->findChildren<QWidget*>() );
      foreach( QWidget * child, children ) {
            if ( child->parent() == viewport && child->backgroundRole() == QPalette::Window ) {
                  child->setAutoFillBackground( false );
                  }
            }
      }

//---------------------------------------------------------
//   drawPrimitive
//---------------------------------------------------------

void MgStyle::drawPrimitive(PrimitiveElement element, const QStyleOption* option,
                            QPainter* painter, const QWidget* widget) const {
      painter->save();
      StylePrimitive fcn(0);

      if(!widget)
            widget = QApplication::activeWindow();

      switch (element) {
            case PE_FrameStatusBar:
                  fcn = &MgStyle::emptyPrimitive;
                  break;
            case PE_Frame:
                  fcn = &MgStyle::drawFramePrimitive;
                  break;
            case PE_FrameFocusRect:
                  fcn = _frameFocusPrimitive;
                  break;
            case PE_FrameGroupBox:
                  fcn = &MgStyle::drawFrameGroupBoxPrimitive;
                  break;
            case PE_FrameLineEdit:
                  fcn = &MgStyle::drawFramePrimitive;
                  break;
            case PE_FrameMenu:
                  fcn = &MgStyle::drawFrameMenuPrimitive;
                  break;
            case PE_FrameTabBarBase:
                  fcn = &MgStyle::drawFrameTabBarBasePrimitive;
                  break;
            case PE_FrameTabWidget:
                  fcn = &MgStyle::drawFrameTabWidgetPrimitive;
                  break;
            case PE_FrameWindow:
                  fcn = &MgStyle::drawFrameWindowPrimitive;
                  break;
            case PE_IndicatorArrowUp:
                  fcn = &MgStyle::drawIndicatorArrowUpPrimitive;
                  break;
            case PE_IndicatorArrowDown:
                  fcn = &MgStyle::drawIndicatorArrowDownPrimitive;
                  break;
            case PE_IndicatorArrowLeft:
                  fcn = &MgStyle::drawIndicatorArrowLeftPrimitive;
                  break;
            case PE_IndicatorArrowRight:
                  fcn = &MgStyle::drawIndicatorArrowRightPrimitive;
                  break;
            case PE_IndicatorDockWidgetResizeHandle:
                  fcn = &MgStyle::drawIndicatorDockWidgetResizeHandlePrimitive;
                  break;
            case PE_IndicatorHeaderArrow:
                  fcn = &MgStyle::drawIndicatorHeaderArrowPrimitive;
                  break;
            case PE_PanelButtonCommand:
                  fcn = &MgStyle::drawPanelButtonCommandPrimitive;
                  break;
            case PE_PanelButtonTool:
                  fcn = &MgStyle::drawPanelButtonToolPrimitive;
                  break;
            case PE_PanelItemViewItem:
                  fcn = &MgStyle::drawPanelItemViewItemPrimitive;
                  break;
            case PE_PanelLineEdit:
                  fcn = &MgStyle::drawPanelLineEditPrimitive;
                  break;
            case PE_PanelMenu:
                  fcn = &MgStyle::drawPanelMenuPrimitive;
                  break;
            case PE_PanelScrollAreaCorner:
                  fcn = &MgStyle::drawPanelScrollAreaCornerPrimitive;
                  break;
            case PE_PanelTipLabel:
                  fcn = &MgStyle::drawPanelTipLabelPrimitive;
                  break;
            case PE_IndicatorBranch:
                  fcn = &MgStyle::drawIndicatorBranchPrimitive;
                  break;
            case PE_IndicatorButtonDropDown:
                  fcn = &MgStyle::drawIndicatorButtonDropDownPrimitive;
                  break;
            case PE_IndicatorCheckBox:
                  fcn = &MgStyle::drawIndicatorCheckBoxPrimitive;
                  break;
            case PE_IndicatorRadioButton:
                  fcn = &MgStyle::drawIndicatorRadioButtonPrimitive;
                  break;
            case PE_IndicatorTabTear:
                  fcn = &MgStyle::drawIndicatorTabTearPrimitive;
                  break;
            case PE_IndicatorToolBarHandle:
                  fcn = &MgStyle::drawIndicatorToolBarHandlePrimitive;
                  break;
            case PE_IndicatorToolBarSeparator:
                  fcn = &MgStyle::drawIndicatorToolBarSeparatorPrimitive;
                  break;
            case PE_Widget:
                  fcn = &MgStyle::drawWidgetPrimitive;
                  break;
            default:
                  break;
            }

      // try find primitive in map, and run.
      // exit if result is true, otherwise fallback to generic case
      if (!(fcn && (this->*fcn)(option, painter, widget)))
            QCommonStyle::drawPrimitive( element, option, painter, widget );
      painter->restore();
      }

//---------------------------------------------------------
//   drawPanelTipLabelPrimitive
//---------------------------------------------------------

bool MgStyle::drawPanelTipLabelPrimitive(const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      // parent style painting if frames should not be styled
      if (!MgStyleConfigData::toolTipDrawStyledFrames)
            return false;

      const QRect& r( option->rect );
      const QColor color( option->palette.brush(QPalette::ToolTipBase).color() );
      QColor topColor(_helper.backgroundTopColor(color));
      QColor bottomColor(_helper.backgroundBottomColor(color));

      // make tooltip semi transparents when possible
      // alpha is copied from "kdebase/apps/dolphin/tooltips/filemetadatatooltip.cpp"
      const bool hasAlpha = _helper.hasAlphaChannel(widget);
      if (hasAlpha && MgStyleConfigData_toolTipTransparent) {
            topColor.setAlpha(220);
            bottomColor.setAlpha(220);
            }

      QLinearGradient gr(0, r.top(), 0, r.bottom());
      gr.setColorAt(0, topColor);
      gr.setColorAt(1, bottomColor);

      // contrast pixmap
      QLinearGradient gr2(0, r.top(), 0, r.bottom());
      gr2.setColorAt(0.5, _helper.calcLightColor(bottomColor));
      gr2.setColorAt(0.9, bottomColor);

      painter->save();
      if (hasAlpha) {
            painter->setRenderHint(QPainter::Antialiasing);
            QRectF local( r );
            local.adjust( 0.5, 0.5, -0.5, -0.5 );

            painter->setPen( Qt::NoPen );
            painter->setBrush( gr );
            painter->drawRoundedRect( local, 4, 4 );

            painter->setBrush( Qt::NoBrush );
            painter->setPen(QPen( gr2, 1.1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            painter->drawRoundedRect( local, 4, 4 );
            }
      else {
            painter->setPen(Qt::NoPen);
            painter->setBrush(gr);
            painter->drawRect(r);

            painter->setBrush(Qt::NoBrush);
            painter->setPen(QPen(gr2, 1.1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            painter->drawRect(r);
            }
      painter->restore();
      return true;
      }

//---------------------------------------------------------
//   drawFramePrimitive
//---------------------------------------------------------

bool MgStyle::drawFramePrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {
      const State& flags( option->state );
      const QRect& r( option->rect );
      const QPalette& palette( option->palette );

      const bool enabled( flags & State_Enabled );
      const bool isInputWidget( widget && widget->testAttribute( Qt::WA_Hover ) );
      const bool hoverHighlight( enabled && isInputWidget && (flags & State_MouseOver) );


      //const bool focusHighlight( enabled && isInputWidget && (flags&State_HasFocus) );
      bool focusHighlight(false);
      if ( enabled && isInputWidget && (flags & State_HasFocus) )
            focusHighlight = true;

      // assume focus takes precedence over hover
      animations().lineEditEngine().updateState( widget, AnimationFocus, focusHighlight );
      animations().lineEditEngine().updateState( widget, AnimationHover, hoverHighlight && !focusHighlight );

      if ( flags & State_Sunken) {
            const QRect local( r.adjusted( 1, 1, -1, -1 ) );
            qreal opacity( -1 );
            AnimationMode mode = AnimationNone;
            if ( enabled && animations().lineEditEngine().isAnimated( widget, AnimationFocus ) ) {

                  opacity = animations().lineEditEngine().opacity( widget, AnimationFocus  );
                  mode = AnimationFocus;

                  }
            else if ( enabled && animations().lineEditEngine().isAnimated( widget, AnimationHover ) ) {

                  opacity = animations().lineEditEngine().opacity( widget, AnimationHover );
                  mode = AnimationHover;

                  }

            if ( frameShadowFactory().isRegistered( widget ) ) {

                  frameShadowFactory().updateState( widget, focusHighlight, hoverHighlight, opacity, mode );

                  }
            else {

                  _helper.renderHole(
                        painter, palette.color(QPalette::Window), local, focusHighlight, hoverHighlight,
                        opacity, mode, TileSet::Ring );

                  }

            }
      else if ( flags & State_Raised ) {

            const QRect local( r.adjusted(-1, -1, 1, 1) );
            renderSlab( painter, local, palette.color(QPalette::Background), NoFill);

            }

      return true;
      }

bool MgStyle::drawFrameFocusRectPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {
      if(!widget)
            widget = QApplication::activeWindow();

      if ( !widget ) return true;

      // focus indicators are painted only in Q3ListView and QAbstractItemView
      if ( !( qobject_cast<const QAbstractItemView*>( widget ) || widget->inherits( "Q3ListView" ) ) )
            return true;

      return true; // WS

      const State& flags( option->state );
      const QRect r( option->rect.adjusted( 0, 0, 0, -2 ) );
      const QPalette& palette( option->palette );

      QLinearGradient lg(r.bottomLeft(), r.bottomRight() );

      lg.setColorAt(0.0, Qt::transparent);
      lg.setColorAt(1.0, Qt::transparent);
      if ( flags & State_Selected) {

            lg.setColorAt(0.2, palette.color(QPalette::BrightText));
            lg.setColorAt(0.8, palette.color(QPalette::BrightText));

            }
      else {

            lg.setColorAt(0.2, palette.color(QPalette::Text));
            lg.setColorAt(0.8, palette.color(QPalette::Text));

            }

      painter->setRenderHint(QPainter::Antialiasing, false);
      painter->setPen(QPen(lg, 1));
      painter->drawLine(r.bottomLeft(), r.bottomRight() );

      return true;

      }

//---------------------------------------------------------
//   drawFrameGroupBoxPrimitive
//---------------------------------------------------------

bool MgStyle::drawFrameGroupBoxPrimitive(const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      if(!widget)
            widget = QApplication::activeWindow();

      // cast option and check
      const QStyleOptionFrame* fOpt = qstyleoption_cast<const QStyleOptionFrame*>(option);
      if (!fOpt)
            return true;

      // no frame for flat groupboxes
      QStyleOptionFrameV2 fOpt2(*fOpt);
      if (fOpt2.features & QStyleOptionFrameV2::Flat)
            return true;

      // normal frame
      const QPalette& palette( option->palette );
      const QRect& r( option->rect );
      const QColor base( _helper.backgroundColor( palette.color( QPalette::Window ), widget, r.center() ) );

      painter->save();
      painter->setRenderHint(QPainter::Antialiasing);
      painter->setPen(Qt::NoPen);

      //lasconic : no gradient
      /*QLinearGradient innerGradient(0, r.top() - r.height() + 12, 0, r.bottom() + r.height() - 19);
      QColor light(_helper.calcLightColor(base));
      light.setAlphaF(0.4);
      innerGradient.setColorAt(0.0, light);
      light.setAlphaF(0.0);
      innerGradient.setColorAt(1.0, light);
      painter->setBrush(innerGradient);
      painter->setClipRect(r.adjusted(0, 0, 0, -19));
      _helper.fillSlab(*painter, r);*/

      TileSet* slopeTileSet = _helper.slope(base, 0.0);
      painter->setClipping(false);
      slopeTileSet->render(r, painter);

      painter->restore();
      return true;
      }

bool MgStyle::drawFrameMenuPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      // only draw frame for (expanded) toolbars
      // do nothing for other cases
      if(!widget)
            widget = QApplication::activeWindow();

      if ( qobject_cast<const QToolBar*>(widget) ) {
            _helper.renderWindowBackground( painter, option->rect, widget, option->palette );
            _helper.drawFloatFrame( painter, option->rect, option->palette.window().color(), true );
            }
      return true;
      }

bool MgStyle::drawFrameTabBarBasePrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const {

      // cast option and check
      const QStyleOptionTabBarBase* tabOpt( qstyleoption_cast<const QStyleOptionTabBarBase*>( option ) );
      if ( !tabOpt ) return true;

      if ( tabOpt->tabBarRect.isValid() ) {

            // if tabBar rect is valid, all the frame is handled in tabBarTabShapeControl
            // nothing to be done here.
            // on the other hand, invalid tabBarRect corresponds to buttons in tabbars (e.g. corner buttons),
            // and the appropriate piece of frame needs to be drawn
            return true;

            }

      // store palette and rect
      const QPalette& palette( option->palette );
      const QRect& r( option->rect );

      QRect frameRect( r );
      SlabRect slab;
      switch ( tabOpt->shape ) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth: {
                  frameRect.adjust( -7, -GlowWidth, 7, GlowWidth );
                  frameRect.translate( 0, 4 );
                  slab = SlabRect( frameRect, TileSet::Top );
                  break;
                  }

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth: {
                  frameRect.adjust( -7, -GlowWidth, 7, GlowWidth );
                  frameRect.translate( 0, -4 );
                  slab = SlabRect( frameRect, TileSet::Bottom );
                  break;
                  }

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest: {
                  frameRect.adjust( -GlowWidth, -7, GlowWidth, 7 + 1 );
                  frameRect.translate( 5, 0 );
                  slab = SlabRect( frameRect, TileSet::Left );
                  break;
                  }

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast: {
                  frameRect.adjust( -GlowWidth, -7, GlowWidth, 7 + 1 );
                  frameRect.translate( -5, 0 );
                  slab = SlabRect( frameRect, TileSet::Right );
                  break;
                  }

            default:
                  return true;
            }

      // render registered slabs
      renderSlab( painter, slab, palette.color(QPalette::Window), NoFill );

      return true;
      }

bool MgStyle::drawFrameTabWidgetPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const {
      // cast option and check
      const QStyleOptionTabWidgetFrame* tabOpt( qstyleoption_cast<const QStyleOptionTabWidgetFrame*>( option ) );
      if ( !tabOpt )
            return true;

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      const bool reverseLayout( option->direction == Qt::RightToLeft );

      /*
      no frame is drawn when tabbar is empty.
      this is consistent with the tabWidgetTabContents subelementRect
      */
      if ( tabOpt->tabBarSize.isEmpty() ) return true;

      // get tabbar dimentions
      const int w( tabOpt->tabBarSize.width() );
      const int h( tabOpt->tabBarSize.height() );

      // left corner widget
      const int lw( tabOpt->leftCornerWidgetSize.width() );
      const int lh( tabOpt->leftCornerWidgetSize.height() );

      // right corner
      const int rw( tabOpt->rightCornerWidgetSize.width() );
      const int rh( tabOpt->rightCornerWidgetSize.height() );

      // list of slabs to be drawn
      SlabRectList slabs;

      // expand rect by glow width.
      QRect baseSlabRect( insideMargin( r, -GlowWidth ) );

      // render the three free sides
      switch ( tabOpt->shape ) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth: {
                  // main slab
                  slabs << SlabRect( baseSlabRect, (TileSet::Ring & ~TileSet::Top) );

                  // top
                  if ( reverseLayout ) {

                        // left side
                        QRect slabRect( baseSlabRect );
                        slabRect.setRight( qMax( slabRect.right() - w - lw, slabRect.left() + rw ) + 7 );
                        slabRect.setHeight( 7 );
                        slabs << SlabRect( slabRect, TileSet::TopLeft );

                        // right side
                        if ( rw > 0 ) {
                              QRect slabRect( baseSlabRect );
                              slabRect.setLeft( slabRect.right() - rw - 7 );
                              slabRect.setHeight( 7 );
                              slabs << SlabRect( slabRect, TileSet::TopRight );
                              }

                        }
                  else {

                        // left side
                        if ( lw > 0 ) {

                              QRect slabRect( baseSlabRect );
                              slabRect.setRight( baseSlabRect.left() + lw + 7 );
                              slabRect.setHeight( 7 );
                              slabs << SlabRect( slabRect, TileSet::TopLeft );

                              }


                        // right side
                        QRect slabRect( baseSlabRect );
                        slabRect.setLeft( qMin( slabRect.left() + w + lw + 1, slabRect.right() - rw ) - 7 );
                        slabRect.setHeight( 7 );
                        slabs << SlabRect( slabRect, TileSet::TopRight );

                        }
                  break;
                  }

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth: {

                  slabs << SlabRect( baseSlabRect, TileSet::Ring & ~TileSet::Bottom );

                  if ( reverseLayout ) {

                        // left side
                        QRect slabRect( baseSlabRect );
                        slabRect.setRight( qMax( slabRect.right() - w - lw, slabRect.left() + rw ) + 7 );
                        slabRect.setTop( slabRect.bottom() - 7 );
                        slabs << SlabRect( slabRect, TileSet::BottomLeft );

                        // right side
                        if ( rw > 0 ) {
                              QRect slabRect( baseSlabRect );
                              slabRect.setLeft( slabRect.right() - rw - 7 );
                              slabRect.setTop( slabRect.bottom() - 7 );
                              slabs << SlabRect( slabRect, TileSet::BottomRight );
                              }

                        }
                  else {

                        // left side
                        if ( lw > 0 ) {

                              QRect slabRect( baseSlabRect );
                              slabRect.setRight( baseSlabRect.left() + lw + 7 );
                              slabRect.setTop( slabRect.bottom() - 7 );
                              slabs << SlabRect( slabRect, TileSet::BottomLeft );

                              }

                        // right side
                        QRect slabRect( baseSlabRect );
                        slabRect.setLeft( qMin( slabRect.left() + w + lw + 1, slabRect.right() - rw ) - 7 );
                        slabRect.setTop( slabRect.bottom() - 7 );
                        slabs << SlabRect( slabRect, TileSet::BottomRight );

                        }

                  break;
                  }

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest: {
                  slabs << SlabRect( baseSlabRect, TileSet::Ring & ~TileSet::Left );

                  // top side
                  if ( lh > 0 ) {

                        QRect slabRect( baseSlabRect );
                        slabRect.setBottom( baseSlabRect.top() + lh + 7 + 1 );
                        slabRect.setWidth( 7 );
                        slabs << SlabRect( slabRect, TileSet::TopLeft );

                        }

                  // bottom side
                  QRect slabRect( baseSlabRect );
                  slabRect.setTop( qMin( slabRect.top() + h + lh, slabRect.bottom() - rh ) - 7 + 1 );
                  slabRect.setWidth( 7 );
                  slabs << SlabRect( slabRect, TileSet::BottomLeft );

                  break;
                  }

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast: {
                  slabs << SlabRect( baseSlabRect, TileSet::Ring & ~TileSet::Right );

                  // top side
                  if ( lh > 0 ) {

                        QRect slabRect( baseSlabRect );
                        slabRect.setBottom( baseSlabRect.top() + lh + 7 + 1 );
                        slabRect.setLeft( slabRect.right() - 7 );
                        slabs << SlabRect( slabRect, TileSet::TopRight );

                        }

                  // bottom side
                  QRect slabRect( baseSlabRect );
                  slabRect.setTop( qMin( slabRect.top() + h + lh, slabRect.bottom() - rh ) - 7 + 1 );
                  slabRect.setLeft( slabRect.right() - 7 );
                  slabs << SlabRect( slabRect, TileSet::BottomRight );
                  break;
                  }

            break;

            default:
                  break;
            }

      // render registered slabs
      foreach( const SlabRect & slab, slabs ) {
            renderSlab( painter, slab, palette.color(QPalette::Window), NoFill );
            }

      return true;

      }

bool MgStyle::drawFrameWindowPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const {
      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      _helper.drawFloatFrame( painter, r, palette.window().color(), false );
      return true;
      }

bool MgStyle::drawIndicatorArrowPrimitive( ArrowOrientation orientation, const QStyleOption* option, QPainter* painter, const QWidget* ) const {
      const QRect& r(option->rect);
      const QPalette& palette(option->palette);
      const State& flags(option->state);
      const bool enabled(flags & State_Enabled);
      const bool mouseOver(enabled && (flags & State_MouseOver));

      // define gradient and polygon for drawing arrow
      const QPolygonF a = genericArrow(orientation, ArrowNormal);

      QColor color = palette.color(QPalette::WindowText);
      const QColor background = palette.color(QPalette::Window);
      const QColor highlight( _helper.viewHoverBrush().brush(palette).color());
      const qreal penThickness = 1.6;
      const qreal offset(qMin( penThickness, qreal(1.0)));

      if (mouseOver)
            color = highlight;

      painter->translate(r.center());
      painter->setRenderHint(QPainter::Antialiasing);

      painter->translate(0, offset);
      painter->setPen(QPen(_helper.calcLightColor(background), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
      painter->drawPolyline(a);
      painter->translate(0, -offset);

      painter->setPen(QPen(_helper.decoColor(background, color), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
      painter->drawPolyline(a);
      return true;
      }

bool MgStyle::drawIndicatorHeaderArrowPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {
      const QStyleOptionHeader* headerOpt = qstyleoption_cast<const QStyleOptionHeader*>(option);
      const State& flags( option->state );

      if(!widget)
            widget = QApplication::activeWindow();

      // arrow orientation
      ArrowOrientation orientation( ArrowNone );
      if ( flags& State_UpArrow || ( headerOpt && headerOpt->sortIndicator == QStyleOptionHeader::SortUp ) ) orientation = ArrowUp;
      else if ( flags& State_DownArrow || ( headerOpt && headerOpt->sortIndicator == QStyleOptionHeader::SortDown ) ) orientation = ArrowDown;
      if ( orientation == ArrowNone ) return true;

      // flags, rect and palette
      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      const bool enabled( flags & State_Enabled );
      const bool mouseOver( enabled && (flags & State_MouseOver ) );

      animations().headerViewEngine().updateState( widget, r.topLeft(), mouseOver );
      const bool animated( enabled && animations().headerViewEngine().isAnimated( widget, r.topLeft() ) );

      // define gradient and polygon for drawing arrow
      const QPolygonF a = genericArrow( orientation, ArrowNormal );
      QColor color = palette.color( QPalette::WindowText );
      const QColor background = palette.color(QPalette::Window);
      const QColor highlight( _helper.viewHoverBrush().brush(palette).color() );
      const qreal penThickness = 1.6;
      const qreal offset( qMin( penThickness, qreal(1.0)) );

      if ( animated ) {

            const qreal opacity( animations().headerViewEngine().opacity( widget, r.topLeft() ) );
            color = ColorUtils::mix( color, highlight, opacity );

            }
      else if ( mouseOver ) color = highlight;

      painter->translate( r.center() );
      painter->translate( 0, 1 );
      painter->setRenderHint(QPainter::Antialiasing);

      painter->translate(0, offset);
      painter->setPen(QPen(_helper.calcLightColor(background), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
      painter->drawPolyline(a);
      painter->translate(0, -offset);

      painter->setPen(QPen( _helper.decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
      painter->drawPolyline(a);

      return true;
      }

//---------------------------------------------------------
//   drawPanelButtonCommandPrimitive
//---------------------------------------------------------

bool MgStyle::drawPanelButtonCommandPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
      {
      if(!widget)
            widget = QApplication::activeWindow();

      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );
      const bool mouseOver( enabled && (flags & State_MouseOver) );
      const bool hasFocus( enabled && (flags & State_HasFocus) );
      const QPalette& palette( option->palette );

      StyleOptions opts = 0;
      if ( flags & (State_On | State_Sunken) ) opts |= Sunken;
      if ( flags & State_HasFocus) opts |= Focus;
      if ( enabled && (flags & State_MouseOver)) opts |= Hover;

      // update animation state
      animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
      animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );

      // store animation state
      const bool hoverAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationHover ) );
      const bool focusAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) );
      const qreal hoverOpacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
      const qreal focusOpacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );

      // decide if widget must be rendered flat.
      /*
      The decision is made depending on
      - whether the "flat" flag is set in the option
      - whether the widget is hight enough to render both icons and normal margins
      Note: in principle one should also check for the button text height
      */

      const QRect& r( option->rect );
      const QStyleOptionButton* bOpt( qstyleoption_cast< const QStyleOptionButton* >( option ) );
      bool flat = ( bOpt && (
                          bOpt->features.testFlag( QStyleOptionButton::Flat ) ||
                          ( (!bOpt->icon.isNull()) && sizeFromContents( CT_PushButton, option, bOpt->iconSize, widget ).height() > r.height() ) ) );

      if ( flat ) {

            QRect slitRect(r);
            if ( !( opts & Sunken) ) {
                  // hover rect
                  if ( enabled && hoverAnimated ) {

                        QColor glow( _helper.alphaColor( _helper.viewFocusBrush().brush(QPalette::Active).color(), hoverOpacity ) );
                        _helper.slitFocused( glow )->render(slitRect, painter );

                        }
                  else if ( mouseOver) {

                        _helper.slitFocused(_helper.viewFocusBrush().brush(QPalette::Active).color())->render(slitRect, painter );

                        }

                  }
            else {

                  slitRect.adjust( 0, 0, 0, -1 );

                  // flat pressed-down buttons do not get focus effect,
                  // consistently with tool buttons
                  if ( enabled && hoverAnimated ) {

                        _helper.renderHole( painter, palette.color(QPalette::Window), slitRect, false, mouseOver, hoverOpacity, AnimationHover, TileSet::Ring );

                        }
                  else {

                        _helper.renderHole( painter, palette.color(QPalette::Window), slitRect, false, mouseOver);

                        }

                  }

            }
      else {

            const QRect slabRect(r.adjusted( -1, 0, 1, 0 ) );

            // match color to the window background
            const QColor buttonColor( _helper.backgroundColor( palette.color(QPalette::Button), widget, r.center() ) );

            if ( enabled && hoverAnimated && !(opts & Sunken ) ) {

                  renderButtonSlab( painter, slabRect, buttonColor, opts, hoverOpacity, AnimationHover, TileSet::Ring );

                  }
            else if ( enabled && !mouseOver && focusAnimated && !(opts & Sunken ) ) {

                  renderButtonSlab( painter, slabRect, buttonColor, opts, focusOpacity, AnimationFocus, TileSet::Ring );

                  }
            else {

                  renderButtonSlab( painter, slabRect, buttonColor, opts);

                  }

            }

      return true;

      }

//---------------------------------------------------------
//   drawPanelButtonToolPrimitive
//---------------------------------------------------------

bool MgStyle::drawPanelButtonToolPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget) const
      {
      /*
      For toolbutton in TabBars, corresponding to expanding arrows, no frame is drawn
      However one needs to draw the window background, because the button rect might
      overlap with some tab below. (this is a Qt bug)
      */
      if(!widget)
            widget = QApplication::activeWindow();

      bool isInTabBar(widget && qobject_cast<const QTabBar*>( widget->parent()));

      if (qobject_cast<const Ms::PaletteBoxButton*>(widget))
            isInTabBar = true;

      if (isInTabBar) {
            const QPalette& palette(option->palette);
            QRect r(option->rect);

            // adjust rect depending on shape
            if (qobject_cast<const QTabBar*>( widget->parent())) {
                  const QTabBar* tabBar( static_cast<const QTabBar*>( widget->parent() ) );
                  switch ( tabBar->shape() ) {
                        case QTabBar::RoundedNorth:
                        case QTabBar::TriangularNorth:
                              r.setBottom( r.bottom() - 6 );
                              break;

                        case QTabBar::RoundedSouth:
                        case QTabBar::TriangularSouth:
                              r.setTop( r.top() + 6 );
                              break;

                        case QTabBar::RoundedWest:
                        case QTabBar::TriangularWest:
                              r.setRight( r.right() - 6 );
                              break;

                        case QTabBar::RoundedEast:
                        case QTabBar::TriangularEast:
                              r.setLeft( r.left() + 6 );
                              break;

                        default:
                              break;

                        }
                  }

            const QPalette local(widget && widget->parentWidget() ? widget->parentWidget()->palette() : palette);

            // check whether parent has autofill background flag
            if (const QWidget* parent = _helper.checkAutoFillBackground(widget))
                  painter->fillRect(r, parent->palette().color(parent->backgroundRole()));
            else
                  _helper.renderWindowBackground(painter, r, widget, local);
            return true;
            }

      const QRect& r( option->rect );
      const State& flags( option->state );
      const QPalette& palette( option->palette );

      const bool enabled( flags & State_Enabled );
      const bool mouseOver(enabled && (flags & State_MouseOver));
      const bool hasFocus(enabled && (flags & State_HasFocus));
      const bool reverseLayout( option->direction == Qt::RightToLeft );
      const bool autoRaised( flags & State_AutoRaise );

      // check whether toolbutton is in toolbar
      const bool isInToolBar( widget && qobject_cast<const QToolBar*>( widget->parent() ) );

      // toolbar engine
      const bool toolBarAnimated( isInToolBar /*&& widget */ && ( animations().toolBarEngine().isAnimated( widget->parentWidget() ) || animations().toolBarEngine().isFollowMouseAnimated( widget->parentWidget() ) ) );
      const QRect animatedRect( (isInToolBar /* && widget */) ? animations().toolBarEngine().animatedRect( widget->parentWidget() ) : QRect() );
#if 0 // yet (?) unused
      const QRect childRect( (widget && widget->parentWidget()) ? r.translated( widget->mapToParent( QPoint(0, 0) ) ) : QRect() );
#endif
      const QRect currentRect(  widget ? animations().toolBarEngine().currentRect( widget->parentWidget() ) : QRect() );
      const bool current( isInToolBar /* && widget */ && widget->parentWidget() && currentRect.intersects( r.translated( widget->mapToParent( QPoint(0, 0) ) ) ) );
      const bool toolBarTimerActive( isInToolBar /* && widget */ && animations().toolBarEngine().isTimerActive( widget->parentWidget() ) );
      const qreal toolBarOpacity( ( isInToolBar /* && widget */) ? animations().toolBarEngine().opacity( widget->parentWidget() ) : 0 );

      // toolbutton engine
      if ( isInToolBar && !toolBarAnimated ) {
            animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
            }
      else {
            // mouseOver has precedence over focus
            animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
            animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );
            }

      bool hoverAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationHover ) );
      bool focusAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) );

      qreal hoverOpacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
      qreal focusOpacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );

      // slit rect
      QRect slitRect( r );

      // non autoraised tool buttons get same slab as regular buttons
      if (widget && !autoRaised) {
            StyleOptions opts = 0;
            slitRect.adjust( -1, 0, 1, 0 );

            // "normal" parent, and non "autoraised" (that is: always raised) buttons
            if ( flags & (State_On | State_Sunken) )
                  opts |= Sunken;
            if ( flags & State_HasFocus)
                  opts |= Focus;
            if ( enabled && (flags & State_MouseOver))
                  opts |= Hover;

            TileSet::Tiles tiles(TileSet::Ring);

            // adjust tiles and rect in case of menubutton
            const QToolButton* t = qobject_cast<const QToolButton*>( widget );
            if ( t && t->popupMode() == QToolButton::MenuButtonPopup ) {
                  if ( reverseLayout ) {
                        tiles = TileSet::Bottom | TileSet::Top | TileSet::Right;
                        slitRect.adjust( -4, 0, 0, 0 );

                        }
                  else {
                        tiles = TileSet::Bottom | TileSet::Top | TileSet::Left;
                        slitRect.adjust( 0, 0, 4, 0 );
                        }
                  }

            // adjust opacity and animation mode
            qreal opacity( -1 );
            AnimationMode mode( AnimationNone );
            if ( enabled && hoverAnimated ) {
                  opacity = hoverOpacity;
                  mode = AnimationHover;

                  }
            else if ( enabled && !hasFocus && focusAnimated ) {

                  opacity = focusOpacity;
                  mode = AnimationFocus;

                  }

            // match button color to window background
            const QColor buttonColor( _helper.backgroundColor( palette.color(QPalette::Button), widget, r.center() ) );

            // render slab
            renderButtonSlab( painter, slitRect, buttonColor, opts, opacity, mode, tiles );
            return true;
            }

      //! fine tuning of slitRect geometry
      if ( widget && widget->inherits( "QDockWidgetTitleButton" ) )
            slitRect.adjust( 1, 0, 0, 0 );
      else if ( widget && widget->inherits( "QToolBarExtension" ) )
            slitRect.adjust( 1, 1, -1, -1 );
      else if ( widget && widget->objectName() == "qt_menubar_ext_button" )
            slitRect.adjust( -1, -1, 0, 0 );

      // normal (auto-raised) toolbuttons
      if (flags & (State_Sunken | State_On)) {
            // painter->setBrush(palette.color(QPalette::Base));           // button Background
            painter->setBrush(widget ? widget->palette().color(QPalette::Base) : palette.color(QPalette::Base));           // button Background
            painter->setPen(Qt::NoPen);
            _helper.fillHole(*painter, slitRect.adjusted(-2, -2, 4, 4));
            QColor color(palette.color(QPalette::Window));
            if (enabled && hoverAnimated )
                  _helper.renderHole(painter, color, slitRect, hasFocus, mouseOver, hoverOpacity, AnimationHover, TileSet::Ring);
            else if (toolBarAnimated ) {
                  if (enabled && animatedRect.isNull() && current)
                        _helper.renderHole(painter, color, slitRect, hasFocus, mouseOver, toolBarOpacity, AnimationHover, TileSet::Ring);
                  else
                        _helper.renderHole(painter, color, slitRect, false, false);
                  }
            else if (toolBarTimerActive && current )
                  _helper.renderHole(painter, color, slitRect, hasFocus, true);
            else
                  _helper.renderHole(painter, color, slitRect, hasFocus, mouseOver);
            }
      else {

            if ( enabled && hoverAnimated ) {

                  QColor glow( _helper.alphaColor( _helper.viewFocusBrush().brush(QPalette::Active).color(), hoverOpacity ) );
                  _helper.slitFocused( glow )->render( slitRect, painter );

                  }
            else if ( toolBarAnimated ) {

                  if ( enabled && animatedRect.isNull() && current ) {
                        QColor glow( _helper.alphaColor( _helper.viewFocusBrush().brush(QPalette::Active).color(), toolBarOpacity ) );
                        _helper.slitFocused( glow )->render( slitRect, painter );
                        }

                  }
            else if ( hasFocus || mouseOver || (toolBarTimerActive && current ) ) {

                  _helper.slitFocused(_helper.viewFocusBrush().brush(QPalette::Active).color())->render( slitRect, painter );

                  }

            }

      return true;
      }

bool MgStyle::drawPanelItemViewItemPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      const QStyleOptionViewItemV4* opt = qstyleoption_cast<const QStyleOptionViewItemV4*>(option);
      const QAbstractItemView* view = qobject_cast<const QAbstractItemView*>(widget);
      const bool hover = (option->state & State_MouseOver) && (!view || view->selectionMode() != QAbstractItemView::NoSelection);

      const bool hasCustomBackground = opt->backgroundBrush.style() != Qt::NoBrush && !(option->state & State_Selected);
      const bool hasSolidBackground = !hasCustomBackground || opt->backgroundBrush.style() == Qt::SolidPattern;

      if ( !hover && !(option->state & State_Selected) && !hasCustomBackground && !(opt->features & QStyleOptionViewItemV2::Alternate) ) {
            return true;
            }

      QPalette::ColorGroup cg;
      if ( option->state & State_Enabled) cg = (option->state & State_Active) ? QPalette::Normal : QPalette::Inactive;
      else cg = QPalette::Disabled;

      QColor color;
      if ( hasCustomBackground && hasSolidBackground) color = opt->backgroundBrush.color();
      else color = option->palette.color(cg, QPalette::Highlight);

      if ( hover && !hasCustomBackground) {
            if ( !(option->state & State_Selected)) color.setAlphaF(0.2);
            else color = color.lighter(110);
            }

      if ( opt && (opt->features & QStyleOptionViewItemV2::Alternate)) {
            painter->fillRect(option->rect, option->palette.brush(cg, QPalette::AlternateBase));
            }

      if ( !hover && !(option->state & State_Selected) && !hasCustomBackground) {
            return true;
            }

      if ( hasCustomBackground && !hasSolidBackground) {

            const QPointF oldBrushOrigin = painter->brushOrigin();
            painter->setBrushOrigin(opt->rect.topLeft());
            painter->setBrush(opt->backgroundBrush);
            painter->setPen(Qt::NoPen);
            painter->drawRect(opt->rect);
            painter->setBrushOrigin(oldBrushOrigin);

            }
      else {

            // get selection tileset
            QRect r = option->rect;
            TileSet* tileSet( _helper.selection( color, r.height(), hasCustomBackground ) );

            bool roundedLeft  = false;
            bool roundedRight = false;
            if ( opt ) {

                  roundedLeft  = (opt->viewItemPosition == QStyleOptionViewItemV4::Beginning);
                  roundedRight = (opt->viewItemPosition == QStyleOptionViewItemV4::End);
                  if ( opt->viewItemPosition == QStyleOptionViewItemV4::OnlyOne ||
                              opt->viewItemPosition == QStyleOptionViewItemV4::Invalid ||
                              (view && view->selectionBehavior() != QAbstractItemView::SelectRows)) {
                        roundedLeft  = true;
                        roundedRight = true;
                        }

                  }

            const bool reverseLayout( option->direction == Qt::RightToLeft );

            TileSet::Tiles tiles( TileSet::Center );
            if ( !reverseLayout ? roundedLeft : roundedRight) tiles |= TileSet::Left;
            else r.adjust( -8, 0, 0, 0 );

            if ( !reverseLayout ? roundedRight : roundedLeft) tiles |= TileSet::Right;
            else r.adjust( 0, 0, 8, 0 );

            if ( r.isValid()) tileSet->render( r, painter, tiles );
            }

      return true;
      }

bool MgStyle::drawPanelLineEditPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {

      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );

      // cast option and check
      const QStyleOptionFrame* panel = qstyleoption_cast<const QStyleOptionFrame*>(option);
      if ( !panel ) return true;

      const QBrush inputBrush( enabled ? palette.base() : palette.window() );
      const int lineWidth(panel->lineWidth);

      if(!widget)
            widget = QApplication::activeWindow();

      if ( lineWidth > 0) {
            painter->save();
            painter->setRenderHint(QPainter::Antialiasing);
            painter->setPen(Qt::NoPen);
            painter->setBrush(inputBrush);

            _helper.fillHole(*painter, r.adjusted( 0, -1, 0, 0 ) );
            drawPrimitive(PE_FrameLineEdit, panel, painter, widget);

            painter->restore();

            }
      else  {

            painter->fillRect(r.adjusted(2, 2, -2, -2), inputBrush);

            }

      return true;

      }

//---------------------------------------------------------
//   drawPanelMenuPrimitive
//---------------------------------------------------------

bool MgStyle::drawPanelMenuPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      // do nothing if menu is embedded in another widget
      // this corresponds to having a transparent background
      if(!widget)
            widget = QApplication::activeWindow();

      if (widget && !widget->isWindow())
            return true;

      const QStyleOptionMenuItem* mOpt( qstyleoption_cast<const QStyleOptionMenuItem*>(option) );
      if ( !( mOpt && widget ) )
            return true;
      const QRect& r = mOpt->rect;
      const QColor color = mOpt->palette.color( widget->window()->backgroundRole() );

      const bool hasAlpha( _helper.hasAlphaChannel( widget ) );
      if ( hasAlpha ) {
            painter->setCompositionMode(QPainter::CompositionMode_Source );
            TileSet* tileSet( _helper.roundCorner(color) );
            tileSet->render( r, painter );

            painter->setCompositionMode(QPainter::CompositionMode_SourceOver );
            painter->setClipRegion( _helper.roundedMask( r.adjusted( 1, 1, -1, -1 ) ), Qt::IntersectClip );
            }

      _helper.renderMenuBackground( painter, r, widget, mOpt->palette );

      if ( hasAlpha )
            painter->setClipping( false );
      _helper.drawFloatFrame( painter, r, color, !hasAlpha );
      return true;
      }

bool MgStyle::drawPanelScrollAreaCornerPrimitive( const QStyleOption*, QPainter*, const QWidget* widget) const {
      // disable painting of PE_PanelScrollAreaCorner
      // the default implementation fills the rect with the window background color
      // which does not work for windows that have gradients.
      // unfortunately, this does not work when scrollbars are children of QWebView,
      // in which case, false is returned, in order to fall back to the parent style implementation
      if(!widget)
            widget = QApplication::activeWindow();

      return !( widget && widget->inherits( "QWebView" ) );
      }

bool MgStyle::drawIndicatorBranchPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const {
      const State& flags( option->state );
      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      const QPoint center( r.center() );

      const bool reverseLayout( option->direction == Qt::RightToLeft );

      const int centerX = center.x();
      const int centerY = center.y();

      int expanderAdjust = 0;

      //draw expander
      if (flags & State_Children) {

            int sizeLimit = qMin( qMin(r.width(), r.height() ), (int) Tree_MaxExpanderSize );
            const bool expanderOpen( flags & State_Open );

            // make sure size limit is odd
            if ( !(sizeLimit & 1) ) --sizeLimit;
            expanderAdjust = sizeLimit / 2 + 1;


            QRect expanderRect = centerRect( r, sizeLimit, sizeLimit );
            const int radius( (expanderRect.width() - 4) / 2 );

            // flags
            const bool enabled( flags & State_Enabled );
            const bool mouseOver(enabled && (flags & State_MouseOver));

            // color
            const QColor expanderColor( mouseOver ? _helper.viewHoverBrush().brush(palette).color() : palette.color( QPalette::Text ) );

            if (!MgStyleConfigData_viewDrawTriangularExpander) {

                  // plus or minus sign used for expanders
                  painter->save();
                  painter->setPen( expanderColor );
                  painter->drawLine( center - QPoint( radius, 0 ), center + QPoint( radius, 0 ) );

                  if ( !expanderOpen ) {
                        painter->drawLine( center - QPoint( 0, radius ), center + QPoint( 0, radius ) );
                        }

                  painter->restore();

                  }
            else {

                  // arrows
                  painter->save();
                  painter->translate( center );

                  // get size from option
                  QPolygonF a;
                  ArrowSize size = ArrowSmall;
                  size = MgStyleConfigData_viewTriangularExpanderSize;

                  if ( expanderOpen ) {

                        painter->translate( 0, 0.5 );
                        a = genericArrow( ArrowDown, size );

                        }
                  else {

                        painter->translate( 0.5, 0 );
                        a = genericArrow( reverseLayout ? ArrowLeft : ArrowRight, size );

                        }

                  const qreal penThickness( 1.2 );

                  painter->setPen( QPen( expanderColor, penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                  painter->setRenderHint(QPainter::Antialiasing);
                  painter->drawPolyline( a );
                  painter->restore();
                  }

            }


      // tree branches
      if ( !MgStyleConfigData_viewDrawTreeBranchLines) return true;

      painter->setPen( ColorUtils::mix( palette.color( QPalette::Text ), palette.color( QPalette::Background ), 0.8 ) );
      if (flags & (State_Item | State_Children | State_Sibling)) {
            const QLine line( QPoint( centerX, r.top() ), QPoint( centerX, centerY - expanderAdjust ) );
            painter->drawLine( line );
            }

      //The right/left (depending on dir) line gets drawn if we have an item
      if (flags & State_Item) {
            const QLine line = reverseLayout ?
                               QLine( QPoint( r.left(), centerY ), QPoint( centerX - expanderAdjust, centerY ) ) :
                               QLine( QPoint( centerX + expanderAdjust, centerY ), QPoint( r.right(), centerY ) );
            painter->drawLine( line );

            }

      //The bottom if we have a sibling
      if (flags & State_Sibling) {
            const QLine line( QPoint( centerX, centerY + expanderAdjust ), QPoint( centerX, r.bottom()) );
            painter->drawLine( line );
            }

      return true;
      }

bool MgStyle::drawIndicatorButtonDropDownPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      const QPalette& palette( option->palette );
      const QRect& r( option->rect );
      const State& flags( option->state );

      const bool enabled( flags & State_Enabled );
      const bool mouseOver(enabled && (flags & State_MouseOver));
      const bool reverseLayout( option->direction == Qt::RightToLeft );
      const bool autoRaise( flags & State_AutoRaise );
      const bool sunken(enabled && (flags & State_Sunken));

      if(!widget)
            widget = QApplication::activeWindow();

      // match button color to window background
      const QToolButton* tool( qobject_cast<const QToolButton*>(widget) );
      const QColor highlight( _helper.viewHoverBrush().brush( palette ).color() );
      QColor color = palette.color( autoRaise ? QPalette::WindowText : QPalette::ButtonText );
      QColor background = palette.color( QPalette::Window );
      StyleOptions opts = 0;

      // define gradient and polygon for drawing arrow
      QPolygonF a = genericArrow( ArrowDown, ArrowNormal );

      qreal penThickness = 1.6;
      bool drawContrast = true;

      // toolbuttons
      if ( tool->popupMode() == QToolButton::MenuButtonPopup ) {

            if (!autoRaise) {

                  const bool hasFocus(enabled && (flags & State_HasFocus));

                  // handle animations
                  // mouseOver has precedence over focus
                  animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
                  animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );

                  const bool hoverAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationHover ) );
                  const bool focusAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) );

                  const qreal hoverOpacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
                  const qreal focusOpacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );

                  color = palette.color( QPalette::ButtonText );
                  background = _helper.backgroundColor( palette.color( QPalette::Button ), widget, r.center() );

                  if ( hasFocus ) opts |= Focus;
                  if ( mouseOver ) opts |= Hover;

                  // adjust opacity and animation mode
                  qreal opacity( -1 );
                  AnimationMode mode( AnimationNone );
                  if ( enabled && hoverAnimated ) {

                        opacity = hoverOpacity;
                        mode = AnimationHover;

                        }
                  else if ( enabled && !hasFocus && focusAnimated ) {

                        opacity = focusOpacity;
                        mode = AnimationFocus;

                        }

                  // paint frame
                  painter->save();
                  if ( reverseLayout ) {

                        QRect frameRect( r.adjusted( 0, 0, 10, 0 ) );
                        if ( flags & (State_On | State_Sunken) ) {
                              frameRect.adjust( 0, 0, -1, -1 );
                              opts |= Sunken;
                              }

                        painter->setClipRect( frameRect.adjusted( 0, 0, -8, 0 ), Qt::IntersectClip );
                        renderButtonSlab( painter, frameRect, background, opts, opacity, mode, TileSet::Bottom | TileSet::Top | TileSet::Left );

                        }
                  else {


                        QRect frameRect( r.adjusted(-10, 0, 0, 0) );
                        if ( flags & (State_On | State_Sunken) ) {
                              frameRect.adjust( 1, 0, 0, -1 );
                              opts |= Sunken;
                              }

                        painter->setClipRect( frameRect.adjusted( 8, 0, 0, 0 ), Qt::IntersectClip );
                        renderButtonSlab( painter, frameRect, background, opts, opacity, mode, TileSet::Bottom | TileSet::Top | TileSet::Right );

                        }

                  painter->restore();

                  // draw separating vertical line
                  const QColor color( palette.color(QPalette::Window) );
                  QColor light = _helper.alphaColor( _helper.calcLightColor(color), 0.6 );
                  QColor dark = _helper.calcDarkColor(color);
                  dark.setAlpha(200);

                  int yTop( r.top() + 2 );
                  if ( sunken ) yTop += 1;

                  const int yBottom( r.bottom() - 4 );
                  painter->setPen(QPen(light, 1));

                  if ( reverseLayout ) {

                        painter->drawLine(r.right() + 5, yTop + 1, r.right() + 5, yBottom);
                        painter->drawLine(r.right() + 3, yTop + 2, r.right() + 3, yBottom);
                        painter->setPen(QPen(dark, 1));
                        painter->drawLine(r.right() + 4, yTop, r.right() + 4, yBottom);

                        a.translate( 3, 1 );

                        }
                  else {

                        painter->drawLine(r.x() - 5, yTop + 1, r.x() - 5, yBottom - 1);
                        painter->drawLine(r.x() - 3, yTop + 1, r.x() - 3, yBottom - 1);
                        painter->setPen(QPen(dark, 1));
                        painter->drawLine(r.x() - 4, yTop, r.x() - 4, yBottom);

                        a.translate(-3, 1);

                        }

                  }

            // handle arrow over animation
            if ( const QStyleOptionToolButton* tbOption = qstyleoption_cast<const QStyleOptionToolButton*>(option) ) {

                  const bool arrowHover( enabled && mouseOver && (tbOption->activeSubControls & SC_ToolButtonMenu));
                  animations().toolButtonEngine().updateState( widget, AnimationHover, arrowHover );

                  const bool animated( enabled && animations().toolButtonEngine().isAnimated( widget, AnimationHover ) );
                  const qreal opacity( animations().toolButtonEngine().opacity( widget, AnimationHover) );

                  if ( animated ) color = ColorUtils::mix( color, highlight, opacity );
                  else if ( arrowHover ) color = highlight;
                  else color = palette.color( autoRaise ? QPalette::WindowText : QPalette::ButtonText );

                  }

            }
      else {

            // toolbutton animation
            // when the arrow is painted directly on the icon, button hover and arrow hover
            // are identical. The generic widget engine is used.
            animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
            const bool animated( animations().widgetStateEngine().isAnimated( widget, AnimationHover ) );
            const qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );

            if ( animated ) color = ColorUtils::mix( color, highlight, opacity );
            else if ( mouseOver ) color = highlight;
            else color = palette.color( autoRaise ? QPalette::WindowText : QPalette::ButtonText );

            // smaller down arrow for menu indication on toolbuttons
            penThickness = 1.4;
            a = genericArrow( ArrowDown, ArrowSmall );

            }

      painter->translate( r.center() );
      painter->setRenderHint(QPainter::Antialiasing);

      // white reflection
      if ( drawContrast ) {

            const qreal offset( qMin( penThickness, qreal(1.0)) );
            painter->translate(0, offset);
            painter->setPen(QPen(_helper.calcLightColor( background ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            painter->drawPolyline(a);
            painter->translate(0, -offset);

            }

      painter->setPen(QPen( _helper.decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
      painter->drawPolyline(a);

      return true;

      }
bool MgStyle::drawIndicatorCheckBoxPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      const QRect& r( option->rect );
      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );
      const bool mouseOver(enabled && (flags & State_MouseOver));
      const bool hasFocus( flags & State_HasFocus );

      StyleOptions opts(0);
      if ( !enabled ) opts |= Disabled;
      if ( mouseOver ) opts |= Hover;
      if ( hasFocus ) opts |= Focus;

      // get checkbox state
      CheckBoxState state;
      if ( flags & State_NoChange ) state = CheckTriState;
      else if ( flags & State_On ) state = CheckOn;
      else state = CheckOff;

      if(!widget)
            widget = QApplication::activeWindow();

      // match button color to window background
      QPalette palette( option->palette );
      palette.setColor(
            QPalette::Button,
            _helper.backgroundColor(
                  palette.color( QPalette::Button ), widget, r.center() ) );

      // mouseOver has precedence over focus
      animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
      animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );

      if ( enabled && animations().widgetStateEngine().isAnimated( widget, AnimationHover ) ) {

            const qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
            renderCheckBox( painter, r, palette, opts, state, opacity, AnimationHover );

            }
      else if ( enabled && !hasFocus && animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) ) {

            const qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );
            renderCheckBox( painter, r, palette, opts, state, opacity, AnimationFocus );

            }
      else renderCheckBox( painter, r, palette, opts, state);

      return true;
      }

//---------------------------------------------------------
//   drawIndicatorRadioButtonPrimitive
//---------------------------------------------------------

bool MgStyle::drawIndicatorRadioButtonPrimitive(const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      const QRect& r( option->rect );
      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );
      const bool mouseOver(enabled && (flags & State_MouseOver));
      const bool hasFocus( flags & State_HasFocus );

      StyleOptions opts(0);
      if ( !enabled ) opts |= Disabled;
      if ( mouseOver ) opts |= Hover;
      if ( hasFocus ) opts |= Focus;

      if(!widget)
            widget = QApplication::activeWindow();

      // match button color to window background
      QPalette palette( option->palette );
      palette.setColor( QPalette::Button, _helper.backgroundColor( palette.color( QPalette::Button ), widget, r.center() ) );

      // mouseOver has precedence over focus
      animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
      animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );

      const CheckBoxState state( ( flags & State_On ) ? CheckOn : CheckOff );
      if ( enabled && animations().widgetStateEngine().isAnimated( widget, AnimationHover ) ) {

            const qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
            renderRadioButton( painter, r, palette, opts, state, opacity, AnimationHover );

            }
      else if (  enabled && animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) ) {

            const qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );
            renderRadioButton( painter, r, palette, opts, state, opacity, AnimationFocus );

            }
      else renderRadioButton( painter, r, palette, opts, state );

      return true;
      }

bool MgStyle::drawIndicatorTabTearPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {
      const QStyleOptionTab* tabOpt( qstyleoption_cast<const QStyleOptionTab*>(option) );
      if (!tabOpt)
            return true;

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      const bool reverseLayout( option->direction == Qt::RightToLeft );

      // in fact with current version of Qt (4.6.0) the cast fails and document mode is always false
      // this will hopefully be fixed in later versions
      const QStyleOptionTabV3* tabOptV3( qstyleoption_cast<const QStyleOptionTabV3*>(option) );
      bool documentMode( tabOptV3 ? tabOptV3->documentMode : false );

      if(!widget)
            widget = QApplication::activeWindow();

      const QTabWidget* tabWidget = (widget && widget->parentWidget()) ? qobject_cast<const QTabWidget*>(widget->parentWidget()) : NULL;
      documentMode |= (tabWidget ? tabWidget->documentMode() : true );

      QRect gradientRect(r);
      switch ( tabOpt->shape ) {

            case QTabBar::TriangularNorth:
            case QTabBar::RoundedNorth:
                  gradientRect.adjust( 0, 0, 0, -5 );
                  if ( !reverseLayout ) gradientRect.translate(-GlowWidth, 0);
                  break;

            case QTabBar::TriangularSouth:
            case QTabBar::RoundedSouth:
                  gradientRect.adjust( 0, 5, 0, 0 );
                  if ( !reverseLayout ) gradientRect.translate(-GlowWidth, 0);
                  break;

            case QTabBar::TriangularWest:
            case QTabBar::RoundedWest:
                  gradientRect.adjust( 0, 0, -5, 0 );
                  gradientRect.translate(0, -GlowWidth);
                  break;

            case QTabBar::TriangularEast:
            case QTabBar::RoundedEast:
                  gradientRect.adjust( 5, 0, 0, 0 );
                  gradientRect.translate(0, -GlowWidth);
                  break;

            default:
                  return true;
            }

      // fade tabbar
      QPixmap pm(gradientRect.size());
      pm.fill(Qt::transparent);
      QPainter pp(&pm);

      const bool verticalTabs( isVerticalTab( tabOpt ) );

      int w = 0, h = 0;
      if ( verticalTabs ) h = gradientRect.height();
      else w = gradientRect.width();

      QLinearGradient grad;
      if ( reverseLayout && !verticalTabs ) grad = QLinearGradient( 0, 0, w, h );
      else grad = QLinearGradient(w, h, 0, 0);

      grad.setColorAt(0, Qt::transparent );
      grad.setColorAt(0.6, Qt::black);

      _helper.renderWindowBackground( &pp, pm.rect(), widget, palette );
      pp.setCompositionMode(QPainter::CompositionMode_DestinationAtop);
      pp.fillRect(pm.rect(), QBrush(grad));
      pp.end();

      // draw pixmap
      painter->drawPixmap(gradientRect.topLeft() + QPoint(0, -1), pm);

      return true;
      }

bool MgStyle::drawIndicatorToolBarHandlePrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const {
      const State& flags( option->state );
      const bool horizontal( flags & State_Horizontal );
      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      int counter(1);

      if ( horizontal ) {

            const int center( r.left() + r.width() / 2 );
            for ( int j = r.top() + 2; j <= r.bottom() - 3; j += 3, ++counter ) {
                  if (counter % 2 == 0) _helper.renderDot( painter, QPoint(center + 1, j), palette.color(QPalette::Background));
                  else _helper.renderDot( painter, QPoint(center - 2, j), palette.color(QPalette::Background));
                  }

            }
      else {

            const int center( r.top() + r.height() / 2 );
            for ( int j = r.left() + 2; j <= r.right() - 3; j += 3, ++counter ) {
                  if (counter % 2 == 0) _helper.renderDot( painter, QPoint(j, center + 1), palette.color(QPalette::Background));
                  else _helper.renderDot( painter, QPoint(j, center - 2), palette.color(QPalette::Background));
                  }
            }

      return true;

      }

bool MgStyle::drawIndicatorToolBarSeparatorPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const {
      const State& flags( option->state );
      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      if ( MgStyleConfigData_toolBarDrawItemSeparator ) {
            const QColor color( palette.color(QPalette::Window) );
            if (flags & State_Horizontal) _helper.drawSeparator( painter, r, color, Qt::Vertical );
            else _helper.drawSeparator( painter, r, color, Qt::Horizontal );
            }

      return true;
      }

//---------------------------------------------------------
//   drawWidgetPrimitive
//---------------------------------------------------------

bool MgStyle::drawWidgetPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      // check widget and attributes
      if(!widget)
            widget = QApplication::activeWindow();

      if (!widget || !widget->testAttribute(Qt::WA_StyledBackground) || widget->testAttribute(Qt::WA_NoSystemBackground))
            return false;
      if (!((widget->windowFlags() & Qt::WindowType_Mask) & (Qt::Window | Qt::Dialog)))
            return false;
      if (!widget->isWindow())
            return false;
      // normal "window" background
      _helper.renderWindowBackground(painter, option->rect, widget, option->palette);
      return true;
      }

void MgStyle::renderSplitter( const QStyleOption* option, QPainter* painter, const QWidget* widget, bool horizontal ) const {

      const QPalette& palette( option->palette );
      const QRect& r( option->rect );
      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );
      const bool mouseOver(enabled && (flags & (State_MouseOver | State_Sunken) ));

      // get orientation
      const Qt::Orientation orientation( horizontal ? Qt::Horizontal : Qt::Vertical );

      bool animated( false );
      qreal opacity( AnimationData::OpacityInvalid );

      if(!widget)
            widget = QApplication::activeWindow();

      if ( enabled ) {
            if ( qobject_cast<const QMainWindow*>( widget ) ) {

                  animations().dockSeparatorEngine().updateRect( widget, r, orientation, mouseOver );
                  animated = animations().dockSeparatorEngine().isAnimated( widget, r, orientation );
                  opacity = animated ? animations().dockSeparatorEngine().opacity( widget, orientation ) : AnimationData::OpacityInvalid;

                  }
            else if (  QPaintDevice* device = painter->device() ) {

                  /*
                  try update QSplitterHandle using painter device, because Qt passes
                  QSplitter as the widget to the QStyle primitive.
                  */
                  animations().splitterEngine().updateState( device, mouseOver );
                  animated = animations().splitterEngine().isAnimated( device );
                  opacity = animations().splitterEngine().opacity( device );

                  }
            }

      // get base color
      const QColor color = palette.color(QPalette::Background);

      if ( horizontal ) {
            const int h = r.height();

            if ( animated || mouseOver ) {
                  QColor highlight = _helper.alphaColor(_helper.calcLightColor(color), 0.5 * ( animated ? opacity : 1.0 ) );
                  qreal a( r.height() > 30 ? 10.0 / r.height() : 0.1 );
                  QLinearGradient lg( 0, r.top(), 0, r.bottom() );
                  lg.setColorAt(0, Qt::transparent );
                  lg.setColorAt(a, highlight );
                  lg.setColorAt(1.0 - a, highlight );
                  lg.setColorAt(1, Qt::transparent );
                  painter->fillRect( r, lg );
                  }

            const int ngroups( qMax(1, h / 250) );
            int center( (h - (ngroups - 1) * 250) / 2 + r.top() );
            for (int k = 0; k < ngroups; k++, center += 250) {
                  _helper.renderDot( painter, QPoint(r.left() + 1, center - 3), color);
                  _helper.renderDot( painter, QPoint(r.left() + 1, center), color);
                  _helper.renderDot( painter, QPoint(r.left() + 1, center + 3), color);
                  }

            }
      else {

            const int w( r.width() );
            if ( animated || mouseOver ) {
                  const QColor highlight( _helper.alphaColor(_helper.calcLightColor(color), 0.5 * ( animated ? opacity : 1.0 ) ) );
                  const qreal a( r.width() > 30 ? 10.0 / r.width() : 0.1 );
                  QLinearGradient lg( r.left(), 0, r.right(), 0 );
                  lg.setColorAt(0, Qt::transparent );
                  lg.setColorAt(a, highlight );
                  lg.setColorAt(1.0 - a, highlight );
                  lg.setColorAt(1, Qt::transparent );
                  painter->fillRect( r, lg );

                  }

            int ngroups = qMax(1, w / 250);
            int center = (w - (ngroups - 1) * 250) / 2 + r.left();
            for (int k = 0; k < ngroups; k++, center += 250) {
                  _helper.renderDot( painter, QPoint(center - 3, r.top() + 1), color);
                  _helper.renderDot( painter, QPoint(center, r.top() + 1), color);
                  _helper.renderDot( painter, QPoint(center + 3, r.top() + 1), color);
                  }

            }

      }

//---------------------------------------------------------
//   renderRadioButton
//---------------------------------------------------------

void MgStyle::renderRadioButton(QPainter* painter, const QRect& rect,
                                const QPalette& palette, StyleOptions options, CheckBoxState state,
                                qreal opacity, AnimationMode mode) const {
      const int s( CheckBox_Size );
      const QRect r( centerRect(rect, s, s) );
      const int x = r.x();
      const int y = r.y();

      const QColor color( palette.color(QPalette::Button) );
      const QColor glow( slabShadowColor( color, options, opacity, mode ) );

      QPixmap slabPixmap = glow.isValid() ? _helper.roundSlabFocused( color, glow, 0.0 ) : _helper.roundSlab( color, 0.0 );
      painter->drawPixmap(x, y, slabPixmap);

      // draw the radio mark
      if (state == CheckOn) {
            const qreal radius( 2.6 );
            const qreal dx( 0.5 * r.width() - radius );
            const qreal dy( 0.5 * r.height() - radius );

            painter->save();
            painter->setRenderHints(QPainter::Antialiasing);
            painter->setPen(Qt::NoPen);

            const QColor background( palette.color( QPalette::Button ) );
            const QColor color( palette.color(QPalette::ButtonText) );

            painter->setBrush( _helper.calcLightColor( background ) );
            painter->translate( 0, radius / 2 );
            painter->drawEllipse( QRectF(r).adjusted(dx, dy, -dx, -dy) );

            painter->setBrush( _helper.decoColor( background, color ) );
            painter->translate( 0, -radius / 2 );
            painter->drawEllipse( QRectF(r).adjusted(dx, dy, -dx, -dy ) );
            painter->restore();
            }
      }

//---------------------------------------------------------
//   slabShadowColor
//---------------------------------------------------------

QColor MgStyle::slabShadowColor(QColor color, StyleOptions options, qreal opacity, AnimationMode mode) const {
      QColor glow;
      if ( mode == AnimationNone || opacity < 0 ) {
            if ( options & Hover )
                  glow = _helper.viewHoverBrush().brush(QPalette::Active).color();
            else if ( options & Focus )
                  glow = _helper.viewFocusBrush().brush(QPalette::Active).color();
            else if ( (options & SubtleShadow) && color.isValid() )
                  glow = _helper.alphaColor(_helper.calcShadowColor(color), 0.15 );
            }
      else if ( mode == AnimationHover ) {
            // animated color, hover
            if ( options & Focus )
                  glow = _helper.viewFocusBrush().brush(QPalette::Active).color();
            else if ( (options & SubtleShadow) && color.isValid() )
                  glow = _helper.alphaColor(_helper.calcShadowColor(color), 0.15 );
            if ( glow.isValid() )
                  glow = ColorUtils::mix( glow,  _helper.viewHoverBrush().brush(QPalette::Active).color(), opacity );
            else
                  glow = _helper.alphaColor(  _helper.viewHoverBrush().brush(QPalette::Active).color(), opacity );
            }
      else if ( mode == AnimationFocus ) {
            if ( options & Hover )
                  glow = _helper.viewHoverBrush().brush(QPalette::Active).color();
            else if ( (options & SubtleShadow) && color.isValid() )
                  glow = _helper.alphaColor(_helper.calcShadowColor(color), 0.15 );
            if ( glow.isValid() )
                  glow = ColorUtils::mix( glow,  _helper.viewFocusBrush().brush(QPalette::Active).color(), opacity );
            else
                  glow = _helper.alphaColor(  _helper.viewFocusBrush().brush(QPalette::Active).color(), opacity );
            }
      return glow;
      }

void MgStyle::renderCheckBox(
      QPainter* painter, const QRect& rect, const QPalette& palette,
      StyleOptions options, CheckBoxState state,
      qreal opacity,
      AnimationMode mode ) const {

      const int s( qMin(rect.width(), rect.height()) );
      //const int s( CheckBox_Size );
      const QRect r( centerRect(rect, s, s) );

      if ( options & Sunken ) _helper.holeFlat( palette.color(QPalette::Window), 0.0 )->render( r, painter, TileSet::Full );
      else renderSlab( painter, r, palette.color(QPalette::Button), options, opacity, mode, TileSet::Ring );

      // check mark
      const qreal x( r.center().x() - 3.5 );
      const qreal y( r.center().y() - 2.5 );

      if ( state != CheckOff) {

            qreal penThickness( 2.0 );
            const QColor color( (options & Sunken) ? palette.color(QPalette::WindowText) : palette.color(QPalette::ButtonText) );
            const QColor background( (options & Sunken) ? palette.color(QPalette::Window) : palette.color(QPalette::Button) );
            QPen pen( _helper.decoColor( background, color ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
            QPen contrastPen( _helper.calcLightColor( background ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);

            pen.setCapStyle(Qt::RoundCap);
            if ( state == CheckTriState) {
                  QVector<qreal> dashes;
                  if ( MgStyleConfigData_checkBoxStyle_CS_CHECK) {

                        dashes << 1.0 << 2.0;
                        penThickness = 1.3;
                        pen.setWidthF(penThickness);
                        contrastPen.setWidthF(penThickness);

                        }
                  else {

                        dashes << 0.4 << 2.0;

                        }
                  pen.setDashPattern(dashes);
                  contrastPen.setDashPattern(dashes);
                  }

            painter->save();
            if ( !(options & Sunken) ) painter->translate(0, -1);
            painter->setRenderHint(QPainter::Antialiasing);

            const qreal offset( qMin( penThickness, qreal(1.0) ) );
            if ( MgStyleConfigData_checkBoxStyle_CS_CHECK) {

                  painter->setPen(contrastPen);
                  painter->translate( 0, offset );
                  painter->drawLine(QPointF(x + 9, y), QPointF(x + 3, y + 7));
                  painter->drawLine(QPointF(x, y + 4), QPointF(x + 3, y + 7));

                  painter->setPen(pen);
                  painter->translate( 0, -offset );
                  painter->drawLine(QPointF(x + 9, y), QPointF(x + 3, y + 7));
                  painter->drawLine(QPointF(x, y + 4), QPointF(x + 3, y + 7));

                  }
            else {

                  if ( options & Sunken ) {

                        painter->setPen(contrastPen);
                        painter->translate( 0, offset );
                        painter->drawLine(QPointF(x + 8, y), QPointF(x + 1, y + 7));
                        painter->drawLine(QPointF(x + 8, y + 7), QPointF(x + 1, y));

                        painter->setPen(pen);
                        painter->translate( 0, -offset );
                        painter->drawLine(QPointF(x + 8, y), QPointF(x + 1, y + 7));
                        painter->drawLine(QPointF(x + 8, y + 7), QPointF(x + 1, y));

                        }
                  else {

                        painter->setPen(contrastPen);
                        painter->translate( 0, offset );
                        painter->drawLine(QPointF(x + 8, y - 1), QPointF(x, y + 7));
                        painter->drawLine(QPointF(x + 8, y + 7), QPointF(x, y - 1));

                        painter->setPen(pen);
                        painter->translate( 0, -offset );
                        painter->drawLine(QPointF(x + 8, y - 1), QPointF(x, y + 7));
                        painter->drawLine(QPointF(x + 8, y + 7), QPointF(x, y - 1));

                        }
                  }
            painter->restore();
            }

      return;

      }

void MgStyle::renderScrollBarHole(
      QPainter* painter, const QRect& r, const QColor& color,
      const Qt::Orientation& orientation, const TileSet::Tiles& tiles) const {

      if ( !r.isValid() ) return;

      // one need to make smaller shadow
      // (notably on the size when rect height is too high)
      const bool smallShadow( r.height() < 10 );
      _helper.scrollHole( color, orientation, smallShadow )->render( r, painter, tiles );

      }

//---------------------------------------------------------
//   renderScrollBarHandle
//---------------------------------------------------------

void MgStyle::renderScrollBarHandle(
      QPainter* painter, const QRect& r, const QPalette& palette,
      const Qt::Orientation& orientation, const bool& hover, const qreal& opacity ) const {

      if ( !r.isValid()) return;

      painter->save();
      painter->setRenderHints(QPainter::Antialiasing);
      const QColor color( palette.color(QPalette::Button) );
      const QColor light( _helper.calcLightColor(color) );
      const QColor mid( _helper.calcMidColor(color) );
      const QColor dark( _helper.calcDarkColor(color) );
      const QColor shadow( _helper.calcShadowColor(color) );
      const bool horizontal( orientation == Qt::Horizontal );

      // draw the hole as background
      const QRect holeRect( horizontal ? r.adjusted(-4, 0, 4, 0) : r.adjusted(0, -3, 0, 4) );
      renderScrollBarHole( painter, holeRect, palette.color(QPalette::Window), orientation, horizontal ? TileSet::Vertical : TileSet::Horizontal );

      // draw the slider itself
      QRectF rect( horizontal ? r.adjusted(3, 2, -3, -3) : r.adjusted(3, 4, -3, -3) );

      if ( !rect.isValid()) {
            // e.g. not enough height
            painter->restore();
            return;
            }

      // draw the slider
      QColor glowColor;
      if ( !MgStyleConfigData_scrollBarColored) {
            QColor base = ColorUtils::mix(dark, shadow, 0.5);
            QColor hovered = _helper.viewHoverBrush().brush(QPalette::Active).color();

            if ( opacity >= 0 ) glowColor = ColorUtils::mix( base, hovered, opacity );
            else if ( hover ) glowColor = hovered;
            else glowColor = base;

            }
      else {

            glowColor = ColorUtils::mix(dark, shadow, 0.5);

            }

      // glow / shadow
      painter->setPen(Qt::NoPen);
      painter->setBrush(_helper.alphaColor(glowColor, 0.6));
      painter->drawRoundedRect(rect.adjusted(-0.8, -0.8, 0.8, 0.8), 3, 3);
      painter->setPen(QPen( _helper.alphaColor(glowColor, 0.3),  1.5));
      if ( horizontal) painter->drawRoundedRect(rect.adjusted(-1.2, -0.8, 1.2, 0.8), 3, 3);
      else painter->drawRoundedRect(rect.adjusted(-0.8, -1.2, 0.8, 1.2), 3, 3);

      // colored background
      painter->setPen(Qt::NoPen);
      if ( MgStyleConfigData_scrollBarColored) {

            if ( opacity >= 0 ) painter->setBrush( ColorUtils::mix( color, palette.color(QPalette::Highlight), opacity ) );
            else if ( hover ) painter->setBrush(  palette.color(QPalette::Highlight) );
            else painter->setBrush( color );
            painter->drawRoundedRect(rect, 2, 2);

            }

      // slider gradient
            {
            QLinearGradient sliderGradient( rect.topLeft(), horizontal ? rect.bottomLeft() : rect.topRight());
            if ( !MgStyleConfigData_scrollBarColored) {
                  sliderGradient.setColorAt(0.0, color);
                  sliderGradient.setColorAt(1.0, mid);
                  }
            else {
                  sliderGradient.setColorAt(0.0, _helper.alphaColor( light, 0.6 ));
                  sliderGradient.setColorAt(0.3, _helper.alphaColor( dark, 0.3 ));
                  sliderGradient.setColorAt(1.0, _helper.alphaColor( light, 0.8 ));
                  }

            painter->setBrush(sliderGradient);
            painter->drawRoundedRect(rect, 2, 2);
            }

      // pattern
      if ( MgStyleConfigData_scrollBarBevel ) {
            // don't let the pattern move
            QPoint offset = horizontal ? QPoint(-rect.left(), 0) : QPoint(0, -rect.top());
            QPoint periodEnd = offset + (horizontal ? QPoint(30, 0) : QPoint(0, 30));
            QLinearGradient patternGradient(rect.topLeft() + offset, rect.topLeft() + periodEnd);
            if ( !MgStyleConfigData_scrollBarColored) {
                  patternGradient.setColorAt(0.0, _helper.alphaColor(shadow, 0.1));
                  patternGradient.setColorAt(1.0, _helper.alphaColor(light, 0.1));
                  }
            else {
                  patternGradient.setColorAt(0.0, _helper.alphaColor(shadow, 0.15));
                  patternGradient.setColorAt(1.0, _helper.alphaColor(light, 0.15));
                  }
            patternGradient.setSpread(QGradient::ReflectSpread);

            painter->setBrush(patternGradient);
            painter->drawRoundedRect(rect, 2, 2);
            }

      if ( MgStyleConfigData_scrollBarColored) {
            painter->restore();
            return;
            }

      // bevel
            {
            QLinearGradient bevelGradient( rect.topLeft(), horizontal ? rect.topRight() : rect.bottomLeft());
            bevelGradient.setColorAt(0.0, Qt::transparent);
            bevelGradient.setColorAt(0.5, light);
            bevelGradient.setColorAt(1.0, Qt::transparent);

            rect.adjust(0.5, 0.5, -0.5, -0.5); // for sharper lines
            painter->setPen(QPen(bevelGradient, 1.0));
            painter->drawLine(rect.topLeft(), horizontal ? rect.topRight() : rect.bottomLeft());
            painter->drawLine(rect.bottomRight(), horizontal ? rect.bottomLeft() : rect.topRight());
            }

      painter->restore();

      }

//---------------------------------------------------------
//   renderScrollBarArrow
//---------------------------------------------------------

void MgStyle::renderScrollBarArrow(QPainter* painter, const QRect& r, const QColor& color,
                                   const QColor& background, ArrowOrientation orientation) const {
      const qreal penThickness = 1.6;
      QPolygonF a(genericArrow(orientation, ArrowNormal));

      const QColor contrast(_helper.calcLightColor(background));
      const QColor base(_helper.decoColor(background, color));

      painter->save();
      painter->translate( r.center() );
      painter->setRenderHint(QPainter::Antialiasing);

      const qreal offset( qMin( penThickness, qreal(1.0)) );
      painter->translate(0, offset);
      painter->setPen( QPen( contrast, penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
      painter->drawPolyline(a);
      painter->translate(0, -offset);

      painter->setPen(QPen( base, penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
      painter->drawPolyline(a);
      painter->restore();
      }

//______________________________________________________________________________
QColor MgStyle::scrollBarArrowColor( const QStyleOption* option, const SubControl& control, const QWidget* widget ) const {
      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      QColor color( palette.color( QPalette::WindowText ) );

      const bool enabled( option->state & State_Enabled );
      if ( !enabled ) return color;

      if(!widget)
            widget = QApplication::activeWindow();

      const bool hover( animations().scrollBarEngine().isHovered( widget, control ) );
      const bool animated( animations().scrollBarEngine().isAnimated( widget, control ) );
      const qreal opacity( animations().scrollBarEngine().opacity( widget, control ) );

      QPoint position( hover && widget ? widget->mapFromGlobal( QCursor::pos() ) : QPoint( -1, -1 ) );
      if ( hover && r.contains( position ) ) {
            // we need to update the arrow controlRect on fly because there is no
            // way to get it from the styles directly, outside of repaint events
            animations().scrollBarEngine().setSubControlRect( widget, control, r );
            }


      if ( r.intersects(  animations().scrollBarEngine().subControlRect( widget, control ) ) ) {

            QColor highlight = _helper.viewHoverBrush().brush(palette).color();
            if ( animated ) {
                  color = ColorUtils::mix( color, highlight, opacity );

                  }
            else if ( hover ) {

                  color = highlight;

                  }

            }

      return color;

      }

void MgStyle::renderSliderTickmarks( QPainter* painter, const QStyleOptionSlider* option,  const QWidget* widget ) const {

      if(!widget)
            widget = QApplication::activeWindow();

      const int& ticks( option->tickPosition );
      const int available( pixelMetric(PM_SliderSpaceAvailable, option, widget) );
      int interval = option->tickInterval;
      if ( interval < 1 ) interval = option->pageStep;
      if ( interval < 1 ) return;

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );

      const int fudge( pixelMetric(PM_SliderLength, option, widget) / 2 );
      int current( option->minimum );

      // Since there is no subrect for tickmarks do a translation here.
      painter->save();
      painter->translate(r.x(), r.y());

      if ( option->orientation == Qt::Horizontal ) {
            QColor base( _helper.backgroundColor( palette.color( QPalette::Window ), widget, r.center() ) );
            painter->setPen( _helper.calcDarkColor( base ) );
            }

      int tickSize( option->orientation == Qt::Horizontal ? r.height() / 3 : r.width() / 3 );

      while ( current <= option->maximum ) {

            const int position( sliderPositionFromValue(option->minimum, option->maximum, current, available) + fudge );

            // calculate positions
            if ( option->orientation == Qt::Horizontal ) {
                  if ( ticks == QSlider::TicksAbove ) painter->drawLine( position, 0, position, tickSize );
                  else if ( ticks == QSlider::TicksBelow ) painter->drawLine( position, r.height() - tickSize, position, r.height() );
                  else {
                        painter->drawLine( position, 0, position, tickSize );
                        painter->drawLine( position, r.height() - tickSize, position, r.height() );
                        }

                  }
            else {

                  QColor base( _helper.backgroundColor( palette.color( QPalette::Window ), widget, QPoint( r.center().x(), position ) ) );
                  painter->setPen( _helper.calcDarkColor( base ) );

                  if ( ticks == QSlider::TicksAbove ) painter->drawLine( 0, position, tickSize, position );
                  else if ( ticks == QSlider::TicksBelow ) painter->drawLine( r.width() - tickSize, position, r.width(), position );
                  else {
                        painter->drawLine( 0, position, tickSize, position );
                        painter->drawLine( r.width() - tickSize, position, r.width(), position );
                        }
                  }

            // go to next position
            current += interval;

            }

      painter->restore();
      }

//---------------------------------------------------------
//   genericArrow
//---------------------------------------------------------

QPolygonF MgStyle::genericArrow(MgStyle::ArrowOrientation orientation, MgStyle::ArrowSize size) const {
      QPolygonF a;

      switch (orientation) {
            case ArrowUp: {
                  if (size == ArrowTiny)
                        a << QPointF(-1.75, 1.125) << QPointF(0.5, -1.125) << QPointF(2.75, 1.125);
                  else if ( size == ArrowSmall )
                        a << QPointF( -2, 1.5) << QPointF(0.5, -1.5) << QPointF(3, 1.5);
                  else
                        a << QPointF( -3, 2.5) << QPointF(0.5, -1.5) << QPointF(4, 2.5);
                  break;
                  }

            case ArrowDown: {
                  if ( size == ArrowTiny )
                        a << QPointF( -1.75, -1.125 ) << QPointF( 0.5, 1.125 ) << QPointF( 2.75, -1.125 );
                  else if ( size == ArrowSmall )
                        a << QPointF( -2, -1.5) << QPointF(0.5, 1.5) << QPointF(3, -1.5);
                  else
                        a << QPointF( -3, -1.5) << QPointF(0.5, 2.5) << QPointF(4, -1.5);
                  break;
                  }

            case ArrowLeft: {
                  if ( size == ArrowTiny )
                        a << QPointF( 1.125, -1.75 ) << QPointF( -1.125, 0.5 ) << QPointF( 1.125, 2.75 );
                  else if ( size == ArrowSmall )
                        a << QPointF(1.5, -2) << QPointF(-1.5, 0.5) << QPointF(1.5, 3);
                  else
                        a << QPointF(2.5, -3) << QPointF(-1.5, 0.5) << QPointF(2.5, 4);
                  break;
                  }

            case ArrowRight: {
                  if ( size == ArrowTiny )
                        a << QPointF( -1.125, -1.75 ) << QPointF( 1.125, 0.5 ) << QPointF( -1.125, 2.75 );
                  else if ( size == ArrowSmall )
                        a << QPointF(-1.5, -2) << QPointF(1.5, 0.5) << QPointF(-1.5, 3);
                  else
                        a << QPointF(-1.5, -3) << QPointF(2.5, 0.5) << QPointF(-1.5, 4);
                  break;
                  }

            default:
                  break;
            }
      return a;
      }

//---------------------------------------------------------
//   renderDialSlab
//---------------------------------------------------------

void MgStyle::renderDialSlab( QPainter* painter, const QRect& r, const QColor& color, const QStyleOption* option, StyleOptions opts, qreal opacity, AnimationMode mode) const {

      // cast option
      const QStyleOptionSlider* sliderOption( qstyleoption_cast<const QStyleOptionSlider*>( option ) );
      if ( !sliderOption ) return;

      // adjust rect to be square, and centered
      const int dimension( qMin( r.width(), r.height() ) );
      const QRect rect( centerRect( r, dimension, dimension ) );

      // calculate glow color
      const QColor glow( slabShadowColor( color, opts, opacity, mode ) );

      // get main slab
      QPixmap pix( glow.isValid() ? _helper.dialSlabFocused( color, glow, 0.0, dimension ) : _helper.dialSlab( color, 0.0, dimension ));
      const qreal baseOffset( 3.5 );

      const QColor light( _helper.calcLightColor(color) );
      const QColor shadow( _helper.calcShadowColor(color) );

      QPainter p( &pix );
      p.setPen( Qt::NoPen );
      p.setRenderHints(QPainter::Antialiasing);

      // indicator
      qreal angle(0);
      if ( sliderOption->maximum == sliderOption->minimum ) angle = M_PI / 2;
      else {

            const qreal fraction( qreal(sliderOption->sliderValue - sliderOption->minimum) / qreal(sliderOption->maximum - sliderOption->minimum));
            if ( sliderOption->dialWrapping ) angle = 1.5 * M_PI - fraction * 2 * M_PI;
            else  angle = (M_PI * 8 - fraction * 10 * M_PI) / 6;
            }

      QPointF center( pix.rect().center() );
      const int sliderWidth( dimension / 6 );
      const qreal radius( 0.5 * ( dimension - 2 * sliderWidth ) );
      center += QPointF( radius * cos(angle), -radius * sin(angle));

      QRectF sliderRect( 0, 0, sliderWidth, sliderWidth );
      sliderRect.moveCenter( center );

      // outline circle
      const qreal offset( 0.3 );
      QLinearGradient lg( 0, baseOffset, 0, baseOffset + 2 * sliderRect.height() );
      p.setBrush( light );
      p.setPen( Qt::NoPen );
      p.drawEllipse( sliderRect.translated(0, offset) );

      // mask
      p.setPen( Qt::NoPen );
      p.save();
      p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
      p.setBrush(QBrush(Qt::black));
      p.drawEllipse( sliderRect );
      p.restore();

      // shadow
      p.translate( sliderRect.topLeft() );
      _helper.drawInverseShadow( p, shadow.darker(200), 0.0, sliderRect.width(), 0.0 );

      // glow
      if ( glow.isValid() ) _helper.drawInverseGlow( p, glow, 0.0, sliderRect.width(),  sliderRect.width() );

      p.end();

      painter->drawPixmap( rect.topLeft(), pix );

      return;

      }

//---------------------------------------------------------
//   renderButtonSlab
//---------------------------------------------------------

void MgStyle::renderButtonSlab(QPainter* painter, QRect r, const QColor& color,
   StyleOptions options, qreal opacity, AnimationMode mode,
   TileSet::Tiles tiles) const
      {
      if ( (r.width() <= 0) || (r.height() <= 0))
            return;

//WS      r.translate(0, -1);
      if ( !painter->clipRegion().isEmpty() )
            painter->setClipRegion( painter->clipRegion().translated(0, -1) );

      if ( options & Sunken)
            r.adjust( -1, 0, 1, 1 );

      // fill

      if (!(options & NoFill)) {
            painter->save();
            painter->setRenderHint(QPainter::Antialiasing);
            painter->setPen(Qt::NoPen);

            if (_helper.calcShadowColor(color).value() > color.value() && (options & Sunken)) {
                  QLinearGradient innerGradient(0, r.top(), 0, r.bottom() + r.height());
                  innerGradient.setColorAt(0.0, color);
                  innerGradient.setColorAt(1.0, _helper.calcLightColor(color));
                  painter->setBrush(innerGradient);

                  }
            else if (options & Sunken) {
                  QLinearGradient innerGradient(0, r.top() - r.height(), 0, r.bottom());
                  innerGradient.setColorAt(0.0, _helper.calcLightColor(color));
                  innerGradient.setColorAt(1.0, color);
                  painter->setBrush(innerGradient);

                  }
            else {

                  QLinearGradient innerGradient(0, r.top() - 0.2 * r.height(), 0, r.bottom() + 0.4 * r.height() );
                  innerGradient.setColorAt(0.0, _helper.calcLightColor(color));
                  innerGradient.setColorAt(0.6, color );
                  painter->setBrush(innerGradient);
                  }
            _helper.fillSlab(*painter, r);
            painter->restore();
            }

      // edges
      // for slabs, hover takes precedence over focus (other way around for holes)
      // but in any case if the button is sunken we don't show focus nor hover

      TileSet* tile;
      if ( options & Sunken) {
            tile = _helper.slabSunken(color, 0.0);
            }
      else {
            QColor glow = slabShadowColor( color, options, opacity, mode );
            tile = glow.isValid() ? _helper.slabFocused(color, glow, 0.0) : _helper.slab(color, 0.0);
            }
      tile->render(r, painter, tiles);
      }

//---------------------------------------------------------
//   renderSlab
//---------------------------------------------------------

void MgStyle::renderSlab(QPainter* painter, QRect r, const QColor& color, StyleOptions options, qreal opacity,
                         AnimationMode mode, TileSet::Tiles tiles) const {
      // check rect
      if ( !r.isValid() )
            return;

      // this is needed for button vertical alignment
      r.translate(0, -1);
      if (!painter->clipRegion().isEmpty())
            painter->setClipRegion( painter->clipRegion().translated(0, -1));

      // additional adjustment for sunken frames
      if (options & Sunken)
            r.adjust(-1, 0, 1, 2);

      // fill
      if (!(options & NoFill)) {
            painter->save();
            painter->setRenderHint(QPainter::Antialiasing);
            painter->setPen(Qt::NoPen);

            if (_helper.calcShadowColor(color).value() > color.value() && (options & Sunken)) {
                  QLinearGradient innerGradient(0, r.top(), 0, r.bottom() + r.height());
                  innerGradient.setColorAt(0.0, color);
                  innerGradient.setColorAt(1.0, _helper.calcLightColor(color));
                  painter->setBrush(innerGradient);
                  }
            else {
                  QLinearGradient innerGradient(0, r.top() - r.height(), 0, r.bottom());
                  innerGradient.setColorAt(0.0, _helper.calcLightColor(color));
                  innerGradient.setColorAt(1.0, color);
                  painter->setBrush(innerGradient);
                  }
            _helper.fillSlab(*painter, r);
            painter->restore();
            }

      // edges
      // for slabs, hover takes precedence over focus (other way around for holes)
      // but in any case if the button is sunken we don't show focus nor hover

      TileSet* tile = 0;
      if ((options & Sunken) && color.isValid())
            tile = _helper.slabSunken(color, 0.0);
      else {
            // calculate proper glow color based on current settings and opacity
            QColor glow(slabShadowColor(color, options, opacity, mode));
            if (glow.isValid())
                  tile = _helper.slabFocused(color, glow , 0.0);
            else if (color.isValid())
                  tile = _helper.slab(color, 0.0);
            else
                  return;
            }
      // render tileset
      if (tile)
            tile->render(r, painter, tiles);
      }

void MgStyle::fillTabBackground( QPainter* painter, const QRect& r, const QColor& color, QTabBar::Shape shape, const QWidget* widget ) const {
      // filling
      QRect fillRect(r);
      switch ( shape ) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth:
                  fillRect.adjust( 4, 4, -4, -6 );
                  break;

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth:
                  fillRect.adjust( 4, 4, -4, -4 );
                  break;

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest:
                  fillRect.adjust( 4, 3, -5, -5 );
                  break;

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast:
                  fillRect.adjust( 5, 3, -4, -5 );
                  break;

            default:
                  return;

            }

      if ( widget ) _helper.renderWindowBackground( painter, fillRect, widget, color );
      else painter->fillRect( fillRect, color );

      }

void MgStyle::fillTab( QPainter* painter, const QRect& r, const QColor& color, QTabBar::Shape shape, bool active ) const {
      const QColor dark( _helper.calcDarkColor(color) );
#if 0 // yet (?) unused
      const QColor shadow( _helper.calcShadowColor(color) );
#endif
      const QColor light( _helper.calcLightColor(color) );
#if 0 // yet (?) unused
      const QColor hl( _helper.viewFocusBrush().brush(QPalette::Active).color() );
#endif
      const QRect fillRect( r.adjusted(4, 3, -4, -5) );

      QLinearGradient highlight;
      switch ( shape ) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth:
                  highlight = QLinearGradient(fillRect.topLeft(), fillRect.bottomLeft());
                  break;

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth:
                  highlight = QLinearGradient(fillRect.bottomLeft(), fillRect.topLeft());
                  break;

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast:
                  highlight = QLinearGradient(fillRect.topRight(), fillRect.topLeft());
                  break;

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest:
                  highlight = QLinearGradient(fillRect.topLeft(), fillRect.topRight());
                  break;

            default:
                  return;

            }

      if ( active) {

            highlight.setColorAt(0.0, _helper.alphaColor(light, 0.5));
            highlight.setColorAt(0.1, _helper.alphaColor(light, 0.5));
            highlight.setColorAt(0.25, _helper.alphaColor(light, 0.3));
            highlight.setColorAt(0.5, _helper.alphaColor(light, 0.2));
            highlight.setColorAt(0.75, _helper.alphaColor(light, 0.1));
            highlight.setColorAt(0.9, Qt::transparent);

            }
      else {

            // inactive
            highlight.setColorAt(0.0, _helper.alphaColor(light, 0.1));
            highlight.setColorAt(0.4, _helper.alphaColor(dark, 0.5));
            highlight.setColorAt(0.8, _helper.alphaColor(dark, 0.4));
            highlight.setColorAt(0.9, Qt::transparent);

            }

      painter->setRenderHints(QPainter::Antialiasing);
      painter->setPen(Qt::NoPen);

      painter->setBrush(highlight);
      painter->drawRoundedRect( fillRect, 2, 2 );

      }


//---------------------------------------------------------
//   drawControl
//---------------------------------------------------------

void MgStyle::drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      painter->save();

      if(!widget)
            widget = QApplication::activeWindow();

      StyleControl fcn(0);
      if (element == CE_CapacityBar)
            fcn = &MgStyle::drawCapacityBarControl;
      else {
            switch (element) {
                  case CE_ComboBoxLabel:
                        fcn = &MgStyle::drawComboBoxLabelControl;
                        break;
                  case CE_DockWidgetTitle:
                        fcn = &MgStyle::drawDockWidgetTitleControl;
                        break;
                  case CE_HeaderEmptyArea:
                        fcn = &MgStyle::drawHeaderEmptyAreaControl;
                        break;
                  case CE_HeaderLabel:
                        fcn = &MgStyle::drawHeaderLabelControl;
                        break;
                  case CE_HeaderSection:
                        fcn = &MgStyle::drawHeaderSectionControl;
                        break;
                  case CE_MenuBarEmptyArea:
                        fcn = &MgStyle::emptyControl;
                        break;
                  case CE_MenuBarItem:
                        fcn = &MgStyle::drawMenuBarItemControl;
                        break;
                  case CE_MenuItem:
                        fcn = &MgStyle::drawMenuItemControl;
                        break;
                  case CE_ProgressBar:
                        fcn = &MgStyle::drawProgressBarControl;
                        break;
                  case CE_ProgressBarContents:
                        fcn = &MgStyle::drawProgressBarContentsControl;
                        break;
                  case CE_ProgressBarGroove:
                        fcn = &MgStyle::drawProgressBarGrooveControl;
                        break;
                  case CE_ProgressBarLabel:
                        fcn = &MgStyle::drawProgressBarLabelControl;
                        break;

                        /*
                        for CE_PushButtonBevel the only thing that is done is draw the PanelButtonCommand primitive
                        since the prototypes are identical we register the second directly in the control map: fcn = without
                        using an intermediate function
                        */
                  case CE_PushButtonBevel:
                        fcn = &MgStyle::drawPanelButtonCommandPrimitive;
                        break;
                  case CE_PushButtonLabel:
                        fcn = &MgStyle::drawPushButtonLabelControl;
                        break;
                  case CE_RubberBand:
                        fcn = &MgStyle::drawRubberBandControl;
                        break;
                  case CE_ScrollBarSlider:
                        fcn = &MgStyle::drawScrollBarSliderControl;
                        break;
                  case CE_ScrollBarAddLine:
                        fcn = &MgStyle::drawScrollBarAddLineControl;
                        break;
                  case CE_ScrollBarAddPage:
                        fcn = &MgStyle::drawScrollBarAddPageControl;
                        break;
                  case CE_ScrollBarSubLine:
                        fcn = &MgStyle::drawScrollBarSubLineControl;
                        break;
                  case CE_ScrollBarSubPage:
                        fcn = &MgStyle::drawScrollBarSubPageControl;
                        break;
                  case CE_ShapedFrame:
                        fcn = &MgStyle::drawShapedFrameControl;
                        break;
                  case CE_Splitter:
                        fcn = &MgStyle::drawSplitterControl;
                        break;
                  case CE_TabBarTabLabel:
                        fcn = &MgStyle::drawTabBarTabLabelControl;
                        break;
                  case CE_TabBarTabShape:
                        fcn = &MgStyle::drawTabBarTabShapeControl_Single;
                        break;
                  case CE_ToolBar:
                        fcn = &MgStyle::drawToolBarControl;
                        break;
                  case CE_ToolBoxTabLabel:
                        fcn = &MgStyle::drawToolBoxTabLabelControl;
                        break;
                  case CE_ToolBoxTabShape:
                        fcn = &MgStyle::drawToolBoxTabShapeControl;
                        break;
                  case CE_ToolButtonLabel:
                        fcn = &MgStyle::drawToolButtonLabelControl;
                        break;
                  default:
                        break;
                  }
            }
      if (!(fcn && (this->*fcn)(option, painter, widget))) {
            QCommonStyle::drawControl(element, option, painter, widget);
            }
      painter->restore();
      }

//---------------------------------------------------------
//   drawComplexControl
//---------------------------------------------------------

void MgStyle::drawComplexControl(ComplexControl element, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const {
      painter->save();

      if(!widget)
            widget = QApplication::activeWindow();

      StyleComplexControl fcn(0);
      switch (element) {
            case CC_ComboBox:
                  fcn = &MgStyle::drawComboBoxComplexControl;
                  break;
            case CC_Dial:
                  fcn = &MgStyle::drawDialComplexControl;
                  break;
            case CC_GroupBox:
                  fcn = &MgStyle::drawGroupBoxComplexControl;
                  break;
            case CC_Slider:
                  fcn = &MgStyle::drawSliderComplexControl;
                  break;
            case CC_SpinBox:
                  fcn = &MgStyle::drawSpinBoxComplexControl;
                  break;
            case CC_TitleBar:
                  fcn = &MgStyle::drawTitleBarComplexControl;
                  break;
            case CC_ToolButton:
                  fcn = &MgStyle::drawToolButtonComplexControl;
                  break;
            default:
                  break;
            }

      if (!(fcn && (this->*fcn)(option, painter, widget)))
            QCommonStyle::drawComplexControl( element, option, painter, widget);
      painter->restore();
      }

//---------------------------------------------------------
//   drawItemText
//---------------------------------------------------------

void MgStyle::drawItemText(QPainter* painter, const QRect& r, int flags, const QPalette& palette,
                           bool enabled, const QString& text, QPalette::ColorRole textRole ) const {
      if ( (flags & Qt::TextShowMnemonic) || !(flags & Qt::TextHideMnemonic) ) {
            flags &= ~Qt::TextShowMnemonic;
            flags |= _mnemonic;
            }

      if ( animations().widgetEnabilityEngine().enabled() ) {
            /*
            check if painter engine is registered to WidgetEnabilityEngine, and animated
            if yes, merge the palettes. Note: a static_cast is safe here, since only the address
            of the pointer is used, not the actual content.
            */
            const QWidget* widget( static_cast<const QWidget*>( painter->device() ) );
            if (animations().widgetEnabilityEngine().isAnimated( widget, AnimationEnable)) {
                  const QPalette pal = _helper.mergePalettes(palette, animations().widgetEnabilityEngine().opacity(widget, AnimationEnable));
                  return QCommonStyle::drawItemText(painter, r, flags, pal, enabled, text, textRole);
                  }
            }
      return QCommonStyle::drawItemText(painter, r, flags, palette, enabled, text, textRole);
      }

//---------------------------------------------------------
//   eventFilter
//---------------------------------------------------------

bool MgStyle::eventFilter(QObject* object, QEvent* event) {
      if (QTabBar* tabBar = qobject_cast<QTabBar*>(object))
            return eventFilterTabBar( tabBar, event );
      if (QToolBar* toolBar = qobject_cast<QToolBar*>(object))
            return eventFilterToolBar( toolBar, event );
      if (QDockWidget* dockWidget = qobject_cast<QDockWidget*>(object))
            return eventFilterDockWidget(dockWidget, event);
      if (QToolBox* toolBox = qobject_cast<QToolBox*>(object))
            return eventFilterToolBox(toolBox, event);
      if (QMdiSubWindow* subWindow = qobject_cast<QMdiSubWindow*>(object))
            return eventFilterMdiSubWindow(subWindow, event);
      if (QScrollBar* scrollBar = qobject_cast<QScrollBar*>(object))
            return eventFilterScrollBar(scrollBar, event);
      // cast to QWidget
      QWidget* widget = static_cast<QWidget*>(object);

      if (widget->inherits("QComboBoxPrivateContainer"))
            return eventFilterComboBoxContainer(widget, event);
      return QCommonStyle::eventFilter(object, event);
      }

bool MgStyle::drawComboBoxComplexControl(const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const {
      // cast option and check
      const QStyleOptionComboBox* cb( qstyleoption_cast<const QStyleOptionComboBox*>(option) );
      if ( !cb )
            return true;

      const State& flags( option->state );
      const QRect& r(option->rect);
      const QPalette& palette( option->palette);
      const bool enabled(flags & State_Enabled);
      const bool mouseOver(enabled && (flags & State_MouseOver));
      const bool hasFocus( flags & State_HasFocus );
      const bool& editable( cb->editable );
      const bool& hasFrame( cb->frame );

      if(!widget)
            widget = QApplication::activeWindow();

      // frame
      if ( cb->subControls & SC_ComboBoxFrame) {
            // style options
            StyleOptions opts = 0;
            if (mouseOver)
                  opts |= Hover;
            if (hasFocus)
                  opts |= Focus;
            if ((flags & (State_Sunken | State_On)) && !editable)
                  opts |= Sunken;

            const QColor inputColor( enabled ? palette.color(QPalette::Base) : palette.color(QPalette::Window) );
#if 0 // yet (?) unused
            const QRect editField( subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget) );
#endif
            if (editable) {
                  // editable combobox. Make it look like a LineEdit
                  // focus takes precedence over hover
                  animations().lineEditEngine().updateState( widget, AnimationFocus, hasFocus );
                  animations().lineEditEngine().updateState( widget, AnimationHover, mouseOver && !hasFocus );

                  const QRect fr( r.adjusted(1, 1, -1, -1) );

                  // input area
                  painter->save();
                  painter->setRenderHint(QPainter::Antialiasing);
                  painter->setPen(Qt::NoPen);
                  painter->setBrush(inputColor);

                  if ( !hasFrame ) {

                        // adjust rect to match frameLess editors
                        painter->fillRect(r, inputColor);
                        painter->restore();

                        }
                  else {
                        _helper.fillHole( *painter, r.adjusted( 0, -1, 0, 0 ) );
                        painter->restore();

                        const QColor color( palette.color(QPalette::Window) );
                        if ( enabled && animations().lineEditEngine().isAnimated( widget, AnimationFocus ) ) {

                              _helper.renderHole(painter, color, fr, hasFocus, mouseOver, animations().lineEditEngine().opacity( widget, AnimationFocus ), AnimationFocus, TileSet::Ring);

                              }
                        else if ( enabled && animations().lineEditEngine().isAnimated( widget, AnimationHover ) ) {

                              _helper.renderHole(painter, color, fr, hasFocus, mouseOver, animations().lineEditEngine().opacity( widget, AnimationHover ), AnimationHover, TileSet::Ring);

                              }
                        else {
                              _helper.renderHole(painter, color, fr, hasFocus && enabled, mouseOver);
                              }

                        }

                  }
            else {
                  // non editable combobox. Make it look like a PushButton
                  // hover takes precedence over focus

                  animations().lineEditEngine().updateState(widget, AnimationHover, mouseOver );
                  animations().lineEditEngine().updateState(widget, AnimationFocus, hasFocus && !mouseOver);

                  // blend button color to the background
                  const QColor buttonColor(_helper.backgroundColor(palette.color(QPalette::Button), widget, r.center()));
                  // const QRect slabRect(r.adjusted(-1, 0, 1, 0 ));
                  const QRect slabRect(r.adjusted(-1, -1, 1, 1 ));

                  if (!hasFrame) {
                        // do nothing.
                        }
                  else if ( enabled && animations().lineEditEngine().isAnimated( widget, AnimationHover ) ) {

                        const qreal opacity( animations().lineEditEngine().opacity( widget, AnimationHover ) );
                        renderButtonSlab(painter, slabRect, buttonColor, opts, opacity, AnimationHover, TileSet::Ring );

                        }
                  else if ( enabled && animations().lineEditEngine().isAnimated( widget, AnimationFocus ) ) {
                        const qreal opacity( animations().lineEditEngine().opacity( widget, AnimationFocus ) );
                        renderButtonSlab(painter, slabRect, buttonColor, opts, opacity, AnimationFocus, TileSet::Ring );
                        }
                  else {
                        renderButtonSlab(painter, slabRect, buttonColor, opts);
                        }
                  }
            }

      if ( cb->subControls & SC_ComboBoxArrow) {

            const QComboBox* comboBox = qobject_cast<const QComboBox*>( widget );
            const bool empty( comboBox && !comboBox->count() );

            QColor color;
            QColor background;
            bool drawContrast( true );

            if ( cb->editable ) {

                  if ( enabled && empty ) color = palette.color( QPalette::Disabled,  QPalette::Text );
                  else {

                        // check animation state
                        const bool subControlHover( enabled && mouseOver && cb->activeSubControls & SC_ComboBoxArrow );
                        animations().comboBoxEngine().updateState( widget, AnimationHover, subControlHover  );

                        const bool animated( enabled && animations().comboBoxEngine().isAnimated( widget, AnimationHover ) );
                        const qreal opacity( animations().comboBoxEngine().opacity( widget, AnimationHover ) );

                        if ( animated ) {

                              QColor highlight = _helper.viewHoverBrush().brush(palette).color();
                              color = ColorUtils::mix( palette.color( QPalette::Text ), highlight, opacity );

                              }
                        else if ( subControlHover ) {

                              color = _helper.viewHoverBrush().brush(palette).color();

                              }
                        else {

                              color = palette.color( QPalette::Text );

                              }

                        }

                  background = palette.color( QPalette::Background );

                  if ( enabled ) drawContrast = false;

                  }
            else {

                  if ( enabled && empty ) color = palette.color( QPalette::Disabled,  QPalette::ButtonText );
                  else color  = palette.color( QPalette::ButtonText );
                  background = palette.color( QPalette::Button );

                  }

            // draw the arrow
            QRect arrowRect = comboBoxSubControlRect( option, SC_ComboBoxArrow, widget );

            const QPolygonF a( genericArrow( ArrowDown, ArrowNormal ) );
            const qreal penThickness = 1.6;

            painter->save();
            painter->translate( arrowRect.center() );
            painter->setRenderHint(QPainter::Antialiasing);

            if ( drawContrast ) {

                  const qreal offset( qMin( penThickness, qreal(1.0)) );
                  painter->translate(0, offset);
                  painter->setPen( QPen( _helper.calcLightColor( palette.color(QPalette::Window)), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
                  painter->drawPolyline(a);
                  painter->translate(0, -offset);

                  }

            painter->setPen(QPen( _helper.decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            painter->drawPolyline(a);
            painter->restore();

            }

      return true;
      }

bool MgStyle::drawDialComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const {
      const State& flags( option->state );
      const bool enabled = flags & State_Enabled;
      const bool mouseOver(enabled && (flags & State_MouseOver));
      const bool hasFocus( enabled && (flags & State_HasFocus));
      const bool sunken( flags & (State_On | State_Sunken) );

      StyleOptions opts = 0;
      if ( sunken ) opts |= Sunken;
      if ( hasFocus ) opts |= Focus;
      if ( mouseOver ) opts |= Hover;

      if(!widget)
            widget = QApplication::activeWindow();

      // mouseOver has precedence over focus
      animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
      animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );

      const QRect rect( option->rect );
      const QPalette& palette( option->palette );
      const QColor buttonColor( _helper.backgroundColor( palette.color(QPalette::Button), widget, rect.center() ) );

      if ( enabled && animations().widgetStateEngine().isAnimated( widget, AnimationHover ) && !(opts & Sunken ) ) {

            qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationHover ) );
            renderDialSlab( painter, rect, buttonColor, option, opts, opacity, AnimationHover );

            }
      else if ( enabled && !mouseOver && animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) && !(opts & Sunken ) ) {

            qreal opacity( animations().widgetStateEngine().opacity( widget, AnimationFocus ) );
            renderDialSlab( painter, rect, buttonColor, option, opts, opacity, AnimationFocus );

            }
      else {

            renderDialSlab( painter, rect, buttonColor, option, opts);

            }

      return true;

      }

//---------------------------------------------------------
//   drawGroupBoxComplexControl
//---------------------------------------------------------

bool MgStyle::drawGroupBoxComplexControl(const QStyleOptionComplex* /*option*/, QPainter* /*painter*/, const QWidget* /*widget*/) const {
#if 0
      const QStyleOptionGroupBox* groupBox = qstyleoption_cast<const QStyleOptionGroupBox*>(option);
      if (groupBox && groupBox->features & QStyleOptionFrameV2::Flat) {
            // for flat groupboxes, the groupBox title is rendered bold
            /*
            TODO: talk to pinheiro. This is not an optimal design
            I would rather
                  1/ keep the font unchanged
                  2/ add an horizontal separator next to the title
            (Hugo)
            */
            const QFont oldFont = painter->font();
            QFont font = oldFont;
            font.setBold(true);
            painter->setFont(font);
            QCommonStyle::drawComplexControl(CC_GroupBox, option, painter, widget);
            painter->setFont(oldFont);
            return true;
            }
      else
#endif
            return false;
      }

bool MgStyle::drawSliderComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const {
      const QStyleOptionSlider* slider( qstyleoption_cast<const QStyleOptionSlider*>( option ) );
      if ( !slider ) return true;

      const QPalette& palette( option->palette );
      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );
      const bool mouseOver(enabled && (flags & State_MouseOver));
      const bool hasFocus( flags & State_HasFocus );

      if(!widget)
            widget = QApplication::activeWindow();

      if ( slider->subControls & SC_SliderTickmarks ) {
            renderSliderTickmarks( painter, slider, widget );
            }

      // groove
      if ( slider->subControls & SC_SliderGroove ) {
            const QRect groove = sliderSubControlRect( slider, SC_SliderGroove, widget );
            if ( groove.isValid() ) _helper.groove( palette.color(QPalette::Window), 0.0)->render( groove, painter);
            }

      // handle
      if (slider->subControls & SC_SliderHandle) {
            const QRect handle = sliderSubControlRect( slider, SC_SliderHandle, widget );
            const QColor buttonColor( _helper.backgroundColor( palette.color(QPalette::Button), widget, handle.center() ) );
            const bool handleActive( slider->activeSubControls & SC_SliderHandle );
            StyleOptions opts(0);
            if ( hasFocus ) opts |= Focus;

            animations().sliderEngine().updateState( widget, enabled && handleActive );
            if ( enabled &&  animations().sliderEngine().isAnimated( widget ) ) {

                  renderSlab( painter, handle, buttonColor, opts,  animations().sliderEngine().opacity( widget ), AnimationHover, TileSet::Ring );

                  }
            else {

                  if ( handleActive && mouseOver ) opts |= Hover;
                  renderSlab( painter, handle, buttonColor, opts );

                  }
            }

      return true;
      }

bool MgStyle::drawSpinBoxComplexControl(const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const {
      const QStyleOptionSpinBox* sb = qstyleoption_cast<const QStyleOptionSpinBox*>( option );
      if (!sb)
            return true;

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );

      const State& flags( option->state );
      const bool enabled(flags & State_Enabled);
      const bool mouseOver(enabled && (flags & State_MouseOver));
      const bool hasFocus( flags & State_HasFocus );
      const QColor inputColor( palette.color( enabled ? QPalette::Base : QPalette::Window ) );

      if(!widget)
            widget = QApplication::activeWindow();

      if ( sb->subControls & SC_SpinBoxFrame) {

            //WS QRect fr( r.adjusted(1, 1, -1, -1) );
            QRect fr( r.adjusted(1, 0, -1, 0) );
            painter->save();
            painter->setRenderHint(QPainter::Antialiasing);
            painter->setPen(Qt::NoPen);
            painter->setBrush(inputColor);

            if ( !sb->frame ) {
                  // frameless spinbox
                  // frame is adjusted to have the same dimensions as a frameless editor
                  painter->fillRect(r, inputColor);
                  painter->restore();
                  }
            else {
                  // normal spinbox
                  _helper.fillHole(*painter, r.adjusted(0, -1, 0, 0));
                  painter->restore();

                  QColor local( palette.color(QPalette::Window) );
                  if (widget) {
                        animations().lineEditEngine().updateState( widget, AnimationHover, mouseOver );
                        animations().lineEditEngine().updateState( widget, AnimationFocus, hasFocus );

                        if (enabled && animations().lineEditEngine().isAnimated(widget, AnimationFocus))
                              _helper.renderHole(painter, local, fr, hasFocus, mouseOver, animations().lineEditEngine().opacity(widget, AnimationFocus), AnimationFocus, TileSet::Ring);
                        else if (enabled && animations().lineEditEngine().isAnimated(widget, AnimationHover))
                              _helper.renderHole(painter, local, fr, hasFocus, mouseOver, animations().lineEditEngine().opacity(widget, AnimationHover), AnimationHover, TileSet::Ring);
                        else
                              _helper.renderHole(painter, local, fr, hasFocus, mouseOver);
                        }
                  else
                        _helper.renderHole(painter, local, fr, hasFocus, mouseOver);
                  }
            }

      if ( sb->subControls & SC_SpinBoxUp ) renderSpinBoxArrow( painter, sb, widget, SC_SpinBoxUp );
      if ( sb->subControls & SC_SpinBoxDown ) renderSpinBoxArrow( painter, sb, widget, SC_SpinBoxDown );

      return true;

      }

bool MgStyle::drawTitleBarComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const {
      const QStyleOptionTitleBar* tb( qstyleoption_cast<const QStyleOptionTitleBar*>(option) );
      if ( !tb) return true;

      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );
      const bool active( enabled && (tb->titleBarState & Qt::WindowActive ) );

      if(!widget)
            widget = QApplication::activeWindow();

      // draw title text
            {
            QRect textRect = subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, widget);

            // enable state transition
            animations().widgetEnabilityEngine().updateState( widget, AnimationEnable, active );

            // make sure palette has the correct color group
            QPalette palette( option->palette );

            if ( animations().widgetEnabilityEngine().isAnimated( widget, AnimationEnable ) ) {
                  palette = _helper.mergePalettes( palette, animations().widgetEnabilityEngine().opacity( widget, AnimationEnable )  );
                  }

            palette.setCurrentColorGroup( active ? QPalette::Active : QPalette::Disabled );
            QCommonStyle::drawItemText( painter, textRect, Qt::AlignCenter, palette, active, tb->text, QPalette::WindowText);

            }


      // menu button
      if ( (tb->subControls & SC_TitleBarSysMenu) && (tb->titleBarFlags & Qt::WindowSystemMenuHint) && !tb->icon.isNull() ) {

            const QRect br = subControlRect( CC_TitleBar, tb, SC_TitleBarSysMenu, widget );
            tb->icon.paint( painter, br);

            }

      if ( (tb->subControls & SC_TitleBarMinButton) && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) ) {
            renderTitleBarButton( painter, tb, widget, SC_TitleBarMinButton );
            }

      if ( (tb->subControls & SC_TitleBarMaxButton) && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) ) {
            renderTitleBarButton( painter, tb, widget, SC_TitleBarMaxButton );
            }

      if ( (tb->subControls & SC_TitleBarCloseButton) ) {
            renderTitleBarButton( painter, tb, widget, SC_TitleBarCloseButton );
            }

      if ( (tb->subControls & SC_TitleBarNormalButton) &&
                  ( ( ( tb->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
                      ( tb->titleBarState & Qt::WindowMinimized ) ) ||
                    ( ( tb->titleBarFlags & Qt::WindowMaximizeButtonHint ) &&
                      ( tb->titleBarState & Qt::WindowMaximized ) ) ) ) {
            renderTitleBarButton( painter, tb, widget, SC_TitleBarNormalButton );
            }

      if ( tb->subControls & SC_TitleBarShadeButton ) {
            renderTitleBarButton( painter, tb, widget, SC_TitleBarShadeButton );
            }

      if ( tb->subControls & SC_TitleBarUnshadeButton ) {
            renderTitleBarButton( painter, tb, widget, SC_TitleBarUnshadeButton );
            }

      if ( (tb->subControls & SC_TitleBarContextHelpButton) && (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)) {
            renderTitleBarButton( painter, tb, widget, SC_TitleBarContextHelpButton );
            }

      return true;
      }

//---------------------------------------------------------
//   drawToolButtonComplexControl
//---------------------------------------------------------

bool MgStyle::drawToolButtonComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const {
      if(!widget)
            widget = QApplication::activeWindow();

      // check autoRaise state
      const State flags( option->state );
      const bool isInToolBar( widget && qobject_cast<QToolBar*>(widget->parent()) );

      // get rect and palette
      const QRect& rect(option->rect );
      const QStyleOptionToolButton* tool(qstyleoption_cast<const QStyleOptionToolButton*>(option) );
      if (!tool)
            return true;

      const bool enabled( flags & State_Enabled );
      const bool mouseOver(enabled && (flags & State_MouseOver));
      const bool hasFocus(enabled && (flags & State_HasFocus));
      const bool sunken( flags & (State_Sunken | State_On) );

      if ( isInToolBar ) {
            animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
            }
      else {
            // mouseOver has precedence over focus
            animations().widgetStateEngine().updateState( widget, AnimationHover, mouseOver );
            animations().widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver );
            }

      // toolbar animation
      const bool toolBarAnimated( isInToolBar && animations().toolBarEngine().isAnimated( widget->parentWidget() ) );
      const QRect animatedRect( animations().toolBarEngine().animatedRect( widget ? widget->parentWidget() : NULL) );
      const QRect currentRect( animations().toolBarEngine().currentRect( widget ? widget->parentWidget() : NULL) );
      const bool current( isInToolBar && currentRect.intersects( rect.translated( widget->mapToParent( QPoint(0, 0) ) ) ) );
      const bool toolBarTimerActive( isInToolBar && animations().toolBarEngine().isTimerActive( widget->parentWidget() ) );

      // normal toolbutton animation
      const bool hoverAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationHover ) );
      const bool focusAnimated( animations().widgetStateEngine().isAnimated( widget, AnimationFocus ) );

      // local copy of option
      QStyleOptionToolButton tOpt(*tool);

      if ( enabled && !(mouseOver || hasFocus || sunken ) ) {
            if (hoverAnimated || (focusAnimated && !hasFocus) || (((toolBarAnimated && animatedRect.isNull()) || toolBarTimerActive) && current)) {
                  QRect buttonRect = subControlRect(CC_ToolButton, option, SC_ToolButton, widget);
                  tOpt.rect = buttonRect;
                  tOpt.state = flags;
                  drawPrimitive(PE_PanelButtonTool, &tOpt, painter, widget );
                  }
            }

      QRect buttonRect = subControlRect(CC_ToolButton, tool, SC_ToolButton, widget);
      QRect menuRect   = subControlRect(CC_ToolButton, tool, SC_ToolButtonMenu, widget);

      // State_AutoRaise: only draw button when State_MouseOver
      State bflags = tool->state;
      if (bflags & State_AutoRaise && !(bflags & State_MouseOver))
            bflags &= ~State_Raised;

      tOpt.palette = option->palette;
      tOpt.state   = bflags;

      if (tool->subControls & SC_ToolButton && (bflags & (State_Sunken | State_On | State_Raised))) {
            tOpt.rect = buttonRect;
            drawPrimitive(PE_PanelButtonTool, &tOpt, painter, widget );
            }

      if ( tool->subControls & SC_ToolButtonMenu) {
            tOpt.rect = menuRect;
            painter->save();
            drawIndicatorButtonDropDownPrimitive( &tOpt, painter, widget );
            painter->restore();
            }
      else if (tool->features & QStyleOptionToolButton::HasMenu) {
            // This is requesting KDE3-style arrow indicator, per Qt 4.4 behavior. Qt 4.3 prefers to hide
            // the fact of the menu's existence. Whee! Since we don't know how to paint this right,
            // though, we have to have some metrics set for it to look nice.
            const int size( ToolButton_InlineMenuIndicatorSize );
            if ( size) {
                  const int xOff( ToolButton_InlineMenuIndicatorXOff );
                  const int yOff( ToolButton_InlineMenuIndicatorYOff );

                  QRect r = QRect(buttonRect.right() + xOff + 1, buttonRect.bottom() + yOff + 1, size, size);
                  tOpt.rect  = r;
                  painter->save();
                  drawIndicatorButtonDropDownPrimitive( &tOpt, painter, widget );
                  painter->restore();
                  }
            }

      // CE_ToolButtonLabel expects a readjusted rect, for the button area proper
      QStyleOptionToolButton labelOpt = *tool;
      labelOpt.rect = buttonRect;
      drawControl(CE_ToolButtonLabel, &labelOpt, painter, widget );
      return true;
      }

bool MgStyle::eventFilterComboBoxContainer( QWidget* widget, QEvent* event ) {
      if(!widget)
            widget = QApplication::activeWindow();

      switch (event->type()) {

            case QEvent::Show:
            case QEvent::Resize: {
                  if(widget) {
                        if ( !_helper.hasAlphaChannel(widget) ) widget->setMask(_helper.roundedMask( widget->rect() ));
                        else widget->clearMask();
                  }
                  return false;
                  }

            case QEvent::Paint: {

                  QPainter painter(widget);
                  QPaintEvent* paintEvent = static_cast<QPaintEvent*>( event );
                  painter.setClipRegion(paintEvent->region());

                  const QRect r( widget ? widget->rect() : QRect());
                  const QColor color( widget->palette().color( widget->window()->backgroundRole() ) );    // TODO
                  const bool hasAlpha( _helper.hasAlphaChannel( widget ) );

                  if ( hasAlpha ) {

                        TileSet* tileSet( _helper.roundCorner(color) );
                        tileSet->render( r, &painter );
                        painter.setCompositionMode(QPainter::CompositionMode_SourceOver );
                        painter.setClipRegion( _helper.roundedMask( r.adjusted( 1, 1, -1, -1 ) ), Qt::IntersectClip );

                        }

                  // background
                  _helper.renderMenuBackground( &painter, paintEvent->rect(), widget, widget->palette());    // TODO

                  // frame
                  if ( hasAlpha ) painter.setClipping( false );

                  _helper.drawFloatFrame( &painter, r, color, !hasAlpha );
                  return false;

                  }
            default:
                  return false;
            }
      }

//---------------------------------------------------------
//   eventFilterDockWidget
//---------------------------------------------------------

bool MgStyle::eventFilterDockWidget( QDockWidget* dockWidget, QEvent* event ) {
      switch ( event->type() ) {
            case QEvent::Show:
            case QEvent::Resize: {
                  // make sure mask is appropriate
                  if ( dockWidget->isFloating() && !_helper.hasAlphaChannel( dockWidget ) ) {
#ifndef Q_OS_WIN
                        dockWidget->setMask(_helper.roundedMask( dockWidget->rect() ) );
#endif
                        }
                  else
                        dockWidget->clearMask();
                  return false;
                  }

            case QEvent::Paint: {
                  QPainter painter( dockWidget );
                  QPaintEvent* paintEvent = static_cast<QPaintEvent*>( event );
                  painter.setClipRegion(paintEvent->region());

                  const QColor color( dockWidget->palette().color(QPalette::Window) );
                  const QRect r( dockWidget->rect() );
                  if (dockWidget->isWindow()) {
#ifndef Q_OS_WIN
                        bool hasAlpha( _helper.hasAlphaChannel( dockWidget ) );
                        if ( hasAlpha ) {
                              painter.setCompositionMode( QPainter::CompositionMode_Source );
                              TileSet* tileSet( _helper.roundCorner(color) );
                              tileSet->render( r, &painter );
                              // set clip region
                              painter.setCompositionMode( QPainter::CompositionMode_SourceOver);
                              painter.setClipRegion(_helper.roundedMask(r.adjusted(1, 1, -1, -1)), Qt::IntersectClip);
                              }
#endif
                        _helper.renderWindowBackground( &painter, r, dockWidget, color );
#ifndef Q_OS_WIN
                        if ( hasAlpha ) painter.setClipping( false );
                        _helper.drawFloatFrame( &painter, r, color, !hasAlpha );
#endif
                        }
                  else {
                        // need to draw window background for autoFilled dockWidgets for better rendering
                        if ( dockWidget->autoFillBackground() ) {
                              _helper.renderWindowBackground( &painter, r, dockWidget, color );
                              }
                        // adjust color
                        QColor local( _helper.backgroundColor( color, dockWidget, r.center() ) );
                        TileSet* tileSet = _helper.dockFrame( local, r.width() );
                        tileSet->render( r, &painter );
                        }
                  return false;
                  }
            default:
                  return false;
            }
      }


bool MgStyle::eventFilterMdiSubWindow( QMdiSubWindow* subWindow, QEvent* event ) {

      if ( event->type() == QEvent::Paint) {

            QPainter painter(subWindow);
            QRect clip( static_cast<QPaintEvent*>( event )->rect() );
            if ( subWindow->isMaximized() ) _helper.renderWindowBackground(&painter, clip, subWindow, subWindow->palette() );
            else {

                  painter.setClipRect( clip );

                  const QRect r( subWindow->rect() );
                  TileSet* tileSet( _helper.roundCorner( subWindow->palette().color( subWindow->backgroundRole() ) ) );
                  tileSet->render( r, &painter );

                  painter.setClipRegion( _helper.roundedMask( r.adjusted( 1, 1, -1, -1 ) ), Qt::IntersectClip );
                  _helper.renderWindowBackground(&painter, clip, subWindow, subWindow, subWindow->palette(), 0, 58 );

                  }

            }

      // continue with normal painting
      return false;

      }

bool MgStyle::eventFilterScrollBar( QWidget* widget, QEvent* event ) {

      if(!widget)
            widget = QApplication::activeWindow();

      if ( event->type() == QEvent::Paint ) {
            QPainter painter( widget );
            painter.setClipRegion( static_cast<QPaintEvent*>( event )->region() );
            _helper.renderWindowBackground(&painter, widget ? widget->rect() : QRect(), widget, widget ? widget->palette() : QApplication::palette());
            }

      return false;
      }

bool MgStyle::eventFilterTabBar( QWidget* widget, QEvent* event ) {
      if(!widget)
            widget = QApplication::activeWindow();

      if ( event->type() == QEvent::Paint && tabBarData().locks( widget ) ) {
            /*
            this makes sure that tabBar base is drawn (and drawn only once)
            every time a replaint is triggered by dragging a tab around
            */
            tabBarData().setDirty();
            }

      return false;
      }

//_____________________________________________________________________
bool MgStyle::eventFilterToolBar( QToolBar* toolBar, QEvent* event ) {
      switch (event->type()) {
            case QEvent::Show:
            case QEvent::Resize: {
                  // make sure mask is appropriate
                  if ( toolBar->isFloating() && !_helper.hasAlphaChannel( toolBar ) ) {

                        toolBar->setMask(_helper.roundedMask( toolBar->rect() ));

                        }
                  else  toolBar->clearMask();
                  return false;
                  }

            case QEvent::Paint: {

                  QPainter painter( toolBar );
                  QPaintEvent* paintEvent = static_cast<QPaintEvent*>( event );
                  painter.setClipRegion( paintEvent->region() );

                  const QRect r( toolBar->rect() );
                  const QColor color( toolBar->palette().window().color() );

                  // default painting when not qrealing
                  if ( !toolBar->isFloating() ) {

                        // background has to be rendered explicitly
                        // when one of the parent has autofillBackground set to true
                        if ( _helper.checkAutoFillBackground( toolBar ) ) {
                              _helper.renderWindowBackground(&painter, r, toolBar, color);
                              }

                        return false;

                        }

                  const bool hasAlpha( _helper.hasAlphaChannel( toolBar ) );
                  if ( hasAlpha ) {
                        painter.setCompositionMode(QPainter::CompositionMode_Source );
                        TileSet* tileSet( _helper.roundCorner(color) );
                        tileSet->render( r, &painter );

                        painter.setCompositionMode(QPainter::CompositionMode_SourceOver );
                        painter.setClipRegion( _helper.roundedMask( r.adjusted( 1, 1, -1, -1 ) ), Qt::IntersectClip );
                        }

                  // background
                  _helper.renderWindowBackground(&painter, r, toolBar, color);

                  if ( toolBar->isMovable() ) {
                        // remaining painting: need to add handle
                        // this is copied from QToolBar::paintEvent
                        QStyleOptionToolBar opt;
                        opt.initFrom( toolBar );
                        if ( toolBar->orientation() == Qt::Horizontal) {

                              opt.rect = handleRTL( &opt, QRect( r.topLeft(), QSize( 8, r.height() ) ) );
                              opt.state |= QStyle::State_Horizontal;

                              }
                        else {

                              opt.rect = handleRTL( &opt, QRect( r.topLeft(), QSize( r.width(), 8 ) ) );

                              }

                        drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &painter, toolBar );
                        }

                  // frame
                  if ( hasAlpha ) painter.setClipping( false );
                  _helper.drawFloatFrame( &painter, r, color, !hasAlpha );

                  return true;

                  }
            default:
                  return false;
            }

      }

//---------------------------------------------------------
//   eventFilterToolBox
//---------------------------------------------------------

bool MgStyle::eventFilterToolBox( QToolBox* toolBox, QEvent* event ) {
      if (event->type() == QEvent::Paint) {
            if (toolBox->frameShape() != QFrame::NoFrame) {
                  const QRect r(toolBox->rect());
                  const StyleOptions opts(NoFill);

                  QPainter painter(toolBox);
                  painter.setClipRegion(static_cast<QPaintEvent*>( event )->region());
                  renderSlab(&painter, r, toolBox->palette().color(QPalette::Button), opts);
                  }
            }
      return false;
      }

bool MgStyle::drawCapacityBarControl( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {

      if(!widget)
            widget = QApplication::activeWindow();

      // cast option
      const QStyleOptionProgressBar* cbOption( qstyleoption_cast<const QStyleOptionProgressBar*>( option ) );
      if ( !cbOption ) return true;

      // draw container
      QStyleOptionProgressBarV2 sub_opt(*cbOption);
      sub_opt.rect = subElementRect( QStyle::SE_ProgressBarGroove, cbOption, widget);
      drawProgressBarGrooveControl( &sub_opt, painter, widget);

      // draw bar
      sub_opt.rect = subElementRect( QStyle::SE_ProgressBarContents, cbOption, widget);
      drawProgressBarContentsControl( &sub_opt, painter, widget);

      // draw label
      sub_opt.rect = subElementRect( QStyle::SE_ProgressBarLabel, cbOption, widget);
      drawProgressBarLabelControl( &sub_opt, painter, widget);

      return true;

      }

bool MgStyle::drawComboBoxLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {

      if(!widget)
            widget = QApplication::activeWindow();

      //same as CommonStyle, except for filling behind icon
      if ( const QStyleOptionComboBox* cb = qstyleoption_cast<const QStyleOptionComboBox*>(option)) {

            QRect editRect( subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget) );

            painter->save();
            if ( !cb->currentIcon.isNull() ) {

                  QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
                  QPixmap pixmap( cb->currentIcon.pixmap(cb->iconSize, mode) );
                  QRect iconRect(editRect);
                  iconRect.setWidth(cb->iconSize.width() + 4);
                  iconRect = alignedRect(
                                   cb->direction,
                                   Qt::AlignLeft | Qt::AlignVCenter,
                                   iconRect.size(), editRect);

                  drawItemPixmap( painter, iconRect, Qt::AlignCenter, pixmap);

                  if ( cb->direction == Qt::RightToLeft) editRect.translate(-4 - cb->iconSize.width(), 0);
                  else editRect.translate(cb->iconSize.width() + 4, 0);
                  }

            if ( !cb->currentText.isEmpty() && !cb->editable) {
                  drawItemText(
                        painter, editRect.adjusted(1, 0, -1, 0),
                        visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
                        cb->palette, cb->state & State_Enabled, cb->currentText, QPalette::ButtonText );
                  }
            painter->restore();
            return true;

            }
      else return false;

      }

//---------------------------------------------------------
//   drawDockWidgetTitleControl
//---------------------------------------------------------

bool MgStyle::drawDockWidgetTitleControl( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      // cast option and check
      const QStyleOptionDockWidget* dwOpt = ::qstyleoption_cast<const QStyleOptionDockWidget*>(option);
      if (!dwOpt)
            return true;

      const QPalette& palette( option->palette );
      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );
      const bool reverseLayout( option->direction == Qt::RightToLeft );

      if(!widget)
            widget = QApplication::activeWindow();

      // cast to v2 to check vertical bar
      const QStyleOptionDockWidgetV2* v2 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>( option );
      const bool verticalTitleBar( v2 ? v2->verticalTitleBar : false);

      const QRect btnr(subElementRect(dwOpt->floatable ? SE_DockWidgetFloatButton : SE_DockWidgetCloseButton, option, widget));

      // get rectangle and adjust to properly accounts for buttons
      QRect r(insideMargin(dwOpt->rect, DockWidget_TitleMargin));
      if (verticalTitleBar) {
            if (btnr.isValid())
                  r.setTop(btnr.bottom() + 1);
            }
      else if (reverseLayout) {
            if ( btnr.isValid() )
                  r.setLeft(btnr.right() + 1);
            r.adjust(0, 0, -4, 0);
            }
      else {
            if (btnr.isValid())
                  r.setRight(btnr.left() - 1);
            r.adjust(4, 0, 0, 0);
            }

      QString title(dwOpt->title);
      QString tmpTitle = title;

      // problem: find expanded width of text with mnemonic macro
      // this is quite suboptimal
      // and does not really work
      if (tmpTitle.contains("&")) {
            int pos = tmpTitle.indexOf("&");
            if (!(tmpTitle.size() - 1 > pos && tmpTitle.at(pos + 1) == QChar('&')))
                  tmpTitle.remove(pos, 1);
            }

      int tw = dwOpt->fontMetrics.width(tmpTitle);
      int width = verticalTitleBar ? r.height() : r.width();
      if (width < tw)
            title = dwOpt->fontMetrics.elidedText(title, Qt::ElideRight, width, Qt::TextShowMnemonic);

      if (verticalTitleBar) {
            QSize s = r.size();
            s.transpose();
            r.setSize(s);

            painter->save();
            painter->translate(r.left(), r.top() + r.width());
            painter->rotate(-90);
            painter->translate(-r.left(), -r.top());
            drawItemText(painter, r, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette, enabled, title, QPalette::WindowText);
            painter->restore();
            }
      else
            drawItemText(painter, r, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette, enabled, title, QPalette::WindowText);
      return true;
      }

bool MgStyle::drawHeaderEmptyAreaControl( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {

      // use the same background as in drawHeaderPrimitive
      QPalette palette( option->palette );

      if(!widget)
            widget = QApplication::activeWindow();

      if ( widget && animations().widgetEnabilityEngine().isAnimated( widget, AnimationEnable ) ) {
            palette = _helper.mergePalettes( palette, animations().widgetEnabilityEngine().opacity( widget, AnimationEnable )  );
            }

      const bool horizontal( option->state & QStyle::State_Horizontal );
      const bool reverseLayout( option->direction == Qt::RightToLeft );
      renderHeaderBackground( option->rect, palette, painter, widget, horizontal, reverseLayout );

      return true;

      }

bool MgStyle::drawHeaderLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const {
      const QStyleOptionHeader* headerOpt( qstyleoption_cast<const QStyleOptionHeader*>( option ) );
      if ( !headerOpt ) return true;

      QRect rect( headerOpt->rect );

      if (!headerOpt->icon.isNull()) {
            const QPixmap pixmap( headerOpt->icon.pixmap(
                                        pixelMetric(PM_SmallIconSize),
                                        (headerOpt->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled ));

            int pixw = pixmap.width();

            QRect aligned = alignedRect(headerOpt->direction, QFlag(headerOpt->iconAlignment), pixmap.size(), rect);
            QRect inter = aligned.intersected(rect);
            painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height());

            if (headerOpt->direction == Qt::LeftToRight) rect.setLeft(rect.left() + pixw + 2);
            else rect.setRight(rect.right() - pixw - 2);

            }

      drawItemText(
            painter, rect, headerOpt->textAlignment, headerOpt->palette,
            (headerOpt->state & State_Enabled), headerOpt->text, QPalette::WindowText );

      return true;
      }

bool MgStyle::drawHeaderSectionControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );

      const QStyleOptionHeader* headerOpt( qstyleoption_cast<const QStyleOptionHeader*>( option ) );
      if ( !headerOpt ) return true;

      const bool horizontal( headerOpt->orientation == Qt::Horizontal );
      const bool reverseLayout( option->direction == Qt::RightToLeft );
      const bool isFirst( horizontal && ( headerOpt->position == QStyleOptionHeader::Beginning ) );
      const bool isCorner( widget && widget->inherits( "QTableCornerButton" ) );

      if(!widget)
            widget = QApplication::activeWindow();

      // corner header lines
      if ( isCorner ) {

            if ( widget ) _helper.renderWindowBackground( painter, r, widget, palette );
            else painter->fillRect( r, palette.color( QPalette::Window ) );
            if ( reverseLayout ) renderHeaderLines( r, palette, painter, TileSet::BottomLeft );
            else renderHeaderLines( r, palette, painter, TileSet::BottomRight );

            }
      else renderHeaderBackground( r, palette, painter, widget, horizontal, reverseLayout );

      // dots
      painter->setPen(palette.color(QPalette::Text));
      const QColor color( palette.color(QPalette::Window) );
      if ( horizontal ) {

            if (headerOpt->section != 0 || isFirst ) {
                  const int center( r.center().y() );
                  const int pos( reverseLayout ? r.left() + 1 : r.right() - 1 );
                  _helper.renderDot( painter, QPoint(pos, center - 3), color);
                  _helper.renderDot( painter, QPoint(pos, center), color);
                  _helper.renderDot( painter, QPoint(pos, center + 3), color);
                  }

            }
      else {

            const int center( r.center().x() );
            const int pos( r.bottom() - 1 );
            _helper.renderDot( painter, QPoint(center - 3, pos), color);
            _helper.renderDot( painter, QPoint(center, pos), color);
            _helper.renderDot( painter, QPoint(center + 3, pos), color);

            }

      return true;

      }

bool MgStyle::drawMenuBarItemControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {
      const QStyleOptionMenuItem* menuOpt = ::qstyleoption_cast<const QStyleOptionMenuItem*>(option);
      if (!menuOpt) return true;

      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );

      if(!widget)
            widget = QApplication::activeWindow();

      if ( enabled ) {
            const bool active( flags & State_Selected );
            const bool animated( animations().menuBarEngine().isAnimated(widget, r.topLeft() ) );
            const qreal opacity( animations().menuBarEngine().opacity( widget, r.topLeft() ) );
            const QRect currentRect( animations().menuBarEngine().currentRect( widget, r.topLeft() ) );
            const QRect animatedRect( animations().menuBarEngine().animatedRect( widget ) );

            const bool intersected( animatedRect.intersects( r ) );
            const bool current( currentRect.contains( r.topLeft() ) );
            const bool timerIsActive( animations().menuBarEngine().isTimerActive(widget) );

            // do nothing in case of empty intersection between animated rect and current
            if ( ( intersected || !animated || animatedRect.isNull() ) && ( active || animated || timerIsActive ) ) {

                  QColor color( palette.color(QPalette::Window) );
                  if ( MgStyleConfigData::menuHighlightMode != MgStyleConfigData::MM_DARK) {

                        if (flags & State_Sunken) {

                              if ( MgStyleConfigData::menuHighlightMode == MgStyleConfigData::MM_STRONG) color = palette.color(QPalette::Highlight);
                              else color = ColorUtils::mix(color, ColorUtils::tint(color, palette.color(QPalette::Highlight), 0.6));

                              }
                        else {

                              if ( MgStyleConfigData::menuHighlightMode == MgStyleConfigData::MM_STRONG) color = ColorUtils::tint(color, _helper.viewHoverBrush().brush( palette ).color());
                              else color = ColorUtils::mix(color, ColorUtils::tint(color, _helper.viewHoverBrush().brush( palette ).color()));
                              }

                        }
                  else color = _helper.calcMidColor( _helper.backgroundColor( color, widget, r.center() ) );

                  // drawing
                  if ( animated && intersected ) {

                        _helper.holeFlat(color, 0.0)->render(animatedRect.adjusted(1, 1, -1, -1), painter, TileSet::Full);

                        }
                  else if ( timerIsActive && current ) {

                        _helper.holeFlat(color, 0.0)->render(r.adjusted(1, 1, -1, -1), painter, TileSet::Full);

                        }
                  else if ( animated && current ) {

                        color.setAlphaF( opacity );
                        _helper.holeFlat(color, 0.0)->render(r.adjusted(1, 1, -1, -1), painter, TileSet::Full);

                        }
                  else if ( active ) {

                        _helper.holeFlat(color, 0.0)->render(r.adjusted(1, 1, -1, -1), painter, TileSet::Full);

                        }

                  }

            }

      // text
      QPalette::ColorRole role( QPalette::WindowText );
      if ( MgStyleConfigData::menuHighlightMode == MgStyleConfigData::MM_STRONG && (flags & State_Sunken) && enabled ) {
            role = QPalette::HighlightedText;
            }

      drawItemText(painter, r, Qt::AlignCenter | Qt::TextShowMnemonic, palette, enabled, menuOpt->text, role);

      return true;

      }

//---------------------------------------------------------
//   drawMenuItemControl
//---------------------------------------------------------

bool MgStyle::drawMenuItemControl(const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      const State& flags( option->state );
      const bool active( flags & State_Selected );
      const bool enabled( flags & State_Enabled );
      const bool hasFocus( enabled && (flags & State_HasFocus));
      const bool mouseOver( enabled && (flags & State_MouseOver) );

      if(!widget)
            widget = QApplication::activeWindow();

      //First of all,render the background.
      renderMenuItemBackground(option, painter, widget);

      // do nothing if invalid option, or empty area
      const QStyleOptionMenuItem* menuItemOption = qstyleoption_cast<const QStyleOptionMenuItem*>(option);
      if ( !menuItemOption || menuItemOption->menuItemType == QStyleOptionMenuItem::EmptyArea)
            return true;

      //First, figure out the left column width.
      const int iconColW   = (int)MenuItem_IconWidth; //qMax( menuItemOption->maxIconWidth, (int)MenuItem_IconWidth );
      const int checkColW  = MenuItem_CheckWidth;
      const int checkSpace = MenuItem_CheckSpace;

      int leftColW = iconColW;

      // only use the additional check row if the menu has checkable menuItems.
      bool hasCheckableItems = menuItemOption->menuHasCheckableItems;
      if (hasCheckableItems)
            leftColW = checkColW + checkSpace; //leftColW += checkColW + checkSpace;

      // right arrow column...
      int rightColW = MenuItem_ArrowSpace + MenuItem_ArrowWidth;

      //Separators: done with the bg, can paint them and bail them out.
      if (menuItemOption->menuItemType == QStyleOptionMenuItem::Separator) {
            // check text and icon
            // separators with non empty text are rendered as checked toolbuttons
            if (!menuItemOption->text.isEmpty()) {
                  QStyleOptionToolButton toolButtonOpt;
                  toolButtonOpt.features    = QStyleOptionToolButton::None;
                  toolButtonOpt.state       = State_On | State_Sunken | State_Enabled;
                  toolButtonOpt.rect        = r.adjusted( 0, 0, 0, 1 );
                  toolButtonOpt.subControls = SC_ToolButton;
                  toolButtonOpt.icon        =  menuItemOption->icon;

                  toolButtonOpt.font = widget->font();     // TODO Inherit font from environment
                  toolButtonOpt.font.setBold(true);

                  toolButtonOpt.iconSize = QSize(
                                                 pixelMetric(QStyle::PM_SmallIconSize, 0, 0),
                                                 pixelMetric(QStyle::PM_SmallIconSize, 0, 0)
                                           );

                  // for now menu size is not calculated properly
                  // (meaning it doesn't account for titled separators width
                  // as a fallback, we elide the text to be displayed
                  int width(r.width());
                  if (!menuItemOption->icon.isNull())
                        width -= toolButtonOpt.iconSize.width() + 2;
                  width -= 2 * ToolButton_ContentsMargin;

                  toolButtonOpt.text = QFontMetrics(toolButtonOpt.font).elidedText(menuItemOption->text, Qt::ElideRight, width);

                  toolButtonOpt.toolButtonStyle = Qt::ToolButtonTextBesideIcon;
                  drawComplexControl(CC_ToolButton, &toolButtonOpt, painter, widget);
                  }
            else {
                  // in all other cases draw regular separator
                  const QColor color(_helper.menuBackgroundColor(palette.color(QPalette::Window), widget, r.center()));
                  _helper.drawSeparator(painter, r, color, Qt::Horizontal);
                  }
            return true;
            }

      //Remove the margin (for everything but the column background)
      const QRect ir( insideMargin(r, MenuItem_Margin ) );

      // Active indicator...
      if (active && enabled) {
            // check if there is a 'sliding' animation in progress, in which case, do nothing
            const QRect animatedRect( animations().menuEngine().animatedRect( widget ) );
            if (animatedRect.isNull()) {
                  const bool animated( animations().menuEngine().isAnimated(widget, Current ) );
                  const QRect currentRect( animations().menuEngine().currentRect( widget, Current ) );
                  const bool intersected( currentRect.contains( r.topLeft() ) );

                  const QColor color( _helper.menuBackgroundColor( palette.color( QPalette::Window ), widget, r.center() ) );

                  if (animated && intersected)
                        renderMenuItemRect( option, r, color, palette, painter, animations().menuEngine().opacity( widget, Current ) );
                  else
                        renderMenuItemRect( option, r, color, palette, painter );
                  }
            }

      // color
      QPalette::ColorRole textRole((active && enabled && MgStyleConfigData::menuHighlightMode == MgStyleConfigData::MM_STRONG ) ?
                                   QPalette::HighlightedText : QPalette::WindowText);

      //Readjust the column rectangle back to proper height
      QRect leftColRect(ir.x(), ir.y(), leftColW, ir.height());

      // paint a normal check- resp. radiomark.
      const QRect checkColRect(leftColRect.x(), leftColRect.y(), checkColW, leftColRect.height());

      const CheckBoxState checkBoxState( menuItemOption->checked ? CheckOn : CheckOff );
      if (menuItemOption->checkType == QStyleOptionMenuItem::NonExclusive) {
            StyleOptions opts(0);
            opts |= Sunken;
            if (!enabled)
                  opts |= Disabled;
            if (mouseOver)
                  opts |= Hover;
            if ( hasFocus)
                  opts |= Focus;

            const QRect r( handleRTL(option, checkColRect) );
            QPalette localPalette( palette );
            localPalette.setColor( QPalette::Window, _helper.menuBackgroundColor( palette.color( QPalette::Window ), widget, r.topLeft() ) );
            renderCheckBox( painter, r.adjusted(2, -2, 2, 2), localPalette, opts, checkBoxState );
            }
      else if ( menuItemOption->checkType == QStyleOptionMenuItem::Exclusive) {
            StyleOptions opts(0);
            if ( !enabled )
                  opts |= Disabled;
            if ( mouseOver )
                  opts |= Hover;
            if ( hasFocus )
                  opts |= Focus;

            const QRect r( handleRTL(option, checkColRect) );
            QPalette localPalette( palette );
            localPalette.setColor( QPalette::Window, _helper.menuBackgroundColor( palette.color( QPalette::Window ), widget, r.topLeft() ) );
            renderRadioButton( painter, r.adjusted(2, -2, 2, 2), localPalette, opts, checkBoxState );
            }

      // Paint the menu icon.
      if ( !menuItemOption->icon.isNull()) {
            QRect iconColRect;
            if ( hasCheckableItems ) {
                  iconColRect = QRect(
                                      leftColRect.x() + checkColW + checkSpace, leftColRect.y(),
                                      leftColRect.width() - (checkColW + checkSpace), leftColRect.height() );
                  }
            else
                  iconColRect = leftColRect;
            // icon mode
            QIcon::Mode mode;
            if (enabled)
                  mode = active ? QIcon::Active : QIcon::Normal;
            else
                  mode = QIcon::Disabled;

            // icon state
            const QIcon::State iconState(
                  ( (flags & State_On) || (flags & State_Sunken) ) ? QIcon::On : QIcon::Off );

            // icon size
            const QSize size( pixelMetric(PM_SmallIconSize), pixelMetric(PM_SmallIconSize) );
            const QRect r( handleRTL(option, centerRect(iconColRect, size ) ) );
            const QPixmap icon = menuItemOption->icon.pixmap(size, mode, iconState);
            painter->drawPixmap( centerRect( r, size ), icon );
            }


      //Now include the spacing when calculating the next columns
      leftColW += MenuItem_IconSpace;

      //Render the text, including any accel.
      QString text = menuItemOption->text;
      const QRect textRect( handleRTL( option, QRect(ir.x() + leftColW, ir.y(), ir.width() - leftColW - rightColW, ir.height()) ) );

      painter->setFont( menuItemOption->font );

      int tabPos = menuItemOption->text.indexOf(QLatin1Char('\t'));
      if ( tabPos != -1) {

            text = menuItemOption->text.left(tabPos);
            QString accl = menuItemOption->text.mid (tabPos + 1);

            drawItemText(
                  painter, textRect, Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::AlignRight, palette,
                  enabled, accl, textRole);

            }

      //Draw the text.
      drawItemText(
            painter, textRect, Qt::AlignVCenter | Qt::TextShowMnemonic, palette,
            enabled, text, textRole);

      //Render arrow, if need be.
      if ( menuItemOption->menuItemType == QStyleOptionMenuItem::SubMenu ) {
            const qreal penThickness = 1.6;
            const QColor color = palette.color( textRole );
            const QColor background = palette.color(QPalette::Window);

            const int aw = MenuItem_ArrowWidth;
            QRect arrowRect = handleRTL( option, QRect(ir.x() + ir.width() - aw, ir.y(), aw, ir.height()) );

            // get arrow shape
            QPolygonF a = genericArrow( option->direction == Qt::LeftToRight ? ArrowRight : ArrowLeft, ArrowNormal );

            painter->translate( arrowRect.center() );
            painter->setRenderHint(QPainter::Antialiasing);

            // white reflection
            const qreal offset( qMin( penThickness, qreal(1.0)) );
            painter->translate(0, offset);
            painter->setPen(QPen(_helper.calcLightColor( background ), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            painter->drawPolyline(a);
            painter->translate(0, -offset);

            painter->setPen(QPen( _helper.decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            painter->drawPolyline(a);
            }
      return true;
      }

bool MgStyle::drawProgressBarControl( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {

      if ( const QStyleOptionProgressBar* pb = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {

            if(!widget)
                  widget = QApplication::activeWindow();

            // same as QCommonStyle::drawControl, except that it handles animations
            QStyleOptionProgressBarV2 subopt = *pb;
            subopt.rect = subElementRect(SE_ProgressBarGroove, pb, widget);
            drawProgressBarGrooveControl(&subopt, painter, widget);

            if ( animations().progressBarEngine().busyIndicatorEnabled() && pb->maximum == 0 && pb->minimum == 0 ) {
                  animations().progressBarEngine().startBusyTimer();
                  }

            if ( animations().progressBarEngine().isAnimated( widget ) ) {
                  subopt.progress = animations().progressBarEngine().value( widget );
                  }

            subopt.rect = subElementRect( SE_ProgressBarContents, &subopt, widget );
            drawProgressBarContentsControl( &subopt, painter, widget );

            if ( pb->textVisible) {
                  subopt.rect = subElementRect( SE_ProgressBarLabel, pb, widget );
                  drawProgressBarLabelControl( &subopt, painter, widget );
                  }

            }

      return true;

      }

bool MgStyle::drawProgressBarContentsControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const {

      const QStyleOptionProgressBar* pbOpt = qstyleoption_cast<const QStyleOptionProgressBar*>(option);
      if ( !pbOpt ) return true;

      const QStyleOptionProgressBarV2* pbOpt2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>(option);

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );

      // check if anything is to be drawn
      const qreal progress = pbOpt->progress - pbOpt->minimum;
      const bool busyIndicator = (pbOpt->minimum == 0 && pbOpt->maximum == 0);
      if ( !( progress || busyIndicator ) ) return true;

      const int steps = qMax(pbOpt->maximum  - pbOpt->minimum, 1);
      const bool horizontal = !pbOpt2 || pbOpt2->orientation == Qt::Horizontal;

      //Calculate width fraction
      qreal widthFrac( busyIndicator ?  ProgressBar_BusyIndicatorSize / 100.0 : progress / steps );
      widthFrac = qMin( 1.0, widthFrac );

      // And now the pixel width
      const int indicatorSize( widthFrac * ( horizontal ? r.width() : r.height() ) );

      // do nothing if indicator size is too small
      if ( indicatorSize < 4 ) return true;

      QRect indicatorRect;
      if (busyIndicator) {

            // The space around which we move around...
            int remSize = ( (1.0 - widthFrac) * ( horizontal ? r.width() : r.height() ) );
            remSize = qMax( remSize, 1 );

            int pstep =  int(progress) % (2 * remSize);
            if (pstep > remSize) {
                  // Bounce about.. We're remWidth + some delta, we want to be remWidth - delta...
                  // - ( (remWidth + some delta) - 2* remWidth )  = - (some deleta - remWidth) = remWidth - some delta..
                  pstep = -( pstep - 2 * remSize );
                  }

            if (horizontal) indicatorRect = QRect(r.x() + pstep, r.y(), indicatorSize, r.height());
            else indicatorRect = QRect(r.x(), r.y() + pstep, r.width(), indicatorSize);

            }
      else {

            if (horizontal) indicatorRect = QRect(r.x(), r.y(), indicatorSize, r.height());
            else indicatorRect = QRect(r.x(), r.bottom() - indicatorSize + 1, r.width(), indicatorSize );

            }

      // handle right to left
      indicatorRect = handleRTL( option, indicatorRect );

      QPixmap pixmap( _helper.progressBarIndicator( palette, indicatorRect ) );
      painter->drawPixmap( indicatorRect.adjusted(-1, -2, 0, 0).topLeft(), pixmap );
      return true;

      }

bool MgStyle::drawProgressBarGrooveControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const {

      const QStyleOptionProgressBarV2* pbOpt = qstyleoption_cast<const QStyleOptionProgressBarV2*>(option);
      const Qt::Orientation orientation( pbOpt ? pbOpt->orientation : Qt::Horizontal );

      renderScrollBarHole( painter, option->rect, option->palette.color(QPalette::Window), orientation);

      return true;
      }

bool MgStyle::drawProgressBarLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const {
      const QStyleOptionProgressBar* pbOpt = qstyleoption_cast<const QStyleOptionProgressBar*>(option);
      if ( !pbOpt ) return true;

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );

      const QStyleOptionProgressBarV2* pbOpt2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>(option);
      const bool horizontal = !pbOpt2 || pbOpt2->orientation == Qt::Horizontal;
      const bool reverseLayout = ( option->direction == Qt::RightToLeft );

      // rotate label for vertical layout
      if (! (horizontal || reverseLayout ) ) {

            painter->translate(r.topRight());
            painter->rotate(90.0);

            }
      else if ( !horizontal ) {

            painter->translate(r.bottomLeft());
            painter->rotate(-90.0);

            }

      Qt::Alignment hAlign( ( pbOpt->textAlignment == Qt::AlignLeft ) ? Qt::AlignHCenter : pbOpt->textAlignment );

      /*
      Figure out the geometry of the indicator.
      This is copied from drawProgressBarContentsControl
      */
      QRect progressRect;
      const QRect textRect( horizontal ? r : QRect( 0, 0, r.height(), r.width() ) );
      const qreal progress = pbOpt->progress - pbOpt->minimum;
      const int steps = qMax( pbOpt->maximum  - pbOpt->minimum, 1);
      const bool busyIndicator = (steps <= 1 );

      int indicatorSize( 0 );
      if ( !busyIndicator ) {
            const qreal widthFrac = qMin( 1.0, progress / steps );
            indicatorSize = widthFrac * ( horizontal ? r.width() : r.height() );
            }

      if ( indicatorSize ) {
            if (horizontal) painter->setClipRect(handleRTL(option, QRect(r.x(), r.y(), indicatorSize, r.height())));
            else if (!reverseLayout)  painter->setClipRect(QRect(r.height() - indicatorSize, 0, r.height(), r.width()));
            else painter->setClipRect(QRect(0, 0, indicatorSize, r.width()));

            // first pass (highlighted)
            drawItemText( painter, textRect, Qt::AlignVCenter | hAlign, palette, enabled, pbOpt->text, QPalette::HighlightedText );

            // second pass (normal)
            if ( horizontal ) painter->setClipRect( handleRTL(option, QRect(r.x() + indicatorSize, r.y(), r.width() - indicatorSize, r.height())));
            else if ( !reverseLayout ) painter->setClipRect(QRect(0, 0, r.height() - indicatorSize, r.width() ) );
            else painter->setClipRect(QRect( indicatorSize, 0, r.height() - indicatorSize, r.width()));
            drawItemText( painter, textRect, Qt::AlignVCenter | hAlign, palette, enabled, pbOpt->text, QPalette::WindowText );

            }
      else {

            drawItemText( painter, textRect, Qt::AlignVCenter | hAlign, palette, enabled, pbOpt->text, QPalette::WindowText );

            }

      return true;
      }

//---------------------------------------------------------
//   drawPushButtonLabelControl
//---------------------------------------------------------

bool MgStyle::drawPushButtonLabelControl(const QStyleOption* option, QPainter* painter, const QWidget*) const {
      // cast option and check
      const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
      if (!bOpt)
            return true;

      const QRect& r(option->rect);
      const QPalette& palette( option->palette );
      const State& flags( option->state );
      const bool active = (flags & State_On) || (flags & State_Sunken);
      const bool enabled = (flags & State_Enabled);
      const bool hasFocus = (flags & State_HasFocus);

      //Extract out coordinates for easier manipulation
      int x, y, w, h;
      r.getRect(&x, &y, &w, &h);

      //Layout the stuff.
      if (bOpt->features & QStyleOptionButton::HasMenu) {
            const int indicatorWidth( PushButton_MenuIndicatorSize );
            const int indicatorSpacing = PushButton_TextToIconSpace;
            w -= indicatorWidth + indicatorSpacing;

            // arrow
            const QRect arrowRect( x + w + indicatorSpacing, y + 1, indicatorWidth, h );
            const qreal penThickness = 1.6;
            QPolygonF a = genericArrow( ArrowDown, ArrowNormal );
            const QColor color = palette.color( QPalette::ButtonText );
            const QColor background = palette.color(QPalette::Button);

            painter->save();
            painter->translate( arrowRect.center() );
            painter->setRenderHint(QPainter::Antialiasing);

            const qreal offset( qMin( penThickness, qreal(1.0)) );
            painter->translate(0, offset);
            painter->setPen( QPen( _helper.calcLightColor(  palette.color(QPalette::Window)), penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin) );
            painter->drawPolyline(a);
            painter->translate(0, -offset);

            painter->setPen(QPen( _helper.decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            painter->drawPolyline(a);
            painter->restore();

            }

      // Draw the icon if there is one
      if (!bOpt->icon.isNull() ) {
            QIcon::Mode mode;
            if (enabled)
                  mode = (hasFocus) ? QIcon::Active : QIcon::Normal;
            else
                  mode = QIcon::Disabled;

            QIcon::State iconState = active ? QIcon::On : QIcon::Off;
            QSize size = bOpt->iconSize;
            if (!size.isValid())
                  size = QSize(pixelMetric(PM_SmallIconSize), pixelMetric(PM_SmallIconSize));
            QPixmap icon = bOpt->icon.pixmap(size, mode, iconState);

            QRect iconRect;
            if (!bOpt->text.isEmpty()) {
                  const int margin = PushButton_TextToIconSpace;
                  const int length = bOpt->iconSize.width() + margin + painter->fontMetrics().size(Qt::TextShowMnemonic, bOpt->text).width();

                  //Calculate offset.
                  const int offset = (w - length) / 2;
                  iconRect = QRect(handleRTL( bOpt, QRect( QPoint(x + offset, y + h / 2 - bOpt->iconSize.height() / 2), bOpt->iconSize)));

                  painter->drawPixmap(centerRect( iconRect, icon.size()), icon);

                  //new bounding rect for the text
                  x += offset + bOpt->iconSize.width() + margin;
                  w =  length - bOpt->iconSize.width() - margin;
                  }
            else {
                  iconRect = QRect( x, y, w, h );
                  }
            painter->drawPixmap(centerRect(iconRect, icon.size()), icon);
            }
      else {
            //Center the text
            int textW = painter->fontMetrics().size(Qt::TextShowMnemonic, bOpt->text).width();
            x += (w - textW) / 2;
            w =  textW;
            }

      QRect textRect( handleRTL( bOpt, QRect(x, y, w, h) ) );
      if ( !bOpt->icon.isNull() ) textRect.adjust( 0, 0, 0, 1 );
      drawItemText( painter, textRect, Qt::AlignCenter | Qt::TextShowMnemonic, palette, enabled, bOpt->text, QPalette::ButtonText );

      return true;
      }

bool MgStyle::drawRubberBandControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const {

      if ( const QStyleOptionRubberBand* rbOpt = qstyleoption_cast<const QStyleOptionRubberBand*>(option)) {

            painter->save();
            QColor color = rbOpt->palette.color(QPalette::Highlight);
            painter->setPen(ColorUtils::mix(color, rbOpt->palette.color(QPalette::Active, QPalette::WindowText)));
            color.setAlpha(50);
            painter->setBrush(color);
            painter->setClipRegion(rbOpt->rect);
            painter->drawRect(rbOpt->rect.adjusted(0, 0, -1, -1));
            painter->restore();
            return true;

            }
      else return false;

      }

bool MgStyle::drawScrollBarSliderControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {

      // cast option and check
      const QStyleOptionSlider* slider = qstyleoption_cast<const QStyleOptionSlider*>( option );
      if ( !slider ) return true;

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );

      const State& flags( option->state );
      const bool horizontal( flags & State_Horizontal );
      const bool enabled( flags & State_Enabled );
      const bool mouseOver( enabled && (flags & State_MouseOver) );

      if(!widget)
            widget = QApplication::activeWindow();

      // enable animation state
      animations().scrollBarEngine().updateState( widget, enabled && slider && (slider->activeSubControls & SC_ScrollBarSlider) );

      const bool animated( enabled && animations().scrollBarEngine().isAnimated( widget, SC_ScrollBarSlider ) );

      if ( horizontal ) {
            if ( animated ) renderScrollBarHandle( painter, r, palette, Qt::Horizontal, mouseOver, animations().scrollBarEngine().opacity( widget, SC_ScrollBarSlider ) );
            else renderScrollBarHandle( painter, r, palette, Qt::Horizontal, mouseOver );

            }
      else {

            if ( animated ) renderScrollBarHandle( painter, r, palette, Qt::Vertical, mouseOver, animations().scrollBarEngine().opacity( widget, SC_ScrollBarSlider ) );
            else renderScrollBarHandle( painter, r, palette, Qt::Vertical, mouseOver );

            }

      return true;
      }

bool MgStyle::drawScrollBarAddLineControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {

      // cast option and check
      const QStyleOptionSlider* slOpt = qstyleoption_cast<const QStyleOptionSlider*>(option);
      if (!slOpt) return true;

      const State& flags( option->state );
      const bool horizontal( flags & State_Horizontal );
      const bool reverseLayout( option->direction == Qt::RightToLeft );

      // colors
      const QPalette& palette( option->palette );
      const QColor background( palette.color( QPalette::Window ) );

      // adjust rect, based on number of buttons to be drawn
      const QRect r( scrollBarInternalSubControlRect( slOpt, SC_ScrollBarAddLine ) );

      if(!widget)
            widget = QApplication::activeWindow();

      // draw the end of the scrollbar groove
      if ( horizontal ) {

            if ( reverseLayout ) renderScrollBarHole( painter, QRect(r.right() + 1, r.top(), 5, r.height()), background, Qt::Horizontal, TileSet::Top | TileSet::Bottom | TileSet::Left);
            else renderScrollBarHole( painter, QRect(r.left() - 5, r.top(), 5, r.height()), background, Qt::Horizontal, TileSet::Top | TileSet::Right | TileSet::Bottom);

            }
      else renderScrollBarHole( painter, QRect(r.left(), r.top() - 5, r.width(), 5), background, Qt::Vertical, TileSet::Bottom | TileSet::Left | TileSet::Right);

      // stop here if no buttons are defined
      if ( _addLineButtons == NoButton ) return true;

      QColor color;
      QStyleOption localOption( *option );
      if ( _addLineButtons == DoubleButton ) {

            if ( horizontal ) {

                  //Draw the arrows
                  const QSize halfSize( r.width() / 2, r.height() );
                  const QRect leftSubButton(r.topLeft(), halfSize );
                  const QRect rightSubButton( leftSubButton.topRight() + QPoint( 1, 0 ), halfSize );

                  localOption.rect = leftSubButton;
                  color = scrollBarArrowColor( &localOption,  reverseLayout ? SC_ScrollBarAddLine : SC_ScrollBarSubLine, widget );
                  renderScrollBarArrow( painter, leftSubButton, color, background, ArrowLeft );

                  localOption.rect = rightSubButton;
                  color = scrollBarArrowColor( &localOption,  reverseLayout ? SC_ScrollBarSubLine : SC_ScrollBarAddLine, widget );
                  renderScrollBarArrow( painter, rightSubButton, color, background, ArrowRight );

                  }
            else {

                  const QSize halfSize( r.width(), r.height() / 2 );
                  const QRect topSubButton( r.topLeft(), halfSize );
                  const QRect botSubButton( topSubButton.bottomLeft() + QPoint( 0, 1 ), halfSize );

                  localOption.rect = topSubButton;
                  color = scrollBarArrowColor( &localOption, SC_ScrollBarSubLine, widget );
                  renderScrollBarArrow( painter, topSubButton, color, background, ArrowUp );

                  localOption.rect = botSubButton;
                  color = scrollBarArrowColor( &localOption, SC_ScrollBarAddLine, widget );
                  renderScrollBarArrow( painter, botSubButton, color, background, ArrowDown );

                  }

            }
      else if ( _addLineButtons == SingleButton ) {

            localOption.rect = r;
            color = scrollBarArrowColor( &localOption,  SC_ScrollBarAddLine, widget );
            if ( horizontal ) renderScrollBarArrow( painter, r, color, background, reverseLayout ? ArrowLeft : ArrowRight );
            else renderScrollBarArrow( painter, r, color, background, ArrowDown );

            }

      return true;
      }

bool MgStyle::drawScrollBarAddPageControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const {

      // cast option and check
      const QStyleOptionSlider* slOpt = qstyleoption_cast<const QStyleOptionSlider*>(option);
      if (!slOpt) return true;

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      const QColor color( palette.color(QPalette::Window) );

      const State& flags( option->state );
      const bool horizontal( flags & State_Horizontal );
      const bool reverseLayout( slOpt->direction == Qt::RightToLeft );

      if ( horizontal ) {
            if ( reverseLayout ) renderScrollBarHole( painter, r.adjusted(0, 0, 10, 0), color, Qt::Horizontal, TileSet::Vertical );
            else renderScrollBarHole( painter, r.adjusted(-10, 0, 0, 0), color, Qt::Horizontal, TileSet::Vertical );
            }
      else renderScrollBarHole( painter, r.adjusted(0, -10, 0, 0), color, Qt::Vertical, TileSet::Horizontal );

      return true;

      }

bool MgStyle::drawScrollBarSubLineControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {

      // cast option and check
      const QStyleOptionSlider* slOpt = qstyleoption_cast<const QStyleOptionSlider*>(option);
      if (!slOpt) return true;

      const State& flags( option->state );
      const bool horizontal( flags & State_Horizontal );
      const bool reverseLayout( option->direction == Qt::RightToLeft );

      // colors
      const QPalette& palette( option->palette );
      const QColor background( palette.color( QPalette::Window ) );

      if(!widget)
            widget = QApplication::activeWindow();

      // adjust rect, based on number of buttons to be drawn
      QRect r( scrollBarInternalSubControlRect( slOpt, SC_ScrollBarSubLine ) );

      // draw the end of the scrollbar groove
      if ( horizontal ) {

            if ( reverseLayout) renderScrollBarHole( painter, QRect(r.left() - 5, r.top(), 5, r.height()), background, Qt::Horizontal, TileSet::Top | TileSet::Right | TileSet::Bottom);
            else renderScrollBarHole( painter, QRect(r.right() + 1, r.top(), 5, r.height()), background, Qt::Horizontal, TileSet::Top | TileSet::Left | TileSet::Bottom);

            r.translate( 1, 0 );

            }
      else {

            renderScrollBarHole( painter, QRect(r.left(), r.bottom() + 3, r.width(), 5), background, Qt::Vertical, TileSet::Top | TileSet::Left | TileSet::Right);
            r.translate( 0, 2 );

            }

      // stop here if no buttons are defined
      if ( _addLineButtons == NoButton ) return true;

      QColor color;
      QStyleOption localOption( *option );
      if ( _subLineButtons == DoubleButton ) {

            if ( horizontal ) {

                  //Draw the arrows
                  const QSize halfSize( r.width() / 2, r.height() );
                  const QRect leftSubButton(r.topLeft(), halfSize );
                  const QRect rightSubButton( leftSubButton.topRight() + QPoint( 1, 0 ), halfSize );

                  localOption.rect = leftSubButton;
                  color = scrollBarArrowColor( &localOption,  reverseLayout ? SC_ScrollBarAddLine : SC_ScrollBarSubLine, widget );
                  renderScrollBarArrow( painter, leftSubButton, color, background, ArrowLeft );

                  localOption.rect = rightSubButton;
                  color = scrollBarArrowColor( &localOption,  reverseLayout ? SC_ScrollBarSubLine : SC_ScrollBarAddLine, widget );
                  renderScrollBarArrow( painter, rightSubButton, color, background, ArrowRight );

                  }
            else {

                  const QSize halfSize( r.width(), r.height() / 2 );
                  const QRect topSubButton( r.topLeft(), halfSize );
                  const QRect botSubButton( topSubButton.bottomLeft() + QPoint( 0, 1 ), halfSize );

                  localOption.rect = topSubButton;
                  color = scrollBarArrowColor( &localOption, SC_ScrollBarSubLine, widget );
                  renderScrollBarArrow( painter, topSubButton, color, background, ArrowUp );

                  localOption.rect = botSubButton;
                  color = scrollBarArrowColor( &localOption, SC_ScrollBarAddLine, widget );
                  renderScrollBarArrow( painter, botSubButton, color, background, ArrowDown );

                  }

            }
      else if ( _subLineButtons == SingleButton ) {

            localOption.rect = r;
            color = scrollBarArrowColor( &localOption,  SC_ScrollBarSubLine, widget );
            if ( horizontal ) renderScrollBarArrow( painter, r, color, background, reverseLayout ? ArrowRight : ArrowLeft );
            else renderScrollBarArrow( painter, r, color, background, ArrowUp );

            }

      return true;
      }

bool MgStyle::drawScrollBarSubPageControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const {

      // cast option and check
      const QStyleOptionSlider* slOpt = qstyleoption_cast<const QStyleOptionSlider*>(option);
      if (!slOpt) return true;

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      const QColor color( palette.color(QPalette::Window) );

      const State& flags( option->state );
      const bool horizontal( flags & State_Horizontal );
      const bool reverseLayout( slOpt->direction == Qt::RightToLeft );

      if ( horizontal ) {
            if ( reverseLayout ) renderScrollBarHole( painter, r.adjusted(-10, 0, 0, 0), color, Qt::Horizontal, TileSet::Vertical );
            else renderScrollBarHole( painter, r.adjusted(0, 0, 10, 0), color, Qt::Horizontal, TileSet::Vertical );
            }
      else renderScrollBarHole( painter, r.adjusted(0, 2, 0, 12), color, Qt::Vertical, TileSet::Horizontal );

      return true;

      }

bool MgStyle::drawShapedFrameControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const {

      // cast option and check
      const QStyleOptionFrameV3* frameOpt = qstyleoption_cast<const QStyleOptionFrameV3*>( option );
      if ( !frameOpt ) return false;

      switch ( frameOpt->frameShape ) {

            case QFrame::Box: {
                  if ( option->state & State_Sunken ) return true;
                  else break;
                  }

            case QFrame::HLine: {
                  _helper.drawSeparator( painter, option->rect, option->palette.color(QPalette::Window), Qt::Horizontal);
                  return true;
                  }

            case QFrame::VLine: {
                  _helper.drawSeparator( painter, option->rect, option->palette.color(QPalette::Window), Qt::Vertical);
                  return true;
                  }

            default:
                  break;

            }

      return false;

      }

bool MgStyle::drawTabBarTabLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      const QStyleOptionTab* tabOpt = qstyleoption_cast< const QStyleOptionTab* >(option);
      if ( !tabOpt ) return true;

      const bool selected( option->state & State_Selected );
      QStyleOptionTabV3 tabOptV3( *tabOpt );

      if(!widget)
            widget = QApplication::activeWindow();

      // add extra offset for selected tas
      switch ( tabOpt->shape ) {


            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth:
                  if ( selected ) tabOptV3.rect.translate( 0, -1 );
                  break;

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest:
                  if ( selected ) tabOptV3.rect.translate( -1, 0 );
                  break;

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast:
                  if ( selected ) tabOptV3.rect.translate( 1, 0 );
                  break;

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth:
                  if ( selected ) tabOptV3.rect.translate( 0, 1 );
                  break;

            default:
                  break;

            }

      // use QCommonStyle painting on tranlated rect
      QCommonStyle::drawControl( CE_TabBarTabLabel, &tabOptV3, painter, widget );
      return true;

      }

bool MgStyle::drawTabBarTabShapeControl_Single(const QStyleOption* option, QPainter* painter, const QWidget* widget) const {
      const QStyleOptionTab* tabOpt( qstyleoption_cast<const QStyleOptionTab*>(option) );
      if (!tabOpt)
            return true;

      const State& flags(option->state);
      const QRect& r(option->rect);
      const QPalette& palette(option->palette);

      const bool enabled(flags & State_Enabled);
      const bool selected(flags & State_Selected);
      const bool reverseLayout(option->direction == Qt::RightToLeft);

      if(!widget)
            widget = QApplication::activeWindow();

      // this is needed to complete the base frame when there are widgets in tabbar
      const QTabBar* tabBar(qobject_cast<const QTabBar*>(widget));
      const QRect tabBarRect(tabBar ? insideMargin(tabBar->rect(), -GlowWidth ) : QRect());

      // check if tab is being dragged
      const bool isDragged(selected && painter->device() != tabBar);

      // hover and animation flags
      /* all are disabled when tabBar is locked (drag in progress) */
      const bool tabBarLocked( tabBarData().locks( tabBar ) );
      const bool mouseOver( enabled && !tabBarLocked && (flags & State_MouseOver) );

      // animation state
      animations().tabBarEngine().updateState( widget, r.topLeft(), mouseOver );
      const bool animated( enabled && !selected && !tabBarLocked && animations().tabBarEngine().isAnimated( widget, r.topLeft() ) );

      // handle base frame painting, for tabbars in which tab is being dragged
      tabBarData().drawTabBarBaseControl(tabOpt, painter, widget);
      if (selected && tabBar && isDragged)
            tabBarData().lock( tabBar );
      else if ( selected  && tabBarData().locks( tabBar ) )
            tabBarData().release();

      // tab position and flags
      const QStyleOptionTab::TabPosition& position = tabOpt->position;
      const bool isFirst( position == QStyleOptionTab::OnlyOneTab || position == QStyleOptionTab::Beginning );
      const bool isRightOfSelected( tabOpt->selectedPosition == QStyleOptionTab::PreviousIsSelected );

      // document mode
      const QStyleOptionTabV3* tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3*>(option);
      bool documentMode = tabOptV3 ? tabOptV3->documentMode : false;
      const QTabWidget* tabWidget = (widget && widget->parentWidget()) ? qobject_cast<const QTabWidget*>(widget->parentWidget()) : NULL;
      documentMode |= (tabWidget ? tabWidget->documentMode() : true );

      // corner widgets
      const bool hasLeftCornerWidget( tabOpt->cornerWidgets & QStyleOptionTab::LeftCornerWidget );
      const bool hasRightCornerWidget( tabOpt->cornerWidgets & QStyleOptionTab::RightCornerWidget );

      // true if widget is alligned to the frame
      /* need to check for 'isRightOfSelected' because for some reason the isFirst flag is set when active tab is being moved */
      const bool isFrameAligned( !documentMode && isFirst && !hasLeftCornerWidget && !isRightOfSelected && !isDragged );

      // part of the tab in which the text is drawn
      QRect tabRect( r );

      // connection to the frame
      SlabRectList slabs;

      switch (tabOpt->shape) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth: {
                  // part of the tab in which the text is drawn
                  // larger tabs when selected
                  if ( selected )
                        tabRect.adjust( 0, -1, 0, 2 );
                  else
                        tabRect.adjust( 0, 1, 0, 2 );

                  // reduces the space between tabs
                  tabRect.adjust(-GlowWidth, 0, GlowWidth, 0);

                  // connection to the main frame
                  if ( selected ) {

                        // do nothing if dragged
                        if ( isDragged ) break;

                        // left side
                        if ( isFrameAligned && !reverseLayout ) {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - GlowWidth );
                              frameRect.setRight( tabRect.left() + 7 );
                              frameRect.setTop( tabRect.bottom() - 13 );
                              frameRect.setBottom( frameRect.bottom() + 7 - 1 );
                              slabs << SlabRect( frameRect, TileSet::Left );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - 7 );
                              frameRect.setRight( tabRect.left() + 7 + 3 );
                              frameRect.setTop( r.bottom() - 7 );
                              slabs << SlabRect( frameRect, TileSet::Top );
                              }

                        // right side
                        if ( isFrameAligned && reverseLayout ) {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 7 );
                              frameRect.setRight( frameRect.right() + GlowWidth );
                              frameRect.setTop( tabRect.bottom() - 13 );
                              frameRect.setBottom( frameRect.bottom() + 7 - 1 );
                              slabs << SlabRect( frameRect, TileSet::Right );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 7 - 3 );
                              frameRect.setRight( frameRect.right() + 7 );
                              frameRect.setTop( r.bottom() - 7 );
                              slabs << SlabRect( frameRect, TileSet::Top );

                              }

                        // extra base, to extend below inactive tabs and buttons
                        if ( tabBar ) {
                              if ( r.left() > tabBarRect.left() + 1 ) {
                                    QRect frameRect( r );
                                    frameRect.setLeft( tabBarRect.left() - 7 + 1 );
                                    frameRect.setRight( r.left() + 7 - 1 );
                                    frameRect.setTop( r.bottom() - 7 );
                                    if ( documentMode || reverseLayout ) slabs << SlabRect( frameRect, TileSet::Top );
                                    else slabs << SlabRect( frameRect, TileSet::TopLeft );

                                    }

                              if ( r.right() < tabBarRect.right() - 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setLeft( r.right() - 7 + 1 );
                                    frameRect.setRight( tabBarRect.right() + 7 - 1 );
                                    frameRect.setTop( r.bottom() - 7 );
                                    if ( documentMode || !reverseLayout ) slabs << SlabRect( frameRect, TileSet::Top );
                                    else slabs << SlabRect( frameRect, TileSet::TopRight );
                                    }
                              }

                        }
                  else if ( isFrameAligned ) {

                        if ( reverseLayout ) {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 7 );
                              frameRect.setRight( frameRect.right() + GlowWidth );
                              frameRect.setTop( tabRect.bottom() - 13 );
                              frameRect.setBottom( frameRect.bottom() + 7 - 2 );
                              slabs << SlabRect( frameRect, TileSet::Right );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - GlowWidth );
                              frameRect.setRight( tabRect.left() + 7 );
                              frameRect.setTop( tabRect.bottom() - 13 );
                              frameRect.setBottom( frameRect.bottom() + 7 - 2 );
                              slabs << SlabRect( frameRect, TileSet::Left );

                              }
                        }

                  break;

                  }

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth: {

                  // larger tabs when selected
                  if ( selected ) tabRect.adjust( 0, -2, 0, 1 );
                  else tabRect.adjust( 0, -2, 0, -1 );

                  // reduces the space between tabs
                  tabRect.adjust(-GlowWidth, 0, GlowWidth, 0);

                  // connection to the main frame
                  if ( selected ) {

                        // do nothing if dragged
                        if ( isDragged ) break;

                        // left side
                        if ( isFrameAligned && !reverseLayout ) {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - GlowWidth );
                              frameRect.setRight( tabRect.left() + 7 );
                              frameRect.setTop( frameRect.top() - 7 + 1 );
                              frameRect.setBottom( tabRect.top() + 13 );
                              slabs << SlabRect( frameRect, TileSet::Left );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - 7 );
                              frameRect.setRight( tabRect.left() + 7 + 3 );
                              frameRect.setBottom( r.top() + 7 );
                              slabs << SlabRect( frameRect, TileSet::Bottom );
                              }

                        // right side
                        if ( isFrameAligned && reverseLayout ) {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 7 );
                              frameRect.setRight( frameRect.right() + GlowWidth );
                              frameRect.setTop( frameRect.top() - 7 + 1 );
                              frameRect.setBottom( tabRect.top() + 13 );
                              slabs << SlabRect( frameRect, TileSet::Right );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 7 - 3 );
                              frameRect.setRight( frameRect.right() + 7 );
                              frameRect.setBottom( r.top() + 7 );
                              slabs << SlabRect( frameRect, TileSet::Bottom );

                              }

                        // extra base, to extend below tabbar buttons
                        if ( tabBar ) {
                              if ( r.left() > tabBarRect.left() + 1 ) {
                                    QRect frameRect( r );
                                    frameRect.setLeft( tabBarRect.left() - 7 + 1 );
                                    frameRect.setRight( r.left() + 7 - 1 );
                                    frameRect.setBottom( r.top() + 7 );
                                    if ( documentMode || reverseLayout ) slabs << SlabRect( frameRect, TileSet::Bottom );
                                    else slabs << SlabRect( frameRect, TileSet::BottomLeft );
                                    }

                              if ( r.right() < tabBarRect.right() - 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setLeft( r.right() - 7 + 1 );
                                    frameRect.setRight( tabBarRect.right() + 7 - 1 );
                                    frameRect.setBottom( r.top() + 7 );
                                    if ( documentMode || !reverseLayout ) slabs << SlabRect( frameRect, TileSet::Bottom );
                                    else slabs << SlabRect( frameRect, TileSet::BottomRight );
                                    }

                              }

                        }
                  else if ( isFrameAligned ) {

                        if ( reverseLayout ) {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 7 );
                              frameRect.setRight( frameRect.right() + GlowWidth );
                              frameRect.setTop( frameRect.top() - 7 + 2 );
                              frameRect.setBottom( tabRect.top() + 13 );
                              slabs << SlabRect( frameRect, TileSet::Right );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - GlowWidth );
                              frameRect.setRight( tabRect.left() + 7 );
                              frameRect.setTop( frameRect.top() - 7 + 2 );
                              frameRect.setBottom( tabRect.top() + 13 );
                              slabs << SlabRect( frameRect, TileSet::Left );

                              }
                        }

                  break;

                  }

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest: {

                  // larger tabs when selected
                  if ( selected ) tabRect.adjust( -1, 0, 2, 0 );
                  else tabRect.adjust( 1, 0, 2, 0 );

                  // reduces the space between tabs
                  tabRect.adjust( 0, -GlowWidth, 0, GlowWidth );

                  // connection to the main frame
                  if ( selected ) {

                        // do nothing if dragged
                        if ( isDragged ) break;

                        // top side
                        if ( isFrameAligned ) {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 13 );
                              frameRect.setRight( frameRect.right() + 7 - 1 );
                              frameRect.setTop( frameRect.top() - GlowWidth );
                              frameRect.setBottom( tabRect.top() + 7 );
                              slabs << SlabRect( frameRect, TileSet::Top );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( r.right() - 7 );
                              frameRect.setTop( frameRect.top() - 7 );
                              frameRect.setBottom( tabRect.top() + 7 + 3 );
                              slabs << SlabRect( frameRect, TileSet::Left );
                              }

                        // bottom side
                        QRect frameRect( r );
                        frameRect.setLeft( r.right() - 7 );
                        frameRect.setTop( tabRect.bottom() - 7 - 3 );
                        frameRect.setBottom( frameRect.bottom() + 7 );
                        slabs << SlabRect( frameRect, TileSet::Left );

                        // extra base, to extend below tabbar buttons
                        if ( tabBar ) {
                              if ( r.top() > tabBarRect.top() + 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setTop( tabBarRect.top() - 7 + 1 );
                                    frameRect.setBottom( r.top() + 7 - 1 );
                                    frameRect.setLeft( r.right() - 7 );
                                    if ( documentMode ) slabs << SlabRect( frameRect, TileSet::Left );
                                    else slabs << SlabRect( frameRect, TileSet::TopLeft );
                                    }

                              if ( r.bottom() < tabBarRect.bottom() - 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setTop( r.bottom() - 7 + 1 );
                                    if ( hasRightCornerWidget && documentMode ) frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
                                    else frameRect.setBottom( tabBarRect.bottom() + 7 );
                                    frameRect.setLeft( r.right() - 7 );
                                    slabs << SlabRect( frameRect, TileSet::Left );

                                    }
                              }

                        }
                  else if ( isFrameAligned ) {

                        QRect frameRect( r );
                        frameRect.setLeft( tabRect.right() - 13 );
                        frameRect.setRight( frameRect.right() + 7 - 2 );
                        frameRect.setTop( frameRect.top() - GlowWidth );
                        frameRect.setBottom( tabRect.top() + 7 );
                        slabs << SlabRect( frameRect, TileSet::Top );

                        }

                  break;
                  }

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast: {

                  // larger tabs when selected
                  if ( selected ) tabRect.adjust( -2, 0, 1, 0 );
                  else tabRect.adjust( -2, 0, -1, 0 );

                  // reduces the space between tabs
                  tabRect.adjust( 0, -GlowWidth, 0, GlowWidth );

                  // connection to the main frame
                  if ( selected ) {

                        // do nothing if dragged
                        if ( isDragged ) break;

                        // top side
                        if ( isFrameAligned ) {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - 7 + 1 );
                              frameRect.setRight( tabRect.left() + 13 );
                              frameRect.setTop( frameRect.top() - GlowWidth );
                              frameRect.setBottom( tabRect.top() + 7 );
                              slabs << SlabRect( frameRect, TileSet::Top );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setRight( r.left() + 7 );
                              frameRect.setTop( frameRect.top() - 7 );
                              frameRect.setBottom( tabRect.top() + 7 + 3 );
                              slabs << SlabRect( frameRect, TileSet::Right );
                              }

                        // bottom side
                        QRect frameRect( r );
                        frameRect.setRight( r.left() + 7 );
                        frameRect.setTop( tabRect.bottom() - 7 - 3 );
                        frameRect.setBottom( frameRect.bottom() + 7 );
                        slabs << SlabRect( frameRect, TileSet::Right );

                        // extra base, to extend below tabbar buttons
                        if ( tabBar ) {
                              if ( r.top() > tabBarRect.top() + 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setTop( tabBarRect.top() - 7 + 1 );
                                    frameRect.setBottom( r.top() + 7 - 1 );
                                    frameRect.setRight( r.left() + 7 );
                                    if ( documentMode ) slabs << SlabRect( frameRect, TileSet::Right );
                                    else slabs << SlabRect( frameRect, TileSet::TopRight );
                                    }

                              if ( r.bottom() < tabBarRect.bottom() - 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setTop( r.bottom() - 7 + 1 );
                                    if ( hasRightCornerWidget && documentMode ) frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
                                    else frameRect.setBottom( tabBarRect.bottom() + 7 );
                                    frameRect.setRight( r.left() + 7 );
                                    slabs << SlabRect( frameRect, TileSet::Right );

                                    }
                              }

                        }
                  else if ( isFrameAligned ) {

                        QRect frameRect( r );
                        frameRect.setLeft( frameRect.left() - 7 + 2 );
                        frameRect.setRight( tabRect.left() + 13 );
                        frameRect.setTop( frameRect.top() - GlowWidth );
                        frameRect.setBottom( tabRect.top() + 7 );
                        slabs << SlabRect( frameRect, TileSet::Top );

                        }

                  break;
                  }

            default:
                  break;
            }


      // slab options
      StyleOptions slabOptions( NoFill );
      if ( MgStyleConfigData::tabSubtleShadow)
            slabOptions |= SubtleShadow;
      if ((!selected) && (mouseOver || animated))
            slabOptions |= Hover;

      // color
      const QColor color( palette.color(QPalette::Window) );

      // render connections to frame
      // extra care must be taken care of so that no slab
      // extends beyond tabWidget frame, if any
      const bool verticalTabs( isVerticalTab( tabOpt ) );
      const QRect tabWidgetRect( tabWidget ?
                                 insideMargin( tabWidget->rect(), -GlowWidth ).translated( -widget->geometry().topLeft() ) :
                                 QRect() );

      foreach( SlabRect slab, slabs ) { // krazy:exclude=foreach
            adjustSlabRect( slab, tabWidgetRect, documentMode, verticalTabs );
            if (selected || !animated )
                  renderSlab( painter, slab, color, slabOptions );
            else {
                  const qreal opacity( animations().tabBarEngine().opacity( widget, r.topLeft() ) );
                  renderSlab( painter, slab, color, slabOptions, opacity, AnimationHover);
                  }
            }

      //  adjust clip rect and render tabs
      if ( tabBar ) {
            painter->save();
            painter->setClipRegion( tabBarClipRegion( tabBar ) );
            }

      // draw tab
      TileSet::Tiles tiles(tilesByShape(tabOpt->shape));
      if (selected) {
            // render window background in case of dragged tabwidget
            if (isDragged)
                  fillTabBackground(painter, tabRect, color, tabOpt->shape, widget);
            renderSlab(painter, tabRect, color, slabOptions, tiles);
            }
      else if (animated) {
            const qreal opacity(animations().tabBarEngine().opacity(widget, r.topLeft()));
            renderSlab(painter, tabRect, color, slabOptions, opacity, AnimationHover, tiles);
            }
      else
            renderSlab(painter, tabRect, color, slabOptions, tiles);

      // fill tab
      fillTab(painter, tabRect, color, tabOpt->shape, selected);

      // restore clip region
      if (tabBar)
            painter->restore();

      return true;
      }

bool MgStyle::drawTabBarTabShapeControl_Plain( const QStyleOption* option, QPainter* painter, const QWidget* widget) const {

      const QStyleOptionTab* tabOpt( qstyleoption_cast<const QStyleOptionTab*>(option) );
      if ( !tabOpt ) return true;

      const State& flags( option->state );
      const QRect& r( option->rect );
      const QPalette& palette( option->palette );

      const bool enabled( flags & State_Enabled );
      const bool selected( flags & State_Selected );
      const bool reverseLayout( option->direction == Qt::RightToLeft );

      if(!widget)
            widget = QApplication::activeWindow();

      // tab position and flags
      const QStyleOptionTab::TabPosition& position = tabOpt->position;
      bool isFirst( position == QStyleOptionTab::OnlyOneTab || position == QStyleOptionTab::Beginning );
      bool isLast( position == QStyleOptionTab::OnlyOneTab || position == QStyleOptionTab::End );
      bool isLeftOfSelected( tabOpt->selectedPosition == QStyleOptionTab::NextIsSelected );
      bool isRightOfSelected( tabOpt->selectedPosition == QStyleOptionTab::PreviousIsSelected );

      // document mode
      const QStyleOptionTabV3* tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3*>(option);
      bool documentMode = tabOptV3 ? tabOptV3->documentMode : false;
      const QTabWidget* tabWidget = (widget && widget->parentWidget()) ? qobject_cast<const QTabWidget*>(widget->parentWidget()) : NULL;
      documentMode |= (tabWidget ? tabWidget->documentMode() : true );

      // this is needed to complete the base frame when there are widgets in tabbar
      const QTabBar* tabBar( qobject_cast<const QTabBar*>( widget ) );
      const QRect tabBarRect( tabBar ? insideMargin( tabBar->rect(), -GlowWidth ) : QRect() );

      // check if tab is being dragged
      const bool isDragged( selected && painter->device() != tabBar );

      // hover and animation flags
      /* all are disabled when tabBar is locked (drag in progress) */
      const bool tabBarLocked( tabBarData().locks( tabBar ) );
      const bool mouseOver( enabled && !tabBarLocked && (flags & State_MouseOver) );

      // animation state
      animations().tabBarEngine().updateState( widget, r.topLeft(), mouseOver );
      const bool animated( enabled && !selected && !tabBarLocked && animations().tabBarEngine().isAnimated( widget, r.topLeft() ) );

      // handle base frame painting, for tabbars in which tab is being dragged
      tabBarData().drawTabBarBaseControl( tabOpt, painter, widget );
      if ( selected && tabBar && isDragged ) tabBarData().lock( tabBar );
      else if ( selected  && tabBarData().locks( tabBar ) ) tabBarData().release();

      // corner widgets
      const bool hasLeftCornerWidget( tabOpt->cornerWidgets & QStyleOptionTab::LeftCornerWidget );
      const bool hasRightCornerWidget( tabOpt->cornerWidgets & QStyleOptionTab::RightCornerWidget );

      // true if widget is alligned to the frame
      /* need to check for 'isRightOfSelected' because for some reason the isFirst flag is set when active tab is being moved */
      const bool isFrameAligned( !documentMode && isFirst && !hasLeftCornerWidget && !isRightOfSelected && !isDragged );
      isFirst &= !isRightOfSelected;
      isLast &= !isLeftOfSelected;

      // swap flags based on reverse layout, so that they become layout independent
      const bool verticalTabs( isVerticalTab( tabOpt ) );
      if ( reverseLayout && !verticalTabs ) {
            qSwap( isFirst, isLast );
            qSwap( isLeftOfSelected, isRightOfSelected );
            }

      const qreal radius = 5;

      // part of the tab in which the text is drawn
      QRect tabRect( r );
      QPainterPath path;

      // connection to the frame
      SlabRectList slabs;

      // highlighted slab (if any)
      SlabRect highlightSlab;

      switch ( tabOpt->shape ) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth: {

                  // part of the tab in which the text is drawn
                  // larger tabs when selected
                  if ( selected ) tabRect.adjust( 0, -1, 0, 2 );
                  else tabRect.adjust( 0, 3, 1, -7 + 1 );

                  // connection to the main frame
                  if ( selected ) {

                        // reduces the space between tabs
                        tabRect.adjust(-GlowWidth, 0, GlowWidth, 0);

                        // do nothing if dragged
                        if ( isDragged ) break;

                        // left side
                        if ( isFrameAligned && !reverseLayout ) {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - GlowWidth );
                              frameRect.setRight( tabRect.left() + 7 );
                              frameRect.setTop( tabRect.bottom() - 13 );
                              frameRect.setBottom( frameRect.bottom() + 7 - 1 );
                              slabs << SlabRect( frameRect, TileSet::Left );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - 7 );
                              frameRect.setRight( tabRect.left() + 7 + 3 );
                              frameRect.setTop( r.bottom() - 7 );
                              slabs << SlabRect( frameRect, TileSet::Top );
                              }

                        // right side
                        if ( isFrameAligned && reverseLayout ) {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 7 );
                              frameRect.setRight( frameRect.right() + GlowWidth );
                              frameRect.setTop( tabRect.bottom() - 13 );
                              frameRect.setBottom( frameRect.bottom() + 7 - 1 );
                              slabs << SlabRect( frameRect, TileSet::Right );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 7 - 3 );
                              frameRect.setRight( frameRect.right() + 7 );
                              frameRect.setTop( r.bottom() - 7 );
                              slabs << SlabRect( frameRect, TileSet::Top );

                              }

                        // extra base, to extend below inactive tabs and buttons
                        if ( tabBar ) {
                              if ( r.left() > tabBarRect.left() + 1 ) {
                                    QRect frameRect( r );
                                    frameRect.setLeft( tabBarRect.left() - 7 + 1 );
                                    frameRect.setRight( r.left() + 7 - 1 );
                                    frameRect.setTop( r.bottom() - 7 );
                                    if ( documentMode || reverseLayout ) slabs << SlabRect( frameRect, TileSet::Top );
                                    else slabs << SlabRect( frameRect, TileSet::TopLeft );

                                    }

                              if ( r.right() < tabBarRect.right() - 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setLeft( r.right() - 7 + 1 );
                                    frameRect.setRight( tabBarRect.right() + 7 - 1);
                                    frameRect.setTop( r.bottom() - 7 );
                                    if ( documentMode || !reverseLayout ) slabs << SlabRect( frameRect, TileSet::Top );
                                    else slabs << SlabRect( frameRect, TileSet::TopRight );
                                    }
                              }

                        }
                  else {

                        // adjust sides when slab is adjacent to selected slab
                        if ( isLeftOfSelected ) tabRect.setRight( tabRect.right() + 2 );
                        else if ( isRightOfSelected ) tabRect.setLeft( tabRect.left() - 2 );

                        if ( isFirst ) {

                              tabRect.adjust( GlowWidth, 0, 0, 0 );
                              if ( isFrameAligned ) path.moveTo( tabRect.bottomLeft() + QPoint( 0, 2 ) );
                              else path.moveTo( tabRect.bottomLeft() );
                              path.lineTo( tabRect.topLeft() + QPointF( 0, radius ) );
                              path.quadTo( tabRect.topLeft(), tabRect.topLeft() + QPoint( radius, 0 ) );
                              path.lineTo( tabRect.topRight() );
                              path.lineTo( tabRect.bottomRight() );


                              }
                        else if ( isLast ) {

                              tabRect.adjust( 0, 0, -GlowWidth - 1, 0 );
                              path.moveTo( tabRect.bottomLeft() );
                              path.lineTo( tabRect.topLeft() );
                              path.lineTo( tabRect.topRight() - QPointF( radius, 0 ) );
                              path.quadTo( tabRect.topRight(), tabRect.topRight() + QPointF( 0, radius ) );
                              if ( isFrameAligned ) path.lineTo( tabRect.bottomRight() + QPointF( 0, 2 ) );
                              else path.lineTo( tabRect.bottomRight() );

                              }
                        else {

                              path.moveTo( tabRect.bottomLeft() );
                              path.lineTo( tabRect.topLeft() );
                              path.lineTo( tabRect.topRight() );
                              path.lineTo( tabRect.bottomRight() );

                              }

                        // highlight
                        QRect highlightRect( tabRect.left(), tabRect.bottom() - 1, tabRect.width(), 7 );
                        if ( isFrameAligned && isFirst ) highlightSlab = SlabRect( highlightRect.adjusted( -2, 0, 7 + 1, 0 ), TileSet::TopLeft );
                        else if ( isFrameAligned && isLast ) highlightSlab = SlabRect( highlightRect.adjusted( -7, 0, 2, 0 ), TileSet::TopRight );
                        else highlightSlab = SlabRect( highlightRect.adjusted( -7, 0, 7, 0 ), TileSet::Top );

                        }

                  break;

                  }

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth: {

                  // larger tabs when selected
                  if ( selected ) tabRect.adjust( 0, -2, 0, 1 );
                  else tabRect.adjust( 0, 7 - 1, 1, -3 );

                  // connection to the main frame
                  if ( selected ) {

                        // reduces the space between tabs
                        tabRect.adjust(-GlowWidth, 0, GlowWidth, 0);

                        // do nothing if dragged
                        if ( isDragged ) break;

                        // left side
                        if ( isFrameAligned && !reverseLayout ) {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - GlowWidth );
                              frameRect.setRight( tabRect.left() + 7 );
                              frameRect.setTop( frameRect.top() - 7 + 1 );
                              frameRect.setBottom( tabRect.top() + 13 );
                              slabs << SlabRect( frameRect, TileSet::Left );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - 7 );
                              frameRect.setRight( tabRect.left() + 7 + 3 );
                              frameRect.setBottom( r.top() + 7 );
                              slabs << SlabRect( frameRect, TileSet::Bottom );
                              }

                        // right side
                        if ( isFrameAligned && reverseLayout ) {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 7 );
                              frameRect.setRight( frameRect.right() + GlowWidth );
                              frameRect.setTop( frameRect.top() - 7 + 1 );
                              frameRect.setBottom( tabRect.top() + 13 );
                              slabs << SlabRect( frameRect, TileSet::Right );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 7 - 3 );
                              frameRect.setRight( frameRect.right() + 7 );
                              frameRect.setBottom( r.top() + 7 );
                              slabs << SlabRect( frameRect, TileSet::Bottom );

                              }

                        // extra base, to extend below tabbar buttons
                        if ( tabBar ) {
                              if ( r.left() > tabBarRect.left() + 1 ) {
                                    QRect frameRect( r );
                                    frameRect.setLeft( tabBarRect.left() - 7 + 1);
                                    frameRect.setRight( r.left() + 7 - 1 );
                                    frameRect.setBottom( r.top() + 7 );
                                    if ( documentMode || reverseLayout ) slabs << SlabRect( frameRect, TileSet::Bottom );
                                    else slabs << SlabRect( frameRect, TileSet::BottomLeft );
                                    }

                              if ( r.right() < tabBarRect.right() - 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setLeft( r.right() - 7 + 1 );
                                    frameRect.setRight( tabBarRect.right() + 7 - 1 );
                                    frameRect.setBottom( r.top() + 7 );
                                    if ( documentMode || !reverseLayout ) slabs << SlabRect( frameRect, TileSet::Bottom );
                                    else slabs << SlabRect( frameRect, TileSet::BottomRight );
                                    }

                              }

                        }
                  else {

                        // adjust sides when slab is adjacent to selected slab
                        if ( isLeftOfSelected ) tabRect.setRight( tabRect.right() + 2 );
                        else if ( isRightOfSelected ) tabRect.setLeft( tabRect.left() - 2 );

                        if ( isFirst ) {

                              tabRect.adjust( GlowWidth, 0, 0, 0 );
                              if ( isFrameAligned ) path.moveTo( tabRect.topLeft() - QPoint( 0, 2 ) );
                              else path.moveTo( tabRect.topLeft() );
                              path.lineTo( tabRect.bottomLeft() - QPointF( 0, radius ) );
                              path.quadTo( tabRect.bottomLeft(), tabRect.bottomLeft() + QPoint( radius, 0 ) );
                              path.lineTo( tabRect.bottomRight() );
                              path.lineTo( tabRect.topRight() );

                              }
                        else if ( isLast ) {

                              tabRect.adjust( 0, 0, -GlowWidth - 1, 0 );
                              path.moveTo( tabRect.topLeft() );
                              path.lineTo( tabRect.bottomLeft() );
                              path.lineTo( tabRect.bottomRight() - QPointF( radius, 0 ) );
                              path.quadTo( tabRect.bottomRight(), tabRect.bottomRight() - QPointF( 0, radius ) );
                              if ( isFrameAligned ) path.lineTo( tabRect.topRight() - QPointF( 0, 2 ) );
                              else path.lineTo( tabRect.topRight() );

                              }
                        else {

                              path.moveTo( tabRect.topLeft() );
                              path.lineTo( tabRect.bottomLeft() );
                              path.lineTo( tabRect.bottomRight() );
                              path.lineTo( tabRect.topRight() );

                              }

                        // highlight
                        QRect highlightRect( tabRect.left(), tabRect.top() - 5, tabRect.width(), 7 );
                        if ( isFrameAligned && isFirst ) highlightSlab = SlabRect( highlightRect.adjusted( -2, 0, 7 + 1, 0 ), TileSet::BottomLeft );
                        else if ( isFrameAligned && isLast ) highlightSlab = SlabRect( highlightRect.adjusted( -7, 0, 2, 0 ), TileSet::BottomRight );
                        else highlightSlab = SlabRect( highlightRect.adjusted( -7, 0, 7, 0 ), TileSet::Bottom );

                        }

                  break;

                  }

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest: {

                  // larger tabs when selected
                  if ( selected ) tabRect.adjust( -1, 0, 2, 0 );
                  else tabRect.adjust( 3, 0, -7 + 1, 1 );

                  // connection to the main frame
                  if ( selected ) {

                        // reduces the space between tabs
                        tabRect.adjust( 0, -GlowWidth, 0, GlowWidth );

                        // do nothing if dragged
                        if ( isDragged ) break;

                        // top side
                        if ( isFrameAligned ) {

                              QRect frameRect( r );
                              frameRect.setLeft( tabRect.right() - 13 );
                              frameRect.setRight( frameRect.right() + 7 - 1 );
                              frameRect.setTop( frameRect.top() - GlowWidth );
                              frameRect.setBottom( tabRect.top() + 7 );
                              slabs << SlabRect( frameRect, TileSet::Top );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setLeft( r.right() - 7 );
                              frameRect.setTop( frameRect.top() - 7 );
                              frameRect.setBottom( tabRect.top() + 7 + 3 );
                              slabs << SlabRect( frameRect, TileSet::Left );
                              }

                        // bottom side
                        QRect frameRect( r );
                        frameRect.setLeft( r.right() - 7 );
                        frameRect.setTop( tabRect.bottom() - 7 - 3 );
                        frameRect.setBottom( frameRect.bottom() + 7 );
                        slabs << SlabRect( frameRect, TileSet::Left );

                        // extra base, to extend below tabbar buttons
                        if ( tabBar ) {
                              if ( r.top() > tabBarRect.top() + 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setTop( tabBarRect.top() - 7 + 1 );
                                    frameRect.setBottom( r.top() + 7 - 1 );
                                    frameRect.setLeft( r.right() - 7 );
                                    if ( documentMode ) slabs << SlabRect( frameRect, TileSet::Left );
                                    else slabs << SlabRect( frameRect, TileSet::TopLeft );
                                    }

                              if ( r.bottom() < tabBarRect.bottom() - 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setTop( r.bottom() - 7 + 1 );
                                    if ( hasRightCornerWidget && documentMode ) frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
                                    else frameRect.setBottom( tabBarRect.bottom() + 7 );
                                    frameRect.setLeft( r.right() - 7 );
                                    slabs << SlabRect( frameRect, TileSet::Left );

                                    }
                              }

                        }
                  else {

                        // adjust sides when slab is adjacent to selected slab
                        if ( isLeftOfSelected ) tabRect.setBottom( tabRect.bottom() + 2 );
                        else if ( isRightOfSelected ) tabRect.setTop( tabRect.top() - 2 );

                        if ( isFirst ) {

                              tabRect.adjust( 0, GlowWidth, 0, 0 );
                              if ( isFrameAligned ) path.moveTo( tabRect.topRight() + QPoint( 2, 0 ) );
                              else path.moveTo( tabRect.topRight() );
                              path.lineTo( tabRect.topLeft() + QPointF( radius, 0 ) );
                              path.quadTo( tabRect.topLeft(), tabRect.topLeft() + QPoint( 0, radius ) );
                              path.lineTo( tabRect.bottomLeft() );
                              path.lineTo( tabRect.bottomRight() );

                              }
                        else if ( isLast ) {

                              tabRect.adjust( 0, 0, 0, -GlowWidth );
                              path.moveTo( tabRect.topRight() );
                              path.lineTo( tabRect.topLeft() );
                              path.lineTo( tabRect.bottomLeft() - QPointF( 0, radius ) );
                              path.quadTo( tabRect.bottomLeft(), tabRect.bottomLeft() + QPointF( radius, 0 ) );
                              path.lineTo( tabRect.bottomRight() );

                              }
                        else {

                              path.moveTo( tabRect.topRight() );
                              path.lineTo( tabRect.topLeft() );
                              path.lineTo( tabRect.bottomLeft() );
                              path.lineTo( tabRect.bottomRight() );

                              }

                        // highlight
                        QRect highlightRect( tabRect.right() - 1, tabRect.top(), 7, tabRect.height() );
                        if ( isFrameAligned && isFirst ) highlightSlab = SlabRect( highlightRect.adjusted( 0, -2, 0, 7 + 1 ), TileSet::TopLeft );
                        else if ( isFrameAligned && isLast ) highlightSlab = SlabRect( highlightRect.adjusted( 0, -7, 0, 2 ), TileSet::BottomLeft );
                        else highlightSlab = SlabRect( highlightRect.adjusted( 0, -7 + 1, 0, 7 + 1 ), TileSet::Left );

                        }

                  break;
                  }

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast: {

                  // larger tabs when selected
                  if ( selected ) tabRect.adjust( -2, 0, 1, 0 );
                  else tabRect.adjust( 7 - 1, 0, -3, 1 );

                  // connection to the main frame
                  if ( selected ) {

                        // reduces the space between tabs
                        tabRect.adjust( 0, -GlowWidth, 0, GlowWidth );

                        // do nothing if dragged
                        if ( isDragged ) break;

                        // top side
                        if ( isFrameAligned ) {

                              QRect frameRect( r );
                              frameRect.setLeft( frameRect.left() - 7 + 1 );
                              frameRect.setRight( tabRect.left() + 13 );
                              frameRect.setTop( frameRect.top() - GlowWidth );
                              frameRect.setBottom( tabRect.top() + 7 );
                              slabs << SlabRect( frameRect, TileSet::Top );

                              }
                        else {

                              QRect frameRect( r );
                              frameRect.setRight( r.left() + 7 );
                              frameRect.setTop( frameRect.top() - 7 );
                              frameRect.setBottom( tabRect.top() + 7 + 3 );
                              slabs << SlabRect( frameRect, TileSet::Right );
                              }

                        // bottom side
                        QRect frameRect( r );
                        frameRect.setRight( r.left() + 7 );
                        frameRect.setTop( tabRect.bottom() - 7 - 3 );
                        frameRect.setBottom( frameRect.bottom() + 7 );
                        slabs << SlabRect( frameRect, TileSet::Right );

                        // extra base, to extend below tabbar buttons
                        if ( tabBar ) {
                              if ( r.top() > tabBarRect.top() + 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setTop( tabBarRect.top() - 7 + 1 );
                                    frameRect.setBottom( r.top() + 7 - 1 );
                                    frameRect.setRight( r.left() + 7 );
                                    if ( documentMode ) slabs << SlabRect( frameRect, TileSet::Right );
                                    else slabs << SlabRect( frameRect, TileSet::TopRight );
                                    }

                              if ( r.bottom() < tabBarRect.bottom() - 1 ) {

                                    QRect frameRect( r );
                                    frameRect.setTop( r.bottom() - 7 + 1 );
                                    if ( hasRightCornerWidget && documentMode ) frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
                                    else frameRect.setBottom( tabBarRect.bottom() + 7 );
                                    frameRect.setRight( r.left() + 7 );
                                    slabs << SlabRect( frameRect, TileSet::Right );

                                    }
                              }

                        }
                  else {

                        // adjust sides when slab is adjacent to selected slab
                        if ( isLeftOfSelected ) tabRect.setBottom( tabRect.bottom() + 2 );
                        else if ( isRightOfSelected ) tabRect.setTop( tabRect.top() - 2 );

                        if ( isFirst ) {

                              tabRect.adjust( 0, GlowWidth, 0, 0 );
                              if ( isFrameAligned ) path.moveTo( tabRect.topLeft() - QPoint( 2, 0 ) );
                              else path.moveTo( tabRect.topLeft() );
                              path.lineTo( tabRect.topRight() - QPointF( radius, 0 ) );
                              path.quadTo( tabRect.topRight(), tabRect.topRight() + QPoint( 0, radius ) );
                              path.lineTo( tabRect.bottomRight() );
                              path.lineTo( tabRect.bottomLeft() );

                              }
                        else if ( isLast ) {

                              tabRect.adjust( 0, 0, 0, -GlowWidth );
                              path.moveTo( tabRect.topLeft() );
                              path.lineTo( tabRect.topRight() );
                              path.lineTo( tabRect.bottomRight() - QPointF( 0, radius ) );
                              path.quadTo( tabRect.bottomRight(), tabRect.bottomRight() - QPointF( radius, 0 ) );
                              path.lineTo( tabRect.bottomLeft() );

                              }
                        else {

                              path.moveTo( tabRect.topLeft() );
                              path.lineTo( tabRect.topRight() );
                              path.lineTo( tabRect.bottomRight() );
                              path.lineTo( tabRect.bottomLeft() );

                              }

                        // highlight
                        QRect highlightRect( tabRect.left() - 5, tabRect.top(), 7, tabRect.height() );
                        if ( isFrameAligned && isFirst ) highlightSlab = SlabRect( highlightRect.adjusted( 0, -2, 0, 7 + 1 ), TileSet::TopRight );
                        else if ( isFrameAligned && isLast ) highlightSlab = SlabRect( highlightRect.adjusted( 0, -7, 0, 2 ), TileSet::BottomRight );
                        else highlightSlab = SlabRect( highlightRect.adjusted( 0, -7 + 1, 0, 7 + 1 ), TileSet::Right );

                        }

                  break;
                  }

            default:
                  break;
            }

      const QColor color( palette.color(QPalette::Window) );

      // render connections to frame
      // extra care must be taken care of so that no slab
      // extends beyond tabWidget frame, if any
      const QRect tabWidgetRect( tabWidget ?
                                 insideMargin( tabWidget->rect(), -GlowWidth ).translated( -widget->geometry().topLeft() ) :
                                 QRect() );

      foreach( SlabRect slab, slabs ) { // krazy:exclude=foreach
            adjustSlabRect( slab, tabWidgetRect, documentMode, verticalTabs );
            renderSlab( painter, slab, color, NoFill );
            }

      //  adjust clip rect and render tab
      if ( tabBar ) {
            painter->save();
            painter->setClipRegion( tabBarClipRegion( tabBar ) );
            }

      // fill tab
      if ( selected ) {

            // render window background in case of dragged tabwidget
            if ( isDragged ) fillTabBackground( painter, tabRect, color, tabOpt->shape, widget );

            // slab options
            StyleOptions selectedTabOpts( NoFill );
            if ( MgStyleConfigData::tabSubtleShadow) selectedTabOpts |= SubtleShadow;

            TileSet::Tiles tiles( tilesByShape( tabOpt->shape ) );
            renderSlab( painter, tabRect, color, selectedTabOpts, tiles );
            fillTab( painter, tabRect, color, tabOpt->shape, selected );

            }
      else {

            const QColor backgroundColor = _helper.backgroundColor( color, widget, r.center() );
            const QColor midColor = _helper.alphaColor(_helper.calcDarkColor(backgroundColor), 0.4);
            const QColor darkColor = _helper.alphaColor(_helper.calcDarkColor(backgroundColor), 0.6);

            painter->save();
            painter->translate( 0.5, 0.5 );
            painter->setRenderHints( QPainter::Antialiasing );
            painter->setPen(darkColor);
            painter->setBrush(midColor);
            painter->drawPath( path );
            painter->restore();

            }

      // restore clip region
      if ( tabBar ) painter->restore();

      // hovered highlight
      if ( (animated || mouseOver) && highlightSlab._r.isValid() ) {

            const qreal opacity( animations().tabBarEngine().opacity( widget, r.topLeft() ) );
            const StyleOptions hoverTabOpts( NoFill | Hover );
            adjustSlabRect( highlightSlab, tabWidgetRect, documentMode, verticalTabs );

            // pass an invalid color to have only the glow painted
            if ( animated ) renderSlab( painter, highlightSlab, QColor(), hoverTabOpts, opacity, AnimationHover);
            else renderSlab( painter, highlightSlab, QColor(), hoverTabOpts );

            }


      return true;

      }

void MgStyle::TabBarData::drawTabBarBaseControl( const QStyleOptionTab* tabOpt, QPainter* painter, const QWidget* widget) {

      // check parent
      if ( !_style ) return;

      if(!widget)
            widget = QApplication::activeWindow();

      // make sure widget is locked
      if ( !locks( widget ) ) return;

      // make sure dirty flag is set
      if ( !_dirty ) return;

      // cast to TabBar and check
      const QTabBar* tabBar( qobject_cast<const QTabBar*>( widget ) );
      if ( !tabBar ) return;

      // get reverseLayout flag
      const bool reverseLayout( tabOpt->direction == Qt::RightToLeft );

      // get documentMode flag
      const QStyleOptionTabV3* tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3*>(tabOpt);
      bool documentMode = tabOptV3 ? tabOptV3->documentMode : false;
      const QTabWidget* tabWidget = (widget && widget->parentWidget()) ? qobject_cast<const QTabWidget*>(widget->parentWidget()) : NULL;
      documentMode |= (tabWidget ? tabWidget->documentMode() : true );

      const QRect tabBarRect( _style.data()->insideMargin( tabBar->rect(), -GlowWidth ) );

      // define slab
      MgStyle::SlabRect slab;

      // switch on tab shape
      switch ( tabOpt->shape ) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth: {
                  TileSet::Tiles tiles( TileSet::Top );
                  QRect frameRect;
                  frameRect.setLeft( tabBarRect.left() - 7 + 1 );
                  frameRect.setRight( tabBarRect.right() + 7 - 1 );
                  frameRect.setTop( tabBarRect.bottom() - 8 );
                  frameRect.setHeight( 4 );
                  if ( !( documentMode || reverseLayout ) ) tiles |= TileSet::Left;
                  if ( !documentMode && reverseLayout ) tiles |= TileSet::Right;
                  slab = SlabRect( frameRect, tiles );
                  break;
                  }

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth: {
                  TileSet::Tiles tiles( TileSet::Bottom );
                  QRect frameRect;
                  frameRect.setLeft( tabBarRect.left() - 7 + 1 );
                  frameRect.setRight( tabBarRect.right() + 7 - 1 );
                  frameRect.setBottom( tabBarRect.top() + 8 );
                  frameRect.setTop( frameRect.bottom() - 4 );
                  if ( !( documentMode || reverseLayout ) ) tiles |= TileSet::Left;
                  if ( !documentMode && reverseLayout ) tiles |= TileSet::Right;
                  slab = SlabRect( frameRect, tiles );
                  break;
                  }

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest: {
                  TileSet::Tiles tiles( TileSet::Left );
                  QRect frameRect;
                  frameRect.setTop( tabBarRect.top() - 7 + 1 );
                  frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
                  frameRect.setLeft( tabBarRect.right() - 8 );
                  frameRect.setWidth( 4 );
                  if ( !( documentMode || reverseLayout ) ) tiles |= TileSet::Top;
                  if ( !documentMode && reverseLayout ) tiles |= TileSet::Bottom;
                  slab = SlabRect( frameRect, tiles );
                  break;
                  }

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast: {
                  TileSet::Tiles tiles( TileSet::Right );
                  QRect frameRect;
                  frameRect.setTop( tabBarRect.top() - 7 + 1 );
                  frameRect.setBottom( tabBarRect.bottom() + 7 - 1 );
                  frameRect.setRight( tabBarRect.left() + 8 );
                  frameRect.setLeft( frameRect.right() - 4 );
                  if ( !( documentMode || reverseLayout ) ) tiles |= TileSet::Top;
                  if ( !documentMode && reverseLayout ) tiles |= TileSet::Bottom;
                  slab = SlabRect( frameRect, tiles );
                  break;
                  }

            default:
                  break;
            }

      const bool verticalTabs( _style.data()->isVerticalTab( tabOpt ) );
      const QRect tabWidgetRect( tabWidget ?
                                 _style.data()->insideMargin( tabWidget->rect(), -GlowWidth ).translated( -widget->geometry().topLeft() ) :
                                 QRect() );

      const QPalette& palette( tabOpt->palette );
      const QColor color( palette.color(QPalette::Window) );
      _style.data()->adjustSlabRect( slab, tabWidgetRect, documentMode, verticalTabs );
      _style.data()->renderSlab( painter, slab, color, NoFill );

      setDirty( false );
      return;

      }

bool MgStyle::drawToolBarControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {

      const QRect& r( option->rect );

      if(!widget)
            widget = QApplication::activeWindow();

      // when timeLine is running draw border event if not hovered
      const bool toolBarAnimated( animations().toolBarEngine().isFollowMouseAnimated( widget ) );
      const QRect animatedRect( animations().toolBarEngine().animatedRect( widget ) );
      const bool toolBarIntersected( toolBarAnimated && animatedRect.intersects( r ) );
      if ( toolBarIntersected ) {
            _helper.slitFocused(_helper.viewFocusBrush().brush(QPalette::Active).color())->render(animatedRect, painter );
            }

      // draw nothing otherwise (toolbars are transparent)

      return true;

      }

bool MgStyle::drawToolBoxTabLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {

      const QStyleOptionToolBox* toolBoxOption( qstyleoption_cast<const QStyleOptionToolBox*>( option ));
      const bool enabled( toolBoxOption->state & State_Enabled );
      const bool selected( toolBoxOption->state & State_Selected );

      if(!widget)
            widget = QApplication::activeWindow();
      QPixmap pm(
            toolBoxOption->icon.pixmap( pixelMetric(QStyle::PM_SmallIconSize, toolBoxOption, widget),
                                        enabled ? QIcon::Normal : QIcon::Disabled ) );

      const QRect cr( toolBoxTabContentsRect( toolBoxOption, widget ) );
      QRect tr;
      QRect ir;
      int ih( 0 );
      if ( pm.isNull() ) {
            tr = cr;
            tr.adjust(4, 0, -8, 0);
            }
      else {
            int iw = pm.width() + 4;
            ih = pm.height();
            ir = QRect(cr.left() + 4, cr.top(), iw + 2, ih);
            tr = QRect(ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height());
            }

      if ( selected ) {
            QFont f(painter->font());
            f.setBold(true);
            painter->setFont(f);
            }

      QString txt( toolBoxOption->fontMetrics.elidedText(toolBoxOption->text, Qt::ElideRight, tr.width() ) );

      if ( ih ) painter->drawPixmap(ir.left(), (toolBoxOption->rect.height() - ih) / 2, pm);

      int alignment( Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic );
      drawItemText( painter, tr, alignment, toolBoxOption->palette, enabled, txt, QPalette::WindowText );

      return true;
      }

bool MgStyle::drawToolBoxTabShapeControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {

      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      const State& flags( option->state );

      const bool enabled( flags & State_Enabled );
      const bool selected( flags & State_Selected );
      const bool mouseOver( enabled && !selected && (flags & State_MouseOver) );
      const bool reverseLayout( option->direction == Qt::RightToLeft );

      if(!widget)
            widget = QApplication::activeWindow();


      // cast to v2 and disable paint is tab is first
      const QStyleOptionToolBoxV2* v2 = qstyleoption_cast<const QStyleOptionToolBoxV2*>(option);
      if ( v2 && v2->position == QStyleOptionToolBoxV2::Beginning && selected ) return true;

      /*
      the proper widget (the toolbox tab) is not passed as argument by Qt.
      What is passed is the toolbox directly. To implement animations properly,
      the painter->device() is used instead
      */
      bool animated( false );
      qreal opacity( AnimationData::OpacityInvalid );
      if ( enabled ) {
            // try retrieve button from painter device.
            if ( QPaintDevice* device = painter->device() ) {
                  animations().toolBoxEngine().updateState( device, mouseOver );
                  animated = animations().toolBoxEngine().isAnimated( device );
                  opacity = animations().toolBoxEngine().opacity( device );
                  }

            }

      // save colors for shadow
      /* important: option returns a wrong color. We use the widget's palette when widget is set */
      const QColor color( widget ? widget->palette().color( widget->backgroundRole() ) : palette.color( QPalette::Window ) );
      const QColor dark( _helper.calcDarkColor(color) );
      QList<QColor> colors;
      colors.push_back( _helper.calcLightColor(color) );

      if ( mouseOver || animated ) {

            QColor highlight = _helper.viewHoverBrush().brush( palette ).color();
            if ( animated ) {

                  colors.push_back(ColorUtils::mix( dark, highlight, opacity ) );
                  colors.push_back( _helper.alphaColor( highlight, 0.2 * opacity ) );

                  }
            else {

                  colors.push_back( highlight );
                  colors.push_back( _helper.alphaColor( highlight, 0.2 ) );

                  }

            }
      else colors.push_back( dark );

      // create path
      painter->save();
      QPainterPath path;
      const int y( r.height() * 15 / 100 );
      if ( reverseLayout) {

            path.moveTo(r.left() + 52, r.top());
            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));
            path.lineTo(r.left() + 18 + 9, r.bottom() - y);
            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));
            painter->setClipRect( QRect( r.left() + 21, r.top(), 28, r.height() ) );

            }
      else {

            path.moveTo(r.right() - 52, r.top());
            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));
            path.lineTo(r.right() - 18 - 9, r.bottom() - y);
            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));
            painter->setClipRect( QRect( r.right() - 48, r.top(), 32, r.height() ) );

            }


      // paint
      painter->setRenderHint(QPainter::Antialiasing, true);
      painter->translate(0, 2);
      foreach( const QColor & color, colors ) {
            painter->setPen(color);
            painter->drawPath(path);
            painter->translate(0, -1);
            }
      painter->restore();

      painter->save();
      painter->setRenderHint(QPainter::Antialiasing, false);
      painter->translate(0, 2);
      foreach( const QColor & color, colors ) {
            painter->setPen( color );
            if ( reverseLayout) {
                  painter->drawLine(r.left() + 50 - 1, r.top(), r.right(), r.top());
                  painter->drawLine(r.left() + 20, r.bottom() - 2, r.left(), r.bottom() - 2);
                  }
            else {
                  painter->drawLine(r.left(), r.top(), r.right() - 50 + 1, r.top());
                  painter->drawLine(r.right() - 20, r.bottom() - 2, r.right(), r.bottom() - 2);
                  }
            painter->translate(0, -1);
            }

      painter->restore();
      return true;

      }

//---------------------------------------------------------
//   drawToolButtonLabelControl
//---------------------------------------------------------

bool MgStyle::drawToolButtonLabelControl(const QStyleOption* option, QPainter* painter, const QWidget* widget) const
      {
      // need to customize palettes to deal with autoraised buttons
      const State& flags( option->state );
      const bool autoRaised(flags & State_AutoRaise);

      // normal processing if not autoRaised
      if ( !autoRaised )
            return false;

      const QStyleOptionToolButton* toolButtonOpt(qstyleoption_cast<const QStyleOptionToolButton*>(option));
      if (!toolButtonOpt)
            return true;

      if(!widget)
            widget = QApplication::activeWindow();

      QStyleOptionToolButton localOption(*toolButtonOpt);
      QColor color(option->palette.color(QPalette::WindowText));
      localOption.palette.setColor(QPalette::ButtonText, color);

      QCommonStyle::drawControl(CE_ToolButtonLabel, &localOption, painter, widget);
      return true;
      }

QRect MgStyle::groupBoxSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const {
      QRect r = option->rect;

      if(!widget)
            widget = QApplication::activeWindow();

      switch (subControl) {

            case SC_GroupBoxFrame:
                  return r.adjusted( -1, -2, 1, 0 );

            case SC_GroupBoxContents: {

                  // cast option and check
                  const QStyleOptionGroupBox* gbOpt = qstyleoption_cast<const QStyleOptionGroupBox*>(option);
                  if ( !gbOpt) break;

                  const bool isFlat( gbOpt->features & QStyleOptionFrameV2::Flat );
                  const int th( gbOpt->fontMetrics.height() + 8 );
                  const QRect cr( subElementRect(SE_CheckBoxIndicator, option, widget) );
                  const int fw( pixelMetric(PM_DefaultFrameWidth, option, widget) );
                  const bool checkable( gbOpt->subControls & QStyle::SC_GroupBoxCheckBox );
                  const bool emptyText( gbOpt->text.isEmpty() );

                  r.adjust(fw, fw, -fw, -fw);
                  if ( checkable && !emptyText ) r.adjust(0, qMax(th, cr.height()), 0, 0);
                  else if ( checkable ) r.adjust(0, cr.height(), 0, 0);
                  else if ( !emptyText ) r.adjust(0, th, 0, 0);

                  // add additional indentation to flat group boxes
                  if ( isFlat) {
                        const int leftMarginExtension( 16 );
                        r = visualRect( option->direction, r, r.adjusted(leftMarginExtension, 0, 0, 0) );
                        }

                  return r;
                  }

            case SC_GroupBoxCheckBox:
            case SC_GroupBoxLabel: {
                  // cast option and check
                  const QStyleOptionGroupBox* gbOpt = qstyleoption_cast<const QStyleOptionGroupBox*>(option);
                  if ( !gbOpt) break;

                  const bool isFlat( gbOpt->features & QStyleOptionFrameV2::Flat );
                  QFontMetrics fontMetrics = gbOpt->QStyleOption::fontMetrics;
                  if(widget) {
                        QFont font = widget->font();

                        // calculate text width assuming bold text in flat group boxes
                        if ( isFlat ) font.setBold(true);

                        fontMetrics = QFontMetrics(font);
                  }

                  const int h( fontMetrics.height() );
                  const int tw( fontMetrics.size(Qt::TextShowMnemonic, gbOpt->text + QLatin1String("  ")).width() );
                  r.setHeight(h);

                  // translate down by 6 pixels in non flat mode,
                  // to avoid collision with groupbox frame
                  if ( !isFlat ) r.moveTop(6);

                  QRect cr;
                  if (gbOpt->subControls & QStyle::SC_GroupBoxCheckBox) {
                        cr = subElementRect(SE_CheckBoxIndicator, option, widget);
                        QRect gcr((gbOpt->rect.width() - tw - cr.width()) / 2 , (h - cr.height()) / 2 + r.y(), cr.width(), cr.height());
                        if (subControl == SC_GroupBoxCheckBox) {
                              if ( !isFlat) return visualRect(option->direction, option->rect, gcr);
                              else return visualRect(option->direction, option->rect, QRect(0, 0, cr.width(), cr.height()));
                              }
                        }

                  // left align labels in flat group boxes, center align labels in framed group boxes
                  if ( isFlat) r = QRect(cr.width(), r.y(), tw, r.height());
                  else r = QRect((gbOpt->rect.width() - tw - cr.width()) / 2 + cr.width(), r.y(), tw, r.height());

                  return visualRect(option->direction, option->rect, r);
                  }

            default:
                  break;

            }

      return QCommonStyle::subControlRect( CC_GroupBox, option, subControl, widget );
      }

QRect MgStyle::comboBoxSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const {
      const QRect& r( option->rect );
      const QStyleOptionComboBox* cb = qstyleoption_cast<const QStyleOptionComboBox*>(option);
      if(!widget)
            widget = QApplication::activeWindow();

      if ( !cb ) return QCommonStyle::subControlRect( CC_ComboBox, option, subControl, widget );

      switch ( subControl ) {
            case SC_ComboBoxFrame: {
                  return cb->frame ? r : QRect();
                  }

            case SC_ComboBoxListBoxPopup: {
                  return r.adjusted(1, 0, -1, 0);
                  }

            case SC_ComboBoxArrow:
            case SC_ComboBoxEditField: {
                  // frame width
                  int fw = ComboBox_FrameWidth;

                  // button width
                  int bw = ComboBox_ButtonWidth;

                  // button margin
                  int bm = ComboBox_ButtonMargin;
                  int bml = bm + ComboBox_ButtonMargin_Left;
                  int bmr = bm + ComboBox_ButtonMargin_Right;
                  int bmt = bm + ComboBox_ButtonMargin_Top;
                  int bmb = bm + ComboBox_ButtonMargin_Bottom;

                  // ComboBox without a frame, set the corresponding layout values to 0, reduce button width.
                  if ( !cb->frame) {
                        bw = bw - bmr; // reduce button with as the right button margin will be ignored.
                        fw = 0;

                        // TODO: why is bml not also set to 0
                        bmt = bmb = bmr = 0;
                        }

                  if ( subControl == SC_ComboBoxArrow ) {

                        return
                              handleRTL(option,
                                        QRect(r.right() - bw + bml + 1, r.top() + bmt, bw - bml - bmr, r.height() - bmt - bmb) );

                        }
                  else {

                        QRect labelRect(r.left() + fw, r.top() + fw, r.width() - fw - bw, r.height() - 2 * fw);
                        labelRect = insideMargin( labelRect,
                                                  ComboBox_ContentsMargin,
                                                  ComboBox_ContentsMargin_Left,
                                                  ComboBox_ContentsMargin_Top,
                                                  ComboBox_ContentsMargin_Right,
                                                  ComboBox_ContentsMargin_Bottom );
                        return handleRTL(option, labelRect );

                        }

                  }

            default:
                  break;

            }

      return QCommonStyle::subControlRect( CC_ComboBox, option, subControl, widget );

      }

QRect MgStyle::scrollBarInternalSubControlRect( const QStyleOptionComplex* option, SubControl subControl ) const {

      const QRect& r = option->rect;
      const State& flags( option->state );
      const bool horizontal( flags & State_Horizontal );

      switch (subControl) {

            case SC_ScrollBarSubLine: {
                  int majorSize( scrollBarButtonHeight( _subLineButtons ) );
                  if ( horizontal ) return handleRTL(option, QRect(r.x(), r.y(), majorSize, r.height()));
                  else return handleRTL(option, QRect(r.x(), r.y(), r.width(), majorSize));

                  }

            case SC_ScrollBarAddLine: {
                  int majorSize( scrollBarButtonHeight( _addLineButtons ) );
                  if ( horizontal ) return handleRTL(option, QRect(r.right() - majorSize, r.y(), majorSize, r.height()));
                  else return handleRTL(option, QRect(r.x(), r.bottom() - majorSize, r.width(), majorSize));
                  }

            default:
                  return QRect();

            }
      }

QRect MgStyle::sliderSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const {
      if(!widget)
            widget = QApplication::activeWindow();

      switch ( subControl ) {
            case SC_SliderHandle: {

                  QRect handle( QCommonStyle::subControlRect( CC_Slider, option, subControl, widget ) );
                  if ( const QStyleOptionSlider* slider = qstyleoption_cast<const QStyleOptionSlider*>( option ) ) {
                        const bool horizontal( slider->orientation == Qt::Horizontal );
                        if ( horizontal ) handle.adjust( -1, 0, 1, 0 );
                        else handle.adjust( 0, 0, 0, 2 );
                        }

                  return handle;
                  }

            case SC_SliderGroove: {
                  QRect groove( QCommonStyle::subControlRect( CC_Slider, option, subControl, widget ) );
                  if ( const QStyleOptionSlider* slider = qstyleoption_cast<const QStyleOptionSlider*>( option ) ) {
                        const bool horizontal( slider->orientation == Qt::Horizontal );
                        if ( horizontal) {

                              const int center( groove.center().y() );
                              groove = QRect( groove.left(), center - 2, groove.width(), 5  ).adjusted( 3, 0, -3, 0 );

                              }
                        else {

                              const int center( groove.center().x() );
                              groove = QRect( center - 2, groove.top(), 5, groove.height() ).adjusted( 0, 3, 0, -3 );

                              }

                        }

                  return groove;

                  }

            default:
                  return QCommonStyle::subControlRect( CC_Slider, option, subControl, widget );

            }

      }

QRect MgStyle::scrollBarSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const {
      const QRect& r = option->rect;
      const State& flags( option->state );
      const bool horizontal( flags & State_Horizontal );

      if(!widget)
            widget = QApplication::activeWindow();

      switch (subControl) {
                  //For both arrows, we return -everything-,
                  //to get stuff to repaint right. See scrollBarInternalSubControlRect
                  //for the real thing
            case SC_ScrollBarSubLine:
            case SC_ScrollBarAddLine:
                  if ( horizontal ) return r.adjusted( 0, 1, 0, -1 );
                  else return r.adjusted( 1, 0, -1, 0 );

                  //The main groove area. This is used to compute the others...
            case SC_ScrollBarGroove: {
                  QRect top = handleRTL(option, scrollBarInternalSubControlRect( option, SC_ScrollBarSubLine ));
                  QRect bot = handleRTL(option, scrollBarInternalSubControlRect( option, SC_ScrollBarAddLine ));

                  QPoint topLeftCorner;
                  QPoint botRightCorner;

                  if ( horizontal ) {

                        topLeftCorner  = QPoint(top.right() + 1, top.top());
                        botRightCorner = QPoint(bot.left()  - 1, top.bottom());

                        }
                  else {
                        topLeftCorner  = QPoint(top.left(),  top.bottom() + 1);
                        botRightCorner = QPoint(top.right(), bot.top()    - 1);
                        }

                  // define rect, and reduce margins
                  QRect r( topLeftCorner, botRightCorner );
                  if ( horizontal ) r.adjust( 0, 1, 0, -1 );
                  else r.adjust( 1, 0, -1, 0 );

                  return handleRTL(option, r);
                  }

            case SC_ScrollBarSlider: {
                  const QStyleOptionSlider* slOpt = qstyleoption_cast<const QStyleOptionSlider*>(option);
                  if ( !slOpt ) return QRect();

                  //We do handleRTL here to unreflect things if need be
                  QRect groove = handleRTL(option, scrollBarSubControlRect( option, SC_ScrollBarGroove, widget ) );

                  if (slOpt->minimum == slOpt->maximum) return groove;

                  //Figure out how much room we have..
                  int space( horizontal ? groove.width() : groove.height() );

                  //Calculate the portion of this space that the slider should take up.
                  int sliderSize = space * qreal(slOpt->pageStep) / (slOpt->maximum - slOpt->minimum + slOpt->pageStep );
                  sliderSize = qMax( sliderSize, (int)ScrollBar_MinimumSliderHeight );
                  sliderSize = qMin( sliderSize, space );

                  space -= sliderSize;
                  if ( space <= 0 ) return groove;

                  const int pos = qRound(qreal(slOpt->sliderPosition - slOpt->minimum) / (slOpt->maximum - slOpt->minimum) * space);
                  if ( horizontal ) return handleRTL(option, QRect(groove.x() + pos, groove.y(), sliderSize, groove.height()));
                  else return handleRTL(option, QRect(groove.x(), groove.y() + pos, groove.width(), sliderSize));
                  }

            case SC_ScrollBarSubPage: {

                  //We do handleRTL here to unreflect things if need be
                  QRect slider = handleRTL(option, scrollBarSubControlRect( option, SC_ScrollBarSlider, widget) );
                  QRect groove = handleRTL(option, scrollBarSubControlRect( option, SC_ScrollBarGroove, widget) );

                  if ( horizontal ) return handleRTL(option, QRect(groove.x(), groove.y(), slider.x() - groove.x(), groove.height()));
                  else return handleRTL(option, QRect(groove.x(), groove.y(), groove.width(), slider.y() - groove.y()));
                  }

            case SC_ScrollBarAddPage: {

                  //We do handleRTL here to unreflect things if need be
                  QRect slider = handleRTL(option, scrollBarSubControlRect( option, SC_ScrollBarSlider, widget) );
                  QRect groove = handleRTL(option, scrollBarSubControlRect( option, SC_ScrollBarGroove, widget) );

                  if ( horizontal ) return handleRTL(option, QRect(slider.right() + 1, groove.y(), groove.right() - slider.right(), groove.height()));
                  else return handleRTL(option, QRect(groove.x(), slider.bottom() + 1, groove.width(), groove.bottom() - slider.bottom()));

                  }

            default:
                  return QRect();
            }
      }

QRect MgStyle::spinBoxSubControlRect(const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget) const {
      const QRect& r(option->rect);
      const QStyleOptionSpinBox* sb = qstyleoption_cast<const QStyleOptionSpinBox*>(option);
      if (!sb)
            return r;

      int fw = SpinBox_FrameWidth;
      int bw = SpinBox_ButtonWidth;
      int bm = SpinBox_ButtonMargin;
      int bml = bm + SpinBox_ButtonMargin_Left;
      int bmt = bm + SpinBox_ButtonMargin_Top;
      int bmr = bm + SpinBox_ButtonMargin_Right;
      int bmb = bm + SpinBox_ButtonMargin_Bottom;
      int bs = 0 ;

      if(!widget)
            widget = QApplication::activeWindow();

      if (!sb->frame) {
            bw = bw - bmr;
            fw = 0;

            // TODO: why is bml not also set to 0
            bmt = bmb = bmr = 0;
            }

      const int buttonsWidth = bw - bml - bmr;
      const int buttonsLeft = r.right() - bw + bml + 1;

      // compute the height of each button...
      const int availableButtonHeight = r.height() - bmt - bmb - bs;
      const int heightUp = availableButtonHeight / 2;
      const int heightDown = availableButtonHeight - heightUp;

      switch (subControl) {
            case SC_SpinBoxUp:
                  return handleRTL(option, QRect(buttonsLeft, r.top() + bmt, buttonsWidth, heightUp) );
            case SC_SpinBoxDown:
                  return handleRTL(option, QRect(buttonsLeft, r.bottom() - bmb - heightDown, buttonsWidth, heightDown) );
            case SC_SpinBoxEditField: {
                  const QRect labelRect(r.left() + fw, r.top() + fw, r.width() - fw - bw, r.height() - 2 * fw);
                  return handleRTL(option, labelRect );
                  }
            case SC_SpinBoxFrame:
                  return sb->frame ? r : QRect();
            default:
                  break;

            }
      return QCommonStyle::subControlRect(CC_SpinBox, option, subControl, widget);
      }

void MgStyle::renderMenuItemBackground( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {
      const QRect& r( option->rect );
      const QPalette& palette( option->palette );
      if(!widget)
            widget = QApplication::activeWindow();

      const QRect animatedRect( animations().menuEngine().animatedRect( widget ) );
      if ( !animatedRect.isNull() ) {

            if ( animatedRect.intersects( r ) ) {
                  const QColor color( _helper.menuBackgroundColor( palette.color( QPalette::Window ), widget, animatedRect.center() ) );
                  renderMenuItemRect( option, animatedRect, color, palette, painter );
                  }

            }
      else if ( animations().menuEngine().isTimerActive( widget ) ) {

            const QRect previousRect( animations().menuEngine().currentRect( widget, Previous ) );
            if ( previousRect.intersects( r ) ) {

                  const QColor color( _helper.menuBackgroundColor( palette.color( QPalette::Window ), widget, previousRect.center() ) );
                  renderMenuItemRect( option, previousRect, color, palette, painter );
                  }

            }
      else if ( animations().menuEngine().isAnimated(widget, Previous ) ) {

            QRect previousRect( animations().menuEngine().currentRect( widget, Previous ) );
            if ( previousRect.intersects( r ) ) {
                  const qreal opacity(  animations().menuEngine().opacity( widget, Previous ) );
                  const QColor color( _helper.menuBackgroundColor( palette.color( QPalette::Window ), widget, previousRect.center() ) );
                  renderMenuItemRect( option, previousRect, color, palette, painter, opacity );
                  }

            }

      return;
      }

void MgStyle::renderMenuItemRect( const QStyleOption* opt, const QRect& r, const QColor& base, const QPalette& palette, QPainter* painter, qreal opacity ) const {
      if (opacity == 0)
            return;

      // get relevant color
      // TODO: this is inconsistent with MenuBar color.
      // this should change to properly account for 'sunken' state
      QColor color(base);
      if (MgStyleConfigData::menuHighlightMode == MgStyleConfigData::MM_STRONG) {

            color = palette.color(QPalette::Highlight);

            }
      else if (MgStyleConfigData::menuHighlightMode == MgStyleConfigData::MM_SUBTLE) {

            color = ColorUtils::mix(color, ColorUtils::tint(color, palette.color(QPalette::Highlight), 0.6));

            }
      else color = _helper.calcMidColor( color );

      // special painting for items with submenus
      const QStyleOptionMenuItem* menuItemOption = qstyleoption_cast<const QStyleOptionMenuItem*>(opt);
      if ( menuItemOption && menuItemOption->menuItemType == QStyleOptionMenuItem::SubMenu ) {

            QPixmap pm(r.size());
            pm.fill(Qt::transparent);
            QPainter pp(&pm);
            QRect rr(QPoint(0, 0), r.size());

            pp.setRenderHint(QPainter::Antialiasing);
            pp.setPen(Qt::NoPen);

            pp.setBrush(color);
            _helper.fillHole(pp, rr);

            _helper.holeFlat(color, 0.0)->render(rr.adjusted( 1, 2, -2, -1 ), &pp);

            QRect maskr( visualRect(opt->direction, rr, QRect(rr.width() - 40, 0, 40, rr.height())) );
            QLinearGradient gradient(
                  visualPos(opt->direction, maskr, QPoint(maskr.left(), 0)),
                  visualPos(opt->direction, maskr, QPoint(maskr.right() - 4, 0)));
            gradient.setColorAt( 0.0, Qt::black );
            gradient.setColorAt( 1.0, Qt::transparent );
            pp.setBrush(gradient);
            pp.setCompositionMode(QPainter::CompositionMode_DestinationIn);
            pp.drawRect(maskr);

            if ( opacity >= 0 && opacity < 1 ) {
                  pp.setCompositionMode(QPainter::CompositionMode_DestinationIn);
                  pp.fillRect(pm.rect(), _helper.alphaColor( Qt::black, opacity ) );
                  }

            pp.end();

            painter->drawPixmap(handleRTL(opt, r), pm);

            }
      else {

            if ( opacity >= 0 && opacity < 1 ) {
                  color.setAlphaF( opacity );
                  }

            _helper.holeFlat(color, 0.0)->render(r.adjusted(1, 2, -2, -1), painter, TileSet::Full);

            }

      }

void MgStyle::renderHeaderBackground( const QRect& r, const QPalette& palette, QPainter* painter, const QWidget* widget, bool horizontal, bool reverse ) const {
      if(!widget)
            widget = QApplication::activeWindow();

      // use window background for the background
      if ( widget ) _helper.renderWindowBackground( painter, r, widget, palette);
      else painter->fillRect( r, palette.color( QPalette::Window ) );

      if ( horizontal ) renderHeaderLines( r, palette, painter, TileSet::Bottom );
      else if ( reverse ) renderHeaderLines( r, palette, painter, TileSet::Left );
      else renderHeaderLines( r, palette, painter, TileSet::Right );

      }

void MgStyle::renderHeaderLines( const QRect& r, const QPalette& palette, QPainter* painter, TileSet::Tiles tiles ) const {
      // add horizontal lines
      const QColor color( palette.color(QPalette::Window) );
      const QColor dark( _helper.calcDarkColor(color) );
      const QColor light( _helper.calcLightColor(color) );

      painter->save();
      QRect rect( r );
      if ( tiles & TileSet::Bottom  ) {

            painter->setPen(dark);
            if ( tiles & TileSet::Left ) painter->drawPoint( rect.bottomLeft() );
            else if ( tiles & TileSet::Right ) painter->drawPoint( rect.bottomRight() );
            else painter->drawLine(rect.bottomLeft(), rect.bottomRight());

            rect.adjust(0, 0, 0, -1);
            painter->setPen(light);
            if ( tiles & TileSet::Left ) {
                  painter->drawLine(rect.bottomLeft(), rect.bottomLeft() + QPoint( 1, 0 ) );
                  painter->drawLine(rect.bottomLeft() + QPoint( 1, 0 ), rect.bottomLeft() + QPoint( 1, 1 ) );

                  }
            else if ( tiles & TileSet::Right ) {

                  painter->drawLine(rect.bottomRight(), rect.bottomRight() - QPoint( 1, 0 ) );
                  painter->drawLine(rect.bottomRight() - QPoint( 1, 0 ), rect.bottomRight() - QPoint( 1, -1 ) );

                  }
            else {

                  painter->drawLine(rect.bottomLeft(), rect.bottomRight());
                  }
            }
      else if ( tiles & TileSet::Left ) {

            painter->setPen(dark);
            painter->drawLine(rect.topLeft(), rect.bottomLeft());

            rect.adjust(1, 0, 0, 0);
            painter->setPen(light);
            painter->drawLine(rect.topLeft(), rect.bottomLeft());

            }
      else if ( tiles & TileSet::Right ) {

            painter->setPen(dark);
            painter->drawLine(rect.topRight(), rect.bottomRight());

            rect.adjust(0, 0, -1, 0);
            painter->setPen(light);
            painter->drawLine(rect.topRight(), rect.bottomRight());

            }

      painter->restore();

      return;

      }

void MgStyle::renderTitleBarButton( QPainter* painter, const QStyleOptionTitleBar* option, const QWidget* widget, const SubControl& subControl ) const {

      if(!widget)
            widget = QApplication::activeWindow();

      const QRect r = subControlRect(CC_TitleBar, option, subControl, widget );
      if ( !r.isValid() ) return;

      QPalette palette = option->palette;

      painter->save();
      painter->drawPixmap( r, _helper.windecoButton( palette.window().color(), true, r.height() ) );
      painter->setRenderHints(QPainter::Antialiasing);
      painter->setBrush(Qt::NoBrush);

      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );
      const bool active( enabled && (option->titleBarState & Qt::WindowActive ) );

      // enable state transition
      animations().widgetEnabilityEngine().updateState( widget, AnimationEnable, active );
      if ( animations().widgetEnabilityEngine().isAnimated( widget, AnimationEnable ) ) {
            palette = _helper.mergePalettes( palette, animations().widgetEnabilityEngine().opacity( widget, AnimationEnable )  );
            }

      const bool sunken( flags & State_Sunken );
      const bool mouseOver( (!sunken) && widget && r.translated( widget->mapToGlobal( QPoint(0, 0) ) ).contains( QCursor::pos() ) );

      animations().mdiWindowEngine().updateState( widget, subControl, enabled && mouseOver );
      const bool animated( enabled && animations().mdiWindowEngine().isAnimated( widget, subControl ) );
      const qreal opacity( animations().mdiWindowEngine().opacity( widget, subControl ) );

            {

            // contrast pixel
            const QColor contrast = _helper.calcLightColor( option->palette.color( QPalette::Active, QPalette::Window ) );
            const qreal width( 1.1 );
            painter->translate(0, 0.5);
            painter->setPen(QPen( contrast, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            renderTitleBarIcon( painter, QRectF(r).adjusted(-2.5, -2.5, 0, 0), subControl );

            }

            {

            // button color
            QColor color;
            if ( animated ) {

                  const QColor base( palette.color( active ? QPalette::Active : QPalette::Disabled, QPalette::WindowText ) );
                  const QColor glow( subControl == SC_TitleBarCloseButton ?
                                     _helper.viewNegativeTextBrush().brush( palette ).color() :
                                     _helper.viewHoverBrush().brush( palette ).color() );

                  color = ColorUtils::mix( base, glow, opacity );

                  }
            else if ( mouseOver ) {

                  color = ( subControl == SC_TitleBarCloseButton ) ?
                          _helper.viewNegativeTextBrush().brush( palette ).color() :
                          _helper.viewHoverBrush().brush( palette ).color();

                  }
            else {

                  color = palette.color( active ? QPalette::Active : QPalette::Disabled, QPalette::WindowText );

                  }

            // main icon painting
            const qreal width( 1.1 );
            painter->translate(0, -1);
            painter->setPen(QPen( color, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            renderTitleBarIcon( painter, QRectF(r).adjusted(-2.5, -2.5, 0, 0), subControl );

            }

      painter->restore();

      }


void MgStyle::renderTitleBarIcon(QPainter* painter, const QRectF& r, const SubControl& subControl ) const {

      painter->save();
      painter->translate(r.topLeft());
      switch ( subControl ) {
            case SC_TitleBarContextHelpButton: {
                  painter->translate(1.5, 1.5);
                  painter->drawArc(7, 5, 4, 4, 135 * 16, -180 * 16);
                  painter->drawArc(9, 8, 4, 4, 135 * 16, 45 * 16);
                  painter->drawPoint(9, 12);
                  break;
                  }
            case SC_TitleBarMinButton: {
                  painter->drawLine(QPointF( 7.5, 9.5), QPointF(10.5, 12.5));
                  painter->drawLine(QPointF(10.5, 12.5), QPointF(13.5, 9.5));
                  break;
                  }
            case SC_TitleBarNormalButton: {
                  painter->translate(1.5, 1.5);
                  QPoint points[4] = {QPoint(9, 6), QPoint(12, 9), QPoint(9, 12), QPoint(6, 9)};
                  painter->drawPolygon(points, 4);
                  break;
                  }
            case SC_TitleBarMaxButton: {
                  painter->drawLine(QPointF( 7.5, 11.5), QPointF(10.5, 8.5));
                  painter->drawLine(QPointF(10.5, 8.5), QPointF(13.5, 11.5));
                  break;
                  }
            case SC_TitleBarCloseButton: {
                  painter->drawLine(QPointF( 7.5, 7.5), QPointF(13.5, 13.5));
                  painter->drawLine(QPointF(13.5, 7.5), QPointF( 7.5, 13.5));
                  break;
                  }
            case SC_TitleBarShadeButton: {
                  painter->drawLine(QPointF( 7.5, 13.5 ), QPointF(13.5, 13.5));
                  painter->drawLine(QPointF( 7.5, 7.5), QPointF(10.5, 10.5));
                  painter->drawLine(QPointF(10.5, 10.5), QPointF(13.5, 7.5));
                  break;
                  }
            case SC_TitleBarUnshadeButton: {
                  painter->drawLine(QPointF( 7.5, 10.5), QPointF(10.5, 7.5));
                  painter->drawLine(QPointF(10.5, 7.5), QPointF(13.5, 10.5));
                  painter->drawLine(QPointF( 7.5, 13.0), QPointF(13.5, 13.0));
                  break;
                  }
            default:
                  break;
            }
      painter->restore();
      }

void MgStyle::renderSpinBoxArrow( QPainter* painter, const QStyleOptionSpinBox* option, const QWidget* widget, const SubControl& subControl ) const {
      const QPalette& palette( option->palette );

      const State& flags( option->state );
      const bool enabled( flags & State_Enabled );
      const bool mouseOver(enabled && (flags & State_MouseOver));

      // check animation state
      const bool subControlHover( enabled && mouseOver && (option->activeSubControls & subControl) );
      animations().spinBoxEngine().updateState( widget, subControl, subControlHover );

      if(!widget)
            widget = QApplication::activeWindow();

      const bool animated( enabled && animations().spinBoxEngine().isAnimated( widget, subControl ) );
      const qreal opacity( animations().spinBoxEngine().opacity( widget, subControl ) );

      QColor color;
      if ( animated ) {

            QColor highlight = _helper.viewHoverBrush().brush( palette ).color();
            color = ColorUtils::mix( palette.color( QPalette::Text ), highlight, opacity );

            }
      else if ( subControlHover ) {

            color = _helper.viewHoverBrush().brush( palette ).color();

            }
      else {

            color = palette.color( QPalette::Text );

            }

      const qreal penThickness = 1.6;
      const QColor background = palette.color( QPalette::Background );

      const QPolygonF a( genericArrow( (subControl == SC_SpinBoxUp) ? ArrowUp : ArrowDown, ArrowNormal ) );
      const QRect arrowRect( subControlRect( CC_SpinBox, option, subControl, widget ) );

      painter->save();
      painter->translate( arrowRect.center() );
      painter->setRenderHint(QPainter::Antialiasing);

      painter->setPen(QPen( _helper.decoColor( background, color ) , penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
      painter->drawPolyline(a);
      painter->restore();

      return;

      }

QRegion MgStyle::tabBarClipRegion( const QTabBar* tabBar ) const {
      // need to mask-out arrow buttons, if visible.
      QRegion mask( tabBar->rect() );
      foreach( const QObject * child, tabBar->children() ) {
            const QToolButton* toolButton( qobject_cast<const QToolButton*>( child ) );
            if ( toolButton && toolButton->isVisible() ) mask -= toolButton->geometry();
            }

      return mask;

      }

int MgStyle::styleHint(StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData ) const {
      // handles SH_KCustomStyleElement out of switch statement,
      // to avoid warning at compilation
      /* ws: KDE specific?
            if (hint == SH_KCustomStyleElement ) {
                  if( widget )
                        return _styleElements.value(widget->objectName(), 0);
                  else
                        return 0;
                  }
        */
      /*
      special cases, that cannot be registered in styleHint map,
      because of conditional statements
      */
      if(!widget)
            widget = QApplication::activeWindow();

      switch ( hint ) {
            case SH_DialogButtonBox_ButtonsHaveIcons:
                  return 0; // KGlobalSettings::showIconsOnPushButtons();

            case SH_GroupBox_TextLabelColor:
                  if ( option ) return option->palette.color( QPalette::WindowText ).rgba();
                  else return qApp->palette().color( QPalette::WindowText ).rgba();

            case SH_ItemView_ActivateItemOnSingleClick:
                  // return _helper.config()->group("KDE").readEntry("SingleClick", KDE_DEFAULT_SINGLECLICK );
                  return false;

            case SH_RubberBand_Mask: {

                  const QStyleOptionRubberBand* opt = qstyleoption_cast<const QStyleOptionRubberBand*>(option);
                  if ( !opt) return false;

                  if ( QStyleHintReturnMask* mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {

                        mask->region = option->rect;

                        // need to check on widget before removing inner region
                        // in order to still preserve rubberband in MainWindow and QGraphicsView
                        // in QMainWindow because it looks better
                        // in QGraphicsView because the painting fails completely otherwise
                        if ( !( widget && (
                                          qobject_cast<const QGraphicsView*>( widget->parent() ) ||
                                          qobject_cast<const QMainWindow*>( widget->parent() ) ) ) ) {
                              mask->region -= option->rect.adjusted(1, 1, -1, -1);
                              }

                        return true;
                        }
                  return false;
                  }

            case SH_ToolTip_Mask:
            case SH_Menu_Mask: {
                  if ( !_helper.hasAlphaChannel( widget ) && (!widget || widget->isWindow())) {
                        // mask should be set only if compositing is disabled
                        if ( QStyleHintReturnMask* mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
                              mask->region = _helper.roundedMask( option->rect );
                              }
                        }
                  return true;
                  }

            // mouse tracking
            case SH_ComboBox_ListMouseTracking:
                  return true;
            case SH_MenuBar_MouseTracking:
                  return true;
            case SH_Menu_MouseTracking:
                  return true;
            case SH_MenuBar_AltKeyNavigation:
                  return true;

            case SH_Menu_SubMenuPopupDelay:
                  return 150;
            case SH_TitleBar_NoBorder:
                  return 0;
            case SH_GroupBox_TextLabelVerticalAlignment:
                  return Qt::AlignVCenter;
            case SH_DialogButtonLayout:
                  return QDialogButtonBox::KdeLayout;
            case SH_ScrollBar_MiddleClickAbsolutePosition:
                  return true;
            case SH_ItemView_ShowDecorationSelected:
                  return false;
            case SH_ItemView_ArrowKeysNavigateIntoChildren:
                  return true;
            case SH_ScrollView_FrameOnlyAroundContents:
                  return true;
            case SH_FormLayoutFormAlignment:
                  return Qt::AlignLeft | Qt::AlignTop;
            case SH_FormLayoutLabelAlignment:
                  return Qt::AlignRight;
            case SH_FormLayoutFieldGrowthPolicy:
                  return QFormLayout::ExpandingFieldsGrow;
            case SH_FormLayoutWrapPolicy:
                  return QFormLayout::DontWrapRows;
            case SH_MessageBox_TextInteractionFlags:
                  return Qt::LinksAccessibleByMouse | Qt::TextSelectableByMouse;
            case SH_WindowFrame_Mask:
                  return false;

            default:
                  return QCommonStyle::styleHint(hint, option, widget, returnData);
            }

      }

QRect MgStyle::subElementRect(SubElement element, const QStyleOption* option, const QWidget* widget) const {
      if(!widget)
            widget = QApplication::activeWindow();

      switch ( element ) {

                  // push buttons
            case SE_PushButtonContents:
                  return pushButtonContentsRect( option, widget );
            case SE_PushButtonFocusRect:
                  return defaultSubElementRect( option, widget );

                  // checkboxes
            case SE_CheckBoxContents:
                  return checkBoxContentsRect( option, widget );
            case SE_CheckBoxFocusRect:
                  return defaultSubElementRect( option, widget );

                  // progress bars
            case SE_ProgressBarGroove:
                  return defaultSubElementRect( option, widget );
            case SE_ProgressBarContents:
                  return progressBarContentsRect( option, widget );
            case SE_ProgressBarLabel:
                  return defaultSubElementRect( option, widget );

                  // radio buttons
            case SE_RadioButtonContents:
                  return checkBoxContentsRect( option, widget );
            case SE_RadioButtonFocusRect:
                  return defaultSubElementRect( option, widget );

                  // tab widget
            case SE_TabBarTabLeftButton:
                  return tabBarTabLeftButtonRect( option, widget );
            case SE_TabBarTabRightButton:
                  return tabBarTabRightButtonRect( option, widget );
            case SE_TabBarTabText:
                  return tabBarTabTextRect( option, widget );
            case SE_TabWidgetTabContents:
                  return tabWidgetTabContentsRect( option, widget );
            case SE_TabWidgetTabPane:
                  return tabWidgetTabPaneRect( option, widget );
            case SE_TabWidgetLeftCorner:
                  return tabWidgetLeftCornerRect( option, widget );
            case SE_TabWidgetRightCorner:
                  return tabWidgetRightCornerRect( option, widget );

                  // toolboxes
            case SE_ToolBoxTabContents:
                  return toolBoxTabContentsRect( option, widget );

            default:
                  return QCommonStyle::subElementRect( element, option, widget );

            }

      }

//---------------------------------------------------------
//   subControlRect
//---------------------------------------------------------

QRect MgStyle::subControlRect(ComplexControl element, const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const {
      if(!widget)
            widget = QApplication::activeWindow();

      switch (element) {
            case CC_GroupBox:
                  return groupBoxSubControlRect( option, subControl, widget );
            case CC_ComboBox:
                  return comboBoxSubControlRect( option, subControl, widget );
            case CC_Slider:
                  return sliderSubControlRect( option, subControl, widget );
            case CC_ScrollBar:
                  return scrollBarSubControlRect( option, subControl, widget );
            case CC_SpinBox:
                  return spinBoxSubControlRect( option, subControl, widget );
            default:
                  return QCommonStyle::subControlRect( element, option, subControl, widget );
            }
      }

QRect MgStyle::tabWidgetTabContentsRect( const QStyleOption* option, const QWidget* widget ) const {
      // cast option and check
      const QStyleOptionTabWidgetFrame* tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option);
      if ( !tabOpt) return option->rect;

      // do nothing if tabbar is hidden
      if ( tabOpt->tabBarSize.isEmpty() ) return option->rect;

      QRect r( option->rect );

      if(!widget)
            widget = QApplication::activeWindow();


      // include margins
      r = subElementRect(SE_TabWidgetTabPane, option, widget);

      // document mode
      const bool documentMode( tabOpt->lineWidth == 0 );

      if ( !documentMode ) {
            r = insideMargin( r, TabWidget_ContentsMargin );
            r.translate( 0, -1 );
            }

      return r;

      }

QRect MgStyle::tabWidgetTabPaneRect( const QStyleOption* option, const QWidget* ) const {
      const QStyleOptionTabWidgetFrame* tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option);
      if ( !tabOpt) return option->rect;

      QRect r( option->rect );
      const bool documentMode( tabOpt->lineWidth == 0 );
      int overlap( TabBar_BaseOverlap );
      if ( documentMode ) overlap -= TabWidget_ContentsMargin;

      switch ( tabOpt->shape ) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth: {
                  if ( documentMode ) overlap++;
                  r.setTop( r.top() + qMax( tabOpt->tabBarSize.height() - overlap, 0) );
                  break;
                  }

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth: {
                  if ( documentMode ) overlap--;
                  r.setBottom( r.bottom() - qMax( tabOpt->tabBarSize.height() - overlap, 0 ) );
                  break;
                  }

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest: {
                  r.setLeft( r.left() + qMax( tabOpt->tabBarSize.width() - overlap, 0) );
                  break;
                  }

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast: {
                  r.setRight( r.right() - qMax( tabOpt->tabBarSize.width() - overlap, 0) );
                  break;
                  }

            }

      return r;

      }

QRect MgStyle::tabWidgetLeftCornerRect( const QStyleOption* option, const QWidget* widget ) const {
      const QStyleOptionTabWidgetFrame* tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option);
      if (!tabOpt) return QRect();

      if(!widget)
            widget = QApplication::activeWindow();

      QRect r( option->rect );
      const QRect paneRect( subElementRect(SE_TabWidgetTabPane, option, widget) );

      const QTabWidget* tabWidget( qobject_cast<const QTabWidget*>( widget ) );
      const bool documentMode( tabWidget ? tabWidget->documentMode() : false );

      const QSize& size( tabOpt->leftCornerWidgetSize );
      const int h( size.height() );
      const int w( size.width() );

      switch ( tabOpt->shape ) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth:
                  r = QRect(QPoint(paneRect.x(), paneRect.y() - h ), size);
                  r = visualRect(tabOpt->direction, tabOpt->rect, r);
                  if ( !documentMode ) r.translate( 0, 3 );
                  break;

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth:
                  r = QRect(QPoint(paneRect.x(), paneRect.height() ), size);
                  r = visualRect(tabOpt->direction, tabOpt->rect, r);
                  if ( !documentMode ) r.translate( 0, -3 );
                  else r.translate( 0, 2 );
                  break;

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest:
                  r = QRect(QPoint(paneRect.x() - w, paneRect.y()), size);
                  r = visualRect(tabOpt->direction, tabOpt->rect, r);
                  if ( !documentMode ) r.translate( 2, 0 );
                  else r.translate( -2, 0 );
                  break;

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast:
                  r = QRect(QPoint(paneRect.x() + paneRect.width(), paneRect.y()), size);
                  r = visualRect(tabOpt->direction, tabOpt->rect, r);
                  if ( !documentMode ) r.translate( -2, 0 );
                  else r.translate( 2, 0 );
                  break;

            default:
                  break;
            }

      return r;

      }

QRect MgStyle::tabWidgetRightCornerRect( const QStyleOption* option, const QWidget* widget ) const {

      const QStyleOptionTabWidgetFrame* tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option);
      if (!tabOpt) return QRect();

      if(!widget)
            widget = QApplication::activeWindow();

      QRect r( option->rect );
      const QRect paneRect( subElementRect(SE_TabWidgetTabPane, option, widget) );

      const QTabWidget* tabWidget( qobject_cast<const QTabWidget*>( widget ) );
      const bool documentMode( tabWidget ? tabWidget->documentMode() : false );

      const QSize& size( tabOpt->rightCornerWidgetSize );
      const int h( size.height() );
      const int w( size.width() );

      switch ( tabOpt->shape ) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth:
                  r = QRect(QPoint(paneRect.right() - w + 1, paneRect.y() - h ), size);
                  r = visualRect(tabOpt->direction, tabOpt->rect, r);
                  if ( !documentMode ) r.translate( 0, 3 );
                  break;

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth:
                  r = QRect(QPoint(paneRect.right() - w + 1, paneRect.height() ), size);
                  r = visualRect(tabOpt->direction, tabOpt->rect, r);
                  if ( !documentMode ) r.translate( 0, -3 );
                  else r.translate( 0, 2 );
                  break;

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest:
                  r = QRect(QPoint(paneRect.x() - w, paneRect.bottom() - h + 1 ), size);
                  r = visualRect(tabOpt->direction, tabOpt->rect, r);
                  if ( !documentMode ) r.translate( 2, 0 );
                  else r.translate( -2, 0 );
                  break;

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast:
                  r = QRect(QPoint(paneRect.x() + paneRect.width(), paneRect.bottom() - h + 1 ), size);
                  r = visualRect(tabOpt->direction, tabOpt->rect, r);
                  if ( !documentMode ) r.translate( -2, 0 );
                  else r.translate( 2, 0 );
                  break;

            default:
                  break;
            }

      return r;
      }

QStyle::SubControl MgStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex* option, const QPoint& point, const QWidget* widget) const {
      if(!widget)
            widget = QApplication::activeWindow();

      switch ( control ) {
            case CC_ScrollBar: {

                  QRect groove = scrollBarSubControlRect( option, SC_ScrollBarGroove, widget );
                  if (groove.contains(point)) {
                        //Must be either page up/page down, or just click on the slider.
                        //Grab the slider to compare
                        QRect slider = scrollBarSubControlRect( option, SC_ScrollBarSlider, widget );

                        if ( slider.contains(point) ) return SC_ScrollBarSlider;
                        else if ( preceeds( point, slider, option ) ) return SC_ScrollBarSubPage;
                        else return SC_ScrollBarAddPage;

                        }

                  //This is one of the up/down buttons. First, decide which one it is.
                  if ( preceeds( point, groove, option ) ) {

                        if ( _subLineButtons == DoubleButton ) {
                              QRect buttonRect = scrollBarInternalSubControlRect( option, SC_ScrollBarSubLine );
                              return scrollBarHitTest( buttonRect, point, option );
                              }
                        else return SC_ScrollBarSubLine;

                        }

                  if ( _addLineButtons == DoubleButton ) {

                        QRect buttonRect = scrollBarInternalSubControlRect( option, SC_ScrollBarAddLine );
                        return scrollBarHitTest( buttonRect, point, option );

                        }
                  else return SC_ScrollBarAddLine;
                  }

            default:
                  return QCommonStyle::hitTestComplexControl( control, option, point, widget );
            }

      }

QRect MgStyle::tabBarTabButtonRect( SubElement element, const QStyleOption* option, const QWidget* widget ) const {

      const QStyleOptionTab* tabOpt( qstyleoption_cast<const QStyleOptionTab*>(option) );
      if (!tabOpt) return QRect();

      if(!widget)
            widget = QApplication::activeWindow();

      QRect r( QCommonStyle::subElementRect( element, option, widget ) );
      const bool selected( option->state & State_Selected );

      switch ( tabOpt->shape ) {

            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth:
                  r.translate( 0, -1 );
                  if ( selected ) r.translate( 0, -1 );
                  break;

            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth:
                  r.translate( 0, -1 );
                  if ( selected ) r.translate( 0, 1 );
                  break;

            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest:
                  r.translate( 0, 1 );
                  if ( selected )  r.translate( -1, 0 );
                  break;

            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast:
                  r.translate( 0, -2 );
                  if ( selected ) r.translate( 1, 0 );
                  break;

            default:
                  break;

            }
      return r;
      }

//---------------------------------------------------------
//   configurationChanged
//---------------------------------------------------------

void MgStyle::configurationChanged()
      {
      _helper.reloadConfig();

      // reset config
      // MgStyleConfigData::self()->readConfig();

      // update caches size
      int cacheSize = MgStyleConfigData::cacheEnabled ? MgStyleConfigData::maxCacheSize : 0;
      _helper.setMaxCacheSize(cacheSize);

      // reinitialize engines
      animations().setupEngines();
      transitions().setupEngines();

      // scrollbar button dimentions.
      /* it has to be reinitialized here because scrollbar width might have changed */
      _noButtonHeight = 0;
      _singleButtonHeight = qMax(MgStyleConfigData::scrollBarWidth * 7 / 10, 14 );
      _doubleButtonHeight = 2 * _singleButtonHeight;

      _mnemonic = MgStyleConfigData::showMnemonics ? Qt::TextShowMnemonic : Qt::TextHideMnemonic;

      // scrollbar buttons
      switch (MgStyleConfigData::scrollBarAddLineButtons) {
            case 0:
                  _addLineButtons = NoButton;
                  break;
            case 1:
                  _addLineButtons = SingleButton;
                  break;
            default:
            case 2:
                  _addLineButtons = DoubleButton;
                  break;
            }

      switch (MgStyleConfigData::scrollBarSubLineButtons) {
            case 0:
                  _subLineButtons = NoButton;
                  break;
            case 1:
                  _subLineButtons = SingleButton;
                  break;

            default:
            case 2:
                  _subLineButtons = DoubleButton;
                  break;
            }

      // tabbar shape
      switch (MgStyleConfigData::tabStyle) {
            case MgStyleConfigData::TS_PLAIN:
                  _tabBarTabShapeControl = &MgStyle::drawTabBarTabShapeControl_Plain;
                  break;

            default:
            case MgStyleConfigData::TS_SINGLE:
                  _tabBarTabShapeControl = &MgStyle::drawTabBarTabShapeControl_Single;
                  break;
            }

      // frame focus

      if (MgStyleConfigData::viewDrawFocusIndicator)
            _frameFocusPrimitive = &MgStyle::drawFrameFocusRectPrimitive;
      else
            _frameFocusPrimitive = &MgStyle::emptyPrimitive;
      }

//---------------------------------------------------------
//   standardIcon
//---------------------------------------------------------

QIcon MgStyle::standardIcon(StandardPixmap standardIcon,
            const QStyleOption* option, const QWidget* widget) const {
      // MDI windows buttons
      // get button color ( unfortunately option and widget might not be set )
      QColor buttonColor;
      QColor iconColor;
      if(!widget)
            widget = QApplication::activeWindow();

      if (option) {
            buttonColor = option->palette.window().color();
            iconColor   = option->palette.windowText().color();
            }
      else if (widget) {
            buttonColor = widget->palette().window().color();
            iconColor   = widget->palette().windowText().color();
            }
      else if (qApp) {
            // might not have a QApplication
            buttonColor = qApp->palette().window().color();
            iconColor   = qApp->palette().windowText().color();
            }
      else {
            // KCS is always safe
            buttonColor = ColorScheme(QPalette::Active, ColorScheme::Window).background().color();
            iconColor   = ColorScheme(QPalette::Active, ColorScheme::Window).foreground().color();
            }

      switch (standardIcon) {
            case SP_TitleBarNormalButton: {
                  QPixmap realpm(pixelMetric(QStyle::PM_SmallIconSize, 0, 0), pixelMetric(QStyle::PM_SmallIconSize, 0, 0));
                  realpm.fill( Qt::transparent );
                  QPixmap pm = _helper.windecoButton(buttonColor, false, 15);
                  QPainter painter(&realpm);
                  painter.drawPixmap(1, 1, pm);
                  painter.setRenderHints(QPainter::Antialiasing);

                  // should use the same icons as in the deco
                  QPointF points[4] = {QPointF( 8.5, 6 ), QPointF( 11, 8.5 ), QPointF( 8.5, 11 ), QPointF( 6, 8.5 )};
                        {
                        const qreal width( 1.1 );
                        painter.translate( 0, 0.5 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( _helper.calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawPolygon( points, 4 );
                        }

                        {
                        const qreal width( 1.1 );
                        painter.translate( 0, -1 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawPolygon( points, 4 );
                        }
                  painter.end();
                  return QIcon(realpm);
                  }

            case SP_TitleBarShadeButton: {
                  QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize, 0, 0 ), pixelMetric( QStyle::PM_SmallIconSize, 0, 0 ) );
                  realpm.fill( Qt::transparent );
                  QPixmap pm = _helper.windecoButton( buttonColor, false, 15 );
                  QPainter painter( &realpm );
                  painter.drawPixmap( 1, 1, pm );
                  painter.setRenderHints( QPainter::Antialiasing );
                        {
                        qreal width( 1.1 );
                        painter.translate( 0, 0.5 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( _helper.calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawLine( QPointF( 6.5, 6.5 ), QPointF( 8.75, 8.75 ) );
                        painter.drawLine( QPointF( 8.75, 8.75 ), QPointF( 11.0, 6.5 ) );
                        painter.drawLine( QPointF( 6.5, 11.0 ), QPointF( 11.0, 11.0 ) );
                        }

                        {
                        qreal width( 1.1 );
                        painter.translate( 0, -1 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawLine( QPointF( 6.5, 6.5 ), QPointF( 8.75, 8.75 ) );
                        painter.drawLine( QPointF( 8.75, 8.75 ), QPointF( 11.0, 6.5 ) );
                        painter.drawLine( QPointF( 6.5, 11.0 ), QPointF( 11.0, 11.0 ) );
                        }

                  painter.end();
                  return QIcon( realpm );
                  }

            case SP_TitleBarUnshadeButton: {
                  QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize, 0, 0 ), pixelMetric( QStyle::PM_SmallIconSize, 0, 0 ) );
                  realpm.fill( Qt::transparent );
                  QPixmap pm = _helper.windecoButton( buttonColor, false, 15 );
                  QPainter painter( &realpm );
                  painter.drawPixmap( 1, 1, pm );
                  painter.setRenderHints( QPainter::Antialiasing );

                        {

                        qreal width( 1.1 );
                        painter.translate( 0, 0.5 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( _helper.calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawLine( QPointF( 6.5, 8.75 ), QPointF( 8.75, 6.5 ) );
                        painter.drawLine( QPointF( 8.75, 6.5 ), QPointF( 11.0, 8.75 ) );
                        painter.drawLine( QPointF( 6.5, 11.0 ), QPointF( 11.0, 11.0 ) );
                        }

                        {
                        qreal width( 1.1 );
                        painter.translate( 0, -1 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawLine( QPointF( 6.5, 8.75 ), QPointF( 8.75, 6.5 ) );
                        painter.drawLine( QPointF( 8.75, 6.5 ), QPointF( 11.0, 8.75 ) );
                        painter.drawLine( QPointF( 6.5, 11.0 ), QPointF( 11.0, 11.0 ) );
                        }
                  painter.end();

                  return QIcon( realpm );
                  }

            case SP_TitleBarCloseButton:
            case SP_DockWidgetCloseButton: {
                  QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize, 0, 0 ), pixelMetric( QStyle::PM_SmallIconSize, 0, 0 ) );
                  realpm.fill( Qt::transparent );
                  QPixmap pm = _helper.windecoButton( buttonColor, false, 15 );
                  QPainter painter( &realpm );
                  painter.drawPixmap( 1, 1, pm );
                  painter.setRenderHints( QPainter::Antialiasing );
                  painter.setBrush( Qt::NoBrush );
                        {

                        qreal width( 1.1 );
                        painter.translate( 0, 0.5 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( _helper.calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawLine( QPointF( 6.5, 6.5 ), QPointF( 11.0, 11.0 ) );
                        painter.drawLine( QPointF( 11.0, 6.5 ), QPointF( 6.5, 11.0 ) );
                        }

                        {
                        qreal width( 1.1 );
                        painter.translate( 0, -1 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawLine( QPointF( 6.5, 6.5 ), QPointF( 11.0, 11.0 ) );
                        painter.drawLine( QPointF( 11.0, 6.5 ), QPointF( 6.5, 11.0 ) );
                        }

                  painter.end();

                  return QIcon( realpm );
                  }

            case SP_ToolBarHorizontalExtensionButton: {

                  QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize, 0, 0 ), pixelMetric( QStyle::PM_SmallIconSize, 0, 0 ) );
                  realpm.fill( Qt::transparent );
                  QPainter painter( &realpm );
                  painter.setRenderHints( QPainter::Antialiasing );
                  painter.setBrush( Qt::NoBrush );

                  painter.translate( qreal( realpm.width() ) / 2.0, qreal( realpm.height() ) / 2.0 );

                  const bool reverseLayout( option && option->direction == Qt::RightToLeft );
                  QPolygonF a = genericArrow( reverseLayout ? ArrowLeft : ArrowRight, ArrowTiny );
                        {
                        qreal width( 1.1 );
                        painter.translate( 0, 0.5 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( _helper.calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawPolyline( a );
                        }

                        {
                        qreal width( 1.1 );
                        painter.translate( 0, -1 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawPolyline( a );
                        }

                  return QIcon( realpm );
                  }

            case SP_ToolBarVerticalExtensionButton: {
                  QPixmap realpm( pixelMetric( QStyle::PM_SmallIconSize, 0, 0 ), pixelMetric( QStyle::PM_SmallIconSize, 0, 0 ) );
                  realpm.fill( Qt::transparent );
                  QPainter painter( &realpm );
                  painter.setRenderHints( QPainter::Antialiasing );
                  painter.setBrush( Qt::NoBrush );

                  QPolygonF a = genericArrow( ArrowDown, ArrowTiny );
                        {
                        qreal width( 1.1 );
                        painter.translate( 0, 0.5 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( _helper.calcLightColor( buttonColor ), width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawPolyline( a );
                        }

                        {
                        qreal width( 1.1 );
                        painter.translate( 0, -1 );
                        painter.setBrush( Qt::NoBrush );
                        painter.setPen( QPen( iconColor, width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
                        painter.drawPolyline( a );
                        }

                  return QIcon( realpm );
                  }
            case SP_MessageBoxCritical:
                  return getCachedIcon(":/data/icons/dialog-error.svg");
            case SP_MessageBoxWarning:
                  return getCachedIcon(":/data/icons/dialog-warning.svg");
            case SP_MessageBoxInformation:
                  return getCachedIcon(":/data/icons/dialog-information.svg");
            case SP_MessageBoxQuestion:
                  return getCachedIcon(":/data/icons/dialog-question.svg");
            default:
                  // return QIcon();
                  return QCommonStyle::standardIcon( standardIcon, option, widget );
            }
      }

//---------------------------------------------------------
//   getCachedIcon
//---------------------------------------------------------

QIcon MgStyle::getCachedIcon(QString key) const
      {
      QPixmap * pixmap = nullptr;
      QPixmapCache::find(key, pixmap);
      if (pixmap)
            return QIcon(*pixmap);
      else {
            QIcon* icon = new QIcon(new MIconEngine);
            icon->addFile(key);
            QPixmapCache::insert(key, icon->pixmap(48));
            return *icon;
            }
      }
