├── README.md ├── xoptions.pri ├── xoptions.cmake ├── xoptionswidget.pri ├── xoptionswidget.cmake ├── LICENSE ├── xprocesswatch.h ├── codecs ├── codec_cp437.h └── codec_cp437.cpp ├── xthreadobject.h ├── xthreadobject.cpp ├── xprocesswatch.cpp ├── dialogviewcolors.ui ├── dialogviewcolors.h ├── xoptionswidget.h ├── dialogviewcolors.cpp ├── xoptionswidget.cpp ├── xoptions.h ├── xoptionswidget.ui └── xoptions.cpp /README.md: -------------------------------------------------------------------------------- 1 | Options for projects: 2 | 3 | * Detect It Easy: https://github.com/horsicq/Detect-It-Easy 4 | * XAPKDetector: https://github.com/horsicq/XAPKDetector 5 | * XELFViewer: https://github.com/horsicq/XELFViewer 6 | * XPEViewer: https://github.com/horsicq/XPEViewer 7 | * XMACHOViewer: https://github.com/horsicq/XMACHOViewer 8 | * PDBRipper: https://github.com/horsicq/PDBRipper 9 | * XNTSV: https://github.com/horsicq/xntsv 10 | * XDepends: https://github.com/horsicq/XDepends 11 | -------------------------------------------------------------------------------- /xoptions.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD 2 | DEPENDPATH += $$PWD 3 | 4 | HEADERS += \ 5 | $$PWD/codecs/codec_cp437.h \ 6 | $$PWD/xoptions.h \ 7 | $$PWD/xthreadobject.h \ 8 | $$PWD/xprocesswatch.h 9 | 10 | SOURCES += \ 11 | $$PWD/codecs/codec_cp437.cpp \ 12 | $$PWD/xoptions.cpp \ 13 | $$PWD/xthreadobject.cpp \ 14 | $$PWD/xprocesswatch.cpp 15 | 16 | DISTFILES += \ 17 | $$PWD/LICENSE \ 18 | $$PWD/README.md \ 19 | $$PWD/xoptions.cmake 20 | -------------------------------------------------------------------------------- /xoptions.cmake: -------------------------------------------------------------------------------- 1 | include_directories(${CMAKE_CURRENT_LIST_DIR}) 2 | 3 | set(XOPTIONS_SOURCES 4 | ${XOPTIONS_SOURCES} 5 | ${CMAKE_CURRENT_LIST_DIR}/xoptions.cpp 6 | ${CMAKE_CURRENT_LIST_DIR}/xoptions.h 7 | ${CMAKE_CURRENT_LIST_DIR}/codecs/codec_cp437.cpp 8 | ${CMAKE_CURRENT_LIST_DIR}/codecs/codec_cp437.h 9 | ${CMAKE_CURRENT_LIST_DIR}/xthreadobject.cpp 10 | ${CMAKE_CURRENT_LIST_DIR}/xthreadobject.h 11 | ${CMAKE_CURRENT_LIST_DIR}/xprocesswatch.cpp 12 | ${CMAKE_CURRENT_LIST_DIR}/xprocesswatch.h 13 | ) 14 | -------------------------------------------------------------------------------- /xoptionswidget.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD 2 | DEPENDPATH += $$PWD 3 | 4 | HEADERS += \ 5 | $$PWD/dialogviewcolors.h \ 6 | $$PWD/xoptionswidget.h 7 | 8 | SOURCES += \ 9 | $$PWD/dialogviewcolors.cpp \ 10 | $$PWD/xoptionswidget.cpp 11 | 12 | FORMS += \ 13 | $$PWD/dialogviewcolors.ui \ 14 | $$PWD/xoptionswidget.ui 15 | 16 | !contains(XCONFIG, xoptions) { 17 | XCONFIG += xoptions 18 | include($$PWD/xoptions.pri) 19 | } 20 | 21 | DISTFILES += \ 22 | $$PWD/LICENSE \ 23 | $$PWD/README.md \ 24 | $$PWD/xoptionswidget.cmake 25 | -------------------------------------------------------------------------------- /xoptionswidget.cmake: -------------------------------------------------------------------------------- 1 | include_directories(${CMAKE_CURRENT_LIST_DIR}) 2 | 3 | if (NOT DEFINED XOPTIONS_SOURCES) 4 | include(${CMAKE_CURRENT_LIST_DIR}/xoptions.cmake) 5 | set(XOPTIONSWIDGET_SOURCES ${XOPTIONSWIDGET_SOURCES} ${XOPTIONS_SOURCES}) 6 | endif() 7 | 8 | set(XOPTIONSWIDGET_SOURCES 9 | ${XOPTIONSWIDGET_SOURCES} 10 | ${CMAKE_CURRENT_LIST_DIR}/xoptionswidget.cpp 11 | ${CMAKE_CURRENT_LIST_DIR}/xoptionswidget.h 12 | ${CMAKE_CURRENT_LIST_DIR}/xoptionswidget.ui 13 | ${CMAKE_CURRENT_LIST_DIR}/dialogviewcolors.cpp 14 | ${CMAKE_CURRENT_LIST_DIR}/dialogviewcolors.h 15 | ${CMAKE_CURRENT_LIST_DIR}/dialogviewcolors.ui 16 | ) 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2025 hors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /xprocesswatch.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #ifndef XPROCESSWATCH_H 22 | #define XPROCESSWATCH_H 23 | 24 | #include 25 | #include "xbinary.h" 26 | 27 | class XProcessWatch : public QObject { 28 | Q_OBJECT 29 | 30 | public: 31 | explicit XProcessWatch(QObject *parent = nullptr); 32 | ~XProcessWatch(); 33 | 34 | void start(XBinary::PDSTRUCT *pPdStruct); 35 | void stop(); 36 | 37 | private slots: 38 | void _timeout(); 39 | 40 | private: 41 | XBinary::PDSTRUCT *m_pPdStruct; 42 | QTimer *m_pTimer; 43 | }; 44 | 45 | #endif // XPROCESSWATCH_H 46 | -------------------------------------------------------------------------------- /codecs/codec_cp437.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2024-2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #ifndef CODEC_CP437_H 22 | #define CODEC_CP437_H 23 | #include 24 | #if (QT_VERSION_MAJOR < 6) || defined(QT_CORE5COMPAT_LIB) 25 | #include 26 | 27 | class codec_cp437 : public QTextCodec { 28 | public: 29 | codec_cp437(); 30 | ~codec_cp437(); 31 | 32 | QByteArray name() const; 33 | QList aliases() const; 34 | int mibEnum() const; 35 | 36 | protected: 37 | QString convertToUnicode(const char *in, int length, ConverterState *state) const; 38 | QByteArray convertFromUnicode(const QChar *in, int length, ConverterState *state) const; 39 | }; 40 | #endif 41 | #endif // CODEC_CP437_H 42 | -------------------------------------------------------------------------------- /xthreadobject.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #ifndef XTHREADOBJECT_H 22 | #define XTHREADOBJECT_H 23 | 24 | #include 25 | #include 26 | 27 | class XThreadObject : public QObject { 28 | Q_OBJECT 29 | 30 | public: 31 | explicit XThreadObject(QObject *pParent = nullptr); 32 | 33 | virtual void process() = 0; 34 | virtual QString getTitle(); // TODO setTitle 35 | 36 | void _connect(XThreadObject *pThreadObject); 37 | 38 | public slots: 39 | void _process(); 40 | 41 | signals: 42 | void completed(qint64 nElapsedTime); 43 | void errorMessage(const QString &sErrorMessage); 44 | void warningMessage(const QString &sWarningMessage); 45 | void infoMessage(const QString &sInfoMessage); 46 | }; 47 | 48 | #endif // XTHREADOBJECT_H 49 | -------------------------------------------------------------------------------- /xthreadobject.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #include "xthreadobject.h" 22 | 23 | XThreadObject::XThreadObject(QObject *pParent) : QObject(pParent) 24 | { 25 | } 26 | 27 | QString XThreadObject::getTitle() 28 | { 29 | return tr("Process"); 30 | } 31 | 32 | void XThreadObject::_connect(XThreadObject *pThreadObject) 33 | { 34 | connect(pThreadObject, &XThreadObject::errorMessage, this, &XThreadObject::errorMessage); 35 | connect(pThreadObject, &XThreadObject::warningMessage, this, &XThreadObject::warningMessage); 36 | connect(pThreadObject, &XThreadObject::infoMessage, this, &XThreadObject::infoMessage); 37 | } 38 | 39 | void XThreadObject::_process() 40 | { 41 | QElapsedTimer scanTimer; 42 | scanTimer.start(); 43 | 44 | process(); 45 | 46 | emit completed(scanTimer.elapsed()); 47 | } 48 | -------------------------------------------------------------------------------- /xprocesswatch.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #include "xprocesswatch.h" 22 | 23 | XProcessWatch::XProcessWatch(QObject *parent) : QObject(parent) 24 | { 25 | m_pPdStruct = nullptr; 26 | m_pTimer = nullptr; 27 | } 28 | 29 | XProcessWatch::~XProcessWatch() 30 | { 31 | stop(); 32 | } 33 | 34 | void XProcessWatch::start(XBinary::PDSTRUCT *pPdStruct) 35 | { 36 | m_pPdStruct = pPdStruct; 37 | 38 | stop(); 39 | m_pTimer = new QTimer; 40 | connect(m_pTimer, SIGNAL(timeout()), this, SLOT(_timeout())); 41 | m_pTimer->start(1000); 42 | } 43 | 44 | void XProcessWatch::stop() 45 | { 46 | if (m_pTimer) { 47 | m_pTimer->stop(); 48 | delete m_pTimer; 49 | m_pTimer = nullptr; 50 | } 51 | } 52 | 53 | void XProcessWatch::_timeout() 54 | { 55 | qDebug("void XProcessWatch::_timeout()"); 56 | } 57 | -------------------------------------------------------------------------------- /dialogviewcolors.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DialogViewColors 4 | 5 | 6 | Qt::WindowModality::ApplicationModal 7 | 8 | 9 | 10 | 0 11 | 0 12 | 778 13 | 292 14 | 15 | 16 | 17 | Colors 18 | 19 | 20 | true 21 | 22 | 23 | 24 | 25 | 26 | QAbstractItemView::EditTrigger::NoEditTriggers 27 | 28 | 29 | QAbstractItemView::SelectionMode::NoSelection 30 | 31 | 32 | QAbstractItemView::SelectionBehavior::SelectRows 33 | 34 | 35 | false 36 | 37 | 38 | true 39 | 40 | 41 | false 42 | 43 | 44 | 20 45 | 46 | 47 | 20 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Qt::Orientation::Horizontal 57 | 58 | 59 | 60 | 40 61 | 20 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | OK 70 | 71 | 72 | 73 | 74 | 75 | 76 | Cancel 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /dialogviewcolors.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020-2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #ifndef DIALOGVIEWCOLORS_H 22 | #define DIALOGVIEWCOLORS_H 23 | 24 | #include 25 | #include "xshortcutsdialog.h" 26 | #include 27 | #include 28 | 29 | #include "xoptions.h" 30 | 31 | namespace Ui { 32 | class DialogViewColors; 33 | } 34 | 35 | // mb TODO TreeView 36 | class DialogViewColors : public XShortcutsDialog { 37 | Q_OBJECT 38 | 39 | enum COLUMN { 40 | COLUMN_TEXT_COLOR, 41 | COLUMN_TEXT_COLOR_REMOVE, 42 | COLUMN_BACKGROUND_COLOR, 43 | COLUMN_BACKGROUND_COLOR_REMOVE, 44 | COLUMN_GROUP, 45 | COLUMN_STRING 46 | }; 47 | 48 | public: 49 | struct RECORD { 50 | QString sGroup; 51 | QString sText; 52 | XOptions::ID id; 53 | }; 54 | explicit DialogViewColors(QWidget *pParent = nullptr); 55 | ~DialogViewColors(); 56 | 57 | virtual void adjustView(); 58 | 59 | void setOptions(XOptions *pOptions, const QList &listRecords, const QString &sTitle); 60 | void save(); 61 | 62 | private slots: 63 | void on_pushButtonCancel_clicked(); 64 | void on_pushButtonOK_clicked(); 65 | void pushButtonSlot(); 66 | 67 | protected: 68 | virtual void registerShortcuts(bool bState); 69 | 70 | private: 71 | void addRecord(qint32 nRow, const QString &sGroup, const QString &sText, XOptions::ID id); 72 | void addRecord(qint32 nRow, const RECORD &record); 73 | void updateRow(qint32 nRow); 74 | 75 | Ui::DialogViewColors *ui; 76 | XOptions *m_pOptions; 77 | QMap m_mapColors; 78 | }; 79 | 80 | #endif // DIALOGVIEWCOLORS_H 81 | -------------------------------------------------------------------------------- /xoptionswidget.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020-2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #ifndef XOPTIONSWIDGET_H 22 | #define XOPTIONSWIDGET_H 23 | 24 | #include "xshortcutswidget.h" 25 | 26 | #ifdef USE_XSIMD 27 | #include "xsimd.h" 28 | #endif 29 | 30 | namespace Ui { 31 | class XOptionsWidget; 32 | } 33 | 34 | class XOptionsWidget : public XShortcutsWidget { 35 | Q_OBJECT 36 | 37 | public: 38 | explicit XOptionsWidget(QWidget *pParent = nullptr); 39 | ~XOptionsWidget(); 40 | 41 | virtual void adjustView(); 42 | virtual void setGlobal(XShortcuts *pShortcuts, XOptions *pXOptions); 43 | 44 | void setOptions(XOptions *pOptions, const QString &sApplicationDisplayName); 45 | void addListRecord(const QString &sTitle, qint32 nIndex); 46 | void addPage(QWidget *pWidget, const QString &sTitle); 47 | void setCurrentPage(qint32 nPage); // TODO Check -> remove 48 | void setCurrentPage(XOptions::GROUPID groupId); 49 | virtual void reloadData(bool bSaveSelection); 50 | 51 | public slots: 52 | void save(); 53 | void reload(); 54 | 55 | private slots: 56 | void on_listWidgetOptions_currentRowChanged(int nCurrentRow); 57 | void on_checkBoxFileContext_toggled(bool bChecked); 58 | void on_toolButtonViewFontControls_clicked(); 59 | void on_toolButtonViewFontTables_clicked(); 60 | void on_toolButtonViewFontTrees_clicked(); 61 | void on_toolButtonHexFont_clicked(); 62 | void on_toolButtonDisasmFont_clicked(); 63 | void on_toolButtonViewFontTextEdits_clicked(); 64 | void on_pushButtonDefault_clicked(); 65 | void on_pushButtonOK_clicked(); 66 | void on_pushButtonCancel_clicked(); 67 | void on_checkBoxFileSetEnvVar_toggled(bool bChecked); 68 | void on_checkBoxSSE2_toggled(bool bChecked); 69 | void on_checkBoxAVX_toggled(bool bChecked); 70 | void on_checkBoxAVX2_toggled(bool bChecked); 71 | 72 | signals: 73 | void saveSignal(); 74 | void reloadSignal(); 75 | 76 | protected: 77 | virtual void registerShortcuts(bool bState); 78 | 79 | private: 80 | Ui::XOptionsWidget *ui; 81 | QWidget *m_pParent; 82 | XOptions *m_pOptions; 83 | QString m_sApplicationDisplayName; 84 | #ifdef Q_OS_WIN 85 | XOptions::USERROLE m_userRole; 86 | #endif 87 | }; 88 | 89 | #endif // XOPTIONSWIDGET_H 90 | -------------------------------------------------------------------------------- /codecs/codec_cp437.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2024-2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #include "codec_cp437.h" 22 | #if (QT_VERSION_MAJOR < 6) || defined(QT_CORE5COMPAT_LIB) 23 | static const char hexchars[] = "0123456789ABCDEF"; 24 | 25 | // Convert IBM437 character codes 0x00 - 0xFF into Unicode. 26 | static quint16 const cp437ToUnicode[256] = { 27 | 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 28 | 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001c, 0x001b, 0x007f, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 29 | 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 30 | 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 31 | 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 32 | 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 33 | 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x001a, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 34 | 0x00ee, 0x00ec, 0x00c4, 0x00c5, 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, 35 | 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502, 36 | 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, 37 | 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518, 0x250c, 0x2588, 38 | 0x2584, 0x258c, 0x2590, 0x2580, 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x03bc, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, 39 | 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0}; 40 | 41 | // Convert Unicode 0x0000 - 0x00FF into IBM437. 42 | static quint8 const cp437FromUnicode[256] = { 43 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 44 | 0x7f, 0x1b, 0x1a, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 45 | 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 46 | 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 47 | 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x1c, '?', '?', 48 | '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', 49 | '?', '?', '?', '?', 0xff, 0xad, 0x9b, 0x9c, '?', 0x9d, '?', 0x15, '?', '?', 0xa6, 0xae, 0xaa, '?', '?', '?', 0xf8, 0xf1, 0xfd, '?', '?', '?', 50 | 0x14, 0xfa, '?', '?', 0xa7, 0xaf, 0xac, 0xab, '?', 0xa8, '?', '?', '?', '?', 0x8e, 0x8f, 0x92, 0x80, '?', 0x90, '?', '?', '?', '?', '?', '?', 51 | '?', 0xa5, '?', '?', '?', '?', 0x99, '?', '?', '?', '?', '?', 0x9a, '?', '?', 0xe1, 0x85, 0xa0, 0x83, '?', 0x84, 0x86, 0x91, 0x87, 0x8a, 0x82, 52 | 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, '?', 0xa4, 0x95, 0xa2, 0x93, '?', 0x94, 0xf6, '?', 0x97, 0xa3, 0x96, 0x81, '?', '?', 0x98}; 53 | 54 | codec_cp437::codec_cp437() 55 | { 56 | } 57 | 58 | codec_cp437::~codec_cp437() 59 | { 60 | } 61 | 62 | QByteArray codec_cp437::name() const 63 | { 64 | return "IBM437"; 65 | } 66 | 67 | QList codec_cp437::aliases() const 68 | { 69 | QList list; 70 | list << "CP437"; 71 | 72 | return list; 73 | } 74 | 75 | int codec_cp437::mibEnum() const 76 | { 77 | return 437; 78 | } 79 | 80 | QString codec_cp437::convertToUnicode(const char *in, int length, ConverterState *state) const 81 | { 82 | Q_UNUSED(state) 83 | 84 | QString str; 85 | if (length >= 6 && in[0] == '8' && in[1] == '0' && in[length - 4] == 'F' && in[length - 3] == 'F' && in[length - 2] == 'F' && in[length - 1] == 'F') { 86 | // UCS-2 string embedded within a 437-encoded string. 87 | qint32 nibble = 0; 88 | qint32 value = 0; 89 | qint32 digit; 90 | in += 2; 91 | length -= 6; 92 | while (length-- > 0) { 93 | char ch = *in++; 94 | if (ch >= '0' && ch <= '9') digit = ch - '0'; 95 | else if (ch >= 'A' && ch <= 'F') digit = ch - 'A' + 10; 96 | else if (ch >= 'a' && ch <= 'f') digit = ch - 'a' + 10; 97 | else continue; 98 | value = value * 16 + digit; 99 | ++nibble; 100 | if (nibble >= 4) { 101 | str += QChar((ushort)value); 102 | nibble = 0; 103 | value = 0; 104 | } 105 | } 106 | 107 | } else { 108 | // Regular 437-encoded string. 109 | while (length-- > 0) str += QChar((quint32)cp437ToUnicode[*in++ & 0xFF]); 110 | } 111 | return str; 112 | } 113 | 114 | QByteArray codec_cp437::convertFromUnicode(const QChar *in, int length, ConverterState *state) const 115 | { 116 | Q_UNUSED(state) 117 | 118 | QByteArray result; 119 | quint32 ch; 120 | char *out; 121 | 122 | // Determine if the string should be encoded using the UCS-2 hack. 123 | bool non437 = false; 124 | for (qint32 posn = 0; !non437 && posn < length; ++posn) { 125 | ch = in[posn].unicode(); 126 | if (ch >= 0x0100) non437 = true; 127 | else if (cp437FromUnicode[ch] == '?' && ch != '?') non437 = true; 128 | } 129 | if (non437) { 130 | // There is a non CP437 character in this string, so use UCS-2. 131 | result.resize(length * 4 + 6); 132 | out = result.data(); 133 | *out++ = '8'; 134 | *out++ = '0'; 135 | while (length-- > 0) { 136 | quint32 ch = in->unicode(); 137 | ++in; 138 | *out++ = hexchars[(ch >> 12) & 0x0F]; 139 | *out++ = hexchars[(ch >> 8) & 0x0F]; 140 | *out++ = hexchars[(ch >> 4) & 0x0F]; 141 | *out++ = hexchars[ch & 0x0F]; 142 | } 143 | *out++ = 'F'; 144 | *out++ = 'F'; 145 | *out++ = 'F'; 146 | *out = 'F'; 147 | return result; 148 | } 149 | 150 | // If we get here, we can guarantee that the string only contains 151 | // valid CP437 code points between 0x0000 and 0x00FF. 152 | result.resize(length); 153 | out = result.data(); 154 | while (length-- > 0) { 155 | *out++ = (char)cp437FromUnicode[in->unicode()]; 156 | ++in; 157 | } 158 | return result; 159 | } 160 | #endif 161 | -------------------------------------------------------------------------------- /dialogviewcolors.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020-2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #include "dialogviewcolors.h" 22 | 23 | #include "ui_dialogviewcolors.h" 24 | 25 | DialogViewColors::DialogViewColors(QWidget *pParent) : XShortcutsDialog(pParent, false), ui(new Ui::DialogViewColors) 26 | { 27 | ui->setupUi(this); 28 | 29 | m_pOptions = nullptr; 30 | } 31 | 32 | DialogViewColors::~DialogViewColors() 33 | { 34 | delete ui; 35 | } 36 | 37 | void DialogViewColors::adjustView() 38 | { 39 | } 40 | 41 | void DialogViewColors::setOptions(XOptions *pOptions, const QList &listRecords, const QString &sTitle) 42 | { 43 | m_pOptions = pOptions; 44 | 45 | qint32 nNumberOfRecords = listRecords.count(); 46 | 47 | ui->tableWidgetColors->clear(); 48 | 49 | ui->tableWidgetColors->setColumnCount(6); 50 | ui->tableWidgetColors->setRowCount(nNumberOfRecords); 51 | 52 | for (qint32 i = 0; i < nNumberOfRecords; i++) { 53 | addRecord(i, listRecords.at(i)); 54 | } 55 | 56 | // ui->tableWidgetColors->setColumnWidth(COLUMN_TEXT_COLOR,80); 57 | ui->tableWidgetColors->setColumnWidth(COLUMN_TEXT_COLOR_REMOVE, 20); 58 | // ui->tableWidgetColors->setColumnWidth(COLUMN_BACKGROUND_COLOR,80); 59 | ui->tableWidgetColors->setColumnWidth(COLUMN_BACKGROUND_COLOR_REMOVE, 20); 60 | 61 | setWindowTitle(sTitle); 62 | } 63 | 64 | void DialogViewColors::save() 65 | { 66 | QMapIterator iter(m_mapColors); 67 | 68 | while (iter.hasNext()) { 69 | iter.next(); 70 | 71 | XOptions::ID id = iter.key(); 72 | QString sValue = iter.value(); 73 | 74 | m_pOptions->setValue(id, sValue); 75 | } 76 | } 77 | 78 | void DialogViewColors::on_pushButtonCancel_clicked() 79 | { 80 | this->close(); 81 | } 82 | 83 | void DialogViewColors::addRecord(qint32 nRow, const QString &sGroup, const QString &sText, XOptions::ID id) 84 | { 85 | QPushButton *pButtonColor = new QPushButton; 86 | pButtonColor->setText(tr("Color")); 87 | pButtonColor->setProperty("ROW", nRow); 88 | pButtonColor->setProperty("COLUMN", COLUMN_TEXT_COLOR); 89 | pButtonColor->setProperty("ID", id); 90 | 91 | connect(pButtonColor, SIGNAL(clicked(bool)), this, SLOT(pushButtonSlot())); 92 | 93 | ui->tableWidgetColors->setCellWidget(nRow, COLUMN_TEXT_COLOR, pButtonColor); 94 | 95 | QPushButton *pButtonColorRemove = new QPushButton; 96 | pButtonColorRemove->setText(QString("X")); 97 | pButtonColorRemove->setProperty("ROW", nRow); 98 | pButtonColorRemove->setProperty("COLUMN", COLUMN_TEXT_COLOR_REMOVE); 99 | pButtonColorRemove->setProperty("ID", id); 100 | 101 | connect(pButtonColorRemove, SIGNAL(clicked(bool)), this, SLOT(pushButtonSlot())); 102 | 103 | ui->tableWidgetColors->setCellWidget(nRow, COLUMN_TEXT_COLOR_REMOVE, pButtonColorRemove); 104 | 105 | QPushButton *pButtonBackgroundColor = new QPushButton; 106 | pButtonBackgroundColor->setText(tr("Background")); 107 | pButtonBackgroundColor->setProperty("ROW", nRow); 108 | pButtonBackgroundColor->setProperty("COLUMN", COLUMN_BACKGROUND_COLOR); 109 | pButtonBackgroundColor->setProperty("ID", id); 110 | 111 | connect(pButtonBackgroundColor, SIGNAL(clicked(bool)), this, SLOT(pushButtonSlot())); 112 | 113 | ui->tableWidgetColors->setCellWidget(nRow, COLUMN_BACKGROUND_COLOR, pButtonBackgroundColor); 114 | 115 | QPushButton *pButtonBackgroundColorRemove = new QPushButton; 116 | pButtonBackgroundColorRemove->setText(QString("X")); 117 | pButtonBackgroundColorRemove->setProperty("ROW", nRow); 118 | pButtonBackgroundColorRemove->setProperty("COLUMN", COLUMN_BACKGROUND_COLOR_REMOVE); 119 | pButtonBackgroundColorRemove->setProperty("ID", id); 120 | 121 | connect(pButtonBackgroundColorRemove, SIGNAL(clicked(bool)), this, SLOT(pushButtonSlot())); 122 | 123 | ui->tableWidgetColors->setItem(nRow, COLUMN_GROUP, new QTableWidgetItem(sGroup)); 124 | 125 | ui->tableWidgetColors->setCellWidget(nRow, COLUMN_BACKGROUND_COLOR_REMOVE, pButtonBackgroundColorRemove); 126 | 127 | QLineEdit *pLineEdit = new QLineEdit; 128 | pLineEdit->setText(sText); 129 | pLineEdit->setProperty("ROW", nRow); 130 | pLineEdit->setProperty("COLUMN", COLUMN_STRING); 131 | pLineEdit->setProperty("ID", id); 132 | pLineEdit->setReadOnly(true); 133 | 134 | ui->tableWidgetColors->setCellWidget(nRow, COLUMN_STRING, pLineEdit); 135 | 136 | m_mapColors.insert(id, m_pOptions->getValue(id).toString()); 137 | 138 | updateRow(nRow); 139 | } 140 | 141 | void DialogViewColors::addRecord(qint32 nRow, const RECORD &record) 142 | { 143 | addRecord(nRow, record.sGroup, record.sText, record.id); 144 | } 145 | 146 | void DialogViewColors::updateRow(qint32 nRow) 147 | { 148 | XOptions::ID id = (XOptions::ID)(ui->tableWidgetColors->cellWidget(nRow, COLUMN_TEXT_COLOR)->property("ID").toUInt()); 149 | 150 | QString sColor = m_mapColors.value(id); 151 | QString sTextColor = sColor.section("|", 0, 0); 152 | QString sBackgroundColor = sColor.section("|", 1, 1); 153 | 154 | QLineEdit *pLineEdit = (QLineEdit *)(ui->tableWidgetColors->cellWidget(nRow, COLUMN_STRING)); 155 | 156 | pLineEdit->setStyleSheet(QString("color: %1; background-color: %2").arg(sTextColor, sBackgroundColor)); 157 | 158 | ((QPushButton *)(ui->tableWidgetColors->cellWidget(nRow, COLUMN_TEXT_COLOR_REMOVE)))->setEnabled(sTextColor != ""); 159 | ((QPushButton *)(ui->tableWidgetColors->cellWidget(nRow, COLUMN_BACKGROUND_COLOR_REMOVE)))->setEnabled(sBackgroundColor != ""); 160 | } 161 | 162 | void DialogViewColors::on_pushButtonOK_clicked() 163 | { 164 | save(); 165 | 166 | this->close(); 167 | } 168 | 169 | void DialogViewColors::pushButtonSlot() 170 | { 171 | QPushButton *pPushButton = qobject_cast(sender()); 172 | 173 | if (pPushButton) { 174 | qint32 nRow = pPushButton->property("ROW").toInt(); 175 | qint32 nColumn = pPushButton->property("COLUMN").toInt(); 176 | XOptions::ID id = (XOptions::ID)(pPushButton->property("ID").toUInt()); 177 | 178 | QString sColor = m_mapColors.value(id); 179 | QString sTextColor = sColor.section("|", 0, 0); 180 | QString sBackgroundColor = sColor.section("|", 1, 1); 181 | 182 | if (nColumn == COLUMN_TEXT_COLOR) { 183 | QColor color; 184 | color.setNamedColor(sTextColor); 185 | 186 | color = XOptions::getColorDialog(this, tr("Color"), color); 187 | 188 | sTextColor = color.name(); 189 | } else if (nColumn == COLUMN_BACKGROUND_COLOR) { 190 | QColor color; 191 | color.setNamedColor(sBackgroundColor); 192 | 193 | color = XOptions::getColorDialog(this, tr("Background"), color); 194 | 195 | sBackgroundColor = color.name(); 196 | } else if (nColumn == COLUMN_TEXT_COLOR_REMOVE) { 197 | sTextColor = ""; 198 | } else if (nColumn == COLUMN_BACKGROUND_COLOR_REMOVE) { 199 | sBackgroundColor = ""; 200 | } 201 | 202 | if ((sTextColor != "") || (sBackgroundColor != "")) { 203 | sColor = QString("%1|%2").arg(sTextColor, sBackgroundColor); 204 | } else { 205 | sColor = ""; 206 | } 207 | 208 | m_mapColors.insert(id, sColor); 209 | 210 | updateRow(nRow); 211 | } 212 | } 213 | 214 | void DialogViewColors::registerShortcuts(bool bState) 215 | { 216 | Q_UNUSED(bState) 217 | } 218 | -------------------------------------------------------------------------------- /xoptionswidget.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020-2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #include "xoptionswidget.h" 22 | 23 | #include "ui_xoptionswidget.h" 24 | 25 | XOptionsWidget::XOptionsWidget(QWidget *pParent) : XShortcutsWidget(pParent), ui(new Ui::XOptionsWidget) 26 | { 27 | ui->setupUi(this); 28 | 29 | m_pParent = pParent; 30 | m_pOptions = nullptr; 31 | m_sApplicationDisplayName = ""; 32 | 33 | connect(this, SIGNAL(saveSignal()), this, SLOT(save()), Qt::DirectConnection); 34 | connect(this, SIGNAL(reloadSignal()), this, SLOT(reload()), Qt::DirectConnection); 35 | 36 | #ifdef Q_OS_WIN 37 | m_userRole = XOptions::USERROLE_NORMAL; 38 | #endif 39 | } 40 | 41 | XOptionsWidget::~XOptionsWidget() 42 | { 43 | delete ui; 44 | } 45 | 46 | void XOptionsWidget::adjustView() 47 | { 48 | getGlobalOptions()->adjustWidget(this, XOptions::ID_VIEW_FONT_CONTROLS); 49 | XShortcutsWidget::adjustViewChildren(this); 50 | } 51 | 52 | void XOptionsWidget::setGlobal(XShortcuts *pShortcuts, XOptions *pXOptions) 53 | { 54 | XShortcutsWidget::setGlobal(pShortcuts, pXOptions); 55 | XShortcutsWidget::setGlobalChildren(this, pShortcuts, pXOptions); 56 | } 57 | 58 | void XOptionsWidget::setOptions(XOptions *pOptions, const QString &sApplicationDisplayName) 59 | { 60 | m_pOptions = pOptions; 61 | m_sApplicationDisplayName = sApplicationDisplayName; 62 | 63 | if (m_pOptions->isGroupIDPresent(XOptions::GROUPID_VIEW)) { 64 | addListRecord(tr("Appearance"), 0); 65 | ui->pageView->setProperty("GROUPID", XOptions::GROUPID_VIEW); 66 | } 67 | 68 | if (m_pOptions->isGroupIDPresent(XOptions::GROUPID_FILE)) { 69 | addListRecord(tr("File"), 1); 70 | ui->pageFile->setProperty("GROUPID", XOptions::GROUPID_FILE); 71 | } 72 | 73 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_CONTROLS) || m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_TABLEVIEWS) || 74 | m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_TREEVIEWS) || m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_TEXTEDITS)) { 75 | addListRecord(tr("Fonts"), 2); 76 | ui->pageFile->setProperty("GROUPID", XOptions::GROUPID_FONTS); 77 | } 78 | 79 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_READBUFFERSIZE) || m_pOptions->isIDPresent(XOptions::ID_FEATURE_FILEBUFFERSIZE) || 80 | m_pOptions->isIDPresent(XOptions::ID_FEATURE_SSE2) || m_pOptions->isIDPresent(XOptions::ID_FEATURE_AVX) || m_pOptions->isIDPresent(XOptions::ID_FEATURE_AVX2)) { 81 | addListRecord(tr("Features"), 3); 82 | ui->pageFile->setProperty("GROUPID", XOptions::GROUPID_FEATURES); 83 | } 84 | 85 | reload(); 86 | } 87 | 88 | void XOptionsWidget::addListRecord(const QString &sTitle, qint32 nIndex) 89 | { 90 | QListWidgetItem *pItem = new QListWidgetItem; 91 | 92 | pItem->setText(sTitle); 93 | pItem->setData(Qt::UserRole, nIndex); 94 | 95 | ui->listWidgetOptions->addItem(pItem); 96 | 97 | XOptions::adjustListWidgetSize(ui->listWidgetOptions); 98 | } 99 | 100 | void XOptionsWidget::addPage(QWidget *pWidget, const QString &sTitle) 101 | { 102 | qint32 nIndex = ui->stackedWidgetOptions->addWidget(pWidget); 103 | 104 | addListRecord(sTitle, nIndex); 105 | 106 | connect(this, SIGNAL(saveSignal()), pWidget, SLOT(save()), Qt::DirectConnection); 107 | connect(this, SIGNAL(reloadSignal()), pWidget, SLOT(reload()), Qt::DirectConnection); 108 | } 109 | 110 | void XOptionsWidget::setCurrentPage(qint32 nPage) 111 | { 112 | if (nPage < ui->listWidgetOptions->count()) { 113 | ui->listWidgetOptions->setCurrentRow(nPage); 114 | } 115 | } 116 | 117 | void XOptionsWidget::setCurrentPage(XOptions::GROUPID groupId) 118 | { 119 | if (groupId != XOptions::GROUPID_UNKNOWN) { 120 | qint32 nNumberOfPages = ui->stackedWidgetOptions->count(); 121 | qint32 nNumberOfLists = ui->listWidgetOptions->count(); 122 | 123 | for (qint32 i = 0; i < nNumberOfPages; i++) { 124 | if (ui->stackedWidgetOptions->widget(i)->property("GROUPID").toUInt() == groupId) { 125 | for (qint32 j = 0; j < nNumberOfLists; j++) { 126 | qint32 nIndex = ui->listWidgetOptions->item(j)->data(Qt::UserRole).toInt(); 127 | 128 | if (nIndex == i) { 129 | ui->listWidgetOptions->setCurrentRow(j); 130 | 131 | break; 132 | } 133 | } 134 | 135 | break; 136 | } 137 | } 138 | } 139 | } 140 | 141 | void XOptionsWidget::reloadData(bool bSaveSelection) 142 | { 143 | Q_UNUSED(bSaveSelection) 144 | reload(); 145 | } 146 | 147 | void XOptionsWidget::save() 148 | { 149 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_STAYONTOP)) { 150 | m_pOptions->getCheckBox(ui->checkBoxViewStayOnTop, XOptions::ID_VIEW_STAYONTOP); 151 | } 152 | 153 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_SINGLEAPPLICATION)) { 154 | m_pOptions->getCheckBox(ui->checkBoxViewSingleApplication, XOptions::ID_VIEW_SINGLEAPPLICATION); 155 | } 156 | 157 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_STYLE)) { 158 | m_pOptions->getComboBox(ui->comboBoxViewStyle, XOptions::ID_VIEW_STYLE); 159 | } 160 | 161 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_QSS)) { 162 | m_pOptions->getComboBox(ui->comboBoxViewQss, XOptions::ID_VIEW_QSS); 163 | } 164 | 165 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_LANG)) { 166 | m_pOptions->getComboBox(ui->comboBoxViewLanguage, XOptions::ID_VIEW_LANG); 167 | } 168 | 169 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_SHOWLOGO)) { 170 | m_pOptions->getCheckBox(ui->checkBoxViewShowLogo, XOptions::ID_VIEW_SHOWLOGO); 171 | } 172 | 173 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_CONTROLS)) { 174 | m_pOptions->getLineEdit(ui->lineEditViewFontControls, XOptions::ID_VIEW_FONT_CONTROLS); 175 | } 176 | 177 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_TABLEVIEWS)) { 178 | m_pOptions->getLineEdit(ui->lineEditViewFontTables, XOptions::ID_VIEW_FONT_TABLEVIEWS); 179 | } 180 | 181 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_TREEVIEWS)) { 182 | m_pOptions->getLineEdit(ui->lineEditViewFontTrees, XOptions::ID_VIEW_FONT_TREEVIEWS); 183 | } 184 | 185 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_TEXTEDITS)) { 186 | m_pOptions->getLineEdit(ui->lineEditViewFontTextEdits, XOptions::ID_VIEW_FONT_TEXTEDITS); 187 | } 188 | 189 | if (m_pOptions->isIDPresent(XOptions::ID_HEX_FONT)) { 190 | m_pOptions->getLineEdit(ui->lineEditHexFont, XOptions::ID_HEX_FONT); 191 | } 192 | 193 | if (m_pOptions->isIDPresent(XOptions::ID_DISASM_FONT)) { 194 | m_pOptions->getLineEdit(ui->lineEditDisasmFont, XOptions::ID_DISASM_FONT); 195 | } 196 | 197 | if (m_pOptions->isIDPresent(XOptions::ID_FILE_SAVELASTDIRECTORY)) { 198 | m_pOptions->getCheckBox(ui->checkBoxFileSaveLastDirectory, XOptions::ID_FILE_SAVELASTDIRECTORY); 199 | } 200 | 201 | if (m_pOptions->isIDPresent(XOptions::ID_FILE_SAVEBACKUP)) { 202 | m_pOptions->getCheckBox(ui->checkBoxFileSaveBackup, XOptions::ID_FILE_SAVEBACKUP); 203 | } 204 | 205 | if (m_pOptions->isIDPresent(XOptions::ID_FILE_SAVERECENTFILES)) { 206 | m_pOptions->getCheckBox(ui->checkBoxFileSaveHistory, XOptions::ID_FILE_SAVERECENTFILES); 207 | } 208 | #ifdef Q_OS_WIN 209 | if (m_pOptions->isIDPresent(XOptions::ID_FILE_SETENV)) { 210 | m_pOptions->getCheckBox(ui->checkBoxFileSetEnvVar, XOptions::ID_FILE_SETENV); 211 | 212 | QString appDir = QFileInfo(QCoreApplication::applicationFilePath()).absolutePath(); 213 | QString formattedDir = QDir::toNativeSeparators(appDir); 214 | 215 | if (ui->checkBoxFileSetEnvVar->isChecked()) { 216 | m_pOptions->appendToUserPathVariable(formattedDir); 217 | } else { 218 | m_pOptions->removeFromUserPathVariable(formattedDir); 219 | } 220 | } 221 | #endif 222 | 223 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_READBUFFERSIZE)) { 224 | m_pOptions->getComboBox(ui->comboBoxReadBufferSize, XOptions::ID_FEATURE_READBUFFERSIZE); 225 | } 226 | 227 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_FILEBUFFERSIZE)) { 228 | m_pOptions->getComboBox(ui->comboBoxFileBufferSize, XOptions::ID_FEATURE_FILEBUFFERSIZE); 229 | } 230 | 231 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_SSE2)) { 232 | m_pOptions->getCheckBox(ui->checkBoxSSE2, XOptions::ID_FEATURE_SSE2); 233 | } 234 | 235 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_AVX)) { 236 | m_pOptions->getCheckBox(ui->checkBoxAVX, XOptions::ID_FEATURE_AVX); 237 | } 238 | 239 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_AVX2)) { 240 | m_pOptions->getCheckBox(ui->checkBoxAVX2, XOptions::ID_FEATURE_AVX2); 241 | } 242 | 243 | m_pOptions->save(); 244 | } 245 | 246 | void XOptionsWidget::reload() 247 | { 248 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_STAYONTOP)) { 249 | m_pOptions->setCheckBox(ui->checkBoxViewStayOnTop, XOptions::ID_VIEW_STAYONTOP); 250 | } else { 251 | ui->checkBoxViewStayOnTop->hide(); 252 | } 253 | 254 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_SINGLEAPPLICATION)) { 255 | m_pOptions->setCheckBox(ui->checkBoxViewSingleApplication, XOptions::ID_VIEW_SINGLEAPPLICATION); 256 | } else { 257 | ui->checkBoxViewSingleApplication->hide(); 258 | } 259 | 260 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_STYLE)) { 261 | m_pOptions->setComboBox(ui->comboBoxViewStyle, XOptions::ID_VIEW_STYLE); 262 | } else { 263 | ui->groupBoxViewStyle->hide(); 264 | } 265 | 266 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_QSS)) { 267 | m_pOptions->setComboBox(ui->comboBoxViewQss, XOptions::ID_VIEW_QSS); 268 | } else { 269 | ui->groupBoxViewQss->hide(); 270 | } 271 | 272 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_LANG)) { 273 | m_pOptions->setComboBox(ui->comboBoxViewLanguage, XOptions::ID_VIEW_LANG); 274 | } else { 275 | ui->groupBoxViewLanguage->hide(); 276 | } 277 | 278 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_SHOWLOGO)) { 279 | m_pOptions->setCheckBox(ui->checkBoxViewShowLogo, XOptions::ID_VIEW_SHOWLOGO); 280 | } else { 281 | ui->checkBoxViewShowLogo->hide(); 282 | } 283 | 284 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_CONTROLS)) { 285 | m_pOptions->setLineEdit(ui->lineEditViewFontControls, XOptions::ID_VIEW_FONT_CONTROLS); 286 | } else { 287 | ui->groupBoxViewFontControls->hide(); 288 | } 289 | 290 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_TEXTEDITS)) { 291 | m_pOptions->setLineEdit(ui->lineEditViewFontTextEdits, XOptions::ID_VIEW_FONT_TEXTEDITS); 292 | } else { 293 | ui->groupBoxViewFontTextEdits->hide(); 294 | } 295 | 296 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_TABLEVIEWS)) { 297 | m_pOptions->setLineEdit(ui->lineEditViewFontTables, XOptions::ID_VIEW_FONT_TABLEVIEWS); 298 | } else { 299 | ui->groupBoxViewFontTables->hide(); 300 | } 301 | 302 | if (m_pOptions->isIDPresent(XOptions::ID_VIEW_FONT_TREEVIEWS)) { 303 | m_pOptions->setLineEdit(ui->lineEditViewFontTrees, XOptions::ID_VIEW_FONT_TREEVIEWS); 304 | } else { 305 | ui->groupBoxViewFontTrees->hide(); 306 | } 307 | if (m_pOptions->isIDPresent(XOptions::ID_HEX_FONT)) { 308 | m_pOptions->setLineEdit(ui->lineEditHexFont, XOptions::ID_HEX_FONT); 309 | } else { 310 | ui->groupBoxHexFont->hide(); 311 | } 312 | 313 | if (m_pOptions->isIDPresent(XOptions::ID_DISASM_FONT)) { 314 | m_pOptions->setLineEdit(ui->lineEditDisasmFont, XOptions::ID_DISASM_FONT); 315 | } else { 316 | ui->groupBoxDisasmFont->hide(); 317 | } 318 | 319 | if (m_pOptions->isIDPresent(XOptions::ID_FILE_SAVELASTDIRECTORY)) { 320 | m_pOptions->setCheckBox(ui->checkBoxFileSaveLastDirectory, XOptions::ID_FILE_SAVELASTDIRECTORY); 321 | } else { 322 | ui->checkBoxFileSaveLastDirectory->hide(); 323 | } 324 | 325 | if (m_pOptions->isIDPresent(XOptions::ID_FILE_SAVEBACKUP)) { 326 | m_pOptions->setCheckBox(ui->checkBoxFileSaveBackup, XOptions::ID_FILE_SAVEBACKUP); 327 | } else { 328 | ui->checkBoxFileSaveBackup->hide(); 329 | } 330 | 331 | if (m_pOptions->isIDPresent(XOptions::ID_FILE_SAVERECENTFILES)) { 332 | m_pOptions->setCheckBox(ui->checkBoxFileSaveHistory, XOptions::ID_FILE_SAVERECENTFILES); 333 | } else { 334 | ui->checkBoxFileSaveHistory->hide(); 335 | } 336 | 337 | if (m_pOptions->isIDPresent(XOptions::ID_FILE_CONTEXT)) { 338 | #ifdef Q_OS_WIN 339 | // bool bAdmin = m_pOptions->checkContext(m_sApplicationDisplayName, m_pOptions->getValue(XOptions::ID_FILE_CONTEXT).toString(), XOptions::USERROLE_ADMIN); 340 | // bool bUser = m_pOptions->checkContext(m_sApplicationDisplayName, m_pOptions->getValue(XOptions::ID_FILE_CONTEXT).toString(), XOptions::USERROLE_NORMAL); 341 | 342 | // if (bAdmin && 343 | // (!bUser)) { 344 | // m_userRole = XOptions::USERROLE_ADMIN; 345 | // } 346 | ui->checkBoxFileContext->setChecked(m_pOptions->checkContext(m_sApplicationDisplayName, m_pOptions->getValue(XOptions::ID_FILE_CONTEXT).toString(), m_userRole)); 347 | 348 | // Check if application directory is present in system PATH 349 | QString appDir = QFileInfo(QCoreApplication::applicationFilePath()).absolutePath(); 350 | QString formattedDir = QDir::toNativeSeparators(appDir); 351 | 352 | ui->checkBoxFileSetEnvVar->setChecked(m_pOptions->isPathInUserEnvironment(formattedDir)); 353 | #endif 354 | } else { 355 | ui->checkBoxFileContext->hide(); 356 | ui->checkBoxFileSetEnvVar->hide(); 357 | } 358 | 359 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_READBUFFERSIZE)) { 360 | m_pOptions->setComboBox(ui->comboBoxReadBufferSize, XOptions::ID_FEATURE_READBUFFERSIZE); 361 | } else { 362 | ui->comboBoxReadBufferSize->hide(); 363 | } 364 | 365 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_FILEBUFFERSIZE)) { 366 | m_pOptions->setComboBox(ui->comboBoxFileBufferSize, XOptions::ID_FEATURE_FILEBUFFERSIZE); 367 | } else { 368 | ui->comboBoxFileBufferSize->hide(); 369 | } 370 | 371 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_SSE2)) { 372 | m_pOptions->setCheckBox(ui->checkBoxSSE2, XOptions::ID_FEATURE_SSE2); 373 | #ifdef USE_XSIMD 374 | if (!xsimd_is_sse2_present()) { 375 | ui->checkBoxSSE2->hide(); 376 | } 377 | #endif 378 | } else { 379 | ui->checkBoxSSE2->hide(); 380 | } 381 | 382 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_AVX)) { 383 | m_pOptions->setCheckBox(ui->checkBoxAVX, XOptions::ID_FEATURE_AVX); 384 | #ifdef USE_XSIMD 385 | if (!xsimd_is_avx_present()) { 386 | ui->checkBoxAVX->hide(); 387 | } 388 | #endif 389 | } else { 390 | ui->checkBoxAVX->hide(); 391 | } 392 | 393 | if (m_pOptions->isIDPresent(XOptions::ID_FEATURE_AVX2)) { 394 | m_pOptions->setCheckBox(ui->checkBoxAVX2, XOptions::ID_FEATURE_AVX2); 395 | #ifdef USE_XSIMD 396 | if (!xsimd_is_avx2_present()) { 397 | ui->checkBoxAVX2->hide(); 398 | } 399 | #endif 400 | } else { 401 | ui->checkBoxAVX2->hide(); 402 | } 403 | } 404 | 405 | void XOptionsWidget::on_listWidgetOptions_currentRowChanged(int nCurrentRow) 406 | { 407 | if (nCurrentRow < ui->stackedWidgetOptions->count()) { 408 | qint32 nIndex = ui->listWidgetOptions->item(nCurrentRow)->data(Qt::UserRole).toInt(); 409 | ui->stackedWidgetOptions->setCurrentIndex(nIndex); 410 | } 411 | } 412 | 413 | void XOptionsWidget::on_checkBoxFileContext_toggled(bool bChecked) 414 | { 415 | if (m_pOptions->isIDPresent(XOptions::ID_FILE_CONTEXT)) { 416 | #ifdef Q_OS_WIN 417 | if (m_pOptions->checkContext(m_sApplicationDisplayName, m_pOptions->getValue(XOptions::ID_FILE_CONTEXT).toString(), m_userRole) != bChecked) { 418 | bool bSuccess = false; 419 | 420 | if (bChecked) { 421 | bSuccess = m_pOptions->registerContext(m_sApplicationDisplayName, m_pOptions->getValue(XOptions::ID_FILE_CONTEXT).toString(), qApp->applicationFilePath(), 422 | m_userRole); 423 | } else { 424 | bSuccess = m_pOptions->clearContext(m_sApplicationDisplayName, m_pOptions->getValue(XOptions::ID_FILE_CONTEXT).toString(), m_userRole); 425 | } 426 | 427 | if (!bSuccess) { 428 | QMessageBox::critical(this, tr("Error"), tr("Please run the program as an administrator")); 429 | 430 | ui->checkBoxFileContext->setChecked(!bChecked); 431 | } 432 | } 433 | #else 434 | Q_UNUSED(bChecked) 435 | #endif 436 | } 437 | } 438 | 439 | void XOptionsWidget::on_checkBoxFileSetEnvVar_toggled(bool bChecked) 440 | { 441 | #ifdef Q_OS_WIN 442 | QString appDir = QFileInfo(QCoreApplication::applicationFilePath()).absolutePath(); 443 | QString formattedDir = QDir::toNativeSeparators(appDir); 444 | 445 | bool bIsSet = m_pOptions->isPathInUserEnvironment(formattedDir); 446 | 447 | if (bChecked) { 448 | if (!bIsSet) { 449 | m_pOptions->appendToUserPathVariable(formattedDir); 450 | } 451 | } else { 452 | if (bIsSet) { 453 | m_pOptions->removeFromUserPathVariable(formattedDir); 454 | } 455 | } 456 | #else 457 | Q_UNUSED(bChecked) 458 | #endif 459 | } 460 | 461 | void XOptionsWidget::on_toolButtonViewFontControls_clicked() 462 | { 463 | XOptions::handleFontButton(this, ui->lineEditViewFontControls); 464 | } 465 | 466 | void XOptionsWidget::on_toolButtonViewFontTables_clicked() 467 | { 468 | XOptions::handleFontButton(this, ui->lineEditViewFontTables); 469 | } 470 | 471 | void XOptionsWidget::on_toolButtonViewFontTrees_clicked() 472 | { 473 | XOptions::handleFontButton(this, ui->lineEditViewFontTrees); 474 | } 475 | 476 | void XOptionsWidget::on_toolButtonHexFont_clicked() 477 | { 478 | XOptions::handleFontButton(this, ui->lineEditHexFont); 479 | } 480 | 481 | void XOptionsWidget::on_toolButtonDisasmFont_clicked() 482 | { 483 | XOptions::handleFontButton(this, ui->lineEditDisasmFont); 484 | } 485 | 486 | void XOptionsWidget::on_toolButtonViewFontTextEdits_clicked() 487 | { 488 | XOptions::handleFontButton(this, ui->lineEditViewFontTextEdits); 489 | } 490 | 491 | void XOptionsWidget::on_pushButtonDefault_clicked() 492 | { 493 | m_pOptions->resetToDefault(); 494 | 495 | emit reloadSignal(); 496 | } 497 | 498 | void XOptionsWidget::on_pushButtonOK_clicked() 499 | { 500 | emit saveSignal(); 501 | 502 | if (m_pOptions->isRestartNeeded()) { 503 | QMessageBox::information(this, tr("Information"), tr("Please restart the application")); 504 | } 505 | 506 | m_pParent->close(); 507 | } 508 | 509 | void XOptionsWidget::on_pushButtonCancel_clicked() 510 | { 511 | m_pParent->close(); 512 | } 513 | 514 | void XOptionsWidget::registerShortcuts(bool bState) 515 | { 516 | Q_UNUSED(bState) 517 | } 518 | 519 | void XOptionsWidget::on_checkBoxSSE2_toggled(bool bChecked) 520 | { 521 | #ifdef USE_XSIMD 522 | if (bChecked) { 523 | if (!xsimd_is_sse2_present()) { 524 | ui->checkBoxSSE2->setChecked(false); 525 | return; 526 | } 527 | xsimd_set_sse2(1); 528 | } else { 529 | xsimd_set_sse2(0); 530 | } 531 | #else 532 | Q_UNUSED(bChecked) 533 | #endif 534 | } 535 | 536 | void XOptionsWidget::on_checkBoxAVX_toggled(bool bChecked) 537 | { 538 | #ifdef USE_XSIMD 539 | if (bChecked) { 540 | if (!xsimd_is_avx_present()) { 541 | ui->checkBoxAVX->setChecked(false); 542 | return; 543 | } 544 | xsimd_set_avx(1); 545 | } else { 546 | xsimd_set_avx(0); 547 | } 548 | #else 549 | Q_UNUSED(bChecked) 550 | #endif 551 | } 552 | 553 | void XOptionsWidget::on_checkBoxAVX2_toggled(bool bChecked) 554 | { 555 | #ifdef USE_XSIMD 556 | if (bChecked) { 557 | if (!xsimd_is_avx2_present()) { 558 | ui->checkBoxAVX2->setChecked(false); 559 | return; 560 | } 561 | xsimd_set_avx2(1); 562 | } else { 563 | xsimd_set_avx2(0); 564 | } 565 | #else 566 | Q_UNUSED(bChecked) 567 | #endif 568 | } 569 | -------------------------------------------------------------------------------- /xoptions.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020-2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #ifndef XOPTIONS_H 22 | #define XOPTIONS_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #ifdef QT_GUI_LIB 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #else 62 | #include 63 | #endif 64 | #if (QT_VERSION_MAJOR < 6) || defined(QT_CORE5COMPAT_LIB) 65 | #include 66 | #include "codecs/codec_cp437.h" 67 | #endif 68 | #if defined(Q_OS_FREEBSD) 69 | #include 70 | #endif 71 | #ifdef Q_OS_WIN 72 | #include 73 | #include 74 | #endif 75 | 76 | #ifdef USE_XSIMD 77 | #include "xsimd.h" 78 | #endif 79 | 80 | typedef quint64 XVPOS; 81 | 82 | class XOptions : public QObject { 83 | Q_OBJECT 84 | 85 | public: 86 | // TODO: Check if update available 87 | // TODO: Show in dialog all available updates 88 | // Ubuntu -> Ubuntu + Debian + appImage 89 | // Debian -> Debian + appImage 90 | // Parrot -> Parrot + Debian + appImage 91 | // MX Linux -> MX Linux + Debian + appImage 92 | // Linux X64 -> appImage 93 | // Windows 64 -> Windows 32 + Windows 64 + Windows XP 94 | // Windows 32 -> Windows 32 + Windows XP 95 | // Windows XP -> Windows XP 96 | // MacOS M1 -> MacOS M1 + MacOS X64 97 | // MacOS X64 -> MacOS X64 98 | // TODO: Linux ARM types 32, old ARM? Check 99 | // TODO: Check other BSD 100 | // TODO: Check Windows ARM 101 | enum BUNDLE { 102 | BUNDLE_UNKNOWN = 0, 103 | BUNDLE_LINUX_ARCH_X64, 104 | BUNDLE_WINDOWS_QT6_X64, 105 | BUNDLE_LINUX_APPIMAGE_X64, 106 | BUNDLE_LINUX_DEBIAN_X64, 107 | BUNDLE_LINUX_DEBIAN_X86, 108 | BUNDLE_LINUX_DEBIAN_ARM64, 109 | BUNDLE_LINUX_UBUNTU_X64, 110 | BUNDLE_LINUX_UBUNTU_ARM64, 111 | BUNDLE_LINUX_PARROT_X64, 112 | BUNDLE_LINUX_KALI_X64, 113 | BUNDLE_WINDOWS_XP_X86, 114 | BUNDLE_WINDOWS_X86, 115 | BUNDLE_WINDOWS_X64, 116 | BUNDLE_WINDOWS_ARM64, 117 | BUNDLE_MACOS_X64, 118 | BUNDLE_MACOS_QT6_ARM64, // TODO: Check 119 | BUNDLE_FREEBSD_X64, 120 | BUNDLE_FEDORA_X64 121 | // TODO: Add more BUNDLES for different operating systems! 122 | }; 123 | 124 | enum WIDGETTYPE { 125 | WIDGETTYPE_UNKNOWN = 0, 126 | WIDGETTYPE_HEX, 127 | WIDGETTYPE_DISASM, 128 | WIDGETTYPE_MEMORYMAP, 129 | WIDGETTYPE_CUSTOM 130 | }; 131 | 132 | enum CR { 133 | CR_SUCCESS = 0, 134 | CR_CANNOTFINDFILE = 1, 135 | CR_CANNOTOPENFILE = 2, 136 | CR_CANNOTFINDDATABASE = 3, 137 | CR_INVALIDPARAMETER = 4 138 | // TODO: Add more CR's 139 | }; 140 | 141 | enum GROUPID { 142 | GROUPID_UNKNOWN = 0, 143 | GROUPID_VIEW, 144 | GROUPID_EDIT, 145 | GROUPID_FILE, 146 | GROUPID_FONTS, 147 | GROUPID_FEATURES, 148 | GROUPID_SCAN, 149 | GROUPID_SIGNATURES, 150 | GROUPID_DEBUGGER, 151 | GROUPID_HEX, 152 | GROUPID_STACK, 153 | GROUPID_REGISTERS, 154 | GROUPID_DISASM, 155 | GROUPID_IODRIVER, 156 | GROUPID_STRUCTS, 157 | GROUPID_ONLINETOOLS, 158 | GROUPID_INFO, 159 | GROUPID_GITHUB 160 | }; 161 | 162 | enum ID { 163 | ID_UNKNOWN = 0, 164 | ID_ROOTPATH, 165 | ID_DATAPATH, // TODO: Create group 166 | ID_JSON, // TODO: Create group 167 | ID_STRUCTSPATH, 168 | ID_AUTHUSER, 169 | ID_AUTHTOKEN, 170 | // new 171 | ID_VIEW_STAYONTOP, 172 | ID_VIEW_STYLE, 173 | ID_VIEW_QSS, 174 | ID_VIEW_LANG, 175 | ID_VIEW_SINGLEAPPLICATION, 176 | ID_VIEW_SHOWLOGO, 177 | ID_VIEW_FONT, 178 | ID_VIEW_FONT_CONTROLS, 179 | ID_VIEW_FONT_TABLEVIEWS, 180 | ID_VIEW_FONT_TREEVIEWS, 181 | ID_VIEW_FONT_TEXTEDITS, 182 | ID_VIEW_ADVANCED, 183 | ID_VIEW_SELECTSTYLE, 184 | ID_FILE_SAVELASTDIRECTORY, 185 | ID_FILE_SAVERECENTFILES, 186 | ID_FILE_SAVEBACKUP, 187 | ID_FILE_CONTEXT, 188 | ID_FILE_PATH, 189 | ID_FEATURE_READBUFFERSIZE, 190 | ID_FEATURE_FILEBUFFERSIZE, 191 | ID_FEATURE_SSE2, 192 | ID_FEATURE_AVX, 193 | ID_FEATURE_AVX2, 194 | ID_ENGINE_BUFFERSIZE, // Obsolete 195 | ID_SCAN_BUFFERSIZE, // Obsolete 196 | ID_SCAN_SCANAFTEROPEN, 197 | ID_SCAN_FLAG_RECURSIVE, 198 | ID_SCAN_FLAG_DEEP, 199 | ID_SCAN_FLAG_HEURISTIC, 200 | ID_SCAN_FLAG_AGGRESSIVE, 201 | ID_SCAN_FLAG_VERBOSE, 202 | ID_SCAN_FLAG_ALLTYPES, 203 | ID_SCAN_USECACHE, 204 | ID_SCAN_FORMATRESULT, 205 | ID_SCAN_LOG_PROFILING, 206 | ID_SCAN_HIGHLIGHT, 207 | ID_SCAN_SORT, 208 | ID_SCAN_HIDEUNKNOWN, 209 | ID_SCAN_ENGINE, 210 | ID_SCAN_ENGINE_EMPTY, 211 | ID_SCAN_DATABASE_MAIN_PATH, 212 | ID_SCAN_DATABASE_EXTRA_PATH, 213 | ID_SCAN_DATABASE_CUSTOM_PATH, 214 | ID_SCAN_DATABASE_EXTRA_ENABLED, 215 | ID_SCAN_DATABASE_CUSTOM_ENABLED, 216 | ID_SCAN_YARARULESPATH, 217 | ID_SIGNATURES_PATH, 218 | ID_INFO_PATH, 219 | ID_ONLINETOOLS_VIRUSTOTAL_APIKEY, 220 | ID_DISASM_FONT, 221 | ID_DISASM_SYNTAX, 222 | ID_DISASM_LOCATIONCOLON, 223 | ID_DISASM_UPPERCASE, 224 | ID_DISASM_HIGHLIGHT, 225 | // TODO: Add more 226 | ID_DISASM_COLOR_ARROWS, 227 | ID_DISASM_COLOR_ARROWS_SELECTED, 228 | ID_DISASM_COLOR_REGS, 229 | ID_DISASM_COLOR_NUMBERS, 230 | ID_DISASM_COLOR_OPCODE, 231 | ID_DISASM_COLOR_REFS, 232 | ID_DISASM_COLOR_X86_REGS_GENERAL, 233 | ID_DISASM_COLOR_X86_REGS_STACK, 234 | ID_DISASM_COLOR_X86_REGS_SEGMENT, 235 | ID_DISASM_COLOR_X86_REGS_DEBUG, 236 | ID_DISASM_COLOR_X86_REGS_IP, 237 | ID_DISASM_COLOR_X86_REGS_FLAGS, 238 | ID_DISASM_COLOR_X86_REGS_FPU, 239 | ID_DISASM_COLOR_X86_REGS_XMM, 240 | ID_DISASM_COLOR_X86_REGS_YMM, 241 | ID_DISASM_COLOR_X86_REGS_ZMM, 242 | ID_DISASM_COLOR_X86_OPCODE_CALL, 243 | ID_DISASM_COLOR_X86_OPCODE_RET, 244 | ID_DISASM_COLOR_X86_OPCODE_PUSH, 245 | ID_DISASM_COLOR_X86_OPCODE_POP, 246 | ID_DISASM_COLOR_X86_OPCODE_NOP, 247 | ID_DISASM_COLOR_X86_OPCODE_JMP, 248 | ID_DISASM_COLOR_X86_OPCODE_COND_JMP, 249 | ID_DISASM_COLOR_X86_OPCODE_INT3, 250 | ID_DISASM_COLOR_X86_OPCODE_SYSCALL, 251 | ID_DISASM_COLOR_ARM_REGS_GENERAL, 252 | ID_DISASM_COLOR_ARM_REGS_STACK, 253 | ID_DISASM_COLOR_ARM_OPCODE_BRANCH, 254 | ID_DISASM_COLOR_ARM_OPCODE_BRANCHLINK, 255 | ID_DISASM_COLOR_ARM_OPCODE_RET, 256 | ID_DISASM_COLOR_ARM_OPCODE_PUSH, 257 | ID_DISASM_COLOR_ARM_OPCODE_POP, 258 | ID_DISASM_COLOR_ARM_OPCODE_NOP, 259 | ID_HEX_FONT, 260 | ID_HEX_LOCATIONCOLON, 261 | ID_STACK_FONT, 262 | ID_STACK_LOCATIONCOLON, 263 | ID_REGISTERS_FONT, 264 | ID_DEBUGGER_COLOR_BREAKPOINT, 265 | // TODO: debugger animate timeout 266 | // TODO: Add more ID's for DISASM 267 | ID_IODRIVER_FILENAME, 268 | ID_IODRIVER_SERVICENAME, 269 | ID_STRUCTS_PATH, 270 | // for internal use. 271 | ID_NU_LASTDIRECTORY, // Using if ID_SAVELASTDIRECTORY 272 | ID_NU_RECENTFILES, // Using if ID_SAVERECENTFILES 273 | ID_FILE_SETENV 274 | }; 275 | 276 | enum ICONTYPE { 277 | ICONTYPE_NONE = 0, 278 | ICONTYPE_ACTION, 279 | ICONTYPE_ADD, 280 | ICONTYPE_ADDRESS, 281 | ICONTYPE_ALL, 282 | ICONTYPE_BACKWARD, 283 | ICONTYPE_BOOKMARK, 284 | ICONTYPE_CERTIFICATE, 285 | ICONTYPE_CODE, 286 | ICONTYPE_COPY, 287 | ICONTYPE_DATA, 288 | ICONTYPE_DEBUG, 289 | ICONTYPE_DEMANGLE, 290 | ICONTYPE_DIE, 291 | ICONTYPE_DISASM, 292 | ICONTYPE_DOTNET, 293 | ICONTYPE_DUMPTOFILE, 294 | ICONTYPE_EDIT, 295 | ICONTYPE_ENTROPY, 296 | ICONTYPE_ENTRY, 297 | ICONTYPE_EXCEPTION, 298 | ICONTYPE_EXIT, 299 | ICONTYPE_EXPORT, 300 | ICONTYPE_EXTRACTOR, 301 | ICONTYPE_FILE, 302 | ICONTYPE_FOLLOW, 303 | ICONTYPE_FORWARD, 304 | ICONTYPE_FUNCTION, 305 | ICONTYPE_GENERIC, 306 | ICONTYPE_GOTO, 307 | ICONTYPE_HASH, 308 | ICONTYPE_HEADER, 309 | ICONTYPE_HEX, 310 | ICONTYPE_IMPORT, 311 | ICONTYPE_INFO, 312 | ICONTYPE_LIBRARY, 313 | ICONTYPE_LIST, 314 | ICONTYPE_MANIFEST, 315 | ICONTYPE_MEMORYMAP, 316 | ICONTYPE_METADATA, 317 | ICONTYPE_MIME, 318 | ICONTYPE_NEW, 319 | ICONTYPE_NEXT, 320 | ICONTYPE_NFD, 321 | ICONTYPE_NOTE, 322 | ICONTYPE_OFFSET, 323 | ICONTYPE_OPEN, 324 | ICONTYPE_OPTION, 325 | ICONTYPE_OVERLAY, 326 | ICONTYPE_PATCH, 327 | ICONTYPE_PATH, 328 | ICONTYPE_REFERENCE, 329 | ICONTYPE_RELOAD, 330 | ICONTYPE_RELOC, 331 | ICONTYPE_REMOVE, 332 | ICONTYPE_RESIZE, 333 | ICONTYPE_RESOURCE, 334 | ICONTYPE_SAVE, 335 | ICONTYPE_SCAN, 336 | ICONTYPE_SCRIPT, 337 | ICONTYPE_SEARCH, 338 | ICONTYPE_SECTION, 339 | ICONTYPE_SEGMENT, 340 | ICONTYPE_SELECT, 341 | ICONTYPE_SHORTCUT, 342 | ICONTYPE_SIGNATURE, 343 | ICONTYPE_SIZE, 344 | ICONTYPE_STRING, 345 | ICONTYPE_STRUCTS, 346 | ICONTYPE_SYMBOL, 347 | ICONTYPE_TABLE, 348 | ICONTYPE_TLS, 349 | ICONTYPE_TOOL, 350 | ICONTYPE_VALUE, 351 | ICONTYPE_VERSION, 352 | ICONTYPE_VIRUSTOTAL, 353 | ICONTYPE_VISUALIZATION, 354 | ICONTYPE_WEBSITE, 355 | ICONTYPE_YARA, 356 | ICONTYPE_INSPECTOR, 357 | ICONTYPE_CONVERTOR, 358 | }; 359 | 360 | struct COLOR_RECORD { 361 | QString sColorMain; 362 | QString sColorBackground; 363 | }; 364 | 365 | struct GLOBAL_COLOR_RECORD { 366 | Qt::GlobalColor colorMain; 367 | Qt::GlobalColor colorBackground; 368 | }; 369 | 370 | explicit XOptions(QObject *pParent = nullptr); 371 | 372 | void resetToDefault(); 373 | void setValueIDs(const QList &listValueIDs); 374 | void setDefaultValues(QMap mapDefaultValues); 375 | void addID(ID id, QVariant varDefaultValue = QVariant()); 376 | void removeID(ID id); 377 | GROUPID getGroupID(ID id); 378 | bool isIDPresent(ID id); 379 | bool isGroupIDPresent(GROUPID groupID); 380 | static bool isNative(); 381 | static bool isAppImage(); 382 | void setName(const QString &sValue); 383 | void load(); 384 | void save(); 385 | QVariant getValue(ID id); 386 | void setValue(ID id, QVariant varValue); 387 | void clearValue(ID id); 388 | bool isValuePresent(ID id); 389 | QVariant getDefaultValue(ID id); 390 | static QString idToString(ID id); 391 | QString getLastDirectory(); 392 | void setLastDirectory(const QString &sPathName); 393 | void setLastFileName(const QString &sFileName); 394 | QList getRecentFiles(); 395 | QString getDatabasePath(); 396 | QString getExtraDatabasePath(); 397 | QString getCustomDatabasePath(); 398 | QString getScanEngine(); 399 | QString getInfoPath(); 400 | QString getRootPath(); 401 | QString getDataPath(); 402 | QString getJson(); 403 | QString getAuthUser(); 404 | QString getAuthToken(); 405 | QString getVirusTotalApiKey(); 406 | bool isSaveBackup(); 407 | bool isSaveLastDirectory(); 408 | bool isSaveRecentFiles(); 409 | bool isRestartNeeded(); 410 | bool isStayOnTop(); // TODO: remove 411 | bool isScanAfterOpen(); 412 | bool isSingleApplication(); 413 | bool isShowLogo(); // TODO: remove 414 | QString getSearchSignaturesPath(); 415 | QString getStructsPath(); 416 | QString getApplicationLangPath(); 417 | QString getApplicationQssPath(); 418 | static QList getAllFilesFromDirectory(const QString &sDirectory, const QString &sExtension); 419 | static bool checkNative(const QString &sIniFileName); 420 | QString getApplicationDataPath(); 421 | static QString getTitle(const QString &sName, const QString &sVersion, bool bShowOS = true); 422 | bool isWritable(); 423 | static void adjustApplicationInitAttributes(); 424 | #ifdef QT_GUI_LIB 425 | void setCheckBox(QCheckBox *pCheckBox, ID id); 426 | void getCheckBox(QCheckBox *pCheckBox, ID id); 427 | void setCheckBox(QGroupBox *pGroupBox, ID id); 428 | void getCheckBox(QGroupBox *pGroupBox, ID id); 429 | void setComboBox(QComboBox *pComboBox, ID id); 430 | void getComboBox(QComboBox *pComboBox, ID id); 431 | void setLineEdit(QLineEdit *pLineEdit, ID id); 432 | void getLineEdit(QLineEdit *pLineEdit, ID id); 433 | void adjustStayOnTop(QWidget *pWidget); 434 | static void _adjustStayOnTop(QWidget *pWidget, bool bState); 435 | static bool _isAjustStayOnTop(QWidget *pWidget); 436 | static void _adjustApplicationModal(QWidget *pWidget, bool bState); 437 | static void _adjustFullScreen(QWidget *pWidget, bool bState); 438 | // mb TODO: max/min 439 | QFont adjustFont(QWidget *pWidget, ID id = ID_VIEW_FONT); 440 | void adjustWindow(QWidget *pWidget); 441 | void adjustWidget(QWidget *pWidget, ID id = ID_VIEW_FONT); 442 | void adjustTableWidget(QTableWidget *pWidget, ID id = ID_VIEW_FONT_TABLEVIEWS); 443 | void adjustTableView(QTableView *pWidget, ID id = ID_VIEW_FONT_TABLEVIEWS); 444 | void adjustTreeWidget(QTreeWidget *pWidget, ID id = ID_VIEW_FONT_TREEVIEWS, bool bAdjustSize = false); 445 | void adjustTreeView(QTreeView *pWidget, ID id = ID_VIEW_FONT_TREEVIEWS); 446 | static QFont getDefaultFont(qint32 nFontSize = -1); 447 | static QFont getMonoFont(qint32 nFontSize = -1); 448 | static void setMonoFont(QWidget *pWidget, qint32 nSize = -1); 449 | static void adjustApplicationView(const QString &sTranslationName, XOptions *pOptions); 450 | static void adjustListWidgetSize(QListWidget *pListWidget, qint32 nMinimumWidth = 100); 451 | static qint32 _getTreeWidgetItemSize(QTreeWidget *pTreeWidget, QTreeWidgetItem *pTreeWidgetItem, qint32 nIndent, qint32 nLevel); 452 | static void adjustTreeWidgetSize(QTreeWidget *pTreeWidget, qint32 nMinimumWidth = 100); 453 | // static void adjustApplicationView(const QString &sApplicationFileName, QString sTranslationName); 454 | static QWidget *getMainWidget(QWidget *pWidget); 455 | static QString getTableModelText(QAbstractItemModel *pModel); 456 | static void _getTreeModelText(QString *psString, QAbstractItemModel *pModel, QModelIndex index, qint32 nLevel); 457 | static QString getTreeModelText(QAbstractItemModel *pModel); 458 | static bool saveTableModel(QAbstractItemModel *pModel, const QString &sFileName); 459 | static bool saveTreeModel(QAbstractItemModel *pModel, const QString &sFileName); 460 | static bool saveTextEdit(QTextEdit *pTextEdit, const QString &sFileName); 461 | static bool savePlainTextEdit(QPlainTextEdit *pPlainTextEdit, const QString &sFileName); 462 | static bool saveTableView(QTableView *pTableView, const QString &sFileName); 463 | static bool saveTableWidget(QTableWidget *pTableWidget, const QString &sFileName); 464 | static bool saveListView(QListView *pListView, const QString &sFileName); 465 | static bool saveListWidget(QListWidget *pListWidget, const QString &sFileName); 466 | static bool saveTreeView(QTreeView *pTreeView, const QString &sFileName); 467 | static bool saveTreeWidget(QTreeWidget *pTreeWidget, const QString &sFileName); 468 | static bool saveTextBrowser(QTextBrowser *pTextBrowser, const QString &sFileName); 469 | static bool saveTextBrowserHtml(QTextBrowser *pTextBrowser, const QString &sFileName); 470 | QMenu *createRecentFilesMenu(QWidget *pParent); 471 | static qint32 getCharWidth(QWidget *pWidget); 472 | static qint32 getCharHeight(QWidget *pWidget); 473 | static qint32 getControlWidth(QWidget *pWidget, qint32 nSymbolSize); 474 | static void showInFolder(const QString &sFileName); 475 | static void showFolder(const QString &sDirectory); 476 | static void handleFontButton(QWidget *pParent, QLineEdit *pLineEdit); 477 | static void setModelTextAlignment(QStandardItemModel *pModel, qint32 nColumn, Qt::Alignment flag); 478 | static void setTableViewHeaderWidth(QTableView *pTableView, qint32 nColumn, qint32 nContentWidth); 479 | static void setTreeViewHeaderWidth(QTreeView *pTreeView, qint32 nColumn, qint32 nContentWidth); 480 | static void setTableWidgetHeaderAlignment(QTableWidget *pTableWidget, qint32 nColumn, Qt::Alignment flag); 481 | static QString getImageFilter(); 482 | static QColor getColorDialog(QWidget *pParent, const QString &sTitle, QColor &color); 483 | static void adjustToolButton(QToolButton *pToolButton, ICONTYPE iconType, Qt::ToolButtonStyle style = Qt::ToolButtonTextBesideIcon); 484 | static void adjustTreeWidgetItem(QTreeWidgetItem *pTreeWidgetItem, ICONTYPE iconType); 485 | static QString getIconPath(ICONTYPE iconType); 486 | static void adjustMenu(QMenu *pParentMenu, QMenu *pMenu, const QString &sText, ICONTYPE iconType); 487 | static void adjustAction(QMenu *pParentMenu, QAction *pAction, const QString &sText, const QObject *pRecv, const char *pMethod, ICONTYPE iconType); 488 | static QColor stringToColor(QString sColor); 489 | static QString colorToString(const QColor &color); 490 | static QIcon createIcon(QChar unicode, qint32 nWidth, qint32 nHeight); 491 | static QIcon createIcon(quint32 codepoint, qint32 nWidth, qint32 nHeight); 492 | #endif 493 | static quint32 iconTypeToUnicodeSymbol(ICONTYPE iconType); 494 | static void deleteQObjectList(QList *pList); 495 | #if (QT_VERSION_MAJOR < 6) || defined(QT_CORE5COMPAT_LIB) 496 | static QList getCodePages(bool bAll); 497 | #ifdef QT_GUI_LIB 498 | QMenu *createCodePagesMenu(QWidget *pParent, bool bAll); 499 | #endif 500 | #endif 501 | #ifdef Q_OS_WIN 502 | enum USERROLE { 503 | USERROLE_NORMAL = 0, 504 | USERROLE_ADMIN, 505 | USERROLE_GUEST, 506 | USERROLE_CHILD 507 | }; 508 | QString getClassesPrefix(USERROLE userRole); 509 | bool registerContext(const QString &sApplicationName, const QString &sType, const QString &sApplicationFilePath, USERROLE userRole = USERROLE_ADMIN); 510 | bool clearContext(const QString &sApplicationName, const QString &sType, USERROLE userRole = USERROLE_ADMIN); 511 | bool checkContext(const QString &sApplicationName, const QString &sType, USERROLE userRole = USERROLE_ADMIN); 512 | bool isPathInUserEnvironment(const QString &checkPath); 513 | void appendToUserPathVariable(const QString &newPath); 514 | void removeFromUserPathVariable(const QString &targetPath); 515 | #endif 516 | void setMaxRecentFilesCount(qint32 nValue); 517 | qint32 getMaxRecentFilesCount(); 518 | static BUNDLE getBundle(); 519 | static QString getBundleIdToString(BUNDLE bundle); 520 | static void registerCodecs(); 521 | 522 | #ifndef QT_GUI_LIB 523 | static void printConsole(QString sString, Qt::GlobalColor colorText = Qt::transparent, Qt::GlobalColor colorBackground = Qt::transparent); 524 | static void printModel(QAbstractItemModel *pModel); 525 | #endif 526 | 527 | public slots: 528 | void clearRecentFiles(); 529 | 530 | private slots: 531 | void openRecentFile(); 532 | void setCodePageSlot(); 533 | 534 | private: 535 | void _updateRecentFilesMenu(); 536 | 537 | signals: 538 | void errorMessage(const QString &sText); 539 | void infoMessage(const QString &sText); 540 | void openFile(const QString &sFileName); 541 | void setCodePage(const QString &sCodePage); 542 | 543 | private: 544 | static const qint32 N_MAX_RECENT_FILES_COUNT = 25; 545 | QString m_sName; 546 | QList m_listValueIDs; 547 | QMap m_mapValues; 548 | QMap m_mapDefaultValues; 549 | bool m_bIsNeedRestart; 550 | qint32 m_nMaxRecentFilesCount; 551 | #ifdef QT_GUI_LIB 552 | QMenu *m_pRecentFilesMenu; 553 | QMenu *m_pCodePagesMenu; 554 | #endif 555 | }; 556 | 557 | #endif // XOPTIONS_H -------------------------------------------------------------------------------- /xoptionswidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | XOptionsWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 621 10 | 416 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 0 34 | 35 | 36 | 37 | 38 | Qt::Horizontal 39 | 40 | 41 | 42 | 43 | 0 44 | 0 45 | 46 | 47 | 48 | 49 | 200 50 | 100 51 | 52 | 53 | 54 | 55 | 56 | 57 | 0 58 | 0 59 | 60 | 61 | 62 | 1 63 | 64 | 65 | 66 | 67 | 0 68 | 69 | 70 | 0 71 | 72 | 73 | 0 74 | 75 | 76 | 0 77 | 78 | 79 | 80 | 81 | QFrame::NoFrame 82 | 83 | 84 | QFrame::Plain 85 | 86 | 87 | true 88 | 89 | 90 | 91 | 92 | 0 93 | 0 94 | 287 95 | 384 96 | 97 | 98 | 99 | 100 | 0 101 | 102 | 103 | 0 104 | 105 | 106 | 0 107 | 108 | 109 | 0 110 | 111 | 112 | 113 | 114 | Stay on top 115 | 116 | 117 | 118 | 119 | 120 | 121 | Single application 122 | 123 | 124 | 125 | 126 | 127 | 128 | Style 129 | 130 | 131 | 132 | 2 133 | 134 | 135 | 2 136 | 137 | 138 | 2 139 | 140 | 141 | 6 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | QSS 153 | 154 | 155 | 156 | 2 157 | 158 | 159 | 2 160 | 161 | 162 | 2 163 | 164 | 165 | 2 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | Language 177 | 178 | 179 | 180 | 2 181 | 182 | 183 | 2 184 | 185 | 186 | 2 187 | 188 | 189 | 2 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | Show logo 201 | 202 | 203 | 204 | 205 | 206 | 207 | Qt::Vertical 208 | 209 | 210 | 211 | 20 212 | 40 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 0 227 | 228 | 229 | 0 230 | 231 | 232 | 0 233 | 234 | 235 | 0 236 | 237 | 238 | 239 | 240 | QFrame::NoFrame 241 | 242 | 243 | QFrame::Plain 244 | 245 | 246 | true 247 | 248 | 249 | 250 | 251 | 0 252 | 0 253 | 287 254 | 384 255 | 256 | 257 | 258 | 259 | 0 260 | 261 | 262 | 0 263 | 264 | 265 | 0 266 | 267 | 268 | 269 | 270 | Save last directory 271 | 272 | 273 | 274 | 275 | 276 | 277 | Save backup 278 | 279 | 280 | 281 | 282 | 283 | 284 | Save history 285 | 286 | 287 | 288 | 289 | 290 | 291 | Add to context menu 292 | 293 | 294 | 295 | 296 | 297 | 298 | Set system environment variable 299 | 300 | 301 | 302 | 303 | 304 | 305 | Qt::Vertical 306 | 307 | 308 | 309 | 20 310 | 248 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 0 325 | 326 | 327 | 0 328 | 329 | 330 | 0 331 | 332 | 333 | 0 334 | 335 | 336 | 337 | 338 | Controls 339 | 340 | 341 | 342 | 2 343 | 344 | 345 | 2 346 | 347 | 348 | 2 349 | 350 | 351 | 2 352 | 353 | 354 | 355 | 356 | true 357 | 358 | 359 | 360 | 361 | 362 | 363 | ... 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | Table views 374 | 375 | 376 | 377 | 2 378 | 379 | 380 | 2 381 | 382 | 383 | 2 384 | 385 | 386 | 2 387 | 388 | 389 | 390 | 391 | true 392 | 393 | 394 | 395 | 396 | 397 | 398 | ... 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | Tree views 409 | 410 | 411 | 412 | 2 413 | 414 | 415 | 2 416 | 417 | 418 | 2 419 | 420 | 421 | 2 422 | 423 | 424 | 425 | 426 | true 427 | 428 | 429 | 430 | 431 | 432 | 433 | ... 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | Hex 444 | 445 | 446 | 447 | 2 448 | 449 | 450 | 2 451 | 452 | 453 | 2 454 | 455 | 456 | 2 457 | 458 | 459 | 460 | 461 | true 462 | 463 | 464 | 465 | 466 | 467 | 468 | ... 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | Disasm 479 | 480 | 481 | 482 | 2 483 | 484 | 485 | 2 486 | 487 | 488 | 2 489 | 490 | 491 | 2 492 | 493 | 494 | 495 | 496 | true 497 | 498 | 499 | 500 | 501 | 502 | 503 | ... 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | Text editors 514 | 515 | 516 | 517 | 2 518 | 519 | 520 | 2 521 | 522 | 523 | 2 524 | 525 | 526 | 2 527 | 528 | 529 | 530 | 531 | true 532 | 533 | 534 | 535 | 536 | 537 | 538 | ... 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | Qt::Vertical 549 | 550 | 551 | 552 | 20 553 | 258 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 0 564 | 565 | 566 | 0 567 | 568 | 569 | 0 570 | 571 | 572 | 0 573 | 574 | 575 | 576 | 577 | QFrame::NoFrame 578 | 579 | 580 | QFrame::Plain 581 | 582 | 583 | true 584 | 585 | 586 | 587 | 588 | 0 589 | 0 590 | 287 591 | 384 592 | 593 | 594 | 595 | 596 | 597 | 598 | Read buffer size 599 | 600 | 601 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 602 | 603 | 604 | 605 | 2 606 | 607 | 608 | 2 609 | 610 | 611 | 2 612 | 613 | 614 | 2 615 | 616 | 617 | 618 | 619 | 620 | 200 621 | 0 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | File buffer size 633 | 634 | 635 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 636 | 637 | 638 | 639 | 2 640 | 641 | 642 | 2 643 | 644 | 645 | 2 646 | 647 | 648 | 2 649 | 650 | 651 | 652 | 653 | 654 | 200 655 | 0 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | SSE2 667 | 668 | 669 | 670 | 671 | 672 | 673 | AVX 674 | 675 | 676 | 677 | 678 | 679 | 680 | AVX2 681 | 682 | 683 | 684 | 685 | 686 | 687 | Qt::Vertical 688 | 689 | 690 | 691 | 20 692 | 263 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | Default 712 | 713 | 714 | 715 | 716 | 717 | 718 | Qt::Horizontal 719 | 720 | 721 | 722 | 40 723 | 20 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | OK 732 | 733 | 734 | 735 | 736 | 737 | 738 | Cancel 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | -------------------------------------------------------------------------------- /xoptions.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020-2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in 11 | * all copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #include "xoptions.h" 22 | 23 | XOptions::XOptions(QObject *pParent) : QObject(pParent) 24 | { 25 | #ifdef QT_GUI_LIB 26 | m_pRecentFilesMenu = nullptr; 27 | m_pCodePagesMenu = nullptr; 28 | #endif 29 | m_bIsNeedRestart = false; 30 | m_nMaxRecentFilesCount = N_MAX_RECENT_FILES_COUNT; 31 | m_sName = QString("%1.ini").arg(qApp->applicationName()); // default name 32 | } 33 | 34 | void XOptions::resetToDefault() 35 | { 36 | const qint32 nCount = m_listValueIDs.count(); 37 | if (!nCount) { 38 | return; 39 | } 40 | 41 | const QMap::const_iterator itEnd = m_mapDefaultValues.constEnd(); 42 | 43 | for (qint32 i = 0; i < nCount; ++i) { 44 | const ID id = m_listValueIDs.at(i); 45 | 46 | // Skip non-user (runtime) entries 47 | if ((id == ID_NU_LASTDIRECTORY) || (id == ID_NU_RECENTFILES)) { 48 | continue; 49 | } 50 | 51 | QVariant varDefault; // invalid by default 52 | QMap::const_iterator it = m_mapDefaultValues.constFind(id); 53 | if (it != itEnd) { 54 | varDefault = it.value(); 55 | } 56 | 57 | // Avoid unnecessary insert if value is already equal 58 | if (m_mapValues.value(id) != varDefault) { 59 | m_mapValues.insert(id, varDefault); 60 | } 61 | } 62 | } 63 | 64 | void XOptions::setValueIDs(const QList &listVariantIDs) 65 | { 66 | m_listValueIDs = listVariantIDs; 67 | } 68 | 69 | void XOptions::setDefaultValues(QMap mapDefaultValues) 70 | { 71 | m_mapDefaultValues = mapDefaultValues; 72 | } 73 | 74 | void XOptions::addID(ID id, QVariant varDefaultValue) 75 | { 76 | m_listValueIDs.append(id); 77 | 78 | if (varDefaultValue.isValid()) { 79 | m_mapDefaultValues.insert(id, varDefaultValue); 80 | } 81 | } 82 | 83 | void XOptions::removeID(ID id) 84 | { 85 | m_listValueIDs.removeOne(id); 86 | m_mapDefaultValues.remove(id); 87 | m_mapValues.remove(id); 88 | } 89 | 90 | XOptions::GROUPID XOptions::getGroupID(ID id) 91 | { 92 | GROUPID result = GROUPID_UNKNOWN; 93 | 94 | switch (id) { 95 | case ID_VIEW_STAYONTOP: 96 | case ID_VIEW_STYLE: 97 | case ID_VIEW_QSS: 98 | case ID_VIEW_LANG: 99 | case ID_VIEW_SINGLEAPPLICATION: 100 | case ID_VIEW_SHOWLOGO: 101 | case ID_VIEW_FONT: 102 | case ID_VIEW_FONT_CONTROLS: 103 | case ID_VIEW_FONT_TABLEVIEWS: 104 | case ID_VIEW_FONT_TREEVIEWS: 105 | case ID_VIEW_FONT_TEXTEDITS: 106 | case ID_VIEW_ADVANCED: 107 | case ID_VIEW_SELECTSTYLE: result = GROUPID_VIEW; break; 108 | case ID_FILE_SAVELASTDIRECTORY: 109 | case ID_FILE_SAVERECENTFILES: 110 | case ID_FILE_SAVEBACKUP: 111 | case ID_FILE_CONTEXT: 112 | case ID_FILE_PATH: result = GROUPID_FILE; break; 113 | case ID_SCAN_SCANAFTEROPEN: 114 | case ID_SCAN_FLAG_RECURSIVE: 115 | case ID_SCAN_FLAG_DEEP: 116 | case ID_SCAN_FLAG_HEURISTIC: 117 | case ID_SCAN_FLAG_AGGRESSIVE: 118 | case ID_SCAN_FLAG_VERBOSE: 119 | case ID_SCAN_FLAG_ALLTYPES: 120 | case ID_SCAN_FORMATRESULT: 121 | case ID_SCAN_LOG_PROFILING: 122 | case ID_ENGINE_BUFFERSIZE: 123 | case ID_SCAN_HIGHLIGHT: 124 | case ID_SCAN_SORT: 125 | case ID_SCAN_HIDEUNKNOWN: 126 | case ID_SCAN_ENGINE: 127 | case ID_SCAN_ENGINE_EMPTY: 128 | case ID_SCAN_DATABASE_MAIN_PATH: 129 | case ID_SCAN_DATABASE_EXTRA_PATH: 130 | case ID_SCAN_DATABASE_CUSTOM_PATH: 131 | case ID_SCAN_DATABASE_EXTRA_ENABLED: 132 | case ID_SCAN_DATABASE_CUSTOM_ENABLED: 133 | case ID_SCAN_YARARULESPATH: result = GROUPID_SCAN; break; 134 | case ID_SIGNATURES_PATH: result = GROUPID_SIGNATURES; break; 135 | case ID_INFO_PATH: result = GROUPID_INFO; break; 136 | case ID_DISASM_FONT: 137 | case ID_DISASM_SYNTAX: 138 | case ID_DISASM_LOCATIONCOLON: 139 | case ID_DISASM_UPPERCASE: 140 | case ID_DISASM_HIGHLIGHT: 141 | case ID_DISASM_COLOR_ARROWS: 142 | case ID_DISASM_COLOR_ARROWS_SELECTED: 143 | case ID_DISASM_COLOR_REGS: 144 | case ID_DISASM_COLOR_NUMBERS: 145 | case ID_DISASM_COLOR_OPCODE: 146 | case ID_DISASM_COLOR_REFS: 147 | case ID_DISASM_COLOR_X86_REGS_GENERAL: 148 | case ID_DISASM_COLOR_X86_REGS_STACK: 149 | case ID_DISASM_COLOR_X86_REGS_SEGMENT: 150 | case ID_DISASM_COLOR_X86_REGS_DEBUG: 151 | case ID_DISASM_COLOR_X86_REGS_IP: 152 | case ID_DISASM_COLOR_X86_REGS_FLAGS: 153 | case ID_DISASM_COLOR_X86_REGS_FPU: 154 | case ID_DISASM_COLOR_X86_REGS_XMM: 155 | case ID_DISASM_COLOR_X86_REGS_YMM: 156 | case ID_DISASM_COLOR_X86_REGS_ZMM: 157 | case ID_DISASM_COLOR_X86_OPCODE_CALL: 158 | case ID_DISASM_COLOR_X86_OPCODE_RET: 159 | case ID_DISASM_COLOR_X86_OPCODE_COND_JMP: 160 | case ID_DISASM_COLOR_X86_OPCODE_PUSH: 161 | case ID_DISASM_COLOR_X86_OPCODE_POP: 162 | case ID_DISASM_COLOR_X86_OPCODE_NOP: 163 | case ID_DISASM_COLOR_X86_OPCODE_JMP: 164 | case ID_DISASM_COLOR_X86_OPCODE_INT3: 165 | case ID_DISASM_COLOR_X86_OPCODE_SYSCALL: 166 | case ID_DISASM_COLOR_ARM_REGS_GENERAL: 167 | case ID_DISASM_COLOR_ARM_REGS_STACK: 168 | case ID_DISASM_COLOR_ARM_OPCODE_BRANCH: 169 | case ID_DISASM_COLOR_ARM_OPCODE_BRANCHLINK: 170 | case ID_DISASM_COLOR_ARM_OPCODE_RET: 171 | case ID_DISASM_COLOR_ARM_OPCODE_PUSH: 172 | case ID_DISASM_COLOR_ARM_OPCODE_POP: 173 | case ID_DISASM_COLOR_ARM_OPCODE_NOP: result = GROUPID_DISASM; break; 174 | case ID_DEBUGGER_COLOR_BREAKPOINT: result = GROUPID_DEBUGGER; break; 175 | case ID_HEX_FONT: 176 | case ID_HEX_LOCATIONCOLON: result = GROUPID_HEX; break; 177 | case ID_STACK_FONT: 178 | case ID_STACK_LOCATIONCOLON: result = GROUPID_STACK; break; 179 | case ID_REGISTERS_FONT: result = GROUPID_REGISTERS; break; 180 | case ID_IODRIVER_FILENAME: 181 | case ID_IODRIVER_SERVICENAME: result = GROUPID_IODRIVER; break; 182 | default: 183 | #ifdef QT_DEBUG 184 | qDebug("Unknown GroupID"); 185 | #endif 186 | result = GROUPID_UNKNOWN; 187 | } 188 | 189 | return result; 190 | } 191 | 192 | bool XOptions::isIDPresent(ID id) 193 | { 194 | bool bResult = false; 195 | 196 | qint32 nNumberOfRecords = m_listValueIDs.count(); 197 | 198 | for (qint32 i = 0; i < nNumberOfRecords; i++) { 199 | if (m_listValueIDs.at(i) == id) { 200 | bResult = true; 201 | break; 202 | } 203 | } 204 | 205 | return bResult; 206 | } 207 | 208 | bool XOptions::isGroupIDPresent(GROUPID groupID) 209 | { 210 | bool bResult = false; 211 | 212 | qint32 nNumberOfRecords = m_listValueIDs.count(); 213 | 214 | for (qint32 i = 0; i < nNumberOfRecords; i++) { 215 | if (getGroupID(m_listValueIDs.at(i)) == groupID) { 216 | bResult = true; 217 | break; 218 | } 219 | } 220 | 221 | return bResult; 222 | } 223 | 224 | bool XOptions::isNative() 225 | { 226 | #ifdef X_BUILD_INSTALL 227 | return true; 228 | #else 229 | QString sApplicationDirPath = qApp->applicationDirPath(); 230 | sApplicationDirPath = QDir::cleanPath(sApplicationDirPath); 231 | 232 | bool bResult = false; 233 | #if defined(Q_OS_MAC) 234 | bResult = true; 235 | #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) 236 | if ((sApplicationDirPath == "/bin") || (sApplicationDirPath == "/usr/bin") || (sApplicationDirPath == "/usr/local/bin") || (sApplicationDirPath == "/app/bin") || 237 | (sApplicationDirPath.contains("/usr/local/bin$")) || isAppImage()) { 238 | bResult = true; 239 | } else { 240 | bResult = false; 241 | } 242 | #elif defined(Q_OS_WIN) 243 | QString sLowerPath = sApplicationDirPath.toLower(); 244 | bool bWindowsApps = sLowerPath.contains("\\windowsapps\\"); 245 | bool bProgramFiles = sLowerPath.contains(":\\program files"); 246 | 247 | if (bWindowsApps || bProgramFiles) { 248 | bResult = true; 249 | } 250 | #endif 251 | bResult = bResult || (!QFileInfo(sApplicationDirPath).isWritable()); 252 | return bResult; 253 | #endif 254 | } 255 | 256 | bool XOptions::isAppImage() 257 | { 258 | #ifdef X_BUILD_APPIMAGE 259 | return true; 260 | #else 261 | return false; 262 | #endif 263 | } 264 | 265 | void XOptions::setName(const QString &sValue) 266 | { 267 | m_sName = sValue; 268 | #ifdef QT_DEBUG 269 | #ifdef Q_OS_WIN 270 | #ifndef Q_OS_WIN64 271 | m_sName += "win32.debug.ini"; 272 | #else 273 | m_sName += "win64.debug.ini"; 274 | #endif 275 | #endif 276 | #ifdef Q_OS_LINUX 277 | m_sName += "linux.debug.ini"; 278 | #endif 279 | #ifdef Q_OS_MACOS 280 | m_sName += "macos.debug.ini"; 281 | #endif 282 | #endif 283 | } 284 | 285 | void XOptions::load() 286 | { 287 | QSettings *pSettings = nullptr; 288 | 289 | bool bIsNative = isNative(); 290 | 291 | if (bIsNative) { 292 | pSettings = new QSettings; 293 | } else { 294 | pSettings = new QSettings(getApplicationDataPath() + QDir::separator() + QString("%1").arg(m_sName), QSettings::IniFormat); 295 | } 296 | 297 | #ifdef QT_DEBUG 298 | if (pSettings) { 299 | qDebug("XOptions load file %s", pSettings->fileName().toUtf8().data()); 300 | } 301 | #endif 302 | 303 | qint32 nNumberOfIDs = m_listValueIDs.count(); 304 | 305 | bool bSaveLastDirectory = false; 306 | bool bLastDirectory = false; 307 | bool bSaveRecentFiles = false; 308 | bool bRecentFiles = false; 309 | 310 | for (qint32 i = 0; i < nNumberOfIDs; i++) { 311 | if (m_listValueIDs.at(i) == ID_FILE_SAVELASTDIRECTORY) { 312 | bSaveLastDirectory = true; 313 | } else if (m_listValueIDs.at(i) == ID_NU_LASTDIRECTORY) { 314 | bLastDirectory = true; 315 | } else if (m_listValueIDs.at(i) == ID_FILE_SAVERECENTFILES) { 316 | bSaveRecentFiles = true; 317 | } else if (m_listValueIDs.at(i) == ID_NU_RECENTFILES) { 318 | bRecentFiles = true; 319 | } 320 | } 321 | 322 | if (bSaveLastDirectory && (!bLastDirectory)) { 323 | m_listValueIDs.append(ID_NU_LASTDIRECTORY); 324 | } 325 | 326 | if (bSaveRecentFiles && (!bRecentFiles)) { 327 | m_listValueIDs.append(ID_NU_RECENTFILES); 328 | } 329 | 330 | nNumberOfIDs = m_listValueIDs.count(); 331 | 332 | for (qint32 i = 0; i < nNumberOfIDs; i++) { 333 | ID id = m_listValueIDs.at(i); 334 | QString sName = idToString(id); 335 | 336 | QVariant varDefault; 337 | 338 | if (m_mapDefaultValues.contains(id)) { 339 | varDefault = m_mapDefaultValues.value(id); 340 | } else { 341 | // TODO: remove,use addID 342 | switch (id) { 343 | case ID_ROOTPATH: varDefault = ""; break; 344 | case ID_DATAPATH: varDefault = "$data/data"; break; 345 | case ID_JSON: varDefault = ""; break; 346 | case ID_STRUCTSPATH: varDefault = "$data/structs"; break; 347 | case ID_STRUCTS_PATH: varDefault = "$data/structs"; break; 348 | case ID_AUTHUSER: varDefault = ""; break; 349 | case ID_AUTHTOKEN: varDefault = ""; break; 350 | case ID_NU_RECENTFILES: varDefault = QList(); break; 351 | case ID_NU_LASTDIRECTORY: varDefault = ""; break; 352 | case ID_ENGINE_BUFFERSIZE: varDefault = 2 * 1024 * 1024; break; 353 | default: varDefault = ""; 354 | } 355 | } 356 | 357 | QVariant variant = pSettings->value(sName, varDefault); 358 | 359 | if (!variant.toString().contains("$data")) { 360 | if ((id == ID_SCAN_DATABASE_MAIN_PATH) || (id == ID_SCAN_DATABASE_EXTRA_PATH) || (id == ID_SCAN_DATABASE_CUSTOM_PATH)) { 361 | if ((!QDir(variant.toString()).exists()) && (!QFile(variant.toString()).exists())) { 362 | variant = varDefault; 363 | } 364 | } else if ((id == ID_DATAPATH) || (id == ID_SIGNATURES_PATH) || (id == ID_STRUCTS_PATH) || (id == ID_STRUCTSPATH) || (id == ID_INFO_PATH) || 365 | (id == ID_SCAN_YARARULESPATH)) { 366 | if (!QDir(variant.toString()).exists()) { 367 | variant = varDefault; 368 | } 369 | } 370 | } 371 | 372 | if (bIsNative) { 373 | if (variant.toString().contains("$data")) { 374 | QString sValue = variant.toString(); 375 | sValue = sValue.replace("$data", getApplicationDataPath()); 376 | variant = sValue; 377 | } 378 | } 379 | 380 | m_mapValues.insert(id, variant); 381 | } 382 | 383 | QString sLastDirectory = m_mapValues.value(ID_NU_LASTDIRECTORY).toString(); 384 | 385 | if (sLastDirectory != "") { 386 | if (!QDir(sLastDirectory).exists()) { 387 | m_mapValues.insert(ID_NU_LASTDIRECTORY, ""); 388 | } 389 | } 390 | 391 | #ifdef USE_XSIMD 392 | if (xsimd_is_sse2_present()) { 393 | xsimd_set_sse2(m_mapValues.value(ID_FEATURE_SSE2).toBool()); 394 | } 395 | if (xsimd_is_avx_present()) { 396 | xsimd_set_avx(m_mapValues.value(ID_FEATURE_AVX).toBool()); 397 | } 398 | if (xsimd_is_avx2_present()) { 399 | xsimd_set_avx2(m_mapValues.value(ID_FEATURE_AVX2).toBool()); 400 | } 401 | #endif 402 | 403 | delete pSettings; 404 | } 405 | 406 | void XOptions::save() 407 | { 408 | QSettings *pSettings = nullptr; 409 | 410 | bool bIsNative = isNative(); 411 | 412 | if (bIsNative) { 413 | pSettings = new QSettings; 414 | } else { 415 | pSettings = new QSettings(getApplicationDataPath() + QDir::separator() + QString("%1").arg(m_sName), QSettings::IniFormat); 416 | } 417 | 418 | #ifdef QT_DEBUG 419 | if (pSettings) { 420 | qDebug("XOptions save file %s", pSettings->fileName().toUtf8().data()); 421 | } 422 | #endif 423 | 424 | qint32 nNumberOfIDs = m_listValueIDs.count(); 425 | 426 | for (qint32 i = 0; i < nNumberOfIDs; i++) { 427 | ID id = m_listValueIDs.at(i); 428 | QString sName = idToString(id); 429 | pSettings->setValue(sName, m_mapValues.value(id)); 430 | 431 | if ((id == ID_FILE_SAVELASTDIRECTORY) && (m_mapValues.value(id).toBool() == false)) { 432 | pSettings->setValue(idToString(ID_NU_LASTDIRECTORY), ""); 433 | } else if ((id == ID_FILE_SAVERECENTFILES) && (m_mapValues.value(id).toBool() == false)) { 434 | clearRecentFiles(); 435 | } 436 | } 437 | 438 | delete pSettings; 439 | } 440 | 441 | QVariant XOptions::getValue(XOptions::ID id) 442 | { 443 | return m_mapValues.value(id); 444 | } 445 | 446 | void XOptions::setValue(XOptions::ID id, QVariant varValue) 447 | { 448 | if ((id == ID_VIEW_STYLE) || (id == ID_VIEW_LANG) || (id == ID_VIEW_QSS)) { 449 | QVariant varOld = m_mapValues.value(id); 450 | 451 | if (varValue != varOld) { 452 | m_bIsNeedRestart = true; 453 | } 454 | } 455 | 456 | m_mapValues.insert(id, varValue); 457 | } 458 | 459 | void XOptions::clearValue(XOptions::ID id) 460 | { 461 | m_mapValues.insert(id, ""); 462 | } 463 | 464 | bool XOptions::isValuePresent(ID id) 465 | { 466 | return m_mapValues.contains(id); 467 | } 468 | 469 | QVariant XOptions::getDefaultValue(ID id) 470 | { 471 | return m_mapDefaultValues.value(id); 472 | } 473 | 474 | QString XOptions::idToString(ID id) 475 | { 476 | QString sResult; 477 | 478 | switch (id) { 479 | // TODO: remove 480 | case ID_ROOTPATH: sResult = QString("RootPath"); break; 481 | case ID_DATAPATH: sResult = QString("DataPath"); break; 482 | case ID_JSON: sResult = QString("Json"); break; 483 | case ID_STRUCTSPATH: sResult = QString("StructsPath"); break; 484 | case ID_AUTHUSER: sResult = QString("AuthUser"); break; 485 | case ID_AUTHTOKEN: sResult = QString("AuthToken"); break; 486 | // new 487 | case ID_VIEW_STAYONTOP: sResult = QString("View/StayOnTop"); break; 488 | case ID_VIEW_STYLE: sResult = QString("View/Style"); break; 489 | case ID_VIEW_QSS: sResult = QString("View/Qss"); break; 490 | case ID_VIEW_LANG: sResult = QString("View/Lang"); break; 491 | case ID_VIEW_SINGLEAPPLICATION: sResult = QString("View/SingleApplication"); break; 492 | case ID_VIEW_SHOWLOGO: sResult = QString("View/ShowLogo"); break; 493 | case ID_VIEW_FONT: sResult = QString("View/Font"); break; 494 | case ID_VIEW_FONT_CONTROLS: sResult = QString("View/Font/Controls"); break; 495 | case ID_VIEW_FONT_TABLEVIEWS: sResult = QString("View/Font/TableViews"); break; 496 | case ID_VIEW_FONT_TREEVIEWS: sResult = QString("View/Font/TreeViews"); break; 497 | case ID_VIEW_FONT_TEXTEDITS: sResult = QString("View/Font/TextEdits"); break; 498 | case ID_VIEW_ADVANCED: sResult = QString("View/Advanced"); break; 499 | case ID_VIEW_SELECTSTYLE: sResult = QString("View/SelectStyle"); break; 500 | case ID_FILE_SAVELASTDIRECTORY: sResult = QString("File/SaveLastDirectory"); break; 501 | case ID_FILE_SAVERECENTFILES: sResult = QString("File/SaveRecentFiles"); break; 502 | case ID_FILE_SAVEBACKUP: sResult = QString("File/SaveBackup"); break; 503 | case ID_FILE_CONTEXT: sResult = QString("File/Context"); break; 504 | case ID_FILE_PATH: sResult = QString("File/Path"); break; 505 | case ID_FEATURE_READBUFFERSIZE: sResult = QString("Feature/ReadBufferSize"); break; 506 | case ID_FEATURE_FILEBUFFERSIZE: sResult = QString("Feature/FileBufferSize"); break; 507 | case ID_FEATURE_SSE2: sResult = QString("Feature/SSE2"); break; 508 | case ID_FEATURE_AVX: sResult = QString("Feature/AVX"); break; 509 | case ID_FEATURE_AVX2: sResult = QString("Feature/AVX2"); break; 510 | case ID_ENGINE_BUFFERSIZE: sResult = QString("Engine/BufferSize"); break; 511 | case ID_SCAN_BUFFERSIZE: sResult = QString("Scan/BufferSize"); break; 512 | case ID_SCAN_SCANAFTEROPEN: sResult = QString("Scan/ScanAfterOpen"); break; 513 | case ID_SCAN_FLAG_RECURSIVE: sResult = QString("Scan/Flag/Recursive"); break; 514 | case ID_SCAN_FLAG_DEEP: sResult = QString("Scan/Flag/Deep"); break; 515 | case ID_SCAN_FLAG_HEURISTIC: sResult = QString("Scan/Flag/Heuristic"); break; 516 | case ID_SCAN_FLAG_AGGRESSIVE: sResult = QString("Scan/Flag/Aggressive"); break; 517 | case ID_SCAN_FLAG_VERBOSE: sResult = QString("Scan/Flag/Verbose"); break; 518 | case ID_SCAN_FLAG_ALLTYPES: sResult = QString("Scan/Flag/AllTypes"); break; 519 | case ID_SCAN_USECACHE: sResult = QString("Scan/UseCache"); break; 520 | case ID_SCAN_FORMATRESULT: sResult = QString("Scan/FormatResult"); break; 521 | case ID_SCAN_LOG_PROFILING: sResult = QString("Scan/Log/Profiling"); break; 522 | case ID_SCAN_HIGHLIGHT: sResult = QString("Scan/Highlight"); break; 523 | case ID_SCAN_SORT: sResult = QString("Scan/Sort"); break; 524 | case ID_SCAN_HIDEUNKNOWN: sResult = QString("Scan/HideUnknown"); break; 525 | case ID_SCAN_ENGINE: 526 | case ID_SCAN_ENGINE_EMPTY: sResult = QString("Scan/Engine"); break; 527 | case ID_SCAN_DATABASE_MAIN_PATH: sResult = QString("Scan/Database/Main/Path"); break; 528 | case ID_SCAN_DATABASE_EXTRA_PATH: sResult = QString("Scan/Database/Extra/Path"); break; 529 | case ID_SCAN_DATABASE_CUSTOM_PATH: sResult = QString("Scan/Database/Custom/Path"); break; 530 | case ID_SCAN_DATABASE_EXTRA_ENABLED: sResult = QString("Scan/Database/Extra/Enabled"); break; 531 | case ID_SCAN_DATABASE_CUSTOM_ENABLED: sResult = QString("Scan/Database/Custom/Enabled"); break; 532 | case ID_SCAN_YARARULESPATH: sResult = QString("Scan/YaraRulesPath"); break; 533 | case ID_SIGNATURES_PATH: sResult = QString("Signatures/Path"); break; 534 | case ID_INFO_PATH: sResult = QString("Info/Path"); break; 535 | case ID_ONLINETOOLS_VIRUSTOTAL_APIKEY: sResult = QString("OnlineTools/VirusTotalApi"); break; 536 | case ID_DISASM_FONT: sResult = QString("Disasm/Font"); break; 537 | case ID_DISASM_LOCATIONCOLON: sResult = QString("Disasm/LocationColon"); break; 538 | case ID_DISASM_UPPERCASE: sResult = QString("Disasm/Uppercase"); break; 539 | case ID_DISASM_HIGHLIGHT: sResult = QString("Disasm/Highlight"); break; 540 | case ID_DISASM_SYNTAX: sResult = QString("Disasm/Syntax"); break; 541 | case ID_DISASM_COLOR_ARROWS: sResult = QString("Disasm/Color/Arrows"); break; 542 | case ID_DISASM_COLOR_ARROWS_SELECTED: sResult = QString("Disasm/Color/Arrows/Selected"); break; 543 | case ID_DISASM_COLOR_REGS: sResult = QString("Disasm/Color/Regs"); break; 544 | case ID_DISASM_COLOR_NUMBERS: sResult = QString("Disasm/Color/Numbers"); break; 545 | case ID_DISASM_COLOR_OPCODE: sResult = QString("Disasm/Color/Opcode"); break; 546 | case ID_DISASM_COLOR_REFS: sResult = QString("Disasm/Color/Refs"); break; 547 | case ID_DISASM_COLOR_X86_REGS_GENERAL: sResult = QString("Disasm/Color/x86/Regs/General"); break; 548 | case ID_DISASM_COLOR_X86_REGS_STACK: sResult = QString("Disasm/Color/x86/Regs/Stack"); break; 549 | case ID_DISASM_COLOR_X86_REGS_SEGMENT: sResult = QString("Disasm/Color/x86/Regs/Segment"); break; 550 | case ID_DISASM_COLOR_X86_REGS_DEBUG: sResult = QString("Disasm/Color/x86/Regs/Debug"); break; 551 | case ID_DISASM_COLOR_X86_REGS_IP: sResult = QString("Disasm/Color/x86/Regs/IP"); break; 552 | case ID_DISASM_COLOR_X86_REGS_FLAGS: sResult = QString("Disasm/Color/x86/Regs/Flags"); break; 553 | case ID_DISASM_COLOR_X86_REGS_FPU: sResult = QString("Disasm/Color/x86/Regs/Float"); break; 554 | case ID_DISASM_COLOR_X86_REGS_XMM: sResult = QString("Disasm/Color/x86/Regs/XMM"); break; 555 | case ID_DISASM_COLOR_X86_REGS_YMM: sResult = QString("Disasm/Color/x86/Regs/YMM"); break; 556 | case ID_DISASM_COLOR_X86_REGS_ZMM: sResult = QString("Disasm/Color/x86/Regs/ZMM"); break; 557 | case ID_DISASM_COLOR_X86_OPCODE_CALL: sResult = QString("Disasm/Color/x86/Opcode/call"); break; 558 | case ID_DISASM_COLOR_X86_OPCODE_RET: sResult = QString("Disasm/Color/x86/Opcode/ret"); break; 559 | case ID_DISASM_COLOR_X86_OPCODE_COND_JMP: sResult = QString("Disasm/Color/x86/Opcode/cond_jmp"); break; 560 | case ID_DISASM_COLOR_X86_OPCODE_PUSH: sResult = QString("Disasm/Color/x86/Opcode/push"); break; 561 | case ID_DISASM_COLOR_X86_OPCODE_POP: sResult = QString("Disasm/Color/x86/Opcode/pop"); break; 562 | case ID_DISASM_COLOR_X86_OPCODE_NOP: sResult = QString("Disasm/Color/x86/Opcode/nop"); break; 563 | case ID_DISASM_COLOR_X86_OPCODE_JMP: sResult = QString("Disasm/Color/x86/Opcode/jmp"); break; 564 | case ID_DISASM_COLOR_X86_OPCODE_INT3: sResult = QString("Disasm/Color/x86/Opcode/int3"); break; 565 | case ID_DISASM_COLOR_X86_OPCODE_SYSCALL: sResult = QString("Disasm/Color/x86/Opcode/syscall"); break; 566 | case ID_DISASM_COLOR_ARM_REGS_GENERAL: sResult = QString("Disasm/Color/arm/Regs/General"); break; 567 | case ID_DISASM_COLOR_ARM_REGS_STACK: sResult = QString("Disasm/Color/arm/Regs/Stack"); break; 568 | case ID_DISASM_COLOR_ARM_OPCODE_BRANCH: sResult = QString("Disasm/Color/arm/Opcode/b"); break; 569 | case ID_DISASM_COLOR_ARM_OPCODE_BRANCHLINK: sResult = QString("Disasm/Color/arm/Opcode/bl"); break; 570 | case ID_DISASM_COLOR_ARM_OPCODE_RET: sResult = QString("Disasm/Color/arm/Opcode/ret"); break; 571 | case ID_DISASM_COLOR_ARM_OPCODE_PUSH: sResult = QString("Disasm/Color/arm/Opcode/push"); break; 572 | case ID_DISASM_COLOR_ARM_OPCODE_POP: sResult = QString("Disasm/Color/arm/Opcode/pop"); break; 573 | case ID_DISASM_COLOR_ARM_OPCODE_NOP: sResult = QString("Disasm/Color/arm/Opcode/nop"); break; 574 | case ID_HEX_FONT: sResult = QString("Hex/Font"); break; 575 | case ID_HEX_LOCATIONCOLON: sResult = QString("Hex/LocationColon"); break; 576 | case ID_STACK_FONT: sResult = QString("Stack/Font"); break; 577 | case ID_STACK_LOCATIONCOLON: sResult = QString("Stack/LocationColon"); break; 578 | case ID_REGISTERS_FONT: sResult = QString("Registers/Font"); break; 579 | case ID_DEBUGGER_COLOR_BREAKPOINT: sResult = QString("Debugger/Color/Breakpoint"); break; 580 | case ID_IODRIVER_FILENAME: sResult = QString("IODriver/FileName"); break; 581 | case ID_IODRIVER_SERVICENAME: sResult = QString("IODriver/ServiceName"); break; 582 | case ID_STRUCTS_PATH: sResult = QString("Structs/Path"); break; 583 | case ID_NU_RECENTFILES: sResult = QString("RecentFiles"); break; 584 | case ID_NU_LASTDIRECTORY: sResult = QString("LastDirectory"); break; 585 | default: sResult = QString("Unknown"); 586 | } 587 | 588 | return sResult; 589 | } 590 | 591 | QString XOptions::getLastDirectory() 592 | { 593 | QString sResult; 594 | 595 | bool bSaveLastDirectory = getValue(ID_FILE_SAVELASTDIRECTORY).toBool(); 596 | QString sLastDirectory = getValue(ID_NU_LASTDIRECTORY).toString(); 597 | 598 | if (bSaveLastDirectory && (sLastDirectory != "") && QDir().exists(sLastDirectory)) { 599 | sResult = sLastDirectory; 600 | } 601 | 602 | return sResult; 603 | } 604 | 605 | void XOptions::setLastDirectory(const QString &sPathName) 606 | { 607 | QString _sPathName = sPathName; 608 | 609 | if (getValue(ID_FILE_SAVELASTDIRECTORY).toBool()) { 610 | QFileInfo fi(_sPathName); 611 | 612 | if (fi.isFile()) { 613 | _sPathName = fi.absolutePath(); 614 | } else if (fi.isDir()) { 615 | _sPathName = fi.absoluteFilePath(); 616 | } 617 | 618 | setValue(ID_NU_LASTDIRECTORY, _sPathName); 619 | } 620 | } 621 | 622 | void XOptions::setLastFileName(const QString &sFileName) 623 | { 624 | QFileInfo fi(sFileName); 625 | 626 | QString sDirectory; 627 | 628 | if (fi.isFile()) { 629 | sDirectory = fi.absolutePath(); 630 | } 631 | 632 | if (getValue(ID_FILE_SAVELASTDIRECTORY).toBool()) { 633 | setValue(ID_NU_LASTDIRECTORY, sDirectory); 634 | } 635 | 636 | if (getValue(ID_FILE_SAVERECENTFILES).toBool()) { 637 | QString _sFileName = fi.absoluteFilePath(); 638 | 639 | if (_sFileName != "") { 640 | QList listFiles = getValue(ID_NU_RECENTFILES).toList(); 641 | 642 | listFiles.removeAll(_sFileName); 643 | 644 | listFiles.append(QVariant(_sFileName)); 645 | 646 | if (listFiles.count() > m_nMaxRecentFilesCount) { 647 | listFiles.removeFirst(); 648 | } 649 | 650 | m_mapValues.insert(ID_NU_RECENTFILES, listFiles); 651 | 652 | #ifdef QT_GUI_LIB 653 | _updateRecentFilesMenu(); 654 | #endif 655 | } 656 | } 657 | } 658 | 659 | void XOptions::clearRecentFiles() 660 | { 661 | m_mapValues.insert(ID_NU_RECENTFILES, QList()); 662 | 663 | #ifdef QT_GUI_LIB 664 | _updateRecentFilesMenu(); 665 | #endif 666 | } 667 | 668 | void XOptions::openRecentFile() 669 | { 670 | #ifdef QT_GUI_LIB 671 | QAction *pAction = qobject_cast(sender()); 672 | 673 | if (pAction) { 674 | QString sFileName = pAction->data().toString(); 675 | 676 | if (QFile::exists(sFileName)) { 677 | emit openFile(sFileName); 678 | } else { 679 | emit errorMessage(QString("%1: %2").arg(tr("Cannot find file"), sFileName)); 680 | } 681 | } 682 | #endif 683 | } 684 | 685 | void XOptions::setCodePageSlot() 686 | { 687 | #ifdef QT_GUI_LIB 688 | QAction *pAction = qobject_cast(sender()); 689 | 690 | if (pAction) { 691 | QString sCodePage = pAction->data().toString(); 692 | 693 | emit setCodePage(sCodePage); 694 | } 695 | #endif 696 | } 697 | 698 | QList XOptions::getRecentFiles() 699 | { 700 | QList listResult; 701 | 702 | QList listFiles = getValue(ID_NU_RECENTFILES).toList(); 703 | 704 | qint32 nNumberOfFiles = listFiles.size(); 705 | 706 | for (qint32 i = 0; i < nNumberOfFiles; i++) { 707 | listResult.append(listFiles.at(i).toString()); 708 | } 709 | 710 | return listResult; 711 | } 712 | 713 | QString XOptions::getDatabasePath() 714 | { 715 | return getValue(ID_SCAN_DATABASE_MAIN_PATH).toString(); 716 | } 717 | 718 | QString XOptions::getExtraDatabasePath() 719 | { 720 | return getValue(ID_SCAN_DATABASE_EXTRA_PATH).toString(); 721 | } 722 | 723 | QString XOptions::getCustomDatabasePath() 724 | { 725 | return getValue(ID_SCAN_DATABASE_CUSTOM_PATH).toString(); 726 | } 727 | 728 | QString XOptions::getScanEngine() 729 | { 730 | QString sResult; 731 | 732 | if (isValuePresent(ID_SCAN_ENGINE)) { 733 | sResult = getValue(ID_SCAN_ENGINE).toString(); 734 | } else if (isValuePresent(ID_SCAN_ENGINE_EMPTY)) { 735 | sResult = getValue(ID_SCAN_ENGINE_EMPTY).toString(); 736 | } 737 | 738 | return sResult; 739 | } 740 | 741 | QString XOptions::getInfoPath() 742 | { 743 | return getValue(ID_INFO_PATH).toString(); 744 | } 745 | 746 | QString XOptions::getRootPath() 747 | { 748 | return getValue(ID_ROOTPATH).toString(); 749 | } 750 | 751 | QString XOptions::getDataPath() 752 | { 753 | return getValue(ID_DATAPATH).toString(); 754 | } 755 | 756 | QString XOptions::getJson() 757 | { 758 | return getValue(ID_JSON).toString(); 759 | } 760 | 761 | QString XOptions::getAuthUser() 762 | { 763 | return getValue(ID_AUTHUSER).toString(); 764 | } 765 | 766 | QString XOptions::getAuthToken() 767 | { 768 | return getValue(ID_AUTHTOKEN).toString(); 769 | } 770 | 771 | QString XOptions::getVirusTotalApiKey() 772 | { 773 | return getValue(ID_ONLINETOOLS_VIRUSTOTAL_APIKEY).toString(); 774 | } 775 | 776 | #ifdef QT_GUI_LIB 777 | void XOptions::adjustStayOnTop(QWidget *pWidget) 778 | { 779 | if (isIDPresent(XOptions::ID_VIEW_STAYONTOP)) { 780 | _adjustStayOnTop(pWidget, isStayOnTop()); 781 | } 782 | } 783 | #endif 784 | #ifdef QT_GUI_LIB 785 | void XOptions::_adjustStayOnTop(QWidget *pWidget, bool bState) 786 | { 787 | Qt::WindowFlags wf = pWidget->windowFlags(); 788 | 789 | if (bState) { 790 | wf |= Qt::WindowStaysOnTopHint; 791 | } else { 792 | wf &= ~(Qt::WindowStaysOnTopHint); 793 | } 794 | 795 | pWidget->setWindowFlags(wf); 796 | pWidget->show(); 797 | } 798 | #endif 799 | #ifdef QT_GUI_LIB 800 | bool XOptions::_isAjustStayOnTop(QWidget *pWidget) 801 | { 802 | bool bResult = false; 803 | 804 | Qt::WindowFlags wf = pWidget->windowFlags(); 805 | 806 | if (wf & Qt::WindowStaysOnTopHint) { 807 | bResult = true; 808 | } 809 | 810 | return bResult; 811 | } 812 | #endif 813 | #ifdef QT_GUI_LIB 814 | void XOptions::_adjustApplicationModal(QWidget *pWidget, bool bState) 815 | { 816 | if (bState) { 817 | pWidget->setWindowModality(Qt::ApplicationModal); 818 | } else { 819 | pWidget->setWindowModality(Qt::NonModal); 820 | } 821 | 822 | pWidget->show(); 823 | } 824 | #endif 825 | #ifdef QT_GUI_LIB 826 | void XOptions::_adjustFullScreen(QWidget *pWidget, bool bState) 827 | { 828 | if (bState) { 829 | pWidget->showFullScreen(); 830 | } else { 831 | pWidget->showNormal(); 832 | } 833 | } 834 | #endif 835 | #ifdef QT_GUI_LIB 836 | QFont XOptions::adjustFont(QWidget *pWidget, ID id) 837 | { 838 | QFont result; 839 | QString sFont = getValue(id).toString(); 840 | 841 | if ((sFont != "") && result.fromString(sFont)) { 842 | QFont fontOld = pWidget->font(); 843 | 844 | result.setBold(fontOld.bold()); 845 | 846 | pWidget->setFont(result); 847 | } 848 | 849 | return result; 850 | } 851 | #endif 852 | #ifdef QT_GUI_LIB 853 | void XOptions::adjustWindow(QWidget *pWidget) 854 | { 855 | if (isIDPresent(XOptions::ID_VIEW_STAYONTOP)) { 856 | adjustStayOnTop(pWidget); 857 | } 858 | 859 | adjustWidget(pWidget, XOptions::ID_VIEW_FONT); 860 | } 861 | #endif 862 | #ifdef QT_GUI_LIB 863 | void XOptions::adjustWidget(QWidget *pWidget, ID id) 864 | { 865 | if (isIDPresent(id)) { 866 | adjustFont(pWidget, id); 867 | } 868 | } 869 | #endif 870 | #ifdef QT_GUI_LIB 871 | void XOptions::adjustTableWidget(QTableWidget *pWidget, ID id) 872 | { 873 | if (isIDPresent(id)) { 874 | QFont _font = adjustFont(pWidget, id); 875 | 876 | const QFontMetricsF fm(_font); 877 | 878 | qint32 nCharHeight = fm.height(); 879 | 880 | pWidget->verticalHeader()->setMinimumSectionSize(nCharHeight + 3); 881 | pWidget->verticalHeader()->setDefaultSectionSize(nCharHeight + 3); 882 | } 883 | } 884 | #endif 885 | #ifdef QT_GUI_LIB 886 | void XOptions::adjustTableView(QTableView *pWidget, ID id) 887 | { 888 | if (isIDPresent(id)) { 889 | QFont _font = adjustFont(pWidget, id); 890 | 891 | const QFontMetricsF fm(_font); 892 | 893 | qint32 nCharHeight = fm.height(); 894 | 895 | pWidget->verticalHeader()->setMinimumSectionSize(nCharHeight + 3); 896 | pWidget->verticalHeader()->setDefaultSectionSize(nCharHeight + 3); 897 | } 898 | } 899 | #endif 900 | #ifdef QT_GUI_LIB 901 | void XOptions::adjustTreeWidget(QTreeWidget *pWidget, ID id, bool bAdjustSize) 902 | { 903 | if (isIDPresent(id)) { 904 | adjustFont(pWidget, id); 905 | } 906 | 907 | if (bAdjustSize) { 908 | adjustTreeWidgetSize(pWidget); 909 | } 910 | } 911 | #endif 912 | #ifdef QT_GUI_LIB 913 | void XOptions::adjustTreeView(QTreeView *pWidget, ID id) 914 | { 915 | if (isIDPresent(id)) { 916 | adjustFont(pWidget, id); 917 | } 918 | } 919 | #endif 920 | #ifdef QT_GUI_LIB 921 | QFont XOptions::getDefaultFont(qint32 nFontSize) 922 | { 923 | QFont fontResult; 924 | 925 | if (nFontSize == -1) { 926 | #ifdef Q_OS_MACOS 927 | nFontSize = 13; 928 | #endif 929 | #ifdef Q_OS_WIN 930 | nFontSize = 9; 931 | #endif 932 | #ifdef Q_OS_LINUX 933 | nFontSize = 11; 934 | #endif 935 | } 936 | 937 | #ifdef Q_OS_WIN 938 | fontResult = QFont("Segoe UI", nFontSize); 939 | #endif 940 | #ifdef Q_OS_LINUX 941 | fontResult = QFont("Ubuntu", nFontSize); 942 | #endif 943 | #ifdef Q_OS_MACOS 944 | fontResult = QFont(".AppleSystemUIFont", nFontSize); 945 | #endif 946 | 947 | return fontResult; 948 | } 949 | #endif 950 | #ifdef QT_GUI_LIB 951 | QFont XOptions::getMonoFont(qint32 nFontSize) 952 | { 953 | QFont fontResult; 954 | 955 | if (nFontSize == -1) { 956 | #ifdef Q_OS_MACOS 957 | nFontSize = 12; 958 | #endif 959 | #ifdef Q_OS_WIN 960 | nFontSize = 10; 961 | #endif 962 | #ifdef Q_OS_LINUX 963 | nFontSize = 10; 964 | #endif 965 | } 966 | 967 | #ifdef Q_OS_WIN 968 | fontResult = QFont("Courier", nFontSize); 969 | #endif 970 | #ifdef Q_OS_LINUX 971 | fontResult = QFont("DejaVu Sans Mono", nFontSize); 972 | #endif 973 | #ifdef Q_OS_MACOS 974 | fontResult = QFont("Menlo", nFontSize); 975 | #endif 976 | 977 | return fontResult; 978 | } 979 | #endif 980 | #ifdef QT_GUI_LIB 981 | void XOptions::setMonoFont(QWidget *pWidget, qint32 nSize) 982 | { 983 | QFont font = pWidget->font(); 984 | QFont fontMono = getMonoFont(nSize); 985 | 986 | font.setFamily(fontMono.family()); 987 | font.setPointSize(fontMono.pointSize()); 988 | 989 | pWidget->setFont(font); 990 | } 991 | #endif 992 | #ifdef QT_GUI_LIB 993 | void XOptions::setCheckBox(QCheckBox *pCheckBox, XOptions::ID id) 994 | { 995 | pCheckBox->setChecked(getValue(id).toBool()); 996 | } 997 | #endif 998 | #ifdef QT_GUI_LIB 999 | void XOptions::getCheckBox(QCheckBox *pCheckBox, XOptions::ID id) 1000 | { 1001 | setValue(id, pCheckBox->isChecked()); 1002 | } 1003 | #endif 1004 | #ifdef QT_GUI_LIB 1005 | void XOptions::setCheckBox(QGroupBox *pGroupBox, ID id) 1006 | { 1007 | pGroupBox->setChecked(getValue(id).toBool()); 1008 | } 1009 | #endif 1010 | #ifdef QT_GUI_LIB 1011 | void XOptions::getCheckBox(QGroupBox *pGroupBox, ID id) 1012 | { 1013 | setValue(id, pGroupBox->isChecked()); 1014 | } 1015 | #endif 1016 | #ifdef QT_GUI_LIB 1017 | void XOptions::setComboBox(QComboBox *pComboBox, XOptions::ID id) 1018 | { 1019 | const bool bBlocked1 = pComboBox->blockSignals(true); 1020 | 1021 | pComboBox->clear(); 1022 | 1023 | QString sValue = getValue(id).toString(); 1024 | 1025 | if (id == ID_VIEW_STYLE) { 1026 | pComboBox->addItem("Default", ""); 1027 | QStringList listKeys = QStyleFactory::keys(); 1028 | 1029 | qint32 nNumberOfKeys = listKeys.count(); 1030 | 1031 | for (qint32 i = 0; i < nNumberOfKeys; i++) { 1032 | QString sRecord = listKeys.at(i); 1033 | pComboBox->addItem(sRecord, sRecord); 1034 | } 1035 | } else if (id == ID_VIEW_LANG) { 1036 | pComboBox->addItem("English", ""); 1037 | pComboBox->addItem("System", "System"); 1038 | 1039 | QList listFileNames = getAllFilesFromDirectory(getApplicationLangPath(), "*.qm"); 1040 | 1041 | qint32 nNumberOfRecords = listFileNames.count(); 1042 | 1043 | for (qint32 i = 0; i < nNumberOfRecords; i++) { 1044 | QFileInfo fi(listFileNames.at(i)); 1045 | 1046 | QString sRecord = fi.completeBaseName(); 1047 | 1048 | QLocale locale(sRecord.section("_", 1, -1)); 1049 | QString sLocale = locale.nativeLanguageName(); 1050 | 1051 | if (sRecord.count("_") == 2) { 1052 | sLocale += QString("(%1)").arg(locale.nativeCountryName()); 1053 | } 1054 | 1055 | if (sLocale != "") { 1056 | sLocale.replace(0, 1, sLocale[0].toUpper()); 1057 | } 1058 | 1059 | sLocale += QString("[%1]").arg(locale.languageToString(locale.language())); 1060 | 1061 | pComboBox->addItem(sLocale, sRecord); 1062 | } 1063 | } else if (id == ID_VIEW_QSS) { 1064 | pComboBox->addItem("Default", ""); 1065 | 1066 | QList listFileNames = getAllFilesFromDirectory(getApplicationQssPath(), "*.qss"); 1067 | 1068 | qint32 nNumberOfRecords = listFileNames.count(); 1069 | 1070 | for (qint32 i = 0; i < nNumberOfRecords; i++) { 1071 | QFileInfo fi(listFileNames.at(i)); 1072 | 1073 | QString sRecord = fi.completeBaseName(); 1074 | 1075 | pComboBox->addItem(sRecord, sRecord); 1076 | } 1077 | } else if (id == ID_SCAN_ENGINE) { 1078 | pComboBox->addItem(tr("Automatic"), "auto"); 1079 | pComboBox->addItem(QString("Detect It Easy (DiE)"), "die"); 1080 | pComboBox->addItem(QString("Nauz File Detector (NFD)"), "nfd"); 1081 | #ifdef USE_YARA 1082 | pComboBox->addItem(QString("Yara rules"), "yara"); 1083 | #endif 1084 | } else if (id == ID_SCAN_ENGINE_EMPTY) { 1085 | pComboBox->addItem("", ""); 1086 | pComboBox->addItem(QString("Detect It Easy (DiE)"), "die"); 1087 | pComboBox->addItem(QString("Nauz File Detector (NFD)"), "nfd"); 1088 | #ifdef USE_YARA 1089 | pComboBox->addItem(QString("Yara rules"), "yara"); 1090 | #endif 1091 | } else if (id == ID_DISASM_SYNTAX) { 1092 | pComboBox->addItem("Default", ""); 1093 | pComboBox->addItem(QString("ATT"), "ATT"); 1094 | pComboBox->addItem(QString("INTEL"), "INTEL"); 1095 | pComboBox->addItem(QString("MASM"), "MASM"); 1096 | pComboBox->addItem(QString("MOTOROLA"), "MOTOROLA"); 1097 | } else if (id == ID_FEATURE_READBUFFERSIZE) { 1098 | pComboBox->addItem("", 0); 1099 | pComboBox->addItem("1 KiB", 1 * 1024); 1100 | pComboBox->addItem("2 KiB", 2 * 1024); 1101 | pComboBox->addItem("4 KiB", 4 * 1024); 1102 | pComboBox->addItem("8 KiB", 8 * 1024); 1103 | pComboBox->addItem("16 KiB", 16 * 1024); 1104 | pComboBox->addItem("32 KiB", 32 * 1024); 1105 | pComboBox->addItem("64 KiB", 64 * 1024); 1106 | pComboBox->addItem("128 KiB", 128 * 1024); 1107 | pComboBox->addItem("256 KiB", 256 * 1024); 1108 | pComboBox->addItem("512 KiB", 512 * 1024); 1109 | } else if (id == ID_FEATURE_FILEBUFFERSIZE) { 1110 | pComboBox->addItem("", 0); 1111 | pComboBox->addItem("1 MiB", 1 * 1024 * 1024); 1112 | pComboBox->addItem("2 MiB", 2 * 1024 * 1024); 1113 | pComboBox->addItem("4 MiB", 4 * 1024 * 1024); 1114 | pComboBox->addItem("8 MiB", 8 * 1024 * 1024); 1115 | pComboBox->addItem("16 MiB", 16 * 1024 * 1024); 1116 | pComboBox->addItem("32 MiB", 32 * 1024 * 1024); 1117 | pComboBox->addItem("64 MiB", 64 * 1024 * 1024); 1118 | pComboBox->addItem("128 MiB", 128 * 1024 * 1024); 1119 | pComboBox->addItem("256 MiB", 256 * 1024 * 1024); 1120 | pComboBox->addItem("512 MiB", 512 * 1024 * 1024); 1121 | pComboBox->addItem("1 GiB", 1LL * 1024 * 1024 * 1024); 1122 | pComboBox->addItem("2 GiB", 2LL * 1024 * 1024 * 1024); 1123 | pComboBox->addItem("4 GiB", 4LL * 1024 * 1024 * 1024); 1124 | } 1125 | 1126 | qint32 nNumberOfItems = pComboBox->count(); 1127 | qint32 nIndex = -1; 1128 | 1129 | for (qint32 i = 0; i < nNumberOfItems; i++) { 1130 | if (sValue == pComboBox->itemData(i, Qt::UserRole)) { 1131 | nIndex = i; 1132 | } 1133 | } 1134 | 1135 | if (nIndex != -1) { 1136 | pComboBox->setCurrentIndex(nIndex); 1137 | } 1138 | 1139 | pComboBox->blockSignals(bBlocked1); 1140 | } 1141 | #endif 1142 | #ifdef QT_GUI_LIB 1143 | void XOptions::getComboBox(QComboBox *pComboBox, XOptions::ID id) 1144 | { 1145 | setValue(id, pComboBox->currentData()); 1146 | } 1147 | #endif 1148 | #ifdef QT_GUI_LIB 1149 | void XOptions::setLineEdit(QLineEdit *pLineEdit, XOptions::ID id) 1150 | { 1151 | pLineEdit->setText(getValue(id).toString()); 1152 | } 1153 | #endif 1154 | #ifdef QT_GUI_LIB 1155 | void XOptions::getLineEdit(QLineEdit *pLineEdit, XOptions::ID id) 1156 | { 1157 | setValue(id, pLineEdit->text()); 1158 | } 1159 | #endif 1160 | bool XOptions::isSaveBackup() 1161 | { 1162 | return getValue(XOptions::ID_FILE_SAVEBACKUP).toBool(); 1163 | } 1164 | 1165 | bool XOptions::isSaveLastDirectory() 1166 | { 1167 | return getValue(XOptions::ID_FILE_SAVELASTDIRECTORY).toBool(); 1168 | } 1169 | 1170 | bool XOptions::isSaveRecentFiles() 1171 | { 1172 | return getValue(XOptions::ID_FILE_SAVERECENTFILES).toBool(); 1173 | } 1174 | 1175 | bool XOptions::isRestartNeeded() 1176 | { 1177 | return m_bIsNeedRestart; 1178 | } 1179 | 1180 | bool XOptions::isStayOnTop() 1181 | { 1182 | return getValue(XOptions::ID_VIEW_STAYONTOP).toBool(); 1183 | } 1184 | 1185 | bool XOptions::isScanAfterOpen() 1186 | { 1187 | return getValue(XOptions::ID_SCAN_SCANAFTEROPEN).toBool(); 1188 | } 1189 | 1190 | bool XOptions::isSingleApplication() 1191 | { 1192 | return getValue(XOptions::ID_VIEW_SINGLEAPPLICATION).toBool(); 1193 | } 1194 | 1195 | bool XOptions::isShowLogo() 1196 | { 1197 | return getValue(XOptions::ID_VIEW_SHOWLOGO).toBool(); 1198 | } 1199 | 1200 | QString XOptions::getSearchSignaturesPath() 1201 | { 1202 | return getValue(XOptions::ID_SIGNATURES_PATH).toString(); 1203 | } 1204 | 1205 | QString XOptions::getStructsPath() 1206 | { 1207 | return getValue(XOptions::ID_STRUCTS_PATH).toString(); 1208 | } 1209 | 1210 | void XOptions::adjustApplicationInitAttributes() 1211 | { 1212 | #ifdef QT_GUI_LIB 1213 | #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) 1214 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 1215 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 1216 | #endif 1217 | #endif 1218 | #endif 1219 | } 1220 | #ifdef QT_GUI_LIB 1221 | QColor XOptions::stringToColor(QString sColor) 1222 | { 1223 | QColor result; 1224 | 1225 | if (sColor != "") { 1226 | result.setNamedColor(sColor); 1227 | } 1228 | 1229 | return result; 1230 | } 1231 | #endif 1232 | #ifdef QT_GUI_LIB 1233 | QString XOptions::colorToString(const QColor &color) 1234 | { 1235 | return color.name(); 1236 | } 1237 | #endif 1238 | #ifdef QT_GUI_LIB 1239 | QIcon XOptions::createIcon(QChar unicode, qint32 nWidth, qint32 nHeight) 1240 | { 1241 | return createIcon(unicode.unicode(), nWidth, nHeight); 1242 | } 1243 | 1244 | QIcon XOptions::createIcon(quint32 codepoint, qint32 nWidth, qint32 nHeight) 1245 | { 1246 | // Create a pixmap with the specified dimensions 1247 | QPixmap pixmap(nWidth, nHeight); 1248 | pixmap.fill(Qt::transparent); 1249 | 1250 | // Setup painter 1251 | QPainter painter(&pixmap); 1252 | painter.setRenderHint(QPainter::Antialiasing); 1253 | painter.setRenderHint(QPainter::TextAntialiasing); 1254 | 1255 | // Setup font - try multiple emoji fonts 1256 | QFont font; 1257 | font.setPixelSize(qMin(nWidth, nHeight) * 0.8); // 80% of size for better fit 1258 | 1259 | font.setFamily("Segoe UI Emoji"); 1260 | 1261 | painter.setFont(font); 1262 | 1263 | // Draw the Unicode character centered 1264 | painter.setPen(Qt::black); 1265 | 1266 | // Convert codepoint to QString properly 1267 | QString text; 1268 | if (codepoint <= 0xFFFF) { 1269 | text = QString(QChar(codepoint)); 1270 | } else { 1271 | // Handle surrogate pairs for codepoints > U+FFFF 1272 | text = QString::fromUcs4(&codepoint, 1); 1273 | } 1274 | 1275 | painter.drawText(pixmap.rect(), Qt::AlignCenter, text); 1276 | 1277 | painter.end(); 1278 | 1279 | // // Debug: Save icon to C:\tmp 1280 | // static bool debugDumpEnabled = true; 1281 | // if (debugDumpEnabled) { 1282 | // QString filename = QString("C:/tmp/icon_%1_%2x%3_U%4.png") 1283 | // .arg(QDateTime::currentMSecsSinceEpoch()) 1284 | // .arg(nWidth) 1285 | // .arg(nHeight) 1286 | // .arg(codepoint, 4, 16, QChar('0')); 1287 | // pixmap.save(filename); 1288 | // #ifdef QT_DEBUG 1289 | // qDebug() << "Saved icon:" << filename << "text:" << text << "code:" << QString("U+%1").arg(codepoint, 4, 16, QChar('0')); 1290 | // #endif 1291 | // } 1292 | 1293 | return QIcon(pixmap); 1294 | } 1295 | 1296 | quint32 XOptions::iconTypeToUnicodeSymbol(ICONTYPE iconType) 1297 | { 1298 | quint32 result; 1299 | 1300 | switch (iconType) { 1301 | case ICONTYPE_ACTION: result = 0x26A1; break; // ⚡ - High Voltage Sign (action/execute) 1302 | case ICONTYPE_ADD: result = 0x2795; break; // ➕ - Heavy Plus Sign 1303 | case ICONTYPE_ADDRESS: result = 0x1F4CD; break; // 📍 - Round Pushpin (location/address) 1304 | case ICONTYPE_ALL: result = 0x2261; break; // ≡ - Identical To (all/everything) 1305 | case ICONTYPE_BACKWARD: result = 0x23EA; break; // ⏪ - Black Left-Pointing Double Triangle 1306 | case ICONTYPE_BOOKMARK: result = 0x1F516; break; // 🔖 - Bookmark 1307 | case ICONTYPE_CERTIFICATE: result = 0x1F4DC; break; // 📜 - Scroll (certificate) 1308 | case ICONTYPE_CODE: result = 0x1F5CB; break; // 🗋 - Document (code file) 1309 | case ICONTYPE_COPY: result = 0x1F4CB; break; // 📋 - Clipboard 1310 | case ICONTYPE_DATA: result = 0x1F4CA; break; // 📊 - Bar Chart (data) 1311 | case ICONTYPE_DEBUG: result = 0x1F41E; break; // 🐞 - Lady Beetle (debug) 1312 | case ICONTYPE_DEMANGLE: result = 0x1F9F5; break; // 🧵 - Thread (untangle) 1313 | case ICONTYPE_DIE: result = 0x1F3B2; break; // 🎲 - Game Die 1314 | case ICONTYPE_DISASM: result = 0x2699; break; // ⚙ - Gear (disassembly) 1315 | case ICONTYPE_DOTNET: result = 0x1F310; break; // 🌐 - Globe With Meridians (.NET) 1316 | case ICONTYPE_DUMPTOFILE: result = 0x1F4BE; break; // 💾 - Floppy Disk (save/dump) 1317 | case ICONTYPE_EDIT: result = 0x270E; break; // ✎ - Lower Right Pencil 1318 | case ICONTYPE_ENTROPY: result = 0x1F300; break; // 🌀 - Cyclone (chaos/entropy) 1319 | case ICONTYPE_ENTRY: result = 0x1F6AA; break; // 🚪 - Door (entry point) 1320 | case ICONTYPE_EXCEPTION: result = 0x26A0; break; // ⚠ - Warning Sign 1321 | case ICONTYPE_EXIT: result = 0x1F6AA; break; // 🚪 - Door (exit) 1322 | case ICONTYPE_EXPORT: result = 0x1F4E4; break; // 📤 - Outbox Tray 1323 | case ICONTYPE_EXTRACTOR: result = 0x1F5C4; break; // 🗄 - File Cabinet (extract) 1324 | case ICONTYPE_FILE: result = 0x1F4C4; break; // 📄 - Page Facing Up 1325 | case ICONTYPE_FOLLOW: result = 0x1F517; break; // 🔗 - Link Symbol 1326 | case ICONTYPE_FORWARD: result = 0x23E9; break; // ⏩ - Black Right-Pointing Double Triangle 1327 | case ICONTYPE_FUNCTION: result = 0x0192; break; // ƒ - Latin Small Letter F With Hook 1328 | case ICONTYPE_GENERIC: result = 0x25A0; break; // ■ - Black Square 1329 | case ICONTYPE_GOTO: result = 0x21E8; break; // ⇨ - Rightwards White Arrow 1330 | case ICONTYPE_HASH: result = 0x0023; break; // # - Number Sign 1331 | case ICONTYPE_HEADER: result = 0x1F4C3; break; // 📃 - Page With Curl 1332 | case ICONTYPE_HEX: result = 0x0023; break; // # - Number Sign (hex) 1333 | case ICONTYPE_IMPORT: result = 0x1F4E5; break; // 📥 - Inbox Tray 1334 | case ICONTYPE_INFO: result = 0x2139; break; // ℹ - Information Source 1335 | case ICONTYPE_LIBRARY: result = 0x1F4DA; break; // 📚 - Books 1336 | case ICONTYPE_LIST: result = 0x1F4CB; break; // 📋 - Clipboard (list) 1337 | case ICONTYPE_MANIFEST: result = 0x1F4DC; break; // 📜 - Scroll (manifest) 1338 | case ICONTYPE_MEMORYMAP: result = 0x1F5FA; break; // 🗺 - World Map 1339 | case ICONTYPE_METADATA: result = 0x1F3F7; break; // 🏷 - Label (metadata) 1340 | case ICONTYPE_MIME: result = 0x1F4CE; break; // 📎 - Paperclip (MIME type) 1341 | case ICONTYPE_NEW: result = 0x2795; break; // ➕ - Heavy Plus Sign (new/add) 1342 | case ICONTYPE_NEXT: result = 0x25B6; break; // ▶ - Black Right-Pointing Triangle 1343 | case ICONTYPE_NFD: result = 0x1F4C2; break; // 📂 - Open File Folder 1344 | case ICONTYPE_NOTE: result = 0x1F4DD; break; // 📝 - Memo 1345 | case ICONTYPE_OFFSET: result = 0x21F1; break; // ⇱ - North West Arrow To Corner 1346 | case ICONTYPE_OPEN: result = 0x1F4C2; break; // 📂 - Open File Folder 1347 | case ICONTYPE_OPTION: result = 0x2699; break; // ⚙ - Gear (option/setting) 1348 | case ICONTYPE_OVERLAY: result = 0x1F5C4; break; // 🗄 - File Cabinet (overlay) 1349 | case ICONTYPE_PATCH: result = 0x1FA79; break; // 🩹 - Adhesive Bandage 1350 | case ICONTYPE_PATH: result = 0x1F6E4; break; // 🛤 - Railway Track (path) 1351 | case ICONTYPE_REFERENCE: result = 0x1F517; break; // 🔗 - Link Symbol (reference) 1352 | case ICONTYPE_RELOAD: result = 0x21BB; break; // ↻ - Clockwise Open Circle Arrow (refresh/reload) 1353 | case ICONTYPE_RELOC: result = 0x1F4CD; break; // 📍 - Round Pushpin (relocation) 1354 | case ICONTYPE_REMOVE: result = 0x2796; break; // ➖ - Heavy Minus Sign 1355 | case ICONTYPE_RESIZE: result = 0x21D4; break; // ⇔ - Left Right Double Arrow 1356 | case ICONTYPE_RESOURCE: result = 0x1F4E6; break; // 📦 - Package 1357 | case ICONTYPE_SAVE: result = 0x1F5AB; break; // 🖫 - White Hard Shell Floppy Disk 1358 | case ICONTYPE_SCAN: result = 0x1F50D; break; // 🔍 - Left-Pointing Magnifying Glass (scan/search) 1359 | case ICONTYPE_SCRIPT: result = 0x1F4DC; break; // 📜 - Scroll (script) 1360 | case ICONTYPE_SEARCH: result = 0x1F50D; break; // 🔍 - Left-Pointing Magnifying Glass 1361 | case ICONTYPE_SECTION: result = 0x00A7; break; // § - Section Sign 1362 | case ICONTYPE_SEGMENT: result = 0x25A8; break; // ▨ - Square With Upper Right To Lower Left Fill 1363 | case ICONTYPE_SELECT: result = 0x1F5F1; break; // 🗱 - Ballot Box With Check 1364 | case ICONTYPE_SHORTCUT: result = 0x1F517; break; // 🔗 - Link Symbol (shortcut) 1365 | case ICONTYPE_SIGNATURE: result = 0x270D; break; // ✍ - Writing Hand 1366 | case ICONTYPE_SIZE: result = 0x1F4CF; break; // 📏 - Straight Ruler 1367 | case ICONTYPE_STRING: result = 0x1F4AC; break; // 💬 - Speech Balloon 1368 | case ICONTYPE_STRUCTS: result = 0x1F9F1; break; // 🧱 - Brick (structure) 1369 | case ICONTYPE_SYMBOL: result = 0x1F523; break; // 🔣 - Input Symbol For Symbols 1370 | case ICONTYPE_TABLE: result = 0x1F5C3; break; // 🗃 - Card File Box 1371 | case ICONTYPE_TLS: result = 0x1F512; break; // 🔒 - Lock (TLS/security) 1372 | case ICONTYPE_TOOL: result = 0x1F527; break; // 🔧 - Wrench 1373 | case ICONTYPE_VALUE: result = 0x1F4B0; break; // 💰 - Money Bag (value) 1374 | case ICONTYPE_VERSION: result = 0x1F4C5; break; // 📅 - Calendar (version) 1375 | case ICONTYPE_VIRUSTOTAL: result = 0x1F9A0; break; // 🦠 - Microbe (virus) 1376 | case ICONTYPE_VISUALIZATION: result = 0x1F4CA; break; // 📊 - Bar Chart 1377 | case ICONTYPE_WEBSITE: result = 0x1F310; break; // 🌐 - Globe With Meridians 1378 | case ICONTYPE_YARA: result = 0x1F50E; break; // 🔎 - Right-Pointing Magnifying Glass (Yara scan) 1379 | case ICONTYPE_INSPECTOR: result = 0x1F50D; break; // 🔍 - Left-Pointing Magnifying Glass 1380 | case ICONTYPE_CONVERTOR: result = 0x21C4; break; // ⇄ - Rightwards Arrow Over Leftwards Arrow 1381 | 1382 | case ICONTYPE_NONE: 1383 | default: 1384 | result = 0; // Null character for unmapped types 1385 | break; 1386 | } 1387 | 1388 | return result; 1389 | } 1390 | #endif 1391 | #ifdef QT_GUI_LIB 1392 | void XOptions::adjustApplicationView(const QString &sTranslationName, XOptions *pOptions) 1393 | { 1394 | if (pOptions->isIDPresent(XOptions::ID_VIEW_STYLE)) { 1395 | QString sStyle = pOptions->getValue(XOptions::ID_VIEW_STYLE).toString(); 1396 | 1397 | if (sStyle != "") { 1398 | qApp->setStyle(QStyleFactory::create(sStyle)); 1399 | } 1400 | } 1401 | 1402 | if (pOptions->isIDPresent(XOptions::ID_VIEW_LANG)) { 1403 | QTranslator *pTranslator = new QTranslator; // Important 1404 | QString sLang = pOptions->getValue(XOptions::ID_VIEW_LANG).toString(); 1405 | QString sLangsPath = pOptions->getApplicationLangPath(); 1406 | 1407 | bool bLoad = false; 1408 | 1409 | if (sLang == "System") { 1410 | QLocale locale = QLocale::system(); 1411 | if (locale != QLocale::English) { 1412 | bLoad = pTranslator->load(locale, sTranslationName, "_", sLangsPath, ".qm"); 1413 | } 1414 | } else if (sLang != "") { 1415 | bLoad = pTranslator->load(sLang, sLangsPath); 1416 | } 1417 | 1418 | if (bLoad) { 1419 | qApp->installTranslator(pTranslator); 1420 | } 1421 | } 1422 | 1423 | if (pOptions->isIDPresent(XOptions::ID_VIEW_QSS)) { 1424 | QString sQss = pOptions->getValue(XOptions::ID_VIEW_QSS).toString(); 1425 | 1426 | if (sQss != "") { 1427 | QString sQssFileName = pOptions->getApplicationQssPath() + QDir::separator() + QString("%1.qss").arg(sQss); 1428 | 1429 | if (QFile::exists(sQssFileName)) { 1430 | QFile file; 1431 | file.setFileName(sQssFileName); 1432 | 1433 | if (file.open(QIODevice::ReadOnly)) { 1434 | QByteArray baQss = file.readAll(); 1435 | qApp->setStyleSheet(baQss.data()); 1436 | file.close(); 1437 | } 1438 | } 1439 | } 1440 | } 1441 | 1442 | if (pOptions->isIDPresent(XOptions::ID_VIEW_FONT)) { 1443 | QString sFont = pOptions->getValue(XOptions::ID_VIEW_FONT).toString(); 1444 | 1445 | if (sFont != "") { 1446 | qApp->setFont(sFont); 1447 | } 1448 | } 1449 | } 1450 | #endif 1451 | #ifdef QT_GUI_LIB 1452 | void XOptions::adjustListWidgetSize(QListWidget *pListWidget, qint32 nMinimumWidth) 1453 | { 1454 | qint32 nWidth = nMinimumWidth; 1455 | 1456 | qint32 nNumberOfRecords = pListWidget->count(); 1457 | 1458 | for (qint32 i = 0; i < nNumberOfRecords; i++) { 1459 | QString sText = pListWidget->item(i)->text() + "WWWW"; 1460 | nWidth = qMax(QFontMetrics(pListWidget->item(i)->font()).size(Qt::TextSingleLine, sText).width(), nWidth); 1461 | } 1462 | 1463 | pListWidget->setMinimumWidth(0); 1464 | pListWidget->setMaximumWidth(nWidth); 1465 | } 1466 | #endif 1467 | #ifdef QT_GUI_LIB 1468 | qint32 XOptions::_getTreeWidgetItemSize(QTreeWidget *pTreeWidget, QTreeWidgetItem *pTreeWidgetItem, qint32 nIndent, qint32 nLevel) 1469 | { 1470 | qint32 nResult = 0; 1471 | 1472 | QString sText = pTreeWidgetItem->text(0) + "WW"; 1473 | 1474 | QFont _font = pTreeWidget->font(); 1475 | QString sFont = _font.toString(); 1476 | 1477 | nResult = QFontMetrics(_font).size(Qt::TextSingleLine, sText).width() + ((nIndent + 16) * nLevel); // 16 size of icon 1478 | 1479 | qint32 nNumberOfRecords = pTreeWidgetItem->childCount(); 1480 | 1481 | for (qint32 i = 0; i < nNumberOfRecords; i++) { 1482 | nResult = qMax(_getTreeWidgetItemSize(pTreeWidget, pTreeWidgetItem->child(i), nIndent, nLevel + 1), nResult); 1483 | } 1484 | 1485 | return nResult; 1486 | } 1487 | #endif 1488 | #ifdef QT_GUI_LIB 1489 | void XOptions::adjustTreeWidgetSize(QTreeWidget *pTreeWidget, qint32 nMinimumWidth) 1490 | { 1491 | qint32 nWidth = nMinimumWidth; 1492 | qint32 nIndent = pTreeWidget->indentation(); 1493 | qint32 nNumberOfItems = pTreeWidget->topLevelItemCount(); 1494 | 1495 | for (qint32 i = 0; i < nNumberOfItems; i++) { 1496 | nWidth = qMax(_getTreeWidgetItemSize(pTreeWidget, pTreeWidget->topLevelItem(i), nIndent, 1), nWidth); 1497 | } 1498 | 1499 | pTreeWidget->setMinimumWidth(0); 1500 | pTreeWidget->setMaximumWidth(nWidth); 1501 | } 1502 | #endif 1503 | // #ifdef QT_GUI_LIB 1504 | // void XOptions::adjustApplicationView(QString sApplicationFileName,QString 1505 | // sTranslationName) 1506 | //{ 1507 | // XOptions xOptions; 1508 | 1509 | // xOptions.setName(sApplicationFileName); 1510 | 1511 | // QList listIDs; 1512 | 1513 | // listIDs.append(XOptions::ID_VIEW_STYLE); 1514 | // listIDs.append(XOptions::ID_VIEW_LANG); 1515 | // listIDs.append(XOptions::ID_VIEW_QSS); 1516 | 1517 | // xOptions.setValueIDs(listIDs); 1518 | // xOptions.load(); 1519 | 1520 | // xOptions.adjustApplicationView(sTranslationName,&xOptions); 1521 | //} 1522 | // #endif 1523 | #ifdef QT_GUI_LIB 1524 | QWidget *XOptions::getMainWidget(QWidget *pWidget) 1525 | { 1526 | QWidget *pResult = pWidget; 1527 | 1528 | if (pResult) { 1529 | while (pResult->parent()) { 1530 | pResult = qobject_cast(pResult->parent()); 1531 | } 1532 | } 1533 | 1534 | return pResult; 1535 | } 1536 | #endif 1537 | #ifdef QT_GUI_LIB 1538 | QString XOptions::getTableModelText(QAbstractItemModel *pModel) 1539 | { 1540 | QString sResult; 1541 | 1542 | if (pModel) { 1543 | qint32 nNumberOfRows = pModel->rowCount(); 1544 | qint32 nNumberOfColumns = pModel->columnCount(); 1545 | 1546 | QList listHeaders; 1547 | QList> listListStrings; 1548 | 1549 | for (qint32 i = 0; i < nNumberOfColumns; i++) { 1550 | QString sHeader = pModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); 1551 | 1552 | listHeaders.append(sHeader); 1553 | } 1554 | 1555 | for (qint32 i = 0; i < nNumberOfRows; i++) { 1556 | QList listStrings; 1557 | 1558 | for (qint32 j = 0; j < nNumberOfColumns; j++) { 1559 | QString sString = pModel->data(pModel->index(i, j)).toString(); 1560 | 1561 | listStrings.append(sString); 1562 | } 1563 | 1564 | listListStrings.append(listStrings); 1565 | } 1566 | 1567 | for (qint32 i = 0; i < nNumberOfColumns; i++) { 1568 | if (i != (nNumberOfColumns - 1)) { 1569 | sResult += QString("%1\t").arg(listHeaders.at(i)); 1570 | } else { 1571 | sResult += QString("%1\r\n").arg(listHeaders.at(i)); 1572 | } 1573 | } 1574 | 1575 | // mb TODO: csv,tsv,json,xml,json 1576 | qint32 _nNumberOfLines = listListStrings.count(); 1577 | 1578 | for (qint32 i = 0; i < _nNumberOfLines; i++) { 1579 | qint32 _nNumberOfColumns = listListStrings.at(i).count(); 1580 | 1581 | for (qint32 j = 0; j < _nNumberOfColumns; j++) { 1582 | QString sString = listListStrings.at(i).at(j); 1583 | 1584 | if (j != (_nNumberOfColumns - 1)) { 1585 | sResult += QString("%1\t").arg(sString); 1586 | } else { 1587 | sResult += QString("%1\r\n").arg(sString); 1588 | } 1589 | } 1590 | } 1591 | } 1592 | 1593 | return sResult; 1594 | } 1595 | #endif 1596 | #ifdef QT_GUI_LIB 1597 | void XOptions::_getTreeModelText(QString *psString, QAbstractItemModel *pModel, QModelIndex index, qint32 nLevel) 1598 | { 1599 | qint32 nNumberOfRows = pModel->rowCount(index); 1600 | qint32 nNumberOfColumns = pModel->columnCount(index); 1601 | 1602 | for (qint32 i = 0; i < nNumberOfRows; i++) { 1603 | QString sPrefix; 1604 | sPrefix = sPrefix.leftJustified(4 * nLevel, ' '); 1605 | 1606 | *psString += sPrefix; 1607 | 1608 | for (qint32 j = 0; j < nNumberOfColumns; j++) { 1609 | QString sString = pModel->data(pModel->index(i, j, index)).toString(); 1610 | 1611 | if (j != (nNumberOfColumns - 1)) { 1612 | *psString += QString("%1\t").arg(sString); 1613 | } else { 1614 | *psString += QString("%1\r\n").arg(sString); 1615 | } 1616 | } 1617 | 1618 | if (nNumberOfColumns) { 1619 | _getTreeModelText(psString, pModel, pModel->index(i, 0, index), nLevel + 1); 1620 | } 1621 | } 1622 | } 1623 | #endif 1624 | #ifdef QT_GUI_LIB 1625 | QString XOptions::getTreeModelText(QAbstractItemModel *pModel) 1626 | { 1627 | QString sResult; 1628 | 1629 | if (pModel) { 1630 | _getTreeModelText(&sResult, pModel, QModelIndex(), 0); 1631 | } 1632 | 1633 | return sResult; 1634 | } 1635 | #endif 1636 | #ifdef QT_GUI_LIB 1637 | bool XOptions::saveTableModel(QAbstractItemModel *pModel, const QString &sFileName) 1638 | { 1639 | bool bResult = false; 1640 | 1641 | QFile file; 1642 | file.setFileName(sFileName); 1643 | 1644 | if (file.open(QIODevice::ReadWrite)) { 1645 | QString sText = getTableModelText(pModel); 1646 | 1647 | file.resize(0); 1648 | file.write(sText.toUtf8().data()); 1649 | file.close(); 1650 | 1651 | bResult = true; 1652 | } 1653 | 1654 | return bResult; 1655 | } 1656 | #endif 1657 | #ifdef QT_GUI_LIB 1658 | bool XOptions::saveTreeModel(QAbstractItemModel *pModel, const QString &sFileName) 1659 | { 1660 | bool bResult = false; 1661 | 1662 | QFile file; 1663 | file.setFileName(sFileName); 1664 | 1665 | if (file.open(QIODevice::ReadWrite)) { 1666 | QString sText = getTreeModelText(pModel); 1667 | 1668 | file.resize(0); 1669 | file.write(sText.toUtf8().data()); 1670 | file.close(); 1671 | 1672 | bResult = true; 1673 | } 1674 | 1675 | return bResult; 1676 | } 1677 | #endif 1678 | #ifdef QT_GUI_LIB 1679 | bool XOptions::saveTextEdit(QTextEdit *pTextEdit, const QString &sFileName) 1680 | { 1681 | bool bResult = false; 1682 | 1683 | QFile file; 1684 | file.setFileName(sFileName); 1685 | 1686 | if (file.open(QIODevice::ReadWrite)) { 1687 | QString sResult = pTextEdit->toPlainText(); 1688 | 1689 | file.resize(0); 1690 | file.write(sResult.toUtf8().data()); 1691 | file.close(); 1692 | 1693 | bResult = true; 1694 | } 1695 | 1696 | return bResult; 1697 | } 1698 | #endif 1699 | #ifdef QT_GUI_LIB 1700 | bool XOptions::savePlainTextEdit(QPlainTextEdit *pPlainTextEdit, const QString &sFileName) 1701 | { 1702 | bool bResult = false; 1703 | 1704 | QFile file; 1705 | file.setFileName(sFileName); 1706 | 1707 | if (file.open(QIODevice::ReadWrite)) { 1708 | QString sResult = pPlainTextEdit->toPlainText(); 1709 | 1710 | file.resize(0); 1711 | file.write(sResult.toUtf8().data()); 1712 | file.close(); 1713 | 1714 | bResult = true; 1715 | } 1716 | 1717 | return bResult; 1718 | } 1719 | #endif 1720 | #ifdef QT_GUI_LIB 1721 | bool XOptions::saveTableView(QTableView *pTableView, const QString &sFileName) 1722 | { 1723 | return saveTableModel(pTableView->model(), sFileName); 1724 | } 1725 | #endif 1726 | #ifdef QT_GUI_LIB 1727 | bool XOptions::saveTableWidget(QTableWidget *pTableWidget, const QString &sFileName) 1728 | { 1729 | return saveTableModel(pTableWidget->model(), sFileName); 1730 | } 1731 | #endif 1732 | #ifdef QT_GUI_LIB 1733 | bool XOptions::saveListView(QListView *pListView, const QString &sFileName) 1734 | { 1735 | return saveTableModel(pListView->model(), sFileName); 1736 | } 1737 | #endif 1738 | #ifdef QT_GUI_LIB 1739 | bool XOptions::saveListWidget(QListWidget *pListWidget, const QString &sFileName) 1740 | { 1741 | return saveTableModel(pListWidget->model(), sFileName); 1742 | } 1743 | #endif 1744 | #ifdef QT_GUI_LIB 1745 | bool XOptions::saveTreeView(QTreeView *pTreeView, const QString &sFileName) 1746 | { 1747 | return saveTreeModel(pTreeView->model(), sFileName); 1748 | } 1749 | #endif 1750 | #ifdef QT_GUI_LIB 1751 | bool XOptions::saveTreeWidget(QTreeWidget *pTreeWidget, const QString &sFileName) 1752 | { 1753 | return saveTreeModel(pTreeWidget->model(), sFileName); 1754 | } 1755 | #endif 1756 | #ifdef QT_GUI_LIB 1757 | bool XOptions::saveTextBrowser(QTextBrowser *pTextBrowser, const QString &sFileName) 1758 | { 1759 | bool bResult = false; 1760 | 1761 | QFile file; 1762 | file.setFileName(sFileName); 1763 | 1764 | if (file.open(QIODevice::ReadWrite)) { 1765 | QString sResult = pTextBrowser->toPlainText(); 1766 | 1767 | file.resize(0); 1768 | file.write(sResult.toUtf8().data()); 1769 | file.close(); 1770 | 1771 | bResult = true; 1772 | } 1773 | 1774 | return bResult; 1775 | } 1776 | #endif 1777 | #ifdef QT_GUI_LIB 1778 | bool XOptions::saveTextBrowserHtml(QTextBrowser *pTextBrowser, const QString &sFileName) 1779 | { 1780 | bool bResult = false; 1781 | 1782 | QFile file; 1783 | file.setFileName(sFileName); 1784 | 1785 | if (file.open(QIODevice::ReadWrite)) { 1786 | QString sResult = pTextBrowser->toHtml(); 1787 | 1788 | file.resize(0); 1789 | file.write(sResult.toUtf8().data()); 1790 | file.close(); 1791 | 1792 | bResult = true; 1793 | } 1794 | 1795 | return bResult; 1796 | } 1797 | #endif 1798 | #ifdef QT_GUI_LIB 1799 | QMenu *XOptions::createRecentFilesMenu(QWidget *pParent) 1800 | { 1801 | m_pRecentFilesMenu = new QMenu(tr("Recent files"), pParent); 1802 | 1803 | _updateRecentFilesMenu(); 1804 | 1805 | return m_pRecentFilesMenu; 1806 | } 1807 | #endif 1808 | #ifdef QT_GUI_LIB 1809 | qint32 XOptions::getCharWidth(QWidget *pWidget) 1810 | { 1811 | const QFontMetricsF fm(pWidget->font()); 1812 | 1813 | return fm.maxWidth(); 1814 | } 1815 | #endif 1816 | #ifdef QT_GUI_LIB 1817 | qint32 XOptions::getCharHeight(QWidget *pWidget) 1818 | { 1819 | const QFontMetricsF fm(pWidget->font()); 1820 | 1821 | return fm.height(); 1822 | } 1823 | #endif 1824 | #ifdef QT_GUI_LIB 1825 | qint32 XOptions::getControlWidth(QWidget *pWidget, qint32 nSymbolSize) 1826 | { 1827 | QFontMetrics fm(pWidget->font()); 1828 | 1829 | QString sText = QString(nSymbolSize, '0') + QString(2, ' '); 1830 | 1831 | return fm.boundingRect(sText).width(); 1832 | } 1833 | #endif 1834 | #ifdef QT_GUI_LIB 1835 | void XOptions::showInFolder(const QString &sFileName) 1836 | { 1837 | // TODO: https://github.com/qt-creator/qt-creator/blob/master/src/plugins/coreplugin/fileutils.cpp#L67 1838 | QFileInfo fi = QFileInfo(sFileName); 1839 | 1840 | #if defined(Q_OS_WIN) 1841 | QStringList slParams; 1842 | if (!fi.isDir()) { 1843 | slParams += QLatin1String("/select,"); 1844 | } 1845 | 1846 | slParams += QDir::toNativeSeparators(fi.canonicalFilePath()); 1847 | 1848 | QProcess::startDetached("explorer.exe", slParams); 1849 | #elif defined(Q_OS_MAC) 1850 | QStringList slParams; 1851 | slParams << "-e"; 1852 | slParams << "tell application \"Finder\""; 1853 | slParams << "-e"; 1854 | slParams << "activate"; 1855 | slParams << "-e"; 1856 | slParams << "select POSIX file \"" + fi.path() + "\""; 1857 | slParams << "-e"; 1858 | slParams << "end tell"; 1859 | slParams << "-e"; 1860 | slParams << "return"; 1861 | QProcess::execute("/usr/bin/osascript", slParams); 1862 | #else 1863 | QDesktopServices::openUrl(QUrl::fromLocalFile(fi.path())); 1864 | #endif 1865 | } 1866 | #endif 1867 | #ifdef QT_GUI_LIB 1868 | void XOptions::showFolder(const QString &sDirectory) 1869 | { 1870 | #if defined(Q_OS_WIN) 1871 | QStringList slParams; 1872 | 1873 | slParams += QDir::toNativeSeparators(sDirectory); 1874 | 1875 | QProcess::startDetached("explorer.exe", slParams); 1876 | #elif defined(Q_OS_MAC) 1877 | QStringList slParams; 1878 | slParams << "-e"; 1879 | slParams << "tell application \"Finder\""; 1880 | slParams << "-e"; 1881 | slParams << "activate"; 1882 | slParams << "-e"; 1883 | slParams << "select POSIX file \"" + sDirectory + "\""; // TODO: Check 1884 | slParams << "-e"; 1885 | slParams << "end tell"; 1886 | slParams << "-e"; 1887 | slParams << "return"; 1888 | QProcess::execute("/usr/bin/osascript", slParams); 1889 | #else 1890 | QDesktopServices::openUrl(QUrl::fromLocalFile(sDirectory)); 1891 | #endif 1892 | } 1893 | #endif 1894 | #ifdef QT_GUI_LIB 1895 | void XOptions::handleFontButton(QWidget *pParent, QLineEdit *pLineEdit) 1896 | { 1897 | QFont _font; 1898 | _font.fromString(pLineEdit->text()); 1899 | 1900 | bool bOK = false; 1901 | _font = QFontDialog::getFont(&bOK, _font, pParent); 1902 | 1903 | if (bOK) { 1904 | pLineEdit->setText(_font.toString()); 1905 | } 1906 | } 1907 | #endif 1908 | #ifdef QT_GUI_LIB 1909 | void XOptions::setModelTextAlignment(QStandardItemModel *pModel, qint32 nColumn, Qt::Alignment flag) 1910 | { 1911 | qint32 nNumberOfRows = pModel->rowCount(); 1912 | 1913 | pModel->setHeaderData(nColumn, Qt::Horizontal, (qint32)flag, Qt::TextAlignmentRole); 1914 | 1915 | for (qint32 i = 0; i < nNumberOfRows; i++) { 1916 | QStandardItem *pItem = pModel->item(i, nColumn); 1917 | 1918 | if (pItem) { 1919 | pItem->setTextAlignment(flag); 1920 | // pModel->setData(pModel->index(i, nColumn), (qint32)flag, Qt::TextAlignmentRole); 1921 | 1922 | QModelIndex index = pModel->index(i, 0); 1923 | qint32 _nNumberOfRows = pModel->rowCount(index); 1924 | 1925 | for (qint32 j = 0; j < _nNumberOfRows; j++) { 1926 | pModel->setData(pModel->index(j, nColumn, index), (qint32)flag, Qt::TextAlignmentRole); 1927 | } 1928 | } 1929 | } 1930 | } 1931 | #endif 1932 | #ifdef QT_GUI_LIB 1933 | void XOptions::setTableViewHeaderWidth(QTableView *pTableView, qint32 nColumn, qint32 nContentWidth) 1934 | { 1935 | QFont font = pTableView->font(); 1936 | font.setBold(true); 1937 | 1938 | const QFontMetricsF fm(font); 1939 | 1940 | QString sTitle = pTableView->model()->headerData(nColumn, Qt::Horizontal, Qt::DisplayRole).toString(); 1941 | 1942 | qreal rWidth = fm.boundingRect(sTitle + " ").width(); 1943 | 1944 | nContentWidth = qMax(nContentWidth, (qint32)(rWidth)); 1945 | 1946 | pTableView->setColumnWidth(nColumn, nContentWidth); 1947 | } 1948 | #endif 1949 | #ifdef QT_GUI_LIB 1950 | void XOptions::setTreeViewHeaderWidth(QTreeView *pTreeView, qint32 nColumn, qint32 nContentWidth) 1951 | { 1952 | QFont font = pTreeView->font(); 1953 | font.setBold(true); 1954 | 1955 | const QFontMetricsF fm(font); 1956 | 1957 | QString sTitle = pTreeView->model()->headerData(nColumn, Qt::Horizontal, Qt::DisplayRole).toString(); 1958 | 1959 | qreal rWidth = fm.boundingRect(sTitle + " ").width(); 1960 | 1961 | nContentWidth = qMax(nContentWidth, (qint32)(rWidth)); 1962 | 1963 | pTreeView->setColumnWidth(nColumn, nContentWidth); 1964 | } 1965 | #endif 1966 | #ifdef QT_GUI_LIB 1967 | void XOptions::setTableWidgetHeaderAlignment(QTableWidget *pTableWidget, qint32 nColumn, Qt::Alignment flag) 1968 | { 1969 | pTableWidget->model()->setHeaderData(nColumn, Qt::Horizontal, (qint32)flag, Qt::TextAlignmentRole); 1970 | } 1971 | #endif 1972 | 1973 | void XOptions::deleteQObjectList(QList *pList) 1974 | { 1975 | qint32 nNumberOfRecords = pList->count(); 1976 | 1977 | for (qint32 i = 0; i < nNumberOfRecords; i++) { 1978 | delete pList->at(i); 1979 | } 1980 | } 1981 | 1982 | QString XOptions::getApplicationLangPath() 1983 | { 1984 | QString sResult; 1985 | 1986 | sResult = getApplicationDataPath() + QDir::separator() + "lang"; 1987 | 1988 | return sResult; 1989 | } 1990 | 1991 | QString XOptions::getApplicationQssPath() 1992 | { 1993 | QString sResult; 1994 | 1995 | sResult = getApplicationDataPath() + QDir::separator() + "qss"; 1996 | 1997 | return sResult; 1998 | } 1999 | 2000 | QList XOptions::getAllFilesFromDirectory(const QString &sDirectory, const QString &sExtension) 2001 | { 2002 | QDir directory(sDirectory); 2003 | 2004 | return directory.entryList(QStringList() << sExtension, QDir::Files); 2005 | } 2006 | 2007 | bool XOptions::checkNative(const QString &sIniFileName) 2008 | { 2009 | Q_UNUSED(sIniFileName) 2010 | 2011 | QString sApplicationDirPath = qApp->applicationDirPath(); 2012 | sApplicationDirPath = QDir::cleanPath(sApplicationDirPath); 2013 | 2014 | bool bResult = false; 2015 | #if defined(Q_OS_MAC) 2016 | bResult = true; 2017 | #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) 2018 | if ((sApplicationDirPath == "/bin") || (sApplicationDirPath == "/usr/bin") || (sApplicationDirPath == "/usr/local/bin") || (sApplicationDirPath == "/app/bin") || 2019 | (sApplicationDirPath.contains("/usr/local/bin$")) || isAppImage()) { 2020 | bResult = true; 2021 | } else { 2022 | bResult = false; 2023 | } 2024 | #elif defined(Q_OS_WIN) 2025 | if (sApplicationDirPath.toLower().contains(":\\program files")) { 2026 | bResult = true; 2027 | } 2028 | #endif 2029 | 2030 | bResult = bResult || (!QFileInfo(sApplicationDirPath).isWritable()); 2031 | 2032 | return bResult; 2033 | } 2034 | 2035 | QString XOptions::getApplicationDataPath() 2036 | { 2037 | QString sResult; 2038 | 2039 | #ifdef Q_OS_MAC 2040 | sResult = sApplicationDirPath + "/../Resources"; 2041 | #endif 2042 | #ifdef Q_OS_WIN 2043 | sResult = qApp->applicationDirPath(); 2044 | #endif 2045 | #ifdef Q_OS_LINUX 2046 | if (isNative()) { 2047 | QString sApplicationDirPath = qApp->applicationDirPath(); 2048 | 2049 | if (sApplicationDirPath.contains("/usr/local/bin$")) { 2050 | QString sPrefix = sApplicationDirPath.section("/usr/local/bin", 0, 0); 2051 | 2052 | sResult += sPrefix + QString("/usr/local/lib/%1").arg(qApp->applicationName()); 2053 | } else if (sApplicationDirPath.startsWith("/app/bin")) { // Flatpak 2054 | sResult += QString("/app/lib/%1").arg(qApp->applicationName()); 2055 | } else { 2056 | if (sApplicationDirPath.contains("/tmp/.mount_")) // AppImage 2057 | { 2058 | sResult = sApplicationDirPath.section("/", 0, 2); 2059 | } 2060 | 2061 | sResult += QString("/usr/lib/%1").arg(qApp->applicationName()); 2062 | } 2063 | } else { 2064 | sResult = qApp->applicationDirPath(); 2065 | } 2066 | #endif 2067 | #ifdef X_BUILD_APPIMAGE 2068 | QString sApplicationDirPath = qApp->applicationDirPath(); 2069 | if (sApplicationDirPath.contains("/tmp/.mount_")) { 2070 | sResult = sApplicationDirPath.section("/", 0, 2); 2071 | } 2072 | sResult += QString("/usr/lib/%1").arg(qApp->applicationName()); 2073 | #endif 2074 | #ifdef X_BUILD_FLATPACK 2075 | sResult = QString("/app/lib/%1").arg(qApp->applicationName()); 2076 | #endif 2077 | #ifdef Q_OS_FREEBSD 2078 | sResult = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation).at(1) + QDir::separator() + qApp->applicationName(); 2079 | #endif 2080 | 2081 | return sResult; 2082 | } 2083 | 2084 | QString XOptions::getTitle(const QString &sName, const QString &sVersion, bool bShowOS) 2085 | { 2086 | QString sResult = QString("%1 v%2").arg(sName, sVersion); 2087 | 2088 | if (bShowOS) { 2089 | #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) 2090 | // TODO: Check Windows 11 (DiE currently detectes Windows 11 as Windows 10) 2091 | QString architecture = QSysInfo::buildCpuArchitecture(); 2092 | if (architecture == "x86_64" || architecture == "amd64") { 2093 | architecture = "x64"; 2094 | } else if (architecture == "arm32" || architecture == "armhf" || architecture == "aarch32") { 2095 | architecture = "ARM32"; 2096 | } else if (architecture == "arm64" || architecture == "aarch64") { 2097 | architecture = "ARM64"; 2098 | } else if (architecture == "i386" || architecture == "i686") { 2099 | architecture = "x86"; 2100 | } 2101 | sResult += QString(" [%1] (%2)").arg(QSysInfo::prettyProductName(), architecture); 2102 | #else 2103 | // TODO: OS Name // For Windows Arch GetVersionExA 2104 | #endif 2105 | } 2106 | 2107 | return sResult; 2108 | } 2109 | 2110 | bool XOptions::isWritable() 2111 | { 2112 | bool bResult = false; 2113 | QSettings *pSettings = nullptr; 2114 | 2115 | bool bIsNative = isNative(); 2116 | 2117 | if (bIsNative) { 2118 | pSettings = new QSettings; 2119 | } else { 2120 | pSettings = new QSettings(getApplicationDataPath() + QDir::separator() + QString("%1").arg(m_sName), QSettings::IniFormat); 2121 | } 2122 | 2123 | bResult = pSettings->isWritable(); 2124 | 2125 | delete pSettings; 2126 | 2127 | return bResult; 2128 | } 2129 | 2130 | #if (QT_VERSION_MAJOR < 6) || defined(QT_CORE5COMPAT_LIB) 2131 | 2132 | bool sort_code_page(const qint32 &nValue1, const qint32 &nValue2) 2133 | { 2134 | return (qAbs(nValue1) < qAbs(nValue2)); 2135 | } 2136 | 2137 | QList XOptions::getCodePages(bool bAll) 2138 | { 2139 | QList listResult; 2140 | 2141 | listResult.append(""); // Empty 2142 | 2143 | QList list = QTextCodec::availableMibs(); 2144 | 2145 | std::sort(list.begin(), list.end(), sort_code_page); 2146 | 2147 | qint32 nNumberOfRecords = list.count(); 2148 | 2149 | for (qint32 i = 0; i < nNumberOfRecords; i++) { 2150 | qint32 nMIB = list.at(i); 2151 | 2152 | // qDebug("%s",QTextCodec::codecForMib(nMIB)->name().data()); 2153 | 2154 | bool bAdd = true; 2155 | 2156 | if (!bAll) { 2157 | if (nMIB == 106) bAdd = false; // UTF8 2158 | else if ((nMIB >= 1013) && (nMIB <= 1019)) bAdd = false; // Unicode 2159 | } 2160 | 2161 | if (bAdd) { 2162 | QString sName = QTextCodec::codecForMib(nMIB)->name(); 2163 | 2164 | listResult.append(sName); 2165 | } 2166 | } 2167 | 2168 | return listResult; 2169 | } 2170 | #endif 2171 | void XOptions::registerCodecs() 2172 | { 2173 | #if (QT_VERSION_MAJOR < 6) || defined(QT_CORE5COMPAT_LIB) 2174 | { 2175 | codec_cp437 *pCodec = new codec_cp437; 2176 | 2177 | if (!pCodec) { 2178 | qFatal("Codec failed"); 2179 | } 2180 | // TODO: more codecs 2181 | 2182 | // delete pCodec; // TODO: unregisterCodecs 2183 | } 2184 | #endif 2185 | } 2186 | #ifndef QT_GUI_LIB 2187 | void XOptions::printConsole(QString sString, Qt::GlobalColor colorText, Qt::GlobalColor colorBackground) 2188 | { 2189 | bool bEscapeMode = false; 2190 | bool bNativeMode = false; 2191 | 2192 | #ifdef Q_OS_WIN 2193 | HANDLE hConsole = 0; 2194 | WORD wOldAttribute = 0; 2195 | DWORD dwMode = 0; 2196 | 2197 | if (colorText != Qt::transparent || colorBackground != Qt::transparent) { 2198 | hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 2199 | 2200 | if (hConsole) { 2201 | GetConsoleMode(hConsole, &dwMode); 2202 | #ifndef _USING_V110_SDK71_ 2203 | #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING 2204 | #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 2205 | #endif 2206 | if (SetConsoleMode(hConsole, dwMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) { 2207 | bEscapeMode = true; 2208 | } else { 2209 | bNativeMode = true; 2210 | } 2211 | #else 2212 | bNativeMode = true; 2213 | #endif 2214 | } else { 2215 | #ifdef QT_DEBUG 2216 | qWarning("GetStdHandle(STD_OUTPUT_HANDLE) failed"); 2217 | #endif 2218 | } 2219 | } 2220 | #else 2221 | if (colorText != Qt::transparent || colorBackground != Qt::transparent) { 2222 | bEscapeMode = true; 2223 | } 2224 | #endif 2225 | 2226 | if (bEscapeMode) { 2227 | if (colorText != Qt::transparent || colorBackground != Qt::transparent) { 2228 | // Foreground 2229 | int fg = 39, bg = 49; // Default 2230 | // Map Qt::GlobalColor to ANSI codes 2231 | switch (colorText) { 2232 | case Qt::black: fg = 30; break; 2233 | case Qt::red: fg = 31; break; 2234 | case Qt::green: fg = 32; break; 2235 | case Qt::yellow: fg = 33; break; 2236 | case Qt::blue: fg = 34; break; 2237 | case Qt::magenta: fg = 35; break; 2238 | case Qt::cyan: fg = 36; break; 2239 | case Qt::gray: fg = 90; break; 2240 | case Qt::white: fg = 37; break; 2241 | case Qt::darkRed: fg = 91; break; 2242 | case Qt::darkGreen: fg = 92; break; 2243 | case Qt::darkYellow: fg = 93; break; 2244 | case Qt::darkBlue: fg = 94; break; 2245 | case Qt::darkMagenta: fg = 95; break; 2246 | case Qt::darkCyan: fg = 96; break; 2247 | case Qt::darkGray: fg = 90; break; // Or 90 as gray 2248 | default: fg = 39; break; 2249 | } 2250 | switch (colorBackground) { 2251 | case Qt::black: bg = 40; break; 2252 | case Qt::red: bg = 41; break; 2253 | case Qt::green: bg = 42; break; 2254 | case Qt::yellow: bg = 43; break; 2255 | case Qt::blue: bg = 44; break; 2256 | case Qt::magenta: bg = 45; break; 2257 | case Qt::cyan: bg = 46; break; 2258 | case Qt::gray: bg = 100; break; 2259 | case Qt::white: bg = 47; break; 2260 | case Qt::darkRed: bg = 101; break; 2261 | case Qt::darkGreen: bg = 102; break; 2262 | case Qt::darkYellow: bg = 103; break; 2263 | case Qt::darkBlue: bg = 104; break; 2264 | case Qt::darkMagenta: bg = 105; break; 2265 | case Qt::darkCyan: bg = 106; break; 2266 | case Qt::darkGray: bg = 100; break; 2267 | default: bg = 49; break; 2268 | } 2269 | printf("\033[%d;%dm", fg, bg); 2270 | } 2271 | } else if (bNativeMode) { 2272 | #ifdef Q_OS_WIN 2273 | CONSOLE_SCREEN_BUFFER_INFO csbi = {}; 2274 | 2275 | if (GetConsoleScreenBufferInfo(hConsole, &csbi)) { 2276 | wOldAttribute = csbi.wAttributes; 2277 | } 2278 | 2279 | WORD wAttribute = 0; 2280 | 2281 | // Foreground (text) color 2282 | if (colorText == Qt::black) { 2283 | wAttribute |= 0; 2284 | } else if (colorText == Qt::white) { 2285 | wAttribute |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; 2286 | } else if (colorText == Qt::blue) { 2287 | wAttribute |= FOREGROUND_BLUE; 2288 | } else if (colorText == Qt::red) { 2289 | wAttribute |= FOREGROUND_RED; 2290 | } else if (colorText == Qt::green) { 2291 | wAttribute |= FOREGROUND_GREEN; 2292 | } else if (colorText == Qt::yellow) { 2293 | wAttribute |= FOREGROUND_RED | FOREGROUND_GREEN; 2294 | } else if (colorText == Qt::magenta) { 2295 | wAttribute |= FOREGROUND_RED | FOREGROUND_BLUE; 2296 | } else if (colorText == Qt::cyan) { 2297 | wAttribute |= FOREGROUND_GREEN | FOREGROUND_BLUE; 2298 | } else if (colorText == Qt::darkBlue) { 2299 | wAttribute |= FOREGROUND_BLUE | FOREGROUND_INTENSITY; 2300 | } else if (colorText == Qt::darkRed) { 2301 | wAttribute |= FOREGROUND_RED | FOREGROUND_INTENSITY; 2302 | } else if (colorText == Qt::darkGreen) { 2303 | wAttribute |= FOREGROUND_GREEN | FOREGROUND_INTENSITY; 2304 | } else if (colorText == Qt::darkYellow) { 2305 | wAttribute |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; 2306 | } else if (colorText == Qt::darkMagenta) { 2307 | wAttribute |= FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; 2308 | } else if (colorText == Qt::darkCyan) { 2309 | wAttribute |= FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; 2310 | } else if (colorText == Qt::gray) { 2311 | wAttribute |= FOREGROUND_INTENSITY; 2312 | } else if (colorText == Qt::darkGray) { 2313 | wAttribute |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; 2314 | } else if (colorText == Qt::transparent) { 2315 | wAttribute |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; 2316 | } 2317 | 2318 | // Background color 2319 | if (colorBackground == Qt::black) { 2320 | wAttribute |= 0; 2321 | } else if (colorBackground == Qt::white) { 2322 | wAttribute |= BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; 2323 | } else if (colorBackground == Qt::blue) { 2324 | wAttribute |= BACKGROUND_BLUE; 2325 | } else if (colorBackground == Qt::red) { 2326 | wAttribute |= BACKGROUND_RED; 2327 | } else if (colorBackground == Qt::green) { 2328 | wAttribute |= BACKGROUND_GREEN; 2329 | } else if (colorBackground == Qt::yellow) { 2330 | wAttribute |= BACKGROUND_RED | BACKGROUND_GREEN; 2331 | } else if (colorBackground == Qt::magenta) { 2332 | wAttribute |= BACKGROUND_RED | BACKGROUND_BLUE; 2333 | } else if (colorBackground == Qt::cyan) { 2334 | wAttribute |= BACKGROUND_GREEN | BACKGROUND_BLUE; 2335 | } else if (colorBackground == Qt::darkBlue) { 2336 | wAttribute |= BACKGROUND_BLUE | BACKGROUND_INTENSITY; 2337 | } else if (colorBackground == Qt::darkRed) { 2338 | wAttribute |= BACKGROUND_RED | BACKGROUND_INTENSITY; 2339 | } else if (colorBackground == Qt::darkGreen) { 2340 | wAttribute |= BACKGROUND_GREEN | BACKGROUND_INTENSITY; 2341 | } else if (colorBackground == Qt::darkYellow) { 2342 | wAttribute |= BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY; 2343 | } else if (colorBackground == Qt::darkMagenta) { 2344 | wAttribute |= BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY; 2345 | } else if (colorBackground == Qt::darkCyan) { 2346 | wAttribute |= BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY; 2347 | } else if (colorBackground == Qt::gray) { 2348 | wAttribute |= BACKGROUND_INTENSITY; 2349 | } else if (colorBackground == Qt::darkGray) { 2350 | wAttribute |= BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY; 2351 | } else if (colorBackground == Qt::transparent) { 2352 | // No background bits set (leave as is) 2353 | } 2354 | 2355 | if (wAttribute) { 2356 | SetConsoleTextAttribute(hConsole, wAttribute); 2357 | } 2358 | #endif 2359 | } 2360 | 2361 | printf("%s", sString.toUtf8().data()); 2362 | 2363 | if (bEscapeMode) { 2364 | if (colorText != Qt::transparent || colorBackground != Qt::transparent) { 2365 | printf("\033[0m"); 2366 | } 2367 | #ifdef Q_OS_WIN 2368 | SetConsoleMode(hConsole, dwMode); // Restore original console mode TODO: optimize 2369 | #endif 2370 | } else if (bNativeMode) { 2371 | #ifdef Q_OS_WIN 2372 | if (colorText != Qt::transparent || colorBackground != Qt::transparent) { 2373 | if (wOldAttribute) { 2374 | SetConsoleTextAttribute(hConsole, wOldAttribute); 2375 | } 2376 | } 2377 | #endif 2378 | } 2379 | } 2380 | #endif 2381 | #ifndef QT_GUI_LIB 2382 | void XOptions::printModel(QAbstractItemModel *pModel) 2383 | { 2384 | if (pModel) { 2385 | qint32 nNumberOfRows = pModel->rowCount(); 2386 | qint32 nNumberOfColumns = pModel->columnCount(); 2387 | 2388 | QList listColumnSymbolSize; 2389 | listColumnSymbolSize.reserve(nNumberOfColumns); 2390 | QChar charSpace(' '); 2391 | 2392 | for (qint32 i = 0; i < nNumberOfColumns; i++) { 2393 | qint32 nSymbolSize = 0; 2394 | nSymbolSize = qMax(nSymbolSize, pModel->headerData(i, Qt::Horizontal).toString().length()); 2395 | 2396 | for (qint32 j = 0; j < nNumberOfRows; j++) { 2397 | QModelIndex index = pModel->index(j, i); 2398 | QString sData = pModel->data(index, Qt::DisplayRole).toString(); 2399 | 2400 | nSymbolSize = qMax(nSymbolSize, sData.length()); 2401 | } 2402 | 2403 | listColumnSymbolSize.append(nSymbolSize); 2404 | } 2405 | 2406 | QString sTableLine; 2407 | 2408 | { 2409 | for (qint32 i = 0; i < nNumberOfColumns; i++) { 2410 | sTableLine += "+"; 2411 | 2412 | for (int j = 0; j < listColumnSymbolSize[i]; j++) { 2413 | sTableLine += "-"; 2414 | } 2415 | } 2416 | 2417 | sTableLine += "+\n"; 2418 | } 2419 | 2420 | { 2421 | printConsole(sTableLine); 2422 | 2423 | for (qint32 i = 0; i < nNumberOfColumns; i++) { 2424 | printConsole("|"); 2425 | QString sString = pModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); 2426 | qint32 nColumnSize = listColumnSymbolSize[i]; 2427 | QString sEmpty = QString(nColumnSize - sString.size(), ' '); 2428 | 2429 | Qt::AlignmentFlag flag = (Qt::AlignmentFlag)(pModel->headerData(i, Qt::Horizontal, Qt::TextAlignmentRole).toInt()); 2430 | 2431 | if (flag & Qt::AlignRight) { 2432 | sString.prepend(sEmpty); 2433 | } else { 2434 | sString.append(sEmpty); 2435 | } 2436 | 2437 | printConsole(sString, Qt::red); 2438 | 2439 | if (i == (nNumberOfColumns - 1)) { 2440 | printConsole("|\n"); 2441 | } 2442 | } 2443 | 2444 | printConsole(sTableLine); 2445 | } 2446 | 2447 | { 2448 | for (qint32 i = 0; i < nNumberOfRows; i++) { 2449 | for (qint32 j = 0; j < nNumberOfColumns; j++) { 2450 | printConsole("|"); 2451 | 2452 | QModelIndex index = pModel->index(i, j); 2453 | QString sString = pModel->data(index, Qt::DisplayRole).toString(); 2454 | 2455 | qint32 nColumnSize = listColumnSymbolSize[j]; 2456 | QString sEmpty = QString(nColumnSize - sString.size(), ' '); 2457 | 2458 | Qt::AlignmentFlag flag = (Qt::AlignmentFlag)(pModel->data(index, Qt::TextAlignmentRole).toInt()); 2459 | 2460 | if (flag & Qt::AlignRight) { 2461 | sString.prepend(sEmpty); 2462 | } else { 2463 | sString.append(sEmpty); 2464 | } 2465 | 2466 | printConsole(sString); 2467 | 2468 | if (j == (nNumberOfColumns - 1)) { 2469 | printConsole("|\n"); 2470 | } 2471 | } 2472 | } 2473 | 2474 | printConsole(sTableLine); 2475 | } 2476 | } 2477 | } 2478 | #endif 2479 | 2480 | #if (QT_VERSION_MAJOR < 6) || defined(QT_CORE5COMPAT_LIB) 2481 | #ifdef QT_GUI_LIB 2482 | QMenu *XOptions::createCodePagesMenu(QWidget *pParent, bool bAll) 2483 | { 2484 | m_pCodePagesMenu = new QMenu(tr("Code pages"), pParent); 2485 | 2486 | if (m_pCodePagesMenu) { 2487 | m_pCodePagesMenu->clear(); // TODO: Check 2488 | 2489 | QList listCodePages = getCodePages(bAll); 2490 | 2491 | qint32 nNumberOfRecords = listCodePages.count(); 2492 | 2493 | for (qint32 i = 0; i < nNumberOfRecords; i++) { 2494 | QAction *pAction = new QAction(listCodePages.at(i), m_pCodePagesMenu); 2495 | pAction->setData(listCodePages.at(i)); 2496 | 2497 | connect(pAction, SIGNAL(triggered()), this, SLOT(setCodePageSlot())); 2498 | 2499 | m_pCodePagesMenu->addAction(pAction); 2500 | } 2501 | } 2502 | 2503 | return m_pCodePagesMenu; 2504 | } 2505 | #endif 2506 | #endif 2507 | #ifdef Q_OS_WIN 2508 | QString XOptions::getClassesPrefix(USERROLE userRole) 2509 | { 2510 | QString sResult; 2511 | 2512 | if (userRole == USERROLE_ADMIN) { 2513 | sResult = "HKEY_CLASSES_ROOT"; 2514 | } else if (userRole == USERROLE_NORMAL || userRole == USERROLE_GUEST || userRole == USERROLE_CHILD) { 2515 | sResult = "HKEY_CURRENT_USER\\Software\\Classes"; 2516 | } 2517 | 2518 | return sResult; 2519 | } 2520 | #endif 2521 | #ifdef Q_OS_WIN 2522 | bool XOptions::isPathInUserEnvironment(const QString &checkPath) 2523 | { 2524 | QSettings settings("HKEY_CURRENT_USER\\Environment", QSettings::NativeFormat); 2525 | QString currentPath = settings.value("Path").toString(); 2526 | 2527 | QString formattedPath = QDir::toNativeSeparators(checkPath); 2528 | #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) 2529 | QStringList pathEntries = currentPath.split(';', Qt::SkipEmptyParts); 2530 | #else 2531 | QStringList pathEntries = currentPath.split(';', QString::SkipEmptyParts); 2532 | #endif 2533 | 2534 | return pathEntries.contains(formattedPath, Qt::CaseInsensitive); 2535 | } 2536 | #endif 2537 | #ifdef Q_OS_WIN 2538 | void XOptions::appendToUserPathVariable(const QString &newPath) 2539 | { 2540 | QSettings settings("HKEY_CURRENT_USER\\Environment", QSettings::NativeFormat); 2541 | QString currentPath = settings.value("Path").toString(); 2542 | 2543 | QString formattedPath = QDir::toNativeSeparators(newPath); 2544 | #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) 2545 | QStringList pathEntries = currentPath.split(';', Qt::SkipEmptyParts); 2546 | #else 2547 | QStringList pathEntries = currentPath.split(';', QString::SkipEmptyParts); 2548 | #endif 2549 | 2550 | if (!pathEntries.contains(formattedPath, Qt::CaseInsensitive)) { 2551 | pathEntries.append(formattedPath); 2552 | settings.setValue("Path", pathEntries.join(';')); 2553 | 2554 | #ifdef QT_GUI_LIB 2555 | // SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 5000, nullptr); 2556 | #endif 2557 | } 2558 | } 2559 | #endif 2560 | #ifdef Q_OS_WIN 2561 | void XOptions::removeFromUserPathVariable(const QString &targetPath) 2562 | { 2563 | QSettings settings("HKEY_CURRENT_USER\\Environment", QSettings::NativeFormat); 2564 | QString currentPath = settings.value("Path").toString(); 2565 | 2566 | QString formattedPath = QDir::toNativeSeparators(targetPath); 2567 | #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) 2568 | QStringList pathEntries = currentPath.split(';', Qt::SkipEmptyParts); 2569 | #else 2570 | QStringList pathEntries = currentPath.split(';', QString::SkipEmptyParts); 2571 | #endif 2572 | 2573 | if (pathEntries.contains(formattedPath, Qt::CaseInsensitive)) { 2574 | pathEntries.removeAll(formattedPath); 2575 | settings.setValue("Path", pathEntries.join(';')); 2576 | 2577 | #ifdef QT_GUI_LIB 2578 | // SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 5000, nullptr); 2579 | #endif 2580 | } 2581 | } 2582 | #endif 2583 | #ifdef Q_OS_WIN 2584 | bool XOptions::registerContext(const QString &sApplicationName, const QString &sType, const QString &sApplicationFilePath, USERROLE userRole) 2585 | { 2586 | QString _sApplicationFilePath = sApplicationFilePath; 2587 | 2588 | QSettings settings(getClassesPrefix(userRole) + QString("\\%1\\shell\\%2\\command").arg(sType, sApplicationName), QSettings::NativeFormat); 2589 | settings.setValue(".", "\"" + _sApplicationFilePath.replace("/", "\\") + "\" \"%1\""); 2590 | 2591 | QSettings settingsIcon(getClassesPrefix(userRole) + QString("\\%1\\shell\\%2").arg(sType, sApplicationName), QSettings::NativeFormat); 2592 | settingsIcon.setValue("Icon", "\"" + _sApplicationFilePath.replace("/", "\\") + "\""); 2593 | 2594 | // TODO: Check if not send message 2595 | return checkContext(sApplicationName, sType); 2596 | } 2597 | #endif 2598 | #ifdef Q_OS_WIN 2599 | bool XOptions::clearContext(const QString &sApplicationName, const QString &sType, USERROLE userRole) 2600 | { 2601 | QSettings settings(getClassesPrefix(userRole) + QString("\\%1\\shell\\%2").arg(sType, sApplicationName), QSettings::NativeFormat); 2602 | settings.clear(); 2603 | 2604 | // TODO: Check if not send message 2605 | return !(checkContext(sApplicationName, sType)); 2606 | } 2607 | #endif 2608 | #ifdef Q_OS_WIN 2609 | bool XOptions::checkContext(const QString &sApplicationName, const QString &sType, USERROLE userRole) 2610 | { 2611 | QSettings settings(getClassesPrefix(userRole) + QString("\\%1\\shell").arg(sType), QSettings::NativeFormat); 2612 | 2613 | return (settings.value(QString("%1/command/Default").arg(sApplicationName)).toString() != ""); 2614 | } 2615 | #endif 2616 | 2617 | void XOptions::setMaxRecentFilesCount(qint32 nValue) 2618 | { 2619 | m_nMaxRecentFilesCount = nValue; 2620 | } 2621 | 2622 | qint32 XOptions::getMaxRecentFilesCount() 2623 | { 2624 | return m_nMaxRecentFilesCount; 2625 | } 2626 | 2627 | QString XOptions::getBundleIdToString(BUNDLE bundle) 2628 | { 2629 | QString sResult; 2630 | 2631 | if (bundle == BUNDLE_LINUX_ARCH_X64) { 2632 | sResult = "Linux Arch x64"; 2633 | } else if (bundle == BUNDLE_WINDOWS_QT6_X64) { 2634 | sResult = "Windows Qt6 x64"; 2635 | } else if (bundle == BUNDLE_LINUX_APPIMAGE_X64) { 2636 | sResult = "Linux AppImage x64"; 2637 | } else if (bundle == BUNDLE_LINUX_DEBIAN_X64) { 2638 | sResult = "Linux Debian x64"; 2639 | } else if (bundle == BUNDLE_LINUX_DEBIAN_X86) { 2640 | sResult = "Linux Debian x86"; 2641 | } else if (bundle == BUNDLE_LINUX_DEBIAN_ARM64) { 2642 | sResult = "Linux Debian ARM64"; 2643 | } else if (bundle == BUNDLE_LINUX_UBUNTU_X64) { 2644 | sResult = "Linux Ubuntu x64"; 2645 | } else if (bundle == BUNDLE_LINUX_PARROT_X64) { 2646 | sResult = "Linux Parrot x64"; 2647 | } else if (bundle == BUNDLE_LINUX_KALI_X64) { 2648 | sResult = "Linux Kali x64"; 2649 | } else if (bundle == BUNDLE_WINDOWS_XP_X86) { 2650 | sResult = "Windows XP x86"; 2651 | } else if (bundle == BUNDLE_WINDOWS_X86) { 2652 | sResult = "Windows x86"; 2653 | } else if (bundle == BUNDLE_WINDOWS_X64) { 2654 | sResult = "Windows x64"; 2655 | } else if (bundle == BUNDLE_WINDOWS_ARM64) { 2656 | sResult = "Windows ARM64"; 2657 | } else if (bundle == BUNDLE_MACOS_X64) { 2658 | sResult = "MacOS x64"; 2659 | } else if (bundle == BUNDLE_MACOS_QT6_ARM64) { 2660 | sResult = "MacOS Qt6 ARM64"; 2661 | } else if (bundle == BUNDLE_FEDORA_X64) { 2662 | sResult = "Fedora x64"; 2663 | } else if (bundle == BUNDLE_FREEBSD_X64) { 2664 | sResult = "FreeBSD x64"; 2665 | } else { 2666 | sResult = tr("Unknown"); 2667 | } 2668 | 2669 | return sResult; 2670 | } 2671 | 2672 | #ifdef QT_GUI_LIB 2673 | void XOptions::_updateRecentFilesMenu() 2674 | { 2675 | if (m_pRecentFilesMenu) { 2676 | m_pRecentFilesMenu->clear(); 2677 | 2678 | QList listRecentFiles = getRecentFiles(); 2679 | 2680 | qint32 nNumberOfRecentFiles = listRecentFiles.count(); 2681 | 2682 | for (qint32 i = nNumberOfRecentFiles - 1; i >= 0; i--) { 2683 | QAction *pAction = new QAction(listRecentFiles.at(i), m_pRecentFilesMenu); 2684 | pAction->setData(listRecentFiles.at(i)); 2685 | 2686 | connect(pAction, SIGNAL(triggered()), this, SLOT(openRecentFile())); 2687 | 2688 | m_pRecentFilesMenu->addAction(pAction); 2689 | } 2690 | 2691 | if (nNumberOfRecentFiles) { 2692 | m_pRecentFilesMenu->addSeparator(); 2693 | 2694 | QAction *pAction = new QAction(tr("Clear"), m_pRecentFilesMenu); 2695 | 2696 | connect(pAction, SIGNAL(triggered()), this, SLOT(clearRecentFiles())); 2697 | 2698 | m_pRecentFilesMenu->addAction(pAction); 2699 | } 2700 | 2701 | m_pRecentFilesMenu->setEnabled(nNumberOfRecentFiles); 2702 | } 2703 | } 2704 | #endif 2705 | #ifdef QT_GUI_LIB 2706 | QString XOptions::getImageFilter() 2707 | { 2708 | const QList listImageFormats = QImageWriter::supportedImageFormats(); 2709 | 2710 | QStringList listFilter; 2711 | 2712 | qint32 nNumberOfImageFormats = listImageFormats.count(); 2713 | 2714 | if (nNumberOfImageFormats) { 2715 | QString sImageFilter = tr("Images") + " ("; 2716 | 2717 | for (qint32 i = 0; i < nNumberOfImageFormats; i++) { 2718 | if (i > 0) { 2719 | sImageFilter += " "; 2720 | } 2721 | 2722 | sImageFilter += "*."; 2723 | sImageFilter += listImageFormats.at(i); 2724 | } 2725 | 2726 | sImageFilter += ")"; 2727 | 2728 | listFilter.append(sImageFilter); 2729 | } 2730 | 2731 | listFilter.append(QString("PDF %1 (*.pdf)").arg(tr("Documents"))); 2732 | // listFilter.append(QString("Postscript %1 (*.ps)").arg(tr("Documents"))); 2733 | 2734 | return listFilter.join(";;"); 2735 | } 2736 | #endif 2737 | #ifdef QT_GUI_LIB 2738 | QColor XOptions::getColorDialog(QWidget *pParent, const QString &sTitle, QColor &color) 2739 | { 2740 | QColor colResult; 2741 | 2742 | QColorDialog colorDialog(pParent); 2743 | colorDialog.setCurrentColor(color); 2744 | colorDialog.setWindowTitle(sTitle); 2745 | 2746 | _adjustApplicationModal(&colorDialog, true); 2747 | _adjustStayOnTop(&colorDialog, true); 2748 | 2749 | if (colorDialog.exec() == QDialog::Accepted) { 2750 | colResult = colorDialog.currentColor(); 2751 | } 2752 | 2753 | return colResult; 2754 | } 2755 | #endif 2756 | #ifdef QT_GUI_LIB 2757 | void XOptions::adjustToolButton(QToolButton *pToolButton, ICONTYPE iconType, Qt::ToolButtonStyle style) 2758 | { 2759 | QString sIconName = getIconPath(iconType); 2760 | 2761 | if (sIconName != "") { 2762 | QIcon icon; 2763 | icon.addFile(sIconName, QSize(), QIcon::Normal, QIcon::Off); 2764 | pToolButton->setIcon(icon); 2765 | pToolButton->setIconSize(QSize(16, 16)); 2766 | pToolButton->setToolButtonStyle(style); 2767 | } else { 2768 | #ifdef QT_DEBUG 2769 | qDebug("Icon not found: %s", sIconName.toUtf8().data()); 2770 | #endif 2771 | } 2772 | } 2773 | #endif 2774 | #ifdef QT_GUI_LIB 2775 | void XOptions::adjustTreeWidgetItem(QTreeWidgetItem *pTreeWidgetItem, ICONTYPE iconType) 2776 | { 2777 | QString sIconName = getIconPath(iconType); 2778 | 2779 | if (sIconName != "") { 2780 | QIcon icon; 2781 | icon.addFile(sIconName, QSize(), QIcon::Normal, QIcon::Off); 2782 | pTreeWidgetItem->setIcon(0, icon); 2783 | } else { 2784 | #ifdef QT_DEBUG 2785 | qDebug("Icon not found: %s", sIconName.toUtf8().data()); 2786 | #endif 2787 | } 2788 | } 2789 | #endif 2790 | #ifdef QT_GUI_LIB 2791 | QString XOptions::getIconPath(ICONTYPE iconType) 2792 | { 2793 | QString sResult; 2794 | 2795 | if (iconType == ICONTYPE_NONE) { 2796 | sResult = ""; 2797 | } else if (iconType == ICONTYPE_GENERIC) { 2798 | sResult = ":/XStyles/icons/BreakpointEnabled.16.16.png"; 2799 | } else if (iconType == ICONTYPE_ACTION) { 2800 | sResult = ":/XStyles/icons/Action.16.16.png"; 2801 | } else if (iconType == ICONTYPE_HEX) { 2802 | sResult = ":/XStyles/icons/Binary.16.16.png"; 2803 | } else if (iconType == ICONTYPE_DISASM) { 2804 | sResult = ":/XStyles/icons/Disasm.16.16.png"; 2805 | } else if (iconType == ICONTYPE_ENTROPY) { 2806 | sResult = ":/XStyles/icons/Entropy.16.16.png"; 2807 | } else if (iconType == ICONTYPE_STRING) { 2808 | sResult = ":/XStyles/icons/String.16.16.png"; 2809 | } else if (iconType == ICONTYPE_SIGNATURE) { 2810 | sResult = ":/XStyles/icons/Signature.16.16.png"; 2811 | } else if (iconType == ICONTYPE_SIZE) { 2812 | sResult = ":/XStyles/icons/Size.16.16.png"; 2813 | } else if (iconType == ICONTYPE_VALUE) { 2814 | sResult = ":/XStyles/icons/Value.16.16.png"; 2815 | } else if (iconType == ICONTYPE_MEMORYMAP) { 2816 | sResult = ":/XStyles/icons/MemoryMap.16.16.png"; 2817 | } else if (iconType == ICONTYPE_INFO) { 2818 | sResult = ":/XStyles/icons/Info.16.16.png"; 2819 | } else if (iconType == ICONTYPE_HASH) { 2820 | sResult = ":/XStyles/icons/Hash.16.16.png"; 2821 | } else if (iconType == ICONTYPE_VISUALIZATION) { 2822 | sResult = ":/XStyles/icons/Image.16.16.png"; 2823 | } else if (iconType == ICONTYPE_SEARCH) { 2824 | sResult = ":/XStyles/icons/Search.16.16.png"; 2825 | } else if (iconType == ICONTYPE_EXTRACTOR) { 2826 | sResult = ":/XStyles/icons/Extract.16.16.png"; 2827 | } else if (iconType == ICONTYPE_FILE) { 2828 | sResult = ":/XStyles/icons/File.16.16.png"; 2829 | } else if (iconType == ICONTYPE_SAVE) { 2830 | sResult = ":/XStyles/icons/Save.16.16.png"; 2831 | } else if (iconType == ICONTYPE_COPY) { 2832 | sResult = ":/XStyles/icons/Copy.16.16.png"; 2833 | } else if (iconType == ICONTYPE_EDIT) { 2834 | sResult = ":/XStyles/icons/Edit.16.16.png"; 2835 | } else if (iconType == ICONTYPE_OVERLAY) { 2836 | sResult = ":/XStyles/icons/Overlay.16.16.png"; 2837 | } else if (iconType == ICONTYPE_RELOAD) { 2838 | sResult = ":/XStyles/icons/Refresh.16.16.png"; 2839 | } else if (iconType == ICONTYPE_SCAN) { 2840 | sResult = ":/XStyles/icons/Search.16.16.png"; 2841 | } else if (iconType == ICONTYPE_DUMPTOFILE) { 2842 | sResult = ":/XStyles/icons/Download.16.16.png"; 2843 | } else if (iconType == ICONTYPE_ENTRY) { 2844 | sResult = ":/XStyles/icons/Entry.16.16.png"; 2845 | } else if (iconType == ICONTYPE_BACKWARD) { 2846 | sResult = ":/XStyles/icons/Backward.16.16.png"; 2847 | } else if (iconType == ICONTYPE_FORWARD) { 2848 | sResult = ":/XStyles/icons/Forward.16.16.png"; 2849 | } else if (iconType == ICONTYPE_ADD) { 2850 | sResult = ":/XStyles/icons/Add.16.16.png"; 2851 | } else if (iconType == ICONTYPE_OPEN) { 2852 | sResult = ":/XStyles/icons/Open.16.16.png"; 2853 | } else if (iconType == ICONTYPE_LIST) { 2854 | sResult = ":/XStyles/icons/List.16.16.png"; 2855 | } else if (iconType == ICONTYPE_NEW) { 2856 | sResult = ":/XStyles/icons/Add.16.16.png"; 2857 | } else if (iconType == ICONTYPE_OPTION) { 2858 | sResult = ":/XStyles/icons/Option.16.16.png"; 2859 | } else if (iconType == ICONTYPE_YARA) { 2860 | sResult = ":/XStyles/icons/Yara.16.16.png"; 2861 | } else if (iconType == ICONTYPE_MIME) { 2862 | sResult = ":/XStyles/icons/Mime.16.16.png"; 2863 | } else if (iconType == ICONTYPE_VIRUSTOTAL) { 2864 | sResult = ":/XStyles/icons/Virustotal.16.16.png"; 2865 | } else if (iconType == ICONTYPE_TOOL) { 2866 | sResult = ":/XStyles/icons/Tool.16.16.png"; 2867 | } else if (iconType == ICONTYPE_EXIT) { 2868 | sResult = ":/XStyles/icons/Exit.16.16.png"; 2869 | } else if (iconType == ICONTYPE_DEMANGLE) { 2870 | sResult = ":/XStyles/icons/Demangle.16.16.png"; 2871 | } else if (iconType == ICONTYPE_SHORTCUT) { 2872 | sResult = ":/XStyles/icons/Shortcut.16.16.png"; 2873 | } else if (iconType == ICONTYPE_GOTO) { 2874 | sResult = ":/XStyles/icons/Goto.16.16.png"; 2875 | } else if (iconType == ICONTYPE_SECTION) { 2876 | sResult = ":/XStyles/icons/Section.16.16.png"; 2877 | } else if (iconType == ICONTYPE_SEGMENT) { 2878 | sResult = ":/XStyles/icons/Segment.16.16.png"; 2879 | } else if (iconType == ICONTYPE_EXCEPTION) { 2880 | sResult = ":/XStyles/icons/Exception.16.16.png"; 2881 | } else if (iconType == ICONTYPE_CERTIFICATE) { 2882 | sResult = ":/XStyles/icons/Certificate.16.16.png"; 2883 | } else if (iconType == ICONTYPE_RELOC) { 2884 | sResult = ":/XStyles/icons/Reloc.16.16.png"; 2885 | } else if (iconType == ICONTYPE_DEBUG) { 2886 | sResult = ":/XStyles/icons/Debug.16.16.png"; 2887 | } else if (iconType == ICONTYPE_HEADER) { 2888 | sResult = ":/XStyles/icons/Header.16.16.png"; 2889 | } else if (iconType == ICONTYPE_LIBRARY) { 2890 | sResult = ":/XStyles/icons/Library.16.16.png"; 2891 | } else if (iconType == ICONTYPE_SYMBOL) { 2892 | sResult = ":/XStyles/icons/Symbol.16.16.png"; 2893 | } else if (iconType == ICONTYPE_TABLE) { 2894 | sResult = ":/XStyles/icons/Table.16.16.png"; 2895 | } else if (iconType == ICONTYPE_DOTNET) { 2896 | sResult = ":/XStyles/icons/DotNet.16.16.png"; 2897 | } else if (iconType == ICONTYPE_METADATA) { 2898 | sResult = ":/XStyles/icons/Metadata.16.16.png"; 2899 | } else if (iconType == ICONTYPE_RESOURCE) { 2900 | sResult = ":/XStyles/icons/Resource.16.16.png"; 2901 | } else if (iconType == ICONTYPE_TLS) { 2902 | sResult = ":/XStyles/icons/TLS.16.16.png"; 2903 | } else if (iconType == ICONTYPE_SELECT) { 2904 | sResult = ":/XStyles/icons/Select.16.16.png"; 2905 | } else if (iconType == ICONTYPE_ADDRESS) { 2906 | sResult = ":/XStyles/icons/Address.16.16.png"; 2907 | } else if (iconType == ICONTYPE_OFFSET) { 2908 | sResult = ":/XStyles/icons/Offset.16.16.png"; 2909 | } else if (iconType == ICONTYPE_IMPORT) { 2910 | sResult = ":/XStyles/icons/Import.16.16.png"; 2911 | } else if (iconType == ICONTYPE_EXPORT) { 2912 | sResult = ":/XStyles/icons/Export.16.16.png"; 2913 | } else if (iconType == ICONTYPE_DATA) { 2914 | sResult = ":/XStyles/icons/Data.16.16.png"; 2915 | } else if (iconType == ICONTYPE_DIE) { 2916 | sResult = ":/XStyles/icons/DIE.16.16.png"; 2917 | } else if (iconType == ICONTYPE_NFD) { 2918 | sResult = ":/XStyles/icons/NFD.16.16.png"; 2919 | } else if (iconType == ICONTYPE_VERSION) { 2920 | sResult = ":/XStyles/icons/Version.16.16.png"; 2921 | } else if (iconType == ICONTYPE_MANIFEST) { 2922 | sResult = ":/XStyles/icons/Manifest.16.16.png"; 2923 | } else if (iconType == ICONTYPE_FOLLOW) { 2924 | sResult = ":/XStyles/icons/Follow.16.16.png"; 2925 | } else if (iconType == ICONTYPE_NEXT) { 2926 | sResult = ":/XStyles/icons/Next.16.16.png"; 2927 | } else if (iconType == ICONTYPE_ALL) { 2928 | sResult = ":/XStyles/icons/All.16.16.png"; 2929 | } else if (iconType == ICONTYPE_PATH) { 2930 | sResult = ":/XStyles/icons/Path.16.16.png"; 2931 | } else if (iconType == ICONTYPE_NOTE) { 2932 | sResult = ":/XStyles/icons/Note.16.16.png"; 2933 | } else if (iconType == ICONTYPE_FUNCTION) { 2934 | sResult = ":/XStyles/icons/Function.16.16.png"; 2935 | } else if (iconType == ICONTYPE_SCRIPT) { 2936 | sResult = ":/XStyles/icons/Script.16.16.png"; 2937 | } else if (iconType == ICONTYPE_PATCH) { 2938 | sResult = ":/XStyles/icons/Patch.16.16.png"; 2939 | } else if (iconType == ICONTYPE_REMOVE) { 2940 | sResult = ":/XStyles/icons/Remove.16.16.png"; 2941 | } else if (iconType == ICONTYPE_RESIZE) { 2942 | sResult = ":/XStyles/icons/Resize.16.16.png"; 2943 | } else if (iconType == ICONTYPE_CODE) { 2944 | sResult = ":/XStyles/icons/Code.16.16.png"; 2945 | } else if (iconType == ICONTYPE_REFERENCE) { 2946 | sResult = ":/XStyles/icons/Reference.16.16.png"; 2947 | } else if (iconType == ICONTYPE_BOOKMARK) { 2948 | sResult = ":/XStyles/icons/Bookmark.16.16.png"; 2949 | } else if (iconType == ICONTYPE_INSPECTOR) { 2950 | sResult = ":/XStyles/icons/Inspector.16.16.png"; 2951 | } else if (iconType == ICONTYPE_CONVERTOR) { 2952 | sResult = ":/XStyles/icons/Convertor.16.16.png"; 2953 | } else if (iconType == ICONTYPE_STRUCTS) { 2954 | sResult = ":/XStyles/icons/Structs.16.16.png"; 2955 | } else { 2956 | sResult = ":/XStyles/icons/BreakpointDisabled.16.16.png"; 2957 | } 2958 | 2959 | if (sResult != "") { 2960 | if (!QFile::exists(sResult)) { 2961 | sResult = ""; 2962 | } 2963 | } 2964 | 2965 | return sResult; 2966 | } 2967 | #endif 2968 | #ifdef QT_GUI_LIB 2969 | void XOptions::adjustMenu(QMenu *pParentMenu, QMenu *pMenu, const QString &sText, ICONTYPE iconType) 2970 | { 2971 | pMenu->setTitle(sText); 2972 | 2973 | QString sIconPath = XOptions::getIconPath(iconType); 2974 | 2975 | if (sIconPath != "") { 2976 | QIcon icon; 2977 | icon.addFile(sIconPath, QSize(), QIcon::Normal, QIcon::Off); 2978 | pMenu->setIcon(icon); 2979 | } 2980 | 2981 | if (pParentMenu) { 2982 | pParentMenu->addMenu(pMenu); 2983 | } 2984 | } 2985 | #endif 2986 | #ifdef QT_GUI_LIB 2987 | void XOptions::adjustAction(QMenu *pParentMenu, QAction *pAction, const QString &sText, const QObject *pRecv, const char *pMethod, ICONTYPE iconType) 2988 | { 2989 | connect(pAction, SIGNAL(triggered()), pRecv, pMethod); 2990 | 2991 | pAction->setText(sText); 2992 | 2993 | QString sIconPath = XOptions::getIconPath(iconType); 2994 | 2995 | if (sIconPath != "") { 2996 | QIcon icon; 2997 | icon.addFile(sIconPath, QSize(), QIcon::Normal, QIcon::Off); 2998 | pAction->setIcon(icon); 2999 | } 3000 | 3001 | if (pParentMenu) { 3002 | pParentMenu->addAction(pAction); 3003 | } 3004 | } 3005 | #endif 3006 | 3007 | XOptions::BUNDLE XOptions::getBundle() 3008 | { 3009 | BUNDLE result = BUNDLE_UNKNOWN; 3010 | 3011 | #ifdef QT_DEBUG 3012 | #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) 3013 | QString _sProductType = QSysInfo::productType(); 3014 | qDebug("OS: %s", _sProductType.toUtf8().data()); 3015 | #endif 3016 | #endif 3017 | 3018 | #ifdef Q_OS_WIN 3019 | #if defined(Q_PROCESSOR_ARM64) 3020 | result = BUNDLE_WINDOWS_ARM64; 3021 | #elif QT_VERSION <= QT_VERSION_CHECK(5, 6, 3) 3022 | result = BUNDLE_WINDOWS_XP_X86; 3023 | #elif (QT_VERSION_MAJOR >= 6) 3024 | #ifdef Q_OS_WIN64 3025 | result = BUNDLE_WINDOWS_QT6_X64; 3026 | #else 3027 | result = BUNDLE_WINDOWS_QT6_X86; 3028 | #endif 3029 | #else 3030 | #ifdef Q_OS_WIN64 3031 | result = BUNDLE_WINDOWS_X64; 3032 | #else 3033 | result = BUNDLE_WINDOWS_X86; 3034 | #endif 3035 | #endif 3036 | #endif 3037 | #ifdef Q_PROCESSOR_X86 3038 | #ifdef Q_OS_LINUX 3039 | result = BUNDLE_LINUX_DEBIAN_X86; 3040 | #endif 3041 | #endif 3042 | #ifdef Q_PROCESSOR_X86_64 3043 | #ifdef Q_OS_LINUX 3044 | #if QT_VERSION == QT_VERSION_CHECK(5, 2, 1) 3045 | result = BUNDLE_LINUX_APPIMAGE_X64; 3046 | #elif QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) 3047 | QString sProductType = QSysInfo::productType(); 3048 | 3049 | if (sProductType == "ubuntu") { 3050 | result = BUNDLE_LINUX_UBUNTU_X64; 3051 | } 3052 | #endif 3053 | #endif 3054 | #ifdef Q_OS_FRREBSD 3055 | result = BUNDLE_FREEBSD_X64; 3056 | #endif 3057 | #ifdef Q_OS_MACOS 3058 | // TODO: QSysInfo::currentCpuArchitecture(); 3059 | #endif 3060 | #ifdef Q_OS_FEDORA 3061 | result = BUNDLE_FEDORA_X64; 3062 | #endif 3063 | #endif 3064 | 3065 | return result; 3066 | } --------------------------------------------------------------------------------