complete_preferences.cpp 23.6 KB
Newer Older
zorglub's avatar
zorglub committed
1
/*****************************************************************************
Pere Orga's avatar
Pere Orga committed
2
 * complete_preferences.cpp : "Normal preferences"
zorglub's avatar
zorglub committed
3
 ****************************************************************************
4
 * Copyright (C) 2006-2011 the VideoLAN team
5
 * $Id$
zorglub's avatar
zorglub committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
 *
 * 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.
 *****************************************************************************/
23
24
25
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
zorglub's avatar
zorglub committed
26

27
#include <QApplication>
zorglub's avatar
zorglub committed
28
29
30
31
32
33
34
35
36
#include <QLabel>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QVariant>
#include <QString>
#include <QFont>
#include <QGroupBox>
#include <QScrollArea>
#include <QVBoxLayout>
zorglub's avatar
zorglub committed
37
#include <QGridLayout>
zorglub's avatar
zorglub committed
38

39
#include "components/complete_preferences.hpp"
zorglub's avatar
zorglub committed
40
41
42
43
#include "components/preferences_widgets.hpp"

#include <vlc_config_cat.h>
#include <vlc_intf_strings.h>
44
#include <vlc_modules.h>
45
#include <vlc_plugin.h>
zorglub's avatar
zorglub committed
46
47
#include <assert.h>

zorglub's avatar
zorglub committed
48
49
50
51
52
53
54
55
#define ITEM_HEIGHT 25

/*********************************************************************
 * The Tree
 *********************************************************************/
PrefsTree::PrefsTree( intf_thread_t *_p_intf, QWidget *_parent ) :
                            QTreeWidget( _parent ), p_intf( _p_intf )
{
56
    b_show_only_loaded = false;
57
    /* General Qt options */
zorglub's avatar
zorglub committed
58
    setAlternatingRowColors( true );
59
    setHeaderHidden( true );
60

zorglub's avatar
zorglub committed
61
    setIconSize( QSize( ITEM_HEIGHT,ITEM_HEIGHT ) );
62
    setTextElideMode( Qt::ElideNone );
zorglub's avatar
zorglub committed
63

64
65
66
    setUniformRowHeights( true );
    CONNECT( this, itemExpanded(QTreeWidgetItem*), this, resizeColumns() );

67
    /* Nice icons */
68
#define BI( a,b) QIcon a##_icon = QIcon( b )
69
70
71
72
73
74
75
    BI( audio, ":/prefsmenu/advanced/audio" );
    BI( video, ":/prefsmenu/advanced/video" );
    BI( input, ":/prefsmenu/advanced/codec" );
    BI( sout, ":/prefsmenu/advanced/sout" );
    BI( advanced, ":/prefsmenu/advanced/extended" );
    BI( playlist, ":/prefsmenu/advanced/playlist" );
    BI( interface, ":/prefsmenu/advanced/intf" );
zorglub's avatar
zorglub committed
76
77
78
#undef BI

    /* Build the tree for the main module */
79
    module_t *p_module = module_get_main();
zorglub's avatar
zorglub committed
80

81
    /* Initialisation and get the confsize */
zorglub's avatar
zorglub committed
82
    PrefsItemData *data = NULL;
83
    PrefsItemData *data_sub = NULL;
zorglub's avatar
zorglub committed
84
    QTreeWidgetItem *current_item = NULL;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
85
    unsigned confsize;
86
    module_config_t *const p_config = module_config_get (p_module, &confsize);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
87

88
89
    /* Go through the list of conf */
    for( size_t i = 0; i < confsize; i++ )
zorglub's avatar
zorglub committed
90
    {
Christophe Mutricy's avatar
Christophe Mutricy committed
91
        const char *psz_help;
zorglub's avatar
zorglub committed
92
        QIcon icon;
93
94
95
96

        /* Work on a new item */
        module_config_t *p_item = p_config + i;

zorglub's avatar
zorglub committed
97
        switch( p_item->i_type )
zorglub's avatar
zorglub committed
98
        {
99
        /* This is a category */
zorglub's avatar
zorglub committed
100
        case CONFIG_CATEGORY:
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
101
            if( p_item->value.i == -1 ) break;
102
103

            /* PrefsItemData Init */
zorglub's avatar
zorglub committed
104
            data = new PrefsItemData();
105
            data->name = qtr( config_CategoryNameGet( p_item->value.i ) );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
106
            psz_help = config_CategoryHelpGet( p_item->value.i );
zorglub's avatar
zorglub committed
107
            if( psz_help )
108
                data->help = qtr( psz_help );
zorglub's avatar
zorglub committed
109
110
            else
                data->help.clear();
111
            data->i_type = PrefsItemData::TYPE_CATEGORY;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
112
            data->i_object_id = p_item->value.i;
zorglub's avatar
zorglub committed
113

114
            /* This is a category, put a nice icon */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
115
            switch( p_item->value.i )
zorglub's avatar
zorglub committed
116
117
            {
#define CI(a,b) case a: icon = b##_icon;break
zorglub's avatar
zorglub committed
118
119
120
121
122
123
124
125
            CI( CAT_AUDIO, audio );
            CI( CAT_VIDEO, video );
            CI( CAT_INPUT, input );
            CI( CAT_SOUT, sout );
            CI( CAT_ADVANCED, advanced );
            CI( CAT_PLAYLIST, playlist );
            CI( CAT_INTERFACE, interface );
            }
126
#undef CI
zorglub's avatar
zorglub committed
127

128
            /* Create a new QTreeItem to display it in the tree at top level */
zorglub's avatar
zorglub committed
129
130
131
            current_item = new QTreeWidgetItem();
            current_item->setText( 0, data->name );
            current_item->setIcon( 0 , icon );
132
            //current_item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );
zorglub's avatar
zorglub committed
133
134
135
            current_item->setData( 0, Qt::UserRole,
                                   qVariantFromValue( data ) );
            addTopLevelItem( current_item );
136
            expandItem( current_item );
zorglub's avatar
zorglub committed
137
            break;
138
139

        /* This is a subcategory */
zorglub's avatar
zorglub committed
140
        case CONFIG_SUBCATEGORY:
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
141
            if( p_item->value.i == -1 ) break;
142
143

            /* Special cases: move the main subcategories to the parent cat*/
zorglub's avatar
zorglub committed
144
            if( data &&
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
145
146
147
148
149
150
151
                ( p_item->value.i == SUBCAT_VIDEO_GENERAL ||
                  p_item->value.i == SUBCAT_ADVANCED_MISC ||
                  p_item->value.i == SUBCAT_INPUT_GENERAL ||
                  p_item->value.i == SUBCAT_INTERFACE_GENERAL ||
                  p_item->value.i == SUBCAT_SOUT_GENERAL||
                  p_item->value.i == SUBCAT_PLAYLIST_GENERAL||
                  p_item->value.i == SUBCAT_AUDIO_GENERAL ) )
zorglub's avatar
zorglub committed
152
            {
153
                /* Data still contains the correct thing */
154
                data->i_type = PrefsItemData::TYPE_CATSUBCAT;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
155
                data->i_subcat_id = p_item->value.i;
156
                data->name = qtr( config_CategoryNameGet( p_item->value.i ) );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
157
                psz_help = config_CategoryHelpGet( p_item->value.i );
zorglub's avatar
zorglub committed
158
                if( psz_help )
159
                    data->help = qtr( psz_help );
zorglub's avatar
zorglub committed
160
161
                else
                    data->help.clear();
zorglub's avatar
zorglub committed
162
163
164
                current_item->setData( 0, Qt::UserRole,
                                       QVariant::fromValue( data ) );
                continue;
zorglub's avatar
zorglub committed
165
            }
166

167
168
169
170
171
            /* Normal Subcategories */

            /* Process the Data */
            data_sub = new PrefsItemData();
            data_sub->name = qtr( config_CategoryNameGet( p_item->value.i) );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
172
            psz_help = config_CategoryHelpGet( p_item->value.i );
zorglub's avatar
zorglub committed
173
            if( psz_help )
174
                data_sub->help = qtr( psz_help );
zorglub's avatar
zorglub committed
175
            else
176
                data_sub->help.clear();
177
            data_sub->i_type = PrefsItemData::TYPE_SUBCATEGORY;
178
            data_sub->i_object_id = p_item->value.i;
zorglub's avatar
zorglub committed
179

180
            /* Create a new TreeWidget */
zorglub's avatar
zorglub committed
181
            QTreeWidgetItem *subcat_item = new QTreeWidgetItem();
182
            subcat_item->setText( 0, data_sub->name );
zorglub's avatar
zorglub committed
183
            subcat_item->setData( 0, Qt::UserRole,
184
                                  qVariantFromValue( data_sub ) );
185
            //subcat_item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );
186
187
188

            /* Add it to the parent */
            assert( current_item );
zorglub's avatar
zorglub committed
189
190
            current_item->addChild( subcat_item );
            break;
191
192

        /* Other items don't need yet a place on the tree */
zorglub's avatar
zorglub committed
193
        }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
194
    }
195
    module_config_free( p_config );
196

197
198
    size_t count;
    module_t **p_list = module_list_get( &count );
zorglub's avatar
zorglub committed
199
    /* Build the tree of plugins */
200
    for( size_t i = 0; i < count; i++ )
zorglub's avatar
zorglub committed
201
    {
202
        p_module = p_list[i];
zorglub's avatar
zorglub committed
203
        // Main module excluded
204
        if( module_is_main( p_module) ) continue;
zorglub's avatar
zorglub committed
205

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
206
207
208
        unsigned  confsize;
        int i_subcategory = 0, i_category = 0;

209
        bool b_options = false;
210
        module_config_t *const p_config = module_config_get (p_module, &confsize);
211

212
        /* Loop through the configurations items */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
213
        for (size_t i = 0; i < confsize; i++)
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
214
        {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
215
            const module_config_t *p_item = p_config + i;
zorglub's avatar
zorglub committed
216
217

            if( p_item->i_type == CONFIG_CATEGORY )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
218
                i_category = p_item->value.i;
zorglub's avatar
zorglub committed
219
            else if( p_item->i_type == CONFIG_SUBCATEGORY )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
220
                i_subcategory = p_item->value.i;
221

222
            if( CONFIG_ITEM(p_item->i_type) )
223
                b_options = true;
zorglub's avatar
zorglub committed
224

225
            if( b_options && i_category && i_subcategory )
zorglub's avatar
zorglub committed
226
                break;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
227
        }
228
        module_config_free (p_config);
229
230

        /* Dummy item, please proceed */
231
        if( !b_options || i_category == 0 || i_subcategory == 0 ) continue;
zorglub's avatar
zorglub committed
232

233

zorglub's avatar
zorglub committed
234
235
236
        // Locate the category item;
        QTreeWidgetItem *subcat_item = NULL;
        bool b_found = false;
237

zorglub's avatar
zorglub committed
238
239
240
        for( int i_cat_index = 0 ; i_cat_index < topLevelItemCount();
                                   i_cat_index++ )
        {
241
            /* Get the treeWidgetItem that correspond to the category */
zorglub's avatar
zorglub committed
242
243
244
            QTreeWidgetItem *cat_item = topLevelItem( i_cat_index );
            PrefsItemData *data = cat_item->data( 0, Qt::UserRole ).
                                             value<PrefsItemData *>();
245
246

            /* If we match the good category */
zorglub's avatar
zorglub committed
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
            if( data->i_object_id == i_category )
            {
                for( int i_sc_index = 0; i_sc_index < cat_item->childCount();
                         i_sc_index++ )
                {
                    subcat_item = cat_item->child( i_sc_index );
                    PrefsItemData *sc_data = subcat_item->data(0, Qt::UserRole).
                                                value<PrefsItemData *>();
                    if( sc_data && sc_data->i_object_id == i_subcategory )
                    {
                        b_found = true;
                        break;
                    }
                }
                if( !b_found )
                {
                    subcat_item = cat_item;
                    b_found = true;
                }
                break;
            }
        }
        if( !b_found ) continue;

        PrefsItemData *module_data = new PrefsItemData();
272
        module_data->i_type = PrefsItemData::TYPE_MODULE;
273
        module_data->psz_shortcut = strdup( module_get_object( p_module ) );
274
        module_data->name = qtr( module_get_name( p_module, false ) );
zorglub's avatar
zorglub committed
275
        module_data->help.clear();
276
277
278
279
        const char *psz_help = module_get_help( p_module );
        if ( psz_help )
            module_data->help = qtr( psz_help );

zorglub's avatar
zorglub committed
280
        QTreeWidgetItem *module_item = new QTreeWidgetItem();
281
        module_item->setText( 0, module_data->name );
zorglub's avatar
zorglub committed
282
283
        module_item->setData( 0, Qt::UserRole,
                              QVariant::fromValue( module_data) );
284
        //module_item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );
zorglub's avatar
zorglub committed
285
286
287
288
289
290
        subcat_item->addChild( module_item );
    }

    /* We got everything, just sort a bit */
    sortItems( 0, Qt::AscendingOrder );

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
291
    module_list_free( p_list );
292
    resizeColumnToContents( 0 );
zorglub's avatar
zorglub committed
293
294
}

zorglub's avatar
zorglub committed
295
void PrefsTree::applyAll()
zorglub's avatar
zorglub committed
296
{
zorglub's avatar
zorglub committed
297
    doAll( false );
zorglub's avatar
zorglub committed
298
299
}

zorglub's avatar
zorglub committed
300
void PrefsTree::cleanAll()
zorglub's avatar
zorglub committed
301
{
zorglub's avatar
zorglub committed
302
    doAll( true );
zorglub's avatar
zorglub committed
303
304
}

zorglub's avatar
zorglub committed
305
void PrefsTree::doAll( bool doclean )
zorglub's avatar
zorglub committed
306
307
308
309
310
{
    for( int i_cat_index = 0 ; i_cat_index < topLevelItemCount();
             i_cat_index++ )
    {
        QTreeWidgetItem *cat_item = topLevelItem( i_cat_index );
zorglub's avatar
zorglub committed
311
        for( int i_sc_index = 0; i_sc_index < cat_item->childCount();
zorglub's avatar
zorglub committed
312
313
314
                 i_sc_index++ )
        {
            QTreeWidgetItem *sc_item = cat_item->child( i_sc_index );
zorglub's avatar
zorglub committed
315
            for( int i_module = 0 ; i_module < sc_item->childCount();
zorglub's avatar
zorglub committed
316
317
                     i_module++ )
            {
zorglub's avatar
zorglub committed
318
319
                PrefsItemData *data = sc_item->child( i_module )->
                               data( 0, Qt::UserRole).value<PrefsItemData *>();
zorglub's avatar
zorglub committed
320
                if( data->panel && doclean )
zorglub's avatar
zorglub committed
321
322
323
324
                {
                    delete data->panel;
                    data->panel = NULL;
                }
zorglub's avatar
zorglub committed
325
                else if( data->panel )
zorglub's avatar
zorglub committed
326
                    data->panel->apply();
zorglub's avatar
zorglub committed
327
            }
zorglub's avatar
zorglub committed
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
            PrefsItemData *data = sc_item->data( 0, Qt::UserRole).
                                            value<PrefsItemData *>();
            if( data->panel && doclean )
            {
                delete data->panel;
                data->panel = NULL;
            }
            else if( data->panel )
                data->panel->apply();
        }
        PrefsItemData *data = cat_item->data( 0, Qt::UserRole).
                                            value<PrefsItemData *>();
        if( data->panel && doclean )
        {
            delete data->panel;
            data->panel = NULL;
zorglub's avatar
zorglub committed
344
        }
zorglub's avatar
zorglub committed
345
346
        else if( data->panel )
            data->panel->apply();
zorglub's avatar
zorglub committed
347
348
349
    }
}

Yuval Tze's avatar
Yuval Tze committed
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
/* apply filter on tree item and recursively on its sub items
 * returns whether the item was filtered */
bool PrefsTree::filterItems( QTreeWidgetItem *item, const QString &text,
                           Qt::CaseSensitivity cs )
{
    bool sub_filtered = true;

    for( int i = 0; i < item->childCount(); i++ )
    {
        QTreeWidgetItem *sub_item = item->child( i );
        if ( !filterItems( sub_item, text, cs ) )
        {
            /* not all the sub items were filtered */
            sub_filtered = false;
        }
    }

    PrefsItemData *data = item->data( 0, Qt::UserRole ).value<PrefsItemData *>();

    bool filtered = sub_filtered && !data->contains( text, cs );
370
371
    if ( b_show_only_loaded && sub_filtered && !data->b_loaded )
        filtered = true;
Yuval Tze's avatar
Yuval Tze committed
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    item->setExpanded( !sub_filtered );
    item->setHidden( filtered );

    return filtered;
}


/* collapse item if it's not selected or one of its sub items
 * returns whether the item was collapsed */
bool PrefsTree::collapseUnselectedItems( QTreeWidgetItem *item )
{
    bool sub_collapsed = true;

    for( int i = 0; i < item->childCount(); i++ )
    {
        QTreeWidgetItem *sub_item = item->child( i );
        if ( !collapseUnselectedItems( sub_item ) )
        {
            /* not all the sub items were collapsed */
            sub_collapsed = false;
        }
    }

    bool collapsed = sub_collapsed && !item->isSelected();
    item->setExpanded( !sub_collapsed );
    item->setHidden( false );

    return collapsed;
}

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
static void populateLoadedSet( QSet<QString> *loaded, vlc_object_t *p_node )
{
    Q_ASSERT( loaded );
    char *name = vlc_object_get_name( p_node );
    if ( !EMPTY_STR( name ) ) loaded->insert( QString( name ) );
    free( name );

    vlc_list_t *l = vlc_list_children( p_node );
    for( int i=0; i < l->i_count; i++ )
        populateLoadedSet( loaded, l->p_values[i].p_object );
    vlc_list_release( l );
}

/* Updates the PrefsItemData loaded status to reflect currently
 * running modules */
void PrefsTree::updateLoadedStatus( QTreeWidgetItem *item = NULL,
                                    QSet<QString> *loaded = NULL )
{
    bool b_release = false;

    if( loaded == NULL )
    {
        vlc_object_t *p_root = VLC_OBJECT( p_intf->p_libvlc );
        loaded = new QSet<QString>();
        populateLoadedSet( loaded, p_root );
        b_release = true;
    }

    if ( item == NULL )
    {
        for( int i = 0 ; i < topLevelItemCount(); i++ )
            updateLoadedStatus( topLevelItem( i ), loaded );
    }
    else
    {
        PrefsItemData *data = item->data( 0, Qt::UserRole )
                .value<PrefsItemData *>();
439
        data->b_loaded = loaded->contains( QString( data->psz_shortcut ) );
440
441
442
443
444
445
446
447
448

        for( int i = 0; i < item->childCount(); i++ )
            updateLoadedStatus( item->child( i ), loaded );
    }

    if ( b_release )
        delete loaded;
}

Yuval Tze's avatar
Yuval Tze committed
449
450
451
/* apply filter on tree */
void PrefsTree::filter( const QString &text )
{
452
453
454
    bool clear_filter = text.isEmpty() && ! b_show_only_loaded;

    updateLoadedStatus();
Yuval Tze's avatar
Yuval Tze committed
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

    for( int i = 0 ; i < topLevelItemCount(); i++ )
    {
        QTreeWidgetItem *cat_item = topLevelItem( i );
        if ( clear_filter )
        {
            collapseUnselectedItems( cat_item );
        }
        else
        {
            filterItems( cat_item, text, Qt::CaseInsensitive );
        }
    }
}

470
471
472
473
474
475
void PrefsTree::setLoadedOnly( bool b_only )
{
    b_show_only_loaded = b_only;
    filter( "" );
}

476
477
478
479
480
void PrefsTree::resizeColumns()
{
    resizeColumnToContents( 0 );
}

481
482
483
484
485
PrefsItemData::PrefsItemData()
{
    panel = NULL;
    i_object_id = 0;
    i_subcat_id = -1;
486
    psz_shortcut = NULL;
487
488
489
    b_loaded = false;
}

Yuval Tze's avatar
Yuval Tze committed
490
491
492
493
494
495
496
497
498
/* go over the module config items and search text in psz_text
 * also search the module name and head */
bool PrefsItemData::contains( const QString &text, Qt::CaseSensitivity cs )
{
    /* Find our module */
    module_t *p_module = NULL;
    if( this->i_type == TYPE_CATEGORY )
        return false;
    else if( this->i_type == TYPE_MODULE )
499
        p_module = module_find( this->psz_shortcut );
Yuval Tze's avatar
Yuval Tze committed
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
    else
    {
        p_module = module_get_main();
        assert( p_module );
    }

    unsigned confsize;
    module_config_t *const p_config = module_config_get (p_module, &confsize),
                    *p_item = p_config,
                    *p_end = p_config + confsize;

    if( this->i_type == TYPE_SUBCATEGORY || this->i_type ==  TYPE_CATSUBCAT )
    {
        while ( p_item < p_end )
        {
            if( p_item->i_type == CONFIG_SUBCATEGORY &&
                (
                    ( this->i_type == TYPE_SUBCATEGORY &&
                              p_item->value.i == this->i_object_id )
                    ||
                    ( this->i_type == TYPE_CATSUBCAT &&
                              p_item->value.i == this->i_subcat_id )
                )
              )
                break;
            p_item++;
        }
    }

    QString head;

    if( this->i_type == TYPE_SUBCATEGORY || this->i_type ==  TYPE_CATSUBCAT )
    {
        head.clear();
        p_item++; // Why that ? +1
    }
    else
    {
        head = QString( qtr( module_GetLongName( p_module ) ) );
    }

    if (name.contains( text, cs ) || head.contains( text, cs ) || help.contains( text, cs ))
ivoire's avatar
ivoire committed
542
543
    {
        module_config_free( p_config );
Yuval Tze's avatar
Yuval Tze committed
544
        return true;
ivoire's avatar
ivoire committed
545
    }
Yuval Tze's avatar
Yuval Tze committed
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560

    if( p_item ) do
    {
        if (
            (
                ( this->i_type == TYPE_SUBCATEGORY && p_item->value.i != this->i_object_id )
                ||
                ( this->i_type == TYPE_CATSUBCAT && p_item->value.i != this->i_subcat_id )
            ) &&
            ( p_item->i_type == CONFIG_CATEGORY || p_item->i_type == CONFIG_SUBCATEGORY )
           ) break;

        if( p_item->b_internal ) continue;

        if ( p_item->psz_text && qtr( p_item->psz_text ).contains( text, cs ) )
ivoire's avatar
ivoire committed
561
562
        {
            module_config_free( p_config );
Yuval Tze's avatar
Yuval Tze committed
563
            return true;
ivoire's avatar
ivoire committed
564
        }
Yuval Tze's avatar
Yuval Tze committed
565
566
567
568
569
570
571
572
573
574
    }
    while (
            !(
                ( this->i_type == TYPE_SUBCATEGORY || this->i_type == TYPE_CATSUBCAT )
                &&
                ( p_item->i_type == CONFIG_CATEGORY || p_item->i_type == CONFIG_SUBCATEGORY )
             )
             && ( ++p_item < p_end )
          );

ivoire's avatar
ivoire committed
575
    module_config_free( p_config );
Yuval Tze's avatar
Yuval Tze committed
576
577
578
    return false;
}

zorglub's avatar
zorglub committed
579
580
581
/*********************************************************************
 * The Panel
 *********************************************************************/
582
AdvPrefsPanel::AdvPrefsPanel( QWidget *_parent ) : QWidget( _parent )
zorglub's avatar
zorglub committed
583
584
{}

585
AdvPrefsPanel::AdvPrefsPanel( intf_thread_t *_p_intf, QWidget *_parent,
zorglub's avatar
zorglub committed
586
                        PrefsItemData * data ) :
zorglub's avatar
zorglub committed
587
588
                        QWidget( _parent ), p_intf( _p_intf )
{
zorglub's avatar
zorglub committed
589
    /* Find our module */
zorglub's avatar
zorglub committed
590
    module_t *p_module = NULL;
591
    if( data->i_type == PrefsItemData::TYPE_CATEGORY )
zorglub's avatar
zorglub committed
592
        return;
593
    else if( data->i_type == PrefsItemData::TYPE_MODULE )
594
        p_module = module_find( data->psz_shortcut );
zorglub's avatar
zorglub committed
595
596
    else
    {
597
        p_module = module_get_main();
zorglub's avatar
zorglub committed
598
        assert( p_module );
zorglub's avatar
zorglub committed
599
600
    }

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
601
    unsigned confsize;
ivoire's avatar
ivoire committed
602
    module_config_t *const p_config = module_config_get( p_module, &confsize ),
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
603
604
                    *p_item = p_config,
                    *p_end = p_config + confsize;
zorglub's avatar
zorglub committed
605

606
607
    if( data->i_type == PrefsItemData::TYPE_SUBCATEGORY ||
        data->i_type == PrefsItemData::TYPE_CATSUBCAT )
zorglub's avatar
zorglub committed
608
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
609
        while (p_item < p_end)
zorglub's avatar
zorglub committed
610
        {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
611
            if(  p_item->i_type == CONFIG_SUBCATEGORY &&
612
613
614
615
                 ( ( data->i_type == PrefsItemData::TYPE_SUBCATEGORY &&
                     p_item->value.i == data->i_object_id ) ||
                   ( data->i_type == PrefsItemData::TYPE_CATSUBCAT &&
                     p_item->value.i == data->i_subcat_id ) ) )
zorglub's avatar
zorglub committed
616
                break;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
617
618
            p_item++;
        }
zorglub's avatar
zorglub committed
619
620
    }

621
    /* Widgets now */
zorglub's avatar
zorglub committed
622
    global_layout = new QVBoxLayout();
623
    global_layout->setMargin( 2 );
zorglub's avatar
zorglub committed
624
    QString head;
625
626
627
628
    QString help;

    help = QString( data->help );

629
630
    if( data->i_type == PrefsItemData::TYPE_SUBCATEGORY ||
        data->i_type == PrefsItemData::TYPE_CATSUBCAT )
zorglub's avatar
zorglub committed
631
632
633
634
635
    {
        head = QString( data->name );
        p_item++; // Why that ?
    }
    else
636
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
637
        head = QString( qtr( module_GetLongName( p_module ) ) );
638
    }
zorglub's avatar
zorglub committed
639

640
    QLabel *titleLabel = new QLabel( head );
641
    QFont titleFont = QApplication::font();
642
643
644
645
646
647
648
    titleFont.setPointSize( titleFont.pointSize() + 6 );
    titleLabel->setFont( titleFont );

    // Title <hr>
    QFrame *title_line = new QFrame;
    title_line->setFrameShape(QFrame::HLine);
    title_line->setFrameShadow(QFrame::Sunken);
zorglub's avatar
zorglub committed
649

650
651
652
    QLabel *helpLabel = new QLabel( help, this );
    helpLabel->setWordWrap( true );

653
654
    global_layout->addWidget( titleLabel );
    global_layout->addWidget( title_line );
655
    global_layout->addWidget( helpLabel );
zorglub's avatar
zorglub committed
656
657

    QGroupBox *box = NULL;
zorglub's avatar
zorglub committed
658
    QGridLayout *boxlayout = NULL;
zorglub's avatar
zorglub committed
659
660

    QScrollArea *scroller= new QScrollArea;
661
    scroller->setFrameStyle( QFrame::NoFrame );
zorglub's avatar
zorglub committed
662
663
    QWidget *scrolled_area = new QWidget;

zorglub's avatar
zorglub committed
664
665
    QGridLayout *layout = new QGridLayout();
    int i_line = 0, i_boxline = 0;
666
    bool has_hotkey = false;
zorglub's avatar
zorglub committed
667
668
669

    if( p_item ) do
    {
670
        if( ( ( data->i_type == PrefsItemData::TYPE_SUBCATEGORY &&
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
671
                p_item->value.i != data->i_object_id ) ||
672
              ( data->i_type == PrefsItemData::TYPE_CATSUBCAT  &&
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
673
                p_item->value.i != data->i_subcat_id ) ) &&
zorglub's avatar
zorglub committed
674
675
676
            ( p_item->i_type == CONFIG_CATEGORY ||
              p_item->i_type == CONFIG_SUBCATEGORY ) )
            break;
ivoire's avatar
ivoire committed
677
        if( p_item->b_internal ) continue;
zorglub's avatar
zorglub committed
678
679
680
681
682
683

        if( p_item->i_type == CONFIG_SECTION )
        {
            if( box )
            {
                box->setLayout( boxlayout );
684
                box->show();
685
                layout->addWidget( box, i_line, 0, 1, -1 );
zorglub's avatar
zorglub committed
686
                i_line++;
zorglub's avatar
zorglub committed
687
            }
688
            box = new QGroupBox( qtr( p_item->psz_text ), this );
689
            box->hide();
zorglub's avatar
zorglub committed
690
691
            boxlayout = new QGridLayout();
        }
692
        /* Only one hotkey control */
693
        if( p_item->i_type == CONFIG_ITEM_KEY )
694
695
696
        {
            if( has_hotkey )
                continue;
697
            has_hotkey = true;
698
        }
zorglub's avatar
zorglub committed
699

zorglub's avatar
zorglub committed
700
701
702
        ConfigControl *control;
        if( ! box )
            control = ConfigControl::createControl( VLC_OBJECT( p_intf ),
703
                                        p_item, this, layout, i_line );
zorglub's avatar
zorglub committed
704
705
        else
            control = ConfigControl::createControl( VLC_OBJECT( p_intf ),
706
                                    p_item, this, boxlayout, i_boxline );
zorglub's avatar
zorglub committed
707
708
        if( !control )
            continue;
zorglub's avatar
zorglub committed
709

zorglub's avatar
zorglub committed
710
711
        if( box ) i_boxline++;
        else i_line++;
zorglub's avatar
zorglub committed
712
713
        controls.append( control );
    }
714
715
    while( !( ( data->i_type == PrefsItemData::TYPE_SUBCATEGORY ||
               data->i_type == PrefsItemData::TYPE_CATSUBCAT ) &&
zorglub's avatar
zorglub committed
716
             ( p_item->i_type == CONFIG_CATEGORY ||
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
717
718
               p_item->i_type == CONFIG_SUBCATEGORY ) )
        && ( ++p_item < p_end ) );
zorglub's avatar
zorglub committed
719

720
    if( box && i_boxline > 0 )
zorglub's avatar
zorglub committed
721
722
    {
        box->setLayout( boxlayout );
723
        box->show();
724
        layout->addWidget( box, i_line, 0, 1, -1 );
zorglub's avatar
zorglub committed
725
726
727
728
729
730
731
    }

    scrolled_area->setSizePolicy( QSizePolicy::Preferred,QSizePolicy::Fixed );
    scrolled_area->setLayout( layout );
    scroller->setWidget( scrolled_area );
    scroller->setWidgetResizable( true );
    global_layout->addWidget( scroller );
zorglub's avatar
zorglub committed
732
    setLayout( global_layout );
ivoire's avatar
ivoire committed
733
734

    module_config_free( p_config );
zorglub's avatar
zorglub committed
735
736
}

737
void AdvPrefsPanel::apply()
zorglub's avatar
zorglub committed
738
{
739
    foreach ( ConfigControl *cfg, controls )
740
        cfg->doApply();
zorglub's avatar
zorglub committed
741
}
742

743
void AdvPrefsPanel::clean()
zorglub's avatar
zorglub committed
744
{}
745
746
747
748
749
750

AdvPrefsPanel::~AdvPrefsPanel()
{
    qDeleteAll( controls ); controls.clear();
}