/* * 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 "FilterBarComboBox.h" #include "StyleHelper.h" #include "Utils.h" namespace { int getHSpacing (const QWidget * w) { return qMax (3, w->style ()->pixelMetric (QStyle::PM_LayoutHorizontalSpacing, 0, w)); } } FilterBarComboBox::FilterBarComboBox (QWidget * parent): QComboBox (parent) { setSizeAdjustPolicy (QComboBox::AdjustToContents); } int FilterBarComboBox::currentCount () const { int count = 0; const QModelIndex modelIndex = model ()->index (currentIndex (), 0, rootModelIndex ()); if (modelIndex.isValid ()) count = modelIndex.data (CountRole).toInt (); return count; } QSize FilterBarComboBox::minimumSizeHint () const { QFontMetrics fm (fontMetrics ()); const QSize textSize = fm.boundingRect (itemText (0)).size (); const QSize countSize = fm.boundingRect (itemData (0, CountStringRole).toString ()).size (); return calculateSize (textSize, countSize); } QSize FilterBarComboBox::sizeHint () const { QFontMetrics fm (fontMetrics ()); QSize maxTextSize (0, 0); QSize maxCountSize (0, 0); for (int i = 0, n = count (); i < n; ++i) { const QSize textSize = fm.boundingRect (itemText (i)).size (); maxTextSize.setHeight (qMax (maxTextSize.height (), textSize.height ())); maxTextSize.setWidth (qMax (maxTextSize.width (), textSize.width ())); const QSize countSize = fm.boundingRect (itemData (i, CountStringRole).toString ()).size (); maxCountSize.setHeight (qMax (maxCountSize.height (), countSize.height ())); maxCountSize.setWidth (qMax (maxCountSize.width (), countSize.width ())); } return calculateSize (maxTextSize, maxCountSize); } QSize FilterBarComboBox::calculateSize (const QSize& textSize, const QSize& countSize) const { const int hmargin = getHSpacing (this); QStyleOptionComboBox option; initStyleOption (&option); QSize contentSize = iconSize () + QSize (4, 2); contentSize.setHeight (qMax (contentSize.height (), textSize.height ())); contentSize.rwidth () += hmargin + textSize.width (); contentSize.rwidth () += hmargin + countSize.width (); return style ()->sizeFromContents (QStyle::CT_ComboBox, &option, contentSize, this).expandedTo (qApp->globalStrut ()); } void FilterBarComboBox::paintEvent (QPaintEvent * e) { Q_UNUSED (e); QStylePainter painter (this); painter.setPen (palette ().color (QPalette::Text)); // draw the combobox frame, focusrect and selected etc. QStyleOptionComboBox opt; initStyleOption (&opt); painter.drawComplexControl (QStyle::CC_ComboBox, opt); // draw the icon and text const QModelIndex modelIndex = model ()->index (currentIndex (), 0, rootModelIndex ()); if (modelIndex.isValid ()) { QStyle * s = style (); const int hmargin = getHSpacing (this); QRect rect = s->subControlRect (QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this); rect.adjust (2, 1, -2, -1); // draw the icon const QIcon icon = Utils::getIconFromIndex (modelIndex); if (!icon.isNull ()) { const QRect iconRect = QStyle::alignedRect(opt.direction, Qt::AlignLeft | Qt::AlignVCenter, opt.iconSize, rect); icon.paint (&painter, iconRect, Qt::AlignCenter, StyleHelper::getIconMode (opt.state), QIcon::Off); Utils::narrowRect (rect, iconRect.width () + hmargin, 0, opt.direction); } // draw the count QString text = modelIndex.data (CountStringRole).toString (); if (!text.isEmpty ()) { const QPen pen = painter.pen (); painter.setPen (Utils::getFadedColor (pen.color ())); const QRect textRect = QStyle::alignedRect(opt.direction, Qt::AlignRight | Qt::AlignVCenter, QSize (opt.fontMetrics.width (text), rect.height ()), rect); painter.drawText (textRect, Qt::AlignRight | Qt::AlignVCenter, text); Utils::narrowRect (rect, 0, textRect.width () + hmargin, opt.direction); painter.setPen (pen); } // draw the text text = modelIndex.data (Qt::DisplayRole).toString (); text = painter.fontMetrics ().elidedText (text, Qt::ElideRight, rect.width ()); painter.drawText (rect, Qt::AlignLeft | Qt::AlignVCenter, text); } }