Permalink
Browse files

qtui: Fix slow searching on large playlists. Closes: #819.

  • Loading branch information...
jlindgren90 committed Sep 5, 2018
1 parent 43db691 commit 9d162207ef01c5972e4bb718d390c494f0ad0241
Showing with 42 additions and 17 deletions.
  1. +41 −17 src/qtui/playlist-qt.cc
  2. +1 −0 src/qtui/playlist-qt.h
@@ -89,6 +89,31 @@ int PlaylistWidget::indexToRow (const QModelIndex & index)
return proxyModel->mapToSource (index).row ();
}

QModelIndex PlaylistWidget::visibleIndexNear (int row)
{
QModelIndex index = rowToIndex (row);
if (index.isValid ())
return index;

int n_entries = m_playlist.n_entries ();

for (int r = row + 1; r < n_entries; r ++)
{
index = rowToIndex (r);
if (index.isValid ())
return index;
}

for (int r = row - 1; r >= 0; r --)
{
index = rowToIndex (r);
if (index.isValid ())
return index;
}

return index;
}

void PlaylistWidget::contextMenuEvent (QContextMenuEvent * event)
{
if (contextMenu)
@@ -379,33 +404,32 @@ void PlaylistWidget::playCurrentIndex ()

void PlaylistWidget::setFilter (const char * text)
{
// Save the current focus before filtering
int focus = m_playlist.get_focus ();

// Empty the model before updating the filter. This prevents Qt from
// performing a series of "rows added" or "rows deleted" updates, which can
// be very slow (worst case O(N^2) complexity) on a large playlist.
model->entriesRemoved (0, model->rowCount ());

// Update the filter
proxyModel->setFilter (text);

int focus = m_playlist.get_focus ();
QModelIndex index;
// Repopulate the model
model->entriesAdded (0, m_playlist.n_entries ());

// If there was a valid focus before filtering, Qt updates it for us via
// currentChanged(). If not, we will set focus on the first visible row.
// If the previously focused row is no longer visible with the new filter,
// try to find a nearby one that is, and focus it.
auto index = visibleIndexNear (focus);

if (focus >= 0)
index = rowToIndex (focus);
else
if (index.isValid ())
{
if (! proxyModel->rowCount ())
return;

index = proxyModel->index (0, 0);
focus = indexToRow (index);
m_playlist.set_focus (focus);
}

if (! m_playlist.entry_selected (focus))
{
m_playlist.select_all (false);
m_playlist.select_entry (focus, true);
scrollTo (index);
}

scrollTo (index);
}

void PlaylistWidget::setFirstVisibleColumn (int col)
@@ -66,6 +66,7 @@ class PlaylistWidget : public QTreeView

QModelIndex rowToIndex (int row);
int indexToRow (const QModelIndex & index);
QModelIndex visibleIndexNear (int row);

void getSelectedRanges (int rowsBefore, int rowsAfter,
QItemSelection & selected, QItemSelection & deselected);

0 comments on commit 9d16220

Please sign in to comment.