Clementine-audio-player-Mac.../src/globalsearch/globalsearchwidget.h

195 lines
5.0 KiB
C++

/* This file is part of Clementine.
Copyright 2010, 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 GLOBALSEARCHWIDGET_H
#define GLOBALSEARCHWIDGET_H
#include "searchprovider.h"
#include "ui/settingsdialog.h"
#include <QScopedPointer>
#include <QWidget>
#include <boost/bimap.hpp>
class GlobalSearch;
class GlobalSearchTooltip;
class LibraryBackendInterface;
class Ui_GlobalSearchWidget;
class QDesktopWidget;
class QListView;
class QMimeData;
class QModelIndex;
class QSortFilterProxyModel;
class QStandardItemModel;
class QToolButton;
class GlobalSearchWidget : public QWidget {
Q_OBJECT
public:
GlobalSearchWidget(QWidget* parent = 0);
~GlobalSearchWidget();
static const int kMinVisibleItems;
static const int kMaxVisibleItems;
static const int kSwapModelsTimeoutMsec;
static const int kSuggestionTimeoutMsec;
static const int kSuggestionCount;
enum Role {
Role_PrimaryResult = Qt::UserRole + 1,
Role_AllResults,
Role_LazyLoadingArt,
Role_OrderArrived
};
void Init(GlobalSearch* engine_);
// Called by the delegate
void LazyLoadArt(const QModelIndex& index);
// QObject
bool eventFilter(QObject* o, QEvent* e);
public slots:
void ReloadSettings();
void StartSearch(const QString& query);
signals:
void AddToPlaylist(QMimeData* data);
void OpenSettingsAtPage(SettingsDialog::Page page);
protected:
void resizeEvent(QResizeEvent* e);
void paintEvent(QPaintEvent* e);
void showEvent(QShowEvent* e);
void hideEvent(QHideEvent* e);
private slots:
void TextEdited(const QString& text);
void AddResults(int id, const SearchProvider::ResultList& results);
void ArtLoaded(int id, const QPixmap& pixmap);
void TracksLoaded(int id, MimeData* mime_data);
void ResultDoubleClicked();
void AddCurrent();
void AddAndPlayCurrent();
void AddAndQueueCurrent();
void ReplaceCurrent();
void ReplaceAndPlayCurrent();
void SettingsClicked();
void HidePopup(bool manual);
void UpdateTooltip();
void UpdateTooltipPosition();
void SwapModels();
void NextSuggestion();
private:
// Return values from CanCombineResults
enum CombineAction {
CannotCombine, // The two results are different and can't be combined
LeftPreferred, // The two results can be combined - the left one is better
RightPreferred // The two results can be combined - the right one is better
};
class CombineCache {
public:
CombineCache(QAbstractItemModel* model);
QModelIndexList FindCandidates(const QModelIndex& result) const;
void Insert(const QModelIndex& index);
void Remove(const QModelIndex& index);
void Clear();
static uint Hash(const QModelIndex& index);
private:
QAbstractItemModel* model_;
QMultiMap<uint, int> data_;
};
void RepositionPopup();
CombineAction CanCombineResults(const QModelIndex& left, const QModelIndex& right) const;
void CombineResults(const QModelIndex& superior, const QModelIndex& inferior);
bool EventFilterSearchWidget(QObject* o, QEvent* e);
bool EventFilterPopup(QObject* o, QEvent* e);
void LoadTracks(QAction* trigger);
private:
Ui_GlobalSearchWidget* ui_;
GlobalSearch* engine_;
int last_id_;
int order_arrived_counter_;
bool closed_since_search_began_;
QMap<int, QModelIndex> art_requests_;
QMap<int, QAction*> track_requests_;
// Like graphics APIs have a front buffer and a back buffer, there's a front
// 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_;
QMap<QStandardItemModel*, CombineCache*> combine_cache_;
QSortFilterProxyModel* front_proxy_;
QSortFilterProxyModel* back_proxy_;
QSortFilterProxyModel* current_proxy_;
QListView* view_;
bool consume_focus_out_;
QTimer* swap_models_timer_;
QPixmap background_;
QPixmap background_scaled_;
QDesktopWidget* desktop_;
bool show_tooltip_;
bool combine_identical_results_;
QStringList provider_order_;
QScopedPointer<GlobalSearchTooltip> tooltip_;
QAction* add_;
QAction* add_and_play_;
QAction* add_and_queue_;
QAction* replace_;
QAction* replace_and_play_;
QList<QAction*> actions_;
QString hint_text_;
QTimer* next_suggestion_timer_;
};
#endif // GLOBALSEARCHWIDGET_H