Added rudementary queue support
This commit is contained in:
parent
3880262046
commit
5241b3c6da
4 changed files with 141 additions and 11 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 &);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue