Preserve the current song in the library view when filtering. Fixes issue 2936
This commit is contained in:
parent
1aec4a4c7f
commit
682acad53f
|
@ -671,10 +671,11 @@ void LibraryModel::ResetAsyncQueryFinished() {
|
||||||
init_task_id_ = -1;
|
init_task_id_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
reset();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibraryModel::BeginReset() {
|
void LibraryModel::BeginReset() {
|
||||||
|
beginResetModel();
|
||||||
delete root_;
|
delete root_;
|
||||||
song_nodes_.clear();
|
song_nodes_.clear();
|
||||||
container_nodes_[0].clear();
|
container_nodes_[0].clear();
|
||||||
|
@ -706,7 +707,7 @@ void LibraryModel::Reset() {
|
||||||
// Populate top level
|
// Populate top level
|
||||||
LazyPopulate(root_, false);
|
LazyPopulate(root_, false);
|
||||||
|
|
||||||
reset();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibraryModel::InitQuery(GroupBy type, LibraryQuery* q) {
|
void LibraryModel::InitQuery(GroupBy type, LibraryQuery* q) {
|
||||||
|
|
|
@ -185,6 +185,111 @@ LibraryView::LibraryView(QWidget* parent)
|
||||||
LibraryView::~LibraryView() {
|
LibraryView::~LibraryView() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LibraryView::SaveFocus() {
|
||||||
|
QModelIndex current = currentIndex();
|
||||||
|
QVariant type = model()->data(current, LibraryModel::Role_Type);
|
||||||
|
if (!type.isValid() || !(type.toInt() == LibraryItem::Type_Song ||
|
||||||
|
type.toInt() == LibraryItem::Type_Container ||
|
||||||
|
type.toInt() == LibraryItem::Type_Divider)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_selected_path_.clear();
|
||||||
|
last_selected_song_ = Song();
|
||||||
|
last_selected_container_ = QString();
|
||||||
|
|
||||||
|
switch (type.toInt()) {
|
||||||
|
case LibraryItem::Type_Song: {
|
||||||
|
QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())
|
||||||
|
->mapToSource(current);
|
||||||
|
SongList songs = app_->library_model()->GetChildSongs(index);
|
||||||
|
if (!songs.isEmpty()) {
|
||||||
|
last_selected_song_ = songs.last();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LibraryItem::Type_Container:
|
||||||
|
case LibraryItem::Type_Divider: {
|
||||||
|
QString text = model()->data(current, LibraryModel::Role_SortText).toString();
|
||||||
|
last_selected_container_ = text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveContainerPath(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibraryView::SaveContainerPath(const QModelIndex& child) {
|
||||||
|
QModelIndex current = model()->parent(child);
|
||||||
|
QVariant type = model()->data(current, LibraryModel::Role_Type);
|
||||||
|
if (!type.isValid() || !(type.toInt() == LibraryItem::Type_Container ||
|
||||||
|
type.toInt() == LibraryItem::Type_Divider)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString text = model()->data(current, LibraryModel::Role_SortText).toString();
|
||||||
|
last_selected_path_ << text;
|
||||||
|
SaveContainerPath(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibraryView::RestoreFocus() {
|
||||||
|
if (last_selected_container_.isEmpty() && last_selected_song_.url().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RestoreLevelFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibraryView::RestoreLevelFocus(const QModelIndex& parent) {
|
||||||
|
if (model()->canFetchMore(parent)) {
|
||||||
|
model()->fetchMore(parent);
|
||||||
|
}
|
||||||
|
int rows = model()->rowCount(parent);
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
QModelIndex current = model()->index(i, 0, parent);
|
||||||
|
QVariant type = model()->data(current, LibraryModel::Role_Type);
|
||||||
|
switch (type.toInt()) {
|
||||||
|
case LibraryItem::Type_Song:
|
||||||
|
if (!last_selected_song_.url().isEmpty()) {
|
||||||
|
QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())
|
||||||
|
->mapToSource(current);
|
||||||
|
SongList songs = app_->library_model()->GetChildSongs(index);
|
||||||
|
foreach (const Song& song, songs) {
|
||||||
|
if (song == last_selected_song_) {
|
||||||
|
setCurrentIndex(current);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LibraryItem::Type_Container:
|
||||||
|
case LibraryItem::Type_Divider: {
|
||||||
|
QString text = model()->data(current, LibraryModel::Role_SortText).toString();
|
||||||
|
if (!last_selected_container_.isEmpty() && last_selected_container_ == text) {
|
||||||
|
emit expand(current);
|
||||||
|
setCurrentIndex(current);
|
||||||
|
return true;
|
||||||
|
} else if (last_selected_path_.contains(text)) {
|
||||||
|
emit expand(current);
|
||||||
|
// If a selected container or song were not found, we've got into a wrong subtree
|
||||||
|
// (happens with "unknown" all the time)
|
||||||
|
if (!RestoreLevelFocus(current)) {
|
||||||
|
emit collapse(current);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void LibraryView::ReloadSettings() {
|
void LibraryView::ReloadSettings() {
|
||||||
QSettings s;
|
QSettings s;
|
||||||
s.beginGroup(kSettingsGroup);
|
s.beginGroup(kSettingsGroup);
|
||||||
|
|
|
@ -73,6 +73,9 @@ class LibraryView : public AutoExpandingTreeView {
|
||||||
|
|
||||||
void FilterReturnPressed();
|
void FilterReturnPressed();
|
||||||
|
|
||||||
|
void SaveFocus();
|
||||||
|
void RestoreFocus();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ShowConfigDialog();
|
void ShowConfigDialog();
|
||||||
|
|
||||||
|
@ -107,6 +110,8 @@ class LibraryView : public AutoExpandingTreeView {
|
||||||
private:
|
private:
|
||||||
void RecheckIsEmpty();
|
void RecheckIsEmpty();
|
||||||
void ShowInVarious(bool on);
|
void ShowInVarious(bool on);
|
||||||
|
bool RestoreLevelFocus(const QModelIndex& parent = QModelIndex());
|
||||||
|
void SaveContainerPath(const QModelIndex& child);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Application* app_;
|
Application* app_;
|
||||||
|
@ -139,6 +144,11 @@ class LibraryView : public AutoExpandingTreeView {
|
||||||
boost::scoped_ptr<EditTagDialog> edit_tag_dialog_;
|
boost::scoped_ptr<EditTagDialog> edit_tag_dialog_;
|
||||||
|
|
||||||
bool is_in_keyboard_search_;
|
bool is_in_keyboard_search_;
|
||||||
|
|
||||||
|
// Save focus
|
||||||
|
Song last_selected_song_;
|
||||||
|
QString last_selected_container_;
|
||||||
|
QSet<QString> last_selected_path_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LIBRARYVIEW_H
|
#endif // LIBRARYVIEW_H
|
||||||
|
|
|
@ -433,6 +433,8 @@ MainWindow::MainWindow(Application* app,
|
||||||
connect(library_view_->view(), SIGNAL(AddToPlaylistSignal(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
connect(library_view_->view(), SIGNAL(AddToPlaylistSignal(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
||||||
connect(library_view_->view(), SIGNAL(ShowConfigDialog()), SLOT(ShowLibraryConfig()));
|
connect(library_view_->view(), SIGNAL(ShowConfigDialog()), SLOT(ShowLibraryConfig()));
|
||||||
connect(app_->library_model(), SIGNAL(TotalSongCountUpdated(int)), library_view_->view(), SLOT(TotalSongCountUpdated(int)));
|
connect(app_->library_model(), SIGNAL(TotalSongCountUpdated(int)), library_view_->view(), SLOT(TotalSongCountUpdated(int)));
|
||||||
|
connect(app_->library_model(), SIGNAL(modelAboutToBeReset()), library_view_->view(), SLOT(SaveFocus()));
|
||||||
|
connect(app_->library_model(), SIGNAL(modelReset()), library_view_->view(), SLOT(RestoreFocus()));
|
||||||
|
|
||||||
connect(app_->task_manager(), SIGNAL(PauseLibraryWatchers()), app_->library(), SLOT(PauseWatcher()));
|
connect(app_->task_manager(), SIGNAL(PauseLibraryWatchers()), app_->library(), SLOT(PauseWatcher()));
|
||||||
connect(app_->task_manager(), SIGNAL(ResumeLibraryWatchers()), app_->library(), SLOT(ResumeWatcher()));
|
connect(app_->task_manager(), SIGNAL(ResumeLibraryWatchers()), app_->library(), SLOT(ResumeWatcher()));
|
||||||
|
|
Loading…
Reference in New Issue