diff --git a/data/data.qrc b/data/data.qrc index 24032bb7e..02a4e0612 100644 --- a/data/data.qrc +++ b/data/data.qrc @@ -53,5 +53,7 @@ somafm.png refresh.png web.png + library.png + media-playback-start-32.png diff --git a/data/library.png b/data/library.png new file mode 100644 index 000000000..073784559 Binary files /dev/null and b/data/library.png differ diff --git a/data/media-playback-start-32.png b/data/media-playback-start-32.png new file mode 100644 index 000000000..71906857c Binary files /dev/null and b/data/media-playback-start-32.png differ diff --git a/src/library.cpp b/src/library.cpp index 8a4866242..0f40b7a1d 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -2,7 +2,7 @@ #include "librarybackend.h" #include "libraryitem.h" #include "songmimedata.h" -#include "libraryconfig.h" +#include "librarydirectorymodel.h" #include #include @@ -15,9 +15,9 @@ Library::Library(EngineBase* engine, QObject* parent) engine_(engine), backend_(new BackgroundThread(this)), watcher_(new BackgroundThread(this)), + dir_model_(new LibraryDirectoryModel(this)), artist_icon_(":artist.png"), - album_icon_(":album.png"), - config_(new LibraryConfig) + album_icon_(":album.png") { root_->lazy_loaded = true; @@ -28,7 +28,6 @@ Library::Library(EngineBase* engine, QObject* parent) Library::~Library() { delete root_; - delete config_; } void Library::StartThreads() { @@ -44,7 +43,7 @@ void Library::BackendInitialised() { connect(backend_->Worker().get(), SIGNAL(Error(QString)), SIGNAL(Error(QString))); connect(backend_->Worker().get(), SIGNAL(TotalSongCountUpdated(int)), SIGNAL(TotalSongCountUpdated(int))); - config_->SetBackend(backend_->Worker()); + dir_model_->SetBackend(backend_->Worker()); if (--waiting_for_threads_ == 0) Initialise(); @@ -496,10 +495,6 @@ SongList Library::GetChildSongs(const QModelIndex& index) const { return ret; } -void Library::ShowConfig() { - config_->show(); -} - void Library::SetFilterAge(int age) { query_options_.max_age = age; Reset(); diff --git a/src/library.h b/src/library.h index 1b6f78989..6d92751a6 100644 --- a/src/library.h +++ b/src/library.h @@ -13,7 +13,7 @@ #include "libraryitem.h" #include "simpletreemodel.h" -class LibraryConfig; +class LibraryDirectoryModel; class Library : public SimpleTreeModel { Q_OBJECT @@ -30,6 +30,8 @@ class Library : public SimpleTreeModel { void StartThreads(); + LibraryDirectoryModel* GetDirectoryModel() const { return dir_model_; } + // Get information about the library void GetChildSongs(LibraryItem* item, QList* urls, SongList* songs) const; SongList GetChildSongs(const QModelIndex& index) const; @@ -49,8 +51,6 @@ class Library : public SimpleTreeModel { void ScanFinished(); public slots: - void ShowConfig(); - void SetFilterAge(int age); void SetFilterText(const QString& text); @@ -89,6 +89,7 @@ class Library : public SimpleTreeModel { EngineBase* engine_; BackgroundThread* backend_; BackgroundThread* watcher_; + LibraryDirectoryModel* dir_model_; int waiting_for_threads_; @@ -101,8 +102,6 @@ class Library : public SimpleTreeModel { QIcon artist_icon_; QIcon album_icon_; - - LibraryConfig* config_; }; #endif // LIBRARY_H diff --git a/src/libraryconfig.cpp b/src/libraryconfig.cpp index 31fd67b45..0f3f87aa6 100644 --- a/src/libraryconfig.cpp +++ b/src/libraryconfig.cpp @@ -1,5 +1,5 @@ #include "libraryconfig.h" -#include "librarybackend.h" +#include "librarydirectorymodel.h" #include #include @@ -8,24 +8,28 @@ const char* LibraryConfig::kSettingsGroup = "LibraryConfig"; LibraryConfig::LibraryConfig(QWidget* parent) - : QDialog(parent), - dir_icon_(":folder.png") + : QWidget(parent), + model_(NULL) { ui_.setupUi(this); connect(ui_.add, SIGNAL(clicked()), SLOT(Add())); connect(ui_.remove, SIGNAL(clicked()), SLOT(Remove())); - connect(ui_.list, SIGNAL(currentRowChanged(int)), SLOT(CurrentRowChanged(int))); } -void LibraryConfig::SetBackend(boost::shared_ptr backend) { - backend_ = backend; +void LibraryConfig::SetModel(LibraryDirectoryModel *model) { + model_ = model; + ui_.list->setModel(model_); - connect(backend_.get(), SIGNAL(DirectoriesDiscovered(DirectoryList)), SLOT(DirectoriesDiscovered(DirectoryList))); - connect(backend_.get(), SIGNAL(DirectoriesDeleted(DirectoryList)), SLOT(DirectoriesDeleted(DirectoryList))); + connect(ui_.list->selectionModel(), + SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), + SLOT(CurrentRowChanged(QModelIndex))); - ui_.list->setEnabled(true); - ui_.add->setEnabled(true); + + if (model_->IsBackendReady()) + BackendReady(); + else + connect(model_, SIGNAL(BackendReady()), SLOT(BackendReady())); } void LibraryConfig::Add() { @@ -36,41 +40,22 @@ void LibraryConfig::Add() { path = QFileDialog::getExistingDirectory(this, "Add directory...", path); if (!path.isNull()) { - backend_->AddDirectory(path); + model_->AddDirectory(path); } settings.setValue("last_path", path); } void LibraryConfig::Remove() { - QListWidgetItem* item = ui_.list->currentItem(); - if (item == NULL) - return; - - Directory dir; - dir.path = item->text(); - dir.id = item->type(); - - backend_->RemoveDirectory(dir); + model_->RemoveDirectory(ui_.list->currentIndex()); } -void LibraryConfig::DirectoriesDiscovered(const DirectoryList& list) { - foreach (const Directory& dir, list) { - new QListWidgetItem(dir_icon_, dir.path, ui_.list, dir.id); - } +void LibraryConfig::CurrentRowChanged(const QModelIndex& index) { + ui_.remove->setEnabled(index.isValid()); } -void LibraryConfig::DirectoriesDeleted(const DirectoryList& list) { - foreach (const Directory& dir, list) { - for (int i=0 ; icount() ; ++i) { - if (ui_.list->item(i)->type() == dir.id) { - delete ui_.list->takeItem(i); - break; - } - } - } -} - -void LibraryConfig::CurrentRowChanged(int row) { - ui_.remove->setEnabled(row != -1); +void LibraryConfig::BackendReady() { + ui_.list->setEnabled(true); + ui_.add->setEnabled(true); + ui_.remove->setEnabled(true); } diff --git a/src/libraryconfig.h b/src/libraryconfig.h index fcefbaa86..16bc0e5cf 100644 --- a/src/libraryconfig.h +++ b/src/libraryconfig.h @@ -1,39 +1,32 @@ #ifndef LIBRARYCONFIG_H #define LIBRARYCONFIG_H -#include - -#include +#include #include "ui_libraryconfig.h" -#include "directory.h" -class LibraryBackend; +class LibraryDirectoryModel; -class LibraryConfig : public QDialog { +class LibraryConfig : public QWidget { Q_OBJECT public: LibraryConfig(QWidget* parent = 0); - void SetBackend(boost::shared_ptr backend); + void SetModel(LibraryDirectoryModel* model); private slots: void Add(); void Remove(); + void BackendReady(); - void DirectoriesDiscovered(const DirectoryList&); - void DirectoriesDeleted(const DirectoryList&); - - void CurrentRowChanged(int); + void CurrentRowChanged(const QModelIndex& index); private: static const char* kSettingsGroup; Ui::LibraryConfig ui_; - QIcon dir_icon_; - - boost::shared_ptr backend_; + LibraryDirectoryModel* model_; }; #endif // LIBRARYCONFIG_H diff --git a/src/libraryconfig.ui b/src/libraryconfig.ui index 8919e1e73..c6f6170f3 100644 --- a/src/libraryconfig.ui +++ b/src/libraryconfig.ui @@ -1,19 +1,19 @@ LibraryConfig - + 0 0 489 - 273 + 232 - - Music Library - + + 0 + @@ -24,7 +24,7 @@ - + false @@ -88,59 +88,15 @@ - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - list add remove - buttonBox - - - buttonBox - accepted() - LibraryConfig - accept() - - - 248 - 254 - - - 157 - 272 - - - - - buttonBox - rejected() - LibraryConfig - reject() - - - 316 - 260 - - - 286 - 272 - - - - + diff --git a/src/libraryconfigdialog.cpp b/src/libraryconfigdialog.cpp new file mode 100644 index 000000000..45344be91 --- /dev/null +++ b/src/libraryconfigdialog.cpp @@ -0,0 +1,11 @@ +#include "libraryconfigdialog.h" + +LibraryConfigDialog::LibraryConfigDialog(QWidget *parent) + : QDialog(parent) +{ + ui_.setupUi(this); +} + +void LibraryConfigDialog::SetModel(LibraryDirectoryModel* model) { + ui_.config->SetModel(model); +} diff --git a/src/libraryconfigdialog.h b/src/libraryconfigdialog.h new file mode 100644 index 000000000..a1f3dfe7d --- /dev/null +++ b/src/libraryconfigdialog.h @@ -0,0 +1,21 @@ +#ifndef LIBRARYCONFIGDIALOG_H +#define LIBRARYCONFIGDIALOG_H + +#include + +#include "ui_libraryconfigdialog.h" + +class LibraryDirectoryModel; + +class LibraryConfigDialog : public QDialog { + Q_OBJECT + public: + LibraryConfigDialog(QWidget* parent = 0); + + void SetModel(LibraryDirectoryModel* model); + + private: + Ui::LibraryConfigDialog ui_; +}; + +#endif // LIBRARYCONFIGDIALOG_H diff --git a/src/libraryconfigdialog.ui b/src/libraryconfigdialog.ui new file mode 100644 index 000000000..1f11b7000 --- /dev/null +++ b/src/libraryconfigdialog.ui @@ -0,0 +1,88 @@ + + + LibraryConfigDialog + + + + 0 + 0 + 400 + 300 + + + + Music Library + + + + :/library.png:/library.png + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + LibraryConfig + QWidget +
libraryconfig.h
+ 1 +
+
+ + + + + + buttonBox + accepted() + LibraryConfigDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + LibraryConfigDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/src/librarydirectorymodel.cpp b/src/librarydirectorymodel.cpp new file mode 100644 index 000000000..8e585c764 --- /dev/null +++ b/src/librarydirectorymodel.cpp @@ -0,0 +1,55 @@ +#include "librarydirectorymodel.h" +#include "librarybackend.h" + +LibraryDirectoryModel::LibraryDirectoryModel(QObject* parent) + : QStandardItemModel(parent), + dir_icon_(":folder.png") +{ +} + +void LibraryDirectoryModel::SetBackend(boost::shared_ptr backend) { + backend_ = backend; + + connect(backend_.get(), SIGNAL(DirectoriesDiscovered(DirectoryList)), SLOT(DirectoriesDiscovered(DirectoryList))); + connect(backend_.get(), SIGNAL(DirectoriesDeleted(DirectoryList)), SLOT(DirectoriesDeleted(DirectoryList))); + + emit BackendReady(); +} + +void LibraryDirectoryModel::DirectoriesDiscovered(const DirectoryList &directories) { + foreach (const Directory& dir, directories) { + QStandardItem* item = new QStandardItem(dir.path); + item->setData(dir.id, kIdRole); + item->setIcon(dir_icon_); + appendRow(item); + } +} + +void LibraryDirectoryModel::DirectoriesDeleted(const DirectoryList &directories) { + foreach (const Directory& dir, directories) { + for (int i=0 ; idata(kIdRole).toInt() == dir.id) { + removeRow(i); + break; + } + } + } +} + +void LibraryDirectoryModel::AddDirectory(const QString& path) { + if (!backend_) + return; + + backend_->AddDirectory(path); +} + +void LibraryDirectoryModel::RemoveDirectory(const QModelIndex& index) { + if (!backend_ || !index.isValid()) + return; + + Directory dir; + dir.path = index.data().toString(); + dir.id = index.data(kIdRole).toInt(); + + backend_->RemoveDirectory(dir); +} diff --git a/src/librarydirectorymodel.h b/src/librarydirectorymodel.h new file mode 100644 index 000000000..b3692addc --- /dev/null +++ b/src/librarydirectorymodel.h @@ -0,0 +1,41 @@ +#ifndef LIBRARYDIRECTORYMODEL_H +#define LIBRARYDIRECTORYMODEL_H + +#include +#include + +#include + +#include "directory.h" + +class LibraryBackend; + +class LibraryDirectoryModel : public QStandardItemModel { + Q_OBJECT + + public: + LibraryDirectoryModel(QObject* parent = 0); + + void SetBackend(boost::shared_ptr backend); + bool IsBackendReady() const { return backend_; } + + // To be called by GUIs + void AddDirectory(const QString& path); + void RemoveDirectory(const QModelIndex& index); + + signals: + void BackendReady(); + + private slots: + // To be called by the backend + void DirectoriesDiscovered(const DirectoryList& directories); + void DirectoriesDeleted(const DirectoryList& directories); + + private: + static const int kIdRole = Qt::UserRole + 1; + + QIcon dir_icon_; + boost::shared_ptr backend_; +}; + +#endif // LIBRARYDIRECTORYMODEL_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 465e6f315..eb67132d1 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -12,6 +12,8 @@ #include "trackslider.h" #include "edittagdialog.h" #include "multiloadingindicator.h" +#include "settingsdialog.h" +#include "libraryconfigdialog.h" #include "qxtglobalshortcut.h" @@ -38,6 +40,8 @@ MainWindow::MainWindow(QWidget *parent) track_slider_(new TrackSlider(this)), edit_tag_dialog_(new EditTagDialog(this)), multi_loading_indicator_(new MultiLoadingIndicator(this)), + settings_dialog_(new SettingsDialog(this)), + library_config_dialog_(new LibraryConfigDialog(this)), radio_model_(new RadioModel(this)), playlist_(new Playlist(this)), player_(new Player(playlist_, radio_model_->GetLastFMService(), this)), @@ -70,6 +74,8 @@ MainWindow::MainWindow(QWidget *parent) ui_.library_view->setModel(library_sort_model_); ui_.library_view->SetLibrary(library_); + library_config_dialog_->SetModel(library_->GetDirectoryModel()); + settings_dialog_->SetLibraryDirectoryModel(library_->GetDirectoryModel()); ui_.radio_view->setModel(radio_model_); @@ -89,6 +95,7 @@ MainWindow::MainWindow(QWidget *parent) connect(ui_.action_love, SIGNAL(triggered()), SLOT(Love())); connect(ui_.action_clear_playlist, SIGNAL(triggered()), playlist_, SLOT(Clear())); connect(ui_.action_edit_track, SIGNAL(triggered()), SLOT(EditTracks())); + connect(ui_.action_configure, SIGNAL(triggered()), settings_dialog_, SLOT(show())); // Give actions to buttons ui_.forward_button->setDefaultAction(ui_.action_next_track); @@ -135,7 +142,7 @@ MainWindow::MainWindow(QWidget *parent) // Library connections connect(library_, SIGNAL(Error(QString)), SLOT(ReportError(QString))); connect(ui_.library_view, SIGNAL(doubleClicked(QModelIndex)), SLOT(LibraryDoubleClick(QModelIndex))); - connect(ui_.library_view, SIGNAL(ShowConfigDialog()), library_, SLOT(ShowConfig())); + connect(ui_.library_view, SIGNAL(ShowConfigDialog()), library_config_dialog_, SLOT(show())); connect(library_, SIGNAL(TotalSongCountUpdated(int)), ui_.library_view, SLOT(TotalSongCountUpdated(int))); connect(library_, SIGNAL(ScanStarted()), SLOT(LibraryScanStarted())); connect(library_, SIGNAL(ScanFinished()), SLOT(LibraryScanFinished())); @@ -171,7 +178,7 @@ MainWindow::MainWindow(QWidget *parent) QMenu* library_menu = new QMenu(this); library_menu->addActions(filter_age_group->actions()); library_menu->addSeparator(); - library_menu->addAction("Configure library...", library_, SLOT(ShowConfig())); + library_menu->addAction("Configure library...", library_config_dialog_, SLOT(show())); ui_.library_options->setMenu(library_menu); // Playlist menu diff --git a/src/mainwindow.h b/src/mainwindow.h index 36f32c5c1..1fddda5b4 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -9,7 +9,7 @@ class Playlist; class Player; class Library; -class LibraryConfig; +class LibraryConfigDialog; class RadioModel; class Song; class RadioItem; @@ -17,6 +17,7 @@ class OSD; class TrackSlider; class EditTagDialog; class MultiLoadingIndicator; +class SettingsDialog; class QSortFilterProxyModel; class SystemTrayIcon; @@ -80,6 +81,8 @@ class MainWindow : public QMainWindow { TrackSlider* track_slider_; EditTagDialog* edit_tag_dialog_; MultiLoadingIndicator* multi_loading_indicator_; + SettingsDialog* settings_dialog_; + LibraryConfigDialog* library_config_dialog_; RadioModel* radio_model_; Playlist* playlist_; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index b92792f7e..3562b67bd 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -14,7 +14,7 @@ Clementine - + :/icon.png:/icon.png @@ -294,7 +294,7 @@ - + :/clear.png:/clear.png @@ -314,7 +314,7 @@ - + :/configure.png:/configure.png @@ -428,9 +428,55 @@ + + + + 0 + 0 + 804 + 23 + + + + + Music + + + + + + + + + + + + + + Playlist + + + + + + Settings + + + + + + Help + + + + + + + + - + :/media-skip-backward.png:/media-skip-backward.png @@ -439,7 +485,7 @@ - + :/media-playback-start.png:/media-playback-start.png @@ -451,7 +497,7 @@ false - + :/media-playback-stop.png:/media-playback-stop.png @@ -460,7 +506,7 @@ - + :/media-skip-forward.png:/media-skip-forward.png @@ -469,7 +515,7 @@ - + :/exit.png:/exit.png @@ -481,7 +527,7 @@ - + :/media-playback-stop.png:/media-playback-stop.png @@ -547,7 +593,7 @@ false - + :/last.fm/love.png:/last.fm/love.png @@ -559,7 +605,7 @@ false - + :/last.fm/ban.png:/last.fm/ban.png @@ -568,7 +614,7 @@ - + :/clear-list.png:/clear-list.png @@ -580,13 +626,27 @@ - + :/edit-track.png:/edit-track.png Edit track information... + + + + :/configure.png:/configure.png + + + Configure Clementine... + + + + + About Clementine... + + @@ -623,6 +683,8 @@
radioview.h
- + + + diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp new file mode 100644 index 000000000..5af93706b --- /dev/null +++ b/src/settingsdialog.cpp @@ -0,0 +1,20 @@ +#include "settingsdialog.h" +#include "ui_settingsdialog.h" + +SettingsDialog::SettingsDialog(QWidget* parent) + : QDialog(parent) +{ + ui_.setupUi(this); + + connect(ui_.list, SIGNAL(currentTextChanged(QString)), SLOT(CurrentTextChanged(QString))); + + ui_.list->setCurrentRow(0); +} + +void SettingsDialog::CurrentTextChanged(const QString &text) { + ui_.title->setText("" + text + ""); +} + +void SettingsDialog::SetLibraryDirectoryModel(LibraryDirectoryModel* model) { + ui_.library_config->SetModel(model); +} diff --git a/src/settingsdialog.h b/src/settingsdialog.h new file mode 100644 index 000000000..e49b9ddaf --- /dev/null +++ b/src/settingsdialog.h @@ -0,0 +1,25 @@ +#ifndef SETTINGSDIALOG_H +#define SETTINGSDIALOG_H + +#include + +#include "ui_settingsdialog.h" + +class LibraryDirectoryModel; + +class SettingsDialog : public QDialog { + Q_OBJECT + + public: + SettingsDialog(QWidget* parent = 0); + + void SetLibraryDirectoryModel(LibraryDirectoryModel* model); + + private slots: + void CurrentTextChanged(const QString& text); + + private: + Ui::SettingsDialog ui_; +}; + +#endif // SETTINGSDIALOG_H diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui new file mode 100644 index 000000000..8d9449a8e --- /dev/null +++ b/src/settingsdialog.ui @@ -0,0 +1,311 @@ + + + SettingsDialog + + + + 0 + 0 + 708 + 549 + + + + Form + + + + + + + 180 + 16777215 + + + + + 32 + 32 + + + + QListView::Static + + + 2 + + + QListView::ListMode + + + true + + + true + + + true + + + + Playback + + + + :/media-playback-start-32.png:/media-playback-start-32.png + + + + + Music Library + + + + :/library.png:/library.png + + + + + Last.fm + + + + :/last.fm/as.png:/last.fm/as.png + + + + + + + + + + + + + Qt::Horizontal + + + + + + + 0 + + + + + 0 + + + + + Fadeout + + + + + + No fadeout + + + + + + + Fadeout + + + + + + + + + Fadeout duration + + + 22 + + + + + + + ms + + + 10000 + + + 2000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + groupBox + verticalSpacer + + + + + 0 + + + + + + + + + + + + + Qt::Horizontal + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + LibraryConfig + QWidget +
libraryconfig.h
+ 1 +
+
+ + list + radioButton + radioButton_2 + spinBox + buttonBox + + + + + + + list + currentRowChanged(int) + stackedWidget + setCurrentIndex(int) + + + 82 + 72 + + + 307 + 96 + + + + + radioButton_2 + toggled(bool) + spinBox + setEnabled(bool) + + + 272 + 108 + + + 369 + 132 + + + + + radioButton_2 + toggled(bool) + label + setEnabled(bool) + + + 248 + 108 + + + 264 + 131 + + + + + buttonBox + accepted() + SettingsDialog + accept() + + + 518 + 524 + + + 521 + 545 + + + + + buttonBox + rejected() + SettingsDialog + reject() + + + 324 + 521 + + + 322 + 549 + + + + +
diff --git a/src/src.pro b/src/src.pro index 01e612104..e01b2e99e 100644 --- a/src/src.pro +++ b/src/src.pro @@ -48,7 +48,10 @@ SOURCES += main.cpp \ edittagdialog.cpp \ lineedit.cpp \ multiloadingindicator.cpp \ - somafmservice.cpp + somafmservice.cpp \ + settingsdialog.cpp \ + librarydirectorymodel.cpp \ + libraryconfigdialog.cpp HEADERS += mainwindow.h \ player.h \ library.h \ @@ -97,7 +100,10 @@ HEADERS += mainwindow.h \ edittagdialog.h \ lineedit.h \ multiloadingindicator.h \ - somafmservice.h + somafmservice.h \ + settingsdialog.h \ + librarydirectorymodel.h \ + libraryconfigdialog.h FORMS += mainwindow.ui \ libraryconfig.ui \ fileview.ui \ @@ -105,7 +111,9 @@ FORMS += mainwindow.ui \ lastfmstationdialog.ui \ trackslider.ui \ edittagdialog.ui \ - multiloadingindicator.ui + multiloadingindicator.ui \ + settingsdialog.ui \ + libraryconfigdialog.ui RESOURCES += ../data/data.qrc OTHER_FILES += ../data/schema.sql \ ../data/mainwindow.css