articleviewerwebenginewidgetng.cpp 6.69 KB
Newer Older
Laurent Montel's avatar
Laurent Montel committed
1
/*
Laurent Montel's avatar
Laurent Montel committed
2
   Copyright (C) 2016-2020 Laurent Montel <montel@kde.org>
Laurent Montel's avatar
Laurent Montel committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

   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) any later version.

   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; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
Laurent Montel's avatar
Laurent Montel committed
18
19
20
*/

#include "articleviewerwebenginewidgetng.h"
Laurent Montel's avatar
Laurent Montel committed
21
#include "akregator_debug.h"
Laurent Montel's avatar
Laurent Montel committed
22
23
24
#include <KActionCollection>
#include <KLocalizedString>
#include <QVBoxLayout>
Laurent Montel's avatar
Laurent Montel committed
25
#include <viewerplugintoolmanager.h>
Laurent Montel's avatar
Laurent Montel committed
26
#include <KRun>
Laurent Montel's avatar
Laurent Montel committed
27
28
29

#include <KPIMTextEdit/kpimtextedit/texttospeechwidget.h>

30
#include <KPIMTextEdit/SlideContainer>
Laurent Montel's avatar
Laurent Montel committed
31

Laurent Montel's avatar
Laurent Montel committed
32
#include <WebEngineViewer/FindBarWebEngineView>
Laurent Montel's avatar
Laurent Montel committed
33
#include <WebEngineViewer/WebEngineExportHtmlPageJob>
Laurent Montel's avatar
Laurent Montel committed
34

Laurent Montel's avatar
Laurent Montel committed
35
#include <QApplication>
36
37
#include <QPrinter>
#include <QPrintDialog>
Laurent Montel's avatar
Laurent Montel committed
38
#include <QPrintPreviewDialog>
39

Laurent Montel's avatar
Laurent Montel committed
40
using namespace Akregator;
41
42
43
44
template<typename Arg, typename R, typename C>
struct InvokeWrapper {
    R *receiver;
    void (C::*memberFun)(Arg);
Laurent Montel's avatar
Laurent Montel committed
45
46
    void operator()(Arg result)
    {
47
48
49
50
51
52
53
54
55
56
57
        (receiver->*memberFun)(result);
    }
};

template<typename Arg, typename R, typename C>
InvokeWrapper<Arg, R, C> invoke(R *receiver, void (C::*memberFun)(Arg))
{
    InvokeWrapper<Arg, R, C> wrapper = {receiver, memberFun};
    return wrapper;
}

Laurent Montel's avatar
Laurent Montel committed
58
ArticleViewerWebEngineWidgetNg::ArticleViewerWebEngineWidgetNg(ArticleViewerWebEngine *customViewer, KActionCollection *ac, QWidget *parent)
Laurent Montel's avatar
Laurent Montel committed
59
60
    : QWidget(parent)
    , mCurrentPrinter(nullptr)
Laurent Montel's avatar
Laurent Montel committed
61
62
63
64
65
66
{
    mArticleViewerNg = customViewer;
    initializeLayout(ac);
}

ArticleViewerWebEngineWidgetNg::ArticleViewerWebEngineWidgetNg(KActionCollection *ac, QWidget *parent)
Laurent Montel's avatar
Laurent Montel committed
67
68
69
    : QWidget(parent)
    , mArticleViewerNg(nullptr)
    , mCurrentPrinter(nullptr)
Laurent Montel's avatar
Laurent Montel committed
70
71
72
73
74
75
{
    initializeLayout(ac);
}

void ArticleViewerWebEngineWidgetNg::initializeLayout(KActionCollection *ac)
{
Laurent Montel's avatar
Laurent Montel committed
76
    QVBoxLayout *layout = new QVBoxLayout(this);
Laurent Montel's avatar
Laurent Montel committed
77
    layout->setContentsMargins(0, 0, 0, 0);
Laurent Montel's avatar
Laurent Montel committed
78
79
80
81
82
83

    mTextToSpeechWidget = new KPIMTextEdit::TextToSpeechWidget(this);
    mTextToSpeechWidget->setObjectName(QStringLiteral("texttospeechwidget"));
    layout->addWidget(mTextToSpeechWidget);

    if (!mArticleViewerNg) {
Laurent Montel's avatar
Laurent Montel committed
84
        mArticleViewerNg = new ArticleViewerWebEngine(ac, this);
Laurent Montel's avatar
Laurent Montel committed
85
86
87
88
    }
    mArticleViewerNg->setObjectName(QStringLiteral("articleviewerng"));
    layout->addWidget(mArticleViewerNg);

89
    mArticleViewerNg->createViewerPluginToolManager(ac, this);
Laurent Montel's avatar
Laurent Montel committed
90

Laurent Montel's avatar
Laurent Montel committed
91
92
    mSliderContainer = new KPIMTextEdit::SlideContainer(this);
    mSliderContainer->setObjectName(QStringLiteral("slidercontainer"));
Laurent Montel's avatar
Laurent Montel committed
93
    mFindBarWebView = new WebEngineViewer::FindBarWebEngineView(mArticleViewerNg, this);
Laurent Montel's avatar
Laurent Montel committed
94
    mFindBarWebView->setObjectName(QStringLiteral("findbarwebview"));
Laurent Montel's avatar
Laurent Montel committed
95
    connect(mFindBarWebView, &WebEngineViewer::FindBarWebEngineView::hideFindBar, mSliderContainer, &KPIMTextEdit::SlideContainer::slideOut);
Laurent Montel's avatar
Laurent Montel committed
96
97
    mSliderContainer->setContent(mFindBarWebView);
    layout->addWidget(mSliderContainer);
Laurent Montel's avatar
Laurent Montel committed
98
99
    connect(articleViewerNg(), &ArticleViewerWebEngine::textToSpeech, this, &ArticleViewerWebEngineWidgetNg::slotSpeakText);
    connect(articleViewerNg(), &ArticleViewerWebEngine::findTextInHtml, this, &ArticleViewerWebEngineWidgetNg::slotFind);
Laurent Montel's avatar
Laurent Montel committed
100
101
102
103
104
105
}

ArticleViewerWebEngineWidgetNg::~ArticleViewerWebEngineWidgetNg()
{
}

Laurent Montel's avatar
Laurent Montel committed
106
ArticleViewerWebEngine *ArticleViewerWebEngineWidgetNg::articleViewerNg() const
Laurent Montel's avatar
Laurent Montel committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
{
    return mArticleViewerNg;
}

void ArticleViewerWebEngineWidgetNg::slotFind()
{
    if (mArticleViewerNg->hasSelection()) {
        mFindBarWebView->setText(mArticleViewerNg->selectedText());
    }
    mSliderContainer->slideIn();
    mFindBarWebView->focusAndSetCursor();
}

void ArticleViewerWebEngineWidgetNg::slotSpeakText()
{
    const QString text = mArticleViewerNg->selectedText();
    mTextToSpeechWidget->say(text);
}
125
126
127

void ArticleViewerWebEngineWidgetNg::saveCurrentPosition()
{
Laurent Montel's avatar
Laurent Montel committed
128
    mArticleViewerNg->saveRelativePosition();
129
130
}

Laurent Montel's avatar
Laurent Montel committed
131
132
void ArticleViewerWebEngineWidgetNg::slotPrint()
{
133
    printRequested(mArticleViewerNg->page());
Laurent Montel's avatar
Laurent Montel committed
134
135
}

136
137
void ArticleViewerWebEngineWidgetNg::printRequested(QWebEnginePage *page)
{
Laurent Montel's avatar
Laurent Montel committed
138
    if (mCurrentPrinter) {
139
        return;
Laurent Montel's avatar
Laurent Montel committed
140
    }
141
    mCurrentPrinter = new QPrinter();
Laurent Montel's avatar
Laurent Montel committed
142
    QPointer<QPrintDialog> dialog = new QPrintDialog(mCurrentPrinter, this);
143
    dialog->setWindowTitle(i18nc("@title:window", "Print Document"));
144
145
    if (dialog->exec() != QDialog::Accepted) {
        slotHandlePagePrinted(false);
Laurent Montel's avatar
Laurent Montel committed
146
        delete dialog;
147
148
        return;
    }
Laurent Montel's avatar
Laurent Montel committed
149
    delete dialog;
150
151
152
153
154
155
156
    page->print(mCurrentPrinter, invoke(this, &ArticleViewerWebEngineWidgetNg::slotHandlePagePrinted));
}

void ArticleViewerWebEngineWidgetNg::slotHandlePagePrinted(bool result)
{
    Q_UNUSED(result);
    delete mCurrentPrinter;
Laurent Montel's avatar
Laurent Montel committed
157
    mCurrentPrinter = nullptr;
158
159
}

Laurent Montel's avatar
Laurent Montel committed
160
161
void ArticleViewerWebEngineWidgetNg::slotPrintPreview()
{
Laurent Montel's avatar
Laurent Montel committed
162
    QPrintPreviewDialog *dialog = new QPrintPreviewDialog(this);
Laurent Montel's avatar
Laurent Montel committed
163
164
165
166
167
168
169
170
171
172
173
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->resize(800, 750);

    connect(dialog, &QPrintPreviewDialog::paintRequested, this, [=](QPrinter *printing) {
        QApplication::setOverrideCursor(Qt::WaitCursor);

        mArticleViewerNg->execPrintPreviewPage(printing, 10*1000);
        QApplication::restoreOverrideCursor();
    });

    dialog->open();
Laurent Montel's avatar
Laurent Montel committed
174
175
}

Laurent Montel's avatar
Laurent Montel committed
176
177
void ArticleViewerWebEngineWidgetNg::slotOpenInBrowser()
{
Laurent Montel's avatar
Laurent Montel committed
178
179
    const QUrl currentUrl(mArticleViewerNg->url());
    if (currentUrl.isLocalFile()) {
Laurent Montel's avatar
Laurent Montel committed
180
181
182
183
184
185
        WebEngineViewer::WebEngineExportHtmlPageJob *job = new WebEngineViewer::WebEngineExportHtmlPageJob;
        job->setEngineView(mArticleViewerNg);
        connect(job, &WebEngineViewer::WebEngineExportHtmlPageJob::failed, this, &ArticleViewerWebEngineWidgetNg::slotExportHtmlPageFailed);
        connect(job, &WebEngineViewer::WebEngineExportHtmlPageJob::success, this, &ArticleViewerWebEngineWidgetNg::slotExportHtmlPageSuccess);
        job->start();
    } else {
Laurent Montel's avatar
Laurent Montel committed
186
187
188
        KRun::RunFlags flags;
        flags |= KRun::RunExecutables;
        KRun::runUrl(currentUrl, QStringLiteral("text/html"), this, flags);
Laurent Montel's avatar
Laurent Montel committed
189
    }
Laurent Montel's avatar
Laurent Montel committed
190
191
192
193
194
195
196
197
}

void ArticleViewerWebEngineWidgetNg::slotExportHtmlPageFailed()
{
    qCDebug(AKREGATOR_LOG) << " Failed to export as HTML";
}

void ArticleViewerWebEngineWidgetNg::slotExportHtmlPageSuccess(const QString &filename)
Laurent Montel's avatar
Laurent Montel committed
198
199
{
    const QUrl url(QUrl::fromLocalFile(filename));
Laurent Montel's avatar
Laurent Montel committed
200
201
202
    KRun::RunFlags flags;
    flags |= KRun::DeleteTemporaryFiles;
    KRun::runUrl(url, QStringLiteral("text/html"), this, flags);
Laurent Montel's avatar
Laurent Montel committed
203
}