Header cleanup
[amarok.git] / src / configdialog.cpp
blobb5aa45a34a698a5e8aa2a9520ca353553afe7533
1 /***************************************************************************
2 begin : 2004/02/07
3 copyright : (C) Mark Kretschmann
4 email : markey@web.de
5 ***************************************************************************/
7 /***************************************************************************
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 ***************************************************************************/
16 #include "amarok.h"
17 #include "amarokconfig.h"
18 #include "app.h"
19 #include "collectiondb.h"
20 #include "config.h" // Has USE_MYSQL
21 #include "configdialog.h"
22 #include "contextbrowser.h"
23 #include "dbsetup.h"
24 #include "debug.h"
25 #include "directorylist.h"
26 #include "enginecontroller.h"
27 #include "mediabrowser.h"
28 #include "mediumpluginmanager.h"
29 #include "Options1.h"
30 #include "Options2.h"
31 #include "Options4.h"
32 #include "Options5.h"
33 #include "Options7.h"
34 #include "Options8.h"
35 #include "osd.h"
36 #include "playlistwindow.h"
37 #include "plugin/pluginconfig.h"
38 #include "pluginmanager.h"
40 #include <q3groupbox.h>
41 #include <QLabel>
42 #include <QLayout>
43 #include <QLineEdit>
44 #include <QMessageBox>
45 #include <QObject>
46 #include <QPushButton>
47 #include <QRadioButton>
48 #include <qspinbox.h>
49 #include <QTextCodec>
50 #include <QToolTip>
51 #include <kvbox.h>
52 //Added by qt3to4:
53 #include <QByteArray>
54 #include <QPixmap>
56 #include <kapplication.h> //kapp
57 #include <kcombobox.h>
58 #include <kiconloader.h>
59 #include <klineedit.h>
60 #include <klocale.h>
61 #include <kpushbutton.h>
62 #include <kstandarddirs.h>
65 #undef Q_WS_X11 //HACK: The OSD is broken anyway
68 namespace Amarok {
69 int databaseTypeCode( const QString type )
71 // can't use kconfigxt for the database comboxbox since we need the DBConnection id and not the index
72 int dbType = DbConnection::sqlite;
73 if ( type == "MySQL")
74 dbType = DbConnection::mysql;
75 else if ( type == "Postgresql" )
76 dbType = DbConnection::postgresql;
77 return dbType;
82 //////////////////////////////////////////////////////////////////////////////////////////
83 // PUBLIC
84 //////////////////////////////////////////////////////////////////////////////////////////
86 AmarokConfigDialog::AmarokConfigDialog( QWidget *parent, const char* name, KConfigSkeleton *config )
87 : KConfigDialog( parent, name, config )
88 , m_engineConfig( 0 )
89 , m_opt4( 0 )
91 setAttribute( Qt::WA_DeleteOnClose );
93 // IMPORTANT Don't simply change the page names, they are used as identifiers in other parts of the app.
94 m_opt1 = new Options1( 0, "General" );
95 #ifdef Q_WS_MAC
96 m_opt1->kcfg_ShowSplashscreen->setEnabled(false);
97 m_opt1->kcfg_ShowTrayIcon->setEnabled(false);
98 m_opt1->kcfg_AnimateTrayIcon->setEnabled(false);
99 #endif
100 m_opt2 = new Options2( 0, "Appearance" );
101 m_opt4 = new Options4( 0, "Playback" );
102 #ifdef Q_WS_X11
103 Options5 *opt5 = new Options5( 0, "OSD" );
104 #endif
105 KVBox *opt6 = new KVBox;
106 m_opt7 = new Options7( 0, "Collection" );
107 Options8 *opt8 = new Options8( 0, "Scrobbler" );
108 KVBox *opt9 = new KVBox;
110 // Sound System
111 opt6->setObjectName( "Engine" );
112 opt6->setSpacing( KDialog::spacingHint() );
113 QWidget *groupBox, *aboutEngineButton;
114 groupBox = new Q3GroupBox( 2, Qt::Horizontal, i18n("Sound System"), opt6 );
115 m_engineConfigFrame = new Q3GroupBox( 1, Qt::Horizontal, opt6 );
116 m_soundSystem = new QComboBox;
117 m_soundSystem->setParent( groupBox );
118 aboutEngineButton = new QPushButton( i18n("About"), groupBox );
120 m_soundSystem->setToolTip( i18n("Click to select the sound system to use for playback.") );
121 aboutEngineButton->setToolTip( i18n("Click to get the plugin information.") );
123 /// Populate the engine selection combo box
124 KService::List offers = PluginManager::query( "[X-KDE-Amarok-plugintype] == 'engine'" );
125 KService::List::ConstIterator end( offers.end() );
126 for( KService::List::ConstIterator it = offers.begin(); it != end; ++it ) {
127 // Don't list the <no engine> (void engine) entry if it's not currently active,
128 // cause there's no point in choosing this engine (it's a dummy, after all).
129 if( (*it)->property( "X-KDE-Amarok-name" ).toString() == "void-engine"
130 && AmarokConfig::soundSystem() != "void-engine" ) continue;
132 m_soundSystem->addItem( (*it)->name() );
133 // Save name properties in QMap for lookup
134 m_pluginName[(*it)->name()] = (*it)->property( "X-KDE-Amarok-name" ).toString();
135 m_pluginAmarokName[(*it)->property( "X-KDE-Amarok-name" ).toString()] = (*it)->name();
138 // Collection
139 #if !defined(USE_MYSQL) && !defined(USE_POSTGRESQL)
140 m_opt7->databaseBox->hide();
141 #endif
143 #ifndef USE_MYSQL
144 //FIXME we do this because this widget breaks the Apply button (always enabled).
145 //It breaks because it is set to type="password" in the .kcfg file. Setting to
146 //type="string" also fixes this bug, but means the password is stored in plain
147 //text. This is a temporary fix so that the majority of users get a fixed Apply
148 //button.
149 delete m_opt7->dbSetupFrame->kcfg_MySqlPassword2;
150 #endif
151 m_opt7->collectionFoldersBox->setColumns( 1 );
152 new CollectionSetup( m_opt7->collectionFoldersBox ); //TODO this widget doesn't update the apply/ok buttons
154 // Media Devices
155 opt9->setObjectName( "Media Devices" );
156 opt9->setSpacing( KDialog::spacingHint() );
157 KVBox *topbox = new KVBox( opt9 );
158 topbox->setSpacing( KDialog::spacingHint() );
159 Q3GroupBox *mediaBox = new Q3GroupBox( 2, Qt::Horizontal, i18n("Media Devices"), topbox );
160 mediaBox->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum );
161 KVBox *vbox = new KVBox( mediaBox );
162 vbox->setSpacing( KDialog::spacingHint() );
163 m_deviceManager = new MediumPluginManager( vbox );
165 KHBox *hbox = new KHBox( topbox );
166 hbox->setSpacing( KDialog::spacingHint() );
167 hbox->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum );
168 KPushButton *autodetect = new KPushButton( i18n( "Autodetect Devices" ), hbox );
169 autodetect->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
170 connect( autodetect, SIGNAL(clicked()), m_deviceManager, SLOT(redetectDevices()) );
171 KPushButton *add = new KPushButton( i18n( "Add Device..." ), hbox );
172 add->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
173 connect( add, SIGNAL(clicked()), m_deviceManager, SLOT(newDevice()) );
175 QFrame *frame = new QFrame( topbox );
176 frame->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
178 // add pages
179 addPage( m_opt1, i18n( "General" ), Amarok::icon( "settings_general" ), i18n( "Configure General Options" ) );
180 addPage( m_opt2, i18n( "Appearance" ), Amarok::icon( "settings_view" ), i18n( "Configure Amarok's Appearance" ) );
181 addPage( m_opt4, i18n( "Playback" ), Amarok::icon( "settings_playback" ), i18n( "Configure Playback" ) );
182 #ifdef Q_WS_X11
183 addPage( opt5, i18n( "OSD" ), Amarok::icon( "settings_indicator" ), i18n( "Configure On-Screen-Display" ) );
184 #endif
185 addPage( opt6, i18n( "Engine" ), Amarok::icon( "settings_engine" ), i18n( "Configure Engine" ) );
186 addPage( m_opt7, i18n( "Collection" ), Amarok::icon( "collection" ), i18n( "Configure Collection" ) );
187 addPage( opt8, i18n( "last.fm" ), Amarok::icon( "audioscrobbler" ), i18n( "Configure last.fm Support" ) );
188 addPage( opt9, i18n( "Media Devices" ), Amarok::icon( "device" ), i18n( "Configure Portable Player Support" ) );
190 // Show information labels (must be done after insertions)
192 QObjectList list = queryList( "QLabel", "infoPixmap" );
193 QPixmap const info = KIconLoader::global()->iconPath( "messagebox_info", -K3Icon::SizeHuge );
194 for( int labelI = 0; labelI < list.size(); labelI++ )
195 qobject_cast<QLabel*>( list.at(labelI) )->setPixmap( info );
198 //stop KFont Requesters getting stupidly large
200 QObjectList list = queryList( "QLabel", "m_sampleLabel" );
201 for( int labelI = 0; labelI < list.size(); labelI++ )
202 qobject_cast<QLabel*>( list.at( labelI ) )->setMaximumWidth( 250 );
204 connect( m_deviceManager, SIGNAL(changed()), SLOT(updateButtons()) );
205 connect( m_soundSystem, SIGNAL(activated( int )), SLOT(updateButtons()) );
206 connect( aboutEngineButton, SIGNAL(clicked()), SLOT(aboutEngine()) );
207 #ifdef Q_WS_X11
208 connect( opt5, SIGNAL(settingsChanged()), SLOT(updateButtons()) ); //see options5.ui.h
209 #endif
210 connect( m_opt2->styleComboBox, SIGNAL( activated( int ) ), SLOT( updateButtons() ) );
211 connect( m_opt7->dbSetupFrame->databaseEngine, SIGNAL( activated( int ) ), SLOT( updateButtons() ) );
212 connect( m_opt1->kComboBox_browser, SIGNAL( activated( int ) ), SLOT( updateButtons() ) );
213 connect( m_opt1->kLineEdit_customBrowser, SIGNAL( textChanged( const QString& ) ), SLOT( updateButtons() ) );
216 AmarokConfigDialog::~AmarokConfigDialog()
218 DEBUG_FUNC_INFO
219 delete m_engineConfig;
220 delete m_deviceManager;
224 /** Reimplemented from KConfigDialog */
225 void AmarokConfigDialog::addPage( QWidget *page, const QString &itemName, const QString &pixmapName, const QString &header, bool manage )
227 // Add the widget pointer to our list, for later reference
228 m_pageList << page;
230 KConfigDialog::addPage( page, itemName, pixmapName, header, manage );
233 /** Show page by object name */
234 void AmarokConfigDialog::showPageByName( const QByteArray& page )
236 for( uint index = 0; index < m_pageList.count(); index++ ) {
237 if ( m_pageList[index]->name() == page ) {
238 KConfigDialog::setCurrentPage( qobject_cast<KPageWidgetItem*>( m_pageList[index] ) );
239 return;
244 //////////////////////////////////////////////////////////////////////////////////////////
245 // PROTECTED SLOTS
246 //////////////////////////////////////////////////////////////////////////////////////////
249 * Update the buttons.
250 * REIMPLEMENTED
253 void AmarokConfigDialog::updateButtons()
255 KConfigDialog::updateButtons();
259 * Update the settings from the dialog.
260 * Example use: User clicks Ok or Apply button in a configure dialog.
261 * REIMPLEMENTED
263 void AmarokConfigDialog::updateSettings()
265 #ifdef Q_WS_X11
266 OSDPreviewWidget *osd = findChild<OSDPreviewWidget*>( "osdpreview" );
267 AmarokConfig::setOsdAlignment( osd->alignment() );
268 AmarokConfig::setOsdYOffset( osd->y() );
269 Amarok::OSD::instance()->applySettings();
270 #endif
272 CollectionSetup* cs = findChild<CollectionSetup*>("CollectionSetup");
273 if ( cs ) cs->writeConfig();
275 if ( m_engineConfig ) m_engineConfig->save();
277 AmarokConfig::setExternalBrowser( externalBrowser() );
279 // When sound system has changed, update engine config page
280 if ( m_soundSystem->currentText() != m_pluginAmarokName[AmarokConfig::soundSystem()] ) {
281 AmarokConfig::setSoundSystem( m_pluginName[m_soundSystem->currentText()] );
282 emit settingsChanged( objectName() );
283 soundSystemChanged();
286 if ( m_opt2->styleComboBox->currentText() != AmarokConfig::contextBrowserStyleSheet() ) {
287 //can't use kconfigxt for the style comboxbox's since we need the string, not the index
288 AmarokConfig::setContextBrowserStyleSheet( m_opt2->styleComboBox->currentText() );
289 ContextBrowser::instance()->reloadStyleSheet();
292 int dbType = Amarok::databaseTypeCode( m_opt7->dbSetupFrame->databaseEngine->currentText() );
293 if ( dbType != AmarokConfig::databaseEngine().toInt() ) {
294 AmarokConfig::setDatabaseEngine( QString::number( dbType ) );
295 emit settingsChanged( objectName() );
298 m_deviceManager->finished();
300 if( MediaBrowser::isAvailable() )
302 PlaylistWindow::self()->addBrowser( "MediaBrowser", MediaBrowser::instance(), i18n( "Media Device" ), Amarok::icon( "device" ) );
303 //to re-enable mediabrowser hiding, uncomment this:
304 //connect( MediaBrowser::instance(), SIGNAL( availabilityChanged( bool ) ),
305 // PlaylistWindow::self(), SLOT( mbAvailabilityChanged( bool ) ) );
309 Amarok::setUseScores( m_opt1->kcfg_UseScores->isChecked() );
310 Amarok::setUseRatings( m_opt1->kcfg_UseRatings->isChecked() );
312 // The following makes everything with a moodbar redraw itself.
313 Amarok::setMoodbarPrefs( m_opt1->kcfg_ShowMoodbar->isChecked(),
314 m_opt1->kcfg_MakeMoodier->isChecked(),
315 m_opt1->kcfg_AlterMood->currentIndex(),
316 m_opt1->kcfg_MoodsWithMusic->isChecked() );
321 * Update the configuration-widgets in the dialog based on Amarok's current settings.
322 * Example use: Initialisation of dialog.
323 * Example use: User clicks Reset button in a configure dialog.
324 * REIMPLEMENTED
326 void AmarokConfigDialog::updateWidgets()
328 int current = m_soundSystem->findText( m_pluginAmarokName[AmarokConfig::soundSystem()] );
329 m_soundSystem->setCurrentIndex( current );
330 soundSystemChanged();
335 * Update the configuration-widgets in the dialog based on the default values for Amarok's settings.
336 * Example use: User clicks Defaults button in a configure dialog.
337 * REIMPLEMENTED
339 void AmarokConfigDialog::updateWidgetsDefault()
341 m_soundSystem->setCurrentIndex( 0 );
345 //////////////////////////////////////////////////////////////////////////////////////////
346 // PROTECTED
347 //////////////////////////////////////////////////////////////////////////////////////////
350 * @return true if any configuration items we are managing changed from Amarok's stored settings
351 * We manage the engine combo box and some of the OSD settings
352 * REIMPLEMENTED
354 bool AmarokConfigDialog::hasChanged()
356 #ifdef Q_WS_X11
357 OSDPreviewWidget *osd = findChild<OSDPreviewWidget*>( "osdpreview" );
358 #endif
360 return m_soundSystem->currentText() != m_pluginAmarokName[AmarokConfig::soundSystem()] ||
361 #ifdef Q_WS_X11
362 osd->alignment() != AmarokConfig::osdAlignment() ||
363 osd->alignment() != OSDWidget::Center && osd->y() != AmarokConfig::osdYOffset() ||
364 #endif
365 m_opt2->styleComboBox->currentText() != AmarokConfig::contextBrowserStyleSheet() ||
366 Amarok::databaseTypeCode( m_opt7->dbSetupFrame->databaseEngine->currentText() ) != AmarokConfig::databaseEngine().toInt() ||
367 m_engineConfig && m_engineConfig->hasChanged() ||
368 m_deviceManager && m_deviceManager->hasChanged() ||
369 externalBrowser() != AmarokConfig::externalBrowser();
373 /** REIMPLEMENTED */
374 bool AmarokConfigDialog::isDefault()
376 AMAROK_NOTIMPLEMENTED
378 //TODO hard to implement - what are default settings for OSD etc?
380 return false;
384 //////////////////////////////////////////////////////////////////////////////////////////
385 // PRIVATE SLOTS
386 //////////////////////////////////////////////////////////////////////////////////////////
388 void AmarokConfigDialog::aboutEngine() //SLOT
390 PluginManager::showAbout( QString( "Name == '%1'" ).arg( m_soundSystem->currentText() ) );
394 //////////////////////////////////////////////////////////////////////////////////////////
395 // PRIVATE
396 //////////////////////////////////////////////////////////////////////////////////////////
398 void AmarokConfigDialog::soundSystemChanged()
400 ///A new sound system has been LOADED
401 ///If only the sound system widget has been changed don't call this!
403 // remove old engine config widget
404 // will delete the view if implementation is done correctly
405 delete m_engineConfig;
407 if( EngineController::hasEngineProperty( "HasConfigure" ) )
409 m_engineConfig = EngineController::engine()->configure();
410 m_engineConfig->view()->reparent( m_engineConfigFrame, QPoint() );
411 m_engineConfig->view()->show();
412 m_engineConfigFrame->setTitle( i18nc( "to change settings", "Configure %1", m_soundSystem->currentText() ) );
413 m_engineConfigFrame->show();
415 connect( m_engineConfig, SIGNAL(viewChanged()), SLOT(updateButtons()) );
417 else {
418 m_engineConfig = 0;
419 m_engineConfigFrame->hide();
422 const bool hasCrossfade = EngineController::hasEngineProperty( "HasCrossfade" );
423 const bool crossfadeOn = m_opt4->kcfg_Crossfade->isChecked();
424 // Enable crossfading option when available
425 m_opt4->kcfg_Crossfade->setEnabled( hasCrossfade );
426 m_opt4->kcfg_CrossfadeLength->setEnabled( hasCrossfade && crossfadeOn );
427 m_opt4->crossfadeLengthLabel->setEnabled( hasCrossfade && crossfadeOn );
428 m_opt4->kcfg_CrossfadeType->setEnabled( hasCrossfade && crossfadeOn );
430 if (!hasCrossfade)
432 m_opt4->radioButtonNormalPlayback->setChecked( true );
436 QString AmarokConfigDialog::externalBrowser() const
438 return m_opt1->kComboBox_browser->isEnabled() ?
439 #ifdef Q_WS_MAC
440 m_opt1->kComboBox_browser->currentText() == i18n( "Default Browser" ) ?
441 "open" :
442 #else
443 m_opt1->kComboBox_browser->currentText() == i18n( "Default KDE Browser" ) ?
444 "kfmclient openUrl" :
445 #endif
446 m_opt1->kComboBox_browser->currentText().toLower() :
447 m_opt1->kLineEdit_customBrowser->text().toLower();
451 #include "configdialog.moc"