From c7e02ed876b579aff6cb16cf94018f613f3d0235 Mon Sep 17 00:00:00 2001 From: Christoph Cullmann Date: Thu, 27 Feb 2025 20:42:03 +0100 Subject: [PATCH] port to QStringDecoder/Encoder --- CMakeLists.txt | 1 - src/CMakeLists.txt | 2 -- src/Emulation.cpp | 44 +++++++++++++++++++------------ src/Emulation.h | 30 ++++++++++++++------- src/Vt102Emulation.cpp | 6 ++--- src/profile/Profile.cpp | 6 ++--- src/session/Session.cpp | 25 +++++------------- src/session/Session.h | 7 ++--- src/session/SessionController.cpp | 14 +++++----- src/session/SessionController.h | 4 +-- src/session/SessionManager.cpp | 4 +-- src/widgets/EditProfileDialog.cpp | 9 +++---- src/widgets/EditProfileDialog.h | 2 +- 13 files changed, 75 insertions(+), 79 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0fdd263df..343854ad4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,6 @@ find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED Multimedia PrintSupport Widgets - Core5Compat ) find_package(KF6 ${KF6_DEP_VERSION} REQUIRED diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 455563e5f..c8706b4c1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -296,8 +296,6 @@ target_link_libraries(konsoleprivate ) target_link_libraries(konsoleprivate - PUBLIC - Qt6::Core5Compat PRIVATE KF6::IconWidgets KF6::BookmarksWidgets diff --git a/src/Emulation.cpp b/src/Emulation.cpp index a0b4d6c45..6227210d4 100644 --- a/src/Emulation.cpp +++ b/src/Emulation.cpp @@ -148,29 +148,38 @@ const HistoryType &Emulation::history() const return _screen[0]->getScroll(); } -void Emulation::setCodec(const QTextCodec *codec) +bool Emulation::setCodec(QAnyStringView name) { - if (codec != nullptr) { - _codec = codec; - - _decoder.reset(_codec->makeDecoder()); - - Q_EMIT useUtf8Request(utf8()); - } else { -#if defined(Q_OS_WIN) - setCodec(Utf8Codec); -#else - setCodec(LocaleCodec); -#endif + // if we requested a specific codec, only try that one + if (!name.isEmpty()) { + QStringDecoder decoder(name); + QStringEncoder encoder(name); + if (decoder.isValid() && encoder.isValid()) { + _decoder = std::move(decoder); + _encoder = std::move(encoder); + Q_EMIT useUtf8Request(utf8()); + return true; + } + return false; } + + // try with a fallback if no name given +#if defined(Q_OS_WIN) + setCodec(Utf8Codec); +#else + setCodec(LocaleCodec); +#endif + + // fallback always works + return true; } void Emulation::setCodec(EmulationCodec codec) { if (codec == Utf8Codec) { - setCodec(QTextCodec::codecForName("utf8")); + setCodec(QStringConverter::nameForEncoding(QStringConverter::Utf8)); } else if (codec == LocaleCodec) { - setCodec(QTextCodec::codecForLocale()); + setCodec(QStringConverter::nameForEncoding(QStringConverter::System)); } } @@ -228,12 +237,13 @@ void Emulation::sendKeyEvent(QKeyEvent *ev) void Emulation::receiveData(const char *text, int length) { - Q_ASSERT(_decoder); + Q_ASSERT(_decoder.isValid()); bufferedUpdate(); // send characters to terminal emulator - const QVector chars = _decoder->toUnicode(text, length).toUcs4(); + const QString readString = _decoder.decode(QByteArrayView(text, length)); + const QVector chars = readString.toUcs4(); receiveChars(chars); // look for z-modem indicator diff --git a/src/Emulation.h b/src/Emulation.h index 32ddd3949..515a49870 100644 --- a/src/Emulation.h +++ b/src/Emulation.h @@ -10,7 +10,8 @@ // Qt #include -#include +#include +#include #include // Konsole @@ -135,14 +136,20 @@ public: */ virtual void writeToStream(TerminalCharacterDecoder *decoder, int startLine, int endLine); - /** Returns the codec used to decode incoming characters. See setCodec() */ - const QTextCodec *codec() const + /** Returns the decoder used to decode incoming characters. See setCodec() */ + const QStringDecoder &decoder() const { - return _codec; + return _decoder; + } + + /** Returns the encoder used to encode characters send to the terminal. See setCodec() */ + const QStringEncoder &encoder() const + { + return _encoder; } /** Sets the codec used to decode incoming characters. */ - void setCodec(const QTextCodec *); + bool setCodec(QAnyStringView name); /** * Convenience method. @@ -151,8 +158,8 @@ public: */ bool utf8() const { - Q_ASSERT(_codec); - return _codec->mibEnum() == 106; + Q_ASSERT(_decoder.isValid()); + return QStringConverter::encodingForName(_decoder.name()) == QStringConverter::Utf8; } /** Returns the special character used for erasing character. */ @@ -453,9 +460,12 @@ protected: // scrollbars are not enabled in this mode ) // decodes an incoming C-style character stream into a unicode QString using - // the current text codec. (this allows for rendering of non-ASCII characters in text files etc.) - const QTextCodec *_codec = nullptr; - std::unique_ptr _decoder; + QStringDecoder _decoder; + + // the current text encoder to send unicode to the terminal + // (this allows for rendering of non-ASCII characters in text files etc.) + QStringEncoder _encoder; + const KeyboardTranslator *_keyTranslator = nullptr; // the keyboard layout protected Q_SLOTS: diff --git a/src/Vt102Emulation.cpp b/src/Vt102Emulation.cpp index ef647f859..baf7bc4f8 100644 --- a/src/Vt102Emulation.cpp +++ b/src/Vt102Emulation.cpp @@ -112,7 +112,7 @@ void Vt102Emulation::reset(bool softReset, bool preservePrompt) // Save the current codec so we can set it later. // Ideally we would want to use the profile setting - const QTextCodec *currentCodec = codec(); + const QByteArray currentCodec(encoder().name()); resetTokenizer(); if (softReset) { @@ -2802,8 +2802,8 @@ void Vt102Emulation::sendKeyEvent(QKeyEvent *event) } else if (!entry.text().isEmpty()) { textToSend += entry.text(true, modifiers); } else { - Q_ASSERT(_codec); - textToSend += _codec->fromUnicode(event->text()); + Q_ASSERT(_encoder.isValid()); + textToSend += _encoder.encode(event->text()); } } diff --git a/src/profile/Profile.cpp b/src/profile/Profile.cpp index 2dce92165..ecafc65a6 100644 --- a/src/profile/Profile.cpp +++ b/src/profile/Profile.cpp @@ -13,7 +13,7 @@ // Qt #include #include -#include +#include // KDE #include @@ -274,9 +274,9 @@ void Profile::useBuiltin() setProperty(Arguments, QStringList{defaultShell()}); setProperty(Font, QFontDatabase::systemFont(QFontDatabase::FixedFont)); #if defined(Q_OS_WIN) - setProperty(DefaultEncoding, QLatin1String(QTextCodec::codecForName("utf8")->name())); + setProperty(DefaultEncoding, QString::fromUtf8(QStringConverter::nameForEncoding(QStringConverter::Utf8))); #else - setProperty(DefaultEncoding, QLatin1String(QTextCodec::codecForLocale()->name())); + setProperty(DefaultEncoding, QString::fromUtf8(QStringConverter::nameForEncoding(QStringConverter::System))); #endif // Built-in profile should not be shown in menus setHidden(true); diff --git a/src/session/Session.cpp b/src/session/Session.cpp index f6b41373c..25eefca31 100644 --- a/src/session/Session.cpp +++ b/src/session/Session.cpp @@ -236,32 +236,19 @@ bool Session::hasFocus() const }); } -void Session::setCodec(QTextCodec *codec) +bool Session::setCodec(QAnyStringView name) { - if (isReadOnly()) { - return; - } - - emulation()->setCodec(codec); - - Q_EMIT sessionCodecChanged(codec); -} - -bool Session::setCodec(const QByteArray &name) -{ - QTextCodec *codec = QTextCodec::codecForName(name); - - if (codec != nullptr) { - setCodec(codec); - return true; - } else { + if (isReadOnly() || !emulation()->setCodec(name)) { return false; } + + Q_EMIT sessionCodecChanged(codec()); + return true; } QByteArray Session::codec() { - return _emulation->codec()->name(); + return _emulation->encoder().name(); } void Session::setProgram(const QString &program) diff --git a/src/session/Session.h b/src/session/Session.h index 70d23b16d..754d85e66 100644 --- a/src/session/Session.h +++ b/src/session/Session.h @@ -393,9 +393,6 @@ public: ProfileChange = 50, // this clashes with Xterm's font change command }; - // Sets the text codec used by this sessions terminal emulation. - void setCodec(QTextCodec *codec); - // session management void saveSession(KConfigGroup &group); void restoreSession(KConfigGroup &group); @@ -594,7 +591,7 @@ public Q_SLOTS: * Overloaded to accept a QByteArray for convenience since DBus * does not accept QTextCodec directly. */ - Q_SCRIPTABLE bool setCodec(const QByteArray &name); + Q_SCRIPTABLE bool setCodec(QAnyStringView name); /** Returns the codec used to decode incoming characters in this * terminal emulation @@ -755,7 +752,7 @@ Q_SIGNALS: /** * Emitted when the session text encoding changes. */ - void sessionCodecChanged(QTextCodec *codec); + void sessionCodecChanged(const QByteArray &codec); /** Emitted when a bell event occurs in the session. */ void bellRequest(const QString &message); diff --git a/src/session/SessionController.cpp b/src/session/SessionController.cpp index 09c8201af..30d210608 100644 --- a/src/session/SessionController.cpp +++ b/src/session/SessionController.cpp @@ -814,14 +814,12 @@ void SessionController::setupCommonActions() connect(session(), &Konsole::Session::sessionCodecChanged, this, &Konsole::SessionController::updateCodecAction); connect(_codecAction, &KCodecAction::codecNameTriggered, this, [this](const QByteArray &codecName) { - changeCodec(QTextCodec::codecForName(codecName)); + changeCodec(codecName); }); connect(_codecAction, &KCodecAction::defaultItemTriggered, this, [this] { Profile::Ptr profile = SessionManager::instance()->sessionProfile(session()); - QByteArray name = profile->defaultEncoding().toUtf8(); - - changeCodec(QTextCodec::codecForName(name)); + changeCodec(profile->defaultEncoding().toUtf8()); }); // Mouse tracking enabled @@ -1012,12 +1010,12 @@ void SessionController::prepareSwitchProfileMenu() _switchProfileMenu->menu()->clear(); _switchProfileMenu->menu()->addActions(_profileList->actions()); } -void SessionController::updateCodecAction(QTextCodec *codec) +void SessionController::updateCodecAction(const QByteArray &codec) { - _codecAction->setCurrentCodec(QString::fromUtf8(codec->name())); + _codecAction->setCurrentCodec(QString::fromUtf8(codec)); } -void SessionController::changeCodec(QTextCodec *codec) +void SessionController::changeCodec(const QByteArray &codec) { session()->setCodec(codec); } @@ -1861,7 +1859,7 @@ void SessionController::clearHistoryAndReset() Emulation *emulation = session()->emulation(); emulation->reset(false, true); session()->refresh(); - session()->setCodec(QTextCodec::codecForName(name)); + session()->setCodec(name); clearHistory(); } diff --git a/src/session/SessionController.h b/src/session/SessionController.h index 9689d5084..1eb27bf02 100644 --- a/src/session/SessionController.h +++ b/src/session/SessionController.h @@ -269,7 +269,7 @@ private Q_SLOTS: void editCurrentProfile(); void nextProfile(); void prevProfile(); - void changeCodec(QTextCodec *codec); + void changeCodec(const QByteArray &codec); void enableSearchBar(bool showSearchBar); void searchHistory(bool showSearchBar); void searchBarEvent(); @@ -305,7 +305,7 @@ private Q_SLOTS: // other void setupSearchBar(); void prepareSwitchProfileMenu(); - void updateCodecAction(QTextCodec *codec); + void updateCodecAction(const QByteArray &codec); void showDisplayContextMenu(const QPoint &position); void movementKeyFromSearchBarReceived(QKeyEvent *event); void sessionNotificationsChanged(Session::Notification notification, bool enabled); diff --git a/src/session/SessionManager.cpp b/src/session/SessionManager.cpp index 25522e995..df7836a2c 100644 --- a/src/session/SessionManager.cpp +++ b/src/session/SessionManager.cpp @@ -11,7 +11,6 @@ // Qt #include -#include // KDE #include @@ -266,8 +265,7 @@ void SessionManager::applyProfile(Session *session, const Profile::Ptr &profile, // Encoding if (apply.shouldApply(Profile::DefaultEncoding)) { - QByteArray name = profile->defaultEncoding().toUtf8(); - session->setCodec(QTextCodec::codecForName(name)); + session->setCodec(profile->defaultEncoding()); } // Monitor Silence diff --git a/src/widgets/EditProfileDialog.cpp b/src/widgets/EditProfileDialog.cpp index 975fc5b59..09825cd28 100644 --- a/src/widgets/EditProfileDialog.cpp +++ b/src/widgets/EditProfileDialog.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -2014,11 +2013,11 @@ void EditProfileDialog::setupAdvancedPage(const Profile::Ptr &profile) _advancedUi->selectEncodingButton->setMenu(codecAction->menu()); connect(codecAction, &KCodecAction::codecNameTriggered, this, [this](const QByteArray &codecName) { - setDefaultCodec(QTextCodec::codecForName(codecName)); + setDefaultCodec(codecName); }); connect(codecAction, &KCodecAction::defaultItemTriggered, this, [this] { - setDefaultCodec(QTextCodec::codecForLocale()); + setDefaultCodec(QStringConverter::nameForEncoding(QStringConverter::System)); }); _advancedUi->selectEncodingButton->setText(profile->defaultEncoding()); @@ -2069,9 +2068,9 @@ int EditProfileDialog::maxSpinBoxWidth(const KPluralHandlingSpinBox *spinBox, co return spinBoxSize.width(); } -void EditProfileDialog::setDefaultCodec(QTextCodec *codec) +void EditProfileDialog::setDefaultCodec(const QByteArray &codec) { - QString name = QString::fromLocal8Bit(codec->name()); + QString name = QString::fromLocal8Bit(codec); updateTempProfileProperty(Profile::DefaultEncoding, name); _advancedUi->selectEncodingButton->setText(name); diff --git a/src/widgets/EditProfileDialog.h b/src/widgets/EditProfileDialog.h index 52dc1e18c..59614cc0c 100644 --- a/src/widgets/EditProfileDialog.h +++ b/src/widgets/EditProfileDialog.h @@ -225,7 +225,7 @@ private Q_SLOTS: void toggleReverseUrlHints(bool); void setAutoSaveInterval(int); - void setDefaultCodec(QTextCodec *); + void setDefaultCodec(const QByteArray &codec); void setTextEditorCombo(const Profile::Ptr &profile);