Added rudementary queue support

This commit is contained in:
Brian Hrebec 2013-04-10 02:12:46 -07:00
parent 3880262046
commit 5241b3c6da
4 changed files with 141 additions and 11 deletions

View file

@ -29,23 +29,24 @@
#include "playlistmodel.h"
#include "xclient.h"
#include "xclientcache.h"
#include "xplayback.h"
// Used to check for Protocolversion at compiletime
#include <xmmsc/xmmsc_idnumbers.h>
PlaylistModel::PlaylistModel (QObject *parent, XClient *client, const QString &name) : QAbstractItemModel (parent), m_current_pos (0)
{
// m_columns.append ("#");
m_columns.append ("Artist");
m_columns.append ("Album");
m_columns.append ("Title");
m_columns.append ("#queue");
m_columns.append ("Duration");
// m_colfallback.append ("");
m_colfallback.append ("");
m_colfallback.append ("");
m_colfallback.append ("url");
m_colfallback.append ("");
m_colfallback.append ("");
m_cached_size.append (QSize ());
m_cached_size.append (QSize ());
@ -127,9 +128,11 @@ PlaylistModel::handle_update_pos (const Xmms::Dict &posdict)
#else
uint32_t pos = posdict.get<uint32_t> ("position");
#endif
m_current_pos = pos;
emit currentPosChanged (index (pos, 0));
emit dataChanged(index (pos, 0), index (pos, m_columns.size ()));
if (queue_next(pos)) {
m_current_pos = pos;
emit currentPosChanged (index (pos, 0));
emit dataChanged(index (pos, 0), index (pos, m_columns.size ()));
}
}
return true;
}
@ -137,9 +140,11 @@ PlaylistModel::handle_update_pos (const Xmms::Dict &posdict)
bool
PlaylistModel::handle_update_pos (const uint32_t &pos)
{
m_current_pos = pos;
emit currentPosChanged (index (pos, 0));
emit dataChanged(index (pos, 0), index (pos, m_columns.size ()));
if (queue_next()) {
m_current_pos = pos;
emit currentPosChanged (index (pos, 0));
emit dataChanged(index (pos, 0), index (pos, m_columns.size ()));
}
return true;
}
#endif
@ -223,14 +228,16 @@ PlaylistModel::handle_change (const Xmms::Dict &chg)
break;
case XMMS_PLAYLIST_CHANGED_REMOVE:
m_queue.removeAt(m_queue_index.take(m_plist[pos]));
m_client->cache ()->invalidate (m_plist[pos]);
beginRemoveRows (idx, pos, pos);
m_plist.removeAt (pos);
endRemoveRows ();
break;
case XMMS_PLAYLIST_CHANGED_CLEAR:
queueClear();
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;
@ -387,6 +394,12 @@ PlaylistModel::data (const QModelIndex &index, int role) const
if (key == "#") {
return QVariant (index.row ());
} else if (key == "#queue") {
unsigned int id = m_plist[index.row ()];
if (m_queue_index.contains (id)) {
return QVariant (QString ("(%1)").arg (m_queue_index.value(id) + 1));
}
return QVariant ();
} else {
unsigned int id = m_plist[index.row ()];
PlaylistModel *fake = const_cast<PlaylistModel*> (this);
@ -631,4 +644,74 @@ PlaylistModel::removeRows (QModelIndexList index_list)
}
}
void
PlaylistModel::queueToggle(unsigned int pos)
{
uint32_t id = m_plist.at(pos);
if (m_queue_index.contains(id)) {
unsigned int queue_idx = m_queue_index.take(id);
m_queue.removeAt(queue_idx);
} else {
m_queue.append(id);
m_queue_index[id] = m_queue.length() - 1;
}
emit dataChanged(index(pos, 3), index(pos, 3));
}
void
PlaylistModel::queueClear()
{
m_queue.clear();
m_queue_index.clear();
}
int
PlaylistModel::queue_peek ()
{
if (m_queue.isEmpty())
return -1;
uint32_t next_id = m_queue.first();
QList<uint32_t> next_pos_list = getPosById(next_id);
if (next_pos_list.isEmpty())
return -1;
else
return next_pos_list.first();
}
void
PlaylistModel::queue_pop ()
{
uint32_t next_id = m_queue.takeFirst();
m_queue_index.remove(next_id);
QHash<uint32_t, int>::iterator it;
for (it = m_queue_index.begin(); it != m_queue_index.end(); ++it) {
it.value()--;
}
}
bool
PlaylistModel::queue_next (int pos)
{
while (!m_queue.isEmpty()) {
int next_pos = queue_peek();
if (next_pos == -1) {
// Queue item no longer exists in playlist
queue_pop();
} else if (next_pos == pos) {
// Now on the next queue item; we're done
queue_pop();
return true;
} else if (pos - m_current_pos != 1) {
// User manually jumped in playlist, bail out
return true;
} else {
// Jump to queue position
m_client->xplayback ()->setPos(next_pos);
return false;
}
}
return true;
}
#include "playlistmodel.moc"

View file

@ -26,6 +26,7 @@ class XClient;
#include <QAbstractTableModel>
#include <QVariant>
#include <QHash>
#include <QList>
#include <QIcon>
/**
@ -118,6 +119,17 @@ class PlaylistModel : public QAbstractItemModel
uint32_t getPlaytimeForSelection(const QModelIndexList &index_list);
/**
* Add a playlist item to the queue
* @param pos Position of the item to be added
*/
void queueToggle(uint32_t pos);
/**
* Clears the playlist queue
*/
void queueClear();
protected:
XClient *m_client;
QList < unsigned int > m_plist;
@ -153,6 +165,10 @@ class PlaylistModel : public QAbstractItemModel
void emitTotalPlaytime ();
bool queue_next(int pos);
void queue_pop();
int queue_peek();
uint32_t m_current_pos;
bool m_isactive;
@ -160,6 +176,9 @@ class PlaylistModel : public QAbstractItemModel
QString m_name;
QList<uint32_t> m_queue; // list of ids, in queue order
QHash<uint32_t, int> m_queue_index; // map of ids to queue position
};
#endif

View file

@ -70,7 +70,7 @@ PlaylistDelegate::paint( QPainter *painter, const QStyleOptionViewItem& option,
QRect r = option.rect;
QString s;
// Get playtime and if it exists, draw it
m = index.sibling (index.row (), 3);
m = index.sibling (index.row (), 4);
tmp = m.data ();
if (tmp.isValid ()) {
int seconds = tmp.toInt () / 1000;
@ -81,11 +81,12 @@ PlaylistDelegate::paint( QPainter *painter, const QStyleOptionViewItem& option,
r.setWidth (r.width () - option.fontMetrics.width (s));
}
// now build String for Artis Title and Position
// now build String for Artist, Title and Position
s = QString ("%1. ").arg (index.row () + 1);
tmp = index.data ();
if (tmp.isValid ())
s.append (tmp.toString ()).append (" - ");
m = index.sibling (index.row (), 1);
tmp = m.data ();
if (tmp.isValid ())
@ -93,8 +94,14 @@ PlaylistDelegate::paint( QPainter *painter, const QStyleOptionViewItem& option,
m = index.sibling (index.row (), 2);
tmp = m.data ();
if (tmp.isValid ())
s.append (tmp.toString ().append (" "));
m = index.sibling (index.row (), 3);
tmp = m.data ();
if (tmp.isValid ())
s.append (tmp.toString ());
s = option.fontMetrics.elidedText(s, Qt::ElideRight, r.width());
painter->drawText (r, Qt::AlignVCenter, s);
@ -371,6 +378,26 @@ PlaylistView::mouseMoveEvent (QMouseEvent *event)
}
}
void
PlaylistView::keyPressEvent (QKeyEvent *event)
{
if (event->key() == Qt::Key_Q) {
PlaylistModel *plmodel = qobject_cast<PlaylistModel *> (model ());
if (event->modifiers () && Qt::ShiftModifier) {
plmodel->queueClear ();
} else {
QModelIndexList sel = selectedIndexes ();
for (int i = 0; i < sel.size (); i++) {
plmodel->queueToggle (sel[i].row());
}
}
} else {
QListView::keyPressEvent(event);
}
}
void
PlaylistView::entryMoved(QModelIndex a, QModelIndex b)
{

View file

@ -75,6 +75,7 @@ class PlaylistView : public QListView {
protected:
void mouseDoubleClickEvent (QMouseEvent *event);
void mouseMoveEvent (QMouseEvent *event);
void keyPressEvent (QKeyEvent *event);
protected slots:
void selectionChanged (const QItemSelection &, const QItemSelection &);