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.
This commit is contained in:
Matthieu Gautier 2018-05-21 16:57:23 +02:00
parent bbbae462fd
commit a248348452
15 changed files with 446 additions and 0 deletions

7
blobbuffer.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "blobbuffer.h"
BlobBuffer::BlobBuffer(zim::Blob blob)
: blob(blob)
{
setData(blob.data(), blob.size());
}

16
blobbuffer.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef BLOBBUFFER_H
#define BLOBBUFFER_H
#include <zim/blob.h>
#include <QBuffer>
class BlobBuffer : public QBuffer
{
public:
BlobBuffer(zim::Blob blob);
private:
zim::Blob blob;
};
#endif // BLOBBUFFER_H

80
kiwix-desktop.pro Normal file
View File

@ -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)

28
kiwixapp.cpp Normal file
View File

@ -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;
}

25
kiwixapp.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef KIWIXAPP_H
#define KIWIXAPP_H
#include "kiwixschemehandler.h"
#include "kiwixrequestinterceptor.h"
#include <QApplication>
#include <kiwix/reader.h>
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

View File

@ -0,0 +1,23 @@
#include "kiwixrequestinterceptor.h"
#include <QWebEngineUrlRequestInfo>
#include <QDebug>
#include <iostream>
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);
}

14
kiwixrequestinterceptor.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef KIWIXREQUESTINTERCEPTOR_H
#define KIWIXREQUESTINTERCEPTOR_H
#include <QWebEngineUrlRequestInterceptor>
class KiwixRequestInterceptor : public QWebEngineUrlRequestInterceptor
{
public:
KiwixRequestInterceptor();
virtual void interceptRequest(QWebEngineUrlRequestInfo &info);
};
#endif // KIWIXREQUESTINTERCEPTOR_H

38
kiwixschemehandler.cpp Normal file
View File

@ -0,0 +1,38 @@
#include "kiwixapp.h"
#include "kiwixschemehandler.h"
#include "blobbuffer.h"
#include <QDebug>
#include <QWebEngineUrlRequestJob>
#include <QTextStream>
#include <iostream>
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*>(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);
}

13
kiwixschemehandler.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef KIWIXSCHEMEHANDLER_H
#define KIWIXSCHEMEHANDLER_H
#include <QWebEngineUrlSchemeHandler>
class KiwixSchemeHandler : public QWebEngineUrlSchemeHandler
{
public:
KiwixSchemeHandler();
void requestStarted(QWebEngineUrlRequestJob *request);
};
#endif // KIWIXSCHEMEHANDLER_H

16
kiwixwebview.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "kiwixwebview.h"
#include <QWebEngineProfile>
#include <iostream>
KiwixWebView::KiwixWebView(QWidget *parent)
: QWebEngineView(parent)
{
auto profile = page()->profile();
profile->installUrlSchemeHandler("zim", &schemeHandler);
profile->setRequestInterceptor(&requestInterceptor);
}
KiwixWebView::~KiwixWebView()
{}

22
kiwixwebview.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef KIWIXWEBVIEW_H
#define KIWIXWEBVIEW_H
#include <QWebEngineView>
#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

24
main.cpp Normal file
View File

@ -0,0 +1,24 @@
#include "kiwixapp.h"
#include "mainwindow.h"
#include <QCommandLineParser>
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();
}

33
mainwindow.cpp Normal file
View File

@ -0,0 +1,33 @@
#include "kiwixapp.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWebEngineProfile>
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());
}

26
mainwindow.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
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

81
mainwindow.ui Normal file
View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>873</width>
<height>984</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QLineEdit" name="addressBar">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="refreshButton">
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="KiwixWebView" name="webview" native="true"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>873</width>
<height>42</height>
</rect>
</property>
<widget class="QMenu" name="menuFichier">
<property name="title">
<string>Fichier</string>
</property>
</widget>
<addaction name="menuFichier"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>KiwixWebView</class>
<extends>QWidget</extends>
<header>kiwixwebview.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>