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
*~
*.a
*.orig
*.qm
!qt_*.qm
headers*.tar.gz

@ -52,7 +52,7 @@ To install QupZilla, you will have to run this command: (it may be neccessary to
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.
However, if you want the latest revision, just take the latest code snapshot either by
downloading a tarball or running:

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

@ -1,6 +1,7 @@
#include "testplugin.h"
#include "qupzilla.h"
#include "webview.h"
#include "pluginproxy.h"
PluginSpec TestPlugin::pluginSpec()
{
@ -26,6 +27,8 @@ void TestPlugin::init(const QString &sPath)
m_settingsPath = sPath;
m_view = 0;
QZ_REGISTER_EVENT_HANDLER(PluginProxy::MousePressHandler);
}
void TestPlugin::unload()
@ -52,7 +55,7 @@ QTranslator* TestPlugin::getTranslator(const QString &locale)
return translator;
}
void TestPlugin::showSettings(QWidget *parent)
void TestPlugin::showSettings(QWidget* parent)
{
QDialog* dialog = new QDialog(parent);
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()));
}
bool TestPlugin::mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event)
{
qDebug() << "mousePress" << type << obj << event;
return false;
}
void TestPlugin::actionSlot()
{
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);
bool mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event);
private slots:
void actionSlot();

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

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

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

@ -63,7 +63,13 @@ public:
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 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")

@ -18,14 +18,62 @@
#include "pluginproxy.h"
#include "plugininterface.h"
#include "mainapplication.h"
#include "speeddial.h"
#include "settings.h"
PluginProxy::PluginProxy()
: 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)
@ -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;
settings.beginGroup("ClickToFlash");
c2f_whitelist = settings.value("whitelist", QStringList()).toStringList();
c2f_enabled = settings.value("Enabled", true).toBool();
settings.endGroup();
bool accepted = false;
foreach(PluginInterface * iPlugin, m_mousePressHandlers) {
if (iPlugin->mousePress(type, obj, event)) {
accepted = true;
}
}
return accepted;
}
void PluginProxy::c2f_saveSettings()
bool PluginProxy::processMouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event)
{
Settings settings;
settings.beginGroup("ClickToFlash");
settings.setValue("whitelist", c2f_whitelist);
settings.setValue("Enabled", c2f_enabled);
settings.endGroup();
bool accepted = false;
foreach(PluginInterface * iPlugin, m_mouseReleaseHandlers) {
if (iPlugin->mouseRelease(type, obj, event)) {
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 <QWebHitTestResult>
#include "mainapplication.h"
#include "plugins.h"
#include "qz_namespace.h"
class SpeedDial;
class PluginProxy : public Plugins
{
public:
enum EventHandlerType { MousePressHandler, MouseReleaseHandler, MouseMoveHandler, KeyPressHandler, KeyReleaseHandler };
explicit PluginProxy();
// Application API
void unloadPlugin(Plugin* plugin);
void registerAppEventHandler(const EventHandlerType &type, PluginInterface* obj);
void populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r);
// 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; }
bool processMousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event);
bool processMouseRelease(const Qz::ObjectName &object, QObject* obj, QMouseEvent* event);
bool processMouseMove(const Qz::ObjectName &object, QObject* obj, QMouseEvent* event);
// SpeedDial
SpeedDial* speedDial() { return m_speedDial; }
bool processKeyPress(const Qz::ObjectName &object, QObject* obj, QKeyEvent* event);
bool processKeyRelease(const Qz::ObjectName &object, QObject* obj, QKeyEvent* event);
private:
QStringList c2f_whitelist;
bool c2f_enabled;
QList<PluginInterface*> m_mousePressHandlers;
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

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

@ -27,6 +27,7 @@
#include <iostream>
#include "plugininterface.h"
class SpeedDial;
class Plugins : public QObject
{
Q_OBJECT
@ -54,9 +55,21 @@ public:
QList<Plugin> getAvailablePlugins() { return m_availablePlugins; }
void loadPlugin(Plugin* plugin);
bool loadPlugin(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:
void loadSettings();
void loadPlugins();
@ -73,6 +86,10 @@ private:
bool m_pluginsEnabled;
bool m_pluginsLoaded;
SpeedDial* m_speedDial;
QStringList c2f_whitelist;
bool c2f_enabled;
};
Q_DECLARE_METATYPE(Plugins::Plugin)

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

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

Loading…
Cancel
Save