Python bindings for LibraryView + new UI hook for plugins: the view's context menu

support for IN operator in LibraryQuery.AddWhere
This commit is contained in:
Paweł Bara 2011-01-18 16:34:43 +00:00
parent 1a959b136c
commit 07739d6c68
11 changed files with 103 additions and 55 deletions

View File

@ -71,8 +71,17 @@ void LibraryQuery::AddWhere(const QString& column, const QVariant& value, const
if (value.type() == QVariant::Int)
where_clauses_ << QString("%1 %2 %3").arg(column, op, value.toString());
else {
where_clauses_ << QString("%1 %2 ?").arg(column, op);
bound_values_ << value;
if(!op.compare("IN", Qt::CaseInsensitive)) {
QStringList final;
foreach(const QString& old, value.toStringList()) {
final << "'" + QString(old).replace("'", "''") + "'";
}
where_clauses_ << QString("%1 IN (%3)").arg(column, final.join(","));
} else {
where_clauses_ << QString("%1 %2 ?").arg(column, op);
bound_values_ << value;
}
}
}
@ -83,6 +92,7 @@ void LibraryQuery::AddCompilationRequirement(bool compilation) {
QSqlError LibraryQuery::Exec(QSqlDatabase db, const QString& songs_table,
const QString& fts_table) {
QString sql;
if (join_with_fts_) {
sql = QString("SELECT %1 FROM %2 INNER JOIN %3 AS fts ON %2.ROWID = fts.ROWID")
.arg(column_spec_, songs_table, fts_table);
@ -103,6 +113,7 @@ QSqlError LibraryQuery::Exec(QSqlDatabase db, const QString& songs_table,
sql.replace("%songs_table", songs_table);
sql.replace("%fts_table_noprefix", fts_table.section('.', -1, -1));
sql.replace("%fts_table", fts_table);
query_ = QSqlQuery(sql, db);
// Bind values

View File

@ -42,6 +42,9 @@ class LibraryQuery {
void SetColumnSpec(const QString& spec) { column_spec_ = spec; }
void SetOrderBy(const QString& order_by) { order_by_ = order_by; }
// Adds a fragment of WHERE clause. When executed, this Query will connect all
// the fragments with AND operator.
// Please note that IN operator expects a QStringList as value.
void AddWhere(const QString& column, const QVariant& value, const QString& op = "=");
void AddCompilationRequirement(bool compilation);
void SetLimit(int limit) { limit_ = limit; }

View File

@ -96,6 +96,46 @@ LibraryView::LibraryView(QWidget* parent)
ReloadSettings();
setStyleSheet("QTreeView::item{padding-top:1px;}");
context_menu_ = new QMenu(this);
load_ = context_menu_->addAction(IconLoader::Load("media-playback-start"),
tr("Load"), this, SLOT(Load()));
add_to_playlist_ = context_menu_->addAction(IconLoader::Load("media-playback-start"),
tr("Add to playlist"), this, SLOT(AddToPlaylist()));
add_to_playlist_enqueue_ = context_menu_->addAction(IconLoader::Load("media-playback-start"),
tr("Enqueue to playlist"), this, SLOT(AddToPlaylistEnqueue()));
context_menu_->addSeparator();
new_smart_playlist_ = context_menu_->addAction(IconLoader::Load("document-new"),
tr("New smart playlist..."), this, SLOT(NewSmartPlaylist()));
edit_smart_playlist_ = context_menu_->addAction(IconLoader::Load("edit-rename"),
tr("Edit smart playlist..."), this, SLOT(EditSmartPlaylist()));
delete_smart_playlist_ = context_menu_->addAction(IconLoader::Load("edit-delete"),
tr("Delete smart playlist"), this, SLOT(DeleteSmartPlaylist()));
context_menu_->addSeparator();
organise_ = context_menu_->addAction(IconLoader::Load("edit-copy"),
tr("Organise files..."), this, SLOT(Organise()));
copy_to_device_ = context_menu_->addAction(IconLoader::Load("multimedia-player-ipod-mini-blue"),
tr("Copy to device..."), this, SLOT(CopyToDevice()));
// this will get finalized later
copy_to_device_->setDisabled(true);
delete_ = context_menu_->addAction(IconLoader::Load("edit-delete"),
tr("Delete from disk..."), this, SLOT(Delete()));
context_menu_->addSeparator();
edit_track_ = context_menu_->addAction(IconLoader::Load("edit-rename"),
tr("Edit track information..."), this, SLOT(EditTracks()));
edit_tracks_ = context_menu_->addAction(IconLoader::Load("edit-rename"),
tr("Edit tracks information..."), this, SLOT(EditTracks()));
context_menu_->addSeparator();
show_in_various_ = context_menu_->addAction(
tr("Show in various artists"), this, SLOT(ShowInVarious()));
no_show_in_various_ = context_menu_->addAction(
tr("Don't show in various artists"), this, SLOT(NoShowInVarious()));
context_menu_->addSeparator();
}
LibraryView::~LibraryView() {
@ -123,6 +163,11 @@ void LibraryView::SetLibrary(LibraryModel *library) {
void LibraryView::SetDeviceManager(DeviceManager *device_manager) {
devices_ = device_manager;
// lazy finalization
copy_to_device_->setDisabled(devices_->connected_devices_model()->rowCount() == 0);
connect(devices_->connected_devices_model(), SIGNAL(IsEmptyChanged(bool)),
copy_to_device_, SLOT(setDisabled(bool)));
}
void LibraryView::TotalSongCountUpdated(int count) {
@ -176,48 +221,6 @@ void LibraryView::mouseReleaseEvent(QMouseEvent* e) {
}
void LibraryView::contextMenuEvent(QContextMenuEvent *e) {
if (!context_menu_) {
context_menu_ = new QMenu(this);
load_ = context_menu_->addAction(IconLoader::Load("media-playback-start"),
tr("Load"), this, SLOT(Load()));
add_to_playlist_ = context_menu_->addAction(IconLoader::Load("media-playback-start"),
tr("Add to playlist"), this, SLOT(AddToPlaylist()));
add_to_playlist_enqueue_ = context_menu_->addAction(IconLoader::Load("media-playback-start"),
tr("Enqueue to playlist"), this, SLOT(AddToPlaylistEnqueue()));
context_menu_->addSeparator();
new_smart_playlist_ = context_menu_->addAction(IconLoader::Load("document-new"),
tr("New smart playlist..."), this, SLOT(NewSmartPlaylist()));
edit_smart_playlist_ = context_menu_->addAction(IconLoader::Load("edit-rename"),
tr("Edit smart playlist..."), this, SLOT(EditSmartPlaylist()));
delete_smart_playlist_ = context_menu_->addAction(IconLoader::Load("edit-delete"),
tr("Delete smart playlist"), this, SLOT(DeleteSmartPlaylist()));
context_menu_->addSeparator();
organise_ = context_menu_->addAction(IconLoader::Load("edit-copy"),
tr("Organise files..."), this, SLOT(Organise()));
copy_to_device_ = context_menu_->addAction(IconLoader::Load("multimedia-player-ipod-mini-blue"),
tr("Copy to device..."), this, SLOT(CopyToDevice()));
delete_ = context_menu_->addAction(IconLoader::Load("edit-delete"),
tr("Delete from disk..."), this, SLOT(Delete()));
context_menu_->addSeparator();
edit_track_ = context_menu_->addAction(IconLoader::Load("edit-rename"),
tr("Edit track information..."), this, SLOT(EditTracks()));
edit_tracks_ = context_menu_->addAction(IconLoader::Load("edit-rename"),
tr("Edit tracks information..."), this, SLOT(EditTracks()));
context_menu_->addSeparator();
show_in_various_ = context_menu_->addAction(
tr("Show in various artists"), this, SLOT(ShowInVarious()));
no_show_in_various_ = context_menu_->addAction(
tr("Don't show in various artists"), this, SLOT(NoShowInVarious()));
copy_to_device_->setDisabled(devices_->connected_devices_model()->rowCount() == 0);
connect(devices_->connected_devices_model(), SIGNAL(IsEmptyChanged(bool)),
copy_to_device_, SLOT(setDisabled(bool)));
}
context_menu_index_ = indexAt(e->pos());
if (!context_menu_index_.isValid())
return;
@ -225,6 +228,7 @@ void LibraryView::contextMenuEvent(QContextMenuEvent *e) {
context_menu_index_ = qobject_cast<QSortFilterProxyModel*>(model())
->mapToSource(context_menu_index_);
// TODO: check if custom plugin actions should be enabled / visible
const int type = library_->data(context_menu_index_, LibraryModel::Role_Type).toInt();
const bool enable_various = type == LibraryItem::Type_Container ||
type == LibraryItem::Type_Song;

View File

@ -50,6 +50,11 @@ class LibraryView : public AutoExpandingTreeView {
static const char* kSettingsGroup;
// Returns Songs currently selected in the library view. Please note that the
// selection is recursive meaning that if for example an album is selected
// this will return all of it's songs.
SongList GetSelectedSongs() const;
void SetTaskManager(TaskManager* task_manager);
void SetLibrary(LibraryModel* library);
void SetDeviceManager(DeviceManager* device_manager);
@ -58,6 +63,8 @@ class LibraryView : public AutoExpandingTreeView {
void keyboardSearch(const QString &search);
void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible);
QMenu* context_menu() const { return context_menu_; }
public slots:
void TotalSongCountUpdated(int count);
void ReloadSettings();
@ -99,7 +106,6 @@ class LibraryView : public AutoExpandingTreeView {
private:
void RecheckIsEmpty();
void ShowInVarious(bool on);
SongList GetSelectedSongs() const;
private:
LibraryModel* library_;

View File

@ -0,0 +1,7 @@
class AutoExpandingTreeView : QTreeView {
%TypeHeaderCode
#include "widgets/autoexpandingtreeview.h"
%End
};

View File

@ -4,11 +4,13 @@
%Import QtGui/QtGuimod.sip
%Import QtNetwork/QtNetworkmod.sip
%Include autoexpandingtreeview.sip
%Include directory.sip
%Include engine_fwd.sip
%Include iconloader.sip
%Include librarybackend.sip
%Include libraryquery.sip
%Include libraryview.sip
%Include mergedproxymodel.sip
%Include network.sip
%Include parserbase.sip

View File

@ -0,0 +1,10 @@
class LibraryView : AutoExpandingTreeView {
%TypeHeaderCode
#include "library/libraryview.h"
%End
public:
SongList GetSelectedSongs() const;
};

View File

@ -114,6 +114,7 @@ Script* PythonEngine::CreateScript(const ScriptInfo& info) {
AddObject(manager()->data().settings_dialog_, sipType_SettingsDialog, "settings_dialog");
AddObject(manager()->data().radio_model_, sipType_RadioModel, "radio_model");
AddObject(manager()->ui(), sipType_UIInterface, "ui");
AddObject(manager()->data().library_view_, sipType_LibraryView, "library_view");
AddObject(this, sipType_PythonEngine, "pythonengine");
// Create a module for scripts

View File

@ -27,6 +27,7 @@
class LanguageEngine;
class Library;
class LibraryView;
class Player;
class PlaylistManager;
class RadioModel;
@ -57,10 +58,11 @@ public:
struct GlobalData {
GlobalData() {}
GlobalData(Library* library, Player* player, PlaylistManager* playlists,
TaskManager* task_manager, SettingsDialog* settings_dialog,
RadioModel* radio_model)
GlobalData(Library* library, LibraryView* library_view, Player* player,
PlaylistManager* playlists, TaskManager* task_manager,
SettingsDialog* settings_dialog, RadioModel* radio_model)
: library_(library),
library_view_(library_view),
player_(player),
playlists_(playlists),
task_manager_(task_manager),
@ -69,6 +71,7 @@ public:
{}
Library* library_;
LibraryView* library_view_;
Player* player_;
PlaylistManager* playlists_;
TaskManager* task_manager_;

View File

@ -72,15 +72,15 @@ msgstr ""
msgid "%1: Wiimotedev module"
msgstr ""
#, c-format
#, c-format, qt-plural-format
msgid "%n failed"
msgstr ""
#, c-format
#, c-format, qt-plural-format
msgid "%n finished"
msgstr ""
#, c-format
#, c-format, qt-plural-format
msgid "%n remaining"
msgstr ""
@ -2513,7 +2513,7 @@ msgstr ""
msgid "Zero"
msgstr ""
#, c-format
#, c-format, qt-plural-format
msgid "add %n songs"
msgstr ""
@ -2572,7 +2572,7 @@ msgstr ""
msgid "options"
msgstr ""
#, c-format
#, c-format, qt-plural-format
msgid "remove %n songs"
msgstr ""

View File

@ -587,6 +587,7 @@ MainWindow::MainWindow(
scripts_->ui()->RegisterActionLocation("tools_menu", ui_->menu_tools, ui_->action_update_library);
scripts_->ui()->RegisterActionLocation("extras_menu", ui_->menu_extras, NULL);
scripts_->ui()->RegisterActionLocation("help_menu", ui_->menu_help, NULL);
scripts_->ui()->RegisterActionLocation("library_context_menu", library_view_->view()->context_menu(), NULL);
// Load theme
StyleSheetLoader* css_loader = new StyleSheetLoader(this);
@ -645,8 +646,8 @@ MainWindow::MainWindow(
#endif
scripts_->Init(ScriptManager::GlobalData(
library_, player_, playlists_, task_manager_, settings_dialog_.get(),
radio_model_));
library_, library_view_->view(), player_, playlists_,
task_manager_, settings_dialog_.get(), radio_model_));
connect(ui_->action_script_manager, SIGNAL(triggered()), SLOT(ShowScriptDialog()));
}