This commit is contained in:
Matthieu Gautier 2021-10-19 11:01:45 +02:00 committed by GitHub
commit 30d6ffde2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 473 additions and 299 deletions

View File

@ -44,7 +44,7 @@ SOURCES += \
src/blobbuffer.cpp \ src/blobbuffer.cpp \
src/library.cpp \ src/library.cpp \
src/settingsmanager.cpp \ src/settingsmanager.cpp \
src/settingsmanagerview.cpp \ src/settingsview.cpp \
src/topwidget.cpp \ src/topwidget.cpp \
src/urlschemehandler.cpp \ src/urlschemehandler.cpp \
src/webview.cpp \ src/webview.cpp \
@ -76,7 +76,7 @@ HEADERS += \
src/blobbuffer.h \ src/blobbuffer.h \
src/library.h \ src/library.h \
src/settingsmanager.h \ src/settingsmanager.h \
src/settingsmanagerview.h \ src/settingsview.h \
src/topwidget.h \ src/topwidget.h \
src/kconstants.h \ src/kconstants.h \
src/urlschemehandler.h \ src/urlschemehandler.h \
@ -105,7 +105,8 @@ FORMS += \
ui/about.ui \ ui/about.ui \
src/contentmanagerside.ui \ src/contentmanagerside.ui \
src/readinglistbar.ui \ src/readinglistbar.ui \
ui/localkiwixserver.ui ui/localkiwixserver.ui \
ui/settings.ui
include(subprojects/QtSingleApplication/src/qtsingleapplication.pri) include(subprojects/QtSingleApplication/src/qtsingleapplication.pri)
CODECFORSRC = UTF-8 CODECFORSRC = UTF-8

View File

@ -1,88 +1,40 @@
html, body { QWidget#widget {
padding: 0; max-width: 500;
margin: auto;
height: 100%;
position: relative;
width: 80%;
overflow: hidden;
} }
#settings { QLabel,
height: 100%; QPushButton,
position: relative; QSpinBox {
font-size: 16px;
line-height: 24px;
padding: 8px;
} }
#header { QFrame[frameShape="4"] {
display: flex; /*frameShape 4 is HLine */
flex-direction: row; border: 1px solid #eaecf0;
flex-wrap: nowrap; min-height: 0pt;
justify-content: space-between; max-height: 1pt;
} }
.row { QLabel#settingsLabel {
display: flex; font-size: 32px;
flex-direction: row; line-height: 44px;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
border-top: 1px solid grey;
height: 40px;
}
input {
margin: 5px;
}
#download_dir {
flex: 1;
margin: 5px;
overflow: hidden;
direction: rtl;
}
#download_dir > span {
display: block;
float: right;
direction: ltr;
min-width: 100%;
font-size: 0.9em;
}
input[type=number] {
width: 80px;
}
input[type=button] {
color: blue;
font-weight: bold; font-weight: bold;
font-size: 14px; }
border: 0; QSpinBox,
background: transparent; QLabel#downloadDirPath {
border-radius: 2px; font: bold 12pt "Cantarell";
}
QPushButton {
background-color: white;
color: #3366cc;
padding: 4px;
font: bold;
border-radius: 4px;
} }
input[type=button]:hover { QPushButton:hover {
background-color: #3366cc;
color: white; color: white;
background: blue;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
opacity: 1;
}
div.percentage-symbol {
position: relative;
}
div.percentage-symbol:before {
position: absolute;
content: "%";
top: 0.4em;
right: 1.5em;
}
div.percentage-symbol input {
text-align: left;
} }

View File

@ -1,61 +0,0 @@
function onDownloadDirChanged (downloadDir) {
app.downloadDir = downloadDir;
}
function validPort (port) {
return /^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/.test(port);
}
function setTranslations(translations) {
app.translations = createDict(TRANSLATION_KEYS, translations);
}
const TRANSLATION_KEYS = ["settings",
"port-for-local-kiwix-server-setting",
"zoom-level-setting",
"download-directory-setting",
"reset",
"browse",
"invalid-port"];
function init() {
new QWebChannel(qt.webChannelTransport, function(channel) {
settingsManager = channel.objects.settingsManager;
app = new Vue({
el: "#settings",
data: {
settingsManager: settingsManager,
kiwixServerPort: settingsManager.kiwixServerPort,
zoomFactor: Math.floor(settingsManager.zoomFactor * 100),
downloadDir: settingsManager.downloadDir,
translations:{}
},
methods: {
gt : function(key) {
return this.translations[key];
},
setPort : function() {
if (!validPort(this.kiwixServerPort)) {
alert(this.gt("invalid-port"));
this.kiwixServerPort = settingsManager.kiwixServerPort;
return;
}
settingsManager.setKiwixServerPort(this.kiwixServerPort);
},
setZoomFactor : function() {
this.zoomFactor = (this.zoomFactor < 30) ? 30 : this.zoomFactor;
this.zoomFactor = (this.zoomFactor > 500) ? 500 : this.zoomFactor;
settingsManager.setZoomFactor(this.zoomFactor / 100);
},
resetDownloadDir : function() {
settingsManager.resetDownloadDir();
},
browseDownloadDir : function() {
settingsManager.browseDownloadDir();
}
}
});
settingsManager.downloadDirChanged.connect(onDownloadDirChanged)
settingsManager.getTranslations(TRANSLATION_KEYS, setTranslations);
});
}

View File

@ -1,7 +1,5 @@
<RCC> <RCC>
<qresource prefix="/"> <qresource prefix="/">
<file>texts/_settingsManager.html</file>
<file>css/_settingsManager.css</file> <file>css/_settingsManager.css</file>
<file>js/_settingsManager.js</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -1,33 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html>
<head>
<script src="qrc:///js/vue.js"></script>
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script src="qrc:///js/_settingsManager.js"></script>
<script src="qrc:///js/tools.js"></script>
<link rel="stylesheet" type="text/css" href="qrc:///css/_settingsManager.css"/>
</head>
<body onload="init()">
<div id="settings">
<div id="header">
<h1>{{ gt("settings") }}</h1>
</div>
<div class="row">
<label>{{ gt("port-for-local-kiwix-server-setting") }}</label>
<input type="number" min="1" max="65535" v-on:change="setPort()" v-model="kiwixServerPort">
</div>
<div class="row">
<label>{{ gt("zoom-level-setting") }}</label>
<div class="percentage-symbol">
<input type="number" step="10" min="30" max="500" v-on:change="setZoomFactor()" v-model="zoomFactor" >
</div>
</div>
<div class="row">
<label>{{ gt("download-directory-setting") }}</label>
<span id="download_dir"><span>{{ downloadDir }}</span></span>
<input type="button" :value="gt('reset')" v-on:click="resetDownloadDir()">
<input type="button" :value="gt('browse')" v-on:click="browseDownloadDir()">
</div>
</div>
</body></html>

View File

@ -17,7 +17,6 @@
KiwixApp::KiwixApp(int& argc, char *argv[]) KiwixApp::KiwixApp(int& argc, char *argv[])
: QtSingleApplication("kiwix-desktop", argc, argv), : QtSingleApplication("kiwix-desktop", argc, argv),
m_settingsManager(),
m_profile(), m_profile(),
m_libraryDirectory(findLibraryDirectory()), m_libraryDirectory(findLibraryDirectory()),
m_library(m_libraryDirectory), m_library(m_libraryDirectory),

View File

@ -4,23 +4,23 @@
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox> #include <QMessageBox>
#include <kiwix/tools.h> #include <kiwix/tools.h>
SettingsManager::SettingsManager(QObject *parent) SettingsManager::SettingsManager(QObject *parent)
: QObject(parent), : QObject(parent),
m_settings("Kiwix", "Kiwix-desktop"), m_settings("Kiwix", "Kiwix-desktop"),
m_settingsViewDisplayed(false) m_view(nullptr)
{ {
initSettings(); initSettings();
} }
SettingsManagerView* SettingsManager::getView() SettingsView* SettingsManager::getView()
{ {
auto view = new SettingsManagerView(); if (m_view == nullptr) {
view->registerObject("settingsManager", this); auto view = new SettingsView();
view->setHtml(); view->init(m_kiwixServerPort, m_zoomFactor * 100, m_downloadDir);
connect(view, &QObject::destroyed, this, [=]() { m_settingsViewDisplayed = false; }); connect(view, &QObject::destroyed, this, [=]() { m_view = nullptr; });
m_settingsViewDisplayed = true; m_view = view;
return view; }
return m_view;
} }
void SettingsManager::setSettings(const QString &key, const QVariant &value) void SettingsManager::setSettings(const QString &key, const QVariant &value)
@ -64,69 +64,17 @@ void SettingsManager::setZoomFactor(qreal zoomFactor)
{ {
m_zoomFactor = zoomFactor; m_zoomFactor = zoomFactor;
m_settings.setValue("view/zoomFactor", zoomFactor); m_settings.setValue("view/zoomFactor", zoomFactor);
emit(zoomChanged(zoomFactor));
} }
bool SettingsManager::setDownloadDir(QString downloadDir) bool SettingsManager::setDownloadDir(QString downloadDir)
{ {
m_downloadDir = downloadDir; m_downloadDir = downloadDir;
m_settings.setValue("download/dir", downloadDir); m_settings.setValue("download/dir", downloadDir);
emit(downloadDirChanged(downloadDir));
return true; return true;
} }
bool SettingsManager::confirmDialogDownloadDir(const QString& dir)
{
auto text = gt("download-dir-dialog-msg");
text = text.replace("{{DIRECTORY}}", dir);
QMessageBox msgBox(
QMessageBox::Question, //Icon
gt("download-dir-dialog-title"), //Title
text, //Text
QMessageBox::Ok | QMessageBox::Cancel //Buttons
);
msgBox.setDefaultButton(QMessageBox::Ok);
int ret = msgBox.exec();
return (ret == QMessageBox::Ok);
}
void SettingsManager::resetDownloadDir()
{
auto dir = QString::fromStdString(kiwix::getDataDirectory());
if (dir == m_downloadDir) {
return;
}
if (confirmDialogDownloadDir(dir)) {
setDownloadDir(dir);
emit(downloadDirChanged(dir));
}
}
void SettingsManager::browseDownloadDir()
{
QString dir = QFileDialog::getExistingDirectory(KiwixApp::instance()->getMainWindow(),
gt("browse-directory"),
m_downloadDir,
QFileDialog::ShowDirsOnly);
if (dir == m_downloadDir || dir.isEmpty()) {
return;
}
if (confirmDialogDownloadDir(dir)) {
setDownloadDir(dir);
emit(downloadDirChanged(dir));
}
}
QStringList SettingsManager::getTranslations(const QStringList &keys)
{
QStringList translations;
for(auto& key: keys) {
translations.append(KiwixApp::instance()->getText(key));
}
return translations;
}
void SettingsManager::initSettings() void SettingsManager::initSettings()
{ {
m_kiwixServerPort = m_settings.value("localKiwixServer/port", 8181).toInt(); m_kiwixServerPort = m_settings.value("localKiwixServer/port", 8181).toInt();

View File

@ -3,21 +3,20 @@
#include <QObject> #include <QObject>
#include <QSettings> #include <QSettings>
#include "settingsmanagerview.h" #include "settingsview.h"
class SettingsManager : public QObject class SettingsManager : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int kiwixServerPort READ getKiwixServerPort NOTIFY portChanged) Q_PROPERTY(int kiwixServerPort READ getKiwixServerPort NOTIFY portChanged)
Q_PROPERTY(qreal zoomFactor READ getZoomFactor NOTIFY zoomChanged) Q_PROPERTY(qreal zoomFactor MEMBER m_zoomFactor WRITE setZoomFactor NOTIFY zoomChanged)
Q_PROPERTY(QString downloadDir READ getDownloadDir NOTIFY downloadDirChanged) Q_PROPERTY(QString downloadDir MEMBER m_downloadDir WRITE setDownloadDir NOTIFY downloadDirChanged)
public: public:
explicit SettingsManager(QObject *parent = nullptr); explicit SettingsManager(QObject *parent = nullptr);
virtual ~SettingsManager() {}; virtual ~SettingsManager() {};
SettingsManagerView* getView(); SettingsView* getView();
bool isSettingsViewdisplayed() { return m_settingsViewDisplayed; };
void setSettings(const QString &key, const QVariant &value); void setSettings(const QString &key, const QVariant &value);
void deleteSettings(const QString &key); void deleteSettings(const QString &key);
bool settingsExists(const QString &key); bool settingsExists(const QString &key);
@ -25,19 +24,14 @@ public:
qreal getZoomFactorByZimId(const QString &id); qreal getZoomFactorByZimId(const QString &id);
public slots: public slots:
QStringList getTranslations(const QStringList &keys);
void setKiwixServerPort(int port); void setKiwixServerPort(int port);
int getKiwixServerPort() { return m_kiwixServerPort; }; int getKiwixServerPort() { return m_kiwixServerPort; };
void setZoomFactor(qreal zoomFactor); void setZoomFactor(qreal zoomFactor);
qreal getZoomFactor() { return m_zoomFactor; }; qreal getZoomFactor() { return m_zoomFactor; };
bool setDownloadDir(QString downloadDir); bool setDownloadDir(QString downloadDir);
QString getDownloadDir() { return m_downloadDir; } QString getDownloadDir() { return m_downloadDir; }
void resetDownloadDir();
void browseDownloadDir();
private: private:
void initSettings(); void initSettings();
bool confirmDialogDownloadDir(const QString& dir);
signals: signals:
void portChanged(int port); void portChanged(int port);
@ -46,7 +40,7 @@ signals:
private: private:
QSettings m_settings; QSettings m_settings;
bool m_settingsViewDisplayed; SettingsView *m_view;
int m_kiwixServerPort; int m_kiwixServerPort;
qreal m_zoomFactor; qreal m_zoomFactor;
QString m_downloadDir; QString m_downloadDir;

View File

@ -1,23 +0,0 @@
#include "settingsmanagerview.h"
#include "kiwixapp.h"
#include <QFile>
SettingsManagerView::SettingsManagerView(QWidget *parent) : QWebEngineView(parent)
{
page()->setWebChannel(&m_webChannel);
setContextMenuPolicy( Qt::NoContextMenu );
}
void SettingsManagerView::registerObject(const QString& id, QObject* object)
{
m_webChannel.registerObject(id, object);
}
void SettingsManagerView::setHtml()
{
QFile contentFile(":texts/_settingsManager.html");
contentFile.open(QIODevice::ReadOnly);
auto byteContent = contentFile.readAll();
contentFile.close();
QWebEngineView::setHtml(byteContent);
}

View File

@ -1,19 +0,0 @@
#ifndef SETTINGSMANAGERVIEW_H
#define SETTINGSMANAGERVIEW_H
#include <QWebEngineView>
#include <QWebChannel>
class SettingsManagerView : public QWebEngineView
{
Q_OBJECT
public:
SettingsManagerView(QWidget *parent = nullptr);
void registerObject(const QString &id, QObject *object);
void setHtml();
private:
QWebChannel m_webChannel;
};
#endif // SETTINGSMANAGERVIEW_H

105
src/settingsview.cpp Normal file
View File

@ -0,0 +1,105 @@
#include "settingsview.h"
#include "ui_settings.h"
#include "kiwixapp.h"
#include <kiwix/tools.h>
#include <QMessageBox>
#include <QFileDialog>
SettingsView::SettingsView(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Settings)
{
ui->setupUi(this);
QFile file(QString::fromUtf8(":/css/_settingsManager.css"));
file.open(QFile::ReadOnly);
QString styleSheet = QString(file.readAll());
ui->widget->setStyleSheet(styleSheet);
connect(ui->serverPortSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &SettingsView::setKiwixServerPort);
connect(ui->zoomPercentSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &SettingsView::setZoom);
connect(ui->browseButton, &QPushButton::clicked, this, &SettingsView::browseDownloadDir);
connect(ui->resetButton, &QPushButton::clicked, this, &SettingsView::resetDownloadDir);
connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::downloadDirChanged, this, &SettingsView::onDownloadDirChanged);
connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::zoomChanged, this, &SettingsView::onZoomChanged);
connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::portChanged, this, &SettingsView::onServerPortChanged);
ui->settingsLabel->setText(gt("settings"));
ui->serverPortLabel->setText(gt("port-for-local-kiwix-server-setting"));
ui->zoomPercentLabel->setText(gt("zoom-level-setting"));
ui->downloadDirLabel->setText(gt("download-directory-setting"));
ui->resetButton->setText(gt("reset"));
ui->browseButton->setText(gt("browse"));
}
void SettingsView::init(int port, int zoomPercent, const QString &dir)
{
ui->serverPortSpinBox->setValue(port);
ui->zoomPercentSpinBox->setValue(zoomPercent);
ui->downloadDirPath->setText(dir);
}
bool SettingsView::confirmDialogDownloadDir(const QString& dir)
{
auto text = gt("download-dir-dialog-msg");
text = text.replace("{{DIRECTORY}}", dir);
QMessageBox msgBox(
QMessageBox::Question, //Icon
gt("download-dir-dialog-title"), //Title
text, //Text
QMessageBox::Ok | QMessageBox::Cancel //Buttons
);
msgBox.setDefaultButton(QMessageBox::Ok);
int ret = msgBox.exec();
return (ret == QMessageBox::Ok);
}
void SettingsView::resetDownloadDir()
{
auto dir = QString::fromStdString(kiwix::getDataDirectory());
const auto &downloadDir = KiwixApp::instance()->getSettingsManager()->getDownloadDir();
if (dir == downloadDir) {
return;
}
if (confirmDialogDownloadDir(dir)) {
KiwixApp::instance()->getSettingsManager()->setDownloadDir(dir);
}
}
void SettingsView::browseDownloadDir()
{
const auto &downloadDir = KiwixApp::instance()->getSettingsManager()->getDownloadDir();
QString dir = QFileDialog::getExistingDirectory(KiwixApp::instance()->getMainWindow(),
gt("browse-directory"),
downloadDir,
QFileDialog::ShowDirsOnly);
if (dir == downloadDir || dir.isEmpty()) {
return;
}
if (confirmDialogDownloadDir(dir)) {
KiwixApp::instance()->getSettingsManager()->setDownloadDir(dir);
}
}
void SettingsView::setZoom(int zoomPercent)
{
qreal zoomFactor = (qreal) zoomPercent/100;
KiwixApp::instance()->getSettingsManager()->setZoomFactor(zoomFactor);
}
void SettingsView::setKiwixServerPort(int port)
{
KiwixApp::instance()->getSettingsManager()->setKiwixServerPort(port);
}
void SettingsView::onDownloadDirChanged(const QString &dir)
{
ui->downloadDirPath->setText(dir);
}
void SettingsView::onZoomChanged(qreal zoomFactor)
{
qreal zoomPercent = zoomFactor * 100;
ui->zoomPercentSpinBox->setValue(zoomPercent);
}
void SettingsView::onServerPortChanged(int port)
{
ui->serverPortSpinBox->setValue(port);
}

29
src/settingsview.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef SETTINGSVIEW_H
#define SETTINGSVIEW_H
#include <QWidget>
namespace Ui {
class Settings;
}
class SettingsView : public QWidget
{
Q_OBJECT
public:
SettingsView(QWidget *parent = nullptr);
~SettingsView(){};
void init(int port, int zoomPercent, const QString &dir);
public Q_SLOTS:
void resetDownloadDir();
void browseDownloadDir();
void setZoom(int zoomPercent);
void onDownloadDirChanged(const QString &dir);
void onZoomChanged(qreal zoomFactor);
void onServerPortChanged(int port);
void setKiwixServerPort(int port);
private:
bool confirmDialogDownloadDir(const QString& dir);
Ui::Settings *ui;
};
#endif // SETTINGSVIEW_H

View File

@ -8,7 +8,6 @@
#include <QToolTip> #include <QToolTip>
#include <QCursor> #include <QCursor>
#include <QPainter> #include <QPainter>
#define QUITIFNULL(VIEW) if (nullptr==(VIEW)) { return; } #define QUITIFNULL(VIEW) if (nullptr==(VIEW)) { return; }
#define CURRENTIFNULL(VIEW) if(nullptr==VIEW) { VIEW = currentZimView();} #define CURRENTIFNULL(VIEW) if(nullptr==VIEW) { VIEW = currentZimView();}
@ -55,16 +54,17 @@ TabBar::TabBar(QWidget *parent) :
}); });
connect(app->getAction(KiwixApp::SettingAction), &QAction::triggered, connect(app->getAction(KiwixApp::SettingAction), &QAction::triggered,
this, [=]() { this, [=]() {
for (int i = 0 ; i < (mp_stackedWidget->count() - 1) ; i++) { SettingsView* view = KiwixApp::instance()->getSettingsManager()->getView();
if (qobject_cast<SettingsManagerView*>(mp_stackedWidget->widget(i))) { for (int i = 0 ; i < mp_stackedWidget->count(); i++) {
if (mp_stackedWidget->widget(i) == view) {
setCurrentIndex(i); setCurrentIndex(i);
return; return;
} }
} }
int index = currentIndex() + 1; int index = currentIndex() + 1;
SettingsManagerView* view = KiwixApp::instance()->getSettingsManager()->getView();
mp_stackedWidget->insertWidget(index, view); mp_stackedWidget->insertWidget(index, view);
insertTab(index,QIcon(":/icons/settings.svg"), gt("settings")); insertTab(index,QIcon(":/icons/settings.svg"), gt("settings"));
KiwixApp::instance()->setSideBar(KiwixApp::SideBarType::NONE);
QToolButton *tb = new QToolButton(this); QToolButton *tb = new QToolButton(this);
tb->setDefaultAction(KiwixApp::instance()->getAction(KiwixApp::CloseTabAction)); tb->setDefaultAction(KiwixApp::instance()->getAction(KiwixApp::CloseTabAction));
setTabButton(index, QTabBar::RightSide, tb); setTabButton(index, QTabBar::RightSide, tb);
@ -294,7 +294,7 @@ void TabBar::onCurrentChanged(int index)
QWidget *w = mp_stackedWidget->widget(index); QWidget *w = mp_stackedWidget->widget(index);
if (qobject_cast<SettingsManagerView*>(w)) { if (qobject_cast<SettingsView*>(w)) {
emit webActionEnabledChanged(QWebEnginePage::Back, false); emit webActionEnabledChanged(QWebEnginePage::Back, false);
emit webActionEnabledChanged(QWebEnginePage::Forward, false); emit webActionEnabledChanged(QWebEnginePage::Forward, false);
emit libraryPageDisplayed(false); emit libraryPageDisplayed(false);

View File

@ -79,7 +79,11 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QStackedWidget" name="mainView"/> <widget class="QStackedWidget" name="mainView">
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
</widget>
</item> </item>
</layout> </layout>
</item> </item>

280
ui/settings.ui Normal file
View File

@ -0,0 +1,280 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Settings</class>
<widget class="QWidget" name="Settings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1029</width>
<height>580</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>600</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QWidget" name="widget" native="true">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="mainLayout">
<item>
<widget class="QLabel" name="settingsLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Settings</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="serverPortLabel">
<property name="text">
<string>Port for local kiwix server:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSpinBox" name="serverPortSpinBox">
<property name="frame">
<bool>false</bool>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string/>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>65535</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="zoomPercentLabel">
<property name="text">
<string>Zoom level:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSpinBox" name="zoomPercentSpinBox">
<property name="frame">
<bool>false</bool>
</property>
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<number>30</number>
</property>
<property name="maximum">
<number>500</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_2">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="downloadDirLabel">
<property name="text">
<string>Download directory:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="downloadDirPath">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="resetButton">
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>Reset</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="browseButton">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>Browse</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>