#include "mainui.hpp" #include #include "medialibrary/medialib.hpp" #include "medialibrary/mlqmltypes.hpp" #include "medialibrary/mlcustomcover.hpp" #include "medialibrary/mlalbummodel.hpp" #include "medialibrary/mlartistmodel.hpp" #include "medialibrary/mlalbumtrackmodel.hpp" #include "medialibrary/mlgenremodel.hpp" #include "medialibrary/mlurlmodel.hpp" #include "medialibrary/mlvideomodel.hpp" #include "medialibrary/mlrecentsmodel.hpp" #include "medialibrary/mlrecentsvideomodel.hpp" #include "medialibrary/mlfoldersmodel.hpp" #include "medialibrary/mlvideogroupsmodel.hpp" #include "medialibrary/mlvideofoldersmodel.hpp" #include "medialibrary/mlplaylistlistmodel.hpp" #include "medialibrary/mlplaylistmodel.hpp" #include "medialibrary/mlplaylist.hpp" #include "medialibrary/mlbookmarkmodel.hpp" #include "player/player_controller.hpp" #include "player/player_controlbar_model.hpp" #include "player/control_list_model.hpp" #include "player/control_list_filter.hpp" #include "player/delay_estimator.hpp" #include "dialogs/toolbar/controlbar_profile_model.hpp" #include "dialogs/toolbar/controlbar_profile.hpp" #include "playlist/playlist_model.hpp" #include "playlist/playlist_controller.hpp" #include "util/csdmenu.hpp" #include "util/item_key_event_filter.hpp" #include "util/imageluminanceextractor.hpp" #include "util/keyhelper.hpp" #include "style/systempalette.hpp" #include "util/navigation_history.hpp" #include "util/flickable_scroll_handler.hpp" #include "util/color_svg_image_provider.hpp" #include "util/effects_image_provider.hpp" #include "util/vlcaccess_image_provider.hpp" #include "util/csdbuttonmodel.hpp" #include "util/vlctick.hpp" #include "util/list_selection_model.hpp" #include "dialogs/help/aboutmodel.hpp" #include "dialogs/dialogs_provider.hpp" #include "dialogs/dialogs/dialogmodel.hpp" #include "network/networkmediamodel.hpp" #include "network/networkdevicemodel.hpp" #include "network/networksourcesmodel.hpp" #include "network/servicesdiscoverymodel.hpp" #include "network/standardpathmodel.hpp" #include "menus/qml_menu_wrapper.hpp" #include "widgets/native/csdthemeimage.hpp" #include "widgets/native/roundimage.hpp" #include "widgets/native/navigation_attached.hpp" #include "widgets/native/viewblockingrectangle.hpp" #if QT_VERSION < QT_VERSION_CHECK(6, 4, 0) #include "widgets/native/doubleclickignoringitem.hpp" #else // QQuickItem already ignores double click, starting // with Qt 6.4.0: #define DoubleClickIgnoringItem QQuickItem #endif #include "videosurface.hpp" #include "mainctx.hpp" #include "mainctx_submodels.hpp" #include using namespace vlc::playlist; MainUI::MainUI(qt_intf_t *p_intf, MainCtx *mainCtx, QWindow* interfaceWindow, QObject *parent) : QObject(parent) , m_intf(p_intf) , m_mainCtx(mainCtx) , m_interfaceWindow(interfaceWindow) { assert(m_intf); assert(m_mainCtx); assert(m_interfaceWindow); registerQMLTypes(); } MainUI::~MainUI() { qmlClearTypeRegistrations(); } bool MainUI::setup(QQmlEngine* engine) { engine->setOutputWarningsToStandardError(false); connect(engine, &QQmlEngine::warnings, this, &MainUI::onQmlWarning); if (m_mainCtx->hasMediaLibrary()) { engine->addImageProvider(MLCustomCover::providerId, new MLCustomCover(m_mainCtx->getMediaLibrary())); } #if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) engine->addImportPath(":/qt/qml"); #endif if (!EffectsImageProvider::instance(engine, engine)) new EffectsImageProvider(engine); engine->addImageProvider(QStringLiteral("svgcolor"), new SVGColorImageImageProvider()); engine->addImageProvider(QStringLiteral("vlcaccess"), new VLCAccessImageProvider()); m_component = new QQmlComponent(engine, QStringLiteral("qrc:/qt/qml/VLC/MainInterface/MainInterface.qml"), QQmlComponent::PreferSynchronous, engine); if (m_component->isLoading()) { msg_Warn(m_intf, "component is still loading"); } if (m_component->isError()) { for(auto& error: m_component->errors()) msg_Err(m_intf, "qml loading %s %s:%u", qtu(error.description()), qtu(error.url().toString()), error.line()); #ifdef QT_STATIC assert( !"Missing qml modules from qt contribs." ); #else msg_Err( m_intf, "Install missing modules using your packaging tool" ); #endif return false; } return true; } QQuickItem* MainUI::createRootItem() { QObject* rootObject = m_component->create(); if (m_component->isError()) { for(auto& error: m_component->errors()) msg_Err(m_intf, "qml loading %s %s:%u", qtu(error.description()), qtu(error.url().toString()), error.line()); return nullptr; } if (rootObject == nullptr) { msg_Err(m_intf, "unable to create main interface, no root item"); return nullptr; } m_rootItem = qobject_cast(rootObject); if (!m_rootItem) { msg_Err(m_intf, "unexpected type of qml root item"); return nullptr; } return m_rootItem; } void MainUI::registerQMLTypes() { { const char* uri = "VLC.MainInterface"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.MainInterface qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "MainCtx", m_mainCtx); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "SearchCtx", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "SortCtx", ""); qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "History", new NavigationHistory(this)); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "QtAbstractItemModel", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "QtWindow", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "QtScreen", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "vlcTick", ""); qmlRegisterType(uri, versionMajor, versionMinor, "VideoSurface"); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "BaseModel", "Base Model is uncreatable." ); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "VLCVarChoiceModel", "generic variable with choice model" ); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "CSDButton", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "CSDButtonModel", "has CSD buttons and provides for communicating CSD events between UI and backend"); qmlRegisterTypesAndRevisions( uri, versionMajor); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "Navigation", "Navigation is only available via attached properties"); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } { const char* uri = "VLC.Dialogs"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.Dialogs qmlRegisterType( uri, versionMajor, versionMinor, "AboutModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "VLCDialog" ); assert(VLCDialogModel::getInstance()); qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "VLCDialogModel", VLCDialogModel::getInstance()); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "dialogId", ""); assert(DialogsProvider::getInstance()); qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "DialogsProvider", DialogsProvider::getInstance()); assert(DialogErrorModel::getInstance()); qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "DialogErrorModel", DialogErrorModel::getInstance()); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } { const char* uri = "VLC.Menus"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.Menus qmlRegisterType( uri, versionMajor, versionMinor, "StringListMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "SortMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "SortMenuVideo" ); qmlRegisterType( uri, versionMajor, versionMinor, "QmlGlobalMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "QmlMenuBar" ); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } { const char* uri = "VLC.Player"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.Player qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "TrackListModel", "available tracks of a media (audio/video/sub)" ); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "TitleListModel", "available titles of a media" ); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "ChapterListModel", "available chapters of a media" ); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "ProgramListModel", "available programs of a media" ); assert(m_intf->p_mainPlayerController); qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "Player", m_intf->p_mainPlayerController); qmlRegisterType( uri, versionMajor, versionMinor, "QmlBookmarkMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "QmlProgramMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "QmlRendererMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "QmlSubtitleMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "QmlAudioMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "QmlAudioContextMenu" ); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } { const char* uri = "VLC.PlayerControls"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.PlayerControls qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "ControlbarProfileModel", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "ControlbarProfile", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "PlayerControlbarModel", ""); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "ControlListModel", "" ); qmlRegisterType(uri, versionMajor, versionMinor, "ControlListFilter"); qmlRegisterSingletonType(uri, versionMajor, versionMinor, "PlayerListModel", PlayerControlbarModel::getPlaylistIdentifierListModel); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } { const char* uri = "VLC.Playlist"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.Playlist qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "playlistItem", ""); qmlRegisterType( uri, versionMajor, versionMinor, "PlaylistListModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "PlaylistController" ); qmlRegisterType( uri, versionMajor, versionMinor, "PlaylistContextMenu" ); assert(m_intf->p_mainPlaylistController); qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "MainPlaylistController", m_intf->p_mainPlaylistController); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } { const char* uri = "VLC.Network"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.Network qmlRegisterType( uri, versionMajor, versionMinor, "NetworkMediaModel"); qmlRegisterType( uri, versionMajor, versionMinor, "NetworkDeviceModel"); qmlRegisterType( uri, versionMajor, versionMinor, "NetworkSourcesModel"); qmlRegisterType( uri, versionMajor, versionMinor, "ServicesDiscoveryModel"); qmlRegisterType( uri, versionMajor, versionMinor, "StandardPathModel"); qmlRegisterType( uri, versionMajor, versionMinor, "MLFolderModel"); qmlRegisterType( uri, versionMajor, versionMinor, "NetworkMediaContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "NetworkDeviceContextMenu" ); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } { const char* uri = "VLC.Style"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.Style qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "ColorSchemeModel", ""); qmlRegisterType(uri, versionMajor, versionMinor, "ColorContext"); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "colorProperty", ""); qmlRegisterType(uri, versionMajor, versionMinor, "SystemPalette"); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } { const char* uri = "VLC.Util"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.Util qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "KeyHelper", new QmlKeyHelper(this)); qmlRegisterSingletonType(uri, versionMajor, versionMinor, "Effects", EffectsImageProvider::instance); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "SVGColorImageBuilder", ""); qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "SVGColorImage", new SVGColorImage(this)); qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "VLCAccessImage", new VLCAccessImage(this)); qmlRegisterType( uri, versionMajor, versionMinor, "DelayEstimator" ); qmlRegisterType( uri, versionMajor, versionMinor, "ImageLuminanceExtractor"); qmlRegisterType( uri, versionMajor, versionMinor, "KeyEventFilter" ); qmlRegisterType( uri, versionMajor, versionMinor, "FlickableScrollHandler" ); qmlRegisterType( uri, versionMajor, versionMinor, "ListSelectionModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "DoubleClickIgnoringItem" ); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } { const char* uri = "VLC.Widgets"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.Widgets qmlRegisterType( uri, versionMajor, versionMinor, "RoundImage" ); qmlRegisterType(uri, versionMajor, versionMinor, "CSDThemeImage"); qmlRegisterType( uri, versionMajor, versionMinor, "ViewBlockingRectangle" ); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } if (m_mainCtx->hasMediaLibrary()) { const char* uri = "VLC.MediaLibrary"; const int versionMajor = 1; const int versionMinor = 0; // @uri VLC.MediaLibrary assert(m_mainCtx->getMediaLibrary()); qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "MediaLib", m_mainCtx->getMediaLibrary()); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "mediaId", ""); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "MLBaseModel", "ML Base Model is uncreatable." ); qmlRegisterType( uri, versionMajor, versionMinor, "MLAlbumModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLArtistModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLAlbumTrackModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLGenreModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLUrlModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLVideoModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLRecentsVideoModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLVideoGroupsModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLVideoFoldersModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLPlaylistListModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLPlaylistModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "MLBookmarkModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "NetworkMediaModel"); qmlRegisterType( uri, versionMajor, versionMinor, "NetworkDeviceModel"); qmlRegisterType( uri, versionMajor, versionMinor, "NetworkSourcesModel"); qmlRegisterType( uri, versionMajor, versionMinor, "ServicesDiscoveryModel"); qmlRegisterType( uri, versionMajor, versionMinor, "MLFolderModel"); qmlRegisterType( uri, versionMajor, versionMinor, "MLRecentModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "PlaylistListContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "PlaylistMediaContextMenu" ); qmlRegisterModule(uri, versionMajor, versionMinor); qmlProtectModule(uri, versionMajor); } #if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) // Dummy QtQuick.Effects module qmlRegisterModule("QtQuick.Effects", 0, 0); // Do not protect, types can still be registered. #else // Dummy Qt5Compat.GraphicalEffects module qmlRegisterModule("Qt5Compat.GraphicalEffects", 0, 0); // Do not protect, types can still be registered. #endif } void MainUI::onQmlWarning(const QList& qmlErrors) { for( const auto& error: qmlErrors ) { vlc_log_type type; switch( error.messageType() ) { case QtInfoMsg: type = VLC_MSG_INFO; break; case QtWarningMsg: type = VLC_MSG_WARN; break; case QtCriticalMsg: case QtFatalMsg: type = VLC_MSG_ERR; break; case QtDebugMsg: default: type = VLC_MSG_DBG; } msg_Generic( m_intf, type, "qml message %s:%i %s", qtu(error.url().toString()), error.line(), qtu(error.description()) ); } }