Full implementation of library manager
authorNikolay Tischenko <niktischenko@gmail.com>
Wed, 20 Oct 2010 17:57:05 +0000 (00:57 +0700)
committerNikolay Tischenko <niktischenko@gmail.com>
Wed, 20 Oct 2010 17:57:05 +0000 (00:57 +0700)
* adding directories
* deleting directories
* updating all directories
* updating selected directories
* updating playlists

21 files changed:
resources/black/update.png [new file with mode: 0644]
resources/resources.qrc
resources/white/update.png [new file with mode: 0644]
src/busywidget.cpp
src/busywidget.h
src/dbstorage.cpp
src/dbstorage.h
src/library.cpp
src/library.h
src/libraryform.cpp
src/mainwindow.cpp
src/mainwindow.h
src/managelibraryform.cpp
src/managelibraryform.h
src/playerform.cpp
src/playerform.h
src/tagresolver.cpp
src/tagresolver.h
src/ui/busywidget.ui
src/ui/mainwindow.ui
src/ui/managelibraryform.ui

diff --git a/resources/black/update.png b/resources/black/update.png
new file mode 100644 (file)
index 0000000..bb76626
Binary files /dev/null and b/resources/black/update.png differ
index 7780bfd..6988e29 100644 (file)
@@ -66,5 +66,7 @@
         <file>white/use.png</file>
         <file>white/volume.png</file>
         <file>white/window.png</file>
+        <file>white/update.png</file>
+        <file>black/update.png</file>
     </qresource>
 </RCC>
diff --git a/resources/white/update.png b/resources/white/update.png
new file mode 100644 (file)
index 0000000..a54934e
Binary files /dev/null and b/resources/white/update.png differ
index cc05758..69113d0 100644 (file)
@@ -33,10 +33,6 @@ BusyWidget::~BusyWidget()
     delete ui;
 }
 
-void BusyWidget::setText(QString text) {
-       ui->label->setText(text);
-}
-
 void BusyWidget::setMax(int max) {
        ui->progressBar->setMaximum(max);
        ui->progressBar->setValue(0);
index 86ab387..011284c 100644 (file)
@@ -33,7 +33,6 @@ class BusyWidget : public QWidget
 public:
        explicit BusyWidget(QWidget *parent = 0);
        ~BusyWidget();
-       void setText(QString text);
 public slots:
        void setMax(int);
        void tick();
index 485a59d..b6e26bd 100644 (file)
@@ -82,8 +82,8 @@ void DbStorage::_prepare_queries() {
                                                                "WHERE track_id IN "
                                                                "(SELECT track_id FROM adding_date ORDER BY date DESC LIMIT 0, :max)");
 
-       _get_track_count = new QSqlQuery(db);
-       _get_track_count->prepare("SELECT count from tracks WHERE id = :id");
+       _get_track_count_query = new QSqlQuery(db);
+       _get_track_count_query->prepare("SELECT count from tracks WHERE id = :id");
 
        _get_tracks_by_pattern_query = new QSqlQuery(db);
        _get_tracks_by_pattern_query->prepare("SELECT id, title, artist, album, source, count, length, year FROM "
@@ -99,6 +99,18 @@ void DbStorage::_prepare_queries() {
        _get_directories_query = new QSqlQuery(db);
        _get_directories_query->prepare("SELECT id, path FROM directories");
 
+       _get_artists_count_query = new QSqlQuery(db);
+       _get_artists_count_query->prepare("SELECT COUNT(id) AS cnt FROM artist");
+
+       _get_albums_count_query = new QSqlQuery(db);
+       _get_albums_count_query->prepare("SELECT COUNT(id) AS cnt FROM album");
+
+       _get_tracks_count_query = new QSqlQuery(db);
+       _get_tracks_count_query->prepare("SELECT COUNT(id) AS cnt FROM tracks");
+
+       _get_tracks_source_from_query = new QSqlQuery(db);
+       _get_tracks_source_from_query->prepare("SELECT source FROM tracks WHERE directory = :directory_id");
+
        _check_artist_query = new QSqlQuery(db);
        _check_artist_query->prepare("SELECT id FROM artist WHERE uname = :uname");
 
@@ -145,6 +157,12 @@ void DbStorage::_prepare_queries() {
                                             "(SELECT COUNT(tracks.id) AS cnt, artist.id FROM "
                                             "artist LEFT OUTER JOIN tracks ON artist.id = tracks.artist_id "
                                             "GROUP BY artist.id) WHERE cnt = 0)");
+
+       _remove_tracks_from_query = new QSqlQuery(db);
+       _remove_tracks_from_query->prepare("DELETE FROM tracks WHERE directory = :directory_id");
+
+       _remove_directory_query = new QSqlQuery(db);
+       _remove_directory_query->prepare("DELETE FROM directories WHERE path = :path");
 }
 
 void DbStorage::_create_database_structure() {
@@ -209,6 +227,10 @@ DbStorage::~DbStorage() {
        delete _get_tracks_for_album_query;
        delete _get_tracks_by_pattern_query;
        delete _get_directories_query;
+       delete _get_artists_count_query;
+       delete _get_albums_count_query;
+       delete _get_tracks_count_query;
+       delete _get_tracks_source_from_query;
        delete _check_album_query;
        delete _check_artist_query;
        delete _check_directory_query;
@@ -221,6 +243,8 @@ DbStorage::~DbStorage() {
        delete _insert_directory_query;
        delete _update_track_count_query;
        delete _remove_track_query;
+       delete _remove_directory_query;
+       delete _remove_tracks_from_query;
        db.close();
 }
 
@@ -446,7 +470,7 @@ void DbStorage::updateTrackCount(Track track) {
        query->exec();
        if (query->next()) {
                int id = query->value(0).toInt();
-               query = _get_track_count;
+               query = _get_track_count_query;
                query->bindValue(":id", id);
                query->exec();
                if (query->next()) {
@@ -570,3 +594,66 @@ QList<QString> DbStorage::getDirectories() {
        }
        return directories;
 }
+
+int DbStorage::getArtistsCount() {
+       QSqlQuery *query = _get_artists_count_query;
+       query->exec();
+       if (query->next()) {
+               return query->value(0).toInt();
+       }
+       return 0;
+}
+
+int DbStorage::getAlbumsCount() {
+       QSqlQuery *query = _get_albums_count_query;
+       query->exec();
+       if (query->next()) {
+               return query->value(0).toInt();
+       }
+       return 0;
+}
+
+int DbStorage::getTracksCount() {
+       QSqlQuery *query = _get_tracks_count_query;
+       query->exec();
+       if (query->next()) {
+               return query->value(0).toInt();
+       }
+       return 0;
+}
+
+void DbStorage::deleteTracksFrom(QString path) {
+       QSqlQuery *query = _check_directory_query;
+       query->bindValue(":path", path);
+       query->exec();
+       if (query->next()) {
+               int id = query->value(0).toInt();
+               query = _remove_tracks_from_query;
+               query->bindValue(":directory_id", id);
+               query->exec();
+               query = _remove_directory_query;
+               query->bindValue(":path", path);
+               query->exec();
+               _cleanup();
+       }
+}
+
+void DbStorage::checkTracksFrom(QString path) {
+       QSqlQuery *query = _check_directory_query;
+       query->bindValue(":path", path);
+       query->exec();
+       if (query->next()) {
+               int id = query->value(0).toInt();
+               query = _get_tracks_source_from_query;
+               query->bindValue(":directory_id", id);
+               query->exec();
+               while (query->next()) {
+                       QString source = query->value(0).toString();
+                       if (!QFile::exists(source)) {
+                               Track track(TrackMetadata(), source);   // removeTrack uses only source field, so
+                               removeTrack(track);                     // we can use this method
+                       }
+               }
+               _cleanup();
+       }
+}
index cc10880..a280fda 100644 (file)
@@ -54,6 +54,10 @@ namespace SomePlayer {
 
                        QList<Track> search(QString pattern);
 
+                       int getArtistsCount();
+                       int getAlbumsCount();
+                       int getTracksCount();
+
                        void removeTrack(Track track);
                        void addToFavorites(Track track);
 
@@ -61,6 +65,9 @@ namespace SomePlayer {
                        Track updateTrack(Track);
                        void addTrack(Track track);
 
+                       void deleteTracksFrom(QString path);
+                       void checkTracksFrom(QString path);
+
                private:
                        QSqlDatabase db;
                        void _create_database_structure();
@@ -81,10 +88,14 @@ namespace SomePlayer {
                        QSqlQuery *_get_most_played_query;
                        QSqlQuery *_get_never_played_query;
                        QSqlQuery *_get_recently_added_query;
-                       QSqlQuery *_get_track_count;
+                       QSqlQuery *_get_track_count_query;
                        QSqlQuery *_get_tracks_by_pattern_query;
                        QSqlQuery *_get_track_id_by_source_query;
                        QSqlQuery *_get_directories_query;
+                       QSqlQuery *_get_artists_count_query;
+                       QSqlQuery *_get_albums_count_query;
+                       QSqlQuery *_get_tracks_count_query;
+                       QSqlQuery *_get_tracks_source_from_query;
 
                        QSqlQuery *_check_artist_query;
                        QSqlQuery *_check_album_query;
@@ -102,6 +113,8 @@ namespace SomePlayer {
                        QSqlQuery *_remove_track_query;
                        QSqlQuery *_remove_empty_artists_query;
                        QSqlQuery *_remove_empty_albums_query;
+                       QSqlQuery *_remove_tracks_from_query;
+                       QSqlQuery *_remove_directory_query;
                };
        };
 };
index ffe1580..58dbf24 100644 (file)
@@ -24,6 +24,7 @@ using namespace SomePlayer::Storage;
 
 #include "mediascanner.h"
 #include <QDir>
+#include <QDebug>
 
 Library::Library(QString databasePath, QString playlistsPath) : QObject(0) {
        _library_storage = new DbStorage(databasePath);
@@ -31,6 +32,7 @@ Library::Library(QString databasePath, QString playlistsPath) : QObject(0) {
        _scanner = new MediaScanner();
        _resolver = new TagResolver(this);
        connect(_scanner, SIGNAL(scanFinish(QStringList)), this, SLOT(_scanned(QStringList)));
+       connect(_resolver, SIGNAL(started()), this, SIGNAL(started()));
        connect(_resolver, SIGNAL(done()), this, SIGNAL(done()));
        connect(_resolver, SIGNAL(decoded(Track)), this, SLOT(_decoded(Track)));
 }
@@ -40,9 +42,10 @@ Library::~Library() {
        delete _playlist_storage;
 }
 
-void Library::addDirectory(QString path) {
+void Library::addDirectory(QString path, bool async) {
        _scanner->init(path);
-       _scanner->start(QThread::LowestPriority);
+       if (async) _scanner->start(QThread::LowestPriority);
+       else _scanner->run();
 }
 
 void Library::addFile(QString path) {
@@ -134,12 +137,12 @@ void Library::saveCurrentPlaylist(const Playlist &playlist) {
 }
 
 void Library::_decoded(Track track) {
-       emit trackAdded();
+       emit tick();
        addTrack(track);
 }
 
 void Library::_scanned(QStringList files) {
-       emit addingTracks(files.count());
+       emit allCount(files.count());
        _resolver->decode(files);
 }
 
@@ -162,3 +165,57 @@ void Library::updateTrackMetadata(Track track) {
 QList<Track> Library::search(QString pattern) {
        return _library_storage->search(pattern);
 }
+
+QList<QString> Library::getDirectories() {
+       return _library_storage->getDirectories();
+}
+
+int Library::getArtistsCount() {
+       return _library_storage->getArtistsCount();
+}
+
+int Library::getAlbumsCount() {
+       return _library_storage->getAlbumsCount();
+}
+
+int Library::getTracksCount() {
+       return _library_storage->getTracksCount();
+}
+
+void Library::updateAll() {
+       QList<QString> directories = _library_storage->getDirectories();
+       updateDirectories(directories);
+}
+
+void Library::updateDirectories(QList<QString> directories) {
+       foreach (QString directory, directories) {
+               _library_storage->checkTracksFrom(directory);
+               addDirectory(directory, false);
+       }
+}
+
+void Library::deleteDirectories(QList<QString> directories) {
+       foreach (QString directory, directories) {
+               _library_storage->deleteTracksFrom(directory);
+       }
+}
+
+void Library::updatePlaylists() {
+       emit started();
+       QList<QString> playlists = getPlaylistsNames();
+       emit allCount(playlists.count());
+       foreach (QString name, playlists) {
+               Playlist playlist = getPlaylist(name);
+               QList<Track> tracks = playlist.tracks();
+               QList<Track> ntracks;
+               foreach (const Track &track, tracks) {
+                       if (QFile::exists(track.source())) {
+                               ntracks.append(track);
+                       }
+               }
+               playlist.setTracks(ntracks);
+               savePlaylist(playlist);
+               emit tick();
+       }
+       emit done();
+}
index 77239b7..36741e0 100644 (file)
@@ -47,9 +47,10 @@ namespace SomePlayer {
                        Library(QString databasePath, QString playlistsPath);
                        ~Library();
 
-                       void addDirectory(QString path);
+                       void addDirectory(QString path, bool async = true);
                        void addFile(QString path);
 
+                       QList<QString> getDirectories();
                        QList<QString> getArtists();
                        QMap<QString, int> getAlbumsForArtist(QString artist);
                        QList<Track> getTracksForAlbum(QString album, QString artist);
@@ -61,6 +62,10 @@ namespace SomePlayer {
                        Playlist getNeverPlayed();
                        Playlist getRecentlyAdded();
 
+                       int getArtistsCount();
+                       int getAlbumsCount();
+                       int getTracksCount();
+
                        QList<Playlist> getPlaylists();
                        QStringList getPlaylistsNames();
                        Playlist getPlaylist(QString name);
@@ -71,11 +76,16 @@ namespace SomePlayer {
                        Playlist getCurrentPlaylist();
                        void saveCurrentPlaylist(const Playlist &playlist);
 
+                       void updateDirectories(QList<QString> directories);
+                       void updateAll();
+                       void deleteDirectories(QList<QString> directories);
+
                signals:
+                       void started();
                        void done();
                        void busy(QString);
-                       void addingTracks(int);
-                       void trackAdded();
+                       void allCount(int);
+                       void tick();
 
                private:
                        DbStorage *_library_storage;
@@ -93,6 +103,7 @@ namespace SomePlayer {
                        void addToFavorites(Track);
                        void updateTrackCount(Track);
                        void updateTrackMetadata(Track);
+                       void updatePlaylists();
                };
 
        };
index 3f9f9ea..3987c80 100644 (file)
@@ -147,6 +147,8 @@ LibraryForm::LibraryForm(Library *lib, QWidget *parent) :
        _top_gradient = ui->topWidget->styleSheet();
        _bottom_gradient = ui->bottomWidget->styleSheet();
        _is_dynamic = false;
+       setAttribute(Qt::WA_Maemo5StackedWindow);
+       setWindowFlags(Qt::Window | windowFlags());
 }
 
 LibraryForm::~LibraryForm()
@@ -524,7 +526,15 @@ void LibraryForm::_toggle_select_all_button() {
                ui->listView->selectionModel()->clearSelection();
                ui->selectAllButton->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
        } else {
+               disconnect(ui->listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+                          this, SLOT(_process_selection(QItemSelection,QItemSelection)));
                ui->listView->selectAll();
+               int cnt = _model->rowCount();
+               for (int i = 0; i < cnt; i++) {
+                       _model->item(i)->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
+               }
+               connect(ui->listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+                          this, SLOT(_process_selection(QItemSelection,QItemSelection)));
                ui->selectAllButton->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
        }
 }
@@ -655,6 +665,7 @@ void LibraryForm::updateIcons() {
                ui->moreButton->setIcon(QIcon(landscape ? ":/icons/"+_icons_theme+"/unmore_l.png" : ":/icons/"+_icons_theme+"/more.png"));
        }
        ui->playlistsButton->setIcon(QIcon(":/icons/"+_icons_theme+"/playlists.png"));
+       ui->playerButton->setIcon(QIcon(":/icons/"+_icons_theme+"/player.png"));
        ui->viewButton->setIcon(QIcon(":/icons/"+_icons_theme+"/artists.png"));
        if (ui->listView->selectionModel()->selectedRows().count() == _model->rowCount()) {
                ui->selectAllButton->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
index 40c5304..a7d3fdc 100644 (file)
@@ -50,16 +50,9 @@ MainWindow::MainWindow(QWidget *parent) :
        _player_form = new PlayerForm(_library, this);
        ui->centralWidget->layout()->addWidget(_player_form);
        _library_form = new LibraryForm(_library, this);
-       _library_form->setAttribute(Qt::WA_Maemo5StackedWindow);
-       _library_form->setWindowFlags(_library_form->windowFlags() | Qt::Window);
-       _busy_widget = new BusyWidget(this);
-       ui->centralWidget->layout()->addWidget(_busy_widget);
-       _busy_widget->hide();
        _timer = new QTimer(this);
        _equalizer_dialog = new EqualizerDialog(this);
        _manage_library_form = new ManageLibraryForm(_library, this);
-       _manage_library_form->setAttribute(Qt::WA_Maemo5StackedWindow);
-       _manage_library_form->setWindowFlags(Qt::Window | _manage_library_form->windowFlags());
        connect(_player_form, SIGNAL(library()), this, SLOT(library()));
        connect(_library_form, SIGNAL(refreshPlayer()), this, SLOT(player()));
        connect(ui->actionManageLibrary, SIGNAL(triggered()), this, SLOT(_manage_library()));
@@ -67,10 +60,9 @@ MainWindow::MainWindow(QWidget *parent) :
        connect(_player_form, SIGNAL(clearPlaylist()), this, SLOT(_clear_current_playlist()));
        connect(ui->actionSetTimer, SIGNAL(triggered()), this, SLOT(_set_timer()));
        connect(ui->actionEqualizer, SIGNAL(triggered()), this, SLOT(_equalizer()));
-       connect(_library, SIGNAL(done()), this, SLOT(library()));
        connect(_library, SIGNAL(done()), _library_form, SLOT(refresh()));
-       connect(_library, SIGNAL(addingTracks(int)), _busy_widget, SLOT(setMax(int)));
-       connect(_library, SIGNAL(trackAdded()), _busy_widget, SLOT(tick()));
+       connect(_player_form, SIGNAL(refreshLibrary()), _library_form, SLOT(refresh()));
+       connect(_manage_library_form, SIGNAL(refreshLibrary()), _library_form, SLOT(refresh()));
        connect(_timer, SIGNAL(timeout()), this, SLOT(_timeout()));
        connect(_equalizer_dialog, SIGNAL(valueChanged(int,int)), this, SLOT(_equalizer_value_changed(int, int)));
        connect(_equalizer_dialog, SIGNAL(equalizerEnabled()), _player_form, SLOT(enableEqualizer()));
@@ -98,6 +90,7 @@ MainWindow::MainWindow(QWidget *parent) :
        }
        _library_form->updateIcons();
        _player_form->updateIcons();
+       _manage_library_form->updateIcons();
        _player_form->checkGradient();
        _library_form->checkGradient();
        setWindowTitle("SomePlayer");
@@ -125,12 +118,11 @@ void MainWindow::library() {
        ui->menuBar->setEnabled(true);
        _library_form->show();
        _orientation_changed(); // workaround
-       _busy_widget->hide();
        _manage_library_form->hide();
-       _player_form->show();
 }
 
 void MainWindow::_manage_library() {
+       _manage_library_form->refresh();
        _manage_library_form->show();
 }
 
@@ -174,13 +166,6 @@ void MainWindow::_clear_current_playlist() {
        _player_form->reload(true);
 }
 
-void MainWindow::showBusyWidget(QString caption) {
-       _busy_widget->setText(caption);
-       ui->menuBar->setEnabled(false);
-       _player_form->hide();
-       _busy_widget->show();
-}
-
 void MainWindow::_add_files() {
        QStringList files = QFileDialog::getOpenFileNames(this, "Add file");
        if (!files.isEmpty()) _player_form->addFiles(files);
@@ -248,6 +233,7 @@ void MainWindow::settings() {
        }
        _player_form->updateIcons();
        _library_form->updateIcons();
+       _manage_library_form->updateIcons();
        _player_form->checkGradient();
        _library_form->checkGradient();
 }
index df6c266..4fc7cd5 100644 (file)
@@ -56,10 +56,8 @@ public slots:
        void player();
        void library();
        void settings();
-       void showBusyWidget(QString);
 private slots:
        void _manage_library();
-//     void _add_directory();
        void _save_playlist();
        void _clear_current_playlist();
        void _add_files();
index 066d4ac..32d0f3d 100644 (file)
 #include "ui_managelibraryform.h"
 #include "library.h"
 #include <QFileDialog>
+#include <QDebug>
+
+#define DEFAULT_PATH_PREFIX "/home/user/MyDocs/"
 
 using namespace SomePlayer::DataObjects;
+using namespace SomePlayer::Storage;
 
 ManageLibraryForm::ManageLibraryForm(Library *library, QWidget *parent) :
                QWidget(parent),
@@ -30,7 +34,27 @@ ManageLibraryForm::ManageLibraryForm(Library *library, QWidget *parent) :
                _library (library)
 {
        ui->setupUi(this);
-       connect(ui->addButton, SIGNAL(clicked()), this, SLOT(add()));
+       setAttribute(Qt::WA_Maemo5StackedWindow);
+       setWindowFlags(Qt::Window | windowFlags());
+       _model = new QStandardItemModel(0, 2, this);
+       ui->dirView->setModel(_model);
+       _busy_widget = new BusyWidget(this);
+       ui->mainLayout->addWidget(_busy_widget);
+       _busy_widget->hide();
+       connect(ui->addButton, SIGNAL(clicked()), this, SLOT(_add()));
+       connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(_delete_selected()));
+       connect(ui->updateButton, SIGNAL(clicked()), this, SLOT(_update_selected()));
+       connect(ui->updateAllButton, SIGNAL(clicked()), this, SLOT(_update_all()));
+       connect(ui->updatePlsButton, SIGNAL(clicked()), _library, SLOT(updatePlaylists()));
+       connect(_library, SIGNAL(allCount(int)), _busy_widget, SLOT(setMax(int)));
+       connect(_library, SIGNAL(tick()), _busy_widget, SLOT(tick()));
+       connect(_library, SIGNAL(done()), _busy_widget, SLOT(hide()));
+       connect(_library, SIGNAL(started()), _busy_widget, SLOT(show()));
+       connect(_library, SIGNAL(done()), this, SLOT(refresh()));
+       connect(ui->dirView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+               this, SLOT(_process_selection(QItemSelection,QItemSelection)));
+       Config config;
+       _icons_theme = config.getValue("ui/iconstheme").toString();
 }
 
 ManageLibraryForm::~ManageLibraryForm()
@@ -38,9 +62,102 @@ ManageLibraryForm::~ManageLibraryForm()
        delete ui;
 }
 
-void ManageLibraryForm::add() {
-       QString directory = QFileDialog::getExistingDirectory (this, "Select directory", "/home/user/MyDocs", QFileDialog::ShowDirsOnly );
+void ManageLibraryForm::_add() {
+       QString directory = QFileDialog::getExistingDirectory (this, "Select directory", DEFAULT_PATH_PREFIX, QFileDialog::ShowDirsOnly );
        if (!directory.isEmpty()) {
                _library->addDirectory(directory);
        }
 }
+
+void ManageLibraryForm::refresh() {
+       QList<QString> directories = _library->getDirectories();
+       qSort(directories);
+       int artists_count = _library->getArtistsCount();
+       int albums_count = _library->getAlbumsCount();
+       int tracks_count = _library->getTracksCount();
+
+       ui->artistsLabel->setText(QString("%1 artists").arg(artists_count));
+       ui->albumsLabel->setText(QString("%1 albums").arg(albums_count));
+       ui->tracksView->setText(QString("%1 tracks").arg(tracks_count));
+
+       int dcount = directories.count();
+       _model->setRowCount(dcount);
+       for (int i = 0; i < dcount; i++) {
+               _model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
+               QString dir = directories.at(i);
+               dir.replace(DEFAULT_PATH_PREFIX, "");
+               _model->setItem(i, 1, new QStandardItem(dir));
+       }
+       ui->dirView->setColumnWidth(0, 70);
+}
+
+void ManageLibraryForm::updateIcons() {
+       Config config;
+       _icons_theme = config.getValue("ui/iconstheme").toString();
+       ui->addButton->setIcon(QIcon(":/icons/"+_icons_theme+"/add.png"));
+       ui->deleteButton->setIcon(QIcon(":/icons/"+_icons_theme+"/delete.png"));
+       ui->updateButton->setIcon(QIcon(":/icons/"+_icons_theme+"/update.png"));
+       ui->updateAllButton->setIcon(QIcon(":/icons/"+_icons_theme+"/update.png"));
+       ui->updatePlsButton->setIcon(QIcon(":/icons/"+_icons_theme+"/update.png"));
+       refresh();
+}
+
+void ManageLibraryForm::_process_selection(QItemSelection selected, QItemSelection deselected) {
+       foreach (QModelIndex id, selected.indexes()) {
+               if (id.column() == 0) {
+                       _model->item(id.row())->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
+               }
+               ui->dirView->selectionModel()->select(id, QItemSelectionModel::Select);
+       }
+       foreach (QModelIndex id, deselected.indexes()) {
+               if (id.column() == 0) {
+                       _model->item(id.row())->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
+               }
+               ui->dirView->selectionModel()->select(id, QItemSelectionModel::Deselect);
+       }
+}
+
+void ManageLibraryForm::_delete_selected() {
+       QList<QString> directories;
+       QModelIndexList idx = ui->dirView->selectionModel()->selectedIndexes();
+       foreach (QModelIndex id, idx) {
+               if (id.column() == 1) {
+                       QString path = id.data().toString();
+                       if (!path.startsWith("/")) {
+                               path = DEFAULT_PATH_PREFIX+path;
+                       }
+                       directories.append(path);
+               }
+       }
+       if (!directories.isEmpty()) {
+               _library->deleteDirectories(directories);
+       }
+       ui->dirView->selectionModel()->clearSelection();
+       refresh();
+       emit refreshLibrary();
+}
+
+void ManageLibraryForm::_update_selected() {
+       QList<QString> directories;
+       QModelIndexList idx = ui->dirView->selectionModel()->selectedIndexes();
+       foreach (QModelIndex id, idx) {
+               if (id.column() == 1) {
+                       QString path = id.data().toString();
+                       if (!path.startsWith("/")) {
+                               path = DEFAULT_PATH_PREFIX+path;
+                       }
+                       directories.append(path);
+               }
+       }
+       if (!directories.isEmpty()) {
+               _library->updateDirectories(directories);
+       }
+       refresh();
+       emit refreshLibrary();
+}
+
+void ManageLibraryForm::_update_all() {
+       _library->updateAll();
+       refresh();
+       emit refreshLibrary();
+}
index 91568b8..99ee295 100644 (file)
 
 #include <QWidget>
 #include "someplayer.h"
+#include <QStandardItemModel>
+#include "config.h"
+#include "busywidget.h"
+#include <QItemSelection>
+#include <QItemSelectionModel>
 
 namespace Ui {
        class ManageLibraryForm;
@@ -37,12 +42,26 @@ public:
        explicit ManageLibraryForm(Library *library, QWidget *parent = 0);
        ~ManageLibraryForm();
 
+signals:
+       void refreshLibrary();
+
+public slots:
+       void refresh();
+       void updateIcons();
+
 private slots:
-       void add();
+       void _add();
+       void _process_selection(QItemSelection, QItemSelection);
+       void _delete_selected();
+       void _update_selected();
+       void _update_all();
 
 private:
        Ui::ManageLibraryForm *ui;
        Library *_library;
+       QStandardItemModel *_model;
+       QString _icons_theme;
+       BusyWidget *_busy_widget;
 };
 
 #endif // MANAGELIBRARYFORM_H
index 567f7b6..f6c657b 100644 (file)
@@ -371,6 +371,7 @@ void PlayerForm::_edit_tags() {
                track.setMetadata(dialog.meta());
                _lib->updateTrackMetadata(track);
                reload(true);
+               emit refreshLibrary();
        }
 }
 
index 1be2824..6cf22be 100644 (file)
@@ -58,6 +58,7 @@ signals:
        void library();
        void fullscreen(bool);
        void clearPlaylist();
+       void refreshLibrary();
 
 public slots:
        void reload(bool);
index b4f90e1..7ec6231 100644 (file)
@@ -32,6 +32,7 @@ TagResolver::TagResolver(QObject *parent) :
 }
 
 void TagResolver::decode(QStringList files) {
+       emit started();
        foreach (QString filename, files) {
                TagLib::FileRef file_ref(QFile::encodeName(filename).data());
                if (!file_ref.isNull()) {
index 459a6c9..972ff41 100644 (file)
@@ -42,6 +42,7 @@ namespace SomePlayer {
                signals:
                        void decoded(Track);
                        void done();
+                       void started();
                };
        };
 };
index c599fd9..f0b125d 100644 (file)
    </rect>
   </property>
   <property name="windowTitle">
-   <string>Form</string>
+   <string/>
   </property>
-    <layout class="QGridLayout" name="gridLayout">
-   <item row="1" column="0">
-    <widget class="QLabel" name="label">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="text">
-      <string>BUSY</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignCenter</set>
-     </property>
-    </widget>
-   </item>
-   <item row="2" column="0">
+  <layout class="QGridLayout" name="gridLayout">
+   <property name="leftMargin">
+    <number>9</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>9</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
+   <property name="spacing">
+    <number>0</number>
+   </property>
+   <item row="0" column="0">
     <widget class="QProgressBar" name="progressBar">
      <property name="value">
       <number>24</number>
      </property>
     </widget>
    </item>
-   <item row="0" column="0">
-    <spacer name="verticalSpacer_2">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>40</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item row="3" column="0">
-    <spacer name="verticalSpacer_3">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>40</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
   </layout>
  </widget>
  <resources/>
index 7da86cc..263d702 100644 (file)
@@ -52,8 +52,8 @@
     <property name="title">
      <string>Tools</string>
     </property>
-    <addaction name="actionEqualizer"/>
     <addaction name="actionSetTimer"/>
+    <addaction name="actionEqualizer"/>
    </widget>
    <widget class="QMenu" name="menuPlayer">
     <property name="title">
@@ -95,6 +95,9 @@
    <property name="text">
     <string>Save playlist</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+S</string>
+   </property>
   </action>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
index beab448..e86d4bc 100644 (file)
@@ -6,14 +6,14 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>553</width>
-    <height>300</height>
+    <width>620</width>
+    <height>394</height>
    </rect>
   </property>
   <property name="windowTitle">
-   <string>Form</string>
+   <string>Manage library</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout_2">
+  <layout class="QVBoxLayout" name="mainLayout">
    <property name="spacing">
     <number>6</number>
    </property>
      </property>
      <item>
       <widget class="QPushButton" name="addButton">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>70</width>
+         <height>70</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>70</width>
+         <height>70</height>
+        </size>
+       </property>
        <property name="text">
-        <string>Add new</string>
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../resources/resources.qrc">
+         <normaloff>:/icons/white/add.png</normaloff>:/icons/white/add.png</iconset>
+       </property>
+       <property name="flat">
+        <bool>true</bool>
        </property>
       </widget>
      </item>
      </item>
      <item>
       <widget class="QPushButton" name="updateButton">
+       <property name="minimumSize">
+        <size>
+         <width>70</width>
+         <height>70</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>70</width>
+         <height>70</height>
+        </size>
+       </property>
+       <property name="text">
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../resources/resources.qrc">
+         <normaloff>:/icons/white/update.png</normaloff>:/icons/white/update.png</iconset>
+       </property>
+       <property name="flat">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_4">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="updateAllButton">
+       <property name="minimumSize">
+        <size>
+         <width>70</width>
+         <height>70</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>70</width>
+         <height>70</height>
+        </size>
+       </property>
        <property name="text">
-        <string>Update</string>
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../resources/resources.qrc">
+         <normaloff>:/icons/white/update.png</normaloff>:/icons/white/update.png</iconset>
+       </property>
+       <property name="flat">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_5">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="updatePlsButton">
+       <property name="minimumSize">
+        <size>
+         <width>70</width>
+         <height>70</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>70</width>
+         <height>70</height>
+        </size>
+       </property>
+       <property name="text">
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../resources/resources.qrc">
+         <normaloff>:/icons/white/update.png</normaloff>:/icons/white/update.png</iconset>
+       </property>
+       <property name="flat">
+        <bool>true</bool>
        </property>
       </widget>
      </item>
      </item>
      <item>
       <widget class="QPushButton" name="deleteButton">
+       <property name="minimumSize">
+        <size>
+         <width>70</width>
+         <height>70</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>70</width>
+         <height>70</height>
+        </size>
+       </property>
        <property name="text">
-        <string>Delete</string>
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../resources/resources.qrc">
+         <normaloff>:/icons/white/delete.png</normaloff>:/icons/white/delete.png</iconset>
+       </property>
+       <property name="flat">
+        <bool>true</bool>
        </property>
       </widget>
      </item>
          <property name="text">
           <string>0 albums</string>
          </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
         </widget>
        </item>
        <item>
          <property name="text">
           <string>0 tracks</string>
          </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
         </widget>
        </item>
       </layout>
    </item>
   </layout>
  </widget>
- <resources/>
+ <resources>
+  <include location="../../resources/resources.qrc"/>
+ </resources>
  <connections/>
 </ui>