diff --git a/src/kpart/kmarkdownwebviewpartui.rc b/src/kpart/kmarkdownwebviewpartui.rc index 683973d..da03481 100644 --- a/src/kpart/kmarkdownwebviewpartui.rc +++ b/src/kpart/kmarkdownwebviewpartui.rc @@ -1,10 +1,11 @@ &Edit - + + diff --git a/src/kpart/markdownbrowserextension.cpp b/src/kpart/markdownbrowserextension.cpp index 5094d5c..ef6bef6 100644 --- a/src/kpart/markdownbrowserextension.cpp +++ b/src/kpart/markdownbrowserextension.cpp @@ -1,153 +1,151 @@ /* * Copyright (C) 2017 by Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "markdownbrowserextension.h" #include "markdownpart.h" #include // KF #include #include // Qt #include MarkdownBrowserExtension::MarkdownBrowserExtension(MarkdownPart* part) : KParts::BrowserExtension(part) , m_part(part) , m_contextMenuActionCollection(new KActionCollection(this)) { - emit enableAction("copy", false); + emit enableAction("copy", m_part->view()->isCopyTextEnabled()); } void MarkdownBrowserExtension::copy() { m_part->copySelection(); } -void MarkdownBrowserExtension::updateEditActions() +void MarkdownBrowserExtension::updateCopyAction(bool enabled) { - emit enableAction("copy", m_part->view()->canCopyText()); + emit enableAction("copy", enabled); } void MarkdownBrowserExtension::requestOpenUrl(const QUrl& url) { emit openUrlRequest(url); } void MarkdownBrowserExtension::requestOpenUrlNewWindow(const QUrl& url) { emit createNewWindow(url); } void MarkdownBrowserExtension::requestContextMenu(const QPoint& globalPos, const QUrl& linkUrl, const QString& linkText, bool hasSelection, bool forcesNewWindow) { // Clear the previous collection entries first... m_contextMenuActionCollection->clear(); // default menu arguments PopupFlags flags = DefaultPopupItems | ShowBookmark; ActionGroupMap mapAction; QString mimeType; QUrl emitUrl; if (!linkUrl.isValid()) { emitUrl = m_part->url(); mimeType = QStringLiteral("text/markdown"); if (hasSelection) { flags |= ShowTextSelectionItems; QList selectActions; - auto action = m_part->createCopySelectionAction(m_contextMenuActionCollection); - m_contextMenuActionCollection->addAction(QStringLiteral("copy"), action); + auto action = m_part->copySelectionAction(); selectActions.append(action); mapAction.insert(QStringLiteral("editactions"), selectActions); } } else { flags |= IsLink; emitUrl = linkUrl; QMimeDatabase mimeDb; if (linkUrl.isLocalFile()) mimeType = mimeDb.mimeTypeForUrl(linkUrl).name(); else { const QString fileName = linkUrl.fileName(); if (!fileName.isEmpty() && !linkUrl.hasFragment() && !linkUrl.hasQuery()) { auto mime = mimeDb.mimeTypeForFile(fileName); if (!mime.isDefault()) { mimeType = mime.name(); } } } QList linkActions; if (hasSelection) { - auto action = m_part->createCopySelectionAction(m_contextMenuActionCollection); - m_contextMenuActionCollection->addAction(QStringLiteral("copy"), action); + auto action = m_part->copySelectionAction(); linkActions.append(action); } if (linkUrl.scheme() == QLatin1String("mailto")) { auto action = m_part->createCopyEmailAddressAction(m_contextMenuActionCollection, linkUrl); m_contextMenuActionCollection->addAction(QStringLiteral("copylinklocation"), action); linkActions.append(action); } else { if (!linkText.isEmpty()) { auto action = m_part->createCopyLinkTextAction(m_contextMenuActionCollection, linkText); m_contextMenuActionCollection->addAction(QStringLiteral("copylinktext"), action); linkActions.append(action); } auto action = m_part->createCopyLinkUrlAction(m_contextMenuActionCollection); m_contextMenuActionCollection->addAction(QStringLiteral("copylinkurl"), action); linkActions.append(action); action = m_part->createSaveLinkAsAction(m_contextMenuActionCollection); m_contextMenuActionCollection->addAction(QStringLiteral("savelinkas"), action); linkActions.append(action); } mapAction.insert(QStringLiteral("linkactions"), linkActions); } if (!mapAction.isEmpty()) { KParts::OpenUrlArguments args; args.setMimeType(mimeType); KParts::BrowserArguments bargs; bargs.setForcesNewWindow(forcesNewWindow); emit popupMenu(globalPos, emitUrl, static_cast(-1), args, bargs, flags, mapAction); } } int MarkdownBrowserExtension::xOffset() { return m_part->view()->scrollPosition().x(); } int MarkdownBrowserExtension::yOffset() { return m_part->view()->scrollPosition().y(); } diff --git a/src/kpart/markdownbrowserextension.h b/src/kpart/markdownbrowserextension.h index 36979da..c3c6468 100644 --- a/src/kpart/markdownbrowserextension.h +++ b/src/kpart/markdownbrowserextension.h @@ -1,52 +1,52 @@ /* * Copyright (C) 2017 by Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef MARKDOWNBROWSEREXTENSION_H #define MARKDOWNBROWSEREXTENSION_H // KF headers #include class MarkdownPart; class KActionCollection; class MarkdownBrowserExtension : public KParts::BrowserExtension { Q_OBJECT public: explicit MarkdownBrowserExtension(MarkdownPart* part); int xOffset() override; int yOffset() override; public Q_SLOTS: void copy(); - void updateEditActions(); + void updateCopyAction(bool enabled); void requestOpenUrl(const QUrl& url); void requestOpenUrlNewWindow(const QUrl& url); void requestContextMenu(const QPoint& globalPos, const QUrl& linkUrl, const QString& linkText, bool hasSelection, bool forcesNewWindow); private: MarkdownPart* m_part; // needed to memory manage the context menu actions KActionCollection* m_contextMenuActionCollection; }; #endif diff --git a/src/kpart/markdownpart.cpp b/src/kpart/markdownpart.cpp index ab41b95..d04e59d 100644 --- a/src/kpart/markdownpart.cpp +++ b/src/kpart/markdownpart.cpp @@ -1,296 +1,306 @@ /* * Copyright (C) 2017 by Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "markdownpart.h" #include "markdownsourcedocument.h" #include "markdownbrowserextension.h" #include // KF #include #include #include #include // Qt #include #include #include #include #include #include #include #include #include MarkdownPart::MarkdownPart(QWidget* parentWidget, QObject* parent, const KAboutData& aboutData, Modus modus) : KParts::ReadOnlyPart(parent) , m_sourceDocument(new MarkdownSourceDocument(this)) , m_widget(new KMarkdownView(m_sourceDocument, parentWidget)) , m_browserExtension(new MarkdownBrowserExtension(this)) { // set component data // the first arg must be the same as the subdirectory into which the part's rc file is installed setComponentData(aboutData); // set internal UI setWidget(m_widget); // set KXMLUI resource file setXMLFile(QStringLiteral("kmarkdownwebviewpartui.rc")); if (modus == BrowserViewModus) { connect(m_widget, &KMarkdownView::openUrlRequested, m_browserExtension, &MarkdownBrowserExtension::requestOpenUrl); - connect(m_widget, &KMarkdownView::selectionChanged, - m_browserExtension, &MarkdownBrowserExtension::updateEditActions); + connect(m_widget, &KMarkdownView::copyTextEnabledChanged, + m_browserExtension, &MarkdownBrowserExtension::updateCopyAction); // connect(m_widget, &KMarkdownView::linkMiddleOrCtrlClicked, // this, &MarkdownBrowserExtension::requestOpenUrlNewWindow); connect(m_widget, &KMarkdownView::contextMenuRequested, m_browserExtension, &MarkdownBrowserExtension::requestContextMenu); } else { connect(m_widget, &KMarkdownView::openUrlRequested, this, &MarkdownPart::handleOpenUrlRequest); connect(m_widget, &KMarkdownView::contextMenuRequested, this, &MarkdownPart::requestContextMenu); } - setupActions(); + setupActions(modus); } MarkdownPart::~MarkdownPart() = default; -void MarkdownPart::setupActions() +void MarkdownPart::setupActions(Modus modus) { - auto action = KStandardAction::selectAll(this, &MarkdownPart::selectAll, actionCollection()); - action->setShortcutContext(Qt::WidgetShortcut); - m_widget->addAction(action); + // only register to xmlgui if not in browser mode + QObject* copySelectionActionParent = (modus == BrowserViewModus) ? static_cast(this) : static_cast(actionCollection()); + m_copySelectionAction = KStandardAction::copy(copySelectionActionParent); + m_copySelectionAction->setText(i18n("&Copy Text")); + m_copySelectionAction->setEnabled(m_widget->isCopyTextEnabled()); + connect(m_widget, &KMarkdownView::copyTextEnabledChanged, + m_copySelectionAction, &QAction::setEnabled); + connect(m_copySelectionAction, &QAction::triggered, this, &MarkdownPart::copySelection); + + m_selectAllAction = KStandardAction::selectAll(this, &MarkdownPart::selectAll, actionCollection()); + m_selectAllAction->setEnabled(m_widget->isSelectAllEnabled()); + connect(m_widget, &KMarkdownView::selectAllEnabledChanged, + m_selectAllAction, &QAction::setEnabled); + m_selectAllAction->setShortcutContext(Qt::WidgetShortcut); + m_widget->addAction(m_selectAllAction); } bool MarkdownPart::openFile() { QFile file(localFilePath()); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } prepareViewStateRestoringOnReload(); QTextStream stream(&file); QString text = stream.readAll(); file.close(); disconnect(m_widget, &KMarkdownView::renderingDone, this, &MarkdownPart::restoreScrollPosition); connect(m_widget, &KMarkdownView::renderingDone, this, &MarkdownPart::restoreScrollPosition); m_sourceDocument->setText(text); return true; } bool MarkdownPart::doOpenStream(const QString& mimeType) { auto mime = QMimeDatabase().mimeTypeForName(mimeType); if (!mime.inherits(QStringLiteral("text/markdown"))) { return false; } m_streamedData.clear(); m_sourceDocument->setText(QString()); return true; } bool MarkdownPart::doWriteStream(const QByteArray& data) { m_streamedData.append(data); return true; } bool MarkdownPart::doCloseStream() { QBuffer buffer(&m_streamedData); if (!buffer.open(QIODevice::ReadOnly | QIODevice::Text)) { m_streamedData.clear(); return false; } prepareViewStateRestoringOnReload(); QTextStream stream(&buffer); QString text = stream.readAll(); disconnect(m_widget, &KMarkdownView::renderingDone, this, &MarkdownPart::restoreScrollPosition); connect(m_widget, &KMarkdownView::renderingDone, this, &MarkdownPart::restoreScrollPosition); m_sourceDocument->setText(text); m_streamedData.clear(); return true; } bool MarkdownPart::closeUrl() { // protect against repeated call if already closed const auto currentUrl = url(); if (currentUrl.isValid()) { m_previousScrollPosition = m_widget->scrollPosition(); m_previousUrl = currentUrl; } m_sourceDocument->setText(QString()); m_streamedData.clear(); return ReadOnlyPart::closeUrl(); } void MarkdownPart::prepareViewStateRestoringOnReload() { if (url() == m_previousUrl) { KParts::OpenUrlArguments args(arguments()); args.setXOffset(m_previousScrollPosition.x()); args.setYOffset(m_previousScrollPosition.y()); setArguments(args); } } void MarkdownPart::restoreScrollPosition() { const KParts::OpenUrlArguments args(arguments()); m_widget->setScrollPosition(args.xOffset(), args.yOffset()); disconnect(m_widget, &KMarkdownView::renderingDone, this, &MarkdownPart::restoreScrollPosition); } void MarkdownPart::handleOpenUrlRequest(const QUrl& url) { QDesktopServices::openUrl(url); } void MarkdownPart::requestContextMenu(const QPoint& globalPos, const QUrl& linkUrl, const QString& linkText, bool hasSelection, bool forcesNewWindow) { Q_UNUSED(forcesNewWindow); QMenu menu(m_widget); if (!linkUrl.isValid()) { if (hasSelection) { - menu.addAction(createCopySelectionAction(&menu)); + menu.addAction(m_copySelectionAction); + } else { + menu.addAction(m_selectAllAction); } } else { auto action = menu.addAction(i18n("Open Link")); connect(action, &QAction::triggered, this, [&] { handleOpenUrlRequest(linkUrl); }); menu.addSeparator(); if (linkUrl.scheme() == QLatin1String("mailto")) { menu.addAction(createCopyEmailAddressAction(&menu, linkUrl)); } else { if (!linkText.isEmpty()) { menu.addAction(createCopyLinkTextAction(&menu, linkText)); } menu.addAction(createCopyLinkUrlAction(&menu)); } } if (!menu.isEmpty()) { menu.exec(globalPos); } } -QAction* MarkdownPart::createCopySelectionAction(QObject* parent) +QAction* MarkdownPart::copySelectionAction() const { - auto action = KStandardAction::copy(parent); - action->setText(i18n("&Copy Text")); - connect(action, &QAction::triggered, this, &MarkdownPart::copySelection); - - return action; + return m_copySelectionAction; } QAction* MarkdownPart::createCopyEmailAddressAction(QObject* parent, const QUrl& mailtoUrl) { auto action = new QAction(parent); action->setText(i18n("&Copy Email Address")); connect(action, &QAction::triggered, parent, [&] { QMimeData* data = new QMimeData; data->setText(mailtoUrl.path()); QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard); }); return action; } QAction* MarkdownPart::createCopyLinkTextAction(QObject* parent, const QString& text) { auto action = new QAction(parent); action->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); action->setText(i18n("Copy Link &Text")); connect(action, &QAction::triggered, parent, [&] { QMimeData* data = new QMimeData; data->setText(text); QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard); }); return action; } QAction* MarkdownPart::createCopyLinkUrlAction(QObject* parent) { auto action = new QAction(parent); action->setText(i18n("Copy Link &URL")); connect(action, &QAction::triggered, this, &MarkdownPart::copyLinkUrl); return action; } QAction* MarkdownPart::createSaveLinkAsAction(QObject* parent) { auto action = new QAction(parent); action->setText(i18n("&Save Link As...")); connect(action, &QAction::triggered, this, &MarkdownPart::saveLinkAs); return action; } void MarkdownPart::copySelection() { m_widget->copySelection(); } void MarkdownPart::copyLinkUrl() { m_widget->copyLinkUrl(); } void MarkdownPart::saveLinkAs() { m_widget->saveLinkAs(); } void MarkdownPart::selectAll() { m_widget->selectAllText(); } diff --git a/src/kpart/markdownpart.h b/src/kpart/markdownpart.h index 5d7cee6..8f12816 100644 --- a/src/kpart/markdownpart.h +++ b/src/kpart/markdownpart.h @@ -1,100 +1,102 @@ /* * Copyright (C) 2017 by Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef MARKDOWNPART_H #define MARKDOWNPART_H // KF #include // Qt #include #include class MarkdownBrowserExtension; class MarkdownSourceDocument; class KMarkdownView; class KAboutData; class MarkdownPart : public KParts::ReadOnlyPart { Q_OBJECT public: enum Modus { ReadOnlyModus = 0, BrowserViewModus = 1 }; /** * Default constructor, with arguments as expected by MarkdownPartFactory */ MarkdownPart(QWidget* parentWidget, QObject* parent, const KAboutData& aboutData, Modus modus); /** * Destructor */ ~MarkdownPart() override; KMarkdownView* view() const; - QAction* createCopySelectionAction(QObject* parent); + QAction* copySelectionAction() const; QAction* createCopyEmailAddressAction(QObject* parent, const QUrl& mailtoUrl); QAction* createCopyLinkTextAction(QObject* parent, const QString& text); QAction* createCopyLinkUrlAction(QObject* parent); QAction* createSaveLinkAsAction(QObject* parent); void copySelection(); protected: // KParts::ReadOnlyPart API bool openFile() override; bool doOpenStream(const QString& mimeType) override; bool doWriteStream(const QByteArray& data) override; bool doCloseStream() override; bool closeUrl() override; private: - void setupActions(); + void setupActions(Modus modus); void prepareViewStateRestoringOnReload(); void restoreScrollPosition(); void handleOpenUrlRequest(const QUrl& url); void requestContextMenu(const QPoint& globalPos, const QUrl& linkUrl, const QString& linkText, bool hasSelection, bool forcesNewWindow); void copyLinkUrl(); void saveLinkAs(); void selectAll(); private: MarkdownSourceDocument* m_sourceDocument; KMarkdownView* m_widget; + QAction* m_copySelectionAction; + QAction* m_selectAllAction; MarkdownBrowserExtension* const m_browserExtension; QByteArray m_streamedData; QUrl m_previousUrl; QPoint m_previousScrollPosition; }; inline KMarkdownView* MarkdownPart::view() const { return m_widget; } #endif diff --git a/src/lib/kmarkdownview.cpp b/src/lib/kmarkdownview.cpp index 7ebd8ec..6594b8d 100644 --- a/src/lib/kmarkdownview.cpp +++ b/src/lib/kmarkdownview.cpp @@ -1,129 +1,138 @@ /* * Copyright (C) 2017 by Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "kmarkdownview.h" #ifndef USE_QTWEBKIT #include "kmarkdownviewpage.h" #endif #include "kabstractmarkdownsourcedocument.h" #include "kmarkdownhtmlview.h" // Qt #ifdef USE_QTWEBKIT #include #include #include #else #include #include #include #endif #include KMarkdownView::KMarkdownView(KAbstractMarkdownSourceDocument* sourceDocument, QWidget* parent) #ifdef USE_QTWEBKIT : QWebView(parent) #else : QWebEngineView(parent) , m_viewPage(new KMarkdownViewPage(new QWebEngineProfile(this), this)) #endif , m_htmlView(new KMarkdownHtmlView(this)) , m_sourceDocument(sourceDocument) { #ifdef USE_QTWEBKIT auto page = this->page(); page->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); connect(this, &QWebView::linkClicked, this, &KMarkdownView::openUrlRequested); #else setPage(m_viewPage); connect(m_viewPage, &KMarkdownViewPage::openUrlRequested, this, &KMarkdownView::openUrlRequested); #endif + auto copyAction = pageAction(WebPage::Copy); + connect(copyAction, &QAction::changed, this, [&] { + emit copyTextEnabledChanged(pageAction(WebPage::Copy)->isEnabled()); + }); + auto selectAllAction = pageAction(WebPage::SelectAll); + connect(selectAllAction, &QAction::changed, this, [&] { + emit selectAllEnabledChanged(pageAction(WebPage::SelectAll)->isEnabled()); + }); + #ifdef USE_QTWEBKIT auto frame = page->mainFrame(); frame->addToJavaScriptWindowObject(QStringLiteral("sourceTextObject"), m_sourceDocument); frame->addToJavaScriptWindowObject(QStringLiteral("viewObject"), m_htmlView); #else QWebChannel* channel = new QWebChannel(this); channel->registerObject(QStringLiteral("sourceTextObject"), m_sourceDocument); channel->registerObject(QStringLiteral("viewObject"), m_htmlView); m_viewPage->setWebChannel(channel); #endif connect(m_htmlView, &KMarkdownHtmlView::renderingDone, this, &KMarkdownView::renderingDone); setUrl(QUrl(QStringLiteral("qrc:/kmarkdownwebview/index.html"))); } KMarkdownView::~KMarkdownView() = default; QPoint KMarkdownView::scrollPosition() const { return m_htmlView->scrollPosition(); } void KMarkdownView::setScrollPosition(int x, int y) { m_htmlView->requestSetScrollPosition(x, y); } void KMarkdownView::renderPage(QPainter* painter, const QRect& clip) { #ifdef USE_QTWEBKIT auto mainFrame = page()->mainFrame(); page()->setViewportSize(mainFrame->contentsSize()); mainFrame->render(painter, QWebFrame::ContentsLayer, clip); #else Q_UNUSED(painter); Q_UNUSED(clip); // TODO: used for thumbnailing of page, but QtWebEngine seems to not yet support offscreen rendering #endif } void KMarkdownView::contextMenuEvent(QContextMenuEvent* event) { #ifdef USE_QTWEBKIT QWebHitTestResult result = page()->mainFrame()->hitTestContent(event->pos()); #else QWebEngineContextMenuData result = page()->contextMenuData(); #endif // default menu arguments bool forcesNewWindow = false; bool hasSelection = false; if (!result.linkUrl().isValid()) { #ifdef USE_QTWEBKIT hasSelection = result.isContentSelected(); #else hasSelection = result.selectedText().isEmpty(); #endif } else { #ifdef USE_QTWEBKIT // Show the OpenInThisWindow context menu item forcesNewWindow = (page()->currentFrame() != result.linkTargetFrame()); #endif } emit contextMenuRequested(event->globalPos(), result.linkUrl(), result.linkText(), hasSelection, forcesNewWindow); event->accept(); } diff --git a/src/lib/kmarkdownview.h b/src/lib/kmarkdownview.h index a7f2e7f..e1e77e4 100644 --- a/src/lib/kmarkdownview.h +++ b/src/lib/kmarkdownview.h @@ -1,115 +1,123 @@ /* * Copyright (C) 2017 by Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KMARKDOWNVIEW_H #define KMARKDOWNVIEW_H #include #include // Qt headers #ifdef USE_QTWEBKIT #include #else #include #endif #include class KMarkdownViewPage; class KAbstractMarkdownSourceDocument; class KMarkdownHtmlView; class QUrl; class KMARKDOWNVIEW_EXPORT KMarkdownView : public #ifdef USE_QTWEBKIT QWebView #else QWebEngineView #endif { Q_OBJECT public: #ifdef USE_QTWEBKIT typedef QWebPage WebPage; #else typedef QWebEnginePage WebPage; #endif public: explicit KMarkdownView(KAbstractMarkdownSourceDocument* sourceDocument, QWidget* parent = nullptr); ~KMarkdownView() override; public: void copySelection(); void copyLinkUrl(); void saveLinkAs(); void selectAllText(); - bool canCopyText() const; + bool isCopyTextEnabled() const; + bool isSelectAllEnabled() const; QPoint scrollPosition() const; void setScrollPosition(int x, int y); void renderPage(QPainter* painter, const QRect& clip); Q_SIGNALS: + void copyTextEnabledChanged(bool enabled); + void selectAllEnabledChanged(bool enabled); void openUrlRequested(const QUrl& url); void contextMenuRequested(const QPoint& globalPos, const QUrl& linkUrl, const QString& linkText, bool hasSelection, bool forcesNewWindow); void renderingDone(); protected: void contextMenuEvent(QContextMenuEvent* event) override; private: #ifdef USE_QTWEBKIT void openUrlExternally(const QUrl& url); #endif private: #ifndef USE_QTWEBKIT KMarkdownViewPage* m_viewPage = nullptr; #endif KMarkdownHtmlView* const m_htmlView; KAbstractMarkdownSourceDocument* const m_sourceDocument; }; inline void KMarkdownView::copySelection() { triggerPageAction(WebPage::Copy); } inline void KMarkdownView::copyLinkUrl() { triggerPageAction(WebPage::CopyLinkToClipboard); } inline void KMarkdownView::saveLinkAs() { triggerPageAction(WebPage::DownloadLinkToDisk); } inline void KMarkdownView::selectAllText() { triggerPageAction(WebPage::SelectAll); } -inline bool KMarkdownView::canCopyText() const +inline bool KMarkdownView::isCopyTextEnabled() const { return pageAction(WebPage::Copy)->isEnabled(); } +inline bool KMarkdownView::isSelectAllEnabled() const +{ + return pageAction(WebPage::SelectAll)->isEnabled(); +} + #endif