From e181c7207b69044c21e17de558f017f49e93a2a8 Mon Sep 17 00:00:00 2001 From: Kebap Date: Wed, 1 May 2024 23:27:53 +0200 Subject: [PATCH 1/8] Infra: Refactor some TTextEdit code logic (#7218) #### Brief overview of PR changes/additions No functionality changes, just housekeeping. #### Motivation for adding to Mudlet Follow-up PR to realise my comments from #7123 #### Other info (issues closed, discussion etc) --- src/TTextEdit.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/TTextEdit.cpp b/src/TTextEdit.cpp index d3209d57d86..0bfb1c9ea52 100644 --- a/src/TTextEdit.cpp +++ b/src/TTextEdit.cpp @@ -1109,14 +1109,13 @@ void TTextEdit::expandSelectionToWords() if (yind >= 0 && yind < static_cast(mpBuffer->lineBuffer.size())) { for (; xind >= 0; --xind) { // Ensure xind is within the valid range for the current line - if (xind < static_cast(mpBuffer->lineBuffer.at(yind).size())) { - const QChar currentChar = mpBuffer->lineBuffer.at(yind).at(xind); - if (currentChar == QChar::Space - || mpHost->mDoubleClickIgnore.contains(currentChar)) { - break; - } - } else { + if (xind >= static_cast(mpBuffer->lineBuffer.at(yind).size())) { break; // xind is out of bounds, break the loop + } + const QChar currentChar = mpBuffer->lineBuffer.at(yind).at(xind); + if (currentChar == QChar::Space + || mpHost->mDoubleClickIgnore.contains(currentChar)) { + break; } } } From f4639c879d5d596cf88f1d91c11f52c0d7790016 Mon Sep 17 00:00:00 2001 From: Vadim Peretokin Date: Sun, 5 May 2024 17:02:39 +0200 Subject: [PATCH 2/8] Fix spellchecker loading on Windows (#6740) #### Brief overview of PR changes/additions The two file paths were swapped by accident #### Motivation for adding to Mudlet Should fix... something? #### Other info (issues closed, discussion etc) --- src/mudlet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mudlet.cpp b/src/mudlet.cpp index d34bbc2890f..c2fdc552b16 100644 --- a/src/mudlet.cpp +++ b/src/mudlet.cpp @@ -4331,8 +4331,8 @@ Hunhandle* mudlet::prepareProfileDictionary(const QString& hostName, QSet(wordList.begin(), wordList.end()); #if defined(Q_OS_WIN32) - mudlet::self()->sanitizeUtf8Path(affixPath, qsl("profile.dic")); - mudlet::self()->sanitizeUtf8Path(dictionaryPath, qsl("profile.aff")); + mudlet::self()->sanitizeUtf8Path(dictionaryPath, qsl("profile.dic")); + mudlet::self()->sanitizeUtf8Path(affixPath, qsl("profile.aff")); #endif return Hunspell_create(affixPath.toUtf8().constData(), dictionaryPath.toUtf8().constData()); } From 67c18dd103e728f358fe3f8ce1f1716dea6a076e Mon Sep 17 00:00:00 2001 From: Vadim Peretokin Date: Wed, 8 May 2024 09:19:50 +0200 Subject: [PATCH 3/8] Fix: announce autocompleted text for a11y (#7186) #### Brief overview of PR changes/additions Announce text that was autocompleted via screen readers #### Motivation for adding to Mudlet https://github.com/Mudlet/Mudlet/issues/6150#issuecomment-1994347946 #### Other info (issues closed, discussion etc) Close https://github.com/Mudlet/Mudlet/issues/6150#issuecomment-1994347946 --- src/TCommandLine.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/TCommandLine.cpp b/src/TCommandLine.cpp index 9f1a3c861f7..fa4d5f89595 100644 --- a/src/TCommandLine.cpp +++ b/src/TCommandLine.cpp @@ -1064,9 +1064,11 @@ void TCommandLine::handleTabCompletion(bool direction) if (mTabCompletionCount < 0) { mTabCompletionCount = 0; } + const QString proposal = filterList[mTabCompletionCount]; const QString userWords = mTabCompletionTyped.left(typePosition); setPlainText(QString(userWords + proposal)); + mudlet::self()->announce(proposal); moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); mTabCompletionOld = toPlainText(); } @@ -1084,6 +1086,7 @@ void TCommandLine::handleAutoCompletion() QString neu = toPlainText(); neu.chop(textCursor().selectedText().size()); setPlainText(neu); + mudlet::self()->announce(neu); mTabCompletionOld = neu; const int oldLength = toPlainText().size(); if (mAutoCompletionCount >= mHistoryList.size()) { @@ -1098,6 +1101,7 @@ void TCommandLine::handleAutoCompletion() mAutoCompletionCount = i; mLastCompletion = mHistoryList[i]; setPlainText(mHistoryList[i]); + mudlet::self()->announce(mHistoryList[i]); moveCursor(QTextCursor::Start); for (int k = 0; k < oldLength; k++) { moveCursor(QTextCursor::Right, QTextCursor::MoveAnchor); @@ -1130,6 +1134,7 @@ void TCommandLine::historyMove(MoveDirection direction) mHistoryBuffer = 0; } setPlainText(mHistoryList[mHistoryBuffer]); + mudlet::self()->announce(mHistoryList[mHistoryBuffer]); if (mpHost->mHighlightHistory) { selectAll(); } else { From 5385f888d1b7de7a4541aa7e041438106d916590 Mon Sep 17 00:00:00 2001 From: Stephen Lyons Date: Wed, 8 May 2024 12:17:29 +0100 Subject: [PATCH 4/8] Improve: add faint support and separate bold from colours (#7010) #### Brief overview of PR changes/additions This disconnects the link that Mudlet had between ANSI colour numbers 8 to 15 (in the 16 and 256 colour ranges) from emboldening (increasing the "weight") of the Font used. It also adds support for the ANSI Escape SGR sequence "2" option for "faint" (a.k.a. "dim") which provides two additional "weights" that can be combined with the bold effect. So as to enable Mudlet to work with 16-Colour MUDs that still use the BOLD attribute to select the second set of 8 Colours a "BOLD is Bright" option is now provided - so as to emulate prior Mudlet behaviour it defaults to being enabled but in most cases users will want to disable it so that the Bold effect is used only to change the way the font is presented and possibly be combined with the Faint effect - provided that the font in use has enough weights. #### Motivation for adding to Mudlet I have often wondered about why we have been apply the bold font effect to characters that use the second eight of the ANSI 16 / 256 colour indexes - and, since it dates back to early Heiko era code (commit 3e127f554bb23f8e86fbe64c560bccfc7bd096d0 ) it is hard to see as there is no documentation. My best *guess* is that it was intended to emphasis that the colour was from the second eight of the sixteen which for Muds that use that many colours are the brighter ones (with the RGB components at "full-strength") compared to the first eight which are less bright/intense. #### Other info (issues closed, discussion etc) This should help to close #3693. I am considering providing (in a separate PR) a button on the display preferences for the colours of the main console that will "Reset to 8-color defaults" and to rename the existing one "Reset to 16/256 color defaults" which will swap (all but the "blacks") the first 8 with the second 8 so that MUDs that only use 8 colours will automagically show the "full-strength" colours for the eight that they do use. To demonstrate all four font weights (and to check that it works with the selected font) the following sample code could be used: ```lua feedTriggers("\027[2mFaint \027[22mNormal \027[1;2mDemi-bold \027[22;1mBold\027[22m\n") ``` --------- Signed-off-by: Stephen Lyons --- src/Host.h | 13 +- src/TAccessibleTextEdit.cpp | 27 +++- src/TBuffer.cpp | 269 +++++++++++++++------------------- src/TBuffer.h | 72 +++++++-- src/TLuaInterpreter.cpp | 10 +- src/TLuaInterpreter.h | 3 +- src/TLuaInterpreterUI.cpp | 160 ++++++++++---------- src/TMainConsole.h | 2 +- src/TTextEdit.cpp | 11 +- src/XMLexport.cpp | 4 +- src/XMLimport.cpp | 9 +- src/dlgProfilePreferences.cpp | 19 ++- src/dlgProfilePreferences.h | 2 +- src/mudlet-lua/lua/Other.lua | 1 + src/ui/profile_preferences.ui | 45 ++++-- 15 files changed, 367 insertions(+), 280 deletions(-) diff --git a/src/Host.h b/src/Host.h index acafdf11224..742e1dd7d82 100644 --- a/src/Host.h +++ b/src/Host.h @@ -4,7 +4,7 @@ /*************************************************************************** * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * - * Copyright (C) 2015-2020, 2022-2023 by Stephen Lyons * + * Copyright (C) 2015-2020, 2022-2024 by Stephen Lyons * * - slysven@virginmedia.com * * Copyright (C) 2016 by Ian Adkins - ieadkins@gmail.com * * Copyright (C) 2018 by Huadong Qi - novload@outlook.com * @@ -706,6 +706,17 @@ class Host : public QObject // shortcut to switch between the input line and the main window CaretShortcut mCaretShortcut = CaretShortcut::None; + // Support a long-standing hack among all clients for using the 1m + // Bold) code to select a set of brighter 8 colors (the second eight) from + // the 256 colors for "16 color" mode of operation - alongside the basic + // 30m (Black) to 37m (White) set of codes. Using the "AIXTERM" + // codes (90m to 97m) codes or the 38::5:Nm ones are later + // (better) ways of accessing that second set of 8 but some Servers only + // know the first for 16 color operation. The prior behaviour for Mudlet + // would be almost equivalent to this option being true but it limits the + // ability to have completely separate bold (and faint) font weightings: + bool mBoldIsBright = true; + signals: // Tells TTextEdit instances for this profile how to draw the ambiguous // width characters: diff --git a/src/TAccessibleTextEdit.cpp b/src/TAccessibleTextEdit.cpp index 244dd4b4be6..6e4f41117dd 100644 --- a/src/TAccessibleTextEdit.cpp +++ b/src/TAccessibleTextEdit.cpp @@ -1,7 +1,8 @@ /*************************************************************************** * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * * Copyright (C) 2014-2017 by Ahmed Charles - acharles@outlook.com * - * Copyright (C) 2014-2020 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2014-2020, 2023-2024 by Stephen Lyons * + * - slysven@virginmedia.com * * Copyright (C) 2022 by Thiago Jung Bauermann - bauermann@kolabnow.com * * * * This program is free software; you can redistribute it and/or modify * @@ -388,7 +389,22 @@ QString TAccessibleTextEdit::attributes(int offset, int *startOffset, int *endOf const TChar &charStyle = textEdit()->mpBuffer->buffer.at(line).at(column); // IAccessible2's text attributes don't support the overline attribute. const TChar::AttributeFlags attributes = charStyle.allDisplayAttributes(); - const bool isBold = (attributes & TChar::Bold) || font.weight() > QFont::Normal; + // According to + // https://wiki.linuxfoundation.org/accessibility/iaccessible2/textattributes + // only the names "normal" and "bold" are supported alongside the numeric + // values as explained in + // https://www.w3.org/TR/CSS21/fonts.html#font-boldness : +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + const int fontWeight = (attributes & TChar::Bold) ? ((attributes & TChar::Faint) ? TBuffer::csmCssFontWeight_boldAndFaint + : TBuffer::csmCssFontWeight_bold) + : ((attributes & TChar::Faint) ? TBuffer::csmCssFontWeight_faint + : TBuffer::csmCssFontWeight_normal); +#else + const int fontWeight = (attributes & TChar::Bold) ? ((attributes & TChar::Faint) ? TBuffer::csmFontWeight_boldAndFaint + : TBuffer::csmFontWeight_bold) + : ((attributes & TChar::Faint) ? TBuffer::csmFontWeight_faint + : TBuffer::csmFontWeight_normal); +#endif const bool isItalics = (attributes & TChar::Italic) || style == QFont::StyleItalic; const bool isStrikeOut = attributes & TChar::StrikeOut; const bool isUnderline = attributes & TChar::Underline; @@ -396,9 +412,10 @@ QString TAccessibleTextEdit::attributes(int offset, int *startOffset, int *endOf const bool caretIsHere = textEdit()->mpHost->caretEnabled() && textEdit()->mCaretLine == line && textEdit()->mCaretColumn == column; - // Different weight values are not handled. - if (isBold) { - ret += "font-weight:bold;"; + if (fontWeight != 400) { + // 400 is the "normal" value however we might not have defined ours to + // be that: + ret += "font-weight:" + QString::number(fontWeight) + ";"; } if (isItalics || style != QFont::StyleNormal) { ret += "font-style:" + QString::fromLatin1(isItalics ? "italic;" : "oblique;"); diff --git a/src/TBuffer.cpp b/src/TBuffer.cpp index 85cde48d254..37b0c410973 100644 --- a/src/TBuffer.cpp +++ b/src/TBuffer.cpp @@ -161,7 +161,6 @@ TBuffer::TBuffer(Host* pH, TConsole* pConsole) , mLightWhite(pH->mLightWhite) , mWhite(pH->mWhite) , mForeGroundColor(pH->mFgColor) -, mForeGroundColorLight(pH->mFgColor) , mBackGroundColor(pH->mBgColor) , mpHost(pH) { @@ -243,7 +242,6 @@ void TBuffer::updateColors() mLightWhite = pH->mLightWhite; mWhite = pH->mWhite; mForeGroundColor = pH->mFgColor; - mForeGroundColorLight = pH->mFgColor; mBackGroundColor = pH->mBgColor; } @@ -578,15 +576,16 @@ void TBuffer::translateToPlainText(std::string& incoming, const bool isFromServe const int spacesNeeded = temp.toInt(&isOk); if (isOk && spacesNeeded > 0) { const TChar::AttributeFlags attributeFlags = - ((mIsDefaultColor ? mBold || mpHost->mMxpClient.bold() : false) ? TChar::Bold : TChar::None) - | (mItalics || mpHost->mMxpClient.italic() ? TChar::Italic : TChar::None) + ( ((mBold || mpHost->mMxpClient.bold()) ? TChar::Bold : TChar::None) + | (mFaint ? TChar::Faint : TChar::None) + | ((mItalics || mpHost->mMxpClient.italic()) ? TChar::Italic : TChar::None) | (mOverline ? TChar::Overline : TChar::None) | (mReverse ? TChar::Reverse : TChar::None) - | (mStrikeOut || mpHost->mMxpClient.strikeOut() ? TChar::StrikeOut : TChar::None) - | (mUnderline || mpHost->mMxpClient.underline() ? TChar::Underline : TChar::None) + | ((mStrikeOut || mpHost->mMxpClient.strikeOut()) ? TChar::StrikeOut : TChar::None) + | ((mUnderline || mpHost->mMxpClient.underline()) ? TChar::Underline : TChar::None) | (mFastBlink ? TChar::FastBlink : (mBlink ? TChar::Blink :TChar::None)) | (TChar::alternateFontFlag(mAltFont)) - | (mConcealed ? TChar::Concealed : TChar::None); + | (mConcealed ? TChar::Concealed : TChar::None)); // Note: we are using the background color for the // foreground color as well so that we are transparent: @@ -730,17 +729,19 @@ void TBuffer::translateToPlainText(std::string& incoming, const bool isFromServe if (mpHost->mBlankLineBehaviour == Host::BlankLineBehaviour::Hide) { localBufferPosition++; continue; - } else if (mpHost->mBlankLineBehaviour == Host::BlankLineBehaviour::ReplaceWithSpace) { + } + if (mpHost->mBlankLineBehaviour == Host::BlankLineBehaviour::ReplaceWithSpace) { const TChar::AttributeFlags attributeFlags = - ((mIsDefaultColor ? mBold || mpHost->mMxpClient.bold(): false) ? TChar::Bold : TChar::None) - | (mItalics || mpHost->mMxpClient.italic() ? TChar::Italic : TChar::None) + ( ((mBold || mpHost->mMxpClient.bold()) ? TChar::Bold : TChar::None) + | (mFaint ? TChar::Faint : TChar::None) + | ((mItalics || mpHost->mMxpClient.italic()) ? TChar::Italic : TChar::None) | (mOverline ? TChar::Overline : TChar::None) | (mReverse ? TChar::Reverse : TChar::None) - | (mStrikeOut || mpHost->mMxpClient.strikeOut() ? TChar::StrikeOut : TChar::None) - | (mUnderline || mpHost->mMxpClient.underline() ? TChar::Underline : TChar::None) + | ((mStrikeOut || mpHost->mMxpClient.strikeOut()) ? TChar::StrikeOut : TChar::None) + | ((mUnderline || mpHost->mMxpClient.underline()) ? TChar::Underline : TChar::None) | (mFastBlink ? TChar::FastBlink : (mBlink ? TChar::Blink :TChar::None)) | (TChar::alternateFontFlag(mAltFont)) - | (mConcealed ? TChar::Concealed : TChar::None); + | (mConcealed ? TChar::Concealed : TChar::None)); // Note: we are using the background color for the // foreground color as well so that we are transparent: @@ -878,17 +879,21 @@ void TBuffer::translateToPlainText(std::string& incoming, const bool isFromServe } const TChar::AttributeFlags attributeFlags = - ((mIsDefaultColor ? mBold || mpHost->mMxpClient.bold() : false) ? TChar::Bold : TChar::None) - | (mItalics || mpHost->mMxpClient.italic() ? TChar::Italic : TChar::None) + ( ((mBold || mpHost->mMxpClient.bold()) ? TChar::Bold : TChar::None) + | (mFaint ? TChar::Faint : TChar::None) + | ((mItalics || mpHost->mMxpClient.italic()) ? TChar::Italic : TChar::None) | (mOverline ? TChar::Overline : TChar::None) | (mReverse ? TChar::Reverse : TChar::None) - | (mStrikeOut || mpHost->mMxpClient.strikeOut() ? TChar::StrikeOut : TChar::None) - | (mUnderline || mpHost->mMxpClient.underline() ? TChar::Underline : TChar::None) + | ((mStrikeOut || mpHost->mMxpClient.strikeOut()) ? TChar::StrikeOut : TChar::None) + | ((mUnderline || mpHost->mMxpClient.underline()) ? TChar::Underline : TChar::None) | (mFastBlink ? TChar::FastBlink : (mBlink ? TChar::Blink :TChar::None)) | (TChar::alternateFontFlag(mAltFont)) - | (mConcealed ? TChar::Concealed : TChar::None); + | (mConcealed ? TChar::Concealed : TChar::None)); - TChar c((!mIsDefaultColor && mBold) ? mForeGroundColorLight : mForeGroundColor, mBackGroundColor, attributeFlags); + TChar c((mpHost && mpHost->mBoldIsBright && mMayShift8ColorSet && mBold) ? mForeGroundColorLight + : mForeGroundColor, + mBackGroundColor, + attributeFlags); if (mpHost->mMxpClient.isInLinkMode()) { c.mLinkIndex = mLinkStore.getCurrentLinkID(); @@ -921,6 +926,7 @@ void TBuffer::decodeSGR38(const QStringList& parameters, bool isColonSeparated) qDebug() << " TBuffer::decodeSGR38(" << parameters << "," << isColonSeparated <<") INFO - called"; #endif if (parameters.at(1) == QLatin1String("5")) { + int tag = 0; if (parameters.count() > 2) { bool isOk = false; @@ -945,53 +951,29 @@ void TBuffer::decodeSGR38(const QStringList& parameters, bool isColonSeparated) #endif } - if (tag < 16) { - if (tag >= 8) { - tag -= 8; - mBold = true; - } else { - mBold = false; - } - mIsDefaultColor = false; - + if (tag >=0 && tag < 16) { switch (tag) { - case 0: - mForeGroundColor = mBlack; - mForeGroundColorLight = mLightBlack; - break; - case 1: - mForeGroundColor = mRed; - mForeGroundColorLight = mLightRed; - break; - case 2: - mForeGroundColor = mGreen; - mForeGroundColorLight = mLightGreen; - break; - case 3: - mForeGroundColor = mYellow; - mForeGroundColorLight = mLightYellow; - break; - case 4: - mForeGroundColor = mBlue; - mForeGroundColorLight = mLightBlue; - break; - case 5: - mForeGroundColor = mMagenta; - mForeGroundColorLight = mLightMagenta; - break; - case 6: - mForeGroundColor = mCyan; - mForeGroundColorLight = mLightCyan; - break; - case 7: - mForeGroundColor = mWhite; - mForeGroundColorLight = mLightWhite; - break; + case 0: mForeGroundColor = mBlack; break; + case 1: mForeGroundColor = mRed; break; + case 2: mForeGroundColor = mGreen; break; + case 3: mForeGroundColor = mYellow; break; + case 4: mForeGroundColor = mBlue; break; + case 5: mForeGroundColor = mMagenta; break; + case 6: mForeGroundColor = mCyan; break; + case 7: mForeGroundColor = mWhite; break; + case 8: mForeGroundColor = mLightBlack; break; + case 9: mForeGroundColor = mLightRed; break; + case 10: mForeGroundColor = mLightGreen; break; + case 11: mForeGroundColor = mLightYellow; break; + case 12: mForeGroundColor = mLightBlue; break; + case 13: mForeGroundColor = mLightMagenta; break; + case 14: mForeGroundColor = mLightCyan; break; + case 15: mForeGroundColor = mLightWhite; break; } - } else if (tag < 232) { + } else if (tag >=15 && tag < 232) { // because color 1-15 behave like normal ANSI colors - tag -= 16; + tag -= 16; // 6x6x6 RGB color space quint8 const r = tag / 36; quint8 const g = (tag - (r * 36)) / 6; @@ -1003,15 +985,15 @@ void TBuffer::decodeSGR38(const QStringList& parameters, bool isColonSeparated) mForeGroundColor = QColor(r == 0 ? 0 : (r - 1) * 40 + 95, g == 0 ? 0 : (g - 1) * 40 + 95, b == 0 ? 0 : (b - 1) * 40 + 95); - mForeGroundColorLight = mForeGroundColor; - } else { + } else if (tag >=232 && tag < 256) { const int value = (tag - 232) * 10 + 8; mForeGroundColor = QColor(value, value, value); - mForeGroundColorLight = mForeGroundColor; } + // else ignore it altogether } else if (parameters.at(1) == QLatin1String("2")) { + if (parameters.count() >= 6) { // Have enough for all three colour // components @@ -1045,7 +1027,6 @@ void TBuffer::decodeSGR38(const QStringList& parameters, bool isColonSeparated) #endif } } - mForeGroundColorLight = mForeGroundColor; } else if (parameters.at(1) == QLatin1String("4") || parameters.at(1) == QLatin1String("3") @@ -1078,9 +1059,9 @@ void TBuffer::decodeSGR48(const QStringList& parameters, bool isColonSeparated) #if defined(DEBUG_SGR_PROCESSING) qDebug() << " TBuffer::decodeSGR48(" << parameters << "," << isColonSeparated <<") INFO - called"; #endif - bool useLightColor = false; if (parameters.at(1) == QLatin1String("5")) { + int tag = 0; if (parameters.count() > 2) { bool isOk = false; @@ -1105,55 +1086,27 @@ void TBuffer::decodeSGR48(const QStringList& parameters, bool isColonSeparated) #endif } - if (tag < 16) { - if (tag >= 8) { - tag -= 8; - useLightColor = true; - } else { - useLightColor = false; - } - mIsDefaultColor = false; - QColor bgColorLight; - + if (tag >=0 && tag < 16) { switch (tag) { - case 0: - mBackGroundColor = mBlack; - bgColorLight = mLightBlack; - break; - case 1: - mBackGroundColor = mRed; - bgColorLight = mLightRed; - break; - case 2: - mBackGroundColor = mGreen; - bgColorLight = mLightGreen; - break; - case 3: - mBackGroundColor = mYellow; - bgColorLight = mLightYellow; - break; - case 4: - mBackGroundColor = mBlue; - bgColorLight = mLightBlue; - break; - case 5: - mBackGroundColor = mMagenta; - bgColorLight = mLightMagenta; - break; - case 6: - mBackGroundColor = mCyan; - bgColorLight = mLightCyan; - break; - case 7: - mBackGroundColor = mWhite; - bgColorLight = mLightWhite; - break; - } - if (useLightColor) { - mBackGroundColor = bgColorLight; + case 0: mBackGroundColor = mBlack; break; + case 1: mBackGroundColor = mRed; break; + case 2: mBackGroundColor = mGreen; break; + case 3: mBackGroundColor = mYellow; break; + case 4: mBackGroundColor = mBlue; break; + case 5: mBackGroundColor = mMagenta; break; + case 6: mBackGroundColor = mCyan; break; + case 7: mBackGroundColor = mWhite; break; + case 8: mBackGroundColor = mLightBlack; break; + case 9: mBackGroundColor = mLightRed; break; + case 10: mBackGroundColor = mLightGreen; break; + case 11: mBackGroundColor = mLightYellow; break; + case 12: mBackGroundColor = mLightBlue; break; + case 13: mBackGroundColor = mLightMagenta; break; + case 14: mBackGroundColor = mLightCyan; break; + case 15: mBackGroundColor = mLightWhite; break; } - } else if (tag < 232) { + } else if (tag >= 16 && tag < 232) { // because color 1-15 behave like normal ANSI colors tag -= 16; // 6x6x6 RGB color space @@ -1168,12 +1121,14 @@ void TBuffer::decodeSGR48(const QStringList& parameters, bool isColonSeparated) g == 0 ? 0 : (g - 1) * 40 + 95, b == 0 ? 0 : (b - 1) * 40 + 95); - } else { + } else if (tag >= 232 && tag < 256) { const int value = (tag - 232) * 10 + 8; mBackGroundColor = QColor(value, value, value); } + // else ignore it altogether } else if (parameters.at(1) == QLatin1String("2")) { + if (parameters.count() >= 6) { // Have enough for all three colour // components @@ -1520,10 +1475,11 @@ void TBuffer::decodeSGR(const QString& sequence) if (isOk) { switch (tag) { case 0: - mIsDefaultColor = true; mForeGroundColor = pHost->mFgColor; mBackGroundColor = pHost->mBgColor; + mMayShift8ColorSet = false; mBold = false; + mFaint = false; mItalics = false; mOverline = false; mReverse = false; @@ -1538,10 +1494,7 @@ void TBuffer::decodeSGR(const QString& sequence) mBold = true; break; case 2: - // Technically this should be faint (i.e. decreased - // intensity compared to normal and 22 should be - // the reset to "normal" intensity): - mBold = false; + mFaint = true; break; case 3: // There is a proposal by the "VTE" terminal @@ -1610,10 +1563,12 @@ void TBuffer::decodeSGR(const QString& sequence) case 19: mAltFont = 9; break; + // case 20: // Fracktur - a weird gothic Germanic font apparently // case 21: // Double underline according to specs // break; - case 22: + case 22: // "Neither Bold nor Dim" (Faint) mBold = false; + mFaint = false; break; case 23: mItalics = false; @@ -1637,44 +1592,48 @@ void TBuffer::decodeSGR(const QString& sequence) case 30: mForeGroundColor = mBlack; mForeGroundColorLight = mLightBlack; - mIsDefaultColor = false; + mMayShift8ColorSet = true; break; case 31: mForeGroundColor = mRed; mForeGroundColorLight = mLightRed; - mIsDefaultColor = false; + mMayShift8ColorSet = true; break; case 32: mForeGroundColor = mGreen; mForeGroundColorLight = mLightGreen; - mIsDefaultColor = false; + mMayShift8ColorSet = true; break; case 33: mForeGroundColor = mYellow; mForeGroundColorLight = mLightYellow; - mIsDefaultColor = false; + mMayShift8ColorSet = true; break; case 34: mForeGroundColor = mBlue; mForeGroundColorLight = mLightBlue; - mIsDefaultColor = false; + mMayShift8ColorSet = true; break; case 35: mForeGroundColor = mMagenta; mForeGroundColorLight = mLightMagenta; - mIsDefaultColor = false; + mMayShift8ColorSet = true; break; case 36: mForeGroundColor = mCyan; mForeGroundColorLight = mLightCyan; - mIsDefaultColor = false; + mMayShift8ColorSet = true; break; case 37: mForeGroundColor = mWhite; mForeGroundColorLight = mLightWhite; - mIsDefaultColor = false; + mMayShift8ColorSet = true; break; case 38: { + // We are not now using the basic 8 colors so we won't + // attempt to use the Bold attribute to shift those to the + // next 8 out of the first 16: + mMayShift8ColorSet = false; // We only have single elements so we will need to steal the // needed number from the remainder: if (paraIndex + 1 >= total) { @@ -1768,6 +1727,7 @@ void TBuffer::decodeSGR(const QString& sequence) break; case 39: //default foreground color mForeGroundColor = pHost->mFgColor; + mMayShift8ColorSet = false; break; case 40: mBackGroundColor = mBlack; @@ -1913,43 +1873,35 @@ void TBuffer::decodeSGR(const QString& sequence) // break; case 90: mForeGroundColor = mLightBlack; - mForeGroundColorLight = mLightBlack; - mIsDefaultColor = false; + mMayShift8ColorSet = false; break; case 91: mForeGroundColor = mLightRed; - mForeGroundColorLight = mLightRed; - mIsDefaultColor = false; + mMayShift8ColorSet = false; break; case 92: mForeGroundColor = mLightGreen; - mForeGroundColorLight = mLightGreen; - mIsDefaultColor = false; + mMayShift8ColorSet = false; break; case 93: mForeGroundColor = mLightYellow; - mForeGroundColorLight = mLightYellow; - mIsDefaultColor = false; + mMayShift8ColorSet = false; break; case 94: mForeGroundColor = mLightBlue; - mForeGroundColorLight = mLightBlue; - mIsDefaultColor = false; + mMayShift8ColorSet = false; break; case 95: mForeGroundColor = mLightMagenta; - mForeGroundColorLight = mLightMagenta; - mIsDefaultColor = false; + mMayShift8ColorSet = false; break; case 96: mForeGroundColor = mLightCyan; - mForeGroundColorLight = mLightCyan; - mIsDefaultColor = false; + mMayShift8ColorSet = false; break; case 97: mForeGroundColor = mLightWhite; - mForeGroundColorLight = mLightWhite; - mIsDefaultColor = false; + mMayShift8ColorSet = false; break; case 100: mBackGroundColor = mLightBlack; @@ -3366,10 +3318,21 @@ QString TBuffer::bufferToHtml(const bool showTimeStamp /*= false*/, const int ro // clang-format off if (currentFlags & TChar::Reverse) { // Swap the fore and background colours: - s.append(qsl("") + s.append(qsl("") .arg(QString::number(currentBgColor.red()), QString::number(currentBgColor.green()), QString::number(currentBgColor.blue()), // args 1 to 3 QString::number(currentFgColor.red()), QString::number(currentFgColor.green()), QString::number(currentFgColor.blue()), // args 4 to 6 - currentFlags & TChar::Bold ? QLatin1String(" font-weight: bold;") : QString(), // arg 7 + // Whilst we could skip an entry altogether if the weight is "normal" (400) we can't if the constant is set differently: +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QString::number(currentFlags & TChar::Bold ? (currentFlags & TChar::Faint ? csmCssFontWeight_boldAndFaint + : csmCssFontWeight_bold) + : (currentFlags & TChar::Faint ? csmCssFontWeight_faint + : csmCssFontWeight_normal)), // arg 7 +#else + QString::number(currentFlags & TChar::Bold ? (currentFlags & TChar::Faint ? csmFontWeight_boldAndFaint + : csmFontWeight_bold) + : (currentFlags & TChar::Faint ? csmFontWeight_faint + : csmFontWeight_normal)), // arg 7 +#endif currentFlags & TChar::Italic ? QLatin1String(" font-style: italic;") : QString(), // arg 8 currentFlags & (TChar::Underline | TChar::StrikeOut | TChar::Overline ) // remainder is arg 9 ? qsl(" text-decoration:%1%2%3") @@ -3378,10 +3341,20 @@ QString TBuffer::bufferToHtml(const bool showTimeStamp /*= false*/, const int ro currentFlags & TChar::Overline ? QLatin1String(" overline") : QString()) : QString())); } else { - s.append(qsl("") + s.append(qsl("") .arg(QString::number(currentFgColor.red()), QString::number(currentFgColor.green()), QString::number(currentFgColor.blue()), // args 1 to 3 QString::number(currentBgColor.red()), QString::number(currentBgColor.green()), QString::number(currentBgColor.blue()), // args 4 to 6 - currentFlags & TChar::Bold ? QLatin1String(" font-weight: bold;") : QString(), // arg 7 +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QString::number(currentFlags & TChar::Bold ? (currentFlags & TChar::Faint ? csmCssFontWeight_boldAndFaint + : csmCssFontWeight_bold) + : (currentFlags & TChar::Faint ? csmCssFontWeight_faint + : csmCssFontWeight_normal)), // arg 7 +#else + QString::number(currentFlags & TChar::Bold ? (currentFlags & TChar::Faint ? csmFontWeight_boldAndFaint + : csmFontWeight_bold) + : (currentFlags & TChar::Faint ? csmFontWeight_faint + : csmFontWeight_normal)), // arg 7 +#endif currentFlags & TChar::Italic ? QLatin1String(" font-style: italic;") : QString(), // arg 8 currentFlags & (TChar::Underline | TChar::StrikeOut | TChar::Overline ) // remainder is arg 9 ? qsl(" text-decoration:%1%2%3") diff --git a/src/TBuffer.h b/src/TBuffer.h index b872b445f48..133b6d856f8 100644 --- a/src/TBuffer.h +++ b/src/TBuffer.h @@ -4,7 +4,7 @@ /*************************************************************************** * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * - * Copyright (C) 2015, 2017-2018, 2020, 2022-2023 by Stephen Lyons * + * Copyright (C) 2015, 2017-2018, 2020, 2022-2024 by Stephen Lyons * * - slysven@virginmedia.com * * * * This program is free software; you can redistribute it and/or modify * @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,16 @@ class TChar None = 0x0, // Replaces TCHAR_BOLD 2 Bold = 0x1, // 0000 0000 0000 0000 0000 0000 0000 0001 + Faint = 0x40000, // 0000 0000 0000 0100 0000 0000 0000 0000 + /* + * The above pair of values for our text attribute flags can be + * combined to produced four different QFont::weight values - note + * however that the numeric values assigned to the enum have changed + * between Qt 5 & 6: + * Note that both values with the Bold flag should be greater than the + * QFont::Medium (Qt5: 57, Qt6: 500) value so BOTH will produce a + * QFont::bold() value of true, whereas the other two will not. + */ // Replaces TCHAR_ITALICS 1 Italic = 0x2, // 0000 0000 0000 0000 0000 0000 0000 0010 // Replaces TCHAR_UNDERLINE 4 @@ -104,7 +115,7 @@ class TChar // Mask for "any alternate font" - only the most significant one should // be used if more than one is set: AltFontMask = 0x1ff00, // 0000 0000 0000 0001 1111 1111 0000 0000 - TestMask = 0x3ffff, // 0000 0000 0000 0011 1111 1111 1111 1111 + TestMask = 0x7ffff, // 0000 0000 0000 0111 1111 1111 1111 1111 // The remainder are internal use ones that do not related to SGR codes // that have been parsed from the incoming text. // Has been found in a search operation (currently Main Console only) @@ -153,6 +164,7 @@ class TChar bool isSelected() const { return mIsSelected; } int linkIndex () const { return mLinkIndex; } bool isBold() const { return mFlags & Bold; } + bool isFaint() const { return mFlags & Faint; } bool isItalic() const { return mFlags & Italic; } bool isUnderlined() const { return mFlags & Underline; } bool isOverlined() const { return mFlags & Overline; } @@ -249,6 +261,45 @@ class TBuffer public: explicit TBuffer(Host* pH, TConsole* pConsole = nullptr); + + /* + * From the Qt5 documentation: + * "Qt uses a weighting scale from 0 to 99 similar to, but not the same + * as, the scales used in Windows or CSS. A weight of 0 will be thin, + * whilst 99 will be extremely black." + * From the Qt6 documentation: + * "Qt uses a weighting scale from 1 to 1000 compatible with OpenType. A + * weight of 1 will be thin, whilst 1000 will be extremely black." + * In summary: + * enum QFont::Weight Qt5 Qt6 + * QFont::Thin 0 100 + * Faint QFont::ExtraLight 12 200 + * QFont::Light 25 300 + * Normal QFont::Normal 50 400 + * QFont::Medium 57 500 + * Faint + Bold QFont::DemiBold 63 600 + * QFont::Bold 75 700 + * Bold QFont::ExtraBold 81 800 + * QFont::Black 87 900 + * + * Used in TTextEdit::drawGraphemeForeground(...) and + * dlgProfilePreferences::updateFontSampleDisplays(const QFont& newFont) + * and (for Qt 6.x or later) TBuffer::bufferToHtml(...): + */ + static const QFont::Weight csmFontWeight_faint = QFont::ExtraLight; + static const QFont::Weight csmFontWeight_normal = QFont::Normal; + static const QFont::Weight csmFontWeight_boldAndFaint = QFont::DemiBold; + static const QFont::Weight csmFontWeight_bold = QFont::ExtraBold; +#if QT_VERSION < QT_VERSION_CHECK(6 , 0, 0) + // Used in TBuffer::bufferToHtml(...) for Qt5 ONLY - the above and below + // values need to be kept in sync if changes are made - the Qt5 values below + // have to be the numeric equivalent to the enum values for the Qt6 ones: + static const int csmCssFontWeight_faint = 200; + static const int csmCssFontWeight_normal = 400; + static const int csmCssFontWeight_boldAndFaint = 600; + static const int csmCssFontWeight_bold = 800; +#endif + QPoint insert(QPoint&, const QString& text, int, int, int, int, int, int, bool bold, bool italics, bool underline, bool strikeout); bool insertInLine(QPoint& cursor, const QString& what, const TChar& format); void expandLine(int y, int count, TChar&); @@ -345,7 +396,6 @@ class TBuffer // Second stage in decoding OSC sequences - set true when we see the ASCII // ESC character followed by the ']' one: bool mGotOSC = false; - bool mIsDefaultColor = true; QColor mBlack; @@ -364,12 +414,6 @@ class TBuffer QColor mMagenta; QColor mLightWhite; QColor mWhite; - // These three replace three sets of three integers that were used to hold - // colour components during the parsing of SGR sequences, they were called: - // fgColor{R|G|B}, fgColorLight{R|G|B} and bgColor{R|G|B} apart from - // anything else, the first and last sets had the same names as arguments - // to several of the methods which meant the latter shadowed and masked - // them off! QColor mForeGroundColor; QColor mForeGroundColorLight; QColor mBackGroundColor; @@ -377,6 +421,7 @@ class TBuffer QPointer mpHost; bool mBold = false; + bool mFaint = false; bool mItalics = false; bool mOverline = false; bool mReverse = false; @@ -388,6 +433,12 @@ class TBuffer bool mFastBlink = false; bool mConcealed = false; quint8 mAltFont = 0; + // If enabled by a per profile setting (Host::mBoldIsBright == true) this + // will cause the first 8 ANSI colors (set by direct 30m to 37m) + // to be converted to second 8 ANSI colors (equivalent to 90m to + // 97m) if the Bold attribute (1m) is ALSO active - was called + // mIsDefaultColor but used in an inverted sense: + bool mMayShift8ColorSet = false; QString mMudLine; std::deque mMudBuffer; @@ -420,6 +471,9 @@ inline QDebug& operator<<(QDebug& debug, const TChar::AttributeFlags& attributes if (attributes & TChar::Bold) { presentAttributes << QLatin1String("Bold (0x01)"); } + if (attributes & TChar::Faint) { + presentAttributes << QLatin1String("Faint (0x40000)"); + } if (attributes & TChar::Italic) { presentAttributes << QLatin1String("Italic (0x02)"); } diff --git a/src/TLuaInterpreter.cpp b/src/TLuaInterpreter.cpp index b091c6cdb85..0b3da931ed8 100644 --- a/src/TLuaInterpreter.cpp +++ b/src/TLuaInterpreter.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * - * Copyright (C) 2013-2023 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2013-2024 by Stephen Lyons - slysven@virginmedia.com * * Copyright (C) 2014-2017 by Ahmed Charles - acharles@outlook.com * * Copyright (C) 2016 by Eric Wallace - eewallace@gmail.com * * Copyright (C) 2016 by Chris Leacy - cleacy1972@gmail.com * @@ -5075,6 +5075,7 @@ void TLuaInterpreter::initLuaGlobals() lua_register(pGlobalLua, "loadRawFile", TLuaInterpreter::loadReplay); lua_register(pGlobalLua, "loadReplay", TLuaInterpreter::loadReplay); lua_register(pGlobalLua, "setBold", TLuaInterpreter::setBold); + lua_register(pGlobalLua, "setFaint", TLuaInterpreter::setFaint); lua_register(pGlobalLua, "setItalics", TLuaInterpreter::setItalics); lua_register(pGlobalLua, "setOverline", TLuaInterpreter::setOverline); lua_register(pGlobalLua, "setReverse", TLuaInterpreter::setReverse); @@ -7238,6 +7239,10 @@ int TLuaInterpreter::setConfig(lua_State * L) } return success(); } + if (key == qsl("boldIsBright")) { + host.mBoldIsBright = getVerifiedBool(L, __func__, 2, "value"); + return success(); + } return warnArgumentValue(L, __func__, qsl("'%1' isn't a valid configuration option").arg(key)); } @@ -7345,7 +7350,8 @@ int TLuaInterpreter::getConfig(lua_State *L) default: lua_pushstring(L, "asis"); } - } } //, <- not needed until another one is added + } }, + { qsl("boldIsBright"), [&](){ lua_pushboolean(L, host.mBoldIsBright); } } //, <- not needed until another one is added }; auto it = configMap.find(key); diff --git a/src/TLuaInterpreter.h b/src/TLuaInterpreter.h index bebf628e919..4e054056bbc 100644 --- a/src/TLuaInterpreter.h +++ b/src/TLuaInterpreter.h @@ -3,7 +3,7 @@ /*************************************************************************** * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * - * Copyright (C) 2013-2016, 2018-2023 by Stephen Lyons * + * Copyright (C) 2013-2016, 2018-2024 by Stephen Lyons * * - slysven@virginmedia.com * * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * * Copyright (C) 2016-2018 by Ian Adkins - ieadkins@gmail.com * @@ -431,6 +431,7 @@ class TLuaInterpreter : public QThread static int hideToolBar(lua_State*); static int loadReplay(lua_State*); static int setBold(lua_State*); + static int setFaint(lua_State*); static int setItalics(lua_State*); static int setReverse(lua_State*); static int setOverline(lua_State*); diff --git a/src/TLuaInterpreterUI.cpp b/src/TLuaInterpreterUI.cpp index c0cf0581b89..18c39e4e35e 100644 --- a/src/TLuaInterpreterUI.cpp +++ b/src/TLuaInterpreterUI.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * - * Copyright (C) 2013-2022 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2013-2024 by Stephen Lyons - slysven@virginmedia.com * * Copyright (C) 2014-2017 by Ahmed Charles - acharles@outlook.com * * Copyright (C) 2016 by Eric Wallace - eewallace@gmail.com * * Copyright (C) 2016 by Chris Leacy - cleacy1972@gmail.com * @@ -1188,29 +1188,36 @@ int TLuaInterpreter::getTextFormat(lua_State* L) lua_newtable(L); - TChar::AttributeFlags const format = result.second.allDisplayAttributes(); lua_pushstring(L, "bold"); - lua_pushboolean(L, format & TChar::Bold); + lua_pushboolean(L, result.second.isBold()); + lua_settable(L, -3); + + lua_pushstring(L, "blink"); + lua_pushnumber(L, result.second.isFastBlinking() ? 2 : (result.second.isBlinking() ? 1 : 0)); + lua_settable(L, -3); + + lua_pushstring(L, "faint"); + lua_pushboolean(L, result.second.isFaint()); lua_settable(L, -3); lua_pushstring(L, "italic"); - lua_pushboolean(L, format & TChar::Italic); + lua_pushboolean(L, result.second.isItalic()); lua_settable(L, -3); lua_pushstring(L, "overline"); - lua_pushboolean(L, format & TChar::Overline); + lua_pushboolean(L, result.second.isOverlined()); lua_settable(L, -3); lua_pushstring(L, "reverse"); - lua_pushboolean(L, format & TChar::Reverse); + lua_pushboolean(L, result.second.isReversed()); lua_settable(L, -3); lua_pushstring(L, "strikeout"); - lua_pushboolean(L, format & TChar::StrikeOut); + lua_pushboolean(L, result.second.isStruckOut()); lua_settable(L, -3); lua_pushstring(L, "underline"); - lua_pushboolean(L, format & TChar::Underline); + lua_pushboolean(L, result.second.isUnderlined()); lua_settable(L, -3); const QColor foreground(result.second.foreground()); @@ -2265,6 +2272,21 @@ int TLuaInterpreter::setBorderTop(lua_State* L) return 0; } +// Documentation: https://wiki.mudlet.org/w/Manual:Lua_Functions#setBold +int TLuaInterpreter::setFaint(lua_State* L) +{ + QString windowName; + int s = 1; + if (lua_gettop(L) > 1) { // Have more than one argument so first must be a console name + windowName = WINDOW_NAME(L, s++); + } + const bool isAttributeEnabled = getVerifiedBool(L, __func__, s, "enable faint attribute"); + auto console = CONSOLE(L, windowName); + console->setDisplayAttributes(TChar::Faint, isAttributeEnabled); + lua_pushboolean(L, true); + return 1; +} + // Documentation: https://wiki.mudlet.org/w/Manual:Lua_Functions#setFgColor int TLuaInterpreter::setFgColor(lua_State* L) { @@ -2765,93 +2787,61 @@ int TLuaInterpreter::setTextFormat(lua_State* L) colorComponents[5] = qRound(qBound(0.0, getVerifiedDouble(L, __func__, 7, "blue foreground color component"), 255.0)); int s = 7; - bool bold; - if (lua_isboolean(L, ++s)) { - bold = lua_toboolean(L, s); - } else if (lua_isnumber(L, s)) { - bold = !qFuzzyCompare(1.0, 1.0 + lua_tonumber(L, s)); - } else { - lua_pushfstring(L, "setTextFormat: bad argument #%d type (bold format as boolean or number {true/non-zero to enable} expected, got %s!)", - s, luaL_typename(L, s)); - return lua_error(L); - } - - bool underline; - if (lua_isboolean(L, ++s)) { - underline = lua_toboolean(L, s); - } else if (lua_isnumber(L, s)) { - underline = !qFuzzyCompare(1.0, 1.0 + lua_tonumber(L, s)); - } else { - lua_pushfstring(L, "setTextFormat: bad argument #%d type (underline format as boolean or number {true/non-zero to enable} expected, got %s!)", - s, luaL_typename(L, s)); - return lua_error(L); - } - - bool italics; - if (lua_isboolean(L, ++s)) { - italics = lua_toboolean(L, s); - } else if (lua_isnumber(L, s)) { - italics = !qFuzzyCompare(1.0, 1.0 + lua_tonumber(L, s)); - } else { - lua_pushfstring(L, "setTextFormat: bad argument #%d type (italic format as boolean or number {true/non-zero to enable} expected, got %s!)", - s, luaL_typename(L, s)); - return lua_error(L); - } - - bool strikeout = false; - if (s < n) { - // s has not been incremented yet so this means we still have another argument! + auto formatFlag = [&] (const char* name) { if (lua_isboolean(L, ++s)) { - strikeout = lua_toboolean(L, s); - } else if (lua_isnumber(L, s)) { - strikeout = !qFuzzyCompare(1.0, 1.0 + lua_tonumber(L, s)); - } else { - lua_pushfstring(L, "setTextFormat: bad argument #%d type (strikeout format as boolean or number {true/non-zero to enable} is optional, got %s!)", - s, luaL_typename(L, s)); - return lua_error(L); + // Surprisingly, the return type from lua_toboolean(...) is actually + // numeric: + return static_cast(lua_toboolean(L, s)); } - } - - bool overline = false; - if (s < n) { - // s has not been incremented yet so this means we still have another argument! - if (lua_isboolean(L, ++s)) { - overline = lua_toboolean(L, s); - } else if (lua_isnumber(L, s)) { - overline = !qFuzzyCompare(1.0, 1.0 + lua_tonumber(L, s)); - } else { - lua_pushfstring(L, "setTextFormat: bad argument #%d type (overline format as boolean or number {true/non-zero to enable} is optional, got %s!)", - s, luaL_typename(L, s)); - return lua_error(L); + if (lua_isnumber(L, s)) { + return !qFuzzyCompare(1.0, 1.0 + lua_tonumber(L, s)); } - } + lua_pushfstring(L, "setTextFormat: bad argument #%d type (%s format as boolean or number {true/non-zero to enable} expected, got %s!)", + s, name, luaL_typename(L, s)); + lua_error(L); + Q_UNREACHABLE(); + }; - bool reverse = false; - if (s < n) { - // s has not been incremented yet so this means we still have another argument! - if (lua_isboolean(L, ++s)) { - reverse = lua_toboolean(L, s); - } else if (lua_isnumber(L, s)) { - reverse = !qFuzzyCompare(1.0, 1.0 + lua_tonumber(L, s)); - } else { - lua_pushfstring(L, "setTextFormat: bad argument #%d type (reverse format as boolean or number {true/non-zero to enable} is optional, got %s!)", - s, luaL_typename(L, s)); - return lua_error(L); + auto optionalFormatFlag = [&] (const char* name) { + if (++s > n) { + // We do the pre-increment here so that it always gets done, even + // though we are past the end of the arguments so that we can still + // track where we are if debugging: + return false; } - } + if (lua_isboolean(L, s)) { + return static_cast(lua_toboolean(L, s)); + } + if (lua_isnumber(L, s)) { + return !qFuzzyCompare(1.0, 1.0 + lua_tonumber(L, s)); + } + lua_pushfstring(L, "setTextFormat: bad argument #%d type (%s format as boolean or number {true/non-zero to enable} is optional, got %s!)", + s, name, luaL_typename(L, s)); + lua_error(L); + Q_UNREACHABLE(); + }; + + bool bold = formatFlag("bold"); // Arg: 8 + bool underline = formatFlag("underline"); // Arg: 9 + bool italics = formatFlag("italic"); // Arg: 10 + bool strikeout = optionalFormatFlag("strikeout"); // Arg: 11 + bool overline = optionalFormatFlag("overline"); // Arg: 12 + bool reverse = optionalFormatFlag("reverse"); // Arg: 13 + bool faint = optionalFormatFlag("faint"); // Arg: 14 TChar::AttributeFlags const flags = (bold ? TChar::Bold : TChar::None) - | (italics ? TChar::Italic : TChar::None) - | (overline ? TChar::Overline : TChar::None) - | (reverse ? TChar::Reverse : TChar::None) - | (strikeout ? TChar::StrikeOut : TChar::None) - | (underline ? TChar::Underline : TChar::None); + | (faint ? TChar::Faint : TChar::None) + | (italics ? TChar::Italic : TChar::None) + | (overline ? TChar::Overline : TChar::None) + | (reverse ? TChar::Reverse : TChar::None) + | (strikeout ? TChar::StrikeOut : TChar::None) + | (underline ? TChar::Underline : TChar::None); if (!host.mpConsole->setTextFormat(windowName, - QColor(colorComponents.at(3), colorComponents.at(4), colorComponents.at(5)), - QColor(colorComponents.at(0), colorComponents.at(1), colorComponents.at(2)), - flags)) { + QColor(colorComponents.at(3), colorComponents.at(4), colorComponents.at(5)), + QColor(colorComponents.at(0), colorComponents.at(1), colorComponents.at(2)), + flags)) { return warnArgumentValue(L, __func__, qsl("window '%1' does not exist").arg(windowName), true); } diff --git a/src/TMainConsole.h b/src/TMainConsole.h index 0acf819a269..61cd24a5875 100644 --- a/src/TMainConsole.h +++ b/src/TMainConsole.h @@ -4,7 +4,7 @@ /*************************************************************************** * Copyright (C) 2008-2012 by Heiko Koehn - KoehnHeiko@googlemail.com * * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * - * Copyright (C) 2014-2016, 2018-2022 by Stephen Lyons * + * Copyright (C) 2014-2016, 2018-2022, 2023 by Stephen Lyons * * - slysven@virginmedia.com * * Copyright (C) 2016 by Ian Adkins - ieadkins@gmail.com * * * diff --git a/src/TTextEdit.cpp b/src/TTextEdit.cpp index 0bfb1c9ea52..e89f513be6a 100644 --- a/src/TTextEdit.cpp +++ b/src/TTextEdit.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * Copyright (C) 2008-2012 by Heiko Koehn - KoehnHeiko@googlemail.com * * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * - * Copyright (C) 2014-2016, 2018-2023 by Stephen Lyons * + * Copyright (C) 2014-2016, 2018-2024 by Stephen Lyons * * - slysven@virginmedia.com * * Copyright (C) 2016-2017 by Ian Adkins - ieadkins@gmail.com * * Copyright (C) 2017 by Chris Reid - WackyWormer@hotmail.com * @@ -701,8 +701,11 @@ int TTextEdit::drawGraphemeBackground(QPainter& painter, QVector& fgColo void TTextEdit::drawGraphemeForeground(QPainter& painter, const QColor& fgColor, const QRect& textRect, const QString& grapheme, TChar& charStyle) const { - TChar::AttributeFlags attributes = charStyle.allDisplayAttributes(); + const TChar::AttributeFlags attributes = charStyle.allDisplayAttributes(); const bool isBold = attributes & TChar::Bold; + const bool isFaint = attributes & TChar::Faint; + const QFont::Weight fontWeight = (isBold ? (isFaint ? TBuffer::csmFontWeight_boldAndFaint : TBuffer::csmFontWeight_bold) + : (isFaint ? TBuffer::csmFontWeight_faint : TBuffer::csmFontWeight_normal)); // At present we cannot display flashing text - and we just make it italic // (we ought to eventually add knobs for them so they can be shown in a user // preferred style - which might be static for some users) - anyhow Mudlet @@ -713,14 +716,14 @@ void TTextEdit::drawGraphemeForeground(QPainter& painter, const QColor& fgColor, const bool isUnderline = attributes & TChar::Underline; // const bool isConcealed = attributes & TChar::Concealed; // const int altFontIndex = charStyle.alternateFont(); - if ((painter.font().bold() != isBold) + if ((painter.font().weight() != fontWeight) || (painter.font().italic() != isItalics) || (painter.font().overline() != isOverline) || (painter.font().strikeOut() != isStrikeOut) || (painter.font().underline() != isUnderline)) { QFont font = painter.font(); - font.setBold(isBold); + font.setWeight(fontWeight); font.setItalic(isItalics); font.setOverline(isOverline); font.setStrikeOut(isStrikeOut); diff --git a/src/XMLexport.cpp b/src/XMLexport.cpp index db7e42a3296..bd3a1f76d70 100644 --- a/src/XMLexport.cpp +++ b/src/XMLexport.cpp @@ -2,7 +2,7 @@ * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * * Copyright (C) 2016-2017 by Ian Adkins - ieadkins@gmail.com * - * Copyright (C) 2017-2023 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2017-2024 by Stephen Lyons - slysven@virginmedia.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -487,6 +487,8 @@ void XMLexport::writeHost(Host* pHost, pugi::xml_node mudletPackage) host.append_attribute("Large2DMapAreaExitArrows") = "yes"; } + host.append_attribute("BoldIsBright") = pHost->mBoldIsBright ? "yes" : "no"; + { // Blocked so that indentation reflects that of the XML file host.append_child("name").text().set(pHost->mHostName.toUtf8().constData()); diff --git a/src/XMLimport.cpp b/src/XMLimport.cpp index 238c3dcdb58..2bce2628f49 100644 --- a/src/XMLimport.cpp +++ b/src/XMLimport.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * Copyright (C) 2008-2013 by Heiko Koehn - KoehnHeiko@googlemail.com * * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * - * Copyright (C) 2016-2023 by Stephen Lyons - slysven@virginmedia.com * + * Copyright (C) 2016-2024 by Stephen Lyons - slysven@virginmedia.com * * Copyright (C) 2016-2017 by Ian Adkins - ieadkins@gmail.com * * * * This program is free software; you can redistribute it and/or modify * @@ -985,6 +985,13 @@ void XMLimport::readHost(Host* pHost) pHost->setLargeAreaExitArrows(false); } + if (attributes().hasAttribute(qsl("BoldIsBright"))) { + pHost->mBoldIsBright = (attributes().value(qsl("BoldIsBright")) == YES); + } else { + // The default, backwards compatible, option is true, though false would be "better": + pHost->mBoldIsBright = true; + } + if (attributes().value(qsl("mShowInfo")) == qsl("no")) { mpHost->mMapInfoContributors.clear(); } diff --git a/src/dlgProfilePreferences.cpp b/src/dlgProfilePreferences.cpp index 3c4150b19bb..8077446b388 100644 --- a/src/dlgProfilePreferences.cpp +++ b/src/dlgProfilePreferences.cpp @@ -1,7 +1,7 @@ /*************************************************************************** * Copyright (C) 2008-2012 by Heiko Koehn - KoehnHeiko@googlemail.com * * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * - * Copyright (C) 2014, 2016-2018, 2020-2023 by Stephen Lyons * + * Copyright (C) 2014, 2016-2018, 2020-2024 by Stephen Lyons * * - slysven@virginmedia.com * * Copyright (C) 2016 by Ian Adkins - ieadkins@gmail.com * * * @@ -794,7 +794,6 @@ void dlgProfilePreferences::initWithHost(Host* pHost) // has a font size larger than the preset range offers? fontSize->setCurrentIndex(9); // default font is size 10, index 9. } - wrap_at_spinBox->setValue(pHost->mWrapAt); indent_wrapped_spinBox->setValue(pHost->mWrapIndentCount); @@ -897,7 +896,7 @@ void dlgProfilePreferences::initWithHost(Host* pHost) commandLineMinimumHeight->setValue(pHost->commandLineMinimumHeight); - mNoAntiAlias->setChecked(!pHost->mNoAntiAlias); + checkBox_antiAlias->setChecked(!pHost->mNoAntiAlias); mFORCE_MCCP_OFF->setChecked(pHost->mFORCE_NO_COMPRESSION); mFORCE_GA_OFF->setChecked(pHost->mFORCE_GA_OFF); mAlertOnNewData->setChecked(pHost->mAlertOnNewData); @@ -1165,6 +1164,8 @@ void dlgProfilePreferences::initWithHost(Host* pHost) checkBox_largeAreaExitArrows->setChecked(pHost->getLargeAreaExitArrows()); comboBox_blankLinesBehaviour->setCurrentIndex(static_cast(pHost->mBlankLineBehaviour)); + checkBox_boldIsBright->setChecked(pHost->mBoldIsBright); + // Enable the controls that would be disabled if there wasn't a Host instance // on tab_general: // groupBox_iconsAndToolbars is NOT dependent on pHost - leave it alone @@ -1435,7 +1436,7 @@ void dlgProfilePreferences::clearHostDetails() mIsToLogInHtml->setChecked(false); mIsLoggingTimestamps->setChecked(false); commandLineMinimumHeight->clear(); - mNoAntiAlias->setChecked(false); + checkBox_antiAlias->setChecked(false); mFORCE_MCCP_OFF->setChecked(false); mFORCE_GA_OFF->setChecked(false); mAlertOnNewData->setChecked(false); @@ -1878,6 +1879,7 @@ void dlgProfilePreferences::slot_setDisplayFont() } QFont newFont = fontComboBox->currentFont(); newFont.setPointSize(mFontSize); + newFont.setWeight(TBuffer::csmFontWeight_normal); if (pHost->getDisplayFont() == newFont) { return; @@ -1888,14 +1890,16 @@ void dlgProfilePreferences::slot_setDisplayFont() if (auto [validFont, errorMessage] = pHost->setDisplayFont(newFont); !validFont) { label_invalidFontError->show(); return; - } else if (!QFontInfo(newFont).fixedPitch()) { + } + + if (!QFontInfo(newFont).fixedPitch()) { label_variableWidthFontWarning->show(); } #if defined(Q_OS_LINUX) // On Linux ensure that emojis are displayed in colour even if this font // doesn't support it: - QFont::insertSubstitution(pHost->mDisplayFont.family(), qsl("Noto Color Emoji")); + QFont::insertSubstitution(newFont.family(), qsl("Noto Color Emoji")); #endif auto mainConsole = pHost->mpConsole; @@ -2884,7 +2888,7 @@ void dlgProfilePreferences::slot_saveAndClose() pHost->mLogDir = mLogDirPath; pHost->mLogFileName = lineEdit_logFileName->text(); pHost->mLogFileNameFormat = comboBox_logFileNameFormat->currentData().toString(); - pHost->mNoAntiAlias = !mNoAntiAlias->isChecked(); + pHost->mNoAntiAlias = !checkBox_antiAlias->isChecked(); pHost->mAlertOnNewData = mAlertOnNewData->isChecked(); pHost->mUseProxy = groupBox_proxy->isChecked(); @@ -3077,6 +3081,7 @@ void dlgProfilePreferences::slot_saveAndClose() pHost->setHaveColorSpaceId(checkBox_expectCSpaceIdInColonLessMColorCode->isChecked()); pHost->setMayRedefineColors(checkBox_allowServerToRedefineColors->isChecked()); + pHost->mBoldIsBright = checkBox_boldIsBright->isChecked(); pHost->setDebugShowAllProblemCodepoints(checkBox_debugShowAllCodepointProblems->isChecked()); pHost->mCaretShortcut = static_cast(comboBox_caretModeKey->currentIndex()); diff --git a/src/dlgProfilePreferences.h b/src/dlgProfilePreferences.h index b4b952bd7d2..a3889374dfc 100644 --- a/src/dlgProfilePreferences.h +++ b/src/dlgProfilePreferences.h @@ -4,7 +4,7 @@ /*************************************************************************** * Copyright (C) 2008-2012 by Heiko Koehn - KoehnHeiko@googlemail.com * * Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com * - * Copyright (C) 2017-2018, 2022 by Stephen Lyons * + * Copyright (C) 2017-2018, 2022-2023 by Stephen Lyons * * - slysven@virginmedia.com * * * * This program is free software; you can redistribute it and/or modify * diff --git a/src/mudlet-lua/lua/Other.lua b/src/mudlet-lua/lua/Other.lua index 1e9c3d74d51..211f81df867 100644 --- a/src/mudlet-lua/lua/Other.lua +++ b/src/mudlet-lua/lua/Other.lua @@ -1236,6 +1236,7 @@ function getConfig(...) "askTlsAvailable", "autoClearInputLine", "blankLinesBehaviour", + "boldIsBright", "caretShortcut", "commandLineHistorySaveSize", "compactInputLine", diff --git a/src/ui/profile_preferences.ui b/src/ui/profile_preferences.ui index 8f0a3707bae..85db215c68b 100644 --- a/src/ui/profile_preferences.ui +++ b/src/ui/profile_preferences.ui @@ -756,12 +756,15 @@ Font - + Font: + + fontComboBox + @@ -785,12 +788,25 @@ Size: + + fontSize + - + + + + <p>Anti-aliasing use on the font for the <b>Main</b> console. Smoothes fonts if you have a high screen resolution and you can use larger fonts. Note that on low resolutions and small font sizes, the font gets blurry. </p> + + + Enable anti-aliasing + + + + @@ -802,7 +818,7 @@ - + @@ -815,16 +831,6 @@ you can use it but there could be issues with aligning columns of text - - - - Use anti aliasing on fonts. Smoothes fonts if you have a high screen resolution and you can use larger fonts. Note that on low resolutions and small font sizes, the font gets blurry. - - - Enable anti-aliasing - - - @@ -1916,6 +1922,16 @@ you can use it but there could be issues with aligning columns of text + + + + <p>Server uses BOLD to make Light 8 colors (only for some 16 Color MUDs)</p><p>Some older Game Servers support eight different colors which are selected by using the original eight "Set Graphic Rendition" <tt> &lt;SGR&gt; 30</tt> (black) to <tt>37</tt> (white)</tt> ANSI ESC color codes and combine those with the <tt>&lt;SGR&gt; 1</tt> (bold or more intense) code to provide a second set of eight colors for sixteen in total. This checkbox causes this use of the <tt>&lt;SGR&gt; 1</tt> code however it should not be used if the Game Server:<ul><li>only uses eight colors</li><li>uses more than sixteen colors</li><li>uses sixteen colors but selects the "brighter" eight colors with <tt>&lt;SGR&gt; 90</tt> (light black) to <tt>&lt;SGR&gt; 97</tt> (light white) {and <tt>100</tt> to <tt>107</tt> for the same as a background} of the sixteeen</li></ul></p><p><i>Older versions of Mudlet had code that effectively had this option permanently enabled. However nowadays it interferes with using the BOLD attribute to provide <b>bold</b> text alongside the less often used FAINT attribute to provide <span style=" font-weight: 200">faint</span> and <span style=" font-weight: 600">demi-bold</span> text effects.</p> + + + BOLD is Bright + + + @@ -4201,8 +4217,8 @@ you can use it but there could be issues with aligning columns of text radioButton_userDictionary_profile radioButton_userDictionary_common fontComboBox - mNoAntiAlias fontSize + checkBox_antiAlias topBorderHeight bottomBorderHeight leftBorderWidth @@ -4238,6 +4254,7 @@ you can use it but there could be issues with aligning columns of text pushButton_cyan pushButton_white checkBox_allowServerToRedefineColors + checkBox_boldIsBright pushButton_lBlack pushButton_lRed pushButton_lGreen From 6d7c931e3a2f965ac3af325a2e7a91ab18ac08ed Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 9 May 2024 13:47:50 -0500 Subject: [PATCH 5/8] Add: Steam Launch Support (#7219) #### Brief overview of PR changes/additions Add and modify some QSettings based on if we're launching from Steam. #### Motivation for adding to Mudlet Attempting to meet Steam's requirements to bring Mudlet to Steam. #### Other info (issues closed, discussion etc) N/A --------- Co-authored-by: Stephen Lyons --- src/dlgAboutDialog.cpp | 25 ++++++++++++++++++------- src/main.cpp | 10 +++++++--- src/mudlet.h | 2 ++ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/dlgAboutDialog.cpp b/src/dlgAboutDialog.cpp index f716692c806..0e9fff80cdb 100644 --- a/src/dlgAboutDialog.cpp +++ b/src/dlgAboutDialog.cpp @@ -1077,13 +1077,24 @@ void dlgAboutDialog::setSupportersTab(const QString& htmlHead) // clang-format on } - QString supporters_text(qsl(R"( -


%1

- %2 - )") - .arg(tr(R"( - These formidable folks will be fondly remembered forever
for their generous financial support on Mudlet's patreon: - )"), supporters_image_html)); + QString supporters_text; + if (mudlet::smSteamMode) { + supporters_text = qsl(R"( +


%1

+ %2 + )") + .arg(tr(R"( + These formidable folks will be fondly remembered forever
for their generous financial support on Mudlet's patreon: + )"), supporters_image_html); + } else { + supporters_text = qsl(R"( +


%1

+ %2 + )") + .arg(tr(R"( + These formidable folks will be fondly remembered forever
for their generous financial support on Mudlet's patreon: + )"), supporters_image_html); + } supportersDocument->setHtml(qsl("%1%2").arg(htmlHead, supporters_text)); textBrowser_supporters->setDocument(supportersDocument.get()); diff --git a/src/main.cpp b/src/main.cpp index d1933a9b486..40c0c42382a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -277,6 +277,9 @@ int main(int argc, char* argv[]) qsl("predefined_game")); parser.addOption(onlyPredefinedProfileToShow); + const QCommandLineOption steamMode(QStringList() << qsl("steammode"), qsl("Adjusts Mudlet settings to match Steam's requirements.")); + parser.addOption(steamMode); + parser.addPositionalArgument("package", "Path to .mpackage file"); const bool parsedCommandLineOk = parser.parse(app->arguments()); @@ -311,6 +314,8 @@ int main(int argc, char* argv[]) " repeated.")); texts << appendLF.arg(QCoreApplication::translate("main", " -o, --only= make Mudlet only show the specific\n" " predefined game, may be repeated.")); + texts << appendLF.arg(QCoreApplication::translate("main", " --steammode adjusts Mudlet settings to match\n" + " Steam's requirements.")); texts << appendLF.arg(QCoreApplication::translate("main", "There are other inherited options that arise from the Qt Libraries which are\n" "less likely to be useful for normal use of this application:")); // From documentation and from http://qt-project.org/doc/qt-5/qapplication.html: @@ -382,8 +387,6 @@ int main(int argc, char* argv[]) return 0; } - - // Handles installing a package from a command line argument. // Used when mudlet is used to open an .mpackage file on some operating systems. // @@ -425,7 +428,7 @@ int main(int argc, char* argv[]) const QStringList cliProfiles = parser.values(profileToOpen); const QStringList onlyProfiles = parser.values(onlyPredefinedProfileToShow); - + const bool showSplash = parser.isSet(showSplashscreen); QImage splashImage = mudlet::getSplashScreen(releaseVersion, publicTestVersion); @@ -651,6 +654,7 @@ int main(int argc, char* argv[]) } mudlet::self()->smMirrorToStdOut = parser.isSet(mirrorToStdout); + mudlet::smSteamMode = parser.isSet(steamMode); if (!onlyProfiles.isEmpty()) { mudlet::self()->onlyShowProfiles(onlyProfiles); } diff --git a/src/mudlet.h b/src/mudlet.h index 065c316310f..eb0b16bcb87 100644 --- a/src/mudlet.h +++ b/src/mudlet.h @@ -301,6 +301,8 @@ class mudlet : public QMainWindow, public Ui::main_window inline static QPointer smpDebugArea; // mirror everything shown in any console to stdout. Helpful for CI environments inline static bool smMirrorToStdOut = false; + // adjust Mudlet settings to match Steam's requirements + inline static bool smSteamMode = false; void showEvent(QShowEvent*) override; From ee14effd0f4cc537b25e148008c41ca0545a239e Mon Sep 17 00:00:00 2001 From: Stephen Lyons Date: Sun, 12 May 2024 18:33:47 +0100 Subject: [PATCH 6/8] Infra: Repair name of Linux PTB version (#7221) #### Brief overview of PR changes/additions I made an error in #7160 as I thought that something that looked like a function call returned a value that could be assigned to something with a `set(...)` but CMake doesn't work like that, instead one has to provide a variable to recieve the value as the last argument to a `string(...)` function. :roll_eyes: #### Motivation for adding to Mudlet Fix an error that causes cruft to appear, at least, in the version number on the first tab of the "About Mudlet" dialogue. #### Other info (issues closed, discussion etc) This should close #7220. Signed-off-by: Stephen Lyons --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68a849908ba..69c2c7bb5b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ execute_process( # If a CI/CB build system provides an alternative Git SHA1 to identify the build # use that instead - reporting which is being used: if(DEFINED ENV{BUILD_COMMIT} AND NOT $ENV{BUILD_COMMIT} STREQUAL "") - set(GIT_SHA1 string(TOLOWER $ENV{BUILD_COMMIT})) + string(TOLOWER $ENV{BUILD_COMMIT} GIT_SHA1) message(STATUS "Git SHA1 set from environemnt: ${GIT_SHA1}") else() message(STATUS "Git SHA1 used: ${GIT_SHA1}") From 22d2662f92ce00476c4a2cf3f125628c1b1d3a35 Mon Sep 17 00:00:00 2001 From: Greg Date: Tue, 14 May 2024 03:19:12 -0500 Subject: [PATCH 7/8] Fix: Update CFGUI Source (#7222) #### Brief overview of PR changes/additions Needed to update the CFGUI loader source to pull from organization's repository #### Motivation for adding to Mudlet To correct existing game-specific feature so it would keep receiving future updates #### Other info (issues closed, discussion etc) --- src/CF-loader.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CF-loader.xml b/src/CF-loader.xml index 61e1b83373e..e1016878b89 100644 --- a/src/CF-loader.xml +++ b/src/CF-loader.xml @@ -16,7 +16,7 @@