diff --git a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -127,6 +127,8 @@
set(ENABLE_PYTHON_PLUGINS TRUE)
endif()
+find_package(LibIntl)
+
# Git revision
if (EXISTS "${CMAKE_SOURCE_DIR}/.git")
find_package(Git QUIET)
diff --git a/cmake/FindLibIntl.cmake b/cmake/FindLibIntl.cmake
new file mode 100644
--- /dev/null
+++ b/cmake/FindLibIntl.cmake
@@ -0,0 +1,9 @@
+find_path(LibIntl_INCLUDE_DIRS NAMES libintl.h)
+find_library(LibIntl_LIBRARIES NAMES intl libintl)
+include(CheckCXXSymbolExists)
+check_cxx_symbol_exists(gettext libintl.h LibIntl_SYMBOL_FOUND)
+if (LibIntl_SYMBOL_FOUND)
+ set(LibIntl_FOUND 1)
+else()
+ set(LibIntl_FOUND 0)
+endif()
diff --git a/config.h.cmake b/config.h.cmake
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -9,3 +9,5 @@
/* Disable DBus support */
#cmakedefine DISABLE_DBUS
+
+#define HAVE_LIBINTL ${LibIntl_FOUND}
diff --git a/linux/appdata/org.kde.falkon.appdata.xml b/linux/appdata/org.kde.falkon.appdata.xml
--- a/linux/appdata/org.kde.falkon.appdata.xml
+++ b/linux/appdata/org.kde.falkon.appdata.xml
@@ -4,6 +4,7 @@
CC0-1.0
GPL-3.0+
Falkon
+ فالكون
Falkon
Falkon
Falkon
@@ -28,6 +29,7 @@
xxFalkonxx
Falkon
Web Browser
+ متصفّح الوبّ
Restolador web
Navegador web
Navegador web
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -154,6 +154,43 @@
plugins/pluginproxy.cpp
plugins/plugins.cpp
plugins/speeddial.cpp
+ plugins/qml/qmlpluginloader.cpp
+ plugins/qml/qmlplugin.cpp
+ plugins/qml/qmlplugins.cpp
+ plugins/qml/qmlplugininterface.cpp
+ plugins/qml/qmlengine.cpp
+ plugins/qml/qmlstaticdata.cpp
+ plugins/qml/api/bookmarks/qmlbookmarktreenode.cpp
+ plugins/qml/api/bookmarks/qmlbookmarks.cpp
+ plugins/qml/api/topsites/qmlmostvisitedurl.cpp
+ plugins/qml/api/topsites/qmltopsites.cpp
+ plugins/qml/api/history/qmlhistoryitem.cpp
+ plugins/qml/api/history/qmlhistory.cpp
+ plugins/qml/api/cookies/qmlcookie.cpp
+ plugins/qml/api/cookies/qmlcookies.cpp
+ plugins/qml/api/tabs/qmltab.cpp
+ plugins/qml/api/tabs/qmltabs.cpp
+ plugins/qml/api/notifications/qmlnotifications.cpp
+ plugins/qml/api/clipboard/qmlclipboard.cpp
+ plugins/qml/api/windows/qmlwindow.cpp
+ plugins/qml/api/windows/qmlwindows.cpp
+ plugins/qml/api/browseraction/qmlbrowseraction.cpp
+ plugins/qml/api/sidebar/qmlsidebar.cpp
+ plugins/qml/api/menus/qmlmenu.cpp
+ plugins/qml/api/menus/qmlaction.cpp
+ plugins/qml/api/menus/qmlwebhittestresult.cpp
+ plugins/qml/api/settings/qmlsettings.cpp
+ plugins/qml/api/events/qmlqzobjects.cpp
+ plugins/qml/api/events/qmlmouseevent.cpp
+ plugins/qml/api/events/qmlwheelevent.cpp
+ plugins/qml/api/events/qmlkeyevent.cpp
+ plugins/qml/api/userscript/qmluserscript.cpp
+ plugins/qml/api/userscript/qmluserscripts.cpp
+ plugins/qml/api/userscript/qmlexternaljsobject.cpp
+ plugins/qml/api/extensionscheme/qmlextensionscheme.cpp
+ plugins/qml/api/extensionscheme/qmlwebengineurlrequestjob.cpp
+ plugins/qml/api/fileutils/qmlfileutils.cpp
+ plugins/qml/api/qmlenums.cpp
popupwindow/popuplocationbar.cpp
popupwindow/popupstatusbarmessage.cpp
popupwindow/popupwebview.cpp
@@ -228,6 +265,10 @@
webtab/webtab.cpp
)
+if (LibIntl_FOUND)
+ set(SRCS ${SRCS} plugins/qml/api/i18n/qmli18n.cpp)
+endif()
+
if (WIN32)
set(SRCS ${SRCS} other/registerqappassociation.cpp)
endif()
diff --git a/src/lib/history/history.h b/src/lib/history/history.h
--- a/src/lib/history/history.h
+++ b/src/lib/history/history.h
@@ -54,6 +54,7 @@
void deleteHistoryEntry(int index);
void deleteHistoryEntry(const QList &list);
+ void deleteHistoryEntry(const QString &url);
void deleteHistoryEntry(const QString &url, const QString &title);
QList indexesFromTimeRange(qint64 start, qint64 end);
@@ -66,6 +67,9 @@
void loadSettings();
+ QList searchHistoryEntry(const QString &text);
+ HistoryEntry *getHistoryEntry(const QString &text);
+
Q_SIGNALS:
void historyEntryAdded(const HistoryEntry &entry);
void historyEntryDeleted(const HistoryEntry &entry);
diff --git a/src/lib/history/history.cpp b/src/lib/history/history.cpp
--- a/src/lib/history/history.cpp
+++ b/src/lib/history/history.cpp
@@ -180,6 +180,18 @@
db.commit();
}
+void History::deleteHistoryEntry(const QString &url)
+{
+ QSqlQuery query(SqlDatabase::instance()->database());
+ query.prepare(QSL("SELECT id FROM history WHERE url=?"));
+ query.bindValue(0, url);
+ query.exec();
+ if (query.next()) {
+ int id = query.value(0).toInt();
+ deleteHistoryEntry(id);
+ }
+}
+
void History::deleteHistoryEntry(const QString &url, const QString &title)
{
QSqlQuery query(SqlDatabase::instance()->database());
@@ -285,3 +297,42 @@
return QString();
}
}
+
+QList History::searchHistoryEntry(const QString &text)
+{
+ QList list;
+ QSqlQuery query(SqlDatabase::instance()->database());
+ query.prepare("SELECT count, date, id, title, url FROM history WHERE title LIKE ? OR url LIKE ?");
+ query.bindValue(0, QString("%%1%").arg(text));
+ query.bindValue(1, QString("%%1%").arg(text));
+ query.exec();
+ while (query.next()) {
+ HistoryEntry entry;
+ entry.count = query.value(0).toInt();
+ entry.date = query.value(1).toDateTime();
+ entry.id = query.value(2).toInt();
+ entry.title = query.value(3).toString();
+ entry.url = query.value(4).toUrl();
+ list.append(entry);
+ }
+ return list;
+}
+
+HistoryEntry *History::getHistoryEntry(const QString &text)
+{
+ QSqlQuery query(SqlDatabase::instance()->database());
+ query.prepare("SELECT count, date, id, title, url FROM history WHERE url = ?");
+ query.bindValue(0, text);
+ query.exec();
+
+ HistoryEntry *entry = nullptr;
+ if (query.next()) {
+ entry = new HistoryEntry;
+ entry->count = query.value(0).toInt();
+ entry->date = query.value(1).toDateTime();
+ entry->id = query.value(2).toInt();
+ entry->title = query.value(3).toString();
+ entry->url = query.value(4).toUrl();
+ }
+ return entry;
+}
diff --git a/src/lib/plugins/plugins.h b/src/lib/plugins/plugins.h
--- a/src/lib/plugins/plugins.h
+++ b/src/lib/plugins/plugins.h
@@ -24,6 +24,7 @@
#include "qzcommon.h"
#include "plugininterface.h"
+#include "qml/qmlpluginloader.h"
class QLibrary;
class QPluginLoader;
@@ -55,7 +56,8 @@
Invalid = 0,
InternalPlugin,
SharedLibraryPlugin,
- PythonPlugin
+ PythonPlugin,
+ QmlPlugin
};
Type type = Invalid;
QString pluginId;
@@ -88,6 +90,7 @@
bool loadPlugin(Plugin* plugin);
void unloadPlugin(Plugin* plugin);
+ void removePlugin(Plugin *plugin);
void shutdown();
@@ -106,6 +109,7 @@
Q_SIGNALS:
void pluginUnloaded(PluginInterface* plugin);
+ void refreshedLoadedPlugins();
private:
void loadPythonSupport();
diff --git a/src/lib/plugins/plugins.cpp b/src/lib/plugins/plugins.cpp
--- a/src/lib/plugins/plugins.cpp
+++ b/src/lib/plugins/plugins.cpp
@@ -24,10 +24,14 @@
#include "adblock/adblockplugin.h"
#include "../config.h"
#include "desktopfile.h"
+#include "qml/qmlplugins.h"
+#include "qml/qmlplugin.h"
#include
#include
#include
+#include
+#include
Plugins::Plugins(QObject* parent)
: QObject(parent)
@@ -82,6 +86,28 @@
refreshLoadedPlugins();
}
+void Plugins::removePlugin(Plugins::Plugin *plugin)
+{
+ if (plugin->type != Plugin::QmlPlugin) {
+ return;
+ }
+ if (plugin->isLoaded()) {
+ unloadPlugin(plugin);
+ }
+
+ // For QML plugins, pluginId is qml:
+ const QString dirName = plugin->pluginId.mid(4);
+ const QString dirPath = DataPaths::locate(DataPaths::Plugins, QSL("qml/") + dirName);
+ bool result = QDir(dirPath).removeRecursively();
+ if (!result) {
+ qWarning() << "Unable to remove" << plugin->pluginSpec.name;
+ return;
+ }
+
+ m_availablePlugins.removeOne(*plugin);
+ refreshedLoadedPlugins();
+}
+
void Plugins::loadSettings()
{
QStringList defaultAllowedPlugins = {
@@ -204,6 +230,24 @@
}
}
}
+
+ // QmlPlugin
+ for (QString dir : dirs) {
+ // qml plugins will be loaded from subdirectory qml
+ dir.append(QSL("/qml"));
+ const auto qmlDirs = QDir(dir).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
+ for (const QFileInfo &info : qmlDirs) {
+ Plugin plugin = QmlPlugin::loadPlugin(info.absoluteFilePath());
+ if (plugin.type == Plugin::Invalid) {
+ continue;
+ }
+ if (plugin.pluginSpec.name.isEmpty()) {
+ qWarning() << "Invalid plugin spec of" << info.absoluteFilePath() << "plugin";
+ continue;
+ }
+ registerAvailablePlugin(plugin);
+ }
+ }
}
void Plugins::registerAvailablePlugin(const Plugin &plugin)
@@ -222,6 +266,8 @@
m_loadedPlugins.append(plugin.instance);
}
}
+
+ emit refreshedLoadedPlugins();
}
void Plugins::loadPythonSupport()
@@ -258,6 +304,8 @@
type = Plugin::SharedLibraryPlugin;
} else if (t == QL1S("python")) {
type = Plugin::PythonPlugin;
+ } else if (t == QL1S("qml")) {
+ type = Plugin::QmlPlugin;
}
name = id.mid(colon + 1);
} else {
@@ -275,6 +323,9 @@
case Plugin::PythonPlugin:
return loadPythonPlugin(name);
+ case Plugin::QmlPlugin:
+ return QmlPlugin::loadPlugin(name);
+
default:
return Plugin();
}
@@ -359,6 +410,10 @@
initPythonPlugin(plugin);
break;
+ case Plugin::QmlPlugin:
+ QmlPlugin::initPlugin(plugin);
+ break;
+
default:
return false;
}
@@ -367,6 +422,8 @@
return false;
}
+ // DataPaths::currentProfilePath() + QL1S("/extensions") is duplicated in qmlsettings.cpp
+ // If you change this, please change it there too.
plugin->instance->init(state, DataPaths::currentProfilePath() + QL1S("/extensions"));
if (!plugin->instance->testPlugin()) {
diff --git a/src/lib/plugins/qml/api/bookmarks/qmlbookmarks.h b/src/lib/plugins/qml/api/bookmarks/qmlbookmarks.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/bookmarks/qmlbookmarks.h
@@ -0,0 +1,155 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include "qmlbookmarktreenode.h"
+#include "mainapplication.h"
+
+#include
+
+/**
+ * @brief The class exposing the Bookmarks API to QML
+ */
+class QmlBookmarks : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QmlBookmarks(QObject *parent = nullptr);
+
+ /**
+ * @brief Checks if the url is bookmarked
+ * @param String representing the url to check
+ * @return true if bookmarked, else false
+ */
+ Q_INVOKABLE bool isBookmarked(const QString &url) const;
+ /**
+ * @brief Get the root bookmark item
+ * @return Root boomkark item
+ */
+ Q_INVOKABLE QmlBookmarkTreeNode *rootItem() const;
+ /**
+ * @brief Get the bookmarks toolbar
+ * @return Bookmarks toolbar
+ */
+ Q_INVOKABLE QmlBookmarkTreeNode *toolbarFolder() const;
+ /**
+ * @brief Get the bookmarks menu folder
+ * @return Bookmarks menu folder
+ */
+ Q_INVOKABLE QmlBookmarkTreeNode *menuFolder() const;
+ /**
+ * @brief Get the unsorted bookmarks folder
+ * @return Unsorted bookmarks folder
+ */
+ Q_INVOKABLE QmlBookmarkTreeNode *unsortedFolder() const;
+ /**
+ * @brief Get the last used bookmarks folder
+ * @return Last used bookmarks folder
+ */
+ Q_INVOKABLE QmlBookmarkTreeNode *lastUsedFolder() const;
+ /**
+ * @brief Creates a bookmark item
+ * @param A JavaScript object containing
+ * - parent:
+ * Object of type [QmlBookmarkTreeNode](@ref QmlBookmarkTreeNode), representing
+ * the parent of the new bookmark item. This is required field.
+ * - title:
+ * String representing the title of the new bookmark item. Defaults to empty string
+ * - url:
+ * String representing the url of the new bookmark item. Defaults to empty string
+ * - description
+ * String representing the description of the new bookmark item. Defaults to empty string
+ * - type:
+ * [Type](@ref QmlBookmarkTreeNode::Type) representing the type of the new bookmark item.
+ * Defaults to [Url](@ref QmlBookmarkTreeNode::Url) if url is provided, else
+ * [Folder](@ref QmlBookmarkTreeNode::Folder) if title is provided, else
+ * [Invalid](@ref QmlBookmarkTreeNode::Invalid)
+ * @return true if the bookmark it created, else false
+ */
+ Q_INVOKABLE bool create(const QVariantMap &map) const;
+ /**
+ * @brief Removes a bookmark item
+ * @param treeNode:
+ * Object of type [QmlBookmarkTreeNode](@ref QmlBookmarkTreeNode) to be removed
+ * @return true if the bookmark is removed, else false
+ */
+ Q_INVOKABLE bool remove(QmlBookmarkTreeNode *treeNode) const;
+ /**
+ * @brief QmlBookmarks::search
+ * @param A JavaScript object containing
+ * - query:
+ * String containing search query
+ * - url:
+ * String representing url to be search
+ * @return List containing [QmlBookmarkTreeNode](@ref QmlBookmarkTreeNode). If both
+ * query and url are not supplied then empty list is returned.
+ */
+ Q_INVOKABLE QList search(const QVariantMap &map) const;
+ /**
+ * @brief Updates a bookmark item
+ * @param Object of type [QmlBookmarkTreeNode](@ref QmlBookmarkTreeNode), representing the bookmark
+ * to update
+ * @param JavaScript object containing the values to be updated
+ * - title:
+ * String representing the new title of the bookmark item
+ * - description:
+ * String representing the new description of the bookmark item
+ * - keyword:
+ * String representing the new keyword of the bookmark item
+ * @return true if the bookmark is updated, else false
+ */
+ Q_INVOKABLE bool update(QObject *object, const QVariantMap &changes) const;
+ /**
+ * @brief Get the first matched bookmark item
+ * @param String representing the query
+ * @return Object of type [QmlBookmarkTreeNode](@ref QmlBookmarkTreeNode) if
+ * the query is matched with a bookmark, else null
+ */
+ Q_INVOKABLE QmlBookmarkTreeNode *get(const QString &string) const;
+ /**
+ * @brief Get children of the bookmark item
+ * @param Object of type [QmlBookmarkTreeNode](@ref QmlBookmarkTreeNode), representing
+ * the parent whose children are requested.
+ * @return List containing the children, of type [QmlBookmarkTreeNode](@ref QmlBookmarkTreeNode)
+ */
+ Q_INVOKABLE QList getChildren(QObject *object) const;
+
+Q_SIGNALS:
+ /**
+ * @brief This signal is emitted when a new bookmark item is created
+ * @param bookmark item, exposed to QML as [QmlBookmarkTreeNode](@ref QmlBookmarkTreeNode)
+ */
+ void created(QmlBookmarkTreeNode *treeNode);
+
+ /**
+ * @brief This signal is emitted when a bookmark item is edited
+ * @param bookmark item, exposed to QML as [QmlBookmarkTreeNode](@ref QmlBookmarkTreeNode)
+ */
+ void changed(QmlBookmarkTreeNode *treeNode);
+
+ /**
+ * @brief This signal is emitted when a bookmark item is removed
+ * @param bookmark item, exposed to QML as [QmlBookmarkTreeNode](@ref QmlBookmarkTreeNode)
+ */
+ void removed(QmlBookmarkTreeNode *treeNode);
+
+private:
+ BookmarkItem *getBookmarkItem(QmlBookmarkTreeNode *treeNode) const;
+ BookmarkItem *getBookmarkItem(QObject *object) const;
+};
diff --git a/src/lib/plugins/qml/api/bookmarks/qmlbookmarks.cpp b/src/lib/plugins/qml/api/bookmarks/qmlbookmarks.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/bookmarks/qmlbookmarks.cpp
@@ -0,0 +1,257 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlbookmarks.h"
+#include "bookmarks.h"
+#include "qml/qmlstaticdata.h"
+#include
+#include
+
+QmlBookmarks::QmlBookmarks(QObject *parent)
+ : QObject(parent)
+{
+ connect(mApp->bookmarks(), &Bookmarks::bookmarkAdded, this, [this](BookmarkItem *item){
+ auto treeNode = QmlStaticData::instance().getBookmarkTreeNode(item);
+ emit created(treeNode);
+ });
+
+ connect(mApp->bookmarks(), &Bookmarks::bookmarkChanged, this, [this](BookmarkItem *item){
+ auto treeNode = QmlStaticData::instance().getBookmarkTreeNode(item);
+ emit changed(treeNode);
+ });
+
+ connect(mApp->bookmarks(), &Bookmarks::bookmarkRemoved, this, [this](BookmarkItem *item){
+ auto treeNode = QmlStaticData::instance().getBookmarkTreeNode(item);
+ emit removed(treeNode);
+ });
+}
+
+BookmarkItem *QmlBookmarks::getBookmarkItem(QmlBookmarkTreeNode *treeNode) const
+{
+ auto bookmarks = mApp->bookmarks();
+ QList items;
+
+ if (treeNode->url().isEmpty()) {
+ if (treeNode->item() == bookmarks->rootItem()) {
+ return bookmarks->rootItem();
+
+ } else if (treeNode->item() == bookmarks->toolbarFolder()) {
+ return bookmarks->toolbarFolder();
+
+ } else if (treeNode->item() == bookmarks->menuFolder()) {
+ return bookmarks->menuFolder();
+
+ } else if (treeNode->item() == bookmarks->unsortedFolder()) {
+ return bookmarks->unsortedFolder();
+ }
+
+ items = bookmarks->searchBookmarks(treeNode->title());
+ } else {
+ items = bookmarks->searchBookmarks(QUrl::fromEncoded(treeNode->url().toUtf8()));
+ }
+
+ for (BookmarkItem *item : qAsConst(items)) {
+ if (treeNode->item() == item) {
+ return item;
+ }
+ }
+
+ return nullptr;
+}
+
+BookmarkItem *QmlBookmarks::getBookmarkItem(QObject *object) const
+{
+ auto treeNode = qobject_cast(object);
+ if (!treeNode) {
+ return nullptr;
+ }
+
+ auto item = getBookmarkItem(treeNode);
+ if (!item || item->urlString() != treeNode->url()) {
+ return nullptr;
+ }
+
+ return item;
+}
+
+bool QmlBookmarks::isBookmarked(const QString &url) const
+{
+ return mApp->bookmarks()->isBookmarked(QUrl::fromEncoded(url.toUtf8()));
+}
+
+QmlBookmarkTreeNode *QmlBookmarks::rootItem() const
+{
+ return QmlStaticData::instance().getBookmarkTreeNode(mApp->bookmarks()->rootItem());
+}
+
+QmlBookmarkTreeNode *QmlBookmarks::toolbarFolder() const
+{
+ return QmlStaticData::instance().getBookmarkTreeNode(mApp->bookmarks()->toolbarFolder());
+}
+
+QmlBookmarkTreeNode *QmlBookmarks::menuFolder() const
+{
+ return QmlStaticData::instance().getBookmarkTreeNode(mApp->bookmarks()->menuFolder());
+}
+
+QmlBookmarkTreeNode *QmlBookmarks::unsortedFolder() const
+{
+ return QmlStaticData::instance().getBookmarkTreeNode(mApp->bookmarks()->unsortedFolder());
+}
+
+QmlBookmarkTreeNode *QmlBookmarks::lastUsedFolder() const
+{
+ return QmlStaticData::instance().getBookmarkTreeNode(mApp->bookmarks()->lastUsedFolder());
+}
+
+bool QmlBookmarks::create(const QVariantMap &map) const
+{
+ if (!map.contains(QSL("parent"))) {
+ qWarning() << "Unable to create new bookmark:" << "parent not found";
+ return false;
+ }
+ const QString title = map.value(QSL("title")).toString();
+ const QString urlString = map.value(QSL("url")).toString();
+ const QString description = map.value(QSL("description")).toString();
+
+ BookmarkItem::Type type;
+ if (map.contains(QSL("type"))) {
+ type = BookmarkItem::Type(map.value(QSL("type")).toInt());
+ } else if (urlString.isEmpty()){
+ if (!title.isEmpty()) {
+ type = BookmarkItem::Folder;
+ } else {
+ type = BookmarkItem::Invalid;
+ }
+ } else {
+ type = BookmarkItem::Url;
+ }
+
+ auto object = map.value(QSL("parent")).value();
+ auto parent = getBookmarkItem(object);
+ if (!parent) {
+ qWarning() << "Unable to create new bookmark:" << "parent not found";
+ return false;
+ }
+ auto item = new BookmarkItem(type);
+ item->setTitle(title);
+ item->setUrl(QUrl::fromEncoded(urlString.toUtf8()));
+ item->setDescription(description);
+ mApp->bookmarks()->addBookmark(parent, item);
+ return true;
+}
+
+bool QmlBookmarks::remove(QmlBookmarkTreeNode *treeNode) const
+{
+ auto item = getBookmarkItem(treeNode);
+ if (!item) {
+ qWarning() << "Unable to remove bookmark:" <<"BookmarkItem not found";
+ return false;
+ }
+ return mApp->bookmarks()->removeBookmark(item);
+}
+
+QList QmlBookmarks::search(const QVariantMap &map) const
+{
+ if (!map.contains(QSL("query")) && !map.contains(QSL("url"))) {
+ qWarning() << "Unable to search bookmarks";
+ return QList();
+ }
+
+ const QString query = map.value(QSL("query")).toString();
+ const QString urlString = map.value(QSL("url")).toString();
+ QList items;
+ if (urlString.isEmpty()) {
+ items = mApp->bookmarks()->searchBookmarks(query);
+ } else {
+ items = mApp->bookmarks()->searchBookmarks(QUrl::fromEncoded(urlString.toUtf8()));
+ }
+ QList ret;
+ ret.reserve(items.size());
+ for (auto item : qAsConst(items)) {
+ ret.append(QmlStaticData::instance().getBookmarkTreeNode(item));
+ }
+ return ret;
+}
+
+bool QmlBookmarks::update(QObject *object, const QVariantMap &changes) const
+{
+ auto treeNode = qobject_cast(object);
+ if (!treeNode) {
+ qWarning() << "Unable to update bookmark:" << "unable to cast QVariant to QmlBookmarkTreeNode";
+ return false;
+ }
+
+ auto item = getBookmarkItem(treeNode);
+ if (!item) {
+ qWarning() << "Unable to update bookmark:" << "bookmark not found";
+ return false;
+ }
+
+ if (!mApp->bookmarks()->canBeModified(item)) {
+ qWarning() << "Unable to update bookmark:" << "bookmark can not be modified";
+ }
+
+ QString newTitle = treeNode->title();
+ if (changes.contains(QSL("title"))) {
+ newTitle = changes.value(QSL("title")).toString();
+ }
+ QString newDescription = treeNode->description();
+ if (changes.contains(QSL("description"))) {
+ newDescription = changes.value(QSL("description")).toString();
+ }
+ QString newKeyword = treeNode->keyword();
+ if (changes.contains(QSL("keyword"))) {
+ newKeyword = changes.value(QSL("keyword")).toString();
+ }
+
+ item->setTitle(newTitle);
+ item->setDescription(newDescription);
+ item->setKeyword(newKeyword);
+ mApp->bookmarks()->changeBookmark(item);
+ return true;
+}
+
+QmlBookmarkTreeNode *QmlBookmarks::get(const QString &string) const
+{
+ const QList items = mApp->bookmarks()->searchBookmarks(QUrl(string));
+ for (BookmarkItem *item : items) {
+ if (item->urlString() == string) {
+ return QmlStaticData::instance().getBookmarkTreeNode(item);
+ }
+ }
+
+ return nullptr;
+}
+
+QList QmlBookmarks::getChildren(QObject *object) const
+{
+ QList ret;
+
+ auto bookmarkItem = getBookmarkItem(object);
+ if (!bookmarkItem) {
+ qWarning() << "Unable to get children:" << "parent not found";
+ return ret;
+ }
+
+ const QList items = bookmarkItem->children();
+ for (BookmarkItem *item : items) {
+ ret.append(QmlStaticData::instance().getBookmarkTreeNode(item));
+ }
+
+ return ret;
+}
diff --git a/src/lib/plugins/qml/api/bookmarks/qmlbookmarktreenode.h b/src/lib/plugins/qml/api/bookmarks/qmlbookmarktreenode.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/bookmarks/qmlbookmarktreenode.h
@@ -0,0 +1,104 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+#include "bookmarkitem.h"
+
+/**
+ * @brief The class exposing the bookmark item to QML
+ */
+class QmlBookmarkTreeNode : public QObject
+{
+ Q_OBJECT
+
+ /**
+ * @brief type of bookmark tree node.
+ */
+ Q_PROPERTY(Type type READ type CONSTANT)
+
+ /**
+ * @brief title of bookmark tree node.
+ */
+ Q_PROPERTY(QString title READ title CONSTANT)
+
+ /**
+ * @brief url of bookmark tree node.
+ */
+ Q_PROPERTY(QString url READ url CONSTANT)
+
+ /**
+ * @brief description of bookmark tree node.
+ */
+ Q_PROPERTY(QString description READ description CONSTANT)
+
+ /**
+ * @brief keyword of bookmark tree node.
+ */
+ Q_PROPERTY(QString keyword READ keyword CONSTANT)
+
+ /**
+ * @brief visit count of bookmark tree node.
+ */
+ Q_PROPERTY(int visitCount READ visitCount CONSTANT)
+
+ /**
+ * @brief parent of bookmark tree node.
+ */
+ Q_PROPERTY(QmlBookmarkTreeNode* parent READ parent CONSTANT)
+
+ /**
+ * @brief checks if bookmark tree node is unmodifiable.
+ */
+ Q_PROPERTY(bool unmodifiable READ unmodifiable CONSTANT)
+
+ /**
+ * @brief gets children of bookmark tree node.
+ */
+ Q_PROPERTY(QList children READ children CONSTANT)
+
+public:
+ /**
+ * @brief The Type enum
+ *
+ * Contains the information of the type of the bookmark item,
+ */
+ enum Type {
+ Root = BookmarkItem::Root, //!< Represents the root bookmark item
+ Url = BookmarkItem::Url, //!< Represents the single bookmark item of type url
+ Folder = BookmarkItem::Folder, //!< Represents the bookmark folder
+ Separator = BookmarkItem::Separator, //!< Represents the bookmark seperator
+ Invalid = BookmarkItem::Invalid //!< Represents invalid bookmark item
+ };
+ Q_ENUM(Type)
+
+ explicit QmlBookmarkTreeNode(BookmarkItem *item = nullptr);
+
+ BookmarkItem *item();
+ Type type() const;
+ QString title() const;
+ QString url() const;
+ QString description() const;
+ QString keyword() const;
+
+private:
+ BookmarkItem *m_item = nullptr;
+
+ int visitCount() const;
+ QmlBookmarkTreeNode *parent() const;
+ bool unmodifiable() const;
+ QList children() const;
+};
diff --git a/src/lib/plugins/qml/api/bookmarks/qmlbookmarktreenode.cpp b/src/lib/plugins/qml/api/bookmarks/qmlbookmarktreenode.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/bookmarks/qmlbookmarktreenode.cpp
@@ -0,0 +1,128 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlbookmarktreenode.h"
+#include "mainapplication.h"
+#include "bookmarks.h"
+#include "qml/qmlstaticdata.h"
+#include
+
+QmlBookmarkTreeNode::QmlBookmarkTreeNode(BookmarkItem *item)
+ : m_item(item)
+{
+ QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
+}
+
+BookmarkItem *QmlBookmarkTreeNode::item()
+{
+ return m_item;
+}
+
+QmlBookmarkTreeNode::Type QmlBookmarkTreeNode::type() const
+{
+ if (!m_item) {
+ return Invalid;
+ }
+
+ switch (m_item->type()) {
+ case BookmarkItem::Root:
+ return Root;
+
+ case BookmarkItem::Url:
+ return Url;
+
+ case BookmarkItem::Folder:
+ return Folder;
+
+ case BookmarkItem::Separator:
+ return Separator;
+
+ case BookmarkItem::Invalid:
+ default:
+ return Invalid;
+ }
+}
+
+QString QmlBookmarkTreeNode::title() const
+{
+ if (!m_item) {
+ return QString();
+ }
+
+ return m_item->title();
+}
+
+QString QmlBookmarkTreeNode::url() const
+{
+ if (!m_item) {
+ return QString();
+ }
+
+ return m_item->urlString();
+}
+
+QString QmlBookmarkTreeNode::description() const
+{
+ if (!m_item) {
+ return QString();
+ }
+
+ return m_item->description();
+}
+
+QString QmlBookmarkTreeNode::keyword() const
+{
+ if (!m_item) {
+ return QString();
+ }
+
+ return m_item->keyword();
+}
+
+int QmlBookmarkTreeNode::visitCount() const
+{
+ if (!m_item) {
+ return 0;
+ }
+
+ return m_item->visitCount();
+}
+
+QmlBookmarkTreeNode *QmlBookmarkTreeNode::parent() const
+{
+ if (!m_item) {
+ return nullptr;
+ }
+
+ return QmlStaticData::instance().getBookmarkTreeNode(m_item->parent());
+}
+
+bool QmlBookmarkTreeNode::unmodifiable() const
+{
+ return !mApp->bookmarks()->canBeModified(m_item);
+}
+
+QList QmlBookmarkTreeNode::children() const
+{
+ const QList items = m_item->children();
+ QList ret;
+ ret.reserve(items.size());
+ for (BookmarkItem *item : items) {
+ ret.append(QmlStaticData::instance().getBookmarkTreeNode(item));
+ }
+ return ret;
+}
diff --git a/src/lib/plugins/qml/api/browseraction/qmlbrowseraction.h b/src/lib/plugins/qml/api/browseraction/qmlbrowseraction.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/browseraction/qmlbrowseraction.h
@@ -0,0 +1,211 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+#include "abstractbuttoninterface.h"
+#include "mainapplication.h"
+#include
+#include
+
+class QmlBrowserActionButton;
+
+/**
+ * @brief The class exposing BrowserAction API to QML
+ */
+class QmlBrowserAction : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+
+ /**
+ * @brief identity for the button. This is a required property.
+ */
+ Q_PROPERTY(QString identity READ identity WRITE setIdentity NOTIFY identityChanged)
+
+ /**
+ * @brief name of the button. This is a required property.
+ */
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+
+ /**
+ * @brief title of the button.
+ */
+ Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
+
+ /**
+ * @brief tool tip of the button.
+ */
+ Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip NOTIFY toolTipChanged)
+
+ /**
+ * @brief icon path of button
+ *
+ * The icon path will be search in the following order
+ * - Theme icon: if the icon is found as a theme icon, then it will
+ * be used even if the icon file with same name is present
+ * in the plugin directory
+ * - Falkon resource: for the icons starting with ":", they are searched in
+ * falkon resource file
+ * - Files in plugin directory: All other paths will be resolved relative to
+ * the plugin directory. If the icon path is outside the
+ * plugin directory, then it will be resolved as empty path.
+ */
+ Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
+
+ /**
+ * @brief badge text of the button
+ */
+ Q_PROPERTY(QString badgeText READ badgeText WRITE setBadgeText NOTIFY badgeTextChanged)
+
+ /**
+ * @brief the popup shown when the button is clicked. This must be a QML Window.
+ */
+ Q_PROPERTY(QQmlComponent* popup READ popup WRITE setPopup NOTIFY popupChanged)
+
+ /**
+ * @brief represents locations where the button is to be added.
+ */
+ Q_PROPERTY(Locations location READ location WRITE setLocation NOTIFY locationChanged)
+
+public:
+ /**
+ * @brief The Location enum
+ */
+ enum Location {
+ NavigationToolBar = 0x1, //!< to add the button in navigation tool bar
+ StatusBar = 0x2 //!< to add the button in status bar
+ };
+ Q_DECLARE_FLAGS(Locations, Location)
+ Q_ENUM(Locations)
+
+ explicit QmlBrowserAction(QObject *parent = nullptr);
+ ~QmlBrowserAction() override;
+ void classBegin() override {}
+ void componentComplete() override;
+ QmlBrowserActionButton *button() const;
+ Locations location() const;
+
+Q_SIGNALS:
+ /**
+ * @brief This signal is emitted when identity property is changed
+ * @param QString representing identity
+ */
+ void identityChanged(const QString &identity);
+
+ /**
+ * @brief This signal is emitted when name property is changed
+ * @param QString representing name
+ */
+ void nameChanged(const QString &name);
+
+ /**
+ * @brief This signal is emitted when title property is changed
+ * @param QString representing title
+ */
+ void titleChanged(const QString &title);
+
+ /**
+ * @brief This signal is emitted when the toolTip property is changed
+ * @param QString representing toolTip
+ */
+ void toolTipChanged(const QString &toolTip);
+
+ /**
+ * @brief This signal is emitted when the icon property is changed
+ * @param QString representing icon
+ */
+ void iconChanged(const QString &icon);
+
+ /**
+ * @brief This signal is emitted when the badgeText property is changed
+ * @param QString representing badgeText
+ */
+ void badgeTextChanged(const QString &badgeText);
+
+ /**
+ * @brief This signal is emitted when the popup property is changed
+ * @param QQmComponent representing popup
+ */
+ void popupChanged(QQmlComponent *popup);
+
+ /**
+ * @brief This signal is emitted when the locations property is changed
+ * @param locations
+ */
+ void locationChanged(const Locations &locations);
+
+ /**
+ * @brief This signal is emitted when the button is clicked
+ */
+ void clicked();
+
+private:
+ QString m_identity;
+ QString m_name;
+ QString m_title;
+ QString m_toolTip;
+ QString m_icon;
+ QString m_badgeText;
+ QQmlComponent *m_popup = nullptr;
+ Locations m_locations = NavigationToolBar;
+ QmlBrowserActionButton *m_button = nullptr;
+
+ QString identity() const;
+ void setIdentity(const QString &identity);
+ QString name() const;
+ void setName(const QString &name);
+ QString title() const;
+ void setTitle(const QString &title);
+ QString toolTip() const;
+ void setToolTip(const QString &toolTip);
+ QString icon() const;
+ void setIcon(const QString &icon);
+ QString badgeText() const;
+ void setBadgeText(const QString &badgeText);
+ QQmlComponent *popup() const;
+ void setPopup(QQmlComponent *popup);
+ void setLocation(const Locations &locations);
+
+ void addButton(BrowserWindow *window);
+ void removeButton(BrowserWindow *window);
+};
+
+class QmlBrowserActionButton : public AbstractButtonInterface
+{
+ Q_OBJECT
+public:
+ explicit QmlBrowserActionButton(QObject *parent = nullptr);
+ QString id() const;
+ void setId(const QString &id);
+ QString name() const;
+ void setName(const QString &name);
+ void setTitle(const QString &title);
+ void setToolTip(const QString &toolTip);
+ void setIcon(const QString &icon);
+ void setBadgeText(const QString &badgeText);
+ void setPopup(QQmlComponent *popup);
+
+ void positionPopup(ClickController *clickController);
+
+private:
+ QString m_id;
+ QString m_name;
+ QString m_iconUrl;
+ QQmlComponent *m_popup = nullptr;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QmlBrowserAction::Locations)
diff --git a/src/lib/plugins/qml/api/browseraction/qmlbrowseraction.cpp b/src/lib/plugins/qml/api/browseraction/qmlbrowseraction.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/browseraction/qmlbrowseraction.cpp
@@ -0,0 +1,263 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlbrowseraction.h"
+#include "qztools.h"
+#include "navigationbar.h"
+#include "statusbar.h"
+#include "pluginproxy.h"
+#include "qml/api/fileutils/qmlfileutils.h"
+#include "qml/qmlengine.h"
+#include "qml/qmlstaticdata.h"
+#include
+#include
+
+QmlBrowserAction::QmlBrowserAction(QObject *parent)
+ : QObject(parent)
+{
+ m_button = new QmlBrowserActionButton();
+
+ connect(this, &QmlBrowserAction::identityChanged, m_button, &QmlBrowserActionButton::setId);
+ connect(this, &QmlBrowserAction::nameChanged, m_button, &QmlBrowserActionButton::setName);
+ connect(this, &QmlBrowserAction::titleChanged, m_button, &QmlBrowserActionButton::setTitle);
+ connect(this, &QmlBrowserAction::toolTipChanged, m_button, &QmlBrowserActionButton::setToolTip);
+ connect(this, &QmlBrowserAction::iconChanged, m_button, &QmlBrowserActionButton::setIcon);
+ connect(this, &QmlBrowserAction::badgeTextChanged, m_button, &QmlBrowserActionButton::setBadgeText);
+ connect(this, &QmlBrowserAction::popupChanged, m_button, &QmlBrowserActionButton::setPopup);
+
+ connect(m_button, &QmlBrowserActionButton::clicked, this, &QmlBrowserAction::clicked);
+
+ connect(mApp->plugins(), &PluginProxy::mainWindowCreated, this, &QmlBrowserAction::addButton);
+}
+
+void QmlBrowserAction::componentComplete()
+{
+ const QList windows = mApp->windows();
+ for (BrowserWindow *window : windows) {
+ addButton(window);
+ }
+}
+
+QmlBrowserAction::~QmlBrowserAction()
+{
+ const QList windows = mApp->windows();
+ for (BrowserWindow *window : windows) {
+ removeButton(window);
+ }
+}
+
+QmlBrowserActionButton *QmlBrowserAction::button() const
+{
+ return m_button;
+}
+
+QmlBrowserAction::Locations QmlBrowserAction::location() const
+{
+ return m_locations;
+}
+
+QString QmlBrowserAction::identity() const
+{
+ return m_identity;
+}
+
+void QmlBrowserAction::setIdentity(const QString &identity)
+{
+ m_identity = identity;
+ emit identityChanged(m_identity);
+}
+
+QString QmlBrowserAction::name() const
+{
+ return m_name;
+}
+
+void QmlBrowserAction::setName(const QString &name)
+{
+ m_name = name;
+ emit nameChanged(m_name);
+}
+
+QString QmlBrowserAction::title() const
+{
+ return m_title;
+}
+
+void QmlBrowserAction::setTitle(const QString &title)
+{
+ m_title = title;
+ emit titleChanged(m_title);
+}
+
+QString QmlBrowserAction::toolTip() const
+{
+ return m_toolTip;
+}
+
+void QmlBrowserAction::setToolTip(const QString &toolTip)
+{
+ m_toolTip = toolTip;
+ emit toolTipChanged(m_toolTip);
+}
+
+QString QmlBrowserAction::icon() const
+{
+ return m_icon;
+}
+
+void QmlBrowserAction::setIcon(const QString &icon)
+{
+ m_icon = icon;
+ emit iconChanged(m_icon);
+}
+
+QString QmlBrowserAction::badgeText() const
+{
+ return m_badgeText;
+}
+
+void QmlBrowserAction::setBadgeText(const QString &badgeText)
+{
+ m_badgeText = badgeText;
+ emit badgeTextChanged(m_badgeText);
+}
+
+QQmlComponent *QmlBrowserAction::popup() const
+{
+ return m_popup;
+}
+
+void QmlBrowserAction::setPopup(QQmlComponent *popup)
+{
+ m_popup = popup;
+ emit popupChanged(m_popup);
+}
+
+void QmlBrowserAction::setLocation(const Locations &locations)
+{
+ m_locations = locations;
+ emit locationChanged(m_locations);
+}
+
+void QmlBrowserAction::addButton(BrowserWindow *window)
+{
+ if (location().testFlag(NavigationToolBar)) {
+ window->navigationBar()->addToolButton(button());
+ }
+
+ if (location().testFlag(StatusBar)) {
+ window->statusBar()->addButton(button());
+ }
+}
+
+void QmlBrowserAction::removeButton(BrowserWindow *window)
+{
+ if (location().testFlag(NavigationToolBar)) {
+ window->navigationBar()->removeToolButton(button());
+ }
+
+ if (location().testFlag(StatusBar)) {
+ window->statusBar()->removeButton(button());
+ }
+}
+
+QmlBrowserActionButton::QmlBrowserActionButton(QObject *parent)
+ : AbstractButtonInterface(parent)
+{
+ connect(this, &AbstractButtonInterface::clicked, this, &QmlBrowserActionButton::positionPopup);
+}
+
+QString QmlBrowserActionButton::id() const
+{
+ return m_id;
+}
+
+void QmlBrowserActionButton::setId(const QString &id)
+{
+ m_id = id;
+}
+
+QString QmlBrowserActionButton::name() const
+{
+ return m_name;
+}
+
+void QmlBrowserActionButton::setName(const QString &name)
+{
+ m_name = name;
+}
+
+void QmlBrowserActionButton::setTitle(const QString &title)
+{
+ AbstractButtonInterface::setTitle(title);
+}
+
+void QmlBrowserActionButton::setToolTip(const QString &toolTip)
+{
+ AbstractButtonInterface::setToolTip(toolTip);
+}
+
+void QmlBrowserActionButton::setIcon(const QString &icon)
+{
+ m_iconUrl = icon;
+ if (!m_popup) {
+ return;
+ }
+ auto qmlEngine = qobject_cast(m_popup->creationContext()->engine());
+ if (!qmlEngine) {
+ return;
+ }
+ const QString pluginPath = qmlEngine->extensionPath();
+ QIcon qicon = QmlStaticData::instance().getIcon(m_iconUrl, pluginPath);
+ AbstractButtonInterface::setIcon(qicon);
+}
+
+void QmlBrowserActionButton::setBadgeText(const QString &badgeText)
+{
+ AbstractButtonInterface::setBadgeText(badgeText);
+}
+
+void QmlBrowserActionButton::setPopup(QQmlComponent *popup)
+{
+ m_popup = popup;
+}
+
+void QmlBrowserActionButton::positionPopup(ClickController *clickController)
+{
+ if (!m_popup) {
+ qWarning() << "No popup to show";
+ return;
+ }
+
+ QQuickWindow *quickWindow = qobject_cast(m_popup->create(m_popup->creationContext()));
+ if (!quickWindow) {
+ qWarning() << "Cannot create QQuickWindow from popup";
+ return;
+ }
+ quickWindow->setFlags(Qt::Popup);
+ quickWindow->setPosition(clickController->callPopupPosition(quickWindow->size()));
+
+ connect(quickWindow, &QQuickWindow::activeChanged, this, [quickWindow, clickController]{
+ if (!quickWindow->isActive()) {
+ quickWindow->destroy();
+ clickController->callPopupClosed();
+ }
+ });
+
+ quickWindow->show();
+ quickWindow->requestActivate();
+}
diff --git a/src/lib/plugins/qml/api/clipboard/qmlclipboard.h b/src/lib/plugins/qml/api/clipboard/qmlclipboard.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/clipboard/qmlclipboard.h
@@ -0,0 +1,36 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+
+/**
+ * @brief The class exposing application
+ * clipboard to QML
+ */
+class QmlClipboard : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlClipboard(QObject *parent = nullptr);
+ /**
+ * @brief Copy the string to clipboard
+ * @param String representing the text to be copied
+ */
+ Q_INVOKABLE void copy(const QString &text);
+};
diff --git a/src/lib/plugins/qml/api/clipboard/qmlclipboard.cpp b/src/lib/plugins/qml/api/clipboard/qmlclipboard.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/clipboard/qmlclipboard.cpp
@@ -0,0 +1,31 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlclipboard.h"
+#include "mainapplication.h"
+#include
+#include
+
+QmlClipboard::QmlClipboard(QObject *parent)
+ : QObject(parent)
+{
+}
+
+void QmlClipboard::copy(const QString &text)
+{
+ mApp->clipboard()->setText(text);
+}
diff --git a/src/lib/plugins/qml/api/cookies/qmlcookie.h b/src/lib/plugins/qml/api/cookies/qmlcookie.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/cookies/qmlcookie.h
@@ -0,0 +1,80 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include
+#include
+
+/**
+ * @brief The class exposing QNetworkCookie to QML
+ */
+class QmlCookie : public QObject
+{
+ Q_OBJECT
+
+ /**
+ * @brief domain of the cookie
+ */
+ Q_PROPERTY(QString domain READ domain CONSTANT)
+
+ /**
+ * @brief expiration date of the cookie
+ */
+ Q_PROPERTY(QDateTime expirationDate READ expirationDate CONSTANT)
+
+ /**
+ * @brief name of the cookie
+ */
+ Q_PROPERTY(QString name READ name CONSTANT)
+
+ /**
+ * @brief path of the cookie
+ */
+ Q_PROPERTY(QString path READ path CONSTANT)
+
+ /**
+ * @brief checks if cookie is secure
+ */
+ Q_PROPERTY(bool secure READ secure CONSTANT)
+
+ /**
+ * @brief checks if cookie is a session cookie
+ */
+ Q_PROPERTY(bool session READ session CONSTANT)
+
+ /**
+ * @brief value of the cookie
+ */
+ Q_PROPERTY(QString value READ value CONSTANT)
+public:
+ explicit QmlCookie(QNetworkCookie *cookie, QObject *parent = nullptr);
+
+private:
+ QNetworkCookie *m_cookie = nullptr;
+
+ QString domain() const;
+ QDateTime expirationDate() const;
+ QString name() const;
+ QString path() const;
+ bool secure() const;
+ bool session() const;
+ QString value() const;
+};
+
+Q_DECLARE_METATYPE(QmlCookie*)
diff --git a/src/lib/plugins/qml/api/cookies/qmlcookie.cpp b/src/lib/plugins/qml/api/cookies/qmlcookie.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/cookies/qmlcookie.cpp
@@ -0,0 +1,82 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlcookie.h"
+#include
+
+QmlCookie::QmlCookie(QNetworkCookie *cookie, QObject *parent)
+ : QObject(parent)
+ , m_cookie(cookie)
+{
+ QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
+}
+
+QString QmlCookie::domain() const
+{
+ if (!m_cookie) {
+ return QString();
+ }
+ return m_cookie->domain();
+}
+
+QDateTime QmlCookie::expirationDate() const
+{
+ if (!m_cookie) {
+ return QDateTime();
+ }
+ return m_cookie->expirationDate();
+}
+
+QString QmlCookie::name() const
+{
+ if (!m_cookie) {
+ return QString();
+ }
+ return QString(m_cookie->name());
+}
+
+QString QmlCookie::path() const
+{
+ if (!m_cookie) {
+ return QString();
+ }
+ return m_cookie->path();
+}
+
+bool QmlCookie::secure() const
+{
+ if (!m_cookie) {
+ return false;
+ }
+ return m_cookie->isSecure();
+}
+
+bool QmlCookie::session() const
+{
+ if (!m_cookie) {
+ return false;
+ }
+ return m_cookie->isSessionCookie();
+}
+
+QString QmlCookie::value() const
+{
+ if (!m_cookie) {
+ return QString();
+ }
+ return QString(m_cookie->value());
+}
diff --git a/src/lib/plugins/qml/api/cookies/qmlcookies.h b/src/lib/plugins/qml/api/cookies/qmlcookies.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/cookies/qmlcookies.h
@@ -0,0 +1,98 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include "qmlcookie.h"
+
+/**
+ * @brief The class exposing Cookies API to QML
+ */
+class QmlCookies : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlCookies(QObject *parent = nullptr);
+ /**
+ * @brief Get a cookie
+ * @param A JavaScript object containing
+ * - name:
+ * String representing the name of the cookie
+ * - url:
+ * String representing the url of the cookie
+ * @return Cookie of type [QmlCookie](@ref QmlCookie)
+ * if such cookie exists, else null
+ */
+ Q_INVOKABLE QmlCookie *get(const QVariantMap &map);
+ /**
+ * @brief Get all cookies matching a criteria
+ * @param A JavaScript object containing
+ * - name:
+ * String representing the name of the cookie
+ * - url:
+ * String representing the url of the cookie
+ * - path:
+ * String representing the path of the cookie
+ * - secure:
+ * Bool representing if the cookie is secure
+ * - session:
+ * Bool representing if the cookie is a session cookie
+ * @return List containing cookies, each of type [QmlCookie](@ref QmlCookie)
+ */
+ Q_INVOKABLE QList getAll(const QVariantMap &map);
+ /**
+ * @brief Set a cookie
+ * @param A JavaScript object containing
+ * - name:
+ * String representing the name of the cookie
+ * - url:
+ * String representing the name of the cookie
+ * - path:
+ * String representing the path of the cookie
+ * - secure:
+ * Bool representing if the cookie is secure
+ * - expirationDate:
+ * A JavaScript Date object, representing the expiration date of the cookie
+ * - httpOnly:
+ * Bool representing if the cookie is httpOnly
+ * - value:
+ * String representing the value of the cookie
+ */
+ Q_INVOKABLE void set(const QVariantMap &map);
+ /**
+ * @brief Remove a cookie
+ * @param A JavaScript object containing
+ * - name:
+ * String representing the name of the cookie
+ * - url:
+ * String representing the url of the cookie
+ */
+ Q_INVOKABLE void remove(const QVariantMap &map);
+Q_SIGNALS:
+ /**
+ * @brief The signal emitted when a cookie is added or removed
+ * @param A JavaScript object containing
+ * - cookie:
+ * Object of type [QmlCookie](@ref QmlCookie), which is added or removed
+ * - removed:
+ * Bool representing if the cookie is removed
+ */
+ void changed(const QVariantMap &map);
+private:
+ QNetworkCookie getNetworkCookie(const QVariantMap &map);
+};
diff --git a/src/lib/plugins/qml/api/cookies/qmlcookies.cpp b/src/lib/plugins/qml/api/cookies/qmlcookies.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/cookies/qmlcookies.cpp
@@ -0,0 +1,114 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlcookies.h"
+#include "mainapplication.h"
+#include "cookiejar.h"
+#include "qwebengineprofile.h"
+#include "qml/qmlstaticdata.h"
+#include
+
+QmlCookies::QmlCookies(QObject *parent)
+ : QObject(parent)
+{
+ connect(mApp->cookieJar(), &CookieJar::cookieAdded, this, [this](const QNetworkCookie &network_cookie){
+ QmlCookie *cookie = QmlStaticData::instance().getCookie(network_cookie);
+ QVariantMap map;
+ map.insert(QSL("cookie"), QVariant::fromValue(cookie));
+ map.insert(QSL("removed"), false);
+ emit changed(map);
+ });
+
+ connect(mApp->cookieJar(), &CookieJar::cookieRemoved, this, [this](QNetworkCookie network_cookie){
+ QmlCookie *cookie = QmlStaticData::instance().getCookie(network_cookie);
+ QVariantMap map;
+ map.insert(QSL("cookie"), QVariant::fromValue(cookie));
+ map.insert(QSL("removed"), true);
+ emit changed(map);
+ });
+}
+
+QNetworkCookie QmlCookies::getNetworkCookie(const QVariantMap &map)
+{
+ if (!map.contains(QSL("name")) || !map.contains(QSL("url"))) {
+ qWarning() << "Error:" << "Wrong arguments passed to" << __FUNCTION__;
+ return QNetworkCookie();
+ }
+ const QString name = map.value(QSL("name")).toString();
+ const QString url = map.value(QSL("url")).toString();
+ QVector cookies = mApp->cookieJar()->getAllCookies();
+ for (const QNetworkCookie &cookie : qAsConst(cookies)) {
+ if (cookie.name() == name && cookie.domain() == url) {
+ return cookie;
+ }
+ }
+ return QNetworkCookie();
+}
+
+QmlCookie *QmlCookies::get(const QVariantMap &map)
+{
+ QNetworkCookie netCookie = getNetworkCookie(map);
+ return QmlStaticData::instance().getCookie(netCookie);
+}
+
+QList QmlCookies::getAll(const QVariantMap &map)
+{
+ QList qmlCookies;
+ const QString name = map.value(QSL("name")).toString();
+ const QString url = map.value(QSL("url")).toString();
+ const QString path = map.value(QSL("path")).toString();
+ const bool secure = map.value(QSL("secure")).toBool();
+ const bool session = map.value(QSL("session")).toBool();
+ QVector cookies = mApp->cookieJar()->getAllCookies();
+ for (QNetworkCookie cookie : qAsConst(cookies)) {
+ if ((!map.contains(QSL("name")) || cookie.name() == name)
+ && (!map.contains(QSL("url")) || cookie.domain() == url)
+ && (!map.contains(QSL("path")) || cookie.path() == path)
+ && (!map.contains(QSL("secure")) || cookie.isSecure() == secure)
+ && (!map.contains(QSL("session")) || cookie.isSessionCookie() == session)) {
+ QmlCookie *qmlCookie = QmlStaticData::instance().getCookie(cookie);
+ qmlCookies.append(qmlCookie);
+ }
+ }
+ return qmlCookies;
+}
+
+void QmlCookies::set(const QVariantMap &map)
+{
+ const QString name = map.value(QSL("name")).toString();
+ const QString url = map.value(QSL("url")).toString();
+ const QString path = map.value(QSL("path")).toString();
+ const bool secure = map.value(QSL("secure")).toBool();
+ const QDateTime expirationDate = QDateTime::fromMSecsSinceEpoch(map.value(QSL("expirationDate")).toDouble());
+ const bool httpOnly = map.value(QSL("httpOnly")).toBool();
+ const QString value = map.value(QSL("value")).toString();
+ QNetworkCookie cookie;
+ cookie.setName(name.toUtf8());
+ cookie.setDomain(url);
+ cookie.setPath(path);
+ cookie.setSecure(secure);
+ cookie.setExpirationDate(expirationDate);
+ cookie.setHttpOnly(httpOnly);
+ cookie.setValue(value.toUtf8());
+ mApp->webProfile()->cookieStore()->setCookie(cookie);
+}
+
+void QmlCookies::remove(const QVariantMap &map)
+{
+ QNetworkCookie netCookie = getNetworkCookie(map);
+ mApp->webProfile()->cookieStore()->deleteCookie(netCookie);
+}
diff --git a/src/lib/plugins/qml/api/events/qmlkeyevent.h b/src/lib/plugins/qml/api/events/qmlkeyevent.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/events/qmlkeyevent.h
@@ -0,0 +1,76 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include
+
+/**
+ * @brief The class exposing KeyEvent to QML
+ */
+class QmlKeyEvent : public QObject
+{
+ Q_OBJECT
+ /**
+ * @brief number of keys involved in this event
+ */
+ Q_PROPERTY(int count READ count CONSTANT)
+ /**
+ * @brief checks if the event comes from an auto-repeating key
+ */
+ Q_PROPERTY(bool autoRepeat READ isAutoRepeat CONSTANT)
+ /**
+ * @brief key code which is pressed/released
+ */
+ Q_PROPERTY(int key READ key CONSTANT)
+ /**
+ * @brief modifiers associated with the event
+ */
+ Q_PROPERTY(int modifiers READ modifiers CONSTANT)
+ /**
+ * @brief native modifiers of the event
+ */
+ Q_PROPERTY(quint32 nativeModifiers READ nativeModifiers CONSTANT)
+ /**
+ * @brief native scan code of the event
+ */
+ Q_PROPERTY(quint32 nativeScanCode READ nativeScanCode CONSTANT)
+ /**
+ * @brief native virtual key, or key sum of the event
+ */
+ Q_PROPERTY(quint32 nativeVirtualKey READ nativeVirtualKey CONSTANT)
+ /**
+ * @brief Returns the Unicode text that this key generated
+ */
+ Q_PROPERTY(QString text READ text CONSTANT)
+public:
+ explicit QmlKeyEvent(QKeyEvent *keyEvent = nullptr, QObject *parent = nullptr);
+ int count() const;
+ bool isAutoRepeat() const;
+ int key() const;
+ int modifiers() const;
+ quint32 nativeModifiers() const;
+ quint32 nativeScanCode() const;
+ quint32 nativeVirtualKey() const;
+ QString text() const;
+
+ void clear();
+
+private:
+ QKeyEvent *m_keyEvent = nullptr;
+};
diff --git a/src/lib/plugins/qml/api/events/qmlkeyevent.cpp b/src/lib/plugins/qml/api/events/qmlkeyevent.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/events/qmlkeyevent.cpp
@@ -0,0 +1,94 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlkeyevent.h"
+#include
+
+QmlKeyEvent::QmlKeyEvent(QKeyEvent *keyEvent, QObject *parent)
+ : QObject(parent)
+ , m_keyEvent(keyEvent)
+{
+}
+
+int QmlKeyEvent::count() const
+{
+ if (!m_keyEvent) {
+ return -1;
+ }
+ return m_keyEvent->count();
+}
+
+bool QmlKeyEvent::isAutoRepeat() const
+{
+ if (!m_keyEvent) {
+ return false;
+ }
+ return m_keyEvent->isAutoRepeat();
+}
+
+int QmlKeyEvent::key() const
+{
+ if (!m_keyEvent) {
+ return -1;
+ }
+ return m_keyEvent->key();
+}
+
+int QmlKeyEvent::modifiers() const
+{
+ if (!m_keyEvent) {
+ return -1;
+ }
+ return static_cast(m_keyEvent->modifiers());
+}
+
+quint32 QmlKeyEvent::nativeModifiers() const
+{
+ if (!m_keyEvent) {
+ return -1;
+ }
+ return m_keyEvent->nativeModifiers();
+}
+
+quint32 QmlKeyEvent::nativeScanCode() const
+{
+ if (!m_keyEvent) {
+ return -1;
+ }
+ return m_keyEvent->nativeScanCode();
+}
+
+quint32 QmlKeyEvent::nativeVirtualKey() const
+{
+ if (!m_keyEvent) {
+ return -1;
+ }
+ return m_keyEvent->nativeVirtualKey();
+}
+
+QString QmlKeyEvent::text() const
+{
+ if (!m_keyEvent) {
+ return QString();
+ }
+ return m_keyEvent->text();
+}
+
+void QmlKeyEvent::clear()
+{
+ m_keyEvent = nullptr;
+}
diff --git a/src/lib/plugins/qml/api/events/qmlmouseevent.h b/src/lib/plugins/qml/api/events/qmlmouseevent.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/events/qmlmouseevent.h
@@ -0,0 +1,95 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+
+/**
+ * @brief The class exposing MouseEvent to QML
+ */
+class QmlMouseEvent : public QObject
+{
+ Q_OBJECT
+ /**
+ * @brief button associated with the event
+ */
+ Q_PROPERTY(int button READ button CONSTANT)
+ /**
+ * @brief button state associated with the event
+ */
+ Q_PROPERTY(int buttons READ buttons CONSTANT)
+ /**
+ * @brief global position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(QPoint globalPos READ globalPos CONSTANT)
+ /**
+ * @brief global x position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(int globalX READ globalX CONSTANT)
+ /**
+ * @brief global y position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(int globalY READ globalY CONSTANT)
+ /**
+ * @brief local position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(QPointF localPos READ localPos CONSTANT)
+ /**
+ * @brief position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(QPoint pos READ pos CONSTANT)
+ /**
+ * @brief screen position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(QPointF screenPos READ screenPos CONSTANT)
+ /**
+ * @brief source of the event
+ */
+ Q_PROPERTY(int source READ source CONSTANT)
+ /**
+ * @brief window position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(QPointF windowPos READ windowPos CONSTANT)
+ /**
+ * @brief x position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(int x READ x CONSTANT)
+ /**
+ * @brief y position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(int y READ y CONSTANT)
+public:
+ explicit QmlMouseEvent(QMouseEvent *mouseEvent = nullptr, QObject *parent = nullptr);
+ int button() const;
+ int buttons() const;
+ QPoint globalPos() const;
+ int globalX() const;
+ int globalY() const;
+ QPointF localPos() const;
+ QPoint pos() const;
+ QPointF screenPos() const;
+ int source() const;
+ QPointF windowPos() const;
+ int x() const;
+ int y() const;
+
+ void clear();
+
+private:
+ QMouseEvent *m_mouseEvent = nullptr;
+};
diff --git a/src/lib/plugins/qml/api/events/qmlmouseevent.cpp b/src/lib/plugins/qml/api/events/qmlmouseevent.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/events/qmlmouseevent.cpp
@@ -0,0 +1,126 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlmouseevent.h"
+#include
+
+QmlMouseEvent::QmlMouseEvent(QMouseEvent *mouseEvent, QObject *parent)
+ : QObject(parent)
+ , m_mouseEvent(mouseEvent)
+{
+}
+
+int QmlMouseEvent::button() const
+{
+ if (!m_mouseEvent) {
+ return -1;
+ }
+ return static_cast(m_mouseEvent->button());
+}
+
+int QmlMouseEvent::buttons() const
+{
+ if (!m_mouseEvent) {
+ return -1;
+ }
+ return static_cast(m_mouseEvent->buttons());
+}
+
+QPoint QmlMouseEvent::globalPos() const
+{
+ if (!m_mouseEvent) {
+ return QPoint(-1, -1);
+ }
+ return m_mouseEvent->globalPos();
+}
+
+int QmlMouseEvent::globalX() const
+{
+ if (!m_mouseEvent) {
+ return -1;
+ }
+ return m_mouseEvent->globalX();
+}
+
+int QmlMouseEvent::globalY() const
+{
+ if (!m_mouseEvent) {
+ return -1;
+ }
+ return m_mouseEvent->globalY();
+}
+
+QPointF QmlMouseEvent::localPos() const
+{
+ if (!m_mouseEvent) {
+ return QPointF(-1, -1);
+ }
+ return m_mouseEvent->localPos();
+}
+
+QPoint QmlMouseEvent::pos() const
+{
+ if (!m_mouseEvent) {
+ return QPoint(-1, -1);
+ }
+ return m_mouseEvent->pos();
+}
+
+QPointF QmlMouseEvent::screenPos() const
+{
+ if (!m_mouseEvent) {
+ return QPointF(-1, -1);
+ }
+ return m_mouseEvent->screenPos();
+}
+
+int QmlMouseEvent::source() const
+{
+ if (!m_mouseEvent) {
+ return -1;
+ }
+ return static_cast(m_mouseEvent->source());
+}
+
+QPointF QmlMouseEvent::windowPos() const
+{
+ if (!m_mouseEvent) {
+ return QPointF(-1, -1);
+ }
+ return m_mouseEvent->windowPos();
+}
+
+int QmlMouseEvent::x() const
+{
+ if (!m_mouseEvent) {
+ return -1;
+ }
+ return m_mouseEvent->x();
+}
+
+int QmlMouseEvent::y() const
+{
+ if (!m_mouseEvent) {
+ return -1;
+ }
+ return m_mouseEvent->y();
+}
+
+void QmlMouseEvent::clear()
+{
+ m_mouseEvent = nullptr;
+}
diff --git a/src/lib/plugins/qml/api/events/qmlqzobjects.h b/src/lib/plugins/qml/api/events/qmlqzobjects.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/events/qmlqzobjects.h
@@ -0,0 +1,42 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include "qzcommon.h"
+#include
+
+/**
+ * @brief The class exposing Qz ObjectName to QML
+ */
+class QmlQzObjects : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * @brief The ObjectName enum
+ */
+ enum ObjectName {
+ ON_WebView = Qz::ON_WebView, //!< Represents object is webview
+ ON_TabBar = Qz::ON_TabBar, //!< Represents object is tabbar
+ ON_TabWidget = Qz::ON_TabWidget, //!< Represents object is tabwidget
+ ON_BrowserWindow = Qz::ON_BrowserWindow //!< Represents object is browser window
+ };
+ Q_ENUM(ObjectName)
+
+ explicit QmlQzObjects(QObject *parent = nullptr);
+};
diff --git a/src/lib/plugins/qml/api/events/qmlqzobjects.cpp b/src/lib/plugins/qml/api/events/qmlqzobjects.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/events/qmlqzobjects.cpp
@@ -0,0 +1,23 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlqzobjects.h"
+
+QmlQzObjects::QmlQzObjects(QObject *parent)
+ : QObject(parent)
+{
+}
diff --git a/src/lib/plugins/qml/api/events/qmlwheelevent.h b/src/lib/plugins/qml/api/events/qmlwheelevent.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/events/qmlwheelevent.h
@@ -0,0 +1,105 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include
+
+/**
+ * @brief The class exposing WheelEvent to QML
+ */
+class QmlWheelEvent : public QObject
+{
+ Q_OBJECT
+ /**
+ * @brief the distance that the wheel is rotated, in eighths of a degree
+ */
+ Q_PROPERTY(QPoint angleDelta READ angleDelta CONSTANT)
+ /**
+ * @brief mouse state at the time of event
+ */
+ Q_PROPERTY(int buttons READ buttons CONSTANT)
+ /**
+ * @brief global position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(QPoint globalPos READ globalPos CONSTANT)
+ /**
+ * @brief global position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(QPointF globalPosF READ globalPosF CONSTANT)
+ /**
+ * @brief global x position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(int globalX READ globalX CONSTANT)
+ /**
+ * @brief global y position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(int globalY READ globalY CONSTANT)
+ /**
+ * @brief checks if the delta values delivered with the event are inverted
+ */
+ Q_PROPERTY(bool inverted READ inverted CONSTANT)
+ /**
+ * @brief scrolling phase of this wheel event
+ */
+ Q_PROPERTY(int phase READ phase CONSTANT)
+ /**
+ * @brief scrolling distance in pixels on screen
+ */
+ Q_PROPERTY(QPoint pixelDelta READ pixelDelta CONSTANT)
+ /**
+ * @brief position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(QPoint pos READ pos CONSTANT)
+ /**
+ * @brief position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(QPointF posF READ posF CONSTANT)
+ /**
+ * @brief source of the event
+ */
+ Q_PROPERTY(int source READ source CONSTANT)
+ /**
+ * @brief x position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(int x READ x CONSTANT)
+ /**
+ * @brief y position of mouse cursor at the time of event
+ */
+ Q_PROPERTY(int y READ y CONSTANT)
+public:
+ explicit QmlWheelEvent(QWheelEvent *wheelEvent = nullptr, QObject *parent = nullptr);
+ QPoint angleDelta() const;
+ int buttons() const;
+ QPoint globalPos() const;
+ QPointF globalPosF() const;
+ int globalX() const;
+ int globalY() const;
+ bool inverted() const;
+ int phase() const;
+ QPoint pixelDelta() const;
+ QPoint pos() const;
+ QPointF posF() const;
+ int source() const;
+ int x() const;
+ int y() const;
+
+ void clear();
+private:
+ QWheelEvent *m_wheelEvent = nullptr;
+};
diff --git a/src/lib/plugins/qml/api/events/qmlwheelevent.cpp b/src/lib/plugins/qml/api/events/qmlwheelevent.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/events/qmlwheelevent.cpp
@@ -0,0 +1,142 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlwheelevent.h"
+#include
+
+QmlWheelEvent::QmlWheelEvent(QWheelEvent *wheelEvent, QObject *parent)
+ : QObject(parent)
+ , m_wheelEvent(wheelEvent)
+{
+}
+
+QPoint QmlWheelEvent::angleDelta() const
+{
+ if (!m_wheelEvent) {
+ return QPoint(-1, -1);
+ }
+ return m_wheelEvent->angleDelta();
+}
+
+int QmlWheelEvent::buttons() const
+{
+ if (!m_wheelEvent) {
+ return -1;
+ }
+ return static_cast(m_wheelEvent->buttons());
+}
+
+QPoint QmlWheelEvent::globalPos() const
+{
+ if (!m_wheelEvent) {
+ return QPoint(-1, -1);
+ }
+ return m_wheelEvent->globalPos();
+}
+
+QPointF QmlWheelEvent::globalPosF() const
+{
+ if (!m_wheelEvent) {
+ return QPointF(-1, -1);
+ }
+ return m_wheelEvent->globalPosF();
+}
+
+int QmlWheelEvent::globalX() const
+{
+ if (!m_wheelEvent) {
+ return -1;
+ }
+ return m_wheelEvent->globalX();
+}
+
+int QmlWheelEvent::globalY() const
+{
+ if (!m_wheelEvent) {
+ return -1;
+ }
+ return m_wheelEvent->globalY();
+}
+
+bool QmlWheelEvent::inverted() const
+{
+ if (!m_wheelEvent) {
+ return false;
+ }
+ return m_wheelEvent->inverted();
+}
+
+int QmlWheelEvent::phase() const
+{
+ if (!m_wheelEvent) {
+ return -1;
+ }
+ return static_cast(m_wheelEvent->phase());
+}
+
+QPoint QmlWheelEvent::pixelDelta() const
+{
+ if (!m_wheelEvent) {
+ return QPoint(-1, -1);
+ }
+ return m_wheelEvent->pixelDelta();
+}
+
+QPoint QmlWheelEvent::pos() const
+{
+ if (!m_wheelEvent) {
+ return QPoint(-1, -1);
+ }
+ return m_wheelEvent->pos();
+}
+
+QPointF QmlWheelEvent::posF() const
+{
+ if (!m_wheelEvent) {
+ return QPointF(-1, -1);
+ }
+ return m_wheelEvent->posF();
+}
+
+int QmlWheelEvent::source() const
+{
+ if (!m_wheelEvent) {
+ return -1;
+ }
+ return static_cast(m_wheelEvent->source());
+}
+
+int QmlWheelEvent::x() const
+{
+ if (!m_wheelEvent) {
+ return -1;
+ }
+ return m_wheelEvent->x();
+}
+
+int QmlWheelEvent::y() const
+{
+ if (!m_wheelEvent) {
+ return -1;
+ }
+ return m_wheelEvent->y();
+}
+
+void QmlWheelEvent::clear()
+{
+ m_wheelEvent = nullptr;
+}
diff --git a/src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.h b/src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.h
@@ -0,0 +1,63 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include "schemehandlers/extensionschemehandler.h"
+#include "qmlwebengineurlrequestjob.h"
+#include
+#include
+
+class QmlExtensionSchemeHandler;
+
+/**
+ * @brief The QmlExtensionScheme class, exposed to QML as ExtensionScheme
+ */
+class QmlExtensionScheme : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ /**
+ * @brief extension scheme handle name
+ */
+ Q_PROPERTY(QString name READ name WRITE setName)
+public:
+ explicit QmlExtensionScheme(QObject *parent = nullptr);
+ ~QmlExtensionScheme() override;
+ void classBegin() override {}
+ void componentComplete() override;
+Q_SIGNALS:
+ /**
+ * @brief The signal emitted when the request to the scheme handle is started
+ * @param request of the type [QmlWebEngineUrlRequestJob](@ref QmlWebEngineUrlRequestJob)
+ */
+ void requestStarted(QmlWebEngineUrlRequestJob *request);
+private:
+ QString m_name;
+ QmlExtensionSchemeHandler *m_schemeHandler = nullptr;
+
+ QString name() const;
+ void setName(const QString &name);
+};
+
+class QmlExtensionSchemeHandler : public ExtensionSchemeHandler
+{
+ Q_OBJECT
+public:
+ void requestStarted(QWebEngineUrlRequestJob *job);
+Q_SIGNALS:
+ void _requestStarted(QWebEngineUrlRequestJob *job);
+};
diff --git a/src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp b/src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp
@@ -0,0 +1,59 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlextensionscheme.h"
+#include "mainapplication.h"
+#include "networkmanager.h"
+#include
+#include
+#include
+
+QmlExtensionScheme::QmlExtensionScheme(QObject *parent)
+ : QObject(parent)
+{
+ m_schemeHandler = new QmlExtensionSchemeHandler;
+ connect(m_schemeHandler, &QmlExtensionSchemeHandler::_requestStarted, this, [this](QWebEngineUrlRequestJob *job) {
+ QmlWebEngineUrlRequestJob *request = new QmlWebEngineUrlRequestJob(job);
+ emit requestStarted(request);
+ });
+}
+
+QmlExtensionScheme::~QmlExtensionScheme()
+{
+ mApp->networkManager()->unregisterExtensionSchemeHandler(m_schemeHandler);
+ m_schemeHandler->deleteLater();
+}
+
+void QmlExtensionScheme::componentComplete()
+{
+ mApp->networkManager()->registerExtensionSchemeHandler(m_name, m_schemeHandler);
+}
+
+QString QmlExtensionScheme::name() const
+{
+ return m_name;
+}
+
+void QmlExtensionScheme::setName(const QString &name)
+{
+ m_name = name;
+}
+
+void QmlExtensionSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job)
+{
+ emit _requestStarted(job);
+}
diff --git a/src/lib/plugins/qml/api/extensionscheme/qmlwebengineurlrequestjob.h b/src/lib/plugins/qml/api/extensionscheme/qmlwebengineurlrequestjob.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/extensionscheme/qmlwebengineurlrequestjob.h
@@ -0,0 +1,77 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+
+/**
+ * @brief The QmlWebEngineUrlRequestJob class
+ */
+class QmlWebEngineUrlRequestJob : public QObject
+{
+ Q_OBJECT
+ /**
+ * @brief initiator of the QWebEngineUrlRequestJob
+ */
+ Q_PROPERTY(QString initiator READ initiator CONSTANT)
+ /**
+ * @brief request url of the QWebEngineUrlRequestJob
+ */
+ Q_PROPERTY(QString requestUrl READ requestUrl CONSTANT)
+ /**
+ * @brief request method of the QWebEngineUrlRequestJob
+ */
+ Q_PROPERTY(QString requestMethod READ requestMethod CONSTANT)
+public:
+ /**
+ * @brief The Error enum, exposes QWebEngineUrlRequestJob::Error to QML
+ */
+ enum Error {
+ NoError = QWebEngineUrlRequestJob::NoError, //! No error
+ UrlNotFound = QWebEngineUrlRequestJob::UrlNotFound, //! Url not found error
+ UrlInvaild = QWebEngineUrlRequestJob::UrlInvalid, //! Url invalid error
+ RequestAborted = QWebEngineUrlRequestJob::RequestAborted, //! Request aborted
+ RequestDenied = QWebEngineUrlRequestJob::RequestDenied, //! Request denied
+ RequestFailed = QWebEngineUrlRequestJob::RequestFailed //! Request failed
+ };
+ Q_ENUM(Error)
+ explicit QmlWebEngineUrlRequestJob(QWebEngineUrlRequestJob *job = nullptr, QObject *parent = nullptr);
+ /**
+ * @brief Fails the request with the error
+ * @param error
+ */
+ Q_INVOKABLE void fail(Error error);
+ /**
+ * @brief Redirects the request to the url
+ * @param urlString, represents the url to which the request is to be redirected
+ */
+ Q_INVOKABLE void redirect(const QString &urlString);
+ /**
+ * @brief Replies to the request
+ * @param A JavaScript object containing
+ * - content: String representing the reply data
+ * - contentType: String representing the contentType of reply data
+ */
+ Q_INVOKABLE void reply(const QVariantMap &map);
+private:
+ QWebEngineUrlRequestJob *m_job = nullptr;
+
+ QString initiator() const;
+ QString requestUrl() const;
+ QString requestMethod() const;
+};
diff --git a/src/lib/plugins/qml/api/extensionscheme/qmlwebengineurlrequestjob.cpp b/src/lib/plugins/qml/api/extensionscheme/qmlwebengineurlrequestjob.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/extensionscheme/qmlwebengineurlrequestjob.cpp
@@ -0,0 +1,85 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlwebengineurlrequestjob.h"
+#include
+#include
+#include
+
+QmlWebEngineUrlRequestJob::QmlWebEngineUrlRequestJob(QWebEngineUrlRequestJob *job, QObject *parent)
+ : QObject(parent)
+ , m_job(job)
+{
+}
+
+void QmlWebEngineUrlRequestJob::fail(QmlWebEngineUrlRequestJob::Error error)
+{
+ if (!m_job) {
+ return;
+ }
+ m_job->fail(QWebEngineUrlRequestJob::Error(error));
+}
+
+void QmlWebEngineUrlRequestJob::redirect(const QString &urlString)
+{
+ if (!m_job) {
+ return;
+ }
+ return m_job->redirect(QUrl::fromEncoded(urlString.toUtf8()));
+}
+
+void QmlWebEngineUrlRequestJob::reply(const QVariantMap &map)
+{
+ if (!m_job) {
+ return;
+ }
+ if (!map.contains(QSL("content")) || !map.contains(QSL("contentType"))) {
+ qWarning() << "Unable to call" << __FUNCTION__ << ": invalid parameters";
+ return;
+ }
+ QByteArray content = map.value(QSL("content")).toString().toUtf8();
+ QByteArray contentType = map.value(QSL("contentType")).toString().toUtf8();
+ QBuffer *buffer = new QBuffer();
+ buffer->open(QIODevice::ReadWrite);
+ buffer->write(content);
+ buffer->seek(0);
+ m_job->reply(contentType, buffer);
+}
+
+QString QmlWebEngineUrlRequestJob::initiator() const
+{
+ if (!m_job) {
+ return QString();
+ }
+ return QString::fromUtf8(m_job->initiator().toEncoded());
+}
+
+QString QmlWebEngineUrlRequestJob::requestUrl() const
+{
+ if (!m_job) {
+ return QString();
+ }
+ return QString::fromUtf8(m_job->requestUrl().toEncoded());
+}
+
+QString QmlWebEngineUrlRequestJob::requestMethod() const
+{
+ if (!m_job) {
+ return QString();
+ }
+ return QString::fromUtf8(m_job->requestMethod());
+}
diff --git a/src/lib/plugins/qml/api/fileutils/qmlfileutils.h b/src/lib/plugins/qml/api/fileutils/qmlfileutils.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/fileutils/qmlfileutils.h
@@ -0,0 +1,52 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+
+/**
+ * @brief The QmlFileUtils class, exposed to QML as FileUtils
+ */
+class QmlFileUtils : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlFileUtils(QString filePath, QObject *parent = nullptr);
+ /**
+ * @brief Get the path of the file within the plugin directory.
+ * If the filePath provided is resolved to be outside the plugin
+ * directory then empty string is returned
+ * @param file path within the plugin directory
+ * @return resolved path
+ */
+ Q_INVOKABLE QString resolve(const QString &filePath);
+ /**
+ * @brief Read the contents of the file within the plugin directory
+ * @param file path within the plugin directory
+ * @return contents of the file
+ */
+ Q_INVOKABLE QByteArray readAllFileContents(const QString &fileName);
+ /**
+ * @brief Checks if the file exists within the plugin directory
+ * @param file path within the plugin directory
+ * @return true if file exists, otherwise false
+ */
+ Q_INVOKABLE bool exists(const QString &filePath);
+private:
+ QString m_path;
+};
diff --git a/src/lib/plugins/qml/api/fileutils/qmlfileutils.cpp b/src/lib/plugins/qml/api/fileutils/qmlfileutils.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/fileutils/qmlfileutils.cpp
@@ -0,0 +1,51 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlfileutils.h"
+#include "datapaths.h"
+#include "qztools.h"
+#include
+#include
+#include
+
+QmlFileUtils::QmlFileUtils(QString filePath, QObject *parent)
+ : QObject(parent)
+{
+ m_path = filePath;
+}
+
+QString QmlFileUtils::resolve(const QString &filePath)
+{
+ QString resolvedPath = m_path + QL1C('/') + filePath;
+ resolvedPath = QDir::cleanPath(resolvedPath);
+ if (resolvedPath.contains(m_path)) {
+ return resolvedPath;
+ }
+ return QString();
+}
+
+QByteArray QmlFileUtils::readAllFileContents(const QString &fileName)
+{
+ const QString path = resolve(fileName);
+ return QzTools::readAllFileByteContents(path);
+}
+
+bool QmlFileUtils::exists(const QString &filePath)
+{
+ const QString path = resolve(filePath);
+ return QFile(path).exists();
+}
diff --git a/src/lib/plugins/qml/api/history/qmlhistory.h b/src/lib/plugins/qml/api/history/qmlhistory.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/history/qmlhistory.h
@@ -0,0 +1,85 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include "qmlhistoryitem.h"
+
+/**
+ * @brief The class exposing the History API to QML
+ */
+class QmlHistory : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlHistory(QObject *parent = nullptr);
+ /**
+ * @brief Searches History Entries against a search query
+ * @param String representing the search query
+ * @return List of History Entries, each of type [QmlHistoryItem](@ref QmlHistoryItem),
+ * matching the search query
+ */
+ Q_INVOKABLE QList search(const QString &text);
+ /**
+ * @brief Get the visit count of a url
+ * @param String representing the url
+ * @return Integer representing the visit count of the given url
+ */
+ Q_INVOKABLE int getVisits(const QString &url);
+ /**
+ * @brief Add url to the history
+ * @param A JavaScript object containing
+ * - title:
+ * String representing the title of the hisotry entry
+ * - url:
+ * String representing the url of the history entry
+ */
+ Q_INVOKABLE void addUrl(const QVariantMap &map);
+ /**
+ * @brief Deletes a url from the history
+ * @param String representing the url of the history entry
+ */
+ Q_INVOKABLE void deleteUrl(const QString &url);
+ /**
+ * @brief Deletes history entries within the given range
+ * @param A JavaScript object containing
+ * - startTime:
+ * A JavaScript Date object representing the start time
+ * - endTime:
+ * A JavaScript Date object representing the end time
+ */
+ Q_INVOKABLE void deleteRange(const QVariantMap &map);
+ /**
+ * @brief Clears all the history
+ */
+ Q_INVOKABLE void deleteAll();
+Q_SIGNALS:
+ /**
+ * @brief The signal emitted when a HistoryEntry is added
+ * @param Object of type [QmlHistoryItem](@ref QmlHistoryItem), representing
+ * the added History Entry
+ */
+ void visited(QmlHistoryItem *historyItem);
+
+ /**
+ * @brief The signal emitted when a HistoryEntry is removed
+ * @param Object of type [QmlHistoryItem](@ref QmlHistoryItem), representing
+ * the removed History Entry
+ */
+ void visitRemoved(QmlHistoryItem *historyItem);
+};
diff --git a/src/lib/plugins/qml/api/history/qmlhistory.cpp b/src/lib/plugins/qml/api/history/qmlhistory.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/history/qmlhistory.cpp
@@ -0,0 +1,97 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlhistory.h"
+#include "mainapplication.h"
+#include "history.h"
+#include "sqldatabase.h"
+#include "qml/qmlstaticdata.h"
+#include
+
+QmlHistory::QmlHistory(QObject *parent)
+ : QObject(parent)
+{
+ connect(mApp->history(), &History::historyEntryAdded, this, [this](HistoryEntry entry){
+ QmlHistoryItem *historyItem = QmlStaticData::instance().getHistoryItem(entry);
+ emit visited(historyItem);
+ });
+
+ connect(mApp->history(), &History::historyEntryDeleted, this, [this](HistoryEntry entry){
+ QmlHistoryItem *historyItem = QmlStaticData::instance().getHistoryItem(entry);
+ emit visitRemoved(historyItem);
+ });
+}
+
+QList QmlHistory::search(const QString &text)
+{
+ QList list;
+ const QList result = mApp->history()->searchHistoryEntry(text);
+ list.reserve(result.size());
+ for (HistoryEntry entry : result) {
+ auto item = QmlStaticData::instance().getHistoryItem(entry);
+ list.append(item);
+ }
+ return list;
+}
+
+int QmlHistory::getVisits(const QString &url)
+{
+ HistoryEntry *entry = mApp->history()->getHistoryEntry(url);
+ if (!entry) {
+ return -1;
+ }
+ return entry->count;
+}
+
+void QmlHistory::addUrl(const QVariantMap &map)
+{
+ if (!map.contains(QSL("title")) || !map.contains(QSL("url"))) {
+ qWarning() << "Error:" << "wrong arguments passed to" << __FUNCTION__;
+ return;
+ }
+ QString title = map.value(QSL("title")).toString();
+ const QString url = map.value(QSL("url")).toString();
+
+ title = title.isEmpty() ? url : title;
+
+ mApp->history()->addHistoryEntry(QUrl::fromEncoded(url.toUtf8()), title);
+}
+
+void QmlHistory::deleteUrl(const QString &url)
+{
+ mApp->history()->deleteHistoryEntry(url);
+}
+
+void QmlHistory::deleteRange(const QVariantMap &map)
+{
+ if (!map.contains(QSL("startTime")) || !map.contains(QSL("endTime"))) {
+ qWarning() << "Error:" << "wrong arguments passed to" << __FUNCTION__;
+ return;
+ }
+ const qlonglong startTime = map.value(QSL("startTime")).toLongLong();
+ const qlonglong endTime = map.value(QSL("endTime")).toLongLong();
+
+ const QList entries = mApp->history()->indexesFromTimeRange(startTime, endTime);
+ for (int index : entries) {
+ mApp->history()->deleteHistoryEntry(index);
+ }
+}
+
+void QmlHistory::deleteAll()
+{
+ mApp->history()->clearHistory();
+}
diff --git a/src/lib/plugins/qml/api/history/qmlhistoryitem.h b/src/lib/plugins/qml/api/history/qmlhistoryitem.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/history/qmlhistoryitem.h
@@ -0,0 +1,65 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include "history.h"
+
+/**
+ * @brief The class exposing HistoryEntry to QML
+ */
+class QmlHistoryItem : public QObject
+{
+ Q_OBJECT
+
+ /**
+ * @brief id of the history item
+ */
+ Q_PROPERTY(int id READ id CONSTANT)
+
+ /**
+ * @brief url of the history item
+ */
+ Q_PROPERTY(QString url READ url CONSTANT)
+
+ /**
+ * @brief title of the history item
+ */
+ Q_PROPERTY(QString title READ title CONSTANT)
+
+ /**
+ * @brief visit count of the history item
+ */
+ Q_PROPERTY(int visitCount READ visitCount CONSTANT)
+
+ /**
+ * @brief last visit time of the history item
+ */
+ Q_PROPERTY(QDateTime lastVisitTime READ lastVisitTime CONSTANT)
+public:
+ explicit QmlHistoryItem(HistoryEntry entry, QObject *parent = nullptr);
+
+private:
+ HistoryEntry m_entry;
+
+ int id() const;
+ QString url() const;
+ QString title() const;
+ int visitCount() const;
+ QDateTime lastVisitTime() const;
+};
diff --git a/src/lib/plugins/qml/api/history/qmlhistoryitem.cpp b/src/lib/plugins/qml/api/history/qmlhistoryitem.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/history/qmlhistoryitem.cpp
@@ -0,0 +1,51 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlhistoryitem.h"
+#include
+
+QmlHistoryItem::QmlHistoryItem(HistoryEntry entry, QObject *parent)
+ : QObject(parent)
+ , m_entry(entry)
+{
+ QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
+}
+
+int QmlHistoryItem::id() const
+{
+ return m_entry.id;
+}
+
+QString QmlHistoryItem::url() const
+{
+ return QString::fromUtf8(m_entry.url.toEncoded());
+}
+
+QString QmlHistoryItem::title() const
+{
+ return m_entry.title;
+}
+
+int QmlHistoryItem::visitCount() const
+{
+ return m_entry.count;
+}
+
+QDateTime QmlHistoryItem::lastVisitTime() const
+{
+ return m_entry.date;
+}
diff --git a/src/lib/plugins/qml/api/i18n/qmli18n.h b/src/lib/plugins/qml/api/i18n/qmli18n.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/i18n/qmli18n.h
@@ -0,0 +1,46 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+
+extern "C" {
+#include
+}
+
+/**
+ * @brief The class exposing GNU Gettext to QML
+ */
+class QmlI18n : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlI18n(const QString &pluginName, QObject *parent = nullptr);
+ void initTranslations();
+ /**
+ * @brief wrapper for gettext function
+ */
+ Q_INVOKABLE QString i18n(const QString &string);
+ /**
+ * @brief wrapper for ngettext function
+ */
+ Q_INVOKABLE QString i18np(const QString &string1, const QString &string2, int count);
+private:
+ QString m_pluginName;
+ QString m_domain;
+};
diff --git a/src/lib/plugins/qml/api/i18n/qmli18n.cpp b/src/lib/plugins/qml/api/i18n/qmli18n.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/i18n/qmli18n.cpp
@@ -0,0 +1,52 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmli18n.h"
+#include "qztools.h"
+#include
+
+QmlI18n::QmlI18n(const QString &pluginName, QObject *parent)
+ : QObject(parent)
+{
+ m_pluginName = pluginName;
+ initTranslations();
+}
+
+void QmlI18n::initTranslations()
+{
+ m_domain = QString(QSL("falkon_%1")).arg(m_pluginName);
+ const QString localeDir = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSL("locale"), QStandardPaths::LocateDirectory);
+ const bool isLanguageSet = qEnvironmentVariableIsSet("LANGUAGE");
+ const QByteArray language = qgetenv("LANGUAGE");
+ qputenv("LANGUAGE", QLocale::system().name().toUtf8());
+ bindtextdomain(m_domain.toUtf8(), localeDir.toUtf8());
+ if (!isLanguageSet) {
+ qunsetenv("LANGUAGE");
+ } else {
+ qputenv("LANGUAGE", language);
+ }
+}
+
+QString QmlI18n::i18n(const QString &string)
+{
+ return QString::fromUtf8(dgettext(m_domain.toUtf8(), string.toUtf8()));
+}
+
+QString QmlI18n::i18np(const QString &string1, const QString &string2, int count)
+{
+ return QString::fromUtf8(dngettext(m_domain.toUtf8(), string1.toUtf8(), string2.toUtf8(), count));
+}
diff --git a/src/lib/plugins/qml/api/menus/qmlaction.h b/src/lib/plugins/qml/api/menus/qmlaction.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/menus/qmlaction.h
@@ -0,0 +1,50 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include
+#include
+
+class QmlEngine;
+
+/**
+ * @brief The class exposing Action API to QML
+ */
+class QmlAction : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlAction(QAction *action, QmlEngine *engine, QObject *parent = nullptr);
+ void setProperties(const QVariantMap &map);
+ /**
+ * @brief Updates the properties of the action
+ * @param A JavaScript object containing the updated properties of the action.
+ */
+ Q_INVOKABLE void update(const QVariantMap &map);
+
+Q_SIGNALS:
+ /**
+ * @brief This signal is emitted when the action is triggered.
+ */
+ void triggered();
+
+private:
+ QAction *m_action = nullptr;
+ QString m_pluginPath;
+};
diff --git a/src/lib/plugins/qml/api/menus/qmlaction.cpp b/src/lib/plugins/qml/api/menus/qmlaction.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/menus/qmlaction.cpp
@@ -0,0 +1,57 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlaction.h"
+#include "qztools.h"
+#include "qml/api/fileutils/qmlfileutils.h"
+#include "qml/qmlengine.h"
+#include "qml/qmlstaticdata.h"
+#include
+
+QmlAction::QmlAction(QAction *action, QmlEngine *engine, QObject *parent)
+ : QObject(parent)
+ , m_action(action)
+{
+ QmlEngine *qmlEngine = qobject_cast(engine);
+ m_pluginPath = qmlEngine->extensionPath();
+ connect(m_action, &QAction::triggered, this, &QmlAction::triggered);
+}
+
+void QmlAction::setProperties(const QVariantMap &map)
+{
+ if (!m_action) {
+ return;
+ }
+
+ for (auto it = map.cbegin(); it != map.cend(); it++) {
+ const QString key = it.key();
+ if (key == QSL("icon")) {
+ QString iconPath = map.value(key).toString();
+ QIcon icon = QmlStaticData::instance().getIcon(iconPath, m_pluginPath);
+ m_action->setIcon(icon);
+ } else if (key == QSL("shortcut")) {
+ m_action->setShortcut(QKeySequence(map.value(key).toString()));
+ } else {
+ m_action->setProperty(key.toUtf8(), map.value(key));
+ }
+ }
+}
+
+void QmlAction::update(const QVariantMap &map)
+{
+ setProperties(map);
+}
diff --git a/src/lib/plugins/qml/api/menus/qmlmenu.h b/src/lib/plugins/qml/api/menus/qmlmenu.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/menus/qmlmenu.h
@@ -0,0 +1,64 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include "qmlaction.h"
+#include
+#include
+
+class QmlEngine;
+
+/**
+ * @brief The class exposing WebView contextmenu to QML as Menu API
+ */
+class QmlMenu : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlMenu(QMenu *menu, QQmlEngine *engine, QObject *parent = nullptr);
+ /**
+ * @brief Adds action to menu
+ * @param A JavaScript object containing properties for action.
+ * The icon property must be in form of url of the path
+ * and shortcut in form string.
+ * @return action of type [QmlAction](@ref QmlAction)
+ */
+ Q_INVOKABLE QmlAction *addAction(const QVariantMap &map);
+ /**
+ * @brief Adds sub-menu to menu
+ * @param A JavaScript object containing properties of menu.
+ * The icon property must be in form of url of the path.
+ * @return menu of type [QmlMenu](@ref QmlMenu)
+ */
+ Q_INVOKABLE QmlMenu *addMenu(const QVariantMap &map);
+ /**
+ * @brief Adds a separator to menu
+ */
+ Q_INVOKABLE void addSeparator();
+
+Q_SIGNALS:
+ /**
+ * @brief This signal is emitted when the menu is triggred
+ */
+ void triggered();
+
+private:
+ QMenu *m_menu = nullptr;
+ QString m_pluginPath;
+ QmlEngine *m_engine = nullptr;
+};
diff --git a/src/lib/plugins/qml/api/menus/qmlmenu.cpp b/src/lib/plugins/qml/api/menus/qmlmenu.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/menus/qmlmenu.cpp
@@ -0,0 +1,78 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlmenu.h"
+#include "qztools.h"
+#include "qml/api/fileutils/qmlfileutils.h"
+#include "qml/qmlengine.h"
+#include "qml/qmlstaticdata.h"
+
+QmlMenu::QmlMenu(QMenu *menu, QQmlEngine *engine, QObject *parent)
+ : QObject(parent)
+ , m_menu(menu)
+{
+ QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership);
+
+ m_engine = qobject_cast(engine);
+ m_pluginPath = m_engine->extensionPath();
+ connect(m_menu, &QMenu::triggered, this, &QmlMenu::triggered);
+}
+
+QmlAction *QmlMenu::addAction(const QVariantMap &map)
+{
+ if (!m_menu) {
+ return nullptr;
+ }
+
+ QAction *action = new QAction();
+ QmlAction *qmlAction = new QmlAction(action, m_engine, this);
+ qmlAction->setProperties(map);
+ m_menu->addAction(action);
+
+ return qmlAction;
+}
+
+QmlMenu *QmlMenu::addMenu(const QVariantMap &map)
+{
+ if (!m_menu) {
+ return nullptr;
+ }
+
+ QMenu *newMenu = new QMenu();
+ for (auto it = map.cbegin(); it != map.cend(); it++) {
+ const QString key = it.key();
+ if (key == QSL("icon")) {
+ QString iconPath = map.value(key).toString();
+ QIcon icon = QmlStaticData::instance().getIcon(iconPath, m_pluginPath);
+ newMenu->setIcon(icon);
+ continue;
+ }
+ newMenu->setProperty(key.toUtf8(), map.value(key));
+ }
+ m_menu->addMenu(newMenu);
+ QmlMenu *newQmlMenu = new QmlMenu(newMenu, m_engine, this);
+ return newQmlMenu;
+}
+
+void QmlMenu::addSeparator()
+{
+ if (!m_menu) {
+ return;
+ }
+
+ m_menu->addSeparator();
+}
diff --git a/src/lib/plugins/qml/api/menus/qmlwebhittestresult.h b/src/lib/plugins/qml/api/menus/qmlwebhittestresult.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/menus/qmlwebhittestresult.h
@@ -0,0 +1,114 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include "webhittestresult.h"
+#include
+
+/**
+ * @brief The class exposing result of WebHitTest to QML
+ */
+class QmlWebHitTestResult : public QObject
+{
+ Q_OBJECT
+ /**
+ * @brief Gets the tagName of the element on which the context menu is requested.
+ */
+ Q_PROPERTY(QString tagName READ tagName CONSTANT)
+ /**
+ * @brief Gets the base url on which the context menu is requested.
+ */
+ Q_PROPERTY(QString baseUrl READ baseUrl CONSTANT)
+ /**
+ * @brief Gets the link title on which the context menu is requested.
+ */
+ Q_PROPERTY(QString linkTitle READ linkTitle CONSTANT)
+ /**
+ * @brief Gets the link url on which the context menu is requested.
+ */
+ Q_PROPERTY(QString linkUrl READ linkUrl CONSTANT)
+ /**
+ * @brief Gets the url of image on which the context menu is requested.
+ */
+ Q_PROPERTY(QString imageUrl READ imageUrl CONSTANT)
+ /**
+ * @brief Gets the url of media on which the context menu is requested.
+ */
+ Q_PROPERTY(QString mediaUrl READ mediaUrl CONSTANT)
+ /**
+ * @brief Gets the position at which the context menu is requested.
+ */
+ Q_PROPERTY(QPoint pos READ pos CONSTANT)
+ /**
+ * @brief Gets the viewport position at which the context menu is requested.
+ */
+ Q_PROPERTY(QPointF viewportPos READ viewportPos CONSTANT)
+public:
+ explicit QmlWebHitTestResult(const WebHitTestResult &webHitTestResult, QObject *parent = nullptr);
+ /**
+ * @brief Checks if the context menu is requested on image.
+ * @return true if image, else false
+ */
+ Q_INVOKABLE bool isImage() const;
+ /**
+ * @brief Checks if the context menu is requested on editable content.
+ * @return true if the content is editable, else false
+ */
+ Q_INVOKABLE bool isContentEditable() const;
+ /**
+ * @brief Checks if the context menu is requested on the selected content.
+ * @return true if content is selected, else false.
+ */
+ Q_INVOKABLE bool isContentSelected() const;
+ /**
+ * @brief Checks if the context menu is requested on null element.
+ * @return true if the element is null, else false
+ */
+ Q_INVOKABLE bool isNull() const;
+ /**
+ * @brief Checks if the context menu is requested on a link.
+ * @return true if the element is link, else false
+ */
+ Q_INVOKABLE bool isLink() const;
+ /**
+ * @brief Checks if the context menu is requested on a media element.
+ * @return true if the element is media, else false
+ */
+ Q_INVOKABLE bool isMedia() const;
+ /**
+ * @brief Checks if the context menu requested on media element is paused.
+ * @return true if media is paused, else false
+ */
+ Q_INVOKABLE bool mediaPaused() const;
+ /**
+ * @brief Checks if the context menu requested on media element is muted.
+ * @return true if media is muted, else false
+ */
+ Q_INVOKABLE bool mediaMuted() const;
+ QString tagName() const;
+ QString baseUrl() const;
+ QString linkTitle() const;
+ QString linkUrl() const;
+ QString imageUrl() const;
+ QString mediaUrl() const;
+ QPoint pos() const;
+ QPointF viewportPos() const;
+
+private:
+ WebHitTestResult m_webHitTestResult;
+};
diff --git a/src/lib/plugins/qml/api/menus/qmlwebhittestresult.cpp b/src/lib/plugins/qml/api/menus/qmlwebhittestresult.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/menus/qmlwebhittestresult.cpp
@@ -0,0 +1,110 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlwebhittestresult.h"
+#include
+
+QmlWebHitTestResult::QmlWebHitTestResult(const WebHitTestResult &webHitTestResult, QObject *parent)
+ : QObject(parent)
+ , m_webHitTestResult(webHitTestResult)
+{
+ QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership);
+}
+
+bool QmlWebHitTestResult::isImage() const
+{
+ return !m_webHitTestResult.imageUrl().isEmpty();
+}
+
+bool QmlWebHitTestResult::isContentEditable() const
+{
+ return m_webHitTestResult.isContentEditable();
+}
+
+bool QmlWebHitTestResult::isContentSelected() const
+{
+ return m_webHitTestResult.isContentSelected();
+}
+
+bool QmlWebHitTestResult::isNull() const
+{
+ return m_webHitTestResult.isNull();
+}
+
+bool QmlWebHitTestResult::isLink() const
+{
+ return !m_webHitTestResult.linkUrl().isEmpty();
+}
+
+bool QmlWebHitTestResult::isMedia() const
+{
+ return !m_webHitTestResult.mediaUrl().isEmpty();
+}
+
+bool QmlWebHitTestResult::mediaPaused() const
+{
+ return m_webHitTestResult.mediaPaused();
+}
+
+bool QmlWebHitTestResult::mediaMuted() const
+{
+ return m_webHitTestResult.mediaMuted();
+}
+
+QString QmlWebHitTestResult::tagName() const
+{
+ return m_webHitTestResult.tagName();
+}
+
+QString QmlWebHitTestResult::baseUrl() const
+{
+ const QUrl base = m_webHitTestResult.baseUrl();
+ return QString::fromUtf8(base.toEncoded());
+}
+
+QString QmlWebHitTestResult::linkTitle() const
+{
+ return m_webHitTestResult.linkTitle();
+}
+
+QString QmlWebHitTestResult::linkUrl() const
+{
+ const QUrl link = m_webHitTestResult.linkUrl();
+ return QString::fromUtf8(link.toEncoded());
+}
+
+QString QmlWebHitTestResult::imageUrl() const
+{
+ const QUrl image = m_webHitTestResult.imageUrl();
+ return QString::fromUtf8(image.toEncoded());
+}
+
+QString QmlWebHitTestResult::mediaUrl() const
+{
+ const QUrl media = m_webHitTestResult.mediaUrl();
+ return QString::fromUtf8(media.toEncoded());
+}
+
+QPoint QmlWebHitTestResult::pos() const
+{
+ return m_webHitTestResult.pos();
+}
+
+QPointF QmlWebHitTestResult::viewportPos() const
+{
+ return m_webHitTestResult.viewportPos();
+}
diff --git a/src/lib/plugins/qml/api/notifications/qmlnotifications.h b/src/lib/plugins/qml/api/notifications/qmlnotifications.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/notifications/qmlnotifications.h
@@ -0,0 +1,50 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+
+/**
+ * @brief The class to display notifications
+ */
+class QmlNotifications : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlNotifications(QObject *parent = nullptr);
+ /**
+ * @brief Create and display a notification
+ * @param JavaScript object containing
+ * - icon:
+ * String representing the icon file url. The icon path will be
+ * search in the following order
+ * - Falkon resource: for the icons starting with ":", they are searched in
+ * falkon resource file
+ * - Files in plugin directory: All other paths will be resolved relative to
+ * the plugin directory. If the icon path is outside the
+ * plugin directory, then it will be resolved as empty path.
+ * - heading:
+ * String representing the heading of the notification
+ * - message:
+ * String representing the message of the notification
+ */
+ Q_INVOKABLE void create(const QVariantMap &map);
+ void setPluginPath(const QString &path);
+private:
+ QString m_pluginPath;
+};
diff --git a/src/lib/plugins/qml/api/notifications/qmlnotifications.cpp b/src/lib/plugins/qml/api/notifications/qmlnotifications.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/notifications/qmlnotifications.cpp
@@ -0,0 +1,43 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlnotifications.h"
+#include "mainapplication.h"
+#include "desktopnotificationsfactory.h"
+#include "qztools.h"
+#include "qml/api/fileutils/qmlfileutils.h"
+
+QmlNotifications::QmlNotifications(QObject *parent)
+ : QObject(parent)
+{
+}
+
+void QmlNotifications::create(const QVariantMap &map)
+{
+ const QString iconUrl = map.value(QSL("icon")).toString();
+ QmlFileUtils fileUtils(m_pluginPath);
+ const QString iconPath = fileUtils.resolve(iconUrl);
+ QPixmap icon = QPixmap(iconPath);
+ const QString heading = map.value(QSL("heading")).toString();
+ const QString message = map.value(QSL("message")).toString();
+ mApp->desktopNotifications()->showNotification(icon, heading, message);
+}
+
+void QmlNotifications::setPluginPath(const QString &path)
+{
+ m_pluginPath = path;
+}
diff --git a/src/lib/plugins/qml/api/qmlenums.h b/src/lib/plugins/qml/api/qmlenums.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/qmlenums.h
@@ -0,0 +1,54 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include "qzcommon.h"
+
+/**
+ * @brief The class exposing Enums to QML
+ */
+class QmlEnums : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * @brief The WindowState enum
+ */
+ enum WindowState {
+ FullScreen, //! Represents full screen window
+ Maximized, //! Represents maximized window
+ Minimized, //! Represents minimized window
+ Normal, //! Represents normal window
+ Invalid //! Represents a invalid window
+ };
+ Q_ENUM(WindowState)
+
+ /**
+ * @brief The WindowType enum
+ */
+ enum WindowType {
+ FirstAppWindow = Qz::BW_FirstAppWindow, //! Represents first app window
+ MacFirstWindow = Qz::BW_MacFirstWindow, //! Represents first mac window
+ NewWindow = Qz::BW_NewWindow, //! Represents new window
+ OtherRestoredWindow = Qz::BW_OtherRestoredWindow //! Represents other restored window
+ };
+ Q_ENUM(WindowType)
+
+ QmlEnums(QObject *parent = nullptr);
+};
diff --git a/src/lib/plugins/qml/api/qmlenums.cpp b/src/lib/plugins/qml/api/qmlenums.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/qmlenums.cpp
@@ -0,0 +1,23 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlenums.h"
+
+QmlEnums::QmlEnums(QObject *parent)
+ : QObject(parent)
+{
+}
diff --git a/src/lib/plugins/qml/api/settings/qmlsettings.h b/src/lib/plugins/qml/api/settings/qmlsettings.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/settings/qmlsettings.h
@@ -0,0 +1,80 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include
+
+/**
+ * @brief The class exposing Settings API to QML
+ */
+class QmlSettings : public QObject
+{
+ Q_OBJECT
+
+ /**
+ * @brief name of the folder in which settings.ini file is located
+ * on the standard extension path.
+ */
+ Q_PROPERTY(QString name READ name WRITE setName)
+
+public:
+ explicit QmlSettings(QObject *parent = nullptr);
+ /**
+ * @brief Sets the value for a given key.
+ * @param A JavaScript object containing
+ * - key: QString representing the key
+ * - value: QVariant representing the value for the key
+ * @return true if value is set, else false
+ */
+ Q_INVOKABLE bool setValue(const QVariantMap &map);
+ /**
+ * @brief Gets the value for a given key.
+ * @param A JavaScript object containing
+ * - key: QString representing the key
+ * - defaultValue: QVariant representing the default value for the key
+ * @return QVariant representing value
+ */
+ Q_INVOKABLE QVariant value(const QVariantMap &map);
+ /**
+ * @brief Checks if a given key exists.
+ * @param QString representing the key
+ * @return true if key exists, else false
+ */
+ Q_INVOKABLE bool contains(const QString &key);
+ /**
+ * @brief Removes the given key-value from the settings.
+ * @param QString representing the key
+ * @return true if key-value pair is removed, else false
+ */
+ Q_INVOKABLE bool remove(const QString &key);
+ /**
+ * @brief syncs the settings
+ * @return true if success, else false
+ */
+ Q_INVOKABLE bool sync();
+
+private:
+ QSettings *m_settings = nullptr;
+ QString m_settingsPath;
+ QString m_name;
+
+ QString name() const;
+ void setName(const QString &name);
+ void createSettings();
+};
diff --git a/src/lib/plugins/qml/api/settings/qmlsettings.cpp b/src/lib/plugins/qml/api/settings/qmlsettings.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/settings/qmlsettings.cpp
@@ -0,0 +1,104 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlsettings.h"
+#include "datapaths.h"
+#include
+
+QmlSettings::QmlSettings(QObject *parent)
+ : QObject(parent)
+{
+ m_settingsPath = DataPaths::currentProfilePath() + QL1S("/extensions");
+}
+
+bool QmlSettings::setValue(const QVariantMap &map)
+{
+ if (!m_settings) {
+ return false;
+ }
+
+ if (!map.contains(QSL("key")) || !map.contains(QSL("value"))) {
+ qWarning() << "Unable to set value:" << "cannot determine Key-Value from the argument";
+ return false;
+ }
+ const QString key = map.value(QSL("key")).toString();
+ const QVariant value = map.value(QSL("value"));
+ m_settings->setValue(key, value);
+ return true;
+}
+
+QVariant QmlSettings::value(const QVariantMap &map)
+{
+ if (!m_settings) {
+ return QVariant();
+ }
+
+ if (!map.contains(QSL("key"))) {
+ qWarning() << "Unable to get value:" << "key not defined";
+ return QVariant();
+ }
+
+ const QString key = map.value(QSL("key")).toString();
+ const QVariant defaultValue = map.value(QSL("defaultValue"));
+ return m_settings->value(key, defaultValue);
+}
+
+bool QmlSettings::contains(const QString &key)
+{
+ if (!m_settings) {
+ return false;
+ }
+
+ return m_settings->contains(key);
+}
+
+bool QmlSettings::remove(const QString &key)
+{
+ if (!m_settings) {
+ return false;
+ }
+
+ m_settings->remove(key);
+ return true;
+}
+
+bool QmlSettings::sync()
+{
+ if (!m_settings) {
+ return false;
+ }
+
+ m_settings->sync();
+ return true;
+}
+
+QString QmlSettings::name() const
+{
+ return m_name;
+}
+
+void QmlSettings::setName(const QString &name)
+{
+ m_name = name;
+ createSettings();
+}
+
+void QmlSettings::createSettings()
+{
+ m_settingsPath += QL1C('/') + m_name + QL1S("/settings.ini");
+ m_settings = new QSettings(m_settingsPath, QSettings::IniFormat, this);
+}
diff --git a/src/lib/plugins/qml/api/sidebar/qmlsidebar.h b/src/lib/plugins/qml/api/sidebar/qmlsidebar.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/sidebar/qmlsidebar.h
@@ -0,0 +1,159 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+#include "sidebarinterface.h"
+#include
+#include
+
+class QmlSideBarHelper;
+
+/**
+ * @brief The class exposing SideBar API to QML
+ */
+class QmlSideBar : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+
+ /**
+ * @brief name of the sidebar. This is required property.
+ */
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+
+ /**
+ * @brief title of the sidebar action.
+ */
+ Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
+
+ /**
+ * @brief icon path of the sidebar action.
+ *
+ * The icon path will be search in the following order
+ * - Theme icon: if the icon is found as a theme icon, then it will
+ * be used even if the icon file with same name is present
+ * in the plugin directory
+ * - Falkon resource: for the icons starting with ":", they are searched in
+ * falkon resource file
+ * - Files in plugin directory: All other paths will be resolved relative to
+ * the plugin directory. If the icon path is outside the
+ * plugin directory, then it will be resolved as empty path.
+ */
+ Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
+
+ /**
+ * @brief shortcut for the sidebar action.
+ */
+ Q_PROPERTY(QString shortcut READ shortcut WRITE setShortcut NOTIFY shortcutChanged)
+
+ /**
+ * @brief represents whether the sidebar action is checkable
+ */
+ Q_PROPERTY(bool checkable READ checkable WRITE setCheckable NOTIFY checkableChanged)
+
+ /**
+ * @brief the GUI of the sidebar. This must be provided as QML Window.
+ * This is a default property.
+ */
+ Q_PROPERTY(QQmlComponent* item READ item WRITE setItem NOTIFY itemChanged)
+ Q_CLASSINFO("DefaultProperty", "item")
+
+public:
+ explicit QmlSideBar(QObject *parent = nullptr);
+ ~QmlSideBar() override;
+ void classBegin() override {}
+ void componentComplete() override;
+ QString name() const;
+ SideBarInterface *sideBar() const;
+
+Q_SIGNALS:
+ /**
+ * @brief This signal is emitted when name property is changed.
+ * @param QString represening name
+ */
+ void nameChanged(const QString &name);
+
+ /**
+ * @brief This signal is emitted when title property is changed
+ * @param QString representing title
+ */
+ void titleChanged(const QString &title);
+
+ /**
+ * @brief This signal is emitted when icon property is changed
+ * @param QString representing icon path url
+ */
+ void iconChanged(const QString &icon);
+
+ /**
+ * @brief This signal is emitted when shortcut property is changed
+ * @param QString representing shortcut
+ */
+ void shortcutChanged(const QString &shortcut);
+
+ /**
+ * @brief This signal is emitted when checkable property is changed
+ * @param checkable
+ */
+ void checkableChanged(bool checkable);
+ void itemChanged(QQmlComponent *item);
+
+private:
+ QString m_name;
+ QString m_title;
+ QString m_iconUrl;
+ QString m_shortcut;
+ bool m_checkable = false;
+ QQmlComponent *m_item = nullptr;
+
+ QmlSideBarHelper *m_sideBarHelper = nullptr;
+
+ void setName(const QString &name);
+ QString title() const;
+ void setTitle(const QString &title);
+ QString icon() const;
+ void setIcon(const QString &icon);
+ QString shortcut() const;
+ void setShortcut(const QString &shortcut);
+ bool checkable();
+ void setCheckable(bool checkable);
+ QQmlComponent *item() const;
+ void setItem(QQmlComponent *item);
+};
+
+class QmlSideBarHelper : public SideBarInterface
+{
+ Q_OBJECT
+public:
+ explicit QmlSideBarHelper(QObject *parent = nullptr);
+ QString title() const;
+ QAction *createMenuAction();
+ QWidget *createSideBarWidget(BrowserWindow *mainWindow);
+
+ void setTitle(const QString &title);
+ void setIcon(const QString &icon);
+ void setShortcut(const QString &shortcut);
+ void setCheckable(bool checkable);
+ void setItem(QQmlComponent *item);
+
+private:
+ QString m_title;
+ QString m_iconUrl;
+ QString m_shortcut;
+ bool m_checkable = false;
+ QQmlComponent *m_item = nullptr;
+};
diff --git a/src/lib/plugins/qml/api/sidebar/qmlsidebar.cpp b/src/lib/plugins/qml/api/sidebar/qmlsidebar.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/sidebar/qmlsidebar.cpp
@@ -0,0 +1,186 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlsidebar.h"
+#include "mainapplication.h"
+#include "qztools.h"
+#include "sidebar.h"
+#include "qml/api/fileutils/qmlfileutils.h"
+#include "qml/qmlengine.h"
+#include "qml/qmlstaticdata.h"
+#include
+#include
+#include
+
+QmlSideBar::QmlSideBar(QObject *parent)
+ : QObject(parent)
+{
+ m_sideBarHelper = new QmlSideBarHelper(this);
+
+ connect(this, &QmlSideBar::titleChanged, m_sideBarHelper, &QmlSideBarHelper::setTitle);
+ connect(this, &QmlSideBar::iconChanged, m_sideBarHelper, &QmlSideBarHelper::setIcon);
+ connect(this, &QmlSideBar::shortcutChanged, m_sideBarHelper, &QmlSideBarHelper::setShortcut);
+ connect(this, &QmlSideBar::checkableChanged, m_sideBarHelper, &QmlSideBarHelper::setCheckable);
+ connect(this, &QmlSideBar::itemChanged, m_sideBarHelper, &QmlSideBarHelper::setItem);
+}
+
+QmlSideBar::~QmlSideBar()
+{
+ SideBarManager::removeSidebar(m_sideBarHelper);
+}
+
+void QmlSideBar::componentComplete()
+{
+ SideBarManager::addSidebar(name(), sideBar());
+}
+
+QString QmlSideBar::name() const
+{
+ return m_name;
+}
+
+SideBarInterface *QmlSideBar::sideBar() const
+{
+ return m_sideBarHelper;
+}
+
+void QmlSideBar::setName(const QString &name)
+{
+ m_name = name;
+ emit nameChanged(m_name);
+}
+
+QString QmlSideBar::title() const
+{
+ return m_title;
+}
+
+void QmlSideBar::setTitle(const QString &title)
+{
+ m_title = title;
+ emit titleChanged(title);
+}
+
+QString QmlSideBar::icon() const
+{
+ return m_iconUrl;
+}
+
+void QmlSideBar::setIcon(const QString &icon)
+{
+ m_iconUrl = icon;
+ emit iconChanged(m_iconUrl);
+}
+
+QString QmlSideBar::shortcut() const
+{
+ return m_shortcut;
+}
+
+void QmlSideBar::setShortcut(const QString &shortcut)
+{
+ m_shortcut = shortcut;
+ emit shortcutChanged(m_shortcut);
+}
+
+bool QmlSideBar::checkable()
+{
+ return m_checkable;
+}
+
+void QmlSideBar::setCheckable(bool checkable)
+{
+ m_checkable = checkable;
+ emit checkableChanged(m_checkable);
+}
+
+QQmlComponent *QmlSideBar::item() const
+{
+ return m_item;
+}
+
+void QmlSideBar::setItem(QQmlComponent *item)
+{
+ m_item = item;
+ emit itemChanged(m_item);
+}
+
+QmlSideBarHelper::QmlSideBarHelper(QObject *parent)
+ : SideBarInterface(parent)
+{
+}
+
+QString QmlSideBarHelper::title() const
+{
+ return m_title;
+}
+
+QAction *QmlSideBarHelper::createMenuAction()
+{
+ QAction *action = new QAction(m_title);
+ action->setShortcut(QKeySequence(m_shortcut));
+ action->setCheckable(m_checkable);
+ if (!m_item) {
+ return action;
+ }
+ auto qmlEngine = qobject_cast(m_item->creationContext()->engine());
+ if (qmlEngine) {
+ return action;
+ }
+ const QString pluginPath = qmlEngine->extensionPath();
+ QIcon icon = QmlStaticData::instance().getIcon(m_iconUrl, pluginPath);
+ action->setIcon(icon);
+ return action;
+}
+
+QWidget *QmlSideBarHelper::createSideBarWidget(BrowserWindow *mainWindow)
+{
+ Q_UNUSED(mainWindow)
+
+ QQuickWindow *window = qobject_cast(m_item->create(m_item->creationContext()));
+ if (!window) {
+ qWarning() << "Unable to create QQuickWindow";
+ return nullptr;
+ }
+
+ return QWidget::createWindowContainer(window);
+}
+
+void QmlSideBarHelper::setTitle(const QString &title)
+{
+ m_title = title;
+}
+
+void QmlSideBarHelper::setIcon(const QString &icon)
+{
+ m_iconUrl = icon;
+}
+
+void QmlSideBarHelper::setShortcut(const QString &shortcut)
+{
+ m_shortcut = shortcut;
+}
+
+void QmlSideBarHelper::setCheckable(bool checkable)
+{
+ m_checkable = checkable;
+}
+
+void QmlSideBarHelper::setItem(QQmlComponent *item)
+{
+ m_item = item;
+}
diff --git a/src/lib/plugins/qml/api/tabs/qmltab.h b/src/lib/plugins/qml/api/tabs/qmltab.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/tabs/qmltab.h
@@ -0,0 +1,283 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include
+#include
+
+#include "webtab.h"
+#include "../windows/qmlwindow.h"
+#include "qml/api/menus/qmlwebhittestresult.h"
+
+/**
+ * @brief The class exposing a browser tab to QML
+ */
+class QmlTab : public QObject
+{
+ Q_OBJECT
+
+ /**
+ * @brief url of the tab
+ */
+ Q_PROPERTY(QString url READ url CONSTANT)
+
+ /**
+ * @brief title of the tab
+ */
+ Q_PROPERTY(QString title READ title CONSTANT)
+
+ /**
+ * @brief zoom level of the tab
+ *
+ * Zoom levels are from 0 to 18
+ */
+ Q_PROPERTY(int zoomLevel READ zoomLevel CONSTANT)
+
+ /**
+ * @brief index of the tab
+ */
+ Q_PROPERTY(int index READ index CONSTANT)
+
+ /**
+ * @brief checks if the tab is pinned
+ */
+ Q_PROPERTY(bool pinned READ pinned CONSTANT)
+
+ /**
+ * @brief checks if the tab is muted
+ */
+ Q_PROPERTY(bool muted READ muted CONSTANT)
+
+ /**
+ * @brief checks if the tab is restored
+ */
+ Q_PROPERTY(bool restored READ restored CONSTANT)
+
+ /**
+ * @brief checks if the tab is the current tab
+ */
+ Q_PROPERTY(bool current READ current CONSTANT)
+
+ /**
+ * @brief checks if the tab is playing
+ */
+ Q_PROPERTY(bool playing READ playing CONSTANT)
+
+ /**
+ * @brief window of the tab
+ */
+ Q_PROPERTY(QmlWindow* browserWindow READ browserWindow CONSTANT)
+
+ /**
+ * @brief checks if the tab is loading
+ */
+ Q_PROPERTY(bool loading READ loading CONSTANT)
+
+ /**
+ * @brief get the loading progress of the tab
+ */
+ Q_PROPERTY(int loadingProgress READ loadingProgress CONSTANT)
+
+ /**
+ * @brief checks if the tab has associated background activity
+ */
+ Q_PROPERTY(bool backgroundActivity READ backgroundActivity CONSTANT)
+
+ /**
+ * @brief checks if the tab is can go back
+ */
+ Q_PROPERTY(bool canGoBack READ canGoBack CONSTANT)
+
+ /**
+ * @brief checks if the tab is can go forward
+ */
+ Q_PROPERTY(bool canGoForward READ canGoForward CONSTANT)
+public:
+ explicit QmlTab(WebTab *webTab = nullptr, QObject *parent = nullptr);
+
+ /**
+ * @brief Detaches the tab
+ */
+ Q_INVOKABLE void detach();
+ /**
+ * @brief Set the zoom level of the tab
+ * @param Integer representing the zoom level
+ */
+ Q_INVOKABLE void setZoomLevel(int zoomLevel);
+ /**
+ * @brief Stops webview associated with the tab
+ */
+ Q_INVOKABLE void stop();
+ /**
+ * @brief Reloads webview associated with the tab
+ */
+ Q_INVOKABLE void reload();
+ /**
+ * @brief Unloads the tab
+ */
+ Q_INVOKABLE void unload();
+ /**
+ * @brief Loads webview associated with the tab
+ * @param String representing the url to load
+ */
+ Q_INVOKABLE void load(const QString &url);
+ /**
+ * @brief Decreases the zoom level of the tab
+ */
+ Q_INVOKABLE void zoomIn();
+ /**
+ * @brief Increases the zoom level of the tab
+ */
+ Q_INVOKABLE void zoomOut();
+ /**
+ * @brief Resets the tab zoom level
+ */
+ Q_INVOKABLE void zoomReset();
+ /**
+ * @brief Performs edit undo on the tab
+ */
+ Q_INVOKABLE void undo();
+ /**
+ * @brief Performs edit redo on the tab
+ */
+ Q_INVOKABLE void redo();
+ /**
+ * @brief Performs edit select-all on the tab
+ */
+ Q_INVOKABLE void selectAll();
+ /**
+ * @brief Reloads the tab by bypassing the cache
+ */
+ Q_INVOKABLE void reloadBypassCache();
+ /**
+ * @brief Loads the previous page
+ */
+ Q_INVOKABLE void back();
+ /**
+ * @brief Loads the next page
+ */
+ Q_INVOKABLE void forward();
+ /**
+ * @brief Prints the page
+ */
+ Q_INVOKABLE void printPage();
+ /**
+ * @brief Shows the page source
+ */
+ Q_INVOKABLE void showSource();
+ /**
+ * @brief Sends page by mail
+ */
+ Q_INVOKABLE void sendPageByMail();
+ /**
+ * @brief execute JavaScript function in a page
+ * @param value, representing JavaScript function
+ * @return QVariant, the return value of executed javascript
+ */
+ Q_INVOKABLE QVariant execJavaScript(const QJSValue &value);
+ /**
+ * @brief Gets result of web hit test at a given point
+ * @param point
+ * @return result of web hit test
+ */
+ Q_INVOKABLE QmlWebHitTestResult *hitTestContent(const QPoint &point);
+
+ void setWebPage(WebPage *webPage);
+
+Q_SIGNALS:
+ /**
+ * @brief The signal emitted when the tab title is changed
+ * @param String representing the new title
+ */
+ void titleChanged(const QString &title);
+
+ /**
+ * @brief The signal emitted when pinned state of the tab is changed
+ * @param Bool representing if a tab is pinned
+ */
+ void pinnedChanged(bool pinned);
+
+ /**
+ * @brief The signal emitted when loading state of the tab is changed
+ * @param Bool representing if the tab is loading
+ */
+ void loadingChanged(bool loading);
+
+ /**
+ * @brief The signal emitted when muted state of the tab is changed
+ * @param Bool representing if the tab is muted
+ */
+ void mutedChanged(bool muted);
+
+ /**
+ * @brief The signal emitted when restored state of the tab is changed
+ * @param Bool representing if the tab is restored
+ */
+ void restoredChanged(bool restored);
+
+ /**
+ * @brief The signal emitted when playing state of the tab is changed
+ * @param Bool representing if the tab is in playing state
+ */
+ void playingChanged(bool playing);
+
+ /**
+ * @brief The signal emitted when zoom level of the tab is changed
+ * @param Integer representing the zoom level
+ */
+ void zoomLevelChanged(int zoomLevel);
+
+ /**
+ * @brief The signal emitted when background activity of the tab is changed
+ * @param Bool representing if there is background activity attached to the tab
+ */
+ void backgroundActivityChanged(int backgroundActivityChanged);
+
+ /**
+ * @brief The signal emitted when navigation request is accepted
+ * @param url, representing requested url
+ * @param type of navigation
+ * @param isMainFrame, represents if navigation is requested for a top level page.
+ */
+ void navigationRequestAccepted(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame);
+
+private:
+ WebTab *m_webTab = nullptr;
+ WebPage *m_webPage = nullptr;
+ QList m_lambdaConnections;
+
+ QString url() const;
+ QString title() const;
+ int zoomLevel() const;
+ int index() const;
+ bool pinned() const;
+ bool muted() const;
+ bool restored() const;
+ bool current() const;
+ bool playing() const;
+ QmlWindow *browserWindow() const;
+ bool loading() const;
+ int loadingProgress() const;
+ bool backgroundActivity() const;
+ bool canGoBack() const;
+ bool canGoForward() const;
+
+ void createConnections();
+ void removeConnections();
+};
diff --git a/src/lib/plugins/qml/api/tabs/qmltab.cpp b/src/lib/plugins/qml/api/tabs/qmltab.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/tabs/qmltab.cpp
@@ -0,0 +1,422 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmltab.h"
+#include "loadrequest.h"
+#include "tabbedwebview.h"
+#include "webpage.h"
+#include "qml/qmlstaticdata.h"
+#include
+#include
+
+QmlTab::QmlTab(WebTab *webTab, QObject *parent)
+ : QObject(parent)
+ , m_webTab(webTab)
+{
+ QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
+
+ if (!m_webTab) {
+ return;
+ }
+
+ createConnections();
+}
+
+void QmlTab::detach()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->detach();
+}
+
+void QmlTab::setZoomLevel(int zoomLevel)
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->setZoomLevel(zoomLevel);
+}
+
+void QmlTab::stop()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->stop();
+}
+
+void QmlTab::reload()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->reload();
+}
+
+void QmlTab::unload()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->unload();
+}
+
+void QmlTab::load(const QString &url)
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ LoadRequest req;
+ req.setUrl(QUrl::fromEncoded(url.toUtf8()));
+ m_webTab->load(req);
+}
+
+void QmlTab::zoomIn()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->zoomIn();
+}
+
+void QmlTab::zoomOut()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->zoomOut();
+}
+
+void QmlTab::zoomReset()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->zoomReset();
+}
+
+void QmlTab::undo()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->editUndo();
+}
+
+void QmlTab::redo()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->editRedo();
+}
+
+void QmlTab::selectAll()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->editSelectAll();
+}
+
+void QmlTab::reloadBypassCache()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->reloadBypassCache();
+}
+
+void QmlTab::back()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->back();
+}
+
+void QmlTab::forward()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->forward();
+}
+
+void QmlTab::printPage()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->printPage();
+}
+
+void QmlTab::showSource()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->showSource();
+}
+
+void QmlTab::sendPageByMail()
+{
+ if (!m_webTab) {
+ return;
+ }
+
+ m_webTab->webView()->sendPageByMail();
+}
+
+QVariant QmlTab::execJavaScript(const QJSValue &value)
+{
+ if (!m_webPage && !m_webTab) {
+ return QVariant();
+ }
+ WebPage *webPage = m_webPage;
+ if (!m_webPage) {
+ webPage = m_webTab->webView()->page();
+ }
+ return webPage->execJavaScript(value.toString());
+}
+
+QmlWebHitTestResult *QmlTab::hitTestContent(const QPoint &point)
+{
+ if (!m_webPage && !m_webTab) {
+ return nullptr;
+ }
+ WebPage *webPage = m_webPage;
+ if (!m_webPage) {
+ webPage = m_webTab->webView()->page();
+ }
+ WebHitTestResult result = webPage->hitTestContent(point);
+ return new QmlWebHitTestResult(result);
+}
+
+QString QmlTab::url() const
+{
+ if (!m_webTab) {
+ return QString();
+ }
+
+ return QString::fromUtf8(m_webTab->url().toEncoded());
+}
+
+QString QmlTab::title() const
+{
+ if (!m_webTab) {
+ return QString();
+ }
+
+ return m_webTab->title();
+}
+
+
+int QmlTab::zoomLevel() const
+{
+ if (!m_webTab) {
+ return -1;
+ }
+
+ return m_webTab->zoomLevel();
+}
+
+int QmlTab::index() const
+{
+ if (!m_webTab) {
+ return -1;
+ }
+
+ return m_webTab->tabIndex();
+}
+
+bool QmlTab::pinned() const
+{
+ if (!m_webTab) {
+ return false;
+ }
+
+ return m_webTab->isPinned();
+}
+
+bool QmlTab::muted() const
+{
+ if (!m_webTab) {
+ return false;
+ }
+
+ return m_webTab->isMuted();
+}
+
+bool QmlTab::restored() const
+{
+ if (!m_webTab) {
+ return false;
+ }
+
+ return m_webTab->isRestored();
+}
+
+bool QmlTab::current() const
+{
+ if (!m_webTab) {
+ return false;
+ }
+
+ return m_webTab->isCurrentTab();
+}
+
+bool QmlTab::playing() const
+{
+ if (!m_webTab) {
+ return false;
+ }
+
+ return m_webTab->isPlaying();
+}
+
+QmlWindow *QmlTab::browserWindow() const
+{
+ if (!m_webTab) {
+ return nullptr;
+ }
+
+ return QmlStaticData::instance().getWindow(m_webTab->browserWindow());
+}
+
+bool QmlTab::loading() const
+{
+ if (!m_webTab) {
+ return false;
+ }
+
+ return m_webTab->webView()->isLoading();
+}
+
+int QmlTab::loadingProgress() const
+{
+ if (!m_webTab) {
+ return -1;
+ }
+
+ return m_webTab->webView()->loadingProgress();
+}
+
+bool QmlTab::backgroundActivity() const
+{
+ if (!m_webTab) {
+ return false;
+ }
+
+ return m_webTab->webView()->backgroundActivity();
+}
+
+bool QmlTab::canGoBack() const
+{
+ if (!m_webTab) {
+ return false;
+ }
+
+ return m_webTab->webView()->history()->canGoBack();
+}
+
+bool QmlTab::canGoForward() const
+{
+ if (!m_webTab) {
+ return false;
+ }
+
+ return m_webTab->webView()->history()->canGoForward();
+}
+
+void QmlTab::setWebPage(WebPage *webPage)
+{
+ if (m_webPage) {
+ removeConnections();
+ }
+ m_webPage = webPage;
+ TabbedWebView *tabbedWebView = qobject_cast(m_webPage->view());
+ m_webTab = tabbedWebView->webTab();
+ if (m_webTab) {
+ createConnections();
+ }
+}
+
+void QmlTab::createConnections()
+{
+ Q_ASSERT(m_lambdaConnections.length() == 0);
+
+ auto titleChangedConnection = connect(m_webTab, &WebTab::titleChanged, this, [this](const QString &title){
+ emit titleChanged(title);
+ });
+ m_lambdaConnections.append(titleChangedConnection);
+
+ auto pinnedChangedConnection = connect(m_webTab, &WebTab::pinnedChanged, this, [this](bool pinned){
+ emit pinnedChanged(pinned);
+ });
+ m_lambdaConnections.append(pinnedChangedConnection);
+
+ auto loadingChangedConnection = connect(m_webTab, &WebTab::loadingChanged, this, [this](bool loading){
+ emit loadingChanged(loading);
+ });
+ m_lambdaConnections.append(loadingChangedConnection);
+
+ auto mutedChangedConnection = connect(m_webTab, &WebTab::mutedChanged, this, [this](bool muted){
+ emit mutedChanged(muted);
+ });
+ m_lambdaConnections.append(mutedChangedConnection);
+
+ auto restoredChangedConnection = connect(m_webTab, &WebTab::restoredChanged, this, [this](bool restored){
+ emit restoredChanged(restored);
+ });
+ m_lambdaConnections.append(restoredChangedConnection);
+
+ auto playingChangedConnection = connect(m_webTab, &WebTab::playingChanged, this, [this](bool playing){
+ emit playingChanged(playing);
+ });
+ m_lambdaConnections.append(playingChangedConnection);
+
+ connect(m_webTab->webView(), &TabbedWebView::zoomLevelChanged, this, &QmlTab::zoomLevelChanged);
+ connect(m_webTab->webView(), &TabbedWebView::backgroundActivityChanged, this, &QmlTab::backgroundActivityChanged);
+
+ if (m_webPage) {
+ connect(m_webPage, &WebPage::navigationRequestAccepted, this, &QmlTab::navigationRequestAccepted);
+ }
+}
+
+void QmlTab::removeConnections()
+{
+ disconnect(this);
+}
diff --git a/src/lib/plugins/qml/api/tabs/qmltabs.h b/src/lib/plugins/qml/api/tabs/qmltabs.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/tabs/qmltabs.h
@@ -0,0 +1,233 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include "mainapplication.h"
+#include "qmltab.h"
+
+/**
+ * @brief The class exposing Tabs API to QML
+ */
+class QmlTabs : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlTabs(QObject *parent = nullptr);
+ /**
+ * @brief Sets the current tab in a window
+ * @param A JavaScript object containing
+ * - index:
+ * Integer representing new current index
+ * - windowId:
+ * The id of window containing the tab
+ * @return True if success, else false
+ */
+ Q_INVOKABLE bool setCurrentIndex(const QVariantMap &map);
+ /**
+ * @brief Sets the next tab as current tab
+ * @param Integer representing the window
+ * @return True if success, else false
+ */
+ Q_INVOKABLE bool nextTab(int windowId = -1);
+ /**
+ * @brief Sets the prvious tab as current tab
+ * @param Integer representing the window
+ * @return True if success, else false
+ */
+ Q_INVOKABLE bool previousTab(int windowId = -1);
+ /**
+ * @brief Moves a tab
+ * @param A JavaScript object containing
+ * - from:
+ * The initial index of the tab
+ * - to:
+ * The final index of the tab
+ * - windowId:
+ * The id of window containing the tab
+ * @return True if tab is moved, else false
+ */
+ Q_INVOKABLE bool moveTab(const QVariantMap &map);
+ /**
+ * @brief Pins a tab
+ * @param A JavaScript object containing
+ * - index:
+ * Integer representing the tab to be pinned
+ * - windowId:
+ * The id of window containing the tab
+ * @return True if success, else false
+ */
+ Q_INVOKABLE bool pinTab(const QVariantMap &map);
+ /**
+ * @brief Un-pins a tab
+ * @param A JavaScript object containing
+ * - index:
+ * Integer representing the tab to be unpinned
+ * - windowId:
+ * The id of window containing the tab
+ * @return True if success, else false
+ */
+ Q_INVOKABLE bool unpinTab(const QVariantMap &map);
+ /**
+ * @brief Detaches a tab
+ * @param A JavaScript object containing
+ * - index:
+ * Integer representing the tab to be detached
+ * - windowId:
+ * The id of window containing the tab
+ * @return True if tab is detached, else false
+ */
+ Q_INVOKABLE bool detachTab(const QVariantMap &map);
+ /**
+ * @brief Duplicates a tab
+ * @param A JavaScript object containing
+ * - index:
+ * Integer representing the tab to duplicate
+ * - windowId:
+ * The id of window containing the tab
+ * @return True if success, else false
+ */
+ Q_INVOKABLE bool duplicate(const QVariantMap &map);
+ /**
+ * @brief Close a tab
+ * @param A JavaScript object containing
+ * - index:
+ * Integer representing the tab to be closed
+ * - windowId:
+ * The id of window containing the tab
+ * @return True if success, else false
+ */
+ Q_INVOKABLE bool closeTab(const QVariantMap &map);
+ /**
+ * @brief Reloads a tab
+ * @param A JavaScript object containing
+ * - index:
+ * Integer representing the tab to be reloaded
+ * - windowId:
+ * The id of window containing the tab
+ * @return True if success, else false
+ */
+ Q_INVOKABLE bool reloadTab(const QVariantMap &map);
+ /**
+ * @brief Stops a tab
+ * @param A JavaScript object containing
+ * - index:
+ * Integer representing the tab to be stoped
+ * - windowId:
+ * The id of window containing the tab
+ * @return True if success, else false
+ */
+ Q_INVOKABLE bool stopTab(const QVariantMap &map);
+ /**
+ * @brief Gets a tab
+ * @param A JavaScript object contining
+ * - index:
+ * Integer representign the index of the tab
+ * - windowId:
+ * The id of window containing the tab
+ * @return Tab of type [QmlTab](@ref QmlTab) if exists, else null
+ */
+ Q_INVOKABLE QmlTab *get(const QVariantMap &map) const;
+ /**
+ * @brief Get the normal tabs count in a window
+ * @param Integer representing the window
+ * @return Number of normal tabs in the window
+ */
+ Q_INVOKABLE int normalTabsCount(int windowId = -1) const;
+ /**
+ * @brief Get the pinned tabs count in a window
+ * @param Integer representing the window
+ * @return Number of pinned tabs in the window
+ */
+ Q_INVOKABLE int pinnedTabsCount(int windowId = -1) const;
+ /**
+ * @brief Gets all the tabs of a window
+ * @param A JavaScript object containing
+ * - windowId:
+ * The id of window containing the tab
+ * - withPinned:
+ * Bool representing if the searched tab can be pinned
+ * @return List of tabs, each of type [QmlTab](@ref QmlTab)
+ */
+ Q_INVOKABLE QList getAll(const QVariantMap &map = QVariantMap()) const;
+ /**
+ * @brief Searches tabs against a criteria
+ * @param A JavaScript object containing
+ * - title:
+ * String representing the title to be searched
+ * - url:
+ * String representing the url to be searched
+ * - withPinned:
+ * Bool representing if the searched tab can be pinned
+ * @return List of tabs, each of type [QmlTab](@ref QmlTab), which are
+ * matched against the criteria
+ */
+ Q_INVOKABLE QList search(const QVariantMap &map);
+ /**
+ * @brief Adds a tab
+ * @param A JavaScript object containing
+ * - url:
+ * String representing the url of the tab
+ * - windowId:
+ * The id of window containing the tab
+ * @return True if the tab is added, else false
+ */
+ Q_INVOKABLE bool addTab(const QVariantMap &map);
+Q_SIGNALS:
+ /**
+ * @brief The signal emitted when tabs in the tab widget are changed
+ * @param window id representing the window in which the change occurs
+ */
+ void changed(int windowId);
+
+ /**
+ * @brief The signal emitted when a tab is inserted
+ * @param A JavaScript object containing
+ * - index:
+ * The index of the inserted tab
+ * - windowId:
+ * The id of window in which the tab is inserted
+ */
+ void tabInserted(const QVariantMap &map);
+
+ /**
+ * @brief The signal emitted when a tab is removed
+ * @param A JavaScript object containing
+ * - index:
+ * The index of the removed tab
+ * - windowId:
+ * The id of window in which the tab is removed
+ */
+ void tabRemoved(const QVariantMap &map);
+
+ /**
+ * @brief The signal emitted when a tab is moved
+ * @param A JavaScript object containing
+ * - from:
+ * The initial index of the moved tab
+ * - to:
+ * The final index of the moved tab
+ * - windowId:
+ * The id of window in which the tab is moved
+ */
+ void tabMoved(const QVariantMap &map);
+private:
+ BrowserWindow *getWindow(const QVariantMap &map) const;
+ BrowserWindow *getWindow(int windowId) const;
+ void windowCreated(BrowserWindow *window);
+};
diff --git a/src/lib/plugins/qml/api/tabs/qmltabs.cpp b/src/lib/plugins/qml/api/tabs/qmltabs.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/tabs/qmltabs.cpp
@@ -0,0 +1,363 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmltabs.h"
+#include "tabwidget.h"
+#include "pluginproxy.h"
+#include "qml/qmlstaticdata.h"
+#include
+
+QmlTabs::QmlTabs(QObject *parent)
+ : QObject(parent)
+{
+ const QList windows = mApp->windows();
+ for (BrowserWindow *window : windows) {
+ windowCreated(window);
+ }
+
+ connect(mApp->plugins(), &PluginProxy::mainWindowCreated, this, &QmlTabs::windowCreated);
+}
+
+bool QmlTabs::setCurrentIndex(const QVariantMap &map)
+{
+ if (!map.contains(QSL("index"))) {
+ qWarning() << "Unable to set current index:" << "index not defined";
+ return false;
+ }
+
+ const int index = map.value(QSL("index")).toInt();
+
+ const auto window = getWindow(map);
+ if (!window) {
+ return false;
+ }
+ window->tabWidget()->setCurrentIndex(index);
+ return true;
+}
+
+bool QmlTabs::nextTab(int windowId)
+{
+ const auto window = getWindow(windowId);
+ if (!window) {
+ return false;
+ }
+ window->tabWidget()->nextTab();
+ return true;
+}
+
+bool QmlTabs::previousTab(int windowId)
+{
+ const auto window = getWindow(windowId);
+ if (!window) {
+ return false;
+ }
+ window->tabWidget()->previousTab();
+ return true;
+}
+
+bool QmlTabs::moveTab(const QVariantMap &map)
+{
+ if (!map.contains(QSL("from"))) {
+ qWarning() << "Unable to move tab:" << "from not defined";
+ return false;
+ }
+ if (!map.contains(QSL("to"))) {
+ qWarning() << "Unable to move tab:" << "to not defined";
+ return false;
+ }
+
+ const int from = map.value(QSL("from")).toInt();
+ const int to = map.value(QSL("to")).toInt();
+
+ const auto window = getWindow(map);
+ if (!window) {
+ return false;
+ }
+ window->tabWidget()->moveTab(from, to);
+ return true;
+}
+
+bool QmlTabs::pinTab(const QVariantMap &map)
+{
+ if (!map.contains(QSL("index"))) {
+ qWarning() << "Unable to pin tab:" << "index not defined";
+ return false;
+ }
+
+ const int index = map.value(QSL("index")).toInt();
+
+ const auto window = getWindow(map);
+ if (!window) {
+ return false;
+ }
+
+ WebTab *webTab = window->tabWidget()->webTab(index);
+
+ if (webTab->isPinned()) {
+ return false;
+ }
+
+ webTab->togglePinned();
+ return true;
+}
+
+bool QmlTabs::unpinTab(const QVariantMap &map)
+{
+ if (!map.contains(QSL("index"))) {
+ qWarning() << "Unable to unpin tab:" << "index not defined";
+ return false;
+ }
+
+ const int index = map.value(QSL("index")).toInt();
+
+ const auto window = getWindow(map);
+ if (!window) {
+ return false;
+ }
+
+ WebTab *webTab = window->tabWidget()->webTab(index);
+
+ if (!webTab->isPinned()) {
+ return false;
+ }
+
+ webTab->togglePinned();
+ return true;
+}
+
+bool QmlTabs::detachTab(const QVariantMap &map)
+{
+ if (!map.contains(QSL("index"))) {
+ qWarning() << "Unable to detatch tab:" << "index not defined";
+ return false;
+ }
+
+ const int index = map.value(QSL("index")).toInt();
+
+ const auto window = getWindow(map);
+ if (!window) {
+ return false;
+ }
+ window->tabWidget()->detachTab(index);
+ return true;
+}
+
+bool QmlTabs::duplicate(const QVariantMap &map)
+{
+ if (!map.contains(QSL("index"))) {
+ qWarning() << "Unable to duplicate:" << "index not defined";
+ return false;
+ }
+
+ const int index = map.value(QSL("index")).toInt();
+
+ const auto window = getWindow(map);
+ if (!window) {
+ return false;
+ }
+ window->tabWidget()->duplicateTab(index);
+ return true;
+}
+
+bool QmlTabs::closeTab(const QVariantMap &map)
+{
+ if (!map.contains(QSL("index"))) {
+ qWarning() << "Unable to close tab:" << "index not defined";
+ return false;
+ }
+
+ const int index = map.value(QSL("index")).toInt();
+
+ const auto window = getWindow(map);
+ if (!window) {
+ return false;
+ }
+ window->tabWidget()->closeTab(index);
+ return true;
+}
+
+bool QmlTabs::reloadTab(const QVariantMap &map)
+{
+ if (!map.contains(QSL("index"))) {
+ qWarning() << "Unable to reload tab:" << "index not defined";
+ return false;
+ }
+
+ const int index = map.value(QSL("index")).toInt();
+
+ const auto window = getWindow(map);
+ if (!window) {
+ return false;
+ }
+ window->tabWidget()->reloadTab(index);
+ return true;
+}
+
+bool QmlTabs::stopTab(const QVariantMap &map)
+{
+ if (!map.contains(QSL("index"))) {
+ qWarning() << "Unable to close tab:" << "index not defined";
+ return false;
+ }
+
+ const int index = map.value(QSL("index")).toInt();
+
+ const auto window = getWindow(map);
+ if (!window) {
+ return false;
+ }
+ window->tabWidget()->stopTab(index);
+ return true;
+}
+
+QmlTab *QmlTabs::get(const QVariantMap &map) const
+{
+ if (!map.contains(QSL("index"))) {
+ qWarning() << "Unable to set current index:" << "index not defined";
+ return nullptr;
+ }
+
+ const int index = map.value(QSL("index")).toInt();
+
+ const auto window = getWindow(map);
+ if (!window) {
+ return nullptr;
+ }
+ const auto webTab = window->tabWidget()->webTab(index);
+ return QmlStaticData::instance().getTab(webTab);
+}
+
+int QmlTabs::normalTabsCount(int windowId) const
+{
+ const auto window = getWindow(windowId);
+ if (!window) {
+ return -1;
+ }
+ return window->tabWidget()->normalTabsCount();
+}
+
+int QmlTabs::pinnedTabsCount(int windowId) const
+{
+ const auto window = getWindow(windowId);
+ if (!window) {
+ return -1;
+ }
+ return window->tabWidget()->pinnedTabsCount();
+}
+
+QList QmlTabs::getAll(const QVariantMap &map) const
+{
+ const auto window = getWindow(map);
+ if (!window) {
+ return QList();
+ }
+
+ const bool withPinned = map.value(QSL("withPinned")).toBool();
+ const QList tabList = window->tabWidget()->allTabs(withPinned);
+
+ QList list;
+ list.reserve(tabList.size());
+ for (WebTab *tab : tabList) {
+ list.append(QmlStaticData::instance().getTab(tab));
+ }
+
+ return list;
+}
+
+QList QmlTabs::search(const QVariantMap &map)
+{
+ const QString title = map.value(QSL("title")).toString();
+ const QString url = map.value(QSL("url")).toString();
+ const bool withPinned = map.value(QSL("withPinned")).toBool();
+ QList list;
+ foreach (BrowserWindow *window, mApp->windows()) {
+ foreach (WebTab *webTab, window->tabWidget()->allTabs(withPinned)) {
+ if (webTab->title().contains(title, Qt::CaseInsensitive)
+ || QString::fromUtf8(webTab->url().toEncoded()).contains(url, Qt::CaseInsensitive)) {
+ list.append(QmlStaticData::instance().getTab(webTab));
+ }
+ }
+ }
+ return list;
+}
+
+bool QmlTabs::addTab(const QVariantMap &map)
+{
+ const QString urlString = map.value(QSL("url")).toString();
+ const auto window = getWindow(map);
+ if (!window) {
+ qDebug() << "Unable to add tab:" << "window not found";
+ return false;
+ }
+ LoadRequest req(QUrl::fromEncoded(urlString.toUtf8()));
+ const int ret = window->tabWidget()->addView(req);
+ return ret != -1 ? true : false;
+}
+
+BrowserWindow *QmlTabs::getWindow(const QVariantMap &map) const
+{
+ const int windowId = map.value(QSL("windowId"), -1).toInt();
+ return getWindow(windowId);
+}
+
+BrowserWindow *QmlTabs::getWindow(int windowId) const
+{
+ if (windowId == -1) {
+ return mApp->getWindow();
+ }
+
+ auto windowIdHash = QmlStaticData::instance().windowIdHash();
+ for (auto it = windowIdHash.cbegin(); it != windowIdHash.cend(); it++) {
+ BrowserWindow *window = it.key();
+ if (QmlStaticData::instance().windowIdHash().value(window, -1) == windowId) {
+ return window;
+ }
+ }
+ qWarning() << "Unable to get window with given windowId";
+ return nullptr;
+}
+
+void QmlTabs::windowCreated(BrowserWindow *window)
+{
+ const int windowId = QmlStaticData::instance().windowIdHash().value(window, -1);
+
+ connect(window->tabWidget(), &TabWidget::changed, this, [this, windowId]{
+ emit changed(windowId);
+ });
+
+ connect(window->tabWidget(), &TabWidget::tabInserted, this, [this, windowId](int index){
+ QVariantMap map;
+ map.insert(QSL("windowId"), windowId);
+ map.insert(QSL("index"), index);
+ emit tabInserted(map);
+ });
+
+ connect(window->tabWidget(), &TabWidget::tabRemoved, this, [this, windowId](int index){
+ QVariantMap map;
+ map.insert(QSL("windowId"), windowId);
+ map.insert(QSL("index"), index);
+ emit tabRemoved(map);
+ });
+
+ connect(window->tabWidget(), &TabWidget::tabMoved, this, [this, windowId](int from, int to){
+ QVariantMap map;
+ map.insert(QSL("windowId"), windowId);
+ map.insert(QSL("from"), from);
+ map.insert(QSL("to"), to);
+ emit tabMoved(map);
+ });
+}
diff --git a/src/lib/plugins/qml/api/topsites/qmlmostvisitedurl.h b/src/lib/plugins/qml/api/topsites/qmlmostvisitedurl.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/topsites/qmlmostvisitedurl.h
@@ -0,0 +1,49 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include
+#include
+
+/**
+ * @brief The class exposing MostVisitedUrl type to QML
+ */
+class QmlMostVisitedUrl : public QObject
+{
+ Q_OBJECT
+
+ /**
+ * @brief title of "most visited url" item
+ */
+ Q_PROPERTY(QString title READ title CONSTANT)
+
+ /**
+ * @brief url of "most visited url" item
+ */
+ Q_PROPERTY(QString url READ url CONSTANT)
+public:
+ explicit QmlMostVisitedUrl(const QString &title = QString(), const QString &url = QString(), QObject *parent = nullptr);
+
+private:
+ QString m_title;
+ QString m_url;
+
+ QString title() const;
+ QString url() const;
+};
diff --git a/src/lib/plugins/qml/api/topsites/qmlmostvisitedurl.cpp b/src/lib/plugins/qml/api/topsites/qmlmostvisitedurl.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/topsites/qmlmostvisitedurl.cpp
@@ -0,0 +1,37 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlmostvisitedurl.h"
+#include
+
+QmlMostVisitedUrl::QmlMostVisitedUrl(const QString &title, const QString &url, QObject *parent)
+ : QObject(parent)
+ , m_title(title)
+ , m_url(url)
+{
+ QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
+}
+
+QString QmlMostVisitedUrl::title() const
+{
+ return m_title;
+}
+
+QString QmlMostVisitedUrl::url() const
+{
+ return m_url;
+}
diff --git a/src/lib/plugins/qml/api/topsites/qmltopsites.h b/src/lib/plugins/qml/api/topsites/qmltopsites.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/topsites/qmltopsites.h
@@ -0,0 +1,37 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include "qmlmostvisitedurl.h"
+
+/**
+ * @brief The class exposing TopSites API to QML
+ */
+class QmlTopSites : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlTopSites(QObject *parent = nullptr);
+ /**
+ * @brief Get the topsites. These refer to the sites which
+ * are displayed in the speed-dial (New tab page)
+ * @return List of MostVisitedUrl objects of type [QmlMostVisitedUrl](@ref QmlMostVisitedUrl)
+ */
+ Q_INVOKABLE QList get() const;
+};
diff --git a/src/lib/plugins/qml/api/topsites/qmltopsites.cpp b/src/lib/plugins/qml/api/topsites/qmltopsites.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/topsites/qmltopsites.cpp
@@ -0,0 +1,40 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmltopsites.h"
+#include "speeddial.h"
+#include "mainapplication.h"
+#include "pluginproxy.h"
+#include "qml/qmlstaticdata.h"
+#include
+
+QmlTopSites::QmlTopSites(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QList QmlTopSites::get() const
+{
+ const QList pages = mApp->plugins()->speedDial()->pages();
+ QList list;
+ list.reserve(pages.size());
+ for(const SpeedDial::Page &page : pages) {
+ auto mostVisitedUrl = QmlStaticData::instance().getMostVisitedUrl(page.title, page.url);
+ list.append(mostVisitedUrl);
+ }
+ return list;
+}
diff --git a/src/lib/plugins/qml/api/userscript/qmlexternaljsobject.h b/src/lib/plugins/qml/api/userscript/qmlexternaljsobject.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/userscript/qmlexternaljsobject.h
@@ -0,0 +1,32 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+
+class QmlExternalJsObject : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QmlExternalJsObject(QObject *parent = nullptr);
+ ~QmlExternalJsObject();
+ Q_INVOKABLE void registerExtraObject(const QVariantMap &map);
+ Q_INVOKABLE void unregisterExtraObject(QObject *object);
+private:
+ QList m_objects;
+};
diff --git a/src/lib/plugins/qml/api/userscript/qmlexternaljsobject.cpp b/src/lib/plugins/qml/api/userscript/qmlexternaljsobject.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/userscript/qmlexternaljsobject.cpp
@@ -0,0 +1,54 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlexternaljsobject.h"
+#include "javascript/externaljsobject.h"
+#include
+
+QmlExternalJsObject::QmlExternalJsObject(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QmlExternalJsObject::~QmlExternalJsObject()
+{
+ for (QObject *object : qAsConst(m_objects)) {
+ ExternalJsObject::unregisterExtraObject(object);
+ }
+}
+
+void QmlExternalJsObject::registerExtraObject(const QVariantMap &map)
+{
+ if (!map.contains(QSL("id")) || !map.contains(QSL("object"))) {
+ qWarning() << "Unable to call" << __FUNCTION__ << ": unsufficient parameters";
+ return;
+ }
+
+ const QString id = map.value(QSL("id")).toString();
+ QObject *object = qvariant_cast(map.value(QSL("object")));
+ if (!object) {
+ qWarning() << "Unable to cast to QObject";
+ return;
+ }
+ ExternalJsObject::registerExtraObject(id, object);
+ m_objects.append(object);
+}
+
+void QmlExternalJsObject::unregisterExtraObject(QObject *object)
+{
+ ExternalJsObject::unregisterExtraObject(object);
+}
diff --git a/src/lib/plugins/qml/api/userscript/qmluserscript.h b/src/lib/plugins/qml/api/userscript/qmluserscript.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/userscript/qmluserscript.h
@@ -0,0 +1,113 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include "qzcommon.h"
+
+#include
+#include
+
+/**
+ * @brief The class exposing QWebEngineScript to QML
+ */
+class FALKON_EXPORT QmlUserScript : public QObject
+{
+ Q_OBJECT
+ /**
+ * @brief Checks if the UserScript is null
+ */
+ Q_PROPERTY(bool null READ null CONSTANT)
+ /**
+ * @brief Name of the UserScript
+ */
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ /**
+ * @brief Checks if the UserScript runs on sub frames
+ */
+ Q_PROPERTY(bool runsOnSubFrames READ runsOnSubFrames WRITE setRunsOnSubFrames NOTIFY runsOnSubFramesChanged)
+ /**
+ * @brief WorldId of the UserScript
+ */
+ Q_PROPERTY(int worldId READ worldId WRITE setWorldId NOTIFY worldIdChanged)
+ /**
+ * @brief Source code of the UserScript
+ */
+ Q_PROPERTY(QString sourceCode READ sourceCode WRITE setSourceCode NOTIFY sourceCodeChanged)
+ /**
+ * @brief Injection point of the UserScript
+ */
+ Q_PROPERTY(InjectionPoint injectionPoint READ injectionPoint WRITE setInjectionPoint NOTIFY injectionPointChanged)
+public:
+ /**
+ * @brief The enum exposing QWebEngineScript::InjectionPoint
+ */
+ enum InjectionPoint {
+ DocumentCreation = QWebEngineScript::DocumentCreation, //!< Represents QWebEngineScript::DocumentCreation
+ DocumentReady = QWebEngineScript::DocumentReady, //!< Represents QWebEngineScript::DocumentReady,
+ Deferred = QWebEngineScript::Deferred //!< Represents QWebEngineScript::Deferred
+ };
+ /**
+ * @brief The enum wrapping QWebEngineScript::ScriptWorldId
+ */
+ enum ScriptWorldId {
+ MainWorld = QWebEngineScript::MainWorld, //!< Represents QWebEngineScript::MainWorld
+ ApplicationWorld = QWebEngineScript::ApplicationWorld, //!< Represents QWebEngineScript::ApplicationWorld
+ UserWorld = QWebEngineScript::UserWorld //! < Represents QWebEngineScript::UserWorld
+ };
+ Q_ENUM(InjectionPoint)
+ Q_ENUM(ScriptWorldId)
+
+ explicit QmlUserScript(QObject *parent = nullptr);
+ QWebEngineScript webEngineScript() const;
+ void setWebEngineScript(const QWebEngineScript &script);
+Q_SIGNALS:
+ /**
+ * @brief The signal emitted when the script name is changed
+ */
+ void nameChanged(const QString &name);
+ /**
+ * @brief The signal emitted when runsOnSubFrame property of the script is changed
+ */
+ void runsOnSubFramesChanged(bool runsOnSubFrames);
+ /**
+ * @brief The signal emitted when worldId property of the script is changed
+ */
+ void worldIdChanged(int worldId);
+ /**
+ * @brief The signal emitted when source code of the script is changed
+ */
+ void sourceCodeChanged(const QString &sourceCode);
+ /**
+ * @brief The signal emitted when injectionPoint property of the script is changed
+ */
+ void injectionPointChanged(int injectionPoint);
+private:
+ QWebEngineScript m_webEngineScript;
+
+ bool null() const;
+ QString name() const;
+ void setName(const QString &name);
+ bool runsOnSubFrames() const;
+ void setRunsOnSubFrames(bool runsOnSubFrames);
+ int worldId() const;
+ void setWorldId(int worldId);
+ QString sourceCode() const;
+ void setSourceCode(const QString &sourceCode);
+ InjectionPoint injectionPoint() const;
+ void setInjectionPoint(InjectionPoint injectionPoint);
+};
diff --git a/src/lib/plugins/qml/api/userscript/qmluserscript.cpp b/src/lib/plugins/qml/api/userscript/qmluserscript.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/userscript/qmluserscript.cpp
@@ -0,0 +1,117 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmluserscript.h"
+
+QmlUserScript::QmlUserScript(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QWebEngineScript QmlUserScript::webEngineScript() const
+{
+ return m_webEngineScript;
+}
+
+void QmlUserScript::setWebEngineScript(const QWebEngineScript &script)
+{
+ m_webEngineScript = script;
+}
+
+bool QmlUserScript::null() const
+{
+ return m_webEngineScript.isNull();
+}
+
+QString QmlUserScript::name() const
+{
+ return m_webEngineScript.name();
+}
+
+void QmlUserScript::setName(const QString &name)
+{
+ m_webEngineScript.setName(name);
+ emit nameChanged(name);
+}
+
+bool QmlUserScript::runsOnSubFrames() const
+{
+ return m_webEngineScript.runsOnSubFrames();
+}
+
+void QmlUserScript::setRunsOnSubFrames(bool runsOnSubFrames)
+{
+ m_webEngineScript.setRunsOnSubFrames(runsOnSubFrames);
+ emit runsOnSubFramesChanged(runsOnSubFrames);
+}
+
+int QmlUserScript::worldId() const
+{
+ return static_cast(m_webEngineScript.worldId());
+}
+
+void QmlUserScript::setWorldId(int worldId)
+{
+ switch (worldId) {
+ case QWebEngineScript::MainWorld:
+ m_webEngineScript.setWorldId(QWebEngineScript::MainWorld);
+ break;
+ case QWebEngineScript::ApplicationWorld:
+ m_webEngineScript.setWorldId(QWebEngineScript::ApplicationWorld);
+ break;
+ case QWebEngineScript::UserWorld:
+ m_webEngineScript.setWorldId(QWebEngineScript::UserWorld);
+ break;
+ default:
+ break;
+ }
+ emit worldIdChanged(worldId);
+}
+
+QString QmlUserScript::sourceCode() const
+{
+ return m_webEngineScript.sourceCode();
+}
+
+void QmlUserScript::setSourceCode(const QString &sourceCode)
+{
+ m_webEngineScript.setSourceCode(sourceCode);
+ emit sourceCodeChanged(sourceCode);
+}
+
+QmlUserScript::InjectionPoint QmlUserScript::injectionPoint() const
+{
+ return (InjectionPoint)m_webEngineScript.injectionPoint();
+}
+
+void QmlUserScript::setInjectionPoint(InjectionPoint injectionPoint)
+{
+ switch (injectionPoint) {
+ case QWebEngineScript::DocumentCreation:
+ m_webEngineScript.setInjectionPoint(QWebEngineScript::DocumentCreation);
+ break;
+ case QWebEngineScript::DocumentReady:
+ m_webEngineScript.setInjectionPoint(QWebEngineScript::DocumentReady);
+ break;
+ case QWebEngineScript::Deferred:
+ m_webEngineScript.setInjectionPoint(QWebEngineScript::Deferred);
+ break;
+ default:
+ break;
+ }
+ emit injectionPointChanged(injectionPoint);
+}
diff --git a/src/lib/plugins/qml/api/userscript/qmluserscripts.h b/src/lib/plugins/qml/api/userscript/qmluserscripts.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/userscript/qmluserscripts.h
@@ -0,0 +1,88 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include "qmluserscript.h"
+#include
+
+/**
+ * @brief The class exposing QWebEngineScriptCollection to QML
+ */
+class FALKON_EXPORT QmlUserScripts : public QObject
+{
+ Q_OBJECT
+ /**
+ * @brief Number of elements in the collection
+ */
+ Q_PROPERTY(int count READ count CONSTANT)
+ /**
+ * @brief Size of the collection
+ */
+ Q_PROPERTY(int size READ size CONSTANT)
+ /**
+ * @brief Checks if the collection is empty
+ */
+ Q_PROPERTY(bool empty READ empty CONSTANT)
+public:
+ explicit QmlUserScripts(QObject *parent = nullptr);
+ ~QmlUserScripts();
+ /**
+ * @brief Checks if the script is in collection
+ * @param object of type QmlUserScript
+ * @return true if the the script in in collection, else false
+ */
+ Q_INVOKABLE bool contains(QObject *object) const;
+ /**
+ * @brief Finds a script in collection by name
+ * @param name of the script
+ * @return object of type QmlUserScript, representing the script of given name
+ */
+ Q_INVOKABLE QObject *findScript(const QString &name) const;
+ /**
+ * @brief Finds all scripts in collection by a given name
+ * @return list of objects, each of type QmlUserScript, representing the script of given name
+ */
+ Q_INVOKABLE QList findScripts(const QString &name) const;
+ /**
+ * @brief Inserts a script into collection
+ * @param object of type QmlUserScript
+ */
+ Q_INVOKABLE void insert(QObject *object);
+ /**
+ * @brief Inserts a list of scripts into collection
+ * @param list of objects, each of type QmlUserScript
+ */
+ Q_INVOKABLE void insert(const QList &list);
+ /**
+ * @brief Removes a script from collection
+ * @param object of type QmlUserScript
+ */
+ Q_INVOKABLE void remove(QObject *object) const;
+ /**
+ * @brief Gets all the scripts of the collection
+ * @return list of objects, each of type QmlUserScript
+ */
+ Q_INVOKABLE QList toList() const;
+private:
+ int count() const;
+ int size() const;
+ bool empty() const;
+ QList m_webEngineScripts;
+
+ QList toQObjectList(const QList &list) const;
+};
diff --git a/src/lib/plugins/qml/api/userscript/qmluserscripts.cpp b/src/lib/plugins/qml/api/userscript/qmluserscripts.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/userscript/qmluserscripts.cpp
@@ -0,0 +1,126 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmluserscripts.h"
+#include "mainapplication.h"
+#include
+#include
+#include
+
+QmlUserScripts::QmlUserScripts(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QmlUserScripts::~QmlUserScripts()
+{
+ // remove scripts added by the plugin
+ for (const QWebEngineScript &webEngineScript : qAsConst(m_webEngineScripts)) {
+ mApp->webProfile()->scripts()->remove(webEngineScript);
+ }
+}
+
+int QmlUserScripts::count() const
+{
+ return mApp->webProfile()->scripts()->count();
+}
+
+int QmlUserScripts::size() const
+{
+ return mApp->webProfile()->scripts()->size();
+}
+
+bool QmlUserScripts::empty() const
+{
+ return mApp->webProfile()->scripts()->isEmpty();
+}
+
+QList QmlUserScripts::toQObjectList(const QList &list) const
+{
+ QList userScriptList;
+ userScriptList.reserve(list.size());
+ for (const QWebEngineScript &script : list) {
+ QmlUserScript *userScript = new QmlUserScript();
+ userScript->setWebEngineScript(script);
+ userScriptList.append(userScript);
+ }
+ return userScriptList;
+}
+
+bool QmlUserScripts::contains(QObject *object) const
+{
+ QmlUserScript *userScript = qobject_cast(object);
+ if (!userScript) {
+ return false;
+ }
+ QWebEngineScript webEngineScript = userScript->webEngineScript();
+ return mApp->webProfile()->scripts()->contains(webEngineScript);
+}
+
+QObject *QmlUserScripts::findScript(const QString &name) const
+{
+ QWebEngineScript webEngineScript = mApp->webProfile()->scripts()->findScript(name);
+ QmlUserScript *qmlUserScript = new QmlUserScript();
+ qmlUserScript->setWebEngineScript(webEngineScript);
+ return qmlUserScript;
+}
+
+QList QmlUserScripts::findScripts(const QString &name) const
+{
+ QList list = mApp->webProfile()->scripts()->findScripts(name);
+ return toQObjectList(list);
+}
+
+void QmlUserScripts::insert(QObject *object)
+{
+ QmlUserScript *userScript = qobject_cast(object);
+ if (!userScript) {
+ return;
+ }
+ QWebEngineScript webEngineScript = userScript->webEngineScript();
+ mApp->webProfile()->scripts()->insert(webEngineScript);
+ m_webEngineScripts.append(webEngineScript);
+}
+
+void QmlUserScripts::insert(const QList &list)
+{
+ for (QObject *object : list) {
+ QmlUserScript *userScript = qobject_cast(object);
+ if (!userScript) {
+ continue;
+ }
+ QWebEngineScript webEngineScript = userScript->webEngineScript();
+ mApp->webProfile()->scripts()->insert(webEngineScript);
+ m_webEngineScripts.append(webEngineScript);
+ }
+}
+
+void QmlUserScripts::remove(QObject *object) const
+{
+ QmlUserScript *userScript = qobject_cast(object);
+ if (!userScript) {
+ return;
+ }
+ QWebEngineScript webEngineScript = userScript->webEngineScript();
+ mApp->webProfile()->scripts()->remove(webEngineScript);
+}
+
+QList QmlUserScripts::toList() const
+{
+ QList list = mApp->webProfile()->scripts()->toList();
+ return toQObjectList(list);
+}
diff --git a/src/lib/plugins/qml/api/windows/qmlwindow.h b/src/lib/plugins/qml/api/windows/qmlwindow.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/windows/qmlwindow.h
@@ -0,0 +1,89 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include "browserwindow.h"
+#include "../qmlenums.h"
+/**
+ * @brief The class exposing Browser window to QML
+ */
+class QmlWindow : public QObject
+{
+ Q_OBJECT
+
+ /**
+ * @brief id of window
+ */
+ Q_PROPERTY(int id READ id CONSTANT)
+
+ /**
+ * @brief checks if the window is private
+ */
+ Q_PROPERTY(bool incognito READ incognito CONSTANT)
+
+ /**
+ * @brief title of window
+ */
+ Q_PROPERTY(QString title READ title CONSTANT)
+
+ /**
+ * @brief [window state](@ref QmlWindowState::WindowState) of window
+ */
+ Q_PROPERTY(QmlEnums::WindowState state READ state CONSTANT)
+
+ /**
+ * @brief [window type](@ref QmlWindowType::WindowType) of window
+ */
+ Q_PROPERTY(QmlEnums::WindowType type READ type CONSTANT)
+
+ /**
+ * @brief list of all tabs of window
+ */
+ Q_PROPERTY(QList tabs READ tabs CONSTANT)
+
+ /**
+ * @brief checks if the window is focussed
+ */
+ Q_PROPERTY(bool focussed READ focussed CONSTANT)
+
+ /**
+ * @brief height of window
+ */
+ Q_PROPERTY(int height READ height CONSTANT)
+
+ /**
+ * @brief width of window
+ */
+ Q_PROPERTY(int width READ width CONSTANT)
+public:
+ QmlWindow(BrowserWindow *window = nullptr, QObject *parent = nullptr);
+
+private:
+ BrowserWindow *m_window = nullptr;
+
+ int id() const;
+ bool incognito() const;
+ QString title() const;
+ QmlEnums::WindowState state() const;
+ QmlEnums::WindowType type() const;
+ QList tabs() const;
+ bool focussed() const;
+ int height() const;
+ int width() const;
+};
diff --git a/src/lib/plugins/qml/api/windows/qmlwindow.cpp b/src/lib/plugins/qml/api/windows/qmlwindow.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/windows/qmlwindow.cpp
@@ -0,0 +1,131 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlwindow.h"
+#include "mainapplication.h"
+#include "../tabs/qmltab.h"
+#include "tabwidget.h"
+#include "qml/qmlstaticdata.h"
+#include
+
+QmlWindow::QmlWindow(BrowserWindow *window, QObject *parent)
+ : QObject(parent)
+ , m_window(window)
+{
+ QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
+}
+
+int QmlWindow::id() const
+{
+ if (!QmlStaticData::instance().windowIdHash().contains(m_window)) {
+ return -1;
+ }
+
+ return QmlStaticData::instance().windowIdHash().value(m_window, -1);
+}
+
+bool QmlWindow::incognito() const
+{
+ return mApp->isPrivate();
+}
+
+QString QmlWindow::title() const
+{
+ if (!m_window) {
+ return QString();
+ }
+
+ return m_window->windowTitle();
+}
+
+QmlEnums::WindowState QmlWindow::state() const
+{
+ if (!m_window) {
+ return QmlEnums::Invalid;
+ }
+
+ if (m_window->isFullScreen()) {
+ return QmlEnums::FullScreen;
+ } else if (m_window->isMaximized()) {
+ return QmlEnums::Maximized;
+ } else if (m_window->isMinimized()) {
+ return QmlEnums::Minimized;
+ } else {
+ return QmlEnums::Normal;
+ }
+}
+
+QmlEnums::WindowType QmlWindow::type() const
+{
+ if (!m_window) {
+ return QmlEnums::OtherRestoredWindow;
+ }
+
+ switch (m_window->windowType()) {
+ case Qz::BW_FirstAppWindow:
+ return QmlEnums::FirstAppWindow;
+ case Qz::BW_MacFirstWindow:
+ return QmlEnums::MacFirstWindow;
+ case Qz::BW_NewWindow:
+ return QmlEnums::NewWindow;
+ default:
+ return QmlEnums::OtherRestoredWindow;
+ }
+}
+
+QList QmlWindow::tabs() const
+{
+ if (!m_window) {
+ return QList();
+ }
+
+ QList list;
+ const QList allTabs = m_window->tabWidget()->allTabs(true);
+ list.reserve(allTabs.size());
+ for (WebTab *tab : allTabs) {
+ list.append(new QmlTab(tab));
+ }
+
+ return list;
+}
+
+bool QmlWindow::focussed() const
+{
+ if (!m_window) {
+ return false;
+ }
+
+ return m_window->isActiveWindow();
+}
+
+int QmlWindow::height() const
+{
+ if (!m_window) {
+ return -1;
+ }
+
+ return m_window->height();
+}
+
+int QmlWindow::width() const
+{
+ if (!m_window) {
+ return -1;
+ }
+
+ return m_window->width();
+}
diff --git a/src/lib/plugins/qml/api/windows/qmlwindows.h b/src/lib/plugins/qml/api/windows/qmlwindows.h
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/windows/qmlwindows.h
@@ -0,0 +1,76 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 .
+* ============================================================ */
+#pragma once
+
+#include
+#include "qmlwindow.h"
+
+/**
+ * @brief The class exposing Windows API to QML
+ */
+class QmlWindows : public QObject
+{
+ Q_OBJECT
+public:
+ QmlWindows(QObject *parent = nullptr);
+ /**
+ * @brief Gets a browser window
+ * @param Integer representing the browser window
+ * @return Object of type [QmlWindow](@ref QmlWindow)
+ */
+ Q_INVOKABLE QmlWindow *get(int id) const;
+ /**
+ * @brief Gets the current browser window
+ * @return Object of type [QmlWindow](@ref QmlWindow)
+ */
+ Q_INVOKABLE QmlWindow *getCurrent() const;
+ /**
+ * @brief Get all the browser window
+ * @return List of windows of type [QmlWindow](@ref QmlWindow)
+ */
+ Q_INVOKABLE QList getAll() const;
+ /**
+ * @brief Creates a browser window
+ * @param A JavaScript object containing
+ * - url:
+ * The url of the first tab of the window
+ * - type:
+ * The window [type](@ref QmlWindowType)
+ * @return
+ */
+ Q_INVOKABLE QmlWindow *create(const QVariantMap &map) const;
+ /**
+ * @brief Removes a browser window
+ * @param Integer representing the window id
+ */
+ Q_INVOKABLE void remove(int windowId) const;
+Q_SIGNALS:
+ /**
+ * @brief The signal emitted when a window is created
+ * @param Object of type [QmlWindow](@ref QmlWindow)
+ */
+ void created(QmlWindow *window);
+
+ /**
+ * @brief The signal emitted when a window is removed
+ * @param Object of type [QmlWindow](@ref QmlWindow)
+ */
+ void removed(QmlWindow *window);
+private:
+ BrowserWindow *getBrowserWindow(int windowId) const;
+};
diff --git a/src/lib/plugins/qml/api/windows/qmlwindows.cpp b/src/lib/plugins/qml/api/windows/qmlwindows.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/plugins/qml/api/windows/qmlwindows.cpp
@@ -0,0 +1,84 @@
+/* ============================================================
+* Falkon - Qt web browser
+* Copyright (C) 2018 Anmol Gautam
+*
+* 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 "qmlwindows.h"
+#include "mainapplication.h"
+#include "pluginproxy.h"
+#include "qml/qmlstaticdata.h"
+#include
+
+QmlWindows::QmlWindows(QObject *parent)
+ : QObject(parent)
+{
+ connect(mApp->plugins(), &PluginProxy::mainWindowCreated, this, [this](BrowserWindow *window){
+ QmlWindow *qmlWindow = QmlStaticData::instance().getWindow(window);
+ emit created(qmlWindow);
+ });
+
+ connect(mApp->plugins(), &PluginProxy::mainWindowDeleted, this, [this](BrowserWindow *window){
+ QmlWindow *qmlWindow = QmlStaticData::instance().getWindow(window);
+ emit removed(qmlWindow);
+ });
+}
+
+QmlWindow *QmlWindows::get(int id) const
+{
+ return QmlStaticData::instance().getWindow(getBrowserWindow(id));
+}
+
+QmlWindow *QmlWindows::getCurrent() const
+{
+ return QmlStaticData::instance().getWindow(mApp->getWindow());
+}
+
+QList QmlWindows::getAll() const
+{
+ QList list;
+ const QList windows = mApp->windows();
+ list.reserve(windows.size());
+ for (BrowserWindow *window : windows) {
+ list.append(QmlStaticData::instance().getWindow(window));
+ }
+ return list;
+}
+
+QmlWindow *QmlWindows::create(const QVariantMap &map) const
+{
+ const QUrl url = QUrl::fromEncoded(map.value(QSL("url")).toString().toUtf8());
+ const Qz::BrowserWindowType type = Qz::BrowserWindowType(map.value(QSL("type"), QmlEnums::NewWindow).toInt());
+ BrowserWindow *window = mApp->createWindow(type, url);
+ return QmlStaticData::instance().getWindow(window);
+}
+
+void QmlWindows::remove(int windowId) const
+{
+ BrowserWindow *window = getBrowserWindow(windowId);
+ window->close();
+}
+
+BrowserWindow *QmlWindows::getBrowserWindow(int windowId) const
+{
+ const QList