Axivion: Consolidate column information

Splitting the column information across multiple lists
was not smart as it complicates the handling and the
planned extension.
No change in functionality intended yet.

Change-Id: I968edf28a6a279a14dbe223bf21e007b3e42f843
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
Christian Stenger
2024-08-05 07:58:17 +02:00
parent 281f9c28d6
commit fd94f03c3d
3 changed files with 48 additions and 44 deletions

View File

@@ -469,15 +469,16 @@ void IssuesWidget::updateTable()
QStringList columnHeaders; QStringList columnHeaders;
QStringList hiddenColumns; QStringList hiddenColumns;
QList<bool> sortableColumns; QList<IssueHeaderView::ColumnInfo> columnInfos;
QList<int> columnWidths;
QList<Qt::Alignment> alignments; QList<Qt::Alignment> alignments;
for (const Dto::ColumnInfoDto &column : m_currentTableInfo->columns) { for (const Dto::ColumnInfoDto &column : m_currentTableInfo->columns) {
columnHeaders << column.header.value_or(column.key); columnHeaders << column.header.value_or(column.key);
if (!column.showByDefault) if (!column.showByDefault)
hiddenColumns << column.key; hiddenColumns << column.key;
sortableColumns << column.canSort; IssueHeaderView::ColumnInfo info;
columnWidths << column.width; info.sortable = column.canSort;
info.width = column.width;
columnInfos.append(info);
alignments << alignmentFromString(column.alignment); alignments << alignmentFromString(column.alignment);
} }
m_addedFilter->setText("0"); m_addedFilter->setText("0");
@@ -487,8 +488,7 @@ void IssuesWidget::updateTable()
m_issuesModel->clear(); m_issuesModel->clear();
m_issuesModel->setHeader(columnHeaders); m_issuesModel->setHeader(columnHeaders);
m_issuesModel->setAlignments(alignments); m_issuesModel->setAlignments(alignments);
m_headerView->setSortableColumns(sortableColumns); m_headerView->setColumnInfoList(columnInfos);
m_headerView->setColumnWidths(columnWidths);
int counter = 0; int counter = 0;
for (const QString &header : std::as_const(columnHeaders)) for (const QString &header : std::as_const(columnHeaders))
m_issuesView->setColumnHidden(counter++, hiddenColumns.contains(header)); m_issuesView->setColumnHidden(counter++, hiddenColumns.contains(header));
@@ -705,7 +705,7 @@ IssueListSearch IssuesWidget::searchFromUi() const
QTC_ASSERT(m_currentTableInfo, return search); QTC_ASSERT(m_currentTableInfo, return search);
QTC_ASSERT((ulong)column < m_currentTableInfo->columns.size(), return search); QTC_ASSERT((ulong)column < m_currentTableInfo->columns.size(), return search);
search.sort = m_currentTableInfo->columns.at(m_headerView->currentSortColumn()).key search.sort = m_currentTableInfo->columns.at(m_headerView->currentSortColumn()).key
+ (m_headerView->currentSortOrder() == SortOrder::Ascending ? " asc" : " desc"); + (m_headerView->currentSortOrder() == Qt::AscendingOrder ? " asc" : " desc");
} }
return search; return search;

View File

@@ -12,7 +12,7 @@ namespace Axivion::Internal {
constexpr int ICON_SIZE = 16; constexpr int ICON_SIZE = 16;
static QIcon iconForSorted(SortOrder order) static QIcon iconForSorted(std::optional<Qt::SortOrder> order)
{ {
const Utils::Icon UNSORTED( const Utils::Icon UNSORTED(
{{":/axivion/images/sortAsc.png", Utils::Theme::IconsDisabledColor}, {{":/axivion/images/sortAsc.png", Utils::Theme::IconsDisabledColor},
@@ -30,30 +30,24 @@ static QIcon iconForSorted(SortOrder order)
static const QIcon sortedAsc = SORT_ASC.icon(); static const QIcon sortedAsc = SORT_ASC.icon();
static const QIcon sortedDesc = SORT_DESC.icon(); static const QIcon sortedDesc = SORT_DESC.icon();
switch (order) { if (!order)
case SortOrder::None:
return unsorted; return unsorted;
case SortOrder::Ascending: return order.value() == Qt::AscendingOrder ? sortedAsc : sortedDesc;
return sortedAsc;
case SortOrder::Descending:
return sortedDesc;
}
return {};
} }
void IssueHeaderView::setSortableColumns(const QList<bool> &sortable) void IssueHeaderView::setColumnInfoList(const QList<ColumnInfo> &infos)
{ {
m_sortableColumns = sortable; m_columnInfoList = infos;
int oldIndex = m_currentSortIndex; int oldIndex = m_currentSortIndex;
m_currentSortIndex = -1; m_currentSortIndex = -1;
m_currentSortOrder = SortOrder::None; m_currentSortOrder.reset();
if (oldIndex != -1) if (oldIndex != -1)
headerDataChanged(Qt::Horizontal, oldIndex, oldIndex); headerDataChanged(Qt::Horizontal, oldIndex, oldIndex);
} }
int IssueHeaderView::currentSortColumn() const int IssueHeaderView::currentSortColumn() const
{ {
return m_currentSortOrder == SortOrder::None ? -1 : m_currentSortIndex; return m_currentSortOrder ? m_currentSortIndex : -1;
} }
void IssueHeaderView::mousePressEvent(QMouseEvent *event) void IssueHeaderView::mousePressEvent(QMouseEvent *event)
@@ -85,12 +79,12 @@ void IssueHeaderView::mouseReleaseEvent(QMouseEvent *event)
const int y = position.y(); const int y = position.y();
const int logical = logicalIndexAt(position.x()); const int logical = logicalIndexAt(position.x());
if (logical == m_lastToggleLogicalPos if (logical == m_lastToggleLogicalPos
&& logical > -1 && logical < m_sortableColumns.size()) { && logical > -1 && logical < m_columnInfoList.size()) {
if (m_sortableColumns.at(logical)) { // ignore non-sortable if (m_columnInfoList.at(logical).sortable) { // ignore non-sortable
if (y < height() / 2) // TODO improve if (y < height() / 2) // TODO improve
onToggleSort(logical, SortOrder::Ascending); onToggleSort(logical, Qt::AscendingOrder);
else else
onToggleSort(logical, SortOrder::Descending); onToggleSort(logical, Qt::DescendingOrder);
} }
} }
} }
@@ -105,12 +99,16 @@ void IssueHeaderView::mouseMoveEvent(QMouseEvent *event)
QHeaderView::mouseMoveEvent(event); QHeaderView::mouseMoveEvent(event);
} }
void IssueHeaderView::onToggleSort(int index, SortOrder order) void IssueHeaderView::onToggleSort(int index, Qt::SortOrder order)
{ {
if (m_currentSortIndex == index) if (m_currentSortIndex == index) {
m_currentSortOrder = (order == m_currentSortOrder) ? SortOrder::None : order; if (!m_currentSortOrder || m_currentSortOrder.value() != order)
else m_currentSortOrder = order;
else
m_currentSortOrder.reset();
} else {
m_currentSortOrder = order; m_currentSortOrder = order;
}
int oldIndex = m_currentSortIndex; int oldIndex = m_currentSortIndex;
m_currentSortIndex = index; m_currentSortIndex = index;
@@ -123,11 +121,12 @@ void IssueHeaderView::onToggleSort(int index, SortOrder order)
QSize IssueHeaderView::sectionSizeFromContents(int logicalIndex) const QSize IssueHeaderView::sectionSizeFromContents(int logicalIndex) const
{ {
const QSize oldSize = QHeaderView::sectionSizeFromContents(logicalIndex); const QSize oldSize = QHeaderView::sectionSizeFromContents(logicalIndex);
const QSize newSize = logicalIndex < m_columnWidths.size() const QSize newSize = logicalIndex < m_columnInfoList.size()
? QSize(qMax(m_columnWidths.at(logicalIndex), oldSize.width()), oldSize.height()) : oldSize; ? QSize(qMax(m_columnInfoList.at(logicalIndex).width, oldSize.width()), oldSize.height())
: oldSize;
const int margin = style()->pixelMetric(QStyle::PM_HeaderGripMargin, nullptr, this); const int margin = style()->pixelMetric(QStyle::PM_HeaderGripMargin, nullptr, this);
// add icon size and margin (default resize handle margin + 1) // add icon size and margin (default resize handle margin)
return QSize{newSize.width() + ICON_SIZE + margin, qMax(newSize.height(), ICON_SIZE)}; return QSize{newSize.width() + ICON_SIZE + margin, qMax(newSize.height(), ICON_SIZE)};
} }
@@ -136,13 +135,13 @@ void IssueHeaderView::paintSection(QPainter *painter, const QRect &rect, int log
painter->save(); painter->save();
QHeaderView::paintSection(painter, rect, logicalIndex); QHeaderView::paintSection(painter, rect, logicalIndex);
painter->restore(); painter->restore();
if (logicalIndex < 0 || logicalIndex >= m_sortableColumns.size()) if (logicalIndex < 0 || logicalIndex >= m_columnInfoList.size())
return; return;
if (!m_sortableColumns.at(logicalIndex)) if (!m_columnInfoList.at(logicalIndex).sortable)
return; return;
const int margin = style()->pixelMetric(QStyle::PM_HeaderGripMargin, nullptr, this); const int margin = style()->pixelMetric(QStyle::PM_HeaderGripMargin, nullptr, this);
const QIcon icon = iconForSorted(logicalIndex == m_currentSortIndex ? m_currentSortOrder : SortOrder::None); const QIcon icon = iconForSorted(logicalIndex == m_currentSortIndex ? m_currentSortOrder : std::nullopt);
const int offset = qMax((rect.height() - ICON_SIZE), 0) / 2; const int offset = qMax((rect.height() - ICON_SIZE), 0) / 2;
const int left = rect.left() + rect.width() - ICON_SIZE - margin; const int left = rect.left() + rect.width() - ICON_SIZE - margin;
const QRect iconRect(left, offset, ICON_SIZE, ICON_SIZE); const QRect iconRect(left, offset, ICON_SIZE, ICON_SIZE);

View File

@@ -6,19 +6,25 @@
#include <QHeaderView> #include <QHeaderView>
#include <QList> #include <QList>
namespace Axivion::Internal { #include <optional>
enum class SortOrder { None, Ascending, Descending }; namespace Axivion::Internal {
class IssueHeaderView : public QHeaderView class IssueHeaderView : public QHeaderView
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit IssueHeaderView(QWidget *parent = nullptr) : QHeaderView(Qt::Horizontal, parent) {} struct ColumnInfo
void setSortableColumns(const QList<bool> &sortable); {
void setColumnWidths(const QList<int> &widths) { m_columnWidths = widths; } int width = 0;
std::optional<Qt::SortOrder> sortOrder = std::nullopt;
bool sortable = false;
};
SortOrder currentSortOrder() const { return m_currentSortOrder; } explicit IssueHeaderView(QWidget *parent = nullptr) : QHeaderView(Qt::Horizontal, parent) {}
void setColumnInfoList(const QList<ColumnInfo> &infos);
std::optional<Qt::SortOrder> currentSortOrder() const { return m_currentSortOrder; }
int currentSortColumn() const; int currentSortColumn() const;
signals: signals:
@@ -32,14 +38,13 @@ protected:
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override;
private: private:
void onToggleSort(int index, SortOrder order); void onToggleSort(int index, Qt::SortOrder order);
bool m_dragging = false; bool m_dragging = false;
bool m_maybeToggleSort = false; bool m_maybeToggleSort = false;
int m_lastToggleLogicalPos = -1; int m_lastToggleLogicalPos = -1;
int m_currentSortIndex = -1; int m_currentSortIndex = -1;
SortOrder m_currentSortOrder = SortOrder::None; std::optional<Qt::SortOrder> m_currentSortOrder = std::nullopt;
QList<bool> m_sortableColumns; QList<ColumnInfo> m_columnInfoList;
QList<int> m_columnWidths;
}; };
} // namespace Axivion::Internal } // namespace Axivion::Internal