previous/next button, some fixes
[tomamp] / mainwindow.cpp
1 #include <QtGui>
2 #include <QtDebug>
3 #include <QInputDialog>
4
5 #include "mainwindow.h"
6 #include "time.h"
7
8 #define AVOID_INPUT_DIALOG 1
9
10 MainWindow::MainWindow()
11     : settings (tr ("TomAmp"), "TomAmp")
12 {
13     audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
14     mediaObject = new Phonon::MediaObject(this);
15     metaInformationResolver = new Phonon::MediaObject(this);
16
17     mediaObject->setTickInterval(1000);
18     connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
19     connect(mediaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
20         this, SLOT(stateChanged(Phonon::State,Phonon::State)));
21     connect(metaInformationResolver, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
22         this, SLOT(metaStateChanged(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
27     Phonon::createPath(mediaObject, audioOutput);
28
29     repeat = settings.value("repeat", false).toBool();
30     shuffle = settings.value("shuffle", false).toBool();
31     qsrand (time (NULL));
32     setupShuffleList();
33     setupActions();
34     setupMenus();
35     setupUi();
36     timeLcd->display("00:00");
37     addStringList(settings.value("lastPlaylist").toStringList());
38     audioOutput->setVolume(settings.value("volume", .5).toReal());
39 }
40
41 MainWindow::~MainWindow()
42 {
43     settings.setValue("shuffle", shuffle);
44     QStringList curList;
45     foreach (Phonon::MediaSource src, sources)
46     {
47         if (src.type () == Phonon::MediaSource::LocalFile)
48             curList.append(src.fileName());
49         else
50             curList.append(src.url().toString());
51     }
52     settings.setValue("lastPlaylist", curList);
53     settings.setValue("volume", audioOutput->volume());
54     qDebug () << "cucc: " << musicTable->columnWidth(1);
55 }
56
57 void MainWindow::addFiles()
58 {
59     QString folder = settings.value("LastFolder").toString();
60     if (folder.isEmpty())
61         folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
62     QStringList files = QFileDialog::getOpenFileNames(this, tr("Select Files To Add"),
63                     folder);
64
65     if (files.isEmpty())
66         return;
67
68     QString dir = QFileInfo (files[0]).absoluteDir().absolutePath();
69     settings.setValue("LastFolder", dir);
70     int index = sources.size();
71     foreach (QString string, files)
72     {
73         Phonon::MediaSource source (string);
74         sources.append(source);
75     }
76     if (!sources.isEmpty())
77         metaInformationResolver->setCurrentSource(sources.at(index));
78     setupShuffleList();
79
80 }
81
82 void MainWindow::addFolder()
83 {
84     QString folder = settings.value("LastFolder").toString();
85     if (folder.isEmpty())
86         folder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
87     QString dir = QFileDialog::getExistingDirectory(this,
88             tr("Select Directory To Add"),
89             folder);
90
91     int index = sources.size();
92     QStringList filters;
93     QStringList files = QDir (dir).entryList(filters, QDir::AllDirs);
94     qDebug () << files;
95     bool recursive = false;
96     if (files.size())
97         recursive = QMessageBox::question(this, "Add all folders", "Subfolders have been detected, add everything?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes;
98     parseAndAddFolder(dir, recursive);
99     if (!sources.isEmpty() && index < sources.size())
100         metaInformationResolver->setCurrentSource(sources.at(index));
101     setupShuffleList();
102
103 }
104
105 void MainWindow::parseAndAddFolder(const QString &dir, bool recursive)
106 {
107     QStringList filters;
108 //    filters << "*.mp3";
109
110     QStringList files = QDir (dir).entryList(filters);
111
112     if (files.isEmpty())
113         return;
114
115     qDebug () << files;
116
117     settings.setValue("LastFolder", dir);
118     foreach (QString string, files)
119     {
120         QString fname = dir + "/" + string;
121         qDebug () << fname;
122         Phonon::MediaSource source(fname);
123         sources.append(source);
124     }
125
126 }
127
128 void MainWindow::addUrl()
129 {
130 #ifdef AVOID_INPUT_DIALOG
131     QString url = "http://war.str3am.com:7970";
132 #else
133     QString url = QInputDialog::getText(this, "Get URL", "Please type in the stream URL");
134 #endif
135     int index = sources.size();
136     if (!url.isEmpty())
137     {
138         Phonon::MediaSource source(url);
139         sources.append(source);
140     }
141     if (!sources.isEmpty())
142         metaInformationResolver->setCurrentSource(sources.at(index));
143     setupShuffleList();
144 }
145
146 void MainWindow::addStringList(const QStringList& list)
147 {
148     int index = sources.size();
149     foreach (QString string, list)
150     {
151         Phonon::MediaSource source(string);
152         sources.append(source);
153     }
154     if (!sources.isEmpty())
155         metaInformationResolver->setCurrentSource(sources.at(index));
156     setupShuffleList();
157 }
158
159 void MainWindow::about()
160 {
161     QMessageBox::information(this, tr("About TomAmp v0.1"),
162         tr("TomAmp is a simple playlist-based music player.\n\n"
163         "(c) 2010 Tamas Marki <tmarki@gmail.com>\n\n"
164         "Please send comments and bug reports to the above e-mail address.\n\n"
165         "Icons by deleket (http://www.deleket.com)"));
166 }
167
168 void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */)
169 {
170     qDebug () << "State: " << newState;
171     switch (newState)
172     {
173         case Phonon::ErrorState:
174             if (mediaObject->errorType() == Phonon::FatalError)
175             {
176                 QMessageBox::warning(this, tr("Fatal Error"),
177                 mediaObject->errorString());
178             }
179             else
180             {
181                 QMessageBox::warning(this, tr("Error"),
182                 mediaObject->errorString());
183             }
184             break;
185         case Phonon::PlayingState:
186             setWindowTitle(mediaObject->metaData().value("TITLE") + " - TomAmp");
187             pauseAction->setVisible(true);
188             playAction->setVisible (false);
189             playAction->setEnabled(false);
190             pauseAction->setEnabled(true);
191             stopAction->setEnabled(true);
192             break;
193         case Phonon::StoppedState:
194             stopAction->setEnabled(false);
195             playAction->setEnabled(true);
196             pauseAction->setVisible(false);
197             playAction->setVisible(true);
198             pauseAction->setEnabled(false);
199             timeLcd->display("00:00");
200             break;
201         case Phonon::PausedState:
202             pauseAction->setEnabled(false);
203             stopAction->setEnabled(true);
204             pauseAction->setVisible(false);
205             playAction->setVisible(true);
206             playAction->setEnabled(true);
207             qDebug () << "Queue size: " << mediaObject->queue().size ();
208             if (mediaObject->queue().size ())
209             {
210                 mediaObject->setCurrentSource(mediaObject->queue()[0]);
211                 musicTable->selectRow(sources.indexOf(mediaObject->currentSource()));
212                 mediaObject->play();
213             }
214             mediaObject->clearQueue();
215             break;
216         case Phonon::BufferingState:
217             qDebug () << "Buffering";
218             break;
219         default:
220         ;
221     }
222 }
223
224 void MainWindow::next()
225 {
226     bool wasPlaying = (mediaObject->state () == Phonon::PlayingState);
227     int index = sources.indexOf(mediaObject->currentSource()) + 1;
228     if (shuffle)
229     {
230         index = shuffleList.indexOf(sources.indexOf(mediaObject->currentSource())) + 1;
231         if (index < shuffleList.size ())
232         {
233             mediaObject->setCurrentSource(sources.at (shuffleList[index]));
234         }
235         else if (repeat)
236         {
237             mediaObject->setCurrentSource(sources.at (shuffleList[0]));
238         }
239
240     }
241     else
242     {
243         if (sources.size() > index)
244         {
245             mediaObject->setCurrentSource(sources.at(index));
246         }
247         else if (repeat)
248         {
249             mediaObject->setCurrentSource(sources.at(0));
250         }
251     }
252     if (wasPlaying)
253         mediaObject->play();
254 }
255
256 void MainWindow::previous()
257 {
258     bool wasPlaying = (mediaObject->state () == Phonon::PlayingState);
259     int index = sources.indexOf(mediaObject->currentSource()) - 1;
260     if (shuffle)
261     {
262         index = shuffleList.indexOf(sources.indexOf(mediaObject->currentSource())) - 1;
263         if (index >= 0)
264         {
265             mediaObject->setCurrentSource(sources.at (shuffleList[index]));
266         }
267         else if (repeat)
268         {
269             mediaObject->setCurrentSource(sources.at (shuffleList[shuffleList.size() - 1]));
270         }
271
272     }
273     else
274     {
275         if (index >= 0)
276         {
277             mediaObject->setCurrentSource(sources.at(index));
278         }
279         else if (repeat)
280         {
281             mediaObject->setCurrentSource(sources.at(sources.size() - 1));
282         }
283     }
284     if (wasPlaying)
285         mediaObject->play();
286
287 }
288
289 void MainWindow::tick(qint64 time)
290 {
291     QTime displayTime(0, (time / 60000) % 60, (time / 1000) % 60);
292
293     timeLcd->display(displayTime.toString("mm:ss"));
294 }
295
296 void MainWindow::tableClicked(int row, int /* column */)
297 {
298 //    bool wasPlaying = mediaObject->state() == Phonon::PlayingState;
299
300     mediaObject->stop();
301     mediaObject->clearQueue();
302
303     if (row >= sources.size())
304         return;
305
306     mediaObject->setCurrentSource(sources[row]);
307
308     mediaObject->play();
309     int ind = shuffleList.indexOf(row);
310     shuffleList.removeAt(ind);
311     shuffleList.insert(0, row);
312     qDebug () << "Modified shuffle list: " << shuffleList;
313 }
314
315 void MainWindow::sourceChanged(const Phonon::MediaSource &source)
316 {
317     musicTable->selectRow(sources.indexOf(source));
318     timeLcd->display("00:00");
319 }
320
321 void MainWindow::metaStateChanged(Phonon::State newState, Phonon::State /* oldState */)
322 {
323     if (newState == Phonon::ErrorState)
324     {
325         QMessageBox::warning(this, tr("Error opening files"),
326         metaInformationResolver->errorString());
327         while (!sources.isEmpty() &&
328             !(sources.takeLast() == metaInformationResolver->currentSource())) {}  /* loop */;
329         return;
330     }
331
332     if (newState != Phonon::StoppedState && newState != Phonon::PausedState)
333     {
334         return;
335     }
336
337     if (metaInformationResolver->currentSource().type() == Phonon::MediaSource::Invalid)
338         return;
339
340     QMap<QString, QString> metaData = metaInformationResolver->metaData();
341
342     QString title = metaData.value("TITLE");
343     if (title == "")
344         title = metaInformationResolver->currentSource().fileName();
345
346     if (title == "")
347         title = metaInformationResolver->currentSource().url().toString();
348
349     QTableWidgetItem *titleItem = new QTableWidgetItem(title);
350     titleItem->setFlags(titleItem->flags() ^ Qt::ItemIsEditable);
351     QTableWidgetItem *artistItem = new QTableWidgetItem(metaData.value("ARTIST"));
352     artistItem->setFlags(artistItem->flags() ^ Qt::ItemIsEditable);
353     QTableWidgetItem *albumItem = new QTableWidgetItem(metaData.value("ALBUM"));
354     albumItem->setFlags(albumItem->flags() ^ Qt::ItemIsEditable);
355
356     int currentRow = musicTable->rowCount();
357     musicTable->insertRow(currentRow);
358     musicTable->setItem(currentRow, 0, artistItem);
359     musicTable->setItem(currentRow, 1, titleItem);
360     musicTable->setItem(currentRow, 2, albumItem);
361
362
363     if (musicTable->selectedItems().isEmpty())
364     {
365         musicTable->selectRow(0);
366         mediaObject->setCurrentSource(metaInformationResolver->currentSource());
367     }
368
369     Phonon::MediaSource source = metaInformationResolver->currentSource();
370     int index = sources.indexOf(metaInformationResolver->currentSource()) + 1;
371     if (sources.size() > index)
372     {
373         metaInformationResolver->setCurrentSource(sources.at(index));
374     }
375     else
376     {
377         musicTable->resizeColumnsToContents();
378 /*        if (musicTable->columnWidth(0) > 300)
379             musicTable->setColumnWidth(0, 300);*/
380     }
381 }
382
383 void MainWindow::aboutToFinish()
384 {
385     qDebug () << "Abouttotfinish";
386     int index = sources.indexOf(mediaObject->currentSource()) + 1;
387     if (shuffle)
388     {
389         index = shuffleList.indexOf(sources.indexOf(mediaObject->currentSource())) + 1;
390         if (index < shuffleList.size ())
391         {
392             mediaObject->enqueue(sources.at (shuffleList[index]));
393         }
394         else if (repeat)
395         {
396             mediaObject->enqueue(sources.at (shuffleList[0]));
397         }
398
399     }
400     else
401     {
402         if (sources.size() > index)
403         {
404             mediaObject->enqueue(sources.at(index));
405             qDebug () << "Enqueue " << index << " pfm " << mediaObject->prefinishMark();
406         }
407         else if (repeat)
408         {
409             mediaObject->enqueue(sources.at(0));
410             qDebug () << "Enqueue " << 0 << " pfm " << mediaObject->prefinishMark();
411         }
412     }
413 }
414
415 void MainWindow::finished()
416 {
417     qDebug () << "Finished";
418 }
419
420 void MainWindow::setupActions()
421 {
422     playAction = new QAction(QIcon (QPixmap (":images/play")), tr("Play"), this);
423     playAction->setShortcut(tr("Crl+P"));
424     playAction->setDisabled(true);
425     pauseAction = new QAction(QIcon (QPixmap (":images/pause")), tr("Pause"), this);
426     pauseAction->setShortcut(tr("Ctrl+A"));
427     pauseAction->setDisabled(true);
428     pauseAction->setVisible(false);
429     stopAction = new QAction(QIcon (QPixmap (":images/stop")), tr("Stop"), this);
430     stopAction->setShortcut(tr("Ctrl+S"));
431     stopAction->setDisabled(true);
432     nextAction = new QAction(QIcon (QPixmap (":images/next")), tr("Next"), this);
433     nextAction->setShortcut(tr("Ctrl+N"));
434     previousAction = new QAction(QIcon (QPixmap (":images/previous")), tr("Previous"), this);
435     previousAction->setShortcut(tr("Ctrl+R"));
436     repeatAction = new QAction(QIcon (QPixmap (":images/repeat")), tr("Repeat"), this);
437     repeatAction->setCheckable(true);
438     repeatAction->setChecked(repeat);
439     repeatAction->setShortcut(tr("Ctrl+I"));
440     shuffleAction = new QAction(QIcon (QPixmap (":images/shuffle")), tr("Shuffle"), this);
441     shuffleAction->setCheckable(true);
442     shuffleAction->setChecked(shuffle);
443     shuffleAction->setShortcut(tr("Ctrl+H"));
444     volumeAction = new QAction(QIcon (QPixmap (":images/volume")), tr("Volume"), this);
445     volumeAction->setCheckable(true);
446     volumeAction->setShortcut(tr("Ctrl+V"));
447     addFilesAction = new QAction(tr("Add &File"), this);
448     addFilesAction->setShortcut(tr("Ctrl+F"));
449     addFoldersAction = new QAction(tr("Add F&older"), this);
450     addFoldersAction->setShortcut(tr("Ctrl+O"));
451     addUrlAction = new QAction(tr("Add &Url"), this);
452     addUrlAction->setShortcut(tr("Ctrl+U"));
453     savePlaylistAction = new QAction (tr("Sa&ve Playlist"), this);
454     savePlaylistAction->setShortcut(tr ("Ctrl+V"));
455     loadPlaylistAction = new QAction (tr("&Load Playlist"), this);
456     loadPlaylistAction->setShortcut(tr("Ctrl+L"));
457     clearPlaylistAction = new QAction (tr("&Clear Playlist"), this);
458     clearPlaylistAction->setShortcut(tr("Ctrl+C"));
459     exitAction = new QAction(tr("E&xit"), this);
460     exitAction->setShortcut(tr("Ctrl+X"));
461     aboutAction = new QAction(tr("A&bout"), this);
462     aboutAction->setShortcut(tr("Ctrl+B"));
463     aboutQtAction = new QAction(tr("About &Qt"), this);
464     aboutQtAction->setShortcut(tr("Ctrl+Q"));
465
466     connect(playAction, SIGNAL(triggered()), mediaObject, SLOT(play()));
467     connect(pauseAction, SIGNAL(triggered()), mediaObject, SLOT(pause()) );
468     connect(stopAction, SIGNAL(triggered()), mediaObject, SLOT(stop()));
469     connect(repeatAction, SIGNAL(triggered()), this, SLOT(repeatToggle()));
470     connect(shuffleAction, SIGNAL(triggered()), this, SLOT(shuffleToggle()));
471     connect(volumeAction, SIGNAL(triggered()), this, SLOT(volumeToggle()));
472     connect(addFilesAction, SIGNAL(triggered()), this, SLOT(addFiles()));
473     connect(addFoldersAction, SIGNAL(triggered()), this, SLOT(addFolder()));
474     connect(addUrlAction, SIGNAL(triggered()), this, SLOT(addUrl()));
475     connect (savePlaylistAction, SIGNAL (triggered()), this, SLOT (savePlaylist()));
476     connect (loadPlaylistAction, SIGNAL (triggered()), this, SLOT (loadPlaylist()));
477     connect (clearPlaylistAction, SIGNAL (triggered()), this, SLOT (clearPlaylist()));
478     connect (nextAction, SIGNAL(triggered()), this, SLOT(next()));
479     connect (previousAction, SIGNAL(triggered()), this, SLOT(previous()));
480     connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
481     connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
482     connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
483 }
484
485 void MainWindow::savePlaylist()
486 {
487     QString filename = QFileDialog::getSaveFileName(this, tr("Please select file name"), "", "Playlist Files (*.m3u)");
488     if (filename.isEmpty())
489         return;
490     if (filename.length() < 4 || filename.right(4).toLower() != ".m3u")
491         filename += ".m3u";
492     QFile f (filename);
493     try
494     {
495         f.open(QFile::WriteOnly);
496         for (int i = 0; i < sources.size(); ++i)
497         {
498             if (sources[i].type() == Phonon::MediaSource::LocalFile)
499                 f.write (sources[i].fileName().toAscii());
500             else
501                 f.write(sources[i].url().toString().toAscii());
502             f.write ("\n");
503         }
504         f.close ();
505     }
506     catch (...)
507     {
508         QMessageBox::critical(this, "Write error", "Could not write playlist file", QMessageBox::Ok);
509     }
510 }
511
512 void MainWindow::loadPlaylist()
513 {
514     QString filename = QFileDialog::getOpenFileName(this, tr("Select playlist file to load"), "", "*.m3u");
515     QFile f(filename);
516     f.open (QFile::ReadOnly);
517     QString tmp = f.readAll();
518     f.close ();
519     QStringList lines = tmp.split("\n");
520     clearPlaylist();
521     foreach (QString l, lines)
522     {
523         if (l.isEmpty() || (!QFileInfo (l).exists() && (l.indexOf("http") != 0)))
524         {
525             qDebug () << "not loadable: " << l;\
526             continue;
527         }
528         qDebug () << "Load " << l;
529         Phonon::MediaSource source(l);
530         sources.append(source);
531     }
532     if (!sources.isEmpty())
533         metaInformationResolver->setCurrentSource(sources.at(0));
534     setupShuffleList();
535 }
536
537 void MainWindow::clearPlaylist()
538 {
539     sources.clear();
540     while (musicTable->rowCount())
541         musicTable->removeRow(0);
542     mediaObject->clear();
543 }
544
545 void MainWindow::repeatToggle ()
546 {
547     repeat = !repeat;
548     qDebug() << "Repeat toggled to " << repeat;
549     settings.setValue("repeat", QVariant (repeat));
550 }
551
552 void MainWindow::shuffleToggle ()
553 {
554     shuffle = !shuffle;
555     settings.setValue("shuffle", QVariant (shuffle));
556 }
557
558 void MainWindow::volumeToggle ()
559 {
560     qDebug () << "Volumetoggle: " << volumeAction->isChecked();
561     volumeSlider->setVisible(volumeAction->isChecked());
562 }
563
564
565 void MainWindow::setupMenus()
566 {
567     QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
568     fileMenu->addAction(addFilesAction);
569     fileMenu->addAction(addFoldersAction);
570     fileMenu->addAction(addUrlAction);
571     fileMenu->addSeparator();
572     fileMenu->addAction(savePlaylistAction);
573     fileMenu->addAction(loadPlaylistAction);
574     fileMenu->addAction(clearPlaylistAction);
575 //    fileMenu->addAction(exitAction);
576
577     QMenu *aboutMenu = menuBar()->addMenu(tr("&Help"));
578     aboutMenu->addAction(aboutAction);
579     aboutMenu->addAction(aboutQtAction);
580 }
581
582 void MainWindow::setupUi()
583 {
584     QToolBar *bar = new QToolBar;
585
586     bar->setOrientation(Qt::Vertical);
587     bar->setStyleSheet("padding:7px");
588     //bar->addAction(volumeAction);
589
590     seekSlider = new Phonon::SeekSlider(this);
591     seekSlider->setMediaObject(mediaObject);
592
593     volumeSlider = new Phonon::VolumeSlider(this);
594     volumeSlider->setAudioOutput(audioOutput);
595     volumeSlider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
596     volumeSlider->setOrientation(Qt::Horizontal);
597     volumeSlider->setMuteVisible(false);
598 //    volumeAddedAction = bar->addWidget(volumeSlider);
599 //    volumeAddedAction->setVisible(false);
600     bar->addAction(playAction);
601     bar->addAction(pauseAction);
602     bar->addAction(stopAction);
603     bar->addAction(repeatAction);
604     bar->addAction(shuffleAction);
605     bar->addAction(nextAction);
606     bar->addAction(previousAction);
607
608 /*    QLabel *volumeLabel = new QLabel;
609     volumeLabel->setPixmap(QPixmap("images/volume.png"));*/
610
611 /*    QPalette palette;
612     palette.setBrush(QPalette::Light, Qt::darkGray);*/
613
614     timeLcd = new QLCDNumber;
615 //    timeLcd->setPalette(palette);
616
617     QStringList headers;
618     headers << tr("Artist") << tr("Title") << tr("Album");
619
620     musicTable = new QTableWidget(0, 3);
621     musicTable->setHorizontalHeaderLabels(headers);
622     musicTable->setSelectionMode(QAbstractItemView::SingleSelection);
623     musicTable->setSelectionBehavior(QAbstractItemView::SelectRows);
624     connect(musicTable, SIGNAL(cellDoubleClicked(int,int)),
625         this, SLOT(tableClicked(int,int)));
626     connect(musicTable, SIGNAL(cellClicked(int,int)),
627         this, SLOT(cellClicked(int,int)));
628     musicTable->setSelectionBehavior(QAbstractItemView::SelectRows);
629
630     QHBoxLayout *seekerLayout = new QHBoxLayout;
631     QToolBar* bar2 = new QToolBar;
632     bar2->addAction(volumeAction);
633     seekerLayout->addWidget(bar2);
634     seekerLayout->addWidget(volumeSlider);
635     seekerLayout->addWidget(seekSlider);
636     seekerLayout->addWidget(timeLcd);
637
638     QVBoxLayout *playbackLayout = new QVBoxLayout;
639     volumeSlider->hide ();
640     playbackLayout->addWidget(bar);
641 //    playbackLayout->addStretch();
642 //    playbackLayout->addWidget(volumeSlider);
643 //    playbackLayout->addWidget(volumeLabel);
644
645     QVBoxLayout *seekAndTableLayout = new QVBoxLayout;
646
647     seekAndTableLayout->addWidget(musicTable);
648     seekAndTableLayout->addLayout(seekerLayout);
649
650     QHBoxLayout *mainLayout = new QHBoxLayout;
651     mainLayout->addLayout(seekAndTableLayout);
652     mainLayout->addLayout(playbackLayout);
653
654     QWidget *widget = new QWidget;
655     widget->setLayout(mainLayout);
656
657     setCentralWidget(widget);
658     setWindowTitle("TomAmp");
659     qDebug () << "cucc: " << musicTable->columnWidth(1);
660 }
661
662 void MainWindow::cellClicked(int row, int)
663 {
664     if (mediaObject->state() == Phonon::PlayingState)
665     {
666         int index = sources.indexOf(mediaObject->currentSource());
667         if (index >= 0)
668         {
669             musicTable->selectRow(index);
670         }
671     }
672     else if (row < sources.size())
673     {
674         mediaObject->setCurrentSource(sources[row]);
675         shuffleList.removeAll(row);
676         shuffleList.insert(0, row);
677         qDebug () << shuffleList;
678     }
679 }
680
681 void MainWindow::setupShuffleList()
682 {
683     QList<int> tmp;
684     int index = sources.indexOf(mediaObject->currentSource());
685     if (index < 0)
686         index = 0;
687     for (int i = 0; i < sources.size(); ++i)
688     {
689         if (i != index)
690             tmp.append(i);
691     }
692     shuffleList.clear();
693     shuffleList.append (index);
694     while (tmp.size ())
695     {
696         int ind = qrand () % tmp.size();
697         shuffleList.append(tmp[ind]);
698         tmp.removeAt(ind);
699     }
700     qDebug () << shuffleList;
701     qDebug () << shuffleList;
702 }