diff options
Diffstat (limited to 'src/webengine/ui_delegates_manager.cpp')
-rw-r--r-- | src/webengine/ui_delegates_manager.cpp | 738 |
1 files changed, 0 insertions, 738 deletions
diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp deleted file mode 100644 index 19274bedf..000000000 --- a/src/webengine/ui_delegates_manager.cpp +++ /dev/null @@ -1,738 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "ui_delegates_manager.h" - -#include "api/qquickwebengineview_p.h" -#include <authentication_dialog_controller.h> -#include <color_chooser_controller.h> -#include <file_picker_controller.h> -#include <javascript_dialog_controller.h> -#include <touch_selection_menu_controller.h> -#include <web_contents_adapter_client.h> - -#include <QFileInfo> -#include <QQmlContext> -#include <QQmlEngine> -#include <QQmlProperty> -#include <QQuickWindow> -#include <QCursor> -#include <QList> -#include <QScreen> -#include <QTimer> -#include <QGuiApplication> - -// Uncomment for QML debugging -//#define UI_DELEGATES_DEBUG - -namespace QtWebEngineCore { - -#define NO_SEPARATOR -#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) -#define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \ - case UIDelegatesManager::TYPE:\ - return QString::fromLatin1(#TYPE ##".qml"); -#else -#define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \ - case UIDelegatesManager::TYPE:\ - return QStringLiteral(#TYPE".qml"); -#endif - -static QString fileNameForComponent(UIDelegatesManager::ComponentType type) -{ - switch (type) { - FOR_EACH_COMPONENT_TYPE(FILE_NAME_CASE_STATEMENT, NO_SEPARATOR) - default: - Q_UNREACHABLE(); - } - return QString(); -} - -static QPoint calculateToolTipPosition(QPoint &position, QSize &toolTip) { - QRect screen; - const QList<QScreen *> screens = QGuiApplication::screens(); - for (const QScreen *src : screens) - if (src->availableGeometry().contains(position)) - screen = src->availableGeometry(); - - position += QPoint(2, 16); - - if (position.x() + toolTip.width() > screen.x() + screen.width()) - position.rx() -= 4 + toolTip.width(); - if (position.y() + toolTip.height() > screen.y() + screen.height()) - position.ry() -= 24 + toolTip.height(); - if (position.y() < screen.y()) - position.setY(screen.y()); - if (position.x() + toolTip.width() > screen.x() + screen.width()) - position.setX(screen.x() + screen.width() - toolTip.width()); - if (position.x() < screen.x()) - position.setX(screen.x()); - if (position.y() + toolTip.height() > screen.y() + screen.height()) - position.setY(screen.y() + screen.height() - toolTip.height()); - - return position; -} - -const char *defaultPropertyName(QObject *obj) -{ - const QMetaObject *metaObject = obj->metaObject(); - - int idx = metaObject->indexOfClassInfo("DefaultProperty"); - if (-1 == idx) - return 0; - - QMetaClassInfo info = metaObject->classInfo(idx); - return info.value(); -} - -#define COMPONENT_MEMBER_INIT(TYPE, COMPONENT) \ - , COMPONENT##Component(0) - -UIDelegatesManager::UIDelegatesManager(QQuickWebEngineView *view) - : m_view(view) - , m_toolTip(nullptr) - , m_touchSelectionMenu(nullptr) - FOR_EACH_COMPONENT_TYPE(COMPONENT_MEMBER_INIT, NO_SEPARATOR) -{ -} - -UIDelegatesManager::~UIDelegatesManager() -{ -} - -#define COMPONENT_MEMBER_CASE_STATEMENT(TYPE, COMPONENT) \ - case TYPE: \ - component = &COMPONENT##Component; \ - break; - -bool UIDelegatesManager::initializeImportDirs(QStringList &dirs, QQmlEngine *engine) -{ - const QStringList paths = engine->importPathList(); - for (const QString &path : paths) { - QString importPath = path % QLatin1String("/QtWebEngine/Controls1Delegates/"); - - // resource paths have to be tested using the ":/" prefix - if (importPath.startsWith(QLatin1String("qrc:/"))) - importPath.remove(0, 3); - - QFileInfo fi(importPath); - if (fi.exists()) - dirs << fi.absolutePath(); - } - return !dirs.isEmpty(); -} - -bool UIDelegatesManager::ensureComponentLoaded(ComponentType type) -{ - QQmlEngine* engine = qmlEngine(m_view); - if (m_importDirs.isEmpty() && !initializeImportDirs(m_importDirs, engine)) - return false; - - QQmlComponent **component; - switch (type) { - FOR_EACH_COMPONENT_TYPE(COMPONENT_MEMBER_CASE_STATEMENT, NO_SEPARATOR) - default: - Q_UNREACHABLE(); - return false; - } - QString fileName(fileNameForComponent(type)); -#ifndef UI_DELEGATES_DEBUG - if (*component) - return true; -#else // Unconditionally reload the components each time. - fprintf(stderr, "%s: %s\n", Q_FUNC_INFO, qPrintable(fileName)); -#endif - if (!engine) - return false; - - for (const QString &importDir : qAsConst(m_importDirs)) { - const QString componentFilePath = importDir % QLatin1Char('/') % fileName; - - if (!QFileInfo(componentFilePath).exists()) - continue; - - // FIXME: handle async loading - *component = (new QQmlComponent(engine, - importDir.startsWith(QLatin1String(":/")) ? QUrl(QLatin1String("qrc") + componentFilePath) - : QUrl::fromLocalFile(componentFilePath), - QQmlComponent::PreferSynchronous, m_view)); - - if ((*component)->status() != QQmlComponent::Ready) { - const QList<QQmlError> errs = (*component)->errors(); - for (const QQmlError &err : errs) - qWarning("QtWebEngine: component error: %s\n", qPrintable(err.toString())); - delete *component; - *component = nullptr; - return false; - } - return true; - } - return false; -} - -#define CHECK_QML_SIGNAL_PROPERTY(prop, location) \ - if (!prop.isSignalProperty()) \ - qWarning("%s is missing %s signal property.\n", qPrintable(location.toString()), qPrintable(prop.name())); - -void UIDelegatesManager::addMenuItem(QQuickWebEngineAction *action, QObject *menu, bool checkable, bool checked) -{ - Q_ASSERT(action); - if (!ensureComponentLoaded(MenuItem)) - return; - QObject *it = menuItemComponent->beginCreate(qmlContext(m_view)); - - QQmlProperty(it, QStringLiteral("text")).write(action->text()); - QQmlProperty(it, QStringLiteral("iconName")).write(action->iconName()); - QQmlProperty(it, QStringLiteral("enabled")).write(action->isEnabled()); - QQmlProperty(it, QStringLiteral("checkable")).write(checkable); - QQmlProperty(it, QStringLiteral("checked")).write(checked); - - QQmlProperty signal(it, QStringLiteral("onTriggered")); - CHECK_QML_SIGNAL_PROPERTY(signal, menuItemComponent->url()); - const QMetaObject *actionMeta = action->metaObject(); - QObject::connect(it, signal.method(), action, actionMeta->method(actionMeta->indexOfSlot("trigger()"))); - menuItemComponent->completeCreate(); - - it->setParent(menu); - - QQmlListReference entries(menu, defaultPropertyName(menu), qmlEngine(m_view)); - if (entries.isValid()) - entries.append(it); -} - -void UIDelegatesManager::addMenuSeparator(QObject *menu) -{ - if (!ensureComponentLoaded(MenuSeparator)) - return; - - QQmlContext *itemContext = qmlContext(m_view); - QObject *sep = menuSeparatorComponent->create(itemContext); - sep->setParent(menu); - - QQmlListReference entries(menu, defaultPropertyName(menu), qmlEngine(m_view)); - if (entries.isValid() && entries.count() > 0) - entries.append(sep); -} - -QObject *UIDelegatesManager::addMenu(QObject *parentMenu, const QString &title, const QPoint& pos) -{ - Q_ASSERT(parentMenu); - if (!ensureComponentLoaded(Menu)) - return nullptr; - QQmlContext *context = qmlContext(m_view); - QObject *menu = menuComponent->beginCreate(context); - // set visual parent for non-Window-based menus - if (QQuickItem *item = qobject_cast<QQuickItem*>(menu)) - item->setParentItem(m_view); - - if (!title.isEmpty()) - QQmlProperty(menu, QStringLiteral("title")).write(title); - if (!pos.isNull()) - menu->setProperty("pos", pos); - - menu->setParent(parentMenu); - - QQmlProperty doneSignal(menu, QStringLiteral("onDone")); - static int deleteLaterIndex = menu->metaObject()->indexOfSlot("deleteLater()"); - CHECK_QML_SIGNAL_PROPERTY(doneSignal, menuComponent->url()); - QObject::connect(menu, doneSignal.method(), menu, menu->metaObject()->method(deleteLaterIndex)); - - QQmlListReference entries(parentMenu, defaultPropertyName(parentMenu), qmlEngine(m_view)); - if (entries.isValid()) - entries.append(menu); - - menuComponent->completeCreate(); - return menu; -} - -#define ASSIGN_DIALOG_COMPONENT_DATA_CASE_STATEMENT(TYPE, COMPONENT) \ - case TYPE:\ - dialogComponent = COMPONENT##Component; \ - break; - - -void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> dialogController) -{ - Q_ASSERT(!dialogController.isNull()); - ComponentType dialogComponentType = Invalid; - QString title; - switch (dialogController->type()) { - case WebContentsAdapterClient::AlertDialog: - dialogComponentType = AlertDialog; - title = tr("Javascript Alert - %1").arg(m_view->url().toString()); - break; - case WebContentsAdapterClient::ConfirmDialog: - dialogComponentType = ConfirmDialog; - title = tr("Javascript Confirm - %1").arg(m_view->url().toString()); - break; - case WebContentsAdapterClient::PromptDialog: - dialogComponentType = PromptDialog; - title = tr("Javascript Prompt - %1").arg(m_view->url().toString()); - break; - case WebContentsAdapterClient::UnloadDialog: - dialogComponentType = ConfirmDialog; - title = tr("Are you sure you want to leave this page?"); - break; - case WebContentsAdapterClient::InternalAuthorizationDialog: - dialogComponentType = ConfirmDialog; - title = dialogController->title(); - break; - default: - Q_UNREACHABLE(); - } - - if (!ensureComponentLoaded(dialogComponentType)) { - // Let the controller know it couldn't be loaded - qWarning("Failed to load dialog, rejecting."); - dialogController->reject(); - return; - } - - QQmlComponent *dialogComponent = nullptr; - switch (dialogComponentType) { - FOR_EACH_COMPONENT_TYPE(ASSIGN_DIALOG_COMPONENT_DATA_CASE_STATEMENT, NO_SEPARATOR) - default: - Q_UNREACHABLE(); - } - - QQmlContext *context = qmlContext(m_view); - QObject *dialog = dialogComponent->beginCreate(context); - // set visual parent for non-Window-based dialogs - if (QQuickItem *item = qobject_cast<QQuickItem*>(dialog)) - item->setParentItem(m_view); - dialog->setParent(m_view); - QQmlProperty textProp(dialog, QStringLiteral("text")); - if (dialogController->type() == WebContentsAdapterClient::UnloadDialog) - textProp.write(tr("Changes that you made may not be saved.")); - else - textProp.write(dialogController->message()); - - QQmlProperty titleProp(dialog, QStringLiteral("title")); - titleProp.write(title); - - QQmlProperty acceptSignal(dialog, QStringLiteral("onAccepted")); - QQmlProperty rejectSignal(dialog, QStringLiteral("onRejected")); - CHECK_QML_SIGNAL_PROPERTY(acceptSignal, dialogComponent->url()); - CHECK_QML_SIGNAL_PROPERTY(rejectSignal, dialogComponent->url()); - - static int acceptIndex = dialogController->metaObject()->indexOfSlot("accept()"); - QObject::connect(dialog, acceptSignal.method(), dialogController.data(), dialogController->metaObject()->method(acceptIndex)); - static int rejectIndex = dialogController->metaObject()->indexOfSlot("reject()"); - QObject::connect(dialog, rejectSignal.method(), dialogController.data(), dialogController->metaObject()->method(rejectIndex)); - - if (dialogComponentType == PromptDialog) { - QQmlProperty promptProp(dialog, QStringLiteral("prompt")); - promptProp.write(dialogController->defaultPrompt()); - QQmlProperty inputSignal(dialog, QStringLiteral("onInput")); - CHECK_QML_SIGNAL_PROPERTY(inputSignal, dialogComponent->url()); - static int setTextIndex = dialogController->metaObject()->indexOfSlot("textProvided(QString)"); - QObject::connect(dialog, inputSignal.method(), dialogController.data(), dialogController->metaObject()->method(setTextIndex)); - } - - dialogComponent->completeCreate(); - - QObject::connect(dialogController.data(), &JavaScriptDialogController::dialogCloseRequested, dialog, &QObject::deleteLater); - - QMetaObject::invokeMethod(dialog, "open"); -} - -void UIDelegatesManager::showColorDialog(QSharedPointer<ColorChooserController> controller) -{ - if (!ensureComponentLoaded(ColorDialog)) { - // Let the controller know it couldn't be loaded - qWarning("Failed to load dialog, rejecting."); - controller->reject(); - return; - } - - QQmlContext *context = qmlContext(m_view); - QObject *colorDialog = colorDialogComponent->beginCreate(context); - if (QQuickItem *item = qobject_cast<QQuickItem*>(colorDialog)) - item->setParentItem(m_view); - colorDialog->setParent(m_view); - - if (controller->initialColor().isValid()) - colorDialog->setProperty("color", controller->initialColor()); - - QQmlProperty selectedColorSignal(colorDialog, QStringLiteral("onSelectedColor")); - CHECK_QML_SIGNAL_PROPERTY(selectedColorSignal, colorDialogComponent->url()); - QQmlProperty rejectedSignal(colorDialog, QStringLiteral("onRejected")); - CHECK_QML_SIGNAL_PROPERTY(rejectedSignal, colorDialogComponent->url()); - - static int acceptIndex = controller->metaObject()->indexOfSlot("accept(QVariant)"); - QObject::connect(colorDialog, selectedColorSignal.method(), controller.data(), controller->metaObject()->method(acceptIndex)); - static int rejectIndex = controller->metaObject()->indexOfSlot("reject()"); - QObject::connect(colorDialog, rejectedSignal.method(), controller.data(), controller->metaObject()->method(rejectIndex)); - - // delete later - static int deleteLaterIndex = colorDialog->metaObject()->indexOfSlot("deleteLater()"); - QObject::connect(colorDialog, selectedColorSignal.method(), colorDialog, colorDialog->metaObject()->method(deleteLaterIndex)); - QObject::connect(colorDialog, rejectedSignal.method(), colorDialog, colorDialog->metaObject()->method(deleteLaterIndex)); - - colorDialogComponent->completeCreate(); - QMetaObject::invokeMethod(colorDialog, "open"); -} - -void UIDelegatesManager::showDialog(QSharedPointer<AuthenticationDialogController> dialogController) -{ - Q_ASSERT(!dialogController.isNull()); - - if (!ensureComponentLoaded(AuthenticationDialog)) { - // Let the controller know it couldn't be loaded - qWarning("Failed to load authentication dialog, rejecting."); - dialogController->reject(); - return; - } - - QQmlContext *context = qmlContext(m_view); - QObject *authenticationDialog = authenticationDialogComponent->beginCreate(context); - // set visual parent for non-Window-based dialogs - if (QQuickItem *item = qobject_cast<QQuickItem*>(authenticationDialog)) - item->setParentItem(m_view); - authenticationDialog->setParent(m_view); - - QString introMessage; - if (dialogController->isProxy()) { - introMessage = tr("Connect to proxy \"%1\" using:"); - introMessage = introMessage.arg(dialogController->host().toHtmlEscaped()); - } else { - const QUrl url = dialogController->url(); - introMessage = tr("Enter username and password for \"%1\" at %2://%3"); - introMessage = introMessage.arg(dialogController->realm(), url.scheme(), url.host()); - } - QQmlProperty textProp(authenticationDialog, QStringLiteral("text")); - textProp.write(introMessage); - - QQmlProperty acceptSignal(authenticationDialog, QStringLiteral("onAccepted")); - QQmlProperty rejectSignal(authenticationDialog, QStringLiteral("onRejected")); - CHECK_QML_SIGNAL_PROPERTY(acceptSignal, authenticationDialogComponent->url()); - CHECK_QML_SIGNAL_PROPERTY(rejectSignal, authenticationDialogComponent->url()); - - static int acceptIndex = dialogController->metaObject()->indexOfSlot("accept(QString,QString)"); - static int deleteLaterIndex = authenticationDialog->metaObject()->indexOfSlot("deleteLater()"); - QObject::connect(authenticationDialog, acceptSignal.method(), dialogController.data(), dialogController->metaObject()->method(acceptIndex)); - QObject::connect(authenticationDialog, acceptSignal.method(), authenticationDialog, authenticationDialog->metaObject()->method(deleteLaterIndex)); - static int rejectIndex = dialogController->metaObject()->indexOfSlot("reject()"); - QObject::connect(authenticationDialog, rejectSignal.method(), dialogController.data(), dialogController->metaObject()->method(rejectIndex)); - QObject::connect(authenticationDialog, rejectSignal.method(), authenticationDialog, authenticationDialog->metaObject()->method(deleteLaterIndex)); - - authenticationDialogComponent->completeCreate(); - QMetaObject::invokeMethod(authenticationDialog, "open"); -} - -void UIDelegatesManager::showFilePicker(QSharedPointer<FilePickerController> controller) -{ - - if (!ensureComponentLoaded(FilePicker)) - return; - - QQmlContext *context = qmlContext(m_view); - QObject *filePicker = filePickerComponent->beginCreate(context); - if (QQuickItem *item = qobject_cast<QQuickItem*>(filePicker)) - item->setParentItem(m_view); - filePicker->setParent(m_view); - filePickerComponent->completeCreate(); - - // Fine-tune some properties depending on the mode. - switch (controller->mode()) { - case FilePickerController::Open: - break; - case FilePickerController::Save: - filePicker->setProperty("selectExisting", false); - break; - case FilePickerController::OpenMultiple: - filePicker->setProperty("selectMultiple", true); - break; - case FilePickerController::UploadFolder: - filePicker->setProperty("selectFolder", true); - break; - default: - Q_UNREACHABLE(); - } - - QQmlProperty filesPickedSignal(filePicker, QStringLiteral("onFilesSelected")); - CHECK_QML_SIGNAL_PROPERTY(filesPickedSignal, filePickerComponent->url()); - QQmlProperty rejectSignal(filePicker, QStringLiteral("onRejected")); - CHECK_QML_SIGNAL_PROPERTY(rejectSignal, filePickerComponent->url()); - static int acceptedIndex = controller->metaObject()->indexOfSlot("accepted(QVariant)"); - QObject::connect(filePicker, filesPickedSignal.method(), controller.data(), controller->metaObject()->method(acceptedIndex)); - static int rejectedIndex = controller->metaObject()->indexOfSlot("rejected()"); - QObject::connect(filePicker, rejectSignal.method(), controller.data(), controller->metaObject()->method(rejectedIndex)); - - // delete when done. - static int deleteLaterIndex = filePicker->metaObject()->indexOfSlot("deleteLater()"); - QObject::connect(filePicker, filesPickedSignal.method(), filePicker, filePicker->metaObject()->method(deleteLaterIndex)); - QObject::connect(filePicker, rejectSignal.method(), filePicker, filePicker->metaObject()->method(deleteLaterIndex)); - - QMetaObject::invokeMethod(filePicker, "open"); -} - -class TemporaryCursorMove -{ -public: - TemporaryCursorMove(const QQuickItem *item, const QPoint &pos) - { - if (pos.isNull() || !item->contains(pos)) - return; - const QPoint oldPos = QCursor::pos(); - const QPoint globalPos = item->mapToGlobal(QPointF(pos)).toPoint(); - if (oldPos == globalPos) - return; - m_oldCursorPos = oldPos; - QCursor::setPos(globalPos); - } - - ~TemporaryCursorMove() - { - if (!m_oldCursorPos.isNull()) - QCursor::setPos(m_oldCursorPos); - } - -private: - QPoint m_oldCursorPos; -}; - -void UIDelegatesManager::showMenu(QObject *menu) -{ - // QtQuick.Controls.Menu.popup() always shows the menu under the mouse cursor, i.e. the menu's - // position we set above is ignored. Work around the problem by moving the mouse cursor - // temporarily to the right position. - TemporaryCursorMove tcm(m_view, menu->property("pos").toPoint()); - QMetaObject::invokeMethod(menu, "popup"); -} - -void UIDelegatesManager::showToolTip(const QString &text) -{ - if (text.isEmpty()) { - m_toolTip.reset(); - return; - } - - if (!ensureComponentLoaded(ToolTip)) - return; - - if (!m_toolTip.isNull()) - return; - - QQmlContext *context = qmlContext(m_view); - m_toolTip.reset(toolTipComponent->beginCreate(context)); - if (QQuickItem *item = qobject_cast<QQuickItem *>(m_toolTip.data())) - item->setParentItem(m_view); - m_toolTip->setParent(m_view); - toolTipComponent->completeCreate(); - - QQmlProperty(m_toolTip.data(), QStringLiteral("text")).write(text); - - int height = QQmlProperty(m_toolTip.data(), QStringLiteral("height")).read().toInt(); - int width = QQmlProperty(m_toolTip.data(), QStringLiteral("width")).read().toInt(); - QSize toolTipSize(width, height); - QPoint position = m_view->cursor().pos(); - position = m_view->mapFromGlobal(calculateToolTipPosition(position, toolTipSize)).toPoint(); - - QQmlProperty(m_toolTip.data(), QStringLiteral("x")).write(position.x()); - QQmlProperty(m_toolTip.data(), QStringLiteral("y")).write(position.y()); - - QMetaObject::invokeMethod(m_toolTip.data(), "open"); -} - -QQuickItem *UIDelegatesManager::createTouchHandle() -{ - if (!ensureComponentLoaded(TouchHandle)) - return nullptr; - - QQmlContext *context = qmlContext(m_view); - QObject *touchHandle = touchHandleComponent->beginCreate(context); - QQuickItem *item = qobject_cast<QQuickItem *>(touchHandle); - Q_ASSERT(item); - item->setParentItem(m_view); - touchHandleComponent->completeCreate(); - - return item; -} - -void UIDelegatesManager::showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *menuController, const QRect &bounds, const int spacing) -{ - if (!ensureComponentLoaded(TouchSelectionMenu)) - return; - - QQmlContext *context = qmlContext(m_view); - m_touchSelectionMenu.reset(touchSelectionMenuComponent->beginCreate(context)); - if (QQuickItem *item = qobject_cast<QQuickItem *>(m_touchSelectionMenu.data())) - item->setParentItem(m_view); - m_touchSelectionMenu->setParent(m_view); - - QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("width")).write(bounds.width()); - QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("height")).write(bounds.height()); - QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("x")).write(bounds.x()); - QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("y")).write(bounds.y()); - QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("border.width")).write(spacing); - - // Cut button - bool cutEnabled = menuController->isCommandEnabled(TouchSelectionMenuController::Cut); - QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("isCutEnabled")).write(cutEnabled); - if (cutEnabled) { - QQmlProperty cutSignal(m_touchSelectionMenu.data(), QStringLiteral("onCutTriggered")); - CHECK_QML_SIGNAL_PROPERTY(cutSignal, touchSelectionMenuComponent->url()); - int cutIndex = menuController->metaObject()->indexOfSlot("cut()"); - QObject::connect(m_touchSelectionMenu.data(), cutSignal.method(), menuController, menuController->metaObject()->method(cutIndex)); - } - - // Copy button - bool copyEnabled = menuController->isCommandEnabled(TouchSelectionMenuController::Copy); - QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("isCopyEnabled")).write(copyEnabled); - if (copyEnabled) { - QQmlProperty copySignal(m_touchSelectionMenu.data(), QStringLiteral("onCopyTriggered")); - CHECK_QML_SIGNAL_PROPERTY(copySignal, touchSelectionMenuComponent->url()); - int copyIndex = menuController->metaObject()->indexOfSlot("copy()"); - QObject::connect(m_touchSelectionMenu.data(), copySignal.method(), menuController, menuController->metaObject()->method(copyIndex)); - } - - // Paste button - bool pasteEnabled = menuController->isCommandEnabled(TouchSelectionMenuController::Paste); - QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("isPasteEnabled")).write(pasteEnabled); - if (pasteEnabled) { - QQmlProperty pasteSignal(m_touchSelectionMenu.data(), QStringLiteral("onPasteTriggered")); - CHECK_QML_SIGNAL_PROPERTY(pasteSignal, touchSelectionMenuComponent->url()); - int pasteIndex = menuController->metaObject()->indexOfSlot("paste()"); - QObject::connect(m_touchSelectionMenu.data(), pasteSignal.method(), menuController, menuController->metaObject()->method(pasteIndex)); - } - - // Context menu button - QQmlProperty contextMenuSignal(m_touchSelectionMenu.data(), QStringLiteral("onContextMenuTriggered")); - CHECK_QML_SIGNAL_PROPERTY(contextMenuSignal, touchSelectionMenuComponent->url()); - int contextMenuIndex = menuController->metaObject()->indexOfSlot("runContextMenu()"); - QObject::connect(m_touchSelectionMenu.data(), contextMenuSignal.method(), menuController, menuController->metaObject()->method(contextMenuIndex)); - - touchSelectionMenuComponent->completeCreate(); -} - -void UIDelegatesManager::hideTouchSelectionMenu() -{ - QTimer::singleShot(0, m_view, [this] { m_touchSelectionMenu.reset(); }); -} - -UI2DelegatesManager::UI2DelegatesManager(QQuickWebEngineView *view) : UIDelegatesManager(view) -{ - -} - -bool UI2DelegatesManager::initializeImportDirs(QStringList &dirs, QQmlEngine *engine) -{ - const QStringList paths = engine->importPathList(); - for (const QString &path : paths) { - QString controls2ImportPath = path % QLatin1String("/QtWebEngine/Controls2Delegates/"); - QString controls1ImportPath = path % QLatin1String("/QtWebEngine/Controls1Delegates/"); - - // resource paths have to be tested using the ":/" prefix - if (controls2ImportPath.startsWith(QLatin1String("qrc:/"))) { - controls2ImportPath.remove(0, 3); - controls1ImportPath.remove(0, 3); - } - - QFileInfo fi2(controls2ImportPath); - if (fi2.exists()) - dirs << fi2.absolutePath(); - - QFileInfo fi1(controls1ImportPath); - if (fi1.exists()) - dirs << fi1.absolutePath(); - } - return !dirs.isEmpty(); -} - -QObject *UI2DelegatesManager::addMenu(QObject *parentMenu, const QString &title, const QPoint &pos) -{ - Q_ASSERT(parentMenu); - if (!ensureComponentLoaded(Menu)) - return nullptr; - QQmlContext *context = qmlContext(m_view); - QObject *menu = menuComponent->beginCreate(context); - - // set visual parent for non-Window-based menus - if (QQuickItem *item = qobject_cast<QQuickItem*>(menu)) - item->setParentItem(m_view); - - if (!title.isEmpty()) - menu->setProperty("title", title); - if (!pos.isNull()) { - menu->setProperty("x", pos.x()); - menu->setProperty("y", pos.y()); - } - - menu->setParent(parentMenu); - QQmlProperty doneSignal(menu, QStringLiteral("onDone")); - CHECK_QML_SIGNAL_PROPERTY(doneSignal, menuComponent->url()) - static int deleteLaterIndex = menu->metaObject()->indexOfSlot("deleteLater()"); - QObject::connect(menu, doneSignal.method(), menu, menu->metaObject()->method(deleteLaterIndex)); - menuComponent->completeCreate(); - return menu; -} - -void UI2DelegatesManager::addMenuItem(QQuickWebEngineAction *action, QObject *menu, bool checkable, bool checked) -{ - Q_ASSERT(action); - if (!ensureComponentLoaded(MenuItem)) - return; - - QObject *it = menuItemComponent->beginCreate(qmlContext(m_view)); - - it->setProperty("text", action->text()); - it->setProperty("enabled", action->isEnabled()); - it->setProperty("checked", checked); - it->setProperty("checkable", checkable); - - QQmlProperty signal(it, QStringLiteral("onTriggered")); - CHECK_QML_SIGNAL_PROPERTY(signal, menuItemComponent->url()); - const QMetaObject *actionMeta = action->metaObject(); - QObject::connect(it, signal.method(), action, actionMeta->method(actionMeta->indexOfSlot("trigger()"))); - menuItemComponent->completeCreate(); - - it->setParent(menu); - - QQmlListReference entries(menu, defaultPropertyName(menu), qmlEngine(m_view)); - if (entries.isValid()) - entries.append(it); -} - -void UI2DelegatesManager::showMenu(QObject *menu) -{ - QMetaObject::invokeMethod(menu, "open"); -} - -} // namespace QtWebEngineCore |