diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..66a7170 --- /dev/null +++ b/.clangd @@ -0,0 +1,19 @@ +CompileFlags: + Add: + - -I/usr/include/qt6 + - -I/usr/include/qt6/QtCore + - -I/usr/include/qt6/QtGui + - -I/usr/include/qt6/QtWidgets + - -I/usr/include/qt6/QtWebEngineCore + - -I/usr/include/qt6/QtWebEngineWidgets + - -I/usr/include/qt6/QtNetwork + - -I/usr/include/qt6/QtXml + - -I/usr/include/qt6/QtPrintSupport + - -I/usr/include/qt6/QtWebChannel + - -I/usr/include/qt6/QtQml + - -I/usr/include/qt6/QtQmlIntegration + - -I/usr/include/qt6/QtPositioning + - -Isrc + - -x + - c++ + - -std=c++20 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1463607..a9f3235 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,8 @@ jobs: qt6-base-dev \ qt6-tools-dev-tools \ qt6-webengine-dev \ + libwebkit2gtk-4.1-dev \ + libgtk-3-dev \ zlib1g-dev - name: Build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bbc05b1..411a42a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,6 +42,8 @@ jobs: qt6-base-dev \ qt6-tools-dev-tools \ qt6-webengine-dev \ + libwebkit2gtk-4.1-dev \ + libgtk-3-dev \ shared-mime-info \ zlib1g-dev diff --git a/.gitignore b/.gitignore index 2f6c4ec..bbebf3e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,19 @@ /safe-exam-browser /seb-linux-qt /*.o +/*.a +/*.so* /.qmake.stash +/.moc/ +/.obj/ +/.rcc/ /moc_* /ui_* /qrc_* /build/ /dist/ -/windows/ \ No newline at end of file +/windows/ +/compile_commands.json +/.clangd/ +/.vscode/ +/.idea/ diff --git a/README.md b/README.md index 5599ef3..0efb994 100644 --- a/README.md +++ b/README.md @@ -3,107 +3,48 @@ # Safe Exam Browser for Linux - **A native Linux implementation of Safe Exam Browser, built with Qt 6 and Qt WebEngine.** + Hey there! This is a community-driven, native Linux version of Safe Exam Browser. We built it with Qt 6 to give Linux users a reliable way to take exams without needing a specific OS. -## Overview +## What is this? -This project provides a native Linux client focused on: +We're trying to make SEB work great on Linux. This client handles all the important stuff like `.seb` files and special links (`seb://`), so you can just focus on your exam. -- Reliable startup and kiosk-like exam runtime behavior -- Linux desktop integration (file associations and protocol handling) -- Packaging and distribution for common Linux ecosystems +### Running Everywhere +One cool thing we did is make the browser engine flexible. +- Most people will use **Qt WebEngine** (it's fast and integrated). +- If your system doesn't support it, we automatically try to use **WebKitGTK** as a backup. -It supports: +This means SEB should "just work" on pretty much any Linux device you throw at it. -- Opening `.seb` configuration files -- Handling `seb://` and `sebs://` links -- Running as an installed Linux desktop application +## Getting Started -> [!IMPORTANT] -> This repository is an independent Linux implementation and is **not** an official Safe Exam Browser release. - -## Prerequisites - -Make sure your environment has the dependencies required for a Qt 6 + Qt WebEngine desktop build. - -## Build +### Prerequisites +You'll need the usual Qt 6 development tools. If you're on something like RISC-V where Qt WebEngine isn't around, make sure you've got `libwebkit2gtk-4.1-dev` and `libgtk-3-dev` installed so we can use the fallback engine. +### How to Build +It's pretty simple: ```bash ./scripts/build.sh ``` +You'll find the binary at `build/bin/safe-exam-browser`. -Compiled binary output: - -```bash -build/bin/safe-exam-browser -``` - -## Run - -Start with default behavior: - -```bash -./build/bin/safe-exam-browser -``` - -Open a local exam file: - -```bash -./build/bin/safe-exam-browser /path/to/exam.seb -``` - -Open a remote exam link: - -```bash -./build/bin/safe-exam-browser sebs://demo.safeexambrowser.org/exams/DemoExamGeneral.seb -``` - -Run with a JSON config file: - +### Running an Exam +Just point it at your `.seb` file: ```bash -./build/bin/safe-exam-browser --config ./examples/minimal-config.json +./build/bin/safe-exam-browser /path/to/my-exam.seb ``` - -## Create Release Artifacts - +Or use a link: ```bash -./scripts/build-release.sh 0.1.0 +./build/bin/safe-exam-browser sebs://exam-link.seb ``` -Release files are written to `dist/`. - -Prebuilt binaries are available from the GitHub Releases page. - -## Installation - -### Debian/Ubuntu - -```bash -sudo apt install ./dist/safe-exam-browser_0.1.0_amd64.deb -``` +## Troubleshooting & Support -### Arch Linux +If you run the app and see a message saying **"Safe Exam Browser is not supported on your device"**, it means we couldn't find a compatible browser engine on your system. -```bash -cd packaging/arch -makepkg -si -``` - -## Contributing - -Please review these files before opening a PR: - -- [CONTRIBUTING.md](./CONTRIBUTING.md) -- [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) -- [SECURITY.md](./SECURITY.md) - -Quick copy/open helper: - -```bash -cat CONTRIBUTING.md CODE_OF_CONDUCT.md SECURITY.md -``` +We want to fix that! please [open an issue here](https://github.com/Jvr2022/seb-linux/issues) with some details about your system and what version of Linux you're using. ## License -Licensed under the terms in `LICENSE`. +This is an open-source project licensed under the `MPL2`. Check the `LICENSE` file for the legalese. diff --git a/bin/safe-exam-browser b/bin/safe-exam-browser new file mode 100755 index 0000000..64cd70d Binary files /dev/null and b/bin/safe-exam-browser differ diff --git a/packaging/arch/PKGBUILD b/packaging/arch/PKGBUILD index d5d9ae8..2f4b3c7 100644 --- a/packaging/arch/PKGBUILD +++ b/packaging/arch/PKGBUILD @@ -2,10 +2,10 @@ pkgname=safe-exam-browser pkgver=0.1.0 pkgrel=1 pkgdesc="Qt-based Linux port of Safe Exam Browser" -arch=('x86_64') +arch=('x86_64' 'aarch64' 'riscv64') url="https://github.com/example/safe-exam-browser-linux" license=('MPL2') -depends=('qt6-base' 'qt6-webengine' 'zlib' 'hicolor-icon-theme' 'shared-mime-info' 'desktop-file-utils' 'polkit') +depends=('qt6-base' 'qt6-webengine' 'webkit2gtk-4.1' 'gtk3' 'zlib' 'hicolor-icon-theme' 'shared-mime-info' 'desktop-file-utils' 'polkit') makedepends=('qt6-tools' 'gcc' 'make') source=("safe-exam-browser-${pkgver}.tar.gz") sha256sums=('SKIP') diff --git a/packaging/linux/safe-exam-browser.metainfo.xml b/packaging/linux/safe-exam-browser.metainfo.xml index 2b80a4b..e97fff2 100644 --- a/packaging/linux/safe-exam-browser.metainfo.xml +++ b/packaging/linux/safe-exam-browser.metainfo.xml @@ -10,7 +10,7 @@ safe-exam-browser.desktop -

Safe Exam Browser for Linux with `.seb` file loading, `seb://` and `sebs://` protocol handling, remote configuration loading, and a Qt WebEngine runtime.

+

Safe Exam Browser for Linux with `.seb` file loading, `seb://` and `sebs://` protocol handling, remote configuration loading, and a Qt WebEngine runtime when that browser engine is available.

Education diff --git a/scripts/build-release.sh b/scripts/build-release.sh index 4d61f59..adf6629 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -19,14 +19,15 @@ make INSTALL_ROOT="${STAGE_DIR}" install popd >/dev/null mkdir -p "${ARTIFACT_DIR}/debian/DEBIAN" +DP_ARCH=$(dpkg --print-architecture 2>/dev/null || echo "amd64") cat > "${ARTIFACT_DIR}/debian/DEBIAN/control" </dev/null -qmake6 ../seb-linux-qt.pro +qmake6 ../seb-linux-qt.pro "$@" make -j"$(nproc)" popd >/dev/null diff --git a/seb-linux-qt.pro b/seb-linux-qt.pro index affad3a..a156b17 100644 --- a/seb-linux-qt.pro +++ b/seb-linux-qt.pro @@ -1,4 +1,32 @@ -QT += core gui widgets network xml webenginecore webenginewidgets +QT += core gui widgets network xml + +# Safe Exam Browser for Linux: Browser Engine Detection +# We support Qt WebEngine (primary) and WebKitGTK (fallback for RISC-V/Older systems). +equals(QT_MAJOR_VERSION, 6):qtHaveModule(webenginecore):qtHaveModule(webenginewidgets) { + QT += webenginecore webenginewidgets + DEFINES += SEB_HAS_QTWEBENGINE=1 + DEFINES += SEB_HAS_ANY_ENGINE=1 +} else { + DEFINES += SEB_HAS_QTWEBENGINE=0 + # Check for WebKitGTK using pkg-config + CONFIG += link_pkgconfig + packagesExist(webkit2gtk-4.1 gtk+-3.0) { + DEFINES += SEB_HAS_WEBKITGTK=1 + DEFINES += SEB_HAS_ANY_ENGINE=1 + PKGCONFIG += webkit2gtk-4.1 gtk+-3.0 + message("Building with WebKitGTK fallback (QtWebEngine not found or unsupported).") + } else { + DEFINES += SEB_HAS_ANY_ENGINE=0 + warning("No supported browser engine found (QtWebEngine/WebKitGTK missing). The app will show an error on startup.") + } +} + +# Dev Bypass Build Option +# Usage: qmake CONFIG+=dev_bypass +dev_bypass { + DEFINES += SEB_DEV_BYPASS_DEFAULT=1 + message("Building with PERSISTENT developer bypass enabled.") +} CONFIG += c++20 console warn_on object_parallel_to_source TEMPLATE = app @@ -83,14 +111,16 @@ SOURCES += \ src/browser/BrowserControl.cpp \ src/browser/BrowserWindow.cpp \ src/browser/Clipboard.cpp \ - src/browser/content/ContentLoader.cpp \ - src/browser/filters/RequestFilter.cpp \ - src/browser/filters/RuleFactory.cpp \ - src/browser/filters/rules/RegexRule.cpp \ - src/browser/filters/rules/SimplifiedRule.cpp \ + src/browser/engines/qtwebengine/qt_webengine_profile.cpp \ + src/browser/engines/qtwebengine/qt_webengine_provider.cpp \ + src/browser/engines/qtwebengine/qt_webengine_view.cpp \ + src/browser/engines/webkitgtk/webkitgtk_profile.cpp \ + src/browser/engines/webkitgtk/webkitgtk_provider.cpp \ + src/browser/engines/webkitgtk/webkitgtk_view.cpp \ src/browser/key_generator.cpp \ src/browser/request_filter.cpp \ src/browser/request_interceptor.cpp \ + src/browser/engines/engine_factory.cpp \ src/browser/webengine_environment.cpp \ src/app_controller.cpp \ src/main.cpp \ @@ -122,14 +152,13 @@ SOURCES += \ src/ui/seb_taskbar.cpp \ src/seb_settings.cpp \ src/seb_session.cpp \ + src/security/security_service.cpp \ src/browser_window.cpp - HEADERS += \ src/app_controller.h \ src/applications/application_factory.h \ src/applications/application_manager.h \ src/applications/application_window.h \ - src/applications/contracts/Properties/AssemblyInfo.h \ src/applications/contracts/application.h \ src/applications/contracts/application_factory.h \ src/applications/contracts/application_window.h \ @@ -156,8 +185,6 @@ HEADERS += \ src/client/responsibilities/client_responsibility.h \ src/client/responsibilities/client_task.h \ src/client/responsibilities/shell_responsibility.h \ - src/communication/Properties/AssemblyInfo.h \ - src/communication/contracts/Properties/AssemblyInfo.h \ src/communication/contracts/data/authentication_response.h \ src/communication/contracts/data/configuration_response.h \ src/communication/contracts/data/connection_response.h \ @@ -285,128 +312,25 @@ HEADERS += \ src/browser/BrowserApplication.h \ src/browser/BrowserApplicationContext.h \ src/browser/BrowserControl.h \ - src/browser/BrowserIconResource.h \ src/browser/BrowserWindow.h \ src/browser/BrowserWindowContext.h \ src/browser/Clipboard.h \ - src/browser/Properties/AssemblyInfo.h \ src/browser/contracts/IBrowserApplication.h \ src/browser/contracts/IBrowserWindow.h \ - src/browser/contracts/Properties/AssemblyInfo.h \ - src/browser/contracts/events/download_event_args.h \ - src/browser/contracts/events/download_finished_callback.h \ - src/browser/contracts/events/download_requested_event_handler.h \ - src/browser/contracts/events/lose_focus_requested_event_handler.h \ - src/browser/contracts/events/tab_pressed_event_handler.h \ - src/browser/contracts/events/termination_requested_event_handler.h \ - src/browser/contracts/events/user_identifier_detected_event_handler.h \ - src/browser/contracts/filters/IRequestFilter.h \ - src/browser/contracts/filters/IRule.h \ - src/browser/contracts/filters/IRuleFactory.h \ - src/browser/contracts/filters/request.h \ - src/browser/content/ContentLoader.h \ - src/browser/events/clipboard_changed_event_handler.h \ - src/browser/events/dialog_requested_event_args.h \ - src/browser/events/dialog_requested_event_handler.h \ - src/browser/events/download_aborted_event_handler.h \ - src/browser/events/download_updated_event_handler.h \ - src/browser/events/favicon_changed_event_handler.h \ - src/browser/events/javascript_dialog_requested_event_args.h \ - src/browser/events/javascript_dialog_requested_event_handler.h \ - src/browser/events/javascript_dialog_type.h \ - src/browser/events/popup_requested_event_args.h \ - src/browser/events/popup_requested_event_handler.h \ - src/browser/events/progress_changed_event_handler.h \ - src/browser/events/reset_requested_event_handler.h \ - src/browser/events/url_event_handler.h \ - src/browser/events/window_closed_event_handler.h \ - src/browser/filters/RequestFilter.h \ - src/browser/filters/RuleFactory.h \ - src/browser/filters/rules/RegexRule.h \ - src/browser/filters/rules/SimplifiedRule.h \ - src/browser/handlers/ContextMenuHandler.h \ - src/browser/handlers/CookieVisitor.h \ - src/browser/handlers/DialogHandler.h \ - src/browser/handlers/DisplayHandler.h \ - src/browser/handlers/DownloadHandler.h \ - src/browser/handlers/DragHandler.h \ - src/browser/handlers/FocusHandler.h \ - src/browser/handlers/JavaScriptDialogHandler.h \ - src/browser/handlers/KeyboardHandler.h \ - src/browser/handlers/RenderProcessMessageHandler.h \ - src/browser/handlers/RequestHandler.h \ - src/browser/handlers/ResourceHandler.h \ - src/browser/integrations/EdxIntegration.h \ - src/browser/integrations/GenericIntegration.h \ - src/browser/integrations/Integration.h \ - src/browser/integrations/MoodleIntegration.h \ + src/browser/contracts/i_engine_provider.h \ + src/browser/contracts/i_webprofile.h \ + src/browser/contracts/i_webview.h \ + src/browser/engines/qtwebengine/qt_webengine_profile.h \ + src/browser/engines/qtwebengine/qt_webengine_provider.h \ + src/browser/engines/qtwebengine/qt_webengine_view.h \ + src/browser/engines/webkitgtk/webkitgtk_profile.h \ + src/browser/engines/webkitgtk/webkitgtk_provider.h \ + src/browser/engines/webkitgtk/webkitgtk_view.h \ src/browser/key_generator.h \ src/browser/request_filter.h \ src/browser/request_interceptor.h \ - src/browser/responsibilities/BrowserTask.h \ - src/browser/responsibilities/WindowTask.h \ - src/browser/responsibilities/browser/BrowserResponsibility.h \ - src/browser/responsibilities/browser/CacheResponsibility.h \ - src/browser/responsibilities/browser/ConfigurationResponsibility.h \ - src/browser/responsibilities/browser/FileSystemResponsibility.h \ - src/browser/responsibilities/browser/IntegrityResponsibility.h \ - src/browser/responsibilities/browser/WindowHandlingResponsibility.h \ - src/browser/responsibilities/window/ControlResponsibility.h \ - src/browser/responsibilities/window/CookieResponsibility.h \ - src/browser/responsibilities/window/DialogResponsibility.h \ - src/browser/responsibilities/window/DisplayResponsibility.h \ - src/browser/responsibilities/window/DownloadResponsibility.h \ - src/browser/responsibilities/window/KeyboardResponsibility.h \ - src/browser/responsibilities/window/LifeSpanResponsibility.h \ - src/browser/responsibilities/window/RequestResponsibility.h \ - src/browser/responsibilities/window/WindowResponsibility.h \ - src/browser/responsibilities/window/ZoomResponsibility.h \ + src/browser/engines/engine_factory.h \ src/browser/webengine_environment.h \ - src/browser/wrapper/CefSharpBrowserControl.h \ - src/browser/wrapper/CefSharpPopupControl.h \ - src/browser/wrapper/Extensions.h \ - src/browser/wrapper/ICefSharpControl.h \ - src/browser/wrapper/events/AuthCredentialsEventHandler.h \ - src/browser/wrapper/events/BeforeBrowseEventHandler.h \ - src/browser/wrapper/events/BeforeContextMenuEventHandler.h \ - src/browser/wrapper/events/BeforeDownloadEventHandler.h \ - src/browser/wrapper/events/BeforeUnloadDialogEventHandler.h \ - src/browser/wrapper/events/CanDownloadEventHandler.h \ - src/browser/wrapper/events/ContextCreatedEventHandler.h \ - src/browser/wrapper/events/ContextMenuCommandEventHandler.h \ - src/browser/wrapper/events/ContextMenuDismissedEventHandler.h \ - src/browser/wrapper/events/ContextReleasedEventHandler.h \ - src/browser/wrapper/events/DialogClosedEventHandler.h \ - src/browser/wrapper/events/DownloadUpdatedEventHandler.h \ - src/browser/wrapper/events/DragEnterEventHandler.h \ - src/browser/wrapper/events/DraggableRegionsChangedEventHandler.h \ - src/browser/wrapper/events/FaviconUrlChangedEventHandler.h \ - src/browser/wrapper/events/FileDialogRequestedEventHandler.h \ - src/browser/wrapper/events/FocusedNodeChangedEventHandler.h \ - src/browser/wrapper/events/GenericEventArgs.h \ - src/browser/wrapper/events/GotFocusEventHandler.h \ - src/browser/wrapper/events/JavaScriptDialogEventHandler.h \ - src/browser/wrapper/events/KeyEventHandler.h \ - src/browser/wrapper/events/LoadingProgressChangedEventHandler.h \ - src/browser/wrapper/events/OpenUrlFromTabEventHandler.h \ - src/browser/wrapper/events/PreKeyEventHandler.h \ - src/browser/wrapper/events/ResetDialogStateEventHandler.h \ - src/browser/wrapper/events/ResourceRequestEventArgs.h \ - src/browser/wrapper/events/ResourceRequestEventHandler.h \ - src/browser/wrapper/events/RunContextMenuEventHandler.h \ - src/browser/wrapper/events/SetFocusEventHandler.h \ - src/browser/wrapper/events/TakeFocusEventHandler.h \ - src/browser/wrapper/events/UncaughtExceptionEventHandler.h \ - src/browser/wrapper/handlers/ContextMenuHandlerSwitch.h \ - src/browser/wrapper/handlers/DialogHandlerSwitch.h \ - src/browser/wrapper/handlers/DisplayHandlerSwitch.h \ - src/browser/wrapper/handlers/DownloadHandlerSwitch.h \ - src/browser/wrapper/handlers/DragHandlerSwitch.h \ - src/browser/wrapper/handlers/FocusHandlerSwitch.h \ - src/browser/wrapper/handlers/JavaScriptDialogHandlerSwitch.h \ - src/browser/wrapper/handlers/KeyboardHandlerSwitch.h \ - src/browser/wrapper/handlers/RenderProcessMessageHandlerSwitch.h \ - src/browser/wrapper/handlers/RequestHandlerSwitch.h \ src/settings/password_container.h \ src/settings/resource_loader.h \ src/settings/settings_defaults.h \ @@ -433,72 +357,12 @@ HEADERS += \ src/ui/taskbar/controls/raise_hand_control.h \ src/ui/taskbar/controls/window_list_popup.h \ src/ui/taskbar/taskbar_widget.h \ - src/userinterface/contracts/Properties/AssemblyInfo.h \ - src/userinterface/contracts/browser/data/download_item_state.h \ - src/userinterface/contracts/browser/data/javascript_result.h \ - src/userinterface/contracts/browser/events/address_changed_event_handler.h \ - src/userinterface/contracts/browser/events/find_requested_event_handler.h \ - src/userinterface/contracts/browser/events/load_failed_event_handler.h \ - src/userinterface/contracts/browser/events/loading_state_changed_event_handler.h \ - src/userinterface/contracts/browser/events/title_changed_event_handler.h \ - src/userinterface/contracts/browser/i_browser_control.h \ - src/userinterface/contracts/browser/i_browser_window.h \ - src/userinterface/contracts/events/action_requested_event_handler.h \ - src/userinterface/contracts/file_system_dialog/file_system_dialog_result.h \ - src/userinterface/contracts/file_system_dialog/file_system_element.h \ - src/userinterface/contracts/file_system_dialog/file_system_operation.h \ - src/userinterface/contracts/file_system_dialog/i_file_system_dialog.h \ - src/userinterface/contracts/i_progress_indicator.h \ - src/userinterface/contracts/i_user_interface_factory.h \ - src/userinterface/contracts/i_window_guard.h \ - src/userinterface/contracts/message_box/i_message_box.h \ - src/userinterface/contracts/message_box/message_box_action.h \ - src/userinterface/contracts/message_box/message_box_icon.h \ - src/userinterface/contracts/message_box/message_box_result.h \ - src/userinterface/contracts/proctoring/events/cancellation_requested_event_handler.h \ - src/userinterface/contracts/proctoring/events/full_screen_changed_event_handler.h \ - src/userinterface/contracts/proctoring/i_proctoring_control.h \ - src/userinterface/contracts/proctoring/i_proctoring_finalization_dialog.h \ - src/userinterface/contracts/proctoring/i_proctoring_window.h \ - src/userinterface/contracts/shell/events/activator_event_handler.h \ - src/userinterface/contracts/shell/events/quit_button_clicked_event_handler.h \ - src/userinterface/contracts/shell/i_action_center.h \ - src/userinterface/contracts/shell/i_action_center_activator.h \ - src/userinterface/contracts/shell/i_activator.h \ - src/userinterface/contracts/shell/i_application_control.h \ - src/userinterface/contracts/shell/i_notification_control.h \ - src/userinterface/contracts/shell/i_system_control.h \ - src/userinterface/contracts/shell/i_taskbar.h \ - src/userinterface/contracts/shell/i_taskbar_activator.h \ - src/userinterface/contracts/shell/i_taskview.h \ - src/userinterface/contracts/shell/i_taskview_activator.h \ - src/userinterface/contracts/shell/i_termination_activator.h \ - src/userinterface/contracts/shell/i_verificator_activator.h \ - src/userinterface/contracts/shell/location.h \ - src/userinterface/contracts/windows/data/credentials_dialog_purpose.h \ - src/userinterface/contracts/windows/data/credentials_dialog_result.h \ - src/userinterface/contracts/windows/data/exam_selection_dialog_result.h \ - src/userinterface/contracts/windows/data/lock_screen_option.h \ - src/userinterface/contracts/windows/data/lock_screen_result.h \ - src/userinterface/contracts/windows/data/password_dialog_result.h \ - src/userinterface/contracts/windows/data/server_failure_dialog_result.h \ - src/userinterface/contracts/windows/events/window_closed_event_handler.h \ - src/userinterface/contracts/windows/events/window_closing_event_handler.h \ - src/userinterface/contracts/windows/i_credentials_dialog.h \ - src/userinterface/contracts/windows/i_exam_selection_dialog.h \ - src/userinterface/contracts/windows/i_lock_screen.h \ - src/userinterface/contracts/windows/i_password_dialog.h \ - src/userinterface/contracts/windows/i_runtime_window.h \ - src/userinterface/contracts/windows/i_server_failure_dialog.h \ - src/userinterface/contracts/windows/i_splash_screen.h \ - src/userinterface/contracts/windows/i_verificator_overlay.h \ - src/userinterface/contracts/windows/i_window.h \ src/ui/runtime_window.h \ src/ui/seb_taskbar.h \ src/seb_settings.h \ src/seb_session.h \ + src/security/security_service.h \ src/browser_window.h - RESOURCES += resources.qrc target.path = /usr/bin diff --git a/src/app_controller.cpp b/src/app_controller.cpp index aa6d87f..380bae8 100644 --- a/src/app_controller.cpp +++ b/src/app_controller.cpp @@ -59,7 +59,18 @@ bool AppController::launchResolved(const seb::SebSettings &settings, const QStri bool AppController::applySettings(const seb::SebSettings &settings, const QStringList &warnings, QString *error) { - if (!settings.browser.enableBrowser) { + seb::SebSettings finalSettings = settings; + + bool currentBypass = false; + if (session_) { + currentBypass = session_->settings().devBypass; + } + + if (currentBypass || finalSettings.devBypass) { + seb::applyDevBypassOverrides(finalSettings); + } + + if (!finalSettings.browser.enableBrowser) { if (error) { *error = QStringLiteral("The loaded configuration disables the browser."); } @@ -86,7 +97,7 @@ bool AppController::applySettings(const seb::SebSettings &settings, const QStrin startupTimer.start(); auto nextSession = std::make_unique( - settings, + finalSettings, [this](const QString &resource, QWidget *parent) { QString error; if (launch(resource, &error)) { @@ -114,8 +125,13 @@ bool AppController::applySettings(const seb::SebSettings &settings, const QStrin if (mainWindow_) { mainWindow_->hide(); mainWindow_->deleteLater(); + mainWindow_ = nullptr; } + if (session_) { + session_.release()->deleteLater(); + } + mainWindow_ = nextWindow; session_ = std::move(nextSession); diff --git a/src/applications/contracts/Properties/AssemblyInfo.h b/src/applications/contracts/Properties/AssemblyInfo.h deleted file mode 100644 index 34cf0db..0000000 --- a/src/applications/contracts/Properties/AssemblyInfo.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -namespace seb::applications::contracts::assemblyinfo { - -inline constexpr auto kTitle = "SafeExamBrowser.Applications.Contracts"; -inline constexpr auto kDescription = "Safe Exam Browser"; -inline constexpr auto kCompany = "JVR2022"; -inline constexpr auto kProduct = "SafeExamBrowser.Applications.Contracts"; -inline constexpr auto kCopyright = "Copyright (C) 2026 JVR2022"; -inline constexpr auto kGuid = "ac77745d-3b41-43e2-8e84-d40e5a4ee77f"; -inline constexpr auto kVersion = "1.0.0.0"; - -} // namespace seb::applications::contracts::assemblyinfo diff --git a/src/browser/BrowserControl.cpp b/src/browser/BrowserControl.cpp index fbe8071..ee638d8 100644 --- a/src/browser/BrowserControl.cpp +++ b/src/browser/BrowserControl.cpp @@ -1,16 +1,15 @@ #include "BrowserControl.h" - -#include -#include +#include "contracts/i_webview.h" namespace seb::browser { -BrowserControl::BrowserControl(QWebEngineView *view, QObject *parent) +BrowserControl::BrowserControl(contracts::IWebView *view, QObject *parent) : QObject(parent) , view_(view) { } + QString BrowserControl::address() const { return view_ ? view_->url().toString() : QString(); @@ -18,32 +17,40 @@ QString BrowserControl::address() const bool BrowserControl::canNavigateBackwards() const { - return view_ && view_->history()->canGoBack(); + return view_ && view_->canGoBack(); } bool BrowserControl::canNavigateForwards() const { - return view_ && view_->history()->canGoForward(); + return view_ && view_->canGoForward(); } void BrowserControl::navigateTo(const QString &address) { - if (view_) view_->setUrl(QUrl::fromUserInput(address)); + if (view_) { + view_->setUrl(QUrl::fromUserInput(address)); + } } void BrowserControl::navigateBackwards() { - if (view_) view_->back(); + if (view_) { + view_->back(); + } } void BrowserControl::navigateForwards() { - if (view_) view_->forward(); + if (view_) { + view_->forward(); + } } void BrowserControl::reload() { - if (view_) view_->reload(); + if (view_) { + view_->reload(); + } } } // namespace seb::browser diff --git a/src/browser/BrowserControl.h b/src/browser/BrowserControl.h index f3196b6..06c7d11 100644 --- a/src/browser/BrowserControl.h +++ b/src/browser/BrowserControl.h @@ -1,12 +1,9 @@ #pragma once +#include "contracts/i_webview.h" #include #include -QT_BEGIN_NAMESPACE -class QWebEngineView; -QT_END_NAMESPACE - namespace seb::browser { class BrowserControl : public QObject @@ -14,7 +11,7 @@ class BrowserControl : public QObject Q_OBJECT public: - explicit BrowserControl(QWebEngineView *view, QObject *parent = nullptr); + explicit BrowserControl(contracts::IWebView *view, QObject *parent = nullptr); QString address() const; bool canNavigateBackwards() const; @@ -25,7 +22,7 @@ class BrowserControl : public QObject void reload(); private: - QWebEngineView *view_ = nullptr; + contracts::IWebView *view_ = nullptr; }; } // namespace seb::browser diff --git a/src/browser/BrowserIconResource.h b/src/browser/BrowserIconResource.h deleted file mode 100644 index 5f0fdff..0000000 --- a/src/browser/BrowserIconResource.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -namespace seb::browser { - -class BrowserIconResource -{ -public: - explicit BrowserIconResource(const QString &path = QStringLiteral(":/assets/icons/safe-exam-browser.png")) - : path_(path) - { - } - - QString path() const { return path_; } - -private: - QString path_; -}; - -} // namespace seb::browser diff --git a/src/browser/BrowserWindow.cpp b/src/browser/BrowserWindow.cpp index 206b0ef..d273b73 100644 --- a/src/browser/BrowserWindow.cpp +++ b/src/browser/BrowserWindow.cpp @@ -43,7 +43,7 @@ bool BrowserWindowPort::isMainWindow() const QString BrowserWindowPort::url() const { - return window_ && window_->page() ? window_->page()->url().toString() : QString(); + return window_ ? window_->currentUrl().toString() : QString(); } BrowserWindowContext BrowserWindowPort::context() const @@ -53,7 +53,7 @@ BrowserWindowContext BrowserWindowPort::context() const context.id = static_cast(reinterpret_cast(window_) & 0x7fffffff); context.isMainWindow = window_->isMainWindow(); context.title = window_->taskbarTitle(); - context.url = window_->page() ? window_->page()->url().toString() : QString(); + context.url = window_->currentUrl().toString(); } return context; } diff --git a/src/browser/Properties/AssemblyInfo.h b/src/browser/Properties/AssemblyInfo.h deleted file mode 100644 index 735b054..0000000 --- a/src/browser/Properties/AssemblyInfo.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::assemblyinfo { - -inline constexpr auto kTitle = "SafeExamBrowser.Browser"; -inline constexpr auto kDescription = "Safe Exam Browser"; -inline constexpr auto kCompany = "JVR2022"; -inline constexpr auto kProduct = "SafeExamBrowser.Browser"; -inline constexpr auto kCopyright = "Copyright (C) 2026 JVR2022"; -inline constexpr auto kGuid = "04e653f1-98e6-4e34-9dd7-7f2bc1a8b767"; -inline constexpr auto kVersion = "1.0.0.0"; - -} // namespace seb::browser::assemblyinfo diff --git a/src/browser/content/ContentLoader.cpp b/src/browser/content/ContentLoader.cpp deleted file mode 100644 index 21967ef..0000000 --- a/src/browser/content/ContentLoader.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "ContentLoader.h" - -#include - -namespace seb::browser::content { - -QString ContentLoader::loadApi(const QString &browserExamKey, const QString &configurationKey, const QString &version) -{ - if (api_.isEmpty()) { - api_ = load(QStringLiteral(":/browser/content/Api.js")); - } - - QString js = api_; - js.replace(QStringLiteral("%%_BEK_%%"), browserExamKey); - js.replace(QStringLiteral("%%_CK_%%"), configurationKey); - js.replace(QStringLiteral("%%_VERSION_%%"), version); - return js; -} - -QString ContentLoader::loadBlockedContent() const -{ - QString html = load(QStringLiteral(":/browser/content/BlockedContent.html")); - html.replace(QStringLiteral("%%MESSAGE%%"), QStringLiteral("This content has been blocked by Safe Exam Browser.")); - return html; -} - -QString ContentLoader::loadBlockedPage() const -{ - QString html = load(QStringLiteral(":/browser/content/BlockedPage.html")); - html.replace(QStringLiteral("%%BACK_BUTTON%%"), QStringLiteral("Back")); - html.replace(QStringLiteral("%%MESSAGE%%"), QStringLiteral("This page has been blocked by Safe Exam Browser.")); - html.replace(QStringLiteral("%%TITLE%%"), QStringLiteral("Blocked Page")); - return html; -} - -QString ContentLoader::loadClipboard() -{ - if (clipboard_.isEmpty()) { - clipboard_ = load(QStringLiteral(":/browser/content/Clipboard.js")); - } - - return clipboard_; -} - -QString ContentLoader::loadPageZoom() -{ - if (pageZoom_.isEmpty()) { - pageZoom_ = load(QStringLiteral(":/browser/content/PageZoom.js")); - } - - return pageZoom_; -} - -QString ContentLoader::load(const QString &resourcePath) -{ - QFile file(resourcePath); - if (!file.open(QIODevice::ReadOnly)) { - return {}; - } - return QString::fromUtf8(file.readAll()); -} - -} // namespace seb::browser::content diff --git a/src/browser/content/ContentLoader.h b/src/browser/content/ContentLoader.h deleted file mode 100644 index b2fb509..0000000 --- a/src/browser/content/ContentLoader.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::content { - -class ContentLoader -{ -public: - QString loadApi(const QString &browserExamKey, const QString &configurationKey, const QString &version); - QString loadBlockedContent() const; - QString loadBlockedPage() const; - QString loadClipboard(); - QString loadPageZoom(); - -private: - static QString load(const QString &resourcePath); - - QString api_; - QString clipboard_; - QString pageZoom_; -}; - -} // namespace seb::browser::content diff --git a/src/browser/contracts/Properties/AssemblyInfo.h b/src/browser/contracts/Properties/AssemblyInfo.h deleted file mode 100644 index a4cfdaa..0000000 --- a/src/browser/contracts/Properties/AssemblyInfo.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -namespace seb::browser::contracts::assemblyinfo { - -inline constexpr auto kTitle = "SafeExamBrowser.Browser.Contracts"; -inline constexpr auto kDescription = "Safe Exam Browser"; -inline constexpr auto kCompany = "JVR2022"; -inline constexpr auto kProduct = "SafeExamBrowser.Browser.Contracts"; -inline constexpr auto kCopyright = "Copyright (C) 2026 JVR2022"; -inline constexpr auto kGuid = "5fb5273d-277c-41dd-8593-a25ce1aff2e9"; -inline constexpr auto kVersion = "1.0.0.0"; - -} // namespace seb::browser::contracts::assemblyinfo diff --git a/src/browser/contracts/events/download_event_args.h b/src/browser/contracts/events/download_event_args.h deleted file mode 100644 index cae9810..0000000 --- a/src/browser/contracts/events/download_event_args.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "download_finished_callback.h" - -#include - -namespace seb::browser::contracts::events { - -struct DownloadEventArgs -{ - bool allowDownload = false; - DownloadFinishedCallback callback; - QString downloadPath; - QString url; -}; - -} // namespace seb::browser::contracts::events diff --git a/src/browser/contracts/events/download_finished_callback.h b/src/browser/contracts/events/download_finished_callback.h deleted file mode 100644 index a0f20d1..0000000 --- a/src/browser/contracts/events/download_finished_callback.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::contracts::events { - -using DownloadFinishedCallback = std::function; - -} // namespace seb::browser::contracts::events diff --git a/src/browser/contracts/events/download_requested_event_handler.h b/src/browser/contracts/events/download_requested_event_handler.h deleted file mode 100644 index e6fc32b..0000000 --- a/src/browser/contracts/events/download_requested_event_handler.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "download_event_args.h" - -#include -#include - -namespace seb::browser::contracts::events { - -using DownloadRequestedEventHandler = std::function; - -} // namespace seb::browser::contracts::events diff --git a/src/browser/contracts/events/lose_focus_requested_event_handler.h b/src/browser/contracts/events/lose_focus_requested_event_handler.h deleted file mode 100644 index 738100a..0000000 --- a/src/browser/contracts/events/lose_focus_requested_event_handler.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::contracts::events { - -using LoseFocusRequestedEventHandler = std::function; - -} // namespace seb::browser::contracts::events diff --git a/src/browser/contracts/events/tab_pressed_event_handler.h b/src/browser/contracts/events/tab_pressed_event_handler.h deleted file mode 100644 index ff60d83..0000000 --- a/src/browser/contracts/events/tab_pressed_event_handler.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::contracts::events { - -using TabPressedEventHandler = std::function; - -} // namespace seb::browser::contracts::events diff --git a/src/browser/contracts/events/termination_requested_event_handler.h b/src/browser/contracts/events/termination_requested_event_handler.h deleted file mode 100644 index db50fbc..0000000 --- a/src/browser/contracts/events/termination_requested_event_handler.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::contracts::events { - -using TerminationRequestedEventHandler = std::function; - -} // namespace seb::browser::contracts::events diff --git a/src/browser/contracts/events/user_identifier_detected_event_handler.h b/src/browser/contracts/events/user_identifier_detected_event_handler.h deleted file mode 100644 index 01cfcd1..0000000 --- a/src/browser/contracts/events/user_identifier_detected_event_handler.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::contracts::events { - -using UserIdentifierDetectedEventHandler = std::function; - -} // namespace seb::browser::contracts::events diff --git a/src/browser/contracts/filters/IRequestFilter.h b/src/browser/contracts/filters/IRequestFilter.h deleted file mode 100644 index 0003c32..0000000 --- a/src/browser/contracts/filters/IRequestFilter.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../../../seb_settings.h" -#include "IRule.h" -#include "request.h" - -namespace seb::browser::contracts::filters { - -class IRequestFilter -{ -public: - virtual ~IRequestFilter() = default; - - virtual seb::FilterResult defaultResult() const = 0; - virtual void setDefaultResult(seb::FilterResult result) = 0; - virtual void load(IRule *rule) = 0; - virtual seb::FilterResult process(const Request &request) const = 0; -}; - -} // namespace seb::browser::contracts::filters diff --git a/src/browser/contracts/filters/IRule.h b/src/browser/contracts/filters/IRule.h deleted file mode 100644 index 5bb700f..0000000 --- a/src/browser/contracts/filters/IRule.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../../seb_settings.h" -#include "request.h" - -namespace seb::browser::contracts::filters { - -class IRule -{ -public: - virtual ~IRule() = default; - - virtual seb::FilterResult result() const = 0; - virtual void initialize(const seb::FilterRuleSettings &settings) = 0; - virtual bool isMatch(const Request &request) const = 0; -}; - -} // namespace seb::browser::contracts::filters diff --git a/src/browser/contracts/filters/IRuleFactory.h b/src/browser/contracts/filters/IRuleFactory.h deleted file mode 100644 index dfa85cb..0000000 --- a/src/browser/contracts/filters/IRuleFactory.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../../seb_settings.h" -#include "IRule.h" - -namespace seb::browser::contracts::filters { - -class IRuleFactory -{ -public: - virtual ~IRuleFactory() = default; - virtual IRule *createRule(seb::FilterRuleType type) = 0; -}; - -} // namespace seb::browser::contracts::filters diff --git a/src/browser/contracts/filters/request.h b/src/browser/contracts/filters/request.h deleted file mode 100644 index d74c73c..0000000 --- a/src/browser/contracts/filters/request.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::contracts::filters { - -struct Request -{ - QString url; -}; - -} // namespace seb::browser::contracts::filters diff --git a/src/browser/contracts/i_engine_provider.h b/src/browser/contracts/i_engine_provider.h new file mode 100644 index 0000000..59530dc --- /dev/null +++ b/src/browser/contracts/i_engine_provider.h @@ -0,0 +1,28 @@ +#pragma once + +#include "i_webprofile.h" +#include "i_webview.h" + +#include + +QT_BEGIN_NAMESPACE +class QObject; +class QWidget; +QT_END_NAMESPACE + +namespace seb::browser { +class RequestInterceptor; +} + +namespace seb::browser::contracts { + +class IEngineProvider +{ +public: + virtual ~IEngineProvider() = default; + + virtual std::unique_ptr createProfile(QObject *parent) = 0; + virtual std::unique_ptr createWebView(IWebProfile *profile, QWidget *parent) = 0; +}; + +} // namespace seb::browser::contracts diff --git a/src/browser/contracts/i_request_interceptor.h b/src/browser/contracts/i_request_interceptor.h new file mode 100644 index 0000000..7ebd0cd --- /dev/null +++ b/src/browser/contracts/i_request_interceptor.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +namespace seb::browser::contracts { + +enum class ResourceType { + MainFrame, + NavigationPreloadMainFrame, + SubFrame, + Other +}; + +class IRequest { +public: + virtual ~IRequest() = default; + + virtual QUrl requestUrl() const = 0; + virtual QUrl firstPartyUrl() const = 0; + virtual ResourceType resourceType() const = 0; + + virtual void block(bool shouldBlock) = 0; + virtual void redirect(const QUrl &url) = 0; + virtual void setHttpHeader(const QByteArray &name, const QByteArray &value) = 0; +}; + +class IRequestInterceptor { +public: + virtual ~IRequestInterceptor() = default; + + virtual void interceptRequest(IRequest &request) = 0; +}; + +} // namespace seb::browser::contracts diff --git a/src/browser/contracts/i_webprofile.h b/src/browser/contracts/i_webprofile.h new file mode 100644 index 0000000..a8dd333 --- /dev/null +++ b/src/browser/contracts/i_webprofile.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QUrl; +QT_END_NAMESPACE + +namespace seb::browser::contracts { +class IRequestInterceptor; +} + +namespace seb::browser::contracts { + +class IWebProfile : public QObject +{ + Q_OBJECT + +public: + explicit IWebProfile(QObject *parent = nullptr) : QObject(parent) {} + virtual ~IWebProfile() = default; + + virtual void setPersistentStoragePath(const QString &path) = 0; + virtual void setCachePath(const QString &path) = 0; + virtual void setDownloadPath(const QString &path) = 0; + + // Settings equivalent to QWebEngineSettings + virtual void setPdfViewerEnabled(bool enabled) = 0; + virtual void setSpellCheckEnabled(bool enabled) = 0; + virtual void setSpellCheckLanguages(const QStringList &languages) = 0; + virtual void setHttpUserAgent(const QString &userAgent) = 0; + virtual void setDevBypass(bool enabled) = 0; + virtual void setUrlRequestInterceptor(IRequestInterceptor *interceptor) = 0; + virtual void deleteAllCookies() = 0; + +signals: + // Simple download abstraction. A full download interceptor would have its own class. + void downloadRequested(const QUrl &url, const QString &suggestedFilename, bool &accepted, QString &downloadDirectory); +}; + +} // namespace seb::browser::contracts diff --git a/src/browser/contracts/i_webview.h b/src/browser/contracts/i_webview.h new file mode 100644 index 0000000..12fe245 --- /dev/null +++ b/src/browser/contracts/i_webview.h @@ -0,0 +1,54 @@ +#pragma once + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QWidget; +class QAuthenticator; +QT_END_NAMESPACE + +namespace seb::browser::contracts { + +class IWebView : public QObject +{ + Q_OBJECT + +public: + explicit IWebView(QObject *parent = nullptr) : QObject(parent) {} + virtual ~IWebView() = default; + + /*! + * \brief Returns the actual Qt widget that can be inserted into the UI layout. + * For WebEngine this is the QWebEngineView. For WebKitGTK this is a QWindow container widget. + */ + virtual QWidget *widget() const = 0; + + virtual QUrl url() const = 0; + virtual void setUrl(const QUrl &url) = 0; + + virtual void back() = 0; + virtual void forward() = 0; + virtual void reload() = 0; + virtual void openDevTools() = 0; + virtual bool canGoBack() const = 0; + virtual bool canGoForward() const = 0; + + virtual void findText(const QString &text) = 0; + + /*! + * \brief Allows injecting a delegate to approve/block top-level navigations. + */ + using NavigationRequestDelegate = std::function; + virtual void setNavigationRequestDelegate(NavigationRequestDelegate delegate) = 0; + +signals: + void urlChanged(const QUrl &url); + void titleChanged(const QString &title); + void newWindowRequested(const QUrl &targetUrl, bool &handled); + void proxyAuthenticationRequired(const QUrl &url, QAuthenticator *authenticator, const QString &proxyHost); +}; + +} // namespace seb::browser::contracts diff --git a/src/browser/engines/engine_factory.cpp b/src/browser/engines/engine_factory.cpp new file mode 100644 index 0000000..8be200b --- /dev/null +++ b/src/browser/engines/engine_factory.cpp @@ -0,0 +1,23 @@ +#include "engine_factory.h" +#include "../webengine_compat.h" + +#if SEB_HAS_QTWEBENGINE +#include "qtwebengine/qt_webengine_provider.h" +#elif SEB_HAS_WEBKITGTK +#include "webkitgtk/webkitgtk_provider.h" +#endif + +namespace seb::browser { + +std::unique_ptr createEngineProvider() +{ +#if SEB_HAS_QTWEBENGINE + return std::make_unique(); +#elif SEB_HAS_WEBKITGTK + return std::make_unique(); +#else + return nullptr; +#endif +} + +} // namespace seb::browser diff --git a/src/browser/engines/engine_factory.h b/src/browser/engines/engine_factory.h new file mode 100644 index 0000000..5927f5d --- /dev/null +++ b/src/browser/engines/engine_factory.h @@ -0,0 +1,15 @@ +#pragma once + +#include "../contracts/i_engine_provider.h" +#include + +namespace seb::browser { + +/*! + * \brief Returns the active engine provider based on build-time configuration. + * On complete builds this returns QtWebEngineProvider. On compatibility builds + * this returns WebKitGtkProvider. + */ +std::unique_ptr createEngineProvider(); + +} // namespace seb::browser diff --git a/src/browser/engines/qtwebengine/qt_webengine_profile.cpp b/src/browser/engines/qtwebengine/qt_webengine_profile.cpp new file mode 100644 index 0000000..64bfd08 --- /dev/null +++ b/src/browser/engines/qtwebengine/qt_webengine_profile.cpp @@ -0,0 +1,146 @@ +#include "../../webengine_compat.h" +#include "qt_webengine_profile.h" + + +#if SEB_HAS_QTWEBENGINE +#include +#include +#include +#include +#include + +namespace seb::browser { + +namespace { + +contracts::ResourceType mapResourceType(QWebEngineUrlRequestInfo::ResourceType type) +{ + switch (type) { + case QWebEngineUrlRequestInfo::ResourceTypeMainFrame: + return contracts::ResourceType::MainFrame; + case QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadMainFrame: + return contracts::ResourceType::NavigationPreloadMainFrame; + case QWebEngineUrlRequestInfo::ResourceTypeSubFrame: + return contracts::ResourceType::SubFrame; + default: + return contracts::ResourceType::Other; + } +} + +class NativeRequestWrapper : public contracts::IRequest +{ +public: + explicit NativeRequestWrapper(QWebEngineUrlRequestInfo &info) : info_(info) {} + + QUrl requestUrl() const override { return info_.requestUrl(); } + QUrl firstPartyUrl() const override { return info_.firstPartyUrl(); } + contracts::ResourceType resourceType() const override { return mapResourceType(info_.resourceType()); } + + void block(bool shouldBlock) override { info_.block(shouldBlock); } + void redirect(const QUrl &url) override { info_.redirect(url); } + void setHttpHeader(const QByteArray &name, const QByteArray &value) override { info_.setHttpHeader(name, value); } + +private: + QWebEngineUrlRequestInfo &info_; +}; + +class NativeRequestInterceptor : public QWebEngineUrlRequestInterceptor +{ +public: + explicit NativeRequestInterceptor(contracts::IRequestInterceptor *abstractInterceptor, QObject *parent = nullptr) + : QWebEngineUrlRequestInterceptor(parent) + , abstractInterceptor_(abstractInterceptor) + { + } + + void interceptRequest(QWebEngineUrlRequestInfo &info) override + { + if (abstractInterceptor_) { + NativeRequestWrapper request(info); + abstractInterceptor_->interceptRequest(request); + } + } + +private: + contracts::IRequestInterceptor *abstractInterceptor_; +}; + +} // namespace + +QtWebEngineProfile::QtWebEngineProfile(QObject *parent) + : IWebProfile(parent) +{ + profile_ = new QWebEngineProfile(this); + + // Forward native download requests to the abstraction + connect(profile_, &QWebEngineProfile::downloadRequested, this, [this](auto *download) { + bool accepted = false; + QString downloadDir; + emit this->downloadRequested(download->url(), download->downloadFileName(), accepted, downloadDir); + + if (!accepted) { + download->cancel(); + } else { + if (!downloadDir.isEmpty()) { + download->setDownloadDirectory(downloadDir); + } + download->accept(); + } + }); +} + +void QtWebEngineProfile::setPersistentStoragePath(const QString &path) +{ + profile_->setPersistentStoragePath(path); +} + +void QtWebEngineProfile::setCachePath(const QString &path) +{ + profile_->setCachePath(path); +} + +void QtWebEngineProfile::setDownloadPath(const QString &path) +{ + profile_->setDownloadPath(path); +} + +void QtWebEngineProfile::setPdfViewerEnabled(bool enabled) +{ + profile_->settings()->setAttribute(QWebEngineSettings::PdfViewerEnabled, enabled); +} + +void QtWebEngineProfile::setSpellCheckEnabled(bool enabled) +{ + profile_->setSpellCheckEnabled(enabled); +} + +void QtWebEngineProfile::setSpellCheckLanguages(const QStringList &languages) +{ + profile_->setSpellCheckLanguages(languages); +} + +void QtWebEngineProfile::setHttpUserAgent(const QString &userAgent) +{ + profile_->setHttpUserAgent(userAgent); +} + +void QtWebEngineProfile::setUrlRequestInterceptor(contracts::IRequestInterceptor *interceptor) +{ + if (!interceptor) { + profile_->setUrlRequestInterceptor(nullptr); + return; + } + + auto *nativeInterceptor = new NativeRequestInterceptor(interceptor, this); + profile_->setUrlRequestInterceptor(nativeInterceptor); +} + +void QtWebEngineProfile::deleteAllCookies() +{ + if (profile_->cookieStore()) { + profile_->cookieStore()->deleteAllCookies(); + } +} + +} // namespace seb::browser +#endif diff --git a/src/browser/engines/qtwebengine/qt_webengine_profile.h b/src/browser/engines/qtwebengine/qt_webengine_profile.h new file mode 100644 index 0000000..d2399e6 --- /dev/null +++ b/src/browser/engines/qtwebengine/qt_webengine_profile.h @@ -0,0 +1,42 @@ +#pragma once + +#if SEB_HAS_QTWEBENGINE + +#include "browser/contracts/i_request_interceptor.h" +#include "browser/contracts/i_webprofile.h" +#include + +namespace seb::browser { + +class QtWebEngineProfile : public contracts::IWebProfile +{ + Q_OBJECT + +public: + explicit QtWebEngineProfile(QObject *parent = nullptr); + ~QtWebEngineProfile() override = default; + + QWebEngineProfile *nativeProfile() const { return profile_; } + + void setPersistentStoragePath(const QString &path) override; + void setCachePath(const QString &path) override; + void setDownloadPath(const QString &path) override; + + void setPdfViewerEnabled(bool enabled) override; + void setSpellCheckEnabled(bool enabled) override; + void setSpellCheckLanguages(const QStringList &languages) override; + void setHttpUserAgent(const QString &userAgent) override; + void setDevBypass(bool enabled) override { devBypass_ = enabled; } + bool devBypass() const { return devBypass_; } + + void setUrlRequestInterceptor(contracts::IRequestInterceptor *interceptor) override; + void deleteAllCookies() override; + +private: + QWebEngineProfile *profile_ = nullptr; + bool devBypass_ = false; +}; + +} // namespace seb::browser + +#endif diff --git a/src/browser/engines/qtwebengine/qt_webengine_provider.cpp b/src/browser/engines/qtwebengine/qt_webengine_provider.cpp new file mode 100644 index 0000000..b6ed1e6 --- /dev/null +++ b/src/browser/engines/qtwebengine/qt_webengine_provider.cpp @@ -0,0 +1,23 @@ +#include "qt_webengine_provider.h" + +#if SEB_HAS_QTWEBENGINE +#include "../../webengine_compat.h" +#include "qt_webengine_profile.h" +#include "qt_webengine_view.h" + +namespace seb::browser { + +std::unique_ptr QtWebEngineProvider::createProfile(QObject *parent) +{ + return std::make_unique(parent); +} + +std::unique_ptr QtWebEngineProvider::createWebView(contracts::IWebProfile *profile, QWidget *parent) +{ + auto *qtProfile = static_cast(profile); + return std::make_unique(qtProfile, parent); +} + +} // namespace seb::browser + +#endif diff --git a/src/browser/engines/qtwebengine/qt_webengine_provider.h b/src/browser/engines/qtwebengine/qt_webengine_provider.h new file mode 100644 index 0000000..9322983 --- /dev/null +++ b/src/browser/engines/qtwebengine/qt_webengine_provider.h @@ -0,0 +1,21 @@ +#pragma once + +#if SEB_HAS_QTWEBENGINE + +#include "browser/contracts/i_engine_provider.h" + +namespace seb::browser { + +class QtWebEngineProvider : public contracts::IEngineProvider +{ +public: + QtWebEngineProvider() = default; + ~QtWebEngineProvider() override = default; + + std::unique_ptr createProfile(QObject *parent) override; + std::unique_ptr createWebView(contracts::IWebProfile *profile, QWidget *parent) override; +}; + +} // namespace seb::browser + +#endif diff --git a/src/browser/engines/qtwebengine/qt_webengine_view.cpp b/src/browser/engines/qtwebengine/qt_webengine_view.cpp new file mode 100644 index 0000000..9719e09 --- /dev/null +++ b/src/browser/engines/qtwebengine/qt_webengine_view.cpp @@ -0,0 +1,150 @@ +#include "qt_webengine_view.h" + +#if SEB_HAS_QTWEBENGINE +#include "qt_webengine_profile.h" +#include +#include +#include +#include +#include +#include + +namespace seb::browser { + +class InterceptingPage : public QWebEnginePage +{ +public: + InterceptingPage(QWebEngineProfile *profile, QtWebEngineWebView *wrapper, QObject *parent = nullptr) + : QWebEnginePage(profile, parent), wrapper_(wrapper) {} + +protected: + bool acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) override + { + if (wrapper_->delegate() && !wrapper_->delegate()(url, isMainFrame)) { + return false; + } + return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame); + } + +private: + QtWebEngineWebView *wrapper_; +}; + +QtWebEngineWebView::QtWebEngineWebView(QtWebEngineProfile *profile, QWidget *parent) + : IWebView(parent) +{ + view_ = new QWebEngineView(parent); + auto *page = new InterceptingPage(profile->nativeProfile(), this, view_); + view_->setPage(page); + +#if defined(QT_DEBUG) || defined(SEB_DEV_BYPASS_OPTION) + if (profile->devBypass()) { + QWebEngineScript script; + script.setName(QStringLiteral("seb-stealth")); + script.setSourceCode(QStringLiteral( + "(function() {" + " const mask = (obj, prop, val) => {" + " try { Object.defineProperty(obj, prop, { get: () => val, enumerable: true, configurable: true }); } catch (e) {}" + " };" + " mask(navigator, 'webdriver', false);" + " mask(navigator, 'plugins', [1, 2, 3, 4, 5]);" + " mask(navigator, 'languages', ['en-US', 'en']);" + " window.chrome = { runtime: {} };" + " mask(document, 'hidden', false);" + " mask(document, 'visibilityState', 'visible');" + " window.addEventListener('blur', e => e.stopImmediatePropagation(), true);" + " document.addEventListener('blur', e => e.stopImmediatePropagation(), true);" + " window.addEventListener('mouseleave', e => e.stopImmediatePropagation(), true);" + "})();" + )); + script.setInjectionPoint(QWebEngineScript::DocumentCreation); + script.setWorldId(QWebEngineScript::MainWorld); + script.setRunsOnSubFrames(true); + profile->nativeProfile()->scripts()->insert(script); + } +#endif + + connect(view_, &QWebEngineView::urlChanged, this, &QtWebEngineWebView::urlChanged); + connect(view_, &QWebEngineView::titleChanged, this, &QtWebEngineWebView::titleChanged); + + connect(page, &QWebEnginePage::newWindowRequested, this, [this](auto &request) { + bool handled = false; + emit this->newWindowRequested(request.requestedUrl(), handled); + if (handled) { + // In our simplified API we handle the window opening externally, so we drop the request object. + } + }); + + connect(page, &QWebEnginePage::proxyAuthenticationRequired, + this, &QtWebEngineWebView::proxyAuthenticationRequired); +} + +QtWebEngineWebView::~QtWebEngineWebView() +{ + // delete view_; // Parent ownership will handle this usually, but view_ is a QWidget. +} + +QWidget *QtWebEngineWebView::widget() const +{ + return view_; +} + +QUrl QtWebEngineWebView::url() const +{ + return view_->url(); +} + +void QtWebEngineWebView::setUrl(const QUrl &url) +{ + view_->setUrl(url); +} + +void QtWebEngineWebView::back() +{ + view_->back(); +} + +void QtWebEngineWebView::forward() +{ + view_->forward(); +} + +void QtWebEngineWebView::reload() +{ + view_->reload(); +} + +void QtWebEngineWebView::openDevTools() +{ + auto *devTools = new QWebEngineView(); + auto *devPage = new QWebEnginePage(view_->page()->profile(), devTools); + view_->page()->setDevToolsPage(devPage); + devTools->setPage(devPage); + devTools->setAttribute(Qt::WA_DeleteOnClose); + devTools->resize(1100, 700); + devTools->show(); +} + +bool QtWebEngineWebView::canGoBack() const +{ + return view_->history()->canGoBack(); +} + +bool QtWebEngineWebView::canGoForward() const +{ + return view_->history()->canGoForward(); +} + +void QtWebEngineWebView::findText(const QString &text) +{ + view_->page()->findText(QString()); + view_->page()->findText(text); +} + +void QtWebEngineWebView::setNavigationRequestDelegate(contracts::IWebView::NavigationRequestDelegate delegate) +{ + navigationDelegate_ = std::move(delegate); +} + +} // namespace seb::browser +#endif diff --git a/src/browser/engines/qtwebengine/qt_webengine_view.h b/src/browser/engines/qtwebengine/qt_webengine_view.h new file mode 100644 index 0000000..8d3ffce --- /dev/null +++ b/src/browser/engines/qtwebengine/qt_webengine_view.h @@ -0,0 +1,47 @@ +#pragma once + +#if SEB_HAS_QTWEBENGINE + +#include "browser/contracts/i_webview.h" + +QT_BEGIN_NAMESPACE +class QWebEngineView; +QT_END_NAMESPACE + +namespace seb::browser { + +class QtWebEngineProfile; + +class QtWebEngineWebView : public contracts::IWebView +{ + Q_OBJECT + +public: + explicit QtWebEngineWebView(QtWebEngineProfile *profile, QWidget *parent = nullptr); + ~QtWebEngineWebView() override; + + QWidget *widget() const override; + + QUrl url() const override; + void setUrl(const QUrl &url) override; + + void back() override; + void forward() override; + void reload() override; + void openDevTools() override; + bool canGoBack() const override; + bool canGoForward() const override; + + void findText(const QString &text) override; + + void setNavigationRequestDelegate(contracts::IWebView::NavigationRequestDelegate delegate) override; + const contracts::IWebView::NavigationRequestDelegate& delegate() const { return navigationDelegate_; } + +private: + QWebEngineView *view_ = nullptr; + contracts::IWebView::NavigationRequestDelegate navigationDelegate_; +}; + +} // namespace seb::browser + +#endif diff --git a/src/browser/engines/webkitgtk/webkitgtk_profile.cpp b/src/browser/engines/webkitgtk/webkitgtk_profile.cpp new file mode 100644 index 0000000..141fc44 --- /dev/null +++ b/src/browser/engines/webkitgtk/webkitgtk_profile.cpp @@ -0,0 +1,83 @@ +#include "webkitgtk_profile.h" + +#if !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK + +#include + +namespace seb::browser { + +class WebKitGtkProfile::Private +{ +public: + WebKitWebContext *context = nullptr; +}; + +WebKitGtkProfile::WebKitGtkProfile(QObject *parent) + : IWebProfile(parent) + , d(std::make_unique()) +{ + // Create an ephemeral or persistent WebKitContext + d->context = webkit_web_context_new(); +} + +WebKitGtkProfile::~WebKitGtkProfile() +{ + if (d->context) { + g_object_unref(d->context); + } +} + +void WebKitGtkProfile::setPersistentStoragePath(const QString &path) +{ + // WebKitGTK data dir config +} + +void WebKitGtkProfile::setCachePath(const QString &path) +{ + // WebKitGTK cache dir config +} + +void WebKitGtkProfile::setDownloadPath(const QString &path) +{ + // Handled at download request level in WebKitGTK +} + +void WebKitGtkProfile::setPdfViewerEnabled(bool enabled) +{ + // Not directly supported out of the box in WebKitGTK without Evince plugin +} + +void WebKitGtkProfile::setSpellCheckEnabled(bool enabled) +{ + if (d->context) { + webkit_web_context_set_spell_checking_enabled(d->context, enabled); + } +} + +void WebKitGtkProfile::setSpellCheckLanguages(const QStringList &languages) +{ + if (d->context) { + QString langStr = languages.join(QStringLiteral(",")); + webkit_web_context_set_spell_checking_languages(d->context, langStr.toUtf8().constData()); + } +} + +void WebKitGtkProfile::setHttpUserAgent(const QString &userAgent) +{ + // Agent is typically set on WebKitSettings per WebView, but can be managed here +} + +void WebKitGtkProfile::setUrlRequestInterceptor(seb::browser::contracts::IRequestInterceptor *interceptor) +{ + // Use WebKitUserContentManager or custom URI scheme handler +} + +void WebKitGtkProfile::deleteAllCookies() +{ + WebKitCookieManager *cookieManager = webkit_web_context_get_cookie_manager(d->context); + webkit_cookie_manager_delete_all_cookies(cookieManager); +} + +} // namespace seb::browser + +#endif // !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK diff --git a/src/browser/engines/webkitgtk/webkitgtk_profile.h b/src/browser/engines/webkitgtk/webkitgtk_profile.h new file mode 100644 index 0000000..c0aa845 --- /dev/null +++ b/src/browser/engines/webkitgtk/webkitgtk_profile.h @@ -0,0 +1,38 @@ +#pragma once + +#include "browser/webengine_compat.h" +#if !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK + +#include "browser/contracts/i_webprofile.h" + +namespace seb::browser { + +class WebKitGtkProfile : public contracts::IWebProfile { + Q_OBJECT + +public: + explicit WebKitGtkProfile(QObject *parent = nullptr); + ~WebKitGtkProfile() override; + + void setPersistentStoragePath(const QString &path) override; + void setCachePath(const QString &path) override; + void setDownloadPath(const QString &path) override; + + void setPdfViewerEnabled(bool enabled) override; + void setSpellCheckEnabled(bool enabled) override; + void setSpellCheckLanguages(const QStringList &languages) override; + void setHttpUserAgent(const QString &userAgent) override; + void setDevBypass(bool enabled) override {} + + void setUrlRequestInterceptor( + seb::browser::contracts::IRequestInterceptor *interceptor) override; + void deleteAllCookies() override; + +private: + class Private; + std::unique_ptr d; +}; + +} // namespace seb::browser + +#endif // !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK diff --git a/src/browser/engines/webkitgtk/webkitgtk_provider.cpp b/src/browser/engines/webkitgtk/webkitgtk_provider.cpp new file mode 100644 index 0000000..f0cf357 --- /dev/null +++ b/src/browser/engines/webkitgtk/webkitgtk_provider.cpp @@ -0,0 +1,27 @@ +#include "webkitgtk_provider.h" + +#if !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK +#include "webkitgtk_profile.h" +#include "webkitgtk_view.h" +#include "../../contracts/i_webprofile.h" +#include "../../contracts/i_webview.h" +#include +#include +#include + +namespace seb::browser { + +std::unique_ptr WebKitGtkProvider::createProfile(QObject *parent) +{ + return std::make_unique(parent); +} + +std::unique_ptr WebKitGtkProvider::createWebView(contracts::IWebProfile *profile, QWidget *parent) +{ + auto *webkitProfile = static_cast(profile); + return std::make_unique(webkitProfile, parent); +} + +} // namespace seb::browser + +#endif // !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK diff --git a/src/browser/engines/webkitgtk/webkitgtk_provider.h b/src/browser/engines/webkitgtk/webkitgtk_provider.h new file mode 100644 index 0000000..06444c1 --- /dev/null +++ b/src/browser/engines/webkitgtk/webkitgtk_provider.h @@ -0,0 +1,25 @@ +#pragma once + +#if !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK + +#include +#include +#include + +#include "../../contracts/i_engine_provider.h" + +namespace seb::browser { + +class WebKitGtkProvider : public contracts::IEngineProvider +{ +public: + WebKitGtkProvider() = default; + ~WebKitGtkProvider() override = default; + + std::unique_ptr createProfile(QObject *parent) override; + std::unique_ptr createWebView(contracts::IWebProfile *profile, QWidget *parent) override; +}; + +} // namespace seb::browser + +#endif // !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK diff --git a/src/browser/engines/webkitgtk/webkitgtk_view.cpp b/src/browser/engines/webkitgtk/webkitgtk_view.cpp new file mode 100644 index 0000000..1d153ac --- /dev/null +++ b/src/browser/engines/webkitgtk/webkitgtk_view.cpp @@ -0,0 +1,138 @@ +#include "webkitgtk_view.h" + +#if !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK + +#include +#include + +#include +#include +#include + +namespace seb::browser { + +class WebKitGtkWebView::Private +{ +public: + QWidget *containerWidget = nullptr; + GtkWidget *gtkWindow = nullptr; + GtkWidget *webView = nullptr; + NavigationRequestDelegate navigationDelegate; +}; + +WebKitGtkWebView::WebKitGtkWebView(WebKitGtkProfile *profile, QWidget *parent) + : IWebView(parent) + , d(std::make_unique()) +{ + d->containerWidget = new QWidget(parent); + + // NOTE: Full embedding of GTK into Qt6 requires bridging the X11 Window ID. + // This is a minimal stub to ensure compilation and linkage to GTK+3 and WebKit2. + // In a production environment, you would use gtk_plug_new() and QWindow::fromWinId(). + + // gtk_init must be called exactly once per process. + static bool gtkInitialized = false; + if (!gtkInitialized) { + gtk_init(nullptr, nullptr); + gtkInitialized = true; + } + d->webView = webkit_web_view_new(); + + // Connect WebKitGTK signals (load-changed, decide-policy, etc.) + g_signal_connect(d->webView, "load-changed", G_CALLBACK(+[](WebKitWebView *, WebKitLoadEvent event, gpointer data) { + auto *self = static_cast(data); + if (event == WEBKIT_LOAD_COMMITTED) { + emit self->urlChanged(self->url()); + } + }), this); + + g_signal_connect(d->webView, "notify::title", G_CALLBACK(+[](WebKitWebView *view, GParamSpec *, gpointer data) { + auto *self = static_cast(data); + const char *title = webkit_web_view_get_title(view); + if (title) { + emit self->titleChanged(QString::fromUtf8(title)); + } + }), this); +} + +WebKitGtkWebView::~WebKitGtkWebView() +{ + if (d->webView) { + gtk_widget_destroy(d->webView); + } +} + +QWidget *WebKitGtkWebView::widget() const +{ + return d->containerWidget; +} + +QUrl WebKitGtkWebView::url() const +{ + if (!d->webView) return {}; + const char *uri = webkit_web_view_get_uri(WEBKIT_WEB_VIEW(d->webView)); + return uri ? QUrl(QString::fromUtf8(uri)) : QUrl(); +} + +void WebKitGtkWebView::setUrl(const QUrl &url) +{ + if (d->webView) { + webkit_web_view_load_uri(WEBKIT_WEB_VIEW(d->webView), url.toString().toUtf8().constData()); + } +} + +void WebKitGtkWebView::back() +{ + if (d->webView) { + webkit_web_view_go_back(WEBKIT_WEB_VIEW(d->webView)); + } +} + +void WebKitGtkWebView::forward() +{ + if (d->webView) { + webkit_web_view_go_forward(WEBKIT_WEB_VIEW(d->webView)); + } +} + +void WebKitGtkWebView::reload() +{ + if (d->webView) { + webkit_web_view_reload(WEBKIT_WEB_VIEW(d->webView)); + } +} + +void WebKitGtkWebView::openDevTools() +{ + if (d->webView) { + WebKitWebInspector *inspector = webkit_web_view_get_inspector(WEBKIT_WEB_VIEW(d->webView)); + if (inspector) { + webkit_web_inspector_show(inspector); + } + } +} + +bool WebKitGtkWebView::canGoBack() const +{ + return d->webView && webkit_web_view_can_go_back(WEBKIT_WEB_VIEW(d->webView)); +} + +bool WebKitGtkWebView::canGoForward() const +{ + return d->webView && webkit_web_view_can_go_forward(WEBKIT_WEB_VIEW(d->webView)); +} + +void WebKitGtkWebView::findText(const QString &text) +{ + if (!d->webView) return; + WebKitFindController *finder = webkit_web_view_get_find_controller(WEBKIT_WEB_VIEW(d->webView)); + webkit_find_controller_search(finder, text.toUtf8().constData(), WEBKIT_FIND_OPTIONS_NONE, G_MAXUINT); +} + +void WebKitGtkWebView::setNavigationRequestDelegate(NavigationRequestDelegate delegate) +{ + d->navigationDelegate = std::move(delegate); +} + +} // namespace seb::browser +#endif // !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK diff --git a/src/browser/engines/webkitgtk/webkitgtk_view.h b/src/browser/engines/webkitgtk/webkitgtk_view.h new file mode 100644 index 0000000..265c785 --- /dev/null +++ b/src/browser/engines/webkitgtk/webkitgtk_view.h @@ -0,0 +1,42 @@ +#pragma once + +#if !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK + +#include "../../contracts/i_webview.h" + +namespace seb::browser { + +class WebKitGtkProfile; + +class WebKitGtkWebView : public contracts::IWebView +{ + Q_OBJECT + +public: + explicit WebKitGtkWebView(WebKitGtkProfile *profile, QWidget *parent = nullptr); + ~WebKitGtkWebView() override; + + QWidget *widget() const override; + + QUrl url() const override; + void setUrl(const QUrl &url) override; + + void back() override; + void forward() override; + void reload() override; + void openDevTools() override; + bool canGoBack() const override; + bool canGoForward() const override; + + void findText(const QString &text) override; + + void setNavigationRequestDelegate(IWebView::NavigationRequestDelegate delegate) override; + +private: + class Private; + std::unique_ptr d; +}; + +} // namespace seb::browser + +#endif // !SEB_HAS_QTWEBENGINE && SEB_HAS_WEBKITGTK diff --git a/src/browser/events/clipboard_changed_event_handler.h b/src/browser/events/clipboard_changed_event_handler.h deleted file mode 100644 index fbd2e11..0000000 --- a/src/browser/events/clipboard_changed_event_handler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::events { -using ClipboardChangedEventHandler = std::function; -} diff --git a/src/browser/events/dialog_requested_event_args.h b/src/browser/events/dialog_requested_event_args.h deleted file mode 100644 index 9fbe269..0000000 --- a/src/browser/events/dialog_requested_event_args.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::events { - -struct DialogRequestedEventArgs -{ - QString message; - QString title; -}; - -} // namespace seb::browser::events diff --git a/src/browser/events/dialog_requested_event_handler.h b/src/browser/events/dialog_requested_event_handler.h deleted file mode 100644 index 55e1e86..0000000 --- a/src/browser/events/dialog_requested_event_handler.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "dialog_requested_event_args.h" - -#include - -namespace seb::browser::events { -using DialogRequestedEventHandler = std::function; -} diff --git a/src/browser/events/download_aborted_event_handler.h b/src/browser/events/download_aborted_event_handler.h deleted file mode 100644 index 36e5ea1..0000000 --- a/src/browser/events/download_aborted_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::events { -using DownloadAbortedEventHandler = std::function; -} diff --git a/src/browser/events/download_updated_event_handler.h b/src/browser/events/download_updated_event_handler.h deleted file mode 100644 index 1650452..0000000 --- a/src/browser/events/download_updated_event_handler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::events { -using DownloadUpdatedEventHandler = std::function; -} diff --git a/src/browser/events/favicon_changed_event_handler.h b/src/browser/events/favicon_changed_event_handler.h deleted file mode 100644 index 891e24a..0000000 --- a/src/browser/events/favicon_changed_event_handler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::events { -using FaviconChangedEventHandler = std::function; -} diff --git a/src/browser/events/javascript_dialog_requested_event_args.h b/src/browser/events/javascript_dialog_requested_event_args.h deleted file mode 100644 index 81f736f..0000000 --- a/src/browser/events/javascript_dialog_requested_event_args.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "javascript_dialog_type.h" - -#include - -namespace seb::browser::events { - -struct JavaScriptDialogRequestedEventArgs -{ - JavaScriptDialogType type = JavaScriptDialogType::Alert; - QString message; - QString promptText; -}; - -} // namespace seb::browser::events diff --git a/src/browser/events/javascript_dialog_requested_event_handler.h b/src/browser/events/javascript_dialog_requested_event_handler.h deleted file mode 100644 index f614940..0000000 --- a/src/browser/events/javascript_dialog_requested_event_handler.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "javascript_dialog_requested_event_args.h" - -#include - -namespace seb::browser::events { -using JavaScriptDialogRequestedEventHandler = std::function; -} diff --git a/src/browser/events/javascript_dialog_type.h b/src/browser/events/javascript_dialog_type.h deleted file mode 100644 index 0ef8981..0000000 --- a/src/browser/events/javascript_dialog_type.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -namespace seb::browser::events { - -enum class JavaScriptDialogType -{ - Alert, - Confirm, - Prompt -}; - -} // namespace seb::browser::events diff --git a/src/browser/events/popup_requested_event_args.h b/src/browser/events/popup_requested_event_args.h deleted file mode 100644 index f7e00ed..0000000 --- a/src/browser/events/popup_requested_event_args.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::events { - -struct PopupRequestedEventArgs -{ - QString targetUrl; -}; - -} // namespace seb::browser::events diff --git a/src/browser/events/popup_requested_event_handler.h b/src/browser/events/popup_requested_event_handler.h deleted file mode 100644 index cf01fca..0000000 --- a/src/browser/events/popup_requested_event_handler.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "popup_requested_event_args.h" - -#include - -namespace seb::browser::events { -using PopupRequestedEventHandler = std::function; -} diff --git a/src/browser/events/progress_changed_event_handler.h b/src/browser/events/progress_changed_event_handler.h deleted file mode 100644 index faecebc..0000000 --- a/src/browser/events/progress_changed_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::events { -using ProgressChangedEventHandler = std::function; -} diff --git a/src/browser/events/reset_requested_event_handler.h b/src/browser/events/reset_requested_event_handler.h deleted file mode 100644 index 11c6670..0000000 --- a/src/browser/events/reset_requested_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::events { -using ResetRequestedEventHandler = std::function; -} diff --git a/src/browser/events/url_event_handler.h b/src/browser/events/url_event_handler.h deleted file mode 100644 index e5857ab..0000000 --- a/src/browser/events/url_event_handler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::events { -using UrlEventHandler = std::function; -} diff --git a/src/browser/events/window_closed_event_handler.h b/src/browser/events/window_closed_event_handler.h deleted file mode 100644 index f015b7d..0000000 --- a/src/browser/events/window_closed_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::events { -using WindowClosedEventHandler = std::function; -} diff --git a/src/browser/filters/RequestFilter.cpp b/src/browser/filters/RequestFilter.cpp deleted file mode 100644 index e9076cf..0000000 --- a/src/browser/filters/RequestFilter.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "RequestFilter.h" - -#include "RuleFactory.h" - -namespace seb::browser::filters { -namespace { - -bool matchesRule(const RuleVariant &variant, const QString &url) -{ - return std::visit([&url](const auto &compiledRule) { - return compiledRule.matches(url); - }, variant); -} - -} // namespace - -RequestFilter::RequestFilter(const seb::FilterSettings &settings) -{ - for (const auto &rule : settings.rules) { - CompiledRule compiled{RuleFactory::create(rule), rule.result}; - if (rule.result == seb::FilterResult::Allow) { - allowRules_.push_back(std::move(compiled)); - } else { - blockRules_.push_back(std::move(compiled)); - } - } -} - -bool RequestFilter::isAllowed(const QString &url) const -{ - for (const auto &rule : blockRules_) { - if (matchesRule(rule.rule, url)) { - return false; - } - } - - for (const auto &rule : allowRules_) { - if (matchesRule(rule.rule, url)) { - return true; - } - } - - return defaultResult_ == seb::FilterResult::Allow; -} - -} // namespace seb::browser::filters diff --git a/src/browser/filters/RequestFilter.h b/src/browser/filters/RequestFilter.h deleted file mode 100644 index d359e0b..0000000 --- a/src/browser/filters/RequestFilter.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "../../seb_settings.h" - -#include "RuleFactory.h" - -#include -#include - -namespace seb::browser::filters { - -class RequestFilter -{ -public: - explicit RequestFilter(const seb::FilterSettings &settings); - - bool isAllowed(const QString &url) const; - -private: - struct CompiledRule - { - RuleVariant rule; - seb::FilterResult result = seb::FilterResult::Block; - }; - - QVector allowRules_; - QVector blockRules_; - seb::FilterResult defaultResult_ = seb::FilterResult::Block; -}; - -} // namespace seb::browser::filters diff --git a/src/browser/filters/RuleFactory.cpp b/src/browser/filters/RuleFactory.cpp deleted file mode 100644 index a931ab9..0000000 --- a/src/browser/filters/RuleFactory.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "RuleFactory.h" - -namespace seb::browser::filters { - -RuleVariant RuleFactory::create(const seb::FilterRuleSettings &rule) -{ - if (rule.type == seb::FilterRuleType::Regex) { - return rules::RegexRule(rule.expression); - } - return rules::SimplifiedRule(rule.expression); -} - -} // namespace seb::browser::filters diff --git a/src/browser/filters/RuleFactory.h b/src/browser/filters/RuleFactory.h deleted file mode 100644 index 59eb2c6..0000000 --- a/src/browser/filters/RuleFactory.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../../seb_settings.h" - -#include "rules/RegexRule.h" -#include "rules/SimplifiedRule.h" - -#include - -namespace seb::browser::filters { - -using RuleVariant = std::variant; - -class RuleFactory -{ -public: - static RuleVariant create(const seb::FilterRuleSettings &rule); -}; - -} // namespace seb::browser::filters diff --git a/src/browser/filters/rules/RegexRule.cpp b/src/browser/filters/rules/RegexRule.cpp deleted file mode 100644 index 7af0ca4..0000000 --- a/src/browser/filters/rules/RegexRule.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "RegexRule.h" - -namespace seb::browser::filters::rules { - -RegexRule::RegexRule(const QString &pattern) - : regex_(pattern, QRegularExpression::CaseInsensitiveOption) -{ -} - -bool RegexRule::isValid() const -{ - return regex_.isValid(); -} - -bool RegexRule::matches(const QString &url) const -{ - return regex_.isValid() && regex_.match(url).hasMatch(); -} - -} // namespace seb::browser::filters::rules diff --git a/src/browser/filters/rules/RegexRule.h b/src/browser/filters/rules/RegexRule.h deleted file mode 100644 index e6b2864..0000000 --- a/src/browser/filters/rules/RegexRule.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::filters::rules { - -class RegexRule -{ -public: - explicit RegexRule(const QString &pattern); - - bool isValid() const; - bool matches(const QString &url) const; - -private: - QRegularExpression regex_; -}; - -} // namespace seb::browser::filters::rules diff --git a/src/browser/filters/rules/SimplifiedRule.cpp b/src/browser/filters/rules/SimplifiedRule.cpp deleted file mode 100644 index b5ea293..0000000 --- a/src/browser/filters/rules/SimplifiedRule.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "SimplifiedRule.h" - -#include -#include - -namespace seb::browser::filters::rules { -namespace { - -constexpr auto kUrlDelimiterPattern = - R"((?:([^\:]*)\://)?(?:([^\:\@]*)(?:\:([^\@]*))?\@)?(?:([^/\:\?#]*))?(?:\:([0-9\*]*))?([^\?#]*)?(?:\?([^#]*))?(?:#(.*))?)"; - -bool hasContent(const QString &expression) -{ - static const QRegularExpression pattern(QStringLiteral(R"([a-zA-Z0-9\*]+)")); - return pattern.match(expression).hasMatch(); -} - -} // namespace - -SimplifiedRule::SimplifiedRule(const QString &pattern) -{ - if (!hasContent(pattern)) { - return; - } - - const QRegularExpression delimiter(QString::fromLatin1(kUrlDelimiterPattern)); - const auto delimiterMatch = delimiter.match(pattern); - if (!delimiterMatch.hasMatch()) { - return; - } - - parseExpression(pattern); - valid_ = host_.isValid(); -} - -bool SimplifiedRule::isValid() const -{ - return valid_; -} - -bool SimplifiedRule::matches(const QString &url) const -{ - if (!valid_) { - return false; - } - - const QUrl parsed(url, QUrl::StrictMode); - if (!parsed.isValid()) { - return false; - } - - bool isMatch = true; - isMatch = isMatch && (!scheme_.isValid() || scheme_.match(parsed.scheme()).hasMatch()); - isMatch = isMatch && (!userInfo_.isValid() || userInfo_.match(parsed.userInfo()).hasMatch()); - isMatch = isMatch && host_.match(parsed.host()).hasMatch(); - isMatch = isMatch && (!port_.has_value() || port_.value() == parsed.port()); - isMatch = isMatch && (!path_.isValid() || path_.match(parsed.path()).hasMatch()); - isMatch = isMatch && (!query_.isValid() || query_.match(QStringLiteral("?") + parsed.query()).hasMatch() || - query_.match(parsed.query()).hasMatch()); - isMatch = isMatch && (!fragment_.isValid() || fragment_.match(QStringLiteral("#") + parsed.fragment()).hasMatch() || - fragment_.match(parsed.fragment()).hasMatch()); - return isMatch; -} - -QString SimplifiedRule::replaceWildcard(QString expression) -{ - expression.replace(QStringLiteral(R"(\*)"), QStringLiteral(".*")); - return expression; -} - -QRegularExpression SimplifiedRule::buildExpression(const QString &expression) -{ - return QRegularExpression(QStringLiteral("^%1$").arg(expression), QRegularExpression::CaseInsensitiveOption); -} - -void SimplifiedRule::parseExpression(const QString &expression) -{ - const QRegularExpression delimiter(QString::fromLatin1(kUrlDelimiterPattern)); - const auto match = delimiter.match(expression); - - parseScheme(match.captured(1)); - parseUserInfo(match.captured(2), match.captured(3)); - parseHost(match.captured(4)); - parsePort(match.captured(5)); - parsePath(match.captured(6)); - parseQuery(match.captured(7)); - parseFragment(match.captured(8)); -} - -void SimplifiedRule::parseScheme(QString expression) -{ - if (expression.isEmpty()) { - return; - } - - expression = replaceWildcard(QRegularExpression::escape(expression)); - scheme_ = buildExpression(expression); -} - -void SimplifiedRule::parseUserInfo(QString userName, QString password) -{ - if (userName.isEmpty()) { - return; - } - - userName = QRegularExpression::escape(userName); - password = QRegularExpression::escape(password); - - QString expression = password.isEmpty() - ? QStringLiteral("%1(:.*)?").arg(userName) - : QStringLiteral("%1:%2").arg(userName, password); - expression = replaceWildcard(expression); - - userInfo_ = buildExpression(expression); -} - -void SimplifiedRule::parseHost(QString expression) -{ - static const QRegularExpression alphaNumeric(QStringLiteral(R"(^[a-zA-Z0-9]+$)")); - const bool isAlphaNumeric = alphaNumeric.match(expression).hasMatch(); - const bool matchExactSubdomain = expression.startsWith(QLatin1Char('.')); - - if (matchExactSubdomain) { - expression.remove(0, 1); - } - - expression = replaceWildcard(QRegularExpression::escape(expression)); - if (!isAlphaNumeric && !matchExactSubdomain) { - expression = QStringLiteral("(.+?\\.)*%1").arg(expression); - } - - host_ = buildExpression(expression); -} - -void SimplifiedRule::parsePort(const QString &expression) -{ - bool ok = false; - const int parsed = expression.toInt(&ok); - if (ok) { - port_ = parsed; - } -} - -void SimplifiedRule::parsePath(QString expression) -{ - if (expression.trimmed().isEmpty() || expression == QStringLiteral("/")) { - return; - } - - expression = replaceWildcard(QRegularExpression::escape(expression)); - expression = expression.endsWith(QLatin1Char('/')) - ? QStringLiteral("%1?").arg(expression) - : QStringLiteral("%1/?").arg(expression); - - path_ = buildExpression(expression); -} - -void SimplifiedRule::parseQuery(QString expression) -{ - if (expression.trimmed().isEmpty()) { - return; - } - - if (expression == QStringLiteral(".")) { - query_ = buildExpression(QStringLiteral(R"(\??)")); - return; - } - - expression = replaceWildcard(QRegularExpression::escape(expression)); - query_ = buildExpression(QStringLiteral(R"(\??%1)").arg(expression)); -} - -void SimplifiedRule::parseFragment(QString expression) -{ - if (expression.trimmed().isEmpty()) { - return; - } - - expression = replaceWildcard(QRegularExpression::escape(expression)); - fragment_ = buildExpression(QStringLiteral("#?%1").arg(expression)); -} - -} // namespace seb::browser::filters::rules diff --git a/src/browser/filters/rules/SimplifiedRule.h b/src/browser/filters/rules/SimplifiedRule.h deleted file mode 100644 index 71b4993..0000000 --- a/src/browser/filters/rules/SimplifiedRule.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace seb::browser::filters::rules { - -class SimplifiedRule -{ -public: - explicit SimplifiedRule(const QString &pattern); - - bool isValid() const; - bool matches(const QString &url) const; - -private: - static QString replaceWildcard(QString expression); - static QRegularExpression buildExpression(const QString &expression); - - void parseExpression(const QString &expression); - void parseScheme(QString expression); - void parseUserInfo(QString userName, QString password); - void parseHost(QString expression); - void parsePort(const QString &expression); - void parsePath(QString expression); - void parseQuery(QString expression); - void parseFragment(QString expression); - - bool valid_ = false; - QRegularExpression fragment_; - QRegularExpression host_; - QRegularExpression path_; - std::optional port_; - QRegularExpression query_; - QRegularExpression scheme_; - QRegularExpression userInfo_; -}; - -} // namespace seb::browser::filters::rules diff --git a/src/browser/handlers/ContextMenuHandler.h b/src/browser/handlers/ContextMenuHandler.h deleted file mode 100644 index 0f56c28..0000000 --- a/src/browser/handlers/ContextMenuHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class ContextMenuHandler {}; } diff --git a/src/browser/handlers/CookieVisitor.h b/src/browser/handlers/CookieVisitor.h deleted file mode 100644 index ce2d91c..0000000 --- a/src/browser/handlers/CookieVisitor.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class CookieVisitor {}; } diff --git a/src/browser/handlers/DialogHandler.h b/src/browser/handlers/DialogHandler.h deleted file mode 100644 index 959ad43..0000000 --- a/src/browser/handlers/DialogHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class DialogHandler {}; } diff --git a/src/browser/handlers/DisplayHandler.h b/src/browser/handlers/DisplayHandler.h deleted file mode 100644 index 4e26e2a..0000000 --- a/src/browser/handlers/DisplayHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class DisplayHandler {}; } diff --git a/src/browser/handlers/DownloadHandler.h b/src/browser/handlers/DownloadHandler.h deleted file mode 100644 index d38c9ab..0000000 --- a/src/browser/handlers/DownloadHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class DownloadHandler {}; } diff --git a/src/browser/handlers/DragHandler.h b/src/browser/handlers/DragHandler.h deleted file mode 100644 index 766485a..0000000 --- a/src/browser/handlers/DragHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class DragHandler {}; } diff --git a/src/browser/handlers/FocusHandler.h b/src/browser/handlers/FocusHandler.h deleted file mode 100644 index a9bca64..0000000 --- a/src/browser/handlers/FocusHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class FocusHandler {}; } diff --git a/src/browser/handlers/JavaScriptDialogHandler.h b/src/browser/handlers/JavaScriptDialogHandler.h deleted file mode 100644 index 5b35e2d..0000000 --- a/src/browser/handlers/JavaScriptDialogHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class JavaScriptDialogHandler {}; } diff --git a/src/browser/handlers/KeyboardHandler.h b/src/browser/handlers/KeyboardHandler.h deleted file mode 100644 index 3dd241a..0000000 --- a/src/browser/handlers/KeyboardHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class KeyboardHandler {}; } diff --git a/src/browser/handlers/RenderProcessMessageHandler.h b/src/browser/handlers/RenderProcessMessageHandler.h deleted file mode 100644 index 987726a..0000000 --- a/src/browser/handlers/RenderProcessMessageHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class RenderProcessMessageHandler {}; } diff --git a/src/browser/handlers/RequestHandler.h b/src/browser/handlers/RequestHandler.h deleted file mode 100644 index 735a523..0000000 --- a/src/browser/handlers/RequestHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class RequestHandler {}; } diff --git a/src/browser/handlers/ResourceHandler.h b/src/browser/handlers/ResourceHandler.h deleted file mode 100644 index 735bc4c..0000000 --- a/src/browser/handlers/ResourceHandler.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::handlers { class ResourceHandler {}; } diff --git a/src/browser/integrations/EdxIntegration.h b/src/browser/integrations/EdxIntegration.h deleted file mode 100644 index 31c7ce8..0000000 --- a/src/browser/integrations/EdxIntegration.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "Integration.h" - -namespace seb::browser::integrations { - -class EdxIntegration : public Integration -{ -public: - QString name() const override { return QStringLiteral("EdxIntegration"); } -}; - -} // namespace seb::browser::integrations diff --git a/src/browser/integrations/GenericIntegration.h b/src/browser/integrations/GenericIntegration.h deleted file mode 100644 index 8699fe6..0000000 --- a/src/browser/integrations/GenericIntegration.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "Integration.h" - -namespace seb::browser::integrations { - -class GenericIntegration : public Integration -{ -public: - QString name() const override { return QStringLiteral("GenericIntegration"); } -}; - -} // namespace seb::browser::integrations diff --git a/src/browser/integrations/Integration.h b/src/browser/integrations/Integration.h deleted file mode 100644 index 1104a17..0000000 --- a/src/browser/integrations/Integration.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::integrations { - -class Integration -{ -public: - virtual ~Integration() = default; - virtual QString name() const = 0; -}; - -} // namespace seb::browser::integrations diff --git a/src/browser/integrations/MoodleIntegration.h b/src/browser/integrations/MoodleIntegration.h deleted file mode 100644 index 73972b2..0000000 --- a/src/browser/integrations/MoodleIntegration.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "Integration.h" - -namespace seb::browser::integrations { - -class MoodleIntegration : public Integration -{ -public: - QString name() const override { return QStringLiteral("MoodleIntegration"); } -}; - -} // namespace seb::browser::integrations diff --git a/src/browser/request_filter.cpp b/src/browser/request_filter.cpp index 2f9ae0b..b2cf225 100644 --- a/src/browser/request_filter.cpp +++ b/src/browser/request_filter.cpp @@ -33,7 +33,19 @@ RequestFilter::RequestFilter(const seb::FilterSettings &settings) } } -FilterDecision RequestFilter::evaluate(const QUrl &url, QWebEngineUrlRequestInfo::ResourceType resourceType) const +QRegularExpression RequestFilter::compileRule(const seb::FilterRuleSettings &rule) +{ + switch (rule.type) { + case seb::FilterRuleType::Regex: + return QRegularExpression(rule.expression, QRegularExpression::CaseInsensitiveOption); + case seb::FilterRuleType::Simplified: + return QRegularExpression(wildcardToRegexPattern(rule.expression), QRegularExpression::CaseInsensitiveOption); + } + + return {}; +} + +FilterDecision RequestFilter::evaluate(const QUrl &url, contracts::ResourceType resourceType) const { const bool mainRequest = isMainRequest(resourceType); if ((mainRequest && !settings_.processMainRequests) || (!mainRequest && !settings_.processContentRequests)) { @@ -55,23 +67,10 @@ FilterDecision RequestFilter::evaluate(const QUrl &url, QWebEngineUrlRequestInfo return FilterDecision::Block; } - -QRegularExpression RequestFilter::compileRule(const seb::FilterRuleSettings &rule) -{ - switch (rule.type) { - case seb::FilterRuleType::Regex: - return QRegularExpression(rule.expression, QRegularExpression::CaseInsensitiveOption); - case seb::FilterRuleType::Simplified: - return QRegularExpression(wildcardToRegexPattern(rule.expression), QRegularExpression::CaseInsensitiveOption); - } - - return {}; -} - -bool RequestFilter::isMainRequest(QWebEngineUrlRequestInfo::ResourceType resourceType) +bool RequestFilter::isMainRequest(contracts::ResourceType resourceType) { - return resourceType == QWebEngineUrlRequestInfo::ResourceTypeMainFrame || - resourceType == QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadMainFrame; + return resourceType == contracts::ResourceType::MainFrame || + resourceType == contracts::ResourceType::NavigationPreloadMainFrame; } } // namespace seb::browser diff --git a/src/browser/request_filter.h b/src/browser/request_filter.h index 79a7f18..e505bed 100644 --- a/src/browser/request_filter.h +++ b/src/browser/request_filter.h @@ -1,14 +1,13 @@ #pragma once - #include "../seb_settings.h" #include #include -#include -QT_BEGIN_NAMESPACE -class QUrl; -QT_END_NAMESPACE +#include "contracts/i_request_interceptor.h" + +#include +#include namespace seb::browser { @@ -24,7 +23,7 @@ class RequestFilter public: explicit RequestFilter(const seb::FilterSettings &settings); - FilterDecision evaluate(const QUrl &url, QWebEngineUrlRequestInfo::ResourceType resourceType) const; + FilterDecision evaluate(const QUrl &url, contracts::ResourceType resourceType) const; private: struct CompiledRule @@ -34,7 +33,7 @@ class RequestFilter }; static QRegularExpression compileRule(const seb::FilterRuleSettings &rule); - static bool isMainRequest(QWebEngineUrlRequestInfo::ResourceType resourceType); + static bool isMainRequest(contracts::ResourceType resourceType); seb::FilterSettings settings_; QVector allowRules_; diff --git a/src/browser/request_interceptor.cpp b/src/browser/request_interceptor.cpp index c80320e..ad6fd9d 100644 --- a/src/browser/request_interceptor.cpp +++ b/src/browser/request_interceptor.cpp @@ -1,59 +1,58 @@ #include "request_interceptor.h" #include -#include namespace seb::browser { -RequestInterceptor::RequestInterceptor(const seb::SebSettings &settings, QObject *parent) - : QWebEngineUrlRequestInterceptor(parent) - , settings_(settings) +RequestInterceptor::RequestInterceptor(const seb::SebSettings &settings) + : settings_(settings) , filter_(settings.browser.filter) , keyGenerator_(settings) { } -void RequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) +void RequestInterceptor::interceptRequest(contracts::IRequest &request) { - const QUrl requestUrl = info.requestUrl(); + const QUrl requestUrl = request.requestUrl(); if (!requestUrl.isValid()) { return; } if (requestUrl.scheme() == QStringLiteral("mailto")) { - info.block(true); + request.block(true); return; } if (requestUrl.scheme() == QStringLiteral("seb") || requestUrl.scheme() == QStringLiteral("sebs")) { - info.redirect(replaceSebScheme(requestUrl)); + request.redirect(replaceSebScheme(requestUrl)); return; } - const FilterDecision decision = filter_.evaluate(requestUrl, info.resourceType()); + const FilterDecision decision = filter_.evaluate(requestUrl, request.resourceType()); if (decision == FilterDecision::Block) { - info.block(true); + request.block(true); return; } - if (shouldAppendHeaders(info)) { + if (shouldAppendHeaders(request)) { if (settings_.browser.sendConfigurationKey && !settings_.browser.configurationKey.isEmpty()) { - info.setHttpHeader("X-SafeExamBrowser-ConfigKeyHash", keyGenerator_.configurationKeyHash(requestUrl)); + request.setHttpHeader("X-SafeExamBrowser-ConfigKeyHash", keyGenerator_.configurationKeyHash(requestUrl)); } if (settings_.browser.sendBrowserExamKey) { - info.setHttpHeader("X-SafeExamBrowser-RequestHash", keyGenerator_.requestHash(requestUrl)); + request.setHttpHeader("X-SafeExamBrowser-RequestHash", keyGenerator_.requestHash(requestUrl)); } } } -bool RequestInterceptor::shouldAppendHeaders(const QWebEngineUrlRequestInfo &info) const +bool RequestInterceptor::shouldAppendHeaders(const contracts::IRequest &request) const { - if (info.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame || - info.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeNavigationPreloadMainFrame) { + const auto type = request.resourceType(); + if (type == contracts::ResourceType::MainFrame || + type == contracts::ResourceType::NavigationPreloadMainFrame) { return true; } - return sameHost(info.firstPartyUrl(), info.requestUrl()); + return sameHost(request.firstPartyUrl(), request.requestUrl()); } bool RequestInterceptor::sameHost(const QUrl &lhs, const QUrl &rhs) @@ -72,4 +71,5 @@ QUrl RequestInterceptor::replaceSebScheme(const QUrl &url) return replaced; } + } // namespace seb::browser diff --git a/src/browser/request_interceptor.h b/src/browser/request_interceptor.h index 438f7d4..582c6a9 100644 --- a/src/browser/request_interceptor.h +++ b/src/browser/request_interceptor.h @@ -4,19 +4,19 @@ #include "key_generator.h" #include "request_filter.h" -#include +#include "contracts/i_request_interceptor.h" namespace seb::browser { -class RequestInterceptor : public QWebEngineUrlRequestInterceptor +class RequestInterceptor : public contracts::IRequestInterceptor { public: - explicit RequestInterceptor(const seb::SebSettings &settings, QObject *parent = nullptr); + explicit RequestInterceptor(const seb::SebSettings &settings); - void interceptRequest(QWebEngineUrlRequestInfo &info) override; + void interceptRequest(contracts::IRequest &request) override; private: - bool shouldAppendHeaders(const QWebEngineUrlRequestInfo &info) const; + bool shouldAppendHeaders(const contracts::IRequest &request) const; static bool sameHost(const QUrl &lhs, const QUrl &rhs); static QUrl replaceSebScheme(const QUrl &url); diff --git a/src/browser/responsibilities/BrowserTask.h b/src/browser/responsibilities/BrowserTask.h deleted file mode 100644 index 2a3977a..0000000 --- a/src/browser/responsibilities/BrowserTask.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -namespace seb::browser::responsibilities { - -enum class BrowserTask -{ - InitializeBrowserConfiguration, - InitializeCookies, - InitializeFileSystem, - InitializeIntegrity, - InitializePreferences, - CreateMainWindow, - CloseAllWindows, - FinalizeCookies, - FinalizeFileSystem, - FinalizeCache -}; - -} // namespace seb::browser::responsibilities diff --git a/src/browser/responsibilities/WindowTask.h b/src/browser/responsibilities/WindowTask.h deleted file mode 100644 index 19e913f..0000000 --- a/src/browser/responsibilities/WindowTask.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -namespace seb::browser::responsibilities { - -enum class WindowTask -{ - InitializeLifeSpanHandler, - InitializeRequestFilter -}; - -} // namespace seb::browser::responsibilities diff --git a/src/browser/responsibilities/browser/BrowserResponsibility.h b/src/browser/responsibilities/browser/BrowserResponsibility.h deleted file mode 100644 index 6957397..0000000 --- a/src/browser/responsibilities/browser/BrowserResponsibility.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -namespace seb::browser::responsibilities::browser { - -class BrowserResponsibility -{ -public: - virtual ~BrowserResponsibility() = default; -}; - -} // namespace seb::browser::responsibilities::browser diff --git a/src/browser/responsibilities/browser/CacheResponsibility.h b/src/browser/responsibilities/browser/CacheResponsibility.h deleted file mode 100644 index b9e226d..0000000 --- a/src/browser/responsibilities/browser/CacheResponsibility.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "BrowserResponsibility.h" - -namespace seb::browser::responsibilities::browser { -class CacheResponsibility : public BrowserResponsibility {}; -} diff --git a/src/browser/responsibilities/browser/ConfigurationResponsibility.h b/src/browser/responsibilities/browser/ConfigurationResponsibility.h deleted file mode 100644 index 4675ec9..0000000 --- a/src/browser/responsibilities/browser/ConfigurationResponsibility.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "BrowserResponsibility.h" - -namespace seb::browser::responsibilities::browser { -class ConfigurationResponsibility : public BrowserResponsibility {}; -} diff --git a/src/browser/responsibilities/browser/FileSystemResponsibility.h b/src/browser/responsibilities/browser/FileSystemResponsibility.h deleted file mode 100644 index 3d1025b..0000000 --- a/src/browser/responsibilities/browser/FileSystemResponsibility.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "BrowserResponsibility.h" - -namespace seb::browser::responsibilities::browser { -class FileSystemResponsibility : public BrowserResponsibility {}; -} diff --git a/src/browser/responsibilities/browser/IntegrityResponsibility.h b/src/browser/responsibilities/browser/IntegrityResponsibility.h deleted file mode 100644 index cee5704..0000000 --- a/src/browser/responsibilities/browser/IntegrityResponsibility.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "BrowserResponsibility.h" - -namespace seb::browser::responsibilities::browser { -class IntegrityResponsibility : public BrowserResponsibility {}; -} diff --git a/src/browser/responsibilities/browser/WindowHandlingResponsibility.h b/src/browser/responsibilities/browser/WindowHandlingResponsibility.h deleted file mode 100644 index 72e6a38..0000000 --- a/src/browser/responsibilities/browser/WindowHandlingResponsibility.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "BrowserResponsibility.h" - -namespace seb::browser::responsibilities::browser { -class WindowHandlingResponsibility : public BrowserResponsibility {}; -} diff --git a/src/browser/responsibilities/window/ControlResponsibility.h b/src/browser/responsibilities/window/ControlResponsibility.h deleted file mode 100644 index b93aadf..0000000 --- a/src/browser/responsibilities/window/ControlResponsibility.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::responsibilities::window { class ControlResponsibility {}; } diff --git a/src/browser/responsibilities/window/CookieResponsibility.h b/src/browser/responsibilities/window/CookieResponsibility.h deleted file mode 100644 index e15f0be..0000000 --- a/src/browser/responsibilities/window/CookieResponsibility.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::responsibilities::window { class CookieResponsibility {}; } diff --git a/src/browser/responsibilities/window/DialogResponsibility.h b/src/browser/responsibilities/window/DialogResponsibility.h deleted file mode 100644 index fd73bb7..0000000 --- a/src/browser/responsibilities/window/DialogResponsibility.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::responsibilities::window { class DialogResponsibility {}; } diff --git a/src/browser/responsibilities/window/DisplayResponsibility.h b/src/browser/responsibilities/window/DisplayResponsibility.h deleted file mode 100644 index c8b90ed..0000000 --- a/src/browser/responsibilities/window/DisplayResponsibility.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::responsibilities::window { class DisplayResponsibility {}; } diff --git a/src/browser/responsibilities/window/DownloadResponsibility.h b/src/browser/responsibilities/window/DownloadResponsibility.h deleted file mode 100644 index 26657e2..0000000 --- a/src/browser/responsibilities/window/DownloadResponsibility.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::responsibilities::window { class DownloadResponsibility {}; } diff --git a/src/browser/responsibilities/window/KeyboardResponsibility.h b/src/browser/responsibilities/window/KeyboardResponsibility.h deleted file mode 100644 index c290c7b..0000000 --- a/src/browser/responsibilities/window/KeyboardResponsibility.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::responsibilities::window { class KeyboardResponsibility {}; } diff --git a/src/browser/responsibilities/window/LifeSpanResponsibility.h b/src/browser/responsibilities/window/LifeSpanResponsibility.h deleted file mode 100644 index 7f247f6..0000000 --- a/src/browser/responsibilities/window/LifeSpanResponsibility.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::responsibilities::window { class LifeSpanResponsibility {}; } diff --git a/src/browser/responsibilities/window/RequestResponsibility.h b/src/browser/responsibilities/window/RequestResponsibility.h deleted file mode 100644 index eaf8e27..0000000 --- a/src/browser/responsibilities/window/RequestResponsibility.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::responsibilities::window { class RequestResponsibility {}; } diff --git a/src/browser/responsibilities/window/WindowResponsibility.h b/src/browser/responsibilities/window/WindowResponsibility.h deleted file mode 100644 index b1c2629..0000000 --- a/src/browser/responsibilities/window/WindowResponsibility.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::responsibilities::window { class WindowResponsibility {}; } diff --git a/src/browser/responsibilities/window/ZoomResponsibility.h b/src/browser/responsibilities/window/ZoomResponsibility.h deleted file mode 100644 index 72f6720..0000000 --- a/src/browser/responsibilities/window/ZoomResponsibility.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::responsibilities::window { class ZoomResponsibility {}; } diff --git a/src/browser/webengine_compat.h b/src/browser/webengine_compat.h new file mode 100644 index 0000000..356468c --- /dev/null +++ b/src/browser/webengine_compat.h @@ -0,0 +1,5 @@ +#pragma once + +#ifndef SEB_HAS_QTWEBENGINE +#define SEB_HAS_QTWEBENGINE 0 +#endif diff --git a/src/browser/webengine_environment.cpp b/src/browser/webengine_environment.cpp index 640bcc0..7f5f95c 100644 --- a/src/browser/webengine_environment.cpp +++ b/src/browser/webengine_environment.cpp @@ -1,5 +1,7 @@ #include "webengine_environment.h" +#include "webengine_compat.h" + #include namespace seb::browser { @@ -38,6 +40,10 @@ QString buildProxyServerValue(const seb::ProxySettings &proxySettings) void applyWebEngineEnvironment(const seb::SebSettings &settings) { +#if !SEB_HAS_QTWEBENGINE + Q_UNUSED(settings); + return; +#else if (settings.browser.proxy.policy != seb::ProxyPolicy::Custom) { return; } @@ -61,6 +67,7 @@ void applyWebEngineEnvironment(const seb::SebSettings &settings) flags.removeDuplicates(); qputenv("QTWEBENGINE_CHROMIUM_FLAGS", flags.join(' ').toUtf8()); +#endif } } // namespace seb::browser diff --git a/src/browser/wrapper/CefSharpBrowserControl.h b/src/browser/wrapper/CefSharpBrowserControl.h deleted file mode 100644 index 607e319..0000000 --- a/src/browser/wrapper/CefSharpBrowserControl.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "ICefSharpControl.h" - -namespace seb::browser::wrapper { - -class CefSharpBrowserControl : public ICefSharpControl -{ -public: - QString address() const override { return {}; } -}; - -} // namespace seb::browser::wrapper diff --git a/src/browser/wrapper/CefSharpPopupControl.h b/src/browser/wrapper/CefSharpPopupControl.h deleted file mode 100644 index 650f993..0000000 --- a/src/browser/wrapper/CefSharpPopupControl.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "ICefSharpControl.h" - -namespace seb::browser::wrapper { - -class CefSharpPopupControl : public ICefSharpControl -{ -public: - QString address() const override { return {}; } -}; - -} // namespace seb::browser::wrapper diff --git a/src/browser/wrapper/Extensions.h b/src/browser/wrapper/Extensions.h deleted file mode 100644 index af815e7..0000000 --- a/src/browser/wrapper/Extensions.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -namespace seb::browser::wrapper { - -class Extensions -{ -public: - Extensions() = delete; -}; - -} // namespace seb::browser::wrapper diff --git a/src/browser/wrapper/ICefSharpControl.h b/src/browser/wrapper/ICefSharpControl.h deleted file mode 100644 index 32a6aed..0000000 --- a/src/browser/wrapper/ICefSharpControl.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper { - -class ICefSharpControl -{ -public: - virtual ~ICefSharpControl() = default; - virtual QString address() const = 0; -}; - -} // namespace seb::browser::wrapper diff --git a/src/browser/wrapper/events/AuthCredentialsEventHandler.h b/src/browser/wrapper/events/AuthCredentialsEventHandler.h deleted file mode 100644 index 1f435e9..0000000 --- a/src/browser/wrapper/events/AuthCredentialsEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using AuthCredentialsEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/BeforeBrowseEventHandler.h b/src/browser/wrapper/events/BeforeBrowseEventHandler.h deleted file mode 100644 index 4962615..0000000 --- a/src/browser/wrapper/events/BeforeBrowseEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using BeforeBrowseEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/BeforeContextMenuEventHandler.h b/src/browser/wrapper/events/BeforeContextMenuEventHandler.h deleted file mode 100644 index 4b0f7d6..0000000 --- a/src/browser/wrapper/events/BeforeContextMenuEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using BeforeContextMenuEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/BeforeDownloadEventHandler.h b/src/browser/wrapper/events/BeforeDownloadEventHandler.h deleted file mode 100644 index 20393ce..0000000 --- a/src/browser/wrapper/events/BeforeDownloadEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using BeforeDownloadEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/BeforeUnloadDialogEventHandler.h b/src/browser/wrapper/events/BeforeUnloadDialogEventHandler.h deleted file mode 100644 index 055f8eb..0000000 --- a/src/browser/wrapper/events/BeforeUnloadDialogEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using BeforeUnloadDialogEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/CanDownloadEventHandler.h b/src/browser/wrapper/events/CanDownloadEventHandler.h deleted file mode 100644 index a5d8f2d..0000000 --- a/src/browser/wrapper/events/CanDownloadEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using CanDownloadEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/ContextCreatedEventHandler.h b/src/browser/wrapper/events/ContextCreatedEventHandler.h deleted file mode 100644 index ead880e..0000000 --- a/src/browser/wrapper/events/ContextCreatedEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using ContextCreatedEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/ContextMenuCommandEventHandler.h b/src/browser/wrapper/events/ContextMenuCommandEventHandler.h deleted file mode 100644 index 9fab140..0000000 --- a/src/browser/wrapper/events/ContextMenuCommandEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using ContextMenuCommandEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/ContextMenuDismissedEventHandler.h b/src/browser/wrapper/events/ContextMenuDismissedEventHandler.h deleted file mode 100644 index 3f2e0e2..0000000 --- a/src/browser/wrapper/events/ContextMenuDismissedEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using ContextMenuDismissedEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/ContextReleasedEventHandler.h b/src/browser/wrapper/events/ContextReleasedEventHandler.h deleted file mode 100644 index fe7617a..0000000 --- a/src/browser/wrapper/events/ContextReleasedEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using ContextReleasedEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/DialogClosedEventHandler.h b/src/browser/wrapper/events/DialogClosedEventHandler.h deleted file mode 100644 index 6932ff5..0000000 --- a/src/browser/wrapper/events/DialogClosedEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using DialogClosedEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/DownloadUpdatedEventHandler.h b/src/browser/wrapper/events/DownloadUpdatedEventHandler.h deleted file mode 100644 index e96774d..0000000 --- a/src/browser/wrapper/events/DownloadUpdatedEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using DownloadUpdatedEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/DragEnterEventHandler.h b/src/browser/wrapper/events/DragEnterEventHandler.h deleted file mode 100644 index f4a26de..0000000 --- a/src/browser/wrapper/events/DragEnterEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using DragEnterEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/DraggableRegionsChangedEventHandler.h b/src/browser/wrapper/events/DraggableRegionsChangedEventHandler.h deleted file mode 100644 index d3059b9..0000000 --- a/src/browser/wrapper/events/DraggableRegionsChangedEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using DraggableRegionsChangedEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/FaviconUrlChangedEventHandler.h b/src/browser/wrapper/events/FaviconUrlChangedEventHandler.h deleted file mode 100644 index d3da5d1..0000000 --- a/src/browser/wrapper/events/FaviconUrlChangedEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using FaviconUrlChangedEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/FileDialogRequestedEventHandler.h b/src/browser/wrapper/events/FileDialogRequestedEventHandler.h deleted file mode 100644 index 4c7fb8a..0000000 --- a/src/browser/wrapper/events/FileDialogRequestedEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using FileDialogRequestedEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/FocusedNodeChangedEventHandler.h b/src/browser/wrapper/events/FocusedNodeChangedEventHandler.h deleted file mode 100644 index 72fce19..0000000 --- a/src/browser/wrapper/events/FocusedNodeChangedEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using FocusedNodeChangedEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/GenericEventArgs.h b/src/browser/wrapper/events/GenericEventArgs.h deleted file mode 100644 index 51ae5bb..0000000 --- a/src/browser/wrapper/events/GenericEventArgs.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace seb::browser::wrapper::events { - -struct GenericEventArgs -{ - bool value = false; -}; - -} // namespace seb::browser::wrapper::events diff --git a/src/browser/wrapper/events/GotFocusEventHandler.h b/src/browser/wrapper/events/GotFocusEventHandler.h deleted file mode 100644 index 6e10b07..0000000 --- a/src/browser/wrapper/events/GotFocusEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using GotFocusEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/JavaScriptDialogEventHandler.h b/src/browser/wrapper/events/JavaScriptDialogEventHandler.h deleted file mode 100644 index e222145..0000000 --- a/src/browser/wrapper/events/JavaScriptDialogEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using JavaScriptDialogEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/KeyEventHandler.h b/src/browser/wrapper/events/KeyEventHandler.h deleted file mode 100644 index c29f271..0000000 --- a/src/browser/wrapper/events/KeyEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using KeyEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/LoadingProgressChangedEventHandler.h b/src/browser/wrapper/events/LoadingProgressChangedEventHandler.h deleted file mode 100644 index 2da9f51..0000000 --- a/src/browser/wrapper/events/LoadingProgressChangedEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using LoadingProgressChangedEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/OpenUrlFromTabEventHandler.h b/src/browser/wrapper/events/OpenUrlFromTabEventHandler.h deleted file mode 100644 index 86f875c..0000000 --- a/src/browser/wrapper/events/OpenUrlFromTabEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using OpenUrlFromTabEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/PreKeyEventHandler.h b/src/browser/wrapper/events/PreKeyEventHandler.h deleted file mode 100644 index 630ca81..0000000 --- a/src/browser/wrapper/events/PreKeyEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using PreKeyEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/ResetDialogStateEventHandler.h b/src/browser/wrapper/events/ResetDialogStateEventHandler.h deleted file mode 100644 index 7028dcb..0000000 --- a/src/browser/wrapper/events/ResetDialogStateEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using ResetDialogStateEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/ResourceRequestEventArgs.h b/src/browser/wrapper/events/ResourceRequestEventArgs.h deleted file mode 100644 index dee7dc6..0000000 --- a/src/browser/wrapper/events/ResourceRequestEventArgs.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { - -struct ResourceRequestEventArgs -{ - QString handlerId; -}; - -} // namespace seb::browser::wrapper::events diff --git a/src/browser/wrapper/events/ResourceRequestEventHandler.h b/src/browser/wrapper/events/ResourceRequestEventHandler.h deleted file mode 100644 index 7aa6738..0000000 --- a/src/browser/wrapper/events/ResourceRequestEventHandler.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "ResourceRequestEventArgs.h" - -#include - -namespace seb::browser::wrapper::events { -using ResourceRequestEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/RunContextMenuEventHandler.h b/src/browser/wrapper/events/RunContextMenuEventHandler.h deleted file mode 100644 index fd04c3f..0000000 --- a/src/browser/wrapper/events/RunContextMenuEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using RunContextMenuEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/SetFocusEventHandler.h b/src/browser/wrapper/events/SetFocusEventHandler.h deleted file mode 100644 index ea38a6a..0000000 --- a/src/browser/wrapper/events/SetFocusEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using SetFocusEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/TakeFocusEventHandler.h b/src/browser/wrapper/events/TakeFocusEventHandler.h deleted file mode 100644 index 0fc067f..0000000 --- a/src/browser/wrapper/events/TakeFocusEventHandler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::browser::wrapper::events { -using TakeFocusEventHandler = std::function; -} diff --git a/src/browser/wrapper/events/UncaughtExceptionEventHandler.h b/src/browser/wrapper/events/UncaughtExceptionEventHandler.h deleted file mode 100644 index 8b6929f..0000000 --- a/src/browser/wrapper/events/UncaughtExceptionEventHandler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::browser::wrapper::events { -using UncaughtExceptionEventHandler = std::function; -} diff --git a/src/browser/wrapper/handlers/ContextMenuHandlerSwitch.h b/src/browser/wrapper/handlers/ContextMenuHandlerSwitch.h deleted file mode 100644 index 9d162e3..0000000 --- a/src/browser/wrapper/handlers/ContextMenuHandlerSwitch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::wrapper::handlers { class ContextMenuHandlerSwitch {}; } diff --git a/src/browser/wrapper/handlers/DialogHandlerSwitch.h b/src/browser/wrapper/handlers/DialogHandlerSwitch.h deleted file mode 100644 index 8b78555..0000000 --- a/src/browser/wrapper/handlers/DialogHandlerSwitch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::wrapper::handlers { class DialogHandlerSwitch {}; } diff --git a/src/browser/wrapper/handlers/DisplayHandlerSwitch.h b/src/browser/wrapper/handlers/DisplayHandlerSwitch.h deleted file mode 100644 index 24f8a32..0000000 --- a/src/browser/wrapper/handlers/DisplayHandlerSwitch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::wrapper::handlers { class DisplayHandlerSwitch {}; } diff --git a/src/browser/wrapper/handlers/DownloadHandlerSwitch.h b/src/browser/wrapper/handlers/DownloadHandlerSwitch.h deleted file mode 100644 index fc7f1ba..0000000 --- a/src/browser/wrapper/handlers/DownloadHandlerSwitch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::wrapper::handlers { class DownloadHandlerSwitch {}; } diff --git a/src/browser/wrapper/handlers/DragHandlerSwitch.h b/src/browser/wrapper/handlers/DragHandlerSwitch.h deleted file mode 100644 index 9c50d9c..0000000 --- a/src/browser/wrapper/handlers/DragHandlerSwitch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::wrapper::handlers { class DragHandlerSwitch {}; } diff --git a/src/browser/wrapper/handlers/FocusHandlerSwitch.h b/src/browser/wrapper/handlers/FocusHandlerSwitch.h deleted file mode 100644 index a47deb1..0000000 --- a/src/browser/wrapper/handlers/FocusHandlerSwitch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::wrapper::handlers { class FocusHandlerSwitch {}; } diff --git a/src/browser/wrapper/handlers/JavaScriptDialogHandlerSwitch.h b/src/browser/wrapper/handlers/JavaScriptDialogHandlerSwitch.h deleted file mode 100644 index 9ac721b..0000000 --- a/src/browser/wrapper/handlers/JavaScriptDialogHandlerSwitch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::wrapper::handlers { class JavaScriptDialogHandlerSwitch {}; } diff --git a/src/browser/wrapper/handlers/KeyboardHandlerSwitch.h b/src/browser/wrapper/handlers/KeyboardHandlerSwitch.h deleted file mode 100644 index 7d67735..0000000 --- a/src/browser/wrapper/handlers/KeyboardHandlerSwitch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::wrapper::handlers { class KeyboardHandlerSwitch {}; } diff --git a/src/browser/wrapper/handlers/RenderProcessMessageHandlerSwitch.h b/src/browser/wrapper/handlers/RenderProcessMessageHandlerSwitch.h deleted file mode 100644 index 8940c9a..0000000 --- a/src/browser/wrapper/handlers/RenderProcessMessageHandlerSwitch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::wrapper::handlers { class RenderProcessMessageHandlerSwitch {}; } diff --git a/src/browser/wrapper/handlers/RequestHandlerSwitch.h b/src/browser/wrapper/handlers/RequestHandlerSwitch.h deleted file mode 100644 index c3d884a..0000000 --- a/src/browser/wrapper/handlers/RequestHandlerSwitch.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::browser::wrapper::handlers { class RequestHandlerSwitch {}; } diff --git a/src/browser_window.cpp b/src/browser_window.cpp index 613f340..89a18df 100644 --- a/src/browser_window.cpp +++ b/src/browser_window.cpp @@ -5,51 +5,33 @@ #include #include +#if SEB_HAS_QTWEBENGINE #include +#include +#endif +#include "browser/contracts/i_webview.h" +#include "browser/contracts/i_webprofile.h" #include #include +#include +#include #include +#include #include #include #include #include #include #include +#include #include #include #include #include -#include -#include -#include -#include -#include -BrowserPage::BrowserPage(SebSession &session, BrowserWindow *window) - : QWebEnginePage(session.profile(), window) - , session_(session) - , window_(window) -{ -} - -bool BrowserPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) -{ - if (isMainFrame && !window_->shouldAllowNavigation(url)) { - return false; - } - return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame); -} - -QStringList BrowserPage::chooseFiles( - QWebEnginePage::FileSelectionMode mode, - const QStringList &oldFiles, - const QStringList &acceptedMimeTypes) -{ - if (!session_.settings().browser.allowUploads) { - return {}; - } - return QWebEnginePage::chooseFiles(mode, oldFiles, acceptedMimeTypes); -} +#include "browser/contracts/i_engine_provider.h" +#include "browser/contracts/i_webview.h" +#include "browser/contracts/i_webprofile.h" BrowserWindow::BrowserWindow( SebSession &session, @@ -67,10 +49,15 @@ BrowserWindow::BrowserWindow( contentLayout->setContentsMargins(0, 0, 0, 0); contentLayout->setSpacing(0); - view_ = new QWebEngineView(contentContainer_); - page_ = new BrowserPage(session_, this); - view_->setPage(page_); - contentLayout->addWidget(view_, 1); + view_ = session_.engineProvider()->createWebView(session_.profile(), contentContainer_); + contentLayout->addWidget(view_->widget(), 1); + + view_->setNavigationRequestDelegate([this](const QUrl &url, bool isMainFrame) { + if (isMainFrame && !this->shouldAllowNavigation(url)) { + return false; + } + return true; + }); if (isMainWindow_ && session_.settings().taskbar.enableTaskbar) { taskbar_ = new SebTaskbar(session_, session_.settings(), contentContainer_); @@ -78,17 +65,14 @@ BrowserWindow::BrowserWindow( } setCentralWidget(contentContainer_); - view_->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, false); - view_->settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); - if (!isMainWindow_) { configureToolbar(); } configureShortcuts(); applyWindowGeometry(); - connect(view_, &QWebEngineView::urlChanged, this, &BrowserWindow::updateAddressBar); - connect(view_, &QWebEngineView::titleChanged, this, [this](const QString &title) { + connect(view_.get(), &seb::browser::contracts::IWebView::urlChanged, this, &BrowserWindow::updateAddressBar); + connect(view_.get(), &seb::browser::contracts::IWebView::titleChanged, this, [this](const QString &title) { const QString resolvedTitle = title.trimmed().isEmpty() ? QStringLiteral("SEB Linux") : title; setWindowTitle(resolvedTitle); if (taskbar_) { @@ -96,14 +80,15 @@ BrowserWindow::BrowserWindow( } notifyTaskbarStateChanged(); }); - connect(page_, &QWebEnginePage::newWindowRequested, this, &BrowserWindow::handleNewWindowRequest); + connect(view_.get(), &seb::browser::contracts::IWebView::newWindowRequested, this, &BrowserWindow::handleNewWindowRequest); connect( - page_, - &QWebEnginePage::proxyAuthenticationRequired, + view_.get(), + &seb::browser::contracts::IWebView::proxyAuthenticationRequired, this, [this](const QUrl &, QAuthenticator *authenticator, const QString &proxyHost) { session_.applyProxyAuthentication(proxyHost, authenticator); }); + if (taskbar_) { connect(taskbar_, &SebTaskbar::quitRequested, this, [this] { if (isMainWindow_ && @@ -119,6 +104,10 @@ BrowserWindow::BrowserWindow( view_->setUrl(initialUrl); } + if (view_->widget()) { + view_->widget()->installEventFilter(this); + } + session_.registerBrowserWindow(this); notifyTaskbarStateChanged(); } @@ -128,9 +117,9 @@ BrowserWindow::~BrowserWindow() session_.unregisterBrowserWindow(this); } -QWebEnginePage *BrowserWindow::page() const +QUrl BrowserWindow::currentUrl() const { - return page_; + return view_ ? view_->url() : QUrl(); } bool BrowserWindow::isMainWindow() const @@ -224,30 +213,49 @@ void BrowserWindow::keyPressEvent(QKeyEvent *event) const bool ctrl = event->modifiers().testFlag(Qt::ControlModifier); const bool shift = event->modifiers().testFlag(Qt::ShiftModifier); const bool alt = event->modifiers().testFlag(Qt::AltModifier); + const bool devBypass = session_.settings().devBypass; + + if (event->key() == Qt::Key_F11) { + if (devBypass) { + if (isFullScreen()) { + showNormal(); + if (toolbar_) toolbar_->show(); + if (taskbar_) taskbar_->show(); + } else { + showFullScreen(); + if (toolbar_) toolbar_->hide(); + if (taskbar_) taskbar_->show(); + } + } + event->accept(); + return; + } if (!windowSettings_.allowReloading && - (event->key() == Qt::Key_F5 || (ctrl && event->key() == Qt::Key_R))) { + (event->key() == Qt::Key_F5 || (ctrl && event->key() == Qt::Key_R)) && + !devBypass) { event->accept(); return; } if (!windowSettings_.allowBackwardNavigation && - ((alt && event->key() == Qt::Key_Left) || event->key() == Qt::Key_Backspace)) { + ((alt && event->key() == Qt::Key_Left) || event->key() == Qt::Key_Backspace) && + !devBypass) { event->accept(); return; } - if (!windowSettings_.allowForwardNavigation && (alt && event->key() == Qt::Key_Right)) { + if (!windowSettings_.allowForwardNavigation && (alt && event->key() == Qt::Key_Right) && !devBypass) { event->accept(); return; } - if (!session_.settings().browser.allowPrint && ctrl && event->key() == Qt::Key_P) { + if (!session_.settings().browser.allowPrint && ctrl && event->key() == Qt::Key_P && !devBypass) { event->accept(); return; } - if (!session_.settings().browser.allowFind && ctrl && event->key() == Qt::Key_F) { + if (!session_.settings().browser.allowFind && ctrl && event->key() == Qt::Key_F && !devBypass) { event->accept(); return; } @@ -255,12 +263,13 @@ void BrowserWindow::keyPressEvent(QKeyEvent *event) if (!session_.settings().browser.allowPageZoom && ctrl && (event->key() == Qt::Key_Plus || event->key() == Qt::Key_Equal || event->key() == Qt::Key_Minus || - event->key() == Qt::Key_0)) { + event->key() == Qt::Key_0) && + !devBypass) { event->accept(); return; } - if (!windowSettings_.allowDeveloperConsole && event->key() == Qt::Key_F12) { + if (!windowSettings_.allowDeveloperConsole && event->key() == Qt::Key_F12 && !devBypass) { event->accept(); return; } @@ -285,6 +294,16 @@ void BrowserWindow::focusInEvent(QFocusEvent *event) notifyTaskbarStateChanged(); } +void BrowserWindow::focusOutEvent(QFocusEvent *event) +{ + QMainWindow::focusOutEvent(event); +} + +bool BrowserWindow::eventFilter(QObject *watched, QEvent *event) +{ + return QMainWindow::eventFilter(watched, event); +} + void BrowserWindow::applyWindowFlags() { setWindowFlag(Qt::WindowStaysOnTopHint, windowSettings_.alwaysOnTop); @@ -401,6 +420,40 @@ void BrowserWindow::configureToolbar() } } +void BrowserWindow::configureFallbackView(const QUrl &initialUrl) +{ +#if SEB_HAS_QTWEBENGINE + Q_UNUSED(initialUrl); +#else + fallbackUrl_ = initialUrl; + if (!fallbackView_) { + fallbackView_ = new QTextBrowser(contentContainer_); + fallbackView_->setFrameShape(QFrame::NoFrame); + fallbackView_->setOpenLinks(false); + fallbackView_->setOpenExternalLinks(false); + fallbackView_->setReadOnly(true); + fallbackView_->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse); + } + + const QString targetUrl = fallbackUrl_.isValid() + ? fallbackUrl_.toDisplayString() + : QStringLiteral("Not configured"); + const QString homeUrl = session_.homeUrl().isValid() + ? session_.homeUrl().toDisplayString() + : QStringLiteral("Not configured"); + + fallbackView_->setHtml(QStringLiteral( + "

Qt WebEngine Is Unavailable

" + "

This build can still load SEB configuration, start the protected shell, and exercise the Linux UI, " + "but it cannot render exam pages because Qt WebEngine is disabled for this target.

" + "

Current target URL: %1
" + "Configured home URL: %2

" + "

This compatibility mode is intended for architectures such as riscv64 until a supported " + "embedded browser engine becomes available.

") + .arg(targetUrl.toHtmlEscaped(), homeUrl.toHtmlEscaped())); +#endif +} + void BrowserWindow::configureShortcuts() { auto *reloadAction = new QAction(this); @@ -439,7 +492,11 @@ void BrowserWindow::configureShortcuts() auto *devToolsAction = new QAction(this); devToolsAction->setShortcut(QKeySequence(Qt::Key_F12)); addAction(devToolsAction); - connect(devToolsAction, &QAction::triggered, this, &BrowserWindow::openDevTools); + connect(devToolsAction, &QAction::triggered, this, [this] { + if (windowSettings_.allowDeveloperConsole && view_) { + view_->openDevTools(); + } + }); if (windowSettings_.allowAddressBar && addressBar_) { auto *focusAddressBar = new QAction(this); @@ -461,17 +518,21 @@ void BrowserWindow::findInPage() bool accepted = false; const QString text = QInputDialog::getText( this, - QStringLiteral("Find in Page"), - QStringLiteral("Search text:"), + tr("Find in Page"), + tr("Search text:"), QLineEdit::Normal, QString(), &accepted); + if (!accepted || text.isEmpty()) { return; } - page_->findText(QString()); - page_->findText(text); + if (view_) { + // First clear selection then search + view_->findText(QString()); + view_->findText(text); + } } void BrowserWindow::navigateHome() @@ -485,49 +546,47 @@ void BrowserWindow::navigateHome() return; } - view_->setUrl(home); + if (view_) { + view_->setUrl(home); + updateAddressBar(home); + } } -void BrowserWindow::openDevTools() -{ - if (!windowSettings_.allowDeveloperConsole) { - return; - } - auto *devTools = new QWebEngineView(); - auto *devPage = new QWebEnginePage(session_.profile(), devTools); - page_->setDevToolsPage(devPage); - devTools->setPage(devPage); - devTools->setAttribute(Qt::WA_DeleteOnClose); - devTools->resize(1100, 700); - devTools->show(); -} -void BrowserWindow::handleNewWindowRequest(QWebEngineNewWindowRequest &request) +void BrowserWindow::handleNewWindowRequest(const QUrl &target, bool &handled) { bool openInSameWindow = false; - const QUrl target = request.requestedUrl(); const QUrl opener = view_->url(); const QString scheme = target.scheme().toLower(); if (scheme == QStringLiteral("seb") || scheme == QStringLiteral("sebs") || target.path().endsWith(QStringLiteral(".seb"), Qt::CaseInsensitive)) { session_.openSebResource(target, this); + handled = true; return; } if (!session_.isPopupAllowed(opener, target, &openInSameWindow)) { + handled = true; // Blocked popup return; } if (openInSameWindow) { - request.openIn(page_); + if (view_) { + view_->setUrl(target); + } else { + // Unlikely to hit this branch unless we are in the compat window + } + handled = true; return; } auto *window = session_.createWindow(target, false); - window->show(); - request.openIn(window->page()); + if (window) { + window->show(); + } + handled = true; } void BrowserWindow::reloadPage() @@ -540,7 +599,9 @@ void BrowserWindow::reloadPage() return; } - view_->reload(); + if (view_) { + view_->reload(); + } } void BrowserWindow::updateAddressBar(const QUrl &url) diff --git a/src/browser_window.h b/src/browser_window.h index 051e45c..02a0afe 100644 --- a/src/browser_window.h +++ b/src/browser_window.h @@ -3,43 +3,38 @@ #include "seb_settings.h" #include -#include + + +#include QT_BEGIN_NAMESPACE +#if SEB_HAS_QTWEBENGINE class QAuthenticator; +#endif class QCloseEvent; class QEvent; class QFocusEvent; class QKeyEvent; class QLineEdit; +class QTextBrowser; class QToolBar; class QWidget; class QUrl; +#if SEB_HAS_QTWEBENGINE class QWebEngineNewWindowRequest; class QWebEngineView; +#endif QT_END_NAMESPACE +namespace seb::browser::contracts { +class IWebView; +} + class SebSession; class SebTaskbar; class BrowserWindow; -class BrowserPage : public QWebEnginePage -{ -public: - BrowserPage(SebSession &session, BrowserWindow *window); - -protected: - bool acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) override; - QStringList chooseFiles( - QWebEnginePage::FileSelectionMode mode, - const QStringList &oldFiles, - const QStringList &acceptedMimeTypes) override; - -private: - SebSession &session_; - BrowserWindow *window_; -}; class BrowserWindow : public QMainWindow { @@ -53,7 +48,8 @@ class BrowserWindow : public QMainWindow bool isMainWindow); ~BrowserWindow() override; - QWebEnginePage *page() const; + + QUrl currentUrl() const; bool isMainWindow() const; bool shouldAllowNavigation(const QUrl &url); QString taskbarIconPath() const; @@ -64,24 +60,25 @@ class BrowserWindow : public QMainWindow void closeEvent(QCloseEvent *event) override; void keyPressEvent(QKeyEvent *event) override; void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; private: void applyWindowFlags(); void applyWindowGeometry(); void configureToolbar(); + void configureFallbackView(const QUrl &initialUrl); void configureShortcuts(); void findInPage(); void navigateHome(); - void openDevTools(); - void handleNewWindowRequest(QWebEngineNewWindowRequest &request); + void handleNewWindowRequest(const QUrl &url, bool &handled); void reloadPage(); void updateAddressBar(const QUrl &url); void notifyTaskbarStateChanged(); SebSession &session_; seb::WindowSettings windowSettings_; - QWebEngineView *view_ = nullptr; - BrowserPage *page_ = nullptr; + std::unique_ptr view_; QWidget *contentContainer_ = nullptr; QToolBar *toolbar_ = nullptr; QLineEdit *addressBar_ = nullptr; diff --git a/src/communication/Properties/AssemblyInfo.h b/src/communication/Properties/AssemblyInfo.h deleted file mode 100644 index f44536b..0000000 --- a/src/communication/Properties/AssemblyInfo.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -namespace seb::communication::assemblyinfo { - -inline constexpr auto kTitle = "SafeExamBrowser.Communication"; -inline constexpr auto kDescription = "Safe Exam Browser"; -inline constexpr auto kCompany = "JVR2022"; -inline constexpr auto kProduct = "SafeExamBrowser.Communication"; -inline constexpr auto kCopyright = "Copyright (C) 2026 JVR2022"; -inline constexpr auto kGuid = "c9416a62-0623-4d38-96aa-92516b32f02f"; -inline constexpr auto kVersion = "1.0.0.0"; - -} // namespace seb::communication::assemblyinfo diff --git a/src/communication/contracts/Properties/AssemblyInfo.h b/src/communication/contracts/Properties/AssemblyInfo.h deleted file mode 100644 index ee0b336..0000000 --- a/src/communication/contracts/Properties/AssemblyInfo.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -namespace seb::communication::contracts::assemblyinfo { - -inline constexpr auto kTitle = "SafeExamBrowser.Communication.Contracts"; -inline constexpr auto kDescription = "Safe Exam Browser"; -inline constexpr auto kCompany = "JVR2022"; -inline constexpr auto kProduct = "SafeExamBrowser.Communication.Contracts"; -inline constexpr auto kCopyright = "Copyright (C) 2026 JVR2022"; -inline constexpr auto kGuid = "0cd2c5fe-711a-4c32-afe0-bb804fe8b220"; -inline constexpr auto kVersion = "1.0.0.0"; - -} // namespace seb::communication::contracts::assemblyinfo diff --git a/src/configuration/contracts/cryptography/i_certificate_store.h b/src/configuration/contracts/cryptography/i_certificate_store.h index e040b92..bfb3979 100644 --- a/src/configuration/contracts/cryptography/i_certificate_store.h +++ b/src/configuration/contracts/cryptography/i_certificate_store.h @@ -2,6 +2,7 @@ #include #include +#include #include namespace seb::configuration::contracts::cryptography { @@ -11,6 +12,7 @@ class ICertificateStore public: virtual ~ICertificateStore() = default; virtual bool tryGetCertificateWith(const QByteArray &keyHash, QSslCertificate &certificate) const = 0; + virtual bool tryGetPrivateKeyFor(const QSslCertificate &certificate, QSslKey &key) const = 0; virtual void extractAndImportIdentities(const QVariantMap &data) = 0; }; diff --git a/src/configuration/cryptography/certificate_store.cpp b/src/configuration/cryptography/certificate_store.cpp index 6c21661..4e2f909 100644 --- a/src/configuration/cryptography/certificate_store.cpp +++ b/src/configuration/cryptography/certificate_store.cpp @@ -1,5 +1,8 @@ #include "certificate_store.h" +#include +#include + namespace seb::configuration::cryptography { bool CertificateStore::tryGetCertificateWith(const QByteArray &keyHash, QSslCertificate &certificate) const @@ -12,16 +15,56 @@ bool CertificateStore::tryGetCertificateWith(const QByteArray &keyHash, QSslCert return true; } +bool CertificateStore::tryGetPrivateKeyFor(const QSslCertificate &certificate, QSslKey &key) const +{ + for (const auto &pair : identities_) { + if (pair.first == certificate) { + key = pair.second; + return true; + } + } + return false; +} + void CertificateStore::extractAndImportIdentities(const QVariantMap &data) { - const QByteArray pem = data.value(QStringLiteral("embeddedCertificate")).toByteArray(); - if (pem.isEmpty()) { - return; + // SEB usually stores identities in a list of dictionaries + const QVariantList identities = data.value(QStringLiteral("identities")).toList(); + for (const QVariant &v : identities) { + const QVariantMap m = v.toMap(); + const QByteArray certData = m.value(QStringLiteral("certificate")).toByteArray(); + const QByteArray keyData = m.value(QStringLiteral("privateKey")).toByteArray(); + + if (certData.isEmpty()) continue; + + QSslCertificate cert(certData); + if (cert.isNull()) { + // Try base64 + cert = QSslCertificate(QByteArray::fromBase64(certData)); + } + + if (!cert.isNull()) { + certificates_.insert(cert.digest(), cert); + + if (!keyData.isEmpty()) { + QSslKey key(keyData, QSsl::Rsa); // Assuming RSA for SEB + if (key.isNull()) { + key = QSslKey(QByteArray::fromBase64(keyData), QSsl::Rsa); + } + if (!key.isNull()) { + identities_.append({cert, key}); + } + } + } } - const QSslCertificate certificate(pem); - if (!certificate.isNull()) { - certificates_.insert(certificate.digest(), certificate); + // Also check for legacy 'embeddedCertificate' for backward compatibility + const QByteArray pem = data.value(QStringLiteral("embeddedCertificate")).toByteArray(); + if (!pem.isEmpty()) { + QSslCertificate certificate(pem); + if (!certificate.isNull()) { + certificates_.insert(certificate.digest(), certificate); + } } } diff --git a/src/configuration/cryptography/certificate_store.h b/src/configuration/cryptography/certificate_store.h index 3dcabb7..378c018 100644 --- a/src/configuration/cryptography/certificate_store.h +++ b/src/configuration/cryptography/certificate_store.h @@ -3,6 +3,8 @@ #include "../contracts/cryptography/i_certificate_store.h" #include +#include +#include namespace seb::configuration::cryptography { @@ -10,10 +12,12 @@ class CertificateStore : public contracts::cryptography::ICertificateStore { public: bool tryGetCertificateWith(const QByteArray &keyHash, QSslCertificate &certificate) const override; + bool tryGetPrivateKeyFor(const QSslCertificate &certificate, QSslKey &key) const override; void extractAndImportIdentities(const QVariantMap &data) override; private: QHash certificates_; + QList> identities_; }; } // namespace seb::configuration::cryptography diff --git a/src/configuration/cryptography/password_encryption.cpp b/src/configuration/cryptography/password_encryption.cpp index baefc84..636e0fa 100644 --- a/src/configuration/cryptography/password_encryption.cpp +++ b/src/configuration/cryptography/password_encryption.cpp @@ -1,21 +1,165 @@ #include "password_encryption.h" +#include +#include +#include +#include + namespace seb::configuration::cryptography { -contracts::LoadStatus PasswordEncryption::decrypt(const QByteArray &data, const QString &password, QByteArray &decrypted) const -{ - if (password.isNull()) { - return contracts::LoadStatus::PasswordNeeded; - } +namespace { +constexpr int kIterations = 10000; +constexpr int kKeySize = 32; +constexpr int kSaltSize = 8; +constexpr int kIvSize = 16; +constexpr int kVersion = 2; +constexpr int kOptions = 1; +constexpr int kHmacSize = 32; +} // namespace + +contracts::LoadStatus PasswordEncryption::decrypt(const QByteArray &data, + const QString &password, + QByteArray &decrypted) const { + if (password.isNull()) + return contracts::LoadStatus::PasswordNeeded; + if (data.size() < (2 + 2 * kSaltSize + kIvSize + kHmacSize)) + return contracts::LoadStatus::InvalidData; + + const char *ptr = data.constData(); + if (static_cast(ptr[0]) != kVersion || + static_cast(ptr[1]) != kOptions) + return contracts::LoadStatus::InvalidData; + + QByteArray encSalt = data.mid(2, kSaltSize); + QByteArray authSalt = data.mid(2 + kSaltSize, kSaltSize); + QByteArray iv = data.mid(2 + 2 * kSaltSize, kIvSize); + QByteArray payload = + data.mid(2 + 2 * kSaltSize + kIvSize, + data.size() - (2 + 2 * kSaltSize + kIvSize + kHmacSize)); + QByteArray originalHmac = data.right(kHmacSize); + + QByteArray encryptionKey(kKeySize, 0); + QByteArray authenticationKey(kKeySize, 0); + + PKCS5_PBKDF2_HMAC_SHA1( + password.toUtf8().constData(), -1, + reinterpret_cast(encSalt.constData()), kSaltSize, + kIterations, kKeySize, + reinterpret_cast(encryptionKey.data())); + PKCS5_PBKDF2_HMAC_SHA1( + password.toUtf8().constData(), -1, + reinterpret_cast(authSalt.constData()), kSaltSize, + kIterations, kKeySize, + reinterpret_cast(authenticationKey.data())); + + // Verify HMAC + unsigned char computedHmac[kHmacSize]; + if (!HMAC(EVP_sha256(), authenticationKey.constData(), kKeySize, + reinterpret_cast(data.constData()), + data.size() - kHmacSize, computedHmac, nullptr)) { + return contracts::LoadStatus::UnexpectedError; + } + + if (CRYPTO_memcmp(computedHmac, originalHmac.constData(), kHmacSize) != 0) { + return contracts::LoadStatus::InvalidData; + } + + // Decrypt + decrypted.resize(payload.size()); + int outLen = 0; + int finalLen = 0; + + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + if (!ctx) return contracts::LoadStatus::UnexpectedError; + + auto cleanup = [ctx, &decrypted]() { + EVP_CIPHER_CTX_free(ctx); + decrypted.clear(); + }; - decrypted = data; - return contracts::LoadStatus::Success; + if (EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, + reinterpret_cast(encryptionKey.constData()), + reinterpret_cast(iv.constData())) != 1) { + cleanup(); + return contracts::LoadStatus::UnexpectedError; + } + + if (EVP_DecryptUpdate(ctx, reinterpret_cast(decrypted.data()), &outLen, + reinterpret_cast(payload.constData()), + payload.size()) != 1) { + cleanup(); + return contracts::LoadStatus::InvalidData; + } + + if (EVP_DecryptFinal_ex(ctx, reinterpret_cast(decrypted.data()) + outLen, &finalLen) != 1) { + cleanup(); + return contracts::LoadStatus::InvalidData; + } + + EVP_CIPHER_CTX_free(ctx); + decrypted.resize(outLen + finalLen); + return contracts::LoadStatus::Success; } -contracts::SaveStatus PasswordEncryption::encrypt(const QByteArray &data, const QString &, QByteArray &encrypted) const -{ - encrypted = data; - return contracts::SaveStatus::Success; +contracts::SaveStatus PasswordEncryption::encrypt(const QByteArray &data, + const QString &password, + QByteArray &encrypted) const { + if (password.isNull()) + return contracts::SaveStatus::UnexpectedError; + + QByteArray encSalt(kSaltSize, 0); + QByteArray authSalt(kSaltSize, 0); + QByteArray iv(kIvSize, 0); + RAND_bytes(reinterpret_cast(encSalt.data()), kSaltSize); + RAND_bytes(reinterpret_cast(authSalt.data()), kSaltSize); + RAND_bytes(reinterpret_cast(iv.data()), kIvSize); + + QByteArray encryptionKey(kKeySize, 0); + QByteArray authenticationKey(kKeySize, 0); + PKCS5_PBKDF2_HMAC_SHA1( + password.toUtf8().constData(), -1, + reinterpret_cast(encSalt.constData()), kSaltSize, + kIterations, kKeySize, + reinterpret_cast(encryptionKey.data())); + PKCS5_PBKDF2_HMAC_SHA1( + password.toUtf8().constData(), -1, + reinterpret_cast(authSalt.constData()), kSaltSize, + kIterations, kKeySize, + reinterpret_cast(authenticationKey.data())); + + encrypted.clear(); + encrypted.append(static_cast(kVersion)); + encrypted.append(static_cast(kOptions)); + encrypted.append(encSalt); + encrypted.append(authSalt); + encrypted.append(iv); + + QByteArray cipherData(data.size() + kIvSize, 0); + int outLen = 0; + int finalLen = 0; + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex( + ctx, EVP_aes_256_cbc(), nullptr, + reinterpret_cast(encryptionKey.constData()), + reinterpret_cast(iv.constData())); + EVP_EncryptUpdate( + ctx, reinterpret_cast(cipherData.data()), &outLen, + reinterpret_cast(data.constData()), data.size()); + EVP_EncryptFinal_ex( + ctx, reinterpret_cast(cipherData.data()) + outLen, + &finalLen); + EVP_CIPHER_CTX_free(ctx); + cipherData.resize(outLen + finalLen); + encrypted.append(cipherData); + + unsigned int hmacLen = 0; + unsigned char hmac[kHmacSize]; + HMAC(EVP_sha256(), authenticationKey.constData(), kKeySize, + reinterpret_cast(encrypted.constData()), + encrypted.size(), hmac, &hmacLen); + encrypted.append(reinterpret_cast(hmac), kHmacSize); + + return contracts::SaveStatus::Success; } -} // namespace seb::configuration::cryptography +} // namespace seb::configuration::cryptography diff --git a/src/configuration/cryptography/public_key_encryption.cpp b/src/configuration/cryptography/public_key_encryption.cpp index 5e00e8d..fae0c9e 100644 --- a/src/configuration/cryptography/public_key_encryption.cpp +++ b/src/configuration/cryptography/public_key_encryption.cpp @@ -1,5 +1,10 @@ #include "public_key_encryption.h" +#include +#include +#include +#include + namespace seb::configuration::cryptography { PublicKeyEncryption::PublicKeyEncryption(contracts::cryptography::ICertificateStore &store) @@ -9,18 +14,79 @@ PublicKeyEncryption::PublicKeyEncryption(contracts::cryptography::ICertificateSt contracts::LoadStatus PublicKeyEncryption::decrypt(const QByteArray &data, QByteArray &decrypted, QSslCertificate &certificate) const { - if (!store_.tryGetCertificateWith(data.left(20), certificate)) { + if (data.size() < 20) return contracts::LoadStatus::InvalidData; + + const QByteArray keyHash = data.left(20); + if (!store_.tryGetCertificateWith(keyHash, certificate)) { + return contracts::LoadStatus::InvalidData; + } + + QSslKey privateKey; + if (!store_.tryGetPrivateKeyFor(certificate, privateKey)) { + return contracts::LoadStatus::PasswordNeeded; // Or a more specific status + } + + const QByteArray cipherData = data.mid(20); + + // Convert QSslKey to EVP_PKEY via PEM to avoid fragile handle() casts + const QByteArray pemKey = privateKey.toPem(); + BIO *bio = BIO_new_mem_buf(pemKey.constData(), pemKey.size()); + if (!bio) return contracts::LoadStatus::UnexpectedError; + + EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr); + BIO_free(bio); + if (!pkey) return contracts::LoadStatus::UnexpectedError; + + auto cleanup = [pkey]() { + EVP_PKEY_free(pkey); + }; + + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, nullptr); + if (!ctx) { + cleanup(); + return contracts::LoadStatus::UnexpectedError; + } + + if (EVP_PKEY_decrypt_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + cleanup(); + return contracts::LoadStatus::UnexpectedError; + } + + if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) { + EVP_PKEY_CTX_free(ctx); + cleanup(); + return contracts::LoadStatus::UnexpectedError; + } + + size_t outLen = 0; + if (EVP_PKEY_decrypt(ctx, nullptr, &outLen, + reinterpret_cast(cipherData.constData()), + cipherData.size()) <= 0) { + EVP_PKEY_CTX_free(ctx); + cleanup(); return contracts::LoadStatus::InvalidData; } - decrypted = data.mid(20); + decrypted.resize(static_cast(outLen)); + if (EVP_PKEY_decrypt(ctx, reinterpret_cast(decrypted.data()), &outLen, + reinterpret_cast(cipherData.constData()), + cipherData.size()) <= 0) { + EVP_PKEY_CTX_free(ctx); + cleanup(); + return contracts::LoadStatus::InvalidData; + } + + decrypted.resize(static_cast(outLen)); + EVP_PKEY_CTX_free(ctx); + cleanup(); + return contracts::LoadStatus::Success; } -contracts::SaveStatus PublicKeyEncryption::encrypt(const QByteArray &data, const QSslCertificate &, QByteArray &encrypted) const +contracts::SaveStatus PublicKeyEncryption::encrypt(const QByteArray &, const QSslCertificate &, QByteArray &) const { - encrypted = data; - return contracts::SaveStatus::Success; + return contracts::SaveStatus::NotSupported; } } // namespace seb::configuration::cryptography diff --git a/src/configuration/cryptography/public_key_symmetric_encryption.cpp b/src/configuration/cryptography/public_key_symmetric_encryption.cpp index 25e3296..0f02dee 100644 --- a/src/configuration/cryptography/public_key_symmetric_encryption.cpp +++ b/src/configuration/cryptography/public_key_symmetric_encryption.cpp @@ -1,21 +1,61 @@ #include "public_key_symmetric_encryption.h" +#include + namespace seb::configuration::cryptography { -QByteArray PublicKeySymmetricEncryption::decrypt(const QByteArray &data, const contracts::cryptography::PublicKeyParameters &, bool *ok) const +PublicKeySymmetricEncryption::PublicKeySymmetricEncryption( + contracts::cryptography::ICertificateStore &store, + contracts::cryptography::IPublicKeyEncryption &rsa, + contracts::cryptography::IPasswordEncryption &aes) + : store_(store) + , rsa_(rsa) + , aes_(aes) { - if (ok) { - *ok = true; - } - return data; } -QByteArray PublicKeySymmetricEncryption::encrypt(const QByteArray &data, const contracts::cryptography::PublicKeyParameters &, bool *ok) const +contracts::LoadStatus PublicKeySymmetricEncryption::decrypt(const QByteArray &data, QByteArray &decrypted, QSslCertificate &certificate) const { - if (ok) { - *ok = true; + if (data.size() < 24) return contracts::LoadStatus::InvalidData; // 20 (hash) + 4 (length) + + // First 20 bytes are public key hash + const QByteArray keyHash = data.left(20); + + // Next 4 bytes are encrypted key length (little endian int) + QDataStream ds(data.mid(20, 4)); + ds.setByteOrder(QDataStream::LittleEndian); + qint32 encryptedKeyLength = 0; + ds >> encryptedKeyLength; + + const int remainingDataSize = data.size() - 24; + if (encryptedKeyLength < 0 || encryptedKeyLength > remainingDataSize) { + return contracts::LoadStatus::InvalidData; } - return data; + + const QByteArray encryptedKey = data.mid(24, encryptedKeyLength); + const QByteArray payload = data.mid(24 + encryptedKeyLength); + + // Decrypt the symmetric key using RSA + // We need the keyHash block to identify the cert, so we prepend it for the rsa_.decrypt call + QByteArray rsaBlock = keyHash + encryptedKey; + QByteArray decryptedKey; + auto status = rsa_.decrypt(rsaBlock, decryptedKey, certificate); + if (status != contracts::LoadStatus::Success) return status; + + // The decrypted key is likely a base64 string or raw bytes. + // SEB Windows converts it to base64 before using it as the password for PasswordEncryption. + // Wait, let's look at PasswordSymmetricEncryption.cs line 102: + // var symmetricKey = Convert.ToBase64String(decryptedKey.ToArray()); + // So we use the base64 version. + const QString aesPassword = QString::fromLatin1(decryptedKey.toBase64()); + + // Decrypt the payload using AES + return aes_.decrypt(payload, aesPassword, decrypted); +} + +contracts::SaveStatus PublicKeySymmetricEncryption::encrypt(const QByteArray &, const QSslCertificate &, QByteArray &) const +{ + return contracts::SaveStatus::NotSupported; } } // namespace seb::configuration::cryptography diff --git a/src/configuration/cryptography/public_key_symmetric_encryption.h b/src/configuration/cryptography/public_key_symmetric_encryption.h index 41ce179..e8e75ca 100644 --- a/src/configuration/cryptography/public_key_symmetric_encryption.h +++ b/src/configuration/cryptography/public_key_symmetric_encryption.h @@ -1,16 +1,26 @@ #pragma once -#include "../contracts/cryptography/public_key_parameters.h" - -#include +#include "../contracts/cryptography/i_public_key_encryption.h" +#include "../contracts/cryptography/i_password_encryption.h" +#include "../contracts/cryptography/i_certificate_store.h" namespace seb::configuration::cryptography { -class PublicKeySymmetricEncryption +class PublicKeySymmetricEncryption : public contracts::cryptography::IPublicKeyEncryption { public: - QByteArray decrypt(const QByteArray &data, const contracts::cryptography::PublicKeyParameters ¶meters, bool *ok = nullptr) const; - QByteArray encrypt(const QByteArray &data, const contracts::cryptography::PublicKeyParameters ¶meters, bool *ok = nullptr) const; + PublicKeySymmetricEncryption( + contracts::cryptography::ICertificateStore &store, + contracts::cryptography::IPublicKeyEncryption &rsa, + contracts::cryptography::IPasswordEncryption &aes); + + contracts::LoadStatus decrypt(const QByteArray &data, QByteArray &decrypted, QSslCertificate &certificate) const override; + contracts::SaveStatus encrypt(const QByteArray &data, const QSslCertificate &certificate, QByteArray &encrypted) const override; + +private: + contracts::cryptography::ICertificateStore &store_; + contracts::cryptography::IPublicKeyEncryption &rsa_; + contracts::cryptography::IPasswordEncryption &aes_; }; } // namespace seb::configuration::cryptography diff --git a/src/main.cpp b/src/main.cpp index 6ca2623..e8bef57 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include "app_controller.h" +#include "security/security_service.h" #include "browser/webengine_environment.h" #include "seb_settings.h" @@ -14,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -137,13 +140,12 @@ bool hasArgument(int argc, char *argv[], const QString &value) return false; } -void appendPkexecEnvironmentVariable(QStringList &pkexecArgs, const char *name) +static void appendPkexecEnvironmentVariable(QStringList &args, const char *name) { - if (!qEnvironmentVariableIsSet(name)) { - return; + const QByteArray value = qgetenv(name); + if (!value.isEmpty()) { + args << (QString(name) + QLatin1Char('=') + QString::fromLocal8Bit(value)); } - - pkexecArgs << QStringLiteral("%1=%2").arg(QString::fromLatin1(name), QString::fromLocal8Bit(qgetenv(name))); } void applyProtectedWindowSettings(seb::WindowSettings &settings, bool fullScreen) @@ -223,7 +225,9 @@ void applyEarlyEnvironment(int argc, char *argv[]) qputenv("QT_QPA_PLATFORM", "linuxfb"); qputenv("QT_QUICK_BACKEND", "software"); } +#if SEB_HAS_QTWEBENGINE qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--no-sandbox"); +#endif } seb::browser::applyWebEngineEnvironment(settings); @@ -275,6 +279,10 @@ void applyCommandLineOverrides(const QCommandLineParser &parser, seb::SebSetting if (parser.isSet("disable-quit")) { settings.security.allowTermination = false; } + + if (parser.isSet("dev-bypass")) { + settings.devBypass = true; + } } } // namespace @@ -327,17 +335,28 @@ int main(int argc, char *argv[]) QStringLiteral("disable-quit"), QStringLiteral("Disable manual termination even if the configuration allows it."))); parser.addOption(QCommandLineOption( - QStringLiteral("anti-cheat"), + QStringList{QStringLiteral("anti-cheat")}, QStringLiteral("Enable anticheat mode."))); parser.addOption(QCommandLineOption( - QStringLiteral("menu-lockdown"), + QStringList{QStringLiteral("menu-lockdown")}, QStringLiteral("Enable the protected start-menu lockdown mode."))); +#if defined(QT_DEBUG) || defined(SEB_DEV_BYPASS_OPTION) + parser.addOption(QCommandLineOption( + QStringList{QStringLiteral("dev-bypass")}, + QStringLiteral("Skip strict lockdowns for development purposes."))); +#endif parser.process(app); seb::SebSettings settings = seb::defaultSettings(); QTextStream err(stderr); +#if !SEB_HAS_QTWEBENGINE + err << "warning: This build was compiled without QtWebEngine support. " + "Safe Exam Browser will start in compatibility mode and cannot render exam pages." + << Qt::endl; +#endif + const QString resource = parser.isSet("config") ? parser.value("config") : (parser.positionalArguments().isEmpty() ? QString() : parser.positionalArguments().constFirst()); @@ -384,8 +403,12 @@ int main(int argc, char *argv[]) const bool launchedWithoutExam = resource.isEmpty(); const bool menuLockdown = parser.isSet("menu-lockdown"); const bool examAntiCheat = parser.isSet("anti-cheat"); - - if (!parser.isSet("anti-cheat") && !menuLockdown) { + bool devBypass = settings.devBypass || parser.isSet("dev-bypass"); +#ifdef SEB_DEV_BYPASS_DEFAULT + devBypass = true; +#endif + + if (!devBypass && !parser.isSet("anti-cheat") && !menuLockdown) { if (launchedWithoutExam) { const auto answer = QMessageBox::question( nullptr, @@ -475,18 +498,21 @@ int main(int argc, char *argv[]) } } - if (menuLockdown && launchedWithoutExam) { + if (menuLockdown && launchedWithoutExam && !devBypass) { applyProtectedSessionSettings(settings, false, false, true); - } else if (examAntiCheat) { + } else if (examAntiCheat && !devBypass) { applyProtectedSessionSettings(settings, true, true, false); } else if (!launchedWithoutExam && settings.browser.mainWindow.fullScreenMode && - settings.browser.mainWindow.alwaysOnTop) { - // Re-assert secure settings after command-line parsing so weakening flags - // like --windowed/--allow-devtools cannot downgrade a protected exam launch. + settings.browser.mainWindow.alwaysOnTop && + !devBypass) { applyProtectedSessionSettings(settings, true, true, false); } + if (devBypass) { + seb::applyDevBypassOverrides(settings); + } + AppController controller; QString launchError; if (!controller.launchResolved(settings, warnings, &launchError)) { @@ -494,5 +520,25 @@ int main(int argc, char *argv[]) return 1; } + seb::security::SecurityService security; + if (!devBypass) { + if (security.isVirtualMachine()) { + err << "Error: Running in a virtual machine is not allowed." << Qt::endl; + return 1; + } + if (security.isDebuggerAttached()) { + err << "Error: A debugger is attached." << Qt::endl; + return 1; + } + + QObject::connect(&security, &seb::security::SecurityService::secureViolationDetected, [&app](const QString &reason) { + qCritical() << "Security Violation:" << reason; + app.quit(); + }); + security.startMonitoring(); + } else { + qDebug() << "Developer bypass active; security monitoring disabled."; + } + return app.exec(); } diff --git a/src/seb_session.cpp b/src/seb_session.cpp index 1a41ce8..7d7b94b 100644 --- a/src/seb_session.cpp +++ b/src/seb_session.cpp @@ -1,5 +1,6 @@ #include "seb_session.h" - +#include +#include "browser/engines/engine_factory.h" #include "browser/request_interceptor.h" #include "applications/application_manager.h" #include "browser_window.h" @@ -14,20 +15,22 @@ #include #include #include -#include #include +#include +#include +#include +#include +#include +#include +#include #include -#include #include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include + +#include "browser/contracts/i_engine_provider.h" +#include "browser/contracts/i_webprofile.h" namespace { @@ -85,7 +88,23 @@ SebSession::SebSession(const seb::SebSettings &settings, ResourceOpener opener, settings_.browser.deleteCookiesOnShutdown || settings_.browser.deleteCookiesOnStartup; - profile_.reset(new QWebEngineProfile(this)); + engineProvider_ = seb::browser::createEngineProvider(); + if (!engineProvider_) { + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Critical); + msgBox.setWindowTitle(tr("Unsupported Device")); + msgBox.setText(tr("Safe Exam Browser is not supported on your device.")); + msgBox.setInformativeText(tr("If you want support please open a GitHub issue with details about your system configuration.")); + QPushButton *issueButton = msgBox.addButton(tr("Open GitHub Issue"), QMessageBox::ActionRole); + msgBox.addButton(QMessageBox::Close); + msgBox.exec(); + + if (msgBox.clickedButton() == issueButton) { + QDesktopServices::openUrl(QUrl(QStringLiteral("https://github.com/Jvr2022/seb-linux/issues"))); + } + std::exit(1); + } + profile_ = engineProvider_->createProfile(this); if (useTemporaryProfile) { profileDirectory_ = std::make_unique( @@ -106,22 +125,20 @@ SebSession::SebSession(const seb::SebSettings &settings, ResourceOpener opener, profile_->setDownloadPath(defaultDownloadDirectory()); } - profile_->settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); - profile_->settings()->setAttribute(QWebEngineSettings::PdfViewerEnabled, settings_.browser.allowPdfReader); - profile_->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, false); - profile_->settings()->setAttribute(QWebEngineSettings::HyperlinkAuditingEnabled, false); - profile_->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true); + profile_->setPdfViewerEnabled(settings_.browser.allowPdfReader); profile_->setSpellCheckEnabled(settings_.browser.allowSpellChecking); profile_->setSpellCheckLanguages(QStringList{QLocale::system().bcp47Name()}); profile_->setHttpUserAgent(buildUserAgent()); + profile_->setDevBypass(settings_.devBypass); - interceptor_.reset(new seb::browser::RequestInterceptor(settings_, this)); + interceptor_.reset(new seb::browser::RequestInterceptor(settings_)); profile_->setUrlRequestInterceptor(interceptor_.data()); - connect(profile_.data(), &QWebEngineProfile::downloadRequested, this, &SebSession::handleDownloadRequested); + connect(profile_.get(), &seb::browser::contracts::IWebProfile::downloadRequested, + this, &SebSession::handleDownloadRequested); if (settings_.browser.deleteCookiesOnStartup) { - profile_->cookieStore()->deleteAllCookies(); + profile_->deleteAllCookies(); } applicationManager_ = std::make_unique(settings_.applications, this); @@ -269,9 +286,14 @@ const seb::SebSettings &SebSession::settings() const return settings_; } -QWebEngineProfile *SebSession::profile() const +seb::browser::contracts::IWebProfile *SebSession::profile() const { - return profile_.data(); + return profile_.get(); +} + +seb::browser::contracts::IEngineProvider *SebSession::engineProvider() const +{ + return engineProvider_.get(); } QUrl SebSession::homeUrl() const @@ -364,30 +386,25 @@ void SebSession::activateWindow(BrowserWindow *window) window->activateWindow(); } -void SebSession::handleDownloadRequested(QWebEngineDownloadRequest *download) +void SebSession::handleDownloadRequested(const QUrl &url, const QString &suggestedFilename, bool &accepted, QString &downloadDirectory) { - if (!download) { - return; - } - - const QString fileName = download->downloadFileName().isEmpty() + const QString fileName = suggestedFilename.isEmpty() ? QStringLiteral("download") - : download->downloadFileName(); + : suggestedFilename; const bool sebConfig = fileName.endsWith(QStringLiteral(".seb"), Qt::CaseInsensitive); if (!settings_.browser.allowDownloads && !(sebConfig && settings_.browser.allowConfigurationDownloads)) { - download->cancel(); + accepted = false; return; } if (sebConfig && !settings_.browser.allowConfigurationDownloads) { - download->cancel(); + accepted = false; return; } if (sebConfig) { - const QUrl url = download->url(); - download->cancel(); + accepted = false; openSebResource(url, QApplication::activeWindow()); return; } @@ -400,7 +417,7 @@ void SebSession::handleDownloadRequested(QWebEngineDownloadRequest *download) destination); if (selected.isEmpty()) { - download->cancel(); + accepted = false; return; } @@ -408,9 +425,8 @@ void SebSession::handleDownloadRequested(QWebEngineDownloadRequest *download) } const QFileInfo info(destination); - download->setDownloadDirectory(info.dir().path()); - download->setDownloadFileName(info.fileName()); - download->accept(); + downloadDirectory = info.dir().path(); + accepted = true; } QString SebSession::buildUserAgent() const @@ -420,11 +436,7 @@ QString SebSession::buildUserAgent() const if (settings_.browser.useCustomUserAgent && !settings_.browser.customUserAgent.isEmpty()) { agent = settings_.browser.customUserAgent.trimmed(); } else { - QString defaultAgent = profile_->httpUserAgent(); - QRegularExpression regex(QStringLiteral("Chrome/([0-9.]+)")); - QRegularExpressionMatch match = regex.match(defaultAgent); - QString chromeVersion = match.hasMatch() ? match.captured(1) : QStringLiteral("110.0.0.0"); - + const QString chromeVersion = QStringLiteral("110.0.0.0"); agent = QStringLiteral("Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/") + chromeVersion; } diff --git a/src/seb_session.h b/src/seb_session.h index 993614c..b9ef340 100644 --- a/src/seb_session.h +++ b/src/seb_session.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include namespace seb::browser { class RequestInterceptor; @@ -20,14 +22,16 @@ class ExternalApplication; QT_BEGIN_NAMESPACE class QAuthenticator; class QTemporaryDir; -class QUrl; class QWidget; -class QWebEngineDownloadRequest; -class QWebEngineProfile; QT_END_NAMESPACE class BrowserWindow; +namespace seb::browser::contracts { +class IWebProfile; +class IEngineProvider; +} + class SebSession : public QObject { Q_OBJECT @@ -47,7 +51,8 @@ class SebSession : public QObject bool promptForHomeNavigation(QWidget *parent) const; bool requestApplicationQuit(QWidget *parent, const QString &reason) const; const seb::SebSettings &settings() const; - QWebEngineProfile *profile() const; + seb::browser::contracts::IWebProfile *profile() const; + seb::browser::contracts::IEngineProvider *engineProvider() const; QUrl homeUrl() const; QUrl initialUrl() const; bool openSebResource(const QUrl &url, QWidget *parent) const; @@ -65,15 +70,16 @@ public slots: void activateWindow(BrowserWindow *window); private: - void handleDownloadRequested(QWebEngineDownloadRequest *download); + void handleDownloadRequested(const QUrl &url, const QString &suggestedFilename, bool &accepted, QString &downloadDirectory); QString buildUserAgent() const; QString defaultDownloadDirectory() const; QString normalizeUrl(const QUrl &url) const; bool promptForPassword(QWidget *parent, const QString &title, const QString &message) const; seb::SebSettings settings_; - QScopedPointer profile_; QScopedPointer interceptor_; + std::unique_ptr engineProvider_; + std::unique_ptr profile_; std::unique_ptr profileDirectory_; std::unique_ptr downloadDirectory_; std::unique_ptr applicationManager_; diff --git a/src/seb_settings.cpp b/src/seb_settings.cpp index cf62ea4..dd790b5 100644 --- a/src/seb_settings.cpp +++ b/src/seb_settings.cpp @@ -147,4 +147,42 @@ ResourceLoadResult loadSettingsFromResource( return settingsinternal::loadSettingsFromNetworkResource(url, passwordProvider); } +void applyDevBypassOverrides(SebSettings &settings) +{ + settings.devBypass = true; + + auto overrideWindow = [](WindowSettings &ws) { + ws.fullScreenMode = false; + ws.alwaysOnTop = false; + ws.allowAddressBar = true; + ws.allowBackwardNavigation = true; + ws.allowForwardNavigation = true; + ws.allowDeveloperConsole = true; + ws.allowMinimize = true; + ws.allowReloading = true; + ws.showHomeButton = true; + ws.showReloadButton = true; + ws.showToolbar = true; + ws.frameless = false; + }; + + overrideWindow(settings.browser.mainWindow); + overrideWindow(settings.browser.additionalWindow); + + settings.browser.allowDownloads = true; + settings.browser.allowUploads = true; + settings.browser.allowPageZoom = true; + settings.browser.allowFind = true; + settings.browser.allowPrint = true; + settings.browser.allowSpellChecking = true; + settings.browser.confirmQuitUrl = false; + settings.browser.homeNavigationRequiresPassword = false; + + settings.security.allowTermination = true; + settings.security.quitPasswordHash.clear(); + + settings.taskbar.enableTaskbar = true; + settings.taskbar.showNetwork = true; +} + } // namespace seb diff --git a/src/seb_settings.h b/src/seb_settings.h index 9cfdd6f..761488f 100644 --- a/src/seb_settings.h +++ b/src/seb_settings.h @@ -209,6 +209,7 @@ struct SebSettings SecuritySettings security; TaskbarSettings taskbar; QString sourceFile; + bool devBypass = false; }; struct LoadResult @@ -239,4 +240,6 @@ ResourceLoadResult loadSettingsFromResource( const QString &resource, const std::function &passwordProvider = {}); +void applyDevBypassOverrides(SebSettings &settings); + } // namespace seb diff --git a/src/security/security_service.cpp b/src/security/security_service.cpp new file mode 100644 index 0000000..52db5f3 --- /dev/null +++ b/src/security/security_service.cpp @@ -0,0 +1,154 @@ +#include "security_service.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace seb::security { + +SecurityService::SecurityService(QObject *parent) + : QObject(parent) +{ +} + +bool SecurityService::isVirtualMachine() const +{ + // Check for common VM artifacts in /proc/cpuinfo and dmesg-like files + QFile cpuinfo("/proc/cpuinfo"); + if (cpuinfo.open(QIODevice::ReadOnly | QIODevice::Text)) { + QString content = cpuinfo.readAll(); + if (content.contains("hypervisor", Qt::CaseInsensitive) || + content.contains("VMware", Qt::CaseInsensitive) || + content.contains("QEMU", Qt::CaseInsensitive) || + content.contains("VirtualBox", Qt::CaseInsensitive)) { + return true; + } + } + + // Check system vendor + QFile vendor("/sys/class/dmi/id/sys_vendor"); + if (vendor.open(QIODevice::ReadOnly | QIODevice::Text)) { + QString content = vendor.readAll().trimmed(); + if (content.contains("VMware", Qt::CaseInsensitive) || + content.contains("QEMU", Qt::CaseInsensitive) || + content.contains("innotek", Qt::CaseInsensitive) || // VirtualBox + content.contains("Microsoft Corporation", Qt::CaseInsensitive)) { // Hyper-V + return true; + } + } + + return false; +} + +bool SecurityService::isDebuggerAttached() const +{ + // Check TracerPid in /proc/self/status + QFile status("/proc/self/status"); + if (status.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&status); + while (!in.atEnd()) { + QString line = in.readLine(); + if (line.startsWith("TracerPid:")) { + int tracerPid = line.section(':', 1).trimmed().toInt(); + if (tracerPid != 0) { + return true; + } + break; + } + } + } + + return false; +} + +QStringList SecurityService::detectProhibitedProcesses() const +{ + static const QStringList prohibited = { + QStringLiteral("discord"), QStringLiteral("slack"), QStringLiteral("teamviewer"), + QStringLiteral("anydesk"), QStringLiteral("obs"), QStringLiteral("simplescreenrecorder"), + QStringLiteral("wireshark"), QStringLiteral("tcpdump"), QStringLiteral("gdb"), + QStringLiteral("strace") + }; + + QStringList detected; + QDir proc(QStringLiteral("/proc")); + const QStringList pids = proc.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + + for (const QString &pid : pids) { + bool ok; + pid.toInt(&ok); + if (!ok) continue; + + QFile cmdline(QStringLiteral("/proc/%1/cmdline").arg(pid)); + if (cmdline.open(QIODevice::ReadOnly)) { + const QByteArray data = cmdline.readAll(); + if (data.isEmpty()) continue; + + const QString name = QString::fromLocal8Bit(data.constData()).section(QLatin1Char('\0'), 0, 0); + const QString baseName = QFileInfo(name).fileName().toLower(); + + for (const QString &p : prohibited) { + if (baseName.contains(p)) { + detected << name; + break; // Move to next process immediately + } + } + } + } + + return detected; +} + +void SecurityService::startMonitoring() +{ + if (timerId_ == -1) { + timerId_ = startTimer(5000); // Check every 5 seconds + } +} + +void SecurityService::stopMonitoring() +{ + if (timerId_ != -1) { + killTimer(timerId_); + timerId_ = -1; + } +} + +bool SecurityService::isMultipleDisplaysActive() const +{ + return QGuiApplication::screens().size() > 1; +} + +void SecurityService::performCheck() +{ + if (isDebuggerAttached()) { + emit secureViolationDetected("Debugger attached"); + } + + if (isMultipleDisplaysActive()) { + emit secureViolationDetected("Multiple displays detected"); + } + + QStringList detected = detectProhibitedProcesses(); + if (!detected.isEmpty()) { + emit secureViolationDetected(QString("Prohibited processes detected: %1").arg(detected.join(", "))); + } +} + +void SecurityService::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == timerId_) { + performCheck(); + } +} + +} // namespace seb::security diff --git a/src/security/security_service.h b/src/security/security_service.h new file mode 100644 index 0000000..6eba589 --- /dev/null +++ b/src/security/security_service.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include + +namespace seb::security { + +class SecurityService : public QObject +{ + Q_OBJECT + +public: + explicit SecurityService(QObject *parent = nullptr); + + bool isVirtualMachine() const; + bool isDebuggerAttached() const; + bool isMultipleDisplaysActive() const; + QStringList detectProhibitedProcesses() const; + + void startMonitoring(); + void stopMonitoring(); + +protected: + void timerEvent(QTimerEvent *event) override; + +signals: + void secureViolationDetected(const QString &reason); + +private: + void performCheck(); + int timerId_ = -1; +}; + +} // namespace seb::security diff --git a/src/settings/password_container.cpp b/src/settings/password_container.cpp index a3dbed7..bc4af8c 100644 --- a/src/settings/password_container.cpp +++ b/src/settings/password_container.cpp @@ -1,63 +1,68 @@ #include "password_container.h" +#include "../configuration/cryptography/certificate_store.h" +#include "../configuration/cryptography/password_encryption.h" +#include "../configuration/cryptography/public_key_encryption.h" +#include "../configuration/cryptography/public_key_symmetric_encryption.h" #include #include +#include #include - +#include +#include #include - #include - #include +using namespace seb::configuration::cryptography; + namespace seb::settingsinternal { namespace { -QString sha256Hex(const QByteArray &data) -{ - return QString::fromLatin1(QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex()); +QString sha256Hex(const QByteArray &data) { + return QString::fromLatin1( + QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex()); } -QString hashPassword(const QString &password) -{ - return sha256Hex(password.toUtf8()); +QString hashPassword(const QString &password) { + return sha256Hex(password.toUtf8()); } -QByteArray inflateGzip(const QByteArray &data, QString *error) -{ - z_stream stream {}; - stream.next_in = reinterpret_cast(const_cast(data.data())); - stream.avail_in = static_cast(data.size()); +QByteArray inflateGzip(const QByteArray &data, QString *error) { + z_stream stream{}; + stream.next_in = reinterpret_cast(const_cast(data.data())); + stream.avail_in = static_cast(data.size()); - if (inflateInit2(&stream, 16 + MAX_WBITS) != Z_OK) { - if (error) { - *error = QStringLiteral("Failed to initialize gzip decompression."); - } - return {}; + if (inflateInit2(&stream, 16 + MAX_WBITS) != Z_OK) { + if (error) { + *error = QStringLiteral("Failed to initialize gzip decompression."); } - - QByteArray output; - char buffer[8192]; - int status = Z_OK; - - while (status == Z_OK) { - stream.next_out = reinterpret_cast(buffer); - stream.avail_out = sizeof(buffer); - status = inflate(&stream, Z_NO_FLUSH); - - if (status != Z_OK && status != Z_STREAM_END) { - if (error) { - *error = QStringLiteral("Failed to decompress gzip-compressed SEB data."); - } - inflateEnd(&stream); - return {}; - } - - output.append(buffer, static_cast(sizeof(buffer) - stream.avail_out)); + return {}; + } + + QByteArray output; + char buffer[8192]; + int status = Z_OK; + + while (status == Z_OK) { + stream.next_out = reinterpret_cast(buffer); + stream.avail_out = sizeof(buffer); + status = inflate(&stream, Z_NO_FLUSH); + + if (status != Z_OK && status != Z_STREAM_END) { + if (error) { + *error = + QStringLiteral("Failed to decompress gzip-compressed SEB data."); + } + inflateEnd(&stream); + return {}; } - inflateEnd(&stream); - return output; + output.append(buffer, static_cast(sizeof(buffer) - stream.avail_out)); + } + + inflateEnd(&stream); + return output; } constexpr int kSebPrefixLength = 4; @@ -79,236 +84,263 @@ const QByteArray kPrefixPlain = "plnd"; const QByteArray kPrefixMultipart = "mphd"; const QByteArray kPrefixCustomHeader = "cmhd"; -QByteArray readPrefix(const QByteArray &data) -{ - return data.left(kSebPrefixLength); +QByteArray readPrefix(const QByteArray &data) { + return data.left(kSebPrefixLength); } -QByteArray deriveKey(const QString &password, const QByteArray &salt) -{ - const QByteArray passwordBytes = password.toUtf8(); - QByteArray key(kSebRncryptorKeyLength, Qt::Uninitialized); - PKCS5_PBKDF2_HMAC_SHA1( - passwordBytes.constData(), - passwordBytes.size(), - reinterpret_cast(salt.constData()), - salt.size(), - kSebRncryptorIterations, - kSebRncryptorKeyLength, - reinterpret_cast(key.data())); - return key; +QByteArray deriveKey(const QString &password, const QByteArray &salt) { + const QByteArray passwordBytes = password.toUtf8(); + QByteArray key(kSebRncryptorKeyLength, Qt::Uninitialized); + PKCS5_PBKDF2_HMAC_SHA1( + passwordBytes.constData(), passwordBytes.size(), + reinterpret_cast(salt.constData()), salt.size(), + kSebRncryptorIterations, kSebRncryptorKeyLength, + reinterpret_cast(key.data())); + return key; } -bool decryptPasswordBlock(const QByteArray &data, const QString &password, QByteArray *decrypted, QString *error) -{ - if (data.size() < kSebRncryptorHeaderLength + 2 * kSebRncryptorSaltLength + kSebRncryptorIvLength + 32) { - if (error) { - *error = QStringLiteral("The encrypted SEB payload is truncated."); - } - return false; +bool decryptPasswordBlock(const QByteArray &data, const QString &password, + QByteArray *decrypted, QString *error) { + if (data.size() < kSebRncryptorHeaderLength + 2 * kSebRncryptorSaltLength + + kSebRncryptorIvLength + 32) { + if (error) { + *error = QStringLiteral("The encrypted SEB payload is truncated."); } - - const unsigned char version = static_cast(data.at(0)); - const unsigned char options = static_cast(data.at(1)); - if (version != kSebRncryptorVersion || options != kSebRncryptorOptions) { - if (error) { - *error = QStringLiteral("Unsupported encrypted SEB format version."); - } - return false; + return false; + } + + const unsigned char version = static_cast(data.at(0)); + const unsigned char options = static_cast(data.at(1)); + if (version != kSebRncryptorVersion || options != kSebRncryptorOptions) { + if (error) { + *error = QStringLiteral("Unsupported encrypted SEB format version."); } - - int offset = kSebRncryptorHeaderLength; - const QByteArray encryptionSalt = data.mid(offset, kSebRncryptorSaltLength); - offset += kSebRncryptorSaltLength; - const QByteArray authenticationSalt = data.mid(offset, kSebRncryptorSaltLength); - offset += kSebRncryptorSaltLength; - const QByteArray iv = data.mid(offset, kSebRncryptorIvLength); - offset += kSebRncryptorIvLength; - - const int hmacLength = 32; - const QByteArray encryptedPayload = data.mid(offset, data.size() - offset - hmacLength); - const QByteArray originalHmac = data.right(hmacLength); - - const QByteArray authenticationKey = deriveKey(password, authenticationSalt); - const QByteArray encryptionKey = deriveKey(password, encryptionSalt); - const QByteArray computedHmac = QMessageAuthenticationCode::hash( - data.left(data.size() - hmacLength), - authenticationKey, - QCryptographicHash::Sha256); - - if (computedHmac != originalHmac) { - if (error) { - *error = QStringLiteral("Invalid password or corrupted encrypted SEB data."); - } - return false; + return false; + } + + int offset = kSebRncryptorHeaderLength; + const QByteArray encryptionSalt = data.mid(offset, kSebRncryptorSaltLength); + offset += kSebRncryptorSaltLength; + const QByteArray authenticationSalt = + data.mid(offset, kSebRncryptorSaltLength); + offset += kSebRncryptorSaltLength; + const QByteArray iv = data.mid(offset, kSebRncryptorIvLength); + offset += kSebRncryptorIvLength; + + const int hmacLength = 32; + const QByteArray encryptedPayload = + data.mid(offset, data.size() - offset - hmacLength); + const QByteArray originalHmac = data.right(hmacLength); + + const QByteArray authenticationKey = deriveKey(password, authenticationSalt); + const QByteArray encryptionKey = deriveKey(password, encryptionSalt); + const QByteArray computedHmac = QMessageAuthenticationCode::hash( + data.left(data.size() - hmacLength), authenticationKey, + QCryptographicHash::Sha256); + + if (computedHmac != originalHmac) { + if (error) { + *error = + QStringLiteral("Invalid password or corrupted encrypted SEB data."); } + return false; + } - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - if (!ctx) { - if (error) { - *error = QStringLiteral("Failed to decrypt the SEB payload."); - } - return false; + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + if (!ctx) { + if (error) { + *error = QStringLiteral("Failed to decrypt the SEB payload."); } - - QByteArray clear(encryptedPayload.size() + kSebRncryptorIvLength, Qt::Uninitialized); - int firstChunkLength = 0; - int finalChunkLength = 0; - const bool ok = - EVP_DecryptInit_ex( - ctx, - EVP_aes_256_cbc(), - nullptr, - reinterpret_cast(encryptionKey.constData()), - reinterpret_cast(iv.constData())) == 1 && - EVP_DecryptUpdate( - ctx, - reinterpret_cast(clear.data()), - &firstChunkLength, - reinterpret_cast(encryptedPayload.constData()), - encryptedPayload.size()) == 1 && - EVP_DecryptFinal_ex( - ctx, - reinterpret_cast(clear.data()) + firstChunkLength, - &finalChunkLength) == 1; - EVP_CIPHER_CTX_free(ctx); - - if (!ok) { - if (error) { - *error = QStringLiteral("Failed to decrypt the SEB payload."); - } - return false; - } - - clear.truncate(firstChunkLength + finalChunkLength); - if (decrypted) { - *decrypted = clear; + return false; + } + + QByteArray clear(encryptedPayload.size() + kSebRncryptorIvLength, + Qt::Uninitialized); + int firstChunkLength = 0; + int finalChunkLength = 0; + const bool ok = + EVP_DecryptInit_ex( + ctx, EVP_aes_256_cbc(), nullptr, + reinterpret_cast(encryptionKey.constData()), + reinterpret_cast(iv.constData())) == 1 && + EVP_DecryptUpdate( + ctx, reinterpret_cast(clear.data()), + &firstChunkLength, + reinterpret_cast(encryptedPayload.constData()), + encryptedPayload.size()) == 1 && + EVP_DecryptFinal_ex(ctx, + reinterpret_cast(clear.data()) + + firstChunkLength, + &finalChunkLength) == 1; + EVP_CIPHER_CTX_free(ctx); + + if (!ok) { + if (error) { + *error = QStringLiteral("Failed to decrypt the SEB payload."); } - return true; + return false; + } + + clear.truncate(firstChunkLength + finalChunkLength); + if (decrypted) { + *decrypted = clear; + } + return true; } -} // namespace +} // namespace -bool looksLikeHtml(const QByteArray &raw) -{ - const QByteArray trimmed = raw.trimmed().left(256).toLower(); - return trimmed.startsWith(" &passwordProvider) -{ - while (raw.size() >= kSebPrefixLength) { - const QByteArray prefix = readPrefix(raw); - - if (prefix == kPrefixMultipart) { - if (raw.size() < kSebPrefixLength + kSebMultipartLength) { - if (error) { - *error = QStringLiteral("Invalid multipart SEB header."); - } - return {}; - } +QByteArray +unwrapSebContainer(QByteArray raw, QString *error, QStringList *warnings, + const std::function &passwordProvider) { + while (raw.size() >= kSebPrefixLength) { + const QByteArray prefix = readPrefix(raw); - qint64 firstPartLength = 0; - memcpy(&firstPartLength, raw.constData() + kSebPrefixLength, sizeof(firstPartLength)); - raw = raw.mid(kSebPrefixLength + kSebMultipartLength, static_cast(firstPartLength)); - if (warnings) { - warnings->push_back(QStringLiteral("Ignored additional multipart SEB resources.")); - } - continue; + if (prefix == kPrefixMultipart) { + if (raw.size() < kSebPrefixLength + kSebMultipartLength) { + if (error) { + *error = QStringLiteral("Invalid multipart SEB header."); } + return {}; + } + + qint64 firstPartLength = 0; + memcpy(&firstPartLength, raw.constData() + kSebPrefixLength, + sizeof(firstPartLength)); + raw = raw.mid(kSebPrefixLength + kSebMultipartLength, + static_cast(firstPartLength)); + if (warnings) { + warnings->push_back( + QStringLiteral("Ignored additional multipart SEB resources.")); + } + continue; + } - if (prefix == kPrefixCustomHeader) { - if (raw.size() < kSebPrefixLength + kSebCustomHeaderLength) { - if (error) { - *error = QStringLiteral("Invalid custom-header SEB payload."); - } - return {}; - } + if (prefix == kPrefixCustomHeader) { + if (raw.size() < kSebPrefixLength + kSebCustomHeaderLength) { + if (error) { + *error = QStringLiteral("Invalid custom-header SEB payload."); + } + return {}; + } + + qint32 headerLength = 0; + memcpy(&headerLength, raw.constData() + kSebPrefixLength, + sizeof(headerLength)); + raw = raw.mid(kSebPrefixLength + kSebCustomHeaderLength + headerLength); + if (warnings) { + warnings->push_back( + QStringLiteral("Ignored unsupported custom SEB header data.")); + } + continue; + } - qint32 headerLength = 0; - memcpy(&headerLength, raw.constData() + kSebPrefixLength, sizeof(headerLength)); - raw = raw.mid(kSebPrefixLength + kSebCustomHeaderLength + headerLength); - if (warnings) { - warnings->push_back(QStringLiteral("Ignored unsupported custom SEB header data.")); - } - continue; + if (prefix == kPrefixPlain) { + return raw.mid(kSebPrefixLength); + } + + if (prefix == kPrefixPassword || prefix == kPrefixPasswordConfigureClient) { + const bool hashPasswordBeforeUse = + prefix == kPrefixPasswordConfigureClient; + const QByteArray encrypted = raw.mid(kSebPrefixLength); + + for (int attempt = 0; attempt < 5; ++attempt) { + if (!passwordProvider) { + if (error) { + *error = QStringLiteral( + "This SEB file is encrypted and requires a password."); + } + return {}; } - if (prefix == kPrefixPlain) { - return raw.mid(kSebPrefixLength); + const QString supplied = passwordProvider(hashPasswordBeforeUse); + if (supplied.isNull() || supplied.isEmpty()) { + if (error) { + *error = QStringLiteral("Password entry was cancelled."); + } + return {}; } - if (prefix == kPrefixPassword || prefix == kPrefixPasswordConfigureClient) { - const bool hashPasswordBeforeUse = prefix == kPrefixPasswordConfigureClient; - const QByteArray encrypted = raw.mid(kSebPrefixLength); - - for (int attempt = 0; attempt < 5; ++attempt) { - if (!passwordProvider) { - if (error) { - *error = QStringLiteral("This SEB file is encrypted and requires a password."); - } - return {}; - } - - const QString supplied = passwordProvider(hashPasswordBeforeUse); - if (supplied.isNull() || supplied.isEmpty()) { - if (error) { - *error = QStringLiteral("Password entry was cancelled."); - } - return {}; - } - - const QString password = hashPasswordBeforeUse ? hashPassword(supplied).toUpper() : supplied; - QByteArray decrypted; - QString decryptError; - if (decryptPasswordBlock(encrypted, password, &decrypted, &decryptError)) { - raw = decrypted; - if (raw.size() >= 2 && - static_cast(raw.at(0)) == 0x1f && - static_cast(raw.at(1)) == 0x8b) { - raw = inflateGzip(raw, &decryptError); - if (raw.isEmpty()) { - if (error) { - *error = decryptError; - } - return {}; - } - } - break; - } - - if (attempt == 4) { - if (error) { - *error = decryptError; - } - return {}; - } + const QString password = + hashPasswordBeforeUse ? hashPassword(supplied).toUpper() : supplied; + QByteArray decrypted; + QString decryptError; + if (decryptPasswordBlock(encrypted, password, &decrypted, + &decryptError)) { + raw = decrypted; + if (raw.size() >= 2 && + static_cast(raw.at(0)) == 0x1f && + static_cast(raw.at(1)) == 0x8b) { + raw = inflateGzip(raw, &decryptError); + if (raw.isEmpty()) { + if (error) { + *error = decryptError; + } + return {}; } - - continue; + } + break; } - if (prefix == kPrefixPublicKey || prefix == kPrefixPublicKeySymmetric) { - if (error) { - *error = QStringLiteral("Certificate-encrypted SEB files are not implemented yet on Linux."); - } - return {}; + if (attempt == 4) { + if (error) { + *error = decryptError; + } + return {}; } + } + + continue; + } - break; + if (prefix == kPrefixPublicKey || prefix == kPrefixPublicKeySymmetric) { + CertificateStore store; + + PasswordEncryption aes; + PublicKeyEncryption rsa(store); + PublicKeySymmetricEncryption hybrid(store, rsa, aes); + + using LoadStatus = seb::configuration::contracts::LoadStatus; + QSslCertificate cert; + QByteArray decrypted; + LoadStatus status; + + if (prefix == kPrefixPublicKey) { + status = rsa.decrypt(raw.mid(kSebPrefixLength), decrypted, cert); + } else { + status = hybrid.decrypt(raw.mid(kSebPrefixLength), decrypted, cert); + } + + if (status == LoadStatus::Success) { + raw = decrypted; + continue; + } else if (status == LoadStatus::PasswordNeeded) { + if (error) + *error = QStringLiteral( + "A certificate with private key is required to open this file."); + return {}; + } else { + if (error) + *error = QStringLiteral( + "Failed to decrypt certificate-encrypted SEB file."); + return {}; + } } - return raw; + break; + } + + return raw; } -} // namespace seb::settingsinternal +} // namespace seb::settingsinternal diff --git a/src/settings/resource_loader.cpp b/src/settings/resource_loader.cpp index b9bde5e..2fd8bd4 100644 --- a/src/settings/resource_loader.cpp +++ b/src/settings/resource_loader.cpp @@ -45,13 +45,15 @@ ResourceLoadResult loadSettingsFromNetworkResource( const QByteArray contentType = reply->header(QNetworkRequest::ContentTypeHeader).toByteArray(); const QByteArray body = reply->readAll(); + const bool isSebExtension = url.path().endsWith(QStringLiteral(".seb"), Qt::CaseInsensitive); + if (reply->error() != QNetworkReply::NoError && httpStatus == 0) { result.error = QStringLiteral("Failed to download '%1': %2").arg(url.toString(), reply->errorString()); reply->deleteLater(); return result; } - if (httpStatus == 401 || contentType.startsWith("text/html") || looksLikeHtml(body)) { + if (!isSebExtension && (httpStatus == 401 || contentType.startsWith("text/html") || looksLikeHtml(body))) { result.settings = browserFallbackSettings(url); result.browserUrl = url; result.ok = true; diff --git a/src/userinterface/contracts/Properties/AssemblyInfo.h b/src/userinterface/contracts/Properties/AssemblyInfo.h deleted file mode 100644 index 68992d7..0000000 --- a/src/userinterface/contracts/Properties/AssemblyInfo.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -namespace seb::userinterface::contracts::assemblyinfo { - -inline constexpr auto kTitle = "SafeExamBrowser.UserInterface.Contracts"; -inline constexpr auto kDescription = "Safe Exam Browser"; -inline constexpr auto kCompany = "JVR2022"; -inline constexpr auto kProduct = "SafeExamBrowser.UserInterface.Contracts"; -inline constexpr auto kCopyright = "Copyright (C) 2026 JVR2022"; -inline constexpr auto kVersion = "1.0.0.0"; - -} // namespace seb::userinterface::contracts::assemblyinfo diff --git a/src/userinterface/contracts/browser/data/download_item_state.h b/src/userinterface/contracts/browser/data/download_item_state.h deleted file mode 100644 index 13374a6..0000000 --- a/src/userinterface/contracts/browser/data/download_item_state.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::browser::data { enum class DownloadItemState { InProgress, Completed, Cancelled, Interrupted }; } diff --git a/src/userinterface/contracts/browser/data/javascript_result.h b/src/userinterface/contracts/browser/data/javascript_result.h deleted file mode 100644 index 82480d3..0000000 --- a/src/userinterface/contracts/browser/data/javascript_result.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::browser::data { - -struct JavascriptResult -{ - bool success = false; - QString value; -}; - -} // namespace seb::userinterface::contracts::browser::data diff --git a/src/userinterface/contracts/browser/events/address_changed_event_handler.h b/src/userinterface/contracts/browser/events/address_changed_event_handler.h deleted file mode 100644 index 2844504..0000000 --- a/src/userinterface/contracts/browser/events/address_changed_event_handler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::userinterface::contracts::browser::events { -using AddressChangedEventHandler = std::function; -} diff --git a/src/userinterface/contracts/browser/events/find_requested_event_handler.h b/src/userinterface/contracts/browser/events/find_requested_event_handler.h deleted file mode 100644 index e30c519..0000000 --- a/src/userinterface/contracts/browser/events/find_requested_event_handler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::userinterface::contracts::browser::events { -using FindRequestedEventHandler = std::function; -} diff --git a/src/userinterface/contracts/browser/events/load_failed_event_handler.h b/src/userinterface/contracts/browser/events/load_failed_event_handler.h deleted file mode 100644 index 15aa9c6..0000000 --- a/src/userinterface/contracts/browser/events/load_failed_event_handler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::userinterface::contracts::browser::events { -using LoadFailedEventHandler = std::function; -} diff --git a/src/userinterface/contracts/browser/events/loading_state_changed_event_handler.h b/src/userinterface/contracts/browser/events/loading_state_changed_event_handler.h deleted file mode 100644 index a572989..0000000 --- a/src/userinterface/contracts/browser/events/loading_state_changed_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::browser::events { -using LoadingStateChangedEventHandler = std::function; -} diff --git a/src/userinterface/contracts/browser/events/title_changed_event_handler.h b/src/userinterface/contracts/browser/events/title_changed_event_handler.h deleted file mode 100644 index 0d88135..0000000 --- a/src/userinterface/contracts/browser/events/title_changed_event_handler.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include -#include - -namespace seb::userinterface::contracts::browser::events { -using TitleChangedEventHandler = std::function; -} diff --git a/src/userinterface/contracts/browser/i_browser_control.h b/src/userinterface/contracts/browser/i_browser_control.h deleted file mode 100644 index 9b5db88..0000000 --- a/src/userinterface/contracts/browser/i_browser_control.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "events/address_changed_event_handler.h" -#include "events/find_requested_event_handler.h" -#include "events/load_failed_event_handler.h" -#include "events/loading_state_changed_event_handler.h" -#include "events/title_changed_event_handler.h" - -#include -#include - -namespace seb::userinterface::contracts::browser { - -class IBrowserControl -{ -public: - virtual ~IBrowserControl() = default; - virtual QString address() const = 0; - virtual bool isLoading() const = 0; - virtual QString title() const = 0; - virtual void findText(const QString &text, bool forward = true, bool matchCase = false) = 0; - virtual void load(const QUrl &url) = 0; -}; - -} // namespace seb::userinterface::contracts::browser diff --git a/src/userinterface/contracts/browser/i_browser_window.h b/src/userinterface/contracts/browser/i_browser_window.h deleted file mode 100644 index 8a935ec..0000000 --- a/src/userinterface/contracts/browser/i_browser_window.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../windows/i_window.h" -#include "i_browser_control.h" - -namespace seb::userinterface::contracts::browser { - -class IBrowserWindow : public windows::IWindow -{ -public: - ~IBrowserWindow() override = default; - virtual IBrowserControl *browserControl() = 0; -}; - -} // namespace seb::userinterface::contracts::browser diff --git a/src/userinterface/contracts/events/action_requested_event_handler.h b/src/userinterface/contracts/events/action_requested_event_handler.h deleted file mode 100644 index e5c4d25..0000000 --- a/src/userinterface/contracts/events/action_requested_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::events { -using ActionRequestedEventHandler = std::function; -} diff --git a/src/userinterface/contracts/file_system_dialog/file_system_dialog_result.h b/src/userinterface/contracts/file_system_dialog/file_system_dialog_result.h deleted file mode 100644 index ae15a83..0000000 --- a/src/userinterface/contracts/file_system_dialog/file_system_dialog_result.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::file_system_dialog { enum class FileSystemDialogResult { Cancel, Accept }; } diff --git a/src/userinterface/contracts/file_system_dialog/file_system_element.h b/src/userinterface/contracts/file_system_dialog/file_system_element.h deleted file mode 100644 index 8d55377..0000000 --- a/src/userinterface/contracts/file_system_dialog/file_system_element.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::file_system_dialog { - -struct FileSystemElement -{ - QString name; - QString path; - bool directory = false; -}; - -} // namespace seb::userinterface::contracts::file_system_dialog diff --git a/src/userinterface/contracts/file_system_dialog/file_system_operation.h b/src/userinterface/contracts/file_system_dialog/file_system_operation.h deleted file mode 100644 index e6d5fbe..0000000 --- a/src/userinterface/contracts/file_system_dialog/file_system_operation.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::file_system_dialog { enum class FileSystemOperation { Open, Save, SelectFolder }; } diff --git a/src/userinterface/contracts/file_system_dialog/i_file_system_dialog.h b/src/userinterface/contracts/file_system_dialog/i_file_system_dialog.h deleted file mode 100644 index ddfd641..0000000 --- a/src/userinterface/contracts/file_system_dialog/i_file_system_dialog.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "file_system_dialog_result.h" -#include "file_system_operation.h" - -#include - -namespace seb::userinterface::contracts::file_system_dialog { - -class IFileSystemDialog -{ -public: - virtual ~IFileSystemDialog() = default; - virtual FileSystemDialogResult exec() = 0; - virtual QString selectedPath() const = 0; - virtual void setOperation(FileSystemOperation operation) = 0; -}; - -} // namespace seb::userinterface::contracts::file_system_dialog diff --git a/src/userinterface/contracts/i_progress_indicator.h b/src/userinterface/contracts/i_progress_indicator.h deleted file mode 100644 index 632c0ad..0000000 --- a/src/userinterface/contracts/i_progress_indicator.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts { class IProgressIndicator { public: virtual ~IProgressIndicator() = default; virtual void setBusy(bool busy) = 0; virtual void setProgress(int current, int maximum) = 0; }; } diff --git a/src/userinterface/contracts/i_user_interface_factory.h b/src/userinterface/contracts/i_user_interface_factory.h deleted file mode 100644 index 0022202..0000000 --- a/src/userinterface/contracts/i_user_interface_factory.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "browser/i_browser_window.h" -#include "message_box/i_message_box.h" -#include "shell/i_taskbar.h" -#include "windows/i_runtime_window.h" -#include "windows/i_splash_screen.h" - -namespace seb::userinterface::contracts { - -class IUserInterfaceFactory -{ -public: - virtual ~IUserInterfaceFactory() = default; - virtual message_box::IMessageBox *messageBox() = 0; - virtual shell::ITaskbar *taskbar() = 0; - virtual windows::IRuntimeWindow *runtimeWindow() = 0; - virtual windows::ISplashScreen *splashScreen() = 0; -}; - -} // namespace seb::userinterface::contracts diff --git a/src/userinterface/contracts/i_window_guard.h b/src/userinterface/contracts/i_window_guard.h deleted file mode 100644 index ccbcc09..0000000 --- a/src/userinterface/contracts/i_window_guard.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts { class IWindowGuard { public: virtual ~IWindowGuard() = default; virtual void show() = 0; virtual void hide() = 0; }; } diff --git a/src/userinterface/contracts/message_box/i_message_box.h b/src/userinterface/contracts/message_box/i_message_box.h deleted file mode 100644 index a85980e..0000000 --- a/src/userinterface/contracts/message_box/i_message_box.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "message_box_action.h" -#include "message_box_icon.h" -#include "message_box_result.h" - -#include - -namespace seb::userinterface::contracts::message_box { - -class IMessageBox -{ -public: - virtual ~IMessageBox() = default; - virtual MessageBoxResult show( - const QString &title, - const QString &text, - MessageBoxAction action = MessageBoxAction::Ok, - MessageBoxIcon icon = MessageBoxIcon::Information) = 0; -}; - -} // namespace seb::userinterface::contracts::message_box diff --git a/src/userinterface/contracts/message_box/message_box_action.h b/src/userinterface/contracts/message_box/message_box_action.h deleted file mode 100644 index 256065b..0000000 --- a/src/userinterface/contracts/message_box/message_box_action.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::message_box { enum class MessageBoxAction { Ok, YesNo, OkCancel }; } diff --git a/src/userinterface/contracts/message_box/message_box_icon.h b/src/userinterface/contracts/message_box/message_box_icon.h deleted file mode 100644 index 48c4eeb..0000000 --- a/src/userinterface/contracts/message_box/message_box_icon.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::message_box { enum class MessageBoxIcon { Information, Warning, Error, Question }; } diff --git a/src/userinterface/contracts/message_box/message_box_result.h b/src/userinterface/contracts/message_box/message_box_result.h deleted file mode 100644 index 63babaa..0000000 --- a/src/userinterface/contracts/message_box/message_box_result.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::message_box { enum class MessageBoxResult { None, Ok, Yes, No, Cancel }; } diff --git a/src/userinterface/contracts/proctoring/events/cancellation_requested_event_handler.h b/src/userinterface/contracts/proctoring/events/cancellation_requested_event_handler.h deleted file mode 100644 index d307ec1..0000000 --- a/src/userinterface/contracts/proctoring/events/cancellation_requested_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::proctoring::events { -using CancellationRequestedEventHandler = std::function; -} diff --git a/src/userinterface/contracts/proctoring/events/full_screen_changed_event_handler.h b/src/userinterface/contracts/proctoring/events/full_screen_changed_event_handler.h deleted file mode 100644 index 85ed1ed..0000000 --- a/src/userinterface/contracts/proctoring/events/full_screen_changed_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::proctoring::events { -using FullScreenChangedEventHandler = std::function; -} diff --git a/src/userinterface/contracts/proctoring/i_proctoring_control.h b/src/userinterface/contracts/proctoring/i_proctoring_control.h deleted file mode 100644 index 388551b..0000000 --- a/src/userinterface/contracts/proctoring/i_proctoring_control.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::proctoring { class IProctoringControl { public: virtual ~IProctoringControl() = default; virtual void setFullScreen(bool fullScreen) = 0; }; } diff --git a/src/userinterface/contracts/proctoring/i_proctoring_finalization_dialog.h b/src/userinterface/contracts/proctoring/i_proctoring_finalization_dialog.h deleted file mode 100644 index 73093ab..0000000 --- a/src/userinterface/contracts/proctoring/i_proctoring_finalization_dialog.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::proctoring { class IProctoringFinalizationDialog { public: virtual ~IProctoringFinalizationDialog() = default; virtual int exec() = 0; }; } diff --git a/src/userinterface/contracts/proctoring/i_proctoring_window.h b/src/userinterface/contracts/proctoring/i_proctoring_window.h deleted file mode 100644 index c044a87..0000000 --- a/src/userinterface/contracts/proctoring/i_proctoring_window.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::proctoring { class IProctoringWindow { public: virtual ~IProctoringWindow() = default; virtual void show() = 0; virtual void hide() = 0; }; } diff --git a/src/userinterface/contracts/shell/events/activator_event_handler.h b/src/userinterface/contracts/shell/events/activator_event_handler.h deleted file mode 100644 index eb75b3c..0000000 --- a/src/userinterface/contracts/shell/events/activator_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::shell::events { -using ActivatorEventHandler = std::function; -} diff --git a/src/userinterface/contracts/shell/events/quit_button_clicked_event_handler.h b/src/userinterface/contracts/shell/events/quit_button_clicked_event_handler.h deleted file mode 100644 index f1502ad..0000000 --- a/src/userinterface/contracts/shell/events/quit_button_clicked_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::shell::events { -using QuitButtonClickedEventHandler = std::function; -} diff --git a/src/userinterface/contracts/shell/i_action_center.h b/src/userinterface/contracts/shell/i_action_center.h deleted file mode 100644 index 00c7a56..0000000 --- a/src/userinterface/contracts/shell/i_action_center.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::shell { class IActionCenter { public: virtual ~IActionCenter() = default; virtual void show() = 0; virtual void hide() = 0; }; } diff --git a/src/userinterface/contracts/shell/i_action_center_activator.h b/src/userinterface/contracts/shell/i_action_center_activator.h deleted file mode 100644 index 7fcbbbd..0000000 --- a/src/userinterface/contracts/shell/i_action_center_activator.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "i_activator.h" -namespace seb::userinterface::contracts::shell { class IActionCenterActivator : public IActivator { public: ~IActionCenterActivator() override = default; }; } diff --git a/src/userinterface/contracts/shell/i_activator.h b/src/userinterface/contracts/shell/i_activator.h deleted file mode 100644 index 6e15416..0000000 --- a/src/userinterface/contracts/shell/i_activator.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::shell { class IActivator { public: virtual ~IActivator() = default; virtual void setEnabled(bool enabled) = 0; }; } diff --git a/src/userinterface/contracts/shell/i_application_control.h b/src/userinterface/contracts/shell/i_application_control.h deleted file mode 100644 index 7921f26..0000000 --- a/src/userinterface/contracts/shell/i_application_control.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::shell { class IApplicationControl { public: virtual ~IApplicationControl() = default; virtual void updateState() = 0; }; } diff --git a/src/userinterface/contracts/shell/i_notification_control.h b/src/userinterface/contracts/shell/i_notification_control.h deleted file mode 100644 index cc7b4a4..0000000 --- a/src/userinterface/contracts/shell/i_notification_control.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::shell { class INotificationControl { public: virtual ~INotificationControl() = default; virtual void setVisible(bool visible) = 0; }; } diff --git a/src/userinterface/contracts/shell/i_system_control.h b/src/userinterface/contracts/shell/i_system_control.h deleted file mode 100644 index 2448831..0000000 --- a/src/userinterface/contracts/shell/i_system_control.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::shell { class ISystemControl { public: virtual ~ISystemControl() = default; virtual void setEnabled(bool enabled) = 0; }; } diff --git a/src/userinterface/contracts/shell/i_taskbar.h b/src/userinterface/contracts/shell/i_taskbar.h deleted file mode 100644 index e703405..0000000 --- a/src/userinterface/contracts/shell/i_taskbar.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::shell { class ITaskbar { public: virtual ~ITaskbar() = default; virtual void show() = 0; virtual void hide() = 0; }; } diff --git a/src/userinterface/contracts/shell/i_taskbar_activator.h b/src/userinterface/contracts/shell/i_taskbar_activator.h deleted file mode 100644 index d8e1ba8..0000000 --- a/src/userinterface/contracts/shell/i_taskbar_activator.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "i_activator.h" -namespace seb::userinterface::contracts::shell { class ITaskbarActivator : public IActivator { public: ~ITaskbarActivator() override = default; }; } diff --git a/src/userinterface/contracts/shell/i_taskview.h b/src/userinterface/contracts/shell/i_taskview.h deleted file mode 100644 index d31c085..0000000 --- a/src/userinterface/contracts/shell/i_taskview.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::shell { class ITaskView { public: virtual ~ITaskView() = default; virtual void show() = 0; virtual void hide() = 0; }; } diff --git a/src/userinterface/contracts/shell/i_taskview_activator.h b/src/userinterface/contracts/shell/i_taskview_activator.h deleted file mode 100644 index 3380a38..0000000 --- a/src/userinterface/contracts/shell/i_taskview_activator.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "i_activator.h" -namespace seb::userinterface::contracts::shell { class ITaskViewActivator : public IActivator { public: ~ITaskViewActivator() override = default; }; } diff --git a/src/userinterface/contracts/shell/i_termination_activator.h b/src/userinterface/contracts/shell/i_termination_activator.h deleted file mode 100644 index 0047d09..0000000 --- a/src/userinterface/contracts/shell/i_termination_activator.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "i_activator.h" -namespace seb::userinterface::contracts::shell { class ITerminationActivator : public IActivator { public: ~ITerminationActivator() override = default; }; } diff --git a/src/userinterface/contracts/shell/i_verificator_activator.h b/src/userinterface/contracts/shell/i_verificator_activator.h deleted file mode 100644 index c2ba482..0000000 --- a/src/userinterface/contracts/shell/i_verificator_activator.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "i_activator.h" -namespace seb::userinterface::contracts::shell { class IVerificatorActivator : public IActivator { public: ~IVerificatorActivator() override = default; }; } diff --git a/src/userinterface/contracts/shell/location.h b/src/userinterface/contracts/shell/location.h deleted file mode 100644 index f7ff42c..0000000 --- a/src/userinterface/contracts/shell/location.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::shell { enum class Location { Taskbar, ActionCenter, Taskview }; } diff --git a/src/userinterface/contracts/windows/data/credentials_dialog_purpose.h b/src/userinterface/contracts/windows/data/credentials_dialog_purpose.h deleted file mode 100644 index b9c25d4..0000000 --- a/src/userinterface/contracts/windows/data/credentials_dialog_purpose.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::windows::data { enum class CredentialsDialogPurpose { Proxy, Server, WiFi }; } diff --git a/src/userinterface/contracts/windows/data/credentials_dialog_result.h b/src/userinterface/contracts/windows/data/credentials_dialog_result.h deleted file mode 100644 index 5bed86e..0000000 --- a/src/userinterface/contracts/windows/data/credentials_dialog_result.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::windows::data { -struct CredentialsDialogResult { bool accepted = false; QString username; QString password; }; -} diff --git a/src/userinterface/contracts/windows/data/exam_selection_dialog_result.h b/src/userinterface/contracts/windows/data/exam_selection_dialog_result.h deleted file mode 100644 index be8871a..0000000 --- a/src/userinterface/contracts/windows/data/exam_selection_dialog_result.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::windows::data { -struct ExamSelectionDialogResult { bool accepted = false; QString examId; }; -} diff --git a/src/userinterface/contracts/windows/data/lock_screen_option.h b/src/userinterface/contracts/windows/data/lock_screen_option.h deleted file mode 100644 index d489a3e..0000000 --- a/src/userinterface/contracts/windows/data/lock_screen_option.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::windows::data { enum class LockScreenOption { None, Password, SignOut }; } diff --git a/src/userinterface/contracts/windows/data/lock_screen_result.h b/src/userinterface/contracts/windows/data/lock_screen_result.h deleted file mode 100644 index ccdf134..0000000 --- a/src/userinterface/contracts/windows/data/lock_screen_result.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "lock_screen_option.h" -namespace seb::userinterface::contracts::windows::data { struct LockScreenResult { bool accepted = false; LockScreenOption option = LockScreenOption::None; }; } diff --git a/src/userinterface/contracts/windows/data/password_dialog_result.h b/src/userinterface/contracts/windows/data/password_dialog_result.h deleted file mode 100644 index d342bab..0000000 --- a/src/userinterface/contracts/windows/data/password_dialog_result.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::windows::data { -struct PasswordDialogResult { bool accepted = false; QString password; }; -} diff --git a/src/userinterface/contracts/windows/data/server_failure_dialog_result.h b/src/userinterface/contracts/windows/data/server_failure_dialog_result.h deleted file mode 100644 index af9c702..0000000 --- a/src/userinterface/contracts/windows/data/server_failure_dialog_result.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::windows::data { enum class ServerFailureDialogResult { Retry, Continue, Quit }; } diff --git a/src/userinterface/contracts/windows/events/window_closed_event_handler.h b/src/userinterface/contracts/windows/events/window_closed_event_handler.h deleted file mode 100644 index 59861c3..0000000 --- a/src/userinterface/contracts/windows/events/window_closed_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::windows::events { -using WindowClosedEventHandler = std::function; -} diff --git a/src/userinterface/contracts/windows/events/window_closing_event_handler.h b/src/userinterface/contracts/windows/events/window_closing_event_handler.h deleted file mode 100644 index 2001c24..0000000 --- a/src/userinterface/contracts/windows/events/window_closing_event_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::contracts::windows::events { -using WindowClosingEventHandler = std::function; -} diff --git a/src/userinterface/contracts/windows/i_credentials_dialog.h b/src/userinterface/contracts/windows/i_credentials_dialog.h deleted file mode 100644 index 949bfde..0000000 --- a/src/userinterface/contracts/windows/i_credentials_dialog.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "data/credentials_dialog_result.h" - -namespace seb::userinterface::contracts::windows { class ICredentialsDialog { public: virtual ~ICredentialsDialog() = default; virtual data::CredentialsDialogResult exec() = 0; }; } diff --git a/src/userinterface/contracts/windows/i_exam_selection_dialog.h b/src/userinterface/contracts/windows/i_exam_selection_dialog.h deleted file mode 100644 index fbcba0b..0000000 --- a/src/userinterface/contracts/windows/i_exam_selection_dialog.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "data/exam_selection_dialog_result.h" - -namespace seb::userinterface::contracts::windows { class IExamSelectionDialog { public: virtual ~IExamSelectionDialog() = default; virtual data::ExamSelectionDialogResult exec() = 0; }; } diff --git a/src/userinterface/contracts/windows/i_lock_screen.h b/src/userinterface/contracts/windows/i_lock_screen.h deleted file mode 100644 index 3d69f13..0000000 --- a/src/userinterface/contracts/windows/i_lock_screen.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "data/lock_screen_result.h" - -namespace seb::userinterface::contracts::windows { class ILockScreen { public: virtual ~ILockScreen() = default; virtual data::LockScreenResult exec() = 0; }; } diff --git a/src/userinterface/contracts/windows/i_password_dialog.h b/src/userinterface/contracts/windows/i_password_dialog.h deleted file mode 100644 index 72b7728..0000000 --- a/src/userinterface/contracts/windows/i_password_dialog.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "data/password_dialog_result.h" - -namespace seb::userinterface::contracts::windows { class IPasswordDialog { public: virtual ~IPasswordDialog() = default; virtual data::PasswordDialogResult exec() = 0; }; } diff --git a/src/userinterface/contracts/windows/i_runtime_window.h b/src/userinterface/contracts/windows/i_runtime_window.h deleted file mode 100644 index 6268a02..0000000 --- a/src/userinterface/contracts/windows/i_runtime_window.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "i_window.h" -namespace seb::userinterface::contracts::windows { class IRuntimeWindow : public IWindow { public: ~IRuntimeWindow() override = default; }; } diff --git a/src/userinterface/contracts/windows/i_server_failure_dialog.h b/src/userinterface/contracts/windows/i_server_failure_dialog.h deleted file mode 100644 index dd5dd11..0000000 --- a/src/userinterface/contracts/windows/i_server_failure_dialog.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "data/server_failure_dialog_result.h" - -namespace seb::userinterface::contracts::windows { class IServerFailureDialog { public: virtual ~IServerFailureDialog() = default; virtual data::ServerFailureDialogResult exec() = 0; }; } diff --git a/src/userinterface/contracts/windows/i_splash_screen.h b/src/userinterface/contracts/windows/i_splash_screen.h deleted file mode 100644 index 12de131..0000000 --- a/src/userinterface/contracts/windows/i_splash_screen.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "i_window.h" -namespace seb::userinterface::contracts::windows { class ISplashScreen : public IWindow { public: ~ISplashScreen() override = default; }; } diff --git a/src/userinterface/contracts/windows/i_verificator_overlay.h b/src/userinterface/contracts/windows/i_verificator_overlay.h deleted file mode 100644 index 113c482..0000000 --- a/src/userinterface/contracts/windows/i_verificator_overlay.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "i_window.h" -namespace seb::userinterface::contracts::windows { class IVerificatorOverlay : public IWindow { public: ~IVerificatorOverlay() override = default; }; } diff --git a/src/userinterface/contracts/windows/i_window.h b/src/userinterface/contracts/windows/i_window.h deleted file mode 100644 index eeebbd4..0000000 --- a/src/userinterface/contracts/windows/i_window.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::contracts::windows { class IWindow { public: virtual ~IWindow() = default; virtual void show() = 0; virtual void hide() = 0; virtual void close() = 0; }; } diff --git a/src/userinterface/desktop/Properties/AssemblyInfo.h b/src/userinterface/desktop/Properties/AssemblyInfo.h deleted file mode 100644 index e583988..0000000 --- a/src/userinterface/desktop/Properties/AssemblyInfo.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -namespace seb::userinterface::desktop::assemblyinfo { - -inline constexpr auto kTitle = "SafeExamBrowser.UserInterface.Desktop"; -inline constexpr auto kDescription = "Safe Exam Browser"; -inline constexpr auto kCompany = "JVR2022"; -inline constexpr auto kProduct = "SafeExamBrowser.UserInterface.Desktop"; -inline constexpr auto kCopyright = "Copyright (C) 2026 JVR2022"; -inline constexpr auto kVersion = "1.0.0.0"; - -} // namespace seb::userinterface::desktop::assemblyinfo diff --git a/src/userinterface/desktop/control_factory.cpp b/src/userinterface/desktop/control_factory.cpp deleted file mode 100644 index a4a48f5..0000000 --- a/src/userinterface/desktop/control_factory.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "control_factory.h" diff --git a/src/userinterface/desktop/control_factory.h b/src/userinterface/desktop/control_factory.h deleted file mode 100644 index 29d554b..0000000 --- a/src/userinterface/desktop/control_factory.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -namespace seb::userinterface::desktop { class ControlFactory {}; } diff --git a/src/userinterface/desktop/controls/action_center/action_center_control_base.cpp b/src/userinterface/desktop/controls/action_center/action_center_control_base.cpp deleted file mode 100644 index 5db6fe7..0000000 --- a/src/userinterface/desktop/controls/action_center/action_center_control_base.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "action_center_control_base.h" -namespace seb::userinterface::desktop::controls::action_center { ActionCenterControlBase::ActionCenterControlBase(QWidget *parent) : QWidget(parent) {} } diff --git a/src/userinterface/desktop/controls/action_center/action_center_control_base.h b/src/userinterface/desktop/controls/action_center/action_center_control_base.h deleted file mode 100644 index 9639b55..0000000 --- a/src/userinterface/desktop/controls/action_center/action_center_control_base.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::action_center { class ActionCenterControlBase : public QWidget { Q_OBJECT public: explicit ActionCenterControlBase(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/application_button.cpp b/src/userinterface/desktop/controls/action_center/application_button.cpp deleted file mode 100644 index e25a76c..0000000 --- a/src/userinterface/desktop/controls/action_center/application_button.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "application_button.h" -namespace seb::userinterface::desktop::controls::action_center { ApplicationButton::ApplicationButton(QWidget *parent) : QPushButton(parent) { setText(QStringLiteral("App")); } } diff --git a/src/userinterface/desktop/controls/action_center/application_button.h b/src/userinterface/desktop/controls/action_center/application_button.h deleted file mode 100644 index 30cb56e..0000000 --- a/src/userinterface/desktop/controls/action_center/application_button.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::action_center { class ApplicationButton : public QPushButton { Q_OBJECT public: explicit ApplicationButton(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/application_control.cpp b/src/userinterface/desktop/controls/action_center/application_control.cpp deleted file mode 100644 index 87f67c1..0000000 --- a/src/userinterface/desktop/controls/action_center/application_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "application_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::action_center { ApplicationControl::ApplicationControl(QWidget *parent) : ActionCenterControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Application"), this)); } } diff --git a/src/userinterface/desktop/controls/action_center/application_control.h b/src/userinterface/desktop/controls/action_center/application_control.h deleted file mode 100644 index d5f047c..0000000 --- a/src/userinterface/desktop/controls/action_center/application_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "action_center_control_base.h" -namespace seb::userinterface::desktop::controls::action_center { class ApplicationControl : public ActionCenterControlBase { Q_OBJECT public: explicit ApplicationControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/audio_control.cpp b/src/userinterface/desktop/controls/action_center/audio_control.cpp deleted file mode 100644 index e5f37c5..0000000 --- a/src/userinterface/desktop/controls/action_center/audio_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "audio_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::action_center { AudioControl::AudioControl(QWidget *parent) : ActionCenterControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Audio"), this)); } } diff --git a/src/userinterface/desktop/controls/action_center/audio_control.h b/src/userinterface/desktop/controls/action_center/audio_control.h deleted file mode 100644 index 449c11e..0000000 --- a/src/userinterface/desktop/controls/action_center/audio_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "action_center_control_base.h" -namespace seb::userinterface::desktop::controls::action_center { class AudioControl : public ActionCenterControlBase { Q_OBJECT public: explicit AudioControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/clock.cpp b/src/userinterface/desktop/controls/action_center/clock.cpp deleted file mode 100644 index 56fed38..0000000 --- a/src/userinterface/desktop/controls/action_center/clock.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "clock.h" -#include -#include -namespace seb::userinterface::desktop::controls::action_center { Clock::Clock(QWidget *parent) : ActionCenterControlBase(parent) { auto *l = new QVBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("00:00"), this)); l->addWidget(new QLabel(QStringLiteral("1970-01-01"), this)); } } diff --git a/src/userinterface/desktop/controls/action_center/clock.h b/src/userinterface/desktop/controls/action_center/clock.h deleted file mode 100644 index a3f01d3..0000000 --- a/src/userinterface/desktop/controls/action_center/clock.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "action_center_control_base.h" -namespace seb::userinterface::desktop::controls::action_center { class Clock : public ActionCenterControlBase { Q_OBJECT public: explicit Clock(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/keyboard_layout_button.cpp b/src/userinterface/desktop/controls/action_center/keyboard_layout_button.cpp deleted file mode 100644 index 4427ea1..0000000 --- a/src/userinterface/desktop/controls/action_center/keyboard_layout_button.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "keyboard_layout_button.h" -namespace seb::userinterface::desktop::controls::action_center { KeyboardLayoutButton::KeyboardLayoutButton(QWidget *parent) : QPushButton(parent) { setText(QStringLiteral("EN")); } } diff --git a/src/userinterface/desktop/controls/action_center/keyboard_layout_button.h b/src/userinterface/desktop/controls/action_center/keyboard_layout_button.h deleted file mode 100644 index 4eecbac..0000000 --- a/src/userinterface/desktop/controls/action_center/keyboard_layout_button.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::action_center { class KeyboardLayoutButton : public QPushButton { Q_OBJECT public: explicit KeyboardLayoutButton(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/keyboard_layout_control.cpp b/src/userinterface/desktop/controls/action_center/keyboard_layout_control.cpp deleted file mode 100644 index e3fa60b..0000000 --- a/src/userinterface/desktop/controls/action_center/keyboard_layout_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "keyboard_layout_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::action_center { KeyboardLayoutControl::KeyboardLayoutControl(QWidget *parent) : ActionCenterControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Keyboard"), this)); } } diff --git a/src/userinterface/desktop/controls/action_center/keyboard_layout_control.h b/src/userinterface/desktop/controls/action_center/keyboard_layout_control.h deleted file mode 100644 index add4fe6..0000000 --- a/src/userinterface/desktop/controls/action_center/keyboard_layout_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "action_center_control_base.h" -namespace seb::userinterface::desktop::controls::action_center { class KeyboardLayoutControl : public ActionCenterControlBase { Q_OBJECT public: explicit KeyboardLayoutControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/network_button.cpp b/src/userinterface/desktop/controls/action_center/network_button.cpp deleted file mode 100644 index d838d00..0000000 --- a/src/userinterface/desktop/controls/action_center/network_button.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "network_button.h" -namespace seb::userinterface::desktop::controls::action_center { NetworkButton::NetworkButton(QWidget *parent) : QPushButton(parent) { setText(QStringLiteral("Net")); } } diff --git a/src/userinterface/desktop/controls/action_center/network_button.h b/src/userinterface/desktop/controls/action_center/network_button.h deleted file mode 100644 index 6623672..0000000 --- a/src/userinterface/desktop/controls/action_center/network_button.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::action_center { class NetworkButton : public QPushButton { Q_OBJECT public: explicit NetworkButton(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/network_control.cpp b/src/userinterface/desktop/controls/action_center/network_control.cpp deleted file mode 100644 index a161e6c..0000000 --- a/src/userinterface/desktop/controls/action_center/network_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "network_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::action_center { NetworkControl::NetworkControl(QWidget *parent) : ActionCenterControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Network"), this)); } } diff --git a/src/userinterface/desktop/controls/action_center/network_control.h b/src/userinterface/desktop/controls/action_center/network_control.h deleted file mode 100644 index 8ebd77f..0000000 --- a/src/userinterface/desktop/controls/action_center/network_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "action_center_control_base.h" -namespace seb::userinterface::desktop::controls::action_center { class NetworkControl : public ActionCenterControlBase { Q_OBJECT public: explicit NetworkControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/notification_button.cpp b/src/userinterface/desktop/controls/action_center/notification_button.cpp deleted file mode 100644 index dbf15ce..0000000 --- a/src/userinterface/desktop/controls/action_center/notification_button.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "notification_button.h" -namespace seb::userinterface::desktop::controls::action_center { NotificationButton::NotificationButton(QWidget *parent) : QPushButton(parent) { setText(QStringLiteral("!")); } } diff --git a/src/userinterface/desktop/controls/action_center/notification_button.h b/src/userinterface/desktop/controls/action_center/notification_button.h deleted file mode 100644 index 4ed44ce..0000000 --- a/src/userinterface/desktop/controls/action_center/notification_button.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::action_center { class NotificationButton : public QPushButton { Q_OBJECT public: explicit NotificationButton(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/power_supply_control.cpp b/src/userinterface/desktop/controls/action_center/power_supply_control.cpp deleted file mode 100644 index beffb2b..0000000 --- a/src/userinterface/desktop/controls/action_center/power_supply_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "power_supply_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::action_center { PowerSupplyControl::PowerSupplyControl(QWidget *parent) : ActionCenterControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Power"), this)); } } diff --git a/src/userinterface/desktop/controls/action_center/power_supply_control.h b/src/userinterface/desktop/controls/action_center/power_supply_control.h deleted file mode 100644 index 28da6c2..0000000 --- a/src/userinterface/desktop/controls/action_center/power_supply_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "action_center_control_base.h" -namespace seb::userinterface::desktop::controls::action_center { class PowerSupplyControl : public ActionCenterControlBase { Q_OBJECT public: explicit PowerSupplyControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/quit_button.cpp b/src/userinterface/desktop/controls/action_center/quit_button.cpp deleted file mode 100644 index 93a3030..0000000 --- a/src/userinterface/desktop/controls/action_center/quit_button.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "quit_button.h" -namespace seb::userinterface::desktop::controls::action_center { QuitButton::QuitButton(QWidget *parent) : QPushButton(parent) { setText(QStringLiteral("Quit")); } } diff --git a/src/userinterface/desktop/controls/action_center/quit_button.h b/src/userinterface/desktop/controls/action_center/quit_button.h deleted file mode 100644 index 23b5c13..0000000 --- a/src/userinterface/desktop/controls/action_center/quit_button.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::action_center { class QuitButton : public QPushButton { Q_OBJECT public: explicit QuitButton(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/action_center/raise_hand_control.cpp b/src/userinterface/desktop/controls/action_center/raise_hand_control.cpp deleted file mode 100644 index 3c9ae5a..0000000 --- a/src/userinterface/desktop/controls/action_center/raise_hand_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "raise_hand_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::action_center { RaiseHandControl::RaiseHandControl(QWidget *parent) : ActionCenterControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Raise Hand"), this)); } } diff --git a/src/userinterface/desktop/controls/action_center/raise_hand_control.h b/src/userinterface/desktop/controls/action_center/raise_hand_control.h deleted file mode 100644 index 6caa999..0000000 --- a/src/userinterface/desktop/controls/action_center/raise_hand_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "action_center_control_base.h" -namespace seb::userinterface::desktop::controls::action_center { class RaiseHandControl : public ActionCenterControlBase { Q_OBJECT public: explicit RaiseHandControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/browser/download_item_control.cpp b/src/userinterface/desktop/controls/browser/download_item_control.cpp deleted file mode 100644 index 5b241e4..0000000 --- a/src/userinterface/desktop/controls/browser/download_item_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "download_item_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::browser { DownloadItemControl::DownloadItemControl(QWidget *parent) : QWidget(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Download"), this)); } } diff --git a/src/userinterface/desktop/controls/browser/download_item_control.h b/src/userinterface/desktop/controls/browser/download_item_control.h deleted file mode 100644 index aaeee01..0000000 --- a/src/userinterface/desktop/controls/browser/download_item_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::browser { class DownloadItemControl : public QWidget { Q_OBJECT public: explicit DownloadItemControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/application_control.cpp b/src/userinterface/desktop/controls/taskbar/application_control.cpp deleted file mode 100644 index fda76ae..0000000 --- a/src/userinterface/desktop/controls/taskbar/application_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "application_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::taskbar { ApplicationControl::ApplicationControl(QWidget *parent) : TaskbarControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("App"), this)); } } diff --git a/src/userinterface/desktop/controls/taskbar/application_control.h b/src/userinterface/desktop/controls/taskbar/application_control.h deleted file mode 100644 index 8d4c265..0000000 --- a/src/userinterface/desktop/controls/taskbar/application_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "taskbar_control_base.h" -namespace seb::userinterface::desktop::controls::taskbar { class ApplicationControl : public TaskbarControlBase { Q_OBJECT public: explicit ApplicationControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/application_window_button.cpp b/src/userinterface/desktop/controls/taskbar/application_window_button.cpp deleted file mode 100644 index 5ff413b..0000000 --- a/src/userinterface/desktop/controls/taskbar/application_window_button.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "application_window_button.h" -namespace seb::userinterface::desktop::controls::taskbar { ApplicationWindowButton::ApplicationWindowButton(QWidget *parent) : QPushButton(parent) { setText(QStringLiteral("Window")); } } diff --git a/src/userinterface/desktop/controls/taskbar/application_window_button.h b/src/userinterface/desktop/controls/taskbar/application_window_button.h deleted file mode 100644 index e9e04bb..0000000 --- a/src/userinterface/desktop/controls/taskbar/application_window_button.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::taskbar { class ApplicationWindowButton : public QPushButton { Q_OBJECT public: explicit ApplicationWindowButton(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/audio_control.cpp b/src/userinterface/desktop/controls/taskbar/audio_control.cpp deleted file mode 100644 index 2553526..0000000 --- a/src/userinterface/desktop/controls/taskbar/audio_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "audio_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::taskbar { AudioControl::AudioControl(QWidget *parent) : TaskbarControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Audio"), this)); } } diff --git a/src/userinterface/desktop/controls/taskbar/audio_control.h b/src/userinterface/desktop/controls/taskbar/audio_control.h deleted file mode 100644 index 89e9b03..0000000 --- a/src/userinterface/desktop/controls/taskbar/audio_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "taskbar_control_base.h" -namespace seb::userinterface::desktop::controls::taskbar { class AudioControl : public TaskbarControlBase { Q_OBJECT public: explicit AudioControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/clock.cpp b/src/userinterface/desktop/controls/taskbar/clock.cpp deleted file mode 100644 index 577e376..0000000 --- a/src/userinterface/desktop/controls/taskbar/clock.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "clock.h" -#include -#include -namespace seb::userinterface::desktop::controls::taskbar { Clock::Clock(QWidget *parent) : TaskbarControlBase(parent) { auto *l = new QVBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("00:00"), this)); l->addWidget(new QLabel(QStringLiteral("1970-01-01"), this)); } } diff --git a/src/userinterface/desktop/controls/taskbar/clock.h b/src/userinterface/desktop/controls/taskbar/clock.h deleted file mode 100644 index 0bbfcc8..0000000 --- a/src/userinterface/desktop/controls/taskbar/clock.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "taskbar_control_base.h" -namespace seb::userinterface::desktop::controls::taskbar { class Clock : public TaskbarControlBase { Q_OBJECT public: explicit Clock(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/keyboard_layout_button.cpp b/src/userinterface/desktop/controls/taskbar/keyboard_layout_button.cpp deleted file mode 100644 index 66f9491..0000000 --- a/src/userinterface/desktop/controls/taskbar/keyboard_layout_button.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "keyboard_layout_button.h" -namespace seb::userinterface::desktop::controls::taskbar { KeyboardLayoutButton::KeyboardLayoutButton(QWidget *parent) : QPushButton(parent) { setText(QStringLiteral("EN")); } } diff --git a/src/userinterface/desktop/controls/taskbar/keyboard_layout_button.h b/src/userinterface/desktop/controls/taskbar/keyboard_layout_button.h deleted file mode 100644 index 6b965ae..0000000 --- a/src/userinterface/desktop/controls/taskbar/keyboard_layout_button.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::taskbar { class KeyboardLayoutButton : public QPushButton { Q_OBJECT public: explicit KeyboardLayoutButton(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/keyboard_layout_control.cpp b/src/userinterface/desktop/controls/taskbar/keyboard_layout_control.cpp deleted file mode 100644 index 0682b61..0000000 --- a/src/userinterface/desktop/controls/taskbar/keyboard_layout_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "keyboard_layout_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::taskbar { KeyboardLayoutControl::KeyboardLayoutControl(QWidget *parent) : TaskbarControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Keyboard"), this)); } } diff --git a/src/userinterface/desktop/controls/taskbar/keyboard_layout_control.h b/src/userinterface/desktop/controls/taskbar/keyboard_layout_control.h deleted file mode 100644 index 001b852..0000000 --- a/src/userinterface/desktop/controls/taskbar/keyboard_layout_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "taskbar_control_base.h" -namespace seb::userinterface::desktop::controls::taskbar { class KeyboardLayoutControl : public TaskbarControlBase { Q_OBJECT public: explicit KeyboardLayoutControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/network_button.cpp b/src/userinterface/desktop/controls/taskbar/network_button.cpp deleted file mode 100644 index c949af3..0000000 --- a/src/userinterface/desktop/controls/taskbar/network_button.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "network_button.h" -namespace seb::userinterface::desktop::controls::taskbar { NetworkButton::NetworkButton(QWidget *parent) : QPushButton(parent) { setText(QStringLiteral("Net")); } } diff --git a/src/userinterface/desktop/controls/taskbar/network_button.h b/src/userinterface/desktop/controls/taskbar/network_button.h deleted file mode 100644 index d84c51c..0000000 --- a/src/userinterface/desktop/controls/taskbar/network_button.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::taskbar { class NetworkButton : public QPushButton { Q_OBJECT public: explicit NetworkButton(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/network_control.cpp b/src/userinterface/desktop/controls/taskbar/network_control.cpp deleted file mode 100644 index c7fcea7..0000000 --- a/src/userinterface/desktop/controls/taskbar/network_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "network_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::taskbar { NetworkControl::NetworkControl(QWidget *parent) : TaskbarControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Network"), this)); } } diff --git a/src/userinterface/desktop/controls/taskbar/network_control.h b/src/userinterface/desktop/controls/taskbar/network_control.h deleted file mode 100644 index 61e59c2..0000000 --- a/src/userinterface/desktop/controls/taskbar/network_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "taskbar_control_base.h" -namespace seb::userinterface::desktop::controls::taskbar { class NetworkControl : public TaskbarControlBase { Q_OBJECT public: explicit NetworkControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/notification_button.cpp b/src/userinterface/desktop/controls/taskbar/notification_button.cpp deleted file mode 100644 index d9c9f9f..0000000 --- a/src/userinterface/desktop/controls/taskbar/notification_button.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "notification_button.h" -namespace seb::userinterface::desktop::controls::taskbar { NotificationButton::NotificationButton(QWidget *parent) : QPushButton(parent) { setText(QStringLiteral("!")); } } diff --git a/src/userinterface/desktop/controls/taskbar/notification_button.h b/src/userinterface/desktop/controls/taskbar/notification_button.h deleted file mode 100644 index 498a6d2..0000000 --- a/src/userinterface/desktop/controls/taskbar/notification_button.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::taskbar { class NotificationButton : public QPushButton { Q_OBJECT public: explicit NotificationButton(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/power_supply_control.cpp b/src/userinterface/desktop/controls/taskbar/power_supply_control.cpp deleted file mode 100644 index d3e315a..0000000 --- a/src/userinterface/desktop/controls/taskbar/power_supply_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "power_supply_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::taskbar { PowerSupplyControl::PowerSupplyControl(QWidget *parent) : TaskbarControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Power"), this)); } } diff --git a/src/userinterface/desktop/controls/taskbar/power_supply_control.h b/src/userinterface/desktop/controls/taskbar/power_supply_control.h deleted file mode 100644 index 0457443..0000000 --- a/src/userinterface/desktop/controls/taskbar/power_supply_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "taskbar_control_base.h" -namespace seb::userinterface::desktop::controls::taskbar { class PowerSupplyControl : public TaskbarControlBase { Q_OBJECT public: explicit PowerSupplyControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/quit_button.cpp b/src/userinterface/desktop/controls/taskbar/quit_button.cpp deleted file mode 100644 index d445d6a..0000000 --- a/src/userinterface/desktop/controls/taskbar/quit_button.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "quit_button.h" -namespace seb::userinterface::desktop::controls::taskbar { QuitButton::QuitButton(QWidget *parent) : QPushButton(parent) { setText(QStringLiteral("Quit")); } } diff --git a/src/userinterface/desktop/controls/taskbar/quit_button.h b/src/userinterface/desktop/controls/taskbar/quit_button.h deleted file mode 100644 index c8d70a1..0000000 --- a/src/userinterface/desktop/controls/taskbar/quit_button.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::taskbar { class QuitButton : public QPushButton { Q_OBJECT public: explicit QuitButton(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/raise_hand_control.cpp b/src/userinterface/desktop/controls/taskbar/raise_hand_control.cpp deleted file mode 100644 index abc5fce..0000000 --- a/src/userinterface/desktop/controls/taskbar/raise_hand_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "raise_hand_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::taskbar { RaiseHandControl::RaiseHandControl(QWidget *parent) : TaskbarControlBase(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Raise Hand"), this)); } } diff --git a/src/userinterface/desktop/controls/taskbar/raise_hand_control.h b/src/userinterface/desktop/controls/taskbar/raise_hand_control.h deleted file mode 100644 index 750709b..0000000 --- a/src/userinterface/desktop/controls/taskbar/raise_hand_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "taskbar_control_base.h" -namespace seb::userinterface::desktop::controls::taskbar { class RaiseHandControl : public TaskbarControlBase { Q_OBJECT public: explicit RaiseHandControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/controls/taskbar/taskbar_control_base.cpp b/src/userinterface/desktop/controls/taskbar/taskbar_control_base.cpp deleted file mode 100644 index 034102e..0000000 --- a/src/userinterface/desktop/controls/taskbar/taskbar_control_base.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "taskbar_control_base.h" - -namespace seb::userinterface::desktop::controls::taskbar { - -TaskbarControlBase::TaskbarControlBase(QWidget *parent) : QWidget(parent) {} - -} // namespace seb::userinterface::desktop::controls::taskbar diff --git a/src/userinterface/desktop/controls/taskbar/taskbar_control_base.h b/src/userinterface/desktop/controls/taskbar/taskbar_control_base.h deleted file mode 100644 index cac5c2c..0000000 --- a/src/userinterface/desktop/controls/taskbar/taskbar_control_base.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::desktop::controls::taskbar { - -class TaskbarControlBase : public QWidget -{ -public: - explicit TaskbarControlBase(QWidget *parent = nullptr); -}; - -} // namespace seb::userinterface::desktop::controls::taskbar diff --git a/src/userinterface/desktop/controls/taskview/window_control.cpp b/src/userinterface/desktop/controls/taskview/window_control.cpp deleted file mode 100644 index 6093deb..0000000 --- a/src/userinterface/desktop/controls/taskview/window_control.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "window_control.h" -#include -#include -namespace seb::userinterface::desktop::controls::taskview { WindowControl::WindowControl(QWidget *parent) : QWidget(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Window"), this)); } } diff --git a/src/userinterface/desktop/controls/taskview/window_control.h b/src/userinterface/desktop/controls/taskview/window_control.h deleted file mode 100644 index a5d20be..0000000 --- a/src/userinterface/desktop/controls/taskview/window_control.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include -namespace seb::userinterface::desktop::controls::taskview { class WindowControl : public QWidget { Q_OBJECT public: explicit WindowControl(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/file_system_dialog_factory.cpp b/src/userinterface/desktop/file_system_dialog_factory.cpp deleted file mode 100644 index a7385bd..0000000 --- a/src/userinterface/desktop/file_system_dialog_factory.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "file_system_dialog_factory.h" - -#include - -namespace seb::userinterface::desktop { - -using contracts::file_system_dialog::FileSystemDialogResult; -using contracts::file_system_dialog::FileSystemOperation; - -FileSystemDialogResult FileSystemDialogFactory::exec() -{ - QFileDialog dialog; - dialog.setFileMode(QFileDialog::AnyFile); - - if (operation_ == FileSystemOperation::Save) { - dialog.setAcceptMode(QFileDialog::AcceptSave); - } else { - dialog.setAcceptMode(QFileDialog::AcceptOpen); - } - - if (dialog.exec() == QDialog::Accepted) { - const QStringList files = dialog.selectedFiles(); - if (!files.isEmpty()) { - selectedPath_ = files.first(); - } - return FileSystemDialogResult::Accept; - } - - selectedPath_.clear(); - return FileSystemDialogResult::Cancel; -} - -QString FileSystemDialogFactory::selectedPath() const -{ - return selectedPath_; -} - -void FileSystemDialogFactory::setOperation(FileSystemOperation operation) -{ - operation_ = operation; -} - -} // namespace seb::userinterface::desktop diff --git a/src/userinterface/desktop/file_system_dialog_factory.h b/src/userinterface/desktop/file_system_dialog_factory.h deleted file mode 100644 index 8c760ce..0000000 --- a/src/userinterface/desktop/file_system_dialog_factory.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "../contracts/file_system_dialog/i_file_system_dialog.h" - -#include - -namespace seb::userinterface::desktop { - -class FileSystemDialogFactory : public contracts::file_system_dialog::IFileSystemDialog -{ -public: - FileSystemDialogFactory() = default; - - contracts::file_system_dialog::FileSystemDialogResult exec() override; - QString selectedPath() const override; - void setOperation(contracts::file_system_dialog::FileSystemOperation operation) override; - -private: - QString selectedPath_; - contracts::file_system_dialog::FileSystemOperation operation_ = - contracts::file_system_dialog::FileSystemOperation::Open; -}; - -} // namespace seb::userinterface::desktop diff --git a/src/userinterface/desktop/message_box_factory.cpp b/src/userinterface/desktop/message_box_factory.cpp deleted file mode 100644 index 044f345..0000000 --- a/src/userinterface/desktop/message_box_factory.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "message_box_factory.h" - -#include - -namespace seb::userinterface::desktop { - -contracts::message_box::MessageBoxResult MessageBoxFactory::show( - const QString &title, - const QString &text, - contracts::message_box::MessageBoxAction action, - contracts::message_box::MessageBoxIcon icon) -{ - QMessageBox box; - box.setWindowTitle(title); - box.setText(text); - box.setIcon(icon == contracts::message_box::MessageBoxIcon::Warning ? QMessageBox::Warning : - icon == contracts::message_box::MessageBoxIcon::Error ? QMessageBox::Critical : - icon == contracts::message_box::MessageBoxIcon::Question ? QMessageBox::Question : - QMessageBox::Information); - box.setStandardButtons(action == contracts::message_box::MessageBoxAction::YesNo ? QMessageBox::Yes | QMessageBox::No : - action == contracts::message_box::MessageBoxAction::OkCancel ? QMessageBox::Ok | QMessageBox::Cancel : - QMessageBox::Ok); - const auto result = static_cast(box.exec()); - if (result == QMessageBox::Yes) return contracts::message_box::MessageBoxResult::Yes; - if (result == QMessageBox::No) return contracts::message_box::MessageBoxResult::No; - if (result == QMessageBox::Cancel) return contracts::message_box::MessageBoxResult::Cancel; - return contracts::message_box::MessageBoxResult::Ok; -} - -} // namespace seb::userinterface::desktop diff --git a/src/userinterface/desktop/message_box_factory.h b/src/userinterface/desktop/message_box_factory.h deleted file mode 100644 index 473e44d..0000000 --- a/src/userinterface/desktop/message_box_factory.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../contracts/message_box/i_message_box.h" - -namespace seb::userinterface::desktop { - -class MessageBoxFactory : public contracts::message_box::IMessageBox -{ -public: - contracts::message_box::MessageBoxResult show( - const QString &title, - const QString &text, - contracts::message_box::MessageBoxAction action = contracts::message_box::MessageBoxAction::Ok, - contracts::message_box::MessageBoxIcon icon = contracts::message_box::MessageBoxIcon::Information) override; -}; - -} // namespace seb::userinterface::desktop diff --git a/src/userinterface/desktop/user_interface_factory.cpp b/src/userinterface/desktop/user_interface_factory.cpp deleted file mode 100644 index b94eead..0000000 --- a/src/userinterface/desktop/user_interface_factory.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "user_interface_factory.h" - -namespace seb::userinterface::desktop { - -UserInterfaceFactory::UserInterfaceFactory(contracts::shell::ITaskbar *taskbar) - : taskbar_(taskbar), - runtimeWindow_(windowFactory_.createRuntimeWindow()), - splashScreen_(windowFactory_.createSplashScreen()) -{ -} - -contracts::message_box::IMessageBox *UserInterfaceFactory::messageBox() { return &messageBoxFactory_; } -contracts::shell::ITaskbar *UserInterfaceFactory::taskbar() { return taskbar_; } -contracts::windows::IRuntimeWindow *UserInterfaceFactory::runtimeWindow() { return runtimeWindow_.get(); } -contracts::windows::ISplashScreen *UserInterfaceFactory::splashScreen() { return splashScreen_.get(); } - -} // namespace seb::userinterface::desktop diff --git a/src/userinterface/desktop/user_interface_factory.h b/src/userinterface/desktop/user_interface_factory.h deleted file mode 100644 index 55d3f8f..0000000 --- a/src/userinterface/desktop/user_interface_factory.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "../contracts/i_user_interface_factory.h" -#include "../contracts/shell/i_taskbar.h" -#include "file_system_dialog_factory.h" -#include "message_box_factory.h" -#include "window_factory.h" -#include "windows/splash_screen.h" - -#include - -namespace seb::userinterface::desktop { - -class UserInterfaceFactory : public contracts::IUserInterfaceFactory -{ -public: - explicit UserInterfaceFactory(contracts::shell::ITaskbar *taskbar = nullptr); - - contracts::message_box::IMessageBox *messageBox() override; - contracts::shell::ITaskbar *taskbar() override; - contracts::windows::IRuntimeWindow *runtimeWindow() override; - contracts::windows::ISplashScreen *splashScreen() override; - -private: - FileSystemDialogFactory fileSystemDialogFactory_; - MessageBoxFactory messageBoxFactory_; - WindowFactory windowFactory_; - contracts::shell::ITaskbar *taskbar_ = nullptr; - std::unique_ptr runtimeWindow_; - std::unique_ptr splashScreen_; -}; - -} // namespace seb::userinterface::desktop diff --git a/src/userinterface/desktop/viewmodels/date_time_view_model.cpp b/src/userinterface/desktop/viewmodels/date_time_view_model.cpp deleted file mode 100644 index 474494f..0000000 --- a/src/userinterface/desktop/viewmodels/date_time_view_model.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "date_time_view_model.h" - -namespace seb::userinterface::desktop::viewmodels { - -QDateTime DateTimeViewModel::current() const -{ - return QDateTime::currentDateTime(); -} - -} // namespace seb::userinterface::desktop::viewmodels diff --git a/src/userinterface/desktop/viewmodels/date_time_view_model.h b/src/userinterface/desktop/viewmodels/date_time_view_model.h deleted file mode 100644 index e775d2b..0000000 --- a/src/userinterface/desktop/viewmodels/date_time_view_model.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::desktop::viewmodels { - -class DateTimeViewModel -{ -public: - QDateTime current() const; -}; - -} // namespace seb::userinterface::desktop::viewmodels diff --git a/src/userinterface/desktop/viewmodels/log_view_model.cpp b/src/userinterface/desktop/viewmodels/log_view_model.cpp deleted file mode 100644 index bd57ba6..0000000 --- a/src/userinterface/desktop/viewmodels/log_view_model.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "log_view_model.h" - -namespace seb::userinterface::desktop::viewmodels { - -void LogViewModel::append(const QString &line) -{ - lines_.push_back(line); -} - -QStringList LogViewModel::lines() const -{ - return lines_; -} - -} // namespace seb::userinterface::desktop::viewmodels diff --git a/src/userinterface/desktop/viewmodels/log_view_model.h b/src/userinterface/desktop/viewmodels/log_view_model.h deleted file mode 100644 index 57d9632..0000000 --- a/src/userinterface/desktop/viewmodels/log_view_model.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::desktop::viewmodels { - -class LogViewModel -{ -public: - void append(const QString &line); - QStringList lines() const; - -private: - QStringList lines_; -}; - -} // namespace seb::userinterface::desktop::viewmodels diff --git a/src/userinterface/desktop/viewmodels/progress_indicator_view_model.cpp b/src/userinterface/desktop/viewmodels/progress_indicator_view_model.cpp deleted file mode 100644 index 360dbf8..0000000 --- a/src/userinterface/desktop/viewmodels/progress_indicator_view_model.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "progress_indicator_view_model.h" - -namespace seb::userinterface::desktop::viewmodels { - -void ProgressIndicatorViewModel::setBusy(bool busy) { busy_ = busy; } -void ProgressIndicatorViewModel::setProgress(int current, int maximum) { current_ = current; maximum_ = maximum; } -bool ProgressIndicatorViewModel::busy() const { return busy_; } -int ProgressIndicatorViewModel::current() const { return current_; } -int ProgressIndicatorViewModel::maximum() const { return maximum_; } - -} // namespace seb::userinterface::desktop::viewmodels diff --git a/src/userinterface/desktop/viewmodels/progress_indicator_view_model.h b/src/userinterface/desktop/viewmodels/progress_indicator_view_model.h deleted file mode 100644 index 73d7be6..0000000 --- a/src/userinterface/desktop/viewmodels/progress_indicator_view_model.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -namespace seb::userinterface::desktop::viewmodels { - -class ProgressIndicatorViewModel -{ -public: - void setBusy(bool busy); - void setProgress(int current, int maximum); - bool busy() const; - int current() const; - int maximum() const; - -private: - bool busy_ = false; - int current_ = 0; - int maximum_ = 0; -}; - -} // namespace seb::userinterface::desktop::viewmodels diff --git a/src/userinterface/desktop/viewmodels/runtime_window_view_model.cpp b/src/userinterface/desktop/viewmodels/runtime_window_view_model.cpp deleted file mode 100644 index 6d8b882..0000000 --- a/src/userinterface/desktop/viewmodels/runtime_window_view_model.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "runtime_window_view_model.h" - -namespace seb::userinterface::desktop::viewmodels { - -void RuntimeWindowViewModel::setStatus(const QString &status) { status_ = status; } -QString RuntimeWindowViewModel::status() const { return status_; } - -} // namespace seb::userinterface::desktop::viewmodels diff --git a/src/userinterface/desktop/viewmodels/runtime_window_view_model.h b/src/userinterface/desktop/viewmodels/runtime_window_view_model.h deleted file mode 100644 index 63ee34e..0000000 --- a/src/userinterface/desktop/viewmodels/runtime_window_view_model.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -namespace seb::userinterface::desktop::viewmodels { - -class RuntimeWindowViewModel -{ -public: - void setStatus(const QString &status); - QString status() const; - -private: - QString status_; -}; - -} // namespace seb::userinterface::desktop::viewmodels diff --git a/src/userinterface/desktop/window_factory.cpp b/src/userinterface/desktop/window_factory.cpp deleted file mode 100644 index 158805b..0000000 --- a/src/userinterface/desktop/window_factory.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "window_factory.h" - -namespace seb::userinterface::desktop { - -std::unique_ptr WindowFactory::createAboutWindow() { return std::make_unique(); } -std::unique_ptr WindowFactory::createActionCenter() { return std::make_unique(); } -std::unique_ptr WindowFactory::createBrowserWindow(contracts::browser::IBrowserControl *) { return std::make_unique(); } -std::unique_ptr WindowFactory::createCredentialsDialog() { return std::make_unique(); } -std::unique_ptr WindowFactory::createExamSelectionDialog() { return std::make_unique(); } -std::unique_ptr WindowFactory::createLockScreen() { return std::make_unique(); } -std::unique_ptr WindowFactory::createLogWindow() { return std::make_unique(); } -std::unique_ptr WindowFactory::createPasswordDialog() { return std::make_unique(); } -std::unique_ptr WindowFactory::createProctoringFinalizationDialog() { return std::make_unique(); } -std::unique_ptr WindowFactory::createProctoringWindow(contracts::proctoring::IProctoringControl *) { return std::make_unique(); } -std::unique_ptr WindowFactory::createRuntimeWindow() { return std::make_unique(); } -std::unique_ptr WindowFactory::createServerFailureDialog() { return std::make_unique(); } -std::unique_ptr WindowFactory::createSplashScreen() { return std::make_unique(); } -std::unique_ptr WindowFactory::createTaskbarWindow() { return std::make_unique(); } -std::unique_ptr WindowFactory::createTaskview() { return std::make_unique(); } -std::unique_ptr WindowFactory::createVerificatorOverlay() { return std::make_unique(); } - -} // namespace seb::userinterface::desktop diff --git a/src/userinterface/desktop/window_factory.h b/src/userinterface/desktop/window_factory.h deleted file mode 100644 index a01a57d..0000000 --- a/src/userinterface/desktop/window_factory.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include "../contracts/browser/i_browser_control.h" -#include "../contracts/browser/i_browser_window.h" -#include "../contracts/proctoring/i_proctoring_control.h" -#include "../contracts/shell/i_action_center.h" -#include "../contracts/shell/i_taskbar.h" -#include "../contracts/shell/i_taskview.h" -#include "../contracts/windows/i_credentials_dialog.h" -#include "../contracts/windows/i_exam_selection_dialog.h" -#include "../contracts/windows/i_lock_screen.h" -#include "../contracts/windows/i_password_dialog.h" -#include "../contracts/windows/i_runtime_window.h" -#include "../contracts/windows/i_server_failure_dialog.h" -#include "../contracts/windows/i_splash_screen.h" -#include "../contracts/windows/i_verificator_overlay.h" -#include "windows/about_window.h" -#include "windows/action_center.h" -#include "windows/browser_window.h" -#include "windows/credentials_dialog.h" -#include "windows/exam_selection_dialog.h" -#include "windows/lock_screen.h" -#include "windows/log_window.h" -#include "windows/password_dialog.h" -#include "windows/proctoring_finalization_dialog.h" -#include "windows/proctoring_window.h" -#include "windows/runtime_window.h" -#include "windows/server_failure_dialog.h" -#include "windows/splash_screen.h" -#include "windows/taskbar_window.h" -#include "windows/taskview.h" -#include "windows/verificator_overlay.h" - -#include - -namespace seb::userinterface::desktop { - -class WindowFactory -{ -public: - WindowFactory() = default; - - std::unique_ptr createAboutWindow(); - std::unique_ptr createActionCenter(); - std::unique_ptr createBrowserWindow(contracts::browser::IBrowserControl *control = nullptr); - std::unique_ptr createCredentialsDialog(); - std::unique_ptr createExamSelectionDialog(); - std::unique_ptr createLockScreen(); - std::unique_ptr createLogWindow(); - std::unique_ptr createPasswordDialog(); - std::unique_ptr createProctoringFinalizationDialog(); - std::unique_ptr createProctoringWindow(contracts::proctoring::IProctoringControl *control = nullptr); - std::unique_ptr createRuntimeWindow(); - std::unique_ptr createServerFailureDialog(); - std::unique_ptr createSplashScreen(); - std::unique_ptr createTaskbarWindow(); - std::unique_ptr createTaskview(); - std::unique_ptr createVerificatorOverlay(); -}; - -} // namespace seb::userinterface::desktop diff --git a/src/userinterface/desktop/windows/about_window.cpp b/src/userinterface/desktop/windows/about_window.cpp deleted file mode 100644 index 0c9771d..0000000 --- a/src/userinterface/desktop/windows/about_window.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "about_window.h" - -#include -#include - -namespace seb::userinterface::desktop::windows { - -AboutWindow::AboutWindow(QWidget *parent) : BaseWindow(parent) -{ - setWindowTitle(QStringLiteral("About Safe Exam Browser")); - auto *layout = new QVBoxLayout(this); - layout->addWidget(new QLabel(QStringLiteral("Safe Exam Browser"), this)); -} - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/about_window.h b/src/userinterface/desktop/windows/about_window.h deleted file mode 100644 index 10447c4..0000000 --- a/src/userinterface/desktop/windows/about_window.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "base_window.h" - -namespace seb::userinterface::desktop::windows { -class AboutWindow : public BaseWindow { Q_OBJECT public: explicit AboutWindow(QWidget *parent = nullptr); }; -} diff --git a/src/userinterface/desktop/windows/action_center.cpp b/src/userinterface/desktop/windows/action_center.cpp deleted file mode 100644 index 970f882..0000000 --- a/src/userinterface/desktop/windows/action_center.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "action_center.h" -#include "../controls/action_center/application_control.h" -#include "../controls/action_center/audio_control.h" -#include "../controls/action_center/network_control.h" -#include "../controls/action_center/power_supply_control.h" -#include "../controls/action_center/clock.h" -#include "../controls/action_center/quit_button.h" -#include -namespace seb::userinterface::desktop::windows { ActionCenter::ActionCenter(QWidget *parent) : BaseWindow(parent) { auto *l = new QVBoxLayout(this); l->addWidget(new controls::action_center::ApplicationControl(this)); l->addWidget(new controls::action_center::AudioControl(this)); l->addWidget(new controls::action_center::NetworkControl(this)); l->addWidget(new controls::action_center::PowerSupplyControl(this)); l->addWidget(new controls::action_center::Clock(this)); l->addWidget(new controls::action_center::QuitButton(this)); } } diff --git a/src/userinterface/desktop/windows/action_center.h b/src/userinterface/desktop/windows/action_center.h deleted file mode 100644 index 9af9aa0..0000000 --- a/src/userinterface/desktop/windows/action_center.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "base_window.h" -namespace seb::userinterface::desktop::windows { class ActionCenter : public BaseWindow { Q_OBJECT public: explicit ActionCenter(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/windows/base_window.cpp b/src/userinterface/desktop/windows/base_window.cpp deleted file mode 100644 index 5dac2b6..0000000 --- a/src/userinterface/desktop/windows/base_window.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "base_window.h" - -namespace seb::userinterface::desktop::windows { - -BaseWindow::BaseWindow(QWidget *parent) : QDialog(parent) {} -void BaseWindow::show() { QDialog::show(); } -void BaseWindow::hide() { QDialog::hide(); } -void BaseWindow::close() { QDialog::close(); } - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/base_window.h b/src/userinterface/desktop/windows/base_window.h deleted file mode 100644 index 2e48e03..0000000 --- a/src/userinterface/desktop/windows/base_window.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../contracts/windows/i_window.h" - -#include - -namespace seb::userinterface::desktop::windows { - -class BaseWindow : public QDialog, public contracts::windows::IWindow -{ -public: - explicit BaseWindow(QWidget *parent = nullptr); - void show() override; - void hide() override; - void close() override; -}; - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/browser_window.cpp b/src/userinterface/desktop/windows/browser_window.cpp deleted file mode 100644 index 5f468e4..0000000 --- a/src/userinterface/desktop/windows/browser_window.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "browser_window.h" -#include -#include -namespace seb::userinterface::desktop::windows { BrowserWindow::BrowserWindow(QWidget *parent) : BaseWindow(parent) { auto *l = new QVBoxLayout(this); l->addWidget(new QLabel(QStringLiteral("Browser Window"), this)); } } diff --git a/src/userinterface/desktop/windows/browser_window.h b/src/userinterface/desktop/windows/browser_window.h deleted file mode 100644 index f200680..0000000 --- a/src/userinterface/desktop/windows/browser_window.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "base_window.h" -namespace seb::userinterface::desktop::windows { class BrowserWindow : public BaseWindow { Q_OBJECT public: explicit BrowserWindow(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/windows/credentials_dialog.cpp b/src/userinterface/desktop/windows/credentials_dialog.cpp deleted file mode 100644 index edf10be..0000000 --- a/src/userinterface/desktop/windows/credentials_dialog.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "credentials_dialog.h" - -#include -#include -#include -#include - -namespace seb::userinterface::desktop::windows { - -CredentialsDialog::CredentialsDialog(QWidget *parent) : parent_(parent) {} - -contracts::windows::data::CredentialsDialogResult CredentialsDialog::exec() -{ - QDialog dialog(parent_); - dialog.setWindowTitle(QStringLiteral("Credentials")); - auto *layout = new QVBoxLayout(&dialog); - auto *usernameEdit = new QLineEdit(&dialog); - auto *passwordEdit = new QLineEdit(&dialog); - passwordEdit->setEchoMode(QLineEdit::Password); - layout->addWidget(usernameEdit); - layout->addWidget(passwordEdit); - auto *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog); - QObject::connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); - QObject::connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); - layout->addWidget(buttons); - - contracts::windows::data::CredentialsDialogResult result; - result.accepted = (dialog.exec() == QDialog::Accepted); - result.username = usernameEdit->text(); - result.password = passwordEdit->text(); - return result; -} - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/credentials_dialog.h b/src/userinterface/desktop/windows/credentials_dialog.h deleted file mode 100644 index ce94262..0000000 --- a/src/userinterface/desktop/windows/credentials_dialog.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "../../contracts/windows/i_credentials_dialog.h" - -class QWidget; - -namespace seb::userinterface::desktop::windows { - -class CredentialsDialog : public contracts::windows::ICredentialsDialog -{ -public: - explicit CredentialsDialog(QWidget *parent = nullptr); - contracts::windows::data::CredentialsDialogResult exec() override; - -private: - QWidget *parent_ = nullptr; -}; - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/exam_selection_dialog.cpp b/src/userinterface/desktop/windows/exam_selection_dialog.cpp deleted file mode 100644 index f01af51..0000000 --- a/src/userinterface/desktop/windows/exam_selection_dialog.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "exam_selection_dialog.h" -#include -#include -#include -#include -namespace seb::userinterface::desktop::windows { ExamSelectionDialog::ExamSelectionDialog(QWidget *parent) : parent_(parent) {} contracts::windows::data::ExamSelectionDialogResult ExamSelectionDialog::exec() { QDialog dialog(parent_); auto *l = new QVBoxLayout(&dialog); auto *list = new QListWidget(&dialog); l->addWidget(list); auto *b = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog); QObject::connect(b, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); QObject::connect(b, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); l->addWidget(b); contracts::windows::data::ExamSelectionDialogResult r; r.accepted = (dialog.exec() == QDialog::Accepted); if (auto *item = list->currentItem()) r.examId = item->text(); return r; } } diff --git a/src/userinterface/desktop/windows/exam_selection_dialog.h b/src/userinterface/desktop/windows/exam_selection_dialog.h deleted file mode 100644 index 9a0c8f5..0000000 --- a/src/userinterface/desktop/windows/exam_selection_dialog.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "../../contracts/windows/i_exam_selection_dialog.h" -class QWidget; -namespace seb::userinterface::desktop::windows { class ExamSelectionDialog : public contracts::windows::IExamSelectionDialog { public: explicit ExamSelectionDialog(QWidget *parent = nullptr); contracts::windows::data::ExamSelectionDialogResult exec() override; private: QWidget *parent_ = nullptr; }; } diff --git a/src/userinterface/desktop/windows/file_system_dialog.cpp b/src/userinterface/desktop/windows/file_system_dialog.cpp deleted file mode 100644 index 7021b7b..0000000 --- a/src/userinterface/desktop/windows/file_system_dialog.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "file_system_dialog.h" -#include -namespace seb::userinterface::desktop::windows { FileSystemDialog::FileSystemDialog(QWidget *parent) : parent_(parent) {} contracts::file_system_dialog::FileSystemDialogResult FileSystemDialog::exec() { selectedPath_ = operation_ == contracts::file_system_dialog::FileSystemOperation::SelectFolder ? QFileDialog::getExistingDirectory(parent_) : QFileDialog::getOpenFileName(parent_); return selectedPath_.isEmpty() ? contracts::file_system_dialog::FileSystemDialogResult::Cancel : contracts::file_system_dialog::FileSystemDialogResult::Accept; } QString FileSystemDialog::selectedPath() const { return selectedPath_; } void FileSystemDialog::setOperation(contracts::file_system_dialog::FileSystemOperation operation) { operation_ = operation; } } diff --git a/src/userinterface/desktop/windows/file_system_dialog.h b/src/userinterface/desktop/windows/file_system_dialog.h deleted file mode 100644 index b5a5f44..0000000 --- a/src/userinterface/desktop/windows/file_system_dialog.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "../../contracts/file_system_dialog/i_file_system_dialog.h" -class QWidget; -namespace seb::userinterface::desktop::windows { class FileSystemDialog : public contracts::file_system_dialog::IFileSystemDialog { public: explicit FileSystemDialog(QWidget *parent = nullptr); contracts::file_system_dialog::FileSystemDialogResult exec() override; QString selectedPath() const override; void setOperation(contracts::file_system_dialog::FileSystemOperation operation) override; private: QWidget *parent_ = nullptr; QString selectedPath_; contracts::file_system_dialog::FileSystemOperation operation_ = contracts::file_system_dialog::FileSystemOperation::Open; }; } diff --git a/src/userinterface/desktop/windows/lock_screen.cpp b/src/userinterface/desktop/windows/lock_screen.cpp deleted file mode 100644 index 97451df..0000000 --- a/src/userinterface/desktop/windows/lock_screen.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "lock_screen.h" -#include -namespace seb::userinterface::desktop::windows { LockScreen::LockScreen(QWidget *parent) : parent_(parent) {} contracts::windows::data::LockScreenResult LockScreen::exec() { QDialog dialog(parent_); contracts::windows::data::LockScreenResult r; r.accepted = (dialog.exec() == QDialog::Accepted); return r; } } diff --git a/src/userinterface/desktop/windows/lock_screen.h b/src/userinterface/desktop/windows/lock_screen.h deleted file mode 100644 index 01f97ce..0000000 --- a/src/userinterface/desktop/windows/lock_screen.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "../../contracts/windows/i_lock_screen.h" -class QWidget; -namespace seb::userinterface::desktop::windows { class LockScreen : public contracts::windows::ILockScreen { public: explicit LockScreen(QWidget *parent = nullptr); contracts::windows::data::LockScreenResult exec() override; private: QWidget *parent_ = nullptr; }; } diff --git a/src/userinterface/desktop/windows/log_window.cpp b/src/userinterface/desktop/windows/log_window.cpp deleted file mode 100644 index 60c019e..0000000 --- a/src/userinterface/desktop/windows/log_window.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "log_window.h" - -#include -#include - -namespace seb::userinterface::desktop::windows { - -LogWindow::LogWindow(QWidget *parent) : BaseWindow(parent) -{ - setWindowTitle(QStringLiteral("Log")); - auto *layout = new QVBoxLayout(this); - textEdit_ = new QTextEdit(this); - textEdit_->setReadOnly(true); - layout->addWidget(textEdit_); -} - -void LogWindow::append(const QString &line) -{ - textEdit_->append(line); -} - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/log_window.h b/src/userinterface/desktop/windows/log_window.h deleted file mode 100644 index 55e92df..0000000 --- a/src/userinterface/desktop/windows/log_window.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "base_window.h" - -class QTextEdit; - -namespace seb::userinterface::desktop::windows { - -class LogWindow : public BaseWindow -{ -public: - explicit LogWindow(QWidget *parent = nullptr); - void append(const QString &line); - -private: - QTextEdit *textEdit_ = nullptr; -}; - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/password_dialog.cpp b/src/userinterface/desktop/windows/password_dialog.cpp deleted file mode 100644 index 219e4cf..0000000 --- a/src/userinterface/desktop/windows/password_dialog.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "password_dialog.h" - -#include -#include -#include -#include - -namespace seb::userinterface::desktop::windows { - -PasswordDialog::PasswordDialog(QWidget *parent) : parent_(parent) {} - -contracts::windows::data::PasswordDialogResult PasswordDialog::exec() -{ - QDialog dialog(parent_); - dialog.setWindowTitle(QStringLiteral("Password")); - auto *layout = new QVBoxLayout(&dialog); - auto *passwordEdit = new QLineEdit(&dialog); - passwordEdit->setEchoMode(QLineEdit::Password); - layout->addWidget(passwordEdit); - auto *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog); - QObject::connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); - QObject::connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); - layout->addWidget(buttons); - - contracts::windows::data::PasswordDialogResult result; - result.accepted = (dialog.exec() == QDialog::Accepted); - result.password = passwordEdit->text(); - return result; -} - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/password_dialog.h b/src/userinterface/desktop/windows/password_dialog.h deleted file mode 100644 index a48990d..0000000 --- a/src/userinterface/desktop/windows/password_dialog.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "../../contracts/windows/i_password_dialog.h" - -class QWidget; - -namespace seb::userinterface::desktop::windows { - -class PasswordDialog : public contracts::windows::IPasswordDialog -{ -public: - explicit PasswordDialog(QWidget *parent = nullptr); - contracts::windows::data::PasswordDialogResult exec() override; - -private: - QWidget *parent_ = nullptr; -}; - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/proctoring_finalization_dialog.cpp b/src/userinterface/desktop/windows/proctoring_finalization_dialog.cpp deleted file mode 100644 index 6928745..0000000 --- a/src/userinterface/desktop/windows/proctoring_finalization_dialog.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "proctoring_finalization_dialog.h" -#include -namespace seb::userinterface::desktop::windows { ProctoringFinalizationDialog::ProctoringFinalizationDialog(QWidget *parent) : parent_(parent) {} int ProctoringFinalizationDialog::exec() { QDialog dialog(parent_); return dialog.exec(); } } diff --git a/src/userinterface/desktop/windows/proctoring_finalization_dialog.h b/src/userinterface/desktop/windows/proctoring_finalization_dialog.h deleted file mode 100644 index bc14284..0000000 --- a/src/userinterface/desktop/windows/proctoring_finalization_dialog.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "../../contracts/proctoring/i_proctoring_finalization_dialog.h" -class QWidget; -namespace seb::userinterface::desktop::windows { class ProctoringFinalizationDialog : public contracts::proctoring::IProctoringFinalizationDialog { public: explicit ProctoringFinalizationDialog(QWidget *parent = nullptr); int exec() override; private: QWidget *parent_ = nullptr; }; } diff --git a/src/userinterface/desktop/windows/proctoring_window.cpp b/src/userinterface/desktop/windows/proctoring_window.cpp deleted file mode 100644 index fe23999..0000000 --- a/src/userinterface/desktop/windows/proctoring_window.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "proctoring_window.h" -namespace seb::userinterface::desktop::windows { ProctoringWindow::ProctoringWindow(QWidget *parent) : BaseWindow(parent) {} void ProctoringWindow::hide() { BaseWindow::hide(); } void ProctoringWindow::show() { BaseWindow::show(); } } diff --git a/src/userinterface/desktop/windows/proctoring_window.h b/src/userinterface/desktop/windows/proctoring_window.h deleted file mode 100644 index 3cc0d71..0000000 --- a/src/userinterface/desktop/windows/proctoring_window.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "../../contracts/proctoring/i_proctoring_window.h" -#include "base_window.h" -namespace seb::userinterface::desktop::windows { class ProctoringWindow : public BaseWindow, public contracts::proctoring::IProctoringWindow { Q_OBJECT public: explicit ProctoringWindow(QWidget *parent = nullptr); void hide() override; void show() override; }; } diff --git a/src/userinterface/desktop/windows/runtime_window.cpp b/src/userinterface/desktop/windows/runtime_window.cpp deleted file mode 100644 index bad0fe4..0000000 --- a/src/userinterface/desktop/windows/runtime_window.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "runtime_window.h" - -#include - -namespace seb::userinterface::desktop::windows { - -RuntimeWindow::RuntimeWindow(QWidget *parent) : BaseWindow(parent) -{ - setWindowTitle(QStringLiteral("SEB Runtime")); - resize(640, 360); - - auto *layout = new QVBoxLayout(this); - statusLabel_ = new QLabel(QStringLiteral("Starting session..."), this); - progressBar_ = new QProgressBar(this); - logOutput_ = new QTextEdit(this); - - logOutput_->setReadOnly(true); - progressBar_->setRange(0, 100); - progressBar_->setValue(0); - - layout->addWidget(statusLabel_); - layout->addWidget(progressBar_); - layout->addWidget(logOutput_); -} - -void RuntimeWindow::show() -{ - BaseWindow::show(); -} - -void RuntimeWindow::hide() -{ - BaseWindow::hide(); -} - -void RuntimeWindow::close() -{ - BaseWindow::close(); -} - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/runtime_window.h b/src/userinterface/desktop/windows/runtime_window.h deleted file mode 100644 index a6edaac..0000000 --- a/src/userinterface/desktop/windows/runtime_window.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "../../contracts/windows/i_runtime_window.h" -#include "../viewmodels/runtime_window_view_model.h" -#include "base_window.h" - -#include -#include -#include - -namespace seb::userinterface::desktop::windows { - -class RuntimeWindow : public BaseWindow, public contracts::windows::IRuntimeWindow -{ -public: - explicit RuntimeWindow(QWidget *parent = nullptr); - - void show() override; - void hide() override; - void close() override; - -private: - viewmodels::RuntimeWindowViewModel viewModel_; - QLabel *statusLabel_ = nullptr; - QProgressBar *progressBar_ = nullptr; - QTextEdit *logOutput_ = nullptr; -}; - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/server_failure_dialog.cpp b/src/userinterface/desktop/windows/server_failure_dialog.cpp deleted file mode 100644 index f2f30c0..0000000 --- a/src/userinterface/desktop/windows/server_failure_dialog.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "server_failure_dialog.h" -#include -namespace seb::userinterface::desktop::windows { ServerFailureDialog::ServerFailureDialog(QWidget *parent) : parent_(parent) {} contracts::windows::data::ServerFailureDialogResult ServerFailureDialog::exec() { QDialog dialog(parent_); return dialog.exec() == QDialog::Accepted ? contracts::windows::data::ServerFailureDialogResult::Retry : contracts::windows::data::ServerFailureDialogResult::Quit; } } diff --git a/src/userinterface/desktop/windows/server_failure_dialog.h b/src/userinterface/desktop/windows/server_failure_dialog.h deleted file mode 100644 index 617a6bf..0000000 --- a/src/userinterface/desktop/windows/server_failure_dialog.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "../../contracts/windows/i_server_failure_dialog.h" -class QWidget; -namespace seb::userinterface::desktop::windows { class ServerFailureDialog : public contracts::windows::IServerFailureDialog { public: explicit ServerFailureDialog(QWidget *parent = nullptr); contracts::windows::data::ServerFailureDialogResult exec() override; private: QWidget *parent_ = nullptr; }; } diff --git a/src/userinterface/desktop/windows/splash_screen.cpp b/src/userinterface/desktop/windows/splash_screen.cpp deleted file mode 100644 index 46db9be..0000000 --- a/src/userinterface/desktop/windows/splash_screen.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "splash_screen.h" - -namespace seb::userinterface::desktop::windows { - -SplashScreen::SplashScreen(const QPixmap &pixmap) : QSplashScreen(pixmap) {} -void SplashScreen::close() { QSplashScreen::close(); } -void SplashScreen::hide() { QSplashScreen::hide(); } -void SplashScreen::show() { QSplashScreen::show(); } - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/splash_screen.h b/src/userinterface/desktop/windows/splash_screen.h deleted file mode 100644 index 78dea4a..0000000 --- a/src/userinterface/desktop/windows/splash_screen.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../contracts/windows/i_splash_screen.h" - -#include - -namespace seb::userinterface::desktop::windows { - -class SplashScreen : public QSplashScreen, public contracts::windows::ISplashScreen -{ -public: - explicit SplashScreen(const QPixmap &pixmap = QPixmap()); - void close() override; - void hide() override; - void show() override; -}; - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/taskbar_window.cpp b/src/userinterface/desktop/windows/taskbar_window.cpp deleted file mode 100644 index 2490883..0000000 --- a/src/userinterface/desktop/windows/taskbar_window.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "taskbar_window.h" -#include "../controls/taskbar/application_control.h" -#include "../controls/taskbar/audio_control.h" -#include "../controls/taskbar/network_control.h" -#include "../controls/taskbar/power_supply_control.h" -#include "../controls/taskbar/clock.h" -#include "../controls/taskbar/quit_button.h" -#include -namespace seb::userinterface::desktop::windows { TaskbarWindow::TaskbarWindow(QWidget *parent) : BaseWindow(parent) { auto *l = new QHBoxLayout(this); l->addWidget(new controls::taskbar::ApplicationControl(this)); l->addWidget(new controls::taskbar::PowerSupplyControl(this)); l->addWidget(new controls::taskbar::NetworkControl(this)); l->addWidget(new controls::taskbar::AudioControl(this)); l->addWidget(new controls::taskbar::Clock(this)); l->addWidget(new controls::taskbar::QuitButton(this)); } } diff --git a/src/userinterface/desktop/windows/taskbar_window.h b/src/userinterface/desktop/windows/taskbar_window.h deleted file mode 100644 index 5a917d7..0000000 --- a/src/userinterface/desktop/windows/taskbar_window.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "base_window.h" -namespace seb::userinterface::desktop::windows { class TaskbarWindow : public BaseWindow { Q_OBJECT public: explicit TaskbarWindow(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/windows/taskview.cpp b/src/userinterface/desktop/windows/taskview.cpp deleted file mode 100644 index 2de18f6..0000000 --- a/src/userinterface/desktop/windows/taskview.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "taskview.h" -#include "../controls/taskview/window_control.h" -#include -namespace seb::userinterface::desktop::windows { Taskview::Taskview(QWidget *parent) : BaseWindow(parent) { auto *l = new QVBoxLayout(this); l->addWidget(new controls::taskview::WindowControl(this)); } } diff --git a/src/userinterface/desktop/windows/taskview.h b/src/userinterface/desktop/windows/taskview.h deleted file mode 100644 index 6b86632..0000000 --- a/src/userinterface/desktop/windows/taskview.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -#include "base_window.h" -namespace seb::userinterface::desktop::windows { class Taskview : public BaseWindow { Q_OBJECT public: explicit Taskview(QWidget *parent = nullptr); }; } diff --git a/src/userinterface/desktop/windows/verificator_overlay.cpp b/src/userinterface/desktop/windows/verificator_overlay.cpp deleted file mode 100644 index 3c13df9..0000000 --- a/src/userinterface/desktop/windows/verificator_overlay.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "verificator_overlay.h" - -namespace seb::userinterface::desktop::windows { - -VerificatorOverlay::VerificatorOverlay(QWidget *parent) : BaseWindow(parent) {} - -void VerificatorOverlay::show() -{ - BaseWindow::show(); -} - -void VerificatorOverlay::hide() -{ - BaseWindow::hide(); -} - -void VerificatorOverlay::close() -{ - BaseWindow::close(); -} - -} // namespace seb::userinterface::desktop::windows diff --git a/src/userinterface/desktop/windows/verificator_overlay.h b/src/userinterface/desktop/windows/verificator_overlay.h deleted file mode 100644 index cacdc31..0000000 --- a/src/userinterface/desktop/windows/verificator_overlay.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "../../contracts/windows/i_verificator_overlay.h" -#include "base_window.h" - -namespace seb::userinterface::desktop::windows { - -class VerificatorOverlay : public BaseWindow, public contracts::windows::IVerificatorOverlay -{ -public: - explicit VerificatorOverlay(QWidget *parent = nullptr); - - void show() override; - void hide() override; - void close() override; -}; - -} // namespace seb::userinterface::desktop::windows