[Bookmarks] New bookmarks backend using JSON format

New format is compatible with Chromium's Bookmarks file.
It will support everything as the current backend +
 * multi-level bookmarks
 * bookmark description
 * bookmark keyword
 * remember expanded state (for folders)

NOTE: It is NOT yet complete. There is a LOT of work still needed.
Only bookmarks loading + saving and internal tree representation is
done.
remotes/origin/falkon
nowrep 12 years ago
parent a48b230ac8
commit 03186060aa
  1. 2
      .travis.yml
  2. 3
      src/lib/app/qz_namespace.h
  3. 159
      src/lib/bookmarks/bookmarkitem.cpp
  4. 80
      src/lib/bookmarks/bookmarkitem.h
  5. 152
      src/lib/bookmarks/bookmarks.cpp
  6. 13
      src/lib/bookmarks/bookmarks.h
  7. 16
      src/lib/lib.pro
  8. 33
      src/lib/tools/json.cpp
  9. 33
      src/lib/tools/json.h

@ -11,7 +11,7 @@ before_install:
install:
- sudo apt-get -qq update
- sudo apt-get -qq install libssl-dev pkg-config libhunspell-dev
- sudo apt-get -qq install libssl-dev pkg-config libhunspell-dev libqjson-dev
- if [[ "$QT" == "qt4" ]]; then sudo apt-get -qq install libqt4-dev libqt4-webkit libqt4-sql-sqlite; fi
- if [[ "$QT" == "qt5" ]]; then sudo apt-add-repository -y ppa:beineri/opt-qt511; sudo apt-get update -qq; sudo apt-get install -qq qt51base qt51webkit qt51tools qt51script libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev; fi

@ -43,6 +43,9 @@ static const int sessionVersion = 0x0003 | 0x050000;
static const int sessionVersion = 0x0003;
#endif
// Version of bookmarks.json file
static const int bookmarksVersion = 1;
enum AppMessageType {
AM_SetAdBlockIconEnabled,
AM_CheckPrivateBrowsing,

@ -0,0 +1,159 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2014 David Rosca <nowrep@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 "bookmarkitem.h"
BookmarkItem::BookmarkItem(BookmarkItem::Type type, BookmarkItem *parent)
: m_type(type)
, m_parent(parent)
, m_expanded(false)
{
if (m_parent) {
parent->addChild(this);
}
}
BookmarkItem::~BookmarkItem()
{
qDeleteAll(m_children);
}
BookmarkItem::Type BookmarkItem::type() const
{
return m_type;
}
void BookmarkItem::setType(BookmarkItem::Type type)
{
m_type = type;
}
BookmarkItem *BookmarkItem::parent() const
{
return m_parent;
}
QList<BookmarkItem *> BookmarkItem::children() const
{
return m_children;
}
QUrl BookmarkItem::url() const
{
return m_url;
}
void BookmarkItem::setUrl(const QUrl &url)
{
m_url = url;
}
QString BookmarkItem::title() const
{
return m_title;
}
void BookmarkItem::setTitle(const QString &title)
{
m_title = title;
}
QString BookmarkItem::description() const
{
return m_description;
}
void BookmarkItem::setDescription(const QString &description)
{
m_description = description;
}
QString BookmarkItem::keyword() const
{
return m_keyword;
}
void BookmarkItem::setKeyword(const QString &keyword)
{
m_keyword = keyword;
}
bool BookmarkItem::isExpanded() const
{
return m_type == Root ? true : m_expanded;
}
void BookmarkItem::setExpanded(bool expanded)
{
m_expanded = expanded;
}
void BookmarkItem::addChild(BookmarkItem *child, int index)
{
if (child->m_parent) {
child->m_parent->removeChild(child);
}
child->m_parent = this;
if (index == -1) {
m_children.append(child);
}
else {
m_children.insert(index, child);
}
}
void BookmarkItem::removeChild(BookmarkItem *child)
{
child->m_parent = 0;
m_children.removeOne(child);
}
BookmarkItem::Type BookmarkItem::typeFromString(const QString &string)
{
if (string == QLatin1String("url")) {
return Url;
}
if (string == QLatin1String("folder")) {
return Folder;
}
if (string == QLatin1String("separator")) {
return Separator;
}
return Invalid;
}
QString BookmarkItem::typeToString(BookmarkItem::Type type)
{
switch (type) {
case Url:
return QString("url");
case Folder:
return QString("folder");
case Separator:
return QString("separator");
default:
return QString("invalid");
}
}

@ -0,0 +1,80 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2014 David Rosca <nowrep@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/>.
* ============================================================ */
#ifndef BOOKMARKITEM_H
#define BOOKMARKITEM_H
#include <QString>
#include <QList>
#include <QUrl>
#include "qz_namespace.h"
class QT_QUPZILLA_EXPORT BookmarkItem
{
public:
enum Type {
Root,
Url,
Folder,
Separator,
Invalid
};
explicit BookmarkItem(Type type, BookmarkItem* parent = 0);
~BookmarkItem();
Type type() const;
void setType(Type type);
BookmarkItem *parent() const;
QList<BookmarkItem*> children() const;
QUrl url() const;
void setUrl(const QUrl &url);
QString title() const;
void setTitle(const QString &title);
QString description() const;
void setDescription(const QString &description);
QString keyword() const;
void setKeyword(const QString &keyword);
bool isExpanded() const;
void setExpanded(bool expanded);
void addChild(BookmarkItem *child, int index = -1);
void removeChild(BookmarkItem *child);
static Type typeFromString(const QString &string);
static QString typeToString(Type type);
private:
Type m_type;
BookmarkItem* m_parent;
QList<BookmarkItem*> m_children;
QUrl m_url;
QString m_title;
QString m_description;
QString m_keyword;
bool m_expanded;
};
#endif // BOOKMARKITEM_H

@ -16,12 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "bookmarks.h"
#include "bookmarkitem.h"
#include "tabbedwebview.h"
#include "iconprovider.h"
#include "databasewriter.h"
#include "mainapplication.h"
#include "settings.h"
#include "json.h"
#include <QSqlQuery>
#include <QTextStream>
#include <QBuffer>
#include <QDebug>
@ -35,9 +37,157 @@
Bookmarks::Bookmarks(QObject* parent)
: QObject(parent)
{
loadBookmarks();
loadSettings();
}
void Bookmarks::loadBookmarks()
{
m_root = new BookmarkItem(BookmarkItem::Root);
m_folderToolbar = new BookmarkItem(BookmarkItem::Folder, m_root);
m_folderToolbar->setTitle(tr("Bookmarks ToolBar"));
m_folderToolbar->setDescription(tr("Bookmarks located in Bookmarks Toolbar"));
m_folderMenu = new BookmarkItem(BookmarkItem::Folder, m_root);
m_folderMenu->setTitle(tr("Bookmarks In Menu"));
m_folderMenu->setDescription(tr("Bookmarks located in Bookmarks Menu"));
m_folderUnsorted = new BookmarkItem(BookmarkItem::Folder, m_root);
m_folderUnsorted->setTitle(tr("Unsorted Bookmarks"));
m_folderUnsorted->setDescription(tr("All other bookmarks"));
// TODO: Make sure bookmarks are loaded correctly even on error
QFile bFile(mApp->currentProfilePath() + QLatin1String("/bookmarks.json"));
bFile.open(QFile::ReadOnly);
QByteArray data = bFile.readAll();
bFile.close();
bool ok;
const QVariant res = Json::parse(data, &ok);
if (!ok || res.type() != QVariant::Map) {
qWarning() << "Bookmarks::loadBookmarks() Error parsing bookmarks!";
return;
}
const QVariantMap map = res.toMap();
const QVariantMap bookmarksMap = map.value("roots").toMap();
readBookmarks(bookmarksMap.value("bookmark_bar").toMap().value("children").toList(), m_folderToolbar);
readBookmarks(bookmarksMap.value("bookmark_menu").toMap().value("children").toList(), m_folderMenu);
readBookmarks(bookmarksMap.value("other").toMap().value("children").toList(), m_folderUnsorted);
}
void Bookmarks::saveBookmarks()
{
QVariantMap toolbarMap;
toolbarMap.insert("children", writeBookmarks(m_folderToolbar));
QVariantMap menuMap;
menuMap.insert("children", writeBookmarks(m_folderMenu));
QVariantMap unsortedMap;
unsortedMap.insert("children", writeBookmarks(m_folderUnsorted));
QVariantMap bookmarksMap;
bookmarksMap.insert("bookmark_bar", toolbarMap);
bookmarksMap.insert("bookmark_menu", menuMap);
bookmarksMap.insert("other", unsortedMap);
QVariantMap map;
map.insert("version", Qz::bookmarksVersion);
map.insert("roots", bookmarksMap);
bool ok;
const QByteArray data = Json::serialize(map, &ok);
if (!ok || data.isEmpty()) {
qWarning() << "Bookmarks::saveBookmarks() Error serializing bookmarks!";
return;
}
QFile bFile(mApp->currentProfilePath() + QLatin1String("/bookmarks.json"));
if (!bFile.open(QFile::WriteOnly)) {
qWarning() << "Bookmarks::saveBookmarks() Error opening bookmarks file for writing!";
}
bFile.write(data);
bFile.close();
}
void Bookmarks::readBookmarks(const QVariantList &list, BookmarkItem *parent)
{
if (!parent) {
return;
}
foreach (const QVariant &entry, list) {
const QVariantMap map = entry.toMap();
BookmarkItem::Type type = BookmarkItem::typeFromString(map.value("type").toString());
if (type == BookmarkItem::Invalid) {
continue;
}
BookmarkItem* item = new BookmarkItem(type, parent);
item->setUrl(map.value("url").toUrl());
item->setTitle(map.value("name").toString());
item->setDescription(map.value("description").toString());
item->setKeyword(map.value("keyword").toString());
item->setExpanded(map.value("expanded").toBool());
if (map.contains("children")) {
readBookmarks(map.value("children").toList(), item);
}
}
}
QVariantList Bookmarks::writeBookmarks(BookmarkItem *parent)
{
QVariantList list;
if (!parent) {
return list;
}
foreach (BookmarkItem* child, parent->children()) {
QVariantMap map;
map.insert("type", BookmarkItem::typeToString(child->type()));
map.insert("url", child->url());
map.insert("name", child->title());
map.insert("description", child->description());
map.insert("keyword", child->keyword());
map.insert("expanded", child->isExpanded());
if (!child->children().isEmpty()) {
map.insert("children", writeBookmarks(child));
}
list.append(map);
}
return list;
}
void Bookmarks::writeChildren(BookmarkItem *parent)
{
if (!parent) {
return;
}
foreach (BookmarkItem* child, parent->children()) {
if (child->type() == BookmarkItem::Url) {
qDebug() << child->title() << child->url();
}
else {
qDebug() << "folder" << child->title();
}
}
}
void Bookmarks::loadSettings()
{
Settings settings;

@ -32,6 +32,7 @@
class QIcon;
class WebView;
class BookmarkItem;
class QT_QUPZILLA_EXPORT Bookmarks : public QObject
{
@ -120,9 +121,21 @@ public slots:
void changeFolderParent(const QString &name, bool isSubfolder, bool* ok = 0);
private:
void loadBookmarks();
void saveBookmarks();
void readBookmarks(const QVariantList &list, BookmarkItem* parent);
QVariantList writeBookmarks(BookmarkItem* parent);
void writeChildren(BookmarkItem* parent);
bool m_showMostVisited;
bool m_showOnlyIconsInToolbar;
QString m_lastFolder;
BookmarkItem* m_root;
BookmarkItem* m_folderToolbar;
BookmarkItem* m_folderMenu;
BookmarkItem* m_folderUnsorted;
};
typedef Bookmarks::Bookmark Bookmark;

@ -251,7 +251,9 @@ SOURCES += \
tools/tabstackedwidget.cpp \
tools/combotabbar.cpp \
webview/javascript/externaljsobject.cpp \
bookmarks/bookmarks.cpp
bookmarks/bookmarks.cpp \
bookmarks/bookmarkitem.cpp \
tools/json.cpp
HEADERS += \
@ -439,7 +441,9 @@ HEADERS += \
tools/tabstackedwidget.h \
tools/combotabbar.h \
webview/javascript/externaljsobject.h \
bookmarks/bookmarks.h
bookmarks/bookmarks.h \
bookmarks/bookmarkitem.h \
tools/json.h
FORMS += \
preferences/autofillmanager.ui \
@ -510,7 +514,7 @@ isEqual(QT_MAJOR_VERSION, 5) {
INSTALLS += target
!contains(DEFINES, NO_X11):LIBS += -lX11
LIBS += -lcrypto
LIBS += -lcrypto -lqjson
RESOURCES -= data/certs.qrc
}
@ -519,11 +523,11 @@ win32 {
HEADERS += other/registerqappassociation.h
SOURCES += other/registerqappassociation.cpp
LIBS += -llibeay32
LIBS += -llibeay32 -lqjson
}
os2 {
LIBS += -lcrypto
LIBS += -lcrypto -lqjson
}
mac {
@ -533,7 +537,7 @@ mac {
webview/macwebviewscroller.cpp
RESOURCES -= data/certs.qrc
LIBS += -lcrypto -framework CoreServices
LIBS += -lcrypto -lqjson -framework CoreServices
}
message(===========================================)

@ -0,0 +1,33 @@
/* ===========================================================
* QupZilla - WebKit based browser
* Copyright (C) 2014 David Rosca <nowrep@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 "json.h"
#include <qjson/parser.h>
#include <qjson/serializer.h>
QVariant Json::parse(const QByteArray &data, bool *ok)
{
QJson::Parser parser;
return parser.parse(data, ok);
}
QByteArray Json::serialize(const QVariant &variant, bool *ok)
{
QJson::Serializer serializer;
serializer.setIndentMode(QJson::IndentFull);
return serializer.serialize(variant, ok);
}

@ -0,0 +1,33 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2014 David Rosca <nowrep@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/>.
* ============================================================ */
#ifndef JSON_H
#define JSON_H
#include <QVariant>
#include <QByteArray>
#include "qz_namespace.h"
class QT_QUPZILLA_EXPORT Json
{
public:
static QVariant parse(const QByteArray &data, bool* ok);
static QByteArray serialize(const QVariant &variant, bool* ok);
};
#endif // JSON_H
Loading…
Cancel
Save