Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 444668 | Differences between
and this patch

Collapse All | Expand All

(-)a/apps/kmix.cpp (-9 / +12 lines)
Lines 313-332 Link Here
313
 */
313
 */
314
bool KMixWindow::updateDocking()
314
bool KMixWindow::updateDocking()
315
{
315
{
316
    // delete old dock widget
316
    kDebug();
317
    if (m_dockWidget)
318
    {
319
        // If this is called during a master control change, the dock widget is currently active, so we use deleteLater().
320
        m_dockWidget->deleteLater();
321
        m_dockWidget = 0L;
322
    }
323
317
324
    if ( m_showDockWidget == false || Mixer::mixers().count() == 0 ) {
318
    if ( m_showDockWidget == false || Mixer::mixers().count() == 0 ) {
319
        if (m_dockWidget) { // Config update: we are not supposed to have one, but we have one.
320
            m_dockWidget->deleteLater();
321
            m_dockWidget = 0;
322
        }
325
        return false;
323
        return false;
326
    }
324
    }
327
325
328
    m_dockWidget = new KMixDockWidget( this, m_volumeWidget );  // Could be optimized, by refreshing instead of recreating.
326
    if (!m_dockWidget) {
329
    connect(m_dockWidget, SIGNAL(newMasterSelected()), SLOT(saveConfig()) );
327
        m_dockWidget = new KMixDockWidget( this, m_volumeWidget );  // Could be optimized, by refreshing instead of recreating.
328
        connect(m_dockWidget, SIGNAL(newMasterSelected()), SLOT(saveConfig()) );
329
    } else {
330
        m_dockWidget->update();
331
    }
332
330
    return true;
333
    return true;
331
}
334
}
332
335
(-)a/gui/kmixdockwidget.h (-3 / +31 lines)
Lines 24-30 Link Here
24
#define KMIXDOCKWIDGET_H
24
#define KMIXDOCKWIDGET_H
25
25
26
class QString;
26
class QString;
27
#include <QWidget>
28
class QWidgetAction;
27
class QWidgetAction;
29
#include <kstatusnotifieritem.h>
28
#include <kstatusnotifieritem.h>
30
29
Lines 33-38 Link Here
33
class ViewDockAreaPopup;
32
class ViewDockAreaPopup;
34
class Volume;
33
class Volume;
35
34
35
/**
36
 * @brief The MetaMixer class provides a solid wrapper around a possible changing mixer.
37
 *
38
 * The primay use of this class is to provide one instance to connect slots to
39
 * while the underlying object that triggers the signals can be changing.
40
 * Additionally it nicely hides the rewiring logic that is going on in the back.
41
 */
42
class MetaMixer : public QObject
43
{
44
    Q_OBJECT
45
public:
46
    MetaMixer() : m_mixer(0) {}
47
48
    /**
49
     * @brief rewires against current master mixer
50
     * @note this also triggers all signals to ensure UI updates are done accordingly
51
     */
52
    void reset();
53
54
    Mixer *mixer() const { return m_mixer; }
55
    bool hasMixer() const { return m_mixer; }
56
57
signals:
58
    void controlChanged();
59
60
private:
61
    Mixer *m_mixer;
62
};
63
36
namespace Phonon
64
namespace Phonon
37
{
65
{
38
    class MediaObject;
66
    class MediaObject;
Lines 51-56 Link Here
51
   void setErrorPixmap();
79
   void setErrorPixmap();
52
   void ignoreNextEvent();
80
   void ignoreNextEvent();
53
   //ViewDockAreaPopup* getDockAreaPopup();
81
   //ViewDockAreaPopup* getDockAreaPopup();
82
   void update();
54
83
55
 signals:
84
 signals:
56
   void newMasterSelected();
85
   void newMasterSelected();
Lines 77-83 Link Here
77
   char _oldPixmapType;
106
   char _oldPixmapType;
78
   bool _volumePopup;
107
   bool _volumePopup;
79
   KMixWindow* _kmixMainWindow;
108
   KMixWindow* _kmixMainWindow;
80
   Mixer *m_mixer;
109
   MetaMixer m_metaMixer;
81
110
82
   bool _contextMenuWasOpen;
111
   bool _contextMenuWasOpen;
83
112
Lines 89-95 Link Here
89
   void selectMaster();
118
   void selectMaster();
90
   void handleNewMaster(QString& soundcard_id, QString& channel_id);
119
   void handleNewMaster(QString& soundcard_id, QString& channel_id);
91
   void contextMenuAboutToShow();
120
   void contextMenuAboutToShow();
92
   void activateMenuOrWindow(bool, const QPoint &);
93
};
121
};
94
122
95
#endif
123
#endif
(-)a/gui/kmixdockwidget.cpp (-88 / +56 lines)
Lines 25-49 Link Here
25
25
26
#include <kaction.h>
26
#include <kaction.h>
27
#include <klocale.h>
27
#include <klocale.h>
28
#include <kapplication.h>
29
#include <kmenu.h>
28
#include <kmenu.h>
30
#include <kurl.h>
31
#include <kglobalsettings.h>
32
#include <kdialog.h>
33
#include <kiconloader.h>
34
#include <kdebug.h>
29
#include <kdebug.h>
35
#include <kwindowsystem.h>
30
#include <kwindowsystem.h>
36
#include <kactioncollection.h>
31
#include <kactioncollection.h>
37
#include <ktoggleaction.h>
32
#include <ktoggleaction.h>
38
#include <qapplication.h>
39
#include <qcursor.h>
40
#include <QDesktopWidget>
33
#include <QDesktopWidget>
41
#include <QMouseEvent>
34
#include <QApplication>
42
43
#ifdef Q_WS_X11
44
#include <fixx11h.h>
45
#endif
46
47
#include <Phonon/MediaObject>
35
#include <Phonon/MediaObject>
48
36
49
#include "gui/dialogselectmaster.h"
37
#include "gui/dialogselectmaster.h"
Lines 53-61 Link Here
53
#include "core/mixertoolbox.h"
41
#include "core/mixertoolbox.h"
54
#include "gui/viewdockareapopup.h"
42
#include "gui/viewdockareapopup.h"
55
43
44
void MetaMixer::reset()
45
{
46
    disconnect(m_mixer, SIGNAL(controlChanged()), this, SIGNAL(controlChanged()));
47
    m_mixer = Mixer::getGlobalMasterMixer();
48
    m_mixer->readSetFromHWforceUpdate();
49
    connect(m_mixer, SIGNAL(controlChanged()), this, SIGNAL(controlChanged()));
50
    emit controlChanged(); // Triggers UI updates accordingly
51
}
52
56
KMixDockWidget::KMixDockWidget(KMixWindow* parent, bool volumePopup)
53
KMixDockWidget::KMixDockWidget(KMixWindow* parent, bool volumePopup)
57
    : KStatusNotifierItem(parent)
54
    : KStatusNotifierItem(parent)
58
  //  : KStatusNotifierItem(0)
59
    , _audioPlayer(0L)
55
    , _audioPlayer(0L)
60
    , _playBeepOnVolumeChange(false) // disabled due to triggering a "Bug"
56
    , _playBeepOnVolumeChange(false) // disabled due to triggering a "Bug"
61
    , _oldToolTipValue(-1)
57
    , _oldToolTipValue(-1)
Lines 68-90 Link Here
68
    setTitle(i18n( "Volume Control"));
64
    setTitle(i18n( "Volume Control"));
69
    setCategory(Hardware);
65
    setCategory(Hardware);
70
    setStatus(Active);
66
    setStatus(Active);
71
    m_mixer = Mixer::getGlobalMasterMixer();  // ugly, but we'll live with that for now
67
68
    m_metaMixer.reset();
72
    createMasterVolWidget();
69
    createMasterVolWidget();
73
    createActions();
70
    createActions();
71
74
    connect(this, SIGNAL(scrollRequested(int,Qt::Orientation)), this, SLOT(trayWheelEvent(int,Qt::Orientation)));
72
    connect(this, SIGNAL(scrollRequested(int,Qt::Orientation)), this, SLOT(trayWheelEvent(int,Qt::Orientation)));
75
    connect(this, SIGNAL(secondaryActivateRequested(QPoint)), this, SLOT(dockMute()));
73
    connect(this, SIGNAL(secondaryActivateRequested(QPoint)), this, SLOT(dockMute()));
76
74
77
    bool NO_MENU_ANYMORE = true; 
75
    connect(contextMenu(), SIGNAL(aboutToShow()), this, SLOT(contextMenuAboutToShow()));
78
    
79
    if ( NO_MENU_ANYMORE )
80
    {
81
      connect(contextMenu(), SIGNAL(aboutToShow()), this, SLOT(contextMenuAboutToShow()));
82
    }
83
    else
84
    {
85
      connect(this, SIGNAL(activateRequested(bool,QPoint)), this, SLOT(activateMenuOrWindow(bool,QPoint)));
86
      connect(contextMenu(), SIGNAL(aboutToShow()), this, SLOT(contextMenuAboutToShow()));
87
    }
88
76
89
#ifdef __GNUC__
77
#ifdef __GNUC__
90
#warning minimizeRestore usage is currently slightly broken in KMIx. This should be fixed before doing a release.
78
#warning minimizeRestore usage is currently slightly broken in KMIx. This should be fixed before doing a release.
Lines 102-120 Link Here
102
        _volWA->setDefaultWidget(_referenceWidget2);
90
        _volWA->setDefaultWidget(_referenceWidget2);
103
        _referenceWidget->addAction(_volWA);
91
        _referenceWidget->addAction(_volWA);
104
92
105
        connect( m_mixer, SIGNAL(controlChanged()), _referenceWidget2, SLOT(refreshVolumeLevels()) );
93
        connect( &m_metaMixer, SIGNAL(controlChanged()), _referenceWidget2, SLOT(refreshVolumeLevels()) );
106
        //setAssociatedWidget(_referenceWidget);
94
        //setAssociatedWidget(_referenceWidget);
107
        //setAssociatedWidget(_referenceWidget);  // If you use the popup, associate that instead of the MainWindow
95
        //setAssociatedWidget(_referenceWidget);  // If you use the popup, associate that instead of the MainWindow
108
	
96
109
	//setContextMenu(_referenceWidget2);
97
        //setContextMenu(_referenceWidget2);
110
    }
98
    } else {
111
    else {
112
        _volWA = 0;
99
        _volWA = 0;
113
        _referenceWidget = 0;
100
        _referenceWidget = 0;
114
    }
101
    }
115
}
102
}
116
103
117
118
KMixDockWidget::~KMixDockWidget()
104
KMixDockWidget::~KMixDockWidget()
119
{
105
{
120
    delete _audioPlayer;
106
    delete _audioPlayer;
Lines 127-153 Link Here
127
113
128
void KMixDockWidget::createActions()
114
void KMixDockWidget::createActions()
129
{
115
{
130
   QMenu *menu = contextMenu();
116
    QMenu *menu = contextMenu();
131
   
117
132
   shared_ptr<MixDevice> md = Mixer::getGlobalMasterMD();
118
    shared_ptr<MixDevice> md = Mixer::getGlobalMasterMD();
133
  if ( md.get() != 0 && md->playbackVolume().hasSwitch() )
119
    if ( md.get() != 0 && md->playbackVolume().hasSwitch() ) {
134
  {
120
        // Put "Mute" selector in context menu
135
    // Put "Mute" selector in context menu
121
        KToggleAction *action = actionCollection()->add<KToggleAction>( "dock_mute" );
136
    KToggleAction *action = actionCollection()->add<KToggleAction>( "dock_mute" );
122
        action->setText( i18n( "M&ute" ) );
137
    action->setText( i18n( "M&ute" ) );
123
        connect(action, SIGNAL(triggered(bool)), SLOT(dockMute()));
138
    connect(action, SIGNAL(triggered(bool)), SLOT(dockMute()));
124
        menu->addAction( action );
125
    }
126
127
    // Put "Select Master Channel" dialog in context menu
128
    QAction *action = actionCollection()->addAction( "select_master" );
129
    action->setText( i18n("Select Master Channel...") );
130
    action->setEnabled(m_metaMixer.hasMixer());
131
    connect(action, SIGNAL(triggered(bool)), SLOT(selectMaster()));
139
    menu->addAction( action );
132
    menu->addAction( action );
140
}
141
133
142
  // Put "Select Master Channel" dialog in context menu
134
    //Context menu entry to access phonon settings
143
  if ( m_mixer != 0 ) {
135
    menu->addAction(_kmixMainWindow->actionCollection()->action("launch_kdesoundsetup"));
144
  QAction *action = actionCollection()->addAction( "select_master" );
145
  action->setText( i18n("Select Master Channel...") );
146
  connect(action, SIGNAL(triggered(bool)), SLOT(selectMaster()));
147
  menu->addAction( action );
148
  }
149
  //Context menu entry to access phonon settings
150
  menu->addAction(_kmixMainWindow->actionCollection()->action("launch_kdesoundsetup"));
151
136
152
   // Setup volume preview
137
   // Setup volume preview
153
  if ( _playBeepOnVolumeChange ) {
138
  if ( _playBeepOnVolumeChange ) {
Lines 157-164 Link Here
157
}
142
}
158
143
159
144
160
void
145
void KMixDockWidget::createMasterVolWidget()
161
KMixDockWidget::createMasterVolWidget()
162
{
146
{
163
     // Reset flags, so that the dock icon will be reconstructed
147
     // Reset flags, so that the dock icon will be reconstructed
164
     _oldToolTipValue = -1;
148
     _oldToolTipValue = -1;
Lines 173-206 Link Here
173
    }
157
    }
174
    // create devices
158
    // create devices
175
159
176
    m_mixer->readSetFromHWforceUpdate();  // after changing the master device, make sure to re-read (otherwise no "changed()" signals might get sent by the Mixer
177
    /* With the recently introduced QSocketNotifier stuff, we can't rely on regular timer updates
178
       any longer. Also the readSetFromHWforceUpdate() won't be enough. As a workaround, we trigger
179
       all "repaints" manually here.
180
       The call to m_mixer->readSetFromHWforceUpdate() is most likely superfluous, even if we don't use QSocketNotifier (e.g. in backends OSS, Solaris, ...)
181
     */
182
    setVolumeTip();
160
    setVolumeTip();
183
    updatePixmap();
161
    updatePixmap();
184
    /* We are setting up 3 connections:
162
185
     * Refreshig the _dockAreaPopup (not anymore necessary, because ViewBase already does it)
163
    connect( &m_metaMixer, SIGNAL(controlChanged()), this, SLOT(setVolumeTip()) );
186
     * Refreshing the Tooltip
164
    connect( &m_metaMixer, SIGNAL(controlChanged()), this, SLOT(updatePixmap()) );
187
     * Refreshing the Icon
188
     */
189
    //    connect( m_mixer, SIGNAL(controlChanged()), _dockAreaPopup, SLOT(refreshVolumeLevels()) );
190
    connect( m_mixer, SIGNAL(controlChanged()), this, SLOT(setVolumeTip()) );
191
    connect( m_mixer, SIGNAL(controlChanged()), this, SLOT(updatePixmap()) );
192
}
165
}
193
166
194
void KMixDockWidget::selectMaster()
167
void KMixDockWidget::selectMaster()
195
{
168
{
196
   DialogSelectMaster* dsm = new DialogSelectMaster(m_mixer);
169
   DialogSelectMaster* dsm = new DialogSelectMaster(m_metaMixer.mixer());
197
   dsm->setAttribute(Qt::WA_DeleteOnClose, true);
170
   dsm->setAttribute(Qt::WA_DeleteOnClose, true);
198
   connect ( dsm, SIGNAL(newMasterSelected(QString&,QString&)), SLOT(handleNewMaster(QString&,QString&)) );
171
   connect ( dsm, SIGNAL(newMasterSelected(QString&,QString&)), SLOT(handleNewMaster(QString&,QString&)) );
199
   connect ( dsm, SIGNAL(newMasterSelected(QString&,QString&)), SIGNAL(newMasterSelected()) );
172
   connect ( dsm, SIGNAL(newMasterSelected(QString&,QString&)), SIGNAL(newMasterSelected()) );
200
   dsm->show();
173
   dsm->show();
201
}
174
}
202
175
203
204
void KMixDockWidget::handleNewMaster(QString& /*mixerID*/, QString& /*control_id*/)
176
void KMixDockWidget::handleNewMaster(QString& /*mixerID*/, QString& /*control_id*/)
205
{
177
{
206
   /* When a new master is selected, we will need to destroy *this instance of KMixDockWidget.
178
   /* When a new master is selected, we will need to destroy *this instance of KMixDockWidget.
Lines 212-222 Link Here
212
   _kmixMainWindow->updateDocking();
184
   _kmixMainWindow->updateDocking();
213
}
185
}
214
186
187
void KMixDockWidget::update()
188
{
189
    m_metaMixer.reset();
190
    actionCollection()->action(QLatin1String("select_master"))->setEnabled(m_metaMixer.hasMixer());
191
}
215
192
216
void
193
void KMixDockWidget::setVolumeTip()
217
KMixDockWidget::setVolumeTip()
218
{
194
{
219
	shared_ptr<MixDevice> md = Mixer::getGlobalMasterMD();
195
    shared_ptr<MixDevice> md = Mixer::getGlobalMasterMD();
220
    QString tip = "";
196
    QString tip = "";
221
    int newToolTipValue = 0;
197
    int newToolTipValue = 0;
222
198
Lines 294-307 Link Here
294
   _oldPixmapType = newPixmapType;
270
   _oldPixmapType = newPixmapType;
295
}
271
}
296
272
297
298
299
void KMixDockWidget::activateMenuOrWindow(bool val, const QPoint &pos)
300
{
301
    kDebug() << "activateMenuOrWindow: " << val << "," << pos;
302
}
303
304
305
void KMixDockWidget::activate(const QPoint &pos)
273
void KMixDockWidget::activate(const QPoint &pos)
306
{
274
{
307
    kDebug() << "Activate at " << pos;
275
    kDebug() << "Activate at " << pos;
Lines 315-326 Link Here
315
        kDebug() << "Use default KStatusNotifierItem behavior";
283
        kDebug() << "Use default KStatusNotifierItem behavior";
316
        setAssociatedWidget(_kmixMainWindow);
284
        setAssociatedWidget(_kmixMainWindow);
317
//        KStatusNotifierItem::activate(pos);
285
//        KStatusNotifierItem::activate(pos);
318
	KStatusNotifierItem::activate();
286
        KStatusNotifierItem::activate();
319
        return;
287
        return;
320
    }
288
    }
321
289
322
    KMenu* dockAreaPopup =_referenceWidget; // TODO Refactor to use _referenceWidget directly
290
    KMenu* dockAreaPopup =_referenceWidget; // TODO Refactor to use _referenceWidget directly
323
    kDebug() << "Skip default KStatusNotifierItkdebem behavior";
291
    kDebug() << "Skip default KStatusNotifierItem behavior";
324
    if ( dockAreaPopup->isVisible() ) {
292
    if ( dockAreaPopup->isVisible() ) {
325
        dockAreaPopup->hide();
293
        dockAreaPopup->hide();
326
        kDebug() << "dap is visible => hide and return";
294
        kDebug() << "dap is visible => hide and return";
Lines 424-435 Link Here
424
void
392
void
425
KMixDockWidget::dockMute()
393
KMixDockWidget::dockMute()
426
{
394
{
427
	shared_ptr<MixDevice> md = Mixer::getGlobalMasterMD();
395
    shared_ptr<MixDevice> md = Mixer::getGlobalMasterMD();
428
	if ( md )
396
    if ( md )
429
   {
397
    {
430
      md->toggleMute();
398
        md->toggleMute();
431
      md->mixer()->commitVolumeChange( md );
399
        md->mixer()->commitVolumeChange( md );
432
   }
400
    }
433
}
401
}
434
402
435
void
403
void

Return to bug 444668