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

View File

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

View File

@ -1,12 +1,14 @@
#include "QConsoleWidget.h" #include "QConsoleWidget.h"
#include "QConsoleIODevice.h"
#include "class/langservice.h" #include "class/ascompletion.h"
#include "control/qcodecompletionwidget.h"
#include "qdocumentline.h" #include "qdocumentline.h"
#include "qformatscheme.h" #include "qformatscheme.h"
#include "qlanguagefactory.h" #include "qlanguagefactory.h"
#include "utilities.h" #include "utilities.h"
#include "QConsoleIODevice.h"
#include <QApplication> #include <QApplication>
#include <QClipboard> #include <QClipboard>
#include <QDebug> #include <QDebug>
@ -19,18 +21,8 @@
#include <QScrollBar> #include <QScrollBar>
QConsoleWidget::QConsoleWidget(QWidget *parent) QConsoleWidget::QConsoleWidget(QWidget *parent)
: QEditor(false, parent), mode_(Output), completer_(nullptr) { : QEditor(false, parent), mode_(Output) {
iodevice_ = new QConsoleIODevice(this, this); 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); setUndoRedoEnabled(false);
} }
@ -44,7 +36,6 @@ void QConsoleWidget::setMode(ConsoleMode m) {
auto cursor = this->cursor(); auto cursor = this->cursor();
cursor.movePosition(QDocumentCursor::End); cursor.movePosition(QDocumentCursor::End);
setCursor(cursor); setCursor(cursor);
// setCurrentCharFormat(chanFormat_[StandardInput]);
inpos_ = cursor; inpos_ = cursor;
mode_ = Input; mode_ = Input;
} }
@ -88,34 +79,26 @@ void QConsoleWidget::handleReturnKey() {
emit consoleCommand(code); 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) { void QConsoleWidget::keyPressEvent(QKeyEvent *e) {
if (completer_ && completer_->isVisible()) { if (mode() == Input) {
// The following keys are forwarded by the completer to the widget auto ascom = dynamic_cast<AsCompletion *>(completionEngine());
switch (e->key()) { if (ascom) {
case Qt::Key_Tab: auto cw = ascom->codeCompletionWidget();
case Qt::Key_Enter: if (cw && cw->isVisible()) {
case Qt::Key_Return: // The following keys are forwarded by the completer to the
case Qt::Key_Escape: // widget
case Qt::Key_Backtab: switch (e->key()) {
e->ignore(); case Qt::Key_Tab:
return; // let the completer do default behavior case Qt::Key_Enter:
default: case Qt::Key_Return:
break; 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) { void QConsoleWidget::replaceCommandLine(const QString &str) {
// Select the text after the last command prompt ... // Select the text after the last command prompt ...
auto textCursor = this->cursor(); auto textCursor = this->cursor();
auto line = textCursor.line(); auto line = textCursor.line();
@ -321,25 +303,14 @@ QString QConsoleWidget::getHistoryPath() {
return dir.absoluteFilePath(QStringLiteral(".command_history.lst")); return dir.absoluteFilePath(QStringLiteral(".command_history.lst"));
} }
void QConsoleWidget::write(const QString &message, const QTextCharFormat &fmt) { void QConsoleWidget::write(const QString &message, const QString &sfmtID) {
// QTextCharFormat currfmt = currentCharFormat();
auto tc = cursor(); auto tc = cursor();
auto ascom = dynamic_cast<AsCompletion *>(completionEngine());
Q_ASSERT(ascom);
auto cw = ascom->codeCompletionWidget();
if (mode() == Input) { if (mode() == Output || (cw && cw->isCompleting())) {
// in Input mode output messages are inserted // in output mode or completion messages are appended
// 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
auto tc1 = tc; auto tc1 = tc;
tc1.movePosition(QDocumentCursor::End); tc1.movePosition(QDocumentCursor::End);
@ -349,21 +320,32 @@ void QConsoleWidget::write(const QString &message, const QTextCharFormat &fmt) {
// insert text // insert text
setCursor(tc1); setCursor(tc1);
tc.insertText(message /*, fmt*/); tc.insertText(message, false, sfmtID);
ensureCursorVisible(); ensureCursorVisible();
// restore cursor if needed // restore cursor if needed
if (needsRestore) if (needsRestore)
setCursor(tc); 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) { void QConsoleWidget::writeStdOut(const QString &s) {
write(s, chanFormat_[StandardOutput]); write(s, QStringLiteral("stdout"));
} }
void QConsoleWidget::writeStdErr(const QString &s) { void QConsoleWidget::writeStdErr(const QString &s) {
write(s, chanFormat_[StandardError]); write(s, QStringLiteral("stderr"));
} }
/////////////////// QConsoleWidget::History ///////////////////// /////////////////// QConsoleWidget::History /////////////////////
@ -454,12 +436,12 @@ QTextStream &inputMode(QTextStream &s) {
QTextStream &outChannel(QTextStream &s) { QTextStream &outChannel(QTextStream &s) {
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device()); QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
if (d) if (d)
d->setCurrentWriteChannel(QConsoleWidget::StandardOutput); d->setCurrentWriteChannel(STDOUT_FILENO);
return s; return s;
} }
QTextStream &errChannel(QTextStream &s) { QTextStream &errChannel(QTextStream &s) {
QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device()); QConsoleIODevice *d = qobject_cast<QConsoleIODevice *>(s.device());
if (d) if (d)
d->setCurrentWriteChannel(QConsoleWidget::StandardError); d->setCurrentWriteChannel(STDERR_FILENO);
return s; return s;
} }

View File

@ -5,7 +5,6 @@
#include <QTextCharFormat> #include <QTextCharFormat>
#include <QTextStream> #include <QTextStream>
#include "control/qcodecompletionwidget.h"
#include "qeditor.h" #include "qeditor.h"
#include "qlanguagefactory.h" #include "qlanguagefactory.h"
@ -18,31 +17,20 @@ public:
enum ConsoleMode { Input, Output }; enum ConsoleMode { Input, Output };
Q_ENUM(ConsoleMode) Q_ENUM(ConsoleMode)
enum ConsoleChannel {
StandardInput,
StandardOutput,
StandardError,
nConsoleChannels
};
Q_ENUM(ConsoleChannel)
explicit QConsoleWidget(QWidget *parent = nullptr); explicit QConsoleWidget(QWidget *parent = nullptr);
virtual ~QConsoleWidget(); virtual ~QConsoleWidget();
ConsoleMode mode() const { return mode_; } ConsoleMode mode() const { return mode_; }
void setMode(ConsoleMode m); void setMode(ConsoleMode m);
QIODevice *device() const { return (QIODevice *)iodevice_; } 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); } virtual QSize sizeHint() const override { return QSize(600, 400); }
// write a formatted message to the console // 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_; } static const QStringList &history() { return history_.strings_; }
void setCompleter(QCodeCompletionWidget *c);
// get the current command line // get the current command line
QString getCommandLine(); QString getCommandLine();
@ -103,8 +91,6 @@ private:
QDocumentCursor inpos_; QDocumentCursor inpos_;
QString currentMultiLineCode_; QString currentMultiLineCode_;
QConsoleIODevice *iodevice_; QConsoleIODevice *iodevice_;
QTextCharFormat chanFormat_[nConsoleChannels];
QCodeCompletionWidget *completer_;
QLanguageFactory *m_language = nullptr; 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 flushMatches(int groupId);
void addMatch(int groupId, int line, int pos, int len, int format); void addMatch(int groupId, int line, int pos, int len, int format);
static QFont font(); QFont font();
static void setFont(const QFont &f); void setFont(const QFont &f);
static const QFontMetrics &fontMetrics(); const QFontMetrics &fontMetrics();
static LineEnding defaultLineEnding(); int tabStop();
static void setDefaultLineEnding(LineEnding le); void setTabStop(int n);
static int tabStop(); WhiteSpaceMode showSpaces();
static void setTabStop(int n); void setShowSpaces(WhiteSpaceMode y);
static WhiteSpaceMode showSpaces();
static void setShowSpaces(WhiteSpaceMode y);
static QFormatScheme *defaultFormatScheme(); static QFormatScheme *defaultFormatScheme();
static void setDefaultFormatScheme(QFormatScheme *f); static void setDefaultFormatScheme(QFormatScheme *f);

View File

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

View File

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

View File

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

View File

@ -515,9 +515,10 @@ void QDocumentCursor::insertLine(bool keepAnchor) {
\note Nothing happens if \a s is empty \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) if (m_handle)
m_handle->insertText(s, keepAnchor); m_handle->insertText(s, keepAnchor, sfmtID);
} }
/*! /*!

View File

@ -141,7 +141,8 @@ public:
void eraseLine(); void eraseLine();
void insertLine(bool keepAnchor = false); 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 selectionStart() const;
QDocumentCursor selectionEnd() const; QDocumentCursor selectionEnd() const;

View File

@ -92,7 +92,8 @@ public:
void shift(int offset); void shift(int offset);
bool movePosition(int offset, int op, int m); 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 nextChar() const;
QChar previousChar() const; QChar previousChar() const;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -232,7 +232,9 @@ set(CLASS_SRC
src/class/qcodenode.cpp src/class/qcodenode.cpp
src/class/qcodenode.h src/class/qcodenode.h
src/class/langservice.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) if(WINGHEX_USE_FRAMELESS)
set(WIDGET_FRAME_SRC set(WIDGET_FRAME_SRC
@ -268,6 +270,7 @@ set(MODEL_SRC
src/model/dbgbreakpointmodel.cpp) src/model/dbgbreakpointmodel.cpp)
set(SETTING_SRC set(SETTING_SRC
src/settings/settings.h
src/settings/generalsettingdialog.h src/settings/generalsettingdialog.h
src/settings/generalsettingdialog.cpp src/settings/generalsettingdialog.cpp
src/settings/generalsettingdialog.ui src/settings/generalsettingdialog.ui
@ -285,7 +288,10 @@ set(SETTING_SRC
src/settings/scriptbehaviorsettingdialog.ui src/settings/scriptbehaviorsettingdialog.ui
src/settings/othersettingsdialog.h src/settings/othersettingsdialog.h
src/settings/othersettingsdialog.cpp 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 set(SCRIPT_ADDON_SRC
src/scriptaddon/scriptqstring.h src/scriptaddon/scriptqstring.h
@ -312,7 +318,9 @@ set(CODEEDIT_WIDGET
src/qcodeeditwidget/qformatconfig.ui src/qcodeeditwidget/qformatconfig.ui
src/qcodeeditwidget/qsnippetedit.cpp src/qcodeeditwidget/qsnippetedit.cpp
src/qcodeeditwidget/qsnippetedit.h 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 set(PLUGIN_SRC src/plugin/iwingplugin.h src/plugin/pluginsystem.cpp
src/plugin/pluginsystem.h src/plugin/settingpage.h) 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") "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("-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("-o", "--output", help="where to put the installer")
parser.add_argument("--no-build", action='store_false')
args = parser.parse_args() 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\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 += r'Root: HKCR; Subkey: "*\shell\OpenWithWingHexExplorer\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey' + '\n'
iss_content += """ iss_content += """
@ -249,19 +248,18 @@ Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChang
with codecs.open(script_src,'w', "utf-8-sig") as iss: with codecs.open(script_src,'w', "utf-8-sig") as iss:
iss.write(iss_content) iss.write(iss_content)
if(args.build):
print(Fore.GREEN + ">> Copying finished, running ISCC building..." + Style.RESET_ALL) print(Fore.GREEN + ">> Copying finished, running ISCC building..." + Style.RESET_ALL)
pak_out = "" pak_out = ""
if args.output is None: if args.output is None:
pak_out = exeDebPath pak_out = exeDebPath
else: else:
pak_out = args.output pak_out = args.output
ret = run_command_interactive([args.cc, f'/O{pak_out}', script_src]) ret = run_command_interactive([args.cc, f'/O{pak_out}', script_src])
exit(ret) exit(ret)
exit(0)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -10,6 +10,8 @@
<file>images/clearhis.png</file> <file>images/clearhis.png</file>
<file>images/clone.png</file> <file>images/clone.png</file>
<file>images/closefile.png</file> <file>images/closefile.png</file>
<file>images/codefmt.png</file>
<file>images/codeformat.png</file>
<file>images/copy.png</file> <file>images/copy.png</file>
<file>images/copyhex.png</file> <file>images/copyhex.png</file>
<file>images/cut.png</file> <file>images/cut.png</file>
@ -89,6 +91,7 @@
<file>images/scriptfolderusr.png</file> <file>images/scriptfolderusr.png</file>
<file>images/setting.png</file> <file>images/setting.png</file>
<file>images/settingplugin.png</file> <file>images/settingplugin.png</file>
<file>images/snippt.png</file>
<file>images/soft.png</file> <file>images/soft.png</file>
<file>images/sponsor.png</file> <file>images/sponsor.png</file>
<file>images/sum.png</file> <file>images/sum.png</file>
@ -100,6 +103,7 @@
<file>images/win.png</file> <file>images/win.png</file>
<file>images/workspace.png</file> <file>images/workspace.png</file>
<file>images/writable.png</file> <file>images/writable.png</file>
<file>src/TESTCODE.as</file>
</qresource> </qresource>
<qresource prefix="/qpathedit/icons"> <qresource prefix="/qpathedit/icons">
<file alias="dialog.ico">3rdparty/QPathEdit/Fatcow-Farm-Fresh-Dialog.ico</file> <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="copy.png">images/copy.png</file>
<file alias="cut.png">images/cut.png</file> <file alias="cut.png">images/cut.png</file>
<file alias="find.png">images/find.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="paste.png">images/paste.png</file>
<file alias="redo.png">images/redo.png</file> <file alias="redo.png">images/redo.png</file>
<file alias="replace.png">images/replace.png</file> <file alias="replace.png">images/replace.png</file>
<file alias="undo.png">images/undo.png</file> <file alias="undo.png">images/undo.png</file>
<file alias="goto.png">images/goto.png</file>
</qresource> </qresource>
<qresource prefix="/completion"> <qresource prefix="/completion">
<file>images/completion/classnew.png</file>
<file>images/completion/CTvirtuals.png</file> <file>images/completion/CTvirtuals.png</file>
<file>images/completion/CVclass.png</file> <file>images/completion/CVclass.png</file>
<file>images/completion/CVenum.png</file> <file>images/completion/CVenum.png</file>
@ -146,5 +149,6 @@
<file>images/completion/CVstruct.png</file> <file>images/completion/CVstruct.png</file>
<file>images/completion/CVtypedef.png</file> <file>images/completion/CVtypedef.png</file>
<file>images/completion/CVunion.png</file> <file>images/completion/CVunion.png</file>
<file>images/completion/classnew.png</file>
</qresource> </qresource>
</RCC> </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 <QFont>
#include "class/clangformatmanager.h"
#include "class/langservice.h"
#include "class/logger.h" #include "class/logger.h"
#include "languagemanager.h" #include "languagemanager.h"
#include "settingmanager.h" #include "settingmanager.h"
@ -58,6 +60,7 @@ AppManager::AppManager(int &argc, char *argv[])
SkinManager::instance(); SkinManager::instance();
LanguageManager::instance(); LanguageManager::instance();
ClangFormatManager::instance();
_w = new MainWindow; _w = new MainWindow;

View File

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

View File

@ -33,10 +33,13 @@ public:
virtual QCodeCompletionEngine *clone() override; virtual QCodeCompletionEngine *clone() override;
virtual QString language() const override; virtual QString language() const override;
virtual QStringList extensions() const override; virtual QStringList extensions() const override;
virtual void setEditor(QEditor *e) override; virtual void setEditor(QEditor *e) override;
QCodeCompletionWidget *codeCompletionWidget() const;
protected: protected:
virtual void complete(const QDocumentCursor &c, virtual void complete(const QDocumentCursor &c,
const QString &trigger) override; 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 "class/skinmanager.h"
#include "qdocument.h" #include "qdocument.h"
#include "qeditor.h" #include "qeditor.h"
#include "qformat.h"
#include "qformatscheme.h" #include "qformatscheme.h"
#include "qsnippetmanager.h" #include "qsnippetmanager.h"
@ -25,11 +26,22 @@ void LangService::init(asIScriptEngine *engine) {
new QFormatScheme(QStringLiteral(":/qcodeedit/as_light.qxf"), this); new QFormatScheme(QStringLiteral(":/qcodeedit/as_light.qxf"), this);
break; 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); QDocument::setDefaultFormatScheme(format);
m_language = new QLanguageFactory(format, this); m_language = new QLanguageFactory(format, this);
m_language->addDefinitionPath(QStringLiteral(":/qcodeedit")); 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_snippetManager = new QSnippetManager(this);
m_snipbind = new QSnippetBinding(m_snippetManager); m_snipbind = new QSnippetBinding(m_snippetManager);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,24 +23,6 @@
#include <QShortcut> #include <QShortcut>
ScriptingConsole::ScriptingConsole(QWidget *parent) : QConsoleWidget(parent) { 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); auto shortCut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_L), this);
connect(shortCut, &QShortcut::activated, this, connect(shortCut, &QShortcut::activated, this,
&ScriptingConsole::clearConsole); &ScriptingConsole::clearConsole);
@ -53,7 +35,7 @@ void ScriptingConsole::stdOut(const QString &str) { writeStdOut(str); }
void ScriptingConsole::stdErr(const QString &str) { writeStdErr(str); } void ScriptingConsole::stdErr(const QString &str) { writeStdErr(str); }
void ScriptingConsole::stdWarn(const QString &str) { void ScriptingConsole::stdWarn(const QString &str) {
write(str, m_stdoutFmtWarn); write(str, QStringLiteral("stdwarn"));
} }
void ScriptingConsole::newLine() { _s << Qt::endl; } void ScriptingConsole::newLine() { _s << Qt::endl; }
@ -91,6 +73,17 @@ void ScriptingConsole::init() {
&ScriptingConsole::consoleCommand); &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() { void ScriptingConsole::clearConsole() {
setMode(Output); setMode(Output);
clear(); clear();
@ -131,7 +124,7 @@ QString ScriptingConsole::getInput() {
if (!_cmdQueue.isEmpty()) { if (!_cmdQueue.isEmpty()) {
instr = _cmdQueue.takeFirst(); instr = _cmdQueue.takeFirst();
setMode(Output); setMode(Output);
write(instr, QTextCharFormat()); QConsoleWidget::write(instr);
setMode(Input); setMode(Input);
break; break;
} }
@ -165,7 +158,7 @@ void ScriptingConsole::appendCommandPrompt(bool storeOnly) {
_lastCommandPrompt = storeOnly; _lastCommandPrompt = storeOnly;
write(commandPrompt, m_stdoutFmtTitle); QConsoleWidget::write(commandPrompt);
} }
ScriptMachine *ScriptingConsole::machine() const { return _sp; } ScriptMachine *ScriptingConsole::machine() const { return _sp; }

View File

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

View File

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

View File

@ -20,6 +20,7 @@
#include "QWingRibbon/ribbontabcontent.h" #include "QWingRibbon/ribbontabcontent.h"
#include "Qt-Advanced-Docking-System/src/DockAreaWidget.h" #include "Qt-Advanced-Docking-System/src/DockAreaWidget.h"
#include "aboutsoftwaredialog.h" #include "aboutsoftwaredialog.h"
#include "class/clangformatmanager.h"
#include "class/langservice.h" #include "class/langservice.h"
#include "class/languagemanager.h" #include "class/languagemanager.h"
#include "class/qkeysequences.h" #include "class/qkeysequences.h"
@ -27,12 +28,14 @@
#include "class/wingfiledialog.h" #include "class/wingfiledialog.h"
#include "class/wingmessagebox.h" #include "class/wingmessagebox.h"
#include "control/toast.h" #include "control/toast.h"
#include "qcodeeditwidget/qdocumentswaptextcommand.h"
#include "qcodeeditwidget/qeditconfig.h" #include "qcodeeditwidget/qeditconfig.h"
#include "qcodeeditwidget/qsnippetedit.h" #include "qcodeeditwidget/qsnippetedit.h"
#include "qdocumentline.h" #include "qdocumentline.h"
#include "qeditor.h" #include "qeditor.h"
#include "qformatscheme.h" #include "qformatscheme.h"
#include "qlinemarksinfocenter.h" #include "qlinemarksinfocenter.h"
#include "settings/clangformatsetdialog.h"
#include <QDesktopServices> #include <QDesktopServices>
#include <QHeaderView> #include <QHeaderView>
@ -375,6 +378,12 @@ RibbonTabContent *ScriptingDialog::buildEditPage(RibbonTabContent *tab) {
shortcuts.keySequence(QKeySequences::Key::GOTO)); shortcuts.keySequence(QKeySequences::Key::GOTO));
} }
{
auto pannel = tab->addGroup(tr("Format"));
addPannelAction(pannel, QStringLiteral("codefmt"), tr("CodeFormat"),
&ScriptingDialog::on_codefmt);
}
return tab; return tab;
} }
@ -508,8 +517,13 @@ RibbonTabContent *ScriptingDialog::buildSettingPage(RibbonTabContent *tab) {
auto pannel = tab->addGroup(tr("Settings")); auto pannel = tab->addGroup(tr("Settings"));
addPannelAction(pannel, QStringLiteral("file"), tr("Editor"), 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; return tab;
} }
@ -572,7 +586,6 @@ ScriptingDialog::buildUpOutputShowDock(ads::CDockManager *dock,
ads::DockWidgetArea area, ads::DockWidgetArea area,
ads::CDockAreaWidget *areaw) { ads::CDockAreaWidget *areaw) {
m_consoleout = new ScriptingConsole(this); m_consoleout = new ScriptingConsole(this);
m_consoleout->clear();
m_consoleout->setMode(ScriptingConsole::Output); m_consoleout->setMode(ScriptingConsole::Output);
auto dw = buildDockWidget(dock, QStringLiteral("ConsoleOutput"), auto dw = buildDockWidget(dock, QStringLiteral("ConsoleOutput"),
tr("ConsoleOutput"), m_consoleout); tr("ConsoleOutput"), m_consoleout);
@ -954,6 +967,9 @@ void ScriptingDialog::buildUpSettingDialog() {
new QSnippetEdit(LangService::instance().snippetManager(), m_setdialog); new QSnippetEdit(LangService::instance().snippetManager(), m_setdialog);
m_setdialog->addPage(snip); m_setdialog->addPage(snip);
auto clang = new ClangFormatSetDialog(m_setdialog);
m_setdialog->addPage(clang);
m_setdialog->build(); 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(); } void ScriptingDialog::on_about() { AboutSoftwareDialog().exec(); }

View File

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

View File

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

View File

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

View File

@ -22,11 +22,8 @@
<property name="title"> <property name="title">
<string>Font</string> <string>Font</string>
</property> </property>
<layout class="QGridLayout"> <layout class="QGridLayout" name="layoutFont">
<property name="margin" stdset="0"> <item row="1" column="0">
<number>4</number>
</property>
<item row="0" column="0">
<widget class="QFontComboBox" name="cbFont"> <widget class="QFontComboBox" name="cbFont">
<property name="font"> <property name="font">
<font> <font>
@ -40,10 +37,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="1" column="1" colspan="2">
<widget class="QSpinBox" name="spnFontSize"> <widget class="QSpinBox" name="spnFontSize">
<property name="buttonSymbols"> <property name="buttonSymbols">
<enum>QAbstractSpinBox::UpDownArrows</enum> <enum>QAbstractSpinBox::ButtonSymbols::UpDownArrows</enum>
</property> </property>
<property name="minimum"> <property name="minimum">
<number>6</number> <number>6</number>
@ -56,49 +53,22 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" colspan="3"> <item row="2" column="0" colspan="3">
<widget class="QLabel" name="lblSampleText"> <widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font"> <property name="font">
<font> <font>
<family>Monospace</family> <bold>true</bold>
<underline>true</underline>
</font> </font>
</property> </property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text"> <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>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="margin">
<number>0</number>
</property> </property>
</widget> </widget>
</item> </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> </layout>
</widget> </widget>
</item> </item>
@ -145,7 +115,7 @@
<item> <item>
<spacer> <spacer>
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Orientation::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
@ -263,10 +233,10 @@
<item> <item>
<spacer> <spacer>
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Orientation::Vertical</enum>
</property> </property>
<property name="sizeType"> <property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum> <enum>QSizePolicy::Policy::MinimumExpanding</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>

View File

@ -23,6 +23,7 @@
#include "qsnippet.h" #include "qsnippet.h"
#include "qsnippetmanager.h" #include "qsnippetmanager.h"
#include "utilities.h"
#include <QMessageBox> #include <QMessageBox>
@ -49,7 +50,9 @@ QSnippetEdit::QSnippetEdit(QSnippetManager *mgr, QWidget *p)
QSnippetManager *QSnippetEdit::snippetManager() const { return m_manager; } 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"); } 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-foreground: #eff0f1;
qproperty-opacity: 0.8; qproperty-opacity: 0.8;
} }
QConsoleWidget
{
background-color: #1d2023;
color: #eff0f1;
selection-background-color: #3daee9;
}