Preserve the current song in the library view when filtering. Fixes issue 2936

This commit is contained in:
Ilya Kasnacheev 2012-08-26 13:36:44 +01:00 committed by David Sansome
parent 1aec4a4c7f
commit 682acad53f
4 changed files with 120 additions and 2 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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()));