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;
|
||||
}
|
||||
|
||||
reset();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void LibraryModel::BeginReset() {
|
||||
beginResetModel();
|
||||
delete root_;
|
||||
song_nodes_.clear();
|
||||
container_nodes_[0].clear();
|
||||
|
@ -706,7 +707,7 @@ void LibraryModel::Reset() {
|
|||
// Populate top level
|
||||
LazyPopulate(root_, false);
|
||||
|
||||
reset();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void LibraryModel::InitQuery(GroupBy type, LibraryQuery* q) {
|
||||
|
|
|
@ -185,6 +185,111 @@ LibraryView::LibraryView(QWidget* parent)
|
|||
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() {
|
||||
QSettings s;
|
||||
s.beginGroup(kSettingsGroup);
|
||||
|
|
|
@ -73,6 +73,9 @@ class LibraryView : public AutoExpandingTreeView {
|
|||
|
||||
void FilterReturnPressed();
|
||||
|
||||
void SaveFocus();
|
||||
void RestoreFocus();
|
||||
|
||||
signals:
|
||||
void ShowConfigDialog();
|
||||
|
||||
|
@ -107,6 +110,8 @@ class LibraryView : public AutoExpandingTreeView {
|
|||
private:
|
||||
void RecheckIsEmpty();
|
||||
void ShowInVarious(bool on);
|
||||
bool RestoreLevelFocus(const QModelIndex& parent = QModelIndex());
|
||||
void SaveContainerPath(const QModelIndex& child);
|
||||
|
||||
private:
|
||||
Application* app_;
|
||||
|
@ -139,6 +144,11 @@ class LibraryView : public AutoExpandingTreeView {
|
|||
boost::scoped_ptr<EditTagDialog> edit_tag_dialog_;
|
||||
|
||||
bool is_in_keyboard_search_;
|
||||
|
||||
// Save focus
|
||||
Song last_selected_song_;
|
||||
QString last_selected_container_;
|
||||
QSet<QString> last_selected_path_;
|
||||
};
|
||||
|
||||
#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(ShowConfigDialog()), SLOT(ShowLibraryConfig()));
|
||||
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(ResumeLibraryWatchers()), app_->library(), SLOT(ResumeWatcher()));
|
||||
|
|
Loading…
Reference in New Issue