forked from qt-creator/qt-creator
Use qlitehtml from separate repository
qlitehtml moved into its own playground repository, get it from there instead of carrying our copy around. Change-Id: I0e267344e5ccf95f579e4fb239e6789d177d7b78 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -6,9 +6,9 @@
|
||||
path = src/tools/perfparser
|
||||
url = ../perfparser.git
|
||||
ignore = dirty
|
||||
[submodule "litehtml"]
|
||||
path = src/plugins/help/qlitehtml/litehtml
|
||||
url = https://github.com/litehtml/litehtml.git
|
||||
[submodule "googletest"]
|
||||
path = tests/unit/unittest/3rdparty/googletest
|
||||
url = https://github.com/google/googletest.git
|
||||
[submodule "src/libs/qlitehtml"]
|
||||
path = src/libs/qlitehtml
|
||||
url = https://code.qt.io/playground/qlitehtml.git
|
||||
|
@ -18,3 +18,31 @@ add_subdirectory(clangsupport)
|
||||
add_subdirectory(tracing)
|
||||
|
||||
add_subdirectory(qtcreatorcdbext)
|
||||
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/qlitehtml/src/CMakeLists.txt)
|
||||
option(BUILD_LIBRARY_QLITEHTML "Build library qlitehtml." ${BUILD_LIBRARIES_BY_DEFAULT})
|
||||
set(QLITEHTML_VERSION_COMPAT ${IDE_VERSION_COMPAT} CACHE STRING "")
|
||||
if(BUILD_LIBRARY_QLITEHTML)
|
||||
set(QLITEHTML_BIN_PATH ${IDE_BIN_PATH})
|
||||
set(QLITEHTML_LIBRARY_PATH ${IDE_LIBRARY_PATH})
|
||||
set(QLITEHTML_EXPORT QtCreator)
|
||||
set(QLITEHTML_DEVEL_COMPONENT Devel)
|
||||
set(QLITEHTML_DEVEL_EXCLUDE_FROM_ALL ON)
|
||||
set(QLITEHTML_HEADER_PATH "include/src/lib/qlitehtml")
|
||||
add_subdirectory(qlitehtml/src)
|
||||
endif()
|
||||
if(TARGET qlitehtml)
|
||||
target_compile_definitions(qlitehtml PRIVATE ${DEFAULT_DEFINES}) # for precompiled headers
|
||||
enable_pch(qlitehtml)
|
||||
#doesn't work: TARGET 'qlitehtml' was not created in this directory.
|
||||
#qtc_enable_separate_debug_info(qlitehtml "${IDE_LIBRARY_PATH}")
|
||||
qtc_output_binary_dir(_output_binary_dir)
|
||||
set_target_properties(qlitehtml PROPERTIES
|
||||
BUILD_RPATH "${_LIB_RPATH}"
|
||||
INSTALL_RPATH "${_LIB_RPATH}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${IDE_BIN_PATH}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${_output_binary_dir}/${IDE_LIBRARY_PATH}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${_output_binary_dir}/${IDE_LIBRARY_PATH}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -1,7 +1,10 @@
|
||||
import qbs
|
||||
import qbs.File
|
||||
|
||||
Project {
|
||||
name: "Libs"
|
||||
property string qlitehtmlQbs: path + "/qlitehtml/src/qlitehtml.qbs"
|
||||
property stringList qlitehtml: File.exists(qlitehtmlQbs) ? [qlitehtmlQbs] : []
|
||||
references: [
|
||||
"advanceddockingsystem/advanceddockingsystem.qbs",
|
||||
"aggregation/aggregation.qbs",
|
||||
@ -24,5 +27,5 @@ Project {
|
||||
"utils/utils.qbs",
|
||||
"3rdparty/syntax-highlighting/syntax-highlighting.qbs",
|
||||
"3rdparty/yaml-cpp/yaml-cpp.qbs",
|
||||
].concat(project.additionalLibs)
|
||||
].concat(qlitehtml).concat(project.additionalLibs)
|
||||
}
|
||||
|
1
src/libs/qlitehtml
Submodule
1
src/libs/qlitehtml
Submodule
Submodule src/libs/qlitehtml added at 3bccbb86ee
@ -60,11 +60,8 @@ extend_qtc_plugin(Help
|
||||
webenginehelpviewer.h
|
||||
)
|
||||
|
||||
find_package(litehtml QUIET)
|
||||
add_subdirectory(qlitehtml)
|
||||
|
||||
extend_qtc_plugin(Help
|
||||
CONDITION TARGET litehtml AND TARGET qlitehtml
|
||||
CONDITION TARGET qlitehtml
|
||||
FEATURE_INFO "litehtml help viewer"
|
||||
DEPENDS qlitehtml
|
||||
DEFINES QTC_LITEHTML_HELPVIEWER
|
||||
|
@ -75,11 +75,14 @@ osx {
|
||||
}
|
||||
}
|
||||
|
||||
exists($$PWD/qlitehtml/litehtml/CMakeLists.txt)|!isEmpty(LITEHTML_INSTALL_DIR) {
|
||||
include(qlitehtml/qlitehtml.pri)
|
||||
HEADERS += litehtmlhelpviewer.h
|
||||
SOURCES += litehtmlhelpviewer.cpp
|
||||
DEFINES += QTC_LITEHTML_HELPVIEWER
|
||||
QLITEHTML_DIR = $$PWD/../../libs/qlitehtml
|
||||
exists($$QLITEHTML_DIR/src/qlitehtml.pri) {
|
||||
exists($$QLITEHTML_DIR/src/3rdparty/litehtml/CMakeLists.txt)|!isEmpty(LITEHTML_INSTALL_DIR) {
|
||||
include($$QLITEHTML_DIR/src/qlitehtml.pri)
|
||||
HEADERS += litehtmlhelpviewer.h
|
||||
SOURCES += litehtmlhelpviewer.cpp
|
||||
DEFINES += QTC_LITEHTML_HELPVIEWER
|
||||
}
|
||||
}
|
||||
|
||||
RESOURCES += help.qrc
|
||||
|
@ -3,8 +3,6 @@ import qbs.Utilities
|
||||
Project {
|
||||
name: "Help"
|
||||
|
||||
references: "qlitehtml"
|
||||
|
||||
QtcPlugin {
|
||||
name: "Help"
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
find_package(litehtml QUIET)
|
||||
if(NOT TARGET litehtml AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/litehtml/CMakeLists.txt)
|
||||
set(ORIG_FPIC ${CMAKE_POSITION_INDEPENDENT_CODE})
|
||||
if (WIN32)
|
||||
set(LITEHTML_UTF8 ON CACHE BOOL "")
|
||||
endif()
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_subdirectory(litehtml EXCLUDE_FROM_ALL)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE "${ORIG_FPIC}")
|
||||
# force optimized litehtml even in debug
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
# except for windows
|
||||
if (NOT WIN32)
|
||||
target_compile_options(gumbo PRIVATE -O2)
|
||||
target_compile_options(litehtml PRIVATE -O2)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_qtc_library(qlitehtml
|
||||
CONDITION TARGET litehtml
|
||||
PUBLIC_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
DEPENDS Qt5::Widgets litehtml
|
||||
PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
SOURCES
|
||||
container_qpainter.cpp container_qpainter.h container_qpainter_p.h
|
||||
qlitehtml_global.h
|
||||
qlitehtmlwidget.cpp qlitehtmlwidget.h
|
||||
)
|
@ -1,24 +0,0 @@
|
||||
# Qt backend for litehtml
|
||||
|
||||
Provides
|
||||
|
||||
* A QPainter based rendering backend for the light-weight HTML/CSS rendering engine [litehtml].
|
||||
* A QWidget that uses the QPainter based backend and provides API for simply setting the HTML text
|
||||
and a base URL plus hook that are used for requesting referenced resources.
|
||||
|
||||
## How to build
|
||||
|
||||
Build and install [litehtml]. It is recommended to build [litehtml] in release mode
|
||||
|
||||
```
|
||||
cd litehtml
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$PWD/../install" -DCMAKE_BUILD_TYPE=Release -G Ninja ..
|
||||
cmake --build .
|
||||
cmake --install .
|
||||
```
|
||||
|
||||
Add the [litehtml] installation path to the `CMAKE_PREFIX_PATH` when building the Qt backend
|
||||
|
||||
[litehtml]: https://github.com/litehtml/litehtml
|
File diff suppressed because it is too large
Load Diff
@ -1,124 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of QLiteHtml.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qlitehtml_global.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QPaintDevice>
|
||||
#include <QPainter>
|
||||
#include <QPoint>
|
||||
#include <QRect>
|
||||
#include <QString>
|
||||
#include <QTextDocument>
|
||||
#include <QUrl>
|
||||
#include <QVector>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
class DocumentContainerPrivate;
|
||||
class DocumentContainerContextPrivate;
|
||||
|
||||
class QLITEHTML_EXPORT DocumentContainerContext
|
||||
{
|
||||
public:
|
||||
DocumentContainerContext();
|
||||
~DocumentContainerContext();
|
||||
|
||||
void setMasterStyleSheet(const QString &css);
|
||||
|
||||
private:
|
||||
std::unique_ptr<DocumentContainerContextPrivate> d;
|
||||
|
||||
friend class DocumentContainer;
|
||||
friend class DocumentContainerPrivate;
|
||||
};
|
||||
|
||||
class QLITEHTML_EXPORT DocumentContainer
|
||||
{
|
||||
public:
|
||||
DocumentContainer();
|
||||
virtual ~DocumentContainer();
|
||||
|
||||
public: // outside API
|
||||
void setPaintDevice(QPaintDevice *paintDevice);
|
||||
void setDocument(const QByteArray &data, DocumentContainerContext *context);
|
||||
bool hasDocument() const;
|
||||
void setBaseUrl(const QString &url);
|
||||
void setScrollPosition(const QPoint &pos);
|
||||
void render(int width, int height);
|
||||
void draw(QPainter *painter, const QRect &clip);
|
||||
int documentWidth() const;
|
||||
int documentHeight() const;
|
||||
int anchorY(const QString &anchorName) const;
|
||||
|
||||
// these return areas to redraw in document space
|
||||
QVector<QRect> mousePressEvent(const QPoint &documentPos,
|
||||
const QPoint &viewportPos,
|
||||
Qt::MouseButton button);
|
||||
QVector<QRect> mouseMoveEvent(const QPoint &documentPos, const QPoint &viewportPos);
|
||||
QVector<QRect> mouseReleaseEvent(const QPoint &documentPos,
|
||||
const QPoint &viewportPos,
|
||||
Qt::MouseButton button);
|
||||
QVector<QRect> mouseDoubleClickEvent(const QPoint &documentPos,
|
||||
const QPoint &viewportPos,
|
||||
Qt::MouseButton button);
|
||||
QVector<QRect> leaveEvent();
|
||||
|
||||
QUrl linkAt(const QPoint &documentPos, const QPoint &viewportPos);
|
||||
|
||||
QString caption() const;
|
||||
QString selectedText() const;
|
||||
|
||||
void findText(const QString &text,
|
||||
QTextDocument::FindFlags flags,
|
||||
bool incremental,
|
||||
bool *wrapped,
|
||||
bool *success,
|
||||
QVector<QRect> *oldSelection,
|
||||
QVector<QRect> *newSelection);
|
||||
|
||||
void setDefaultFont(const QFont &font);
|
||||
QFont defaultFont() const;
|
||||
|
||||
using DataCallback = std::function<QByteArray(QUrl)>;
|
||||
void setDataCallback(const DataCallback &callback);
|
||||
|
||||
using CursorCallback = std::function<void(QCursor)>;
|
||||
void setCursorCallback(const CursorCallback &callback);
|
||||
|
||||
using LinkCallback = std::function<void(QUrl)>;
|
||||
void setLinkCallback(const LinkCallback &callback);
|
||||
|
||||
using PaletteCallback = std::function<QPalette()>;
|
||||
void setPaletteCallback(const PaletteCallback &callback);
|
||||
|
||||
int withFixedElementPosition(int y, const std::function<void()> &action);
|
||||
|
||||
private:
|
||||
std::unique_ptr<DocumentContainerPrivate> d;
|
||||
};
|
@ -1,163 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of QLiteHtml.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "container_qpainter.h"
|
||||
|
||||
#include <litehtml.h>
|
||||
|
||||
#include <QPaintDevice>
|
||||
#include <QPixmap>
|
||||
#include <QPoint>
|
||||
#include <QRect>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
class Selection
|
||||
{
|
||||
public:
|
||||
struct Element
|
||||
{
|
||||
litehtml::element::ptr element;
|
||||
int index = -1;
|
||||
int x = -1;
|
||||
};
|
||||
|
||||
enum class Mode { Free, Word };
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
void update();
|
||||
QRect boundingRect() const;
|
||||
|
||||
Element startElem;
|
||||
Element endElem;
|
||||
QVector<QRect> selection;
|
||||
QString text;
|
||||
|
||||
QPoint selectionStartDocumentPos;
|
||||
Mode mode = Mode::Free;
|
||||
bool isSelecting = false;
|
||||
};
|
||||
|
||||
struct Index
|
||||
{
|
||||
QString text;
|
||||
// only contains leaf elements
|
||||
std::unordered_map<litehtml::element::ptr, int> elementToIndex;
|
||||
|
||||
using Entry = std::pair<int, litehtml::element::ptr>;
|
||||
std::vector<Entry> indexToElement;
|
||||
|
||||
Entry findElement(int index) const;
|
||||
};
|
||||
|
||||
class DocumentContainerPrivate : public litehtml::document_container
|
||||
{
|
||||
public: // document_container API
|
||||
litehtml::uint_ptr create_font(const litehtml::tchar_t *faceName,
|
||||
int size,
|
||||
int weight,
|
||||
litehtml::font_style italic,
|
||||
unsigned int decoration,
|
||||
litehtml::font_metrics *fm) override;
|
||||
void delete_font(litehtml::uint_ptr hFont) override;
|
||||
int text_width(const litehtml::tchar_t *text, litehtml::uint_ptr hFont) override;
|
||||
void draw_text(litehtml::uint_ptr hdc,
|
||||
const litehtml::tchar_t *text,
|
||||
litehtml::uint_ptr hFont,
|
||||
litehtml::web_color color,
|
||||
const litehtml::position &pos) override;
|
||||
int pt_to_px(int pt) override;
|
||||
int get_default_font_size() const override;
|
||||
const litehtml::tchar_t *get_default_font_name() const override;
|
||||
void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker &marker) override;
|
||||
void load_image(const litehtml::tchar_t *src,
|
||||
const litehtml::tchar_t *baseurl,
|
||||
bool redraw_on_ready) override;
|
||||
void get_image_size(const litehtml::tchar_t *src,
|
||||
const litehtml::tchar_t *baseurl,
|
||||
litehtml::size &sz) override;
|
||||
void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint &bg) override;
|
||||
void draw_borders(litehtml::uint_ptr hdc,
|
||||
const litehtml::borders &borders,
|
||||
const litehtml::position &draw_pos,
|
||||
bool root) override;
|
||||
void set_caption(const litehtml::tchar_t *caption) override;
|
||||
void set_base_url(const litehtml::tchar_t *base_url) override;
|
||||
void link(const std::shared_ptr<litehtml::document> &doc,
|
||||
const litehtml::element::ptr &el) override;
|
||||
void on_anchor_click(const litehtml::tchar_t *url, const litehtml::element::ptr &el) override;
|
||||
void set_cursor(const litehtml::tchar_t *cursor) override;
|
||||
void transform_text(litehtml::tstring &text, litehtml::text_transform tt) override;
|
||||
void import_css(litehtml::tstring &text,
|
||||
const litehtml::tstring &url,
|
||||
litehtml::tstring &baseurl) override;
|
||||
void set_clip(const litehtml::position &pos,
|
||||
const litehtml::border_radiuses &bdr_radius,
|
||||
bool valid_x,
|
||||
bool valid_y) override;
|
||||
void del_clip() override;
|
||||
void get_client_rect(litehtml::position &client) const override;
|
||||
std::shared_ptr<litehtml::element> create_element(const litehtml::tchar_t *tag_name,
|
||||
const litehtml::string_map &attributes,
|
||||
const std::shared_ptr<litehtml::document> &doc) override;
|
||||
void get_media_features(litehtml::media_features &media) const override;
|
||||
void get_language(litehtml::tstring &language, litehtml::tstring &culture) const override;
|
||||
|
||||
QPixmap getPixmap(const QString &imageUrl, const QString &baseUrl);
|
||||
QString serifFont() const;
|
||||
QString sansSerifFont() const;
|
||||
QString monospaceFont() const;
|
||||
QUrl resolveUrl(const QString &url, const QString &baseUrl) const;
|
||||
void drawSelection(QPainter *painter, const QRect &clip) const;
|
||||
void buildIndex();
|
||||
|
||||
QPaintDevice *m_paintDevice = nullptr;
|
||||
litehtml::document::ptr m_document;
|
||||
Index m_index;
|
||||
QString m_baseUrl;
|
||||
QRect m_clientRect;
|
||||
QPoint m_scrollPosition;
|
||||
QString m_caption;
|
||||
QFont m_defaultFont = QFont(sansSerifFont(), 16);
|
||||
QByteArray m_defaultFontFamilyName = m_defaultFont.family().toUtf8();
|
||||
QHash<QUrl, QPixmap> m_pixmaps;
|
||||
Selection m_selection;
|
||||
DocumentContainer::DataCallback m_dataCallback;
|
||||
DocumentContainer::CursorCallback m_cursorCallback;
|
||||
DocumentContainer::LinkCallback m_linkCallback;
|
||||
DocumentContainer::PaletteCallback m_paletteCallback;
|
||||
bool m_blockLinks = false;
|
||||
};
|
||||
|
||||
class DocumentContainerContextPrivate
|
||||
{
|
||||
public:
|
||||
litehtml::context context;
|
||||
};
|
Submodule src/plugins/help/qlitehtml/litehtml deleted from db7f59d588
@ -1,164 +0,0 @@
|
||||
exists($$PWD/litehtml/CMakeLists.txt) {
|
||||
LH_SRC = $$PWD/litehtml
|
||||
LH_HDR = $$LH_SRC/include/litehtml
|
||||
GB_SRC = $$PWD/litehtml/src/gumbo
|
||||
GB_HDR = $$GB_SRC/include/gumbo
|
||||
|
||||
# gumbo
|
||||
SOURCES += \
|
||||
$$GB_SRC/attribute.c \
|
||||
$$GB_SRC/char_ref.c \
|
||||
$$GB_SRC/error.c \
|
||||
$$GB_SRC/parser.c \
|
||||
$$GB_SRC/string_buffer.c \
|
||||
$$GB_SRC/string_piece.c \
|
||||
$$GB_SRC/tag.c \
|
||||
$$GB_SRC/tokenizer.c \
|
||||
$$GB_SRC/utf8.c \
|
||||
$$GB_SRC/util.c \
|
||||
$$GB_SRC/vector.c
|
||||
|
||||
HEADERS += \
|
||||
$$GB_SRC/include//gumbo.h \
|
||||
$$GB_HDR/attribute.h \
|
||||
$$GB_HDR/char_ref.h \
|
||||
$$GB_HDR/error.h \
|
||||
$$GB_HDR/insertion_mode.h \
|
||||
$$GB_HDR/parser.h \
|
||||
$$GB_HDR/string_buffer.h \
|
||||
$$GB_HDR/string_piece.h \
|
||||
$$GB_HDR/tag_enum.h \
|
||||
$$GB_HDR/tag_gperf.h \
|
||||
$$GB_HDR/tag_sizes.h \
|
||||
$$GB_HDR/tag_strings.h \
|
||||
$$GB_HDR/token_type.h \
|
||||
$$GB_HDR/tokenizer.h \
|
||||
$$GB_HDR/tokenizer_states.h \
|
||||
$$GB_HDR/utf8.h \
|
||||
$$GB_HDR/util.h \
|
||||
$$GB_HDR/vector.h
|
||||
|
||||
INCLUDEPATH *= $$GB_SRC/include $$GB_HDR
|
||||
|
||||
win32 {
|
||||
HEADERS += \
|
||||
$$GB_SRC/visualc/include/strings.h
|
||||
INCLUDEPATH *= $$GB_SRC/visualc/include
|
||||
}
|
||||
|
||||
# litehtml
|
||||
SOURCES += \
|
||||
$$LH_SRC/src/background.cpp \
|
||||
$$LH_SRC/src/box.cpp \
|
||||
$$LH_SRC/src/context.cpp \
|
||||
$$LH_SRC/src/css_length.cpp \
|
||||
$$LH_SRC/src/css_selector.cpp \
|
||||
$$LH_SRC/src/document.cpp \
|
||||
$$LH_SRC/src/el_anchor.cpp \
|
||||
$$LH_SRC/src/el_base.cpp \
|
||||
$$LH_SRC/src/el_before_after.cpp \
|
||||
$$LH_SRC/src/el_body.cpp \
|
||||
$$LH_SRC/src/el_break.cpp \
|
||||
$$LH_SRC/src/el_cdata.cpp \
|
||||
$$LH_SRC/src/el_comment.cpp \
|
||||
$$LH_SRC/src/el_div.cpp \
|
||||
$$LH_SRC/src/element.cpp \
|
||||
$$LH_SRC/src/el_font.cpp \
|
||||
$$LH_SRC/src/el_image.cpp \
|
||||
$$LH_SRC/src/el_li.cpp \
|
||||
$$LH_SRC/src/el_link.cpp \
|
||||
$$LH_SRC/src/el_para.cpp \
|
||||
$$LH_SRC/src/el_script.cpp \
|
||||
$$LH_SRC/src/el_space.cpp \
|
||||
$$LH_SRC/src/el_style.cpp \
|
||||
$$LH_SRC/src/el_table.cpp \
|
||||
$$LH_SRC/src/el_td.cpp \
|
||||
$$LH_SRC/src/el_text.cpp \
|
||||
$$LH_SRC/src/el_title.cpp \
|
||||
$$LH_SRC/src/el_tr.cpp \
|
||||
$$LH_SRC/src/html.cpp \
|
||||
$$LH_SRC/src/html_tag.cpp \
|
||||
$$LH_SRC/src/iterators.cpp \
|
||||
$$LH_SRC/src/media_query.cpp \
|
||||
$$LH_SRC/src/num_cvt.cpp \
|
||||
$$LH_SRC/src/style.cpp \
|
||||
$$LH_SRC/src/stylesheet.cpp \
|
||||
$$LH_SRC/src/table.cpp \
|
||||
$$LH_SRC/src/utf8_strings.cpp \
|
||||
$$LH_SRC/src/web_color.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$LH_SRC/include/litehtml.h \
|
||||
$$LH_HDR/attributes.h \
|
||||
$$LH_HDR/background.h \
|
||||
$$LH_HDR/borders.h \
|
||||
$$LH_HDR/box.h \
|
||||
$$LH_HDR/context.h \
|
||||
$$LH_HDR/css_length.h \
|
||||
$$LH_HDR/css_margins.h \
|
||||
$$LH_HDR/css_offsets.h \
|
||||
$$LH_HDR/css_position.h \
|
||||
$$LH_HDR/css_selector.h \
|
||||
$$LH_HDR/document.h \
|
||||
$$LH_HDR/el_anchor.h \
|
||||
$$LH_HDR/el_base.h \
|
||||
$$LH_HDR/el_before_after.h \
|
||||
$$LH_HDR/el_body.h \
|
||||
$$LH_HDR/el_break.h \
|
||||
$$LH_HDR/el_cdata.h \
|
||||
$$LH_HDR/el_comment.h \
|
||||
$$LH_HDR/el_div.h \
|
||||
$$LH_HDR/el_font.h \
|
||||
$$LH_HDR/el_image.h \
|
||||
$$LH_HDR/el_li.h \
|
||||
$$LH_HDR/el_link.h \
|
||||
$$LH_HDR/el_para.h \
|
||||
$$LH_HDR/el_script.h \
|
||||
$$LH_HDR/el_space.h \
|
||||
$$LH_HDR/el_style.h \
|
||||
$$LH_HDR/el_table.h \
|
||||
$$LH_HDR/el_td.h \
|
||||
$$LH_HDR/el_text.h \
|
||||
$$LH_HDR/el_title.h \
|
||||
$$LH_HDR/el_tr.h \
|
||||
$$LH_HDR/element.h \
|
||||
$$LH_HDR/html.h \
|
||||
$$LH_HDR/html_tag.h \
|
||||
$$LH_HDR/iterators.h \
|
||||
$$LH_HDR/media_query.h \
|
||||
$$LH_HDR/num_cvt.h \
|
||||
$$LH_HDR/os_types.h \
|
||||
$$LH_HDR/style.h \
|
||||
$$LH_HDR/stylesheet.h \
|
||||
$$LH_HDR/table.h \
|
||||
$$LH_HDR/types.h \
|
||||
$$LH_HDR/utf8_strings.h \
|
||||
$$LH_HDR/web_color.h
|
||||
|
||||
INCLUDEPATH *= $$LH_SRC/include $$LH_HDR
|
||||
|
||||
# litehtml without optimization is not fun
|
||||
QMAKE_CFLAGS_DEBUG += -O2
|
||||
QMAKE_CXXFLAGS_DEBUG += -O2
|
||||
} else {
|
||||
INCLUDEPATH *= $$LITEHTML_INSTALL_DIR/include $$LITEHTML_INSTALL_DIR/include/litehtml
|
||||
LITEHTML_LIB_DIR = $$LITEHTML_INSTALL_DIR/lib
|
||||
LIBS += -L$$LITEHTML_LIB_DIR -llitehtml -lgumbo
|
||||
|
||||
win32: PRE_TARGETDEPS += $$LITEHTML_LIB_DIR/litehtml.lib $$LITEHTML_LIB_DIR/gumbo.lib
|
||||
else:unix: PRE_TARGETDEPS += $$LITEHTML_LIB_DIR/liblitehtml.a $$LITEHTML_LIB_DIR/libgumbo.a
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/container_qpainter.h \
|
||||
$$PWD/container_qpainter_p.h \
|
||||
$$PWD/qlitehtmlwidget.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/container_qpainter.cpp \
|
||||
$$PWD/qlitehtmlwidget.cpp
|
||||
|
||||
INCLUDEPATH *= $$PWD
|
||||
win32: DEFINES += LITEHTML_UTF8
|
||||
|
||||
DEFINES *= QLITEHTML_STATIC_LIBRARY
|
@ -1,216 +0,0 @@
|
||||
import qbs.File
|
||||
import qbs.FileInfo
|
||||
|
||||
Product {
|
||||
type: buildLib ? ["staticlibrary"] : undefined
|
||||
|
||||
Depends { name: "cpp" }
|
||||
Depends { name: "qtc" }
|
||||
|
||||
property bool useExternalLib: qtc.litehtmlInstallDir
|
||||
property bool buildLib: !useExternalLib && File.exists(path + "/litehtml/CMakeLists.txt")
|
||||
condition: useExternalLib || buildLib
|
||||
|
||||
property string gumboSrcDir: path + "/litehtml/src/gumbo"
|
||||
property string gumboHeaderDir: gumboSrcDir + "/include/gumbo"
|
||||
property string litehtmlHeaderDir: path + "/litehtml/include/litehtml"
|
||||
property string mainHeaderDir: litehtmlHeaderDir + '/..'
|
||||
property stringList sharedDefines: {
|
||||
var defines = ["QLITEHTML_STATIC_LIBRARY"];
|
||||
if (qbs.targetOS.contains("windows"))
|
||||
defines.push("LITEHTML_UTF8");
|
||||
return defines;
|
||||
}
|
||||
|
||||
cpp.defines: sharedDefines
|
||||
cpp.includePaths: {
|
||||
var paths = [gumboHeaderDir, gumboHeaderDir + '/..', litehtmlHeaderDir, mainHeaderDir];
|
||||
if (qbs.targetOS.contains("windows"))
|
||||
paths.push(gumboSrcDir + "/visualc/include");
|
||||
return paths;
|
||||
}
|
||||
cpp.optimization: "fast"
|
||||
cpp.warningLevel: "none"
|
||||
cpp.cxxLanguageVersion: "c++14"
|
||||
|
||||
Export {
|
||||
Depends { name: "cpp" }
|
||||
Group {
|
||||
name: "litehtml/Qt glue"
|
||||
cpp.warningLevel: "none"
|
||||
files: [
|
||||
"container_qpainter.cpp",
|
||||
"container_qpainter.h",
|
||||
"container_qpainter_p.h",
|
||||
"qlitehtmlwidget.cpp",
|
||||
"qlitehtmlwidget.h",
|
||||
]
|
||||
}
|
||||
|
||||
Properties {
|
||||
condition: product.useExternalLib
|
||||
cpp.dynamicLibraries: ["litehtml", "gumbo"]
|
||||
cpp.includePaths: [
|
||||
FileInfo.joinPaths(qtc.litehtmlInstallDir, "include"),
|
||||
FileInfo.joinPaths(qtc.litehtmlInstallDir, "include", "litehtml"),
|
||||
]
|
||||
cpp.libraryPaths: FileInfo.joinPaths(qtc.litehtmlInstallDir, "lib")
|
||||
}
|
||||
Properties {
|
||||
condition: product.buildLib
|
||||
cpp.defines: product.sharedDefines
|
||||
cpp.includePaths: [product.mainHeaderDir, path]
|
||||
}
|
||||
}
|
||||
|
||||
Group {
|
||||
condition: buildLib
|
||||
name: "gumbo sources"
|
||||
prefix: gumboSrcDir + '/'
|
||||
files: [
|
||||
"attribute.c",
|
||||
"char_ref.c",
|
||||
"error.c",
|
||||
"parser.c",
|
||||
"string_buffer.c",
|
||||
"string_piece.c",
|
||||
"tag.c",
|
||||
"tokenizer.c",
|
||||
"utf8.c",
|
||||
"util.c",
|
||||
"vector.c",
|
||||
]
|
||||
}
|
||||
|
||||
Group {
|
||||
condition: buildLib
|
||||
name: "gumbo headers"
|
||||
prefix: gumboHeaderDir + '/'
|
||||
files: [
|
||||
"../gumbo.h",
|
||||
"attribute.h",
|
||||
"char_ref.h",
|
||||
"error.h",
|
||||
"insertion_mode.h",
|
||||
"parser.h",
|
||||
"string_buffer.h",
|
||||
"string_piece.h",
|
||||
"tag_enum.h",
|
||||
"tag_gperf.h",
|
||||
"tag_sizes.h",
|
||||
"tag_strings.h",
|
||||
"token_type.h",
|
||||
"tokenizer.h",
|
||||
"tokenizer_states.h",
|
||||
"utf8.h",
|
||||
"util.h",
|
||||
"vector.h",
|
||||
]
|
||||
|
||||
Group {
|
||||
name: "gumbo Windows headers"
|
||||
condition: qbs.targetOS.contains("windows")
|
||||
files: "../../visualc/include/strings.h"
|
||||
}
|
||||
}
|
||||
|
||||
Group {
|
||||
condition: buildLib
|
||||
name: "litehtml sources"
|
||||
prefix: "litehtml/src/"
|
||||
files: [
|
||||
"background.cpp",
|
||||
"box.cpp",
|
||||
"context.cpp",
|
||||
"css_length.cpp",
|
||||
"css_selector.cpp",
|
||||
"document.cpp",
|
||||
"el_anchor.cpp",
|
||||
"el_base.cpp",
|
||||
"el_before_after.cpp",
|
||||
"el_body.cpp",
|
||||
"el_break.cpp",
|
||||
"el_cdata.cpp",
|
||||
"el_comment.cpp",
|
||||
"el_div.cpp",
|
||||
"element.cpp",
|
||||
"el_font.cpp",
|
||||
"el_image.cpp",
|
||||
"el_li.cpp",
|
||||
"el_link.cpp",
|
||||
"el_para.cpp",
|
||||
"el_script.cpp",
|
||||
"el_space.cpp",
|
||||
"el_style.cpp",
|
||||
"el_table.cpp",
|
||||
"el_td.cpp",
|
||||
"el_text.cpp",
|
||||
"el_title.cpp",
|
||||
"el_tr.cpp",
|
||||
"html.cpp",
|
||||
"html_tag.cpp",
|
||||
"iterators.cpp",
|
||||
"media_query.cpp",
|
||||
"num_cvt.cpp",
|
||||
"style.cpp",
|
||||
"stylesheet.cpp",
|
||||
"table.cpp",
|
||||
"utf8_strings.cpp",
|
||||
"web_color.cpp",
|
||||
]
|
||||
}
|
||||
|
||||
Group {
|
||||
condition: buildLib
|
||||
name: "litehtml headers"
|
||||
prefix: litehtmlHeaderDir + '/'
|
||||
files: [
|
||||
"../litehtml.h",
|
||||
"attributes.h",
|
||||
"background.h",
|
||||
"borders.h",
|
||||
"box.h",
|
||||
"context.h",
|
||||
"css_length.h",
|
||||
"css_margins.h",
|
||||
"css_offsets.h",
|
||||
"css_position.h",
|
||||
"css_selector.h",
|
||||
"document.h",
|
||||
"el_anchor.h",
|
||||
"el_base.h",
|
||||
"el_before_after.h",
|
||||
"el_body.h",
|
||||
"el_break.h",
|
||||
"el_cdata.h",
|
||||
"el_comment.h",
|
||||
"el_div.h",
|
||||
"el_font.h",
|
||||
"el_image.h",
|
||||
"el_li.h",
|
||||
"el_link.h",
|
||||
"el_para.h",
|
||||
"el_script.h",
|
||||
"el_space.h",
|
||||
"el_style.h",
|
||||
"el_table.h",
|
||||
"el_td.h",
|
||||
"el_text.h",
|
||||
"el_title.h",
|
||||
"el_tr.h",
|
||||
"element.h",
|
||||
"html.h",
|
||||
"html_tag.h",
|
||||
"iterators.h",
|
||||
"media_query.h",
|
||||
"num_cvt.h",
|
||||
"os_types.h",
|
||||
"style.h",
|
||||
"stylesheet.h",
|
||||
"table.h",
|
||||
"types.h",
|
||||
"utf8_strings.h",
|
||||
"web_color.h",
|
||||
]
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
#if defined(QLITEHTML_LIBRARY)
|
||||
# define QLITEHTML_EXPORT Q_DECL_EXPORT
|
||||
#elif defined(QLITEHTML_STATIC_LIBRARY) // Abuse single files for manual tests
|
||||
# define QLITEHTML_EXPORT
|
||||
#else
|
||||
# define QLITEHTML_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
@ -1,656 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of QLiteHtml.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qlitehtmlwidget.h"
|
||||
|
||||
#include "container_qpainter.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
#include <QScrollBar>
|
||||
#include <QStyle>
|
||||
#include <QTimer>
|
||||
|
||||
const int kScrollBarStep = 40;
|
||||
|
||||
// TODO copied from litehtml/include/master.css
|
||||
const char mastercss[] = R"RAW(
|
||||
html {
|
||||
display: block;
|
||||
height:100%;
|
||||
width:100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
head {
|
||||
display: none
|
||||
}
|
||||
|
||||
meta {
|
||||
display: none
|
||||
}
|
||||
|
||||
title {
|
||||
display: none
|
||||
}
|
||||
|
||||
link {
|
||||
display: none
|
||||
}
|
||||
|
||||
style {
|
||||
display: none
|
||||
}
|
||||
|
||||
script {
|
||||
display: none
|
||||
}
|
||||
|
||||
body {
|
||||
display:block;
|
||||
margin:8px;
|
||||
height:100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
p {
|
||||
display:block;
|
||||
margin-top:1em;
|
||||
margin-bottom:1em;
|
||||
}
|
||||
|
||||
b, strong {
|
||||
display:inline;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
i, em {
|
||||
display:inline;
|
||||
font-style:italic;
|
||||
}
|
||||
|
||||
center
|
||||
{
|
||||
text-align:center;
|
||||
display:block;
|
||||
}
|
||||
|
||||
a:link
|
||||
{
|
||||
text-decoration: underline;
|
||||
color: #00f;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6, div {
|
||||
display:block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight:bold;
|
||||
margin-top:0.67em;
|
||||
margin-bottom:0.67em;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight:bold;
|
||||
margin-top:0.83em;
|
||||
margin-bottom:0.83em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight:bold;
|
||||
margin-top:1em;
|
||||
margin-bottom:1em;
|
||||
font-size:1.17em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-weight:bold;
|
||||
margin-top:1.33em;
|
||||
margin-bottom:1.33em
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-weight:bold;
|
||||
margin-top:1.67em;
|
||||
margin-bottom:1.67em;
|
||||
font-size:.83em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-weight:bold;
|
||||
margin-top:2.33em;
|
||||
margin-bottom:2.33em;
|
||||
font-size:.67em;
|
||||
}
|
||||
|
||||
br {
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
br[clear="all"]
|
||||
{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
br[clear="left"]
|
||||
{
|
||||
clear:left;
|
||||
}
|
||||
|
||||
br[clear="right"]
|
||||
{
|
||||
clear:right;
|
||||
}
|
||||
|
||||
span {
|
||||
display:inline
|
||||
}
|
||||
|
||||
img {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
img[align="right"]
|
||||
{
|
||||
float: right;
|
||||
}
|
||||
|
||||
img[align="left"]
|
||||
{
|
||||
float: left;
|
||||
}
|
||||
|
||||
hr {
|
||||
display: block;
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border-style: inset;
|
||||
border-width: 1px
|
||||
}
|
||||
|
||||
|
||||
/***************** TABLES ********************/
|
||||
|
||||
table {
|
||||
display: table;
|
||||
border-collapse: separate;
|
||||
border-spacing: 2px;
|
||||
border-top-color:gray;
|
||||
border-left-color:gray;
|
||||
border-bottom-color:black;
|
||||
border-right-color:black;
|
||||
}
|
||||
|
||||
tbody, tfoot, thead {
|
||||
display:table-row-group;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
tr {
|
||||
display: table-row;
|
||||
vertical-align: inherit;
|
||||
border-color: inherit;
|
||||
}
|
||||
|
||||
td, th {
|
||||
display: table-cell;
|
||||
vertical-align: inherit;
|
||||
border-width:1px;
|
||||
padding:1px;
|
||||
}
|
||||
|
||||
th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table[border] {
|
||||
border-style:solid;
|
||||
}
|
||||
|
||||
table[border|=0] {
|
||||
border-style:none;
|
||||
}
|
||||
|
||||
table[border] td, table[border] th {
|
||||
border-style:solid;
|
||||
border-top-color:black;
|
||||
border-left-color:black;
|
||||
border-bottom-color:gray;
|
||||
border-right-color:gray;
|
||||
}
|
||||
|
||||
table[border|=0] td, table[border|=0] th {
|
||||
border-style:none;
|
||||
}
|
||||
|
||||
caption {
|
||||
display: table-caption;
|
||||
}
|
||||
|
||||
td[nowrap], th[nowrap] {
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
tt, code, kbd, samp {
|
||||
font-family: monospace
|
||||
}
|
||||
pre, xmp, plaintext, listing {
|
||||
display: block;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
margin: 1em 0
|
||||
}
|
||||
|
||||
/***************** LISTS ********************/
|
||||
|
||||
ul, menu, dir {
|
||||
display: block;
|
||||
list-style-type: disc;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
padding-left: 40px
|
||||
}
|
||||
|
||||
ol {
|
||||
display: block;
|
||||
list-style-type: decimal;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
padding-left: 40px
|
||||
}
|
||||
|
||||
li {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
ul ul, ol ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
ol ol ul, ol ul ul, ul ol ul, ul ul ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
dd {
|
||||
display: block;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
dl {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ol ul, ul ol, ul ul, ol ol {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0
|
||||
}
|
||||
|
||||
blockquote {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
margin-left: 40px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
/*********** FORM ELEMENTS ************/
|
||||
|
||||
form {
|
||||
display: block;
|
||||
margin-top: 0em;
|
||||
}
|
||||
|
||||
option {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input, textarea, keygen, select, button, isindex {
|
||||
margin: 0em;
|
||||
color: initial;
|
||||
line-height: normal;
|
||||
text-transform: none;
|
||||
text-indent: 0;
|
||||
text-shadow: none;
|
||||
display: inline-block;
|
||||
}
|
||||
input[type="hidden"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
article, aside, footer, header, hgroup, nav, section
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
)RAW";
|
||||
|
||||
class QLiteHtmlWidgetPrivate
|
||||
{
|
||||
public:
|
||||
QString html;
|
||||
DocumentContainerContext context;
|
||||
QUrl url;
|
||||
DocumentContainer documentContainer;
|
||||
qreal zoomFactor = 1;
|
||||
};
|
||||
|
||||
QLiteHtmlWidget::QLiteHtmlWidget(QWidget *parent)
|
||||
: QAbstractScrollArea(parent)
|
||||
, d(new QLiteHtmlWidgetPrivate)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
horizontalScrollBar()->setSingleStep(kScrollBarStep);
|
||||
verticalScrollBar()->setSingleStep(kScrollBarStep);
|
||||
|
||||
d->documentContainer.setCursorCallback([this](const QCursor &c) { viewport()->setCursor(c); });
|
||||
d->documentContainer.setPaletteCallback([this] { return palette(); });
|
||||
d->documentContainer.setLinkCallback([this](const QUrl &url) {
|
||||
QUrl fullUrl = url;
|
||||
if (url.isRelative() && url.path(QUrl::FullyEncoded).isEmpty()) { // fragment/anchor only
|
||||
fullUrl = d->url;
|
||||
fullUrl.setFragment(url.fragment(QUrl::FullyEncoded));
|
||||
}
|
||||
// delay because document may not be changed directly during this callback
|
||||
QTimer::singleShot(0, this, [this, fullUrl] { emit linkClicked(fullUrl); });
|
||||
});
|
||||
|
||||
// TODO adapt mastercss to palette (default text & background color)
|
||||
d->context.setMasterStyleSheet(mastercss);
|
||||
}
|
||||
|
||||
QLiteHtmlWidget::~QLiteHtmlWidget()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::setUrl(const QUrl &url)
|
||||
{
|
||||
d->url = url;
|
||||
QUrl urlWithoutAnchor = url;
|
||||
urlWithoutAnchor.setFragment({});
|
||||
const QString urlString = urlWithoutAnchor.toString(QUrl::None);
|
||||
const int lastSlash = urlString.lastIndexOf('/');
|
||||
const QString baseUrl = lastSlash >= 0 ? urlString.left(lastSlash) : urlString;
|
||||
d->documentContainer.setBaseUrl(baseUrl);
|
||||
}
|
||||
|
||||
QUrl QLiteHtmlWidget::url() const
|
||||
{
|
||||
return d->url;
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::setHtml(const QString &content)
|
||||
{
|
||||
d->html = content;
|
||||
d->documentContainer.setPaintDevice(viewport());
|
||||
d->documentContainer.setDocument(content.toUtf8(), &d->context);
|
||||
verticalScrollBar()->setValue(0);
|
||||
horizontalScrollBar()->setValue(0);
|
||||
render();
|
||||
}
|
||||
|
||||
QString QLiteHtmlWidget::html() const
|
||||
{
|
||||
return d->html;
|
||||
}
|
||||
|
||||
QString QLiteHtmlWidget::title() const
|
||||
{
|
||||
return d->documentContainer.caption();
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::setZoomFactor(qreal scale)
|
||||
{
|
||||
Q_ASSERT(scale != 0);
|
||||
d->zoomFactor = scale;
|
||||
withFixedTextPosition([this] { render(); });
|
||||
}
|
||||
|
||||
qreal QLiteHtmlWidget::zoomFactor() const
|
||||
{
|
||||
return d->zoomFactor;
|
||||
}
|
||||
|
||||
bool QLiteHtmlWidget::findText(const QString &text,
|
||||
QTextDocument::FindFlags flags,
|
||||
bool incremental,
|
||||
bool *wrapped)
|
||||
{
|
||||
bool success = false;
|
||||
QVector<QRect> oldSelection;
|
||||
QVector<QRect> newSelection;
|
||||
d->documentContainer
|
||||
.findText(text, flags, incremental, wrapped, &success, &oldSelection, &newSelection);
|
||||
// scroll to search result position and/or redraw as necessary
|
||||
QRect newSelectionCombined;
|
||||
for (const QRect &r : qAsConst(newSelection))
|
||||
newSelectionCombined = newSelectionCombined.united(r);
|
||||
QScrollBar *vBar = verticalScrollBar();
|
||||
const int top = newSelectionCombined.top();
|
||||
const int bottom = newSelectionCombined.bottom() - toVirtual(viewport()->size()).height();
|
||||
if (success && top < vBar->value() && vBar->minimum() <= top) {
|
||||
vBar->setValue(top);
|
||||
} else if (success && vBar->value() < bottom && bottom <= vBar->maximum()) {
|
||||
vBar->setValue(bottom);
|
||||
} else {
|
||||
viewport()->update(fromVirtual(newSelectionCombined.translated(-scrollPosition())));
|
||||
for (const QRect &r : qAsConst(oldSelection))
|
||||
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::setDefaultFont(const QFont &font)
|
||||
{
|
||||
withFixedTextPosition([this, &font] {
|
||||
d->documentContainer.setDefaultFont(font);
|
||||
render();
|
||||
});
|
||||
}
|
||||
|
||||
QFont QLiteHtmlWidget::defaultFont() const
|
||||
{
|
||||
return d->documentContainer.defaultFont();
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::scrollToAnchor(const QString &name)
|
||||
{
|
||||
if (!d->documentContainer.hasDocument())
|
||||
return;
|
||||
horizontalScrollBar()->setValue(0);
|
||||
if (name.isEmpty()) {
|
||||
verticalScrollBar()->setValue(0);
|
||||
return;
|
||||
}
|
||||
const int y = d->documentContainer.anchorY(name);
|
||||
if (y >= 0)
|
||||
verticalScrollBar()->setValue(std::min(y, verticalScrollBar()->maximum()));
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::setResourceHandler(const QLiteHtmlWidget::ResourceHandler &handler)
|
||||
{
|
||||
d->documentContainer.setDataCallback(handler);
|
||||
}
|
||||
|
||||
QString QLiteHtmlWidget::selectedText() const
|
||||
{
|
||||
return d->documentContainer.selectedText();
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
if (!d->documentContainer.hasDocument())
|
||||
return;
|
||||
d->documentContainer.setScrollPosition(scrollPosition());
|
||||
QPainter p(viewport());
|
||||
p.setWorldTransform(QTransform().scale(d->zoomFactor, d->zoomFactor));
|
||||
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
d->documentContainer.draw(&p, toVirtual(event->rect()));
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
withFixedTextPosition([this, event] {
|
||||
QAbstractScrollArea::resizeEvent(event);
|
||||
render();
|
||||
});
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QPoint viewportPos;
|
||||
QPoint pos;
|
||||
htmlPos(event->pos(), &viewportPos, &pos);
|
||||
for (const QRect &r : d->documentContainer.mouseMoveEvent(pos, viewportPos))
|
||||
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QPoint viewportPos;
|
||||
QPoint pos;
|
||||
htmlPos(event->pos(), &viewportPos, &pos);
|
||||
for (const QRect &r : d->documentContainer.mousePressEvent(pos, viewportPos, event->button()))
|
||||
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
QPoint viewportPos;
|
||||
QPoint pos;
|
||||
htmlPos(event->pos(), &viewportPos, &pos);
|
||||
for (const QRect &r : d->documentContainer.mouseReleaseEvent(pos, viewportPos, event->button()))
|
||||
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
QPoint viewportPos;
|
||||
QPoint pos;
|
||||
htmlPos(event->pos(), &viewportPos, &pos);
|
||||
for (const QRect &r :
|
||||
d->documentContainer.mouseDoubleClickEvent(pos, viewportPos, event->button())) {
|
||||
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
|
||||
}
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::leaveEvent(QEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
for (const QRect &r : d->documentContainer.leaveEvent())
|
||||
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
QPoint viewportPos;
|
||||
QPoint pos;
|
||||
htmlPos(event->pos(), &viewportPos, &pos);
|
||||
emit contextMenuRequested(event->pos(), d->documentContainer.linkAt(pos, viewportPos));
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::withFixedTextPosition(const std::function<void()> &action)
|
||||
{
|
||||
// remember element to which to scroll after re-rendering
|
||||
QPoint viewportPos;
|
||||
QPoint pos;
|
||||
htmlPos({}, &viewportPos, &pos); // top-left
|
||||
const int y = d->documentContainer.withFixedElementPosition(pos.y(), action);
|
||||
if (y >= 0)
|
||||
verticalScrollBar()->setValue(std::min(y, verticalScrollBar()->maximum()));
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::render()
|
||||
{
|
||||
if (!d->documentContainer.hasDocument())
|
||||
return;
|
||||
const int fullWidth = width() / d->zoomFactor;
|
||||
const QSize vViewportSize = toVirtual(viewport()->size());
|
||||
const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent, nullptr, this);
|
||||
const int w = fullWidth - scrollbarWidth - 2;
|
||||
d->documentContainer.render(w, vViewportSize.height());
|
||||
// scroll bars reflect virtual/scaled size of html document
|
||||
horizontalScrollBar()->setPageStep(vViewportSize.width());
|
||||
horizontalScrollBar()->setRange(0, std::max(0, d->documentContainer.documentWidth() - w));
|
||||
verticalScrollBar()->setPageStep(vViewportSize.height());
|
||||
verticalScrollBar()
|
||||
->setRange(0, std::max(0, d->documentContainer.documentHeight() - vViewportSize.height()));
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
QPoint QLiteHtmlWidget::scrollPosition() const
|
||||
{
|
||||
return {horizontalScrollBar()->value(), verticalScrollBar()->value()};
|
||||
}
|
||||
|
||||
void QLiteHtmlWidget::htmlPos(const QPoint &pos, QPoint *viewportPos, QPoint *htmlPos) const
|
||||
{
|
||||
*viewportPos = toVirtual(viewport()->mapFromParent(pos));
|
||||
*htmlPos = *viewportPos + scrollPosition();
|
||||
}
|
||||
|
||||
QPoint QLiteHtmlWidget::toVirtual(const QPoint &p) const
|
||||
{
|
||||
return {int(p.x() / d->zoomFactor), int(p.y() / d->zoomFactor)};
|
||||
}
|
||||
|
||||
QSize QLiteHtmlWidget::toVirtual(const QSize &s) const
|
||||
{
|
||||
return {int(s.width() / d->zoomFactor), int(s.height() / d->zoomFactor)};
|
||||
}
|
||||
|
||||
QRect QLiteHtmlWidget::toVirtual(const QRect &r) const
|
||||
{
|
||||
return {toVirtual(r.topLeft()), toVirtual(r.size())};
|
||||
}
|
||||
|
||||
QRect QLiteHtmlWidget::fromVirtual(const QRect &r) const
|
||||
{
|
||||
const QPoint tl{int(r.x() * d->zoomFactor), int(r.y() * d->zoomFactor)};
|
||||
// round size up, and add one since the topleft point was rounded down
|
||||
const QSize s{int(r.width() * d->zoomFactor + 0.5) + 1,
|
||||
int(r.height() * d->zoomFactor + 0.5) + 1};
|
||||
return {tl, s};
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of QLiteHtml.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qlitehtml_global.h"
|
||||
|
||||
#include <QAbstractScrollArea>
|
||||
#include <QTextDocument>
|
||||
|
||||
#include <functional>
|
||||
|
||||
class QLiteHtmlWidgetPrivate;
|
||||
|
||||
class QLITEHTML_EXPORT QLiteHtmlWidget : public QAbstractScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QLiteHtmlWidget(QWidget *parent = nullptr);
|
||||
~QLiteHtmlWidget() override;
|
||||
|
||||
// declaring the getters Q_INVOKABLE to make them Squish-testable
|
||||
void setUrl(const QUrl &url);
|
||||
Q_INVOKABLE QUrl url() const;
|
||||
void setHtml(const QString &content);
|
||||
Q_INVOKABLE QString html() const;
|
||||
Q_INVOKABLE QString title() const;
|
||||
|
||||
void setZoomFactor(qreal scale);
|
||||
qreal zoomFactor() const;
|
||||
|
||||
bool findText(const QString &text,
|
||||
QTextDocument::FindFlags flags,
|
||||
bool incremental,
|
||||
bool *wrapped = nullptr);
|
||||
|
||||
void setDefaultFont(const QFont &font);
|
||||
QFont defaultFont() const;
|
||||
|
||||
void scrollToAnchor(const QString &name);
|
||||
|
||||
using ResourceHandler = std::function<QByteArray(QUrl)>;
|
||||
void setResourceHandler(const ResourceHandler &handler);
|
||||
|
||||
// declaring this Q_INVOKABLE to make it Squish-testable
|
||||
Q_INVOKABLE QString selectedText() const;
|
||||
|
||||
signals:
|
||||
void linkClicked(const QUrl &url);
|
||||
void contextMenuRequested(const QPoint &pos, const QUrl &url);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
void leaveEvent(QEvent *event) override;
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
|
||||
private:
|
||||
void withFixedTextPosition(const std::function<void()> &action);
|
||||
void render();
|
||||
QPoint scrollPosition() const;
|
||||
void htmlPos(const QPoint &pos, QPoint *viewportPos, QPoint *htmlPos) const;
|
||||
QPoint toVirtual(const QPoint &p) const;
|
||||
QSize toVirtual(const QSize &s) const;
|
||||
QRect toVirtual(const QRect &r) const;
|
||||
QRect fromVirtual(const QRect &r) const;
|
||||
|
||||
QLiteHtmlWidgetPrivate *d;
|
||||
};
|
Reference in New Issue
Block a user