1 /*****************************************************************************
2 * preferences.cpp : "Normal preferences"
3 ****************************************************************************
4 * Copyright (C) 2006-2007 the VideoLAN team
7 * Authors: Clément Stenac <zorglub@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
27 #include <QApplication>
29 #include <QTreeWidget>
30 #include <QTreeWidgetItem>
35 #include <QScrollArea>
36 #include <QVBoxLayout>
37 #include <QGridLayout>
38 #include <QHeaderView>
40 #include "components/complete_preferences.hpp"
41 #include "components/preferences_widgets.hpp"
43 #include <vlc_config_cat.h>
44 #include <vlc_intf_strings.h>
45 #include <vlc_modules.h>
48 #define ITEM_HEIGHT 25
50 /*********************************************************************
52 *********************************************************************/
53 PrefsTree::PrefsTree( intf_thread_t
*_p_intf
, QWidget
*_parent
) :
54 QTreeWidget( _parent
), p_intf( _p_intf
)
56 /* General Qt options */
57 setAlternatingRowColors( true );
58 setHeaderHidden( true );
60 setIconSize( QSize( ITEM_HEIGHT
,ITEM_HEIGHT
) );
61 setTextElideMode( Qt::ElideNone
);
64 #define BI( a,b) QIcon a##_icon = QIcon( b )
65 BI( audio
, ":/prefsmenu/advanced/audio" );
66 BI( video
, ":/prefsmenu/advanced/video" );
67 BI( input
, ":/prefsmenu/advanced/codec" );
68 BI( sout
, ":/prefsmenu/advanced/sout" );
69 BI( advanced
, ":/prefsmenu/advanced/extended" );
70 BI( playlist
, ":/prefsmenu/advanced/playlist" );
71 BI( interface
, ":/prefsmenu/advanced/intf" );
74 /* Build the tree for the main module */
75 module_t
*p_module
= module_get_main();
77 /* Initialisation and get the confsize */
78 PrefsItemData
*data
= NULL
;
79 PrefsItemData
*data_sub
= NULL
;
80 QTreeWidgetItem
*current_item
= NULL
;
82 module_config_t
*const p_config
= module_config_get (p_module
, &confsize
);
84 /* Go through the list of conf */
85 for( size_t i
= 0; i
< confsize
; i
++ )
90 /* Work on a new item */
91 module_config_t
*p_item
= p_config
+ i
;
93 switch( p_item
->i_type
)
95 /* This is a category */
97 if( p_item
->value
.i
== -1 ) break;
99 /* PrefsItemData Init */
100 data
= new PrefsItemData();
101 data
->name
= qtr( config_CategoryNameGet( p_item
->value
.i
) );
102 psz_help
= config_CategoryHelpGet( p_item
->value
.i
);
104 data
->help
= qtr( psz_help
);
107 data
->i_type
= TYPE_CATEGORY
;
108 data
->i_object_id
= p_item
->value
.i
;
110 /* This is a category, put a nice icon */
111 switch( p_item
->value
.i
)
113 #define CI(a,b) case a: icon = b##_icon;break
114 CI( CAT_AUDIO
, audio
);
115 CI( CAT_VIDEO
, video
);
116 CI( CAT_INPUT
, input
);
117 CI( CAT_SOUT
, sout
);
118 CI( CAT_ADVANCED
, advanced
);
119 CI( CAT_PLAYLIST
, playlist
);
120 CI( CAT_INTERFACE
, interface
);
124 /* Create a new QTreeItem to display it in the tree at top level */
125 current_item
= new QTreeWidgetItem();
126 current_item
->setText( 0, data
->name
);
127 current_item
->setIcon( 0 , icon
);
128 //current_item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );
129 current_item
->setData( 0, Qt::UserRole
,
130 qVariantFromValue( data
) );
131 addTopLevelItem( current_item
);
134 /* This is a subcategory */
135 case CONFIG_SUBCATEGORY
:
136 if( p_item
->value
.i
== -1 ) break;
138 /* Special cases: move the main subcategories to the parent cat*/
140 ( p_item
->value
.i
== SUBCAT_VIDEO_GENERAL
||
141 p_item
->value
.i
== SUBCAT_ADVANCED_MISC
||
142 p_item
->value
.i
== SUBCAT_INPUT_GENERAL
||
143 p_item
->value
.i
== SUBCAT_INTERFACE_GENERAL
||
144 p_item
->value
.i
== SUBCAT_SOUT_GENERAL
||
145 p_item
->value
.i
== SUBCAT_PLAYLIST_GENERAL
||
146 p_item
->value
.i
== SUBCAT_AUDIO_GENERAL
) )
148 /* Data still contains the correct thing */
149 data
->i_type
= TYPE_CATSUBCAT
;
150 data
->i_subcat_id
= p_item
->value
.i
;
151 data
->name
= qtr( config_CategoryNameGet( p_item
->value
.i
) );
152 psz_help
= config_CategoryHelpGet( p_item
->value
.i
);
154 data
->help
= qtr( psz_help
);
157 current_item
->setData( 0, Qt::UserRole
,
158 QVariant::fromValue( data
) );
162 /* Normal Subcategories */
164 /* Process the Data */
165 data_sub
= new PrefsItemData();
166 data_sub
->name
= qtr( config_CategoryNameGet( p_item
->value
.i
) );
167 psz_help
= config_CategoryHelpGet( p_item
->value
.i
);
169 data_sub
->help
= qtr( psz_help
);
171 data_sub
->help
.clear();
172 data_sub
->i_type
= TYPE_SUBCATEGORY
;
173 data_sub
->i_object_id
= p_item
->value
.i
;
175 /* Create a new TreeWidget */
176 QTreeWidgetItem
*subcat_item
= new QTreeWidgetItem();
177 subcat_item
->setText( 0, data_sub
->name
);
178 subcat_item
->setData( 0, Qt::UserRole
,
179 qVariantFromValue( data_sub
) );
180 //subcat_item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );
182 /* Add it to the parent */
183 assert( current_item
);
184 current_item
->addChild( subcat_item
);
187 /* Other items don't need yet a place on the tree */
190 module_config_free( p_config
);
191 module_release( p_module
);
194 module_t
**p_list
= module_list_get( NULL
);
195 /* Build the tree of plugins */
196 for( size_t i
= 0; (p_module
= p_list
[i
]) != NULL
; i
++ )
198 // Main module excluded
199 if( module_is_main( p_module
) ) continue;
202 int i_subcategory
= 0, i_category
= 0;
204 bool b_options
= false;
205 module_config_t
*const p_config
= module_config_get (p_module
, &confsize
);
207 /* Loop through the configurations items */
208 for (size_t i
= 0; i
< confsize
; i
++)
210 const module_config_t
*p_item
= p_config
+ i
;
212 if( p_item
->i_type
== CONFIG_CATEGORY
)
213 i_category
= p_item
->value
.i
;
214 else if( p_item
->i_type
== CONFIG_SUBCATEGORY
)
215 i_subcategory
= p_item
->value
.i
;
217 if( p_item
->i_type
& CONFIG_ITEM
)
220 if( b_options
&& i_category
&& i_subcategory
)
223 module_config_free (p_config
);
225 /* Dummy item, please proceed */
226 if( !b_options
|| i_category
== 0 || i_subcategory
== 0 ) continue;
229 // Locate the category item;
230 QTreeWidgetItem
*subcat_item
= NULL
;
231 bool b_found
= false;
233 for( int i_cat_index
= 0 ; i_cat_index
< topLevelItemCount();
236 /* Get the treeWidgetItem that correspond to the category */
237 QTreeWidgetItem
*cat_item
= topLevelItem( i_cat_index
);
238 PrefsItemData
*data
= cat_item
->data( 0, Qt::UserRole
).
239 value
<PrefsItemData
*>();
241 /* If we match the good category */
242 if( data
->i_object_id
== i_category
)
244 for( int i_sc_index
= 0; i_sc_index
< cat_item
->childCount();
247 subcat_item
= cat_item
->child( i_sc_index
);
248 PrefsItemData
*sc_data
= subcat_item
->data(0, Qt::UserRole
).
249 value
<PrefsItemData
*>();
250 if( sc_data
&& sc_data
->i_object_id
== i_subcategory
)
258 subcat_item
= cat_item
;
264 if( !b_found
) continue;
266 PrefsItemData
*module_data
= new PrefsItemData();
267 module_data
->i_type
= TYPE_MODULE
;
268 module_data
->psz_name
= strdup( module_get_object( p_module
) );
269 module_data
->help
.clear();
270 QTreeWidgetItem
*module_item
= new QTreeWidgetItem();
271 module_item
->setText( 0, qtr( module_get_name( p_module
, false ) ) );
272 module_item
->setData( 0, Qt::UserRole
,
273 QVariant::fromValue( module_data
) );
274 //module_item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );
275 subcat_item
->addChild( module_item
);
278 /* We got everything, just sort a bit */
279 sortItems( 0, Qt::AscendingOrder
);
281 module_list_free( p_list
);
282 resizeColumnToContents( 0 );
285 PrefsTree::~PrefsTree() {}
287 void PrefsTree::applyAll()
292 void PrefsTree::cleanAll()
297 void PrefsTree::doAll( bool doclean
)
299 for( int i_cat_index
= 0 ; i_cat_index
< topLevelItemCount();
302 QTreeWidgetItem
*cat_item
= topLevelItem( i_cat_index
);
303 for( int i_sc_index
= 0; i_sc_index
< cat_item
->childCount();
306 QTreeWidgetItem
*sc_item
= cat_item
->child( i_sc_index
);
307 for( int i_module
= 0 ; i_module
< sc_item
->childCount();
310 PrefsItemData
*data
= sc_item
->child( i_module
)->
311 data( 0, Qt::UserRole
).value
<PrefsItemData
*>();
312 if( data
->panel
&& doclean
)
317 else if( data
->panel
)
318 data
->panel
->apply();
320 PrefsItemData
*data
= sc_item
->data( 0, Qt::UserRole
).
321 value
<PrefsItemData
*>();
322 if( data
->panel
&& doclean
)
327 else if( data
->panel
)
328 data
->panel
->apply();
330 PrefsItemData
*data
= cat_item
->data( 0, Qt::UserRole
).
331 value
<PrefsItemData
*>();
332 if( data
->panel
&& doclean
)
337 else if( data
->panel
)
338 data
->panel
->apply();
342 /*********************************************************************
344 *********************************************************************/
345 AdvPrefsPanel::AdvPrefsPanel( QWidget
*_parent
) : QWidget( _parent
)
348 AdvPrefsPanel::AdvPrefsPanel( intf_thread_t
*_p_intf
, QWidget
*_parent
,
349 PrefsItemData
* data
) :
350 QWidget( _parent
), p_intf( _p_intf
)
352 /* Find our module */
353 module_t
*p_module
= NULL
;
354 if( data
->i_type
== TYPE_CATEGORY
)
356 else if( data
->i_type
== TYPE_MODULE
)
357 p_module
= module_find( data
->psz_name
);
360 p_module
= module_get_main();
365 module_config_t
*const p_config
= module_config_get (p_module
, &confsize
),
367 *p_end
= p_config
+ confsize
;
369 if( data
->i_type
== TYPE_SUBCATEGORY
|| data
->i_type
== TYPE_CATSUBCAT
)
371 while (p_item
< p_end
)
373 if( p_item
->i_type
== CONFIG_SUBCATEGORY
&&
374 ( ( data
->i_type
== TYPE_SUBCATEGORY
&&
375 p_item
->value
.i
== data
->i_object_id
) ||
376 ( data
->i_type
== TYPE_CATSUBCAT
&&
377 p_item
->value
.i
== data
->i_subcat_id
) ) )
384 global_layout
= new QVBoxLayout();
385 global_layout
->setMargin( 2 );
389 help
= QString( data
->help
);
391 if( data
->i_type
== TYPE_SUBCATEGORY
|| data
->i_type
== TYPE_CATSUBCAT
)
393 head
= QString( data
->name
);
394 p_item
++; // Why that ?
398 const char *psz_help
= module_get_help (p_module
);
399 head
= QString( qtr( module_GetLongName( p_module
) ) );
403 help
.append( qtr( psz_help
) );
407 QLabel
*titleLabel
= new QLabel( head
);
408 QFont titleFont
= QApplication::font();
409 titleFont
.setPointSize( titleFont
.pointSize() + 6 );
410 titleLabel
->setFont( titleFont
);
413 QFrame
*title_line
= new QFrame
;
414 title_line
->setFrameShape(QFrame::HLine
);
415 title_line
->setFrameShadow(QFrame::Sunken
);
417 QLabel
*helpLabel
= new QLabel( help
, this );
418 helpLabel
->setWordWrap( true );
420 global_layout
->addWidget( titleLabel
);
421 global_layout
->addWidget( title_line
);
422 global_layout
->addWidget( helpLabel
);
424 QGroupBox
*box
= NULL
;
425 QGridLayout
*boxlayout
= NULL
;
427 QScrollArea
*scroller
= new QScrollArea
;
428 scroller
->setFrameStyle( QFrame::NoFrame
);
429 QWidget
*scrolled_area
= new QWidget
;
431 QGridLayout
*layout
= new QGridLayout();
432 int i_line
= 0, i_boxline
= 0;
433 bool has_hotkey
= false;
437 if( ( ( data
->i_type
== TYPE_SUBCATEGORY
&&
438 p_item
->value
.i
!= data
->i_object_id
) ||
439 ( data
->i_type
== TYPE_CATSUBCAT
&&
440 p_item
->value
.i
!= data
->i_subcat_id
) ) &&
441 ( p_item
->i_type
== CONFIG_CATEGORY
||
442 p_item
->i_type
== CONFIG_SUBCATEGORY
) )
444 if( p_item
->b_internal
) continue;
446 if( p_item
->i_type
== CONFIG_SECTION
)
450 box
->setLayout( boxlayout
);
452 layout
->addWidget( box
, i_line
, 0, 1, -1 );
455 box
= new QGroupBox( qtr( p_item
->psz_text
), this );
457 boxlayout
= new QGridLayout();
459 /* Only one hotkey control */
460 if( (p_item
->i_type
& CONFIG_ITEM
) == CONFIG_ITEM_KEY
)
467 ConfigControl
*control
;
469 control
= ConfigControl::createControl( VLC_OBJECT( p_intf
),
470 p_item
, this, layout
, i_line
);
472 control
= ConfigControl::createControl( VLC_OBJECT( p_intf
),
473 p_item
, this, boxlayout
, i_boxline
);
477 if( box
) i_boxline
++;
479 controls
.append( control
);
481 while( !( ( data
->i_type
== TYPE_SUBCATEGORY
||
482 data
->i_type
== TYPE_CATSUBCAT
) &&
483 ( p_item
->i_type
== CONFIG_CATEGORY
||
484 p_item
->i_type
== CONFIG_SUBCATEGORY
) )
485 && ( ++p_item
< p_end
) );
489 box
->setLayout( boxlayout
);
491 layout
->addWidget( box
, i_line
, 0, 1, -1 );
494 module_release (p_module
);
496 scrolled_area
->setSizePolicy( QSizePolicy::Preferred
,QSizePolicy::Fixed
);
497 scrolled_area
->setLayout( layout
);
498 scroller
->setWidget( scrolled_area
);
499 scroller
->setWidgetResizable( true );
500 global_layout
->addWidget( scroller
);
501 setLayout( global_layout
);
504 void AdvPrefsPanel::apply()
506 QList
<ConfigControl
*>::Iterator i
;
507 for( i
= controls
.begin() ; i
!= controls
.end() ; i
++ )
509 ConfigControl
*c
= qobject_cast
<ConfigControl
*>(*i
);
510 c
->doApply( p_intf
);
514 void AdvPrefsPanel::clean()
517 AdvPrefsPanel::~AdvPrefsPanel()
519 qDeleteAll( controls
); controls
.clear();