From dab8f1e7d4d3a83a7b550add618f57343abb2ce7 Mon Sep 17 00:00:00 2001 From: Mark Long Date: Sat, 29 Oct 2016 18:11:42 -0500 Subject: [PATCH] Improved control character display in ApplesoftViewer --- src/applesoftfile/ApplesoftRetokenizer.cpp | 1 - src/applesoftfile/applesoftformatter.cxx | 328 +++------------------ src/applesoftfile/applesoftformatter.h | 21 +- src/applesoftfile/applesofttoken.cxx | 16 +- src/applesoftfile/applesofttoken.h | 5 +- src/ui/viewers/applesoftfileviewer.cxx | 34 ++- src/ui/viewers/applesoftfileviewer.h | 2 + 7 files changed, 92 insertions(+), 315 deletions(-) diff --git a/src/applesoftfile/ApplesoftRetokenizer.cpp b/src/applesoftfile/ApplesoftRetokenizer.cpp index 3de0408..62f6db3 100644 --- a/src/applesoftfile/ApplesoftRetokenizer.cpp +++ b/src/applesoftfile/ApplesoftRetokenizer.cpp @@ -175,7 +175,6 @@ void ApplesoftRetokenizer::retokenizeLinesForFormatting() void ApplesoftRetokenizer::retokenizeLine(ApplesoftLine &line) { - qDebug() << "Retokenize line"; QList tmptokens = QList::fromVector(line.tokens); tmptokens = retokenizeRems(tmptokens); tmptokens = retokenizeStrings(tmptokens); diff --git a/src/applesoftfile/applesoftformatter.cxx b/src/applesoftfile/applesoftformatter.cxx index c212072..94b787c 100644 --- a/src/applesoftfile/applesoftformatter.cxx +++ b/src/applesoftfile/applesoftformatter.cxx @@ -2,6 +2,7 @@ #include "util.h" #include #include +#include #define HEXPREFIX "0x" @@ -17,287 +18,6 @@ void ApplesoftFormatter::setFile(ApplesoftFile *file) emit newFile(file); } -void ApplesoftFormatter::formatText() -{ - m_formattedText.clear(); - - if (!m_file) { - return; - } - - - QString formattedText; - m_flowTargets.clear(); - - foreach (ApplesoftLine line, m_file->getLines()) { - QString linestring = QString("%1 ").arg(line.linenum,5,10,QChar(' ')); - - int indentlevel = 1; - formattedText.append(linestring); - - - QVectorIterator tokenIt(line.tokens); - ApplesoftToken previousToken; - bool firstToken = true; - while (tokenIt.hasNext()) - { - ApplesoftToken token = tokenIt.next(); - bool isFlowTarget = false; - - QString tokenstr = token.getRawPrintableString(); - - if (firstToken) - { - if (!tokenstr.startsWith(" ")) - { - tokenstr.prepend(" "); - } - firstToken = false; - } - - - //TODO: Move this to the parser. - //TODO: This doesn't yet handle: ON expr GOTO/GOSUB n1,n2,n3,... - if (previousToken.getTokenId() == ApplesoftToken::ASGoto || - previousToken.getTokenId() == ApplesoftToken::ASGosub || - previousToken.getTokenId() == ApplesoftToken::ASThen) - { - isFlowTarget = false; - if (previousToken.getTokenId() == ApplesoftToken::ASGoto || - previousToken.getTokenId() == ApplesoftToken::ASGosub) - { - isFlowTarget = true; - } - else if (previousToken.getTokenId() == ApplesoftToken::ASThen && - token.getTokenId() == ApplesoftToken::IntegerTokenVal) - { - isFlowTarget = true; - } - - if (isFlowTarget) - { - QPair pair; - pair.first = line.linenum; - pair.second = token.getWordValue(); - m_flowTargets.append(pair); - } - } - - if (m_format_options.testFlag(ShowIntsAsHex)) { - if (token.getTokenId() == ApplesoftToken::IntegerTokenVal) - { - bool okToConvert = !isFlowTarget; - - if (okToConvert) - { - quint32 ui32val = token.getUnsignedIntegerValue(); - qint32 i32val = token.getIntegerValue(); - if ((i32val < 128 && i32val >= -128) || ui32val < 256) - { - quint8 ui8 = ui32val; - tokenstr = HEXPREFIX+uint8ToHex(ui8); - } - else if ((i32val < 32768 && i32val >= -32768) || ui32val < 65536) - { - quint16 ui16 = ui32val; - tokenstr = HEXPREFIX+uint16ToHex(ui16); - } - else - { - tokenstr = HEXPREFIX+uint32ToHex(ui32val); - } - } - } - } - - if (m_format_options.testFlag(BreakAfterReturn)) { - if (token.getTokenId() == ApplesoftToken::ASReturn) - { - tokenstr += "\n"; - } - } - - if (m_format_options.testFlag(ReindentCode)) - { - if (token.getTokenId() == ':') - { - tokenstr += "\n"; - for (int ind = 0; ind < indentlevel; ind++) - { - tokenstr += " "; - } - if (!tokenIt.peekNext().getRawPrintableString().startsWith(" ")) - { - tokenstr += " "; - } - } - if (token.getTokenId() == ApplesoftToken::ASThen) - { - indentlevel++; - if (tokenIt.peekNext().getTokenId() != ApplesoftToken::IntegerTokenVal) - { - tokenstr += "\n"; - for (int ind = 0; ind < indentlevel; ind++) - { - tokenstr += " "; - } - if (!tokenIt.peekNext().getRawPrintableString().startsWith(" ")) - { - tokenstr += " "; - } - } - } - } - -#define noDEBUGTOKENS -#ifdef DEBUGTOKENS - if (token.getTokenId() >= 0x80) - { - tokenstr = QString("{%1 (%2)}").arg(tokenstr).arg(uint16ToHex(token.getTokenId())); - // tokenstr = " __ "; - } - -#endif - - if (m_format_options.testFlag(ShowCtrlChars)) - { - tokenstr.replace(QChar(0x7f),QChar(0x2401)); - - for (int idx = 1; idx <= 0x1f; idx++) { - if (idx == '\n') continue; - tokenstr.replace(QChar(idx),QChar(idx+0x2400)); - // tokenstr.replace(QChar(idx), QString("<%1>").arg(uint8ToHex(idx))); - } - } - - formattedText.append(tokenstr); - previousToken = token; - } // While tokenIt.hasNext(); - - formattedText.append("\n"); - if (m_format_options.testFlag(ReindentCode)) - { - // retval.append("\n"); - } - - } //foreach line - m_formattedText = formattedText; -} - - -void ApplesoftFormatter::newFormatText() -{ - m_formattedText.clear(); - - QString formattedText; - - foreach (ApplesoftLine line, m_file->getLines()) - { - QString linestring = QString("%1 ").arg(line.linenum,5,10,QChar(' ')); - formattedText.append(linestring); - - QVectorIteratortokenIt(line.tokens); - while (tokenIt.hasNext()) - { - ApplesoftToken token = tokenIt.next(); - bool isBranchTarget = false; - if (token.isOptFmtToken()) - { - switch (token.getTokenId()) - { - - case ApplesoftToken::OptFmtFlagFlowTargetNextTokenValue: - { - if (m_format_options.testFlag(ShowIntsAsHex)) - isBranchTarget = true; - break; - } - - case ApplesoftToken::OptFmtIndentLineBreakTokenValue: - { - if (m_format_options.testFlag(ReindentCode)) - formattedText.append("\n"); - break; - } - case ApplesoftToken::OptFmtIndentSpaceTokenValue: - { - if (m_format_options.testFlag(ReindentCode)) - formattedText.append(" "); - break; - } - case ApplesoftToken::OptFmtIndentTabTokenValue: - { - if (m_format_options.testFlag(ReindentCode)) - formattedText.append(" "); - break; - } - case ApplesoftToken::OptFmtLeadingSpaceTokenValue: - { - formattedText.append(" "); - break; - } - case ApplesoftToken::OptFmtReturnLineBreakTokenValue: - { - if (m_format_options.testFlag(BreakAfterReturn)) - formattedText.append("\n"); - break; - } - default: - { - break; - } - } - } // isOptFmt - else - { - QString tokenstr = token.getRawPrintableString(); - - if (token.getTokenId() == ApplesoftToken::IntegerTokenVal) - { - if (m_format_options.testFlag(ShowIntsAsHex) && !isBranchTarget) - { - quint32 ui32val = token.getUnsignedIntegerValue(); - qint32 i32val = token.getIntegerValue(); - if ((i32val < 128 && i32val >= -128) || ui32val < 256) - { - quint8 ui8 = ui32val; - tokenstr = HEXPREFIX+uint8ToHex(ui8); - } - else if ((i32val < 32768 && i32val >= -32768) || ui32val < 65536) - { - quint16 ui16 = ui32val; - tokenstr = HEXPREFIX+uint16ToHex(ui16); - } - else - { - tokenstr = HEXPREFIX+uint32ToHex(ui32val); - } - } // isShowIntsAsHex - } - - if (m_format_options.testFlag(ShowCtrlChars)) - { - tokenstr.replace(QChar(0x7f),QChar(0x2401)); - - for (int idx = 1; idx <= 0x1f; idx++) { - if (idx == '\n') continue; - tokenstr.replace(QChar(idx),QChar(idx+0x2400)); - // tokenstr.replace(QChar(idx), QString("<%1>").arg(uint8ToHex(idx))); - } - } // if ShowCtrlChars - - formattedText.append(tokenstr); - - } - - } // while tokenIt.hasNext() - - formattedText.append("\n"); - - } // foreach line - m_formattedText = formattedText; -} - void ApplesoftFormatter::formatDocument(QTextDocument *doc) { if (!doc) return; @@ -314,7 +34,8 @@ void ApplesoftFormatter::formatDocument(QTextDocument *doc) if (synhl) { - cursor.insertText(linestring,ApplesoftToken::textFormat(ApplesoftToken::LineNumberTokenVal)); + cursor.insertText(linestring, + ApplesoftToken::textFormat(ApplesoftToken::LineNumberTokenVal)); } else { @@ -406,19 +127,40 @@ void ApplesoftFormatter::formatDocument(QTextDocument *doc) isBranchTarget = false; } - if (m_format_options.testFlag(ShowCtrlChars)) + // if (m_format_options.testFlag(ShowCtrlChars)) + // { + // tokenstr.replace(QChar(0x7f),QChar(0x2401)); + + // for (int idx = 1; idx <= 0x1f; idx++) { + // if (idx == '\n') continue; + // tokenstr.replace(QChar(idx),QChar(idx+0x2400)); + // } + // } // if ShowCtrlChars + + + + QTextCharFormat invFormat = ApplesoftToken::defaultInverseTextFormat(); + if (m_format_options.testFlag(SyntaxHighlighting)) + invFormat = ApplesoftToken::textFormat( + ApplesoftToken::ControlCharTokenVal); + + + foreach (QChar ch, tokenstr) { - tokenstr.replace(QChar(0x7f),QChar(0x2401)); - - for (int idx = 1; idx <= 0x1f; idx++) { - if (idx == '\n') continue; - tokenstr.replace(QChar(idx),QChar(idx+0x2400)); - // tokenstr.replace(QChar(idx), QString("<%1>").arg(uint8ToHex(idx))); + if (ch == QChar(0x7f)) + { + cursor.insertText(QChar(0x00d7),invFormat); } - } // if ShowCtrlChars - - //formattedText.append(tokenstr); - cursor.insertText(tokenstr,fmt); + else if (ch < QChar(' ')) + { + if (m_format_options.testFlag(ShowCtrlChars)) + { + QChar newch = ch.unicode()+0x40; + cursor.insertText(newch,invFormat); + } + } + else cursor.insertText(ch,fmt); + } } diff --git a/src/applesoftfile/applesoftformatter.h b/src/applesoftfile/applesoftformatter.h index 2e5efc6..e6b1f2a 100644 --- a/src/applesoftfile/applesoftformatter.h +++ b/src/applesoftfile/applesoftformatter.h @@ -14,14 +14,13 @@ class ApplesoftFormatter : public QObject public: enum FormatOption { - NoOptions = 0x00, + NoOptions = 0x00, SyntaxHighlighting = 0x01, - ShowCtrlChars = 0x02, - BreakAfterReturn = 0x04, - - ReindentCode = 0x08, - ShowIntsAsHex = 0x10, + ShowCtrlChars = 0x02, + BreakAfterReturn = 0x04, + ReindentCode = 0x08, + ShowIntsAsHex = 0x10, AllFlags = 0xffffffff }; @@ -31,15 +30,11 @@ public: explicit ApplesoftFormatter(QObject *parent = 0); void setFlags(FormatOptions options) { m_format_options = options; } void setFile(ApplesoftFile *file); + FormatOptions flags() { return m_format_options; } - void formatText(); - QString getFormattedText() const { return m_formattedText; } - - QList > flowTargets() const { return m_flowTargets; } - - void newFormatText(); void formatDocument(QTextDocument *doc); + signals: void newFile(ApplesoftFile *file); @@ -47,11 +42,9 @@ public slots: private: FormatOptions m_format_options; - QList > m_flowTargets; ApplesoftFile *m_file; - QString m_formattedText; }; diff --git a/src/applesoftfile/applesofttoken.cxx b/src/applesoftfile/applesofttoken.cxx index 64c1b61..85cf257 100644 --- a/src/applesoftfile/applesofttoken.cxx +++ b/src/applesoftfile/applesofttoken.cxx @@ -135,12 +135,18 @@ QString ApplesoftToken::getRawPrintableString() const QTextCharFormat ApplesoftToken::defaultTextFormat() { QTextCharFormat tf; // Default -// tf.setFont(QFont("Courier")); -// tf.setFontPointSize(10); tf.setForeground(Qt::black); return tf; } +QTextCharFormat ApplesoftToken::defaultInverseTextFormat() +{ + QTextCharFormat tf; + tf.setForeground(Qt::white); + tf.setBackground(Qt::black); + return tf; +} + QTextCharFormat ApplesoftToken::textFormat(quint16 tokenType) { QTextCharFormat tf = defaultTextFormat(); @@ -182,6 +188,12 @@ QTextCharFormat ApplesoftToken::textFormat(quint16 tokenType) { tf.setForeground(Qt::darkRed); } + else if (tokenType == ControlCharTokenVal) + { + // Inverse of StringTokenVal + tf.setForeground(Qt::white); + tf.setBackground(Qt::blue); + } return tf; } diff --git a/src/applesoftfile/applesofttoken.h b/src/applesoftfile/applesofttoken.h index e2bd543..92a463e 100644 --- a/src/applesoftfile/applesofttoken.h +++ b/src/applesoftfile/applesofttoken.h @@ -49,7 +49,7 @@ public: static const quint16 OptFmtFlagFlowTargetNextTokenValue = 0xe004; static const quint16 OptFmtReturnLineBreakTokenValue = 0xe005; - + static const quint16 ControlCharTokenVal = 0xfffd; static const quint16 LineNumberTokenVal = 0xfffe; static const quint16 DefaultTokenVal = 0xffff; @@ -183,6 +183,8 @@ public: return textFormat(m_token_id); } + static QTextCharFormat defaultTextFormat(); + static QTextCharFormat defaultInverseTextFormat(); static QTextCharFormat textFormat(quint16 tokentype) ; QString getStringForToken(quint8 token) { @@ -190,7 +192,6 @@ public: return m_tokens[token]; } - static QTextCharFormat defaultTextFormat(); bool isOptFmtToken() const { return (m_token_id >= 0xe000 && m_token_id < 0xf000); } diff --git a/src/ui/viewers/applesoftfileviewer.cxx b/src/ui/viewers/applesoftfileviewer.cxx index b215b24..4007c6d 100644 --- a/src/ui/viewers/applesoftfileviewer.cxx +++ b/src/ui/viewers/applesoftfileviewer.cxx @@ -20,7 +20,7 @@ ApplesoftFileViewer::ApplesoftFileViewer(QWidget *parent) : setWindowTitle(title); m_formatter = new ApplesoftFormatter(this); - m_formatter->setFlags(ApplesoftFormatter::NoOptions); + m_formatter->setFlags(ApplesoftFormatter::ShowCtrlChars); connect(ui->findButton,SIGNAL(clicked(bool)), SLOT(findText())); m_isFirstFind = true; ui->textArea->setUndoRedoEnabled(false); @@ -32,13 +32,15 @@ ApplesoftFileViewer::ApplesoftFileViewer(QWidget *parent) : m_syntaxHighlightingAction = Q_NULLPTR; m_showVarExplorerAction = Q_NULLPTR; m_wordWrapAction = Q_NULLPTR; + m_showCtrlCharsAction = Q_NULLPTR; toggleWordWrap(settings.value("ASViewer.WordWrap",true).toBool()); setIndentCode(settings.value("ASViewer.indentCode",false).toBool(), NoReformat); setIntsAsHex(settings.value("ASViewer.intsAsHex",false).toBool(), NoReformat); setBreakAfterReturn(settings.value("ASViewer.breakAfterReturn",false).toBool(), NoReformat); - setSyntaxHighlighting(settings.value("ASViewer.syntaxHighlighting",false).toBool(), NoReformat); + setSyntaxHighlighting(settings.value("ASViewer.syntaxHighlighting",true).toBool(), NoReformat); + setShowCtrlChars(settings.value("ASViewer.showCtrlChars",true).toBool(), NoReformat); } ApplesoftFileViewer::~ApplesoftFileViewer() @@ -52,7 +54,7 @@ bool ApplesoftFileViewer::makeMenuOptions(QMenu *menu) if (!m_showIntsAction) { - m_showIntsAction = new QAction("Show &Ints as Hex",menu); + m_showIntsAction = new QAction("Show Ints as &Hex",menu); m_showIntsAction->setCheckable(true); m_showIntsAction->setChecked(settings.value("ASViewer.intsAsHex",false).toBool()); setIntsAsHex(settings.value("ASViewer.intsAsHex",false).toBool(),NoReformat); @@ -83,6 +85,16 @@ bool ApplesoftFileViewer::makeMenuOptions(QMenu *menu) } menu->addAction(m_blankAfterReturnsAction); + if (!m_showCtrlCharsAction) + { + m_showCtrlCharsAction = new QAction("Show &Control Characters",menu); + m_showCtrlCharsAction->setCheckable(true); + m_showCtrlCharsAction->setChecked(settings.value("ASViewer.showCtrlChars",false).toBool()); + setIndentCode(settings.value("ASViewer.showCtrlChars",false).toBool(),NoReformat); + connect(m_showCtrlCharsAction, SIGNAL(toggled(bool)), ui->findText,SLOT(clear())); + connect(m_showCtrlCharsAction, SIGNAL(toggled(bool)),SLOT(setShowCtrlChars(bool))); + } + menu->addAction(m_showCtrlCharsAction); menu->addSeparator(); @@ -175,6 +187,22 @@ void ApplesoftFileViewer::setBreakAfterReturn(bool enabled, ReformatRule reforma reformatText(); } +void ApplesoftFileViewer::setShowCtrlChars(bool enabled, ReformatRule reformat) +{ + if (enabled) + { + m_formatter->setFlags(m_formatter->flags() | ApplesoftFormatter::ShowCtrlChars); + } + else + { + m_formatter->setFlags(m_formatter->flags() & ~ApplesoftFormatter::ShowCtrlChars); + } + QSettings settings; + settings.setValue("ASViewer.showCtrlChars",enabled); + if (reformat == ForceReformat) + reformatText(); +} + void ApplesoftFileViewer::setSyntaxHighlighting(bool enabled, ReformatRule reformat) { if (enabled) diff --git a/src/ui/viewers/applesoftfileviewer.h b/src/ui/viewers/applesoftfileviewer.h index 6f9d260..a99c8cb 100644 --- a/src/ui/viewers/applesoftfileviewer.h +++ b/src/ui/viewers/applesoftfileviewer.h @@ -50,6 +50,7 @@ protected slots: void setIndentCode(bool enabled, ReformatRule reformat = ForceReformat); void setIntsAsHex(bool enabled, ReformatRule reformat = ForceReformat); void setBreakAfterReturn(bool enabled, ReformatRule reformat = ForceReformat); + void setShowCtrlChars(bool enabled, ReformatRule reformat = ForceReformat); void launchVarBrowser(); void reformatText(); @@ -67,6 +68,7 @@ private: QAction *m_syntaxHighlightingAction; QAction *m_showVarExplorerAction; QAction *m_wordWrapAction; + QAction *m_showCtrlCharsAction; }; #endif // APPLESOFTFILEVIEWER_H