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

/***************************************************************************
 *                                                                         *
 *   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 <klocale.h>
#include <keditcl.h>
#include <kfiledialog.h>
21
#include <kiconloader.h>
22 23 24 25 26 27 28 29 30 31 32 33 34
#include <kdebug.h>

#include "juk.h"

////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////

JuK::JuK(QWidget *parent, const char *name) : KMainWindow(parent, name)
{
  setupActions();
  setupLayout();
  setupPlayer();
35
  readConfig();
36 37 38 39
}

JuK::~JuK()
{
40
  saveConfig();
41
  delete(playTimer);
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
}

////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////

void JuK::setupActions()
{
  // file menu
  KStdAction::open(this, SLOT(openFile()), actionCollection());
  (void) new KAction(i18n("Open &Directory..."), "fileopen", 0, this, SLOT(openDirectory()), actionCollection(), "openDirectory");
  KStdAction::save(this, SLOT(saveFile()), actionCollection());
  (void) new KAction(i18n("Delete"), "edittrash", 0, this, SLOT(deleteFile()), actionCollection(), "deleteFile");
  KStdAction::quit(this, SLOT(quit()), actionCollection());
  
  // edit menu
  KStdAction::cut(this, SLOT(cut()), actionCollection());
  KStdAction::copy(this, SLOT(copy()), actionCollection());
  KStdAction::paste(this, SLOT(paste()), actionCollection());
  KStdAction::selectAll(this, SLOT(selectAll()), actionCollection());
 
  // play menu
64 65 66 67
  addToPlaylistAction = new KAction(i18n("&Add to Playlist"), "enqueue", 0, this, 
				    SLOT(addToPlaylist()), actionCollection(), "addToPlaylist");
  removeFromPlaylistAction = new KAction(i18n("&Remove from Playlist"), "dequeue", 0, this, 
					 SLOT(removeFromPlaylist()), actionCollection(), "removeFromPlaylist");
68 69 70 71 72 73
  playAction = new KAction(i18n("&Play"), "1rightarrow", 0, this, SLOT(playFile()), actionCollection(), "playFile");
  pauseAction = new KAction(i18n("P&ause"), "player_pause", 0, this, SLOT(pauseFile()), actionCollection(), "pauseFile");
  stopAction = new KAction(i18n("&Stop"), "player_stop", 0, this, SLOT(stopFile()), actionCollection(), "stopFile");

  // function menu

74 75
  showTaggerAction = new KAction(i18n("Tagger"), "tag", 0, this, SLOT(showTagger()), actionCollection(), "showTagger");
  showPlaylistAction = new KAction(i18n("Playlist Editor"), "edit", 0, this, SLOT(showPlaylist()), actionCollection(), "showPlaylist");
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
  

  // just in the toolbar
  sliderAction = new SliderAction(i18n("Track Position"), actionCollection(), "trackPositionAction");

  createGUI();
}

void JuK::setupLayout()
{
  // automagically save and restore settings
  this->setAutoSaveSettings();

  // create the main widgets
  tagger = new TaggerWidget(this);
  playlist = new PlaylistWidget(this);
  
  showTagger();

  // set the slider to the proper orientation and make it stay that way
  sliderAction->updateOrientation();
  connect(this, SIGNAL(dockWindowPositionChanged(QDockWindow *)), sliderAction, SLOT(updateOrientation(QDockWindow *)));
98 99 100

  // playlist item activation connection
  connect(playlist->getPlaylistList(), SIGNAL(doubleClicked(QListViewItem *)), this, SLOT(playItem(QListViewItem *)));
101 102

  tagger->getTaggerList()->setFocus();
103 104 105 106 107 108 109 110 111
}

void JuK::setupPlayer()
{
  trackPositionDragging=false;
  noSeek=false;
  pauseAction->setEnabled(false);
  stopAction->setEnabled(false);

112 113 114
  playTimer=new QTimer(this);
  connect(playTimer, SIGNAL(timeout()), this, SLOT(pollPlay()));

115 116 117 118 119 120 121 122 123 124
  if(sliderAction && sliderAction->getTrackPositionSlider() && sliderAction->getVolumeSlider()) {
    connect(sliderAction->getTrackPositionSlider(), SIGNAL(valueChanged(int)), this, SLOT(trackPositionSliderUpdate(int)));
    connect(sliderAction->getTrackPositionSlider(), SIGNAL(sliderPressed()), this, SLOT(trackPositionSliderClick()));
    connect(sliderAction->getTrackPositionSlider(), SIGNAL(sliderReleased()), this, SLOT(trackPositionSliderRelease()));    
    sliderAction->getTrackPositionSlider()->setEnabled(false);

    connect(sliderAction->getVolumeSlider(), SIGNAL(valueChanged(int)), this, SLOT(setVolume(int)));
  }
}

125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
void JuK::readConfig()
{
  KConfig *config = KGlobal::config();
  { // player settings
    KConfigGroupSaver saver(config, "Player");
    if(sliderAction && sliderAction->getVolumeSlider()) {
      int volume = config->readNumEntry("Volume", sliderAction->getVolumeSlider()->maxValue());
      sliderAction->getVolumeSlider()->setValue(volume);
    }
  }
}

void JuK::saveConfig()
{
  KConfig *config = KGlobal::config();
  { // player settings
    KConfigGroupSaver saver(config, "Player");
    if(sliderAction && sliderAction->getVolumeSlider())
      config->writeEntry("Volume", sliderAction->getVolumeSlider()->value());
  }  
}

147 148 149 150 151 152 153 154 155 156 157 158 159
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// private slot definitions
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// private action slot implementations - file menu
////////////////////////////////////////////////////////////////////////////////

void JuK::openFile()
{
  QStringList files = KFileDialog::getOpenFileNames(QString::null, "*.mp3|MPEG Audio (*.mp3)");
160
  tagger->add(files);
161 162 163 164 165 166 167
}

void JuK::openDirectory()
{
  tagger->add(KFileDialog::getExistingDirectory());
}

168 169 170 171 172 173
void JuK::saveFile()
{
  if(tagger && tagger->isVisible())
    tagger->save();
}

174 175
void JuK::quit()
{
176
  delete(this);
177 178 179 180 181 182 183 184 185 186 187
}

////////////////////////////////////////////////////////////////////////////////
// function menu
////////////////////////////////////////////////////////////////////////////////

void JuK::showTagger()
{
  playlist->hide();
  tagger->show();
  setCentralWidget(tagger);
188 189 190 191 192 193

  addToPlaylistAction->setEnabled(true);
  removeFromPlaylistAction->setEnabled(false);

  showTaggerAction->setEnabled(false);
  showPlaylistAction->setEnabled(true);
194 195 196 197 198 199 200
}

void JuK::showPlaylist()
{
  tagger->hide();
  playlist->show();
  setCentralWidget(playlist);
201 202 203 204 205 206

  addToPlaylistAction->setEnabled(false);
  removeFromPlaylistAction->setEnabled(true);

  showTaggerAction->setEnabled(true);
  showPlaylistAction->setEnabled(false);
207 208 209 210 211 212
}

////////////////////////////////////////////////////////////////////////////////
// player menu
////////////////////////////////////////////////////////////////////////////////

213 214
void JuK::addToPlaylist()
{
215 216
  QPtrList<QListViewItem> items(tagger->getSelectedItems());
  playlist->add(items);
217 218 219 220
}

void JuK::removeFromPlaylist()
{
221 222
  QPtrList<QListViewItem> items(tagger->getSelectedItems());
  playlist->remove(items);
223
}
224 225 226

void JuK::playFile()
{
227 228 229 230 231 232
  if(player.paused()) {
    player.play();
    if(player.playing()) {
      playAction->setEnabled(false);
      pauseAction->setEnabled(true);
      stopAction->setEnabled(true);
233
      playTimer->start(pollInterval);
234 235 236
    }
  }
  else if(playlist) {
237 238 239
    QPtrList<QListViewItem> items(tagger->getSelectedItems());
    if(items.count() > 0)
      playItem(dynamic_cast<FileListItem *>(items.at(0)));
240 241
    else
      playItem(playlist->firstItem());
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
  }
}

void JuK::pauseFile()
{
  playTimer->stop();
  player.pause();
  playAction->setEnabled(true);
  pauseAction->setEnabled(false);
}

void JuK::stopFile()
{
  playTimer->stop();
  player.stop();
  playAction->setEnabled(true);
  pauseAction->setEnabled(false);
  stopAction->setEnabled(false);
  sliderAction->getTrackPositionSlider()->setValue(0);
  sliderAction->getTrackPositionSlider()->setEnabled(false);
262
  playingItem->setPixmap(0, 0);
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
}

void JuK::trackPositionSliderClick()
{
  trackPositionDragging=true;
}

void JuK::trackPositionSliderRelease()
{
  trackPositionDragging=false;
  player.seekPosition(sliderAction->getTrackPositionSlider()->value());
}

void JuK::trackPositionSliderUpdate(int position)
{
  if(player.playing() && !trackPositionDragging && !noSeek) {
    player.seekPosition(position);
  }
}

void JuK::pollPlay()
{
285
  noSeek = true;
286 287 288 289 290 291
  if(!player.playing()) {
    playTimer->stop();
    if(player.paused()) {
      pauseFile();
    }
    else {
292 293 294 295 296 297 298 299 300 301 302 303
      if(playingItem && dynamic_cast<FileListItem*>(playingItem->itemBelow())) {
	playingItem->setPixmap(0, 0);
        playingItem = dynamic_cast<FileListItem *>(playingItem->itemBelow());
	sliderAction->getTrackPositionSlider()->setValue(0);
	player.play(playingItem->absFilePath(), player.getVolume());
	if(player.playing()) {
	  playTimer->start(pollInterval);
	  playingItem->setPixmap(0, QPixmap(UserIcon("playing")));
	}
      }
      else
	stopFile();
304 305 306 307 308 309
    }
  }
  else if(!trackPositionDragging) {
    //    kdDebug() << player.position() << " - " << sliderAction->getTrackPositionSlider()->maxValue() << endl;
    sliderAction->getTrackPositionSlider()->setValue(player.position());
  }
310 311 312 313

  if(player.playing() && float(player.totalTime() - player.currentTime()) < pollInterval * 2)
    playTimer->changeInterval(50);

314 315 316 317 318 319 320 321 322 323 324 325
  noSeek=false;
}

void JuK::setVolume(int volume)
{
  if(sliderAction && sliderAction->getVolumeSlider() && 
     sliderAction->getVolumeSlider()->maxValue() > 0 &&
     volume >= 0 && sliderAction->getVolumeSlider()->maxValue() >= volume)
    {
      player.setVolume(float(volume) / float(sliderAction->getVolumeSlider()->maxValue()));
    }
}
326 327 328 329 330 331 332 333 334 335

void JuK::playItem(QListViewItem *item)
{
  FileListItem *fileListItem = dynamic_cast<FileListItem *>(item);
  if(fileListItem)
    playItem(fileListItem);
}

void JuK::playItem(FileListItem *item)
{
336
  if(player.playing() || player.paused())
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
    stopFile();
  
  if(item) {
    playingItem = item;
    float volume = float(sliderAction->getVolumeSlider()->value()) / float(sliderAction->getVolumeSlider()->maxValue());  
    player.play(playingItem->absFilePath(), volume);
    if(player.playing()) {
      playAction->setEnabled(false);
      pauseAction->setEnabled(true);
      stopAction->setEnabled(true);
      sliderAction->getTrackPositionSlider()->setEnabled(true);
      playingItem->setPixmap(0, QPixmap(UserIcon("playing")));
      playTimer->start(pollInterval);
    }
  }
}
353 354 355 356 357 358 359 360 361 362

void JuK::playTaggerItem(QListViewItem *item)
{

}

void JuK::playTaggerItem(FileListItem *item)
{

}