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)
17 audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
18 mediaObject = new Phonon::MediaObject(this);
20 mediaObject->setTickInterval(1000);
21 connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
22 connect(mediaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
23 this, SLOT(stateChanged(Phonon::State,Phonon::State)));
24 connect(mediaObject, SIGNAL(currentSourceChanged(Phonon::MediaSource)),
25 this, SLOT(sourceChanged(Phonon::MediaSource)));
26 connect(mediaObject, SIGNAL(aboutToFinish()), this, SLOT(aboutToFinish()));
27 connect (&plman, SIGNAL (playlistChanged (int)), this, SLOT (playlistChanged(int)));
28 connect (&plman, SIGNAL (itemUpdated(int)), this, SLOT (itemUpdated (int)));
29 connect (&plman, SIGNAL (itemRemoved(int)), this, SLOT (itemRemoved (int)));
31 Phonon::createPath(mediaObject, audioOutput);
34 repeat = settings.value("repeat", false).toBool();
35 shuffle = settings.value("shuffle", false).toBool();
36 headers = settings.value ("headers", QStringList()).toStringList();
40 /* if (settings.value("uiflipped", false).toBool())
45 timeLcd->display("00:00:00");
46 plman.addStringList(settings.value("lastPlaylist").toStringList());
48 int curind = settings.value("currentIndex", -1).toInt ();
50 setItem (curind, false);
51 audioOutput->setVolume(settings.value("volume", .5).toReal());
52 QApplication::setWindowIcon(QIcon (QPixmap (":images/tomamp")));
55 MainWindow::~MainWindow()
57 settings.setValue("shuffle", shuffle);
58 settings.setValue("repeat", repeat);
59 settings.setValue("lastPlaylist", plman.playlistStrings());
60 settings.setValue("volume", audioOutput->volume());
61 settings.setValue("currentIndex", plman.indexOf(mediaObject->currentSource()));
62 settings.setValue("headers", headers);
63 for (int i = 0; i < musicTable->columnCount(); ++i)
65 QString lab = QString ("colWidth_%1").arg (i);
66 settings.setValue(lab, musicTable->columnWidth(i));
70 void MainWindow::setOrientation ()
73 QString orient = settings.value("orientation", "Automatic").toString();
74 if (orient == "Portrait")
75 setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
76 else if (orient == "Landscape")
77 setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
79 setAttribute(Qt::WA_Maemo5AutoOrientation, true);
83 void MainWindow::addFiles()
85 QString folder = settings.value("LastFolder").toString();
87 folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
88 QStringList files = QFileDialog::getOpenFileNames(this, tr("Select Files To Add"),
89 folder, "Music files (*.mp3 *.ogg *.wav *.flac);;Playlists (*.m3u *.pls)");
94 QString dir = QFileInfo (files[0]).absoluteDir().absolutePath();
95 settings.setValue("LastFolder", dir);
97 foreach (QString string, files)
99 if (string.toLower().endsWith(".pls") || string.toLower().endsWith(".m3u"))
100 plman.addPlaylist(string);
102 toadd.append (string);
104 plman.addStringList(toadd);
107 void MainWindow::addFolder()
109 QString folder = settings.value("LastFolder").toString();
110 if (folder.isEmpty())
111 folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
112 QString dir = QFileDialog::getExistingDirectory(this,
113 tr("Select Directory To Add"),
119 settings.setValue("LastFolder", dir);
122 QStringList files = QDir (dir).entryList(filters, QDir::AllDirs);
123 files.removeAll(".");
124 files.removeAll("..");
125 bool recursive = false;
127 recursive = QMessageBox::question(this, "Add all folders", "Subfolders have been detected, add everything?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes;
128 plman.parseAndAddFolder(dir, recursive);
132 void MainWindow::addUrl()
134 #ifdef AVOID_INPUT_DIALOG
135 QString url = "http://war.str3am.com:7970";
137 QString url = QInputDialog::getText(this, "Get URL", "Please type in the stream URL");
139 if (url.isEmpty() || !url.toLower().startsWith("http"))
143 plman.addStringList(toadd);
147 void MainWindow::about()
149 QMessageBox::information(this, tr("About TomAmp v0.1"),
150 tr("TomAmp is a simple playlist-based music player.\n\n"
151 "(c) 2010 Tamas Marki <tmarki@gmail.com>\n\n"
152 "Please send comments and bug reports to the above e-mail address.\n\n"
153 "Icons by http://itweek.deviantart.com/\n\n"
154 "Special thanks to Attila Csipa"));
157 void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */)
161 case Phonon::ErrorState:
162 if (mediaObject->errorType() == Phonon::FatalError)
164 // QMessageBox::warning(this, tr("Fatal Error"),
165 // mediaObject->errorString() + mediaObject->currentSource().fileName() + ", " + mediaObject->currentSource().url().toString());
169 // QMessageBox::warning(this, tr("Error"),
170 // mediaObject->errorString());
174 case Phonon::PlayingState:
175 setWindowTitle(mediaObject->metaData().value("TITLE") + "(" + mediaObject->metaData().value("ARTIST") + ") - TomAmp");
176 pauseAction->setVisible(true);
177 playAction->setVisible (false);
178 playAction->setEnabled(false);
179 pauseAction->setEnabled(true);
180 stopAction->setEnabled(true);
181 unhighlightRow(lastPlayed);
182 lastPlayed = plman.indexOf(mediaObject->currentSource());
183 highlightRow(plman.indexOf(mediaObject->currentSource()));
184 musicTable->selectRow(plman.indexOf(mediaObject->currentSource()));
186 case Phonon::StoppedState:
187 setWindowTitle("TomAmp");
188 stopAction->setEnabled(false);
189 playAction->setEnabled(true);
190 pauseAction->setVisible(false);
191 playAction->setVisible(true);
192 pauseAction->setEnabled(false);
193 timeLcd->display("00:00:00");
194 unhighlightRow(plman.indexOf(mediaObject->currentSource()));
196 case Phonon::PausedState:
197 pauseAction->setEnabled(false);
198 stopAction->setEnabled(true);
199 pauseAction->setVisible(false);
200 playAction->setVisible(true);
201 playAction->setEnabled(true);
203 case Phonon::BufferingState:
210 void MainWindow::next()
212 bool wasPlaying = isPlaying;
213 if (mediaObject->state () == Phonon::ErrorState)
215 if (mediaObject->queue().size())
217 setItem (plman.indexOf(mediaObject->queue()[0]), wasPlaying);
220 int index = plman.indexOf(mediaObject->currentSource());
223 index = shuffleList.indexOf(plman.indexOf(mediaObject->currentSource())) + 1;
224 while (index < shuffleList.size () && !plman.getItem(shuffleList[index]).playable)
228 if (index < shuffleList.size ())
230 setItem (index, wasPlaying);
235 while ((index) < shuffleList.size () && !plman.getItem(shuffleList[index]).playable)
239 setItem (index, wasPlaying);
245 while ((index) < plman.size () && !plman.getItem(index).playable)
249 if (index < plman.size())
251 setItem (index, wasPlaying);
256 while ((index) < plman.size () && !plman.getItem(index).playable)
260 setItem (index, wasPlaying);
265 void MainWindow::setItem(int i, bool doplay)
267 if (i < plman.size() && i >= 0)
269 /* if (lastPlayed >= 0)
270 unhighlightRow(lastPlayed);*/
273 mediaObject->setCurrentSource(plman.at (shuffleList[i]));
277 mediaObject->setCurrentSource(plman.at(i));
280 if (doplay && mediaObject->currentSource().type() != Phonon::MediaSource::Invalid)
288 void MainWindow::previous()
290 bool wasPlaying = isPlaying;//(mediaObject->state () == Phonon::PlayingState);
291 if (mediaObject->state () == Phonon::ErrorState)
293 int index = plman.indexOf(mediaObject->currentSource());
296 index = shuffleList.indexOf(plman.indexOf(mediaObject->currentSource())) - 1;
297 while (index >= 0 && !plman.getItem(shuffleList[index]).playable)
303 setItem (index, wasPlaying);
307 index = plman.size () - 1;
308 while (index >= 0 && !plman.getItem(shuffleList[index]).playable)
312 setItem (index, wasPlaying);
315 wasPlaying = false;*/
321 while ((index) >= 0 && !plman.getItem(index).playable)
327 setItem (index, wasPlaying);
331 index = plman.size() - 1;
332 while ((index) >= 0 && !plman.getItem(index).playable)
336 setItem (index, wasPlaying);
341 void MainWindow::highlightRow (int i)
343 for (int j = 0; j < 3; ++j)
345 QTableWidgetItem* item = musicTable->item(i, j);
348 QFont font = item->font();
350 font.setItalic(true);
356 void MainWindow::unhighlightRow (int i)
358 for (int j = 0; j < 3; ++j)
360 QTableWidgetItem* item = musicTable->item(i, j);
363 QFont font = item->font();
365 font.setItalic(false);
372 void MainWindow::tick(qint64 time)
374 QTime displayTime((time / 3600000), (time / 60000) % 60, (time / 1000) % 60);
376 timeLcd->display(displayTime.toString("HH:mm:ss"));
379 void MainWindow::tableClicked(int row, int /* column */)
381 // bool wasPlaying = mediaObject->state() == Phonon::PlayingState;
383 /* mediaObject->stop();
384 mediaObject->clearQueue();*/
386 if (row >= plman.size())
390 while (index < shuffleList.size () && !plman.getItem(index).playable)
394 if (plman.size() > index)
397 index = shuffleList.indexOf(index);
398 setItem (index, true);
399 // mediaObject->play();
404 while (index < plman.size () && !plman.getItem(index).playable)
408 if (plman.size() > index)
411 index = shuffleList.indexOf(index);
412 setItem (index, true);
413 // mediaObject->play();
419 void MainWindow::sourceChanged(const Phonon::MediaSource &source)
421 int ind = plman.indexOf(source);
423 unhighlightRow(lastPlayed);
425 musicTable->selectRow(ind);
426 timeLcd->display("00:00:00");
430 void MainWindow::aboutToFinish()
432 if (mediaObject->queue().size())
434 int index = plman.indexOf(mediaObject->currentSource()) + 1;
437 index = shuffleList.indexOf(plman.indexOf(mediaObject->currentSource())) + 1;
438 if (index < shuffleList.size ())
440 mediaObject->enqueue(plman.at (shuffleList[index]));
444 mediaObject->enqueue(plman.at (shuffleList[0]));
450 if (plman.size() > index)
452 mediaObject->enqueue(plman.at(index));
456 mediaObject->enqueue(plman.at(0));
461 void MainWindow::finished()
465 void MainWindow::setupActions()
467 playAction = new QAction(QIcon (QPixmap (":images/play")), "", this);
468 playAction->setShortcut(tr("Crl+P"));
469 playAction->setDisabled(true);
470 pauseAction = new QAction(QIcon (QPixmap (":images/pause")), "", this);
471 pauseAction->setShortcut(tr("Ctrl+A"));
472 pauseAction->setDisabled(true);
473 pauseAction->setVisible(false);
474 stopAction = new QAction(QIcon (QPixmap (":images/stop")), "", this);
475 stopAction->setShortcut(tr("Ctrl+S"));
476 stopAction->setDisabled(true);
477 nextAction = new QAction(QIcon (QPixmap (":images/next")), "", this);
478 nextAction->setShortcut(tr("Ctrl+N"));
479 upAction = new QAction (QString::fromUtf8("▲"), this);
480 downAction = new QAction (QString::fromUtf8("▼"), this);
481 delAction = new QAction (QString::fromUtf8("╳"), this);
482 previousAction = new QAction(QIcon (QPixmap (":images/previous")), "", this);
483 previousAction->setShortcut(tr("Ctrl+R"));
485 repeatAction = new QAction(QIcon (QPixmap (":images/repeatActive")), "", this);
487 repeatAction = new QAction(QIcon (QPixmap (":images/repeat")), "", this);
488 repeatAction->setCheckable(true);
489 repeatAction->setChecked(repeat);
490 repeatAction->setShortcut(tr("Ctrl+I"));
492 shuffleAction = new QAction(QIcon (QPixmap (":images/shuffleActive")), "", this);
494 shuffleAction = new QAction(QIcon (QPixmap (":images/shuffle")), "", this);
495 shuffleAction->setCheckable(true);
496 shuffleAction->setChecked(shuffle);
497 shuffleAction->setShortcut(tr("Ctrl+H"));
498 enqueueActionButton = new QAction (tr ("E"), this);
499 volumeAction = new QAction(QIcon (QPixmap (":images/volume")), "", this);
500 volumeAction->setCheckable(true);
501 volumeAction->setShortcut(tr("Ctrl+V"));
502 addFilesAction = new QAction(tr("Add &File"), this);
503 addFilesAction->setShortcut(tr("Ctrl+F"));
504 addFoldersAction = new QAction(tr("Add F&older"), this);
505 addFoldersAction->setShortcut(tr("Ctrl+O"));
506 addUrlAction = new QAction(tr("Add &Url"), this);
507 addUrlAction->setShortcut(tr("Ctrl+U"));
508 savePlaylistAction = new QAction (tr("Sa&ve Playlist"), this);
509 savePlaylistAction->setShortcut(tr ("Ctrl+V"));
510 loadPlaylistAction = new QAction (tr("&Load Playlist"), this);
511 loadPlaylistAction->setShortcut(tr("Ctrl+L"));
512 clearPlaylistAction = new QAction (tr("&Clear Playlist"), this);
513 clearPlaylistAction->setShortcut(tr("Ctrl+C"));
514 optionAction = new QAction (tr("Op&tions"), this);
515 optionAction->setShortcut(tr("Ctrl+T"));
516 exitAction = new QAction(tr("E&xit"), this);
517 exitAction->setShortcut(tr("Ctrl+X"));
518 aboutAction = new QAction(tr("A&bout"), this);
519 aboutAction->setShortcut(tr("Ctrl+B"));
520 aboutQtAction = new QAction(tr("About &Qt"), this);
521 aboutQtAction->setShortcut(tr("Ctrl+Q"));
522 /* removeSelected = new QAction (tr("&Delete from playlist"));
523 removeSelected->setShortcut(tr ("Ctrl+D"));*/
525 connect(playAction, SIGNAL(triggered()), this, SLOT(play()));
526 connect(pauseAction, SIGNAL(triggered()), mediaObject, SLOT(pause()) );
527 connect(stopAction, SIGNAL(triggered()), this, SLOT(stop()));
528 connect(repeatAction, SIGNAL(triggered()), this, SLOT(repeatToggle()));
529 connect(shuffleAction, SIGNAL(triggered()), this, SLOT(shuffleToggle()));
530 connect(volumeAction, SIGNAL(triggered()), this, SLOT(volumeToggle()));
531 connect(enqueueActionButton, SIGNAL(triggered()), this, SLOT(enqueueSelected()));
533 connect(addFilesAction, SIGNAL(triggered()), this, SLOT(addFiles()));
534 connect(addFoldersAction, SIGNAL(triggered()), this, SLOT(addFolder()));
535 connect(addUrlAction, SIGNAL(triggered()), this, SLOT(addUrl()));
536 connect (savePlaylistAction, SIGNAL (triggered()), this, SLOT (savePlaylist()));
537 connect (loadPlaylistAction, SIGNAL (triggered()), this, SLOT (loadPlaylist()));
538 connect (clearPlaylistAction, SIGNAL (triggered()), &plman, SLOT (clearPlaylist()));
539 connect (optionAction, SIGNAL (triggered()), this, SLOT (showOptions()));
540 connect (nextAction, SIGNAL(triggered()), this, SLOT(next()));
541 connect (previousAction, SIGNAL(triggered()), this, SLOT(previous()));
542 connect (upAction, SIGNAL(triggered()), this, SLOT(upSelected()));
543 connect (downAction, SIGNAL(triggered()), this, SLOT(downSelected()));
544 connect (delAction, SIGNAL(triggered()), this, SLOT(removeSelectedItem()));
545 connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
546 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
547 connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
548 // connect (removeSelected, SIGNAL (triggered()), this, SLOT (removeSelectedItem()));
551 void MainWindow::removeSelectedItem()
553 if (QMessageBox::question(this, "Confirm remove", "Are you sure you want to remove this item?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
555 int row = musicTable->currentRow();
557 plman.removeItem(row);
560 void MainWindow::removeAllButSelectedItem()
562 if (QMessageBox::question(this, "Confirm remove", "Are you sure you want to remove all other items?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
564 int row = musicTable->currentRow();
567 QString uri = plman.getItem(row).uri;
570 plman.clearPlaylist();
571 plman.addStringList(lst);
575 void MainWindow::repeatToggle ()
578 settings.setValue("repeat", QVariant (repeat));
580 repeatAction->setIcon(QIcon (QPixmap (":images/repeatActive")));
582 repeatAction->setIcon(QIcon (QPixmap (":images/repeat")));
585 void MainWindow::shuffleToggle ()
588 settings.setValue("shuffle", QVariant (shuffle));
590 shuffleAction->setIcon(QIcon (QPixmap (":images/shuffleActive")));
592 shuffleAction->setIcon(QIcon (QPixmap (":images/shuffle")));
595 void MainWindow::volumeToggle ()
597 volumeSlider->setVisible(volumeAction->isChecked());
600 void MainWindow::play()
603 // lastPlayed = plman.indexOf(mediaObject->currentSource());
604 highlightRow(lastPlayed);
608 void MainWindow::stop()
615 void MainWindow::setupMenus()
617 QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
618 fileMenu->addAction(addFilesAction);
619 fileMenu->addAction(addFoldersAction);
620 fileMenu->addAction(addUrlAction);
621 fileMenu->addSeparator();
622 fileMenu->addAction(savePlaylistAction);
623 fileMenu->addAction(loadPlaylistAction);
624 fileMenu->addAction(clearPlaylistAction);
625 fileMenu->addAction(optionAction);
626 // fileMenu->addAction(exitAction);
628 QMenu *aboutMenu = menuBar()->addMenu(tr("&Help"));
629 aboutMenu->addAction(aboutAction);
630 aboutMenu->addAction(aboutQtAction);
633 void MainWindow::setupUi()
635 QToolBar *bar = new QToolBar;
636 bool flip = settings.value("uiflipped", false).toBool();
638 if(!flip) bar->setOrientation(Qt::Vertical);
639 bar->setStyleSheet("padding:7px");
641 seekSlider = new Phonon::SeekSlider(this);
642 seekSlider->setMediaObject(mediaObject);
643 if (flip) seekSlider->setOrientation(Qt::Vertical);
645 volumeSlider = new Phonon::VolumeSlider(this);
646 volumeSlider->setAudioOutput(audioOutput);
647 volumeSlider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
648 if (flip) volumeSlider->setOrientation(Qt::Vertical);
649 volumeSlider->setMuteVisible(false);
650 bar->addAction(playAction);
651 bar->addAction(pauseAction);
652 bar->addAction(stopAction);
653 bar->addAction(repeatAction);
654 bar->addAction(shuffleAction);
655 bar->addAction(nextAction);
656 bar->addAction(previousAction);
657 bar->addAction(upAction);
658 bar->addAction(downAction);
659 bar->addAction(delAction);
660 bar->addAction(enqueueActionButton);
662 contextMenu = new QMenu (this);
663 enqueueAction = contextMenu->addAction(tr ("Enqueue"));
664 removeSelected = contextMenu->addAction(tr ("Remove selected"));
665 removeAllButSelected = contextMenu->addAction(tr("Remove all but selected"));
666 connect (removeSelected, SIGNAL (triggered()), this, SLOT (removeSelectedItem()));
667 connect (removeAllButSelected, SIGNAL (triggered()), this, SLOT (removeAllButSelectedItem()));
668 connect (enqueueAction, SIGNAL (triggered()), this, SLOT (enqueueSelected()));
671 timeLcd = new QLCDNumber;
673 if (!headers.size ())
675 headers << "Artist" << "Title" << "Album";
676 settings.setValue("headers", headers);
679 musicTable = new QTableWidget(0, headers.size ());
680 musicTable->setHorizontalHeaderLabels(headers);
681 musicTable->setSelectionMode(QAbstractItemView::SingleSelection);
682 musicTable->setSelectionBehavior(QAbstractItemView::SelectRows);
683 connect(musicTable, SIGNAL(cellDoubleClicked(int,int)),
684 this, SLOT(tableClicked(int,int)));
685 connect(musicTable, SIGNAL(cellClicked(int,int)),
686 this, SLOT(cellClicked(int,int)));
687 for (int i = 0; i < musicTable->columnCount(); ++i)
689 QString lab = QString ("colWidth_%1").arg (i);
690 int val = settings.value(lab, 0).toInt();
692 musicTable->setColumnWidth(i, val);
696 QLayout *seekerLayout;
697 QLayout *playbackLayout;
700 seekerLayout = new QVBoxLayout;
701 playbackLayout = new QHBoxLayout;
702 bar->addWidget(timeLcd);
706 seekerLayout = new QHBoxLayout;
707 playbackLayout = new QVBoxLayout;
709 QToolBar* bar2 = new QToolBar;
710 bar2->addAction(volumeAction);
711 seekerLayout->addWidget(bar2);
712 seekerLayout->addWidget(volumeSlider);
713 seekerLayout->addWidget(seekSlider);
715 seekerLayout->addWidget(timeLcd);
716 volumeSlider->hide ();
717 playbackLayout->addWidget(bar);
719 QVBoxLayout *seekAndTableLayout = new QVBoxLayout;
721 seekAndTableLayout->addWidget(musicTable);
722 QHBoxLayout *mainLayout = new QHBoxLayout;
723 mainLayout->addLayout(seekAndTableLayout);
726 seekAndTableLayout->addLayout(playbackLayout);
727 mainLayout->addLayout(seekerLayout);
731 seekAndTableLayout->addLayout(seekerLayout);
732 mainLayout->addLayout(playbackLayout);
736 QWidget *widget = new QWidget;
737 widget->setLayout(mainLayout);
739 setCentralWidget(widget);
740 setWindowTitle("TomAmp");
743 void MainWindow::cellClicked(int /*row*/, int)
747 void MainWindow::enqueueSelected()
749 int sel = musicTable->currentRow();
752 mediaObject->queue().clear();
753 mediaObject->enqueue(plman.at(sel));
755 QMaemo5InformationBox::information(this, tr ("Song enqueued as next song"),
756 QMaemo5InformationBox::DefaultTimeout);
762 void MainWindow::contextMenuEvent (QContextMenuEvent*e)
764 if (!childAt (e->pos()))
766 if (childAt (e->pos())->parentWidget() != musicTable)
768 contextMenu->popup(e->globalPos());
772 void MainWindow::setupShuffleList()
775 int index = plman.indexOf(mediaObject->currentSource());
778 for (int i = 0; i < plman.size(); ++i)
784 shuffleList.append (index);
787 int ind = qrand () % tmp.size();
788 shuffleList.append(tmp[ind]);
793 void MainWindow::savePlaylist ()
795 QString filename = QFileDialog::getSaveFileName(this, tr("Please select file name"), "", "Playlist Files (*.m3u *.pls)");
796 if (filename.isEmpty())
798 plman.savePlaylist(filename);
801 void MainWindow::loadPlaylist ()
803 QString filename = QFileDialog::getOpenFileName(this, tr("Select playlist file to load"), "", "*.m3u *.pls");
804 if (filename.isEmpty())
806 plman.loadPlaylist (filename);
809 void MainWindow::playlistChanged(int from)
811 while (musicTable->rowCount() > from)
813 musicTable->removeRow(musicTable->rowCount () - 1);
816 for (int i = from; i < plman.size (); ++i)
818 if (firstGood < 0 && plman.getItem (i).playable)
820 int currentRow = musicTable->rowCount();
821 musicTable->insertRow(currentRow);
822 setRowFromItem (currentRow, plman.getItem(i));
824 /* if (plman.indexOf(mediaObject->currentSource()) < 0)
826 setItem (firstGood, false);
831 void MainWindow::setRowFromItem (int row, const PlaylistItem& item)
833 if (row >= musicTable->rowCount())
835 if (item.artist.isEmpty() && item.title.isEmpty())
837 int col = headers.indexOf("Title");
840 QTableWidgetItem *item1 = new QTableWidgetItem(item.uri);
841 item1->setFlags(item1->flags() ^ Qt::ItemIsEditable);
842 musicTable->setItem(row, col, item1);
847 int col = headers.indexOf("Artist");
850 QTableWidgetItem *item1 = new QTableWidgetItem(item.artist);
851 item1->setFlags(item1->flags() ^ Qt::ItemIsEditable);
852 musicTable->setItem(row, col, item1);
854 col = headers.indexOf("Title");
857 if (!musicTable->item (row, col))
859 QTableWidgetItem *item2 = new QTableWidgetItem(item.title);
860 item2->setFlags(item2->flags() ^ Qt::ItemIsEditable);
861 musicTable->setItem(row, col, item2);
865 musicTable->item (row, col)->setText(item.title);
868 col = headers.indexOf("Album");
871 QTableWidgetItem *item3 = new QTableWidgetItem(item.album);
872 item3->setFlags(item3->flags() ^ Qt::ItemIsEditable);
873 musicTable->setItem(row, col, item3);
877 int controlCol = headers.indexOf("Controls");
878 if (controlCol >= 0 && !musicTable->cellWidget(row, controlCol))
880 QLabel* label = new QLabel;
881 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='info'>i</a></b>"));
882 label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
883 label->setProperty("row", row);
884 musicTable->setCellWidget(row, controlCol, label);
885 connect (label, SIGNAL (linkActivated (const QString&)), this, SLOT (playlistControl (const QString&)));
889 void MainWindow::playlistControl (const QString& con)
891 int i = sender ()->property("row").toInt();
892 qDebug () << "Playlist control: " << con << " on " << i;
895 else if (con == "down")
897 else if (con == "del")
900 QMessageBox::information(this, tr ("Coming up..."), tr ("This feature is not implemented yet."));
904 void MainWindow::buttonUp(int i)
906 qDebug () << "Presses up on " << i;
910 setRowFromItem (i, plman.getItem(i));
911 setRowFromItem (i - 1, plman.getItem(i - 1));
912 int controlCol = headers.indexOf("Controls");
915 musicTable->cellWidget(i, controlCol)->setProperty("row", i);
916 musicTable->cellWidget(i - 1, controlCol)->setProperty("row", i - 1);
918 musicTable->selectRow(i - 1);
922 void MainWindow::buttonDown(int i)
924 qDebug () << "Presses down on " << i;
925 if (i < plman.size() - 1)
927 plman.moveItemDown(i);
928 setRowFromItem (i, plman.getItem(i));
929 setRowFromItem (i + 1, plman.getItem(i + 1));
930 int controlCol = headers.indexOf("Controls");
933 musicTable->cellWidget(i, controlCol)->setProperty("row", i);
934 musicTable->cellWidget(i + 1, controlCol)->setProperty("row", i + 1);
936 musicTable->selectRow(i + 1);
940 void MainWindow::buttonDel(int i)
942 qDebug () << "Presses del on " << i;
943 if (QMessageBox::question(this, "Confirm remove", "Are you sure you want to remove this item?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
945 if (i < plman.size())
951 void MainWindow::itemUpdated(int index)
953 if (plman.indexOf(mediaObject->currentSource()) < 0 && plman.getItem (index).playable)
955 setItem (index, false);
957 setRowFromItem (index, plman.getItem(index));
958 if (plman.indexOf(mediaObject->currentSource()) == index)
960 if (shuffle) index = shuffleList.indexOf(index);
961 setItem (index, false);
965 void MainWindow::itemRemoved (int i)
967 musicTable->removeRow(i);
968 int controlCol = headers.indexOf("Controls");
971 for (int j = i ? (i - 1) : 0; j < musicTable->rowCount(); ++j)
973 if (musicTable->cellWidget(j, controlCol))
974 musicTable->cellWidget(j, controlCol)->setProperty("row", j);
978 void MainWindow::upSelected()
980 int sel = musicTable->currentRow();
985 void MainWindow::downSelected()
987 int sel = musicTable->currentRow();
994 void MainWindow::showOptions ()
996 bool flip = settings.value("uiflipped", false).toBool();
997 OptionDialog* dlg = new OptionDialog (this, settings);
1000 if (flip != settings.value("uiflipped", false).toBool())
1002 delete centralWidget();
1006 if (headers != settings.value("headers", QStringList ()).toStringList())
1008 headers = settings.value("headers", QStringList ()).toStringList();
1009 musicTable->setColumnCount(headers.size ());
1010 musicTable->setHorizontalHeaderLabels(headers);