diff --git a/src/plugins/AutoScroll/AutoScroll.pro b/src/plugins/AutoScroll/AutoScroll.pro
new file mode 100644
index 000000000..70831caa0
--- /dev/null
+++ b/src/plugins/AutoScroll/AutoScroll.pro
@@ -0,0 +1,15 @@
+TARGET = $$qtLibraryTarget(AutoScroll)
+# OS/2 allows only 8 chars in TARGET
+os2: TARGET = AutoScrl
+
+SOURCES += autoscrollplugin.cpp \
+ autoscroller.cpp \
+ framescroller.cpp
+
+HEADERS += autoscrollplugin.h \
+ autoscroller.h \
+ framescroller.h
+
+RESOURCES += autoscroll.qrc
+
+include(../../plugins.pri)
diff --git a/src/plugins/AutoScroll/autoscroll.qrc b/src/plugins/AutoScroll/autoscroll.qrc
new file mode 100644
index 000000000..90805a517
--- /dev/null
+++ b/src/plugins/AutoScroll/autoscroll.qrc
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/plugins/AutoScroll/autoscroller.cpp b/src/plugins/AutoScroll/autoscroller.cpp
new file mode 100644
index 000000000..82ea68b2b
--- /dev/null
+++ b/src/plugins/AutoScroll/autoscroller.cpp
@@ -0,0 +1,179 @@
+/* ============================================================
+* QupZilla - WebKit based browser
+* Copyright (C) 2014 David Rosca
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+* ============================================================ */
+#include "autoscroller.h"
+#include "framescroller.h"
+#include "webview.h"
+#include "webpage.h"
+
+#include
+#include
+#include
+#include
+
+AutoScroller::AutoScroller(const QString &settings, QObject* parent)
+ : QObject(parent)
+ , m_view(0)
+{
+ Q_UNUSED(settings)
+
+ m_indicator = new QLabel;
+ m_indicator->resize(30, 30);
+ m_indicator->setStyleSheet("QLabel{background-color: red;}");
+ m_indicator->installEventFilter(this);
+
+ m_frameScroller = new FrameScroller(this);
+}
+
+bool AutoScroller::mouseMove(QObject* obj, QMouseEvent* event)
+{
+ Q_UNUSED(obj)
+
+ if (m_indicator->isVisible()) {
+ QRect rect = indicatorGlobalRect();
+ int xlength = 0;
+ int ylength = 0;
+
+ if (rect.left() > event->globalPos().x()) {
+ xlength = event->globalPos().x() - rect.left();
+ }
+ else if (rect.right() < event->globalPos().x()) {
+ xlength = event->globalPos().x() - rect.right();
+ }
+ if (rect.top() > event->globalPos().y()) {
+ ylength = event->globalPos().y() - rect.top();
+ }
+ else if (rect.bottom() < event->globalPos().y()) {
+ ylength = event->globalPos().y() - rect.bottom();
+ }
+
+ m_frameScroller->startScrolling(xlength, ylength);
+ }
+
+ return false;
+}
+
+bool AutoScroller::mousePress(QObject* obj, QMouseEvent* event)
+{
+ bool middleButton = event->buttons() == Qt::MiddleButton;
+ WebView* view = qobject_cast(obj);
+ Q_ASSERT(view);
+
+ // Start?
+ if (m_view != view && middleButton) {
+ return showIndicator(view, event->pos());
+ }
+ else if (!m_indicator->isVisible() && middleButton) {
+ return showIndicator(view, event->pos());
+ }
+
+ // Stop
+ if (m_indicator->isVisible()) {
+ stopScrolling();
+ return true;
+ }
+
+ return false;
+}
+
+bool AutoScroller::mouseRelease(QObject* obj, QMouseEvent* event)
+{
+ Q_UNUSED(obj)
+
+ if (m_indicator->isVisible()) {
+ if (!indicatorGlobalRect().contains(event->globalPos())) {
+ stopScrolling();
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool AutoScroller::eventFilter(QObject* obj, QEvent* event)
+{
+ if (obj == m_indicator) {
+ switch (event->type()) {
+ case QEvent::Enter:
+ m_frameScroller->stopScrolling();
+ break;
+
+ case QEvent::Wheel:
+ case QEvent::Hide:
+ case QEvent::MouseButtonPress:
+ stopScrolling();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+bool AutoScroller::showIndicator(WebView* view, const QPoint &pos)
+{
+ QWebFrame* frame = view->page()->frameAt(pos);
+
+ if (!frame) {
+ return false;
+ }
+
+ const QWebHitTestResult res = frame->hitTestContent(pos);
+
+ if (res.isContentEditable() || !res.linkUrl().isEmpty()) {
+ return false;
+ }
+
+ bool vertical = frame->scrollBarGeometry(Qt::Vertical).isValid();
+ bool horizontal = frame->scrollBarGeometry(Qt::Horizontal).isValid();
+
+ if (!vertical && !horizontal) {
+ return false;
+ }
+
+ m_view = view;
+
+ QPoint p;
+ p.setX(pos.x() - m_indicator->width() / 2);
+ p.setY(pos.y() - m_indicator->height() / 2);
+
+ m_indicator->setParent(view->parentWidget());
+ m_indicator->move(p);
+ m_indicator->show();
+
+ m_frameScroller->setFrame(frame);
+
+ m_view->grabMouse();
+ return true;
+}
+
+void AutoScroller::stopScrolling()
+{
+ m_view->releaseMouse();
+
+ m_indicator->hide();
+ m_indicator->setParent(0);
+ m_frameScroller->stopScrolling();
+}
+
+QRect AutoScroller::indicatorGlobalRect() const
+{
+ QPoint pos = m_indicator->parentWidget()->mapToGlobal(m_indicator->geometry().topLeft());
+ return QRect(pos.x(), pos.y(), m_indicator->width(), m_indicator->height());
+}
diff --git a/src/plugins/AutoScroll/autoscroller.h b/src/plugins/AutoScroll/autoscroller.h
new file mode 100644
index 000000000..c5815bb14
--- /dev/null
+++ b/src/plugins/AutoScroll/autoscroller.h
@@ -0,0 +1,54 @@
+/* ============================================================
+* QupZilla - WebKit based browser
+* Copyright (C) 2014 David Rosca
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+* ============================================================ */
+#ifndef AUTOSCROLLER_H
+#define AUTOSCROLLER_H
+
+#include
+#include
+
+class QMouseEvent;
+class QLabel;
+class QRect;
+
+class WebView;
+class FrameScroller;
+
+class AutoScroller : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AutoScroller(const QString &settings, QObject* parent = 0);
+
+ bool mouseMove(QObject* obj, QMouseEvent* event);
+ bool mousePress(QObject* obj, QMouseEvent* event);
+ bool mouseRelease(QObject* obj, QMouseEvent* event);
+
+private:
+ bool eventFilter(QObject* obj, QEvent* event);
+
+ bool showIndicator(WebView* view, const QPoint &pos);
+ void stopScrolling();
+
+ QRect indicatorGlobalRect() const;
+
+ WebView* m_view;
+ QLabel* m_indicator;
+ FrameScroller* m_frameScroller;
+};
+
+#endif // AUTOSCROLLER_H
diff --git a/src/plugins/AutoScroll/autoscrollplugin.cpp b/src/plugins/AutoScroll/autoscrollplugin.cpp
new file mode 100644
index 000000000..493c97139
--- /dev/null
+++ b/src/plugins/AutoScroll/autoscrollplugin.cpp
@@ -0,0 +1,103 @@
+/* ============================================================
+* QupZilla - WebKit based browser
+* Copyright (C) 2014 David Rosca
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+* ============================================================ */
+#include "autoscrollplugin.h"
+#include "autoscroller.h"
+#include "qupzilla.h"
+#include "pluginproxy.h"
+#include "mainapplication.h"
+
+#include
+
+AutoScrollPlugin::AutoScrollPlugin()
+ : QObject()
+ , m_scroller(0)
+{
+}
+
+PluginSpec AutoScrollPlugin::pluginSpec()
+{
+ PluginSpec spec;
+ spec.name = "AutoScroll";
+ spec.info = "AutoScroll plugin";
+ spec.description = "Provides support for autoscroll with middle mouse button";
+ spec.version = "0.1.0";
+ spec.author = "David Rosca ";
+ spec.icon = QPixmap(":/autoscroll/data/icon.png");
+ spec.hasSettings = false;
+
+ return spec;
+}
+
+void AutoScrollPlugin::init(InitState state, const QString &settingsPath)
+{
+ Q_UNUSED(state)
+
+ m_scroller = new AutoScroller(settingsPath, this);
+
+ QZ_REGISTER_EVENT_HANDLER(PluginProxy::MouseMoveHandler);
+ QZ_REGISTER_EVENT_HANDLER(PluginProxy::MousePressHandler);
+ QZ_REGISTER_EVENT_HANDLER(PluginProxy::MouseReleaseHandler);
+}
+
+void AutoScrollPlugin::unload()
+{
+ m_scroller->deleteLater();
+}
+
+bool AutoScrollPlugin::testPlugin()
+{
+ return (QupZilla::VERSION == QLatin1String("1.7.0"));
+}
+
+QTranslator* AutoScrollPlugin::getTranslator(const QString &locale)
+{
+ QTranslator* translator = new QTranslator(this);
+ translator->load(locale, ":/autoscroll/locale/");
+ return translator;
+}
+
+bool AutoScrollPlugin::mouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event)
+{
+ if (type == Qz::ON_WebView) {
+ return m_scroller->mouseMove(obj, event);
+ }
+
+ return false;
+}
+
+bool AutoScrollPlugin::mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event)
+{
+ if (type == Qz::ON_WebView) {
+ return m_scroller->mousePress(obj, event);
+ }
+
+ return false;
+}
+
+bool AutoScrollPlugin::mouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event)
+{
+ if (type == Qz::ON_WebView) {
+ return m_scroller->mouseRelease(obj, event);
+ }
+
+ return false;
+}
+
+#if QT_VERSION < 0x050000
+Q_EXPORT_PLUGIN2(AutoScroll, AutoScrollPlugin)
+#endif
diff --git a/src/plugins/AutoScroll/autoscrollplugin.h b/src/plugins/AutoScroll/autoscrollplugin.h
new file mode 100644
index 000000000..5ac546b2d
--- /dev/null
+++ b/src/plugins/AutoScroll/autoscrollplugin.h
@@ -0,0 +1,52 @@
+/* ============================================================
+* QupZilla - WebKit based browser
+* Copyright (C) 2014 David Rosca
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+* ============================================================ */
+#ifndef AUTOSCROLLPLUGIN_H
+#define AUTOSCROLLPLUGIN_H
+
+#include "plugininterface.h"
+
+class AutoScroller;
+
+class AutoScrollPlugin : public QObject, public PluginInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(PluginInterface)
+
+#if QT_VERSION >= 0x050000
+ Q_PLUGIN_METADATA(IID "QupZilla.Browser.plugin.TestPlugin")
+#endif
+
+public:
+ explicit AutoScrollPlugin();
+ PluginSpec pluginSpec();
+
+ void init(InitState state, const QString &settingsPath);
+ void unload();
+ bool testPlugin();
+
+ QTranslator* getTranslator(const QString &locale);
+
+ bool mouseMove(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event);
+ bool mousePress(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event);
+ bool mouseRelease(const Qz::ObjectName &type, QObject* obj, QMouseEvent* event);
+
+private:
+ AutoScroller* m_scroller;
+};
+
+#endif // TESTPLUGIN_H
diff --git a/src/plugins/AutoScroll/framescroller.cpp b/src/plugins/AutoScroll/framescroller.cpp
new file mode 100644
index 000000000..fe1e56cd4
--- /dev/null
+++ b/src/plugins/AutoScroll/framescroller.cpp
@@ -0,0 +1,63 @@
+/* ============================================================
+* QupZilla - WebKit based browser
+* Copyright (C) 2014 David Rosca
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+* ============================================================ */
+#include "framescroller.h"
+
+#include
+#include
+#include
+
+FrameScroller::FrameScroller(QObject* parent)
+ : QObject(parent)
+ , m_frame(0)
+ , m_lengthX(0)
+ , m_lengthY(0)
+{
+ m_timer = new QTimer(this);
+ m_timer->setInterval(20);
+ connect(m_timer, SIGNAL(timeout()), this, SLOT(scrollStep()));
+}
+
+void FrameScroller::setFrame(QWebFrame* frame)
+{
+ m_frame = frame;
+}
+
+void FrameScroller::startScrolling(int lengthX, int lengthY)
+{
+ Q_ASSERT(m_frame);
+
+ m_lengthX = lengthX;
+ m_lengthY = lengthY;
+
+ if (m_lengthX == 0 && m_lengthY == 0) {
+ m_timer->stop();
+ }
+ else if (!m_timer->isActive()) {
+ m_timer->start();
+ }
+}
+
+void FrameScroller::stopScrolling()
+{
+ m_timer->stop();
+}
+
+void FrameScroller::scrollStep()
+{
+ m_frame->scroll(qCeil(m_lengthX / 8.0), qCeil(m_lengthY / 8.0));
+}
diff --git a/src/plugins/AutoScroll/framescroller.h b/src/plugins/AutoScroll/framescroller.h
new file mode 100644
index 000000000..67417ea14
--- /dev/null
+++ b/src/plugins/AutoScroll/framescroller.h
@@ -0,0 +1,49 @@
+/* ============================================================
+* QupZilla - WebKit based browser
+* Copyright (C) 2014 David Rosca
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+* ============================================================ */
+#ifndef FRAMESCROLLER_H
+#define FRAMESCROLLER_H
+
+#include
+
+class QTimer;
+class QWebFrame;
+
+class FrameScroller : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit FrameScroller(QObject* parent = 0);
+
+ void setFrame(QWebFrame* frame);
+
+ void startScrolling(int lengthX, int lengthY);
+ void stopScrolling();
+
+private slots:
+ void scrollStep();
+
+private:
+ QWebFrame* m_frame;
+ QTimer* m_timer;
+
+ int m_lengthX;
+ int m_lengthY;
+};
+
+#endif // FRAMESCROLLER_H