07a208ae0aab0f4a25ac09c611a4fac49c085776
[tomamp] / mainwindow.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the examples of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial Usage
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file.  Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
35 **
36 ** If you have questions regarding the use of this file, please contact
37 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
39 **
40 ***************************************************************************/
41
42 #include <QtGui>
43 #include <QtDebug>
44
45 #include "mainwindow.h"
46
47 MainWindow::MainWindow()
48     : settings (tr ("TomAmp"), "TomAmp")
49 {
50     audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
51     mediaObject = new Phonon::MediaObject(this);
52     metaInformationResolver = new Phonon::MediaObject(this);
53
54     mediaObject->setTickInterval(1000);
55     connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
56     connect(mediaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
57     this, SLOT(stateChanged(Phonon::State,Phonon::State)));
58     connect(metaInformationResolver, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
59     this, SLOT(metaStateChanged(Phonon::State,Phonon::State)));
60     connect(mediaObject, SIGNAL(currentSourceChanged(Phonon::MediaSource)),
61     this, SLOT(sourceChanged(Phonon::MediaSource)));
62     connect(mediaObject, SIGNAL(aboutToFinish()), this, SLOT(aboutToFinish()));
63
64     Phonon::createPath(mediaObject, audioOutput);
65
66     setupActions();
67     setupMenus();
68     setupUi();
69     timeLcd->display("00:00");
70 }
71
72 void MainWindow::addFiles()
73 {
74     QString folder = settings.value("LastFolder").toString();
75     if (folder.isEmpty())
76         folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
77     QStringList files = QFileDialog::getOpenFileNames(this, tr("Select Files To Add"),
78                     folder);
79
80     if (files.isEmpty())
81         return;
82
83     QString dir = QFileInfo (files[0]).absoluteDir().absolutePath();
84     settings.setValue("LastFolder", dir);
85     int index = sources.size();
86     foreach (QString string, files)
87     {
88         Phonon::MediaSource source (string);
89         sources.append(source);
90     }
91     if (!sources.isEmpty())
92         metaInformationResolver->setCurrentSource(sources.at(index));
93
94 }
95
96 void MainWindow::addFolders()
97 {
98     QString folder = settings.value("LastFolder").toString();
99     if (folder.isEmpty())
100         folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
101     QString dir = QFileDialog::getExistingDirectory(this,
102             tr("Select Directory To Add"),
103             folder);
104
105     QStringList filters;
106     filters << "*.mp3";
107
108     QStringList files = QDir (dir).entryList(filters);
109
110     if (files.isEmpty())
111         return;
112
113     settings.setValue("LastFolder", dir);
114     int index = sources.size();
115     foreach (QString string, files)
116     {
117         QString fname = dir + "/" + string;
118         qDebug () << fname;
119         Phonon::MediaSource source(fname);
120         sources.append(source);
121     }
122     if (!sources.isEmpty())
123         metaInformationResolver->setCurrentSource(sources.at(index));
124
125 }
126
127
128 void MainWindow::about()
129 {
130     QMessageBox::information(this, tr("About Music Player"),
131         tr("The Music Player example shows how to use Phonon - the multimedia"
132         " framework that comes with Qt - to create a simple music player."));
133 }
134
135 void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */)
136 {
137     qDebug () << "State: " << newState;
138     switch (newState)
139     {
140         case Phonon::ErrorState:
141             if (mediaObject->errorType() == Phonon::FatalError)
142             {
143                 QMessageBox::warning(this, tr("Fatal Error"),
144                 mediaObject->errorString());
145             }
146             else
147             {
148                 QMessageBox::warning(this, tr("Error"),
149                 mediaObject->errorString());
150             }
151             break;
152         case Phonon::PlayingState:
153             setWindowTitle(metaInformationResolver->metaData().value("TITLE") + " - TomAmp");
154             playAction->setEnabled(false);
155             pauseAction->setEnabled(true);
156             stopAction->setEnabled(true);
157             break;
158         case Phonon::StoppedState:
159             stopAction->setEnabled(false);
160             playAction->setEnabled(true);
161             pauseAction->setEnabled(false);
162             timeLcd->display("00:00");
163             break;
164         case Phonon::PausedState:
165             pauseAction->setEnabled(false);
166             stopAction->setEnabled(true);
167             playAction->setEnabled(true);
168             qDebug () << "Queue size: " << mediaObject->queue().size ();
169             if (mediaObject->queue().size ())
170             {
171                 int index = sources.indexOf(mediaObject->currentSource());
172                 mediaObject->setCurrentSource(
173                     sources.at(index));
174                 mediaObject->play ();
175                 musicTable->setCurrentCell(index, 0);;
176             }
177             break;
178         case Phonon::BufferingState:
179             break;
180         default:
181         ;
182     }
183 }
184
185 void MainWindow::tick(qint64 time)
186 {
187     QTime displayTime(0, (time / 60000) % 60, (time / 1000) % 60);
188
189     timeLcd->display(displayTime.toString("mm:ss"));
190 }
191
192 void MainWindow::tableClicked(int row, int /* column */)
193 {
194 //    bool wasPlaying = mediaObject->state() == Phonon::PlayingState;
195
196     mediaObject->stop();
197     mediaObject->clearQueue();
198
199     if (row >= sources.size())
200         return;
201
202     mediaObject->setCurrentSource(sources[row]);
203
204     mediaObject->play();
205 }
206
207 void MainWindow::sourceChanged(const Phonon::MediaSource &source)
208 {
209     musicTable->selectRow(sources.indexOf(source));
210     timeLcd->display("00:00");
211 }
212
213 void MainWindow::metaStateChanged(Phonon::State newState, Phonon::State /* oldState */)
214 {
215     if (newState == Phonon::ErrorState)
216     {
217         QMessageBox::warning(this, tr("Error opening files"),
218         metaInformationResolver->errorString());
219         while (!sources.isEmpty() &&
220             !(sources.takeLast() == metaInformationResolver->currentSource())) {}  /* loop */;
221         return;
222     }
223
224     if (newState != Phonon::StoppedState && newState != Phonon::PausedState)
225     {
226         return;
227     }
228
229     if (metaInformationResolver->currentSource().type() == Phonon::MediaSource::Invalid)
230         return;
231
232     QMap<QString, QString> metaData = metaInformationResolver->metaData();
233
234     QString title = metaData.value("TITLE");
235     if (title == "")
236         title = metaInformationResolver->currentSource().fileName();
237
238     QTableWidgetItem *titleItem = new QTableWidgetItem(title);
239     titleItem->setFlags(titleItem->flags() ^ Qt::ItemIsEditable);
240     QTableWidgetItem *artistItem = new QTableWidgetItem(metaData.value("ARTIST"));
241     artistItem->setFlags(artistItem->flags() ^ Qt::ItemIsEditable);
242     QTableWidgetItem *albumItem = new QTableWidgetItem(metaData.value("ALBUM"));
243     albumItem->setFlags(albumItem->flags() ^ Qt::ItemIsEditable);
244     QTableWidgetItem *yearItem = new QTableWidgetItem(metaData.value("DATE"));
245     yearItem->setFlags(yearItem->flags() ^ Qt::ItemIsEditable);
246
247     int currentRow = musicTable->rowCount();
248     musicTable->insertRow(currentRow);
249     musicTable->setItem(currentRow, 0, artistItem);
250     musicTable->setItem(currentRow, 1, titleItem);
251     musicTable->setItem(currentRow, 2, albumItem);
252     musicTable->setItem(currentRow, 3, yearItem);
253
254
255     if (musicTable->selectedItems().isEmpty())
256     {
257         musicTable->selectRow(0);
258         mediaObject->setCurrentSource(metaInformationResolver->currentSource());
259     }
260
261     Phonon::MediaSource source = metaInformationResolver->currentSource();
262     int index = sources.indexOf(metaInformationResolver->currentSource()) + 1;
263     if (sources.size() > index)
264     {
265         metaInformationResolver->setCurrentSource(sources.at(index));
266     }
267     else
268     {
269         musicTable->resizeColumnsToContents();
270         if (musicTable->columnWidth(0) > 300)
271             musicTable->setColumnWidth(0, 300);
272     }
273 }
274
275 void MainWindow::aboutToFinish()
276 {
277     int index = sources.indexOf(mediaObject->currentSource()) + 1;
278     if (sources.size() > index)
279     {
280         mediaObject->enqueue(sources.at(index));
281         qDebug () << "Enqueue " << index;
282     }
283 }
284
285 void MainWindow::setupActions()
286 {
287     playAction = new QAction(style()->standardIcon(QStyle::SP_MediaPlay), tr("Play"), this);
288     playAction->setShortcut(tr("Crl+P"));
289     playAction->setDisabled(true);
290     pauseAction = new QAction(style()->standardIcon(QStyle::SP_MediaPause), tr("Pause"), this);
291     pauseAction->setShortcut(tr("Ctrl+A"));
292     pauseAction->setDisabled(true);
293     stopAction = new QAction(style()->standardIcon(QStyle::SP_MediaStop), tr("Stop"), this);
294     stopAction->setShortcut(tr("Ctrl+S"));
295     stopAction->setDisabled(true);
296     nextAction = new QAction(style()->standardIcon(QStyle::SP_MediaSkipForward), tr("Next"), this);
297     nextAction->setShortcut(tr("Ctrl+N"));
298     previousAction = new QAction(style()->standardIcon(QStyle::SP_MediaSkipBackward), tr("Previous"), this);
299     previousAction->setShortcut(tr("Ctrl+R"));
300     addFilesAction = new QAction(tr("Add &File"), this);
301     addFilesAction->setShortcut(tr("Ctrl+F"));
302     addFoldersAction = new QAction(tr("Add F&older"), this);
303     addFoldersAction->setShortcut(tr("Ctrl+O"));
304     exitAction = new QAction(tr("E&xit"), this);
305     exitAction->setShortcuts(QKeySequence::Quit);
306     aboutAction = new QAction(tr("A&bout"), this);
307     aboutAction->setShortcut(tr("Ctrl+B"));
308     aboutQtAction = new QAction(tr("About &Qt"), this);
309     aboutQtAction->setShortcut(tr("Ctrl+Q"));
310
311     connect(playAction, SIGNAL(triggered()), mediaObject, SLOT(play()));
312     connect(pauseAction, SIGNAL(triggered()), mediaObject, SLOT(pause()) );
313     connect(stopAction, SIGNAL(triggered()), mediaObject, SLOT(stop()));
314     connect(addFilesAction, SIGNAL(triggered()), this, SLOT(addFiles()));
315     connect(addFoldersAction, SIGNAL(triggered()), this, SLOT(addFolders()));
316     connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
317     connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
318     connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
319 }
320
321 void MainWindow::setupMenus()
322 {
323     QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
324     fileMenu->addAction(addFilesAction);
325     fileMenu->addAction(addFoldersAction);
326     fileMenu->addSeparator();
327     fileMenu->addAction(exitAction);
328
329     QMenu *aboutMenu = menuBar()->addMenu(tr("&Help"));
330     aboutMenu->addAction(aboutAction);
331     aboutMenu->addAction(aboutQtAction);
332 }
333
334 void MainWindow::setupUi()
335 {
336     QToolBar *bar = new QToolBar;
337
338     bar->setOrientation(Qt::Vertical);
339     bar->addAction(playAction);
340     bar->addAction(pauseAction);
341     bar->addAction(stopAction);
342
343     seekSlider = new Phonon::SeekSlider(this);
344     seekSlider->setMediaObject(mediaObject);
345
346     volumeSlider = new Phonon::VolumeSlider(this);
347     volumeSlider->setAudioOutput(audioOutput);
348     volumeSlider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
349     volumeSlider->setOrientation(Qt::Vertical);
350
351     QLabel *volumeLabel = new QLabel;
352     volumeLabel->setPixmap(QPixmap("images/volume.png"));
353
354 /*    QPalette palette;
355     palette.setBrush(QPalette::Light, Qt::darkGray);*/
356
357     timeLcd = new QLCDNumber;
358 //    timeLcd->setPalette(palette);
359
360     QStringList headers;
361     headers << tr("Artist") << tr("Title") << tr("Album") << tr("Year");
362
363     musicTable = new QTableWidget(0, 4);
364     musicTable->setHorizontalHeaderLabels(headers);
365     musicTable->setSelectionMode(QAbstractItemView::SingleSelection);
366     musicTable->setSelectionBehavior(QAbstractItemView::SelectRows);
367     connect(musicTable, SIGNAL(cellDoubleClicked(int,int)),
368         this, SLOT(tableClicked(int,int)));
369
370     QHBoxLayout *seekerLayout = new QHBoxLayout;
371     seekerLayout->addWidget(seekSlider);
372     seekerLayout->addWidget(timeLcd);
373
374     QVBoxLayout *playbackLayout = new QVBoxLayout;
375     playbackLayout->addWidget(bar);
376     playbackLayout->addStretch();
377     playbackLayout->addWidget(volumeSlider);
378     playbackLayout->addWidget(volumeLabel);
379
380     QVBoxLayout *seekAndTableLayout = new QVBoxLayout;
381
382     seekAndTableLayout->addWidget(musicTable);
383     seekAndTableLayout->addLayout(seekerLayout);
384
385     QHBoxLayout *mainLayout = new QHBoxLayout;
386     mainLayout->addLayout(seekAndTableLayout);
387     mainLayout->addLayout(playbackLayout);
388
389     QWidget *widget = new QWidget;
390     widget->setLayout(mainLayout);
391
392     setCentralWidget(widget);
393     setWindowTitle("TomAmp");
394 //    ui.setupUi(this);
395 }
396