From c739f40cbb87a28f3ba4e36a20a8edd1aab2117e Mon Sep 17 00:00:00 2001 From: Nikolay Tischenko Date: Mon, 11 Oct 2010 21:39:30 +0700 Subject: [PATCH] Added year metainfo Sorting albums by year Fixed segfault when context menu's item selected without any track selected --- src/dbstorage.cpp | 68 +++++++++++++++++++++++++++--------------- src/dbstorage.h | 7 +++-- src/library.cpp | 2 +- src/library.h | 2 +- src/libraryform.cpp | 52 ++++++++++++++++++++++---------- src/playerform.cpp | 10 +++++++ src/tagresolver.cpp | 2 ++ src/trackmetainformation.cpp | 9 ++++++ src/trackmetainformation.h | 3 ++ 9 files changed, 111 insertions(+), 44 deletions(-) diff --git a/src/dbstorage.cpp b/src/dbstorage.cpp index aba866c..05428cb 100644 --- a/src/dbstorage.cpp +++ b/src/dbstorage.cpp @@ -38,15 +38,18 @@ DbStorage::DbStorage(QString path) { void DbStorage::_prepare_queries() { _get_artists_query = new QSqlQuery(db); - _get_artists_query->prepare("SELECT name FROM artist ORDER BY name"); + _get_artists_query->prepare("SELECT name FROM artist ORDER BY uname"); - _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)) ORDER BY name;"); + _get_albums_for_artist_sort_name_query = new QSqlQuery(db); + _get_albums_for_artist_sort_name_query->prepare("SELECT name, year FROM album WHERE artist_id in (SELECT id from artist WHERE uname = :uname) ORDER BY uname;"); + + _get_albums_for_artist_sort_year_query = new QSqlQuery(db); + _get_albums_for_artist_sort_year_query->prepare("SELECT name, year FROM album WHERE artist_id in (SELECT id from artist WHERE uname = :uname) ORDER BY year;"); _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 uname = :artist_uname) AND album_id IN " + "(SELECT id FROM album WHERE uname = :album_uname);"); _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 " @@ -87,22 +90,22 @@ void DbStorage::_prepare_queries() { "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)"); + _check_artist_query->prepare("SELECT id FROM artist WHERE uname = :uname"); _check_album_query = new QSqlQuery(db); - _check_album_query->prepare("SELECT id FROM album WHERE UPPER(name) = UPPER(:name) AND artist_id = :artist_id"); + _check_album_query->prepare("SELECT id FROM album WHERE uname = :uname AND artist_id = :artist_id"); _check_track_query = new QSqlQuery(db); _check_track_query->prepare("SELECT id FROM tracks WHERE source = :source"); _insert_artist_query = new QSqlQuery(db); - _insert_artist_query->prepare("INSERT INTO artist (name) values (:name)"); + _insert_artist_query->prepare("INSERT INTO artist (name, uname) values (:name, :uname)"); _insert_album_query = new QSqlQuery(db); - _insert_album_query->prepare("INSERT INTO album (name, artist_id) values (:name, :artist_id)"); + _insert_album_query->prepare("INSERT INTO album (name, uname, artist_id, year) values (:name, :uname, :artist_id, :year)"); _insert_track_query = new QSqlQuery(db); - _insert_track_query->prepare("INSERT INTO tracks (title, artist_id, album_id, source, length) values (:title, :artist_id, :album_id, :source, :length)"); + _insert_track_query->prepare("INSERT INTO tracks (title, utitle, artist_id, album_id, source, length) values (:title, :utitle, :artist_id, :album_id, :source, :length)"); _insert_date_query = new QSqlQuery(db); _insert_date_query->prepare("INSERT INTO adding_date (track_id, date) values (:track_id, strftime('%s', 'now'))"); @@ -120,17 +123,21 @@ void DbStorage::_prepare_queries() { void DbStorage::_create_database_structure() { QSqlQuery *query = new QSqlQuery(db); query->exec("create table artist (id integer primary key, " - "name text " + "name text, " + "uname text " ");"); query->exec("create table album (id integer primary key, " "artist_id integer, " "name text, " + "uname text, " + "year int, " "foreign key(artist_id) references arist(id) " ");"); query->exec("create table tracks (id integer primary key, " "artist_id integer, " "album_id integer, " "title text, " + "utitle text, " "source text, " "count integer default 0, " "length integer default 0, " @@ -147,7 +154,8 @@ void DbStorage::_create_database_structure() { } DbStorage::~DbStorage() { - delete _get_albums_for_artist_query; + delete _get_albums_for_artist_sort_name_query; + delete _get_albums_for_artist_sort_year_query; delete _get_artists_query; delete _get_favorites_query; delete _get_most_played_query; @@ -179,14 +187,21 @@ QList DbStorage::getArtists() { return artists; } -QList DbStorage::getAlbumsForArtist(QString artist) { - QList albums; - QSqlQuery *query = _get_albums_for_artist_query; - query->bindValue(":name", artist); +QMap DbStorage::getAlbumsForArtist(QString artist) { + QMap albums; + Config config; + QString sort = config.getValue("ui/albumsorting").toString(); + QSqlQuery *query = NULL; + if (sort == "date") { + query = _get_albums_for_artist_sort_year_query; + } else { + query = _get_albums_for_artist_sort_name_query; + } + query->bindValue(":uname", artist.toUpper()); query->exec(); while (query->next()) { QString name = query->value(0).toString(); - albums.append(name); + albums[name] = query->value(1).toInt(); } return albums; } @@ -194,8 +209,8 @@ QList DbStorage::getAlbumsForArtist(QString artist) { QList DbStorage::getTracksForAlbum(QString album, QString artist) { QList tracks; QSqlQuery *query = _get_tracks_for_album_query; - query->bindValue(":artist_name", artist); - query->bindValue(":album_name", album); + query->bindValue(":artist_uname", artist.toUpper()); + query->bindValue(":album_uname", album.toUpper()); query->exec(); while (query->next()) { @@ -319,8 +334,9 @@ void DbStorage::addTrack(Track track) { QString artist = track.metadata().artist(); QString album = track.metadata().album(); QString source = track.source(); + int year = track.metadata().year(); int artist_id = _check_add_artist(artist); - int album_id = _check_add_album(album, artist_id); + int album_id = _check_add_album(album, artist_id, year); if (artist_id == -1 || album_id == -1) { //big bang return; @@ -334,6 +350,7 @@ void DbStorage::addTrack(Track track) { } query = _insert_track_query; query->bindValue(":title", title); + query->bindValue(":utitle", title.toUpper()); query->bindValue(":artist_id", artist_id); query->bindValue(":album_id", album_id); query->bindValue(":source", source); @@ -404,7 +421,7 @@ Track DbStorage::updateTrack(Track track) { int DbStorage::_check_add_artist(QString artist) { QSqlQuery *query = _check_artist_query; - query->bindValue(":name", artist); + query->bindValue(":uname", artist.toUpper()); query->exec(); if (query->next()) { int id = query->value(0).toInt(); @@ -412,6 +429,7 @@ int DbStorage::_check_add_artist(QString artist) { } else { query = _insert_artist_query; query->bindValue(":name", artist); + query->bindValue(":uname", artist.toUpper()); if (query->exec()) { return _check_add_artist(artist); } else { @@ -421,9 +439,9 @@ int DbStorage::_check_add_artist(QString artist) { } } -int DbStorage::_check_add_album(QString album, int artist_id) { +int DbStorage::_check_add_album(QString album, int artist_id, int year) { QSqlQuery *query = _check_album_query; - query->bindValue(":name", album); + query->bindValue(":uname", album.toUpper()); query->bindValue(":artist_id", artist_id); query->exec(); if (query->next()) { @@ -432,9 +450,11 @@ int DbStorage::_check_add_album(QString album, int artist_id) { } else { query = _insert_album_query; query->bindValue(":name", album); + query->bindValue(":uname", album.toUpper()); query->bindValue(":artist_id", artist_id); + query->bindValue(":year", year); if (query->exec()) { - return _check_add_album(album, artist_id); + return _check_add_album(album, artist_id, year); } else { // big bang return -1; diff --git a/src/dbstorage.h b/src/dbstorage.h index 822140d..9976519 100644 --- a/src/dbstorage.h +++ b/src/dbstorage.h @@ -43,7 +43,7 @@ namespace SomePlayer { DbStorage(QString path); ~DbStorage(); QList getArtists(); - QList getAlbumsForArtist(QString artist); + QMap getAlbumsForArtist(QString artist); QList getTracksForAlbum(QString album, QString artist); // hm... Playlist getFavorites(); @@ -64,11 +64,12 @@ namespace SomePlayer { void _prepare_queries(); int _check_add_artist(QString artist); - int _check_add_album(QString album, int artist_id); + int _check_add_album(QString album, int artist_id, int year); // queries QSqlQuery *_get_artists_query; - QSqlQuery *_get_albums_for_artist_query; + QSqlQuery *_get_albums_for_artist_sort_name_query; + QSqlQuery *_get_albums_for_artist_sort_year_query; QSqlQuery *_get_tracks_for_album_query; QSqlQuery *_get_favorites_query; QSqlQuery *_get_most_played_query; diff --git a/src/library.cpp b/src/library.cpp index d175f5a..2b07566 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -54,7 +54,7 @@ QList Library::getArtists() { return _library_storage->getArtists(); } -QList Library::getAlbumsForArtist(QString artist) { +QMap Library::getAlbumsForArtist(QString artist) { return _library_storage->getAlbumsForArtist(artist); } diff --git a/src/library.h b/src/library.h index 6359548..f57c881 100644 --- a/src/library.h +++ b/src/library.h @@ -51,7 +51,7 @@ namespace SomePlayer { void addFile(QString path); QList getArtists(); - QList getAlbumsForArtist(QString artist); + QMap getAlbumsForArtist(QString artist); QList getTracksForAlbum(QString album, QString artist); Playlist getFavorites(); diff --git a/src/libraryform.cpp b/src/libraryform.cpp index 975e47b..257e3b0 100644 --- a/src/libraryform.cpp +++ b/src/libraryform.cpp @@ -55,6 +55,27 @@ inline void __fill_model(QStandardItemModel *model, QList data, QString } } +inline void __fill_model_album(QStandardItemModel *model, QMap data, QString icons_theme) { + model->clear(); + int count = data.count(); + model->setRowCount(count); + QMap > years; + foreach (QString name, data.keys()) { + years[data[name]].append(name); + } + QList keys = years.keys(); + qSort(keys); + + int i = 0; + foreach (int year, keys) { + foreach (QString name, years[year]) { + model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+icons_theme+"/deselect_all.png"), "")); + model->setItem(i, 1, new QStandardItem(QString("[%1] %2").arg(year).arg(name))); + i++; + } + } +} + inline void __fill_model_tracks (QStandardItemModel *model, QList tracks, QString icons_theme) { int count = tracks.count(); model->setRowCount(count); @@ -168,9 +189,10 @@ void LibraryForm::_process_list_click(QModelIndex index) { } if (_state == STATE_NONE) return; QString data = index.data().toString(); + QRegExp regexp("\\[\\d+\\]\\ (.*)"); switch (_state) { case STATE_ARTIST: - __fill_model(_model, _lib->getAlbumsForArtist(data), _icons_theme); + __fill_model_album(_model, _lib->getAlbumsForArtist(data), _icons_theme); ui->listView->setColumnWidth(0, 70); ui->listView->scrollToTop(); _current_artist = data; @@ -179,14 +201,16 @@ void LibraryForm::_process_list_click(QModelIndex index) { ui->listLabel->setText(QString("Albums by \"%1\"").arg(_current_artist)); break; case STATE_ALBUM: - _current_album = data; - _current_tracks = _lib->getTracksForAlbum(data, _current_artist); - __fill_model_tracks(_model, _current_tracks, _icons_theme); - ui->listView->setColumnWidth(0, 70); - ui->listView->scrollToTop(); - _state = STATE_TRACK; - ui->backButton->setEnabled(true); - ui->listLabel->setText(QString("Tracks from \"%1\" by \"%2\"").arg(_current_album).arg(_current_artist)); + if (regexp.indexIn(data) != -1) { + _current_album = regexp.cap(1).trimmed(); + _current_tracks = _lib->getTracksForAlbum(_current_album, _current_artist); + __fill_model_tracks(_model, _current_tracks, _icons_theme); + ui->listView->setColumnWidth(0, 70); + ui->listView->scrollToTop(); + _state = STATE_TRACK; + ui->backButton->setEnabled(true); + ui->listLabel->setText(QString("Tracks from \"%1\" by \"%2\"").arg(_current_album).arg(_current_artist)); + } break; case STATE_PLAYLIST: { @@ -291,8 +315,8 @@ void LibraryForm::_add_button() { void LibraryForm::_add_artist(Playlist *cur, QString artist) { - QList albums = _lib->getAlbumsForArtist(artist); - foreach(QString album, albums) { + QMap albums = _lib->getAlbumsForArtist(artist); + foreach(QString album, albums.keys()) { _add_album(cur, artist, album); } } @@ -323,7 +347,7 @@ void LibraryForm::_back_button() { ui->listView->scrollToTop(); break; case STATE_TRACK: - __fill_model(_model, _lib->getAlbumsForArtist(_current_artist), _icons_theme); + __fill_model_album(_model, _lib->getAlbumsForArtist(_current_artist), _icons_theme); ui->listView->setColumnWidth(0, 70); ui->listView->scrollToTop(); _state = STATE_ALBUM; @@ -413,7 +437,6 @@ void LibraryForm::search(QString pattern) { } void LibraryForm::nextItem() { - qWarning() << "searching" << _search_pattern; QString data = _model->index(_search_current_id, 0).data().toString(); for (int i = _search_current_id+1; i < _model->rowCount(); i++) { data = _model->index(i, 1).data().toString(); @@ -454,7 +477,7 @@ void LibraryForm::refresh() { _view_button(); break; case STATE_ALBUM: - __fill_model(_model, _lib->getAlbumsForArtist(_current_artist), _icons_theme); + __fill_model_album(_model, _lib->getAlbumsForArtist(_current_artist), _icons_theme); ui->listView->setColumnWidth(0, 70); break; case STATE_PLAYLIST: @@ -654,7 +677,6 @@ void LibraryForm::_process_dblclick(QModelIndex id) { if (id.column() == 0) return; if (_state == STATE_TRACK || _state == STATE_PLAYLIST_TRACK) { - qWarning() << "double clicked"; Playlist cur = _lib->getCurrentPlaylist(); Track track = _current_tracks.at(id.row()); cur.addTrack(track); diff --git a/src/playerform.cpp b/src/playerform.cpp index 2ec4222..9558416 100644 --- a/src/playerform.cpp +++ b/src/playerform.cpp @@ -215,6 +215,8 @@ void PlayerForm::_custom_context_menu_requested(const QPoint &pos) { void PlayerForm::_delete_track() { QList idx = ui->playlistView->selectionModel()->selectedIndexes(); + if (idx.isEmpty()) + return; int id = idx.first().row(); int aid = _track_renderer->activeRow(); if (aid > id) { @@ -229,12 +231,16 @@ void PlayerForm::_delete_track() { void PlayerForm::_enqueue_track() { QList idx = ui->playlistView->selectionModel()->selectedIndexes(); + if (idx.isEmpty()) + return; int id = idx.first().row(); _player->enqueue(id); } void PlayerForm::_add_to_favorites() { QList idx = ui->playlistView->selectionModel()->selectedIndexes(); + if (idx.isEmpty()) + return; int id = idx.first().row(); _lib->addToFavorites(_current_playlist.tracks().at(id)); } @@ -332,6 +338,8 @@ void PlayerForm::_track_decoded(Track track) { void PlayerForm::_add_to_playlists() { QList idx = ui->playlistView->selectionModel()->selectedIndexes(); + if (idx.isEmpty()) + return; int id = idx.first().row(); QList names = _lib->getPlaylistsNames(); @@ -349,6 +357,8 @@ void PlayerForm::_add_to_playlists() { void PlayerForm::_edit_tags() { QList idx = ui->playlistView->selectionModel()->selectedIndexes(); + if (idx.isEmpty()) + return; Track track = _current_playlist.tracks().at(idx.first().row()); EditTagsDialog dialog(this); diff --git a/src/tagresolver.cpp b/src/tagresolver.cpp index 170296d..fef54e4 100644 --- a/src/tagresolver.cpp +++ b/src/tagresolver.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace SomePlayer::DataObjects; @@ -42,6 +43,7 @@ void TagResolver::decode(QStringList files) { QString::fromStdWString(tag->artist().toWString()), QString::fromStdWString(tag->album().toWString()), properties->length()); + meta.setYear(tag->year()); Track track(0, meta, filename); emit decoded(track); } diff --git a/src/trackmetainformation.cpp b/src/trackmetainformation.cpp index 0f9f1b8..f5f9e5b 100644 --- a/src/trackmetainformation.cpp +++ b/src/trackmetainformation.cpp @@ -34,6 +34,7 @@ TrackMetadata::TrackMetadata(QString title = "", QString artist = "", QString al TrackMetadata::TrackMetadata(const TrackMetadata &metadata) { this->_metadata = metadata._metadata; this->_length = metadata._length; + this->_year = metadata._year; } QString TrackMetadata::title() { @@ -64,6 +65,10 @@ int TrackMetadata::length() { return _length; } +int TrackMetadata::year() { + return _year; +} + void TrackMetadata::setTitle(QString title) { _metadata["TITLE"] = title; } @@ -79,3 +84,7 @@ void TrackMetadata::setAlbum(QString album) { void TrackMetadata::setLength(int length) { _length = length; } + +void TrackMetadata::setYear(int year) { + _year = year; +} diff --git a/src/trackmetainformation.h b/src/trackmetainformation.h index 3842cf9..a53af83 100644 --- a/src/trackmetainformation.h +++ b/src/trackmetainformation.h @@ -42,15 +42,18 @@ namespace SomePlayer { QString artist(); QString album(); int length(); + int year(); void setTitle(QString title); void setArtist(QString artist); void setAlbum(QString album); void setLength(int length); + void setYear(int year); private: QMap _metadata; int _length; + int _year; }; }; }; -- 1.7.9.5