From: Nikolay Tischenko Date: Mon, 27 Sep 2010 05:37:10 +0000 (+0700) Subject: Implemented new features: X-Git-Tag: 1.2.1 X-Git-Url: http://git.maemo.org/git/?p=someplayer;a=commitdiff_plain;h=68e7e55646f7caf47dd678a5f2f51644ddacd751 Implemented new features: * stop timer * tag editing * soft volume slider * sorting artist by alphabet in library Fixed bugs: * auto-refreshing library view after adding new directory --- diff --git a/resources/resources.qrc b/resources/resources.qrc index 444ab95..984ba8d 100644 --- a/resources/resources.qrc +++ b/resources/resources.qrc @@ -25,5 +25,6 @@ forward.png window.png fullscreen.png + volume.png diff --git a/resources/volume.png b/resources/volume.png new file mode 100644 index 0000000..6e833f8 Binary files /dev/null and b/resources/volume.png differ diff --git a/someplayer.pro b/someplayer.pro index 1269327..f7e5f1b 100644 --- a/someplayer.pro +++ b/someplayer.pro @@ -115,7 +115,9 @@ SOURCES += src/main.cpp\ src/taglib/trueaudio/trueaudioproperties.cpp \ src/taglib/trueaudio/trueaudiofile.cpp \ src/taglib/wavpack/wavpackproperties.cpp \ - src/taglib/wavpack/wavpackfile.cpp + src/taglib/wavpack/wavpackfile.cpp \ + src/edittagsdialog.cpp \ + src/timerdialog.cpp HEADERS += src/mainwindow.h \ src/player/player.h \ @@ -208,13 +210,17 @@ HEADERS += src/mainwindow.h \ src/taglib/trueaudio/trueaudioproperties.h \ src/taglib/trueaudio/trueaudiofile.h \ src/taglib/wavpack/wavpackproperties.h \ - src/taglib/wavpack/wavpackfile.h + src/taglib/wavpack/wavpackfile.h \ + src/edittagsdialog.h \ + src/timerdialog.h FORMS += src/ui/mainwindow.ui \ src/ui/playerform.ui \ src/ui/libraryform.ui \ src/ui/busywidget.ui \ - src/playlistdialog.ui + src/ui/playlistdialog.ui \ + src/ui/edittagsdialog.ui \ + src/ui/timerdialog.ui CONFIG += mobility MOBILITY = diff --git a/src/dbstorage.cpp b/src/dbstorage.cpp index b78dc3a..8b29483 100644 --- a/src/dbstorage.cpp +++ b/src/dbstorage.cpp @@ -20,6 +20,7 @@ #include "dbstorage.h" #include #include +#include using namespace SomePlayer::Storage; using namespace SomePlayer::DataObjects; @@ -38,48 +39,54 @@ DbStorage::DbStorage(QString path) { void DbStorage::_prepare_queries() { _get_artists_query = new QSqlQuery(db); - _get_artists_query->prepare("SELECT name FROM artist"); + _get_artists_query->prepare("SELECT name FROM artist ORDER BY name"); _get_albums_for_artist_query = new QSqlQuery(db); - _get_albums_for_artist_query->prepare("SELECT name FROM album WHERE artist_id in (SELECT id from artist WHERE UPPER(name) = UPPER(:name));"); + _get_albums_for_artist_query->prepare("SELECT name FROM album WHERE artist_id in (SELECT id from artist WHERE UPPER(name) = UPPER(:name)) ORDER BY name;"); _get_tracks_for_album_query = new QSqlQuery(db); _get_tracks_for_album_query->prepare("SELECT id, title, source, count, length FROM tracks WHERE artist_id IN " - "(SELECT id FROM artist WHERE UPPER(name) = UPPER(:artist_name)) AND album_id IN " - "(SELECT id FROM album WHERE UPPER(name) = UPPER(:album_name));"); + "(SELECT id FROM artist WHERE UPPER(name) = UPPER(:artist_name)) AND album_id IN " + "(SELECT id FROM album WHERE UPPER(name) = UPPER(:album_name));"); _get_favorites_query = new QSqlQuery(db); _get_favorites_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM " - "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM " - "tracks JOIN artist ON tracks.artist_id = artist.id) " - "JOIN album ON album_id = album.id WHERE track_id IN " - "(SELECT track_id FROM favorites);"); + "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM " + "tracks JOIN artist ON tracks.artist_id = artist.id) " + "JOIN album ON album_id = album.id WHERE track_id IN " + "(SELECT track_id FROM favorites);"); _get_most_played_query = new QSqlQuery(db); _get_most_played_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM " - "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM " - "tracks JOIN artist ON tracks.artist_id = artist.id) " - "JOIN album ON album_id = album.id ORDER BY count DESC " - "LIMIT 0, :max"); + "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM " + "tracks JOIN artist ON tracks.artist_id = artist.id) " + "JOIN album ON album_id = album.id ORDER BY count DESC " + "LIMIT 0, :max"); _get_never_played_query = new QSqlQuery(db); _get_never_played_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM " - "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM " - "tracks JOIN artist ON tracks.artist_id = artist.id) " - "JOIN album ON album_id = album.id " - "WHERE count = 0"); + "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM " + "tracks JOIN artist ON tracks.artist_id = artist.id) " + "JOIN album ON album_id = album.id " + "WHERE count = 0"); _get_recently_added_query = new QSqlQuery(db); _get_recently_added_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM " - "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM " - "tracks JOIN artist ON tracks.artist_id = artist.id) " - "JOIN album ON album_id = album.id " - "WHERE track_id IN " - "(SELECT track_id FROM adding_date ORDER BY date DESC LIMIT 0, :max)"); + "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM " + "tracks JOIN artist ON tracks.artist_id = artist.id) " + "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"); + _get_track_by_source_query = new QSqlQuery(db); + _get_track_by_source_query->prepare("SELECT track_id AS id, title, artist, album.name AS album, source, count, length FROM " + "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, tracks.album_id, length FROM " + "tracks JOIN artist ON tracks.artist_id = artist.id AND source = :source) " + "JOIN album ON album_id = album.id LIMIT 1"); + _check_artist_query = new QSqlQuery(db); _check_artist_query->prepare("SELECT id FROM artist WHERE UPPER(name) = UPPER(:name)"); @@ -106,35 +113,38 @@ void DbStorage::_prepare_queries() { _update_track_count_query = new QSqlQuery(db); _update_track_count_query->prepare("UPDATE tracks SET count = :count where id = :id"); + + _remove_track_query = new QSqlQuery(db); + _remove_track_query->prepare("DELETE FROM tracks WHERE id = :id"); } void DbStorage::_create_database_structure() { QSqlQuery *query = new QSqlQuery(db); query->exec("create table artist (id integer primary key, " - "name text " - ");"); + "name text " + ");"); query->exec("create table album (id integer primary key, " - "artist_id integer, " - "name text, " - "foreign key(artist_id) references arist(id) " - ");"); + "artist_id integer, " + "name text, " + "foreign key(artist_id) references arist(id) " + ");"); query->exec("create table tracks (id integer primary key, " - "artist_id integer, " - "album_id integer, " - "title text, " - "source text, " - "count integer default 0, " - "length integer default 0, " - "foreign key(artist_id) references artist(id), " - "foreign key(album_id) references album(id) " - ");"); + "artist_id integer, " + "album_id integer, " + "title text, " + "source text, " + "count integer default 0, " + "length integer default 0, " + "foreign key(artist_id) references artist(id), " + "foreign key(album_id) references album(id) " + ");"); query->exec("create table favorites (track_id integer, " - "foreign key(track_id) references tracks(id) " - ");"); + "foreign key(track_id) references tracks(id) " + ");"); query->exec("create table adding_date (track_id integer, " - "date integer, " - "foreign key(track_id) references tracks(id) " - ");"); + "date integer, " + "foreign key(track_id) references tracks(id) " + ");"); } DbStorage::~DbStorage() { @@ -145,6 +155,7 @@ DbStorage::~DbStorage() { delete _get_never_played_query; delete _get_recently_added_query; delete _get_tracks_for_album_query; + delete _get_track_by_source_query; delete _check_album_query; delete _check_artist_query; delete _check_track_query; @@ -154,6 +165,7 @@ DbStorage::~DbStorage() { delete _insert_track_query; delete _insert_favorites_query; delete _update_track_count_query; + delete _remove_track_query; db.close(); } @@ -311,6 +323,7 @@ void DbStorage::addTrack(Track track) { int artist_id = _check_add_artist(artist); int album_id = _check_add_album(album, artist_id); if (artist_id == -1 || album_id == -1) { + qDebug () << "one"; //big bang return; } @@ -318,6 +331,7 @@ void DbStorage::addTrack(Track track) { query->bindValue(":source", source); query->exec(); if (query->next()) { + qDebug () << "two"; // already in datebase, skip return; } @@ -339,12 +353,15 @@ void DbStorage::addTrack(Track track) { if (query->exec()) { // ok } else { + qDebug () << "three"; // big bang } } else { + qDebug () << "four"; // big bang } } else { + qDebug () << "five"; // big bang } } @@ -368,6 +385,38 @@ void DbStorage::updateTrackCount(Track track) { } } +Track DbStorage::updateTrack(Track track) { + QSqlQuery *query = _remove_track_query; + query->bindValue(":id", track.id()); + if (!query->exec()) { + qDebug() << "Problem here"; + } + addTrack(track); + query = _get_track_by_source_query; + query->bindValue(":source", track.source()); + query->exec(); + if (query->next()) { + qDebug() << "enter"; + int id = query->value(0).toInt(); + qDebug() << id; + QString title = query->value(1).toString(); + qDebug() << title; + QString artist = query->value(2).toString(); + qDebug() << artist; + QString album = query->value(3).toString(); + qDebug() << album; + QString source = query->value(4).toString(); + qDebug() << source; + int count = query->value(5).toInt(); + int length = query->value(6).toInt(); + TrackMetadata meta(title, artist, album, length); + Track ntrack(id, meta, source); + ntrack.setCount(count); + return ntrack; + } + return track; +} + int DbStorage::_check_add_artist(QString artist) { QSqlQuery *query = _check_artist_query; query->bindValue(":name", artist); diff --git a/src/dbstorage.h b/src/dbstorage.h index 5c1b761..822140d 100644 --- a/src/dbstorage.h +++ b/src/dbstorage.h @@ -55,6 +55,7 @@ namespace SomePlayer { void addToFavorites(Track track); void updateTrackCount(Track track); + Track updateTrack(Track); void addTrack(Track track); private: @@ -74,6 +75,7 @@ namespace SomePlayer { QSqlQuery *_get_never_played_query; QSqlQuery *_get_recently_added_query; QSqlQuery *_get_track_count; + QSqlQuery *_get_track_by_source_query; QSqlQuery *_check_artist_query; QSqlQuery *_check_album_query; @@ -86,6 +88,8 @@ namespace SomePlayer { QSqlQuery *_insert_favorites_query; QSqlQuery *_update_track_count_query; + + QSqlQuery *_remove_track_query; }; }; }; diff --git a/src/edittagsdialog.cpp b/src/edittagsdialog.cpp new file mode 100644 index 0000000..b385270 --- /dev/null +++ b/src/edittagsdialog.cpp @@ -0,0 +1,50 @@ +/* + * SomePlayer - An alternate music player for Maemo 5 + * Copyright (C) 2010 Nikolay (somebody) Tischenko + * + * 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 "edittagsdialog.h" +#include "ui_edittagsdialog.h" +#include "trackmetainformation.h" + +using namespace SomePlayer::DataObjects; + +EditTagsDialog::EditTagsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::EditTagsDialog) +{ + ui->setupUi(this); +} + +EditTagsDialog::~EditTagsDialog() +{ + delete ui; +} + +void EditTagsDialog::setTrackMetadata(TrackMetadata meta) { + _meta = meta; + ui->artistLineEdit->setText(meta.artist()); + ui->albumLineEdit->setText(meta.album()); + ui->titleLineEdit->setText(meta.title()); +} + +TrackMetadata EditTagsDialog::meta() { + _meta.setArtist(ui->artistLineEdit->text()); + _meta.setAlbum(ui->albumLineEdit->text()); + _meta.setTitle(ui->titleLineEdit->text()); + return _meta; +} diff --git a/src/edittagsdialog.h b/src/edittagsdialog.h new file mode 100644 index 0000000..a2b2b4b --- /dev/null +++ b/src/edittagsdialog.h @@ -0,0 +1,47 @@ +/* + * SomePlayer - An alternate music player for Maemo 5 + * Copyright (C) 2010 Nikolay (somebody) Tischenko + * + * 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 EDITTAGSDIALOG_H +#define EDITTAGSDIALOG_H + +#include +#include "someplayer.h" +#include "trackmetainformation.h" + +using SomePlayer::DataObjects::TrackMetadata; +namespace Ui { + class EditTagsDialog; +} + +class EditTagsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit EditTagsDialog(QWidget *parent = 0); + ~EditTagsDialog(); + void setTrackMetadata(TrackMetadata meta); + TrackMetadata meta(); + +private: + Ui::EditTagsDialog *ui; + TrackMetadata _meta; +}; + +#endif // EDITTAGSDIALOG_H diff --git a/src/library.cpp b/src/library.cpp index 562afd5..7f8165b 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -18,6 +18,7 @@ */ #include "library.h" +#include using namespace SomePlayer::DataObjects; using namespace SomePlayer::Storage; @@ -142,3 +143,22 @@ void Library::_scanned(QStringList files) { emit addingTracks(files.count()); _resolver->decode(files); } + +void Library::updateTrackMetadata(Track track) { + Track ntrack = track; + if (track.id() > 0) { + ntrack = _library_storage->updateTrack(track); + } + // update all playlists + QList playlists = getPlaylistsNames(); + foreach (QString name, playlists) { + Playlist pl = getPlaylist(name); + QList tracks = pl.tracks(); + int pos = tracks.indexOf(ntrack); // comparing using source + tracks.removeOne(ntrack); // comparing using source + tracks.insert(pos, ntrack); + pl.setTracks(tracks); + savePlaylist(pl); + } + _resolver->updateTags(ntrack); +} diff --git a/src/library.h b/src/library.h index 9268609..6359548 100644 --- a/src/library.h +++ b/src/library.h @@ -90,6 +90,7 @@ namespace SomePlayer { void addTrack(Track); void addToFavorites(Track); void updateTrackCount(Track); + void updateTrackMetadata(Track); }; }; diff --git a/src/libraryform.cpp b/src/libraryform.cpp index f63cdf4..5fd2177 100644 --- a/src/libraryform.cpp +++ b/src/libraryform.cpp @@ -358,3 +358,29 @@ void LibraryForm::cancelSearch() { _search_pattern = ""; ui->listView->selectionModel()->clearSelection(); } + +void LibraryForm::refresh() { + switch (_state) { + case STATE_ARTIST: + _view_button(); + break; + case STATE_ALBUM: + __fill_model(_model, _lib->getAlbumsForArtist(_current_artist)); + break; + case STATE_PLAYLIST: + _playlists_button(); + break; + case STATE_DYNAMIC: + _dynamic_button(); + break; + case STATE_PLAYLIST_TRACK: + _current_playlist = _lib->getPlaylist(_current_playlist.name()); + _current_tracks = _current_playlist.tracks(); + __fill_model_tracks(_model, _current_tracks); + break; + case STATE_TRACK: + _current_tracks = _lib->getTracksForAlbum(_current_album, _current_artist); + __fill_model_tracks(_model, _current_tracks); + break; + } +} diff --git a/src/libraryform.h b/src/libraryform.h index 8e7892c..6672789 100644 --- a/src/libraryform.h +++ b/src/libraryform.h @@ -54,6 +54,7 @@ public slots: void nextItem(); void prevItem(); void cancelSearch(); + void refresh(); private slots: void _player(); void _view_button(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 424023f..63017be 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -27,6 +27,7 @@ #include "player/player.h" #include "library.h" +#include "timerdialog.h" using namespace SomePlayer::DataObjects; using namespace SomePlayer::Storage; @@ -44,6 +45,7 @@ MainWindow::MainWindow(QWidget *parent) : _player_form = new PlayerForm(_library, ui->stackedWidget); _library_form = new LibraryForm(_library, ui->stackedWidget); _busy_widget = new BusyWidget(ui->stackedWidget); + _timer = new QTimer(this); ui->stackedWidget->insertWidget(0, _player_form); ui->stackedWidget->insertWidget(1, _library_form); ui->stackedWidget->insertWidget(2, _busy_widget); @@ -51,13 +53,16 @@ MainWindow::MainWindow(QWidget *parent) : QAction *save_playlist = ui->menuLibrary->addAction("Save playlist"); QAction *clear_playlist = ui->menuLibrary->addAction("Clear current playlist"); QAction *add_files = ui->menuLibrary->addAction("Add file to current playlist"); + QAction *set_timer = ui->menuBar->addAction("Set timer"); 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(save_playlist, SIGNAL(triggered()), this, SLOT(_save_playlist())); connect(clear_playlist, SIGNAL(triggered()), this, SLOT(_clear_current_playlist())); connect(add_files, SIGNAL(triggered()), this, SLOT(_add_files())); + connect(set_timer, SIGNAL(triggered()), this, SLOT(_set_timer())); 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(_library_form, SIGNAL(done()), this, SLOT(library())); @@ -69,6 +74,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(ui->nextButton, SIGNAL(clicked()), this, SLOT(_nextItem())); connect(ui->prevButton, SIGNAL(clicked()), this, SLOT(_prevItem())); connect(ui->fscreenButton, SIGNAL(clicked()), this, SLOT(_toggle_full_screen())); + connect(_timer, SIGNAL(timeout()), this, SLOT(_timeout())); hideSearchPanel(); library(); } @@ -85,7 +91,7 @@ void MainWindow::aboutQt() { } void MainWindow::about() { - QMessageBox::about(this, "About SomePlayer", "Alternate music player for Maemo 5 " + QMessageBox::about(this, QString("About SomePlayer v")+_SOMEPLAYER_VERSION_, "Alternate music player for Maemo 5 " "written in C++ with Qt4\n\n" "Author: Nikolay Tischenko aka \"somebody\" "); } @@ -206,3 +212,31 @@ void MainWindow::_add_files() { QStringList files = QFileDialog::getOpenFileNames(this, "Add file"); if (!files.isEmpty()) _player_form->addFiles(files); } + +void MainWindow::_set_timer() { + TimerDialog dialog(this); + dialog.init(); + if (_timer->isActive()) { + dialog.showDisable(); + int msec = _timer->interval(); + int h = msec/3600000; + int m = msec/60000 - h * 60; + int s = msec/1000 - h * 3600 - m * 60; + dialog.setTime(h, m, s); + } + if (QDialog::Accepted == dialog.exec()) { + if (!dialog.timerDisabled()) { + int h, m, s; + dialog.getTime(&h, &m, &s); + _timer->setInterval(h*3600000+m*60000+s*1000); + _timer->start(); + } else if (_timer->isActive()) { + _timer->stop(); + } + } +} + +void MainWindow::_timeout() { + _player_form->stop(); + _timer->stop(); +} diff --git a/src/mainwindow.h b/src/mainwindow.h index e2036e4..3a274a0 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -26,6 +26,7 @@ #include "libraryform.h" #include "busywidget.h" #include "library.h" +#include namespace Ui { class MainWindow; @@ -63,11 +64,14 @@ private slots: void _prevItem(); void _cancelSearch(); void _toggle_full_screen(); + void _set_timer(); + void _timeout(); private: PlayerForm *_player_form; LibraryForm *_library_form; BusyWidget *_busy_widget; Library *_library; + QTimer *_timer; }; #endif // MAINWINDOW_H diff --git a/src/player/player.cpp b/src/player/player.cpp index bd8c8d5..05d37cd 100644 --- a/src/player/player.cpp +++ b/src/player/player.cpp @@ -188,3 +188,6 @@ void Player::toggleRepeat() { _config.setValue("playback/repeat", _repeat); } +void Player::setVolume(int v) { + _output->setVolume(v*0.01); +} diff --git a/src/player/player.h b/src/player/player.h index cf45026..625aa63 100644 --- a/src/player/player.h +++ b/src/player/player.h @@ -8,6 +8,7 @@ #include "../playlist.h" #include #include +#include #include #include @@ -31,6 +32,7 @@ namespace SomePlayer { bool random() {return _random;} bool repeat() {return _repeat;} + int volume() {return (int)(_output->volume()*100 + 0.5);} Phonon::MediaObject* mediaObject() {return _player;} signals: @@ -51,6 +53,7 @@ namespace SomePlayer { void toggleRandom(); void toggleRepeat(); void seek(int); + void setVolume(int); private slots: void _stateChanged(Phonon::State, Phonon::State); void _tick(qint64); diff --git a/src/playerform.cpp b/src/playerform.cpp index fd2bdab..4aa4e16 100644 --- a/src/playerform.cpp +++ b/src/playerform.cpp @@ -27,6 +27,7 @@ #include "trackrenderer.h" #include #include "playlistdialog.h" +#include "edittagsdialog.h" using namespace SomePlayer::DataObjects; using namespace SomePlayer::Playback; @@ -61,6 +62,9 @@ PlayerForm::PlayerForm(Library* lib, QWidget *parent) : } else { ui->repeatButton->setIcon(QIcon(":/icons/repeat_inactive.png")); } + ui->volumeSlider->setMinimum(0); + ui->volumeSlider->setMaximum(100); + ui->volumeSlider->hide(); _seek_slider = new QSlider(Qt::Horizontal); _seek_slider->setEnabled(false); ui->progressLayout->insertWidget(1, _seek_slider); @@ -69,9 +73,10 @@ PlayerForm::PlayerForm(Library* lib, QWidget *parent) : ui->playlistView->setModel(_model); _context_menu = new QMenu(ui->playlistView); QAction *delete_action = _context_menu->addAction("Delete"); - QAction *enqueue_action = _context_menu->addAction("Enqueue"); QAction *add_to_favorites = _context_menu->addAction("Add to favorites"); + QAction *enqueue_action = _context_menu->addAction("Enqueue"); QAction *add_to_playlists = _context_menu->addAction("Add to playlists"); + QAction *edit_tags = _context_menu->addAction("Edit tags"); _track_renderer = new TrackRenderer(this); ui->playlistView->setItemDelegateForColumn(0, _track_renderer); @@ -90,14 +95,17 @@ PlayerForm::PlayerForm(Library* lib, QWidget *parent) : connect(ui->randomButton, SIGNAL(clicked()), this, SLOT(_toggle_random())); connect(ui->repeatButton, SIGNAL(clicked()), this, SLOT(_toggle_repeat())); connect(_seek_slider, SIGNAL(sliderReleased()), this, SLOT(_slider_released())); + connect(ui->volumeSlider, SIGNAL(sliderMoved(int)), _player, SLOT(setVolume(int))); connect(ui->playlistView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(_custom_context_venu_requested(QPoint))); connect(delete_action, SIGNAL(triggered()), this, SLOT(_delete_track())); connect(enqueue_action, SIGNAL(triggered()), this, SLOT(_enqueue_track())); connect(add_to_favorites, SIGNAL(triggered()), this, SLOT(_add_to_favorites())); connect(add_to_playlists, SIGNAL(triggered()), this, SLOT(_add_to_playlists())); + connect(edit_tags, SIGNAL(triggered()), this, SLOT(_edit_tags())); connect(_player, SIGNAL(stateChanged(PlayerState)), this, SLOT(_state_changed(PlayerState))); connect(_player, SIGNAL(trackDone(Track)), _lib, SLOT(updateTrackCount(Track))); connect(_tag_resolver, SIGNAL(decoded(Track)), this, SLOT(_track_decoded(Track))); + connect(ui->volumeButton, SIGNAL(clicked()), this, SLOT(_toggle_volume())); } PlayerForm::~PlayerForm() @@ -297,11 +305,43 @@ void PlayerForm::_add_to_playlists() { QList names = _lib->getPlaylistsNames(); names.removeOne(_CURRENT_PLAYLIST_SUBST_); PlaylistDialog dialog(names, this); - dialog.exec(); - QList selected = dialog.selected(); - foreach (QString name, selected) { - Playlist pl = _lib->getPlaylist(name); - pl.addTrack(_current_playlist.tracks().at(id)); - _lib->savePlaylist(pl); + if (dialog.exec() == QDialog::Accepted) { + QList selected = dialog.selected(); + foreach (QString name, selected) { + Playlist pl = _lib->getPlaylist(name); + pl.addTrack(_current_playlist.tracks().at(id)); + _lib->savePlaylist(pl); + } } } + +void PlayerForm::_edit_tags() { + QList idx = ui->playlistView->selectionModel()->selectedIndexes(); + Track track = _current_playlist.tracks().at(idx.first().row()); + + EditTagsDialog dialog(this); + dialog.setTrackMetadata(track.metadata()); + if (dialog.exec() == QDialog::Accepted) { + track.setMetadata(dialog.meta()); + _lib->updateTrackMetadata(track); + reload(); + } +} + +void PlayerForm::stop() { + _player->stop(); +} + +void PlayerForm::_toggle_volume() { + if (ui->volumeSlider->isVisible()) { + ui->volumeSlider->hide(); + } else { + ui->volumeSlider->show(); + ui->volumeSlider->setValue(_player->volume()); + } +} + +void PlayerForm::_volume_changed() { + int value = ui->volumeSlider->value(); + _player->setVolume(value); +} diff --git a/src/playerform.h b/src/playerform.h index 6129049..5f9f00d 100644 --- a/src/playerform.h +++ b/src/playerform.h @@ -61,6 +61,7 @@ public slots: void prevItem(); void cancelSearch(); void addFiles(QList files); + void stop(); private slots: void _library(); @@ -74,10 +75,13 @@ private slots: void _enqueue_track(); void _add_to_favorites(); void _add_to_playlists(); + void _edit_tags(); void _state_changed(PlayerState); void _toggle_repeat(); void _toggle_random(); + void _toggle_volume(); void _track_decoded(Track); + void _volume_changed(); private: Ui::PlayerForm *ui; diff --git a/src/playlist.cpp b/src/playlist.cpp index 81ea60c..2233da3 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -57,6 +57,10 @@ void Playlist::removeTrackAt(int id) { _tracks.removeAt(id); } +void Playlist::setTracks(QList tracks) { + _tracks = tracks; +} + void Playlist::clear() { _tracks.clear(); } diff --git a/src/playlist.h b/src/playlist.h index 3abb9e6..28975db 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -42,6 +42,7 @@ namespace SomePlayer { void addTrack(Track track); void removeTrack(Track track); void removeTrackAt(int id); + void setTracks(QList); void clear(); private: diff --git a/src/someplayer.h b/src/someplayer.h index 2008b4b..8920e77 100644 --- a/src/someplayer.h +++ b/src/someplayer.h @@ -47,6 +47,7 @@ namespace SomePlayer { #include "config.h" #define _DYNAMIC_PLAYLIST_MAX_COUNT_ 50 +#define _SOMEPLAYER_VERSION_ "1.2.1" #define NDEBUG #endif diff --git a/src/tagresolver.cpp b/src/tagresolver.cpp index 9ab07a4..10bf0a6 100644 --- a/src/tagresolver.cpp +++ b/src/tagresolver.cpp @@ -50,3 +50,16 @@ void TagResolver::decode(QStringList files) { } emit done(); } + +void TagResolver::updateTags(Track track) { + TagLib::FileRef file_ref(QFile::encodeName(track.source()).data()); + if (!file_ref.isNull()) { + TagLib::Tag *tag = file_ref.tag(); + if (NULL != tag) { + tag->setArtist(TagLib::String(track.metadata().artist().toStdWString())); + tag->setAlbum(TagLib::String(track.metadata().album().toStdWString())); + tag->setTitle(TagLib::String(track.metadata().title().toStdWString())); + } + file_ref.save(); + } +} diff --git a/src/tagresolver.h b/src/tagresolver.h index 31facd9..459a6c9 100644 --- a/src/tagresolver.h +++ b/src/tagresolver.h @@ -37,6 +37,7 @@ namespace SomePlayer { explicit TagResolver(QObject *parent = 0); public slots: void decode (QStringList files); + void updateTags(Track); signals: void decoded(Track); diff --git a/src/timerdialog.cpp b/src/timerdialog.cpp new file mode 100644 index 0000000..e2856bc --- /dev/null +++ b/src/timerdialog.cpp @@ -0,0 +1,46 @@ +#include "timerdialog.h" +#include "ui_timerdialog.h" +#include + +TimerDialog::TimerDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::TimerDialog) +{ + ui->setupUi(this); + ui->disableCheckBox->setChecked(false); + ui->disableCheckBox->setVisible(false); +} + +TimerDialog::~TimerDialog() +{ + delete ui; +} + +void TimerDialog::init() { + setTime(0, 0, 0); +} + +void TimerDialog::setTime(int h, int m, int s) { + if (h < 0 || h > 12 || m < 0 || m > 59 || s < 0 || s > 59) + return; + ui->hoursListWidget->setCurrentRow(h); + ui->hoursListWidget->scrollTo(ui->hoursListWidget->model()->index(h, 0)); + ui->minutesListWidget->setCurrentRow(m); + ui->minutesListWidget->scrollTo(ui->minutesListWidget->model()->index(m, 0)); + ui->secondsListWidget->setCurrentRow(s); + ui->secondsListWidget->scrollTo(ui->secondsListWidget->model()->index(s, 0)); +} + +void TimerDialog::getTime(int *h, int *m, int *s) { + (*h) = ui->hoursListWidget->currentRow(); + (*m) = ui->minutesListWidget->currentRow(); + (*s) = ui->secondsListWidget->currentRow(); +} + +bool TimerDialog::timerDisabled() { + return ui->disableCheckBox->isChecked(); +} + +void TimerDialog::showDisable() { + ui->disableCheckBox->setVisible(true); +} diff --git a/src/timerdialog.h b/src/timerdialog.h new file mode 100644 index 0000000..bc56b10 --- /dev/null +++ b/src/timerdialog.h @@ -0,0 +1,30 @@ +#ifndef TIMERDIALOG_H +#define TIMERDIALOG_H + +#include + +namespace Ui { + class TimerDialog; +} + +class TimerDialog : public QDialog +{ + Q_OBJECT + +public: + explicit TimerDialog(QWidget *parent = 0); + ~TimerDialog(); + void getTime(int *, int *, int *); + bool timerDisabled(); + +public slots: + void init(); + void setTime (int, int, int); + void showDisable(); + + +private: + Ui::TimerDialog *ui; +}; + +#endif // TIMERDIALOG_H diff --git a/src/track.cpp b/src/track.cpp index 66bde60..807f156 100644 --- a/src/track.cpp +++ b/src/track.cpp @@ -59,6 +59,10 @@ TrackMetadata Track::metadata() const { return _metadata; } +void Track::setMetadata(TrackMetadata meta) { + _metadata = meta; +} + QString Track::source() const { return _source; } diff --git a/src/track.h b/src/track.h index 8d1d488..5a81d90 100644 --- a/src/track.h +++ b/src/track.h @@ -41,6 +41,7 @@ namespace SomePlayer { ~Track(); Track &operator=(const Track &track); TrackMetadata metadata() const; //read-write + void setMetadata(TrackMetadata meta); QString source() const; int id() const; void setSource (QString source); diff --git a/src/ui/edittagsdialog.ui b/src/ui/edittagsdialog.ui new file mode 100644 index 0000000..f45b77f --- /dev/null +++ b/src/ui/edittagsdialog.ui @@ -0,0 +1,98 @@ + + + EditTagsDialog + + + + 0 + 0 + 800 + 480 + + + + Edit tags + + + + + + + + Artist: + + + + + + + + + + Album: + + + + + + + + + + Title: + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + EditTagsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + EditTagsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/playerform.ui b/src/ui/playerform.ui index 2c2b473..2ebead7 100644 --- a/src/ui/playerform.ui +++ b/src/ui/playerform.ui @@ -13,125 +13,143 @@ Form - - + + 0 - + 0 - - - - 1 + + + + 0 - - - - 0 - - - 0 - - - - - Qt::CustomContextMenu - - - QAbstractItemView::NoEditTriggers - - - Qt::ElideLeft - - - true + + + + 1 + + + + + 0 - - true + + 0 - - - - - - - - - - - + + + + Qt::CustomContextMenu + + + QAbstractItemView::NoEditTriggers + + + Qt::ElideLeft + + + true + + + true + + + + + + + + + + - - - Qt::Horizontal - - - - 40 - 20 - - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 0/0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + - + - 0/0 + <h3>Title</h3> - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignCenter - - - - - - <h3>Title</h3> - - - Qt::AlignCenter - - - - - - - - 00:00 - - + + + + + 00:00 + + + + + + + 00:00 + + + + - + - 00:00 + <b>Artist</b><br/>album + + + Qt::AlignCenter - - - - - <b>Artist</b><br/>album - - - Qt::AlignCenter - - - - + + + + + + + + + + + + Qt::Vertical + - - + + - + 0 @@ -452,6 +470,45 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 70 + 70 + + + + + + + + :/icons/volume.png:/icons/volume.png + + + true + + + diff --git a/src/ui/playlistdialog.ui b/src/ui/playlistdialog.ui new file mode 100644 index 0000000..048b5c6 --- /dev/null +++ b/src/ui/playlistdialog.ui @@ -0,0 +1,80 @@ + + + PlaylistDialog + + + + 0 + 0 + 592 + 361 + + + + Dialog + + + + 0 + + + 0 + + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::MultiSelection + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + PlaylistDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PlaylistDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/timerdialog.ui b/src/ui/timerdialog.ui new file mode 100644 index 0000000..7de7cac --- /dev/null +++ b/src/ui/timerdialog.ui @@ -0,0 +1,1196 @@ + + + TimerDialog + + + + 0 + 0 + 800 + 480 + + + + Set timer + + + + + + + + + + Hours + + + + + + + + 00 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 01 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 02 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 03 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 04 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 05 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 06 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 07 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 08 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 09 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 10 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 11 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 12 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + + + + + + : + + + + + + + + + Minutes + + + + + + + + 00 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 01 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 02 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 03 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 04 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 05 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 06 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 07 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 08 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 09 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 10 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 11 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 12 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 13 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 14 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 15 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 16 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 17 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 18 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 19 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 20 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 21 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 22 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 23 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 24 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 25 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 26 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 27 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 28 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 29 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 30 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 31 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 32 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 33 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 34 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 35 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 36 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 37 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 38 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 40 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 41 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 42 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 43 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 44 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 45 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 46 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 47 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 48 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 49 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 50 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 51 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 52 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 53 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 54 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 55 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 56 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 57 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 58 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 59 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + + + + + + : + + + + + + + + + Seconds + + + + + + + + 00 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 01 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 02 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 03 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 04 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 05 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 06 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 07 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 08 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 09 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 10 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 11 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 12 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 13 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 14 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 15 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 16 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 17 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 18 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 19 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 20 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 21 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 22 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 23 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 24 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 25 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 26 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 27 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 28 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 29 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 30 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 31 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 32 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 33 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 34 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 35 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 36 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 37 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 38 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 39 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 40 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 41 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 42 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 43 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 44 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 45 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 46 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 47 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 48 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 49 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 50 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 51 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 52 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 53 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 54 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 55 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 56 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 57 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 58 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + 59 + + + AlignHCenter|AlignVCenter|AlignCenter + + + + + + + + + + + + + 0 + 0 + + + + Disable + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + TimerDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + TimerDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +