File indexing completed on 2024-04-28 16:01:47

0001 /*  This file is part of the KDE project
0002     Copyright (C) 2006-2008 Matthias Kretz <kretz@kde.org>
0003 
0004     This library is free software; you can redistribute it and/or
0005     modify it under the terms of the GNU Lesser General Public
0006     License as published by the Free Software Foundation; either
0007     version 2.1 of the License, or (at your option) version 3, or any
0008     later version accepted by the membership of KDE e.V. (or its
0009     successor approved by the membership of KDE e.V.), Nokia Corporation
0010     (or its successors, if any) and the KDE Free Qt Foundation, which shall
0011     act as a proxy defined in Section 6 of version 3 of the license.
0012 
0013     This library is distributed in the hope that it will be useful,
0014     but WITHOUT ANY WARRANTY; without even the implied warranty of
0015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016     Lesser General Public License for more details.
0017 
0018     You should have received a copy of the GNU Lesser General Public
0019     License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0020 
0021 */
0022 
0023 #include "globalconfig.h"
0024 #include "globalconfig_p.h"
0025 
0026 #include "factory_p.h"
0027 #include "phonondefs_p.h"
0028 #include "platformplugin.h"
0029 #include "backendinterface.h"
0030 #include "qsettingsgroup_p.h"
0031 #include "phononnamespace_p.h"
0032 #include "phononnamespace.h"
0033 #include "pulsesupport.h"
0034 
0035 #include <QList>
0036 #include <QVariant>
0037 
0038 namespace Phonon
0039 {
0040 
0041 GlobalConfigPrivate::GlobalConfigPrivate() : config(QLatin1String("kde.org"), QLatin1String("libphonon"))
0042 {
0043 }
0044 
0045 GlobalConfig::GlobalConfig()
0046     : k_ptr(new GlobalConfigPrivate)
0047 {
0048 }
0049 
0050 GlobalConfig::~GlobalConfig()
0051 {
0052     delete k_ptr;
0053 }
0054 
0055 enum WhatToFilter {
0056     FilterAdvancedDevices = 1,
0057     FilterHardwareDevices = 2,
0058     FilterUnavailableDevices = 4
0059 };
0060 
0061 static void filter(ObjectDescriptionType type, BackendInterface *backendIface, QList<int> *list, int whatToFilter)
0062 {
0063     QMutableListIterator<int> it(*list);
0064     while (it.hasNext()) {
0065         QHash<QByteArray, QVariant> properties;
0066         if (backendIface)
0067             properties = backendIface->objectDescriptionProperties(type, it.next());
0068         else
0069             properties = PulseSupport::getInstance()->objectDescriptionProperties(type, it.next());
0070         QVariant var;
0071         if (whatToFilter & FilterAdvancedDevices) {
0072             var = properties.value("isAdvanced");
0073             if (var.isValid() && var.toBool()) {
0074                 it.remove();
0075                 continue;
0076             }
0077         }
0078         if (whatToFilter & FilterHardwareDevices) {
0079             var = properties.value("isHardwareDevice");
0080             if (var.isValid() && var.toBool()) {
0081                 it.remove();
0082                 continue;
0083             }
0084         }
0085         if (whatToFilter & FilterUnavailableDevices) {
0086             var = properties.value("available");
0087             if (var.isValid() && !var.toBool()) {
0088                 it.remove();
0089                 continue;
0090             }
0091         }
0092     }
0093 }
0094 
0095 #ifndef QT_NO_PHONON_SETTINGSGROUP
0096 static QList<int> sortDevicesByCategoryPriority(const GlobalConfig *config, const QSettingsGroup *backendConfig, ObjectDescriptionType type, Category category, QList<int> &defaultList)
0097 {
0098     Q_ASSERT(config); Q_UNUSED(config);
0099     Q_ASSERT(backendConfig);
0100     Q_ASSERT(type == AudioOutputDeviceType);
0101 
0102     if (defaultList.size() <= 1) {
0103         // nothing to sort
0104         return defaultList;
0105     } else {
0106         // make entries unique
0107         QSet<int> seen;
0108         QMutableListIterator<int> it(defaultList);
0109         while (it.hasNext()) {
0110             if (seen.contains(it.next())) {
0111                 it.remove();
0112             } else {
0113                 seen.insert(it.value());
0114             }
0115         }
0116     }
0117 
0118     QList<int> deviceList;
0119     PulseSupport *pulse = PulseSupport::getInstance();
0120     if (pulse->isUsed()) {
0121         deviceList = pulse->objectIndexesByCategory(type, category);
0122     } else {
0123         QString categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(category));
0124         if (!backendConfig->hasKey(categoryKey)) {
0125             // no list in config for the given category
0126             categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(NoCategory));
0127             if (!backendConfig->hasKey(categoryKey)) {
0128                 // no list in config for NoCategory
0129                 return defaultList;
0130             }
0131         }
0132 
0133         //Now the list from d->config
0134         deviceList = backendConfig->value(categoryKey, QList<int>());
0135     }
0136 
0137     //if there are devices in d->config that the backend doesn't report, remove them from the list
0138     QMutableListIterator<int> i(deviceList);
0139     while (i.hasNext()) {
0140         if (0 == defaultList.removeAll(i.next())) {
0141             i.remove();
0142         }
0143     }
0144 
0145     //if the backend reports more devices that are not in d->config append them to the list
0146     deviceList += defaultList;
0147 
0148     return deviceList;
0149 }
0150 
0151 static QList<int> sortDevicesByCategoryPriority(const GlobalConfig *config, const QSettingsGroup *backendConfig, ObjectDescriptionType type, CaptureCategory category, QList<int> &defaultList)
0152 {
0153     Q_ASSERT(config); Q_UNUSED(config);
0154     Q_ASSERT(backendConfig);
0155     Q_ASSERT(type == AudioCaptureDeviceType || type == VideoCaptureDeviceType);
0156 
0157     if (defaultList.size() <= 1) {
0158         // nothing to sort
0159         return defaultList;
0160     } else {
0161         // make entries unique
0162         QSet<int> seen;
0163         QMutableListIterator<int> it(defaultList);
0164         while (it.hasNext()) {
0165             if (seen.contains(it.next())) {
0166                 it.remove();
0167             } else {
0168                 seen.insert(it.value());
0169             }
0170         }
0171     }
0172 
0173     QList<int> deviceList;
0174     PulseSupport *pulse = PulseSupport::getInstance();
0175     if (pulse->isUsed()) {
0176         deviceList = pulse->objectIndexesByCategory(type, category);
0177     } else {
0178         QString categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(category));
0179         if (!backendConfig->hasKey(categoryKey)) {
0180             // no list in config for the given category
0181             categoryKey = QLatin1String("Category_") + QString::number(static_cast<int>(NoCategory));
0182             if (!backendConfig->hasKey(categoryKey)) {
0183                 // no list in config for NoCategory
0184                 return defaultList;
0185             }
0186         }
0187 
0188         //Now the list from d->config
0189         deviceList = backendConfig->value(categoryKey, QList<int>());
0190     }
0191 
0192     //if there are devices in d->config that the backend doesn't report, remove them from the list
0193     QMutableListIterator<int> i(deviceList);
0194     while (i.hasNext()) {
0195         if (0 == defaultList.removeAll(i.next())) {
0196             i.remove();
0197         }
0198     }
0199 
0200     //if the backend reports more devices that are not in d->config append them to the list
0201     deviceList += defaultList;
0202 
0203     return deviceList;
0204 }
0205 
0206 bool GlobalConfig::hideAdvancedDevices() const
0207 {
0208     P_D(const GlobalConfig);
0209     //The devices need to be stored independently for every backend
0210     const QSettingsGroup generalGroup(&d->config, QLatin1String("General"));
0211     return generalGroup.value(QLatin1String("HideAdvancedDevices"), true);
0212 }
0213 
0214 void GlobalConfig::setHideAdvancedDevices(bool hide)
0215 {
0216     P_D(GlobalConfig);
0217     QSettingsGroup generalGroup(&d->config, QLatin1String("General"));
0218     generalGroup.setValue(QLatin1String("HideAdvancedDevices"), hide);
0219 }
0220 #endif // QT_NO_PHONON_SETTINGSGROUP
0221 
0222 static bool isHiddenAudioOutputDevice(const GlobalConfig *config, int i)
0223 {
0224     Q_ASSERT(config);
0225 
0226 #ifndef QT_NO_PHONON_SETTINGSGROUP
0227     if (!config->hideAdvancedDevices())
0228         return false;
0229 #endif // QT_NO_PHONON_SETTINGSGROUP
0230 
0231     AudioOutputDevice ad = AudioOutputDevice::fromIndex(i);
0232     const QVariant var = ad.property("isAdvanced");
0233     return (var.isValid() && var.toBool());
0234 }
0235 
0236 #ifndef PHONON_NO_AUDIOCAPTURE
0237 static bool isHiddenAudioCaptureDevice(const GlobalConfig *config, int i)
0238 {
0239     Q_ASSERT(config);
0240 
0241 #ifndef QT_NO_PHONON_SETTINGSGROUP
0242     if (!config->hideAdvancedDevices())
0243         return false;
0244 #endif // QT_NO_PHONON_SETTINGSGROUP
0245 
0246     AudioCaptureDevice ad = AudioCaptureDevice::fromIndex(i);
0247     const QVariant var = ad.property("isAdvanced");
0248     return (var.isValid() && var.toBool());
0249 }
0250 #endif
0251 
0252 #ifndef PHONON_NO_VIDEOCAPTURE
0253 static bool isHiddenVideoCaptureDevice(const GlobalConfig *config, int i)
0254 {
0255     Q_ASSERT(config);
0256 
0257 #ifndef QT_NO_PHONON_SETTINGSGROUP
0258     if (!config->hideAdvancedDevices())
0259         return false;
0260 #endif // QT_NO_PHONON_SETTINGSGROUP
0261 
0262     VideoCaptureDevice vd = VideoCaptureDevice::fromIndex(i);
0263     const QVariant var = vd.property("isAdvanced");
0264     return (var.isValid() && var.toBool());
0265 }
0266 #endif
0267 
0268 static QList<int> reindexList(const GlobalConfig *config, ObjectDescriptionType type, Category category, QList<int>newOrder)
0269 {
0270     Q_ASSERT(config);
0271     Q_ASSERT(type == AudioOutputDeviceType);
0272     Q_UNUSED(type);
0273 
0274     /*QString sb;
0275     sb = QString("(Size %1)").arg(currentList.size());
0276     foreach (int i, currentList)
0277     sb += QString("%1, ").arg(i);
0278     fprintf(stderr, "=== Reindex Current: %s\n", sb.toUtf8().constData());
0279     sb = QString("(Size %1)").arg(newOrder.size());
0280     foreach (int i, newOrder)
0281     sb += QString("%1, ").arg(i);
0282     fprintf(stderr, "=== Reindex Before : %s\n", sb.toUtf8().constData());*/
0283 
0284     int override = GlobalConfig::ShowUnavailableDevices | GlobalConfig::ShowAdvancedDevices;
0285     QList<int> currentList = config->audioOutputDeviceListFor(category, override);
0286 
0287 
0288     QList<int> newList;
0289 
0290     foreach (int i, newOrder) {
0291         int found = currentList.indexOf(i);
0292         if (found < 0) {
0293             // It's not in the list, so something is odd (e.g. client error). Ignore it.
0294             continue;
0295         }
0296 
0297         // Iterate through the list from this point onward. If there are hidden devices
0298         // immediately following, take them too.
0299         newList.append(currentList.takeAt(found));
0300 
0301         while (found < currentList.size()) {
0302             bool hidden = isHiddenAudioOutputDevice(config, currentList.at(found));
0303             if (!hidden)
0304                 break;
0305 
0306             newList.append(currentList.takeAt(found));
0307         }
0308     }
0309 
0310     // If there are any devices left in.. just tack them on the end.
0311     if (currentList.size() > 0)
0312         newList += currentList;
0313 
0314     /*sb = QString("(Size %1)").arg(newList.size());
0315     foreach (int i, newList)
0316     sb += QString("%1, ").arg(i);
0317     fprintf(stderr, "=== Reindex After  : %s\n", sb.toUtf8().constData());*/
0318     return newList;
0319 }
0320 
0321 static QList<int> reindexList(const GlobalConfig *config, ObjectDescriptionType type, CaptureCategory category, QList<int>newOrder)
0322 {
0323     Q_ASSERT(config);
0324     Q_ASSERT(type == AudioCaptureDeviceType || type == VideoCaptureDeviceType);
0325 
0326     QList<int> currentList;
0327     int override = GlobalConfig::ShowUnavailableDevices | GlobalConfig::ShowAdvancedDevices;
0328 
0329     switch (type) {
0330 #ifndef PHONON_NO_AUDIOCAPTURE
0331     case AudioCaptureDeviceType:
0332         currentList = config->audioCaptureDeviceListFor(category, override);
0333         break;
0334 #endif
0335 
0336 #ifndef PHONON_NO_VIDEOCAPTURE
0337     case VideoCaptureDeviceType:
0338         currentList = config->videoCaptureDeviceListFor(category, override);
0339         break;
0340 #endif
0341 
0342     default: ;
0343     }
0344 
0345     QList<int> newList;
0346 
0347     foreach (int i, newOrder) {
0348         int found = currentList.indexOf(i);
0349         if (found < 0) {
0350             // It's not in the list, so something is odd (e.g. client error). Ignore it.
0351             continue;
0352         }
0353 
0354         // Iterate through the list from this point onward. If there are hidden devices
0355         // immediately following, take them too.
0356         newList.append(currentList.takeAt(found));
0357 
0358         while (found < currentList.size()) {
0359             bool hidden = true;
0360 
0361             switch (type) {
0362 #ifndef PHONON_NO_AUDIOCAPTURE
0363             case AudioCaptureDeviceType:
0364                 hidden = isHiddenAudioCaptureDevice(config, currentList.at(found));
0365                 break;
0366 #endif
0367 
0368 #ifndef PHONON_NO_VIDEOCAPTURE
0369             case VideoCaptureDeviceType:
0370                 hidden = isHiddenVideoCaptureDevice(config, currentList.at(found));
0371                 break;
0372 #endif
0373 
0374             default: ;
0375             }
0376 
0377             if (!hidden)
0378                 break;
0379 
0380             newList.append(currentList.takeAt(found));
0381         }
0382     }
0383 
0384     // If there are any devices left in.. just tack them on the end.
0385     if (currentList.size() > 0)
0386         newList += currentList;
0387 
0388     return newList;
0389 }
0390 
0391 void GlobalConfig::setAudioOutputDeviceListFor(Category category, QList<int> order)
0392 {
0393     PulseSupport *pulse = PulseSupport::getInstance();
0394     if (pulse->isUsed()) {
0395         pulse->setOutputDevicePriorityForCategory(category, order);
0396         return;
0397     }
0398 
0399 #ifndef QT_NO_PHONON_SETTINGSGROUP
0400     P_D(GlobalConfig);
0401     QSettingsGroup backendConfig(&d->config, QLatin1String("AudioOutputDevice")); // + Factory::identifier());
0402 
0403     order = reindexList(this, AudioOutputDeviceType, category, order);
0404 
0405     const QList<int> noCategoryOrder = audioOutputDeviceListFor(NoCategory, ShowUnavailableDevices|ShowAdvancedDevices);
0406     if (category != NoCategory && order == noCategoryOrder) {
0407         backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category));
0408     } else {
0409         backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order);
0410     }
0411 #endif //QT_NO_PHONON_SETTINGSGROUP
0412 }
0413 
0414 QList<int> GlobalConfig::audioOutputDeviceListFor(Category category, int override) const
0415 {
0416     P_D(const GlobalConfig);
0417 
0418 #ifndef QT_NO_PHONON_SETTINGSGROUP
0419     const bool hide = ((override & AdvancedDevicesFromSettings)
0420             ? hideAdvancedDevices()
0421             : static_cast<bool>(override & HideAdvancedDevices));
0422 #else
0423     const bool hide = !((override & AdvancedDevicesFromSettings) && static_cast<bool>(override & HideAdvancedDevices));
0424 #endif
0425 
0426     QList<int> defaultList;
0427 
0428     PulseSupport *pulse = PulseSupport::getInstance();
0429     if (pulse->isUsed()) {
0430         defaultList = pulse->objectDescriptionIndexes(AudioOutputDeviceType);
0431         if (hide || (override & HideUnavailableDevices)) {
0432             filter(AudioOutputDeviceType, nullptr, &defaultList,
0433                     (hide ? FilterAdvancedDevices : 0)
0434                     | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0)
0435                     );
0436         }
0437     } else {
0438         BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend());
0439 
0440 #ifndef QT_NO_PHONON_PLATFORMPLUGIN
0441         if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) {
0442             // the platform plugin lists the audio devices for the platform
0443             // this list already is in default order (as defined by the platform plugin)
0444             defaultList = platformPlugin->objectDescriptionIndexes(AudioOutputDeviceType);
0445             if (hide) {
0446                 QMutableListIterator<int> it(defaultList);
0447                 while (it.hasNext()) {
0448                     AudioOutputDevice objDesc = AudioOutputDevice::fromIndex(it.next());
0449                     const QVariant var = objDesc.property("isAdvanced");
0450                     if (var.isValid() && var.toBool()) {
0451                         it.remove();
0452                     }
0453                 }
0454             }
0455         }
0456 #endif //QT_NO_PHONON_PLATFORMPLUGIN
0457 
0458         // lookup the available devices directly from the backend
0459         if (backendIface) {
0460             // this list already is in default order (as defined by the backend)
0461             QList<int> list = backendIface->objectDescriptionIndexes(AudioOutputDeviceType);
0462             if (hide || !defaultList.isEmpty() || (override & HideUnavailableDevices)) {
0463                 filter(AudioOutputDeviceType, backendIface, &list,
0464                         (hide ? FilterAdvancedDevices : 0)
0465                         // the platform plugin maybe already provided the hardware devices?
0466                         | (defaultList.isEmpty() ? 0 : FilterHardwareDevices)
0467                         | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0)
0468                         );
0469             }
0470             defaultList += list;
0471         }
0472     }
0473 
0474 #ifndef QT_NO_PHONON_SETTINGSGROUP
0475     const QSettingsGroup backendConfig(&d->config, QLatin1String("AudioOutputDevice")); // + Factory::identifier());
0476     return sortDevicesByCategoryPriority(this, &backendConfig, AudioOutputDeviceType, category, defaultList);
0477 #else //QT_NO_PHONON_SETTINGSGROUP
0478     return defaultList;
0479 #endif //QT_NO_PHONON_SETTINGSGROUP
0480 }
0481 
0482 
0483 int GlobalConfig::audioOutputDeviceFor(Category category, int override) const
0484 {
0485 #ifndef QT_NO_PHONON_SETTINGSGROUP
0486     QList<int> ret = audioOutputDeviceListFor(category, override);
0487     if (!ret.isEmpty())
0488         return ret.first();
0489 #endif //QT_NO_PHONON_SETTINGSGROUP
0490     return -1;
0491 }
0492 
0493 QHash<QByteArray, QVariant> GlobalConfig::audioOutputDeviceProperties(int index) const
0494 {
0495     return deviceProperties(AudioOutputDeviceType, index);
0496 }
0497 
0498 
0499 #ifndef PHONON_NO_AUDIOCAPTURE
0500 void GlobalConfig::setAudioCaptureDeviceListFor(CaptureCategory category, QList<int> order)
0501 {
0502 
0503     PulseSupport *pulse = PulseSupport::getInstance();
0504     if (pulse->isUsed()) {
0505         pulse->setCaptureDevicePriorityForCategory(category, order);
0506         return;
0507     }
0508 
0509 #ifndef QT_NO_PHONON_SETTINGSGROUP
0510     P_D(GlobalConfig);
0511     QSettingsGroup backendConfig(&d->config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier());
0512 
0513     order = reindexList(this, AudioCaptureDeviceType, category, order);
0514 
0515     const QList<int> noCategoryOrder = audioCaptureDeviceListFor(NoCaptureCategory, ShowUnavailableDevices|ShowAdvancedDevices);
0516     if (category != NoCaptureCategory && order == noCategoryOrder) {
0517         backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category));
0518     } else {
0519         backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order);
0520     }
0521 #endif //QT_NO_PHONON_SETTINGSGROUP
0522 }
0523 
0524 QList<int> GlobalConfig::audioCaptureDeviceListFor(CaptureCategory category, int override) const
0525 {
0526     P_D(const GlobalConfig);
0527 
0528 #ifndef QT_NO_PHONON_SETTINGSGROUP
0529     const bool hide = ((override & AdvancedDevicesFromSettings)
0530         ? hideAdvancedDevices()
0531         : static_cast<bool>(override & HideAdvancedDevices));
0532 #else
0533     const bool hide = !((override & AdvancedDevicesFromSettings) && static_cast<bool>(override & HideAdvancedDevices));
0534 #endif
0535 
0536     QList<int> defaultList;
0537 
0538     PulseSupport *pulse = PulseSupport::getInstance();
0539     if (pulse->isUsed()) {
0540         defaultList = pulse->objectDescriptionIndexes(AudioCaptureDeviceType);
0541         if (hide || (override & HideUnavailableDevices)) {
0542             filter(AudioCaptureDeviceType, nullptr, &defaultList,
0543                     (hide ? FilterAdvancedDevices : 0)
0544                     | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0)
0545                     );
0546         }
0547     } else {
0548         BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend());
0549 
0550 #ifndef QT_NO_PHONON_PLATFORMPLUGIN
0551         if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) {
0552             // the platform plugin lists the audio devices for the platform
0553             // this list already is in default order (as defined by the platform plugin)
0554             defaultList += platformPlugin->objectDescriptionIndexes(AudioCaptureDeviceType);
0555             if (hide) {
0556                 QMutableListIterator<int> it(defaultList);
0557                 while (it.hasNext()) {
0558                     AudioCaptureDevice objDesc = AudioCaptureDevice::fromIndex(it.next());
0559                     const QVariant var = objDesc.property("isAdvanced");
0560                     if (var.isValid() && var.toBool()) {
0561                         it.remove();
0562                     }
0563                 }
0564             }
0565         }
0566 #endif //QT_NO_PHONON_PLATFORMPLUGIN
0567 
0568         // lookup the available devices directly from the backend
0569         if (backendIface) {
0570             // this list already is in default order (as defined by the backend)
0571             QList<int> list = backendIface->objectDescriptionIndexes(AudioCaptureDeviceType);
0572             if (hide || !defaultList.isEmpty() || (override & HideUnavailableDevices)) {
0573                 filter(AudioCaptureDeviceType, backendIface, &list,
0574                         (hide ? FilterAdvancedDevices : 0)
0575                         // the platform plugin maybe already provided the hardware devices?
0576                         | (defaultList.isEmpty() ? 0 : FilterHardwareDevices)
0577                         | ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0)
0578                         );
0579             }
0580             defaultList += list;
0581         }
0582     }
0583 
0584 #ifndef QT_NO_PHONON_SETTINGSGROUP
0585     const QSettingsGroup backendConfig(&d->config, QLatin1String("AudioCaptureDevice")); // + Factory::identifier());
0586     return sortDevicesByCategoryPriority(this, &backendConfig, AudioCaptureDeviceType, category, defaultList);
0587 #else //QT_NO_PHONON_SETTINGSGROUP
0588 #ifndef QT_NO_PHONON_PLATFORMPLUGIN
0589     return defaultList;
0590 #else //QT_NO_PHONON_PLATFORMPLUGIN
0591     return QList<int>();
0592 #endif //QT_NO_PHONON_PLATFORMPLUGIN
0593 #endif //QT_NO_PHONON_SETTINGSGROUP
0594 }
0595 
0596 int GlobalConfig::audioCaptureDeviceFor(CaptureCategory category, int override) const
0597 {
0598     QList<int> ret = audioCaptureDeviceListFor(category, override);
0599     if (ret.isEmpty())
0600         return -1;
0601     return ret.first();
0602 }
0603 
0604 QHash<QByteArray, QVariant> GlobalConfig::audioCaptureDeviceProperties(int index) const
0605 {
0606     return deviceProperties(AudioCaptureDeviceType, index);
0607 }
0608 
0609 void GlobalConfig::setAudioCaptureDeviceListFor(Category category, QList<int> order)
0610 {
0611     CaptureCategory cat = categoryToCaptureCategory(category);
0612     setAudioCaptureDeviceListFor(cat, order);
0613 }
0614 
0615 QList<int> GlobalConfig::audioCaptureDeviceListFor(Category category, int override) const
0616 {
0617     CaptureCategory cat = categoryToCaptureCategory(category);
0618     return audioCaptureDeviceListFor(cat, override);
0619 }
0620 
0621 int GlobalConfig::audioCaptureDeviceFor(Category category, int override) const
0622 {
0623     CaptureCategory cat = categoryToCaptureCategory(category);
0624     return audioCaptureDeviceFor(cat, override);
0625 }
0626 
0627 #endif //PHONON_NO_AUDIOCAPTURE
0628 
0629 
0630 #ifndef PHONON_NO_VIDEOCAPTURE
0631 void GlobalConfig::setVideoCaptureDeviceListFor(CaptureCategory category, QList<int> order)
0632 {
0633 #ifndef QT_NO_PHONON_SETTINGSGROUP
0634     P_D(GlobalConfig);
0635     QSettingsGroup backendConfig(&d->config, QLatin1String("VideoCaptureDevice")); // + Factory::identifier());
0636 
0637     order = reindexList(this, VideoCaptureDeviceType, category, order);
0638 
0639     const QList<int> noCategoryOrder = videoCaptureDeviceListFor(NoCaptureCategory, ShowUnavailableDevices|ShowAdvancedDevices);
0640     if (category != NoCaptureCategory && order == noCategoryOrder) {
0641         backendConfig.removeEntry(QLatin1String("Category_") + QString::number(category));
0642     } else {
0643         backendConfig.setValue(QLatin1String("Category_") + QString::number(category), order);
0644     }
0645 #endif //QT_NO_PHONON_SETTINGSGROUP
0646 }
0647 
0648 QList<int> GlobalConfig::videoCaptureDeviceListFor(CaptureCategory category, int override) const
0649 {
0650     P_D(const GlobalConfig);
0651 
0652 #ifndef QT_NO_PHONON_SETTINGSGROUP
0653     const bool hide = ((override & AdvancedDevicesFromSettings)
0654         ? hideAdvancedDevices()
0655         : static_cast<bool>(override & HideAdvancedDevices));
0656 #else
0657     const bool hide = !((override & AdvancedDevicesFromSettings) && static_cast<bool>(override & HideAdvancedDevices));
0658 #endif
0659 
0660     //First we lookup the available devices directly from the backend
0661     BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend());
0662     if (!backendIface) {
0663         return QList<int>();
0664     }
0665 
0666     // this list already is in default order (as defined by the backend)
0667     QList<int> defaultList = backendIface->objectDescriptionIndexes(VideoCaptureDeviceType);
0668 
0669 #ifndef QT_NO_PHONON_PLATFORMPLUGIN
0670     if (PlatformPlugin *platformPlugin = Factory::platformPlugin()) {
0671         // the platform plugin lists the video devices for the platform
0672         // this list already is in default order (as defined by the platform plugin)
0673         defaultList += platformPlugin->objectDescriptionIndexes(VideoCaptureDeviceType);
0674         if (hide) {
0675             QMutableListIterator<int> it(defaultList);
0676             while (it.hasNext()) {
0677                 VideoCaptureDevice objDesc = VideoCaptureDevice::fromIndex(it.next());
0678                 const QVariant var = objDesc.property("isAdvanced");
0679                 if (var.isValid() && var.toBool()) {
0680                     it.remove();
0681                 }
0682             }
0683         }
0684     }
0685 #endif //QT_NO_PHONON_PLATFORMPLUGIN
0686 
0687 #ifndef QT_NO_PHONON_SETTINGSGROUP
0688     if (hideAdvancedDevices() || (override & HideUnavailableDevices)) {
0689         filter(VideoCaptureDeviceType, backendIface, &defaultList,
0690             (hideAdvancedDevices() ? FilterAdvancedDevices : 0) |
0691             ((override & HideUnavailableDevices) ? FilterUnavailableDevices : 0)
0692             );
0693     }
0694 
0695     //The devices need to be stored independently for every backend
0696     const QSettingsGroup backendConfig(&d->config, QLatin1String("VideoCaptureDevice")); // + Factory::identifier());
0697     return sortDevicesByCategoryPriority(this, &backendConfig, VideoCaptureDeviceType, category, defaultList);
0698 #else // QT_NO_PHONON_SETTINGSGROUP
0699     return defaultList;
0700 #endif // QT_NO_PHONON_SETTINGSGROUP
0701 }
0702 
0703 int GlobalConfig::videoCaptureDeviceFor(CaptureCategory category, int override) const
0704 {
0705     QList<int> ret = videoCaptureDeviceListFor(category, override);
0706     if (ret.isEmpty())
0707         return -1;
0708     return ret.first();
0709 }
0710 
0711 QHash<QByteArray, QVariant> GlobalConfig::videoCaptureDeviceProperties(int index) const
0712 {
0713     return deviceProperties(VideoCaptureDeviceType, index);
0714 }
0715 
0716 void GlobalConfig::setVideoCaptureDeviceListFor(Category category, QList<int> order)
0717 {
0718     CaptureCategory cat = categoryToCaptureCategory(category);
0719     setVideoCaptureDeviceListFor(cat, order);
0720 }
0721 
0722 QList<int> GlobalConfig::videoCaptureDeviceListFor(Category category, int override) const
0723 {
0724     CaptureCategory cat = categoryToCaptureCategory(category);
0725     return videoCaptureDeviceListFor(cat, override);
0726 }
0727 
0728 int GlobalConfig::videoCaptureDeviceFor(Category category, int override) const
0729 {
0730     CaptureCategory cat = categoryToCaptureCategory(category);
0731     return videoCaptureDeviceFor(cat, override);
0732 }
0733 
0734 #endif // PHONON_NO_VIDEOCAPTURE
0735 
0736 QHash<QByteArray, QVariant> GlobalConfig::deviceProperties(ObjectDescriptionType deviceType, int index) const
0737 {
0738     QList<int> indices;
0739     QHash<QByteArray, QVariant> props;
0740 
0741     // Try a pulseaudio device
0742     PulseSupport *pulse = PulseSupport::getInstance();
0743     if (pulse->isUsed()) {
0744         // Check the index before passing it to PulseSupport
0745         indices = pulse->objectDescriptionIndexes(deviceType);
0746         if (indices.contains(index))
0747             props = pulse->objectDescriptionProperties(deviceType, index);
0748     }
0749     if (!props.isEmpty())
0750         return props;
0751 
0752     #ifndef QT_NO_PHONON_PLATFORMPLUGIN
0753     // Try a device from the platform
0754     if (PlatformPlugin *platformPlugin = Factory::platformPlugin())
0755         props = platformPlugin->objectDescriptionProperties(deviceType, index);
0756     if (!props.isEmpty())
0757         return props;
0758     #endif //QT_NO_PHONON_PLATFORMPLUGIN
0759 
0760     // Try a device from the backend
0761     BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend());
0762     if (backendIface)
0763         props = backendIface->objectDescriptionProperties(deviceType, index);
0764     if (!props.isEmpty())
0765         return props;
0766 
0767     return props;
0768 }
0769 
0770 
0771 } // namespace Phonon