Compare commits

...

7 Commits

Author SHA1 Message Date
Xavier Del Campo Romero 6e5fd11186
WIP query dialog 2023-10-10 15:39:55 +02:00
Xavier Del Campo Romero 8cb79ee671 build.yml: Test CMake builds 2023-10-02 16:36:29 +02:00
Xavier Del Campo Romero 42022bdfd2 Add CMake-based build system 2023-10-02 16:36:29 +02:00
Xavier Del Campo Romero 317bdbad5b settingsdialog.ui: Move "Generic" widgets to QScrollArea
This would allow smaller screens (think of mobile devices such as the
PinePhone or Librem 5) to be able to fit the settings dialog, and
therefore use it.
2023-09-29 14:23:09 +02:00
Xavier Del Campo Romero 505723e9df browsertab.cpp: Use multi-line input when required
Some Gemini sites such as Station or BBS allow multi-line posts.
2023-09-29 14:22:22 +02:00
Michael Steenbeek 3709c3d6bd Use startsWith() instead of left(4) 2023-08-30 08:43:16 +02:00
Michael Steenbeek 10a9c4ccfa Support URLs in Gophermaps
Paths in Gophermaps that start with “URL:” should be interpreted as direct
URLs, rather than references to files or directories on the Gopher server
itself.

An excerpt from the standard document:
```

Links to URLs from a gopher directory shall be defined as follows:

 Type -- the appropriate character corresponding to the type of the
 document on the remote end; h if HTML.

 Path -- the full URL, preceeded by "URL:".  For instance:
         URL:http://www.complete.org/

 Host, Port -- pointing back to the gopher server that provided
 the directory for compatibility reasons.

 Name -- as usual for a Gopher directory entry.

```
Source: gopher://quux.org/0/Archives/Mailing Lists/gopher/gopher.2002-02?/MBOX-MESSAGE/34

An example of this in the wild can be seen at gopher://gopher.floodgap.com ,
at the bottom of the page.

Note that above link carries a fallback for clients that do not support it,
as described by the Bucktooth server software:
```
[...]  most people will want to add web links to their
gophers anyway. In 0.1-pr4 and up, this is supported in a protocol independent
fashion; simply specify any URL and an 'h' item type, like so:

hYour Web Link<TAB>URL:http://www.floodgap.com/

Note that the URL must be preceded by a literal "URL:" and that the itemtype
is h. Smart clients will automatically take the URL portion and use it, but
even if they do not, Bucktooth will generate an HTML page with a Refresh:
header and forward them on automatically.
```

Other clients supporting this standard include the OverbiteWX extension.
(Most likely, there will be others, but I haven’t tested them all.)
2023-08-30 08:43:16 +02:00
12 changed files with 715 additions and 304 deletions

View File

@ -33,7 +33,27 @@ jobs:
- name: make
run: make build/kristall
build_cmake:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: jurplel/install-qt-action@v2
with:
version: "5.12.8"
- name: Install OpenSSL
run: sudo apt install -y libssl-dev
- name: Configure the project
uses: threeal/cmake-action@v1.3.0
with:
build-dir: build
- name: Build the project
run: cmake --build build
# Disabled until both aqinstall and install-qt-action support the fixes…
# build_windows:
# runs-on: windows-latest

188
CMakeLists.txt Normal file
View File

@ -0,0 +1,188 @@
cmake_minimum_required(VERSION 3.13)
if(NOT KRISTALL_VERSION)
execute_process(COMMAND git describe --tags --abbrev=0
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE KRISTALL_CMAKE_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT KRISTALL_CMAKE_VERSION)
set(KRISTALL_CMAKE_VERSION "0.0.0")
endif()
execute_process(COMMAND git describe --tags
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE KRISTALL_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT KRISTALL_VERSION)
set(KRISTALL_VERSION "development")
endif()
endif()
# CMake requires the following format for versions:
# <major>[.<minor>[.<patch>[.<tweak>]]]]
string(REPLACE "V" "" KRISTALL_CMAKE_VERSION ${KRISTALL_CMAKE_VERSION})
project(kristall VERSION ${KRISTALL_CMAKE_VERSION} LANGUAGES CXX)
set(QT_VERSION_MAJOR 5)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
# QXmpp requires C++17.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 COMPONENTS
Multimedia MultimediaWidgets Network Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS
Multimedia MultimediaWidgets Network Widgets REQUIRED)
set(PROJECT_SOURCES
src/browsertab.cpp
src/certificatehelper.cpp
src/cryptoidentity.cpp
src/dialogs/certificateiodialog.cpp
src/dialogs/certificatemanagementdialog.cpp
src/dialogs/certificateselectiondialog.cpp
src/dialogs/newidentitiydialog.cpp
src/dialogs/settingsdialog.cpp
src/documentoutlinemodel.cpp
src/documentstyle.cpp
src/favouritecollection.cpp
src/identitycollection.cpp
src/ioutil.cpp
src/localization.cpp
src/main.cpp
src/mainwindow.cpp
src/renderers/htmlrenderer.cpp
src/renderers/markdownrenderer.cpp
src/renderers/renderhelpers.cpp
src/renderers/textstyleinstance.cpp
src/widgets/browsertabbar.cpp
src/widgets/browsertabwidget.cpp
src/widgets/kristalltextbrowser.cpp
src/widgets/mediaplayer.cpp
src/mimeparser.cpp
src/protocolhandler.cpp
src/protocols/abouthandler.cpp
src/protocols/filehandler.cpp
src/protocols/fingerclient.cpp
src/protocols/geminiclient.cpp
src/protocols/gopherclient.cpp
src/protocols/webclient.cpp
src/protocolsetup.cpp
src/renderers/geminirenderer.cpp
src/renderers/gophermaprenderer.cpp
src/renderers/plaintextrenderer.cpp
src/ssltrust.cpp
src/tabbrowsinghistory.cpp
src/trustedhost.cpp
src/trustedhostcollection.cpp
src/widgets/elidelabel.cpp
src/widgets/searchbar.cpp
src/widgets/ssltrusteditor.cpp
src/widgets/favouritepopup.cpp
src/widgets/favouritebutton.cpp
src/widgets/querydialog.ui
src/widgets/querydialog.cpp
src/cachehandler.cpp
src/widgets/searchbox.cpp
src/browsertab.ui
src/dialogs/certificateiodialog.ui
src/dialogs/certificatemanagementdialog.ui
src/dialogs/certificateselectiondialog.ui
src/dialogs/newidentitiydialog.ui
src/dialogs/settingsdialog.ui
src/mainwindow.ui
src/widgets/mediaplayer.ui
src/widgets/ssltrusteditor.ui
src/fonts.qrc
lib/BreezeStyleSheets/breeze.qrc
src/builtins.qrc
src/icons.qrc
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(${PROJECT_NAME}
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
if(ANDROID)
add_library(${PROJECT_NAME} SHARED
${PROJECT_SOURCES}
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(${PROJECT_NAME}
${PROJECT_SOURCES}
)
endif()
endif()
message(STATUS "Building Kristall ${KRISTALL_VERSION}")
target_compile_definitions(${PROJECT_NAME} PUBLIC
KRISTALL_VERSION=${KRISTALL_VERSION})
add_subdirectory(lib/luis-l-gist)
target_link_libraries(${PROJECT_NAME} PRIVATE luis-l-gist)
find_package(PkgConfig REQUIRED)
pkg_check_modules(cmark IMPORTED_TARGET cmark)
if(cmark_FOUND)
target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::cmark)
else()
message(STATUS "Using in-tree cmark")
add_subdirectory(lib/cmark)
target_link_libraries(${PROJECT_NAME} PRIVATE cmark)
endif()
pkg_check_modules(gumbo-parser IMPORTED_TARGET gumbo)
if(gumbo_FOUND)
target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::gumbo-parser)
else()
message(STATUS "Using in-tree gumbo-parser")
add_subdirectory(lib/gumbo-parser)
target_link_libraries(${PROJECT_NAME} PRIVATE gumbo-parser)
endif()
target_link_libraries(${PROJECT_NAME} PRIVATE
Qt${QT_VERSION_MAJOR}::Multimedia
Qt${QT_VERSION_MAJOR}::MultimediaWidgets
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Widgets)
target_include_directories(${PROJECT_NAME} PRIVATE src)
set_target_properties(${PROJECT_NAME} PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(${PROJECT_NAME})
endif()
find_package(OpenSSL 1.1 REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE OpenSSL::SSL)
if(NOT UNIX)
target_link_libraries(${PROJECT_NAME} PRIVATE iconv)
endif()

24
lib/cmark/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.13)
project(cmark C)
set(sources
src/blocks.c
src/buffer.c
src/cmark.c
src/cmark_ctype.c
src/commonmark.c
src/houdini_href_e.c
src/houdini_html_e.c
src/houdini_html_u.c
src/inlines.c
src/iterator.c
src/node.c
src/references.c
src/render.c
src/scanners.c
src/utf8.c
src/html.c
src/xml.c)
add_library(${PROJECT_NAME} ${sources})
target_include_directories(${PROJECT_NAME} PUBLIC src)

17
lib/gumbo-parser/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.13)
project(gumbo-parser C)
set(sources
attribute.c
char_ref.c
error.c
gumbo-utf8.c
parser.c
string_buffer.c
string_piece.c
tag.c
tokenizer.c
util.c
vector.c
)
add_library(${PROJECT_NAME} ${sources})
target_include_directories(${PROJECT_NAME} PUBLIC include PRIVATE .)

7
lib/luis-l-gist/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.13)
project(luis-l-gist CXX)
add_library(${PROJECT_NAME} interactiveview.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC .)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Widgets)

View File

@ -25,6 +25,7 @@
#include "kristall.hpp"
#include "widgets/favouritepopup.hpp"
#include "widgets/searchbox.hpp"
#include "widgets/querydialog.hpp"
#include <cassert>
#include <QTabWidget>
@ -867,9 +868,8 @@ void BrowserTab::on_inputRequired(const QString &query, const bool is_sensitive)
{
this->network_timeout_timer.stop();
QInputDialog dialog{this};
QueryDialog dialog(this);
dialog.setInputMode(QInputDialog::TextInput);
dialog.setLabelText(query);
if (is_sensitive) dialog.setTextEchoMode(QLineEdit::Password);

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1100</width>
<height>737</height>
<width>496</width>
<height>404</height>
</rect>
</property>
<property name="windowTitle">
@ -32,281 +32,303 @@
<string>Generic</string>
</attribute>
<layout class="QFormLayout" name="formLayout">
<item row="1" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Start Page:</string>
<item row="0" column="0" colspan="2">
<widget class="QScrollArea" name="scrollArea">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="start_page">
<property name="placeholderText">
<string>about://blank</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_40">
<property name="text">
<string>Search engine:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="search_engine">
<property name="editable">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>585</width>
<height>490</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_44">
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="selected_language"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Start Page:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="start_page">
<property name="placeholderText">
<string>about://blank</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_40">
<property name="text">
<string>Search engine:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="search_engine">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Additional toolbar buttons</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_99">
<item>
<widget class="QCheckBox" name="enable_home_btn">
<property name="text">
<string>Home</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_newtab_btn">
<property name="text">
<string>New tab</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_root_btn">
<property name="text">
<string>Root (/)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_parent_btn">
<property name="text">
<string>Parent (..)</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Startup Behaviour</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="session_restore_behaviour"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>UI Theme</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="ui_theme"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_34">
<property name="text">
<string>Icon Theme</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="icon_theme"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_1">
<property name="text">
<string>UI Density</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="ui_density"/>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Enabled Protocols</string>
</property>
</widget>
</item>
<item row="8" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="enable_gemini">
<property name="text">
<string>Gemini</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_gopher">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Gopher</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_finger">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Finger</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_http">
<property name="text">
<string>HTTP</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_https">
<property name="text">
<string>HTTPS</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Unknown Scheme</string>
</property>
</widget>
</item>
<item row="9" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QRadioButton" name="scheme_os_default">
<property name="text">
<string>Use OS default handler</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="scheme_error">
<property name="text">
<string>Display error message</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
</layout>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>Max. Number of Redirections</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QSpinBox" name="max_redirects">
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Redirection Handling</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QComboBox" name="redirection_mode"/>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_28">
<property name="text">
<string>Network Timeout</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QSpinBox" name="network_timeout">
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>90000</number>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_45">
<property name="text">
<string>Tab close behaviour</string>
</property>
</widget>
</item>
<item row="13" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QRadioButton" name="tab_keep_window">
<property name="text">
<string>Keep window open</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup_10</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="tab_close_window">
<property name="text">
<string>Close window</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup_10</string>
</attribute>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Additional toolbar buttons</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_99">
<item>
<widget class="QCheckBox" name="enable_home_btn">
<property name="text">
<string>Home</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_newtab_btn">
<property name="text">
<string>New tab</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_root_btn">
<property name="text">
<string>Root (/)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_parent_btn">
<property name="text">
<string>Parent (..)</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Startup Behaviour</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="session_restore_behaviour"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>UI Theme</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="ui_theme"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_34">
<property name="text">
<string>Icon Theme</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="icon_theme"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_1">
<property name="text">
<string>UI Density</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="ui_density"/>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Enabled Protocols</string>
</property>
</widget>
</item>
<item row="8" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="enable_gemini">
<property name="text">
<string>Gemini</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_gopher">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Gopher</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_finger">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Finger</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_http">
<property name="text">
<string>HTTP</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enable_https">
<property name="text">
<string>HTTPS</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Unknown Scheme</string>
</property>
</widget>
</item>
<item row="9" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QRadioButton" name="scheme_os_default">
<property name="text">
<string>Use OS default handler</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="scheme_error">
<property name="text">
<string>Display error message</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
</layout>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>Max. Number of Redirections</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QSpinBox" name="max_redirects">
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Redirection Handling</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QComboBox" name="redirection_mode"/>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_28">
<property name="text">
<string>Network Timeout</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QSpinBox" name="network_timeout">
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>90000</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_44">
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="selected_language"/>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_45">
<property name="text">
<string>Tab close behaviour</string>
</property>
</widget>
</item>
<item row="13" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QRadioButton" name="tab_keep_window">
<property name="text">
<string>Keep window open</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup_10</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="tab_close_window">
<property name="text">
<string>Close window</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup_10</string>
</attribute>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="display_tab">
@ -705,9 +727,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>530</width>
<height>712</height>
<y>-351</y>
<width>570</width>
<height>783</height>
</rect>
</property>
<layout class="QFormLayout" name="style_scroll_layout">
@ -1619,9 +1641,6 @@
</customwidget>
</customwidgets>
<tabstops>
<tabstop>ui_theme</tabstop>
<tabstop>icon_theme</tabstop>
<tabstop>ui_density</tabstop>
<tabstop>enable_gemini</tabstop>
<tabstop>enable_gopher</tabstop>
<tabstop>enable_finger</tabstop>
@ -1629,9 +1648,6 @@
<tabstop>enable_https</tabstop>
<tabstop>scheme_os_default</tabstop>
<tabstop>scheme_error</tabstop>
<tabstop>max_redirects</tabstop>
<tabstop>redirection_mode</tabstop>
<tabstop>network_timeout</tabstop>
<tabstop>enable_home_btn</tabstop>
<tabstop>enable_newtab_btn</tabstop>
<tabstop>enable_root_btn</tabstop>
@ -1714,15 +1730,15 @@
</connection>
</connections>
<buttongroups>
<buttongroup name="buttonGroup_2"/>
<buttongroup name="buttonGroup_7"/>
<buttongroup name="buttonGroup_5"/>
<buttongroup name="buttonGroup"/>
<buttongroup name="buttonGroup_6"/>
<buttongroup name="buttonGroup_8"/>
<buttongroup name="buttonGroup_3"/>
<buttongroup name="buttonGroup_7"/>
<buttongroup name="buttonGroup_4"/>
<buttongroup name="buttonGroup_9"/>
<buttongroup name="buttonGroup_10"/>
<buttongroup name="buttonGroup_8"/>
<buttongroup name="buttonGroup_2"/>
<buttongroup name="buttonGroup_6"/>
<buttongroup name="buttonGroup_9"/>
</buttongroups>
</ui>

View File

@ -218,7 +218,8 @@ FORMS += \
dialogs/settingsdialog.ui \
mainwindow.ui \
widgets/mediaplayer.ui \
widgets/ssltrusteditor.ui
widgets/ssltrusteditor.ui \
widgets/querydialog.ui
CONFIG += lrelease embed_translations

View File

@ -156,21 +156,32 @@ std::unique_ptr<QTextDocument> GophermapRenderer::render(const QByteArray &input
else
{
QString dst_url;
switch (items.size())
// If a resources path starts with “URL:”, it is a direct link (to HTTP or another protocol), rather than a file or directory on this server.
if (items.size() >= 2 && items.at(1).startsWith("URL:"))
{
case 0:
assert(false);
case 1:
assert(false);
case 2:
dst_url = root_url.resolved(QUrl(items.at(1))).toString();
break;
case 3:
dst_url = scheme + "://" + items.at(2) + "/" + QString(type) + items.at(1);
break;
default:
dst_url = scheme + "://" + items.at(2) + ":" + items.at(3) + "/" + QString(type) + items.at(1);
break;
auto item1 = QString(items.at(1));
item1.remove(0, 4);
dst_url = item1;
}
else
{
switch (items.size())
{
case 0:
assert(false);
case 1:
assert(false);
case 2:
dst_url = root_url.resolved(QUrl(items.at(1))).toString();
break;
case 3:
dst_url = scheme + "://" + items.at(2) + "/" + QString(type) + items.at(1);
break;
default:
dst_url = scheme + "://" + items.at(2) + ":" + items.at(3) + "/" + QString(type) + items.at(1);
break;
}
}
if (not QUrl(dst_url).isValid())

View File

@ -0,0 +1,30 @@
#include "widgets/querydialog.hpp"
QueryDialog::QueryDialog(QWidget *parent) :
QDialog(parent),
mode(QLineEdit::Normal)
{
ui.setupUi(this);
ui.lineEdit->setVisible(false);
}
void QueryDialog::setLabelText(const QString &text)
{
ui.query->setText(text);
}
void QueryDialog::setTextEchoMode(QLineEdit::EchoMode mode)
{
ui.text->setVisible(mode == QLineEdit::Normal);
ui.lineEdit->setVisible(mode != QLineEdit::Normal);
ui.lineEdit->setEchoMode(mode);
this->mode = mode;
}
QString QueryDialog::textValue()
{
if (mode == QLineEdit::Normal)
return ui.text->toPlainText();
return ui.lineEdit->text();
}

View File

@ -0,0 +1,20 @@
#ifndef QUERYDIALOG_H
#define QUERYDIALOG_H
#include "ui_querydialog.h"
#include <QDialog>
#include <QLineEdit>
#include <QString>
class QueryDialog : public QDialog {
public:
QueryDialog(QWidget *parent);
void setLabelText(const QString &text);
void setTextEchoMode(QLineEdit::EchoMode mode);
QString textValue();
private:
Ui_QueryDialog ui;
QLineEdit::EchoMode mode;
};
#endif

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QueryDialog</class>
<widget class="QDialog" name="QueryDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>480</width>
<height>240</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="query">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="text"/>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QueryDialog</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>QueryDialog</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>