Change playlist to use Esperanza's playlistmodel

This commit is contained in:
Thomas Frauendorfer 2007-10-07 14:34:53 +02:00
parent 85cf6a8d1c
commit 503385309b
96 changed files with 2010 additions and 412 deletions

View file

@ -1,29 +0,0 @@
#include <xmmsclient/xmmsclient++.h>
#include <QErrorMessage>
#include "XMMSSocket.h"
XMMSSocket::XMMSSocket (const char *name) :
m_client (name)
{
}
bool
XMMSSocket::connect (const char *path)
{
try {
m_client.connect (path ? path : "");
}
catch (Xmms::connection_error& e) {
QErrorMessage *err = new QErrorMessage ();
err->showMessage ("Couldn't connect to XMMS2, please try again.");
err->exec ();
delete err;
return false;
}
m_client.setMainloop (new XmmsQT4 (m_client.getConnection ()));
return true;
}

View file

@ -1,20 +0,0 @@
#ifndef __XMMSSOCKET_H__
#define __XMMSSOCKET_H__
#include <xmmsclient/xmmsclient++.h>
#include "XmmsQT4.h"
#include <QObject>
#include <QTimer>
class XMMSSocket
{
public:
XMMSSocket (const char *name = "promoe");
~XMMSSocket () { qDebug("destroy"); };
bool connect (const char *path);
Xmms::Client m_client;
};
#endif

View file

@ -1,33 +0,0 @@
#ifndef __XMMSQT4_H__
#define __XMMSQT4_H__
#include <xmmsclient/xmmsclient++/mainloop.h>
#include <QApplication>
#include <QObject>
#include <QSocketNotifier>
class XmmsQT4 : public QObject, public Xmms::MainloopInterface
{
Q_OBJECT
public:
XmmsQT4(xmmsc_connection_t *xmmsc);
~XmmsQT4();
void run ();
void ToggleWrite(bool toggle);
xmmsc_connection_t *GetXmmsConnection();
public slots:
void OnRead ();
void OnWrite ();
private:
int m_fd;
QSocketNotifier *m_rsock;
QSocketNotifier *m_wsock;
xmmsc_connection_t *m_xmmsc;
};
#endif

2
config.pri Normal file
View file

@ -0,0 +1,2 @@
DEPENDPATH += $PWD/src $PWD/lib
INCLUDEPATH += $$PWD/src $$PWD/lib

2
lib/TODO Normal file
View file

@ -0,0 +1,2 @@
Contains a copy of some of Esperanzas src/lib/ directory
Will have to be removed as soon as those files become a seperate lib

28
lib/debug.h Normal file
View file

@ -0,0 +1,28 @@
/**
* This file is a part of Esperanza, an XMMS2 Client.
*
* Copyright (C) 2007 XMMS2 Team
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
// Usage: include it and then just do a DBGOUT("bla foo bar " << variable << " is awesome.");
// while in debug mode, it will all be print to console. In release mode, DBGOUT does nothing
#ifndef __DEBUG_H__
# define __DEBUG_H__
# ifdef _DEBUG
# include <QDebug>
# define DBGOUT(a) qDebug () << QString(__FILE__ ":%1").arg(__LINE__) << "[" << __func__ << "] -" << a
# else
# define DBGOUT(a)
# endif
#endif

35
lib/lib.pro Normal file
View file

@ -0,0 +1,35 @@
TEMPLATE = lib
CONFIG += static
include (../config.pri)
SOURCES += xclient.cpp \
xclientcache.cpp \
playlistmodel.cpp \
xmmsqt4.cpp
HEADERS += xclient.h \
xclientcache.h \
playlistmodel.h \
xmmsqt4.h \
debug.h
;RESOURCES = promoe.qrc
;macx:RC_FILE = promoe.icns
;macx:INCLUDEPATH = /sw/include
QT += network
;macx:QTPLUGIN += qjpeg
QMAKE_LFLAGS += -L$$[QT_INSTALL_PLUGINS]/imageformats
CONFIG += link_pkgconfig
QMAKE_CXXFLAGS += -g
;CONFIG += debug warn_on
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter
PKGCONFIG += xmms2-client xmms2-client-cpp
;CONFIG += avahi

516
lib/playlistmodel.cpp Normal file
View file

@ -0,0 +1,516 @@
/**
* This file is a part of Esperanza, an XMMS2 Client.
*
* Copyright (C) 2005-2007 XMMS2 Team
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <xmmsclient/xmmsclient++.h>
#include <QAbstractTableModel>
#include <QHash>
#include <QVariant>
#include <QMimeData>
#include <QSettings>
#include <QUrl>
#include <QFileInfo>
#include "playlistmodel.h"
PlaylistModel::PlaylistModel (QObject *parent, XClient *client, const QString &name) : QAbstractItemModel (parent)
{
// m_columns.append ("#");
m_columns.append ("Artist");
m_columns.append ("Title");
// m_colfallback.append ("");
m_colfallback.append ("");
m_colfallback.append ("url");
m_cached_size.append (QSize ());
m_cached_size.append (QSize ());
m_cached_size.append (QSize ());
connect (client, SIGNAL(gotConnection (XClient *)), this, SLOT (got_connection (XClient *)));
connect (client->cache (), SIGNAL(entryChanged (uint32_t)), this, SLOT (entry_changed (uint32_t)));
if (name == QLatin1String ("_active")) {
m_isactive = true;
}
m_name = name;
if (client->isConnected ()) {
got_connection (client);
}
}
void
PlaylistModel::set_playlist (const QString &name)
{
if (name == QLatin1String ("_active")) {
m_isactive = true;
m_client->playlist ()->currentActive () (Xmms::bind (&PlaylistModel::handle_current_pls, this));
} else {
m_isactive = false;
}
m_name = name;
m_client->playlist ()->listEntries (XClient::qToStd (name)) (Xmms::bind (&PlaylistModel::handle_list, this));
}
bool
PlaylistModel::handle_current_pls (const std::string &name)
{
if (m_name == QLatin1String ("_active")) {
m_name = XClient::stdToQ (name);
}
return true;
}
void
PlaylistModel::got_connection (XClient *client)
{
if (m_isactive) {
client->playlist ()->currentActive () (Xmms::bind (&PlaylistModel::handle_current_pls, this));
}
client->playlist ()->listEntries (XClient::qToStd (m_name)) (Xmms::bind (&PlaylistModel::handle_list, this));
client->playlist ()->currentPos () (Xmms::bind (&PlaylistModel::handle_update_pos, this));
client->playlist ()->broadcastChanged () (Xmms::bind (&PlaylistModel::handle_change, this));
client->playlist ()->broadcastCurrentPos () (Xmms::bind (&PlaylistModel::handle_update_pos, this));
client->playlist ()->broadcastLoaded () (Xmms::bind (&PlaylistModel::handle_pls_loaded, this));
m_client = client;
}
bool
PlaylistModel::handle_pls_loaded (const std::string &name)
{
if (m_isactive) {
m_client->playlist ()->listEntries (name)
(Xmms::bind (&PlaylistModel::handle_list, this));
m_name = XClient::stdToQ (name);
}
return true;
}
bool
PlaylistModel::handle_update_pos (const uint32_t &pos)
{
m_current_pos = pos;
emit dataChanged(index (pos, 0), index (pos, m_columns.size ()));
return true;
}
QList<QString>
PlaylistModel::columns () const
{
return m_columns;
}
void
PlaylistModel::setColumns (const QList<QString> &new_columns)
{
m_columns = new_columns;
reset ();
}
void
PlaylistModel::setColumnFallback (const QList<QString> &new_columns)
{
m_colfallback = new_columns;
reset ();
}
bool
PlaylistModel::handle_change (const Xmms::Dict &chg)
{
int32_t change = chg.get<int32_t> ("type");
int32_t pos = 0, npos = 0;
uint32_t id = 0;
QString s;
if (chg.contains ("position")) {
pos = chg.get<int32_t> ("position");
}
if (chg.contains ("id")) {
id = chg.get<uint32_t> ("id");
}
if (chg.contains ("name")) {
s = XClient::stdToQ (chg.get<std::string> ("name"));
}
if (s != m_name) {
return true;
}
QModelIndex idx = QModelIndex ();
switch (change) {
case XMMS_PLAYLIST_CHANGED_ADD:
beginInsertRows (idx, pos, pos);
m_plist.append (id);
endInsertRows ();
break;
case XMMS_PLAYLIST_CHANGED_INSERT:
beginInsertRows (idx, pos, pos);
m_plist.insert (pos, id);
endInsertRows ();
break;
case XMMS_PLAYLIST_CHANGED_MOVE:
npos = chg.get<int32_t> ("newposition");
beginRemoveRows (idx, pos, pos);
m_plist.removeAt (pos);
endRemoveRows ();
beginInsertRows (idx, npos, npos);
m_plist.insert (npos, id);
endInsertRows ();
if (pos < npos && pos)
pos --;
emit entryMoved (index (pos, 0), index (npos, 0));
break;
case XMMS_PLAYLIST_CHANGED_REMOVE:
m_client->cache ()->invalidate (m_plist[pos]);
beginRemoveRows (idx, pos, pos);
m_plist.removeAt (pos);
endRemoveRows ();
break;
case XMMS_PLAYLIST_CHANGED_SHUFFLE:
case XMMS_PLAYLIST_CHANGED_SORT:
case XMMS_PLAYLIST_CHANGED_CLEAR:
m_client->cache ()->invalidate_all ();
m_client->playlist ()->listEntries () (Xmms::bind (&PlaylistModel::handle_list, this));
break;
}
return true;
}
bool
PlaylistModel::handle_list (const Xmms::List< unsigned int > &list)
{
beginRemoveRows (QModelIndex (), 0, m_plist.size ());
m_plist.clear ();
endRemoveRows ();
int i = 0;
for (list.first (); list.isValid (); ++list) {
i ++;
}
beginInsertRows (QModelIndex (), 0, i);
for (list.first (); list.isValid (); ++list) {
m_plist.append (*list);
}
endInsertRows ();
return true;
}
QModelIndexList
PlaylistModel::get_idxlist_by_id (uint32_t id)
{
QModelIndexList ret;
QList<uint32_t> l = getPosById (id);
for (int i = 0; i < l.count (); i++) {
ret.append (index (l.at (i), 0));
}
return ret;
}
QList<uint32_t>
PlaylistModel::getPosById (uint32_t id)
{
QList<uint32_t> ret;
int32_t pos = m_plist.indexOf (id);
while (pos != -1) {
ret.append (pos);
pos = m_plist.indexOf (id, pos + 1);
}
return ret;
}
void
PlaylistModel::entry_changed (uint32_t id)
{
QList<uint32_t> pos = getPosById (id);
for (int i = 0; i < pos.size (); i ++) {
QModelIndex idx1 = index (pos.at (i), 0);
QModelIndex idx2 = index (pos.at (i), m_columns.size ());
emit dataChanged(idx1, idx2);
}
}
int
PlaylistModel::columnCount (const QModelIndex &parent) const
{
return m_columns.size ();
}
int
PlaylistModel::rowCount (const QModelIndex &parent) const
{
if (!parent.isValid ()) {
return m_plist.size ();
}
return 0;
}
QModelIndex
PlaylistModel::parent (const QModelIndex &idx) const
{
return QModelIndex ();
}
QModelIndex
PlaylistModel::index (int row, int column, const QModelIndex &parent) const
{
if (!parent.isValid ()) {
if (row > (m_plist.size () - 1))
return QModelIndex ();
if (row < 0)
return QModelIndex ();
return createIndex (row, column, -1);
}
return QModelIndex ();
}
QVariant
PlaylistModel::data (const QModelIndex &index, int role) const
{
if (!index.isValid ()) {
return QVariant ();
}
if (index.row () >= m_plist.size ()) {
return QVariant ();
}
if (role == MedialibIdRole) {
return QVariant (m_plist[index.row ()]);
}
if (role == Qt::SizeHintRole) {
if (m_cached_size[index.column ()].isValid ()) {
return QVariant (m_cached_size[index.column ()]);
}
return QVariant ();
}
if (role == Qt::DisplayRole || role == Qt::ToolTipRole) {
QString key = m_columns[index.column ()].toLower ();
QString fallkey = m_colfallback[index.column ()].toLower ();
if (key == "#") {
return QVariant (index.row ());
} else {
unsigned int id = m_plist[index.row ()];
PlaylistModel *fake = const_cast<PlaylistModel*> (this);
QHash<QString, QVariant> d = fake->m_client->cache ()->get_info (id);
if (d.contains (key)) {
return QVariant (d[key]);
} else if (d.contains (fallkey)) {
return QVariant (d[fallkey]);
}
return QVariant ();
}
} else if (role == CurrentEntryRole) {
int i = m_current_pos;
if (index.row () == i)
return QVariant (true);
return QVariant (false);
}
return QVariant ();
}
QStringList
PlaylistModel::mimeTypes () const
{
QStringList l ("application/x-xmms2poslist");
l << "application/x-xmms2mlibid";
l << "text/uri-list";
return l;
}
QMimeData *
PlaylistModel::mimeData (const QModelIndexList &list) const
{
QMimeData *ret = new QMimeData ();
QByteArray ba;
QDataStream stream (&ba, QIODevice::WriteOnly);
QList<int> l;
for (int i = 0; i < list.size (); i ++) {
QModelIndex idx = list.at (i);
if (idx.column () != 0)
continue;
l.append (idx.row ());
}
stream << l;
ret->setData ("application/x-xmms2poslist", ba);
return ret;
}
bool
PlaylistModel::dropMimeData (const QMimeData *data,
Qt::DropAction action,
int row, int column,
const QModelIndex & parent)
{
if (parent.internalId () != -1 && parent.isValid ()) {
return false;
}
if (data->hasFormat ("application/x-xmms2poslist")) {
if (!parent.isValid ())
return false;
QByteArray ba = data->data ("application/x-xmms2poslist");
QDataStream stream (&ba, QIODevice::ReadOnly);
QList<int> l;
stream >> l;
qSort (l);
int target = parent.row ();
int mod = 0;
while (l.size ()) {
int orow = l.takeAt (0) - mod;
m_client->playlist ()->moveEntry (orow, target) ();
if (orow < target) {
mod ++;
} else {
target ++;
}
}
return true;
} else if (data->hasFormat ("application/x-xmms2mlibid")) {
QByteArray ba = data->data ("application/x-xmms2mlibid");
QDataStream stream (&ba, QIODevice::ReadOnly);
QList<int> l;
stream >> l;
int target;
if (parent.isValid ())
target = parent.row () + 1;
else
target = m_plist.size () + 1;
while (l.size ()) {
int id = l.takeAt (0);
if (target >= m_plist.size ()) {
m_client->playlist ()->addId (id) ();
} else {
m_client->playlist ()->insertId (target ++, id) ();
}
}
return true;
} else if (data->hasFormat ("text/uri-list")) {
int target;
if (parent.isValid ())
target = parent.row () + 1;
else
target = m_plist.size () + 1;
QList<QUrl> l = data->urls ();
qSort (l);
for (int i = 0; i < l.size (); i++) {
QFileInfo fi (l.at (i).toLocalFile ());
std::string s ("file:///");
s.append (fi.absoluteFilePath ().toLocal8Bit ());
if (fi.isFile ()) {
if (target >= m_plist.size ()) {
m_client->playlist ()->addUrl (s) ();
} else {
m_client->playlist ()->insertUrl (target ++, s) ();
}
} else if (fi.isDir ()) {
m_client->playlist ()->addRecursive (s) ();
}
}
return true;
}
return false;
}
Qt::DropActions
PlaylistModel::supportedDropActions () const
{
return Qt::CopyAction | Qt::MoveAction;
}
QVariant
PlaylistModel::headerData (int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole) {
return QVariant ();
}
if (orientation == Qt::Horizontal) {
if (section <= m_columns.size ())
return QVariant (m_columns[section]);
}
return QVariant ();
}
Qt::ItemFlags
PlaylistModel::flags (const QModelIndex &idx) const
{
unsigned int id = m_plist[idx.row ()];
PlaylistModel *fake = const_cast<PlaylistModel*> (this);
QHash<QString, QVariant> d = fake->m_client->cache ()->get_info (id);
Qt::ItemFlags f = Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
if (idx.isValid ()) {
f |= Qt::ItemIsDropEnabled;
}
if (d.contains ("status") && d["status"] != XMMS_MEDIALIB_ENTRY_STATUS_NOT_AVAILABLE) {
f |= Qt::ItemIsEnabled;
}
return f;
}
QList<uint32_t>
PlaylistModel::get_all_id ()
{
return m_plist;
}

147
lib/playlistmodel.h Normal file
View file

@ -0,0 +1,147 @@
/**
* This file is a part of Esperanza, an XMMS2 Client.
*
* Copyright (C) 2005-2007 XMMS2 Team
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __PLAYLIST_MODEL_H__
#define __PLAYLIST_MODEL_H__
#include <xmmsclient/xmmsclient++.h>
#include <QAbstractTableModel>
#include <QVariant>
#include <QHash>
#include <QIcon>
#include "xclient.h"
/**
* @class PlaylistModel playlistmodel.h
* @brief A model that represents a playlist on the server
*
* This model will show the playlist and update it according to the
* changes from the server. This can be subclassed to be customized.
**/
class PlaylistModel : public QAbstractItemModel
{
Q_OBJECT
public:
/**
* The constructor for the PlaylistModel.
* @param parent The parent QObject for this model
* @param client The XClient object to be used in order to get the updates
* @param n The name of the playlist that this model should show
**/
PlaylistModel (QObject *parent, XClient *client, const QString &n = "_active");
enum {
DisplayRole = Qt::DisplayRole,
ToolTipRole = Qt::ToolTipRole,
CurrentEntryRole = 200,
MedialibIdRole,
AvailableRole
};
int rowCount (const QModelIndex &parent) const;
int columnCount (const QModelIndex &parent) const;
QVariant data (const QModelIndex &index, int role = DisplayRole) const;
QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
Qt::ItemFlags flags (const QModelIndex &) const;
QModelIndex parent (const QModelIndex &) const;
QModelIndex index (int row, int column, const QModelIndex &idx = QModelIndex ()) const;
QMimeData *mimeData (const QModelIndexList &list) const;
bool dropMimeData (const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent);
Qt::DropActions supportedDropActions () const;
QStringList mimeTypes () const;
/**
* Set the columns that should be shown in the view.
* @param columns A list of property keys. i.e. "artist", "album"
**/
void setColumns (const QList <QString> &columns);
/**
* Set fallback columns. A fallback column is what should be shown
* if the first column is not available for that entry.
* @param columns A list of property keys.
**/
void setColumnFallback (const QList <QString> &columns);
/**
* Return the current columns.
**/
QList<QString> columns () const;
/**
* Return a list of all entry ids that are currently in the list.
**/
QList<uint32_t> get_all_id ();
void set_cached_size (int i, const QSize &size) {
m_cached_size[i] = size;
};
QSize cached_size (int i) const {
return m_cached_size[i];
};
/**
* Return a list of QModelIndex for the entry. Since one
* entry can be in the Playlist multiple times we need to
* return a list of indexes.
* @
**/
QModelIndexList get_idxlist_by_id (uint32_t);
QModelIndex current_playlist_pos () const {
return index (m_current_pos, 0);
};
void set_playlist (const QString &);
protected:
XClient *m_client;
QList < unsigned int > m_plist;
QList < uint32_t > getPosById (uint32_t id);
QList < QString > m_columns;
QList < QString > m_colfallback;
signals:
void entryMoved (const QModelIndex &, const QModelIndex &);
public slots:
void got_connection (XClient *);
void entry_changed (uint32_t);
private:
bool handle_list (const Xmms::List< unsigned int > &list);
bool handle_change (const Xmms::Dict &chg);
bool handle_update_pos (const unsigned int &pos);
bool handle_pls_loaded (const std::string &);
bool handle_current_pls (const std::string &);
void getInfo (unsigned int id) const;
uint32_t m_current_pos;
bool m_isactive;
QList<QSize> m_cached_size;
QString m_name;
};
#endif

210
lib/xclient.cpp Normal file
View file

@ -0,0 +1,210 @@
/**
* This file is a part of Esperanza, an XMMS2 Client.
*
* Copyright (C) 2005-2007 XMMS2 Team
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <xmmsclient/xmmsclient++.h>
#include <QObject>
#include <QHash>
#include <QVariant>
#include <QErrorMessage>
#include <QSettings>
#include "xclient.h"
#include "xmmsqt4.h"
#include "debug.h"
XSettings::XSettings (QObject *parent) : QObject (parent)
{
/* dummy */
}
void
XSettings::change_settings ()
{
emit settingsChanged ();
}
QString
XClient::stdToQ (const std::string &str)
{
return QString::fromUtf8 (str.c_str ());
}
std::string
XClient::qToStd (const QString &str)
{
return std::string (str.toUtf8 ().data ());
}
QDir
XClient::esperanza_dir ()
{
QDir c (stdToQ (Xmms::getUserConfDir ()));
if (!c.cd ("clients/Esperanza")) {
c.mkpath ("clients/Esperanza");
if (!c.cd ("clients/Esperanza")) {
qDebug ("couldn't open dir");
}
return c;
} else {
return c;
}
return QDir ();
}
XClient::XClient (QObject *parent, const std::string &name) : QObject (parent), m_sync (name + "-sync")
{
m_client = NULL;
m_isconnected = false;
m_cache = new XClientCache (this, this);
m_settings = new XSettings (this);
m_name = name;
}
void XClient::disconnect ()
{
delete m_client;
m_client = NULL;
m_isconnected = false;
}
bool
XClient::connect (const char *ipcpath, const bool &sync, QWidget *parent)
{
bool tried_once = false;
try_again:
try {
delete m_client;
m_client = new Xmms::Client (m_name);
if (!ipcpath || ipcpath == "")
m_client->connect (NULL);
else
m_client->connect (ipcpath);
}
catch (Xmms::connection_error& e) {
if (ipcpath == NULL && !tried_once) {
QSettings s;
if (s.value ("core/autostart", true).toBool ()) {
if (!system ("xmms2-launcher")) {
tried_once = true;
goto try_again;
}
}
}
QErrorMessage *err = new QErrorMessage (parent);
err->showMessage ("Couldn't connect to XMMS2, please try again.");
err->exec ();
delete err;
return false;
}
m_client->setMainloop (new XmmsQT4 (m_client->getConnection ()));
if (sync) {
try {
m_sync.connect (ipcpath);
}
catch (Xmms::connection_error &e) {
qWarning ("Couldn't establish sync connection!");
}
}
m_isconnected = true;
emit gotConnection (this);
return true;
}
void
XClient::dictToQHash (const std::string &key,
const Xmms::Dict::Variant &value,
QHash<QString, QVariant> &hash)
{
if (value.type () == typeid (int32_t)) {
hash.insert (QString::fromLatin1 (key.c_str ()),
QVariant (boost::get< int32_t > (value)));
} else if (value.type () == typeid (uint32_t)) {
hash.insert (QString::fromLatin1 (key.c_str ()),
QVariant (boost::get< uint32_t > (value)));
} else {
QString val;
val = QString::fromUtf8 (boost::get< std::string > (value).c_str ());
hash.insert (stdToQ (key), QVariant (val));
}
}
/**
* convert a Xmms::Dict to a QHash<QString, QVariant>
**/
QHash<QString, QVariant>
XClient::convert_dict (const Xmms::Dict &dict)
{
QHash<QString, QVariant> hash;
dict.each (boost::bind (&XClient::dictToQHash,
_1, _2, boost::ref (hash)));
return hash;
}
void
XClient::propDictToQHash (const std::string &key,
const Xmms::Dict::Variant &value,
const std::string &source,
QHash<QString, QVariant> &hash)
{
if (value.type () == typeid (int32_t)) {
hash.insert (QString::fromLatin1 (key.c_str ()),
QVariant (boost::get< int32_t > (value)));
} else if (value.type () == typeid (uint32_t)) {
hash.insert (QString::fromLatin1 (key.c_str ()),
QVariant (boost::get< uint32_t > (value)));
} else {
QString val;
if (key == "url") {
/* This really is wrong ...*/
char *c = const_cast<char *>(xmmsc_result_decode_url (NULL, boost::get< std::string >(value).c_str ()));
val = QString::fromUtf8 (c);
val = val.mid (val.lastIndexOf ("/") + 1);
if (val.isEmpty ()) {
val = QString::fromUtf8 (c);
}
free (c);
} else {
val = QString::fromUtf8 (boost::get< std::string > (value).c_str ());
}
hash.insert (stdToQ (key), QVariant (val));
}
}
/**
* convert a Xmms::PropDict to a QHash<QString, QVariant>
**/
QHash<QString, QVariant>
XClient::convert_propdict (const Xmms::PropDict &dict)
{
QHash<QString, QVariant> hash;
dict.each (boost::bind (&XClient::propDictToQHash,
_1, _2, _3, boost::ref (hash)));
return hash;
}

110
lib/xclient.h Normal file
View file

@ -0,0 +1,110 @@
/**
* This file is a part of Esperanza, an XMMS2 Client.
*
* Copyright (C) 2005-2007 XMMS2 Team
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __XCLIENT_H__
#define __XCLIENT_H__
#include <xmmsclient/xmmsclient++.h>
class XClient;
#include <QObject>
#include <QHash>
#include <QVariant>
#include <QDir>
#include <QWidget>
#include "xclientcache.h"
class XSettings : public QObject
{
Q_OBJECT
public:
XSettings (QObject *);
void change_settings ();
signals:
void settingsChanged ();
};
class XClient : public QObject {
Q_OBJECT
public:
XClient (QObject *, const std::string &);
void disconnect ();
bool connect (const char *path = NULL, const bool &sync = false, QWidget* parent = NULL);
static void propDictToQHash (const std::string &key,
const Xmms::Dict::Variant &value,
const std::string &source,
QHash<QString, QVariant> &hash);
static void dictToQHash (const std::string &key,
const Xmms::Dict::Variant &value,
QHash<QString, QVariant> &hash);
static QHash<QString, QVariant> convert_propdict (const Xmms::PropDict &);
static QHash<QString, QVariant> convert_dict (const Xmms::Dict &);
XClientCache *cache () const {
return m_cache;
};
XSettings *settings () const {
return m_settings;
};
const Xmms::Client *sync () const {
return &m_sync;
};
static QString stdToQ (const std::string &);
static std::string qToStd (const QString &);
bool isConnected () const {
return m_isconnected;
};
static QDir esperanza_dir ();
void setDisconnectCallback (const Xmms::DisconnectCallback::slot_type &slot) { m_client->setDisconnectCallback (slot); }
const Xmms::Collection* collection () { if (m_client && m_client->isConnected ()) return &m_client->collection; else return NULL; }
const Xmms::Playlist* playlist () { if (m_client && m_client->isConnected ()) return &m_client->playlist; else return NULL; }
const Xmms::Playback* playback () { if (m_client && m_client->isConnected ()) return &m_client->playback; else return NULL; }
const Xmms::Medialib* medialib () { if (m_client && m_client->isConnected ()) return &m_client->medialib; else return NULL; }
const Xmms::Bindata* bindata () { if (m_client && m_client->isConnected ()) return &m_client->bindata; else return NULL; }
const Xmms::Config* config () { if (m_client && m_client->isConnected ()) return &m_client->config; else return NULL; }
const Xmms::Stats* stats () { if (m_client && m_client->isConnected ()) return &m_client->stats; else return NULL; }
signals:
void gotConnection (XClient *);
protected:
Xmms::Client *m_client;
private:
std::string m_name;
// Xmms::Client *m_client;
XClientCache *m_cache;
XSettings *m_settings;
bool m_isconnected;
Xmms::Client m_sync;
};
#endif

167
lib/xclientcache.cpp Normal file
View file

@ -0,0 +1,167 @@
/**
* This file is a part of Esperanza, an XMMS2 Client.
*
* Copyright (C) 2005-2007 XMMS2 Team
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "xclientcache.h"
#include <QObject>
#include <QIcon>
#include <QPixmap>
#include <QHash>
#include <QList>
#include <QVariant>
#include <QPixmapCache>
#include <QSettings>
XClientCache::XClientCache (QObject *parent, XClient *client) : QObject (parent)
{
QSettings s;
connect (client, SIGNAL (gotConnection (XClient *)), this, SLOT (got_connection (XClient *)));
QPixmapCache::setCacheLimit (s.value ("core/pixmapcache").toInt ());
}
void
XClientCache::got_connection (XClient *client)
{
m_client = client;
client->playback ()->signalPlaytime () (Xmms::bind (&XClientCache::handle_playtime, this));
client->playback ()->getPlaytime () (Xmms::bind (&XClientCache::handle_playtime, this));
client->medialib ()->broadcastEntryChanged () (Xmms::bind (&XClientCache::handle_mlib_entry_changed, this));
}
bool
XClientCache::handle_medialib_info_error (const std::string &error, uint32_t id)
{
/* we probably couldn't find that entry, let's remove it */
m_info.remove (id);
emit entryRemoved (id);
return true;
}
bool
XClientCache::handle_medialib_info (const Xmms::PropDict &info)
{
int32_t id = info.get<int32_t> ("id");
QHash<QString, QVariant> hash = XClient::convert_propdict (info);
m_info.insert (id, hash);
emit entryChanged (id);
return true;
}
void
XClientCache::extra_info_set (uint32_t id, const QString &name,
const QVariant &value)
{
m_extra_info[id][name] = value;
}
QVariant
XClientCache::extra_info_get (uint32_t id, const QString &name)
{
return m_extra_info[id][name];
}
void
XClientCache::invalidate (uint32_t id)
{
m_info.remove (id);
}
void
XClientCache::invalidate_all ()
{
m_info.clear ();
}
bool
XClientCache::handle_bindata (const Xmms::bin &data, const QString &id)
{
QPixmap i;
i.loadFromData (data.c_str (), data.size());
if (i.isNull ()) {
return true;
}
/* conserve memory client side */
if (i.width () < 300) {
i = i.scaledToWidth (300, Qt::SmoothTransformation);
}
QPixmapCache::insert (id, i);
QList<uint32_t> ids = m_icon_map[id];
for (int i = 0; i < ids.size (); i++) {
emit entryChanged (ids.at (i));
}
return true;
}
QIcon
XClientCache::get_icon (uint32_t id)
{
return QIcon (get_pixmap (id));
}
QPixmap
XClientCache::get_pixmap (uint32_t id)
{
if (m_info[id].contains ("picture_front")) {
QString hash = m_info[id]["picture_front"].toString ();
QPixmap p;
if (!QPixmapCache::find (hash, p)) {
m_client->bindata ()->retrieve (hash.toStdString ()) (
boost::bind (&XClientCache::handle_bindata, this, _1, hash));
QPixmapCache::insert (hash, QPixmap ());
m_icon_map[hash].append (id);
}
return p;
}
return QPixmap ();
}
QHash<QString, QVariant>
XClientCache::get_info (uint32_t id)
{
if (!m_info.contains (id)) {
m_client->medialib ()->getInfo (id) (Xmms::bind (&XClientCache::handle_medialib_info, this),
boost::bind (&XClientCache::handle_medialib_info_error, this, _1, id));
m_info[id] = QHash<QString, QVariant> ();
}
return m_info[id];
}
bool
XClientCache::handle_mlib_entry_changed (const uint32_t &id)
{
m_client->medialib ()->getInfo (id) (Xmms::bind (&XClientCache::handle_medialib_info, this));
return true;
}
bool
XClientCache::handle_playtime (const unsigned int &tme)
{
emit playtime(tme);
return true;
}

80
lib/xclientcache.h Normal file
View file

@ -0,0 +1,80 @@
/**
* This file is a part of Esperanza, an XMMS2 Client.
*
* Copyright (C) 2005-2007 XMMS2 Team
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __XCLIENTCACHE_H__
#define __XCLIENTCACHE_H__
class XClientCache;
#include "xclient.h"
#include <QObject>
#include <QIcon>
#include <QPixmap>
#include <QHash>
#include <QList>
#include <QVariant>
#include <QPixmapCache>
class XClientCache : public QObject
{
Q_OBJECT
public:
XClientCache (QObject *, XClient *);
QHash<QString, QVariant> get_info (uint32_t id);
QIcon get_icon (uint32_t id);
QPixmap get_pixmap (uint32_t id);
QVariant extra_info_get (uint32_t, const QString &);
void extra_info_set (uint32_t, const QString &, const QVariant &);
void invalidate (uint32_t);
void invalidate_all ();
bool extra_info_has (uint32_t id, const QString &s) {
if (m_extra_info.contains (id))
if (m_extra_info[id].contains (s))
return true;
return false;
};
signals:
void entryChanged (uint32_t);
void entryRemoved (uint32_t);
void playtime (uint32_t);
public slots:
void got_connection (XClient *);
private:
bool handle_medialib_info (const Xmms::PropDict &info);
bool handle_medialib_info_error (const std::string &, uint32_t);
bool handle_mlib_entry_changed (const uint32_t &id);
bool handle_bindata (const Xmms::bin &, const QString &);
bool handle_playtime (const unsigned int &tme);
QHash< uint32_t, QHash<QString, QVariant> > m_info;
QHash < QString, QList <uint32_t> > m_icon_map;
QHash < int, QHash < QString, QVariant > > m_extra_info;
XClient *m_client;
};
#endif

View file

@ -1,6 +1,23 @@
/**
* This file is a part of Esperanza, an XMMS2 Client.
*
* Copyright (C) 2005-2007 XMMS2 Team
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <xmmsclient/xmmsclient++/mainloop.h> #include <xmmsclient/xmmsclient++/mainloop.h>
#include <xmmsclient/xmmsclient.h> #include <xmmsclient/xmmsclient.h>
#include "XmmsQT4.h" #include "xmmsqt4.h"
#include <QApplication> #include <QApplication>
#include <QObject> #include <QObject>

50
lib/xmmsqt4.h Normal file
View file

@ -0,0 +1,50 @@
/**
* This file is a part of Esperanza, an XMMS2 Client.
*
* Copyright (C) 2005-2007 XMMS2 Team
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __XMMSQT4_H__
#define __XMMSQT4_H__
#include <xmmsclient/xmmsclient++/mainloop.h>
#include <QApplication>
#include <QObject>
#include <QSocketNotifier>
class XmmsQT4 : public QObject, public Xmms::MainloopInterface
{
Q_OBJECT
public:
XmmsQT4(xmmsc_connection_t *xmmsc);
~XmmsQT4();
void run ();
void ToggleWrite(bool toggle);
xmmsc_connection_t *GetXmmsConnection();
public slots:
void OnRead ();
void OnWrite ();
private:
int m_fd;
QSocketNotifier *m_rsock;
QSocketNotifier *m_wsock;
xmmsc_connection_t *m_xmmsc;
};
#endif

View file

@ -1,82 +1,4 @@
SOURCES += XmmsQT4.cpp \ TEMPLATE = subdirs
PixWidget.cpp \ CONFIG += ordered
Skin.cpp \ SUBDIRS = lib src
MainWindow.cpp \
Display.cpp \
MainDisplay.cpp \
TitleBar.cpp \
Button.cpp \
TextBar.cpp \
NumberDisplay.cpp \
TimeDisplay.cpp \
XMMSHandler.cpp \
SmallNumberDisplay.cpp \
StereoMono.cpp \
PosBar.cpp \
PlayStatus.cpp \
ShadedDisplay.cpp \
Playlist.cpp \
PlaylistList.cpp \
SkinChooser.cpp \
PlaylistShade.cpp \
qtmd5.cpp \
SettingsWindow.cpp \
PlaylistMenu.cpp \
VolumeSlider.cpp \
ClutterBar.cpp \
Equalizer.cpp \
FileDialog.cpp \
BrowseModel.cpp \
BrowseDialog.cpp
HEADERS += XmmsQT4.h \
PixWidget.h \
Skin.h \
MainWindow.h \
Display.h \
MainDisplay.h \
TitleBar.h \
Button.h \
TextBar.h \
NumberDisplay.h \
TimeDisplay.h \
XMMSHandler.h \
SmallNumberDisplay.h \
StereoMono.h \
PosBar.h \
PlayStatus.h \
ShadedDisplay.h \
Playlist.h \
PlaylistList.h \
SkinChooser.h \
PlaylistShade.h \
qtmd5.h \
SettingsWindow.h \
PlaylistMenu.h \
VolumeSlider.h \
ClutterBar.h \
Equalizer.h \
FileDialog.h \
BrowseModel.h \
BrowseDialog.h
RESOURCES = promoe.qrc
macx:RC_FILE = promoe.icns
macx:INCLUDEPATH = /sw/include
QT += network
;macx:QTPLUGIN += qjpeg
QMAKE_LFLAGS += -L$$[QT_INSTALL_PLUGINS]/imageformats
CONFIG += link_pkgconfig
QMAKE_CXXFLAGS += -g
;CONFIG += debug warn_on
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter
PKGCONFIG += xmms2-client xmms2-client-cpp
;CONFIG += avahi

View file

@ -36,8 +36,7 @@ void
BrowseModel::setPath (const QModelIndex &index) BrowseModel::setPath (const QModelIndex &index)
{ {
BrowseModelItem *item = m_list.at (index.row ()); BrowseModelItem *item = m_list.at (index.row ());
m_client->xform.browse (item->data("path").toStdString (), m_client->xform.browse (item->data("path").toStdString ()) (Xmms::bind (&BrowseModel::list_cb, this));
Xmms::bind (&BrowseModel::list_cb, this));
m_current_dir = item->data ("path"); m_current_dir = item->data ("path");
} }
@ -47,7 +46,7 @@ BrowseModel::setPath (const QString &path)
if (path.isEmpty()) if (path.isEmpty())
list_root (); list_root ();
m_client->xform.browse (path.toStdString (), m_client->xform.browse (path.toStdString ())(
Xmms::bind (&BrowseModel::list_cb, this), Xmms::bind (&BrowseModel::list_cb, this),
Xmms::bind (&BrowseModel::list_err, this)); Xmms::bind (&BrowseModel::list_err, this));
m_current_dir = path; m_current_dir = path;

View file

@ -72,8 +72,10 @@ MainDisplay::MainDisplay (QWidget *parent) : SkinDisplay(parent)
this, SLOT(setMediainfo (const Xmms::PropDict &))); this, SLOT(setMediainfo (const Xmms::PropDict &)));
connect (&xmmsh, SIGNAL(playbackStatusChanged(Xmms::Playback::Status)), connect (&xmmsh, SIGNAL(playbackStatusChanged(Xmms::Playback::Status)),
this, SLOT(setStatus(Xmms::Playback::Status))); this, SLOT(setStatus(Xmms::Playback::Status)));
connect (&xmmsh, SIGNAL(playtimeChanged(uint)), // connect (&xmmsh, SIGNAL(playtimeChanged(uint)),
this, SLOT(setPlaytime(uint))); // this, SLOT(setPlaytime(uint)));
connect (xmmsh.cache () , SIGNAL (playtime (uint32_t)),
this, SLOT (setPlaytime (uint32_t)));
connect (&xmmsh, SIGNAL(getVolume(uint)), this, SLOT(updateVolume(uint))); connect (&xmmsh, SIGNAL(getVolume(uint)), this, SLOT(updateVolume(uint)));
connect (m_vslider, SIGNAL(valueChanged(int)), this, SLOT(setVolume(int))); connect (m_vslider, SIGNAL(valueChanged(int)), this, SLOT(setVolume(int)));
xmmsh.volumeGet(); xmmsh.volumeGet();
@ -113,8 +115,7 @@ void
MainDisplay::setPixmaps (Skin *skin) MainDisplay::setPixmaps (Skin *skin)
{ {
QPalette palette = QPalette(); QPalette palette = QPalette();
QBrush brush = QBrush(Qt::TexturePattern); QBrush brush = QBrush(skin->getItem(Skin::MAIN_WINDOW));
brush.setTexture(skin->getItem(Skin::MAIN_WINDOW));
palette.setBrush(QPalette::Background, brush); palette.setBrush(QPalette::Background, brush);
setPalette(palette); setPalette(palette);
@ -133,9 +134,9 @@ MainDisplay::setStatus (Xmms::Playback::Status status)
} }
void void
MainDisplay::setPlaytime (uint time) MainDisplay::setPlaytime (uint32_t time)
{ {
uint showtime; uint32_t showtime;
if (m_mw->isTimemodeReverse()) { if (m_mw->isTimemodeReverse()) {
uint maxtime = m_posbar->getMax(); uint maxtime = m_posbar->getMax();
showtime = -(maxtime - time); showtime = -(maxtime - time);

View file

@ -70,7 +70,7 @@ class MainDisplay : public SkinDisplay
public slots: public slots:
void setPixmaps(Skin *skin); void setPixmaps(Skin *skin);
void setStatus (Xmms::Playback::Status status); void setStatus (Xmms::Playback::Status status);
void setPlaytime (uint time); void setPlaytime (uint32_t time);
void setMediainfo (const Xmms::PropDict &); void setMediainfo (const Xmms::PropDict &);
void togglePL(void); void togglePL(void);
void toggleEQ(void); void toggleEQ(void);

View file

@ -14,7 +14,7 @@ class MainWindow;
#include <QHash> #include <QHash>
#include <QSettings> #include <QSettings>
#include "XmmsQT4.h" #include "xmmsqt4.h"
/* /*
#include "Skin.h" #include "Skin.h"

View file

@ -1,7 +1,6 @@
#ifndef __MEDIALIBVIEW_H__ #ifndef __MEDIALIBVIEW_H__
#define __MEDIALIBVIEW_H__ #define __MEDIALIBVIEW_H__
#include "XMMSSocket.h"
#include <QTreeView> #include <QTreeView>
#include <QAbstractItemModel> #include <QAbstractItemModel>

View file

@ -21,8 +21,7 @@ NumberDisplay::NumberDisplay (QWidget *parent, TimeDisplay *td,uint w, uint star
void void
NumberDisplay::setPixmaps (Skin *skin) NumberDisplay::setPixmaps (Skin *skin)
{ {
QBrush b (Qt::TexturePattern); QBrush b (skin->getNumber (10));
b.setTexture (skin->getNumber (10));
QPainter paint; QPainter paint;
paint.begin (&m_pixmap); paint.begin (&m_pixmap);

View file

@ -1,7 +1,8 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "BrowseDialog.h" #include "BrowseDialog.h"
#include "Playlist.h" #include "Playlist.h"
#include "PlaylistList.h" #include "PlaylistView.h"
#include "playlistmodel.h"
#include "PlaylistShade.h" #include "PlaylistShade.h"
#include "PlaylistMenu.h" #include "PlaylistMenu.h"
@ -15,30 +16,139 @@
#include <QSettings> #include <QSettings>
#include <QFileDialog> #include <QFileDialog>
PlaylistScrollButton::PlaylistScrollButton (PlaylistScroller *parent, uint normal, uint pressed) : Button (parent, normal, pressed, true) /*
*
* PlaylistScrollBar
*
*/
PlaylistScrollBar::PlaylistScrollBar (QWidget *parent) :
QScrollBar (Qt::Vertical, parent)
{ {
m_slider = parent; Skin *skin = Skin::getInstance ();
setContextMenuPolicy(Qt::NoContextMenu);
m_pixmap = QPixmap (0, 0);
m_slider = QPixmap (0, 0);
m_slider_down = QPixmap (0, 0);
connect (skin, SIGNAL (skinChanged (Skin *)),
this, SLOT (setPixmaps(Skin *)));
} }
void void
PlaylistScrollButton::mouseMoveEvent (QMouseEvent *event) PlaylistScrollBar::mouseMoveEvent (QMouseEvent *event)
{ {
QPoint p (event->pos ()); if (!isSliderDown ())
return;
int npos = pos().y()+p.y()-m_diffy; int tmp = sliderValueFromPosition(event->y () - m_sliderOffset);
if (npos >= 0 && npos + rect().height() <= m_slider->rect().height()) { if (tmp == value())
move (0, npos); return;
} else if (npos < 0) {
move (0, 0);
npos = 0;
} else if (npos + rect().height() > m_slider->rect().height()) {
move (0, m_slider->rect().height()-rect().height());
npos = m_slider->rect().height()-rect().height();
}
m_slider->doScroll (); setValue(tmp);
//TODO only repaint necessyry range
repaint ();
} }
void
PlaylistScrollBar::mousePressEvent (QMouseEvent *event)
{
if (event->button() == Qt::RightButton) {
event->ignore();
return;
}
if (maximum () == minimum ())
return;
int sliderBase = sliderPositionFromValue();
if (event->y () < sliderBase) {
triggerAction (QAbstractSlider::SliderPageStepSub);
} else if (event->y () > sliderBase + m_slider.height ()) {
triggerAction (QAbstractSlider::SliderPageStepAdd);
} else {
m_sliderOffset = event->y () - sliderBase;
setSliderDown (true);
}
//TODO only repaint necessary range
repaint ();
}
void
PlaylistScrollBar::mouseReleaseEvent (QMouseEvent *event)
{
if (event->button() == Qt::RightButton) {
event->ignore();
return;
}
if (isSliderDown ()) {
setValue(sliderValueFromPosition(event->y () - m_sliderOffset));
setSliderDown (false);
}
//TODO only repaint necessary range
repaint ();
}
void
PlaylistScrollBar::paintEvent (QPaintEvent *event)
{
if (m_pixmap.isNull ()) {
return;
}
// TODO remove, in here for debuging
// qDebug("%i %i %i %i %i %i %i", event->rect ().x(), event->rect ().y(), event->rect ().width(), event->rect ().height(),
// minimum(), maximum (), sliderPosition ());
QPainter (paint);
paint.begin (this);
/* draw background */
paint.drawPixmap (event->rect (), m_pixmap, m_pixmap.rect ());
/* draw slider */
QPixmap *slider = isSliderDown () ? &m_slider_down : &m_slider ;
QRect rect (slider->rect ());
rect.moveTop (sliderPositionFromValue ());
paint.drawPixmap (rect , *slider, slider->rect ());
paint.end ();
}
void
PlaylistScrollBar::setPixmaps (Skin *skin)
{
m_pixmap = skin->getPls (Skin::PLS_RFILL2_0);
m_slider = skin->getPls (Skin::PLS_SCROLL_0);
m_slider_down = skin->getPls (Skin::PLS_SCROLL_1);
}
int
PlaylistScrollBar::sliderPositionFromValue ()
{
return QStyle::sliderPositionFromValue (minimum (), maximum (),
sliderPosition (),
height () - m_slider.height (),
false);
}
int
PlaylistScrollBar::sliderValueFromPosition (int position)
{
return QStyle::sliderValueFromPosition (minimum (), maximum (),
position,
height () - m_slider.height (),
false);
}
/*
* dragButton
*/
void void
dragButton::mouseMoveEvent (QMouseEvent *event) dragButton::mouseMoveEvent (QMouseEvent *event)
{ {
@ -47,68 +157,10 @@ dragButton::mouseMoveEvent (QMouseEvent *event)
pw->size().height()+(event->pos().y()-m_diffy)); pw->size().height()+(event->pos().y()-m_diffy));
} }
PlaylistScroller::PlaylistScroller (PlaylistWidget *parent) : QWidget (parent)
{
Skin *skin = Skin::getInstance ();
m_pixmap = QPixmap(0,0);
connect (skin, SIGNAL (skinChanged (Skin *)),
this, SLOT (setPixmaps(Skin *)));
m_button = new PlaylistScrollButton (this, Skin::PLS_SCROLL_0, Skin::PLS_SCROLL_1);
m_button->move (0, 0);
}
void
PlaylistScroller::setMax (uint max)
{
m_max = max;
repositionButton ();
}
uint
PlaylistScroller::getMax (void)
{
return rect().height()-m_button->rect().height();
}
uint
PlaylistScroller::getPos (void)
{
return (int)((float)(m_button->pos ().y ()) / (float)getMax() * (float)m_max);
}
void
PlaylistScroller::setPixmaps (Skin *skin)
{
m_pixmap = skin->getPls (Skin::PLS_RFILL2_0);
}
void
PlaylistScroller::repositionButton (void)
{
PlaylistWidget *pw = dynamic_cast<PlaylistWidget *>(parent ());
/* x = 182.6 / (454 - 242) * 224 */
int bpos = (int)((float)(pw->getOffset ()) / (float)m_max * (float) getMax ());
if (bpos > getMax ())
bpos = getMax ();
m_button->move (0, bpos);
}
void
PlaylistScroller::paintEvent (QPaintEvent *event)
{
if (m_pixmap.isNull ()) {
return;
}
QPainter (paint);
paint.begin (this);
paint.drawPixmap (event->rect (), m_pixmap, m_pixmap.rect ());
paint.end ();
}
/*
* PlaylistWindow
*/
PlaylistWindow::PlaylistWindow (QWidget *parent) : QMainWindow (parent) PlaylistWindow::PlaylistWindow (QWidget *parent) : QMainWindow (parent)
{ {
QSettings s; QSettings s;
@ -236,6 +288,9 @@ PlaylistWindow::leaveEvent (QEvent *event)
} }
/*
* PlaylistWidget
*/
PlaylistWidget::PlaylistWidget (QWidget *parent) : QWidget (parent) PlaylistWidget::PlaylistWidget (QWidget *parent) : QWidget (parent)
{ {
Skin *skin = Skin::getInstance (); Skin *skin = Skin::getInstance ();
@ -248,12 +303,26 @@ PlaylistWidget::PlaylistWidget (QWidget *parent) : QWidget (parent)
m_view = new PlaylistView (this); m_view = new PlaylistView (this);
m_view->move (10, 20); m_view->move (10, 20);
m_view->resize (size().width()-30, size().height()-20-38); m_view->resize (size().width()-30, size().height()-20-38);
m_view->setModel (XMMSHandler::getInstance().getPlaylistModel());
m_list = new PlaylistList (m_view); //m_list = new PlaylistList (m_view);
m_scroller = new PlaylistScroller (this); /*
connect (m_scroller, SIGNAL(scrolled(int)), this, SLOT(doScroll (int))); * This is a hack to make PlaylistScrollBar work with PlaylistView.
connect (m_list, SIGNAL(sizeChanged(QSize)), this, SLOT(sizeChangedList (QSize))); * It is necessery because of limitations and at least one Bug in the
* QT library (as of Version 4.3
* TODO: This might in a future Qt version. Try to find a better solution
*/
//m_scroller = new PlaylistScrollBar (this);
m_scrollBar = new PlaylistScrollBar (this);
m_view->setVerticalScrollBar (m_scrollBar);
m_scrollBar->setParent(this);
m_scrollBar->show();
/* Workarounds for another QT bug (at least in my opinion) */
connect (m_scrollBar, SIGNAL(actionTriggered (int)),
m_view, SLOT(verticalScrollbarAction (int)));
connect (m_scrollBar, SIGNAL(valueChanged (int)),
m_view, SLOT(verticalScrollbarValueChanged (int)));
m_drag = new dragButton (this); m_drag = new dragButton (this);
m_drag->resize (30, 30); m_drag->resize (30, 30);
@ -294,7 +363,7 @@ PlaylistWidget::addButtons (void)
Skin::PLS_DEL_CRP_1); Skin::PLS_DEL_CRP_1);
b = new PlaylistMenuButton (m_del, Skin::PLS_DEL_FIL_0, b = new PlaylistMenuButton (m_del, Skin::PLS_DEL_FIL_0,
Skin::PLS_DEL_FIL_1); Skin::PLS_DEL_FIL_1);
connect (b, SIGNAL(activated ()), m_list, SLOT (deleteFiles ())); // connect (b, SIGNAL(activated ()), m_list, SLOT (deleteFiles ()));
m_sel = new PlaylistMenu (this, Skin::PLS_SEL, m_sel = new PlaylistMenu (this, Skin::PLS_SEL,
Skin::PLS_SEL_DEC); Skin::PLS_SEL_DEC);
@ -383,43 +452,22 @@ PlaylistWidget::menuAddFile ()
} }
void
PlaylistWidget::sizeChangedList (QSize s)
{
m_scroller->setMax (s.height() - m_view->height());
}
void
PlaylistWidget::doScroll (int pos)
{
m_list->setOffset (pos);
if (pos == 0) {
m_list->update ();
} else {
m_list->scroll (0, pos);
}
QApplication::sendPostedEvents (m_list, 0);
}
void void
PlaylistWidget::resizeEvent (QResizeEvent *event) PlaylistWidget::resizeEvent (QResizeEvent *event)
{ {
m_view->resize (size().width()-30, size().height()-20-38); m_view->resize (size().width()-30, size().height()-20-38);
m_list->setSize (m_view->size().width(), m_view->size().height());
/* since the sizes has changed we need to move the buttons */ /* since the sizes has changed we need to move the buttons */
m_scroller->move (size().width()-m_rfill3.width()-m_rfill2.width(), m_scrollBar->move (size().width()-m_rfill3.width()-m_rfill2.width(),
m_corner2.height()); m_corner2.height());
m_scroller->resize (m_rfill2.width(), m_scrollBar->resize (m_rfill2.width(),
size().height()-m_corner2.height()-m_corner4.height()); size().height()-m_corner2.height()-m_corner4.height());
m_scroller->setMax (m_list->height() - m_view->height());
/* drag corner */ /* drag corner */
m_drag->move (size().width()-30, m_drag->move (size().width()-30,
size().height()-30); size().height()-30);
/* move add menu */ /* move menus */
m_add->move (11, height() - m_add->height() - 12); m_add->move (11, height() - m_add->height() - 12);
m_del->move (40, height() - m_del->height() - 12); m_del->move (40, height() - m_del->height() - 12);
m_sel->move (69, height() - m_sel->height() - 12); m_sel->move (69, height() - m_sel->height() - 12);
@ -469,13 +517,6 @@ PlaylistWidget::setActive (bool active)
update (); update ();
} }
uint
PlaylistWidget::getOffset (void)
{
return m_list->getOffset ();
}
void void
PlaylistWidget::mouseDoubleClickEvent (QMouseEvent *event) PlaylistWidget::mouseDoubleClickEvent (QMouseEvent *event)
{ {

View file

@ -5,6 +5,7 @@
#include <QMainWindow> #include <QMainWindow>
#include <QFont> #include <QFont>
#include <QScrollBar>
class MainWindow; class MainWindow;
class PlaylistWidget; class PlaylistWidget;
@ -13,10 +14,38 @@ class PlaylistScroller;
#include "Button.h" #include "Button.h"
class Skin; class Skin;
class PlaylistList; //class PlaylistList;
class PlaylistView;
class PlaylistShade; class PlaylistShade;
class PlaylistMenu; class PlaylistMenu;
class PlaylistScrollBar : public QScrollBar {
Q_OBJECT
public:
PlaylistScrollBar (QWidget *parent = NULL);
~PlaylistScrollBar () {}
public slots:
void mouseMoveEvent (QMouseEvent *event);
void mousePressEvent (QMouseEvent *event);
void mouseReleaseEvent (QMouseEvent *event);
void paintEvent (QPaintEvent *event);
void setPixmaps (Skin *skin);
private:
int sliderPositionFromValue ();
int sliderValueFromPosition (int position);
int m_sliderOffset;
QPixmap m_pixmap;
QPixmap m_slider;
QPixmap m_slider_down;
};
class dragButton : public Button { class dragButton : public Button {
public: public:
dragButton (QWidget *parent) : Button (parent) {} dragButton (QWidget *parent) : Button (parent) {}
@ -25,47 +54,6 @@ class dragButton : public Button {
void mouseMoveEvent (QMouseEvent *event); void mouseMoveEvent (QMouseEvent *event);
}; };
class PlaylistScrollButton : public Button {
public:
PlaylistScrollButton (PlaylistScroller *parent, uint normal, uint pressed);
~PlaylistScrollButton () {}
private:
PlaylistScroller *m_slider;
void mouseMoveEvent (QMouseEvent *event);
};
class PlaylistScroller : public QWidget{
Q_OBJECT
public:
PlaylistScroller (PlaylistWidget *arent);
~PlaylistScroller () {}
void doScroll (void) { emit scrolled(getPos ()); }
uint getPos (void);
uint getMax (void);
void setMax (uint max);
void repositionButton (void);
public slots:
void setPixmaps (Skin *skin);
signals:
void scrolled (int);
private:
void paintEvent (QPaintEvent *event);
QPixmap m_pixmap;
PlaylistScrollButton *m_button;
uint m_max;
};
class PlaylistView : public QWidget {
public:
PlaylistView (QWidget *parent) : QWidget (parent) {}
~PlaylistView () {}
};
class PlaylistWidget : public QWidget { class PlaylistWidget : public QWidget {
Q_OBJECT Q_OBJECT
@ -76,12 +64,9 @@ class PlaylistWidget : public QWidget {
void setActive (bool); void setActive (bool);
void switchDisplay (void); void switchDisplay (void);
uint getOffset (void);
public slots: public slots:
void setPixmaps (Skin *skin); void setPixmaps (Skin *skin);
void doScroll (int);
void sizeChangedList (QSize);
void menuAddUrl () {} void menuAddUrl () {}
void menuAddDir (); void menuAddDir ();
@ -110,8 +95,7 @@ class PlaylistWidget : public QWidget {
bool m_active; bool m_active;
PlaylistView *m_view; PlaylistView *m_view;
PlaylistList *m_list; QScrollBar *m_scrollBar;
PlaylistScroller *m_scroller;
dragButton *m_drag; dragButton *m_drag;
PlaylistMenu *m_add; PlaylistMenu *m_add;
@ -145,12 +129,13 @@ class PlaylistWindow : public QMainWindow {
private: private:
PlaylistWidget *m_playlist; PlaylistWidget *m_playlist;
PlaylistShade *m_shaded; PlaylistShade *m_shaded;
int m_diffx; int m_diffx;
int m_diffy; int m_diffy;
Button *m_shadebtn; Button *m_shadebtn;
Button *m_closebtn; Button *m_closebtn;
uint getOffset (void);
MainWindow *m_mw; MainWindow *m_mw;
}; };

View file

@ -10,6 +10,12 @@
class PlaylistItem; class PlaylistItem;
class PlaylistView : public QWidget {
public:
PlaylistView (QWidget *parent) : QWidget (parent) {}
~PlaylistView () {}
};
class PlaylistList : public QWidget { class PlaylistList : public QWidget {
Q_OBJECT Q_OBJECT

221
src/PlaylistView.cpp Normal file
View file

@ -0,0 +1,221 @@
// TODO might not need those
#include <xmmsclient/xmmsclient++.h>
#include "XMMSHandler.h"
#include "PlaylistView.h"
#include "playlistmodel.h"
#include "Playlist.h"
#include <QColor>
#include <QMenu>
#include <QPaintEvent>
#include <QPalette>
#include <QSettings>
#include <QSizePolicy>
/*
* PlaylistDelegate
*/
PlaylistDelegate::PlaylistDelegate (QObject *parent) :
QAbstractItemDelegate (parent)
{
}
void
PlaylistDelegate::paint( QPainter *painter, const QStyleOptionViewItem& option,
const QModelIndex &index ) const
{
painter->save ();
/* Set background color */
if ( option.state & QStyle::State_Selected ) {
qDrawPlainRect (painter, option.rect, QColor("#FFFFFF"), 0,
&option.palette.brush (QPalette::Highlight));
}
/* Set forground color */
if ( index.data (PlaylistModel::CurrentEntryRole).toBool () ) {
painter->setPen (option.palette.brush (QPalette::BrightText).color ());
} else {
painter->setPen (option.palette.brush (QPalette::Text).color ());
}
/* generate string */
//TODO Add album and playtime
QVariant tmp;
QString s = QString ("%1. ").arg (index.row () + 1);
tmp = index.data ();
if (tmp.isValid ())
s.append (tmp.toString ()).append (" - ");
QModelIndex m = index.sibling (index.row (), 1);
tmp = m.data ();
if (tmp.isValid ())
s.append (tmp.toString ());
s = option.fontMetrics.elidedText(s, Qt::ElideRight, option.rect.width());
painter->drawText (option.rect, Qt::AlignVCenter, s);
painter->restore ();
}
QSize
PlaylistDelegate::sizeHint ( const QStyleOptionViewItem &option,
const QModelIndex &index ) const
{
/* For QListModel, width must be > 0, but is otherwise */
return QSize (1, option.font.pixelSize () +3);
}
/*
* PlaylistView
*/
//PlaylistView::PlaylistView (QWidget *parent) : QTableView (parent)
PlaylistView::PlaylistView (QWidget *parent) : QListView (parent)
{
QSettings s;
Skin *skin = Skin::getInstance ();
if (!s.contains ("playlist/fontsize"))
s.setValue ("playlist/fontsize", 10);
setAttribute (Qt::WA_NoBackground);
// TODO make drag and drop work
//setDragEnabled(true);
//setAcceptDrops(true);
//setDropIndicatorShown (true);
// end DragandDrop
setFrameStyle(QFrame::NoFrame);
setFocusPolicy (Qt::StrongFocus);
setSelectionMode (QAbstractItemView::ExtendedSelection);
setUniformItemSizes(true);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// TODO make sure delegate gets deleted
setItemDelegate (new PlaylistDelegate (this));
connect (skin, SIGNAL (skinChanged (Skin *)),
this, SLOT (setPixmaps(Skin *)));
m_font = NULL;
m_fontmetrics = NULL;
XMMSHandler &xmmsh = XMMSHandler::getInstance ();
connect (&xmmsh, SIGNAL(settingsSaved()),
this, SLOT(settingsSaved()));
connect (&xmmsh, SIGNAL(playbackStatusChanged(Xmms::Playback::Status)),
this, SLOT(handleStatus(Xmms::Playback::Status)));
}
void
PlaylistView::setModel (QAbstractItemModel *model) {
QListView::setModel (model);
setModelColumn(0);
updateGeometry();
}
void
PlaylistView::contextMenuEvent (QContextMenuEvent *e)
{
QMenu qm(this);
QAction *a;
a = new QAction (tr ("Show file info"), this);
a->setShortcut (tr ("Ctrl+Enter"));
// connect (a, SIGNAL (triggered ()), this, SLOT (showMlib ()));
qm.addAction (a);
qm.addSeparator ();
a = new QAction (tr ("Add file"), this);
a->setShortcut (tr ("Ctrl+F"));
qm.addAction (a);
a = new QAction (tr ("Remove selected"), this);
qm.addAction (a);
qm.addSeparator ();
a = new QAction (tr ("Medialib browser"), this);
qm.addAction (a);
e->accept ();
qm.exec (e->globalPos ());
}
void
PlaylistView::handleStatus (const Xmms::Playback::Status st)
{
m_status = st;
}
void
PlaylistView::settingsSaved ()
{
QSettings s;
m_font->setPixelSize (s.value ("playlist/fontsize").toInt ());
if (m_fontmetrics) {
delete m_fontmetrics;
}
m_fontmetrics = new QFontMetrics (*m_font);
update ();
}
void
PlaylistView::setPixmaps (Skin *skin)
{
QSettings s;
QPalette pal;
QColor c;
c.setNamedColor (skin->getPLeditValue ("normalbg"));
QBrush b (c);
pal.setBrush (QPalette::Window, b);
setPalette (pal);
if (m_font) {
delete m_font;
}
m_font = new QFont (skin->getPLeditValue ("font"));
m_font->setPixelSize (s.value ("playlist/fontsize").toInt ());
if (m_fontmetrics) {
delete m_fontmetrics;
}
m_fontmetrics = new QFontMetrics (*m_font);
m_color_active.setNamedColor (skin->getPLeditValue ("current"));
m_color_selected.setNamedColor (skin->getPLeditValue ("selectedbg"));
m_color_normal.setNamedColor (skin->getPLeditValue ("normal"));
m_color_normal_bg.setNamedColor (skin->getPLeditValue ("normalbg"));
// remove later, in here for testing
setFont(*m_font);
pal.setColor (QPalette::Text, m_color_normal);
pal.setColor (QPalette::BrightText, m_color_active);
pal.setColor (QPalette::Base, m_color_normal_bg);
pal.setColor (QPalette::Highlight, m_color_selected);
setPalette (pal);
update ();
}
void
PlaylistView::mouseDoubleClickEvent (QMouseEvent *event)
{
QModelIndex index = indexAt(event->pos());
if (!index.isValid()) {
return;
}
XMMSHandler &xmmsh = XMMSHandler::getInstance ();
xmmsh.requestTrackChange (index.row());
// TODO check for status first.
if (m_status == XMMS_PLAYBACK_STATUS_STOP ||
m_status == XMMS_PLAYBACK_STATUS_PAUSE) {
xmmsh.play ();
}
}

57
src/PlaylistView.h Normal file
View file

@ -0,0 +1,57 @@
#ifndef __PLAYLISTVIEW_H__
#define __PLAYLISTVIEW_H__
//include "Playlist.h"
#include <xmmsclient/xmmsclient++.h>
#include "Skin.h"
#include <QObject>
#include <QAbstractItemDelegate>
#include <QListView>
#include <QWidget>
class PlaylistDelegate : public QAbstractItemDelegate {
Q_OBJECT
public:
PlaylistDelegate (QObject *parent = NULL);
~PlaylistDelegate () { }
void paint( QPainter * painter, const QStyleOptionViewItem & option,
const QModelIndex & index ) const;
QSize sizeHint ( const QStyleOptionViewItem &option,
const QModelIndex &index ) const;
};
class PlaylistView : public QListView {
Q_OBJECT
public:
PlaylistView (QWidget *parent);
~PlaylistView () {}
void setModel (QAbstractItemModel *model);
public slots:
void contextMenuEvent (QContextMenuEvent *e);
void handleStatus (const Xmms::Playback::Status st);
void settingsSaved (void);
void setPixmaps (Skin *skin);
protected:
void mouseDoubleClickEvent (QMouseEvent *event);
private:
Xmms::Playback::Status m_status;
QFont *m_font;
QFontMetrics *m_fontmetrics;
QColor m_color_active;
QColor m_color_selected;
QColor m_color_normal;
QColor m_color_normal_bg;
};
#endif

View file

@ -61,8 +61,8 @@ ShadedDisplay::ShadedDisplay (QWidget *parent) : SkinDisplay (parent)
connect (&xmmsh, SIGNAL(playbackStatusChanged(Xmms::Playback::Status)), connect (&xmmsh, SIGNAL(playbackStatusChanged(Xmms::Playback::Status)),
this, SLOT(setStatus(Xmms::Playback::Status))); this, SLOT(setStatus(Xmms::Playback::Status)));
connect (&xmmsh, SIGNAL(playtimeChanged(uint)), connect (xmmsh.cache (), SIGNAL (playtime (uint32_t)),
this, SLOT(setPlaytime(uint))); this, SLOT ( setPlaytime(uint32_t)));
connect (&xmmsh, SIGNAL(currentSong (const Xmms::PropDict &)), connect (&xmmsh, SIGNAL(currentSong (const Xmms::PropDict &)),
this, SLOT(setMediainfo (const Xmms::PropDict &))); this, SLOT(setMediainfo (const Xmms::PropDict &)));
} }
@ -94,18 +94,15 @@ ShadedDisplay::setStatus (Xmms::Playback::Status status)
} }
void void
ShadedDisplay::setPlaytime (uint time) ShadedDisplay::setPlaytime (uint32_t time)
{ {
uint sec, min; uint sec, min;
sec = (time / 1000) % 60; sec = (time / 1000) % 60;
min = (time / 1000) / 60; min = (time / 1000) / 60;
if (sec != m_number2->getNumber ()) {
m_number2->setNumber (sec, 2); m_number2->setNumber (sec, 2);
} else if (min != m_number->getNumber ()) {
m_number->setNumber (min, 2); m_number->setNumber (min, 2);
}
} }

View file

@ -32,7 +32,7 @@ class ShadedDisplay : public SkinDisplay
public slots: public slots:
void setStatus (Xmms::Playback::Status status); void setStatus (Xmms::Playback::Status status);
void setPlaytime (uint time); void setPlaytime (uint32_t time);
void setMediainfo (const Xmms::PropDict &info); void setMediainfo (const Xmms::PropDict &info);
}; };

View file

@ -74,11 +74,11 @@ Skin::BuildPlaylist (void)
m_playlist[PLS_VISMINI_0] = img->copy(205, 0, 75, 38); m_playlist[PLS_VISMINI_0] = img->copy(205, 0, 75, 38);
m_playlist[PLS_LFILL_0] = img->copy(0, 42, 12, 29); m_playlist[PLS_LFILL_0] = img->copy(0, 42, 12, 29);
m_playlist[PLS_RFILL_0] = img->copy(31, 42, 5, 29); m_playlist[PLS_RFILL_0] = img->copy(31, 42, 5, 29);
m_playlist[PLS_RFILL2_0] = img->copy(36, 42, 8, 29); m_playlist[PLS_RFILL2_0] = img->copy(36, 42, 8, 29);
m_playlist[PLS_RFILL3_0] = img->copy(44, 42, 7, 29); m_playlist[PLS_RFILL3_0] = img->copy(44, 42, 7, 29);
tmp = m_playlist[PLS_CORNER_UR_0]; tmp = m_playlist[PLS_CORNER_UR_0];
m_playlist[PLS_CLOSE_BTN_0] = tmp.copy(14, 3, 9, 9); m_playlist[PLS_CLOSE_BTN_0] = tmp.copy(14, 3, 9, 9);

View file

View file

@ -69,8 +69,7 @@ void
TextScroller::setPixmaps (Skin *skin) TextScroller::setPixmaps (Skin *skin)
{ {
QPalette pal = palette (); QPalette pal = palette ();
QBrush b = QBrush (Qt::TexturePattern); QBrush b = QBrush (skin->getItem (Skin::TEXTBG));
b.setTexture (skin->getItem (Skin::TEXTBG));
pal.setBrush (QPalette::Window, b); pal.setBrush (QPalette::Window, b);
setPalette (pal); setPalette (pal);

View file

@ -65,8 +65,7 @@ TimeDisplay::drawMinus ()
Skin *skin = Skin::getInstance (); Skin *skin = Skin::getInstance ();
// Draw background // Draw background
QBrush b (Qt::TexturePattern); QBrush b (skin->getNumber (10));
b.setTexture (skin->getNumber (10));
QPainter paint; QPainter paint;
paint.begin (&m_pixmap); paint.begin (&m_pixmap);

View file

@ -1,7 +1,8 @@
#include <xmmsclient/xmmsclient++.h> #include <xmmsclient/xmmsclient++.h>
#include "XmmsQT4.h" #include "xmmsqt4.h"
#include "XMMSHandler.h" #include "XMMSHandler.h"
#include "playlistmodel.h"
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
@ -18,27 +19,24 @@ static bool log ( /*const std::string& text = ""*/ )
return false; return false;
} }
static bool logUint ( const unsigned int & /*, const std::string& text = "" */ )
{
return false;
}
XMMSHandler &XMMSHandler::getInstance () XMMSHandler &XMMSHandler::getInstance ()
{ {
static XMMSHandler singleton; static XMMSHandler singleton(NULL, "Prome_Main");
return singleton; return singleton;
} }
XMMSHandler::XMMSHandler () : QObject (), m_client ("Prome_Main") XMMSHandler::XMMSHandler (QObject *parent, const std::string &name) : XClient (parent, name)
{ {
connect (std::getenv ( "XMMS_PATH" )); connect_handler();
} }
bool bool
XMMSHandler::connect (const char *path) XMMSHandler::connect_handler (const char *ipcpath, const bool &sync, QWidget *parent)
{ {
try { /* try {
m_client.connect (path ? path : ""); m_client.connect(path);
//TODO reenable checking of path
//m_client.connect (path ? path : "");
} }
catch (Xmms::connection_error& e) { catch (Xmms::connection_error& e) {
QErrorMessage *err = new QErrorMessage (); QErrorMessage *err = new QErrorMessage ();
@ -49,30 +47,30 @@ XMMSHandler::connect (const char *path)
} }
m_client.setMainloop (new XmmsQT4 (m_client.getConnection ())); m_client.setMainloop (new XmmsQT4 (m_client.getConnection ()));
*/
//TODO must be moved elsewere later
m_playlist_model = new PlaylistModel(NULL, this, "_active");
connect(ipcpath, sync, parent);
using Xmms::bind; using Xmms::bind;
m_client.playlist.list (bind (&XMMSHandler::playlist_list, this)); // m_client->playlist.listEntries () (bind (&XMMSHandler::playlist_list, this));
m_client.playlist.broadcastChanged ( // m_client->playlist.broadcastChanged () (bind (&XMMSHandler::playlist_changed, this));
bind (&XMMSHandler::playlist_changed, this));
m_client.medialib.broadcastEntryChanged ( m_client->medialib.broadcastEntryChanged () (bind (&XMMSHandler::medialib_entry_changed, this));
bind (&XMMSHandler::medialib_entry_changed, this));
m_client.playback.currentID ( m_client->playback.currentID () (bind (&XMMSHandler::playback_current_id, this));
bind (&XMMSHandler::playback_current_id, this)); m_client->playback.broadcastCurrentID () (bind (&XMMSHandler::playback_current_id, this));
m_client.playback.broadcastCurrentID (
bind (&XMMSHandler::playback_current_id, this));
m_client.playback.getStatus (bind (&XMMSHandler::playback_status, this)); m_client->playback.getStatus () (bind (&XMMSHandler::playback_status, this));
m_client.playback.broadcastStatus ( m_client->playback.broadcastStatus () (bind (&XMMSHandler::playback_status, this));
bind (&XMMSHandler::playback_status, this));
m_client.playback.broadcastVolumeChanged ( m_client->playback.broadcastVolumeChanged () (bind (&XMMSHandler::volume_changed, this));
bind (&XMMSHandler::volume_changed, this));
QObject::connect (&m_playtime_timer, SIGNAL (timeout ()), // TODO: Disabled for now. Seems to cause problems on startup
this, SLOT (restartPlaytime ())); // QObject::connect (&m_playtime_timer, SIGNAL (timeout ()),
m_playtime_timer.start(0); // this, SLOT (restartPlaytime ()));
// m_playtime_timer.start(0);
return true; return true;
} }
@ -81,14 +79,13 @@ XMMSHandler::connect (const char *path)
Xmms::Client * Xmms::Client *
XMMSHandler::getClient () XMMSHandler::getClient ()
{ {
return &m_client; return m_client;
} }
void void
XMMSHandler::restartPlaytime () XMMSHandler::restartPlaytime ()
{ {
m_client.playback.getPlaytime (Xmms::bind (&XMMSHandler::playback_playtime, m_client->playback.getPlaytime () (Xmms::bind (&XMMSHandler::playback_playtime, this));
this));
} }
bool bool
@ -103,38 +100,37 @@ XMMSHandler::medialib_entry_changed (const unsigned int &id)
void void
XMMSHandler::playlistAddURL (const QString &s) XMMSHandler::playlistAddURL (const QString &s)
{ {
m_client.playlist.addUrl (s.toAscii ().constData (), &log); m_client->playlist.addUrl (s.toAscii ().constData ()) ();
} }
void void
XMMSHandler::playlistRemove (uint pos) XMMSHandler::playlistRemove (uint pos)
{ {
m_client.playlist.remove (pos, &log); m_client->playlist.removeEntry (pos) ();
} }
void void
XMMSHandler::playlistMove (uint pos, uint newpos) XMMSHandler::playlistMove (uint pos, uint newpos)
{ {
m_client.playlist.move (pos, newpos, &log); m_client->playlist.moveEntry (pos, newpos) ();
} }
void void
XMMSHandler::requestMediainfo (uint id) XMMSHandler::requestMediainfo (uint id)
{ {
m_client.medialib.getInfo (id, m_client->medialib.getInfo (id) (Xmms::bind (&XMMSHandler::medialib_info, this));
Xmms::bind (&XMMSHandler::medialib_info, this));
} }
void void
XMMSHandler::requestPlaylistList () XMMSHandler::requestPlaylistList ()
{ {
m_client.playlist.list (Xmms::bind (&XMMSHandler::playlist_list, this)); // m_client->playlist.listEntries () (Xmms::bind (&XMMSHandler::playlist_list, this));
} }
void void
XMMSHandler::requestTrackChange (int pos) XMMSHandler::requestTrackChange (int pos)
{ {
m_client.playlist.setNext (pos, &logUint); m_client->playlist.setNext (pos) ();
m_client.playback.tickle (&log); m_client->playback.tickle () ();
} }
bool bool
@ -175,7 +171,7 @@ XMMSHandler::playback_current_id (const unsigned int &id)
void void
XMMSHandler::setPlaytime (uint pos) XMMSHandler::setPlaytime (uint pos)
{ {
m_client.playback.seekMs (pos, &log); m_client->playback.seekMs (pos) ();
} }
void void
@ -265,7 +261,7 @@ XMMSHandler::volume_error (const std::string &error)
void void
XMMSHandler::volumeGet () XMMSHandler::volumeGet ()
{ {
m_client.playback.volumeGet (Xmms::bind (&XMMSHandler::volume_get, this), m_client->playback.volumeGet () (Xmms::bind (&XMMSHandler::volume_get, this),
Xmms::bind (&XMMSHandler::volume_error, this)); Xmms::bind (&XMMSHandler::volume_error, this));
} }
@ -274,12 +270,12 @@ XMMSHandler::volumeSet (uint volume)
{ {
if(m_masterchan) if(m_masterchan)
{ {
m_client.playback.volumeSet ("master", volume, &log); m_client->playback.volumeSet ("master", volume) ();
} }
else else
{ {
m_client.playback.volumeSet ("left", volume, &log); m_client->playback.volumeSet ("left", volume) ();
m_client.playback.volumeSet ("right", volume, &log); m_client->playback.volumeSet ("right", volume) ();
} }
} }
@ -323,33 +319,33 @@ XMMSHandler::volume_get (const Xmms::Dict &levels)
void XMMSHandler::playlistClear () void XMMSHandler::playlistClear ()
{ {
m_client.playlist.clear (&log); m_client->playlist.clear () ();
} }
void XMMSHandler::play () void XMMSHandler::play ()
{ {
m_client.playback.start (&log); m_client->playback.start () ();
} }
void XMMSHandler::stop () void XMMSHandler::stop ()
{ {
m_client.playback.stop (&log); m_client->playback.stop () ();
} }
void XMMSHandler::pause () void XMMSHandler::pause ()
{ {
m_client.playback.pause (&log); m_client->playback.pause () ();
} }
void XMMSHandler::next () void XMMSHandler::next ()
{ {
m_client.playlist.setNextRel (1, &logUint); m_client->playlist.setNextRel (1) ();
m_client.playback.tickle (&log); m_client->playback.tickle () ();
} }
void XMMSHandler::prev () void XMMSHandler::prev ()
{ {
m_client.playlist.setNextRel (-1, &logUint); m_client->playlist.setNextRel (-1) ();
m_client.playback.tickle (&log); m_client->playback.tickle () ();
} }

View file

@ -3,18 +3,24 @@
#include <xmmsclient/xmmsclient++.h> #include <xmmsclient/xmmsclient++.h>
#include "XmmsQT4.h" #include "xclient.h"
#include "xmmsqt4.h"
#include <QObject> #include <QObject>
#include <QHash> #include <QHash>
#include <QTimer> #include <QTimer>
class XMMSHandler : public QObject { class PlaylistModel;
class XMMSHandler : public XClient {
Q_OBJECT Q_OBJECT
public: public:
static XMMSHandler &getInstance (); static XMMSHandler &getInstance ();
bool connect (const char *path); XMMSHandler (QObject *parent, const std::string &name);
~XMMSHandler () {};
bool connect_handler (const char *ipcpath = NULL, const bool &sync = false, QWidget *parent = NULL);
bool playback_playtime (const unsigned int &time); bool playback_playtime (const unsigned int &time);
bool playlist_list (const Xmms::List< unsigned int > &playlist); bool playlist_list (const Xmms::List< unsigned int > &playlist);
@ -50,6 +56,8 @@ class XMMSHandler : public QObject {
Xmms::Client *getClient (); Xmms::Client *getClient ();
PlaylistModel *getPlaylistModel () {return m_playlist_model; }
public slots: public slots:
void setPlaytime (uint pos); void setPlaytime (uint pos);
void restartPlaytime (); void restartPlaytime ();
@ -79,12 +87,10 @@ class XMMSHandler : public QObject {
private: private:
QTimer m_playtime_timer; QTimer m_playtime_timer;
XMMSHandler ();
~XMMSHandler () {};
void DictToQHash (const std::string &key, void DictToQHash (const std::string &key,
const Xmms::Dict::Variant &value, const Xmms::Dict::Variant &value,
QHash<QString, QString> &hash); QHash<QString, QString> &hash);
void PropDictToQHash (const std::string &key, void PropDictToQHash (const std::string &key,
const Xmms::Dict::Variant &value, const Xmms::Dict::Variant &value,
const std::string &source, const std::string &source,
QHash<QString, QString> &hash); QHash<QString, QString> &hash);
@ -92,8 +98,8 @@ class XMMSHandler : public QObject {
bool volume_get (const Xmms::Dict &levels); bool volume_get (const Xmms::Dict &levels);
bool volume_error (const std::string &error); bool volume_error (const std::string &error);
Xmms::Client m_client;
XmmsQT4 *m_qt4; XmmsQT4 *m_qt4;
PlaylistModel *m_playlist_model;
unsigned int m_currentid; unsigned int m_currentid;
bool m_masterchan; bool m_masterchan;
}; };

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Before After
Before After

89
src/src.pro Normal file
View file

@ -0,0 +1,89 @@
TEMPLATE = app
include (../config.pri)
COMPONENTS+=../lib/liblib.a
LIBS += $$COMPONENTS
PRE_TARGETDEPS = $$COMPONENTS
SOURCES += PixWidget.cpp \
Skin.cpp \
MainWindow.cpp \
Display.cpp \
MainDisplay.cpp \
TitleBar.cpp \
Button.cpp \
TextBar.cpp \
NumberDisplay.cpp \
TimeDisplay.cpp \
XMMSHandler.cpp \
SmallNumberDisplay.cpp \
StereoMono.cpp \
PosBar.cpp \
PlayStatus.cpp \
ShadedDisplay.cpp \
Playlist.cpp \
PlaylistView.cpp \
SkinChooser.cpp \
PlaylistShade.cpp \
qtmd5.cpp \
SettingsWindow.cpp \
PlaylistMenu.cpp \
VolumeSlider.cpp \
ClutterBar.cpp \
Equalizer.cpp \
FileDialog.cpp \
BrowseModel.cpp \
BrowseDialog.cpp
HEADERS += PixWidget.h \
Skin.h \
MainWindow.h \
Display.h \
MainDisplay.h \
TitleBar.h \
Button.h \
TextBar.h \
NumberDisplay.h \
TimeDisplay.h \
XMMSHandler.h \
SmallNumberDisplay.h \
StereoMono.h \
PosBar.h \
PlayStatus.h \
ShadedDisplay.h \
Playlist.h \
PlaylistView.h \
SkinChooser.h \
PlaylistShade.h \
qtmd5.h \
SettingsWindow.h \
PlaylistMenu.h \
VolumeSlider.h \
ClutterBar.h \
Equalizer.h \
FileDialog.h \
BrowseModel.h \
BrowseDialog.h
TARGET = promoe
DESTDIR = $$PWD/..
RESOURCES = promoe.qrc
macx:RC_FILE = promoe.icns
macx:INCLUDEPATH = /sw/include
QT += network
;macx:QTPLUGIN += qjpeg
QMAKE_LFLAGS += -L$$[QT_INSTALL_PLUGINS]/imageformats
CONFIG += link_pkgconfig
QMAKE_CXXFLAGS += -g
;CONFIG += debug warn_on
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter
PKGCONFIG += xmms2-client xmms2-client-cpp
;CONFIG += avahi