]> git.sesse.net Git - vlc/blob - modules/gui/qt4/components/preferences_widgets.cpp
Qt4 - Complete preferences. Make ModuleList Clearer than it is now... Align SpinBox...
[vlc] / modules / gui / qt4 / components / preferences_widgets.cpp
1 /*****************************************************************************
2  * preferences_widgets.cpp : Widgets for preferences displays
3  ****************************************************************************
4  * Copyright (C) 2006-2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *          Antoine Cellerier <dionoea@videolan.org>
9  *          Jean-Baptiste Kempf <jb@videolan.org>
10  *
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.
15  *
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.
20  *
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  *****************************************************************************/
25
26 /**
27  * Todo:
28  *  - Finish implementation (see WX)
29  *  - Improvements over WX
30  *      - Password field implementation (through "pwd" bool param
31  *      - Validator for modulelist
32  *  - Implement update stuff using a general Updated signal
33  */
34
35 #include "components/preferences_widgets.hpp"
36 #include "util/customwidgets.hpp"
37 #include "qt4.hpp"
38
39 #include <QLineEdit>
40 #include <QString>
41 #include <QSpinBox>
42 #include <QDoubleSpinBox>
43 #include <QVariant>
44 #include <QComboBox>
45 #include <QGridLayout>
46 #include <QPushButton>
47 #include <QSlider>
48 #include <QFileDialog>
49 #include <QFontDialog>
50 #include <QGroupBox>
51
52 #include <vlc_keys.h>
53
54 ConfigControl *ConfigControl::createControl( vlc_object_t *p_this,
55                                              module_config_t *p_item,
56                                              QWidget *parent )
57 {
58     int i=0;
59     return createControl( p_this, p_item, parent, NULL, i );
60 }
61
62 ConfigControl *ConfigControl::createControl( vlc_object_t *p_this,
63                                              module_config_t *p_item,
64                                              QWidget *parent,
65                                              QGridLayout *l, int &line )
66 {
67     ConfigControl *p_control = NULL;
68     if( p_item->psz_current ) return NULL;
69
70     switch( p_item->i_type )
71     {
72     case CONFIG_ITEM_MODULE:
73         p_control = new ModuleConfigControl( p_this, p_item, parent, false,
74                                              l, line );
75         break;
76     case CONFIG_ITEM_MODULE_CAT:
77         p_control = new ModuleConfigControl( p_this, p_item, parent, true,
78                                              l, line );
79         break;
80     case CONFIG_ITEM_MODULE_LIST:
81         p_control = new ModuleListConfigControl( p_this, p_item, parent, false,
82                                              l, line );
83         break;
84     case CONFIG_ITEM_MODULE_LIST_CAT:
85         p_control = new ModuleListConfigControl( p_this, p_item, parent, true,
86                                              l, line );
87         break;
88     case CONFIG_ITEM_STRING:
89         if( !p_item->i_list )
90             p_control = new StringConfigControl( p_this, p_item, parent,
91                                                  l, line, false );
92         else
93             p_control = new StringListConfigControl( p_this, p_item,
94                                             parent, false, l, line );
95         break;
96     case CONFIG_ITEM_INTEGER:
97         if( p_item->i_list )
98             p_control = new IntegerListConfigControl( p_this, p_item,
99                                             parent, false, l, line );
100         else if( p_item->min.i || p_item->max.i )
101             p_control = new IntegerRangeConfigControl( p_this, p_item, parent,
102                                                        l, line );
103         else
104             p_control = new IntegerConfigControl( p_this, p_item, parent,
105                                                   l, line );
106         break;
107     case CONFIG_ITEM_FILE:
108         p_control = new FileConfigControl( p_this, p_item, parent, l,
109                                                 line, false );
110         break;
111     case CONFIG_ITEM_DIRECTORY:
112         p_control = new DirectoryConfigControl( p_this, p_item, parent, l,
113                                                 line, false );
114         break;
115     case CONFIG_ITEM_FONT:
116         p_control = new FontConfigControl( p_this, p_item, parent, l,
117                                            line, false );
118         break;
119     case CONFIG_ITEM_KEY:
120         p_control = new KeySelectorControl( p_this, p_item, parent, l, line );
121         break;
122     case CONFIG_ITEM_BOOL:
123         p_control = new BoolConfigControl( p_this, p_item, parent, l, line );
124         break;
125     case CONFIG_ITEM_FLOAT:
126         if( p_item->min.f || p_item->max.f )
127             p_control = new FloatRangeConfigControl( p_this, p_item, parent,
128                                                      l, line );
129         else
130             p_control = new FloatConfigControl( p_this, p_item, parent,
131                                                   l, line );
132         break;
133     default:
134         break;
135     }
136     return p_control;
137 }
138
139 void ConfigControl::doApply( intf_thread_t *p_intf )
140 {
141     switch( getType() )
142     {
143         case 1:
144         {
145             VIntConfigControl *vicc = qobject_cast<VIntConfigControl *>(this);
146             assert( vicc );
147             config_PutInt( p_intf, vicc->getName(), vicc->getValue() );
148             break;
149         }
150         case 2:
151         {
152             VFloatConfigControl *vfcc =
153                                     qobject_cast<VFloatConfigControl *>(this);
154             assert( vfcc );
155             config_PutFloat( p_intf, vfcc->getName(), vfcc->getValue() );
156             break;
157         }
158         case 3:
159         {
160             VStringConfigControl *vscc =
161                             qobject_cast<VStringConfigControl *>(this);
162             assert( vscc );
163             config_PutPsz( p_intf, vscc->getName(), qta( vscc->getValue() ) );
164             break;
165         }
166         case 4:
167         {
168             KeySelectorControl *ksc = qobject_cast<KeySelectorControl *>(this);
169             assert( ksc );
170             ksc->doApply();
171         }
172     }
173 }
174
175 /**************************************************************************
176  * String-based controls
177  *************************************************************************/
178
179 /*********** String **************/
180 StringConfigControl::StringConfigControl( vlc_object_t *_p_this,
181                                           module_config_t *_p_item,
182                                           QWidget *_parent, QGridLayout *l,
183                                           int &line, bool pwd ) :
184                            VStringConfigControl( _p_this, _p_item, _parent )
185 {
186     label = new QLabel( qfu(p_item->psz_text) );
187     text = new QLineEdit( qfu(p_item->value.psz) );
188     finish();
189
190     if( !l )
191     {
192         QHBoxLayout *layout = new QHBoxLayout();
193         layout->addWidget( label, 0 ); layout->addWidget( text, 1 );
194         widget->setLayout( layout );
195     }
196     else
197     {
198         l->addWidget( label, line, 0 ); l->addWidget( text, line, 1 );
199     }
200 }
201
202 StringConfigControl::StringConfigControl( vlc_object_t *_p_this,
203                                    module_config_t *_p_item,
204                                    QLabel *_label, QLineEdit *_text, bool pwd ):
205                            VStringConfigControl( _p_this, _p_item )
206 {
207     text = _text;
208     label = _label;
209     finish( );
210 }
211
212 void StringConfigControl::finish()
213 {
214     text->setText( qfu(p_item->value.psz) );
215     text->setToolTip( qfu(p_item->psz_longtext) );
216     if( label )
217         label->setToolTip( qfu(p_item->psz_longtext) );
218 }
219
220 /*********** File **************/
221 FileConfigControl::FileConfigControl( vlc_object_t *_p_this,
222                                           module_config_t *_p_item,
223                                           QWidget *_parent, QGridLayout *l,
224                                           int &line, bool pwd ) :
225                            VStringConfigControl( _p_this, _p_item, _parent )
226 {
227     label = new QLabel( qfu(p_item->psz_text) );
228     text = new QLineEdit( qfu(p_item->value.psz) );
229     browse = new QPushButton( qtr( "Browse..." ) );
230     QHBoxLayout *textAndButton = new QHBoxLayout();
231     textAndButton->setMargin( 0 );
232     textAndButton->addWidget( text, 2 );
233     textAndButton->addWidget( browse, 0 );
234
235     BUTTONACT( browse, updateField() );
236
237     finish();
238
239     if( !l )
240     {
241         QHBoxLayout *layout = new QHBoxLayout();
242         layout->addWidget( label, 0 );
243         layout->addLayout( textAndButton, 1 );
244         widget->setLayout( layout );
245     }
246     else
247     {
248         l->addWidget( label, line, 0 );
249         l->addLayout( textAndButton, line, 1 );
250     }
251 }
252
253
254 FileConfigControl::FileConfigControl( vlc_object_t *_p_this,
255                                    module_config_t *_p_item,
256                                    QLabel *_label, QLineEdit *_text,
257                                    QPushButton *_button, bool pwd ):
258                            VStringConfigControl( _p_this, _p_item )
259 {
260     browse = _button;
261     text = _text;
262     label = _label;
263
264     BUTTONACT( browse, updateField() );
265
266     finish( );
267 }
268
269 void FileConfigControl::updateField()
270 {
271     QString file = QFileDialog::getOpenFileName( NULL,
272                   qtr( "Select File" ), qfu( p_this->p_libvlc->psz_homedir ) );
273     if( file.isNull() ) return;
274     text->setText( file );
275 }
276
277 void FileConfigControl::finish()
278 {
279     text->setText( qfu(p_item->value.psz) );
280     text->setToolTip( qfu(p_item->psz_longtext) );
281     if( label )
282         label->setToolTip( qfu(p_item->psz_longtext) );
283 }
284
285 /********* String / Directory **********/
286 DirectoryConfigControl::DirectoryConfigControl( vlc_object_t *_p_this,
287                         module_config_t *_p_item, QWidget *_p_widget,
288                         QGridLayout *_p_layout, int& _int, bool _pwd ) :
289      FileConfigControl( _p_this, _p_item, _p_widget, _p_layout, _int, _pwd)
290 {}
291
292 DirectoryConfigControl::DirectoryConfigControl( vlc_object_t *_p_this,
293                         module_config_t *_p_item, QLabel *_p_label,
294                         QLineEdit *_p_line, QPushButton *_p_button, bool _pwd ):
295      FileConfigControl( _p_this, _p_item, _p_label, _p_line, _p_button, _pwd)
296 {}
297
298 void DirectoryConfigControl::updateField()
299 {
300     QString dir = QFileDialog::getExistingDirectory( NULL,
301                       qtr( "Select Directory" ),
302                       text->text().isEmpty() ?
303                         qfu( p_this->p_libvlc->psz_homedir ) : text->text(),
304                       QFileDialog::ShowDirsOnly |
305                         QFileDialog::DontResolveSymlinks );
306     if( dir.isNull() ) return;
307     text->setText( dir );
308 }
309
310 /********* String / Font **********/
311 FontConfigControl::FontConfigControl( vlc_object_t *_p_this,
312                         module_config_t *_p_item, QWidget *_p_widget,
313                         QGridLayout *_p_layout, int& _int, bool _pwd ) :
314      FileConfigControl( _p_this, _p_item, _p_widget, _p_layout, _int, _pwd)
315 {}
316
317 FontConfigControl::FontConfigControl( vlc_object_t *_p_this,
318                         module_config_t *_p_item, QLabel *_p_label,
319                         QLineEdit *_p_line, QPushButton *_p_button, bool _pwd ):
320      FileConfigControl( _p_this, _p_item, _p_label, _p_line, _p_button, _pwd)
321 {}
322
323 void FontConfigControl::updateField()
324 {
325     bool ok;
326     QFont font = QFontDialog::getFont( &ok, QFont( text->text() ), NULL );
327     if( !ok ) return;
328     text->setText( font.family() );
329 }
330
331 /********* String / choice list **********/
332 StringListConfigControl::StringListConfigControl( vlc_object_t *_p_this,
333                module_config_t *_p_item, QWidget *_parent, bool bycat,
334                QGridLayout *l, int &line) :
335                VStringConfigControl( _p_this, _p_item, _parent )
336 {
337     label = new QLabel( qfu(p_item->psz_text) );
338     combo = new QComboBox();
339     finish( bycat );
340     if( !l )
341     {
342         QHBoxLayout *layout = new QHBoxLayout();
343         layout->addWidget( label ); layout->addWidget( combo );
344         widget->setLayout( layout );
345     }
346     else
347     {
348         l->addWidget( label, line, 0 );
349         l->addWidget( combo, line, 1, Qt::AlignRight );
350     }
351 }
352 StringListConfigControl::StringListConfigControl( vlc_object_t *_p_this,
353                 module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
354                 bool bycat ) : VStringConfigControl( _p_this, _p_item )
355 {
356     combo = _combo;
357     label = _label;
358     finish( bycat );
359 }
360
361 void StringListConfigControl::finish( bool bycat )
362 {
363     combo->setEditable( false );
364
365     for( int i_index = 0; i_index < p_item->i_list; i_index++ )
366     {
367         combo->addItem( qfu(p_item->ppsz_list_text ?
368                             p_item->ppsz_list_text[i_index] :
369                             p_item->ppsz_list[i_index] ),
370                         QVariant( p_item->ppsz_list[i_index] ) );
371         if( p_item->value.psz && !strcmp( p_item->value.psz,
372                                           p_item->ppsz_list[i_index] ) )
373             combo->setCurrentIndex( combo->count() - 1 );
374     }
375     combo->setToolTip( qfu(p_item->psz_longtext) );
376     if( label )
377         label->setToolTip( qfu(p_item->psz_longtext) );
378 }
379
380 QString StringListConfigControl::getValue()
381 {
382     return combo->itemData( combo->currentIndex() ).toString();
383 }
384
385 /********* Module **********/
386 ModuleConfigControl::ModuleConfigControl( vlc_object_t *_p_this,
387                module_config_t *_p_item, QWidget *_parent, bool bycat,
388                QGridLayout *l, int &line) :
389                VStringConfigControl( _p_this, _p_item, _parent )
390 {
391     label = new QLabel( qfu(p_item->psz_text) );
392     combo = new QComboBox();
393     finish( bycat );
394     if( !l )
395     {
396         QHBoxLayout *layout = new QHBoxLayout();
397         layout->addWidget( label ); layout->addWidget( combo );
398         widget->setLayout( layout );
399     }
400     else
401     {
402         l->addWidget( label, line, 0 );
403         l->addWidget( combo, line, 1, Qt::AlignRight );
404     }
405 }
406 ModuleConfigControl::ModuleConfigControl( vlc_object_t *_p_this,
407                 module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
408                 bool bycat ) : VStringConfigControl( _p_this, _p_item )
409 {
410     combo = _combo;
411     label = _label;
412     finish( bycat );
413 }
414
415 void ModuleConfigControl::finish( bool bycat )
416 {
417     vlc_list_t *p_list;
418     module_t *p_parser;
419
420     combo->setEditable( false );
421
422     /* build a list of available modules */
423     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
424     combo->addItem( qtr("Default") );
425     for( int i_index = 0; i_index < p_list->i_count; i_index++ )
426     {
427         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
428
429         if( bycat )
430         {
431             if( !strcmp( p_parser->psz_object_name, "main" ) ) continue;
432
433             for (size_t i = 0; i < p_parser->confsize; i++)
434             {
435                 module_config_t *p_config = p_parser->p_config + i;
436                 /* Hack: required subcategory is stored in i_min */
437                 if( p_config->i_type == CONFIG_SUBCATEGORY &&
438                     p_config->value.i == p_item->min.i )
439                     combo->addItem( qfu(p_parser->psz_longname),
440                                     QVariant( p_parser->psz_object_name ) );
441                 if( p_item->value.psz && !strcmp( p_item->value.psz,
442                                                   p_parser->psz_object_name) )
443                     combo->setCurrentIndex( combo->count() - 1 );
444             }
445         }
446         else if( !strcmp( p_parser->psz_capability, p_item->psz_type ) )
447         {
448             combo->addItem( qfu(p_parser->psz_longname),
449                             QVariant( p_parser->psz_object_name ) );
450             if( p_item->value.psz && !strcmp( p_item->value.psz,
451                                               p_parser->psz_object_name) )
452                 combo->setCurrentIndex( combo->count() - 1 );
453         }
454     }
455     vlc_list_release( p_list );
456     combo->setToolTip( qfu(p_item->psz_longtext) );
457     if( label )
458         label->setToolTip( qfu(p_item->psz_longtext) );
459 }
460
461 QString ModuleConfigControl::getValue()
462 {
463     return combo->itemData( combo->currentIndex() ).toString();
464 }
465
466 /********* Module list **********/
467 ModuleListConfigControl::ModuleListConfigControl( vlc_object_t *_p_this,
468                module_config_t *_p_item, QWidget *_parent, bool bycat,
469                QGridLayout *l, int &line) :
470                VStringConfigControl( _p_this, _p_item, _parent )
471 {
472     groupBox = new QGroupBox ( qfu(p_item->psz_text) );
473     text = new QLineEdit();
474     QGridLayout *layoutGroupBox = new QGridLayout( groupBox );
475
476     finish( bycat );
477
478     int boxline = 0;
479     for( QVector<QCheckBox*>::iterator it = modules.begin();
480          it != modules.end(); it++ )
481     {
482         layoutGroupBox->addWidget( *it, boxline++, 0 );
483     }
484     layoutGroupBox->addWidget( text, boxline, 0 );
485
486     if( !l )
487     {
488         QVBoxLayout *layout = new QVBoxLayout();
489         layout->addWidget( groupBox, line, 0 );
490         widget->setLayout( layout );
491     }
492     else
493     {
494         l->addWidget( groupBox, line, 0, 1, -1 );
495     }
496 }
497 #if 0
498 ModuleConfigControl::ModuleConfigControl( vlc_object_t *_p_this,
499                 module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
500                 bool bycat ) : VStringConfigControl( _p_this, _p_item )
501 {
502     combo = _combo;
503     label = _label;
504     finish( bycat );
505 }
506 #endif
507
508 ModuleListConfigControl::~ModuleListConfigControl()
509 {
510     for( QVector<QCheckBox*>::iterator it = modules.begin();
511          it != modules.end(); it++ )
512     {
513         delete *it;
514     }
515     delete groupBox;
516     delete text;
517 }
518
519 void ModuleListConfigControl::finish( bool bycat )
520 {
521     vlc_list_t *p_list;
522     module_t *p_parser;
523
524     /* build a list of available modules */
525     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
526     for( int i_index = 0; i_index < p_list->i_count; i_index++ )
527     {
528         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
529
530         if( bycat )
531         {
532             if( !strcmp( p_parser->psz_object_name, "main" ) ) continue;
533
534             for (size_t i = 0; i < p_parser->confsize; i++)
535             {
536                 module_config_t *p_config = p_parser->p_config + i;
537                 /* Hack: required subcategory is stored in i_min */
538                 if( p_config->i_type == CONFIG_SUBCATEGORY &&
539                     p_config->value.i == p_item->min.i )
540                 {
541                     QCheckBox *cb =
542                         new QCheckBox( qfu( p_parser->psz_object_name ) );
543                     cb->setToolTip( qfu(p_parser->psz_longname) );
544                     modules.push_back( cb );
545                 }
546             }
547         }
548         else if( !strcmp( p_parser->psz_capability, p_item->psz_type ) )
549         {
550             QCheckBox *cb =
551                 new QCheckBox( qfu( p_parser->psz_object_name ) );
552             cb->setToolTip( qfu(p_parser->psz_longname) );
553             modules.push_back( cb );
554         }
555     }
556     vlc_list_release( p_list );
557     text->setToolTip( qfu(p_item->psz_longtext) );
558     if( groupBox )
559         groupBox->setToolTip( qfu(p_item->psz_longtext) );
560 }
561
562 QString ModuleListConfigControl::getValue()
563 {
564     return text->text();
565 }
566
567 void ModuleListConfigControl::hide()
568 {
569     for( QVector<QCheckBox*>::iterator it = modules.begin();
570          it != modules.end(); it++ )
571     {
572         (*it)->hide();
573     }
574     groupBox->hide();
575 }
576
577 void ModuleListConfigControl::show()
578 {
579     for( QVector<QCheckBox*>::iterator it = modules.begin();
580          it != modules.end(); it++ )
581     {
582         (*it)->show();
583     }
584     groupBox->show();
585 }
586
587
588 void ModuleListConfigControl::wakeUp_TheUserJustClickedOnSomething( int value )
589 {
590     text->clear();
591     for( QVector<QCheckBox*>::iterator it = modules.begin();
592          it != modules.end(); it++ )
593     {
594     }
595 }
596
597 /**************************************************************************
598  * Integer-based controls
599  *************************************************************************/
600
601 /*********** Integer **************/
602 IntegerConfigControl::IntegerConfigControl( vlc_object_t *_p_this,
603                                             module_config_t *_p_item,
604                                             QWidget *_parent, QGridLayout *l,
605                                             int &line ) :
606                            VIntConfigControl( _p_this, _p_item, _parent )
607 {
608     label = new QLabel( qfu(p_item->psz_text) );
609     spin = new QSpinBox; spin->setMinimumWidth( 80 );
610     spin->setAlignment( Qt::AlignRight );
611     spin->setMaximumWidth( 90 );
612     finish();
613
614     if( !l )
615     {
616         QHBoxLayout *layout = new QHBoxLayout();
617         layout->addWidget( label, 0 ); layout->addWidget( spin, 1 );
618         widget->setLayout( layout );
619     }
620     else
621     {
622         l->addWidget( label, line, 0 );
623         l->addWidget( spin, line, 1, Qt::AlignRight );
624     }
625 }
626 IntegerConfigControl::IntegerConfigControl( vlc_object_t *_p_this,
627                                             module_config_t *_p_item,
628                                             QLabel *_label, QSpinBox *_spin ) :
629                                       VIntConfigControl( _p_this, _p_item )
630 {
631     spin = _spin;
632     label = _label;
633     finish();
634 }
635
636 void IntegerConfigControl::finish()
637 {
638     spin->setMaximum( 2000000000 );
639     spin->setMinimum( -2000000000 );
640     spin->setValue( p_item->value.i );
641     spin->setToolTip( qfu(p_item->psz_longtext) );
642     if( label )
643         label->setToolTip( qfu(p_item->psz_longtext) );
644 }
645
646 int IntegerConfigControl::getValue()
647 {
648     return spin->value();
649 }
650
651 /********* Integer range **********/
652 IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t *_p_this,
653                                             module_config_t *_p_item,
654                                             QWidget *_parent, QGridLayout *l,
655                                             int &line ) :
656             IntegerConfigControl( _p_this, _p_item, _parent, l, line )
657 {
658     finish();
659 }
660
661 IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t *_p_this,
662                                             module_config_t *_p_item,
663                                             QLabel *_label, QSpinBox *_spin ) :
664             IntegerConfigControl( _p_this, _p_item, _label, _spin )
665 {
666     finish();
667 }
668
669 void IntegerRangeConfigControl::finish()
670 {
671     spin->setMaximum( p_item->max.i );
672     spin->setMinimum( p_item->min.i );
673 }
674
675 IntegerRangeSliderConfigControl::IntegerRangeSliderConfigControl(
676                                             vlc_object_t *_p_this,
677                                             module_config_t *_p_item,
678                                             QLabel *_label, QSlider *_slider ):
679                     VIntConfigControl( _p_this, _p_item )
680 {
681     slider = _slider;
682     label = _label;
683     slider->setMaximum( p_item->max.i );
684     slider->setMinimum( p_item->min.i );
685     slider->setValue( p_item->value.i );
686     slider->setToolTip( qfu(p_item->psz_longtext) );
687     if( label )
688         label->setToolTip( qfu(p_item->psz_longtext) );
689 }
690
691 int IntegerRangeSliderConfigControl::getValue()
692 {
693         return slider->value();
694 }
695
696
697 /********* Integer / choice list **********/
698 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *_p_this,
699                module_config_t *_p_item, QWidget *_parent, bool bycat,
700                QGridLayout *l, int &line) :
701                VIntConfigControl( _p_this, _p_item, _parent )
702 {
703     label = new QLabel( qfu(p_item->psz_text) );
704     combo = new QComboBox();
705     finish( bycat );
706     if( !l )
707     {
708         QHBoxLayout *layout = new QHBoxLayout();
709         layout->addWidget( label ); layout->addWidget( combo );
710         widget->setLayout( layout );
711     }
712     else
713     {
714         l->addWidget( label, line, 0 );
715         l->addWidget( combo, line, 1, Qt::AlignRight );
716     }
717 }
718 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *_p_this,
719                 module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
720                 bool bycat ) : VIntConfigControl( _p_this, _p_item )
721 {
722     combo = _combo;
723     label = _label;
724     finish( bycat );
725 }
726
727 void IntegerListConfigControl::finish( bool bycat )
728 {
729     combo->setEditable( false );
730
731     for( int i_index = 0; i_index < p_item->i_list; i_index++ )
732     {
733         combo->addItem( qfu(p_item->ppsz_list_text[i_index] ),
734                         QVariant( p_item->pi_list[i_index] ) );
735         if( p_item->value.i == p_item->pi_list[i_index] )
736             combo->setCurrentIndex( combo->count() - 1 );
737     }
738     combo->setToolTip( qfu(p_item->psz_longtext) );
739     if( label )
740         label->setToolTip( qfu(p_item->psz_longtext) );
741 }
742
743 int IntegerListConfigControl::getValue()
744 {
745     return combo->itemData( combo->currentIndex() ).toInt();
746 }
747
748 /*********** Boolean **************/
749 BoolConfigControl::BoolConfigControl( vlc_object_t *_p_this,
750                                       module_config_t *_p_item,
751                                       QWidget *_parent, QGridLayout *l,
752                                       int &line ) :
753                     VIntConfigControl( _p_this, _p_item, _parent )
754 {
755     checkbox = new QCheckBox( qfu(p_item->psz_text) );
756     finish();
757
758     if( !l )
759     {
760         QHBoxLayout *layout = new QHBoxLayout();
761         layout->addWidget( checkbox, 0 );
762         widget->setLayout( layout );
763     }
764     else
765     {
766         l->addWidget( checkbox, line, 0 );
767     }
768 }
769 BoolConfigControl::BoolConfigControl( vlc_object_t *_p_this,
770                                       module_config_t *_p_item,
771                                       QLabel *_label,
772                                       QCheckBox *_checkbox,
773                                       bool bycat ) :
774                    VIntConfigControl( _p_this, _p_item )
775 {
776     checkbox = _checkbox;
777     finish();
778 }
779
780 void BoolConfigControl::finish()
781 {
782     checkbox->setCheckState( p_item->value.i == VLC_TRUE ? Qt::Checked
783                                                         : Qt::Unchecked );
784     checkbox->setToolTip( qfu(p_item->psz_longtext) );
785 }
786
787 int BoolConfigControl::getValue()
788 {
789     return checkbox->checkState() == Qt::Checked ? VLC_TRUE : VLC_FALSE;
790 }
791
792 /**************************************************************************
793  * Float-based controls
794  *************************************************************************/
795
796 /*********** Float **************/
797 FloatConfigControl::FloatConfigControl( vlc_object_t *_p_this,
798                                         module_config_t *_p_item,
799                                         QWidget *_parent, QGridLayout *l,
800                                         int &line ) :
801                     VFloatConfigControl( _p_this, _p_item, _parent )
802 {
803     label = new QLabel( qfu(p_item->psz_text) );
804     spin = new QDoubleSpinBox; spin->setMinimumWidth( 80 );
805     spin->setMaximumWidth( 90 );
806     spin->setAlignment( Qt::AlignRight );
807     finish();
808
809     if( !l )
810     {
811         QHBoxLayout *layout = new QHBoxLayout();
812         layout->addWidget( label, 0 ); layout->addWidget( spin, 1 );
813         widget->setLayout( layout );
814     }
815     else
816     {
817         l->addWidget( label, line, 0 );
818         l->addWidget( spin, line, 1, Qt::AlignRight );
819     }
820 }
821
822 FloatConfigControl::FloatConfigControl( vlc_object_t *_p_this,
823                                         module_config_t *_p_item,
824                                         QLabel *_label,
825                                         QDoubleSpinBox *_spin ) :
826                     VFloatConfigControl( _p_this, _p_item )
827 {
828     spin = _spin;
829     label = _label;
830     finish();
831 }
832
833 void FloatConfigControl::finish()
834 {
835     spin->setMaximum( 2000000000. );
836     spin->setMinimum( -2000000000. );
837     spin->setSingleStep( 0.1 );
838     spin->setValue( (double)p_item->value.f );
839     spin->setToolTip( qfu(p_item->psz_longtext) );
840     if( label )
841         label->setToolTip( qfu(p_item->psz_longtext) );
842 }
843
844 float FloatConfigControl::getValue()
845 {
846     return (float)spin->value();
847 }
848
849 /*********** Float with range **************/
850 FloatRangeConfigControl::FloatRangeConfigControl( vlc_object_t *_p_this,
851                                         module_config_t *_p_item,
852                                         QWidget *_parent, QGridLayout *l,
853                                         int &line ) :
854                 FloatConfigControl( _p_this, _p_item, _parent, l, line )
855 {
856     finish();
857 }
858
859 FloatRangeConfigControl::FloatRangeConfigControl( vlc_object_t *_p_this,
860                                         module_config_t *_p_item,
861                                         QLabel *_label,
862                                         QDoubleSpinBox *_spin ) :
863                 FloatConfigControl( _p_this, _p_item, _label, _spin )
864 {
865     finish();
866 }
867
868 void FloatRangeConfigControl::finish()
869 {
870     spin->setMaximum( (double)p_item->max.f );
871     spin->setMinimum( (double)p_item->min.f );
872 }
873
874
875 /**********************************************************************
876  * Key selector widget
877  **********************************************************************/
878 KeySelectorControl::KeySelectorControl( vlc_object_t *_p_this,
879                                       module_config_t *_p_item,
880                                       QWidget *_parent, QGridLayout *l,
881                                       int &line ) :
882                                 ConfigControl( _p_this, _p_item, _parent )
883
884 {
885     label = new QLabel( qtr("Select an action to change the associated hotkey") );
886     table = new QTreeWidget( 0 );
887     finish();
888
889     if( !l )
890     {
891         QVBoxLayout *layout = new QVBoxLayout();
892         layout->addWidget( label, 0 ); layout->addWidget( table, 1 );
893         widget->setLayout( layout );
894     }
895     else
896     {
897         l->addWidget( label, line, 0, 1, 2 );
898         l->addWidget( table, line+1, 0, 1,2 );
899     }
900 }
901
902 void KeySelectorControl::finish()
903 {
904     if( label )
905         label->setToolTip( qfu(p_item->psz_longtext) );
906
907     /* Fill the table */
908     table->setColumnCount( 2 );
909     table->setAlternatingRowColors( true );
910
911     module_t *p_main = config_FindModule( p_this, "main" );
912     assert( p_main );
913
914     for (size_t i = 0; i < p_main->confsize; i++)
915     {
916         module_config_t *p_item = p_main->p_config + i;
917
918         if( p_item->i_type & CONFIG_ITEM && p_item->psz_name &&
919             strstr( p_item->psz_name , "key-" ) )
920         {
921             QTreeWidgetItem *treeItem = new QTreeWidgetItem();
922             treeItem->setText( 0, qfu( p_item->psz_text ) );
923             treeItem->setText( 1, VLCKeyToString( p_item->value.i ) );
924             treeItem->setData( 0, Qt::UserRole,
925                                   QVariant::fromValue( (void*)p_item ) );
926             values += p_item;
927             table->addTopLevelItem( treeItem );
928         }
929     }
930     table->resizeColumnToContents( 0 );
931
932     CONNECT( table, itemDoubleClicked( QTreeWidgetItem *, int ),
933              this, selectKey( QTreeWidgetItem * ) );
934 }
935
936 void KeySelectorControl::selectKey( QTreeWidgetItem *keyItem )
937 {
938    module_config_t *p_keyItem = static_cast<module_config_t*>
939                           (keyItem->data( 0, Qt::UserRole ).value<void*>());
940
941     KeyInputDialog *d = new KeyInputDialog( values, p_keyItem->psz_text );
942     d->exec();
943     if( d->result() == QDialog::Accepted )
944     {
945         p_keyItem->value.i = d->keyValue;
946         if( d->conflicts )
947         {
948             for( int i = 0; i < table->topLevelItemCount() ; i++ )
949             {
950                 QTreeWidgetItem *it = table->topLevelItem(i);
951                 module_config_t *p_item = static_cast<module_config_t*>
952                               (it->data( 0, Qt::UserRole ).value<void*>());
953                 it->setText( 1, VLCKeyToString( p_item->value.i ) );
954             }
955         }
956         else
957             keyItem->setText( 1, VLCKeyToString( p_keyItem->value.i ) );
958     }
959     delete d;
960 }
961
962 void KeySelectorControl::doApply()
963 {
964     foreach( module_config_t *p_current, values )
965     {
966         config_PutInt( p_this, p_current->psz_name, p_current->value.i );
967     }
968 }
969
970 KeyInputDialog::KeyInputDialog( QList<module_config_t*>& _values,
971                                 const char * _keyToChange ) :
972                                                 QDialog(0), keyValue(0)
973 {
974     setModal( true );
975     values = _values;
976     conflicts = false;
977     keyToChange = _keyToChange;
978     setWindowTitle( qtr( "Hotkey for " ) + qfu( keyToChange)  );
979
980     QVBoxLayout *l = new QVBoxLayout( this );
981     selected = new QLabel( qtr("Press the new keys for ")  + qfu(keyToChange) );
982     warning = new QLabel();
983     l->addWidget( selected , Qt::AlignCenter );
984     l->addWidget( warning, Qt::AlignCenter );
985
986     QHBoxLayout *l2 = new QHBoxLayout();
987     QPushButton *ok = new QPushButton( qtr("OK") );
988     l2->addWidget( ok );
989     QPushButton *cancel = new QPushButton( qtr("Cancel") );
990     l2->addWidget( cancel );
991
992     BUTTONACT( ok, accept() );
993     BUTTONACT( cancel, reject() );
994
995     l->addLayout( l2 );
996 }
997
998 void KeyInputDialog::checkForConflicts( int i_vlckey )
999 {
1000     conflicts = false;
1001     module_config_t *p_current = NULL;
1002     foreach( p_current, values )
1003     {
1004         if( p_current->value.i == i_vlckey && strcmp( p_current->psz_text,
1005                                                     keyToChange ) )
1006         {
1007             p_current->value.i = 0;
1008             conflicts = true;
1009             break;
1010         }
1011     }
1012     if( conflicts )
1013     {
1014         warning->setText(
1015           qtr("Warning: the  key is already assigned to \"") +
1016           QString( p_current->psz_text ) + "\"" );
1017     }
1018     else warning->setText( "" );
1019 }
1020
1021 void KeyInputDialog::keyPressEvent( QKeyEvent *e )
1022 {
1023     if( e->key() == Qt::Key_Tab ) return;
1024     int i_vlck = qtEventToVLCKey( e );
1025     selected->setText( VLCKeyToString( i_vlck ) );
1026     checkForConflicts( i_vlck );
1027     keyValue = i_vlck;
1028 }
1029
1030 void KeyInputDialog::wheelEvent( QWheelEvent *e )
1031 {
1032     int i_vlck = qtWheelEventToVLCKey( e );
1033     selected->setText( VLCKeyToString( i_vlck ) );
1034     checkForConflicts( i_vlck );
1035     keyValue = i_vlck;
1036 }