Add M4A to files pattern
[someplayer] / src / directoryview.cpp
1 /*
2  * SomePlayer - An alternate music player for Maemo 5
3  * Copyright (C) 2010 Nikolay (somebody) Tischenko <niktischenko@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 #include "directoryview.h"
21 #include "ui_directoryview.h"
22 #include <QDir>
23 #include <QFileInfo>
24 #include "someplayer.h"
25 #include <QDebug>
26 #include <QRegExp>
27 #include "config.h"
28
29 using namespace SomePlayer::Storage;
30 using namespace SomePlayer::DataObjects;
31
32 DirectoryView::DirectoryView(QWidget *parent) :
33                 QWidget(parent),
34                 ui(new Ui::DirectoryView)
35 {
36         ui->setupUi(this);
37         Config config;
38         _icons_theme = config.getValue("ui/iconstheme").toString();
39         REGISTERED_FILE_EXTENSIONS << "mp3" << "flac" << "wma" << "aac" << "ogg" << "asf" << "ape" << "wav" << "m4a";
40         setWindowFlags(windowFlags() | Qt::Window);
41         setAttribute(Qt::WA_Maemo5StackedWindow);
42         _model = new QStandardItemModel(0, 2, this);
43         ui->dirView->setModel(_model);
44         ui->dirView->setColumnHidden(2, true);
45         _current_dir = QDir::homePath();
46         _tagresolver = new TagResolver(this);
47         _mediascanner = new MediaScanner(this);
48
49         ui->addButton->setEnabled(false);
50         ui->addButton->setIcon(QIcon());
51
52         ui->progressBar->hide();
53
54         _home();
55         connect(ui->backButton, SIGNAL(clicked()), this, SLOT(_back()));
56         connect(ui->dirView, SIGNAL(clicked(QModelIndex)), this, SLOT(_process_click(QModelIndex)));
57         connect(ui->dirView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(_process_dblclick(QModelIndex)));
58         connect(ui->dirView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this,
59                 SLOT(_process_selection(QItemSelection,QItemSelection)));
60         connect(ui->homeButton, SIGNAL(clicked()), this, SLOT(_home()));
61         connect(ui->selectToggleButton, SIGNAL(clicked()), this, SLOT(_toggle_selection()));
62         connect(ui->addButton, SIGNAL(clicked()), this, SLOT(_add()));
63         connect(_tagresolver, SIGNAL(decoded(Track)), this, SLOT(_add_track(Track)));
64         connect(_tagresolver, SIGNAL(done()), this, SLOT(_done()));
65         connect(ui->playerButton, SIGNAL(clicked()), this, SLOT(hide()));
66         _top_gradient = ui->topWidget->styleSheet();
67         _bottom_gradient = ui->bottomWidget->styleSheet();
68 }
69
70 DirectoryView::~DirectoryView()
71 {
72         delete ui;
73 }
74
75 void DirectoryView::readDir(QString path, QString pathToScroll) {
76         QDir dir(path);
77         _current_dir = dir.absoluteFilePath(path);
78         _directories.clear();
79         _files.clear();
80         QList<QString> dirnames;
81         QList<QString> filenames;
82         QFileInfoList items = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden);
83         foreach (QFileInfo info, items) {
84                 if (info.isDir()) {
85                         if (info.fileName().startsWith(".")) {
86                                 if (info.fileName() == ".sounds") {
87                                         _directories << info.absoluteFilePath();
88                                         dirnames << tr("Audioclips");
89                                 }
90                         } else {
91                                 _directories << info.absoluteFilePath();
92                                 dirnames << info.fileName();
93                         }
94                 } else {
95                         if (REGISTERED_FILE_EXTENSIONS.contains(info.suffix().toLower())) {
96                                 _files << info.absoluteFilePath();
97                                 filenames << info.fileName();
98                         }
99                 }
100         }
101         _model->setRowCount(dirnames.count() + filenames.count());
102         int i = 0;
103         foreach (QString str, dirnames) {
104                 _model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
105                 _model->setItem(i, 1, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/folder.png"), str));
106                 i++;
107         }
108         foreach (QString str, filenames) {
109                 _model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
110                 _model->setItem(i, 1, new QStandardItem(str));
111                 i++;
112         }
113         ui->dirView->setColumnWidth(0, 70);
114         ui->addButton->setEnabled(false);
115         ui->addButton->setIcon(QIcon());
116         if (pathToScroll.isEmpty()) {
117                 ui->dirView->scrollToTop();
118                 return;
119         }
120         int row = _directories.indexOf(pathToScroll);
121         if (row >= 0 && row < _model->rowCount()) {
122                 QModelIndex id = _model->index(row, 1);
123                 ui->dirView->scrollTo(id, QAbstractItemView::PositionAtCenter);
124         }
125 }
126
127 void DirectoryView::_back() {
128         QDir current(_current_dir);
129         current.cdUp();
130         QString dir_to_center = "";
131         if (_nav_history.size() > 0) {
132                 dir_to_center = _nav_history.pop();
133         }
134         readDir(current.path(), dir_to_center);
135 }
136
137 void DirectoryView::_process_click(QModelIndex index) {
138         if (index.column() == 0) {
139         } else {
140                 if (index.row() < _directories.count()) {
141                         _current_dir = _directories.at(index.row());
142                         readDir(_current_dir);
143                         _nav_history.push(_current_dir);
144                         return;
145                 }
146         }
147 }
148
149 void DirectoryView::_process_dblclick(QModelIndex index) {
150         if (index.column() == 0) {
151         } else {
152                 if (index.row() >= _directories.count()) {
153                         QString filename = _files.at(index.row() - _directories.count());
154                         Track track = _tagresolver->decodeOne(filename);
155                         emit addAndPlay(track);
156                         return;
157                 }
158         }
159 }
160
161 void DirectoryView::_process_selection(QItemSelection selected, QItemSelection deselected) {
162         foreach (QModelIndex id, selected.indexes()) {
163                 if (id.column() == 0) {
164                         _model->item(id.row())->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
165                 }
166                 ui->dirView->selectionModel()->select(id, QItemSelectionModel::Select);
167         }
168         foreach (QModelIndex id, deselected.indexes()) {
169                 if (id.column() == 0) {
170                         _model->item(id.row())->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
171                 }
172                 ui->dirView->selectionModel()->select(id, QItemSelectionModel::Deselect);
173         }
174         if (ui->dirView->selectionModel()->selectedRows().count() > 0) {
175                 ui->addButton->setEnabled(true);
176                 ui->addButton->setIcon(QIcon(":/icons/"+_icons_theme+"/add.png"));
177         } else {
178                 ui->addButton->setEnabled(false);
179                 ui->addButton->setIcon(QIcon());
180         }
181 }
182
183 void DirectoryView::_home() {
184         _current_dir = QDir::homePath();
185         homeScreen();
186         _nav_history.clear();
187 }
188
189 void DirectoryView::_toggle_selection() {
190         if (ui->dirView->selectionModel()->selectedRows().count() == _model->rowCount()) {
191                 ui->dirView->clearSelection();
192                 ui->selectToggleButton->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
193         } else {
194                 ui->dirView->selectAll();
195                 ui->selectToggleButton->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
196         }
197 }
198
199 void DirectoryView::_add() {
200         QModelIndexList selected = ui->dirView->selectionModel()->selectedRows(1);
201         QStringList files;
202         QStringList directories;
203         foreach (QModelIndex index, selected) {
204                 if (index.row() >= _directories.count()) {
205                         files << _files.at(index.row() - _directories.count());
206                 } else {
207                         directories << _directories.at(index.row());
208                 }
209         }
210         foreach (QString dir, directories) {
211                 files.append(_mediascanner->singleScan(dir));
212         }
213         _tracks.clear();
214         ui->progressBar->setMinimum(0);
215         ui->progressBar->setMaximum(files.count());
216         ui->progressBar->show();
217         _tagresolver->decode(files);
218         ui->dirView->clearSelection();
219 }
220
221 void DirectoryView::_add_track(Track track) {
222         _tracks.append(track);
223         ui->progressBar->setValue(ui->progressBar->value()+1);
224 }
225
226 void DirectoryView::_done() {
227         emit addTracks(_tracks);
228         ui->progressBar->hide();
229         _tracks.clear();
230 }
231
232 void DirectoryView::updateIcons() {
233         Config config;
234         _icons_theme = config.getValue("ui/iconstheme").toString();
235         if (!ui->addButton->icon().isNull())
236                 ui->addButton->setIcon(QIcon(":/icons/"+_icons_theme+"/add.png"));
237         ui->homeButton->setIcon(QIcon(":/icons/"+_icons_theme+"/home.png"));
238         ui->backButton->setIcon(QIcon(":/icons/"+_icons_theme+"/back.png"));
239         if (ui->dirView->selectionModel()->selectedRows().count() == _model->rowCount()) {
240                 ui->selectToggleButton->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
241         } else {
242                 ui->selectToggleButton->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
243         }
244         ui->playerButton->setIcon(QIcon(":/icons/"+_icons_theme+"/player.png"));
245         _home();
246 }
247
248 void DirectoryView::checkGradient() {
249         Config config;
250         if (config.getValue("ui/gradient").toString() == "yes") {
251                 ui->bottomWidget->setStyleSheet(_bottom_gradient);
252                 ui->topWidget->setStyleSheet(_top_gradient);
253         } else {
254                 ui->topWidget->setStyleSheet("");
255                 ui->bottomWidget->setStyleSheet("");
256         }
257 }
258
259 void DirectoryView::lanscapeMode() {
260         ui->topWidget->hide();
261         ui->bottomWidget->hide();
262         ui->lverticalLayout->removeItem(ui->lverticalSpacer_0);
263         ui->lverticalLayout->removeItem(ui->lverticalSpacer_1);
264         ui->lverticalLayout->addWidget(ui->backButton);
265         ui->lverticalLayout->addItem(ui->lverticalSpacer_0);
266         ui->lverticalLayout->addWidget(ui->homeButton);
267         ui->lverticalLayout->addItem(ui->lverticalSpacer_1);
268         ui->lverticalLayout->addWidget(ui->playerButton);
269         ui->rverticalLayout->removeItem(ui->rverticalSpacer);
270         ui->rverticalLayout->addWidget(ui->addButton);
271         ui->rverticalLayout->addItem(ui->rverticalSpacer);
272         ui->rverticalLayout->addWidget(ui->selectToggleButton);
273         ui->lverticalWidget->show();
274         ui->rverticalWidget->show();
275 }
276
277 void DirectoryView::portraitMode() {
278         ui->lverticalWidget->hide();
279         ui->rverticalWidget->hide();
280         ui->lverticalLayout->removeItem(ui->lverticalSpacer_0);
281         ui->lverticalLayout->removeItem(ui->lverticalSpacer_1);
282         ui->rverticalLayout->removeItem(ui->rverticalSpacer);
283         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_0);
284         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_1);
285         ui->topWidget->layout()->addWidget(ui->backButton);
286         ui->topWidget->layout()->addItem(ui->thorizontalSpacer_0);
287         ui->topWidget->layout()->addWidget(ui->homeButton);
288         ui->topWidget->layout()->addItem(ui->thorizontalSpacer_1);
289         ui->topWidget->layout()->addWidget(ui->addButton);
290         ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer);
291         ui->bottomWidget->layout()->addWidget(ui->playerButton);
292         ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer);
293         ui->bottomWidget->layout()->addWidget(ui->selectToggleButton);
294         ui->topWidget->show();
295         ui->bottomWidget->show();
296 }
297
298 void DirectoryView::updateTranslations() {
299         ui->retranslateUi(this);
300 }
301
302 void DirectoryView::homeScreen() {
303         _directories.clear();
304         _files.clear();
305         _model->clear();
306         _model->setRowCount(2);
307         _model->setColumnCount(2);
308         _model->setItem(0, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
309         _model->setItem(0, 1, new QStandardItem(tr("Inner memory")));
310         _model->setItem(1, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
311         _model->setItem(1, 1, new QStandardItem(tr("Memory card")));
312         _directories << QDir::homePath()+"/MyDocs/";
313         _directories << "/media/mmc1/";
314         ui->dirView->setColumnWidth(0, 70);
315         ui->addButton->setEnabled(false);
316         ui->addButton->setIcon(QIcon());
317 }