diff --git a/lib/playlistmodel.cpp b/lib/playlistmodel.cpp index 54f82fe..515654c 100644 --- a/lib/playlistmodel.cpp +++ b/lib/playlistmodel.cpp @@ -225,6 +225,9 @@ PlaylistModel::handle_change (const Xmms::Dict &chg) break; } + /* TODO: call this only for the necessary methods */ + emitTotalPlaytime (); + return true; } @@ -246,6 +249,8 @@ PlaylistModel::handle_list (const Xmms::List< unsigned int > &list) endInsertRows (); + emitTotalPlaytime (); + return true; } @@ -284,6 +289,8 @@ PlaylistModel::entry_changed (uint32_t id) QModelIndex idx2 = index (pos.at (i), m_columns.size ()); emit dataChanged(idx1, idx2); } + + emitTotalPlaytime (); } int @@ -535,6 +542,39 @@ PlaylistModel::flags (const QModelIndex &idx) const return f; } +void +PlaylistModel::emitTotalPlaytime () +{ + bool isExact = true; + uint32_t time = 0; + + foreach (uint32_t index, m_plist) { + QHash data = m_client->cache ()->get_info (index, + false); + if (!data.isEmpty ()) { + time += data.value ("duration", 0).toInt (); + } else { + isExact = false; + } + } + + emit totalPlaytime (time/1000, isExact); +} + +uint32_t +PlaylistModel::getPlaytimeForSelection(const QModelIndexList &index_list) +{ + uint32_t playtime = 0; + foreach (QModelIndex idx, index_list) { + int id = idx.row (); + if (id >= m_plist.size ()) continue; + QHash data = + m_client->cache ()->get_info (m_plist.at (id), false); + if (!data.isEmpty ()) playtime += data.value ("duration", 0).toInt (); + } + return playtime/1000; +} + QList PlaylistModel::get_all_id () { diff --git a/lib/playlistmodel.h b/lib/playlistmodel.h index 3f915af..ef70000 100644 --- a/lib/playlistmodel.h +++ b/lib/playlistmodel.h @@ -115,6 +115,8 @@ class PlaylistModel : public QAbstractItemModel void removeRows (QModelIndexList); + uint32_t getPlaytimeForSelection(const QModelIndexList &index_list); + protected: XClient *m_client; QList < unsigned int > m_plist; @@ -125,6 +127,7 @@ class PlaylistModel : public QAbstractItemModel signals: void entryMoved (const QModelIndex &, const QModelIndex &); void currentPosChanged (QModelIndex); + void totalPlaytime (uint32_t seconds, bool isExact); public slots: void got_connection (XClient *); @@ -143,6 +146,8 @@ class PlaylistModel : public QAbstractItemModel void getInfo (unsigned int id) const; + void emitTotalPlaytime (); + uint32_t m_current_pos; bool m_isactive; diff --git a/lib/xclientcache.cpp b/lib/xclientcache.cpp index 6117e5f..04089ad 100644 --- a/lib/xclientcache.cpp +++ b/lib/xclientcache.cpp @@ -154,9 +154,9 @@ XClientCache::get_pixmap (uint32_t id) } QHash -XClientCache::get_info (uint32_t id) +XClientCache::get_info (uint32_t id, bool fetchFromServer) { - if (!m_info.contains (id)) { + if ((!m_info.contains (id)) && fetchFromServer) { m_client->medialib ()->getInfo (id) ( Xmms::bind (&XClientCache::handle_medialib_info, this), boost::bind (&XClientCache::handle_medialib_info_error, @@ -164,7 +164,7 @@ XClientCache::get_info (uint32_t id) m_info[id] = QHash (); } - return m_info[id]; + return m_info.value(id, QHash()); } bool diff --git a/lib/xclientcache.h b/lib/xclientcache.h index bd2318a..d381379 100644 --- a/lib/xclientcache.h +++ b/lib/xclientcache.h @@ -46,7 +46,16 @@ class XClientCache : public QObject public: XClientCache (XClient *); - QHash get_info (uint32_t id); + /* Returns the metadata of the given medialib id, if it is cached + * locally. If the metadata is not cached, an empty QHash is returned + * If the metadata is not cached and fetchFromServer is true, the + * metadata is fetched from the server and a entryChanged SIGNAL is + * emitted to notify the caller that the metadata has arrived + * DO NOT use this function with fetchFromServer set to false if you + * didn't understand this explanation + */ + QHash get_info (uint32_t id, + bool fetchFromServer=true); QVariantHash get_current_info () {return get_info (m_current_id);} QIcon get_icon (uint32_t id); QPixmap get_pixmap (uint32_t id); diff --git a/src/Skin.cpp b/src/Skin.cpp index f7df491..e32bd91 100644 --- a/src/Skin.cpp +++ b/src/Skin.cpp @@ -375,6 +375,7 @@ Skin::BuildLetterMap (void) /* special characters */ m_letterMap['"'] = letters[0][27]; m_letterMap['@'] = letters[0][28]; + m_letterMap[':'] = letters[1][12]; m_letterMap['('] = letters[1][13]; m_letterMap[')'] = letters[1][14]; m_letterMap['-'] = letters[1][15]; diff --git a/src/Skin.h b/src/Skin.h index ee9546f..7049070 100644 --- a/src/Skin.h +++ b/src/Skin.h @@ -47,6 +47,7 @@ class Skin : public QObject { return m_backgrounds.value(item); }; const PixmapMap getNumbers () const { return m_numbers; } const PixmapMap getSmallNumbers () const { return m_smallNumbers; } + const PixmapMap getPixmapFont () const { return m_letterMap; } const QPixmap getItem (uint part) const { return m_items.value (part); } const QPixmap getPls (uint part) const @@ -87,7 +88,7 @@ class Skin : public QObject QMap m_numbers; QMap m_smallNumbers; QMap m_items; - QMap m_letterMap; + QMap m_letterMap; QMap m_playlist; QMap m_pledit_txt; diff --git a/src/playlist/playlistcontrols.cpp b/src/playlist/playlistcontrols.cpp index 0e87b01..49540ef 100644 --- a/src/playlist/playlistcontrols.cpp +++ b/src/playlist/playlistcontrols.cpp @@ -17,6 +17,24 @@ #include "pixmapbutton.h" #include "timedisplay.h" +#include + +QString secondsToString (uint32_t seconds) +{ + int h, m, s; + s = seconds % 60; + seconds /= 60; + m = seconds % 60; + h = seconds / 60; + + QString ret = QString ("%1%2%3") + .arg (h ? QString ("%1:").arg(h) : "") + .arg (m ? QString ("%1:").arg(m) : "") + .arg (s); + return ret; +} + + PlaylistControls::PlaylistControls (QWidget *parent) : QWidget (parent) { setFixedSize (100, 38); @@ -63,7 +81,30 @@ PlaylistControls::PlaylistControls (QWidget *parent) : QWidget (parent) connect (this, SIGNAL (setDisplayTime (int)), m_timedisplay, SLOT (setTime (int))); - //TODO: playtimes + m_selection_playtime = 0; + m_playlist_playtime = 0; + is_playlist_playtime_exact = true; +} + +void +PlaylistControls::paintEvent (QPaintEvent *event) +{ + if (m_font.isEmpty ()) return; + + int x = 8, y = 10; + QString time = QString ("%1/%2%3") + .arg (secondsToString (m_selection_playtime)) + .arg (secondsToString (m_playlist_playtime)) + .arg (is_playlist_playtime_exact ? "" : "+"); + + QPainter paint; + paint.begin (this); + foreach (QChar c, time) { + paint.drawPixmap (x, y, m_font[c.toAscii()]); + x += 5; + } + paint.end (); + } void @@ -73,13 +114,23 @@ PlaylistControls::setNumbers (const PixmapMap &p) } void -PlaylistControls::setSelectedLength (int lenght) +PlaylistControls::setPixmapFont (const PixmapMap &p) { - //TODO + m_font = p; + update (); } void -PlaylistControls::setPlaylistLength (int lenght) +PlaylistControls::setSelectionPlaytime (uint32_t playtime) { - //TODO + m_selection_playtime = playtime; + update (); +} + +void +PlaylistControls::setPlaylistPlaytime (uint32_t playtime, bool isExact) +{ + m_playlist_playtime = playtime; + is_playlist_playtime_exact = isExact; + update (); } diff --git a/src/playlist/playlistcontrols.h b/src/playlist/playlistcontrols.h index a379b30..cf28190 100644 --- a/src/playlist/playlistcontrols.h +++ b/src/playlist/playlistcontrols.h @@ -20,6 +20,7 @@ #include class SmallTimeDisplay; +class QPaintEvent; class QPixmap; typedef QMap PixmapMap; @@ -31,10 +32,11 @@ class PlaylistControls : public QWidget { PlaylistControls (QWidget *parent); void setNumbers (const PixmapMap &p); + void setPixmapFont (const PixmapMap &p); public slots: - void setSelectedLength (int); - void setPlaylistLength (int); + void setSelectionPlaytime (uint32_t); + void setPlaylistPlaytime (uint32_t, bool isExact); signals: // emitted when buttons are clicked @@ -49,9 +51,14 @@ class PlaylistControls : public QWidget { //connected to internal timedisplay void setDisplayTime (int); + private slots: + void paintEvent (QPaintEvent *event); + private: - int m_playlist_length; - int m_selected_length; + uint32_t m_playlist_playtime; + bool is_playlist_playtime_exact; + uint32_t m_selection_playtime; + PixmapMap m_font; SmallTimeDisplay *m_timedisplay; }; diff --git a/src/playlist/playlistview.cpp b/src/playlist/playlistview.cpp index 41462cd..bc4148e 100644 --- a/src/playlist/playlistview.cpp +++ b/src/playlist/playlistview.cpp @@ -144,7 +144,21 @@ PlaylistView::PlaylistView (QWidget *parent) : QListView (parent) } void -PlaylistView::invertSelection () { +PlaylistView::selectionChanged (const QItemSelection &selected, + const QItemSelection &deselected) +{ + /* selectedIndexes () is used here because selected only contains newly + * seleted indexes and will give a wrong result if pressing CONTROL to + * modify a selection */ + uint32_t playtime = qobject_cast (model ())->getPlaytimeForSelection (selectedIndexes ()); + emit selectionPlaytimeChanged (playtime); + + QListView::selectionChanged (selected, deselected); +} + +void +PlaylistView::invertSelection () +{ QItemSelection selection = QItemSelection (model ()->index (0, 0), model ()->index (model ()->rowCount ()-1, 0)); selectionModel ()->select (selection, QItemSelectionModel::Toggle | diff --git a/src/playlist/playlistview.h b/src/playlist/playlistview.h index b252089..d49b931 100644 --- a/src/playlist/playlistview.h +++ b/src/playlist/playlistview.h @@ -55,6 +55,9 @@ class PlaylistView : public QListView { {qWarning ("Trying to set wrong model in PlaylistView"); return;}; void setModel (PlaylistModel *model); + signals: + void selectionPlaytimeChanged (uint32_t playtime); + public slots: void contextMenuEvent (QContextMenuEvent *e); @@ -66,9 +69,13 @@ class PlaylistView : public QListView { void settingsChanged (void); void setPixmaps (Skin *skin); void currentPosChanged (QModelIndex); + protected: void mouseDoubleClickEvent (QMouseEvent *event); + protected slots: + void selectionChanged (const QItemSelection &, const QItemSelection &); + private: Xmms::Playback::Status m_status; QFont *m_font; diff --git a/src/playlist/playlistwidget.cpp b/src/playlist/playlistwidget.cpp index 61cca99..a6bc78a 100644 --- a/src/playlist/playlistwidget.cpp +++ b/src/playlist/playlistwidget.cpp @@ -238,6 +238,14 @@ PlaylistWidget::PlaylistWidget (PlaylistWindow *parent) : QWidget (parent) connect (parent, SIGNAL (setDisplayTime (int)), m_controls, SIGNAL (setDisplayTime (int))); + + connect (App->client ()->active_playlist (), + SIGNAL (totalPlaytime(uint32_t, bool)), + m_controls, SLOT (setPlaylistPlaytime (uint32_t, bool))); + + connect (m_view, SIGNAL (selectionPlaytimeChanged(uint32_t)), + m_controls, SLOT (setSelectionPlaytime (uint32_t))); + setMinimumSize (275, 116); // resize (275, 300); } @@ -448,6 +456,7 @@ PlaylistWidget::setPixmaps (Skin *skin) m_shadebtn->setIcon (skin->getIcon (Skin::BUTTON_PLS_SHADE)); m_controls->setNumbers (skin->getSmallNumbers ()); + m_controls->setPixmapFont (skin->getPixmapFont ()); setActive (m_active);