Improved Plugin API. Plugins can now receive input events.

- mousePress, mouseRelease, mouseMove
- keyPress, keyRelease
- only WebView class is sending these events now
remotes/origin/falkon
nowrep 14 years ago
parent c082abdab9
commit 37f5d1bb6e
  1. 1
      .gitignore
  2. 2
      README.md
  3. 6
      plugins.pri
  4. 12
      plugins/TestPlugin/testplugin.cpp
  5. 2
      plugins/TestPlugin/testplugin.h
  6. 30
      scripts/coding_style.sh
  7. 17
      scripts/cppcheck.sh
  8. 2
      src/app/proxystyle.cpp
  9. 8
      src/plugins/plugininterface.h
  10. 126
      src/plugins/pluginproxy.cpp
  11. 34
      src/plugins/pluginproxy.h
  12. 31
      src/plugins/plugins.cpp
  13. 19
      src/plugins/plugins.h
  14. 30
      src/webview/webview.cpp
  15. 2
      src/webview/webview.h

1
.gitignore vendored

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

@ -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:

@ -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

@ -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 :-)"));

@ -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();

@ -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'`
rm */*.orig
}
echo "running astyle for *.h ..." function format_headers {
astyle --indent=spaces=4 --style=linux \
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

@ -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

@ -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);

@ -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")

@ -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;
}

@ -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

@ -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) {

@ -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)

@ -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);

@ -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);

Loading…
Cancel
Save