bool QDecorationStyled::paint(QPainter *painter, const QWidget *widget, int decorationRegion,
                            DecorationState state)
{
    if (decorationRegion == None)
        return false;

    bool isActive = (widget == qApp->activeWindow());
    QPalette pal = qApp->palette();
    //ideally, the difference between Active and Inactive should be enough, so we shouldn't need to test this
    if (!isActive) {
        //pal.setCurrentColorGroup(QPalette::Disabled); //Can't do this either, because of palette limitations
        //copied from Q3TitleBar:
	pal.setColor(QPalette::Inactive, QPalette::Highlight,
		     pal.color(QPalette::Inactive, QPalette::Dark));
        pal.setColor(QPalette::Inactive, QPalette::Base,
                      pal.color(QPalette::Inactive, QPalette::Dark));
        pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
                      pal.color(QPalette::Inactive, QPalette::Window));
    }

    Qt::WindowFlags flags = widget->windowFlags();
    bool hasBorder = !widget->isMaximized();
    bool hasTitle = flags & Qt::WindowTitleHint;
    bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
    bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
    bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
    bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;

    bool paintAll = (DecorationRegion(decorationRegion) == All);
    bool handled = false;

    QStyle *style = QApplication::style();

    // In the case of a borderless title bar, the title bar must be expanded one
    // borderWidth to the left, right and up.
    bool noTitleBorder = style->styleHint(QStyle::SH_TitleBar_NoBorder, 0, widget);
    int borderWidth = style->pixelMetric(QStyle::PM_MDIFrameWidth, 0, 0);
    int titleHeight = titleBarHeight(widget) + (noTitleBorder ? borderWidth : 0);
    int titleExtra = noTitleBorder ? borderWidth : 0;

    if ((paintAll || decorationRegion & Borders) && state == Normal && hasBorder) {
        QRegion newClip = painter->clipRegion();
        if (hasTitle) { // reduce flicker
            QRect rect(widget->rect());
            QRect r(rect.left() - titleExtra, rect.top() - titleHeight,
                    rect.width() + 2 * titleExtra, titleHeight);
            newClip -= r;
        }
        if (!newClip.isEmpty()) {
            QRect br = QDecoration::region(widget).boundingRect();
            painter->save();
            painter->setClipRegion(newClip);

            QStyleOptionFrame opt;
            opt.palette = pal;
            opt.rect = br;
            opt.lineWidth = borderWidth;

            if (isActive)
                opt.state |= QStyle::State_Active;
            bool porterDuff = painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff);
            if (porterDuff)
                painter->setCompositionMode(QPainter::CompositionMode_Source);
            painter->fillRect(br, pal.window());
            if (porterDuff)
                painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
            style->drawPrimitive(QStyle::PE_FrameWindow, &opt, painter, 0);
            painter->restore();

            decorationRegion &= (~Borders);
            handled |= true;
        }
    }

    if (hasTitle) {
        painter->save();

        QStyleOptionTitleBar opt;
        opt.subControls = (decorationRegion & Title
                              ? QStyle::SC_TitleBarLabel : QStyle::SubControl(0))
                          | (decorationRegion & Menu
                              ? QStyle::SC_TitleBarSysMenu : QStyle::SubControl(0))
                          | (decorationRegion & Help
                              ? QStyle::SC_TitleBarContextHelpButton : QStyle::SubControl(0))
                          | (decorationRegion & Minimize
                              ? QStyle::SC_TitleBarMinButton : QStyle::SubControl(0))
                          | (decorationRegion & Maximize
                              ? QStyle::SC_TitleBarMaxButton : QStyle::SubControl(0))
                          | (decorationRegion & (Minimize | Maximize)
                              ? QStyle::SC_TitleBarNormalButton : QStyle::SubControl(0))
                          | (decorationRegion & Close
                              ? QStyle::SC_TitleBarCloseButton : QStyle::SubControl(0));
        opt.titleBarFlags = widget->windowFlags();
        opt.titleBarState = widget->windowState();
        if (isActive)
            opt.titleBarState |= QStyle::State_Active;
        opt.text = windowTitleFor(widget);
        opt.icon = widget->windowIcon();
        opt.palette = pal;
        opt.rect = QRect(widget->rect().x() - titleExtra, -titleHeight,
                         widget->rect().width() + 2 * titleExtra, titleHeight);

        if (paintAll) {
            painter->setClipRegion(opt.rect);
        } else {
            const QRect widgetRect = widget->rect();
            QRegion newClip = opt.rect;
            if (!(decorationRegion & Menu) && hasSysMenu)
                newClip -= region(widget, widgetRect, Menu);
            if (!(decorationRegion & Title) && hasTitle)
                newClip -= region(widget, widgetRect, Title);
            if (!(decorationRegion & Help) && hasContextHelp)
                newClip -= region(widget, widgetRect, Help);
            if (!(decorationRegion & Minimize) && hasMinimize)
                newClip -= region(widget, widgetRect, Minimize);
            if (!(decorationRegion & Maximize) && hasMaximize)
                newClip -= region(widget, widgetRect, Maximize);
            if (!(decorationRegion & (Minimize | Maximize)) && (hasMaximize | hasMinimize))
                newClip -= region(widget, widgetRect, Normal);
            if (!(decorationRegion & Close))
                newClip -= region(widget, widgetRect, Close);
            painter->setClipRegion(newClip);
        }

        if (state == Pressed)
            opt.activeSubControls = opt.subControls;

        style->drawComplexControl(QStyle::CC_TitleBar, &opt, painter, 0);
        painter->restore();

        decorationRegion &= ~(Title | Menu | Help | Normalize | Minimize | Maximize | Close);
        handled |= true;
    }

    return handled;
}
Beispiel #2
0
/*!\reimp
*/
void QLabel::paintEvent(QPaintEvent *)
{
    Q_D(QLabel);
    QStyle *style = QWidget::style();
    QPainter painter(this);
    drawFrame(&painter);
    QRect cr = contentsRect();
    cr.adjust(d->margin, d->margin, -d->margin, -d->margin);
    int align = QStyle::visualAlignment(d->isTextLabel ? d->textDirection()
                                                       : layoutDirection(), QFlag(d->align));

#if QT_CONFIG(movie)
    if (d->movie) {
        if (d->scaledcontents)
            style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap().scaled(cr.size()));
        else
            style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap());
    }
    else
#endif
    if (d->isTextLabel) {
        QRectF lr = d->layoutRect().toAlignedRect();
        QStyleOption opt;
        opt.initFrom(this);
#ifndef QT_NO_STYLE_STYLESHEET
        if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
            cssStyle->styleSheetPalette(this, &opt, &opt.palette);
        }
#endif
        if (d->control) {
#ifndef QT_NO_SHORTCUT
            const bool underline = (bool)style->styleHint(QStyle::SH_UnderlineShortcut, 0, this, 0);
            if (d->shortcutId != 0
                && underline != d->shortcutCursor.charFormat().fontUnderline()) {
                QTextCharFormat fmt;
                fmt.setFontUnderline(underline);
                d->shortcutCursor.mergeCharFormat(fmt);
            }
#endif
            d->ensureTextLayouted();

            QAbstractTextDocumentLayout::PaintContext context;
            // Adjust the palette
            context.palette = opt.palette;

            if (foregroundRole() != QPalette::Text && isEnabled())
                context.palette.setColor(QPalette::Text, context.palette.color(foregroundRole()));

            painter.save();
            painter.translate(lr.topLeft());
            painter.setClipRect(lr.translated(-lr.x(), -lr.y()));
            d->control->setPalette(context.palette);
            d->control->drawContents(&painter, QRectF(), this);
            painter.restore();
        } else {
            int flags = align | (d->textDirection() == Qt::LeftToRight ? Qt::TextForceLeftToRight
                                                                       : Qt::TextForceRightToLeft);
            if (d->hasShortcut) {
                flags |= Qt::TextShowMnemonic;
                if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt, this))
                    flags |= Qt::TextHideMnemonic;
            }
            style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole());
        }
    } else
#ifndef QT_NO_PICTURE
    if (d->picture) {
        QRect br = d->picture->boundingRect();
        int rw = br.width();
        int rh = br.height();
        if (d->scaledcontents) {
            painter.save();
            painter.translate(cr.x(), cr.y());
            painter.scale((double)cr.width()/rw, (double)cr.height()/rh);
            painter.drawPicture(-br.x(), -br.y(), *d->picture);
            painter.restore();
        } else {
            int xo = 0;
            int yo = 0;
            if (align & Qt::AlignVCenter)
                yo = (cr.height()-rh)/2;
            else if (align & Qt::AlignBottom)
                yo = cr.height()-rh;
            if (align & Qt::AlignRight)
                xo = cr.width()-rw;
            else if (align & Qt::AlignHCenter)
                xo = (cr.width()-rw)/2;
            painter.drawPicture(cr.x()+xo-br.x(), cr.y()+yo-br.y(), *d->picture);
        }
    } else
#endif
    if (d->pixmap && !d->pixmap->isNull()) {
        QPixmap pix;
        if (d->scaledcontents) {
            QSize scaledSize = cr.size() * devicePixelRatioF();
            if (!d->scaledpixmap || d->scaledpixmap->size() != scaledSize) {
                if (!d->cachedimage)
                    d->cachedimage = new QImage(d->pixmap->toImage());
                delete d->scaledpixmap;
                QImage scaledImage =
                    d->cachedimage->scaled(scaledSize,
                                           Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
                d->scaledpixmap = new QPixmap(QPixmap::fromImage(scaledImage));
                d->scaledpixmap->setDevicePixelRatio(devicePixelRatioF());
            }
            pix = *d->scaledpixmap;
        } else
            pix = *d->pixmap;
        QStyleOption opt;
        opt.initFrom(this);
        if (!isEnabled())
            pix = style->generatedIconPixmap(QIcon::Disabled, pix, &opt);
        style->drawItemPixmap(&painter, cr, align, pix);
    }
}
QRegion QDecorationStyled::region(const QWidget *widget, const QRect &rect, int decorationRegion)
{
    QStyle *style = QApplication::style();

    // In the case of a borderless title bar, the title bar must be expanded one
    // borderWidth to the left, right and up.
    bool noTitleBorder = style->styleHint(QStyle::SH_TitleBar_NoBorder, 0, widget);
    int borderWidth = style->pixelMetric(QStyle::PM_MDIFrameWidth, 0, 0);
    int titleHeight = titleBarHeight(widget) + (noTitleBorder ? borderWidth : 0);
    int titleExtra = noTitleBorder ? borderWidth : 0;

    QRect inside = QRect(rect.x() - titleExtra, rect.top() - titleHeight,
                         rect.width() + 2 * titleExtra, titleHeight);

    Qt::WindowFlags flags = widget->windowFlags();
    bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
    bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
    bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
    bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;

    QStyleOptionTitleBar opt;
    opt.subControls = QStyle::SC_TitleBarLabel
                      | QStyle::SC_TitleBarSysMenu
                      | QStyle::SC_TitleBarNormalButton
                      | QStyle::SC_TitleBarMinButton
                      | QStyle::SC_TitleBarMaxButton
                      | QStyle::SC_TitleBarCloseButton;
    opt.titleBarFlags = widget->windowFlags();
    opt.direction = QApplication::layoutDirection();
    opt.text = windowTitleFor(widget);
    opt.icon = widget->windowIcon();
    opt.rect = inside;

    QRegion region;
    switch (decorationRegion) {
    case Title:
        region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                       QStyle::SC_TitleBarLabel, 0);
        break;
    case Menu:
        if (hasSysMenu)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarSysMenu, 0);
        break;
    case Help:
        if (hasContextHelp)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarContextHelpButton,
                                           0);
        break;
    case Normalize:
        if (hasMaximize | hasMinimize)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarNormalButton,
                                           0);
        break;
    case Minimize:
        if (hasMinimize)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarMinButton,
                                           0);
        break;
    case Maximize:
        if (hasMaximize)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarMaxButton,
                                           0);
        break;
    case Close:
        region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                       QStyle::SC_TitleBarCloseButton, 0);
        break;

    default:
        region = QDecorationDefault::region(widget, rect, decorationRegion);
    }

    opt.rect = QRect(rect.x() - titleExtra, rect.top() - titleHeight,
                         rect.width() + 2 * titleExtra,
                         rect.height() + titleHeight + titleExtra);

    QStyleHintReturnMask mask;
    style->styleHint(QStyle::SH_WindowFrame_Mask, &opt, 0, &mask);

    return (mask.region.isEmpty() ? region : (region & mask.region));
}
Beispiel #4
0
void LedgerDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    QStyleOptionViewItem opt = option;
    initStyleOption(&opt, index);

    // never change the background of the cell the mouse is hovering over
    opt.state &= ~QStyle::State_MouseOver;

    // show the focus only on the detail column
    opt.state &= ~QStyle::State_HasFocus;
    if(index.column() == LedgerModel::DetailColumn) {
        QAbstractItemView* view = qobject_cast< QAbstractItemView* >(parent());
        if(view) {
            if(view->currentIndex().row() == index.row()) {
                opt.state |= QStyle::State_HasFocus;
            }
        }
    }

    painter->save();

    // Background
    QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
    style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);

    // Do not paint text if the edit widget is shown
    const LedgerView *view = qobject_cast<const LedgerView *>(opt.widget);
    if (view && view->indexWidget(index)) {
        painter->restore();
        return;
    }

    const int margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
    const QRect textArea = QRect(opt.rect.x() + margin, opt.rect.y() + margin, opt.rect.width() - 2 * margin, opt.rect.height() - 2 * margin);

    QStringList lines;
    if(index.column() == LedgerModel::DetailColumn) {
        lines << index.model()->data(index, LedgerModel::PayeeNameRole).toString();
        lines << index.model()->data(index, LedgerModel::CounterAccountRole).toString();
        lines << index.model()->data(index, LedgerModel::SingleLineMemoRole).toString();
        lines.removeAll(QString());
    }

    const bool erroneous = index.model()->data(index, LedgerModel::ErroneousRole).toBool();
    const bool selected = opt.state & QStyle::State_Selected;

    // draw the text items
    if(!opt.text.isEmpty() || !lines.isEmpty()) {

        // check if it is a scheduled transaction and display it as inactive
        if(!index.model()->data(index, LedgerModel::ScheduleIdRole).toString().isEmpty()) {
            opt.state &= ~QStyle::State_Enabled;
        }

        QPalette::ColorGroup cg = (opt.state & QStyle::State_Enabled)
                                  ? QPalette::Normal : QPalette::Disabled;

        if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) {
            cg = QPalette::Inactive;
        }
        if (opt.state & QStyle::State_Selected) {
            painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
        } else {
            painter->setPen(opt.palette.color(cg, QPalette::Text));
        }
        if (opt.state & QStyle::State_Editing) {
            painter->setPen(opt.palette.color(cg, QPalette::Text));
            painter->drawRect(textArea.adjusted(0, 0, -1, -1));
        }

        // Don't play with the color if it's selected
        // otherwise switch the color if the transaction has errors
        if(erroneous && !selected) {
            painter->setPen(m_erroneousColor);
        }

        // collect data for the various colums
        if(index.column() == LedgerModel::DetailColumn) {
            for(int i = 0; i < lines.count(); ++i) {
                painter->drawText(textArea.adjusted(0, (opt.fontMetrics.lineSpacing() + 5) * i, 0, 0), opt.displayAlignment, lines[i]);
            }

        } else {
            painter->drawText(textArea, opt.displayAlignment, opt.text);
        }
    }

    // draw the focus rect
    if(opt.state & QStyle::State_HasFocus) {
        QStyleOptionFocusRect o;
        o.QStyleOption::operator=(opt);
        o.rect = style->proxy()->subElementRect(QStyle::SE_ItemViewItemFocusRect, &opt, opt.widget);
        o.state |= QStyle::State_KeyboardFocusChange;
        o.state |= QStyle::State_Item;

        QPalette::ColorGroup cg = (opt.state & QStyle::State_Enabled)
                                  ? QPalette::Normal : QPalette::Disabled;
        o.backgroundColor = opt.palette.color(cg, (opt.state & QStyle::State_Selected)
                                              ? QPalette::Highlight : QPalette::Window);
        style->proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter, opt.widget);
    }

    if((index.column() == LedgerModel::DetailColumn)
            && erroneous) {
        QPixmap attention;
        attention.loadFromData(attentionSign, sizeof(attentionSign), 0, 0);
        style->proxy()->drawItemPixmap(painter, option.rect, Qt::AlignRight | Qt::AlignTop, attention);
    }

    painter->restore();
#if 0
    const QHeaderView* horizontalHeader = view->horizontalHeader();
    const QHeaderView* verticalHeader = view->verticalHeader();
    const QWidget* viewport = view->viewport();
    const bool showGrid = view->showGrid() && !view->indexWidget(index);
    const int gridSize = showGrid ? 1 : 0;
    const int gridHint = style->styleHint(QStyle::SH_Table_GridLineColor, &option, view);
    const QColor gridColor = static_cast<QRgb>(gridHint);
    const QPen gridPen = QPen(gridColor, 0, view->gridStyle());
    const bool rightToLeft = view->isRightToLeft();
    const int viewportOffset = horizontalHeader->offset();


    // QStyledItemDelegate::paint(painter, opt, index);

    if(!horizontalHeader->isSectionHidden(LedgerModel::DateColumn)) {
        QDate postDate = index.data(LedgerModel::PostDateRole).toDate();
        if(postDate.isValid()) {
            int ofs = horizontalHeader->sectionViewportPosition(LedgerModel::DateColumn) + viewportOffset;
            QRect oRect = opt.rect;
            opt.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
            opt.rect.setLeft(opt.rect.left()+ofs);
            opt.rect.setTop(opt.rect.top()+margin);
            opt.rect.setWidth(horizontalHeader->sectionSize(LedgerModel::DateColumn));
            opt.text = KGlobal::locale()->formatDate(postDate, QLocale::ShortFormat);
            style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
            opt.rect = oRect;
        }
    }

    if(!horizontalHeader->isSectionHidden(LedgerModel::DetailColumn)) {
        QString payee = index.data(LedgerModel::PayeeRole).toString();
        QString counterAccount = index.data(LedgerModel::CounterAccountRole).toString();
        QString txt = payee;
        if(payee.length() > 0)
            txt += '\n';
        txt += counterAccount;
        int ofs = horizontalHeader->sectionViewportPosition(LedgerModel::DetailColumn) + viewportOffset;
        QRect oRect = opt.rect;
        opt.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
        opt.rect.setLeft(opt.rect.left()+ofs);
        opt.rect.setTop(opt.rect.top()+margin);
        opt.rect.setWidth(horizontalHeader->sectionSize(LedgerModel::DetailColumn));
        opt.text = txt;
        style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
        opt.rect = oRect;

    }
#if 0
    opt.features |= QStyleOptionViewItemV2::HasDisplay;
    QString txt = QString("%1").arg(index.isValid() ? "true" : "false");
    if(index.isValid())
        txt += QString(" %1 - %2").arg(index.row()).arg(view->verticalHeader()->sectionViewportPosition(index.row()));
    opt.text = displayText(txt, opt.locale);

    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
#endif

    // paint grid
    if(showGrid) {
        painter->save();
        QPen old = painter->pen();
        painter->setPen(gridPen);

        // qDebug() << "Paint grid for" << index.row() << "in" << opt.rect;
        for(int i=0; i < horizontalHeader->count(); ++i) {
            if(!horizontalHeader->isSectionHidden(i)) {
                int ofs = horizontalHeader->sectionViewportPosition(i) + viewportOffset;
                if(!rightToLeft) {
                    ofs += horizontalHeader->sectionSize(i) - gridSize;
                }
                if(ofs-viewportOffset < viewport->width()) {
                    // I have no idea, why I need to paint the grid for the selected row and the one below
                    // but it was the only way to get this working correctly. Otherwise the grid was missing
                    // while moving the mouse over the view from bottom to top.
                    painter->drawLine(opt.rect.x()+ofs, opt.rect.y(), opt.rect.x()+ofs, opt.rect.height());
                    painter->drawLine(opt.rect.x()+ofs, opt.rect.y()+verticalHeader->sectionSize(index.row()), opt.rect.x()+ofs, opt.rect.height());
                }
            }
        }
        painter->setPen(old);
        painter->restore();
    }
#endif
}