qt: preferences: Always use a combobox for resume playback
[vlc.git] / modules / gui / qt / components / simple_preferences.cpp
blob1c758cb72b2b3b3f0a508d08ecd638b86c1bcccb
1 /*****************************************************************************
2 * simple_preferences.cpp : "Simple preferences"
3 ****************************************************************************
4 * Copyright (C) 2006-2010 the VideoLAN team
5 * $Id$
7 * Authors: Clément Stenac <zorglub@videolan.org>
8 * Antoine Cellerier <dionoea@videolan.org>
9 * Jean-Baptiste Kempf <jb@videolan.org>
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.
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.
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 *****************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
30 #include "components/simple_preferences.hpp"
31 #include "components/preferences_widgets.hpp"
33 #include <vlc_config_cat.h>
34 #include <vlc_configuration.h>
36 #include <QString>
37 #include <QFont>
38 #include <QToolButton>
39 #include <QSignalMapper>
40 #include <QVBoxLayout>
41 #include <QScrollArea>
43 #include <QStyleFactory>
44 #include <QSettings>
45 #include <QtAlgorithms>
46 #include <QDir>
47 #include <assert.h>
48 #include <math.h>
50 #define ICON_HEIGHT 48
52 #ifdef _WIN32
53 # include <vlc_charset.h>
54 # include <shobjidl.h>
55 #endif
56 #include <vlc_modules.h>
58 static const char *const ppsz_language[] =
60 "auto",
61 "en",
62 "ar",
63 "bn",
64 "pt_BR",
65 "en_GB",
66 "el",
67 "bg",
68 "ca",
69 "zh_TW",
70 "cs",
71 "cy",
72 "da",
73 "nl",
74 "fi",
75 "et",
76 "eu",
77 "fr",
78 "ga",
79 "gd",
80 "gl",
81 "ka",
82 "de",
83 "he",
84 "hr",
85 "hu",
86 "hy",
87 "is",
88 "id",
89 "it",
90 "ja",
91 "ko",
92 "lt",
93 "mn",
94 "ms",
95 "nb",
96 "nn",
97 "kk",
98 "km",
99 "ne",
100 "oc",
101 "fa",
102 "pl",
103 "pt_PT",
104 "pa",
105 "ro",
106 "ru",
107 "zh_CN",
108 "si",
109 "sr",
110 "sk",
111 "sl",
112 "ckb",
113 "es",
114 "sv",
115 "te",
116 "tr",
117 "uk",
118 "vi",
119 "wa",
120 NULL,
123 static const char *const ppsz_language_text[] =
125 N_("Auto"),
126 "American English",
127 "ﻉﺮﺒﻳ",
128 "বাংলা",
129 "Português Brasileiro",
130 "British English",
131 "Νέα Ελληνικά",
132 "български език",
133 "Català",
134 "正體中文",
135 "Čeština",
136 "Cymraeg",
137 "Dansk",
138 "Nederlands",
139 "Suomi",
140 "eesti keel",
141 "Euskara",
142 "Français",
143 "Gaeilge",
144 "Gàidhlig",
145 "Galego",
146 "ქართული",
147 "Deutsch",
148 "עברית",
149 "hrvatski",
150 "Magyar",
151 "հայերեն",
152 "íslenska",
153 "Bahasa Indonesia",
154 "Italiano",
155 "日本語",
156 "한국어",
157 "lietuvių",
158 "Монгол хэл",
159 "Melayu",
160 "Bokmål",
161 "Nynorsk",
162 "Қазақ тілі",
163 "ភាសាខ្មែរ",
164 "नेपाली",
165 "Occitan",
166 "ﻑﺍﺮﺳی",
167 "Polski",
168 "Português",
169 "ਪੰਜਾਬੀ",
170 "Română",
171 "Русский",
172 "简体中文",
173 "සිංහල",
174 "српски",
175 "Slovensky",
176 "slovenščina",
177 "کوردیی سۆرانی",
178 "Español",
179 "Svenska",
180 "తెలుగు",
181 "Türkçe",
182 "украї́нська мо́ва",
183 "tiếng Việt",
184 "Walon",
187 static int getDefaultAudioVolume(vlc_object_t *obj, const char *aout)
189 if (!strcmp(aout, "") || !strcmp(aout, "any"))
190 return -1;
191 else
192 /* Note: For hysterical raisins, this is sorted by decreasing priority
193 * order (then alphabetical order). */
194 if (!strcmp(aout, "pulse"))
195 return -1;
196 else
197 #ifdef __linux__
198 if (!strcmp(aout, "alsa") && module_exists("alsa"))
199 return cbrtf(config_GetFloat(obj, "alsa-gain")) * 100.f + .5f;
200 else
201 #endif
202 #ifdef _WIN32
203 if (!strcmp(aout, "mmdevice"))
204 return -1;
205 else
206 #endif
207 if (!strcmp(aout, "sndio"))
208 return -1;
209 else
210 #ifdef __APPLE__
211 if (!strcmp(aout, "auhal") && module_exists("auhal"))
212 return (config_GetFloat(obj, "auhal-volume") * 100.f + .5f)
213 / AOUT_VOLUME_DEFAULT;
214 else
215 #endif
216 #ifdef _WIN32
217 if (!strcmp(aout, "directsound") && module_exists("directsound"))
218 return config_GetFloat(obj, "directx-volume") * 100.f + .5f;
219 else
220 #endif
221 if (!strcmp(aout, "jack"))
222 return cbrtf(config_GetFloat(obj, "jack-gain")) * 100.f + 0.5f;
223 else
224 #ifdef __OS2__
225 if (!strcmp(aout, "kai"))
226 return cbrtf(config_GetFloat(obj, "kai-gain")) * 100.f + .5f;
227 else
228 #endif
229 if (!strcmp(aout, "oss"))
230 return -1;
231 else
232 #ifdef _WIN32
233 if (!strcmp(aout, "waveout"))
234 return config_GetFloat(obj, "waveout-volume") * 100.f + .5f;
235 else
236 #endif
237 return -1;
240 /*********************************************************************
241 * The List of categories
242 *********************************************************************/
243 SPrefsCatList::SPrefsCatList( intf_thread_t *_p_intf, QWidget *_parent ) :
244 QWidget( _parent ), p_intf( _p_intf )
246 QHBoxLayout *layout = new QHBoxLayout();
248 /* Use autoExclusive buttons and a mapper as QButtonGroup can't
249 set focus (keys) when it manages the buttons's exclusivity.
250 See QT bugs 131 & 816 and QAbstractButton's source code. */
251 QSignalMapper *mapper = new QSignalMapper( layout );
252 CONNECT( mapper, mapped(int), this, switchPanel(int) );
254 short icon_height = ICON_HEIGHT;
256 #define ADD_CATEGORY( button, label, ltooltip, icon, numb ) \
257 QToolButton * button = new QToolButton( this ); \
258 button->setIcon( QIcon( ":/prefsmenu/" #icon ) ); \
259 button->setText( label ); \
260 button->setToolTip( ltooltip ); \
261 button->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); \
262 button->setIconSize( QSize( icon_height + 40 , icon_height ) ); \
263 button->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred ); \
264 button->setAutoRaise( true ); \
265 button->setCheckable( true ); \
266 button->setAutoExclusive( true ); \
267 CONNECT( button, clicked(), mapper, map() ); \
268 mapper->setMapping( button, numb ); \
269 layout->addWidget( button );
271 ADD_CATEGORY( SPrefsInterface, qtr("Interface"), qtr("Interface Settings"),
272 cone_interface_64, 0 );
273 ADD_CATEGORY( SPrefsAudio, qtr("Audio"), qtr("Audio Settings"),
274 cone_audio_64, 1 );
275 ADD_CATEGORY( SPrefsVideo, qtr("Video"), qtr("Video Settings"),
276 cone_video_64, 2 );
277 ADD_CATEGORY( SPrefsSubtitles, qtr(SUBPIC_TITLE), qtr("Subtitle & On Screen Display Settings"),
278 cone_subtitles_64, 3 );
279 ADD_CATEGORY( SPrefsInputAndCodecs, qtr(INPUT_TITLE), qtr("Input & Codecs Settings"),
280 cone_input_64, 4 );
281 ADD_CATEGORY( SPrefsHotkeys, qtr("Hotkeys"), qtr("Configure Hotkeys"),
282 cone_hotkeys_64, 5 );
284 #undef ADD_CATEGORY
286 SPrefsInterface->setChecked( true );
287 layout->setMargin( 0 );
288 layout->setSpacing( 1 );
290 setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Preferred);
291 setMinimumWidth( ICON_HEIGHT * 6 + 10 );
292 setLayout( layout );
295 void SPrefsCatList::switchPanel( int i )
297 emit currentItemChanged( i );
300 /*********************************************************************
301 * The Panels
302 *********************************************************************/
303 SPrefsPanel::SPrefsPanel( intf_thread_t *_p_intf, QWidget *_parent,
304 int _number ) : QWidget( _parent ), p_intf( _p_intf )
306 module_config_t *p_config;
307 ConfigControl *control;
308 number = _number;
309 lang = NULL;
310 radioGroup = NULL;
312 #define CONFIG_GENERIC( option, type, label, qcontrol ) \
313 p_config = config_FindConfig( VLC_OBJECT(p_intf), option ); \
314 if( p_config ) \
316 control = new type ## ConfigControl( VLC_OBJECT(p_intf), \
317 p_config, label, ui.qcontrol, false ); \
318 controls.append( control ); \
320 else { \
321 ui.qcontrol->setEnabled( false ); \
322 if( label ) label->setEnabled( false ); \
325 #define CONFIG_BOOL( option, qcontrol ) \
326 p_config = config_FindConfig( VLC_OBJECT(p_intf), option ); \
327 if( p_config ) \
329 control = new BoolConfigControl( VLC_OBJECT(p_intf), \
330 p_config, NULL, ui.qcontrol ); \
331 controls.append( control ); \
333 else { ui.qcontrol->setEnabled( false ); }
336 #define CONFIG_GENERIC_NO_UI( option, type, label, qcontrol ) \
337 p_config = config_FindConfig( VLC_OBJECT(p_intf), option ); \
338 if( p_config ) \
340 control = new type ## ConfigControl( VLC_OBJECT(p_intf), \
341 p_config, label, qcontrol, false ); \
342 controls.append( control ); \
344 else { \
345 QWidget *widget = label; \
346 qcontrol->setVisible( false ); \
347 if( widget ) widget->setEnabled( false ); \
351 #define CONFIG_GENERIC_NO_BOOL( option, type, label, qcontrol ) \
352 p_config = config_FindConfig( VLC_OBJECT(p_intf), option ); \
353 if( p_config ) \
355 control = new type ## ConfigControl( VLC_OBJECT(p_intf), \
356 p_config, label, ui.qcontrol ); \
357 controls.append( control ); \
360 #define CONFIG_GENERIC_FILE( option, type, label, qcontrol, qbutton ) \
361 p_config = config_FindConfig( VLC_OBJECT(p_intf), option ); \
362 if( p_config ) \
364 control = new type ## ConfigControl( VLC_OBJECT(p_intf), \
365 p_config, label, qcontrol, qbutton ); \
366 controls.append( control ); \
369 #define START_SPREFS_CAT( name , label ) \
370 case SPrefs ## name: \
372 Ui::SPrefs ## name ui; \
373 ui.setupUi( panel ); \
374 panel_label->setText( label );
376 #define END_SPREFS_CAT \
377 break; \
380 QVBoxLayout *panel_layout = new QVBoxLayout();
381 QWidget *panel = new QWidget();
382 panel_layout->setMargin( 3 );
384 // Title Label
385 QLabel *panel_label = new QLabel;
386 QFont labelFont = QApplication::font();
387 labelFont.setPointSize( labelFont.pointSize() + 6 );
388 panel_label->setFont( labelFont );
390 // Title <hr>
391 QFrame *title_line = new QFrame;
392 title_line->setFrameShape(QFrame::HLine);
393 title_line->setFrameShadow(QFrame::Sunken);
395 QFont italicFont = QApplication::font();
396 italicFont.setItalic( true );
398 switch( number )
400 /******************************
401 * VIDEO Panel Implementation *
402 ******************************/
403 START_SPREFS_CAT( Video , qtr("Video Settings") );
404 CONFIG_BOOL( "video", enableVideo );
405 ui.videoZone->setEnabled( ui.enableVideo->isChecked() );
406 CONNECT( ui.enableVideo, toggled( bool ),
407 ui.videoZone, setEnabled( bool ) );
409 CONFIG_BOOL( "fullscreen", fullscreen );
410 CONFIG_BOOL( "video-on-top", alwaysOnTop );
411 CONFIG_BOOL( "video-deco", windowDecorations );
412 CONFIG_GENERIC( "vout", StringList, ui.voutLabel, outputModule );
414 #ifdef _WIN32
415 CONFIG_GENERIC( "directx-device", StringList, ui.dxDeviceLabel,
416 dXdisplayDevice );
417 CONFIG_BOOL( "directx-overlay", overlay );
418 CONFIG_BOOL( "directx-hw-yuv", hwYUVBox );
419 CONNECT( ui.overlay, toggled( bool ), ui.hwYUVBox, setEnabled( bool ) );
420 #else
421 ui.directXBox->setVisible( false );
422 ui.overlay->setVisible( false );
423 ui.hwYUVBox->setVisible( false );
424 #endif
426 #ifdef __OS2__
427 CONFIG_BOOL( "kva-fixt23", kvaFixT23 );
428 CONFIG_GENERIC( "kva-video-mode", StringList, ui.kvaVideoModeLabel,
429 kvaVideoMode );
430 #else
431 ui.kvaBox->setVisible( false );
432 #endif
434 CONFIG_GENERIC( "deinterlace", IntegerList, ui.deinterLabel, deinterlaceBox );
435 CONFIG_GENERIC( "deinterlace-mode", StringList, ui.deinterModeLabel, deinterlaceModeBox );
436 CONFIG_GENERIC( "aspect-ratio", String, ui.arLabel, arLine );
438 CONFIG_GENERIC_FILE( "snapshot-path", Directory, ui.dirLabel,
439 ui.snapshotsDirectory, ui.snapshotsDirectoryBrowse );
440 CONFIG_GENERIC( "snapshot-prefix", String, ui.prefixLabel, snapshotsPrefix );
441 CONFIG_BOOL( "snapshot-sequential",
442 snapshotsSequentialNumbering );
443 CONFIG_GENERIC( "snapshot-format", StringList, ui.arLabel,
444 snapshotsFormat );
445 END_SPREFS_CAT;
447 /******************************
448 * AUDIO Panel Implementation *
449 ******************************/
450 START_SPREFS_CAT( Audio, qtr("Audio Settings") );
452 CONFIG_BOOL( "audio", enableAudio );
453 ui.audioZone->setEnabled( ui.enableAudio->isChecked() );
454 CONNECT( ui.enableAudio, toggled( bool ),
455 ui.audioZone, setEnabled( bool ) );
457 #define audioCommon( name ) \
458 QLabel * name ## Label = new QLabel( qtr( "Device:" ) ); \
459 name ## Label->setMinimumSize(QSize(250, 0)); \
460 outputAudioLayout->addWidget( name ## Label, outputAudioLayout->rowCount(), 0, 1, 1 ); \
462 #define audioControl( name) \
463 audioCommon( name ) \
464 QComboBox * name ## Device = new QComboBox; \
465 name ## Label->setBuddy( name ## Device ); \
466 name ## Device->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred );\
467 outputAudioLayout->addWidget( name ## Device, outputAudioLayout->rowCount() - 1, 1, 1, -1 );
469 #define audioControl2( name) \
470 audioCommon( name ) \
471 QHBoxLayout * name ## hboxLayout = new QHBoxLayout; \
472 QLineEdit * name ## Device = new QLineEdit; \
473 name ## Label->setBuddy( name ## Device ); \
474 name ## hboxLayout->addWidget( name ## Device ); \
475 QPushButton * name ## Browse = new QPushButton( qtr( "Browse..." ) ); \
476 name ## hboxLayout->addWidget( name ## Browse ); \
477 outputAudioLayout->addLayout( name ## hboxLayout, outputAudioLayout->rowCount() - 1, 1, 1, 1, Qt::AlignLeft );
479 /* Build if necessary */
480 QGridLayout * outputAudioLayout = qobject_cast<QGridLayout *>(ui.outputAudioBox->layout());
481 #ifdef _WIN32
482 audioControl( DirectX );
483 optionWidgets["directxL" ] = DirectXLabel;
484 optionWidgets["directxW" ] = DirectXDevice;
485 CONFIG_GENERIC_NO_UI( "directx-audio-device", StringList,
486 DirectXLabel, DirectXDevice );
488 audioControl( Waveout );
489 optionWidgets["waveoutL" ] = WaveoutLabel;
490 optionWidgets["waveoutW" ] = WaveoutDevice;
491 CONFIG_GENERIC_NO_UI( "waveout-audio-device", StringList,
492 WaveoutLabel, WaveoutDevice );
494 #elif defined( __OS2__ )
495 audioControl( kai );
496 optionWidgets["kaiL"] = kaiLabel;
497 optionWidgets["kaiW"] = kaiDevice;
498 CONFIG_GENERIC_NO_UI( "kai-audio-device", StringList, kaiLabel,
499 kaiDevice );
500 #else
501 if( module_exists( "alsa" ) )
503 audioControl( alsa );
504 optionWidgets["alsaL"] = alsaLabel;
505 optionWidgets["alsaW"] = alsaDevice;
506 CONFIG_GENERIC_NO_UI( "alsa-audio-device" , StringList, alsaLabel,
507 alsaDevice );
509 if( module_exists( "oss" ) )
511 audioControl2( OSS );
512 optionWidgets["ossL"] = OSSLabel;
513 optionWidgets["ossW"] = OSSDevice;
514 optionWidgets["ossB"] = OSSBrowse;
515 CONFIG_GENERIC_FILE( "oss-audio-device" , File, OSSLabel, OSSDevice,
516 OSSBrowse );
518 #endif
520 #undef audioControl2
521 #undef audioControl
522 #undef audioCommon
524 int i_max_volume = config_GetInt( p_intf, "qt-max-volume" );
526 /* Audio Options */
527 ui.volumeValue->setMaximum( i_max_volume );
528 ui.defaultVolume->setMaximum( i_max_volume );
530 CONNECT( ui.defaultVolume, valueChanged( int ),
531 this, updateAudioVolume( int ) );
533 ui.defaultVolume_zone->setEnabled( ui.resetVolumeCheckbox->isChecked() );
534 CONNECT( ui.resetVolumeCheckbox, toggled( bool ),
535 ui.defaultVolume_zone, setEnabled( bool ) );
537 CONFIG_GENERIC( "audio-language" , String , ui.langLabel,
538 preferredAudioLanguage );
540 CONFIG_BOOL( "spdif", spdifBox );
541 CONFIG_GENERIC( "force-dolby-surround", IntegerList, ui.dolbyLabel,
542 detectionDolby );
544 CONFIG_GENERIC_NO_BOOL( "norm-max-level" , Float, NULL,
545 volNormSpin );
546 CONFIG_GENERIC( "audio-replay-gain-mode", StringList, ui.replayLabel,
547 replayCombo );
548 CONFIG_GENERIC( "audio-visual" , StringList, ui.visuLabel,
549 visualisation);
550 CONFIG_BOOL( "audio-time-stretch", autoscaleBox );
552 /* Audio Output Specifics */
553 CONFIG_GENERIC( "aout", StringList, ui.outputLabel, outputModule );
555 CONNECT( ui.outputModule, currentIndexChanged( int ),
556 this, updateAudioOptions( int ) );
558 /* File output exists on all platforms */
559 CONFIG_GENERIC_FILE( "audiofile-file", File, ui.fileLabel,
560 ui.fileName, ui.fileBrowseButton );
562 optionWidgets["fileW"] = ui.fileControl;
563 optionWidgets["audioOutCoB"] = ui.outputModule;
564 optionWidgets["normalizerChB"] = ui.volNormBox;
565 /*Little mofification of ui.volumeValue to compile with Qt < 4.3 */
566 ui.volumeValue->setButtonSymbols(QAbstractSpinBox::NoButtons);
567 optionWidgets["volLW"] = ui.volumeValue;
568 optionWidgets["headphoneB"] = ui.headphoneEffect;
569 optionWidgets["spdifChB"] = ui.spdifBox;
570 optionWidgets["defaultVolume"] = ui.defaultVolume;
571 optionWidgets["resetVolumeCheckbox"] = ui.resetVolumeCheckbox;
572 updateAudioOptions( ui.outputModule->currentIndex() );
574 /* LastFM */
575 if( module_exists( "audioscrobbler" ) )
577 CONFIG_GENERIC( "lastfm-username", String, ui.lastfm_user_label,
578 lastfm_user_edit );
579 CONFIG_GENERIC( "lastfm-password", String, ui.lastfm_pass_label,
580 lastfm_pass_edit );
582 if( config_ExistIntf( VLC_OBJECT( p_intf ), "audioscrobbler" ) )
583 ui.lastfm->setChecked( true );
584 else
585 ui.lastfm->setChecked( false );
587 ui.lastfm_zone->setVisible( ui.lastfm->isChecked() );
589 CONNECT( ui.lastfm, toggled( bool ),
590 ui.lastfm_zone, setVisible( bool ) );
591 CONNECT( ui.lastfm, stateChanged( int ),
592 this, lastfm_Changed( int ) );
594 else
596 ui.lastfm->hide();
597 ui.lastfm_zone->hide();
600 /* Normalizer */
601 CONNECT( ui.volNormBox, toggled( bool ), ui.volNormSpin,
602 setEnabled( bool ) );
604 char* psz = config_GetPsz( p_intf, "audio-filter" );
605 qs_filter = qfu( psz ).split( ':', QString::SkipEmptyParts );
606 free( psz );
608 bool b_enabled = ( qs_filter.contains( "normvol" ) );
609 ui.volNormBox->setChecked( b_enabled );
610 ui.volNormSpin->setEnabled( b_enabled );
612 b_enabled = ( qs_filter.contains( "headphone" ) );
613 ui.headphoneEffect->setChecked( b_enabled );
615 /* Volume Label */
616 updateAudioVolume( ui.defaultVolume->value() ); // First time init
618 END_SPREFS_CAT;
620 /* Input and Codecs Panel Implementation */
621 START_SPREFS_CAT( InputAndCodecs, qtr("Input & Codecs Settings") );
623 /* Disk Devices */
625 ui.DVDDeviceComboBox->setToolTip(
626 qtr( "If this property is blank, different values\n"
627 "for DVD, VCD, and CDDA are set.\n"
628 "You can define a unique one or configure them \n"
629 "individually in the advanced preferences." ) );
630 char *psz_dvddiscpath = config_GetPsz( p_intf, "dvd" );
631 char *psz_vcddiscpath = config_GetPsz( p_intf, "vcd" );
632 char *psz_cddadiscpath = config_GetPsz( p_intf, "cd-audio" );
633 if( psz_dvddiscpath && psz_vcddiscpath && psz_cddadiscpath )
634 if( !strcmp( psz_cddadiscpath, psz_dvddiscpath ) &&
635 !strcmp( psz_dvddiscpath, psz_vcddiscpath ) )
637 ui.DVDDeviceComboBox->setEditText( qfu( psz_dvddiscpath ) );
639 free( psz_cddadiscpath );
640 free( psz_dvddiscpath );
641 free( psz_vcddiscpath );
643 #ifndef _WIN32
644 QStringList DVDDeviceComboBoxStringList = QStringList();
645 DVDDeviceComboBoxStringList
646 << "dvd*" << "scd*" << "sr*" << "sg*" << "cd*";
647 ui.DVDDeviceComboBox->addItems( QDir( "/dev/" )
648 .entryList( DVDDeviceComboBoxStringList, QDir::System )
649 .replaceInStrings( QRegExp("^"), "/dev/" )
651 #endif
652 CONFIG_GENERIC( "dvd", String, ui.DVDLabel,
653 DVDDeviceComboBox->lineEdit() );
654 CONFIG_GENERIC_FILE( "input-record-path", Directory, ui.recordLabel,
655 ui.recordPath, ui.recordBrowse );
657 CONFIG_GENERIC( "http-proxy", String , ui.httpProxyLabel, proxy );
658 CONFIG_GENERIC_NO_BOOL( "postproc-q", Integer, ui.ppLabel,
659 PostProcLevel );
660 CONFIG_GENERIC( "avi-index", IntegerList, ui.aviLabel, AviRepair );
662 /* live555 module prefs */
663 CONFIG_BOOL( "rtsp-tcp",
664 live555TransportRTSP_TCPRadio );
665 if ( !module_exists( "live555" ) )
667 ui.live555TransportRTSP_TCPRadio->hide();
668 ui.live555TransportHTTPRadio->hide();
669 ui.live555TransportLabel->hide();
671 CONFIG_GENERIC( "avcodec-hw", StringList, ui.hwAccelLabel, hwAccelModule );
672 #ifdef _WIN32
673 HINSTANCE hdxva2_dll = LoadLibrary(TEXT("DXVA2.DLL") );
674 if( !hdxva2_dll )
675 ui.hwAccelModule->setEnabled( false );
676 else
677 FreeLibrary( hdxva2_dll );
678 #endif
679 optionWidgets["inputLE"] = ui.DVDDeviceComboBox;
680 optionWidgets["cachingCoB"] = ui.cachingCombo;
681 CONFIG_GENERIC( "avcodec-skiploopfilter", IntegerList, ui.filterLabel, loopFilterBox );
682 CONFIG_GENERIC( "sout-x264-tune", StringList, ui.x264Label, tuneBox );
683 CONFIG_GENERIC( "sout-x264-preset", StringList, ui.x264Label, presetBox );
684 CONFIG_GENERIC( "sout-x264-profile", StringList, ui.x264profileLabel, profileBox );
685 CONFIG_GENERIC( "sout-x264-level", String, ui.x264profileLabel, levelBox );
686 CONFIG_BOOL( "mkv-preload-local-dir", mkvPreloadBox );
688 /* Caching */
689 /* Add the things to the ComboBox */
690 #define addToCachingBox( str, cachingNumber ) \
691 ui.cachingCombo->addItem( qtr(str), QVariant( cachingNumber ) );
692 addToCachingBox( N_("Custom"), CachingCustom );
693 addToCachingBox( N_("Lowest latency"), CachingLowest );
694 addToCachingBox( N_("Low latency"), CachingLow );
695 addToCachingBox( N_("Normal"), CachingNormal );
696 addToCachingBox( N_("High latency"), CachingHigh );
697 addToCachingBox( N_("Higher latency"), CachingHigher );
698 #undef addToCachingBox
700 #define TestCaC( name, factor ) \
701 b_cache_equal = b_cache_equal && \
702 ( i_cache * factor == config_GetInt( p_intf, name ) );
703 /* Select the accurate value of the ComboBox */
704 bool b_cache_equal = true;
705 int i_cache = config_GetInt( p_intf, "file-caching" );
707 TestCaC( "network-caching", 10/3 );
708 TestCaC( "disc-caching", 1);
709 TestCaC( "live-caching", 1 );
710 if( b_cache_equal == 1 )
711 ui.cachingCombo->setCurrentIndex(
712 ui.cachingCombo->findData( QVariant( i_cache ) ) );
713 #undef TestCaC
715 END_SPREFS_CAT;
716 /*******************
717 * Interface Panel *
718 *******************/
719 START_SPREFS_CAT( Interface, qtr("Interface Settings") );
721 #ifndef _WIN32
722 ui.langBox->hide();
723 #else
724 for( int i = 0; ppsz_language[i] != NULL; i++)
725 ui.langCombo->addItem( qfu(ppsz_language_text[i]), ppsz_language[i]);
726 CONNECT( ui.langCombo, currentIndexChanged( int ), this, langChanged( int ) );
728 HKEY h_key;
729 char *langReg = NULL;
730 if( RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("Software\\VideoLAN\\VLC\\"), 0, KEY_READ, &h_key )
731 == ERROR_SUCCESS )
733 TCHAR szData[256];
734 DWORD len = 256;
735 if( RegQueryValueEx( h_key, TEXT("Lang"), NULL, NULL, (LPBYTE) &szData, &len ) == ERROR_SUCCESS ) {
736 langReg = FromWide( szData );
737 ui.langCombo->setCurrentIndex( ui.langCombo->findData(langReg) );
740 free( langReg);
741 #endif
743 // ui.defaultLabel->setFont( italicFont );
744 ui.skinsLabel->setText(
745 qtr( "This is VLC's skinnable interface. You can download other skins at" )
746 + QString( " <a href=\"http://www.videolan.org/vlc/skins.php\">" )
747 + qtr( "VLC skins website" )+ QString( "</a>." ) );
748 ui.skinsLabel->setFont( italicFont );
750 #ifdef _WIN32
751 BUTTONACT( ui.assoButton, assoDialog() );
752 #else
753 ui.osGroupBox->hide();
754 #endif
756 /* interface */
757 char *psz_intf = config_GetPsz( p_intf, "intf" );
758 if( psz_intf )
760 if( strstr( psz_intf, "skin" ) )
761 ui.skins->setChecked( true );
762 } else {
763 /* defaults to qt */
764 ui.qt->setChecked( true );
766 free( psz_intf );
768 optionWidgets["skinRB"] = ui.skins;
769 optionWidgets["qtRB"] = ui.qt;
770 #if !defined( _WIN32)
771 ui.stylesCombo->addItem( qtr("System's default") );
772 ui.stylesCombo->addItems( QStyleFactory::keys() );
773 ui.stylesCombo->setCurrentIndex( ui.stylesCombo->findText(
774 getSettings()->value( "MainWindow/QtStyle", "" ).toString() ) );
775 ui.stylesCombo->insertSeparator( 1 );
776 if ( ui.stylesCombo->currentIndex() < 0 )
777 ui.stylesCombo->setCurrentIndex( 0 ); /* default */
779 CONNECT( ui.stylesCombo, currentIndexChanged( QString ), this, changeStyle( QString ) );
780 optionWidgets["styleCB"] = ui.stylesCombo;
781 #else
782 ui.stylesCombo->hide();
783 ui.stylesLabel->hide();
784 #endif
785 radioGroup = new QButtonGroup(this);
786 radioGroup->addButton( ui.qt, 0 );
787 radioGroup->addButton( ui.skins, 1 );
788 CONNECT( radioGroup, buttonClicked( int ),
789 ui.styleStackedWidget, setCurrentIndex( int ) );
790 ui.styleStackedWidget->setCurrentIndex( radioGroup->checkedId() );
792 CONNECT( ui.minimalviewBox, toggled( bool ),
793 ui.mainPreview, setNormalPreview( bool ) );
794 CONFIG_BOOL( "qt-minimal-view", minimalviewBox );
795 ui.mainPreview->setNormalPreview( ui.minimalviewBox->isChecked() );
796 ui.skinsPreview->setPreview( InterfacePreviewWidget::SKINS );
798 CONFIG_BOOL( "embedded-video", embedVideo );
799 CONFIG_BOOL( "qt-video-autoresize", resizingBox );
800 CONNECT( ui.embedVideo, toggled( bool ), ui.resizingBox, setEnabled( bool ) );
801 ui.resizingBox->setEnabled( ui.embedVideo->isChecked() );
803 CONFIG_BOOL( "qt-fs-controller", fsController );
804 CONFIG_BOOL( "qt-system-tray", systrayBox );
805 CONFIG_GENERIC( "qt-notification", IntegerList, ui.notificationComboLabel,
806 notificationCombo );
807 CONNECT( ui.systrayBox, toggled( bool ), ui.notificationCombo, setEnabled( bool ) );
808 CONNECT( ui.systrayBox, toggled( bool ), ui.notificationComboLabel, setEnabled( bool ) );
809 ui.notificationCombo->setEnabled( ui.systrayBox->isChecked() );
811 CONFIG_BOOL( "qt-pause-minimized", pauseMinimizedBox );
812 CONFIG_BOOL( "playlist-tree", treePlaylist );
813 CONFIG_BOOL( "play-and-pause", playPauseBox );
814 CONFIG_GENERIC_FILE( "skins2-last", File, ui.skinFileLabel,
815 ui.fileSkin, ui.skinBrowse );
817 CONFIG_BOOL( "metadata-network-access", MetadataNetworkAccessMode );
819 /* UPDATE options */
820 #ifdef UPDATE_CHECK
821 CONFIG_BOOL( "qt-updates-notif", updatesBox );
822 CONFIG_GENERIC_NO_BOOL( "qt-updates-days", Integer, NULL,
823 updatesDays );
824 ui.updatesDays->setEnabled( ui.updatesBox->isChecked() );
825 CONNECT( ui.updatesBox, toggled( bool ),
826 ui.updatesDays, setEnabled( bool ) );
827 #else
828 ui.updatesBox->hide();
829 ui.updatesDays->hide();
830 #endif
831 /* ONE INSTANCE options */
832 #if !defined( _WIN32 ) && !defined(__APPLE__) && !defined(__OS2__)
833 if( !module_exists( "dbus" ) )
834 ui.OneInterfaceBox->hide();
835 else
836 #endif
838 CONFIG_BOOL( "one-instance", OneInterfaceMode );
839 CONFIG_BOOL( "playlist-enqueue", EnqueueOneInterfaceMode );
840 ui.EnqueueOneInterfaceMode->setEnabled(
841 ui.OneInterfaceMode->isChecked() );
842 CONNECT( ui.OneInterfaceMode, toggled( bool ),
843 ui.EnqueueOneInterfaceMode, setEnabled( bool ) );
844 CONFIG_BOOL( "one-instance-when-started-from-file", oneInstanceFromFile );
847 /* RECENTLY PLAYED options */
848 CONNECT( ui.saveRecentlyPlayed, toggled( bool ),
849 ui.recentlyPlayedFilters, setEnabled( bool ) );
850 ui.recentlyPlayedFilters->setEnabled( false );
851 CONFIG_BOOL( "qt-recentplay", saveRecentlyPlayed );
852 CONFIG_GENERIC( "qt-continue", IntegerList, ui.continuePlaybackLabel, continuePlaybackComboBox );
853 CONFIG_GENERIC( "qt-recentplay-filter", String, ui.filterLabel,
854 recentlyPlayedFilters );
856 END_SPREFS_CAT;
858 START_SPREFS_CAT( Subtitles,
859 qtr("Subtitle & On Screen Display Settings") );
860 CONFIG_BOOL( "osd", OSDBox);
861 CONFIG_BOOL( "video-title-show", OSDTitleBox);
862 CONFIG_GENERIC( "video-title-position", IntegerList,
863 ui.OSDTitlePosLabel, OSDTitlePos );
865 CONFIG_BOOL( "spu", spuActiveBox);
866 ui.spuZone->setEnabled( ui.spuActiveBox->isChecked() );
867 CONNECT( ui.spuActiveBox, toggled( bool ),
868 ui.spuZone, setEnabled( bool ) );
870 CONFIG_GENERIC( "subsdec-encoding", StringList, ui.encodLabel,
871 encoding );
872 CONFIG_GENERIC( "sub-language", String, ui.subLangLabel,
873 preferredLanguage );
875 CONFIG_GENERIC( "freetype-rel-fontsize", IntegerList,
876 ui.fontSizeLabel, fontSize );
878 CONFIG_GENERIC_NO_BOOL( "freetype-font", Font, ui.fontLabel, font );
879 CONFIG_GENERIC_NO_BOOL( "freetype-color", Color, ui.fontColorLabel,
880 fontColor );
881 CONFIG_GENERIC( "freetype-outline-thickness", IntegerList,
882 ui.fontEffectLabel, effect );
883 CONFIG_GENERIC_NO_BOOL( "freetype-outline-color", Color, ui.outlineColorLabel,
884 outlineColor );
886 CONFIG_GENERIC_NO_BOOL( "sub-margin", Integer, ui.subsPosLabel, subsPosition );
888 ui.shadowCheck->setChecked( config_GetInt( p_intf, "freetype-shadow-opacity" ) > 0 );
889 ui.backgroundCheck->setChecked( config_GetInt( p_intf, "freetype-background-opacity" ) > 0 );
890 optionWidgets["shadowCB"] = ui.shadowCheck;
891 optionWidgets["backgroundCB"] = ui.backgroundCheck;
893 END_SPREFS_CAT;
895 case SPrefsHotkeys:
897 p_config = config_FindConfig( VLC_OBJECT(p_intf), "key-play" );
899 QGridLayout *gLayout = new QGridLayout;
900 panel->setLayout( gLayout );
901 int line = 0;
903 panel_label->setText( qtr( "Configure Hotkeys" ) );
904 control = new KeySelectorControl( VLC_OBJECT(p_intf), p_config, this );
905 control->insertIntoExistingGrid( gLayout, line );
906 controls.append( control );
908 line++;
910 QFrame *sepline = new QFrame;
911 sepline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
912 gLayout->addWidget( sepline, line, 0, 1, -1 );
914 line++;
916 p_config = config_FindConfig( VLC_OBJECT(p_intf), "hotkeys-y-wheel-mode" );
917 control = new IntegerListConfigControl( VLC_OBJECT(p_intf),
918 p_config, this, false );
919 control->insertIntoExistingGrid( gLayout, line );
920 controls.append( control );
922 line++;
924 p_config = config_FindConfig( VLC_OBJECT(p_intf), "hotkeys-x-wheel-mode" );
925 control = new IntegerListConfigControl( VLC_OBJECT(p_intf),
926 p_config, this, false );
927 control->insertIntoExistingGrid( gLayout, line );
928 controls.append( control );
930 #ifdef _WIN32
931 line++;
933 p_config = config_FindConfig( VLC_OBJECT(p_intf), "qt-disable-volume-keys" );
934 control = new BoolConfigControl( VLC_OBJECT(p_intf), p_config, this );
935 control->insertIntoExistingGrid( gLayout, line );
936 controls.append( control );
937 #endif
939 break;
943 panel_layout->addWidget( panel_label );
944 panel_layout->addWidget( title_line );
946 QScrollArea *scroller= new QScrollArea;
947 scroller->setWidget( panel );
948 scroller->setWidgetResizable( true );
949 scroller->setFrameStyle( QFrame::NoFrame );
950 panel_layout->addWidget( scroller );
952 setLayout( panel_layout );
954 #undef END_SPREFS_CAT
955 #undef START_SPREFS_CAT
956 #undef CONFIG_GENERIC_FILE
957 #undef CONFIG_GENERIC_NO_BOOL
958 #undef CONFIG_GENERIC_NO_UI
959 #undef CONFIG_GENERIC
960 #undef CONFIG_BOOL
964 void SPrefsPanel::updateAudioOptions( int number)
966 QString value = qobject_cast<QComboBox *>(optionWidgets["audioOutCoB"])
967 ->itemData( number ).toString();
968 #ifdef _WIN32
969 optionWidgets["directxW"]->setVisible( ( value == "directsound" ) );
970 optionWidgets["directxL"]->setVisible( ( value == "directsound" ) );
971 optionWidgets["waveoutW"]->setVisible( ( value == "waveout" ) );
972 optionWidgets["waveoutL"]->setVisible( ( value == "waveout" ) );
973 #elif defined( __OS2__ )
974 optionWidgets["kaiL"]->setVisible( ( value == "kai" ) );
975 optionWidgets["kaiW"]->setVisible( ( value == "kai" ) );
976 #else
977 /* optionWidgets["ossW] can be NULL */
978 if( optionWidgets["ossW"] ) {
979 optionWidgets["ossW"]->setVisible( ( value == "oss" ) );
980 optionWidgets["ossL"]->setVisible( ( value == "oss" ) );
981 optionWidgets["ossB"]->setVisible( ( value == "oss" ) );
983 /* optionWidgets["alsaW] can be NULL */
984 if( optionWidgets["alsaW"] ) {
985 optionWidgets["alsaW"]->setVisible( ( value == "alsa" ) );
986 optionWidgets["alsaL"]->setVisible( ( value == "alsa" ) );
988 #endif
989 optionWidgets["fileW"]->setVisible( ( value == "afile" ) );
990 optionWidgets["spdifChB"]->setVisible( ( value == "alsa" || value == "oss" || value == "auhal" ||
991 value == "directsound" || value == "waveout" ) );
993 int volume = getDefaultAudioVolume(VLC_OBJECT(p_intf), qtu(value));
994 bool save = true;
996 if (volume >= 0)
997 save = config_GetInt(VLC_OBJECT(p_intf), "volume-save");
999 QCheckBox *resetVolumeCheckBox =
1000 qobject_cast<QCheckBox *>(optionWidgets["resetVolumeCheckbox"]);
1001 resetVolumeCheckBox->setChecked(!save);
1002 resetVolumeCheckBox->setEnabled(volume >= 0);
1004 QSlider *defaultVolume =
1005 qobject_cast<QSlider *>(optionWidgets["defaultVolume"]);
1006 defaultVolume->setValue((volume >= 0) ? volume : 100);
1007 defaultVolume->setEnabled(volume >= 0);
1011 SPrefsPanel::~SPrefsPanel()
1013 qDeleteAll( controls ); controls.clear();
1014 free( lang );
1017 void SPrefsPanel::updateAudioVolume( int volume )
1019 qobject_cast<QSpinBox *>(optionWidgets["volLW"])
1020 ->setValue( volume );
1024 /* Function called from the main Preferences dialog on each SPrefs Panel */
1025 void SPrefsPanel::apply()
1027 /* Generic save for ever panel */
1028 QList<ConfigControl *>::const_iterator i;
1029 for( i = controls.begin() ; i != controls.end() ; ++i )
1031 ConfigControl *c = qobject_cast<ConfigControl *>(*i);
1032 c->doApply();
1035 switch( number )
1037 case SPrefsInputAndCodecs:
1039 /* Device default selection */
1040 QByteArray devicepath =
1041 qobject_cast<QComboBox *>(optionWidgets["inputLE"])->currentText().toUtf8();
1042 if( devicepath.size() > 0 )
1044 config_PutPsz( p_intf, "dvd", devicepath );
1045 config_PutPsz( p_intf, "vcd", devicepath );
1046 config_PutPsz( p_intf, "cd-audio", devicepath );
1049 #define CaC( name, factor ) config_PutInt( p_intf, name, i_comboValue * factor )
1050 /* Caching */
1051 QComboBox *cachingCombo = qobject_cast<QComboBox *>(optionWidgets["cachingCoB"]);
1052 int i_comboValue = cachingCombo->itemData( cachingCombo->currentIndex() ).toInt();
1053 if( i_comboValue )
1055 CaC( "file-caching", 1 );
1056 CaC( "network-caching", 10/3 );
1057 CaC( "disc-caching", 1 );
1058 CaC( "live-caching", 1 );
1060 break;
1061 #undef CaC
1064 /* Interfaces */
1065 case SPrefsInterface:
1067 if( qobject_cast<QRadioButton *>(optionWidgets["skinRB"])->isChecked() )
1068 config_PutPsz( p_intf, "intf", "skins2,any" );
1069 else
1070 //if( qobject_cast<QRadioButton *>(optionWidgets[qtRB])->isChecked() )
1071 config_PutPsz( p_intf, "intf", "" );
1072 if( qobject_cast<QComboBox *>(optionWidgets["styleCB"]) )
1073 getSettings()->setValue( "MainWindow/QtStyle",
1074 qobject_cast<QComboBox *>(optionWidgets["styleCB"])->currentText() );
1075 #ifdef _WIN32
1076 saveLang();
1077 #endif
1078 break;
1081 case SPrefsAudio:
1083 bool b_checked =
1084 qobject_cast<QCheckBox *>(optionWidgets["normalizerChB"])->isChecked();
1085 if( b_checked && !qs_filter.contains( "normvol" ) )
1086 qs_filter.append( "normvol" );
1087 if( !b_checked && qs_filter.contains( "normvol" ) )
1088 qs_filter.removeAll( "normvol" );
1090 b_checked =
1091 qobject_cast<QCheckBox *>(optionWidgets["headphoneB"])->isChecked();
1093 if( b_checked && !qs_filter.contains( "headphone" ) )
1094 qs_filter.append( "headphone" );
1095 if( !b_checked && qs_filter.contains( "headphone" ) )
1096 qs_filter.removeAll( "headphone" );
1098 config_PutPsz( p_intf, "audio-filter", qtu( qs_filter.join( ":" ) ) );
1100 /* Default volume */
1101 int i_volume =
1102 qobject_cast<QSlider *>(optionWidgets["defaultVolume"])->value();
1103 bool b_reset_volume =
1104 qobject_cast<QCheckBox *>(optionWidgets["resetVolumeCheckbox"])->isChecked();
1105 char *psz_aout = config_GetPsz( p_intf, "aout" );
1107 float f_gain = powf( i_volume / 100.f, 3 );
1109 #define save_vol_aout( name ) \
1110 module_exists( name ) && ( !psz_aout || !strcmp( psz_aout, name ) || !strcmp( psz_aout, "any" ) )
1112 //FIXME this is moot
1113 #if defined( _WIN32 )
1114 VLC_UNUSED( f_gain );
1115 if( save_vol_aout( "directsound" ) )
1116 config_PutFloat( p_intf, "directx-volume", i_volume / 100.f );
1117 if( save_vol_aout( "waveout" ) )
1118 config_PutFloat( p_intf, "waveout-volume", i_volume / 100.f );
1119 #elif defined( Q_OS_MAC )
1120 VLC_UNUSED( f_gain );
1121 if( save_vol_aout( "auhal" ) )
1122 config_PutFloat( p_intf, "auhal-volume", i_volume / 100.f
1123 * AOUT_VOLUME_DEFAULT );
1124 #elif defined( __OS2__ )
1125 if( save_vol_aout( "kai" ) )
1126 config_PutFloat( p_intf, "kai-gain", f_gain );
1127 #else
1128 if( save_vol_aout( "alsa" ) )
1129 config_PutFloat( p_intf, "alsa-gain", f_gain );
1130 if( save_vol_aout( "jack" ) )
1131 config_PutFloat( p_intf, "jack-gain", f_gain );
1132 #endif
1133 #undef save_vol_aout
1134 free( psz_aout );
1136 config_PutInt( p_intf, "volume-save", !b_reset_volume );
1138 break;
1140 case SPrefsSubtitles:
1142 bool b_checked = qobject_cast<QCheckBox *>(optionWidgets["shadowCB"])->isChecked();
1143 if( b_checked && config_GetInt( p_intf, "freetype-shadow-opacity" ) == 0 ) {
1144 config_PutInt( p_intf, "freetype-shadow-opacity", 128 );
1146 else if (!b_checked ) {
1147 config_PutInt( p_intf, "freetype-shadow-opacity", 0 );
1150 b_checked = qobject_cast<QCheckBox *>(optionWidgets["backgroundCB"])->isChecked();
1151 if( b_checked && config_GetInt( p_intf, "freetype-background-opacity" ) == 0 ) {
1152 config_PutInt( p_intf, "freetype-background-opacity", 128 );
1154 else if (!b_checked ) {
1155 config_PutInt( p_intf, "freetype-background-opacity", 0 );
1162 void SPrefsPanel::clean()
1165 void SPrefsPanel::lastfm_Changed( int i_state )
1167 if( i_state == Qt::Checked )
1168 config_AddIntf( VLC_OBJECT( p_intf ), "audioscrobbler" );
1169 else if( i_state == Qt::Unchecked )
1170 config_RemoveIntf( VLC_OBJECT( p_intf ), "audioscrobbler" );
1173 void SPrefsPanel::changeStyle( QString s_style )
1175 QApplication::setStyle( s_style );
1177 /* force refresh on all widgets */
1178 QWidgetList widgets = QApplication::allWidgets();
1179 QWidgetList::iterator it = widgets.begin();
1180 while( it != widgets.end() ) {
1181 (*it)->update();
1182 ++it;
1186 void SPrefsPanel::langChanged( int i )
1188 free( lang );
1189 lang = strdup( ppsz_language[i] );
1192 void SPrefsPanel::configML()
1194 #ifdef SQL_MEDIA_LIBRARY
1195 MLConfDialog *mld = new MLConfDialog( this, p_intf );
1196 mld->exec();
1197 delete mld;
1198 #endif
1201 #ifdef _WIN32
1202 #include <QDialogButtonBox>
1203 #include "util/registry.hpp"
1205 void SPrefsPanel::cleanLang() {
1206 QVLCRegistry qvReg( HKEY_CURRENT_USER );
1207 qvReg.DeleteValue( "Software\\VideoLAN\\VLC\\", "Lang" );
1208 qvReg.DeleteKey( "Software\\VideoLAN\\", "VLC" );
1209 qvReg.DeleteKey( "Software\\", "VideoLAN" );
1212 void SPrefsPanel::saveLang() {
1213 if( !lang ) return;
1215 if( !strncmp( lang, "auto", 4 ) ) {
1216 cleanLang();
1218 else
1220 QVLCRegistry qvReg( HKEY_CURRENT_USER );
1221 qvReg.WriteRegistry( "Software\\VideoLAN\\VLC\\", "Lang", lang );
1225 bool SPrefsPanel::addType( const char * psz_ext, QTreeWidgetItem* current,
1226 QTreeWidgetItem* parent, QVLCRegistry *qvReg )
1228 bool b_temp;
1229 const char* psz_VLC = "VLC";
1230 current = new QTreeWidgetItem( parent, QStringList( psz_ext ) );
1232 if( strstr( qvReg->ReadRegistry( psz_ext, "", "" ), psz_VLC ) )
1234 current->setCheckState( 0, Qt::Checked );
1235 b_temp = true;
1237 else
1239 current->setCheckState( 0, Qt::Unchecked );
1240 b_temp = false;
1242 listAsso.append( current );
1243 return b_temp;
1246 #if !defined(__IApplicationAssociationRegistrationUI_INTERFACE_DEFINED__)
1247 #define __IApplicationAssociationRegistrationUI_INTERFACE_DEFINED__
1248 const GUID IID_IApplicationAssociationRegistrationUI = {0x1f76a169,0xf994,0x40ac, {0x8f,0xc8,0x09,0x59,0xe8,0x87,0x47,0x10}};
1249 extern const GUID CLSID_ApplicationAssociationRegistrationUI;
1250 interface IApplicationAssociationRegistrationUI : public IUnknown
1252 virtual HRESULT STDMETHODCALLTYPE LaunchAdvancedAssociationUI(
1253 LPCWSTR pszAppRegName) = 0;
1255 #endif /* __IApplicationAssociationRegistrationUI_INTERFACE_DEFINED__ */
1257 void SPrefsPanel::assoDialog()
1259 HRESULT hr;
1261 hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
1262 if( SUCCEEDED(hr) )
1264 void *p;
1266 hr = CoCreateInstance(CLSID_ApplicationAssociationRegistrationUI,
1267 NULL, CLSCTX_INPROC_SERVER,
1268 IID_IApplicationAssociationRegistrationUI, &p);
1269 if( SUCCEEDED(hr) )
1271 IApplicationAssociationRegistrationUI *p_regui =
1272 (IApplicationAssociationRegistrationUI *)p;
1274 hr = p_regui->LaunchAdvancedAssociationUI(L"VLC" );
1275 p_regui->Release();
1277 CoUninitialize();
1280 if( SUCCEEDED(hr) )
1281 return;
1283 QDialog *d = new QDialog( this );
1284 d->setWindowTitle( qtr( "File associations" ) );
1285 QGridLayout *assoLayout = new QGridLayout( d );
1287 QTreeWidget *filetypeList = new QTreeWidget;
1288 assoLayout->addWidget( filetypeList, 0, 0, 1, 4 );
1289 filetypeList->header()->hide();
1291 QVLCRegistry qvReg( HKEY_CLASSES_ROOT );
1293 QTreeWidgetItem *audioType = new QTreeWidgetItem( QStringList( qtr( "Audio Files" ) ) );
1294 QTreeWidgetItem *videoType = new QTreeWidgetItem( QStringList( qtr( "Video Files" ) ) );
1295 QTreeWidgetItem *otherType = new QTreeWidgetItem( QStringList( qtr( "Playlist Files" ) ) );
1297 filetypeList->addTopLevelItem( audioType );
1298 filetypeList->addTopLevelItem( videoType );
1299 filetypeList->addTopLevelItem( otherType );
1301 audioType->setExpanded( true ); audioType->setCheckState( 0, Qt::Unchecked );
1302 videoType->setExpanded( true ); videoType->setCheckState( 0, Qt::Unchecked );
1303 otherType->setExpanded( true ); otherType->setCheckState( 0, Qt::Unchecked );
1305 QTreeWidgetItem *currentItem = NULL;
1307 int i_temp = 0;
1308 #define aTa( name ) i_temp += addType( name, currentItem, audioType, &qvReg )
1309 #define aTv( name ) i_temp += addType( name, currentItem, videoType, &qvReg )
1310 #define aTo( name ) i_temp += addType( name, currentItem, otherType, &qvReg )
1312 aTa( ".3ga" ); aTa( ".669" ); aTa( ".a52" ); aTa( ".aac" ); aTa( ".ac3" );
1313 aTa( ".adt" ); aTa( ".adts" ); aTa( ".aif" ); aTa( ".aifc" ); aTa( ".aiff" );
1314 aTa( ".au" ); aTa( ".amr" ); aTa( ".aob" ); aTa( ".ape" ); aTa( ".caf" );
1315 aTa( ".cda" ); aTa( ".dts" ); aTa( ".flac" ); aTa( ".it" ); aTa( ".m4a" );
1316 aTa( ".m4p" ); aTa( ".mid" ); aTa( ".mka" ); aTa( ".mlp" ); aTa( ".mod" );
1317 aTa( ".mp1" ); aTa( ".mp2" ); aTa( ".mp3" ); aTa( ".mpc" ); aTa( ".mpga" );
1318 aTa( ".oga" ); aTa( ".oma" ); aTa( ".opus" ); aTa( ".qcp" ); aTa( ".ra" );
1319 aTa( ".rmi" ); aTa( ".snd" ); aTa( ".s3m" ); aTa( ".spx" ); aTa( ".tta" );
1320 aTa( ".voc" ); aTa( ".vqf" ); aTa( ".w64" ); aTa( ".wav" ); aTa( ".wma" );
1321 aTa( ".wv" ); aTa( ".xa" ); aTa( ".xm" );
1322 audioType->setCheckState( 0, ( i_temp > 0 ) ?
1323 ( ( i_temp == audioType->childCount() ) ?
1324 Qt::Checked : Qt::PartiallyChecked )
1325 : Qt::Unchecked );
1327 i_temp = 0;
1328 aTv( ".3g2" ); aTv( ".3gp" ); aTv( ".3gp2" ); aTv( ".3gpp" ); aTv( ".amv" );
1329 aTv( ".asf" ); aTv( ".avi" ); aTv( ".bik" ); aTv( ".divx" ); aTv( ".drc" );
1330 aTv( ".dv" ); aTv( ".f4v" ); aTv( ".flv" ); aTv( ".gvi" ); aTv( ".gxf" );
1331 aTv( ".m1v" ); aTv( ".m2t" ); aTv( ".m2v" ); aTv( ".m2ts" ); aTv( ".m4v" );
1332 aTv( ".mkv" ); aTv( ".mov" ); aTv( ".mp2v" ); aTv( ".mp4" ); aTv( ".mp4v" );
1333 aTv( ".mpa" ); aTv( ".mpe" ); aTv( ".mpeg" ); aTv( ".mpeg1" ); aTv( ".mpeg2" );
1334 aTv( ".mpeg4" ); aTv( ".mpg" ); aTv( ".mpv2" ); aTv( ".mts" ); aTv( ".mtv" );
1335 aTv( ".mxf" ); aTv( ".nsv" ); aTv( ".nuv" ); aTv( ".ogg" ); aTv( ".ogm" );
1336 aTv( ".ogx" ); aTv( ".ogv" ); aTv( ".rec" ); aTv( ".rm" ); aTv( ".rmvb" );
1337 aTv( ".rpl" ); aTv( ".thp" ); aTv( ".tod" ); aTv( ".ts" ); aTv( ".tts" );
1338 aTv( ".vob" ); aTv( ".vro" ); aTv( ".webm" ); aTv( ".wmv" ); aTv( ".xesc" );
1339 videoType->setCheckState( 0, ( i_temp > 0 ) ?
1340 ( ( i_temp == videoType->childCount() ) ?
1341 Qt::Checked : Qt::PartiallyChecked )
1342 : Qt::Unchecked );
1344 i_temp = 0;
1345 aTo( ".asx" ); aTo( ".b4s" ); aTo( ".cue" ); aTo( ".ifo" ); aTo( ".m3u" );
1346 aTo( ".m3u8" ); aTo( ".pls" ); aTo( ".ram" ); aTo( ".sdp" ); aTo( ".vlc" );
1347 aTo( ".wvx" ); aTo( ".xspf" );
1348 otherType->setCheckState( 0, ( i_temp > 0 ) ?
1349 ( ( i_temp == otherType->childCount() ) ?
1350 Qt::Checked : Qt::PartiallyChecked )
1351 : Qt::Unchecked );
1353 #undef aTo
1354 #undef aTv
1355 #undef aTa
1357 CONNECT( filetypeList, itemChanged(QTreeWidgetItem*, int), this, updateCheckBoxes(QTreeWidgetItem*, int) );
1359 QDialogButtonBox *buttonBox = new QDialogButtonBox( d );
1360 QPushButton *closeButton = new QPushButton( qtr( "&Apply" ) );
1361 QPushButton *clearButton = new QPushButton( qtr( "&Cancel" ) );
1362 buttonBox->addButton( closeButton, QDialogButtonBox::AcceptRole );
1363 buttonBox->addButton( clearButton, QDialogButtonBox::ActionRole );
1365 assoLayout->addWidget( buttonBox, 1, 2, 1, 2 );
1367 CONNECT( closeButton, clicked(), this, saveAsso() );
1368 CONNECT( clearButton, clicked(), d, reject() );
1369 d->resize( 300, 400 );
1370 d->exec();
1371 listAsso.clear();
1374 void SPrefsPanel::updateCheckBoxes(QTreeWidgetItem* item, int column)
1376 if( column != 0 )
1377 return;
1379 /* temporarily block signals to avoid signal loops */
1380 bool b_signalsBlocked = item->treeWidget()->blockSignals(true);
1382 /* A parent checkbox was changed */
1383 if( item->parent() == 0 )
1385 Qt::CheckState checkState = item->checkState(0);
1386 for( int i = 0; i < item->childCount(); i++ )
1388 item->child(i)->setCheckState(0, checkState);
1392 /* A child checkbox was changed */
1393 else
1395 bool b_diff = false;
1396 for( int i = 0; i < item->parent()->childCount(); i++ )
1398 if( i != item->parent()->indexOfChild(item) && item->checkState(0) != item->parent()->child(i)->checkState(0) )
1400 b_diff = true;
1401 break;
1405 if( b_diff )
1406 item->parent()->setCheckState(0, Qt::PartiallyChecked);
1407 else
1408 item->parent()->setCheckState(0, item->checkState(0));
1411 /* Stop signal blocking */
1412 item->treeWidget()->blockSignals(b_signalsBlocked);
1415 void addAsso( QVLCRegistry *qvReg, const char *psz_ext )
1417 QString s_path( "VLC" ); s_path += psz_ext;
1418 QString s_path2 = s_path;
1420 /* Save a backup if already assigned */
1421 char *psz_value = qvReg->ReadRegistry( psz_ext, "", "" );
1423 if( !EMPTY_STR(psz_value) && strcmp( qtu(s_path), psz_value ) )
1424 qvReg->WriteRegistry( psz_ext, "VLC.backup", psz_value );
1425 free( psz_value );
1427 /* Put a "link" to VLC.EXT as default */
1428 qvReg->WriteRegistry( psz_ext, "", qtu( s_path ) );
1430 /* Create the needed Key if they weren't done in the installer */
1431 if( !qvReg->RegistryKeyExists( qtu( s_path ) ) )
1433 qvReg->WriteRegistry( psz_ext, "", qtu( s_path ) );
1434 qvReg->WriteRegistry( qtu( s_path ), "", "Media file" );
1435 qvReg->WriteRegistry( qtu( s_path.append( "\\shell" ) ), "", "Play" );
1437 /* Get the installer path */
1438 QVLCRegistry qvReg2( HKEY_LOCAL_MACHINE );
1439 QString str_temp = qvReg2.ReadRegistry( "Software\\VideoLAN\\VLC", "", "" );
1441 if( str_temp.size() )
1443 qvReg->WriteRegistry( qtu( s_path.append( "\\Play\\command" ) ),
1444 "", qtu( str_temp.append(" --started-from-file \"%1\"" ) ) );
1446 qvReg->WriteRegistry( qtu( s_path2.append( "\\DefaultIcon" ) ),
1447 "", qtu( str_temp.append(",0") ) );
1452 void delAsso( QVLCRegistry *qvReg, const char *psz_ext )
1454 QString s_path( "VLC"); s_path += psz_ext;
1455 char *psz_value = qvReg->ReadRegistry( psz_ext, "", "" );
1457 if( psz_value && !strcmp( qtu(s_path), psz_value ) )
1459 free( psz_value );
1460 psz_value = qvReg->ReadRegistry( psz_ext, "VLC.backup", "" );
1461 if( psz_value )
1462 qvReg->WriteRegistry( psz_ext, "", psz_value );
1464 qvReg->DeleteValue( psz_ext, "VLC.backup" );
1466 free( psz_value );
1469 void SPrefsPanel::saveAsso()
1471 QVLCRegistry qvReg( HKEY_CLASSES_ROOT );
1472 for( int i = 0; i < listAsso.size(); i ++ )
1474 if( listAsso[i]->checkState( 0 ) > 0 )
1476 addAsso( &qvReg, qtu( listAsso[i]->text( 0 ) ) );
1478 else
1480 delAsso( &qvReg, qtu( listAsso[i]->text( 0 ) ) );
1483 /* Gruik ? Naaah */
1484 qobject_cast<QDialog *>(listAsso[0]->treeWidget()->parent())->accept();
1487 #endif /* _WIN32 */