1 /*****************************************************************************
2 * preferences_widgets.cpp : Widgets for preferences displays
3 ****************************************************************************
4 * Copyright (C) 2006-2007 the VideoLAN team
7 * Authors: Clément Stenac <zorglub@videolan.org>
8 * Antoine Cellerier <dionoea@videolan.org>
9 * Jean-Baptiste Kempf <jb@videolan.org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
28 * - Finish implementation (see WX, there might be missing a
29 * i_action handler for IntegerLists, but I don't see any module using it...
30 * - Improvements over WX
31 * - Validator for modulelist
37 #include "components/preferences_widgets.hpp"
38 #include "util/customwidgets.hpp"
39 #include "util/qt_dirs.hpp"
44 #include <QGridLayout>
46 #include <QFileDialog>
48 #include <QTreeWidgetItem>
49 #include <QSignalMapper>
50 #include <QDialogButtonBox>
52 #define MINWIDTH_BOX 90
53 #define LAST_COLUMN 10
55 QString
formatTooltip(const QString
& tooltip
)
58 "<html><head><meta name=\"qrichtext\" content=\"1\" />"
59 "<style type=\"text/css\"> p, li { white-space: pre-wrap; } </style></head>"
60 "<body style=\" font-family:'Sans Serif'; "
61 "font-style:normal; text-decoration:none;\">"
62 "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; "
63 "margin-right:0px; -qt-block-indent:0; text-indent:0px;\">" +
69 ConfigControl
*ConfigControl::createControl( vlc_object_t
*p_this
,
70 module_config_t
*p_item
,
74 return createControl( p_this
, p_item
, parent
, NULL
, i
);
77 ConfigControl
*ConfigControl::createControl( vlc_object_t
*p_this
,
78 module_config_t
*p_item
,
80 QGridLayout
*l
, int &line
)
82 ConfigControl
*p_control
= NULL
;
84 switch( p_item
->i_type
)
86 case CONFIG_ITEM_MODULE
:
87 p_control
= new ModuleConfigControl( p_this
, p_item
, parent
, false,
90 case CONFIG_ITEM_MODULE_CAT
:
91 p_control
= new ModuleConfigControl( p_this
, p_item
, parent
, true,
94 case CONFIG_ITEM_MODULE_LIST
:
95 p_control
= new ModuleListConfigControl( p_this
, p_item
, parent
, false,
98 case CONFIG_ITEM_MODULE_LIST_CAT
:
99 p_control
= new ModuleListConfigControl( p_this
, p_item
, parent
, true,
101 /* Special Hack for a bug in video-filter */
102 if( qobject_cast
<ModuleListConfigControl
*>( p_control
)->groupBox
== NULL
)
105 case CONFIG_ITEM_STRING
:
106 if( !p_item
->i_list
)
107 p_control
= new StringConfigControl( p_this
, p_item
, parent
,
110 p_control
= new StringListConfigControl( p_this
, p_item
,
111 parent
, false, l
, line
);
113 case CONFIG_ITEM_PASSWORD
:
114 if( !p_item
->i_list
)
115 p_control
= new StringConfigControl( p_this
, p_item
, parent
,
118 p_control
= new StringListConfigControl( p_this
, p_item
,
119 parent
, true, l
, line
);
121 case CONFIG_ITEM_INTEGER
:
123 p_control
= new IntegerListConfigControl( p_this
, p_item
,
124 parent
, false, l
, line
);
125 else if( p_item
->min
.i
|| p_item
->max
.i
)
126 p_control
= new IntegerRangeConfigControl( p_this
, p_item
, parent
,
129 p_control
= new IntegerConfigControl( p_this
, p_item
, parent
,
132 case CONFIG_ITEM_FILE
:
133 p_control
= new FileConfigControl( p_this
, p_item
, parent
, l
, line
);
135 case CONFIG_ITEM_DIRECTORY
:
136 p_control
= new DirectoryConfigControl( p_this
, p_item
, parent
, l
,
139 case CONFIG_ITEM_FONT
:
140 p_control
= new FontConfigControl( p_this
, p_item
, parent
, l
,
143 case CONFIG_ITEM_KEY
:
144 p_control
= new KeySelectorControl( p_this
, p_item
, parent
, l
, line
);
146 case CONFIG_ITEM_BOOL
:
147 p_control
= new BoolConfigControl( p_this
, p_item
, parent
, l
, line
);
149 case CONFIG_ITEM_FLOAT
:
150 if( p_item
->min
.f
|| p_item
->max
.f
)
151 p_control
= new FloatRangeConfigControl( p_this
, p_item
, parent
,
154 p_control
= new FloatConfigControl( p_this
, p_item
, parent
,
163 void ConfigControl::doApply( intf_thread_t
*p_intf
)
167 case CONFIG_ITEM_INTEGER
:
168 case CONFIG_ITEM_BOOL
:
170 VIntConfigControl
*vicc
= qobject_cast
<VIntConfigControl
*>(this);
172 config_PutInt( p_intf
, vicc
->getName(), vicc
->getValue() );
175 case CONFIG_ITEM_FLOAT
:
177 VFloatConfigControl
*vfcc
=
178 qobject_cast
<VFloatConfigControl
*>(this);
180 config_PutFloat( p_intf
, vfcc
->getName(), vfcc
->getValue() );
183 case CONFIG_ITEM_STRING
:
185 VStringConfigControl
*vscc
=
186 qobject_cast
<VStringConfigControl
*>(this);
188 config_PutPsz( p_intf
, vscc
->getName(), qtu( vscc
->getValue() ) );
191 case CONFIG_ITEM_KEY
:
193 KeySelectorControl
*ksc
= qobject_cast
<KeySelectorControl
*>(this);
200 /*******************************************************
202 *******************************************************/
203 InterfacePreviewWidget::InterfacePreviewWidget
204 ( QWidget
*parent
) : QLabel( parent
, 0 )
206 setGeometry( 0, 0, 128, 100 );
207 setSizePolicy( QSizePolicy::Fixed
, QSizePolicy::Fixed
);
210 void InterfacePreviewWidget::setPreview( int comboid
)
212 /* Need to move resources references as soon as qt4.cpp
213 local defines has been moved somewhere else
215 const char * pixmaps
[] = { ":/prefsmenu/sample_classic",
216 ":/prefsmenu/sample_complete",
217 ":/prefsmenu/sample_minimal",
218 ":/prefsmenu/sample_skins" };
219 setPixmap( QPixmap( pixmaps
[ comboid
] ) );
224 /**************************************************************************
225 * String-based controls
226 *************************************************************************/
228 /*********** String **************/
229 StringConfigControl::StringConfigControl( vlc_object_t
*_p_this
,
230 module_config_t
*_p_item
,
231 QWidget
*_parent
, QGridLayout
*l
,
232 int &line
, bool pwd
) :
233 VStringConfigControl( _p_this
, _p_item
, _parent
)
235 label
= new QLabel( qtr(p_item
->psz_text
) );
236 text
= new QLineEdit( qfu(p_item
->value
.psz
) );
237 if( pwd
) text
->setEchoMode( QLineEdit::Password
);
242 QHBoxLayout
*layout
= new QHBoxLayout();
243 layout
->addWidget( label
, 0 ); layout
->insertSpacing( 1, 10 );
244 layout
->addWidget( text
, LAST_COLUMN
);
245 widget
->setLayout( layout
);
249 l
->addWidget( label
, line
, 0 );
250 l
->setColumnMinimumWidth( 1, 10 );
251 l
->addWidget( text
, line
, LAST_COLUMN
);
255 StringConfigControl::StringConfigControl( vlc_object_t
*_p_this
,
256 module_config_t
*_p_item
,
257 QLabel
*_label
, QLineEdit
*_text
, bool pwd
):
258 VStringConfigControl( _p_this
, _p_item
)
261 if( pwd
) text
->setEchoMode( QLineEdit::Password
);
266 void StringConfigControl::finish()
268 text
->setText( qfu(p_item
->value
.psz
) );
269 text
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
272 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
273 label
->setBuddy( text
);
277 /*********** File **************/
278 FileConfigControl::FileConfigControl( vlc_object_t
*_p_this
,
279 module_config_t
*_p_item
,
280 QWidget
*_parent
, QGridLayout
*l
,
282 VStringConfigControl( _p_this
, _p_item
, _parent
)
284 label
= new QLabel( qtr(p_item
->psz_text
) );
285 text
= new QLineEdit( qfu(p_item
->value
.psz
) );
286 browse
= new QPushButton( qtr( "Browse..." ) );
287 QHBoxLayout
*textAndButton
= new QHBoxLayout();
288 textAndButton
->setMargin( 0 );
289 textAndButton
->addWidget( text
, 2 );
290 textAndButton
->addWidget( browse
, 0 );
292 BUTTONACT( browse
, updateField() );
298 QHBoxLayout
*layout
= new QHBoxLayout();
299 layout
->addWidget( label
, 0 );
300 layout
->insertSpacing( 1, 10 );
301 layout
->addLayout( textAndButton
, LAST_COLUMN
);
302 widget
->setLayout( layout
);
306 l
->addWidget( label
, line
, 0 );
307 l
->setColumnMinimumWidth( 1, 10 );
308 l
->addLayout( textAndButton
, line
, LAST_COLUMN
);
313 FileConfigControl::FileConfigControl( vlc_object_t
*_p_this
,
314 module_config_t
*_p_item
,
315 QLabel
*_label
, QLineEdit
*_text
,
316 QPushButton
*_button
):
317 VStringConfigControl( _p_this
, _p_item
)
323 BUTTONACT( browse
, updateField() );
328 void FileConfigControl::updateField()
330 QString file
= QFileDialog::getOpenFileName( NULL
,
331 qtr( "Select File" ), QVLCUserDir( VLC_HOME_DIR
) );
332 if( file
.isNull() ) return;
333 text
->setText( toNativeSeparators( file
) );
336 void FileConfigControl::finish()
338 text
->setText( qfu(p_item
->value
.psz
) );
339 text
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
342 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
343 label
->setBuddy( text
);
347 /********* String / Directory **********/
348 DirectoryConfigControl::DirectoryConfigControl( vlc_object_t
*_p_this
,
349 module_config_t
*_p_item
, QWidget
*_p_widget
,
350 QGridLayout
*_p_layout
, int& _int
) :
351 FileConfigControl( _p_this
, _p_item
, _p_widget
, _p_layout
, _int
)
354 DirectoryConfigControl::DirectoryConfigControl( vlc_object_t
*_p_this
,
355 module_config_t
*_p_item
, QLabel
*_p_label
,
356 QLineEdit
*_p_line
, QPushButton
*_p_button
):
357 FileConfigControl( _p_this
, _p_item
, _p_label
, _p_line
, _p_button
)
360 void DirectoryConfigControl::updateField()
362 QString dir
= QFileDialog::getExistingDirectory( NULL
,
363 qtr( "Select Directory" ),
364 text
->text().isEmpty() ?
365 QVLCUserDir( VLC_HOME_DIR
) : text
->text(),
366 QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks
);
368 if( dir
.isNull() ) return;
369 text
->setText( toNativeSepNoSlash( dir
) );
372 /********* String / Font **********/
373 FontConfigControl::FontConfigControl( vlc_object_t
*_p_this
,
374 module_config_t
*_p_item
, QWidget
*_parent
,
375 QGridLayout
*_p_layout
, int& line
) :
376 VStringConfigControl( _p_this
, _p_item
, _parent
)
378 label
= new QLabel( qtr(p_item
->psz_text
) );
379 font
= new QFontComboBox( _parent
);
380 font
->setCurrentFont( QFont( qfu( p_item
->value
.psz
) ) );
383 QHBoxLayout
*layout
= new QHBoxLayout();
384 layout
->addWidget( label
, 0 );
385 layout
->addWidget( font
, 1 );
386 widget
->setLayout( layout
);
390 _p_layout
->addWidget( label
, line
, 0 );
391 _p_layout
->addWidget( font
, line
, 1, 1, -1 );
395 FontConfigControl::FontConfigControl( vlc_object_t
*_p_this
,
396 module_config_t
*_p_item
, QLabel
*_p_label
,
397 QFontComboBox
*_p_font
):
398 VStringConfigControl( _p_this
, _p_item
)
402 font
->setCurrentFont( QFont( qfu( p_item
->value
.psz
) ) );
405 /********* String / choice list **********/
406 StringListConfigControl::StringListConfigControl( vlc_object_t
*_p_this
,
407 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
408 QGridLayout
*l
, int &line
) :
409 VStringConfigControl( _p_this
, _p_item
, _parent
)
411 label
= new QLabel( qtr(p_item
->psz_text
) );
412 combo
= new QComboBox();
413 combo
->setMinimumWidth( MINWIDTH_BOX
);
414 combo
->setSizePolicy( QSizePolicy::MinimumExpanding
, QSizePolicy::Preferred
);
416 module_config_t
*p_module_config
= config_FindConfig( p_this
, p_item
->psz_name
);
417 if(p_module_config
&& p_module_config
->pf_update_list
)
420 val
.psz_string
= strdup(p_module_config
->value
.psz
);
422 p_module_config
->pf_update_list(p_this
, p_item
->psz_name
, val
, val
, NULL
);
424 // assume in any case that dirty was set to true
425 // because lazy programmes will use the same callback for
426 // this, like the one behind the refresh push button?
427 p_module_config
->b_dirty
= false;
429 free( val
.psz_string
);
432 finish( p_module_config
, bycat
);
435 l
= new QGridLayout();
436 l
->addWidget( label
, 0, 0 ); l
->addWidget( combo
, 0, LAST_COLUMN
);
437 widget
->setLayout( l
);
441 l
->addWidget( label
, line
, 0 );
442 l
->addWidget( combo
, line
, LAST_COLUMN
, Qt::AlignRight
);
445 if( p_item
->i_action
)
447 QSignalMapper
*signalMapper
= new QSignalMapper(this);
449 /* Some stringLists like Capture listings have action associated */
450 for( int i
= 0; i
< p_item
->i_action
; i
++ )
452 QPushButton
*button
=
453 new QPushButton( qfu( p_item
->ppsz_action_text
[i
] ));
454 CONNECT( button
, clicked(), signalMapper
, map() );
455 signalMapper
->setMapping( button
, i
);
456 l
->addWidget( button
, line
, LAST_COLUMN
- p_item
->i_action
+ i
,
459 CONNECT( signalMapper
, mapped( int ),
460 this, actionRequested( int ) );
464 void StringListConfigControl::actionRequested( int i_action
)
466 /* Supplementary check for boundaries */
467 if( i_action
< 0 || i_action
>= p_item
->i_action
) return;
469 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
470 if(!p_module_config
) return;
473 val
.psz_string
= const_cast<char *>
474 qtu( (combo
->itemData( combo
->currentIndex() ).toString() ) );
476 p_module_config
->ppf_action
[i_action
]( p_this
, getName(), val
, val
, 0 );
478 if( p_module_config
->b_dirty
)
481 finish( p_module_config
, true );
482 p_module_config
->b_dirty
= false;
485 StringListConfigControl::StringListConfigControl( vlc_object_t
*_p_this
,
486 module_config_t
*_p_item
, QLabel
*_label
, QComboBox
*_combo
,
487 bool bycat
) : VStringConfigControl( _p_this
, _p_item
)
492 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
494 finish( p_module_config
, bycat
);
497 void StringListConfigControl::finish(module_config_t
*p_module_config
, bool bycat
)
499 combo
->setEditable( false );
501 if(!p_module_config
) return;
503 for( int i_index
= 0; i_index
< p_module_config
->i_list
; i_index
++ )
505 combo
->addItem( qfu((p_module_config
->ppsz_list_text
&&
506 p_module_config
->ppsz_list_text
[i_index
])?
507 p_module_config
->ppsz_list_text
[i_index
] :
508 p_module_config
->ppsz_list
[i_index
] ),
509 QVariant( qfu(p_module_config
->ppsz_list
[i_index
] )) );
510 if( p_item
->value
.psz
&& !strcmp( p_module_config
->value
.psz
,
511 p_module_config
->ppsz_list
[i_index
] ) )
512 combo
->setCurrentIndex( combo
->count() - 1 );
514 combo
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
517 label
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
518 label
->setBuddy( combo
);
522 QString
StringListConfigControl::getValue()
524 return combo
->itemData( combo
->currentIndex() ).toString();
527 void setfillVLCConfigCombo( const char *configname
, intf_thread_t
*p_intf
,
530 module_config_t
*p_config
=
531 config_FindConfig( VLC_OBJECT(p_intf
), configname
);
534 if(p_config
->pf_update_list
)
537 val
.i_int
= p_config
->value
.i
;
538 p_config
->pf_update_list(VLC_OBJECT(p_intf
), configname
, val
, val
, NULL
);
539 // assume in any case that dirty was set to true
540 // because lazy programmes will use the same callback for
541 // this, like the one behind the refresh push button?
542 p_config
->b_dirty
= false;
545 for ( int i_index
= 0; i_index
< p_config
->i_list
; i_index
++ )
547 combo
->addItem( qfu( p_config
->ppsz_list_text
[i_index
] ),
548 QVariant( p_config
->pi_list
[i_index
] ) );
549 if( p_config
->value
.i
== p_config
->pi_list
[i_index
] )
551 combo
->setCurrentIndex( i_index
);
554 combo
->setToolTip( qfu( p_config
->psz_longtext
) );
558 /********* Module **********/
559 ModuleConfigControl::ModuleConfigControl( vlc_object_t
*_p_this
,
560 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
561 QGridLayout
*l
, int &line
) :
562 VStringConfigControl( _p_this
, _p_item
, _parent
)
564 label
= new QLabel( qtr(p_item
->psz_text
) );
565 combo
= new QComboBox();
566 combo
->setMinimumWidth( MINWIDTH_BOX
);
570 QHBoxLayout
*layout
= new QHBoxLayout();
571 layout
->addWidget( label
); layout
->addWidget( combo
, LAST_COLUMN
);
572 widget
->setLayout( layout
);
576 l
->addWidget( label
, line
, 0 );
577 l
->addWidget( combo
, line
, LAST_COLUMN
, Qt::AlignRight
);
581 ModuleConfigControl::ModuleConfigControl( vlc_object_t
*_p_this
,
582 module_config_t
*_p_item
, QLabel
*_label
, QComboBox
*_combo
,
583 bool bycat
) : VStringConfigControl( _p_this
, _p_item
)
590 void ModuleConfigControl::finish( bool bycat
)
594 combo
->setEditable( false );
596 /* build a list of available modules */
597 module_t
**p_list
= module_list_get( NULL
);
598 combo
->addItem( qtr("Default") );
599 for( size_t i
= 0; (p_parser
= p_list
[i
]) != NULL
; i
++ )
603 if( !strcmp( module_get_object( p_parser
), "main" ) ) continue;
606 module_config_t
*p_config
;
608 p_config
= module_config_get (p_parser
, &confsize
);
609 for (size_t i
= 0; i
< confsize
; i
++)
611 /* Hack: required subcategory is stored in i_min */
612 const module_config_t
*p_cfg
= p_config
+ i
;
613 if( p_cfg
->i_type
== CONFIG_SUBCATEGORY
&&
614 p_cfg
->value
.i
== p_item
->min
.i
)
615 combo
->addItem( qtr( module_GetLongName( p_parser
)),
616 QVariant( module_get_object( p_parser
) ) );
617 if( p_item
->value
.psz
&& !strcmp( p_item
->value
.psz
,
618 module_get_object( p_parser
) ) )
619 combo
->setCurrentIndex( combo
->count() - 1 );
621 module_config_free (p_config
);
623 else if( module_provides( p_parser
, p_item
->psz_type
) )
625 combo
->addItem( qtr(module_GetLongName( p_parser
) ),
626 QVariant( module_get_object( p_parser
) ) );
627 if( p_item
->value
.psz
&& !strcmp( p_item
->value
.psz
,
628 module_get_object( p_parser
) ) )
629 combo
->setCurrentIndex( combo
->count() - 1 );
632 module_list_free( p_list
);
633 combo
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
636 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
637 label
->setBuddy( combo
);
641 QString
ModuleConfigControl::getValue()
643 return combo
->itemData( combo
->currentIndex() ).toString();
646 /********* Module list **********/
647 ModuleListConfigControl::ModuleListConfigControl( vlc_object_t
*_p_this
,
648 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
649 QGridLayout
*l
, int &line
) :
650 VStringConfigControl( _p_this
, _p_item
, _parent
)
654 if( !p_item
->psz_text
) return;
656 groupBox
= new QGroupBox ( qtr(p_item
->psz_text
), _parent
);
657 text
= new QLineEdit
;
658 QGridLayout
*layoutGroupBox
= new QGridLayout( groupBox
);
663 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
664 it
!= modules
.end(); it
++ )
666 layoutGroupBox
->addWidget( (*it
)->checkBox
, boxline
++, 0 );
668 layoutGroupBox
->addWidget( text
, boxline
, 0 );
672 QVBoxLayout
*layout
= new QVBoxLayout();
673 layout
->addWidget( groupBox
, line
, 0 );
674 widget
->setLayout( layout
);
678 l
->addWidget( groupBox
, line
, 0, 1, -1 );
681 text
->setToolTip( formatTooltip( qtr( p_item
->psz_longtext
) ) );
684 ModuleListConfigControl::~ModuleListConfigControl()
686 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
687 it
!= modules
.end(); it
++ )
694 #define CHECKBOX_LISTS \
696 QCheckBox *cb = new QCheckBox( qtr( module_GetLongName( p_parser ) ) );\
697 checkBoxListItem *cbl = new checkBoxListItem; \
699 CONNECT( cb, stateChanged( int ), this, onUpdate() );\
700 cb->setToolTip( formatTooltip( qtr( module_get_help( p_parser ))));\
701 cbl->checkBox = cb; \
703 cbl->psz_module = strdup( module_get_object( p_parser ) ); \
704 modules.push_back( cbl ); \
706 if( p_item->value.psz && strstr( p_item->value.psz, cbl->psz_module ) ) \
707 cbl->checkBox->setChecked( true ); \
711 void ModuleListConfigControl::finish( bool bycat
)
715 /* build a list of available modules */
716 module_t
**p_list
= module_list_get( NULL
);
717 for( size_t i
= 0; (p_parser
= p_list
[i
]) != NULL
; i
++ )
721 if( !strcmp( module_get_object( p_parser
), "main" ) ) continue;
724 module_config_t
*p_config
= module_config_get (p_parser
, &confsize
);
726 for (size_t i
= 0; i
< confsize
; i
++)
728 module_config_t
*p_cfg
= p_config
+ i
;
729 /* Hack: required subcategory is stored in i_min */
730 if( p_cfg
->i_type
== CONFIG_SUBCATEGORY
&&
731 p_cfg
->value
.i
== p_item
->min
.i
)
736 module_config_free (p_config
);
738 else if( module_provides( p_parser
, p_item
->psz_type
) )
743 module_list_free( p_list
);
744 text
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
746 groupBox
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
748 #undef CHECKBOX_LISTS
750 QString
ModuleListConfigControl::getValue()
756 void ModuleListConfigControl::hide()
758 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
759 it
!= modules
.end(); it
++ )
761 (*it
)->checkBox
->hide();
766 void ModuleListConfigControl::show()
768 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
769 it
!= modules
.end(); it
++ )
771 (*it
)->checkBox
->show();
777 void ModuleListConfigControl::onUpdate()
782 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
783 it
!= modules
.end(); it
++ )
785 if( (*it
)->checkBox
->isChecked() )
789 text
->setText( text
->text() + (*it
)->psz_module
);
794 text
->setText( text
->text() + ":" + (*it
)->psz_module
);
800 /**************************************************************************
801 * Integer-based controls
802 *************************************************************************/
804 /*********** Integer **************/
805 IntegerConfigControl::IntegerConfigControl( vlc_object_t
*_p_this
,
806 module_config_t
*_p_item
,
807 QWidget
*_parent
, QGridLayout
*l
,
809 VIntConfigControl( _p_this
, _p_item
, _parent
)
811 label
= new QLabel( qtr(p_item
->psz_text
) );
812 spin
= new QSpinBox
; spin
->setMinimumWidth( MINWIDTH_BOX
);
813 spin
->setAlignment( Qt::AlignRight
);
814 spin
->setMaximumWidth( MINWIDTH_BOX
);
819 QHBoxLayout
*layout
= new QHBoxLayout();
820 layout
->addWidget( label
, 0 ); layout
->addWidget( spin
, LAST_COLUMN
);
821 widget
->setLayout( layout
);
825 l
->addWidget( label
, line
, 0 );
826 l
->addWidget( spin
, line
, LAST_COLUMN
, Qt::AlignRight
);
829 IntegerConfigControl::IntegerConfigControl( vlc_object_t
*_p_this
,
830 module_config_t
*_p_item
,
831 QLabel
*_label
, QSpinBox
*_spin
) :
832 VIntConfigControl( _p_this
, _p_item
)
839 void IntegerConfigControl::finish()
841 spin
->setMaximum( 2000000000 );
842 spin
->setMinimum( -2000000000 );
843 spin
->setValue( p_item
->value
.i
);
844 spin
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
847 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
848 label
->setBuddy( spin
);
852 int IntegerConfigControl::getValue()
854 return spin
->value();
857 /********* Integer range **********/
858 IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t
*_p_this
,
859 module_config_t
*_p_item
,
860 QWidget
*_parent
, QGridLayout
*l
,
862 IntegerConfigControl( _p_this
, _p_item
, _parent
, l
, line
)
867 IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t
*_p_this
,
868 module_config_t
*_p_item
,
869 QLabel
*_label
, QSpinBox
*_spin
) :
870 IntegerConfigControl( _p_this
, _p_item
, _label
, _spin
)
875 void IntegerRangeConfigControl::finish()
877 spin
->setMaximum( p_item
->max
.i
);
878 spin
->setMinimum( p_item
->min
.i
);
881 IntegerRangeSliderConfigControl::IntegerRangeSliderConfigControl(
882 vlc_object_t
*_p_this
,
883 module_config_t
*_p_item
,
884 QLabel
*_label
, QSlider
*_slider
):
885 VIntConfigControl( _p_this
, _p_item
)
889 slider
->setMaximum( p_item
->max
.i
);
890 slider
->setMinimum( p_item
->min
.i
);
891 slider
->setValue( p_item
->value
.i
);
892 slider
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
895 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
896 label
->setBuddy( slider
);
900 int IntegerRangeSliderConfigControl::getValue()
902 return slider
->value();
906 /********* Integer / choice list **********/
907 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t
*_p_this
,
908 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
909 QGridLayout
*l
, int &line
) :
910 VIntConfigControl( _p_this
, _p_item
, _parent
)
912 label
= new QLabel( qtr(p_item
->psz_text
) );
913 combo
= new QComboBox();
914 combo
->setMinimumWidth( MINWIDTH_BOX
);
916 module_config_t
*p_module_config
= config_FindConfig( p_this
, p_item
->psz_name
);
917 if(p_module_config
&& p_module_config
->pf_update_list
)
920 val
.i_int
= p_module_config
->value
.i
;
922 p_module_config
->pf_update_list(p_this
, p_item
->psz_name
, val
, val
, NULL
);
924 // assume in any case that dirty was set to true
925 // because lazy programmes will use the same callback for
926 // this, like the one behind the refresh push button?
927 p_module_config
->b_dirty
= false;
931 finish( p_module_config
, bycat
);
934 QHBoxLayout
*layout
= new QHBoxLayout();
935 layout
->addWidget( label
); layout
->addWidget( combo
, LAST_COLUMN
);
936 widget
->setLayout( layout
);
940 l
->addWidget( label
, line
, 0 );
941 l
->addWidget( combo
, line
, LAST_COLUMN
, Qt::AlignRight
);
944 if( p_item
->i_action
)
946 QSignalMapper
*signalMapper
= new QSignalMapper(this);
948 /* Some stringLists like Capture listings have action associated */
949 for( int i
= 0; i
< p_item
->i_action
; i
++ )
951 QPushButton
*button
=
952 new QPushButton( qfu( p_item
->ppsz_action_text
[i
] ));
953 CONNECT( button
, clicked(), signalMapper
, map() );
954 signalMapper
->setMapping( button
, i
);
955 l
->addWidget( button
, line
, LAST_COLUMN
- p_item
->i_action
+ i
,
958 CONNECT( signalMapper
, mapped( int ),
959 this, actionRequested( int ) );
963 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t
*_p_this
,
964 module_config_t
*_p_item
, QLabel
*_label
, QComboBox
*_combo
,
965 bool bycat
) : VIntConfigControl( _p_this
, _p_item
)
970 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
972 finish( p_module_config
, bycat
);
975 void IntegerListConfigControl::finish(module_config_t
*p_module_config
, bool bycat
)
977 combo
->setEditable( false );
979 if(!p_module_config
) return;
981 for( int i_index
= 0; i_index
< p_module_config
->i_list
; i_index
++ )
983 combo
->addItem( qtr(p_module_config
->ppsz_list_text
[i_index
] ),
984 QVariant( p_module_config
->pi_list
[i_index
] ) );
985 if( p_module_config
->value
.i
== p_module_config
->pi_list
[i_index
] )
986 combo
->setCurrentIndex( combo
->count() - 1 );
988 combo
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
991 label
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
992 label
->setBuddy( combo
);
996 void IntegerListConfigControl::actionRequested( int i_action
)
998 /* Supplementary check for boundaries */
999 if( i_action
< 0 || i_action
>= p_item
->i_action
) return;
1001 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
1002 if(!p_module_config
) return;
1006 val
.i_int
= combo
->itemData( combo
->currentIndex() ).toInt();
1008 p_module_config
->ppf_action
[i_action
]( p_this
, getName(), val
, val
, 0 );
1010 if( p_module_config
->b_dirty
)
1013 finish( p_module_config
, true );
1014 p_module_config
->b_dirty
= false;
1018 int IntegerListConfigControl::getValue()
1020 return combo
->itemData( combo
->currentIndex() ).toInt();
1023 /*********** Boolean **************/
1024 BoolConfigControl::BoolConfigControl( vlc_object_t
*_p_this
,
1025 module_config_t
*_p_item
,
1026 QWidget
*_parent
, QGridLayout
*l
,
1028 VIntConfigControl( _p_this
, _p_item
, _parent
)
1030 checkbox
= new QCheckBox( qtr(p_item
->psz_text
) );
1035 QHBoxLayout
*layout
= new QHBoxLayout();
1036 layout
->addWidget( checkbox
, 0 );
1037 widget
->setLayout( layout
);
1041 l
->addWidget( checkbox
, line
, 0 );
1044 BoolConfigControl::BoolConfigControl( vlc_object_t
*_p_this
,
1045 module_config_t
*_p_item
,
1047 QAbstractButton
*_checkbox
,
1049 VIntConfigControl( _p_this
, _p_item
)
1051 checkbox
= _checkbox
;
1052 VLC_UNUSED( _label
);
1056 void BoolConfigControl::finish()
1058 checkbox
->setChecked( p_item
->value
.i
== true );
1059 checkbox
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
1062 int BoolConfigControl::getValue()
1064 return checkbox
->isChecked();
1067 /**************************************************************************
1068 * Float-based controls
1069 *************************************************************************/
1071 /*********** Float **************/
1072 FloatConfigControl::FloatConfigControl( vlc_object_t
*_p_this
,
1073 module_config_t
*_p_item
,
1074 QWidget
*_parent
, QGridLayout
*l
,
1076 VFloatConfigControl( _p_this
, _p_item
, _parent
)
1078 label
= new QLabel( qtr(p_item
->psz_text
) );
1079 spin
= new QDoubleSpinBox
;
1080 spin
->setMinimumWidth( MINWIDTH_BOX
);
1081 spin
->setMaximumWidth( MINWIDTH_BOX
);
1082 spin
->setAlignment( Qt::AlignRight
);
1087 QHBoxLayout
*layout
= new QHBoxLayout();
1088 layout
->addWidget( label
, 0 ); layout
->addWidget( spin
, LAST_COLUMN
);
1089 widget
->setLayout( layout
);
1093 l
->addWidget( label
, line
, 0 );
1094 l
->addWidget( spin
, line
, LAST_COLUMN
, Qt::AlignRight
);
1098 FloatConfigControl::FloatConfigControl( vlc_object_t
*_p_this
,
1099 module_config_t
*_p_item
,
1101 QDoubleSpinBox
*_spin
) :
1102 VFloatConfigControl( _p_this
, _p_item
)
1109 void FloatConfigControl::finish()
1111 spin
->setMaximum( 2000000000. );
1112 spin
->setMinimum( -2000000000. );
1113 spin
->setSingleStep( 0.1 );
1114 spin
->setValue( (double)p_item
->value
.f
);
1115 spin
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
1118 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
1119 label
->setBuddy( spin
);
1123 float FloatConfigControl::getValue()
1125 return (float)spin
->value();
1128 /*********** Float with range **************/
1129 FloatRangeConfigControl::FloatRangeConfigControl( vlc_object_t
*_p_this
,
1130 module_config_t
*_p_item
,
1131 QWidget
*_parent
, QGridLayout
*l
,
1133 FloatConfigControl( _p_this
, _p_item
, _parent
, l
, line
)
1138 FloatRangeConfigControl::FloatRangeConfigControl( vlc_object_t
*_p_this
,
1139 module_config_t
*_p_item
,
1141 QDoubleSpinBox
*_spin
) :
1142 FloatConfigControl( _p_this
, _p_item
, _label
, _spin
)
1147 void FloatRangeConfigControl::finish()
1149 spin
->setMaximum( (double)p_item
->max
.f
);
1150 spin
->setMinimum( (double)p_item
->min
.f
);
1154 /**********************************************************************
1155 * Key selector widget
1156 **********************************************************************/
1157 KeySelectorControl::KeySelectorControl( vlc_object_t
*_p_this
,
1158 module_config_t
*_p_item
,
1159 QWidget
*_parent
, QGridLayout
*l
,
1161 ConfigControl( _p_this
, _p_item
, _parent
)
1164 QWidget
*keyContainer
= new QWidget
;
1165 QGridLayout
*gLayout
= new QGridLayout( keyContainer
);
1168 qtr( "Select an action to change the associated hotkey") );
1170 QLabel
*searchLabel
= new QLabel( qtr( "Search" ) );
1171 actionSearch
= new SearchLineEdit( keyContainer
);
1173 table
= new QTreeWidget
;
1174 table
->setColumnCount(3);
1175 table
->headerItem()->setText( 0, qtr( "Action" ) );
1176 table
->headerItem()->setText( 1, qtr( "Hotkey" ) );
1177 table
->headerItem()->setText( 2, qtr( "Global" ) );
1178 table
->setAlternatingRowColors( true );
1180 shortcutValue
= new KeyShortcutEdit
;
1181 shortcutValue
->setReadOnly(true);
1183 QPushButton
*clearButton
= new QPushButton( qtr( "Clear" ) );
1184 QPushButton
*setButton
= new QPushButton( qtr( "Set" ) );
1185 setButton
->setDefault( true );
1188 gLayout
->addWidget( label
, 0, 0, 1, 4 );
1189 gLayout
->addWidget( searchLabel
, 1, 0, 1, 2 );
1190 gLayout
->addWidget( actionSearch
, 1, 2, 1, 2 );
1191 gLayout
->addWidget( table
, 2, 0, 1, 4 );
1192 gLayout
->addWidget( clearButton
, 3, 0, 1, 1 );
1193 gLayout
->addWidget( shortcutValue
, 3, 1, 1, 2 );
1194 gLayout
->addWidget( setButton
, 3, 3, 1, 1 );
1196 l
->addWidget( keyContainer
, line
, 0, 1, -1 );
1198 CONNECT( clearButton
, clicked(), shortcutValue
, clear() );
1199 CONNECT( clearButton
, clicked(), this, setTheKey() );
1200 BUTTONACT( setButton
, setTheKey() );
1201 CONNECT( actionSearch
, textChanged( const QString
& ),
1202 this, filter( const QString
& ) );
1205 void KeySelectorControl::finish()
1208 label
->setToolTip( formatTooltip( qtr( p_item
->psz_longtext
) ) );
1210 /* Fill the table */
1212 /* Get the main Module */
1213 module_t
*p_main
= module_get_main();
1216 /* Access to the module_config_t */
1218 module_config_t
*p_config
;
1220 p_config
= module_config_get (p_main
, &confsize
);
1222 for (size_t i
= 0; i
< confsize
; i
++)
1224 module_config_t
*p_item
= p_config
+ i
;
1226 /* If we are a key option not empty */
1227 if( p_item
->i_type
& CONFIG_ITEM
&& p_item
->psz_name
1228 && strstr( p_item
->psz_name
, "key-" )
1229 && !strstr( p_item
->psz_name
, "global-key" )
1230 && !EMPTY_STR( p_item
->psz_text
) )
1234 - QString text in column 0
1235 - QString name in data of column 0
1236 - KeyValue in String in column 1
1237 - KeyValue in int in column 1
1239 QTreeWidgetItem
*treeItem
= new QTreeWidgetItem();
1240 treeItem
->setText( 0, qtr( p_item
->psz_text
) );
1241 treeItem
->setData( 0, Qt::UserRole
,
1242 QVariant( qfu( p_item
->psz_name
) ) );
1243 treeItem
->setText( 1, VLCKeyToString( p_item
->value
.i
) );
1244 treeItem
->setData( 1, Qt::UserRole
, QVariant( p_item
->value
.i
) );
1245 table
->addTopLevelItem( treeItem
);
1249 if( p_item
->i_type
& CONFIG_ITEM
&& p_item
->psz_name
1250 && strstr( p_item
->psz_name
, "global-key" )
1251 && !EMPTY_STR( p_item
->psz_text
) )
1253 QList
<QTreeWidgetItem
*> list
=
1254 table
->findItems( qtr( p_item
->psz_text
), Qt::MatchExactly
);
1255 if( list
.count() >= 1 )
1257 list
[0]->setText( 2, VLCKeyToString( p_item
->value
.i
) );
1258 list
[0]->setData( 2, Qt::UserRole
,
1259 QVariant( p_item
->value
.i
) );
1261 if( list
.count() >= 2 )
1262 msg_Dbg( p_this
, "This is probably wrong, %s", p_item
->psz_text
);
1265 module_config_free (p_config
);
1266 module_release (p_main
);
1268 table
->resizeColumnToContents( 0 );
1270 CONNECT( table
, itemDoubleClicked( QTreeWidgetItem
*, int ),
1271 this, selectKey( QTreeWidgetItem
*, int ) );
1272 CONNECT( table
, itemSelectionChanged(),
1273 this, select1Key() );
1275 CONNECT( shortcutValue
, pressed(), this, selectKey() );
1278 void KeySelectorControl::filter( const QString
&qs_search
)
1280 QList
<QTreeWidgetItem
*> resultList
=
1281 table
->findItems( qs_search
, Qt::MatchContains
, 0 );
1282 for( int i
= 0; i
< table
->topLevelItemCount(); i
++ )
1284 table
->topLevelItem( i
)->setHidden(
1285 !resultList
.contains( table
->topLevelItem( i
) ) );
1289 /* Show the key selected from the table in the keySelector */
1290 void KeySelectorControl::select1Key()
1292 QTreeWidgetItem
*keyItem
= table
->currentItem();
1293 shortcutValue
->setText( keyItem
->text( 1 ) );
1294 shortcutValue
->setValue( keyItem
->data( 1, Qt::UserRole
).toInt() );
1295 shortcutValue
->setGlobal( false );
1298 void KeySelectorControl::selectKey( QTreeWidgetItem
*keyItem
, int column
)
1300 /* This happens when triggered by ClickEater */
1301 if( keyItem
== NULL
) keyItem
= table
->currentItem();
1303 /* This can happen when nothing is selected on the treeView
1304 and the shortcutValue is clicked */
1305 if( !keyItem
) return;
1307 /* If clicked on the first column, assuming user wants the normal hotkey */
1308 if( column
== 0 ) column
= 1;
1310 bool b_global
= ( column
== 2 );
1312 /* Launch a small dialog to ask for a new key */
1313 KeyInputDialog
*d
= new KeyInputDialog( table
, keyItem
->text( 0 ), widget
, b_global
);
1316 if( d
->result() == QDialog::Accepted
)
1318 int newValue
= d
->keyValue
;
1319 shortcutValue
->setText( VLCKeyToString( newValue
) );
1320 shortcutValue
->setValue( newValue
);
1321 shortcutValue
->setGlobal( b_global
);
1325 QTreeWidgetItem
*it
;
1326 for( int i
= 0; i
< table
->topLevelItemCount() ; i
++ )
1328 it
= table
->topLevelItem(i
);
1329 if( ( keyItem
!= it
) &&
1330 ( it
->data( b_global
? 2: 1, Qt::UserRole
).toInt() == newValue
) )
1332 it
->setData( b_global
? 2 : 1, Qt::UserRole
, QVariant( -1 ) );
1333 it
->setText( b_global
? 2 : 1, qtr( "Unset" ) );
1336 /* We already made an OK once. */
1343 void KeySelectorControl::setTheKey()
1345 if( !table
->currentItem() ) return;
1346 table
->currentItem()->setText( shortcutValue
->getGlobal() ? 2 : 1,
1347 shortcutValue
->text() );
1348 table
->currentItem()->setData( shortcutValue
->getGlobal() ? 2 : 1,
1349 Qt::UserRole
, shortcutValue
->getValue() );
1352 void KeySelectorControl::doApply()
1354 QTreeWidgetItem
*it
;
1355 for( int i
= 0; i
< table
->topLevelItemCount() ; i
++ )
1357 it
= table
->topLevelItem(i
);
1358 if( it
->data( 1, Qt::UserRole
).toInt() >= 0 )
1359 config_PutInt( p_this
,
1360 qtu( it
->data( 0, Qt::UserRole
).toString() ),
1361 it
->data( 1, Qt::UserRole
).toInt() );
1362 if( it
->data( 2, Qt::UserRole
).toInt() >= 0 )
1363 config_PutInt( p_this
,
1364 qtu( "global-" + it
->data( 0, Qt::UserRole
).toString() ),
1365 it
->data( 2, Qt::UserRole
).toInt() );
1371 * Class KeyInputDialog
1373 KeyInputDialog::KeyInputDialog( QTreeWidget
*_table
,
1374 const QString
& keyToChange
,
1377 QDialog( _parent
), keyValue(0), b_global( _b_global
)
1383 setWindowTitle( b_global
? qtr( "Global" ): ""
1384 + qtr( "Hotkey for " ) + keyToChange
);
1385 setWindowRole( "vlc-key-input" );
1387 vLayout
= new QVBoxLayout( this );
1388 selected
= new QLabel( qtr( "Press the new keys for " ) + keyToChange
);
1389 vLayout
->addWidget( selected
, Qt::AlignCenter
);
1391 warning
= new QLabel
;
1393 vLayout
->insertWidget( 1, warning
);
1395 buttonBox
= new QDialogButtonBox
;
1396 QPushButton
*ok
= new QPushButton( qtr("OK") );
1397 QPushButton
*cancel
= new QPushButton( qtr("Cancel") );
1398 buttonBox
->addButton( ok
, QDialogButtonBox::AcceptRole
);
1399 buttonBox
->addButton( cancel
, QDialogButtonBox::RejectRole
);
1400 ok
->setDefault( true );
1402 vLayout
->addWidget( buttonBox
);
1405 CONNECT( buttonBox
, accepted(), this, accept() );
1406 CONNECT( buttonBox
, rejected(), this, reject() );
1409 void KeyInputDialog::checkForConflicts( int i_vlckey
)
1411 QList
<QTreeWidgetItem
*> conflictList
=
1412 table
->findItems( VLCKeyToString( i_vlckey
), Qt::MatchExactly
,
1415 if( conflictList
.size() &&
1416 conflictList
[0]->data( b_global
? 2 : 1, Qt::UserRole
).toInt() > 1 )
1417 /* Avoid 0 or -1 that are the "Unset" states */
1419 warning
->setText( qtr("Warning: the key is already assigned to \"") +
1420 conflictList
[0]->text( 0 ) + "\"" );
1429 void KeyInputDialog::keyPressEvent( QKeyEvent
*e
)
1431 if( e
->key() == Qt::Key_Tab
||
1432 e
->key() == Qt::Key_Shift
||
1433 e
->key() == Qt::Key_Control
||
1434 e
->key() == Qt::Key_Meta
||
1435 e
->key() == Qt::Key_Alt
||
1436 e
->key() == Qt::Key_AltGr
)
1438 int i_vlck
= qtEventToVLCKey( e
);
1439 selected
->setText( qtr( "Key: " ) + VLCKeyToString( i_vlck
) );
1440 checkForConflicts( i_vlck
);
1444 void KeyInputDialog::wheelEvent( QWheelEvent
*e
)
1446 int i_vlck
= qtWheelEventToVLCKey( e
);
1447 selected
->setText( qtr( "Key: " ) + VLCKeyToString( i_vlck
) );
1448 checkForConflicts( i_vlck
);
1452 void KeyShortcutEdit::mousePressEvent( QMouseEvent
*)