Split some bits of GlobalSearchView into a GlobalSearchModel
This commit is contained in:
parent
c9745bca5d
commit
97b4298002
|
@ -139,6 +139,7 @@ set(SOURCES
|
|||
globalsearch/digitallyimportedsearchprovider.cpp
|
||||
globalsearch/globalsearch.cpp
|
||||
globalsearch/globalsearchitemdelegate.cpp
|
||||
globalsearch/globalsearchmodel.cpp
|
||||
globalsearch/globalsearchsettingspage.cpp
|
||||
globalsearch/globalsearchsortmodel.cpp
|
||||
globalsearch/globalsearchview.cpp
|
||||
|
@ -414,6 +415,7 @@ set(HEADERS
|
|||
engines/gstelementdeleter.h
|
||||
|
||||
globalsearch/globalsearch.h
|
||||
globalsearch/globalsearchmodel.h
|
||||
globalsearch/globalsearchsettingspage.h
|
||||
globalsearch/globalsearchview.h
|
||||
globalsearch/groovesharksearchprovider.h
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/* This file is part of Clementine.
|
||||
Copyright 2012, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "globalsearchmodel.h"
|
||||
|
||||
GlobalSearchModel::GlobalSearchModel(QObject* parent)
|
||||
: QStandardItemModel(parent),
|
||||
use_pretty_covers_(true),
|
||||
artist_icon_(":/icons/22x22/x-clementine-artist.png"),
|
||||
album_icon_(":/icons/22x22/x-clementine-album.png")
|
||||
{
|
||||
group_by_[0] = LibraryModel::GroupBy_Artist;
|
||||
group_by_[1] = LibraryModel::GroupBy_Album;
|
||||
group_by_[2] = LibraryModel::GroupBy_None;
|
||||
|
||||
no_cover_icon_ = QPixmap(":nocover.png").scaled(
|
||||
LibraryModel::kPrettyCoverSize, LibraryModel::kPrettyCoverSize,
|
||||
Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
void GlobalSearchModel::AddResults(const SearchProvider::ResultList& results) {
|
||||
int sort_index = 0;
|
||||
|
||||
// Create a divider for this provider if we haven't seen it before.
|
||||
SearchProvider* provider = results.first().provider_;
|
||||
|
||||
if (!provider_sort_indices_.contains(provider)) {
|
||||
// TODO: Check if the user has configured a sort order for this provider.
|
||||
sort_index = next_provider_sort_index_ ++;
|
||||
|
||||
QStandardItem* divider = new QStandardItem(provider->icon(), provider->name());
|
||||
divider->setData(true, LibraryModel::Role_IsDivider);
|
||||
divider->setData(sort_index, Role_ProviderIndex);
|
||||
divider->setFlags(Qt::ItemIsEnabled);
|
||||
appendRow(divider);
|
||||
|
||||
provider_sort_indices_[provider] = sort_index;
|
||||
} else {
|
||||
sort_index = provider_sort_indices_[provider];
|
||||
}
|
||||
|
||||
foreach (const SearchProvider::Result& result, results) {
|
||||
QStandardItem* parent = invisibleRootItem();
|
||||
|
||||
// Find (or create) the container nodes for this result if we can.
|
||||
if (result.group_automatically_) {
|
||||
ContainerKey key;
|
||||
key.provider_index_ = sort_index;
|
||||
|
||||
parent = BuildContainers(result.metadata_, parent, &key);
|
||||
}
|
||||
|
||||
// Create the item
|
||||
QStandardItem* item = new QStandardItem(result.metadata_.title());
|
||||
item->setData(QVariant::fromValue(result), Role_Result);
|
||||
item->setData(sort_index, Role_ProviderIndex);
|
||||
|
||||
parent->appendRow(item);
|
||||
}
|
||||
}
|
||||
|
||||
QStandardItem* GlobalSearchModel::BuildContainers(
|
||||
const Song& s, QStandardItem* parent, ContainerKey* key, int level) {
|
||||
if (level >= 3) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool has_artist_icon = false;
|
||||
bool has_album_icon = false;
|
||||
QString display_text;
|
||||
QString sort_text;
|
||||
int year = 0;
|
||||
|
||||
switch (group_by_[level]) {
|
||||
case LibraryModel::GroupBy_Artist:
|
||||
display_text = LibraryModel::TextOrUnknown(s.artist());
|
||||
sort_text = LibraryModel::SortTextForArtist(s.artist());
|
||||
has_artist_icon = true;
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_YearAlbum:
|
||||
year = qMax(0, s.year());
|
||||
display_text = LibraryModel::PrettyYearAlbum(year, s.album());
|
||||
sort_text = LibraryModel::SortTextForYear(year) + s.album();
|
||||
has_album_icon = true;
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_Year:
|
||||
year = qMax(0, s.year());
|
||||
display_text = QString::number(year);
|
||||
sort_text = LibraryModel::SortTextForYear(year) + " ";
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_Composer: display_text = s.composer();
|
||||
case LibraryModel::GroupBy_Genre: if (display_text.isNull()) display_text = s.genre();
|
||||
case LibraryModel::GroupBy_Album: if (display_text.isNull()) display_text = s.album();
|
||||
case LibraryModel::GroupBy_AlbumArtist: if (display_text.isNull()) display_text = s.effective_albumartist();
|
||||
display_text = LibraryModel::TextOrUnknown(display_text);
|
||||
sort_text = LibraryModel::SortTextForArtist(display_text);
|
||||
has_album_icon = true;
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_FileType:
|
||||
display_text = s.TextForFiletype();
|
||||
sort_text = display_text;
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_None:
|
||||
return parent;
|
||||
}
|
||||
|
||||
// Find a container for this level
|
||||
key->group_[level] = display_text;
|
||||
QStandardItem* container = containers_[*key];
|
||||
if (!container) {
|
||||
container = new QStandardItem(display_text);
|
||||
container->setData(key->provider_index_, Role_ProviderIndex);
|
||||
container->setData(sort_text, LibraryModel::Role_SortText);
|
||||
container->setData(group_by_[level], LibraryModel::Role_ContainerType);
|
||||
|
||||
if (has_artist_icon) {
|
||||
container->setIcon(artist_icon_);
|
||||
} else if (has_album_icon) {
|
||||
if (use_pretty_covers_) {
|
||||
container->setData(no_cover_icon_, Qt::DecorationRole);
|
||||
} else {
|
||||
container->setIcon(album_icon_);
|
||||
}
|
||||
}
|
||||
|
||||
parent->appendRow(container);
|
||||
containers_[*key] = container;
|
||||
}
|
||||
|
||||
// Create the container for the next level.
|
||||
return BuildContainers(s, container, key, level + 1);
|
||||
}
|
||||
|
||||
void GlobalSearchModel::Clear() {
|
||||
provider_sort_indices_.clear();
|
||||
containers_.clear();
|
||||
next_provider_sort_index_ = 1000;
|
||||
clear();
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/* This file is part of Clementine.
|
||||
Copyright 2012, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GLOBALSEARCHMODEL_H
|
||||
#define GLOBALSEARCHMODEL_H
|
||||
|
||||
#include "searchprovider.h"
|
||||
#include "library/librarymodel.h"
|
||||
|
||||
#include <QStandardItemModel>
|
||||
|
||||
class GlobalSearchModel : public QStandardItemModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GlobalSearchModel(QObject* parent = 0);
|
||||
|
||||
enum Role {
|
||||
Role_Result = LibraryModel::LastRole,
|
||||
Role_LazyLoadingArt,
|
||||
Role_ProviderIndex,
|
||||
|
||||
LastRole
|
||||
};
|
||||
|
||||
struct ContainerKey {
|
||||
int provider_index_;
|
||||
QString group_[3];
|
||||
};
|
||||
|
||||
void set_use_pretty_covers(bool pretty) { use_pretty_covers_ = pretty; }
|
||||
|
||||
void Clear();
|
||||
|
||||
public slots:
|
||||
void AddResults(const SearchProvider::ResultList& results);
|
||||
|
||||
private:
|
||||
QStandardItem* BuildContainers(const Song& metadata, QStandardItem* parent,
|
||||
ContainerKey* key, int level = 0);
|
||||
|
||||
private:
|
||||
LibraryModel::Grouping group_by_;
|
||||
|
||||
QMap<SearchProvider*, int> provider_sort_indices_;
|
||||
int next_provider_sort_index_;
|
||||
QMap<ContainerKey, QStandardItem*> containers_;
|
||||
|
||||
bool use_pretty_covers_;
|
||||
QIcon artist_icon_;
|
||||
QIcon album_icon_;
|
||||
QPixmap no_cover_icon_;
|
||||
};
|
||||
|
||||
inline uint qHash(const GlobalSearchModel::ContainerKey& key) {
|
||||
return qHash(key.provider_index_)
|
||||
^ qHash(key.group_[0])
|
||||
^ qHash(key.group_[1])
|
||||
^ qHash(key.group_[2]);
|
||||
}
|
||||
|
||||
inline bool operator <(const GlobalSearchModel::ContainerKey& left,
|
||||
const GlobalSearchModel::ContainerKey& right) {
|
||||
#define CMP(field) \
|
||||
if (left.field < right.field) return true; \
|
||||
if (left.field > right.field) return false
|
||||
|
||||
CMP(provider_index_);
|
||||
CMP(group_[0]);
|
||||
CMP(group_[1]);
|
||||
CMP(group_[2]);
|
||||
return false;
|
||||
|
||||
#undef CMP
|
||||
}
|
||||
|
||||
#endif // GLOBALSEARCHMODEL_H
|
|
@ -15,8 +15,8 @@
|
|||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "globalsearchmodel.h"
|
||||
#include "globalsearchsortmodel.h"
|
||||
#include "globalsearchview.h"
|
||||
#include "searchprovider.h"
|
||||
#include "core/logging.h"
|
||||
|
||||
|
@ -27,8 +27,8 @@ GlobalSearchSortModel::GlobalSearchSortModel(QObject* parent)
|
|||
|
||||
bool GlobalSearchSortModel::lessThan(const QModelIndex& left, const QModelIndex& right) const {
|
||||
// Compare the provider sort index first.
|
||||
const int index_left = left.data(GlobalSearchView::Role_ProviderIndex).toInt();
|
||||
const int index_right = right.data(GlobalSearchView::Role_ProviderIndex).toInt();
|
||||
const int index_left = left.data(GlobalSearchModel::Role_ProviderIndex).toInt();
|
||||
const int index_right = right.data(GlobalSearchModel::Role_ProviderIndex).toInt();
|
||||
if (index_left < index_right) return true;
|
||||
if (index_left > index_right) return false;
|
||||
|
||||
|
@ -50,9 +50,9 @@ bool GlobalSearchSortModel::lessThan(const QModelIndex& left, const QModelIndex&
|
|||
}
|
||||
|
||||
// Otherwise we're comparing songs. Sort by disc, track, then title.
|
||||
const SearchProvider::Result r1 = left.data(GlobalSearchView::Role_Result)
|
||||
const SearchProvider::Result r1 = left.data(GlobalSearchModel::Role_Result)
|
||||
.value<SearchProvider::Result>();
|
||||
const SearchProvider::Result r2 = right.data(GlobalSearchView::Role_Result)
|
||||
const SearchProvider::Result r2 = right.data(GlobalSearchModel::Role_Result)
|
||||
.value<SearchProvider::Result>();
|
||||
|
||||
#define CompareInt(field) \
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "globalsearch.h"
|
||||
#include "globalsearchitemdelegate.h"
|
||||
#include "globalsearchmodel.h"
|
||||
#include "globalsearchsortmodel.h"
|
||||
#include "globalsearchview.h"
|
||||
#include "searchprovider.h"
|
||||
|
@ -39,15 +40,13 @@ GlobalSearchView::GlobalSearchView(Application* app, QWidget* parent)
|
|||
engine_(app_->global_search()),
|
||||
ui_(new Ui_GlobalSearchView),
|
||||
last_search_id_(0),
|
||||
front_model_(new QStandardItemModel(this)),
|
||||
back_model_(new QStandardItemModel(this)),
|
||||
front_model_(new GlobalSearchModel(this)),
|
||||
back_model_(new GlobalSearchModel(this)),
|
||||
current_model_(front_model_),
|
||||
front_proxy_(new GlobalSearchSortModel(this)),
|
||||
back_proxy_(new GlobalSearchSortModel(this)),
|
||||
current_proxy_(front_proxy_),
|
||||
swap_models_timer_(new QTimer(this)),
|
||||
artist_icon_(":/icons/22x22/x-clementine-artist.png"),
|
||||
album_icon_(":/icons/22x22/x-clementine-album.png")
|
||||
swap_models_timer_(new QTimer(this))
|
||||
{
|
||||
ui_->setupUi(this);
|
||||
|
||||
|
@ -81,14 +80,6 @@ GlobalSearchView::GlobalSearchView(Application* app, QWidget* parent)
|
|||
help_font.setBold(true);
|
||||
ui_->help_text->setFont(help_font);
|
||||
|
||||
group_by_[0] = LibraryModel::GroupBy_Artist;
|
||||
group_by_[1] = LibraryModel::GroupBy_Album;
|
||||
group_by_[2] = LibraryModel::GroupBy_None;
|
||||
|
||||
no_cover_icon_ = QPixmap(":nocover.png").scaled(
|
||||
LibraryModel::kPrettyCoverSize, LibraryModel::kPrettyCoverSize,
|
||||
Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
// Set up the sorting proxy model
|
||||
front_proxy_->setSourceModel(front_model_);
|
||||
front_proxy_->setDynamicSortFilter(true);
|
||||
|
@ -149,6 +140,11 @@ void GlobalSearchView::ReloadSettings() {
|
|||
}
|
||||
|
||||
ui_->disabled_label->setVisible(any_disabled);
|
||||
|
||||
// Update models to use pretty covers.
|
||||
const bool pretty = app_->library_model()->use_pretty_covers();
|
||||
front_model_->set_use_pretty_covers(pretty);
|
||||
back_model_->set_use_pretty_covers(pretty);
|
||||
}
|
||||
|
||||
void GlobalSearchView::StartSearch(const QString& query) {
|
||||
|
@ -164,10 +160,7 @@ void GlobalSearchView::TextEdited(const QString& text) {
|
|||
const QString trimmed(text.trimmed());
|
||||
|
||||
// Add results to the back model, switch models after some delay.
|
||||
provider_sort_indices_.clear();
|
||||
containers_.clear();
|
||||
next_provider_sort_index_ = 1000;
|
||||
back_model_->clear();
|
||||
back_model_->Clear();
|
||||
current_model_ = back_model_;
|
||||
current_proxy_ = back_proxy_;
|
||||
swap_models_timer_->start();
|
||||
|
@ -186,121 +179,7 @@ void GlobalSearchView::AddResults(int id, const SearchProvider::ResultList& resu
|
|||
if (id != last_search_id_ || results.isEmpty())
|
||||
return;
|
||||
|
||||
int sort_index = 0;
|
||||
|
||||
// Create a divider for this provider if we haven't seen it before.
|
||||
SearchProvider* provider = results.first().provider_;
|
||||
|
||||
if (!provider_sort_indices_.contains(provider)) {
|
||||
// TODO: Check if the user has configured a sort order for this provider.
|
||||
sort_index = next_provider_sort_index_ ++;
|
||||
|
||||
QStandardItem* divider = new QStandardItem(provider->icon(), provider->name());
|
||||
divider->setData(true, LibraryModel::Role_IsDivider);
|
||||
divider->setData(sort_index, Role_ProviderIndex);
|
||||
divider->setFlags(Qt::ItemIsEnabled);
|
||||
current_model_->appendRow(divider);
|
||||
|
||||
provider_sort_indices_[provider] = sort_index;
|
||||
} else {
|
||||
sort_index = provider_sort_indices_[provider];
|
||||
}
|
||||
|
||||
foreach (const SearchProvider::Result& result, results) {
|
||||
QStandardItem* parent = current_model_->invisibleRootItem();
|
||||
|
||||
// Find (or create) the container nodes for this result if we can.
|
||||
if (result.group_automatically_) {
|
||||
ContainerKey key;
|
||||
key.provider_index_ = sort_index;
|
||||
|
||||
parent = BuildContainers(result.metadata_, parent, &key);
|
||||
}
|
||||
|
||||
// Create the item
|
||||
QStandardItem* item = new QStandardItem(result.metadata_.title());
|
||||
item->setData(QVariant::fromValue(result), Role_Result);
|
||||
item->setData(sort_index, Role_ProviderIndex);
|
||||
|
||||
parent->appendRow(item);
|
||||
}
|
||||
}
|
||||
|
||||
QStandardItem* GlobalSearchView::BuildContainers(
|
||||
const Song& s, QStandardItem* parent, ContainerKey* key, int level) {
|
||||
if (level >= 3) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool has_artist_icon = false;
|
||||
bool has_album_icon = false;
|
||||
QString display_text;
|
||||
QString sort_text;
|
||||
int year = 0;
|
||||
|
||||
switch (group_by_[level]) {
|
||||
case LibraryModel::GroupBy_Artist:
|
||||
display_text = LibraryModel::TextOrUnknown(s.artist());
|
||||
sort_text = LibraryModel::SortTextForArtist(s.artist());
|
||||
has_artist_icon = true;
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_YearAlbum:
|
||||
year = qMax(0, s.year());
|
||||
display_text = LibraryModel::PrettyYearAlbum(year, s.album());
|
||||
sort_text = LibraryModel::SortTextForYear(year) + s.album();
|
||||
has_album_icon = true;
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_Year:
|
||||
year = qMax(0, s.year());
|
||||
display_text = QString::number(year);
|
||||
sort_text = LibraryModel::SortTextForYear(year) + " ";
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_Composer: display_text = s.composer();
|
||||
case LibraryModel::GroupBy_Genre: if (display_text.isNull()) display_text = s.genre();
|
||||
case LibraryModel::GroupBy_Album: if (display_text.isNull()) display_text = s.album();
|
||||
case LibraryModel::GroupBy_AlbumArtist: if (display_text.isNull()) display_text = s.effective_albumartist();
|
||||
display_text = LibraryModel::TextOrUnknown(display_text);
|
||||
sort_text = LibraryModel::SortTextForArtist(display_text);
|
||||
has_album_icon = true;
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_FileType:
|
||||
display_text = s.TextForFiletype();
|
||||
sort_text = display_text;
|
||||
break;
|
||||
|
||||
case LibraryModel::GroupBy_None:
|
||||
return parent;
|
||||
}
|
||||
|
||||
// Find a container for this level
|
||||
key->group_[level] = display_text;
|
||||
QStandardItem* container = containers_[*key];
|
||||
if (!container) {
|
||||
container = new QStandardItem(display_text);
|
||||
container->setData(key->provider_index_, Role_ProviderIndex);
|
||||
container->setData(sort_text, LibraryModel::Role_SortText);
|
||||
container->setData(group_by_[level], LibraryModel::Role_ContainerType);
|
||||
|
||||
if (has_artist_icon) {
|
||||
container->setIcon(artist_icon_);
|
||||
} else if (has_album_icon) {
|
||||
if (app_->library_model()->use_pretty_covers()) {
|
||||
container->setData(no_cover_icon_, Qt::DecorationRole);
|
||||
} else {
|
||||
container->setIcon(album_icon_);
|
||||
}
|
||||
}
|
||||
|
||||
parent->appendRow(container);
|
||||
containers_[*key] = container;
|
||||
}
|
||||
|
||||
// Create the container for the next level.
|
||||
return BuildContainers(s, container, key, level + 1);
|
||||
current_model_->AddResults(results);
|
||||
}
|
||||
|
||||
void GlobalSearchView::SwapModels() {
|
||||
|
@ -324,7 +203,7 @@ void GlobalSearchView::LazyLoadArt(const QModelIndex& proxy_index) {
|
|||
}
|
||||
|
||||
// Already loading art for this item?
|
||||
if (proxy_index.data(Role_LazyLoadingArt).isValid()) {
|
||||
if (proxy_index.data(GlobalSearchModel::Role_LazyLoadingArt).isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -345,7 +224,7 @@ void GlobalSearchView::LazyLoadArt(const QModelIndex& proxy_index) {
|
|||
// Mark the item as loading art
|
||||
const QModelIndex source_index = front_proxy_->mapToSource(proxy_index);
|
||||
QStandardItem* item = front_model_->itemFromIndex(source_index);
|
||||
item->setData(true, Role_LazyLoadingArt);
|
||||
item->setData(true, GlobalSearchModel::Role_LazyLoadingArt);
|
||||
|
||||
// Walk down the item's children until we find a track
|
||||
while (item->rowCount()) {
|
||||
|
@ -354,7 +233,7 @@ void GlobalSearchView::LazyLoadArt(const QModelIndex& proxy_index) {
|
|||
|
||||
// Get the track's Result
|
||||
const SearchProvider::Result result =
|
||||
item->data(Role_Result).value<SearchProvider::Result>();
|
||||
item->data(GlobalSearchModel::Role_Result).value<SearchProvider::Result>();
|
||||
|
||||
// Load the art.
|
||||
int id = engine_->LoadArtAsync(result);
|
||||
|
@ -387,7 +266,7 @@ void GlobalSearchView::GetChildResults(const QStandardItem* item,
|
|||
}
|
||||
} else {
|
||||
// No - it's a song, add its result
|
||||
results->append(item->data(Role_Result).value<SearchProvider::Result>());
|
||||
results->append(item->data(GlobalSearchModel::Role_Result).value<SearchProvider::Result>());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,7 +287,7 @@ MimeData* GlobalSearchView::LoadSelectedTracks() {
|
|||
|
||||
// Still got nothing? Give up.
|
||||
if (indexes.isEmpty()) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get all the results in these indexes
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <QWidget>
|
||||
|
||||
class Application;
|
||||
class GlobalSearchModel;
|
||||
class SearchProviderStatusWidget;
|
||||
class Ui_GlobalSearchView;
|
||||
|
||||
|
@ -42,19 +43,6 @@ public:
|
|||
|
||||
static const int kSwapModelsTimeoutMsec;
|
||||
|
||||
enum Role {
|
||||
Role_Result = LibraryModel::LastRole,
|
||||
Role_LazyLoadingArt,
|
||||
Role_ProviderIndex,
|
||||
|
||||
LastRole
|
||||
};
|
||||
|
||||
struct ContainerKey {
|
||||
int provider_index_;
|
||||
QString group_[3];
|
||||
};
|
||||
|
||||
// Called by the delegate
|
||||
void LazyLoadArt(const QModelIndex& index);
|
||||
|
||||
|
@ -71,13 +59,10 @@ private slots:
|
|||
void SwapModels();
|
||||
void TextEdited(const QString& text);
|
||||
void AddResults(int id, const SearchProvider::ResultList& results);
|
||||
|
||||
void ArtLoaded(int id, const QPixmap& pixmap);
|
||||
|
||||
private:
|
||||
MimeData* LoadSelectedTracks();
|
||||
QStandardItem* BuildContainers(const Song& metadata, QStandardItem* parent,
|
||||
ContainerKey* key, int level = 0);
|
||||
|
||||
void GetChildResults(const QStandardItem* item,
|
||||
SearchProvider::ResultList* results,
|
||||
|
@ -94,52 +79,19 @@ private:
|
|||
// model and a back model - the front model is the one that's shown in the
|
||||
// UI and the back model is the one that lies in wait. current_model_ will
|
||||
// point to either the front or the back model.
|
||||
QStandardItemModel* front_model_;
|
||||
QStandardItemModel* back_model_;
|
||||
QStandardItemModel* current_model_;
|
||||
GlobalSearchModel* front_model_;
|
||||
GlobalSearchModel* back_model_;
|
||||
GlobalSearchModel* current_model_;
|
||||
|
||||
QSortFilterProxyModel* front_proxy_;
|
||||
QSortFilterProxyModel* back_proxy_;
|
||||
QSortFilterProxyModel* current_proxy_;
|
||||
|
||||
QTimer* swap_models_timer_;
|
||||
|
||||
LibraryModel::Grouping group_by_;
|
||||
|
||||
QMap<SearchProvider*, int> provider_sort_indices_;
|
||||
int next_provider_sort_index_;
|
||||
QMap<ContainerKey, QStandardItem*> containers_;
|
||||
|
||||
QMap<int, QAction*> track_requests_;
|
||||
QMap<int, QModelIndex> art_requests_;
|
||||
|
||||
QIcon artist_icon_;
|
||||
QIcon album_icon_;
|
||||
QPixmap no_cover_icon_;
|
||||
QTimer* swap_models_timer_;
|
||||
|
||||
QList<SearchProviderStatusWidget*> provider_status_widgets_;
|
||||
};
|
||||
|
||||
inline uint qHash(const GlobalSearchView::ContainerKey& key) {
|
||||
return qHash(key.provider_index_)
|
||||
^ qHash(key.group_[0])
|
||||
^ qHash(key.group_[1])
|
||||
^ qHash(key.group_[2]);
|
||||
}
|
||||
|
||||
inline bool operator <(const GlobalSearchView::ContainerKey& left,
|
||||
const GlobalSearchView::ContainerKey& right) {
|
||||
#define CMP(field) \
|
||||
if (left.field < right.field) return true; \
|
||||
if (left.field > right.field) return false
|
||||
|
||||
CMP(provider_index_);
|
||||
CMP(group_[0]);
|
||||
CMP(group_[1]);
|
||||
CMP(group_[2]);
|
||||
return false;
|
||||
|
||||
#undef CMP
|
||||
}
|
||||
|
||||
#endif // GLOBALSEARCHVIEW_H
|
||||
|
|
Loading…
Reference in New Issue