Commit 138397b7 authored by Anmol Gautam's avatar Anmol Gautam

merged patch D14513

parents 87987e25 dacf9939
......@@ -128,6 +128,9 @@ if (PySide2_FOUND AND Shiboken2_FOUND AND PythonLibs_FOUND)
endif()
find_package(LibIntl)
if (LibIntl_FOUND)
set(HAVE_LIBINTL TRUE)
endif()
# Git revision
if (EXISTS "${CMAKE_SOURCE_DIR}/.git")
......
......@@ -10,4 +10,4 @@
/* Disable DBus support */
#cmakedefine DISABLE_DBUS
#define HAVE_LIBINTL LibIntl_FOUND
#cmakedefine HAVE_LIBINTL
......@@ -155,9 +155,11 @@ set(SRCS ${SRCS}
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
......
......@@ -335,12 +335,3 @@ HistoryEntry *History::getHistoryEntry(const QString &text)
}
return entry;
}
void History::deleteRange(double startTime, double endTime)
{
QSqlQuery query(SqlDatabase::instance()->database());
query.prepare(QSL("DELETE FROM history WHERE date >= ? AND date <= ?"));
query.bindValue(0, startTime);
query.bindValue(1, endTime);
query.exec();
}
......@@ -69,7 +69,6 @@ public:
QList<HistoryEntry *> searchHistoryEntry(const QString &text);
HistoryEntry *getHistoryEntry(const QString &text);
void deleteRange(double startTime, double endTime);
Q_SIGNALS:
void historyEntryAdded(const HistoryEntry &entry);
......@@ -87,6 +86,5 @@ typedef History::HistoryEntry HistoryEntry;
// Hint to QVector to use std::realloc on item moving
Q_DECLARE_TYPEINFO(HistoryEntry, Q_MOVABLE_TYPE);
Q_DECLARE_METATYPE(HistoryEntry)
#endif // HISTORY_H
......@@ -26,6 +26,7 @@
#include "desktopfile.h"
#include "qml/qmlplugins.h"
#include "sqldatabase.h"
#include "qml/qmlplugin.h"
#include <iostream>
#include <QPluginLoader>
......@@ -37,7 +38,6 @@ Plugins::Plugins(QObject* parent)
: QObject(parent)
, m_pluginsLoaded(false)
, m_speedDial(new SpeedDial(this))
, m_qmlSupportLoaded(false)
{
loadSettings();
......@@ -136,7 +136,6 @@ PluginSpec Plugins::createSpec(const DesktopFile &metaData)
spec.description = metaData.comment();
spec.version = metaData.value(QSL("X-Falkon-Version")).toString();
spec.author = QSL("%1 <%2>").arg(metaData.value(QSL("X-Falkon-Author")).toString(), metaData.value(QSL("X-Falkon-Email")).toString());
spec.entryPoint = metaData.value(QSL("X-Falkon-EntryPoint")).toString();
spec.hasSettings = metaData.value(QSL("X-Falkon-Settings")).toBool();
const QString iconName = metaData.icon();
......@@ -235,7 +234,7 @@ void Plugins::loadAvailablePlugins()
dir.append(QSL("/qml"));
const auto qmlDirs = QDir(dir).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const QFileInfo &info : qmlDirs) {
Plugin plugin = loadQmlPlugin(info.absoluteFilePath());
Plugin plugin = QmlPlugin::loadPlugin(info.absoluteFilePath());
if (plugin.type == Plugin::Invalid) {
continue;
}
......@@ -288,12 +287,6 @@ void Plugins::loadPythonSupport()
}
}
void Plugins::loadQmlSupport()
{
QmlPlugins::registerQmlTypes();
m_qmlSupportLoaded = true;
}
Plugins::Plugin Plugins::loadPlugin(const QString &id)
{
QString name;
......@@ -328,7 +321,7 @@ Plugins::Plugin Plugins::loadPlugin(const QString &id)
return loadPythonPlugin(name);
case Plugin::QmlPlugin:
return loadQmlPlugin(name);
return QmlPlugin::loadPlugin(name);
default:
return Plugin();
......@@ -395,31 +388,6 @@ Plugins::Plugin Plugins::loadPythonPlugin(const QString &name)
return f(name);
}
Plugins::Plugin Plugins::loadQmlPlugin(const QString &name)
{
if (!m_qmlSupportLoaded) {
loadQmlSupport();
}
QString fullPath;
if (QFileInfo(name).isAbsolute()) {
fullPath = name;
} else {
fullPath = DataPaths::locate(DataPaths::Plugins, QSL("qml/") + name);
if (fullPath.isEmpty()) {
qWarning() << "Plugin" << name << "not found";
return Plugin();
}
}
Plugin plugin;
plugin.type = Plugin::QmlPlugin;
plugin.pluginId = QSL("qml:%1").arg(QFileInfo(name).fileName());
plugin.pluginSpec = createSpec(DesktopFile(fullPath + QSL("/metadata.desktop")));
plugin.data = QVariant::fromValue(new QmlPluginLoader(QDir(fullPath).filePath(plugin.pluginSpec.entryPoint)));
return plugin;
}
bool Plugins::initPlugin(PluginInterface::InitState state, Plugin *plugin)
{
if (!plugin) {
......@@ -440,7 +408,7 @@ bool Plugins::initPlugin(PluginInterface::InitState state, Plugin *plugin)
break;
case Plugin::QmlPlugin:
initQmlPlugin(plugin);
QmlPlugin::initPlugin(plugin);
break;
default:
......@@ -496,27 +464,6 @@ void Plugins::initPythonPlugin(Plugin *plugin)
f(plugin);
}
void Plugins::initQmlPlugin(Plugin *plugin)
{
Q_ASSERT(plugin->type == Plugin::QmlPlugin);
const QString name = plugin->pluginSpec.name;
auto qmlPluginLoader = static_cast<QmlPluginLoader *>(plugin->data.value<void *>());
if (!qmlPluginLoader) {
qWarning() << "Failed to cast from data";
return;
}
qmlPluginLoader->createComponent();
if (!qmlPluginLoader->instance()) {
qWarning().noquote() << "Falied to create component for" << name << "plugin:" << qmlPluginLoader->component()->errorString();
return;
}
qmlPluginLoader->setName(name);
plugin->instance = qobject_cast<PluginInterface*>(qmlPluginLoader->instance());
}
// static
QStringList Plugins::getDefaultAllowedPlugins()
{
......
......@@ -38,7 +38,6 @@ struct PluginSpec {
QString author;
QString version;
QPixmap icon;
QString entryPoint;
bool hasSettings = false;
bool operator==(const PluginSpec &other) const {
......@@ -117,17 +116,14 @@ Q_SIGNALS:
private:
void loadPythonSupport();
void loadQmlSupport();
Plugin loadPlugin(const QString &id);
Plugin loadInternalPlugin(const QString &name);
Plugin loadSharedLibraryPlugin(const QString &name);
Plugin loadPythonPlugin(const QString &name);
Plugin loadQmlPlugin(const QString &name);
bool initPlugin(PluginInterface::InitState state, Plugin *plugin);
void initInternalPlugin(Plugin *plugin);
void initSharedLibraryPlugin(Plugin *plugin);
void initPythonPlugin(Plugin *plugin);
void initQmlPlugin(Plugin *plugin);
void registerAvailablePlugin(const Plugin &plugin);
......@@ -143,7 +139,6 @@ private:
QList<PluginInterface*> m_internalPlugins;
QLibrary *m_pythonPlugin = nullptr;
bool m_qmlSupportLoaded;
};
Q_DECLARE_METATYPE(Plugins::Plugin)
......
/* ============================================================
* Falkon - Qt web browser
* Copyright (C) 2018 Anmol Gautam <tarptaeya@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "qmlbookmarks.h"
#include "bookmarks.h"
#include "qml/qmlstaticdata.h"
#include <QDebug>
#include <QQmlEngine>
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<BookmarkItem*> 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<QmlBookmarkTreeNode*>(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<QObject*>();
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<QObject*> QmlBookmarks::search(const QVariantMap &map) const
{
if (!map.contains(QSL("query")) && !map.contains(QSL("url"))) {
qWarning() << "Unable to search bookmarks";
return QList<QObject*>();
}
const QString query = map.value(QSL("query")).toString();
const QString urlString = map.value(QSL("url")).toString();
QList<BookmarkItem*> items;
if (urlString.isEmpty()) {
items = mApp->bookmarks()->searchBookmarks(query);
} else {
items = mApp->bookmarks()->searchBookmarks(QUrl::fromEncoded(urlString.toUtf8()));
}
QList<QObject*> 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<QmlBookmarkTreeNode*>(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<BookmarkItem*> items = mApp->bookmarks()->searchBookmarks(QUrl(string));
for (BookmarkItem *item : items) {
if (item->urlString() == string) {
return QmlStaticData::instance().getBookmarkTreeNode(item);
}
}
return nullptr;
}
QList<QObject*> QmlBookmarks::getChildren(QObject *object) const
{
QList<QObject*> ret;
auto bookmarkItem = getBookmarkItem(object);
if (!bookmarkItem) {
qWarning() << "Unable to get children:" << "parent not found";
return ret;
}
const QList<BookmarkItem*> items = bookmarkItem->children();
for (BookmarkItem *item : items) {
ret.append(QmlStaticData::instance().getBookmarkTreeNode(item));
}
return ret;
}
/* ============================================================
* Falkon - Qt web browser
* Copyright (C) 2018 Anmol Gautam <tarptaeya@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
* ============================================================ */
#pragma once
#include "qmlbookmarktreenode.h"
#include "mainapplication.h"
#include <QObject>
/**
* @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.
*/
<