// Copyright (C) 2019 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmlpreviewplugin.h" #include "qmlpreviewactions.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace QmlPreview { using QmlPreviewRunControlList = QList; } Q_DECLARE_METATYPE(QmlPreview::QmlPreviewRunControlList) namespace QmlDesigner { static QObject *s_previewPlugin = nullptr; QmlPreviewWidgetPlugin::QmlPreviewWidgetPlugin() { DesignerActionManager &designerActionManager = QmlDesignerPlugin::instance()->designerActionManager(); auto previewAction = new QmlPreviewAction(); designerActionManager.addDesignerAction(new ActionGroup( QString(), ComponentCoreConstants::qmlPreviewCategory, {}, ComponentCoreConstants::Priorities::QmlPreviewCategory, &SelectionContextFunctors::always)); s_previewPlugin = getPreviewPlugin(); if (s_previewPlugin) { bool connected = connect(s_previewPlugin, SIGNAL(runningPreviewsChanged(const QmlPreviewRunControlList &)), this, SLOT(handleRunningPreviews())); QTC_ASSERT(connected, qWarning() << "something wrong with the runningPreviewsChanged signal"); } designerActionManager.addDesignerAction(previewAction); auto zoomAction = new ZoomPreviewAction; designerActionManager.addDesignerAction(zoomAction); auto separator = new SeparatorDesignerAction(ComponentCoreConstants::qmlPreviewCategory, 0); designerActionManager.addDesignerAction(separator); m_previewToggleAction = previewAction->action(); Core::Context globalContext; auto registerCommand = [&globalContext](ActionInterface *action){ const QString id = QStringLiteral("QmlPreview.%1").arg(QString::fromLatin1(action->menuId())); Core::Command *cmd = Core::ActionManager::registerAction(action->action(), id.toLatin1().constData(), globalContext); cmd->setDefaultKeySequence(action->action()->shortcut()); cmd->setDescription(action->action()->toolTip()); action->action()->setToolTip(cmd->action()->toolTip()); action->action()->setShortcut(cmd->action()->shortcut()); }; // Only register previewAction as others don't have keyboard shortcuts for them registerCommand(previewAction); if (s_previewPlugin) { auto fpsAction = new FpsAction; designerActionManager.addDesignerAction(fpsAction); bool hasFpsHandler = s_previewPlugin->setProperty("fpsHandler", QVariant::fromValue(FpsLabelAction::fpsHandler)); QTC_CHECK(hasFpsHandler); auto switchLanguageAction = new SwitchLanguageAction; designerActionManager.addDesignerAction(switchLanguageAction); } } QString QmlPreviewWidgetPlugin::pluginName() const { return QLatin1String("QmlPreviewPlugin"); } void QmlPreviewWidgetPlugin::stopAllRunControls() { QTC_ASSERT(s_previewPlugin, return); const QVariant variant = s_previewPlugin->property("runningPreviews"); auto runControls = variant.value(); for (ProjectExplorer::RunControl *runControl : runControls) runControl->initiateStop(); } void QmlPreviewWidgetPlugin::handleRunningPreviews() { QTC_ASSERT(s_previewPlugin, return); const QVariant variant = s_previewPlugin->property("runningPreviews"); if (variant.isValid()) { // the QmlPreview::QmlPreviewRunControlList type have to be available and used in the qmlpreview plugin QTC_ASSERT(variant.canConvert(), return); auto runControls = variant.value(); m_previewToggleAction->setChecked(!runControls.isEmpty()); if (runControls.isEmpty()) FpsLabelAction::cleanFpsCounter(); } } QString QmlPreviewWidgetPlugin::metaInfo() const { return QLatin1String(":/qmlpreviewplugin/qmlpreview.metainfo"); } void QmlPreviewWidgetPlugin::setQmlFile() { if (s_previewPlugin) { const Utils::FilePath qmlFileName = QmlDesignerPlugin::instance()->currentDesignDocument()->fileName(); bool hasPreviewedFile = s_previewPlugin->setProperty("previewedFile", qmlFileName.toString()); QTC_CHECK(hasPreviewedFile); } } float QmlPreviewWidgetPlugin::zoomFactor() { QVariant zoomFactorVariant = 1.0; if (s_previewPlugin && !s_previewPlugin->property("zoomFactor").isNull()) zoomFactorVariant = s_previewPlugin->property("zoomFactor"); return zoomFactorVariant.toFloat(); } void QmlPreviewWidgetPlugin::setZoomFactor(float zoomFactor) { if (auto s_previewPlugin = getPreviewPlugin()) { bool hasZoomFactor = s_previewPlugin->setProperty("zoomFactor", zoomFactor); QTC_CHECK(hasZoomFactor); } } void QmlPreviewWidgetPlugin::setLanguageLocale(const QString &locale) { if (auto s_previewPlugin = getPreviewPlugin()) { bool hasLocaleIsoCode = s_previewPlugin->setProperty("localeIsoCode", locale); QTC_CHECK(hasLocaleIsoCode); } } QObject *QmlPreviewWidgetPlugin::getPreviewPlugin() { const QVector &specs = ExtensionSystem::PluginManager::plugins(); const auto pluginIt = std::find_if(specs.cbegin(), specs.cend(), [](const ExtensionSystem::PluginSpec *p) { return p->name() == "QmlPreview"; }); if (pluginIt != specs.cend()) return (*pluginIt)->plugin(); return nullptr; } } // namespace QmlDesigner