Implemented directory browser
authorNikolay Tischenko <niktischenko@gmail.com>
Sat, 30 Oct 2010 21:02:52 +0000 (03:02 +0600)
committerNikolay Tischenko <niktischenko@gmail.com>
Sat, 30 Oct 2010 21:02:52 +0000 (03:02 +0600)
Now user can add any media files to current playlist directly

16 files changed:
resources/black/home.png [new file with mode: 0644]
resources/resources.qrc
resources/white/home.png [new file with mode: 0644]
someplayer.pro
src/directoryview.cpp [new file with mode: 0644]
src/directoryview.h [new file with mode: 0644]
src/mainwindow.cpp
src/mainwindow.h
src/mediascanner.cpp
src/mediascanner.h
src/playerform.cpp
src/playerform.h
src/tagresolver.cpp
src/tagresolver.h
src/ui/directoryview.ui [new file with mode: 0644]
src/ui/libraryform.ui

diff --git a/resources/black/home.png b/resources/black/home.png
new file mode 100644 (file)
index 0000000..2c5816e
Binary files /dev/null and b/resources/black/home.png differ
index 229926f..6774c0d 100644 (file)
@@ -69,5 +69,7 @@
         <file>black/arrow_r.png</file>
         <file>black/directory.png</file>
         <file>white/directory.png</file>
+        <file>black/home.png</file>
+        <file>white/home.png</file>
     </qresource>
 </RCC>
diff --git a/resources/white/home.png b/resources/white/home.png
new file mode 100644 (file)
index 0000000..c857c9c
Binary files /dev/null and b/resources/white/home.png differ
index f46e990..2a1ae52 100644 (file)
@@ -123,7 +123,8 @@ SOURCES += src/main.cpp\
     src/settingsdialog.cpp \
     src/dbusadaptor.cpp \
     src/toolswidget.cpp \
-    src/managelibraryform.cpp
+    src/managelibraryform.cpp \
+    src/directoryview.cpp
 
 HEADERS  += src/mainwindow.h \
                src/player/player.h \
@@ -225,7 +226,8 @@ HEADERS  += src/mainwindow.h \
     src/abstractitemrenderer.h \
     src/dbusadaptor.h \
     src/toolswidget.h \
-    src/managelibraryform.h
+    src/managelibraryform.h \
+    src/directoryview.h
 
 FORMS    += src/ui/mainwindow.ui \
     src/ui/playerform.ui \
@@ -238,7 +240,8 @@ FORMS    += src/ui/mainwindow.ui \
     src/ui/saveplaylistdialog.ui \
     src/ui/settingsdialog.ui \
     src/ui/toolswidget.ui \
-    src/ui/managelibraryform.ui
+    src/ui/managelibraryform.ui \
+    src/ui/directoryview.ui
 
 CONFIG += mobility
 MOBILITY = 
diff --git a/src/directoryview.cpp b/src/directoryview.cpp
new file mode 100644 (file)
index 0000000..60e0839
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * SomePlayer - An alternate music player for Maemo 5
+ * Copyright (C) 2010 Nikolay (somebody) Tischenko <niktischenko@gmail.com>
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "directoryview.h"
+#include "ui_directoryview.h"
+#include <QDir>
+#include <QFileInfo>
+#include "someplayer.h"
+#include <QDebug>
+#include <QRegExp>
+#include "config.h"
+
+using namespace SomePlayer::Storage;
+using namespace SomePlayer::DataObjects;
+
+DirectoryView::DirectoryView(QWidget *parent) :
+               QWidget(parent),
+               ui(new Ui::DirectoryView)
+{
+       ui->setupUi(this);
+       Config config;
+       _icons_theme = config.getValue("ui/iconstheme").toString();
+       REGISTERED_FILE_EXTENSIONS << "mp3" << "flac" << "wma" << "aac" << "ogg";
+       setWindowFlags(windowFlags() | Qt::Window);
+       setAttribute(Qt::WA_Maemo5StackedWindow);
+       _model = new QStandardItemModel(0, 2, this);
+       ui->dirView->setModel(_model);
+       ui->dirView->setColumnHidden(2, true);
+       _current_dir = QDir::homePath();
+       _tagresolver = new TagResolver(this);
+       _mediascanner = new MediaScanner(this);
+
+       ui->addButton->setEnabled(false);
+       ui->addButton->setIcon(QIcon());
+
+       ui->progressBar->hide();
+
+       readDir(_current_dir);
+       connect(ui->backButton, SIGNAL(clicked()), this, SLOT(_back()));
+       connect(ui->dirView, SIGNAL(clicked(QModelIndex)), this, SLOT(_process_click(QModelIndex)));
+       connect(ui->dirView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(_process_dblclick(QModelIndex)));
+       connect(ui->dirView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this,
+               SLOT(_process_selection(QItemSelection,QItemSelection)));
+       connect(ui->homeButton, SIGNAL(clicked()), this, SLOT(_home()));
+       connect(ui->selectToggleButton, SIGNAL(clicked()), this, SLOT(_toggle_selection()));
+       connect(ui->addButton, SIGNAL(clicked()), this, SLOT(_add()));
+       connect(_tagresolver, SIGNAL(decoded(Track)), this, SLOT(_add_track(Track)));
+       connect(_tagresolver, SIGNAL(done()), this, SLOT(_done()));
+       _top_gradient = ui->topWidget->styleSheet();
+       _bottom_gradient = ui->bottomWidget->styleSheet();
+}
+
+DirectoryView::~DirectoryView()
+{
+       delete ui;
+}
+
+void DirectoryView::readDir(QString path) {
+       QDir dir(path);
+       _current_dir = dir.absoluteFilePath(path);
+       _directories.clear();
+       _files.clear();
+       QList<QString> dirnames;
+       QList<QString> filenames;
+       QFileInfoList items = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
+       foreach (QFileInfo info, items) {
+               if (info.isDir()) {
+                       _directories << info.absoluteFilePath();
+                       dirnames << info.fileName();
+               } else {
+                       if (REGISTERED_FILE_EXTENSIONS.contains(info.suffix().toLower())) {
+                               _files << info.absoluteFilePath();
+                               filenames << info.fileName();
+                       }
+               }
+       }
+       _model->setRowCount(dirnames.count() + filenames.count());
+       int i = 0;
+       foreach (QString str, dirnames) {
+               _model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
+               _model->setItem(i, 1, new QStandardItem(str+"/"));
+               i++;
+       }
+       foreach (QString str, filenames) {
+               _model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
+               _model->setItem(i, 1, new QStandardItem(str));
+               i++;
+       }
+       ui->dirView->setColumnWidth(0, 70);
+       ui->addButton->setEnabled(false);
+       ui->addButton->setIcon(QIcon());
+}
+
+void DirectoryView::_back() {
+       readDir(_current_dir+"/..");
+}
+
+void DirectoryView::_process_click(QModelIndex index) {
+       if (index.column() == 0) {
+       } else {
+               QString data = index.data().toString();
+               if (data.endsWith("/")) {
+                       _current_dir = _directories.at(index.row());
+                       readDir(_current_dir);
+                       return;
+               }
+       }
+}
+
+void DirectoryView::_process_dblclick(QModelIndex index) {
+       if (index.column() == 0) {
+       } else {
+               QString data = index.data().toString();
+               if (!data.endsWith("/")) {
+                       QString filename = _files.at(index.row() - _directories.count());
+                       Track track = _tagresolver->decodeOne(filename);
+                       emit addAndPlay(track);
+                       return;
+               }
+       }
+}
+
+void DirectoryView::_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);
+       }
+       if (ui->dirView->selectionModel()->selectedRows().count() > 0) {
+               ui->addButton->setEnabled(true);
+               ui->addButton->setIcon(QIcon(":/icons/"+_icons_theme+"/add.png"));
+       } else {
+               ui->addButton->setEnabled(false);
+               ui->addButton->setIcon(QIcon());
+       }
+}
+
+void DirectoryView::_home() {
+       _current_dir = QDir::homePath();
+       readDir(_current_dir);
+}
+
+void DirectoryView::_toggle_selection() {
+       if (ui->dirView->selectionModel()->selectedRows().count() == _model->rowCount()) {
+               ui->dirView->clearSelection();
+               ui->selectToggleButton->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
+       } else {
+               ui->dirView->selectAll();
+               ui->selectToggleButton->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
+       }
+}
+
+void DirectoryView::_add() {
+       QModelIndexList selected = ui->dirView->selectionModel()->selectedRows(1);
+       QStringList files;
+       QStringList directories;
+       foreach (QModelIndex index, selected) {
+               if (!index.data().toString().endsWith("/")) {
+                       files << _files.at(index.row() - _directories.count());
+               } else {
+                       directories << _directories.at(index.row());
+               }
+       }
+       foreach (QString dir, directories) {
+               files.append(_mediascanner->singleScan(dir));
+       }
+       _tracks.clear();
+       ui->progressBar->setMinimum(0);
+       ui->progressBar->setMaximum(files.count());
+       ui->progressBar->show();
+       _tagresolver->decode(files);
+       ui->dirView->clearSelection();
+}
+
+void DirectoryView::_add_track(Track track) {
+       _tracks.append(track);
+       ui->progressBar->setValue(ui->progressBar->value()+1);
+}
+
+void DirectoryView::_done() {
+       emit addTracks(_tracks);
+       ui->progressBar->hide();
+       _tracks.clear();
+}
+
+void DirectoryView::updateIcons() {
+       Config config;
+       _icons_theme = config.getValue("ui/iconstheme").toString();
+       if (!ui->addButton->icon().isNull())
+               ui->addButton->setIcon(QIcon(":/icons/"+_icons_theme+"/add.png"));
+       ui->homeButton->setIcon(QIcon(":/icons/"+_icons_theme+"/home.png"));
+       ui->backButton->setIcon(QIcon(":/icons/"+_icons_theme+"/back.png"));
+       if (ui->dirView->selectionModel()->selectedRows().count() == _model->rowCount()) {
+               ui->selectToggleButton->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
+       } else {
+               ui->selectToggleButton->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
+       }
+       ui->playerButton->setIcon(QIcon(":/icons/"+_icons_theme+"/player.png"));
+       readDir(_current_dir);
+}
+
+void DirectoryView::updateGradient() {
+       Config config;
+       if (config.getValue("ui/gradient").toString() == "yes") {
+               ui->bottomWidget->setStyleSheet(_bottom_gradient);
+               ui->topWidget->setStyleSheet(_top_gradient);
+       } else {
+               ui->topWidget->setStyleSheet("");
+               ui->bottomWidget->setStyleSheet("");
+       }
+}
+
+void DirectoryView::lanscapeMode() {
+       ui->topWidget->hide();
+       ui->bottomWidget->hide();
+       ui->lverticalLayout->removeItem(ui->lverticalSpacer_0);
+       ui->lverticalLayout->removeItem(ui->lverticalSpacer_1);
+       ui->lverticalLayout->addWidget(ui->backButton);
+       ui->lverticalLayout->addItem(ui->lverticalSpacer_0);
+       ui->lverticalLayout->addWidget(ui->homeButton);
+       ui->lverticalLayout->addItem(ui->lverticalSpacer_1);
+       ui->lverticalLayout->addWidget(ui->playerButton);
+       ui->rverticalLayout->removeItem(ui->rverticalSpacer);
+       ui->rverticalLayout->addWidget(ui->addButton);
+       ui->rverticalLayout->addItem(ui->rverticalSpacer);
+       ui->rverticalLayout->addWidget(ui->selectToggleButton);
+}
+
+void DirectoryView::portraitMode() {
+       ui->lverticalLayout->removeItem(ui->lverticalSpacer_0);
+       ui->lverticalLayout->removeItem(ui->lverticalSpacer_1);
+       ui->rverticalLayout->removeItem(ui->rverticalSpacer);
+       ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_0);
+       ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_1);
+       ui->topWidget->layout()->addWidget(ui->backButton);
+       ui->topWidget->layout()->addItem(ui->thorizontalSpacer_0);
+       ui->topWidget->layout()->addWidget(ui->homeButton);
+       ui->topWidget->layout()->addItem(ui->thorizontalSpacer_1);
+       ui->topWidget->layout()->addWidget(ui->addButton);
+       ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer);
+       ui->bottomWidget->layout()->addWidget(ui->playerButton);
+       ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer);
+       ui->bottomWidget->layout()->addWidget(ui->selectToggleButton);
+       ui->topWidget->show();
+       ui->bottomWidget->show();
+}
diff --git a/src/directoryview.h b/src/directoryview.h
new file mode 100644 (file)
index 0000000..db180ef
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * SomePlayer - An alternate music player for Maemo 5
+ * Copyright (C) 2010 Nikolay (somebody) Tischenko <niktischenko@gmail.com>
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef DIRECTORYVIEW_H
+#define DIRECTORYVIEW_H
+
+#include <QWidget>
+#include <QStandardItemModel>
+#include <QStandardItem>
+#include <QItemSelection>
+#include "tagresolver.h"
+#include "mediascanner.h"
+
+namespace Ui {
+       class DirectoryView;
+}
+
+using SomePlayer::DataObjects::TagResolver;
+using SomePlayer::Storage::MediaScanner;
+using SomePlayer::DataObjects::Track;
+
+class DirectoryView : public QWidget
+{
+       Q_OBJECT
+
+public:
+       explicit DirectoryView(QWidget *parent = 0);
+       ~DirectoryView();
+       void updateIcons();
+       void updateGradient();
+       void lanscapeMode();
+       void portraitMode();
+
+signals:
+       void addAndPlay(Track);
+       void addTracks(QList<Track>);
+
+private:
+       Ui::DirectoryView *ui;
+       QStandardItemModel *_model;
+       QList<QString> REGISTERED_FILE_EXTENSIONS;
+       void readDir(QString path);
+       QList<QString> _directories;
+       QList<QString> _files;
+       QString _icons_theme;
+       QString _current_dir;
+       TagResolver *_tagresolver;
+       MediaScanner *_mediascanner;
+       QList<Track> _tracks;
+       QString _bottom_gradient;
+       QString _top_gradient;
+
+private slots:
+       void _back();
+       void _home();
+       void _toggle_selection();
+       void _add();
+       void _add_track(Track);
+       void _done();
+       void _process_click(QModelIndex);
+       void _process_dblclick(QModelIndex);
+       void _process_selection(QItemSelection, QItemSelection);
+
+};
+
+#endif // DIRECTORYVIEW_H
index 67b1399..9f3dd12 100644 (file)
@@ -50,6 +50,8 @@ MainWindow::MainWindow(QWidget *parent) :
        _player_form = new PlayerForm(_library, this);
        ui->centralWidget->layout()->addWidget(_player_form);
        _library_form = new LibraryForm(_library, this);
+       _directory_form = new DirectoryView(this);
+       _directory_form->hide();
        _timer = new QTimer(this);
        _equalizer_dialog = new EqualizerDialog(this);
        _manage_library_form = new ManageLibraryForm(_library, this);
@@ -70,6 +72,9 @@ MainWindow::MainWindow(QWidget *parent) :
        connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(_orientation_changed()));
        connect(_player_form, SIGNAL(fullscreen(bool)), this, SLOT(_fullscreen(bool)));
        connect(_library_form, SIGNAL(addAndPlay(Track)), _player_form, SLOT(play(Track)));
+       connect(_directory_form, SIGNAL(addAndPlay(Track)), _player_form, SLOT(play(Track)));
+       connect(_player_form, SIGNAL(dirView()), _directory_form, SLOT(show()));
+       connect(_directory_form, SIGNAL(addTracks(QList<Track>)), this, SLOT(_add_tracks(QList<Track>)));
        _player_form->reload(true);
        QString mode = config.getValue("ui/orientation").toString();
        if (mode == "landscape") {
@@ -77,22 +82,27 @@ MainWindow::MainWindow(QWidget *parent) :
                _player_form->landscapeMode();
                _library_form->landscapeMode();
                _equalizer_dialog->landscapeMode();
+               _directory_form->lanscapeMode();
        } else if (mode == "portrait") {
                setAttribute(Qt::WA_Maemo5PortraitOrientation);
                _player_form->portraitMode();
                _library_form->portraitMode();
                _equalizer_dialog->portraitMode();
+               _directory_form->portraitMode();
        } else if (mode == "auto") { // initialization in landscape
                _player_form->landscapeMode();
                _library_form->landscapeMode();
                _equalizer_dialog->landscapeMode();
+               _directory_form->lanscapeMode();
                setAttribute(Qt::WA_Maemo5AutoOrientation);
        }
        _library_form->updateIcons();
        _player_form->updateIcons();
        _manage_library_form->updateIcons();
+       _directory_form->updateIcons();
        _player_form->checkGradient();
        _library_form->checkGradient();
+       _directory_form->updateGradient();
        setWindowTitle("SomePlayer");
 }
 
@@ -249,6 +259,8 @@ void MainWindow::settings() {
        _manage_library_form->updateIcons();
        _player_form->checkGradient();
        _library_form->checkGradient();
+       _directory_form->updateIcons();
+       _directory_form->updateGradient();
 }
 
 void MainWindow::_orientation_changed() {
@@ -257,10 +269,12 @@ void MainWindow::_orientation_changed() {
                _player_form->landscapeMode();
                _library_form->landscapeMode();
                _equalizer_dialog->landscapeMode();
+               _directory_form->lanscapeMode();
        } else {
                _player_form->portraitMode();
                _library_form->portraitMode();
                _equalizer_dialog->portraitMode();
+               _directory_form->portraitMode();
        }
 }
 
@@ -268,3 +282,12 @@ void MainWindow::_fullscreen(bool f) {
        if (f) showFullScreen();
        else showNormal();
 }
+
+void MainWindow::_add_tracks(QList<Track> tracks) {
+       Playlist cur = _library->getCurrentPlaylist();
+       foreach (Track track, tracks) {
+               cur.addTrack(track);
+       }
+       _library->saveCurrentPlaylist(cur);
+       _player_form->reload(true);
+}
index 0212d06..fbfc860 100644 (file)
@@ -27,6 +27,7 @@
 #include "busywidget.h"
 #include "equalizerdialog.h"
 #include "managelibraryform.h"
+#include "directoryview.h"
 #include "library.h"
 #include <QTimer>
 
@@ -35,6 +36,7 @@ namespace Ui {
 }
 
 using SomePlayer::DataObjects::Library;
+using SomePlayer::DataObjects::Track;
 
 class MainWindow : public QMainWindow
 {
@@ -66,10 +68,12 @@ private slots:
        void _equalizer_value_changed(int, int);
        void _orientation_changed();
        void _fullscreen(bool);
+       void _add_tracks(QList<Track>);
 private:
        PlayerForm *_player_form;
        LibraryForm *_library_form;
        BusyWidget *_busy_widget;
+       DirectoryView *_directory_form;
        Library *_library;
        QTimer *_timer;
        EqualizerDialog *_equalizer_dialog;
index f6a32c1..0fc2d37 100644 (file)
@@ -35,11 +35,17 @@ void MediaScanner::run() {
                return;
        _foundMedia.clear();
        _scan_directory(_dir);
+       _foundMedia = _scan_directory(_dir);
        emit scanFinish(_foundMedia);
        _stopped = true;
 }
 
-void MediaScanner::_scan_directory(QDir dir) {
+QStringList MediaScanner::singleScan(QString path) {
+       _dir = path;
+       return _scan_directory(_dir);
+}
+
+QStringList MediaScanner::_scan_directory(QDir dir) {
        QFileInfoList items = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
        foreach (QFileInfo info, items) {
                if (info.isDir()) {
@@ -53,6 +59,7 @@ void MediaScanner::_scan_directory(QDir dir) {
                        }
                }
        }
+       return _foundMedia;
 }
 
 void MediaScanner::stop() {
index 8a33e2c..151bf3d 100644 (file)
@@ -36,6 +36,7 @@ namespace SomePlayer {
                public:
                        explicit MediaScanner(QObject *parent = 0);
                        void run();
+                       QStringList singleScan(QString);
 
                signals:
                        void scanFinish(QStringList);
@@ -49,7 +50,7 @@ namespace SomePlayer {
                        QStringList REGISTERED_FILE_EXTENSIONS;
                        QStringList _foundMedia;
 
-                       void _scan_directory(QDir);
+                       QStringList _scan_directory(QDir);
                };
 
        };
index f01eb99..83b0ee1 100644 (file)
@@ -394,7 +394,7 @@ void PlayerForm::stop() {
 }
 
 void PlayerForm::_dirview() {
-
+       emit dirView();
 }
 
 void PlayerForm::landscapeMode() {
@@ -556,5 +556,11 @@ void PlayerForm::play(Track track) {
        if (id >= 0) {
                _player->setTrackId(id);
                _player->play();
+       } else {
+               _current_playlist.addTrack(track);
+               _lib->saveCurrentPlaylist(_current_playlist);
+               reload(true);
+               _player->setTrackId(_current_playlist.tracks().count()-1);
+               _player->play();
        }
 }
index 21ab858..cbfa802 100644 (file)
@@ -60,6 +60,7 @@ signals:
        void fullscreen(bool);
        void clearPlaylist();
        void refreshLibrary();
+       void dirView();
 
 public slots:
        void reload(bool);
index 7ec6231..efa81c3 100644 (file)
@@ -74,3 +74,31 @@ void TagResolver::updateTags(Track track) {
                file_ref.save();
        }
 }
+
+Track TagResolver::decodeOne(QString filename) {
+       TagLib::FileRef file_ref(QFile::encodeName(filename).data());
+       if (!file_ref.isNull()) {
+               TagLib::Tag *tag = file_ref.tag();
+               if (NULL != tag) {
+                       TagLib::AudioProperties *properties = file_ref.audioProperties();
+                       if (NULL != properties) {
+                               TrackMetadata meta(QString::fromStdWString(tag->title().toWString()),
+                                                  QString::fromStdWString(tag->artist().toWString()),
+                                                  QString::fromStdWString(tag->album().toWString()),
+                                                  properties->length());
+                               meta.setYear(tag->year());
+                               Track track(meta, filename);
+                               return track;
+                       }
+               }
+       } else { // workaround
+               TrackMetadata meta;
+               meta.setLength(0);
+               QFileInfo fi(filename);
+               meta.setArtist(fi.suffix().toUpper());
+               meta.setTitle(fi.baseName());
+               Track track(meta, filename);
+               return track;
+       }
+       return Track();
+}
index 972ff41..074d5b4 100644 (file)
@@ -38,6 +38,7 @@ namespace SomePlayer {
                public slots:
                        void decode (QStringList files);
                        void updateTags(Track);
+                       Track decodeOne (QString filepath);
 
                signals:
                        void decoded(Track);
diff --git a/src/ui/directoryview.ui b/src/ui/directoryview.ui
new file mode 100644 (file)
index 0000000..0485509
--- /dev/null
@@ -0,0 +1,406 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DirectoryView</class>
+ <widget class="QWidget" name="DirectoryView">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>480</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Directories</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout_3">
+   <property name="spacing">
+    <number>0</number>
+   </property>
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <item>
+    <layout class="QVBoxLayout" name="lverticalLayout">
+     <property name="spacing">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QPushButton" name="backButton">
+       <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/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../resources/resources.qrc">
+         <normaloff>:/icons/white/back.png</normaloff>:/icons/white/back.png</iconset>
+       </property>
+       <property name="flat">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="lverticalSpacer_0">
+       <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>
+      <widget class="QPushButton" name="homeButton">
+       <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="text">
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../resources/resources.qrc">
+         <normaloff>:/icons/white/home.png</normaloff>:/icons/white/home.png</iconset>
+       </property>
+       <property name="flat">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="lverticalSpacer_1">
+       <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>
+      <widget class="QPushButton" name="playerButton">
+       <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/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../resources/resources.qrc">
+         <normaloff>:/icons/white/player.png</normaloff>:/icons/white/player.png</iconset>
+       </property>
+       <property name="flat">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <property name="spacing">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QWidget" name="topWidget" native="true">
+       <property name="styleSheet">
+        <string notr="true">background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(38, 38, 38, 255), stop:1 rgba(92, 92, 92, 255))</string>
+       </property>
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <property name="spacing">
+         <number>0</number>
+        </property>
+        <property name="margin">
+         <number>0</number>
+        </property>
+        <item>
+         <spacer name="thorizontalSpacer_0">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Maximum</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>324</width>
+            <height>0</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <spacer name="thorizontalSpacer_1">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Maximum</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>327</width>
+            <height>0</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <widget class="QTableView" name="dirView">
+       <property name="contextMenuPolicy">
+        <enum>Qt::CustomContextMenu</enum>
+       </property>
+       <property name="frameShadow">
+        <enum>QFrame::Sunken</enum>
+       </property>
+       <property name="horizontalScrollBarPolicy">
+        <enum>Qt::ScrollBarAlwaysOff</enum>
+       </property>
+       <property name="autoScroll">
+        <bool>false</bool>
+       </property>
+       <property name="editTriggers">
+        <set>QAbstractItemView::NoEditTriggers</set>
+       </property>
+       <property name="showDropIndicator" stdset="0">
+        <bool>false</bool>
+       </property>
+       <property name="dragEnabled">
+        <bool>false</bool>
+       </property>
+       <property name="dragDropOverwriteMode">
+        <bool>false</bool>
+       </property>
+       <property name="dragDropMode">
+        <enum>QAbstractItemView::NoDragDrop</enum>
+       </property>
+       <property name="selectionMode">
+        <enum>QAbstractItemView::MultiSelection</enum>
+       </property>
+       <property name="selectionBehavior">
+        <enum>QAbstractItemView::SelectRows</enum>
+       </property>
+       <property name="iconSize">
+        <size>
+         <width>50</width>
+         <height>50</height>
+        </size>
+       </property>
+       <property name="showGrid">
+        <bool>false</bool>
+       </property>
+       <property name="cornerButtonEnabled">
+        <bool>false</bool>
+       </property>
+       <attribute name="horizontalHeaderVisible">
+        <bool>false</bool>
+       </attribute>
+       <attribute name="horizontalHeaderStretchLastSection">
+        <bool>true</bool>
+       </attribute>
+       <attribute name="verticalHeaderVisible">
+        <bool>false</bool>
+       </attribute>
+       <attribute name="verticalHeaderDefaultSectionSize">
+        <number>70</number>
+       </attribute>
+       <attribute name="verticalHeaderMinimumSectionSize">
+        <number>70</number>
+       </attribute>
+      </widget>
+     </item>
+     <item>
+      <widget class="QProgressBar" name="progressBar">
+       <property name="value">
+        <number>24</number>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QWidget" name="bottomWidget" native="true">
+       <property name="styleSheet">
+        <string notr="true">background:qlineargradient(spread:pad, x1:1, y1:1, x2:1, y2:0, stop:0 rgba(38, 38, 38, 255), stop:1 rgba(92, 92, 92, 255))</string>
+       </property>
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <property name="spacing">
+         <number>0</number>
+        </property>
+        <property name="margin">
+         <number>0</number>
+        </property>
+        <item>
+         <spacer name="bhorizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>651</width>
+            <height>0</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QVBoxLayout" name="rverticalLayout">
+     <property name="spacing">
+      <number>0</number>
+     </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/>
+       </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>
+      <spacer name="rverticalSpacer">
+       <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>
+      <widget class="QPushButton" name="selectToggleButton">
+       <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/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../resources/resources.qrc">
+         <normaloff>:/icons/white/select_all.png</normaloff>:/icons/white/select_all.png</iconset>
+       </property>
+       <property name="flat">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../../resources/resources.qrc"/>
+ </resources>
+ <connections>
+  <connection>
+   <sender>playerButton</sender>
+   <signal>clicked()</signal>
+   <receiver>DirectoryView</receiver>
+   <slot>hide()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>35</x>
+     <y>443</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>399</x>
+     <y>239</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
index 918c94b..ac90790 100644 (file)
@@ -11,7 +11,7 @@
    </rect>
   </property>
   <property name="windowTitle">
-   <string>SomePlayer Library</string>
+   <string>Library</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_2">
    <property name="spacing">
           <string/>
          </property>
          <property name="icon">
-          <iconset resource="../../resources/resources.qrc">
+          <iconset>
            <normaloff>:/icons/white/back.png</normaloff>:/icons/white/back.png</iconset>
          </property>
          <property name="flat">
           <string/>
          </property>
          <property name="icon">
-          <iconset resource="../../resources/resources.qrc">
+          <iconset>
            <normaloff>:/icons/white/add.png</normaloff>:/icons/white/add.png</iconset>
          </property>
          <property name="flat">
           <string/>
          </property>
          <property name="icon">
-          <iconset resource="../../resources/resources.qrc">
+          <iconset>
            <normaloff>:/icons/white/delete.png</normaloff>:/icons/white/delete.png</iconset>
          </property>
          <property name="flat">
           <string/>
          </property>
          <property name="icon">
-          <iconset resource="../../resources/resources.qrc">
+          <iconset>
            <normaloff>:/icons/white/use.png</normaloff>:/icons/white/use.png</iconset>
          </property>
          <property name="flat">
           <string/>
          </property>
          <property name="icon">
-          <iconset resource="../../resources/resources.qrc">
+          <iconset>
            <normaloff>:/icons/white/player.png</normaloff>:/icons/white/player.png</iconset>
          </property>
          <property name="flat">
           <string/>
          </property>
          <property name="icon">
-          <iconset resource="../../resources/resources.qrc">
+          <iconset>
            <normaloff>:/icons/white/more.png</normaloff>:/icons/white/more.png</iconset>
          </property>
          <property name="flat">
           <string/>
          </property>
          <property name="icon">
-          <iconset resource="../../resources/resources.qrc">
+          <iconset>
            <normaloff>:/icons/white/select_all.png</normaloff>:/icons/white/select_all.png</iconset>
          </property>
          <property name="flat">
           <string/>
          </property>
          <property name="icon">
-          <iconset resource="../../resources/resources.qrc">
+          <iconset>
            <normaloff>:/icons/white/artists.png</normaloff>:/icons/white/artists.png</iconset>
          </property>
          <property name="flat">
           <string/>
          </property>
          <property name="icon">
-          <iconset resource="../../resources/resources.qrc">
+          <iconset>
            <normaloff>:/icons/white/playlists.png</normaloff>:/icons/white/playlists.png</iconset>
          </property>
          <property name="flat">
           <string/>
          </property>
          <property name="icon">
-          <iconset resource="../../resources/resources.qrc">
+          <iconset>
            <normaloff>:/icons/white/dynamic.png</normaloff>:/icons/white/dynamic.png</iconset>
          </property>
          <property name="flat">
    </item>
   </layout>
  </widget>
- <resources>
-  <include location="../../resources/resources.qrc"/>
- </resources>
+ <resources/>
  <connections/>
 </ui>