/* * This file Copyright (C) 2012-2015 Mnemosyne LLC * * It may be used under the GNU GPL versions 2 or 3 * or any future license endorsed by Mnemosyne LLC. * */ #include #include #include #include #include "FilterBarComboBox.h" #include "FilterBarComboBoxDelegate.h" #include "StyleHelper.h" #include "Utils.h" namespace { int getHSpacing(const QWidget* w) { return qMax(3, w->style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing, 0, w)); } } // namespace FilterBarComboBoxDelegate::FilterBarComboBoxDelegate(QObject* parent, QComboBox* combo) : QItemDelegate(parent), myCombo(combo) { } bool FilterBarComboBoxDelegate::isSeparator(const QModelIndex& index) { return index.data(Qt::AccessibleDescriptionRole).toString() == QLatin1String("separator"); } void FilterBarComboBoxDelegate::setSeparator(QAbstractItemModel* model, const QModelIndex& index) { model->setData(index, QString::fromLatin1("separator"), Qt::AccessibleDescriptionRole); if (QStandardItemModel* m = qobject_cast(model)) { if (QStandardItem* item = m->itemFromIndex(index)) { item->setFlags(item->flags() & ~(Qt::ItemIsSelectable | Qt::ItemIsEnabled)); } } } void FilterBarComboBoxDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (isSeparator(index)) { QRect rect = option.rect; if (const QAbstractItemView* view = qobject_cast(option.widget)) { rect.setWidth(view->viewport()->width()); } QStyleOption opt; opt.rect = rect; myCombo->style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, painter, myCombo); } else { QStyleOptionViewItem disabledOption = option; const QPalette::ColorRole disabledColorRole = (disabledOption.state & QStyle::State_Selected) ? QPalette::HighlightedText : QPalette::Text; disabledOption.palette.setColor(disabledColorRole, Utils::getFadedColor(disabledOption.palette.color( disabledColorRole))); QRect boundingBox = option.rect; const int hmargin = getHSpacing(myCombo); boundingBox.adjust(hmargin, 0, -hmargin, 0); QRect decorationRect = rect(option, index, Qt::DecorationRole); decorationRect.setSize(myCombo->iconSize()); decorationRect = QStyle::alignedRect(option.direction, Qt::AlignLeft | Qt::AlignVCenter, decorationRect.size(), boundingBox); Utils::narrowRect(boundingBox, decorationRect.width() + hmargin, 0, option.direction); QRect countRect = rect(option, index, FilterBarComboBox::CountStringRole); countRect = QStyle::alignedRect(option.direction, Qt::AlignRight | Qt::AlignVCenter, countRect.size(), boundingBox); Utils::narrowRect(boundingBox, 0, countRect.width() + hmargin, option.direction); const QRect displayRect = boundingBox; const QIcon icon = Utils::getIconFromIndex(index); drawBackground(painter, option, index); icon.paint(painter, decorationRect, Qt::AlignCenter, StyleHelper::getIconMode(option.state), QIcon::Off); drawDisplay(painter, option, displayRect, index.data(Qt::DisplayRole).toString()); drawDisplay(painter, disabledOption, countRect, index.data(FilterBarComboBox::CountStringRole).toString()); drawFocus(painter, option, displayRect | countRect); } } QSize FilterBarComboBoxDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { if (isSeparator(index)) { const int pm = myCombo->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, myCombo); return QSize(pm, pm + 10); } else { QStyle* s = myCombo->style(); const int hmargin = getHSpacing(myCombo); QSize size = QItemDelegate::sizeHint(option, index); size.setHeight(qMax(size.height(), myCombo->iconSize().height() + 6)); size.rwidth() += s->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, myCombo); size.rwidth() += rect(option, index, FilterBarComboBox::CountStringRole).width(); size.rwidth() += hmargin * 4; return size; } }