]> git.sesse.net Git - vlc/blob - modules/gui/qt4/components/preferences_widgets.cpp
QT4: enable fontdialog for choosing freetype-font family
[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, 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
32  */
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36
37 #include "components/preferences_widgets.hpp"
38 #include "util/customwidgets.hpp"
39 #include "util/qt_dirs.hpp"
40 #include <vlc_keys.h>
41
42 #include <QString>
43 #include <QVariant>
44 #include <QGridLayout>
45 #include <QSlider>
46 #include <QFileDialog>
47 #include <QGroupBox>
48 #include <QTreeWidgetItem>
49 #include <QSignalMapper>
50 #include <QDialogButtonBox>
51
52 #define MINWIDTH_BOX 90
53 #define LAST_COLUMN 10
54
55 QString formatTooltip(const QString & tooltip)
56 {
57     QString formatted =
58     "<html><head><meta name=\"qrichtext\" content=\"1\" />"
59     "<style type=\"text/css\"> p, li { white-space: pre-wrap; } </style></head>"
60     "<body style=\" font-family:'Sans Serif'; "
61     "font-style:normal; text-decoration:none;\">"
62     "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; "
63     "margin-right:0px; -qt-block-indent:0; text-indent:0px;\">" +
64     tooltip +
65     "</p></body></html>";
66     return formatted;
67 }
68
69 ConfigControl *ConfigControl::createControl( vlc_object_t *p_this,
70                                              module_config_t *p_item,
71                                              QWidget *parent )
72 {
73     int i = 0;
74     return createControl( p_this, p_item, parent, NULL, i );
75 }
76
77 ConfigControl *ConfigControl::createControl( vlc_object_t *p_this,
78                                              module_config_t *p_item,
79                                              QWidget *parent,
80                                              QGridLayout *l, int &line )
81 {
82     ConfigControl *p_control = NULL;
83
84     switch( p_item->i_type )
85     {
86     case CONFIG_ITEM_MODULE:
87         p_control = new ModuleConfigControl( p_this, p_item, parent, false,
88                                              l, line );
89         break;
90     case CONFIG_ITEM_MODULE_CAT:
91         p_control = new ModuleConfigControl( p_this, p_item, parent, true,
92                                              l, line );
93         break;
94     case CONFIG_ITEM_MODULE_LIST:
95         p_control = new ModuleListConfigControl( p_this, p_item, parent, false,
96                                              l, line );
97         break;
98     case CONFIG_ITEM_MODULE_LIST_CAT:
99         p_control = new ModuleListConfigControl( p_this, p_item, parent, true,
100                                              l, line );
101         /* Special Hack for a bug in video-filter */
102         if( qobject_cast<ModuleListConfigControl *>( p_control )->groupBox == NULL )
103             return NULL;
104         break;
105     case CONFIG_ITEM_STRING:
106         if( !p_item->i_list )
107             p_control = new StringConfigControl( p_this, p_item, parent,
108                                                  l, line, false );
109         else
110             p_control = new StringListConfigControl( p_this, p_item,
111                                             parent, false, l, line );
112         break;
113     case CONFIG_ITEM_PASSWORD:
114         if( !p_item->i_list )
115             p_control = new StringConfigControl( p_this, p_item, parent,
116                                                  l, line, true );
117         else
118             p_control = new StringListConfigControl( p_this, p_item,
119                                             parent, true, l, line );
120         break;
121     case CONFIG_ITEM_INTEGER:
122         if( p_item->i_list )
123             p_control = new IntegerListConfigControl( p_this, p_item,
124                                             parent, false, l, line );
125         else if( p_item->min.i || p_item->max.i )
126             p_control = new IntegerRangeConfigControl( p_this, p_item, parent,
127                                                        l, line );
128         else
129             p_control = new IntegerConfigControl( p_this, p_item, parent,
130                                                   l, line );
131         break;
132     case CONFIG_ITEM_FILE:
133         p_control = new FileConfigControl( p_this, p_item, parent, l, line);
134         break;
135     case CONFIG_ITEM_DIRECTORY:
136         p_control = new DirectoryConfigControl( p_this, p_item, parent, l,
137                                                 line );
138         break;
139     case CONFIG_ITEM_FONT:
140         p_control = new FontConfigControl( p_this, p_item, parent, l,
141                                            line);
142         break;
143     case CONFIG_ITEM_KEY:
144         p_control = new KeySelectorControl( p_this, p_item, parent, l, line );
145         break;
146     case CONFIG_ITEM_BOOL:
147         p_control = new BoolConfigControl( p_this, p_item, parent, l, line );
148         break;
149     case CONFIG_ITEM_FLOAT:
150         if( p_item->min.f || p_item->max.f )
151             p_control = new FloatRangeConfigControl( p_this, p_item, parent,
152                                                      l, line );
153         else
154             p_control = new FloatConfigControl( p_this, p_item, parent,
155                                                   l, line );
156         break;
157     default:
158         break;
159     }
160     return p_control;
161 }
162
163 void ConfigControl::doApply( intf_thread_t *p_intf )
164 {
165     switch( getType() )
166     {
167         case CONFIG_ITEM_INTEGER:
168         case CONFIG_ITEM_BOOL:
169         {
170             VIntConfigControl *vicc = qobject_cast<VIntConfigControl *>(this);
171             assert( vicc );
172             config_PutInt( p_intf, vicc->getName(), vicc->getValue() );
173             break;
174         }
175         case CONFIG_ITEM_FLOAT:
176         {
177             VFloatConfigControl *vfcc =
178                                     qobject_cast<VFloatConfigControl *>(this);
179             assert( vfcc );
180             config_PutFloat( p_intf, vfcc->getName(), vfcc->getValue() );
181             break;
182         }
183         case CONFIG_ITEM_STRING:
184         {
185             VStringConfigControl *vscc =
186                             qobject_cast<VStringConfigControl *>(this);
187             assert( vscc );
188             config_PutPsz( p_intf, vscc->getName(), qtu( vscc->getValue() ) );
189             break;
190         }
191         case CONFIG_ITEM_KEY:
192         {
193             KeySelectorControl *ksc = qobject_cast<KeySelectorControl *>(this);
194             assert( ksc );
195             ksc->doApply();
196         }
197     }
198 }
199
200 /*******************************************************
201  * Simple widgets
202  *******************************************************/
203 InterfacePreviewWidget::InterfacePreviewWidget
204         ( QWidget *parent ) : QLabel( parent, 0 )
205 {
206     setGeometry( 0, 0, 128, 100 );
207     setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
208 }
209
210 void InterfacePreviewWidget::setPreview( int comboid )
211 {
212     /* Need to move resources references as soon as qt4.cpp
213        local defines has been moved somewhere else
214     */
215     const char * pixmaps[] = { ":/prefsmenu/sample_classic",
216                                ":/prefsmenu/sample_complete",
217                                ":/prefsmenu/sample_minimal" };
218     setPixmap( QPixmap( pixmaps[ comboid ] ) );
219 }
220
221
222
223 /**************************************************************************
224  * String-based controls
225  *************************************************************************/
226
227 /*********** String **************/
228 StringConfigControl::StringConfigControl( vlc_object_t *_p_this,
229                                           module_config_t *_p_item,
230                                           QWidget *_parent, QGridLayout *l,
231                                           int &line, bool pwd ) :
232                            VStringConfigControl( _p_this, _p_item, _parent )
233 {
234     label = new QLabel( qtr(p_item->psz_text) );
235     text = new QLineEdit( qfu(p_item->value.psz) );
236     if( pwd ) text->setEchoMode( QLineEdit::Password );
237     finish();
238
239     if( !l )
240     {
241         QHBoxLayout *layout = new QHBoxLayout();
242         layout->addWidget( label, 0 ); layout->insertSpacing( 1, 10 );
243         layout->addWidget( text, LAST_COLUMN );
244         widget->setLayout( layout );
245     }
246     else
247     {
248         l->addWidget( label, line, 0 );
249         l->setColumnMinimumWidth( 1, 10 );
250         l->addWidget( text, line, LAST_COLUMN );
251     }
252 }
253
254 StringConfigControl::StringConfigControl( vlc_object_t *_p_this,
255                                    module_config_t *_p_item,
256                                    QLabel *_label, QLineEdit *_text, bool pwd ):
257                            VStringConfigControl( _p_this, _p_item )
258 {
259     text = _text;
260     if( pwd ) text->setEchoMode( QLineEdit::Password );
261     label = _label;
262     finish( );
263 }
264
265 void StringConfigControl::finish()
266 {
267     text->setText( qfu(p_item->value.psz) );
268     text->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
269     if( label )
270     {
271         label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
272         label->setBuddy( text );
273     }
274 }
275
276 /*********** File **************/
277 FileConfigControl::FileConfigControl( vlc_object_t *_p_this,
278                                           module_config_t *_p_item,
279                                           QWidget *_parent, QGridLayout *l,
280                                           int &line ) :
281                            VStringConfigControl( _p_this, _p_item, _parent )
282 {
283     label = new QLabel( qtr(p_item->psz_text) );
284     text = new QLineEdit( qfu(p_item->value.psz) );
285     browse = new QPushButton( qtr( "Browse..." ) );
286     QHBoxLayout *textAndButton = new QHBoxLayout();
287     textAndButton->setMargin( 0 );
288     textAndButton->addWidget( text, 2 );
289     textAndButton->addWidget( browse, 0 );
290
291     BUTTONACT( browse, updateField() );
292
293     finish();
294
295     if( !l )
296     {
297         QHBoxLayout *layout = new QHBoxLayout();
298         layout->addWidget( label, 0 );
299         layout->insertSpacing( 1, 10 );
300         layout->addLayout( textAndButton, LAST_COLUMN );
301         widget->setLayout( layout );
302     }
303     else
304     {
305         l->addWidget( label, line, 0 );
306         l->setColumnMinimumWidth( 1, 10 );
307         l->addLayout( textAndButton, line, LAST_COLUMN );
308     }
309 }
310
311
312 FileConfigControl::FileConfigControl( vlc_object_t *_p_this,
313                                    module_config_t *_p_item,
314                                    QLabel *_label, QLineEdit *_text,
315                                    QPushButton *_button ):
316                            VStringConfigControl( _p_this, _p_item )
317 {
318     browse = _button;
319     text = _text;
320     label = _label;
321
322     BUTTONACT( browse, updateField() );
323
324     finish( );
325 }
326
327 void FileConfigControl::updateField()
328 {
329     QString file = QFileDialog::getOpenFileName( NULL,
330                   qtr( "Select File" ), qfu( config_GetHomeDir() ) );
331     if( file.isNull() ) return;
332     text->setText( toNativeSeparators( file ) );
333 }
334
335 void FileConfigControl::finish()
336 {
337     text->setText( qfu(p_item->value.psz) );
338     text->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
339     if( label )
340     {
341         label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
342         label->setBuddy( text );
343     }
344 }
345
346 /********* String / Directory **********/
347 DirectoryConfigControl::DirectoryConfigControl( vlc_object_t *_p_this,
348                         module_config_t *_p_item, QWidget *_p_widget,
349                         QGridLayout *_p_layout, int& _int ) :
350      FileConfigControl( _p_this, _p_item, _p_widget, _p_layout, _int )
351 {}
352
353 DirectoryConfigControl::DirectoryConfigControl( vlc_object_t *_p_this,
354                         module_config_t *_p_item, QLabel *_p_label,
355                         QLineEdit *_p_line, QPushButton *_p_button ):
356      FileConfigControl( _p_this, _p_item, _p_label, _p_line, _p_button)
357 {}
358
359 void DirectoryConfigControl::updateField()
360 {
361     QString dir = QFileDialog::getExistingDirectory( NULL,
362                       qtr( "Select Directory" ),
363                       text->text().isEmpty() ?
364                         qfu( config_GetHomeDir() ) : text->text(),
365                   QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks );
366
367     if( dir.isNull() ) return;
368     text->setText( toNativeSepNoSlash( dir ) );
369 }
370
371 #include <QFontDialog>
372
373 /********* String / Font **********/
374 FontConfigControl::FontConfigControl( vlc_object_t *_p_this,
375                         module_config_t *_p_item, QWidget *_p_widget,
376                         QGridLayout *_p_layout, int& _int) :
377      FileConfigControl( _p_this, _p_item, _p_widget, _p_layout, _int)
378 {}
379
380 FontConfigControl::FontConfigControl( vlc_object_t *_p_this,
381                         module_config_t *_p_item, QLabel *_p_label,
382                         QLineEdit *_p_line, QPushButton *_p_button):
383      FileConfigControl( _p_this, _p_item, _p_label, _p_line, _p_button)
384 {}
385
386 void FontConfigControl::updateField()
387 {
388     bool ok;
389     QFont font = QFontDialog::getFont( &ok, QFont( text->text() ), NULL );
390     if( !ok ) return;
391     text->setText( font.family() );
392 }
393
394 /********* String / choice list **********/
395 StringListConfigControl::StringListConfigControl( vlc_object_t *_p_this,
396                module_config_t *_p_item, QWidget *_parent, bool bycat,
397                QGridLayout *l, int &line) :
398                VStringConfigControl( _p_this, _p_item, _parent )
399 {
400     label = new QLabel( qtr(p_item->psz_text) );
401     combo = new QComboBox();
402     combo->setMinimumWidth( MINWIDTH_BOX );
403     combo->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
404
405     module_config_t *p_module_config = config_FindConfig( p_this, p_item->psz_name );
406     if(p_module_config && p_module_config->pf_update_list)
407     {
408        vlc_value_t val;
409        val.psz_string = strdup(p_module_config->value.psz);
410
411        p_module_config->pf_update_list(p_this, p_item->psz_name, val, val, NULL);
412
413        // assume in any case that dirty was set to true
414        // because lazy programmes will use the same callback for
415        // this, like the one behind the refresh push button?
416        p_module_config->b_dirty = false;
417
418        free( val.psz_string );
419     }
420
421     finish( p_module_config, bycat );
422     if( !l )
423     {
424         l = new QGridLayout();
425         l->addWidget( label, 0, 0 ); l->addWidget( combo, 0, LAST_COLUMN );
426         widget->setLayout( l );
427     }
428     else
429     {
430         l->addWidget( label, line, 0 );
431         l->addWidget( combo, line, LAST_COLUMN, Qt::AlignRight );
432     }
433
434     if( p_item->i_action )
435     {
436         QSignalMapper *signalMapper = new QSignalMapper(this);
437
438         /* Some stringLists like Capture listings have action associated */
439         for( int i = 0; i < p_item->i_action; i++ )
440         {
441             QPushButton *button =
442                 new QPushButton( qfu( p_item->ppsz_action_text[i] ));
443             CONNECT( button, clicked(), signalMapper, map() );
444             signalMapper->setMapping( button, i );
445             l->addWidget( button, line, LAST_COLUMN - p_item->i_action + i,
446                     Qt::AlignRight );
447         }
448         CONNECT( signalMapper, mapped( int ),
449                 this, actionRequested( int ) );
450     }
451 }
452
453 void StringListConfigControl::actionRequested( int i_action )
454 {
455     /* Supplementary check for boundaries */
456     if( i_action < 0 || i_action >= p_item->i_action ) return;
457
458     module_config_t *p_module_config = config_FindConfig( p_this, getName() );
459     if(!p_module_config) return;
460
461     vlc_value_t val;
462     val.psz_string = const_cast<char *>
463         qtu( (combo->itemData( combo->currentIndex() ).toString() ) );
464
465     p_module_config->ppf_action[i_action]( p_this, getName(), val, val, 0 );
466
467     if( p_module_config->b_dirty )
468     {
469         combo->clear();
470         finish( p_module_config, true );
471         p_module_config->b_dirty = false;
472     }
473 }
474 StringListConfigControl::StringListConfigControl( vlc_object_t *_p_this,
475                 module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
476                 bool bycat ) : VStringConfigControl( _p_this, _p_item )
477 {
478     combo = _combo;
479     label = _label;
480
481     module_config_t *p_module_config = config_FindConfig( p_this, getName() );
482
483     finish( p_module_config, bycat );
484 }
485
486 void StringListConfigControl::finish(module_config_t *p_module_config, bool bycat )
487 {
488     combo->setEditable( false );
489
490     if(!p_module_config) return;
491
492     for( int i_index = 0; i_index < p_module_config->i_list; i_index++ )
493     {
494         combo->addItem( qfu((p_module_config->ppsz_list_text &&
495                             p_module_config->ppsz_list_text[i_index])?
496                             p_module_config->ppsz_list_text[i_index] :
497                             p_module_config->ppsz_list[i_index] ),
498                    QVariant( qfu(p_module_config->ppsz_list[i_index] )) );
499         if( p_item->value.psz && !strcmp( p_module_config->value.psz,
500                                           p_module_config->ppsz_list[i_index] ) )
501             combo->setCurrentIndex( combo->count() - 1 );
502     }
503     combo->setToolTip( formatTooltip(qtr(p_module_config->psz_longtext)) );
504     if( label )
505     {
506         label->setToolTip( formatTooltip(qtr(p_module_config->psz_longtext)) );
507         label->setBuddy( combo );
508     }
509 }
510
511 QString StringListConfigControl::getValue()
512 {
513     return combo->itemData( combo->currentIndex() ).toString();
514 }
515
516 void setfillVLCConfigCombo( const char *configname, intf_thread_t *p_intf,
517                         QComboBox *combo )
518 {
519     module_config_t *p_config =
520                       config_FindConfig( VLC_OBJECT(p_intf), configname );
521     if( p_config )
522     {
523        if(p_config->pf_update_list)
524         {
525             vlc_value_t val;
526             val.i_int = p_config->value.i;
527             p_config->pf_update_list(VLC_OBJECT(p_intf), configname, val, val, NULL);
528             // assume in any case that dirty was set to true
529             // because lazy programmes will use the same callback for
530             // this, like the one behind the refresh push button?
531             p_config->b_dirty = false;
532         }
533
534         for ( int i_index = 0; i_index < p_config->i_list; i_index++ )
535         {
536             combo->addItem( qfu( p_config->ppsz_list_text[i_index] ),
537                     QVariant( p_config->pi_list[i_index] ) );
538             if( p_config->value.i == p_config->pi_list[i_index] )
539             {
540                 combo->setCurrentIndex( i_index );
541             }
542         }
543         combo->setToolTip( qfu( p_config->psz_longtext ) );
544     }
545 }
546
547 /********* Module **********/
548 ModuleConfigControl::ModuleConfigControl( vlc_object_t *_p_this,
549                module_config_t *_p_item, QWidget *_parent, bool bycat,
550                QGridLayout *l, int &line) :
551                VStringConfigControl( _p_this, _p_item, _parent )
552 {
553     label = new QLabel( qtr(p_item->psz_text) );
554     combo = new QComboBox();
555     combo->setMinimumWidth( MINWIDTH_BOX );
556     finish( bycat );
557     if( !l )
558     {
559         QHBoxLayout *layout = new QHBoxLayout();
560         layout->addWidget( label ); layout->addWidget( combo, LAST_COLUMN );
561         widget->setLayout( layout );
562     }
563     else
564     {
565         l->addWidget( label, line, 0 );
566         l->addWidget( combo, line, LAST_COLUMN, Qt::AlignRight );
567     }
568 }
569
570 ModuleConfigControl::ModuleConfigControl( vlc_object_t *_p_this,
571                 module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
572                 bool bycat ) : VStringConfigControl( _p_this, _p_item )
573 {
574     combo = _combo;
575     label = _label;
576     finish( bycat );
577 }
578
579 void ModuleConfigControl::finish( bool bycat )
580 {
581     module_t *p_parser;
582
583     combo->setEditable( false );
584
585     /* build a list of available modules */
586     module_t **p_list = module_list_get( NULL );
587     combo->addItem( qtr("Default") );
588     for( size_t i = 0; (p_parser = p_list[i]) != NULL; i++ )
589     {
590         if( bycat )
591         {
592             if( !strcmp( module_get_object( p_parser ), "main" ) ) continue;
593
594             unsigned confsize;
595             module_config_t *p_config;
596
597             p_config = module_config_get (p_parser, &confsize);
598              for (size_t i = 0; i < confsize; i++)
599             {
600                 /* Hack: required subcategory is stored in i_min */
601                 const module_config_t *p_cfg = p_config + i;
602                 if( p_cfg->i_type == CONFIG_SUBCATEGORY &&
603                     p_cfg->value.i == p_item->min.i )
604                     combo->addItem( qtr( module_GetLongName( p_parser )),
605                                     QVariant( module_get_object( p_parser ) ) );
606                 if( p_item->value.psz && !strcmp( p_item->value.psz,
607                                                   module_get_object( p_parser ) ) )
608                     combo->setCurrentIndex( combo->count() - 1 );
609             }
610             module_config_free (p_config);
611         }
612         else if( module_provides( p_parser, p_item->psz_type ) )
613         {
614             combo->addItem( qtr(module_GetLongName( p_parser ) ),
615                             QVariant( module_get_object( p_parser ) ) );
616             if( p_item->value.psz && !strcmp( p_item->value.psz,
617                                               module_get_object( p_parser ) ) )
618                 combo->setCurrentIndex( combo->count() - 1 );
619         }
620     }
621     module_list_free( p_list );
622     combo->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
623     if( label )
624     {
625         label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
626         label->setBuddy( combo );
627     }
628 }
629
630 QString ModuleConfigControl::getValue()
631 {
632     return combo->itemData( combo->currentIndex() ).toString();
633 }
634
635 /********* Module list **********/
636 ModuleListConfigControl::ModuleListConfigControl( vlc_object_t *_p_this,
637         module_config_t *_p_item, QWidget *_parent, bool bycat,
638         QGridLayout *l, int &line) :
639     VStringConfigControl( _p_this, _p_item, _parent )
640 {
641     groupBox = NULL;
642     /* Special Hack */
643     if( !p_item->psz_text ) return;
644
645     groupBox = new QGroupBox ( qtr(p_item->psz_text), _parent );
646     text = new QLineEdit;
647     QGridLayout *layoutGroupBox = new QGridLayout( groupBox );
648
649     finish( bycat );
650
651     int boxline = 0;
652     for( QVector<checkBoxListItem*>::iterator it = modules.begin();
653             it != modules.end(); it++ )
654     {
655         layoutGroupBox->addWidget( (*it)->checkBox, boxline++, 0 );
656     }
657     layoutGroupBox->addWidget( text, boxline, 0 );
658
659     if( !l )
660     {
661         QVBoxLayout *layout = new QVBoxLayout();
662         layout->addWidget( groupBox, line, 0 );
663         widget->setLayout( layout );
664     }
665     else
666     {
667         l->addWidget( groupBox, line, 0, 1, -1 );
668     }
669
670     text->setToolTip( formatTooltip( qtr( p_item->psz_longtext) ) );
671 }
672
673 ModuleListConfigControl::~ModuleListConfigControl()
674 {
675     for( QVector<checkBoxListItem*>::iterator it = modules.begin();
676             it != modules.end(); it++ )
677     {
678         delete *it;
679     }
680     delete groupBox;
681 }
682
683 #define CHECKBOX_LISTS \
684 { \
685        QCheckBox *cb = new QCheckBox( qtr( module_GetLongName( p_parser ) ) );\
686        checkBoxListItem *cbl = new checkBoxListItem; \
687 \
688        CONNECT( cb, stateChanged( int ), this, onUpdate() );\
689        cb->setToolTip( formatTooltip( qtr( module_get_help( p_parser ))));\
690        cbl->checkBox = cb; \
691 \
692        cbl->psz_module = strdup( module_get_object( p_parser ) ); \
693        modules.push_back( cbl ); \
694 \
695        if( p_item->value.psz && strstr( p_item->value.psz, cbl->psz_module ) ) \
696             cbl->checkBox->setChecked( true ); \
697 }
698
699
700 void ModuleListConfigControl::finish( bool bycat )
701 {
702     module_t *p_parser;
703
704     /* build a list of available modules */
705     module_t **p_list = module_list_get( NULL );
706     for( size_t i = 0; (p_parser = p_list[i]) != NULL; i++ )
707     {
708         if( bycat )
709         {
710             if( !strcmp( module_get_object( p_parser ), "main" ) ) continue;
711
712             unsigned confsize;
713             module_config_t *p_config = module_config_get (p_parser, &confsize);
714
715             for (size_t i = 0; i < confsize; i++)
716             {
717                 module_config_t *p_cfg = p_config + i;
718                 /* Hack: required subcategory is stored in i_min */
719                 if( p_cfg->i_type == CONFIG_SUBCATEGORY &&
720                         p_cfg->value.i == p_item->min.i )
721                 {
722                     CHECKBOX_LISTS;
723                 }
724             }
725             module_config_free (p_config);
726         }
727         else if( module_provides( p_parser, p_item->psz_type ) )
728         {
729             CHECKBOX_LISTS;
730         }
731     }
732     module_list_free( p_list );
733     text->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
734     assert( groupBox );
735     groupBox->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
736 }
737 #undef CHECKBOX_LISTS
738
739 QString ModuleListConfigControl::getValue()
740 {
741     assert( text );
742     return text->text();
743 }
744
745 void ModuleListConfigControl::hide()
746 {
747     for( QVector<checkBoxListItem*>::iterator it = modules.begin();
748          it != modules.end(); it++ )
749     {
750         (*it)->checkBox->hide();
751     }
752     groupBox->hide();
753 }
754
755 void ModuleListConfigControl::show()
756 {
757     for( QVector<checkBoxListItem*>::iterator it = modules.begin();
758          it != modules.end(); it++ )
759     {
760         (*it)->checkBox->show();
761     }
762     groupBox->show();
763 }
764
765
766 void ModuleListConfigControl::onUpdate()
767 {
768     text->clear();
769     bool first = true;
770
771     for( QVector<checkBoxListItem*>::iterator it = modules.begin();
772          it != modules.end(); it++ )
773     {
774         if( (*it)->checkBox->isChecked() )
775         {
776             if( first )
777             {
778                 text->setText( text->text() + (*it)->psz_module );
779                 first = false;
780             }
781             else
782             {
783                 text->setText( text->text() + ":" + (*it)->psz_module );
784             }
785         }
786     }
787 }
788
789 /**************************************************************************
790  * Integer-based controls
791  *************************************************************************/
792
793 /*********** Integer **************/
794 IntegerConfigControl::IntegerConfigControl( vlc_object_t *_p_this,
795                                             module_config_t *_p_item,
796                                             QWidget *_parent, QGridLayout *l,
797                                             int &line ) :
798                            VIntConfigControl( _p_this, _p_item, _parent )
799 {
800     label = new QLabel( qtr(p_item->psz_text) );
801     spin = new QSpinBox; spin->setMinimumWidth( MINWIDTH_BOX );
802     spin->setAlignment( Qt::AlignRight );
803     spin->setMaximumWidth( MINWIDTH_BOX );
804     finish();
805
806     if( !l )
807     {
808         QHBoxLayout *layout = new QHBoxLayout();
809         layout->addWidget( label, 0 ); layout->addWidget( spin, LAST_COLUMN );
810         widget->setLayout( layout );
811     }
812     else
813     {
814         l->addWidget( label, line, 0 );
815         l->addWidget( spin, line, LAST_COLUMN, Qt::AlignRight );
816     }
817 }
818 IntegerConfigControl::IntegerConfigControl( vlc_object_t *_p_this,
819                                             module_config_t *_p_item,
820                                             QLabel *_label, QSpinBox *_spin ) :
821                                       VIntConfigControl( _p_this, _p_item )
822 {
823     spin = _spin;
824     label = _label;
825     finish();
826 }
827
828 void IntegerConfigControl::finish()
829 {
830     spin->setMaximum( 2000000000 );
831     spin->setMinimum( -2000000000 );
832     spin->setValue( p_item->value.i );
833     spin->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
834     if( label )
835     {
836         label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
837         label->setBuddy( spin );
838     }
839 }
840
841 int IntegerConfigControl::getValue()
842 {
843     return spin->value();
844 }
845
846 /********* Integer range **********/
847 IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t *_p_this,
848                                             module_config_t *_p_item,
849                                             QWidget *_parent, QGridLayout *l,
850                                             int &line ) :
851             IntegerConfigControl( _p_this, _p_item, _parent, l, line )
852 {
853     finish();
854 }
855
856 IntegerRangeConfigControl::IntegerRangeConfigControl( vlc_object_t *_p_this,
857                                             module_config_t *_p_item,
858                                             QLabel *_label, QSpinBox *_spin ) :
859             IntegerConfigControl( _p_this, _p_item, _label, _spin )
860 {
861     finish();
862 }
863
864 void IntegerRangeConfigControl::finish()
865 {
866     spin->setMaximum( p_item->max.i );
867     spin->setMinimum( p_item->min.i );
868 }
869
870 IntegerRangeSliderConfigControl::IntegerRangeSliderConfigControl(
871                                             vlc_object_t *_p_this,
872                                             module_config_t *_p_item,
873                                             QLabel *_label, QSlider *_slider ):
874                     VIntConfigControl( _p_this, _p_item )
875 {
876     slider = _slider;
877     label = _label;
878     slider->setMaximum( p_item->max.i );
879     slider->setMinimum( p_item->min.i );
880     slider->setValue( p_item->value.i );
881     slider->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
882     if( label )
883     {
884         label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
885         label->setBuddy( slider );
886     }
887 }
888
889 int IntegerRangeSliderConfigControl::getValue()
890 {
891         return slider->value();
892 }
893
894
895 /********* Integer / choice list **********/
896 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *_p_this,
897                module_config_t *_p_item, QWidget *_parent, bool bycat,
898                QGridLayout *l, int &line) :
899                VIntConfigControl( _p_this, _p_item, _parent )
900 {
901     label = new QLabel( qtr(p_item->psz_text) );
902     combo = new QComboBox();
903     combo->setMinimumWidth( MINWIDTH_BOX );
904
905     module_config_t *p_module_config = config_FindConfig( p_this, p_item->psz_name );
906     if(p_module_config && p_module_config->pf_update_list)
907     {
908        vlc_value_t val;
909        val.i_int = p_module_config->value.i;
910
911        p_module_config->pf_update_list(p_this, p_item->psz_name, val, val, NULL);
912
913        // assume in any case that dirty was set to true
914        // because lazy programmes will use the same callback for
915        // this, like the one behind the refresh push button?
916        p_module_config->b_dirty = false;
917     }
918
919
920     finish( p_module_config, bycat );
921     if( !l )
922     {
923         QHBoxLayout *layout = new QHBoxLayout();
924         layout->addWidget( label ); layout->addWidget( combo, LAST_COLUMN );
925         widget->setLayout( layout );
926     }
927     else
928     {
929         l->addWidget( label, line, 0 );
930         l->addWidget( combo, line, LAST_COLUMN, Qt::AlignRight );
931     }
932
933     if( p_item->i_action )
934     {
935         QSignalMapper *signalMapper = new QSignalMapper(this);
936
937         /* Some stringLists like Capture listings have action associated */
938         for( int i = 0; i < p_item->i_action; i++ )
939         {
940             QPushButton *button =
941                 new QPushButton( qfu( p_item->ppsz_action_text[i] ));
942             CONNECT( button, clicked(), signalMapper, map() );
943             signalMapper->setMapping( button, i );
944             l->addWidget( button, line, LAST_COLUMN - p_item->i_action + i,
945                     Qt::AlignRight );
946         }
947         CONNECT( signalMapper, mapped( int ),
948                 this, actionRequested( int ) );
949     }
950
951 }
952 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *_p_this,
953                 module_config_t *_p_item, QLabel *_label, QComboBox *_combo,
954                 bool bycat ) : VIntConfigControl( _p_this, _p_item )
955 {
956     combo = _combo;
957     label = _label;
958
959     module_config_t *p_module_config = config_FindConfig( p_this, getName() );
960
961     finish( p_module_config, bycat );
962 }
963
964 void IntegerListConfigControl::finish(module_config_t *p_module_config, bool bycat )
965 {
966     combo->setEditable( false );
967
968     if(!p_module_config) return;
969
970     for( int i_index = 0; i_index < p_module_config->i_list; i_index++ )
971     {
972         combo->addItem( qtr(p_module_config->ppsz_list_text[i_index] ),
973                         QVariant( p_module_config->pi_list[i_index] ) );
974         if( p_module_config->value.i == p_module_config->pi_list[i_index] )
975             combo->setCurrentIndex( combo->count() - 1 );
976     }
977     combo->setToolTip( formatTooltip(qtr(p_module_config->psz_longtext)) );
978     if( label )
979     {
980         label->setToolTip( formatTooltip(qtr(p_module_config->psz_longtext)) );
981         label->setBuddy( combo );
982     }
983 }
984
985 void IntegerListConfigControl::actionRequested( int i_action )
986 {
987     /* Supplementary check for boundaries */
988     if( i_action < 0 || i_action >= p_item->i_action ) return;
989
990     module_config_t *p_module_config = config_FindConfig( p_this, getName() );
991     if(!p_module_config) return;
992
993
994     vlc_value_t val;
995     val.i_int = combo->itemData( combo->currentIndex() ).toInt();
996
997     p_module_config->ppf_action[i_action]( p_this, getName(), val, val, 0 );
998
999     if( p_module_config->b_dirty )
1000     {
1001         combo->clear();
1002         finish( p_module_config, true );
1003         p_module_config->b_dirty = false;
1004     }
1005 }
1006
1007 int IntegerListConfigControl::getValue()
1008 {
1009     return combo->itemData( combo->currentIndex() ).toInt();
1010 }
1011
1012 /*********** Boolean **************/
1013 BoolConfigControl::BoolConfigControl( vlc_object_t *_p_this,
1014                                       module_config_t *_p_item,
1015                                       QWidget *_parent, QGridLayout *l,
1016                                       int &line ) :
1017                     VIntConfigControl( _p_this, _p_item, _parent )
1018 {
1019     checkbox = new QCheckBox( qtr(p_item->psz_text) );
1020     finish();
1021
1022     if( !l )
1023     {
1024         QHBoxLayout *layout = new QHBoxLayout();
1025         layout->addWidget( checkbox, 0 );
1026         widget->setLayout( layout );
1027     }
1028     else
1029     {
1030         l->addWidget( checkbox, line, 0 );
1031     }
1032 }
1033 BoolConfigControl::BoolConfigControl( vlc_object_t *_p_this,
1034                                       module_config_t *_p_item,
1035                                       QLabel *_label,
1036                                       QAbstractButton *_checkbox,
1037                                       bool bycat ) :
1038                    VIntConfigControl( _p_this, _p_item )
1039 {
1040     checkbox = _checkbox;
1041     VLC_UNUSED( _label );
1042     finish();
1043 }
1044
1045 void BoolConfigControl::finish()
1046 {
1047     checkbox->setChecked( p_item->value.i == true );
1048     checkbox->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
1049 }
1050
1051 int BoolConfigControl::getValue()
1052 {
1053     return checkbox->isChecked();
1054 }
1055
1056 /**************************************************************************
1057  * Float-based controls
1058  *************************************************************************/
1059
1060 /*********** Float **************/
1061 FloatConfigControl::FloatConfigControl( vlc_object_t *_p_this,
1062                                         module_config_t *_p_item,
1063                                         QWidget *_parent, QGridLayout *l,
1064                                         int &line ) :
1065                     VFloatConfigControl( _p_this, _p_item, _parent )
1066 {
1067     label = new QLabel( qtr(p_item->psz_text) );
1068     spin = new QDoubleSpinBox;
1069     spin->setMinimumWidth( MINWIDTH_BOX );
1070     spin->setMaximumWidth( MINWIDTH_BOX );
1071     spin->setAlignment( Qt::AlignRight );
1072     finish();
1073
1074     if( !l )
1075     {
1076         QHBoxLayout *layout = new QHBoxLayout();
1077         layout->addWidget( label, 0 ); layout->addWidget( spin, LAST_COLUMN );
1078         widget->setLayout( layout );
1079     }
1080     else
1081     {
1082         l->addWidget( label, line, 0 );
1083         l->addWidget( spin, line, LAST_COLUMN, Qt::AlignRight );
1084     }
1085 }
1086
1087 FloatConfigControl::FloatConfigControl( vlc_object_t *_p_this,
1088                                         module_config_t *_p_item,
1089                                         QLabel *_label,
1090                                         QDoubleSpinBox *_spin ) :
1091                     VFloatConfigControl( _p_this, _p_item )
1092 {
1093     spin = _spin;
1094     label = _label;
1095     finish();
1096 }
1097
1098 void FloatConfigControl::finish()
1099 {
1100     spin->setMaximum( 2000000000. );
1101     spin->setMinimum( -2000000000. );
1102     spin->setSingleStep( 0.1 );
1103     spin->setValue( (double)p_item->value.f );
1104     spin->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
1105     if( label )
1106     {
1107         label->setToolTip( formatTooltip(qtr(p_item->psz_longtext)) );
1108         label->setBuddy( spin );
1109     }
1110 }
1111
1112 float FloatConfigControl::getValue()
1113 {
1114     return (float)spin->value();
1115 }
1116
1117 /*********** Float with range **************/
1118 FloatRangeConfigControl::FloatRangeConfigControl( vlc_object_t *_p_this,
1119                                         module_config_t *_p_item,
1120                                         QWidget *_parent, QGridLayout *l,
1121                                         int &line ) :
1122                 FloatConfigControl( _p_this, _p_item, _parent, l, line )
1123 {
1124     finish();
1125 }
1126
1127 FloatRangeConfigControl::FloatRangeConfigControl( vlc_object_t *_p_this,
1128                                         module_config_t *_p_item,
1129                                         QLabel *_label,
1130                                         QDoubleSpinBox *_spin ) :
1131                 FloatConfigControl( _p_this, _p_item, _label, _spin )
1132 {
1133     finish();
1134 }
1135
1136 void FloatRangeConfigControl::finish()
1137 {
1138     spin->setMaximum( (double)p_item->max.f );
1139     spin->setMinimum( (double)p_item->min.f );
1140 }
1141
1142
1143 /**********************************************************************
1144  * Key selector widget
1145  **********************************************************************/
1146 KeySelectorControl::KeySelectorControl( vlc_object_t *_p_this,
1147                                       module_config_t *_p_item,
1148                                       QWidget *_parent, QGridLayout *l,
1149                                       int &line ) :
1150                                 ConfigControl( _p_this, _p_item, _parent )
1151
1152 {
1153     QWidget *keyContainer = new QWidget;
1154     QGridLayout *gLayout = new QGridLayout( keyContainer );
1155
1156     label = new QLabel(
1157             qtr( "Select an action to change the associated hotkey") );
1158
1159     QLabel *searchLabel = new QLabel( qtr( "Search" ) );
1160     actionSearch = new SearchLineEdit( keyContainer );
1161
1162     table = new QTreeWidget;
1163     table->setColumnCount(3);
1164     table->headerItem()->setText( 0, qtr( "Action" ) );
1165     table->headerItem()->setText( 1, qtr( "Hotkey" ) );
1166     table->headerItem()->setText( 2, qtr( "Global" ) );
1167     table->setAlternatingRowColors( true );
1168
1169     shortcutValue = new KeyShortcutEdit;
1170     shortcutValue->setReadOnly(true);
1171
1172     QPushButton *clearButton = new QPushButton( qtr( "Clear" ) );
1173     QPushButton *setButton = new QPushButton( qtr( "Set" ) );
1174     setButton->setDefault( true );
1175     finish();
1176
1177     gLayout->addWidget( label, 0, 0, 1, 4 );
1178     gLayout->addWidget( searchLabel, 1, 0, 1, 2 );
1179     gLayout->addWidget( actionSearch, 1, 2, 1, 2 );
1180     gLayout->addWidget( table, 2, 0, 1, 4 );
1181     gLayout->addWidget( clearButton, 3, 0, 1, 1 );
1182     gLayout->addWidget( shortcutValue, 3, 1, 1, 2 );
1183     gLayout->addWidget( setButton, 3, 3, 1, 1 );
1184
1185     l->addWidget( keyContainer, line, 0, 1, -1 );
1186
1187     CONNECT( clearButton, clicked(), shortcutValue, clear() );
1188     CONNECT( clearButton, clicked(), this, setTheKey() );
1189     BUTTONACT( setButton, setTheKey() );
1190     CONNECT( actionSearch, textChanged( const QString& ),
1191              this, filter( const QString& ) );
1192 }
1193
1194 void KeySelectorControl::finish()
1195 {
1196     if( label )
1197         label->setToolTip( formatTooltip( qtr( p_item->psz_longtext ) ) );
1198
1199     /* Fill the table */
1200
1201     /* Get the main Module */
1202     module_t *p_main = module_get_main();
1203     assert( p_main );
1204
1205     /* Access to the module_config_t */
1206     unsigned confsize;
1207     module_config_t *p_config;
1208
1209     p_config = module_config_get (p_main, &confsize);
1210
1211     for (size_t i = 0; i < confsize; i++)
1212     {
1213         module_config_t *p_item = p_config + i;
1214
1215         /* If we are a key option not empty */
1216         if( p_item->i_type & CONFIG_ITEM && p_item->psz_name
1217             && strstr( p_item->psz_name , "key-" )
1218             && !strstr( p_item->psz_name , "global-key" )
1219             && !EMPTY_STR( p_item->psz_text ) )
1220         {
1221             /*
1222                Each tree item has:
1223                 - QString text in column 0
1224                 - QString name in data of column 0
1225                 - KeyValue in String in column 1
1226                 - KeyValue in int in column 1
1227              */
1228             QTreeWidgetItem *treeItem = new QTreeWidgetItem();
1229             treeItem->setText( 0, qtr( p_item->psz_text ) );
1230             treeItem->setData( 0, Qt::UserRole,
1231                                QVariant( qfu( p_item->psz_name ) ) );
1232             treeItem->setText( 1, VLCKeyToString( p_item->value.i ) );
1233             treeItem->setData( 1, Qt::UserRole, QVariant( p_item->value.i ) );
1234             table->addTopLevelItem( treeItem );
1235             continue;
1236         }
1237
1238         if( p_item->i_type & CONFIG_ITEM && p_item->psz_name
1239                 && strstr( p_item->psz_name , "global-key" )
1240                 && !EMPTY_STR( p_item->psz_text ) )
1241         {
1242             QList<QTreeWidgetItem *> list =
1243                 table->findItems( qtr( p_item->psz_text ), Qt::MatchExactly );
1244             if( list.count() >= 1 )
1245             {
1246                 list[0]->setText( 2, VLCKeyToString( p_item->value.i ) );
1247                 list[0]->setData( 2, Qt::UserRole,
1248                                   QVariant( p_item->value.i ) );
1249             }
1250             if( list.count() >= 2 )
1251                 msg_Dbg( p_this, "This is probably wrong, %s", p_item->psz_text );
1252         }
1253     }
1254     module_config_free (p_config);
1255     module_release (p_main);
1256
1257     table->resizeColumnToContents( 0 );
1258
1259     CONNECT( table, itemDoubleClicked( QTreeWidgetItem *, int ),
1260              this, selectKey( QTreeWidgetItem *, int ) );
1261     CONNECT( table, itemSelectionChanged(),
1262              this, select1Key() );
1263
1264     CONNECT( shortcutValue, pressed(), this, selectKey() );
1265 }
1266
1267 void KeySelectorControl::filter( const QString &qs_search )
1268 {
1269     QList<QTreeWidgetItem *> resultList =
1270             table->findItems( qs_search, Qt::MatchContains, 0 );
1271     for( int i = 0; i < table->topLevelItemCount(); i++ )
1272     {
1273         table->topLevelItem( i )->setHidden(
1274                 !resultList.contains( table->topLevelItem( i ) ) );
1275     }
1276 }
1277
1278 /* Show the key selected from the table in the keySelector */
1279 void KeySelectorControl::select1Key()
1280 {
1281     QTreeWidgetItem *keyItem = table->currentItem();
1282     shortcutValue->setText( keyItem->text( 1 ) );
1283     shortcutValue->setValue( keyItem->data( 1, Qt::UserRole ).toInt() );
1284     shortcutValue->setGlobal( false );
1285 }
1286
1287 void KeySelectorControl::selectKey( QTreeWidgetItem *keyItem, int column )
1288 {
1289     /* This happens when triggered by ClickEater */
1290     if( keyItem == NULL ) keyItem = table->currentItem();
1291
1292     /* This can happen when nothing is selected on the treeView
1293        and the shortcutValue is clicked */
1294     if( !keyItem ) return;
1295
1296     /* If clicked on the first column, assuming user wants the normal hotkey */
1297     if( column == 0 ) column = 1;
1298
1299     bool b_global = ( column == 2 );
1300
1301     /* Launch a small dialog to ask for a new key */
1302     KeyInputDialog *d = new KeyInputDialog( table, keyItem->text( 0 ), widget, b_global );
1303     d->exec();
1304
1305     if( d->result() == QDialog::Accepted )
1306     {
1307         int newValue = d->keyValue;
1308         shortcutValue->setText( VLCKeyToString( newValue ) );
1309         shortcutValue->setValue( newValue );
1310         shortcutValue->setGlobal( b_global );
1311
1312         if( d->conflicts )
1313         {
1314             QTreeWidgetItem *it;
1315             for( int i = 0; i < table->topLevelItemCount() ; i++ )
1316             {
1317                 it = table->topLevelItem(i);
1318                 if( ( keyItem != it ) &&
1319                     ( it->data( b_global ? 2: 1, Qt::UserRole ).toInt() == newValue ) )
1320                 {
1321                     it->setData( b_global ? 2 : 1, Qt::UserRole, QVariant( -1 ) );
1322                     it->setText( b_global ? 2 : 1, qtr( "Unset" ) );
1323                 }
1324             }
1325             /* We already made an OK once. */
1326             setTheKey();
1327         }
1328     }
1329     delete d;
1330 }
1331
1332 void KeySelectorControl::setTheKey()
1333 {
1334     if( !table->currentItem() ) return;
1335     table->currentItem()->setText( shortcutValue->getGlobal() ? 2 : 1,
1336                                    shortcutValue->text() );
1337     table->currentItem()->setData( shortcutValue->getGlobal() ? 2 : 1,
1338                                    Qt::UserRole, shortcutValue->getValue() );
1339 }
1340
1341 void KeySelectorControl::doApply()
1342 {
1343     QTreeWidgetItem *it;
1344     for( int i = 0; i < table->topLevelItemCount() ; i++ )
1345     {
1346         it = table->topLevelItem(i);
1347         if( it->data( 1, Qt::UserRole ).toInt() >= 0 )
1348             config_PutInt( p_this,
1349                            qtu( it->data( 0, Qt::UserRole ).toString() ),
1350                            it->data( 1, Qt::UserRole ).toInt() );
1351         if( it->data( 2, Qt::UserRole ).toInt() >= 0 )
1352             config_PutInt( p_this,
1353                            qtu( "global-" + it->data( 0, Qt::UserRole ).toString() ),
1354                            it->data( 2, Qt::UserRole ).toInt() );
1355
1356     }
1357 }
1358
1359 /**
1360  * Class KeyInputDialog
1361  **/
1362 KeyInputDialog::KeyInputDialog( QTreeWidget *_table,
1363                                 const QString& keyToChange,
1364                                 QWidget *_parent,
1365                                 bool _b_global ) :
1366                                 QDialog( _parent ), keyValue(0), b_global( _b_global )
1367 {
1368     setModal( true );
1369     conflicts = false;
1370
1371     table = _table;
1372     setWindowTitle( b_global ? qtr( "Global" ): ""
1373                     + qtr( "Hotkey for " ) + keyToChange );
1374
1375     vLayout = new QVBoxLayout( this );
1376     selected = new QLabel( qtr( "Press the new keys for " ) + keyToChange );
1377     vLayout->addWidget( selected , Qt::AlignCenter );
1378
1379     warning = new QLabel;
1380     warning->hide();
1381     vLayout->insertWidget( 1, warning );
1382
1383     buttonBox = new QDialogButtonBox;
1384     QPushButton *ok = new QPushButton( qtr("OK") );
1385     QPushButton *cancel = new QPushButton( qtr("Cancel") );
1386     buttonBox->addButton( ok, QDialogButtonBox::AcceptRole );
1387     buttonBox->addButton( cancel, QDialogButtonBox::RejectRole );
1388     ok->setDefault( true );
1389
1390     vLayout->addWidget( buttonBox );
1391     buttonBox->hide();
1392
1393     CONNECT( buttonBox, accepted(), this, accept() );
1394     CONNECT( buttonBox, rejected(), this, reject() );
1395 }
1396
1397 void KeyInputDialog::checkForConflicts( int i_vlckey )
1398 {
1399      QList<QTreeWidgetItem *> conflictList =
1400          table->findItems( VLCKeyToString( i_vlckey ), Qt::MatchExactly,
1401                            b_global ? 2 : 1 );
1402
1403     if( conflictList.size() &&
1404         conflictList[0]->data( b_global ? 2 : 1, Qt::UserRole ).toInt() > 1 )
1405         /* Avoid 0 or -1 that are the "Unset" states */
1406     {
1407         warning->setText( qtr("Warning: the key is already assigned to \"") +
1408                           conflictList[0]->text( 0 ) + "\"" );
1409         warning->show();
1410         buttonBox->show();
1411
1412         conflicts = true;
1413     }
1414     else accept();
1415 }
1416
1417 void KeyInputDialog::keyPressEvent( QKeyEvent *e )
1418 {
1419     if( e->key() == Qt::Key_Tab ||
1420         e->key() == Qt::Key_Shift ||
1421         e->key() == Qt::Key_Control ||
1422         e->key() == Qt::Key_Meta ||
1423         e->key() == Qt::Key_Alt ||
1424         e->key() == Qt::Key_AltGr )
1425         return;
1426     int i_vlck = qtEventToVLCKey( e );
1427     selected->setText( qtr( "Key: " ) + VLCKeyToString( i_vlck ) );
1428     checkForConflicts( i_vlck );
1429     keyValue = i_vlck;
1430 }
1431
1432 void KeyInputDialog::wheelEvent( QWheelEvent *e )
1433 {
1434     int i_vlck = qtWheelEventToVLCKey( e );
1435     selected->setText( qtr( "Key: " ) + VLCKeyToString( i_vlck ) );
1436     checkForConflicts( i_vlck );
1437     keyValue = i_vlck;
1438 }
1439
1440 void KeyShortcutEdit::mousePressEvent( QMouseEvent *)
1441 {
1442     emit pressed();
1443 }
1444