src/tagresolver.cpp \
src/playerform.cpp \
src/libraryform.cpp \
- src/busywidget.cpp
+ src/busywidget.cpp \
+ src/trackrenderer.cpp
HEADERS += src/mainwindow.h \
src/player/player.h \
src/tagresolver.h \
src/playerform.h \
src/libraryform.h \
- src/busywidget.h
+ src/busywidget.h \
+ src/trackrenderer.h
FORMS += src/ui/mainwindow.ui \
src/ui/playerform.ui \
"JOIN album ON album_id = album.id "
"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");
+
_check_artist_query = new QSqlQuery(db);
_check_artist_query->prepare("SELECT id FROM artist WHERE name = :name");
}
void DbStorage::updateTrackCount(Track track) {
- QSqlQuery *query = _update_track_count_query;
- query->bindValue(":count", track.count());
+ QSqlQuery *query = _get_track_count;
query->bindValue(":id", track.id());
query->exec();
+ if (query->next()) {
+ int count = query->value(0).toInt();
+ query = _update_track_count_query;
+ query->bindValue(":count", count+1);
+ query->bindValue(":id", track.id());
+ query->exec();
+ }
}
int DbStorage::_check_add_artist(QString artist) {
QSqlQuery *_get_most_played_query;
QSqlQuery *_get_never_played_query;
QSqlQuery *_get_recently_added_query;
+ QSqlQuery *_get_track_count;
QSqlQuery *_check_artist_query;
QSqlQuery *_check_album_query;
FileStorage::FileStorage(QString path) {
_path_prefix = path;
- _meta_regexp.setPattern("#META \\[(\\d+)\\].*::(.+)::,::(.+)::,::(.+)::");
+ _meta_regexp.setPattern("#META\\ +\\[(\\d+)\\]\\[(\\d+)\\].*::(.+)::,::(.+)::,::(.+)::");
_path_regexp.setPattern("#PATH (.+)");
Playlist current = getCurrentPlaylist();
playlistFile.open(QFile::ReadOnly);
QTextStream stream(&playlistFile);
QString buffer = stream.readLine();
- int index = 0;
if (buffer.startsWith(_PLAYLIST_SIGNATURE_)) {
while (!stream.atEnd()) {
buffer = stream.readLine();
if (_meta_regexp.indexIn(buffer) != -1) {
- int seconds = _meta_regexp.cap(1).toInt();
- QString artist = _meta_regexp.cap(2);
- QString album = _meta_regexp.cap(3);
- QString title = _meta_regexp.cap(4);
+ int id = _meta_regexp.cap(1).toInt();
+ int seconds = _meta_regexp.cap(2).toInt();
+ QString artist = _meta_regexp.cap(3);
+ QString album = _meta_regexp.cap(4);
+ QString title = _meta_regexp.cap(5);
buffer = stream.readLine();
if (_path_regexp.indexIn(buffer) != -1) {
QString source = _path_regexp.cap(1);
TrackMetadata meta(title, artist, album, seconds);
- Track track(index++, meta, source);
+ Track track(id, meta, source);
playlist.addTrack(track);
}
}
stream << _PLAYLIST_SIGNATURE_ << endl;
const QList<Track> &tracks = playlist.tracks();
foreach (Track track, tracks) {
- stream << _PLAYLIST_META_KEYWORD_ << " [" << track.metadata().length() << "],::" << track.metadata().artist()
- << "::,::" << track.metadata().album() << "::,::" << track.metadata().title() << "::" << endl;
+ stream << _PLAYLIST_META_KEYWORD_ << " [" << track.id() << "]" << "[" << track.metadata().length() << "],::"
+ << track.metadata().artist() << "::,::" << track.metadata().album() << "::,::"
+ << track.metadata().title() << "::" << endl;
stream << _PLAYLIST_PATH_KEYWORD_ << " " << track.source() << endl;
}
}
// format:
/*
#SOMEPLAYLIST
- #META [seconds],::artist::,::album::,::title::
+ #META [ID][seconds],::artist::,::album::,::title::
#PATH file_path
- #META [seconds],::artist::,::album::,::title::
+ #META [ID][seconds],::artist::,::album::,::title::
#PATH file_path
...
*/
_scanner = new MediaScanner();
_resolver = new TagResolver(this);
connect(_scanner, SIGNAL(scanFinish(QStringList)), _resolver, SLOT(decode(QStringList)));
- connect(_resolver, SIGNAL(done()), this, SIGNAL(addingDone()));
+ connect(_resolver, SIGNAL(done()), this, SIGNAL(done()));
connect(_resolver, SIGNAL(decoded(Track)), this, SLOT(addTrack(Track)));
}
void saveCurrentPlaylist(const Playlist &playlist);
signals:
- void addingDone();
+ void done();
+ void busy(QString);
private:
DbStorage *_library_storage;
connect(ui->playerButton, SIGNAL(clicked()), this, SLOT(_player()));
connect(ui->viewButton, SIGNAL(clicked()), this, SLOT(_view_button()));
connect(ui->playlistsButton, SIGNAL(clicked()), this, SLOT(_playlists_button()));
+ connect(ui->dynamicButton, SIGNAL(clicked()), this, SLOT(_dynamic_button()));
connect(ui->listView, SIGNAL(clicked(QModelIndex)), this, SLOT(_process_list_click(QModelIndex)));
connect(ui->addButton, SIGNAL(clicked()), this, SLOT(_add_button()));
connect(ui->backButton, SIGNAL(clicked()), this, SLOT(_back_button()));
connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(_delete_button()));
+ connect(ui->useButton, SIGNAL(clicked()), this, SLOT(_use_button()));
_view_button();
}
ui->backButton->setEnabled(false);
ui->listLabel->setText("Artists");
ui->addButton->setEnabled(true);
- ui->deleteButton->setEnabled(false);
+ ui->deleteButton->hide();
+ ui->useButton->hide();
}
void LibraryForm::_dynamic_button() {
+ ui->useButton->hide();
+ ui->backButton->setEnabled(false);
+ ui->addButton->setEnabled(true);
+ _model->clear();
+ _model->setRowCount(4);
+ _model->setItem(0, new QStandardItem("Favorites"));
+ _model->setItem(1, new QStandardItem("Most played"));
+ _model->setItem(2, new QStandardItem("Never played"));
+ _model->setItem(3, new QStandardItem("Recently added"));
+ _state = STATE_DYNAMIC;
}
void LibraryForm::_process_list_click(QModelIndex index) {
break;
case STATE_PLAYLIST:
{
- Playlist playlist = _lib->getPlaylist(data);
- _current_tracks = playlist.tracks();
+ _current_playlist = _lib->getPlaylist(data);
+ _current_tracks = _current_playlist.tracks();
__fill_model_tracks(_model, _current_tracks);
_state = STATE_PLAYLIST_TRACK;
ui->backButton->setEnabled(true);
- ui->deleteButton->setEnabled(true);
+ ui->deleteButton->show();
+ ui->useButton->show();
ui->listLabel->setText(QString("Tracks in playlist \"%1\"").arg(data));
}
break;
+ case STATE_DYNAMIC:
+ {
+ switch(index.row()) {
+ case 0: //favorites
+ _current_playlist = _lib->getFavorites();
+ break;
+ case 1: //most played
+ _current_playlist = _lib->getMostPlayed();
+ break;
+ case 2: //never played
+ _current_playlist = _lib->getNeverPlayed();
+ case 3: //recently added
+ _current_playlist = _lib->getRecentlyAdded();
+ break;
+ default:
+ return;
+ }
+ _current_tracks = _current_playlist.tracks();
+ __fill_model_tracks(_model, _current_tracks);
+ _state = STATE_PLAYLIST_TRACK;
+ ui->backButton->setEnabled(true);
+ ui->useButton->show();
+ ui->listLabel->setText(_current_playlist.name());
+ }
default:
return;
}
if (_state == STATE_NONE) return;
QModelIndexList selected = ui->listView->selectionModel()->selectedIndexes();
ui->listView->selectionModel()->clearSelection();
+ emit busy(QString("<H1>Adding... Please wait</H1>"));
switch (_state) {
case STATE_ARTIST:
foreach (QModelIndex id, selected) {
}
break;
default:
+ emit done();
return;
}
+ emit done();
}
ui->backButton->setEnabled(false);
ui->listLabel->setText("Playlists");
ui->addButton->setEnabled(false);
+ ui->deleteButton->hide();
+ ui->useButton->hide();
}
void LibraryForm::_delete_button() {
current.removeTrack(track);
_lib->saveCurrentPlaylist(current);
}
+
+void LibraryForm::_use_button() {
+ _lib->saveCurrentPlaylist(_current_playlist);
+}
#include <QStandardItemModel>
#include <QStandardItem>
#include <QModelIndex>
+#include "playlist.h"
namespace Ui {
class LibraryForm;
using SomePlayer::DataObjects::Track;
using SomePlayer::DataObjects::Playlist;
-enum LibraryFormListState {STATE_NONE, STATE_ARTIST, STATE_ALBUM, STATE_TRACK, STATE_PLAYLIST, STATE_PLAYLIST_TRACK};
+enum LibraryFormListState {STATE_NONE, STATE_ARTIST, STATE_ALBUM, STATE_TRACK, STATE_PLAYLIST, STATE_PLAYLIST_TRACK, STATE_DYNAMIC};
class LibraryForm : public QWidget
{
~LibraryForm();
signals:
void player();
+ void busy(QString);
+ void done();
private slots:
void _player();
void _view_button();
void _add_button();
void _delete_button();
void _back_button();
+ void _use_button();
void _process_list_click(QModelIndex);
private:
LibraryFormListState _state;
QString _current_artist;
QString _current_album;
+ Playlist _current_playlist;
QList<Track> _current_tracks;
void _add_artist(QString artist);
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
+#include <QInputDialog>
#include <QFile>
#include "player/player.h"
ui->stackedWidget->insertWidget(2, _busy_widget);
_library_menu = new QMenu("Lirary");
QAction *add_directory = _library_menu->addAction("Add directory");
+ QAction *save_playlist = _library_menu->addAction("Save playlist");
+ QAction *clear_playlist = _library_menu->addAction("Clear current playlist");
_player_menu = new QMenu("Player");
connect(_player_form, SIGNAL(library()), this, SLOT(library()));
connect(_library_form, SIGNAL(player()), this, SLOT(player()));
connect(add_directory, SIGNAL(triggered()), this, SLOT(_add_directory()));
- connect(_library, SIGNAL(addingDone()), this, SLOT(library()));
+ connect(save_playlist, SIGNAL(triggered()), this, SLOT(_save_playlist()));
+ connect(clear_playlist, SIGNAL(triggered()), this, SLOT(_clear_current_playlist()));
+ connect(_library, SIGNAL(done()), this, SLOT(library()));
+ connect(_library_form, SIGNAL(done()), this, SLOT(library()));
+ connect(_library_form, SIGNAL(busy(QString)), this, SLOT(showBusyWidget(QString)));
library();
}
void MainWindow::_add_directory() {
QString directory = QFileDialog::getExistingDirectory (this, "Select directory", "/home/user/MyDocs", QFileDialog::ShowDirsOnly );
if (!directory.isEmpty()) {
- _busy_widget->setText("<H1>Scanning... Please wait</H1>");
- ui->menuBar->setEnabled(false);
- ui->stackedWidget->setCurrentIndex(2);
+ showBusyWidget("<H1>Scanning... Please wait</H1>");
_library->addDirectory(directory);
}
}
+
+void MainWindow::_save_playlist() {
+ QString name = QInputDialog::getText(this, "Playlist name", "Name:");
+ Playlist playlist = _library->getCurrentPlaylist();
+ playlist.setName(name);
+ _library->savePlaylist(playlist);
+}
+
+void MainWindow::_clear_current_playlist() {
+ Playlist playlist = _library->getCurrentPlaylist();
+ playlist.clear();
+ _library->saveCurrentPlaylist(playlist);
+ _player_form->reload();
+}
+
+void MainWindow::showBusyWidget(QString caption) {
+ _busy_widget->setText(caption);
+ ui->menuBar->setEnabled(false);
+ ui->stackedWidget->setCurrentIndex(2);
+}
void about();
void player();
void library();
+ void showBusyWidget(QString);
private slots:
void _add_directory();
+ void _save_playlist();
+ void _clear_current_playlist();
private:
PlayerForm *_player_form;
LibraryForm *_library_form;
connect(_player, SIGNAL(tick(qint64)), this, SLOT(_tick(qint64)));
Phonon::createPath(_player, _output);
int seed = reinterpret_cast<int> (_player);
- srand(seed);
+ qsrand(seed);
_random = false;
_repeat = false;
}
void Player::setTrackId(int id) {
_current = id;
- _history.push(_current);
+ if (!_history.isEmpty() && _history.top() != _current || _history.isEmpty()) {
+ _history.push(_current);
+ }
+ _track = _playlist.tracks().at(_current);
_set_source();
_state = PLAYER_LOADING;
emit stateChanged(_state);
}
-void Player::play() {
- _player->play();
- _state = PLAYER_PLAYING;
- emit stateChanged(_state);
+void Player::toggle() {
+ if (_state == PLAYER_PLAYING) { // pause
+ _player->pause();
+ _state = PLAYER_PAUSED;
+ emit stateChanged(_state);
+ } else { //play
+ play();
+ }
}
void Player::stop() {
emit stateChanged(_state);
}
-void Player::pause() {
- _player->pause();
- _state = PLAYER_PAUSED;
- emit stateChanged(_state);
-}
-
void Player::next() {
- _history.push(_current);
- if (_random) {
- _current = rand() % _playlist.tracks().count();
+ int count = _playlist.tracks().count();
+ if (count == 0) {
+ stop(); // empty playlist
+ return;
+ }
+ _history.push(_current % count);
+ if (!_queue.isEmpty()) {
+ _current = _queue.dequeue();
} else {
- _current = (_current + 1) % _playlist.tracks().count();
+ if (_random) {
+ _current = (count + (qrand() + qrand() + qrand()) % count) % count;
+ } else {
+ _current = _current + 1;
+ }
}
- if (_history.count()-1 == _playlist.tracks().count() && !_repeat) {
+ if (_random && _history.count() >= count && !_repeat ||
+ !_repeat && _current >= count) {
_history.clear();
stop();
} else {
+ _current %= count;
+ _track = _playlist.tracks().at(_current);
_set_source();
play();
}
}
void Player::_set_source() {
- Track track = _playlist.tracks().at(_current);
- _player->setCurrentSource(Phonon::MediaSource(track.source()));
- emit trackChanged(track);
+ _player->setCurrentSource(Phonon::MediaSource(_track.source()));
+ emit trackChanged(_track);
}
void Player::prev() {
- if (_history.count() > 0)
+ if (_history.count() > 0) {
+ _queue.push_front(_current);
_current = _history.pop();
+ _track = _playlist.tracks().at(_current);
+ }
_set_source();
play();
}
}
void Player::_tick(qint64 ticks) {
- emit tick(ticks/1000, _playlist.tracks().at(_current).metadata().length());
+ int done = ticks/1000;
+ int all = _track.metadata().length();
+ emit tick(done, all);
+ if (done+2 == all) {
+ _track.setCount(_track.count()+1);
+ emit trackDone(_track);
+ }
}
void Player::setPlaylist(Playlist playlist) {
void Player::seek(int s) {
_player->seek(s*1000);
}
+
+void Player::play() {
+ _player->play();
+ _state = PLAYER_PLAYING;
+ emit stateChanged(_state);
+}
+
+void Player::enqueue(int id) {
+ _queue.enqueue(id);
+}
#include <phonon/MediaObject>
#include <phonon/AudioOutput>
#include <QStack>
+#include <QQueue>
// represents player
void stateChanged (PlayerState);
void trackChanged (Track);
void tick (int, int); // played | all (seconds)
+ void trackDone(Track);
public slots:
void setTrackId(int id);
+ void enqueue(int id);
+ void toggle();
void play();
- void pause();
void stop();
void next();
void prev();
void _tick(qint64);
private:
int _current;
+ Track _track; // current track (workaround)
bool _random;
bool _repeat;
QStack<int> _history;
+ QQueue<int> _queue;
Playlist _playlist;
Phonon::MediaObject *_player;
Phonon::AudioOutput *_output;
PlayerState _state;
void _set_source();
+
};
};
};
#include <QDebug>
#include <QTime>
#include <QSlider>
+#include "trackrenderer.h"
using namespace SomePlayer::DataObjects;
using namespace SomePlayer::Playback;
_model->setRowCount(count);
for (int i = 0; i < count; i++) {
TrackMetadata meta = tracks.at(i).metadata();
- _model->setItem(i, 0, new QStandardItem(meta.title()));
- _model->setItem(i, 1, new QStandardItem(meta.artist()));
+ QString t = meta.title()+"#_#"+meta.artist()+"#_#"+meta.album();
+ _model->setItem(i, 0, new QStandardItem(t));
}
}
connect(ui->libraryButton, SIGNAL(clicked()), this, SLOT(_library()));
connect(ui->viewButton, SIGNAL(clicked()), this, SLOT(_toggle_view()));
connect(ui->playlistView, SIGNAL(clicked(QModelIndex)), this, SLOT(_process_click(QModelIndex)));
- connect(ui->playButton, SIGNAL(clicked()), _player, SLOT(play()));
- connect(ui->pauseButton, SIGNAL(clicked()), _player, SLOT(pause()));
+ connect(ui->playpauseButton, SIGNAL(clicked()), _player, SLOT(toggle()));
connect(ui->stopButton, SIGNAL(clicked()), _player, SLOT(stop()));
connect(ui->nextButton, SIGNAL(clicked()), _player, SLOT(next()));
connect(ui->prevButton, SIGNAL(clicked()), _player, SLOT(prev()));
connect(_player, SIGNAL(trackChanged(Track)), this, SLOT(_track_changed(Track)));
connect(_player, SIGNAL(tick(int,int)), this, SLOT(_tick(int,int)));
+ connect(ui->randomButton, SIGNAL(clicked()), _player, SLOT(toggleRandom()));
+ connect(ui->repeatButton, SIGNAL(clicked()), _player, SLOT(toggleRepeat()));
+ ui->randomButton->setChecked(_player->random());
+ ui->repeatButton->setChecked(_player->repeat());
_seek_slider = new QSlider(Qt::Horizontal);
ui->progressLayout->insertWidget(1, _seek_slider);
_seek_slider->setTracking(false);
- connect(_seek_slider, SIGNAL(sliderMoved(int)), _player, SLOT(seek(int)));
+ connect(_seek_slider, SIGNAL(sliderReleased()), this, SLOT(_slider_released()));
+ connect(ui->playlistView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(_custom_context_venu_requested(QPoint)));
_model = new QStandardItemModel(0, 2, this);
ui->playlistView->setModel(_model);
+ _context_menu = new QMenu(ui->playlistView);
+ QAction *delete_action = _context_menu->addAction("Delete");
+ connect(delete_action, SIGNAL(triggered()), this, SLOT(_delete_track()));
+ QAction *enqueue_action = _context_menu->addAction("Enqueue");
+ connect(enqueue_action, SIGNAL(triggered()), this, SLOT(_enqueue_track()));
+ QAction *add_to_favorites = _context_menu->addAction("Add to favorites");
+ connect(add_to_favorites, SIGNAL(triggered()), this, SLOT(_add_to_favorites()));
+
+ _track_renderer = new TrackRenderer(this);
+ ui->playlistView->setItemDelegateForColumn(0, _track_renderer);
+ connect(_player, SIGNAL(trackDone(Track)), _lib, SLOT(updateTrackCount(Track)));
}
PlayerForm::~PlayerForm()
_player->stop();
_player->setTrackId(id);
_player->play();
+ _track_renderer->setActiveRow(id);
+ ui->playlistView->hide();
+ ui->playlistView->show();
}
void PlayerForm::_track_changed(Track track) {
int id = _current_playlist.tracks().indexOf(track);
QModelIndex index = _model->index(id, 0);
ui->playlistView->setCurrentIndex(index);
+ ui->playlistView->scrollTo(index);
+ _track_renderer->setActiveRow(id);
+ ui->playlistView->hide();
+ ui->playlistView->show();
_display_track(track);
}
arg(track.metadata().album()));
_seek_slider->setMinimum(0);
_seek_slider->setMaximum(track.metadata().length());
+ _tick(0, track.metadata().length());
}
void PlayerForm::_tick(int done, int all) {
- QTime time1(0, all/60, all%60);
- QTime time2(0, done/60, done%60);
- ui->allTimeLabel->setText(time1.toString("mm:ss"));
- ui->doneTimeLabel->setText(time2.toString("mm:ss"));
+ QTime time(0, all/60, all%60);
+ ui->allTimeLabel->setText(time.toString("mm:ss"));
+ time.setHMS(0, done/60, done%60);
+ ui->doneTimeLabel->setText(time.toString("mm:ss"));
_seek_slider->setValue(done);
}
void PlayerForm::_slider_released() {
_player->seek(_seek_slider->value());
}
+
+void PlayerForm::_custom_context_venu_requested(const QPoint &pos) {
+ _context_menu->exec(pos);
+}
+
+void PlayerForm::_delete_track() {
+ QList<QModelIndex> idx = ui->playlistView->selectionModel()->selectedIndexes();
+ int id = idx.first().row();
+ _current_playlist.removeTrackAt(id);
+ _lib->saveCurrentPlaylist(_current_playlist);
+ reload();
+}
+
+void PlayerForm::_enqueue_track() {
+ QList<QModelIndex> idx = ui->playlistView->selectionModel()->selectedIndexes();
+ int id = idx.first().row();
+ _player->enqueue(id);
+}
+
+void PlayerForm::_add_to_favorites() {
+ QList<QModelIndex> idx = ui->playlistView->selectionModel()->selectedIndexes();
+ int id = idx.first().row();
+ _lib->addToFavorites(_current_playlist.tracks().at(id));
+}
#include <QStandardItemModel>
#include "player/player.h"
#include <QSlider>
+#include <QMenu>
+#include "trackrenderer.h"
namespace Ui {
class PlayerForm;
void _track_changed(Track);
void _tick(int, int);
void _slider_released();
+ void _custom_context_venu_requested ( const QPoint & pos );
+ void _delete_track();
+ void _enqueue_track();
+ void _add_to_favorites();
private:
Ui::PlayerForm *ui;
QStandardItemModel *_model;
Player *_player;
QSlider *_seek_slider;
+ QMenu *_context_menu;
+ TrackRenderer *_track_renderer;
void _display_track(Track);
};
_tracks.removeOne(track);
}
+void Playlist::removeTrackAt(int id) {
+ _tracks.removeAt(id);
+}
+
+void Playlist::clear() {
+ _tracks.clear();
+}
void setName(QString name);
void addTrack(Track track);
void removeTrack(Track track);
+ void removeTrackAt(int id);
+ void clear();
private:
QString _name;
_id = id;
_metadata = metadata;
_source = source;
+ _count = 0;
}
Track::Track(const Track &track) : QObject() {
this->_metadata = track.metadata();
this->_source = track.source();
+ this->_id = track._id;
+ this->_count = track._count;
}
Track::Track(QString source) :QObject() {
QStringList foo;
foo << source;
_resolver->decode(foo);
+ _count = 0;
+ _id = 0;
}
TrackMetadata Track::metadata() const {
_id = track.id();
_source = track.source();
_metadata = track.metadata();
+ _count = track._count;
return *this;
}
--- /dev/null
+#include "trackrenderer.h"
+#include <QFont>
+#include <QFontMetrics>
+#include <QSize>
+#include <QColor>
+
+TrackRenderer::TrackRenderer(QObject *parent) :
+ QAbstractItemDelegate(parent)
+{
+}
+
+void TrackRenderer::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
+ QString value = index.data().toString();
+ QStringList meta = value.split("#_#");
+
+ QFont f = painter->font();
+ QFont fp = painter->font();
+
+ int x1, y1, x2, y2;
+ option.rect.getCoords(&x1, &y1, &x2, &y2);
+
+ QPen pen = painter->pen();
+ QPen npen (QColor::fromRgb(80, 130, 255, 50));
+ QPen apen (QColor::fromRgb(255, 255, 255, 128));
+ QPen spen (QColor::fromRgb(100, 150, 220));
+
+ f.setBold(true);
+ painter->setFont(f);
+ f.setBold(false);
+ painter->setPen(npen);
+ painter->drawLine(x1, y1, x2, y1);
+ if (index.row() == _active_row) {
+ painter->setPen(spen);
+ } else {
+ painter->setPen(pen);
+ }
+ painter->drawText(x1, y1 + 2*(y2-y1)/5, meta[0]);
+ fp.setBold(false);
+ fp.setPointSize(f.pointSize()*3/4);
+ painter->setFont(fp);
+ painter->setPen(apen);
+ painter->drawText((x2+x1)/2, y1 + 4*(y2-y1)/6, meta[1]);
+ painter->drawText((x2+x1)/2, y1 + 11*(y2-y1)/12, meta[2]);
+ painter->setPen(npen);
+ painter->drawLine(x1, y2, x2, y2);
+ painter->setFont(f);
+ painter->setPen(pen);
+}
+
+QSize TrackRenderer::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
+ return QSize(option.rect.width(), option.rect.height()/3);
+}
+
+void TrackRenderer::setActiveRow(int r) {
+ _active_row = r;
+}
--- /dev/null
+#ifndef TRACKRENDERER_H
+#define TRACKRENDERER_H
+
+#include <QAbstractItemDelegate>
+#include <QPainter>
+
+class TrackRenderer : public QAbstractItemDelegate
+{
+ Q_OBJECT
+public:
+ explicit TrackRenderer(QObject *parent = 0);
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+signals:
+
+public slots:
+ void setActiveRow(int);
+private:
+ int _active_row;
+
+};
+
+#endif // TRACKRENDERER_H
</widget>
</item>
<item>
+ <spacer name="verticalSpacer_4">
+ <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="useButton">
+ <property name="text">
+ <string>Use</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="margin">
- <number>0</number>
- </property>
- <item>
- <widget class="QStackedWidget" name="stackedWidget">
- <property name="currentIndex">
- <number>1</number>
- </property>
- <widget class="QWidget" name="page">
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="margin">
- <number>0</number>
- </property>
- <item>
- <widget class="QListView" name="playlistView">
- <property name="editTriggers">
- <set>QAbstractItemView::NoEditTriggers</set>
- </property>
- <property name="textElideMode">
- <enum>Qt::ElideLeft</enum>
- </property>
- <property name="uniformItemSizes">
- <bool>true</bool>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="page_2">
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QWidget" name="widget" native="true">
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <item>
- <spacer name="horizontalSpacer_2">
- <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="QLabel" name="countLabel">
- <property name="text">
- <string>0/0</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QLabel" name="titleLabel">
- <property name="text">
- <string><h3>Title</h3></string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="progressLayout">
- <item>
- <widget class="QLabel" name="doneTimeLabel">
- <property name="text">
- <string>00:00</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="allTimeLabel">
- <property name="text">
- <string>00:00</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QLabel" name="artistAlbumLabel">
- <property name="text">
- <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
-<html><head><meta name="qrichtext" content="1" /><style type="text/css">
-p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Droid Sans'; font-size:9pt; font-weight:400; font-style:normal;">
-<p style=" margin-top:14px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:large; font-weight:600;">Artist</span></p>
-<p style=" margin-top:14px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:large;">album</span></p></body></html></string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
</spacer>
</item>
<item>
- <widget class="QPushButton" name="prevButton">
+ <widget class="QPushButton" name="randomButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
</size>
</property>
<property name="text">
- <string><|</string>
+ <string>S</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</widget>
</item>
<item>
- <widget class="QPushButton" name="playButton">
+ <widget class="QPushButton" name="repeatButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
</size>
</property>
<property name="text">
- <string>></string>
+ <string>R</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</widget>
</item>
<item>
- <widget class="QPushButton" name="pauseButton">
+ <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="prevButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
</size>
</property>
<property name="text">
- <string>||</string>
+ <string><|</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="playpauseButton">
+ <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>>||</string>
</property>
<property name="flat">
<bool>true</bool>
</item>
</layout>
</item>
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <widget class="QWidget" name="page">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QListView" name="playlistView">
+ <property name="contextMenuPolicy">
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="textElideMode">
+ <enum>Qt::ElideLeft</enum>
+ </property>
+ <property name="uniformItemSizes">
+ <bool>true</bool>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_2">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QWidget" name="widget" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <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="QLabel" name="countLabel">
+ <property name="text">
+ <string>0/0</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="titleLabel">
+ <property name="text">
+ <string><h3>Title</h3></string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="progressLayout">
+ <item>
+ <widget class="QLabel" name="doneTimeLabel">
+ <property name="text">
+ <string>00:00</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="allTimeLabel">
+ <property name="text">
+ <string>00:00</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="artistAlbumLabel">
+ <property name="text">
+ <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Droid Sans'; font-size:9pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:14px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:large; font-weight:600;">Artist</span></p>
+<p style=" margin-top:14px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:large;">album</span></p></body></html></string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ <zorder></zorder>
+ <zorder>widget</zorder>
+ </widget>
+ </widget>
+ </item>
</layout>
</widget>
<resources/>