Commit bd3330cf authored by Scott Wheeler's avatar Scott Wheeler

More of the architecture cleanups -- added files.

svn path=/trunk/kdemultimedia/juk/; revision=177613
parent c4aa5cd1
/***************************************************************************
playlist.cpp - description
-------------------
begin : Sat Feb 16 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 <kmessagebox.h>
#include <klocale.h>
#include <kdebug.h>
#include <qfileinfo.h>
#include <qdir.h>
#include <qtimer.h>
#include <qapplication.h>
#include <qptrlist.h>
#include "playlist.h"
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
Playlist::Playlist(QWidget *parent, const char *name) : KListView(parent, name)
{
setup();
}
Playlist::~Playlist()
{
}
void Playlist::append(const QString &item)
{
QApplication::setOverrideCursor(Qt::waitCursor);
appendImpl(item);
QApplication::restoreOverrideCursor();
emit(collectionChanged(this));
}
void Playlist::append(const QStringList &items)
{
QApplication::setOverrideCursor(Qt::waitCursor);
for(QStringList::ConstIterator it = items.begin(); it != items.end(); ++it)
appendImpl(*it);
QApplication::restoreOverrideCursor();
emit(collectionChanged(this));
}
void Playlist::append(PlaylistItem *item)
{
if(item && members.contains(item->absFilePath()) == 0) {
members.append(item->absFilePath());
(void) new PlaylistItem(*item, this);
}
emit(collectionChanged(this));
}
void Playlist::append(QPtrList<PlaylistItem> &items)
{
QPtrListIterator<PlaylistItem> it(items);
while(it.current()) {
append(it.current());
++it;
}
// the emit(collectionChanged()) is handled in the above function
}
void Playlist::clearItems(const QPtrList<PlaylistItem> &items)
{
QPtrListIterator<PlaylistItem> it(items);
while(it.current()) {
members.remove(it.current()->absFilePath());
delete(it.current());
++it;
}
}
QPtrList<PlaylistItem> Playlist::selectedItems() const
{
QPtrList<PlaylistItem> list;
for(PlaylistItem *i = static_cast<PlaylistItem *>(firstChild()); i != 0; i = static_cast<PlaylistItem *>(i->itemBelow())) {
if(i->isSelected())
list.append(i);
}
return(list);
}
void Playlist::remove()
{
remove(selectedItems());
}
void Playlist::remove(const QPtrList<PlaylistItem> &items)
{
if(isVisible() && !items.isEmpty()) {
QString message = i18n("Are you sure that you want to delete:\n");
for(QPtrListIterator<PlaylistItem> it(items); it.current() != 0; ++it)
message.append(it.current()->fileName() + "\n");
if(KMessageBox::warningYesNo(this, message, i18n("Delete Files")) == KMessageBox::Yes) {
for(QPtrListIterator<PlaylistItem> it(items); it.current() != 0; ++it) {
if(QFile::remove(it.current()->filePath()))
delete(it.current());
else
KMessageBox::sorry(this, i18n("Could not save delete ") + it.current()->fileName() + ".");
}
}
}
}
QStringList &Playlist::getArtistList()
{
return(artistList);
}
QStringList &Playlist::getAlbumList()
{
return(albumList);
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void Playlist::setup()
{
processed = 0;
extensions.append("mp3");
addColumn(i18n("Track Name"));
addColumn(i18n("Artist"));
addColumn(i18n("Album"));
addColumn(i18n("Track"));
addColumn(i18n("Genre"));
addColumn(i18n("Year"));
addColumn(i18n("Length"));
addColumn(i18n("File Name"));
setAllColumnsShowFocus(true);
setSelectionMode(QListView::Extended);
setShowSortIndicator(true);
setItemMargin(3);
setSorting(1);
connect(this, SIGNAL(selectionChanged()), this, SLOT(emitSelected()));
}
void Playlist::appendImpl(const QString &item)
{
processEvents();
QFileInfo file(QDir::cleanDirPath(item));
if(file.exists()) {
if(file.isDir()) {
QDir dir(file.filePath());
QStringList dirContents=dir.entryList();
for(QStringList::Iterator it = dirContents.begin(); it != dirContents.end(); ++it) {
if(*it != "." && *it != "..") {
appendImpl(file.filePath() + QDir::separator() + *it);
}
}
}
else {
QString extension = file.extension(false);
if(extensions.contains(extension) > 0 && members.contains(file.absFilePath()) == 0) {
members.append(file.absFilePath());
(void) new PlaylistItem(file, this);
}
}
}
}
void Playlist::processEvents()
{
if(processed == 0)
qApp->processEvents();
processed = ( processed + 1 ) % 10;
}
////////////////////////////////////////////////////////////////////////////////
// private slots
////////////////////////////////////////////////////////////////////////////////
void Playlist::emitSelected()
{
emit(selectionChanged(selectedItems()));
}
#include "playlist.moc"
/***************************************************************************
playlist.h - description
-------------------
begin : Sat Feb 16 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. *
* *
***************************************************************************/
#ifndef PLAYLIST_H
#define PLAYLIST_H
#include <klistview.h>
#include <qstringlist.h>
#include "playlistitem.h"
class Playlist : public KListView
{
Q_OBJECT
public:
Playlist(QWidget *parent = 0, const char *name = 0);
virtual ~Playlist();
virtual void append(const QString &item);
virtual void append(const QStringList &items);
virtual void append(PlaylistItem *item);
virtual void append(QPtrList<PlaylistItem> &items);
virtual void clearItems(const QPtrList<PlaylistItem> &items);
QPtrList<PlaylistItem> selectedItems() const;
void remove();
void remove(const QPtrList<PlaylistItem> &items);
// These are used in a hard-core, encapsulation breaking way and should be
// replaced soon (see PlaylistItem). Unfortunately they're more efficient
// than elegant solutions. These also should be removed by doing the
// checking that is currently done in PlaylistItem in the CollectionList
// subclass of Playlist.
QStringList &getArtistList();
QStringList &getAlbumList();
private:
void setup();
void appendImpl(const QString &item);
QStringList extensions;
QStringList members;
QStringList artistList;
QStringList albumList;
void processEvents();
int processed;
private slots:
void emitSelected();
signals:
void dataChanged();
// This signal should later be moved to the "CollectionList" subclass of
// Playlist.
void collectionChanged(Playlist *list);
void selectionChanged(const QPtrList<PlaylistItem> &selection);
};
#endif
/***************************************************************************
playlistbox.cpp - description
-------------------
begin : Thu Sep 12 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 <kiconloader.h>
#include <qdrawutil.h>
#include "playlistbox.h"
////////////////////////////////////////////////////////////////////////////////
// PlaylistBox public methods
////////////////////////////////////////////////////////////////////////////////
PlaylistBox::PlaylistBox(QWidget *parent, const char *name) : KListBox(parent, name)
{
connect(this, SIGNAL(currentChanged(QListBoxItem *)), this, SLOT(currentItemChanged(QListBoxItem *)));
}
PlaylistBox::~PlaylistBox()
{
}
void PlaylistBox::resizeEvent(QResizeEvent *e)
{
// hack-ish, but functional
for(int i = 0; i <= count(); i++)
updateItem(i);
KListBox::resizeEvent(e);
}
////////////////////////////////////////////////////////////////////////////////
// PlaylistBox private slots
////////////////////////////////////////////////////////////////////////////////
void PlaylistBox::currentItemChanged(QListBoxItem *item)
{
PlaylistBoxItem *i = dynamic_cast<PlaylistBoxItem *>(item);
if(i)
emit(currentChanged(i));
}
////////////////////////////////////////////////////////////////////////////////
// PlaylistBoxItem public methods
////////////////////////////////////////////////////////////////////////////////
PlaylistBoxItem::PlaylistBoxItem(QListBox *listbox, const QPixmap &pix, const QString &text, Playlist *l) : ListBoxPixmap(listbox, pix, text)
{
list = l;
setOrientation(Qt::Vertical);
}
PlaylistBoxItem::PlaylistBoxItem(QListBox *listbox, const QString &text, Playlist *l) : ListBoxPixmap(listbox, SmallIcon("midi", 32), text)
{
list = l;
setOrientation(Qt::Vertical);
}
PlaylistBoxItem::~PlaylistBoxItem()
{
}
Playlist *PlaylistBoxItem::playlist() const
{
return(list);
}
#include "playlistbox.moc"
/***************************************************************************
playlistbox.h - description
-------------------
begin : Thu Sep 12 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. *
* *
***************************************************************************/
#ifndef PLAYLISTBOX_H
#define PLAYLISTBOX_H
#include <klistbox.h>
#include <qwidgetstack.h>
#include "listboxpixmap.h"
#include "playlist.h"
class PlaylistBoxItem;
/** This is the play list selection box that is by default on the right side of
JuK's main widget (PlaylistSplitter). */
class PlaylistBox : public KListBox
{
Q_OBJECT
public:
PlaylistBox(QWidget *parent = 0, const char *name = 0);
virtual ~PlaylistBox();
protected:
virtual void resizeEvent(QResizeEvent *e);
private:
QWidgetStack *stack;
private slots:
/** Catches QListBox::clicked(QListBoxItem *), does a cast and then re-emits
the signal as clicked(PlaylistBoxItem *). */
void currentItemChanged(QListBoxItem *item);
signals:
void currentChanged(PlaylistBoxItem *);
};
class PlaylistBoxItem : public ListBoxPixmap
{
public:
PlaylistBoxItem(QListBox *listbox, const QPixmap &pix, const QString &text, Playlist *l = 0);
PlaylistBoxItem(QListBox *listbox, const QString &text, Playlist *l = 0);
virtual ~PlaylistBoxItem();
// This (and the playlist member variable) should be switched to the Playlist class once
// the design is ready for that.
Playlist *playlist() const;
private:
Playlist *list;
};
#endif
This diff is collapsed.
/***************************************************************************
playlistitem.h - description
-------------------
begin : Sun Feb 17 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. *
* *
***************************************************************************/
#ifndef PLAYLISTITEM_H
#define PLAYLISTITEM_H
#include <klistview.h>
#include <qfileinfo.h>
#include <qobject.h>
#include "tag.h"
#include "audiodata.h"
class Playlist;
class PlaylistItem : public QObject, public KListViewItem
{
Q_OBJECT
public:
enum ColumnType { TrackColumn = 0, ArtistColumn = 1, AlbumColumn = 2, TrackNumberColumn = 3,
GenreColumn = 4, YearColumn = 5, LengthColumn = 6, FileNameColumn = 7 };
PlaylistItem(const QFileInfo &file, Playlist *parent);
PlaylistItem(PlaylistItem &item, Playlist *parent);
virtual ~PlaylistItem();
// these can't be const members because they fetch the data "on demand"
Tag *getTag();
AudioData *getAudioData();
void setFile(const QString &file);
// QFileInfo-ish methods
QString fileName() const;
QString filePath() const;
QString absFilePath() const;
QString dirPath(bool absPath = false) const;
bool isWritable() const;
public slots:
void refresh();
protected slots:
void addSibling(const PlaylistItem *sibling);
void removeSibling(const PlaylistItem *sibling);
signals:
void refreshed();
private:
class Data;
Data *getData();
int compare(QListViewItem *item, int column, bool ascending) const;
int compare(PlaylistItem *firstItem, PlaylistItem *secondItem, int column, bool ascending) const;
Data *data;
};
#endif
/***************************************************************************
playlistsplitter.cpp - description
-------------------
begin : Fri Sep 13 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 <kiconloader.h>
#include <kdebug.h>
#include "playlistsplitter.h"
////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////
PlaylistSplitter::PlaylistSplitter(QWidget *parent, const char *name) : QSplitter(Qt::Horizontal, parent, name)
{
setupLayout();
readConfig();
}
PlaylistSplitter::~PlaylistSplitter()
{
}
void PlaylistSplitter::createPlaylist(const QString &name)
{
Playlist *p = new Playlist(playlistStack, name.latin1());
(void) new PlaylistBoxItem(playlistBox, SmallIcon("midi", 32), name, p);
connect(p, SIGNAL(selectionChanged(const QPtrList<PlaylistItem> &)), editor, SLOT(setItems(const QPtrList<PlaylistItem> &)));
connect(p, SIGNAL(doubleClicked(QListViewItem *)), this, SIGNAL(playlistDoubleClicked(QListViewItem *)));
}
QPtrList<PlaylistItem> PlaylistSplitter::playlistSelection() const
{
Playlist *p = static_cast<Playlist *>(playlistStack->visibleWidget());
return(p->selectedItems());
}
PlaylistItem *PlaylistSplitter::playlistFirstItem() const
{
Playlist *p = static_cast<Playlist *>(playlistStack->visibleWidget());
PlaylistItem *i = static_cast<PlaylistItem *>(p->firstChild());
return(i);
}
////////////////////////////////////////////////////////////////////////////////
// public slots
////////////////////////////////////////////////////////////////////////////////
void PlaylistSplitter::open(const QStringList &files)
{
collection->append(files);
// If the collection is not the top widget in the widget stack, assume that
// the open was intended to go to the top widget and open the files there
// too.
// The open methods are currently causing segfaults. I haven't tried to debug
// them yet.
if(playlistStack->visibleWidget() != collection) {
Playlist *p = static_cast<Playlist *>(playlistStack->visibleWidget());
p->append(files);
}
}
void PlaylistSplitter::open(const QString &file)
{
collection->append(file);
// If the collection is not the top widget in the widget stack, assume that
// the open was intended to go to the top widget and open the files there
// too.
if(playlistStack->visibleWidget() != collection) {
Playlist *p = static_cast<Playlist *>(playlistStack->visibleWidget());
p->append(file);
}
}
void PlaylistSplitter::remove()
{
Playlist *p = static_cast<Playlist *>(playlistStack->visibleWidget());
p->remove();
}
void PlaylistSplitter::setEditorVisible(bool visible)
{
if(visible)
editor->show();
else
editor->hide();
}
void PlaylistSplitter::clearSelectedItems()
{
Playlist *p = static_cast<Playlist *>(playlistStack->visibleWidget());
p->clearItems(p->selectedItems());
}
void PlaylistSplitter::selectAll(bool select)
{
Playlist *p = static_cast<Playlist *>(playlistStack->visibleWidget());
p->selectAll(select);
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void PlaylistSplitter::setupLayout()
{
setOpaqueResize();
playlistBox = new PlaylistBox(this, "playlistBox");
// Create a splitter to go between the playlists and the editor.
QSplitter *editorSplitter = new QSplitter(Qt::Vertical, this, "editorSplitter");
// Create the playlist and the editor.
playlistStack = new QWidgetStack(editorSplitter, "playlistStack");
editor = new TagEditor(editorSplitter, "tagEditor");
// Make the editor as small as possible (or at least as small as recommended)
editorSplitter->setResizeMode(editor, QSplitter::FollowSizeHint);
// Make the connection that will update the selected playlist when a
// selection is made in the playlist box.
connect(playlistBox, SIGNAL(currentChanged(PlaylistBoxItem *)), this, SLOT(changePlaylist(PlaylistBoxItem *)));
// Create the collection list; this should always exist. This has a
// slightly different creation process than normal playlists (since it in
// fact is a subclass) so it is created here rather than by using
// createPlaylist().
collection = new CollectionList(playlistStack, "collectionList");
PlaylistBoxItem *collectionBoxItem = new PlaylistBoxItem(playlistBox, SmallIcon("folder_sound", 32), i18n("Music Collection"), collection);
connect(collection, SIGNAL(selectionChanged(const QPtrList<PlaylistItem> &)), editor, SLOT(setItems(const QPtrList<PlaylistItem> &)));
connect(collection, SIGNAL(doubleClicked(QListViewItem *)), this, SIGNAL(playlistDoubleClicked(QListViewItem *)));
// Show the collection on startup.
playlistBox->setSelected(collectionBoxItem, true);
// just for testing -- until I get the dialog/menu entry for adding playlists
createPlaylist(i18n("Playlist 1"));
}
void PlaylistSplitter::readConfig()
{
// This should eventually be replace by a KConfig entry.
showEditor = true;
setEditorVisible(showEditor);
}
////////////////////////////////////////////////////////////////////////////////
// private slots
////////////////////////////////////////////////////////////////////////////////
void PlaylistSplitter::changePlaylist(PlaylistBoxItem *item)