Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 4b04d9a4 authored by Scott Wheeler's avatar Scott Wheeler

Several days of changes -- again.

First: Partial restoring of Playlists.  This is a little broken at the
moment, but will be fixed soon.

Also, settings aren't currently being saved with Qt 3.1 Beta 1.  It's a
bug in Qt that I've already patched and sent to qt-bugs.

Added features; fixed bugs.  ;-)

svn path=/trunk/kdemultimedia/juk/; revision=181429
parent 59a684a1
...@@ -57,7 +57,7 @@ CollectionListItem *CollectionList::lookup(const QString &file) ...@@ -57,7 +57,7 @@ CollectionListItem *CollectionList::lookup(const QString &file)
return(itemsDict.find(file)); return(itemsDict.find(file));
} }
PlaylistItem *CollectionList::createItem(const QFileInfo &file) PlaylistItem *CollectionList::createItem(const QFileInfo &file, QListViewItem *)
{ {
if(itemsDict.find(file.absFilePath())) if(itemsDict.find(file.absFilePath()))
return(0); return(0);
......
...@@ -48,7 +48,7 @@ public: ...@@ -48,7 +48,7 @@ public:
QStringList albums() const; QStringList albums() const;
CollectionListItem *lookup(const QString &file); CollectionListItem *lookup(const QString &file);
virtual PlaylistItem *createItem(const QFileInfo &file); virtual PlaylistItem *createItem(const QFileInfo &file, QListViewItem *);
protected: protected:
CollectionList(QWidget *parent = 0); CollectionList(QWidget *parent = 0);
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
// public members // public members
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
JuK::JuK(QWidget *parent, const char *name) : KMainWindow(parent, name) JuK::JuK(QWidget *parent, const char *name) : KMainWindow(parent, name, WDestructiveClose)
{ {
// Expect segfaults if you change this order. // Expect segfaults if you change this order.
...@@ -54,9 +54,6 @@ JuK::~JuK() ...@@ -54,9 +54,6 @@ JuK::~JuK()
void JuK::setupLayout() void JuK::setupLayout()
{ {
// automagically save and restore settings
setAutoSaveSettings();
PlaylistSplitter::initialize(this); PlaylistSplitter::initialize(this);
splitter = PlaylistSplitter::instance(); splitter = PlaylistSplitter::instance();
setCentralWidget(splitter); setCentralWidget(splitter);
...@@ -152,6 +149,9 @@ void JuK::processArgs() ...@@ -152,6 +149,9 @@ void JuK::processArgs()
void JuK::readConfig() void JuK::readConfig()
{ {
// Automagically save and restore many window settings.
setAutoSaveSettings();
KConfig *config = KGlobal::config(); KConfig *config = KGlobal::config();
{ // player settings { // player settings
KConfigGroupSaver saver(config, "Player"); KConfigGroupSaver saver(config, "Player");
...@@ -227,7 +227,9 @@ void JuK::remove() ...@@ -227,7 +227,9 @@ void JuK::remove()
void JuK::quit() void JuK::quit()
{ {
kapp->quit(); // delete(this);
// kapp->quit();
close();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
......
...@@ -35,7 +35,7 @@ public: ...@@ -35,7 +35,7 @@ public:
} }
Qt::Orientation orientation; Qt::Orientation orientation;
int lineCount; uint lineCount;
}; };
ListBoxPixmap::ListBoxPixmap(QListBox *listbox, const QPixmap &pixmap) ListBoxPixmap::ListBoxPixmap(QListBox *listbox, const QPixmap &pixmap)
......
...@@ -43,7 +43,7 @@ Playlist::Playlist(QWidget *parent, const char *name) : KListView(parent, name) ...@@ -43,7 +43,7 @@ Playlist::Playlist(QWidget *parent, const char *name) : KListView(parent, name)
{ {
setup(); setup();
internalFile = true; internalFile = true;
fileName = QString::null; playlistFileName = QString::null;
} }
Playlist::Playlist(const QFileInfo &playlistFile, QWidget *parent, const char *name) : KListView(parent, name) Playlist::Playlist(const QFileInfo &playlistFile, QWidget *parent, const char *name) : KListView(parent, name)
...@@ -51,22 +51,32 @@ Playlist::Playlist(const QFileInfo &playlistFile, QWidget *parent, const char *n ...@@ -51,22 +51,32 @@ Playlist::Playlist(const QFileInfo &playlistFile, QWidget *parent, const char *n
setup(); setup();
internalFile = false; internalFile = false;
fileName = playlistFile.absFilePath(); playlistFileName = playlistFile.absFilePath();
QFile file(fileName); QFile file(playlistFileName);
file.open(IO_ReadOnly); if(!file.open(IO_ReadOnly))
return;
QTextStream stream(&file); QTextStream stream(&file);
// turn off non-explicit sorting
setSorting(columns() + 1);
PlaylistItem *after = 0;
while(!stream.atEnd()) { while(!stream.atEnd()) {
QString itemName = (stream.readLine()).stripWhiteSpace(); QString itemName = (stream.readLine()).stripWhiteSpace();
QFileInfo item(itemName); QFileInfo item(itemName);
if(item.isRelative()) if(item.isRelative())
item.setFile(QDir::cleanDirPath(playlistFile.dirPath(true) + "/" + itemName)); item.setFile(QDir::cleanDirPath(playlistFile.dirPath(true) + "/" + itemName));
if(item.exists() && item.isFile() && item.isReadable()) if(item.exists() && item.isFile() && item.isReadable()) {
createItem(item); if(after)
after = createItem(item, after);
else
after = createItem(item);
}
} }
file.close(); file.close();
...@@ -79,14 +89,49 @@ Playlist::~Playlist() ...@@ -79,14 +89,49 @@ Playlist::~Playlist()
void Playlist::save() void Playlist::save()
{ {
kdDebug() << "Playlist::save() -- Not yet implemented!" << endl; if(internalFile || playlistFileName == QString::null)
// needs an implementation to write to m3u files return saveAs();
QFile file(playlistFileName);
if(!file.open(IO_WriteOnly))
return KMessageBox::error(this, i18n("Could not save to file %1.").arg(playlistFileName));
QTextStream stream(&file);
QStringList fileList = files();
for(QStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it)
stream << *it << endl;
file.close();
} }
void Playlist::saveAs() void Playlist::saveAs()
{ {
kdDebug() << "Playlist::saveAs() -- Not yet implemented!" << endl; // If this is one of our internal files, remove it when we save it to an
// needs an implementation to write to m3u files // "external" file.
if(internalFile && playlistFileName != QString::null)
QFile::remove(playlistFileName);
// This needs to be replace with something that sets the default to the
// playlist name.
QStringList extensions = PlaylistSplitter::playlistExtensions();
playlistFileName = KFileDialog::getSaveFileName(QString::null,
PlaylistSplitter::extensionsString(PlaylistSplitter::playlistExtensions(),
i18n("Playlists")));
playlistFileName = playlistFileName.stripWhiteSpace();
internalFile = false;
if(playlistFileName != QString::null) {
if(!PlaylistSplitter::playlistExtensions().contains(playlistFileName.section('.', -1)))
playlistFileName.append('.' + PlaylistSplitter::playlistExtensions().first());
emit(fileNameChanged(playlistFileName));
save();
}
} }
void Playlist::refresh() void Playlist::refresh()
...@@ -190,9 +235,9 @@ bool Playlist::isInternalFile() const ...@@ -190,9 +235,9 @@ bool Playlist::isInternalFile() const
return(internalFile); return(internalFile);
} }
QString Playlist::file() const QString Playlist::fileName() const
{ {
return(fileName); return(playlistFileName);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
...@@ -256,7 +301,7 @@ void Playlist::contentsDragMoveEvent(QDragMoveEvent *e) ...@@ -256,7 +301,7 @@ void Playlist::contentsDragMoveEvent(QDragMoveEvent *e)
e->accept(false); e->accept(false);
} }
PlaylistItem *Playlist::createItem(const QFileInfo &file) PlaylistItem *Playlist::createItem(const QFileInfo &file, QListViewItem *after)
{ {
CollectionListItem *item = CollectionList::instance()->lookup(file.absFilePath()); CollectionListItem *item = CollectionList::instance()->lookup(file.absFilePath());
...@@ -265,8 +310,10 @@ PlaylistItem *Playlist::createItem(const QFileInfo &file) ...@@ -265,8 +310,10 @@ PlaylistItem *Playlist::createItem(const QFileInfo &file)
if(item && members.contains(file.absFilePath()) == 0 || allowDuplicates) { if(item && members.contains(file.absFilePath()) == 0 || allowDuplicates) {
members.append(file.absFilePath()); members.append(file.absFilePath());
PlaylistItem *newItem = new PlaylistItem(item, this); if(after)
return(newItem); return(new PlaylistItem(item, this, after));
else
return(new PlaylistItem(item, this));
} }
else else
return(0); return(0);
......
...@@ -33,36 +33,44 @@ public: ...@@ -33,36 +33,44 @@ public:
Playlist(const QFileInfo &playlistFile, QWidget *parent = 0, const char *name = 0); Playlist(const QFileInfo &playlistFile, QWidget *parent = 0, const char *name = 0);
virtual ~Playlist(); virtual ~Playlist();
// "File Menu" like operations. "Open" is the constructor above.
virtual void save(); virtual void save();
virtual void saveAs(); virtual void saveAs();
virtual void refresh(); virtual void refresh();
virtual void clearItems(const PlaylistItemList &items); virtual void clearItems(const PlaylistItemList &items);
/** All of the files in the list. */ /**
* All of the (media) files in the list.
*/
QStringList files() const; QStringList files() const;
/** All of the items in the list. */ /**
* All of the items in the list.
*/
PlaylistItemList items() const; PlaylistItemList items() const;
PlaylistItemList selectedItems() const; PlaylistItemList selectedItems() const;
void remove(); void remove();
void remove(const PlaylistItemList &items); void remove(const PlaylistItemList &items);
/** Allow duplicate files in the playlist. */ /**
* Allow duplicate files in the playlist.
*/
void setAllowDuplicates(bool allow); void setAllowDuplicates(bool allow);
/** This gets the next item to be played in the playlist. */ /**
static PlaylistItem *nextItem(PlaylistItem *current, bool random = false); * This is being used as a mini-factory of sorts to make the construction
* of PlaylistItems virtual.
/** This is being used as a mini-factory of sorts to make the construction */
of PlaylistItems virtual. */ virtual PlaylistItem *createItem(const QFileInfo &file, QListViewItem *after = 0);
virtual PlaylistItem *createItem(const QFileInfo &file);
bool isInternalFile() const; bool isInternalFile() const;
QString file() const; QString fileName() const;
// static methods
/**
* This gets the next item to be played in the specified playlist.
*/
static PlaylistItem *nextItem(PlaylistItem *current, bool random = false);
protected: protected:
virtual QDragObject *dragObject(); virtual QDragObject *dragObject();
...@@ -76,30 +84,37 @@ private: ...@@ -76,30 +84,37 @@ private:
int processed; int processed;
bool allowDuplicates; bool allowDuplicates;
// If a file is "internal" it is not one that the user has yet chosen to /**
// save. However for the purposes of being able to restore a user's * If a file is "internal" it is not one that the user has yet chosen to
// loaded playlists it will be saved "internally" in: * save. However for the purposes of being able to restore a user's
// $KDEHOME/share/apps/juk/playlists. * loaded playlists it will be saved "internally" in:
* $KDEHOME/share/apps/juk/playlists.
*/
bool internalFile; bool internalFile;
QString fileName; QString playlistFileName;
private slots: private slots:
void emitSelected(); void emitSelected();
signals: signals:
/** This signal is connected to PlaylistItem::refreshed() in the /**
PlaylistItem class. */ * This signal is connected to PlaylistItem::refreshed() in the
* PlaylistItem class.
*/
void dataChanged(); void dataChanged();
/**
/** This signal is emitted when items are added to the collection list. * This signal is emitted when items are added to the collection list.
This happens in the createItem() method when items are added to the * This happens in the createItem() method when items are added to the
collection. */ * collection.
*/
void collectionChanged(); void collectionChanged();
/** This is emitted when the playlist selection is changed. This is used /**
primarily to notify the TagEditor of the new data. */ * This is emitted when the playlist selection is changed. This is used
* primarily to notify the TagEditor of the new data.
*/
void selectionChanged(const PlaylistItemList &selection); void selectionChanged(const PlaylistItemList &selection);
void fileNameChanged(const QString &fileName);
}; };
#endif #endif
...@@ -149,14 +149,14 @@ void PlaylistBox::deleteItem(PlaylistBoxItem *item) ...@@ -149,14 +149,14 @@ void PlaylistBox::deleteItem(PlaylistBoxItem *item)
// the file then delete it. Otherwise, just remove the file from the // the file then delete it. Otherwise, just remove the file from the
// PlaylistBox. // PlaylistBox.
if(item->playlist()->file() != QString::null) { if(item->playlist()->fileName() != QString::null) {
if(item->playlist()->isInternalFile()) if(item->playlist()->isInternalFile())
QFile::remove(item->playlist()->file()); QFile::remove(item->playlist()->fileName());
else { else {
int remove = KMessageBox::warningYesNoCancel(this, i18n("Do you want to delete this file from the disk as well?")); int remove = KMessageBox::warningYesNoCancel(this, i18n("Do you want to delete this file from the disk as well?"));
if(remove == KMessageBox::Yes) { if(remove == KMessageBox::Yes) {
if(!QFile::remove(item->playlist()->file())) if(!QFile::remove(item->playlist()->fileName()))
KMessageBox::sorry(this, i18n("Could not delete the specified file.")); KMessageBox::sorry(this, i18n("Could not delete the specified file."));
} }
else if(remove == KMessageBox::Cancel) else if(remove == KMessageBox::Cancel)
...@@ -317,11 +317,13 @@ void PlaylistBox::contextDeleteItem() ...@@ -317,11 +317,13 @@ void PlaylistBox::contextDeleteItem()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
PlaylistBoxItem::PlaylistBoxItem(PlaylistBox *listbox, const QPixmap &pix, const QString &text, Playlist *l) PlaylistBoxItem::PlaylistBoxItem(PlaylistBox *listbox, const QPixmap &pix, const QString &text, Playlist *l)
: ListBoxPixmap(listbox, pix, text) : QObject(listbox), ListBoxPixmap(listbox, pix, text)
{ {
list = l; list = l;
setOrientation(Qt::Vertical); setOrientation(Qt::Vertical);
listbox->addName(text); listbox->addName(text);
connect(l, SIGNAL(fileNameChanged(const QString &)), this, SLOT(changeFile(const QString &)));
} }
PlaylistBoxItem::PlaylistBoxItem(PlaylistBox *listbox, const QString &text, Playlist *l) PlaylistBoxItem::PlaylistBoxItem(PlaylistBox *listbox, const QString &text, Playlist *l)
...@@ -341,4 +343,21 @@ Playlist *PlaylistBoxItem::playlist() const ...@@ -341,4 +343,21 @@ Playlist *PlaylistBoxItem::playlist() const
return(list); return(list);
} }
void PlaylistBoxItem::changeFile(const QString &file)
{
QStringList extensions = PlaylistSplitter::playlistExtensions();
// get just the filename, not the path
QString text = file.section(QDir::separator(), -1);
for(QStringList::Iterator it = extensions.begin(); it != extensions.end(); ++it) {
if(text.endsWith(*it)) {
// remove the extension
text = text.left(text.length() - (*it).length() - 1);
setText(text);
return;
}
}
}
#include "playlistbox.moc" #include "playlistbox.moc"
...@@ -39,6 +39,7 @@ class PlaylistBox : public KListBox ...@@ -39,6 +39,7 @@ class PlaylistBox : public KListBox
friend class PlaylistBoxItem; friend class PlaylistBoxItem;
Q_OBJECT Q_OBJECT
public: public:
PlaylistBox(PlaylistSplitter *parent = 0, const char *name = 0); PlaylistBox(PlaylistSplitter *parent = 0, const char *name = 0);
virtual ~PlaylistBox(); virtual ~PlaylistBox();
...@@ -46,6 +47,7 @@ public: ...@@ -46,6 +47,7 @@ public:
QStringList names() const; QStringList names() const;
public slots: public slots:
// All of the slots without parameters default to the selected item.
void save(); void save();
void save(PlaylistBoxItem *item); void save(PlaylistBoxItem *item);
void saveAs(); void saveAs();
...@@ -56,15 +58,16 @@ public slots: ...@@ -56,15 +58,16 @@ public slots:
void duplicate(PlaylistBoxItem *item); void duplicate(PlaylistBoxItem *item);
void deleteItem(); void deleteItem();
void deleteItem(PlaylistBoxItem *item); void deleteItem(PlaylistBoxItem *item);
private: private:
virtual void resizeEvent(QResizeEvent *e); virtual void resizeEvent(QResizeEvent *e);
virtual void dropEvent(QDropEvent *e); virtual void dropEvent(QDropEvent *e);
virtual void dragMoveEvent(QDragMoveEvent *e); virtual void dragMoveEvent(QDragMoveEvent *e);
virtual void mousePressEvent(QMouseEvent *e); virtual void mousePressEvent(QMouseEvent *e);
/** This is used by PlaylistItemBox (a friend class) to add names to the name /**
list returned by names(). */ * This is used by PlaylistItemBox (a friend class) to add names to the name
* list returned by names().
*/
void addName(const QString &name); void addName(const QString &name);
PlaylistSplitter *splitter; PlaylistSplitter *splitter;
...@@ -74,18 +77,20 @@ private: ...@@ -74,18 +77,20 @@ private:
PlaylistBoxItem *contextMenuOn; PlaylistBoxItem *contextMenuOn;
private slots: private slots:
/** Catches QListBox::currentChanged(QListBoxItem *), does a cast and then re-emits /**
the signal as currentChanged(PlaylistBoxItem *). */ * Catches QListBox::currentChanged(QListBoxItem *), does a cast and then re-emits
* the signal as currentChanged(PlaylistBoxItem *).
*/
void playlistChanged(QListBoxItem *item); void playlistChanged(QListBoxItem *item);
void playlistDoubleClicked(QListBoxItem *item); void playlistDoubleClicked(QListBoxItem *item);
void drawContextMenu(QListBoxItem *item, const QPoint &point); void drawContextMenu(QListBoxItem *item, const QPoint &point);
// context menu entries // context menu entries
void contextSave(); void contextSave();
void contextSaveAs(); void contextSaveAs();
void contextRename(); void contextRename();
void contextDuplicate(); void contextDuplicate();
void contextDeleteItem(); void contextDeleteItem();
signals: signals:
void currentChanged(PlaylistBoxItem *); void currentChanged(PlaylistBoxItem *);
...@@ -101,16 +106,21 @@ public: ...@@ -101,16 +106,21 @@ public:
class PlaylistBoxItem : public ListBoxPixmap class PlaylistBoxItem : public QObject, public ListBoxPixmap
{ {
friend class PlaylistBox; friend class PlaylistBox;
Q_OBJECT
public: public:
PlaylistBoxItem(PlaylistBox *listbox, const QPixmap &pix, const QString &text, Playlist *l = 0); PlaylistBoxItem(PlaylistBox *listbox, const QPixmap &pix, const QString &text, Playlist *l = 0);
PlaylistBoxItem(PlaylistBox *listbox, const QString &text, Playlist *l = 0); PlaylistBoxItem(PlaylistBox *listbox, const QString &text, Playlist *l = 0);
virtual ~PlaylistBoxItem(); virtual ~PlaylistBoxItem();
Playlist *playlist() const; Playlist *playlist() const;
public slots:
void changeFile(const QString &file);
private: private:
Playlist *list; Playlist *list;
......
...@@ -81,7 +81,7 @@ PlaylistItem::PlaylistItem(CollectionListItem *item, Playlist *parent) : QObject ...@@ -81,7 +81,7 @@ PlaylistItem::PlaylistItem(CollectionListItem *item, Playlist *parent) : QObject
setup(item, parent); setup(item, parent);
} }
PlaylistItem::PlaylistItem(CollectionListItem *item, Playlist *parent, PlaylistItem *after) : QObject(parent), KListViewItem(parent, after) PlaylistItem::PlaylistItem(CollectionListItem *item, Playlist *parent, QListViewItem *after) : QObject(parent), KListViewItem(parent, after)
{ {
setup(item, parent); setup(item, parent);
} }
......
...@@ -69,7 +69,7 @@ protected: ...@@ -69,7 +69,7 @@ protected:
/** Items should always be created using Playlist::createItem() or through a /** Items should always be created using Playlist::createItem() or through a
subclss or friend class. */ subclss or friend class. */
PlaylistItem(CollectionListItem *item, Playlist *parent); PlaylistItem(CollectionListItem *item, Playlist *parent);
PlaylistItem(CollectionListItem *item, Playlist *parent, PlaylistItem *after); PlaylistItem(CollectionListItem *item, Playlist *parent, QListViewItem *after);
PlaylistItem(Playlist *parent); PlaylistItem(Playlist *parent);
class Data; class Data;
......
...@@ -36,7 +36,7 @@ void processEvents() ...@@ -36,7 +36,7 @@ void processEvents()
static int processed = 0; static int processed = 0;
if(processed == 0) if(processed == 0)
kapp->processEvents(); kapp->processEvents();
processed = (processed + 1) % 10; processed = (processed + 1) % 5;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
...@@ -104,13 +104,39 @@ PlaylistItem *PlaylistSplitter::playlistFirstItem() const ...@@ -104,13 +104,39 @@ PlaylistItem *PlaylistSplitter::playlistFirstItem() const
return(i); return(i);
} }
QString PlaylistSplitter::extensionsString(const QStringList &extensions, const QString &type)
{
QStringList l;
for(QStringList::ConstIterator it = extensions.begin(); it != extensions.end(); ++it)
l.append(QString("*." + (*it)));
// i.e. "*.m3u, *.mp3|Media Files"
QString s = l.join(" ");
if(type != QString::null)
s = + "|" + type;
return(s);
}
QStringList PlaylistSplitter::playlistExtensions()
{
if(splitter)
return(splitter->listExtensions);
else
return(QString::null);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// public slots // public slots
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void PlaylistSplitter::open() void PlaylistSplitter::open()
{ {
QStringList files = KFileDialog::getOpenFileNames(QString::null, "*.mp3 *.m3u|Media Files"); QStringList files = KFileDialog::getOpenFileNames(QString::null,
extensionsString((mediaExtensions + listExtensions), i18n("Media Files")));
open(files); open(files);
} }
...@@ -193,6 +219,7 @@ Playlist *PlaylistSplitter::createPlaylist(const QString &name) ...@@ -193,6 +219,7 @@ Playlist *PlaylistSplitter::createPlaylist(const QString &name)
{ {
Playlist *p = new Playlist(playlistStack, name.latin1()); Playlist *p = new Playlist(playlistStack, name.latin1());