Commit c67272ad authored by Scott Wheeler's avatar Scott Wheeler

Added a simple splash screen that shows things as items are loaded.

Started work on the "Genre List Editor", but that doesn't work yet.

Hmm, fixed some other stuff that I'm too tired to remember.

svn path=/trunk/kdemultimedia/juk/; revision=193005
parent b45646b5
......@@ -3,12 +3,12 @@ bin_PROGRAMS = juk
## INCLUDES were found outside kdevelop specific part
juk_SOURCES = statuslabel.cpp cachedtag.cpp oggtag.cpp id3tag.cpp collectionlist.cpp playlistitem.cpp playlist.cpp playlistsplitter.cpp listboxpixmap.cpp playlistbox.cpp tageditor.cpp cache.cpp audiodata.cpp genrelistreader.cpp genrelistlist.cpp genrelist.cpp genre.cpp player.cpp tag.cpp customaction.cpp slideraction.cpp juk.cpp main.cpp
juk_SOURCES = genrelisteditor.cpp genrelisteditorbase.ui splashscreen.cpp statuslabel.cpp cachedtag.cpp oggtag.cpp id3tag.cpp collectionlist.cpp playlistitem.cpp playlist.cpp playlistsplitter.cpp listboxpixmap.cpp playlistbox.cpp tageditor.cpp cache.cpp audiodata.cpp genrelistreader.cpp genrelistlist.cpp genrelist.cpp genre.cpp player.cpp tag.cpp customaction.cpp slideraction.cpp juk.cpp main.cpp
juk_LDADD = -lid3 -lsoundserver_idl $(LIB_KFILE) $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) $(LIBSOCKET)
SUBDIRS = pics data
EXTRA_DIST = main.cpp juk.cpp juk.h juk.desktop jukui.rc slideraction.cpp slideraction.h customaction.h customaction.cpp tag.cpp tag.h player.cpp player.h genre.h genre.cpp hi16-app-juk.png hi32-app-juk.png hi48-app-juk.png genrelist.cpp genrelist.h genrelistlist.cpp genrelistlist.h genrelistreader.cpp genrelistreader.h audiodata.cpp audiodata.h cache.cpp cache.h tageditor.cpp tageditor.h playlistbox.cpp playlistbox.h listboxpixmap.cpp listboxpixmap.h playlistsplitter.cpp playlistsplitter.h playlist.cpp playlist.h playlistitem.cpp playlistitem.h collectionlist.cpp collectionlist.h id3tag.cpp id3tag.h oggtag.cpp oggtag.h cachedtag.cpp cachedtag.h statuslabel.cpp statuslabel.h
EXTRA_DIST = main.cpp juk.cpp juk.h juk.desktop jukui.rc slideraction.cpp slideraction.h customaction.h customaction.cpp tag.cpp tag.h player.cpp player.h genre.h genre.cpp hi16-app-juk.png hi32-app-juk.png hi48-app-juk.png genrelist.cpp genrelist.h genrelistlist.cpp genrelistlist.h genrelistreader.cpp genrelistreader.h audiodata.cpp audiodata.h cache.cpp cache.h tageditor.cpp tageditor.h playlistbox.cpp playlistbox.h listboxpixmap.cpp listboxpixmap.h playlistsplitter.cpp playlistsplitter.h playlist.cpp playlist.h playlistitem.cpp playlistitem.h collectionlist.cpp collectionlist.h id3tag.cpp id3tag.h oggtag.cpp oggtag.h cachedtag.cpp cachedtag.h statuslabel.cpp statuslabel.h splashscreen.cpp splashscreen.h genrelisteditorbase.ui genrelisteditor.cpp genrelisteditor.h
install-data-local:
$(mkinstalldirs) $(kde_appsdir)/Multimedia/
......
......@@ -22,6 +22,7 @@
#include "collectionlist.h"
#include "playlistsplitter.h"
#include "cache.h"
#include "splashscreen.h"
////////////////////////////////////////////////////////////////////////////////
// static methods
......@@ -148,6 +149,8 @@ CollectionListItem::CollectionListItem(const QFileInfo &file) : PlaylistItem(Col
else
kdError() << "CollectionListItems should not be created before"
<< "CollectionList::initialize() has been called." << endl;
SplashScreen::increment();
}
CollectionListItem::~CollectionListItem()
......
......@@ -62,11 +62,17 @@ protected:
// These methods are used by CollectionListItem, which is a friend class.
void addToDict(const QString &file, CollectionListItem *item);
void removeFromDict(const QString &file);
/** This checks to see if the artist given is in the artist list maintained
by the collection list (for use in autocompletion and the TagEditor
combo boxes), and if it is not, it adds it to the list. */
/**
* This checks to see if the artist given is in the artist list maintained
* by the collection list (for use in autocompletion and the TagEditor
* combo boxes), and if it is not, it adds it to the list.
*/
void addArtist(const QString &artist);
/** This is similar to addArtist(), but is for album names. */
/**
* This is similar to addArtist(), but is for album names.
*/
void addAlbum(const QString &album);
private:
......
......@@ -21,10 +21,9 @@
// public members
////////////////////////////////////////////////////////////////////////////////
Genre::Genre() : QString()
Genre::Genre() : QString(), ID3v1(255)
{
name = QString::null;
ID3v1 = 255;
}
Genre::Genre(const QString &genreName, int ID3v1Number) : QString(genreName)
......
......@@ -32,7 +32,6 @@ public:
void setID3v1(int number);
private:
QString name;
int ID3v1;
};
......
......@@ -24,14 +24,13 @@
// public members
////////////////////////////////////////////////////////////////////////////////
GenreList::GenreList(bool createIndex) : QValueList<Genre>()
GenreList::GenreList(bool createIndex) : QValueList<Genre>(), hasIndex(createIndex)
{
hasIndex = createIndex;
}
GenreList::GenreList(const QString &file, bool createIndex) : QValueList<Genre>()
GenreList::GenreList(const QString &file, bool createIndex) : QValueList<Genre>(), hasIndex(createIndex)
{
hasIndex = createIndex;
load(file);
}
......@@ -53,7 +52,7 @@ void GenreList::load(const QString &file)
initializeIndex();
}
QString GenreList::name(int ID3v1)
QString GenreList::ID3v1Name(int ID3v1)
{
if(hasIndex && ID3v1 >= 0 && ID3v1 < int(index.size()))
return(index[ID3v1]);
......@@ -87,6 +86,16 @@ int GenreList::findIndex(const QString &item)
return(-1);
}
QString GenreList::name() const
{
return(listName);
}
void GenreList::setName(const QString &n)
{
listName = n;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
......
......@@ -32,21 +32,38 @@ public:
virtual ~GenreList();
void load(const QString &file);
QString name(int ID3v1);
/**
* Do a "reverse" lookup. Given an ID3v1 genre name, find the index.
* Given an ID3v1 "number", look up the name.
*/
QString ID3v1Name(int ID3v1);
/**
* Do a "reverse" lookup. Given an ID3v1 genre name, find the index. Though
* I didn't realize it at the time that I wrote it, this is a
* reimplimentation from QValueList; ours however caches the last search so
* it should speed things up a bit for "two in a row" searches that are
* common.
*/
int findIndex(const QString &item);
QString name() const;
void setName(const QString &n);
bool readOnly() const { return readOnlyList; }
void setReadOnly(bool ro) { readOnlyList = ro; }
private:
QValueVector<QString> index;
bool hasIndex;
/**
* This is used for creating a mapping between ID3v1 genre numbers and the
* name that is associated with those genres. There is no reason that this
* should be called for GenreLists other than the ID3v1 GenreList.
*/
void initializeIndex();
QValueVector<QString> index;
bool hasIndex;
QString listName;
bool readOnlyList;
};
#endif
/***************************************************************************
genrelisteditor.cpp - description
-------------------
begin : Sun Dec 8 2002
copyright : (C) 2002 by Scott Wheeler
email : wheeler@kde.org
***************************************************************************/
/***************************************************************************
* *
* 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 <kcombobox.h>
#include <klistview.h>
#include <klineedit.h>
#include <kdebug.h>
#include "genrelisteditor.h"
#include "genrelistlist.h"
////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////
GenreListEditor::GenreListEditor(QWidget *parent, const char *name ) : GenreListEditorBase(parent, name, true)
{
loadID3v1Genres();
loadLists();
}
GenreListEditor::~GenreListEditor()
{
}
////////////////////////////////////////////////////////////////////////////////
// private methods
////////////////////////////////////////////////////////////////////////////////
void GenreListEditor::loadID3v1Genres()
{
GenreList ID3v1List = GenreListList::ID3v1List();
for(GenreList::Iterator it = ID3v1List.begin(); it != ID3v1List.end(); it++) {
ID3v1Box->insertItem(*it);
}
}
void GenreListEditor::loadLists()
{
GenreListList lists = GenreListList::lists();
for(GenreListList::Iterator it = lists.begin(); it != lists.end(); it++) {
listDict.insert((*it).name(), &(*it));
selectListBox->insertItem((*it).name());
}
updateGenreList();
}
void GenreListEditor::updateGenreList()
{
GenreList *currentList = listDict[selectListBox->currentText()];
if(currentList) {
genreList->clear();
for(GenreList::Iterator it = currentList->begin(); it != currentList->end(); it++)
new KListViewItem(genreList, *it, currentList->ID3v1Name((*it).getID3v1()));
}
}
////////////////////////////////////////////////////////////////////////////////
// private slots
////////////////////////////////////////////////////////////////////////////////
void GenreListEditor::updateGenreBoxes(QListViewItem *item)
{
if(item) {
genreNameBox->setText(item->text(0));
ID3v1Box->setCurrentItem(GenreListList::ID3v1List().findIndex(item->text(1)));
}
}
void GenreListEditor::updateGenreName(const QString &name)
{
QListViewItem *current = genreList->currentItem();
if(!name.isEmpty() && current)
current->setText(0, name);
}
#include "genrelisteditor.moc"
/***************************************************************************
genrelisteditor.h - description
-------------------
begin : Sun Dec 8 2002
copyright : (C) 2002 by Scott Wheeler
email : wheeler@kde.org
***************************************************************************/
/***************************************************************************
* *
* 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 GENRELISTEDITOR_H
#define GENRELISTEDITOR_H
#include <qdict.h>
#include "genrelisteditorbase.h"
class GenreList;
class GenreListEditor : public GenreListEditorBase
{
Q_OBJECT
public:
GenreListEditor(QWidget *parent = 0, const char *name = 0);
~GenreListEditor();
private:
void loadID3v1Genres();
void loadLists();
void updateGenreList();
QDict<GenreList> listDict;
private slots:
virtual void updateGenreBoxes(QListViewItem *item);
virtual void updateGenreName(const QString &name);
};
#endif
This diff is collapsed.
......@@ -16,6 +16,9 @@
***************************************************************************/
#include <kstandarddirs.h>
#include <kdebug.h>
#include <qdir.h>
#include "genrelistlist.h"
......@@ -30,19 +33,38 @@
// public
GenreList *GenreListList::ID3v1List()
GenreList GenreListList::ID3v1List()
{
if(!ID3v1Loaded) {
if(!ID3v1) {
ID3v1 = new GenreList(true);
ID3v1->load(locate("data", "juk/id3v1.genreml"));
ID3v1Loaded = true;
ID3v1->setReadOnly(true);
}
return(*ID3v1);
}
GenreListList GenreListList::lists()
{
GenreListList l;
if(ID3v1)
l.append(*ID3v1);
QDir dir(KGlobal::dirs()->saveLocation("appdata"));
QStringList files = dir.entryList("*.genreml");
for(QStringList::Iterator it = files.begin(); it != files.end(); it++) {
GenreList genreList(*it);
if(genreList.count() > 0)
l.append(genreList);
}
return(ID3v1);
return(l);
}
// private
GenreList *GenreListList::ID3v1 = new GenreList(true);
bool GenreListList::ID3v1Loaded = false;
GenreList *GenreListList::ID3v1 = 0;
////////////////////////////////////////////////////////////////////////////////
// public members
......@@ -50,7 +72,7 @@ bool GenreListList::ID3v1Loaded = false;
GenreListList::GenreListList()
{
}
GenreListList::~GenreListList()
......
......@@ -28,11 +28,11 @@ public:
GenreListList();
virtual ~GenreListList();
static GenreList *ID3v1List();
static GenreList ID3v1List();
static GenreListList lists();
private:
static GenreList *ID3v1;
static bool ID3v1Loaded;
};
#endif
......@@ -23,10 +23,9 @@
// public members
////////////////////////////////////////////////////////////////////////////////
GenreListReader::GenreListReader(GenreList *genreList)
GenreListReader::GenreListReader(GenreList *genreList) : QXmlDefaultHandler(), list(genreList), inGenreTag(false)
{
list = genreList;
inGenreTag = false;
}
GenreListReader::~GenreListReader()
......@@ -43,9 +42,14 @@ bool GenreListReader::startElement(const QString &, const QString &, const QStri
else
ID3v1 = 255;
}
else {
ID3v1 = 255;
else if(element.lower() == "genrelist") {
if(attributes.index("name") != -1) {
list->setName(attributes.value("name"));
}
}
else
ID3v1 = 255;
return(true);
};
......@@ -53,10 +57,11 @@ bool GenreListReader::endElement(const QString &, const QString &, const QString
{
if(element.lower() == "genre")
inGenreTag = false;
return(true);
};
bool GenreListReader::characters(const QString& content)
bool GenreListReader::characters(const QString &content)
{
if(inGenreTag)
list->append(Genre(content, ID3v1));
......
......@@ -22,6 +22,12 @@
#include "genrelist.h"
/**
* A SAX2 based XML reader to read GenreLists. Since there's little use to keep
* the document structure in memory, I've opted for SAX2 over QDom, since it's
* a good deal faster.
*/
class GenreListReader : public QXmlDefaultHandler
{
public:
......
......@@ -100,7 +100,7 @@ ID3Tag::ID3Tag(const QString &file) : Tag(file)
// parse the genre string for (<ID3v1 number>)
if(tagGenre == "(" + QString::number(tagGenre.getID3v1()) + ")" || tagGenre == QString::null)
tagGenre = GenreListList::ID3v1List()->name(tagGenre.getID3v1());
tagGenre = GenreListList::ID3v1List().ID3v1Name(tagGenre.getID3v1());
else if(tagGenre.find(QRegExp("\\([0-9]+\\)")) == 0)
tagGenre = tagGenre.mid(tagGenre.find(")") + 1);
......@@ -142,10 +142,10 @@ void ID3Tag::save()
else
ID3_RemoveTracks(&tag);
if(tagGenre.getID3v1() >= 0 && tagGenre.getID3v1() < int(GenreListList::ID3v1List()->count())) {
if(tagGenre.getID3v1() >= 0 && tagGenre.getID3v1() < int(GenreListList::ID3v1List().count())) {
QString genreString;
if(tagGenre != GenreListList::ID3v1List()->name(tagGenre.getID3v1()))
if(tagGenre != GenreListList::ID3v1List().ID3v1Name(tagGenre.getID3v1()))
genreString = "(" + QString::number(tagGenre.getID3v1()) + ")" + tagGenre;
else
genreString = "(" + QString::number(tagGenre.getID3v1()) + ")";
......
......@@ -15,6 +15,7 @@
* *
***************************************************************************/
#include <kapplication.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kcmdlineargs.h>
......@@ -30,6 +31,8 @@
#include "slideraction.h"
#include "cache.h"
#include "statuslabel.h"
#include "splashscreen.h"
#include "genrelisteditor.h"
////////////////////////////////////////////////////////////////////////////////
// public members
......@@ -37,6 +40,9 @@
JuK::JuK(QWidget *parent, const char *name) : KMainWindow(parent, name, WDestructiveClose)
{
SplashScreen::instance()->show();
kapp->processEvents();
// Expect segfaults if you change this order.
readSettings();
......@@ -45,6 +51,8 @@ JuK::JuK(QWidget *parent, const char *name) : KMainWindow(parent, name, WDestruc
setupPlayer();
readConfig();
processArgs();
SplashScreen::finishedLoading();
}
JuK::~JuK()
......@@ -114,6 +122,7 @@ void JuK::setupActions()
// settings menu
restoreOnLoadAction = new KToggleAction(i18n("Restored Playlists on Load"), 0, actionCollection(), "restoreOnLoad");
new KAction(i18n("Genre List Editor"), 0, this, SLOT(showGenreListEditor()), actionCollection(), "showGenreListEditor");
playlistChanged(0);
connect(splitter, SIGNAL(playlistChanged(Playlist *)), this, SLOT(playlistChanged(Playlist *)));
......@@ -359,6 +368,15 @@ void JuK::forwardFile()
playItem(i);
}
////////////////////////////////////////////////////////////////////////////////
// settings menu
////////////////////////////////////////////////////////////////////////////////
void JuK::showGenreListEditor()
{
GenreListEditor * editor = new GenreListEditor();
editor->exec();
}
////////////////////////////////////////////////////////////////////////////////
// additional player slots
......
......@@ -113,6 +113,9 @@ private slots:
void backFile();
void forwardFile();
// settings menu
void showGenreListEditor();
// additional player slots
void trackPositionSliderClick();
void trackPositionSliderRelease();
......
......@@ -35,6 +35,7 @@
<Action name="deleteItemPlaylist"/>
</Menu>
<Menu name="settings" noMerge="1"><text>&amp;Settings</text>
<Action name="showGenreListEditor"/>
<Action name="restoreOnLoad"/>
</Menu>
</MenuBar>
......
......@@ -75,7 +75,7 @@ QString OggTag::album() const
Genre OggTag::genre() const
{
QString genreName = readCommentString("Genre");
int index = GenreListList::ID3v1List()->findIndex(genreName);
int index = GenreListList::ID3v1List().findIndex(genreName);
return Genre(genreName, index);
}
......
......@@ -15,6 +15,7 @@
* *
***************************************************************************/
#include <kapplication.h>
#include <kmessagebox.h>
#include <kurl.h>
#include <kurldrag.h>
......@@ -165,8 +166,16 @@ void Playlist::saveAs()
void Playlist::refresh()
{
PlaylistItemList list;
for(PlaylistItem *i = static_cast<PlaylistItem *>(firstChild()); i; i = static_cast<PlaylistItem *>(i->itemBelow()))
KApplication::setOverrideCursor(Qt::waitCursor);
int j = 0;
for(PlaylistItem *i = static_cast<PlaylistItem *>(firstChild()); i; i = static_cast<PlaylistItem *>(i->itemBelow())) {
i->refreshFromDisk();
if(j % 5 == 0)
kapp->processEvents();
j = j % 5 + 1;
}
KApplication::restoreOverrideCursor();
}
void Playlist::clearItems(const PlaylistItemList &items)
......
......@@ -61,12 +61,24 @@ public:
*/
QStringList files() const;
/**
* All of the items in the list.
* Returns a list of all of the items in the playlist.
*/
PlaylistItemList items() const;
/**
* Returns a list of the currently selected items.
*/
PlaylistItemList selectedItems() const;
/**
* Remove the currently selected items from the playlist.
*/
void remove();
/**
* Remove \a items from the playlist. This will ignore items that are not
* actually in the list.
*/
void remove(const PlaylistItemList &items);
/**
......
......@@ -86,15 +86,42 @@ public:
static void setSelected(PlaylistItem *i);
public slots:
/**
* Open files or playlists.
*/
void open();
/**
* Open a directory recursively, grabbing all of the music and playlist files
* in it's heirarchy.
*/
void openDirectory();
/**
* Open each of \a files, where \a files is a list of playlists and music
* files.
*/
void open(const QStringList &files);
/**
* Open \a file where \a is a playlist or music file.
*/
void open(const QString &file);
/**
* Save.
*/
void save();
/**
* Deletes the selected items from the hard disk.
*/
void remove();
/**
* Refresh the contents of the currently visible playlist. This will cause
* all of the audio meta data to be reread from disk.
*/
void refresh();
/**
* Removes the selected items from the playlist.
......@@ -104,9 +131,21 @@ public slots:
void setEditorVisible(bool visible);
/**
* Create a playlist and prompt the user for a name.
*/
Playlist *createPlaylist();
/**
* Create a playlist with the named \a name.
*/
Playlist *createPlaylist(const QString &name);
/**
* Prompt the user for a playlist to open.
*/
void openPlaylist();
/**
* Open the playlist (m3u file or simiar) at \a playlistFile.
*/
Playlist *openPlaylist(const QString &playlistFile);
void add(const QString &file, Playlist *list);
......
/***************************************************************************
splashscreen.cpp - description
-------------------
begin : Sun Dec 8 2002
copyright : (C) 2002 by Scott Wheeler
email : wheeler@kde.org
***************************************************************************/
/***************************************************************************
* *
* 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 <kapplication.h>
#include <kiconloader.h>
#include <klocale.h>
#include <qlabel.h>
#include <qfont.h>
#include "splashscreen.h"
SplashScreen *SplashScreen::splash = 0;
bool SplashScreen::done = false;
int SplashScreen::count = 0;
////////////////////////////////////////////////////////////////////////////////
// pubic members
////////////////////////////////////////////////////////////////////////////////