From a2483484523513b8ed5b80ae084fea720dd07458 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Mon, 21 May 2018 16:57:23 +0200 Subject: [PATCH] Initial commit. This is a first "more than alpha" version of kiwix-desktop. It takes a zim as command line argument and open it. There is no navigation button, and the adresse bar is read only. It crashes if no zim is given on the command line. --- blobbuffer.cpp | 7 ++++ blobbuffer.h | 16 ++++++++ kiwix-desktop.pro | 80 ++++++++++++++++++++++++++++++++++++ kiwixapp.cpp | 28 +++++++++++++ kiwixapp.h | 25 ++++++++++++ kiwixrequestinterceptor.cpp | 23 +++++++++++ kiwixrequestinterceptor.h | 14 +++++++ kiwixschemehandler.cpp | 38 +++++++++++++++++ kiwixschemehandler.h | 13 ++++++ kiwixwebview.cpp | 16 ++++++++ kiwixwebview.h | 22 ++++++++++ main.cpp | 24 +++++++++++ mainwindow.cpp | 33 +++++++++++++++ mainwindow.h | 26 ++++++++++++ mainwindow.ui | 81 +++++++++++++++++++++++++++++++++++++ 15 files changed, 446 insertions(+) create mode 100644 blobbuffer.cpp create mode 100644 blobbuffer.h create mode 100644 kiwix-desktop.pro create mode 100644 kiwixapp.cpp create mode 100644 kiwixapp.h create mode 100644 kiwixrequestinterceptor.cpp create mode 100644 kiwixrequestinterceptor.h create mode 100644 kiwixschemehandler.cpp create mode 100644 kiwixschemehandler.h create mode 100644 kiwixwebview.cpp create mode 100644 kiwixwebview.h create mode 100644 main.cpp create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h create mode 100644 mainwindow.ui diff --git a/blobbuffer.cpp b/blobbuffer.cpp new file mode 100644 index 0000000..175bf9a --- /dev/null +++ b/blobbuffer.cpp @@ -0,0 +1,7 @@ +#include "blobbuffer.h" + +BlobBuffer::BlobBuffer(zim::Blob blob) + : blob(blob) +{ + setData(blob.data(), blob.size()); +} diff --git a/blobbuffer.h b/blobbuffer.h new file mode 100644 index 0000000..d62e335 --- /dev/null +++ b/blobbuffer.h @@ -0,0 +1,16 @@ +#ifndef BLOBBUFFER_H +#define BLOBBUFFER_H + +#include +#include + +class BlobBuffer : public QBuffer +{ +public: + BlobBuffer(zim::Blob blob); + +private: + zim::Blob blob; +}; + +#endif // BLOBBUFFER_H diff --git a/kiwix-desktop.pro b/kiwix-desktop.pro new file mode 100644 index 0000000..249d2a5 --- /dev/null +++ b/kiwix-desktop.pro @@ -0,0 +1,80 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2018-04-11T15:26:46 +# +#------------------------------------------------- + +QT += core gui +QT += webenginewidgets + +CONFIG += link_pkgconfig + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = kiwix-desktop +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + kiwixschemehandler.cpp \ + kiwixapp.cpp \ + blobbuffer.cpp \ + kiwixrequestinterceptor.cpp \ + kiwixwebview.cpp + +HEADERS += \ + mainwindow.h \ + kiwixschemehandler.h \ + kiwixapp.h \ + blobbuffer.h \ + kiwixrequestinterceptor.h \ + kiwixwebview.h + +FORMS += \ + mainwindow.ui + +isEmpty(PREFIX) { + PREFIX = /usr/local +} +target.path = $$PREFIX/bin +INSTALLS += target + +static { + PKGCONFIG_OPTION = "--static" + QMAKE_LFLAGS += "-static-libstdc++ --static" +} + +unix { + QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN/../lib64\ '" +} + +PKGCONFIG_CFLAGS = $$system(pkg-config --cflags $$PKGCONFIG_OPTION kiwix) + +PKGCONFIG_INCLUDEPATH = $$find(PKGCONFIG_CFLAGS, ^-I.*) +PKGCONFIG_INCLUDEPATH ~= s/^-I(.*)/\\1/g + +PKGCONFIG_DEFINES = $$find(PKGCONFIG_CFLAGS, ^-D.*) +PKGCONFIG_DEFINES ~= s/^-D(.*)/\\1/g + +PKGCONFIG_CFLAGS ~= s/^-[ID].*//g + +INCLUDEPATH *= $$PKGCONFIG_INCLUDEPATH +DEFINES *= $$PKGCONFIG_DEFINES + +QMAKE_CXXFLAGS += $$PKGCONFIG_CFLAGS +QMAKE_CFLAGS += $$PKGCONFIG_CFLAGS + +LIBS += $$system(pkg-config --libs $$PKGCONFIG_OPTION kiwix) diff --git a/kiwixapp.cpp b/kiwixapp.cpp new file mode 100644 index 0000000..060282c --- /dev/null +++ b/kiwixapp.cpp @@ -0,0 +1,28 @@ +#include "kiwixapp.h" + +KiwixApp::KiwixApp(int& argc, char *argv[]) + : QApplication(argc, argv), + reader(nullptr) +{ +} + +KiwixApp::~KiwixApp() +{ + if (reader) + delete reader; +} + + +void KiwixApp::openZimFile(const QString &zimfile) +{ + if (reader) + delete reader; + const std::string zimfile_ = zimfile.toLocal8Bit().constData(); + std::cout << "Opening " << zimfile_ << std::endl; + reader = new kiwix::Reader(zimfile_); +} + +kiwix::Reader* KiwixApp::getReader() +{ + return reader; +} diff --git a/kiwixapp.h b/kiwixapp.h new file mode 100644 index 0000000..36c66d3 --- /dev/null +++ b/kiwixapp.h @@ -0,0 +1,25 @@ +#ifndef KIWIXAPP_H +#define KIWIXAPP_H + +#include "kiwixschemehandler.h" +#include "kiwixrequestinterceptor.h" + +#include +#include + + +class KiwixApp : public QApplication +{ +public: + KiwixApp(int& argc, char *argv[]); + virtual ~KiwixApp(); + + void openZimFile(const QString& zimfile); + kiwix::Reader* getReader(); + + +private: + kiwix::Reader* reader; +}; + +#endif // KIWIXAPP_H diff --git a/kiwixrequestinterceptor.cpp b/kiwixrequestinterceptor.cpp new file mode 100644 index 0000000..53af39f --- /dev/null +++ b/kiwixrequestinterceptor.cpp @@ -0,0 +1,23 @@ +#include "kiwixrequestinterceptor.h" + +#include +#include +#include + +KiwixRequestInterceptor::KiwixRequestInterceptor() +{ + +} + + +void KiwixRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) +{ + std::cout << "Intercept request" << std::endl; + auto url = info.requestUrl(); + std::cout << " - " << url.toString().toUtf8().constData() << std::endl; + url.setScheme("zim"); + std::cout << " + " << url.toString().toUtf8().constData() << std::endl; + info.redirect(url); + +} + diff --git a/kiwixrequestinterceptor.h b/kiwixrequestinterceptor.h new file mode 100644 index 0000000..75f2ea6 --- /dev/null +++ b/kiwixrequestinterceptor.h @@ -0,0 +1,14 @@ +#ifndef KIWIXREQUESTINTERCEPTOR_H +#define KIWIXREQUESTINTERCEPTOR_H + +#include + + +class KiwixRequestInterceptor : public QWebEngineUrlRequestInterceptor +{ +public: + KiwixRequestInterceptor(); + virtual void interceptRequest(QWebEngineUrlRequestInfo &info); +}; + +#endif // KIWIXREQUESTINTERCEPTOR_H diff --git a/kiwixschemehandler.cpp b/kiwixschemehandler.cpp new file mode 100644 index 0000000..c4d6b39 --- /dev/null +++ b/kiwixschemehandler.cpp @@ -0,0 +1,38 @@ +#include "kiwixapp.h" +#include "kiwixschemehandler.h" +#include "blobbuffer.h" +#include +#include +#include +#include + +KiwixSchemeHandler::KiwixSchemeHandler() +{ + +} + + +void +KiwixSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request) +{ + std::cout << "Handling request " << request->requestUrl().toString().toUtf8().constData() << std::endl; + std::string url = request->requestUrl().path().toUtf8().constData(); + zim::Article art; + std::cout << "Url is " << url << std::endl; + auto reader = static_cast(KiwixApp::instance())->getReader(); + if ( !reader->getArticleObjectByDecodedUrl(url, art)) + { + url = "A/" + url; + if (!reader->getArticleObjectByDecodedUrl(url, art)) + { + request->fail(QWebEngineUrlRequestJob::UrlNotFound); + return; + } + } + + BlobBuffer* buffer = new BlobBuffer(art.getData()); + std::cout << " mimetype : " << art.getMimeType() << std::endl; + auto mimeType = QByteArray::fromRawData(art.getMimeType().data(), art.getMimeType().size()); + connect(buffer, &QIODevice::aboutToClose, buffer, &QObject::deleteLater); + request->reply(mimeType, buffer); +} diff --git a/kiwixschemehandler.h b/kiwixschemehandler.h new file mode 100644 index 0000000..14d35af --- /dev/null +++ b/kiwixschemehandler.h @@ -0,0 +1,13 @@ +#ifndef KIWIXSCHEMEHANDLER_H +#define KIWIXSCHEMEHANDLER_H + +#include + +class KiwixSchemeHandler : public QWebEngineUrlSchemeHandler +{ +public: + KiwixSchemeHandler(); + void requestStarted(QWebEngineUrlRequestJob *request); +}; + +#endif // KIWIXSCHEMEHANDLER_H diff --git a/kiwixwebview.cpp b/kiwixwebview.cpp new file mode 100644 index 0000000..3b860b1 --- /dev/null +++ b/kiwixwebview.cpp @@ -0,0 +1,16 @@ +#include "kiwixwebview.h" + +#include +#include + +KiwixWebView::KiwixWebView(QWidget *parent) + : QWebEngineView(parent) +{ + auto profile = page()->profile(); + profile->installUrlSchemeHandler("zim", &schemeHandler); + profile->setRequestInterceptor(&requestInterceptor); + +} + +KiwixWebView::~KiwixWebView() +{} diff --git a/kiwixwebview.h b/kiwixwebview.h new file mode 100644 index 0000000..ed19a02 --- /dev/null +++ b/kiwixwebview.h @@ -0,0 +1,22 @@ +#ifndef KIWIXWEBVIEW_H +#define KIWIXWEBVIEW_H + +#include +#include "kiwixschemehandler.h" +#include "kiwixrequestinterceptor.h" + + +class KiwixWebView : public QWebEngineView +{ + Q_OBJECT + +public: + KiwixWebView(QWidget *parent = Q_NULLPTR); + virtual ~KiwixWebView(); + +private: + KiwixSchemeHandler schemeHandler; + KiwixRequestInterceptor requestInterceptor; +}; + +#endif // KIWIXWEBVIEW_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..9d8a7ea --- /dev/null +++ b/main.cpp @@ -0,0 +1,24 @@ +#include "kiwixapp.h" +#include "mainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + KiwixApp a(argc, argv); + KiwixApp::setApplicationName("kiwix-desktop"); + + + QCommandLineParser parser; + parser.addPositionalArgument("zimfile", "The zim file"); + + parser.process(a); + const QString zimfile = parser.positionalArguments().at(0); + + a.openZimFile(zimfile); + + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..b14f8a6 --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,33 @@ +#include "kiwixapp.h" +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + ui->webview->page()->setUrl(QUrl("http://foo.zim")); + //ui->webview->page()->setUrl(QUrl("http://localhost:8080")); + + QObject::connect(ui->webview, SIGNAL(urlChanged(const QUrl&)), this, SLOT(on_urlChanged_triggered(const QUrl&))); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::on_pushButton_clicked() +{ + ui->webview->reload(); +} + + +void MainWindow::on_urlChanged_triggered(const QUrl& url) +{ + std::cout << "new url : " << url.toString().toUtf8().constData() << std::endl; + ui->addressBar->setText(url.toString()); +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..6432c14 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,26 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private slots: + void on_pushButton_clicked(); + void on_urlChanged_triggered(const QUrl& url); + +private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..8603c11 --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,81 @@ + + + MainWindow + + + + 0 + 0 + 873 + 984 + + + + MainWindow + + + + + + + QLayout::SetMinimumSize + + + + + false + + + + + + + Refresh + + + + + + + + + + + + + + 0 + 0 + 873 + 42 + + + + + Fichier + + + + + + + TopToolBarArea + + + false + + + + + + + + KiwixWebView + QWidget +
kiwixwebview.h
+ 1 +
+
+ + +