juk.cpp 19.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/**
 * Copyright (C) 2002-2004 Scott Wheeler <wheeler@kde.org>
 * Copyright (C) 2008, 2009 Michael Pyne <mpyne@kde.org>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */
17

18 19
#include "juk.h"

20
#include <kmessagebox.h>
Laurent Montel's avatar
Poirt  
Laurent Montel committed
21
#include <kactioncollection.h>
Aaron J. Seigo's avatar
Aaron J. Seigo committed
22
#include <kstandardaction.h>
Laurent Montel's avatar
Laurent Montel committed
23 24
#include <ktoggleaction.h>
#include <kactionmenu.h>
25
#include <kconfiggroup.h>
Michael Pyne's avatar
Michael Pyne committed
26
#include <KSharedConfig>
27 28
#include <kglobalaccel.h>
#include <ktoolbarpopupaction.h>
29
#include <knotification.h>
30

31 32
#include <QIcon>
#include <QAction>
33
#include <QCoreApplication>
34
#include <QKeyEvent>
35
#include <QDir>
36
#include <QDirIterator>
37
#include <QTime>
38
#include <QTimer>
39
#include <QDesktopWidget>
Michael Pyne's avatar
Michael Pyne committed
40
#include <QStatusBar>
41

42 43 44 45 46
#include "slideraction.h"
#include "statuslabel.h"
#include "systemtray.h"
#include "keydialog.h"
#include "tagguesserconfigdlg.h"
47
#include "filerenamerconfigdlg.h"
48
#include "scrobbler.h"
49
#include "scrobbleconfigdlg.h"
50
#include "actioncollection.h"
51
#include "cache.h"
52 53
#include "playlistsplitter.h"
#include "collectionlist.h"
54
#include "covermanager.h"
55
#include "tagtransactionmanager.h"
Michael Pyne's avatar
Michael Pyne committed
56
#include "juk_debug.h"
57

58 59
using namespace ActionCollection;

60 61
JuK* JuK::m_instance;

62 63 64 65 66 67 68
template<class T>
void deleteAndClear(T *&ptr)
{
    delete ptr;
    ptr = 0;
}

69 70 71 72
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////

Luigi Toscano's avatar
Luigi Toscano committed
73
JuK::JuK(const QStringList &filesToOpen, QWidget *parent) :
74
    KXmlGuiWindow(parent, Qt::WindowFlags(Qt::WA_DeleteOnClose)),
75 76 77
    m_splitter(nullptr),
    m_statusLabel(nullptr),
    m_systemTray(nullptr),
78
    m_player(new PlayerManager),
79
    m_scrobbler(nullptr),
Michael Pyne's avatar
Michael Pyne committed
80 81
    m_filesToOpen(filesToOpen),
    m_shuttingDown(false)
82
{
83 84
    // Expect segfaults if you change this order.

85 86
    m_instance = this;

87
    readSettings();
88

89 90
    Cache::ensureAppDataStorageExists();

91
    setupActions();
92
    setupLayout();
93

94
    bool firstRun = !KSharedConfig::openConfig()->hasGroup("MainWindow");
95 96

    if(firstRun) {
97
        KConfigGroup mainWindowConfig(KSharedConfig::openConfig(), "MainWindow");
98 99 100 101
        KConfigGroup playToolBarConfig(&mainWindowConfig, "Toolbar playToolBar");
        playToolBarConfig.writeEntry("ToolButtonStyle", "IconOnly");
    }

102 103
    QSize defaultSize(800, 480);

104
    if(QApplication::isRightToLeft())
105
        setupGUI(defaultSize, ToolBar | Save | Create, "jukui-rtl.rc");
106
    else
107 108 109 110
        setupGUI(defaultSize, ToolBar | Save | Create);

    // Center the GUI if this is our first run ever.

111
    if(firstRun) {
112
        QRect r = rect();
Luigi Toscano's avatar
Luigi Toscano committed
113
        r.moveCenter(QApplication::desktop()->screenGeometry().center());
114 115
        move(r.topLeft());
    }
116

Michael Pyne's avatar
Michael Pyne committed
117
    connect(m_splitter, SIGNAL(guiReady()), SLOT(slotSetupSystemTray()));
118
    readConfig();
119
    setupGlobalAccels();
120
    activateScrobblerIfEnabled();
121

122 123
    connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), SLOT(slotAboutToQuit()));

Michael Pyne's avatar
Michael Pyne committed
124 125
    // slotCheckCache loads the cached entries first to populate the collection list

Michael Pyne's avatar
Michael Pyne committed
126
    QTimer::singleShot(0, this, SLOT(slotClearOldCovers()));
127
    QTimer::singleShot(0, CollectionList::instance(), SLOT(startLoadingCachedItems()));
128
    QTimer::singleShot(0, this, SLOT(slotProcessArgs()));
129 130 131 132 133 134
}

JuK::~JuK()
{
}

135 136 137 138 139
JuK* JuK::JuKInstance()
{
    return m_instance;
}

140 141 142 143 144
PlayerManager *JuK::playerManager() const
{
    return m_player;
}

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
void JuK::coverDownloaded(const QPixmap &cover)
{
    QString event(cover.isNull() ? "coverFailed" : "coverDownloaded");
    KNotification *notification = new KNotification(event, this);
    notification->setPixmap(cover);
    notification->setFlags(KNotification::CloseOnTimeout);

    if(cover.isNull())
        notification->setText(i18n("Your album art failed to download."));
    else
        notification->setText(i18n("Your album art has finished downloading."));

    notification->sendEvent();
}

160 161 162 163
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////

164 165
void JuK::setupLayout()
{
166 167
    new TagTransactionManager(this);

Michael Pyne's avatar
Michael Pyne committed
168
    qCDebug(JUK_LOG) << "Creating GUI";
169 170 171
    QTime stopwatch;
    stopwatch.start();

172
    m_splitter = new PlaylistSplitter(m_player, this);
173
    setCentralWidget(m_splitter);
174

175
    m_statusLabel = new StatusLabel(m_splitter->playlist(), statusBar());
176 177
    connect(CollectionList::instance(), SIGNAL(signalCollectionChanged()),
            m_statusLabel, SLOT(updateData()));
178
    statusBar()->addWidget(m_statusLabel, 1);
179
    m_player->setStatusLabel(m_statusLabel);
180

181
    m_splitter->setFocus();
182

Michael Pyne's avatar
Michael Pyne committed
183
    qCDebug(JUK_LOG) << "GUI created in" << stopwatch.elapsed() << "ms";
184 185
}

186 187
void JuK::setupActions()
{
188
    KActionCollection *collection = ActionCollection::actions();
Michael Pyne's avatar
Michael Pyne committed
189

190
    // Setup KDE standard actions that JuK uses.
191

Aaron J. Seigo's avatar
Aaron J. Seigo committed
192 193 194 195 196
    KStandardAction::quit(this, SLOT(slotQuit()), collection);
    KStandardAction::undo(this, SLOT(slotUndo()), collection);
    KStandardAction::cut(collection);
    KStandardAction::copy(collection);
    KStandardAction::paste(collection);
197
    QAction *clear = KStandardAction::clear(collection);
Aaron J. Seigo's avatar
Aaron J. Seigo committed
198 199
    KStandardAction::selectAll(collection);
    KStandardAction::keyBindings(this, SLOT(slotEditKeys()), collection);
Scott Wheeler's avatar
Scott Wheeler committed
200

201
    // Setup the menu which handles the random play options.
202 203
    KActionMenu *actionMenu = collection->add<KActionMenu>("actionMenu");
    actionMenu->setText(i18n("&Random Play"));
Michael Pyne's avatar
Michael Pyne committed
204
    actionMenu->setIcon(QIcon::fromTheme( QLatin1String( "media-playlist-shuffle" )));
205
    actionMenu->setDelayed(false);
206

207
    QActionGroup* randomPlayGroup = new QActionGroup(this);
David Faure's avatar
David Faure committed
208

209 210
    QAction *act = collection->add<KToggleAction>("disableRandomPlay");
    act->setText(i18n("&Disable Random Play"));
Michael Pyne's avatar
Michael Pyne committed
211
    act->setIcon(QIcon::fromTheme( QLatin1String( "go-down" )));
212
    act->setActionGroup(randomPlayGroup);
Stephan Kulow's avatar
Stephan Kulow committed
213
    actionMenu->addAction(act);
214

Laurent Montel's avatar
Port++  
Laurent Montel committed
215 216
    m_randomPlayAction = collection->add<KToggleAction>("randomPlay");
    m_randomPlayAction->setText(i18n("Use &Random Play"));
Michael Pyne's avatar
Michael Pyne committed
217
    m_randomPlayAction->setIcon(QIcon::fromTheme( QLatin1String( "media-playlist-shuffle" )));
David Faure's avatar
David Faure committed
218
    m_randomPlayAction->setActionGroup(randomPlayGroup);
Stephan Kulow's avatar
Stephan Kulow committed
219
    actionMenu->addAction(m_randomPlayAction);
220

221 222
    act = collection->add<KToggleAction>("albumRandomPlay");
    act->setText(i18n("Use &Album Random Play"));
Michael Pyne's avatar
Michael Pyne committed
223
    act->setIcon(QIcon::fromTheme( QLatin1String( "media-playlist-shuffle" )));
224 225
    act->setActionGroup(randomPlayGroup);
    connect(act, SIGNAL(triggered(bool)), SLOT(slotCheckAlbumNextAction(bool)));
Stephan Kulow's avatar
Stephan Kulow committed
226
    actionMenu->addAction(act);
227

228
    act = collection->addAction("removeFromPlaylist", clear, SLOT(clear()));
Laurent Montel's avatar
Port++  
Laurent Montel committed
229
    act->setText(i18n("Remove From Playlist"));
Michael Pyne's avatar
Michael Pyne committed
230
    act->setIcon(QIcon::fromTheme( QLatin1String( "list-remove" )));
Laurent Montel's avatar
Port++  
Laurent Montel committed
231

232 233
    act = collection->addAction("play", m_player, SLOT(play()));
    act->setText(i18n("&Play"));
Michael Pyne's avatar
Michael Pyne committed
234
    act->setIcon(QIcon::fromTheme( QLatin1String( "media-playback-start" )));
235

236 237
    act = collection->addAction("pause", m_player, SLOT(pause()));
    act->setText(i18n("P&ause"));
Michael Pyne's avatar
Michael Pyne committed
238
    act->setIcon(QIcon::fromTheme( QLatin1String( "media-playback-pause" )));
239

240 241
    act = collection->addAction("stop", m_player, SLOT(stop()));
    act->setText(i18n("&Stop"));
Michael Pyne's avatar
Michael Pyne committed
242
    act->setIcon(QIcon::fromTheme( QLatin1String( "media-playback-stop" )));
Scott Wheeler's avatar
Scott Wheeler committed
243

Michael Pyne's avatar
Michael Pyne committed
244
    act = new KToolBarPopupAction(QIcon::fromTheme( QLatin1String( "media-skip-backward") ), i18nc("previous track", "Previous" ), collection);
245
    collection->addAction("back", act);
246 247
    connect(act, SIGNAL(triggered(bool)), m_player, SLOT(back()));

248 249
    act = collection->addAction("forward", m_player, SLOT(forward()));
    act->setText(i18nc("next track", "&Next"));
Michael Pyne's avatar
Michael Pyne committed
250
    act->setIcon(QIcon::fromTheme( QLatin1String( "media-skip-forward" )));
251

252 253
    act = collection->addAction("loopPlaylist");
    act->setText(i18n("&Loop Playlist"));
254 255
    act->setCheckable(true);

256 257
    act = collection->add<KToggleAction>("resizeColumnsManually");
    act->setText(i18n("&Resize Playlist Columns Manually"));
258 259

    // the following are not visible by default
260

261 262
    act = collection->addAction("mute", m_player, SLOT(mute()));
    act->setText(i18nc("silence playback", "Mute"));
Michael Pyne's avatar
Michael Pyne committed
263
    act->setIcon(QIcon::fromTheme( QLatin1String( "audio-volume-muted" )));
264

265 266
    act = collection->addAction("volumeUp", m_player, SLOT(volumeUp()));
    act->setText(i18n("Volume Up"));
Michael Pyne's avatar
Michael Pyne committed
267
    act->setIcon(QIcon::fromTheme( QLatin1String( "audio-volume-high" )));
268

269 270
    act = collection->addAction("volumeDown", m_player, SLOT(volumeDown()));
    act->setText(i18n("Volume Down"));
Michael Pyne's avatar
Michael Pyne committed
271
    act->setIcon(QIcon::fromTheme( QLatin1String( "audio-volume-low" )));
272

273 274
    act = collection->addAction("playPause", m_player, SLOT(playPause()));
    act->setText(i18n("Play / Pause"));
Michael Pyne's avatar
Michael Pyne committed
275
    act->setIcon(QIcon::fromTheme( QLatin1String( "media-playback-start" )));
276

277 278
    act = collection->addAction("seekForward", m_player, SLOT(seekForward()));
    act->setText(i18n("Seek Forward"));
Michael Pyne's avatar
Michael Pyne committed
279
    act->setIcon(QIcon::fromTheme( QLatin1String( "media-seek-forward" )));
280

281 282
    act = collection->addAction("seekBack", m_player, SLOT(seekBack()));
    act->setText(i18n("Seek Back"));
Michael Pyne's avatar
Michael Pyne committed
283
    act->setIcon(QIcon::fromTheme( QLatin1String( "media-seek-backward" )));
284

285 286
    act = collection->addAction("showHide", this, SLOT(slotShowHide()));
    act->setText(i18n("Show / Hide"));
Stephan Binner's avatar
Stephan Binner committed
287

288
    //////////////////////////////////////////////////
289
    // settings menu
290 291
    //////////////////////////////////////////////////

292 293 294 295 296 297
    m_toggleSystemTrayAction = collection->add<KToggleAction>("toggleSystemTray");
    m_toggleSystemTrayAction->setText(i18n("&Dock in System Tray"));
    connect(m_toggleSystemTrayAction, SIGNAL(triggered(bool)), SLOT(slotToggleSystemTray(bool)));

    m_toggleDockOnCloseAction = collection->add<KToggleAction>("dockOnClose");
    m_toggleDockOnCloseAction->setText(i18n("&Stay in System Tray on Close"));
298

299 300
    m_togglePopupsAction = collection->add<KToggleAction>("togglePopups");
    m_togglePopupsAction->setText(i18n("Popup &Track Announcement"));
301

302 303
    act = collection->add<KToggleAction>("saveUpcomingTracks");
    act->setText(i18n("Save &Play Queue on Exit"));
Scott Wheeler's avatar
Scott Wheeler committed
304

305 306
    act = collection->addAction("tagGuesserConfig", this, SLOT(slotConfigureTagGuesser()));
    act->setText(i18n("&Tag Guesser..."));
307

308 309
    act = collection->addAction("fileRenamerConfig", this, SLOT(slotConfigureFileRenamer()));
    act->setText(i18n("&File Renamer..."));
310

311
    act = collection->addAction("scrobblerConfig", this, SLOT(slotConfigureScrobbling()));
312
    act->setText(i18n("&Configure scrobbling..."));
313

314
    //////////////////////////////////////////////////
315
    // just in the toolbar
316 317
    //////////////////////////////////////////////////

318 319 320
    collection->addAction("trackPositionAction",
                          new TrackPositionAction(i18n("Track Position"), this));
    collection->addAction("volumeAction",
321
                          new VolumeAction(i18n("Volume"), this));
322

323 324 325
    ActionCollection::actions()->addAssociatedWidget(this);
    foreach (QAction* action, ActionCollection::actions()->actions())
        action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
326 327
}

Michael Pyne's avatar
Michael Pyne committed
328
void JuK::slotSetupSystemTray()
329
{
330
    if(m_toggleSystemTrayAction && m_toggleSystemTrayAction->isChecked()) {
Michael Pyne's avatar
Michael Pyne committed
331
        qCDebug(JUK_LOG) << "Setting up systray";
332
        QTime stopwatch; stopwatch.start();
333
        m_systemTray = new SystemTray(m_player, this);
Laurent Montel's avatar
Laurent Montel committed
334
        m_systemTray->setObjectName( QLatin1String("systemTray" ));
335

336 337
        m_toggleDockOnCloseAction->setEnabled(true);
        m_togglePopupsAction->setEnabled(true);
Michael Pyne's avatar
Michael Pyne committed
338
        qCDebug(JUK_LOG) << "Finished setting up systray, took" << stopwatch.elapsed() << "ms";
339
    }
340
    else {
341 342 343
        m_systemTray = 0;
        m_toggleDockOnCloseAction->setEnabled(false);
        m_togglePopupsAction->setEnabled(false);
344
    }
345 346
}

347 348
void JuK::setupGlobalAccels()
{
349 350 351 352 353 354 355 356 357 358 359 360
    KeyDialog::setupActionShortcut("play");
    KeyDialog::setupActionShortcut("playPause");
    KeyDialog::setupActionShortcut("stop");
    KeyDialog::setupActionShortcut("back");
    KeyDialog::setupActionShortcut("forward");
    KeyDialog::setupActionShortcut("seekBack");
    KeyDialog::setupActionShortcut("seekForward");
    KeyDialog::setupActionShortcut("volumeUp");
    KeyDialog::setupActionShortcut("volumeDown");
    KeyDialog::setupActionShortcut("mute");
    KeyDialog::setupActionShortcut("showHide");
    KeyDialog::setupActionShortcut("forwardAlbum");
361 362
}

363
void JuK::slotProcessArgs()
364
{
Luigi Toscano's avatar
Luigi Toscano committed
365
    CollectionList::instance()->addFiles(m_filesToOpen);
366 367
}

Michael Pyne's avatar
Michael Pyne committed
368 369 370 371 372 373
void JuK::slotClearOldCovers()
{
    // Find all saved covers from the previous run of JuK and clear them out, in case
    // we find our tracks in a different order this run, which would cause old saved
    // covers to be wrong.
    // See mpris2/mediaplayer2player.cpp
374 375
    QString tmpDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
    QStringList nameFilters;
Michael Pyne's avatar
Michael Pyne committed
376

377 378 379 380
    nameFilters << QStringLiteral("juk-cover-*.png");
    QDirIterator jukCoverIter(tmpDir, nameFilters);
    while (jukCoverIter.hasNext()) {
        QFile::remove(jukCoverIter.next());
Michael Pyne's avatar
Michael Pyne committed
381 382 383
    }
}

384 385 386
void JuK::keyPressEvent(QKeyEvent *e)
{
    if (e->key() >= Qt::Key_Back && e->key() <= Qt::Key_MediaLast)
Frerich Raabe's avatar
Frerich Raabe committed
387
        e->accept();
Kevin Ottens's avatar
Kevin Ottens committed
388
    KXmlGuiWindow::keyPressEvent(e);
389 390
}

391 392 393 394 395 396
/**
 * These are settings that need to be know before setting up the GUI.
 */

void JuK::readSettings()
{
397
    KConfigGroup config(KSharedConfig::openConfig(), "Settings");
398
    m_startDocked = config.readEntry("StartDocked", false);
399 400
}

401 402
void JuK::readConfig()
{
403
    // player settings
404

405
    KConfigGroup playerConfig(KSharedConfig::openConfig(), "Player");
406

407 408 409 410 411
    if(m_player)
    {
        const int maxVolume = 100;
        const int volume = playerConfig.readEntry("Volume", maxVolume);
        m_player->setVolume(volume * 0.01);
412

413 414
        //bool enableCrossfade = playerConfig.readEntry("CrossfadeTracks", true);
        //m_player->setCrossfadeEnabled(enableCrossfade);
Michael Pyne's avatar
Michael Pyne committed
415
        //ActionCollection::action<QAction>("crossfadeTracks")->setChecked(enableCrossfade);
416
    }
417

418 419
    // Default to no random play

420
    ActionCollection::action<KToggleAction>("disableRandomPlay")->setChecked(true);
421

422 423
    QString randomPlayMode = playerConfig.readEntry("RandomPlay", "Disabled");
    if(randomPlayMode == "true" || randomPlayMode == "Normal")
424
        m_randomPlayAction->setChecked(true);
425
    else if(randomPlayMode == "AlbumRandomPlay")
Michael Pyne's avatar
Michael Pyne committed
426
        ActionCollection::action<QAction>("albumRandomPlay")->setChecked(true);
427

428
    bool loopPlaylist = playerConfig.readEntry("LoopPlaylist", false);
429
    ActionCollection::action<QAction>("loopPlaylist")->setChecked(loopPlaylist);
430

431
    // general settings
432

433
    KConfigGroup settingsConfig(KSharedConfig::openConfig(), "Settings");
434

435
    bool dockInSystemTray = settingsConfig.readEntry("DockInSystemTray", true);
436 437
    m_toggleSystemTrayAction->setChecked(dockInSystemTray);

438
    bool dockOnClose = settingsConfig.readEntry("DockOnClose", true);
439 440
    m_toggleDockOnCloseAction->setChecked(dockOnClose);

441
    bool showPopups = settingsConfig.readEntry("TrackPopup", false);
442
    m_togglePopupsAction->setChecked(showPopups);
443 444 445 446
}

void JuK::saveConfig()
{
447
    // player settings
448

449
    KConfigGroup playerConfig(KSharedConfig::openConfig(), "Player");
450

451
    if (m_player)
452
    {
453
        playerConfig.writeEntry("Volume", static_cast<int>(100.0 * m_player->volume()));
454 455
    }

456 457
    playerConfig.writeEntry("RandomPlay", m_randomPlayAction->isChecked());

Michael Pyne's avatar
Michael Pyne committed
458
    QAction *a = ActionCollection::action<QAction>("loopPlaylist");
459 460
    playerConfig.writeEntry("LoopPlaylist", a->isChecked());

461
    playerConfig.writeEntry("CrossfadeTracks", false); // TODO bring back
462

Michael Pyne's avatar
Michael Pyne committed
463
    a = ActionCollection::action<QAction>("albumRandomPlay");
464
    if(a->isChecked())
465
        playerConfig.writeEntry("RandomPlay", "AlbumRandomPlay");
466
    else if(m_randomPlayAction->isChecked())
467
        playerConfig.writeEntry("RandomPlay", "Normal");
468
    else
469
        playerConfig.writeEntry("RandomPlay", "Disabled");
470

471 472
    // general settings

473
    KConfigGroup settingsConfig(KSharedConfig::openConfig(), "Settings");
474 475 476 477 478
    settingsConfig.writeEntry("StartDocked", m_startDocked);
    settingsConfig.writeEntry("DockInSystemTray", m_toggleSystemTrayAction->isChecked());
    settingsConfig.writeEntry("DockOnClose", m_toggleDockOnCloseAction->isChecked());
    settingsConfig.writeEntry("TrackPopup", m_togglePopupsAction->isChecked());

479
    KSharedConfig::openConfig()->sync();
480 481
}

482 483
bool JuK::queryClose()
{
484
    if(!m_shuttingDown &&
485
       !qApp->isSavingSession() &&
486 487 488
       m_systemTray &&
       m_toggleDockOnCloseAction->isChecked())
    {
489 490 491 492 493 494
        KMessageBox::information(this,
            i18n("<qt>Closing the main window will keep JuK running in the system tray. "
                 "Use Quit from the File menu to quit the application.</qt>"),
            i18n("Docking in System Tray"), "hideOnCloseInfo");
        hide();
        return false;
495 496
    }
    else
497 498 499 500 501 502 503 504 505
    {
        // Some phonon backends will crash on shutdown unless we've stopped
        // playback.
        if(m_player->playing())
            m_player->stop();

        // Save configuration data.
        m_startDocked = !isVisible();
        saveConfig();
506
        return true;
507
    }
508 509
}

510 511 512 513
////////////////////////////////////////////////////////////////////////////////
// private slot definitions
////////////////////////////////////////////////////////////////////////////////

514 515
void JuK::slotShowHide()
{
Stephan Kulow's avatar
Stephan Kulow committed
516
    setHidden(!isHidden());
517 518
}

519 520 521
void JuK::slotAboutToQuit()
{
    m_shuttingDown = true;
522

523 524 525 526
    deleteAndClear(m_systemTray);
    deleteAndClear(m_splitter);
    deleteAndClear(m_player);
    deleteAndClear(m_statusLabel);
527 528
}

529 530
void JuK::slotQuit()
{
Michael Pyne's avatar
Michael Pyne committed
531
    m_shuttingDown = true;
532

533
    qApp->quit();
534 535
}

536 537 538 539
////////////////////////////////////////////////////////////////////////////////
// settings menu
////////////////////////////////////////////////////////////////////////////////

540
void JuK::slotToggleSystemTray(bool enabled)
541
{
542
    if(enabled && !m_systemTray)
Michael Pyne's avatar
Michael Pyne committed
543
        slotSetupSystemTray();
544
    else if(!enabled && m_systemTray) {
545 546 547 548
        delete m_systemTray;
        m_systemTray = 0;
        m_toggleDockOnCloseAction->setEnabled(false);
        m_togglePopupsAction->setEnabled(false);
549 550 551
    }
}

552 553
void JuK::slotEditKeys()
{
554
    KeyDialog(ActionCollection::actions(), this).configure();
555 556
}

557 558
void JuK::slotConfigureTagGuesser()
{
559
    TagGuesserConfigDlg(this).exec();
560 561
}

562 563
void JuK::slotConfigureFileRenamer()
{
564
    FileRenamerConfigDlg(this).exec();
565 566
}

567 568 569
void JuK::slotConfigureScrobbling()
{
    ScrobbleConfigDlg(this).exec();
570
    activateScrobblerIfEnabled();
571 572
}

573 574 575 576 577 578 579 580 581 582 583 584 585 586
void JuK::activateScrobblerIfEnabled()
{
    bool isScrobbling = Scrobbler::isScrobblingEnabled();

    if (!m_scrobbler && isScrobbling) {
        m_scrobbler = new Scrobbler(this);
        connect (m_player,    SIGNAL(signalItemChanged(FileHandle)),
                 m_scrobbler, SLOT(nowPlaying(FileHandle)));
    }
    else if (m_scrobbler && !isScrobbling) {
        delete m_scrobbler;
        m_scrobbler = 0;
    }
}
587

588 589 590 591 592
void JuK::slotUndo()
{
    TagTransactionManager::instance()->undo();
}

593 594 595 596 597 598
void JuK::slotCheckAlbumNextAction(bool albumRandomEnabled)
{
    // If album random play is enabled, then enable the Play Next Album action
    // unless we're not playing right now.

    if(albumRandomEnabled && !m_player->playing())
599
        albumRandomEnabled = false;
600 601 602 603

    action("forwardAlbum")->setEnabled(albumRandomEnabled);
}

604
// vim: set et sw=4 tw=0 sta: