Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (15)
Showing
with 1023 additions and 73 deletions
......@@ -334,9 +334,11 @@ typedef struct vlc_ml_playlist_list_t
typedef struct vlc_ml_folder_t
{
int64_t i_id; /**< This folder's MRL. Will be NULL if b_present is false */
char* psz_mrl; /**< This folder's MRL. Will be NULL if b_present is false */
bool b_present; /**< The presence state for this folder. */
int64_t i_id; /**< The folder's MRL. Will be NULL if b_present is false */
char* psz_name; /**< The folder's name */
char* psz_mrl; /**< The folder's MRL. Will be NULL if b_present is false */
unsigned int i_nb_media; /**< The media count */
bool b_present; /**< The folder's presence state */
bool b_banned; /**< Will be true if the user required this folder to be excluded */
} vlc_ml_folder_t;
......@@ -443,6 +445,8 @@ enum vlc_ml_list_queries
VLC_ML_COUNT_ENTRY_POINTS, /**< arg1 bool: list_banned; arg2 (out): size_t* */
VLC_ML_LIST_FOLDERS, /**< arg1 (out): vlc_ml_folder_list_t** */
VLC_ML_COUNT_FOLDERS, /**< arg1 (out): size_t* */
VLC_ML_LIST_FOLDERS_BY_TYPE, /**< arg1 vlc_ml_media_type_t: the media type. arg2 (out): vlc_ml_media_list_t** */
VLC_ML_COUNT_FOLDERS_BY_TYPE, /**< arg1 vlc_ml_media_type_t: the media type. arg2 (out): vlc_ml_media_list_t** */
/* Album specific listings */
VLC_ML_LIST_ALBUM_TRACKS, /**< arg1: The album id. arg2 (out): vlc_ml_media_list_t** */
......@@ -484,12 +488,16 @@ enum vlc_ml_list_queries
/* Folder specific listings */
VLC_ML_LIST_SUBFOLDERS, /**< arg1: parent id; arg2 (out): vlc_ml_folder_list_t** */
VLC_ML_COUNT_SUBFOLDERS, /**< arg1: parent id; arg2 (out): size_t* */
VLC_ML_LIST_FOLDER_MEDIAS, /**< arg1: folder id; arg2 (out): vlc_ml_media_list_t** */
VLC_ML_COUNT_FOLDER_MEDIAS, /**< arg1: folder id; arg2 (out): size_t* */
VLC_ML_LIST_FOLDER_MEDIA, /**< arg1: folder id; arg2 (out): vlc_ml_media_list_t** */
VLC_ML_COUNT_FOLDER_MEDIA, /**< arg1: folder id; arg2 (out): size_t* */
/* Children entities listing */
VLC_ML_LIST_MEDIA_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): ml_media_list_t** */
VLC_ML_COUNT_MEDIA_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): size_t* */
VLC_ML_LIST_VIDEO_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): size_t* */
VLC_ML_COUNT_VIDEO_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): size_t* */
VLC_ML_LIST_AUDIO_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): size_t* */
VLC_ML_COUNT_AUDIO_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): size_t* */
VLC_ML_LIST_ARTISTS_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): ml_artist_list_t** */
VLC_ML_COUNT_ARTISTS_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): size_t* */
VLC_ML_LIST_ALBUMS_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): ml_album_list_t** */
......@@ -504,6 +512,7 @@ enum vlc_ml_parent_type
VLC_ML_PARENT_SHOW,
VLC_ML_PARENT_GENRE,
VLC_ML_PARENT_GROUP,
VLC_ML_PARENT_FOLDER,
VLC_ML_PARENT_PLAYLIST,
};
......@@ -1209,6 +1218,66 @@ static inline size_t vlc_ml_count_media_of( vlc_medialibrary_t* p_ml, const vlc_
return res;
}
static inline vlc_ml_media_list_t* vlc_ml_list_video_of( vlc_medialibrary_t* p_ml,
const vlc_ml_query_params_t* params,
int i_parent_type, int64_t i_parent_id )
{
vlc_assert( p_ml != NULL );
vlc_ml_media_list_t* res;
if ( vlc_ml_list( p_ml, VLC_ML_LIST_VIDEO_OF,
params, i_parent_type, i_parent_id, &res ) != VLC_SUCCESS )
return NULL;
return res;
}
static inline size_t vlc_ml_count_video_of( vlc_medialibrary_t* p_ml,
const vlc_ml_query_params_t* params,
int i_parent_type, int64_t i_parent_id )
{
vlc_assert( p_ml != NULL );
size_t res;
if ( vlc_ml_list( p_ml, VLC_ML_COUNT_VIDEO_OF,
params, i_parent_type, i_parent_id, &res ) != VLC_SUCCESS )
return 0;
return res;
}
static inline vlc_ml_media_list_t* vlc_ml_list_audio_of( vlc_medialibrary_t* p_ml,
const vlc_ml_query_params_t* params,
int i_parent_type, int64_t i_parent_id )
{
vlc_assert( p_ml != NULL );
vlc_ml_media_list_t* res;
if ( vlc_ml_list( p_ml, VLC_ML_LIST_AUDIO_OF,
params, i_parent_type, i_parent_id, &res ) != VLC_SUCCESS )
return NULL;
return res;
}
static inline size_t vlc_ml_count_audio_of( vlc_medialibrary_t* p_ml,
const vlc_ml_query_params_t* params,
int i_parent_type, int64_t i_parent_id )
{
vlc_assert( p_ml != NULL );
size_t res;
if ( vlc_ml_list( p_ml, VLC_ML_COUNT_AUDIO_OF,
params, i_parent_type, i_parent_id, &res ) != VLC_SUCCESS )
return 0;
return res;
}
static inline vlc_ml_artist_list_t* vlc_ml_list_artist_of( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int i_parent_type, int64_t i_parent_id )
{
vlc_assert( p_ml != NULL );
......@@ -1693,6 +1762,93 @@ static inline size_t vlc_ml_count_banned_entry_points( vlc_medialibrary_t* p_ml,
return res;
}
// Folders
static inline vlc_ml_folder_list_t * vlc_ml_list_folders(vlc_medialibrary_t * p_ml,
const vlc_ml_query_params_t * params)
{
vlc_assert(p_ml != NULL);
vlc_ml_folder_list_t * res;
if (vlc_ml_list(p_ml, VLC_ML_LIST_FOLDERS, params, &res) != VLC_SUCCESS)
return NULL;
return res;
}
static inline size_t vlc_ml_count_folders(vlc_medialibrary_t * p_ml,
const vlc_ml_query_params_t * params)
{
vlc_assert(p_ml != NULL);
size_t count;
if (vlc_ml_list(p_ml, VLC_ML_COUNT_FOLDERS, params, &count) != VLC_SUCCESS)
return 0;
return count;
}
static inline
vlc_ml_folder_list_t * vlc_ml_list_folders_by_type(vlc_medialibrary_t * p_ml,
const vlc_ml_query_params_t * params,
vlc_ml_media_type_t type)
{
vlc_assert(p_ml != NULL);
vlc_ml_folder_list_t * res;
if (vlc_ml_list(p_ml, VLC_ML_LIST_FOLDERS_BY_TYPE, params, (int) type, &res) != VLC_SUCCESS)
return NULL;
return res;
}
static inline size_t vlc_ml_count_folders_by_type(vlc_medialibrary_t * p_ml,
const vlc_ml_query_params_t * params,
vlc_ml_media_type_t type)
{
vlc_assert(p_ml != NULL);
size_t count;
if (vlc_ml_list(p_ml, VLC_ML_COUNT_FOLDERS_BY_TYPE, params, (int) type, &count) != VLC_SUCCESS)
return 0;
return count;
}
// Folder Media
static inline vlc_ml_media_list_t * vlc_ml_list_folder_media(vlc_medialibrary_t * p_ml,
const vlc_ml_query_params_t * params,
int64_t i_folder_id)
{
vlc_assert(p_ml != NULL);
vlc_ml_media_list_t * res;
if (vlc_ml_list(p_ml, VLC_ML_LIST_FOLDER_MEDIA, params, i_folder_id, &res) != VLC_SUCCESS)
return NULL;
return res;
}
static inline size_t vlc_ml_count_folder_media(vlc_medialibrary_t * p_ml,
const vlc_ml_query_params_t * params,
int64_t i_folder_id)
{
vlc_assert(p_ml != NULL);
size_t count;
if (vlc_ml_list(p_ml, VLC_ML_COUNT_FOLDER_MEDIA, params, i_folder_id, &count) != VLC_SUCCESS)
return 0;
return count;
}
#ifdef __cplusplus
}
#endif /* C++ */
......
......@@ -162,6 +162,8 @@ libqt_plugin_la_SOURCES = \
gui/qt/medialibrary/mlbookmarkmodel.cpp \
gui/qt/medialibrary/mlbookmarkmodel.hpp \
gui/qt/medialibrary/mlevent.hpp \
gui/qt/medialibrary/mlfolder.cpp \
gui/qt/medialibrary/mlfolder.hpp \
gui/qt/medialibrary/mlfoldersmodel.cpp \
gui/qt/medialibrary/mlfoldersmodel.hpp \
gui/qt/medialibrary/mlgenre.cpp \
......@@ -170,8 +172,6 @@ libqt_plugin_la_SOURCES = \
gui/qt/medialibrary/mlgenremodel.hpp \
gui/qt/medialibrary/mlgroup.cpp \
gui/qt/medialibrary/mlgroup.hpp \
gui/qt/medialibrary/mlgrouplistmodel.cpp \
gui/qt/medialibrary/mlgrouplistmodel.hpp \
gui/qt/medialibrary/mlhelper.cpp \
gui/qt/medialibrary/mlhelper.hpp \
gui/qt/medialibrary/mlitemcover.cpp \
......@@ -191,6 +191,10 @@ libqt_plugin_la_SOURCES = \
gui/qt/medialibrary/mlurlmodel.hpp \
gui/qt/medialibrary/mlvideo.cpp \
gui/qt/medialibrary/mlvideo.hpp \
gui/qt/medialibrary/mlvideofoldersmodel.cpp \
gui/qt/medialibrary/mlvideofoldersmodel.hpp \
gui/qt/medialibrary/mlvideogroupsmodel.cpp \
gui/qt/medialibrary/mlvideogroupsmodel.hpp \
gui/qt/medialibrary/mlvideomodel.cpp \
gui/qt/medialibrary/mlvideomodel.hpp \
gui/qt/medialibrary/mlplaylist.cpp \
......@@ -391,7 +395,6 @@ nodist_libqt_plugin_la_SOURCES = \
gui/qt/medialibrary/mlbasemodel.moc.cpp \
gui/qt/medialibrary/mlfoldersmodel.moc.cpp \
gui/qt/medialibrary/mlgenremodel.moc.cpp \
gui/qt/medialibrary/mlgrouplistmodel.moc.cpp \
gui/qt/medialibrary/mllistcache.moc.cpp \
gui/qt/medialibrary/mlthreadpool.moc.cpp \
gui/qt/medialibrary/mlqmltypes.moc.cpp \
......@@ -402,6 +405,8 @@ nodist_libqt_plugin_la_SOURCES = \
gui/qt/medialibrary/mlvideomodel.moc.cpp \
gui/qt/medialibrary/mlplaylistlistmodel.moc.cpp \
gui/qt/medialibrary/mlplaylistmodel.moc.cpp \
gui/qt/medialibrary/mlvideofoldersmodel.moc.cpp \
gui/qt/medialibrary/mlvideogroupsmodel.moc.cpp \
gui/qt/menus/custom_menus.moc.cpp \
gui/qt/menus/qml_menu_wrapper.moc.cpp \
gui/qt/menus/menus.moc.cpp \
......
......@@ -13,7 +13,8 @@
#include "medialibrary/mlrecentsmodel.hpp"
#include "medialibrary/mlrecentsvideomodel.hpp"
#include "medialibrary/mlfoldersmodel.hpp"
#include "medialibrary/mlgrouplistmodel.hpp"
#include "medialibrary/mlvideogroupsmodel.hpp"
#include "medialibrary/mlvideofoldersmodel.hpp"
#include "medialibrary/mlplaylistlistmodel.hpp"
#include "medialibrary/mlplaylistmodel.hpp"
#include "medialibrary/mlplaylist.hpp"
......@@ -324,7 +325,8 @@ void MainUI::registerQMLTypes()
qmlRegisterType<MLUrlModel>( uri, versionMajor, versionMinor, "MLUrlModel" );
qmlRegisterType<MLVideoModel>( uri, versionMajor, versionMinor, "MLVideoModel" );
qmlRegisterType<MLRecentsVideoModel>( uri, versionMajor, versionMinor, "MLRecentsVideoModel" );
qmlRegisterType<MLGroupListModel>( uri, versionMajor, versionMinor, "MLGroupListModel" );
qmlRegisterType<MLVideoGroupsModel>( uri, versionMajor, versionMinor, "MLVideoGroupsModel" );
qmlRegisterType<MLVideoFoldersModel>( uri, versionMajor, versionMinor, "MLVideoFoldersModel" );
qmlRegisterType<MLPlaylistListModel>( uri, versionMajor, versionMinor, "MLPlaylistListModel" );
qmlRegisterType<MLPlaylistModel>( uri, versionMajor, versionMinor, "MLPlaylistModel" );
......@@ -347,7 +349,8 @@ void MainUI::registerQMLTypes()
qmlRegisterType<AlbumTrackContextMenu>( uri, versionMajor, versionMinor, "AlbumTrackContextMenu" );
qmlRegisterType<URLContextMenu>( uri, versionMajor, versionMinor, "URLContextMenu" );
qmlRegisterType<VideoContextMenu>( uri, versionMajor, versionMinor, "VideoContextMenu" );
qmlRegisterType<GroupListContextMenu>( uri, versionMajor, versionMinor, "GroupListContextMenu" );
qmlRegisterType<VideoGroupsContextMenu>( uri, versionMajor, versionMinor, "VideoGroupsContextMenu" );
qmlRegisterType<VideoFoldersContextMenu>( uri, versionMajor, versionMinor, "VideoFoldersContextMenu" );
qmlRegisterType<PlaylistListContextMenu>( uri, versionMajor, versionMinor, "PlaylistListContextMenu" );
qmlRegisterType<PlaylistMediaContextMenu>( uri, versionMajor, versionMinor, "PlaylistMediaContextMenu" );
......
......@@ -36,8 +36,10 @@
#include "mlqueryparams.hpp"
#include "util/listcacheloader.hpp"
// Fordward declarations
class MLListCache;
class MediaLib;
class MLItemCover;
class MLBaseModel : public QAbstractListModel
{
......@@ -172,6 +174,9 @@ protected:
bool m_need_reset = false;
mutable std::unique_ptr<MLListCache> m_cache;
private: // Friends
friend QString getVideoListCover(const MLBaseModel*, MLItemCover*, int, int, int);
};
#endif // MLBASEMODEL_HPP
/*****************************************************************************
* Copyright (C) 2021 VLC authors and VideoLAN
*
* Authors: Benjamin Arnaud <bunjee@omega.gg>
*
* 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 "mlfolder.hpp"
// Ctor / dtor
MLFolder::MLFolder(const vlc_ml_folder_t * data)
: MLItemCover(MLItemId(data->i_id, VLC_ML_PARENT_FOLDER))
, m_present(data->b_present)
, m_banned(data->b_banned)
, m_title(data->psz_name)
, m_mrl(data->psz_mrl)
, m_duration(0) // FIXME: We should have a duration field in vlc_ml_folder_t.
, m_count(data->i_nb_media) {}
// Interface
bool MLFolder::isPresent() const
{
return m_present;
}
bool MLFolder::isBanned() const
{
return m_banned;
}
QString MLFolder::getTitle() const
{
return m_title;
}
QString MLFolder::getMRL() const
{
return m_mrl;
}
int64_t MLFolder::getDuration() const
{
return m_duration;
}
unsigned int MLFolder::getCount() const
{
return m_count;
}
/*****************************************************************************
* Copyright (C) 2021 VLC authors and VideoLAN
*
* Authors: Benjamin Arnaud <bunjee@omega.gg>
*
* 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 MLFOLDER_HPP
#define MLFOLDER_HPP
// MediaLibrary includes
#include "mlitemcover.hpp"
class MLFolder : public MLItemCover
{
public:
MLFolder(const vlc_ml_folder_t * data);
public: // Interface
bool isPresent() const;
bool isBanned() const;
QString getTitle() const;
QString getMRL() const;
int64_t getDuration() const;
unsigned int getCount() const;
private:
bool m_present;
bool m_banned;
QString m_title;
QString m_mrl;
int64_t m_duration;
unsigned int m_count;
};
#endif
......@@ -18,6 +18,10 @@
#include "mlhelper.hpp"
// MediaLibrary includes
#include "mlbasemodel.hpp"
#include "mlitemcover.hpp"
QString MsToString( int64_t time , bool doShort )
{
if (time < 0)
......@@ -42,3 +46,59 @@ QString MsToString( int64_t time , bool doShort )
.arg(sec, 2, 10, QChar('0'));
}
QString getVideoListCover( const MLBaseModel* model, MLItemCover* item, int width, int height,
int role )
{
QString cover = item->getCover();
// NOTE: Making sure we're not already generating a cover.
if (cover.isNull() == false || item->hasGenerator())
return cover;
MLItemId itemId = item->getId();
struct Context { QString cover; };
item->setGenerator(true);
model->ml()->runOnMLThread<Context>(model,
//ML thread
[itemId, width, height]
(vlc_medialibrary_t * ml, Context & ctx)
{
CoverGenerator generator{ ml, itemId };
generator.setSize(QSize(width, height));
generator.setDefaultThumbnail(":/noart_videoCover.svg");
if (generator.cachedFileAvailable())
ctx.cover = generator.cachedFileURL();
else
ctx.cover = generator.execute();
},
//UI Thread
[model, itemId, role]
(quint64, Context & ctx)
{
int row;
// NOTE: We want to avoid calling 'MLBaseModel::item' for performance issues.
auto item = static_cast<MLItemCover *>(model->findInCache(itemId, &row));
if (!item)
return;
item->setCover(ctx.cover);
item->setGenerator(false);
QModelIndex modelIndex = model->index(row);
//we're running in a callback
emit const_cast<MLBaseModel *>(model)->dataChanged(modelIndex, modelIndex, { role });
});
return cover;
}
......@@ -28,6 +28,10 @@
#include "vlc_media_library.h"
#include <QString>
// Forward declarations
class MLBaseModel;
class MLItemCover;
template<typename T>
class MLDeleter
{
......@@ -73,4 +77,7 @@ MLListRange<T> ml_range_iterate(L& list)
QString MsToString( int64_t time, bool doShort = false );
QString getVideoListCover( const MLBaseModel* model, MLItemCover* item, int width, int height,
int role );
#endif // MLHELPER_HPP
......@@ -53,6 +53,7 @@ public:
ML_PARENT_TYPE_CASE(VLC_ML_PARENT_SHOW);
ML_PARENT_TYPE_CASE(VLC_ML_PARENT_GENRE);
ML_PARENT_TYPE_CASE(VLC_ML_PARENT_GROUP);
ML_PARENT_TYPE_CASE(VLC_ML_PARENT_FOLDER);
ML_PARENT_TYPE_CASE(VLC_ML_PARENT_PLAYLIST);
default:
return QString("UNKNOWN - %2").arg(id);
......
/*****************************************************************************
* Copyright (C) 2021 VLC authors and VideoLAN
*
* Authors: Benjamin Arnaud <bunjee@omega.gg>
*
* 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.
*****************************************************************************/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "mlvideofoldersmodel.hpp"
// VLC includes
#include <vlc_media_library.h>
// Util includes
#include "util/covergenerator.hpp"
// MediaLibrary includes
#include "mlhelper.hpp"
#include "mlfolder.hpp"
// Static variables
// NOTE: We multiply by 2 to cover most dpi settings.
static const int MLVIDEOFOLDERSMODEL_COVER_WIDTH = 512 * 2; // 16 / 10 ratio
static const int MLVIDEOFOLDERSMODEL_COVER_HEIGHT = 320 * 2;
static const QHash<QByteArray, vlc_ml_sorting_criteria_t> criterias =
{
{ "title", VLC_ML_SORTING_ALPHA },
{ "duration", VLC_ML_SORTING_DURATION }
};
// Ctor / dtor
/* explicit */ MLVideoFoldersModel::MLVideoFoldersModel(QObject * parent) : MLBaseModel(parent) {}
// MLBaseModel reimplementation
QHash<int, QByteArray> MLVideoFoldersModel::roleNames() const /* override */
{
return {
{ FOLDER_ID, "id" },
{ FOLDER_IS_NEW, "isNew" },
{ FOLDER_TITLE, "title" },
{ FOLDER_THUMBNAIL, "thumbnail" },
{ FOLDER_DURATION, "duration" },
{ FOLDER_PROGRESS, "progress" },
{ FOLDER_COUNT, "count"},
};
}
// Protected MLVideoModel implementation
QVariant MLVideoFoldersModel::itemRoleData(MLItem * item, const int role) const /* override */
{
if (item == nullptr)
return QVariant();
MLFolder * folder = static_cast<MLFolder *> (item);
switch (role)
{
// NOTE: This is the condition for QWidget view(s).
case Qt::DisplayRole:
return QVariant::fromValue(folder->getTitle());
// NOTE: These are the conditions for QML view(s).
case FOLDER_ID:
return QVariant::fromValue(folder->getId());
case FOLDER_TITLE:
return QVariant::fromValue(folder->getTitle());
case FOLDER_THUMBNAIL:
return getVideoListCover(this, folder, MLVIDEOFOLDERSMODEL_COVER_WIDTH,
MLVIDEOFOLDERSMODEL_COVER_HEIGHT, FOLDER_THUMBNAIL);
case FOLDER_DURATION:
return QVariant::fromValue(folder->getDuration());
case FOLDER_COUNT:
return QVariant::fromValue(folder->getCount());
default:
return QVariant();
}
}
vlc_ml_sorting_criteria_t MLVideoFoldersModel::roleToCriteria(int role) const /* override */
{
switch (role)
{
case FOLDER_TITLE:
return VLC_ML_SORTING_ALPHA;
case FOLDER_DURATION:
return VLC_ML_SORTING_DURATION;
default:
return VLC_ML_SORTING_DEFAULT;
}
}
vlc_ml_sorting_criteria_t MLVideoFoldersModel::nameToCriteria(QByteArray name) const /* override */
{
return criterias.value(name, VLC_ML_SORTING_DEFAULT);
}
QByteArray MLVideoFoldersModel::criteriaToName(vlc_ml_sorting_criteria_t criteria) const
/* override */
{
return criterias.key(criteria, "");
}
ListCacheLoader<std::unique_ptr<MLItem>> * MLVideoFoldersModel::createLoader() const /* override */
{
return new Loader(*this);
}
// Protected MLBaseModel reimplementation
void MLVideoFoldersModel::onVlcMlEvent(const MLEvent & event) /* override */
{
// FIXME: Add support for folder events once the MediaLibrary supports them.
MLBaseModel::onVlcMlEvent(event);
}
// Loader
MLVideoFoldersModel::Loader::Loader(const MLVideoFoldersModel & model)
: MLBaseModel::BaseLoader(model) {}
size_t MLVideoFoldersModel::Loader::count(vlc_medialibrary_t * ml) const /* override */
{
vlc_ml_query_params_t params = getParams().toCQueryParams();
return vlc_ml_count_folders_by_type(ml, &params, VLC_ML_MEDIA_TYPE_VIDEO);
}
std::vector<std::unique_ptr<MLItem>>
MLVideoFoldersModel::Loader::load(vlc_medialibrary_t * ml,
size_t index, size_t count) const /* override */
{
vlc_ml_query_params_t params = getParams(index, count).toCQueryParams();
ml_unique_ptr<vlc_ml_folder_list_t> list(vlc_ml_list_folders_by_type(ml, &params,
VLC_ML_MEDIA_TYPE_VIDEO));
if (list == nullptr)
return {};
std::vector<std::unique_ptr<MLItem>> result;
for (const vlc_ml_folder_t & folder : ml_range_iterate<vlc_ml_folder_t>(list))
{
result.emplace_back(std::make_unique<MLFolder>(&folder));
}
return result;
}
/*****************************************************************************
* Copyright (C) 2021 VLC authors and VideoLAN
*
* Authors: Benjamin Arnaud <bunjee@omega.gg>
*
* 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 MLVIDEOFOLDERSMODEL_HPP
#define MLVIDEOFOLDERSMODEL_HPP
// MediaLibrary includes
#include "mlvideomodel.hpp"
// Forward declarations
class MLFolder;
class MLVideoFoldersModel : public MLBaseModel
{
Q_OBJECT
public:
enum Roles
{
FOLDER_ID = Qt::UserRole + 1,
FOLDER_IS_NEW,
FOLDER_TITLE,
FOLDER_THUMBNAIL,
FOLDER_DURATION,
FOLDER_PROGRESS,
FOLDER_COUNT
};
public:
explicit MLVideoFoldersModel(QObject * parent = nullptr);
public: // MLBaseModel reimplementation
QHash<int, QByteArray> roleNames() const override;
protected:
QVariant itemRoleData(MLItem *item, int role = Qt::DisplayRole) 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;
ListCacheLoader<std::unique_ptr<MLItem>> * createLoader() const override;
protected: // MLBaseModel reimplementation
void onVlcMlEvent(const MLEvent & event) override;
private:
struct Loader : public BaseLoader
{
Loader(const MLVideoFoldersModel & model);
size_t count(vlc_medialibrary_t * ml) const override;
std::vector<std::unique_ptr<MLItem>> load(vlc_medialibrary_t * ml,
size_t index, size_t count) const override;
};
};
#endif // MLVIDEOFOLDERSMODEL_HPP
......@@ -22,7 +22,7 @@
# include "config.h"
#endif
#include "mlgrouplistmodel.hpp"
#include "mlvideogroupsmodel.hpp"
// VLC includes
#include <vlc_media_library.h>
......@@ -39,8 +39,8 @@
// Static variables
// NOTE: We multiply by 2 to cover most dpi settings.
static const int MLGROUPLISTMODEL_COVER_WIDTH = 512 * 2; // 16 / 10 ratio
static const int MLGROUPLISTMODEL_COVER_HEIGHT = 320 * 2;
static const int MLVIDEOGROUPSMODEL_COVER_WIDTH = 512 * 2; // 16 / 10 ratio
static const int MLVIDEOGROUPSMODEL_COVER_HEIGHT = 320 * 2;
static const QHash<QByteArray, vlc_ml_sorting_criteria_t> criterias =
{
......@@ -50,43 +50,29 @@ static const QHash<QByteArray, vlc_ml_sorting_criteria_t> criterias =
};
//=================================================================================================
// MLGroupListModel
// MLVideoGroupsModel
//=================================================================================================
/* explicit */ MLGroupListModel::MLGroupListModel(QObject * parent)
: MLBaseModel(parent) {}
/* explicit */ MLVideoGroupsModel::MLVideoGroupsModel(QObject * parent) : MLVideoModel(parent) {}
//-------------------------------------------------------------------------------------------------
// QAbstractItemModel implementation
// MLVideoModel reimplementation
//-------------------------------------------------------------------------------------------------
QHash<int, QByteArray> MLGroupListModel::roleNames() const /* override */
QHash<int, QByteArray> MLVideoGroupsModel::roleNames() const /* override */
{
return
{
{ GROUP_IS_VIDEO, "isVideo" },
{ GROUP_ID, "id" },
{ GROUP_TITLE, "title" },
{ GROUP_THUMBNAIL, "thumbnail" },
{ GROUP_DURATION, "duration" },
{ GROUP_DATE, "date" },
{ GROUP_COUNT, "count" },
// NOTE: Media specific.
{ GROUP_IS_NEW, "isNew" },
{ GROUP_FILENAME, "fileName" },
{ GROUP_PROGRESS, "progress" },
{ GROUP_PLAYCOUNT, "playcount" },
{ GROUP_RESOLUTION, "resolution_name" },
{ GROUP_CHANNEL, "channel" },
{ GROUP_MRL, "mrl" },
{ GROUP_MRL_DISPLAY, "display_mrl" },
{ GROUP_VIDEO_TRACK, "videoDesc" },
{ GROUP_AUDIO_TRACK, "audioDesc" },
{ GROUP_TITLE_FIRST_SYMBOL, "title_first_symbol" }
};
QHash<int, QByteArray> hash = MLVideoModel::roleNames();
hash.insert(GROUP_IS_VIDEO, "isVideo");
hash.insert(GROUP_DATE, "date");
hash.insert(GROUP_COUNT, "count");
return hash;
}
QVariant MLGroupListModel::itemRoleData(MLItem *item, const int role) const /* override */
// Protected MLVideoModel implementation
QVariant MLVideoGroupsModel::itemRoleData(MLItem * item, const int role) const /* override */
{
if (item == nullptr)
return QVariant();
......@@ -101,16 +87,17 @@ QVariant MLGroupListModel::itemRoleData(MLItem *item, const int role) const /* o
case Qt::DisplayRole:
return QVariant::fromValue(group->getTitle());
// NOTE: These are the conditions for QML view(s).
case GROUP_IS_VIDEO:
return false;
case GROUP_ID:
case VIDEO_ID:
return QVariant::fromValue(group->getId());
case GROUP_TITLE:
case VIDEO_TITLE:
return QVariant::fromValue(group->getTitle());
case GROUP_THUMBNAIL:
return getCover(group);
case GROUP_DURATION:
case VIDEO_THUMBNAIL:
return getVideoListCover(this, group, MLVIDEOGROUPSMODEL_COVER_WIDTH,
MLVIDEOGROUPSMODEL_COVER_HEIGHT, VIDEO_THUMBNAIL);
case VIDEO_DURATION:
return QVariant::fromValue(group->getDuration());
case GROUP_IS_VIDEO:
return false;
case GROUP_DATE:
return QVariant::fromValue(group->getDate());
case GROUP_COUNT:
......@@ -129,66 +116,24 @@ QVariant MLGroupListModel::itemRoleData(MLItem *item, const int role) const /* o
return QVariant::fromValue(video->getTitle());
case GROUP_IS_VIDEO:
return true;
case GROUP_ID:
return QVariant::fromValue(video->getId());
case GROUP_TITLE:
return QVariant::fromValue(video->getTitle());
case GROUP_THUMBNAIL:
{
vlc_ml_thumbnail_status_t status;
const QString thumbnail = video->getThumbnail(&status);
if (status == VLC_ML_THUMBNAIL_STATUS_MISSING || status == VLC_ML_THUMBNAIL_STATUS_FAILURE)
{
generateVideoThumbnail(item->getId().id);
}
return QVariant::fromValue( thumbnail );
}
case GROUP_DURATION:
return QVariant::fromValue(video->getDuration());
case GROUP_DATE:
return QVariant();
case GROUP_COUNT:
return 1;
// NOTE: Media specific.
case GROUP_IS_NEW:
return QVariant::fromValue(video->isNew());
case GROUP_FILENAME:
return QVariant::fromValue(video->getFileName());
case GROUP_PROGRESS:
return QVariant::fromValue(video->getProgress());
case GROUP_PLAYCOUNT:
return QVariant::fromValue(video->getPlayCount());
case GROUP_RESOLUTION:
return QVariant::fromValue(video->getResolutionName());
case GROUP_CHANNEL:
return QVariant::fromValue(video->getChannel());
case GROUP_MRL:
return QVariant::fromValue(video->getMRL());
case GROUP_MRL_DISPLAY:
return QVariant::fromValue(video->getDisplayMRL());
case GROUP_VIDEO_TRACK:
return QVariant::fromValue(video->getVideoDesc());
case GROUP_AUDIO_TRACK:
return QVariant::fromValue(video->getAudioDesc());
case GROUP_TITLE_FIRST_SYMBOL:
return QVariant::fromValue(getFirstSymbol(video->getTitle()));
default:
return QVariant();
return MLVideoModel::itemRoleData(item, role);
}
}
}
//-------------------------------------------------------------------------------------------------
// Protected MLBaseModel implementation
//-------------------------------------------------------------------------------------------------
vlc_ml_sorting_criteria_t MLGroupListModel::roleToCriteria(int role) const /* override */
vlc_ml_sorting_criteria_t MLVideoGroupsModel::roleToCriteria(int role) const /* override */
{
switch (role)
{
case GROUP_TITLE:
case VIDEO_TITLE:
return VLC_ML_SORTING_ALPHA;
case GROUP_DURATION:
case VIDEO_DURATION:
return VLC_ML_SORTING_DURATION;
case GROUP_DATE:
return VLC_ML_SORTING_INSERTIONDATE;
......@@ -197,93 +142,23 @@ vlc_ml_sorting_criteria_t MLGroupListModel::roleToCriteria(int role) const /* ov
}
}
vlc_ml_sorting_criteria_t MLGroupListModel::nameToCriteria(QByteArray name) const /* override */
vlc_ml_sorting_criteria_t MLVideoGroupsModel::nameToCriteria(QByteArray name) const /* override */
{
return criterias.value(name, VLC_ML_SORTING_DEFAULT);
}
QByteArray MLGroupListModel::criteriaToName(vlc_ml_sorting_criteria_t criteria) const
QByteArray MLVideoGroupsModel::criteriaToName(vlc_ml_sorting_criteria_t criteria) const
/* override */
{
return criterias.key(criteria, "");
}
//-------------------------------------------------------------------------------------------------
ListCacheLoader<std::unique_ptr<MLItem>> * MLGroupListModel::createLoader() const /* override */
ListCacheLoader<std::unique_ptr<MLItem>> * MLVideoGroupsModel::createLoader() const /* override */
{
return new Loader(*this);
}
//-------------------------------------------------------------------------------------------------
// Private functions
//-------------------------------------------------------------------------------------------------
QString MLGroupListModel::getCover(MLGroup * group) const
{
QString cover = group->getCover();
// NOTE: Making sure we're not already generating a cover.
if (cover.isNull() == false || group->hasGenerator())
return cover;
MLItemId groupId = group->getId();
struct Context{
QString cover;
};
group->setGenerator(true);
m_mediaLib->runOnMLThread<Context>(this,
//ML thread
[groupId]
(vlc_medialibrary_t* ml, Context& ctx){
CoverGenerator generator{ml, groupId};
generator.setSize(QSize(MLGROUPLISTMODEL_COVER_WIDTH,
MLGROUPLISTMODEL_COVER_HEIGHT));
generator.setDefaultThumbnail(":/noart_videoCover.svg");
if (generator.cachedFileAvailable())
ctx.cover = generator.cachedFileURL();
else
ctx.cover = generator.execute();
},
//UI Thread
[this, groupId]
(quint64, Context& ctx)
{
int row;
// NOTE: We want to avoid calling 'MLBaseModel::item' for performance issues.
auto group = static_cast<MLGroup*>(findInCache(groupId, &row));
if (!group)
return;
group->setCover(ctx.cover);
group->setGenerator(false);
QModelIndex modelIndex =this->index(row);
//we're running in a callback
emit const_cast<MLGroupListModel*>(this)->dataChanged(modelIndex, modelIndex, { GROUP_THUMBNAIL });
});
return cover;
}
void MLGroupListModel::generateVideoThumbnail(uint64_t id) const
{
m_mediaLib->runOnMLThread(this,
//ML thread
[id](vlc_medialibrary_t* ml){
vlc_ml_media_generate_thumbnail(ml, id, VLC_ML_THUMBNAIL_SMALL, 512, 320, .15 );
});
}
//-------------------------------------------------------------------------------------------------
// Private MLBaseModel reimplementation
//-------------------------------------------------------------------------------------------------
void MLGroupListModel::onVlcMlEvent(const MLEvent & event) /* override */
void MLVideoGroupsModel::onVlcMlEvent(const MLEvent & event) /* override */
{
int type = event.i_type;
......@@ -306,22 +181,14 @@ void MLGroupListModel::onVlcMlEvent(const MLEvent & event) /* override */
MLBaseModel::onVlcMlEvent(event);
}
void MLGroupListModel::thumbnailUpdated(const QModelIndex& idx, MLItem* mlitem, const QString& mrl, vlc_ml_thumbnail_status_t status) /* override */
{
auto videoItem = static_cast<MLVideo*>(mlitem);
videoItem->setThumbnail(status, mrl);
emit dataChanged(idx, idx, { GROUP_THUMBNAIL });
}
//=================================================================================================
// Loader
//=================================================================================================
MLGroupListModel::Loader::Loader(const MLGroupListModel & model)
MLVideoGroupsModel::Loader::Loader(const MLVideoGroupsModel & model)
: MLBaseModel::BaseLoader(model) {}
size_t MLGroupListModel::Loader::count(vlc_medialibrary_t* ml) const /* override */
size_t MLVideoGroupsModel::Loader::count(vlc_medialibrary_t* ml) const /* override */
{
vlc_ml_query_params_t params = getParams().toCQueryParams();
......@@ -329,7 +196,8 @@ size_t MLGroupListModel::Loader::count(vlc_medialibrary_t* ml) const /* override
}
std::vector<std::unique_ptr<MLItem>>
MLGroupListModel::Loader::load(vlc_medialibrary_t* ml, size_t index, size_t count) const /* override */
MLVideoGroupsModel::Loader::load(vlc_medialibrary_t* ml,
size_t index, size_t count) const /* override */
{
vlc_ml_query_params_t params = getParams(index, count).toCQueryParams();
......
......@@ -18,53 +18,35 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef MLGROUPLISTMODEL_HPP
#define MLGROUPLISTMODEL_HPP
#ifndef MLVIDEOGROUPSMODEL_HPP
#define MLVIDEOGROUPSMODEL_HPP
// MediaLibrary includes
#include "mlbasemodel.hpp"
#include "mlvideomodel.hpp"
// Forward declarations
struct vlc_medialibrary_t;
class MLGroup;
class MLGroupListModel : public MLBaseModel
class MLVideoGroupsModel : public MLVideoModel
{
Q_OBJECT
public:
enum Roles
{
GROUP_IS_VIDEO = Qt::UserRole + 1,
GROUP_ID,
GROUP_TITLE,
GROUP_THUMBNAIL,
GROUP_DURATION,
// NOTE: Group specific.
GROUP_IS_VIDEO = VIDEO_TITLE_FIRST_SYMBOL + 1,
GROUP_DATE,
GROUP_COUNT,
// NOTE: Media specific.
GROUP_IS_NEW,
GROUP_FILENAME,
GROUP_PROGRESS,
GROUP_PLAYCOUNT,
GROUP_RESOLUTION,
GROUP_CHANNEL,
GROUP_MRL,
GROUP_MRL_DISPLAY,
GROUP_VIDEO_TRACK,
GROUP_AUDIO_TRACK,
GROUP_TITLE_FIRST_SYMBOL
GROUP_COUNT
};
public:
explicit MLGroupListModel(QObject * parent = nullptr);
explicit MLVideoGroupsModel(QObject * parent = nullptr);
public: // QAbstractItemModel implementation
public: // MLVideoModel reimplementation
QHash<int, QByteArray> roleNames() const override;
protected: // MLBaseModel implementation
protected: // MLVideoModel reimplementation
QVariant itemRoleData(MLItem *item, int role = Qt::DisplayRole) const override;
vlc_ml_sorting_criteria_t roleToCriteria(int role) const override;
......@@ -75,20 +57,12 @@ protected: // MLBaseModel implementation
ListCacheLoader<std::unique_ptr<MLItem>> * createLoader() const override;
void thumbnailUpdated(const QModelIndex& idx, MLItem* mlitem, const QString& mrl, vlc_ml_thumbnail_status_t status) override;
private: // Functions
QString getCover(MLGroup * group) const;
private: // MLBaseModel implementation
void onVlcMlEvent(const MLEvent & event) override;
void generateVideoThumbnail(uint64_t id) const;
private:
struct Loader : public MLBaseModel::BaseLoader
struct Loader : public BaseLoader
{
Loader(const MLGroupListModel & model);
Loader(const MLVideoGroupsModel & model);
size_t count(vlc_medialibrary_t* ml) const override;
......@@ -96,4 +70,4 @@ private:
};
};
#endif // MLGROUPLISTMODEL_HPP
#endif // MLVIDEOGROUPSMODEL_HPP
......@@ -188,7 +188,7 @@ size_t MLVideoModel::Loader::count(vlc_medialibrary_t* ml) const /* override */
if (id <= 0)
return vlc_ml_count_video_media(ml, &params);
else
return vlc_ml_count_media_of(ml, &params, m_parent.type, id);
return vlc_ml_count_video_of(ml, &params, m_parent.type, id);
}
std::vector<std::unique_ptr<MLItem>>
......@@ -203,7 +203,7 @@ MLVideoModel::Loader::load(vlc_medialibrary_t* ml, size_t index, size_t count) c
if (id <= 0)
list.reset(vlc_ml_list_video_media(ml, &params));
else
list.reset(vlc_ml_list_media_of(ml, &params, m_parent.type, id));
list.reset(vlc_ml_list_video_of(ml, &params, m_parent.type, id));
if (list == nullptr)
return {};
......
......@@ -32,7 +32,7 @@ VideoAll {
property int initialIndex: 0
property MLItemId initialId
property string initialName
property string initialTitle
// Aliases
......
......@@ -40,8 +40,16 @@ VideoAll {
// Private
property var _meta: (MainCtx.grouping === MainCtx.GROUPING_NONE) ? metaVideo
: metaGroup
property var _meta: {
var grouping = MainCtx.grouping;
if (grouping === MainCtx.GROUPING_NONE)
return metaVideo
else if (grouping === MainCtx.GROUPING_NAME)
return metaGroup
else if (grouping === MainCtx.GROUPING_FOLDER)
return metaFolder
}
// Signals
......@@ -114,9 +122,9 @@ VideoAll {
QtObject {
id: metaGroup
property var model: MLGroupListModel { ml: MediaLib }
property var model: MLVideoGroupsModel { ml: MediaLib }
property var contextMenu: GroupListContextMenu { model: metaGroup.model }
property var contextMenu: VideoGroupsContextMenu { model: metaGroup.model }
function onAction(indexes) {
var index = indexes[0]
......@@ -153,6 +161,32 @@ VideoAll {
}
}
QtObject {
id: metaFolder
property var model: MLVideoFoldersModel { ml: MediaLib }
property var contextMenu: VideoFoldersContextMenu { model: metaFolder.model }
function onAction(indexes) {
var index = indexes[0]
root.showList(model.getDataAt(index), Qt.TabFocusReason)
}
function onDoubleClick(object) {
root.showList(object, Qt.MouseFocusReason)
}
function onLabelGrid(object) {
return root.getLabelGroup(object, I18n.qtr("%1 Videos"))
}
function onLabelList(object) {
return root.getLabelGroup(object, I18n.qtr("%1"))
}
}
// Children
MLRecentsVideoModel {
......
......@@ -19,7 +19,8 @@
#include "menus.hpp"
#include "medialibrary/medialib.hpp"
#include "medialibrary/mlvideomodel.hpp"
#include "medialibrary/mlgrouplistmodel.hpp"
#include "medialibrary/mlvideogroupsmodel.hpp"
#include "medialibrary/mlvideofoldersmodel.hpp"
#include "medialibrary/mlplaylistlistmodel.hpp"
#include "medialibrary/mlplaylistmodel.hpp"
#include "medialibrary/mlalbummodel.hpp"
......@@ -162,6 +163,7 @@ void SortMenuVideo::onPopup(QMenu * menu) /* override */
{
{ N_("Do not group videos"), MainCtx::GROUPING_NONE },
{ N_("Group by name"), MainCtx::GROUPING_NAME },
{ N_("Group by folder"), MainCtx::GROUPING_FOLDER },
};
QActionGroup * group = new QActionGroup(this);
......@@ -542,18 +544,19 @@ void VideoContextMenu::popup(const QModelIndexList& selected, QPoint pos, QVaria
}
//=================================================================================================
// GroupListContextMenu
// VideoGroupsContextMenu
//=================================================================================================
GroupListContextMenu::GroupListContextMenu(QObject * parent) : QObject(parent) {}
VideoGroupsContextMenu::VideoGroupsContextMenu(QObject * parent) : QObject(parent) {}
GroupListContextMenu::~GroupListContextMenu() /* override */
VideoGroupsContextMenu::~VideoGroupsContextMenu() /* override */
{
if (m_menu)
delete m_menu;
}
void GroupListContextMenu::popup(const QModelIndexList & selected, QPoint pos, QVariantMap options)
void VideoGroupsContextMenu::popup(const QModelIndexList & selected, QPoint pos,
QVariantMap options)
{
if (m_model == nullptr)
return;
......@@ -564,7 +567,7 @@ void GroupListContextMenu::popup(const QModelIndexList & selected, QPoint pos, Q
QVariantList ids;
for (const QModelIndex & index : selected)
ids.push_back(m_model->data(index, MLGroupListModel::GROUP_ID));
ids.push_back(m_model->data(index, MLVideoModel::VIDEO_ID));
m_menu = new QMenu();
......@@ -605,7 +608,7 @@ void GroupListContextMenu::popup(const QModelIndexList & selected, QPoint pos, Q
// NOTE: At the moment informations are only available for single video(s).
if (selected.count() == 1
&&
m_model->data(selected.first(), MLGroupListModel::GROUP_IS_VIDEO) == true
m_model->data(selected.first(), MLVideoGroupsModel::GROUP_IS_VIDEO) == true
&&
options.contains("information") && options["information"].type() == QVariant::Int)
{
......@@ -619,16 +622,79 @@ void GroupListContextMenu::popup(const QModelIndexList & selected, QPoint pos, Q
#if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
connect(mapper, &QSignalMapper::mappedInt,
this, &GroupListContextMenu::showMediaInformation);
this, &VideoGroupsContextMenu::showMediaInformation);
#else
connect(mapper, QOverload<int>::of(&QSignalMapper::mapped),
this, &GroupListContextMenu::showMediaInformation);
this, &VideoGroupsContextMenu::showMediaInformation);
#endif
}
m_menu->popup(pos);
}
// VideoFoldersContextMenu
VideoFoldersContextMenu::VideoFoldersContextMenu(QObject * parent) : QObject(parent) {}
VideoFoldersContextMenu::~VideoFoldersContextMenu() /* override */
{
if (m_menu)
delete m_menu;
}
void VideoFoldersContextMenu::popup(const QModelIndexList & selected, QPoint pos,
QVariantMap options)
{
if (m_model == nullptr)
return;
if (m_menu)
delete m_menu;
QVariantList ids;
for (const QModelIndex & index : selected)
ids.push_back(m_model->data(index, MLVideoFoldersModel::FOLDER_ID));
m_menu = new QMenu();
MediaLib * ml = m_model->ml();
QAction * action = m_menu->addAction(qtr("Add and play"));
connect(action, &QAction::triggered, [ml, ids, options]()
{
ml->addAndPlay(ids, options["player-options"].toStringList());
});
action = m_menu->addAction(qtr("Enqueue"));
connect(action, &QAction::triggered, [ml, ids]()
{
ml->addToPlaylist(ids);
});
action = m_menu->addAction(qtr("Add to playlist"));
connect(action, &QAction::triggered, [ids]()
{
DialogsProvider::getInstance()->playlistsDialog(ids);
});
action = m_menu->addAction(qtr("Play as audio"));
connect(action, &QAction::triggered, [ml, ids, options]()
{
QStringList list = options["player-options"].toStringList();
list.prepend(":no-video");
ml->addAndPlay(ids, list);
});
m_menu->popup(pos);
}
//=================================================================================================
// PlaylistListContextMenu
//=================================================================================================
......
......@@ -33,8 +33,8 @@ class MLArtistModel;
class MLAlbumTrackModel;
class MLUrlModel;
class MLVideoModel;
class MLGroupListModel;
class MLGroupModel;
class MLVideoGroupsModel;
class MLVideoFoldersModel;
class MLPlaylistListModel;
class MLPlaylistModel;
class NetworkDeviceModel;
......@@ -278,15 +278,15 @@ private:
// Groups
//-------------------------------------------------------------------------------------------------
class GroupListContextMenu : public QObject {
class VideoGroupsContextMenu : public QObject {
Q_OBJECT
SIMPLE_MENU_PROPERTY(MLGroupListModel *, model, nullptr)
SIMPLE_MENU_PROPERTY(MLVideoGroupsModel *, model, nullptr)
public:
GroupListContextMenu(QObject * parent = nullptr);
VideoGroupsContextMenu(QObject * parent = nullptr);
~GroupListContextMenu() /* override */;
~VideoGroupsContextMenu(); /* override */
public slots:
void popup(const QModelIndexList & selected, QPoint pos, QVariantMap options = {});
......@@ -298,6 +298,29 @@ private:
QMenu * m_menu = nullptr;
};
// Folders
class VideoFoldersContextMenu : public QObject {
Q_OBJECT
SIMPLE_MENU_PROPERTY(MLVideoFoldersModel *, model, nullptr)
public:
VideoFoldersContextMenu(QObject * parent = nullptr);
~VideoFoldersContextMenu(); /* override */
public slots:
void popup(const QModelIndexList & selected, QPoint pos, QVariantMap options = {});
signals:
// FIXME: This signal is required for VideoAll Connections.
void showMediaInformation(int index);
private:
QMenu * m_menu = nullptr;
};
//-------------------------------------------------------------------------------------------------
class PlaylistListContextMenu : public QObject {
......
......@@ -357,6 +357,8 @@ QString CoverGenerator::getPrefix(vlc_ml_parent_type type) const
return "genre";
case VLC_ML_PARENT_GROUP:
return "group";
case VLC_ML_PARENT_FOLDER:
return "folder";
case VLC_ML_PARENT_PLAYLIST:
return "playlist";
default:
......
......@@ -455,18 +455,28 @@ bool Convert( const medialibrary::IPlaylist* input, vlc_ml_playlist_t& output )
bool Convert( const medialibrary::IFolder* input, vlc_ml_folder_t& output )
{
output.i_id = input->id();
output.i_nb_media = input->nbMedia();
output.b_banned = input->isBanned();
if ( strdup_helper( input->name(), output.psz_name ) == false )
return false;
try
{
if ( strdup_helper( input->mrl(), output.psz_mrl ) == false )
if (strdup_helper(input->mrl(), output.psz_mrl) == false)
return false;
output.b_present = true;
}
catch ( const medialibrary::fs::errors::DeviceRemoved& )
{
output.psz_mrl = nullptr;
output.b_present = false;
}
return true;
}
......