diff --git a/CHANGELOG.md b/CHANGELOG.md index bc9dd6d..8d8180b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ============ +## 0.0.91 + +- Implemented: +- Encoding Menu -> Interpret as ... IBM-857, IBM-855, IBM-852, IBM-850 + ## 0.0.90 - Implemented: diff --git a/CMakeLists.txt b/CMakeLists.txt index 08da42c..1c91953 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,6 +221,14 @@ set(PROJECT_SOURCES src/encoding/interpret_as_ibm_861.h src/encoding/interpret_as_ibm_860.cpp src/encoding/interpret_as_ibm_860.h + src/encoding/interpret_as_ibm_857.cpp + src/encoding/interpret_as_ibm_857.h + src/encoding/interpret_as_ibm_855.cpp + src/encoding/interpret_as_ibm_855.h + src/encoding/interpret_as_ibm_852.cpp + src/encoding/interpret_as_ibm_852.h + src/encoding/interpret_as_ibm_850.cpp + src/encoding/interpret_as_ibm_850.h ${PROJECT_UI} ) diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index 9e8f174..2f77570 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -103,14 +103,14 @@ 2 false - -DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} + -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 --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} /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 ca849a7..3599aaa 100644 --- a/src/encoding/interpret_as_dialog.cpp +++ b/src/encoding/interpret_as_dialog.cpp @@ -56,7 +56,11 @@ InterpreteAsDialog::InterpreteAsDialog(QWidget* parent) "IBM-863", "IBM-862", "IBM-861", - "IBM-860" + "IBM-860", + "IBM-857", + "IBM-855", + "IBM-852", + "IBM-850" }); // Create OK and Cancel buttons using QDialogButtonBox diff --git a/src/encoding/interpret_as_ibm_850.cpp b/src/encoding/interpret_as_ibm_850.cpp new file mode 100644 index 0000000..0f247ef --- /dev/null +++ b/src/encoding/interpret_as_ibm_850.cpp @@ -0,0 +1,104 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_850.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_850& Interpret_As_IBM_850::instance() { + static Interpret_As_IBM_850 instance; + return instance; +} + +// EBCDIC to Unicode mapping for IBM-850 (Latin-1) +const std::unordered_map Interpret_As_IBM_850::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_850::Interpret_As_IBM_850() {} + +// Main execution function +void Interpret_As_IBM_850::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 = decodeIBM850(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-850 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-850 encoding +QString Interpret_As_IBM_850::decodeIBM850(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_850.h b/src/encoding/interpret_as_ibm_850.h new file mode 100644 index 0000000..919b687 --- /dev/null +++ b/src/encoding/interpret_as_ibm_850.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_850 { +public: + static Interpret_As_IBM_850& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_850(); + ~Interpret_As_IBM_850() = default; + + Interpret_As_IBM_850(const Interpret_As_IBM_850&) = delete; + Interpret_As_IBM_850& operator=(const Interpret_As_IBM_850&) = delete; + + QString decodeIBM850(const QByteArray& rawData); + static const std::unordered_map ebcdicTable; +}; diff --git a/src/encoding/interpret_as_ibm_852.cpp b/src/encoding/interpret_as_ibm_852.cpp new file mode 100644 index 0000000..af88676 --- /dev/null +++ b/src/encoding/interpret_as_ibm_852.cpp @@ -0,0 +1,104 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_852.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_852& Interpret_As_IBM_852::instance() { + static Interpret_As_IBM_852 instance; + return instance; +} + +// EBCDIC to Unicode mapping for IBM-852 (Central European) +const std::unordered_map Interpret_As_IBM_852::ebcdicTable = { + {0x80, QChar(0x0104)}, // Ą + {0x81, QChar(0x00FC)}, // ü + {0x82, QChar(0x00E9)}, // é + {0x83, QChar(0x0101)}, // ā + {0x84, QChar(0x00E4)}, // ä + {0x85, QChar(0x0123)}, // ģ + {0x86, QChar(0x00E5)}, // å + {0x87, QChar(0x0107)}, // ć + {0x88, QChar(0x0142)}, // ł + {0x89, QChar(0x0113)}, // ē + {0x8A, QChar(0x010D)}, // č + {0x8B, QChar(0x0119)}, // ę + {0x8C, QChar(0x0117)}, // ė + {0x8D, QChar(0x0106)}, // Ć + {0x8E, QChar(0x00C4)}, // Ä + {0x8F, QChar(0x00C5)}, // Å + {0x90, QChar(0x0141)}, // Ł + {0x91, QChar(0x00E6)}, // æ + {0x92, QChar(0x00C6)}, // Æ + {0x93, QChar(0x0112)}, // Ē + {0x94, QChar(0x00F6)}, // ö + {0x95, QChar(0x00F3)}, // ó + {0x96, QChar(0x0144)}, // ń + {0x97, QChar(0x0143)}, // Ń + {0x98, QChar(0x00D6)}, // Ö + {0x99, QChar(0x00DC)}, // Ü + {0x9A, QChar(0x00A2)}, // ¢ + {0x9B, QChar(0x015A)}, // Ś + {0x9C, QChar(0x015B)}, // ś + {0x9D, QChar(0x00D3)}, // Ó + {0x9E, QChar(0x0179)}, // Ź + {0x9F, QChar(0x017A)}, // ź + {0xA0, QChar(0x00E1)}, // á + {0xA1, QChar(0x00ED)}, // í + {0xA2, QChar(0x00F3)}, // ó + {0xA3, QChar(0x00FA)}, // ú + {0xA4, QChar(0x00F1)}, // ñ + {0xA5, QChar(0x00D1)}, // Ñ + {0xA6, QChar(0x015E)}, // Ş + {0xA7, QChar(0x015F)}, // ş +}; + +// Constructor +Interpret_As_IBM_852::Interpret_As_IBM_852() {} + +// Main execution function +void Interpret_As_IBM_852::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 = decodeIBM852(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-852 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-852 encoding +QString Interpret_As_IBM_852::decodeIBM852(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_852.h b/src/encoding/interpret_as_ibm_852.h new file mode 100644 index 0000000..ba6b844 --- /dev/null +++ b/src/encoding/interpret_as_ibm_852.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_852 { +public: + static Interpret_As_IBM_852& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_852(); + ~Interpret_As_IBM_852() = default; + + Interpret_As_IBM_852(const Interpret_As_IBM_852&) = delete; + Interpret_As_IBM_852& operator=(const Interpret_As_IBM_852&) = delete; + + QString decodeIBM852(const QByteArray& rawData); + static const std::unordered_map ebcdicTable; +}; diff --git a/src/encoding/interpret_as_ibm_855.cpp b/src/encoding/interpret_as_ibm_855.cpp new file mode 100644 index 0000000..4672b93 --- /dev/null +++ b/src/encoding/interpret_as_ibm_855.cpp @@ -0,0 +1,94 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_855.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_855& Interpret_As_IBM_855::instance() { + static Interpret_As_IBM_855 instance; + return instance; +} + +// EBCDIC to Unicode mapping for IBM-855 (Cyrillic EBCDIC) +const std::unordered_map Interpret_As_IBM_855::ebcdicTable = { + {0x80, QChar(0x0452)}, // ђ + {0x81, QChar(0x0453)}, // ғ + {0x82, QChar(0x0451)}, // ё + {0x83, QChar(0x0454)}, // є + {0x84, QChar(0x0455)}, // ї + {0x85, QChar(0x0456)}, // і + {0x86, QChar(0x0457)}, // ґ + {0x87, QChar(0x0458)}, // ј + {0x88, QChar(0x0459)}, // љ + {0x89, QChar(0x045A)}, // њ + {0x8A, QChar(0x045B)}, // ћ + {0x8B, QChar(0x045C)}, // ќ + {0x8C, QChar(0x045E)}, // ў + {0x8D, QChar(0x045F)}, // дз + {0x8E, QChar(0x2116)}, // № + {0x8F, QChar(0x0450)}, // ѐ + {0x90, QChar(0x0401)}, // Ё + {0x91, QChar(0x0402)}, // Ђ + {0x92, QChar(0x0403)}, // Ѓ + {0x93, QChar(0x0404)}, // Є + {0x94, QChar(0x0405)}, // Ѕ + {0x95, QChar(0x0406)}, // І + {0x96, QChar(0x0407)}, // Ї + {0x97, QChar(0x0408)}, // Ј + {0x98, QChar(0x0409)}, // Љ + {0x99, QChar(0x040A)}, // Њ + {0x9A, QChar(0x040B)}, // Ћ + {0x9B, QChar(0x040C)}, // Ќ + {0x9C, QChar(0x040E)}, // Ў + {0x9D, QChar(0x040F)}, // Џ +}; + +// Constructor +Interpret_As_IBM_855::Interpret_As_IBM_855() {} + +// Main execution function +void Interpret_As_IBM_855::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 = decodeIBM855(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-855 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-855 encoding +QString Interpret_As_IBM_855::decodeIBM855(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_855.h b/src/encoding/interpret_as_ibm_855.h new file mode 100644 index 0000000..96b2b8d --- /dev/null +++ b/src/encoding/interpret_as_ibm_855.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_855 { +public: + static Interpret_As_IBM_855& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_855(); + ~Interpret_As_IBM_855() = default; + + Interpret_As_IBM_855(const Interpret_As_IBM_855&) = delete; + Interpret_As_IBM_855& operator=(const Interpret_As_IBM_855&) = delete; + + QString decodeIBM855(const QByteArray& rawData); + static const std::unordered_map ebcdicTable; +}; diff --git a/src/encoding/interpret_as_ibm_857.cpp b/src/encoding/interpret_as_ibm_857.cpp new file mode 100644 index 0000000..a3ee411 --- /dev/null +++ b/src/encoding/interpret_as_ibm_857.cpp @@ -0,0 +1,104 @@ +#include "../codeeditor.h" +#include "interpret_as_ibm_857.h" +#include +#include + +// Singleton instance +Interpret_As_IBM_857& Interpret_As_IBM_857::instance() { + static Interpret_As_IBM_857 instance; + return instance; +} + +// EBCDIC to Unicode mapping for IBM-857 (Turkish EBCDIC) +const std::unordered_map Interpret_As_IBM_857::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(0x0131)}, // ı (Dotless i) + {0x99, QChar(0x00D6)}, // Ö + {0x9A, QChar(0x00DC)}, // Ü + {0x9B, QChar(0x011E)}, // Ğ (Uppercase G with Breve) + {0x9C, QChar(0x011F)}, // ğ (Lowercase g with Breve) + {0x9D, QChar(0x0130)}, // İ (Uppercase I with dot) + {0x9E, QChar(0x015E)}, // Ş (Uppercase S with Cedilla) + {0x9F, QChar(0x015F)}, // ş (Lowercase s with Cedilla) + {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_857::Interpret_As_IBM_857() {} + +// Main execution function +void Interpret_As_IBM_857::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 = decodeIBM857(rawData); + editor->setPlainText(decodedText); + qDebug() << "[DEBUG] IBM-857 Decoding applied for file:" << filePath; +} + +// Decode raw data from IBM-857 encoding +QString Interpret_As_IBM_857::decodeIBM857(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_857.h b/src/encoding/interpret_as_ibm_857.h new file mode 100644 index 0000000..5a2a62f --- /dev/null +++ b/src/encoding/interpret_as_ibm_857.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include + +class Interpret_As_IBM_857 { +public: + static Interpret_As_IBM_857& instance(); + void execute(QPlainTextEdit* editor); + +private: + Interpret_As_IBM_857(); + ~Interpret_As_IBM_857() = default; + + Interpret_As_IBM_857(const Interpret_As_IBM_857&) = delete; + Interpret_As_IBM_857& operator=(const Interpret_As_IBM_857&) = delete; + + QString decodeIBM857(const QByteArray& rawData); + static const std::unordered_map ebcdicTable; +}; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e74e0ff..ee8da23 100755 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -73,6 +73,10 @@ #include "encoding/interpret_as_ibm_862.h" #include "encoding/interpret_as_ibm_861.h" #include "encoding/interpret_as_ibm_860.h" +#include "encoding/interpret_as_ibm_857.h" +#include "encoding/interpret_as_ibm_855.h" +#include "encoding/interpret_as_ibm_852.h" +#include "encoding/interpret_as_ibm_850.h" MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), @@ -980,6 +984,18 @@ void MainWindow::on_actionInterpret_As_triggered() if (selectedItem == "IBM-860") { Interpret_As_IBM_860::instance().execute(editor); } + if (selectedItem == "IBM-857") { + Interpret_As_IBM_857::instance().execute(editor); + } + if (selectedItem == "IBM-855") { + Interpret_As_IBM_855::instance().execute(editor); + } + if (selectedItem == "IBM-852") { + Interpret_As_IBM_852::instance().execute(editor); + } + if (selectedItem == "IBM-850") { + Interpret_As_IBM_850::instance().execute(editor); + } } }