diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d8180b..82aa6fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ============ +## 0.0.92 + +- Implemented: +- Encoding Menu -> Interpret as ... IBM-775, IBM-500, IBM-437, IBM-424, IBM-420 + ## 0.0.91 - Implemented: diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c91953..cf84e5a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -229,6 +229,16 @@ set(PROJECT_SOURCES src/encoding/interpret_as_ibm_852.h src/encoding/interpret_as_ibm_850.cpp src/encoding/interpret_as_ibm_850.h + src/encoding/interpret_as_ibm_775.cpp + src/encoding/interpret_as_ibm_775.h + src/encoding/interpret_as_ibm_500.cpp + src/encoding/interpret_as_ibm_500.h + src/encoding/interpret_as_ibm_437.cpp + src/encoding/interpret_as_ibm_437.h + src/encoding/interpret_as_ibm_424.cpp + src/encoding/interpret_as_ibm_424.h + src/encoding/interpret_as_ibm_420.cpp + src/encoding/interpret_as_ibm_420.h ${PROJECT_UI} ) diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index 2f77570..fe6fd12 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -103,13 +103,13 @@ 2 false - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake + -DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} -DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} -DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} /data/Code/Qt/Notepad-- 0 diff --git a/src/encoding/interpret_as_dialog.cpp b/src/encoding/interpret_as_dialog.cpp index 3599aaa..9c7339b 100644 --- a/src/encoding/interpret_as_dialog.cpp +++ b/src/encoding/interpret_as_dialog.cpp @@ -60,7 +60,12 @@ InterpreteAsDialog::InterpreteAsDialog(QWidget* parent) "IBM-857", "IBM-855", "IBM-852", - "IBM-850" + "IBM-850", + "IBM-775", + "IBM-500", + "IBM-437", + "IBM-424", + "IBM-420" }); // Create OK and Cancel buttons using QDialogButtonBox diff --git a/src/encoding/interpret_as_ibm_420.cpp b/src/encoding/interpret_as_ibm_420.cpp new file mode 100644 index 0000000..896d1e8 --- /dev/null +++ b/src/encoding/interpret_as_ibm_420.cpp @@ -0,0 +1,92 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_420.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_420& Interpret_As_IBM_420::instance() { + static Interpret_As_IBM_420 instance; + return instance; +} + +// EBCDIC to Unicode mapping for IBM-420 (Arabic EBCDIC) +const std::unordered_map Interpret_As_IBM_420::ebcdicTable = { + {0x80, QChar(0x0627)}, // ا (Alef) + {0x81, QChar(0x0628)}, // ب (Beh) + {0x82, QChar(0x062A)}, // ت (Teh) + {0x83, QChar(0x062B)}, // ث (Theh) + {0x84, QChar(0x062C)}, // ج (Jeem) + {0x85, QChar(0x062D)}, // ح (Hah) + {0x86, QChar(0x062E)}, // خ (Khah) + {0x87, QChar(0x062F)}, // د (Dal) + {0x88, QChar(0x0630)}, // ذ (Thal) + {0x89, QChar(0x0631)}, // ر (Reh) + {0x8A, QChar(0x0632)}, // ز (Zain) + {0x8B, QChar(0x0633)}, // س (Seen) + {0x8C, QChar(0x0634)}, // ش (Sheen) + {0x8D, QChar(0x0635)}, // ص (Sad) + {0x8E, QChar(0x0636)}, // ض (Dad) + {0x8F, QChar(0x0637)}, // ط (Tah) + {0x90, QChar(0x0638)}, // ظ (Zah) + {0x91, QChar(0x0639)}, // ع (Ain) + {0x92, QChar(0x063A)}, // غ (Ghain) + {0x93, QChar(0x0641)}, // ف (Feh) + {0x94, QChar(0x0642)}, // ق (Qaf) + {0x95, QChar(0x0643)}, // ك (Kaf) + {0x96, QChar(0x0644)}, // ل (Lam) + {0x97, QChar(0x0645)}, // م (Meem) + {0x98, QChar(0x0646)}, // ن (Noon) + {0x99, QChar(0x0647)}, // ه (Heh) + {0x9A, QChar(0x0648)}, // و (Waw) + {0x9B, QChar(0x064A)}, // ي (Yeh) +}; + +// Constructor +Interpret_As_IBM_420::Interpret_As_IBM_420() {} + +// Main execution function +void Interpret_As_IBM_420::execute(QPlainTextEdit* editor) { + if (!editor) { + qWarning() << "[ERROR] No editor instance provided."; + return; + } + + CodeEditor* codeEditor = qobject_cast(editor); + if (!codeEditor) { + qWarning() << "[ERROR] Invalid CodeEditor instance."; + return; + } + + QString filePath = codeEditor->filePath(); + if (filePath.isEmpty()) { + qWarning() << "[ERROR] No file path associated with the editor."; + return; + } + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "[ERROR] Cannot open file:" << filePath; + return; + } + + QByteArray rawData = file.readAll(); + file.close(); + + QString decodedText = decodeIBM420(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-420 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-420 encoding +QString Interpret_As_IBM_420::decodeIBM420(const QByteArray& rawData) { + QString result; + + for (unsigned char byte : rawData) { + if (ebcdicTable.contains(byte)) { + result.append(ebcdicTable.at(byte)); + } else { + result.append(QChar(0xFFFD)); // Fallback for unmapped characters + } + } + return result; +} diff --git a/src/encoding/interpret_as_ibm_420.h b/src/encoding/interpret_as_ibm_420.h new file mode 100644 index 0000000..004287f --- /dev/null +++ b/src/encoding/interpret_as_ibm_420.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_420 { +public: + static Interpret_As_IBM_420& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_420(); + ~Interpret_As_IBM_420() = default; + + Interpret_As_IBM_420(const Interpret_As_IBM_420&) = delete; + Interpret_As_IBM_420& operator=(const Interpret_As_IBM_420&) = delete; + + QString decodeIBM420(const QByteArray& rawData); + static const std::unordered_map ebcdicTable; +}; diff --git a/src/encoding/interpret_as_ibm_424.cpp b/src/encoding/interpret_as_ibm_424.cpp new file mode 100644 index 0000000..f84df96 --- /dev/null +++ b/src/encoding/interpret_as_ibm_424.cpp @@ -0,0 +1,91 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_424.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_424& Interpret_As_IBM_424::instance() { + static Interpret_As_IBM_424 instance; + return instance; +} + +// EBCDIC to Unicode mapping for IBM-424 (Hebrew EBCDIC) +const std::unordered_map Interpret_As_IBM_424::ebcdicTable = { + {0x80, QChar(0x05D0)}, // א (Alef) + {0x81, QChar(0x05D1)}, // ב (Bet) + {0x82, QChar(0x05D2)}, // ג (Gimel) + {0x83, QChar(0x05D3)}, // ד (Dalet) + {0x84, QChar(0x05D4)}, // ה (He) + {0x85, QChar(0x05D5)}, // ו (Vav) + {0x86, QChar(0x05D6)}, // ז (Zayin) + {0x87, QChar(0x05D7)}, // ח (Het) + {0x88, QChar(0x05D8)}, // ט (Tet) + {0x89, QChar(0x05D9)}, // י (Yod) + {0x8A, QChar(0x05DA)}, // ך (Final Kaf) + {0x8B, QChar(0x05DB)}, // כ (Kaf) + {0x8C, QChar(0x05DC)}, // ל (Lamed) + {0x8D, QChar(0x05DD)}, // ם (Final Mem) + {0x8E, QChar(0x05DE)}, // מ (Mem) + {0x8F, QChar(0x05DF)}, // ן (Final Nun) + {0x90, QChar(0x05E0)}, // נ (Nun) + {0x91, QChar(0x05E1)}, // ס (Samekh) + {0x92, QChar(0x05E2)}, // ע (Ayin) + {0x93, QChar(0x05E3)}, // ף (Final Pe) + {0x94, QChar(0x05E4)}, // פ (Pe) + {0x95, QChar(0x05E5)}, // ץ (Final Tsadi) + {0x96, QChar(0x05E6)}, // צ (Tsadi) + {0x97, QChar(0x05E7)}, // ק (Qof) + {0x98, QChar(0x05E8)}, // ר (Resh) + {0x99, QChar(0x05E9)}, // ש (Shin) + {0x9A, QChar(0x05EA)}, // ת (Tav) +}; + +// Constructor +Interpret_As_IBM_424::Interpret_As_IBM_424() {} + +// Main execution function +void Interpret_As_IBM_424::execute(QPlainTextEdit* editor) { + if (!editor) { + qWarning() << "[ERROR] No editor instance provided."; + return; + } + + CodeEditor* codeEditor = qobject_cast(editor); + if (!codeEditor) { + qWarning() << "[ERROR] Invalid CodeEditor instance."; + return; + } + + QString filePath = codeEditor->filePath(); + if (filePath.isEmpty()) { + qWarning() << "[ERROR] No file path associated with the editor."; + return; + } + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "[ERROR] Cannot open file:" << filePath; + return; + } + + QByteArray rawData = file.readAll(); + file.close(); + + QString decodedText = decodeIBM424(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-424 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-424 encoding +QString Interpret_As_IBM_424::decodeIBM424(const QByteArray& rawData) { + QString result; + + for (unsigned char byte : rawData) { + if (ebcdicTable.contains(byte)) { + result.append(ebcdicTable.at(byte)); + } else { + result.append(QChar(0xFFFD)); // Fallback for unmapped characters + } + } + return result; +} diff --git a/src/encoding/interpret_as_ibm_424.h b/src/encoding/interpret_as_ibm_424.h new file mode 100644 index 0000000..059925c --- /dev/null +++ b/src/encoding/interpret_as_ibm_424.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_424 { +public: + static Interpret_As_IBM_424& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_424(); + ~Interpret_As_IBM_424() = default; + + Interpret_As_IBM_424(const Interpret_As_IBM_424&) = delete; + Interpret_As_IBM_424& operator=(const Interpret_As_IBM_424&) = delete; + + QString decodeIBM424(const QByteArray& rawData); + static const std::unordered_map ebcdicTable; +}; diff --git a/src/encoding/interpret_as_ibm_437.cpp b/src/encoding/interpret_as_ibm_437.cpp new file mode 100644 index 0000000..8c969bf --- /dev/null +++ b/src/encoding/interpret_as_ibm_437.cpp @@ -0,0 +1,104 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_437.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_437& Interpret_As_IBM_437::instance() { + static Interpret_As_IBM_437 instance; + return instance; +} + +// ASCII to Unicode mapping for IBM-437 +const std::unordered_map Interpret_As_IBM_437::asciiTable = { + {0x80, QChar(0x00C7)}, // Ç + {0x81, QChar(0x00FC)}, // ü + {0x82, QChar(0x00E9)}, // é + {0x83, QChar(0x00E2)}, // â + {0x84, QChar(0x00E4)}, // ä + {0x85, QChar(0x00E0)}, // à + {0x86, QChar(0x00E5)}, // å + {0x87, QChar(0x00E7)}, // ç + {0x88, QChar(0x00EA)}, // ê + {0x89, QChar(0x00EB)}, // ë + {0x8A, QChar(0x00E8)}, // è + {0x8B, QChar(0x00EF)}, // ï + {0x8C, QChar(0x00EE)}, // î + {0x8D, QChar(0x00EC)}, // ì + {0x8E, QChar(0x00C4)}, // Ä + {0x8F, QChar(0x00C5)}, // Å + {0x90, QChar(0x00C9)}, // É + {0x91, QChar(0x00E6)}, // æ + {0x92, QChar(0x00C6)}, // Æ + {0x93, QChar(0x00F4)}, // ô + {0x94, QChar(0x00F6)}, // ö + {0x95, QChar(0x00F2)}, // ò + {0x96, QChar(0x00FB)}, // û + {0x97, QChar(0x00F9)}, // ù + {0x98, QChar(0x00FF)}, // ÿ + {0x99, QChar(0x00D6)}, // Ö + {0x9A, QChar(0x00DC)}, // Ü + {0x9B, QChar(0x00A2)}, // ¢ + {0x9C, QChar(0x00A3)}, // £ + {0x9D, QChar(0x00A5)}, // ¥ + {0x9E, QChar(0x20A7)}, // ₧ + {0x9F, QChar(0x0192)}, // ƒ + {0xA0, QChar(0x00E1)}, // á + {0xA1, QChar(0x00ED)}, // í + {0xA2, QChar(0x00F3)}, // ó + {0xA3, QChar(0x00FA)}, // ú + {0xA4, QChar(0x00F1)}, // ñ + {0xA5, QChar(0x00D1)}, // Ñ + {0xA6, QChar(0x00AA)}, // ª + {0xA7, QChar(0x00BA)}, // º +}; + +// Constructor +Interpret_As_IBM_437::Interpret_As_IBM_437() {} + +// Main execution function +void Interpret_As_IBM_437::execute(QPlainTextEdit* editor) { + if (!editor) { + qWarning() << "[ERROR] No editor instance provided."; + return; + } + + CodeEditor* codeEditor = qobject_cast(editor); + if (!codeEditor) { + qWarning() << "[ERROR] Invalid CodeEditor instance."; + return; + } + + QString filePath = codeEditor->filePath(); + if (filePath.isEmpty()) { + qWarning() << "[ERROR] No file path associated with the editor."; + return; + } + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "[ERROR] Cannot open file:" << filePath; + return; + } + + QByteArray rawData = file.readAll(); + file.close(); + + QString decodedText = decodeIBM437(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-437 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-437 encoding +QString Interpret_As_IBM_437::decodeIBM437(const QByteArray& rawData) { + QString result; + + for (unsigned char byte : rawData) { + if (asciiTable.contains(byte)) { + result.append(asciiTable.at(byte)); + } else { + result.append(QChar(0xFFFD)); // Fallback for unmapped characters + } + } + return result; +} diff --git a/src/encoding/interpret_as_ibm_437.h b/src/encoding/interpret_as_ibm_437.h new file mode 100644 index 0000000..17510ba --- /dev/null +++ b/src/encoding/interpret_as_ibm_437.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_437 { +public: + static Interpret_As_IBM_437& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_437(); + ~Interpret_As_IBM_437() = default; + + Interpret_As_IBM_437(const Interpret_As_IBM_437&) = delete; + Interpret_As_IBM_437& operator=(const Interpret_As_IBM_437&) = delete; + + QString decodeIBM437(const QByteArray& rawData); + static const std::unordered_map asciiTable; +}; diff --git a/src/encoding/interpret_as_ibm_500.cpp b/src/encoding/interpret_as_ibm_500.cpp new file mode 100644 index 0000000..a53d2e5 --- /dev/null +++ b/src/encoding/interpret_as_ibm_500.cpp @@ -0,0 +1,104 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_500.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_500& Interpret_As_IBM_500::instance() { + static Interpret_As_IBM_500 instance; + return instance; +} + +// EBCDIC to Unicode mapping for IBM-500 (International Latin-1) +const std::unordered_map Interpret_As_IBM_500::ebcdicTable = { + {0x80, QChar(0x00C7)}, // Ç + {0x81, QChar(0x00FC)}, // ü + {0x82, QChar(0x00E9)}, // é + {0x83, QChar(0x00E2)}, // â + {0x84, QChar(0x00E4)}, // ä + {0x85, QChar(0x00E0)}, // à + {0x86, QChar(0x00E5)}, // å + {0x87, QChar(0x00E7)}, // ç + {0x88, QChar(0x00EA)}, // ê + {0x89, QChar(0x00EB)}, // ë + {0x8A, QChar(0x00E8)}, // è + {0x8B, QChar(0x00EF)}, // ï + {0x8C, QChar(0x00EE)}, // î + {0x8D, QChar(0x00EC)}, // ì + {0x8E, QChar(0x00C4)}, // Ä + {0x8F, QChar(0x00C5)}, // Å + {0x90, QChar(0x00C9)}, // É + {0x91, QChar(0x00E6)}, // æ + {0x92, QChar(0x00C6)}, // Æ + {0x93, QChar(0x00F4)}, // ô + {0x94, QChar(0x00F6)}, // ö + {0x95, QChar(0x00F2)}, // ò + {0x96, QChar(0x00FB)}, // û + {0x97, QChar(0x00F9)}, // ù + {0x98, QChar(0x00FF)}, // ÿ + {0x99, QChar(0x00D6)}, // Ö + {0x9A, QChar(0x00DC)}, // Ü + {0x9B, QChar(0x00A2)}, // ¢ + {0x9C, QChar(0x00A3)}, // £ + {0x9D, QChar(0x00A5)}, // ¥ + {0x9E, QChar(0x20A7)}, // ₧ + {0x9F, QChar(0x0192)}, // ƒ + {0xA0, QChar(0x00E1)}, // á + {0xA1, QChar(0x00ED)}, // í + {0xA2, QChar(0x00F3)}, // ó + {0xA3, QChar(0x00FA)}, // ú + {0xA4, QChar(0x00F1)}, // ñ + {0xA5, QChar(0x00D1)}, // Ñ + {0xA6, QChar(0x00AA)}, // ª + {0xA7, QChar(0x00BA)}, // º +}; + +// Constructor +Interpret_As_IBM_500::Interpret_As_IBM_500() {} + +// Main execution function +void Interpret_As_IBM_500::execute(QPlainTextEdit* editor) { + if (!editor) { + qWarning() << "[ERROR] No editor instance provided."; + return; + } + + CodeEditor* codeEditor = qobject_cast(editor); + if (!codeEditor) { + qWarning() << "[ERROR] Invalid CodeEditor instance."; + return; + } + + QString filePath = codeEditor->filePath(); + if (filePath.isEmpty()) { + qWarning() << "[ERROR] No file path associated with the editor."; + return; + } + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "[ERROR] Cannot open file:" << filePath; + return; + } + + QByteArray rawData = file.readAll(); + file.close(); + + QString decodedText = decodeIBM500(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-500 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-500 encoding +QString Interpret_As_IBM_500::decodeIBM500(const QByteArray& rawData) { + QString result; + + for (unsigned char byte : rawData) { + if (ebcdicTable.contains(byte)) { + result.append(ebcdicTable.at(byte)); + } else { + result.append(QChar(0xFFFD)); // Fallback for unmapped characters + } + } + return result; +} diff --git a/src/encoding/interpret_as_ibm_500.h b/src/encoding/interpret_as_ibm_500.h new file mode 100644 index 0000000..d068025 --- /dev/null +++ b/src/encoding/interpret_as_ibm_500.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_500 { +public: + static Interpret_As_IBM_500& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_500(); + ~Interpret_As_IBM_500() = default; + + Interpret_As_IBM_500(const Interpret_As_IBM_500&) = delete; + Interpret_As_IBM_500& operator=(const Interpret_As_IBM_500&) = delete; + + QString decodeIBM500(const QByteArray& rawData); + static const std::unordered_map ebcdicTable; +}; diff --git a/src/encoding/interpret_as_ibm_775.cpp b/src/encoding/interpret_as_ibm_775.cpp new file mode 100644 index 0000000..d25b8d5 --- /dev/null +++ b/src/encoding/interpret_as_ibm_775.cpp @@ -0,0 +1,103 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_775.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_775& Interpret_As_IBM_775::instance() { + static Interpret_As_IBM_775 instance; + return instance; +} + +// EBCDIC to Unicode mapping for IBM-775 (Baltic languages) +const std::unordered_map Interpret_As_IBM_775::ebcdicTable = { + {0x80, QChar(0x0104)}, // Ą + {0x81, QChar(0x0138)}, // ĸ + {0x82, QChar(0x0156)}, // Ŗ + {0x83, QChar(0x00E4)}, // ä + {0x84, QChar(0x0128)}, // Ĩ + {0x85, QChar(0x013B)}, // Ļ + {0x86, QChar(0x00E5)}, // å + {0x87, QChar(0x0112)}, // Ē + {0x88, QChar(0x0122)}, // Ģ + {0x89, QChar(0x0166)}, // Ŧ + {0x8A, QChar(0x0157)}, // ŗ + {0x8B, QChar(0x014A)}, // Ŋ + {0x8C, QChar(0x00C4)}, // Ä + {0x8D, QChar(0x00C5)}, // Å + {0x8E, QChar(0x00C9)}, // É + {0x8F, QChar(0x00E6)}, // æ + {0x90, QChar(0x00C6)}, // Æ + {0x91, QChar(0x014D)}, // ō + {0x92, QChar(0x00F4)}, // ô + {0x93, QChar(0x00F6)}, // ö + {0x94, QChar(0x00F3)}, // ó + {0x95, QChar(0x0168)}, // Ũ + {0x96, QChar(0x00DC)}, // Ü + {0x97, QChar(0x016A)}, // Ū + {0x98, QChar(0x00A2)}, // ¢ + {0x99, QChar(0x00A3)}, // £ + {0x9A, QChar(0x00A5)}, // ¥ + {0x9B, QChar(0x20A7)}, // ₧ + {0x9C, QChar(0x0192)}, // ƒ + {0x9D, QChar(0x00E1)}, // á + {0x9E, QChar(0x00ED)}, // í + {0x9F, QChar(0x00F3)}, // ó + {0xA0, QChar(0x00FA)}, // ú + {0xA1, QChar(0x017D)}, // Ž + {0xA2, QChar(0x017E)}, // ž + {0xA3, QChar(0x00F1)}, // ñ + {0xA4, QChar(0x00D1)}, // Ñ + {0xA5, QChar(0x015A)}, // Ś + {0xA6, QChar(0x015B)}, // ś +}; + +// Constructor +Interpret_As_IBM_775::Interpret_As_IBM_775() {} + +// Main execution function +void Interpret_As_IBM_775::execute(QPlainTextEdit* editor) { + if (!editor) { + qWarning() << "[ERROR] No editor instance provided."; + return; + } + + CodeEditor* codeEditor = qobject_cast(editor); + if (!codeEditor) { + qWarning() << "[ERROR] Invalid CodeEditor instance."; + return; + } + + QString filePath = codeEditor->filePath(); + if (filePath.isEmpty()) { + qWarning() << "[ERROR] No file path associated with the editor."; + return; + } + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "[ERROR] Cannot open file:" << filePath; + return; + } + + QByteArray rawData = file.readAll(); + file.close(); + + QString decodedText = decodeIBM775(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-775 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-775 encoding +QString Interpret_As_IBM_775::decodeIBM775(const QByteArray& rawData) { + QString result; + + for (unsigned char byte : rawData) { + if (ebcdicTable.contains(byte)) { + result.append(ebcdicTable.at(byte)); + } else { + result.append(QChar(0xFFFD)); // Fallback for unmapped characters + } + } + return result; +} diff --git a/src/encoding/interpret_as_ibm_775.h b/src/encoding/interpret_as_ibm_775.h new file mode 100644 index 0000000..ee79d7e --- /dev/null +++ b/src/encoding/interpret_as_ibm_775.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_775 { +public: + static Interpret_As_IBM_775& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_775(); + ~Interpret_As_IBM_775() = default; + + Interpret_As_IBM_775(const Interpret_As_IBM_775&) = delete; + Interpret_As_IBM_775& operator=(const Interpret_As_IBM_775&) = delete; + + QString decodeIBM775(const QByteArray& rawData); + static const std::unordered_map ebcdicTable; +}; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ee8da23..3e17179 100755 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -77,6 +77,11 @@ #include "encoding/interpret_as_ibm_855.h" #include "encoding/interpret_as_ibm_852.h" #include "encoding/interpret_as_ibm_850.h" +#include "encoding/interpret_as_ibm_775.h" +#include "encoding/interpret_as_ibm_500.h" +#include "encoding/interpret_as_ibm_437.h" +#include "encoding/interpret_as_ibm_424.h" +#include "encoding/interpret_as_ibm_420.h" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), @@ -843,7 +848,7 @@ void MainWindow::on_actionInterpret_As_triggered() if (!editor) { qFatal("No active editor"); return; - } + } // combobox items are in interpret as dialog.cpp if (selectedItem == "UTF-8") { Interpret_As_Utf_8::instance().execute(editor); } @@ -996,6 +1001,21 @@ void MainWindow::on_actionInterpret_As_triggered() if (selectedItem == "IBM-850") { Interpret_As_IBM_850::instance().execute(editor); } + if (selectedItem == "IBM-775") { + Interpret_As_IBM_775::instance().execute(editor); + } + if (selectedItem == "IBM-500") { + Interpret_As_IBM_500::instance().execute(editor); + } + if (selectedItem == "IBM-437") { + Interpret_As_IBM_437::instance().execute(editor); + } + if (selectedItem == "IBM-424") { + Interpret_As_IBM_424::instance().execute(editor); + } + if (selectedItem == "IBM-420") { + Interpret_As_IBM_420::instance().execute(editor); + } } }