summaryrefslogtreecommitdiff
path: root/extra/kdemultimedia
diff options
context:
space:
mode:
authorParabola <dev@list.parabolagnulinux.org>2011-05-09 00:26:43 +0000
committerParabola <dev@list.parabolagnulinux.org>2011-05-09 00:26:43 +0000
commitd2f2d3b5c845807249680c275031f94047f9e762 (patch)
tree1237bb3dc8d677e2e405d11f905e143714638be8 /extra/kdemultimedia
parent886d3d0994eb8e9f3e797155619619e0ef1353f8 (diff)
Mon May 9 00:26:43 UTC 2011
Diffstat (limited to 'extra/kdemultimedia')
-rw-r--r--extra/kdemultimedia/kmix-locale-pulseaudio.patch1117
1 files changed, 0 insertions, 1117 deletions
diff --git a/extra/kdemultimedia/kmix-locale-pulseaudio.patch b/extra/kdemultimedia/kmix-locale-pulseaudio.patch
deleted file mode 100644
index 88be8dbde..000000000
--- a/extra/kdemultimedia/kmix-locale-pulseaudio.patch
+++ /dev/null
@@ -1,1117 +0,0 @@
-Index: kmix/apps/kmix.cpp
-===================================================================
---- kmix/apps/kmix.cpp (revision 1226955)
-+++ kmix/apps/kmix.cpp (revision 1226956)
-@@ -78,8 +78,6 @@
- m_dockWidget(),
- m_dontSetDefaultCardOnStart (false)
- {
-- _cornerLabelNew = 0;
--
- setObjectName( QLatin1String("KMixWindow" ));
- // disable delete-on-close because KMix might just sit in the background waiting for cards to be plugged in
- setAttribute(Qt::WA_DeleteOnClose, false);
-@@ -184,16 +182,29 @@
-
- void KMixWindow::initActionsAfterInitMixer()
- {
-+ bool isPulseAudio = false;
- // Add "launch_pavucontrol" to menu, if Pulseaudio backend is in use
- foreach( Mixer* mixer, Mixer::mixers() )
- {
-- if ( mixer->getDriverName() == "PulseAudio") {
-+ if ( mixer->getDriverName() == "PulseAudio")
-+ {
-+ isPulseAudio = true;
- KAction* action = actionCollection()->addAction( "launch_pavucontrol" );
- action->setText( i18n( "Audio setup (&Pulseaudio)" ) );
- connect(action, SIGNAL(triggered(bool) ), SLOT( slotPavucontrolExec() ));
- break;
- }
- }
-+
-+ if (! isPulseAudio )
-+ {
-+ QPixmap cornerNewPM = KIconLoader::global()->loadIcon( "tab-new", KIconLoader::Toolbar, KIconLoader::SizeSmall );
-+ QPushButton* _cornerLabelNew = new QPushButton();
-+ _cornerLabelNew->setIcon(cornerNewPM);
-+ //cornerLabelNew->setSizePolicy(QSizePolicy());
-+ m_wsMixers->setCornerWidget(_cornerLabelNew, Qt::TopLeftCorner);
-+ connect ( _cornerLabelNew, SIGNAL( clicked() ), SLOT (newView() ) );
-+ }
- }
-
- void KMixWindow::initPrefDlg()
-@@ -210,15 +221,10 @@
- m_wsMixers = new KTabWidget();
- m_wsMixers->setDocumentMode(true);
- setCentralWidget(m_wsMixers);
-- m_wsMixers->setTabsClosable(true);
-+ m_wsMixers->setTabsClosable(false);
- connect (m_wsMixers, SIGNAL(tabCloseRequested(int)), SLOT(saveAndCloseView(int)) );
-
- QPixmap cornerNewPM = KIconLoader::global()->loadIcon( "tab-new", KIconLoader::Toolbar, KIconLoader::SizeSmall );
-- _cornerLabelNew = new QPushButton();
-- _cornerLabelNew->setIcon(cornerNewPM);
-- //cornerLabelNew->setSizePolicy(QSizePolicy());
-- m_wsMixers->setCornerWidget(_cornerLabelNew, Qt::TopLeftCorner);
-- connect ( _cornerLabelNew, SIGNAL( clicked() ), SLOT (newView() ) );
-
- connect( m_wsMixers, SIGNAL( currentChanged ( int ) ), SLOT( newMixerShown(int)) );
-
-@@ -516,6 +522,7 @@
- addMixerWidget(mixer->id(), guiprof, -1);
- }
- else {
-+ // did exist => remove and insert new guiprof at old position
- int indexOfTab = m_wsMixers->indexOf(kmw);
- if ( indexOfTab != -1 ) m_wsMixers->removeTab(indexOfTab);
- delete kmw;
-@@ -676,9 +683,9 @@
- m_wsMixers->removeTab(idx);
- delete kmw;
-
-- if ( m_wsMixers->count() < 2 ) {
-- m_wsMixers->setTabsClosable(false);
-- }
-+ bool isPulseAudio = kmw->mixer()->getDriverName() == "PulseAudio";
-+ m_wsMixers->setTabsClosable(!isPulseAudio && m_wsMixers->count() > 1);
-+
- saveViewConfig();
- }
- kDebug() << "Exit";
-@@ -874,9 +881,9 @@
- if ( kmw->getGuiprof()->getId() == m_defaultCardOnStart ) {
- m_wsMixers->setCurrentWidget(kmw);
- }
-- if ( m_wsMixers->count() > 1 ) {
-- m_wsMixers->setTabsClosable(true);
-- }
-+
-+ bool isPulseAudio = mixer->getDriverName() == "PulseAudio";
-+ m_wsMixers->setTabsClosable(!isPulseAudio && m_wsMixers->count() > 1);
- m_dontSetDefaultCardOnStart = false;
-
-
-Index: kmix/apps/kmix.h
-===================================================================
---- kmix/apps/kmix.h (revision 1226955)
-+++ kmix/apps/kmix.h (revision 1226956)
-@@ -116,7 +116,6 @@
- Qt::Orientation m_toplevelOrientation;
-
- KTabWidget *m_wsMixers;
-- QPushButton* _cornerLabelNew;
-
- KMixPrefDlg *m_prefDlg;
- KMixDockWidget *m_dockWidget;
-Index: kmix/gui/viewbase.cpp
-===================================================================
---- kmix/gui/viewbase.cpp (revision 1226956)
-+++ kmix/gui/viewbase.cpp (revision 1226957)
-@@ -226,34 +226,35 @@
-
- // Check the guiprofile... if it is not the fallback GUIProfile, then
- // make sure that we add a specific entry for any devices not present.
-- if ( 0 != _guiprof && GUIProfile::fallbackProfile(_mixer) != _guiprof ) {
-+ if ( 0 != _guiprof && GUIProfile::fallbackProfile(_mixer) != _guiprof ) // TODO colin/cesken IMO calling GUIProfile::fallbackProfile(_mixer) is wrong, as it ALWAYS creates a new Object. fallbackProfile() would need to cache the created fallback profiles so this should make any sense.
-+ {
- kDebug(67100) << "Dynamic mixer " << _mixer->id() << " is NOT using Fallback GUIProfile. Checking to see if new controls are present";
-
- QList<QString> new_mix_devices;
- MixSet ms = _mixer->getMixSet();
- for (int i=0; i < ms.count(); ++i)
-+ {
- new_mix_devices.append("^" + ms[i]->id() + "$");
-+ kDebug(67100) << "new_mix_devices.append => " << ms[i]->id();
-+ }
-
-+ GUIProfile::ControlSet& ctlSet = _guiprof->getControls();
-+
- // std::vector<ProfControl*>::const_iterator itEnd = _guiprof->_controls.end();
- // for ( std::vector<ProfControl*>::const_iterator it = _guiprof->_controls.begin(); it != itEnd; ++it)
- // new_mix_devices.removeAll((*it)->id);
- // TODO Please check this change, Colin
-- foreach ( ProfControl* pctl, _guiprof->getControls() ) {
-+ foreach ( ProfControl* pctl, ctlSet ) {
- new_mix_devices.removeAll(pctl->id);
- }
-
-
- if ( new_mix_devices.count() > 0 ) {
- kDebug(67100) << "Found " << new_mix_devices.count() << " new controls. Adding to GUIProfile";
-+ QString sctlMatchAll("*");
- while ( new_mix_devices.count() > 0 ) {
-- QString sctlMatchAll("*");
- QString new_mix_devices0 = new_mix_devices.takeAt(0);
-- ProfControl* ctl = new ProfControl(new_mix_devices0, sctlMatchAll);
--// ctl->id = new_mix_devices.takeAt(0);
--// ctl->setSubcontrols(QString("*"));
--// ctl->tab = (_guiprof->tabs())[0]->name(); // Use the first tab... not ideal but should work most of the time;
--// ctl->show = "simple";
-- _guiprof->getControls().push_back(ctl);
-+ ctlSet.push_back(new ProfControl(new_mix_devices0, sctlMatchAll));
- }
- _guiprof->setDirty();
- }
-Index: kmix/gui/viewbase.cpp
-===================================================================
---- kmix/gui/viewbase.cpp (revision 1226957)
-+++ kmix/gui/viewbase.cpp (revision 1226958)
-@@ -33,6 +33,7 @@
- #include <kactioncollection.h>
- #include <ktoggleaction.h>
- #include <kstandardaction.h>
-+#include <kmessagebox.h>
- // KMix
- #include "dialogviewconfiguration.h"
- #include "gui/guiprofile.h"
-@@ -43,7 +44,7 @@
-
-
- ViewBase::ViewBase(QWidget* parent, const char* id, Mixer* mixer, Qt::WFlags f, ViewBase::ViewFlags vflags, GUIProfile *guiprof, KActionCollection *actionColletion)
-- : QWidget(parent, f), _actions(actionColletion), _vflags(vflags), _guiprof(guiprof)
-+ : QWidget(parent, f), _popMenu(NULL), _actions(actionColletion), _vflags(vflags), _guiprof(guiprof)
- {
- setObjectName(id);
- m_viewId = id;
-@@ -73,9 +74,11 @@
- }
- }
- }
-- QAction *action = _localActionColletion->addAction("toggle_channels");
-- action->setText(i18n("&Channels"));
-- connect(action, SIGNAL(triggered(bool) ), SLOT(configureView()));
-+ if ( !_mixer->isDynamic() ) {
-+ QAction *action = _localActionColletion->addAction("toggle_channels");
-+ action->setText(i18n("&Channels"));
-+ connect(action, SIGNAL(triggered(bool) ), SLOT(configureView()));
-+ }
- connect ( _mixer, SIGNAL(controlChanged()), this, SLOT(refreshVolumeLevels()) );
- connect ( _mixer, SIGNAL(controlsReconfigured(const QString&)), this, SLOT(controlsReconfigured(const QString&)) );
- }
-@@ -95,7 +98,7 @@
-
- bool ViewBase::isValid() const
- {
-- return ( _mixSet->count() > 0 || _mixer->dynamic() );
-+ return ( _mixSet->count() > 0 || _mixer->isDynamic() );
- }
-
- void ViewBase::setIcons (bool on) { KMixToolBox::setIcons (_mdws, on ); }
-@@ -170,6 +173,8 @@
- {
- QAction *a;
-
-+ if ( _popMenu )
-+ delete _popMenu;
- _popMenu = new KMenu( this );
- _popMenu->addTitle( KIcon( QLatin1String( "kmix" ) ), i18n("Device Settings" ));
-
-@@ -222,44 +227,8 @@
-
- void ViewBase::setMixSet()
- {
-- if ( _mixer->dynamic()) {
-+ if ( _mixer->isDynamic() ) {
-
-- // Check the guiprofile... if it is not the fallback GUIProfile, then
-- // make sure that we add a specific entry for any devices not present.
-- if ( 0 != _guiprof && GUIProfile::fallbackProfile(_mixer) != _guiprof ) // TODO colin/cesken IMO calling GUIProfile::fallbackProfile(_mixer) is wrong, as it ALWAYS creates a new Object. fallbackProfile() would need to cache the created fallback profiles so this should make any sense.
-- {
-- kDebug(67100) << "Dynamic mixer " << _mixer->id() << " is NOT using Fallback GUIProfile. Checking to see if new controls are present";
--
-- QList<QString> new_mix_devices;
-- MixSet ms = _mixer->getMixSet();
-- for (int i=0; i < ms.count(); ++i)
-- {
-- new_mix_devices.append("^" + ms[i]->id() + "$");
-- kDebug(67100) << "new_mix_devices.append => " << ms[i]->id();
-- }
--
-- GUIProfile::ControlSet& ctlSet = _guiprof->getControls();
--
--// std::vector<ProfControl*>::const_iterator itEnd = _guiprof->_controls.end();
--// for ( std::vector<ProfControl*>::const_iterator it = _guiprof->_controls.begin(); it != itEnd; ++it)
--// new_mix_devices.removeAll((*it)->id);
-- // TODO Please check this change, Colin
-- foreach ( ProfControl* pctl, ctlSet ) {
-- new_mix_devices.removeAll(pctl->id);
-- }
--
--
-- if ( new_mix_devices.count() > 0 ) {
-- kDebug(67100) << "Found " << new_mix_devices.count() << " new controls. Adding to GUIProfile";
-- QString sctlMatchAll("*");
-- while ( new_mix_devices.count() > 0 ) {
-- QString new_mix_devices0 = new_mix_devices.takeAt(0);
-- ctlSet.push_back(new ProfControl(new_mix_devices0, sctlMatchAll));
-- }
-- _guiprof->setDirty();
-- }
-- }
--
- // We need to delete the current MixDeviceWidgets so we can redraw them
- while (!_mdws.isEmpty()) {
- QWidget* mdw = _mdws.last();
-@@ -280,6 +249,8 @@
- */
- void ViewBase::configureView() {
-
-+ Q_ASSERT( !_mixer->isDynamic() );
-+
- DialogViewConfiguration* dvc = new DialogViewConfiguration(0, *this);
- dvc->show();
- // !! The dialog is modal. Does it delete itself?
-@@ -302,6 +273,10 @@
- kDebug(67100) << "KMixToolBox::loadView() grp=" << grp.toAscii();
-
- static char guiComplexity[3][20] = { "simple", "extended", "all" };
-+
-+ // Certain bits are not saved for dynamic mixers (e.g. PulseAudio)
-+ bool dynamic = _mixer->isDynamic();
-+
- for ( int tries = 0; tries < 3; tries++ )
- {
- bool atLeastOneControlIsShown = false;
-@@ -315,12 +290,12 @@
- Workaround: If found, write back correct group name.
- */
- MixDeviceWidget* mdw = (MixDeviceWidget*)qmdw;
-- QString devgrp;
-- devgrp.sprintf( "%s.%s.%s", grp.toAscii().data(), mdw->mixDevice()->mixer()->id().toAscii().data(), mdw->mixDevice()->id().toAscii().data() );
-+ MixDevice* md = mdw->mixDevice();
-+
-+ QString devgrp = QString("%1.%2.%3").arg(grp).arg(md->mixer()->id()).arg(md->id());
- KConfigGroup devcg = config->group( devgrp );
-
-- QString buggyDevgrp;
-- buggyDevgrp.sprintf( "%s.%s.%s", grp.toAscii().data(), view->id().toAscii().data(), mdw->mixDevice()->id().toAscii().data() );
-+ QString buggyDevgrp = QString("%1.%2.%3").arg(grp).arg(view->id()).arg(md->id());
- KConfigGroup buggyDevgrpCG = config->group( buggyDevgrp );
- if ( buggyDevgrpCG.exists() ) {
- buggyDevgrpCG.copyTo(&devcg);
-@@ -335,7 +310,7 @@
- }
-
- bool mdwEnabled = false;
-- if ( devcg.hasKey("Show") )
-+ if ( !dynamic && devcg.hasKey("Show") )
- {
- mdwEnabled = ( true == devcg.readEntry("Show", true) );
- //kDebug() << "Load devgrp" << devgrp << "show=" << mdwEnabled;
-@@ -382,20 +357,23 @@
- QString grp = "View.";
- grp += view->id();
- // KConfigGroup cg = config->group( grp );
-- kDebug(67100) << "KMixToolBox::saveView() grp=" << grp.toAscii();
-+ kDebug(67100) << "KMixToolBox::saveView() grp=" << grp;
-
-+ // Certain bits are not saved for dynamic mixers (e.g. PulseAudio)
-+ bool dynamic = _mixer->isDynamic();
-+
- for (int i=0; i < view->_mdws.count(); ++i ){
- QWidget *qmdw = view->_mdws[i];
- if ( qmdw->inherits("MixDeviceWidget") )
- {
- MixDeviceWidget* mdw = (MixDeviceWidget*)qmdw;
-+ MixDevice* md = mdw->mixDevice();
-
- //kDebug(67100) << " grp=" << grp.toAscii();
- //kDebug(67100) << " mixer=" << view->id().toAscii();
- //kDebug(67100) << " mdwPK=" << mdw->mixDevice()->id().toAscii();
-
-- QString devgrp;
-- devgrp.sprintf( "%s.%s.%s", grp.toAscii().data(), mdw->mixDevice()->mixer()->id().toAscii().data(), mdw->mixDevice()->id().toAscii().data() );
-+ QString devgrp = QString("%1.%2.%3").arg(grp).arg(md->mixer()->id()).arg(md->id());
- KConfigGroup devcg = config->group( devgrp );
-
- if ( mdw->inherits("MDWSlider") )
-@@ -403,15 +381,19 @@
- // only sliders have the ability to split apart in mutliple channels
- devcg.writeEntry( "Split", ! mdw->isStereoLinked() );
- }
-- devcg.writeEntry( "Show" , mdw->isVisibleTo(view) );
--kDebug() << "Save devgrp" << devgrp << "show=" << mdw->isVisibleTo(view);
-+ if ( !dynamic ) {
-+ devcg.writeEntry( "Show" , mdw->isVisibleTo(view) );
-+ kDebug() << "Save devgrp" << devgrp << "show=" << mdw->isVisibleTo(view);
-+ }
-
- } // inherits MixDeviceWidget
- } // for all MDW's
-
-- kDebug(67100) << "GUIProfile is dirty: " << guiProfile()->isDirty();
-- if ( guiProfile()->isDirty() ) {
-- guiProfile()->writeProfile();
-+ if ( !dynamic ) {
-+ // We do not save GUIProfiles (as they cannot be customised) for dynamic mixers (e.g. PulseAudio)
-+ kDebug(67100) << "GUIProfile is dirty: " << guiProfile()->isDirty();
-+ if ( guiProfile()->isDirty() )
-+ guiProfile()->writeProfile();
- }
- }
-
-Index: kmix/gui/mdwslider.cpp
-===================================================================
---- kmix/gui/mdwslider.cpp (revision 1226957)
-+++ kmix/gui/mdwslider.cpp (revision 1226958)
-@@ -86,10 +86,14 @@
- KToggleAction *taction = _mdwActions->add<KToggleAction>( "stereo" );
- taction->setText( i18n("&Split Channels") );
- connect( taction, SIGNAL( triggered(bool) ), SLOT( toggleStereoLinked() ) );
-- KAction *action = _mdwActions->add<KToggleAction>( "hide" );
-- action->setText( i18n("&Hide") );
-- connect( action, SIGNAL( triggered(bool) ), SLOT( setDisabled() ) );
-
-+ KAction *action;
-+ if ( ! m_mixdevice->mixer()->isDynamic() ) {
-+ action = _mdwActions->add<KToggleAction>( "hide" );
-+ action->setText( i18n("&Hide") );
-+ connect( action, SIGNAL( triggered(bool) ), SLOT( setDisabled() ) );
-+ }
-+
- if( m_mixdevice->playbackVolume().hasSwitch() ) {
- taction = _mdwActions->add<KToggleAction>( "mute" );
- taction->setText( i18n("&Muted") );
-@@ -129,8 +133,8 @@
- #ifdef __GNUC__
- #warning GLOBAL SHORTCUTS ARE NOW ASSIGNED TO ALL CONTROLS, as enableGlobalShortcut(), has not been committed
- #endif
-- if ( ! mixDevice()->isEthereal() ) {
-- // virtual / ethereal controls won't get shortcuts
-+ if ( ! mixDevice()->mixer()->isDynamic() ) {
-+ // virtual / dynamic controls won't get shortcuts
- b->setGlobalShortcut(dummyShortcut); // -<- enableGlobalShortcut() is not there => use workaround
- // b->enableGlobalShortcut();
- connect( b, SIGNAL( triggered(bool) ), SLOT( increaseVolume() ) );
-@@ -143,8 +147,8 @@
- #ifdef __GNUC__
- #warning GLOBAL SHORTCUTS ARE NOW ASSIGNED TO ALL CONTROLS, as enableGlobalShortcut(), has not been committed
- #endif
-- if ( ! mixDevice()->isEthereal() ) {
-- // virtual / ethereal controls won't get shortcuts
-+ if ( ! mixDevice()->mixer()->isDynamic() ) {
-+ // virtual / dynamic controls won't get shortcuts
- b->setGlobalShortcut(dummyShortcut); // -<- enableGlobalShortcut() is not there => use workaround
- // b->enableGlobalShortcut();
- connect( b, SIGNAL( triggered(bool) ), SLOT( decreaseVolume() ) );
-@@ -157,8 +161,8 @@
- #ifdef __GNUC__
- #warning GLOBAL SHORTCUTS ARE NOW ASSIGNED TO ALL CONTROLS, as enableGlobalShortcut(), has not been committed
- #endif
-- if ( ! mixDevice()->isEthereal() ) {
-- // virtual / ethereal controls won't get shortcuts
-+ if ( ! mixDevice()->mixer()->isDynamic() ) {
-+ // virtual / dynamic controls won't get shortcuts
- b->setGlobalShortcut(dummyShortcut); // -<- enableGlobalShortcut() is not there => use workaround
- // b->enableGlobalShortcut();
- connect( b, SIGNAL( triggered(bool) ), SLOT( toggleMuted() ) );
-Index: kmix/gui/viewdockareapopup.h
-===================================================================
---- kmix/gui/viewdockareapopup.h (revision 1226957)
-+++ kmix/gui/viewdockareapopup.h (revision 1226958)
-@@ -24,7 +24,6 @@
- #include "viewbase.h"
-
- class QGridLayout;
--class QPushButton;
- class QWidget;
-
- class Mixer;
-@@ -48,8 +47,6 @@
-
- protected:
- KMixWindow *_dock;
-- //MixDevice *_dockDevice;
-- QPushButton *_showPanelBox;
-
- void wheelEvent ( QWheelEvent * e );
- virtual void _setMixSet();
-Index: kmix/gui/viewsliders.cpp
-===================================================================
---- kmix/gui/viewsliders.cpp (revision 1226957)
-+++ kmix/gui/viewsliders.cpp (revision 1226958)
-@@ -148,7 +148,7 @@
- {
- const MixSet& mixset = _mixer->getMixSet();
-
-- if ( _mixer->dynamic() ) {
-+ if ( _mixer->isDynamic() ) {
- // We will be recreating our sliders, so make sure we trash all the separators too.
- qDeleteAll(_separators);
- _separators.clear();
-Index: kmix/gui/guiprofile.cpp
-===================================================================
---- kmix/gui/guiprofile.cpp (revision 1226957)
-+++ kmix/gui/guiprofile.cpp (revision 1226958)
-@@ -158,8 +158,12 @@
- {
- GUIProfile* guiprof = 0;
-
-- if ( mixer == 0 || profileName.isEmpty() ) {
-+ if ( mixer == 0 || profileName.isEmpty() )
- return 0;
-+
-+ if ( mixer->isDynamic() ) {
-+ kDebug(67100) << "GUIProfile::find() Not loading GUIProfile for Dynamic Mixer (e.g. PulseAudio)";
-+ return 0;
- }
-
- QString requestedProfileName;
-Index: kmix/gui/viewbase.h
-===================================================================
---- kmix/gui/viewbase.h (revision 1226957)
-+++ kmix/gui/viewbase.h (revision 1226958)
-@@ -133,7 +133,7 @@
-
- ViewFlags _vflags;
- GUIProfile* _guiprof;
-- KActionCollection *_localActionColletion;
-+ KActionCollection *_localActionColletion;
-
- virtual void _setMixSet() = 0;
-
-Index: kmix/gui/viewdockareapopup.cpp
-===================================================================
---- kmix/gui/viewdockareapopup.cpp (revision 1226957)
-+++ kmix/gui/viewdockareapopup.cpp (revision 1226958)
-@@ -88,8 +88,8 @@
- {
- // kDebug(67100) << "ViewDockAreaPopup::setMixSet()\n";
-
-- if ( _mixer->dynamic() ) {
-- // Our _layoutMDW now should only contain spacer widgets from the QSpacerItems's in add() below.
-+ if ( _mixer->isDynamic() ) {
-+ // Our _layoutMDW now should only contain spacer widgets from the QSpacerItem's in add() below.
- // We need to trash those too otherwise all sliders gradually migrate away from the edge :p
- QLayoutItem *li;
- while ( ( li = _layoutMDW->takeAt(0) ) )
-@@ -114,9 +114,9 @@
- QString matchAllPlaybackAndTheCswitch("pvolume,pswitch,cswitch");
- ProfControl *pctl = new ProfControl( dummyMatchAll, matchAllPlaybackAndTheCswitch);
- MixDeviceWidget *mdw = new MDWSlider(
-- md, // only 1 device. This is actually _dockDevice
-+ md, // only 1 device.
- true, // Show Mute LED
-- false, // Show Record LED
-+ false, // Show Record LED
- false, // Small
- Qt::Vertical, // Direction: only 1 device, so doesn't matter
- this, // parent
-@@ -128,10 +128,10 @@
- _layoutMDW->addWidget( mdw, 0, 1 );
-
- // Add button to show main panel
-- _showPanelBox = new QPushButton( i18n("Mixer"), this );
-- _showPanelBox->setObjectName( QLatin1String("MixerPanel" ));
-- connect ( _showPanelBox, SIGNAL( clicked() ), SLOT( showPanelSlot() ) );
-- _layoutMDW->addWidget( _showPanelBox, 1, 0, 1, 3 );
-+ QPushButton *pb = new QPushButton( i18n("Mixer"), this );
-+ pb->setObjectName( QLatin1String("MixerPanel" ));
-+ connect ( pb, SIGNAL( clicked() ), SLOT( showPanelSlot() ) );
-+ _layoutMDW->addWidget( pb, 1, 0, 1, 3 );
-
- return mdw;
- }
-Index: kmix/core/mixdevice.h
-===================================================================
---- kmix/core/mixdevice.h (revision 1226957)
-+++ kmix/core/mixdevice.h (revision 1226958)
-@@ -157,15 +157,6 @@
- _artificial = artificial;
- }
-
-- bool isEthereal() const
-- {
-- return _ethereal;
-- }
-- void setEthereal(bool _ethereal)
-- {
-- this->_ethereal = _ethereal;
-- }
--
- void setControlProfile(ProfControl* control);
- ProfControl* controlProfile();
-
-@@ -191,14 +182,12 @@
- int _enumCurrentId;
- QList<QString> _enumValues; // A MixDevice, that is an ENUM, has these _enumValues
-
-- //bool _doNotRestore;
- // A virtual control. It will not be saved/restored and/or doesn't get shortcuts
-- // Actually we discriminate those "virtual" controls in artificial controls and ethereal controls:
-+ // Actually we discriminate those "virtual" controls in artificial controls and dynamic controls:
- // Type Shortcut Restore
- // Artificial: yes no Virtual::GlobalMaster or Virtual::CaptureGroup_3 (controls that are constructed artificially from other controls)
-- // Ethereal : no no Controls that come and go, like Pulse Stream controls
-+ // Dynamic : no no Controls that come and go, like Pulse Stream controls
- bool _artificial;
-- bool _ethereal;
- MixSet *_moveDestinationMixSet;
- QString _iconName;
-
-Index: kmix/core/mixer.cpp
-===================================================================
---- kmix/core/mixer.cpp (revision 1226957)
-+++ kmix/core/mixer.cpp (revision 1226958)
-@@ -748,7 +748,7 @@
- m_dynamic = dynamic;
- }
-
--bool Mixer::dynamic()
-+bool Mixer::isDynamic()
- {
- return m_dynamic;
- }
-Index: kmix/core/mixer.h
-===================================================================
---- kmix/core/mixer.h (revision 1226957)
-+++ kmix/core/mixer.h (revision 1226958)
-@@ -164,7 +164,7 @@
-
- /// Says if we are dynamic (e.g. widgets can come and go)
- virtual void setDynamic( bool dynamic = true );
-- virtual bool dynamic();
-+ virtual bool isDynamic();
-
- virtual bool moveStream( const QString id, const QString& destId );
-
-Index: kmix/core/mixdevice.cpp
-===================================================================
---- kmix/core/mixdevice.cpp (revision 1226957)
-+++ kmix/core/mixdevice.cpp (revision 1226958)
-@@ -23,6 +23,7 @@
- #include <klocale.h>
-
- #include "core/mixdevice.h"
-+#include "core/mixer.h"
- #include "gui/guiprofile.h"
- #include "core/volume.h"
-
-@@ -96,14 +97,12 @@
-
- MixDevice::MixDevice( Mixer* mixer, const QString& id, const QString& name, const QString& iconName, MixSet* moveDestinationMixSet )
- {
-- // doNotRestore is superseded by the more generic concepts isEthereal(), isArtificial()
- init(mixer, id, name, iconName, moveDestinationMixSet);
- }
-
- void MixDevice::init( Mixer* mixer, const QString& id, const QString& name, const QString& iconName, MixSet* moveDestinationMixSet )
- {
- _artificial = false;
-- _ethereal = false;
- _mixer = mixer;
- _id = id;
- if( name.isEmpty() )
-@@ -117,9 +116,10 @@
- _moveDestinationMixSet = moveDestinationMixSet;
- if ( _id.contains(' ') ) {
- // The key is used in the config file. It MUST NOT contain spaces
-- kError(67100) << "MixDevice::setId(\"" << id << "\") . Invalid key - it might not contain spaces" << endl;
-+ kError(67100) << "MixDevice::setId(\"" << id << "\") . Invalid key - it must not contain spaces" << endl;
- _id.replace(' ', '_');
- }
-+ kDebug(67100) << "MixDevice::init() _id=" << _id;
- }
-
- void MixDevice::addPlaybackVolume(Volume &playbackVol)
-@@ -216,11 +216,10 @@
- */
- void MixDevice::read( KConfig *config, const QString& grp )
- {
-- if ( isEthereal() || isArtificial() ) {
-+ if ( _mixer->isDynamic() || isArtificial() ) {
- kDebug(67100) << "MixDevice::read(): This MixDevice does not permit volume restoration (i.e. because it is handled lower down in the audio stack). Ignoring.";
- } else {
-- QString devgrp;
-- devgrp.sprintf( "%s.Dev%s", grp.toAscii().data(), _id.toAscii().data() );
-+ QString devgrp = QString("%1.Dev%2").arg(grp).arg(_id);
- KConfigGroup cg = config->group( devgrp );
- //kDebug(67100) << "MixDevice::read() of group devgrp=" << devgrp;
-
-@@ -264,11 +263,10 @@
- */
- void MixDevice::write( KConfig *config, const QString& grp )
- {
-- if (isEthereal() || isArtificial()) {
-+ if (_mixer->isDynamic() || isArtificial()) {
- kDebug(67100) << "MixDevice::write(): This MixDevice does not permit volume saving (i.e. because it is handled lower down in the audio stack). Ignoring.";
- } else {
-- QString devgrp;
-- devgrp.sprintf( "%s.Dev%s", grp.toAscii().data(), _id.toAscii().data() );
-+ QString devgrp = QString("%1.Dev%2").arg(grp).arg(_id);
- KConfigGroup cg = config->group(devgrp);
- // kDebug(67100) << "MixDevice::write() of group devgrp=" << devgrp;
-
-Index: kmix/apps/kmix.cpp
-===================================================================
---- kmix/apps/kmix.cpp (revision 1226957)
-+++ kmix/apps/kmix.cpp (revision 1226958)
-@@ -182,21 +182,20 @@
-
- void KMixWindow::initActionsAfterInitMixer()
- {
-- bool isPulseAudio = false;
-- // Add "launch_pavucontrol" to menu, if Pulseaudio backend is in use
-+ // Only show the new tab widget if some of the mixers are not Dynamic.
-+ // The GUI that then pops up could then make a new mixer from a dynamic one,
-+ // if mixed dynamic and non-dynamic mixers were allowed, but this is generally not the case.
-+ bool allDynamic = true;
- foreach( Mixer* mixer, Mixer::mixers() )
- {
-- if ( mixer->getDriverName() == "PulseAudio")
-+ if ( !mixer->isDynamic() )
- {
-- isPulseAudio = true;
-- KAction* action = actionCollection()->addAction( "launch_pavucontrol" );
-- action->setText( i18n( "Audio setup (&Pulseaudio)" ) );
-- connect(action, SIGNAL(triggered(bool) ), SLOT( slotPavucontrolExec() ));
-+ allDynamic = false;
- break;
- }
- }
-
-- if (! isPulseAudio )
-+ if (! allDynamic )
- {
- QPixmap cornerNewPM = KIconLoader::global()->loadIcon( "tab-new", KIconLoader::Toolbar, KIconLoader::SizeSmall );
- QPushButton* _cornerLabelNew = new QPushButton();
-@@ -339,8 +338,11 @@
-
- // The following loop is necessary for the case that the user has hidden all views for a Mixer instance.
- // Otherwise we would not save the Meta information (step -2- below for that mixer.
-- foreach ( Mixer* mixer, Mixer::mixers() )
-- mixerViews[mixer->id()]; // just insert a map entry
-+ // We also do not save dynamic mixers (e.g. PulseAudio)
-+ foreach ( Mixer* mixer, Mixer::mixers() ) {
-+ if ( !mixer->isDynamic() )
-+ mixerViews[mixer->id()]; // just insert a map entry
-+ }
-
- // -1- Save the views themselves
- for ( int i=0; i<m_wsMixers->count() ; ++i ) {
-@@ -351,8 +353,10 @@
- // Otherwise the user will be confused afer re-plugging the card (as the config was not saved).
- mw->saveConfig( KGlobal::config().data() );
- // add the view to the corresponding mixer list, so we can save a views-per-mixer list below
-- QStringList& qsl = mixerViews[mw->mixer()->id()];
-- qsl.append(mw->getGuiprof()->getId());
-+ if ( !mw->mixer()->isDynamic() ) {
-+ QStringList& qsl = mixerViews[mw->mixer()->id()];
-+ qsl.append(mw->getGuiprof()->getId());
-+ }
- }
- }
-
-@@ -539,22 +543,29 @@
- continue; // OK, this mixer already has a profile => skip it
- }
- // No TAB YET => This should mean KMix is just started, or the user has just plugged in a card
-- bool profileListHasKey = pconfig.hasKey( mixer->id() ); // <<< SHOULD be before the following line
-- QStringList profileList = pconfig.readEntry( mixer->id(), QStringList() );
-+ bool profileListHasKey = false;
-+ QStringList profileList;
-+ bool aProfileWasAddedSucesufully = false;
-
-- bool aProfileWasAddedSucesufully = false;
-- foreach ( QString profileId, profileList)
-- {
-- // This handles the profileList form the kmixrc
-- kDebug() << "Now searching for profile: " << profileId ;
-- GUIProfile* guiprof = GUIProfile::find(mixer, profileId, true, false); // ### Card specific profile ###
-- if ( guiprof != 0 ) {
-- addMixerWidget(mixer->id(), guiprof, -1);
-- aProfileWasAddedSucesufully = true;
-+ if ( !mixer->isDynamic() ) {
-+ // We do not support save profiles for dynamic mixers (i.e. PulseAudio)
-+
-+ profileListHasKey = pconfig.hasKey( mixer->id() ); // <<< SHOULD be before the following line
-+ profileList = pconfig.readEntry( mixer->id(), QStringList() );
-+
-+ foreach ( QString profileId, profileList)
-+ {
-+ // This handles the profileList form the kmixrc
-+ kDebug() << "Now searching for profile: " << profileId ;
-+ GUIProfile* guiprof = GUIProfile::find(mixer, profileId, true, false); // ### Card specific profile ###
-+ if ( guiprof != 0 ) {
-+ addMixerWidget(mixer->id(), guiprof, -1);
-+ aProfileWasAddedSucesufully = true;
-+ }
-+ else {
-+ kError() << "Cannot load profile " << profileId << " . It was removed by the user, or the KMix config file is defective.";
-+ }
- }
-- else {
-- kError() << "Cannot load profile " << profileId << " . It was removed by the user, or the KMix config file is defective.";
-- }
- }
-
- // The we_need_a_fallback case is a bit tricky. Please ask the author (cesken) before even considering to change the code.
-@@ -568,11 +579,17 @@
-
- // Lets try a bunch of fallback strategies:
- GUIProfile* guiprof = 0;
-+ if ( !mixer->isDynamic() ) {
-+ // We know that GUIProfile::find() will return 0 if the mixer is dynamic, so don't bother checking.
-+ kDebug() << "Attempting to find a card-specific GUI Profile for the mixer " << mixer->id();
- guiprof = GUIProfile::find(mixer, QString("default"), false, false); // ### Card specific profile ###
-- if ( guiprof == 0 ) {
-- guiprof = GUIProfile::find(mixer, QString("default"), false, true); // ### Card unspecific profile ###
-+ if ( guiprof == 0 ) {
-+ kDebug() << "Not found. Attempting to find a generic GUI Profile for the mixer " << mixer->id();
-+ guiprof = GUIProfile::find(mixer, QString("default"), false, true); // ### Card unspecific profile ###
-+ }
- }
- if ( guiprof == 0) {
-+ kDebug() << "Using fallback GUI Profile for the mixer " << mixer->id();
- // This means there is neither card specific nor card unspecific profile
- // This is the case for some backends (as they don't ship profiles).
- guiprof = GUIProfile::fallbackProfile(mixer);
-@@ -683,8 +700,7 @@
- m_wsMixers->removeTab(idx);
- delete kmw;
-
-- bool isPulseAudio = kmw->mixer()->getDriverName() == "PulseAudio";
-- m_wsMixers->setTabsClosable(!isPulseAudio && m_wsMixers->count() > 1);
-+ m_wsMixers->setTabsClosable(!kmw->mixer()->isDynamic() && m_wsMixers->count() > 1);
-
- saveViewConfig();
- }
-@@ -882,8 +898,7 @@
- m_wsMixers->setCurrentWidget(kmw);
- }
-
-- bool isPulseAudio = mixer->getDriverName() == "PulseAudio";
-- m_wsMixers->setTabsClosable(!isPulseAudio && m_wsMixers->count() > 1);
-+ m_wsMixers->setTabsClosable(!mixer->isDynamic() && m_wsMixers->count() > 1);
- m_dontSetDefaultCardOnStart = false;
-
-
-@@ -1071,12 +1086,6 @@
- KMessageBox::information( 0, m_hwInfoString, i18n("Mixer Hardware Information") );
- }
-
--void KMixWindow::slotPavucontrolExec()
--{
-- QStringList args("pavucontrol");
-- forkExec(args);
--}
--
- void KMixWindow::slotKdeAudioSetupExec()
- {
- QStringList args;
-@@ -1133,6 +1142,12 @@
- m_defaultCardOnStart = kmw->getGuiprof()->getId();
- // As switching the tab does NOT mean switching the master card, we do not need to update dock icon here.
- // It would lead to unnecesary flickering of the (complete) dock area.
-+
-+ // We only show the "Configure Channels..." menu item if the mixer is not dynamic
-+ ViewBase* view = kmw->currentView();
-+ QAction* action = actionCollection()->action( "toggle_channels_currentview" );
-+ if (view && action)
-+ action->setVisible( !view->getMixer()->isDynamic() );
- }
- }
-
-Index: kmix/apps/kmix.h
-===================================================================
---- kmix/apps/kmix.h (revision 1226957)
-+++ kmix/apps/kmix.h (revision 1226958)
-@@ -136,7 +136,6 @@
- private slots:
- void saveConfig();
- void slotHWInfo();
-- void slotPavucontrolExec();
- void slotKdeAudioSetupExec();
- void slotConfigureCurrentView();
- void slotSelectMaster();
-Index: kmix/kmixui.rc
-===================================================================
---- kmix/kmixui.rc (revision 1226957)
-+++ kmix/kmixui.rc (revision 1226958)
-@@ -17,7 +17,6 @@
- <Action name="toggle_channels_currentview" append="save_merge"/>
- <Action name="select_master" append="save_merge"/>
- <Action name="launch_kdesoundsetup" append="save_merge"/>
-- <Action name="launch_pavucontrol" append="save_merge"/>
- </Menu>
- <Menu name="help" append="about_merge"><text>&amp;Help</text>
- <Action name="hwinfo"/>
-Index: kmix/backends/mixer_backend.cpp
-===================================================================
---- kmix/backends/mixer_backend.cpp (revision 1226957)
-+++ kmix/backends/mixer_backend.cpp (revision 1226958)
-@@ -48,7 +48,7 @@
- bool Mixer_Backend::openIfValid() {
- bool valid = false;
- int ret = open();
-- if ( ret == 0 && (m_mixDevices.count() > 0 || _mixer->dynamic())) {
-+ if ( ret == 0 && (m_mixDevices.count() > 0 || _mixer->isDynamic())) {
- valid = true;
- // A better ID is now calculated in mixertoolbox.cpp, and set via setID(),
- // but we want a somehow usable fallback just in case.
-@@ -139,7 +139,7 @@
- return m_mixDevices.at(0); // Backend has NOT set a recommended master. Evil backend => lets help out.
- } //first device (if exists)
- else {
-- if ( !_mixer->dynamic()) {
-+ if ( !_mixer->isDynamic()) {
- // This should never ever happen, as KMix doe NOT accept soundcards without controls
- kError(67100) << "Mixer_Backend::recommendedMaster(): returning invalid master. This is a bug in KMix. Please file a bug report stating how you produced this." << endl;
- }
-Index: kmix/backends/mixer_pulse.cpp
-===================================================================
---- kmix/backends/mixer_pulse.cpp (revision 1226957)
-+++ kmix/backends/mixer_pulse.cpp (revision 1226958)
-@@ -36,6 +36,8 @@
- #define KMIXPA_APP_CAPTURE 3
- #define KMIXPA_WIDGET_MAX KMIXPA_APP_CAPTURE
-
-+#define KMIXPA_EVENT_KEY "sink-input-by-media-role:event"
-+
- static unsigned int refcount = 0;
- static pa_glib_mainloop *s_mainloop = NULL;
- static pa_context *s_context = NULL;
-@@ -189,7 +191,7 @@
-
- devinfo s;
- s.index = s.device_index = i->index;
-- s.name = QString(i->name).replace(' ', '_');
-+ s.name = QString::fromUtf8(i->name).replace(' ', '_');
- s.description = QString::fromUtf8(i->description);
- s.icon_name = QString::fromUtf8(pa_proplist_gets(i->proplist, PA_PROP_DEVICE_ICON_NAME));
- s.volume = i->volume;
-@@ -242,7 +244,7 @@
-
- devinfo s;
- s.index = s.device_index = i->index;
-- s.name = QString(i->name).replace(' ', '_');
-+ s.name = QString::fromUtf8(i->name).replace(' ', '_');
- s.description = QString::fromUtf8(i->description);
- s.icon_name = QString::fromUtf8(pa_proplist_gets(i->proplist, PA_PROP_DEVICE_ICON_NAME));
- s.volume = i->volume;
-@@ -307,26 +309,28 @@
-
- const char *t;
- if ((t = pa_proplist_gets(i->proplist, "module-stream-restore.id"))) {
-- if (strcmp(t, "sink-input-by-media-role:event") == 0) {
-+ if (strcmp(t, KMIXPA_EVENT_KEY) == 0) {
- kWarning(67100) << "Ignoring sink-input due to it being designated as an event and thus handled by the Event slider";
- return;
- }
- }
-
-- QString prefix = QString("%1: ").arg(i18n("Unknown Application"));
-+ QString appname = i18n("Unknown Application");
- if (clients.contains(i->client))
-- prefix = QString("%1: ").arg(clients[i->client]);
-+ appname = clients[i->client];
-
-+ QString prefix = QString("%1: ").arg(appname);
-+
- devinfo s;
- s.index = i->index;
- s.device_index = i->sink;
- s.description = prefix + QString::fromUtf8(i->name);
-- s.name = QString("stream:") + i->index;
-+ s.name = QString("stream:") + QString::number(i->index); //appname.replace(' ', '_').toLower();
- s.icon_name = getIconNameFromProplist(i->proplist);
- s.volume = i->volume;
- s.channel_map = i->channel_map;
- s.mute = !!i->mute;
-- s.stream_restore_rule = t;
-+ s.stream_restore_rule = QString::fromUtf8(t);
-
- translateMasksAndMaps(s);
-
-@@ -370,22 +374,24 @@
- return;
- }
-
-- QString prefix = QString("%1: ").arg(i18n("Unknown Application"));
-+ QString appname = i18n("Unknown Application");
- if (clients.contains(i->client))
-- prefix = QString("%1: ").arg(clients[i->client]);
-+ appname = clients[i->client];
-
-+ QString prefix = QString("%1: ").arg(appname);
-+
- devinfo s;
- s.index = i->index;
- s.device_index = i->source;
- s.description = prefix + QString::fromUtf8(i->name);
-- s.name = QString("stream:") + i->index;
-+ s.name = QString("stream:") + QString::number(i->index); //appname.replace(' ', '_').toLower();
- s.icon_name = getIconNameFromProplist(i->proplist);
- //s.volume = i->volume;
- s.volume = captureDevices[i->source].volume;
- s.channel_map = i->channel_map;
- //s.mute = !!i->mute;
- s.mute = captureDevices[i->source].mute;
-- s.stream_restore_rule = pa_proplist_gets(i->proplist, "module-stream-restore.id");
-+ s.stream_restore_rule = QString::fromUtf8(pa_proplist_gets(i->proplist, "module-stream-restore.id"));
-
- translateMasksAndMaps(s);
-
-@@ -407,7 +413,7 @@
- }
-
-
--static devinfo create_role_devinfo(const char* name) {
-+static devinfo create_role_devinfo(QString name) {
-
- Q_ASSERT(s_RestoreRules.contains(name));
-
-@@ -436,9 +442,10 @@
-
- if (eol > 0) {
- dec_outstanding(c);
-+
- // Special case: ensure that our media events exists.
- // On first login by a new users, this wont be in our database so we should create it.
-- if (!outputRoles.contains(PA_INVALID_INDEX)) {
-+ if (!s_RestoreRules.contains(KMIXPA_EVENT_KEY)) {
- // Create a fake rule
- restoreRule rule;
- rule.channel_map.channels = 1;
-@@ -447,37 +454,56 @@
- rule.volume.values[0] = PA_VOLUME_NORM;
- rule.mute = false;
- rule.device = "";
-- s_RestoreRules["sink-input-by-media-role:event"] = rule;
-+ s_RestoreRules[KMIXPA_EVENT_KEY] = rule;
-+ kDebug(67100) << "Initialising restore rule for new user: " << i18n("Event Sounds");
-+ }
-
-- devinfo s = create_role_devinfo("sink-input-by-media-role:event");
-- outputRoles[s.index] = s;
-- kDebug(67100) << "Initialising restore rule for new user: " << s.description;
-+ if (s_mixers.contains(KMIXPA_APP_PLAYBACK)) {
-+ // If we have rules, it will be created below... but if no rules
-+ // then we add it here.
-+ if (!outputRoles.contains(PA_INVALID_INDEX)) {
-+ devinfo s = create_role_devinfo(KMIXPA_EVENT_KEY);
-+ outputRoles[s.index] = s;
-
-- if (s_mixers.contains(KMIXPA_APP_PLAYBACK))
- s_mixers[KMIXPA_APP_PLAYBACK]->addWidget(s.index);
-+ }
-+
-+ s_mixers[KMIXPA_APP_PLAYBACK]->triggerUpdate();
- }
-
-- if (s_mixers.contains(KMIXPA_APP_PLAYBACK))
-- s_mixers[KMIXPA_APP_PLAYBACK]->triggerUpdate();
- return;
- }
-
-- kDebug(67100) << "Got some info about restore rule: " << i->name << i->device;
-+
-+ QString name = QString::fromUtf8(i->name);
-+ kDebug(67100) << QString("Got some info about restore rule: '%1' (Device: %2)").arg(name).arg(i->device ? i->device : "None");
- restoreRule rule;
- rule.channel_map = i->channel_map;
- rule.volume = i->volume;
- rule.mute = !!i->mute;
- rule.device = i->device;
-- s_RestoreRules[i->name] = rule;
-
-- // We only want to know about Sound Events for now...
-- if (strcmp(i->name, "sink-input-by-media-role:event") == 0) {
-- devinfo s = create_role_devinfo(i->name);
-- bool is_new = !outputRoles.contains(s.index);
-- outputRoles[s.index] = s;
-+ if (rule.channel_map.channels < 1 && name == KMIXPA_EVENT_KEY) {
-+ // Stream restore rules may not have valid volumes/channel maps (as these are optional)
-+ // but we need a valid volume+channelmap for our events sounds so fix it up.
-+ rule.channel_map.channels = 1;
-+ rule.channel_map.map[0] = PA_CHANNEL_POSITION_MONO;
-+ rule.volume.channels = 1;
-+ rule.volume.values[0] = PA_VOLUME_NORM;
-+ }
-
-- if (is_new && s_mixers.contains(KMIXPA_APP_PLAYBACK))
-- s_mixers[KMIXPA_APP_PLAYBACK]->addWidget(s.index);
-+ s_RestoreRules[name] = rule;
-+
-+ if (s_mixers.contains(KMIXPA_APP_PLAYBACK)) {
-+ // We only want to know about Sound Events for now...
-+ if (name == KMIXPA_EVENT_KEY) {
-+ devinfo s = create_role_devinfo(name);
-+ bool is_new = !outputRoles.contains(s.index);
-+ outputRoles[s.index] = s;
-+
-+ if (is_new)
-+ s_mixers[KMIXPA_APP_PLAYBACK]->addWidget(s.index);
-+ }
- }
- }
-
-@@ -788,7 +814,6 @@
- Volume v(dev.chanMask, PA_VOLUME_NORM, PA_VOLUME_MUTED, true, false);
- setVolumeFromPulse(v, dev);
- MixDevice* md = new MixDevice( _mixer, dev.name, dev.description, dev.icon_name, ms);
-- md->setEthereal(true);
- md->addPlaybackVolume(v);
- md->setMuted(dev.mute);
- m_mixDevices.append(md);
-@@ -1095,10 +1120,10 @@
- {
- restoreRule &rule = s_RestoreRules[iter->stream_restore_rule];
- pa_ext_stream_restore_info info;
-- info.name = iter->stream_restore_rule.toAscii().constData();
-+ info.name = iter->stream_restore_rule.toUtf8().constData();
- info.channel_map = rule.channel_map;
- info.volume = genVolumeForPulse(*iter, md->playbackVolume());
-- info.device = rule.device.isEmpty() ? NULL : rule.device.toAscii().constData();
-+ info.device = rule.device.isEmpty() ? NULL : rule.device.toUtf8().constData();
- info.mute = (md->isMuted() ? 1 : 0);
-
- pa_operation* o;
-@@ -1153,13 +1178,13 @@
-
- // Lookup the stream index.
- uint32_t stream_index = PA_INVALID_INDEX;
-- const char* stream_restore_rule = NULL;
-+ QString stream_restore_rule = "";
- devmap::iterator iter;
- devmap *map = get_widget_map(m_devnum);
- for (iter = map->begin(); iter != map->end(); ++iter) {
- if (iter->name == id) {
- stream_index = iter->index;
-- stream_restore_rule = iter->stream_restore_rule.isEmpty() ? NULL : iter->stream_restore_rule.toAscii().constData();
-+ stream_restore_rule = iter->stream_restore_rule;
- break;
- }
- }
-@@ -1171,12 +1196,12 @@
-
- if (destId.isEmpty()) {
- // We want to remove any specific device in the stream restore rule.
-- if (!stream_restore_rule || !s_RestoreRules.contains(stream_restore_rule)) {
-+ if (stream_restore_rule.isEmpty() || !s_RestoreRules.contains(stream_restore_rule)) {
- kWarning(67100) << "Mixer_PULSE::moveStream(): Trying to set Automatic on a stream with no rule";
- } else {
- restoreRule &rule = s_RestoreRules[stream_restore_rule];
- pa_ext_stream_restore_info info;
-- info.name = stream_restore_rule;
-+ info.name = stream_restore_rule.toUtf8().constData();
- info.channel_map = rule.channel_map;
- info.volume = rule.volume;
- info.device = NULL;
-@@ -1192,12 +1217,12 @@
- } else {
- pa_operation* o;
- if (KMIXPA_APP_PLAYBACK == m_devnum) {
-- if (!(o = pa_context_move_sink_input_by_name(s_context, stream_index, destId.toAscii().constData(), NULL, NULL))) {
-+ if (!(o = pa_context_move_sink_input_by_name(s_context, stream_index, destId.toUtf8().constData(), NULL, NULL))) {
- kWarning(67100) << "pa_context_move_sink_input_by_name() failed";
- return false;
- }
- } else {
-- if (!(o = pa_context_move_source_output_by_name(s_context, stream_index, destId.toAscii().constData(), NULL, NULL))) {
-+ if (!(o = pa_context_move_source_output_by_name(s_context, stream_index, destId.toUtf8().constData(), NULL, NULL))) {
- kWarning(67100) << "pa_context_move_source_output_by_name() failed";
- return false;
- }