diff --git a/model/CMakeLists.txt b/model/CMakeLists.txt index 0ad6b09..70503c5 100644 --- a/model/CMakeLists.txt +++ b/model/CMakeLists.txt @@ -15,7 +15,7 @@ set(HEADER_FILES syncthingdevicemodel.h syncthingdownloadmodel.h syncthingrecentchangesmodel.h - syncthingsortfilterdirectorymodel.h + syncthingsortfiltermodel.h syncthingstatusselectionmodel.h syncthingicons.h colors.h) @@ -25,7 +25,7 @@ set(SRC_FILES syncthingdevicemodel.cpp syncthingdownloadmodel.cpp syncthingrecentchangesmodel.cpp - syncthingsortfilterdirectorymodel.cpp + syncthingsortfiltermodel.cpp syncthingstatusselectionmodel.cpp syncthingicons.cpp) set(RES_FILES resources/${META_PROJECT_NAME}icons.qrc) diff --git a/model/syncthingsortfilterdirectorymodel.cpp b/model/syncthingsortfiltermodel.cpp similarity index 55% rename from model/syncthingsortfilterdirectorymodel.cpp rename to model/syncthingsortfiltermodel.cpp index badeab7..0f6c98a 100644 --- a/model/syncthingsortfilterdirectorymodel.cpp +++ b/model/syncthingsortfiltermodel.cpp @@ -1,10 +1,10 @@ -#include "./syncthingsortfilterdirectorymodel.h" +#include "./syncthingsortfiltermodel.h" #include namespace Data { -bool SyncthingSortFilterDirectoryModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +bool SyncthingSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { // show all nested structures if (sourceParent.isValid()) { @@ -14,10 +14,10 @@ bool SyncthingSortFilterDirectoryModel::filterAcceptsRow(int sourceRow, const QM return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); } -bool SyncthingSortFilterDirectoryModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +bool SyncthingSortFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { // keep order within nested structures - if (m_behavior == SyncthingDirectorySortBehavior::KeepRawOrder || left.parent().isValid() || right.parent().isValid()) { + if (m_behavior == SyncthingSortBehavior::KeepRawOrder || left.parent().isValid() || right.parent().isValid()) { return left.row() < right.row(); } // use the default sorting for the top-level diff --git a/model/syncthingsortfilterdirectorymodel.h b/model/syncthingsortfiltermodel.h similarity index 50% rename from model/syncthingsortfilterdirectorymodel.h rename to model/syncthingsortfiltermodel.h index 7d78e25..8b08c1c 100644 --- a/model/syncthingsortfilterdirectorymodel.h +++ b/model/syncthingsortfiltermodel.h @@ -7,42 +7,42 @@ namespace Data { -enum class SyncthingDirectorySortBehavior { +enum class SyncthingSortBehavior { KeepRawOrder, Alphabetically, }; -class LIB_SYNCTHING_MODEL_EXPORT SyncthingSortFilterDirectoryModel : public QSortFilterProxyModel { +class LIB_SYNCTHING_MODEL_EXPORT SyncthingSortFilterModel : public QSortFilterProxyModel { Q_OBJECT public: - explicit SyncthingSortFilterDirectoryModel(QAbstractItemModel *sourceModel = nullptr, QObject *parent = nullptr); + explicit SyncthingSortFilterModel(QAbstractItemModel *sourceModel = nullptr, QObject *parent = nullptr); - SyncthingDirectorySortBehavior behavior() const; - void setBehavior(SyncthingDirectorySortBehavior behavior); + SyncthingSortBehavior behavior() const; + void setBehavior(SyncthingSortBehavior behavior); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; private: - SyncthingDirectorySortBehavior m_behavior; + SyncthingSortBehavior m_behavior; }; -inline SyncthingSortFilterDirectoryModel::SyncthingSortFilterDirectoryModel(QAbstractItemModel *sourceModel, QObject *parent) +inline SyncthingSortFilterModel::SyncthingSortFilterModel(QAbstractItemModel *sourceModel, QObject *parent) : QSortFilterProxyModel(parent) - , m_behavior(SyncthingDirectorySortBehavior::Alphabetically) + , m_behavior(SyncthingSortBehavior::Alphabetically) { setSortCaseSensitivity(Qt::CaseInsensitive); setFilterCaseSensitivity(Qt::CaseInsensitive); setSourceModel(sourceModel); } -inline SyncthingDirectorySortBehavior SyncthingSortFilterDirectoryModel::behavior() const +inline SyncthingSortBehavior SyncthingSortFilterModel::behavior() const { return m_behavior; } -inline void SyncthingSortFilterDirectoryModel::setBehavior(SyncthingDirectorySortBehavior behavior) +inline void SyncthingSortFilterModel::setBehavior(SyncthingSortBehavior behavior) { if (behavior != m_behavior) { m_behavior = behavior; diff --git a/plasmoid/lib/syncthingapplet.cpp b/plasmoid/lib/syncthingapplet.cpp index 3d6b898..80917a9 100644 --- a/plasmoid/lib/syncthingapplet.cpp +++ b/plasmoid/lib/syncthingapplet.cpp @@ -55,6 +55,7 @@ SyncthingApplet::SyncthingApplet(QObject *parent, const QVariantList &data) , m_dirModel(m_connection) , m_sortFilterDirModel(&m_dirModel) , m_devModel(m_connection) + , m_sortFilterDevModel(&m_devModel) , m_downloadModel(m_connection) , m_recentChangesModel(m_connection) , m_settingsDlg(nullptr) @@ -68,6 +69,7 @@ SyncthingApplet::SyncthingApplet(QObject *parent, const QVariantList &data) m_notifier.setService(&m_service); #endif m_sortFilterDirModel.sort(0, Qt::AscendingOrder); + m_sortFilterDevModel.sort(0, Qt::AscendingOrder); qmlRegisterUncreatableMetaObject(Data::staticMetaObject, "martchus.syncthingplasmoid", 0, 6, "Data", QStringLiteral("only enums")); } diff --git a/plasmoid/lib/syncthingapplet.h b/plasmoid/lib/syncthingapplet.h index 062fbc5..34ab20e 100644 --- a/plasmoid/lib/syncthingapplet.h +++ b/plasmoid/lib/syncthingapplet.h @@ -9,7 +9,7 @@ #include "../../model/syncthingdirectorymodel.h" #include "../../model/syncthingdownloadmodel.h" #include "../../model/syncthingrecentchangesmodel.h" -#include "../../model/syncthingsortfilterdirectorymodel.h" +#include "../../model/syncthingsortfiltermodel.h" #include "../../model/syncthingstatusselectionmodel.h" #include "../../connector/syncthingconnection.h" @@ -39,8 +39,9 @@ class SyncthingApplet : public Plasma::Applet { Q_OBJECT Q_PROPERTY(Data::SyncthingConnection *connection READ connection NOTIFY connectionChanged) Q_PROPERTY(Data::SyncthingDirectoryModel *dirModel READ dirModel NOTIFY dirModelChanged) - Q_PROPERTY(Data::SyncthingSortFilterDirectoryModel *sortFilterDirModel READ sortFilterDirModel NOTIFY dirModelChanged) + Q_PROPERTY(Data::SyncthingSortFilterModel *sortFilterDirModel READ sortFilterDirModel NOTIFY dirModelChanged) Q_PROPERTY(Data::SyncthingDeviceModel *devModel READ devModel NOTIFY devModelChanged) + Q_PROPERTY(Data::SyncthingSortFilterModel *sortFilterDevModel READ sortFilterDevModel NOTIFY devModelChanged) Q_PROPERTY(Data::SyncthingDownloadModel *downloadModel READ downloadModel NOTIFY downloadModelChanged) Q_PROPERTY(Data::SyncthingRecentChangesModel *recentChangesModel READ recentChangesModel NOTIFY recentChangesModelChanged) Q_PROPERTY(Data::SyncthingStatusSelectionModel *passiveSelectionModel READ passiveSelectionModel NOTIFY passiveSelectionModelChanged) @@ -73,8 +74,9 @@ public: public: Data::SyncthingConnection *connection() const; Data::SyncthingDirectoryModel *dirModel() const; - Data::SyncthingSortFilterDirectoryModel *sortFilterDirModel() const; + Data::SyncthingSortFilterModel *sortFilterDirModel() const; Data::SyncthingDeviceModel *devModel() const; + Data::SyncthingSortFilterModel *sortFilterDevModel() const; Data::SyncthingDownloadModel *downloadModel() const; Data::SyncthingRecentChangesModel *recentChangesModel() const; Data::SyncthingStatusSelectionModel *passiveSelectionModel() const; @@ -174,8 +176,9 @@ private: #endif QtGui::StatusInfo m_statusInfo; Data::SyncthingDirectoryModel m_dirModel; - Data::SyncthingSortFilterDirectoryModel m_sortFilterDirModel; + Data::SyncthingSortFilterModel m_sortFilterDirModel; Data::SyncthingDeviceModel m_devModel; + Data::SyncthingSortFilterModel m_sortFilterDevModel; Data::SyncthingDownloadModel m_downloadModel; Data::SyncthingRecentChangesModel m_recentChangesModel; Data::SyncthingStatusSelectionModel m_passiveSelectionModel; @@ -200,9 +203,9 @@ inline Data::SyncthingDirectoryModel *SyncthingApplet::dirModel() const return const_cast(&m_dirModel); } -inline Data::SyncthingSortFilterDirectoryModel *SyncthingApplet::sortFilterDirModel() const +inline Data::SyncthingSortFilterModel *SyncthingApplet::sortFilterDirModel() const { - return const_cast(&m_sortFilterDirModel); + return const_cast(&m_sortFilterDirModel); } inline Data::SyncthingDeviceModel *SyncthingApplet::devModel() const @@ -210,6 +213,11 @@ inline Data::SyncthingDeviceModel *SyncthingApplet::devModel() const return const_cast(&m_devModel); } +inline Data::SyncthingSortFilterModel *SyncthingApplet::sortFilterDevModel() const +{ + return const_cast(&m_sortFilterDevModel); +} + inline Data::SyncthingDownloadModel *SyncthingApplet::downloadModel() const { return const_cast(&m_downloadModel); diff --git a/plasmoid/package/contents/ui/DevicesPage.qml b/plasmoid/package/contents/ui/DevicesPage.qml index 591b046..09bc0a2 100644 --- a/plasmoid/package/contents/ui/DevicesPage.qml +++ b/plasmoid/package/contents/ui/DevicesPage.qml @@ -18,7 +18,7 @@ Item { TopLevelView { id: deviceView width: parent.width - model: plasmoid.nativeInterface.devModel + model: plasmoid.nativeInterface.sortFilterDevModel delegate: TopLevelItem { id: item @@ -79,7 +79,7 @@ Item { model: DelegateModel { model: plasmoid.nativeInterface.devModel - rootIndex: detailsView.model.modelIndex(index) + rootIndex: deviceView.model.mapToSource(deviceView.model.index(index, 0)) delegate: DetailItem { width: detailsView.width } diff --git a/tray/gui/devview.cpp b/tray/gui/devview.cpp index 6ba97bc..d908078 100644 --- a/tray/gui/devview.cpp +++ b/tray/gui/devview.cpp @@ -4,6 +4,7 @@ #include "../../connector/syncthingdev.h" #include "../../model/syncthingdevicemodel.h" +#include "../../model/syncthingsortfiltermodel.h" #include #include @@ -28,22 +29,19 @@ DevView::DevView(QWidget *parent) void DevView::mouseReleaseEvent(QMouseEvent *event) { QTreeView::mouseReleaseEvent(event); - const auto *const devModel = qobject_cast(model()); - if (!devModel) { + + const auto pos = event->pos(); + const auto clickedRow = ClickedRow(this, pos); + if (!clickedRow) { return; } - const QPoint pos(event->pos()); - const QModelIndex clickedIndex(indexAt(event->pos())); - if (!clickedIndex.isValid() || clickedIndex.column() != 1 || clickedIndex.parent().isValid()) { + if (clickedRow.index.parent().isValid()) { return; } - const SyncthingDev *const devInfo = devModel->devInfo(clickedIndex); - if (!devInfo) { - return; - } - const QRect itemRect(visualRect(clickedIndex)); + + const auto itemRect = visualRect(clickedRow.proxyIndex); if (pos.x() > itemRect.right() - 17) { - emit pauseResumeDev(*devInfo); + emit pauseResumeDev(*clickedRow.data); } } diff --git a/tray/gui/devview.h b/tray/gui/devview.h index 9aab01b..496836d 100644 --- a/tray/gui/devview.h +++ b/tray/gui/devview.h @@ -6,6 +6,7 @@ namespace Data { struct SyncthingDev; class SyncthingDeviceModel; +class SyncthingSortFilterModel; } // namespace Data namespace QtGui { @@ -14,7 +15,7 @@ class DevView : public QTreeView { Q_OBJECT public: using ModelType = Data::SyncthingDeviceModel; - using SortFilterModelType = void; + using SortFilterModelType = Data::SyncthingSortFilterModel; DevView(QWidget *parent = nullptr); diff --git a/tray/gui/dirview.cpp b/tray/gui/dirview.cpp index 382ca78..de82108 100644 --- a/tray/gui/dirview.cpp +++ b/tray/gui/dirview.cpp @@ -4,7 +4,7 @@ #include "../../connector/syncthingconnection.h" #include "../../model/syncthingdirectorymodel.h" -#include "../../model/syncthingsortfilterdirectorymodel.h" +#include "../../model/syncthingsortfiltermodel.h" #include "../../widgets/misc/direrrorsdialog.h" #include @@ -31,43 +31,32 @@ void DirView::mouseReleaseEvent(QMouseEvent *event) { QTreeView::mouseReleaseEvent(event); - // get SyncthingDir object for clicked index - auto *const sortDirModel = qobject_cast(model()); - auto *const dirModel = qobject_cast(sortDirModel ? sortDirModel->sourceModel() : model()); - if (!dirModel) { - return; - } const auto pos = event->pos(); - const auto clickedProxyIndex = indexAt(event->pos()); - const auto clickedIndex = sortDirModel ? sortDirModel->mapToSource(clickedProxyIndex) : clickedProxyIndex; - if (!clickedIndex.isValid() || clickedIndex.column() != 1) { - return; - } - const auto *const dir = dirModel->dirInfo(clickedIndex); - if (!dir) { + const auto clickedRow = ClickedRow(this, pos); + if (!clickedRow) { return; } - if (!clickedIndex.parent().isValid()) { + if (!clickedRow.index.parent().isValid()) { // open/scan dir buttons - const QRect itemRect = visualRect(clickedProxyIndex); + const QRect itemRect = visualRect(clickedRow.proxyIndex); if (pos.x() <= itemRect.right() - 58) { return; } if (pos.x() < itemRect.right() - 34) { - if (!dir->paused) { - emit scanDir(*dir); + if (!clickedRow.data->paused) { + emit scanDir(*clickedRow.data); } } else if (pos.x() < itemRect.right() - 17) { - emit pauseResumeDir(*dir); + emit pauseResumeDir(*clickedRow.data); } else { - emit openDir(*dir); + emit openDir(*clickedRow.data); } - } else if (clickedIndex.row() == 9 && dir->pullErrorCount) { - auto &connection(*dirModel->connection()); - connection.requestDirPullErrors(dir->id); + } else if (clickedRow.index.row() == 9 && clickedRow.data->pullErrorCount) { + auto &connection(*clickedRow.model->connection()); + connection.requestDirPullErrors(clickedRow.data->id); - auto *const textViewDlg = new DirectoryErrorsDialog(connection, *dir); + auto *const textViewDlg = new DirectoryErrorsDialog(connection, *clickedRow.data); textViewDlg->setAttribute(Qt::WA_DeleteOnClose); textViewDlg->show(); } diff --git a/tray/gui/dirview.h b/tray/gui/dirview.h index 5c7bfdd..f613494 100644 --- a/tray/gui/dirview.h +++ b/tray/gui/dirview.h @@ -6,7 +6,7 @@ namespace Data { struct SyncthingDir; class SyncthingDirectoryModel; -class SyncthingSortFilterDirectoryModel; +class SyncthingSortFilterModel; } // namespace Data namespace QtGui { @@ -15,7 +15,7 @@ class DirView : public QTreeView { Q_OBJECT public: using ModelType = Data::SyncthingDirectoryModel; - using SortFilterModelType = Data::SyncthingSortFilterDirectoryModel; + using SortFilterModelType = Data::SyncthingSortFilterModel; DirView(QWidget *parent = nullptr); diff --git a/tray/gui/helper.h b/tray/gui/helper.h index 0547645..8a73380 100644 --- a/tray/gui/helper.h +++ b/tray/gui/helper.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -23,8 +24,7 @@ inline auto copyToClipboard(const QString &text) return [=] { QGuiApplication::clipboard()->setText(text); }; } -template struct SelectedRow { - explicit SelectedRow(ViewType *view); +template struct BasicRowData { operator bool() const; typename ViewType::ModelType *model = nullptr; @@ -32,6 +32,22 @@ template struct SelectedRow { decltype(model->info(index)) data = decltype(model->info(index))(); }; +template BasicRowData::operator bool() const +{ + if (!model || !index.isValid()) { + return false; + } + if constexpr (CppUtilities::Traits::IsSpecializationOf::value) { + return data.first; + } else { + return data; + } +} + +template struct SelectedRow : public BasicRowData { + explicit SelectedRow(ViewType *view); +}; + template SelectedRow::SelectedRow(ViewType *view) { auto *const selectionModel = view->selectionModel(); @@ -42,30 +58,38 @@ template SelectedRow::SelectedRow(ViewType *view) if (selectedRows.size() != 1) { return; } - index = selectedRows.at(0); + this->index = selectedRows.at(0); if constexpr (std::is_void_v) { - model = qobject_cast(view->model()); + this->model = qobject_cast(view->model()); } else { const auto *const sortFilterModel = qobject_cast(view->model()); if (sortFilterModel) { - index = sortFilterModel->mapToSource(index); - model = qobject_cast(sortFilterModel->sourceModel()); + this->index = sortFilterModel->mapToSource(this->index); + this->model = qobject_cast(sortFilterModel->sourceModel()); } } - if (model) { - data = model->info(index); + if (this->model) { + this->data = this->model->info(this->index); } } -template SelectedRow::operator bool() const +template struct ClickedRow : public BasicRowData { + explicit ClickedRow(ViewType *view, const QPoint &clickPoint); + + typename ViewType::SortFilterModelType *proxyModel = nullptr; + QModelIndex proxyIndex; +}; + +template ClickedRow::ClickedRow(ViewType *view, const QPoint &clickPoint) { - if (!model || !index.isValid()) { - return false; + if constexpr (!std::is_void_v) { + proxyModel = qobject_cast(view->model()); } - if constexpr (CppUtilities::Traits::IsSpecializationOf::value) { - return data.first; - } else { - return data; + this->model = qobject_cast(proxyModel ? proxyModel->sourceModel() : view->model()); + proxyIndex = view->indexAt(clickPoint); + this->index = proxyModel ? proxyModel->mapToSource(proxyIndex) : proxyIndex; + if (this->model && this->index.isValid() && this->index.column() == 1) { + this->data = this->model->info(this->index); } } diff --git a/tray/gui/traywidget.cpp b/tray/gui/traywidget.cpp index d341212..1944a89 100644 --- a/tray/gui/traywidget.cpp +++ b/tray/gui/traywidget.cpp @@ -79,6 +79,7 @@ TrayWidget::TrayWidget(TrayMenu *parent) , m_dirModel(m_connection) , m_sortFilterDirModel(&m_dirModel) , m_devModel(m_connection) + , m_sortFilterDevModel(&m_devModel) , m_dlModel(m_connection) , m_recentChangesModel(m_connection) , m_selectedConnection(nullptr) @@ -102,7 +103,8 @@ TrayWidget::TrayWidget(TrayMenu *parent) // setup models and views m_ui->dirsTreeView->header()->setSortIndicator(0, Qt::AscendingOrder); m_ui->dirsTreeView->setModel(&m_sortFilterDirModel); - m_ui->devsTreeView->setModel(&m_devModel); + m_ui->devsTreeView->header()->setSortIndicator(0, Qt::AscendingOrder); + m_ui->devsTreeView->setModel(&m_sortFilterDevModel); m_ui->downloadsTreeView->setModel(&m_dlModel); m_ui->recentChangesTreeView->setModel(&m_recentChangesModel); m_ui->recentChangesTreeView->setContextMenuPolicy(Qt::CustomContextMenu); diff --git a/tray/gui/traywidget.h b/tray/gui/traywidget.h index cff121b..836e83b 100644 --- a/tray/gui/traywidget.h +++ b/tray/gui/traywidget.h @@ -8,7 +8,7 @@ #include "../../model/syncthingdirectorymodel.h" #include "../../model/syncthingdownloadmodel.h" #include "../../model/syncthingrecentchangesmodel.h" -#include "../../model/syncthingsortfilterdirectorymodel.h" +#include "../../model/syncthingsortfiltermodel.h" #include "../../connector/syncthingconnection.h" #include "../../connector/syncthingnotifier.h" @@ -121,8 +121,9 @@ private: Data::SyncthingConnection m_connection; Data::SyncthingNotifier m_notifier; Data::SyncthingDirectoryModel m_dirModel; - Data::SyncthingSortFilterDirectoryModel m_sortFilterDirModel; + Data::SyncthingSortFilterModel m_sortFilterDirModel; Data::SyncthingDeviceModel m_devModel; + Data::SyncthingSortFilterModel m_sortFilterDevModel; Data::SyncthingDownloadModel m_dlModel; Data::SyncthingRecentChangesModel m_recentChangesModel; QMenu *m_connectionsMenu; diff --git a/tray/gui/traywidget.ui b/tray/gui/traywidget.ui index 0563403..818fae5 100644 --- a/tray/gui/traywidget.ui +++ b/tray/gui/traywidget.ui @@ -436,7 +436,11 @@ For <i>all</i> notifications, checkout the log 0 - + + + true + + @@ -545,8 +549,8 @@ For <i>all</i> notifications, checkout the log - +