feat: 增加 clang-format 的支持;完善代码自动填充;完善代码编辑器组件功能;

This commit is contained in:
寂静的羽夏 2024-11-17 21:46:46 +08:00
parent 48cf02cfa9
commit d5a4095779
53 changed files with 1907 additions and 1146 deletions

View File

@ -9,7 +9,7 @@
QConsoleIODevice::QConsoleIODevice(QConsoleWidget *w, QObject *parent)
: QIODevice(parent), widget_(w), readpos_(0), writtenSinceLastEmit_(0),
readSinceLastEmit_(0) {
setCurrentWriteChannel(QConsoleWidget::StandardOutput);
setCurrentWriteChannel(STDOUT_FILENO);
open(QIODevice::ReadWrite | QIODevice::Unbuffered);
}
@ -53,10 +53,10 @@ qint64 QConsoleIODevice::readData(char *data, qint64 len) {
qint64 QConsoleIODevice::writeData(const char *data, qint64 len) {
QByteArray ba(data, (int)len);
int ch = currentWriteChannel();
if (ch == QConsoleWidget::StandardError)
widget_->writeStdErr(ba);
else
if (ch == STDOUT_FILENO)
widget_->writeStdOut(ba);
else
widget_->writeStdErr(ba);
writtenSinceLastEmit_ += len;
if (!signalsBlocked()) {

View File

@ -6,6 +6,14 @@
class QConsoleWidget;
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
#define STDERR_FILENO 2
#endif
class QConsoleIODevice : public QIODevice {
Q_OBJECT

View File

@ -1,12 +1,14 @@
#include "QConsoleWidget.h"
#include "QConsoleIODevice.h"
#include "class/langservice.h"
#include "class/ascompletion.h"
#include "control/qcodecompletionwidget.h"
#include "qdocumentline.h"
#include "qformatscheme.h"
#include "qlanguagefactory.h"
#include "utilities.h"
#include "QConsoleIODevice.h"
#include <QApplication>
#include <QClipboard>
#include <QDebug>
@ -19,18 +21,8 @@
#include <QScrollBar>
QConsoleWidget::QConsoleWidget(QWidget *parent)
: QEditor(false, parent), mode_(Output), completer_(nullptr) {
: QEditor(false, parent), mode_(Output) {
iodevice_ = new QConsoleIODevice(this, this);
// QTextCharFormat fmt = currentCharFormat();
// for (int i = 0; i < nConsoleChannels; i++)
// chanFormat_[i] = fmt;
chanFormat_[StandardOutput].setForeground(Qt::darkBlue);
chanFormat_[StandardError].setForeground(Qt::red);
// setTextInteractionFlags();
setUndoRedoEnabled(false);
}
@ -44,7 +36,6 @@ void QConsoleWidget::setMode(ConsoleMode m) {
auto cursor = this->cursor();
cursor.movePosition(QDocumentCursor::End);
setCursor(cursor);
// setCurrentCharFormat(chanFormat_[StandardInput]);
inpos_ = cursor;
mode_ = Input;
}
@ -88,34 +79,26 @@ void QConsoleWidget::handleReturnKey() {
emit consoleCommand(code);
}
void QConsoleWidget::setCompleter(QCodeCompletionWidget *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 &)));
}
}
void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
if (completer_ && completer_->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 (mode() == Input) {
auto ascom = dynamic_cast<AsCompletion *>(completionEngine());
if (ascom) {
auto cw = ascom->codeCompletionWidget();
if (cw && cw->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;
}
}
}
}
@ -302,7 +285,6 @@ bool QConsoleWidget::canPaste() const {
}
void QConsoleWidget::replaceCommandLine(const QString &str) {
// Select the text after the last command prompt ...
auto textCursor = this->cursor();
auto line = textCursor.line();
@ -321,25 +303,14 @@ QString QConsoleWidget::getHistoryPath() {
return dir.absoluteFilePath(QStringLiteral(".command_history.lst"));
}
void QConsoleWidget::write(const QString &message, const QTextCharFormat &fmt) {
// QTextCharFormat currfmt = currentCharFormat();
void QConsoleWidget::write(const QString &message, const QString &sfmtID) {
auto tc = cursor();
auto ascom = dynamic_cast<AsCompletion *>(completionEngine());
Q_ASSERT(ascom);
auto cw = ascom->codeCompletionWidget();
if (mode() == Input) {
// in Input mode output messages are inserted
// before the edit block
// get offset of current pos from the end
auto editpos = tc;
auto line = editpos.line();
tc.moveTo(line, 0);
tc.insertLine();
tc.insertText(message /*, fmt*/);
setCursor(editpos);
// setCurrentCharFormat(currfmt);
} else {
// in output mode messages are appended
if (mode() == Output || (cw && cw->isCompleting())) {
// in output mode or completion messages are appended
auto tc1 = tc;
tc1.movePosition(QDocumentCursor::End);
@ -349,21 +320,32 @@ void QConsoleWidget::write(const QString &message, const QTextCharFormat &fmt) {
// insert text
setCursor(tc1);
tc.insertText(message /*, fmt*/);
tc.insertText(message, false, sfmtID);
ensureCursorVisible();
// restore cursor if needed
if (needsRestore)
setCursor(tc);
} else {
// in Input mode output messages are inserted
// before the edit block
// get offset of current pos from the end
auto editpos = tc;
auto line = editpos.line();
tc.moveTo(line, 0);
tc.insertLine();
tc.insertText(message, false, sfmtID);
setCursor(editpos);
}
}
void QConsoleWidget::writeStdOut(const QString &s) {
write(s, chanFormat_[StandardOutput]);
write(s, QStringLiteral("stdout"));
}
void QConsoleWidget::writeStdErr(const QString &s) {
write(s, chanFormat_[StandardError]);
write(s, QStringLiteral("stderr"));
}
/////////////////// QConsoleWidget::History /////////////////////
@ -454,12 +436,12 @@ QTextStream &inputMode(QTextStream &s) {
QTextStream &outChannel(QTextStream &s) {
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
if (d)
d->setCurrentWriteChannel(QConsoleWidget::StandardOutput);
d->setCurrentWriteChannel(STDOUT_FILENO);
return s;
}
QTextStream &errChannel(QTextStream &s) {
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
if (d)
d->setCurrentWriteChannel(QConsoleWidget::StandardError);
d->setCurrentWriteChannel(STDERR_FILENO);
return s;
}

View File

@ -5,7 +5,6 @@
#include <QTextCharFormat>
#include <QTextStream>
#include "control/qcodecompletionwidget.h"
#include "qeditor.h"
#include "qlanguagefactory.h"
@ -18,31 +17,20 @@ public:
enum ConsoleMode { Input, Output };
Q_ENUM(ConsoleMode)
enum ConsoleChannel {
StandardInput,
StandardOutput,
StandardError,
nConsoleChannels
};
Q_ENUM(ConsoleChannel)
explicit QConsoleWidget(QWidget *parent = nullptr);
virtual ~QConsoleWidget();
ConsoleMode mode() const { return mode_; }
void setMode(ConsoleMode m);
QIODevice *device() const { return (QIODevice *)iodevice_; }
QTextCharFormat channelCharFormat(ConsoleChannel ch) const {
return chanFormat_[ch];
}
void setChannelCharFormat(ConsoleChannel ch, const QTextCharFormat &fmt) {
chanFormat_[ch] = fmt;
}
virtual QSize sizeHint() const override { return QSize(600, 400); }
// write a formatted message to the console
void write(const QString &message, const QTextCharFormat &fmt);
void write(const QString &message, const QString &sfmtID = {}) override;
static const QStringList &history() { return history_.strings_; }
void setCompleter(QCodeCompletionWidget *c);
// get the current command line
QString getCommandLine();
@ -103,8 +91,6 @@ private:
QDocumentCursor inpos_;
QString currentMultiLineCode_;
QConsoleIODevice *iodevice_;
QTextCharFormat chanFormat_[nConsoleChannels];
QCodeCompletionWidget *completer_;
QLanguageFactory *m_language = nullptr;
};

File diff suppressed because it is too large Load Diff

View File

@ -192,18 +192,15 @@ public:
void flushMatches(int groupId);
void addMatch(int groupId, int line, int pos, int len, int format);
static QFont font();
static void setFont(const QFont &f);
static const QFontMetrics &fontMetrics();
QFont font();
void setFont(const QFont &f);
const QFontMetrics &fontMetrics();
static LineEnding defaultLineEnding();
static void setDefaultLineEnding(LineEnding le);
int tabStop();
void setTabStop(int n);
static int tabStop();
static void setTabStop(int n);
static WhiteSpaceMode showSpaces();
static void setShowSpaces(WhiteSpaceMode y);
WhiteSpaceMode showSpaces();
void setShowSpaces(WhiteSpaceMode y);
static QFormatScheme *defaultFormatScheme();
static void setDefaultFormatScheme(QFormatScheme *f);

View File

@ -86,7 +86,7 @@ public:
void setWidth();
void setHeight();
static void setFont(const QFont &f);
void setFont(const QFont &f);
void beginChangeBlock();
void endChangeBlock();
@ -120,7 +120,6 @@ public:
void setWidth(int width);
void emitFormatsChanged();
void emitContentsChanged();
void emitLineDeleted(QDocumentLineHandle *h);
@ -165,7 +164,7 @@ private:
struct Match {
int line;
QFormatRange range;
QDocumentLineHandle *h;
QDocumentLineHandle *h = nullptr;
};
struct MatchList : QList<Match> {
@ -182,21 +181,19 @@ private:
int m_width, m_height;
int m_tabStop;
static int m_defaultTabStop;
static QFont *m_font;
static bool m_fixedPitch;
static QFontMetrics *m_fontMetrics;
static int m_leftMargin;
static QDocument::WhiteSpaceMode m_showSpaces;
static QDocument::LineEnding m_defaultLineEnding;
static int m_lineHeight;
static int m_lineSpacing;
static int m_spaceWidth;
static int m_ascent;
static int m_descent;
static int m_leading;
static int m_wrapMargin;
QFont m_font;
bool m_fixedPitch;
QFontMetrics m_fontMetrics;
int m_leftMargin;
QDocument::WhiteSpaceMode m_showSpaces;
int m_lineHeight;
int m_lineSpacing;
int m_spaceWidth;
int m_ascent;
int m_descent;
int m_leading;
int m_wrapMargin;
QFormatScheme *m_formatScheme;
QLanguageDefinition *m_language;

View File

@ -21,6 +21,7 @@
*/
#include "qdocument_p.h"
#include "qformatscheme.h"
/*!
\ingroup document
@ -142,7 +143,8 @@ void QDocumentCommand::setUndoOffset(int off) { m_undoOffset = off; }
This helper method is provided so that subclasses may actually
modify the document contents without using private API.
*/
void QDocumentCommand::insertText(int line, int pos, const QString &s) {
void QDocumentCommand::insertText(int line, int pos, const QString &s,
const QString &sfmtID) {
if (!m_doc)
return;
@ -155,6 +157,19 @@ void QDocumentCommand::insertText(int line, int pos, const QString &s) {
h->textBuffer().insert(pos, s);
h->shiftOverlays(pos, s.length());
if (!sfmtID.isEmpty()) {
auto fmt = m_doc->formatScheme();
auto id = fmt->id(sfmtID);
if (id) {
QFormatRange range;
range.format = id;
range.offset = pos;
range.length = s.length();
h->addOverlay(range);
}
}
pd->adjustWidth(line);
}
@ -484,8 +499,9 @@ void QDocumentCommand::markUndone(QDocumentLineHandle *h) {
QDocumentInsertCommand::QDocumentInsertCommand(int l, int offset,
const QString &text,
QDocument *doc,
const QString &sfmtID,
QDocumentCommand *p)
: QDocumentCommand(Insert, doc, p) {
: QDocumentCommand(Insert, doc, p), m_sfmtID(sfmtID) {
QStringList lines = text.split(QLatin1Char('\n'), Qt::KeepEmptyParts);
if (!m_doc || text.isEmpty())
@ -497,8 +513,9 @@ QDocumentInsertCommand::QDocumentInsertCommand(int l, int offset,
m_data.begin = lines.takeAt(0);
m_data.endOffset = lines.count() ? lines.last().length() : -1;
foreach (const QString &s, lines)
for (auto &s : lines) {
m_data.handles << new QDocumentLineHandle(s, m_doc);
}
QDocumentLine bl = m_doc->line(l);
@ -541,7 +558,7 @@ void QDocumentInsertCommand::redo() {
removeText(m_data.lineNumber, m_data.startOffset, m_data.end.length());
}
insertText(m_data.lineNumber, m_data.startOffset, m_data.begin);
insertText(m_data.lineNumber, m_data.startOffset, m_data.begin, m_sfmtID);
insertLines(m_data.lineNumber, m_data.handles);

View File

@ -41,7 +41,7 @@ public:
QList<QDocumentLineHandle *> handles;
};
QDocumentCommand(Command c, QDocument *d, QDocumentCommand *p = 0);
QDocumentCommand(Command c, QDocument *d, QDocumentCommand *p = nullptr);
virtual ~QDocumentCommand();
virtual int id() const;
@ -77,7 +77,8 @@ protected:
void updateTarget(int l, int offset);
void insertText(int line, int pos, const QString &s);
void insertText(int line, int pos, const QString &s,
const QString &sfmtID = {});
void removeText(int line, int pos, int length);
void insertLines(int after, const QList<QDocumentLineHandle *> &l);
@ -102,7 +103,8 @@ Q_DECLARE_TYPEINFO(QDocumentCommand::TextCommandData, Q_MOVABLE_TYPE);
class QCE_EXPORT QDocumentInsertCommand : public QDocumentCommand {
public:
QDocumentInsertCommand(int l, int offset, const QString &text,
QDocument *doc, QDocumentCommand *p = 0);
QDocument *doc, const QString &sfmtID = 0,
QDocumentCommand *p = nullptr);
virtual ~QDocumentInsertCommand();
@ -113,12 +115,13 @@ public:
private:
TextCommandData m_data;
QString m_sfmtID;
};
class QCE_EXPORT QDocumentEraseCommand : public QDocumentCommand {
public:
QDocumentEraseCommand(int bl, int bo, int el, int eo, QDocument *doc,
QDocumentCommand *p = 0);
QDocumentCommand *p = nullptr);
virtual ~QDocumentEraseCommand();

View File

@ -515,9 +515,10 @@ void QDocumentCursor::insertLine(bool keepAnchor) {
\note Nothing happens if \a s is empty
*/
void QDocumentCursor::insertText(const QString &s, bool keepAnchor) {
void QDocumentCursor::insertText(const QString &s, bool keepAnchor,
const QString &sfmtID) {
if (m_handle)
m_handle->insertText(s, keepAnchor);
m_handle->insertText(s, keepAnchor, sfmtID);
}
/*!

View File

@ -141,7 +141,8 @@ public:
void eraseLine();
void insertLine(bool keepAnchor = false);
void insertText(const QString &s, bool keepAnchor = false);
void insertText(const QString &s, bool keepAnchor = false,
const QString &sfmtID = {});
QDocumentCursor selectionStart() const;
QDocumentCursor selectionEnd() const;

View File

@ -92,7 +92,8 @@ public:
void shift(int offset);
bool movePosition(int offset, int op, int m);
void insertText(const QString &s, bool keepAnchor = false);
void insertText(const QString &s, bool keepAnchor = false,
const QString &sfmtID = {});
QChar nextChar() const;
QChar previousChar() const;

View File

@ -59,7 +59,7 @@ void addDataPath(const QString &path);
template <typename Registerable>
class Registar {
public:
Registar() { Registerable::_register(); }
constexpr Registar() { Registerable::_register(); }
};
// added by wingsummer

View File

@ -1927,34 +1927,6 @@ void QEditor::paste() {
insertFromMimeData(d);
}
static bool unindent(const QDocumentCursor &cur) {
QDocumentLine beg(cur.line());
int r = 0, n = 0, t = QDocument::tabStop();
QString txt = beg.text().left(beg.firstChar());
while (txt.size() && (n < t)) {
if (txt.at(txt.length() - 1) == '\t')
n += t - (n % t);
else
++n;
++r;
txt.chop(1);
}
if (!r)
return false;
QDocumentCursor c(cur);
c.setSilent(true);
c.movePosition(1, QDocumentCursor::StartOfBlock,
QDocumentCursor::MoveAnchor);
c.movePosition(r, QDocumentCursor::Right, QDocumentCursor::KeepAnchor);
c.removeSelectedText();
return true;
}
static void insert(const QDocumentCursor &cur, const QString &txt) {
QDocumentCursor c(cur);
c.setSilent(true);
@ -2325,6 +2297,11 @@ bool QEditor::protectedCursor(const QDocumentCursor &c) const {
\internal
*/
void QEditor::keyPressEvent(QKeyEvent *e) {
if (flag(ReadOnly)) {
e->ignore();
return;
}
for (auto &b : m_bindings)
if (b->keyPressEvent(e, this))
return;
@ -2534,13 +2511,10 @@ void QEditor::inputMethodEvent(QInputMethodEvent *e) {
if (b->inputMethodEvent(e, this))
return;
/*
if ( m_doc->readOnly() )
{
e->ignore();
return;
if (flag(ReadOnly)) {
e->ignore();
return;
}
*/
m_cursor.beginEditBlock();
@ -3471,7 +3445,7 @@ void QEditor::pageUp(QDocumentCursor::MoveMode moveMode) {
if (m_cursor.atStart())
return;
int n = viewport()->height() / QDocument::fontMetrics().lineSpacing();
int n = viewport()->height() / m_doc->fontMetrics().lineSpacing();
repaintCursor();
m_cursor.movePosition(n, QDocumentCursor::Up, moveMode);
@ -3493,7 +3467,7 @@ void QEditor::pageDown(QDocumentCursor::MoveMode moveMode) {
if (m_cursor.atEnd())
return;
int n = viewport()->height() / QDocument::fontMetrics().lineSpacing();
int n = viewport()->height() / m_doc->fontMetrics().lineSpacing();
repaintCursor();
m_cursor.movePosition(n, QDocumentCursor::Down, moveMode);
@ -3691,7 +3665,8 @@ void QEditor::preInsert(QDocumentCursor &c, const QString &s) {
This function is provided to keep indenting/outdenting working when
editing
*/
void QEditor::insertText(QDocumentCursor &c, const QString &text) {
void QEditor::insertText(QDocumentCursor &c, const QString &text,
const QString &sfmtID) {
if (protectedCursor(c))
return;
@ -3712,11 +3687,11 @@ void QEditor::insertText(QDocumentCursor &c, const QString &text) {
// TODO : replace tabs by spaces properly
}
c.insertText(text);
c.insertText(text, false, sfmtID);
} else {
preInsert(c, lines.first());
c.insertText(lines.takeFirst());
c.insertText(lines.takeFirst(), false, sfmtID);
QString indent;
// FIXME ? work on strings to make sure command grouping does not
@ -3743,11 +3718,11 @@ void QEditor::insertText(QDocumentCursor &c, const QString &text) {
}
c.insertLine();
c.insertText(indent);
c.insertText(indent, false, sfmtID);
preInsert(c, l);
c.insertText(l);
c.insertText(l, false, sfmtID);
}
}
}
@ -3759,13 +3734,13 @@ void QEditor::insertText(QDocumentCursor &c, const QString &text) {
from the outside and to keep them compatible with cursor
mirrors.
*/
void QEditor::write(const QString &s) {
void QEditor::write(const QString &s, const QString &sfmtID) {
m_doc->beginMacro();
insertText(m_cursor, s);
insertText(m_cursor, s, sfmtID);
for (int i = 0; i < m_mirrors.count(); ++i)
insertText(m_mirrors[i], s);
insertText(m_mirrors[i], s, sfmtID);
m_doc->endMacro();
@ -3850,7 +3825,7 @@ void QEditor::ensureCursorVisible() {
QPoint pos = m_cursor.documentPosition();
const int ls = QDocument::fontMetrics().lineSpacing();
const int ls = m_doc->fontMetrics().lineSpacing();
int ypos = pos.y(), yval = verticalOffset(), ylen = viewport()->height(),
yend = ypos + ls;
@ -3882,7 +3857,7 @@ void QEditor::ensureVisible(int line) {
if (!m_doc)
return;
const int ls = QDocument::fontMetrics().lineSpacing();
const int ls = m_doc->fontMetrics().lineSpacing();
int ypos = m_doc->y(line), yval = verticalOffset(),
ylen = viewport()->height(), yend = ypos + ls;
@ -3900,7 +3875,7 @@ void QEditor::ensureVisible(const QRect &rect) {
if (!m_doc)
return;
const int ls = QDocument::fontMetrics().lineSpacing();
const int ls = m_doc->fontMetrics().lineSpacing();
int ypos = rect.y(), yval = verticalOffset(), ylen = viewport()->height(),
yend = ypos + rect.height();
@ -4002,7 +3977,7 @@ QRect QEditor::lineRect(const QDocumentLine &l) const {
\return The line rect of the given cursor
*/
QRect QEditor::cursorRect(const QDocumentCursor &c) const {
return QEditor::lineRect(c.lineNumber());
return QEditor::lineRect(c.lineNumber()).adjusted(0, -1, 0, 1);
}
/*!
@ -4164,6 +4139,34 @@ void QEditor::addCursorMirror(const QDocumentCursor &c) {
bool QEditor::undoRedoEnabled() const { return m_undoRedoEnabled; }
bool QEditor::unindent(const QDocumentCursor &cur) {
QDocumentLine beg(cur.line());
int r = 0, n = 0, t = m_doc->tabStop();
QString txt = beg.text().left(beg.firstChar());
while (txt.size() && (n < t)) {
if (txt.at(txt.length() - 1) == '\t')
n += t - (n % t);
else
++n;
++r;
txt.chop(1);
}
if (!r)
return false;
QDocumentCursor c(cur);
c.setSilent(true);
c.movePosition(1, QDocumentCursor::StartOfBlock,
QDocumentCursor::MoveAnchor);
c.movePosition(r, QDocumentCursor::Right, QDocumentCursor::KeepAnchor);
c.removeSelectedText();
return true;
}
/*!
\internal
\brief Copy the selection to the clipboard

View File

@ -237,7 +237,7 @@ public slots:
virtual void retranslate();
virtual void write(const QString &s);
virtual void write(const QString &s, const QString &sfmtID = {});
void addAction(QAction *a, const QString &menu,
const QString &toolbar = QString());
@ -372,7 +372,8 @@ public:
void ensureVisible(const QRect &rect);
void preInsert(QDocumentCursor &c, const QString &text);
void insertText(QDocumentCursor &c, const QString &text);
void insertText(QDocumentCursor &c, const QString &text,
const QString &sfmtID = {});
QDocumentLine lineAtPosition(const QPoint &p) const;
QDocumentCursor cursorForPosition(const QPoint &p) const;
@ -388,6 +389,9 @@ public:
bool undoRedoEnabled() const;
private:
bool unindent(const QDocumentCursor &cur);
protected slots:
void documentWidthChanged(int newWidth);
void documentHeightChanged(int newWidth);

View File

@ -156,6 +156,8 @@ public slots:
void toggleLineMark(const QLineMarkHandle &mark);
void removeLineMark(const QLineMarkHandle &mark);
void lineDeleted(QDocumentLineHandle *h);
void flush(const QString &file);
signals:
@ -168,7 +170,6 @@ protected:
protected slots:
void cursorMoved(QEditor *e);
void lineDeleted(QDocumentLineHandle *h);
void markChanged(const QString &f, QDocumentLineHandle *h, int mark,
bool on);

View File

@ -73,8 +73,6 @@ void QLineChangePanel::paint(QPainter *p, QEditor *e) {
pageBottom = e->viewport()->height(),
contentsY = e->verticalOffset();
QString txt;
QDocument *d = e->document();
n = d->lineNumber(contentsY);
posY = 2 + d->y(n) - contentsY;

View File

@ -232,7 +232,9 @@ set(CLASS_SRC
src/class/qcodenode.cpp
src/class/qcodenode.h
src/class/langservice.h
src/class/langservice.cpp)
src/class/langservice.cpp
src/class/clangformatmanager.h
src/class/clangformatmanager.cpp)
if(WINGHEX_USE_FRAMELESS)
set(WIDGET_FRAME_SRC
@ -268,6 +270,7 @@ set(MODEL_SRC
src/model/dbgbreakpointmodel.cpp)
set(SETTING_SRC
src/settings/settings.h
src/settings/generalsettingdialog.h
src/settings/generalsettingdialog.cpp
src/settings/generalsettingdialog.ui
@ -285,7 +288,10 @@ set(SETTING_SRC
src/settings/scriptbehaviorsettingdialog.ui
src/settings/othersettingsdialog.h
src/settings/othersettingsdialog.cpp
src/settings/othersettingsdialog.ui)
src/settings/othersettingsdialog.ui
src/settings/clangformatsetdialog.h
src/settings/clangformatsetdialog.cpp
src/settings/clangformatsetdialog.ui)
set(SCRIPT_ADDON_SRC
src/scriptaddon/scriptqstring.h
@ -312,7 +318,9 @@ set(CODEEDIT_WIDGET
src/qcodeeditwidget/qformatconfig.ui
src/qcodeeditwidget/qsnippetedit.cpp
src/qcodeeditwidget/qsnippetedit.h
src/qcodeeditwidget/qsnippetedit.ui)
src/qcodeeditwidget/qsnippetedit.ui
src/qcodeeditwidget/qdocumentswaptextcommand.h
src/qcodeeditwidget/qdocumentswaptextcommand.cpp)
set(PLUGIN_SRC src/plugin/iwingplugin.h src/plugin/pluginsystem.cpp
src/plugin/pluginsystem.h src/plugin/settingpage.h)

BIN
images/codefmt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
images/codeformat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
images/snippt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

File diff suppressed because it is too large Load Diff

View File

@ -45,7 +45,6 @@ def main():
"folder", help="A folder that has contained the binary build")
parser.add_argument("-c", "--cc", help="where ISCC.exe locates", default="C:\Program Files (x86)\Inno Setup 6\ISCC.exe")
parser.add_argument("-o", "--output", help="where to put the installer")
parser.add_argument("--no-build", action='store_false')
args = parser.parse_args()
@ -231,7 +230,7 @@ Source: {#MyAppExePath}; DestDir: "{app}"; Flags: ignoreversion
"""
iss_content += r'Root: HKCR; Subkey: "*\shell\OpenWithWingHexExplorer"; ValueType: expandsz; ValueName: ""; ValueData: {cm:OpenWithWingHexExplorer}; Flags: uninsdeletekey' + '\n'
iss_content += r'Root: HKCR; Subkey: "*\shell\WingHexExplorer"; ValueType: expandsz; ValueName: "Icon"; ValueData: {app}\{#MyAppExeName}; Flags: uninsdeletekey' + '\n'
iss_content += r'Root: HKCR; Subkey: "*\shell\OpenWithWingHexExplorer"; ValueType: expandsz; ValueName: "Icon"; ValueData: {app}\{#MyAppExeName}; Flags: uninsdeletekey' + '\n'
iss_content += r'Root: HKCR; Subkey: "*\shell\OpenWithWingHexExplorer\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey' + '\n'
iss_content += """
@ -249,19 +248,18 @@ Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChang
with codecs.open(script_src,'w', "utf-8-sig") as iss:
iss.write(iss_content)
if(args.build):
print(Fore.GREEN + ">> Copying finished, running ISCC building..." + Style.RESET_ALL)
pak_out = ""
if args.output is None:
pak_out = exeDebPath
else:
pak_out = args.output
ret = run_command_interactive([args.cc, f'/O{pak_out}', script_src])
exit(ret)
exit(0)
print(Fore.GREEN + ">> Copying finished, running ISCC building..." + Style.RESET_ALL)
pak_out = ""
if args.output is None:
pak_out = exeDebPath
else:
pak_out = args.output
ret = run_command_interactive([args.cc, f'/O{pak_out}', script_src])
exit(ret)
if __name__ == "__main__":
main()

View File

@ -10,6 +10,8 @@
<file>images/clearhis.png</file>
<file>images/clone.png</file>
<file>images/closefile.png</file>
<file>images/codefmt.png</file>
<file>images/codeformat.png</file>
<file>images/copy.png</file>
<file>images/copyhex.png</file>
<file>images/cut.png</file>
@ -89,6 +91,7 @@
<file>images/scriptfolderusr.png</file>
<file>images/setting.png</file>
<file>images/settingplugin.png</file>
<file>images/snippt.png</file>
<file>images/soft.png</file>
<file>images/sponsor.png</file>
<file>images/sum.png</file>
@ -100,6 +103,7 @@
<file>images/win.png</file>
<file>images/workspace.png</file>
<file>images/writable.png</file>
<file>src/TESTCODE.as</file>
</qresource>
<qresource prefix="/qpathedit/icons">
<file alias="dialog.ico">3rdparty/QPathEdit/Fatcow-Farm-Fresh-Dialog.ico</file>
@ -114,14 +118,13 @@
<file alias="copy.png">images/copy.png</file>
<file alias="cut.png">images/cut.png</file>
<file alias="find.png">images/find.png</file>
<file alias="goto.png">images/goto.png</file>
<file alias="paste.png">images/paste.png</file>
<file alias="redo.png">images/redo.png</file>
<file alias="replace.png">images/replace.png</file>
<file alias="undo.png">images/undo.png</file>
<file alias="goto.png">images/goto.png</file>
</qresource>
<qresource prefix="/completion">
<file>images/completion/classnew.png</file>
<file>images/completion/CTvirtuals.png</file>
<file>images/completion/CVclass.png</file>
<file>images/completion/CVenum.png</file>
@ -146,5 +149,6 @@
<file>images/completion/CVstruct.png</file>
<file>images/completion/CVtypedef.png</file>
<file>images/completion/CVunion.png</file>
<file>images/completion/classnew.png</file>
</qresource>
</RCC>

19
src/TESTCODE.as Normal file
View File

@ -0,0 +1,19 @@
#include <wingsummer>
class CMyClass {
int method() { a++; return a; }
int method() const { return a; }
int a;
}
int main() {
// This is a script
for (int i = 0; i < 5; ++i){
print("hello world!")
}
print("AngelScript for WingHexExplorer2 by wingsummer.")
return 0;
}

View File

@ -19,6 +19,8 @@
#include <QFont>
#include "class/clangformatmanager.h"
#include "class/langservice.h"
#include "class/logger.h"
#include "languagemanager.h"
#include "settingmanager.h"
@ -58,6 +60,7 @@ AppManager::AppManager(int &argc, char *argv[])
SkinManager::instance();
LanguageManager::instance();
ClangFormatManager::instance();
_w = new MainWindow;

View File

@ -82,8 +82,11 @@ void AsCompletion::complete(const QDocumentCursor &c, const QString &trigger) {
// parser.parse(codes, this->editor()->fileName());
// QList<QCodeNode *> nodes = parser.codeNodes();
auto txt = c.line().text().left(c.columnNumber());
auto code = txt.toUtf8();
auto txt = c.line().text();
if (txt.isEmpty()) {
return;
}
auto code = txt.left(c.columnNumber()).toUtf8();
auto p = code.data();
auto len = code.length();
@ -140,21 +143,25 @@ void AsCompletion::complete(const QDocumentCursor &c, const QString &trigger) {
} else if (eb.type == asTC_IDENTIFIER) {
if (r != tokens.rend()) {
auto pr = std::next(r);
if (pr->content == *SEMI_COLON_TRIGGER) {
if (pr != tokens.rend()) {
auto prr = std::next(pr);
auto ns = prr->content;
if (pr != tokens.rend()) {
if (pr->content == *SEMI_COLON_TRIGGER) {
if (pr != tokens.rend()) {
auto prr = std::next(pr);
auto ns = prr->content;
if (prr->type == asTC_IDENTIFIER) {
for (auto &n : _headerNodes) {
auto name = n->qualifiedName();
if (name == ns) {
nodes << n;
break;
if (prr->type == asTC_IDENTIFIER) {
for (auto &n : _headerNodes) {
auto name = n->qualifiedName();
if (name == ns) {
nodes << n;
break;
}
}
} else {
return;
}
} else {
return;
applyEmptyNsNode(nodes);
}
} else {
applyEmptyNsNode(nodes);
@ -186,20 +193,22 @@ void AsCompletion::complete(const QDocumentCursor &c, const QString &trigger) {
} else if (trigger == *LEFT_PARE_TRIGGER) {
if (r != tokens.rend()) {
auto pr = std::next(r);
if (pr->content == *SEMI_COLON_TRIGGER) {
if (pr != tokens.rend()) {
auto prr = std::next(pr);
auto ns = prr->content;
if (prr->type == asTC_IDENTIFIER) {
for (auto &n : _headerNodes) {
auto name = n->qualifiedName();
if (name == ns) {
nodes << n;
break;
if (pr != tokens.rend()) {
if (pr->content == *SEMI_COLON_TRIGGER) {
if (pr != tokens.rend()) {
auto prr = std::next(pr);
auto ns = prr->content;
if (prr->type == asTC_IDENTIFIER) {
for (auto &n : _headerNodes) {
auto name = n->qualifiedName();
if (name == ns) {
nodes << n;
break;
}
}
} else {
return;
}
} else {
return;
}
}
}
@ -284,6 +293,10 @@ void AsCompletion::applyEmptyNsNode(QList<QCodeNode *> &nodes) {
nodes = _emptyNsNodes;
}
QCodeCompletionWidget *AsCompletion::codeCompletionWidget() const {
return pPopup;
}
void AsCompletion::setEditor(QEditor *e) {
QCodeCompletionEngine::setEditor(e);
pPopup->setEditor(e);

View File

@ -33,10 +33,13 @@ public:
virtual QCodeCompletionEngine *clone() override;
virtual QString language() const override;
virtual QStringList extensions() const override;
virtual void setEditor(QEditor *e) override;
QCodeCompletionWidget *codeCompletionWidget() const;
protected:
virtual void complete(const QDocumentCursor &c,
const QString &trigger) override;

View File

@ -0,0 +1,171 @@
#include "clangformatmanager.h"
#include "settings/settings.h"
#include <QDir>
#include <QProcess>
#include <QProcessEnvironment>
Q_GLOBAL_STATIC_WITH_ARGS(QString, CLANG_ENABLE_FMT, ("clang.enabled"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CLANG_AUTO_FMT, ("clang.auto"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, CLANG_STYLE, ("clang.style"))
ClangFormatManager::ClangFormatManager() {
// load config
HANDLE_CONFIG;
READ_CONFIG_BOOL(m_enabled, CLANG_ENABLE_FMT, true);
READ_CONFIG_BOOL(m_autoFmt, CLANG_AUTO_FMT, true);
auto styles = supportedStyles();
READ_CONFIG_STRING(m_clangStyle, CLANG_STYLE, styles.first());
// ok find
refind();
}
ClangFormatManager &ClangFormatManager::instance() {
static ClangFormatManager ins;
return ins;
}
bool ClangFormatManager::exists() { return !m_clangPath.isEmpty(); }
bool ClangFormatManager::refind() {
m_clangPath.clear();
// Get the PATH environment variable
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
QString pathEnv = env.value("PATH");
// Split the PATH variable into individual directories
QStringList paths = pathEnv.split(QDir::listSeparator());
auto name = getProgramName();
for (auto &path : paths) {
QDir dir(path);
auto pp = dir.absoluteFilePath(name);
QFileInfo fileInfo(pp);
// Check if the file exists and is executable
if (fileInfo.exists() && fileInfo.isExecutable()) {
m_clangPath = pp;
bool ok;
auto ret = runClangFormat({"--version"}, QString(), ok);
if (ok) {
auto vstr = QStringLiteral("clang-format version ");
if (ret.startsWith(vstr)) {
m_clangVersion = ret.mid(vstr.length()).simplified();
return true;
} else {
m_clangPath.clear();
}
}
}
}
return false;
}
QString ClangFormatManager::getProgramName() {
#ifdef Q_OS_WIN
return QStringLiteral("clang-format.exe");
#else
return QStringLiteral("clang-format");
#endif
}
QStringList ClangFormatManager::supportedStyles() {
static QStringList styles{"LLVM", "GNU", "Google", "Chromium",
"Microsoft", "Mozilla", "WebKit", "Custom"};
return styles;
}
QString ClangFormatManager::formatCode(const QString &codes, bool &ok) {
auto styles = supportedStyles();
auto fmtind = styles.indexOf(m_clangStyle);
Q_ASSERT(fmtind >= 0);
if (fmtind != styles.size() - 1) {
auto style =
QStringLiteral("--style={BasedOnStyle: %1, IndentWidth: %2}")
.arg(m_clangStyle)
.arg(m_identWidth);
auto ret = runClangFormat(
{style, QStringLiteral("--assume-filename=wing.cpp")}, codes, ok);
return ret;
} else {
return runClangFormat({}, codes, ok);
}
}
QString ClangFormatManager::runClangFormat(const QStringList &params,
const QString &stdinput, bool &ok) {
if (!exists()) {
ok = false;
return {};
}
QProcess process;
process.setProgram(m_clangPath);
process.setArguments(params);
process.start();
if (!process.waitForStarted()) {
process.kill(); // Kill the process if it timed out
process.waitForFinished(); // Ensure process has terminated
ok = false;
return {};
}
process.write(stdinput.toUtf8());
process.closeWriteChannel();
bool finished = process.waitForFinished(-1);
if (finished) {
auto data = process.readAllStandardOutput();
auto error = process.readAllStandardError();
ok = error.isEmpty();
if (ok) {
return QString::fromUtf8(data);
} else {
return {};
}
} else {
process.kill(); // Kill the process if it timed out
process.waitForFinished(); // Ensure process has terminated
ok = false;
return {};
}
}
quint32 ClangFormatManager::identWidth() const { return m_identWidth; }
void ClangFormatManager::setIdentWidth(quint32 newIdentWidth) {
m_identWidth = newIdentWidth;
}
QString ClangFormatManager::clangStyle() const { return m_clangStyle; }
void ClangFormatManager::setClangStyle(const QString &newClangStyle) {
m_clangStyle = newClangStyle;
}
bool ClangFormatManager::enabled() const { return m_enabled; }
void ClangFormatManager::setEnabled(bool newEnabled) { m_enabled = newEnabled; }
QString ClangFormatManager::path() const { return m_clangPath; }
QString ClangFormatManager::customStyleString() const {
return m_customStyleString;
}
void ClangFormatManager::setCustomStyleString(
const QString &newCustomStyleString) {
m_customStyleString = newCustomStyleString;
}
QString ClangFormatManager::version() const { return m_clangVersion; }
int ClangFormatManager::runningTimeout() const { return m_timeout; }
void ClangFormatManager::setRunningTimeout(int msecs) { m_timeout = msecs; }

View File

@ -0,0 +1,63 @@
#ifndef CLANGFORMATMANAGER_H
#define CLANGFORMATMANAGER_H
#include <QString>
class ClangFormatManager {
public:
static ClangFormatManager &instance();
public:
bool exists();
bool refind();
static QString getProgramName();
static QStringList supportedStyles();
QString formatCode(const QString &codes, bool &ok);
int runningTimeout() const;
void setRunningTimeout(int msecs);
QString version() const;
QString customStyleString() const;
void setCustomStyleString(const QString &newCustomStyleString);
QString path() const;
bool enabled() const;
void setEnabled(bool newEnabled);
QString clangStyle() const;
void setClangStyle(const QString &newClangStyle);
quint32 identWidth() const;
void setIdentWidth(quint32 newIdentWidth);
private:
explicit ClangFormatManager();
QString runClangFormat(const QStringList &params, const QString &stdinput,
bool &ok);
private:
bool m_enabled = true;
bool m_autoFmt = true;
quint32 m_identWidth = 4;
QString m_clangPath;
QString m_clangVersion;
QString m_clangStyle;
QString m_customStyleString;
int m_timeout = 5000;
};
#endif // CLANGFORMATMANAGER_H

View File

@ -4,6 +4,7 @@
#include "class/skinmanager.h"
#include "qdocument.h"
#include "qeditor.h"
#include "qformat.h"
#include "qformatscheme.h"
#include "qsnippetmanager.h"
@ -25,11 +26,22 @@ void LangService::init(asIScriptEngine *engine) {
new QFormatScheme(QStringLiteral(":/qcodeedit/as_light.qxf"), this);
break;
}
// additional formats
QFormat fmt;
fmt.foreground = Qt::red;
format->setFormat(QStringLiteral("stderr"), fmt);
fmt.foreground = QColorConstants::Svg::gold;
format->setFormat(QStringLiteral("stdwarn"), fmt);
fmt.foreground = Qt::cyan;
format->setFormat(QStringLiteral("stdout"), fmt);
QDocument::setDefaultFormatScheme(format);
m_language = new QLanguageFactory(format, this);
m_language->addDefinitionPath(QStringLiteral(":/qcodeedit"));
m_language->addCompletionEngine(new AsCompletion(engine, this));
_completion = new AsCompletion(engine, this);
m_language->addCompletionEngine(_completion);
m_snippetManager = new QSnippetManager(this);
m_snipbind = new QSnippetBinding(m_snippetManager);

View File

@ -1,6 +1,7 @@
#ifndef LANGSERVICE_H
#define LANGSERVICE_H
#include "class/ascompletion.h"
#include "qlanguagefactory.h"
#include "qsnippetbinding.h"
@ -33,6 +34,8 @@ private:
QLanguageFactory *m_language = nullptr;
QSnippetManager *m_snippetManager = nullptr;
AsCompletion *_completion = nullptr;
Q_DISABLE_COPY_MOVE(LangService)
};

View File

@ -19,68 +19,17 @@
#include "class/logger.h"
#include "class/skinmanager.h"
#include "settings/settings.h"
#include "utilities.h"
#include <QFileInfo>
#include <QMetaEnum>
#include <QSettings>
QString getRealContent(const QString &value) { return value; }
template <typename T>
QString getRealContent(T &value) {
static_assert(std::is_same<QString &, decltype(*value)>());
return *value;
}
#define HANDLE_CONFIG \
QSettings set(QStringLiteral(APP_ORG), QStringLiteral(APP_NAME))
#define CONFIG set
#define WRITE_CONFIG(config, dvalue) \
#define WRITE_CONFIG_SET(config, dvalue) \
if (this->_setUnsaved.testFlag(SETTING_ITEM::config)) { \
set.setValue(getRealContent(config), dvalue); \
WRITE_CONFIG(config, dvalue); \
_setUnsaved.setFlag(SettingManager::SETTING_ITEM::config, false); \
}
#define READ_CONFIG(config, dvalue) set.value(getRealContent(config), dvalue)
#define READ_CONFIG_SAFE(var, config, dvalue, func) \
{ \
auto b = false; \
var = READ_CONFIG(config, dvalue).func(&b); \
if (!b) { \
var = dvalue; \
} \
}
#define READ_CONFIG_INT(var, config, dvalue) \
READ_CONFIG_SAFE(var, config, dvalue, toInt)
#define READ_CONFIG_BOOL(var, config, dvalue) \
var = READ_CONFIG(config, dvalue).toBool()
#define READ_CONFIG_QSIZETYPE(var, config, dvalue) \
READ_CONFIG_SAFE(var, config, dvalue, toLongLong)
#define READ_CONFIG_INT_POSITIVE(var, config, dvalue) \
{ \
Q_ASSERT(dvalue > 0); \
READ_CONFIG_SAFE(var, config, dvalue, toInt); \
if (var <= 0) { \
var = dvalue; \
} \
}
#define READ_CONFIG_DOUBLE_POSITIVE(var, config, dvalue) \
{ \
Q_ASSERT(dvalue > 0); \
READ_CONFIG_SAFE(var, config, dvalue, toDouble); \
if (var <= 0) { \
var = dvalue; \
} \
}
Q_GLOBAL_STATIC_WITH_ARGS(QString, DOCK_LAYOUT, ("dock.layout"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, SCRIPT_DOCK_LAYOUT, ("script.layout"))
Q_GLOBAL_STATIC_WITH_ARGS(QString, APP_LASTUSED_PATH, ("app.lastusedpath"))
@ -144,8 +93,8 @@ void SettingManager::load() {
m_dockLayout = READ_CONFIG(DOCK_LAYOUT, QByteArray()).toByteArray();
m_scriptDockLayout =
READ_CONFIG(SCRIPT_DOCK_LAYOUT, QByteArray()).toByteArray();
m_appFontFamily =
READ_CONFIG(APP_FONTFAMILY, _defaultFont.family()).toString();
READ_CONFIG_STRING(m_appFontFamily, APP_FONTFAMILY, _defaultFont.family());
// check font
QFont fm(m_appFontFamily);
if (!QFontInfo(fm).exactMatch()) {
@ -373,79 +322,79 @@ void SettingManager::setDefaultWinState(Qt::WindowState newDefaultWinState) {
void SettingManager::save(SETTINGS cat) {
HANDLE_CONFIG;
WRITE_CONFIG(DOCK_LAYOUT, m_dockLayout);
WRITE_CONFIG(SCRIPT_DOCK_LAYOUT, m_scriptDockLayout);
WRITE_CONFIG(EDITOR_RECENTFILES, getVarList(m_recentHexFiles));
WRITE_CONFIG(SCRIPT_RECENTFILES, getVarList(m_recentScriptFiles));
WRITE_CONFIG(APP_LASTUSED_PATH, m_lastUsedPath);
WRITE_CONFIG_SET(DOCK_LAYOUT, m_dockLayout);
WRITE_CONFIG_SET(SCRIPT_DOCK_LAYOUT, m_scriptDockLayout);
WRITE_CONFIG_SET(EDITOR_RECENTFILES, getVarList(m_recentHexFiles));
WRITE_CONFIG_SET(SCRIPT_RECENTFILES, getVarList(m_recentScriptFiles));
WRITE_CONFIG_SET(APP_LASTUSED_PATH, m_lastUsedPath);
if (cat.testFlag(SETTING::APP)) {
WRITE_CONFIG(SKIN_THEME, m_themeID);
WRITE_CONFIG(APP_LANGUAGE, m_defaultLang);
WRITE_CONFIG(APP_FONTFAMILY, m_appFontFamily);
WRITE_CONFIG(APP_FONTSIZE, m_appfontSize);
WRITE_CONFIG(APP_WINDOWSIZE, m_defaultWinState);
WRITE_CONFIG_SET(SKIN_THEME, m_themeID);
WRITE_CONFIG_SET(APP_LANGUAGE, m_defaultLang);
WRITE_CONFIG_SET(APP_FONTFAMILY, m_appFontFamily);
WRITE_CONFIG_SET(APP_FONTSIZE, m_appfontSize);
WRITE_CONFIG_SET(APP_WINDOWSIZE, m_defaultWinState);
}
if (cat.testFlag(SETTING::PLUGIN)) {
WRITE_CONFIG(PLUGIN_ENABLE, m_enablePlugin);
WRITE_CONFIG(PLUGIN_ENABLE_ROOT, m_enablePlgInRoot);
WRITE_CONFIG_SET(PLUGIN_ENABLE, m_enablePlugin);
WRITE_CONFIG_SET(PLUGIN_ENABLE_ROOT, m_enablePlgInRoot);
}
if (cat.testFlag(SETTING::EDITOR)) {
WRITE_CONFIG(EDITOR_FONTSIZE, m_editorfontSize);
WRITE_CONFIG(EDITOR_SHOW_ADDR, m_editorShowHeader);
WRITE_CONFIG(EDITOR_SHOW_COL, m_editorShowcol);
WRITE_CONFIG(EDITOR_SHOW_TEXT, m_editorShowtext);
WRITE_CONFIG(EDITOR_ENCODING, m_editorEncoding);
WRITE_CONFIG(EDITOR_COPY_LIMIT, m_copylimit);
WRITE_CONFIG(EDITOR_DECSTRLIMIT, m_decodeStrlimit);
WRITE_CONFIG_SET(EDITOR_FONTSIZE, m_editorfontSize);
WRITE_CONFIG_SET(EDITOR_SHOW_ADDR, m_editorShowHeader);
WRITE_CONFIG_SET(EDITOR_SHOW_COL, m_editorShowcol);
WRITE_CONFIG_SET(EDITOR_SHOW_TEXT, m_editorShowtext);
WRITE_CONFIG_SET(EDITOR_ENCODING, m_editorEncoding);
WRITE_CONFIG_SET(EDITOR_COPY_LIMIT, m_copylimit);
WRITE_CONFIG_SET(EDITOR_DECSTRLIMIT, m_decodeStrlimit);
}
if (cat.testFlag(SETTING::SCRIPT)) {
WRITE_CONFIG(SCRIPT_ALLOW_USRSCRIPT_INROOT, m_allowUsrScriptInRoot);
WRITE_CONFIG(SCRIPT_USRHIDECATS, m_usrHideCats);
WRITE_CONFIG(SCRIPT_SYSHIDECATS, m_sysHideCats);
WRITE_CONFIG_SET(SCRIPT_ALLOW_USRSCRIPT_INROOT, m_allowUsrScriptInRoot);
WRITE_CONFIG_SET(SCRIPT_USRHIDECATS, m_usrHideCats);
WRITE_CONFIG_SET(SCRIPT_SYSHIDECATS, m_sysHideCats);
}
if (cat.testFlag(SETTING::OTHER)) {
WRITE_CONFIG(OTHER_USESYS_FILEDIALOG, m_useNativeFileDialog);
WRITE_CONFIG_SET(OTHER_USESYS_FILEDIALOG, m_useNativeFileDialog);
#ifdef WINGHEX_USE_FRAMELESS
WRITE_CONFIG(OTHER_USE_NATIVE_TITLEBAR, m_useNativeTitleBar);
WRITE_CONFIG_SET(OTHER_USE_NATIVE_TITLEBAR, m_useNativeTitleBar);
#endif
WRITE_CONFIG(OTHER_LOG_LEVEL, m_logLevel);
WRITE_CONFIG_SET(OTHER_LOG_LEVEL, m_logLevel);
}
}
void SettingManager::reset(SETTINGS cat) {
HANDLE_CONFIG;
if (cat.testFlag(SETTING::APP)) {
WRITE_CONFIG(SKIN_THEME, 0);
WRITE_CONFIG(APP_LANGUAGE, QString());
WRITE_CONFIG(APP_FONTFAMILY, _defaultFont.family());
WRITE_CONFIG(APP_FONTSIZE, _defaultFont.pointSize());
WRITE_CONFIG(APP_WINDOWSIZE, Qt::WindowMaximized);
WRITE_CONFIG_SET(SKIN_THEME, 0);
WRITE_CONFIG_SET(APP_LANGUAGE, QString());
WRITE_CONFIG_SET(APP_FONTFAMILY, _defaultFont.family());
WRITE_CONFIG_SET(APP_FONTSIZE, _defaultFont.pointSize());
WRITE_CONFIG_SET(APP_WINDOWSIZE, Qt::WindowMaximized);
}
if (cat.testFlag(SETTING::PLUGIN)) {
WRITE_CONFIG(PLUGIN_ENABLE, true);
WRITE_CONFIG(PLUGIN_ENABLE_ROOT, false);
WRITE_CONFIG_SET(PLUGIN_ENABLE, true);
WRITE_CONFIG_SET(PLUGIN_ENABLE_ROOT, false);
}
if (cat.testFlag(SETTING::EDITOR)) {
WRITE_CONFIG(EDITOR_FONTSIZE, _defaultFont.pointSize());
WRITE_CONFIG(EDITOR_SHOW_ADDR, true);
WRITE_CONFIG(EDITOR_SHOW_COL, true);
WRITE_CONFIG(EDITOR_SHOW_TEXT, true);
WRITE_CONFIG(EDITOR_ENCODING, QStringLiteral("ASCII"));
WRITE_CONFIG(EDITOR_FIND_MAXCOUNT, 100);
WRITE_CONFIG(EDITOR_COPY_LIMIT, 100);
WRITE_CONFIG(EDITOR_DECSTRLIMIT, 10);
WRITE_CONFIG_SET(EDITOR_FONTSIZE, _defaultFont.pointSize());
WRITE_CONFIG_SET(EDITOR_SHOW_ADDR, true);
WRITE_CONFIG_SET(EDITOR_SHOW_COL, true);
WRITE_CONFIG_SET(EDITOR_SHOW_TEXT, true);
WRITE_CONFIG_SET(EDITOR_ENCODING, QStringLiteral("ASCII"));
WRITE_CONFIG_SET(EDITOR_FIND_MAXCOUNT, 100);
WRITE_CONFIG_SET(EDITOR_COPY_LIMIT, 100);
WRITE_CONFIG_SET(EDITOR_DECSTRLIMIT, 10);
}
if (cat.testFlag(SETTING::SCRIPT)) {
WRITE_CONFIG(SCRIPT_ALLOW_USRSCRIPT_INROOT, false);
WRITE_CONFIG(SCRIPT_USRHIDECATS, QStringList());
WRITE_CONFIG(SCRIPT_SYSHIDECATS, QStringList());
WRITE_CONFIG_SET(SCRIPT_ALLOW_USRSCRIPT_INROOT, false);
WRITE_CONFIG_SET(SCRIPT_USRHIDECATS, QStringList());
WRITE_CONFIG_SET(SCRIPT_SYSHIDECATS, QStringList());
}
if (cat.testFlag(SETTING::OTHER)) {
WRITE_CONFIG(OTHER_USESYS_FILEDIALOG, true);
WRITE_CONFIG_SET(OTHER_USESYS_FILEDIALOG, true);
#ifdef WINGHEX_USE_FRAMELESS
WRITE_CONFIG(OTHER_USE_NATIVE_TITLEBAR, false);
WRITE_CONFIG_SET(OTHER_USE_NATIVE_TITLEBAR, false);
#endif
WRITE_CONFIG(OTHER_LOG_LEVEL, Logger::defaultLevel());
WRITE_CONFIG_SET(OTHER_LOG_LEVEL, Logger::defaultLevel());
}
load();
}

View File

@ -80,7 +80,7 @@ void QCodeCompletionWidget::adjustGeometry() {
QDocumentCursor cursor = e->cursor();
QDocumentLine line = cursor.line();
const QRect lrect = e->lineRect(cursor.lineNumber());
const QFontMetrics fm = QDocument::fontMetrics();
const QFontMetrics fm = e->document()->fontMetrics();
int h = 0, w = 300, ls = fm.lineSpacing(), y = lrect.y(),
x = line.cursorToX(cursor.columnNumber() + offset);
@ -165,6 +165,8 @@ void QCodeCompletionWidget::setTemporaryNodes(const QList<QCodeNode *> &l) {
m_temps = l;
}
bool QCodeCompletionWidget::isCompleting() const { return _completing; }
void QCodeCompletionWidget::clear() { pModel->clear(); }
void QCodeCompletionWidget::popup() {
@ -191,6 +193,8 @@ void QCodeCompletionWidget::popup() {
}
void QCodeCompletionWidget::complete(const QModelIndex &index) {
_completing = true;
QEditor *e = editor();
if (!index.isValid() || !e)
@ -226,6 +230,8 @@ void QCodeCompletionWidget::complete(const QModelIndex &index) {
}
e->setFocus();
_completing = false;
}
void QCodeCompletionWidget::showEvent(QShowEvent *e) {

View File

@ -78,6 +78,8 @@ public:
void setTemporaryNodes(const QList<QCodeNode *> &l);
bool isCompleting() const;
public slots:
void popup();
void clear();
@ -102,6 +104,7 @@ private:
QCodeCompletionModel *pModel;
QPointer<QObject> pEditor;
QList<QCodeNode *> m_temps;
bool _completing = false;
};
#endif // _QCOMPLETION_WIDGET_H_

View File

@ -65,7 +65,11 @@ ScriptEditor::ScriptEditor(QWidget *parent)
true);
}
ScriptEditor::~ScriptEditor() { m_editor->editor()->document(); }
ScriptEditor::~ScriptEditor() {
auto e = m_editor->editor();
e->disconnect();
e->document()->disconnect();
}
QString ScriptEditor::fileName() const {
return m_editor->editor()->fileName();

View File

@ -23,24 +23,6 @@
#include <QShortcut>
ScriptingConsole::ScriptingConsole(QWidget *parent) : QConsoleWidget(parent) {
// m_stdoutFmtTitle = this->currentCharFormat();
m_stdoutFmtWarn = m_stdoutFmtContent =
channelCharFormat(ConsoleChannel::StandardOutput);
m_stdoutFmtContent.setForeground(Qt::green);
m_stdoutFmtWarn.setForeground(QColorConstants::Svg::gold);
setChannelCharFormat(ConsoleChannel::StandardOutput, m_stdoutFmtContent);
_s.setDevice(this->device());
stdWarn(tr("Scripting console for WingHexExplorer"));
_s << Qt::endl;
stdWarn(tr(">>>> Powered by AngelScript <<<<"));
_s << Qt::endl << Qt::endl;
appendCommandPrompt();
setMode(Input);
auto shortCut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_L), this);
connect(shortCut, &QShortcut::activated, this,
&ScriptingConsole::clearConsole);
@ -53,7 +35,7 @@ void ScriptingConsole::stdOut(const QString &str) { writeStdOut(str); }
void ScriptingConsole::stdErr(const QString &str) { writeStdErr(str); }
void ScriptingConsole::stdWarn(const QString &str) {
write(str, m_stdoutFmtWarn);
write(str, QStringLiteral("stdwarn"));
}
void ScriptingConsole::newLine() { _s << Qt::endl; }
@ -91,6 +73,17 @@ void ScriptingConsole::init() {
&ScriptingConsole::consoleCommand);
}
void ScriptingConsole::initOutput() {
_s.setDevice(this->device());
stdWarn(tr("Scripting console for WingHexExplorer"));
_s << Qt::endl;
stdWarn(tr(">>>> Powered by AngelScript <<<<"));
_s << Qt::endl << Qt::endl;
appendCommandPrompt();
setMode(Input);
}
void ScriptingConsole::clearConsole() {
setMode(Output);
clear();
@ -131,7 +124,7 @@ QString ScriptingConsole::getInput() {
if (!_cmdQueue.isEmpty()) {
instr = _cmdQueue.takeFirst();
setMode(Output);
write(instr, QTextCharFormat());
QConsoleWidget::write(instr);
setMode(Input);
break;
}
@ -165,7 +158,7 @@ void ScriptingConsole::appendCommandPrompt(bool storeOnly) {
_lastCommandPrompt = storeOnly;
write(commandPrompt, m_stdoutFmtTitle);
QConsoleWidget::write(commandPrompt);
}
ScriptMachine *ScriptingConsole::machine() const { return _sp; }

View File

@ -45,6 +45,8 @@ public slots:
void init();
void initOutput();
void clearConsole();
void pushInputCmd(const QString &cmd);
@ -64,10 +66,6 @@ private:
QMutex _queueLocker;
bool _waitforRead = false;
QTextCharFormat m_stdoutFmtTitle;
QTextCharFormat m_stdoutFmtContent;
QTextCharFormat m_stdoutFmtWarn;
std::function<QString(void)> _getInputFn;
};

View File

@ -121,7 +121,6 @@ MainWindow::MainWindow(QWidget *parent) : FramelessMainWindow(parent) {
layout->addWidget(m_status);
buildUpContent(cw);
m_scriptDialog = new ScriptingDialog(this);
m_toolBtneditors.value(ToolButtonIndex::EDITOR_VIEWS)->setEnabled(false);
@ -144,13 +143,17 @@ MainWindow::MainWindow(QWidget *parent) : FramelessMainWindow(parent) {
plg.LoadPlugin();
// At this time, AngelScript service plugin has started
m_scriptConsole->init();
m_scriptDialog->initConsole();
ScriptManager::instance().attach(m_scriptConsole);
auto &langins = LangService::instance();
langins.init(m_scriptConsole->machine()->engine());
langins.applyLanguageSerivce(m_scriptConsole);
m_scriptConsole->initOutput();
m_scriptDialog = new ScriptingDialog(this);
m_scriptDialog->initConsole();
// load the model
Q_ASSERT(m_scriptConsole && m_scriptConsole->machine());
m_varshowtable->setModel(m_scriptConsole->consoleMachine()->model());

View File

@ -20,6 +20,7 @@
#include "QWingRibbon/ribbontabcontent.h"
#include "Qt-Advanced-Docking-System/src/DockAreaWidget.h"
#include "aboutsoftwaredialog.h"
#include "class/clangformatmanager.h"
#include "class/langservice.h"
#include "class/languagemanager.h"
#include "class/qkeysequences.h"
@ -27,12 +28,14 @@
#include "class/wingfiledialog.h"
#include "class/wingmessagebox.h"
#include "control/toast.h"
#include "qcodeeditwidget/qdocumentswaptextcommand.h"
#include "qcodeeditwidget/qeditconfig.h"
#include "qcodeeditwidget/qsnippetedit.h"
#include "qdocumentline.h"
#include "qeditor.h"
#include "qformatscheme.h"
#include "qlinemarksinfocenter.h"
#include "settings/clangformatsetdialog.h"
#include <QDesktopServices>
#include <QHeaderView>
@ -375,6 +378,12 @@ RibbonTabContent *ScriptingDialog::buildEditPage(RibbonTabContent *tab) {
shortcuts.keySequence(QKeySequences::Key::GOTO));
}
{
auto pannel = tab->addGroup(tr("Format"));
addPannelAction(pannel, QStringLiteral("codefmt"), tr("CodeFormat"),
&ScriptingDialog::on_codefmt);
}
return tab;
}
@ -508,8 +517,13 @@ RibbonTabContent *ScriptingDialog::buildSettingPage(RibbonTabContent *tab) {
auto pannel = tab->addGroup(tr("Settings"));
addPannelAction(pannel, QStringLiteral("file"), tr("Editor"),
&ScriptingDialog::on_setting);
[=] { m_setdialog->showConfig(QStringLiteral("Edit")); });
addPannelAction(pannel, QStringLiteral("snippt"), tr("Snippets"), [=] {
m_setdialog->showConfig(QStringLiteral("Snippets"));
});
addPannelAction(
pannel, QStringLiteral("codeformat"), tr("ClangFormat"),
[=] { m_setdialog->showConfig(QStringLiteral("ClangFormat")); });
return tab;
}
@ -572,7 +586,6 @@ ScriptingDialog::buildUpOutputShowDock(ads::CDockManager *dock,
ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw) {
m_consoleout = new ScriptingConsole(this);
m_consoleout->clear();
m_consoleout->setMode(ScriptingConsole::Output);
auto dw = buildDockWidget(dock, QStringLiteral("ConsoleOutput"),
tr("ConsoleOutput"), m_consoleout);
@ -954,6 +967,9 @@ void ScriptingDialog::buildUpSettingDialog() {
new QSnippetEdit(LangService::instance().snippetManager(), m_setdialog);
m_setdialog->addPage(snip);
auto clang = new ClangFormatSetDialog(m_setdialog);
m_setdialog->addPage(clang);
m_setdialog->build();
}
@ -1239,7 +1255,23 @@ void ScriptingDialog::on_gotoline() {
}
}
void ScriptingDialog::on_setting() { m_setdialog->showConfig(); }
void ScriptingDialog::on_codefmt() {
auto e = currentEditor();
if (e) {
auto editor = e->editor();
auto codes = editor->text();
bool ok;
auto fmtcodes = ClangFormatManager::instance().formatCode(codes, ok);
if (ok) {
auto doc = editor->document();
doc->execute(new QDocumentSwapTextCommand(fmtcodes, doc));
} else {
Toast::toast(this, NAMEICONRES(QStringLiteral("codefmt")),
tr("FormatCodeFailed"));
}
}
}
void ScriptingDialog::on_about() { AboutSoftwareDialog().exec(); }

View File

@ -227,7 +227,8 @@ private slots:
void on_replace();
void on_gotoline();
void on_setting();
void on_codefmt();
void on_about();
void on_sponsor();
void on_wiki();

View File

@ -86,6 +86,8 @@ void SettingDialog::showConfig(const QString &id) {
ui->listWidget->setCurrentRow(0);
}
ui->listWidget->setCurrentRow(m_pages.indexOf(*r));
Utilities::moveToCenter(this);
_dialog->exec();
}
void SettingDialog::toastTakeEffectReboot() {

View File

@ -0,0 +1,42 @@
/*==============================================================================
** 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/>.
** =============================================================================
*/
#include "qdocumentswaptextcommand.h"
#include "qdocument_p.h"
QDocumentSwapTextCommand::QDocumentSwapTextCommand(const QString &text,
QDocument *doc,
QDocumentCommand *p)
: QDocumentCommand(Command::Custom, doc, p), oldtext(m_doc->text()),
newtext(text) {}
void QDocumentSwapTextCommand::undo() {
m_doc->setText(oldtext);
for (int i = 0; i < m_doc->lineCount(); ++i) {
auto line = m_doc->line(i);
markUndone(line.handle());
}
}
void QDocumentSwapTextCommand::redo() {
m_doc->setText(newtext);
for (int i = 0; i < m_doc->lineCount(); ++i) {
auto line = m_doc->line(i);
markRedone(line.handle(), m_first);
}
}

View File

@ -0,0 +1,38 @@
/*==============================================================================
** 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/>.
** =============================================================================
*/
#ifndef QDOCUMENTSWAPTEXTCOMMAND_H
#define QDOCUMENTSWAPTEXTCOMMAND_H
#include "qdocumentcommand.h"
class QDocumentSwapTextCommand : public QDocumentCommand {
public:
explicit QDocumentSwapTextCommand(const QString &text, QDocument *doc,
QDocumentCommand *p = nullptr);
// QUndoCommand interface
public:
void undo();
void redo();
private:
QString oldtext;
QString newtext;
};
#endif // QDOCUMENTSWAPTEXTCOMMAND_H

View File

@ -22,6 +22,7 @@
\see QEditConfig
*/
#include "class/langservice.h"
#include "qdocument.h"
#include "qdocument_p.h"
#include "qeditor.h"
@ -42,6 +43,20 @@
QEditConfig::QEditConfig(QWidget *w)
: WingHex::SettingPage(w), ui(new Ui::QEditConfig()) {
ui->setupUi(this);
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 QEditor(QString::fromUtf8(cbuffer), this);
LangService::instance().applyLanguageSerivce(_edit);
_edit->setFlag(QEditor::ReadOnly, true);
_edit->setUndoRedoEnabled(false);
ui->layoutFont->addWidget(_edit, ui->layoutFont->rowCount(), 0, 1,
ui->layoutFont->columnCount());
reload();
}
@ -54,46 +69,51 @@ void QEditConfig::apply() {
QFont font = ui->cbFont->currentFont();
font.setPointSize(ui->spnFontSize->value());
QDocument::setFont(font);
QDocument::setTabStop(ui->spnTabWidth->value());
auto &doc_ps = QDocumentPrivate::m_documents;
for (auto &pdoc : doc_ps) {
auto doc = pdoc->m_doc;
doc->setFont(font);
doc->setTabStop(ui->spnTabWidth->value());
if (ui->chkDetectLE->isChecked())
QDocument::setDefaultLineEnding(QDocument::Conservative);
else
QDocument::setDefaultLineEnding(
QDocument::LineEnding(ui->cbLineEndings->currentIndex() + 1));
if (ui->chkDetectLE->isChecked()) {
doc->setLineEnding(QDocument::Conservative);
} else {
doc->setLineEnding(
QDocument::LineEnding(ui->cbLineEndings->currentIndex() + 1));
}
QDocument::WhiteSpaceMode ws = QDocument::ShowNone;
QDocument::WhiteSpaceMode ws = QDocument::ShowNone;
if (ui->chkShowLeadingWhitespace->isChecked())
ws |= QDocument::ShowLeading;
if (ui->chkShowLeadingWhitespace->isChecked())
ws |= QDocument::ShowLeading;
if (ui->chkShowTrailingWhitespace->isChecked())
ws |= QDocument::ShowTrailing;
if (ui->chkShowTrailingWhitespace->isChecked())
ws |= QDocument::ShowTrailing;
if (ui->chkShowTabsInText->isChecked())
ws |= QDocument::ShowTabs;
if (ui->chkShowTabsInText->isChecked())
ws |= QDocument::ShowTabs;
QDocument::setShowSpaces(ws);
doc->setShowSpaces(ws);
int flags = QEditor::defaultFlags();
int flags = QEditor::defaultFlags();
if (ui->chkReplaceTabs->isChecked())
flags |= QEditor::ReplaceTabs;
else
flags &= ~QEditor::ReplaceTabs;
if (ui->chkReplaceTabs->isChecked())
flags |= QEditor::ReplaceTabs;
else
flags &= ~QEditor::ReplaceTabs;
if (ui->chkAutoRemoveTrailingWhitespace->isChecked())
flags |= QEditor::RemoveTrailing;
else
flags &= ~QEditor::RemoveTrailing;
if (ui->chkAutoRemoveTrailingWhitespace->isChecked())
flags |= QEditor::RemoveTrailing;
else
flags &= ~QEditor::RemoveTrailing;
if (ui->chkPreserveTrailingIndent->isChecked())
flags |= QEditor::PreserveTrailingIndent;
else
flags &= ~QEditor::PreserveTrailingIndent;
if (ui->chkPreserveTrailingIndent->isChecked())
flags |= QEditor::PreserveTrailingIndent;
else
flags &= ~QEditor::PreserveTrailingIndent;
QEditor::setDefaultFlags(flags);
QEditor::setDefaultFlags(flags);
}
}
/*!
@ -135,26 +155,26 @@ void QEditConfig::reset() {
void QEditConfig::reload() {
// reload the current config
ui->cbFont->setFont(QDocument::font());
ui->spnFontSize->setValue(QDocument::font().pointSize());
// ui->cbFont->setFont(QDocument::font());
// ui->spnFontSize->setValue(QDocument::font().pointSize());
ui->spnTabWidth->setValue(QDocument::tabStop());
// ui->spnTabWidth->setValue(QDocument::tabStop());
QDocument::WhiteSpaceMode ws = QDocument::showSpaces();
ui->chkShowTabsInText->setChecked(ws & QDocument::ShowTabs);
ui->chkShowLeadingWhitespace->setChecked(ws & QDocument::ShowLeading);
ui->chkShowTrailingWhitespace->setChecked(ws & QDocument::ShowTrailing);
// QDocument::WhiteSpaceMode ws = QDocument::showSpaces();
// ui->chkShowTabsInText->setChecked(ws & QDocument::ShowTabs);
// ui->chkShowLeadingWhitespace->setChecked(ws & QDocument::ShowLeading);
// ui->chkShowTrailingWhitespace->setChecked(ws & QDocument::ShowTrailing);
QDocument::LineEnding le = QDocument::defaultLineEnding();
ui->chkDetectLE->setChecked(le == QDocument::Conservative);
ui->cbLineEndings->setCurrentIndex(le ? le - 1 : 0);
// QDocument::LineEnding le = QDocument::defaultLineEnding();
// ui->chkDetectLE->setChecked(le == QDocument::Conservative);
// ui->cbLineEndings->setCurrentIndex(le ? le - 1 : 0);
int flags = QEditor::defaultFlags();
ui->chkReplaceTabs->setChecked(flags & QEditor::ReplaceTabs);
ui->chkAutoRemoveTrailingWhitespace->setChecked(flags &
QEditor::RemoveTrailing);
ui->chkPreserveTrailingIndent->setChecked(flags &
QEditor::PreserveTrailingIndent);
// int flags = QEditor::defaultFlags();
// ui->chkReplaceTabs->setChecked(flags & QEditor::ReplaceTabs);
// ui->chkAutoRemoveTrailingWhitespace->setChecked(flags &
// QEditor::RemoveTrailing);
// ui->chkPreserveTrailingIndent->setChecked(flags &
// QEditor::PreserveTrailingIndent);
}
/*!
@ -213,9 +233,7 @@ void QEditConfig::loadKeys(const QMap<QString, QVariant> &keys) {
ui->cbFont->setCurrentFont(f);
ui->spnFontSize->setValue(f.pointSize());
QDocument::setFont(f);
ui->lblSampleText->setFont(f);
// QDocument::setFont(f);
} else if (it.key() == "tab_width") {
ui->spnTabWidth->setValue(it->toInt());
@ -266,10 +284,7 @@ void QEditConfig::loadKeys(const QMap<QString, QVariant> &keys) {
void QEditConfig::on_spnFontSize_valueChanged(int size) {
QFont font = ui->cbFont->currentFont();
font.setPointSize(size);
ui->lblSampleText->setFont(font);
QDocument::setFont(font);
_edit->setFont(font);
}
/*!
@ -277,67 +292,80 @@ void QEditConfig::on_spnFontSize_valueChanged(int size) {
*/
void QEditConfig::on_cbFont_currentFontChanged(QFont font) {
font.setPointSize(ui->spnFontSize->value());
ui->lblSampleText->setFont(font);
QDocument::setFont(font);
_edit->setFont(font);
}
/*!
\brief Slot used to apply tab width settings
*/
void QEditConfig::on_spnTabWidth_valueChanged(int n) {
QDocument::setTabStop(n);
_edit->document()->setTabStop(n);
}
/*!
\brief Slot used to apply tabs replacement settings
*/
void QEditConfig::on_chkReplaceTabs_toggled(bool y) {
// FIXME
foreach (QEditor *e, QEditor::m_editors) {
e->setFlag(QEditor::ReplaceTabs, y);
}
_edit->setFlag(QEditor::ReplaceTabs, y);
}
/*!
\brief Slot used to apply tabs display settings
*/
void QEditConfig::on_chkShowTabsInText_toggled(bool y) {
if (y)
QDocument::setShowSpaces(QDocument::showSpaces() | QDocument::ShowTabs);
else
QDocument::setShowSpaces(QDocument::showSpaces() &
~QDocument::ShowTabs);
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) {
if (y)
QDocument::setShowSpaces(QDocument::showSpaces() |
QDocument::ShowLeading);
else
QDocument::setShowSpaces(QDocument::showSpaces() &
~QDocument::ShowLeading);
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) {
if (y)
QDocument::setShowSpaces(QDocument::showSpaces() |
QDocument::ShowTrailing);
else
QDocument::setShowSpaces(QDocument::showSpaces() &
~QDocument::ShowTrailing);
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);
QDocument::setDefaultLineEnding(le);
_edit->document()->setLineEnding(le);
}
/*!
@ -350,27 +378,21 @@ void QEditConfig::on_chkDetectLE_toggled(bool y) {
le = QDocument::LineEnding(ui->cbLineEndings->currentIndex() + 1);
}
QDocument::setDefaultLineEnding(le);
_edit->document()->setLineEnding(le);
}
/*!
\brief Slot used to apply trailing space removal settings
*/
void QEditConfig::on_chkAutoRemoveTrailingWhitespace_toggled(bool y) {
// FIXME
foreach (QEditor *e, QEditor::m_editors) {
e->setFlag(QEditor::RemoveTrailing, y);
}
_edit->setFlag(QEditor::RemoveTrailing, y);
}
/*!
\brief Slot used to indent preservation settings
*/
void QEditConfig::on_chkPreserveTrailingIndent_toggled(bool y) {
// FIXME
foreach (QEditor *e, QEditor::m_editors) {
e->setFlag(QEditor::PreserveTrailingIndent, y);
}
_edit->setFlag(QEditor::PreserveTrailingIndent, y);
}
/*! @} */

View File

@ -2,6 +2,7 @@
#define QEDITCONFIG_H
#include "plugin/settingpage.h"
#include "qeditor.h"
#include <QWidget>
namespace Ui {
@ -50,6 +51,8 @@ private slots:
private:
Ui::QEditConfig *ui;
QEditor *_edit;
};
#endif // QEDITCONFIG_H

View File

@ -22,11 +22,8 @@
<property name="title">
<string>Font</string>
</property>
<layout class="QGridLayout">
<property name="margin" stdset="0">
<number>4</number>
</property>
<item row="0" column="0">
<layout class="QGridLayout" name="layoutFont">
<item row="1" column="0">
<widget class="QFontComboBox" name="cbFont">
<property name="font">
<font>
@ -40,10 +37,10 @@
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1" colspan="2">
<widget class="QSpinBox" name="spnFontSize">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::UpDownArrows</enum>
<enum>QAbstractSpinBox::ButtonSymbols::UpDownArrows</enum>
</property>
<property name="minimum">
<number>6</number>
@ -56,49 +53,22 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QLabel" name="lblSampleText">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="2" column="0" colspan="3">
<widget class="QLabel" name="label">
<property name="font">
<font>
<family>Monospace</family>
<bold>true</bold>
<underline>true</underline>
</font>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string>text which &lt;i&gt;should&lt;/i&gt; be a &lt;b&gt;fair&lt;/b&gt; test of the font</string>
<string>Takes Effect on Terminal as well</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="margin">
<number>0</number>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
@ -145,7 +115,7 @@
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -263,10 +233,10 @@
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
<enum>QSizePolicy::Policy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>

View File

@ -23,6 +23,7 @@
#include "qsnippet.h"
#include "qsnippetmanager.h"
#include "utilities.h"
#include <QMessageBox>
@ -49,7 +50,9 @@ QSnippetEdit::QSnippetEdit(QSnippetManager *mgr, QWidget *p)
QSnippetManager *QSnippetEdit::snippetManager() const { return m_manager; }
QIcon QSnippetEdit::categoryIcon() const { return QIcon(); }
QIcon QSnippetEdit::categoryIcon() const {
return ICONRES(QStringLiteral("snippt"));
}
QString QSnippetEdit::name() const { return tr("Snippets"); }

View File

@ -0,0 +1,50 @@
#include "clangformatsetdialog.h"
#include "class/clangformatmanager.h"
#include "class/winginputdialog.h"
#include "ui_clangformatsetdialog.h"
#include "utilities.h"
ClangFormatSetDialog::ClangFormatSetDialog(QWidget *parent)
: WingHex::SettingPage(parent), ui(new Ui::ClangFormatSetDialog) {
ui->setupUi(this);
auto clang = ClangFormatManager::instance();
ui->cbStyle->addItems(clang.supportedStyles());
ui->leLocation->setText(ClangFormatManager::getProgramName());
if (clang.exists()) {
ui->lblClangPath->setText(clang.path());
ui->lblClangPath->setToolTip(clang.path());
ui->lblClangVersion->setText(clang.version());
} else {
ui->lblClangPath->setStyleSheet(QStringLiteral("color:red"));
}
}
ClangFormatSetDialog::~ClangFormatSetDialog() { delete ui; }
QIcon ClangFormatSetDialog::categoryIcon() const {
return ICONRES(QStringLiteral("codeformat"));
}
QString ClangFormatSetDialog::name() const { return tr("ClangFormat"); }
QString ClangFormatSetDialog::id() const {
return QStringLiteral("ClangFormat");
}
void ClangFormatSetDialog::apply() {}
void ClangFormatSetDialog::reset() {}
void ClangFormatSetDialog::cancel() {}
void ClangFormatSetDialog::on_cbStyle_currentTextChanged(const QString &arg1) {
ui->btnStyleCustom->setEnabled(arg1 == QStringLiteral("Custom"));
}
void ClangFormatSetDialog::on_btnStyleCustom_clicked() {
// TODO
WingInputDialog::getMultiLineText(this, tr("ClangFormat"), "");
}

View File

@ -0,0 +1,37 @@
#ifndef CLANGFORMATSETDIALOG_H
#define CLANGFORMATSETDIALOG_H
#include "plugin/settingpage.h"
namespace Ui {
class ClangFormatSetDialog;
}
class ClangFormatSetDialog : public WingHex::SettingPage {
Q_OBJECT
public:
explicit ClangFormatSetDialog(QWidget *parent = nullptr);
~ClangFormatSetDialog();
private:
Ui::ClangFormatSetDialog *ui;
// PageBase interface
public:
virtual QIcon categoryIcon() const override;
virtual QString name() const override;
virtual QString id() const override;
// SettingPage interface
public:
virtual void apply() override;
virtual void reset() override;
virtual void cancel() override;
private slots:
void on_cbStyle_currentTextChanged(const QString &arg1);
void on_btnStyleCustom_clicked();
};
#endif // CLANGFORMATSETDIALOG_H

View File

@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ClangFormatSetDialog</class>
<widget class="QWidget" name="ClangFormatSetDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>425</width>
<height>323</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>8</number>
</property>
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QCheckBox" name="cbEnabled">
<property name="text">
<string>Enable</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gbInfo">
<property name="title">
<string>Info</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Path</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lblClangPath">
<property name="text">
<string notr="true">-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Version</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="lblClangVersion">
<property name="text">
<string notr="true">-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Configure</string>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="horizontalSpacing">
<number>10</number>
</property>
<property name="verticalSpacing">
<number>10</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Location</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="leLocation"/>
</item>
<item>
<widget class="QPushButton" name="btnBrowse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Style</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cbStyle"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Custom</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="btnStyleCustom">
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>IndentWidth</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="sbIndent">
<property name="minimum">
<number>2</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="value">
<number>4</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbAutoFmt">
<property name="text">
<string>AutoFormatWhenSave</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

64
src/settings/settings.h Normal file
View File

@ -0,0 +1,64 @@
#ifndef SETTINGS_H
#define SETTINGS_H
#include <QSettings>
#include <QString>
inline QString getRealContent(const QString &value) { return value; }
template <typename T>
inline QString getRealContent(T &value) {
static_assert(std::is_same<QString &, decltype(*value)>());
return *value;
}
#define HANDLE_CONFIG \
QSettings set(QStringLiteral(APP_ORG), QStringLiteral(APP_NAME))
#define CONFIG set
#define WRITE_CONFIG(config, dvalue) \
set.setValue(getRealContent(config), dvalue);
#define READ_CONFIG(config, dvalue) set.value(getRealContent(config), dvalue)
#define READ_CONFIG_SAFE(var, config, dvalue, func) \
{ \
auto b = false; \
var = READ_CONFIG(config, dvalue).func(&b); \
if (!b) { \
var = dvalue; \
} \
}
#define READ_CONFIG_INT(var, config, dvalue) \
READ_CONFIG_SAFE(var, config, dvalue, toInt)
#define READ_CONFIG_STRING(var, config, dvalue) \
var = READ_CONFIG(config, dvalue).toString()
#define READ_CONFIG_BOOL(var, config, dvalue) \
var = READ_CONFIG(config, dvalue).toBool()
#define READ_CONFIG_QSIZETYPE(var, config, dvalue) \
READ_CONFIG_SAFE(var, config, dvalue, toLongLong)
#define READ_CONFIG_INT_POSITIVE(var, config, dvalue) \
{ \
Q_ASSERT(dvalue > 0); \
READ_CONFIG_SAFE(var, config, dvalue, toInt); \
if (var <= 0) { \
var = dvalue; \
} \
}
#define READ_CONFIG_DOUBLE_POSITIVE(var, config, dvalue) \
{ \
Q_ASSERT(dvalue > 0); \
READ_CONFIG_SAFE(var, config, dvalue, toDouble); \
if (var <= 0) { \
var = dvalue; \
} \
}
#endif // SETTINGS_H

View File

@ -2980,3 +2980,10 @@ QCallTip
qproperty-foreground: #eff0f1;
qproperty-opacity: 0.8;
}
QConsoleWidget
{
background-color: #1d2023;
color: #eff0f1;
selection-background-color: #3daee9;
}