aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/Development.asciidoc9
-rw-r--r--doc/Development/Fuzzing.asciidoc49
-rw-r--r--lib/configuration/configuration.cpp2
-rw-r--r--meson.build2
-rw-r--r--src/mainwindow/mainwindow.cpp11
-rw-r--r--src/meson.build12
-rw-r--r--src/session/sessiondialog.cpp87
-rw-r--r--src/session/sessiondialog.h34
-rw-r--r--src/session/sessiondialog.ui96
-rw-r--r--src/session/sessionform.cpp36
-rw-r--r--src/session/sessionform.h37
-rw-r--r--src/session/sessionform.ui41
-rwxr-xr-xtools/format-code.sh4
13 files changed, 407 insertions, 13 deletions
diff --git a/doc/Development.asciidoc b/doc/Development.asciidoc
index c849d67..1ef2ded 100644
--- a/doc/Development.asciidoc
+++ b/doc/Development.asciidoc
@@ -15,6 +15,15 @@ extensions. Source code should be kept as platform-agnostic as possible.
syntax (SIGNAL/SLOT). This enables compile-time connect checks.
* Prefer QVector over QList: http://lists.qt-project.org/pipermail/development/2017-March/029040.html
+=== Setting linker
+Meson has no environment variable to set the linker (link:https://github.com/mesonbuild/meson/issues/3597[issue]).
+
+Instead, this can be done using the cpp_link_args:
+[source, sh]
+----
+build% meson configure -Dcpp_link_args='-fuse-ld=gold'
+----
+
=== clazy
You can use https://github.com/KDE/clazy[clazy] to check Qt semantics.
diff --git a/doc/Development/Fuzzing.asciidoc b/doc/Development/Fuzzing.asciidoc
new file mode 100644
index 0000000..0981f1a
--- /dev/null
+++ b/doc/Development/Fuzzing.asciidoc
@@ -0,0 +1,49 @@
+=== Setup
+Required packages: afl
+
+==== Compiling Qt
+This will build an instrumented Qt:
+
+[source, sh]
+----
+export CC=$(which afl-gcc)
+export CXX=$(which afl-g++)
+./configure ...
+make
+----
+
+=== Running the fuzzer
+[source, sh]
+----
+cd /sys/devices/system/cpu
+su
+echo performance | tee cpu*/cpufreq/scaling_governor
+exit
+
+cd $testdir
+afl-fuzz -m 512 -t 40 -i $input -o $output -- $testexe @@
+
+# see for available scaling_governor values:
+cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
+
+cd /sys/devices/system/cpu
+su
+echo powersave | tee cpu*/cpufreq/scaling_governor
+exit
+----
+
+The $input directory contains your reference input files, while the findings of the fuzzers will be written in $output.
+
+@@ gets replaced by the name of a file generated by AFL, containing the mutated input.
+
+=== Using ramdisk for tests
+[source, sh]
+----
+$ mkdir afl
+# mount -t tmpfs -o size=1024M tmpfs afl/
+$ cd afl/
+$ afl-fuzz -i inputs -o findings ...
+----
+
+=== Sources
+1. https://www.kdab.com/fuzzing-qt-fun-profit/
diff --git a/lib/configuration/configuration.cpp b/lib/configuration/configuration.cpp
index 388c7bd..398044b 100644
--- a/lib/configuration/configuration.cpp
+++ b/lib/configuration/configuration.cpp
@@ -55,6 +55,8 @@ Configuration::Configuration(QObject *parent)
("browser.locale", po::value<std::string>(), "Set Qt localization.")
("browser.translation", po::value<std::string>(), "Set application localization.")
+ ("browser.session.path", po::value<std::string>()->default_value("~/.config/smolbote/session.d"))
+
#ifdef CONFIG_USEBREAKPAD
("browser.crash.path", po::value<std::string>()->default_value(CONFIG_PATH_CRASHDUMP))
("browser.crash.handler", po::value<std::string>()->default_value(CONFIG_PATH_CRASHHANDLER))
diff --git a/meson.build b/meson.build
index 25fced3..06d52b6 100644
--- a/meson.build
+++ b/meson.build
@@ -26,7 +26,7 @@ dep_plasma = declare_dependency(
)
# add -DQT_NO_DEBUG to non-debug builds
-if not get_option('buildtype').startswith('debug')
+if not get_option('debug')
add_global_arguments('-DQT_NO_DEBUG', language: 'cpp')
endif
diff --git a/src/mainwindow/mainwindow.cpp b/src/mainwindow/mainwindow.cpp
index 8f635c9..80e4faa 100644
--- a/src/mainwindow/mainwindow.cpp
+++ b/src/mainwindow/mainwindow.cpp
@@ -13,6 +13,7 @@
#include "configuration.h"
#include "profilemanager.h"
#include "session.h"
+#include "session/sessiondialog.h"
#include "subwindow/subwindow.h"
#include "ui_mainwindow.h"
#include "webengine/webview.h"
@@ -126,14 +127,8 @@ MainWindow::MainWindow(const std::unique_ptr<Configuration> &config, QWidget *pa
}
});
connect(ui->actionLoadSession, &QAction::triggered, this, [this]() {
- const QString filename = QFileDialog::getOpenFileName(this, tr("Load Session"), QDir::homePath(), tr("JSON (*.json)"));
- QFile json(filename);
- if(json.open(QIODevice::ReadOnly | QIODevice::Text)) {
- auto *browser = qobject_cast<Browser *>(qApp);
- auto doc = QJsonDocument::fromJson(json.readAll());
- browser->createSession(doc.object());
- json.close();
- }
+ auto *sessionDialog = new SessionDialog(this);
+ sessionDialog->exec();
});
}
diff --git a/src/meson.build b/src/meson.build
index f99d0c7..5df5a36 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,10 +1,11 @@
# poi
poi_moc = qt5.preprocess(
moc_headers: ['browser.h',
- 'mainwindow/mainwindow.h', 'mainwindow/widgets/dockwidget.h', 'mainwindow/widgets/navigationbar.h', 'mainwindow/widgets/searchform.h',
- 'subwindow/subwindow.h', 'subwindow/tabwidget.h',
+ 'mainwindow/mainwindow.h', 'mainwindow/widgets/dockwidget.h', 'mainwindow/widgets/navigationbar.h', 'mainwindow/widgets/searchform.h',
+ 'session/sessiondialog.h', 'session/sessionform.h',
+ 'subwindow/subwindow.h', 'subwindow/tabwidget.h',
'webengine/filter.h', 'webengine/urlinterceptor.h', 'webengine/webpage.h', 'webengine/webview.h'],
- ui_files: ['mainwindow/mainwindow.ui', 'mainwindow/widgets/searchform.ui'],
+ ui_files: ['mainwindow/mainwindow.ui', 'mainwindow/widgets/searchform.ui', 'session/sessiondialog.ui', 'session/sessionform.ui'],
qresources: '../data/resources.qrc',
rcc_extra_arguments: ['--format-version=1'],
dependencies: dep_qt5
@@ -32,7 +33,10 @@ poi = executable(get_option('poiName'), install: true,
'mainwindow/mainwindow.cpp',
'mainwindow/widgets/dockwidget.cpp',
'mainwindow/widgets/navigationbar.cpp',
- 'mainwindow/widgets/searchform.cpp',
+ 'mainwindow/widgets/searchform.cpp',
+
+ 'session/sessiondialog.cpp',
+ 'session/sessionform.cpp',
'subwindow/subwindow.cpp',
'subwindow/tabwidget.cpp',
diff --git a/src/session/sessiondialog.cpp b/src/session/sessiondialog.cpp
new file mode 100644
index 0000000..e31a42f
--- /dev/null
+++ b/src/session/sessiondialog.cpp
@@ -0,0 +1,87 @@
+/*
+ * This file is part of smolbote. It's copyrighted by the contributors recorded
+ * in the version control history of the file, available from its original
+ * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#include "sessiondialog.h"
+#include "../browser.h"
+#include "../util.h"
+#include "sessionform.h"
+#include "ui_sessiondialog.h"
+#include "ui_sessionform.h"
+#include <QFile>
+#include <QFileDialog>
+#include <QToolButton>
+#include <QStyle>
+
+SessionDialog::SessionDialog(QWidget *parent)
+ : QDialog(parent)
+ , ui(new Ui::SessionDialog)
+{
+ ui->setupUi(this);
+ ui->open->setIcon(style()->standardIcon(QStyle::SP_DirOpenIcon));
+
+ auto *browser = qobject_cast<Browser *>(qApp);
+ Q_CHECK_PTR(browser);
+
+ for(const QString &path : Util::files(browser->configuration("browser.session.path"), { "*.json" })) {
+ auto *item = new QListWidgetItem(ui->listWidget);
+ auto *widget = new SessionForm(path, this);
+ connect(widget->ui->delete_toolButton, &QToolButton::clicked, this, [item, widget]() {
+ delete item;
+ delete widget;
+ });
+ ui->listWidget->setItemWidget(item, widget);
+ }
+
+#ifdef QT_DEBUG
+ ui->listWidget->addItem(tr("Start new session"));
+#endif
+
+ connect(ui->listWidget, &QListWidget::currentItemChanged, this, [this](QListWidgetItem *currentItem, QListWidgetItem *previousItem) {
+ auto *currentWidget = qobject_cast<SessionForm *>(ui->listWidget->itemWidget(currentItem));
+ if(currentWidget)
+ currentWidget->ui->delete_toolButton->show();
+
+ auto *previousWidget = qobject_cast<SessionForm *>(ui->listWidget->itemWidget(previousItem));
+ if(previousWidget)
+ previousWidget->ui->delete_toolButton->hide();
+ });
+
+ connect(ui->open, &QPushButton::clicked, this, [this]() {
+ const QString filename = QFileDialog::getOpenFileName(this, tr("Select Session file"), QDir::homePath(), tr("JSON (*.json)"));
+ if(!filename.isEmpty()) {
+ this->openSession(filename);
+ // close the dialog window; reject so it doesn't open another session
+ this->reject();
+ }
+ });
+
+ connect(this, &SessionDialog::accepted, this, [this]() {
+ auto *currentWidget = qobject_cast<SessionForm *>(ui->listWidget->itemWidget(ui->listWidget->currentItem()));
+ if(currentWidget)
+ this->openSession(currentWidget->ui->label->text());
+ });
+}
+
+SessionDialog::~SessionDialog()
+{
+ delete ui;
+}
+
+void SessionDialog::openSession(const QString &filename)
+{
+ auto *browser = qobject_cast<Browser *>(qApp);
+ Q_CHECK_PTR(browser);
+
+ QFile json(filename);
+ if(json.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ auto *browser = qobject_cast<Browser *>(qApp);
+ auto doc = QJsonDocument::fromJson(json.readAll());
+ browser->createSession(doc.object());
+ json.close();
+ }
+}
diff --git a/src/session/sessiondialog.h b/src/session/sessiondialog.h
new file mode 100644
index 0000000..7fea3c2
--- /dev/null
+++ b/src/session/sessiondialog.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of smolbote. It's copyrighted by the contributors recorded
+ * in the version control history of the file, available from its original
+ * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#ifndef SMOLBOTE_SESSIONDIALOG_H
+#define SMOLBOTE_SESSIONDIALOG_H
+
+#include <QDialog>
+
+namespace Ui
+{
+class SessionDialog;
+}
+
+class SessionDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SessionDialog(QWidget *parent = nullptr);
+ ~SessionDialog() override;
+
+private:
+ void openSession(const QString &filename);
+
+private:
+ Ui::SessionDialog *ui;
+};
+
+#endif // SMOLBOTE_SESSIONDIALOG_H
diff --git a/src/session/sessiondialog.ui b/src/session/sessiondialog.ui
new file mode 100644
index 0000000..3a61dc1
--- /dev/null
+++ b/src/session/sessiondialog.ui
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SessionDialog</class>
+ <widget class="QDialog" name="SessionDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1000</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Select Session</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Filter</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit">
+ <property name="placeholderText">
+ <string>Search</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listWidget"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QPushButton" name="open">
+ <property name="text">
+ <string>Open from File</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Open</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>SessionDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>SessionDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/session/sessionform.cpp b/src/session/sessionform.cpp
new file mode 100644
index 0000000..761cb42
--- /dev/null
+++ b/src/session/sessionform.cpp
@@ -0,0 +1,36 @@
+/*
+ * This file is part of smolbote. It's copyrighted by the contributors recorded
+ * in the version control history of the file, available from its original
+ * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#include "sessionform.h"
+#include "ui_sessionform.h"
+#include <QStyle>
+
+SessionForm::SessionForm(const QString &path, QWidget *parent)
+ : QWidget(parent)
+ , ui(new Ui::SessionForm)
+{
+ ui->setupUi(this);
+ ui->label->setText(path);
+ ui->delete_toolButton->setIcon(style()->standardIcon(QStyle::SP_TrashIcon));
+ ui->delete_toolButton->hide();
+}
+
+SessionForm::~SessionForm()
+{
+ delete ui;
+}
+
+void SessionForm::showDetails()
+{
+ ui->delete_toolButton->show();
+}
+
+void SessionForm::hideDetails()
+{
+ ui->delete_toolButton->hide();
+}
diff --git a/src/session/sessionform.h b/src/session/sessionform.h
new file mode 100644
index 0000000..5e5f52e
--- /dev/null
+++ b/src/session/sessionform.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of smolbote. It's copyrighted by the contributors recorded
+ * in the version control history of the file, available from its original
+ * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
+ *
+ * SPDX-License-Identifier: GPL-3.0
+ */
+
+#ifndef SMOLBOTE_SESSIONFORM_H
+#define SMOLBOTE_SESSIONFORM_H
+
+#include <QWidget>
+
+namespace Ui
+{
+class SessionForm;
+}
+
+class SessionForm : public QWidget
+{
+ Q_OBJECT
+
+ friend class SessionDialog;
+
+public:
+ explicit SessionForm(const QString &path, QWidget *parent = nullptr);
+ ~SessionForm() override;
+
+public slots:
+ void showDetails();
+ void hideDetails();
+
+private:
+ Ui::SessionForm *ui;
+};
+
+#endif // SMOLBOTE_SESSIONFORM_H
diff --git a/src/session/sessionform.ui b/src/session/sessionform.ui
new file mode 100644
index 0000000..dbf0237
--- /dev/null
+++ b/src/session/sessionform.ui
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SessionForm</class>
+ <widget class="QWidget" name="SessionForm">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>711</width>
+ <height>34</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="delete_toolButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/format-code.sh b/tools/format-code.sh
new file mode 100755
index 0000000..68be1d8
--- /dev/null
+++ b/tools/format-code.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+# get names of staged files | filter out the header and cpp files | clang-format them
+git diff --staged --name-only | grep --regex="\.h\|\.cpp" | xargs clang-format -i