3 #include <QInputDialog>
5 #include <QtMaemo5/QMaemo5InformationBox>
7 #include "mainwindow.h"
8 #include "optiondialog.h"
11 //#define AVOID_INPUT_DIALOG 0
13 MainWindow::MainWindow()
14 : plman (this), settings (tr ("TomAmp"), "TomAmp"), isPlaying (false)
16 audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
17 mediaObject = new Phonon::MediaObject(this);
19 mediaObject->setTickInterval(1000);
20 connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
21 connect(mediaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
22 this, SLOT(stateChanged(Phonon::State,Phonon::State)));
23 connect(mediaObject, SIGNAL(currentSourceChanged(Phonon::MediaSource)),
24 this, SLOT(sourceChanged(Phonon::MediaSource)));
25 connect(mediaObject, SIGNAL(aboutToFinish()), this, SLOT(aboutToFinish()));
26 connect (&plman, SIGNAL (playlistChanged (int)), this, SLOT (playlistChanged(int)));
27 connect (&plman, SIGNAL (itemUpdated(int)), this, SLOT (itemUpdated (int)));
28 connect (&plman, SIGNAL (itemRemoved(int)), this, SLOT (itemRemoved (int)));
30 Phonon::createPath(mediaObject, audioOutput);
33 repeat = settings.value("repeat", false).toBool();
34 shuffle = settings.value("shuffle", false).toBool();
35 QStringList allowedHeaders;
36 allowedHeaders << "Artist" << "Title" << "Album" << "Controls";
37 foreach (QString h, settings.value ("headers", QStringList()).toStringList())
39 if (allowedHeaders.indexOf(h) >= 0)
43 headers << "Artist" << "Title" << "Album";
48 /* foreach (QString s, Phonon::BackendCapabilities::availableMimeTypes())
51 /* if (settings.value("uiflipped", false).toBool())
56 timeLcd->display("00:00:00");
57 plman.addStringList(settings.value("lastPlaylist").toStringList());
59 int curind = settings.value("currentIndex", -1).toInt ();
61 setItem (curind, false);
62 audioOutput->setVolume(settings.value("volume", .5).toReal());
63 QApplication::setWindowIcon(QIcon (QPixmap (":images/tomamp")));
67 MainWindow::~MainWindow()
69 settings.setValue("shuffle", shuffle);
70 settings.setValue("repeat", repeat);
71 settings.setValue("lastPlaylist", plman.playlistStrings());
72 settings.setValue("volume", audioOutput->volume());
73 settings.setValue("currentIndex", plman.indexOf(mediaObject->currentSource()));
74 settings.setValue("headers", headers);
75 for (int i = 0; i < musicTable->columnCount(); ++i)
77 QString lab = QString ("colWidth_%1").arg (i);
78 settings.setValue(lab, musicTable->columnWidth(i));
82 void MainWindow::setOrientation ()
85 QString orient = settings.value("orientation", "Automatic").toString();
86 if (orient == "Portrait")
88 setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
90 else if (orient == "Landscape")
92 setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
96 setAttribute(Qt::WA_Maemo5AutoOrientation, true);
101 void MainWindow::addFiles()
103 QString folder = settings.value("LastFolder").toString();
104 if (folder.isEmpty())
105 folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
106 QString ext = "*." + plman.allowedExt().join(" *.");
107 ext = "Music files (" + ext + ");;Playlists (*.m3u *.pls)";
108 QStringList files = QFileDialog::getOpenFileNames(this, tr("Select Files To Add"),
109 folder, ext, 0, QFileDialog::DontUseNativeDialog);
114 QString dir = QFileInfo (files[0]).absoluteDir().absolutePath();
115 settings.setValue("LastFolder", dir);
117 foreach (QString string, files)
119 if (string.toLower().endsWith(".pls") || string.toLower().endsWith(".m3u"))
120 plman.addPlaylist(string);
122 toadd.append (string);
124 plman.addStringList(toadd);
127 void MainWindow::addFolder()
129 QString folder = settings.value("LastFolder").toString();
130 if (folder.isEmpty())
131 folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
132 QString dir = QFileDialog::getExistingDirectory(this,
133 tr("Select Directory To Add"),
139 settings.setValue("LastFolder", dir);
142 QStringList files = QDir (dir).entryList(filters, QDir::AllDirs);
143 files.removeAll(".");
144 files.removeAll("..");
145 bool recursive = false;
147 recursive = QMessageBox::question(this, "Add all folders", "Subfolders have been detected, add everything?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes;
148 plman.parseAndAddFolder(dir, recursive);
152 void MainWindow::addUrl()
154 #ifdef AVOID_INPUT_DIALOG
155 QString url = "http://war.str3am.com:7970";
157 QString url = QInputDialog::getText(this, "Get URL", "Please type in the stream URL");
159 if (url.isEmpty() || !url.toLower().startsWith("http"))
163 plman.addStringList(toadd);
167 void MainWindow::about()
169 QMessageBox::information(this, tr("About TomAmp v0.2"),
170 tr("TomAmp is a simple playlist-based music player.\n\n"
171 "(c) 2010 Tamas Marki <tmarki@gmail.com>\n\n"
172 "Please send comments and bug reports to the above e-mail address.\n\n"
173 "Icons by http://itweek.deviantart.com/\n\n"
174 "Special thanks to Attila Csipa"));
177 void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */)
181 case Phonon::ErrorState:
182 if (mediaObject->errorType() == Phonon::FatalError)
184 // QMessageBox::warning(this, tr("Fatal Error"),
185 // mediaObject->errorString() + mediaObject->currentSource().fileName() + ", " + mediaObject->currentSource().url().toString());
189 // QMessageBox::warning(this, tr("Error"),
190 // mediaObject->errorString());
194 case Phonon::PlayingState:
195 setWindowTitle(mediaObject->metaData().value("TITLE") + "(" + mediaObject->metaData().value("ARTIST") + ") - TomAmp");
196 pauseAction->setVisible(true);
197 playAction->setVisible (false);
198 playAction->setEnabled(false);
199 pauseAction->setEnabled(true);
200 stopAction->setEnabled(true);
201 unhighlightRow(lastPlayed);
202 lastPlayed = plman.indexOf(mediaObject->currentSource());
203 highlightRow(plman.indexOf(mediaObject->currentSource()));
204 musicTable->selectRow(plman.indexOf(mediaObject->currentSource()));
206 case Phonon::StoppedState:
207 setWindowTitle("TomAmp");
208 stopAction->setEnabled(false);
209 playAction->setEnabled(true);
210 pauseAction->setVisible(false);
211 playAction->setVisible(true);
212 pauseAction->setEnabled(false);
213 timeLcd->display("00:00:00");
214 unhighlightRow(plman.indexOf(mediaObject->currentSource()));
216 case Phonon::PausedState:
217 pauseAction->setEnabled(false);
218 stopAction->setEnabled(true);
219 pauseAction->setVisible(false);
220 playAction->setVisible(true);
221 playAction->setEnabled(true);
223 case Phonon::BufferingState:
230 void MainWindow::next()
232 bool wasPlaying = isPlaying;
233 if (mediaObject->state () == Phonon::ErrorState)
235 if (mediaObject->queue().size())
237 setItem (plman.indexOf(mediaObject->queue()[0]), wasPlaying);
238 mediaObject->queue().clear();
241 int index = plman.indexOf(mediaObject->currentSource());
244 index = shuffleList.indexOf(plman.indexOf(mediaObject->currentSource())) + 1;
245 while (index < shuffleList.size () && !plman.getItem(shuffleList[index]).playable)
249 if (index < shuffleList.size ())
251 setItem (index, wasPlaying);
256 while ((index) < shuffleList.size () && !plman.getItem(shuffleList[index]).playable)
260 setItem (index, wasPlaying);
266 while ((index) < plman.size () && !plman.getItem(index).playable)
270 if (index < plman.size())
272 setItem (index, wasPlaying);
277 while ((index) < plman.size () && !plman.getItem(index).playable)
281 setItem (index, wasPlaying);
286 void MainWindow::setItem(int i, bool doplay)
288 if (i < plman.size() && i >= 0)
290 /* if (lastPlayed >= 0)
291 unhighlightRow(lastPlayed);*/
294 mediaObject->setCurrentSource(plman.at (shuffleList[i]));
298 mediaObject->setCurrentSource(plman.at(i));
301 if (doplay && mediaObject->currentSource().type() != Phonon::MediaSource::Invalid)
309 void MainWindow::previous()
311 bool wasPlaying = isPlaying;//(mediaObject->state () == Phonon::PlayingState);
312 if (mediaObject->state () == Phonon::ErrorState)
314 int index = plman.indexOf(mediaObject->currentSource());
317 index = shuffleList.indexOf(plman.indexOf(mediaObject->currentSource())) - 1;
318 while (index >= 0 && !plman.getItem(shuffleList[index]).playable)
324 setItem (index, wasPlaying);
328 index = plman.size () - 1;
329 while (index >= 0 && !plman.getItem(shuffleList[index]).playable)
333 setItem (index, wasPlaying);
336 wasPlaying = false;*/
342 while ((index) >= 0 && !plman.getItem(index).playable)
348 setItem (index, wasPlaying);
352 index = plman.size() - 1;
353 while ((index) >= 0 && !plman.getItem(index).playable)
357 setItem (index, wasPlaying);
362 void MainWindow::highlightRow (int i)
364 for (int j = 0; j < 3; ++j)
366 QTableWidgetItem* item = musicTable->item(i, j);
369 QFont font = item->font();
371 font.setItalic(true);
377 void MainWindow::unhighlightRow (int i)
379 for (int j = 0; j < 3; ++j)
381 QTableWidgetItem* item = musicTable->item(i, j);
384 QFont font = item->font();
386 font.setItalic(false);
393 void MainWindow::tick(qint64 time)
395 QTime displayTime((time / 3600000), (time / 60000) % 60, (time / 1000) % 60);
397 timeLcd->display(displayTime.toString("HH:mm:ss"));
400 void MainWindow::tableClicked(int row, int /* column */)
402 // bool wasPlaying = mediaObject->state() == Phonon::PlayingState;
404 /* mediaObject->stop();
405 mediaObject->clearQueue();*/
407 if (row >= plman.size())
411 while (index < shuffleList.size () && !plman.getItem(index).playable)
415 if (plman.size() > index)
418 index = shuffleList.indexOf(index);
419 setItem (index, true);
420 // mediaObject->play();
425 while (index < plman.size () && !plman.getItem(index).playable)
429 if (plman.size() > index)
432 index = shuffleList.indexOf(index);
433 setItem (index, true);
434 // mediaObject->play();
440 void MainWindow::sourceChanged(const Phonon::MediaSource &source)
442 int ind = plman.indexOf(source);
444 unhighlightRow(lastPlayed);
446 musicTable->selectRow(ind);
447 timeLcd->display("00:00:00");
451 void MainWindow::aboutToFinish()
453 if (mediaObject->queue().size())
455 int index = plman.indexOf(mediaObject->currentSource()) + 1;
458 index = shuffleList.indexOf(plman.indexOf(mediaObject->currentSource())) + 1;
459 if (index < shuffleList.size ())
461 mediaObject->enqueue(plman.at (shuffleList[index]));
465 mediaObject->enqueue(plman.at (shuffleList[0]));
471 if (plman.size() > index)
473 mediaObject->enqueue(plman.at(index));
477 mediaObject->enqueue(plman.at(0));
482 void MainWindow::finished()
486 void MainWindow::setupActions()
488 playAction = new QAction(QIcon (QPixmap (":images/play")), "", this);
489 playAction->setShortcut(tr("Crl+P"));
490 playAction->setDisabled(true);
491 pauseAction = new QAction(QIcon (QPixmap (":images/pause")), "", this);
492 pauseAction->setShortcut(tr("Ctrl+A"));
493 pauseAction->setDisabled(true);
494 pauseAction->setVisible(false);
495 stopAction = new QAction(QIcon (QPixmap (":images/stop")), "", this);
496 stopAction->setShortcut(tr("Ctrl+S"));
497 stopAction->setDisabled(true);
498 nextAction = new QAction(QIcon (QPixmap (":images/next")), "", this);
499 nextAction->setShortcut(tr("Ctrl+N"));
500 upAction = new QAction (QString::fromUtf8("▲"), this);
501 downAction = new QAction (QString::fromUtf8("▼"), this);
502 delAction = new QAction (QString::fromUtf8("╳"), this);
503 previousAction = new QAction(QIcon (QPixmap (":images/previous")), "", this);
504 previousAction->setShortcut(tr("Ctrl+R"));
506 repeatAction = new QAction(QIcon (QPixmap (":images/repeatActive")), "", this);
508 repeatAction = new QAction(QIcon (QPixmap (":images/repeat")), "", this);
509 repeatAction->setCheckable(true);
510 repeatAction->setChecked(repeat);
511 repeatAction->setShortcut(tr("Ctrl+I"));
513 shuffleAction = new QAction(QIcon (QPixmap (":images/shuffleActive")), "", this);
515 shuffleAction = new QAction(QIcon (QPixmap (":images/shuffle")), "", this);
516 shuffleAction->setCheckable(true);
517 shuffleAction->setChecked(shuffle);
518 shuffleAction->setShortcut(tr("Ctrl+H"));
519 enqueueActionButton = new QAction (tr ("E"), this);
520 volumeAction = new QAction(QIcon (QPixmap (":images/volume")), "", this);
521 volumeAction->setCheckable(true);
522 volumeAction->setShortcut(tr("Ctrl+V"));
523 addFilesAction = new QAction(tr("Add &File"), this);
524 addFilesAction->setShortcut(tr("Ctrl+F"));
525 addFoldersAction = new QAction(tr("Add F&older"), this);
526 addFoldersAction->setShortcut(tr("Ctrl+O"));
527 addUrlAction = new QAction(tr("Add &Url"), this);
528 addUrlAction->setShortcut(tr("Ctrl+U"));
529 savePlaylistAction = new QAction (tr("Sa&ve Playlist"), this);
530 savePlaylistAction->setShortcut(tr ("Ctrl+V"));
531 loadPlaylistAction = new QAction (tr("&Load Playlist"), this);
532 loadPlaylistAction->setShortcut(tr("Ctrl+L"));
533 clearPlaylistAction = new QAction (tr("&Clear Playlist"), this);
534 clearPlaylistAction->setShortcut(tr("Ctrl+C"));
535 optionAction = new QAction (tr("Op&tions"), this);
536 optionAction->setShortcut(tr("Ctrl+T"));
537 exitAction = new QAction(tr("E&xit"), this);
538 exitAction->setShortcut(tr("Ctrl+X"));
539 aboutAction = new QAction(tr("A&bout"), this);
540 aboutAction->setShortcut(tr("Ctrl+B"));
541 aboutQtAction = new QAction(tr("About &Qt"), this);
542 aboutQtAction->setShortcut(tr("Ctrl+Q"));
543 /* removeSelected = new QAction (tr("&Delete from playlist"));
544 removeSelected->setShortcut(tr ("Ctrl+D"));*/
546 connect(playAction, SIGNAL(triggered()), this, SLOT(play()));
547 connect(pauseAction, SIGNAL(triggered()), mediaObject, SLOT(pause()) );
548 connect(stopAction, SIGNAL(triggered()), this, SLOT(stop()));
549 connect(repeatAction, SIGNAL(triggered()), this, SLOT(repeatToggle()));
550 connect(shuffleAction, SIGNAL(triggered()), this, SLOT(shuffleToggle()));
551 connect(volumeAction, SIGNAL(triggered()), this, SLOT(volumeToggle()));
552 connect(enqueueActionButton, SIGNAL(triggered()), this, SLOT(enqueueSelected()));
554 connect(addFilesAction, SIGNAL(triggered()), this, SLOT(addFiles()));
555 connect(addFoldersAction, SIGNAL(triggered()), this, SLOT(addFolder()));
556 connect(addUrlAction, SIGNAL(triggered()), this, SLOT(addUrl()));
557 connect (savePlaylistAction, SIGNAL (triggered()), this, SLOT (savePlaylist()));
558 connect (loadPlaylistAction, SIGNAL (triggered()), this, SLOT (loadPlaylist()));
559 connect (clearPlaylistAction, SIGNAL (triggered()), &plman, SLOT (clearPlaylist()));
560 connect (optionAction, SIGNAL (triggered()), this, SLOT (showOptions()));
561 connect (nextAction, SIGNAL(triggered()), this, SLOT(next()));
562 connect (previousAction, SIGNAL(triggered()), this, SLOT(previous()));
563 connect (upAction, SIGNAL(triggered()), this, SLOT(upSelected()));
564 connect (downAction, SIGNAL(triggered()), this, SLOT(downSelected()));
565 connect (delAction, SIGNAL(triggered()), this, SLOT(removeSelectedItem()));
566 connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
567 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
568 connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
569 // connect (removeSelected, SIGNAL (triggered()), this, SLOT (removeSelectedItem()));
572 void MainWindow::removeSelectedItem()
574 if (QMessageBox::question(this, "Confirm remove", "Are you sure you want to remove this item?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
576 int row = musicTable->currentRow();
578 plman.removeItem(row);
581 void MainWindow::removeAllButSelectedItem()
583 if (QMessageBox::question(this, "Confirm remove", "Are you sure you want to remove all other items?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
585 int row = musicTable->currentRow();
588 QString uri = plman.getItem(row).uri;
591 plman.clearPlaylist();
592 plman.addStringList(lst);
596 void MainWindow::repeatToggle ()
599 settings.setValue("repeat", QVariant (repeat));
601 repeatAction->setIcon(QIcon (QPixmap (":images/repeatActive")));
603 repeatAction->setIcon(QIcon (QPixmap (":images/repeat")));
606 void MainWindow::shuffleToggle ()
609 settings.setValue("shuffle", QVariant (shuffle));
611 shuffleAction->setIcon(QIcon (QPixmap (":images/shuffleActive")));
613 shuffleAction->setIcon(QIcon (QPixmap (":images/shuffle")));
616 void MainWindow::volumeToggle ()
618 volumeSlider->setVisible(volumeAction->isChecked());
621 void MainWindow::play()
624 // lastPlayed = plman.indexOf(mediaObject->currentSource());
625 highlightRow(lastPlayed);
629 void MainWindow::stop()
636 void MainWindow::setupMenus()
638 QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
639 fileMenu->addAction(addFilesAction);
640 fileMenu->addAction(addFoldersAction);
641 fileMenu->addAction(addUrlAction);
642 fileMenu->addSeparator();
643 fileMenu->addAction(savePlaylistAction);
644 fileMenu->addAction(loadPlaylistAction);
645 fileMenu->addAction(clearPlaylistAction);
646 fileMenu->addAction(optionAction);
647 // fileMenu->addAction(exitAction);
649 QMenu *aboutMenu = menuBar()->addMenu(tr("&Help"));
650 aboutMenu->addAction(aboutAction);
651 aboutMenu->addAction(aboutQtAction);
654 void MainWindow::setupUi()
656 QToolBar *bar = new QToolBar;
657 bool flip = settings.value("uiflipped", false).toBool();
659 if(!flip) bar->setOrientation(Qt::Vertical);
660 bar->setStyleSheet("padding:7px");
662 seekSlider = new Phonon::SeekSlider(this);
663 seekSlider->setMediaObject(mediaObject);
664 if (flip) seekSlider->setOrientation(Qt::Vertical);
666 volumeSlider = new Phonon::VolumeSlider(this);
667 volumeSlider->setAudioOutput(audioOutput);
670 volumeSlider->setOrientation(Qt::Vertical);
671 volumeSlider->setMinimumHeight(150);
675 volumeSlider->setMinimumWidth(150);
677 volumeSlider->setMuteVisible(false);
678 bar->addAction(playAction);
679 bar->addAction(pauseAction);
680 bar->addAction(stopAction);
681 bar->addAction(repeatAction);
682 bar->addAction(shuffleAction);
683 bar->addAction(nextAction);
684 bar->addAction(previousAction);
685 bar->addAction(upAction);
686 bar->addAction(downAction);
687 bar->addAction(delAction);
688 bar->addAction(enqueueActionButton);
690 contextMenu = new QMenu (this);
691 enqueueAction = contextMenu->addAction(tr ("Enqueue"));
692 removeSelected = contextMenu->addAction(tr ("Remove selected"));
693 removeAllButSelected = contextMenu->addAction(tr("Remove all but selected"));
694 connect (removeSelected, SIGNAL (triggered()), this, SLOT (removeSelectedItem()));
695 connect (removeAllButSelected, SIGNAL (triggered()), this, SLOT (removeAllButSelectedItem()));
696 connect (enqueueAction, SIGNAL (triggered()), this, SLOT (enqueueSelected()));
699 timeLcd = new QLCDNumber;
701 if (!headers.size ())
703 headers << "Artist" << "Title" << "Album";
704 settings.setValue("headers", headers);
707 musicTable = new QTableWidget(0, headers.size ());
708 musicTable->setHorizontalHeaderLabels(headers);
709 musicTable->setSelectionMode(QAbstractItemView::SingleSelection);
710 musicTable->setSelectionBehavior(QAbstractItemView::SelectRows);
711 // musicTable->setAlternatingRowColors(true);
712 musicTable->verticalHeader ()->hide();
713 connect(musicTable, SIGNAL(cellDoubleClicked(int,int)),
714 this, SLOT(tableClicked(int,int)));
715 connect(musicTable, SIGNAL(cellClicked(int,int)),
716 this, SLOT(cellClicked(int,int)));
717 for (int i = 0; i < musicTable->columnCount(); ++i)
719 QString lab = QString ("colWidth_%1").arg (i);
720 int val = settings.value(lab, 0).toInt();
722 musicTable->setColumnWidth(i, val);
726 QLayout *seekerLayout;
727 QLayout *playbackLayout;
730 seekerLayout = new QVBoxLayout;
731 playbackLayout = new QHBoxLayout;
732 bar->addWidget(timeLcd);
736 seekerLayout = new QHBoxLayout;
737 playbackLayout = new QVBoxLayout;
739 QToolBar* bar2 = new QToolBar;
740 bar2->addAction(volumeAction);
741 seekerLayout->addWidget(bar2);
742 seekerLayout->addWidget(volumeSlider);
743 seekerLayout->addWidget(seekSlider);
745 seekerLayout->addWidget(timeLcd);
746 volumeSlider->hide ();
747 playbackLayout->addWidget(bar);
749 QVBoxLayout *seekAndTableLayout = new QVBoxLayout;
751 seekAndTableLayout->addWidget(musicTable);
752 QHBoxLayout *mainLayout = new QHBoxLayout;
753 mainLayout->addLayout(seekAndTableLayout);
756 seekAndTableLayout->addLayout(playbackLayout);
757 mainLayout->addLayout(seekerLayout);
761 seekAndTableLayout->addLayout(seekerLayout);
762 mainLayout->addLayout(playbackLayout);
766 QWidget *widget = new QWidget;
767 widget->setLayout(mainLayout);
769 setCentralWidget(widget);
770 setWindowTitle("TomAmp");
773 void MainWindow::cellClicked(int /*row*/, int)
777 void MainWindow::enqueueSelected()
779 int sel = musicTable->currentRow();
780 qDebug () << "Enqueue on " << sel;
783 mediaObject->queue().clear();
784 mediaObject->enqueue(plman.at(sel));
786 QMaemo5InformationBox::information(this, plman.getItem(sel).title + tr (" enqueued as next song"),
787 QMaemo5InformationBox::DefaultTimeout);
793 void MainWindow::contextMenuEvent (QContextMenuEvent*e)
795 if (!childAt (e->pos()))
797 if (childAt (e->pos())->parentWidget() != musicTable)
799 contextMenu->popup(e->globalPos());
803 void MainWindow::setupShuffleList()
806 int index = plman.indexOf(mediaObject->currentSource());
809 for (int i = 0; i < plman.size(); ++i)
815 shuffleList.append (index);
818 int ind = qrand () % tmp.size();
819 shuffleList.append(tmp[ind]);
824 void MainWindow::savePlaylist ()
826 QString filename = QFileDialog::getSaveFileName(this, tr("Please select file name"), "", "Playlist Files (*.m3u *.pls)");
827 if (filename.isEmpty())
829 if (!plman.savePlaylist(filename))
832 QMaemo5InformationBox::information(this, tr ("Error writing playlist file"),
833 QMaemo5InformationBox::DefaultTimeout);
835 QMessageBox::critical(this, "Write error", "Error writing playlist file", QMessageBox::Ok);
841 void MainWindow::loadPlaylist ()
843 QString filename = QFileDialog::getOpenFileName(this, tr("Select playlist file to load"), "", "*.m3u *.pls");
844 if (filename.isEmpty())
846 plman.loadPlaylist (filename);
849 void MainWindow::playlistChanged(int from)
851 while (musicTable->rowCount() > from)
853 musicTable->removeRow(musicTable->rowCount () - 1);
856 for (int i = from; i < plman.size (); ++i)
858 if (firstGood < 0 && plman.getItem (i).playable)
860 int currentRow = musicTable->rowCount();
861 musicTable->insertRow(currentRow);
862 setRowFromItem (currentRow, plman.getItem(i));
864 /* if (plman.indexOf(mediaObject->currentSource()) < 0)
866 setItem (firstGood, false);
871 void MainWindow::setRowFromItem (int row, const PlaylistItem& item)
873 if (row >= musicTable->rowCount())
875 if (item.artist.isEmpty() && item.title.isEmpty())
877 int col = headers.indexOf("Title");
880 QTableWidgetItem *item1 = new QTableWidgetItem(item.uri);
881 item1->setFlags(item1->flags() ^ Qt::ItemIsEditable);
882 musicTable->setItem(row, col, item1);
887 int col = headers.indexOf("Artist");
890 QTableWidgetItem *item1 = new QTableWidgetItem(item.artist);
891 item1->setFlags(item1->flags() ^ Qt::ItemIsEditable);
892 musicTable->setItem(row, col, item1);
894 col = headers.indexOf("Title");
897 if (!musicTable->item (row, col))
899 QTableWidgetItem *item2 = new QTableWidgetItem(item.title);
900 item2->setFlags(item2->flags() ^ Qt::ItemIsEditable);
901 musicTable->setItem(row, col, item2);
905 musicTable->item (row, col)->setText(item.title);
908 col = headers.indexOf("Album");
911 QTableWidgetItem *item3 = new QTableWidgetItem(item.album);
912 item3->setFlags(item3->flags() ^ Qt::ItemIsEditable);
914 musicTable->setItem(row, col, item3);
918 int controlCol = headers.indexOf("Controls");
919 if (controlCol >= 0 && !musicTable->cellWidget(row, controlCol))
921 QLabel* label = new QLabel;
922 label->setText(QString::fromUtf8("<b><a style='text-decoration:none' href='up'>▲</a> <a style='text-decoration:none' href='down'>▼</a> <a style='text-decoration:none' href='del'>╳</a> <a style='text-decoration:none' href='enq'>E</a></b>"));
923 label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
924 label->setProperty("row", row);
925 musicTable->setCellWidget(row, controlCol, label);
926 connect (label, SIGNAL (linkActivated (const QString&)), this, SLOT (playlistControl (const QString&)));
930 void MainWindow::playlistControl (const QString& con)
932 int i = sender ()->property("row").toInt();
935 else if (con == "down")
937 else if (con == "del")
939 else if (con == "enq")
941 musicTable->selectRow(i);
945 QMessageBox::information(this, tr ("Coming up..."), tr ("This feature is not implemented yet."));
949 void MainWindow::buttonUp(int i)
954 setRowFromItem (i, plman.getItem(i));
955 setRowFromItem (i - 1, plman.getItem(i - 1));
956 int controlCol = headers.indexOf("Controls");
959 musicTable->cellWidget(i, controlCol)->setProperty("row", i);
960 musicTable->cellWidget(i - 1, controlCol)->setProperty("row", i - 1);
962 musicTable->selectRow(i - 1);
966 void MainWindow::buttonDown(int i)
968 if (i < plman.size() - 1)
970 plman.moveItemDown(i);
971 setRowFromItem (i, plman.getItem(i));
972 setRowFromItem (i + 1, plman.getItem(i + 1));
973 int controlCol = headers.indexOf("Controls");
976 musicTable->cellWidget(i, controlCol)->setProperty("row", i);
977 musicTable->cellWidget(i + 1, controlCol)->setProperty("row", i + 1);
979 musicTable->selectRow(i + 1);
983 void MainWindow::buttonDel(int i)
985 if (QMessageBox::question(this, "Confirm remove", "Are you sure you want to remove this item?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
987 if (i < plman.size())
993 void MainWindow::itemUpdated(int index)
995 if (plman.indexOf(mediaObject->currentSource()) < 0 && plman.getItem (index).playable)
997 setItem (index, false);
999 setRowFromItem (index, plman.getItem(index));
1000 if (plman.indexOf(mediaObject->currentSource()) == index)
1002 if (shuffle) index = shuffleList.indexOf(index);
1003 setItem (index, false);
1007 void MainWindow::itemRemoved (int i)
1009 musicTable->removeRow(i);
1010 int controlCol = headers.indexOf("Controls");
1013 for (int j = i ? (i - 1) : 0; j < musicTable->rowCount(); ++j)
1015 if (musicTable->cellWidget(j, controlCol))
1016 musicTable->cellWidget(j, controlCol)->setProperty("row", j);
1020 void MainWindow::upSelected()
1022 int sel = musicTable->currentRow();
1027 void MainWindow::downSelected()
1029 int sel = musicTable->currentRow();
1036 void MainWindow::showOptions ()
1038 bool flip = settings.value("uiflipped", false).toBool();
1039 OptionDialog* dlg = new OptionDialog (this, settings);
1042 if (flip != settings.value("uiflipped", false).toBool())
1044 delete centralWidget();
1048 if (headers != settings.value("headers", QStringList ()).toStringList())
1050 headers = settings.value("headers", QStringList ()).toStringList();
1051 musicTable->setColumnCount(headers.size ());
1052 musicTable->setHorizontalHeaderLabels(headers);
1055 int curitem = plman.indexOf(mediaObject->currentSource());
1056 if (curitem >= 0 && isPlaying)
1057 highlightRow(curitem);