feat: add missing KF6 framework recipes
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
ecm_optional_add_subdirectory(codeeditor)
|
||||
ecm_optional_add_subdirectory(codepdfprinter)
|
||||
ecm_optional_add_subdirectory(minimaltest)
|
||||
@@ -0,0 +1,4 @@
|
||||
if(TARGET Qt6::Widgets)
|
||||
add_executable(codeeditor codeeditor.cpp main.cpp)
|
||||
target_link_libraries(codeeditor Qt6::Widgets KF6SyntaxHighlighting)
|
||||
endif()
|
||||
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "codeeditor.h"
|
||||
|
||||
#include <KSyntaxHighlighting/Definition>
|
||||
#include <KSyntaxHighlighting/FoldingRegion>
|
||||
#include <KSyntaxHighlighting/SyntaxHighlighter>
|
||||
#include <KSyntaxHighlighting/Theme>
|
||||
|
||||
#include <QActionGroup>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QFileDialog>
|
||||
#include <QFontDatabase>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QPalette>
|
||||
|
||||
class CodeEditorSidebar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CodeEditorSidebar(CodeEditor *editor);
|
||||
QSize sizeHint() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
CodeEditor *m_codeEditor;
|
||||
};
|
||||
|
||||
CodeEditorSidebar::CodeEditorSidebar(CodeEditor *editor)
|
||||
: QWidget(editor)
|
||||
, m_codeEditor(editor)
|
||||
{
|
||||
}
|
||||
|
||||
QSize CodeEditorSidebar::sizeHint() const
|
||||
{
|
||||
return QSize(m_codeEditor->sidebarWidth(), 0);
|
||||
}
|
||||
|
||||
void CodeEditorSidebar::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
m_codeEditor->sidebarPaintEvent(event);
|
||||
}
|
||||
|
||||
void CodeEditorSidebar::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->pos().x() >= width() - m_codeEditor->fontMetrics().lineSpacing()) {
|
||||
auto block = m_codeEditor->blockAtPosition(event->pos().y());
|
||||
if (!block.isValid() || !m_codeEditor->isFoldable(block)) {
|
||||
return;
|
||||
}
|
||||
m_codeEditor->toggleFold(block);
|
||||
}
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
CodeEditor::CodeEditor(QWidget *parent)
|
||||
: QPlainTextEdit(parent)
|
||||
, m_highlighter(new KSyntaxHighlighting::SyntaxHighlighter(document()))
|
||||
, m_sideBar(new CodeEditorSidebar(this))
|
||||
{
|
||||
setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||
|
||||
setTheme((palette().color(QPalette::Base).lightness() < 128) ? m_repository.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme)
|
||||
: m_repository.defaultTheme(KSyntaxHighlighting::Repository::LightTheme));
|
||||
|
||||
connect(this, &QPlainTextEdit::blockCountChanged, this, &CodeEditor::updateSidebarGeometry);
|
||||
connect(this, &QPlainTextEdit::updateRequest, this, &CodeEditor::updateSidebarArea);
|
||||
connect(this, &QPlainTextEdit::cursorPositionChanged, this, &CodeEditor::highlightCurrentLine);
|
||||
|
||||
updateSidebarGeometry();
|
||||
highlightCurrentLine();
|
||||
}
|
||||
|
||||
CodeEditor::~CodeEditor()
|
||||
{
|
||||
}
|
||||
|
||||
void CodeEditor::openFile(const QString &fileName)
|
||||
{
|
||||
QFile f(fileName);
|
||||
if (!f.open(QFile::ReadOnly)) {
|
||||
qWarning() << "Failed to open" << fileName << ":" << f.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
clear();
|
||||
|
||||
const auto def = m_repository.definitionForFileName(fileName);
|
||||
m_highlighter->setDefinition(def);
|
||||
|
||||
setWindowTitle(fileName);
|
||||
setPlainText(QString::fromUtf8(f.readAll()));
|
||||
}
|
||||
|
||||
void CodeEditor::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
auto menu = createStandardContextMenu(event->pos());
|
||||
menu->addSeparator();
|
||||
auto openAction = menu->addAction(QStringLiteral("Open File..."));
|
||||
connect(openAction, &QAction::triggered, this, [this]() {
|
||||
const auto fileName = QFileDialog::getOpenFileName(this, QStringLiteral("Open File"));
|
||||
if (!fileName.isEmpty()) {
|
||||
openFile(fileName);
|
||||
}
|
||||
});
|
||||
|
||||
// syntax selection
|
||||
auto hlActionGroup = new QActionGroup(menu);
|
||||
hlActionGroup->setExclusive(true);
|
||||
auto hlGroupMenu = menu->addMenu(QStringLiteral("Syntax"));
|
||||
QMenu *hlSubMenu = hlGroupMenu;
|
||||
QString currentGroup;
|
||||
for (const auto &def : m_repository.definitions()) {
|
||||
if (def.isHidden()) {
|
||||
continue;
|
||||
}
|
||||
if (currentGroup != def.section()) {
|
||||
currentGroup = def.section();
|
||||
hlSubMenu = hlGroupMenu->addMenu(def.translatedSection());
|
||||
}
|
||||
|
||||
Q_ASSERT(hlSubMenu);
|
||||
auto action = hlSubMenu->addAction(def.translatedName());
|
||||
action->setCheckable(true);
|
||||
action->setData(def.name());
|
||||
hlActionGroup->addAction(action);
|
||||
if (def.name() == m_highlighter->definition().name()) {
|
||||
action->setChecked(true);
|
||||
}
|
||||
}
|
||||
connect(hlActionGroup, &QActionGroup::triggered, this, [this](QAction *action) {
|
||||
const auto defName = action->data().toString();
|
||||
const auto def = m_repository.definitionForName(defName);
|
||||
m_highlighter->setDefinition(def);
|
||||
});
|
||||
|
||||
// theme selection
|
||||
auto themeGroup = new QActionGroup(menu);
|
||||
themeGroup->setExclusive(true);
|
||||
auto themeMenu = menu->addMenu(QStringLiteral("Theme"));
|
||||
for (const auto &theme : m_repository.themes()) {
|
||||
auto action = themeMenu->addAction(theme.translatedName());
|
||||
action->setCheckable(true);
|
||||
action->setData(theme.name());
|
||||
themeGroup->addAction(action);
|
||||
if (theme.name() == m_highlighter->theme().name()) {
|
||||
action->setChecked(true);
|
||||
}
|
||||
}
|
||||
connect(themeGroup, &QActionGroup::triggered, this, [this](QAction *action) {
|
||||
const auto themeName = action->data().toString();
|
||||
const auto theme = m_repository.theme(themeName);
|
||||
setTheme(theme);
|
||||
});
|
||||
|
||||
menu->exec(event->globalPos());
|
||||
delete menu;
|
||||
}
|
||||
|
||||
void CodeEditor::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QPlainTextEdit::resizeEvent(event);
|
||||
updateSidebarGeometry();
|
||||
}
|
||||
|
||||
void CodeEditor::setTheme(const KSyntaxHighlighting::Theme &theme)
|
||||
{
|
||||
auto pal = qApp->palette();
|
||||
if (theme.isValid()) {
|
||||
pal.setColor(QPalette::Base, theme.editorColor(KSyntaxHighlighting::Theme::BackgroundColor));
|
||||
pal.setColor(QPalette::Highlight, theme.editorColor(KSyntaxHighlighting::Theme::TextSelection));
|
||||
}
|
||||
setPalette(pal);
|
||||
|
||||
m_highlighter->setTheme(theme);
|
||||
m_highlighter->rehighlight();
|
||||
highlightCurrentLine();
|
||||
}
|
||||
|
||||
int CodeEditor::sidebarWidth() const
|
||||
{
|
||||
int digits = 1;
|
||||
auto count = blockCount();
|
||||
while (count >= 10) {
|
||||
++digits;
|
||||
count /= 10;
|
||||
}
|
||||
return 4 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits + fontMetrics().lineSpacing();
|
||||
}
|
||||
|
||||
void CodeEditor::sidebarPaintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(m_sideBar);
|
||||
painter.fillRect(event->rect(), m_highlighter->theme().editorColor(KSyntaxHighlighting::Theme::IconBorder));
|
||||
|
||||
auto block = firstVisibleBlock();
|
||||
auto blockNumber = block.blockNumber();
|
||||
int top = blockBoundingGeometry(block).translated(contentOffset()).top();
|
||||
int bottom = top + blockBoundingRect(block).height();
|
||||
const int currentBlockNumber = textCursor().blockNumber();
|
||||
|
||||
const auto foldingMarkerSize = fontMetrics().lineSpacing();
|
||||
|
||||
while (block.isValid() && top <= event->rect().bottom()) {
|
||||
if (block.isVisible() && bottom >= event->rect().top()) {
|
||||
const auto number = QString::number(blockNumber + 1);
|
||||
painter.setPen(m_highlighter->theme().editorColor((blockNumber == currentBlockNumber) ? KSyntaxHighlighting::Theme::CurrentLineNumber
|
||||
: KSyntaxHighlighting::Theme::LineNumbers));
|
||||
painter.drawText(0, top, m_sideBar->width() - 2 - foldingMarkerSize, fontMetrics().height(), Qt::AlignRight, number);
|
||||
}
|
||||
|
||||
// folding marker
|
||||
if (block.isVisible() && isFoldable(block)) {
|
||||
QPolygonF polygon;
|
||||
if (isFolded(block)) {
|
||||
polygon << QPointF(foldingMarkerSize * 0.4, foldingMarkerSize * 0.25);
|
||||
polygon << QPointF(foldingMarkerSize * 0.4, foldingMarkerSize * 0.75);
|
||||
polygon << QPointF(foldingMarkerSize * 0.8, foldingMarkerSize * 0.5);
|
||||
} else {
|
||||
polygon << QPointF(foldingMarkerSize * 0.25, foldingMarkerSize * 0.4);
|
||||
polygon << QPointF(foldingMarkerSize * 0.75, foldingMarkerSize * 0.4);
|
||||
polygon << QPointF(foldingMarkerSize * 0.5, foldingMarkerSize * 0.8);
|
||||
}
|
||||
painter.save();
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(QColor(m_highlighter->theme().editorColor(KSyntaxHighlighting::Theme::CodeFolding)));
|
||||
painter.translate(m_sideBar->width() - foldingMarkerSize, top);
|
||||
painter.drawPolygon(polygon);
|
||||
painter.restore();
|
||||
}
|
||||
|
||||
block = block.next();
|
||||
top = bottom;
|
||||
bottom = top + blockBoundingRect(block).height();
|
||||
++blockNumber;
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditor::updateSidebarGeometry()
|
||||
{
|
||||
setViewportMargins(sidebarWidth(), 0, 0, 0);
|
||||
const auto r = contentsRect();
|
||||
m_sideBar->setGeometry(QRect(r.left(), r.top(), sidebarWidth(), r.height()));
|
||||
}
|
||||
|
||||
void CodeEditor::updateSidebarArea(const QRect &rect, int dy)
|
||||
{
|
||||
if (dy) {
|
||||
m_sideBar->scroll(0, dy);
|
||||
} else {
|
||||
m_sideBar->update(0, rect.y(), m_sideBar->width(), rect.height());
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditor::highlightCurrentLine()
|
||||
{
|
||||
QTextEdit::ExtraSelection selection;
|
||||
selection.format.setBackground(QColor(m_highlighter->theme().editorColor(KSyntaxHighlighting::Theme::CurrentLine)));
|
||||
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||
selection.cursor = textCursor();
|
||||
selection.cursor.clearSelection();
|
||||
|
||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||
extraSelections.append(selection);
|
||||
setExtraSelections(extraSelections);
|
||||
}
|
||||
|
||||
QTextBlock CodeEditor::blockAtPosition(int y) const
|
||||
{
|
||||
auto block = firstVisibleBlock();
|
||||
if (!block.isValid()) {
|
||||
return QTextBlock();
|
||||
}
|
||||
|
||||
int top = blockBoundingGeometry(block).translated(contentOffset()).top();
|
||||
int bottom = top + blockBoundingRect(block).height();
|
||||
do {
|
||||
if (top <= y && y <= bottom) {
|
||||
return block;
|
||||
}
|
||||
block = block.next();
|
||||
top = bottom;
|
||||
bottom = top + blockBoundingRect(block).height();
|
||||
} while (block.isValid());
|
||||
return QTextBlock();
|
||||
}
|
||||
|
||||
bool CodeEditor::isFoldable(const QTextBlock &block) const
|
||||
{
|
||||
return m_highlighter->startsFoldingRegion(block);
|
||||
}
|
||||
|
||||
bool CodeEditor::isFolded(const QTextBlock &block) const
|
||||
{
|
||||
if (!block.isValid()) {
|
||||
return false;
|
||||
}
|
||||
const auto nextBlock = block.next();
|
||||
if (!nextBlock.isValid()) {
|
||||
return false;
|
||||
}
|
||||
return !nextBlock.isVisible();
|
||||
}
|
||||
|
||||
void CodeEditor::toggleFold(const QTextBlock &startBlock)
|
||||
{
|
||||
// we also want to fold the last line of the region, therefore the ".next()"
|
||||
const auto endBlock = m_highlighter->findFoldingRegionEnd(startBlock).next();
|
||||
|
||||
if (isFolded(startBlock)) {
|
||||
// unfold
|
||||
auto block = startBlock.next();
|
||||
while (block.isValid() && !block.isVisible()) {
|
||||
block.setVisible(true);
|
||||
block.setLineCount(block.layout()->lineCount());
|
||||
block = block.next();
|
||||
}
|
||||
|
||||
} else {
|
||||
// fold
|
||||
auto block = startBlock.next();
|
||||
while (block.isValid() && block != endBlock) {
|
||||
block.setVisible(false);
|
||||
block.setLineCount(0);
|
||||
block = block.next();
|
||||
}
|
||||
}
|
||||
|
||||
// redraw document
|
||||
document()->markContentsDirty(startBlock.position(), endBlock.position() - startBlock.position() + 1);
|
||||
|
||||
// update scrollbars
|
||||
Q_EMIT document()->documentLayout()->documentSizeChanged(document()->documentLayout()->documentSize());
|
||||
}
|
||||
|
||||
#include "codeeditor.moc"
|
||||
#include "moc_codeeditor.cpp"
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef CODEEDITOR_H
|
||||
#define CODEEDITOR_H
|
||||
|
||||
#include <KSyntaxHighlighting/Repository>
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
namespace KSyntaxHighlighting
|
||||
{
|
||||
class SyntaxHighlighter;
|
||||
}
|
||||
|
||||
class CodeEditorSidebar;
|
||||
|
||||
class CodeEditor : public QPlainTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CodeEditor(QWidget *parent = nullptr);
|
||||
~CodeEditor() override;
|
||||
|
||||
void openFile(const QString &fileName);
|
||||
|
||||
protected:
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
friend class CodeEditorSidebar;
|
||||
void setTheme(const KSyntaxHighlighting::Theme &theme);
|
||||
int sidebarWidth() const;
|
||||
void sidebarPaintEvent(QPaintEvent *event);
|
||||
void updateSidebarGeometry();
|
||||
void updateSidebarArea(const QRect &rect, int dy);
|
||||
void highlightCurrentLine();
|
||||
|
||||
QTextBlock blockAtPosition(int y) const;
|
||||
bool isFoldable(const QTextBlock &block) const;
|
||||
bool isFolded(const QTextBlock &block) const;
|
||||
void toggleFold(const QTextBlock &block);
|
||||
|
||||
KSyntaxHighlighting::Repository m_repository;
|
||||
KSyntaxHighlighting::SyntaxHighlighter *m_highlighter;
|
||||
CodeEditorSidebar *m_sideBar;
|
||||
};
|
||||
|
||||
#endif // CODEEDITOR_H
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "codeeditor.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.addHelpOption();
|
||||
parser.addPositionalArgument(QStringLiteral("source"), QStringLiteral("The source file to highlight."));
|
||||
parser.process(app);
|
||||
|
||||
CodeEditor edit;
|
||||
edit.resize(1024, 1024);
|
||||
edit.show();
|
||||
if (parser.positionalArguments().size() == 1) {
|
||||
edit.openFile(parser.positionalArguments().at(0));
|
||||
}
|
||||
return app.exec();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
if(TARGET Qt6::Widgets AND TARGET Qt6::PrintSupport)
|
||||
add_executable(codepdfprinter codepdfprinter.cpp main.cpp)
|
||||
target_link_libraries(codepdfprinter Qt6::Widgets Qt6::PrintSupport KF6SyntaxHighlighting)
|
||||
endif()
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2019 Friedrich W. H. Kossebau <kossebau@kde.org>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "codepdfprinter.h"
|
||||
|
||||
#include <KSyntaxHighlighting/Definition>
|
||||
#include <KSyntaxHighlighting/SyntaxHighlighter>
|
||||
#include <KSyntaxHighlighting/Theme>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QFontDatabase>
|
||||
#include <QFontMetrics>
|
||||
#include <QPrinter>
|
||||
|
||||
CodePdfPrinter::CodePdfPrinter()
|
||||
: m_highlighter(new KSyntaxHighlighting::SyntaxHighlighter(&m_document))
|
||||
{
|
||||
const auto font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
||||
const QFontMetrics fontMetrics(font);
|
||||
m_document.setDefaultFont(font);
|
||||
|
||||
QTextOption textOption(Qt::AlignTop | Qt::AlignLeft);
|
||||
textOption.setTabStopDistance(8 * fontMetrics.horizontalAdvance(QLatin1Char(' ')));
|
||||
textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
|
||||
m_document.setDefaultTextOption(textOption);
|
||||
|
||||
// light theme for "printing" on white PDF "paper"
|
||||
const auto theme = m_repository.defaultTheme(KSyntaxHighlighting::Repository::LightTheme);
|
||||
m_highlighter->setTheme(theme);
|
||||
}
|
||||
|
||||
CodePdfPrinter::~CodePdfPrinter() = default;
|
||||
|
||||
bool CodePdfPrinter::openSourceFile(const QString &fileName)
|
||||
{
|
||||
QFile f(fileName);
|
||||
if (!f.open(QFile::ReadOnly)) {
|
||||
qWarning() << "Failed to open" << fileName << ":" << f.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto def = m_repository.definitionForFileName(fileName);
|
||||
m_highlighter->setDefinition(def);
|
||||
|
||||
m_document.setPlainText(QString::fromUtf8(f.readAll()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void CodePdfPrinter::printPdfFile(const QString &fileName)
|
||||
{
|
||||
QPrinter printer(QPrinter::PrinterResolution);
|
||||
printer.setOutputFormat(QPrinter::PdfFormat);
|
||||
printer.setPageSize(QPageSize(QPageSize::A4));
|
||||
printer.setOutputFileName(fileName);
|
||||
|
||||
m_document.print(&printer);
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2019 Friedrich W. H. Kossebau <kossebau@kde.org>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef CODEPDFPRINTER_H
|
||||
#define CODEPDFPRINTER_H
|
||||
|
||||
#include <KSyntaxHighlighting/Repository>
|
||||
|
||||
#include <QTextDocument>
|
||||
|
||||
namespace KSyntaxHighlighting
|
||||
{
|
||||
class SyntaxHighlighter;
|
||||
}
|
||||
|
||||
class CodePdfPrinter
|
||||
{
|
||||
public:
|
||||
explicit CodePdfPrinter();
|
||||
~CodePdfPrinter();
|
||||
|
||||
public:
|
||||
bool openSourceFile(const QString &fileName);
|
||||
void printPdfFile(const QString &fileName);
|
||||
|
||||
private:
|
||||
QTextDocument m_document;
|
||||
|
||||
KSyntaxHighlighting::Repository m_repository;
|
||||
KSyntaxHighlighting::SyntaxHighlighter *m_highlighter;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2019 Friedrich W. H. Kossebau <kossebau@kde.org>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "codepdfprinter.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.addHelpOption();
|
||||
parser.addPositionalArgument(QStringLiteral("source"), QStringLiteral("The source file to print."));
|
||||
parser.addPositionalArgument(QStringLiteral("pdf"), QStringLiteral("The PDF file to print to."));
|
||||
parser.process(app);
|
||||
|
||||
if (parser.positionalArguments().size() < 2) {
|
||||
parser.showHelp();
|
||||
}
|
||||
|
||||
CodePdfPrinter printer;
|
||||
if (printer.openSourceFile(parser.positionalArguments().at(0))) {
|
||||
printer.printPdfFile(parser.positionalArguments().at(1));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2018 Eike Hein <hein@kde.org>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls as QQC2
|
||||
import org.kde.syntaxhighlighting
|
||||
|
||||
QQC2.ScrollView {
|
||||
width: 250
|
||||
height: 250
|
||||
|
||||
QQC2.TextArea {
|
||||
id: myText
|
||||
|
||||
text: "int foo = 0;"
|
||||
wrapMode: TextEdit.Wrap
|
||||
focus: true
|
||||
|
||||
Kirigami.SpellCheck.enabled: false
|
||||
|
||||
SyntaxHighlighter {
|
||||
textEdit: myText
|
||||
definition: "C++"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
if(TARGET Qt6::Widgets)
|
||||
add_executable(minimal main.cpp)
|
||||
target_link_libraries(minimal Qt6::Widgets KF6SyntaxHighlighting)
|
||||
endif()
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QDebug>
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
#include <KSyntaxHighlighting/Definition>
|
||||
#include <KSyntaxHighlighting/FoldingRegion>
|
||||
#include <KSyntaxHighlighting/Repository>
|
||||
#include <KSyntaxHighlighting/SyntaxHighlighter>
|
||||
#include <KSyntaxHighlighting/Theme>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.addHelpOption();
|
||||
parser.addPositionalArgument(QStringLiteral("source"), QStringLiteral("The source file to highlight."));
|
||||
parser.process(app);
|
||||
|
||||
KSyntaxHighlighting::Repository repository;
|
||||
for (const QString &file : parser.positionalArguments()) {
|
||||
const auto url = QUrl::fromUserInput(file, {}, QUrl::UserInputResolutionOption::AssumeLocalFile);
|
||||
QFile f(url.toLocalFile());
|
||||
if (!f.open(QIODevice::ReadOnly))
|
||||
continue;
|
||||
|
||||
auto view = new QPlainTextEdit();
|
||||
view->setPlainText(QString::fromUtf8(f.readAll()));
|
||||
view->resize(500, 500);
|
||||
|
||||
auto highlighter = new KSyntaxHighlighting::SyntaxHighlighter(view->document());
|
||||
highlighter->setTheme((view->palette().color(QPalette::Base).lightness() < 128) ? repository.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme)
|
||||
: repository.defaultTheme(KSyntaxHighlighting::Repository::LightTheme));
|
||||
|
||||
const auto def = repository.definitionForFileName(url.toLocalFile());
|
||||
highlighter->setDefinition(def);
|
||||
|
||||
view->show();
|
||||
}
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.syntaxhighlighting
|
||||
|
||||
ApplicationWindow {
|
||||
visible: true
|
||||
width: 1024
|
||||
height: 720
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
RowLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
Label { text: "Syntax" }
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: Repository.definitions
|
||||
displayText: currentValue.translatedName + " (" + currentValue.translatedSection + ")"
|
||||
textRole: "translatedName"
|
||||
onCurrentIndexChanged: highlighter.definition = currentValue
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
Label { text: "Theme" }
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: Repository.themes
|
||||
displayText: currentValue.translatedName
|
||||
textRole: "translatedName"
|
||||
onCurrentIndexChanged: highlighter.theme = currentValue
|
||||
}
|
||||
Button {
|
||||
text: "Light"
|
||||
onClicked: highlighter.theme = Repository.defaultTheme(Repository.LightTheme).name
|
||||
}
|
||||
Button {
|
||||
text: "Dark"
|
||||
onClicked: highlighter.theme = Repository.DarkTheme
|
||||
}
|
||||
}
|
||||
ScrollView {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
TextArea {
|
||||
id: myText
|
||||
|
||||
font.family: "monospace"
|
||||
wrapMode: TextEdit.Wrap
|
||||
text: `\
|
||||
Text {
|
||||
text: "Hello World!"
|
||||
width: 42
|
||||
}\
|
||||
`
|
||||
Kirigami.SpellCheck.enabled: false
|
||||
|
||||
SyntaxHighlighter {
|
||||
id: highlighter
|
||||
textEdit: myText
|
||||
repository: Repository
|
||||
}
|
||||
}
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Kirigami.Units.smallSpacing
|
||||
Layout.topMargin: 0
|
||||
elide: Text.ElideRight
|
||||
text: `Syntax: ${highlighter.definition.translatedSection}/${highlighter.definition.translatedName}. Theme: ${highlighter.theme.translatedName}`
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
highlighter.definition = Repository.definitionForFileName("example.qml")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user