/***************************************************************************
**
** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qpixmapstyle_p.h"
#include "qpixmapstyle_p_p.h"

#include <QDebug>
#if QT_CONFIG(textedit)
#include <QTextEdit>
#endif
#include <QStringBuilder>
#include <QPainter>
#include <QPixmapCache>
#include <QStyleOption>
#include <QString>
#if QT_CONFIG(progressbar)
#include <QProgressBar>
#endif
#if QT_CONFIG(slider)
#include <QSlider>
#endif
#include <QEvent>
#if QT_CONFIG(combobox)
#include <QComboBox>
#endif
#if QT_CONFIG(itemviews)
#include <QAbstractItemView>
#include <QStyledItemDelegate>
#endif
#if QT_CONFIG(listview)
#include <QListView>
#endif
#include <QAbstractScrollArea>
#if QT_CONFIG(scrollbar)
#include <QScrollBar>
#endif
#if QT_CONFIG(scroller)
#include <qscroller.h>
#endif

QT_BEGIN_NAMESPACE

/*!
    \class QPixmapStyle
    \brief The QPixmapStyle class provides mechanism for writing pixmap based styles.

    \since 5.7
    \ingroup appearance
    \inmodule QtWidgets
    \internal

    This is a convenience class that enables the implementation of a widget style using
    pixmaps, on the same fashion used by the \l{BorderImage} QML type.

    In order to style a QWidget, one simply needs to call QPixmapStyle::addDescriptor()
    or QPixmapStyle::addPixmap() with the id of the component to be styled, the path of
    the image to be used, the margins and the tiling rules:

    \snippet styles/qcustompixmapstyle.cpp 0

    \sa QStyle, QCommonStyle
*/

/*!
    \internal

    Constructs a QPixmapStyle object.
*/
QPixmapStyle::QPixmapStyle()
    : QCommonStyle(*new QPixmapStylePrivate)
{
}

/*!
    Destroys the QPixmapStyle object.
*/
QPixmapStyle::~QPixmapStyle()
{
}

/*!
    \reimp
*/
void QPixmapStyle::polish(QApplication *application)
{
    QCommonStyle::polish(application);
}

/*!
    \reimp
*/
void QPixmapStyle::polish(QPalette &palette)
{
    palette = proxy()->standardPalette();
}

/*!
    \reimp
*/
void QPixmapStyle::polish(QWidget *widget)
{
    Q_D(QPixmapStyle);

    // Don't fill the interior of the QTextEdit
#if QT_CONFIG(textedit)
    if (qobject_cast<QTextEdit*>(widget)) {
        QPalette p = widget->palette();
        p.setBrush(QPalette::Base, Qt::NoBrush);
        widget->setPalette(p);
    }
#endif
#if QT_CONFIG(progressbar)
    if (QProgressBar *pb = qobject_cast<QProgressBar*>(widget)) {
        // Center the text in the progress bar
        pb->setAlignment(Qt::AlignCenter);
        // Change the font size if needed, as it's used to compute the minimum size
        QFont font = pb->font();
        font.setPixelSize(d->descriptors.value(PB_HBackground).size.height()/2);
        pb->setFont(font);
    }
#endif
#if QT_CONFIG(slider)
    if (qobject_cast<QSlider*>(widget))
        widget->installEventFilter(this);
#endif
#if QT_CONFIG(combobox)
    if (QComboBox *cb = qobject_cast<QComboBox*>(widget)) {
        widget->installEventFilter(this);
        // NOTE: This will break if the private API of QComboBox changes drastically
        // Make sure the popup is created so we can change the frame style
        QAbstractItemView *list = cb->view();
        list->setProperty("_pixmap_combobox_list", true);
        list->setItemDelegate(new QStyledItemDelegate(list));
        QPalette p = list->palette();
        p.setBrush(QPalette::Active, QPalette::Base, QBrush(Qt::transparent) );
        p.setBrush(QPalette::Active, QPalette::AlternateBase, QBrush(Qt::transparent) );
        p.setBrush(QPalette::Inactive, QPalette::Base, QBrush(Qt::transparent) );
        p.setBrush(QPalette::Inactive, QPalette::AlternateBase, QBrush(Qt::transparent) );
        p.setBrush(QPalette::Disabled, QPalette::Base, QBrush(Qt::transparent) );
        p.setBrush(QPalette::Disabled, QPalette::AlternateBase, QBrush(Qt::transparent) );
        list->setPalette(p);

        QFrame *frame = qobject_cast<QFrame*>(list->parent());
        if (frame) {
            const QPixmapStyleDescriptor &desc = d->descriptors.value(DD_PopupDown);
            const QPixmapStylePixmap &pix = d->pixmaps.value(DD_ItemSeparator);
            frame->setContentsMargins(pix.margins.left(), desc.margins.top(),
                                      pix.margins.right(), desc.margins.bottom());
            frame->setAttribute(Qt::WA_TranslucentBackground);
        }
    }
#endif // QT_CONFIG(combobox)
    if (qstrcmp(widget->metaObject()->className(),"QComboBoxPrivateContainer") == 0)
        widget->installEventFilter(this);

#if QT_CONFIG(scrollarea)
    if (QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea*>(widget)) {
        scrollArea->viewport()->setAutoFillBackground(false);
#if QT_CONFIG(itemviews)
        if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(scrollArea)) {
            view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
            view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
        }
#endif
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
        QScroller::grabGesture(scrollArea->viewport(), QScroller::LeftMouseButtonGesture);
#endif
    }
#endif // QT_CONFIG(scrollarea)
#if QT_CONFIG(scrollbar)
    if (qobject_cast<QScrollBar*>(widget))
        widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
#endif
#if !QT_CONFIG(progressbar) && !QT_CONFIG(combobox)
    Q_UNUSED(d);
#endif
    QCommonStyle::polish(widget);
}

/*!
    \reimp
*/
void QPixmapStyle::unpolish(QApplication *application)
{
    QCommonStyle::unpolish(application);
}

/*!
    \reimp
*/
void QPixmapStyle::unpolish(QWidget *widget)
{
    if (
#if QT_CONFIG(slider)
        qobject_cast<QSlider*>(widget)
#else
        false
#endif
#if QT_CONFIG(combobox)
          ||  qobject_cast<QComboBox*>(widget)
#endif
        ) {
        widget->removeEventFilter(this);
    }

    if (qstrcmp(widget->metaObject()->className(),"QComboBoxPrivateContainer") == 0)
        widget->removeEventFilter(this);

#if QT_CONFIG(gestures) && QT_CONFIG(scrollarea) && QT_CONFIG(scroller)
    if (QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea*>(widget))
        QScroller::ungrabGesture(scrollArea->viewport());
#endif

    QCommonStyle::unpolish(widget);
}

/*!
    \reimp
*/
void QPixmapStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                                 QPainter *painter, const QWidget *widget) const
{
    switch (element) {
    case PE_FrameFocusRect: //disable focus rectangle
        break;
    case PE_PanelButtonBevel:
    case PE_PanelButtonCommand:
        drawPushButton(option, painter, widget);
        break;
    case PE_PanelLineEdit:
    case PE_FrameLineEdit:
        drawLineEdit(option, painter, widget);
        break;
    case PE_Frame:
#if QT_CONFIG(textedit)
    case PE_FrameDefaultButton:
        if (qobject_cast<const QTextEdit*>(widget))
            drawTextEdit(option, painter, widget);
        break;
#endif
    case PE_IndicatorCheckBox:
        drawCheckBox(option, painter, widget);
        break;
    case PE_IndicatorRadioButton:
        drawRadioButton(option, painter, widget);
        break;
    case PE_PanelItemViewItem:
#if QT_CONFIG(listview)
        if (qobject_cast<const QListView*>(widget))
            drawPanelItemViewItem(option, painter, widget);
        else
#endif
            QCommonStyle::drawPrimitive(element, option, painter, widget);
        break;
    default:
        QCommonStyle::drawPrimitive(element, option, painter, widget);
    }
}

/*!
    \reimp
*/
void QPixmapStyle::drawControl(ControlElement element, const QStyleOption *option,
                               QPainter *painter, const QWidget *widget) const
{
    Q_D(const QPixmapStyle);

    switch (element) {
    case CE_ProgressBarGroove:
        drawProgressBarBackground(option, painter, widget);
        break;
    case CE_ProgressBarLabel:
        drawProgressBarLabel(option, painter, widget);
        break;
    case CE_ProgressBarContents:
        drawProgressBarFill(option, painter, widget);
        break;
    case CE_ShapedFrame:
        // NOTE: This will break if the private API of QComboBox changes drastically
        if (qstrcmp(widget->metaObject()->className(),"QComboBoxPrivateContainer") == 0) {
            const QPixmapStyleDescriptor &desc = d->descriptors.value(DD_PopupDown);
            const QPixmapStylePixmap &pix = d->pixmaps.value(DD_ItemSeparator);
            QRect rect = option->rect;
            rect.adjust(-pix.margins.left(), -desc.margins.top(),
                        pix.margins.right(), desc.margins.bottom());
            bool up = widget->property("_pixmapstyle_combobox_up").toBool();
            drawCachedPixmap(up ? DD_PopupUp : DD_PopupDown, rect, painter);
        }
        else {
            QCommonStyle::drawControl(element, option, painter, widget);
        }
        break;
    default:
        QCommonStyle::drawControl(element, option, painter, widget);
    }
}

/*!
    \reimp
*/
void QPixmapStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option,
                                      QPainter *painter, const QWidget *widget) const
{
    switch (cc) {
    case CC_Slider:
        drawSlider(option, painter, widget);
        break;
    case CC_ComboBox:
        drawComboBox(option, painter, widget);
        break;
    case CC_ScrollBar:
        drawScrollBar(option, painter, widget);
        break;
    default:
        QCommonStyle::drawComplexControl(cc, option, painter, widget);
    }
}

/*!
    \reimp
*/
QSize QPixmapStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
                                     const QSize &contentsSize, const QWidget *widget) const
{
    switch (type) {
    case CT_PushButton:
        return pushButtonSizeFromContents(option, contentsSize, widget);
    case CT_LineEdit:
        return lineEditSizeFromContents(option, contentsSize, widget);
    case CT_ProgressBar:
        return progressBarSizeFromContents(option, contentsSize, widget);
    case CT_Slider:
        return sliderSizeFromContents(option, contentsSize, widget);
    case CT_ComboBox:
        return comboBoxSizeFromContents(option, contentsSize, widget);
    case CT_ItemViewItem:
        return itemViewSizeFromContents(option, contentsSize, widget);
    default: ;
    }

    return QCommonStyle::sizeFromContents(type, option, contentsSize, widget);
}

/*!
    \reimp
*/
QRect QPixmapStyle::subElementRect(SubElement element, const QStyleOption *option,
                                   const QWidget *widget) const
{
    Q_D(const QPixmapStyle);

    switch (element) {
    case SE_LineEditContents:
    {
        QRect rect = QCommonStyle::subElementRect(element, option, widget);
        const QPixmapStyleDescriptor &desc = d->descriptors.value(LE_Enabled);
        rect.adjust(desc.margins.left(), desc.margins.top(),
                    -desc.margins.right(), -desc.margins.bottom());
        rect = visualRect(option->direction, option->rect, rect);
        return rect;
    }
    default: ;
    }

    return QCommonStyle::subElementRect(element, option, widget);
}

/*!
    \reimp
*/
QRect QPixmapStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option,
                                   SubControl sc, const QWidget *widget) const
{
    switch (cc) {
    case CC_ComboBox:
        return comboBoxSubControlRect(option, sc, widget);
    case CC_ScrollBar:
        return scrollBarSubControlRect(option, sc, widget);
    default: ;
    }

    return QCommonStyle::subControlRect(cc, option, sc, widget);
}

/*!
    \reimp
*/
int QPixmapStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
                              const QWidget *widget) const
{
    Q_D(const QPixmapStyle);

    switch (metric) {
    case PM_ButtonShiftHorizontal:
    case PM_ButtonShiftVertical:
        return 0;
    case PM_DefaultFrameWidth:
#if QT_CONFIG(textedit)
        if (qobject_cast<const QTextEdit*>(widget)) {
            const QPixmapStyleDescriptor &desc = d->descriptors.value(LE_Enabled);
            return qMax(qMax(desc.margins.left(), desc.margins.right()),
                        qMax(desc.margins.top(), desc.margins.bottom()));
        }
#endif
        return 0;
    case PM_IndicatorWidth:
        return d->pixmaps.value(CB_Enabled).pixmap.width();
    case PM_IndicatorHeight:
        return d->pixmaps.value(CB_Enabled).pixmap.height();
    case PM_CheckBoxLabelSpacing:
    {
        const QPixmapStylePixmap &pix = d->pixmaps.value(CB_Enabled);
        return qMax(qMax(pix.margins.left(), pix.margins.right()),
                    qMax(pix.margins.top(), pix.margins.bottom()));
    }
    case PM_ExclusiveIndicatorWidth:
        return d->pixmaps.value(RB_Enabled).pixmap.width();
    case PM_ExclusiveIndicatorHeight:
        return d->pixmaps.value(RB_Enabled).pixmap.height();
    case PM_RadioButtonLabelSpacing:
    {
        const QPixmapStylePixmap &pix = d->pixmaps.value(RB_Enabled);
        return qMax(qMax(pix.margins.left(), pix.margins.right()),
                    qMax(pix.margins.top(), pix.margins.bottom()));
    }
#if QT_CONFIG(slider)
    case PM_SliderThickness:
        if (const QStyleOptionSlider *slider =
                    qstyleoption_cast<const QStyleOptionSlider*>(option)) {
            const QPixmapStyleDescriptor desc =
                d->descriptors.value(slider->orientation == Qt::Horizontal
                                     ? SG_HEnabled : SG_VEnabled);
            return slider->orientation == Qt::Horizontal
                                                ? desc.size.height() : desc.size.width();
        }
        break;
    case PM_SliderControlThickness:
        if (const QStyleOptionSlider *slider =
                    qstyleoption_cast<const QStyleOptionSlider*>(option)) {
            const QPixmapStylePixmap pix =
                    d->pixmaps.value(slider->orientation == Qt::Horizontal
                                     ? SH_HEnabled : SH_VEnabled);
            return slider->orientation == Qt::Horizontal
                                                ? pix.pixmap.height() : pix.pixmap.width();
        }
        break;
    case PM_SliderLength:
        if (const QStyleOptionSlider *slider =
                    qstyleoption_cast<const QStyleOptionSlider*>(option)) {
            const QPixmapStylePixmap pix =
                    d->pixmaps.value(slider->orientation == Qt::Horizontal
                                     ? SH_HEnabled : SH_VEnabled);
            return slider->orientation == Qt::Horizontal
                                                ? pix.pixmap.width() : pix.pixmap.height();
        }
        break;
    case PM_ScrollBarExtent:
        if (const QStyleOptionSlider *slider =
                    qstyleoption_cast<const QStyleOptionSlider*>(option)) {
            const QPixmapStyleDescriptor desc =
                    d->descriptors.value(slider->orientation == Qt::Horizontal
                                         ? SB_Horizontal : SB_Vertical);
            return slider->orientation == Qt::Horizontal
                                                ? desc.size.height() : desc.size.width();
        }
        break;
#endif // QT_CONFIG(slider)
    case PM_ScrollBarSliderMin:
        return 0;
    default: ;
    }

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

/*!
    \reimp
*/
int QPixmapStyle::styleHint(StyleHint hint, const QStyleOption *option,
                            const QWidget *widget, QStyleHintReturn *returnData) const
{
    switch (hint) {
    case SH_EtchDisabledText:
        return false;
    case SH_ComboBox_Popup:
        return false;
    default: ;
    }

    return QCommonStyle::styleHint(hint, option, widget, returnData);
}

/*!
    \reimp
*/
QStyle::SubControl QPixmapStyle::hitTestComplexControl(QStyle::ComplexControl control,
                                                       const QStyleOptionComplex *option,
                                                       const QPoint &pos,
                                                       const QWidget *widget) const
{
    const SubControl sc = QCommonStyle::hitTestComplexControl(control, option, pos, widget);
    if (control == CC_ScrollBar) {
        if (sc == SC_ScrollBarAddLine)
            return SC_ScrollBarAddPage;
        else if (sc == SC_ScrollBarSubLine)
            return SC_ScrollBarSubPage;
    }

    return sc;
}

/*!
    \reimp
*/
bool QPixmapStyle::eventFilter(QObject *watched, QEvent *event)
{
    Q_D(QPixmapStyle);
#if QT_CONFIG(slider)
    if (QSlider *slider = qobject_cast<QSlider*>(watched)) {
        switch (event->type()) {
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonRelease:
        case QEvent::MouseMove:
            slider->update();
            break;
        default: ;
        }
    }
#endif // QT_CONFIG(slider)
#if QT_CONFIG(combobox)
    if (QComboBox *comboBox = qobject_cast<QComboBox*>(watched)) {
        switch (event->type()) {
        case QEvent::MouseButtonPress:
            event->ignore();
            comboBox->setProperty("_pixmapstyle_combobox_pressed", true);
            comboBox->repaint();
            return true;
        case QEvent::MouseButtonRelease:
            comboBox->setProperty("_pixmapstyle_combobox_pressed", false);
            comboBox->repaint();
            if ( comboBox->view() ) {
                if ( comboBox->view()->isVisible() || (!comboBox->isEnabled()))
                    comboBox->hidePopup();
                else
                    comboBox->showPopup();
            }
            break;
        default: ;
        }
    }
#endif // QT_CONFIG(combobox)

    if (qstrcmp(watched->metaObject()->className(),"QComboBoxPrivateContainer") == 0) {
        if (event->type() == QEvent::Show) {
            QWidget *widget = qobject_cast<QWidget*>(watched);
            int yPopup = widget->geometry().top();
            int yCombo = widget->parentWidget()->mapToGlobal(QPoint(0, 0)).y();
            QRect geom = widget->geometry();
            const QPixmapStyleDescriptor &desc = d->descriptors.value(DD_ButtonEnabled);
            const bool up = yPopup < yCombo;
            geom.moveTop(geom.top() + (up ? desc.margins.top() : -desc.margins.bottom()));
            widget->setGeometry(geom);
            widget->setProperty("_pixmapstyle_combobox_up", up);
            widget->parentWidget()->setProperty("_pixmapstyle_combobox_up", up);
        }
    }

    return QCommonStyle::eventFilter(watched, event);
}

/*!
    \fn void QPixmapStyle::addDescriptor(QPixmapStyle::ControlDescriptor control, const QString &fileName, QMargins margins, QTileRules tileRules)

    Associates the pixmap having the given \a fileName with the given \a control. The \a margins parameter describe the boundaries
    of the pixmap's top-left, top-right, bottom-left and bottom-right corners, as well as the left, right, top and bottorm segments
    and the middle. The \a tileRules parameter describes how QPixmapStyle is supposed to handle the scaling of the center of the  pixmap.

    Use QPixmapStyle::addPixmap() for controls that are not resizable.

    \snippet styles/qcustompixmapstyle.cpp 1

    \sa addPixmap, copyDescriptor

*/
void QPixmapStyle::addDescriptor(QPixmapStyle::ControlDescriptor control, const QString &fileName,
                                 QMargins margins, QTileRules tileRules)
{
    Q_D(QPixmapStyle);

    QPixmapStyleDescriptor desc;
    QImage image(fileName);

    if (image.isNull())
        return;

    desc.fileName = fileName;
    desc.margins = margins;
    desc.tileRules = tileRules;
    desc.size = image.size();

    d->descriptors[control] = desc;
}

/*!
    \fn void QPixmapStyle::copyDescriptor(QPixmapStyle::ControlDescriptor source, QPixmapStyle::ControlDescriptor dest)

    Copies the data associated with the \a source descriptor to the \a dest descriptor.

    \snippet styles/qcustompixmapstyle.cpp 2
*/

void QPixmapStyle::copyDescriptor(QPixmapStyle::ControlDescriptor source,
                                  QPixmapStyle::ControlDescriptor dest)
{
    Q_D(QPixmapStyle);
    d->descriptors[dest] = d->descriptors.value(source);
}

/*!
    \fn void QPixmapStyle::drawCachedPixmap(QPixmapStyle::ControlDescriptor control, const QRect &rect, QPainter *painter) const

    Draws the image associated with the current \a control on the given \a rect using the given \a painter.
*/
void QPixmapStyle::drawCachedPixmap(QPixmapStyle::ControlDescriptor control, const QRect &rect,
                                    QPainter *p) const
{
    Q_D(const QPixmapStyle);
    auto descriptor = d->descriptors.constFind(control);
    if (descriptor == d->descriptors.constEnd())
        return;
    const QPixmap pix = d->getCachedPixmap(control, descriptor.value(), rect.size());
    Q_ASSERT(!pix.isNull());
    p->drawPixmap(rect, pix);
}

/*!
    \fn void QPixmapStyle::addPixmap(ControlPixmap control, const QString &fileName, QMargins margins)

    Use this function to style statically sized controls such as check boxes.

    \sa addDescriptor, copyPixmap
*/
void QPixmapStyle::addPixmap(ControlPixmap control, const QString &fileName,
                             QMargins margins)
{
    Q_D(QPixmapStyle);

    QPixmapStylePixmap pix;
    QPixmap image(fileName);

    if (image.isNull())
        return;

    pix.pixmap = image;
    pix.margins = margins;

    d->pixmaps[control] = pix;
}

/*
    \fn void QPixmapStyle::copyPixmap(QPixmapStyle::ControlPixmap source, QPixmapStyle::ControlPixmap dest)

    Copies the data associated with the \a source pixmap to the \a dest pixmap.

    \sa addPixmap, addDescriptor, copyDescriptor
*/
void QPixmapStyle::copyPixmap(QPixmapStyle::ControlPixmap source, QPixmapStyle::ControlPixmap dest)
{
    Q_D(QPixmapStyle);
    d->pixmaps[dest] = d->pixmaps.value(source);
}

/*!
    \internal

    Constructs a QPixmapStyle object.
*/
QPixmapStyle::QPixmapStyle(QPixmapStylePrivate &dd)
    : QCommonStyle(dd)
{}

void QPixmapStyle::drawPushButton(const QStyleOption *option,
                                  QPainter *painter, const QWidget *) const
{
    const bool checked = option->state & State_On;
    const bool pressed = option->state & State_Sunken;
    const bool enabled = option->state & State_Enabled;

    ControlDescriptor control = PB_Enabled;
    if (enabled)
        control = pressed ? PB_Pressed : (checked ? PB_Checked : PB_Enabled);
    else
        control = checked ? PB_PressedDisabled : PB_Disabled;
    drawCachedPixmap(control, option->rect, painter);
}

void QPixmapStyle::drawLineEdit(const QStyleOption *option,
                                QPainter *painter, const QWidget *widget) const
{
    // Don't draw for the line edit inside a combobox
#if QT_CONFIG(combobox)
    if (widget && qobject_cast<const QComboBox*>(widget->parentWidget()))
        return;
#else
    Q_UNUSED(widget);
#endif
    const bool enabled = option->state & State_Enabled;
    const bool focused = option->state & State_HasFocus;
    ControlDescriptor control = enabled ? (focused ? LE_Focused : LE_Enabled) : LE_Disabled;
    drawCachedPixmap(control, option->rect, painter);
}

void QPixmapStyle::drawTextEdit(const QStyleOption *option,
                                QPainter *painter, const QWidget *) const
{
    const bool enabled = option->state & State_Enabled;
    const bool focused = option->state & State_HasFocus;
    ControlDescriptor control = enabled ? (focused ? TE_Focused : TE_Enabled) : TE_Disabled;
    drawCachedPixmap(control, option->rect, painter);
}

void QPixmapStyle::drawCheckBox(const QStyleOption *option,
                                QPainter *painter, const QWidget *) const
{
    Q_D(const QPixmapStyle);

    const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option);

    const bool down = button->state & State_Sunken;
    const bool enabled = button->state & State_Enabled;
    const bool on = button->state & State_On;

    ControlPixmap control;
    if (enabled)
        control = on ? (down ? CB_PressedChecked : CB_Checked) : (down ? CB_Pressed : CB_Enabled);
    else
        control = on ? CB_DisabledChecked : CB_Disabled;
    painter->drawPixmap(button->rect, d->pixmaps.value(control).pixmap);
}

void QPixmapStyle::drawRadioButton(const QStyleOption *option,
                                   QPainter *painter, const QWidget *) const
{
    Q_D(const QPixmapStyle);

    const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option);

    const bool down = button->state & State_Sunken;
    const bool enabled = button->state & State_Enabled;
    const bool on = button->state & State_On;

    ControlPixmap control;
    if (enabled)
        control = on ? RB_Checked : (down ? RB_Pressed : RB_Enabled);
    else
        control = on ? RB_DisabledChecked : RB_Disabled;
    painter->drawPixmap(button->rect, d->pixmaps.value(control).pixmap);
}

void QPixmapStyle::drawPanelItemViewItem(const QStyleOption *option, QPainter *painter,
                                         const QWidget *widget) const
{
    Q_D(const QPixmapStyle);

    ControlPixmap cp = ID_Separator;
    ControlDescriptor cd = ID_Selected;

    if (widget && widget->property("_pixmap_combobox_list").toBool()) {
        cp = DD_ItemSeparator;
        cd = DD_ItemSelected;
    }

    QPixmap pix = d->pixmaps.value(cp).pixmap;
    QRect rect = option->rect;
    rect.setBottom(rect.top() + pix.height()-1);
    painter->drawPixmap(rect, pix);
    if (option->state & QStyle::State_Selected) {
        rect = option->rect;
        rect.setTop(rect.top() + pix.height());
        drawCachedPixmap(cd, rect, painter);
    }
}

void QPixmapStyle::drawProgressBarBackground(const QStyleOption *option,
                                             QPainter *painter, const QWidget *) const
{
    bool vertical = false;
    if (const QStyleOptionProgressBar *pb =
            qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
        vertical = pb->orientation == Qt::Vertical;
    }
    drawCachedPixmap(vertical ? PB_VBackground : PB_HBackground, option->rect, painter);
}

void QPixmapStyle::drawProgressBarLabel(const QStyleOption *option,
                                        QPainter *painter, const QWidget *) const
{
    if (const QStyleOptionProgressBar *pb =
                    qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
        const bool vertical = pb->orientation == Qt::Vertical;
        if (!vertical) {
            QPalette::ColorRole textRole = QPalette::ButtonText;
            proxy()->drawItemText(painter, pb->rect,
                                  Qt::AlignCenter | Qt::TextSingleLine, pb->palette,
                                  pb->state & State_Enabled, pb->text, textRole);
        }
    }
}

void QPixmapStyle::drawProgressBarFill(const QStyleOption *option,
                                       QPainter *painter, const QWidget *) const
{
    const QStyleOptionProgressBar *pbar =
                qstyleoption_cast<const QStyleOptionProgressBar*>(option);
    const bool vertical = pbar->orientation == Qt::Vertical;
    const bool flip = (pbar->direction == Qt::RightToLeft) ^ pbar->invertedAppearance;

    if (pbar->progress == pbar->maximum) {
        drawCachedPixmap(vertical ? PB_VComplete : PB_HComplete, option->rect, painter);

    } else {
        if (pbar->progress == pbar->minimum)
            return;
        const auto totalSteps = qint64(pbar->maximum) - pbar->minimum;
        const auto progressSteps = qint64(pbar->progress) - pbar->minimum;
        const auto availablePixels = vertical ? option->rect.height() : option->rect.width();
        const auto pixelsPerStep = double(availablePixels) / totalSteps;

        const auto progress = static_cast<int>(progressSteps * pixelsPerStep); // width in pixels

        QRect optRect = option->rect;
        if (vertical) {
            if (flip)
                optRect.setBottom(optRect.top()+progress-1);
            else
                optRect.setTop(optRect.bottom()-progress+1);
        } else {
            if (flip)
                optRect.setLeft(optRect.right()-progress+1);
            else
                optRect.setRight(optRect.left()+progress-1);
        }

        drawCachedPixmap(vertical ? PB_VContent : PB_HContent, optRect, painter);
    }
}

void QPixmapStyle::drawSlider(const QStyleOptionComplex *option,
                              QPainter *painter, const QWidget *widget) const
{
#if QT_CONFIG(slider)
    Q_D(const QPixmapStyle);

    const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option);
    if (!slider)
        return;

    const bool enabled = option->state & State_Enabled;
    const bool pressed = option->state & State_Sunken;
    const Qt::Orientation orient = slider->orientation;

    const QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
    if (option->subControls & SC_SliderGroove) {
        QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
        if (groove.isValid()) {
            // Draw the background
            ControlDescriptor control;
            if (orient == Qt::Horizontal)
                control = enabled ? SG_HEnabled : SG_HDisabled;
            else
                control = enabled ? SG_VEnabled : SG_VDisabled;
            drawCachedPixmap(control, groove, painter);

            // Draw the active part
            if (orient == Qt::Horizontal) {
                control = enabled ? (pressed ? SG_HActivePressed : SG_HActiveEnabled )
                                  : SG_HActiveDisabled;
            } else {
                control = enabled ? (pressed ? SG_VActivePressed : SG_VActiveEnabled )
                                  : SG_VActiveDisabled;
            }
            const QPixmapStyleDescriptor &desc = d->descriptors.value(control);
            const QPixmap pix = d->getCachedPixmap(control, desc, groove.size());
            if (!pix.isNull()) {
                groove.setRight(orient == Qt::Horizontal
                               ? handle.center().x() : handle.center().y());
                painter->drawPixmap(groove, pix, groove);
            }
        }
    }
    if (option->subControls & SC_SliderHandle) {
        if (handle.isValid()) {
            ControlPixmap pix;
            if (orient == Qt::Horizontal)
                pix = enabled ? (pressed ? SH_HPressed : SH_HEnabled) : SH_HDisabled;
            else
                pix = enabled ? (pressed ? SH_VPressed : SH_VEnabled) : SH_VDisabled;
            painter->drawPixmap(handle, d->pixmaps.value(pix).pixmap);
        }
    }
#else
    Q_UNUSED(option);
    Q_UNUSED(painter);
    Q_UNUSED(widget);
#endif // QT_CONFIG(slider)
}

void QPixmapStyle::drawComboBox(const QStyleOptionComplex *option,
                                QPainter *painter, const QWidget *widget) const
{
    Q_D(const QPixmapStyle);

    const bool enabled = option->state & State_Enabled;
    const bool pressed = widget->property("_pixmapstyle_combobox_pressed").toBool();
    const bool opened = option->state & State_On;

    ControlDescriptor control =
        enabled ? (pressed ? DD_ButtonPressed : DD_ButtonEnabled) : DD_ButtonDisabled;
    drawCachedPixmap(control, option->rect, painter);

    ControlPixmap cp = enabled ? (opened ? DD_ArrowOpen
                                    : (pressed ? DD_ArrowPressed : DD_ArrowEnabled))
                                    : DD_ArrowDisabled;
    QPixmapStylePixmap pix = d->pixmaps.value(cp);
    QRect rect = comboBoxSubControlRect(option, SC_ComboBoxArrow, widget);
    painter->drawPixmap(rect, pix.pixmap);
}

void QPixmapStyle::drawScrollBar(const QStyleOptionComplex *option,
                                 QPainter *painter, const QWidget *widget) const
{
#if QT_CONFIG(slider)
    if (const QStyleOptionSlider *slider =
                    qstyleoption_cast<const QStyleOptionSlider*>(option)) {
        // Do not draw the scrollbar
        if (slider->minimum == slider->maximum)
            return;

        QRect rect = scrollBarSubControlRect(option, SC_ScrollBarSlider, widget);
        ControlDescriptor control = slider->orientation == Qt::Horizontal
                ? SB_Horizontal : SB_Vertical;
        drawCachedPixmap(control, rect, painter);
    }
#else
    Q_UNUSED(option);
    Q_UNUSED(painter);
    Q_UNUSED(widget);
#endif // QT_CONFIG(slider)
}

QSize QPixmapStyle::pushButtonSizeFromContents(const QStyleOption *option,
                                               const QSize &contentsSize,
                                               const QWidget *widget) const
{
    Q_D(const QPixmapStyle);

    const QPixmapStyleDescriptor &desc = d->descriptors.value(PB_Enabled);
    const int bm = proxy()->pixelMetric(PM_ButtonMargin, option, widget);

    int w = contentsSize.width();
    int h = contentsSize.height();
    w += desc.margins.left() + desc.margins.right() + bm;
    h += desc.margins.top() + desc.margins.bottom() + bm;

    return d->computeSize(desc, w, h);
}

QSize QPixmapStyle::lineEditSizeFromContents(const QStyleOption *,
                                             const QSize &contentsSize, const QWidget *) const
{
    Q_D(const QPixmapStyle);

    const QPixmapStyleDescriptor &desc = d->descriptors.value(LE_Enabled);
    const int border = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth);

    int w = contentsSize.width() + border + desc.margins.left() + desc.margins.right();
    int h = contentsSize.height() + border + desc.margins.top() + desc.margins.bottom();

    return d->computeSize(desc, w, h);
}

QSize QPixmapStyle::progressBarSizeFromContents(const QStyleOption *option,
                                                const QSize &contentsSize,
                                                const QWidget *widget) const
{
    Q_D(const QPixmapStyle);

    bool vertical = false;
    if (const QStyleOptionProgressBar *pb =
                    qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
        vertical = pb->orientation == Qt::Vertical;
    }
    QSize result = QCommonStyle::sizeFromContents(CT_Slider, option, contentsSize, widget);
    if (vertical) {
        const QPixmapStyleDescriptor desc = d->descriptors.value(PB_VBackground);
        return QSize(desc.size.height(), result.height());
    } else {
        const QPixmapStyleDescriptor desc = d->descriptors.value(PB_HBackground);
        return QSize(result.width(), desc.size.height());
    }
}

QSize QPixmapStyle::sliderSizeFromContents(const QStyleOption *option,
                                           const QSize &contentsSize,
                                           const QWidget *widget) const
{
#if QT_CONFIG(slider)
    Q_D(const QPixmapStyle);

    const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option);
    if (!slider)
        return QSize();

    QSize result = QCommonStyle::sizeFromContents(CT_Slider, option, contentsSize, widget);

    const QPixmapStyleDescriptor desc = d->descriptors.value(slider->orientation == Qt::Horizontal
                                                ? SG_HEnabled : SG_VEnabled);

    if (slider->orientation == Qt::Horizontal)
        return QSize(result.width(), desc.size.height());
    else
        return QSize(desc.size.width(), result.height());
#else // QT_CONFIG(slider)
    Q_UNUSED(option);
    Q_UNUSED(contentsSize);
    Q_UNUSED(widget);
    return QSize();
#endif // QT_CONFIG(slider)
}

QSize QPixmapStyle::comboBoxSizeFromContents(const QStyleOption *option,
                                             const QSize &contentsSize,
                                             const QWidget *widget) const
{
    Q_D(const QPixmapStyle);

    const QPixmapStyleDescriptor &desc = d->descriptors.value(DD_ButtonEnabled);

    QSize result = QCommonStyle::sizeFromContents(CT_ComboBox, option, contentsSize, widget);
    return d->computeSize(desc, result.width(), result.height());
}

QSize QPixmapStyle::itemViewSizeFromContents(const QStyleOption *option,
                                             const QSize &contentsSize,
                                             const QWidget *widget) const
{
    Q_D(const QPixmapStyle);

    QSize size = QCommonStyle::sizeFromContents(CT_ItemViewItem, option, contentsSize, widget);

    ControlPixmap cp = ID_Separator;
    ControlDescriptor cd = ID_Selected;
    if (widget && widget->property("_pixmap_combobox_list").toBool()) {
        cp = DD_ItemSeparator;
        cd = DD_ItemSelected;
    }

    const QPixmapStyleDescriptor &desc = d->descriptors.value(cd);
    const QPixmapStylePixmap &pix = d->pixmaps.value(cp);
    size.setHeight(qMax(size.height(),
                        desc.size.height() + pix.pixmap.height()));
    return size;
}

QRect QPixmapStyle::comboBoxSubControlRect(const QStyleOptionComplex *option,
                                           QStyle::SubControl sc, const QWidget *) const
{
    Q_D(const QPixmapStyle);

    QRect r = option->rect; // Default size
    const QPixmapStylePixmap &pix = d->pixmaps.value(DD_ArrowEnabled);
    const QPixmapStyleDescriptor &desc = d->descriptors.value(DD_ButtonEnabled);

    switch (sc) {
    case SC_ComboBoxArrow:
        r.setRect(r.right() - pix.margins.right() - pix.pixmap.width(),
                    r.top() + pix.margins.top(),
                    pix.pixmap.width(), pix.pixmap.height());
        break;
    case SC_ComboBoxEditField:
        r.adjust(desc.margins.left(), desc.margins.right(),
                 -desc.margins.right(), -desc.margins.bottom());
        r.setRight(r.right() - pix.margins.right() - pix.margins.left() - pix.pixmap.width());
        break;
    default:
        break;
    }

    r = visualRect(option->direction, option->rect, r);
    return r;
}

QRect QPixmapStyle::scrollBarSubControlRect(const QStyleOptionComplex *option,
                                            QStyle::SubControl sc, const QWidget *) const
{
#if QT_CONFIG(slider)
    if (const QStyleOptionSlider *slider =
                qstyleoption_cast<const QStyleOptionSlider*>(option)) {
        int length = (slider->orientation == Qt::Horizontal)
                ? slider->rect.width() : slider->rect.height();
        int page = length * slider->pageStep
                / (slider->maximum - slider->minimum + slider->pageStep);
        int pos = length * slider->sliderValue
                / (slider->maximum - slider->minimum + slider->pageStep);
        pos = qMin(pos+page, length) - page;

        QRect rect = slider->rect;

        if (slider->orientation == Qt::Horizontal) {
            switch (sc) {
            case SC_ScrollBarAddPage:
                rect.setLeft(pos+page);
                return rect;
            case SC_ScrollBarSubPage:
                rect.setRight(pos);
                return rect;
            case SC_ScrollBarGroove:
                return rect;
            case SC_ScrollBarSlider:
                rect.setLeft(pos);
                rect.setRight(pos+page);
                return rect;
            default: ;
            }
        } else {
            switch (sc) {
            case SC_ScrollBarAddPage:
                rect.setTop(pos+page);
                return rect;
            case SC_ScrollBarSubPage:
                rect.setBottom(pos);
                return rect;
            case SC_ScrollBarGroove:
                return rect;
            case SC_ScrollBarSlider:
                rect.setTop(pos);
                rect.setBottom(pos+page);
                return rect;
            default: ;
            }
        }
    }
#else
    Q_UNUSED(option);
    Q_UNUSED(sc);
#endif // QT_CONFIG(slider)
    return QRect();
}

QPixmap QPixmapStylePrivate::scale(int w, int h, const QPixmap &pixmap, const QPixmapStyleDescriptor &desc)
{
    QPixmap result(w, h);
    {
        const QColor transparent(0, 0, 0, 0);
        result.fill( transparent );
        QPainter p( &result );
        const QMargins margins = desc.margins;
        qDrawBorderPixmap(&p, result.rect(), margins, pixmap,
                          pixmap.rect(), margins, desc.tileRules);
    }
    return result;
}

QPixmap QPixmapStylePrivate::getCachedPixmap(QPixmapStyle::ControlDescriptor control,
                                             const QPixmapStyleDescriptor &desc,
                                             const QSize &size) const
{
    Q_Q(const QPixmapStyle);

    const QString sizeString = QString::number(size.width()) % QLatin1Char('*')
            % QString::number(size.height());
    const QString key = QLatin1String(q->metaObject()->className()) % QString::number(control)
            % QLatin1Char('@') % sizeString;

    QPixmap result;

    if (!QPixmapCache::find( key, &result)) {
        QPixmap source(desc.fileName);
        result = scale(size.width(), size.height(), source, desc);
        QPixmapCache::insert(key, result);
    }
    return result;
}

QSize QPixmapStylePrivate::computeSize(const QPixmapStyleDescriptor &desc, int width, int height) const
{
    if (desc.tileRules.horizontal != Qt::RepeatTile)
        width = qMax(width, desc.size.width());
    if (desc.tileRules.vertical != Qt::RepeatTile)
        height = qMax(height, desc.size.height());
    return QSize(width, height);
}

QT_END_NAMESPACE
