juk.cpp 22.4 KB
Newer Older
1 2 3 4 5
/***************************************************************************
                          juk.cpp  -  description
                             -------------------
    begin                : Mon Feb  4 23:40:41 EST 2002
    copyright            : (C) 2002 by Scott Wheeler
6
    email                : wheeler@kde.org
7
***************************************************************************/
8 9 10 11 12 13 14 15 16 17

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

18 19 20 21 22 23 24
#include <kcmdlineargs.h>
#include <kstatusbar.h>
#include <kdebug.h>
#include <kmessagebox.h>

#include <qslider.h>

25 26 27 28 29 30 31
#include "juk.h"
#include "slideraction.h"
#include "statuslabel.h"
#include "splashscreen.h"
#include "systemtray.h"
#include "keydialog.h"
#include "tagguesserconfigdlg.h"
32
#include "filerenamerconfigdlg.h"
33
#include "actioncollection.h"
34
#include "cache.h"
35

36 37
using namespace ActionCollection;

38 39 40 41
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////

Scott Wheeler's avatar
Scott Wheeler committed
42 43
JuK::JuK(QWidget *parent, const char *name) :
    KMainWindow(parent, name, WDestructiveClose),
44
    m_player(PlayerManager::instance()),
45
    m_shuttingDown(false)
46
{
47 48
    // Expect segfaults if you change this order.

49
    readSettings();
50

51
    if(m_showSplash && !m_startDocked) {
52 53 54 55
	SplashScreen::instance()->show();
	kapp->processEvents();
    }

56
    setupActions();
57 58
    setupLayout();
    setupSplitterConnections();
59
    slotPlaylistChanged();
60
    readConfig();
61
    setupSystemTray();
62
    setupGlobalAccels();
63
    processArgs();
64

65 66
    m_player->setPlaylistInterface(m_splitter);

67
    SplashScreen::finishedLoading();
Scott Wheeler's avatar
Scott Wheeler committed
68
    QTimer::singleShot(0, CollectionList::instance(), SLOT(slotCheckCache()));
69 70 71 72
}

JuK::~JuK()
{
73

74 75
}

76 77 78 79 80
KActionCollection *JuK::actionCollection() const
{
    return ActionCollection::actions();
}

81 82 83 84
////////////////////////////////////////////////////////////////////////////////
// public slots
////////////////////////////////////////////////////////////////////////////////

85
void JuK::slotGuessTagInfoFromFile()
86
{
87 88 89 90 91 92
    m_splitter->slotGuessTagInfo(TagGuesser::FileName);
}

void JuK::slotGuessTagInfoFromInternet()
{
    m_splitter->slotGuessTagInfo(TagGuesser::MusicBrainz);
93 94
}

95 96 97 98 99 100 101 102 103 104
void JuK::back(int howMany)
{
    for(--howMany; howMany > 0; --howMany)
        m_splitter->playPreviousFile(m_randomPlayAction->isChecked());

    play(m_splitter->playPreviousFile(m_randomPlayAction->isChecked()));
}

void JuK::slotPopulateBackMenu()
{
Scott Wheeler's avatar
Scott Wheeler committed
105 106
    m_splitter->populatePlayHistoryMenu(m_backAction->popupMenu(),
					m_randomPlayAction->isChecked());
107 108 109 110 111 112 113
}

void JuK::openFile(const QString &file)
{
    m_splitter->open(file);
}

114 115 116 117 118 119
void JuK::openFile(const QStringList &files)
{
    for(QStringList::ConstIterator it = files.begin(); it != files.end(); ++it)
	openFile(*it);
}

120 121 122 123
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////

124 125
void JuK::setupLayout()
{
126
    m_splitter = new PlaylistSplitter(this, "playlistSplitter");
127
    setCentralWidget(m_splitter);
128 129

    // playlist item activation connection
Scott Wheeler's avatar
Scott Wheeler committed
130
    connect(m_splitter, SIGNAL(signalActivated()),
131
	    this, SLOT(slotPlayCurrent()));
Scott Wheeler's avatar
Scott Wheeler committed
132
    connect(m_splitter, SIGNAL(signalListBoxDoubleClicked()),
133
	    this, SLOT(slotPlayCurrent()));
134

135
    // create status bar
136

137
    m_statusLabel = new StatusLabel(statusBar());
138

139
    statusBar()->addWidget(m_statusLabel, 1);
140

Scott Wheeler's avatar
Scott Wheeler committed
141 142
    connect(m_splitter, SIGNAL(signalSelectedPlaylistCountChanged(int)),
	    m_statusLabel, SLOT(setPlaylistCount(int)));
143 144
    connect(m_splitter, SIGNAL(signalSelectedPlaylistTimeChanged(int)),
	    m_statusLabel, SLOT(setPlaylistTime(int)));
Scott Wheeler's avatar
Scott Wheeler committed
145 146
    connect(m_statusLabel, SIGNAL(jumpButtonClicked()),
	    m_splitter, SLOT(slotSelectPlaying()));
147

148 149
    PlayerManager::instance()->setStatusLabel(m_statusLabel);

150 151
    // Needs to be here because m_splitter is not called before setupActions
    // (because PlaylistSplitter itself accesses the actionCollection)
152

153
    new KAction(i18n("&Rename File"), 0, "CTRL+r", m_splitter, SLOT(slotRenameFile()),
154
                actions(), "renameFile"); // 4
155

156
    m_splitter->setFocus();
157

158
    resize(750, 500);
159 160
}

161 162
void JuK::setupActions()
{
163
    //////////////////////////////////////////////////
164
    // file menu
165
    //////////////////////////////////////////////////
166

Scott Wheeler's avatar
Scott Wheeler committed
167
    KActionMenu *newMenu = new KActionMenu(i18n("&New"), "filenew",
168
					   actions(), "file_new");
Scott Wheeler's avatar
Scott Wheeler committed
169

170 171 172 173 174 175
    // This connection will call the
    // PlaylistSplitter::slotCreatePlaylist(const QString &) slot - this is
    // possible because the QString parameter has a default value, so the
    // slot can be called without arguments (as required by the signal's
    // signature).

Scott Wheeler's avatar
Scott Wheeler committed
176 177 178
    newMenu->insert(createSplitterAction(i18n("Empty Playlist..."),
					 SLOT(slotCreatePlaylist()), 0, 0, 0));

179
    newMenu->insert(createSplitterAction(i18n("Playlist From Folder..."),
Scott Wheeler's avatar
Scott Wheeler committed
180 181
					 SLOT(slotCreatePlaylistFromDir()), 0, 0, 0));

182 183 184 185 186 187 188 189
    createSplitterAction(i18n("Open..."),         SLOT(slotOpen()),              "file_open", "fileopen", "CTRL+o");
    createSplitterAction(i18n("Open &Folder..."), SLOT(slotOpenDirectory()),     "openDirectory", "fileopen");
    createSplitterAction(i18n("&Rename..."),      SLOT(slotRenamePlaylist()),    "renamePlaylist");
    createSplitterAction(i18n("D&uplicate..."),   SLOT(slotDuplicatePlaylist()), "duplicatePlaylist");
    createSplitterAction(i18n("Save"),            SLOT(slotSavePlaylist()),      "file_save", "filesave", "CTRL+s");
    createSplitterAction(i18n("Save As..."),      SLOT(slotSaveAsPlaylist()),    "file_save_as", "filesaveas");
    createSplitterAction(i18n("R&emove"),         SLOT(slotDeletePlaylist()),    "deleteItemPlaylist", "edittrash");
    createSplitterAction(i18n("Reload"),          SLOT(slotReloadPlaylist()),    "reloadPlaylist", "reload");
190

191
    KStdAction::quit(this, SLOT(slotQuit()), actions());
192

193
    //////////////////////////////////////////////////
194
    // edit menu
195 196
    //////////////////////////////////////////////////

197 198 199 200
    KStdAction::cut(kapp,   SLOT(cut()),   actions());
    KStdAction::copy(kapp,  SLOT(copy()),  actions());
    KStdAction::paste(kapp, SLOT(paste()), actions());
    KStdAction::clear(kapp, SLOT(clear()), actions());
201

202
    KStdAction::selectAll(kapp, SLOT(selectAll()), actions());
203

204
    createSplitterAction(
205
	i18n("Advanced Search"), SLOT(slotAdvancedSearch()), "advancedSearch", "find", "s");
206

207
    //////////////////////////////////////////////////
208
    // view menu
209
    //////////////////////////////////////////////////
210

Scott Wheeler's avatar
Scott Wheeler committed
211
    m_showSearchAction = new KToggleAction(i18n("Show &Search Bar"), "filefind",
212
					   0, actions(), "showSearch");
Scott Wheeler's avatar
Scott Wheeler committed
213
    m_showEditorAction = new KToggleAction(i18n("Show &Tag Editor"), "edit",
214
					   0, actions(), "showEditor");
215
    m_showHistoryAction = new KToggleAction(i18n("Show &History"), "history",
216
					   0, actions(), "showHistory");
217

218
    createSplitterAction(i18n("Refresh Items"), SLOT(slotRefresh()), "refresh", "reload");
219

220
    //////////////////////////////////////////////////
221
    // play menu
222 223
    //////////////////////////////////////////////////

Scott Wheeler's avatar
Scott Wheeler committed
224
    m_randomPlayAction = new KToggleAction(i18n("&Random Play"), 0,
225
					   actions(), "randomPlay");
Scott Wheeler's avatar
Scott Wheeler committed
226

227 228 229
    new KAction(i18n("&Play"),  "player_play",  0, m_player, SLOT(play()),  actions(), "play");
    new KAction(i18n("P&ause"), "player_pause", 0, m_player, SLOT(pause()), actions(), "pause");
    new KAction(i18n("&Stop"),  "player_stop",  0, m_player, SLOT(stop()),  actions(), "stop");
Scott Wheeler's avatar
Scott Wheeler committed
230

231
    m_backAction = new KToolBarPopupAction(i18n("Previous &Track"), "player_start", 0,
232
					   this, SLOT(back()), actions(), "back");
233

Scott Wheeler's avatar
Scott Wheeler committed
234 235 236 237
    connect(m_backAction->popupMenu(), SIGNAL(aboutToShow()),
	    this, SLOT(slotPopulateBackMenu()));
    connect(m_backAction->popupMenu(), SIGNAL(activated(int)),
	    this, SLOT(back(int)));
238

239 240 241 242
    new KAction(i18n("&Next Track"), "player_end", 0, m_player, SLOT(forward()), actions(), "forward");
    new KToggleAction(i18n("&Loop Playlist"), 0, 0, actions(), "loopPlaylist");

    // the following are not visible by default
243

244 245 246 247 248 249 250
    new KAction(i18n("Mute"),         "mute",        0, m_player, SLOT(mute()),        actions(), "mute");
    new KAction(i18n("Volume Up"),    "volumeUp",    0, m_player, SLOT(volumeUp()),    actions(), "volumeUp");
    new KAction(i18n("Volume Down"),  "volumeDown",  0, m_player, SLOT(volumeDown()),  actions(), "volumeDown");
    new KAction(i18n("Play / Pause"), "playPause",   0, m_player, SLOT(playPause()),   actions(), "playPause");
    new KAction(i18n("Seek Forward"), "seekForward", 0, m_player, SLOT(seekForward()), actions(), "seekForward");
    new KAction(i18n("Seek Back"),    "seekBack",    0, m_player, SLOT(seekBack()),    actions(), "seekBack");
    
251

252
    //////////////////////////////////////////////////
253
    // tagger menu
254 255
    //////////////////////////////////////////////////

256
    createSplitterAction(i18n("&Save"), SLOT(slotSaveTag()),
Scott Wheeler's avatar
Scott Wheeler committed
257 258 259
			 "saveItem",   "filesave", "CTRL+t");
    createSplitterAction(i18n("&Delete"), SLOT(slotDeleteSelectedItems()),
			 "removeItem", "editdelete");
260

261 262
    KActionMenu *guessMenu = new KActionMenu(i18n("&Guess Tag Information"),
					     QString::null, actions(),
Scott Wheeler's avatar
Scott Wheeler committed
263
					     "guessTag");
264

265 266 267
    guessMenu->insert(
	new KAction(i18n("From &Filename"), 0, "CTRL+f", this, SLOT(slotGuessTagInfoFromFile()),
		    actions(), "guessTagFile"));
268
#if HAVE_MUSICBRAINZ
269 270 271
    guessMenu->insert(
	new KAction(i18n("From &Internet"), 0, "CTRL+i", this, SLOT(slotGuessTagInfoFromInternet()),
		    actions(), "guessTagInternet"));
272
#endif
Scott Wheeler's avatar
Scott Wheeler committed
273

274
    //////////////////////////////////////////////////
275
    // settings menu
276 277
    //////////////////////////////////////////////////

278
    setStandardToolBarMenuEnabled(true);
279

Stephan Binner's avatar
Stephan Binner committed
280
    m_toggleSplashAction = new KToggleAction(i18n("Show Splash Screen on Startup"),
281
					     0, actions(), "showSplashScreen");
Scott Wheeler's avatar
Scott Wheeler committed
282 283

    m_toggleSystemTrayAction = new KToggleAction(i18n("&Dock in System Tray"),
284
						 0, actions(), "toggleSystemTray");
Scott Wheeler's avatar
Scott Wheeler committed
285 286

    m_toggleDockOnCloseAction = new KToggleAction(i18n("&Stay in System Tray on Close"),
287
						  0, actions(), "dockOnClose");
288

289
    m_togglePopupsAction = new KToggleAction(i18n("Popup &Track Announcement"),
290
					     0, this, 0, actions(), "togglePopups");
291

Scott Wheeler's avatar
Scott Wheeler committed
292 293
    connect(m_toggleSystemTrayAction, SIGNAL(toggled(bool)),
	    this, SLOT(slotToggleSystemTray(bool)));
294

Scott Wheeler's avatar
Scott Wheeler committed
295

296
    m_outputSelectAction = Player::playerSelectAction(actions());
297

298
    if(m_outputSelectAction)
299
        m_outputSelectAction->setCurrentItem(0);
300

Scott Wheeler's avatar
Scott Wheeler committed
301
    new KAction(i18n("&Tag Guesser..."), 0, 0, this, SLOT(slotConfigureTagGuesser()),
302
		actions(), "tagGuesserConfig");
303

304
    new KAction(i18n("&File Renamer..."), 0, 0, this, SLOT(slotConfigureFileRenamer()),
305
		actions(), "fileRenamerConfig");
306

307
    KStdAction::keyBindings(this, SLOT(slotEditKeys()), actions());
308

309
    //////////////////////////////////////////////////
310
    // just in the toolbar
311 312
    //////////////////////////////////////////////////

313
    m_sliderAction = new SliderAction(i18n("Track Position"), actions(),
Scott Wheeler's avatar
Scott Wheeler committed
314
				      "trackPositionAction");
315 316

    createGUI();
317 318

    // set the slider to the proper orientation and make it stay that way
319
    m_sliderAction->slotUpdateOrientation();
320 321
}

322 323 324 325 326 327
void JuK::setupSplitterConnections()
{
    QValueListConstIterator<SplitterConnection> it = m_splitterConnections.begin();
    for(; it != m_splitterConnections.end(); ++it)
        connect((*it).first, SIGNAL(activated()), m_splitter, (*it).second);

Scott Wheeler's avatar
Scott Wheeler committed
328 329 330 331
    connect(m_showSearchAction, SIGNAL(toggled(bool)),
	    m_splitter, SLOT(slotSetSearchVisible(bool)));
    connect(m_showEditorAction, SIGNAL(toggled(bool)),
	    m_splitter, SLOT(slotSetEditorVisible(bool)));
332 333
    connect(m_showHistoryAction, SIGNAL(toggled(bool)),
	    m_splitter, SLOT(slotSetHistoryVisible(bool)));
334
    connect(this, SIGNAL(dockWindowPositionChanged(QDockWindow *)),
Scott Wheeler's avatar
Scott Wheeler committed
335 336 337
	    m_sliderAction, SLOT(slotUpdateOrientation(QDockWindow *)));
    connect(m_splitter, SIGNAL(signalPlaylistChanged()),
	    this, SLOT(slotPlaylistChanged()));
338 339
}

340
void JuK::setupSystemTray()
341
{
342
    if(m_toggleSystemTrayAction && m_toggleSystemTrayAction->isChecked()) {
343 344
        m_systemTray = new SystemTray(this, "systemTray");
        m_systemTray->show();
345

346
        connect(this, SIGNAL(signalNewSong(const QString&)),
Scott Wheeler's avatar
Scott Wheeler committed
347
		m_systemTray, SLOT(slotNewSong(const QString&)));
348

349
        m_toggleDockOnCloseAction->setEnabled(true);
350
	m_togglePopupsAction->setEnabled(true);
351

352
        connect(m_systemTray, SIGNAL(quitSelected()), this, SLOT(slotQuit()));
353
    }
354
    else {
355 356
        m_systemTray = 0;
        m_toggleDockOnCloseAction->setEnabled(false);
357
	m_togglePopupsAction->setEnabled(false);
358
    }
359 360
}

361 362 363
void JuK::setupGlobalAccels()
{
    m_accel = new KGlobalAccel(this);
364

365 366 367 368 369 370 371 372 373
    KeyDialog::insert(m_accel, "PlayPause",   i18n("Play / Pause"), action("playPause"),   SLOT(activate()));
    KeyDialog::insert(m_accel, "Stop",        i18n("Stop Playing"), action("stop"),        SLOT(activate()));
    KeyDialog::insert(m_accel, "Back",        i18n("Back"),         action("back"),        SLOT(activate()));
    KeyDialog::insert(m_accel, "Forward",     i18n("Forward"),      action("forward"),     SLOT(activate()));
    KeyDialog::insert(m_accel, "SeekBack",    i18n("Seek Back"),    action("seekBack"),    SLOT(activate()));
    KeyDialog::insert(m_accel, "SeekForward", i18n("Seek Forward"), action("seekForward"), SLOT(activate()));
    KeyDialog::insert(m_accel, "VolumeUp",    i18n("Volume Up"),    action("volumeUp"),    SLOT(activate()));
    KeyDialog::insert(m_accel, "VolumeDown",  i18n("Volume Down"),  action("volumeDown"),  SLOT(activate()));
    KeyDialog::insert(m_accel, "Mute",        i18n("Mute"),         action("mute"),        SLOT(activate()));
374
    KeyDialog::insert(m_accel, "ShowHide",    i18n("Show / Hide"),  this,                  SLOT(slotShowHide()));
375

376 377 378 379 380
    m_accel->setConfigGroup("Shortcuts");
    m_accel->readSettings();
    m_accel->updateConnections();
}

381 382 383 384
void JuK::processArgs()
{
    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
    QStringList files;
385

386
    for(int i = 0; i < args->count(); i++)
387
        files.append(args->arg(i));
388

389
    m_splitter->open(files);
390 391
}

392 393 394
void JuK::keyPressEvent(QKeyEvent *e)
{
    if (e->key() >= Qt::Key_Back && e->key() <= Qt::Key_MediaLast)
395
        e->accept();
396 397 398
    KMainWindow::keyPressEvent(e);
}

399 400 401 402 403 404 405 406 407
/**
 * These are settings that need to be know before setting up the GUI.
 */

void JuK::readSettings()
{
    KConfig *config = KGlobal::config();
    { // general settings
        KConfigGroupSaver saver(config, "Settings");
408
        m_showSplash = config->readBoolEntry("ShowSplashScreen", true);
409
        m_startDocked = config->readBoolEntry("StartDocked", false);
410 411 412
    }
}

413 414
void JuK::readConfig()
{
415
    // Automagically save and m_restore many window settings.
416 417
    setAutoSaveSettings();

418
    KConfig *config = KGlobal::config();
419
    { // player settings
420
        KConfigGroupSaver saver(config, "Player");
421 422
        if(m_sliderAction->volumeSlider()) {
	    int maxVolume = m_sliderAction->volumeSlider()->maxValue();
Scott Wheeler's avatar
Scott Wheeler committed
423
	    int volume = config->readNumEntry("Volume", maxVolume);
424
            m_sliderAction->volumeSlider()->setValue(volume);
425
        }
426 427
        bool randomPlay = config->readBoolEntry("RandomPlay", false);
        m_randomPlayAction->setChecked(randomPlay);
428

429
        bool loopPlaylist = config->readBoolEntry("LoopPlaylist", false);
430
        ActionCollection::action<KToggleAction>("loopPlaylist")->setChecked(loopPlaylist);
431
    }
432
    { // view settings
433
        KConfigGroupSaver saver(config, "View");
434 435 436 437 438

        bool showSearch = config->readBoolEntry("ShowSearch", true);
        m_showSearchAction->setChecked(showSearch);
        m_splitter->slotSetSearchVisible(showSearch);

439 440 441
        bool showEditor = config->readBoolEntry("ShowEditor", false);
        m_showEditorAction->setChecked(showEditor);
        m_splitter->slotSetEditorVisible(showEditor);
442

443 444 445
	// The history list will actually be created by the playlist restoration
	// code, but we want to remember the checkbox's setting and hope that
	// it's in synch with the code that does the real work.
446

447 448
	bool showHistory = config->readBoolEntry("ShowHistory", false);
	m_showHistoryAction->setChecked(showHistory);
449
    }
450 451
    { // general settings
        KConfigGroupSaver saver(config, "Settings");
452

453 454
        bool dockInSystemTray = config->readBoolEntry("DockInSystemTray", true);
        m_toggleSystemTrayAction->setChecked(dockInSystemTray);
455

456 457
        bool dockOnClose = config->readBoolEntry("DockOnClose", true);
        m_toggleDockOnCloseAction->setChecked(dockOnClose);
458

459 460
        bool showPopups = config->readBoolEntry("TrackPopup", false);
        m_togglePopupsAction->setChecked(showPopups);
461

462 463
        if(m_outputSelectAction)
            m_outputSelectAction->setCurrentItem(config->readNumEntry("MediaSystem", 0));
464
    }
465

466
    m_toggleSplashAction->setChecked(m_showSplash);
467 468 469 470
}

void JuK::saveConfig()
{
471
    KConfig *config = KGlobal::config();
472
    { // player settings
473
        KConfigGroupSaver saver(config, "Player");
474 475 476 477 478
	config->writeEntry("Volume", m_sliderAction->volumeSlider()->value());
	config->writeEntry("RandomPlay", m_randomPlayAction->isChecked());

	KToggleAction *a = ActionCollection::action<KToggleAction>("loopPlaylist");
	config->writeEntry("LoopPlaylist", a->isChecked());
479
    }
480 481
    { // view settings
        KConfigGroupSaver saver(config, "View");
482

483
        config->writeEntry("ShowEditor", m_showEditorAction->isChecked());
484
        config->writeEntry("ShowSearch", m_showSearchAction->isChecked());
485
	config->writeEntry("ShowHistory", m_showHistoryAction->isChecked());
486
    }
487 488
    { // general settings
        KConfigGroupSaver saver(config, "Settings");
489
        config->writeEntry("ShowSplashScreen", m_toggleSplashAction->isChecked());
490
        config->writeEntry("StartDocked", m_startDocked);
491 492 493 494 495
        config->writeEntry("DockInSystemTray", m_toggleSystemTrayAction->isChecked());
        config->writeEntry("DockOnClose", m_toggleDockOnCloseAction->isChecked());
        config->writeEntry("TrackPopup", m_togglePopupsAction->isChecked());
        if(m_outputSelectAction)
            config->writeEntry("MediaSystem", m_outputSelectAction->currentItem());
496
    }
497
    config->sync();
498 499
}

500
bool JuK::queryExit()
501
{
502 503
    m_startDocked = !isVisible();

504
    hide();
505
    action("stop")->activate();
506 507 508
    delete m_systemTray;
    m_systemTray = 0;

509
    Cache::instance()->save();
510
    saveConfig();
511
    delete m_splitter;
512
    return true;
513 514
}

515 516
bool JuK::queryClose()
{
517 518 519 520 521
    if(!m_shuttingDown &&
       !kapp->sessionSaving() &&
       m_systemTray &&
       m_toggleDockOnCloseAction->isChecked())
    {
522
	KMessageBox::information(this,
Scott Wheeler's avatar
Scott Wheeler committed
523 524 525
	    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");
526 527 528 529 530 531 532
	hide();
	return false;
    }
    else
	return true;
}

533 534 535
QString JuK::playingString() const
{
    QString s;
536 537
    if(!m_player->playing() && !m_player->paused())
	return i18n("No song playing");
538

539 540 541 542
    if(!m_splitter->playingArtist().isEmpty())
	s = m_splitter->playingArtist().simplifyWhiteSpace() + " - ";

    s += m_splitter->playingTrack().simplifyWhiteSpace();
543 544 545 546

    return s;
}

547 548
void JuK::updatePlaylistInfo()
{
Scott Wheeler's avatar
Scott Wheeler committed
549
    m_statusLabel->setPlaylistInfo(m_splitter->visiblePlaylistName(),
550 551
				   m_splitter->selectedPlaylistCount(),
				   m_splitter->selectedPlaylistTotalTime());
552 553 554 555
}

void JuK::play(const QString &file)
{
556
    m_player->play(file);
557
    emit signalNewSong(playingString());
558 559
}

Scott Wheeler's avatar
Scott Wheeler committed
560 561 562
KAction *JuK::createSplitterAction(const QString &text, const char *slot,
				   const char *name, const QString &pix,
				   const KShortcut &shortcut)
563 564 565 566
{
    KAction *action;

    if(pix.isNull())
567
	action = new KAction(text, shortcut, actions(), name);
568
    else
569
	action = new KAction(text, pix, shortcut, actions(), name);
570 571

    m_splitterConnections.append(SplitterConnection(action, slot));
572

573 574 575
    return action;
}

576 577 578 579
////////////////////////////////////////////////////////////////////////////////
// private slot definitions
////////////////////////////////////////////////////////////////////////////////

580 581 582 583 584
void JuK::slotShowHide()
{
    setShown(!isShown());
}

585
void JuK::slotPlaylistChanged()
586
{
587 588 589 590
    if(m_splitter->collectionListSelected() ||
       !m_splitter->hasListSelected() ||
       m_splitter->readOnlyListSelected())
    {
591 592 593 594 595
        action("file_save")->setEnabled(false);
        action("file_save_as")->setEnabled(false);
        action("renamePlaylist")->setEnabled(false);
        action("reloadPlaylist")->setEnabled(false);
        action("deleteItemPlaylist")->setEnabled(false);
596 597
    }
    else {
598 599 600 601
        action("file_save")->setEnabled(true);
        action("file_save_as")->setEnabled(true);
        action("renamePlaylist")->setEnabled(true);
        action("deleteItemPlaylist")->setEnabled(true);
602 603

	if(m_splitter->fileBasedListSelected() || m_splitter->dynamicListSelected())
604
	    action("reloadPlaylist")->setEnabled(true);
605
	else
606
	    action("reloadPlaylist")->setEnabled(false);
607
    }
608
    if(m_splitter->hasListSelected())
609
        action("duplicatePlaylist")->setEnabled(true);
610
    else
611
        action("duplicatePlaylist")->setEnabled(false);
612

613 614 615
    updatePlaylistInfo();
}

616 617 618 619 620
void JuK::slotQuit()
{
    kapp->quit();
}

621 622 623 624
////////////////////////////////////////////////////////////////////////////////
// settings menu
////////////////////////////////////////////////////////////////////////////////

625
void JuK::slotToggleSystemTray(bool enabled)
626
{
627
    if(enabled && !m_systemTray)
628
	setupSystemTray();
629 630 631
    else if(!enabled && m_systemTray) {
	delete m_systemTray;
	m_systemTray = 0;
632
	m_toggleDockOnCloseAction->setEnabled(false);
633
	m_togglePopupsAction->setEnabled(false);
634 635 636
    }
}

637 638
void JuK::slotEditKeys()
{
639
    KeyDialog::configure(m_accel, actions(), this);
640 641
}

642
////////////////////////////////////////////////////////////////////////////////
643
// additional player slots
644 645
////////////////////////////////////////////////////////////////////////////////

646
void JuK::slotPlayCurrent()
647
{
648 649
    m_player->stop();
    action("play")->activate();
650 651
}

652 653
void JuK::slotConfigureTagGuesser()
{
654
    TagGuesserConfigDlg(this).exec();
655 656
}

657 658
void JuK::slotConfigureFileRenamer()
{
659
    FileRenamerConfigDlg(this).exec();
660 661
}

662
#include "juk.moc"