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>
53 #define MINWIDTH_BOX 90
54 #define LAST_COLUMN 10
56 QString
formatTooltip(const QString
& tooltip
)
59 "<html><head><meta name=\"qrichtext\" content=\"1\" />"
60 "<style type=\"text/css\"> p, li { white-space: pre-wrap; } </style></head>"
61 "<body style=\" font-family:'Sans Serif'; "
62 "font-style:normal; text-decoration:none;\">"
63 "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; "
64 "margin-right:0px; -qt-block-indent:0; text-indent:0px;\">" +
70 ConfigControl
*ConfigControl::createControl( vlc_object_t
*p_this
,
71 module_config_t
*p_item
,
75 return createControl( p_this
, p_item
, parent
, NULL
, i
);
78 ConfigControl
*ConfigControl::createControl( vlc_object_t
*p_this
,
79 module_config_t
*p_item
,
81 QGridLayout
*l
, int &line
)
83 ConfigControl
*p_control
= NULL
;
85 switch( p_item
->i_type
)
87 case CONFIG_ITEM_MODULE
:
88 p_control
= new ModuleConfigControl( p_this
, p_item
, parent
, false,
91 case CONFIG_ITEM_MODULE_CAT
:
92 p_control
= new ModuleConfigControl( p_this
, p_item
, parent
, true,
95 case CONFIG_ITEM_MODULE_LIST
:
96 p_control
= new ModuleListConfigControl( p_this
, p_item
, parent
, false,
99 case CONFIG_ITEM_MODULE_LIST_CAT
:
100 p_control
= new ModuleListConfigControl( p_this
, p_item
, parent
, true,
102 /* Special Hack for a bug in video-filter */
103 if( qobject_cast
<ModuleListConfigControl
*>( p_control
)->groupBox
== NULL
)
106 case CONFIG_ITEM_STRING
:
107 if( !p_item
->i_list
)
108 p_control
= new StringConfigControl( p_this
, p_item
, parent
,
111 p_control
= new StringListConfigControl( p_this
, p_item
,
112 parent
, false, l
, line
);
114 case CONFIG_ITEM_PASSWORD
:
115 if( !p_item
->i_list
)
116 p_control
= new StringConfigControl( p_this
, p_item
, parent
,
119 p_control
= new StringListConfigControl( p_this
, p_item
,
120 parent
, true, l
, line
);
122 case CONFIG_ITEM_INTEGER
:
124 p_control
= new IntegerListConfigControl( p_this
, p_item
,
125 parent
, false, l
, line
);
126 else if( p_item
->min
.i
|| p_item
->max
.i
)
127 p_control
= new IntegerRangeConfigControl( p_this
, p_item
, parent
,
130 p_control
= new IntegerConfigControl( p_this
, p_item
, parent
,
133 case CONFIG_ITEM_FILE
:
134 p_control
= new FileConfigControl( p_this
, p_item
, parent
, l
, line
);
136 case CONFIG_ITEM_DIRECTORY
:
137 p_control
= new DirectoryConfigControl( p_this
, p_item
, parent
, l
,
140 case CONFIG_ITEM_FONT
:
141 p_control
= new FontConfigControl( p_this
, p_item
, parent
, l
,
144 case CONFIG_ITEM_KEY
:
145 p_control
= new KeySelectorControl( p_this
, p_item
, parent
, l
, line
);
147 case CONFIG_ITEM_BOOL
:
148 p_control
= new BoolConfigControl( p_this
, p_item
, parent
, l
, line
);
150 case CONFIG_ITEM_FLOAT
:
151 if( p_item
->min
.f
|| p_item
->max
.f
)
152 p_control
= new FloatRangeConfigControl( p_this
, p_item
, parent
,
155 p_control
= new FloatConfigControl( p_this
, p_item
, parent
,
164 void ConfigControl::doApply( intf_thread_t
*p_intf
)
168 case CONFIG_ITEM_INTEGER
:
169 case CONFIG_ITEM_BOOL
:
171 VIntConfigControl
*vicc
= qobject_cast
<VIntConfigControl
*>(this);
173 config_PutInt( p_intf
, vicc
->getName(), vicc
->getValue() );
176 case CONFIG_ITEM_FLOAT
:
178 VFloatConfigControl
*vfcc
=
179 qobject_cast
<VFloatConfigControl
*>(this);
181 config_PutFloat( p_intf
, vfcc
->getName(), vfcc
->getValue() );
184 case CONFIG_ITEM_STRING
:
186 VStringConfigControl
*vscc
=
187 qobject_cast
<VStringConfigControl
*>(this);
189 config_PutPsz( p_intf
, vscc
->getName(), qtu( vscc
->getValue() ) );
192 case CONFIG_ITEM_KEY
:
194 KeySelectorControl
*ksc
= qobject_cast
<KeySelectorControl
*>(this);
201 /*******************************************************
203 *******************************************************/
204 InterfacePreviewWidget::InterfacePreviewWidget ( QWidget
*parent
) : QLabel( parent
)
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 static const char pixmaps
[][28] = { ":/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
);
418 finish( p_module_config
, bycat
);
421 l
= new QGridLayout();
422 l
->addWidget( label
, 0, 0 ); l
->addWidget( combo
, 0, LAST_COLUMN
);
423 widget
->setLayout( l
);
427 l
->addWidget( label
, line
, 0 );
428 l
->addWidget( combo
, line
, LAST_COLUMN
, Qt::AlignRight
);
431 if( p_item
->i_action
)
433 QSignalMapper
*signalMapper
= new QSignalMapper(this);
435 /* Some stringLists like Capture listings have action associated */
436 for( int i
= 0; i
< p_item
->i_action
; i
++ )
438 QPushButton
*button
=
439 new QPushButton( qfu( p_item
->ppsz_action_text
[i
] ));
440 CONNECT( button
, clicked(), signalMapper
, map() );
441 signalMapper
->setMapping( button
, i
);
442 l
->addWidget( button
, line
, LAST_COLUMN
- p_item
->i_action
+ i
,
445 CONNECT( signalMapper
, mapped( int ),
446 this, actionRequested( int ) );
450 void StringListConfigControl::actionRequested( int i_action
)
452 /* Supplementary check for boundaries */
453 if( i_action
< 0 || i_action
>= p_item
->i_action
) return;
455 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
456 if(!p_module_config
) return;
459 val
.psz_string
= const_cast<char *>
460 qtu( (combo
->itemData( combo
->currentIndex() ).toString() ) );
462 p_module_config
->ppf_action
[i_action
]( p_this
, getName(), val
, val
, 0 );
464 if( p_module_config
->b_dirty
)
467 finish( p_module_config
, true );
468 p_module_config
->b_dirty
= false;
471 StringListConfigControl::StringListConfigControl( vlc_object_t
*_p_this
,
472 module_config_t
*_p_item
, QLabel
*_label
, QComboBox
*_combo
,
473 bool bycat
) : VStringConfigControl( _p_this
, _p_item
)
478 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
480 finish( p_module_config
, bycat
);
483 void StringListConfigControl::finish(module_config_t
*p_module_config
, bool bycat
)
485 combo
->setEditable( false );
487 if(!p_module_config
) return;
489 if( p_module_config
->pf_update_list
)
492 val
.psz_string
= strdup(p_module_config
->value
.psz
);
494 p_module_config
->pf_update_list(p_this
, p_item
->psz_name
, val
, val
, NULL
);
496 // assume in any case that dirty was set to true
497 // because lazy programmes will use the same callback for
498 // this, like the one behind the refresh push button?
499 p_module_config
->b_dirty
= false;
501 free( val
.psz_string
);
504 for( int i_index
= 0; i_index
< p_module_config
->i_list
; i_index
++ )
506 combo
->addItem( qfu((p_module_config
->ppsz_list_text
&&
507 p_module_config
->ppsz_list_text
[i_index
])?
508 p_module_config
->ppsz_list_text
[i_index
] :
509 p_module_config
->ppsz_list
[i_index
] ),
510 QVariant( qfu(p_module_config
->ppsz_list
[i_index
] )) );
511 if( p_item
->value
.psz
&& !strcmp( p_module_config
->value
.psz
,
512 p_module_config
->ppsz_list
[i_index
] ) )
513 combo
->setCurrentIndex( combo
->count() - 1 );
515 combo
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
518 label
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
519 label
->setBuddy( combo
);
523 QString
StringListConfigControl::getValue()
525 return combo
->itemData( combo
->currentIndex() ).toString();
528 void setfillVLCConfigCombo( const char *configname
, intf_thread_t
*p_intf
,
531 module_config_t
*p_config
=
532 config_FindConfig( VLC_OBJECT(p_intf
), configname
);
535 if(p_config
->pf_update_list
)
538 val
.i_int
= p_config
->value
.i
;
539 p_config
->pf_update_list(VLC_OBJECT(p_intf
), configname
, val
, val
, NULL
);
540 // assume in any case that dirty was set to true
541 // because lazy programmes will use the same callback for
542 // this, like the one behind the refresh push button?
543 p_config
->b_dirty
= false;
546 for ( int i_index
= 0; i_index
< p_config
->i_list
; i_index
++ )
548 combo
->addItem( qfu( p_config
->ppsz_list_text
[i_index
] ),
549 QVariant( p_config
->pi_list
[i_index
] ) );
550 if( p_config
->value
.i
== p_config
->pi_list
[i_index
] )
552 combo
->setCurrentIndex( i_index
);
555 combo
->setToolTip( qfu( p_config
->psz_longtext
) );
559 /********* Module **********/
560 ModuleConfigControl::ModuleConfigControl( vlc_object_t
*_p_this
,
561 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
562 QGridLayout
*l
, int &line
) :
563 VStringConfigControl( _p_this
, _p_item
, _parent
)
565 label
= new QLabel( qtr(p_item
->psz_text
) );
566 combo
= new QComboBox();
567 combo
->setMinimumWidth( MINWIDTH_BOX
);
571 QHBoxLayout
*layout
= new QHBoxLayout();
572 layout
->addWidget( label
); layout
->addWidget( combo
, LAST_COLUMN
);
573 widget
->setLayout( layout
);
577 l
->addWidget( label
, line
, 0 );
578 l
->addWidget( combo
, line
, LAST_COLUMN
, Qt::AlignRight
);
582 ModuleConfigControl::ModuleConfigControl( vlc_object_t
*_p_this
,
583 module_config_t
*_p_item
, QLabel
*_label
, QComboBox
*_combo
,
584 bool bycat
) : VStringConfigControl( _p_this
, _p_item
)
591 void ModuleConfigControl::finish( bool bycat
)
595 combo
->setEditable( false );
597 /* build a list of available modules */
598 module_t
**p_list
= module_list_get( NULL
);
599 combo
->addItem( qtr("Default") );
600 for( size_t i
= 0; (p_parser
= p_list
[i
]) != NULL
; i
++ )
604 if( !strcmp( module_get_object( p_parser
), "main" ) ) continue;
607 module_config_t
*p_config
;
609 p_config
= module_config_get (p_parser
, &confsize
);
610 for (size_t i
= 0; i
< confsize
; i
++)
612 /* Hack: required subcategory is stored in i_min */
613 const module_config_t
*p_cfg
= p_config
+ i
;
614 if( p_cfg
->i_type
== CONFIG_SUBCATEGORY
&&
615 p_cfg
->value
.i
== p_item
->min
.i
)
616 combo
->addItem( qtr( module_GetLongName( p_parser
)),
617 QVariant( module_get_object( p_parser
) ) );
618 if( p_item
->value
.psz
&& !strcmp( p_item
->value
.psz
,
619 module_get_object( p_parser
) ) )
620 combo
->setCurrentIndex( combo
->count() - 1 );
622 module_config_free (p_config
);
624 else if( module_provides( p_parser
, p_item
->psz_type
) )
626 combo
->addItem( qtr(module_GetLongName( p_parser
) ),
627 QVariant( module_get_object( p_parser
) ) );
628 if( p_item
->value
.psz
&& !strcmp( p_item
->value
.psz
,
629 module_get_object( p_parser
) ) )
630 combo
->setCurrentIndex( combo
->count() - 1 );
633 module_list_free( p_list
);
634 combo
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
637 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
638 label
->setBuddy( combo
);
642 QString
ModuleConfigControl::getValue()
644 return combo
->itemData( combo
->currentIndex() ).toString();
647 /********* Module list **********/
648 ModuleListConfigControl::ModuleListConfigControl( vlc_object_t
*_p_this
,
649 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
650 QGridLayout
*l
, int &line
) :
651 VStringConfigControl( _p_this
, _p_item
, _parent
)
655 if( !p_item
->psz_text
) return;
657 groupBox
= new QGroupBox ( qtr(p_item
->psz_text
), _parent
);
658 text
= new QLineEdit
;
659 QGridLayout
*layoutGroupBox
= new QGridLayout( groupBox
);
664 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
665 it
!= modules
.end(); it
++ )
667 layoutGroupBox
->addWidget( (*it
)->checkBox
, boxline
++, 0 );
669 layoutGroupBox
->addWidget( text
, boxline
, 0 );
673 QVBoxLayout
*layout
= new QVBoxLayout();
674 layout
->addWidget( groupBox
, line
, 0 );
675 widget
->setLayout( layout
);
679 l
->addWidget( groupBox
, line
, 0, 1, -1 );
682 text
->setToolTip( formatTooltip( qtr( p_item
->psz_longtext
) ) );
685 ModuleListConfigControl::~ModuleListConfigControl()
687 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
688 it
!= modules
.end(); it
++ )
695 #define CHECKBOX_LISTS \
697 QCheckBox *cb = new QCheckBox( qtr( module_GetLongName( p_parser ) ) );\
698 checkBoxListItem *cbl = new checkBoxListItem; \
700 CONNECT( cb, stateChanged( int ), this, onUpdate() );\
701 cb->setToolTip( formatTooltip( qtr( module_get_help( p_parser ))));\
702 cbl->checkBox = cb; \
704 cbl->psz_module = strdup( module_get_object( p_parser ) ); \
705 modules.push_back( cbl ); \
707 if( p_item->value.psz && strstr( p_item->value.psz, cbl->psz_module ) ) \
708 cbl->checkBox->setChecked( true ); \
712 void ModuleListConfigControl::finish( bool bycat
)
716 /* build a list of available modules */
717 module_t
**p_list
= module_list_get( NULL
);
718 for( size_t i
= 0; (p_parser
= p_list
[i
]) != NULL
; i
++ )
722 if( !strcmp( module_get_object( p_parser
), "main" ) ) continue;
725 module_config_t
*p_config
= module_config_get (p_parser
, &confsize
);
727 for (size_t i
= 0; i
< confsize
; i
++)
729 module_config_t
*p_cfg
= p_config
+ i
;
730 /* Hack: required subcategory is stored in i_min */
731 if( p_cfg
->i_type
== CONFIG_SUBCATEGORY
&&
732 p_cfg
->value
.i
== p_item
->min
.i
)
737 module_config_free (p_config
);
739 else if( module_provides( p_parser
, p_item
->psz_type
) )
744 module_list_free( p_list
);
745 text
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
747 groupBox
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
749 #undef CHECKBOX_LISTS
751 QString
ModuleListConfigControl::getValue()
757 void ModuleListConfigControl::hide()
759 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
760 it
!= modules
.end(); it
++ )
762 (*it
)->checkBox
->hide();
767 void ModuleListConfigControl::show()
769 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
770 it
!= modules
.end(); it
++ )
772 (*it
)->checkBox
->show();
778 void ModuleListConfigControl::onUpdate()
783 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
784 it
!= modules
.end(); it
++ )
786 if( (*it
)->checkBox
->isChecked() )
790 text
->setText( text
->text() + (*it
)->psz_module
);
795 text
->setText( text
->text() + ":" + (*it
)->psz_module
);
801 /**************************************************************************
802 * Integer-based controls
803 *************************************************************************/
805 /*********** Integer **************/
806 IntegerConfigControl::IntegerConfigControl( vlc_object_t
*_p_this
,
807 module_config_t
*_p_item
,
808 QWidget
*_parent
, QGridLayout
*l
,
810 VIntConfigControl( _p_this
, _p_item
, _parent
)
812 label
= new QLabel( qtr(p_item
->psz_text
) );
813 spin
= new QSpinBox
; spin
->setMinimumWidth( MINWIDTH_BOX
);
814 spin
->setAlignment( Qt::AlignRight
);
815 spin
->setMaximumWidth( MINWIDTH_BOX
);
820 QHBoxLayout
*layout
= new QHBoxLayout();
821 layout
->addWidget( label
, 0 ); layout
->addWidget( spin
, LAST_COLUMN
);
822 widget
->setLayout( layout
);
826 l
->addWidget( label
, line
, 0 );
827 l
->addWidget( spin
, line
, LAST_COLUMN
, Qt::AlignRight
);
830 IntegerConfigControl::IntegerConfigControl( vlc_object_t
*_p_this
,
831 module_config_t
*_p_item
,
832 QLabel
*_label
, QSpinBox
*_spin
) :
833 VIntConfigControl( _p_this
, _p_item
)
840 void IntegerConfigControl::finish()
842 spin
->setMaximum( 2000000000 );
843 spin
->setMinimum( -2000000000 );
844 spin
->setValue( p_item
->value
.i
);
845 spin
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
848 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
849 label
->setBuddy( spin
);
853 int IntegerConfigControl::getValue()
855 return spin
->value();
858 /********* Integer range **********/
859 IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t
*_p_this
,
860 module_config_t
*_p_item
,
861 QWidget
*_parent
, QGridLayout
*l
,
863 IntegerConfigControl( _p_this
, _p_item
, _parent
, l
, line
)
868 IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t
*_p_this
,
869 module_config_t
*_p_item
,
870 QLabel
*_label
, QSpinBox
*_spin
) :
871 IntegerConfigControl( _p_this
, _p_item
, _label
, _spin
)
876 void IntegerRangeConfigControl::finish()
878 spin
->setMaximum( p_item
->max
.i
);
879 spin
->setMinimum( p_item
->min
.i
);
882 IntegerRangeSliderConfigControl::IntegerRangeSliderConfigControl(
883 vlc_object_t
*_p_this
,
884 module_config_t
*_p_item
,
885 QLabel
*_label
, QSlider
*_slider
):
886 VIntConfigControl( _p_this
, _p_item
)
890 slider
->setMaximum( p_item
->max
.i
);
891 slider
->setMinimum( p_item
->min
.i
);
892 slider
->setValue( p_item
->value
.i
);
893 slider
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
896 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
897 label
->setBuddy( slider
);
901 int IntegerRangeSliderConfigControl::getValue()
903 return slider
->value();
907 /********* Integer / choice list **********/
908 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t
*_p_this
,
909 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
910 QGridLayout
*l
, int &line
) :
911 VIntConfigControl( _p_this
, _p_item
, _parent
)
913 label
= new QLabel( qtr(p_item
->psz_text
) );
914 combo
= new QComboBox();
915 combo
->setMinimumWidth( MINWIDTH_BOX
);
917 module_config_t
*p_module_config
= config_FindConfig( p_this
, p_item
->psz_name
);
919 finish( p_module_config
, bycat
);
922 QHBoxLayout
*layout
= new QHBoxLayout();
923 layout
->addWidget( label
); layout
->addWidget( combo
, LAST_COLUMN
);
924 widget
->setLayout( layout
);
928 l
->addWidget( label
, line
, 0 );
929 l
->addWidget( combo
, line
, LAST_COLUMN
, Qt::AlignRight
);
932 if( p_item
->i_action
)
934 QSignalMapper
*signalMapper
= new QSignalMapper(this);
936 /* Some stringLists like Capture listings have action associated */
937 for( int i
= 0; i
< p_item
->i_action
; i
++ )
939 QPushButton
*button
=
940 new QPushButton( qfu( p_item
->ppsz_action_text
[i
] ));
941 CONNECT( button
, clicked(), signalMapper
, map() );
942 signalMapper
->setMapping( button
, i
);
943 l
->addWidget( button
, line
, LAST_COLUMN
- p_item
->i_action
+ i
,
946 CONNECT( signalMapper
, mapped( int ),
947 this, actionRequested( int ) );
951 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t
*_p_this
,
952 module_config_t
*_p_item
, QLabel
*_label
, QComboBox
*_combo
,
953 bool bycat
) : VIntConfigControl( _p_this
, _p_item
)
958 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
960 finish( p_module_config
, bycat
);
963 void IntegerListConfigControl::finish(module_config_t
*p_module_config
, bool bycat
)
965 combo
->setEditable( false );
967 if(!p_module_config
) return;
969 if( p_module_config
->pf_update_list
)
972 val
.i_int
= p_module_config
->value
.i
;
974 p_module_config
->pf_update_list(p_this
, p_item
->psz_name
, val
, val
, NULL
);
976 // assume in any case that dirty was set to true
977 // because lazy programmes will use the same callback for
978 // this, like the one behind the refresh push button?
979 p_module_config
->b_dirty
= false;
982 for( int i_index
= 0; i_index
< p_module_config
->i_list
; i_index
++ )
984 combo
->addItem( qtr(p_module_config
->ppsz_list_text
[i_index
] ),
985 QVariant( p_module_config
->pi_list
[i_index
] ) );
986 if( p_module_config
->value
.i
== p_module_config
->pi_list
[i_index
] )
987 combo
->setCurrentIndex( combo
->count() - 1 );
989 combo
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
992 label
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
993 label
->setBuddy( combo
);
997 void IntegerListConfigControl::actionRequested( int i_action
)
999 /* Supplementary check for boundaries */
1000 if( i_action
< 0 || i_action
>= p_item
->i_action
) return;
1002 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
1003 if(!p_module_config
) return;
1007 val
.i_int
= combo
->itemData( combo
->currentIndex() ).toInt();
1009 p_module_config
->ppf_action
[i_action
]( p_this
, getName(), val
, val
, 0 );
1011 if( p_module_config
->b_dirty
)
1014 finish( p_module_config
, true );
1015 p_module_config
->b_dirty
= false;
1019 int IntegerListConfigControl::getValue()
1021 return combo
->itemData( combo
->currentIndex() ).toInt();
1024 /*********** Boolean **************/
1025 BoolConfigControl::BoolConfigControl( vlc_object_t
*_p_this
,
1026 module_config_t
*_p_item
,
1027 QWidget
*_parent
, QGridLayout
*l
,
1029 VIntConfigControl( _p_this
, _p_item
, _parent
)
1031 checkbox
= new QCheckBox( qtr(p_item
->psz_text
) );
1036 QHBoxLayout
*layout
= new QHBoxLayout();
1037 layout
->addWidget( checkbox
, 0 );
1038 widget
->setLayout( layout
);
1042 l
->addWidget( checkbox
, line
, 0 );
1045 BoolConfigControl::BoolConfigControl( vlc_object_t
*_p_this
,
1046 module_config_t
*_p_item
,
1048 QAbstractButton
*_checkbox
,
1050 VIntConfigControl( _p_this
, _p_item
)
1052 checkbox
= _checkbox
;
1053 VLC_UNUSED( _label
);
1057 void BoolConfigControl::finish()
1059 checkbox
->setChecked( p_item
->value
.i
== true );
1060 checkbox
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
1063 int BoolConfigControl::getValue()
1065 return checkbox
->isChecked();
1068 /**************************************************************************
1069 * Float-based controls
1070 *************************************************************************/
1072 /*********** Float **************/
1073 FloatConfigControl::FloatConfigControl( vlc_object_t
*_p_this
,
1074 module_config_t
*_p_item
,
1075 QWidget
*_parent
, QGridLayout
*l
,
1077 VFloatConfigControl( _p_this
, _p_item
, _parent
)
1079 label
= new QLabel( qtr(p_item
->psz_text
) );
1080 spin
= new QDoubleSpinBox
;
1081 spin
->setMinimumWidth( MINWIDTH_BOX
);
1082 spin
->setMaximumWidth( MINWIDTH_BOX
);
1083 spin
->setAlignment( Qt::AlignRight
);
1088 QHBoxLayout
*layout
= new QHBoxLayout();
1089 layout
->addWidget( label
, 0 ); layout
->addWidget( spin
, LAST_COLUMN
);
1090 widget
->setLayout( layout
);
1094 l
->addWidget( label
, line
, 0 );
1095 l
->addWidget( spin
, line
, LAST_COLUMN
, Qt::AlignRight
);
1099 FloatConfigControl::FloatConfigControl( vlc_object_t
*_p_this
,
1100 module_config_t
*_p_item
,
1102 QDoubleSpinBox
*_spin
) :
1103 VFloatConfigControl( _p_this
, _p_item
)
1110 void FloatConfigControl::finish()
1112 spin
->setMaximum( 2000000000. );
1113 spin
->setMinimum( -2000000000. );
1114 spin
->setSingleStep( 0.1 );
1115 spin
->setValue( (double)p_item
->value
.f
);
1116 spin
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
1119 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
1120 label
->setBuddy( spin
);
1124 float FloatConfigControl::getValue()
1126 return (float)spin
->value();
1129 /*********** Float with range **************/
1130 FloatRangeConfigControl::FloatRangeConfigControl( vlc_object_t
*_p_this
,
1131 module_config_t
*_p_item
,
1132 QWidget
*_parent
, QGridLayout
*l
,
1134 FloatConfigControl( _p_this
, _p_item
, _parent
, l
, line
)
1139 FloatRangeConfigControl::FloatRangeConfigControl( vlc_object_t
*_p_this
,
1140 module_config_t
*_p_item
,
1142 QDoubleSpinBox
*_spin
) :
1143 FloatConfigControl( _p_this
, _p_item
, _label
, _spin
)
1148 void FloatRangeConfigControl::finish()
1150 spin
->setMaximum( (double)p_item
->max
.f
);
1151 spin
->setMinimum( (double)p_item
->min
.f
);
1155 /**********************************************************************
1156 * Key selector widget
1157 **********************************************************************/
1158 KeySelectorControl::KeySelectorControl( vlc_object_t
*_p_this
,
1159 module_config_t
*_p_item
,
1160 QWidget
*_parent
, QGridLayout
*l
,
1162 ConfigControl( _p_this
, _p_item
, _parent
)
1165 QWidget
*keyContainer
= new QWidget
;
1166 QGridLayout
*gLayout
= new QGridLayout( keyContainer
);
1169 qtr( "Select an action to change the associated hotkey") );
1171 QLabel
*searchLabel
= new QLabel( qtr( "Search" ) );
1172 actionSearch
= new SearchLineEdit( keyContainer
);
1174 table
= new QTreeWidget
;
1175 table
->setColumnCount(3);
1176 table
->headerItem()->setText( 0, qtr( "Action" ) );
1177 table
->headerItem()->setText( 1, qtr( "Hotkey" ) );
1178 table
->headerItem()->setText( 2, qtr( "Global" ) );
1179 table
->setAlternatingRowColors( true );
1181 shortcutValue
= new KeyShortcutEdit
;
1182 shortcutValue
->setReadOnly(true);
1184 QPushButton
*clearButton
= new QPushButton( qtr( "Clear" ) );
1185 QPushButton
*setButton
= new QPushButton( qtr( "Set" ) );
1186 setButton
->setDefault( true );
1189 gLayout
->addWidget( label
, 0, 0, 1, 4 );
1190 gLayout
->addWidget( searchLabel
, 1, 0, 1, 2 );
1191 gLayout
->addWidget( actionSearch
, 1, 2, 1, 2 );
1192 gLayout
->addWidget( table
, 2, 0, 1, 4 );
1193 gLayout
->addWidget( clearButton
, 3, 0, 1, 1 );
1194 gLayout
->addWidget( shortcutValue
, 3, 1, 1, 2 );
1195 gLayout
->addWidget( setButton
, 3, 3, 1, 1 );
1197 l
->addWidget( keyContainer
, line
, 0, 1, -1 );
1199 CONNECT( clearButton
, clicked(), shortcutValue
, clear() );
1200 CONNECT( clearButton
, clicked(), this, setTheKey() );
1201 BUTTONACT( setButton
, setTheKey() );
1202 CONNECT( actionSearch
, textChanged( const QString
& ),
1203 this, filter( const QString
& ) );
1206 void KeySelectorControl::finish()
1209 label
->setToolTip( formatTooltip( qtr( p_item
->psz_longtext
) ) );
1211 /* Fill the table */
1213 /* Get the main Module */
1214 module_t
*p_main
= module_get_main();
1217 /* Access to the module_config_t */
1219 module_config_t
*p_config
;
1221 p_config
= module_config_get (p_main
, &confsize
);
1223 for (size_t i
= 0; i
< confsize
; i
++)
1225 module_config_t
*p_item
= p_config
+ i
;
1227 /* If we are a key option not empty */
1228 if( p_item
->i_type
& CONFIG_ITEM
&& p_item
->psz_name
1229 && strstr( p_item
->psz_name
, "key-" )
1230 && !strstr( p_item
->psz_name
, "global-key" )
1231 && !EMPTY_STR( p_item
->psz_text
) )
1235 - QString text in column 0
1236 - QString name in data of column 0
1237 - KeyValue in String in column 1
1238 - KeyValue in int in column 1
1240 QTreeWidgetItem
*treeItem
= new QTreeWidgetItem();
1241 treeItem
->setText( 0, qtr( p_item
->psz_text
) );
1242 treeItem
->setData( 0, Qt::UserRole
,
1243 QVariant( qfu( p_item
->psz_name
) ) );
1244 treeItem
->setText( 1, VLCKeyToString( p_item
->value
.i
) );
1245 treeItem
->setData( 1, Qt::UserRole
, QVariant( p_item
->value
.i
) );
1246 table
->addTopLevelItem( treeItem
);
1250 if( p_item
->i_type
& CONFIG_ITEM
&& p_item
->psz_name
1251 && strstr( p_item
->psz_name
, "global-key" )
1252 && !EMPTY_STR( p_item
->psz_text
) )
1254 QList
<QTreeWidgetItem
*> list
=
1255 table
->findItems( qtr( p_item
->psz_text
), Qt::MatchExactly
);
1256 if( list
.count() >= 1 )
1258 list
[0]->setText( 2, VLCKeyToString( p_item
->value
.i
) );
1259 list
[0]->setData( 2, Qt::UserRole
,
1260 QVariant( p_item
->value
.i
) );
1262 if( list
.count() >= 2 )
1263 msg_Dbg( p_this
, "This is probably wrong, %s", p_item
->psz_text
);
1266 module_config_free (p_config
);
1267 module_release (p_main
);
1269 table
->resizeColumnToContents( 0 );
1271 CONNECT( table
, itemDoubleClicked( QTreeWidgetItem
*, int ),
1272 this, selectKey( QTreeWidgetItem
*, int ) );
1273 CONNECT( table
, itemSelectionChanged(),
1274 this, select1Key() );
1276 CONNECT( shortcutValue
, pressed(), this, selectKey() );
1279 void KeySelectorControl::filter( const QString
&qs_search
)
1281 QList
<QTreeWidgetItem
*> resultList
=
1282 table
->findItems( qs_search
, Qt::MatchContains
, 0 );
1283 for( int i
= 0; i
< table
->topLevelItemCount(); i
++ )
1285 table
->topLevelItem( i
)->setHidden(
1286 !resultList
.contains( table
->topLevelItem( i
) ) );
1290 /* Show the key selected from the table in the keySelector */
1291 void KeySelectorControl::select1Key()
1293 QTreeWidgetItem
*keyItem
= table
->currentItem();
1294 shortcutValue
->setText( keyItem
->text( 1 ) );
1295 shortcutValue
->setValue( keyItem
->data( 1, Qt::UserRole
).toInt() );
1296 shortcutValue
->setGlobal( false );
1299 void KeySelectorControl::selectKey( QTreeWidgetItem
*keyItem
, int column
)
1301 /* This happens when triggered by ClickEater */
1302 if( keyItem
== NULL
) keyItem
= table
->currentItem();
1304 /* This can happen when nothing is selected on the treeView
1305 and the shortcutValue is clicked */
1306 if( !keyItem
) return;
1308 /* If clicked on the first column, assuming user wants the normal hotkey */
1309 if( column
== 0 ) column
= 1;
1311 bool b_global
= ( column
== 2 );
1313 /* Launch a small dialog to ask for a new key */
1314 KeyInputDialog
*d
= new KeyInputDialog( table
, keyItem
->text( 0 ), widget
, b_global
);
1317 if( d
->result() == QDialog::Accepted
)
1319 int newValue
= d
->keyValue
;
1320 shortcutValue
->setText( VLCKeyToString( newValue
) );
1321 shortcutValue
->setValue( newValue
);
1322 shortcutValue
->setGlobal( b_global
);
1326 QTreeWidgetItem
*it
;
1327 for( int i
= 0; i
< table
->topLevelItemCount() ; i
++ )
1329 it
= table
->topLevelItem(i
);
1330 if( ( keyItem
!= it
) &&
1331 ( it
->data( b_global
? 2: 1, Qt::UserRole
).toInt() == newValue
) )
1333 it
->setData( b_global
? 2 : 1, Qt::UserRole
, QVariant( -1 ) );
1334 it
->setText( b_global
? 2 : 1, qtr( "Unset" ) );
1337 /* We already made an OK once. */
1344 void KeySelectorControl::setTheKey()
1346 if( !table
->currentItem() ) return;
1347 table
->currentItem()->setText( shortcutValue
->getGlobal() ? 2 : 1,
1348 shortcutValue
->text() );
1349 table
->currentItem()->setData( shortcutValue
->getGlobal() ? 2 : 1,
1350 Qt::UserRole
, shortcutValue
->getValue() );
1353 void KeySelectorControl::doApply()
1355 QTreeWidgetItem
*it
;
1356 for( int i
= 0; i
< table
->topLevelItemCount() ; i
++ )
1358 it
= table
->topLevelItem(i
);
1359 if( it
->data( 1, Qt::UserRole
).toInt() >= 0 )
1360 config_PutInt( p_this
,
1361 qtu( it
->data( 0, Qt::UserRole
).toString() ),
1362 it
->data( 1, Qt::UserRole
).toInt() );
1363 if( it
->data( 2, Qt::UserRole
).toInt() >= 0 )
1364 config_PutInt( p_this
,
1365 qtu( "global-" + it
->data( 0, Qt::UserRole
).toString() ),
1366 it
->data( 2, Qt::UserRole
).toInt() );
1372 * Class KeyInputDialog
1374 KeyInputDialog::KeyInputDialog( QTreeWidget
*_table
,
1375 const QString
& keyToChange
,
1378 QDialog( _parent
), keyValue(0), b_global( _b_global
)
1384 setWindowTitle( b_global
? qtr( "Global" ): ""
1385 + qtr( "Hotkey for " ) + keyToChange
);
1386 setWindowRole( "vlc-key-input" );
1388 vLayout
= new QVBoxLayout( this );
1389 selected
= new QLabel( qtr( "Press the new keys for " ) + keyToChange
);
1390 vLayout
->addWidget( selected
, Qt::AlignCenter
);
1392 warning
= new QLabel
;
1394 vLayout
->insertWidget( 1, warning
);
1396 buttonBox
= new QDialogButtonBox
;
1397 QPushButton
*ok
= new QPushButton( qtr("OK") );
1398 QPushButton
*cancel
= new QPushButton( qtr("Cancel") );
1399 buttonBox
->addButton( ok
, QDialogButtonBox::AcceptRole
);
1400 buttonBox
->addButton( cancel
, QDialogButtonBox::RejectRole
);
1401 ok
->setDefault( true );
1403 vLayout
->addWidget( buttonBox
);
1406 CONNECT( buttonBox
, accepted(), this, accept() );
1407 CONNECT( buttonBox
, rejected(), this, reject() );
1410 void KeyInputDialog::checkForConflicts( int i_vlckey
)
1412 QList
<QTreeWidgetItem
*> conflictList
=
1413 table
->findItems( VLCKeyToString( i_vlckey
), Qt::MatchExactly
,
1416 if( conflictList
.size() &&
1417 conflictList
[0]->data( b_global
? 2 : 1, Qt::UserRole
).toInt() > 1 )
1418 /* Avoid 0 or -1 that are the "Unset" states */
1420 warning
->setText( qtr("Warning: the key is already assigned to \"") +
1421 conflictList
[0]->text( 0 ) + "\"" );
1430 void KeyInputDialog::keyPressEvent( QKeyEvent
*e
)
1432 if( e
->key() == Qt::Key_Tab
||
1433 e
->key() == Qt::Key_Shift
||
1434 e
->key() == Qt::Key_Control
||
1435 e
->key() == Qt::Key_Meta
||
1436 e
->key() == Qt::Key_Alt
||
1437 e
->key() == Qt::Key_AltGr
)
1439 int i_vlck
= qtEventToVLCKey( e
);
1440 selected
->setText( qtr( "Key: " ) + VLCKeyToString( i_vlck
) );
1441 checkForConflicts( i_vlck
);
1445 void KeyInputDialog::wheelEvent( QWheelEvent
*e
)
1447 int i_vlck
= qtWheelEventToVLCKey( e
);
1448 selected
->setText( qtr( "Key: " ) + VLCKeyToString( i_vlck
) );
1449 checkForConflicts( i_vlck
);
1453 void KeyShortcutEdit::mousePressEvent( QMouseEvent
*)