Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-81571

QStyleSheetStyle sizeFromContents for CT_HeaderSection not taking into account the sortIndicator

    XMLWordPrintable

Details

    • Bug
    • Resolution: Incomplete
    • P4: Low
    • None
    • 5.12.3
    • Widgets: Style Sheets
    • None

    Description

      Comparing the code of qstylesheetstyle.cpp and qcommonstyle.cpp, qcommonstyle.cpp actually uses the sortIndicator field of the header and adds the height or width to it. Otherwise when double clicking the section's edge to resize section to fit, it would actually still be a bit narrow if the sort indicator is visible causing the text to get elide.

      Seems desirable to either do what qcommonstyle.cpp does or add the size dictated by the pixelMetric for QStyle::PM_HeaderMarkSize (which is used to in qheaderview.cpp's paintSection to elide the text).

      Haven't officially tested it against 5.12.3 but looking at the code in git, it looks the same so I assume this issue hasn't been addressed.

      int Application::exec()
      {
          auto createTableWidget = []( const QString& styleSheet ) {
              QTableWidget* tableWidget = new QTableWidget(2, 2);
              tableWidget->setFixedSize(400, 200);
              tableWidget->setHorizontalHeaderLabels(QStringList() << "Column 1" << "Column 2");
              tableWidget->setVerticalHeaderLabels(QStringList() << "Row 1" << "Row 2");
              tableWidget->horizontalHeader()->setSortIndicatorShown(true);
              for(int i=0; i < 2; i++)
                  tableWidget->horizontalHeaderItem(i)->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
              tableWidget->horizontalHeader()->setStyleSheet(styleSheet);
              tableWidget->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
              tableWidget->show();
          };
          
          QString noSectionStyling = "QHeaderView::down-arrow { image: url(:/OpenArrow.png); } QHeaderView::up-arrow { image: url(:/UpArrow.png); }";
          QString withSectionStyling = "QHeaderView::down-arrow { image: url(:/OpenArrow.png); } QHeaderView::up-arrow { image: url(:/UpArrow.png); } QHeaderView::section { padding-left: 0px; }";
          
          createTableWidget(noSectionStyling);
          createTableWidget(withSectionStyling);
      
          return QApplication::exec();
      }
      
          // taken from QStyleSheetStyle::sizeFromContents in qstylesheetstyle.cpp
          case CT_HeaderSection: {
                  if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
                      QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
                      if (subRule.hasGeometry() || subRule.hasBox() || !subRule.hasNativeBorder() || subRule.hasFont) {
                          sz = subRule.adjustSize(csz);
                          if (!subRule.hasGeometry()) {
                              QSize nativeContentsSize;
                              bool nullIcon = hdr->icon.isNull();
                              const int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
                              int iconSize = nullIcon ? 0 : pixelMetric(QStyle::PM_SmallIconSize, hdr, w);
                              const QSize txt = subRule.hasFont ? QFontMetrics(subRule.font).size(0, hdr->text)
                                                                : hdr->fontMetrics.size(0, hdr->text);
                              nativeContentsSize.setHeight(margin + qMax(iconSize, txt.height()) + margin);
                              nativeContentsSize.setWidth((nullIcon ? 0 : margin) + iconSize
                                                          + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin);
                              sz = sz.expandedTo(nativeContentsSize);
                          }
                          return subRule.size(sz);
                      }
                      return subRule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
                                                        : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
      
          // taken from QCommonStyle::sizeFromContents in qcommonstyle.cpp
          case CT_HeaderSection:
              if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
                  bool nullIcon = hdr->icon.isNull();
                  int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, hdr, widget);
                  int iconSize = nullIcon ? 0 : proxy()->pixelMetric(QStyle::PM_SmallIconSize, hdr, widget);
                  QSize txt = hdr->fontMetrics.size(0, hdr->text);
                  sz.setHeight(margin + qMax(iconSize, txt.height()) + margin);
                  sz.setWidth((nullIcon ? 0 : margin) + iconSize
                              + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin);
                  if (hdr->sortIndicator != QStyleOptionHeader::None) {
                      int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, hdr, widget);
                      if (hdr->orientation == Qt::Horizontal)
                          sz.rwidth() += sz.height() + margin;
                      else
                          sz.rheight() += sz.width() + margin;
                  }
      

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              qt.team.quick.subscriptions Qt Quick and Widgets Team
              thuan_firelight Thuan Seah
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes