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"
41 #include <vlc_intf_strings.h>
45 #include <QGridLayout>
47 #include <QFileDialog>
49 #include <QTreeWidgetItem>
50 #include <QSignalMapper>
51 #include <QDialogButtonBox>
54 #define MINWIDTH_BOX 90
55 #define LAST_COLUMN 10
57 QString
formatTooltip(const QString
& tooltip
)
60 "<html><head><meta name=\"qrichtext\" content=\"1\" />"
61 "<style type=\"text/css\"> p, li { white-space: pre-wrap; } </style></head>"
62 "<body style=\" font-family:'Sans Serif'; "
63 "font-style:normal; text-decoration:none;\">"
64 "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; "
65 "margin-right:0px; -qt-block-indent:0; text-indent:0px;\">" +
71 ConfigControl
*ConfigControl::createControl( vlc_object_t
*p_this
,
72 module_config_t
*p_item
,
76 return createControl( p_this
, p_item
, parent
, NULL
, i
);
79 ConfigControl
*ConfigControl::createControl( vlc_object_t
*p_this
,
80 module_config_t
*p_item
,
82 QGridLayout
*l
, int &line
)
84 ConfigControl
*p_control
= NULL
;
86 switch( p_item
->i_type
)
88 case CONFIG_ITEM_MODULE
:
89 p_control
= new ModuleConfigControl( p_this
, p_item
, parent
, false,
92 case CONFIG_ITEM_MODULE_CAT
:
93 p_control
= new ModuleConfigControl( p_this
, p_item
, parent
, true,
96 case CONFIG_ITEM_MODULE_LIST
:
97 p_control
= new ModuleListConfigControl( p_this
, p_item
, parent
, false,
100 case CONFIG_ITEM_MODULE_LIST_CAT
:
101 p_control
= new ModuleListConfigControl( p_this
, p_item
, parent
, true,
104 case CONFIG_ITEM_STRING
:
105 if( !p_item
->i_list
)
106 p_control
= new StringConfigControl( p_this
, p_item
, parent
,
109 p_control
= new StringListConfigControl( p_this
, p_item
,
110 parent
, false, l
, line
);
112 case CONFIG_ITEM_PASSWORD
:
113 if( !p_item
->i_list
)
114 p_control
= new StringConfigControl( p_this
, p_item
, parent
,
117 p_control
= new StringListConfigControl( p_this
, p_item
,
118 parent
, true, l
, line
);
120 case CONFIG_ITEM_INTEGER
:
122 p_control
= new IntegerListConfigControl( p_this
, p_item
,
123 parent
, false, l
, line
);
124 else if( p_item
->min
.i
|| p_item
->max
.i
)
125 p_control
= new IntegerRangeConfigControl( p_this
, p_item
, parent
,
128 p_control
= new IntegerConfigControl( p_this
, p_item
, parent
,
131 case CONFIG_ITEM_FILE
:
132 p_control
= new FileConfigControl( p_this
, p_item
, parent
, l
, line
);
134 case CONFIG_ITEM_DIRECTORY
:
135 p_control
= new DirectoryConfigControl( p_this
, p_item
, parent
, l
,
138 case CONFIG_ITEM_FONT
:
139 p_control
= new FontConfigControl( p_this
, p_item
, parent
, l
,
142 case CONFIG_ITEM_KEY
:
143 p_control
= new KeySelectorControl( p_this
, p_item
, parent
, l
, line
);
145 case CONFIG_ITEM_BOOL
:
146 p_control
= new BoolConfigControl( p_this
, p_item
, parent
, l
, line
);
148 case CONFIG_ITEM_FLOAT
:
149 if( p_item
->min
.f
|| p_item
->max
.f
)
150 p_control
= new FloatRangeConfigControl( p_this
, p_item
, parent
,
153 p_control
= new FloatConfigControl( p_this
, p_item
, parent
,
162 void ConfigControl::doApply( intf_thread_t
*p_intf
)
166 case CONFIG_ITEM_INTEGER
:
167 case CONFIG_ITEM_BOOL
:
169 VIntConfigControl
*vicc
= qobject_cast
<VIntConfigControl
*>(this);
171 config_PutInt( p_intf
, vicc
->getName(), vicc
->getValue() );
174 case CONFIG_ITEM_FLOAT
:
176 VFloatConfigControl
*vfcc
=
177 qobject_cast
<VFloatConfigControl
*>(this);
179 config_PutFloat( p_intf
, vfcc
->getName(), vfcc
->getValue() );
182 case CONFIG_ITEM_STRING
:
184 VStringConfigControl
*vscc
=
185 qobject_cast
<VStringConfigControl
*>(this);
187 config_PutPsz( p_intf
, vscc
->getName(), qtu( vscc
->getValue() ) );
190 case CONFIG_ITEM_KEY
:
192 KeySelectorControl
*ksc
= qobject_cast
<KeySelectorControl
*>(this);
199 /*******************************************************
201 *******************************************************/
202 InterfacePreviewWidget::InterfacePreviewWidget ( QWidget
*parent
) : QLabel( parent
)
204 setGeometry( 0, 0, 128, 100 );
205 setSizePolicy( QSizePolicy::Fixed
, QSizePolicy::Fixed
);
208 void InterfacePreviewWidget::setNormalPreview( bool b_minimal
)
210 setPreview( ( b_minimal
)?MINIMAL
:COMPLETE
);
213 void InterfacePreviewWidget::setPreview( enum_style e_style
)
215 QString
pixmapLocationString(":/prefsmenu/");
221 pixmapLocationString
+= "sample_complete";
224 pixmapLocationString
+= "sample_minimal";
227 pixmapLocationString
+= "sample_skins";
231 setPixmap( QPixmap( pixmapLocationString
) );
237 /**************************************************************************
238 * String-based controls
239 *************************************************************************/
241 /*********** String **************/
242 StringConfigControl::StringConfigControl( vlc_object_t
*_p_this
,
243 module_config_t
*_p_item
,
244 QWidget
*_parent
, QGridLayout
*l
,
245 int &line
, bool pwd
) :
246 VStringConfigControl( _p_this
, _p_item
, _parent
)
248 label
= new QLabel( qtr(p_item
->psz_text
) );
249 text
= new QLineEdit( qfu(p_item
->value
.psz
) );
250 if( pwd
) text
->setEchoMode( QLineEdit::Password
);
255 QHBoxLayout
*layout
= new QHBoxLayout();
256 layout
->addWidget( label
, 0 ); layout
->insertSpacing( 1, 10 );
257 layout
->addWidget( text
, LAST_COLUMN
);
258 widget
->setLayout( layout
);
262 l
->addWidget( label
, line
, 0 );
263 l
->setColumnMinimumWidth( 1, 10 );
264 l
->addWidget( text
, line
, LAST_COLUMN
);
268 StringConfigControl::StringConfigControl( vlc_object_t
*_p_this
,
269 module_config_t
*_p_item
,
270 QLabel
*_label
, QLineEdit
*_text
, bool pwd
):
271 VStringConfigControl( _p_this
, _p_item
)
274 if( pwd
) text
->setEchoMode( QLineEdit::Password
);
279 void StringConfigControl::finish()
281 text
->setText( qfu(p_item
->value
.psz
) );
282 text
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
285 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
286 label
->setBuddy( text
);
290 /*********** File **************/
291 FileConfigControl::FileConfigControl( vlc_object_t
*_p_this
,
292 module_config_t
*_p_item
,
293 QWidget
*_parent
, QGridLayout
*l
,
295 VStringConfigControl( _p_this
, _p_item
, _parent
)
297 label
= new QLabel( qtr(p_item
->psz_text
) );
298 text
= new QLineEdit( qfu(p_item
->value
.psz
) );
299 browse
= new QPushButton( qtr( "Browse..." ) );
300 QHBoxLayout
*textAndButton
= new QHBoxLayout();
301 textAndButton
->setMargin( 0 );
302 textAndButton
->addWidget( text
, 2 );
303 textAndButton
->addWidget( browse
, 0 );
305 BUTTONACT( browse
, updateField() );
311 QHBoxLayout
*layout
= new QHBoxLayout();
312 layout
->addWidget( label
, 0 );
313 layout
->insertSpacing( 1, 10 );
314 layout
->addLayout( textAndButton
, LAST_COLUMN
);
315 widget
->setLayout( layout
);
319 l
->addWidget( label
, line
, 0 );
320 l
->setColumnMinimumWidth( 1, 10 );
321 l
->addLayout( textAndButton
, line
, LAST_COLUMN
);
326 FileConfigControl::FileConfigControl( vlc_object_t
*_p_this
,
327 module_config_t
*_p_item
,
328 QLabel
*_label
, QLineEdit
*_text
,
329 QPushButton
*_button
):
330 VStringConfigControl( _p_this
, _p_item
)
336 BUTTONACT( browse
, updateField() );
341 void FileConfigControl::updateField()
343 QString file
= QFileDialog::getOpenFileName( NULL
,
344 qtr( "Select File" ), QVLCUserDir( VLC_HOME_DIR
) );
345 if( file
.isNull() ) return;
346 text
->setText( toNativeSeparators( file
) );
349 void FileConfigControl::finish()
351 text
->setText( qfu(p_item
->value
.psz
) );
352 text
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
355 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
356 label
->setBuddy( text
);
360 /********* String / Directory **********/
361 DirectoryConfigControl::DirectoryConfigControl( vlc_object_t
*_p_this
,
362 module_config_t
*_p_item
, QWidget
*_p_widget
,
363 QGridLayout
*_p_layout
, int& _int
) :
364 FileConfigControl( _p_this
, _p_item
, _p_widget
, _p_layout
, _int
)
367 DirectoryConfigControl::DirectoryConfigControl( vlc_object_t
*_p_this
,
368 module_config_t
*_p_item
, QLabel
*_p_label
,
369 QLineEdit
*_p_line
, QPushButton
*_p_button
):
370 FileConfigControl( _p_this
, _p_item
, _p_label
, _p_line
, _p_button
)
373 void DirectoryConfigControl::updateField()
375 QString dir
= QFileDialog::getExistingDirectory( NULL
,
377 text
->text().isEmpty() ?
378 QVLCUserDir( VLC_HOME_DIR
) : text
->text(),
379 QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks
);
381 if( dir
.isNull() ) return;
382 text
->setText( toNativeSepNoSlash( dir
) );
385 /********* String / Font **********/
386 FontConfigControl::FontConfigControl( vlc_object_t
*_p_this
,
387 module_config_t
*_p_item
, QWidget
*_parent
,
388 QGridLayout
*_p_layout
, int& line
) :
389 VStringConfigControl( _p_this
, _p_item
, _parent
)
391 label
= new QLabel( qtr(p_item
->psz_text
) );
392 font
= new QFontComboBox( _parent
);
393 font
->setCurrentFont( QFont( qfu( p_item
->value
.psz
) ) );
396 QHBoxLayout
*layout
= new QHBoxLayout();
397 layout
->addWidget( label
, 0 );
398 layout
->addWidget( font
, 1 );
399 widget
->setLayout( layout
);
403 _p_layout
->addWidget( label
, line
, 0 );
404 _p_layout
->addWidget( font
, line
, 1, 1, -1 );
408 FontConfigControl::FontConfigControl( vlc_object_t
*_p_this
,
409 module_config_t
*_p_item
, QLabel
*_p_label
,
410 QFontComboBox
*_p_font
):
411 VStringConfigControl( _p_this
, _p_item
)
415 font
->setCurrentFont( QFont( qfu( p_item
->value
.psz
) ) );
418 /********* String / choice list **********/
419 StringListConfigControl::StringListConfigControl( vlc_object_t
*_p_this
,
420 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
421 QGridLayout
*l
, int &line
) :
422 VStringConfigControl( _p_this
, _p_item
, _parent
)
424 label
= new QLabel( qtr(p_item
->psz_text
) );
425 combo
= new QComboBox();
426 combo
->setMinimumWidth( MINWIDTH_BOX
);
427 combo
->setSizePolicy( QSizePolicy::MinimumExpanding
, QSizePolicy::Preferred
);
429 module_config_t
*p_module_config
= config_FindConfig( p_this
, p_item
->psz_name
);
431 finish( p_module_config
, bycat
);
434 l
= new QGridLayout();
435 l
->addWidget( label
, 0, 0 ); l
->addWidget( combo
, 0, LAST_COLUMN
);
436 widget
->setLayout( l
);
440 l
->addWidget( label
, line
, 0 );
441 l
->addWidget( combo
, line
, LAST_COLUMN
, Qt::AlignRight
);
444 if( p_item
->i_action
)
446 QSignalMapper
*signalMapper
= new QSignalMapper(this);
448 /* Some stringLists like Capture listings have action associated */
449 for( int i
= 0; i
< p_item
->i_action
; i
++ )
451 QPushButton
*button
=
452 new QPushButton( qtr( p_item
->ppsz_action_text
[i
] ));
453 CONNECT( button
, clicked(), signalMapper
, map() );
454 signalMapper
->setMapping( button
, i
);
455 l
->addWidget( button
, line
, LAST_COLUMN
- p_item
->i_action
+ i
,
458 CONNECT( signalMapper
, mapped( int ),
459 this, actionRequested( int ) );
463 void StringListConfigControl::actionRequested( int i_action
)
465 /* Supplementary check for boundaries */
466 if( i_action
< 0 || i_action
>= p_item
->i_action
) return;
468 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
469 if(!p_module_config
) return;
472 val
.psz_string
= const_cast<char *>
473 qtu( (combo
->itemData( combo
->currentIndex() ).toString() ) );
475 p_module_config
->ppf_action
[i_action
]( p_this
, getName(), val
, val
, 0 );
477 if( p_module_config
->b_dirty
)
480 finish( p_module_config
, true );
481 p_module_config
->b_dirty
= false;
484 StringListConfigControl::StringListConfigControl( vlc_object_t
*_p_this
,
485 module_config_t
*_p_item
, QLabel
*_label
, QComboBox
*_combo
,
486 bool bycat
) : VStringConfigControl( _p_this
, _p_item
)
491 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
493 finish( p_module_config
, bycat
);
496 void StringListConfigControl::finish(module_config_t
*p_module_config
, bool bycat
)
498 combo
->setEditable( false );
500 if(!p_module_config
) return;
502 if( p_module_config
->pf_update_list
)
505 val
.psz_string
= strdup(p_module_config
->value
.psz
);
507 p_module_config
->pf_update_list(p_this
, p_item
->psz_name
, val
, val
, NULL
);
509 // assume in any case that dirty was set to true
510 // because lazy programmes will use the same callback for
511 // this, like the one behind the refresh push button?
512 p_module_config
->b_dirty
= false;
514 free( val
.psz_string
);
517 for( int i_index
= 0; i_index
< p_module_config
->i_list
; i_index
++ )
519 if( !p_module_config
->ppsz_list
[i_index
] )
521 combo
->addItem( "", QVariant(""));
522 combo
->setCurrentIndex( combo
->count() - 1 );
525 combo
->addItem( qfu((p_module_config
->ppsz_list_text
&&
526 p_module_config
->ppsz_list_text
[i_index
])?
527 p_module_config
->ppsz_list_text
[i_index
] :
528 p_module_config
->ppsz_list
[i_index
] ),
529 QVariant( qfu(p_module_config
->ppsz_list
[i_index
] )) );
530 if( p_item
->value
.psz
&& !strcmp( p_module_config
->value
.psz
,
531 p_module_config
->ppsz_list
[i_index
] ) )
532 combo
->setCurrentIndex( combo
->count() - 1 );
534 combo
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
537 label
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
538 label
->setBuddy( combo
);
542 QString
StringListConfigControl::getValue()
544 return combo
->itemData( combo
->currentIndex() ).toString();
547 void setfillVLCConfigCombo( const char *configname
, intf_thread_t
*p_intf
,
550 module_config_t
*p_config
=
551 config_FindConfig( VLC_OBJECT(p_intf
), configname
);
554 if(p_config
->pf_update_list
)
557 val
.i_int
= p_config
->value
.i
;
558 p_config
->pf_update_list(VLC_OBJECT(p_intf
), configname
, val
, val
, NULL
);
559 // assume in any case that dirty was set to true
560 // because lazy programmes will use the same callback for
561 // this, like the one behind the refresh push button?
562 p_config
->b_dirty
= false;
565 for ( int i_index
= 0; i_index
< p_config
->i_list
; i_index
++ )
567 combo
->addItem( qfu( p_config
->ppsz_list_text
[i_index
] ),
568 QVariant( p_config
->pi_list
[i_index
] ) );
569 if( p_config
->value
.i
== p_config
->pi_list
[i_index
] )
571 combo
->setCurrentIndex( i_index
);
574 combo
->setToolTip( qfu( p_config
->psz_longtext
) );
578 /********* Module **********/
579 ModuleConfigControl::ModuleConfigControl( vlc_object_t
*_p_this
,
580 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
581 QGridLayout
*l
, int &line
) :
582 VStringConfigControl( _p_this
, _p_item
, _parent
)
584 label
= new QLabel( qtr(p_item
->psz_text
) );
585 combo
= new QComboBox();
586 combo
->setMinimumWidth( MINWIDTH_BOX
);
590 QHBoxLayout
*layout
= new QHBoxLayout();
591 layout
->addWidget( label
); layout
->addWidget( combo
, LAST_COLUMN
);
592 widget
->setLayout( layout
);
596 l
->addWidget( label
, line
, 0 );
597 l
->addWidget( combo
, line
, LAST_COLUMN
, Qt::AlignRight
);
601 ModuleConfigControl::ModuleConfigControl( vlc_object_t
*_p_this
,
602 module_config_t
*_p_item
, QLabel
*_label
, QComboBox
*_combo
,
603 bool bycat
) : VStringConfigControl( _p_this
, _p_item
)
610 void ModuleConfigControl::finish( bool bycat
)
614 combo
->setEditable( false );
616 /* build a list of available modules */
617 module_t
**p_list
= module_list_get( NULL
);
618 combo
->addItem( qtr("Default") );
619 for( size_t i
= 0; (p_parser
= p_list
[i
]) != NULL
; i
++ )
623 if( !strcmp( module_get_object( p_parser
), "main" ) ) continue;
626 module_config_t
*p_config
;
628 p_config
= module_config_get (p_parser
, &confsize
);
629 for (size_t i
= 0; i
< confsize
; i
++)
631 /* Hack: required subcategory is stored in i_min */
632 const module_config_t
*p_cfg
= p_config
+ i
;
633 if( p_cfg
->i_type
== CONFIG_SUBCATEGORY
&&
634 p_cfg
->value
.i
== p_item
->min
.i
)
635 combo
->addItem( qtr( module_GetLongName( p_parser
)),
636 QVariant( module_get_object( p_parser
) ) );
637 if( p_item
->value
.psz
&& !strcmp( p_item
->value
.psz
,
638 module_get_object( p_parser
) ) )
639 combo
->setCurrentIndex( combo
->count() - 1 );
641 module_config_free (p_config
);
643 else if( module_provides( p_parser
, p_item
->psz_type
) )
645 combo
->addItem( qtr(module_GetLongName( p_parser
) ),
646 QVariant( module_get_object( p_parser
) ) );
647 if( p_item
->value
.psz
&& !strcmp( p_item
->value
.psz
,
648 module_get_object( p_parser
) ) )
649 combo
->setCurrentIndex( combo
->count() - 1 );
652 module_list_free( p_list
);
653 combo
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
656 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
657 label
->setBuddy( combo
);
661 QString
ModuleConfigControl::getValue()
663 return combo
->itemData( combo
->currentIndex() ).toString();
666 /********* Module list **********/
667 ModuleListConfigControl::ModuleListConfigControl( vlc_object_t
*_p_this
,
668 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
669 QGridLayout
*l
, int &line
) :
670 VStringConfigControl( _p_this
, _p_item
, _parent
)
674 if( !p_item
->psz_text
) return;
676 groupBox
= new QGroupBox ( qtr(p_item
->psz_text
), _parent
);
677 text
= new QLineEdit
;
678 QGridLayout
*layoutGroupBox
= new QGridLayout( groupBox
);
683 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
684 it
!= modules
.end(); it
++ )
686 layoutGroupBox
->addWidget( (*it
)->checkBox
, boxline
++, 0 );
688 layoutGroupBox
->addWidget( text
, boxline
, 0 );
692 QVBoxLayout
*layout
= new QVBoxLayout();
693 layout
->addWidget( groupBox
, line
, 0 );
694 widget
->setLayout( layout
);
698 l
->addWidget( groupBox
, line
, 0, 1, -1 );
701 text
->setToolTip( formatTooltip( qtr( p_item
->psz_longtext
) ) );
704 ModuleListConfigControl::~ModuleListConfigControl()
706 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
707 it
!= modules
.end(); it
++ )
714 #define CHECKBOX_LISTS \
716 QCheckBox *cb = new QCheckBox( qtr( module_GetLongName( p_parser ) ) );\
717 checkBoxListItem *cbl = new checkBoxListItem; \
719 CONNECT( cb, stateChanged( int ), this, onUpdate() );\
720 cb->setToolTip( formatTooltip( qtr( module_get_help( p_parser ))));\
721 cbl->checkBox = cb; \
723 cbl->psz_module = strdup( module_get_object( p_parser ) ); \
724 modules.push_back( cbl ); \
726 if( p_item->value.psz && strstr( p_item->value.psz, cbl->psz_module ) ) \
727 cbl->checkBox->setChecked( true ); \
731 void ModuleListConfigControl::finish( bool bycat
)
735 /* build a list of available modules */
736 module_t
**p_list
= module_list_get( NULL
);
737 for( size_t i
= 0; (p_parser
= p_list
[i
]) != NULL
; i
++ )
741 if( !strcmp( module_get_object( p_parser
), "main" ) ) continue;
744 module_config_t
*p_config
= module_config_get (p_parser
, &confsize
);
746 for (size_t i
= 0; i
< confsize
; i
++)
748 module_config_t
*p_cfg
= p_config
+ i
;
749 /* Hack: required subcategory is stored in i_min */
750 if( p_cfg
->i_type
== CONFIG_SUBCATEGORY
&&
751 p_cfg
->value
.i
== p_item
->min
.i
)
756 module_config_free (p_config
);
758 else if( module_provides( p_parser
, p_item
->psz_type
) )
763 module_list_free( p_list
);
764 text
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
766 groupBox
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
768 #undef CHECKBOX_LISTS
770 QString
ModuleListConfigControl::getValue()
776 void ModuleListConfigControl::hide()
778 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
779 it
!= modules
.end(); it
++ )
781 (*it
)->checkBox
->hide();
786 void ModuleListConfigControl::show()
788 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
789 it
!= modules
.end(); it
++ )
791 (*it
)->checkBox
->show();
797 void ModuleListConfigControl::onUpdate()
802 for( QVector
<checkBoxListItem
*>::iterator it
= modules
.begin();
803 it
!= modules
.end(); it
++ )
805 if( (*it
)->checkBox
->isChecked() )
809 text
->setText( text
->text() + (*it
)->psz_module
);
814 text
->setText( text
->text() + ":" + (*it
)->psz_module
);
820 /**************************************************************************
821 * Integer-based controls
822 *************************************************************************/
824 /*********** Integer **************/
825 IntegerConfigControl::IntegerConfigControl( vlc_object_t
*_p_this
,
826 module_config_t
*_p_item
,
827 QWidget
*_parent
, QGridLayout
*l
,
829 VIntConfigControl( _p_this
, _p_item
, _parent
)
831 label
= new QLabel( qtr(p_item
->psz_text
) );
832 spin
= new QSpinBox
; spin
->setMinimumWidth( MINWIDTH_BOX
);
833 spin
->setAlignment( Qt::AlignRight
);
834 spin
->setMaximumWidth( MINWIDTH_BOX
);
839 QHBoxLayout
*layout
= new QHBoxLayout();
840 layout
->addWidget( label
, 0 ); layout
->addWidget( spin
, LAST_COLUMN
);
841 widget
->setLayout( layout
);
845 l
->addWidget( label
, line
, 0 );
846 l
->addWidget( spin
, line
, LAST_COLUMN
, Qt::AlignRight
);
849 IntegerConfigControl::IntegerConfigControl( vlc_object_t
*_p_this
,
850 module_config_t
*_p_item
,
851 QLabel
*_label
, QSpinBox
*_spin
) :
852 VIntConfigControl( _p_this
, _p_item
)
859 void IntegerConfigControl::finish()
861 spin
->setMaximum( 2000000000 );
862 spin
->setMinimum( -2000000000 );
863 spin
->setValue( p_item
->value
.i
);
864 spin
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
867 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
868 label
->setBuddy( spin
);
872 int IntegerConfigControl::getValue()
874 return spin
->value();
877 /********* Integer range **********/
878 IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t
*_p_this
,
879 module_config_t
*_p_item
,
880 QWidget
*_parent
, QGridLayout
*l
,
882 IntegerConfigControl( _p_this
, _p_item
, _parent
, l
, line
)
887 IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t
*_p_this
,
888 module_config_t
*_p_item
,
889 QLabel
*_label
, QSpinBox
*_spin
) :
890 IntegerConfigControl( _p_this
, _p_item
, _label
, _spin
)
895 void IntegerRangeConfigControl::finish()
897 spin
->setMaximum( p_item
->max
.i
);
898 spin
->setMinimum( p_item
->min
.i
);
901 IntegerRangeSliderConfigControl::IntegerRangeSliderConfigControl(
902 vlc_object_t
*_p_this
,
903 module_config_t
*_p_item
,
904 QLabel
*_label
, QSlider
*_slider
):
905 VIntConfigControl( _p_this
, _p_item
)
909 slider
->setMaximum( p_item
->max
.i
);
910 slider
->setMinimum( p_item
->min
.i
);
911 slider
->setValue( p_item
->value
.i
);
912 slider
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
915 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
916 label
->setBuddy( slider
);
920 int IntegerRangeSliderConfigControl::getValue()
922 return slider
->value();
926 /********* Integer / choice list **********/
927 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t
*_p_this
,
928 module_config_t
*_p_item
, QWidget
*_parent
, bool bycat
,
929 QGridLayout
*l
, int &line
) :
930 VIntConfigControl( _p_this
, _p_item
, _parent
)
932 label
= new QLabel( qtr(p_item
->psz_text
) );
933 combo
= new QComboBox();
934 combo
->setMinimumWidth( MINWIDTH_BOX
);
936 module_config_t
*p_module_config
= config_FindConfig( p_this
, p_item
->psz_name
);
938 finish( p_module_config
, bycat
);
941 QHBoxLayout
*layout
= new QHBoxLayout();
942 layout
->addWidget( label
); layout
->addWidget( combo
, LAST_COLUMN
);
943 widget
->setLayout( layout
);
947 l
->addWidget( label
, line
, 0 );
948 l
->addWidget( combo
, line
, LAST_COLUMN
, Qt::AlignRight
);
951 if( p_item
->i_action
)
953 QSignalMapper
*signalMapper
= new QSignalMapper(this);
955 /* Some stringLists like Capture listings have action associated */
956 for( int i
= 0; i
< p_item
->i_action
; i
++ )
958 QPushButton
*button
=
959 new QPushButton( qfu( p_item
->ppsz_action_text
[i
] ));
960 CONNECT( button
, clicked(), signalMapper
, map() );
961 signalMapper
->setMapping( button
, i
);
962 l
->addWidget( button
, line
, LAST_COLUMN
- p_item
->i_action
+ i
,
965 CONNECT( signalMapper
, mapped( int ),
966 this, actionRequested( int ) );
970 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t
*_p_this
,
971 module_config_t
*_p_item
, QLabel
*_label
, QComboBox
*_combo
,
972 bool bycat
) : VIntConfigControl( _p_this
, _p_item
)
977 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
979 finish( p_module_config
, bycat
);
982 void IntegerListConfigControl::finish(module_config_t
*p_module_config
, bool bycat
)
984 combo
->setEditable( false );
986 if(!p_module_config
) return;
988 if( p_module_config
->pf_update_list
)
991 val
.i_int
= p_module_config
->value
.i
;
993 p_module_config
->pf_update_list(p_this
, p_item
->psz_name
, val
, val
, NULL
);
995 // assume in any case that dirty was set to true
996 // because lazy programmes will use the same callback for
997 // this, like the one behind the refresh push button?
998 p_module_config
->b_dirty
= false;
1001 for( int i_index
= 0; i_index
< p_module_config
->i_list
; i_index
++ )
1003 combo
->addItem( qtr(p_module_config
->ppsz_list_text
[i_index
] ),
1004 QVariant( p_module_config
->pi_list
[i_index
] ) );
1005 if( p_module_config
->value
.i
== p_module_config
->pi_list
[i_index
] )
1006 combo
->setCurrentIndex( combo
->count() - 1 );
1008 combo
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
1011 label
->setToolTip( formatTooltip(qtr(p_module_config
->psz_longtext
)) );
1012 label
->setBuddy( combo
);
1016 void IntegerListConfigControl::actionRequested( int i_action
)
1018 /* Supplementary check for boundaries */
1019 if( i_action
< 0 || i_action
>= p_item
->i_action
) return;
1021 module_config_t
*p_module_config
= config_FindConfig( p_this
, getName() );
1022 if(!p_module_config
) return;
1026 val
.i_int
= combo
->itemData( combo
->currentIndex() ).toInt();
1028 p_module_config
->ppf_action
[i_action
]( p_this
, getName(), val
, val
, 0 );
1030 if( p_module_config
->b_dirty
)
1033 finish( p_module_config
, true );
1034 p_module_config
->b_dirty
= false;
1038 int IntegerListConfigControl::getValue()
1040 return combo
->itemData( combo
->currentIndex() ).toInt();
1043 /*********** Boolean **************/
1044 BoolConfigControl::BoolConfigControl( vlc_object_t
*_p_this
,
1045 module_config_t
*_p_item
,
1046 QWidget
*_parent
, QGridLayout
*l
,
1048 VIntConfigControl( _p_this
, _p_item
, _parent
)
1050 checkbox
= new QCheckBox( qtr(p_item
->psz_text
) );
1055 QHBoxLayout
*layout
= new QHBoxLayout();
1056 layout
->addWidget( checkbox
, 0 );
1057 widget
->setLayout( layout
);
1061 l
->addWidget( checkbox
, line
, 0 );
1065 BoolConfigControl::BoolConfigControl( vlc_object_t
*_p_this
,
1066 module_config_t
*_p_item
,
1068 QAbstractButton
*_checkbox
,
1070 VIntConfigControl( _p_this
, _p_item
)
1072 checkbox
= _checkbox
;
1073 VLC_UNUSED( _label
);
1077 void BoolConfigControl::finish()
1079 checkbox
->setChecked( p_item
->value
.i
== true );
1080 checkbox
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
1083 int BoolConfigControl::getValue()
1085 return checkbox
->isChecked();
1088 /**************************************************************************
1089 * Float-based controls
1090 *************************************************************************/
1092 /*********** Float **************/
1093 FloatConfigControl::FloatConfigControl( vlc_object_t
*_p_this
,
1094 module_config_t
*_p_item
,
1095 QWidget
*_parent
, QGridLayout
*l
,
1097 VFloatConfigControl( _p_this
, _p_item
, _parent
)
1099 label
= new QLabel( qtr(p_item
->psz_text
) );
1100 spin
= new QDoubleSpinBox
;
1101 spin
->setMinimumWidth( MINWIDTH_BOX
);
1102 spin
->setMaximumWidth( MINWIDTH_BOX
);
1103 spin
->setAlignment( Qt::AlignRight
);
1108 QHBoxLayout
*layout
= new QHBoxLayout();
1109 layout
->addWidget( label
, 0 ); layout
->addWidget( spin
, LAST_COLUMN
);
1110 widget
->setLayout( layout
);
1114 l
->addWidget( label
, line
, 0 );
1115 l
->addWidget( spin
, line
, LAST_COLUMN
, Qt::AlignRight
);
1119 FloatConfigControl::FloatConfigControl( vlc_object_t
*_p_this
,
1120 module_config_t
*_p_item
,
1122 QDoubleSpinBox
*_spin
) :
1123 VFloatConfigControl( _p_this
, _p_item
)
1130 void FloatConfigControl::finish()
1132 spin
->setMaximum( 2000000000. );
1133 spin
->setMinimum( -2000000000. );
1134 spin
->setSingleStep( 0.1 );
1135 spin
->setValue( (double)p_item
->value
.f
);
1136 spin
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
1139 label
->setToolTip( formatTooltip(qtr(p_item
->psz_longtext
)) );
1140 label
->setBuddy( spin
);
1144 float FloatConfigControl::getValue()
1146 return (float)spin
->value();
1149 /*********** Float with range **************/
1150 FloatRangeConfigControl::FloatRangeConfigControl( vlc_object_t
*_p_this
,
1151 module_config_t
*_p_item
,
1152 QWidget
*_parent
, QGridLayout
*l
,
1154 FloatConfigControl( _p_this
, _p_item
, _parent
, l
, line
)
1159 FloatRangeConfigControl::FloatRangeConfigControl( vlc_object_t
*_p_this
,
1160 module_config_t
*_p_item
,
1162 QDoubleSpinBox
*_spin
) :
1163 FloatConfigControl( _p_this
, _p_item
, _label
, _spin
)
1168 void FloatRangeConfigControl::finish()
1170 spin
->setMaximum( (double)p_item
->max
.f
);
1171 spin
->setMinimum( (double)p_item
->min
.f
);
1175 /**********************************************************************
1176 * Key selector widget
1177 **********************************************************************/
1178 KeySelectorControl::KeySelectorControl( vlc_object_t
*_p_this
,
1179 module_config_t
*_p_item
,
1180 QWidget
*_parent
, QGridLayout
*l
,
1182 ConfigControl( _p_this
, _p_item
, _parent
)
1185 QWidget
*keyContainer
= new QWidget
;
1186 QGridLayout
*gLayout
= new QGridLayout( keyContainer
);
1189 qtr( "Select an action to change the associated hotkey") );
1191 QLabel
*searchLabel
= new QLabel( qtr( "Search" ) );
1192 actionSearch
= new SearchLineEdit( keyContainer
);
1194 table
= new QTreeWidget
;
1195 table
->setColumnCount(3);
1196 table
->headerItem()->setText( 0, qtr( "Action" ) );
1197 table
->headerItem()->setText( 1, qtr( "Hotkey" ) );
1198 table
->headerItem()->setText( 2, qtr( "Global" ) );
1199 table
->setAlternatingRowColors( true );
1200 table
->setSelectionBehavior( QAbstractItemView::SelectItems
);
1202 shortcutValue
= new KeyShortcutEdit
;
1203 shortcutValue
->setReadOnly(true);
1205 QPushButton
*clearButton
= new QPushButton( qtr( "Clear" ) );
1206 QPushButton
*setButton
= new QPushButton( qtr( "Apply" ) );
1207 setButton
->setDefault( true );
1210 gLayout
->addWidget( label
, 0, 0, 1, 4 );
1211 gLayout
->addWidget( searchLabel
, 1, 0, 1, 2 );
1212 gLayout
->addWidget( actionSearch
, 1, 2, 1, 2 );
1213 gLayout
->addWidget( table
, 2, 0, 1, 4 );
1214 gLayout
->addWidget( clearButton
, 3, 0, 1, 1 );
1215 gLayout
->addWidget( shortcutValue
, 3, 1, 1, 2 );
1216 gLayout
->addWidget( setButton
, 3, 3, 1, 1 );
1218 l
->addWidget( keyContainer
, line
, 0, 1, -1 );
1220 CONNECT( clearButton
, clicked(), shortcutValue
, clear() );
1221 CONNECT( clearButton
, clicked(), this, setTheKey() );
1222 BUTTONACT( setButton
, setTheKey() );
1223 CONNECT( actionSearch
, textChanged( const QString
& ),
1224 this, filter( const QString
& ) );
1227 void KeySelectorControl::finish()
1230 label
->setToolTip( formatTooltip( qtr( p_item
->psz_longtext
) ) );
1232 /* Fill the table */
1234 /* Get the main Module */
1235 module_t
*p_main
= module_get_main();
1238 /* Access to the module_config_t */
1240 module_config_t
*p_config
;
1242 p_config
= module_config_get (p_main
, &confsize
);
1244 for (size_t i
= 0; i
< confsize
; i
++)
1246 module_config_t
*p_item
= p_config
+ i
;
1248 /* If we are a key option not empty */
1249 if( p_item
->i_type
& CONFIG_ITEM
&& p_item
->psz_name
1250 && strstr( p_item
->psz_name
, "key-" )
1251 && !strstr( p_item
->psz_name
, "global-key" )
1252 && !EMPTY_STR( p_item
->psz_text
) )
1256 - QString text in column 0
1257 - QString name in data of column 0
1258 - KeyValue in String in column 1
1259 - KeyValue in int in column 1
1261 QTreeWidgetItem
*treeItem
= new QTreeWidgetItem();
1262 treeItem
->setText( 0, qtr( p_item
->psz_text
) );
1263 treeItem
->setData( 0, Qt::UserRole
,
1264 QVariant( qfu( p_item
->psz_name
) ) );
1265 treeItem
->setText( 1, VLCKeyToString( p_item
->value
.i
) );
1266 treeItem
->setData( 1, Qt::UserRole
, QVariant( p_item
->value
.i
) );
1267 table
->addTopLevelItem( treeItem
);
1271 if( p_item
->i_type
& CONFIG_ITEM
&& p_item
->psz_name
1272 && strstr( p_item
->psz_name
, "global-key" )
1273 && !EMPTY_STR( p_item
->psz_text
) )
1275 QList
<QTreeWidgetItem
*> list
=
1276 table
->findItems( qtr( p_item
->psz_text
), Qt::MatchExactly
);
1277 if( list
.count() >= 1 )
1279 list
[0]->setText( 2, VLCKeyToString( p_item
->value
.i
) );
1280 list
[0]->setData( 2, Qt::UserRole
,
1281 QVariant( p_item
->value
.i
) );
1283 if( list
.count() >= 2 )
1284 msg_Dbg( p_this
, "This is probably wrong, %s", p_item
->psz_text
);
1287 module_config_free (p_config
);
1288 module_release (p_main
);
1290 table
->resizeColumnToContents( 0 );
1292 CONNECT( table
, itemDoubleClicked( QTreeWidgetItem
*, int ),
1293 this, selectKey( QTreeWidgetItem
*, int ) );
1294 CONNECT( table
, itemClicked( QTreeWidgetItem
*, int ),
1295 this, select( QTreeWidgetItem
*, int) );
1296 CONNECT( table
, itemSelectionChanged(),
1297 this, select1Key() );
1299 CONNECT( shortcutValue
, pressed(), this, selectKey() );
1302 void KeySelectorControl::filter( const QString
&qs_search
)
1304 QList
<QTreeWidgetItem
*> resultList
=
1305 table
->findItems( qs_search
, Qt::MatchContains
, 0 );
1306 for( int i
= 0; i
< table
->topLevelItemCount(); i
++ )
1308 table
->topLevelItem( i
)->setHidden(
1309 !resultList
.contains( table
->topLevelItem( i
) ) );
1313 void KeySelectorControl::select( QTreeWidgetItem
*keyItem
, int column
)
1315 shortcutValue
->setGlobal( column
== 2 );
1318 /* Show the key selected from the table in the keySelector */
1319 void KeySelectorControl::select1Key()
1321 QTreeWidgetItem
*keyItem
= table
->currentItem();
1322 shortcutValue
->setText( keyItem
->text( 1 ) );
1323 shortcutValue
->setValue( keyItem
->data( 1, Qt::UserRole
).toInt() );
1324 shortcutValue
->setGlobal( false );
1327 void KeySelectorControl::selectKey( QTreeWidgetItem
*keyItem
, int column
)
1329 /* This happens when triggered by ClickEater */
1330 if( keyItem
== NULL
) keyItem
= table
->currentItem();
1332 /* This can happen when nothing is selected on the treeView
1333 and the shortcutValue is clicked */
1334 if( !keyItem
) return;
1336 /* If clicked on the first column, assuming user wants the normal hotkey */
1337 if( column
== 0 ) column
= 1;
1339 bool b_global
= ( column
== 2 );
1341 /* Launch a small dialog to ask for a new key */
1342 KeyInputDialog
*d
= new KeyInputDialog( table
, keyItem
->text( 0 ), widget
, b_global
);
1345 if( d
->result() == QDialog::Accepted
)
1347 int newValue
= d
->keyValue
;
1348 shortcutValue
->setText( VLCKeyToString( newValue
) );
1349 shortcutValue
->setValue( newValue
);
1350 shortcutValue
->setGlobal( b_global
);
1354 QTreeWidgetItem
*it
;
1355 for( int i
= 0; i
< table
->topLevelItemCount() ; i
++ )
1357 it
= table
->topLevelItem(i
);
1358 if( ( keyItem
!= it
) &&
1359 ( it
->data( b_global
? 2: 1, Qt::UserRole
).toInt() == newValue
) )
1361 it
->setData( b_global
? 2 : 1, Qt::UserRole
, QVariant( -1 ) );
1362 it
->setText( b_global
? 2 : 1, qtr( "Unset" ) );
1365 /* We already made an OK once. */
1372 void KeySelectorControl::setTheKey()
1374 if( !table
->currentItem() ) return;
1375 table
->currentItem()->setText( shortcutValue
->getGlobal() ? 2 : 1,
1376 shortcutValue
->text() );
1377 table
->currentItem()->setData( shortcutValue
->getGlobal() ? 2 : 1,
1378 Qt::UserRole
, shortcutValue
->getValue() );
1381 void KeySelectorControl::doApply()
1383 QTreeWidgetItem
*it
;
1384 for( int i
= 0; i
< table
->topLevelItemCount() ; i
++ )
1386 it
= table
->topLevelItem(i
);
1387 if( it
->data( 1, Qt::UserRole
).toInt() >= 0 )
1388 config_PutInt( p_this
,
1389 qtu( it
->data( 0, Qt::UserRole
).toString() ),
1390 it
->data( 1, Qt::UserRole
).toInt() );
1391 if( it
->data( 2, Qt::UserRole
).toInt() >= 0 )
1392 config_PutInt( p_this
,
1393 qtu( "global-" + it
->data( 0, Qt::UserRole
).toString() ),
1394 it
->data( 2, Qt::UserRole
).toInt() );
1400 * Class KeyInputDialog
1402 KeyInputDialog::KeyInputDialog( QTreeWidget
*_table
,
1403 const QString
& keyToChange
,
1406 QDialog( _parent
), keyValue(0), b_global( _b_global
)
1412 setWindowTitle( b_global
? qtr( "Global" ): ""
1413 + qtr( "Hotkey for " ) + keyToChange
);
1414 setWindowRole( "vlc-key-input" );
1416 vLayout
= new QVBoxLayout( this );
1417 selected
= new QLabel( qtr( "Press the new keys for " ) + keyToChange
);
1418 vLayout
->addWidget( selected
, Qt::AlignCenter
);
1420 warning
= new QLabel
;
1422 vLayout
->insertWidget( 1, warning
);
1424 buttonBox
= new QDialogButtonBox
;
1425 QPushButton
*ok
= new QPushButton( qtr("OK") );
1426 QPushButton
*cancel
= new QPushButton( qtr("Cancel") );
1427 buttonBox
->addButton( ok
, QDialogButtonBox::AcceptRole
);
1428 buttonBox
->addButton( cancel
, QDialogButtonBox::RejectRole
);
1429 ok
->setDefault( true );
1431 vLayout
->addWidget( buttonBox
);
1434 CONNECT( buttonBox
, accepted(), this, accept() );
1435 CONNECT( buttonBox
, rejected(), this, reject() );
1438 void KeyInputDialog::checkForConflicts( int i_vlckey
)
1440 QList
<QTreeWidgetItem
*> conflictList
=
1441 table
->findItems( VLCKeyToString( i_vlckey
), Qt::MatchExactly
,
1444 if( conflictList
.size() &&
1445 conflictList
[0]->data( b_global
? 2 : 1, Qt::UserRole
).toInt() > 1 )
1446 /* Avoid 0 or -1 that are the "Unset" states */
1448 warning
->setText( qtr("Warning: the key is already assigned to \"") +
1449 conflictList
[0]->text( 0 ) + "\"" );
1458 void KeyInputDialog::keyPressEvent( QKeyEvent
*e
)
1460 if( e
->key() == Qt::Key_Tab
||
1461 e
->key() == Qt::Key_Shift
||
1462 e
->key() == Qt::Key_Control
||
1463 e
->key() == Qt::Key_Meta
||
1464 e
->key() == Qt::Key_Alt
||
1465 e
->key() == Qt::Key_AltGr
)
1467 int i_vlck
= qtEventToVLCKey( e
);
1468 selected
->setText( qtr( "Key: " ) + VLCKeyToString( i_vlck
) );
1469 checkForConflicts( i_vlck
);
1473 void KeyInputDialog::wheelEvent( QWheelEvent
*e
)
1475 int i_vlck
= qtWheelEventToVLCKey( e
);
1476 selected
->setText( qtr( "Key: " ) + VLCKeyToString( i_vlck
) );
1477 checkForConflicts( i_vlck
);
1481 void KeyShortcutEdit::mousePressEvent( QMouseEvent
*)