feat: 恢复原有代码填充和控制台功能;脚本设置页重做;

This commit is contained in:
寂静的羽夏 2025-03-19 20:54:31 +08:00
parent 5ff1568cea
commit b4fba2fc05
35 changed files with 2035 additions and 1593 deletions

View File

@ -40,6 +40,8 @@ bool QConsoleIODevice::waitForReadyRead(int msecs) {
return readyReadEmmited_;
}
QConsoleWidget *QConsoleIODevice::widget() const { return widget_; }
qint64 QConsoleIODevice::readData(char *data, qint64 len) {
int b = bytesAvailable();
if (b) {

View File

@ -14,7 +14,9 @@ public:
~QConsoleIODevice();
qint64 bytesAvailable() const override;
bool waitForReadyRead(int msecs) override;
QConsoleWidget *widget() const { return widget_; }
QConsoleWidget *widget() const;
void consoleWidgetInput(const QString &in);
protected:
qint64 readData(char *data, qint64 maxlen) override;
@ -27,7 +29,6 @@ private:
int readpos_;
qint64 writtenSinceLastEmit_, readSinceLastEmit_;
bool readyReadEmmited_;
void consoleWidgetInput(const QString &in);
};
#endif

View File

@ -15,19 +15,28 @@
#include <QTextCursor>
#include <QTextDocumentFragment>
#include <KSyntaxHighlighting/Definition>
#include <KSyntaxHighlighting/Repository>
#include <KSyntaxHighlighting/Theme>
QConsoleWidget::QConsoleWidget(QWidget *parent)
: QPlainTextEdit(parent), mode_(Output), completer_(0) {
: WingCodeEdit(parent), mode_(Output) {
iodevice_ = new QConsoleIODevice(this, this);
QTextCharFormat fmt = currentCharFormat();
for (int i = 0; i < nConsoleChannels; i++)
chanFormat_[i] = fmt;
// chanFormat_[StandardOutput];
chanFormat_[StandardOutput].setForeground(Qt::white);
chanFormat_[StandardError].setForeground(Qt::red);
setTextInteractionFlags(Qt::TextEditorInteraction);
setUndoRedoEnabled(false);
setAutoCloseChar(true);
setMatchBraces(true);
setDefaultTheme();
}
QConsoleWidget::~QConsoleWidget() {}
@ -63,14 +72,6 @@ void QConsoleWidget::setChannelCharFormat(ConsoleChannel ch,
chanFormat_[ch] = fmt;
}
const QStringList &QConsoleWidget::completionTriggers() const {
return completion_triggers_;
}
void QConsoleWidget::setCompletionTriggers(const QStringList &l) {
completion_triggers_ = l;
}
QSize QConsoleWidget::sizeHint() const { return QSize(600, 400); }
QString QConsoleWidget::getCommandLine() {
@ -118,109 +119,13 @@ void QConsoleWidget::handleTabKey() {
tc.setPosition(anchor, QTextCursor::MoveAnchor);
tc.setPosition(position, QTextCursor::KeepAnchor);
if (text.isEmpty()) {
tc.insertText(" ");
} else {
updateCompleter();
if (completer_ && completer_->completionCount() == 1) {
insertCompletion(completer_->currentCompletion());
completer_->popup()->hide();
}
}
}
void QConsoleWidget::updateCompleter() {
if (!completer_)
return;
// if the completer is first shown, mark
// the text position
QTextCursor textCursor = this->textCursor();
if (!completer_->popup()->isVisible()) {
completion_pos_ = textCursor.position();
// qDebug() << "show completer, pos " << completion_pos_;
}
// Get the text between the current cursor position
// and the start of the input
textCursor.setPosition(inpos_, QTextCursor::KeepAnchor);
QString commandText = textCursor.selectedText();
// qDebug() << "code to complete: " << commandText;
// Call the completer to update the completion model
// Place and show the completer if there are available completions
if (completer_->updateCompletionModel(commandText)) {
// qDebug() << "found " << count << " completions";
// Get a QRect for the cursor at the start of the
// current word and then translate it down 8 pixels.
textCursor = this->textCursor();
textCursor.movePosition(QTextCursor::StartOfWord);
QRect cr = this->cursorRect(textCursor);
cr.translate(0, 8);
cr.setWidth(
completer_->popup()->sizeHintForColumn(0) +
completer_->popup()->verticalScrollBar()->sizeHint().width());
completer_->complete(cr);
} else {
// qDebug() << "no completions - hiding";
completer_->popup()->hide();
}
}
void QConsoleWidget::checkCompletionTriggers(const QString &txt) {
if (!completer_ || completion_triggers_.isEmpty() || txt.isEmpty())
return;
foreach (const QString &tr, completion_triggers_) {
if (tr.endsWith(txt)) {
QTextCursor tc = this->textCursor();
tc.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor,
tr.length());
if (tc.selectedText() == tr) {
updateCompleter();
return;
}
}
}
}
void QConsoleWidget::insertCompletion(const QString &completion) {
QTextCursor tc = textCursor();
tc.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor,
tc.position() - inpos_ - completer_->insertPos());
tc.insertText(completion, chanFormat_[StandardInput]);
setTextCursor(tc);
}
void QConsoleWidget::setCompleter(QConsoleWidgetCompleter *c) {
if (completer_) {
completer_->setWidget(0);
QObject::disconnect(completer_, SIGNAL(activated(const QString &)),
this, SLOT(insertCompletion(const QString &)));
}
completer_ = c;
if (completer_) {
completer_->setWidget(this);
QObject::connect(completer_, SIGNAL(activated(const QString &)), this,
SLOT(insertCompletion(const QString &)));
tc.insertText(QString(4, ' '));
}
}
void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
if (completer_ && completer_->popup()->isVisible()) {
// The following keys are forwarded by the completer to the widget
switch (e->key()) {
case Qt::Key_Tab:
case Qt::Key_Enter:
case Qt::Key_Return:
case Qt::Key_Escape:
case Qt::Key_Backtab:
e->ignore();
return; // let the completer do default behavior
default:
break;
}
if (processCompletionBegin(e)) {
return;
}
QTextCursor textCursor = this->textCursor();
@ -308,7 +213,7 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
case Qt::Key_Left:
if (textCursor.position() > inpos_)
QPlainTextEdit::keyPressEvent(e);
processDefaultKeyPressEvent(e);
else {
QApplication::beep();
e->accept();
@ -324,7 +229,7 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
if (textCursor.position() < inpos_)
QApplication::beep();
else
QPlainTextEdit::keyPressEvent(e);
processDefaultKeyPressEvent(e);
}
break;
@ -337,7 +242,7 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
if (textCursor.position() <= inpos_)
QApplication::beep();
else
QPlainTextEdit::keyPressEvent(e);
processDefaultKeyPressEvent(e);
}
break;
@ -367,18 +272,12 @@ void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
default:
e->accept();
setCurrentCharFormat(chanFormat_[StandardInput]);
QPlainTextEdit::keyPressEvent(e);
// check if the last key triggers a completion
checkCompletionTriggers(e->text());
processDefaultKeyPressEvent(e);
break;
}
if (completer_ && completer_->popup()->isVisible()) {
// if the completer is visible check if it should be updated
if (this->textCursor().position() < completion_pos_)
completer_->popup()->hide();
else
updateCompleter();
if (processCompletionEnd(e)) {
return;
}
}
@ -421,6 +320,8 @@ bool QConsoleWidget::canPaste() const {
return true;
}
bool QConsoleWidget::canCut() const { return isSelectionInEditZone(); }
void QConsoleWidget::replaceCommandLine(const QString &str) {
// Select the text after the last command prompt ...
@ -436,6 +337,15 @@ void QConsoleWidget::replaceCommandLine(const QString &str) {
setTextCursor(textCursor);
}
QString QConsoleWidget::currentCommandLine() const {
// Select the text after the last command prompt ...
QTextCursor textCursor = this->textCursor();
textCursor.movePosition(QTextCursor::End);
textCursor.setPosition(inpos_, QTextCursor::KeepAnchor);
return textCursor.selectedText();
}
void QConsoleWidget::write(const QString &message, const QTextCharFormat &fmt) {
QTextCharFormat currfmt = currentCharFormat();
QTextCursor tc = textCursor();
@ -466,7 +376,7 @@ void QConsoleWidget::write(const QString &message, const QTextCharFormat &fmt) {
setTextCursor(tc);
setCurrentCharFormat(currfmt);
} else {
// in output mode messages are appended
// in output mode messages are ed
QTextCursor tc1 = tc;
tc1.movePosition(QTextCursor::End);

View File

@ -2,13 +2,13 @@
#define _QCONSOLEWIDGET_H_
#include <QCompleter>
#include <QPlainTextEdit>
#include <QTextStream>
class QConsoleIODevice;
class QConsoleWidgetCompleter;
#include "WingCodeEdit/wingcodeedit.h"
class QConsoleWidget : public QPlainTextEdit {
class QConsoleIODevice;
class QConsoleWidget : public WingCodeEdit {
Q_OBJECT
public:
@ -53,13 +53,11 @@ public:
QIODevice *device() const;
QTextCharFormat channelCharFormat(ConsoleChannel ch) const;
void setChannelCharFormat(ConsoleChannel ch, const QTextCharFormat &fmt);
const QStringList &completionTriggers() const;
void setCompletionTriggers(const QStringList &l);
virtual QSize sizeHint() const override;
// write a formatted message to the console
void write(const QString &message, const QTextCharFormat &fmt);
static History &history();
void setCompleter(QConsoleWidgetCompleter *c);
// get the current command line
QString getCommandLine();
@ -79,11 +77,9 @@ signals:
protected:
bool canPaste() const;
bool canCut() const { return isSelectionInEditZone(); }
void handleReturnKey();
void handleTabKey();
void updateCompleter();
void checkCompletionTriggers(const QString &txt);
bool canCut() const;
virtual void handleReturnKey();
virtual void handleTabKey();
// reimp QPlainTextEdit functions
void keyPressEvent(QKeyEvent *e) override;
void contextMenuEvent(QContextMenuEvent *event) override;
@ -94,20 +90,15 @@ protected:
// replace the command line
void replaceCommandLine(const QString &str);
protected slots:
QString currentCommandLine() const;
// insert the completion from completer
void insertCompletion(const QString &completion);
private:
protected:
static History history_;
ConsoleMode mode_;
int inpos_, completion_pos_;
QStringList completion_triggers_;
int inpos_;
QString currentMultiLineCode_;
QConsoleIODevice *iodevice_;
QTextCharFormat chanFormat_[nConsoleChannels];
QConsoleWidgetCompleter *completer_;
};
QTextStream &waitForInput(QTextStream &s);
@ -115,22 +106,4 @@ QTextStream &inputMode(QTextStream &s);
QTextStream &outChannel(QTextStream &s);
QTextStream &errChannel(QTextStream &s);
class QConsoleWidgetCompleter : public QCompleter {
public:
/*
* Update the completion model given a string. The given string
* is the current console text between the cursor and the start of
* the line.
*
* Return the completion count
*/
virtual int updateCompletionModel(const QString &str) = 0;
/*
* Return the position in the command line where the completion
* should be inserted
*/
virtual int insertPos() = 0;
};
#endif

@ -1 +1 @@
Subproject commit c919e31227f8bb2aedde7cff6e717e1acd4d62b8
Subproject commit 910a38521cb963cc40581bb8d98bf966eb706f17

View File

@ -206,7 +206,11 @@ set(CONTROL_SRC
src/control/dockwidgettab.h
src/control/dockwidgettab.cpp
src/control/qhextextedit.h
src/control/qhextextedit.cpp)
src/control/qhextextedit.cpp
src/control/popupactionwidget.h
src/control/popupactionwidget.cpp
src/control/settingspopup.cpp
src/control/settingspopup.h)
set(CLASS_SRC
src/class/logger.cpp
@ -279,7 +283,13 @@ set(CLASS_SRC
src/class/inspectqtloghelper.h
src/class/inspectqtloghelper.cpp
src/class/codeinfotip.h
src/class/codeinfotip.cpp)
src/class/codeinfotip.cpp
src/class/wingconsolehighligher.h
src/class/wingconsolehighligher.cpp
src/class/asconsolecompletion.h
src/class/asconsolecompletion.cpp
src/class/scriptsettings.h
src/class/scriptsettings.cpp)
set(INTERNAL_PLG_SRC
src/class/wingangelapi.h src/class/wingangelapi.cpp

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,10 +19,12 @@
#include "asdatabase.h"
#include "model/codecompletionmodel.h"
#include "wingcodeedit.h"
#include <QAbstractItemView>
#include <QByteArray>
#include <QDir>
#include <QEvent>
#include <QLibraryInfo>
#include <QQueue>
#include <QTextStream>
@ -36,7 +38,8 @@ Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, LEFT_PARE_TRIGGER, ("("))
Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, SEMI_COLON_TRIGGER, (";"))
AsCompletion::AsCompletion(asIScriptEngine *engine, WingCodeEdit *p)
: WingCompleter(p), parser(engine), _engine(engine) {
: WingCompleter(p), parser(engine), _engine(engine),
m_parseDocument(false) {
Q_ASSERT(engine);
setTriggerList({*DOT_TRIGGER, *DBL_COLON_TRIGGER,
@ -45,6 +48,17 @@ AsCompletion::AsCompletion(asIScriptEngine *engine, WingCodeEdit *p)
// clear the tips
*SEMI_COLON_TRIGGER});
setTriggerAmount(3);
connect(this, QOverload<const QModelIndex &>::of(&AsCompletion::activated),
this, [this](const QModelIndex &index) {
auto v = index.data(Qt::SelfDataRole).value<CodeInfoTip>();
if (v.type == CodeInfoTip::Type::Function ||
v.type == CodeInfoTip::Type::ClsFunction) {
emit onFunctionTip(v.getTooltip());
}
});
p->installEventFilter(this);
}
AsCompletion::~AsCompletion() {}
@ -91,6 +105,14 @@ void AsCompletion::applyClassNodes(QList<CodeInfoTip> &nodes) {
nodes = clsNodes;
}
bool AsCompletion::parseDocument() const { return m_parseDocument; }
void AsCompletion::setParseDocument(bool newParseDocument) {
m_parseDocument = newParseDocument;
}
void AsCompletion::clearFunctionTip() { emit onFunctionTip({}); }
QString AsCompletion::wordSeperators() const {
static QString eow(QStringLiteral("~!@#$%^&*()_+{}|\"<>?,/;'[]\\-="));
return eow;
@ -99,25 +121,29 @@ QString AsCompletion::wordSeperators() const {
void AsCompletion::processTrigger(const QString &trigger,
const QString &content) {
if (content.isEmpty()) {
emit onFunctionTip({});
return;
}
if (trigger == *SEMI_COLON_TRIGGER) {
emit onFunctionTip({});
clearFunctionTip();
return;
}
auto len = content.length();
auto code = content.toUtf8();
QList<CodeInfoTip> nodes;
// TODO: PRs are welcomed !!!
// If this software is well-known or brings me lots of
// financial support, I will implement it myself.
// PARSING THE DOCUMENT
if (m_parseDocument) {
nodes.append(parseDocument());
}
if (trigger != *DOT_TRIGGER) {
emit onFunctionTip({});
if (!trigger.isEmpty() && trigger != *DOT_TRIGGER) {
clearFunctionTip();
}
auto p = code.data();
@ -183,8 +209,6 @@ void AsCompletion::processTrigger(const QString &trigger,
QString prefix;
auto etoken = tokens.back();
QList<CodeInfoTip> nodes;
// if trigger is empty, it's making editing
if (trigger.isEmpty()) {
// it can not be any trigger, so take the last as prefix
@ -261,3 +285,15 @@ void AsCompletion::processTrigger(const QString &trigger,
setModel(new CodeCompletionModel(nodes, this));
setCompletionPrefix(prefix);
}
QList<CodeInfoTip> AsCompletion::parseDocument() { return {}; }
bool AsCompletion::eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::KeyPress) {
auto e = static_cast<QKeyEvent *>(event);
if (e->key() == Qt::Key_Escape) {
clearFunctionTip();
}
}
return WingCompleter::eventFilter(watched, event);
}

View File

@ -32,13 +32,24 @@ public:
public:
virtual QString wordSeperators() const override;
bool parseDocument() const;
void setParseDocument(bool newParseDocument);
void clearFunctionTip();
protected:
virtual void processTrigger(const QString &trigger,
const QString &content) override;
virtual QList<CodeInfoTip> parseDocument();
signals:
void onFunctionTip(const QString &content);
// QObject interface
public:
virtual bool eventFilter(QObject *watched, QEvent *event) override;
private:
void applyEmptyNsNode(QList<CodeInfoTip> &nodes);
void applyClassNodes(QList<CodeInfoTip> &nodes);
@ -46,6 +57,7 @@ private:
private:
ASDataBase parser;
asIScriptEngine *_engine;
bool m_parseDocument;
};
#endif // _CPP_COMPLETION_H_

View File

@ -0,0 +1,12 @@
#include "asconsolecompletion.h"
#include "control/scriptingconsole.h"
AsConsoleCompletion::AsConsoleCompletion(asIScriptEngine *engine,
ScriptingConsole *p)
: AsCompletion(engine, p), _console(p) {}
QList<CodeInfoTip> AsConsoleCompletion::parseDocument() {
// TODO
return {};
}

View File

@ -0,0 +1,22 @@
#ifndef ASCONSOLECOMPLETION_H
#define ASCONSOLECOMPLETION_H
#include "ascompletion.h"
class ScriptingConsole;
class AsConsoleCompletion : public AsCompletion {
Q_OBJECT
public:
explicit AsConsoleCompletion(asIScriptEngine *engine, ScriptingConsole *p);
virtual ~AsConsoleCompletion() = default;
// AsCompletion interface
protected:
virtual QList<CodeInfoTip> parseDocument() override;
private:
ScriptingConsole *_console;
};
#endif // ASCONSOLECOMPLETION_H

View File

@ -0,0 +1,31 @@
#include "scriptsettings.h"
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_FONT, ("codeedit.font"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_FONT_SIZE, ("codeedit.fontsize"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_SHOW_LEADING_WHITESPACE,
("codeedit.leading_whitespace"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_SHOW_TRAILING_WHITESPACE,
("codeedit.trailing_whitespace"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_SHOW_TABS, ("codeedit.show_tabs"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_TABS_WIDTH, ("codeedit.tab_width"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_REPLACE_TABS,
("codeedit.replace_tabs"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_REMOVE_TRAILING,
("codeedit.remove_trailing"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_PRESERVE_TRAILING_INDENT,
("codeedit.preserve_trailing_indent"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_LINE_ENDINGS,
("codeedit.line_endings"))
ScriptSettings &ScriptSettings::instance() {
static ScriptSettings ins;
return ins;
}
void ScriptSettings::load() {}
void ScriptSettings::save(SETTINGS cat) {}
void ScriptSettings::reset(SETTINGS cat) {}
ScriptSettings::ScriptSettings() : QObject() {}

View File

@ -0,0 +1,52 @@
#ifndef SCRIPTSETTINGS_H
#define SCRIPTSETTINGS_H
#include <QObject>
class ScriptSettings : public QObject {
Q_OBJECT
public:
enum SETTING { EDITOR = 1, CONSOLE = 2, ALL = EDITOR | CONSOLE };
Q_DECLARE_FLAGS(SETTINGS, SETTING)
private:
// Flags to indicate whether the modification has been made.
// There are a maximum of 32 flags,
// but it is impossible to have more than this.
enum class SETTING_ITEM : quint32 {
FONT = 1u,
FONT_SIZE = 1u << 1,
THEME = 1u << 2,
TAB_WIDTH = 1u << 3,
INDENTATION = 1u << 4,
WORD_WRAP = 1u << 5,
MATCH_BRACES = 1u << 6,
SHOW_LINENUMBER = 1u << 7,
SHOW_FOLDING = 1u << 8,
SHOW_INDENTGUIDES = 1u << 9,
SHOW_LONGLINEEDGE = 1u << 10,
SHOW_WHITESPACE = 1u << 11,
AUTO_CLOSE_CHAR = 1u << 12
};
Q_DECLARE_FLAGS(SETTING_ITEMS, SETTING_ITEM)
public:
static ScriptSettings &instance();
void load();
void save(SETTINGS cat = SETTING::ALL);
void reset(SETTINGS cat = SETTING::ALL);
private:
explicit ScriptSettings();
signals:
void editorSettingsUpdate();
void consoleSettingUpdate();
private:
Q_DISABLE_COPY_MOVE(ScriptSettings)
};
#endif // SCRIPTSETTINGS_H

View File

@ -70,23 +70,6 @@ Q_GLOBAL_STATIC_WITH_ARGS(QString, OTHER_LOG_LEVEL, ("sys.loglevel"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, OTHER_LOG_COUNT, ("sys.logCount"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, OTHER_CHECK_UPDATE, ("sys.checkUpdate"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_FONT, ("codeedit.font"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_FONT_SIZE, ("codeedit.fontsize"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_SHOW_LEADING_WHITESPACE,
("codeedit.leading_whitespace"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_SHOW_TRAILING_WHITESPACE,
("codeedit.trailing_whitespace"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_SHOW_TABS, ("codeedit.show_tabs"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_TABS_WIDTH, ("codeedit.tab_width"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_REPLACE_TABS,
("codeedit.replace_tabs"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_REMOVE_TRAILING,
("codeedit.remove_trailing"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_PRESERVE_TRAILING_INDENT,
("codeedit.preserve_trailing_indent"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CODEEDIT_LINE_ENDINGS,
("codeedit.line_endings"))
SettingManager::SettingManager() {
_defaultFont = qApp->font();
qRegisterMetaType<RecentFileManager::RecentInfo>();
@ -94,7 +77,6 @@ SettingManager::SettingManager() {
qRegisterMetaTypeStreamOperators<RecentFileManager::RecentInfo>();
#endif
load();
loadCodeEditorConfig();
}
QString SettingManager::lastUsedPath() const { return m_lastUsedPath; }
@ -252,96 +234,6 @@ void SettingManager::setAllowUsrScriptInRoot(bool newAllowUsrScriptInRoot) {
}
}
void SettingManager::loadCodeEditorConfig() {
HANDLE_CONFIG;
auto dfont = qApp->font();
QString fontName;
READ_CONFIG_STRING(fontName, CODEEDIT_FONT, dfont.family());
int pointSize;
READ_CONFIG_INT_POSITIVE(pointSize, CODEEDIT_FONT_SIZE, dfont.pointSize());
dfont = QFont(fontName, pointSize);
// QEditor::setDefaultFont(dfont);
int tabStop;
READ_CONFIG_INT_POSITIVE(tabStop, CODEEDIT_TABS_WIDTH, 4);
// QEditor::setDefaultTabStop(tabStop);
// QDocument::WhiteSpaceMode ws = QDocument::ShowNone;
bool b;
READ_CONFIG_BOOL(b, CODEEDIT_SHOW_TABS, false);
// if (b)
// ws |= QDocument::ShowTabs;
READ_CONFIG_BOOL(b, CODEEDIT_SHOW_LEADING_WHITESPACE, false);
// if (b)
// ws |= QDocument::ShowLeading;
READ_CONFIG_BOOL(b, CODEEDIT_SHOW_TRAILING_WHITESPACE, false);
// if (b)
// ws |= QDocument::ShowTrailing;
// QEditor::setDefaultShowSpaces(ws);
int enums;
// READ_CONFIG_INT(enums, CODEEDIT_LINE_ENDINGS,
// QDocument::LineEnding::Conservative);
// auto le =
// QDocument::LineEnding(qMin(enums, int(QDocument::LineEnding::Mac)));
// QEditor::setDefaultLineEnding(le);
// int flags = QEditor::defaultFlags();
READ_CONFIG_BOOL(b, CODEEDIT_REPLACE_TABS, true);
// if (b)
// flags |= QEditor::ReplaceTabs;
// else
// flags &= ~QEditor::ReplaceTabs;
READ_CONFIG_BOOL(b, CODEEDIT_REMOVE_TRAILING, true);
// if (b)
// flags |= QEditor::RemoveTrailing;
// else
// flags &= ~QEditor::RemoveTrailing;
READ_CONFIG_BOOL(b, CODEEDIT_PRESERVE_TRAILING_INDENT, false);
// if (b)
// flags |= QEditor::PreserveTrailingIndent;
// else
// flags &= ~QEditor::PreserveTrailingIndent;
// QEditor::setDefaultFlags(flags);
}
void SettingManager::saveCodeEditorConfig() {
HANDLE_CONFIG;
// auto font = QEditor::defaultFont();
// WRITE_CONFIG(CODEEDIT_FONT, font.family());
// WRITE_CONFIG(CODEEDIT_FONT_SIZE, font.pointSize());
// WRITE_CONFIG(CODEEDIT_TABS_WIDTH, QEditor::defaultTabStop());
// auto showSpaces = QEditor::defaultShowSpaces();
// WRITE_CONFIG(CODEEDIT_SHOW_TABS,
// showSpaces.testFlag(QDocument::ShowTabs));
// WRITE_CONFIG(CODEEDIT_SHOW_LEADING_WHITESPACE,
// showSpaces.testFlag(QDocument::ShowLeading));
// WRITE_CONFIG(CODEEDIT_SHOW_TRAILING_WHITESPACE,
// showSpaces.testFlag(QDocument::ShowTrailing));
// WRITE_CONFIG(CODEEDIT_LINE_ENDINGS, int(QEditor::defaultLineEnding()));
// int flags = QEditor::defaultFlags();
// WRITE_CONFIG(CODEEDIT_REPLACE_TABS, flags & QEditor::ReplaceTabs);
// WRITE_CONFIG(CODEEDIT_REMOVE_TRAILING, flags & QEditor::RemoveTrailing);
// WRITE_CONFIG(CODEEDIT_PRESERVE_TRAILING_INDENT,
// flags & QEditor::PreserveTrailingIndent);
}
void SettingManager::setUsrHideCats(const QStringList &newUsrHideCats) {
if (m_usrHideCats != newUsrHideCats) {
m_usrHideCats = newUsrHideCats;
@ -514,9 +406,6 @@ void SettingManager::save(SETTINGS cat) {
WRITE_CONFIG_SET(OTHER_LOG_LEVEL, m_logLevel);
WRITE_CONFIG_SET(OTHER_LOG_COUNT, m_logCount);
}
if (cat.testFlag(SETTING::CODEEDIT)) {
saveCodeEditorConfig();
}
}
void SettingManager::reset(SETTINGS cat) {

View File

@ -37,8 +37,7 @@ public:
EDITOR = 4,
SCRIPT = 8,
OTHER = 16,
CODEEDIT = 32,
ALL = APP | PLUGIN | EDITOR | SCRIPT | OTHER | CODEEDIT
ALL = APP | PLUGIN | EDITOR | SCRIPT | OTHER
};
Q_DECLARE_FLAGS(SETTINGS, SETTING)
private:
@ -183,10 +182,6 @@ signals:
void logLevelChanged();
private:
void loadCodeEditorConfig();
void saveCodeEditorConfig();
private:
SettingManager();

View File

@ -0,0 +1,47 @@
#include "wingconsolehighligher.h"
#include <KSyntaxHighlighting/FoldingRegion>
WingConsoleHighligher::WingConsoleHighligher(QTextDocument *document)
: WingSyntaxHighlighter(document) {}
void WingConsoleHighligher::highlightBlock(const QString &text) {
WingSyntaxHighlighter::highlightBlock(text);
}
void WingConsoleHighligher::applyFormat(
int offset, int length, const KSyntaxHighlighting::Format &format) {
auto blk = currentBlock();
auto offsetv = property(blk, "cmdoff");
bool b;
auto off = offsetv.toInt(&b);
if (b) {
if (off < 0) {
// don't highlight
return;
} else {
if (offset <= off) {
auto div = off - offset;
auto rest = length - div;
if (rest <= 0) {
return;
}
WingSyntaxHighlighter::applyFormat(off, rest, format);
} else {
WingSyntaxHighlighter::applyFormat(offset, length, format);
}
}
} else {
WingSyntaxHighlighter::applyFormat(offset, length, format);
}
}
void WingConsoleHighligher::applyFolding(
int offset, int length, KSyntaxHighlighting::FoldingRegion region) {
Q_UNUSED(offset);
Q_UNUSED(length);
Q_UNUSED(region);
// Console needs no folding
}

View File

@ -0,0 +1,21 @@
#ifndef WINGCONSOLEHIGHLIGHER_H
#define WINGCONSOLEHIGHLIGHER_H
#include "WingCodeEdit/wingsyntaxhighlighter.h"
class WingConsoleHighligher : public WingSyntaxHighlighter {
Q_OBJECT
public:
explicit WingConsoleHighligher(QTextDocument *document = nullptr);
protected:
virtual void highlightBlock(const QString &text) override;
virtual void
applyFormat(int offset, int length,
const KSyntaxHighlighting::Format &format) override;
virtual void
applyFolding(int offset, int length,
KSyntaxHighlighting::FoldingRegion region) override;
};
#endif // WINGCONSOLEHIGHLIGHER_H

View File

@ -19,20 +19,21 @@
#include "model/codecompletionmodel.h"
#include <QModelIndex>
#include <QShortcut>
CodeEdit::CodeEdit(QWidget *parent) : WingCodeEdit(parent) {
setAutoIndent(true);
setAutoCloseChar(true);
setMatchBraces(true);
setShowLongLineEdge(true);
setShowIndentGuides(true);
setShowLineNumbers(true);
setShowFolding(true);
setShowWhitespace(true);
setShowSymbolMark(true);
connect(this->document(), &QTextDocument::modificationChanged, this,
&CodeEdit::contentModified);
addMoveLineShortCut();
}
void CodeEdit::onCompletion(const QModelIndex &index) {
@ -49,3 +50,17 @@ void CodeEdit::onCompletion(const QModelIndex &index) {
}
}
}
void CodeEdit::addMoveLineShortCut() {
auto upLines = new QShortcut(
QKeySequence(Qt::ControlModifier | Qt::AltModifier | Qt::Key_Up), this);
upLines->setContext(Qt::WidgetShortcut);
connect(upLines, &QShortcut::activated, this,
[this]() { moveLines(QTextCursor::PreviousBlock); });
auto downLines = new QShortcut(
QKeySequence(Qt::ControlModifier | Qt::AltModifier | Qt::Key_Down),
this);
downLines->setContext(Qt::WidgetShortcut);
connect(downLines, &QShortcut::activated, this,
[this]() { moveLines(QTextCursor::NextBlock); });
}

View File

@ -31,6 +31,9 @@ signals:
protected slots:
virtual void onCompletion(const QModelIndex &index) override;
private:
void addMoveLineShortCut();
};
#endif // CODEEDIT_H

View File

@ -0,0 +1,16 @@
#include "popupactionwidget.h"
#include <QApplication>
#include <QTimer>
#include <QWidget>
PopupActionWidget::PopupActionWidget(QObject *parent) : QWidgetAction(parent) {}
void PopupActionWidget::closePopUpWidget() {
QTimer::singleShot(100, qApp, []() {
auto popupWidget = QApplication::activePopupWidget();
if (popupWidget) {
popupWidget->close();
}
});
}

View File

@ -0,0 +1,15 @@
#ifndef POPUPACTIONWIDGET_H
#define POPUPACTIONWIDGET_H
#include <QWidgetAction>
class PopupActionWidget : public QWidgetAction {
Q_OBJECT
public:
explicit PopupActionWidget(QObject *parent = nullptr);
protected:
void closePopUpWidget();
};
#endif // POPUPACTIONWIDGET_H

View File

@ -16,7 +16,7 @@
*/
#include "scripteditor.h"
#include "DockWidgetTab.h"
#include "Qt-Advanced-Docking-System/src/DockWidgetTab.h"
#include "utilities.h"
#ifdef Q_OS_LINUX
@ -62,7 +62,8 @@ ScriptEditor::ScriptEditor(asIScriptEngine *engine, QWidget *parent)
m_editor->syntaxRepo().definitionForName("AngelScript"));
auto cm = new AsCompletion(engine, m_editor);
m_editor->setCompleter(cm);
connect(cm, &AsCompletion::onFunctionTip, this,
&ScriptEditor::onFunctionTip);
connect(m_editor, &CodeEdit::symbolMarkLineMarginClicked, this,
&ScriptEditor::onToggleMark);

View File

@ -38,6 +38,7 @@ public:
signals:
void onToggleMark(int line);
void onFunctionTip(const QString &tip);
public slots:
bool openFile(const QString &filename);

View File

@ -16,8 +16,11 @@
*/
#include "scriptingconsole.h"
#include "QConsoleWidget/QConsoleIODevice.h"
#include "class/logger.h"
#include "class/scriptconsolemachine.h"
#include "class/wingconsolehighligher.h"
#include "model/codecompletionmodel.h"
#include <QApplication>
#include <QColor>
@ -25,20 +28,68 @@
#include <QRegularExpression>
#include <QTextBlock>
#include <KSyntaxHighlighting/Definition>
#include <KSyntaxHighlighting/Repository>
#include <KSyntaxHighlighting/Theme>
ScriptingConsole::ScriptingConsole(QWidget *parent) : QConsoleWidget(parent) {
_warnCharFmt.setForeground(QColorConstants::Svg::gold);
setHighlighter(new WingConsoleHighligher);
setSyntax(syntaxRepo().definitionForName("AngelScript"));
}
ScriptingConsole::~ScriptingConsole() {}
void ScriptingConsole::stdOut(const QString &str) { writeStdOut(str); }
void ScriptingConsole::stdOut(const QString &str) {
writeStdOut(str);
dontHighlightLastLine();
}
void ScriptingConsole::stdErr(const QString &str) { writeStdErr(str); }
void ScriptingConsole::stdErr(const QString &str) {
writeStdErr(str);
dontHighlightLastLine();
}
void ScriptingConsole::stdWarn(const QString &str) { write(str, _warnCharFmt); }
void ScriptingConsole::stdWarn(const QString &str) {
write(str, _warnCharFmt);
dontHighlightLastLine();
}
void ScriptingConsole::newLine() { _s << Qt::endl; }
void ScriptingConsole::dontHighlightLastLine() { dontHighlightLastOffset(-1); }
void ScriptingConsole::dontHighlightLastOffset(int offset) {
auto blk = document()->lastBlock();
auto hl = highlighter();
hl->setProperty(blk, "cmdoff", offset);
hl->rehighlightBlock(blk);
}
void ScriptingConsole::handleReturnKey() {
QString code = getCommandLine();
// start new block
appendPlainText(QString());
dontHighlightLastLine();
setMode(Output);
QTextCursor textCursor = this->textCursor();
textCursor.movePosition(QTextCursor::End);
setTextCursor(textCursor);
// Update the history
if (!code.isEmpty())
history_.add(code);
// append the newline char and
// send signal / update iodevice
if (iodevice_->isOpen())
iodevice_->consoleWidgetInput(code);
emit consoleCommand(code);
}
void ScriptingConsole::init() {
_s.setDevice(this->device());
@ -96,11 +147,14 @@ void ScriptingConsole::init() {
connect(this, &QConsoleWidget::consoleCommand, this,
&ScriptingConsole::runConsoleCommand);
auto cm = new AsConsoleCompletion(_sp->engine(), this);
connect(cm, &AsCompletion::onFunctionTip, this,
&ScriptingConsole::onFunctionTip);
}
void ScriptingConsole::initOutput() {
stdWarn(tr("Scripting console for WingHexExplorer"));
_s << Qt::endl;
stdWarn(tr(">>>> Powered by AngelScript <<<<"));
_s << Qt::endl << Qt::endl;
@ -158,6 +212,25 @@ void ScriptingConsole::keyPressEvent(QKeyEvent *e) {
}
}
void ScriptingConsole::onCompletion(const QModelIndex &index) {
WingCodeEdit::onCompletion(index);
auto selfdata = index.data(Qt::SelfDataRole).value<CodeInfoTip>();
if (selfdata.type == CodeInfoTip::Type::Function ||
selfdata.type == CodeInfoTip::Type::ClsFunction) {
auto args = selfdata.addinfo.value(CodeInfoTip::Args);
auto cursor = textCursor();
cursor.insertText(QStringLiteral("()"));
if (!args.isEmpty()) {
cursor.movePosition(QTextCursor::Left);
setTextCursor(cursor);
}
}
}
QString ScriptingConsole::currentCodes() const {
return _codes + currentCommandLine();
}
void ScriptingConsole::appendCommandPrompt(bool storeOnly) {
QString commandPrompt;
@ -166,7 +239,7 @@ void ScriptingConsole::appendCommandPrompt(bool storeOnly) {
} else {
auto cursor = this->textCursor();
if (!cursor.atBlockStart()) {
commandPrompt = QStringLiteral("\n");
newLine();
}
if (_sp && _sp->isDebugMode()) {
commandPrompt += QStringLiteral("[dbg] > ");
@ -177,7 +250,8 @@ void ScriptingConsole::appendCommandPrompt(bool storeOnly) {
_lastCommandPrompt = storeOnly;
stdOut(commandPrompt);
writeStdOut(commandPrompt);
dontHighlightLastOffset(commandPrompt.length());
}
ScriptMachine *ScriptingConsole::machine() const { return _sp; }

View File

@ -19,6 +19,7 @@
#define ScriptingConsole_H
#include "QConsoleWidget/QConsoleWidget.h"
#include "class/asconsolecompletion.h"
#include "class/scriptconsolemachine.h"
#include <QMutex>
@ -37,6 +38,11 @@ public:
//! Appends a newline and command prompt at the end of the document.
void appendCommandPrompt(bool storeOnly = false);
QString currentCodes() const;
signals:
void onFunctionTip(const QString &tip);
public slots:
void stdOut(const QString &str);
void stdErr(const QString &str);
@ -58,9 +64,17 @@ private:
QString packUpLoggingStr(const QString &message);
void dontHighlightLastLine();
void dontHighlightLastOffset(int offset);
protected:
void handleReturnKey() override;
void keyPressEvent(QKeyEvent *e) override;
protected slots:
virtual void onCompletion(const QModelIndex &index) override;
private:
ScriptConsoleMachine *_sp = nullptr;
QTextStream _s;

View File

@ -0,0 +1,258 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** 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 Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
// This file is part of QTextPad.
#include "settingspopup.h"
#include <QApplication>
#include <QHeaderView>
#include <QLineEdit>
#include <QPainter>
#include <QScrollBar>
#include <QTreeWidget>
#include <QVBoxLayout>
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
#include <QStyleHints>
#endif
#include <KSyntaxHighlighting/Repository>
#include "3rdparty/WingCodeEdit/wingcodeedit.h"
#include "utilities.h"
TreeFilterEdit::TreeFilterEdit(QWidget *parent) : QLineEdit(parent) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
const bool darkTheme =
(QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark);
#else
const bool darkTheme =
(palette().color(QPalette::Window).lightness() < 128);
#endif
// TODO
// m_searchIcon =
//(QStringLiteral("search-filter"),
// darkTheme);
setClearButtonEnabled(true);
recomputeIconPos();
}
QSize TreeFilterEdit::sizeHint() const {
QSize hint = QLineEdit::sizeHint();
hint.setHeight(qMin(hint.height(), 18));
return hint;
}
void TreeFilterEdit::paintEvent(QPaintEvent *event) {
QLineEdit::paintEvent(event);
QPainter painter(this);
QRect iconRect(m_iconPosition.x(), m_iconPosition.y(), 16, 16);
if (event->region().intersects(iconRect))
m_searchIcon.paint(&painter, iconRect);
}
void TreeFilterEdit::resizeEvent(QResizeEvent *event) {
QLineEdit::resizeEvent(event);
recomputeIconPos();
}
void TreeFilterEdit::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_Down) {
emit navigateDown();
return;
}
QLineEdit::keyPressEvent(event);
}
void TreeFilterEdit::recomputeIconPos() {
const int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
setStyleSheet(QStringLiteral("QLineEdit { padding-left: %1px; }")
.arg(frameWidth + 18));
m_iconPosition =
QPoint(rect().left() + frameWidth + 1, (rect().bottom() - 16) / 2);
}
static QTreeWidgetItem *firstVisibleItem(QTreeWidgetItem *parent) {
for (int i = 0; i < parent->childCount(); ++i) {
QTreeWidgetItem *item = parent->child(i);
if (!item->isHidden())
return item;
}
return nullptr;
}
FilteredTreePopup::FilteredTreePopup(QWidget *parent) : QWidget(parent) {
auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
m_filter = new TreeFilterEdit(this);
connect(m_filter, &QLineEdit::textChanged, this,
&FilteredTreePopup::filterItems);
layout->addWidget(m_filter);
m_tree = new QTreeWidget(this);
m_tree->header()->hide();
layout->addWidget(m_tree);
connect(m_filter, &TreeFilterEdit::navigateDown, this, [this] {
m_tree->setFocus();
auto topItem = firstVisibleItem(m_tree->invisibleRootItem());
if (topItem)
m_tree->setCurrentItem(topItem);
});
}
QSize FilteredTreePopup::sizeHint() const {
QSize hint;
const int viewWidth =
5 + m_tree->columnWidth(0) +
m_tree->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) +
m_tree->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
hint.setWidth(qMax(viewWidth, m_tree->sizeHint().width()));
const QFontMetrics fm = m_tree->fontMetrics();
hint.setHeight(m_filter->sizeHint().height() + (fm.height() * 16));
return hint;
}
TreeFilterEdit *FilteredTreePopup::filter() { return m_filter; }
QTreeWidget *FilteredTreePopup::tree() { return m_tree; }
template <typename FilterProc>
bool applyFilter(QTreeWidgetItem *parent, const FilterProc &proc) {
bool showParent = false;
for (int i = 0; i < parent->childCount(); ++i) {
QTreeWidgetItem *item = parent->child(i);
if (applyFilter(item, proc)) {
item->setHidden(false);
showParent = true;
continue;
}
if (proc(item)) {
item->setHidden(false);
showParent = true;
} else {
item->setHidden(true);
}
}
return showParent;
}
void FilteredTreePopup::filterItems(const QString &text) {
if (text.isEmpty()) {
applyFilter(m_tree->invisibleRootItem(),
[](QTreeWidgetItem *) { return true; });
} else {
applyFilter(m_tree->invisibleRootItem(), [text](QTreeWidgetItem *item) {
return item->text(0).contains(text, Qt::CaseInsensitive);
});
}
}
void FilteredTreePopup::showEvent(QShowEvent *e) {
m_filter->setFocus();
QWidget::showEvent(e);
}
bool FilteredTreePopup::focusNextPrevChild(bool) {
// The default Qt tab navigation doesn't seem to work correctly
// in a popup widget
if (m_filter->hasFocus())
m_tree->setFocus();
else
m_filter->setFocus();
return true;
}
SyntaxPopup::SyntaxPopup(QWidget *parent) : FilteredTreePopup(parent) {
connect(tree(), &QTreeWidget::itemActivated, this,
&SyntaxPopup::syntaxItemChosen);
connect(tree(), &QTreeWidget::itemClicked, this,
&SyntaxPopup::syntaxItemChosen);
// Default unformatted option
m_plainTextItem =
new QTreeWidgetItem(tree(), QStringList{tr("Plain Text")});
// Load the syntax definitions (these are already sorted)
auto &syntaxRepo = WingCodeEdit::syntaxRepo();
const auto syntaxDefs = syntaxRepo.definitions();
QMap<QString, QTreeWidgetItem *> groupItems;
for (const auto &def : syntaxDefs) {
if (def.isHidden() || def == WingCodeEdit::nullSyntax())
continue;
QTreeWidgetItem *parentItem =
groupItems.value(def.translatedSection(), Q_NULLPTR);
if (!parentItem) {
parentItem = new QTreeWidgetItem(
tree(), QStringList{def.translatedSection()});
groupItems[def.translatedSection()] = parentItem;
}
auto item =
new QTreeWidgetItem(parentItem, QStringList{def.translatedName()});
item->setData(0, Qt::UserRole, QVariant::fromValue(def));
}
tree()->expandAll();
tree()->resizeColumnToContents(0);
}
void SyntaxPopup::syntaxItemChosen(QTreeWidgetItem *current, int) {
if (!current)
return;
if (current == m_plainTextItem) {
emit syntaxSelected(WingCodeEdit::nullSyntax());
return;
}
QVariant itemData = current->data(0, Qt::UserRole);
if (itemData.canConvert<KSyntaxHighlighting::Definition>())
emit syntaxSelected(itemData.value<KSyntaxHighlighting::Definition>());
}
EncodingPopup::EncodingPopup(QWidget *parent) : FilteredTreePopup(parent) {
connect(tree(), &QTreeWidget::itemActivated, this,
&EncodingPopup::encodingItemChosen);
connect(tree(), &QTreeWidget::itemClicked, this,
&EncodingPopup::encodingItemChosen);
auto encodings = Utilities::getEncodings();
for (auto &e : encodings) {
auto item = new QTreeWidgetItem(tree(), QStringList{e});
item->setData(0, Qt::UserRole, e);
}
tree()->resizeColumnToContents(0);
}
void EncodingPopup::encodingItemChosen(QTreeWidgetItem *current, int) {
if (!current)
return;
QVariant codecName = current->data(0, Qt::UserRole);
if (codecName.isValid())
emit encodingSelected(codecName.toString());
}

107
src/control/settingspopup.h Normal file
View File

@ -0,0 +1,107 @@
/*==============================================================================
** Copyright (C) 2024-2027 WingSummer
**
** This program is free software: you can redistribute it and/or modify it under
** the terms of the GNU Affero General Public License as published by the Free
** Software Foundation, version 3.
**
** 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 Affero General Public License for more
** details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <https://www.gnu.org/licenses/>.
** =============================================================================
*/
// This file is part of QTextPad.
#ifndef SETTINGSPOPUP_H
#define SETTINGSPOPUP_H
#include <KSyntaxHighlighting/Definition>
#include <QIcon>
#include <QLineEdit>
class QTreeWidget;
class QTreeWidgetItem;
class TreeFilterEdit : public QLineEdit {
Q_OBJECT
public:
TreeFilterEdit(QWidget *parent = nullptr);
QSize sizeHint() const override;
Q_SIGNALS:
void navigateDown();
protected:
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
private:
QIcon m_searchIcon;
QPoint m_iconPosition;
void recomputeIconPos();
};
class FilteredTreePopup : public QWidget {
Q_OBJECT
public:
FilteredTreePopup(QWidget *parent = nullptr);
QSize sizeHint() const override;
TreeFilterEdit *filter();
QTreeWidget *tree();
public Q_SLOTS:
void filterItems(const QString &text);
protected:
void showEvent(QShowEvent *e) override;
bool focusNextPrevChild(bool next) override;
private:
TreeFilterEdit *m_filter;
QTreeWidget *m_tree;
};
class SyntaxPopup : public FilteredTreePopup {
Q_OBJECT
public:
SyntaxPopup(QWidget *parent = nullptr);
Q_SIGNALS:
void syntaxSelected(const KSyntaxHighlighting::Definition &syntax);
private Q_SLOTS:
void syntaxItemChosen(QTreeWidgetItem *current, int column);
private:
QTreeWidgetItem *m_plainTextItem;
};
class EncodingPopup : public FilteredTreePopup {
Q_OBJECT
public:
EncodingPopup(QWidget *parent = Q_NULLPTR);
Q_SIGNALS:
void encodingSelected(const QString &codecName);
private Q_SLOTS:
void encodingItemChosen(QTreeWidgetItem *current, int column);
};
// Needed for serializing Definition objects into QVariant
Q_DECLARE_METATYPE(KSyntaxHighlighting::Definition)
#endif // QTEXTPAD_SETTINGSPOPUP_H

View File

@ -972,16 +972,11 @@ MainWindow::buildUpScriptConsoleDock(ads::CDockManager *dock,
connect(m_scriptConsole, &ScriptingConsole::consoleCommand, this,
[this] { showStatus({}); });
// connect(m_scriptConsole, &ScriptingConsole::inputTimeOuted, this, [this]
// {
// auto e =
// qobject_cast<AsCompletion
// *>(m_scriptConsole->completionEngine());
// if (e && e->codeCompletionWidget()->isVisible()) {
// return;
// }
// showStatus({});
// });
connect(m_scriptConsole, &ScriptingConsole::onFunctionTip, this,
[this](const QString &content) {
showStatus(QStringLiteral("<b><font color=\"gold\">") +
content + QStringLiteral("</font></b>"));
});
auto dw = buildDockWidget(dock, QStringLiteral("ScriptConsole"),
tr("ScriptConsole"), m_scriptConsole);

View File

@ -93,10 +93,6 @@ ScriptingDialog::ScriptingDialog(QWidget *parent)
m_dock->restoreState(set.scriptDockLayout());
_savedLayout = set.scriptDockLayout();
// connect(&LangService::instance(), &LangService::onScriptEditorTip,
// m_status,
// [this](const QString &message) { m_status->setText(message); });
this->setUpdatesEnabled(true);
}
@ -783,6 +779,11 @@ void ScriptingDialog::registerEditorView(ScriptEditor *editor) {
Q_ASSERT(editor);
toggleBreakPoint(editor, lineIndex);
});
connect(editor, &ScriptEditor::onFunctionTip, this,
[this](const QString &message) {
m_status->setText(QStringLiteral("<b><font color=\"gold\">") +
message + QStringLiteral("</font></b>"));
});
m_views.append(editor);

View File

@ -20,6 +20,8 @@
#include "class/qkeysequences.h"
#include "class/wingmessagebox.h"
#include "control/codeedit.h"
#include "control/popupactionwidget.h"
#include "control/settingspopup.h"
#include "control/toast.h"
#include "dialog/encodingdialog.h"
@ -28,6 +30,28 @@
constexpr auto EMPTY_FUNC = [] {};
class SyntaxPopupAction : public PopupActionWidget {
public:
explicit SyntaxPopupAction(ShowTextDialog *parent)
: PopupActionWidget(parent) {}
protected:
QWidget *createWidget(QWidget *menuParent) override {
auto popup = new SyntaxPopup(menuParent);
connect(popup, &SyntaxPopup::syntaxSelected, this,
[this](const KSyntaxHighlighting::Definition &syntax) {
auto window = qobject_cast<ShowTextDialog *>(parent());
window->setSyntax(syntax);
// Don't close the popup right after clicking, so the user
// can briefly see the visual feedback for the item they
// selected.
closePopUpWidget();
});
return popup;
}
};
ShowTextDialog::ShowTextDialog(QWidget *parent) : FramelessDialogBase(parent) {
this->setUpdatesEnabled(false);
@ -65,6 +89,10 @@ ShowTextDialog::ShowTextDialog(QWidget *parent) : FramelessDialogBase(parent) {
ShowTextDialog::~ShowTextDialog() {}
void ShowTextDialog::setSyntax(const KSyntaxHighlighting::Definition &syntax) {
m_edit->setSyntax(syntax);
}
void ShowTextDialog::load(QHexBuffer *buffer, const QString encoding,
qsizetype offset, qsizetype size) {
// auto editor = m_edit->editor();

View File

@ -39,6 +39,9 @@ public:
explicit ShowTextDialog(QWidget *parent = nullptr);
virtual ~ShowTextDialog();
public:
void setSyntax(const KSyntaxHighlighting::Definition &syntax);
public:
void load(QHexBuffer *buffer, const QString encoding, qsizetype offset = 0,
qsizetype size = -1);

View File

@ -22,12 +22,18 @@
\see QEditConfig
*/
#include "class/settingmanager.h"
#include "control/codeedit.h"
#include "ui_qeditconfig.h"
#include "utilities.h"
#include "class/skinmanager.h"
#include <QDebug>
#include <KSyntaxHighlighting/Definition>
#include <KSyntaxHighlighting/Repository>
#include <KSyntaxHighlighting/Theme>
/*!
\ingroup dialogs
@{
@ -37,23 +43,91 @@
*/
QEditConfig::QEditConfig(QWidget *w)
QEditConfig::QEditConfig(bool isConsole, QWidget *w)
: WingHex::SettingPage(w), ui(new Ui::QEditConfig()) {
ui->setupUi(this);
loadThemes();
loadIndentations();
QFile code(QStringLiteral(":/com.wingsummer.winghex/src/TESTCODE.as"));
auto ret = code.open(QFile::ReadOnly);
Q_ASSERT(ret);
Q_UNUSED(ret);
auto cbuffer = code.readAll();
_edit = new WingCodeEdit(this);
_edit = new CodeEdit(this);
_edit->setPlainText(QString::fromUtf8(cbuffer));
_edit->setReadOnly(true);
_edit->setUndoRedoEnabled(false);
ui->layoutFont->addWidget(_edit, ui->layoutFont->rowCount(), 0, 1,
ui->layoutFont->columnCount());
_edit->setSyntax(WingCodeEdit::syntaxRepo().definitionForName(
QStringLiteral("AngelScript")));
ui->layoutEdit->addWidget(_edit);
connect(ui->cbTheme, QOverload<int>::of(&QComboBox::currentIndexChanged),
_edit, [this](int index) {
if (index == 0) {
switch (SkinManager::instance().currentTheme()) {
case SkinManager::Theme::Dark:
_edit->setTheme(WingCodeEdit::syntaxRepo().defaultTheme(
KSyntaxHighlighting::Repository::DarkTheme));
break;
case SkinManager::Theme::Light:
_edit->setTheme(WingCodeEdit::syntaxRepo().defaultTheme(
KSyntaxHighlighting::Repository::LightTheme));
break;
}
} else {
_edit->setTheme(WingCodeEdit::syntaxRepo().theme(
ui->cbTheme->itemText(index)));
}
});
auto font = _edit->font();
ui->cbFont->setCurrentFont(font);
ui->spnFontSize->setValue(font.pointSize());
connect(ui->cbFont, &QFontComboBox::currentFontChanged, _edit,
[this](const QFont &font) {
auto f = font;
f.setPointSize(ui->spnFontSize->value());
_edit->setFont(f);
});
connect(ui->spnFontSize, QOverload<int>::of(&QSpinBox::valueChanged), _edit,
[this](int value) {
auto f = ui->cbFont->currentFont();
f.setPointSize(value);
_edit->setFont(f);
});
connect(ui->spnTabWidth, QOverload<int>::of(&QSpinBox::valueChanged), _edit,
&CodeEdit::setIndentWidth);
connect(ui->cbIndentation,
QOverload<int>::of(&QComboBox::currentIndexChanged), _edit,
[this](int index) {
bool b;
auto iden = WingCodeEdit::IndentationMode(
ui->cbIndentation->itemData(index).toInt(&b));
if (b) {
_edit->setIndentationMode(iden);
}
});
connect(ui->chkShowLineNumber, &QCheckBox::toggled, _edit,
&CodeEdit::setShowLineNumbers);
connect(ui->chkShowFolding, &QCheckBox::toggled, _edit,
&CodeEdit::setShowFolding);
connect(ui->chkShowIndentGuides, &QCheckBox::toggled, _edit,
&CodeEdit::setShowIndentGuides);
connect(ui->chkLongLineEdge, &QCheckBox::toggled, _edit,
&CodeEdit::setShowLongLineEdge);
connect(ui->chkWordWrap, &QCheckBox::toggled, _edit,
&CodeEdit::setWordWrap);
connect(ui->chkShowWhitespace, &QCheckBox::toggled, _edit,
&CodeEdit::setShowWhitespace);
connect(ui->chkMatchBraces, &QCheckBox::toggled, _edit,
&CodeEdit::setMatchBraces);
connect(ui->chkAutoCloseChar, &QCheckBox::toggled, _edit,
&CodeEdit::setAutoCloseChar);
reload();
}
@ -65,50 +139,6 @@ QEditConfig::~QEditConfig() { delete ui; }
void QEditConfig::apply() {
QFont font = ui->cbFont->currentFont();
font.setPointSize(ui->spnFontSize->value());
// QEditor::setDefaultFont(font);
// QEditor::setDefaultTabStop(ui->spnTabWidth->value());
// if (ui->chkDetectLE->isChecked()) {
// QEditor::setDefaultLineEnding(QDocument::Conservative);
// } else {
// QEditor::setDefaultLineEnding(
// QDocument::LineEnding(ui->cbLineEndings->currentIndex() + 1));
// }
// QDocument::WhiteSpaceMode ws = QDocument::ShowNone;
// if (ui->chkShowLeadingWhitespace->isChecked())
// ws |= QDocument::ShowLeading;
// if (ui->chkShowTrailingWhitespace->isChecked())
// ws |= QDocument::ShowTrailing;
// if (ui->chkShowTabsInText->isChecked())
// ws |= QDocument::ShowTabs;
// QEditor::setDefaultShowSpaces(ws);
// int flags = QEditor::defaultFlags();
// if (ui->chkReplaceTabs->isChecked())
// flags |= QEditor::ReplaceTabs;
// else
// flags &= ~QEditor::ReplaceTabs;
// if (ui->chkAutoRemoveTrailingWhitespace->isChecked())
// flags |= QEditor::RemoveTrailing;
// else
// flags &= ~QEditor::RemoveTrailing;
// if (ui->chkPreserveTrailingIndent->isChecked())
// flags |= QEditor::PreserveTrailingIndent;
// else
// flags &= ~QEditor::PreserveTrailingIndent;
// QEditor::setDefaultFlags(flags);
SettingManager::instance().save(SettingManager::CODEEDIT);
}
/*!
@ -133,16 +163,16 @@ void QEditConfig::reset() {
ui->spnTabWidth->setValue(4);
ui->chkShowTabsInText->setChecked(true);
ui->chkShowLeadingWhitespace->setChecked(true);
ui->chkShowTrailingWhitespace->setChecked(true);
ui->chkShowWhitespace->setChecked(true);
ui->chkShowIndentGuides->setChecked(true);
ui->chkShowLineNumber->setChecked(true);
ui->chkDetectLE->setChecked(true);
ui->cbLineEndings->setCurrentIndex(0);
// ui->chkDetectLE->setChecked(true);
// ui->cbLineEndings->setCurrentIndex(0);
ui->chkReplaceTabs->setChecked(true);
ui->chkAutoRemoveTrailingWhitespace->setChecked(true);
ui->chkPreserveTrailingIndent->setChecked(false);
// ui->chkReplaceTabs->setChecked(true);
// ui->chkAutoRemoveTrailingWhitespace->setChecked(true);
// ui->chkPreserveTrailingIndent->setChecked(false);
apply();
}
@ -174,127 +204,26 @@ void QEditConfig::reload() {
// QEditor::PreserveTrailingIndent);
}
void QEditConfig::loadThemes() {
QStringList themes;
themes.append(tr("Default"));
for (auto &th : CodeEdit::syntaxRepo().themes()) {
themes.append(th.name());
}
ui->cbTheme->addItems(themes);
}
void QEditConfig::loadIndentations() {
ui->cbIndentation->addItem(tr("IndentMixed"),
int(WingCodeEdit::IndentationMode::IndentMixed));
ui->cbIndentation->addItem(
tr("IndentSpaces"), int(WingCodeEdit::IndentationMode::IndentSpaces));
ui->cbIndentation->addItem(tr("IndentTabs"),
int(WingCodeEdit::IndentationMode::IndentTabs));
}
QIcon QEditConfig::categoryIcon() const { return ICONRES("file"); }
QString QEditConfig::name() const { return tr("Edit"); }
QString QEditConfig::id() const { return QStringLiteral("Edit"); }
/*!
\brief Slot used to apply font size settings
*/
void QEditConfig::on_spnFontSize_valueChanged(int size) {
QFont font = ui->cbFont->currentFont();
font.setPointSize(size);
_edit->setFont(font);
}
/*!
\brief Slot used to apply font family settings
*/
void QEditConfig::on_cbFont_currentFontChanged(QFont font) {
font.setPointSize(ui->spnFontSize->value());
_edit->setFont(font);
}
/*!
\brief Slot used to apply tab width settings
*/
void QEditConfig::on_spnTabWidth_valueChanged(int n) {
// _edit->document()->setTabStop(n);
}
/*!
\brief Slot used to apply tabs replacement settings
*/
void QEditConfig::on_chkReplaceTabs_toggled(bool y) {
// _edit->setFlag(QEditor::ReplaceTabs, y);
}
/*!
\brief Slot used to apply tabs display settings
*/
void QEditConfig::on_chkShowTabsInText_toggled(bool y) {
// auto &doc_ps = QDocumentPrivate::m_documents;
// if (y) {
// for (auto &pdoc : doc_ps) {
// auto doc = pdoc->m_doc;
// doc->setShowSpaces(doc->showSpaces() | QDocument::ShowTabs);
// }
// } else {
// for (auto &pdoc : doc_ps) {
// auto doc = pdoc->m_doc;
// doc->setShowSpaces(doc->showSpaces() & ~QDocument::ShowTabs);
// }
// }
}
/*!
\brief Slot used to apply trailing whitespace display settings
*/
void QEditConfig::on_chkShowLeadingWhitespace_toggled(bool y) {
// auto &doc_ps = QDocumentPrivate::m_documents;
// if (y) {
// for (auto &pdoc : doc_ps) {
// auto doc = pdoc->m_doc;
// doc->setShowSpaces(doc->showSpaces() | QDocument::ShowLeading);
// }
// } else {
// for (auto &pdoc : doc_ps) {
// auto doc = pdoc->m_doc;
// doc->setShowSpaces(doc->showSpaces() & ~QDocument::ShowLeading);
// }
// }
}
/*!
\brief Slot used to apply leading whitespace display settings
*/
void QEditConfig::on_chkShowTrailingWhitespace_toggled(bool y) {
// auto &doc_ps = QDocumentPrivate::m_documents;
// if (y) {
// for (auto &pdoc : doc_ps) {
// auto doc = pdoc->m_doc;
// doc->setShowSpaces(doc->showSpaces() | QDocument::ShowTrailing);
// }
// } else {
// for (auto &pdoc : doc_ps) {
// auto doc = pdoc->m_doc;
// doc->setShowSpaces(doc->showSpaces() & ~QDocument::ShowTrailing);
// }
// }
}
void QEditConfig::on_cbLineEndings_currentIndexChanged(int idx) {
// QDocument::LineEnding le = QDocument::LineEnding(idx + 1);
// _edit->document()->setLineEnding(le);
}
/*!
\brief Slot used to apply line endings auto detectionl settings
*/
void QEditConfig::on_chkDetectLE_toggled(bool y) {
// QDocument::LineEnding le = QDocument::Conservative;
// if (!y) {
// le = QDocument::LineEnding(ui->cbLineEndings->currentIndex() + 1);
// }
// _edit->document()->setLineEnding(le);
}
/*!
\brief Slot used to apply trailing space removal settings
*/
void QEditConfig::on_chkAutoRemoveTrailingWhitespace_toggled(bool y) {
// _edit->setFlag(QEditor::RemoveTrailing, y);
}
/*!
\brief Slot used to indent preservation settings
*/
void QEditConfig::on_chkPreserveTrailingIndent_toggled(bool y) {
// _edit->setFlag(QEditor::PreserveTrailingIndent, y);
}
/*! @} */

View File

@ -2,7 +2,7 @@
#define QEDITCONFIG_H
#include "WingPlugin/settingpage.h"
#include "wingcodeedit.h"
#include "control/codeedit.h"
#include <QWidget>
namespace Ui {
@ -13,7 +13,7 @@ class QEditConfig : public WingHex::SettingPage {
Q_OBJECT
public:
explicit QEditConfig(QWidget *parent = nullptr);
explicit QEditConfig(bool isConsole, QWidget *parent = nullptr);
virtual ~QEditConfig();
public:
@ -26,28 +26,13 @@ public:
private:
void reload();
private slots:
void on_spnFontSize_valueChanged(int size);
void on_cbFont_currentFontChanged(QFont font);
void on_spnTabWidth_valueChanged(int n);
void on_chkReplaceTabs_toggled(bool y);
void on_chkShowTabsInText_toggled(bool y);
void on_chkShowLeadingWhitespace_toggled(bool y);
void on_chkShowTrailingWhitespace_toggled(bool y);
void on_cbLineEndings_currentIndexChanged(int idx);
void on_chkDetectLE_toggled(bool y);
void on_chkAutoRemoveTrailingWhitespace_toggled(bool y);
void on_chkPreserveTrailingIndent_toggled(bool y);
void loadThemes();
void loadIndentations();
private:
Ui::QEditConfig *ui;
WingCodeEdit *_edit;
CodeEdit *_edit;
};
#endif // QEDITCONFIG_H

View File

@ -10,34 +10,31 @@
<height>586</height>
</rect>
</property>
<layout class="QVBoxLayout">
<layout class="QVBoxLayout" name="layoutEdit">
<item>
<widget class="QGroupBox" name="gbFont">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Font</string>
<string>Preference</string>
</property>
<layout class="QGridLayout" name="layoutFont">
<item row="1" column="0">
<widget class="QFontComboBox" name="cbFont">
<property name="font">
<font>
<family>Monospace</family>
</font>
</property>
<property name="currentFont">
<font>
<family>Tahoma</family>
</font>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Theme</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<item row="0" column="1">
<widget class="QComboBox" name="cbTheme"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>FontSize</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spnFontSize">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::ButtonSymbols::UpDownArrows</enum>
@ -53,22 +50,75 @@
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QLabel" name="label">
<item row="1" column="1">
<widget class="QFontComboBox" name="cbFont">
<property name="font">
<font>
<bold>true</bold>
<underline>true</underline>
<family>Monospace</family>
</font>
</property>
<property name="text">
<string>Takes Effect on Terminal as well</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
<property name="currentFont">
<font>
<family>Tahoma</family>
</font>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Font</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Tab width</string>
</property>
<property name="buddy">
<cstring>spnTabWidth</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spnTabWidth">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="value">
<number>4</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Indentation</string>
</property>
<property name="buddy">
<cstring>spnTabWidth</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="cbIndentation"/>
</item>
</layout>
</widget>
</item>
@ -81,102 +131,53 @@
</sizepolicy>
</property>
<property name="title">
<string>Tabulators &amp;&amp; Whitespaces</string>
<string>Options</string>
</property>
<layout class="QVBoxLayout">
<property name="margin" stdset="0">
<number>5</number>
</property>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="lblTabWitdh">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Tab width</string>
</property>
<property name="buddy">
<cstring>spnTabWidth</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spnTabWidth">
<property name="value">
<number>4</number>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="chkShowLeadingWhitespace">
<property name="text">
<string>Show leading whitespaces</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkShowTabsInText">
<property name="text">
<string>Show tabs which are neither leading nor trailing</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkShowTrailingWhitespace">
<property name="text">
<string>Show trailing whitespaces</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkReplaceTabs">
<property name="text">
<string>Replace tabs by blanks</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gbEncodings">
<property name="title">
<string>Load &amp;&amp; Save</string>
</property>
<layout class="QGridLayout" name="gridLayout_1">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="chkDetectLE">
<widget class="QCheckBox" name="chkShowLineNumber">
<property name="text">
<string>Preserve line endings</string>
<string>LineNumber</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="chkWordWrap">
<property name="text">
<string>WordWrap</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="chkShowWhitespace">
<property name="text">
<string>Whitespace</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QCheckBox" name="chkAutoCloseChar">
<property name="text">
<string>AutoCloseChar</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="chkMatchBraces">
<property name="text">
<string>MatchBraces</string>
</property>
<property name="checked">
<bool>true</bool>
@ -184,103 +185,40 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="cbLineEndings">
<property name="enabled">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>Local</string>
</property>
</item>
<item>
<property name="text">
<string>Unix/Linux</string>
</property>
</item>
<item>
<property name="text">
<string>DOS/Windows</string>
</property>
</item>
<item>
<property name="text">
<string>Old Mac</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="chkAutoRemoveTrailingWhitespace">
<widget class="QCheckBox" name="chkShowFolding">
<property name="text">
<string>Remove trailing spaces</string>
<string>Folding</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="chkPreserveTrailingIndent">
<property name="enabled">
<item row="0" column="3">
<widget class="QCheckBox" name="chkLongLineEdge">
<property name="text">
<string>LongLineEdge</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="chkShowIndentGuides">
<property name="text">
<string>Preserve trailing indent</string>
<string>IndentGuides</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>492</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>chkDetectLE</sender>
<signal>toggled(bool)</signal>
<receiver>cbLineEndings</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>190</x>
<y>445</y>
</hint>
<hint type="destinationlabel">
<x>279</x>
<y>444</y>
</hint>
</hints>
</connection>
<connection>
<sender>chkAutoRemoveTrailingWhitespace</sender>
<signal>toggled(bool)</signal>
<receiver>chkPreserveTrailingIndent</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>176</x>
<y>475</y>
</hint>
<hint type="destinationlabel">
<x>287</x>
<y>479</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>