diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,9 +192,5 @@ add_subdirectory(kaccess) endif() install(FILES org.kde.plasmashell.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) -if (${ECM_VERSION} STRGREATER "5.58.0") - install(FILES plasma-desktop.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}) -else() - install(FILES plasma-desktop.categories DESTINATION ${KDE_INSTALL_CONFDIR}) -endif() + feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/doc/kcontrol/CMakeLists.txt b/doc/kcontrol/CMakeLists.txt --- a/doc/kcontrol/CMakeLists.txt +++ b/doc/kcontrol/CMakeLists.txt @@ -27,6 +27,5 @@ ecm_optional_add_subdirectory(componentchooser) ecm_optional_add_subdirectory(kded) ecm_optional_add_subdirectory(solid-device-automounter) -ecm_optional_add_subdirectory(phonon) ecm_optional_add_subdirectory(workspaceoptions) diff --git a/doc/kcontrol/phonon/CMakeLists.txt b/doc/kcontrol/phonon/CMakeLists.txt deleted file mode 100644 --- a/doc/kcontrol/phonon/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -########### install files ############### -kdoctools_create_handbook(index.docbook INSTALL_DESTINATION ${KDE_INSTALL_DOCBUNDLEDIR}/en SUBDIR kcontrol/phonon) diff --git a/doc/kcontrol/phonon/index.docbook b/doc/kcontrol/phonon/index.docbook deleted file mode 100644 --- a/doc/kcontrol/phonon/index.docbook +++ /dev/null @@ -1,93 +0,0 @@ - - - -]> -
-Audio and Video Settings - - -MatthiasKretz - - - -2013-12-05 -&kde; 4.12 - - -KDE -Systemsettings -hardware -multimedia -sound -video -backend - - - - -This &systemsettings; module allows you to configure the sound and video device -preference and the backends used by Phonon. - - - -Device Preference tab - -On the left you are presented a tree list with various categories of playback and recording. -For each category you may choose what device you wish to use. -The Audio Playback and Audio Recording -items define the default ordering of devices which can be overridden by -each sub items. -Clicking the Apply Device List To button shows a dialog -which enables you to copy the selected setting from one category to many others. -Highlight a category and the available devices for this category are displayed in the -list on the right. The order in this list determines the preference of the output and capture -devices. If for some reason the first device cannot be used Phonon will try to use the second, &etc; -Use the Prefer and Defer buttons to change the order -and the Test button to play a test sound on the selected device. - - - -Audio Hardware Setup tab - -The various drop down boxes in this tab allow full control over all cards that are attached -to the system. - - -Hardware -Select the Sound Card and an available -Profile to be used. - - -Device Configuration -Select the Sound Device and a Connector. - - -Speaker Placement and Testing or Input Levels - -For a playback device: The buttons on this pane allow you to test each speaker separately. - -For a recording device: A slider shows the Input Levels -of the selected Connector. - - - - - - - - - -Backend tab - -On the left side of this module a list of Phonon backends found on your system is shown. -The order here determines the order Phonon will use the backends. -Use the Prefer and Defer buttons -to change this order. - - - - - -
diff --git a/kcms/CMakeLists.txt b/kcms/CMakeLists.txt --- a/kcms/CMakeLists.txt +++ b/kcms/CMakeLists.txt @@ -44,7 +44,6 @@ add_subdirectory(kded) add_subdirectory(formats) add_subdirectory(notifications) -add_subdirectory(phonon) add_subdirectory(runners) add_subdirectory(spellchecking) add_subdirectory(qtquicksettings) diff --git a/kcms/phonon/CMakeLists.txt b/kcms/phonon/CMakeLists.txt deleted file mode 100644 --- a/kcms/phonon/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -find_package(Phonon4Qt5 4.6.60 NO_MODULE) -include_directories(BEFORE ${PHONON_INCLUDES}) -add_definitions(-DPHONON_LIB_SONAME=\"${PHONON_LIB_SONAME}\") -# KI18N Translation Domain for this library -add_definitions(-DTRANSLATION_DOMAIN=\"kcm5_phonon\") - - -set(kcmphonon_SRCS main.cpp devicepreference.cpp backendselection.cpp) -ki18n_wrap_ui(kcmphonon_SRCS devicepreference.ui backendselection.ui) -set(kcmphonon_LIBS - KF5::ConfigWidgets - KF5::I18n - KF5::IconThemes - KF5::KCMUtils - KF5::KIOWidgets - ${PHONON_LIBRARY}) - -ecm_qt_declare_logging_category(kcmphonon_SRCS HEADER phonon_debug.h IDENTIFIER KCM_PHONON_LOG CATEGORY_NAME org.kde.kcm.phonon) - -add_library(kcm_phonon MODULE ${kcmphonon_SRCS}) -target_link_libraries(kcm_phonon ${kcmphonon_LIBS} KF5::ConfigWidgets) - -install(TARGETS kcm_phonon DESTINATION ${KDE_INSTALL_PLUGINDIR} ) - -########### install files ############### -install( FILES kcm_phonon.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) -install(FILES listview-background.png DESTINATION ${KDE_INSTALL_DATADIR}/kcm_phonon) diff --git a/kcms/phonon/Messages.sh b/kcms/phonon/Messages.sh deleted file mode 100644 --- a/kcms/phonon/Messages.sh +++ /dev/null @@ -1,18 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC *.ui >> rc.cpp -find . -type d | fgrep -v '.svn' | sed -e 's,$,/,' > dirs -msh=`find . -name Messages.sh` -for dir in $msh; do - dir=`dirname $dir` - if test "$dir" != "."; then - egrep -v "^$dir" dirs > dirs.new && mv dirs.new dirs - fi -done -fgrep -v "/tests" dirs > dirs.new && mv dirs.new dirs -dirs=`cat dirs` -find $dirs -maxdepth 1 -name "*.cpp" -print > files -find $dirs -maxdepth 1 -name "*.cc" -print >> files -find $dirs -maxdepth 1 -name "*.h" -print >> files -$XGETTEXT --files-from=files -o $podir/kcm5_phonon.pot -rm -f dirs -rm -f files diff --git a/kcms/phonon/backendselection.h b/kcms/phonon/backendselection.h deleted file mode 100644 --- a/kcms/phonon/backendselection.h +++ /dev/null @@ -1,73 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2004-2007 Matthias Kretz - Copyright (C) 2011-2014 Harald Sitter - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) version 3. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef BACKENDSELECTION_H -#define BACKENDSELECTION_H - -#include "ui_backendselection.h" - -#include -#include - - -struct BackendDescriptor { - explicit BackendDescriptor(const QString &path = QString()); - - bool isValid; - - QString iid; - - QString name; - QString icon; - QString version; - QString website; - int preference; - - QString pluginPath; - - /** Implemented for qSort(QList) */ - bool operator <(const BackendDescriptor &rhs) const; -}; - -class BackendSelection : public QWidget, private Ui::BackendSelection -{ - Q_OBJECT -public: - explicit BackendSelection(QWidget *parent = nullptr); - - void load(); - void save(); - void defaults(); - -private Q_SLOTS: - void selectionChanged(); - void up(); - void down(); - void openWebsite(const QString &url); - -Q_SIGNALS: - void changed(); - -private: - QHash m_backends; - int m_emptyPage; -}; - -#endif // BACKENDSELECTION_H diff --git a/kcms/phonon/backendselection.cpp b/kcms/phonon/backendselection.cpp deleted file mode 100644 --- a/kcms/phonon/backendselection.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2004-2007 Matthias Kretz - Copyright (C) 2011-2014 Harald Sitter - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) version 3. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "backendselection.h" - -#include -#include -#include -#include - -#include "phonon_debug.h" -#include -#include -#include -#include -#include - -BackendDescriptor::BackendDescriptor(const QString &path) - : isValid(false) -{ - QPluginLoader loader(path); - - iid = loader.metaData().value(QLatin1Literal("IID")).toString(); - - const QJsonObject metaData = loader.metaData().value(QLatin1Literal("MetaData")).toObject(); - name = metaData.value(QLatin1Literal("Name")).toString(); - icon = metaData.value(QLatin1Literal("Icon")).toString(); - version = metaData.value(QLatin1Literal("Version")).toString(); - website = metaData.value(QLatin1Literal("Website")).toString(); - preference = metaData.value(QLatin1Literal("InitialPreference")).toDouble(); - - pluginPath = path; - - if (name.isEmpty()) - name = QFileInfo(path).baseName(); - - if (iid.isEmpty()) - return; // Not valid. - - isValid = true; -} - -bool BackendDescriptor::operator <(const BackendDescriptor &rhs) const -{ - return this->preference < rhs.preference; -} - -BackendSelection::BackendSelection(QWidget *parent) - : QWidget(parent) -{ - setupUi(this); - - m_messageWidget->setVisible(false); - m_messageWidget->setCloseButtonVisible(false); - m_messageWidget->setMessageType(KMessageWidget::Information); - m_messageWidget->setText(i18nc("@info User changed Phonon backend", - "To apply the backend change you will have " - "to log out and back in again.")); - - m_down->setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); - m_up->setIcon(QIcon::fromTheme(QStringLiteral("go-up"))); - m_comment->setWordWrap(true); - - m_emptyPage = stackedWidget->addWidget(new QWidget()); - - connect(m_select, &QListWidget::itemSelectionChanged, this, &BackendSelection::selectionChanged); - connect(m_up, &QToolButton::clicked, this, &BackendSelection::up); - connect(m_down, &QToolButton::clicked, this, &BackendSelection::down); -} - -void BackendSelection::load() -{ - // NOTE: for phonon5 this should move into the library in some form. - m_backends.clear(); - - // Read already configured order. - QList iidPreference; - QSettings settings("kde.org", "libphonon"); - const int size = settings.beginReadArray("Backends"); - qCDebug(KCM_PHONON_LOG) << settings.fileName(); - for (int i = 0; i < size; ++i) { - settings.setArrayIndex(i); - iidPreference.append(settings.value(QLatin1String("iid")).toString()); - } - settings.endArray(); - - const QLatin1Literal suffix("/" PHONON_LIB_SONAME "_backend/"); - const QStringList paths = QCoreApplication::libraryPaths(); - qCDebug(KCM_PHONON_LOG) << "libpaths" << paths; - - QList backendList; - - foreach (const QString &path, paths) { - const QString libPath = path + suffix; - const QDir dir(libPath); - if (!dir.exists()) { - qCDebug(KCM_PHONON_LOG) << Q_FUNC_INFO << dir.absolutePath() << "does not exist"; - continue; - } - - const QStringList plugins(dir.entryList(QDir::Files)); - - for (const QString &plugin : plugins) { - BackendDescriptor bd = BackendDescriptor(libPath + plugin); - if (bd.isValid) { - int preference = iidPreference.indexOf(bd.iid); - if (preference != -1) - bd.preference = preference; - backendList.append(bd); - } - } - - std::sort(backendList.begin(), backendList.end()); - } - - /// -------------- LOAD - - m_select->clear(); - - foreach (const struct BackendDescriptor &bd, backendList) { - m_select->addItem(bd.name); - m_backends.insert(bd.name, bd); - } - m_select->item(0)->setSelected(true); -} - -void BackendSelection::save() -{ - qCDebug(KCM_PHONON_LOG) << Q_FUNC_INFO; - qCDebug(KCM_PHONON_LOG) << "~~~~~~~~~~~~~~"; - QSettings settings("kde.org", "libphonon"); - settings.beginWriteArray("Backends", m_select->count()); - for (int i = 0; i < m_select->count(); ++i) { - settings.setArrayIndex(i); - const QListWidgetItem *item = m_select->item(i); - const BackendDescriptor backend = m_backends.value(item->text()); - settings.setValue("iid", backend.iid); - } - settings.endArray(); - settings.sync(); - - qCDebug(KCM_PHONON_LOG) << settings.fileName(); -} - -void BackendSelection::defaults() -{ - load(); -} - -void BackendSelection::selectionChanged() -{ - qCDebug(KCM_PHONON_LOG) << "qooooooooo"; - if (m_select->selectedItems().isEmpty()) { - m_up->setEnabled(false); - m_down->setEnabled(false); - } else { - const QListWidgetItem *const item = m_select->selectedItems().first(); - m_up->setEnabled(m_select->row(item) > 0); - m_down->setEnabled(m_select->row(item) < m_select->count() - 1); - BackendDescriptor backend = m_backends[item->text()]; - - // Have some icon other than "unknown" for backends which don't install an icon. - QIcon icon = QIcon::fromTheme(backend.icon); - if (icon.isNull()) { - QPixmap iconPixmap = KIconLoader::global()->loadIcon("preferences-desktop-sound", KIconLoader::NoGroup, 128); - m_icon->setPixmap(iconPixmap); - } else { - m_icon->setPixmap(icon.pixmap(128, 128)); - } - - m_name->setText(backend.name); - m_website->setText(QString("%1").arg(backend.website)); - connect(m_website, &QLabel::linkActivated, this, &BackendSelection::openWebsite, Qt::UniqueConnection); - m_version->setText(backend.version); - } -} - -void BackendSelection::openWebsite(const QString &url) -{ - new KRun(QUrl(url), window()); -} - -void BackendSelection::up() -{ - QList selectedList = m_select->selectedItems(); - foreach (QListWidgetItem *selected, selectedList) { - const int row = m_select->row(selected); - if (row > 0) { - QListWidgetItem *taken = m_select->takeItem(row - 1); - m_select->insertItem(row, taken); - emit changed(); - selectionChanged(); - } - } -} - -void BackendSelection::down() -{ - QList selectedList = m_select->selectedItems(); - foreach (QListWidgetItem *selected, selectedList) { - const int row = m_select->row(selected); - if (row + 1 < m_select->count()) { - QListWidgetItem *taken = m_select->takeItem(row + 1); - m_select->insertItem(row, taken); - emit changed(); - selectionChanged(); - } - } -} - diff --git a/kcms/phonon/backendselection.ui b/kcms/phonon/backendselection.ui deleted file mode 100644 --- a/kcms/phonon/backendselection.ui +++ /dev/null @@ -1,232 +0,0 @@ - - - Matthias Kretz <kretz@kde.org> - BackendSelection - - - - 0 - 0 - 510 - 362 - - - - - 9 - - - 6 - - - - - 0 - - - 6 - - - - - - 0 - 0 - - - - A list of Phonon Backends found on your system. The order here determines the order Phonon will use them in. - - - A list of Phonon Backends found on your system. The order here determines the order Phonon will use them in. - - - true - - - QAbstractItemView::InternalMove - - - - - - - false - - - Prefer - - - Qt::ToolButtonTextBesideIcon - - - - - - - false - - - Defer - - - Qt::ToolButtonTextBesideIcon - - - - - - - Qt::Horizontal - - - - 81 - 20 - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 6 - - - 9 - - - - - 6 - - - 0 - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - Qt::AlignVCenter - - - - - - - - - QFrame::HLine - - - QFrame::Sunken - - - Qt::Horizontal - - - - - - - - - - Qt::AlignVCenter - - - - - - - - - - - - - - - - - Qt::AlignVCenter - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 20 - - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - - - KMessageWidget - QWidget -
KMessageWidget
- 1 -
-
- - -
diff --git a/kcms/phonon/devicepreference.h b/kcms/phonon/devicepreference.h deleted file mode 100644 --- a/kcms/phonon/devicepreference.h +++ /dev/null @@ -1,95 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006-2008 Matthias Kretz - Copyright (C) 2011 Casian Andrei - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) version 3. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef DEVICEPREFERENCE_H_STUPID_UIC -#define DEVICEPREFERENCE_H_STUPID_UIC - -#include "ui_devicepreference.h" - -#include -#include - -#include -#include - -namespace Phonon { - -class MediaObject; -class AudioOutput; -class VideoWidget; - -class DevicePreference : public QWidget, private Ui::DevicePreference -{ - Q_OBJECT -public: - explicit DevicePreference(QWidget *parent = nullptr); - ~DevicePreference() override; - - void load(); - void save(); - void defaults(); - void pulseAudioEnabled(); - -Q_SIGNALS: - void changed(); - -protected: - void changeEvent(QEvent *) override; - -private Q_SLOTS: - void on_preferButton_clicked(); - void on_deferButton_clicked(); - void on_showAdvancedDevicesCheckBox_toggled(); - void on_applyPreferencesButton_clicked(); - void on_testPlaybackButton_toggled(bool down); - void updateButtonsEnabled(); - void updateDeviceList(); - void updateAudioOutputDevices(); - void updateAudioCaptureDevices(); - void updateVideoCaptureDevices(); - -private: - enum DeviceType {dtInvalidDevice, dtAudioOutput, dtAudioCapture, dtVideoCapture}; - -private: - template void removeDevice(const ObjectDescription &deviceToRemove, - QMap *> *modelMap); - void loadCategoryDevices(); - QList availableAudioOutputDevices() const; - QList availableAudioCaptureDevices() const; - QList availableVideoCaptureDevices() const; - DeviceType shownModelType() const; - -private: - QMap m_audioOutputModel; - QMap m_audioCaptureModel; - QMap m_videoCaptureModel; - QStandardItemModel m_categoryModel; - QStandardItemModel m_headerModel; - DeviceType m_testingType; - - MediaObject *m_media; - AudioOutput *m_audioOutput; - VideoWidget *m_videoWidget; -}; - -} // namespace Phonon - -#endif // DEVICEPREFERENCE_H_STUPID_UIC diff --git a/kcms/phonon/devicepreference.cpp b/kcms/phonon/devicepreference.cpp deleted file mode 100644 --- a/kcms/phonon/devicepreference.cpp +++ /dev/null @@ -1,993 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006-2008 Matthias Kretz - Copyright (C) 2011 Casian Andrei - Copyright (C) 2014 Harald Sitter - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) version 3. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "devicepreference.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifndef METATYPE_QLIST_INT_DEFINED -#define METATYPE_QLIST_INT_DEFINED -// Want this exactly once, see phonondefs_p.h kcm/devicepreference.cpp -Q_DECLARE_METATYPE(QList) -#endif - -namespace Phonon { - -/* - * Lists of categories for every device type - */ -static const Category audioOutCategories[] = { - NoCategory, - NotificationCategory, - MusicCategory, - VideoCategory, - CommunicationCategory, - GameCategory, - AccessibilityCategory, -}; - -static const CaptureCategory audioCapCategories[] = { - NoCaptureCategory, - CommunicationCaptureCategory, - RecordingCaptureCategory, - ControlCaptureCategory -}; - -static const CaptureCategory videoCapCategories[] = { - NoCaptureCategory, - CommunicationCaptureCategory, - RecordingCaptureCategory, -}; - -static const int audioOutCategoriesCount = sizeof(audioOutCategories) / sizeof(Category); -static const int audioCapCategoriesCount = sizeof(audioCapCategories) / sizeof(CaptureCategory); -static const int videoCapCategoriesCount = sizeof(videoCapCategories) / sizeof(CaptureCategory); - -void operator++(Category &c) -{ - c = static_cast(1 + static_cast(c)); - //Q_ASSERT(c <= LastCategory); -} - -class CategoryItem : public QStandardItem { -public: - CategoryItem(Category cat) - : QStandardItem(), - m_cat(cat), - m_odtype(AudioOutputDeviceType) - { - if (cat == NoCategory) { - setText(i18n("Audio Playback")); - } else { - setText(categoryToString(cat)); - } - } - - CategoryItem(CaptureCategory cat, ObjectDescriptionType t = AudioCaptureDeviceType) - : QStandardItem(), - m_capcat(cat), - m_odtype(t) - { - if (cat == NoCaptureCategory) { - switch(t) { - case AudioCaptureDeviceType: - setText(i18n("Audio Recording")); - break; - case VideoCaptureDeviceType: - setText(i18n("Video Recording")); - break; - default: - setText(i18n("Invalid")); - } - } else { - setText(categoryToString(cat)); - } - } - - int type() const override { return 1001; } - Category category() const { return m_cat; } - CaptureCategory captureCategory() const { return m_capcat; } - ObjectDescriptionType odtype() const { return m_odtype; } - -private: - Category m_cat; - CaptureCategory m_capcat; - ObjectDescriptionType m_odtype; -}; - -/** - * Need this to change the colors of the ListView if the Palette changed. With CSS set this won't - * change automatically - */ -void DevicePreference::changeEvent(QEvent *e) -{ - QWidget::changeEvent(e); - if (e->type() == QEvent::PaletteChange) { - deviceList->setStyleSheet(deviceList->styleSheet()); - } -} - -DevicePreference::DevicePreference(QWidget *parent) - : QWidget(parent), - m_headerModel(0, 1, nullptr), - m_media(nullptr), m_audioOutput(nullptr), m_videoWidget(nullptr) -{ - setupUi(this); - - // Setup the buttons - testPlaybackButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); - testPlaybackButton->setEnabled(false); - testPlaybackButton->setToolTip(i18n("Test the selected device")); - deferButton->setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); - preferButton->setIcon(QIcon::fromTheme(QStringLiteral("go-up"))); - - // Configure the device list - deviceList->setDragDropMode(QAbstractItemView::InternalMove); - deviceList->setStyleSheet(QStringLiteral("QTreeView {" - "background-color: palette(base);" - "background-image: url(%1);" - "background-position: bottom left;" - "background-attachment: fixed;" - "background-repeat: no-repeat;" - "background-clip: padding;" - "}") - .arg(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kcm_phonon/listview-background.png"))); - deviceList->setAlternatingRowColors(false); - - // The root item for the categories - QStandardItem *parentItem = m_categoryModel.invisibleRootItem(); - - // Audio Output Parent - QStandardItem *aOutputItem = new CategoryItem(NoCategory); - m_audioOutputModel[NoCategory] = new AudioOutputDeviceModel(this); - aOutputItem->setEditable(false); - aOutputItem->setToolTip(i18n("Defines the default ordering of devices which can be overridden by individual categories.")); - parentItem->appendRow(aOutputItem); - - // Audio Capture Parent - QStandardItem *aCaptureItem = new CategoryItem(NoCaptureCategory, AudioCaptureDeviceType); - m_audioCaptureModel[NoCaptureCategory] = new AudioCaptureDeviceModel(this); - aCaptureItem->setEditable(false); - aCaptureItem->setToolTip(i18n("Defines the default ordering of devices which can be overridden by individual categories.")); - parentItem->appendRow(aCaptureItem); - - // Video Capture Parent - QStandardItem *vCaptureItem = new CategoryItem(NoCaptureCategory, VideoCaptureDeviceType); - m_videoCaptureModel[NoCaptureCategory] = new VideoCaptureDeviceModel(this); - vCaptureItem->setEditable(false); - vCaptureItem->setToolTip(i18n("Defines the default ordering of devices which can be overridden by individual categories.")); - parentItem->appendRow(vCaptureItem); - - // Audio Output Children - parentItem = aOutputItem; - for (int i = 1; i < audioOutCategoriesCount; ++i) { // i == 1 to skip NoCategory - m_audioOutputModel[audioOutCategories[i]] = new AudioOutputDeviceModel(this); - QStandardItem *item = new CategoryItem(audioOutCategories[i]); - item->setEditable(false); - parentItem->appendRow(item); - } - - // Audio Capture Children - parentItem = aCaptureItem; - for (int i = 1; i < audioCapCategoriesCount; ++i) { // i == 1 to skip NoCategory - m_audioCaptureModel[audioCapCategories[i]] = new AudioCaptureDeviceModel(this); - QStandardItem *item = new CategoryItem(audioCapCategories[i], AudioCaptureDeviceType); - item->setEditable(false); - parentItem->appendRow(item); - } - - // Video Capture Children - parentItem = vCaptureItem; - for (int i = 1; i < videoCapCategoriesCount; ++i) { // i == 1 to skip NoCategory - m_videoCaptureModel[videoCapCategories[i]] = new VideoCaptureDeviceModel(this); - QStandardItem *item = new CategoryItem(videoCapCategories[i], VideoCaptureDeviceType); - item->setEditable(false); - parentItem->appendRow(item); - } - - // Configure the category tree - categoryTree->setModel(&m_categoryModel); - if (categoryTree->header()) { - categoryTree->header()->hide(); - } - categoryTree->expandAll(); - - connect(categoryTree->selectionModel(), SIGNAL(currentChanged(const QModelIndex &,const QModelIndex &)), - SLOT(updateDeviceList())); - - // Connect all model data change signals to the changed slot - for (int i = -1; i <= LastCategory; ++i) { - connect(m_audioOutputModel[i], SIGNAL(rowsInserted(QModelIndex, int, int)), this, SIGNAL(changed())); - connect(m_audioOutputModel[i], SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SIGNAL(changed())); - connect(m_audioOutputModel[i], SIGNAL(layoutChanged()), this, SIGNAL(changed())); - connect(m_audioOutputModel[i], SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SIGNAL(changed())); - if (m_audioCaptureModel.contains(i)) { - connect(m_audioCaptureModel[i], SIGNAL(rowsInserted(QModelIndex, int, int)), this, SIGNAL(changed())); - connect(m_audioCaptureModel[i], SIGNAL(rowsRemoved(QModelIndex , int, int)), this, SIGNAL(changed())); - connect(m_audioCaptureModel[i], SIGNAL(layoutChanged()), this, SIGNAL(changed())); - connect(m_audioCaptureModel[i], SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SIGNAL(changed())); - } - if (m_videoCaptureModel.contains(i)) { - connect(m_videoCaptureModel[i], SIGNAL(rowsInserted(QModelIndex, int, int)), this, SIGNAL(changed())); - connect(m_videoCaptureModel[i], SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SIGNAL(changed())); - connect(m_videoCaptureModel[i], SIGNAL(layoutChanged()), this, SIGNAL(changed())); - connect(m_videoCaptureModel[i], SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SIGNAL(changed())); - } - } - - connect(showAdvancedDevicesCheckBox, &QCheckBox::stateChanged, this, &DevicePreference::changed); - - // Connect the signals from Phonon that notify changes in the device lists - connect(BackendCapabilities::notifier(), SIGNAL(availableAudioOutputDevicesChanged()), SLOT(updateAudioOutputDevices())); - connect(BackendCapabilities::notifier(), SIGNAL(availableAudioCaptureDevicesChanged()), SLOT(updateAudioCaptureDevices())); - connect(BackendCapabilities::notifier(), SIGNAL(availableVideoCaptureDevicesChanged()), SLOT(updateVideoCaptureDevices())); - connect(BackendCapabilities::notifier(), SIGNAL(capabilitiesChanged()), SLOT(updateAudioOutputDevices())); - connect(BackendCapabilities::notifier(), SIGNAL(capabilitiesChanged()), SLOT(updateAudioCaptureDevices())); - connect(BackendCapabilities::notifier(), SIGNAL(capabilitiesChanged()), SLOT(updateVideoCaptureDevices())); - - if (!categoryTree->currentIndex().isValid()) { - categoryTree->setCurrentIndex(m_categoryModel.index(0, 0).child(1, 0)); - } -} - -DevicePreference::~DevicePreference() -{ - // Ensure that the video widget is destroyed, if it remains active - delete m_videoWidget; -} - -void DevicePreference::updateDeviceList() -{ - // Temporarily disconnect the device list selection model - if (deviceList->selectionModel()) { - disconnect(deviceList->selectionModel(), - SIGNAL(currentRowChanged(const QModelIndex &,const QModelIndex &)), - this, SLOT(updateButtonsEnabled())); - } - - // Get the current selected category item - QStandardItem *currentItem = m_categoryModel.itemFromIndex(categoryTree->currentIndex()); - if (currentItem && currentItem->type() == 1001) { - CategoryItem *catItem = static_cast(currentItem); - bool cap = catItem->odtype() != AudioOutputDeviceType; - const Category cat = catItem->category(); - const CaptureCategory capcat = catItem->captureCategory(); - - // Update the device list, by setting it's model to the one for the corresponding category - switch (catItem->odtype()) { - case AudioOutputDeviceType: - deviceList->setModel(m_audioOutputModel[cat]); - break; - case AudioCaptureDeviceType: - deviceList->setModel(m_audioCaptureModel[capcat]); - break; - case VideoCaptureDeviceType: - deviceList->setModel(m_videoCaptureModel[capcat]); - break; - default: ; - } - - // Update the header - if (cap ? capcat == NoCaptureCategory : cat == NoCategory) { - switch (catItem->odtype()) { - case AudioOutputDeviceType: - m_headerModel.setHeaderData(0, Qt::Horizontal, i18n("Default Audio Playback Device Preference"), Qt::DisplayRole); - break; - case AudioCaptureDeviceType: - m_headerModel.setHeaderData(0, Qt::Horizontal, i18n("Default Audio Recording Device Preference"), Qt::DisplayRole); - break; - case VideoCaptureDeviceType: - m_headerModel.setHeaderData(0, Qt::Horizontal, i18n("Default Video Recording Device Preference"), Qt::DisplayRole); - break; - default: ; - } - } else { - switch (catItem->odtype()) { - case AudioOutputDeviceType: - m_headerModel.setHeaderData(0, Qt::Horizontal, i18n("Audio Playback Device Preference for the '%1' Category", - categoryToString(cat)), Qt::DisplayRole); - break; - case AudioCaptureDeviceType: - m_headerModel.setHeaderData(0, Qt::Horizontal, i18n("Audio Recording Device Preference for the '%1' Category", - categoryToString(capcat)), Qt::DisplayRole); - break; - case VideoCaptureDeviceType: - m_headerModel.setHeaderData(0, Qt::Horizontal, i18n("Video Recording Device Preference for the '%1' Category", - categoryToString(capcat)), Qt::DisplayRole); - break; - default: ; - } - } - } else { - // No valid category selected - m_headerModel.setHeaderData(0, Qt::Horizontal, QString(), Qt::DisplayRole); - deviceList->setModel(nullptr); - } - - // Update the header, the buttons enabled state - deviceList->header()->setModel(&m_headerModel); - updateButtonsEnabled(); - - // Reconnect the device list selection model - if (deviceList->selectionModel()) { - connect(deviceList->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex &,const QModelIndex &)), - this, SLOT(updateButtonsEnabled())); - } - - deviceList->resizeColumnToContents(0); -} - -void DevicePreference::updateAudioCaptureDevices() -{ - const QList list = availableAudioCaptureDevices(); - QHash hash; - foreach (const AudioCaptureDevice &dev, list) { - hash.insert(dev.index(), dev); - } - - for (int catIndex = 0; catIndex < audioCapCategoriesCount; ++ catIndex) { - const int i = audioCapCategories[catIndex]; - AudioCaptureDeviceModel *model = m_audioCaptureModel.value(i); - Q_ASSERT(model); - - QHash hashCopy(hash); - QList orderedList; - - if (model->rowCount() > 0) { - QList order = model->tupleIndexOrder(); - foreach (int idx, order) { - if (hashCopy.contains(idx)) { - orderedList << hashCopy.take(idx); - } - } - - if (hashCopy.size() > 1) { - // keep the order of the original list - foreach (const AudioCaptureDevice &dev, list) { - if (hashCopy.contains(dev.index())) { - orderedList << hashCopy.take(dev.index()); - } - } - } else if (hashCopy.size() == 1) { - orderedList += hashCopy.values(); - } - - model->setModelData(orderedList); - } else { - model->setModelData(list); - } - } - - deviceList->resizeColumnToContents(0); -} - -void DevicePreference::updateVideoCaptureDevices() -{ - const QList list = availableVideoCaptureDevices(); - QHash hash; - foreach (const VideoCaptureDevice &dev, list) { - hash.insert(dev.index(), dev); - } - - for (int catIndex = 0; catIndex < videoCapCategoriesCount; ++ catIndex) { - const int i = videoCapCategories[catIndex]; - VideoCaptureDeviceModel *model = m_videoCaptureModel.value(i); - Q_ASSERT(model); - - QHash hashCopy(hash); - QList orderedList; - - if (model->rowCount() > 0) { - QList order = model->tupleIndexOrder(); - foreach (int idx, order) { - if (hashCopy.contains(idx)) { - orderedList << hashCopy.take(idx); - } - } - - if (hashCopy.size() > 1) { - // keep the order of the original list - foreach (const VideoCaptureDevice &dev, list) { - if (hashCopy.contains(dev.index())) { - orderedList << hashCopy.take(dev.index()); - } - } - } else if (hashCopy.size() == 1) { - orderedList += hashCopy.values(); - } - - model->setModelData(orderedList); - } else { - model->setModelData(list); - } - } - - deviceList->resizeColumnToContents(0); -} - -void DevicePreference::updateAudioOutputDevices() -{ - const QList list = availableAudioOutputDevices(); - QHash hash; - foreach (const AudioOutputDevice &dev, list) { - hash.insert(dev.index(), dev); - } - - for (int catIndex = 0; catIndex < audioOutCategoriesCount; ++ catIndex) { - const int i = audioOutCategories[catIndex]; - AudioOutputDeviceModel *model = m_audioOutputModel.value(i); - Q_ASSERT(model); - - QHash hashCopy(hash); - QList orderedList; - - if (model->rowCount() > 0) { - QList order = model->tupleIndexOrder(); - foreach (int idx, order) { - if (hashCopy.contains(idx)) { - orderedList << hashCopy.take(idx); - } - } - - if (hashCopy.size() > 1) { - // keep the order of the original list - foreach (const AudioOutputDevice &dev, list) { - if (hashCopy.contains(dev.index())) { - orderedList << hashCopy.take(dev.index()); - } - } - } else if (hashCopy.size() == 1) { - orderedList += hashCopy.values(); - } - - model->setModelData(orderedList); - } else { - model->setModelData(list); - } - } - - deviceList->resizeColumnToContents(0); -} - -QList DevicePreference::availableAudioOutputDevices() const -{ - return BackendCapabilities::availableAudioOutputDevices(); -} - -QList DevicePreference::availableAudioCaptureDevices() const -{ -#ifndef PHONON_NO_AUDIOCAPTURE - return BackendCapabilities::availableAudioCaptureDevices(); -#else - return QList(); -#endif -} - -QList DevicePreference::availableVideoCaptureDevices() const -{ -#ifndef PHONON_NO_VIDEOCAPTURE - return BackendCapabilities::availableVideoCaptureDevices(); -#else - return QList(); -#endif -} - -void DevicePreference::load() -{ - showAdvancedDevicesCheckBox->setChecked(!GlobalConfig().hideAdvancedDevices()); - loadCategoryDevices(); -} - -void DevicePreference::loadCategoryDevices() -{ - // "Load" the settings from the backend. - for (int i = 0; i < audioOutCategoriesCount; ++ i) { - const Category cat = audioOutCategories[i]; - QList list; - const QList deviceIndexes = GlobalConfig().audioOutputDeviceListFor(cat); - foreach (int i, deviceIndexes) { - list.append(AudioOutputDevice::fromIndex(i)); - } - - m_audioOutputModel[cat]->setModelData(list); - } - -#ifndef PHONON_NO_AUDIOCAPTURE - for (int i = 0; i < audioCapCategoriesCount; ++ i) { - const CaptureCategory cat = audioCapCategories[i]; - QList list; - const QList deviceIndexes = GlobalConfig().audioCaptureDeviceListFor(cat); - foreach (int i, deviceIndexes) { - list.append(AudioCaptureDevice::fromIndex(i)); - } - - m_audioCaptureModel[cat]->setModelData(list); - } -#endif - -#ifndef PHONON_NO_VIDEOCAPTURE - for (int i = 0; i < videoCapCategoriesCount; ++ i) { - const CaptureCategory cat = videoCapCategories[i]; - QList list; - const QList deviceIndexes = GlobalConfig().videoCaptureDeviceListFor(cat); - foreach (int i, deviceIndexes) { - list.append(VideoCaptureDevice::fromIndex(i)); - } - - m_videoCaptureModel[cat]->setModelData(list); - } -#endif - - deviceList->resizeColumnToContents(0); -} - -void DevicePreference::save() -{ - for (int i = 0; i < audioOutCategoriesCount; ++i) { - const Category cat = audioOutCategories[i]; - Q_ASSERT(m_audioOutputModel.value(cat)); - const QList order = m_audioOutputModel.value(cat)->tupleIndexOrder(); - GlobalConfig().setAudioOutputDeviceListFor(cat, order); - } - -#ifndef PHONON_NO_AUDIOCAPTURE - for (int i = 0; i < audioCapCategoriesCount; ++i) { - const CaptureCategory cat = audioCapCategories[i]; - Q_ASSERT(m_audioCaptureModel.value(cat)); - const QList order = m_audioCaptureModel.value(cat)->tupleIndexOrder(); - GlobalConfig().setAudioCaptureDeviceListFor(cat, order); - } -#endif - -#ifndef PHONON_NO_VIDEOCAPTURE - for (int i = 0; i < videoCapCategoriesCount; ++i) { - const CaptureCategory cat = videoCapCategories[i]; - Q_ASSERT(m_videoCaptureModel.value(cat)); - const QList order = m_videoCaptureModel.value(cat)->tupleIndexOrder(); - GlobalConfig().setVideoCaptureDeviceListFor(cat, order); - } -#endif -} - -void DevicePreference::defaults() -{ - { - const QList list = availableAudioOutputDevices(); - for (int i = 0; i < audioOutCategoriesCount; ++i) { - m_audioOutputModel[audioOutCategories[i]]->setModelData(list); - } - } - { - const QList list = availableAudioCaptureDevices(); - for (int i = 0; i < audioCapCategoriesCount; ++i) { - m_audioCaptureModel[audioCapCategories[i]]->setModelData(list); - } - } - { - const QList list = availableVideoCaptureDevices(); - for (int i = 0; i < videoCapCategoriesCount; ++i) { - m_videoCaptureModel[videoCapCategories[i]]->setModelData(list); - } - } - - /* - * Save this list (that contains even hidden devices) to GlobaConfig, and then - * load them back. All devices that should be hidden will be hidden - */ - save(); - loadCategoryDevices(); - - deviceList->resizeColumnToContents(0); -} - -void DevicePreference::pulseAudioEnabled() -{ - showAdvancedDevicesContainer->removeItem(showAdvancedDevicesSpacer); - delete showAdvancedDevicesSpacer; - showAdvancedDevicesCheckBox->setVisible(false); -} - -void DevicePreference::on_preferButton_clicked() -{ - QAbstractItemModel *model = deviceList->model(); - { - AudioOutputDeviceModel *deviceModel = dynamic_cast(model); - if (deviceModel) { - deviceModel->moveUp(deviceList->currentIndex()); - updateButtonsEnabled(); - emit changed(); - } - } - { - AudioCaptureDeviceModel *deviceModel = dynamic_cast(model); - if (deviceModel) { - deviceModel->moveUp(deviceList->currentIndex()); - updateButtonsEnabled(); - emit changed(); - } - } - { - VideoCaptureDeviceModel *deviceModel = dynamic_cast(model); - if (deviceModel) { - deviceModel->moveUp(deviceList->currentIndex()); - updateButtonsEnabled(); - emit changed(); - } - } -} - -void DevicePreference::on_deferButton_clicked() -{ - QAbstractItemModel *model = deviceList->model(); - { - AudioOutputDeviceModel *deviceModel = dynamic_cast(model); - if (deviceModel) { - deviceModel->moveDown(deviceList->currentIndex()); - updateButtonsEnabled(); - emit changed(); - } - } - { - AudioCaptureDeviceModel *deviceModel = dynamic_cast(model); - if (deviceModel) { - deviceModel->moveDown(deviceList->currentIndex()); - updateButtonsEnabled(); - emit changed(); - } - } - { - VideoCaptureDeviceModel *deviceModel = dynamic_cast(model); - if (deviceModel) { - deviceModel->moveDown(deviceList->currentIndex()); - updateButtonsEnabled(); - emit changed(); - } - } -} - - -DevicePreference::DeviceType DevicePreference::shownModelType() const -{ - const QStandardItem *item = m_categoryModel.itemFromIndex(categoryTree->currentIndex()); - if (!item) - return dtInvalidDevice; - Q_ASSERT(item->type() == 1001); - - const CategoryItem *catItem = static_cast(item); - if (!catItem) - return dtInvalidDevice; - - switch (catItem->odtype()) { - case AudioOutputDeviceType: - return dtAudioOutput; - case AudioCaptureDeviceType: - return dtAudioCapture; - case VideoCaptureDeviceType: - return dtVideoCapture; - default: - return dtInvalidDevice; - } -} - -void DevicePreference::on_applyPreferencesButton_clicked() -{ - const QModelIndex idx = categoryTree->currentIndex(); - const QStandardItem *item = m_categoryModel.itemFromIndex(idx); - if (!item) - return; - Q_ASSERT(item->type() == 1001); - - const CategoryItem *catItem = static_cast(item); - - QList aoPreferredList; - QList acPreferredList; - QList vcPreferredList; - const Category *categoryList = nullptr; - const CaptureCategory *capCategoryList = nullptr; - int categoryListCount; - int catIndex; - bool cap = false; - - switch (catItem->odtype()) { - case AudioOutputDeviceType: - aoPreferredList = m_audioOutputModel.value(catItem->category())->modelData(); - categoryList = audioOutCategories; - categoryListCount = audioOutCategoriesCount; - cap = false; - break; - - case AudioCaptureDeviceType: - acPreferredList = m_audioCaptureModel.value(catItem->captureCategory())->modelData(); - capCategoryList = audioCapCategories; - categoryListCount = audioCapCategoriesCount; - cap = true; - break; - - case VideoCaptureDeviceType: - vcPreferredList = m_videoCaptureModel.value(catItem->captureCategory())->modelData(); - capCategoryList = videoCapCategories; - categoryListCount = videoCapCategoriesCount; - cap = true; - break; - - default: - return; - } - - QPointer dialog = new QDialog(this); - - QLabel *label = new QLabel(dialog); - label->setText(i18n("Apply the currently shown device preference list to the following other " - "audio playback categories:")); - label->setWordWrap(true); - - QListWidget *list = new QListWidget(dialog); - - for (catIndex = 0; catIndex < categoryListCount; catIndex ++) { - Category cat = cap ? NoCategory : categoryList[catIndex]; - CaptureCategory capcat = cap ? capCategoryList[catIndex] : NoCaptureCategory; - - QListWidgetItem *item = nullptr; - if (cap) { - if (capcat == NoCaptureCategory) { - item = new QListWidgetItem(i18n("Default/Unspecified Category"), list, capcat); - } else { - item = new QListWidgetItem(categoryToString(capcat), list, capcat); - } - } else { - if (cat == NoCategory) { - item = new QListWidgetItem(i18n("Default/Unspecified Category"), list, cat); - } else { - item = new QListWidgetItem(categoryToString(cat), list, cat); - } - } - - item->setCheckState(Qt::Checked); - if (cat == catItem->category()) { - item->setFlags(item->flags() & ~Qt::ItemIsEnabled); - } - } - - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok - | QDialogButtonBox::Cancel, dialog); - connect(buttonBox, &QDialogButtonBox::accepted, dialog.data(), &QDialog::accept); - connect(buttonBox, &QDialogButtonBox::rejected, dialog.data(), &QDialog::reject); - - QVBoxLayout *layout = new QVBoxLayout(dialog); - layout->addWidget(label); - layout->addWidget(list); - layout->addWidget(buttonBox); - - switch (dialog->exec()) { - case QDialog::Accepted: - for (catIndex = 0; catIndex < categoryListCount; catIndex ++) { - Category cat = cap ? NoCategory : categoryList[catIndex]; - CaptureCategory capcat = cap ? capCategoryList[catIndex] : NoCaptureCategory; - - if (cap ? capcat != catItem->captureCategory() : cat != catItem->category()) { - QListWidgetItem *item = list->item(catIndex); - Q_ASSERT(item->type() == cap ? (int) capcat : (int) cat); - if (item->checkState() == Qt::Checked) { - switch (catItem->odtype()) { - case AudioOutputDeviceType: - m_audioOutputModel.value(cat)->setModelData(aoPreferredList); - break; - - case AudioCaptureDeviceType: - m_audioCaptureModel.value(capcat)->setModelData(acPreferredList); - break; - - case VideoCaptureDeviceType: - m_videoCaptureModel.value(capcat)->setModelData(vcPreferredList); - break; - - default: ; - } - } - } - } - - emit changed(); - break; - - case QDialog::Rejected: - // nothing to do - break; - } - - delete dialog; -} - -void DevicePreference::on_showAdvancedDevicesCheckBox_toggled() -{ - // In order to get the right list from the backend, we need to update the settings now - // before calling availableAudio{Output,Capture}Devices() - GlobalConfig().setHideAdvancedDevices(!showAdvancedDevicesCheckBox->isChecked()); - loadCategoryDevices(); -} - -void DevicePreference::on_testPlaybackButton_toggled(bool down) -{ - if (down) { - QModelIndex idx = deviceList->currentIndex(); - if (!idx.isValid()) { - return; - } - - // Shouldn't happen, but better to be on the safe side - if (m_testingType != dtInvalidDevice) { - delete m_media; - m_media = nullptr; - delete m_audioOutput; - m_audioOutput = nullptr; - delete m_videoWidget; - m_videoWidget = nullptr; - } - - // Setup the Phonon objects according to the testing type - m_testingType = shownModelType(); - switch (m_testingType) { - case dtAudioOutput: { - // Create an audio output with the selected device - m_media = new MediaObject(this); - const AudioOutputDeviceModel *model = static_cast(idx.model()); - const AudioOutputDevice &device = model->modelData(idx); - m_audioOutput = new AudioOutput(this); - if (!m_audioOutput->setOutputDevice(device)) { - KMessageBox::error(this, i18n("Failed to set the selected audio output device")); - break; - } - - // Just to be very sure that nothing messes our test sound up - m_audioOutput->setVolume(1.0); - m_audioOutput->setMuted(false); - - createPath(m_media, m_audioOutput); - static QUrl testUrl = QUrl::fromLocalFile(QStandardPaths::locate( - QStandardPaths::GenericDataLocation, - QStringLiteral("sounds/Oxygen-Sys-Log-In.ogg"))); - m_media->setCurrentSource(testUrl); - connect(m_media, &MediaObject::finished, testPlaybackButton, &QToolButton::toggle); - - break; - } - -#ifndef PHONON_NO_AUDIOCAPTURE - case dtAudioCapture: { - // Create a media object and an audio output - m_media = new MediaObject(this); - m_audioOutput = new AudioOutput(NoCategory, this); - - // Just to be very sure that nothing messes our test sound up - m_audioOutput->setVolume(1.0); - m_audioOutput->setMuted(false); - - // Try to create a path - if (!createPath(m_media, m_audioOutput).isValid()) { - KMessageBox::error(this, i18n("Your backend may not support audio recording")); - break; - } - - // Determine the selected device - const AudioCaptureDeviceModel *model = static_cast(idx.model()); - const AudioCaptureDevice &device = model->modelData(idx); - m_media->setCurrentSource(device); - - break; - } -#endif - -#ifndef PHONON_NO_VIDEOCAPTURE - case dtVideoCapture: { - // Create a media object and a video output - m_media = new MediaObject(this); - m_videoWidget = new VideoWidget(nullptr); - - // Try to create a path - if (!createPath(m_media, m_videoWidget).isValid()) { - KMessageBox::error(this, i18n("Your backend may not support video recording")); - break; - } - - // Determine the selected device - const VideoCaptureDeviceModel *model = static_cast(idx.model()); - const VideoCaptureDevice &device = model->modelData(idx); - m_media->setCurrentSource(device); - - // Set up the testing video widget - m_videoWidget->setWindowTitle(i18n("Testing %1", device.name())); - m_videoWidget->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint); - if (device.property("icon").canConvert(QVariant::String)) - m_videoWidget->setWindowIcon(QIcon::fromTheme(device.property("icon").toString())); - m_videoWidget->move(QCursor::pos() - QPoint(250, 295)); - m_videoWidget->resize(320, 240); - m_videoWidget->show(); - - break; - } -#endif - - default: - return; - } - - m_media->play(); - } else { - // Uninitialize the Phonon objects according to the testing type - switch (m_testingType) { - case dtAudioOutput: - disconnect(m_media, &MediaObject::finished, testPlaybackButton, &QToolButton::toggle); - delete m_media; - delete m_audioOutput; - break; - - case dtAudioCapture: - delete m_media; - delete m_audioOutput; - break; - - case dtVideoCapture: - delete m_media; - delete m_videoWidget; - break; - - default: - return; - } - - m_media = nullptr; - m_videoWidget = nullptr; - m_audioOutput = nullptr; - m_testingType = dtInvalidDevice; - } -} - -void DevicePreference::updateButtonsEnabled() -{ - if (deviceList->model()) { - QModelIndex idx = deviceList->currentIndex(); - preferButton->setEnabled(idx.isValid() && idx.row() > 0); - deferButton->setEnabled(idx.isValid() && idx.row() < deviceList->model()->rowCount() - 1); - testPlaybackButton->setEnabled(idx.isValid() && (idx.flags() & Qt::ItemIsEnabled)); - } else { - preferButton->setEnabled(false); - deferButton->setEnabled(false); - testPlaybackButton->setEnabled(false); - } -} - -} // Phonon namespace - -#include "moc_devicepreference.cpp" diff --git a/kcms/phonon/devicepreference.ui b/kcms/phonon/devicepreference.ui deleted file mode 100644 --- a/kcms/phonon/devicepreference.ui +++ /dev/null @@ -1,219 +0,0 @@ - - - Matthias Kretz <kretz@kde.org> - DevicePreference - - - - 0 - 0 - 600 - 400 - - - - - - - - - - 0 - 0 - - - - Qt::CustomContextMenu - - - Various categories of media use cases. For each category, you may choose what device you prefer to be used by the Phonon applications. - - - Various categories of media use cases. For each category, you may choose what device you prefer to be used by the Phonon applications. - - - false - - - - - - - 0 - - - - - Show advanced devices - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 0 - 20 - - - - - - - - - - 0 - - - - - Use the currently shown device list for more categories. - - - Use the currently shown device list for more categories. - - - Apply Device List To... - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 0 - 20 - - - - - - - - - - - - true - - - Devices found on your system, suitable for the selected category. Choose the device that you wish to be used by the applications. - - - The order determines the preference of the devices. If for some reason the first device cannot be used Phonon will try to use the second, and so on. - - - Qt::ScrollBarAsNeeded - - - true - - - QAbstractItemView::InternalMove - - - QAbstractItemView::SelectRows - - - - 32 - 32 - - - - Qt::ElideNone - - - QAbstractItemView::ScrollPerPixel - - - QAbstractItemView::ScrollPerPixel - - - false - - - false - - - - - - - - - Qt::Horizontal - - - - 16 - 29 - - - - - - - - Test - - - true - - - Qt::ToolButtonTextBesideIcon - - - - - - - false - - - prefer the selected device - - - Prefer - - - Qt::ToolButtonTextBesideIcon - - - - - - - false - - - no preference for the selected device - - - Defer - - - Qt::ToolButtonTextBesideIcon - - - - - - - - - - diff --git a/kcms/phonon/kcm_phonon.desktop b/kcms/phonon/kcm_phonon.desktop deleted file mode 100644 --- a/kcms/phonon/kcm_phonon.desktop +++ /dev/null @@ -1,160 +0,0 @@ -[Desktop Entry] -Exec=kcmshell5 kcm_phonon -Icon=preferences-desktop-sound -Type=Service -X-KDE-ServiceTypes=KCModule - -X-KDE-Library=kcm_phonon -X-KDE-FactoryName=kcm_phonon -X-KDE-ParentApp=kcontrol -X-KDE-System-Settings-Parent-Category=audio-and-video -X-DocPath=kcontrol/phonon/index.html - -Name=Audio and Video -Name[ar]=الصّوت والفيديو -Name[bs]=Audio i video -Name[ca]=Àudio i vídeo -Name[ca@valencia]=Àudio i vídeo -Name[cs]=Audio a video -Name[da]=Lyd og video -Name[de]=Audio und Video -Name[el]=Ήχος και βίντεο -Name[en_GB]=Audio and Video -Name[es]=Audio y vídeo -Name[et]=Heli ja video -Name[eu]=Audioa eta bideoa -Name[fi]=Ääni ja video -Name[fr]=Audio et vidéo -Name[gl]=Son e vídeo -Name[he]=שמע ווידאו -Name[hu]=Hang és videó -Name[id]=Audio dan Video -Name[is]=Hljóð og mynd -Name[it]=Audio e video -Name[ja]=オーディオとビデオ -Name[ko]=오디오 및 비디오 -Name[lt]=Garsas ir vaizdas -Name[mr]=ऑडिओ व व्हिडिओ -Name[nb]=Lyd og video -Name[nds]=Video un Klang -Name[nl]=Audio en video -Name[nn]=Lyd og video -Name[pa]=ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ -Name[pl]=Dźwięk i obraz -Name[pt]=Áudio e Vídeo -Name[pt_BR]=Áudio e vídeo -Name[ru]=Звук и видео -Name[sk]=Zvuk a video -Name[sl]=Zvok in video -Name[sr]=Аудио и видео -Name[sr@ijekavian]=Аудио и видео -Name[sr@ijekavianlatin]=Audio i video -Name[sr@latin]=Audio i video -Name[sv]=Ljud- och video -Name[tr]=Ses ve Video -Name[uk]=Звук та відео -Name[x-test]=xxAudio and Videoxx -Name[zh_CN]=音频和视频 -Name[zh_TW]=音效和視訊 -Comment=Phonon Audio and Video -Comment[ar]=صوت وفيديو فنون -Comment[bs]=Audio i Video fonona -Comment[ca]=Àudio i vídeo del Phonon -Comment[ca@valencia]=Àudio i vídeo del Phonon -Comment[cs]=Audio a video - Phonon -Comment[da]=Phonon lyd og video -Comment[de]=Phonon - Audio und Video -Comment[el]=Ήχος και βίντεο Phonon -Comment[en_GB]=Phonon Audio and Video -Comment[es]=Audio y vídeo de Phonon -Comment[et]=Phononi heli ja video -Comment[eu]=Phonon audioa eta bideoa -Comment[fi]=Phononin ääni ja video -Comment[fr]=Audio et vidéo de Phonon -Comment[gl]=Son e vídeo de Phonon -Comment[he]=שמע ווידאו של Phonon -Comment[hu]=Phonon hang és videó -Comment[id]=Phonon Audio dan Video -Comment[is]=Phonon hljóð og mynd -Comment[it]=Audio e video di Phonon -Comment[ja]=Phonon オーディオとビデオ -Comment[ko]=Phonon 오디오 및 비디오 -Comment[lt]=Phonon audio ir video -Comment[mr]=फोनोन ऑडिओ व व्हिडिओ -Comment[nb]=Phonon lyd og video -Comment[nds]=Phonon-Instellen för Video un Klang -Comment[nl]=Phonon audio en video -Comment[nn]=Phonon lyd og video -Comment[pa]=ਫੋਨੋਨ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ -Comment[pl]=Phonon - dźwięk i obraz -Comment[pt]=Áudio e Vídeo do Phonon -Comment[pt_BR]=Áudio e vídeo do Phonon -Comment[ru]=Настройка мультимедийной платформы Phonon -Comment[sk]=Zvuk a video Phonon -Comment[sl]=Phonon: zvok in video -Comment[sr]=Аудио и видео са Фононом -Comment[sr@ijekavian]=Аудио и видео са Фононом -Comment[sr@ijekavianlatin]=Audio i video sa Phononom -Comment[sr@latin]=Audio i video sa Phononom -Comment[sv]=Phonon ljud- och video -Comment[tr]=Phonon Ses ve Görüntü -Comment[uk]=Звук та відео Phonon -Comment[x-test]=xxPhonon Audio and Videoxx -Comment[zh_CN]=Phonon 音频和视频 -Comment[zh_TW]=Phonon 音效和視訊 -X-KDE-Keywords=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine -X-KDE-Keywords[bg]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,Звук,Видео,Изход,Устройство,Уведомление,Музика,Общуване,Медия -X-KDE-Keywords[bn]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine -X-KDE-Keywords[bs]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,zvuk,izlaz,uređaj,informacija,muzika,komunikacija,mediji -X-KDE-Keywords[ca]=So,Phonon,Àudio,Vídeo,Sortida,Dispositiu,Notificació,Música,Comunicació,Suport,NMM,GStreamer,Xine -X-KDE-Keywords[ca@valencia]=So,Phonon,Àudio,Vídeo,Eixida,Dispositiu,Notificació,Música,Comunicació,Suport,NMM,GStreamer,Xine -X-KDE-Keywords[cs]=Zvuk,Phonon,Audio,Video,Výstup,Zařízení,Upozornění,Hudba,Komunikace,Média,NMM,GStreamer,Xine -X-KDE-Keywords[da]=Lyd,Phonon,Audio,Video,Output,Enhed,Bekendtgørelse,Musik,Kommunikation,Medie,NMM,GStreamer,Xine,VLC -X-KDE-Keywords[de]=Klänge,Sound,Phonon,Audio,Video,Ausgabe,Gerät,Benachrichtigung,Notification,Musik,Kommunikation,Media,NMM,GStreamer,Xine -X-KDE-Keywords[el]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine -X-KDE-Keywords[en_GB]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine -X-KDE-Keywords[eo]=Sono,Phonon,Sono,Video,Eligo,Aparato,Atentigo,Muziko,Komunikado,Aŭdvido,NMM,GStreamer,Xine -X-KDE-Keywords[es]=Sonido,Phonom,Audio,Video,Salida,Dispositivo,Notificación,Música,Comunicación,Media,NMM,GStreamer,Xine -X-KDE-Keywords[et]=heli,Phonon,audio,video,väljund,seade,märguanne,muusika,suhtlemine,meedia,NMM,GStreamer,Xine -X-KDE-Keywords[eu]=Soinua,Phonon,Audioa,Bideoa,Irteera,Gailua,Jakinarazpena,Musika,Komunikazioa,Media,NMM,GStreamer,Xine -X-KDE-Keywords[fi]=Ääni,Phonon,Audio,Video,Ulostulo,Lähtö,Tuloste,Laite,Huomautukset,Huomautus,Ilmoitukset,Ilmoitus,Musiikki,Viestintä,Media,NMM,GStreamer,Xine -X-KDE-Keywords[fr]=son, phonon, audio, vidéo, sortie, périphérique, notification, musique, communication, média, NMM, GStreamer, Xine -X-KDE-Keywords[ga]=Fuaim,Phonon,Fís,Aschur,Gléas,Fógairt,Fógra,Ceol,Cumarsáid,Meán,Meáin,NMM,GStreamer,Xine -X-KDE-Keywords[gl]=Son,Phonon,Audio,Vídeo,Saída,Dispositivo,Notificación,Música,Comunicación,Medio,NMM,GStreamer,Xine -X-KDE-Keywords[hi]=ध्वनि, फ़ोनॉन, श्रव्य, वीडियो, आउटपुट, डिवाइस, अधिसूचना, संगीत, संचार,मीडिया, NMM, GStreamer, Xine -X-KDE-Keywords[hu]=Hang,Phonon,Hang,Videó,Kimenet,Eszköz,Értesítés,Zene,Kommunikáció,Média,NMM,GStreamer,Xine -X-KDE-Keywords[ia]=Sono,Phonon,Audio,Video,Exito,Dispositivo,Notification,Musica,Communication,Medios,NMM,GStreamer,Xine -X-KDE-Keywords[id]=Suara,Phonon,Audio,Video,Output,Perangkat,Notifikasi,Musik,Komunikasi,Media,NMM,GStreamer,Xine -X-KDE-Keywords[is]=Hljóð,Phonon,Audio,Vídeó,Úttak,Tæki,Tilkynningar,Tónlist,Samskipti,Miðlar,NMM,GStreamer,Xine -X-KDE-Keywords[it]=suono,Phonon,audio,video,output,dispositivo,notifica,musica,comunicazione,media,NMM,GStreamer,Xine -X-KDE-Keywords[kk]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine -X-KDE-Keywords[km]=សំឡេង Phonon អូឌីយ៉ូ វីដេអូ លទ្ធផល ឧបករណ៍ ការ​ជូនដំណឹង តន្ត្រី ការ​ទាក់ទង មេឌៀ NMM GStreamer Xine -X-KDE-Keywords[ko]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,소리,사운드,오디오,비디오,동영상,음악,출력,장치,알림,대화,미디어 -X-KDE-Keywords[lv]=skaņa,phonon,audio,video,izvade,ierīce,paziņojums,mūzika,saziņa,mēdiji,NMM,GStreamer,Xine -X-KDE-Keywords[mr]=Sound,फोनॉन,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine -X-KDE-Keywords[nb]=Lyd,Phonon,Audio,Video,Utgang,Enhet,Varsling,Musikk,Kommunikasjon,Media,NMM,GStreamer,Xine -X-KDE-Keywords[nds]=Klang,Phonon,Audio,Video,Utgaav,Reedschap,Bescheed,Musik,Kommunikatschoon,Mediendatei,NMM,GStreamer,Xine -X-KDE-Keywords[nl]=Geluid,Phonon,audio,video,uitvoer,apparaat,melding,muziek,communicatie,medium,NMM,GStreamer,Xine -X-KDE-Keywords[nn]=lyd,Phonon,audio,lyd,video,film,utdata,utgang,eining,varsling,musikk,kommunikasjon,media,NMM,GStreamer,Xine -X-KDE-Keywords[pa]=ਸਾਊਂਡ,ਫੋਨੋਨ,ਆਡੀਓ,ਵਿਡੀਓ,ਵੀਡਿਓ,ਆਉਟਪੁੱਟ,ਜੰਤਰ,ਨੋਟੀਫਿਕੇਸ਼ਨ,ਸੂਚਨਾ,ਸੰਗੀਤ,ਮਿਊਜ਼ਕ,ਕਮਿਊਨੀਕੇਸ਼ਨ,ਸੰਚਾਰ, ਮੀਡਿਆ,NMM,ਜੀਸਟਰੀਮਰ,ਜ਼ਾਇਨ -X-KDE-Keywords[pl]=Dźwięk,Phonon,Audio,Video,Wyjście,Urządzenie,Powiadomienia,Muzyka,Komunikacja,Multimedia,NMM,GStreamer,Xine -X-KDE-Keywords[pt]=Som,Phonon,Áudio,Vídeo,Saída,Dispositivo,Notificação,Música,Comunicações,Multimédia,NMM,GStreamer,Xine -X-KDE-Keywords[pt_BR]=Som,Phonon,Áudio,Vídeo,Saída,Dispositivo,Notificação,Música,Comunicações,Multimídia,NMM,GStreamer,Xine -X-KDE-Keywords[ro]=sunet,phonon,audio,video,ieșire,dispozitiv,notificare,muzică,comunicare,media,NMM,GStreamer,Xine -X-KDE-Keywords[ru]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,звук,аудио,видео,вывод,устройство,уведомления,музыка,связь,общение,медиа -X-KDE-Keywords[sk]=Zvuk,Phonon,Audio,Video,Output,Zariadenie,Notifikácia,Hudba,Komunikácia,Mádia,NMM,GStreamer,Xine -X-KDE-Keywords[sl]=zvok,phonon,audio,video,predvajanje,naprava,naprave,obvestila,glasba,komunikacija,igre,snemanje,predstavnost,nmm,gstreamer,xine,vlc -X-KDE-Keywords[sr]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,звук,Фонон,аудио,видео,излаз,уређај,обавештење,музика,комуникација,медија,НММ,Гстример,Ксин -X-KDE-Keywords[sr@ijekavian]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,звук,Фонон,аудио,видео,излаз,уређај,обавештење,музика,комуникација,медија,НММ,Гстример,Ксин -X-KDE-Keywords[sr@ijekavianlatin]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,zvuk,Phonon,audio,video,izlaz,uređaj,obaveštenje,muzika,komunikacija,medija,NMM,GStreamer,Xine -X-KDE-Keywords[sr@latin]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,zvuk,Phonon,audio,video,izlaz,uređaj,obaveštenje,muzika,komunikacija,medija,NMM,GStreamer,Xine -X-KDE-Keywords[sv]=Ljud,Phonon,Video,Utgång,Enhet,Underrättelse,Musik,Kommunikation,Media,NMM,GStreamer,Xine -X-KDE-Keywords[tg]=Овоз,Phonon,Аудио,Видео,Барориш,Дастгоҳ,Огоҳӣ,Мусиқӣ,Паёмнависӣ,Медиа,NMM,GStreamer,Xine -X-KDE-Keywords[tr]=Ses,Phonon,Ses,Video,Çıkış,Aygıt,Bildirim,Müzik,İletişim,Ortam,NMM,GStreamer,Xine -X-KDE-Keywords[ug]=ئاۋاز،Phonon،ئۈن،سىن،چىقىرىش،ئۈسكۈنە،ئۇقتۇرۇش،مۇزىكا،ئالاقە،ۋاسىتە،NMM،GStreamer،Xine -X-KDE-Keywords[uk]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,звук,фонон,аудіо,відео,виведення,показ,відтворення,пристрій,сповіщення,музика,спілкування,мультимедіа -X-KDE-Keywords[vi]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,âm thanh,phim ảnh,thiết bị,thông báo,nhạc,giao tiếp, phương tiện -X-KDE-Keywords[wa]=Son,Phonon,Odio,Videyo,rexhowe,éndjin,notifiaedje,muzike,comunicåcion,media,NMM,GStreamer,Xine -X-KDE-Keywords[x-test]=xxSoundxx,xxPhononxx,xxAudioxx,xxVideoxx,xxOutputxx,xxDevicexx,xxNotificationxx,xxMusicxx,xxCommunicationxx,xxMediaxx,xxNMMxx,xxGStreamerxx,xxXinexx -X-KDE-Keywords[zh_CN]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine,声音,音效,视频,输出,设备,提醒,音乐,通信,媒体 -X-KDE-Keywords[zh_TW]=Sound,Phonon,Audio,Video,Output,Device,Notification,Music,Communication,Media,NMM,GStreamer,Xine diff --git a/kcms/phonon/listview-background.png b/kcms/phonon/listview-background.png deleted file mode 100644 index a4a31840870e371acefa13df2e4dd51771396b93..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@#KU( zUCx|$-tzap^X{#xkCU*N`^n$`Ip^M2*7D_d|I4}WG0r(&^JCZLtPm}lI%5V0H#uNH zcm|Z_I=~p<3IhY@TFHy`(wvKbE&#VS<|WU>+_gEFUGfY}m~Drk*;xFfgA>Oa@^}qk z-Gt)slVRo{0>&di$q?dY5CN17s^=VBIp;aAoa6P^@!G&*j1@TCB6nF)=d2LwiCDmI zI8GdY;;bvU!}k z^#s6gdRWIV(yW4>0$2i^M*+?}P}N}K!73UIsCpgugHs)I?gOs(3*|X@4qVGwte8)C z|NcZ6@n(UwFmk1-IlLLnO-ThMxD+Lw6Qn*+^FZ}f;p7~F00*xT*$gNE$hpj&iJ4{= zozI<6-ZvVo*1#2EX7E>`0;~))IQ59enSU$%PfTjW9sxw+*$TIL5O~4yo^0I{! z$Lko@vCB29fL1Wx3j)=vmOj6dCoap$Axal{LBwte<(?#gOrud1)nVfm;u8~ zeA>;Oh<9H{usXw+CmoJ<25z7MlzcvravEo*3K%;wjeO36U9@2pg|{3zcC3oojxZZs zcwGYwgCQI?5RT{w2_F*P3>m_N7jwhZVTiGA8qiAPXb6lke-IV$=Y6=sGF;O#@$TPe zffL-mMzEg2tl^FhaGqAwRJr8`L+UylhYn2O@WDw84Q3^zu2n1nC`~JQGFsCctTnpU zXKv^Wp?DbKcm$>}Jr)rFN5Kr;2hu+VUS@M3qj6-Sy<77*aU3UD2d>dAJ>LoNm@xI0 zt;VJGkV;kDyL$p#UK+=teWT#6fRjl8eV_{hmkA5O&dN)vKbh{ zLeggtl510lU_khM4O-!S52k4nSR)aGnTiV^CAxi&Ih`*s#wKR6EYp7KRu?CZ|4*oPy8_xN?()fa-}VAd9P@%zZIKQ=y@-Lw!GmH`^_Ks_iy8dj-W_0Wwya>%OxOZW zOJ6Dcaxgt2ATq>xy#lH91lF7YB(JGJ)7S&FdfvpOfOa>+?oNd5T`=t(Fs%Ime1%V{ zt^_v~gAtEZRF}=dDr+1hFyuJLWZZEwSibW_RyJQ)i^G?;F&8bK+x{$SYTF!N{^|hs z?bs(E;u2D(g;8K@kk?L=w{HQb7gAwfU{z2JaeX)%LNpRV$P5vHWlu0N1`fb=U4XlA zIR|6R2UMCX(981{LiTQiidzuMJq|PXJir^5RGD5?-I(;6sr$mo>ercP?f`7cagB-8 zvaKiTw{wBDFmk!c9D6APV~uY61Sx8B$8qt=PwzxNGg5&xggjdb4_NkpR&L`oJ3BODG(fEa@?CJi($4W%aoP#JUX3gZ%BF3goRS_h7>GR!D{ zKN?fv|3i3DfLVAJ=FDR-rXK~f2H|ta1kG%UBh-?haKR@Wpph3~4mPc6?r5xMXW;~_ z0mtO7cP@#=!_nDq`;<`K{OR4uj1S7&zQZ~&&EF2Lr=UyKGAcl-kR}sJw70jTwXGe^ z&1rc~DtobrqE(djR?D(r3$q-%1e%14X@JIL94h=Ds<4D!)?1B|H!Ag3;maof|0^&< zHWwtwyyUs`KnYytRp9zC#M&dEeGFRW5opuT0^DwR`!^F&gj$nQb-|c0e`r{rMBH)*U0SoRn&A=~<{MDilzw^G%x%VC3*Y`G?J76+|1ScB>~y=~f?!M6h&e zAG*4_5R1j70_JjAOiWB*a$*WIGt*+NQS9j-y9UR$p1FiJ6b?zK%O*jtsxo!SxLfOf zd4Xk~uL(CRpnX!N;}gFcrXk@q45`Ew1x6*D;I(iA47IP#q^f(tWBFasCVmcm?0Z0Q zNDUKWAqj1$DGsLV9x#33C7;3;2id_9Jt=o>g!v|DPn^fL5Z~Ev~ zxON7U_BvRsy8;nGS{?WGEyt;+u95Shp+W55zaRO0PPvYh*as>JGOGej5K6U^=jyIu zbB2|`X7qCy230ATR#RW;HCDY=&eelM%RB{b>>dH{FY6OD`FbNA6X2HXxJ*@5B?%+1 zWx+6-=-rX~lZ5r9AE%d|zIrNDjGPNV_W_m0U;Wk?o`0qvlh!Ka`7)5&5q#lD4C~jO zfv(QQI68U++qb`hLZLv{cvRRkpPypR89*_f2e4kF|41m&W1g?=dpMKO$A1iM^lq@+ zPUW-~GNjs?E%8b99H-&a27$MPyir! z|HuE_ftf7FXz^@NZIpmZ#N#;k+>MCEV(9PRCe(DF52QXNECr;Xl2fpHdaq^bc`~Ik zK*qo--w#t1RVuFMTEBzkwh3tO5%B&HaOxOikl{giK?+*fq(#D4Ra|MvG3cZ5zW(f+ z9@g*P&YG^iI@J*iO~DGSgUgbEppK2Z_{7c6VK}=14w|a4)o!2BXbk7QbEEXnJo5ym zGE+VY7x}q`0xDqhzm7FfS6@Y~RvhR$#=K+UAw2Cytkic|1#mxb-2$}9UqCOZ?eueM zC7~&XNQZ=$Vpy-@lBe@Irm?a3(w#GJURZBqi?6*l9y7HWSmtWDS~EapE2Yi)-TS8S z^M@udR#-!wqY7ZA8NvnUUxH*Zg{Pl>9Fvn19!P!FRfScJL*;n_YL2&cGBuVB$n^c^ zto|Hh)invK>y}Gl;F2THxkd*o9u#VOFLV*#!Wsh|WoW}4N!ncF4=$bKY{qf*k@Sjw z>rDmgH#RXX6vDFiT_0i^im;77IC>X?+N__tMeNkso#oh z|EQv<^9Tjzrk<2s%>`B^T<}rbs)8!FevNsrr*-Cm7@&>fj>{!S!3h}v?m!#=5scw4 z0);^@wCSjTHU&LuDvBzxRiWh^+Guh-J&yIy@izsm-`~u_4nxoTuV>{fUu%VBoJ?xk zpx*k|Hy^;(eJ250*rTe6L=u-@dKC^24v0Mh&ju^!?6A%;izis;s;=7H5~_w{R;Q>c zummJQ38}V@<5n1BRi*U-*A>t{AfWvMkU!vsHWevD8Pm6Jx4Ik4^pM7AfcTPthA=W%6y?z71T#v%TU$?Ye8DFtnUpv*do$ z1$B^;eSC8WFK&%`w&u0BEx^W&m*J_W9>eg+U;`)#YK=Ud_wfO+2CFMm)+@0my@t`6 z3NL|804l&LApogt1=QJZ`2cr09Jxn9LK{^6lC50{?et5Yj#s!NfpB|L{w%)GQrM8? zz=#M9if=4sy`8m!qxG8iBoGNr%QZ)95x_2Q2r9(6;~vYPGl;Pl7WJ` z*0(Wm_m50`vwkK$ zsjL@Rk5?3yl$C7$(3VW|2@ie^W8l+3VW2KFNR>kauc9^z4T|7wgt}m_V_5IGjU`;5 z>&y))EMH2YOhG>hE=x4rBk<@`25$L3aS2jY*)BZ)Qn^#<$)|r?StC%Dm{pmR;`&zx z=BAty?Aq;~(U`!TU)Ik&wN(O^#)`T!R)dztbWRxN2d!I;X?>vOMd%}6fj;~tz%5c} z(4G)USOPMO0}E1FaL%US=tq((`<>S_tPvOJZfg(W;tME*v9&f>T6e=e0uz(KwKt}r zF})VIUUb1_$mX(m{)ML{U<6K3H9+&u)oWFCoxS@s|Ab0SoNAsag@6C7pWyZ0`blN$ z4Io%)9tupA5Qh|$-gdPz55PkFb935Dg-Q)h9O98pNjL=cle}ygL85G`J+C z0!vVm_du(ttS~ip1>{(cYTy#IoeG%M!f4m0k#tTFk z;BwKqdZfHYT`kX80Z>W06jdd#m9iAYo1~^yc)j5OQ=ugQ=L)QZ8uWXXhe3^zhFJ zGO40INtUL~Oa_qGi3yv2NW4{N#auE60iiDJiXA2teS@16bx&Qx#q{ z>sQZtK_vJBx>SLsDsLFTW`P#)sw^s=;Ppc4n~0&N%<{hHRz*ePE4`k30rBCFL$eM8 zfZR75?QVt<4=XBL2dvA1K~a;Pd5vMExD__~I3No92`p@*P{3jfg|(YcQk&L={*9Z+>vn*e5n6VCUYYQWcfPvnwm=6qSMC zB~oeKOKR0|neZ}JO~{-osM1TIof*VOZ%1UhqOuHfN0(^Z5}Xag0%>E3-rYw5{@On& z@SR&(4;aF&?Itd}kW`<;L{?kg@F`cv<@n%7+i_&nl+X8H^{#8NcmE!|`s&LdwIpEY zrLJ;b87si*)%K)PADug#Dxezk1D0S^YN$%7Dgai$m=zLIFSI15pfN#P0aO9EQl^tr z+qPwA47?g1lzn*SA*9A{f##O$>Uuncm{3{GG=hNzvb-1?OrE^md2L{&P$2CB3reTo zdrcIvaE@xOY!PfE8n$2We=vrB{Z5kv>5TPfp|!PLGzNZ2aH{I60!Z*Sx`xK2yb6fH zacN*l%6F?@aMn+Arm3(JzyYA5(Hy8uYT$ZVr8RJ_ifpBkU>K(S{%psQkF#@E{@rS7 ztJywTM;Rxo7=OIx`zf(`5GdvOs( zjxA9@g&12F@E8BP1H(tcXlrZ7dFNh?-#-2@GMULhbtM25a8+PQb(OE_3#OVl1t(Zc z1(u);?oz3xDGdZBJkSDiTm@4B7Zj`3)@e+K3Tb6b0|BgjVppye3I*7f4N};WIY`dj zjppeu11O7Ss5OpgSDG3LHKni2Sp_4ejU;<_P9ASqDHPbuIygrYIB<1$&eEa@tmr6CLbBb39WTrq$tS!Aij1$`*km&H-F;MHH=RQr9dN!{uhfrwH~B82Im> zSPa96;G&IJ$}r&B-#y`hRinCVomvujq`)-xLh6Bd)*b##DN_Y2su$cjbg7t6xk~ec zRqa|4xIvIIashDwFFUp7D$FoV`Lr>>k;zQUShfPJJnsriSdU;~?smDyfNKotz7~X1 zkzioCHYpUAfIVKYe)I2GNMl&a0i;qouDX(g!6kL&ZSZ@;wtIh?#$ETeVa4*3vHH~0 zC9Go;qZJTUg{8R{SW-=o@~YrctlPMS$^v84U|<{U1t4e@l_gmHOrzVq(q2_-t2Kbh z`AMq+Cjm;n2Ban*KT61Wc6xdm*=()?ELqro6R{{$OC$Y~Q~`Mc2)>Tm^vU3b=lI0_afI2u8nj1oIdu>ciMV{< zv3x!+-($?>uBT#P*u&_|eG;Z~K)xj1okD6+vJP0Su4;g(c;D_JfFD0t@7}}=M@KK` zV8U?SwPD1<1po{dV#vEKjX;%_%Q5`brXFx@g=oQU5F1;b!O^2f1Y|+LYW|tO3ND>f zuW8&ar81QY?0mC+HD)E#{PqCIHMOp)v|1^lQfsVq(1KcL$bv$u7HZl_`qQkAN@=p*00|vZ#Pdr^B5R|`T(F>&Z2O@PhIOFC8ecv zq?Z1VOsiSH8m}rfR5}+}N2T+mrl{{)fdEy#8WO0ydU>EJ0qTL%<7+^gArmbv&GOnK zBS%pz7Cng}&&2De-#z*(C1#)@q#d_6u-$@F4nkyaFvyS*2I21L`>iUZ$!o z0qUPbsryisHMK0I!m5EFq%oOaxk{-tFwJ&ZvNadn6ZuMXkUQeJ^!Sv@hOi=2Pvour3y1szJ?#L^Da>Z7yp%VRnTKA zKHw^0fVbUBrGeR5B~S@W>BtkXQe{1g%NP^Db|4%H$&g@bD$}4+(2oU$zX#kIB$~rm zenwk4Bwz}xa;!ni#13=~;k@7QV-D+`cQTe3M>jaaoCAv%hj8<zaw$D{?9F(~rWn zhZImbccq`0(($p|PRFWKFM-QBo_qcY0kNw9rNplOF>0`)vO0(f*v9Ir#;_h}X-uBg zD{XL@N(}=51zNAND!|UU&Pr1%S*Z$3fKp6L;C3wN5W*D0kt0VjJ~mMe2Pn>UcA_)C zS&R#4>5O67+LpSKmPR#L$Td+V*fDfmJ`VG1f5*a_i*8vR0I+sl8tc|B1~dU|^cv(R zzYn)~KmoOCukMcF^Itm$r@iIv7@ru$?_YkQ42P>re1DWEFg2JH!;IZc8-I9Uk+8q{1BKq;A`7`I)71gUfiM~@s8HtJDVS6IZ^ijMr} z#oR{M@+5jrNe7g)B)~`Fef{Id<%5R5zKNwd$AW69?vl&8v7~z`IE%oJz8CrNy9BWP zm0yypJQe%O&IG=4?w}*9B+&%G`VFt~4{|nEeO0 zSV7SG)K>qvIxAPko?0tZKnX@t-}a7nG`BQi=NTOiqb}%7tmJxk{G*Kep(Yc zd+AA9C4QA-ekk6%GkaV<75lDFvkne4RenZX|AF;Lr5AxC3@3Iia^wF5C-))7GBMI%u(rPF9@ZIc}#g0>D+%Jfxey&bALuhdxs4+65T^-5y`lN2^cWhIo0 z7Ih+(O5xyvgP5G0s(h*qS}+k0j@gMpy|jE|3lQE1}r`%BooP>{;F2$?2Ynwv!u*^aKx zE`&lMwN<Q4y$qHCFHc5Y#~%S%}zKYpz~k<$xfBH~H%BSu8)mWbfX6n9fXtk~6nb zC3pnQ)^`C-$6L>9MXDw29}Y0BSa93}Ez5Vh#|l8cUO#m=V9oK%~QY2E# zz&V4PxE{HqpMy31pjv~ijQ1W&;+|jJh*-1<+qQ4PRA#~lxIh)9IxF)B)|+H`W7vVg zL&6Swn-98Hg`Bqgk?JX#bon#1s^$RTa$oO~MT-Quow6HO0a5`Ms`uF+FxP|NByJn; z5ujv?-~=hF#~5Si>+3}*Y+~n*J#w3&w+`zfY5xLg`$y122Htj28)6Bw1g1|oz(h%_ zfAAQ>O2_~G6bm!x-GIZYMdj=M(|eF?IvFl^z~k2=KmKJDC+<=}tpdF7P&4j*=thLY zDZJYMGA1U+39>+7y}PyqPyxUaoU9JsJ^OcKDl=L8VSgEzjNa3ikUdfONRHx(} z;icJ9se8M7uyVyp`Duv=e1t`9w|awt+3T!?DLm~~rRGYIdI5zWu#mr_NTM3W}YyLiM`P5m1_XrTADxh>;0X7sev0~+NxtC!3wpXS1T;p=I*moh~yoBYa zCb4RLQ&2eIfSLQ_OSjs`5LP<=Ve^%((fqGk;TFIF`NzKg&p(7z%Q`uC^j^4J$IPJ{ zz@0G=s1#=n45#tk2X7S0(~MnvUd8C>h+5QVN^4aGHYh$Nc;$STP*ve;uo|SUjS{k& zd9!M1RZyjONL8iTcEubEwq?ufmiH~g>Q!rCnmQ;EK^?fvzpTnwP{0cA(|Q#n)hmqw zg0}KmXB76hW#x^Jn~C?nI&e&3 zrG#q}lA(jWvFvwD@PhoI3|%PfpZ_kmL;nS>({LpaqW^uwN;9b6-Ofy!V;jQqG~CNZuebX zo#y^{Y!+y3$X9N zZVV3}R%)b_;nyiDnF1_h-g7g#EHX3G0!*`F1gxR!^wIL(Bug44FsOYvF@*qb8BoUw z1l1~;T@=2Eu7#aA>&&wdiA3r4?^k1G!Kl)Jpj5h9RZjrd14=-Xsqg|g<17lPMWqItbbf(^`!IS|cH(X48Waww$(Cd5;eF}u-#f<;RyuCKV{@zF9%_wEe;rH! z%K-_@`~Ko%Xj*U~z{0Q!`(Y$+Kz8I)$Q`*I;9ODJqGjM4|9%4s&M6o;ykEZMJAp_> z3L9LeqR@a|S11;cD-^4slCLPMR9WhpQ3=aa4Uk5vT2|I7tSYD$c>$?}RgQ~AghL^m zd(L@iYi*_2l!(PV%B%{UDwqT-DX9u6C17>1l1Wh4tXYMrOa|MwZm+FV9o9js{jV_j z04~2~AzC|(vYIODD*d>q4jefyu-ZLR|9Q_7+$NUg)QYj8R1wIH+(P&runKX*P-u= z^lr0`A*^)V`h{B!!(lzTb6AgN?gHEju$m?m_GYv$dN%+Qjx`|MNq`nd=D>eOG4pe8 zSWxl(`+M-fj?)a6i{GAUA$U> zRo?z_N!{ZNhhyFb8{Nc z{qDs|{nf360B>Dgb3gB~`T=fLbgAD(3{Lu%Z}O z{Mysj;k4Cj|M)s9K{-pj>M3I>Dof`Zn(WrCKVuz+hlbJLzk|wo!gvMRCii}Xu@fKq zuL}^0=nYC)T6xU4C}r&^9CKI+*v%b`qp1XJWKsajv$aI(6rmayTzw~WvrB$+#hI63 zrY?sq>ai31-VZ0gi-0Ay#eKiJ3?8Y%-z z>RMCSx~c$UN{y9jsuZV|0hPW2rSL`R>me1sP=!^PoJ;>!5fZFAWsUE9T+yLIs@7R& zt+@sRs(?&uZbdzpE$c;RXQz04=~?8m*%GWCXmxiC?ffg^@4p1+UjTn~<$5OGw|(%~ z!%F2W7Kw$r0Up+zVT7kd(&c0-KQPeJ){bjF^e>1vy$xUntn3!(u?+y{m^ye9a--j> z0_#!P=eM7NM_+t53I!Vn2lfd-ECP_c0xFG}2ikN~E27buR9FJmkiJ}h)nQbd1oYq^ zzPV zJ8lVaruE2>%grF1xd*Jc4;-i@O9tNa!JDz<KQ7t%#Y&HXel_?2WKqw%gT+rE#NGL4F9;-D9C>)?JmQ>YRd)2Nc zRhC@`s#H@6p)@~8X-#;tP$-ORuDT8(GZb8B_3Ee+pDK^I_$jPfcde@!5S(s#!4sP< zU%pJ#UKioXC!Ub8D}@17brs1L`!+US(I=WBmQQ6sjJbAHsO#8qft7&0HN_cQSf05s zr+*GT_XIfI;&Jx*S7F1&{|u(5z+DSg_63;9^TD|#;@CSdefTy3Ma}~(0Q}p-=VI^B z224zhT1P%ckBiDaelO!tql8XfiBdW+(K}VmO7pB9;}Q!Nkvix)RsGNDF@O@Ku=3CH`M~=K>t(Rpt5r z{l0#;o|g4~JAT^KHct?=-;{Tfj6A5))4fXg?1#bx{JFn_uYKjNhKW8Ix0C z+A_l!oPMkXRDCVi-o3M91zMV0Gr*Gn<#9v_$Q_{PNm*qSU>a1pcrqlQMoNO3O3|Eh zf~rEAQlVYFaxFG*+B%o+L8?noxbKxROHdU+i>s>&umG?en>TO4>#rZh;NWFQpH+sl zs@d}*)vRIH&LZkc>jO*%I?jwLu)Y-v3!Wl{Wr^OrA4~Ruk3NKTTfR*xT7V%HIUp|E z;d0jk%)r#e#}OI)F1QSH(U^>g`q&qCAsny8l`A9Ea#Jd-1e9h~W$C$fYpz3UYsa+0 zdZfaVE0E7`bL#jlSO0Rg?@&>UpK!tG+0B!TJC) zlm=CrT>am6+YU@jjN|ChBY8#5Lrb%pkD{sk03QBgP~BiC!&qsN(ds8y--_{Vp|Bu@ zl|zf|hZfnL`vzp;Teop5?)=z~;qo*BU@(ngp|Ypo30x1Rdti$2R_OdgNKU=1sBBm7 zdvK`tHpCMtj89ylMUaHl0j(2Q#wZD}a`_sp6(J*^*9*_I!g})RO3w*($fZ;bsiXo_ z38e&de_hK*N;>odsvKCFpR}C*Leljw@_heuyh}^(EkIsqSFhh>Y6&- z^QrHmw(Wj!*nn*!8Gcy+)de_bHrqmh6hjn`VI_USuR|INkpPk za!a)WER+6g?zN`IR&3jPE6RiAIbaD|0+umGYLN~4EBNO>&*mf)tGpcYZtq(fov z*nT(a>l$YbUGY+#SsbrPIB6~wPn}&|2|{FJ&(wEdlZX?)ynio36BE(}km`zRZ66-^ zv?j#CF22wLh7?#Ag2KWI3t)c)qz0s00AS;mJ8|2G{ySXWR)Cv=*-0cLJ#Ys%32^=3 zc0B7E4F3x_w;i#@p|PcS^5we_O;lkbbcKHCSx6^i9WTOmF2d;906T@9w_m|s@8`*QMstE|%cW+h|H2`sn3!p{QH zLwQ(f_Imx;_3?+%x$d(7G=erAKLyK5!5vsj3os+zi;2E3A{}{6iOqH&UxNe3Zbdw4 zVJbX9|DRH29l+APbPsgO)xYnS9jFlSdc72nC4hDLpG(E#b&x-o`r8_wWQK7j(g2Bznz z0_#F@31}ow0-;}mTT|d%g4c1)YV7>jcTiTfk;>1&(@2E7q4`!rcQ2(xLv-|qn7Z^` zn5jXB%379&U+mw8zTvfq#*&CeBLKJ)*vzb`EJIna9JdRVz5dz_lzyetPo@`B3Xtl( z@=Os>>0VJ*@}J+o;{(M@uT`g2?I`HTaH%_7RUiS(d4Z+E`$uJx;4a@R;LC2xi(mQw0@{Csk?ePNxVqkM<&&q+~J6j8d ztR$SOy3Q%)3U#3+VBLw4kzw>4>CUOCnoPKR>q-2ld!qnYF;~D?FtEx@*LPf;nN0wE z$|uuY*u4bKA?pj4)Zm_ve;IWxcZ1s&L2D%5fN7g>mu&#kvi@ak{22l5|3Er+ z#u@60mE+k%@54x_O(<;~v3NAU<+za2I$p1?uEwSfo3Z?wm9TPWOr>O2$`Mah0CiqF zfh_=SQ$rJ0uULoq6tt?f0R<8Oin(-u+B#5KSxwLqpfYpiR8|SdjNu+p z)9~Bg*F;fEZ;^N`#}^)W1Dmf8=WAIDMFs4I3M&MxoeXd@#!&FzXhmR-KMgzH3rLlv zg~zTx{xq&xbAK*qZxXc0*abj*R!W)GM1ZVm4fq47tyxNORW^50i`TI_+p`qy(F)8| zQxIHgA+`ihd{lY|R8~}q^MCI~clQDGUpTM$v-z0o-#>B^t&J%#rWJDq(hCySC;sk< zpa$N|Ime2XD==_jfPUD8h8;f*Yy6k6jgTYz)zR6G4}RpopuBQzUS&y%lkv0A%ddya z+mwNpEERnflNbI8vCzwoVvls%jpuuAM*r|?#1m<1Ed>ilgLTmNv zby&CdI{f0PpCXw|Ktd}2T>a7{{^=X1WF0FcuuLjzVgbTRk%1-#lx1OE4zJgT3l}a> zU!?-7L4`0@XfLeDL2+$4vRGSgz6m#Oy$^w4M;2P!gl)x;N?n4hVl#A4T~=vz57M!d z2o3yCM8{rmYzZ+e9eaAV;M~w!#FHlC@fc;SW<59<4xpXwE(vfA;BcJFD*l`OL_s!t zlM6}h9J^qH7cRmsuC9s!6qa)I7`T1M-Si9i;!DrwAXNe1b;l?^{m~%+vh-4Q1+)mk zy3kwzU%MZP+vyGFtfFzWpv7eeD&Tq8O_Z z)}r~peeDdEcccI?C$LPDAuJ8!3kz22JMg&M;;b|GjiHVoD^@J0FYxrKGh#*gTT$4% zoQg{d0ZX-|kt47|FMwM~M?wL@Hr;S7Zr=JK1j{-AZj#w{8mZ)E=w;WzUA{K&(^7mk zH1NL>9)1$sHXN!o5~{)eW1BG+ZbK}QR@4?i5tRjiBCRf^#LDMpYZ=5?2_Il?TUvku zan_=5`%nONK5yq{p{lpv1)tZ4Up@0A75T^rfGj86c0&jcKX_?IEr9B`YS0H3AgoUW zEp9i#bj6+|=^ zLn0A}q-)fmKt5)@&Utq9OgN$mqfS zd^J1rN-Jg^@z5bmUj7N9S6(7l0+3@oT#euKZpO%DJ7P(TpiQNcjz|IkV>AhA{<;dEu?S11?_+n4SgKGC~Ls{To7;e+(mW(HWuO z8hZOy<5>TC#8Pz>Ta72A;sQ`yg5oXN8JMD?^QgUs+KolMo=@Dhbi$x^X&r9awgXd> zA-weK=ktdbE4FjT6@2!SLo*w*0dNA#!QcYB5Ln)yT6nPj?KdiIpnhiagtpdJR8&>a zeNWF396H$L@Ch^Ox_Z?rQd{}woIVtpof6Q#l5-CdfK*wU*RN^8ZQE`_Rb^`qS~I7( z2GV8}TKRSG*WM1Md9#YkT!>E|Cbf->?9M#rAjvRY=stBF&R$*vgV$uijYkm^@Pc!P zT1se@*Hnn-A7d?+YMm8S6GjuBt;L>~o}+h_Le*K@w}kMe&s+jyN{CAF zTQ6L+66?1Qk{T>HSikw5Z~9e;n8KeQTgqXEg3iDZ%@3Y5umgsDn{`lf)D5Y8;Th6?KJ zI|wN8v1#LG)YjGG;y^!oj&x;`9Eu+c#_^Fq8pWU9I||(eFlTC2DY#B18Gd~r(SPrQ z;}m3Hh_wM)+Da~WW=BACb4!!(U8`W*oDM7g>5qR#Z!?aplEw(^l>*qt#)eYB${20r zXx2S2WAX=<`_R%PN- z@lY24+tCY{bB5EGmQxsPD$xv^`zUBm?m|39KkTBuDw}VUi_*usm-b!N7_6*SEu%eQ zZEc;@HtERGZpu>0XQVByPT`B68Nhqi#?`QtbOjuK>o1>+r$6zZL;XsViv^{w-+HXm z=5Wvaf^}V|{pgxYC#U_~`93`Ti>LFdqa5;EQ?mqX)~rS#pe(@DE_b#8EBYF_2e4vF z9jxxsMDDs78`id?s$xl2Wl3$bW@VsvFM(G;>szu}F3R+be>;iD$a4q}J%w1P8vw_Q zP%6UlO1yr4Ee6JxA!RmzF`Zlm5fUSalc@xK&A?Ukx+=7Rke8@)2Tddtb(DM_((H@>En;Boip95DXHuvzrx%9X}=PIC%Ps6WZK| z>Pj!RzNZQ++R72|y7I6(6qn+S{uX%Z-jA~8`=NPi9I9&@Q;1FMLqsgnV#3Vy@JwhO z_o3(#oV(nKp@|lR6OFKuImJ3SBM|{*F8Vq8AEQ-!A|59fBpQz(5)NZzbSSeBbfjT5 z#?f4#z%}hrY+OHyn>K_H^jn3~rHsu0R8xZg7X~am@eg4>GGbkN=`c?~js*_uH^1(; zE!L{!qI0vZxzN6>jXI>*xw^=nS9)+@{{a9{U@fG&4Gs0^6wsEH5wvr&^oW4=1bE^M zU{BZ6I_Bm&4>qq4U|FLNUKi~XbNINN%!2K%gsb`{l(l_Q__;SrKQ~u*n~t5MBt&Ae z3yIJ{q+%xuDX#=Mmr)xWtH#)56(aF6#FN5O0i=u|(xzW1tuC$^k|~CiFvH^0E|qX8 z2+*_Xd#Q(G;PQHPY4_7>_vm0u{GJbnT%?A{~pZRbWnX$r{o_4Qar z(3Z^|+Kh50&k1Nx0;x;R24|4Udrgau4J$opt98Ne=8i0xd>XI>q$pnlfAhU4Z@dRC zUqfDT$uh$>rwH7*u;iqGc&eNBrV$IO`pSC=lJZ(ItqZ8#0#J=$EDKohdaa_r3^dQ> z?~qUyYzZV&sSN+;hY38lhoT>2d%AfD0N!@6e*Lkp`xr-Sz5+`%z~y$4OQ7p|e&-~W z6F&3HXUJbG4yvlUbvbCu%L&@Kn;8+%o&pl5!L4u}R>fVYt76!+M#J(3jtZZRV#8nn z_cg**b2I!)w!mMt3BHQ!p}Whn5ab89k&d4cihCUCsIb^c7((@p%)i4_GZ8= z4J+LghqbH6!jFEI#N}ZsI~;qlOM?1#gO$eD9{pMkIL{cklHMbu1VD33GtK!uK9O() z&p-D(E?vA-2+~rjON+PWmKH2sS_1&{12=sc$bg&bBlUFpwsQ7)fVG{#>NcQh3E+1X z2iMR5)8&S@VjX;y8{x0qBmlkv-m+^+b(O&_q!Vwzh@B8HABQ1;w$g*Jj6v9GVOAK7 z%^5~A%oA>BO{!C6kDucB!Ozlo<2=plzDyLOh$~(Tn#A2GPA{PQ`Dpb=}Tb7Wop17VO8CQ zGC#0k1+bz8sILS(dI4}XVLD*y!~zwJdxERs33S5a?}R(h0k^LMuFSQ+1DakApb*P3 z0qzjYG{H+C+hz!y$FnJDI}XsbFrJ{-88^UmKbYo+CJdSf+#Cb9hGCmSfE_6bt6?#b zG~n2?&qD7BE1NN7Na$${J=a4%5#H{w(s<;NN8Bbi+BxT%gj8*5qw6m6KfOK=L6e7e zbaWKYKl3~$Lm?$PFjv*BtgH~=HVIduHt%wjG-Y9EP5>Fz72q;sct$8poolOsjVpm= zO+Zxu@am9-fDA~x07Dor@m8#RY6QF)aND7|tD(Cp2w=@6Os@dT&f>m;AcURD!f9s> z`D>m8?5KcxK-hWM!YpF|4CbuL+J6z)cK|rhZ6O++{$(}Ad}V7F!jDS+-Vw0U`07`` zTwwzZ9HpQjqs&!BWu;^HWX6AerTefrRP1$FmZiWsSJf4uQvasLrUpv=Dv-``aRze) zjKCcNvqDZ-RkwlMyp9F|Z!^%m6j)jT1igUe0&E|^wfXp_^Y&Ng?9YZHz^Svs&Op4~ z1B1hkug3<%M9PEE-n|mMcN(lT9{%dX0f{6KPY8R-=ulDmKl=04omBtsp@>g}-Mpa3F5i(a@SzUqhvI+nMtHV7wf9^bvywXDr zZ)d=H)v7BBX9(KLs!CK;RM2Zz4KJAqW=%n}BVe|Gm*zagT!CeNP+#Tq>T?-9lQt07 zfP`Iv#52!GxZbU>5)@zf(iiH5T2?Bl*uo1PN*q)zsmg5YmeB$(vp2(ogXrx&j)8tU zhFk(VU)5FNrFP|20^G{VN{T7~xN2~n!cT?E+h*1 zq3?QF^INt~(J%Ci?pNFwobJq2VEV zT>`?^#pPNj=JzmFDaK4Ai20$avyrTqbhEiBH#3S<$#q-H-Q?X4PLs8O9K}%JTypq;0dUek&*5C1X@Gl>9xh!`ESigi* z1y{9vv9Oo?NnLj-u-Y>8MQzzfM}{ymG>VDwafHKDO4By&>Qz@YO%qD%hwk=H|FY>C z%kN8@XsoG>$;uEi4Vv5^!a2_tV}ThuY}2-NQyj5x&hm3#g!T6h?1K+7=GALymjN%n z=qlkZ&=Kx_e}I%M2dnBP$Y=toY-l1xhaOLfITDFbt4aV@tGbkU@c8_2d%R>EQ2t&n zUeHYATu)DrjjJ1rur7r07oYo!Am`-AdX%?+X(io-yg%uoql9#NPQsF(rQ*t&!?H{y z5=kUz^Irlfac!7J_8D8AR00if>29iP(CI)pU6{Ccdz4=iJ2!Lb!$yvF9~uIHMOfeF z+k=28kR-Hj5@Sz@*=XIn|jVi%6} z984|3`VJZoJn(>%m>j8w~`xjWTc^7oF z>J>R+z#jc=R~PxHi?A*ZrAX%Jsb0TkB4~r$1kWG%?cWw3rz~zy9zAr(z~Wehb*|&X zAO5i0)&;mW_u8C!!MRuZxeB23d;50+niL=6X$@1y_V0h!E9oMvzoV!^IGOZhA`0L< z3ooFHS+|8rkP87y!{U@z;3*C}p#ce>uBZ3z-Mje1ScLTtJGO7%&NNNaO<|ldjd5-p zwr!<@L96Gfrxw5Ai?A+^MOYWd;#h=raV(BSSQp14tczoDytU)s0cFIrAC%TSQUCw| M07*qoM6N<$f`k#04FCWD diff --git a/kcms/phonon/main.h b/kcms/phonon/main.h deleted file mode 100644 --- a/kcms/phonon/main.h +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006-2007 Matthias Kretz - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) version 3. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef MAIN_H -#define MAIN_H - -#include - -namespace Phonon { -class DevicePreference; -} -class BackendSelection; - -class QTabWidget; - -class PhononKcm : public KCModule -{ - Q_OBJECT -public: - PhononKcm(QWidget *parent, const QVariantList &); - - void load() override; - void save() override; - void defaults() override; - -private: - QTabWidget* m_tabs; - Phonon::DevicePreference *m_devicePreferenceWidget; - BackendSelection *m_backendSelection; -}; - -#endif // MAIN_H diff --git a/kcms/phonon/main.cpp b/kcms/phonon/main.cpp deleted file mode 100644 --- a/kcms/phonon/main.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2006-2007 Matthias Kretz - Copyright (C) 2010 Colin Guthrie - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) version 3. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "main.h" - -#include - -#include -#include -#include - -#include "backendselection.h" -#include "devicepreference.h" - -#include "config-workspace.h" - -K_PLUGIN_FACTORY(PhononKcmFactory, registerPlugin();) - -PhononKcm::PhononKcm(QWidget *parent, const QVariantList &args) - : KCModule(parent, args) -{ - KAboutData *about = new KAboutData( - "kcm_phonon", i18n("Phonon Configuration Module"), - WORKSPACE_VERSION_STRING, QString(), KAboutLicense::GPL, - i18n("Copyright 2006 Matthias Kretz")); - about->addAuthor(i18n("Matthias Kretz"), QString(), "kretz@kde.org"); - about->addAuthor(i18n("Colin Guthrie"), QString(), "colin@mageia.org"); - setAboutData(about); - - setLayout(new QHBoxLayout); - layout()->setContentsMargins(0, 0, 0, 0); - layout()->setSpacing(0); - - m_tabs = new QTabWidget(this); - layout()->addWidget(m_tabs); - - m_devicePreferenceWidget = new Phonon::DevicePreference(this); - m_tabs->addTab(m_devicePreferenceWidget, i18n("Device Preference")); - m_backendSelection = new BackendSelection(this); - m_tabs->addTab(m_backendSelection, i18n("Backend")); - - load(); - connect(m_backendSelection, SIGNAL(changed()), SLOT(changed())); - connect(m_devicePreferenceWidget, SIGNAL(changed()), SLOT(changed())); - - setButtons( KCModule::Default|KCModule::Apply|KCModule::Help ); -} - -void PhononKcm::load() -{ - m_devicePreferenceWidget->load(); - m_backendSelection->load(); -} - -void PhononKcm::save() -{ - m_devicePreferenceWidget->save(); - m_backendSelection->save(); -} - -void PhononKcm::defaults() -{ - m_devicePreferenceWidget->defaults(); - m_backendSelection->defaults(); -} - -#include "main.moc" diff --git a/plasma-desktop.categories b/plasma-desktop.categories deleted file mode 100644 --- a/plasma-desktop.categories +++ /dev/null @@ -1 +0,0 @@ -org.kde.kcm.phonon kcm module phonon IDENTIFIER [KCM_PHONON_LOG]