~ubuntu-branches/ubuntu/natty/kdemultimedia/natty-proposed

« back to all changes in this revision

Viewing changes to kmix/gui/viewsliders.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Debian Qt/KDE Maintainers
  • Date: 2011-05-26 02:41:36 UTC
  • mfrom: (0.2.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 108.
  • Revision ID: james.westby@ubuntu.com-20110526024136-jjwsigfy402jhupm
Tags: upstream-4.6.3
ImportĀ upstreamĀ versionĀ 4.6.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * KMix -- KDE's full featured mini mixer
 
3
 *
 
4
 *
 
5
 * Copyright (C) 1996-2004 Christian Esken <esken@kde.org>
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Library General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2 of the License, or (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Library General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Library General Public
 
18
 * License along with this program; if not, write to the Free
 
19
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
20
 */
 
21
 
 
22
//#define TEST_MIXDEVICE_COMPOSITE
 
23
#undef TEST_MIXDEVICE_COMPOSITE
 
24
 
 
25
#ifdef TEST_MIXDEVICE_COMPOSITE
 
26
#ifdef __GNUC__
 
27
#warning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
28
#warning !!! MIXDEVICE COMPOSITE TESTING IS ACTIVATED   !!!
 
29
#warning !!! THIS IS PRE-ALPHA CODE!                    !!!
 
30
#warning !!! DO NOT SHIP KMIX IN THIS STATE             !!!
 
31
#warning !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
32
#endif
 
33
#endif
 
34
 
 
35
// KMix
 
36
#include "viewsliders.h"
 
37
#include "gui/guiprofile.h"
 
38
#include "mdwenum.h"
 
39
#include "mdwslider.h"
 
40
#include "core/mixdevicecomposite.h"
 
41
#include "core/mixer.h"
 
42
#include "verticaltext.h"
 
43
 
 
44
// KDE
 
45
#include <kdebug.h>
 
46
 
 
47
// Qt
 
48
#include <QWidget>
 
49
#include <QVBoxLayout>
 
50
#include <QHBoxLayout>
 
51
//#include <QFormLayout>
 
52
 
 
53
 
 
54
 
 
55
/**
 
56
 * Generic View implementation. This can hold now all kinds of controls (not just Sliders, as
 
57
 *  the class name suggests).
 
58
 */
 
59
ViewSliders::ViewSliders(QWidget* parent, const char* name, Mixer* mixer, ViewBase::ViewFlags vflags, GUIProfile *guiprof, KActionCollection *actColl)
 
60
      : ViewBase(parent, name, mixer, Qt::FramelessWindowHint, vflags, guiprof, actColl)
 
61
      , _layoutEnum(0)
 
62
{
 
63
   if ( _vflags & ViewBase::Vertical ) {
 
64
      _layoutMDW = new QVBoxLayout(this);
 
65
      _layoutMDW->setAlignment(Qt::AlignLeft|Qt::AlignTop);
 
66
      _layoutSliders = new QVBoxLayout();
 
67
      _layoutSliders->setAlignment(Qt::AlignVCenter|Qt::AlignLeft);
 
68
   }
 
69
   else
 
70
   {
 
71
      _layoutMDW = new QHBoxLayout(this);
 
72
      _layoutMDW->setAlignment(Qt::AlignHCenter|Qt::AlignTop);
 
73
      _layoutSliders = new QHBoxLayout();
 
74
      _layoutSliders->setAlignment(Qt::AlignHCenter|Qt::AlignTop);
 
75
      // Place enums in an own box right from the sliders.
 
76
   }
 
77
   _layoutSliders->setContentsMargins(0,0,0,0);
 
78
   _layoutSliders->setSpacing(0);
 
79
   _layoutMDW->setContentsMargins(0,0,0,0);
 
80
   _layoutMDW->setSpacing(0);
 
81
   _layoutMDW->addItem( _layoutSliders );
 
82
 
 
83
    setMixSet();
 
84
}
 
85
 
 
86
ViewSliders::~ViewSliders()
 
87
{
 
88
  qDeleteAll(_separators);
 
89
}
 
90
 
 
91
 
 
92
 
 
93
QWidget* ViewSliders::add(MixDevice *md)
 
94
{
 
95
    MixDeviceWidget *mdw;
 
96
    Qt::Orientation orientation = (_vflags & ViewBase::Vertical) ? Qt::Horizontal : Qt::Vertical;
 
97
 
 
98
 
 
99
 
 
100
    if ( md->isEnum() ) {
 
101
        mdw = new MDWEnum(
 
102
                md,           // MixDevice (parameter)
 
103
                orientation,  // Orientation
 
104
                this,         // parent
 
105
                this          // View widget
 
106
                , md->controlProfile()
 
107
        );
 
108
        if ( _layoutEnum == 0 ) {
 
109
            // lazily creation of Layout for the first enum
 
110
            _layoutEnum = new QVBoxLayout(); // new QFormLayout();
 
111
            _layoutMDW->addLayout( _layoutEnum );
 
112
        }
 
113
        _layoutEnum->addWidget(mdw);
 
114
    } // an enum
 
115
    else {
 
116
        // add a separator before the device
 
117
        QFrame *_frm = new QFrame(this);
 
118
        if ( orientation == Qt::Vertical)
 
119
            _frm->setFrameStyle(QFrame::VLine | QFrame::Sunken);
 
120
        else
 
121
            _frm->setFrameStyle(QFrame::HLine | QFrame::Sunken);
 
122
        _separators.insert(md->id(),_frm);
 
123
        _layoutSliders->addWidget(_frm);
 
124
        mdw = new MDWSlider(
 
125
                md,           // MixDevice (parameter)
 
126
                true,         // Show Mute LED
 
127
                true,         // Show Record LED
 
128
                false,        // Small
 
129
                orientation,  // Orientation
 
130
                this,         // parent
 
131
                this
 
132
                , md->controlProfile()
 
133
        ); // View widget
 
134
        _layoutSliders->addWidget(mdw);
 
135
//        QHBoxLayout* lay = ::qobject_cast<QHBoxLayout*>(_layoutSliders);
 
136
//        if ( lay )
 
137
//            lay->addSpacing(2);
 
138
//        else
 
139
//            qobject_cast<QVBoxLayout*>(_layoutSliders)->addSpacing(2);
 
140
    }
 
141
 
 
142
 
 
143
    return mdw;
 
144
}
 
145
 
 
146
 
 
147
void ViewSliders::_setMixSet()
 
148
{
 
149
    const MixSet& mixset = _mixer->getMixSet();
 
150
 
 
151
    if ( _mixer->isDynamic() ) {
 
152
        // We will be recreating our sliders, so make sure we trash all the separators too.
 
153
        qDeleteAll(_separators);
 
154
        _separators.clear();
 
155
        // Our _layoutSliders now should only contain spacer widgets from the addSpacing() calls in add() above.
 
156
        // We need to trash those too otherwise all sliders gradually migrate away from the edge :p
 
157
        QLayoutItem *li;
 
158
        while ( ( li = _layoutSliders->takeAt(0) ) )
 
159
            delete li;
 
160
    }
 
161
 
 
162
 
 
163
#ifdef TEST_MIXDEVICE_COMPOSITE
 
164
    QList<MixDevice*> mds;  // For temporary test
 
165
#endif
 
166
 
 
167
    // This method iterates the controls from the Profile
 
168
    // Each control is checked, whether it is also contained in the mixset, and
 
169
    // applicable for this kind of View. If yes, the control is accepted and inserted.
 
170
   
 
171
    foreach ( ProfControl* control, _guiprof->getControls() )
 
172
    {
 
173
        //ProfControl* control = *it;
 
174
        // The TabName of the control matches this View name (!! attention: Better use some ID, due to i18n() )
 
175
        bool isUsed = false;
 
176
 
 
177
        QRegExp idRegexp(control->id);
 
178
        //bool isExactRegexp = control->id.startsWith('^') && control->id.endsWith('$'); // for optimizing
 
179
        //isExactRegexp &= ( ! control->id.contains(".*") ); // For now. Might be removed in the future, as it cannot be done properly !!!
 
180
        //kDebug(67100) << "ViewSliders::setMixSet(): Check GUIProfile id==" << control->id << "\n";
 
181
        // The following for-loop could be simplified by using a std::find_if
 
182
        for ( int i=0; i<mixset.count(); i++ ) {
 
183
            MixDevice *md = mixset[i];
 
184
            if ( md->id().contains(idRegexp) )
 
185
            {
 
186
                // Match found (by name)
 
187
                if ( _mixSet->contains( md ) ) continue; // dup check
 
188
 
 
189
                // Now check whether subcontrols match
 
190
                bool subcontrolPlaybackWanted = (control->useSubcontrolPlayback() && md->playbackVolume().hasVolume());
 
191
                bool subcontrolCaptureWanted  = (control->useSubcontrolCapture()  && md->captureVolume().hasVolume());
 
192
                bool subcontrolEnumWanted  = (control->useSubcontrolEnum() && md->isEnum());
 
193
                bool subcontrolWanted =  subcontrolPlaybackWanted | subcontrolCaptureWanted | subcontrolEnumWanted;
 
194
                bool splitWanted = control->isSplit();
 
195
 
 
196
                if ( !subcontrolWanted ) continue;
 
197
 
 
198
                md->setControlProfile(control);
 
199
                if ( !control->name.isNull() ) {
 
200
                    // Apply the custom name from the profile
 
201
                    md->setReadableName(control->name);  // @todo: This is the wrong place. It only applies to controls in THIS type of view
 
202
                }
 
203
                if ( !control->getSwitchtype().isNull() ) {
 
204
                    if ( control->getSwitchtype() == "On"  )
 
205
                        md->playbackVolume().setSwitchType(Volume::OnSwitch);
 
206
                    else if ( control->getSwitchtype() == "Off"  )
 
207
                        md->playbackVolume().setSwitchType(Volume::OffSwitch);
 
208
                }
 
209
                _mixSet->append(md);
 
210
 
 
211
#ifdef TEST_MIXDEVICE_COMPOSITE
 
212
                if ( md->id() == "Front:0" || md->id() == "Surround:0") { mds.append(md); } // For temporary test
 
213
#endif
 
214
 
 
215
                isUsed = true;
 
216
                // We use no "break;" ,as multiple devices could match
 
217
                //if ( isExactRegexp ) break;  // Optimize! In this case, we can actually break the loop
 
218
            } // name matches
 
219
        } // loop for finding a suitable MixDevice
 
220
        if ( ! isUsed ) {
 
221
            // There is something in the Profile, that doesn't correspond to a Mixer control
 
222
            //kDebug(67100) << "ViewSliders::setMixSet(): No such control '" << control->id << "'in the mixer . Please check the GUIProfile\n";
 
223
        }
 
224
   } // iteration over all controls from the Profile
 
225
 
 
226
#ifdef TEST_MIXDEVICE_COMPOSITE
 
227
    // This is currently hardcoded, and instead must be read as usual from the Profile
 
228
    MixDeviceComposite *mdc = new MixDeviceComposite(_mixer, "Composite_Test", mds, "A Composite Control #1", MixDevice::KMIX_COMPOSITE);
 
229
    QString ctlId("Composite_Test");
 
230
    QString ctlMatchAll("*");
 
231
    ProfControl* pctl = new ProfControl(ctlId, ctlMatchAll);
 
232
    mdc->setControlProfile(pctl);
 
233
    _mixSet->append(mdc);
 
234
#endif
 
235
}
 
236
 
 
237
 
 
238
void ViewSliders::constructionFinished() {
 
239
    configurationUpdate();
 
240
}
 
241
 
 
242
 
 
243
void ViewSliders::configurationUpdate() {
 
244
   // Adjust height of top part by setting it to the maximum of all mdw's
 
245
   bool haveCaptureLEDs = false;
 
246
   int labelExtent = 0;
 
247
   bool haveMuteButtons = false;
 
248
   for ( int i=0; i<_mdws.count(); i++ ) {
 
249
      MDWSlider* mdw = ::qobject_cast<MDWSlider*>(_mdws[i]);
 
250
      if ( mdw && mdw->isVisibleTo(this) ) {
 
251
                 if ( mdw->labelExtentHint() > labelExtent ) labelExtent = mdw->labelExtentHint();
 
252
                 haveCaptureLEDs = haveCaptureLEDs || mdw->hasCaptureLED();
 
253
                 haveMuteButtons = haveMuteButtons || mdw->hasMuteButton();
 
254
      }
 
255
   }
 
256
   //kDebug(67100) << "topPartExtent is " << topPartExtent;
 
257
   bool firstVisibleControlFound = false;
 
258
   for ( int i=0; i<_mdws.count(); i++ ) {
 
259
      MDWSlider* mdw = ::qobject_cast<MDWSlider*>(_mdws[i]);
 
260
      if ( mdw ) {
 
261
                 mdw->setLabelExtent(labelExtent);
 
262
                 mdw->setMuteButtonSpace(haveMuteButtons);
 
263
                 mdw->setCaptureLEDSpace(haveCaptureLEDs);
 
264
         bool thisControlIsVisible = mdw->isVisibleTo(this);
 
265
         bool showSeparator = ( firstVisibleControlFound && thisControlIsVisible);
 
266
         if ( _separators.contains( mdw->mixDevice()->id() )) {
 
267
            QFrame* sep = _separators[mdw->mixDevice()->id()];
 
268
            sep->setVisible(showSeparator);
 
269
         }
 
270
         if ( thisControlIsVisible ) firstVisibleControlFound=true;
 
271
      }
 
272
    } // for all  MDW's
 
273
    _layoutMDW->activate();
 
274
}
 
275
 
 
276
void ViewSliders::refreshVolumeLevels() {
 
277
    //     kDebug(67100) << "ViewSliders::refreshVolumeLevels()\n";
 
278
 
 
279
    for ( int i=0; i<_mdws.count(); i++ ) {
 
280
        QWidget *mdwx = _mdws[i];
 
281
        if ( mdwx == 0 ) {
 
282
            kError(67100) << "ViewSliders::refreshVolumeLevels(): mdw == 0\n";
 
283
            break; // sanity check (normally the lists are set up correctly)
 
284
        }
 
285
        else {
 
286
            MixDeviceWidget* mdw = ::qobject_cast<MixDeviceWidget*>(mdwx);
 
287
            if ( mdw != 0 ) { // sanity check
 
288
 
 
289
#ifdef TEST_MIXDEVICE_COMPOSITE
 
290
                // --- start --- The following 4 code lines should be moved to a more
 
291
                //                      generic place, as it only works in this View. But it
 
292
                //                      should also work in the ViewDockareaPopup and everywhere else.
 
293
                MixDeviceComposite* mdc = ::qobject_cast<MixDeviceComposite*>(mdw->mixDevice());
 
294
                if (mdc != 0) {
 
295
                    mdc->update();
 
296
                }
 
297
                // --- end ---
 
298
#endif
 
299
 
 
300
                mdw->update();
 
301
            }
 
302
            else {
 
303
                kError(67100) << "ViewSliders::refreshVolumeLevels(): mdw is not a MixDeviceWidget\n";
 
304
                // no slider. Cannot happen in theory => skip it
 
305
            }
 
306
        }
 
307
    }
 
308
}
 
309
 
 
310
#include "viewsliders.moc"