diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/lib.pro | 7 | ||||
| -rw-r--r-- | lib/output.cpp | 95 | ||||
| -rw-r--r-- | lib/output.h | 15 | ||||
| -rw-r--r-- | lib/soundcore.cpp | 67 | ||||
| -rw-r--r-- | lib/soundcore.h | 20 | ||||
| -rw-r--r-- | lib/visual.cpp | 106 | ||||
| -rw-r--r-- | lib/visual.h | 21 | ||||
| -rw-r--r-- | lib/visualfactory.h | 50 |
8 files changed, 340 insertions, 41 deletions
diff --git a/lib/lib.pro b/lib/lib.pro index 54e3f0363..5c52041a2 100644 --- a/lib/lib.pro +++ b/lib/lib.pro @@ -17,7 +17,8 @@ HEADERS += recycler.h \ soundcore.h \ streamreader.h \ downloader.h \ - visual.h + visual.h \ + visualfactory.h SOURCES += recycler.cpp \ decoder.cpp \ output.cpp \ @@ -28,7 +29,7 @@ SOURCES += recycler.cpp \ streamreader.cpp \ downloader.cpp \ filetag.cpp \ - visual.cpp + visual.cpp TARGET = qmmp CONFIG += release \ @@ -53,7 +54,7 @@ unix { system($$LINE2) system($$LINE3) system($$LINE4) - QMAKE_CLEAN += ./config.h + QMAKE_CLEAN = ./config.h } target.path = $$LIB_DIR diff --git a/lib/output.cpp b/lib/output.cpp index fbbe1c0e4..94b68aa36 100644 --- a/lib/output.cpp +++ b/lib/output.cpp @@ -62,7 +62,7 @@ Output *Output::create ( QObject *parent ) Output *output = 0; checkFactories(); - if ( factories->isEmpty () ) + if (factories->isEmpty ()) { qDebug("Output: unable to find output plugins"); return output; @@ -76,28 +76,28 @@ Output *Output::create ( QObject *parent ) if (files.at(i).section('/',-1) == pluginFileName) j = i; } - OutputFactory *fact = factories->at ( j ); + OutputFactory *fact = factories->at (j); if ( fact ) { - output = fact->create ( parent ); + output = fact->create (parent); } switch ((int) output->volumeControl()) { case Output::Standard: - { - break; - } + { + break; + } case Output::Custom: - { - timer = new QTimer(output); - connect(timer, SIGNAL(timeout()), output, SLOT(checkVolume())); - timer->start(125); - break; - } + { + timer = new QTimer(output); + connect(timer, SIGNAL(timeout()), output, SLOT(checkVolume())); + timer->start(125); + break; + } case Output::Disabled: - { - break; - } + { + break; + } } return output; } @@ -122,7 +122,15 @@ Output::Output ( QObject* parent, VolumeType vt) : QThread (parent), r (stackSiz Output::~Output() -{} +{ + qDebug("Output::~Output()"); + Visual *visual = 0; + foreach(visual, m_vis_map.values ()) + { + visual->close(); + } + //m_vis_map.clear(); +} void Output::error ( const QString &e ) { @@ -135,6 +143,8 @@ void Output::addVisual ( Visual *v ) if (visuals.indexOf (v) == -1) { visuals.append (v); + v->setOutput(this); + qDebug("Output: added external visualization"); } } @@ -142,6 +152,39 @@ void Output::addVisual ( Visual *v ) void Output::removeVisual (Visual *v) { visuals.removeAll (v); + if (m_vis_map.key(v)) + { + VisualFactory *factory = m_vis_map.key(v); + m_vis_map.remove(factory); + //Visual::setEnabled(factory, FALSE); + } +} + +void Output::addVisual(VisualFactory *factory, QWidget *parent) +{ + if (m_vis_map.value(factory)) + return; + Visual::setEnabled(factory, TRUE); + Visual* visual = factory->create(parent); + visual->setWindowFlags(Qt::Window); + if (visual) + { + visual->setOutput(this); + qDebug("Output: added visual factory: %s", + qPrintable(factory->properties().name)); + m_vis_map.insert (factory, visual); + visual->show(); + } +} + +void Output::removeVisual(VisualFactory *factory) +{ + if (m_vis_map.value(factory)) + { + m_vis_map.value(factory)->close(); + m_vis_map.remove (factory); + } + Visual::setEnabled(factory, FALSE); } void Output::dispatchVisual ( Buffer *buffer, unsigned long written, @@ -150,7 +193,13 @@ void Output::dispatchVisual ( Buffer *buffer, unsigned long written, if ( ! buffer || !visuals.size()) return; Visual* visual = 0; - foreach (visual , visuals); + foreach (visual , visuals) //external + { + visual->mutex()->lock (); + visual->add ( buffer, written, chan, prec ); + visual->mutex()->unlock(); + } + foreach (visual , m_vis_map.values ()) //internal { visual->mutex()->lock (); visual->add ( buffer, written, chan, prec ); @@ -162,7 +211,13 @@ void Output::dispatchVisual ( Buffer *buffer, unsigned long written, void Output::clearVisuals() { Visual *visual = 0; - foreach (visual, visuals ); + foreach (visual, visuals ) + { + visual->mutex()->lock (); + visual->clear(); + visual->mutex()->unlock(); + } + foreach(visual, m_vis_map.values ()) { visual->mutex()->lock (); visual->clear(); @@ -172,7 +227,7 @@ void Output::clearVisuals() void Output::dispatch(OutputState::Type st) { - if(st == OutputState::Stopped) + if (st == OutputState::Stopped) clearVisuals(); emit stateChanged ( OutputState(st) ); } @@ -184,7 +239,7 @@ void Output::dispatch(long s, unsigned long w, int b, int f, int p, int c) void Output::dispatch ( const OutputState &st ) { - if(st.type() == OutputState::Stopped) + if (st.type() == OutputState::Stopped) clearVisuals(); emit stateChanged ( st ); } diff --git a/lib/output.h b/lib/output.h index c87bd2420..24bc9d3fb 100644 --- a/lib/output.h +++ b/lib/output.h @@ -17,13 +17,12 @@ class Output; #include <QIODevice> #include "visual.h" #include "outputfactory.h" +#include "visualfactory.h" #include "recycler.h" class QTimer; -class Visualization; - class OutputState { @@ -154,9 +153,6 @@ public: return &r; } - void addVisual(Visual*); - void removeVisual(Visual*); - QMutex *mutex() { return &mtx; @@ -167,6 +163,12 @@ public: return m_vol; }; + //visualization + void addVisual(Visual*); + void removeVisual(Visual*); + void addVisual(VisualFactory *factory, QWidget *parent); + void removeVisual(VisualFactory *factory); + // abstract virtual bool isInitialized() const = 0; virtual bool initialize() = 0; @@ -204,7 +206,8 @@ protected: private: QMutex mtx; Recycler r; - QList<Visual*> visuals; + QList<Visual*> visuals; //external visualization + QMap<VisualFactory*, Visual*> m_vis_map; //internal visualization VolumeType m_vol; }; diff --git a/lib/soundcore.cpp b/lib/soundcore.cpp index d5aa0435d..05ab4b7bd 100644 --- a/lib/soundcore.cpp +++ b/lib/soundcore.cpp @@ -28,9 +28,13 @@ #include "soundcore.h" + +SoundCore *SoundCore::m_instance = 0; + SoundCore::SoundCore(QObject *parent) : QObject(parent) { + m_instance = this; m_decoder = 0; m_output = 0; m_input = 0; @@ -40,6 +44,7 @@ SoundCore::SoundCore(QObject *parent) m_block = FALSE; m_preamp = 0; m_vis = 0; + m_parentWidget = 0; for (int i = 1; i < 10; ++i) m_bands[i] = 0; m_error = NoError; @@ -101,11 +106,17 @@ bool SoundCore::play(const QString &source) m_error = DecoderError; - if (m_vis) + Visual *visual = 0; + foreach(visual, m_visuals) + m_output->addVisual(visual); + + VisualFactory* factory; + foreach(factory, *Visual::visualFactories()) { - m_vis->setOutput(m_output); - m_output->addVisual(m_vis); + if(Visual::isEnabled(factory)) + m_output->addVisual(factory, m_parentWidget); } + m_source = source; if (source.left(4) != "http") return decode(); @@ -182,6 +193,12 @@ void SoundCore::stop() { qWarning("SoundCore: unable to create output"); } + VisualFactory* factory; + foreach(factory, *Visual::visualFactories()) + { + if(Visual::isEnabled(factory)) + m_output->addVisual(factory, m_parentWidget); + } connect(m_output, SIGNAL(stateChanged(const OutputState&)), SIGNAL(outputStateChanged(const OutputState&))); } @@ -291,7 +308,12 @@ void SoundCore::updateConfig() void SoundCore::addVisualization(Visual *visual) { - m_vis = visual; + if (m_visuals.indexOf (visual) == -1) + { + m_visuals.append(visual); + if(m_output) + m_output->addVisual(visual); + } } bool SoundCore::decode() @@ -331,3 +353,40 @@ bool SoundCore::decode() m_block = FALSE; return FALSE; } + +void SoundCore::showVisualization(QWidget *parent) +{ + if (!m_parentWidget) + { + m_parentWidget = parent; + if(!m_output) + return; + VisualFactory* factory; + foreach(factory, *Visual::visualFactories()) + { + if(Visual::isEnabled(factory)) + m_output->addVisual(factory, m_parentWidget); + } + } +} + +void SoundCore::addVisual(VisualFactory *factory, QWidget *parent) +{ + if(m_output) + m_output->addVisual(factory, parent); + else + Visual::setEnabled(factory, TRUE); +} + +void SoundCore::removeVisual(VisualFactory *factory) +{ + if(m_output) + m_output->removeVisual(factory); + else + Visual::setEnabled(factory, FALSE); +} + +SoundCore* SoundCore::instance() +{ + return m_instance; +} diff --git a/lib/soundcore.h b/lib/soundcore.h index 13e8b97c6..e2e8dd566 100644 --- a/lib/soundcore.h +++ b/lib/soundcore.h @@ -138,6 +138,23 @@ public: */ void addVisualization(Visual *visual); + /*! + * shows enabled visualization with parent widget \b parent + */ + void showVisualization(QWidget *parent); + + /*! + * adds visualization by factory \b factory + */ + void addVisual(VisualFactory *factory, QWidget *parent); + + /*! + * removes visualization by factory \b factory + */ + void removeVisual(VisualFactory *factory); + + static SoundCore* instance(); + signals: /*! @@ -175,7 +192,10 @@ private: int m_preamp; int m_bands[10]; Visual *m_vis; + QList <Visual*> m_visuals; QString m_source; + QWidget *m_parentWidget; + static SoundCore* m_instance; }; #endif diff --git a/lib/visual.cpp b/lib/visual.cpp index 8c03bd65d..ce5e8a982 100644 --- a/lib/visual.cpp +++ b/lib/visual.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2006 by Ilya Kotov * + * Copyright (C) 2007 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -18,14 +18,63 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include <QtGui> +#include <QObject> +#include <QList> +#include <QApplication> + +#include "visualfactory.h" +#include "constants.h" +#include "output.h" + #include "visual.h" -Visual::Visual() -{} +static QList<VisualFactory*> *factories = 0; +static QStringList files; + +static void checkFactories() +{ + if (! factories) + { + files.clear(); + factories = new QList<VisualFactory *>; + + QDir pluginsDir (qApp->applicationDirPath()); + pluginsDir.cdUp(); + pluginsDir.cd("./"LIB_DIR"/qmmp/Visual"); + foreach (QString fileName, pluginsDir.entryList(QDir::Files)) + { + QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); + QObject *plugin = loader.instance(); + if (loader.isLoaded()) + { + qDebug("Visual: plugin loaded - %s", qPrintable(fileName)); + } + VisualFactory *factory = 0; + if (plugin) + factory = qobject_cast<VisualFactory *>(plugin); + + if (factory) + { + factories->append(factory); + files << pluginsDir.absoluteFilePath(fileName); + } + } + } +} + + +Visual::Visual(QWidget *parent) : QWidget(parent) +{ + setAttribute(Qt::WA_DeleteOnClose, TRUE); + setAttribute(Qt::WA_QuitOnClose, FALSE); +} Visual::~Visual() -{} +{ + qDebug("Visual::~Visual()"); +} Decoder *Visual::decoder() const { @@ -51,3 +100,52 @@ QMutex *Visual::mutex() { return &m_mutex; } + +QList<VisualFactory*> *Visual::visualFactories() +{ + checkFactories(); + return factories; +} + +QStringList Visual::visualFiles() +{ + checkFactories(); + return files; +} + +void Visual::setEnabled(VisualFactory* factory, bool enable) +{ + checkFactories(); + if(!factories->contains(factory)) + return; + + QString name = files.at(factories->indexOf(factory)).section('/',-1); + QSettings settings ( QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat ); + QStringList visList = settings.value("Visualization/plugin_files").toStringList(); + + if(enable) + { + if (!visList.contains(name)) + visList << name; + } + else + visList.removeAll(name); + settings.setValue("Visualization/plugin_files", visList); +} + +bool Visual::isEnabled(VisualFactory* factory) +{ + checkFactories(); + if(!factories->contains(factory)) + return FALSE; + QString name = files.at(factories->indexOf(factory)).section('/',-1); + QSettings settings ( QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat ); + QStringList visList = settings.value("Visualization/plugin_files").toStringList(); + return visList.contains(name); +} + +void Visual::closeEvent (QCloseEvent *event) +{ + m_output->removeVisual(this); + QWidget::closeEvent(event); +} diff --git a/lib/visual.h b/lib/visual.h index cc28efb34..ef663bb37 100644 --- a/lib/visual.h +++ b/lib/visual.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2006 by Ilya Kotov * + * Copyright (C) 2007 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * @@ -25,15 +25,20 @@ */ #include <QMutex> +#include <QStringList> +#include <QWidget> +#include <QMap> class Buffer; class Decoder; class Output; +class VisualFactory; -class Visual +class Visual : public QWidget { + Q_OBJECT public: - Visual(); + Visual(QWidget *parent); virtual ~Visual(); @@ -46,11 +51,19 @@ public: void setOutput(Output *output); QMutex *mutex(); + //static methods + static QList<VisualFactory*> *visualFactories(); + static QStringList visualFiles(); + static void setEnabled(VisualFactory* factory, bool enable = TRUE); + static bool isEnabled(VisualFactory* factory); + +protected: + virtual void closeEvent (QCloseEvent *); + private: Decoder *m_decoder; Output *m_output; QMutex m_mutex; - }; #endif diff --git a/lib/visualfactory.h b/lib/visualfactory.h new file mode 100644 index 000000000..6862032bb --- /dev/null +++ b/lib/visualfactory.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2007 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef VISUALFACTORY_H +#define VISUALFACTORY_H + +class QObject; +class QWidget; +class QTranslator; + +class Visual; + +struct VisualProperties +{ + QString name; + bool hasAbout; + bool hasSettings; +}; + +class VisualFactory +{ +public: + virtual ~VisualFactory() {} + virtual const VisualProperties properties() const = 0; + virtual Visual *create(QWidget *parent) = 0; + virtual void showSettings(QWidget *parent) = 0; + virtual void showAbout(QWidget *parent) = 0; + virtual QTranslator *createTranslator(QObject *parent) = 0; +}; + +Q_DECLARE_INTERFACE(VisualFactory, "VisualFactory/1.0"); + +#endif |
