3 #include <QInputDialog>
5 #include "mainwindow.h"
7 #define AVOID_INPUT_DIALOG 1
9 MainWindow::MainWindow()
10 : settings (tr ("TomAmp"), "TomAmp")
12 audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
13 mediaObject = new Phonon::MediaObject(this);
14 metaInformationResolver = new Phonon::MediaObject(this);
16 mediaObject->setTickInterval(500);
17 connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
18 connect(mediaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
19 this, SLOT(stateChanged(Phonon::State,Phonon::State)));
20 connect(metaInformationResolver, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
21 this, SLOT(metaStateChanged(Phonon::State,Phonon::State)));
22 connect(mediaObject, SIGNAL(currentSourceChanged(Phonon::MediaSource)),
23 this, SLOT(sourceChanged(Phonon::MediaSource)));
24 connect(mediaObject, SIGNAL(aboutToFinish()), this, SLOT(aboutToFinish()));
26 Phonon::createPath(mediaObject, audioOutput);
28 repeat = settings.value("repeat", false).toBool();
29 shuffle = settings.value("shuffle", false).toBool();
35 timeLcd->display("00:00");
36 addStringList(settings.value("lastPlaylist").toStringList());
37 audioOutput->setVolume(settings.value("volume", .5).toReal());
40 MainWindow::~MainWindow()
42 settings.setValue("shuffle", shuffle);
44 foreach (Phonon::MediaSource src, sources)
46 if (src.type () == Phonon::MediaSource::LocalFile)
47 curList.append(src.fileName());
49 curList.append(src.url().toString());
51 settings.setValue("lastPlaylist", curList);
52 settings.setValue("volume", audioOutput->volume());
55 void MainWindow::addFiles()
57 QString folder = settings.value("LastFolder").toString();
59 folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
60 QStringList files = QFileDialog::getOpenFileNames(this, tr("Select Files To Add"),
66 QString dir = QFileInfo (files[0]).absoluteDir().absolutePath();
67 settings.setValue("LastFolder", dir);
68 int index = sources.size();
69 foreach (QString string, files)
71 Phonon::MediaSource source (string);
72 sources.append(source);
74 if (!sources.isEmpty())
75 metaInformationResolver->setCurrentSource(sources.at(index));
80 void MainWindow::addFolders()
82 QString folder = settings.value("LastFolder").toString();
84 folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
85 QString dir = QFileDialog::getExistingDirectory(this,
86 tr("Select Directory To Add"),
92 QStringList files = QDir (dir).entryList(filters);
97 settings.setValue("LastFolder", dir);
98 int index = sources.size();
99 foreach (QString string, files)
101 QString fname = dir + "/" + string;
103 Phonon::MediaSource source(fname);
104 sources.append(source);
106 if (!sources.isEmpty())
107 metaInformationResolver->setCurrentSource(sources.at(index));
112 void MainWindow::addUrl()
114 #ifdef AVOID_INPUT_DIALOG
115 QString url = "http://war.str3am.com:7970";
117 QString url = QInputDialog::getText(this, "Get URL", "Please type in the stream URL");
119 int index = sources.size();
122 Phonon::MediaSource source(url);
123 sources.append(source);
125 if (!sources.isEmpty())
126 metaInformationResolver->setCurrentSource(sources.at(index));
130 void MainWindow::addStringList(const QStringList& list)
132 int index = sources.size();
133 foreach (QString string, list)
135 Phonon::MediaSource source(string);
136 sources.append(source);
138 if (!sources.isEmpty())
139 metaInformationResolver->setCurrentSource(sources.at(index));
143 void MainWindow::about()
145 QMessageBox::information(this, tr("About Music Player"),
146 tr("The Music Player example shows how to use Phonon - the multimedia"
147 " framework that comes with Qt - to create a simple music player."));
150 void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */)
152 qDebug () << "State: " << newState;
155 case Phonon::ErrorState:
156 if (mediaObject->errorType() == Phonon::FatalError)
158 QMessageBox::warning(this, tr("Fatal Error"),
159 mediaObject->errorString());
163 QMessageBox::warning(this, tr("Error"),
164 mediaObject->errorString());
167 case Phonon::PlayingState:
168 setWindowTitle(mediaObject->metaData().value("TITLE") + " - TomAmp");
169 playAction->setEnabled(false);
170 pauseAction->setEnabled(true);
171 stopAction->setEnabled(true);
173 case Phonon::StoppedState:
174 stopAction->setEnabled(false);
175 playAction->setEnabled(true);
176 pauseAction->setEnabled(false);
177 timeLcd->display("00:00");
179 case Phonon::PausedState:
180 pauseAction->setEnabled(false);
181 stopAction->setEnabled(true);
182 playAction->setEnabled(true);
183 qDebug () << "Queue size: " << mediaObject->queue().size ();
184 if (mediaObject->queue().size ())
186 mediaObject->setCurrentSource(mediaObject->queue()[0]);
187 musicTable->selectRow(sources.indexOf(mediaObject->currentSource()));
190 mediaObject->clearQueue();
192 case Phonon::BufferingState:
193 qDebug () << "Buffering";
200 void MainWindow::tick(qint64 time)
202 QTime displayTime(0, (time / 60000) % 60, (time / 1000) % 60);
204 timeLcd->display(displayTime.toString("mm:ss"));
207 void MainWindow::tableClicked(int row, int /* column */)
209 // bool wasPlaying = mediaObject->state() == Phonon::PlayingState;
212 mediaObject->clearQueue();
214 if (row >= sources.size())
217 mediaObject->setCurrentSource(sources[row]);
220 int ind = shuffleList.indexOf(row);
221 shuffleList.removeAt(ind);
222 shuffleList.insert(0, row);
223 qDebug () << "Modified shuffle list: " << shuffleList;
226 void MainWindow::sourceChanged(const Phonon::MediaSource &source)
228 musicTable->selectRow(sources.indexOf(source));
229 timeLcd->display("00:00");
232 void MainWindow::metaStateChanged(Phonon::State newState, Phonon::State /* oldState */)
234 if (newState == Phonon::ErrorState)
236 QMessageBox::warning(this, tr("Error opening files"),
237 metaInformationResolver->errorString());
238 while (!sources.isEmpty() &&
239 !(sources.takeLast() == metaInformationResolver->currentSource())) {} /* loop */;
243 if (newState != Phonon::StoppedState && newState != Phonon::PausedState)
248 if (metaInformationResolver->currentSource().type() == Phonon::MediaSource::Invalid)
251 QMap<QString, QString> metaData = metaInformationResolver->metaData();
253 QString title = metaData.value("TITLE");
255 title = metaInformationResolver->currentSource().fileName();
258 title = metaInformationResolver->currentSource().url().toString();
260 QTableWidgetItem *titleItem = new QTableWidgetItem(title);
261 titleItem->setFlags(titleItem->flags() ^ Qt::ItemIsEditable);
262 QTableWidgetItem *artistItem = new QTableWidgetItem(metaData.value("ARTIST"));
263 artistItem->setFlags(artistItem->flags() ^ Qt::ItemIsEditable);
264 QTableWidgetItem *albumItem = new QTableWidgetItem(metaData.value("ALBUM"));
265 albumItem->setFlags(albumItem->flags() ^ Qt::ItemIsEditable);
266 QTableWidgetItem *yearItem = new QTableWidgetItem(metaData.value("DATE"));
267 yearItem->setFlags(yearItem->flags() ^ Qt::ItemIsEditable);
269 int currentRow = musicTable->rowCount();
270 musicTable->insertRow(currentRow);
271 musicTable->setItem(currentRow, 0, artistItem);
272 musicTable->setItem(currentRow, 1, titleItem);
273 musicTable->setItem(currentRow, 2, albumItem);
274 musicTable->setItem(currentRow, 3, yearItem);
277 if (musicTable->selectedItems().isEmpty())
279 musicTable->selectRow(0);
280 mediaObject->setCurrentSource(metaInformationResolver->currentSource());
283 Phonon::MediaSource source = metaInformationResolver->currentSource();
284 int index = sources.indexOf(metaInformationResolver->currentSource()) + 1;
285 if (sources.size() > index)
287 metaInformationResolver->setCurrentSource(sources.at(index));
291 musicTable->resizeColumnsToContents();
292 if (musicTable->columnWidth(0) > 300)
293 musicTable->setColumnWidth(0, 300);
297 void MainWindow::aboutToFinish()
299 qDebug () << "Abouttotfinish";
300 int index = sources.indexOf(mediaObject->currentSource()) + 1;
303 index = shuffleList.indexOf(sources.indexOf(mediaObject->currentSource())) + 1;
304 if (index < shuffleList.size ())
306 mediaObject->enqueue(sources.at (shuffleList[index]));
310 mediaObject->enqueue(sources.at (shuffleList[0]));
316 if (sources.size() > index)
318 mediaObject->enqueue(sources.at(index));
319 qDebug () << "Enqueue " << index << " pfm " << mediaObject->prefinishMark();
323 mediaObject->enqueue(sources.at(0));
324 qDebug () << "Enqueue " << 0 << " pfm " << mediaObject->prefinishMark();
329 void MainWindow::finished()
331 qDebug () << "Finished";
334 void MainWindow::setupActions()
336 playAction = new QAction(style()->standardIcon(QStyle::SP_MediaPlay), tr("Play"), this);
337 playAction->setShortcut(tr("Crl+P"));
338 playAction->setDisabled(true);
339 pauseAction = new QAction(style()->standardIcon(QStyle::SP_MediaPause), tr("Pause"), this);
340 pauseAction->setShortcut(tr("Ctrl+A"));
341 pauseAction->setDisabled(true);
342 stopAction = new QAction(style()->standardIcon(QStyle::SP_MediaStop), tr("Stop"), this);
343 stopAction->setShortcut(tr("Ctrl+S"));
344 stopAction->setDisabled(true);
345 nextAction = new QAction(style()->standardIcon(QStyle::SP_MediaSkipForward), tr("Next"), this);
346 nextAction->setShortcut(tr("Ctrl+N"));
347 previousAction = new QAction(style()->standardIcon(QStyle::SP_MediaSkipBackward), tr("Previous"), this);
348 previousAction->setShortcut(tr("Ctrl+R"));
349 repeatAction = new QAction(style()->standardIcon(QStyle::SP_BrowserReload), tr("Repeat"), this);
350 repeatAction->setCheckable(true);
351 repeatAction->setChecked(repeat);
352 repeatAction->setShortcut(tr("Ctrl+I"));
353 shuffleAction = new QAction(QIcon (QPixmap (":images/shuffle")), tr("Shuffle"), this);
354 shuffleAction->setCheckable(true);
355 shuffleAction->setChecked(shuffle);
356 shuffleAction->setShortcut(tr("Ctrl+H"));
357 volumeAction = new QAction(QIcon (QPixmap (":images/volume")), tr("Volume"), this);
358 volumeAction->setCheckable(true);
359 volumeAction->setShortcut(tr("Ctrl+V"));
360 addFilesAction = new QAction(tr("Add &File"), this);
361 addFilesAction->setShortcut(tr("Ctrl+F"));
362 addFoldersAction = new QAction(tr("Add F&older"), this);
363 addFoldersAction->setShortcut(tr("Ctrl+O"));
364 addUrlAction = new QAction(tr("Add &Url"), this);
365 addUrlAction->setShortcut(tr("Ctrl+U"));
366 savePlaylistAction = new QAction (tr("Sa&ve Playlist"), this);
367 savePlaylistAction->setShortcut(tr ("Ctrl+V"));
368 loadPlaylistAction = new QAction (tr("&Load Playlist"), this);
369 loadPlaylistAction->setShortcut(tr("Ctrl+L"));
370 clearPlaylistAction = new QAction (tr("&Clear Playlist"), this);
371 clearPlaylistAction->setShortcut(tr("Ctrl+C"));
372 exitAction = new QAction(tr("E&xit"), this);
373 exitAction->setShortcut(tr("Ctrl+X"));
374 aboutAction = new QAction(tr("A&bout"), this);
375 aboutAction->setShortcut(tr("Ctrl+B"));
376 aboutQtAction = new QAction(tr("About &Qt"), this);
377 aboutQtAction->setShortcut(tr("Ctrl+Q"));
379 connect(playAction, SIGNAL(triggered()), mediaObject, SLOT(play()));
380 connect(pauseAction, SIGNAL(triggered()), mediaObject, SLOT(pause()) );
381 connect(stopAction, SIGNAL(triggered()), mediaObject, SLOT(stop()));
382 connect(repeatAction, SIGNAL(triggered()), this, SLOT(repeatToggle()));
383 connect(shuffleAction, SIGNAL(triggered()), this, SLOT(shuffleToggle()));
384 connect(volumeAction, SIGNAL(triggered()), this, SLOT(volumeToggle()));
385 connect(addFilesAction, SIGNAL(triggered()), this, SLOT(addFiles()));
386 connect(addFoldersAction, SIGNAL(triggered()), this, SLOT(addFolders()));
387 connect(addUrlAction, SIGNAL(triggered()), this, SLOT(addUrl()));
388 connect (savePlaylistAction, SIGNAL (triggered()), this, SLOT (savePlaylist()));
389 connect (loadPlaylistAction, SIGNAL (triggered()), this, SLOT (loadPlaylist()));
390 connect (clearPlaylistAction, SIGNAL (triggered()), this, SLOT (clearPlaylist()));
391 connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
392 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
393 connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
396 void MainWindow::savePlaylist()
398 QString filename = QFileDialog::getSaveFileName(this, tr("Please select file name"), "", "*.m3u");
399 if (filename.isEmpty())
401 if (filename.length() < 4 || filename.right(4).toLower() != ".m3u")
406 f.open(QFile::WriteOnly);
407 for (int i = 0; i < sources.size(); ++i)
409 if (sources[i].type() == Phonon::MediaSource::Stream)
410 f.write(sources[i].url().toString().toAscii());
412 f.write (sources[i].fileName().toAscii());
419 QMessageBox::critical(this, "Write error", "Could not write playlist file", QMessageBox::Ok);
423 void MainWindow::loadPlaylist()
425 QString filename = QFileDialog::getOpenFileName(this, tr("Select playlist file to load"), "", "*.m3u");
427 f.open (QFile::ReadOnly);
428 QString tmp = f.readAll();
430 QStringList lines = tmp.split("\n");
432 foreach (QString l, lines)
434 qDebug () << "Load " << l;
435 Phonon::MediaSource source(l);
436 sources.append(source);
438 if (!sources.isEmpty())
439 metaInformationResolver->setCurrentSource(sources.at(0));
443 void MainWindow::clearPlaylist()
446 while (musicTable->rowCount())
447 musicTable->removeRow(0);
448 mediaObject->clear();
451 void MainWindow::repeatToggle ()
454 qDebug() << "Repeat toggled to " << repeat;
455 settings.setValue("repeat", QVariant (repeat));
458 void MainWindow::shuffleToggle ()
461 settings.setValue("shuffle", QVariant (shuffle));
464 void MainWindow::volumeToggle ()
466 qDebug () << "Volumetoggle: " << volumeAction->isChecked();
467 volumeSlider->setVisible(volumeAction->isChecked());
471 void MainWindow::setupMenus()
473 QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
474 fileMenu->addAction(addFilesAction);
475 fileMenu->addAction(addFoldersAction);
476 fileMenu->addAction(addUrlAction);
477 fileMenu->addAction(savePlaylistAction);
478 fileMenu->addAction(loadPlaylistAction);
479 fileMenu->addAction(clearPlaylistAction);
480 fileMenu->addSeparator();
481 fileMenu->addAction(exitAction);
483 QMenu *aboutMenu = menuBar()->addMenu(tr("&Help"));
484 aboutMenu->addAction(aboutAction);
485 aboutMenu->addAction(aboutQtAction);
488 void MainWindow::setupUi()
490 QToolBar *bar = new QToolBar;
492 bar->setOrientation(Qt::Vertical);
493 //bar->addAction(volumeAction);
495 seekSlider = new Phonon::SeekSlider(this);
496 seekSlider->setMediaObject(mediaObject);
498 volumeSlider = new Phonon::VolumeSlider(this);
499 volumeSlider->setAudioOutput(audioOutput);
500 volumeSlider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
501 volumeSlider->setOrientation(Qt::Vertical);
502 volumeSlider->setMuteVisible(false);
503 // volumeAddedAction = bar->addWidget(volumeSlider);
504 // volumeAddedAction->setVisible(false);
505 bar->addAction(playAction);
506 bar->addAction(pauseAction);
507 bar->addAction(stopAction);
508 bar->addAction(repeatAction);
509 bar->addAction(shuffleAction);
511 /* QLabel *volumeLabel = new QLabel;
512 volumeLabel->setPixmap(QPixmap("images/volume.png"));*/
515 palette.setBrush(QPalette::Light, Qt::darkGray);*/
517 timeLcd = new QLCDNumber;
518 // timeLcd->setPalette(palette);
521 headers << tr("Artist") << tr("Title") << tr("Album") << tr("Year");
523 musicTable = new QTableWidget(0, 4);
524 musicTable->setHorizontalHeaderLabels(headers);
525 musicTable->setSelectionMode(QAbstractItemView::SingleSelection);
526 musicTable->setSelectionBehavior(QAbstractItemView::SelectRows);
527 connect(musicTable, SIGNAL(cellDoubleClicked(int,int)),
528 this, SLOT(tableClicked(int,int)));
530 QHBoxLayout *seekerLayout = new QHBoxLayout;
531 QToolBar* bar2 = new QToolBar;
532 bar2->addAction(volumeAction);
533 seekerLayout->addWidget(bar2);
534 seekerLayout->addWidget(seekSlider);
535 seekerLayout->addWidget(timeLcd);
537 QVBoxLayout *playbackLayout = new QVBoxLayout;
538 volumeSlider->hide ();
539 playbackLayout->addWidget(bar);
540 // playbackLayout->addStretch();
541 // playbackLayout->addWidget(volumeSlider);
542 // playbackLayout->addWidget(volumeLabel);
544 QVBoxLayout *seekAndTableLayout = new QVBoxLayout;
546 seekAndTableLayout->addWidget(musicTable);
547 seekAndTableLayout->addLayout(seekerLayout);
549 QHBoxLayout *mainLayout = new QHBoxLayout;
550 mainLayout->addWidget(volumeSlider);
551 mainLayout->addLayout(seekAndTableLayout);
552 mainLayout->addLayout(playbackLayout);
554 QWidget *widget = new QWidget;
555 widget->setLayout(mainLayout);
557 setCentralWidget(widget);
558 setWindowTitle("TomAmp");
563 void MainWindow::setupShuffleList()
566 for (int i = 0; i < sources.size(); ++i)
571 int ind = qrand () % tmp.size();
572 shuffleList.append(tmp[ind]);
575 qDebug () << shuffleList;