From 7c18bcd52012d60ad90095ccac4e564c19826d11 Mon Sep 17 00:00:00 2001 From: Remisa Yousefvand Date: Mon, 6 Jan 2025 12:26:14 +0330 Subject: [PATCH] v0.0.89 --- CHANGELOG.md | 5 ++ CMakeLists.txt | 4 ++ CMakeLists.txt.user | 12 ++-- src/encoding/interpret_as_dialog.cpp | 4 +- src/encoding/interpret_as_ibm_868.cpp | 99 +++++++++++++++++++++++++++ src/encoding/interpret_as_ibm_868.h | 22 ++++++ src/encoding/interpret_as_ibm_869.cpp | 99 +++++++++++++++++++++++++++ src/encoding/interpret_as_ibm_869.h | 22 ++++++ src/mainwindow.cpp | 5 ++ 9 files changed, 265 insertions(+), 7 deletions(-) create mode 100644 src/encoding/interpret_as_ibm_868.cpp create mode 100644 src/encoding/interpret_as_ibm_868.h create mode 100644 src/encoding/interpret_as_ibm_869.cpp create mode 100644 src/encoding/interpret_as_ibm_869.h diff --git a/CHANGELOG.md b/CHANGELOG.md index e25ffea..2fe9da1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ============ +## 0.0.89 + +- Implemented: +- Encoding Menu -> Interpret as ... IBM-869, IBM-868 + ## 0.0.88 - Implemented: diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a6a7cd..b16781c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,6 +203,10 @@ set(PROJECT_SOURCES src/encoding/interpret_as_ibm_871.h src/encoding/interpret_as_ibm_870.cpp src/encoding/interpret_as_ibm_870.h + src/encoding/interpret_as_ibm_869.cpp + src/encoding/interpret_as_ibm_869.h + src/encoding/interpret_as_ibm_868.cpp + src/encoding/interpret_as_ibm_868.h ${PROJECT_UI} ) diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index dc08eaf..dab221c 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -103,14 +103,14 @@ 2 false - -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} + -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} -DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} /data/Code/Qt/Notepad-- 0 /data/Code/Qt/Notepad--/build/Desktop_Qt_6_8_1-Debug diff --git a/src/encoding/interpret_as_dialog.cpp b/src/encoding/interpret_as_dialog.cpp index 048ca57..72b8fb7 100644 --- a/src/encoding/interpret_as_dialog.cpp +++ b/src/encoding/interpret_as_dialog.cpp @@ -47,7 +47,9 @@ InterpreteAsDialog::InterpreteAsDialog(QWidget* parent) "ISO-2022-CN", "IBM-918", "IBM-871", - "IBM-870" + "IBM-870", + "IBM-869", + "IBM-868" }); // Create OK and Cancel buttons using QDialogButtonBox diff --git a/src/encoding/interpret_as_ibm_868.cpp b/src/encoding/interpret_as_ibm_868.cpp new file mode 100644 index 0000000..afe1287 --- /dev/null +++ b/src/encoding/interpret_as_ibm_868.cpp @@ -0,0 +1,99 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_868.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_868& Interpret_As_IBM_868::instance() { + static Interpret_As_IBM_868 instance; + return instance; +} + +// EBCDIC to Unicode mapping for IBM-868 (Arabic EBCDIC) +const std::unordered_map Interpret_As_IBM_868::ebcdicTable = { + {0x40, QChar(0x0020)}, // Space + {0x4A, QChar(0x060C)}, // ، (Arabic Comma) + {0x5A, QChar(0x061B)}, // ؛ (Arabic Semicolon) + {0x5F, QChar(0x061F)}, // ؟ (Arabic Question Mark) + {0x61, QChar(0x0621)}, // ء (Hamza) + {0x62, QChar(0x0622)}, // آ (Alef with Madda) + {0x63, QChar(0x0623)}, // أ (Alef with Hamza Above) + {0x64, QChar(0x0624)}, // ؤ (Waw with Hamza Above) + {0x65, QChar(0x0625)}, // إ (Alef with Hamza Below) + {0x66, QChar(0x0626)}, // ئ (Yeh with Hamza Above) + {0x67, QChar(0x0627)}, // ا (Alef) + {0x68, QChar(0x0628)}, // ب (Beh) + {0x69, QChar(0x0629)}, // ة (Teh Marbuta) + {0x6A, QChar(0x062A)}, // ت (Teh) + {0x6B, QChar(0x062B)}, // ث (Theh) + {0x6C, QChar(0x062C)}, // ج (Jeem) + {0x6D, QChar(0x062D)}, // ح (Hah) + {0x6E, QChar(0x062E)}, // خ (Khah) + {0x6F, QChar(0x062F)}, // د (Dal) + {0x70, QChar(0x0630)}, // ذ (Thal) + {0x71, QChar(0x0631)}, // ر (Reh) + {0x72, QChar(0x0632)}, // ز (Zain) + {0x73, QChar(0x0633)}, // س (Seen) + {0x74, QChar(0x0634)}, // ش (Sheen) + {0x75, QChar(0x0635)}, // ص (Sad) + {0x76, QChar(0x0636)}, // ض (Dad) + {0x77, QChar(0x0637)}, // ط (Tah) + {0x78, QChar(0x0638)}, // ظ (Zah) + {0x79, QChar(0x0639)}, // ع (Ain) + {0x7A, QChar(0x063A)}, // غ (Ghain) + {0x7B, QChar(0x0640)}, // ـ (Tatweel) + {0x7C, QChar(0x0641)}, // ف (Feh) + {0x7D, QChar(0x0642)}, // ق (Qaf) + {0x7E, QChar(0x0643)}, // ك (Kaf) + {0x7F, QChar(0x0644)}, // ل (Lam) +}; + +// Constructor +Interpret_As_IBM_868::Interpret_As_IBM_868() {} + +// Main execution function +void Interpret_As_IBM_868::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 = decodeIBM868(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-868 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-868 encoding +QString Interpret_As_IBM_868::decodeIBM868(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_868.h b/src/encoding/interpret_as_ibm_868.h new file mode 100644 index 0000000..d3863b8 --- /dev/null +++ b/src/encoding/interpret_as_ibm_868.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_868 { +public: + static Interpret_As_IBM_868& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_868(); + ~Interpret_As_IBM_868() = default; + + Interpret_As_IBM_868(const Interpret_As_IBM_868&) = delete; + Interpret_As_IBM_868& operator=(const Interpret_As_IBM_868&) = delete; + + QString decodeIBM868(const QByteArray& rawData); + static const std::unordered_map ebcdicTable; +}; diff --git a/src/encoding/interpret_as_ibm_869.cpp b/src/encoding/interpret_as_ibm_869.cpp new file mode 100644 index 0000000..5b67ccc --- /dev/null +++ b/src/encoding/interpret_as_ibm_869.cpp @@ -0,0 +1,99 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_869.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_869& Interpret_As_IBM_869::instance() { + static Interpret_As_IBM_869 instance; + return instance; +} + +// EBCDIC to Unicode mapping for IBM-869 (Greek EBCDIC) +const std::unordered_map Interpret_As_IBM_869::ebcdicTable = { + {0x40, QChar(0x0020)}, // Space + {0x4A, QChar(0x0384)}, // ΄ (Greek Tonos) + {0x5A, QChar(0x003B)}, // ; (Semicolon) + {0x5F, QChar(0x0387)}, // · (Greek Ano Teleia) + {0x61, QChar(0x0391)}, // Α (Alpha) + {0x62, QChar(0x0392)}, // Β (Beta) + {0x63, QChar(0x0393)}, // Γ (Gamma) + {0x64, QChar(0x0394)}, // Δ (Delta) + {0x65, QChar(0x0395)}, // Ε (Epsilon) + {0x66, QChar(0x0396)}, // Ζ (Zeta) + {0x67, QChar(0x0397)}, // Η (Eta) + {0x68, QChar(0x0398)}, // Θ (Theta) + {0x69, QChar(0x0399)}, // Ι (Iota) + {0x6A, QChar(0x039A)}, // Κ (Kappa) + {0x6B, QChar(0x039B)}, // Λ (Lambda) + {0x6C, QChar(0x039C)}, // Μ (Mu) + {0x6D, QChar(0x039D)}, // Ν (Nu) + {0x6E, QChar(0x039E)}, // Ξ (Xi) + {0x6F, QChar(0x039F)}, // Ο (Omicron) + {0x70, QChar(0x03A0)}, // Π (Pi) + {0x71, QChar(0x03A1)}, // Ρ (Rho) + {0x72, QChar(0x03A3)}, // Σ (Sigma) + {0x73, QChar(0x03A4)}, // Τ (Tau) + {0x74, QChar(0x03A5)}, // Υ (Upsilon) + {0x75, QChar(0x03A6)}, // Φ (Phi) + {0x76, QChar(0x03A7)}, // Χ (Chi) + {0x77, QChar(0x03A8)}, // Ψ (Psi) + {0x78, QChar(0x03A9)}, // Ω (Omega) + {0x79, QChar(0x03B1)}, // α (alpha) + {0x7A, QChar(0x03B2)}, // β (beta) + {0x7B, QChar(0x03B3)}, // γ (gamma) + {0x7C, QChar(0x03B4)}, // δ (delta) + {0x7D, QChar(0x03B5)}, // ε (epsilon) + {0x7E, QChar(0x03B6)}, // ζ (zeta) + {0x7F, QChar(0x03B7)}, // η (eta) +}; + +// Constructor +Interpret_As_IBM_869::Interpret_As_IBM_869() {} + +// Main execution function +void Interpret_As_IBM_869::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 = decodeIBM869(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-869 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-869 encoding +QString Interpret_As_IBM_869::decodeIBM869(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_869.h b/src/encoding/interpret_as_ibm_869.h new file mode 100644 index 0000000..da18091 --- /dev/null +++ b/src/encoding/interpret_as_ibm_869.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_869 { +public: + static Interpret_As_IBM_869& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_869(); + ~Interpret_As_IBM_869() = default; + + Interpret_As_IBM_869(const Interpret_As_IBM_869&) = delete; + Interpret_As_IBM_869& operator=(const Interpret_As_IBM_869&) = delete; + + QString decodeIBM869(const QByteArray& rawData); + static const std::unordered_map ebcdicTable; +}; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3c61e59..a185098 100755 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -64,6 +64,8 @@ #include "encoding/interpret_as_ibm_918.h" #include "encoding/interpret_as_ibm_871.h" #include "encoding/interpret_as_ibm_870.h" +#include "encoding/interpret_as_ibm_869.h" +#include "encoding/interpret_as_ibm_868.h" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), @@ -944,6 +946,9 @@ void MainWindow::on_actionInterpret_As_triggered() if (selectedItem == "IBM-870") { Interpret_As_IBM_870::instance().execute(editor); } + if (selectedItem == "IBM-868") { + Interpret_As_IBM_868::instance().execute(editor); + } } }