#include "./helper.h" #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && QT_VERSION < QT_VERSION_CHECK(6, 3, 0) #include #endif #include #include #include #include #include #include namespace QtGui { /*! * \class UnifiedItemDelegate * \brief The UnifiedItemDelegate class draws view items without visual separation. * * This style sets the view item position to "OnlyOne" to prevent styles from drawing separations * too noisily between items. It is used to achieve a cleaner look of the directory/devices tree * view. * * \remarks * The main motivation for this is the Windows 11 style which otherwise draws vertical lines between * the columns which does not look nice at all in these tree views. */ UnifiedItemDelegate::UnifiedItemDelegate(QObject *parent) : QStyledItemDelegate(parent) { } void UnifiedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { auto opt = option; initStyleOption(&opt, index); opt.viewItemPosition = QStyleOptionViewItem::OnlyOne; QStyledItemDelegate::paint(painter, opt, index); } void showViewMenu(const QPoint &position, const QTreeView &view, QMenu &menu) { // map the coordinates to top-level widget if it is a QMenu // note: This necessity is actually considered a bug which is fixed by d0b5adb3b28bf5b9d94ef46cecf402994e7c5b38 which is // part of Qt 6.2.3 and later. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) constexpr auto needsHack = true; #elif QT_VERSION >= QT_VERSION_CHECK(6, 3, 0) constexpr auto needsHack = false; #else static const auto needsHack = QLibraryInfo::version() < QVersionNumber(6, 2, 3); #endif const QMenu *topLevelWidget; if (needsHack && (topLevelWidget = qobject_cast(view.topLevelWidget())) && (topLevelWidget->windowFlags() & Qt::Popup) == Qt::Popup) { menu.exec(topLevelWidget->mapToGlobal(position)); } else { menu.exec(view.viewport()->mapToGlobal(position)); } } void drawBasicItemViewItem(QPainter &painter, const QStyleOptionViewItem &option) { if (auto *const style = option.widget ? option.widget->style() : QApplication::style()) { style->drawControl(QStyle::CE_ItemViewItem, &option, &painter, option.widget); } } void setupPainterToDrawViewItemText(QPainter *painter, QStyleOptionViewItem &opt) { painter->setFont(opt.font); if (!(opt.state & QStyle::State_Selected)) { painter->setPen(opt.palette.color(QPalette::Text)); return; } // set pen/palette in accordance with the Windows 11 or Windows Vista style for selected items // note: These styles unfortunately don't just use the highlighted text color and just using it would // lead to a very bad contrast. #if defined(Q_OS_WINDOWS) && QT_VERSION >= QT_VERSION_CHECK(6, 1, 0) auto *const style = opt.widget ? opt.widget->style() : nullptr; const auto styleName = style ? style->name() : QString(); if (styleName.compare(QLatin1String("windows11"), Qt::CaseInsensitive) == 0) { painter->setPen(QPen(opt.palette.buttonText().color())); return; } else if (styleName.compare(QLatin1String("windowsvista"), Qt::CaseInsensitive) == 0) { opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text)); opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108)); } #endif painter->setPen(opt.palette.color(QPalette::HighlightedText)); } } // namespace QtGui