<commit_before>/****************************************************************************
* Copyright (C) 2011-2014 <NAME>
*
* GNU Lesser General Public License Usage
* This file may be used under the terms of the GNU Lesser
* General Public License version 2.1 as published by the Free Software
* Foundation and appearing in the file LICENSE.LGPL included in the
* packaging of this file.  Please review the following information to
* ensure the GNU Lesser General Public License version 2.1 requirements
* will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
*
* 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.
*****************************************************************************/

#include "material_style.h"
#include <QDebug>
#include <QStyleOptionButton>
#include <QPainter>
#include <qdrawutil.h>
#include <QPushButton>
#include <QComboBox>
#include <QGroupBox>
#include <QResource>
#include <QFontDatabase>
#include <QDirIterator>
//#include <QStyleOptionTabV3>

MaterialStyle::MaterialStyle()
{
    setObjectName(QLatin1String("Fusion"));

    loadCustomFonts();
    groupBoxFont = QFont("Myriad Pro", 10);
    groupBoxFont.setBold(true);
//    groupBoxFont.setStyleStrategy(QFont::NoAntialias);

    regularFont = QFont("Myriad Pro", 10);
//    regularFont.setLetterSpacing(QFont::AbsoluteSpacing, 0.7);
//    regularFont.setWeight(5);
//    regularFont.setPixelSize(2);
//    regularFont.setStyleStrategy(QFont::NoAntialias);
}

void MaterialStyle::drawPrimitive(QStyle::PrimitiveElement elem, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    switch (elem) {
    case PE_FrameGroupBox: {
        painter->setRenderHint(QPainter::Antialiasing);
        QFontMetrics fm(groupBoxFont);
        const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option);
        QRect textRect = fm.boundingRect(groupBox->text);
        textRect.moveTo(0, 0);
        QPixmap bPix(":/images/images/group_box_bottom.png");
        int hExtra = 0;
        int indW = 0;
        QPixmap tPix;
        int glue = 0;
        if (groupBox->subControls & SC_GroupBoxLabel) {
            hExtra = 2 * GROUP_BOX_TEXT_V_MARGIN;
            tPix = QPixmap(":/images/images/group_box_top.png");
        }
        else if (groupBox->subControls & SC_GroupBoxCheckBox) {
            hExtra = 2 * GROUP_BOX_TEXT_V_MARGIN;
            tPix = QPixmap(":/images/images/group_box_top.png");
            indW = pixelMetric(PM_IndicatorWidth, option, widget);
        }
        else {
            hExtra = 0;
            QTransform tranf;
            tranf.rotate(180);
            tPix = bPix.transformed(tranf);
            glue = 4;
        }
        int yDiv = hExtra + qMax(textRect.height(), indW) + glue;
        QRect topFrame(0, 0, groupBox->rect.width(), yDiv);
        QRect bottomFrame(0, yDiv, groupBox->rect.width(), groupBox->rect.height() - yDiv - 1);
        if (groupBox->subControls & SC_GroupBoxLabel || groupBox->subControls & SC_GroupBoxCheckBox) {
            qDrawBorderPixmap(painter, topFrame, QMargins(4, 4, 4, 4), tPix);
            qDrawBorderPixmap(painter, bottomFrame, QMargins(4, 4, 4, 4), bPix);
        }
        else {
            QPixmap px(":/images/images/frame.png");
            qDrawBorderPixmap(painter, groupBox->rect, QMargins(4, 4, 4, 4), px);
        }
        break;
    }
    case PE_IndicatorCheckBox: {
        const QStyleOptionButton *checkBox = qstyleoption_cast<const QStyleOptionButton *>(option);
        QRect indRect = subElementRect(SE_CheckBoxIndicator, option, widget);
        indRect.moveTo(option->rect.topLeft());
        if (checkBox->state & QStyle::State_Off) {
            QPixmap pxm(":/images/images/check_box_state0.png");
            qDrawBorderPixmap(painter, indRect, QMargins(2, 2, 2, 2), pxm);
        }
        else if (checkBox->state & QStyle::State_On) {
            QPixmap pxm(":/images/images/check_box_state1.png");
            qDrawBorderPixmap(painter, indRect, QMargins(3, 3, 3, 3), pxm);
        }
        else {
            QPixmap pxm(":/images/images/check_box_state2.png");
            painter->drawPixmap(indRect.topLeft(), pxm);
        }
        break;
    }
    case PE_IndicatorRadioButton: {
        const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option);
        if (btn) {
            bool checked = btn->state & QStyle::State_On;
            QString iconRes = checked ? ":/images/images/qradiobutton_chacked.png" :
                                        ":/images/images/qradiobutton.png";
            QIcon icon(iconRes);
            QIcon::State st = btn->state & QStyle::State_Enabled ? QIcon::On : QIcon::Off;
            icon.paint(painter, btn->rect, Qt::AlignCenter, QIcon::Normal, st);
        }
        break;
    }
    case PE_FrameFocusRect: {
////        QPen dashedPen(QColor());
//        painter->setOpacity(0.2);
////        painter->fillRect(option->rect, Qt::blue);
//        painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 3, 3);
        QPixmap px(":/images/images/frame.png");
        qDrawBorderPixmap(painter, option->rect, QMargins(4, 4, 4, 4), px);
        break;
    }
    case PE_Frame:
    case PE_FrameMenu:
        if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
//            if (elem == PE_FrameMenu || (frame->state & State_Sunken) || (frame->state & State_Raised)) {
//                QPixmap px(":/images/images/frame.png");
//                qDrawBorderPixmap(painter, frame->rect, QMargins(4, 4, 4, 4), px);
//            } else {
//                qDrawPlainRect(painter, frame->rect, COLOR_FRAME_BORDER, frame->lineWidth);
//            }
            painter->setPen(COLOR_FRAME_BORDER);
            painter->drawRect(frame->rect.adjusted(0, 0, -1, -1));
            break;
        }
    case PE_FrameTabWidget: {
//        painter->fillRect(option->rect, QColor(255, 0 ,0, 100));
        QPixmap px(":/images/images/tabwidget_frame.png");
        if (const QStyleOptionTabWidgetFrame *tWidget = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
            QTransform matrix;
            if (tWidget->shape == QTabBar::RoundedEast) {
                matrix.rotate(+90);
            } else if (tWidget->shape == QTabBar::RoundedSouth) {
                matrix.rotate(+180);
            } else if (tWidget->shape == QTabBar::RoundedWest) {
                matrix.rotate(+270);
            }
            QPixmap pxTransf = px.transformed(matrix);
            qDrawBorderPixmap(painter, option->rect, QMargins(4, 4, 4, 4), pxTransf);
        }

//        painter->save();
//        painter->fillRect(option->rect.adjusted(0, 0, -1, -1), tabFrameColor);
//        if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
//            QColor borderColor = outline.lighter(110);
//            QRect rect = option->rect.adjusted(0, 0, -1, -1);

//            // Shadow outline
//            if (twf->shape != QTabBar::RoundedSouth) {
//                rect.adjust(0, 0, 0, -1);
//                QColor alphaShadow(Qt::black);
//                alphaShadow.setAlpha(15);
//                painter->setPen(alphaShadow);
//                painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());            painter->setPen(borderColor);
//            }

//            // outline
//            painter->setPen(outline);
//            painter->drawRect(rect);

//            // Inner frame highlight
//            painter->setPen(d->innerContrastLine());
//            painter->drawRect(rect.adjusted(1, 1, -1, -1));

//        }
//        painter->restore();
    }
        break ;
    case PE_IndicatorTabClose: {
        QStyleHintReturn *hr = 0;
        QPixmap px(":/images/images/tab_close.png");
        QCommonStyle::drawItemPixmap(painter, option->rect, Qt::AlignCenter, px);
        if (option->state & State_MouseOver) {
            painter->setPen(QPen(COLOR_TAB_NORMAL_UL));
            painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
        }
        break;
    }
    case PE_PanelScrollAreaCorner: {
        painter->save();
        painter->setPen(COLOR_FRAME_BORDER);
        painter->setBrush(option->palette.window().color().darker());
        painter->drawRect(option->rect);
        painter->restore();
    } break;
    default:
        QCommonStyle::drawPrimitive(elem, option, painter, widget);
        break;
    }
}

void MaterialStyle::drawControl(QStyle::ControlElement ce, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    switch (ce) {
    case QStyle::CE_PushButton:
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
            drawPushButton(btn, painter, widget);
        }
        break;
    case QStyle::CE_RadioButton:
    case QStyle::CE_CheckBox: {
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
            bool isRadio = (ce == CE_RadioButton);
            QStyleOptionButton subopt = *btn;
            subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
                                                 : SE_CheckBoxIndicator, btn, widget);
            drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
                          &subopt, painter, widget);
            subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
                                                 : SE_CheckBoxContents, btn, widget);
            drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget);
            if (btn->state & State_HasFocus) {
                QStyleOptionFocusRect fropt;
                fropt.QStyleOption::operator=(*btn);
                fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
                                                    : SE_CheckBoxFocusRect, btn, widget);
                drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
            }
        }
    }
        break;
    case CE_RadioButtonLabel:
    case CE_CheckBoxLabel:
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
            uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);

            if (!styleHint(SH_UnderlineShortcut, btn, widget))
                alignment |= Qt::TextHideMnemonic;
            QPixmap pix;
            QRect textRect = btn->rect;
            if (!btn->icon.isNull()) {
                pix = btn->icon.pixmap(btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
                proxy()->drawItemPixmap(painter, btn->rect, alignment, pix);
                if (btn->direction == Qt::RightToLeft)
                    textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
                else
                    textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
            }
            if (!btn->text.isEmpty()){
                drawItemText(painter, textRect, alignment | Qt::TextShowMnemonic,
                    btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText);
            }
        }
        break;
    case CE_TabBarTab: {
//        painter->fillRect(option->rect, QColor(0, 255, 0, 100));
        painter->save();
        QRect rect = option->rect;
        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
            bool rtlHorTabs = (tab->direction == Qt::RightToLeft
                               && (tab->shape == QTabBar::RoundedNorth
                                   || tab->shape == QTabBar::RoundedSouth));
            bool selected = tab->state & State_Selected;
            bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
                            || (rtlHorTabs
                                && tab->position == QStyleOptionTab::Beginning));
            bool firstTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::Beginning)
                             || (rtlHorTabs
                                 && tab->position == QStyleOptionTab::End));
            bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
            bool hover = tab->state & State_MouseOver;
            int tabOverlap = pixelMetric(PM_TabBarTabOverlap, option, widget);
            rect = option->rect.adjusted(0, 0, (onlyOne || lastTab) ? 0 : tabOverlap, 0);

            QRect r2(rect);
            int x1 = r2.left();
            int x2 = r2.right();
            int y1 = r2.top();
            int y2 = r2.bottom();

            painter->setPen(Qt::red);

            QTransform rotMatrix;
            bool flip = false;
//            painter->setPen(Qt::blue);

            switch (tab->shape) {
            case QTabBar::RoundedNorth:
                break;
            case QTabBar::RoundedSouth:
                rotMatrix.rotate(180);
                rotMatrix.translate(0, -rect.height() + 1);
                rotMatrix.scale(-1, 1);
                painter->setTransform(rotMatrix, true);
                break;
            case QTabBar::RoundedWest:
                rotMatrix.rotate(180 + 90);
                rotMatrix.scale(-1, 1);
                flip = true;
                painter->setTransform(rotMatrix, true);
                break;
            case QTabBar::RoundedEast:
                rotMatrix.rotate(90);
                rotMatrix.translate(0, - rect.width() + 1);
                flip = true;
                painter->setTransform(rotMatrix, true);
                break;
            default:
                painter->restore();
                QCommonStyle::drawControl(ce, tab, painter, widget);
                return;
            }

            if (flip) {
                QRect tmp = rect;
                rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width());
                int temp = x1;
                x1 = y1;
                y1 = temp;
                temp = x2;
                x2 = y2;
                y2 = temp;
            }

            painter->translate(0.5, 0.5);
            QString px1Str;
            QString px2Str;
            QString statusStr;
            if (selected) {
                statusStr = "sunken";
            } else if (hover) {
                statusStr = "hover";
            } else {
                statusStr = "normal";
            }

            if (onlyOne) {
                px1Str = QString(":/images/images/tab_%1_rounded.png").arg(statusStr);
                px2Str = QString(":/images/images/tab_%1_rounded.png").arg(statusStr);
            }
            else {
                if (firstTab) {
                    px1Str = QString(":/images/images/tab_%1_rounded.png").arg(statusStr);
                    px2Str = QString(":/images/images/tab_%1_squared.png").arg(statusStr);
                } else if (lastTab) {
                    px1Str = QString(":/images/images/tab_%1_squared.png").arg(statusStr);
                    px2Str = QString(":/images/images/tab_%1_rounded.png").arg(statusStr);
                } else {
                    px1Str = QString(":/images/images/tab_%1_squared.png").arg(statusStr);
                }
            }

//            painter->setPen(Qt::red);
//            painter->setBrush(QColor(0, 0, 255, 100));
//            painter->drawRect(rect.adjusted(0, 0, -1, 0));
            QPixmap px1(px1Str);
            int test = 0;
//            painter->setRenderHint(QPainter::Antialiasing);
            if (px2Str.isEmpty()) { //una intermedia
                qDrawBorderPixmap(painter, rect.adjusted(-1, test, -1, 0), QMargins(4, 4, 4, 4), px1);
//                painter->drawPixmap(0, 0, px1);
            }
            else {
                QPixmap px2(px2Str);
//                QRect lRect = rect.adjusted(0, 0, -rect.width() / 2, 0);
                int cosmeticOffset = 1;
                qDrawBorderPixmap(painter, rect.adjusted(-cosmeticOffset, test, -rect.width() / 2, 0), QMargins(4, 4, 4, 4), px1);
                if (!px2Str.contains("squared", Qt::CaseInsensitive)) { //la ultima
                    px2 = QPixmap::fromImage(QImage(px2Str).mirrored(true, false));
                    qDrawBorderPixmap(painter, rect.adjusted(rect.width() / 2, test, -1, 0),
                                      QMargins(4, 4, 4, 4), px2);
                }
                else {
                    qDrawBorderPixmap(painter, rect.adjusted(rect.width() / 2, test, -1, 0),
                                      QMargins(4, 4, 4, 4), px2);
                }
            }

//            //###########temporal workaround
//            if (tab->shape == QTabBar::RoundedEast) {
//                qDebug() << "siiiiiiiiiiiii";
//                painter->setPen(QPen(QColor(255, 0, 0, 50), 5));
//                QPoint p1 = rect.topLeft();
//                QPoint p2 = rect.topRight();
//                p1.rx() += 4;
////                p1.ry() += 1;
//                p2.rx() -= 4;
////                p2.ry() += 1;
////                painter->drawLine(p1, p2);
//            }

            //draw the underline
            QColor uLineColor = selected ? COLOR_TAB_SELECTED_UL : COLOR_TAB_NORMAL_UL;
            painter->setPen(QPen(uLineColor, 2));
            QPoint p1 = rect.bottomLeft();
            p1.ry() -= 1;
            QPoint p2 = rect.bottomRight();
            p2.ry() -= 1;
            painter->drawLine(p1, p2);

            //draw the separation
            if (!(lastTab || onlyOne)) {
                int sepMargin = 7;
                painter->setPen(QPen(COLOR_TAB_SEPARATOR, 1));
                painter->drawLine(rect.right(), sepMargin,
                                  rect.right(), rect.height() - sepMargin);
            }

//            QRect drawRect = rect.adjusted(0, selected ? 0 : 2, 0, 3);
//            painter->setPen(outlinePen);
//            painter->save();
//            painter->setClipRect(rect.adjusted(-1, -1, 1, selected ? -2 : -3));
//            painter->setBrush(fillGradient);
//            painter->drawRoundedRect(drawRect.adjusted(0, 0, -1, -1), 2.0, 2.0);
//            painter->setBrush(Qt::NoBrush);
//            painter->setPen(Qt::red);
//            painter->drawRoundedRect(drawRect.adjusted(1, 1, -2, -1), 2.0, 2.0);
//            painter->restore();

//            if (selected) {
//                painter->fillRect(rect.left() + 1, rect.bottom() - 1, rect.width() - 2, rect.bottom() - 1, tabFrameColor);
//                painter->fillRect(QRect(rect.bottomRight() + QPoint(-2, -1), QSize(1, 1)), Qt::red);
//                painter->fillRect(QRect(rect.bottomLeft() + QPoint(0, -1), QSize(1, 1)), Qt::red);
//                painter->fillRect(QRect(rect.bottomRight() + QPoint(-1, -1), QSize(1, 1)), Qt::red);
//            }
        }

        painter->restore();

        drawControl(CE_TabBarTabLabel, option, painter, widget);
        break;
    }
    case CE_ComboBoxLabel://combopaint
        if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
            QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
            painter->save();
            painter->setClipRect(editRect);
            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);
                if (cb->editable)
                    painter->fillRect(iconRect, cb->palette.brush(QPalette::Base));
                proxy()->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) {
                proxy()->drawItemText(painter, editRect.adjusted(1, 0, -1, 0),
                                      visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
                                      cb->palette, cb->state & State_Enabled, cb->currentText,
                                      cb->editable ? QPalette::Text : QPalette::ButtonText);
            }
            painter->restore();
        }
        break;
    case CE_TabBarTabShape: {
        painter->fillRect(option->rect, QColor(0, 0, 255, 100));
        break;
    }
    case CE_TabBarTabLabel: {
        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
            QStyleOptionTabV3 tabV2(*tab);
            QRect tr = tabV2.rect;
            bool verticalTabs = tabV2.shape == QTabBar::RoundedEast
                                || tabV2.shape == QTabBar::RoundedWest
                                || tabV2.shape == QTabBar::TriangularEast
                                || tabV2.shape == QTabBar::TriangularWest;

            int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
            if (!proxy()->styleHint(SH_UnderlineShortcut, option, widget))
                alignment |= Qt::TextHideMnemonic;

            if (verticalTabs) {
                painter->save();
                int newX, newY, newRot;
                if (tabV2.shape == QTabBar::RoundedEast || tabV2.shape == QTabBar::TriangularEast) {
                    newX = tr.width() + tr.x();
                    newY = tr.y();
                    newRot = 90;
                } else {
                    newX = tr.x();
                    newY = tr.y() + tr.height();
                    newRot = -90;
                }
                QTransform m = QTransform::fromTranslate(newX, newY);
                m.rotate(newRot);
                painter->setTransform(m, true);
            }
            QRect iconRect;
            tabLayout(&tabV2, widget, &tr, &iconRect);
            tr = subElementRect(SE_TabBarTabText, option, widget); //we compute tr twice because the style may override subElementRect

            if (!tabV2.icon.isNull()) {
                QPixmap tabIcon = tabV2.icon.pixmap(tabV2.iconSize,
                                                    (tabV2.state & State_Enabled) ? QIcon::Normal
                                                                                  : QIcon::Disabled,
                                                    (tabV2.state & State_Selected) ? QIcon::On
                                                                                   : QIcon::Off);
                painter->drawPixmap(iconRect.x(), iconRect.y(), tabIcon);
            }

            QPalette pal = tab->palette;
            bool selected = tabV2.state & State_Selected;
            pal.setColor(QPalette::WindowText, selected ? COLOR_TAB_SELECTED_TEXT :
                                                          COLOR_TAB_NORMAL_TEXT);
            painter->setFont(groupBoxFont);
            drawItemText(painter, tr, alignment, pal, tab->state & State_Enabled, tab->text, QPalette::WindowText);
            if (verticalTabs)
                painter->restore();

            if (tabV2.state & State_HasFocus) {
                const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth);

                int x1, x2;
                x1 = tabV2.rect.left();
                x2 = tabV2.rect.right() - 1;

                QStyleOptionFocusRect fropt;
                fropt.QStyleOption::operator=(*tab);
                fropt.rect.setRect(x1 + 1 + OFFSET, tabV2.rect.y() + OFFSET,
                                   x2 - x1 - 2*OFFSET, tabV2.rect.height() - 2*OFFSET);
                drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
            }
        }
        break;
    }
    default:
        QCommonStyle::drawControl(ce, option, painter, widget);
        break;
    }
}

void MaterialStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
{
    switch (control) {
    case CC_GroupBox: {
        if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
            drawGroupBox(groupBox, painter, widget);
        }
        break;
    }
    case CC_Slider: {
        if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
            drawSlider(slider, painter, widget);
        }
        break;
    }
    case CC_ScrollBar:
        painter->save();
        if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
            bool horizontal = scrollBar->orientation == Qt::Horizontal;
            bool sunken = scrollBar->state & State_Sunken;

            QRect scrollBarSubLine = subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
            QRect scrollBarAddLine = subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
            QRect scrollBarSlider = subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
//            QRect scrollBarGroove = subControlRect(control, scrollBar, SC_ScrollBarGroove, widget);

            QRect rect = option->rect;
            QColor frameBorderColor = COLOR_FRAME_BORDER;

            QColor arrowColor = option->palette.foreground().color();
            arrowColor.setAlpha(220);


            // Paint groove
            if (scrollBar->subControls & SC_ScrollBarGroove) {
                painter->save();
                painter->fillRect(rect, COLOR_SCROLLBAR_GROOVE);
                painter->setPen(Qt::NoPen);

                painter->fillRect(rect.adjusted(3, 3, -2, -2), COLOR_SCROLL_GROOVE_DECO);

                painter->setPen(frameBorderColor);
                if (horizontal)
                    painter->drawLine(rect.topLeft(), rect.topRight());
                else
                    painter->drawLine(rect.topLeft(), rect.bottomLeft());
                painter->restore();
            }

            QRect pixmapRect = scrollBarSlider;

            // Paint slider
            if (scrollBar->subControls & SC_ScrollBarSlider) {
//                QRect pixmapRect = scrollBarSlider;
//                painter->setPen(QPen(Qt::green));
                if (option->state & State_Sunken && scrollBar->activeSubControls & SC_ScrollBarSlider) {
                    QPixmap px(":/images/images/slider_button_sunken.png");
                    qDrawBorderPixmap(painter, pixmapRect.adjusted(0, 0, horizontal ? 0 : 1, horizontal ? 1 : 0),
                                      QMargins(2, 2, 2, 2), px);
                }
                else if (option->state & State_MouseOver && scrollBar->activeSubControls & SC_ScrollBarSlider) {
                    QPixmap px(":/images/images/slider_button_hover.png");
                    qDrawBorderPixmap(painter, pixmapRect.adjusted(0, 0, horizontal ? 0 : 1, horizontal ? 1 : 0),
                                      QMargins(2, 2, 2, 2), px);
                }
                else { //normal
                    QPixmap px(":/images/images/slider_button_normal.png");
                    qDrawBorderPixmap(painter, pixmapRect.adjusted(0, 0, horizontal ? 0 : 1, horizontal ? 1 : 0),
                                      QMargins(2, 2, 2, 2), px);
                }


//                painter->drawRect(pixmapRect.adjusted(horizontal ? -1 : 0, horizontal ? 0 : -1, horizontal ? 0 : 1, horizontal ? 1 : 0));

//                painter->setPen(Qt::darkYellow);
//                painter->drawRect(scrollBarSlider.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, -1, -1));
            }

            // The SubLine (up/left) buttons
            if (scrollBar->subControls & SC_ScrollBarSubLine) {
//                qDebug() << "SUBLINE";
                if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken)
                    painter->setBrush(scrollBar->palette.window().color().darker(130));
                else if ((scrollBar->activeSubControls & SC_ScrollBarSubLine))
                    painter->setBrush(scrollBar->palette.window().color().darker(116));
                else
                    painter->setBrush(scrollBar->palette.window());

                painter->setPen(Qt::NoPen);
                painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0));
                painter->setPen(QPen(frameBorderColor));
                if (option->state & State_Horizontal) {
                    if (option->direction == Qt::RightToLeft) {
                        pixmapRect.setLeft(scrollBarSubLine.left());
                        painter->drawLine(pixmapRect.topLeft(), pixmapRect.bottomLeft());
                    } else {
                        pixmapRect.setRight(scrollBarSubLine.right());
                        painter->drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
                    }
                } else {
                    pixmapRect.setBottom(scrollBarSubLine.bottom());
                    painter->drawLine(pixmapRect.bottomLeft(), pixmapRect.bottomRight());
                }

//                painter->setBrush(Qt::NoBrush);
//                painter->setPen(Qt::darkGray);
//                painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0 ,  horizontal ? -2 : -1, horizontal ? -1 : -2));

                // Arrows
                int rotation = 0;
                if (option->state & State_Horizontal)
                    rotation = option->direction == Qt::LeftToRight ? -90 : 90;
                QRect upRect = scrollBarSubLine.translated(horizontal ? -2 : -1, 0);
//                QPixmap arrowPixmap = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation);
                QPixmap arrowPixmap(":/images/images/slider_frame.png");
                painter->drawPixmap(QRectF(upRect.center().x() - arrowPixmap.width() / 4.0  + 2.0,
                                          upRect.center().y() - arrowPixmap.height() / 4.0 + 1.0,
                                          arrowPixmap.width() / 2.0, arrowPixmap.height() / 2.0),
                                          arrowPixmap, QRectF(QPoint(0.0, 0.0), arrowPixmap.size()));
            }

            // The AddLine (down/right) button
            if (scrollBar->subControls & SC_ScrollBarAddLine) {
                if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken)
                    painter->setBrush(scrollBar->palette.window().color().darker(130));
                else if ((scrollBar->activeSubControls & SC_ScrollBarAddLine))
                    painter->setBrush(scrollBar->palette.window().color().darker(116));
                else
                    painter->setBrush(scrollBar->palette.window());

                painter->setPen(Qt::NoPen);
                painter->drawRect(scrollBarAddLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0));
                painter->setPen(QPen(frameBorderColor, 1));
                if (option->state & State_Horizontal) {
                    if (option->direction == Qt::LeftToRight) {
                        pixmapRect.setLeft(scrollBarAddLine.left());
                        painter->drawLine(pixmapRect.topLeft(), pixmapRect.bottomLeft());
                    } else {
                        pixmapRect.setRight(scrollBarAddLine.right());
                        painter->drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
                    }
                } else {
                    pixmapRect.setTop(scrollBarAddLine.top());
                    painter->drawLine(pixmapRect.topLeft(), pixmapRect.topRight());
                }

//                painter->setPen(Qt::darkGray);
//                painter->setBrush(Qt::NoBrush);
//                painter->drawRect(scrollBarAddLine.adjusted(1, 1, -1, -1));

                int rotation = 180;
                if (option->state & State_Horizontal)
                    rotation = option->direction == Qt::LeftToRight ? 90 : -90;
                QRect downRect = scrollBarAddLine.translated(-1, 1);
//                QPixmap arrowPixmap = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation);
                QPixmap arrowPixmap(":/images/images/slider_frame.png");
                painter->drawPixmap(QRectF(downRect.center().x() - arrowPixmap.width() / 4.0 + 2.0,
                                           downRect.center().y() - arrowPixmap.height() / 4.0,
                                           arrowPixmap.width() / 2.0, arrowPixmap.height() / 2.0),
                                           arrowPixmap, QRectF(QPoint(0.0, 0.0), arrowPixmap.size()));
            }

        }
        painter->restore();
        break;

    default:
        QCommonStyle::drawComplexControl(control, option, painter, widget);
        break;
    }


}

QRect MaterialStyle::subControlRect(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, QStyle::SubControl sc, const QWidget *widget) const
{
    QRect rect = QCommonStyle::subControlRect(cc, opt, sc, widget);
//    QRect rect;
    switch (cc) {
    case CC_GroupBox: {
        if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
            rect = opt->rect;
            int indWidth = groupBox->subControls & SC_GroupBoxCheckBox ?
                        pixelMetric(PM_IndicatorWidth, opt, widget) : 0;
//            QRect indicatorRect(GROUP_BOX_TEXT_H_MARGIN, (rect.height() - indWidth) / 2, indWidth, indWidth);

            QFontMetrics fm(groupBoxFont);
            QRect textRect = fm.boundingRect(groupBox->text);
            int stolenByText = 0;
            int stolenByIcon = 0;
            int textHeight = 0;
            int indHeight = 0;
            if (groupBox->subControls & SC_GroupBoxLabel) {
                QFontMetrics fm(groupBoxFont);
                QRect textRect = fm.boundingRect(groupBox->text);<commit_msg>combo text fixed<commit_after>/****************************************************************************
* Copyright (C) 2011-2014 <NAME>
*
* GNU Lesser General Public License Usage
* This file may be used under the terms of the GNU Lesser
* General Public License version 2.1 as published by the Free Software
* Foundation and appearing in the file LICENSE.LGPL included in the
* packaging of this file.  Please review the following information to
* ensure the GNU Lesser General Public License version 2.1 requirements
* will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
*
* 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.
*****************************************************************************/

#include "material_style.h"
#include <QDebug>
#include <QStyleOptionButton>
#include <QPainter>
#include <qdrawutil.h>
#include <QPushButton>
#include <QComboBox>
#include <QGroupBox>
#include <QResource>
#include <QFontDatabase>
#include <QDirIterator>
//#include <QStyleOptionTabV3>

MaterialStyle::MaterialStyle()
{
    setObjectName(QLatin1String("Fusion"));

    loadCustomFonts();
    groupBoxFont = QFont("Myriad Pro", 10);
    groupBoxFont.setBold(true);
//    groupBoxFont.setStyleStrategy(QFont::NoAntialias);

    regularFont = QFont("Myriad Pro", 10);
//    regularFont.setLetterSpacing(QFont::AbsoluteSpacing, 0.7);
//    regularFont.setWeight(5);
//    regularFont.setPixelSize(2);
//    regularFont.setStyleStrategy(QFont::NoAntialias);
}

void MaterialStyle::drawPrimitive(QStyle::PrimitiveElement elem, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    switch (elem) {
    case PE_FrameGroupBox: {
        painter->setRenderHint(QPainter::Antialiasing);
        QFontMetrics fm(groupBoxFont);
        const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option);
        QRect textRect = fm.boundingRect(groupBox->text);
        textRect.moveTo(0, 0);
        QPixmap bPix(":/images/images/group_box_bottom.png");
        int hExtra = 0;
        int indW = 0;
        QPixmap tPix;
        int glue = 0;
        if (groupBox->subControls & SC_GroupBoxLabel) {
            hExtra = 2 * GROUP_BOX_TEXT_V_MARGIN;
            tPix = QPixmap(":/images/images/group_box_top.png");
        }
        else if (groupBox->subControls & SC_GroupBoxCheckBox) {
            hExtra = 2 * GROUP_BOX_TEXT_V_MARGIN;
            tPix = QPixmap(":/images/images/group_box_top.png");
            indW = pixelMetric(PM_IndicatorWidth, option, widget);
        }
        else {
            hExtra = 0;
            QTransform tranf;
            tranf.rotate(180);
            tPix = bPix.transformed(tranf);
            glue = 4;
        }
        int yDiv = hExtra + qMax(textRect.height(), indW) + glue;
        QRect topFrame(0, 0, groupBox->rect.width(), yDiv);
        QRect bottomFrame(0, yDiv, groupBox->rect.width(), groupBox->rect.height() - yDiv - 1);
        if (groupBox->subControls & SC_GroupBoxLabel || groupBox->subControls & SC_GroupBoxCheckBox) {
            qDrawBorderPixmap(painter, topFrame, QMargins(4, 4, 4, 4), tPix);
            qDrawBorderPixmap(painter, bottomFrame, QMargins(4, 4, 4, 4), bPix);
        }
        else {
            QPixmap px(":/images/images/frame.png");
            qDrawBorderPixmap(painter, groupBox->rect, QMargins(4, 4, 4, 4), px);
        }
        break;
    }
    case PE_IndicatorCheckBox: {
        const QStyleOptionButton *checkBox = qstyleoption_cast<const QStyleOptionButton *>(option);
        QRect indRect = subElementRect(SE_CheckBoxIndicator, option, widget);
        indRect.moveTo(option->rect.topLeft());
        if (checkBox->state & QStyle::State_Off) {
            QPixmap pxm(":/images/images/check_box_state0.png");
            qDrawBorderPixmap(painter, indRect, QMargins(2, 2, 2, 2), pxm);
        }
        else if (checkBox->state & QStyle::State_On) {
            QPixmap pxm(":/images/images/check_box_state1.png");
            qDrawBorderPixmap(painter, indRect, QMargins(3, 3, 3, 3), pxm);
        }
        else {
            QPixmap pxm(":/images/images/check_box_state2.png");
            painter->drawPixmap(indRect.topLeft(), pxm);
        }
        break;
    }
    case PE_IndicatorRadioButton: {
        const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option);
        if (btn) {
            bool checked = btn->state & QStyle::State_On;
            QString iconRes = checked ? ":/images/images/qradiobutton_chacked.png" :
                                        ":/images/images/qradiobutton.png";
            QIcon icon(iconRes);
            QIcon::State st = btn->state & QStyle::State_Enabled ? QIcon::On : QIcon::Off;
            icon.paint(painter, btn->rect, Qt::AlignCenter, QIcon::Normal, st);
        }
        break;
    }
    case PE_FrameFocusRect: {
////        QPen dashedPen(QColor());
//        painter->setOpacity(0.2);
////        painter->fillRect(option->rect, Qt::blue);
//        painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 3, 3);
        QPixmap px(":/images/images/frame.png");
        qDrawBorderPixmap(painter, option->rect, QMargins(4, 4, 4, 4), px);
        break;
    }
    case PE_Frame:
    case PE_FrameMenu:
        if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
//            if (elem == PE_FrameMenu || (frame->state & State_Sunken) || (frame->state & State_Raised)) {
//                QPixmap px(":/images/images/frame.png");
//                qDrawBorderPixmap(painter, frame->rect, QMargins(4, 4, 4, 4), px);
//            } else {
//                qDrawPlainRect(painter, frame->rect, COLOR_FRAME_BORDER, frame->lineWidth);
//            }
            painter->setPen(COLOR_FRAME_BORDER);
            painter->drawRect(frame->rect.adjusted(0, 0, -1, -1));
            break;
        }
    case PE_FrameTabWidget: {
//        painter->fillRect(option->rect, QColor(255, 0 ,0, 100));
        QPixmap px(":/images/images/tabwidget_frame.png");
        if (const QStyleOptionTabWidgetFrame *tWidget = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
            QTransform matrix;
            if (tWidget->shape == QTabBar::RoundedEast) {
                matrix.rotate(+90);
            } else if (tWidget->shape == QTabBar::RoundedSouth) {
                matrix.rotate(+180);
            } else if (tWidget->shape == QTabBar::RoundedWest) {
                matrix.rotate(+270);
            }
            QPixmap pxTransf = px.transformed(matrix);
            qDrawBorderPixmap(painter, option->rect, QMargins(4, 4, 4, 4), pxTransf);
        }

//        painter->save();
//        painter->fillRect(option->rect.adjusted(0, 0, -1, -1), tabFrameColor);
//        if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
//            QColor borderColor = outline.lighter(110);
//            QRect rect = option->rect.adjusted(0, 0, -1, -1);

//            // Shadow outline
//            if (twf->shape != QTabBar::RoundedSouth) {
//                rect.adjust(0, 0, 0, -1);
//                QColor alphaShadow(Qt::black);
//                alphaShadow.setAlpha(15);
//                painter->setPen(alphaShadow);
//                painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());            painter->setPen(borderColor);
//            }

//            // outline
//            painter->setPen(outline);
//            painter->drawRect(rect);

//            // Inner frame highlight
//            painter->setPen(d->innerContrastLine());
//            painter->drawRect(rect.adjusted(1, 1, -1, -1));

//        }
//        painter->restore();
    }
        break ;
    case PE_IndicatorTabClose: {
        QStyleHintReturn *hr = 0;
        QPixmap px(":/images/images/tab_close.png");
        QCommonStyle::drawItemPixmap(painter, option->rect, Qt::AlignCenter, px);
        if (option->state & State_MouseOver) {
            painter->setPen(QPen(COLOR_TAB_NORMAL_UL));
            painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
        }
        break;
    }
    case PE_PanelScrollAreaCorner: {
        painter->save();
        painter->setPen(COLOR_FRAME_BORDER);
        painter->setBrush(option->palette.window().color().darker());
        painter->drawRect(option->rect);
        painter->restore();
    } break;
    default:
        QCommonStyle::drawPrimitive(elem, option, painter, widget);
        break;
    }
}

void MaterialStyle::drawControl(QStyle::ControlElement ce, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    switch (ce) {
    case QStyle::CE_PushButton:
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
            drawPushButton(btn, painter, widget);
        }
        break;
    case QStyle::CE_RadioButton:
    case QStyle::CE_CheckBox: {
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
            bool isRadio = (ce == CE_RadioButton);
            QStyleOptionButton subopt = *btn;
            subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
                                                 : SE_CheckBoxIndicator, btn, widget);
            drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
                          &subopt, painter, widget);
            subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
                                                 : SE_CheckBoxContents, btn, widget);
            drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget);
            if (btn->state & State_HasFocus) {
                QStyleOptionFocusRect fropt;
                fropt.QStyleOption::operator=(*btn);
                fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
                                                    : SE_CheckBoxFocusRect, btn, widget);
                drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
            }
        }
    }
        break;
    case CE_RadioButtonLabel:
    case CE_CheckBoxLabel:
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
            uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);

            if (!styleHint(SH_UnderlineShortcut, btn, widget))
                alignment |= Qt::TextHideMnemonic;
            QPixmap pix;
            QRect textRect = btn->rect;
            if (!btn->icon.isNull()) {
                pix = btn->icon.pixmap(btn->iconSize, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
                proxy()->drawItemPixmap(painter, btn->rect, alignment, pix);
                if (btn->direction == Qt::RightToLeft)
                    textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
                else
                    textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
            }
            if (!btn->text.isEmpty()){
                drawItemText(painter, textRect, alignment | Qt::TextShowMnemonic,
                    btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText);
            }
        }
        break;
    case CE_TabBarTab: {
//        painter->fillRect(option->rect, QColor(0, 255, 0, 100));
        painter->save();
        QRect rect = option->rect;
        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
            bool rtlHorTabs = (tab->direction == Qt::RightToLeft
                               && (tab->shape == QTabBar::RoundedNorth
                                   || tab->shape == QTabBar::RoundedSouth));
            bool selected = tab->state & State_Selected;
            bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
                            || (rtlHorTabs
                                && tab->position == QStyleOptionTab::Beginning));
            bool firstTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::Beginning)
                             || (rtlHorTabs
                                 && tab->position == QStyleOptionTab::End));
            bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
            bool hover = tab->state & State_MouseOver;
            int tabOverlap = pixelMetric(PM_TabBarTabOverlap, option, widget);
            rect = option->rect.adjusted(0, 0, (onlyOne || lastTab) ? 0 : tabOverlap, 0);

            QRect r2(rect);
            int x1 = r2.left();
            int x2 = r2.right();
            int y1 = r2.top();
            int y2 = r2.bottom();

            painter->setPen(Qt::red);

            QTransform rotMatrix;
            bool flip = false;
//            painter->setPen(Qt::blue);

            switch (tab->shape) {
            case QTabBar::RoundedNorth:
                break;
            case QTabBar::RoundedSouth:
                rotMatrix.rotate(180);
                rotMatrix.translate(0, -rect.height() + 1);
                rotMatrix.scale(-1, 1);
                painter->setTransform(rotMatrix, true);
                break;
            case QTabBar::RoundedWest:
                rotMatrix.rotate(180 + 90);
                rotMatrix.scale(-1, 1);
                flip = true;
                painter->setTransform(rotMatrix, true);
                break;
            case QTabBar::RoundedEast:
                rotMatrix.rotate(90);
                rotMatrix.translate(0, - rect.width() + 1);
                flip = true;
                painter->setTransform(rotMatrix, true);
                break;
            default:
                painter->restore();
                QCommonStyle::drawControl(ce, tab, painter, widget);
                return;
            }

            if (flip) {
                QRect tmp = rect;
                rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width());
                int temp = x1;
                x1 = y1;
                y1 = temp;
                temp = x2;
                x2 = y2;
                y2 = temp;
            }

            painter->translate(0.5, 0.5);
            QString px1Str;
            QString px2Str;
            QString statusStr;
            if (selected) {
                statusStr = "sunken";
            } else if (hover) {
                statusStr = "hover";
            } else {
                statusStr = "normal";
            }

            if (onlyOne) {
                px1Str = QString(":/images/images/tab_%1_rounded.png").arg(statusStr);
                px2Str = QString(":/images/images/tab_%1_rounded.png").arg(statusStr);
            }
            else {
                if (firstTab) {
                    px1Str = QString(":/images/images/tab_%1_rounded.png").arg(statusStr);
                    px2Str = QString(":/images/images/tab_%1_squared.png").arg(statusStr);
                } else if (lastTab) {
                    px1Str = QString(":/images/images/tab_%1_squared.png").arg(statusStr);
                    px2Str = QString(":/images/images/tab_%1_rounded.png").arg(statusStr);
                } else {
                    px1Str = QString(":/images/images/tab_%1_squared.png").arg(statusStr);
                }
            }

//            painter->setPen(Qt::red);
//            painter->setBrush(QColor(0, 0, 255, 100));
//            painter->drawRect(rect.adjusted(0, 0, -1, 0));
            QPixmap px1(px1Str);
            int test = 0;
//            painter->setRenderHint(QPainter::Antialiasing);
            if (px2Str.isEmpty()) { //una intermedia
                qDrawBorderPixmap(painter, rect.adjusted(-1, test, -1, 0), QMargins(4, 4, 4, 4), px1);
//                painter->drawPixmap(0, 0, px1);
            }
            else {
                QPixmap px2(px2Str);
//                QRect lRect = rect.adjusted(0, 0, -rect.width() / 2, 0);
                int cosmeticOffset = 1;
                qDrawBorderPixmap(painter, rect.adjusted(-cosmeticOffset, test, -rect.width() / 2, 0), QMargins(4, 4, 4, 4), px1);
                if (!px2Str.contains("squared", Qt::CaseInsensitive)) { //la ultima
                    px2 = QPixmap::fromImage(QImage(px2Str).mirrored(true, false));
                    qDrawBorderPixmap(painter, rect.adjusted(rect.width() / 2, test, -1, 0),
                                      QMargins(4, 4, 4, 4), px2);
                }
                else {
                    qDrawBorderPixmap(painter, rect.adjusted(rect.width() / 2, test, -1, 0),
                                      QMargins(4, 4, 4, 4), px2);
                }
            }

//            //###########temporal workaround
//            if (tab->shape == QTabBar::RoundedEast) {
//                qDebug() << "siiiiiiiiiiiii";
//                painter->setPen(QPen(QColor(255, 0, 0, 50), 5));
//                QPoint p1 = rect.topLeft();
//                QPoint p2 = rect.topRight();
//                p1.rx() += 4;
////                p1.ry() += 1;
//                p2.rx() -= 4;
////                p2.ry() += 1;
////                painter->drawLine(p1, p2);
//            }

            //draw the underline
            QColor uLineColor = selected ? COLOR_TAB_SELECTED_UL : COLOR_TAB_NORMAL_UL;
            painter->setPen(QPen(uLineColor, 2));
            QPoint p1 = rect.bottomLeft();
            p1.ry() -= 1;
            QPoint p2 = rect.bottomRight();
            p2.ry() -= 1;
            painter->drawLine(p1, p2);

            //draw the separation
            if (!(lastTab || onlyOne)) {
                int sepMargin = 7;
                painter->setPen(QPen(COLOR_TAB_SEPARATOR, 1));
                painter->drawLine(rect.right(), sepMargin,
                                  rect.right(), rect.height() - sepMargin);
            }

//            QRect drawRect = rect.adjusted(0, selected ? 0 : 2, 0, 3);
//            painter->setPen(outlinePen);
//            painter->save();
//            painter->setClipRect(rect.adjusted(-1, -1, 1, selected ? -2 : -3));
//            painter->setBrush(fillGradient);
//            painter->drawRoundedRect(drawRect.adjusted(0, 0, -1, -1), 2.0, 2.0);
//            painter->setBrush(Qt::NoBrush);
//            painter->setPen(Qt::red);
//            painter->drawRoundedRect(drawRect.adjusted(1, 1, -2, -1), 2.0, 2.0);
//            painter->restore();

//            if (selected) {
//                painter->fillRect(rect.left() + 1, rect.bottom() - 1, rect.width() - 2, rect.bottom() - 1, tabFrameColor);
//                painter->fillRect(QRect(rect.bottomRight() + QPoint(-2, -1), QSize(1, 1)), Qt::red);
//                painter->fillRect(QRect(rect.bottomLeft() + QPoint(0, -1), QSize(1, 1)), Qt::red);
//                painter->fillRect(QRect(rect.bottomRight() + QPoint(-1, -1), QSize(1, 1)), Qt::red);
//            }
        }

        painter->restore();

        drawControl(CE_TabBarTabLabel, option, painter, widget);
        break;
    }
    case CE_ComboBoxLabel://combopaint
        if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
            QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
            painter->save();
            painter->setClipRect(editRect);
            if (!cb->currentIcon.isNull()) {
//                qDebug() << "COMBO ICON";
                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);
                if (cb->editable)
                    painter->fillRect(iconRect, cb->palette.brush(QPalette::Base));
                proxy()->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) {
                qDebug() << "COMBO text" << cb->palette.text();
                proxy()->drawItemText(painter, editRect.adjusted(1, 0, -1, 0),
                                      visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
                                      cb->palette, cb->state & State_Enabled, cb->currentText,
                                      QPalette::Text);
            }
            painter->restore();
        }
        break;
    case CE_TabBarTabShape: {
        painter->fillRect(option->rect, QColor(0, 0, 255, 100));
        break;
    }
    case CE_TabBarTabLabel: {
        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
            QStyleOptionTabV3 tabV2(*tab);
            QRect tr = tabV2.rect;
            bool verticalTabs = tabV2.shape == QTabBar::RoundedEast
                                || tabV2.shape == QTabBar::RoundedWest
                                || tabV2.shape == QTabBar::TriangularEast
                                || tabV2.shape == QTabBar::TriangularWest;

            int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
            if (!proxy()->styleHint(SH_UnderlineShortcut, option, widget))
                alignment |= Qt::TextHideMnemonic;

            if (verticalTabs) {
                painter->save();
                int newX, newY, newRot;
                if (tabV2.shape == QTabBar::RoundedEast || tabV2.shape == QTabBar::TriangularEast) {
                    newX = tr.width() + tr.x();
                    newY = tr.y();
                    newRot = 90;
                } else {
                    newX = tr.x();
                    newY = tr.y() + tr.height();
                    newRot = -90;
                }
                QTransform m = QTransform::fromTranslate(newX, newY);
                m.rotate(newRot);
                painter->setTransform(m, true);
            }
            QRect iconRect;
            tabLayout(&tabV2, widget, &tr, &iconRect);
            tr = subElementRect(SE_TabBarTabText, option, widget); //we compute tr twice because the style may override subElementRect

            if (!tabV2.icon.isNull()) {
                QPixmap tabIcon = tabV2.icon.pixmap(tabV2.iconSize,
                                                    (tabV2.state & State_Enabled) ? QIcon::Normal
                                                                                  : QIcon::Disabled,
                                                    (tabV2.state & State_Selected) ? QIcon::On
                                                                                   : QIcon::Off);
                painter->drawPixmap(iconRect.x(), iconRect.y(), tabIcon);
            }

            QPalette pal = tab->palette;
            bool selected = tabV2.state & State_Selected;
            pal.setColor(QPalette::WindowText, selected ? COLOR_TAB_SELECTED_TEXT :
                                                          COLOR_TAB_NORMAL_TEXT);
            painter->setFont(groupBoxFont);
            drawItemText(painter, tr, alignment, pal, tab->state & State_Enabled, tab->text, QPalette::WindowText);
            if (verticalTabs)
                painter->restore();

            if (tabV2.state & State_HasFocus) {
                const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth);

                int x1, x2;
                x1 = tabV2.rect.left();
                x2 = tabV2.rect.right() - 1;

                QStyleOptionFocusRect fropt;
                fropt.QStyleOption::operator=(*tab);
                fropt.rect.setRect(x1 + 1 + OFFSET, tabV2.rect.y() + OFFSET,
                                   x2 - x1 - 2*OFFSET, tabV2.rect.height() - 2*OFFSET);
                drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
            }
        }
        break;
    }
    default:
        QCommonStyle::drawControl(ce, option, painter, widget);
        break;
    }
}

void MaterialStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
{
    switch (control) {
    case CC_GroupBox: {
        if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
            drawGroupBox(groupBox, painter, widget);
        }
        break;
    }
    case CC_Slider: {
        if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
            drawSlider(slider, painter, widget);
        }
        break;
    }
    case CC_ScrollBar:
        painter->save();
        if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
            bool horizontal = scrollBar->orientation == Qt::Horizontal;
            bool sunken = scrollBar->state & State_Sunken;

            QRect scrollBarSubLine = subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
            QRect scrollBarAddLine = subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
            QRect scrollBarSlider = subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
//            QRect scrollBarGroove = subControlRect(control, scrollBar, SC_ScrollBarGroove, widget);

            QRect rect = option->rect;
            QColor frameBorderColor = COLOR_FRAME_BORDER;

            QColor arrowColor = option->palette.foreground().color();
            arrowColor.setAlpha(220);


            // Paint groove
            if (scrollBar->subControls & SC_ScrollBarGroove) {
                painter->save();
                painter->fillRect(rect, COLOR_SCROLLBAR_GROOVE);
                painter->setPen(Qt::NoPen);

                painter->fillRect(rect.adjusted(3, 3, -2, -2), COLOR_SCROLL_GROOVE_DECO);

                painter->setPen(frameBorderColor);
                if (horizontal)
                    painter->drawLine(rect.topLeft(), rect.topRight());
                else
                    painter->drawLine(rect.topLeft(), rect.bottomLeft());
                painter->restore();
            }

            QRect pixmapRect = scrollBarSlider;

            // Paint slider
            if (scrollBar->subControls & SC_ScrollBarSlider) {
//                QRect pixmapRect = scrollBarSlider;
//                painter->setPen(QPen(Qt::green));
                if (option->state & State_Sunken && scrollBar->activeSubControls & SC_ScrollBarSlider) {
                    QPixmap px(":/images/images/slider_button_sunken.png");
                    qDrawBorderPixmap(painter, pixmapRect.adjusted(0, 0, horizontal ? 0 : 1, horizontal ? 1 : 0),
                                      QMargins(2, 2, 2, 2), px);
                }
                else if (option->state & State_MouseOver && scrollBar->activeSubControls & SC_ScrollBarSlider) {
                    QPixmap px(":/images/images/slider_button_hover.png");
                    qDrawBorderPixmap(painter, pixmapRect.adjusted(0, 0, horizontal ? 0 : 1, horizontal ? 1 : 0),
                                      QMargins(2, 2, 2, 2), px);
                }
                else { //normal
                    QPixmap px(":/images/images/slider_button_normal.png");
                    qDrawBorderPixmap(painter, pixmapRect.adjusted(0, 0, horizontal ? 0 : 1, horizontal ? 1 : 0),
                                      QMargins(2, 2, 2, 2), px);
                }


//                painter->drawRect(pixmapRect.adjusted(horizontal ? -1 : 0, horizontal ? 0 : -1, horizontal ? 0 : 1, horizontal ? 1 : 0));

//                painter->setPen(Qt::darkYellow);
//                painter->drawRect(scrollBarSlider.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, -1, -1));
            }

            // The SubLine (up/left) buttons
            if (scrollBar->subControls & SC_ScrollBarSubLine) {
//                qDebug() << "SUBLINE";
                if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken)
                    painter->setBrush(scrollBar->palette.window().color().darker(130));
                else if ((scrollBar->activeSubControls & SC_ScrollBarSubLine))
                    painter->setBrush(scrollBar->palette.window().color().darker(116));
                else
                    painter->setBrush(scrollBar->palette.window());

                painter->setPen(Qt::NoPen);
                painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0));
                painter->setPen(QPen(frameBorderColor));
                if (option->state & State_Horizontal) {
                    if (option->direction == Qt::RightToLeft) {
                        pixmapRect.setLeft(scrollBarSubLine.left());
                        painter->drawLine(pixmapRect.topLeft(), pixmapRect.bottomLeft());
                    } else {
                        pixmapRect.setRight(scrollBarSubLine.right());
                        painter->drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
                    }
                } else {
                    pixmapRect.setBottom(scrollBarSubLine.bottom());
                    painter->drawLine(pixmapRect.bottomLeft(), pixmapRect.bottomRight());
                }

//                painter->setBrush(Qt::NoBrush);
//                painter->setPen(Qt::darkGray);
//                painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0 ,  horizontal ? -2 : -1, horizontal ? -1 : -2));

                // Arrows
                int rotation = 0;
                if (option->state & State_Horizontal)
                    rotation = option->direction == Qt::LeftToRight ? -90 : 90;
                QRect upRect = scrollBarSubLine.translated(horizontal ? -2 : -1, 0);
//                QPixmap arrowPixmap = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation);
                QPixmap arrowPixmap(":/images/images/slider_frame.png");
                painter->drawPixmap(QRectF(upRect.center().x() - arrowPixmap.width() / 4.0  + 2.0,
                                          upRect.center().y() - arrowPixmap.height() / 4.0 + 1.0,
                                          arrowPixmap.width() / 2.0, arrowPixmap.height() / 2.0),
                                          arrowPixmap, QRectF(QPoint(0.0, 0.0), arrowPixmap.size()));
            }

            // The AddLine (down/right) button
            if (scrollBar->subControls & SC_ScrollBarAddLine) {
                if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken)
                    painter->setBrush(scrollBar->palette.window().color().darker(130));
                else if ((scrollBar->activeSubControls & SC_ScrollBarAddLine))
                    painter->setBrush(scrollBar->palette.window().color().darker(116));
                else
                    painter->setBrush(scrollBar->palette.window());

                painter->setPen(Qt::NoPen);
                painter->drawRect(scrollBarAddLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0));
                painter->setPen(QPen(frameBorderColor, 1));
                if (option->state & State_Horizontal) {
                    if (option->direction == Qt::LeftToRight) {
                        pixmapRect.setLeft(scrollBarAddLine.left());
                        painter->drawLine(pixmapRect.topLeft(), pixmapRect.bottomLeft());
                    } else {
                        pixmapRect.setRight(scrollBarAddLine.right());
                        painter->drawLine(pixmapRect.topRight(), pixmapRect.bottomRight());
                    }
                } else {
                    pixmapRect.setTop(scrollBarAddLine.top());
                    painter->drawLine(pixmapRect.topLeft(), pixmapRect.topRight());
                }

//                painter->setPen(Qt::darkGray);
//                painter->setBrush(Qt::NoBrush);
//                painter->drawRect(scrollBarAddLine.adjusted(1, 1, -1, -1));

                int rotation = 180;
                if (option->state & State_Horizontal)
                    rotation = option->direction == Qt::LeftToRight ? 90 : -90;
                QRect downRect = scrollBarAddLine.translated(-1, 1);
//                QPixmap arrowPixmap = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation);
                QPixmap arrowPixmap(":/images/images/slider_frame.png");
                painter->drawPixmap(QRectF(downRect.center().x() - arrowPixmap.width() / 4.0 + 2.0,
                                           downRect.center().y() - arrowPixmap.height() / 4.0,
                                           arrowPixmap.width() / 2.0, arrowPixmap.height() / 2.0),
                                           arrowPixmap, QRectF(QPoint(0.0, 0.0), arrowPixmap.size()));
            }

        }
        painter->restore();
        break;
//    case CC_ComboBox:
//        painter->save();
//        if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
//            bool hasFocus = option->state & State_HasFocus && option->state & State_KeyboardFocusChange;
//            bool sunken = comboBox->state & State_On; // play dead, if combobox has no items
//            bool isEnabled = (comboBox->state & State_Enabled);
//            QPixmap cache;
//            QString pixmapName = QStyleHelper::uniqueName(QLatin1String("combobox"), option, comboBox->rect.size());
//            if (sunken)
//                pixmapName += QLatin1String("-sunken");
//            if (comboBox->editable)
//                pixmapName += QLatin1String("-editable");
//            if (isEnabled)
//                pixmapName += QLatin1String("-enabled");

//            if (!QPixmapCache::find(pixmapName, cache)) {
//                cache = styleCachePixmap(comboBox->rect.size());
//                cache.fill(Qt::transparent);
//                QPainter cachePainter(&cache);
//                QRect pixmapRect(0, 0, comboBox->rect.width(), comboBox->rect.height());
//                QStyleOptionComboBox comboBoxCopy = *comboBox;
//                comboBoxCopy.rect = pixmapRect;

//                QRect rect = pixmapRect;
//                QRect downArrowRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy,
//                                                              SC_ComboBoxArrow, widget);
//                // Draw a line edit
//                if (comboBox->editable) {
//                    QStyleOptionFrame  buttonOption;
//                    buttonOption.QStyleOption::operator=(*comboBox);
//                    buttonOption.rect = rect;
//                    buttonOption.state = (comboBox->state & (State_Enabled | State_MouseOver | State_HasFocus))
//                            | State_KeyboardFocusChange; // Always show hig

//                    if (sunken) {
//                        buttonOption.state |= State_Sunken;
//                        buttonOption.state &= ~State_MouseOver;
//                    }

//                    proxy()->drawPrimitive(PE_FrameLineEdit, &buttonOption, &cachePainter, widget);

//                    // Draw button clipped
//                    cachePainter.save();
//                    cachePainter.setClipRect(downArrowRect.adjusted(0, 0, 1, 0));
//                    buttonOption.rect.setLeft(comboBox->direction == Qt::LeftToRight ?
//                                                  downArrowRect.left() - 6: downArrowRect.right() + 6);
//                    proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget);
//                    cachePainter.restore();
//                    cachePainter.setPen( QPen(hasFocus ? option->palette.highlight() : outline.lighter(110), 1));

//                    if (!sunken) {
//                        int borderSize = 1;
//                        if (comboBox->direction == Qt::RightToLeft) {
//                            cachePainter.drawLine(QPoint(downArrowRect.right() - 1, downArrowRect.top() + borderSize ),
//                                                  QPoint(downArrowRect.right() - 1, downArrowRect.bottom() - borderSize));
//                        } else {
//                            cachePainter.drawLine(QPoint(downArrowRect.left() , downArrowRect.top() + borderSize),
//                                                  QPoint(downArrowRect.left() , downArrowRect.bottom() - borderSize));
//                        }
//                    } else {
//                        if (comboBox->direction == Qt::RightToLeft) {
//                            cachePainter.drawLine(QPoint(downArrowRect.right(), downArrowRect.top() + 2),
//                                                  QPoint(downArrowRect.right(), downArrowRect.bottom() - 2));

//                        } else {
//                            cachePainter.drawLine(QPoint(downArrowRect.left(), downArrowRect.top() + 2),
//                                                  QPoint(downArrowRect.left(), downArrowRect.bottom() - 2));
//                        }
//                    }
//                } else {
//                    QStyleOptionButton buttonOption;
//                    buttonOption.QStyleOption::operator=(*comboBox);
//                    buttonOption.rect = rect;
//                    buttonOption.state = comboBox->state & (State_Enabled | State_MouseOver | State_HasFocus | State_KeyboardFocusChange);
//                    if (sunken) {
//                        buttonOption.state |= State_Sunken;
//                        buttonOption.state &= ~State_MouseOver;
//                    }
//                    proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget);
//                }
//                if (comboBox->subControls & SC_ComboBoxArrow) {
//                    // Draw the up/down arrow
//                    QColor arrowColor = option->palette.buttonText().color();
//                    arrowColor.setAlpha(220);
//                    QPixmap downArrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, 180);
//                    cachePainter.drawPixmap(QRectF(downArrowRect.center().x() - downArrow.width() / 4.0 + 1.0,
//                                                   downArrowRect.center().y() - downArrow.height() / 4.0 + 1.0,
//                                                   downArrow.width() / 2.0, downArrow.height() / 2.0),
//                                                   downArrow, QRectF(QPointF(0.0, 0.0), downArrow.size()));
//                }
//                cachePainter.end();
//                QPixmapCache::insert(pixmapName, cache);
//            }
//            painter->drawPixmap(comboBox->rect.topLeft(), cache);
//        }
//        painter->restore();
//        break;
    default:
        QCommonStyle::drawComplexControl(control, option, painter, widget);
        break;
    }


}

QRect MaterialStyle::subControlRect(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, QStyle::SubControl sc, const QWidget *widget) const
{
    QRect rect = QCommonStyle::subControlRect(cc, opt, sc, widget);
//    QRect rect;
    switch (cc) {
    case CC_GroupBox: {
        if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
            rect = opt->rect;
            int indWidth = groupBox->subControls & SC_GroupBoxCheckBox ?
                        pixelMetric(PM_IndicatorWidth, opt, widget) : 0;
//            QRect indicatorRect(GROUP_BOX_TEXT_H_MARGIN, (rect.height() - indWidth) / 2, indWidth, indWidth);

            QFontMetrics fm(groupBoxFont);
            QRect textRect = fm.boundingRect(groupBox->text);
            int stolenByText = 0;
            int stolenByIcon = 0;
            int textHeight = 0;
            int indHeight = 0;
            if (groupBox->subControls & SC_GroupBoxLabel) {
                QFontMetrics fm(groupBoxFont);
                QRect textRect = fm.boundingRect(groupBox->text);
{'fraction_non_alphanumeric': 0.13039611320554345, 'fraction_numerical': 0.014628577496946849, 'mean_word_length': 1.7248164357796505, 'pattern_counts': {'":': 55, '<': 74, '<?xml version=': 0, '>': 568, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 124, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4197766', 'n_tokens_mistral': 22368, 'n_tokens_neox': 20908, 'n_words': 3894}