diff --git a/src/blackgui/models/columns.cpp b/src/blackgui/models/columns.cpp index 0d40d3bbf..85583d89d 100644 --- a/src/blackgui/models/columns.cpp +++ b/src/blackgui/models/columns.cpp @@ -185,6 +185,58 @@ namespace BlackGui return column >= 0 && column < m_columns.size(); } + bool CColumns::hasAnyWidthPercentage() const + { + for (const CColumn &c : m_columns) { if (c.hasWidthPercentage()) { return true; }} + return false; + } + + void CColumns::setWidthPercentages(const QList percentages) + { + if (percentages.isEmpty()) + { + for (CColumn &column : m_columns) { column.setWidthPercentage(-1); } + return; + } + + int c = 0; + for (CColumn &column : m_columns) + { + column.setWidthPercentage(percentages.at(c++)); + } + } + + QList CColumns::calculateWidths(int totalWidth) const + { + if (m_columns.isEmpty() || !this->hasAnyWidthPercentage()) { return {}; } + + int totalPercentage = 0; + const int averagePercentage = 100 / m_columns.size(); + + for (const CColumn &c : m_columns) + { + totalPercentage += c.hasWidthPercentage() ? c.getWidthPercentage() : averagePercentage; + } + + if (totalPercentage < 1) { return {}; } + + // ideally totalPercentage would be 100%, but there is no guarantee + const double part = static_cast(totalWidth) / totalPercentage; + QList widths; + + int usedWidth = 0; + for (const CColumn &c : m_columns) + { + const int percentage = c.hasWidthPercentage() ? c.getWidthPercentage() : averagePercentage; + const int restWidth = totalWidth - usedWidth; + const int width = qMin(restWidth, qRound(part * percentage)); + widths.push_back(width); + usedWidth += width; + } + + return widths; + } + const CDefaultFormatter *CColumns::getFormatter(const QModelIndex &index) const { if (!isValidColumn(index)) { return nullptr; } diff --git a/src/blackgui/models/columns.h b/src/blackgui/models/columns.h index cd99ee418..6652fa40d 100644 --- a/src/blackgui/models/columns.h +++ b/src/blackgui/models/columns.h @@ -92,6 +92,15 @@ namespace BlackGui //! Translation context void setTranslationContext(const QString &translationContext) { m_translationContext = translationContext; } + //! Width in percentage + int getWidthPercentage() const { return m_widthPercentage; } + + //! Having a width percentage + bool hasWidthPercentage() const { return m_widthPercentage > 0; } + + //! Width percentage + void setWidthPercentage(int width) { m_widthPercentage = width; } + //! Get a standard value object formatted column static CColumn standardValueObject(const QString &headerName, const BlackMisc::CPropertyIndex &propertyIndex, int alignment = CDefaultFormatter::alignDefault()); @@ -114,6 +123,7 @@ namespace BlackGui QString m_translationContext; QString m_columnName; QString m_columnToolTip; + int m_widthPercentage = -1; QSharedPointer m_formatter; //!< Used formatter BlackMisc::CPropertyIndex m_propertyIndex; //!< Property index for column BlackMisc::CPropertyIndex m_sortPropertyIndex; //!< Property index used when sorted (optional alternative) @@ -202,6 +212,15 @@ namespace BlackGui //! Columns const QList &columns() const { return m_columns; } + //! Any column with width percentage? + bool hasAnyWidthPercentage() const; + + //! Set the width percentages + void setWidthPercentages(const QList percentages); + + //! Calculate the absolute width + QList calculateWidths(int totalWidth) const; + private: QList m_columns; QString m_translationContext; //!< for future usage diff --git a/src/blackgui/views/viewbase.cpp b/src/blackgui/views/viewbase.cpp index 43f12c744..00709807d 100644 --- a/src/blackgui/views/viewbase.cpp +++ b/src/blackgui/views/viewbase.cpp @@ -545,6 +545,19 @@ namespace BlackGui tw->setTabText(index, o); } + template + void CViewBase::setPercentageColumnWidths() + { + const int width = this->width() - 25; // avoid scrollbars etc, reserve a little space + QList widths = this->getColumns().calculateWidths(width); + if (widths.isEmpty()) { return; } + for (int c = 0; c < this->getColumns().size(); c++) + { + const int w = widths.at(c); + this->setColumnWidth(c, w); + } + } + template void CViewBase::setSortIndicator() { diff --git a/src/blackgui/views/viewbase.h b/src/blackgui/views/viewbase.h index fba211568..7eadd9d93 100644 --- a/src/blackgui/views/viewbase.h +++ b/src/blackgui/views/viewbase.h @@ -301,6 +301,9 @@ namespace BlackGui //! Workaround as of https://stackoverflow.com/q/3433664/356726 void setForceColumnsToMaxSize(bool force) { m_forceColumnsToMaxSize = force; } + //! Resize mode + void setHorizontalHeaderSectionResizeMode(QHeaderView::ResizeMode mode); + //! Index of the directory we "remember" void setSettingsDirectoryIndex(BlackMisc::CDirectories::ColumnIndex directoryIndex) { m_dirSettingsIndex = directoryIndex; } @@ -744,6 +747,10 @@ namespace BlackGui //! Set a tab widget text based on row count, filter etc. void setTabWidgetViewText(QTabWidget *tw, int index); + //! Set the widths based on the column percentages + //! \sa CColumn::get + void setPercentageColumnWidths(); + protected: ModelClass *m_model = nullptr; //!< corresponding model diff --git a/src/blackgui/views/viewbasenontemplate.cpp b/src/blackgui/views/viewbasenontemplate.cpp index 692b3b80c..074efaa65 100644 --- a/src/blackgui/views/viewbasenontemplate.cpp +++ b/src/blackgui/views/viewbasenontemplate.cpp @@ -39,8 +39,7 @@ namespace BlackGui { namespace Views { - CViewBaseNonTemplate::CViewBaseNonTemplate(QWidget *parent) : - QTableView(parent) + CViewBaseNonTemplate::CViewBaseNonTemplate(QWidget *parent) : QTableView(parent) { this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &QWidget::customContextMenuRequested, this, &CViewBaseNonTemplate::customMenuRequested); @@ -186,6 +185,11 @@ namespace BlackGui return this->ps_saveJson(selectedOnly, directory); } + void CViewBaseNonTemplate::setHorizontalHeaderSectionResizeMode(QHeaderView::ResizeMode mode) + { + this->horizontalHeader()->setSectionResizeMode(mode); + } + IMenuDelegate *CViewBaseNonTemplate::setCustomMenu(IMenuDelegate *menu, bool nestPreviousMenu) { if (menu && nestPreviousMenu)