3c9c084965c8cb3073504afcd216f0df4ef1aebe
[vlc.git] / modules / gui / kde / preferences.cpp
1 /*****************************************************************************
2  * preferences.cpp: preferences window for the kde gui
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: preferences.cpp,v 1.16 2003/05/05 14:58:45 sigmunau Exp $
6  *
7  * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no> Mon Aug 12 2002
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23 #include <kdialogbase.h>
24 #include <qmap.h>
25 #include <qcheckbox.h>
26 #include <qframe.h>
27 #include <qgroupbox.h>
28 #include <qlayout.h>
29 #include <qlabel.h>
30 #include <qlistview.h>
31 #include <qnamespace.h>
32 #include <qobjectlist.h>
33 #include <qslider.h>
34 #include <qspinbox.h>
35 #include <qtooltip.h>
36 #include <qvbox.h>
37
38 #include <kbuttonbox.h>
39 #include <klineedit.h>
40 #include <klocale.h>
41 #include <knuminput.h>
42 #include <kurlrequester.h>
43 #include <kcombobox.h>
44
45 #include "QConfigItem.h"
46 #include "pluginsbox.h"
47 #include "preferences.h"
48
49 /*
50   construct a new configuration window for the given module
51 */
52 KPreferences::KPreferences(intf_thread_t *p_intf, const char *psz_module_name,
53                            QWidget *parent, const QString &caption) :
54     KDialogBase ( TreeList, caption, Ok| Apply|Cancel|User1, Ok, parent,
55                   "vlc preferences", true, false, i18n("&Save") )
56 {
57     module_t *p_parser = NULL;
58     vlc_list_t *p_list;
59     module_config_t *p_item;
60     int i_index;
61     QVBox *category_table = NULL;
62     QString *category_label;
63
64     this->p_intf = p_intf;
65
66     /* List all modules */
67     p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
68
69     for( i_index = 0; i_index < p_list->i_count; i_index++ )
70     {
71         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
72         p_item = p_parser->p_config;
73         while( p_item && p_item->i_type != CONFIG_HINT_END )
74         {
75             switch( p_item->i_type )
76             {
77             case CONFIG_HINT_CATEGORY:
78                 /* force the content to the top of the page */
79                 if ( category_table )
80                 {
81                     QWidget *space = new QWidget( category_table );
82                     category_table->setStretchFactor( space, 10 );
83                     category_table = NULL;
84                 }
85                 
86                 /*
87                  * Now we can start taking care of the new category
88                  */
89                 if( p_item->i_type == CONFIG_HINT_CATEGORY )
90                 {
91                     category_label = new QString( p_item->psz_text );
92                     QStringList path;
93                     if ( strcmp( p_parser->psz_object_name, "main" ) )
94                     {
95                         path += _( "Plugins" );
96                         path += p_parser->psz_capability;
97                         path += p_parser->psz_object_name;
98                     }
99                     path += *category_label;
100                     QFrame *page = addPage( path );
101                     QVBoxLayout *toplayout = new QVBoxLayout( page);
102                     QScrollView *sv = new QScrollView(page);
103                     sv->setResizePolicy(QScrollView::AutoOneFit);
104                     sv->setFrameStyle(QScrollView::NoFrame);
105                     toplayout->addWidget(sv);
106                     category_table = new QVBox(sv->viewport());
107                     sv->addChild(category_table);
108                     category_table->setSpacing(spacingHint());
109                 }
110
111                 break;
112
113             case CONFIG_ITEM_MODULE:
114
115             {
116                 vlc_mutex_lock( p_item->p_lock );
117                 KPluginsBox *item_frame =
118                     new KPluginsBox( p_intf, p_item->psz_text,
119                                      p_item->psz_value ? p_item->psz_value :"",
120                                      category_table,
121                                      spacingHint(),
122                                      this );
123                 QConfigItem *ci = new QConfigItem(this,
124                                                   p_item->psz_name,
125                                                   p_item->i_type,
126                                                   p_item->psz_value);
127                 connect(item_frame, SIGNAL(selectionChanged(const QString &)),
128                         ci, SLOT(setValue(const QString &)));
129
130
131                 /* build a list of available plugins */
132                 for( int i_index = 0; i_index < p_list->i_count; i_index++ )
133                 {
134                     module_t *p_parser = (module_t *)p_list->p_values[i_index].p_object ;
135
136                     if( !strcmp( p_parser->psz_capability,
137                                  p_item->psz_type ) )
138                     {
139                         new QListViewItem(item_frame->getListView(),
140                                           p_parser->psz_object_name,
141                                           p_parser->psz_longname);
142                     }
143                 }
144
145                 vlc_mutex_unlock( p_item->p_lock );
146             }
147             break;
148
149             case CONFIG_ITEM_STRING:
150             {
151                 QHBox *hb = new QHBox(category_table);
152                 hb->setSpacing(spacingHint());
153                 new QLabel(p_item->psz_text, hb);
154                 /* add input box with default value */
155                 vlc_mutex_lock( p_item->p_lock );
156                 QConfigItem *ci = new QConfigItem(this, p_item->psz_name,
157                                                   p_item->i_type,
158                                                   p_item->psz_value ?
159                                                   p_item->psz_value : "");
160                 if ( p_item->ppsz_list )
161                 {
162                     char **ppsz_list = p_item->ppsz_list;
163                     KComboBox *p_combobox = new KComboBox( true, hb );
164                     QToolTip::add(p_combobox, p_item->psz_longtext);
165                     connect(p_combobox, SIGNAL(activated ( const QString & )),
166                             ci, SLOT(setValue( const QString &)));
167                     while ( *ppsz_list )
168                     {
169                         p_combobox->insertItem( *ppsz_list );
170                         if ( !strcmp( *ppsz_list, p_item->psz_value ?
171                                                   p_item->psz_value : "" ) )
172                         {
173 #if KDE_VERSION_MAJOR >= 3
174                             p_combobox->setCurrentText( *ppsz_list );
175 #else
176                             p_combobox->setCurrentItem( p_combobox->count() );
177 #endif
178                         }
179                         ppsz_list++;
180                     }
181                 }
182                 else
183                 {
184                     KLineEdit *kl = new KLineEdit( p_item->psz_value ?
185                                                    p_item->psz_value : "", hb);
186                     connect(kl, SIGNAL(textChanged ( const QString & )),
187                             ci, SLOT(setValue( const QString &)));
188                     QToolTip::add(kl, p_item->psz_longtext);
189                     kl->setMaxLength(40);
190                 }
191
192                 vlc_mutex_unlock( p_item->p_lock );
193             }
194             break;
195
196             case CONFIG_ITEM_FILE:
197             case CONFIG_ITEM_DIRECTORY:
198             {
199                 QHBox *hb = new QHBox(category_table);
200                 hb->setSpacing(spacingHint());
201                 new QLabel(p_item->psz_text, hb);
202                 /* add input box with default value */
203                 vlc_mutex_lock( p_item->p_lock );
204
205 //            KLineEdit *kl = new KLineEdit( p_item->psz_value ?
206 //                                           p_item->psz_value : "", hb);
207                 QConfigItem *ci = new QConfigItem(this, p_item->psz_name,
208                                                   p_item->i_type,
209                                                   p_item->psz_value ?
210                                                   p_item->psz_value : "");
211 //            QPushButton *bbrowse = new QPushButton( _("Browse"), hb );
212                 KURLRequester *kfile = new KURLRequester( p_item->psz_value ?
213                                                           p_item->psz_value : "",
214                                                           hb );
215                 if ( p_item->i_type == CONFIG_ITEM_DIRECTORY )
216                 {
217                     kfile->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly);
218                 }
219                 connect(kfile, SIGNAL(textChanged ( const QString & )),
220                         ci, SLOT(setValue( const QString &)));
221                 QToolTip::add(kfile, p_item->psz_longtext);
222                 vlc_mutex_unlock( p_item->p_lock );
223             }
224             break;
225
226             case CONFIG_ITEM_INTEGER:
227                 /* add input box with default value */
228             {
229                 QHBox *hb = new QHBox(category_table);
230                 hb->setSpacing(spacingHint());
231                 new QLabel(p_item->psz_text, hb);
232                 QConfigItem *ci = new QConfigItem(this, p_item->psz_name,
233                                                   p_item->i_type,
234                                                   p_item->i_value);
235                 if ( p_item->i_min == 0 && p_item->i_max == 0 )
236                 {
237                     QSpinBox *item_adj = new QSpinBox(-1, 99999, 1, hb);
238                     item_adj->setValue( p_item->i_value );
239                     connect(item_adj, SIGNAL(valueChanged( int)),
240                             ci, SLOT(setValue(int)));
241                     QToolTip::add(item_adj, p_item->psz_longtext);
242                 }
243                 else
244                 {
245                     KIntNumInput *p_ii = new KIntNumInput( p_item->i_value, hb );
246                     p_ii->setRange( p_item->i_min, p_item->i_max, 1, true ); 
247                     connect( p_ii, SIGNAL( valueChanged( int ) ),
248                              ci, SLOT( setValue( int ) ) );
249                     QToolTip::add( p_ii, p_item->psz_longtext );
250                 }
251             }
252             break;
253
254             case CONFIG_ITEM_FLOAT:
255             {
256                 QHBox *hb = new QHBox(category_table);
257                 hb->setSpacing(spacingHint());
258                 new QLabel(p_item->psz_text, hb);
259                 KDoubleNumInput *kdi= new KDoubleNumInput(p_item->f_value, hb);
260                 if ( p_item->f_min == 0 && p_item->f_max == 0 )
261                 {
262                     kdi->setRange(-1, 99999, 0.01, false);
263                 }
264                 else
265                 {
266                     kdi->setRange( p_item->f_min, p_item->f_max, 0.01, true );
267                 }
268                 QConfigItem *ci = new QConfigItem(this, p_item->psz_name,
269                                                   p_item->i_type,
270                                                   p_item->f_value);
271                 connect(kdi, SIGNAL(valueChanged(double)),
272                         ci, SLOT(setValue(double)));
273                 QToolTip::add(kdi, p_item->psz_longtext);
274             }
275             break;
276
277             case CONFIG_ITEM_BOOL:
278
279                 /* add check button */
280             {
281                 QCheckBox *bool_checkbutton =
282                     new QCheckBox(QString(p_item->psz_text), category_table);
283                 QConfigItem *ci = new QConfigItem(this, p_item->psz_name,
284                                                   p_item->i_type,
285                                                   p_item->i_value);
286                 bool_checkbutton->setChecked(p_item->i_value);
287                 connect(bool_checkbutton, SIGNAL(stateChanged( int)),
288                         ci, SLOT(setValue(int)));
289                 QToolTip::add(bool_checkbutton, p_item->psz_longtext);
290
291             }
292             break;
293
294             }
295             
296             p_item++;
297         }
298     }
299     /* force the content to the top of the page, even on the last page */
300     if ( category_table )
301     {
302         QWidget *space = new QWidget( category_table );
303         category_table->setStretchFactor( space, 10 );
304         category_table = NULL;
305     }
306                 
307
308     vlc_list_release( p_list );
309
310     exec();
311 }
312
313 /*
314   empty destructor, qt takes care of this (I think)
315 */
316 KPreferences::~KPreferences()
317 {
318 }
319
320 /*
321   return true if the give module is configureable
322 */
323 bool KPreferences::isConfigureable(QString module)
324 {
325     module_t *p_parser;
326     vlc_list_t *p_list;
327     int i_index;
328
329     p_list = vlc_list_find( this->p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
330
331     for( i_index = 0; i_index < p_list->i_count; i_index++ )
332     {
333         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
334
335         if( !module.compare( p_parser->psz_object_name ) )
336         {
337             bool ret = p_parser->i_config_items != 0;
338             vlc_list_release( p_list );
339             return ret;
340         }
341     }
342
343     vlc_list_release( p_list );
344     return false;
345 }
346
347 /*
348   run when the Apply button is pressed, and by the methods for the ok
349   and save buttons
350 */
351 void KPreferences::slotApply()
352 {
353     QObjectList * l = queryList( "QConfigItem" );
354     QObjectListIt it( *l );             // iterate over the config items
355     QObject * obj;
356     while ( (obj=it.current()) != 0 ) {
357         ++it;
358         QConfigItem *p_config = (QConfigItem *)obj;
359         if ( p_config->changed() )
360         {
361             msg_Dbg( p_intf, const_cast<char *>(p_config->name()));
362             msg_Dbg( p_intf, "%d", p_config->getType());
363
364             switch( p_config->getType() ) {
365
366             case CONFIG_ITEM_DIRECTORY:
367             case CONFIG_ITEM_STRING:
368             case CONFIG_ITEM_FILE:
369             case CONFIG_ITEM_MODULE:
370                 if (p_config->sValue()) {
371                     config_PutPsz( p_intf, p_config->name(),
372                                    strdup(p_config->sValue().latin1()));
373                 }
374                 else {
375                     config_PutPsz( p_intf, p_config->name(), NULL );
376                 }
377                 break;
378             case CONFIG_ITEM_INTEGER:
379             case CONFIG_ITEM_BOOL:
380                 config_PutInt( p_intf, p_config->name(), p_config->iValue() );
381                 break;
382             case CONFIG_ITEM_FLOAT:
383                 config_PutFloat( p_intf, p_config->name(), p_config->fValue() );
384                 break;
385             }
386             p_config->resetChanged();
387         }
388     }
389     delete l;
390 }
391
392 /*
393   run when the Ok button is pressed
394 */
395 void KPreferences::slotOk()
396 {
397     slotApply();
398     accept();
399 }
400
401 /*
402   run when the save button is pressed
403 */
404 void KPreferences::slotUser1()
405 {
406     slotApply();
407     config_SaveConfigFile( p_intf, NULL );
408 }