File indexing completed on 2024-12-22 04:41:15
0001 /* ============================================================ 0002 * Falkon - Qt web browser 0003 * Copyright (C) 2018 Anmol Gautam <tarptaeya@gmail.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 * ============================================================ */ 0018 #include "qmlplugininterface.h" 0019 #include "mainapplication.h" 0020 #include "pluginproxy.h" 0021 #include "statusbar.h" 0022 #include "browserwindow.h" 0023 #include "navigationbar.h" 0024 #include "sidebar.h" 0025 #include "api/menus/qmlmenu.h" 0026 #include "api/menus/qmlwebhittestresult.h" 0027 #include "api/events/qmlqzobjects.h" 0028 #include "api/events/qmlmouseevent.h" 0029 #include "api/events/qmlwheelevent.h" 0030 #include "api/events/qmlkeyevent.h" 0031 #include "api/tabs/qmltab.h" 0032 #include "webpage.h" 0033 #include "qztools.h" 0034 #include "qml/qmlengine.h" 0035 #include <QDebug> 0036 #include <QQuickWidget> 0037 #include <QDialog> 0038 #include <QVBoxLayout> 0039 0040 QmlPluginInterface::QmlPluginInterface() 0041 : m_qmlReusableTab(new QmlTab()) 0042 { 0043 } 0044 0045 QmlPluginInterface::~QmlPluginInterface() 0046 { 0047 m_qmlReusableTab->deleteLater(); 0048 } 0049 0050 void QmlPluginInterface::init(InitState state, const QString &settingsPath) 0051 { 0052 if (!m_init.isCallable()) { 0053 qWarning() << "Unable to call" << __FUNCTION__ << "on" << m_name << "plugin"; 0054 return; 0055 } 0056 0057 QJSValueList args; 0058 args.append(state); 0059 args.append(settingsPath); 0060 m_init.call(args); 0061 } 0062 0063 void QmlPluginInterface::unload() 0064 { 0065 if (!m_unload.isCallable()) { 0066 qWarning() << "Unable to call" << __FUNCTION__ << "on" << m_name << "plugin"; 0067 return; 0068 } 0069 0070 m_unload.call(); 0071 0072 for (QObject *childItem : std::as_const(m_childItems)) { 0073 childItem->deleteLater(); 0074 } 0075 0076 Q_EMIT qmlPluginUnloaded(); 0077 } 0078 0079 bool QmlPluginInterface::testPlugin() 0080 { 0081 if (!m_testPlugin.isCallable()) { 0082 qWarning() << "Unable to call" << __FUNCTION__ << "on" << m_name << "plugin"; 0083 return false; 0084 } 0085 0086 QJSValue ret = m_testPlugin.call(); 0087 return ret.toBool(); 0088 } 0089 0090 void QmlPluginInterface::populateWebViewMenu(QMenu *menu, WebView *webview, const WebHitTestResult &webHitTestResult) 0091 { 0092 Q_UNUSED(webview) 0093 0094 if (!m_populateWebViewMenu.isCallable()) { 0095 return; 0096 } 0097 0098 auto *qmlMenu = new QmlMenu(menu, m_engine); 0099 auto *qmlWebHitTestResult = new QmlWebHitTestResult(webHitTestResult); 0100 QJSValueList args; 0101 args.append(m_engine->newQObject(qmlMenu)); 0102 args.append(m_engine->newQObject(qmlWebHitTestResult)); 0103 m_populateWebViewMenu.call(args); 0104 menu->addSeparator(); 0105 } 0106 0107 void QmlPluginInterface::showSettings(QWidget *parent) 0108 { 0109 if (!m_settingsWindow) { 0110 qWarning() << "No dialog to show"; 0111 return; 0112 } 0113 0114 auto *widget = new QQuickWidget(); 0115 widget->setContent(m_settingsWindow->url(), m_settingsWindow, m_settingsWindow->create(m_settingsWindow->creationContext())); 0116 widget->show(); 0117 0118 QzTools::centerWidgetToParent(widget, parent); 0119 } 0120 0121 bool QmlPluginInterface::mouseDoubleClick(Qz::ObjectName type, QObject *obj, QMouseEvent *event) 0122 { 0123 Q_UNUSED(obj) 0124 if (!m_mouseDoubleClick.isCallable()) { 0125 return false; 0126 } 0127 auto qmlMouseEvent = new QmlMouseEvent(event); 0128 QJSValueList args; 0129 args.append(QmlQzObjects::ObjectName(type)); 0130 args.append(m_engine->newQObject(qmlMouseEvent)); 0131 m_mouseDoubleClick.call(args); 0132 qmlMouseEvent->clear(); 0133 return false; 0134 } 0135 0136 bool QmlPluginInterface::mousePress(Qz::ObjectName type, QObject *obj, QMouseEvent *event) 0137 { 0138 Q_UNUSED(obj) 0139 if (!m_mousePress.isCallable()) { 0140 return false; 0141 } 0142 auto qmlMouseEvent = new QmlMouseEvent(event); 0143 QJSValueList args; 0144 args.append(QmlQzObjects::ObjectName(type)); 0145 args.append(m_engine->newQObject(qmlMouseEvent)); 0146 m_mousePress.call(args); 0147 qmlMouseEvent->clear(); 0148 return false; 0149 } 0150 0151 bool QmlPluginInterface::mouseRelease(Qz::ObjectName type, QObject *obj, QMouseEvent *event) 0152 { 0153 Q_UNUSED(obj) 0154 if (!m_mouseRelease.isCallable()) { 0155 return false; 0156 } 0157 auto qmlMouseEvent = new QmlMouseEvent(event); 0158 QJSValueList args; 0159 args.append(QmlQzObjects::ObjectName(type)); 0160 args.append(m_engine->newQObject(qmlMouseEvent)); 0161 m_mouseRelease.call(args); 0162 qmlMouseEvent->clear(); 0163 return false; 0164 } 0165 0166 bool QmlPluginInterface::mouseMove(Qz::ObjectName type, QObject *obj, QMouseEvent *event) 0167 { 0168 Q_UNUSED(obj) 0169 if (!m_mouseMove.isCallable()) { 0170 return false; 0171 } 0172 auto qmlMouseEvent = new QmlMouseEvent(event); 0173 QJSValueList args; 0174 args.append(QmlQzObjects::ObjectName(type)); 0175 args.append(m_engine->newQObject(qmlMouseEvent)); 0176 m_mouseMove.call(args); 0177 qmlMouseEvent->clear(); 0178 return false; 0179 } 0180 0181 bool QmlPluginInterface::wheelEvent(Qz::ObjectName type, QObject *obj, QWheelEvent *event) 0182 { 0183 Q_UNUSED(obj) 0184 if (!m_wheelEvent.isCallable()) { 0185 return false; 0186 } 0187 auto qmlWheelEvent = new QmlWheelEvent(event); 0188 QJSValueList args; 0189 args.append(QmlQzObjects::ObjectName(type)); 0190 args.append(m_engine->newQObject(qmlWheelEvent)); 0191 m_wheelEvent.call(args); 0192 qmlWheelEvent->clear(); 0193 return false; 0194 } 0195 0196 bool QmlPluginInterface::keyPress(Qz::ObjectName type, QObject *obj, QKeyEvent *event) 0197 { 0198 Q_UNUSED(obj) 0199 if (!m_keyPress.isCallable()) { 0200 return false; 0201 } 0202 auto qmlKeyEvent = new QmlKeyEvent(event); 0203 QJSValueList args; 0204 args.append(QmlQzObjects::ObjectName(type)); 0205 args.append(m_engine->newQObject(qmlKeyEvent)); 0206 m_keyPress.call(args); 0207 qmlKeyEvent->clear(); 0208 return false; 0209 } 0210 0211 bool QmlPluginInterface::keyRelease(Qz::ObjectName type, QObject *obj, QKeyEvent *event) 0212 { 0213 Q_UNUSED(obj) 0214 if (!m_keyRelease.isCallable()) { 0215 return false; 0216 } 0217 auto qmlKeyEvent = new QmlKeyEvent(event); 0218 QJSValueList args; 0219 args.append(QmlQzObjects::ObjectName(type)); 0220 args.append(m_engine->newQObject(qmlKeyEvent)); 0221 m_keyRelease.call(args); 0222 qmlKeyEvent->clear(); 0223 return false; 0224 } 0225 0226 bool QmlPluginInterface::acceptNavigationRequest(WebPage *page, const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) 0227 { 0228 if (!m_acceptNavigationRequest.isCallable()) { 0229 return true; 0230 } 0231 m_qmlReusableTab->setWebPage(page); 0232 QJSValueList args; 0233 args.append(m_engine->newQObject(m_qmlReusableTab)); 0234 args.append(QString::fromUtf8(url.toEncoded())); 0235 args.append(type); 0236 args.append(isMainFrame); 0237 return m_acceptNavigationRequest.call(args).toBool(); 0238 } 0239 0240 QJSValue QmlPluginInterface::readInit() const 0241 { 0242 return m_init; 0243 } 0244 0245 void QmlPluginInterface::setInit(const QJSValue &init) 0246 { 0247 m_init = init; 0248 } 0249 0250 QJSValue QmlPluginInterface::readUnload() const 0251 { 0252 return m_unload; 0253 } 0254 0255 void QmlPluginInterface::setUnload(const QJSValue &unload) 0256 { 0257 m_unload = unload; 0258 } 0259 0260 QJSValue QmlPluginInterface::readTestPlugin() const 0261 { 0262 return m_testPlugin; 0263 } 0264 0265 void QmlPluginInterface::setTestPlugin(const QJSValue &testPlugin) 0266 { 0267 m_testPlugin = testPlugin; 0268 } 0269 0270 void QmlPluginInterface::setEngine(QQmlEngine *engine) 0271 { 0272 m_engine = engine; 0273 } 0274 0275 void QmlPluginInterface::setName(const QString &name) 0276 { 0277 m_name = name; 0278 } 0279 0280 QJSValue QmlPluginInterface::readPopulateWebViewMenu() const 0281 { 0282 return m_populateWebViewMenu; 0283 } 0284 0285 void QmlPluginInterface::setPopulateWebViewMenu(const QJSValue &value) 0286 { 0287 m_populateWebViewMenu = value; 0288 } 0289 0290 QQmlComponent *QmlPluginInterface::settingsWindow() const 0291 { 0292 return m_settingsWindow; 0293 } 0294 0295 void QmlPluginInterface::setSettingsWindow(QQmlComponent *settingsWindow) 0296 { 0297 m_settingsWindow = settingsWindow; 0298 } 0299 0300 QJSValue QmlPluginInterface::readMouseDoubleClick() const 0301 { 0302 return m_mouseDoubleClick; 0303 } 0304 0305 void QmlPluginInterface::setMouseDoubleClick(const QJSValue &mouseDoubleClick) 0306 { 0307 m_mouseDoubleClick = mouseDoubleClick; 0308 mApp->plugins()->registerAppEventHandler(PluginProxy::MouseDoubleClickHandler, this); 0309 } 0310 0311 QJSValue QmlPluginInterface::readMousePress() const 0312 { 0313 return m_mousePress; 0314 } 0315 0316 void QmlPluginInterface::setMousePress(const QJSValue &mousePress) 0317 { 0318 m_mousePress = mousePress; 0319 mApp->plugins()->registerAppEventHandler(PluginProxy::MousePressHandler, this); 0320 } 0321 0322 QJSValue QmlPluginInterface::readMouseRelease() const 0323 { 0324 return m_mouseRelease; 0325 } 0326 0327 void QmlPluginInterface::setMouseRelease(const QJSValue &mouseRelease) 0328 { 0329 m_mouseRelease = mouseRelease; 0330 mApp->plugins()->registerAppEventHandler(PluginProxy::MouseReleaseHandler, this); 0331 } 0332 0333 QJSValue QmlPluginInterface::readMouseMove() const 0334 { 0335 return m_mouseMove; 0336 } 0337 0338 void QmlPluginInterface::setMouseMove(const QJSValue &mouseMove) 0339 { 0340 m_mouseMove = mouseMove; 0341 mApp->plugins()->registerAppEventHandler(PluginProxy::MouseMoveHandler, this); 0342 } 0343 0344 QJSValue QmlPluginInterface::readWheelEvent() const 0345 { 0346 return m_wheelEvent; 0347 } 0348 0349 void QmlPluginInterface::setWheelEvent(const QJSValue &wheelEvent) 0350 { 0351 m_wheelEvent = wheelEvent; 0352 mApp->plugins()->registerAppEventHandler(PluginProxy::WheelEventHandler, this); 0353 } 0354 0355 QJSValue QmlPluginInterface::readKeyPress() const 0356 { 0357 return m_keyPress; 0358 } 0359 0360 void QmlPluginInterface::setKeyPress(const QJSValue &keyPress) 0361 { 0362 m_keyPress = keyPress; 0363 mApp->plugins()->registerAppEventHandler(PluginProxy::KeyPressHandler, this); 0364 } 0365 0366 QJSValue QmlPluginInterface::readKeyRelease() const 0367 { 0368 return m_keyRelease; 0369 } 0370 0371 void QmlPluginInterface::setKeyRelease(const QJSValue &keyRelease) 0372 { 0373 m_keyRelease = keyRelease; 0374 mApp->plugins()->registerAppEventHandler(PluginProxy::KeyReleaseHandler, this); 0375 } 0376 0377 QJSValue QmlPluginInterface::readAcceptNavigationRequest() const 0378 { 0379 return m_acceptNavigationRequest; 0380 } 0381 0382 void QmlPluginInterface::setAcceptNavigationRequest(const QJSValue &acceptNavigationRequest) 0383 { 0384 m_acceptNavigationRequest = acceptNavigationRequest; 0385 } 0386 0387 QQmlListProperty<QObject> QmlPluginInterface::childItems() 0388 { 0389 return QQmlListProperty<QObject>(this, &m_childItems); 0390 }