Commit da201402 authored by Robby Stephenson's avatar Robby Stephenson
Browse files

Use QWebEngine by default rather than KHTML

The cmake flag USE_KHTML may be used to build with KHTML rather than
QWebEngine as in previous versions.
parent 5d8ec555
......@@ -39,6 +39,7 @@ include(KDECMakeSettings)
option(ENABLE_CDTEXT "Enable cdtext" TRUE)
option(ENABLE_WEBCAM "Enable support for webcams" FALSE)
option(BUILD_FETCHER_TESTS "Build tests which verify data sources" FALSE)
option(USE_KHTML "Build with KHTML rather than QWebEngine" FALSE)
include(CheckSymbolExists)
check_symbol_exists(strlwr "string.h" HAVE_STRLWR)
......@@ -68,12 +69,25 @@ find_package(KF5 REQUIRED COMPONENTS
JobWidgets
KIO
Solid
Sonnet
TextWidgets
Wallet
WidgetsAddons
WindowSystem
XmlGui
)
find_package(KF5KHtml REQUIRED NO_MODULE)
if(NOT USE_KHTML)
find_package(Qt5 ${QT_MIN_VERSION} CONFIG OPTIONAL_COMPONENTS WebEngineWidgets)
set_package_properties(Qt5WebEngineWidgets PROPERTIES
DESCRIPTION "Building with QWebEngine is preferrable to KHTML"
TYPE OPTIONAL)
endif()
if(USE_KHTML OR NOT Qt5WebEngineWidgets_FOUND)
set(USE_KHTML ON)
find_package(KF5KHtml REQUIRED NO_MODULE)
set_package_properties(KF5Html PROPERTIES
DESCRIPTION "Building with QWebEngine is preferrable to KHTML")
endif()
include(MacroBoolTo01)
......
......@@ -102,7 +102,6 @@ TARGET_LINK_LIBRARIES(tellico
Qt5::Widgets
Qt5::DBus
KF5::Crash
KF5::KHtml
KF5::KIOCore
KF5::KIOFileWidgets
KF5::WindowSystem
......@@ -111,6 +110,13 @@ TARGET_LINK_LIBRARIES(tellico
${LIBXSLT_EXSLT_LIBRARIES}
)
IF(USE_KHTML)
TARGET_LINK_LIBRARIES(tellico KF5::KHtml)
ADD_DEFINITIONS(-DUSE_KHTML=${USE_KHTML})
ELSE()
TARGET_LINK_LIBRARIES(tellico Qt5::WebEngineWidgets)
ENDIF()
IF( KF5NewStuff_FOUND )
TARGET_LINK_LIBRARIES(tellico KF5::NewStuff)
ENDIF( KF5NewStuff_FOUND )
......
########### next target ###############
SET(charts_STAT_SRCS
groupsummary.cpp
)
add_library(charts STATIC ${charts_STAT_SRCS})
TARGET_LINK_LIBRARIES(charts
Qt5::Core
Qt5::Widgets
Qt5::Gui
Qt5::Charts
KF5::I18n
)
/***************************************************************************
Copyright (C) 2020 Robby Stephenson <robby@periapsis.org>
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License or (at your option) version 3 or any later version *
* accepted by the membership of KDE e.V. (or its successor approved *
* by the membership of KDE e.V.), which shall act as a proxy *
* defined in Section 14 of version 3 of the license. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#include "groupsummary.h"
using Tellico::Charts::GroupSummary;
GroupSummary::GroupSummary(QWidget* parent_)
: QWidget(parent_) {
}
/***************************************************************************
Copyright (C) 2020 Robby Stephenson <robby@periapsis.org>
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License or (at your option) version 3 or any later version *
* accepted by the membership of KDE e.V. (or its successor approved *
* by the membership of KDE e.V.), which shall act as a proxy *
* defined in Section 14 of version 3 of the license. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#ifndef TELLICO_CHARTS_GROUPSUMMARY_H
#define TELLICO_CHARTS_GROUPSUMMARY_H
#include <QWidget>
#include <QList>
class QChartView;
namespace Tellico {
namespace Charts {
class GroupSummary : public QWidget {
Q_OBJECT
public:
explicit GroupSummary(QWidget* parent = nullptr);
~GroupSummary() Q_DECL_OVERRIDE {};
private:
QList<QChartView*> m_charts;
};
} // end namespace
} //end namespace
#endif
......@@ -48,7 +48,6 @@
#include <KLocalizedString>
#include <KConfig>
#include <KAcceleratorManager>
#include <KHTMLView>
#include <KColorCombo>
#include <KHelpClient>
#include <KRecentDirs>
......
/***************************************************************************
Copyright (C) 2003-2009 Robby Stephenson <robby@periapsis.org>
Copyright (C) 2003-2020 Robby Stephenson <robby@periapsis.org>
***************************************************************************/
/***************************************************************************
......@@ -40,8 +40,6 @@
#include "tellico_debug.h"
#include <KMessageBox>
#include <KHTMLView>
#include <dom/dom_element.h>
#include <KLocalizedString>
#include <QFile>
......@@ -52,7 +50,16 @@
#include <QApplication>
#include <QDesktopServices>
#ifdef USE_KHTML
#include <dom/dom_element.h>
#else
#include <QWebEnginePage>
#include <QWebEngineSettings>
#endif
using Tellico::EntryView;
#ifdef USE_KHTML
using Tellico::EntryViewWidget;
EntryViewWidget::EntryViewWidget(EntryView* part, QWidget* parent)
......@@ -89,6 +96,50 @@ EntryView::EntryView(QWidget* parent_) : KHTMLPart(new EntryViewWidget(this, par
connect(browserExtension(), &KParts::BrowserExtension::openUrlRequestDelayed,
this, &EntryView::slotOpenURL);
}
#else
using Tellico::EntryViewPage;
EntryViewPage::EntryViewPage(QWidget* parent)
: QWebEnginePage(parent) {
settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false);
settings()->setAttribute(QWebEngineSettings::PluginsEnabled, false);
settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);
settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, true);
}
bool EntryViewPage::acceptNavigationRequest(const QUrl& url_, QWebEnginePage::NavigationType type_, bool isMainFrame_) {
Q_UNUSED(isMainFrame_);
if(url_.scheme() == QLatin1String("tc")) {
// handle this internally
emit signalTellicoAction(url_);
return false;
}
if(type_ == QWebEnginePage::NavigationTypeLinkClicked) {
const QUrl u = Kernel::self()->URL().resolved(url_);
QDesktopServices::openUrl(u);
return false;
}
return true;
}
EntryView::EntryView(QWidget* parent_) : QWebEngineView(parent_),
m_handler(nullptr), m_tempFile(nullptr), m_useGradientImages(true), m_checkCommonFile(true) {
EntryViewPage* page = new EntryViewPage(this);
setPage(page);
connect(page, &EntryViewPage::signalTellicoAction,
this, &EntryView::signalTellicoAction);
setAcceptDrops(true);
DropHandler* drophandler = new DropHandler(this);
installEventFilter(drophandler);
clear(); // needed for initial layout
}
#endif
EntryView::~EntryView() {
delete m_handler;
......@@ -101,12 +152,22 @@ void EntryView::clear() {
m_entry = nullptr;
// just clear the view
#ifdef USE_KHTML
begin();
if(!m_textToShow.isEmpty()) {
write(m_textToShow);
}
end();
view()->layout(); // I need this because some of the margins and widths may get messed up
#else
setUrl(QUrl());
if(!m_textToShow.isEmpty()) {
// the welcome page references local images, which won't load when passing HTML directly
// see https://bugreports.qt.io/browse/QTBUG-55902#comment-335945
// passing "disable-web-security" to QApplication is another option
page()->setHtml(m_textToShow, QUrl(QStringLiteral("file://")));
}
#endif
}
void EntryView::showEntries(Tellico::Data::EntryList entries_) {
......@@ -137,11 +198,9 @@ void EntryView::showEntry(Tellico::Data::EntryPtr entry_) {
m_entry = entry_;
// by setting the xslt file as the URL, any images referenced in the xslt "theme" can be found
// by simply using a relative path in the xslt file
QUrl u = QUrl::fromLocalFile(m_xsltFile);
begin(u);
#ifdef USE_KHTML
begin(QUrl::fromLocalFile(m_xsltFile));
#endif
Export::TellicoXMLExporter exporter(entry_->collection());
exporter.setEntries(Data::EntryList() << entry_);
long opt = exporter.options();
......@@ -197,17 +256,26 @@ void EntryView::showEntry(Tellico::Data::EntryPtr entry_) {
#endif
// myDebug() << html;
#ifdef USE_KHTML
write(html);
end();
// not need anymore?
view()->layout(); // I need this because some of the margins and widths may get messed up
#else
// by setting the xslt file as the URL, any images referenced in the xslt "theme" can be found
// by simply using a relative path in the xslt file
page()->setHtml(html, QUrl::fromLocalFile(m_xsltFile));
#endif
}
void EntryView::showText(const QString& text_) {
m_textToShow = text_;
#ifdef USE_KHTML
begin();
write(text_);
end();
#else
clear(); // shows the default text
#endif
}
void EntryView::setXSLTFile(const QString& file_) {
......@@ -233,7 +301,11 @@ void EntryView::setXSLTFile(const QString& file_) {
str += QLatin1Char(' ');
str += i18n("Please check your installation.");
str += QLatin1String("</qt>");
#ifdef USE_KHTML
KMessageBox::error(view(), str);
#else
KMessageBox::error(this, str);
#endif
clear();
return;
}
......@@ -303,9 +375,12 @@ void EntryView::setXSLTFile(const QString& file_) {
void EntryView::slotRefresh() {
setXSLTFile(m_xsltFile);
showEntry(m_entry);
#ifdef USE_KHTML
view()->repaint();
#endif
}
#ifdef USE_KHTML
// do some contortions in case the url is relative
// need to interpret it relative to document URL instead of xslt file
// the current node under the mouse would be the text node inside
......@@ -313,7 +388,7 @@ void EntryView::slotRefresh() {
void EntryView::slotOpenURL(const QUrl& url_) {
if(url_.scheme() == QLatin1String("tc")) {
// handle this internally
emit signalAction(url_);
emit signalTellicoAction(url_);
return;
}
......@@ -331,14 +406,20 @@ void EntryView::slotOpenURL(const QUrl& url_) {
// open the url
QDesktopServices::openUrl(u);
}
#endif
void EntryView::slotReloadEntry() {
// this slot should only be connected in setXSLTFile()
// must disconnect the signal first, otherwise, get an infinite loop
#ifdef USE_KHTML
void (EntryView::* completed)() = &EntryView::completed;
disconnect(this, completed, this, &EntryView::slotReloadEntry);
closeUrl(); // this is needed to stop everything, for some reason
view()->setUpdatesEnabled(true);
#else
disconnect(this, &EntryView::loadFinished, this, &EntryView::slotReloadEntry);
setUpdatesEnabled(true);
#endif
if(m_entry) {
showEntry(m_entry);
......@@ -409,13 +490,19 @@ void EntryView::resetColors() {
stream << s;
stream.flush();
#ifdef USE_KHTML
KParts::OpenUrlArguments args = arguments();
args.setReload(true); // tell the cache to reload images
setArguments(args);
// don't flicker
view()->setUpdatesEnabled(false);
openUrl(QUrl::fromLocalFile(m_tempFile->fileName()));
void (EntryView::* completed)() = &EntryView::completed;
connect(this, completed, this, &EntryView::slotReloadEntry);
#else
// don't flicker
setUpdatesEnabled(false);
load(QUrl::fromLocalFile(m_tempFile->fileName()));
connect(this, &EntryView::loadFinished, this, &EntryView::slotReloadEntry);
#endif
}
/***************************************************************************
Copyright (C) 2003-2009 Robby Stephenson <robby@periapsis.org>
Copyright (C) 2003-2020 Robby Stephenson <robby@periapsis.org>
***************************************************************************/
/***************************************************************************
......@@ -27,10 +27,14 @@
#include "datavectors.h"
#ifdef USE_KHTML
#include <KHTMLPart>
#include <KHTMLView>
#else
#include <QWebEngineView>
#include <QWebEnginePage>
#include <QPointer>
#endif
class QTemporaryFile;
......@@ -42,7 +46,13 @@ namespace Tellico {
/**
* @author Robby Stephenson
*/
class EntryView : public KHTMLPart {
class EntryView : public
#ifdef USE_KHTML
KHTMLPart {
#else
QWebEngineView {
#endif
Q_OBJECT
public:
......@@ -81,7 +91,7 @@ public:
void resetView();
Q_SIGNALS:
void signalAction(const QUrl& url);
void signalTellicoAction(const QUrl& url);
public Q_SLOTS:
/**
......@@ -91,12 +101,14 @@ public Q_SLOTS:
void showEntries(Tellico::Data::EntryList entries);
private Q_SLOTS:
#ifdef USE_KHTML
/**
* Open a URL.
*
* @param url The URL to open
*/
void slotOpenURL(const QUrl& url);
#endif
void slotReloadEntry();
private:
......@@ -112,8 +124,7 @@ private:
bool m_checkCommonFile;
};
// stupid naming on my part, I need to subclass the view to
// add a slot. EntryView is really a part though
#ifdef USE_KHTML
class EntryViewWidget : public KHTMLView {
Q_OBJECT
public:
......@@ -125,6 +136,19 @@ public Q_SLOTS:
protected:
void changeEvent(QEvent* event) Q_DECL_OVERRIDE;
};
#else
class EntryViewPage : public QWebEnginePage {
Q_OBJECT
public:
EntryViewPage(QWidget* parent);
Q_SIGNALS:
void signalTellicoAction(const QUrl& url);
protected:
virtual bool acceptNavigationRequest(const QUrl& url, QWebEnginePage::NavigationType type, bool isMainFrame) Q_DECL_OVERRIDE;
};
#endif
} //end namespace
#endif
/***************************************************************************
Copyright (C) 2003-2011 Robby Stephenson <robby@periapsis.org>
Copyright (C) 2003-2020 Robby Stephenson <robby@periapsis.org>
***************************************************************************/
/***************************************************************************
......@@ -50,7 +50,6 @@
#endif
#include <KLocalizedString>
#include <KHTMLView>
#include <KSharedConfig>
#include <KAcceleratorManager>
#include <KTextEdit>
......@@ -272,8 +271,12 @@ FetchDialog::FetchDialog(QWidget* parent_)
// set the xslt file AFTER setting the gradient image option
m_entryView->setXSLTFile(QStringLiteral("Compact.xsl"));
m_entryView->addXSLTStringParam("skip-fields", "id,mdate,cdate");
m_entryView->view()->setWhatsThis(i18n("An entry may be shown here before adding it to the "
"current collection by selecting it in the list above"));
m_entryView->
#ifdef USE_KHTML
view()->
#endif
setWhatsThis(i18n("An entry may be shown here before adding it to the "
"current collection by selecting it in the list above"));
QWidget* box3 = new QWidget(mainWidget);
QHBoxLayout* box3HBoxLayout = new QHBoxLayout(box3);
......
......@@ -47,12 +47,20 @@ TARGET_LINK_LIBRARIES(gui
Qt5::Gui
KF5::KIOCore
KF5::KIOFileWidgets
KF5::KHtml
KF5::SonnetCore
KF5::SonnetUi
KF5::XmlGui
KF5::I18n
KF5::TextWidgets
)
IF(USE_KHTML)
TARGET_LINK_LIBRARIES(gui KF5::KHtml)
ADD_DEFINITIONS(-DUSE_KHTML=${USE_KHTML})
ELSE()
TARGET_LINK_LIBRARIES(gui Qt5::WebEngineWidgets)
ENDIF()
IF( KF5Sane_FOUND )
TARGET_LINK_LIBRARIES(gui KF5::Sane)
ENDIF( KF5Sane_FOUND )
......@@ -28,7 +28,6 @@
#include "../images/imagefactory.h" // for StyleOptions
#include <KLocalizedString>
#include <KHTMLView>
#include <QTemporaryDir>
#include <QDialogButtonBox>
......@@ -46,11 +45,12 @@ PreviewDialog::PreviewDialog(QWidget* parent_)
QVBoxLayout* mainLayout = new QVBoxLayout;
setLayout(mainLayout);
QWidget* mainWidget = new QWidget(this);
mainLayout->addWidget(mainWidget);
m_view = new EntryView(mainWidget);
m_view = new EntryView(this);
#ifdef USE_KHTML
mainLayout->addWidget(m_view->view());
#else
mainLayout->addWidget(m_view);
#endif
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
QPushButton* okButton = buttonBox->button(QDialogButtonBox::Ok);
......@@ -59,7 +59,7 @@ PreviewDialog::PreviewDialog(QWidget* parent_)
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
mainLayout->addWidget(buttonBox);
resize(QSize(600, 500));
resize(QSize(800, 600));
m_tempDir->setAutoRemove(true);
}
......
......@@ -82,7 +82,6 @@
#include <KStandardAction>
#include <KWindowSystem>
#include <KWindowConfig>
#include <KHTMLView>
#include <KMessageBox>
#include <KTipDialog>
#include <KRecentDocument>
......@@ -110,6 +109,17 @@
#include <QFileDialog>
#include <QMetaMethod>
#ifdef USE_KHTML
#include <KHTMLPart>
#include <KHTMLView>
#else
#include <QWebEngineView>
#include <QWebEnginePage>
#include <QWebEngineSettings>
#include <QPrinter>
#include <QPrintDialog>
#endif
#include <unistd.h>
namespace {
......@@ -327,6 +337,7 @@ void MainWindow::initActions() {
action = KStandardAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection());
action->setToolTip(i18n("Save the document as a different file..."));
action = KStandardAction::print(this, SLOT(slotFilePrint()), actionCollection());
#ifdef USE_KHTML
{
KHTMLPart w;
// KHTMLPart printing was broken in KDE until KHTML 5.16
......@@ -338,6 +349,7 @@ void MainWindow::initActions() {
action->setEnabled(false);
}
}
#endif
action->setToolTip(i18n("Print the contents of the document..."));
action = KStandardAction::quit(this, SLOT(slotFileQuit()), actionCollection());
......@@ -783,15 +795,20 @@ void MainWindow::initView() {
ImageFactory::init();
m_entryView = new EntryView(this);
connect(m_entryView, &EntryView::signalAction,
connect(m_entryView, &EntryView::signalTellicoAction,
this, &MainWindow::slotURLAction);
m_entryView->view()->setWhatsThis(i18n("<qt>The <i>Entry View</i> shows a formatted view of the entry's contents.</qt>"));
// trick to make sure the group views always extend along the entire left or right side
// using QMainWindow::setCorner does not seem to work
// https://wiki.qt.io/Technical_FAQ#Is_it_possible_for_either_the_left_or_right_dock_areas_to_have_full_height_of_their_side_rather_than_having_the_bottom_take_the_full_width.3F
m_dummyWindow = new QMainWindow(this);
#ifdef USE_KHTML
m_entryView->view()->setWhatsThis(i18n("<qt>The <i>Entry View</i> shows a formatted view of the entry's contents.</qt>"));
m_dummyWindow->setCentralWidget(m_entryView->view());
#else
m_entryView->setWhatsThis(i18n("<qt>The <i>Entry View</i> shows a formatted view of the entry's contents.</qt>"));
m_dummyWindow->setCentralWidget(m_entryView);
#endif
m_dummyWindow->setWindowFlags(Qt::Widget);
setCentralWidget(m_dummyWindow);
......@@ -1681,6 +1698,7 @@ void MainWindow::slotHideReportDialog() {
}
void MainWindow::doPrint(const QString& html_) {
#ifdef USE_KHTML
KHTMLPart w;
// KHTMLPart printing was broken in KDE until KHTML 5.16
......@@ -1700,12 +1718,28 @@ void MainWindow::doPrint(const QString& html_) {
w.begin(Data::Document::self()->URL());
w.write(html_);
w.end();
// the problem with doing my own layout is that the text gets truncated, both at the
// top and at the bottom. Even adding the overlap parameter, there were problems.
// KHTMLView takes care of that with a truncatedAt() parameter, but that's hidden in
// the khtml::render_root class. So for now, just use the KHTMLView::print() method.
w.view()->print();