add QCodeEditor

This commit is contained in:
Carl Philipp Klemm 2025-10-13 12:40:46 +02:00
parent bccee9bd36
commit 2f3069a388
316 changed files with 98016 additions and 0 deletions

View file

@ -0,0 +1,306 @@
// Demo
#include <MainWindow.hpp>
// QCodeEditor
#include <QCodeEditor>
#include <QGLSLCompleter>
#include <QLuaCompleter>
#include <QPythonCompleter>
#include <QSyntaxStyle>
#include <QCXXHighlighter>
#include <QGLSLHighlighter>
#include <QXMLHighlighter>
#include <QJSONHighlighter>
#include <QLuaHighlighter>
#include <QPythonHighlighter>
// Qt
#include <QCheckBox>
#include <QComboBox>
#include <QFile>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QSpinBox>
#include <QVBoxLayout>
MainWindow::MainWindow(QWidget* parent) :
QMainWindow(parent),
m_setupLayout(nullptr),
m_codeSampleCombobox(nullptr),
m_highlighterCombobox(nullptr),
m_completerCombobox(nullptr),
m_styleCombobox(nullptr),
m_readOnlyCheckBox(nullptr),
m_wordWrapCheckBox(nullptr),
m_parenthesesEnabledCheckbox(nullptr),
m_tabReplaceEnabledCheckbox(nullptr),
m_tabReplaceNumberSpinbox(nullptr),
m_autoIndentationCheckbox(nullptr),
m_codeEditor(nullptr),
m_completers(),
m_highlighters(),
m_styles()
{
initData();
createWidgets();
setupWidgets();
performConnections();
}
void MainWindow::initData()
{
m_codeSamples = {
{"C++", loadCode(":/code_samples/cxx.cpp")},
{"GLSL", loadCode(":/code_samples/shader.glsl")},
{"XML", loadCode(":/code_samples/xml.xml")},
{"JSON", loadCode(":/code_samples/json.json")},
{"LUA", loadCode(":/code_samples/lua.lua")},
{"Python", loadCode(":/code_samples/python.py")}
};
m_completers = {
{"None", nullptr},
{"GLSL", new QGLSLCompleter(this)},
{"LUA", new QLuaCompleter(this)},
{"Python", new QPythonCompleter(this)},
};
m_highlighters = {
{"None", nullptr},
{"C++", new QCXXHighlighter},
{"GLSL", new QGLSLHighlighter},
{"XML", new QXMLHighlighter},
{"JSON", new QJSONHighlighter},
{"LUA", new QLuaHighlighter},
{"Python", new QPythonHighlighter},
};
m_styles = {
{"Default", QSyntaxStyle::defaultStyle()}
};
// Loading styles
loadStyle(":/styles/drakula.xml");
}
QString MainWindow::loadCode(QString path)
{
QFile fl(path);
if (!fl.open(QIODevice::ReadOnly))
{
return QString();
}
return fl.readAll();
}
void MainWindow::loadStyle(QString path)
{
QFile fl(path);
if (!fl.open(QIODevice::ReadOnly))
{
return;
}
auto style = new QSyntaxStyle(this);
if (!style->load(fl.readAll()))
{
delete style;
return;
}
m_styles.append({style->name(), style});
}
void MainWindow::createWidgets()
{
// Layout
auto container = new QWidget(this);
setCentralWidget(container);
auto hBox = new QHBoxLayout(container);
auto setupGroup = new QGroupBox("Setup", container);
hBox->addWidget(setupGroup);
m_setupLayout = new QVBoxLayout(setupGroup);
setupGroup->setLayout(m_setupLayout);
setupGroup->setMaximumWidth(300);
// CodeEditor
m_codeEditor = new QCodeEditor(this);
hBox->addWidget(m_codeEditor);
m_codeSampleCombobox = new QComboBox(setupGroup);
m_highlighterCombobox = new QComboBox(setupGroup);
m_completerCombobox = new QComboBox(setupGroup);
m_styleCombobox = new QComboBox(setupGroup);
m_readOnlyCheckBox = new QCheckBox("Read Only", setupGroup);
m_wordWrapCheckBox = new QCheckBox("Word Wrap", setupGroup);
m_parenthesesEnabledCheckbox = new QCheckBox("Auto Parentheses", setupGroup);
m_tabReplaceEnabledCheckbox = new QCheckBox("Tab Replace", setupGroup);
m_tabReplaceNumberSpinbox = new QSpinBox(setupGroup);
m_autoIndentationCheckbox = new QCheckBox("Auto Indentation", setupGroup);
// Adding widgets
m_setupLayout->addWidget(new QLabel(tr("Code sample"), setupGroup));
m_setupLayout->addWidget(m_codeSampleCombobox);
m_setupLayout->addWidget(new QLabel(tr("Completer"), setupGroup));
m_setupLayout->addWidget(m_completerCombobox);
m_setupLayout->addWidget(new QLabel(tr("Highlighter"), setupGroup));
m_setupLayout->addWidget(m_highlighterCombobox);
m_setupLayout->addWidget(new QLabel(tr("Style"), setupGroup));
m_setupLayout->addWidget(m_styleCombobox);
m_setupLayout->addWidget(m_readOnlyCheckBox);
m_setupLayout->addWidget(m_wordWrapCheckBox);
m_setupLayout->addWidget(m_parenthesesEnabledCheckbox);
m_setupLayout->addWidget(m_tabReplaceEnabledCheckbox);
m_setupLayout->addWidget(m_tabReplaceNumberSpinbox);
m_setupLayout->addWidget(m_autoIndentationCheckbox);
m_setupLayout->addSpacerItem(new QSpacerItem(1, 2, QSizePolicy::Minimum, QSizePolicy::Expanding));
}
void MainWindow::setupWidgets()
{
setWindowTitle("QCodeEditor Demo");
// CodeEditor
m_codeEditor->setPlainText (m_codeSamples[0].second);
m_codeEditor->setSyntaxStyle(m_styles[0].second);
m_codeEditor->setCompleter (m_completers[0].second);
m_codeEditor->setHighlighter(m_highlighters[0].second);
QStringList list;
// Code samples
for (auto&& el : m_codeSamples)
{
list << el.first;
}
m_codeSampleCombobox->addItems(list);
list.clear();
// Highlighter
for (auto&& el : m_highlighters)
{
list << el.first;
}
m_highlighterCombobox->addItems(list);
list.clear();
// Completer
for (auto&& el : m_completers)
{
list << el.first;
}
m_completerCombobox->addItems(list);
list.clear();
// Styles
for (auto&& el : m_styles)
{
list << el.first;
}
m_styleCombobox->addItems(list);
list.clear();
m_parenthesesEnabledCheckbox->setChecked(m_codeEditor->autoParentheses());
m_tabReplaceEnabledCheckbox->setChecked(m_codeEditor->tabReplace());
m_tabReplaceNumberSpinbox->setValue(m_codeEditor->tabReplaceSize());
m_tabReplaceNumberSpinbox->setSuffix(tr(" spaces"));
m_autoIndentationCheckbox->setChecked(m_codeEditor->autoIndentation());
m_wordWrapCheckBox->setChecked(m_codeEditor->wordWrapMode() != QTextOption::NoWrap);
}
void MainWindow::performConnections()
{
connect(
m_codeSampleCombobox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
[this](int index)
{ m_codeEditor->setPlainText(m_codeSamples[index].second); }
);
connect(
m_highlighterCombobox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
[this](int index)
{ m_codeEditor->setHighlighter(m_highlighters[index].second); }
);
connect(
m_completerCombobox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
[this](int index)
{ m_codeEditor->setCompleter(m_completers[index].second); }
);
connect(
m_styleCombobox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
[this](int index)
{ m_codeEditor->setSyntaxStyle(m_styles[index].second); }
);
connect(
m_readOnlyCheckBox,
&QCheckBox::stateChanged,
[this](int state)
{ m_codeEditor->setReadOnly(state != 0); }
);
connect(
m_wordWrapCheckBox,
&QCheckBox::stateChanged,
[this](int state)
{
if (state != 0)
{
m_codeEditor->setWordWrapMode(QTextOption::WordWrap);
}
else
{
m_codeEditor->setWordWrapMode(QTextOption::NoWrap);
}
}
);
connect(
m_parenthesesEnabledCheckbox,
&QCheckBox::stateChanged,
[this](int state)
{ m_codeEditor->setAutoParentheses(state != 0); }
);
connect(
m_tabReplaceEnabledCheckbox,
&QCheckBox::stateChanged,
[this](int state)
{ m_codeEditor->setTabReplace(state != 0); }
);
connect(
m_tabReplaceNumberSpinbox,
QOverload<int>::of(&QSpinBox::valueChanged),
[this](int value)
{ m_codeEditor->setTabReplaceSize(value); }
);
connect(
m_autoIndentationCheckbox,
&QCheckBox::stateChanged,
[this](int state)
{ m_codeEditor->setAutoIndentation(state != 0); }
);
}

View file

@ -0,0 +1,104 @@
// Qt
#include <QApplication>
// Demo
#include <MainWindow.hpp>
const char* codeSample = R"(
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the 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. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QCoreApplication>
#include <QTextStream>
#include "game.h"
//! [0]
int main(int argc, char *argv[])
{
)" "\t" R"(QCoreApplication app(argc, argv);
QStringList args = QCoreApplication::arguments();
bool newGame = true;
if (args.length() > 1)
newGame = (args[1].toLower() != QStringLiteral("load"));
bool json = true;
if (args.length() > 2)
json = (args[2].toLower() != QStringLiteral("binary"));
Game game;
if (newGame)
game.newGame();
else if (!game.loadGame(json ? Game::Json : Game::Binary))
return 1;
// Game is played; changes are made...
//! [0]
//! [1]
QTextStream(stdout) << "Game ended in the following state:\n";
game.print();
if (!game.saveGame(json ? Game::Json : Game::Binary))
return 1;
return 0;
}
//! [1]
)";
int main(int argc, char** argv)
{
// Creating application
QApplication a(argc, argv);
// Creating main window
MainWindow w;
w.show();
return QApplication::exec();
}