e0076ee7d242aaa8107a1459acd0e89788c54808
[vlc.git] / modules / gui / qt4 / dialogs / preferences.cpp
1 /*****************************************************************************
2  * preferences.cpp : Preferences
3  *****************************************************************************
4  * Copyright (C) 2006-2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *          Jean-Baptiste Kempf <jb@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #include "dialogs/preferences.hpp"
26 #include "dialogs_provider.hpp"
27 #include "util/qvlcframe.hpp"
28
29 #include "components/complete_preferences.hpp"
30 #include "components/simple_preferences.hpp"
31
32 #include <QHBoxLayout>
33 #include <QGroupBox>
34 #include <QRadioButton>
35 #include <QVBoxLayout>
36 #include <QPushButton>
37 #include <QCheckBox>
38 #include <QScrollArea>
39 #include <QMessageBox>
40 #include <QDialogButtonBox>
41
42 PrefsDialog *PrefsDialog::instance = NULL;
43
44 PrefsDialog::PrefsDialog( intf_thread_t *_p_intf ) : QVLCFrame( _p_intf )
45 {
46     QGridLayout *main_layout = new QGridLayout( this );
47     setWindowTitle( qtr( "Preferences" ) );
48     resize( 750, 550 );
49
50     /* Create Panels */
51     tree_panel = new QWidget;
52     tree_panel_l = new QHBoxLayout;
53     tree_panel->setLayout( tree_panel_l );
54     main_panel = new QWidget;
55     main_panel_l = new QHBoxLayout;
56     main_panel->setLayout( main_panel_l );
57
58     /* Choice for types */
59     types = new QGroupBox( "Show settings" );
60     types->setAlignment( Qt::AlignHCenter );
61     QHBoxLayout *types_l = new QHBoxLayout;
62     types_l->setSpacing( 3 ); types_l->setMargin( 3 );
63     small = new QRadioButton( qtr("Basic"), types );
64     types_l->addWidget( small );
65     all = new QRadioButton( qtr("All"), types ); types_l->addWidget( all );
66     types->setLayout( types_l );
67     small->setChecked( true );
68
69     /* Tree and panel initialisations */
70     advanced_tree = NULL;
71     simple_tree = NULL;
72     current_simple_panel  = NULL;
73     advanced_panel = NULL;
74
75     /* Buttons */
76     QDialogButtonBox *buttonsBox = new QDialogButtonBox();
77     QPushButton *save = new QPushButton( qtr( "&Save" ) );
78     QPushButton *cancel = new QPushButton( qtr( "&Cancel" ) );
79     QPushButton *reset = new QPushButton( qtr( "&Reset Preferences" ) );
80
81     buttonsBox->addButton( save, QDialogButtonBox::AcceptRole );
82     buttonsBox->addButton( cancel, QDialogButtonBox::RejectRole );
83     buttonsBox->addButton( reset, QDialogButtonBox::ActionRole );
84
85     /* Layout  */
86     main_layout->addWidget( tree_panel, 0, 0, 3, 1 );
87     main_layout->addWidget( types, 3, 0, 2, 1 );
88     main_layout->addWidget( main_panel, 0, 1, 4, 1 );
89     main_layout->addWidget( buttonsBox, 4, 1, 1 ,2 );
90
91     main_layout->setColumnMinimumWidth( 0, 150 );
92     main_layout->setColumnStretch( 0, 1 );
93     main_layout->setColumnStretch( 1, 3 );
94
95     main_layout->setRowStretch( 2, 4 );
96
97     setLayout( main_layout );
98
99     /* Margins */
100     tree_panel_l->setMargin( 1 );
101     main_panel_l->setMargin( 3 );
102
103     for( int i = 0; i < SPrefsMax ; i++ ) simple_panels[i] = NULL;
104
105     if( config_GetInt( p_intf, "qt-advanced-pref" ) == 1 )
106         setAdvanced();
107     else
108         setSmall();
109
110     BUTTONACT( save, save() );
111     BUTTONACT( cancel, cancel() );
112     BUTTONACT( reset, reset() );
113
114     BUTTONACT( small, setSmall() );
115     BUTTONACT( all, setAdvanced() );
116 }
117
118 void PrefsDialog::setAdvanced()
119 {
120     /* We already have a simple TREE, and we just want to hide it */
121     if( simple_tree )
122         if( simple_tree->isVisible() ) simple_tree->hide();
123
124     /* If don't have already and advanced TREE, then create it */
125     if( !advanced_tree )
126     {
127         /* Creation */
128          advanced_tree = new PrefsTree( p_intf, tree_panel );
129         /* and connections */
130          CONNECT( advanced_tree,
131                   currentItemChanged( QTreeWidgetItem *, QTreeWidgetItem * ),
132                   this, changeAdvPanel( QTreeWidgetItem * ) );
133         tree_panel_l->addWidget( advanced_tree );
134     }
135
136     /* Show it */
137     advanced_tree->show();
138
139     /* Remove the simple current panel from the main panels*/
140     if( current_simple_panel )
141         if( current_simple_panel->isVisible() ) current_simple_panel->hide();
142
143     /* If no advanced Panel exist, create one, attach it and show it*/
144     if( !advanced_panel )
145     {
146         advanced_panel = new AdvPrefsPanel( main_panel );
147         main_panel_l->addWidget( advanced_panel );
148     }
149     advanced_panel->show();
150
151     all->setChecked( true );
152 }
153
154 void PrefsDialog::setSmall()
155 {
156     /* If an advanced TREE exists, remove and hide it */
157     if( advanced_tree )
158         if( advanced_tree->isVisible() ) advanced_tree->hide();
159
160     /* If no simple_tree, create one, connect it */
161     if( !simple_tree )
162     {
163          simple_tree = new SPrefsCatList( p_intf, tree_panel );
164          CONNECT( simple_tree,
165                   currentItemChanged( int ),
166                   this,  changeSimplePanel( int ) );
167         tree_panel_l->addWidget( simple_tree );
168     }
169
170     /*show it */
171     simple_tree->show();
172
173     /* If an Advanced PANEL exists, remove it */
174     if( advanced_panel )
175         if( advanced_panel->isVisible() ) advanced_panel->hide();
176
177     if( !current_simple_panel )
178     {
179         current_simple_panel =
180             new SPrefsPanel( p_intf, main_panel, SPrefsDefaultCat );
181         simple_panels[SPrefsDefaultCat] =  current_simple_panel;
182         main_panel_l->addWidget( current_simple_panel );
183     }
184
185     current_simple_panel->show();
186     small->setChecked( true );
187 }
188
189 /* Switching from on simple panel to another */
190 void PrefsDialog::changeSimplePanel( int number )
191 {
192     if( current_simple_panel )
193         if( current_simple_panel->isVisible() ) current_simple_panel->hide();
194
195     current_simple_panel = simple_panels[number];
196     if( !current_simple_panel )
197     {
198         current_simple_panel  = new SPrefsPanel( p_intf, main_panel, number );
199         simple_panels[number] = current_simple_panel;
200         main_panel_l->addWidget( current_simple_panel );
201     }
202
203     current_simple_panel->show();
204 }
205
206 /* Changing from one Advanced Panel to another */
207 void PrefsDialog::changeAdvPanel( QTreeWidgetItem *item )
208 {
209     PrefsItemData *data = item->data( 0, Qt::UserRole ).value<PrefsItemData*>();
210
211     if( advanced_panel )
212         if( advanced_panel->isVisible() ) advanced_panel->hide();
213
214     if( !data->panel )
215     {
216         data->panel = new AdvPrefsPanel( p_intf, main_panel , data );
217         main_panel_l->addWidget( data->panel );
218     }
219
220     advanced_panel = data->panel;
221     advanced_panel->show();
222 }
223
224 #if 0
225 /*Called from extended settings, is not used anymore, but could be useful one day*/
226 void PrefsDialog::showModulePrefs( char *psz_module )
227 {
228     setAdvanced();
229     all->setChecked( true );
230     for( int i_cat_index = 0 ; i_cat_index < advanced_tree->topLevelItemCount();
231          i_cat_index++ )
232     {
233         QTreeWidgetItem *cat_item = advanced_tree->topLevelItem( i_cat_index );
234         PrefsItemData *data = cat_item->data( 0, Qt::UserRole ).
235                                                    value<PrefsItemData *>();
236         for( int i_sc_index = 0; i_sc_index < cat_item->childCount();
237                                   i_sc_index++ )
238         {
239             QTreeWidgetItem *subcat_item = cat_item->child( i_sc_index );
240             PrefsItemData *sc_data = subcat_item->data(0, Qt::UserRole).
241                                                     value<PrefsItemData *>();
242             for( int i_module = 0; i_module < subcat_item->childCount();
243                                    i_module++ )
244             {
245                 QTreeWidgetItem *module_item = subcat_item->child( i_module );
246                 PrefsItemData *mod_data = module_item->data( 0, Qt::UserRole ).
247                                                     value<PrefsItemData *>();
248                 if( !strcmp( mod_data->psz_name, psz_module ) ) {
249                     advanced_tree->setCurrentItem( module_item );
250                 }
251             }
252         }
253     }
254     show();
255 }
256 #endif
257
258 /* Actual apply and save for the preferences */
259 void PrefsDialog::save()
260 {
261     if( small->isChecked() && simple_tree->isVisible() )
262     {
263         msg_Dbg( p_intf, "Saving the simple preferences" );
264         for( int i = 0 ; i< SPrefsMax; i++ ){
265             if( simple_panels[i] )simple_panels[i]->apply();
266         }
267     }
268     else if( all->isChecked() && advanced_tree->isVisible() )
269     {
270         msg_Dbg( p_intf, "Saving the advanced preferences" );
271         advanced_tree->applyAll();
272     }
273
274     /* Save to file */
275     config_SaveConfigFile( p_intf, NULL );
276
277     /* Delete the other panel in order to force its reload after clicking
278        on apply. In fact, if we don't do that, the preferences from the other
279        panels won't be accurate, so we would have to recreate the whole dialog,
280        and we don't want that.*/
281     if( small->isChecked() && advanced_panel )
282     {
283         /* Deleting only the active panel from the advanced config doesn't work
284            because the data records of PrefsItemData  contains still a
285            reference to it only cleanAll() is sure to remove all Panels! */
286         advanced_tree->cleanAll();
287         advanced_panel = NULL;
288     }
289     if( all->isChecked() && current_simple_panel )
290     {
291         for( int i = 0 ; i< SPrefsMax; i++ )
292         {
293             if( simple_panels[i] )
294             {
295                delete simple_panels[i];
296                simple_panels[i] = NULL;
297             }
298         }
299         current_simple_panel  = NULL;
300     }
301
302     hide();
303 }
304
305 /* Clean the preferences, dunno if it does something really */
306 void PrefsDialog::cancel()
307 {
308     if( small->isChecked() && simple_tree )
309     {
310         for( int i = 0 ; i< SPrefsMax; i++ )
311             if( simple_panels[i] ) simple_panels[i]->clean();
312     }
313     else if( all->isChecked() && advanced_tree )
314     {
315         advanced_tree->cleanAll();
316         advanced_panel = NULL;
317     }
318     hide();
319 }
320
321 /* Reset all the preferences, when you click the button */
322 void PrefsDialog::reset()
323 {
324     int ret = QMessageBox::question(
325                  this,
326                  qtr( "Reset Preferences" ),
327                  qtr( "This will reset your VLC media player preferences.\n"
328                       "Are you sure you want to continue?" ),
329                  QMessageBox::Ok | QMessageBox::Cancel,
330                  QMessageBox::Ok);
331
332     if( ret == QMessageBox::Ok )
333     {
334         config_ResetAll( p_intf );
335         config_SaveConfigFile( p_intf, NULL );
336     }
337 }