Commit 2c297413 authored by Michael Pyne's avatar Michael Pyne

Fairly large overhaul of the JuK codebase to beat out a lot of the Qt 3 stuff.

Still a lot of Qt 3 code to go but at this point Q3ValueList, Q3Vector, Q3PtrDict and
Q3Dict should all be gone.

In addition many loops have been foreach()'ed, which really does make it more readable.

There is a crash fix as well, now the polish() function in Playlist has been replaced
with an initialization slot which is singleShot'ed since the timing of the polish event
is apparently different than it was in Qt 3, which was making new Playlists crash when
they were first shown.

Also I went through almost every header and pared it down to the minimum reasonably
achievable, which required some additional headers in a few .cpp files but overall
compilation time should be down and you won't have to rebuild all of JuK just because
a header file got touched.

I haven't seen any regressions yet but then again I still can't play music either.

svn path=/trunk/KDE/kdemultimedia/juk/; revision=667815
parent ee136682
......@@ -16,9 +16,9 @@
#ifndef ACTIONCOLLECTION_H
#define ACTIONCOLLECTION_H
#include <ktoolbarpopupaction.h>
class KActionCollection;
class KAction;
class QAction;
class QString;
namespace ActionCollection
{
......
......@@ -18,12 +18,13 @@
#include <kdialog.h>
#include <QList>
#include "searchwidget.h"
#include "playlistsearch.h"
class KLineEdit;
class KPushButton;
class QRadioButton;
class SearchLine;
class AdvancedSearchDialog : public KDialog
{
......
......@@ -16,15 +16,17 @@
#ifndef CACHE_H
#define CACHE_H
#include <QDataStream>
#include "stringhash.h"
#include <QList>
class Tag;
class Playlist;
class PlaylistCollection;
template<class T>
class QList;
typedef QList<Playlist *> PlaylistList;
class Cache : public FileHandleHash
......
......@@ -18,8 +18,6 @@
#include "tagrenameroptions.h"
#include <QList>
enum TagType;
class QString;
......
......@@ -15,22 +15,21 @@
#include "collectionlist.h"
#include <k3urldrag.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kmenu.h>
#include <kiconloader.h>
#include <kconfig.h>
#include <kaction.h>
#include <kurl.h>
#include <kactioncollection.h>
#include <kconfiggroup.h>
#include <kactioncollection.h>
#include <ktoolbarpopupaction.h>
#include <kdirwatch.h>
#include <Q3ValueList>
#include <QList>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QApplication>
#include <QClipboard>
#include "playlistcollection.h"
#include "splashscreen.h"
......@@ -98,7 +97,7 @@ PlaylistItem *CollectionList::createItem(const FileHandle &file, Q3ListViewItem
// It's probably possible to optimize the line below away, but, well, right
// now it's more important to not load duplicate items.
if(m_itemsDict.find(file.absFilePath()))
if(m_itemsDict.contains(file.absFilePath()))
return 0;
PlaylistItem *item = new CollectionListItem(file);
......@@ -133,19 +132,13 @@ void CollectionList::setupTreeViewEntries(ViewMode *viewMode) const
return;
}
Q3ValueList<int> columnList;
QList<int> columnList;
columnList << PlaylistItem::ArtistColumn;
columnList << PlaylistItem::GenreColumn;
columnList << PlaylistItem::AlbumColumn;
QStringList items;
for(Q3ValueList<int>::Iterator colIt = columnList.begin(); colIt != columnList.end(); ++colIt) {
items.clear();
for(TagCountDictIterator it(*m_columnTags[*colIt]); it.current(); ++it)
items << it.currentKey();
treeViewMode->addItems(items, *colIt);
}
foreach(int column, columnList)
treeViewMode->addItems(m_columnTags[column]->keys(), column);
}
void CollectionList::slotNewItems(const KFileItemList &items)
......@@ -190,6 +183,11 @@ void CollectionList::slotDeleteItem(KFileItem *item)
// public slots
////////////////////////////////////////////////////////////////////////////////
void CollectionList::paste()
{
decode(QApplication::clipboard()->mimeData());
}
void CollectionList::clear()
{
int result = KMessageBox::warningContinueCancel(this,
......@@ -208,9 +206,9 @@ void CollectionList::slotCheckCache()
{
PlaylistItemList invalidItems;
for(Q3DictIterator<CollectionListItem>it(m_itemsDict); it.current(); ++it) {
if(!it.current()->checkCurrent())
invalidItems.append(*it);
foreach(CollectionListItem *item, m_itemsDict) {
if(!item->checkCurrent())
invalidItems.append(item);
processEvents();
}
......@@ -224,7 +222,8 @@ void CollectionList::slotRemoveItem(const QString &file)
void CollectionList::slotRefreshItem(const QString &file)
{
m_itemsDict[file]->refresh();
if(m_itemsDict[file])
m_itemsDict[file]->refresh();
}
////////////////////////////////////////////////////////////////////////////////
......@@ -233,7 +232,6 @@ void CollectionList::slotRefreshItem(const QString &file)
CollectionList::CollectionList(PlaylistCollection *collection) :
Playlist(collection, true),
m_itemsDict(5003),
m_columnTags(15, 0)
{
QAction *spaction = ActionCollection::actions()->addAction("showPlaying");
......@@ -242,22 +240,15 @@ CollectionList::CollectionList(PlaylistCollection *collection) :
connect(action<KToolBarPopupAction>("back")->menu(), SIGNAL(aboutToShow()),
this, SLOT(slotPopulateBackMenu()));
connect(action<KToolBarPopupAction>("back")->menu(), SIGNAL(activated(int)),
this, SLOT(slotPlayFromBackMenu(int)));
connect(action<KToolBarPopupAction>("back")->menu(), SIGNAL(activated(QAction *)),
this, SLOT(slotPlayFromBackMenu(QAction *)));
connect(action<KToolBarPopupAction>("back")->menu(), SIGNAL(triggered(QAction *)),
this, SLOT(slotPlayFromBackMenu(QAction *)));
setSorting(-1); // Temporarily disable sorting to add items faster.
m_columnTags[PlaylistItem::ArtistColumn] = new TagCountDict(5001, false);
m_columnTags[PlaylistItem::ArtistColumn]->setAutoDelete(true);
m_columnTags[PlaylistItem::AlbumColumn] = new TagCountDict(5001, false);
m_columnTags[PlaylistItem::AlbumColumn]->setAutoDelete(true);
m_columnTags[PlaylistItem::GenreColumn] = new TagCountDict(5001, false);
m_columnTags[PlaylistItem::GenreColumn]->setAutoDelete(true);
polish();
m_columnTags[PlaylistItem::ArtistColumn] = new TagCountDict;
m_columnTags[PlaylistItem::AlbumColumn] = new TagCountDict;
m_columnTags[PlaylistItem::GenreColumn] = new TagCountDict;
}
CollectionList::~CollectionList()
......@@ -271,8 +262,9 @@ CollectionList::~CollectionList()
// are.
clearItems(items());
for(TagCountDicts::Iterator it = m_columnTags.begin(); it != m_columnTags.end(); ++it)
delete *it;
qDeleteAll(m_columnTags);
m_columnTags.clear();
}
void CollectionList::contentsDropEvent(QDropEvent *e)
......@@ -296,11 +288,10 @@ QString CollectionList::addStringToDict(const QString &value, int column)
if(column > m_columnTags.count() || value.trimmed().isEmpty())
return QString();
int *refCountPtr = m_columnTags[column]->find(value);
if(refCountPtr)
++(*refCountPtr);
if(m_columnTags[column]->contains(value))
++((*m_columnTags[column])[value]);
else {
m_columnTags[column]->insert(value, new int(1));
m_columnTags[column]->insert(value, 1);
emit signalNewTag(value, column);
}
......@@ -329,33 +320,37 @@ QStringList CollectionList::uniqueSet(UniqueSetType t) const
return QStringList();
}
if(column >= m_columnTags.count())
return QStringList();
TagCountDictIterator it(*m_columnTags[column]);
QStringList list;
for(; it.current(); ++it)
list += it.currentKey();
return m_columnTags[column]->keys();
}
return list;
CollectionListItem *CollectionList::lookup(const QString &file) const
{
return m_itemsDict.value(file, 0);
}
void CollectionList::removeStringFromDict(const QString &value, int column)
{
if(column > m_columnTags.count() || value.isEmpty())
if(column > m_columnTags.count() || value.trimmed().isEmpty())
return;
int *refCountPtr = m_columnTags[column]->find(value);
if(refCountPtr) {
--(*refCountPtr);
if(*refCountPtr == 0) {
emit signalRemovedTag(value, column);
m_columnTags[column]->remove(value);
}
if(m_columnTags[column]->contains(value) &&
--((*m_columnTags[column])[value])) // If the decrement goes to 0...
{
emit signalRemovedTag(value, column);
m_columnTags[column]->remove(value);
}
}
void CollectionList::addWatched(const QString &file)
{
m_dirWatch->addFile(file);
}
void CollectionList::removeWatched(const QString &file)
{
m_dirWatch->removeFile(file);
}
////////////////////////////////////////////////////////////////////////////////
// CollectionListItem public methods
////////////////////////////////////////////////////////////////////////////////
......@@ -502,7 +497,7 @@ void CollectionListItem::addChildItem(PlaylistItem *child)
void CollectionListItem::removeChildItem(PlaylistItem *child)
{
if(!m_shuttingDown)
m_children.remove(child);
m_children.removeAll(child);
}
bool CollectionListItem::checkCurrent()
......
......@@ -16,23 +16,17 @@
#ifndef COLLECTIONLIST_H
#define COLLECTIONLIST_H
#include <kapplication.h>
#include <kdirwatch.h>
#include <kfileitem.h>
#include <q3dict.h>
#include <qclipboard.h>
#include <q3valuevector.h>
//Added by qt3to4:
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QHash>
#include <QVector>
#include "playlist.h"
#include "playlistitem.h"
#include "sortedstringlist.h"
class CollectionListItem;
class ViewMode;
class KFileItem;
class KFileItemList;
class KDirWatch;
/**
* This type is for mapping QString track attributes like the album, artist
......@@ -40,16 +34,16 @@ class ViewMode;
* that hold the string.
*/
typedef Q3Dict<int> TagCountDict;
typedef Q3DictIterator<int> TagCountDictIterator;
typedef QHash<QString, int> TagCountDict;
typedef QHashIterator<QString, int> TagCountDictIterator;
/**
* We then have an array of dicts, one for each column in the list view. We
* use pointers to TagCountDicts because QDict has a broken copy ctor, which
* doesn't copy the case sensitivity setting.
* We then have an array of dicts, one for each column in the list view.
* The array is sparse (not every vector will have a TagCountDict so we use
* pointers.
*/
typedef Q3ValueVector<TagCountDict*> TagCountDicts;
typedef QVector<TagCountDict *> TagCountDicts;
/**
* This is the "collection", or all of the music files that have been opened
......@@ -83,7 +77,7 @@ public:
*/
QStringList uniqueSet(UniqueSetType t) const;
CollectionListItem *lookup(const QString &file) { return m_itemsDict.find(file); }
CollectionListItem *lookup(const QString &file) const;
virtual PlaylistItem *createItem(const FileHandle &file,
Q3ListViewItem * = 0,
......@@ -98,7 +92,7 @@ public:
virtual bool canReload() const { return true; }
public slots:
virtual void paste() { decode(kapp->clipboard()->mimeData()); }
virtual void paste();
virtual void clear();
void slotCheckCache();
......@@ -118,7 +112,7 @@ protected:
// These methods are used by CollectionListItem, which is a friend class.
void addToDict(const QString &file, CollectionListItem *item) { m_itemsDict.replace(file, item); }
void addToDict(const QString &file, CollectionListItem *item) { m_itemsDict.insert(file, item); }
void removeFromDict(const QString &file) { m_itemsDict.remove(file); }
// These methods are also used by CollectionListItem, to manage the
......@@ -127,10 +121,10 @@ protected:
QString addStringToDict(const QString &value, int column);
void removeStringFromDict(const QString &value, int column);
void addWatched(const QString &file) { m_dirWatch->addFile(file); }
void removeWatched(const QString &file) { m_dirWatch->removeFile(file); }
void addWatched(const QString &file);
void removeWatched(const QString &file);
virtual bool hasItem(const QString &file) const { return m_itemsDict.find(file); }
virtual bool hasItem(const QString &file) const { return m_itemsDict.contains(file); }
signals:
void signalCollectionChanged();
......@@ -154,7 +148,7 @@ private:
static const int m_uniqueSetCount = 3;
static CollectionList *m_list;
Q3Dict<CollectionListItem> m_itemsDict;
QHash<QString, CollectionListItem *> m_itemsDict;
KDirWatch *m_dirWatch;
TagCountDicts m_columnTags;
};
......@@ -165,11 +159,6 @@ class CollectionListItem : public PlaylistItem
friend class CollectionList;
friend class PlaylistItem;
/**
* Needs access to the destructor, even though the destructor isn't used by QDict.
*/
friend class Q3Dict<CollectionListItem>;
public:
virtual void refresh();
PlaylistItem *itemForPlaylist(const Playlist *playlist);
......
......@@ -24,8 +24,7 @@
#include <klocale.h>
#include <QTimer>
#include <QToolButton>
#include <Q3ValueList>
#include <QList>
#include "covericonview.h"
#include "covermanager.h"
......@@ -102,13 +101,12 @@ void CoverDialog::show()
// covers.
void CoverDialog::loadCovers()
{
Q3ValueList<coverKey> keys = CoverManager::keys();
Q3ValueList<coverKey>::ConstIterator it;
int i = 0;
for(it = keys.begin(); it != keys.end(); ++it) {
new CoverIconViewItem(*it, m_covers);
foreach(coverKey cover, CoverManager::keys()) {
(void) new CoverIconViewItem(cover, m_covers);
// TODO: Threading!
if(++i == 10) {
i = 0;
kapp->processEvents();
......@@ -127,13 +125,11 @@ void CoverDialog::slotArtistClicked(Q3ListViewItem *item)
}
else {
QString artist = item->text(0).toLower();
Q3ValueList<coverKey> keys = CoverManager::keys();
Q3ValueList<coverKey>::ConstIterator it;
for(it = keys.begin(); it != keys.end(); ++it) {
CoverDataPtr data = CoverManager::coverInfo(*it);
foreach(coverKey cover, CoverManager::keys()) {
CoverDataPtr data = CoverManager::coverInfo(cover);
if(data->artist == artist)
new CoverIconViewItem(*it, m_covers);
(void) new CoverIconViewItem(cover, m_covers);
}
}
}
......
......@@ -16,7 +16,6 @@
#include "covermanager.h"
#include <QPixmap>
#include <QMap>
#include <QString>
#include <QFile>
#include <QImage>
......@@ -26,7 +25,8 @@
#include <Q3Cache>
#include <QMimeSource>
#include <QBuffer>
#include <Q3ValueList>
#include <QList>
#include <QMap>
#include <kdebug.h>
#include <kstaticdeleter.h>
......@@ -160,7 +160,7 @@ void CoverManagerPrivate::saveCovers() const
out << quint32(0) << quint32(covers.count());
// Write out the data
for(CoverDataMap::ConstIterator it = covers.begin(); it != covers.end(); ++it) {
for(CoverDataMap::const_iterator it = covers.begin(); it != covers.end(); ++it) {
out << quint32(it.key());
out << *it.value();
}
......@@ -321,8 +321,8 @@ coverKey CoverManager::idFromMetadata(const QString &artist, const QString &albu
{
// Search for the string, yay! It might make sense to use a cache here,
// if so it's not hard to add a QCache.
CoverDataMap::ConstIterator it = begin();
CoverDataMap::ConstIterator endIt = end();
CoverDataMap::const_iterator it = begin();
CoverDataMap::const_iterator endIt = end();
for(; it != endIt; ++it) {
if(it.value()->album == album.toLower() && it.value()->artist == artist.toLower())
......@@ -489,17 +489,17 @@ void CoverManager::shutdown()
sd.destructObject();
}
CoverDataMap::ConstIterator CoverManager::begin()
CoverDataMapIterator CoverManager::begin()
{
return data()->covers.constBegin();
}
CoverDataMap::ConstIterator CoverManager::end()
CoverDataMapIterator CoverManager::end()
{
return data()->covers.constEnd();
}
Q3ValueList<coverKey> CoverManager::keys()
CoverList CoverManager::keys()
{
return data()->covers.keys();
}
......
......@@ -18,16 +18,17 @@
#include <ksharedptr.h>
#include <QMap>
#include <q3dragobject.h>
//Added by qt3to4:
#include <QPixmap>
#include <Q3ValueList>
#include <Q3DragObject>
#include <QString>
class CoverManagerPrivate;
class QString;
class QPixmap;
class QDataStream;
template<class Key, class Value>
class QMap;
template<class T>
class QList;
/**
* This class holds the data on a cover. This includes the path to the cover
......@@ -54,8 +55,14 @@ public:
typedef KSharedPtr<CoverData> CoverDataPtr;
typedef unsigned long coverKey; ///< Type of the id for a cover.
typedef QMap<coverKey, CoverDataPtr> CoverDataMap;
// I can't believe this actually works...
typedef CoverDataMap::const_iterator CoverDataMapIterator;
typedef QList<coverKey> CoverList;
/**
* This class is used to drag covers in JuK. It adds a special mimetype that
* contains the cover ID used for this cover, and also supports an image/png
......@@ -217,17 +224,17 @@ public:
/**
* @return Iterator pointing to the first element in the cover database.
*/
static CoverDataMap::ConstIterator begin();
static CoverDataMapIterator begin();
/**
* @return Iterator pointing after the last element in the cover database.
*/
static CoverDataMap::ConstIterator end();
static CoverDataMapIterator end();
/**
* @return A list of all of the id's listed in the database.
*/
static Q3ValueList<coverKey> keys();
static CoverList keys();
/**
* Associates @p path with the cover identified by @id. No comparison of
......
......@@ -18,11 +18,7 @@
#include "playlistcollection.h"
#include "tracksequencemanager.h"
#include <kdebug.h>
#include <QShowEvent>
#include <Q3ValueList>
#include <QPaintEvent>
#include <QTimer>
class PlaylistDirtyObserver : public PlaylistObserver
{
......@@ -71,12 +67,8 @@ DynamicPlaylist::~DynamicPlaylist()
{
lower();
for(Q3ValueList<PlaylistObserver *>::ConstIterator it = m_observers.begin();
it != m_observers.end();
++it)
{
delete *it;
}
foreach(PlaylistObserver *observer, m_observers)
delete observer;
}
void DynamicPlaylist::setPlaylists(const PlaylistList &playlists)
......@@ -115,7 +107,7 @@ void DynamicPlaylist::lower(QWidget *top)
PlaylistItemList list = PlaylistItem::playingItems();
for(PlaylistItemList::Iterator it = list.begin(); it != list.end(); ++it) {
if((*it)->playlist() == this) {
list.remove(it);
list.erase(it);
break;
}
}
......
......@@ -18,10 +18,7 @@
#include "playlist.h"
#include <Q3ValueList>
class QPaintEvent;
class QShowEvent;
#include <QList>
/**
* A Playlist that is a union of other playlists that is created dynamically.
......@@ -105,7 +102,7 @@ private slots:
void slotUpdateItems();
private:
Q3ValueList<PlaylistObserver *> m_observers;
QList<PlaylistObserver *> m_observers;
PlaylistItemList m_siblings;
PlaylistList m_playlists;
bool m_dirty;
......
......@@ -16,7 +16,7 @@
#ifndef FILEHANDLE_H
#define FILEHANDLE_H
#include <Q3ValueList>
#include <QString>
class QFileInfo;
class QDateTime;
......@@ -27,6 +27,9 @@ class CoverInfo;
class Tag;
class CacheDataStream;
template<class T>
class QList;
/**
* An value based, explicitly shared wrapper around file related information
* used in JuK's playlists.
......@@ -75,7 +78,7 @@ private:
void setup(const QFileInfo &info, const QString &path);
};
typedef Q3ValueList<FileHandle> FileHandleList;
typedef QList<FileHandle> FileHandleList;
QDataStream &operator<<(QDataStream &s, const FileHandle &f);
CacheDataStream &operator>>(CacheDataStream &s, FileHandle &f);
......
/***************************************************************************
begin : Thu Oct 28 2004
copyright : (C) 2004 by Michael Pyne
copyright : (C) 2004, 2007 by Michael Pyne
: (c) 2003 Frerich Raabe <raabe@kde.org>
email : michael.pyne@kdemail.net
***************************************************************************/
......@@ -19,19 +19,17 @@
#include <algorithm>
#include <kdebug.h>
#include <kcombobox.h>
#include <kurl.h>
#include <kurlrequester.h>
//#include <kurlrequester.h>
#include <kiconloader.h>
#include <knuminput.h>
//#include <knuminput.h>
#include <kstandarddirs.h>
#include <kio/netaccess.h>
#include <kconfigbase.h>
#include <kconfig.h>
#include <kdesktopfile.h>
#include <kconfiggroup.h>
#include <kglobal.h>
#include <klineedit.h>
//#include <klineedit.h>
#include <klocale.h>
#include <kconfiggroup.h>
#include <kpushbutton.h>
#include <kapplication.h>
#include <kmessagebox.h>
......@@ -40,25 +38,22 @@
#include <Q3ScrollView>
#include <QFile>
#include <QObject>
#include <QTimer>
#include <QRegExp>
#include <QCheckBox>
#include <QDir>
#include <QLabel>
#include <QLayout>
#include <QSignalMapper>
#include <Q3Header>
#include <QPalette>
#include <QPixmap>
#include <QFrame>
#include <Q3ValueList>
#include "tag.h"
#include "filerenameroptions.h"
#include "filehandle.h"
#include "exampleoptions.h"
#include "playlistitem.h"
#include "playlist.h"
#include "playlist.h" // processEvents()
#include "coverinfo.h"
class ConfirmationDialog : public KDialog
......@@ -133,7 +128,7 @@ ConfigCategoryReader::ConfigCategoryReader() : CategoryReaderInterface(),
m_categoryOrder << catId;
}
m_folderSeparators.resize(m_categoryOrder.count() - 1, false);
m_folderSeparators.fill(false, m_categoryOrder.count() - 1);
QList<int> checkedSeparators = config.readEntry("CheckedDirSeparators", QList<int>());
......@@ -143,7 +138,7 @@ ConfigCategoryReader::ConfigCategoryReader() : CategoryReaderInterface(),
m_folderSeparators[*it] = true;
}
m_musicFolder = config.readEntry("MusicFolder", "${HOME}/music");
m_musicFolder = config.readPathEntry("MusicFolder", "${HOME}/music");
m_separator = config.readEntry("Separator", " - ");
}
......@@ -1020,12 +1015,12 @@ void FileRenamer::setFolderIcon(const KUrl &dst, const PlaylistItem *item)
QPixmap thumb = item->file().coverInfo()->pixmap(CoverInfo::Thumbnail);
thumb.save(path + "/.juk-thumbnail.png", "PNG");
KConfig _config( path + "/.directory", KConfig::OnlyLocal );
KConfigGroup config(&_config, "Desktop Entry");
KDesktopFile dirFile(path + "/.directory");
KConfigGroup desktopGroup(dirFile.desktopGroup());
if(!config.hasKey("Icon")) {
config.writeEntry("Icon", QString("%1/.juk-thumbnail.png").arg(path));
config.sync();
if(!desktopGroup.hasKey("Icon")) {
desktopGroup.writePathEntry("Icon", QString("%1/.juk-thumbnail.png").arg(path));
dirFile.sync();
}
return;
......
/***************************************************************************
begin : Thu Oct 28 2004
copyright : (C) 2004 by Michael Pyne
copyright : (C) 2004, 2007 by Michael Pyne
: (C) 2003 Frerich Raabe <raabe@kde.org>
email : michael.pyne@kdemail.net
***************************************************************************/
......@@ -18,25 +18,27 @@