diff --git a/src/gui/issueswidget.cpp b/src/gui/issueswidget.cpp
index edc984a7d..c132ff925 100644
--- a/src/gui/issueswidget.cpp
+++ b/src/gui/issueswidget.cpp
@@ -107,6 +107,16 @@ void IssuesWidget::showEvent(QShowEvent *ev)
{
ConfigFile cfg;
cfg.restoreGeometryHeader(_ui->_treeWidget->header());
+
+ // Sorting by section was newly enabled. But if we restore the header
+ // from a state where sorting was disabled, both of these flags will be
+ // false and sorting will be impossible!
+ _ui->_treeWidget->header()->setSectionsClickable(true);
+ _ui->_treeWidget->header()->setSortIndicatorShown(true);
+
+ // Switch back to "first important, then by time" ordering
+ _ui->_treeWidget->sortByColumn(0, Qt::DescendingOrder);
+
QWidget::showEvent(ev);
}
@@ -119,6 +129,8 @@ void IssuesWidget::hideEvent(QHideEvent *ev)
void IssuesWidget::cleanItems(const QString &folder)
{
+ _ui->_treeWidget->setSortingEnabled(false);
+
// The issue list is a state, clear it and let the next sync fill it
// with ignored files and propagation errors.
int itemCnt = _ui->_treeWidget->topLevelItemCount();
@@ -129,6 +141,9 @@ void IssuesWidget::cleanItems(const QString &folder)
delete item;
}
}
+
+ _ui->_treeWidget->setSortingEnabled(true);
+
// update the tabtext
emit(issueCountUpdated(_ui->_treeWidget->topLevelItemCount()));
}
@@ -240,7 +255,7 @@ bool IssuesWidget::shouldBeVisible(QTreeWidgetItem *item, AccountState *filterAc
const QString &filterFolderAlias) const
{
bool visible = true;
- auto status = item->data(0, Qt::UserRole);
+ auto status = item->data(3, Qt::UserRole);
visible &= (_ui->showIgnores->isChecked() || status != SyncFileItem::FileIgnored);
visible &= (_ui->showWarnings->isChecked()
|| (status != SyncFileItem::SoftError
@@ -368,13 +383,14 @@ void IssuesWidget::addError(const QString &folderAlias, const QString &message,
QIcon icon = Theme::instance()->syncStateIcon(SyncResult::Error);
- QTreeWidgetItem *twitem = new QTreeWidgetItem(columns);
+ QTreeWidgetItem *twitem = new SortedTreeWidgetItem(columns);
twitem->setData(0, Qt::SizeHintRole, QSize(0, ActivityItemDelegate::rowHeight()));
+ twitem->setData(0, Qt::UserRole, timestamp);
twitem->setIcon(0, icon);
twitem->setToolTip(0, longTimeStr);
- twitem->setToolTip(3, message);
- twitem->setData(0, Qt::UserRole, SyncFileItem::NormalError);
twitem->setData(2, Qt::UserRole, folderAlias);
+ twitem->setToolTip(3, message);
+ twitem->setData(3, Qt::UserRole, SyncFileItem::NormalError);
addItem(twitem);
addErrorWidget(twitem, message, category);
diff --git a/src/gui/issueswidget.ui b/src/gui/issueswidget.ui
index 27bfe1118..2d1161e78 100644
--- a/src/gui/issueswidget.ui
+++ b/src/gui/issueswidget.ui
@@ -99,6 +99,9 @@
false
+
+ true
+
4
diff --git a/src/gui/protocolwidget.cpp b/src/gui/protocolwidget.cpp
index f3a52dff6..e27152563 100644
--- a/src/gui/protocolwidget.cpp
+++ b/src/gui/protocolwidget.cpp
@@ -32,6 +32,19 @@
namespace OCC {
+bool SortedTreeWidgetItem::operator<(const QTreeWidgetItem &other) const
+{
+ int column = treeWidget()->sortColumn();
+ if (column != 0) {
+ return QTreeWidgetItem::operator<(other);
+ }
+
+ // Items with empty "File" column are larger than others,
+ // otherwise sort by time (this uses lexicographic ordering)
+ return std::forward_as_tuple(text(1).isEmpty(), data(0, Qt::UserRole).toDateTime())
+ < std::forward_as_tuple(other.text(1).isEmpty(), other.data(0, Qt::UserRole).toDateTime());
+}
+
ProtocolWidget::ProtocolWidget(QWidget *parent)
: QWidget(parent)
, _ui(new Ui::ProtocolWidget)
@@ -86,6 +99,16 @@ void ProtocolWidget::showEvent(QShowEvent *ev)
{
ConfigFile cfg;
cfg.restoreGeometryHeader(_ui->_treeWidget->header());
+
+ // Sorting by section was newly enabled. But if we restore the header
+ // from a state where sorting was disabled, both of these flags will be
+ // false and sorting will be impossible!
+ _ui->_treeWidget->header()->setSectionsClickable(true);
+ _ui->_treeWidget->header()->setSortIndicatorShown(true);
+
+ // Switch back to "by time" ordering
+ _ui->_treeWidget->sortByColumn(0, Qt::DescendingOrder);
+
QWidget::showEvent(ev);
}
@@ -158,14 +181,15 @@ QTreeWidgetItem *ProtocolWidget::createCompletedTreewidgetItem(const QString &fo
columns << Utility::octetsToString(item._size);
}
- QTreeWidgetItem *twitem = new QTreeWidgetItem(columns);
+ QTreeWidgetItem *twitem = new SortedTreeWidgetItem(columns);
twitem->setData(0, Qt::SizeHintRole, QSize(0, ActivityItemDelegate::rowHeight()));
+ twitem->setData(0, Qt::UserRole, timestamp);
twitem->setIcon(0, icon);
twitem->setToolTip(0, longTimeStr);
twitem->setToolTip(1, item._file);
- twitem->setToolTip(3, message);
- twitem->setData(0, Qt::UserRole, item._status);
twitem->setData(2, Qt::UserRole, folder);
+ twitem->setToolTip(3, message);
+ twitem->setData(3, Qt::UserRole, item._status);
return twitem;
}
diff --git a/src/gui/protocolwidget.h b/src/gui/protocolwidget.h
index 7e3a154a5..77bb641b4 100644
--- a/src/gui/protocolwidget.h
+++ b/src/gui/protocolwidget.h
@@ -34,6 +34,21 @@ namespace Ui {
}
class Application;
+/**
+ * A QTreeWidgetItem with special sorting.
+ *
+ * It allows items for global entries to be moved to the top if the
+ * sorting section is the "Time" column.
+ */
+class SortedTreeWidgetItem : public QTreeWidgetItem
+{
+public:
+ using QTreeWidgetItem::QTreeWidgetItem;
+
+private:
+ bool operator<(const QTreeWidgetItem &other) const override;
+};
+
/**
* @brief The ProtocolWidget class
* @ingroup gui
diff --git a/src/gui/protocolwidget.ui b/src/gui/protocolwidget.ui
index 143c2d627..7cec20f9d 100644
--- a/src/gui/protocolwidget.ui
+++ b/src/gui/protocolwidget.ui
@@ -35,6 +35,9 @@
true
+
+ true
+
4