/* smplayer, GUI front-end for mplayer. Copyright (C) 2007 Ricardo Villalba 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "playlist.h" #include #include #include "myaction.h" #include #include #include #include "filedialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "helper.h" #include "images.h" #include "preferences.h" #include "version.h" #include "global.h" #include "core.h" #include "config.h" #if KDE_SUPPORT #include #endif #define COL_PLAY 0 #define COL_NAME 1 #define COL_TIME 2 Playlist::Playlist( Core *c, QWidget * parent, const char * name, WFlags f) : QMainWindow(parent, name, f) { modified = false; core = c; playlist_path = ""; latest_dir = ""; createTable(); setCentralWidget( listView ); createActions(); createToolbar(); clear(); languageChange(); #if !DOCK_PLAYLIST setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ); adjustSize(); #else //setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); #endif setAcceptDrops(TRUE); // Random seed QTime t; t.start(); srand( t.hour() * 3600 + t.minute() * 60 + t.second() ); loadSettings(); // Save config every 5 minutes. save_timer = new QTimer(this); connect( save_timer, SIGNAL(timeout()), this, SLOT(maybeSaveSettings()) ); save_timer->start( 5 * 60000 ); } Playlist::~Playlist() { saveSettings(); } void Playlist::setModified(bool mod) { qDebug("Playlist::setModified: %d", mod); modified = mod; emit modifiedChanged(modified); } void Playlist::createTable() { listView = new MyTable( this, "listView" ); listView->setSizeHint(QSize(100,100)); listView->setShowGrid( FALSE ); listView->setNumCols(COL_TIME + 1); listView->setReadOnly(TRUE); listView->setFocusStyle(QTable::FollowStyle); listView->setSelectionMode(QTable::MultiRow); //listView->verticalHeader()->hide(); listView->setSorting(FALSE); connect( listView, SIGNAL(doubleClicked(int,int,int,const QPoint &)), this, SLOT(itemDoubleClicked(int)) ); connect( core, SIGNAL(mediaFinished()), this, SLOT(playNext()) ); connect( core, SIGNAL(mediaLoaded()), this, SLOT(getMediaInfo()) ); } void Playlist::createActions() { openAct = new MyAction(this, "pl_open"); connect( openAct, SIGNAL(activated()), this, SLOT(load()) ); saveAct = new MyAction(this, "pl_save"); connect( saveAct, SIGNAL(activated()), this, SLOT(save()) ); playAct = new MyAction(this, "pl_play"); connect( playAct, SIGNAL(activated()), this, SLOT(playCurrent()) ); nextAct = new MyAction(Qt::Key_N /*Qt::Key_Greater*/, this, "pl_next"); connect( nextAct, SIGNAL(activated()), this, SLOT(playNext()) ); prevAct = new MyAction(Qt::Key_P /*Qt::Key_Less*/, this, "pl_prev"); connect( prevAct, SIGNAL(activated()), this, SLOT(playPrev()) ); moveUpAct = new MyAction(this, "pl_move_up"); connect( moveUpAct, SIGNAL(activated()), this, SLOT(upItem()) ); moveDownAct = new MyAction(this, "pl_move_down"); connect( moveDownAct, SIGNAL(activated()), this, SLOT(downItem()) ); repeatAct = new MyAction(this, "pl_repeat"); repeatAct->setToggleAction(true); shuffleAct = new MyAction(this, "pl_shuffle"); shuffleAct->setToggleAction(true); // Add actions addCurrentAct = new MyAction(this, "pl_add_current"); connect( addCurrentAct, SIGNAL(activated()), this, SLOT(addCurrentFile()) ); addFilesAct = new MyAction(this, "pl_add_files"); connect( addFilesAct, SIGNAL(activated()), this, SLOT(addFiles()) ); addDirectoryAct = new MyAction(this, "pl_add_directory"); connect( addDirectoryAct, SIGNAL(activated()), this, SLOT(addDirectory()) ); // Remove actions removeSelectedAct = new MyAction(this, "pl_remove_selected"); connect( removeSelectedAct, SIGNAL(activated()), this, SLOT(removeSelected()) ); removeAllAct = new MyAction(this, "pl_remove_all"); connect( removeAllAct, SIGNAL(activated()), this, SLOT(removeAll()) ); // Edit editAct = new MyAction(this, "pl_edit"); connect( editAct, SIGNAL(activated()), this, SLOT(editCurrentItem()) ); } void Playlist::createToolbar() { toolbar = new QToolBar(this, "toolbar"); toolbar->setResizeEnabled(false); toolbar->setMovingEnabled(false); addDockWindow(toolbar, Qt::DockBottom ); openAct->addTo( toolbar ); saveAct->addTo( toolbar ); toolbar->addSeparator(); add_menu = new QPopupMenu( this, "add_menu" ); addCurrentAct->addTo( add_menu ); addFilesAct->addTo( add_menu ); addDirectoryAct->addTo( add_menu ); add_button = new QToolButton( toolbar, "add_button" ); add_button->setPopup( add_menu ); add_button->setPopupDelay(1); remove_menu = new QPopupMenu( this, "remove_menu" ); removeSelectedAct->addTo( remove_menu ); removeAllAct->addTo( remove_menu ); remove_button = new QToolButton( toolbar, "remove_button" ); remove_button->setPopup( remove_menu ); remove_button->setPopupDelay(1); toolbar->addSeparator(); playAct->addTo( toolbar ); toolbar->addSeparator(); prevAct->addTo( toolbar ); nextAct->addTo( toolbar ); toolbar->addSeparator(); repeatAct->addTo( toolbar ); shuffleAct->addTo( toolbar ); toolbar->addSeparator(); moveUpAct->addTo( toolbar ); moveDownAct->addTo( toolbar ); // Popup menu popup = new QPopupMenu(this, "popup"); playAct->addTo( popup ); removeSelectedAct->addTo( popup ); editAct->addTo( popup ); connect( listView, SIGNAL(contextMenuRequested(int,int,const QPoint &)), this, SLOT(showPopup(int,int,const QPoint &)) ); } void Playlist::languageChange() { listView->horizontalHeader()->setLabel( COL_PLAY, " " ); listView->horizontalHeader()->setLabel( COL_NAME, tr("Name") ); listView->horizontalHeader()->setLabel( COL_TIME, tr("Length") ); openAct->change( Images::icon("open"), tr("&Load") ); saveAct->change( Images::icon("save"), tr("&Save") ); playAct->change( Images::icon("play"), tr("&Play") ); nextAct->change( Images::icon("next"), tr("&Next") ); prevAct->change( Images::icon("previous"), tr("Pre&vious") ); moveUpAct->change( Images::icon("up"), tr("Move &up") ); moveDownAct->change( Images::icon("down"), tr("Move &down") ); repeatAct->change( Images::icon("repeat"), tr("&Repeat") ); shuffleAct->change( Images::icon("shuffle"), tr("S&huffle") ); // Add actions addCurrentAct->change( tr("Add ¤t file") ); addFilesAct->change( tr("Add &file(s)") ); addDirectoryAct->change( tr("Add &directory") ); // Remove actions removeSelectedAct->change( tr("Remove &selected") ); removeAllAct->change( tr("Remove &all") ); // Edit editAct->change( tr("&Edit") ); // Tool buttons add_button->setIconSet( Images::icon("plus") ); QToolTip::add( add_button, tr("Add...") ); remove_button->setIconSet( Images::icon("minus") ); QToolTip::add( remove_button, tr("Remove...") ); // Icon setIcon( Images::icon("logo", 64) ); setCaption( tr( "SMPlayer - Playlist" ) ); } void Playlist::list() { qDebug("Playlist::list"); PlaylistItemList::iterator it; for ( it = pl.begin(); it != pl.end(); ++it ) { qDebug( "filename: '%s', name: '%s' duration: %f", (*it).filename().utf8().data(), (*it).name().utf8().data(), (*it).duration() ); } } void Playlist::updateView() { listView->setNumRows( pl.count() ); int n=0; QString number; QString name; QString time; PlaylistItemList::iterator it; for ( it = pl.begin(); it != pl.end(); ++it ) { number.sprintf("%03d", n +1 ); name = (*it).name(); if (name.isEmpty()) name = (*it).filename(); time = Helper::formatTime( (int) (*it).duration() ); //listView->setText(n, COL_POS, number); listView->setText(n, COL_NAME, name); listView->setText(n, COL_TIME, time); if ((*it).played()) { listView->setPixmap(n, COL_PLAY, Images::icon("ok_small") ); } else { listView->setPixmap(n, COL_PLAY, QPixmap() ); } n++; } for (n=0; n <= COL_TIME; n++) listView->adjustColumn(n); setCurrentItem(current_item); //adjustSize(); } void Playlist::setCurrentItem(int current) { int old_current = current_item; current_item = current; if ((current_item > -1) && (current_item < pl.count())) { pl[current_item].setPlayed(TRUE); } if ( (old_current >= 0) && (old_current < listView->numRows()) ) { listView->setPixmap(old_current, COL_PLAY, QPixmap() ); } if ( (current_item >= 0) && (current_item < listView->numRows()) ) { listView->setPixmap(current_item, COL_PLAY, Images::icon("play") ); } //if (current_item >= 0) listView->selectRow(current_item); if (current_item >= 0) { listView->clearSelection(); listView->setCurrentCell( current_item, 0); listView->selectRow(current_item); } } void Playlist::clear() { pl.clear(); listView->setNumRows(0); setCurrentItem(0); setModified( false ); } int Playlist::count() { return pl.count(); } bool Playlist::isEmpty() { return pl.isEmpty(); } void Playlist::addItem(QString filename, QString name, double duration) { qDebug("Playlist::addItem: '%s'", filename.utf8().data()); #ifdef Q_OS_WIN filename = Helper::changeSlashes(filename); #endif // Test if already is in the list bool exists = FALSE; PlaylistItemList::iterator it; for ( it = pl.begin(); it != pl.end(); ++it ) { if ( (*it).filename() == filename ) { exists = TRUE; break; } } if (!exists) { if (name.isEmpty()) { QFileInfo fi(filename); if (fi.exists()) { // Local file name = fi.fileName(); //fi.baseName(TRUE); } else { // Stream name = filename; } } pl.append( PlaylistItem(filename, name, duration) ); //setModified( true ); // Better set the modified on a higher level } else { qDebug(" Not added. File already in the list"); } } void Playlist::load_m3u(QString file) { qDebug("Playlist::load_m3u"); bool utf8 = (QFileInfo(file).extension(FALSE).lower() == "m3u8"); QRegExp m3u_id("^#EXTM3U|^#M3U"); QRegExp info("^#EXTINF:(.*),(.*)"); QFile f( file ); if ( f.open( IO_ReadOnly ) ) { playlist_path = QFileInfo(file).dirPath(); clear(); QString filename=""; QString name=""; double duration=0; QTextStream stream( &f ); if (utf8) stream.setEncoding(QTextStream::UnicodeUTF8); else stream.setEncoding(QTextStream::Locale); QString line; while ( !stream.atEnd() ) { line = stream.readLine(); // line of text excluding '\n' qDebug( " * line: '%s'", line.utf8().data() ); if (m3u_id.search(line)!=-1) { //#EXTM3U // Ignore line } else if (info.search(line)!=-1) { duration = info.cap(1).toDouble(); name = info.cap(2); qDebug(" * name: '%s', duration: %f", name.utf8().data(), duration ); } else if (line.startsWith("#")) { // Comment // Ignore } else { filename = line; QFileInfo fi(filename); if (fi.exists()) { filename = fi.absFilePath(); } if (!fi.exists()) { if (QFileInfo( playlist_path + "/" + filename).exists() ) { filename = playlist_path + "/" + filename; } } addItem( filename, name, duration ); name=""; duration = 0; } } f.close(); list(); updateView(); setModified( false ); startPlay(); } } bool Playlist::save_m3u(QString file) { qDebug("Playlist::save_m3u: '%s'", file.utf8().data()); QString dir_path = QFileInfo(file).dirPath(); if (!dir_path.endsWith("/")) dir_path += "/"; #ifdef Q_OS_WIN dir_path = Helper::changeSlashes(dir_path); #endif qDebug(" * dirPath: '%s'", dir_path.utf8().data()); bool utf8 = (QFileInfo(file).extension(FALSE).lower() == "m3u8"); QFile f( file ); if ( f.open( IO_WriteOnly ) ) { QTextStream stream( &f ); if (utf8) stream.setEncoding(QTextStream::UnicodeUTF8); else stream.setEncoding(QTextStream::Locale); QString filename; stream << "#EXTM3U" << "\n"; stream << "# Playlist created by SMPlayer " << VERSION << " \n"; PlaylistItemList::iterator it; for ( it = pl.begin(); it != pl.end(); ++it ) { filename = (*it).filename(); #ifdef Q_OS_WIN filename = Helper::changeSlashes(filename); #endif stream << "#EXTINF:"; stream << (*it).duration() << ","; stream << (*it).name() << "\n"; // Try to save the filename as relative instead of absolute if (filename.startsWith( dir_path )) { filename = filename.mid( dir_path.length() ); } stream << filename << "\n"; } f.close(); setModified( false ); return true; } else { return false; } } void Playlist::load() { if (maybeSave()) { QString s = MyFileDialog::getOpenFileName( lastDir(), tr("Playlists") +" (*.m3u *.m3u8)", this, "open file dialog", tr("Choose a file") ); if (!s.isEmpty()) { latest_dir = QFileInfo(s).dirPath(TRUE); load_m3u(s); } } } bool Playlist::save() { QString s = MyFileDialog::getSaveFileName( lastDir(), tr("Playlists") +" (*.m3u *.m3u8)", this, "save file dialog", tr("Choose a filename") ); if (!s.isEmpty()) { // If filename has no extension, add it if (QFileInfo(s).extension().isEmpty()) { s = s + ".m3u"; } if (QFileInfo(s).exists()) { int res = QMessageBox::question( this, tr("Confirm overwrite?"), tr("The file %1 already exists.\n" "Do you want to overwrite?").arg(s), QMessageBox::Yes, QMessageBox::No, QMessageBox::NoButton); if (res == QMessageBox::No ) { return false; } } latest_dir = QFileInfo(s).dirPath(TRUE); return save_m3u(s); } else { return false; } } bool Playlist::maybeSave() { if (!isModified()) return true; int res = QMessageBox::question( this, tr("Playlist modified"), tr("There are unsaved changes, do you want to save the playlist?"), QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel); switch (res) { case QMessageBox::No : return true; // Discard changes case QMessageBox::Cancel : return false; // Cancel operation default : return save(); } } void Playlist::playCurrent() { int current = listView->currentRow(); if (current > -1) { playItem(current); } } void Playlist::itemDoubleClicked(int row) { qDebug("Playlist::itemDoubleClicked: row: %d", row ); playItem(row); } void Playlist::showPopup(int row, int col, const QPoint & pos) { qDebug("Playlist::showPopup: row: %d col: %d", row, col ); if (!popup->isVisible()) { popup->move( pos ); popup->show(); } } void Playlist::startPlay() { // Start to play if ( shuffleAct->isOn() ) playItem( chooseRandomItem() ); else playItem(0); } void Playlist::playItem( int n ) { qDebug("Playlist::playItem: %d (count:%d)", n, pl.count()); if ( (n >= pl.count()) || (n < 0) ) { qDebug(" out of range"); emit playlistEnded(); return; } qDebug(" playlist_path: '%s'", playlist_path.utf8().data() ); QString filename = pl[n].filename(); QString filename_with_path = playlist_path + "/" + filename; if (!filename.isEmpty()) { //pl[n].setPlayed(TRUE); setCurrentItem(n); core->open(filename, 0); } } void Playlist::playNext() { qDebug("Playlist::playNext"); if (shuffleAct->isOn()) { // Shuffle int chosen_item = chooseRandomItem(); if (chosen_item == -1) { clearPlayedTag(); if (repeatAct->isOn()) chosen_item = chooseRandomItem(); } playItem( chosen_item ); } else { bool finished_list = (current_item+1 >= pl.count()); if (finished_list) clearPlayedTag(); if ( (repeatAct->isOn()) && (finished_list) ) { playItem(0); } else { playItem( current_item+1 ); } } } void Playlist::playPrev() { qDebug("Playlist::playPrev"); playItem( current_item-1 ); } void Playlist::getMediaInfo() { qDebug("Playlist:: getMediaInfo"); QString filename = core->mdat.filename; double duration = core->mdat.duration; QString name = core->mdat.clip_name; QString artist = core->mdat.clip_artist; #ifdef Q_OS_WIN filename = Helper::changeSlashes(filename); #endif if (name.isEmpty()) { QFileInfo fi(filename); if (fi.exists()) { // Local file name = fi.fileName(); } else { // Stream name = filename; } } if (!artist.isEmpty()) name = artist + " - " + name; int pos=0; PlaylistItemList::iterator it; for ( it = pl.begin(); it != pl.end(); ++it ) { if ( (*it).filename() == filename ) { if ((*it).duration()<1) { if (!name.isEmpty()) { (*it).setName(name); } (*it).setDuration(duration); //setModified( true ); } else // Edited name (sets duration to 1) if ((*it).duration()==1) { (*it).setDuration(duration); //setModified( true ); } setCurrentItem(pos); } pos++; } updateView(); } // Add current file to playlist void Playlist::addCurrentFile() { qDebug("Playlist::addCurrentFile"); if (!core->mdat.filename.isEmpty()) { addItem( core->mdat.filename, "", 0 ); getMediaInfo(); } } void Playlist::addFiles() { QStringList files = MyFileDialog::getOpenFileNames( tr("All files") +" (*.*)", lastDir(), this, "open files dialog", tr("Select one or more files to open") ); if (files.count()!=0) addFiles(files); } void Playlist::addFiles(QStringList files) { qDebug("Playlist::addFiles"); QStringList::Iterator it = files.begin(); while( it != files.end() ) { addItem( (*it), "", 0 ); // FIXME: set latest_dir only if the file is a local file, // to avoid that dvd:, vcd: and so on will be used. /* latest_dir = QFileInfo((*it)).dirPath(TRUE); */ ++it; } updateView(); qDebug( " * latest_dir: '%s'", latest_dir.utf8().data() ); } void Playlist::addDirectory() { QString s = MyFileDialog::getExistingDirectory( lastDir(), this, "get existing directory", tr("Choose a directory"), TRUE ); if (!s.isEmpty()) { addDirectory(s); latest_dir = s; } } void Playlist::addDirectory(QString dir) { QStringList dir_list = QDir(dir).entryList(); QString filename; QStringList::Iterator it = dir_list.begin(); while( it != dir_list.end() ) { filename = dir; if (filename.right(1)!="/") filename += "/"; filename += (*it); if (!QFileInfo(filename).isDir()) { addItem( filename, "", 0 ); } ++it; } updateView(); } // Remove selected items void Playlist::removeSelected() { qDebug("Playlist::removeSelected"); int first_selected = -1; for (int n=0; n < listView->numRows(); n++) { if (listView->isRowSelected(n)) { qDebug(" row %d selected", n); pl[n].setMarkForDeletion(TRUE); if (first_selected == -1) first_selected = n; } } PlaylistItemList::iterator it; for ( it = pl.begin(); it != pl.end(); ++it ) { if ( (*it).markedForDeletion() ) { qDebug("Remove '%s'", (*it).filename().utf8().data()); it = pl.remove(it); it--; setModified( true ); } } if (isEmpty()) setModified(false); updateView(); if (first_selected >= listView->numRows()) first_selected = listView->numRows() - 1; if ( ( first_selected > -1) && ( first_selected < listView->numRows() ) ) { listView->clearSelection(); listView->setCurrentCell( first_selected, 0); listView->selectRow( first_selected ); } } void Playlist::removeAll() { /* pl.clear(); updateView(); setModified( false ); */ clear(); } void Playlist::clearPlayedTag() { PlaylistItemList::iterator it; for ( it = pl.begin(); it != pl.end(); ++it ) { (*it).setPlayed(FALSE); } updateView(); } int Playlist::chooseRandomItem() { qDebug( "Playlist::chooseRandomItem"); QValueList fi; //List of not played items (free items) int n=0; PlaylistItemList::iterator it; for ( it = pl.begin(); it != pl.end(); ++it ) { if (! (*it).played() ) fi.append(n); n++; } qDebug(" * free items: %d", fi.count() ); if (fi.count()==0) return -1; // none free qDebug(" * items: "); for (int i=0; i < fi.count(); i++) { qDebug(" * item: %d", fi[i]); } int selected = (int) ((double) fi.count() * rand()/(RAND_MAX+1.0)); qDebug(" * selected item: %d (%d)", selected, fi[selected]); return fi[selected]; } void Playlist::swapItems(int item1, int item2 ) { PlaylistItem it1 = pl[item1]; pl[item1] = pl[item2]; pl[item2] = it1; setModified( true ); } void Playlist::upItem() { qDebug("Playlist::upItem"); int current = listView->currentRow(); qDebug(" currentRow: %d", current ); if (current >= 1) { swapItems( current, current-1 ); if (current_item == (current-1)) current_item = current; else if (current_item == current) current_item = current-1; updateView(); listView->clearSelection(); listView->setCurrentCell( current-1, 0); } } void Playlist::downItem() { qDebug("Playlist::downItem"); int current = listView->currentRow(); qDebug(" currentRow: %d", current ); if ( (current > -1) && (current < (pl.count()-1)) ) { swapItems( current, current+1 ); if (current_item == (current+1)) current_item = current; else if (current_item == current) current_item = current+1; updateView(); listView->clearSelection(); listView->setCurrentCell( current+1, 0); } } void Playlist::editCurrentItem() { int current = listView->currentRow(); if (current > -1) editItem(current); } void Playlist::editItem(int item) { QString current_name = pl[item].name(); if (current_name.isEmpty()) current_name = pl[item].filename(); bool ok; QString text = QInputDialog::getText( tr("Edit name"), tr("Type the name that will be displayed in the playlist for this file:"), QLineEdit::Normal, current_name, &ok, this ); if ( ok && !text.isEmpty() ) { // user entered something and pressed OK pl[item].setName(text); // If duration == 0 the name will be overwritten! if (pl[item].duration()<1) pl[item].setDuration(1); updateView(); setModified( true ); } } // Drag&drop void Playlist::dragEnterEvent( QDragEnterEvent *e ) { qDebug("Playlist::dragEnterEvent"); #if QT_VERSION < 0x040000 e->accept( (QUriDrag::canDecode(e) || QTextDrag::canDecode(e)) ); #else e->accept(QUriDrag::canDecode(e)); #endif } void Playlist::dropEvent( QDropEvent *e ) { qDebug("Playlist::dropEvent"); QStringList files; if (QUriDrag::canDecode(e)) { QStrList l; QUriDrag::decode(e, l); QString s; for ( unsigned int i= 0; i < l.count(); ++i ) { s = l.at(i); qDebug(" * '%s'", s.utf8().data() ); #if KDE_SUPPORT KURL u(s); #else QUrl u(s); #endif qDebug(" * protocol: '%s'", u.protocol().utf8().data()); qDebug(" * path: '%s'", u.path().utf8().data()); //qDebug(" filename:='%s'", u.fileName().utf8().data()); if (u.protocol()=="file") { s = u.path(); } files.append( s ); } } #if QT_VERSION < 0x040000 else if (QTextDrag::canDecode(e)) { QString s; if (QTextDrag::decode(e, s)) { qDebug(" * '%s'", s.utf8().data() ); files.append( s ); } } #endif QStringList only_files; for (int n = 0; n < files.count(); n++) { if ( QFileInfo( files[n] ).isDir() ) { addDirectory( files[n] ); } else { //addFiles( files[n] ); //addItem( files[n], "", 0 ); only_files.append( files[n] ); } } //updateView(); //addFiles(files); addFiles( only_files ); } void Playlist::hideEvent( QHideEvent * ) { emit visibilityChanged(); } void Playlist::showEvent( QShowEvent * ) { emit visibilityChanged(); } void Playlist::closeEvent( QCloseEvent * e ) { saveSettings(); e->accept(); } void Playlist::maybeSaveSettings() { qDebug("Playlist::maybeSaveSettings"); if (isModified()) saveSettings(); } void Playlist::saveSettings() { qDebug("Playlist::saveSettings"); QSettings * set = settings; set->beginGroup( "playlist"); set->writeEntry( "repeat", repeatAct->isOn() ); set->writeEntry( "shuffle", shuffleAct->isOn() ); #if !DOCK_PLAYLIST set->writeEntry( "window_width", size().width() ); set->writeEntry( "window_height", size().height() ); #endif set->writeEntry( "latest_dir", latest_dir ); set->endGroup(); //Save current list set->beginGroup( "playlist_contents"); set->writeEntry( "count", (int) pl.count() ); for ( int n=0; n < pl.count(); n++ ) { set->writeEntry( QString("item_%1_filename").arg(n), pl[n].filename() ); set->writeEntry( QString("item_%1_duration").arg(n), pl[n].duration() ); set->writeEntry( QString("item_%1_name").arg(n), pl[n].name() ); } set->writeEntry( "current_item", current_item ); set->writeEntry( "modified", modified ); set->endGroup(); } void Playlist::loadSettings() { qDebug("Playlist::loadSettings"); QSettings * set = settings; set->beginGroup( "playlist"); repeatAct->setOn( set->readBoolEntry( "repeat", repeatAct->isOn() ) ); shuffleAct->setOn( set->readBoolEntry( "shuffle", shuffleAct->isOn() ) ); #if !DOCK_PLAYLIST QSize s; s.setWidth( set->readNumEntry( "window_width", size().width() ) ); s.setHeight( set->readNumEntry( "window_height", size().height() ) ); resize( s ); #endif latest_dir = set->readEntry( "latest_dir", latest_dir ); set->endGroup(); //Load latest list set->beginGroup( "playlist_contents"); int count = set->readNumEntry( "count", 0 ); QString filename, name; int duration; for ( int n=0; n < count; n++ ) { filename = set->readEntry( QString("item_%1_filename").arg(n), "" ); duration = set->readNumEntry( QString("item_%1_duration").arg(n), -1 ); name = set->readEntry( QString("item_%1_name").arg(n), "" ); addItem( filename, name, duration ); } setCurrentItem( set->readNumEntry( "current_item", -1 ) ); setModified( set->readBoolEntry( "modified", false ) ); updateView(); set->endGroup(); } QString Playlist::lastDir() { QString last_dir = latest_dir; if (last_dir.isEmpty()) last_dir = pref->latest_dir; return last_dir; }