File indexing completed on 2024-05-19 05:44:23
0001 /* 0002 SPDX-FileCopyrightText: 2020 Milian Wolff <mail@milianw.de> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include "costheaderview.h" 0008 0009 #include <QDebug> 0010 #include <QEvent> 0011 #include <QMenu> 0012 #include <QPainter> 0013 #include <QScopedValueRollback> 0014 0015 #include <cmath> 0016 0017 CostHeaderView::CostHeaderView(QWidget* parent) 0018 : QHeaderView(Qt::Horizontal, parent) 0019 { 0020 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) 0021 setSectionsMovable(true); 0022 setFirstSectionMovable(false); 0023 #endif 0024 setDefaultSectionSize(100); 0025 setStretchLastSection(false); 0026 connect(this, &QHeaderView::sectionCountChanged, this, [this]() { resizeColumns(false); }); 0027 connect(this, &QHeaderView::sectionResized, this, [this](int index, int oldSize, int newSize) { 0028 if (m_isResizing) 0029 return; 0030 QScopedValueRollback<bool> guard(m_isResizing, true); 0031 if (index != 0) { 0032 // give/take space from first column 0033 resizeSection(0, sectionSize(0) - (newSize - oldSize)); 0034 } else { 0035 // distribute space across all columns 0036 // use actual width as oldSize/newSize isn't reliable here 0037 const auto numSections = count(); 0038 int usedWidth = 0; 0039 for (int i = 0; i < numSections; ++i) 0040 usedWidth += sectionSize(i); 0041 const auto diff = usedWidth - width(); 0042 const auto numVisibleSections = numSections - hiddenSectionCount(); 0043 if (numVisibleSections == 0) 0044 return; 0045 0046 const auto diffPerSection = diff / numVisibleSections; 0047 const auto extraDiff = diff % numVisibleSections; 0048 for (int i = 1; i < numSections; ++i) { 0049 if (isSectionHidden(i)) { 0050 continue; 0051 } 0052 auto newSize = sectionSize(i) - diffPerSection; 0053 if (i == numSections - 1) 0054 newSize -= extraDiff; 0055 resizeSection(i, newSize); 0056 } 0057 } 0058 }); 0059 0060 setContextMenuPolicy(Qt::CustomContextMenu); 0061 connect(this, &QHeaderView::customContextMenuRequested, this, [this](const QPoint& pos) { 0062 const auto numSections = count(); 0063 0064 QMenu menu; 0065 auto resetSizes = menu.addAction(tr("Reset Column Sizes")); 0066 connect(resetSizes, &QAction::triggered, this, [this]() { resizeColumns(true); }); 0067 0068 if (numSections > 1) { 0069 auto* subMenu = menu.addMenu(tr("Visible Columns")); 0070 for (int i = 1; i < numSections; ++i) { 0071 auto* action = subMenu->addAction(model()->headerData(i, Qt::Horizontal).toString()); 0072 action->setCheckable(true); 0073 action->setChecked(!isSectionHidden(i)); 0074 connect(action, &QAction::toggled, this, [this, i](bool visible) { setSectionHidden(i, !visible); }); 0075 } 0076 } 0077 0078 menu.exec(mapToGlobal(pos)); 0079 }); 0080 } 0081 0082 CostHeaderView::~CostHeaderView() = default; 0083 0084 void CostHeaderView::resizeEvent(QResizeEvent* event) 0085 { 0086 QHeaderView::resizeEvent(event); 0087 resizeColumns(false); 0088 } 0089 0090 void CostHeaderView::resizeColumns(bool reset) 0091 { 0092 const auto numColumns = count(); 0093 if (!numColumns) { 0094 return; 0095 } 0096 0097 QScopedValueRollback<bool> guard(m_isResizing, true); 0098 auto availableWidth = width(); 0099 const auto defaultSize = defaultSectionSize(); 0100 0101 for (int i = numColumns - 1; i >= 0; --i) { 0102 if (i == 0) { 0103 resizeSection(i, std::max(availableWidth, defaultSize)); 0104 } else if (reset) { 0105 resizeSection(i, defaultSize); 0106 } 0107 if (!isSectionHidden(i)) { 0108 availableWidth -= sectionSize(i); 0109 } 0110 } 0111 } 0112 0113 #include "moc_costheaderview.cpp"