#include "mainwindow.h" #include "player.h" #include "playlist.h" #include "library.h" #include "libraryconfig.h" #include "songplaylistitem.h" #include "systemtrayicon.h" #include #include #include #include #include #include #include #include #include #include const int MainWindow::kStateVersion = 1; const char* MainWindow::kSettingsGroup = "MainWindow"; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), playlist_(new Playlist(this)), player_(new Player(playlist_, this)), library_(new Library(player_->GetEngine(), this)), library_sort_model_(new QSortFilterProxyModel(this)), tray_icon_(new SystemTrayIcon(this)) { ui_.setupUi(this); tray_icon_->setIcon(windowIcon()); tray_icon_->setToolTip("Tangerine"); tray_icon_->show(); ui_.volume->setValue(player_->GetVolume()); // Models library_sort_model_->setSourceModel(library_); library_sort_model_->setSortRole(Library::Role_SortText); library_sort_model_->setDynamicSortFilter(true); library_sort_model_->sort(0); playlist_->Restore(); ui_.playlist->setModel(playlist_); ui_.library_view->setModel(library_sort_model_); ui_.library_view->SetLibrary(library_); // File view connections connect(ui_.file_view, SIGNAL(Queue(QList)), SLOT(QueueFiles(QList))); connect(ui_.file_view, SIGNAL(PathChanged(QString)), SLOT(FilePathChanged(QString))); // Action connections connect(ui_.action_next_track, SIGNAL(triggered()), player_, SLOT(Next())); connect(ui_.action_previous_track, SIGNAL(triggered()), player_, SLOT(Previous())); connect(ui_.action_play_pause, SIGNAL(triggered()), player_, SLOT(PlayPause())); connect(ui_.action_stop, SIGNAL(triggered()), player_, SLOT(Stop())); connect(ui_.action_quit, SIGNAL(triggered()), qApp, SLOT(quit())); connect(ui_.action_stop_after_this_track, SIGNAL(triggered()), SLOT(StopAfterCurrent())); connect(ui_.library_filter, SIGNAL(textChanged(QString)), library_, SLOT(SetFilterText(QString))); // Give actions to buttons ui_.forward_button->setDefaultAction(ui_.action_next_track); ui_.back_button->setDefaultAction(ui_.action_previous_track); ui_.pause_play_button->setDefaultAction(ui_.action_play_pause); ui_.stop_button->setDefaultAction(ui_.action_stop); // Stop actions QMenu* stop_menu = new QMenu(this); stop_menu->addAction(ui_.action_stop); stop_menu->addAction(ui_.action_stop_after_this_track); ui_.stop_button->setMenu(stop_menu); // Player connections connect(ui_.volume, SIGNAL(valueChanged(int)), player_, SLOT(SetVolume(int))); connect(player_, SIGNAL(Error(QString)), SLOT(ReportError(QString))); connect(player_, SIGNAL(Paused()), SLOT(MediaPaused())); connect(player_, SIGNAL(Playing()), SLOT(MediaPlaying())); connect(player_, SIGNAL(Stopped()), SLOT(MediaStopped())); connect(player_, SIGNAL(Paused()), playlist_, SLOT(Paused())); connect(player_, SIGNAL(Playing()), playlist_, SLOT(Playing())); connect(player_, SIGNAL(Stopped()), playlist_, SLOT(Stopped())); connect(player_, SIGNAL(Paused()), ui_.playlist, SLOT(StopGlowing())); connect(player_, SIGNAL(Playing()), ui_.playlist, SLOT(StartGlowing())); connect(player_, SIGNAL(Stopped()), ui_.playlist, SLOT(StopGlowing())); connect(ui_.playlist, SIGNAL(doubleClicked(QModelIndex)), SLOT(PlayIndex(QModelIndex))); // Library connections connect(library_, SIGNAL(Error(QString)), SLOT(ReportError(QString))); connect(ui_.library_view, SIGNAL(doubleClicked(QModelIndex)), SLOT(LibraryDoubleClick(QModelIndex))); connect(ui_.library_view, SIGNAL(ShowConfigDialog()), library_, SLOT(ShowConfig())); connect(library_, SIGNAL(TotalSongCountUpdated(int)), ui_.library_view, SLOT(TotalSongCountUpdated(int))); // Age filters QActionGroup* filter_age_group = new QActionGroup(this); filter_age_group->addAction(ui_.filter_age_all); filter_age_group->addAction(ui_.filter_age_today); filter_age_group->addAction(ui_.filter_age_week); filter_age_group->addAction(ui_.filter_age_month); filter_age_group->addAction(ui_.filter_age_three_months); filter_age_group->addAction(ui_.filter_age_year); filter_age_group->setExclusive(true); QSignalMapper* filter_age_mapper = new QSignalMapper(this); filter_age_mapper->setMapping(ui_.filter_age_all, -1); filter_age_mapper->setMapping(ui_.filter_age_today, 60*60*24); filter_age_mapper->setMapping(ui_.filter_age_week, 60*60*24*7); filter_age_mapper->setMapping(ui_.filter_age_month, 60*60*24*30); filter_age_mapper->setMapping(ui_.filter_age_three_months, 60*60*24*30*3); filter_age_mapper->setMapping(ui_.filter_age_year, 60*60*24*365); connect(ui_.filter_age_all, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); connect(ui_.filter_age_today, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); connect(ui_.filter_age_week, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); connect(ui_.filter_age_month, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); connect(ui_.filter_age_three_months, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); connect(ui_.filter_age_year, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); connect(filter_age_mapper, SIGNAL(mapped(int)), library_, SLOT(SetFilterAge(int))); connect(ui_.library_filter_clear, SIGNAL(clicked()), SLOT(ClearLibraryFilter())); // Library config menu QMenu* library_menu = new QMenu(this); library_menu->addActions(filter_age_group->actions()); library_menu->addSeparator(); library_menu->addAction("Configure library...", library_, SLOT(ShowConfig())); ui_.library_options->setMenu(library_menu); // Tray icon QMenu* tray_menu = new QMenu(this); tray_menu->addAction(ui_.action_previous_track); tray_menu->addAction(ui_.action_play_pause); tray_menu->addAction(ui_.action_stop); tray_menu->addAction(ui_.action_next_track); tray_menu->addSeparator(); tray_menu->addAction(ui_.action_quit); tray_icon_->setContextMenu(tray_menu); connect(tray_icon_, SIGNAL(WheelEvent(int)), SLOT(VolumeWheelEvent(int))); connect(tray_icon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SLOT(TrayClicked(QSystemTrayIcon::ActivationReason))); // Analyzer ui_.analyzer->set_engine(player_->GetEngine()); // Load theme QFile stylesheet(":mainwindow.css"); if (!stylesheet.open(QIODevice::ReadOnly)) { qWarning("Could not open stylesheet"); } else { setStyleSheet(stylesheet.readAll()); } // Load settings QSettings settings; settings.beginGroup(kSettingsGroup); restoreGeometry(settings.value("geometry").toByteArray()); if (!restoreState(settings.value("state").toByteArray(), kStateVersion)) { tabifyDockWidget(ui_.files_dock, ui_.radio_dock); tabifyDockWidget(ui_.files_dock, ui_.library_dock); } ui_.file_view->SetPath(settings.value("file_path", QDir::homePath()).toString()); if (!settings.value("hidden", false).toBool()) show(); library_->StartThreads(); } MainWindow::~MainWindow() { SaveGeometry(); } void MainWindow::QueueFiles(const QList& urls) { QModelIndex playlist_index = playlist_->InsertPaths(urls); if (playlist_index.isValid() && player_->GetState() != Engine::Playing) player_->PlayAt(playlist_index.row()); } void MainWindow::ReportError(const QString& message) { QMessageBox::warning(this, "Error", message); } void MainWindow::MediaStopped() { ui_.action_stop->setEnabled(false); ui_.action_stop_after_this_track->setEnabled(false); ui_.action_play_pause->setIcon(QIcon(":media-playback-start.png")); ui_.action_play_pause->setText("Play"); } void MainWindow::MediaPaused() { ui_.action_stop->setEnabled(true); ui_.action_stop_after_this_track->setEnabled(true); ui_.action_play_pause->setIcon(QIcon(":media-playback-start.png")); ui_.action_play_pause->setText("Play"); } void MainWindow::MediaPlaying() { ui_.action_stop->setEnabled(true); ui_.action_stop_after_this_track->setEnabled(true); ui_.action_play_pause->setIcon(QIcon(":media-playback-pause.png")); ui_.action_play_pause->setText("Pause"); } void MainWindow::resizeEvent(QResizeEvent*) { SaveGeometry(); } void MainWindow::SaveGeometry() { QSettings settings; settings.beginGroup(kSettingsGroup); settings.setValue("geometry", saveGeometry()); settings.setValue("state", saveState(kStateVersion)); } void MainWindow::PlayIndex(const QModelIndex& index) { if (!index.isValid()) return; player_->PlayAt(index.row()); } void MainWindow::LibraryDoubleClick(const QModelIndex& index) { QModelIndex first_song = playlist_->InsertSongs(library_->GetChildSongs( library_sort_model_->mapToSource(index))); if (first_song.isValid() && player_->GetState() != Engine::Playing) player_->PlayAt(first_song.row()); } void MainWindow::VolumeWheelEvent(int delta) { ui_.volume->setValue(ui_.volume->value() + delta / 20); } void MainWindow::TrayClicked(QSystemTrayIcon::ActivationReason reason) { switch (reason) { case QSystemTrayIcon::DoubleClick: case QSystemTrayIcon::Trigger: SetHiddenInTray(isVisible()); break; case QSystemTrayIcon::MiddleClick: player_->PlayPause(); break; default: break; } } void MainWindow::StopAfterCurrent() { playlist_->StopAfter(playlist_->current_item()); } void MainWindow::closeEvent(QCloseEvent* event) { event->ignore(); SetHiddenInTray(true); } void MainWindow::SetHiddenInTray(bool hidden) { QSettings settings; settings.beginGroup(kSettingsGroup); settings.setValue("hidden", hidden); if (hidden) hide(); else show(); } void MainWindow::ClearLibraryFilter() { ui_.library_filter->clear(); ui_.library_filter->setFocus(); } void MainWindow::FilePathChanged(const QString& path) { QSettings settings; settings.beginGroup(kSettingsGroup); settings.setValue("file_path", path); }