3 #include <QInputDialog>
5 #include <QtMaemo5/QMaemo5InformationBox>
7 #include "mainwindow.h"
8 #include "optiondialog.h"
11 //#define AVOID_INPUT_DIALOG
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 connect (QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(orientationChanged()));
32 Phonon::createPath(mediaObject, audioOutput);
35 repeat = settings.value("repeat", false).toBool();
36 shuffle = settings.value("shuffle", false).toBool();
37 QStringList allowedHeaders;
38 allowedHeaders << "Artist" << "Title" << "Album" << "Controls";
39 foreach (QString h, settings.value ("headers", QStringList()).toStringList())
41 if (allowedHeaders.indexOf(h) >= 0)
45 headers << "Artist" << "Title" << "Album";
51 QRect screenGeometry = QApplication::desktop()->screenGeometry();
52 portrait = screenGeometry.width() < screenGeometry.height();
55 timeLcd->display("00:00:00");
56 plman.addStringList(settings.value("lastPlaylist").toStringList());
58 int curind = settings.value("currentIndex", -1).toInt ();
60 setItem (curind, false);
61 audioOutput->setVolume(settings.value("volume", .5).toReal());
62 QApplication::setWindowIcon(QIcon (QPixmap (":images/tomamp")));
66 MainWindow::~MainWindow()
68 settings.setValue("shuffle", shuffle);
69 settings.setValue("repeat", repeat);
70 settings.setValue("lastPlaylist", plman.playlistStrings());
71 settings.setValue("volume", audioOutput->volume());
72 settings.setValue("currentIndex", plman.indexOf(mediaObject->currentSource()));
73 settings.setValue("headers", headers);
74 for (int i = 0; i < musicTable->columnCount(); ++i)
76 QString lab = QString ("colWidth_%1").arg (i);
77 settings.setValue(lab, musicTable->columnWidth(i));
81 void MainWindow::setOrientation ()
84 QString orient = settings.value("orientation", "Automatic").toString();
85 if (orient == "Portrait")
87 setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
89 else if (orient == "Landscape")
91 setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
95 setAttribute(Qt::WA_Maemo5AutoOrientation, true);
100 void MainWindow::orientationChanged()
102 QRect screenGeometry = QApplication::desktop()->screenGeometry();
103 portrait = screenGeometry.width() < screenGeometry.height();
104 delete centralWidget();
106 int current = musicTable->currentRow();
108 musicTable->selectRow(current);
112 void MainWindow::addFiles()
114 QString folder = settings.value("LastFolder").toString();
115 if (folder.isEmpty())
116 folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
117 QString ext = "*." + plman.allowedExt().join(" *.");
118 ext = "Music files (" + ext + ");;Playlists (*.m3u *.pls)";
119 QStringList files = QFileDialog::getOpenFileNames(this, tr("Select Files To Add"),
125 QString dir = QFileInfo (files[0]).absoluteDir().absolutePath();
126 settings.setValue("LastFolder", dir);
128 foreach (QString string, files)
130 if (string.toLower().endsWith(".pls") || string.toLower().endsWith(".m3u"))
131 plman.addPlaylist(string);
133 toadd.append (string);
135 plman.addStringList(toadd);
138 void MainWindow::addFolder()
140 QString folder = settings.value("LastFolder").toString();
141 if (folder.isEmpty())
142 folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
143 QString dir = QFileDialog::getExistingDirectory(this,
144 tr("Select Directory To Add"),
150 settings.setValue("LastFolder", dir);
153 QStringList files = QDir (dir).entryList(filters, QDir::AllDirs);
154 files.removeAll(".");
155 files.removeAll("..");
156 bool recursive = false;
158 recursive = QMessageBox::question(this, "Add all folders", "Subfolders have been detected, add everything?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes;
159 plman.parseAndAddFolder(dir, recursive);
163 void MainWindow::addUrl()
165 #ifdef AVOID_INPUT_DIALOG
166 QString url = "http://streams.bigvibez.com:7000/listen.pls";
168 QString url = QInputDialog::getText(this, "Get URL", "Please type in the stream URL");
170 if (url.isEmpty() || !url.toLower().startsWith("http"))
174 plman.addStringList(toadd);
178 void MainWindow::about()
180 QMessageBox::information(this, tr("About TomAmp v0.2.1"),
181 tr("TomAmp is a simple playlist-based music player.\n\n"
182 "(c) 2010 Tamas Marki <tmarki@gmail.com>\n\n"
183 "Please send comments and bug reports to the above e-mail address.\n\n"
184 "Icons by http://itweek.deviantart.com/\n\n"
185 "Special thanks to Attila Csipa"));
188 void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */)
192 case Phonon::ErrorState:
193 if (mediaObject->errorType() == Phonon::FatalError)
195 // QMessageBox::warning(this, tr("Fatal Error"),
196 // mediaObject->errorString() + mediaObject->currentSource().fileName() + ", " + mediaObject->currentSource().url().toString());
200 // QMessageBox::warning(this, tr("Error"),
201 // mediaObject->errorString());
205 case Phonon::PlayingState:
206 setWindowTitle(mediaObject->metaData().value("TITLE") + "(" + mediaObject->metaData().value("ARTIST") + ") - TomAmp");
207 pauseAction->setVisible(true);
208 playAction->setVisible (false);
209 playAction->setEnabled(false);
210 pauseAction->setEnabled(true);
211 stopAction->setEnabled(true);
212 unhighlightRow(lastPlayed);
213 lastPlayed = plman.indexOf(mediaObject->currentSource());
214 highlightRow(plman.indexOf(mediaObject->currentSource()));
215 musicTable->selectRow(plman.indexOf(mediaObject->currentSource()));
217 case Phonon::StoppedState:
218 setWindowTitle("TomAmp");
219 stopAction->setEnabled(false);
220 playAction->setEnabled(true);
221 pauseAction->setVisible(false);
222 playAction->setVisible(true);
223 pauseAction->setEnabled(false);
224 timeLcd->display("00:00:00");
225 unhighlightRow(plman.indexOf(mediaObject->currentSource()));
227 case Phonon::PausedState:
228 pauseAction->setEnabled(false);
229 stopAction->setEnabled(true);
230 pauseAction->setVisible(false);
231 playAction->setVisible(true);
232 playAction->setEnabled(true);
234 case Phonon::BufferingState:
241 void MainWindow::next()
243 bool wasPlaying = isPlaying;
244 if (mediaObject->state () == Phonon::ErrorState)
246 if (mediaObject->queue().size())
248 setItem (plman.indexOf(mediaObject->queue()[0]), wasPlaying);
249 mediaObject->queue().clear();
252 int index = plman.indexOf(mediaObject->currentSource());
255 index = shuffleList.indexOf(plman.indexOf(mediaObject->currentSource())) + 1;
256 while (index < shuffleList.size () && !plman.getItem(shuffleList[index]).playable)
260 if (index < shuffleList.size ())
262 setItem (index, wasPlaying);
267 while ((index) < shuffleList.size () && !plman.getItem(shuffleList[index]).playable)
271 setItem (index, wasPlaying);
277 while ((index) < plman.size () && !plman.getItem(index).playable)
281 if (index < plman.size())
283 setItem (index, wasPlaying);
288 while ((index) < plman.size () && !plman.getItem(index).playable)
292 setItem (index, wasPlaying);
297 void MainWindow::setItem(int i, bool doplay)
299 if (i < plman.size() && i >= 0)
301 /* if (lastPlayed >= 0)
302 unhighlightRow(lastPlayed);*/
305 mediaObject->setCurrentSource(plman.at (shuffleList[i]));
309 mediaObject->setCurrentSource(plman.at(i));
312 if (doplay && mediaObject->currentSource().type() != Phonon::MediaSource::Invalid)
320 void MainWindow::previous()
322 bool wasPlaying = isPlaying;//(mediaObject->state () == Phonon::PlayingState);
323 if (mediaObject->state () == Phonon::ErrorState)
325 int index = plman.indexOf(mediaObject->currentSource());
328 index = shuffleList.indexOf(plman.indexOf(mediaObject->currentSource())) - 1;
329 while (index >= 0 && !plman.getItem(shuffleList[index]).playable)
335 setItem (index, wasPlaying);
339 index = plman.size () - 1;
340 while (index >= 0 && !plman.getItem(shuffleList[index]).playable)
344 setItem (index, wasPlaying);
347 wasPlaying = false;*/
353 while ((index) >= 0 && !plman.getItem(index).playable)
359 setItem (index, wasPlaying);
363 index = plman.size() - 1;
364 while ((index) >= 0 && !plman.getItem(index).playable)
368 setItem (index, wasPlaying);
373 void MainWindow::highlightRow (int i)
375 for (int j = 0; j < 3; ++j)
377 QTableWidgetItem* item = musicTable->item(i, j);
380 QFont font = item->font();
382 font.setItalic(true);
388 void MainWindow::unhighlightRow (int i)
390 for (int j = 0; j < 3; ++j)
392 QTableWidgetItem* item = musicTable->item(i, j);
395 QFont font = item->font();
397 font.setItalic(false);
404 void MainWindow::tick(qint64 time)
406 QTime displayTime((time / 3600000), (time / 60000) % 60, (time / 1000) % 60);
408 timeLcd->display(displayTime.toString("HH:mm:ss"));
411 void MainWindow::tableClicked(int row, int /* column */)
413 // bool wasPlaying = mediaObject->state() == Phonon::PlayingState;
415 /* mediaObject->stop();
416 mediaObject->clearQueue();*/
418 if (row >= plman.size())
422 while (index < shuffleList.size () && !plman.getItem(index).playable)
426 if (plman.size() > index)
429 index = shuffleList.indexOf(index);
430 setItem (index, true);
431 // mediaObject->play();
436 while (index < plman.size () && !plman.getItem(index).playable)
440 if (plman.size() > index)
443 index = shuffleList.indexOf(index);
444 setItem (index, true);
445 // mediaObject->play();
451 void MainWindow::sourceChanged(const Phonon::MediaSource &source)
453 int ind = plman.indexOf(source);
455 unhighlightRow(lastPlayed);
457 musicTable->selectRow(ind);
458 timeLcd->display("00:00:00");
462 void MainWindow::aboutToFinish()
464 if (mediaObject->queue().size())
466 int index = plman.indexOf(mediaObject->currentSource()) + 1;
469 index = shuffleList.indexOf(plman.indexOf(mediaObject->currentSource())) + 1;
470 if (index < shuffleList.size ())
472 mediaObject->enqueue(plman.at (shuffleList[index]));
476 mediaObject->enqueue(plman.at (shuffleList[0]));
482 if (plman.size() > index)
484 mediaObject->enqueue(plman.at(index));
488 mediaObject->enqueue(plman.at(0));
493 void MainWindow::finished()
497 void MainWindow::setupActions()
499 playAction = new QAction(QIcon (QPixmap (":images/play")), "", this);
500 playAction->setShortcut(tr("Crl+P"));
501 playAction->setDisabled(true);
502 pauseAction = new QAction(QIcon (QPixmap (":images/pause")), "", this);
503 pauseAction->setShortcut(tr("Ctrl+A"));
504 pauseAction->setDisabled(true);
505 pauseAction->setVisible(false);
506 stopAction = new QAction(QIcon (QPixmap (":images/stop")), "", this);
507 stopAction->setShortcut(tr("Ctrl+S"));
508 stopAction->setDisabled(true);
509 nextAction = new QAction(QIcon (QPixmap (":images/next")), "", this);
510 nextAction->setShortcut(tr("Ctrl+N"));
511 upAction = new QAction (QString::fromUtf8("▲"), this);
512 downAction = new QAction (QString::fromUtf8("▼"), this);
513 delAction = new QAction (QString::fromUtf8("╳"), this);
514 previousAction = new QAction(QIcon (QPixmap (":images/previous")), "", this);
515 previousAction->setShortcut(tr("Ctrl+R"));
517 repeatAction = new QAction(QIcon (QPixmap (":images/repeatActive")), "", this);
519 repeatAction = new QAction(QIcon (QPixmap (":images/repeat")), "", this);
520 repeatAction->setCheckable(true);
521 repeatAction->setChecked(repeat);
522 repeatAction->setShortcut(tr("Ctrl+I"));
524 shuffleAction = new QAction(QIcon (QPixmap (":images/shuffleActive")), "", this);
526 shuffleAction = new QAction(QIcon (QPixmap (":images/shuffle")), "", this);
527 shuffleAction->setCheckable(true);
528 shuffleAction->setChecked(shuffle);
529 shuffleAction->setShortcut(tr("Ctrl+H"));
530 enqueueActionButton = new QAction (tr ("E"), this);
531 volumeAction = new QAction(QIcon (QPixmap (":images/volume")), "", this);
532 volumeAction->setCheckable(true);
533 volumeAction->setShortcut(tr("Ctrl+V"));
534 addFilesAction = new QAction(tr("Add &File"), this);
535 addFilesAction->setShortcut(tr("Ctrl+F"));
536 addFoldersAction = new QAction(tr("Add F&older"), this);
537 addFoldersAction->setShortcut(tr("Ctrl+O"));
538 addUrlAction = new QAction(tr("Add &Url"), this);
539 addUrlAction->setShortcut(tr("Ctrl+U"));
540 savePlaylistAction = new QAction (tr("Sa&ve Playlist"), this);
541 savePlaylistAction->setShortcut(tr ("Ctrl+V"));
542 loadPlaylistAction = new QAction (tr("&Load Playlist"), this);
543 loadPlaylistAction->setShortcut(tr("Ctrl+L"));
544 clearPlaylistAction = new QAction (tr("&Clear Playlist"), this);
545 clearPlaylistAction->setShortcut(tr("Ctrl+C"));
546 optionAction = new QAction (tr("Op&tions"), this);
547 optionAction->setShortcut(tr("Ctrl+T"));
548 exitAction = new QAction(tr("E&xit"), this);
549 exitAction->setShortcut(tr("Ctrl+X"));
550 aboutAction = new QAction(tr("A&bout"), this);
551 aboutAction->setShortcut(tr("Ctrl+B"));
552 aboutQtAction = new QAction(tr("About &Qt"), this);
553 aboutQtAction->setShortcut(tr("Ctrl+Q"));
554 /* removeSelected = new QAction (tr("&Delete from playlist"));
555 removeSelected->setShortcut(tr ("Ctrl+D"));*/
557 connect(playAction, SIGNAL(triggered()), this, SLOT(play()));
558 connect(pauseAction, SIGNAL(triggered()), mediaObject, SLOT(pause()) );
559 connect(stopAction, SIGNAL(triggered()), this, SLOT(stop()));
560 connect(repeatAction, SIGNAL(triggered()), this, SLOT(repeatToggle()));
561 connect(shuffleAction, SIGNAL(triggered()), this, SLOT(shuffleToggle()));
562 connect(volumeAction, SIGNAL(triggered()), this, SLOT(volumeToggle()));
563 connect(enqueueActionButton, SIGNAL(triggered()), this, SLOT(enqueueSelected()));
565 connect(addFilesAction, SIGNAL(triggered()), this, SLOT(addFiles()));
566 connect(addFoldersAction, SIGNAL(triggered()), this, SLOT(addFolder()));
567 connect(addUrlAction, SIGNAL(triggered()), this, SLOT(addUrl()));
568 connect (savePlaylistAction, SIGNAL (triggered()), this, SLOT (savePlaylist()));
569 connect (loadPlaylistAction, SIGNAL (triggered()), this, SLOT (loadPlaylist()));
570 connect (clearPlaylistAction, SIGNAL (triggered()), &plman, SLOT (clearPlaylist()));
571 connect (optionAction, SIGNAL (triggered()), this, SLOT (showOptions()));
572 connect (nextAction, SIGNAL(triggered()), this, SLOT(next()));
573 connect (previousAction, SIGNAL(triggered()), this, SLOT(previous()));
574 connect (upAction, SIGNAL(triggered()), this, SLOT(upSelected()));
575 connect (downAction, SIGNAL(triggered()), this, SLOT(downSelected()));
576 connect (delAction, SIGNAL(triggered()), this, SLOT(removeSelectedItem()));
577 connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
578 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
579 connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
580 // connect (removeSelected, SIGNAL (triggered()), this, SLOT (removeSelectedItem()));
583 void MainWindow::removeSelectedItem()
585 if (QMessageBox::question(this, "Confirm remove", "Are you sure you want to remove this item?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
587 int row = musicTable->currentRow();
589 plman.removeItem(row);
592 void MainWindow::removeAllButSelectedItem()
594 if (QMessageBox::question(this, "Confirm remove", "Are you sure you want to remove all other items?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
596 int row = musicTable->currentRow();
599 QString uri = plman.getItem(row).uri;
602 plman.clearPlaylist();
603 plman.addStringList(lst);
607 void MainWindow::repeatToggle ()
610 settings.setValue("repeat", QVariant (repeat));
612 repeatAction->setIcon(QIcon (QPixmap (":images/repeatActive")));
614 repeatAction->setIcon(QIcon (QPixmap (":images/repeat")));
617 void MainWindow::shuffleToggle ()
620 settings.setValue("shuffle", QVariant (shuffle));
622 shuffleAction->setIcon(QIcon (QPixmap (":images/shuffleActive")));
624 shuffleAction->setIcon(QIcon (QPixmap (":images/shuffle")));
627 void MainWindow::volumeToggle ()
629 volumeSlider->setVisible(volumeAction->isChecked());
632 void MainWindow::play()
635 // lastPlayed = plman.indexOf(mediaObject->currentSource());
636 highlightRow(lastPlayed);
640 void MainWindow::stop()
647 void MainWindow::setupMenus()
649 QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
650 fileMenu->addAction(addFilesAction);
651 fileMenu->addAction(addFoldersAction);
652 fileMenu->addAction(addUrlAction);
653 fileMenu->addSeparator();
654 fileMenu->addAction(savePlaylistAction);
655 fileMenu->addAction(loadPlaylistAction);
656 fileMenu->addAction(clearPlaylistAction);
657 fileMenu->addAction(optionAction);
658 // fileMenu->addAction(exitAction);
660 QMenu *aboutMenu = menuBar()->addMenu(tr("&Help"));
661 aboutMenu->addAction(aboutAction);
662 aboutMenu->addAction(aboutQtAction);
665 void MainWindow::setupUi()
667 QToolBar *bar = new QToolBar;
668 bool flip = !portrait;
670 if(!flip) bar->setOrientation(Qt::Vertical);
671 bar->setStyleSheet("padding:7px");
673 seekSlider = new Phonon::SeekSlider(this);
674 seekSlider->setMediaObject(mediaObject);
675 if (flip) seekSlider->setOrientation(Qt::Vertical);
677 volumeSlider = new Phonon::VolumeSlider(this);
678 volumeSlider->setAudioOutput(audioOutput);
681 volumeSlider->setOrientation(Qt::Vertical);
682 volumeSlider->setMinimumHeight(150);
686 volumeSlider->setMinimumWidth(150);
688 volumeSlider->setMuteVisible(false);
689 bar->addAction(playAction);
690 bar->addAction(pauseAction);
691 bar->addAction(stopAction);
692 bar->addAction(repeatAction);
693 bar->addAction(shuffleAction);
694 bar->addAction(nextAction);
695 bar->addAction(previousAction);
696 bar->addAction(upAction);
697 bar->addAction(downAction);
698 bar->addAction(delAction);
699 bar->addAction(enqueueActionButton);
701 contextMenu = new QMenu (this);
702 enqueueAction = contextMenu->addAction(tr ("Enqueue"));
703 removeSelected = contextMenu->addAction(tr ("Remove selected"));
704 removeAllButSelected = contextMenu->addAction(tr("Remove all but selected"));
705 connect (removeSelected, SIGNAL (triggered()), this, SLOT (removeSelectedItem()));
706 connect (removeAllButSelected, SIGNAL (triggered()), this, SLOT (removeAllButSelectedItem()));
707 connect (enqueueAction, SIGNAL (triggered()), this, SLOT (enqueueSelected()));
710 timeLcd = new QLCDNumber;
712 if (!headers.size ())
714 headers << "Artist" << "Title" << "Album";
715 settings.setValue("headers", headers);
718 musicTable = new QTableWidget(0, headers.size ());
719 musicTable->setHorizontalHeaderLabels(headers);
720 musicTable->setSelectionMode(QAbstractItemView::SingleSelection);
721 musicTable->setSelectionBehavior(QAbstractItemView::SelectRows);
722 // musicTable->setAlternatingRowColors(true);
723 musicTable->verticalHeader ()->hide();
724 connect(musicTable, SIGNAL(cellDoubleClicked(int,int)),
725 this, SLOT(tableClicked(int,int)));
726 connect(musicTable, SIGNAL(cellClicked(int,int)),
727 this, SLOT(cellClicked(int,int)));
728 for (int i = 0; i < musicTable->columnCount(); ++i)
730 QString lab = QString ("colWidth_%1").arg (i);
731 int val = settings.value(lab, 0).toInt();
733 musicTable->setColumnWidth(i, val);
737 QLayout *seekerLayout;
738 QLayout *playbackLayout;
741 seekerLayout = new QVBoxLayout;
742 playbackLayout = new QHBoxLayout;
743 bar->addWidget(timeLcd);
747 seekerLayout = new QHBoxLayout;
748 playbackLayout = new QVBoxLayout;
750 QToolBar* bar2 = new QToolBar;
751 bar2->addAction(volumeAction);
752 seekerLayout->addWidget(bar2);
753 seekerLayout->addWidget(volumeSlider);
754 seekerLayout->addWidget(seekSlider);
756 seekerLayout->addWidget(timeLcd);
757 volumeSlider->hide ();
758 playbackLayout->addWidget(bar);
760 QVBoxLayout *seekAndTableLayout = new QVBoxLayout;
762 seekAndTableLayout->addWidget(musicTable);
763 QHBoxLayout *mainLayout = new QHBoxLayout;
764 mainLayout->addLayout(seekAndTableLayout);
767 seekAndTableLayout->addLayout(playbackLayout);
768 mainLayout->addLayout(seekerLayout);
772 seekAndTableLayout->addLayout(seekerLayout);
773 mainLayout->addLayout(playbackLayout);
777 QWidget *widget = new QWidget;
778 widget->setLayout(mainLayout);
780 setCentralWidget(widget);
781 setWindowTitle("TomAmp");
784 void MainWindow::cellClicked(int /*row*/, int)
788 void MainWindow::enqueueSelected()
790 int sel = musicTable->currentRow();
791 qDebug () << "Enqueue on " << sel;
794 mediaObject->queue().clear();
795 mediaObject->enqueue(plman.at(sel));
797 QMaemo5InformationBox::information(this, plman.getItem(sel).title + tr (" enqueued as next song"),
798 QMaemo5InformationBox::DefaultTimeout);
804 void MainWindow::contextMenuEvent (QContextMenuEvent*e)
806 if (!childAt (e->pos()))
808 if (childAt (e->pos())->parentWidget() != musicTable)
810 contextMenu->popup(e->globalPos());
814 void MainWindow::setupShuffleList()
817 int index = plman.indexOf(mediaObject->currentSource());
820 for (int i = 0; i < plman.size(); ++i)
826 shuffleList.append (index);
829 int ind = qrand () % tmp.size();
830 shuffleList.append(tmp[ind]);
835 void MainWindow::savePlaylist ()
837 QString filename = QFileDialog::getSaveFileName(this, tr("Please select file name"), "", "Playlist Files (*.m3u *.pls)");
838 if (filename.isEmpty())
840 if (!plman.savePlaylist(filename))
843 QMaemo5InformationBox::information(this, tr ("Error writing playlist file"),
844 QMaemo5InformationBox::DefaultTimeout);
846 QMessageBox::critical(this, "Write error", "Error writing playlist file", QMessageBox::Ok);
852 void MainWindow::loadPlaylist ()
854 QString filename = QFileDialog::getOpenFileName(this, tr("Select playlist file to load"), "", "*.m3u *.pls");
855 if (filename.isEmpty())
857 plman.loadPlaylist (filename);
860 void MainWindow::playlistChanged(int from)
862 while (musicTable->rowCount() > from)
864 musicTable->removeRow(musicTable->rowCount () - 1);
867 for (int i = from; i < plman.size (); ++i)
869 if (firstGood < 0 && plman.getItem (i).playable)
871 int currentRow = musicTable->rowCount();
872 musicTable->insertRow(currentRow);
873 setRowFromItem (currentRow, plman.getItem(i));
875 /* if (plman.indexOf(mediaObject->currentSource()) < 0)
877 setItem (firstGood, false);
882 void MainWindow::setRowFromItem (int row, const PlaylistItem& item)
884 if (row >= musicTable->rowCount())
886 if (item.artist.isEmpty() && item.title.isEmpty())
888 int col = headers.indexOf("Title");
891 QTableWidgetItem *item1 = new QTableWidgetItem(item.uri);
892 item1->setFlags(item1->flags() ^ Qt::ItemIsEditable);
893 musicTable->setItem(row, col, item1);
898 int col = headers.indexOf("Artist");
901 QTableWidgetItem *item1 = new QTableWidgetItem(item.artist);
902 item1->setFlags(item1->flags() ^ Qt::ItemIsEditable);
903 musicTable->setItem(row, col, item1);
905 col = headers.indexOf("Title");
908 if (!musicTable->item (row, col))
910 QTableWidgetItem *item2 = new QTableWidgetItem(item.title);
911 item2->setFlags(item2->flags() ^ Qt::ItemIsEditable);
912 musicTable->setItem(row, col, item2);
916 musicTable->item (row, col)->setText(item.title);
919 col = headers.indexOf("Album");
922 QTableWidgetItem *item3 = new QTableWidgetItem(item.album);
923 item3->setFlags(item3->flags() ^ Qt::ItemIsEditable);
925 musicTable->setItem(row, col, item3);
929 int controlCol = headers.indexOf("Controls");
930 if (controlCol >= 0 && !musicTable->cellWidget(row, controlCol))
932 QLabel* label = new QLabel;
933 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>"));
934 label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
935 label->setProperty("row", row);
936 musicTable->setCellWidget(row, controlCol, label);
937 connect (label, SIGNAL (linkActivated (const QString&)), this, SLOT (playlistControl (const QString&)));
941 void MainWindow::playlistControl (const QString& con)
943 int i = sender ()->property("row").toInt();
946 else if (con == "down")
948 else if (con == "del")
950 else if (con == "enq")
952 musicTable->selectRow(i);
956 QMessageBox::information(this, tr ("Coming up..."), tr ("This feature is not implemented yet."));
960 void MainWindow::buttonUp(int i)
965 setRowFromItem (i, plman.getItem(i));
966 setRowFromItem (i - 1, plman.getItem(i - 1));
967 int controlCol = headers.indexOf("Controls");
970 musicTable->cellWidget(i, controlCol)->setProperty("row", i);
971 musicTable->cellWidget(i - 1, controlCol)->setProperty("row", i - 1);
973 musicTable->selectRow(i - 1);
977 void MainWindow::buttonDown(int i)
979 if (i < plman.size() - 1)
981 plman.moveItemDown(i);
982 setRowFromItem (i, plman.getItem(i));
983 setRowFromItem (i + 1, plman.getItem(i + 1));
984 int controlCol = headers.indexOf("Controls");
987 musicTable->cellWidget(i, controlCol)->setProperty("row", i);
988 musicTable->cellWidget(i + 1, controlCol)->setProperty("row", i + 1);
990 musicTable->selectRow(i + 1);
994 void MainWindow::buttonDel(int i)
996 if (QMessageBox::question(this, "Confirm remove", "Are you sure you want to remove this item?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
998 if (i < plman.size())
1000 plman.removeItem(i);
1004 void MainWindow::itemUpdated(int index)
1006 if (plman.indexOf(mediaObject->currentSource()) < 0 && plman.getItem (index).playable)
1008 setItem (index, false);
1010 setRowFromItem (index, plman.getItem(index));
1011 if (plman.indexOf(mediaObject->currentSource()) == index)
1013 if (shuffle) index = shuffleList.indexOf(index);
1014 setItem (index, false);
1018 void MainWindow::itemRemoved (int i)
1020 musicTable->removeRow(i);
1021 int controlCol = headers.indexOf("Controls");
1024 for (int j = i ? (i - 1) : 0; j < musicTable->rowCount(); ++j)
1026 if (musicTable->cellWidget(j, controlCol))
1027 musicTable->cellWidget(j, controlCol)->setProperty("row", j);
1031 void MainWindow::upSelected()
1033 int sel = musicTable->currentRow();
1038 void MainWindow::downSelected()
1040 int sel = musicTable->currentRow();
1047 void MainWindow::showOptions ()
1049 OptionDialog* dlg = new OptionDialog (this, settings);
1053 if (headers != settings.value("headers", QStringList ()).toStringList())
1055 headers = settings.value("headers", QStringList ()).toStringList();
1056 musicTable->setColumnCount(headers.size ());
1057 musicTable->setHorizontalHeaderLabels(headers);
1060 int curitem = plman.indexOf(mediaObject->currentSource());
1061 if (curitem >= 0 && isPlaying)
1062 highlightRow(curitem);