#include "mainui.hpp" #include #include "medialibrary/medialib.hpp" #include "medialibrary/mlqmltypes.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 "player/player_controller.hpp" #include "player/player_controlbar_model.hpp" #include "player/control_list_model.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/item_key_event_filter.hpp" #include "util/imageluminanceextractor.hpp" #include "util/i18n.hpp" #include "util/keyhelper.hpp" #include "util/systempalette.hpp" #include "util/sortfilterproxymodel.hpp" #include "util/navigation_history.hpp" #include "util/qmlinputitem.hpp" #include "util/mouse_event_filter.hpp" #include "util/flickable_scroll_handler.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 "menus/qml_menu_wrapper.hpp" #include "widgets/native/roundimage.hpp" #include "widgets/native/navigation_attached.hpp" #include "videosurface.hpp" #include using namespace vlc::playlist; namespace { template class SingletonRegisterHelper { static QPointer m_instance; public: static QObject* callback(QQmlEngine *engine, QJSEngine *) { assert(m_instance); engine->setObjectOwnership(m_instance, QQmlEngine::ObjectOwnership::CppOwnership); return m_instance; } static void setInstance(T* instance) { assert(!m_instance); m_instance = instance; } static T* getInstance() { return m_instance; } }; template QPointer SingletonRegisterHelper::m_instance = nullptr; template void registerAnonymousType( const char *uri, int versionMajor ) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) qmlRegisterAnonymousType( uri, versionMajor ); #else qmlRegisterType(); VLC_UNUSED( uri ); VLC_UNUSED( versionMajor ); #endif } } // anonymous namespace 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); SingletonRegisterHelper::setInstance(mainCtx); assert(m_intf->p_mainPlayerController); SingletonRegisterHelper::setInstance(m_intf->p_mainPlayerController); assert(DialogsProvider::getInstance()); SingletonRegisterHelper::setInstance(DialogsProvider::getInstance()); SingletonRegisterHelper::setInstance( new NavigationHistory(this) ); SingletonRegisterHelper::setInstance( new I18n(this) ); SingletonRegisterHelper::setInstance( new SystemPalette(this) ); SingletonRegisterHelper::setInstance( new DialogModel(m_intf, this)); SingletonRegisterHelper::setInstance( new QmlKeyHelper(this) ); if (m_mainCtx->hasMediaLibrary()) { assert(m_mainCtx->getMediaLibrary()); SingletonRegisterHelper::setInstance(m_mainCtx->getMediaLibrary()); } registerQMLTypes(); } MainUI::~MainUI() { } bool MainUI::setup(QQmlEngine* engine) { engine->setOutputWarningsToStandardError(false); connect(engine, &QQmlEngine::warnings, this, &MainUI::onQmlWarning); m_component = new QQmlComponent(engine, QStringLiteral("qrc:/main/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_STATICPLUGIN 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 = "org.videolan.vlc"; const int versionMajor = 0; const int versionMinor = 1; qmlRegisterSingletonType(uri, versionMajor, versionMinor, "MainCtx", SingletonRegisterHelper::callback); qmlRegisterSingletonType(uri, versionMajor, versionMinor, "History", SingletonRegisterHelper::callback); qmlRegisterSingletonType(uri, versionMajor, versionMinor, "Player", SingletonRegisterHelper::callback); qmlRegisterSingletonType(uri, versionMajor, versionMinor, "I18n", SingletonRegisterHelper::callback); qmlRegisterSingletonType(uri, versionMajor, versionMinor, "DialogsProvider", SingletonRegisterHelper::callback); qmlRegisterSingletonType(uri, versionMajor, versionMinor, "SystemPalette", SingletonRegisterHelper::callback); qmlRegisterSingletonType(uri, versionMajor, versionMinor, "DialogModel", SingletonRegisterHelper::callback); qmlRegisterSingletonType(uri, versionMajor, versionMinor, "KeyHelper", SingletonRegisterHelper::callback); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "QtAbstractItemModel", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "QtWindow", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "QtScreen", ""); qRegisterMetaType(); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "VLCTick", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "ColorSchemeModel", ""); qRegisterMetaType(); qmlRegisterType(uri, versionMajor, versionMinor, "VideoSurface"); qRegisterMetaType(); 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, "ImageLuminanceExtractor"); 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 titles of a media" ); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "ProgramListModel", "available programs of a media" ); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "VLCVarChoiceModel", "generic variable with choice model" ); qRegisterMetaType(); qRegisterMetaType(); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "PlaylistItem", ""); qmlRegisterType( uri, versionMajor, versionMinor, "PlaylistListModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "PlaylistControllerModel" ); qmlRegisterType( uri, versionMajor, versionMinor, "AboutModel" ); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "DialogErrorModel", ""); qRegisterMetaType(); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "DialogId", ""); qmlRegisterType( uri, versionMajor, versionMinor, "KeyEventFilter" ); qmlRegisterType( uri, versionMajor, versionMinor, "MouseEventFilter" ); qmlRegisterType( uri, versionMajor, versionMinor, "FlickableScrollHandler" ); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "ControlbarProfileModel", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "ControlbarProfile", ""); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "PlayerControlbarModel", ""); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "ControlListModel", "" ); qmlRegisterSingletonType(uri, versionMajor, versionMinor, "PlayerListModel", PlayerControlbarModel::getPlaylistIdentifierListModel); 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" ); qmlRegisterType( uri, versionMajor, versionMinor, "NetworkMediaContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "NetworkDeviceContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "PlaylistContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "SortFilterProxyModel" ); qRegisterMetaType>("QList"); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "Navigation", "Navigation is only available via attached properties"); qmlProtectModule(uri, versionMajor); } { const char* const uri = "org.videolan.compat"; const int versionMajor = 0; const int versionMinor = 1; qmlRegisterModule(uri, versionMajor, versionMinor); #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) qmlRegisterType(QUrl("qrc:///util/BindingRev14.qml"), uri, versionMajor, versionMinor, "BindingCompat"); #else qmlRegisterType(QUrl("qrc:///util/BindingRev8.qml"), uri, versionMajor, versionMinor, "BindingCompat"); #endif qmlProtectModule(uri, versionMajor); } { // Custom controls const char* uri = "org.videolan.controls"; const int versionMajor = 0; const int versionMinor = 1; qmlRegisterType( uri, versionMajor, versionMinor, "RoundImage" ); qmlProtectModule(uri, versionMajor); } if (m_mainCtx->hasMediaLibrary()) { const char* uri = "org.videolan.medialib"; const int versionMajor = 0; const int versionMinor = 1; qmlRegisterSingletonType(uri, versionMajor, versionMinor, "MediaLib", SingletonRegisterHelper::callback); qRegisterMetaType(); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "MLItemId", ""); qmlRegisterUncreatableType( uri, versionMajor, versionMinor, "MLModel", "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" ); qRegisterMetaType(); 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" ); //expose base object, they aren't instanciable from QML side registerAnonymousType(uri, versionMajor); registerAnonymousType(uri, versionMajor); registerAnonymousType(uri, versionMajor); qmlRegisterType( uri, versionMajor, versionMinor, "AlbumContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "ArtistContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "GenreContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "AlbumTrackContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "URLContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "VideoContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "VideoGroupsContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "VideoFoldersContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "PlaylistListContextMenu" ); qmlRegisterType( uri, versionMajor, versionMinor, "PlaylistMediaContextMenu" ); qmlProtectModule(uri, versionMajor); } } void MainUI::onQmlWarning(const QList& qmlErrors) { for (auto& error: qmlErrors) { msg_Warn( m_intf, "qml error %s:%i %s", qtu(error.url().toString()), error.line(), qtu(error.description()) ); } }