/* * 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 "config.h" #include "debug.h" #include "dynamicplaylist.h" #include "iconmanager.h" #include "mainwindow.h" #include "mpd.h" #include "mpdconnection.h" #include "notifications.h" #include "qmpdclient.h" #include "reconnect.h" #include "shortcuts.h" #include #include #include #include #include QMPDClient::QMPDClient(int argc, char **argv) : QApplication(argc, argv), m_translator(0), m_qtTranslator(0) { setObjectName("qmpdclient"); setApplicationName("QMPDClient"); setOrganizationName("QMPDClient"); m_config = Config::instance(); m_mpd = MPD::instance(); // Create mainwin m_mainWindow = new MainWindow; connect(this, SIGNAL(lastWindowClosed()), this, SLOT(quit())); alternatingChanged(m_config->alternatingRowColors()); fontChanged(m_config->font()); iconSetChanged(); localeChanged(m_config->localeFile()); opaqueResizeChanged(m_config->opaqueResize()); connect(m_config, SIGNAL(alternatingChanged(bool)), this, SLOT(alternatingChanged(bool))); connect(m_config, SIGNAL(fontChanged(const QFont &)), this, SLOT(fontChanged(const QFont &))); connect(m_config, SIGNAL(iconSetChanged()), this, SLOT(iconSetChanged())); connect(m_config, SIGNAL(localeChanged(const QString &)), this, SLOT(localeChanged(const QString &))); connect(m_config, SIGNAL(opaqueResizeChanged(bool)), this, SLOT(opaqueResizeChanged(bool))); #if (QT_VERSION >= 0x040300) setStyleSheet(m_config->style()); connect(m_config, SIGNAL(styleChanged(const QString &)), this, SLOT(setStyleSheet(const QString &))); #endif // Services new DynamicPlaylist(this); new Notifications(this); new Reconnect(this); new Shortcuts(m_mainWindow); grabKeys(); // Install event filter to pick up wheel over tray icon installEventFilter(this); if (m_config->autoconnect()) // Autoconnect? MPDConnection::instance()->connectToMPD(m_config->servers().first()); } QMPDClient::~QMPDClient() { ungrabKeys(); delete m_mainWindow; delete m_config; delete m_mpd; } void QMPDClient::alternatingChanged(bool a) { Q_ASSERT(m_mainWindow); foreach(QAbstractItemView *view, m_mainWindow->findChildren(QString())) { if (!view->setProperty("alternatingRowColors", a)) qWarning("Couldn't set alternatingRowColors for view: %s", qPrintable(view->objectName())); } } void QMPDClient::fontChanged(const QFont &font) { Q_ASSERT(m_mainWindow); setFont(font); m_mainWindow->setFont(font); } void QMPDClient::iconSetChanged() { foreach(QPointer child, safeChildren()) { if (!child || child->objectName().isEmpty()) continue; bool icon = child->metaObject()->indexOfProperty("icon") > -1; bool pixmap = child->metaObject()->indexOfProperty("pixmap") > -1; if (icon || pixmap) { QString name = child->objectName(); name.remove(QRegExp("^m_")); name.remove(QRegExp("Button$")); name.remove(QRegExp("Action$")); name.remove(QRegExp("Menu$")); name.remove(QRegExp("Tab$")); name.remove(QRegExp("Item$")); name.remove(QRegExp("Label$")); name = name.toLower(); if (icon) { QIcon icn = IconManager::icon(name); if (icn.isNull()) continue; if (!child->setProperty("icon", icn)) { qWarning("Could not set icon for %s", qPrintable(child->objectName())); } } else if (pixmap) { QPixmap pix = IconManager::pixmap(name); if (pix.isNull()) continue; if (!child->setProperty("pixmap", pix)) { qWarning("Could not set pixmap for %s", qPrintable(child->objectName())); } } } } } void QMPDClient::localeChanged(const QString &locale) { Q_ASSERT(m_config); if (!m_config->translate() || !QFile::exists(locale)) { if (m_translator) delete m_translator; if (m_qtTranslator) delete m_qtTranslator; m_translator = 0; m_qtTranslator = 0; } else { if (!m_translator) m_translator = new QTranslator(this); if (!m_qtTranslator) m_qtTranslator = new QTranslator(this); if (m_translator->load(locale)) installTranslator(m_translator); // Get country code QString cc = locale.section('_', -1, -1).remove(".qm"); if (m_qtTranslator->load(QString("qt_") + cc, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) installTranslator(m_qtTranslator); } const QByteArray normalizedSignature = QMetaObject::normalizedSignature("updateTranslation()"); foreach(QPointer child, safeChildren()) { if (child && child->metaObject()->indexOfMethod(normalizedSignature) > -1) { if (!QMetaObject::invokeMethod(child, "updateTranslation")) qWarning("Could not invoke updateTranslation on '%s'", qPrintable(child->objectName())); } } } void QMPDClient::opaqueResizeChanged(bool a) { Q_ASSERT(m_mainWindow); foreach(QSplitter *splitter, m_mainWindow->findChildren(QString())) { if (!splitter->setProperty("opaqueResize", a)) qWarning("Could not set opaqueResize for splitter '%s'", qPrintable(splitter->objectName())); } } /* * This event filter detects wheelEvents over the tray icon. * If the object which recieves the wheelEvent has no parent it is * either the main window or the tray icon. So, if the wheelEvents * position is outside the mainwindow frame, it must be the tray icon. */ bool QMPDClient::eventFilter(QObject *watched, QEvent *event) { if (event->type() == QEvent::Wheel) { QWheelEvent *e = static_cast(event); Q_ASSERT(m_mainWindow); Q_ASSERT(m_mpd); if (!watched->parent() && !m_mainWindow->frameGeometry().contains(e->globalPos())) { // No parent, and outside mainwindow, should be trayicon. int numDegrees = e->delta() / 8; int numSteps = numDegrees / 15; if (e->orientation() == Qt::Vertical) { if (numSteps > 0) m_mpd->volumeUp(5*numSteps); else if (numSteps < 0) m_mpd->volumeDown(5*numSteps); return true; } } } return QApplication::eventFilter(watched, event); } QList > QMPDClient::safeChildren() { Q_ASSERT(m_mainWindow); // Guard against dangling pointers by using QPointer QList > safeChildren; foreach(QObject *child, m_mainWindow->findChildren(QString())) { safeChildren << QPointer(child); } safeChildren << QPointer(m_mainWindow); return safeChildren; } int g_debugLevel = 0; // Reference to global debug variable int main(int argc, char **argv) { for (int i=0; i