add more spacing
[personal-kdebase.git] / runtime / phonon / platform_kde / kdeplatformplugin.cpp
blobeaf99ce92edc69e339191341b0572d7cbfd1333d
1 /* This file is part of the KDE project
2 Copyright (C) 2007-2008 Matthias Kretz <kretz@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
20 #include "kdeplatformplugin.h"
21 #include "kiomediastream.h"
23 #include <QtCore/QDir>
24 #include <QtCore/QFile>
25 #include <QtCore/QtPlugin>
26 #include <QtCore/QCoreApplication>
28 #include <kaboutdata.h>
29 #include <kdebug.h>
30 #include <kcomponentdata.h>
31 #include <kglobal.h>
32 #include <kicon.h>
33 #include <klibloader.h>
34 #include <klocale.h>
35 #include <kmessagebox.h>
36 #include <kmimetype.h>
37 #include <knotification.h>
38 #include <kservice.h>
39 #include <kservicetypetrader.h>
40 #include <kconfiggroup.h>
41 #include <kstandarddirs.h>
42 #include "devicelisting.h"
44 typedef QPair<QByteArray, QString> PhononDeviceAccess;
45 typedef QList<PhononDeviceAccess> PhononDeviceAccessList;
46 #ifndef KDE_USE_FINAL
47 Q_DECLARE_METATYPE(PhononDeviceAccessList)
48 #endif
49 namespace Phonon
52 K_GLOBAL_STATIC_WITH_ARGS(KComponentData, mainComponentData, (QCoreApplication::applicationName().isEmpty() ? "Qt Application" : QCoreApplication::applicationName().toUtf8()))
53 K_GLOBAL_STATIC_WITH_ARGS(KComponentData, phononComponentData, ("phonon"))
55 static void ensureMainComponentData()
57 if (!KGlobal::hasMainComponent()) {
58 // a pure Qt application does not have a KComponentData object,
59 // we'll give it one.
60 *mainComponentData;
61 qAddPostRoutine(mainComponentData.destroy);
62 Q_ASSERT(KGlobal::hasMainComponent());
66 static const KComponentData &componentData()
68 ensureMainComponentData();
69 return *phononComponentData;
72 KdePlatformPlugin::KdePlatformPlugin()
73 : m_devList(0)
75 ensureMainComponentData();
76 KGlobal::locale()->insertCatalog(QLatin1String("phonon_kde"));
79 KdePlatformPlugin::~KdePlatformPlugin()
81 delete m_devList;
84 AbstractMediaStream *KdePlatformPlugin::createMediaStream(const QUrl &url, QObject *parent)
86 return new KioMediaStream(url, parent);
89 QIcon KdePlatformPlugin::icon(const QString &name) const
91 return KIcon(name);
94 void KdePlatformPlugin::notification(const char *notificationName, const QString &text,
95 const QStringList &actions, QObject *receiver,
96 const char *actionSlot) const
98 KNotification *notification = new KNotification(notificationName);
99 notification->setComponentData(componentData());
100 notification->setText(text);
101 //notification->setPixmap(...);
102 notification->addContext(QLatin1String("Application"), KGlobal::mainComponent().componentName());
103 if (!actions.isEmpty() && receiver && actionSlot) {
104 notification->setActions(actions);
105 QObject::connect(notification, SIGNAL(activated(unsigned int)), receiver, actionSlot);
107 notification->sendEvent();
110 QString KdePlatformPlugin::applicationName() const
112 ensureMainComponentData();
113 const KAboutData *ad = KGlobal::mainComponent().aboutData();
114 if (ad) {
115 const QString programName = ad->programName();
116 if (programName.isEmpty()) {
117 return KGlobal::mainComponent().componentName();
119 return programName;
121 return KGlobal::mainComponent().componentName();
124 #undef PHONON_LOAD_BACKEND_GLOBAL
126 QObject *KdePlatformPlugin::createBackend(KService::Ptr newService)
128 QString errorReason;
129 #ifdef PHONON_LOAD_BACKEND_GLOBAL
130 KLibFactory *factory = 0;
131 // This code is in here temporarily until NMM gets fixed.
132 // Currently the NMM backend will fail with undefined symbols if
133 // the backend is not loaded with global symbol resolution
134 QObject *backend = 0;
135 factory = KLibLoader::self()->factory(newService->library(), QLibrary::ExportExternalSymbolsHint);
136 if (!factory) {
137 errorReason = KLibLoader::self()->lastErrorMessage();
138 } else {
139 QObject *backend = factory->create<QObject>();
140 if (0 == backend) {
141 errorReason = i18n("create method returned 0");
144 #else
145 QObject *backend = newService->createInstance<QObject>(0, QVariantList(), &errorReason);
146 #endif
147 if (0 == backend) {
148 const QLatin1String suffix("/phonon_backend/");
149 const QStringList libFilter(newService->library() + QLatin1String(".*"));
150 foreach (QString libPath, QCoreApplication::libraryPaths()) {
151 libPath += suffix;
152 const QDir dir(libPath);
153 foreach (const QString &pluginName, dir.entryList(libFilter, QDir::Files)) {
154 QPluginLoader pluginLoader(libPath + pluginName);
155 backend = pluginLoader.instance();
156 if (backend) {
157 break;
160 if (backend) {
161 break;
165 if (0 == backend) {
166 kError(600) << "Can not create backend object from factory for " <<
167 newService->name() << ", " << newService->library() << ":\n" << errorReason;
169 KMessageBox::error(0,
170 i18n("<qt>Unable to use the <b>%1</b> Multimedia Backend:<br/>%2</qt>",
171 newService->name(), errorReason));
172 return 0;
175 kDebug() << "using backend: " << newService->name();
176 return backend;
179 QObject *KdePlatformPlugin::createBackend()
181 // Within this process, display the warning about missing backends
182 // only once.
183 static bool has_shown = false;
184 ensureMainComponentData();
185 const KService::List offers = KServiceTypeTrader::self()->query("PhononBackend",
186 "Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1");
187 if (offers.isEmpty()) {
188 if (!has_shown) {
189 #if defined(HAVE_KDE4_MULTIMEDIA)
190 KMessageBox::error(0, i18n("Unable to find a Multimedia Backend"));
191 #endif
192 has_shown = true;
194 return 0;
196 // Flag the warning as not shown, since if the next time the
197 // list of backends is suddenly empty again the user should be
198 // told.
199 has_shown = false;
201 KService::List::const_iterator it = offers.begin();
202 const KService::List::const_iterator end = offers.end();
203 while (it != end) {
204 QObject *backend = createBackend(*it);
205 if (backend) {
206 return backend;
208 ++it;
210 return 0;
213 QObject *KdePlatformPlugin::createBackend(const QString &library, const QString &version)
215 ensureMainComponentData();
216 QString additionalConstraints = QLatin1String(" and Library == '") + library + QLatin1Char('\'');
217 if (!version.isEmpty()) {
218 additionalConstraints += QLatin1String(" and [X-KDE-PhononBackendInfo-Version] == '")
219 + version + QLatin1Char('\'');
221 const KService::List offers = KServiceTypeTrader::self()->query(QLatin1String("PhononBackend"),
222 QString("Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1%1")
223 .arg(additionalConstraints));
224 if (offers.isEmpty()) {
225 KMessageBox::error(0, i18n("Unable to find the requested Multimedia Backend"));
226 return 0;
229 KService::List::const_iterator it = offers.begin();
230 const KService::List::const_iterator end = offers.end();
231 while (it != end) {
232 QObject *backend = createBackend(*it);
233 if (backend) {
234 return backend;
236 ++it;
238 return 0;
241 bool KdePlatformPlugin::isMimeTypeAvailable(const QString &mimeType) const
243 ensureMainComponentData();
244 const KService::List offers = KServiceTypeTrader::self()->query("PhononBackend",
245 "Type == 'Service' and [X-KDE-PhononBackendInfo-InterfaceVersion] == 1");
246 if (!offers.isEmpty()) {
247 return offers.first()->hasMimeType(KMimeType::mimeType(mimeType).data());
249 return false;
252 void KdePlatformPlugin::saveVolume(const QString &outputName, qreal volume)
254 ensureMainComponentData();
255 KConfigGroup config(KGlobal::config(), "Phonon::AudioOutput");
256 config.writeEntry(outputName + "_Volume", volume);
259 qreal KdePlatformPlugin::loadVolume(const QString &outputName) const
261 ensureMainComponentData();
262 KConfigGroup config(KGlobal::config(), "Phonon::AudioOutput");
263 return config.readEntry<qreal>(outputName + "_Volume", 1.0);
266 void KdePlatformPlugin::ensureDeviceListingObject() const
268 if (!m_devList) {
269 m_devList = new DeviceListing;
270 connect(m_devList, SIGNAL(objectDescriptionChanged(ObjectDescriptionType)),
271 SIGNAL(objectDescriptionChanged(ObjectDescriptionType)));
275 QList<int> KdePlatformPlugin::objectDescriptionIndexes(ObjectDescriptionType type) const
277 switch (type) {
278 case AudioOutputDeviceType:
279 case AudioCaptureDeviceType:
280 ensureDeviceListingObject();
281 return m_devList->objectDescriptionIndexes(type);
282 default:
283 return QList<int>();
287 QHash<QByteArray, QVariant> KdePlatformPlugin::objectDescriptionProperties(ObjectDescriptionType type, int index) const
289 switch (type) {
290 case AudioOutputDeviceType:
291 case AudioCaptureDeviceType:
292 ensureDeviceListingObject();
293 return m_devList->objectDescriptionProperties(type, index);
294 default:
295 return QHash<QByteArray, QVariant>();
299 QList<QPair<QByteArray, QString> > KdePlatformPlugin::deviceAccessListFor(const Phonon::AudioOutputDevice &deviceDesc) const
301 const QVariant &deviceAccessListVariant = deviceDesc.property("deviceAccessList");
302 if (deviceAccessListVariant.isValid()) {
303 return qvariant_cast<PhononDeviceAccessList>(deviceAccessListVariant);
305 PhononDeviceAccessList ret;
306 const QVariant &v = deviceDesc.property("driver");
307 if (v.isValid()) {
308 const QByteArray &driver = v.toByteArray();
309 const QStringList &deviceIds = deviceDesc.property("deviceIds").toStringList();
310 foreach (const QString &deviceId, deviceIds) {
311 ret << QPair<QByteArray, QString>(driver, deviceId);
314 return ret;
317 } // namespace Phonon
319 Q_EXPORT_PLUGIN2(phonon_platform_kde, Phonon::KdePlatformPlugin)
321 #include "kdeplatformplugin.moc"
322 // vim: sw=4 sts=4 et tw=100