preferences_widgets.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:47k
源码类别:

midi

开发平台:

Unix_Linux

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