Qt4 - Select the first category on the advanced preferences.
[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 <QMessageBox>
39 #include <QDialogButtonBox>
40
41 PrefsDialog *PrefsDialog::instance = NULL;
42
43 PrefsDialog::PrefsDialog( intf_thread_t *_p_intf ) : QVLCFrame( _p_intf )
44 {
45     QGridLayout *main_layout = new QGridLayout( this );
46     setWindowTitle( qtr( "Preferences" ) );
47
48     /* Create Panels */
49     tree_panel = new QWidget;
50     tree_panel_l = new QHBoxLayout;
51     tree_panel->setLayout( tree_panel_l );
52     main_panel = new QWidget;
53     main_panel_l = new QHBoxLayout;
54     main_panel->setLayout( main_panel_l );
55
56     /* Choice for types */
57     types = new QGroupBox( "Show settings" );
58     types->setAlignment( Qt::AlignHCenter );
59     QHBoxLayout *types_l = new QHBoxLayout;
60     types_l->setSpacing( 3 ); types_l->setMargin( 3 );
61     small = new QRadioButton( qtr("Basic"), types );
62     types_l->addWidget( small );
63     all = new QRadioButton( qtr("All"), types ); types_l->addWidget( all );
64     types->setLayout( types_l );
65     small->setChecked( true );
66
67     /* Tree and panel initialisations */
68     advanced_tree = NULL;
69     simple_tree = NULL;
70     current_simple_panel  = NULL;
71     advanced_panel = NULL;
72
73     /* Buttons */
74     QDialogButtonBox *buttonsBox = new QDialogButtonBox();
75     QPushButton *save = new QPushButton( qtr( "&Save" ) );
76     QPushButton *cancel = new QPushButton( qtr( "&Cancel" ) );
77     QPushButton *reset = new QPushButton( qtr( "&Reset Preferences" ) );
78
79     buttonsBox->addButton( save, QDialogButtonBox::AcceptRole );
80     buttonsBox->addButton( cancel, QDialogButtonBox::RejectRole );
81     buttonsBox->addButton( reset, QDialogButtonBox::ActionRole );
82
83     /* Layout  */
84     main_layout->addWidget( tree_panel, 0, 0, 3, 1 );
85     main_layout->addWidget( types, 3, 0, 2, 1 );
86     main_layout->addWidget( main_panel, 0, 1, 4, 1 );
87     main_layout->addWidget( buttonsBox, 4, 1, 1 ,2 );
88
89     main_layout->setColumnMinimumWidth( 0, 150 );
90     main_layout->setColumnStretch( 0, 1 );
91     main_layout->setColumnStretch( 1, 3 );
92
93     main_layout->setRowStretch( 2, 4 );
94
95     setLayout( main_layout );
96
97     /* Margins */
98     tree_panel_l->setMargin( 1 );
99     main_panel_l->setMargin( 3 );
100
101     for( int i = 0; i < SPrefsMax ; i++ ) simple_panels[i] = NULL;
102
103     if( config_GetInt( p_intf, "qt-advanced-pref" ) == 1 )
104         setAdvanced();
105     else
106         setSmall();
107
108     BUTTONACT( save, save() );
109     BUTTONACT( cancel, cancel() );
110     BUTTONACT( reset, reset() );
111
112     BUTTONACT( small, setSmall() );
113     BUTTONACT( all, setAdvanced() );
114
115     resize( 750, sizeHint().height() );
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     /* Select the first Item of the preferences. Maybe you want to select a specified
152        category... */
153     advanced_tree->setCurrentIndex(
154             advanced_tree->model()->index( 0, 0, QModelIndex() ) );
155
156     all->setChecked( true );
157 }
158
159 void PrefsDialog::setSmall()
160 {
161     /* If an advanced TREE exists, remove and hide it */
162     if( advanced_tree )
163         if( advanced_tree->isVisible() ) advanced_tree->hide();
164
165     /* If no simple_tree, create one, connect it */
166     if( !simple_tree )
167     {
168          simple_tree = new SPrefsCatList( p_intf, tree_panel );
169          CONNECT( simple_tree,
170                   currentItemChanged( int ),
171                   this,  changeSimplePanel( int ) );
172         tree_panel_l->addWidget( simple_tree );
173     }
174
175     /*show it */
176     simple_tree->show();
177
178     /* If an Advanced PANEL exists, remove it */
179     if( advanced_panel )
180         if( advanced_panel->isVisible() ) advanced_panel->hide();
181
182     if( !current_simple_panel )
183     {
184         current_simple_panel =
185             new SPrefsPanel( p_intf, main_panel, SPrefsDefaultCat );
186         simple_panels[SPrefsDefaultCat] =  current_simple_panel;
187         main_panel_l->addWidget( current_simple_panel );
188     }
189
190     current_simple_panel->show();
191     small->setChecked( true );
192 }
193
194 /* Switching from on simple panel to another */
195 void PrefsDialog::changeSimplePanel( int number )
196 {
197     if( current_simple_panel )
198         if( current_simple_panel->isVisible() ) current_simple_panel->hide();
199
200     current_simple_panel = simple_panels[number];
201     if( !current_simple_panel )
202     {
203         current_simple_panel  = new SPrefsPanel( p_intf, main_panel, number );
204         simple_panels[number] = current_simple_panel;
205         main_panel_l->addWidget( current_simple_panel );
206     }
207
208     current_simple_panel->show();
209 }
210
211 /* Changing from one Advanced Panel to another */
212 void PrefsDialog::changeAdvPanel( QTreeWidgetItem *item )
213 {
214     PrefsItemData *data = item->data( 0, Qt::UserRole ).value<PrefsItemData*>();
215
216     if( advanced_panel )
217         if( advanced_panel->isVisible() ) advanced_panel->hide();
218
219     if( !data->panel )
220     {
221         data->panel = new AdvPrefsPanel( p_intf, main_panel , data );
222         main_panel_l->addWidget( data->panel );
223     }
224
225     advanced_panel = data->panel;
226     advanced_panel->show();
227 }
228
229 #if 0
230 /*Called from extended settings, is not used anymore, but could be useful one day*/
231 void PrefsDialog::showModulePrefs( char *psz_module )
232 {
233     setAdvanced();
234     all->setChecked( true );
235     for( int i_cat_index = 0 ; i_cat_index < advanced_tree->topLevelItemCount();
236          i_cat_index++ )
237     {
238         QTreeWidgetItem *cat_item = advanced_tree->topLevelItem( i_cat_index );
239         PrefsItemData *data = cat_item->data( 0, Qt::UserRole ).
240                                                    value<PrefsItemData *>();
241         for( int i_sc_index = 0; i_sc_index < cat_item->childCount();
242                                   i_sc_index++ )
243         {
244             QTreeWidgetItem *subcat_item = cat_item->child( i_sc_index );
245             PrefsItemData *sc_data = subcat_item->data(0, Qt::UserRole).
246                                                     value<PrefsItemData *>();
247             for( int i_module = 0; i_module < subcat_item->childCount();
248                                    i_module++ )
249             {
250                 QTreeWidgetItem *module_item = subcat_item->child( i_module );
251                 PrefsItemData *mod_data = module_item->data( 0, Qt::UserRole ).
252                                                     value<PrefsItemData *>();
253                 if( !strcmp( mod_data->psz_name, psz_module ) ) {
254                     advanced_tree->setCurrentItem( module_item );
255                 }
256             }
257         }
258     }
259     show();
260 }
261 #endif
262
263 /* Actual apply and save for the preferences */
264 void PrefsDialog::save()
265 {
266     if( small->isChecked() && simple_tree->isVisible() )
267     {
268         msg_Dbg( p_intf, "Saving the simple preferences" );
269         for( int i = 0 ; i< SPrefsMax; i++ ){
270             if( simple_panels[i] )simple_panels[i]->apply();
271         }
272     }
273     else if( all->isChecked() && advanced_tree->isVisible() )
274     {
275         msg_Dbg( p_intf, "Saving the advanced preferences" );
276         advanced_tree->applyAll();
277     }
278
279     /* Save to file */
280     config_SaveConfigFile( p_intf, NULL );
281
282     /* Delete the other panel in order to force its reload after clicking
283        on apply. In fact, if we don't do that, the preferences from the other
284        panels won't be accurate, so we would have to recreate the whole dialog,
285        and we don't want that.*/
286     if( small->isChecked() && advanced_panel )
287     {
288         /* Deleting only the active panel from the advanced config doesn't work
289            because the data records of PrefsItemData  contains still a
290            reference to it only cleanAll() is sure to remove all Panels! */
291         advanced_tree->cleanAll();
292         advanced_panel = NULL;
293     }
294     if( all->isChecked() && current_simple_panel )
295     {
296         for( int i = 0 ; i< SPrefsMax; i++ )
297         {
298             if( simple_panels[i] )
299             {
300                delete simple_panels[i];
301                simple_panels[i] = NULL;
302             }
303         }
304         current_simple_panel  = NULL;
305     }
306
307     hide();
308 }
309
310 /* Clean the preferences, dunno if it does something really */
311 void PrefsDialog::cancel()
312 {
313     if( small->isChecked() && simple_tree )
314     {
315         for( int i = 0 ; i< SPrefsMax; i++ )
316             if( simple_panels[i] ) simple_panels[i]->clean();
317     }
318     else if( all->isChecked() && advanced_tree )
319     {
320         advanced_tree->cleanAll();
321         advanced_panel = NULL;
322     }
323     hide();
324 }
325
326 /* Reset all the preferences, when you click the button */
327 void PrefsDialog::reset()
328 {
329     int ret = QMessageBox::question(
330                  this,
331                  qtr( "Reset Preferences" ),
332                  qtr( "This will reset your VLC media player preferences.\n"
333                       "Are you sure you want to continue?" ),
334                  QMessageBox::Ok | QMessageBox::Cancel,
335                  QMessageBox::Ok);
336
337     if( ret == QMessageBox::Ok )
338     {
339         config_ResetAll( p_intf );
340         config_SaveConfigFile( p_intf, NULL );
341     }
342 }