aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/General/mpris/mpris2/root2object.cpp2
-rw-r--r--src/qmmp/decoder.cpp166
-rw-r--r--src/qmmp/decoder.h8
-rw-r--r--src/qmmp/metadatamanager.cpp6
-rw-r--r--src/qmmp/output.cpp10
-rw-r--r--src/qmmp/plugincache.cpp125
-rw-r--r--src/qmmp/plugincache.h57
-rw-r--r--src/qmmp/qmmp.pro6
-rw-r--r--src/qmmpui/aboutdialog.cpp2
-rw-r--r--src/qmmpui/configdialog.cpp2
10 files changed, 280 insertions, 104 deletions
diff --git a/src/plugins/General/mpris/mpris2/root2object.cpp b/src/plugins/General/mpris/mpris2/root2object.cpp
index 5bf47e31f..126a81391 100644
--- a/src/plugins/General/mpris/mpris2/root2object.cpp
+++ b/src/plugins/General/mpris/mpris2/root2object.cpp
@@ -64,7 +64,7 @@ QString Root2Object::identity() const
QStringList Root2Object::supportedMimeTypes() const
{
QStringList mimeTypes;
- foreach(DecoderFactory *factory, *Decoder::factories())
+ foreach(DecoderFactory *factory, Decoder::factories())
mimeTypes << factory->properties().contentTypes;
foreach(EngineFactory *factory, *AbstractEngine::factories())
mimeTypes << factory->properties().contentTypes;
diff --git a/src/qmmp/decoder.cpp b/src/qmmp/decoder.cpp
index 2c6b9a469..1f0c1d4c4 100644
--- a/src/qmmp/decoder.cpp
+++ b/src/qmmp/decoder.cpp
@@ -10,10 +10,7 @@
#include <QSettings>
#include <QIODevice>
#include <math.h>
-
-#include "effect.h"
-#include "effectfactory.h"
-
+#include "plugincache.h"
#include "buffer.h"
#include "output.h"
#include "visual.h"
@@ -85,82 +82,60 @@ QMap<Qmmp::MetaData, QString> Decoder::takeMetaData()
}
// static methods
-QList<DecoderFactory*> *Decoder::m_factories = 0;
-QList<DecoderFactory*> *Decoder::m_disabledFactories = 0;
+QStringList Decoder::m_disabledNames;
DecoderFactory *Decoder::m_lastFactory = 0;
-QHash <DecoderFactory*, QString> *Decoder::m_files = 0;
+QList<PluginCache*> *Decoder::m_cache = 0;
-//sort factories by priority
-static bool _decoderLessComparator(DecoderFactory* f1, DecoderFactory* f2)
+//sort cache items by priority
+/*static bool _decoderLessComparator(DecoderFactory* f1, DecoderFactory* f2)
{
return f1->properties().priority < f2->properties().priority;
-}
+}*/
void Decoder::checkFactories()
{
- if (!m_factories)
- {
- QSettings settings (Qmmp::configFile(), QSettings::IniFormat);
- QStringList disabledNames = settings.value("Decoder/disabled_plugins").toStringList ();
-
- m_factories = new QList<DecoderFactory *>;
- m_disabledFactories = new QList<DecoderFactory *>;
- m_files = new QHash <DecoderFactory*, QString>;
+ if (m_cache)
+ return;
- QDir pluginsDir (Qmmp::pluginsPath());
- pluginsDir.cd("Input");
- foreach (QString fileName, pluginsDir.entryList(QDir::Files))
- {
- QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
- QObject *plugin = loader.instance();
- if (loader.isLoaded())
- qDebug("Decoder: loaded plugin %s", qPrintable(fileName));
- else
- qWarning("Decoder: %s", qPrintable(loader.errorString ()));
- DecoderFactory *factory = 0;
-
- if (plugin)
- factory = qobject_cast<DecoderFactory *>(plugin);
-
- if (factory)
- {
- m_factories->append(factory);
- m_files->insert(factory, pluginsDir.absoluteFilePath(fileName));
- qApp->installTranslator(factory->createTranslator(qApp));
- if(disabledNames.contains(factory->properties().shortName))
- m_disabledFactories->append(factory);
- }
- }
- //remove physically deleted plugins from disabled list
- QStringList names;
- foreach (DecoderFactory *factory, *m_factories)
- {
- names.append(factory->properties().shortName);
- }
- foreach (QString name, disabledNames)
+ m_cache = new QList<PluginCache*>;
+ QSettings settings (Qmmp::configFile(), QSettings::IniFormat);
+ QDir pluginsDir (Qmmp::pluginsPath());
+ pluginsDir.cd("Input");
+ foreach (QString fileName, pluginsDir.entryList(QDir::Files))
+ {
+ PluginCache *item = new PluginCache(pluginsDir.absoluteFilePath(fileName), &settings);
+ if(item->hasError())
{
- if (!names.contains(name))
- disabledNames.removeAll(name);
+ delete item;
+ continue;
}
- settings.setValue("Decoder/disabled_plugins",disabledNames);
- qSort(m_factories->begin(), m_factories->end(), _decoderLessComparator);
+ m_cache->append(item);
}
+ m_disabledNames = settings.value("Decoder/disabled_plugins").toStringList();
}
QString Decoder::file(DecoderFactory *factory)
{
checkFactories();
- return m_files->value(factory);
+ foreach(PluginCache *item, *m_cache)
+ {
+ if(item->shortName() == factory->properties().shortName)
+ return item->file();
+ }
+ return QString();
}
QStringList Decoder::protocols()
{
checkFactories();
QStringList protocolsList;
- foreach(DecoderFactory *f, *m_factories)
+
+ foreach (PluginCache *item, *m_cache)
{
- if(isEnabled(f))
- protocolsList << f->properties().protocols;
+ if(m_disabledNames.contains(item->shortName()))
+ continue;
+ if(item->decoderFactory())
+ protocolsList << item->decoderFactory()->properties().protocols;
}
protocolsList.removeDuplicates();
return protocolsList;
@@ -190,22 +165,33 @@ DecoderFactory *Decoder::findByPath(const QString& source, bool useContent)
return fact;
}
- foreach(DecoderFactory *fact, *m_factories)
+ foreach(PluginCache *item, *m_cache)
{
- if(fact->properties().noInput && !fact->properties().protocols.contains("file"))
+ if(m_disabledNames.contains(item->shortName()))
+ continue;
+
+ fact = item->decoderFactory();
+
+ if(fact && fact->properties().noInput && !fact->properties().protocols.contains("file"))
continue;
- if (isEnabled(fact) && fact->canDecode(&buffer))
+ if (fact->canDecode(&buffer))
{
+ m_lastFactory = fact;
return fact;
}
}
+ fact = 0;
}
- if (fact && fact->supports(source) && isEnabled(fact)) //try last factory
+ if (fact && isEnabled(fact) && fact->supports(source)) //try last factory
return fact;
- foreach(fact, *m_factories)
+
+ foreach (PluginCache *item, *m_cache)
{
- if (fact->supports(source) && isEnabled(fact))
+ if(m_disabledNames.contains(item->shortName()))
+ continue;
+ DecoderFactory *fact = item->decoderFactory();
+ if(fact && fact->supports(source))
{
m_lastFactory = fact;
return fact;
@@ -219,11 +205,12 @@ DecoderFactory *Decoder::findByMime(const QString& type)
if(type.isEmpty())
return 0;
checkFactories();
- DecoderFactory *fact;
- foreach(fact, *m_factories)
+ foreach (PluginCache *item, *m_cache)
{
- if (isEnabled(fact) && !fact->properties().noInput
- && fact->properties().contentTypes.contains(type))
+ if(m_disabledNames.contains(item->shortName()))
+ continue;
+ DecoderFactory *fact = item->decoderFactory();
+ if(fact && !fact->properties().noInput && fact->properties().contentTypes.contains(type))
return fact;
}
return 0;
@@ -232,12 +219,13 @@ DecoderFactory *Decoder::findByMime(const QString& type)
DecoderFactory *Decoder::findByContent(QIODevice *input)
{
checkFactories();
- foreach(DecoderFactory *fact, *m_factories)
+ foreach (PluginCache *item, *m_cache)
{
- if (isEnabled(fact) && !fact->properties().noInput && fact->canDecode(input))
- {
+ if(m_disabledNames.contains(item->shortName()))
+ continue;
+ DecoderFactory *fact = item->decoderFactory();
+ if(fact && !fact->properties().noInput && fact->canDecode(input))
return fact;
- }
}
return 0;
}
@@ -245,10 +233,13 @@ DecoderFactory *Decoder::findByContent(QIODevice *input)
DecoderFactory *Decoder::findByProtocol(const QString &p)
{
checkFactories();
- foreach(DecoderFactory *fact, *m_factories)
+ foreach (PluginCache *item, *m_cache)
{
- if (isEnabled(fact) && fact->properties().protocols.contains(p))
- return fact;
+ if(m_disabledNames.contains(item->shortName()))
+ continue;
+
+ if (item->decoderFactory() && item->decoderFactory()->properties().protocols.contains(p))
+ return item->decoderFactory();
}
return 0;
}
@@ -256,35 +247,36 @@ DecoderFactory *Decoder::findByProtocol(const QString &p)
void Decoder::setEnabled(DecoderFactory* factory, bool enable)
{
checkFactories();
- if (!m_factories->contains(factory))
+ if (!factories().contains(factory))
return;
if(enable == isEnabled(factory))
return;
if(enable)
- m_disabledFactories->removeAll(factory);
+ m_disabledNames.removeAll(factory->properties().shortName);
else
- m_disabledFactories->append(factory);
+ m_disabledNames.append(factory->properties().shortName);
- QStringList disabledNames;
- foreach(DecoderFactory *f, *m_disabledFactories)
- {
- disabledNames << f->properties().shortName;
- }
- disabledNames.removeDuplicates();
+ m_disabledNames.removeDuplicates();
QSettings settings (Qmmp::configFile(), QSettings::IniFormat);
- settings.setValue("Decoder/disabled_plugins", disabledNames);
+ settings.setValue("Decoder/disabled_plugins", m_disabledNames);
}
bool Decoder::isEnabled(DecoderFactory* factory)
{
checkFactories();
- return !m_disabledFactories->contains(factory);
+ return !m_disabledNames.contains(factory->properties().shortName);
}
-QList<DecoderFactory*> *Decoder::factories()
+QList<DecoderFactory *> Decoder::factories()
{
checkFactories();
- return m_factories;
+ QList<DecoderFactory *> list;
+ foreach (PluginCache *item, *m_cache)
+ {
+ if(item->decoderFactory())
+ list.append(item->decoderFactory());
+ }
+ return list;
}
diff --git a/src/qmmp/decoder.h b/src/qmmp/decoder.h
index cc0b2d4ee..2b250774d 100644
--- a/src/qmmp/decoder.h
+++ b/src/qmmp/decoder.h
@@ -20,6 +20,7 @@
class Decoder;
class DecoderFactory;
class QIODevice;
+class PluginCache;
/*! @brief The Decoder class provides the base interface class of audio decoders.
* @author Brad Hughes <bhughes@trolltech.com>
@@ -128,7 +129,7 @@ public:
/*!
* Returns a list of decoder factories.
*/
- static QList<DecoderFactory*> *factories();
+ static QList<DecoderFactory*> factories();
/*!
* Returns plugin file path.
* @param factory Decoder plugin factory.
@@ -162,10 +163,9 @@ protected:
private:
static void checkFactories();
- static QList<DecoderFactory*> *m_factories;
- static QList<DecoderFactory*> *m_disabledFactories;
static DecoderFactory *m_lastFactory;
- static QHash <DecoderFactory*, QString> *m_files;
+ static QList<PluginCache*> *m_cache;
+ static QStringList m_disabledNames;
AudioParameters m_parameters;
QIODevice *m_input;
bool m_hasMetaData;
diff --git a/src/qmmp/metadatamanager.cpp b/src/qmmp/metadatamanager.cpp
index 21bfef294..f0cc7d88c 100644
--- a/src/qmmp/metadatamanager.cpp
+++ b/src/qmmp/metadatamanager.cpp
@@ -69,7 +69,7 @@ QList <FileInfo *> MetaDataManager::createPlayList(const QString &fileName, bool
list << new FileInfo(fileName);
return list;
}
- foreach(fact, *Decoder::factories())
+ foreach(fact, Decoder::factories())
{
if(fact->properties().protocols.contains(scheme) && Decoder::isEnabled(fact))
return fact->createPlayList(fileName, useMetaData);
@@ -115,7 +115,7 @@ MetaDataModel* MetaDataManager::createMetaDataModel(const QString &path, QObject
QStringList MetaDataManager::filters() const
{
QStringList filters;
- foreach(DecoderFactory *fact, *Decoder::factories())
+ foreach(DecoderFactory *fact, Decoder::factories())
{
if (Decoder::isEnabled(fact) && !fact->properties().filters.isEmpty())
filters << fact->properties().description + " (" + fact->properties().filters.join(" ") + ")";
@@ -131,7 +131,7 @@ QStringList MetaDataManager::filters() const
QStringList MetaDataManager::nameFilters() const
{
QStringList filters;
- foreach(DecoderFactory *fact, *Decoder::factories())
+ foreach(DecoderFactory *fact, Decoder::factories())
{
if (Decoder::isEnabled(fact))
filters << fact->properties().filters;
diff --git a/src/qmmp/output.cpp b/src/qmmp/output.cpp
index 703696c88..fcc931a16 100644
--- a/src/qmmp/output.cpp
+++ b/src/qmmp/output.cpp
@@ -78,18 +78,18 @@ void Output::checkFactories()
QDir pluginsDir (Qmmp::pluginsPath());
pluginsDir.cd("Output");
- foreach ( QString fileName, pluginsDir.entryList ( QDir::Files ) )
+ foreach (QString fileName, pluginsDir.entryList (QDir::Files))
{
- QPluginLoader loader ( pluginsDir.absoluteFilePath ( fileName ) );
+ QPluginLoader loader (pluginsDir.absoluteFilePath (fileName));
QObject *plugin = loader.instance();
- if ( loader.isLoaded() )
- qDebug ( "Output: loaded plugin %s", qPrintable ( fileName ) );
+ if (loader.isLoaded())
+ qDebug ("Output: loaded plugin %s", qPrintable (fileName));
else
qWarning("Output: %s", qPrintable(loader.errorString ()));
OutputFactory *factory = 0;
if (plugin)
- factory = qobject_cast<OutputFactory *> ( plugin );
+ factory = qobject_cast<OutputFactory *> (plugin);
if (factory)
{
diff --git a/src/qmmp/plugincache.cpp b/src/qmmp/plugincache.cpp
new file mode 100644
index 000000000..4be3e6164
--- /dev/null
+++ b/src/qmmp/plugincache.cpp
@@ -0,0 +1,125 @@
+/***************************************************************************
+ * Copyright (C) 2013 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <QStringList>
+#include <QDateTime>
+#include <QFileInfo>
+#include <QPluginLoader>
+#include <QApplication>
+#include <QTranslator>
+#include "decoderfactory.h"
+#include "outputfactory.h"
+#include "plugincache.h"
+
+PluginCache::PluginCache(const QString &file, QSettings *settings)
+{
+ m_error = false;
+ m_instance = 0;
+ m_decoderFactory = 0;
+ bool update = false;
+ QFileInfo info(file);
+ m_path = info.QFileInfo::canonicalFilePath();
+
+ settings->beginGroup("PluginCache");
+ QString copy = m_path;
+ if(settings->allKeys().contains(copy.remove(0,1)))
+ {
+ QStringList values = settings->value(m_path).toStringList();
+ if(values.count() != 2)
+ update = true;
+ else
+ {
+ m_shortName = values.at(0);
+ update = (info.lastModified().toString(Qt::ISODate) != values.at(1));
+ }
+ }
+ else
+ update = true;
+
+
+ if(update)
+ {
+ if(DecoderFactory *factory = decoderFactory())
+ {
+ m_shortName = factory->properties().shortName;
+ }
+ /*else if(OutputFactory *factory = outputFactory())
+ {
+ m_shortName = factory->properties().shortName;
+ }*/
+ else
+ m_error = true;
+
+ if (!m_error)
+ {
+ QStringList values;
+ values << m_shortName;
+ values << info.lastModified().toString(Qt::ISODate);
+ settings->setValue(m_path, values);
+ qDebug("PluginCache: added to cache: %s", qPrintable(m_path));
+ }
+ }
+
+ settings->endGroup();
+}
+
+const QString PluginCache::shortName() const
+{
+ return m_shortName;
+}
+
+const QString PluginCache::file() const
+{
+ return m_path;
+}
+
+DecoderFactory *PluginCache::decoderFactory()
+{
+ if(!m_decoderFactory)
+ {
+ m_decoderFactory = qobject_cast<DecoderFactory *> (instance());
+ if(m_decoderFactory)
+ qApp->installTranslator(m_decoderFactory->createTranslator(qApp));
+ }
+ return m_decoderFactory;
+}
+
+bool PluginCache::hasError() const
+{
+ return m_error;
+}
+
+QObject *PluginCache::instance()
+{
+ if(m_error)
+ return 0;
+ if(m_instance)
+ return m_instance;
+ QPluginLoader loader(m_path);
+ m_instance = loader.instance();
+ if (loader.isLoaded())
+ qDebug("PluginCache: loaded plugin %s", qPrintable(QFileInfo(m_path).fileName()));
+ else
+ {
+ m_error = true;
+ qWarning("PluginCache: %s", qPrintable(loader.errorString ()));
+ }
+ return m_instance;
+}
diff --git a/src/qmmp/plugincache.h b/src/qmmp/plugincache.h
new file mode 100644
index 000000000..34aa4427f
--- /dev/null
+++ b/src/qmmp/plugincache.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * Copyright (C) 2013 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef PLUGINCACHE_H
+#define PLUGINCACHE_H
+
+#include <QString>
+#include <QObject>
+#include <QSettings>
+
+class DecoderFactory;
+
+/*! @internal
+ * @author Ilya Kotov <forkotov02@hotmail.ru>
+ */
+class PluginCache
+{
+public:
+ PluginCache(const QString &file, QSettings *settings);
+
+ const QString shortName() const;
+ const QString file() const;
+ bool hasError() const;
+
+
+ DecoderFactory *decoderFactory();
+
+ //OutputFactory *outputFactory();
+ //EngineFactory *engineFactory();
+
+private:
+ QObject *instance();
+ QString m_path;
+ QString m_shortName;
+ bool m_error;
+ QObject *m_instance;
+ DecoderFactory *m_decoderFactory;
+};
+
+#endif // PLUGINCACHE_H
diff --git a/src/qmmp/qmmp.pro b/src/qmmp/qmmp.pro
index 5b20b3d0c..41191d798 100644
--- a/src/qmmp/qmmp.pro
+++ b/src/qmmp/qmmp.pro
@@ -36,7 +36,8 @@ HEADERS += \
volume.h \
volumecontrol_p.h \
outputwriter_p.h \
- recycler_p.h
+ recycler_p.h \
+ plugincache.h
SOURCES += recycler.cpp \
decoder.cpp \
output.cpp \
@@ -64,7 +65,8 @@ SOURCES += recycler.cpp \
qmmpsettings.cpp \
eqsettings.cpp \
qmmpevents.cpp \
- outputwriter.cpp
+ outputwriter.cpp \
+ plugincache.cpp
FORMS +=
unix:TARGET = ../../lib/qmmp
win32:TARGET = ../../../bin/qmmp
diff --git a/src/qmmpui/aboutdialog.cpp b/src/qmmpui/aboutdialog.cpp
index ef79034e4..c464ae5f2 100644
--- a/src/qmmpui/aboutdialog.cpp
+++ b/src/qmmpui/aboutdialog.cpp
@@ -75,7 +75,7 @@ QString AboutDialog::loadAbout()
text.append("<h5>"+tr("Input plugins:")+"</h5>");
text.append("<ul type=\"square\">");
- foreach(DecoderFactory *fact, *Decoder::factories())
+ foreach(DecoderFactory *fact, Decoder::factories())
{
text.append("<li>");
text.append(fact->properties().name);
diff --git a/src/qmmpui/configdialog.cpp b/src/qmmpui/configdialog.cpp
index dc7e92977..e98e09b7d 100644
--- a/src/qmmpui/configdialog.cpp
+++ b/src/qmmpui/configdialog.cpp
@@ -182,7 +182,7 @@ void ConfigDialog::loadPluginsInfo()
load input plugins information
*/
item = new QTreeWidgetItem (m_ui->treeWidget, QStringList() << tr("Decoders"));
- foreach(DecoderFactory *factory, *Decoder::factories())
+ foreach(DecoderFactory *factory, Decoder::factories())
{
new PluginItem (item, factory, Decoder::file(factory));
}