MarkdownView: Merge into TextEditor

Make it a bit more compact, too.

Change-Id: I448164371c5a1d6969a292feba17caa2826f58c3
Reviewed-by: Tasuku Suzuki <tasuku.suzuki@signal-slot.co.jp>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2023-02-20 08:56:33 +01:00
parent efc4a0f1af
commit dce7025969
24 changed files with 118 additions and 506 deletions

View File

@@ -6,7 +6,6 @@ add_subdirectory(texteditor)
add_subdirectory(serialterminal)
add_subdirectory(helloworld)
add_subdirectory(imageviewer)
add_subdirectory(markdownviewer)
add_subdirectory(marketplace)
add_subdirectory(updateinfo)
add_subdirectory(welcome)

View File

@@ -1,12 +0,0 @@
add_qtc_plugin(MarkdownViewer
PLUGIN_DEPENDS Core TextEditor
SOURCES
markdownbrowser.cpp markdownbrowser.h
markdowndocument.cpp markdowndocument.h
markdowneditor.cpp markdowneditor.h
markdownviewer.cpp markdownviewer.h
markdownviewerconstants.h
markdownviewerfactory.cpp markdownviewerfactory.h
markdownviewerplugin.cpp markdownviewerplugin.h
markdownviewerwidget.cpp markdownviewerwidget.h
)

View File

@@ -1,18 +0,0 @@
{
\"Name\" : \"MarkdownViewer\",
\"Version\" : \"$$QTCREATOR_VERSION\",
\"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
\"Vendor\" : \"Signal Slot Inc.\",
\"Copyright\" : \"(C) 2023 Tasuku Suzuki\",
\"License\" : [ \"Commercial Usage\",
\"\",
\"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt 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.\",
\"\",
\"GNU General Public License Usage\",
\"\",
\"Alternatively, this plugin 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 plugin. 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.\"
],
\"Description\" : \"Markdown Viewer component.\",
\"Url\" : \"https://signal-slot.co.jp/\",
$$dependencyList
}

View File

@@ -1,32 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "markdownbrowser.h"
#include <QScrollBar>
namespace Markdown {
namespace Internal {
MarkdownBrowser::MarkdownBrowser(QWidget *parent)
: QTextBrowser(parent)
{}
void MarkdownBrowser::setMarkdown(const QString &markdown)
{
QHash<QScrollBar *, int> positions;
const auto scrollBars = findChildren<QScrollBar *>();
// save scroll positions
for (const auto scrollBar : scrollBars)
positions.insert(scrollBar, scrollBar->value());
QTextBrowser::setMarkdown(markdown);
// restore scroll positions
for (auto scrollBar : scrollBars)
scrollBar->setValue(positions.value(scrollBar));
}
} // namespace Internal
} // namespace Markdown

View File

@@ -1,24 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <QTextBrowser>
namespace Core { class IDocument; }
namespace Markdown {
namespace Internal {
class MarkdownBrowser : public QTextBrowser
{
Q_OBJECT
public:
explicit MarkdownBrowser(QWidget *parent = nullptr);
public slots:
void setMarkdown(const QString &markdown);
};
} // namespace Internal
} // namespace Markdown

View File

@@ -1,18 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "markdowndocument.h"
#include "markdownviewerconstants.h"
namespace Markdown {
namespace Internal {
MarkdownDocument::MarkdownDocument()
{
setId(Constants::MARKDOWNVIEWER_ID);
setMimeType(QLatin1String(Constants::MARKDOWNVIEWER_MIME_TYPE));
connect(this, &MarkdownDocument::mimeTypeChanged, this, &MarkdownDocument::changed);
}
} // namespace Internal
} // namespace Markdown

View File

@@ -1,19 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <texteditor/textdocument.h>
namespace Markdown {
namespace Internal {
class MarkdownDocument : public TextEditor::TextDocument
{
Q_OBJECT
public:
MarkdownDocument();
};
} // namespace Internal
} // namespace Markdown

View File

@@ -1,28 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "markdowneditor.h"
#include "markdownviewerconstants.h"
#include "markdowndocument.h"
#include <coreplugin/icore.h>
#include <texteditor/textdocument.h>
namespace Markdown {
namespace Internal {
MarkdownEditor::MarkdownEditor(QWidget *parent)
: TextEditor::TextEditorWidget(parent)
{
setTextDocument(TextEditor::TextDocumentPtr(new MarkdownDocument));
setupGenericHighlighter();
setMarksVisible(false);
auto context = new Core::IContext(this);
context->setWidget(this);
context->setContext(Core::Context(Constants::MARKDOWNVIEWER_EDITOR_CONTEXT));
Core::ICore::addContextObject(context);
}
} // namespace Internal
} // namespace Markdown

View File

@@ -1,19 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <texteditor/texteditor.h>
namespace Markdown {
namespace Internal {
class MarkdownEditor : public TextEditor::TextEditorWidget
{
Q_OBJECT
public:
MarkdownEditor(QWidget *parent = nullptr);
};
} // namespace Internal
} // namespace Markdown

View File

@@ -1,86 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "markdownviewer.h"
#include "markdownviewerconstants.h"
#include "markdownviewerwidget.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/actionmanager/commandbutton.h>
#include <coreplugin/editormanager/editormanager.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <QFileInfo>
#include <QDesktopServices>
#include <QWidget>
#include <QHBoxLayout>
namespace Markdown {
namespace Internal {
struct MarkdownViewerPrivate
{
MarkdownViewerWidget *widget;
QWidget *toolbar;
QToolButton *toggleEditorVisible;
};
MarkdownViewer::MarkdownViewer()
: d(new MarkdownViewerPrivate)
{
ctor();
}
void MarkdownViewer::ctor()
{
d->widget = new MarkdownViewerWidget;
setContext(Core::Context(Constants::MARKDOWNVIEWER_ID));
setWidget(d->widget);
d->toolbar = new QWidget;
auto layout = new QHBoxLayout;
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
layout->addStretch();
d->toggleEditorVisible = new QToolButton;
d->toggleEditorVisible->setText(tr("Hide Editor"));
d->toggleEditorVisible->setCheckable(true);
d->toggleEditorVisible->setChecked(true);
layout->addWidget(d->toggleEditorVisible);
d->toolbar->setLayout(layout);
// connections
connect(d->toggleEditorVisible, &QToolButton::toggled, d->widget, &MarkdownViewerWidget::setEditorVisible);
connect(d->widget, &MarkdownViewerWidget::editorVisibleChanged, this, [this](bool editorVisible) {
d->toggleEditorVisible->setText(editorVisible ? tr("Hide Editor") : tr("Show Editor"));
});
}
MarkdownViewer::~MarkdownViewer()
{
delete d->widget;
delete d->toolbar;
delete d;
}
Core::IDocument *MarkdownViewer::document() const
{
return d->widget->document();
}
QWidget *MarkdownViewer::toolBar()
{
return d->toolbar;
}
} // namespace Internal
} // namespace Markdown

View File

@@ -1,30 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/idocument.h>
namespace Markdown {
namespace Internal {
class MarkdownDocument;
class MarkdownViewer : public Core::IEditor
{
Q_OBJECT
public:
explicit MarkdownViewer();
~MarkdownViewer() override;
Core::IDocument *document() const override;
QWidget *toolBar() override;
private:
void ctor();
struct MarkdownViewerPrivate *d;
};
} // namespace Internal
} // namespace Markdown

View File

@@ -1,27 +0,0 @@
import qbs 1.0
QtcPlugin {
name: "MarkdownViewer"
Depends { name: "Qt.widgets" }
Depends { name: "Core" }
Depends { name: "TextEditor" }
files: [
"markdownbrowser.cpp",
"markdownbrowser.h",
"markdowndocument.cpp",
"markdowndocument.h",
"markdowneditor.cpp",
"markdowneditor.h",
"markdownviewer.cpp",
"markdownviewer.h",
"markdownviewerconstants.h",
"markdownviewerfactory.cpp",
"markdownviewerfactory.h",
"markdownviewerplugin.cpp",
"markdownviewerplugin.h",
"markdownviewerwidget.cpp",
"markdownviewerwidget.h",
]
}

View File

@@ -1,17 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <qglobal.h>
namespace Markdown {
namespace Constants {
const char MARKDOWNVIEWER_ID[] = "Editors.MarkdownViewer";
const char MARKDOWNVIEWER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("OpenWith::Editors", "Markdown Viewer");
const char MARKDOWNVIEWER_MIME_TYPE[] = "text/markdown";
const char MARKDOWNVIEWER_EDITOR_CONTEXT[] = "Editors.MarkdownViewer.Id";
} // namespace Constants
} // namespace Markdown

View File

@@ -1,22 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "markdownviewerfactory.h"
#include "markdownviewerconstants.h"
#include "markdownviewer.h"
#include <QCoreApplication>
namespace Markdown {
namespace Internal {
MarkdownViewerFactory::MarkdownViewerFactory()
{
setId(Constants::MARKDOWNVIEWER_ID);
setDisplayName(QCoreApplication::translate("OpenWith::Editors", Constants::MARKDOWNVIEWER_DISPLAY_NAME));
addMimeType(Constants::MARKDOWNVIEWER_MIME_TYPE);
setEditorCreator([] { return new MarkdownViewer(); });
}
} // namespace Internal
} // namespace Markdown

View File

@@ -1,25 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "markdownviewerplugin.h"
#include "markdownviewerfactory.h"
#include <extensionsystem/pluginmanager.h>
using namespace Core;
namespace Markdown {
namespace Internal {
bool MarkdownViewerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
Q_UNUSED(arguments)
Q_UNUSED(errorMessage)
ExtensionSystem::PluginManager::addObject(new MarkdownViewerFactory);
return true;
}
} // namespace Internal
} // namespace Markdown

View File

@@ -1,26 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <extensionsystem/iplugin.h>
namespace Markdown {
namespace Internal {
class MarkdownViewerPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "MarkdownViewer.json")
public:
MarkdownViewerPlugin() = default;
~MarkdownViewerPlugin() = default;
private:
bool initialize(const QStringList &arguments, QString *errorMessage) final;
void extensionsInitialized() final {}
};
} // namespace Internal
} // namespace Markdown

View File

@@ -1,58 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "markdownviewerwidget.h"
#include "markdowneditor.h"
#include "markdownbrowser.h"
#include <texteditor/textdocument.h>
namespace Markdown {
namespace Internal {
struct MarkdownViewerWidgetPrivate
{
MarkdownBrowser *browser;
MarkdownEditor *editor;
};
MarkdownViewerWidget::MarkdownViewerWidget()
: d(new MarkdownViewerWidgetPrivate)
{
d->browser = new MarkdownBrowser(this);
d->browser->setOpenExternalLinks(true);
d->browser->setFrameShape(QFrame::NoFrame);
d->editor = new MarkdownEditor(this);
connect(d->editor->document(), &QTextDocument::contentsChanged,
this, [this]() {
const auto plainText = d->editor->textDocument()->plainText();
d->browser->setMarkdown(plainText);
});
}
MarkdownViewerWidget::~MarkdownViewerWidget()
{
delete d;
}
Core::IDocument *MarkdownViewerWidget::document() const
{
return d->editor->textDocument();
}
bool MarkdownViewerWidget::isEditorVisible() const
{
return d->editor->isVisible();
}
void MarkdownViewerWidget::setEditorVisible(bool editorVisible)
{
if (d->editor->isVisible() == editorVisible)
return;
d->editor->setVisible(editorVisible);
emit editorVisibleChanged(editorVisible);
}
} // namespace Internal
} // namespace Markdown

View File

@@ -1,37 +0,0 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <coreplugin/minisplitter.h>
#include <utils/fileutils.h>
namespace Core { class IDocument; }
namespace Markdown {
namespace Internal {
class MarkdownViewerWidget : public Core::MiniSplitter
{
Q_OBJECT
Q_PROPERTY(bool editorVisible READ isEditorVisible WRITE setEditorVisible NOTIFY editorVisibleChanged)
public:
explicit MarkdownViewerWidget();
~MarkdownViewerWidget() override;
Core::IDocument *document() const;
bool isEditorVisible() const;
public slots:
void setEditorVisible(bool editorVisible);
signals:
void editorVisibleChanged(bool editorVisible);
private:
struct MarkdownViewerWidgetPrivate *d;
};
} // namespace Internal
} // namespace Markdown

View File

@@ -50,7 +50,6 @@ Project {
"ios/ios.qbs",
"languageclient/languageclient.qbs",
"macros/macros.qbs",
"markdownviewer/markdownviewer.qbs",
"marketplace/marketplace.qbs",
"mcusupport/mcusupport.qbs",
"mercurial/mercurial.qbs",

View File

@@ -70,6 +70,7 @@ add_qtc_plugin(TextEditor
ioutlinewidget.h
linenumberfilter.cpp linenumberfilter.h
marginsettings.cpp marginsettings.h
markdowneditor.cpp markdowneditor.h
outlinefactory.cpp outlinefactory.h
plaintexteditorfactory.cpp plaintexteditorfactory.h
quickfix.cpp quickfix.h

View File

@@ -0,0 +1,109 @@
// Copyright (C) 2023 Tasuku Suzuki
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "markdowneditor.h"
#include "textdocument.h"
#include "texteditor.h"
#include "texteditortr.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/coreplugintr.h>
#include <coreplugin/minisplitter.h>
#include <QHBoxLayout>
#include <QScrollBar>
#include <QTextBrowser>
#include <QToolButton>
namespace TextEditor::Internal {
const char MARKDOWNVIEWER_ID[] = "Editors.MarkdownViewer";
const char MARKDOWNVIEWER_MIME_TYPE[] = "text/markdown";
const char MARKDOWNVIEWER_EDITOR_CONTEXT[] = "Editors.MarkdownViewer.Id";
class MarkdownEditor : public Core::IEditor
{
public:
MarkdownEditor()
: m_document(new TextDocument(MARKDOWNVIEWER_ID))
{
m_document->setMimeType(MARKDOWNVIEWER_MIME_TYPE);
// Left side
auto browser = new QTextBrowser(&m_widget);
browser->setOpenExternalLinks(true);
browser->setFrameShape(QFrame::NoFrame);
// Right side (hidable)
auto editor = new TextEditorWidget(&m_widget);
editor->setTextDocument(m_document);
editor->setupGenericHighlighter();
editor->setMarksVisible(false);
auto context = new Core::IContext(this);
context->setWidget(editor);
context->setContext(Core::Context(MARKDOWNVIEWER_EDITOR_CONTEXT));
Core::ICore::addContextObject(context);
setContext(Core::Context(MARKDOWNVIEWER_ID));
setWidget(&m_widget);
auto toggleEditorVisible = new QToolButton;
toggleEditorVisible->setText(Tr::tr("Hide Editor"));
toggleEditorVisible->setCheckable(true);
toggleEditorVisible->setChecked(true);
auto layout = new QHBoxLayout(&m_toolbar);
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
layout->addStretch();
layout->addWidget(toggleEditorVisible);
connect(m_document.data(), &TextDocument::mimeTypeChanged,
m_document.data(), &TextDocument::changed);
connect(toggleEditorVisible, &QToolButton::toggled,
editor, [editor, toggleEditorVisible](bool editorVisible) {
if (editor->isVisible() == editorVisible)
return;
editor->setVisible(editorVisible);
toggleEditorVisible->setText(editorVisible ? Tr::tr("Hide Editor") : Tr::tr("Show Editor"));
});
connect(m_document->document(), &QTextDocument::contentsChanged, this, [this, browser] {
QHash<QScrollBar *, int> positions;
const auto scrollBars = findChildren<QScrollBar *>();
// save scroll positions
for (QScrollBar *scrollBar : scrollBars)
positions.insert(scrollBar, scrollBar->value());
browser->setMarkdown(m_document->plainText());
// restore scroll positions
for (QScrollBar *scrollBar : scrollBars)
scrollBar->setValue(positions.value(scrollBar));
});
}
QWidget *toolBar() override { return &m_toolbar; }
Core::IDocument *document() const override { return m_document.data(); }
private:
Core::MiniSplitter m_widget;
TextDocumentPtr m_document;
QWidget m_toolbar;
};
MarkdownEditorFactory::MarkdownEditorFactory()
{
setId(MARKDOWNVIEWER_ID);
setDisplayName(::Core::Tr::tr("Markdown Viewer"));
addMimeType(MARKDOWNVIEWER_MIME_TYPE);
setEditorCreator([] { return new MarkdownEditor; });
}
} // TextEditor::Internal

View File

@@ -5,14 +5,12 @@
#include <coreplugin/editormanager/ieditorfactory.h>
namespace Markdown {
namespace Internal {
namespace TextEditor::Internal {
class MarkdownViewerFactory final : public Core::IEditorFactory
class MarkdownEditorFactory final : public Core::IEditorFactory
{
public:
MarkdownViewerFactory();
MarkdownEditorFactory();
};
} // namespace Internal
} // namespace Markdown
} // TextEditor::Internal

View File

@@ -94,6 +94,8 @@ Project {
"linenumberfilter.h",
"marginsettings.cpp",
"marginsettings.h",
"markdowneditor.cpp",
"markdowneditor.h",
"outlinefactory.cpp",
"outlinefactory.h",
"plaintexteditorfactory.cpp",

View File

@@ -10,6 +10,7 @@
#include "highlighter.h"
#include "icodestylepreferences.h"
#include "linenumberfilter.h"
#include "markdowneditor.h"
#include "outlinefactory.h"
#include "plaintexteditorfactory.h"
#include "snippets/snippetprovider.h"
@@ -66,6 +67,7 @@ public:
FindInOpenFiles findInOpenFilesFilter;
PlainTextEditorFactory plainTextEditorFactory;
MarkdownEditorFactory markdownEditorFactory;
};
static TextEditorPlugin *m_instance = nullptr;