]> git.sesse.net Git - vlc/blob - modules/gui/qt4/dialogs/preferences.cpp
Forgotten tooltips.
[vlc] / 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 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include "dialogs/preferences.hpp"
30 #include "dialogs_provider.hpp"
31 #include "util/qvlcframe.hpp"
32
33 #include "components/complete_preferences.hpp"
34 #include "components/simple_preferences.hpp"
35
36 #include <QHBoxLayout>
37 #include <QGroupBox>
38 #include <QRadioButton>
39 #include <QVBoxLayout>
40 #include <QPushButton>
41 #include <QCheckBox>
42 #include <QMessageBox>
43 #include <QDialogButtonBox>
44
45 PrefsDialog *PrefsDialog::instance = NULL;
46
47 PrefsDialog::PrefsDialog( QWidget *parent, intf_thread_t *_p_intf )
48             : QVLCDialog( parent, _p_intf )
49 {
50     QGridLayout *main_layout = new QGridLayout( this );
51     setWindowTitle( qtr( "Preferences" ) );
52
53     /* Whether we want it or not, we need to destroy on close to get
54        consistency when reset */
55     setAttribute( Qt::WA_DeleteOnClose );
56
57     /* Create Panels */
58     tree_panel = new QWidget;
59     tree_panel_l = new QHBoxLayout;
60     tree_panel->setLayout( tree_panel_l );
61     main_panel = new QWidget;
62     main_panel_l = new QHBoxLayout;
63     main_panel->setLayout( main_panel_l );
64
65     /* Choice for types */
66     types = new QGroupBox( "Show settings" );
67     types->setAlignment( Qt::AlignHCenter );
68     QHBoxLayout *types_l = new QHBoxLayout;
69     types_l->setSpacing( 3 ); types_l->setMargin( 3 );
70     small = new QRadioButton( qtr( "Simple" ), types );
71     small->setToolTip( qtr( "Switch to simple preferences" ) );
72     types_l->addWidget( small );
73     all = new QRadioButton( qtr("All"), types ); types_l->addWidget( all );
74     all->setToolTip( qtr( "Switch to complete preferences" ) );
75     types->setLayout( types_l );
76     small->setChecked( true );
77
78     /* Tree and panel initialisations */
79     advanced_tree = NULL;
80     simple_tree = NULL;
81     current_simple_panel  = NULL;
82     advanced_panel = NULL;
83
84     /* Buttons */
85     QDialogButtonBox *buttonsBox = new QDialogButtonBox();
86     QPushButton *save = new QPushButton( qtr( "&Save" ) );
87     QPushButton *cancel = new QPushButton( qtr( "&Cancel" ) );
88     QPushButton *reset = new QPushButton( qtr( "&Reset Preferences" ) );
89
90     buttonsBox->addButton( save, QDialogButtonBox::AcceptRole );
91     buttonsBox->addButton( cancel, QDialogButtonBox::RejectRole );
92     buttonsBox->addButton( reset, QDialogButtonBox::ResetRole );
93
94     /* Layout  */
95     main_layout->addWidget( tree_panel, 0, 0, 3, 1 );
96     main_layout->addWidget( types, 3, 0, 2, 1 );
97     main_layout->addWidget( main_panel, 0, 1, 4, 2 );
98     main_layout->addWidget( buttonsBox, 4, 2, 1 ,1 );
99
100     main_layout->setColumnMinimumWidth( 0, 150 );
101     main_layout->setColumnMinimumWidth( 1, 10 );
102     main_layout->setColumnStretch( 0, 1 );
103     main_layout->setColumnStretch( 1, 0 );
104     main_layout->setColumnStretch( 2, 3 );
105
106     main_layout->setRowStretch( 2, 4 );
107
108     main_layout->setMargin( 9 );
109     setLayout( main_layout );
110
111     /* Margins */
112     tree_panel_l->setMargin( 1 );
113     main_panel_l->setLayoutMargins( 6, 0, 0, 3, 3 );
114
115     for( int i = 0; i < SPrefsMax ; i++ ) simple_panels[i] = NULL;
116
117     if( config_GetInt( p_intf, "qt-advanced-pref" ) == 1 )
118         setAdvanced();
119     else
120         setSmall();
121
122     BUTTONACT( save, save() );
123     BUTTONACT( cancel, cancel() );
124     BUTTONACT( reset, reset() );
125
126     BUTTONACT( small, setSmall() );
127     BUTTONACT( all, setAdvanced() );
128
129     resize( 750, sizeHint().height() );
130 }
131
132 void PrefsDialog::setAdvanced()
133 {
134     /* We already have a simple TREE, and we just want to hide it */
135     if( simple_tree )
136         if( simple_tree->isVisible() ) simple_tree->hide();
137
138     /* If don't have already and advanced TREE, then create it */
139     if( !advanced_tree )
140     {
141         /* Creation */
142          advanced_tree = new PrefsTree( p_intf, tree_panel );
143         /* and connections */
144          CONNECT( advanced_tree,
145                   currentItemChanged( QTreeWidgetItem *, QTreeWidgetItem * ),
146                   this, changeAdvPanel( QTreeWidgetItem * ) );
147         tree_panel_l->addWidget( advanced_tree );
148     }
149
150     /* Show it */
151     advanced_tree->show();
152
153     /* Remove the simple current panel from the main panels*/
154     if( current_simple_panel )
155         if( current_simple_panel->isVisible() ) current_simple_panel->hide();
156
157     /* If no advanced Panel exist, create one, attach it and show it*/
158     if( !advanced_panel )
159     {
160         advanced_panel = new AdvPrefsPanel( main_panel );
161         main_panel_l->addWidget( advanced_panel );
162     }
163     advanced_panel->show();
164
165     /* Select the first Item of the preferences. Maybe you want to select a specified
166        category... */
167     advanced_tree->setCurrentIndex(
168             advanced_tree->model()->index( 0, 0, QModelIndex() ) );
169
170     all->setChecked( true );
171 }
172
173 void PrefsDialog::setSmall()
174 {
175     /* If an advanced TREE exists, remove and hide it */
176     if( advanced_tree )
177         if( advanced_tree->isVisible() ) advanced_tree->hide();
178
179     /* If no simple_tree, create one, connect it */
180     if( !simple_tree )
181     {
182          simple_tree = new SPrefsCatList( p_intf, tree_panel );
183          CONNECT( simple_tree,
184                   currentItemChanged( int ),
185                   this,  changeSimplePanel( int ) );
186         tree_panel_l->addWidget( simple_tree );
187     }
188
189     /*show it */
190     simple_tree->show();
191
192     /* If an Advanced PANEL exists, remove it */
193     if( advanced_panel )
194         if( advanced_panel->isVisible() ) advanced_panel->hide();
195
196     if( !current_simple_panel )
197     {
198         current_simple_panel =
199             new SPrefsPanel( p_intf, main_panel, SPrefsDefaultCat );
200         simple_panels[SPrefsDefaultCat] =  current_simple_panel;
201         main_panel_l->addWidget( current_simple_panel );
202     }
203
204     current_simple_panel->show();
205     small->setChecked( true );
206 }
207
208 /* Switching from on simple panel to another */
209 void PrefsDialog::changeSimplePanel( int number )
210 {
211     if( current_simple_panel )
212         if( current_simple_panel->isVisible() ) current_simple_panel->hide();
213
214     current_simple_panel = simple_panels[number];
215     if( !current_simple_panel )
216     {
217         current_simple_panel  = new SPrefsPanel( p_intf, main_panel, number );
218         simple_panels[number] = current_simple_panel;
219         main_panel_l->addWidget( current_simple_panel );
220     }
221
222     current_simple_panel->show();
223 }
224
225 /* Changing from one Advanced Panel to another */
226 void PrefsDialog::changeAdvPanel( QTreeWidgetItem *item )
227 {
228     PrefsItemData *data = item->data( 0, Qt::UserRole ).value<PrefsItemData*>();
229
230     if( advanced_panel )
231         if( advanced_panel->isVisible() ) advanced_panel->hide();
232
233     if( !data->panel )
234     {
235         data->panel = new AdvPrefsPanel( p_intf, main_panel , data );
236         main_panel_l->addWidget( data->panel );
237     }
238
239     advanced_panel = data->panel;
240     advanced_panel->show();
241 }
242
243 #if 0
244 /*Called from extended settings, is not used anymore, but could be useful one day*/
245 void PrefsDialog::showModulePrefs( char *psz_module )
246 {
247     setAdvanced();
248     all->setChecked( true );
249     for( int i_cat_index = 0 ; i_cat_index < advanced_tree->topLevelItemCount();
250          i_cat_index++ )
251     {
252         QTreeWidgetItem *cat_item = advanced_tree->topLevelItem( i_cat_index );
253         PrefsItemData *data = cat_item->data( 0, Qt::UserRole ).
254                                                    value<PrefsItemData *>();
255         for( int i_sc_index = 0; i_sc_index < cat_item->childCount();
256                                   i_sc_index++ )
257         {
258             QTreeWidgetItem *subcat_item = cat_item->child( i_sc_index );
259             PrefsItemData *sc_data = subcat_item->data(0, Qt::UserRole).
260                                                     value<PrefsItemData *>();
261             for( int i_module = 0; i_module < subcat_item->childCount();
262                                    i_module++ )
263             {
264                 QTreeWidgetItem *module_item = subcat_item->child( i_module );
265                 PrefsItemData *mod_data = module_item->data( 0, Qt::UserRole ).
266                                                     value<PrefsItemData *>();
267                 if( !strcmp( mod_data->psz_name, psz_module ) ) {
268                     advanced_tree->setCurrentItem( module_item );
269                 }
270             }
271         }
272     }
273     show();
274 }
275 #endif
276
277 /* Actual apply and save for the preferences */
278 void PrefsDialog::save()
279 {
280     if( small->isChecked() && simple_tree->isVisible() )
281     {
282         msg_Dbg( p_intf, "Saving the simple preferences" );
283         for( int i = 0 ; i< SPrefsMax; i++ ){
284             if( simple_panels[i] )simple_panels[i]->apply();
285         }
286     }
287     else if( all->isChecked() && advanced_tree->isVisible() )
288     {
289         msg_Dbg( p_intf, "Saving the advanced preferences" );
290         advanced_tree->applyAll();
291     }
292
293     /* Save to file */
294     config_SaveConfigFile( p_intf, NULL );
295
296     destroyPanels();
297
298     hide();
299 }
300
301 void PrefsDialog::destroyPanels()
302 {
303     msg_Dbg( p_intf, "Destroying the Panels" );
304     /* Delete the other panel in order to force its reload after clicking
305        on apply. In fact, if we don't do that, the preferences from the other
306        panels won't be accurate, so we would have to recreate the whole dialog,
307        and we don't want that.*/
308     if( small->isChecked() && advanced_panel )
309     {
310         /* Deleting only the active panel from the advanced config doesn't work
311            because the data records of PrefsItemData  contains still a
312            reference to it only cleanAll() is sure to remove all Panels! */
313         advanced_tree->cleanAll();
314         advanced_panel = NULL;
315     }
316     if( all->isChecked() && current_simple_panel )
317     {
318         for( int i = 0 ; i< SPrefsMax; i++ )
319         {
320             if( simple_panels[i] )
321             {
322                delete simple_panels[i];
323                simple_panels[i] = NULL;
324             }
325         }
326         current_simple_panel  = NULL;
327     }
328 }
329
330
331 /* Clean the preferences, dunno if it does something really */
332 void PrefsDialog::cancel()
333 {
334     if( small->isChecked() && simple_tree )
335     {
336         for( int i = 0 ; i< SPrefsMax; i++ )
337             if( simple_panels[i] ) simple_panels[i]->clean();
338     }
339     else if( all->isChecked() && advanced_tree )
340     {
341         advanced_tree->cleanAll();
342         advanced_panel = NULL;
343     }
344     hide();
345 }
346
347 /* Reset all the preferences, when you click the button */
348 void PrefsDialog::reset()
349 {
350     int ret = QMessageBox::question(
351                  this,
352                  qtr( "Reset Preferences" ),
353                  qtr( "This will reset your VLC media player preferences.\n"
354                       "Are you sure you want to continue?" ),
355                  QMessageBox::Ok | QMessageBox::Cancel,
356                  QMessageBox::Ok);
357
358     if( ret == QMessageBox::Ok )
359     {
360         config_ResetAll( p_intf );
361         config_SaveConfigFile( p_intf, NULL );
362
363         instance = NULL;
364         close();
365         PrefsDialog::getInstance( p_intf )->show();
366     }
367 }