[vlc-devel] [RFC 51/82] qt: add medialibrary albumtrack model

Pierre Lamot pierre at videolabs.io
Fri Feb 1 14:01:55 CET 2019


---
 modules/gui/qt/Makefile.am                    |   6 +
 .../components/mediacenter/mlalbumtrack.cpp   | 133 +++++++++++++
 .../components/mediacenter/mlalbumtrack.hpp   |  81 ++++++++
 .../mediacenter/mlalbumtrackmodel.cpp         | 179 ++++++++++++++++++
 .../mediacenter/mlalbumtrackmodel.hpp         |  53 ++++++
 5 files changed, 452 insertions(+)
 create mode 100644 modules/gui/qt/components/mediacenter/mlalbumtrack.cpp
 create mode 100644 modules/gui/qt/components/mediacenter/mlalbumtrack.hpp
 create mode 100644 modules/gui/qt/components/mediacenter/mlalbumtrackmodel.cpp
 create mode 100644 modules/gui/qt/components/mediacenter/mlalbumtrackmodel.hpp

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index a7b5cb5d30..0277acdf4a 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -128,6 +128,10 @@ libqt_plugin_la_SOURCES = \
 	gui/qt/components/mediacenter/mlalbum.hpp \
 	gui/qt/components/mediacenter/mlalbummodel.cpp \
 	gui/qt/components/mediacenter/mlalbummodel.hpp \
+	gui/qt/components/mediacenter/mlalbumtrack.cpp \
+	gui/qt/components/mediacenter/mlalbumtrack.hpp \
+	gui/qt/components/mediacenter/mlalbumtrackmodel.cpp \
+	gui/qt/components/mediacenter/mlalbumtrackmodel.hpp \
 	gui/qt/components/playlist/media.hpp \
 	gui/qt/components/playlist/playlist_common.cpp \
 	gui/qt/components/playlist/playlist_common.hpp \
@@ -253,6 +257,8 @@ nodist_libqt_plugin_la_SOURCES = \
 	gui/qt/components/mediacenter/mlbasemodel.moc.cpp \
 	gui/qt/components/mediacenter/mlalbum.moc.cpp \
 	gui/qt/components/mediacenter/mlalbummodel.moc.cpp \
+	gui/qt/components/mediacenter/mlalbumtrack.moc.cpp \
+	gui/qt/components/mediacenter/mlalbumtrackmodel.moc.cpp \
 	gui/qt/components/playlist/playlist_common.moc.cpp \
 	gui/qt/components/playlist/playlist_item.moc.cpp \
 	gui/qt/components/playlist/playlist_model.moc.cpp \
diff --git a/modules/gui/qt/components/mediacenter/mlalbumtrack.cpp b/modules/gui/qt/components/mediacenter/mlalbumtrack.cpp
new file mode 100644
index 0000000000..00706aa72f
--- /dev/null
+++ b/modules/gui/qt/components/mediacenter/mlalbumtrack.cpp
@@ -0,0 +1,133 @@
+/*****************************************************************************
+ * Copyright (C) 2019 VLC authors and VideoLAN
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include <cassert>
+#include "mlalbumtrack.hpp"
+#include "mlhelper.hpp"
+
+MLAlbumTrack::MLAlbumTrack(vlc_medialibrary_t* _ml, const vlc_ml_media_t *_data, QObject *_parent )
+    : QObject( _parent )
+    , m_id         ( _data->i_id, VLC_ML_PARENT_UNKNOWN )
+    , m_title      ( QString::fromUtf8( _data->psz_title ) )
+    , m_trackNumber( _data->album_track.i_track_nb )
+    , m_discNumber( _data->album_track.i_disc_nb )
+{
+    assert( _data );
+    assert( _data->i_type == VLC_ML_MEDIA_TYPE_AUDIO );
+
+    int t_sec = _data->i_duration / 1000000;
+    int sec = t_sec % 60;
+    int min = (t_sec / 60) % 60;
+    int hour = t_sec / 3600;
+    if (hour == 0)
+        m_duration = QString("%1:%2")
+                .arg(min, 2, 10, QChar('0'))
+                .arg(sec, 2, 10, QChar('0'));
+    else
+        m_duration = QString("%1:%2:%3")
+                .arg(hour, 2, 10, QChar('0'))
+                .arg(min, 2, 10, QChar('0'))
+                .arg(sec, 2, 10, QChar('0'));
+
+    for( const vlc_ml_file_t& file: ml_range_iterate<vlc_ml_file_t>( _data->p_files ) )
+        if( file.i_type == VLC_ML_FILE_TYPE_MAIN )
+        {
+            //FIXME should we store every mrl
+            m_mrl = QString::fromUtf8(file.psz_mrl);
+            break;
+        }
+
+    if ( _data->album_track.i_album_id != 0 )
+    {
+        ml_unique_ptr<vlc_ml_album_t> album(vlc_ml_get_album(_ml, _data->album_track.i_album_id));
+        if (album)
+             m_albumTitle =  album->psz_title;
+    }
+
+    if ( _data->album_track.i_artist_id != 0 )
+    {
+        ml_unique_ptr<vlc_ml_artist_t> artist(vlc_ml_get_artist(_ml, _data->album_track.i_artist_id));
+        if (artist)
+             m_artist =  artist->psz_name;
+    }
+}
+
+MLAlbumTrack::MLAlbumTrack(const MLAlbumTrack &albumtrack, QObject *_parent)
+    : QObject( _parent )
+    , m_id         ( albumtrack.m_id )
+    , m_title      ( albumtrack.m_title )
+    , m_albumTitle ( albumtrack.m_albumTitle )
+    , m_artist     ( albumtrack.m_artist )
+    , m_cover      ( albumtrack.m_cover )
+    , m_trackNumber( albumtrack.m_trackNumber )
+    , m_discNumber ( albumtrack.m_discNumber )
+    , m_duration   ( albumtrack.m_duration )
+    , m_mrl        ( albumtrack.m_mrl )
+{
+}
+
+MLParentId MLAlbumTrack::getId() const
+{
+    return m_id;
+}
+
+QString MLAlbumTrack::getTitle() const
+{
+    return m_title;
+}
+
+QString MLAlbumTrack::getAlbumTitle() const
+{
+    return m_albumTitle;
+}
+
+QString MLAlbumTrack::getArtist() const
+{
+    return m_artist;
+}
+
+QString MLAlbumTrack::getCover() const
+{
+    return m_cover;
+}
+
+unsigned int MLAlbumTrack::getTrackNumber() const
+{
+    return m_trackNumber;
+}
+
+unsigned int MLAlbumTrack::getDiscNumber() const
+{
+    return m_discNumber;
+}
+
+QString MLAlbumTrack::getDuration() const
+{
+    return m_duration;
+}
+
+QString MLAlbumTrack::getMRL() const
+{
+    return m_mrl;
+}
+
+MLAlbumTrack *MLAlbumTrack::clone(QObject *parent) const
+{
+    return new MLAlbumTrack(*this, parent);
+}
+
diff --git a/modules/gui/qt/components/mediacenter/mlalbumtrack.hpp b/modules/gui/qt/components/mediacenter/mlalbumtrack.hpp
new file mode 100644
index 0000000000..884419173f
--- /dev/null
+++ b/modules/gui/qt/components/mediacenter/mlalbumtrack.hpp
@@ -0,0 +1,81 @@
+/*****************************************************************************
+ * Copyright (C) 2019 VLC authors and VideoLAN
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#pragma once
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "vlc_common.h"
+
+#include <QObject>
+#include <QString>
+#include <memory>
+
+#include <vlc_media_library.h>
+#include "mlhelper.hpp"
+#include "mlqmltypes.hpp"
+
+class MLAlbumTrack : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(MLParentId id READ getId CONSTANT)
+    Q_PROPERTY(QString title READ getTitle CONSTANT)
+    Q_PROPERTY(QString album_title READ getAlbumTitle CONSTANT)
+    Q_PROPERTY(QString main_artist READ getArtist CONSTANT)
+    Q_PROPERTY(QString cover READ getCover CONSTANT)
+    Q_PROPERTY(unsigned int track_number READ getTrackNumber CONSTANT)
+    Q_PROPERTY(unsigned int disc_number READ getDiscNumber CONSTANT)
+    Q_PROPERTY(QString duration READ getDuration CONSTANT)
+    Q_PROPERTY(QString mrl READ getMRL CONSTANT)
+
+public:
+    MLAlbumTrack(vlc_medialibrary_t *_ml, const vlc_ml_media_t *_data, QObject *_parent = nullptr);
+
+    MLParentId getId() const;
+    QString getTitle() const;
+    QString getAlbumTitle() const;
+    QString getArtist() const;
+    QString getCover() const;
+    unsigned int getTrackNumber() const;
+    unsigned int getDiscNumber() const;
+    QString getDuration() const;
+    QString getMRL() const;
+
+    MLAlbumTrack* clone(QObject *parent = nullptr) const;
+
+private:
+    MLAlbumTrack(const MLAlbumTrack& albumtrack, QObject *_parent = nullptr);
+
+    MLParentId m_id;
+    QString m_title;
+    QString m_albumTitle;
+    QString m_artist;
+    QString m_cover;
+    unsigned int m_trackNumber;
+    unsigned int m_discNumber;
+    QString m_duration;
+    QString m_mrl;
+
+   ml_unique_ptr<vlc_ml_media_t> m_data;
+
+signals:
+
+public slots:
+};
diff --git a/modules/gui/qt/components/mediacenter/mlalbumtrackmodel.cpp b/modules/gui/qt/components/mediacenter/mlalbumtrackmodel.cpp
new file mode 100644
index 0000000000..2b5be88f01
--- /dev/null
+++ b/modules/gui/qt/components/mediacenter/mlalbumtrackmodel.cpp
@@ -0,0 +1,179 @@
+/*****************************************************************************
+ * Copyright (C) 2019 VLC authors and VideoLAN
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include "mlalbumtrackmodel.hpp"
+
+namespace {
+
+enum Role {
+    TRACK_ID = Qt::UserRole + 1,
+    TRACK_TITLE,
+    TRACK_COVER,
+    TRACK_NUMBER,
+    TRACK_DISC_NUMBER,
+    TRACK_DURATION,
+    TRACK_ALBUM,
+    TRACK_ARTIST,
+};
+
+}
+
+QHash<QByteArray, vlc_ml_sorting_criteria_t> MLAlbumTrackModel::M_names_to_criteria = {
+    {"id", VLC_ML_SORTING_DEFAULT},
+    {"title", VLC_ML_SORTING_ALPHA},
+    {"album_title", VLC_ML_SORTING_ALBUM},
+    {"track_number", VLC_ML_SORTING_TRACKNUMBER},
+    {"release_year", VLC_ML_SORTING_RELEASEDATE},
+    {"main_artist", VLC_ML_SORTING_ARTIST},
+    {"duration", VLC_ML_SORTING_DURATION}
+};
+
+MLAlbumTrackModel::MLAlbumTrackModel(QObject *parent)
+    : MLSlidingWindowModel<MLAlbumTrack>(parent)
+{
+}
+
+QVariant MLAlbumTrackModel::data(const QModelIndex &index, int role) const
+{
+    if (!index.isValid() || index.row() < 0)
+        return QVariant();
+
+    const MLAlbumTrack* ml_track = item(static_cast<unsigned int>(index.row()));
+    if ( !ml_track )
+        return QVariant();
+
+    switch (role)
+    {
+    // Tracks
+    case TRACK_ID:
+        return QVariant::fromValue( ml_track->getId() );
+    case TRACK_TITLE :
+        return QVariant::fromValue( ml_track->getTitle() );
+    case TRACK_COVER :
+        return QVariant::fromValue( ml_track->getCover() );
+    case TRACK_NUMBER :
+        return QVariant::fromValue( ml_track->getTrackNumber() );
+    case TRACK_DISC_NUMBER:
+        return QVariant::fromValue( ml_track->getDiscNumber() );
+    case TRACK_DURATION :
+        return QVariant::fromValue( ml_track->getDuration() );
+    case TRACK_ALBUM:
+        return QVariant::fromValue( ml_track->getAlbumTitle() );
+    case TRACK_ARTIST:
+        return QVariant::fromValue( ml_track->getArtist() );
+    default :
+        return QVariant();
+    }
+}
+
+QHash<int, QByteArray> MLAlbumTrackModel::roleNames() const
+{
+    return {
+        { TRACK_ID, "id" },
+        { TRACK_TITLE, "title" },
+        { TRACK_COVER, "cover" },
+        { TRACK_NUMBER, "track_number" },
+        { TRACK_DISC_NUMBER, "disc_number" },
+        { TRACK_DURATION, "duration" },
+        { TRACK_ALBUM, "album_title"},
+        { TRACK_ARTIST, "main_artist"},
+    };
+}
+
+size_t MLAlbumTrackModel::countTotalElements() const
+{
+    auto queryParams = m_query_param;
+    queryParams.i_offset = 0;
+    queryParams.i_nbResults = 0;
+    if ( m_parent.id <= 0 )
+        return vlc_ml_count_audio_media(m_ml, &queryParams);
+    return vlc_ml_count_media_of(m_ml, &queryParams, m_parent.type, m_parent.id );
+}
+
+std::vector<std::unique_ptr<MLAlbumTrack>> MLAlbumTrackModel::fetch()
+{
+    ml_unique_ptr<vlc_ml_media_list_t> media_list;
+
+    if ( m_parent.id <= 0 )
+        media_list.reset( vlc_ml_list_audio_media(m_ml, &m_query_param) );
+    else
+        media_list.reset( vlc_ml_list_media_of(m_ml, &m_query_param, m_parent.type, m_parent.id ) );
+    if ( media_list == nullptr )
+        return {};
+    std::vector<std::unique_ptr<MLAlbumTrack>> res;
+    for( const vlc_ml_media_t& media: ml_range_iterate<vlc_ml_media_t>( media_list ) )
+        res.emplace_back( std::unique_ptr<MLAlbumTrack>{ new MLAlbumTrack( m_ml, &media ) } );
+    return res;
+}
+
+vlc_ml_sorting_criteria_t MLAlbumTrackModel::roleToCriteria(int role) const
+{
+    switch (role) {
+    case TRACK_TITLE :
+        return VLC_ML_SORTING_ALPHA;
+    case TRACK_NUMBER :
+        return VLC_ML_SORTING_TRACKNUMBER;
+    case TRACK_DURATION :
+        return VLC_ML_SORTING_DURATION;
+    default:
+        return VLC_ML_SORTING_DEFAULT;
+    }
+}
+
+vlc_ml_sorting_criteria_t MLAlbumTrackModel::nameToCriteria(QByteArray name) const
+{
+    return M_names_to_criteria.value(name, VLC_ML_SORTING_DEFAULT);
+}
+
+QByteArray MLAlbumTrackModel::criteriaToName(vlc_ml_sorting_criteria_t criteria) const
+{
+    return M_names_to_criteria.key(criteria, "");
+}
+
+void MLAlbumTrackModel::onVlcMlEvent(const vlc_ml_event_t* event)
+{
+    switch (event->i_type)
+    {
+        case VLC_ML_EVENT_MEDIA_ADDED:
+        case VLC_ML_EVENT_MEDIA_UPDATED:
+            if ( event->modification.p_media->i_subtype == VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK )
+                m_need_reset = true;
+            break;
+        case VLC_ML_EVENT_MEDIA_DELETED:
+            // FIXME: Not optimal, this will trigger a clean/refresh for video
+            // media as well, but this needs fixing in the medialibrary
+            m_need_reset = true;
+            break;
+        case VLC_ML_EVENT_ALBUM_UPDATED:
+            if ( m_parent.id != 0 && m_parent.type == VLC_ML_PARENT_ALBUM &&
+                 m_parent.id == event->modification.p_album->i_id )
+                m_need_reset = true;
+            break;
+        case VLC_ML_EVENT_ALBUM_DELETED:
+            if ( m_parent.id != 0 && m_parent.type == VLC_ML_PARENT_ALBUM &&
+                 m_parent.id == event->deletion.i_entity_id )
+                m_need_reset = true;
+            break;
+        case VLC_ML_EVENT_GENRE_DELETED:
+            if ( m_parent.id != 0 && m_parent.type == VLC_ML_PARENT_GENRE &&
+                 m_parent.id == event->deletion.i_entity_id )
+                m_need_reset = true;
+            break;
+    }
+    MLBaseModel::onVlcMlEvent( event );
+}
diff --git a/modules/gui/qt/components/mediacenter/mlalbumtrackmodel.hpp b/modules/gui/qt/components/mediacenter/mlalbumtrackmodel.hpp
new file mode 100644
index 0000000000..4314ff229a
--- /dev/null
+++ b/modules/gui/qt/components/mediacenter/mlalbumtrackmodel.hpp
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (C) 2019 VLC authors and VideoLAN
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef MLTRACKMODEL_HPP
+#define MLTRACKMODEL_HPP
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <QObject>
+#include "mlbasemodel.hpp"
+#include "mlalbumtrack.hpp"
+
+
+class MLAlbumTrackModel : public MLSlidingWindowModel<MLAlbumTrack>
+{
+    Q_OBJECT
+
+public:
+    explicit MLAlbumTrackModel(QObject *parent = nullptr);
+
+    virtual ~MLAlbumTrackModel() = default;
+
+    QVariant data(const QModelIndex &index, int role) const override;
+    QHash<int, QByteArray> roleNames() const override;
+
+private:
+    std::vector<std::unique_ptr<MLAlbumTrack>> fetch() override;
+    size_t countTotalElements() const override;
+    vlc_ml_sorting_criteria_t roleToCriteria(int role) const override;
+    vlc_ml_sorting_criteria_t nameToCriteria(QByteArray name) const override;
+    QByteArray criteriaToName(vlc_ml_sorting_criteria_t criteria) const override;
+    virtual void onVlcMlEvent( const vlc_ml_event_t* event ) override;
+
+    static QHash<QByteArray, vlc_ml_sorting_criteria_t> M_names_to_criteria;
+};
+#endif // MLTRACKMODEL_HPP
-- 
2.19.1



More information about the vlc-devel mailing list