preferences_widgets.cpp 44.3 KB
Newer Older
zorglub's avatar
zorglub committed
1
2
3
/*****************************************************************************
 * preferences_widgets.cpp : Widgets for preferences displays
 ****************************************************************************
4
 * Copyright (C) 2006-2007 the VideoLAN team
5
 * $Id$
zorglub's avatar
zorglub committed
6
7
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
dionoea's avatar
dionoea committed
8
 *          Antoine Cellerier <dionoea@videolan.org>
9
 *          Jean-Baptiste Kempf <jb@videolan.org>
zorglub's avatar
zorglub committed
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

zorglub's avatar
zorglub committed
26
27
/**
 * Todo:
28
29
 *  - Finish implementation (see WX, there might be missing a
 *    i_action handler for IntegerLists, but I don't see any module using it...
zorglub's avatar
zorglub committed
30
31
32
 *  - Improvements over WX
 *      - Validator for modulelist
 */
33
34
35
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
zorglub's avatar
zorglub committed
36

zorglub's avatar
zorglub committed
37
#include "components/preferences_widgets.hpp"
38
#include "util/customwidgets.hpp"
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
39
40
#include <vlc_keys.h>

zorglub's avatar
zorglub committed
41
42
#include <QString>
#include <QVariant>
zorglub's avatar
zorglub committed
43
#include <QGridLayout>
44
#include <QSlider>
45
#include <QFileDialog>
46
#include <QGroupBox>
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
47
#include <QTreeWidgetItem>
48
#include <QSignalMapper>
49
#include <QDialogButtonBox>
50

51
52
53
#define MINWIDTH_BOX 90
#define LAST_COLUMN 10

54
55
56
QString formatTooltip(const QString & tooltip)
{
    QString formatted =
57
58
59
60
61
62
    "<html><head><meta name=\"qrichtext\" content=\"1\" />"
    "<style type=\"text/css\"> p, li { white-space: pre-wrap; } </style></head>"
    "<body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; "
    "font-style:normal; text-decoration:none;\">"
    "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; "
    "margin-right:0px; -qt-block-indent:0; text-indent:0px;\">" +
63
64
65
66
67
    tooltip +
    "</p></body></html>";
    return formatted;
}

zorglub's avatar
zorglub committed
68
ConfigControl *ConfigControl::createControl( vlc_object_t *p_this,
zorglub's avatar
zorglub committed
69
70
                                             module_config_t *p_item,
                                             QWidget *parent )
zorglub's avatar
zorglub committed
71
{
72
    int i = 0;
73
    return createControl( p_this, p_item, parent, NULL, i );
zorglub's avatar
zorglub committed
74
75
76
77
78
}

ConfigControl *ConfigControl::createControl( vlc_object_t *p_this,
                                             module_config_t *p_item,
                                             QWidget *parent,
79
                                             QGridLayout *l, int &line )
zorglub's avatar
zorglub committed
80
81
82
83
84
85
{
    ConfigControl *p_control = NULL;

    switch( p_item->i_type )
    {
    case CONFIG_ITEM_MODULE:
zorglub's avatar
zorglub committed
86
87
        p_control = new ModuleConfigControl( p_this, p_item, parent, false,
                                             l, line );
zorglub's avatar
zorglub committed
88
89
        break;
    case CONFIG_ITEM_MODULE_CAT:
zorglub's avatar
zorglub committed
90
91
        p_control = new ModuleConfigControl( p_this, p_item, parent, true,
                                             l, line );
zorglub's avatar
zorglub committed
92
        break;
93
94
95
96
97
98
99
100
    case CONFIG_ITEM_MODULE_LIST:
        p_control = new ModuleListConfigControl( p_this, p_item, parent, false,
                                             l, line );
        break;
    case CONFIG_ITEM_MODULE_LIST_CAT:
        p_control = new ModuleListConfigControl( p_this, p_item, parent, true,
                                             l, line );
        break;
zorglub's avatar
zorglub committed
101
102
    case CONFIG_ITEM_STRING:
        if( !p_item->i_list )
zorglub's avatar
zorglub committed
103
104
            p_control = new StringConfigControl( p_this, p_item, parent,
                                                 l, line, false );
zorglub's avatar
zorglub committed
105
        else
dionoea's avatar
dionoea committed
106
107
            p_control = new StringListConfigControl( p_this, p_item,
                                            parent, false, l, line );
zorglub's avatar
zorglub committed
108
        break;
109
110
111
112
113
114
115
116
    case CONFIG_ITEM_PASSWORD:
        if( !p_item->i_list )
            p_control = new StringConfigControl( p_this, p_item, parent,
                                                 l, line, true );
        else
            p_control = new StringListConfigControl( p_this, p_item,
                                            parent, true, l, line );
        break;
zorglub's avatar
zorglub committed
117
118
    case CONFIG_ITEM_INTEGER:
        if( p_item->i_list )
dionoea's avatar
dionoea committed
119
120
            p_control = new IntegerListConfigControl( p_this, p_item,
                                            parent, false, l, line );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
121
        else if( p_item->min.i || p_item->max.i )
122
123
            p_control = new IntegerRangeConfigControl( p_this, p_item, parent,
                                                       l, line );
zorglub's avatar
zorglub committed
124
        else
zorglub's avatar
zorglub committed
125
126
            p_control = new IntegerConfigControl( p_this, p_item, parent,
                                                  l, line );
zorglub's avatar
zorglub committed
127
        break;
128
    case CONFIG_ITEM_FILE:
129
130
        p_control = new FileConfigControl( p_this, p_item, parent, l,
                                                line, false );
131
132
        break;
    case CONFIG_ITEM_DIRECTORY:
133
134
        p_control = new DirectoryConfigControl( p_this, p_item, parent, l,
                                                line, false );
135
        break;
136
#if 0
yoann's avatar
yoann committed
137
138
139
140
    case CONFIG_ITEM_FONT:
        p_control = new FontConfigControl( p_this, p_item, parent, l,
                                           line, false );
        break;
141
#endif
142
143
144
    case CONFIG_ITEM_KEY:
        p_control = new KeySelectorControl( p_this, p_item, parent, l, line );
        break;
145
146
147
148
    case CONFIG_ITEM_BOOL:
        p_control = new BoolConfigControl( p_this, p_item, parent, l, line );
        break;
    case CONFIG_ITEM_FLOAT:
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
149
        if( p_item->min.f || p_item->max.f )
150
151
            p_control = new FloatRangeConfigControl( p_this, p_item, parent,
                                                     l, line );
152
        else
153
154
            p_control = new FloatConfigControl( p_this, p_item, parent,
                                                  l, line );
155
        break;
zorglub's avatar
zorglub committed
156
157
158
159
160
161
    default:
        break;
    }
    return p_control;
}

zorglub's avatar
zorglub committed
162
163
164
165
void ConfigControl::doApply( intf_thread_t *p_intf )
{
    switch( getType() )
    {
166
167
        case CONFIG_ITEM_INTEGER:
        case CONFIG_ITEM_BOOL:
zorglub's avatar
zorglub committed
168
169
        {
            VIntConfigControl *vicc = qobject_cast<VIntConfigControl *>(this);
zorglub's avatar
zorglub committed
170
            assert( vicc );
zorglub's avatar
zorglub committed
171
172
173
            config_PutInt( p_intf, vicc->getName(), vicc->getValue() );
            break;
        }
174
        case CONFIG_ITEM_FLOAT:
zorglub's avatar
zorglub committed
175
        {
176
            VFloatConfigControl *vfcc =
zorglub's avatar
zorglub committed
177
                                    qobject_cast<VFloatConfigControl *>(this);
zorglub's avatar
zorglub committed
178
            assert( vfcc );
zorglub's avatar
zorglub committed
179
180
181
            config_PutFloat( p_intf, vfcc->getName(), vfcc->getValue() );
            break;
        }
182
        case CONFIG_ITEM_STRING:
zorglub's avatar
zorglub committed
183
184
185
        {
            VStringConfigControl *vscc =
                            qobject_cast<VStringConfigControl *>(this);
zorglub's avatar
zorglub committed
186
            assert( vscc );
zorglub's avatar
zorglub committed
187
            config_PutPsz( p_intf, vscc->getName(), qta( vscc->getValue() ) );
zorglub's avatar
zorglub committed
188
            break;
zorglub's avatar
zorglub committed
189
        }
190
        case CONFIG_ITEM_KEY:
191
192
        {
            KeySelectorControl *ksc = qobject_cast<KeySelectorControl *>(this);
zorglub's avatar
zorglub committed
193
            assert( ksc );
194
195
            ksc->doApply();
        }
zorglub's avatar
zorglub committed
196
197
198
    }
}

zorglub's avatar
zorglub committed
199
200
201
202
203
204
/**************************************************************************
 * String-based controls
 *************************************************************************/

/*********** String **************/
StringConfigControl::StringConfigControl( vlc_object_t *_p_this,
zorglub's avatar
zorglub committed
205
                                          module_config_t *_p_item,
zorglub's avatar
zorglub committed
206
                                          QWidget *_parent, QGridLayout *l,
207
                                          int &line, bool pwd ) :
zorglub's avatar
zorglub committed
208
                           VStringConfigControl( _p_this, _p_item, _parent )
zorglub's avatar
zorglub committed
209
{
Christophe Mutricy's avatar
Christophe Mutricy committed
210
    label = new QLabel( qtr(p_item->psz_text) );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
211
    text = new QLineEdit( qfu(p_item->value.psz) );
212
    if( pwd ) text->setEchoMode( QLineEdit::Password );
zorglub's avatar
zorglub committed
213
    finish();
zorglub's avatar
zorglub committed
214

zorglub's avatar
zorglub committed
215
216
217
    if( !l )
    {
        QHBoxLayout *layout = new QHBoxLayout();
218
219
        layout->addWidget( label, 0 ); layout->insertSpacing( 1, 10 );
        layout->addWidget( text, LAST_COLUMN );
zorglub's avatar
zorglub committed
220
221
222
223
        widget->setLayout( layout );
    }
    else
    {
224
225
226
        l->addWidget( label, line, 0 );
        l->setColumnMinimumWidth( 1, 10 );
        l->addWidget( text, line, LAST_COLUMN );
zorglub's avatar
zorglub committed
227
    }
zorglub's avatar
zorglub committed
228
229
}

zorglub's avatar
zorglub committed
230
231
StringConfigControl::StringConfigControl( vlc_object_t *_p_this,
                                   module_config_t *_p_item,
zorglub's avatar
zorglub committed
232
                                   QLabel *_label, QLineEdit *_text, bool pwd ):
zorglub's avatar
zorglub committed
233
234
235
                           VStringConfigControl( _p_this, _p_item )
{
    text = _text;
zorglub's avatar
zorglub committed
236
237
    label = _label;
    finish( );
zorglub's avatar
zorglub committed
238
}
zorglub's avatar
zorglub committed
239

zorglub's avatar
zorglub committed
240
void StringConfigControl::finish()
zorglub's avatar
zorglub committed
241
{
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
242
    text->setText( qfu(p_item->value.psz) );
Christophe Mutricy's avatar
Christophe Mutricy committed
243
    text->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
dionoea's avatar
dionoea committed
244
    if( label )
Christophe Mutricy's avatar
Christophe Mutricy committed
245
        label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
dionoea's avatar
dionoea committed
246
247
}

248
249
250
251
252
253
254
/*********** File **************/
FileConfigControl::FileConfigControl( vlc_object_t *_p_this,
                                          module_config_t *_p_item,
                                          QWidget *_parent, QGridLayout *l,
                                          int &line, bool pwd ) :
                           VStringConfigControl( _p_this, _p_item, _parent )
{
Christophe Mutricy's avatar
Christophe Mutricy committed
255
    label = new QLabel( qtr(p_item->psz_text) );
256
    text = new QLineEdit( qfu(p_item->value.psz) );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
257
    browse = new QPushButton( qtr( "Browse..." ) );
258
259
260
261
    QHBoxLayout *textAndButton = new QHBoxLayout();
    textAndButton->setMargin( 0 );
    textAndButton->addWidget( text, 2 );
    textAndButton->addWidget( browse, 0 );
262
263
264
265
266
267
268
269

    BUTTONACT( browse, updateField() );

    finish();

    if( !l )
    {
        QHBoxLayout *layout = new QHBoxLayout();
270
        layout->addWidget( label, 0 );
271
272
        layout->insertSpacing( 1, 10 );
        layout->addLayout( textAndButton, LAST_COLUMN );
273
274
275
276
        widget->setLayout( layout );
    }
    else
    {
277
        l->addWidget( label, line, 0 );
278
279
        l->setColumnMinimumWidth( 1, 10 );
        l->addLayout( textAndButton, line, LAST_COLUMN );
280
281
282
283
284
285
    }
}


FileConfigControl::FileConfigControl( vlc_object_t *_p_this,
                                   module_config_t *_p_item,
286
                                   QLabel *_label, QLineEdit *_text,
287
                                   QPushButton *_button, bool pwd ):
288
289
                           VStringConfigControl( _p_this, _p_item )
{
290
    browse = _button;
291
292
    text = _text;
    label = _label;
293
294
295

    BUTTONACT( browse, updateField() );

296
297
298
299
300
    finish( );
}

void FileConfigControl::updateField()
{
301
302
303
304
    QString file = QFileDialog::getOpenFileName( NULL,
                  qtr( "Select File" ), qfu( p_this->p_libvlc->psz_homedir ) );
    if( file.isNull() ) return;
    text->setText( file );
305
306
307
308
309
}

void FileConfigControl::finish()
{
    text->setText( qfu(p_item->value.psz) );
Christophe Mutricy's avatar
Christophe Mutricy committed
310
    text->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
311
    if( label )
Christophe Mutricy's avatar
Christophe Mutricy committed
312
        label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
313
314
}

315
316
317
318
319
320
321
322
323
/********* String / Directory **********/
DirectoryConfigControl::DirectoryConfigControl( vlc_object_t *_p_this,
                        module_config_t *_p_item, QWidget *_p_widget,
                        QGridLayout *_p_layout, int& _int, bool _pwd ) :
     FileConfigControl( _p_this, _p_item, _p_widget, _p_layout, _int, _pwd)
{}

DirectoryConfigControl::DirectoryConfigControl( vlc_object_t *_p_this,
                        module_config_t *_p_item, QLabel *_p_label,
324
325
                        QLineEdit *_p_line, QPushButton *_p_button, bool _pwd ):
     FileConfigControl( _p_this, _p_item, _p_label, _p_line, _p_button, _pwd)
326
327
328
329
{}

void DirectoryConfigControl::updateField()
{
330
331
    QString dir = QFileDialog::getExistingDirectory( NULL,
                      qtr( "Select Directory" ),
332
333
334
335
                      text->text().isEmpty() ?
                        qfu( p_this->p_libvlc->psz_homedir ) : text->text(),
                      QFileDialog::ShowDirsOnly |
                        QFileDialog::DontResolveSymlinks );
336
337
    if( dir.isNull() ) return;
    text->setText( dir );
338
339
}

340
341
342
#if 0
#include <QFontDialog>

yoann's avatar
yoann committed
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/********* String / Font **********/
FontConfigControl::FontConfigControl( vlc_object_t *_p_this,
                        module_config_t *_p_item, QWidget *_p_widget,
                        QGridLayout *_p_layout, int& _int, bool _pwd ) :
     FileConfigControl( _p_this, _p_item, _p_widget, _p_layout, _int, _pwd)
{}

FontConfigControl::FontConfigControl( vlc_object_t *_p_this,
                        module_config_t *_p_item, QLabel *_p_label,
                        QLineEdit *_p_line, QPushButton *_p_button, bool _pwd ):
     FileConfigControl( _p_this, _p_item, _p_label, _p_line, _p_button, _pwd)
{}

void FontConfigControl::updateField()
{
    bool ok;
    QFont font = QFontDialog::getFont( &ok, QFont( text->text() ), NULL );
    if( !ok ) return;
    text->setText( font.family() );
}
363
#endif
yoann's avatar
yoann committed
364

dionoea's avatar
dionoea committed
365
366
367
/********* String / choice list **********/
StringListConfigControl::StringListConfigControl( vlc_object_t *_p_this,
               module_config_t *_p_item, QWidget *_parent, bool bycat,
368
               QGridLayout *l, int &line) :
dionoea's avatar
dionoea committed
369
370
               VStringConfigControl( _p_this, _p_item, _parent )
{
Christophe Mutricy's avatar
Christophe Mutricy committed
371
    label = new QLabel( qtr(p_item->psz_text) );
dionoea's avatar
dionoea committed
372
    combo = new QComboBox();
373
    combo->setMinimumWidth( MINWIDTH_BOX );
374
    combo->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
375

376
    module_config_t *p_module_config = config_FindConfig( p_this, p_item->psz_name );
377
    if(p_module_config && p_module_config->pf_update_list)
378
379
380
    {
       vlc_value_t val;
       val.psz_string = strdup(p_module_config->value.psz);
381

382
383
384
385
386
387
388
       p_module_config->pf_update_list(p_this, p_item->psz_name, val, val, NULL);

       // assume in a×y case that dirty was set to VLC_TRUE
       // because lazy programmes will use the same callback for
       // this, like the one behind the refresh push button?
       p_module_config->b_dirty = VLC_FALSE;

389
       free( val.psz_string );
390
    }
391
392

    finish( p_module_config, bycat );
dionoea's avatar
dionoea committed
393
394
    if( !l )
    {
395
396
397
        l = new QGridLayout();
        l->addWidget( label, 0, 0 ); l->addWidget( combo, 0, LAST_COLUMN );
        widget->setLayout( l );
dionoea's avatar
dionoea committed
398
399
400
401
    }
    else
    {
        l->addWidget( label, line, 0 );
402
        l->addWidget( combo, line, LAST_COLUMN, Qt::AlignRight );
dionoea's avatar
dionoea committed
403
    }
404
405
406
407
408
409
410
411
412
413
414
415

    if( p_item->i_action )
    {
        QSignalMapper *signalMapper = new QSignalMapper(this);

        /* Some stringLists like Capture listings have action associated */
        for( int i = 0; i < p_item->i_action; i++ )
        {
            QPushButton *button =
                new QPushButton( qfu( p_item->ppsz_action_text[i] ));
            CONNECT( button, clicked(), signalMapper, map() );
            signalMapper->setMapping( button, i );
416
417
            l->addWidget( button, line, LAST_COLUMN - p_item->i_action + i,
                    Qt::AlignRight );
418
419
420
421
422
423
424
425
426
427
428
        }
        CONNECT( signalMapper, mapped( int ),
                this, actionRequested( int ) );
    }
}

void StringListConfigControl::actionRequested( int i_action )
{
    /* Supplementary check for boundaries */
    if( i_action < 0 || i_action >= p_item->i_action ) return;

429
430
431
    module_config_t *p_module_config = config_FindConfig( p_this, getName() );
    if(!p_module_config) return;

432
    vlc_value_t val;
433
    val.psz_string =
434
        qtu( (combo->itemData( combo->currentIndex() ).toString() ) );
435

436
    p_module_config->ppf_action[i_action]( p_this, getName(), val, val, 0 );
437

438
    if( p_module_config->b_dirty )
439
440
    {
        combo->clear();
441
442
        finish( p_module_config, true );
        p_module_config->b_dirty = VLC_FALSE;
443
    }
dionoea's avatar
dionoea committed
444
445
446
447
448
449
450
}
StringListConfigControl::StringListConfigControl( vlc_object_t *_p_this,
                module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
                bool bycat ) : VStringConfigControl( _p_this, _p_item )
{
    combo = _combo;
    label = _label;
451
452
453
454

    module_config_t *p_module_config = config_FindConfig( p_this, getName() );

    finish( p_module_config, bycat );
dionoea's avatar
dionoea committed
455
456
}

457
void StringListConfigControl::finish(module_config_t *p_module_config, bool bycat )
dionoea's avatar
dionoea committed
458
459
460
{
    combo->setEditable( false );

461
462
463
    if(!p_module_config) return;

    for( int i_index = 0; i_index < p_module_config->i_list; i_index++ )
dionoea's avatar
dionoea committed
464
    {
465
466
        combo->addItem( qfu((p_module_config->ppsz_list_text &&
                            p_module_config->ppsz_list_text[i_index])?
467
468
469
470
471
                            p_module_config->ppsz_list_text[i_index] :
                            p_module_config->ppsz_list[i_index] ),
                        QVariant( p_module_config->ppsz_list[i_index] ) );
        if( p_item->value.psz && !strcmp( p_module_config->value.psz,
                                          p_module_config->ppsz_list[i_index] ) )
dionoea's avatar
dionoea committed
472
473
            combo->setCurrentIndex( combo->count() - 1 );
    }
474
    combo->setToolTip( formatTooltip(qtr(p_module_config->psz_longtext)) );
dionoea's avatar
dionoea committed
475
    if( label )
476
        label->setToolTip( formatTooltip(qtr(p_module_config->psz_longtext)) );
dionoea's avatar
dionoea committed
477
478
479
480
481
}

QString StringListConfigControl::getValue()
{
    return combo->itemData( combo->currentIndex() ).toString();
zorglub's avatar
zorglub committed
482
}
zorglub's avatar
zorglub committed
483

484
485
486
487
488
489
490
void setfillVLCConfigCombo( const char *configname, intf_thread_t *p_intf,
                        QComboBox *combo, QWidget *parent )
{
    module_config_t *p_config =
                      config_FindConfig( VLC_OBJECT(p_intf), configname );
    if( p_config )
    {
491
       if(p_config->pf_update_list)
492
493
494
495
496
497
498
499
500
501
        {
            vlc_value_t val;
            val.i_int = p_config->value.i;
            p_config->pf_update_list(VLC_OBJECT(p_intf), configname, val, val, NULL);
            // assume in any case that dirty was set to VLC_TRUE
            // because lazy programmes will use the same callback for
            // this, like the one behind the refresh push button?
            p_config->b_dirty = VLC_FALSE;
        }

502
503
504
505
506
507
508
509
510
511
512
513
514
        for ( int i_index = 0; i_index < p_config->i_list; i_index++ )
        {
            combo->addItem( qfu( p_config->ppsz_list_text[i_index] ),
                    QVariant( p_config->pi_list[i_index] ) );
            if( p_config->value.i == p_config->pi_list[i_index] )
            {
                combo->setCurrentIndex( i_index );
            }
        }
        combo->setToolTip( qfu( p_config->psz_longtext ) );
    }
}

zorglub's avatar
zorglub committed
515
516
/********* Module **********/
ModuleConfigControl::ModuleConfigControl( vlc_object_t *_p_this,
zorglub's avatar
zorglub committed
517
               module_config_t *_p_item, QWidget *_parent, bool bycat,
518
               QGridLayout *l, int &line) :
zorglub's avatar
zorglub committed
519
               VStringConfigControl( _p_this, _p_item, _parent )
zorglub's avatar
zorglub committed
520
{
Christophe Mutricy's avatar
Christophe Mutricy committed
521
    label = new QLabel( qtr(p_item->psz_text) );
zorglub's avatar
zorglub committed
522
    combo = new QComboBox();
523
    combo->setMinimumWidth( MINWIDTH_BOX );
zorglub's avatar
zorglub committed
524
525
526
527
    finish( bycat );
    if( !l )
    {
        QHBoxLayout *layout = new QHBoxLayout();
528
        layout->addWidget( label ); layout->addWidget( combo, LAST_COLUMN );
zorglub's avatar
zorglub committed
529
530
531
532
533
        widget->setLayout( layout );
    }
    else
    {
        l->addWidget( label, line, 0 );
534
        l->addWidget( combo, line, LAST_COLUMN, Qt::AlignRight );
zorglub's avatar
zorglub committed
535
    }
zorglub's avatar
zorglub committed
536
}
537

zorglub's avatar
zorglub committed
538
ModuleConfigControl::ModuleConfigControl( vlc_object_t *_p_this,
zorglub's avatar
zorglub committed
539
                module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
zorglub's avatar
zorglub committed
540
541
542
                bool bycat ) : VStringConfigControl( _p_this, _p_item )
{
    combo = _combo;
zorglub's avatar
zorglub committed
543
544
    label = _label;
    finish( bycat );
zorglub's avatar
zorglub committed
545
546
}

zorglub's avatar
zorglub committed
547
void ModuleConfigControl::finish( bool bycat )
zorglub's avatar
zorglub committed
548
549
550
551
552
553
554
555
{
    vlc_list_t *p_list;
    module_t *p_parser;

    combo->setEditable( false );

    /* build a list of available modules */
    p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
556
    combo->addItem( qtr("Default") );
zorglub's avatar
zorglub committed
557
558
559
560
561
562
    for( int i_index = 0; i_index < p_list->i_count; i_index++ )
    {
        p_parser = (module_t *)p_list->p_values[i_index].p_object ;

        if( bycat )
        {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
563
            if( !strcmp( module_GetObjName( p_parser ), "main" ) ) continue;
zorglub's avatar
zorglub committed
564

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
565
566
567
568
569
            unsigned confsize;
            module_config_t *p_config;

            p_config = module_GetConfig (p_parser, &confsize);
             for (size_t i = 0; i < confsize; i++)
zorglub's avatar
zorglub committed
570
571
            {
                /* Hack: required subcategory is stored in i_min */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
572
573
574
                const module_config_t *p_cfg = p_config + i;
                if( p_cfg->i_type == CONFIG_SUBCATEGORY &&
                    p_cfg->value.i == p_item->min.i )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
575
576
                    combo->addItem( qtr( module_GetLongName( p_parser )),
                                    QVariant( module_GetObjName( p_parser ) ) );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
577
                if( p_item->value.psz && !strcmp( p_item->value.psz,
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
578
                                                  module_GetObjName( p_parser ) ) )
zorglub's avatar
zorglub committed
579
                    combo->setCurrentIndex( combo->count() - 1 );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
580
            }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
581
            module_PutConfig (p_config);
zorglub's avatar
zorglub committed
582
        }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
583
        else if( module_IsCapable( p_parser, p_item->psz_type ) )
zorglub's avatar
zorglub committed
584
        {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
585
586
            combo->addItem( qtr(module_GetLongName( p_parser ) ),
                            QVariant( module_GetObjName( p_parser ) ) );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
587
            if( p_item->value.psz && !strcmp( p_item->value.psz,
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
588
                                              module_GetObjName( p_parser ) ) )
zorglub's avatar
zorglub committed
589
590
591
592
                combo->setCurrentIndex( combo->count() - 1 );
        }
    }
    vlc_list_release( p_list );
Christophe Mutricy's avatar
Christophe Mutricy committed
593
    combo->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
dionoea's avatar
dionoea committed
594
    if( label )
Christophe Mutricy's avatar
Christophe Mutricy committed
595
        label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
zorglub's avatar
zorglub committed
596
597
598
599
600
601
}

QString ModuleConfigControl::getValue()
{
    return combo->itemData( combo->currentIndex() ).toString();
}
zorglub's avatar
zorglub committed
602

603
604
/********* Module list **********/
ModuleListConfigControl::ModuleListConfigControl( vlc_object_t *_p_this,
605
606
607
        module_config_t *_p_item, QWidget *_parent, bool bycat,
        QGridLayout *l, int &line) :
    VStringConfigControl( _p_this, _p_item, _parent )
608
{
Christophe Mutricy's avatar
Christophe Mutricy committed
609
    groupBox = new QGroupBox ( qtr(p_item->psz_text) );
610
    text = new QLineEdit();
611
612
    QGridLayout *layoutGroupBox = new QGridLayout( groupBox );

613
614
    finish( bycat );

615
    int boxline = 0;
616
    for( QVector<checkBoxListItem*>::iterator it = modules.begin();
617
            it != modules.end(); it++ )
618
    {
619
        layoutGroupBox->addWidget( (*it)->checkBox, boxline++, 0 );
620
621
622
    }
    layoutGroupBox->addWidget( text, boxline, 0 );

623
624
    if( !l )
    {
625
626
627
        QVBoxLayout *layout = new QVBoxLayout();
        layout->addWidget( groupBox, line, 0 );
        widget->setLayout( layout );
628
    }
629
    else
630
    {
631
        l->addWidget( groupBox, line, 0, 1, -1 );
632
    }
633

Christophe Mutricy's avatar
Christophe Mutricy committed
634
    text->setToolTip( formatTooltip( qtr( p_item->psz_longtext) ) );
635
636
637
638
}

ModuleListConfigControl::~ModuleListConfigControl()
{
639
    for( QVector<checkBoxListItem*>::iterator it = modules.begin();
640
            it != modules.end(); it++ )
641
642
643
    {
        delete *it;
    }
644
    delete groupBox;
645
646
647
    delete text;
}

648
649
#define CHECKBOX_LISTS \
{ \
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
650
       QCheckBox *cb = new QCheckBox( qtr( module_GetLongName( p_parser ) ) );\
651
652
653
       checkBoxListItem *cbl = new checkBoxListItem; \
\
       CONNECT( cb, stateChanged( int ), this, onUpdate( int ) );\
654
       cb->setToolTip( formatTooltip( qtr( module_GetHelp( p_parser ))));\
655
656
       cbl->checkBox = cb; \
\
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
657
       cbl->psz_module = strdup( module_GetObjName( p_parser ) ); \
658
       modules.push_back( cbl ); \
659
660
661
\
       if( p_item->value.psz && strstr( p_item->value.psz, cbl->psz_module ) ) \
            cbl->checkBox->setChecked( true ); \
662
}
663

664

665
666
667
668
669
670
671
672
673
674
675
676
677
void ModuleListConfigControl::finish( bool bycat )
{
    vlc_list_t *p_list;
    module_t *p_parser;

    /* build a list of available modules */
    p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
    for( int i_index = 0; i_index < p_list->i_count; i_index++ )
    {
        p_parser = (module_t *)p_list->p_values[i_index].p_object ;

        if( bycat )
        {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
678
            if( !strcmp( module_GetObjName( p_parser ), "main" ) ) continue;
679

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
680
681
682
683
            unsigned confsize;
            module_config_t *p_config = module_GetConfig (p_parser, &confsize);

            for (size_t i = 0; i < confsize; i++)
684
            {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
685
                module_config_t *p_cfg = p_config + i;
686
                /* Hack: required subcategory is stored in i_min */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
687
688
                if( p_cfg->i_type == CONFIG_SUBCATEGORY &&
                        p_cfg->value.i == p_item->min.i )
689
                {
690
                    CHECKBOX_LISTS;
691
                }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
692
            }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
693
            module_PutConfig (p_config);
694
        }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
695
        else if( module_IsCapable( p_parser, p_item->psz_type ) )
696
        {
697
            CHECKBOX_LISTS;
698
        }
699
700
    }
    vlc_list_release( p_list );
Christophe Mutricy's avatar
Christophe Mutricy committed
701
    text->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
702
    if( groupBox )
Christophe Mutricy's avatar
Christophe Mutricy committed
703
        groupBox->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
704
}
705
#undef CHECKBOX_LISTS
706
707
708
709
710
711
712
713

QString ModuleListConfigControl::getValue()
{
    return text->text();
}

void ModuleListConfigControl::hide()
{
714
    for( QVector<checkBoxListItem*>::iterator it = modules.begin();
715
716
         it != modules.end(); it++ )
    {
717
        (*it)->checkBox->hide();
718
    }
719
    groupBox->hide();
720
721
722
723
}

void ModuleListConfigControl::show()
{
724
    for( QVector<checkBoxListItem*>::iterator it = modules.begin();
725
726
         it != modules.end(); it++ )
    {
727
        (*it)->checkBox->show();
728
    }
729
    groupBox->show();
730
731
732
}


733
void ModuleListConfigControl::onUpdate( int value )
734
735
{
    text->clear();
736
737
    bool first = true;

738
    for( QVector<checkBoxListItem*>::iterator it = modules.begin();
739
740
         it != modules.end(); it++ )
    {
741
        if( (*it)->checkBox->isChecked() )
742
743
744
        {
            if( first )
            {
745
                text->setText( text->text() + (*it)->psz_module );
746
747
748
749
                first = false;
            }
            else
            {
750
                text->setText( text->text() + ":" + (*it)->psz_module );
751
752
            }
        }
753
754
755
    }
}

zorglub's avatar
zorglub committed
756
757
758
759
760
761
762
/**************************************************************************
 * Integer-based controls
 *************************************************************************/

/*********** Integer **************/
IntegerConfigControl::IntegerConfigControl( vlc_object_t *_p_this,
                                            module_config_t *_p_item,
zorglub's avatar
zorglub committed
763
                                            QWidget *_parent, QGridLayout *l,
764
                                            int &line ) :
zorglub's avatar
zorglub committed
765
766
                           VIntConfigControl( _p_this, _p_item, _parent )
{
Christophe Mutricy's avatar
Christophe Mutricy committed
767
    label = new QLabel( qtr(p_item->psz_text) );
768
    spin = new QSpinBox; spin->setMinimumWidth( MINWIDTH_BOX );
769
    spin->setAlignment( Qt::AlignRight );
770
    spin->setMaximumWidth( MINWIDTH_BOX );
zorglub's avatar
zorglub committed
771
    finish();
zorglub's avatar
zorglub committed
772

zorglub's avatar
zorglub committed
773
774
775
    if( !l )
    {
        QHBoxLayout *layout = new QHBoxLayout();
776
        layout->addWidget( label, 0 ); layout->addWidget( spin, LAST_COLUMN );
zorglub's avatar
zorglub committed
777
778
779
780
781
        widget->setLayout( layout );
    }
    else
    {
        l->addWidget( label, line, 0 );
782
        l->addWidget( spin, line, LAST_COLUMN, Qt::AlignRight );
zorglub's avatar
zorglub committed
783
    }
zorglub's avatar
zorglub committed
784
785
786
}
IntegerConfigControl::IntegerConfigControl( vlc_object_t *_p_this,
                                            module_config_t *_p_item,
zorglub's avatar
zorglub committed
787
                                            QLabel *_label, QSpinBox *_spin ) :
zorglub's avatar
zorglub committed
788
789
790
                                      VIntConfigControl( _p_this, _p_item )
{
    spin = _spin;
zorglub's avatar
zorglub committed
791
792
    label = _label;
    finish();
zorglub's avatar
zorglub committed
793
794
}

zorglub's avatar
zorglub committed
795
void IntegerConfigControl::finish()
zorglub's avatar
zorglub committed
796
{
zorglub's avatar
zorglub committed
797
    spin->setMaximum( 2000000000 );
798
    spin->setMinimum( -2000000000 );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
799
    spin->setValue( p_item->value.i );
Christophe Mutricy's avatar
Christophe Mutricy committed
800
    spin->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
dionoea's avatar
dionoea committed
801
    if( label )
Christophe Mutricy's avatar
Christophe Mutricy committed
802
        label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
zorglub's avatar
zorglub committed
803
804
805
806
807
808
}

int IntegerConfigControl::getValue()
{
    return spin->value();
}
dionoea's avatar
dionoea committed
809

810
811
812
813
/********* Integer range **********/
IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t *_p_this,
                                            module_config_t *_p_item,
                                            QWidget *_parent, QGridLayout *l,
814
                                            int &line ) :
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
            IntegerConfigControl( _p_this, _p_item, _parent, l, line )
{
    finish();
}

IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t *_p_this,
                                            module_config_t *_p_item,
                                            QLabel *_label, QSpinBox *_spin ) :
            IntegerConfigControl( _p_this, _p_item, _label, _spin )
{
    finish();
}

void IntegerRangeConfigControl::finish()
{
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
830
831
    spin->setMaximum( p_item->max.i );
    spin->setMinimum( p_item->min.i );
832
833
}

834
835
836
IntegerRangeSliderConfigControl::IntegerRangeSliderConfigControl(
                                            vlc_object_t *_p_this,
                                            module_config_t *_p_item,
837
                                            QLabel *_label, QSlider *_slider ):
838
839
840
841
842
843
844
                    VIntConfigControl( _p_this, _p_item )
{
    slider = _slider;
    label = _label;
    slider->setMaximum( p_item->max.i );
    slider->setMinimum( p_item->min.i );
    slider->setValue( p_item->value.i );
Christophe Mutricy's avatar
Christophe Mutricy committed
845
    slider->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
846
    if( label )
Christophe Mutricy's avatar
Christophe Mutricy committed
847
        label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
848
849
850
851
852
853
854
855
}

int IntegerRangeSliderConfigControl::getValue()
{
        return slider->value();
}


dionoea's avatar
dionoea committed
856
857
858
/********* Integer / choice list **********/
IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *_p_this,
               module_config_t *_p_item, QWidget *_parent, bool bycat,
859
               QGridLayout *l, int &line) :
dionoea's avatar
dionoea committed
860
861
               VIntConfigControl( _p_this, _p_item, _parent )
{
Christophe Mutricy's avatar
Christophe Mutricy committed
862
    label = new QLabel( qtr(p_item->psz_text) );
dionoea's avatar
dionoea committed
863
    combo = new QComboBox();
864
    combo->setMinimumWidth( MINWIDTH_BOX );
865

866
    module_config_t *p_module_config = config_FindConfig( p_this, p_item->psz_name );
867
    if(p_module_config && p_module_config->pf_update_list)
868
869
870
    {
       vlc_value_t val;
       val.i_int = p_module_config->value.i;
871

872
873
874
875
876
877
878
879
       p_module_config->pf_update_list(p_this, p_item->psz_name, val, val, NULL);

       // assume in any case that dirty was set to VLC_TRUE
       // because lazy programmes will use the same callback for
       // this, like the one behind the refresh push button?
       p_module_config->b_dirty = VLC_FALSE;
    }

880
881

    finish( p_module_config, bycat );
dionoea's avatar
dionoea committed
882
883
884
    if( !l )
    {
        QHBoxLayout *layout = new QHBoxLayout();
885
        layout->addWidget( label ); layout->addWidget( combo, LAST_COLUMN );
dionoea's avatar
dionoea committed
886
887
888
889
890
        widget->setLayout( layout );
    }
    else
    {
        l->addWidget( label, line, 0 );
891
        l->addWidget( combo, line, LAST_COLUMN, Qt::AlignRight );
dionoea's avatar
dionoea committed
892
    }
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911

    if( p_item->i_action )
    {
        QSignalMapper *signalMapper = new QSignalMapper(this);

        /* Some stringLists like Capture listings have action associated */
        for( int i = 0; i < p_item->i_action; i++ )
        {
            QPushButton *button =
                new QPushButton( qfu( p_item->ppsz_action_text[i] ));
            CONNECT( button, clicked(), signalMapper, map() );
            signalMapper->setMapping( button, i );
            l->addWidget( button, line, LAST_COLUMN - p_item->i_action + i,
                    Qt::AlignRight );
        }
        CONNECT( signalMapper, mapped( int ),
                this, actionRequested( int ) );
    }

dionoea's avatar
dionoea committed
912
913
914
915
916
917
918
}
IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *_p_this,
                module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
                bool bycat ) : VIntConfigControl( _p_this, _p_item )
{
    combo = _combo;
    label = _label;
919
920
921
922

    module_config_t *p_module_config = config_FindConfig( p_this, getName() );

    finish( p_module_config, bycat );
dionoea's avatar
dionoea committed
923
924
}

925
void IntegerListConfigControl::finish(module_config_t *p_module_config, bool bycat )
dionoea's avatar
dionoea committed
926
927
928
{
    combo->setEditable( false );

929
930
931
    if(!p_module_config) return;

    for( int i_index = 0; i_index < p_module_config->i_list; i_index++ )
dionoea's avatar
dionoea committed
932
    {
933
934
935
        combo->addItem( qtr(p_module_config->ppsz_list_text[i_index] ),
                        QVariant( p_module_config->pi_list[i_index] ) );
        if( p_module_config->value.i == p_module_config->pi_list[i_index] )
dionoea's avatar
dionoea committed
936
937
            combo->setCurrentIndex( combo->count() - 1 );
    }
938
    combo->setToolTip( formatTooltip(qtr(p_module_config->psz_longtext)) );
dionoea's avatar
dionoea committed
939
    if( label )
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
        label->setToolTip( formatTooltip(qtr(p_module_config->psz_longtext)) );
}

void IntegerListConfigControl::actionRequested( int i_action )
{
    /* Supplementary check for boundaries */
    if( i_action < 0 || i_action >= p_item->i_action ) return;

    module_config_t *p_module_config = config_FindConfig( p_this, getName() );
    if(!p_module_config) return;


    vlc_value_t val;
    val.i_int = combo->itemData( combo->currentIndex() ).toInt();

    p_module_config->ppf_action[i_action]( p_this, getName(), val, val, 0 );

    if( p_module_config->b_dirty )
    {
        combo->clear();
        finish( p_module_config, true );
        p_module_config->b_dirty = VLC_FALSE;
    }
dionoea's avatar
dionoea committed
963
964
965
966
967
968
}

int IntegerListConfigControl::getValue()
{
    return combo->itemData( combo->currentIndex() ).toInt();
}
969
970
971
972
973

/*********** Boolean **************/
BoolConfigControl::BoolConfigControl( vlc_object_t *_p_this,
                                      module_config_t *_p_item,
                                      QWidget *_parent, QGridLayout *l,
974
                                      int &line ) :
975
976
                    VIntConfigControl( _p_this, _p_item, _parent )
{
Christophe Mutricy's avatar
Christophe Mutricy committed
977
    checkbox = new QCheckBox( qtr(p_item->psz_text) );
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
    finish();

    if( !l )
    {
        QHBoxLayout *layout = new QHBoxLayout();
        layout->addWidget( checkbox, 0 );
        widget->setLayout( layout );
    }
    else
    {
        l->addWidget( checkbox, line, 0 );
    }
}
BoolConfigControl::BoolConfigControl( vlc_object_t *_p_this,
                                      module_config_t *_p_item,
                                      QLabel *_label,
                                      QCheckBox *_checkbox,
                                      bool bycat ) :