...
 
Commits (49)
......@@ -42,6 +42,25 @@ if(TUNEPIMP_FOUND)
endif(TUNEPIMP_FOUND)
set(juk_SRCS ${tunepimp_SRCS}
# Playlist classes
playlist/playlists/playlist.cpp
playlist/playlists/dynamicplaylist.cpp
playlist/playlists/folderplaylist.cpp
playlist/playlists/historyplaylist.cpp
playlist/playlists/searchplaylist.cpp
playlist/playlists/treeviewitemplaylist.cpp
playlist/playlists/upcomingplaylist.cpp
playlist/playlistcollection.cpp
playlist/playlistinterface.cpp
playlist/playlistexporter.cpp
playlist/playlistsearch.cpp
playlist/playlistview.cpp
playlist/playlistheaderview.cpp
playlist/playlistsortfilterproxymodel.cpp
playlistbox.cpp
playlistsplitter.cpp
advancedsearchdialog.cpp
slider.cpp
svghandler.cpp
......@@ -58,15 +77,12 @@ set(juk_SRCS ${tunepimp_SRCS}
dbuscollectionproxy.cpp
deletedialog.cpp
directorylist.cpp
dynamicplaylist.cpp
exampleoptions.cpp
folderplaylist.cpp
filehandle.cpp
filerenamer.cpp
filerenameroptions.cpp
filerenamerconfigdlg.cpp
webimagefetcher.cpp
historyplaylist.cpp
juk.cpp
k3bexporter.cpp
keydialog.cpp
......@@ -78,17 +94,8 @@ set(juk_SRCS ${tunepimp_SRCS}
musicbrainzquery.cpp
nowplaying.cpp
playermanager.cpp
playlist.cpp
playlistbox.cpp
playlistcollection.cpp
playlistexporter.cpp
playlistinterface.cpp
playlistitem.cpp
playlistsearch.cpp
playlistsplitter.cpp
scrobbler.cpp
scrobbleconfigdlg.cpp
searchplaylist.cpp
searchwidget.cpp
slideraction.cpp
sortedstringlist.cpp
......@@ -104,8 +111,6 @@ set(juk_SRCS ${tunepimp_SRCS}
tagtransactionmanager.cpp
tracksequenceiterator.cpp
tracksequencemanager.cpp
treeviewitemplaylist.cpp
upcomingplaylist.cpp
ktrm.cpp
viewmode.cpp )
......
......@@ -19,7 +19,7 @@
#include <kdialog.h>
#include <QList>
#include "playlistsearch.h"
#include "playlist/playlistsearch.h"
class KLineEdit;
class KPushButton;
......
......@@ -31,11 +31,11 @@
#include <QBuffer>
#include "tag.h"
#include "searchplaylist.h"
#include "historyplaylist.h"
#include "upcomingplaylist.h"
#include "folderplaylist.h"
#include "playlistcollection.h"
#include "playlist/playlists/searchplaylist.h"
#include "playlist/playlists/historyplaylist.h"
#include "playlist/playlists/upcomingplaylist.h"
#include "playlist/playlists/folderplaylist.h"
#include "playlist/playlistcollection.h"
#include "actioncollection.h"
using namespace ActionCollection;
......@@ -215,8 +215,10 @@ void Cache::loadPlaylists(PlaylistCollection *collection) // static
if(version >= 2) {
qint32 sortColumn;
s >> sortColumn;
if(playlist)
playlist->setSorting(sortColumn);
if(playlist) {
// ### TODO: View
// playlist->setSorting(sortColumn);
}
}
} // while !s.atEnd()
......@@ -313,7 +315,8 @@ void Cache::savePlaylists(const PlaylistList &playlists)
s << qint32(Normal)
<< *(*it);
}
s << qint32((*it)->sortColumn());
// ### TODO: View
s << qint32(0);//qint32((*it)->sortColumn());
}
}
......
This diff is collapsed.
......@@ -19,8 +19,7 @@
#include <QHash>
#include <QVector>
#include "playlist.h"
#include "playlistitem.h"
#include "playlist/playlists/playlist.h"
class ViewMode;
class KFileItem;
......@@ -44,53 +43,9 @@ typedef QHashIterator<QString, int> TagCountDictIterator;
typedef QVector<TagCountDict *> TagCountDicts;
/**
* This is the "collection", or all of the music files that have been opened
* in any playlist and not explicitly removed from the collection.
*
* It is being implemented as a "semi-singleton" because I need universal access
* to just one instance. However, because the collection needs initialization
* parameters (that will not always be available when an instance is needed).
* Hence there will be the familiar singleton "instance()" method allong with an
* "initialize()" method.
*/
class CollectionListItem : public PlaylistItem
{
friend class Playlist;
friend class CollectionList;
friend class PlaylistItem;
public:
virtual void refresh();
PlaylistItem *itemForPlaylist(const Playlist *playlist);
void updateCollectionDict(const QString &oldPath, const QString &newPath);
void repaint() const;
PlaylistItemList children() const { return m_children; }
protected:
CollectionListItem(CollectionList *parent, const FileHandle &file);
virtual ~CollectionListItem();
void addChildItem(PlaylistItem *child);
void removeChildItem(PlaylistItem *child);
/**
* Returns true if the item is now up to date (even if this required a refresh) or
* false if the item is invalid.
*/
bool checkCurrent();
virtual CollectionListItem *collectionItem() { return this; }
private:
bool m_shuttingDown;
PlaylistItemList m_children;
};
class CollectionList : public Playlist
{
friend class CollectionListItem;
// friend class CollectionListItem;
Q_OBJECT
......@@ -109,19 +64,15 @@ public:
*/
QStringList uniqueSet(UniqueSetType t) const;
CollectionListItem *lookup(const QString &file) const;
virtual CollectionListItem *createItem(const FileHandle &file,
Q3ListViewItem * = 0,
bool = false);
const FileHandle &lookup(const QString& file) const;
void emitVisibleColumnsChanged() { emit signalVisibleColumnsChanged(); }
virtual void clearItems(const PlaylistItemList &items);
void setupTreeViewEntries(ViewMode *viewMode) const;
virtual bool canReload() const { return true; }
virtual void removeFile(const FileHandle& file);
public slots:
virtual void paste();
......@@ -133,18 +84,17 @@ public slots:
void slotNewItems(const KFileItemList &items);
void slotRefreshItems(const QList<QPair<KFileItem, KFileItem> > &items);
void slotDeleteItem(const KFileItem &item);
protected:
CollectionList(PlaylistCollection *collection);
virtual ~CollectionList();
virtual void contentsDropEvent(QDropEvent *e);
virtual void contentsDragMoveEvent(QDragMoveEvent *e);
// virtual void contentsDropEvent(QDropEvent *e);
// virtual void contentsDragMoveEvent(QDragMoveEvent *e);
// These methods are used by CollectionListItem, which is a friend class.
void addToDict(const QString &file, CollectionListItem *item) { m_itemsDict.insert(file, item); }
void addToDict(const QString &file, const FileHandle &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
......@@ -187,7 +137,7 @@ private:
static const int m_uniqueSetCount = 3;
static CollectionList *m_list;
QHash<QString, CollectionListItem *> m_itemsDict;
QHash<QString, FileHandle> m_itemsDict;
KDirWatch *m_dirWatch;
TagCountDicts m_columnTags;
};
......
/***************************************************************************
begin : Sun May 15 2005
copyright : (C) 2005 by Michael Pyne
: (C) 2014 by Arnold Dumas <contact@arnolddumas.fr>
email : michael.pyne@kdemail.net
***************************************************************************/
......@@ -15,9 +16,6 @@
#include "coverdialog.h"
#include <k3listview.h>
#include <k3iconview.h>
#include <k3iconviewsearchline.h>
#include <kiconloader.h>
#include <kapplication.h>
#include <kmenu.h>
......@@ -31,32 +29,32 @@
using CoverUtility::CoverIconViewItem;
class AllArtistsListViewItem : public K3ListViewItem
class AllArtistsListViewItem : public QListWidgetItem
{
public:
AllArtistsListViewItem(Q3ListView *parent) :
K3ListViewItem(parent, i18n("&lt;All Artists&gt;"))
AllArtistsListViewItem(KListWidget *parent) :
QListWidgetItem(i18n("&lt;All Artists&gt;"), parent)
{
}
int compare(Q3ListViewItem *, int, bool) const
bool operator< (const QListWidgetItem& other) const
{
return -1; // Always be at the top.
Q_UNUSED(other);
return true; // Always be at the top.
}
};
class CaseInsensitiveItem : public K3ListViewItem
class CaseInsensitiveItem : public QListWidgetItem
{
public:
CaseInsensitiveItem(Q3ListView *parent, const QString &text) :
K3ListViewItem(parent, text)
CaseInsensitiveItem(KListWidget *parent, const QString &text) :
QListWidgetItem(text, parent)
{
}
int compare(Q3ListViewItem *item, int column, bool ascending) const
bool operator< (const QListWidgetItem& other) const
{
Q_UNUSED(ascending);
return text(column).toLower().localeAwareCompare(item->text(column).toLower());
return text().toLower().localeAwareCompare(other.text().toLower());
}
};
......@@ -67,11 +65,16 @@ CoverDialog::CoverDialog(QWidget *parent) :
setObjectName( QLatin1String("juk_cover_dialog" ));
m_covers->setResizeMode(Q3IconView::Adjust);
m_covers->setGridX(140);
m_covers->setGridY(150);
m_searchLine->setClearButtonShown(true);
m_searchLine->setIconView(m_covers);
connect(m_artists, SIGNAL(itemClicked(QListWidgetItem*)),
this, SLOT(slotArtistClicked(QListWidgetItem*)));
connect(m_covers, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(slotContextRequested(QPoint)));
connect(m_searchLine, SIGNAL(textChanged(QString)),
this, SLOT(slotSearchPatternChanged(QString)));
}
CoverDialog::~CoverDialog()
......@@ -85,13 +88,10 @@ void CoverDialog::show()
QStringList artists = CollectionList::instance()->uniqueSet(CollectionList::Artists);
m_artists->setSorting(-1);
new AllArtistsListViewItem(m_artists);
for(QStringList::ConstIterator it = artists.constBegin(); it != artists.constEnd(); ++it)
new CaseInsensitiveItem(m_artists, *it);
m_artists->setSorting(0);
QTimer::singleShot(0, this, SLOT(loadCovers()));
QWidget::show();
}
......@@ -118,7 +118,7 @@ void CoverDialog::loadCovers()
}
// TODO: Add a way to show cover art for tracks with no artist.
void CoverDialog::slotArtistClicked(Q3ListViewItem *item)
void CoverDialog::slotArtistClicked(QListWidgetItem *item)
{
m_covers->clear();
......@@ -127,7 +127,7 @@ void CoverDialog::slotArtistClicked(Q3ListViewItem *item)
loadCovers();
}
else {
QString artist = item->text(0).toLower();
QString artist = item->text().toLower();
CoverDataMapIterator it, end;
......@@ -141,10 +141,12 @@ void CoverDialog::slotArtistClicked(Q3ListViewItem *item)
}
}
void CoverDialog::slotContextRequested(Q3IconViewItem *item, const QPoint &pt)
void CoverDialog::slotContextRequested(const QPoint &pt)
{
static KMenu *menu = 0;
QListWidgetItem* item = m_covers->currentItem();
if(!item)
return;
......@@ -153,7 +155,55 @@ void CoverDialog::slotContextRequested(Q3IconViewItem *item, const QPoint &pt)
menu->addAction(i18n("Remove Cover"), this, SLOT(removeSelectedCover()));
}
menu->popup(pt);
QPoint globalPt = m_covers->mapToGlobal(pt);
menu->popup(globalPt);
}
void CoverDialog::slotSearchPatternChanged(const QString& pattern)
{
m_covers->clear();
QListWidgetItem* item = m_artists->currentItem();
// If the expression is cleared, then use slotArtistClicked.
if (pattern.isEmpty()) {
slotArtistClicked(item);
}
else {
QRegExp filter(pattern, Qt::CaseInsensitive, QRegExp::Wildcard);
QString artist = item->text().toLower();
CoverDataMapIterator it, end;
it = CoverManager::begin();
end = CoverManager::end();
// Here, only show cover that match the search pattern.
if (dynamic_cast<AllArtistsListViewItem *>(item)) {
for(; it != end; ++it) {
if (filter.indexIn(it.value()->artist) != -1) {
(void) new CoverIconViewItem(it.key(), m_covers);
}
}
}
// Here, only show the covers that match the search pattern and
// that have the same artist as the currently selected one.
else {
for(; it != end; ++it) {
if (it.value()->artist == artist
&& (filter.indexIn(it.value()->artist) != -1)
|| (filter.indexIn(it.value()->album) != -1)) {
(void) new CoverIconViewItem(it.key(), m_covers);
}
}
}
}
}
void CoverDialog::removeSelectedCover()
......
/***************************************************************************
begin : Sun May 15 2005
copyright : (C) 2005 by Michael Pyne
: (C) 2014 by Arnold Dumas <contact@arnolddumas.fr>
email : michael.pyne@kdemail.net
***************************************************************************/
......@@ -20,6 +21,8 @@
#include <QWidget>
class QListWidgetItem;
class CoverDialog : public QWidget, public Ui::CoverDialogBase
{
Q_OBJECT
......@@ -30,8 +33,9 @@ public:
virtual void show();
public slots:
void slotArtistClicked(Q3ListViewItem *item);
void slotContextRequested(Q3IconViewItem *item, const QPoint &pt);
void slotArtistClicked(QListWidgetItem *item);
void slotContextRequested(const QPoint &pt);
void slotSearchPatternChanged(const QString& pattern);
private slots:
void loadCovers();
......
......@@ -20,7 +20,7 @@
<number>6</number>
</property>
<item>
<widget class="K3ListView" name="m_artists" >
<widget class="KListWidget" name="m_artists" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>5</hsizetype>
......@@ -35,12 +35,6 @@
<height>0</height>
</size>
</property>
<property name="resizeMode" >
<enum>Q3ListView::LastColumn</enum>
</property>
<property name="shadeSortColumn" >
<bool>false</bool>
</property>
<column>
<property name="text" >
<string>Artist</string>
......@@ -65,7 +59,7 @@
<number>6</number>
</property>
<item>
<widget class="K3IconViewSearchLine" native="1" name="m_searchLine" >
<widget class="KLineEdit" native="1" name="m_searchLine" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>5</hsizetype>
......@@ -96,14 +90,14 @@
</widget>
<customwidgets>
<customwidget>
<class>K3ListView</class>
<extends>Q3ListView</extends>
<header>k3listview.h</header>
<class>KListWidget</class>
<extends>QListWidget</extends>
<header>klistwidget.h</header>
</customwidget>
<customwidget>
<class>K3IconViewSearchLine</class>
<class>KLineEdit</class>
<extends>QWidget</extends>
<header>k3iconviewsearchline.h</header>
<header>klineedit.h</header>
</customwidget>
<customwidget>
<class>CoverIconView</class>
......@@ -114,42 +108,10 @@
</customwidgets>
<includes>
<include location="local" >k3listview.h</include>
<include location="local" >k3iconviewsearchline.h</include>
<include location="local" >klineedit.h</include>
<include location="local" >covericonview.h</include>
</includes>
<resources/>
<connections>
<connection>
<sender>m_artists</sender>
<signal>clicked(Q3ListViewItem*)</signal>
<receiver>CoverDialogBase</receiver>
<slot>slotArtistClicked(Q3ListViewItem*)</slot>
<hints>
<hint type="sourcelabel" >
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel" >
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_covers</sender>
<signal>contextMenuRequested(Q3IconViewItem*,QPoint)</signal>
<receiver>CoverDialogBase</receiver>
<slot>slotContextRequested(Q3IconViewItem*,QPoint)</slot>
<hints>
<hint type="sourcelabel" >
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel" >
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
</connections>
</ui>
/***************************************************************************
begin : Sat Jul 9 2005
copyright : (C) 2005 by Michael Pyne
: (C) 2014 by Arnold Dumas <contact@arnolddumas.fr>
email : michael.pyne@kdemail.net
***************************************************************************/
......@@ -18,34 +19,41 @@
using CoverUtility::CoverIconViewItem;
CoverIconViewItem::CoverIconViewItem(coverKey id, Q3IconView *parent) :
K3IconViewItem(parent), m_id(id)
CoverIconViewItem::CoverIconViewItem(coverKey id, KListWidget *parent) :
QListWidgetItem(parent), m_id(id)
{
CoverDataPtr data = CoverManager::coverInfo(id);
setText(QString("%1 - %2").arg(data->artist, data->album));
setPixmap(data->thumbnail());
setIcon(data->thumbnail());
setSizeHint(QSize(140, 150));
}
CoverIconView::CoverIconView(QWidget *parent, const char *name) : K3IconView(parent, name)
CoverIconView::CoverIconView(QWidget *parent, const char *name) : KListWidget(parent)
{
setResizeMode(Adjust);
setObjectName(name);
setResizeMode(KListWidget::Adjust);
setViewMode(KListWidget::IconMode);
setIconSize(QSize(130, 140));
setMovement(KListWidget::Static);
setContextMenuPolicy(Qt::CustomContextMenu);
}
CoverIconViewItem *CoverIconView::currentItem() const
{
return static_cast<CoverIconViewItem *>(K3IconView::currentItem());
return static_cast<CoverIconViewItem *>(KListWidget::currentItem());
}
// TODO: port to Qt4
#if 0
Q3DragObject *CoverIconView::dragObject()
{
#if 0
// Temporarily disabled pending conversion of the cover manager icon view
// to Qt 4 ish stuff.
CoverIconViewItem *item = currentItem();
if(item)
return new CoverDrag(item->id(), this);
#endif
return 0;
}
#endif
// vim: set et sw=4 tw=0 sta:
/***************************************************************************
begin : Sat Jul 9 2005
copyright : (C) 2005 by Michael Pyne
: (C) 2014 by Arnold Dumas <contact@arnolddumas.fr>
email : michael.pyne@kdemail.net
***************************************************************************/
......@@ -16,7 +17,7 @@
#ifndef COVERICONVIEW_H
#define COVERICONVIEW_H
#include <k3iconview.h>
#include <klistwidget.h>
#include "covermanager.h"
......@@ -27,10 +28,10 @@
namespace CoverUtility
{
class CoverIconViewItem : public K3IconViewItem
class CoverIconViewItem : public QListWidgetItem
{
public:
CoverIconViewItem(coverKey id, Q3IconView *parent);
CoverIconViewItem(coverKey id, KListWidget *parent);
coverKey id() const { return m_id; }
......@@ -42,12 +43,12 @@ namespace CoverUtility
using CoverUtility::CoverIconViewItem;
/**
* This class subclasses K3IconView in order to provide cover drag-and-drop
* This class subclasses KListWidget in order to provide cover drag-and-drop
* support.
*
* @author Michael Pyne <michael.pyne@kdemail.net>
*/
class CoverIconView : public K3IconView
class CoverIconView : public KListWidget
{
public:
explicit CoverIconView(QWidget *parent, const char *name = 0);
......@@ -55,7 +56,7 @@ public:
CoverIconViewItem *currentItem() const;
protected:
virtual Q3DragObject *dragObject();
// virtual Q3DragObject *dragObject();
};
#endif /* COVERICONVIEW_H */
......
......@@ -47,8 +47,7 @@
#include "mediafiles.h"
#include "collectionlist.h"
#include "playlistsearch.h"
#include "playlistitem.h"
#include "playlist/playlistsearch.h"
#include "tag.h"
struct CoverPopup : public QWidget
......@@ -171,11 +170,11 @@ void CoverInfo::applyCoverToWholeAlbum(bool overwriteExistingCovers) const
PlaylistSearch::ComponentList components;
ColumnList columns;
columns.append(PlaylistItem::ArtistColumn);
columns.append(Playlist::ArtistColumn);
components.append(PlaylistSearch::Component(artist, false, columns, PlaylistSearch::Component::Exact));
columns.clear();
columns.append(PlaylistItem::AlbumColumn);
columns.append(Playlist::AlbumColumn);
components.append(PlaylistSearch::Component(album, false, columns, PlaylistSearch::Component::Exact));
PlaylistList playlists;
......@@ -185,16 +184,18 @@ void CoverInfo::applyCoverToWholeAlbum(bool overwriteExistingCovers) const
// Search done, iterate through results.
PlaylistItemList results = search.matchedItems();
PlaylistItemList::ConstIterator it = results.constBegin();
QModelIndexList results = search.matchedItems();
QModelIndexList::ConstIterator it = results.constBegin();
for(; it != results.constEnd(); ++it) {
// Don't worry about files that somehow already have a tag,
// unless the conversion is forced.
if(!overwriteExistingCovers && (*it)->file().coverInfo()->coverId() != CoverManager::NoMatch)
const Playlist *playlist= qobject_cast<const Playlist*>(it->model());
const FileHandle &file = playlist->data(*it, Qt::UserRole).value<FileHandle>();
if(!overwriteExistingCovers && file.coverInfo()->coverId() != CoverManager::NoMatch)
continue;
(*it)->file().coverInfo()->setCoverId(m_coverKey);
file.coverInfo()->setCoverId(m_coverKey);
}
}
......
......@@ -23,7 +23,7 @@
#include <kdebug.h>
#include "collectionadaptor.h"
#include "playlistcollection.h"
#include "playlist/playlistcollection.h"
#include "covermanager.h"
#include "collectionlist.h"
#include "coverinfo.h"
......@@ -119,12 +119,12 @@ QString DBusCollectionProxy::trackCover(const QString &track)
}
// No cover, let's see if one is embedded.
CollectionListItem *collectionItem = CollectionList::instance()->lookup(track);
const FileHandle &file = CollectionList::instance()->lookup(track);
if(!collectionItem)
if(file.isNull())
return QString();
CoverInfo *coverInfo = collectionItem->file().coverInfo();
CoverInfo *coverInfo = file.coverInfo();
if(!coverInfo)
return QString();
......
......@@ -27,6 +27,12 @@
#include "cache.h"
#include "coverinfo.h"
/**
* Used to give every track added in the program a unique identifier. See
* PlaylistItem
*/
quint32 g_trackID = 0;
AddProperty(Title, tag()->title())
AddProperty(Artist, tag()->artist())
AddProperty(Album, tag()->album())
......@@ -70,7 +76,10 @@ class FileHandle::FileHandlePrivate : public RefCounter
public:
FileHandlePrivate() :
tag(0),
coverInfo(0) {}
coverInfo(0),
id(g_trackID++)
{
}
~FileHandlePrivate()
{
......@@ -84,6 +93,7 @@ public:
QFileInfo fileInfo;
QDateTime modificationTime;
QDateTime lastModified;
quint32 id;
};
////////////////////////////////////////////////////////////////////////////////
......@@ -214,6 +224,11 @@ const QDateTime &FileHandle::lastModified() const
return d->lastModified;
}
quint32 FileHandle::id() const
{
return d->id;
}
void FileHandle::read(CacheDataStream &s)
{
switch(s.cacheVersion()) {
......
......@@ -17,6 +17,7 @@
#define FILEHANDLE_H
#include <QString>
#include <QMetaType>
class QFileInfo;
class QDateTime;
......@@ -70,6 +71,8 @@ public:
QString property(const QString &name) const;
static const FileHandle &null();
quint32 id() const;
private:
class FileHandlePrivate;
......@@ -78,6 +81,8 @@ private:
void setup(const QFileInfo &info, const QString &path);
};
Q_DECLARE_METATYPE(FileHandle);
typedef QList<FileHandle> FileHandleList;
QDataStream &operator<<(QDataStream &s, const FileHandle &f);
......
......@@ -2,6 +2,7 @@
begin : Thu Oct 28 2004
copyright : (C) 2004, 2007, 2009 by Michael Pyne
: (c) 2003 Frerich Raabe <raabe@kde.org>
: (C) 2014 Arnold Dumas <contact@arnolddumas.fr>
email : mpyne@kde.org
***************************************************************************/
......@@ -44,14 +45,14 @@
#include <QSignalMapper>
#include <QPixmap>
#include <QFrame>
#include <Q3Header>
#include <QScrollBar>
#include <QTreeWidget>
#include "tag.h"
#include "filerenameroptions.h"
#include "filehandle.h"
#include "exampleoptions.h"
#include "playlistitem.h"
#include "playlist.h" // processEvents()
#include "playlist/playlists/playlist.h" // processEvents()
#include "coverinfo.h"
class ConfirmationDialog : public KDialog
......@@ -77,24 +78,38 @@ public:
"Are you sure you want to continue?"), hbox);
hbox->setStretchFactor(l, 1);
K3ListView *lv = new K3ListView(vbox);
QTreeWidget *lv = new QTreeWidget(vbox);
lv->addColumn(i18n("Original Name"));
lv->addColumn(i18n("New Name"));
QStringList headers;
headers << i18n("Original Name");
headers << i18n("New Name");
lv->setHeaderLabels(headers);
lv->setRootIsDecorated(false);
int lvHeight = 0;
QMap<QString, QString>::ConstIterator it = files.constBegin();
for(; it != files.constEnd(); ++it) {
K3ListViewItem *i = it.key() != it.value()
? new K3ListViewItem(lv, it.key(), it.value())
: new K3ListViewItem(lv, it.key(), i18n("No Change"));
lvHeight += i->height();
QTreeWidgetItem *item = new QTreeWidgetItem(lv);
item->setText(0, it.key());
if (it.key() != it.value()) {
item->setText(1, it.value());
}
else {
item->setText(1, i18n("No Change"));
}
lvHeight += lv->visualItemRect(item).height();
}
lvHeight += lv->horizontalScrollBar()->height() + lv->header()->height();
lv->setMinimumHeight(qMin(lvHeight, 400));
resize(qMin(width(), 500), qMin(minimumHeight(), 400));
show();
}
};
......@@ -142,10 +157,10 @@ ConfigCategoryReader::ConfigCategoryReader() : CategoryReaderInterface(),
QString ConfigCategoryReader::categoryValue(TagType type) const
{
if(!m_currentItem)
if(m_currentItem.isNull())
return QString();
Tag *tag = m_currentItem->file().tag();
Tag *tag = m_currentItem.tag();
switch(type) {
case Track:
......@@ -853,30 +868,30 @@ FileRenamer::FileRenamer()
{
}
void FileRenamer::rename(PlaylistItem *item)
void FileRenamer::rename(const FileHandle& file)
{
PlaylistItemList list;
list.append(item);
FileHandleList list;
list.append(file);
rename(list);
}
void FileRenamer::rename(const PlaylistItemList &items)
void FileRenamer::rename(const FileHandleList& files)
{
ConfigCategoryReader reader;
QStringList errorFiles;
QMap<QString, QString> map;
QMap<QString, PlaylistItem *> itemMap;
QMap<QString, FileHandle> itemMap;
for(PlaylistItemList::ConstIterator it = items.constBegin(); it != items.constEnd(); ++it) {
reader.setPlaylistItem(*it);
QString oldFile = (*it)->file().absFilePath();
QString extension = (*it)->file().fileInfo().suffix();
foreach(const FileHandle &file, files) {
reader.setPlaylistItem(file);
QString oldFile = file.absFilePath();
QString extension = file.fileInfo().suffix();
QString newFile = fileName(reader) + '.' + extension;
if(oldFile != newFile) {
map[oldFile] = newFile;
itemMap[oldFile] = *it;
itemMap[oldFile] = file;
}
}
......@@ -888,8 +903,8 @@ void FileRenamer::rename(const PlaylistItemList &items)
it != map.constEnd(); ++it)
{
if(moveFile(it.key(), it.value())) {
itemMap[it.key()]->setFile(it.value());
itemMap[it.key()]->refresh();
itemMap[it.key()].setFile(it.value());
itemMap[it.key()].refresh();
setFolderIcon(it.value(), itemMap[it.key()]);
}
......@@ -939,10 +954,10 @@ bool FileRenamer::moveFile(const QString &src, const QString &dest)
return KIO::NetAccess::synchronousRun(job, 0);
}
void FileRenamer::setFolderIcon(const KUrl &dst, const PlaylistItem *item)
void FileRenamer::setFolderIcon(const KUrl& dst, const FileHandle& file)
{
if(item->file().tag()->album().isEmpty() ||
!item->file().coverInfo()->hasCover())
if(file.tag()->album().isEmpty() ||
!file.coverInfo()->hasCover())
{
return;
}
......@@ -959,13 +974,13 @@ void FileRenamer::setFolderIcon(const KUrl &dst, const PlaylistItem *item)
path.append('/' + (*it));
kDebug() << "Checking path: " << path;
if((*it).contains(item->file().tag()->album() ) &&
if((*it).contains(file.tag()->album() ) &&
!QFile::exists(path + "/.directory"))
{
// Seems to be a match, let's set the folder icon for the current
// path. First we should write out the file.
QPixmap thumb = item->file().coverInfo()->pixmap(CoverInfo::Thumbnail);
QPixmap thumb = file.coverInfo()->pixmap(CoverInfo::Thumbnail);
thumb.save(path + "/.juk-thumbnail.png", "PNG");
KDesktopFile dirFile(path + "/.directory");
......
......@@ -24,19 +24,17 @@
#include "ui_filerenamerbase.h"
#include "categoryreaderinterface.h"
#include "tagrenameroptions.h"
#include "filehandle.h"
class QCheckBox;
class QPushButton;
class QSignalMapper;
class ExampleOptionsDialog;
class PlaylistItem;
template<class T>
class QList;
typedef QList<PlaylistItem *> PlaylistItemList;
// Used to decide what direction the FileRenamerWidget will move rows in.
enum MovementDirection { MoveUp, MoveDown };
......@@ -98,8 +96,8 @@ public:
ConfigCategoryReader();
const PlaylistItem *playlistItem() const { return m_currentItem; }
void setPlaylistItem(const PlaylistItem *item) { m_currentItem = item; }
const FileHandle &fileHandle() const { return m_currentItem; }
void setPlaylistItem(const FileHandle &file) { m_currentItem = file; }
// CategoryReaderInterface reimplementations
......@@ -116,7 +114,7 @@ public:
virtual bool isDisabled(const CategoryID &category) const;
private:
const PlaylistItem *m_currentItem;
FileHandle m_currentItem;
CategoryOptionsMap m_options;
QList<CategoryID> m_categoryOrder;
QString m_separator;
......@@ -506,7 +504,7 @@ public:
*
* @param item The item to rename.
*/
void rename(PlaylistItem *item);
void rename(const FileHandle &file);
/**
* Renames the filenames on disk of the files given in items according to
......@@ -514,7 +512,7 @@ public:
*
* @param items The items to rename.
*/
void rename(const PlaylistItemList &items);
void rename(const FileHandleList &files);
/**
* Returns the file name that would be generated based on the options read from
......@@ -532,7 +530,7 @@ private:
* there is not already a folder icon set, and if the folder's name has
* the album name.
*/
void setFolderIcon(const KUrl &dst, const PlaylistItem *item);
void setFolderIcon(const KUrl &dst, const FileHandle &item);
/**
* Attempts to rename the file from \a src to \a dest. Returns true if the
......
......@@ -57,6 +57,7 @@
#include "covermanager.h"
#include "tagtransactionmanager.h"
#include "mpris2/mpris2.h"
#include "playermanager.h"
using namespace ActionCollection;
......@@ -78,7 +79,6 @@ JuK::JuK(QWidget *parent) :
m_splitter(0),
m_statusLabel(0),
m_systemTray(0),
m_player(new PlayerManager),
m_shuttingDown(false)
{
// Expect segfaults if you change this order.
......@@ -144,11 +144,6 @@ JuK* JuK::JuKInstance()
return m_instance;
}
PlayerManager *JuK::playerManager() const
{
return m_player;
}
void JuK::coverDownloaded(const QPixmap &cover)
{
QString event(cover.isNull() ? "coverFailed" : "coverDownloaded");
......@@ -172,14 +167,14 @@ void JuK::setupLayout()
{
new TagTransactionManager(this);
m_splitter = new PlaylistSplitter(m_player, this);
m_splitter = new PlaylistSplitter(this);
setCentralWidget(m_splitter);
m_statusLabel = new StatusLabel(m_splitter->playlist(), statusBar());
connect(CollectionList::instance(), SIGNAL(signalCollectionChanged()),
m_statusLabel, SLOT(updateData()));
statusBar()->addWidget(m_statusLabel, 1);
m_player->setStatusLabel(m_statusLabel);
PlayerManager::instance()->setStatusLabel(m_statusLabel);
m_splitter->setFocus();
}
......@@ -233,25 +228,25 @@ void JuK::setupActions()
act = collection->add<KToggleAction>("crossfadeTracks");
act->setText(i18n("Crossfade Between Tracks"));
connect(act, SIGNAL(triggered(bool)), m_player, SLOT(setCrossfadeEnabled(bool)));
connect(act, SIGNAL(triggered(bool)), PlayerManager::instance(), SLOT(setCrossfadeEnabled(bool)));
act = collection->addAction("play", m_player, SLOT(play()));
act = collection->addAction("play", PlayerManager::instance(), SLOT(play()));
act->setText(i18n("&Play"));
act->setIcon(KIcon( QLatin1String( "media-playback-start" )));
act = collection->addAction("pause", m_player, SLOT(pause()));
act = collection->addAction("pause", PlayerManager::instance(), SLOT(pause()));
act->setText(i18n("P&ause"));
act->setIcon(KIcon( QLatin1String( "media-playback-pause" )));
act = collection->addAction("stop", m_player, SLOT(stop()));
act = collection->addAction("stop", PlayerManager::instance(), SLOT(stop()));
act->setText(i18n("&Stop"));
act->setIcon(KIcon( QLatin1String( "media-playback-stop" )));
act = new KToolBarPopupAction(KIcon( QLatin1String( "media-skip-backward") ), i18nc("previous track", "Previous" ), collection);
collection->addAction("back", act);
connect(act, SIGNAL(triggered(bool)), m_player, SLOT(back()));
connect(act, SIGNAL(triggered(bool)), PlayerManager::instance(), SLOT(back()));
act = collection->addAction("forward", m_player, SLOT(forward()));
act = collection->addAction("forward", PlayerManager::instance(), SLOT(forward()));
act->setText(i18nc("next track", "&Next"));
act->setIcon(KIcon( QLatin1String( "media-skip-forward" )));
......@@ -264,27 +259,27 @@ void JuK::setupActions()
// the following are not visible by default
act = collection->addAction("mute", m_player, SLOT(mute()));
act = collection->addAction("mute", PlayerManager::instance(), SLOT(mute()));
act->setText(i18nc("silence playback", "Mute"));
act->setIcon(KIcon( QLatin1String( "audio-volume-muted" )));
act = collection->addAction("volumeUp", m_player, SLOT(volumeUp()));
act = collection->addAction("volumeUp", PlayerManager::instance(), SLOT(volumeUp()));
act->setText(i18n("Volume Up"));
act->setIcon(KIcon( QLatin1String( "audio-volume-high" )));
act = collection->addAction("volumeDown", m_player, SLOT(volumeDown()));
act = collection->addAction("volumeDown", PlayerManager::instance(), SLOT(volumeDown()));
act->setText(i18n("Volume Down"));
act->setIcon(KIcon( QLatin1String( "audio-volume-low" )));
act = collection->addAction("playPause", m_player, SLOT(playPause()));
act = collection->addAction("playPause", PlayerManager::instance(), SLOT(playPause()));
act->setText(i18n("Play / Pause"));
act->setIcon(KIcon( QLatin1String( "media-playback-start" )));
act = collection->addAction("seekForward", m_player, SLOT(seekForward()));
act = collection->addAction("seekForward", PlayerManager::instance(), SLOT(seekForward()));
act->setText(i18n("Seek Forward"));
act->setIcon(KIcon( QLatin1String( "media-seek-forward" )));
act = collection->addAction("seekBack", m_player, SLOT(seekBack()));
act = collection->addAction("seekBack", PlayerManager::instance(), SLOT(seekBack()));
act->setText(i18n("Seek Back"));
act->setIcon(KIcon( QLatin1String( "media-seek-backward" )));
......@@ -337,7 +332,7 @@ void JuK::setupActions()
void JuK::slotSetupSystemTray()
{
if(m_toggleSystemTrayAction && m_toggleSystemTrayAction->isChecked()) {
m_systemTray = new SystemTray(m_player, this);
m_systemTray = new SystemTray(this);
m_systemTray->setObjectName( QLatin1String("systemTray" ));
m_toggleDockOnCloseAction->setEnabled(true);
......@@ -401,16 +396,16 @@ void JuK::readConfig()
KConfigGroup playerConfig(KGlobal::config(), "Player");
if(m_player)
if(PlayerManager::instance())
{
const int maxVolume = 100;
const int volume = playerConfig.readEntry("Volume", maxVolume);
m_player->setVolume(volume * 0.01);
PlayerManager::instance()->setVolume(volume * 0.01);
if(ActionCollection::action<VolumeAction>("volumeAction")->button())
ActionCollection::action<VolumeAction>("volumeAction")->button()->refresh();
bool enableCrossfade = playerConfig.readEntry("CrossfadeTracks", true);
m_player->setCrossfadeEnabled(enableCrossfade);
PlayerManager::instance()->setCrossfadeEnabled(enableCrossfade);
ActionCollection::action<KAction>("crossfadeTracks")->setChecked(enableCrossfade);
}
......@@ -449,9 +444,9 @@ void JuK::saveConfig()
KConfigGroup playerConfig(KGlobal::config(), "Player");
if (m_player)
if (PlayerManager::instance())
{
playerConfig.writeEntry("Volume", static_cast<int>(100.0 * m_player->volume()));
playerConfig.writeEntry("Volume", static_cast<int>(100.0 * PlayerManager::instance()->volume()));
}
playerConfig.writeEntry("RandomPlay", m_randomPlayAction->isChecked());
......@@ -490,8 +485,8 @@ bool JuK::queryExit()
// Some phonon backends will crash on shutdown unless we've stopped
// playback.
if(m_player->playing())
m_player->stop();
if(PlayerManager::instance()->playing())
PlayerManager::instance()->stop();
// Save configuration data.
m_startDocked = !isVisible();
......@@ -534,7 +529,6 @@ void JuK::slotAboutToQuit()
deleteAndClear(m_systemTray);
deleteAndClear(m_splitter);
deleteAndClear(m_player);
deleteAndClear(m_statusLabel);
// Playlists depend on CoverManager, so CoverManager should shutdown as
......@@ -596,7 +590,7 @@ void JuK::slotCheckAlbumNextAction(bool albumRandomEnabled)
// If album random play is enabled, then enable the Play Next Album action
// unless we're not playing right now.
if(albumRandomEnabled && !m_player->playing())
if(albumRandomEnabled && !PlayerManager::instance()->playing())
albumRandomEnabled = false;
action("forwardAlbum")->setEnabled(albumRandomEnabled);
......
......@@ -18,7 +18,6 @@
#include <kxmlguiwindow.h>
#include "playermanager.h"
#include <QKeyEvent>
......@@ -28,7 +27,6 @@ class KGlobalAccel;
class SliderAction;
class StatusLabel;
class SystemTray;
class PlayerManager;
class PlaylistSplitter;
class JuK : public KXmlGuiWindow
......@@ -41,7 +39,6 @@ public:
static JuK* JuKInstance();
PlayerManager *playerManager() const;
// Use a null cover for failure
void coverDownloaded(const QPixmap &cover);
......@@ -90,7 +87,6 @@ private:
KToggleAction *m_toggleSplashAction;
KToggleAction *m_loopPlaylistAction;
PlayerManager *m_player;
KGlobalAccel *m_accel;
bool m_startDocked;
......
......@@ -28,8 +28,7 @@
#include <QMap>
#include "playlistitem.h"
#include "playlist.h"
#include "playlist/playlists/playlist.h"
#include "playlistbox.h"
#include "actioncollection.h"
......@@ -102,7 +101,7 @@ KAction *K3bExporter::action()
return m_action;
}
void K3bExporter::exportPlaylistItems(const PlaylistItemList &items)
void K3bExporter::exportPlaylistItems(const FileHandleList& items)
{
if(items.empty())
return;
......@@ -111,11 +110,12 @@ void K3bExporter::exportPlaylistItems(const PlaylistItemList &items)
void K3bExporter::slotExport()
{
if(m_parent)
exportPlaylistItems(m_parent->selectedItems());
// ### TODO: View
/*if(m_parent)
exportPlaylistItems(m_parent->selectedItems());*/
}
void K3bExporter::exportViaCmdLine(const PlaylistItemList &items)
void K3bExporter::exportViaCmdLine(const FileHandleList &items)
{
K3bOpenMode mode = openMode();
QByteArray cmdOption;
......@@ -138,18 +138,17 @@ void K3bExporter::exportViaCmdLine(const PlaylistItemList &items)
process << "k3b";
process << cmdOption;
PlaylistItemList::ConstIterator it;
for(it = items.begin(); it != items.end(); ++it)
process << (*it)->file().absFilePath();
foreach(const FileHandle &file, items)
process << file.absFilePath();
if(!process.startDetached())
KMessageBox::error(m_parent, i18n("Unable to start K3b."));
KMessageBox::error(/*m_parent ### TODO: View */0, i18n("Unable to start K3b."));
}
K3bExporter::K3bOpenMode K3bExporter::openMode()
{
int reply = KMessageBox::questionYesNoCancel(
m_parent,
/*m_parent*/0,//### TODO: View
i18n("Create an audio mode CD suitable for CD players, or a data "
"mode CD suitable for computers and other digital music "
"players?"),
......@@ -195,7 +194,7 @@ void K3bPlaylistExporter::slotExport()
{
if(m_playlistBox) {
setPlaylist(m_playlistBox->visiblePlaylist());
exportPlaylistItems(m_playlistBox->visiblePlaylist()->items());
exportPlaylistItems(m_playlistBox->visiblePlaylist()->fileHandles());
}
}
......
......@@ -18,10 +18,11 @@
#include <kaction.h>
#include "playlistexporter.h"
#include "playlistitem.h"
#include "playlist/playlistexporter.h"
#include "filehandle.h"
class PlaylistBox;
class Playlist;
class PlaylistAction : public KAction
{
......@@ -67,7 +68,7 @@ public:
void setPlaylist(Playlist *playlist) { m_parent = playlist; }
protected:
void exportPlaylistItems(const PlaylistItemList &items);
void exportPlaylistItems(const FileHandleList &items);
private slots:
void slotExport();
......@@ -76,7 +77,7 @@ private:
enum K3bOpenMode { AudioCD, DataCD, Abort };
// Private method declarations
void exportViaCmdLine(const PlaylistItemList &items);
void exportViaCmdLine(const FileHandleList& items);
K3bOpenMode openMode();
// Private member variable declarations
......
......@@ -22,8 +22,7 @@
#include "juk.h"
#include "playermanager.h"
#include "coverinfo.h"
#include "playlist.h"
#include "playlistitem.h"
#include "playlist/playlists/playlist.h"
#include "tag.h"
#include "filehandle.h"
......@@ -36,24 +35,23 @@
#include <KUrl>
#include <KStandardDirs>
static QByteArray idFromPlaylistItem(const PlaylistItem *item)
static QByteArray idFromFileHandle(const FileHandle &item)
{
return QByteArray("/org/kde/juk/tid_") +
QByteArray::number(item->trackId(), 16).rightJustified(8, '0');
QByteArray::number(item.id(), 16).rightJustified(8, '0');
}
MediaPlayer2Player::MediaPlayer2Player(QObject* parent)
: QDBusAbstractAdaptor(parent)
, m_player(JuK::JuKInstance()->playerManager())
{
connect(m_player, SIGNAL(signalItemChanged(FileHandle)), this, SLOT(currentSourceChanged()));
connect(m_player, SIGNAL(signalPlay()), this, SLOT(stateUpdated()));
connect(m_player, SIGNAL(signalPause()), this, SLOT(stateUpdated()));
connect(m_player, SIGNAL(signalStop()), this, SLOT(stateUpdated()));
connect(m_player, SIGNAL(totalTimeChanged(int)), this, SLOT(totalTimeChanged()));
connect(m_player, SIGNAL(seekableChanged(bool)), this, SLOT(seekableChanged(bool)));
connect(m_player, SIGNAL(volumeChanged(float)), this, SLOT(volumeChanged(float)));
connect(m_player, SIGNAL(seeked(int)), this, SLOT(seeked(int)));
connect(PlayerManager::instance(), SIGNAL(signalItemChanged(FileHandle)), this, SLOT(currentSourceChanged()));
connect(PlayerManager::instance(), SIGNAL(signalPlay()), this, SLOT(stateUpdated()));
connect(PlayerManager::instance(), SIGNAL(signalPause()), this, SLOT(stateUpdated()));
connect(PlayerManager::instance(), SIGNAL(signalStop()), this, SLOT(stateUpdated()));
connect(PlayerManager::instance(), SIGNAL(totalTimeChanged(int)), this, SLOT(totalTimeChanged()));
connect(PlayerManager::instance(), SIGNAL(seekableChanged(bool)), this, SLOT(seekableChanged(bool)));
connect(PlayerManager::instance(), SIGNAL(volumeChanged(float)), this, SLOT(volumeChanged(float)));
connect(PlayerManager::instance(), SIGNAL(seeked(int)), this, SLOT(seeked(int)));
}