diff options
-rw-r--r-- | CMakeLists.txt | 59 | ||||
-rw-r--r-- | src/Makefile | 256 | ||||
-rw-r--r-- | src/main.cpp | 46 | ||||
-rw-r--r-- | src/slxbrowser.cpp | 115 | ||||
-rw-r--r-- | src/slxbrowser.h | 40 | ||||
-rw-r--r-- | src/webview.cpp | 18 | ||||
-rw-r--r-- | src/webview.h | 28 |
7 files changed, 562 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1f23b04 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,59 @@ +cmake_minimum_required(VERSION 3.1) + +# project name +project(slxbrowser) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_BUILD_TYPE Debug) +set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -Wall -Wextra -pedantic -Werror -Wno-multichar") +set(CMAKE_CXX_FLAGS_RELEASE "-O2 -Wno-multichar") + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) + +file(GLOB_RECURSE SLXBROWSER_SOURCES src/*.cpp) +#file(GLOB_RECURSE SLXBROWSER_MOC_HEADERS src/*.h) +#file(GLOB_RECURSE SLXBROWSER_UIS src/ui/*.ui) +#file(GLOB_RECURSE SLXBROWSER_RESOURCES src/*.qrc) + +#include_directories(${CMAKE_CURRENT_BINARY_DIR} ./) + +# +# Qt4 +# +find_package(Qt5WebKitWidgets) + +#if(Qt5_FOUND) +# message(STATUS "Qt5 found") +#else(Qt5_FOUND) +# message(FATAL_ERROR "Qt5 not found") +#endif(Qt5_FOUND) + +#set(QT_USE_QTXML TRUE) +#set(QT_USE_QTSVG TRUE) +#set(QT_USE_QTNETWORK TRUE) +#set(QT_USE_QTWEBKIT TRUE) + +#include(${QT_USE_FILE}) + +#QT4_ADD_RESOURCES(SLXBROWSER_RC_SOURCES ${SLXBROWSER_RESOURCES}) +#QT5_WRAP_UI(SLXBROWSER_UI_HEADERS ${SLXBROWSER_UIS}) +#QT5_WRAP_CPP(SLXBROWSER_MOC_SOURCES ${SLXBROWSER_MOC_HEADERS}) + +# +# build slxbrowser +# +add_executable(slxbrowser + ${SLXBROWSER_SOURCES} +# ${SLXBROWSER_MOC_SOURCES} +# ${SLXBROWSER_UI_HEADERS} +# ${SLXBROWSER_RC_SOURCES} +# ${SLXBROWSER_QMS} +) + +target_link_libraries(slxbrowser + Qt5::WebKitWidgets +) + +install(TARGETS slxbrowser RUNTIME DESTINATION bin) +install(DIRECTORY themes DESTINATION /usr/local/share/slxbrowser) diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..4fd1610 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,256 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Default target executed when no arguments are given to make. +default_target: all + +.PHONY : default_target + +# Allow only one "make -f Makefile2" at a time, but pass parallelism. +.NOTPARALLEL: + + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + + +# A target that is always out of date. +cmake_force: + +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/sr/dev/openslx/slxbrowser + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/sr/dev/openslx/slxbrowser/src + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target install +install: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install + +# Special rule for the target install +install/fast: preinstall/fast + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." + /usr/bin/cmake -P cmake_install.cmake +.PHONY : install/fast + +# Special rule for the target list_install_components +list_install_components: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" +.PHONY : list_install_components + +# Special rule for the target list_install_components +list_install_components/fast: list_install_components + +.PHONY : list_install_components/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache + +.PHONY : rebuild_cache/fast + +# Special rule for the target install/strip +install/strip: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." + /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake +.PHONY : install/strip + +# Special rule for the target install/strip +install/strip/fast: install/strip + +.PHONY : install/strip/fast + +# Special rule for the target install/local +install/local: preinstall + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." + /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake +.PHONY : install/local + +# Special rule for the target install/local +install/local/fast: install/local + +.PHONY : install/local/fast + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..." + /usr/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache + +.PHONY : edit_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/sr/dev/openslx/slxbrowser/src/CMakeFiles /home/sr/dev/openslx/slxbrowser/src/CMakeFiles/progress.marks + $(MAKE) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /home/sr/dev/openslx/slxbrowser/src/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + $(MAKE) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean + +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named slxbrowser + +# Build rule for target. +slxbrowser: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 slxbrowser +.PHONY : slxbrowser + +# fast build rule for target. +slxbrowser/fast: + $(MAKE) -f CMakeFiles/slxbrowser.dir/build.make CMakeFiles/slxbrowser.dir/build +.PHONY : slxbrowser/fast + +CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.o: CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.o + +.PHONY : CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.o + +# target to build an object file +CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.o: + $(MAKE) -f CMakeFiles/slxbrowser.dir/build.make CMakeFiles/slxbrowser.dir/CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.o +.PHONY : CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.o + +CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.i: CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.i + +.PHONY : CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.i + +# target to preprocess a source file +CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.i: + $(MAKE) -f CMakeFiles/slxbrowser.dir/build.make CMakeFiles/slxbrowser.dir/CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.i +.PHONY : CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.i + +CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.s: CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.s + +.PHONY : CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.s + +# target to generate assembly for a file +CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.s: + $(MAKE) -f CMakeFiles/slxbrowser.dir/build.make CMakeFiles/slxbrowser.dir/CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.s +.PHONY : CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp.s + +main.o: main.cpp.o + +.PHONY : main.o + +# target to build an object file +main.cpp.o: + $(MAKE) -f CMakeFiles/slxbrowser.dir/build.make CMakeFiles/slxbrowser.dir/main.cpp.o +.PHONY : main.cpp.o + +main.i: main.cpp.i + +.PHONY : main.i + +# target to preprocess a source file +main.cpp.i: + $(MAKE) -f CMakeFiles/slxbrowser.dir/build.make CMakeFiles/slxbrowser.dir/main.cpp.i +.PHONY : main.cpp.i + +main.s: main.cpp.s + +.PHONY : main.s + +# target to generate assembly for a file +main.cpp.s: + $(MAKE) -f CMakeFiles/slxbrowser.dir/build.make CMakeFiles/slxbrowser.dir/main.cpp.s +.PHONY : main.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... install" + @echo "... list_install_components" + @echo "... rebuild_cache" + @echo "... slxbrowser" + @echo "... install/strip" + @echo "... install/local" + @echo "... edit_cache" + @echo "... CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.o" + @echo "... CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.i" + @echo "... CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.s" + @echo "... main.o" + @echo "... main.i" + @echo "... main.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..6c53756 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,46 @@ +#include "slxbrowser.h" +#include <QMessageBox> +#include <QApplication> +#include <QKeyEvent> +#include <QCommandLineParser> + +class KeyHandler : public QObject +{ +public: + bool eventFilter(QObject *obj, QEvent *event) + { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); + if ( keyEvent->key() == Qt::Key_Q && (keyEvent->modifiers() & Qt::ControlModifier)) + exit(0); + } + return QObject::eventFilter(obj, event); + } +}; + +/** + * MAIN + */ +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + QCommandLineParser parser; + parser.addHelpOption(); + parser.addPositionalArgument("url", "URL to load"); + QCommandLineOption ignoreSsl("insecure", "Ignore SSL errors"); + QCommandLineOption fullscreen("full-screen", "Run browser in full screen"); + parser.addOption(ignoreSsl); + parser.addOption(fullscreen); + parser.process(app); + QStringList list(parser.positionalArguments()); + if (list.empty()) { + QMessageBox::critical(NULL, "Error", "Need one argument: file name"); + return 1; + } + QString url(list[0]); + SLXbrowser main(url, parser.isSet(fullscreen), parser.isSet(ignoreSsl)); + main.show(); + app.installEventFilter(new KeyHandler()); + app.exec(); + return 0; +} diff --git a/src/slxbrowser.cpp b/src/slxbrowser.cpp new file mode 100644 index 0000000..aec5201 --- /dev/null +++ b/src/slxbrowser.cpp @@ -0,0 +1,115 @@ +#include "slxbrowser.h" +#include "webview.h" +#include <QtWebKitWidgets> +#include <QWebPage> +#include <QNetworkReply> +#include <QSslConfiguration> +#include <QProgressBar> + +SLXbrowser::SLXbrowser(QString url, bool fullscreen, bool ignoreSslErrors) + : QMainWindow(NULL), + _url(url), + _ignoreSslErrors(ignoreSslErrors) +{ + if (fullscreen) { + this->showFullScreen(); + this->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); + } + //QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + QWidget *w = new QWidget; + QLayout *l = new QVBoxLayout; + _browser = new WebView; + _progress = new QProgressBar; + _progress->hide(); + l->addWidget(_browser); + l->addWidget(_progress); + l->setMargin(0); + l->setSpacing(0); + l->setContentsMargins(0,0,0,0); + w->setContentsMargins(0,0,0,0); + w->setLayout(l); + this->setCentralWidget(w); + + _reset.setSingleShot(true); + connect(&_reset, SIGNAL(timeout()), this, SLOT(reloadInitial())); + + connect(_browser, SIGNAL(loadStarted()), this, SLOT(loadStarted())); + connect(_browser, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool))); + connect(_browser, SIGNAL(loadProgress(int)), this, SLOT(loadProgress(int))); + // + QWebPage *page = _browser->page(); + QNetworkAccessManager *nam = new QNetworkAccessManager(this); + connect(nam, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), + this, SLOT(sslErrors(QNetworkReply*, const QList<QSslError>&))); + connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*))); + page->setNetworkAccessManager(nam); + page->mainFrame()->load(url); + // + _browser->show(); +} + +SLXbrowser::~SLXbrowser() +{ +} + +void SLXbrowser::loadStarted() +{ + _reset.stop(); + _normalError.clear(); + _sslErrors.clear(); + _progress->setValue(0); + _progress->show(); +} + +void SLXbrowser::loadFinished(bool ok) +{ + _progress->hide(); + if (!ok) { + _browser->page()->mainFrame()->setHtml("<html><body style='background:blue;color:white'><br><br><center><h1>Network Access Error</h1><pre id='content'></pre></body></html>"); + QWebElement el = _browser->page()->mainFrame()->documentElement().findFirst("#content"); + QString str; + if (!_sslErrors.empty()) { + str.append("SSL Errors:\n"); + for (QSslError err : _sslErrors) { + str.append(err.errorString()); + str.append('\n'); + } + } else if (_normalError.length() != 0) { + str.append("Load Error:\n"); + str.append(_normalError); + } else { + str.append("Unknown Error"); + } + str.append("\n\n\n\n" + QDateTime::currentDateTime().toString()); + el.setPlainText(str); + _sslErrors.clear(); + _normalError.clear(); + _reset.start(30000); + } +} + +void SLXbrowser::loadProgress(int progress) +{ + _progress->setValue(progress); +} + +void SLXbrowser::sslErrors(QNetworkReply* reply, const QList<QSslError>& errors) +{ + if (_ignoreSslErrors) { + reply->ignoreSslErrors(); + return; + } + _sslErrors.append(errors); +} + +void SLXbrowser::requestFinished(QNetworkReply *reply) +{ + if (reply->error() != QNetworkReply::NoError) { + _normalError = reply->errorString(); + } +} + +void SLXbrowser::reloadInitial() +{ + _browser->page()->mainFrame()->load(_url); +} diff --git a/src/slxbrowser.h b/src/slxbrowser.h new file mode 100644 index 0000000..fbd4c4a --- /dev/null +++ b/src/slxbrowser.h @@ -0,0 +1,40 @@ +#ifndef SLXBROWSER_H_ +#define SLXBROWSER_H_ + +#include <QMainWindow> +#include <QList> +#include <QSslError> +#include <QTimer> + +class QNetworkReply; +class QWebView; +class QProgressBar; +class QNetworkReply; + +class SLXbrowser : public QMainWindow +{ + Q_OBJECT +public: + SLXbrowser(QString url, bool fullscreen, bool ignoreSslErrors); + virtual ~SLXbrowser(); + +private slots: + void loadStarted(); + void loadFinished(bool ok); + void loadProgress(int progress); + void sslErrors(QNetworkReply * reply, const QList<QSslError> & errors); + void requestFinished(QNetworkReply *reply); + void reloadInitial(); + +private: + QString _url; + bool _ignoreSslErrors; + QWebView *_browser; + QProgressBar *_progress; + QTimer _reset; + QList<QSslError> _sslErrors; + QString _normalError; +}; + +#endif /* SLXBROWSER_H_ */ + diff --git a/src/webview.cpp b/src/webview.cpp new file mode 100644 index 0000000..aa9c650 --- /dev/null +++ b/src/webview.cpp @@ -0,0 +1,18 @@ +#include "webview.h" +#include <QWebFrame> + +void WebView::windowCloseRequested() +{ + // If we have an old URL stored on the stack, navigate back to it, otherwise we return and nothing happens + if (_urls.empty()) + return; + QUrl url = _urls.pop(); + page()->mainFrame()->load(url); +} + +QWebView* WebView::createWindow(QWebPage::WebWindowType) +{ + // Remember current URL, then return the current Web View so no new window opens + _urls.push(this->url()); + return this; +} diff --git a/src/webview.h b/src/webview.h new file mode 100644 index 0000000..753c984 --- /dev/null +++ b/src/webview.h @@ -0,0 +1,28 @@ +#ifndef WEBVIEW_H_ +#define WEBVIEW_H_ + +#include <QStack> +#include <QWebView> + +/** + * Make sure pages that want to load in a new tab are actually loaded in the same page, + * and remember the previous URL in case the "new tab" requests to be closed. + */ +class WebView : public QWebView +{ + Q_OBJECT +public: + WebView(QWidget* parent = NULL) : QWebView(parent) { + connect(page(), SIGNAL(windowCloseRequested()), this, SLOT(windowCloseRequested())); + } +protected: + QWebView *createWindow(QWebPage::WebWindowType); + +protected slots: + void windowCloseRequested(); + +private: + QStack<QUrl> _urls; +}; + +#endif |