1
mirror of https://invent.kde.org/network/falkon.git synced 2024-09-21 17:52:10 +02:00

Improved Plugin API. Plugins can now receive input events.

- mousePress, mouseRelease, mouseMove
- keyPress, keyRelease
- only WebView class is sending these events now
This commit is contained in:
nowrep 2012-02-22 18:33:44 +01:00
parent c082abdab9
commit 37f5d1bb6e
15 changed files with 267 additions and 55 deletions

1
.gitignore vendored
View File

@ -6,6 +6,7 @@ tools_
*.autosave *.autosave
*~ *~
*.a *.a
*.orig
*.qm *.qm
!qt_*.qm !qt_*.qm
headers*.tar.gz headers*.tar.gz

View File

@ -52,7 +52,7 @@ To install QupZilla, you will have to run this command: (it may be neccessary to
Current version Current version
---------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------
The current released version of QupZilla is 1.1.5. You can download precompiled packages The current released version of QupZilla is 1.1.8. You can download precompiled packages
and the sources from the download section. and the sources from the download section.
However, if you want the latest revision, just take the latest code snapshot either by However, if you want the latest revision, just take the latest code snapshot either by
downloading a tarball or running: downloading a tarball or running:

View File

@ -1,3 +1,5 @@
include(defines.pri)
INCLUDEPATH += $$PWD/src/3rdparty\ INCLUDEPATH += $$PWD/src/3rdparty\
$$PWD/src/app\ $$PWD/src/app\
$$PWD/src/autofill\ $$PWD/src/autofill\
@ -24,7 +26,7 @@ INCLUDEPATH += $$PWD/src/3rdparty\
TEMPLATE = lib TEMPLATE = lib
CONFIG += plugin CONFIG += plugin
DESTDIR = $$PWD/bin/plugins DESTDIR = $$PWD/bin/plugins/
OBJECTS_DIR = build OBJECTS_DIR = build
MOC_DIR = build MOC_DIR = build
@ -33,8 +35,6 @@ UI_DIR = build
LIBS += -L $$PWD/bin -lqupzilla LIBS += -L $$PWD/bin -lqupzilla
include(defines.pri)
!mac:unix { !mac:unix {
target.path = $$library_folder/qupzilla target.path = $$library_folder/qupzilla

View File

@ -1,6 +1,7 @@
#include "testplugin.h" #include "testplugin.h"
#include "qupzilla.h" #include "qupzilla.h"
#include "webview.h" #include "webview.h"
#include "pluginproxy.h"
PluginSpec TestPlugin::pluginSpec() PluginSpec TestPlugin::pluginSpec()
{ {
@ -26,6 +27,8 @@ void TestPlugin::init(const QString &sPath)
m_settingsPath = sPath; m_settingsPath = sPath;
m_view = 0; m_view = 0;
QZ_REGISTER_EVENT_HANDLER(PluginProxy::MousePressHandler);
} }
void TestPlugin::unload() void TestPlugin::unload()
@ -52,7 +55,7 @@ QTranslator* TestPlugin::getTranslator(const QString &locale)
return translator; return translator;
} }
void TestPlugin::showSettings(QWidget *parent) void TestPlugin::showSettings(QWidget* parent)
{ {
QDialog* dialog = new QDialog(parent); QDialog* dialog = new QDialog(parent);
QPushButton* b = new QPushButton("Example Plugin v0.0.1"); QPushButton* b = new QPushButton("Example Plugin v0.0.1");
@ -94,6 +97,13 @@ void TestPlugin::populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTe
menu->addAction(tr("My first plugin action") + title, this, SLOT(actionSlot())); menu->addAction(tr("My first plugin action") + title, this, SLOT(actionSlot()));
} }
bool TestPlugin::mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event)
{
qDebug() << "mousePress" << type << obj << event;
return false;
}
void TestPlugin::actionSlot() void TestPlugin::actionSlot()
{ {
QMessageBox::information(m_view, tr("Hello"), tr("First plugin action works :-)")); QMessageBox::information(m_view, tr("Hello"), tr("First plugin action works :-)"));

View File

@ -32,6 +32,8 @@ public:
void populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r); void populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r);
bool mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event);
private slots: private slots:
void actionSlot(); void actionSlot();

View File

@ -4,26 +4,38 @@
# astyle >=2.02 # astyle >=2.02
# #
echo "running astyle for *.cpp ..." function format_sources {
astyle --indent=spaces=4 --style=1tbs \
cd ../src
astyle --indent=spaces=4 --style=1tbs \
--indent-labels --pad-oper --unpad-paren --pad-header \ --indent-labels --pad-oper --unpad-paren --pad-header \
--convert-tabs --indent-preprocessor --break-closing-brackets \ --convert-tabs --indent-preprocessor --break-closing-brackets \
--align-pointer=type --align-reference=name \ --align-pointer=type --align-reference=name \
`find -type f -name '*.cpp'` `find -type f -name '*.cpp'`
echo "running astyle for *.h ..." rm */*.orig
}
astyle --indent=spaces=4 --style=linux \ function format_headers {
astyle --indent=spaces=4 --style=linux \
--indent-labels --pad-oper --unpad-paren --pad-header \ --indent-labels --pad-oper --unpad-paren --pad-header \
--keep-one-line-statements --keep-one-line-blocks \ --keep-one-line-statements --keep-one-line-blocks \
--indent-preprocessor --convert-tabs \ --indent-preprocessor --convert-tabs \
--align-pointer=type --align-reference=name \ --align-pointer=type --align-reference=name \
`find -type f -name '*.h'` `find -type f -name '*.h'`
rm */*.orig rm */*.orig
}
cd ../src
echo "running astyle for *.cpp ..."
format_sources
echo "running astyle for *.h ..."
format_headers
echo "running astyle for plugins ..."
cd ../plugins
format_sources
format_headers
read -p "Press [ENTER] to close terminal" read -p "Press [ENTER] to close terminal"
exit exit

View File

@ -3,14 +3,21 @@
# cppcheck # cppcheck
# #
function check_code {
cppcheck \
--enable=all \
--force \
--verbose \
. > /dev/null
}
echo "cppcheck..." echo "cppcheck..."
cd ../src cd ../src
cppcheck \ check_code
--enable=all \
--force \ cd ../plugins
--verbose \ check_code
. > /dev/null
read -p "Press [ENTER] to close terminal" read -p "Press [ENTER] to close terminal"
exit exit

View File

@ -8,7 +8,7 @@ ProxyStyle::ProxyStyle()
int ProxyStyle::styleHint(StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData) const int ProxyStyle::styleHint(StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData) const
{ {
if (hint == QStyle::SH_Menu_Scrollable) { if (hint == QStyle::SH_Menu_Scrollable) {
return 1; return int(true);
} }
return QProxyStyle::styleHint(hint, option, widget, returnData); return QProxyStyle::styleHint(hint, option, widget, returnData);

View File

@ -63,7 +63,13 @@ public:
virtual void showSettings(QWidget* parent = 0) { Q_UNUSED(parent) } virtual void showSettings(QWidget* parent = 0) { Q_UNUSED(parent) }
virtual void populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r) { Q_UNUSED(menu) Q_UNUSED(view) Q_UNUSED(r) } virtual void populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r) { Q_UNUSED(menu) Q_UNUSED(view) Q_UNUSED(r) }
virtual bool processEvent(const Qz::ObjectName &type, QObject* obj, QEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; }
virtual bool mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; }
virtual bool mouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; }
virtual bool mouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; }
virtual bool keyPress(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; }
virtual bool keyRelease(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event) { Q_UNUSED(type) Q_UNUSED(obj) Q_UNUSED(event) return false; }
}; };
Q_DECLARE_INTERFACE(PluginInterface, "QupZilla.Browser.PluginInterface/1.1") Q_DECLARE_INTERFACE(PluginInterface, "QupZilla.Browser.PluginInterface/1.1")

View File

@ -18,14 +18,62 @@
#include "pluginproxy.h" #include "pluginproxy.h"
#include "plugininterface.h" #include "plugininterface.h"
#include "mainapplication.h" #include "mainapplication.h"
#include "speeddial.h"
#include "settings.h" #include "settings.h"
PluginProxy::PluginProxy() PluginProxy::PluginProxy()
: Plugins() : Plugins()
, m_speedDial(new SpeedDial(this))
{ {
c2f_loadSettings(); }
void PluginProxy::unloadPlugin(Plugins::Plugin* plugin)
{
m_mousePressHandlers.removeOne(plugin->instance);
m_mouseReleaseHandlers.removeOne(plugin->instance);
m_mouseMoveHandlers.removeOne(plugin->instance);
m_keyPressHandlers.removeOne(plugin->instance);
m_keyReleaseHandlers.removeOne(plugin->instance);
Plugins::unloadPlugin(plugin);
}
void PluginProxy::registerAppEventHandler(const PluginProxy::EventHandlerType &type, PluginInterface* obj)
{
switch (type) {
case MousePressHandler:
if (!m_mousePressHandlers.contains(obj)) {
m_mousePressHandlers.append(obj);
}
break;
case MouseReleaseHandler:
if (!m_mouseReleaseHandlers.contains(obj)) {
m_mouseReleaseHandlers.append(obj);
}
break;
case MouseMoveHandler:
if (!m_mouseMoveHandlers.contains(obj)) {
m_mouseMoveHandlers.append(obj);
}
break;
case KeyPressHandler:
if (!m_keyPressHandlers.contains(obj)) {
m_keyPressHandlers.append(obj);
}
break;
case KeyReleaseHandler:
if (!m_keyReleaseHandlers.contains(obj)) {
m_keyReleaseHandlers.append(obj);
}
break;
default:
qWarning("PluginProxy::registerAppEventHandler registering unknown event handler type");
break;
}
} }
void PluginProxy::populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r) void PluginProxy::populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r)
@ -46,20 +94,68 @@ void PluginProxy::populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitT
} }
} }
void PluginProxy::c2f_loadSettings() bool PluginProxy::processMousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event)
{ {
Settings settings; bool accepted = false;
settings.beginGroup("ClickToFlash");
c2f_whitelist = settings.value("whitelist", QStringList()).toStringList(); foreach(PluginInterface * iPlugin, m_mousePressHandlers) {
c2f_enabled = settings.value("Enabled", true).toBool(); if (iPlugin->mousePress(type, obj, event)) {
settings.endGroup(); accepted = true;
}
}
return accepted;
} }
void PluginProxy::c2f_saveSettings() bool PluginProxy::processMouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event)
{ {
Settings settings; bool accepted = false;
settings.beginGroup("ClickToFlash");
settings.setValue("whitelist", c2f_whitelist); foreach(PluginInterface * iPlugin, m_mouseReleaseHandlers) {
settings.setValue("Enabled", c2f_enabled); if (iPlugin->mouseRelease(type, obj, event)) {
settings.endGroup(); accepted = true;
}
}
return accepted;
} }
bool PluginProxy::processMouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event)
{
bool accepted = false;
foreach(PluginInterface * iPlugin, m_mouseMoveHandlers) {
if (iPlugin->mouseMove(type, obj, event)) {
accepted = true;
}
}
return accepted;
}
bool PluginProxy::processKeyPress(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event)
{
bool accepted = false;
foreach(PluginInterface * iPlugin, m_keyPressHandlers) {
if (iPlugin->keyPress(type, obj, event)) {
accepted = true;
}
}
return accepted;
}
bool PluginProxy::processKeyRelease(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event)
{
bool accepted = false;
foreach(PluginInterface * iPlugin, m_keyReleaseHandlers) {
if (iPlugin->keyRelease(type, obj, event)) {
accepted = true;
}
}
return accepted;
}

View File

@ -23,35 +23,39 @@
#include <QWebView> #include <QWebView>
#include <QWebHitTestResult> #include <QWebHitTestResult>
#include "mainapplication.h"
#include "plugins.h" #include "plugins.h"
#include "qz_namespace.h" #include "qz_namespace.h"
class SpeedDial;
class PluginProxy : public Plugins class PluginProxy : public Plugins
{ {
public: public:
enum EventHandlerType { MousePressHandler, MouseReleaseHandler, MouseMoveHandler, KeyPressHandler, KeyReleaseHandler };
explicit PluginProxy(); explicit PluginProxy();
// Application API void unloadPlugin(Plugin* plugin);
void registerAppEventHandler(const EventHandlerType &type, PluginInterface* obj);
void populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r); void populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r);
// CLick2Flash bool processMousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event);
void c2f_loadSettings(); bool processMouseRelease(const Qz::ObjectName &object, QObject* obj, QMouseEvent* event);
void c2f_saveSettings(); bool processMouseMove(const Qz::ObjectName &object, QObject* obj, QMouseEvent* event);
void c2f_addWhitelist(QString page) { c2f_whitelist.append(page); }
void c2f_removeWhitelist(QString page) { c2f_whitelist.removeOne(page); }
void c2f_setEnabled(bool en) { c2f_enabled = en; }
bool c2f_isEnabled() { return c2f_enabled; }
QStringList c2f_getWhiteList() { return c2f_whitelist; }
// SpeedDial bool processKeyPress(const Qz::ObjectName &object, QObject* obj, QKeyEvent* event);
SpeedDial* speedDial() { return m_speedDial; } bool processKeyRelease(const Qz::ObjectName &object, QObject* obj, QKeyEvent* event);
private: private:
QStringList c2f_whitelist; QList<PluginInterface*> m_mousePressHandlers;
bool c2f_enabled; QList<PluginInterface*> m_mouseReleaseHandlers;
QList<PluginInterface*> m_mouseMoveHandlers;
QList<PluginInterface*> m_keyPressHandlers;
QList<PluginInterface*> m_keyReleaseHandlers;
SpeedDial* m_speedDial;
}; };
#define QZ_REGISTER_EVENT_HANDLER(Type) mApp->plugins()->registerAppEventHandler(Type, this);
#endif // PLUGINPROXY_H #endif // PLUGINPROXY_H

View File

@ -18,6 +18,7 @@
#include "pluginproxy.h" #include "pluginproxy.h"
#include "plugininterface.h" #include "plugininterface.h"
#include "mainapplication.h" #include "mainapplication.h"
#include "speeddial.h"
#include "settings.h" #include "settings.h"
#ifdef PORTABLE_BUILD #ifdef PORTABLE_BUILD
@ -29,20 +30,21 @@
Plugins::Plugins(QObject* parent) Plugins::Plugins(QObject* parent)
: QObject(parent) : QObject(parent)
, m_pluginsLoaded(false) , m_pluginsLoaded(false)
, m_speedDial(new SpeedDial(this))
{ {
loadSettings(); loadSettings();
} }
void Plugins::loadPlugin(Plugins::Plugin* plugin) bool Plugins::loadPlugin(Plugins::Plugin* plugin)
{ {
if (plugin->isLoaded()) { if (plugin->isLoaded()) {
return; return true;
} }
plugin->pluginLoader->setFileName(plugin->fullPath); plugin->pluginLoader->setFileName(plugin->fullPath);
PluginInterface* iPlugin = qobject_cast<PluginInterface*>(plugin->pluginLoader->instance()); PluginInterface* iPlugin = qobject_cast<PluginInterface*>(plugin->pluginLoader->instance());
if (!iPlugin) { if (!iPlugin) {
return; return false;
} }
m_availablePlugins.removeOne(*plugin); m_availablePlugins.removeOne(*plugin);
@ -50,6 +52,8 @@ void Plugins::loadPlugin(Plugins::Plugin* plugin)
m_availablePlugins.append(*plugin); m_availablePlugins.append(*plugin);
refreshLoadedPlugins(); refreshLoadedPlugins();
return plugin->isLoaded();
} }
void Plugins::unloadPlugin(Plugins::Plugin* plugin) void Plugins::unloadPlugin(Plugins::Plugin* plugin)
@ -75,8 +79,29 @@ void Plugins::loadSettings()
m_pluginsEnabled = settings.value("EnablePlugins", DEFAULT_ENABLE_PLUGINS).toBool(); m_pluginsEnabled = settings.value("EnablePlugins", DEFAULT_ENABLE_PLUGINS).toBool();
m_allowedPluginFileNames = settings.value("AllowedPlugins", QStringList()).toStringList(); m_allowedPluginFileNames = settings.value("AllowedPlugins", QStringList()).toStringList();
settings.endGroup(); settings.endGroup();
c2f_loadSettings();
} }
void Plugins::c2f_loadSettings()
{
Settings settings;
settings.beginGroup("ClickToFlash");
c2f_whitelist = settings.value("whitelist", QStringList()).toStringList();
c2f_enabled = settings.value("Enabled", true).toBool();
settings.endGroup();
}
void Plugins::c2f_saveSettings()
{
Settings settings;
settings.beginGroup("ClickToFlash");
settings.setValue("whitelist", c2f_whitelist);
settings.setValue("Enabled", c2f_enabled);
settings.endGroup();
}
void Plugins::loadPlugins() void Plugins::loadPlugins()
{ {
if (!m_pluginsEnabled || m_pluginsLoaded) { if (!m_pluginsEnabled || m_pluginsLoaded) {

View File

@ -27,6 +27,7 @@
#include <iostream> #include <iostream>
#include "plugininterface.h" #include "plugininterface.h"
class SpeedDial;
class Plugins : public QObject class Plugins : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -54,9 +55,21 @@ public:
QList<Plugin> getAvailablePlugins() { return m_availablePlugins; } QList<Plugin> getAvailablePlugins() { return m_availablePlugins; }
void loadPlugin(Plugin* plugin); bool loadPlugin(Plugin* plugin);
void unloadPlugin(Plugin* plugin); void unloadPlugin(Plugin* plugin);
// CLick2Flash
void c2f_loadSettings();
void c2f_saveSettings();
void c2f_addWhitelist(QString page) { c2f_whitelist.append(page); }
void c2f_removeWhitelist(QString page) { c2f_whitelist.removeOne(page); }
void c2f_setEnabled(bool en) { c2f_enabled = en; }
bool c2f_isEnabled() { return c2f_enabled; }
QStringList c2f_getWhiteList() { return c2f_whitelist; }
// SpeedDial
SpeedDial* speedDial() { return m_speedDial; }
public slots: public slots:
void loadSettings(); void loadSettings();
void loadPlugins(); void loadPlugins();
@ -73,6 +86,10 @@ private:
bool m_pluginsEnabled; bool m_pluginsEnabled;
bool m_pluginsLoaded; bool m_pluginsLoaded;
SpeedDial* m_speedDial;
QStringList c2f_whitelist;
bool c2f_enabled;
}; };
Q_DECLARE_METATYPE(Plugins::Plugin) Q_DECLARE_METATYPE(Plugins::Plugin)

View File

@ -768,6 +768,10 @@ void WebView::wheelEvent(QWheelEvent* event)
void WebView::mousePressEvent(QMouseEvent* event) void WebView::mousePressEvent(QMouseEvent* event)
{ {
if (mApp->plugins()->processMousePress(Qz::ON_WebView, this, event)) {
return;
}
switch (event->button()) { switch (event->button()) {
case Qt::XButton1: case Qt::XButton1:
back(); back();
@ -820,6 +824,10 @@ void WebView::mousePressEvent(QMouseEvent* event)
void WebView::mouseReleaseEvent(QMouseEvent* event) void WebView::mouseReleaseEvent(QMouseEvent* event)
{ {
if (mApp->plugins()->processMouseRelease(Qz::ON_WebView, this, event)) {
return;
}
switch (event->button()) { switch (event->button()) {
case Qt::MiddleButton: { case Qt::MiddleButton: {
QWebFrame* frame = page()->frameAt(event->pos()); QWebFrame* frame = page()->frameAt(event->pos());
@ -842,8 +850,21 @@ void WebView::mouseReleaseEvent(QMouseEvent* event)
QWebView::mouseReleaseEvent(event); QWebView::mouseReleaseEvent(event);
} }
void WebView::mouseMoveEvent(QMouseEvent* event)
{
if (mApp->plugins()->processMouseMove(Qz::ON_WebView, this, event)) {
return;
}
QWebView::mouseMoveEvent(event);
}
void WebView::keyPressEvent(QKeyEvent* event) void WebView::keyPressEvent(QKeyEvent* event)
{ {
if (mApp->plugins()->processKeyPress(Qz::ON_WebView, this, event)) {
return;
}
switch (event->key()) { switch (event->key()) {
case Qt::Key_C: case Qt::Key_C:
if (event->modifiers() == Qt::ControlModifier) { if (event->modifiers() == Qt::ControlModifier) {
@ -868,6 +889,15 @@ void WebView::keyPressEvent(QKeyEvent* event)
QWebView::keyPressEvent(event); QWebView::keyPressEvent(event);
} }
void WebView::keyReleaseEvent(QKeyEvent* event)
{
if (mApp->plugins()->processKeyRelease(Qz::ON_WebView, this, event)) {
return;
}
QWebView::keyReleaseEvent(event);
}
void WebView::resizeEvent(QResizeEvent* event) void WebView::resizeEvent(QResizeEvent* event)
{ {
QWebView::resizeEvent(event); QWebView::resizeEvent(event);

View File

@ -110,7 +110,9 @@ protected:
void wheelEvent(QWheelEvent* event); void wheelEvent(QWheelEvent* event);
void mousePressEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void keyPressEvent(QKeyEvent* event); void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
void resizeEvent(QResizeEvent* event); void resizeEvent(QResizeEvent* event);
void setZoom(int zoom); void setZoom(int zoom);