/* * QMPDClient - An MPD client written in Qt 4. * Copyright (C) 2005-2007 Håvard Tautra Knutsen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "aboutdialog.h" #include "config.h" #include "directorypanel.h" #include "iconmanager.h" #include "librarypanel.h" #include "mainwindow.h" #include "mpd.h" #include "mpdcache.h" #include "mpdconnection.h" #include "mpdsonglist.h" #include "mpdstats.h" #include "playlistpanel.h" #include "playlistspanel.h" #include "preferencesdialog.h" #include "radiopanel.h" #include "richtext.h" #include "serverinfo.h" #include "shortcuts.h" #include "trayicon.h" #include #include #include #include #include #include MainWindow::MainWindow() : QMainWindow(0), m_config(Config::instance()), m_cache(MPDCache::instance()), m_connection(MPDConnection::instance()), m_mpd(MPD::instance()) { Q_ASSERT(m_cache); Q_ASSERT(m_config); Q_ASSERT(m_connection); Q_ASSERT(m_mpd); setupUi(this); // Status bar m_statsLabel = new QLabel; m_progressBar = new QProgressBar; m_progressBar->hide(); m_progressBar->setMaximumWidth(100); m_progressBar->setMaximumHeight(m_statsLabel->minimumSizeHint().height()); statusBar()->addPermanentWidget(m_progressBar); statusBar()->addPermanentWidget(m_statsLabel); // Show program name and version statusBar()->showMessage(NAMEVER); setStats(MPDStats()); // Ideal style vertical tabbars leftBar->link(leftStack, splitter); rightBar->link(rightStack, splitter); m_playlistTab = leftBar->addPanel(new PlaylistPanel, true); m_libraryTab = rightBar->addPanel(new LibraryPanel); m_directoriesTab = rightBar->addPanel(new DirectoryPanel); m_radioTab = rightBar->addPanel(new RadioPanel); m_playlistsTab = rightBar->addPanel(new PlaylistsPanel); // For icon changes m_radioTab->setObjectName("radioTab"); m_libraryTab->setObjectName("libraryTab"); m_playlistTab->setObjectName("playlistTab"); m_playlistsTab->setObjectName("playlistsTab"); m_directoriesTab->setObjectName("directoriesTab"); // Signals and slots connect(m_connection, SIGNAL(disconnected(const QString &)), this, SLOT(disconnected(const QString &))); connect(m_mpd, SIGNAL(statsUpdated(const MPDStats &)), this, SLOT(setStats(const MPDStats &))); connect(m_mpd, SIGNAL(playingSongUpdated(const MPDSong &)), this, SLOT(setSong(const MPDSong &))); connect(m_cache, SIGNAL(updateStart(int, const QString &)), this, SLOT(updateStart(int, const QString &))); connect(m_cache, SIGNAL(updateProgress(int)), this, SLOT(updateProgress(int))); connect(m_cache, SIGNAL(updateDone()), this, SLOT(updateDone())); // Menu action signals connect(disconnectMenu, SIGNAL(triggered()), m_connection, SLOT(disconnectFromMPD())); connect(rescanMenu, SIGNAL(triggered()), m_cache, SLOT(rescan())); connect(aboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt())); connect(quitMenu, SIGNAL(triggered()), qApp, SLOT(quit())); // Config signals connect(m_config, SIGNAL(serverListChanged(const QList &)), this, SLOT(serverListChanged(const QList &))); connect(m_config, SIGNAL(trayIconChanged(bool)), this, SLOT(trayIconChanged(bool))); // Shortcut keys m_hideKey = new QShortcut(Qt::Key_Escape, this, SLOT(showHide())); // Escape minimizes to tray m_hideKey->setObjectName("minimizeToTrayKey"); // Tray icon m_trayIcon = new TrayIcon(this); if (m_config->trayIconEnabled()) m_trayIcon->show(); connect(m_trayIcon, SIGNAL(clicked()), this, SLOT(showHide())); // Restore state serverListChanged(m_config->servers()); splitter->restore(m_config->mainSplitterSizes()); resize(m_config->windowSize()); if (!m_trayIcon->isVisible() || !m_config->trayIconEnabled() || !m_config->startHidden()) show(); } void MainWindow::updateTranslation() { retranslateUi(this); setSong(m_song); // Sets window title Q_ASSERT(m_playlistTab); Q_ASSERT(m_libraryTab); Q_ASSERT(m_directoriesTab); Q_ASSERT(m_radioTab); Q_ASSERT(m_playlistsTab); Q_ASSERT(m_hideKey); m_playlistTab->setText(tr("&Playlist")); m_libraryTab->setText(tr("&Library")); m_directoriesTab->setText(tr("&Directories")); m_radioTab->setText(tr("&Internet Radio")); m_playlistsTab->setText(tr("Pla&ylists")); m_hideKey->setWhatsThis(tr("Minimize to tray")); setStats(m_stats); } // Auto connected slots void MainWindow::on_about_triggered() { new AboutDialog(this); } void MainWindow::on_splitter_splitterMoved(int, int) { Q_ASSERT(m_config); m_config->setMainSplitterSizes(splitter->saveState()); } void MainWindow::on_preferencesMenu_triggered() { new PreferencesDialog(this); } // User defined slots void MainWindow::closeEvent(QCloseEvent *e) { Q_ASSERT(m_config); Q_ASSERT(m_trayIcon); if (m_trayIcon->isVisible() && m_config->trayIconEnabled() && m_config->minimizeToTray()) { e->ignore(); showHide(); return; } e->accept(); qApp->quit(); } void MainWindow::connectToMPD() { QObject *origin = sender(); if (!origin) return; Q_ASSERT(m_config); Q_ASSERT(m_connection); QAction *action = qobject_cast(origin); m_connection->connectToMPD(m_config->server(action->text())); } void MainWindow::disconnected(const QString &error) { Q_ASSERT(m_progressBar); if (!error.isEmpty()) { statusBar()->showMessage(QString(" %1: %2 ").arg(tr("Error")).arg(error)); Q_ASSERT(m_trayIcon); m_trayIcon->showMessage(tr("Error"), error, QSystemTrayIcon::Critical, 5000); } m_progressBar->reset(); } void MainWindow::resizeEvent(QResizeEvent *e) { Q_ASSERT(m_config); m_config->setWindowSize(e->size()); } void MainWindow::serverListChanged(const QList &sil) { while (!m_actions.isEmpty()) delete m_actions.takeLast(); foreach(ServerInfo si, sil) { QAction *a = connectMenu->addAction(IconManager::icon("server"), si.name(), this, SLOT(connectToMPD())); if (m_actions.isEmpty()) { a->setParent(this); a->setObjectName("connectMenu"); a->setWhatsThis("Connect to first server"); a->setShortcut(tr("Ctrl+C")); // Force shortcut service to reload action list Shortcuts *s = Shortcuts::instance(); if (s) s->updateTranslation(); } else a->setObjectName("connectOthers"); m_actions << a; } } void MainWindow::setSong(const MPDSong &s) { m_song = s; QString windowTitle = NAMEVER; if (!s.isNull()) { int desktopWidth = QApplication::desktop()->width(); QString title = elideRichText("", s.title(), "", desktopWidth / 2); QString artist = elideRichText("", s.artist(), "", desktopWidth / 4); windowTitle = qApp->applicationName(); if (!artist.isEmpty()) windowTitle += " - " + artist; windowTitle += " - " + title; } setWindowTitle(windowTitle); setWindowIconText(windowTitle); } void MainWindow::setStats(const MPDStats &stats) { Q_ASSERT(m_statsLabel); unsigned long secs = stats.dbPlayTime(); int day = secs / (60 * 60 * 24); secs -= day * 60 * 60 * 24; int hour = secs / (60 * 60); secs -= hour * 60 * 60; int min = secs / 60; m_statsLabel->setText(QString(" %1 %2, %3 %4, %5 %6. (%7 %8 %9 %10 %11 %12) ") .arg(stats.numberOfArtists()) .arg(tr("artists")) .arg(stats.numberOfAlbums()) .arg(tr("albums")) .arg(stats.numberOfSongs()) .arg(tr("songs")) .arg(day) .arg(tr("days")) .arg(hour) .arg(tr("hours")) .arg(min) .arg(tr("minutes"))); m_stats = stats; } void MainWindow::showHide() { Q_ASSERT(m_config); Q_ASSERT(m_trayIcon); if (m_config->trayIconEnabled() && m_config->minimizeToTray() && m_trayIcon->isVisible()) isVisible() ? hide() : showNormal(); } void MainWindow::trayIconChanged(bool e) { Q_ASSERT(m_trayIcon); m_trayIcon->setVisible(e); } void MainWindow::updateStart(int max, const QString &msg) { Q_ASSERT(m_progressBar); m_progressBar->setRange(0, max); m_progressBar->setValue(0); m_progressBar->show(); statusBar()->showMessage(msg); } void MainWindow::updateProgress(int at) { Q_ASSERT(m_progressBar); m_progressBar->setValue(at); } void MainWindow::updateDone() { Q_ASSERT(m_connection); Q_ASSERT(m_progressBar); m_progressBar->setValue(m_progressBar->maximum()); m_progressBar->hide(); if (m_connection->isConnected()) statusBar()->showMessage(tr("Done"), 2000); else statusBar()->clearMessage(); }