1 /* $BEGIN_LICENSE
2
3 This file is part of Musique.
4 Copyright 2013, Flavio Tordini <flavio.tordini@gmail.com>
5
6 Musique is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Musique is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Musique. If not, see <http://www.gnu.org/licenses/>.
18
19 $END_LICENSE */
20
21 #include "albumlistview.h"
22
23 #include <QtSql>
24
25 #include "artistsqlmodel.h"
26 #include "database.h"
27 #include "finderitemdelegate.h"
28 #include "iconutils.h"
29 #include "mainwindow.h"
30 #ifdef APP_EXTRA
31 #include "extra.h"
32 #endif
33
34 namespace {
35 const char *sortByKey = "albumSortBy";
36 const char *reverseOrderKey = "albumReverseOrder";
37 } // namespace
38
AlbumListView(QWidget * parent)39 AlbumListView::AlbumListView(QWidget *parent) : FinderListView(parent), showToolBar(false) {
40 toolBar = new QToolBar();
41 toolBar->hide();
42 toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
43 toolBar->setIconSize(QSize(16, 16));
44
45 QSettings settings;
46 sortBy = static_cast<SortBy>(settings.value(sortByKey, SortByYear).toInt());
47
48 QMenu *sortMenu = new QMenu(this);
49 QActionGroup *sortGroup = new QActionGroup(this);
50
51 QAction *sortByArtistAction = new QAction(tr("Artist"), this);
52 sortByArtistAction->setActionGroup(sortGroup);
53 sortByArtistAction->setCheckable(true);
54 if (sortBy == SortByArtist) sortByArtistAction->setChecked(true);
55 connect(sortByArtistAction, SIGNAL(triggered()), SLOT(setSortByArtist()));
56 sortMenu->addAction(sortByArtistAction);
57
58 QAction *sortByNameAction = new QAction(tr("Title"), this);
59 sortByNameAction->setActionGroup(sortGroup);
60 sortByNameAction->setCheckable(true);
61 if (sortBy == SortByTitle) sortByNameAction->setChecked(true);
62 connect(sortByNameAction, SIGNAL(triggered()), SLOT(setSortByTitle()));
63 sortMenu->addAction(sortByNameAction);
64
65 QAction *sortByYearAction = new QAction(tr("Year"), this);
66 sortByYearAction->setActionGroup(sortGroup);
67 sortByYearAction->setCheckable(true);
68 if (sortBy == SortByYear) sortByYearAction->setChecked(true);
69 connect(sortByYearAction, SIGNAL(triggered()), SLOT(setSortByYear()));
70 sortMenu->addAction(sortByYearAction);
71
72 QAction *sortByPopularityAction = new QAction(tr("Popularity"), this);
73 sortByPopularityAction->setActionGroup(sortGroup);
74 sortByPopularityAction->setCheckable(true);
75 if (sortBy == SortByPopularity) sortByPopularityAction->setChecked(true);
76 connect(sortByPopularityAction, SIGNAL(triggered()), SLOT(setSortByPopularity()));
77 sortMenu->addAction(sortByPopularityAction);
78
79 sortMenu->addSeparator();
80
81 reversedOrder = settings.value(reverseOrderKey, false).toBool();
82
83 QAction *reversedOrderAction = new QAction(tr("Reversed Order"), this);
84 reversedOrderAction->setCheckable(true);
85 if (reversedOrder) reversedOrderAction->setChecked(true);
86 connect(reversedOrderAction, SIGNAL(triggered(bool)), SLOT(setReversedOrder(bool)));
87 sortMenu->addAction(reversedOrderAction);
88
89 QToolButton *sortButton = new QToolButton(this);
90 sortButton->setText(tr("Sort by"));
91 IconUtils::setWidgetIcon(sortButton, "sort");
92 sortButton->setIconSize(QSize(16, 16));
93 sortButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
94 sortButton->setPopupMode(QToolButton::InstantPopup);
95 sortButton->setMenu(sortMenu);
96 QWidgetAction *widgetAction = new QWidgetAction(this);
97 widgetAction->setDefaultWidget(sortButton);
98 widgetAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_O));
99 toolBar->addAction(widgetAction);
100 }
101
appear()102 void AlbumListView::appear() {
103 FinderListView::appear();
104 if (showToolBar) {
105 QStatusBar *statusBar = MainWindow::instance()->statusBar();
106 statusBar->insertPermanentWidget(0, toolBar);
107 toolBar->show();
108 }
109 }
110
disappear()111 void AlbumListView::disappear() {
112 FinderListView::disappear();
113 if (showToolBar) {
114 QStatusBar *statusBar = MainWindow::instance()->statusBar();
115 statusBar->removeWidget(toolBar);
116 }
117 }
118
updateQuery(bool transition)119 void AlbumListView::updateQuery(bool transition) {
120 QString sql = "select id from albums where trackCount>0";
121
122 switch (sortBy) {
123 case SortByArtist:
124 sql = "select b.id from albums b, artists a"
125 " where b.artist=a.id and b.trackCount>0"
126 " order by a.name collate nocase";
127 if (reversedOrder) sql += " desc";
128 sql += ", b.year";
129 if (!reversedOrder) sql += " desc";
130 sql += ", b.trackCount";
131 if (!reversedOrder) sql += " desc";
132 break;
133 case SortByYear:
134 sql += " and year>0 order by year";
135 if (!reversedOrder) sql += " desc";
136 break;
137 case SortByPopularity:
138 sql += " order by listeners";
139 if (!reversedOrder) sql += " desc";
140 break;
141 default:
142 sql += " order by title collate nocase";
143 if (reversedOrder) sql += " desc";
144 break;
145 }
146
147 #ifdef APP_EXTRA
148 if (transition) Extra::fadeInWidget(this, this);
149 #endif
150
151 if (!sqlModel->query().isValid()) QTimer::singleShot(500, this, SLOT(preloadThumbs()));
152
153 sqlModel->setQuery(sql, Database::instance().getConnection());
154 if (sqlModel->lastError().isValid()) qWarning() << sqlModel->lastError().text();
155
156 scrollToTop();
157 showToolBar = true;
158 }
159
preloadThumbs()160 void AlbumListView::preloadThumbs() {
161 QSqlDatabase db = Database::instance().getConnection();
162 QSqlQuery query(sqlModel->query().lastQuery(), db);
163 bool success = query.exec();
164 if (!success)
165 qDebug() << query.lastQuery() << query.lastError().text() << query.lastError().number();
166
167 const qreal pixelRatio = devicePixelRatioF();
168
169 while (query.next()) {
170 int albumId = query.value(0).toInt();
171 Album *album = Album::forId(albumId);
172 album->getThumb(delegate->getItemWidth(), delegate->getItemHeight(), pixelRatio);
173 qApp->processEvents();
174 }
175 }
176
setSortBy(SortBy sortBy)177 void AlbumListView::setSortBy(SortBy sortBy) {
178 this->sortBy = sortBy;
179 updateQuery(true);
180 QSettings settings;
181 settings.setValue(sortByKey, (int)sortBy);
182 }
183
setReversedOrder(bool reversedOrder)184 void AlbumListView::setReversedOrder(bool reversedOrder) {
185 this->reversedOrder = reversedOrder;
186 updateQuery(true);
187 QSettings settings;
188 settings.setValue(reverseOrderKey, reversedOrder);
189 }
190