summaryrefslogtreecommitdiffstats
path: root/amarok/src/configdialog.cpp
blob: 8007fc7475f1e7bee62af86f0d06a4ceda3c8fd6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
/***************************************************************************
begin                : 2004/02/07
copyright            : (C) Mark Kretschmann
email                : markey@web.de
***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "amarok.h"
#include "amarokconfig.h"
#include "app.h"
#include "collectiondb.h"
#include "config.h" // Has USE_MYSQL
#include "configdialog.h"
#include "contextbrowser.h"
#include "dbsetup.h"
#include "debug.h"
#include "directorylist.h"
#include "enginecontroller.h"
#include "mediabrowser.h"
#include "mediumpluginmanager.h"
#include "Options1.h"
#include "Options2.h"
#include "Options4.h"
#include "Options5.h"
#include "Options7.h"
#include "Options8.h"
#include "osd.h"
#include "playlistwindow.h"
#include "playerwindow.h"
#include "plugin/pluginconfig.h"
#include "pluginmanager.h"

#include <tqgroupbox.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqlineedit.h>
#include <tqmessagebox.h>
#include <tqobjectlist.h>
#include <tqpushbutton.h>
#include <tqradiobutton.h>
#include <tqspinbox.h>
#include <tqtextcodec.h>
#include <tqtooltip.h>
#include <tqvbox.h>

#include <tdeapplication.h> //kapp
#include <kcombobox.h>
#include <kiconloader.h>
#include <klineedit.h>
#include <tdelocale.h>
#include <kpushbutton.h>
#include <kstandarddirs.h>

namespace Amarok {
    int databaseTypeCode( const TQString type )
    {
        // can't use tdeconfigxt for the database comboxbox since we need the DBConnection id and not the index
        int dbType = DbConnection::sqlite;
        if ( type == "MySQL")
            dbType = DbConnection::mysql;
        else if ( type == "Postgresql" )
            dbType = DbConnection::postgresql;
        return dbType;
    }
}


int AmarokConfigDialog::s_currentPage = 0;

//////////////////////////////////////////////////////////////////////////////////////////
// PUBLIC
//////////////////////////////////////////////////////////////////////////////////////////

AmarokConfigDialog::AmarokConfigDialog( TQWidget *parent, const char* name, TDEConfigSkeleton *config )
        : TDEConfigDialog( parent, name, config )
        , m_engineConfig( 0 )
        , m_opt4( 0 )
{
    setWFlags( WDestructiveClose );

    // IMPORTANT Don't simply change the page names, they are used as identifiers in other parts of the app.
            m_opt1 = new Options1( 0, "General" );
#ifdef TQ_WS_MAC
            m_opt1->kcfg_ShowSplashscreen->setEnabled(false);
            m_opt1->kcfg_ShowTrayIcon->setEnabled(false);
            m_opt1->kcfg_AnimateTrayIcon->setEnabled(false);
            m_opt1->kcfg_ShowPlayerWindow->setEnabled(false);
#endif
            m_opt2 = new Options2( 0, "Appearance" );
            m_opt4 = new Options4( 0, "Playback" );
#ifdef TQ_WS_X11
    Options5 *opt5 = new Options5( 0, "OSD" );
#endif
    TQVBox    *opt6 = new TQVBox;
            m_opt7 = new Options7( 0, "Collection" );
    Options8 *opt8 = new Options8( 0, "Scrobbler" );
    TQVBox    *opt9 = new TQVBox;

    // Sound System
    opt6->setName( "Engine" );
    opt6->setSpacing( KDialog::spacingHint() );
    TQWidget *groupBox, *aboutEngineButton;
    groupBox            = new TQGroupBox( 2, Qt::Horizontal, i18n("Sound System"), opt6 );
    m_engineConfigFrame = new TQGroupBox( 1, Qt::Horizontal, opt6 );
    m_soundSystem       = new TQComboBox( false, groupBox );
    aboutEngineButton   = new TQPushButton( i18n("About"), groupBox );

    TQToolTip::add( m_soundSystem, i18n("Click to select the sound system to use for playback.") );
    TQToolTip::add( aboutEngineButton, i18n("Click to get the plugin information.") );

    /// Populate the engine selection combo box
    TDETrader::OfferList offers = PluginManager::query( "[X-TDE-Amarok-plugintype] == 'engine'" );
    TDETrader::OfferList::ConstIterator end( offers.end() );
    for( TDETrader::OfferList::ConstIterator it = offers.begin(); it != end; ++it ) {
        // Don't list the <no engine> (void engine) entry if it's not currently active,
        // cause there's no point in choosing this engine (it's a dummy, after all).
        if( (*it)->property( "X-TDE-Amarok-name" ).toString() == "void-engine"
            && AmarokConfig::soundSystem() != "void-engine" ) continue;

        m_soundSystem->insertItem( (*it)->name() );
        // Save name properties in TQMap for lookup
        m_pluginName[(*it)->name()] = (*it)->property( "X-TDE-Amarok-name" ).toString();
        m_pluginAmarokName[(*it)->property( "X-TDE-Amarok-name" ).toString()] = (*it)->name();
    }

    // Collection
#if !defined(USE_MYSQL) && !defined(USE_POSTGRESQL)
    m_opt7->databaseBox->hide();
#endif

#ifndef USE_MYSQL
    //FIXME we do this because this widget breaks the Apply button (always enabled).
    //It breaks because it is set to type="password" in the .kcfg file. Setting to
    //type="string" also fixes this bug, but means the password is stored in plain
    //text. This is a temporary fix so that the majority of users get a fixed Apply
    //button.
    delete m_opt7->dbSetupFrame->kcfg_MySqlPassword2;
#endif
    m_opt7->collectionFoldersBox->setColumns( 1 );
    new CollectionSetup( m_opt7->collectionFoldersBox ); //TODO this widget doesn't update the apply/ok buttons

    // Media Devices
    opt9->setName( "Media Devices" );
    opt9->setSpacing( KDialog::spacingHint() );
    TQVBox *topbox = new TQVBox( opt9 );
    topbox->setSpacing( KDialog::spacingHint() );
    TQGroupBox *mediaBox  = new TQGroupBox( 2, Qt::Horizontal, i18n("Media Devices"), topbox );
    mediaBox->setSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Minimum );
    TQVBox *vbox = new TQVBox( mediaBox );
    vbox->setSpacing( KDialog::spacingHint() );
    m_deviceManager = new MediumPluginManager( vbox );

    TQHBox *hbox = new TQHBox( topbox );
    hbox->setSpacing( KDialog::spacingHint() );
    hbox->setSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Minimum );
    KPushButton *autodetect = new KPushButton( i18n( "Autodetect Devices" ), hbox );
    autodetect->setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
    connect( autodetect, TQT_SIGNAL(clicked()), m_deviceManager, TQT_SLOT(redetectDevices()) );
    KPushButton *add = new KPushButton( i18n( "Add Device..." ), hbox );
    add->setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
    connect( add, TQT_SIGNAL(clicked()), m_deviceManager, TQT_SLOT(newDevice()) );

    TQFrame *frame = new TQFrame( topbox );
    frame->setSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding );

    // add pages
    addPage( m_opt1, i18n( "General" ), Amarok::icon( "settings_general" ), i18n( "Configure General Options" ) );
    addPage( m_opt2, i18n( "Appearance" ), Amarok::icon( "settings_view" ), i18n( "Configure Amarok's Appearance" ) );
    addPage( m_opt4, i18n( "Playback" ), Amarok::icon( "settings_playback" ), i18n( "Configure Playback" ) );
#ifdef TQ_WS_X11
    addPage( opt5,   i18n( "OSD" ), Amarok::icon( "settings_indicator" ), i18n( "Configure On-Screen-Display" ) );
#endif
    addPage( opt6,   i18n( "Engine" ), Amarok::icon( "settings_engine" ), i18n( "Configure Engine" ) );
    addPage( m_opt7, i18n( "Collection" ), Amarok::icon( "collection" ), i18n( "Configure Collection" ) );
    addPage( opt8,   i18n( "last.fm" ), Amarok::icon( "audioscrobbler" ), i18n( "Configure last.fm Support" ) );
    addPage( opt9,   i18n( "Media Devices" ), Amarok::icon( "device" ), i18n( "Configure Portable Player Support" ) );

    // Show information labels (must be done after insertions)
    TQObjectList *list = queryList( TQLABEL_OBJECT_NAME_STRING, "infoPixmap" );
    TQPixmap const info = TDEGlobal::iconLoader()->iconPath( "messagebox_info", -TDEIcon::SizeHuge );
    for( TQObject *label = list->first(); label; label = list->next() )
        static_cast<TQLabel*>(TQT_TQWIDGET(label))->setPixmap( info );
    delete list;

    //stop TDEFont Requesters getting stupidly large
    list = queryList( TQLABEL_OBJECT_NAME_STRING, "m_sampleLabel" );
    for( TQObject *label = list->first(); label; label = list->next() )
        static_cast<TQLabel*>(TQT_TQWIDGET(label))->setMaximumWidth( 250 );
    delete list;

    connect( m_deviceManager, TQT_SIGNAL(changed()), TQT_SLOT(updateButtons()) );
    connect( m_soundSystem, TQT_SIGNAL(activated( int )), TQT_SLOT(updateButtons()) );
    connect( aboutEngineButton, TQT_SIGNAL(clicked()), TQT_SLOT(aboutEngine()) );
#ifdef TQ_WS_X11
    connect( opt5, TQT_SIGNAL(settingsChanged()), TQT_SLOT(updateButtons()) ); //see options5.ui.h
#endif
    connect( m_opt2->styleComboBox, TQT_SIGNAL( activated( int ) ), TQT_SLOT( updateButtons() ) );
    connect( m_opt7->dbSetupFrame->databaseEngine, TQT_SIGNAL( activated( int ) ), TQT_SLOT( updateButtons() ) );
    connect( m_opt1->kComboBox_browser, TQT_SIGNAL( activated( int ) ), TQT_SLOT( updateButtons() ) );
    connect( m_opt1->kLineEdit_customBrowser, TQT_SIGNAL( textChanged( const TQString& ) ), TQT_SLOT( updateButtons() ) );
}

AmarokConfigDialog::~AmarokConfigDialog()
{
    DEBUG_FUNC_INFO

    s_currentPage = activePageIndex();

    delete m_engineConfig;
    delete m_deviceManager;
}


/** Reimplemented from TDEConfigDialog */
void AmarokConfigDialog::addPage( TQWidget *page, const TQString &itemName, const TQString &pixmapName, const TQString &header, bool manage )
{
    // Add the widget pointer to our list, for later reference
    m_pageList << page;

    TDEConfigDialog::addPage( page, itemName, pixmapName, header, manage );
}


/** Show page by object name */
void AmarokConfigDialog::showPageByName( const TQCString& page )
{
    for( uint index = 0; index < m_pageList.count(); index++ ) {
        if ( m_pageList[index]->name() == page ) {
            TDEConfigDialog::showPage( index );
            return;
        }
    }
}


//////////////////////////////////////////////////////////////////////////////////////////
// PROTECTED SLOTS
//////////////////////////////////////////////////////////////////////////////////////////

/**
 * Update the buttons.
 * REIMPLEMENTED
 */

void AmarokConfigDialog::updateButtons()
{
    TDEConfigDialog::updateButtons();
}

/**
 * Update the settings from the dialog.
 * Example use: User clicks Ok or Apply button in a configure dialog.
 * REIMPLEMENTED
 */
void AmarokConfigDialog::updateSettings()
{
#ifdef TQ_WS_X11
    OSDPreviewWidget *osd = static_cast<OSDPreviewWidget*>( TQT_TQWIDGET(child( "osdpreview" )) );
    AmarokConfig::setOsdAlignment( osd->alignment() );
    AmarokConfig::setOsdYOffset( osd->y() );
    Amarok::OSD::instance()->applySettings();
#endif

    static_cast<CollectionSetup*>(TQT_TQWIDGET(child("CollectionSetup")))->writeConfig();

    if ( m_engineConfig ) m_engineConfig->save();

    AmarokConfig::setExternalBrowser( externalBrowser() );

    // When sound system has changed, update engine config page
    if ( m_soundSystem->currentText() != m_pluginAmarokName[AmarokConfig::soundSystem()] ) {
        AmarokConfig::setSoundSystem( m_pluginName[m_soundSystem->currentText()] );
        emit settingsChanged();
        soundSystemChanged();
    }

    if ( m_opt2->styleComboBox->currentText() != AmarokConfig::contextBrowserStyleSheet() ) {
        //can't use tdeconfigxt for the style comboxbox's since we need the string, not the index
        AmarokConfig::setContextBrowserStyleSheet( m_opt2->styleComboBox->currentText() );
        ContextBrowser::instance()->reloadStyleSheet();
    }

    int dbType = Amarok::databaseTypeCode( m_opt7->dbSetupFrame->databaseEngine->currentText() );
    if ( dbType != AmarokConfig::databaseEngine().toInt() ) {
        AmarokConfig::setDatabaseEngine( TQString::number( dbType ) );
        emit settingsChanged();
    }

    m_deviceManager->finished();

    if( MediaBrowser::isAvailable() )
    {
        PlaylistWindow::self()->addBrowser( "MediaBrowser", MediaBrowser::instance(), i18n( "Media Device" ), Amarok::icon( "device" ) );
        //to re-enable mediabrowser hiding, uncomment this:
        //connect( MediaBrowser::instance(), TQT_SIGNAL( availabilityChanged( bool ) ),
        //         PlaylistWindow::self(), TQT_SLOT( mbAvailabilityChanged( bool ) ) );

    }

    Amarok::setUseScores( m_opt1->kcfg_UseScores->isChecked() );
    Amarok::setUseRatings( m_opt1->kcfg_UseRatings->isChecked() );

    // The following makes everything with a moodbar redraw itself.
    Amarok::setMoodbarPrefs( m_opt1->kcfg_ShowMoodbar->isChecked(),
                             m_opt1->kcfg_MakeMoodier->isChecked(),
                             m_opt1->kcfg_AlterMood->currentItem(),
                             m_opt1->kcfg_MoodsWithMusic->isChecked() );
}


/**
 * Update the configuration-widgets in the dialog based on Amarok's current settings.
 * Example use: Initialisation of dialog.
 * Example use: User clicks Reset button in a configure dialog.
 * REIMPLEMENTED
 */
void AmarokConfigDialog::updateWidgets()
{
    m_soundSystem->setCurrentText( m_pluginAmarokName[AmarokConfig::soundSystem()] );
    soundSystemChanged();
}


/**
 * Update the configuration-widgets in the dialog based on the default values for Amarok's settings.
 * Example use: User clicks Defaults button in a configure dialog.
 * REIMPLEMENTED
 */
void AmarokConfigDialog::updateWidgetsDefault()
{
    m_soundSystem->setCurrentItem( 0 );
}


//////////////////////////////////////////////////////////////////////////////////////////
// PROTECTED
//////////////////////////////////////////////////////////////////////////////////////////

/**
 * @return true if any configuration items we are managing changed from Amarok's stored settings
 * We manage the engine combo box and some of the OSD settings
 * REIMPLEMENTED
 */
bool AmarokConfigDialog::hasChanged()
{
#ifdef TQ_WS_X11
    OSDPreviewWidget *osd = static_cast<OSDPreviewWidget*>( TQT_TQWIDGET(child( "osdpreview" )) );
#endif

    return  m_soundSystem->currentText() != m_pluginAmarokName[AmarokConfig::soundSystem()] ||
#ifdef TQ_WS_X11
            osd->alignment() != AmarokConfig::osdAlignment() ||
            osd->alignment() != OSDWidget::Center && osd->y() != AmarokConfig::osdYOffset() ||
#endif
            m_opt2->styleComboBox->currentText() != AmarokConfig::contextBrowserStyleSheet() ||
            Amarok::databaseTypeCode(  m_opt7->dbSetupFrame->databaseEngine->currentText()  ) != AmarokConfig::databaseEngine().toInt() ||
            m_engineConfig && m_engineConfig->hasChanged() ||
            m_deviceManager && m_deviceManager->hasChanged() ||
            externalBrowser() != AmarokConfig::externalBrowser();
}


/** REIMPLEMENTED */
bool AmarokConfigDialog::isDefault()
{
    AMAROK_NOTIMPLEMENTED

    //TODO hard to implement - what are default settings for OSD etc?

    return false;
}


//////////////////////////////////////////////////////////////////////////////////////////
// PRIVATE SLOTS
//////////////////////////////////////////////////////////////////////////////////////////

void AmarokConfigDialog::aboutEngine() //SLOT
{
    PluginManager::showAbout( TQString( "Name == '%1'" ).arg( m_soundSystem->currentText() ) );
}


//////////////////////////////////////////////////////////////////////////////////////////
// PRIVATE
//////////////////////////////////////////////////////////////////////////////////////////

void AmarokConfigDialog::soundSystemChanged()
{
    ///A new sound system has been LOADED
    ///If only the sound system widget has been changed don't call this!

    // remove old engine config widget
    // will delete the view if implementation is done correctly
    delete m_engineConfig;

    if( EngineController::hasEngineProperty( "HasConfigure" ) )
    {
        m_engineConfig = EngineController::engine()->configure();
        m_engineConfig->view()->reparent( m_engineConfigFrame, TQPoint() );
        m_engineConfig->view()->show();
        m_engineConfigFrame->setTitle( i18n( "to change settings", "Configure %1" ).arg( m_soundSystem->currentText() ) );
        m_engineConfigFrame->show();

        connect( m_engineConfig, TQT_SIGNAL(viewChanged()), TQT_SLOT(updateButtons()) );
    }
    else {
        m_engineConfig = 0;
        m_engineConfigFrame->hide();
    }

    const bool hasCrossfade = EngineController::hasEngineProperty( "HasCrossfade" );
    const bool crossfadeOn = m_opt4->kcfg_Crossfade->isOn();
    // Enable crossfading option when available
    m_opt4->kcfg_Crossfade->setEnabled( hasCrossfade );
    m_opt4->kcfg_CrossfadeLength->setEnabled( hasCrossfade && crossfadeOn );
    m_opt4->crossfadeLengthLabel->setEnabled( hasCrossfade && crossfadeOn );
    m_opt4->kcfg_CrossfadeType->setEnabled( hasCrossfade && crossfadeOn );

    if (!hasCrossfade)
    {
        m_opt4->radioButtonNormalPlayback->setChecked( true );
    }
}

TQString AmarokConfigDialog::externalBrowser() const
{
    return   m_opt1->kComboBox_browser->isEnabled() ?
#ifdef TQ_WS_MAC
                 m_opt1->kComboBox_browser->currentText() == i18n( "Default Browser" ) ?
                 "open" :
#else
                 m_opt1->kComboBox_browser->currentText() == i18n( "Default TDE Browser" ) ?
                 "kfmclient openURL" :
#endif
                 m_opt1->kComboBox_browser->currentText().lower() :
             m_opt1->kLineEdit_customBrowser->text().lower();
}


#include "configdialog.moc"