diff --git a/src/library/autodj/dlgautodj.cpp b/src/library/autodj/dlgautodj.cpp index 666f3030786..87fcde8e822 100644 --- a/src/library/autodj/dlgautodj.cpp +++ b/src/library/autodj/dlgautodj.cpp @@ -385,3 +385,11 @@ bool DlgAutoDJ::hasFocus() const { void DlgAutoDJ::setFocus() { m_pTrackTableView->setFocus(); } + +void DlgAutoDJ::saveCurrentViewState() { + m_pTrackTableView->saveCurrentViewState(); +} + +void DlgAutoDJ::restoreCurrentViewState() { + m_pTrackTableView->restoreCurrentViewState(); +} diff --git a/src/library/autodj/dlgautodj.h b/src/library/autodj/dlgautodj.h index 05933ae0e23..c109a56363e 100644 --- a/src/library/autodj/dlgautodj.h +++ b/src/library/autodj/dlgautodj.h @@ -34,6 +34,8 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ, public LibraryView { void loadSelectedTrack() override; void loadSelectedTrackToGroup(const QString& group, bool play) override; void moveSelection(int delta) override; + void saveCurrentViewState() override; + void restoreCurrentViewState() override; public slots: void shufflePlaylistButton(bool buttonChecked); diff --git a/src/library/baseexternalplaylistmodel.cpp b/src/library/baseexternalplaylistmodel.cpp index 44f77ab0905..3382dd24c67 100644 --- a/src/library/baseexternalplaylistmodel.cpp +++ b/src/library/baseexternalplaylistmodel.cpp @@ -8,6 +8,12 @@ #include "moc_baseexternalplaylistmodel.cpp" #include "track/track.h" +namespace { + +const QString kModelName = "external:"; + +} // anonymous namespace + BaseExternalPlaylistModel::BaseExternalPlaylistModel(QObject* parent, TrackCollectionManager* pTrackCollectionManager, const char* settingsNamespace, @@ -17,7 +23,8 @@ BaseExternalPlaylistModel::BaseExternalPlaylistModel(QObject* parent, : BaseSqlTableModel(parent, pTrackCollectionManager, settingsNamespace), m_playlistsTable(playlistsTable), m_playlistTracksTable(playlistTracksTable), - m_trackSource(trackSource) { + m_trackSource(trackSource), + m_currentPlaylistId(-1) { } BaseExternalPlaylistModel::~BaseExternalPlaylistModel() { @@ -134,6 +141,7 @@ void BaseExternalPlaylistModel::setPlaylist(const QString& playlist_path) { return; } + m_currentPlaylistId = playlistId; playlistViewColumns.last() = LIBRARYTABLE_PREVIEW; setTable(playlistViewTable, playlistViewColumns.first(), playlistViewColumns, m_trackSource); setDefaultSort(fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION), @@ -163,3 +171,14 @@ TrackModel::Capabilities BaseExternalPlaylistModel::getCapabilities() const { Capability::LoadToPreviewDeck | Capability::LoadToSampler; } + +QString BaseExternalPlaylistModel::modelKey(bool noSearch) const { + if (noSearch) { + return kModelName + + QString::number(m_currentPlaylistId); + } + return kModelName + + QString::number(m_currentPlaylistId) + + QStringLiteral("#") + + currentSearch(); +} diff --git a/src/library/baseexternalplaylistmodel.h b/src/library/baseexternalplaylistmodel.h index ba8f8b81b27..38cb0546723 100644 --- a/src/library/baseexternalplaylistmodel.h +++ b/src/library/baseexternalplaylistmodel.h @@ -1,16 +1,16 @@ #pragma once -#include #include -#include -#include #include +#include +#include +#include -#include "library/trackmodel.h" #include "library/basesqltablemodel.h" -#include "library/librarytablemodel.h" #include "library/dao/playlistdao.h" #include "library/dao/trackdao.h" +#include "library/librarytablemodel.h" +#include "library/trackmodel.h" class BaseExternalPlaylistModel : public BaseSqlTableModel { Q_OBJECT @@ -28,6 +28,7 @@ class BaseExternalPlaylistModel : public BaseSqlTableModel { bool isColumnInternal(int column) override; Qt::ItemFlags flags(const QModelIndex &index) const override; Capabilities getCapabilities() const override; + QString modelKey(bool noSearch) const override; private: TrackId doGetTrackId(const TrackPointer& pTrack) const override; @@ -35,4 +36,5 @@ class BaseExternalPlaylistModel : public BaseSqlTableModel { QString m_playlistsTable; QString m_playlistTracksTable; QSharedPointer m_trackSource; + int m_currentPlaylistId; }; diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp index 3d052440c24..ae539e3aa7c 100644 --- a/src/library/basesqltablemodel.cpp +++ b/src/library/basesqltablemodel.cpp @@ -34,6 +34,8 @@ constexpr int kMaxSortColumns = 3; // Constant for getModelSetting(name) const QString COLUMNS_SORTING = QStringLiteral("ColumnsSorting"); +const QString kModelName = "table:"; + } // anonymous namespace BaseSqlTableModel::BaseSqlTableModel( @@ -613,6 +615,15 @@ int BaseSqlTableModel::fieldIndex(const QString& fieldName) const { return tableIndex; } +QString BaseSqlTableModel::modelKey(bool noSearch) const { + if (noSearch) { + return kModelName + m_tableName; + } + return kModelName + m_tableName + + QStringLiteral("#") + + currentSearch(); +} + QVariant BaseSqlTableModel::rawValue( const QModelIndex& index) const { DEBUG_ASSERT(index.isValid()); diff --git a/src/library/basesqltablemodel.h b/src/library/basesqltablemodel.h index 9f84964c0d2..01003893418 100644 --- a/src/library/basesqltablemodel.h +++ b/src/library/basesqltablemodel.h @@ -73,6 +73,8 @@ class BaseSqlTableModel : public BaseTrackTableModel { int fieldIndex( ColumnCache::Column column) const final; + QString modelKey(bool noSearch) const override; + protected: /////////////////////////////////////////////////////////////////////////// // Inherited from BaseTrackTableModel @@ -98,6 +100,7 @@ class BaseSqlTableModel : public BaseTrackTableModel { QList getTrackRefs(const QModelIndexList& indices) const; QSqlDatabase m_database; + QString m_tableName; QString m_tableOrderBy; int m_columnIndexBySortColumnId[static_cast(TrackModel::SortColumnId::IdMax)]; @@ -140,7 +143,6 @@ class BaseSqlTableModel : public BaseTrackTableModel { QVector m_rowInfo; - QString m_tableName; QString m_idColumn; QSharedPointer m_trackSource; QStringList m_tableColumns; diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 97653ef41d0..ef024497664 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -40,6 +40,10 @@ BrowseFeature::BrowseFeature( &BrowseFeature::requestAddDir, pLibrary, &Library::slotRequestAddDir); + connect(&m_browseModel, + &BrowseTableModel::restoreModelState, + this, + &LibraryFeature::restoreModelState); m_pAddQuickLinkAction = new QAction(tr("Add to Quick Links"),this); connect(m_pAddQuickLinkAction, @@ -245,6 +249,7 @@ void BrowseFeature::activateChild(const QModelIndex& index) { QString path = item->getData().toString(); if (path == QUICK_LINK_NODE || path == DEVICE_NODE) { + emit saveModelState(); m_browseModel.setPath({}); } else { // Open a security token for this path and if we do not have access, ask @@ -260,6 +265,7 @@ void BrowseFeature::activateChild(const QModelIndex& index) { return; } } + emit saveModelState(); m_browseModel.setPath(std::move(dirAccess)); } emit showTrackModel(&m_proxyModel); diff --git a/src/library/browse/browsetablemodel.cpp b/src/library/browse/browsetablemodel.cpp index b0c43a86835..77c013a5ecc 100644 --- a/src/library/browse/browsetablemodel.cpp +++ b/src/library/browse/browsetablemodel.cpp @@ -210,6 +210,11 @@ void BrowseTableModel::addSearchColumn(int index) { } void BrowseTableModel::setPath(mixxx::FileAccess path) { + if (path.info().hasLocation()) { + m_currentDirectory = path.info().locationPath(); + } else { + m_currentDirectory = QString(); + } m_pBrowseThread->executePopulation(std::move(path), this); } @@ -360,6 +365,7 @@ void BrowseTableModel::slotInsert(const QList >& rows, appendRow(rows.at(i)); } } + emit restoreModelState(); } TrackModel::Capabilities BrowseTableModel::getCapabilities() const { @@ -370,6 +376,12 @@ TrackModel::Capabilities BrowseTableModel::getCapabilities() const { Capability::LoadToSampler; } +QString BrowseTableModel::modelKey(bool noSearch) const { + // Browse feature does currently not support searching. + Q_UNUSED(noSearch); + return QStringLiteral("browse:") + m_currentDirectory; +} + Qt::ItemFlags BrowseTableModel::flags(const QModelIndex& index) const { Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); diff --git a/src/library/browse/browsetablemodel.h b/src/library/browse/browsetablemodel.h index de6c47cd593..f4c20d889e5 100644 --- a/src/library/browse/browsetablemodel.h +++ b/src/library/browse/browsetablemodel.h @@ -52,6 +52,7 @@ class BrowseTableModel final : public QStandardItemModel, public virtual TrackMo BrowseTableModel(QObject* parent, TrackCollectionManager* pTrackCollectionManager, RecordingManager* pRec); virtual ~BrowseTableModel(); + // initiate table population, store path void setPath(mixxx::FileAccess path); TrackPointer getTrack(const QModelIndex& index) const override; @@ -78,6 +79,7 @@ class BrowseTableModel final : public QStandardItemModel, public virtual TrackMo bool isColumnSortable(int column) const override; TrackModel::SortColumnId sortColumnIdFromColumnIndex(int index) const override; int columnIndexFromSortColumnId(TrackModel::SortColumnId sortColumn) const override; + QString modelKey(bool noSearch) const override; bool updateTrackGenre( Track* pTrack, @@ -88,6 +90,9 @@ class BrowseTableModel final : public QStandardItemModel, public virtual TrackMo const QString& mood) const override; #endif // __EXTRA_METADATA__ + signals: + void restoreModelState(); + public slots: void slotClear(BrowseTableModel*); void slotInsert(const QList< QList >&, BrowseTableModel*); @@ -101,6 +106,7 @@ class BrowseTableModel final : public QStandardItemModel, public virtual TrackMo QList m_searchColumns; RecordingManager* m_pRecordingManager; BrowseThreadPointer m_pBrowseThread; + QString m_currentDirectory; QString m_previewDeckGroup; int m_columnIndexBySortColumnId[static_cast(TrackModel::SortColumnId::IdMax)]; QMap m_sortColumnIdByColumnIndex; diff --git a/src/library/dlganalysis.cpp b/src/library/dlganalysis.cpp index c5ef8e3681f..ea804bb56b0 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/dlganalysis.cpp @@ -229,3 +229,11 @@ void DlgAnalysis::installEventFilter(QObject* pFilter) { QWidget::installEventFilter(pFilter); m_pAnalysisLibraryTableView->installEventFilter(pFilter); } + +void DlgAnalysis::saveCurrentViewState() { + m_pAnalysisLibraryTableView->saveCurrentViewState(); +} + +void DlgAnalysis::restoreCurrentViewState() { + m_pAnalysisLibraryTableView->restoreCurrentViewState(); +} diff --git a/src/library/dlganalysis.h b/src/library/dlganalysis.h index b75beede923..e9955eae708 100644 --- a/src/library/dlganalysis.h +++ b/src/library/dlganalysis.h @@ -3,11 +3,11 @@ #include #include -#include "preferences/usersettings.h" +#include "analyzer/analyzerprogress.h" #include "library/analysislibrarytablemodel.h" #include "library/libraryview.h" #include "library/ui_dlganalysis.h" -#include "analyzer/analyzerprogress.h" +#include "preferences/usersettings.h" class AnalysisLibraryTableModel; class WAnalysisLibraryTableView; @@ -35,6 +35,8 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis, public virtual Libra inline const QString currentSearch() { return m_pAnalysisLibraryTableModel->currentSearch(); } + void saveCurrentViewState() override; + void restoreCurrentViewState() override; public slots: void tableSelectionChanged(const QItemSelection& selected, diff --git a/src/library/dlghidden.cpp b/src/library/dlghidden.cpp index d4f9fd674f5..118508933cb 100644 --- a/src/library/dlghidden.cpp +++ b/src/library/dlghidden.cpp @@ -124,6 +124,14 @@ bool DlgHidden::hasFocus() const { return m_pTrackTableView->hasFocus(); } +void DlgHidden::saveCurrentViewState() { + m_pTrackTableView->saveCurrentViewState(); +} + +void DlgHidden::restoreCurrentViewState() { + m_pTrackTableView->restoreCurrentViewState(); +} + void DlgHidden::setFocus() { m_pTrackTableView->setFocus(); } diff --git a/src/library/dlghidden.h b/src/library/dlghidden.h index cd1f04cd520..2a459c77366 100644 --- a/src/library/dlghidden.h +++ b/src/library/dlghidden.h @@ -2,11 +2,11 @@ #include -#include "library/ui_dlghidden.h" -#include "preferences/usersettings.h" +#include "controllers/keyboard/keyboardeventfilter.h" #include "library/library.h" #include "library/libraryview.h" -#include "controllers/keyboard/keyboardeventfilter.h" +#include "library/ui_dlghidden.h" +#include "preferences/usersettings.h" class WLibrary; class WTrackTableView; @@ -26,6 +26,8 @@ class DlgHidden : public QWidget, public Ui::DlgHidden, public LibraryView { void setFocus() override; void onSearch(const QString& text) override; QString currentSearch(); + void saveCurrentViewState() override; + void restoreCurrentViewState() override; public slots: void clicked(); diff --git a/src/library/dlgmissing.cpp b/src/library/dlgmissing.cpp index 70340594b28..7c50bc8deb8 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/dlgmissing.cpp @@ -93,6 +93,13 @@ bool DlgMissing::hasFocus() const { return m_pTrackTableView->hasFocus(); } +void DlgMissing::saveCurrentViewState() { + m_pTrackTableView->saveCurrentViewState(); +}; +void DlgMissing::restoreCurrentViewState() { + m_pTrackTableView->restoreCurrentViewState(); +}; + void DlgMissing::setFocus() { m_pTrackTableView->setFocus(); } diff --git a/src/library/dlgmissing.h b/src/library/dlgmissing.h index 882848bfb4e..ac992ecf3f8 100644 --- a/src/library/dlgmissing.h +++ b/src/library/dlgmissing.h @@ -2,11 +2,11 @@ #include -#include "library/ui_dlgmissing.h" -#include "preferences/usersettings.h" +#include "controllers/keyboard/keyboardeventfilter.h" #include "library/library.h" #include "library/libraryview.h" -#include "controllers/keyboard/keyboardeventfilter.h" +#include "library/ui_dlgmissing.h" +#include "preferences/usersettings.h" class WLibrary; class WTrackTableView; @@ -26,6 +26,8 @@ class DlgMissing : public QWidget, public Ui::DlgMissing, public LibraryView { void setFocus() override; void onSearch(const QString& text) override; QString currentSearch(); + void saveCurrentViewState() override; + void restoreCurrentViewState() override; public slots: void clicked(); diff --git a/src/library/hiddentablemodel.cpp b/src/library/hiddentablemodel.cpp index db1a488d387..2f787e318ca 100644 --- a/src/library/hiddentablemodel.cpp +++ b/src/library/hiddentablemodel.cpp @@ -5,6 +5,12 @@ #include "library/trackcollectionmanager.h" #include "moc_hiddentablemodel.cpp" +namespace { + +const QString kModelName = "hidden:"; + +} // anonymous namespace + HiddenTableModel::HiddenTableModel(QObject* parent, TrackCollectionManager* pTrackCollectionManager) : BaseSqlTableModel(parent, pTrackCollectionManager, "mixxx.db.model.missing") { @@ -91,3 +97,12 @@ Qt::ItemFlags HiddenTableModel::flags(const QModelIndex& index) const { TrackModel::Capabilities HiddenTableModel::getCapabilities() const { return Capability::Purge | Capability::Unhide; } + +QString HiddenTableModel::modelKey(bool noSearch) const { + if (noSearch) { + return kModelName + m_tableName; + } + return kModelName + m_tableName + + QStringLiteral("#") + + currentSearch(); +} diff --git a/src/library/hiddentablemodel.h b/src/library/hiddentablemodel.h index f2fabc9d3e5..64cfcf9be1a 100644 --- a/src/library/hiddentablemodel.h +++ b/src/library/hiddentablemodel.h @@ -15,4 +15,6 @@ class HiddenTableModel final : public BaseSqlTableModel { void unhideTracks(const QModelIndexList& indices) final; Qt::ItemFlags flags(const QModelIndex &index) const final; Capabilities getCapabilities() const final; + + QString modelKey(bool noSearch) const override; }; diff --git a/src/library/library.cpp b/src/library/library.cpp index 101fbb07fdd..78ecb99b983 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -393,7 +393,14 @@ void Library::bindLibraryWidget( &Library::switchToView, pLibraryWidget, &WLibrary::switchToView); - + connect(this, + &Library::saveModelState, + pTrackTableView, + &WTrackTableView::slotSaveCurrentViewState); + connect(this, + &Library::restoreModelState, + pTrackTableView, + &WTrackTableView::slotRestoreCurrentViewState); connect(pTrackTableView, &WTrackTableView::trackSelected, this, @@ -474,6 +481,14 @@ void Library::addFeature(LibraryFeature* feature) { &LibraryFeature::trackSelected, this, &Library::trackSelected); + connect(feature, + &LibraryFeature::saveModelState, + this, + &Library::saveModelState); + connect(feature, + &LibraryFeature::restoreModelState, + this, + &Library::restoreModelState); } void Library::onPlayerManagerTrackAnalyzerProgress( diff --git a/src/library/library.h b/src/library/library.h index 873b72a838e..60675511461 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -120,7 +120,7 @@ class Library: public QObject { void onSkinLoadFinished(); signals: - void showTrackModel(QAbstractItemModel* model); + void showTrackModel(QAbstractItemModel* model, bool restoreState = true); void switchToView(const QString& view); void loadTrack(TrackPointer pTrack); void loadTrackToPlayer(TrackPointer pTrack, const QString& group, bool play = false); @@ -134,6 +134,8 @@ class Library: public QObject { void exportLibrary(); void exportCrate(CrateId crateId); #endif + void saveModelState(); + void restoreModelState(); void setTrackTableFont(const QFont& font); void setTrackTableRowHeight(int rowHeight); diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h index a48f59b1b15..9b4a55eaf28 100644 --- a/src/library/libraryfeature.h +++ b/src/library/libraryfeature.h @@ -121,10 +121,14 @@ class LibraryFeature : public QObject { Q_UNUSED(index); } signals: - void showTrackModel(QAbstractItemModel* model); + void showTrackModel(QAbstractItemModel* model, bool restoreState = true); void switchToView(const QString& view); void loadTrack(TrackPointer pTrack); void loadTrackToPlayer(TrackPointer pTrack, const QString& group, bool play = false); + /// saves the scroll, selection and current state of the library model + void saveModelState(); + /// restores the scroll, selection and current state of the library model + void restoreModelState(); void restoreSearch(const QString&); void disableSearch(); // emit this signal before you parse a large music collection, e.g., iTunes, Traktor. diff --git a/src/library/libraryview.h b/src/library/libraryview.h index 1c4498fd0d8..74c9fa7d3cf 100644 --- a/src/library/libraryview.h +++ b/src/library/libraryview.h @@ -12,7 +12,8 @@ class LibraryView { public: - virtual ~LibraryView() {}; + virtual ~LibraryView() { + } virtual void onShow() = 0; virtual bool hasFocus() const = 0; @@ -23,11 +24,19 @@ class LibraryView { /// If applicable, requests that the LibraryView load the selected /// track. Does nothing otherwise. - virtual void loadSelectedTrack() {}; + virtual void loadSelectedTrack() { + } - virtual void slotAddToAutoDJBottom() {}; - virtual void slotAddToAutoDJTop() {}; - virtual void slotAddToAutoDJReplace() {}; + virtual void slotAddToAutoDJBottom() { + } + virtual void slotAddToAutoDJTop() { + } + virtual void slotAddToAutoDJReplace() { + } + virtual void saveCurrentViewState() { + } + virtual void restoreCurrentViewState() { + } /// If applicable, requests that the LibraryView load the selected track to /// the specified group. Does nothing otherwise. @@ -42,9 +51,11 @@ class LibraryView { virtual TrackModel::SortColumnId getColumnIdFromCurrentIndex() { return TrackModel::SortColumnId::Invalid; - }; + } /// If applicable, requests that the LibraryView changes the track color of /// the selected track. Does nothing otherwise. - virtual void assignPreviousTrackColor(){}; - virtual void assignNextTrackColor(){}; + virtual void assignPreviousTrackColor() { + } + virtual void assignNextTrackColor() { + } }; diff --git a/src/library/missingtablemodel.cpp b/src/library/missingtablemodel.cpp index 59ea189cc71..9c72a6d4509 100644 --- a/src/library/missingtablemodel.cpp +++ b/src/library/missingtablemodel.cpp @@ -8,6 +8,7 @@ namespace { const QString kMissingFilter = "mixxx_deleted=0 AND fs_deleted=1"; +const QString kModelName = "missing:"; } // anonymous namespace @@ -89,3 +90,12 @@ Qt::ItemFlags MissingTableModel::flags(const QModelIndex &index) const { TrackModel::Capabilities MissingTableModel::getCapabilities() const { return Capability::Purge; } + +QString MissingTableModel::modelKey(bool noSearch) const { + if (noSearch) { + return kModelName + m_tableName; + } + return kModelName + m_tableName + + QStringLiteral("#") + + currentSearch(); +} diff --git a/src/library/missingtablemodel.h b/src/library/missingtablemodel.h index c57a16e0dc8..94761a9449e 100644 --- a/src/library/missingtablemodel.h +++ b/src/library/missingtablemodel.h @@ -20,4 +20,6 @@ class MissingTableModel final : public BaseSqlTableModel { void purgeTracks(const QModelIndexList& indices) final; Qt::ItemFlags flags(const QModelIndex &index) const final; Capabilities getCapabilities() const final; + + QString modelKey(bool noSearch) const override; }; diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp index 20e9866caa4..fbfd6f59f96 100644 --- a/src/library/mixxxlibraryfeature.cpp +++ b/src/library/mixxxlibraryfeature.cpp @@ -176,12 +176,15 @@ void MixxxLibraryFeature::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { #endif void MixxxLibraryFeature::activate() { + //qDebug() << "MixxxLibraryFeature::activate()"; + emit saveModelState(); emit showTrackModel(m_pLibraryTableModel); emit enableCoverArtDisplay(true); } void MixxxLibraryFeature::activateChild(const QModelIndex& index) { QString itemName = index.data().toString(); + emit saveModelState(); emit switchToView(itemName); if (m_pMissingView && itemName == kMissingTitle) { emit restoreSearch(m_pMissingView->currentSearch()); diff --git a/src/library/playlisttablemodel.cpp b/src/library/playlisttablemodel.cpp index dd4f166b9da..6052ec012e2 100644 --- a/src/library/playlisttablemodel.cpp +++ b/src/library/playlisttablemodel.cpp @@ -7,6 +7,12 @@ #include "library/trackcollectionmanager.h" #include "moc_playlisttablemodel.cpp" +namespace { + +const QString kModelName = "playlist:"; + +} // anonymous namespace + PlaylistTableModel::PlaylistTableModel(QObject* parent, TrackCollectionManager* pTrackCollectionManager, const char* settingsNamespace, @@ -348,6 +354,15 @@ TrackModel::Capabilities PlaylistTableModel::getCapabilities() const { return caps; } +QString PlaylistTableModel::modelKey(bool noSearch) const { + if (noSearch) { + return kModelName + m_tableName; + } + return kModelName + m_tableName + + QStringLiteral("#") + + currentSearch(); +} + void PlaylistTableModel::playlistsChanged(const QSet& playlistIds) { if (playlistIds.contains(m_iPlaylistId)) { select(); // Repopulate the data model. diff --git a/src/library/playlisttablemodel.h b/src/library/playlisttablemodel.h index c2d0b92a470..0b5dce17115 100644 --- a/src/library/playlisttablemodel.h +++ b/src/library/playlisttablemodel.h @@ -30,6 +30,8 @@ class PlaylistTableModel final : public TrackSetTableModel { Capabilities getCapabilities() const final; + QString modelKey(bool noSearch) const override; + private slots: void playlistsChanged(const QSet& playlistIds); diff --git a/src/library/proxytrackmodel.cpp b/src/library/proxytrackmodel.cpp index 5be930b9dfe..b6e942b40b8 100644 --- a/src/library/proxytrackmodel.cpp +++ b/src/library/proxytrackmodel.cpp @@ -76,6 +76,10 @@ void ProxyTrackModel::search(const QString& searchText, const QString& extraFilt } } +QString ProxyTrackModel::modelKey(bool noSearch) const { + return m_pTrackModel ? m_pTrackModel->modelKey(noSearch) : QString(); +} + const QString ProxyTrackModel::currentSearch() const { if (m_bHandleSearches) { return m_currentSearch; diff --git a/src/library/proxytrackmodel.h b/src/library/proxytrackmodel.h index 5c1558d7b3c..b7ac388433d 100644 --- a/src/library/proxytrackmodel.h +++ b/src/library/proxytrackmodel.h @@ -55,6 +55,7 @@ class ProxyTrackModel : public QSortFilterProxyModel, public TrackModel { // Inherited from QAbstractItemModel void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) final; + QString modelKey(bool noSearch) const override; private: TrackModel* m_pTrackModel; diff --git a/src/library/recording/dlgrecording.cpp b/src/library/recording/dlgrecording.cpp index c5befa11422..820ef11b032 100644 --- a/src/library/recording/dlgrecording.cpp +++ b/src/library/recording/dlgrecording.cpp @@ -69,6 +69,10 @@ DlgRecording::DlgRecording( &RecordingManager::durationRecorded, this, &DlgRecording::slotDurationRecorded); + connect(&m_browseModel, + &BrowseTableModel::restoreModelState, + m_pTrackTableView, + &WTrackTableView::restoreCurrentViewState); QBoxLayout* box = qobject_cast(layout()); VERIFY_OR_DEBUG_ASSERT(box) { //Assumes the form layout is a QVBox/QHBoxLayout! @@ -197,3 +201,11 @@ void DlgRecording::refreshLabels() { labelRecFilename->setText(recFile); labelRecStatistics->setText(recData); } + +void DlgRecording::saveCurrentViewState() { + m_pTrackTableView->saveCurrentViewState(); +} + +void DlgRecording::restoreCurrentViewState() { + m_pTrackTableView->restoreCurrentViewState(); +} diff --git a/src/library/recording/dlgrecording.h b/src/library/recording/dlgrecording.h index 306548b8620..079fd2d9af3 100644 --- a/src/library/recording/dlgrecording.h +++ b/src/library/recording/dlgrecording.h @@ -34,6 +34,8 @@ class DlgRecording : public QWidget, public Ui::DlgRecording, public virtual Lib void loadSelectedTrackToGroup(const QString& group, bool play) override; void moveSelection(int delta) override; inline const QString currentSearch() { return m_proxyModel.currentSearch(); } + void saveCurrentViewState() override; + void restoreCurrentViewState() override; public slots: void slotRecordingStateChanged(bool); @@ -46,6 +48,7 @@ class DlgRecording : public QWidget, public Ui::DlgRecording, public virtual Lib void loadTrack(TrackPointer tio); void loadTrackToPlayer(TrackPointer tio, const QString& group, bool play); void restoreSearch(const QString& search); + void restoreModelState(); private: UserSettingsPointer m_pConfig; diff --git a/src/library/recording/recordingfeature.cpp b/src/library/recording/recordingfeature.cpp index 1657f37864c..41e7d8506ae 100644 --- a/src/library/recording/recordingfeature.cpp +++ b/src/library/recording/recordingfeature.cpp @@ -61,6 +61,10 @@ void RecordingFeature::bindLibraryWidget(WLibrary* pLibraryWidget, &DlgRecording::restoreSearch, this, &RecordingFeature::restoreSearch); + connect(pRecordingView, + &DlgRecording::restoreModelState, + this, + &RecordingFeature::restoreModelState); } diff --git a/src/library/rhythmbox/rhythmboxfeature.cpp b/src/library/rhythmbox/rhythmboxfeature.cpp index a0dacbe3797..74bb88be18c 100644 --- a/src/library/rhythmbox/rhythmboxfeature.cpp +++ b/src/library/rhythmbox/rhythmboxfeature.cpp @@ -123,7 +123,7 @@ void RhythmboxFeature::activate() { //calls a slot in the sidebar model such that 'Rhythmbox (isLoading)' is displayed. emit featureIsLoading(this, true); } - + emit saveModelState(); emit showTrackModel(m_pRhythmboxTrackModel); emit enableCoverArtDisplay(false); } @@ -132,6 +132,7 @@ void RhythmboxFeature::activateChild(const QModelIndex& index) { //qDebug() << "RhythmboxFeature::activateChild()" << index; QString playlist = index.data().toString(); qDebug() << "Activating " << playlist; + emit saveModelState(); m_pRhythmboxPlaylistModel->setPlaylist(playlist); emit showTrackModel(m_pRhythmboxPlaylistModel); emit enableCoverArtDisplay(false); diff --git a/src/library/serato/seratofeature.cpp b/src/library/serato/seratofeature.cpp index 078c54a3223..82fa79c17a7 100644 --- a/src/library/serato/seratofeature.cpp +++ b/src/library/serato/seratofeature.cpp @@ -1048,6 +1048,7 @@ void SeratoFeature::activateChild(const QModelIndex& index) { item->setData(QVariant(data)); } else { qDebug() << "Activate Serato Playlist: " << playlist; + emit saveModelState(); m_pSeratoPlaylistModel->setPlaylist(playlist); emit showTrackModel(m_pSeratoPlaylistModel); } @@ -1124,7 +1125,7 @@ void SeratoFeature::onTracksFound() { QString databasePlaylist = m_tracksFuture.result(); qDebug() << "Show Serato Database Playlist: " << databasePlaylist; - + emit saveModelState(); m_pSeratoPlaylistModel->setPlaylist(databasePlaylist); emit showTrackModel(m_pSeratoPlaylistModel); } diff --git a/src/library/trackmodel.h b/src/library/trackmodel.h index d0425601200..a4cd491a824 100644 --- a/src/library/trackmodel.h +++ b/src/library/trackmodel.h @@ -211,6 +211,11 @@ class TrackModel { virtual void select() { } + /// @brief modelKey returns a unique identifier for the model + /// @param noSearch don't include the current search in the key + /// @param baseOnly return only a identifier for the whole subsystem + virtual QString modelKey(bool noSearch) const = 0; + virtual bool updateTrackGenre( Track* pTrack, const QString& genre) const = 0; diff --git a/src/library/trackset/baseplaylistfeature.cpp b/src/library/trackset/baseplaylistfeature.cpp index 1bc39886bfa..c9e65d57861 100644 --- a/src/library/trackset/baseplaylistfeature.cpp +++ b/src/library/trackset/baseplaylistfeature.cpp @@ -184,6 +184,7 @@ void BasePlaylistFeature::activateChild(const QModelIndex& index) { // like the year folder in the history feature return; } + emit saveModelState(); m_pPlaylistTableModel->setTableModel(playlistId); emit showTrackModel(m_pPlaylistTableModel); emit enableCoverArtDisplay(true); @@ -198,6 +199,7 @@ void BasePlaylistFeature::activatePlaylist(int playlistId) { VERIFY_OR_DEBUG_ASSERT(index.isValid()) { return; } + emit saveModelState(); m_lastRightClickedIndex = index; m_pPlaylistTableModel->setTableModel(playlistId); emit showTrackModel(m_pPlaylistTableModel); @@ -501,6 +503,7 @@ void BasePlaylistFeature::slotCreateImportPlaylist() { lastPlaylistId = m_playlistDao.createPlaylist(name); if (lastPlaylistId != kInvalidPlaylistId) { + emit saveModelState(); m_pPlaylistTableModel->setTableModel(lastPlaylistId); } else { QMessageBox::warning(nullptr, @@ -560,6 +563,7 @@ void BasePlaylistFeature::slotExportPlaylist() { m_pLibrary->trackCollectionManager(), "mixxx.db.model.playlist_export")); + emit saveModelState(); pPlaylistTableModel->setTableModel(m_pPlaylistTableModel->getPlaylist()); pPlaylistTableModel->setSort( pPlaylistTableModel->fieldIndex( @@ -602,6 +606,7 @@ void BasePlaylistFeature::slotExportTrackFiles() { m_pLibrary->trackCollectionManager(), "mixxx.db.model.playlist_export")); + emit saveModelState(); pPlaylistTableModel->setTableModel(m_pPlaylistTableModel->getPlaylist()); pPlaylistTableModel->setSort(pPlaylistTableModel->fieldIndex( ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION), diff --git a/src/library/trackset/crate/cratefeature.cpp b/src/library/trackset/crate/cratefeature.cpp index d015dae3d5c..35c5335ecee 100644 --- a/src/library/trackset/crate/cratefeature.cpp +++ b/src/library/trackset/crate/cratefeature.cpp @@ -288,6 +288,7 @@ void CrateFeature::activateChild(const QModelIndex& index) { VERIFY_OR_DEBUG_ASSERT(crateId.isValid()) { return; } + emit saveModelState(); m_crateTableModel.selectCrate(crateId); emit showTrackModel(&m_crateTableModel); emit enableCoverArtDisplay(true); @@ -302,6 +303,7 @@ bool CrateFeature::activateCrate(CrateId crateId) { VERIFY_OR_DEBUG_ASSERT(index.isValid()) { return false; } + emit saveModelState(); m_lastRightClickedIndex = index; m_crateTableModel.selectCrate(crateId); emit showTrackModel(&m_crateTableModel); diff --git a/src/library/trackset/crate/cratetablemodel.cpp b/src/library/trackset/crate/cratetablemodel.cpp index e024fc36156..77a31febba2 100644 --- a/src/library/trackset/crate/cratetablemodel.cpp +++ b/src/library/trackset/crate/cratetablemodel.cpp @@ -10,10 +10,19 @@ #include "track/track.h" #include "util/db/fwdsqlquery.h" +namespace { + +const QString kModelName = "crate"; + +} // anonymous namespace + CrateTableModel::CrateTableModel( QObject* pParent, TrackCollectionManager* pTrackCollectionManager) - : TrackSetTableModel(pParent, pTrackCollectionManager, "mixxx.db.model.crate") { + : TrackSetTableModel( + pParent, + pTrackCollectionManager, + "mixxx.db.model.crate") { } void CrateTableModel::selectCrate(CrateId crateId) { @@ -178,3 +187,22 @@ void CrateTableModel::removeTracks(const QModelIndexList& indices) { select(); } + +QString CrateTableModel::modelKey(bool noSearch) const { + if (m_selectedCrate.isValid()) { + if (noSearch) { + return kModelName + QStringLiteral(":") + + QString::number(m_selectedCrate.value()); + } + return kModelName + QStringLiteral(":") + + QString::number(m_selectedCrate.value()) + + QStringLiteral("#") + + currentSearch(); + } else { + if (noSearch) { + return kModelName; + } + return kModelName + QStringLiteral("#") + + currentSearch(); + } +} diff --git a/src/library/trackset/crate/cratetablemodel.h b/src/library/trackset/crate/cratetablemodel.h index 510b2086546..0020b4e06a7 100644 --- a/src/library/trackset/crate/cratetablemodel.h +++ b/src/library/trackset/crate/cratetablemodel.h @@ -23,6 +23,7 @@ class CrateTableModel final : public TrackSetTableModel { int addTracks(const QModelIndex& index, const QList& locations) final; Capabilities getCapabilities() const final; + QString modelKey(bool noSearch) const override; private: CrateId m_selectedCrate; diff --git a/src/library/traktor/traktorfeature.cpp b/src/library/traktor/traktorfeature.cpp index 8a9c716ff6e..11ab98069b6 100644 --- a/src/library/traktor/traktorfeature.cpp +++ b/src/library/traktor/traktorfeature.cpp @@ -167,7 +167,7 @@ void TraktorFeature::activate() { //calls a slot in the sidebar model such that 'iTunes (isLoading)' is displayed. emit featureIsLoading(this, true); } - + emit saveModelState(); emit showTrackModel(m_pTraktorTableModel); emit enableCoverArtDisplay(false); } @@ -182,6 +182,7 @@ void TraktorFeature::activateChild(const QModelIndex& index) { if (!item->hasChildren()) { qDebug() << "Activate Traktor Playlist: " << item->getData().toString(); + emit saveModelState(); m_pTraktorPlaylistModel->setPlaylist(item->getData().toString()); emit showTrackModel(m_pTraktorPlaylistModel); emit enableCoverArtDisplay(false); @@ -620,6 +621,7 @@ void TraktorFeature::onTrackCollectionLoaded() { m_trackSource->buildIndex(); //m_pTraktorTableModel->select(); + emit saveModelState(); emit showTrackModel(m_pTraktorTableModel); qDebug() << "Traktor library loaded successfully"; } else { diff --git a/src/widget/wlibrary.cpp b/src/widget/wlibrary.cpp index dca7388b63c..918a707f1e3 100644 --- a/src/widget/wlibrary.cpp +++ b/src/widget/wlibrary.cpp @@ -51,14 +51,9 @@ void WLibrary::switchToView(const QString& name) { const auto lock = lockMutex(&m_mutex); //qDebug() << "WLibrary::switchToView" << name; - WTrackTableView* ttView = qobject_cast( + LibraryView* oldLibraryView = dynamic_cast( currentWidget()); - if (ttView != nullptr){ - //qDebug("trying to save position"); - ttView->saveCurrentVScrollBarPos(); - } - QWidget* widget = m_viewMap.value(name, nullptr); if (widget != nullptr) { LibraryView * lview = dynamic_cast(widget); @@ -69,17 +64,13 @@ void WLibrary::switchToView(const QString& name) { return; } if (currentWidget() != widget) { + if (oldLibraryView) { + oldLibraryView->saveCurrentViewState(); + } //qDebug() << "WLibrary::setCurrentWidget" << name; setCurrentWidget(widget); lview->onShow(); - } - - WTrackTableView* ttWidgetView = qobject_cast( - widget); - - if (ttWidgetView != nullptr) { - qDebug("trying to restore position"); - ttWidgetView->restoreCurrentVScrollBarPos(); + lview->restoreCurrentViewState(); } } } diff --git a/src/widget/wlibrarytableview.cpp b/src/widget/wlibrarytableview.cpp index 707f67b4886..ee2a847981e 100644 --- a/src/widget/wlibrarytableview.cpp +++ b/src/widget/wlibrarytableview.cpp @@ -12,14 +12,16 @@ #include "widget/wskincolor.h" #include "widget/wwidget.h" +namespace { +// number of entries in the model cache +constexpr int kModelCacheSize = 1000; +} // namespace + WLibraryTableView::WLibraryTableView(QWidget* parent, - UserSettingsPointer pConfig, - const ConfigKey& vScrollBarPosKey) + UserSettingsPointer pConfig) : QTableView(parent), m_pConfig(pConfig), - m_vScrollBarPosKey(vScrollBarPosKey) { - loadVScrollBarPosState(); - + m_modelStateCache(kModelCacheSize) { // Setup properties for table // Editing starts when clicking on an already selected item. @@ -55,35 +57,6 @@ WLibraryTableView::WLibraryTableView(QWidget* parent, WLibraryTableView::~WLibraryTableView() { } -void WLibraryTableView::loadVScrollBarPosState() { - // TODO(rryan) I'm not sure I understand the value in saving the v-scrollbar - // position across restarts of Mixxx. Now that we have different views for - // each mode, the views should just maintain their scrollbar position when - // you switch views. We should discuss this. - m_noSearchVScrollBarPos = m_pConfig->getValueString(m_vScrollBarPosKey).toInt(); -} - -void WLibraryTableView::restoreNoSearchVScrollBarPos() { - // Restore the scrollbar's position (scroll to that spot) - // when the search has been cleared - //qDebug() << "restoreNoSearchVScrollBarPos()" << m_noSearchVScrollBarPos; - updateGeometries(); - verticalScrollBar()->setValue(m_noSearchVScrollBarPos); -} - -void WLibraryTableView::saveNoSearchVScrollBarPos() { - // Save the scrollbar's position so we can return here after - // a search is cleared. - //qDebug() << "saveNoSearchVScrollBarPos()" << m_noSearchVScrollBarPos; - m_noSearchVScrollBarPos = verticalScrollBar()->value(); -} - - -void WLibraryTableView::saveVScrollBarPosState() { - //Save the vertical scrollbar position. - int scrollbarPosition = verticalScrollBar()->value(); - m_pConfig->set(m_vScrollBarPosKey, ConfigValue(scrollbarPosition)); -} void WLibraryTableView::moveSelection(int delta) { QAbstractItemModel* pModel = model(); @@ -92,42 +65,112 @@ void WLibraryTableView::moveSelection(int delta) { return; } - while(delta != 0) { - // TODO(rryan) what happens if there is nothing selected? - QModelIndex current = currentIndex(); - if(delta > 0) { - // i is positive, so we want to move the highlight down - int row = current.row(); - if (row + 1 < pModel->rowCount()) { - selectRow(row + 1); - } + while (delta != 0) { + QItemSelectionModel* currentSelection = selectionModel(); + if (currentSelection->selectedRows().length() > 0) { + if (delta > 0) { + // i is positive, so we want to move the highlight down + int row = currentSelection->selectedRows().last().row(); + if (row + 1 < pModel->rowCount()) { + selectRow(row + 1); + } else { + // we wrap around at the end of the list so it is faster to get + // to the top of the list again + selectRow(0); + } + + delta--; + } else { + // i is negative, so move down + int row = currentSelection->selectedRows().first().row(); + if (row - 1 >= 0) { + selectRow(row - 1); + } else { + selectRow(pModel->rowCount() - 1); + } - delta--; + delta++; + } } else { - // i is negative, so we want to move the highlight up - int row = current.row(); - if (row - 1 >= 0) { - selectRow(row - 1); + // no selection, so select the first or last element depending on delta + if (delta > 0) { + selectRow(0); + delta--; + } else { + selectRow(pModel->rowCount() - 1); + delta++; } - - delta++; } } } -void WLibraryTableView::saveVScrollBarPos(TrackModel* key){ - m_vScrollBarPosValues[key] = verticalScrollBar()->value(); +void WLibraryTableView::saveTrackModelState( + const QAbstractItemModel* model, const QString& key) { + //qDebug() << "saveTrackModelState:" << model << key; + VERIFY_OR_DEBUG_ASSERT(model) { + return; + } + VERIFY_OR_DEBUG_ASSERT(!key.isEmpty()) { + return; + } + ModelState* state = m_modelStateCache.take(key); + if (!state) { + state = new ModelState(); + } + + state->verticalScrollPosition = verticalScrollBar()->value(); + state->horizontalScrollPosition = horizontalScrollBar()->value(); + + state->selectedRows = selectionModel()->selectedRows(); + + const QModelIndex currIndex = selectionModel()->currentIndex(); + if (currIndex.isValid()) { + state->currentIndex = currIndex; + } else { + state->currentIndex = QModelIndex(); + } + + m_modelStateCache.insert(key, state, 1); } -void WLibraryTableView::restoreVScrollBarPos(TrackModel* key){ - updateGeometries(); +void WLibraryTableView::restoreTrackModelState( + const QAbstractItemModel* model, const QString& key) { + //qDebug() << "restoreTrackModelState:" << model << key; + //qDebug() << m_modelStateCache.keys(); + if (model == nullptr) { + return; + } - if (m_vScrollBarPosValues.contains(key)){ - verticalScrollBar()->setValue(m_vScrollBarPosValues[key]); - }else{ - m_vScrollBarPosValues[key] = 0; + ModelState* state = m_modelStateCache.take(key); + if (!state) { + // No previous state for model key, + // reset scroll bars and current index verticalScrollBar()->setValue(0); + horizontalScrollBar()->setValue(0); + setCurrentIndex(QModelIndex()); + return; } + + verticalScrollBar()->setValue(state->verticalScrollPosition); + horizontalScrollBar()->setValue(state->horizontalScrollPosition); + + auto selection = selectionModel(); + selection->clearSelection(); + QModelIndexList selectedRows = state->selectedRows; + if (!selectedRows.isEmpty()) { + for (auto index : qAsConst(selectedRows)) { + selection->select(index, + QItemSelectionModel::Select | QItemSelectionModel::Rows); + } + } + + QModelIndex currIndex = state->currentIndex; + if (currIndex.isValid()) { + selection->setCurrentIndex(currIndex, QItemSelectionModel::NoUpdate); + } + + // reinsert the state into the cache + m_modelStateCache.insert(key, state, 1); } void WLibraryTableView::setTrackTableFont(const QFont& font) { @@ -160,6 +203,24 @@ void WLibraryTableView::setSelectedClick(bool enable) { } } +void WLibraryTableView::saveCurrentViewState() { + const QAbstractItemModel* currentModel = model(); + QString key = getModelStateKey(); + if (!currentModel || key.isEmpty()) { + return; + } + saveTrackModelState(currentModel, key); +} + +void WLibraryTableView::restoreCurrentViewState() { + const QAbstractItemModel* currentModel = model(); + QString key = getModelStateKey(); + if (!currentModel || key.isEmpty()) { + return; + } + restoreTrackModelState(currentModel, key); +} + void WLibraryTableView::focusInEvent(QFocusEvent* event) { QTableView::focusInEvent(event); diff --git a/src/widget/wlibrarytableview.h b/src/widget/wlibrarytableview.h index 89d4f1bc4ac..6fde3e9e25e 100644 --- a/src/widget/wlibrarytableview.h +++ b/src/widget/wlibrarytableview.h @@ -1,6 +1,8 @@ #pragma once +#include #include +#include #include #include @@ -13,25 +15,32 @@ class TrackModel; class WLibraryTableView : public QTableView, public virtual LibraryView { Q_OBJECT + struct ModelState { + int horizontalScrollPosition; + int verticalScrollPosition; + QModelIndexList selectedRows; + QModelIndex currentIndex; + }; + public: WLibraryTableView(QWidget* parent, - UserSettingsPointer pConfig, - const ConfigKey& vScrollBarPosKey); + UserSettingsPointer pConfig); ~WLibraryTableView() override; void moveSelection(int delta) override; - /** - * Saves current position of scrollbar using string key - * can be any value but should invariant for model - * @param key unique for trackmodel - */ - void saveVScrollBarPos(TrackModel* key); - /** - * Finds scrollbar value associated with model by given key and restores it - * @param key unique for trackmodel - */ - void restoreVScrollBarPos(TrackModel* key); + /// @brief saveTrackModelState function saves current positions of scrollbars, + /// current item selection and current index in a QCache using a unique + /// string key - can be any value but should invariant for model + /// @param key unique for trackmodel + void saveTrackModelState(const QAbstractItemModel* model, const QString& key); + /// @brief restoreTrackModelState function finds scrollbar positions, + /// item selection and current index values associated with model by given + /// key and restores it + /// @param key unique for trackmodel + void restoreTrackModelState(const QAbstractItemModel* model, const QString& key); + void saveCurrentViewState() override; + void restoreCurrentViewState() override; signals: void loadTrack(TrackPointer pTrack); @@ -47,20 +56,9 @@ class WLibraryTableView : public QTableView, public virtual LibraryView { protected: void focusInEvent(QFocusEvent* event) override; - - void saveNoSearchVScrollBarPos(); - void restoreNoSearchVScrollBarPos(); + virtual QString getModelStateKey() const = 0; private: - void loadVScrollBarPosState(); - void saveVScrollBarPosState(); - const UserSettingsPointer m_pConfig; - const ConfigKey m_vScrollBarPosKey; - - QMap m_vScrollBarPosValues; - - // The position of the vertical scrollbar slider, eg. before a search is - // executed - int m_noSearchVScrollBarPos; + QCache m_modelStateCache; }; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 1a046d0dd39..b9f558f483b 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -50,9 +50,7 @@ WTrackTableView::WTrackTableView(QWidget* parent, Library* pLibrary, double backgroundColorOpacity, bool sorting) - : WLibraryTableView(parent, - pConfig, - kVScrollBarPosConfigKey), + : WLibraryTableView(parent, pConfig), m_pConfig(pConfig), m_pLibrary(pLibrary), m_backgroundColorOpacity(backgroundColorOpacity), @@ -152,33 +150,32 @@ void WTrackTableView::slotGuiTick50ms(double /*unused*/) { } // slot -void WTrackTableView::loadTrackModel(QAbstractItemModel* model) { +void WTrackTableView::loadTrackModel(QAbstractItemModel* model, bool restoreState) { qDebug() << "WTrackTableView::loadTrackModel()" << model; - TrackModel* trackModel = dynamic_cast(model); - VERIFY_OR_DEBUG_ASSERT(model) { return; } + TrackModel* trackModel = dynamic_cast(model); + VERIFY_OR_DEBUG_ASSERT(trackModel) { return; } - // If the model has not changed - // there's no need to exchange the headers - // this will cause a small GUI freeze + // If the model has not changed there's no need to exchange the headers + // which would cause a small GUI freeze if (getTrackModel() == trackModel) { // Re-sort the table even if the track model is the same. This triggers // a select() if the table is dirty. doSortByColumn(horizontalHeader()->sortIndicatorSection(), horizontalHeader()->sortIndicatorOrder()); + + if (restoreState) { + restoreCurrentViewState(); + } return; } - // saving current vertical bar position - // using address of track model as key - saveVScrollBarPos(getTrackModel()); - setVisible(false); // Save the previous track model's header state @@ -327,9 +324,10 @@ void WTrackTableView::loadTrackModel(QAbstractItemModel* model) { setVisible(true); - restoreVScrollBarPos(trackModel); - // restoring scrollBar position using model pointer as key - // scrollbar positions with respect to different models are backed by map + // trigger restoring scrollBar position, selection etc. + if (restoreState) { + restoreCurrentViewState(); + } initTrackMenu(); } @@ -476,15 +474,9 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) { void WTrackTableView::onSearch(const QString& text) { TrackModel* trackModel = getTrackModel(); if (trackModel) { - bool searchWasEmpty = false; - if (trackModel->currentSearch().isEmpty()) { - saveNoSearchVScrollBarPos(); - searchWasEmpty = true; - } + saveCurrentViewState(); trackModel->search(text); - if (!searchWasEmpty && text.isEmpty()) { - restoreNoSearchVScrollBarPos(); - } + restoreCurrentViewState(); } } @@ -1086,12 +1078,13 @@ void WTrackTableView::setFocus() { QWidget::setFocus(); } -void WTrackTableView::saveCurrentVScrollBarPos() { - saveVScrollBarPos(getTrackModel()); -} - -void WTrackTableView::restoreCurrentVScrollBarPos() { - restoreVScrollBarPos(getTrackModel()); +QString WTrackTableView::getModelStateKey() const { + TrackModel* trackModel = getTrackModel(); + if (trackModel) { + bool noSearch = trackModel->currentSearch().trimmed().isEmpty(); + return trackModel->modelKey(noSearch); + } + return QString(); } void WTrackTableView::keyNotationChanged() { diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 9a240bd13b6..0ab91e927b5 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -42,8 +42,6 @@ class WTrackTableView : public WLibraryTableView { TrackModel::SortColumnId getColumnIdFromCurrentIndex() override; QList getSelectedTrackIds() const; void setSelectedTracks(const QList& tracks); - void saveCurrentVScrollBarPos(); - void restoreCurrentVScrollBarPos(); double getBackgroundColorOpacity() const { return m_backgroundColorOpacity; @@ -58,7 +56,7 @@ class WTrackTableView : public WLibraryTableView { void trackTableFocusChange(FocusWidget newFocusWidget); public slots: - void loadTrackModel(QAbstractItemModel* model); + void loadTrackModel(QAbstractItemModel* model, bool restoreState = false); void slotMouseDoubleClicked(const QModelIndex &); void slotUnhide(); void slotPurge(); @@ -66,6 +64,12 @@ class WTrackTableView : public WLibraryTableView { void slotAddToAutoDJBottom() override; void slotAddToAutoDJTop() override; void slotAddToAutoDJReplace() override; + void slotSaveCurrentViewState() { + saveCurrentViewState(); + }; + void slotRestoreCurrentViewState() { + restoreCurrentViewState(); + }; protected: void focusInEvent(QFocusEvent* event) override; @@ -83,6 +87,9 @@ class WTrackTableView : public WLibraryTableView { void slotSortingChanged(int headerSection, Qt::SortOrder order); void keyNotationChanged(); + protected: + QString getModelStateKey() const override; + private: void addToAutoDJ(PlaylistDAO::AutoDJSendLoc loc); void dragMoveEvent(QDragMoveEvent * event) override;