├── .github ├── release.yml └── workflows │ ├── build-project.yml │ ├── build-qt-windows.yml │ ├── check-release-pr.yml │ ├── generate-release.yml │ ├── label-pr.yml │ └── tag-release-commit-and-sync-dev.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake ├── FetchOBCMake.cmake ├── file_templates │ ├── QxComponentConfig.cmake.in │ ├── QxConfig.cmake.in │ └── primary_component_header.h.in └── module │ └── Qx │ └── ComponentHelper.cmake ├── doc ├── CMakeLists.txt ├── cmake │ └── file_templates │ │ └── mainpage.md.in ├── general │ ├── majorfeatures.md │ └── namespace.dox └── res │ ├── DoxygenLayout.xml │ └── logo.svg ├── lib ├── core │ ├── CMakeLists.txt │ ├── cmake │ │ ├── depends_qt │ │ └── depends_siblings │ ├── doc │ │ ├── general │ │ │ ├── core.dox │ │ │ ├── declarativejson.md │ │ │ └── properties.md │ │ └── res │ │ │ ├── images │ │ │ └── properties-0.png │ │ │ └── snippets │ │ │ ├── qx-abstracterror.cpp │ │ │ ├── qx-bitarray.cpp │ │ │ ├── qx-error.cpp │ │ │ ├── qx-exclusiveaccess.cpp │ │ │ ├── qx-groupedprogressmanager.cpp │ │ │ ├── qx-index.cpp │ │ │ ├── qx-json.cpp │ │ │ ├── qx-table.cpp │ │ │ ├── qx-threadsafesingleton.cpp │ │ │ └── qx-versionnumber.cpp │ ├── include │ │ └── qx │ │ │ └── core │ │ │ ├── __private │ │ │ ├── qx-internalerror.h │ │ │ └── qx-property_detail.h │ │ │ ├── qx-abstracterror.h │ │ │ ├── qx-algorithm.h │ │ │ ├── qx-array.h │ │ │ ├── qx-base85.h │ │ │ ├── qx-bimap.h │ │ │ ├── qx-bitarray.h │ │ │ ├── qx-bytearray.h │ │ │ ├── qx-char.h │ │ │ ├── qx-cumulation.h │ │ │ ├── qx-datetime.h │ │ │ ├── qx-dsvtable.h │ │ │ ├── qx-error.h │ │ │ ├── qx-exclusiveaccess.h │ │ │ ├── qx-flatmultiset.h │ │ │ ├── qx-freeindextracker.h │ │ │ ├── qx-genericerror.h │ │ │ ├── qx-global.h │ │ │ ├── qx-groupedprogressmanager.h │ │ │ ├── qx-index.h │ │ │ ├── qx-integrity.h │ │ │ ├── qx-iostream.h │ │ │ ├── qx-json.h │ │ │ ├── qx-list.h │ │ │ ├── qx-lopmap.h │ │ │ ├── qx-processbider.h │ │ │ ├── qx-progressgroup.h │ │ │ ├── qx-property.h │ │ │ ├── qx-regularexpression.h │ │ │ ├── qx-setonce.h │ │ │ ├── qx-string.h │ │ │ ├── qx-system.h │ │ │ ├── qx-systemerror.h │ │ │ ├── qx-systemsignalwatcher.h │ │ │ ├── qx-table.h │ │ │ ├── qx-threadsafesingleton.h │ │ │ ├── qx-traverser.h │ │ │ └── qx-versionnumber.h │ └── src │ │ ├── __private │ │ ├── qx-generalworkerthread.cpp │ │ ├── qx-generalworkerthread.h │ │ ├── qx-internalerror.cpp │ │ ├── qx-processwaiter.cpp │ │ ├── qx-processwaiter.h │ │ ├── qx-processwaiter_linux.cpp │ │ ├── qx-processwaiter_linux.h │ │ ├── qx-processwaiter_win.cpp │ │ ├── qx-processwaiter_win.h │ │ ├── qx-signaldaemon.h │ │ ├── qx-signaldaemon_linux.cpp │ │ ├── qx-signaldaemon_linux.h │ │ ├── qx-signaldaemon_win.cpp │ │ └── qx-signaldaemon_win.h │ │ ├── qx-abstracterror.cpp │ │ ├── qx-algorithm.cpp │ │ ├── qx-array.dox │ │ ├── qx-base85.cpp │ │ ├── qx-bimap.dox │ │ ├── qx-bitarray.cpp │ │ ├── qx-bytearray.dox │ │ ├── qx-char.cpp │ │ ├── qx-cumulation.dox │ │ ├── qx-datetime.cpp │ │ ├── qx-dsvtable.cpp │ │ ├── qx-error.cpp │ │ ├── qx-exclusiveaccess.dox │ │ ├── qx-flatmultiset.dox │ │ ├── qx-freeindextracker.cpp │ │ ├── qx-genericerror.cpp │ │ ├── qx-global.cpp │ │ ├── qx-groupedprogressmanager.cpp │ │ ├── qx-index.dox │ │ ├── qx-integrity.cpp │ │ ├── qx-iostream.dox │ │ ├── qx-iostream_linux.cpp │ │ ├── qx-iostream_win.cpp │ │ ├── qx-json.cpp │ │ ├── qx-json_p.cpp │ │ ├── qx-json_p.h │ │ ├── qx-list.dox │ │ ├── qx-lopmap.dox │ │ ├── qx-processbider.cpp │ │ ├── qx-processbider_p.h │ │ ├── qx-progressgroup.cpp │ │ ├── qx-property.cpp │ │ ├── qx-property_p.h │ │ ├── qx-regularexpression.dox │ │ ├── qx-setonce.dox │ │ ├── qx-string.cpp │ │ ├── qx-system.cpp │ │ ├── qx-system_linux.cpp │ │ ├── qx-system_p.h │ │ ├── qx-system_win.cpp │ │ ├── qx-systemerror.cpp │ │ ├── qx-systemerror_linux.cpp │ │ ├── qx-systemerror_win.cpp │ │ ├── qx-systemsignalwatcher.cpp │ │ ├── qx-systemsignalwatcher_p.h │ │ ├── qx-table.dox │ │ ├── qx-threadsafesingleton.dox │ │ ├── qx-traverser.dox │ │ └── qx-versionnumber.cpp ├── gui │ ├── CMakeLists.txt │ ├── cmake │ │ └── depends_qt │ ├── doc │ │ └── general │ │ │ └── gui.dox │ ├── include │ │ └── qx │ │ │ └── gui │ │ │ └── qx-color.h │ └── src │ │ └── qx-color.cpp ├── io │ ├── CMakeLists.txt │ ├── cmake │ │ ├── depends_qt │ │ └── depends_siblings │ ├── doc │ │ ├── general │ │ │ └── io.dox │ │ └── res │ │ │ └── snippets │ │ │ └── qx-applicationlogger.cpp │ ├── include │ │ └── qx │ │ │ └── io │ │ │ ├── qx-applicationlogger.h │ │ │ ├── qx-common-io.h │ │ │ ├── qx-filestreamreader.h │ │ │ ├── qx-filestreamwriter.h │ │ │ ├── qx-ioopreport.h │ │ │ ├── qx-textpos.h │ │ │ ├── qx-textquery.h │ │ │ ├── qx-textstream.h │ │ │ ├── qx-textstreamreader.h │ │ │ └── qx-textstreamwriter.h │ └── src │ │ ├── qx-applicationlogger.cpp │ │ ├── qx-common-io.cpp │ │ ├── qx-common-io_linux.cpp │ │ ├── qx-common-io_p.h │ │ ├── qx-common-io_win.cpp │ │ ├── qx-filestreamreader.cpp │ │ ├── qx-filestreamwriter.cpp │ │ ├── qx-ioopreport.cpp │ │ ├── qx-textpos.cpp │ │ ├── qx-textquery.cpp │ │ ├── qx-textstream.cpp │ │ ├── qx-textstreamreader.cpp │ │ └── qx-textstreamwriter.cpp ├── linux │ ├── CMakeLists.txt │ ├── cmake │ │ ├── depends_qt │ │ └── depends_siblings │ ├── doc │ │ └── general │ │ │ └── linux.dox │ ├── include │ │ └── qx │ │ │ └── linux │ │ │ ├── qx-applicationdesktopentry.h │ │ │ ├── qx-desktopentry.h │ │ │ ├── qx-directorydesktopentry.h │ │ │ └── qx-linkdesktopentry.h │ └── src │ │ ├── qx-applicationdesktopentry.cpp │ │ ├── qx-desktopentry.cpp │ │ ├── qx-directorydesktopentry.cpp │ │ └── qx-linkdesktopentry.cpp ├── network │ ├── CMakeLists.txt │ ├── cmake │ │ ├── depends_qt │ │ └── depends_siblings │ ├── doc │ │ └── general │ │ │ └── network.dox │ ├── include │ │ └── qx │ │ │ └── network │ │ │ ├── qx-downloadmanager.h │ │ │ ├── qx-downloadmanagerreport.h │ │ │ ├── qx-downloadopreport.h │ │ │ ├── qx-downloadtask.h │ │ │ └── qx-networkreplyerror.h │ └── src │ │ ├── qx-downloadmanager.cpp │ │ ├── qx-downloadmanagerreport.cpp │ │ ├── qx-downloadopreport.cpp │ │ ├── qx-downloadtask.cpp │ │ └── qx-networkreplyerror.cpp ├── utility │ ├── CMakeLists.txt │ ├── doc │ │ ├── general │ │ │ └── utility.dox │ │ └── res │ │ │ └── snippets │ │ │ ├── qx-helpers.cpp │ │ │ └── qx-stringliteral.cpp │ ├── include │ │ └── qx │ │ │ └── utility │ │ │ ├── qx-concepts.h │ │ │ ├── qx-helpers.h │ │ │ ├── qx-macros.h │ │ │ ├── qx-stringliteral.h │ │ │ └── qx-typetraits.h │ └── src │ │ ├── qx-concepts.dox │ │ ├── qx-helpers.dox │ │ ├── qx-macros.dox │ │ ├── qx-stringliteral.dox │ │ └── qx-typetraits.dox ├── widgets │ ├── CMakeLists.txt │ ├── cmake │ │ ├── depends_qt │ │ └── depends_siblings │ ├── doc │ │ ├── general │ │ │ └── widgets.dox │ │ └── res │ │ │ ├── images │ │ │ ├── qx-common-widgets-0.png │ │ │ ├── qx-logindialog-0.png │ │ │ └── qx-treeinputdialog-0.png │ │ │ └── snippets │ │ │ └── qx-common-widgets.cpp │ ├── include │ │ └── qx │ │ │ └── widgets │ │ │ ├── qx-buttongroup.h │ │ │ ├── qx-common-widgets.h │ │ │ ├── qx-logindialog.h │ │ │ ├── qx-standarditemmodel.h │ │ │ └── qx-treeinputdialog.h │ └── src │ │ ├── qx-buttongroup.cpp │ │ ├── qx-common-widgets.cpp │ │ ├── qx-common-widgets_p.cpp │ │ ├── qx-common-widgets_p.h │ │ ├── qx-logindialog.cpp │ │ ├── qx-standarditemmodel.cpp │ │ └── qx-treeinputdialog.cpp ├── windows-gui │ ├── CMakeLists.txt │ ├── cmake │ │ ├── depends_qt │ │ └── depends_siblings │ ├── doc │ │ ├── general │ │ │ └── windows-gui.dox │ │ └── res │ │ │ ├── images │ │ │ ├── qx-taskbarbutton-0.png │ │ │ ├── qx-taskbarbutton-1.png │ │ │ ├── qx-taskbarbutton-2.png │ │ │ ├── qx-taskbarbutton-3.png │ │ │ ├── qx-taskbarbutton-4.png │ │ │ └── qx-taskbarbutton-5.png │ │ │ └── snippets │ │ │ └── qx-taskbarbutton.cpp │ ├── include │ │ └── qx │ │ │ └── windows-gui │ │ │ ├── qx-taskbarbutton.h │ │ │ └── qx-winguievent.h │ └── src │ │ ├── qx-taskbarbutton.cpp │ │ ├── qx-winguievent.cpp │ │ ├── qx-winguieventfilter.cpp │ │ └── qx-winguieventfilter_p.h ├── windows │ ├── CMakeLists.txt │ ├── cmake │ │ ├── depends_qt │ │ └── depends_siblings │ ├── doc │ │ └── general │ │ │ ├── qx_windows.dox │ │ │ └── windows.dox │ ├── include │ │ ├── qx │ │ │ └── windows │ │ │ │ ├── qx-common-windows.h │ │ │ │ ├── qx-filedetails.h │ │ │ │ └── qx-windefs.h │ │ └── qx_windows.h │ └── src │ │ ├── qx-common-windows.cpp │ │ ├── qx-common-windows_p.cpp │ │ ├── qx-common-windows_p.h │ │ ├── qx-filedetails.cpp │ │ └── qx-windefs.dox └── xml │ ├── CMakeLists.txt │ ├── cmake │ └── depends_qt │ ├── doc │ └── general │ │ └── xml.dox │ ├── include │ └── qx │ │ └── xml │ │ ├── qx-common-xml.h │ │ ├── qx-xmlstreamreadererror.h │ │ └── qx-xmlstreamwritererror.h │ └── src │ ├── qx-common-xml.cpp │ ├── qx-xmlstreamreadererror.cpp │ └── qx-xmlstreamwritererror.cpp └── tests ├── CMakeLists.txt ├── _common ├── CMakeLists.txt └── include │ └── qx_test_common.h ├── core ├── CMakeLists.txt ├── qx_array │ ├── CMakeLists.txt │ └── tst_qx_array.cpp ├── qx_freeindextracker │ ├── CMakeLists.txt │ └── tst_qx_freeindextracker.cpp ├── qx_integrity │ ├── CMakeLists.txt │ └── tst_qx_integrity.cpp └── qx_json │ ├── CMakeLists.txt │ └── tst_qx_json.cpp ├── gui └── CMakeLists.txt ├── io ├── CMakeLists.txt └── qx_common_io │ ├── CMakeLists.txt │ ├── data │ └── writeStringToFile │ │ ├── overwrite_expected.txt │ │ ├── overwrite_input.txt │ │ └── overwrite_original.txt │ └── tst_qx_common_io.cpp ├── linux └── CMakeLists.txt ├── network └── CMakeLists.txt ├── utility └── CMakeLists.txt ├── widgets └── CMakeLists.txt ├── windows-gui └── CMakeLists.txt ├── windows └── CMakeLists.txt └── xml └── CMakeLists.txt /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | labels: 4 | - release 5 | - common-sync 6 | authors: 7 | - oby-bot 8 | categories: 9 | - title: Breaking Changes 10 | labels: 11 | - breaking 12 | - title: New Features 13 | labels: 14 | - enhancement 15 | - title: Bug Fixes 16 | labels: 17 | - bug 18 | - title: Implementation Improvements 19 | labels: 20 | - implementation 21 | - title: Other Changes 22 | labels: 23 | - "*" 24 | -------------------------------------------------------------------------------- /.github/workflows/build-project.yml: -------------------------------------------------------------------------------- 1 | name: Build Project 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches-ignore: 6 | - 'master' 7 | workflow_run: 8 | workflows: Tag and Sync 9 | types: completed 10 | branches: dev 11 | # This is the branch that the original workflow ran on, which is technically dev, due to how 12 | # the "pull_request" trigger works (it works off master correctly for a merged PR but is triggered 13 | # by dev 14 | 15 | jobs: 16 | trigger-build: 17 | name: Build Project 18 | if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' 19 | uses: oblivioncth/actions/.github/workflows/build-cxx-project.yml@v1 20 | secrets: 21 | ffynnon_access: ${{ secrets.OBYBOT_FFYNNON_ACCESS }} 22 | -------------------------------------------------------------------------------- /.github/workflows/check-release-pr.yml: -------------------------------------------------------------------------------- 1 | name: Check Release PR 2 | on: 3 | pull_request: 4 | types: [opened, synchronize, reopened] 5 | branches: master 6 | 7 | jobs: 8 | check-pr-correctness: 9 | name: Release PR Correctness Check 10 | uses: oblivioncth/actions/.github/workflows/validate-release-pr.yml@v1 11 | -------------------------------------------------------------------------------- /.github/workflows/generate-release.yml: -------------------------------------------------------------------------------- 1 | name: Generate Release 2 | on: 3 | workflow_run: 4 | workflows: Build Project 5 | types: completed 6 | branches: master 7 | 8 | jobs: 9 | generate-release: 10 | name: Generate Release 11 | permissions: 12 | actions: read 13 | contents: write 14 | pages: write 15 | id-token: write 16 | if: github.event.workflow_run.conclusion == 'success' 17 | uses: oblivioncth/actions/.github/workflows/generate-cxx-release.yml@v1 18 | with: 19 | artifacts_run_id: ${{ github.event.workflow_run.id }} 20 | -------------------------------------------------------------------------------- /.github/workflows/label-pr.yml: -------------------------------------------------------------------------------- 1 | name: Label PR 2 | on: 3 | pull_request_target: 4 | types: [opened, synchronize, reopened] 5 | 6 | jobs: 7 | label-pr: 8 | name: Label pull-request 9 | permissions: 10 | contents: read 11 | pull-requests: write 12 | uses: oblivioncth/actions/.github/workflows/label-pr.yml@v1 13 | -------------------------------------------------------------------------------- /.github/workflows/tag-release-commit-and-sync-dev.yml: -------------------------------------------------------------------------------- 1 | name: Tag and Sync 2 | on: 3 | pull_request: 4 | types: [closed] 5 | branches: 6 | - 'master' 7 | 8 | jobs: 9 | tag-master-and-sync-dev: 10 | name: Tag master merge commit, FF back to dev 11 | if: github.event.pull_request.merged == true 12 | permissions: 13 | contents: write 14 | uses: oblivioncth/actions/.github/workflows/tag-main-and-sync-dev.yml@v1 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | *.rc 35 | /.qmake.cache 36 | /.qmake.stash 37 | 38 | # qtcreator generated files 39 | *.pro.user* 40 | *.txt.user* 41 | 42 | # xemacs temporary files 43 | *.flc 44 | 45 | # Vim temporary files 46 | .*.swp 47 | 48 | # Visual Studio generated files 49 | *.ib_pdb_index 50 | *.idb 51 | *.ilk 52 | *.sln 53 | *.suo 54 | *.vcproj 55 | *vcproj.*.*.user 56 | *.ncb 57 | *.sdf 58 | *.opensdf 59 | *.vcxproj 60 | *vcxproj.* 61 | 62 | # MinGW generated files 63 | *.Debug 64 | *.Release 65 | 66 | # Python byte code 67 | *.pyc 68 | 69 | # Build within source 70 | /build 71 | 72 | # Binaries 73 | # -------- 74 | *.dll 75 | *.exe 76 | 77 | -------------------------------------------------------------------------------- /cmake/FetchOBCMake.cmake: -------------------------------------------------------------------------------- 1 | # Sets up OBCMake to be imported via git 2 | 3 | # git_ref - Tag, branch name, or commit hash to retrieve. According to CMake docs, 4 | # a commit hash is preferred for speed and reliability 5 | 6 | macro(fetch_ob_cmake git_ref) 7 | include(FetchContent) 8 | FetchContent_Declare(OBCMake 9 | GIT_REPOSITORY "https://github.com/oblivioncth/OBCMake" 10 | GIT_TAG ${git_ref} 11 | ) 12 | FetchContent_MakeAvailable(OBCMake) 13 | endmacro() 14 | -------------------------------------------------------------------------------- /cmake/file_templates/QxComponentConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # Guard against multiple imports 2 | if(NOT DEFINED __@PROJECT_NAMESPACE_UC@_@COMPONENT_NAME_UC@) 3 | message(VERBOSE "[@PROJECT_NAME@] Importing component: @COMPONENT_NAME@...") 4 | set(__@PROJECT_NAMESPACE_UC@_@COMPONENT_NAME_UC@ TRUE) 5 | 6 | # Inter-component dependencies (inserted when this file was configured) 7 | set(__@PROJECT_NAMESPACE_UC@_@COMPONENT_NAME_UC@_SIBLING_DEPENDS @COMPONENT_DEPENDS_SIBLINGS@) 8 | 9 | # Import above dependencies first 10 | foreach(sibling ${__@PROJECT_NAMESPACE_UC@_@COMPONENT_NAME_UC@_SIBLING_DEPENDS}) 11 | message(VERBOSE "[@PROJECT_NAME@] Component @COMPONENT_NAME@ depends on ${sibling}") 12 | include("${CMAKE_CURRENT_LIST_DIR}/../${sibling}/@PROJECT_NAMESPACE@${sibling}Config.cmake") 13 | endforeach() 14 | 15 | # Qt dependencies (inserted when this file was configured) 16 | set(__@PROJECT_NAMESPACE_UC@_@COMPONENT_NAME_UC@_QT_DEPENDS @COMPONENT_DEPENDS_QT@) 17 | if(__@PROJECT_NAMESPACE_UC@_@COMPONENT_NAME_UC@_QT_DEPENDS) 18 | find_dependency(Qt6 COMPONENTS ${__@PROJECT_NAMESPACE_UC@_@COMPONENT_NAME_UC@_QT_DEPENDS}) 19 | endif() 20 | 21 | # Import component targets 22 | message(VERBOSE "[@PROJECT_NAME@] Importing @COMPONENT_NAME@ targets...") 23 | include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAMESPACE@@COMPONENT_NAME@Targets.cmake") 24 | else() 25 | message(VERBOSE "[@PROJECT_NAME@] Skipping already imported component: @COMPONENT_NAME@") 26 | endif() 27 | -------------------------------------------------------------------------------- /cmake/file_templates/QxConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # Dependency helper for when it's needed 2 | include(CMakeFindDependencyMacro) 3 | 4 | # Find available Components 5 | file(GLOB __@PROJECT_NAMESPACE_UC@_AVAILABLE_COMPONENTS 6 | RELATIVE "${CMAKE_CURRENT_LIST_DIR}" 7 | "${CMAKE_CURRENT_LIST_DIR}/*/@PROJECT_NAMESPACE@*Config.cmake" 8 | ) 9 | 10 | # Report available Components 11 | message(STATUS "[@PROJECT_NAME@] Available Components:") 12 | foreach(component_config ${__@PROJECT_NAMESPACE_UC@_AVAILABLE_COMPONENTS}) 13 | message(STATUS "- ${component_config}") 14 | endforeach() 15 | 16 | # Components were requested 17 | if(@PROJECT_NAMESPACE@_FIND_COMPONENTS) 18 | message(STATUS "[@PROJECT_NAMESPACE@] Components were requested.") 19 | 20 | # Check for and add each request 21 | foreach(req_component ${@PROJECT_NAMESPACE@_FIND_COMPONENTS}) 22 | set(req_component_config ${req_component}/@PROJECT_NAMESPACE@${req_component}Config.cmake) 23 | 24 | if (";${__@PROJECT_NAMESPACE_UC@_AVAILABLE_COMPONENTS};" MATCHES ";${req_component_config};") 25 | message(STATUS "[@PROJECT_NAME@] Including matched component: ${req_component}.") 26 | set(@PROJECT_NAMESPACE@_${req_component}_FOUND True) 27 | include("${CMAKE_CURRENT_LIST_DIR}/${req_component_config}") 28 | elseif() 29 | message(STATUS "[@PROJECT_NAME@] Unavailable component: ${req_component}" 30 | set(@PROJECT_NAMESPACE@_${req_component}_FOUND False) 31 | 32 | if(@PROJECT_NAMESPACE@_FIND_REQUIRED_${req_component}}) 33 | set(@PROJECT_NAMESPACE@_FOUND False) 34 | set(@PROJECT_NAMESPACE@_NOT_FOUND_MESSAGE "Missing component: ${req_component}") 35 | endif() 36 | endif() 37 | endforeach() 38 | else() # Components were not requested 39 | message(STATUS "[Qx] No components were requested. Importing all available.") 40 | 41 | # Add all components 42 | foreach(component_config ${__@PROJECT_NAMESPACE_UC@_AVAILABLE_COMPONENTS}) 43 | message(STATUS "[@PROJECT_NAMESPACE@] Including available component: ${component_config}.") 44 | include("${CMAKE_CURRENT_LIST_DIR}/${component_config}") 45 | endforeach() 46 | endif() 47 | -------------------------------------------------------------------------------- /cmake/file_templates/primary_component_header.h.in: -------------------------------------------------------------------------------- 1 | /* [@PROJECT_NAME@] 2 | * Version: @PROJECT_VERSION_VERBOSE@ 3 | * Qt Version: @Qt6_VERSION@ 4 | * Platform: @CMAKE_SYSTEM_NAME@ 5 | * Build Date: @BUILD_DATE_TIME@ 6 | * Component: @COMPONENT_NAME@ 7 | */ 8 | 9 | #ifndef @COMPONENT_HEADER_GUARD@ 10 | #define @COMPONENT_HEADER_GUARD@ 11 | 12 | @COMPONENT_HEADER_INCLUDES@ 13 | #endif // @COMPONENT_HEADER_GUARD@ 14 | -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Include standard documentation target creator 2 | include(OB/Documentation) 3 | 4 | # Gather component level input 5 | foreach(component ${LIB_COMPONENTS}) 6 | list(APPEND COMPONENT_DOC_ROOTS "${COMPONENTS_PATH}/${component}/doc") 7 | list(APPEND COMPONENT_DOC_INPUT "${COMPONENTS_PATH}/${component}/src") 8 | list(APPEND COMPONENT_DOC_INPUT "${COMPONENTS_PATH}/${component}/include") 9 | endforeach() 10 | 11 | # Set project specific doxygen overrides 12 | set(DOXYGEN_PREDEFINED 13 | "QX_ERROR_TYPE(Type,Name,Code)=Type final : public Qx::AbstractError" 14 | "__QX_JSON_META_STRUCT=" 15 | "QX_DECLARE_ERROR_ADAPTATION(Adaptable, Adapter)=" 16 | ) 17 | 18 | set(DOXYGEN_EXCLUDE_SYMBOLS 19 | "_QxPrivate" 20 | ) 21 | 22 | # Setup documentation 23 | ob_standard_documentation(${DOC_TARGET_NAME} 24 | DOXY_VER 1.9.4 25 | PROJ_NAME "${PROJECT_NAME}" 26 | QT_MODULES 27 | qtconcurrent 28 | qtcore 29 | qtgui 30 | qtnetwork 31 | qtsql 32 | qtsvg 33 | qtwidgets 34 | qtxml 35 | ADDITIONAL_ROOTS 36 | ${COMPONENT_DOC_ROOTS} 37 | INPUT_LIST 38 | ${COMPONENT_DOC_INPUT} 39 | THEME_COLORS 40 | PRIMARY "#CC2828" 41 | NIGHT_PRIMARY "#E22D2D" 42 | ) 43 | -------------------------------------------------------------------------------- /doc/general/majorfeatures.md: -------------------------------------------------------------------------------- 1 | Major Features {#majorfeatures} 2 | =============================== 3 | 4 | This page catalogues the most significant features of Qx, which generally form a complete/comprehensive system that can be evaluated independently from the rest of the library. 5 | 6 | - @subpage properties "Bindable Properties System" 7 | - @subpage declarativejson "Declarative JSON" 8 | -------------------------------------------------------------------------------- /doc/general/namespace.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @namespace Qx 3 | * 4 | * @brief The @c Qx namespace is the main namespace through which all non-global functionality of the Qx 5 | * library is accessed. 6 | * 7 | * Nearly all library features are nested within this namespace in a similar vein as @c std with the 8 | * C++ Standard Library. 9 | * 10 | * See the File Member's Index for all global library elements. 11 | */ 12 | -------------------------------------------------------------------------------- /lib/core/cmake/depends_qt: -------------------------------------------------------------------------------- 1 | Core -------------------------------------------------------------------------------- /lib/core/cmake/depends_siblings: -------------------------------------------------------------------------------- 1 | Utility -------------------------------------------------------------------------------- /lib/core/doc/general/core.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @defgroup qx-core Qx Core 3 | * 4 | * @brief The Core component is the main module of the Qx library. 5 | * 6 | * @component{Core,core.h} 7 | * 8 | * Qx Core provides the most commonly used and general purpose functionality of the library, while also acting as 9 | * a base from which most other components are derived from. 10 | * 11 | * This component roughly mirrors Qt Core in terms of scope and organization. 12 | */ 13 | -------------------------------------------------------------------------------- /lib/core/doc/general/declarativejson.md: -------------------------------------------------------------------------------- 1 | Qx Declarative JSON {#declarativejson} 2 | ====================================== 3 | 4 | Qx features a highly flexible, simple to use, declarative mechanism for parsing/serializing JSON data into user structs and other types. 5 | 6 | For example, the following JSON data: 7 | 8 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.json} 9 | { 10 | "title": "Sample JSON Data", 11 | "info": { 12 | "rating": 10, 13 | "cool": true 14 | }, 15 | "reviews": [ 16 | "Wicked!", 17 | "Awesome!", 18 | "Fantastic!" 19 | ] 20 | } 21 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 22 | 23 | can easily be parsed into a corresponding set of C++ data structures like so: 24 | 25 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} 26 | #include 27 | 28 | struct Info 29 | { 30 | int rating; 31 | bool cool; 32 | 33 | QX_JSON_STRUCT(rating, cool); 34 | }; 35 | 36 | struct MyJson 37 | { 38 | QString title; 39 | Info info; 40 | QList reviews; 41 | 42 | QX_JSON_STRUCT(title, info, reviews); 43 | }; 44 | 45 | int main() 46 | { 47 | QFile jsonFile("data.json"); 48 | MyJson myJsonDoc; 49 | 50 | // Parse into custom structures 51 | Qx::JsonError je = Qx::parseJson(myJsonDoc, jsonFile); 52 | Q_ASSERT(!je.isValid()); 53 | 54 | ... 55 | } 56 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | 58 | Likewise, the structure can be serialized back out into textual JSON data with: 59 | 60 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} 61 | int main() 62 | { 63 | ... 64 | 65 | // Serialize to JSON 66 | je = Qx::serializeJson(jsonFile, myJsonDoc); 67 | Q_ASSERT(!je.isValid()); 68 | } 69 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 70 | 71 | This system is accessed through the qx-json.h header, predominantly with QX_JSON_STRUCT(). -------------------------------------------------------------------------------- /lib/core/doc/res/images/properties-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/lib/core/doc/res/images/properties-0.png -------------------------------------------------------------------------------- /lib/core/doc/res/snippets/qx-abstracterror.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | #include 3 | 4 | class MyError final : public Qx::AbstractError<"MyError", 1015> 5 | { 6 | private: 7 | quint16 mErrorValue; 8 | QString mPrimaryCause; 9 | 10 | public: 11 | MyError() : 12 | mErrorValue(1), 13 | mPrimaryCause("A bad thing happened.") 14 | {} 15 | 16 | private: 17 | void deriveValue() { return mErrorValue; } 18 | void derivePrimary() { return mPrimaryCause; } 19 | //... 20 | } 21 | //! [0] 22 | 23 | //! [1] 24 | template 25 | class MyErrorTemplate : public AbstractError 26 | { 27 | protected: 28 | MyErrorTemplate() {} 29 | 30 | private: 31 | //... 32 | } 33 | //! [1] 34 | 35 | //! [2] 36 | class QX_ERROR_TYPE(MyError, "MyError", 1020) 37 | { 38 | //.. 39 | } 40 | //! [2] 41 | -------------------------------------------------------------------------------- /lib/core/doc/res/snippets/qx-bitarray.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | Qx::BitArray ba = Qx::BitArray::fromInteger(quint16(20)); 3 | ba.at(0); // 0 4 | ba.at(1); // 0 5 | ba.at(2); // 1 6 | ba.at(3); // 0 7 | ba.at(4); // 1 8 | ba.at(5); // 0 9 | ba.at(6); // 0 10 | ba.at(7); // 0 11 | ba.at(8); // 0 12 | ba.at(9); // 0 13 | ba.at(10); // 0 14 | ba.at(11); // 0 15 | ba.at(12); // 0 16 | ba.at(13); // 0 17 | ba.at(14); // 0 18 | ba.at(15); // 0 19 | //! [0] -------------------------------------------------------------------------------- /lib/core/doc/res/snippets/qx-exclusiveaccess.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | class Node; 3 | 4 | class Manager 5 | { 6 | public: 7 | Manager(); 8 | void registerNode(Node* node); 9 | //... 10 | }; 11 | 12 | class Node 13 | { 14 | static Qx::ExclusiveAccess manager() 15 | { 16 | // RAII 17 | static Manager m; 18 | static QMutex mtx; 19 | return Qx::ExclusiveAccess(&m, &mtx); // Locks the mutex and stays locked since this is moved 20 | } 21 | 22 | public: 23 | Node(); 24 | void registerSelf() 25 | { 26 | // Nodes could be in any thread, so this allows access to the manager to be synchronized 27 | auto mAccess = manager(); 28 | mAccess->registerNode(this); 29 | // Use access as needed... 30 | 31 | // Mutex is unlocked when mAccess is destroyed 32 | } 33 | }; 34 | 35 | void someFunctionInAThread() 36 | { 37 | std::shared_ptr node; 38 | node->registerSelf(); 39 | //... 40 | } 41 | //! [0] 42 | -------------------------------------------------------------------------------- /lib/core/doc/res/snippets/qx-groupedprogressmanager.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | Qx::GroupedProgressManager gpm; 3 | 4 | Qx::ProgressGroup* fileGroup = gpm.addGroup("File Copies"); 5 | fileGroup->setMaximum(100); 6 | fileGroup->setValue(50); // 50% completion of "File Copies" 7 | fileGroup->setWeight(3); 8 | 9 | Qx::ProgressGroup* coolGroup = gpm.addGroup("Cool Stuff"); 10 | coolGroup->setMaximum(100); 11 | coolGroup->setValue(0); // 0% completion of "Cool Stuff" 12 | coolGroup->setWeight(7); 13 | 14 | quint64 overallProgress = gpm.value(); // overallProgress = 15 15 | //! [0] -------------------------------------------------------------------------------- /lib/core/doc/res/snippets/qx-index.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | Index(Qx::Last) + 10 // = Index(Qx::Last) 3 | Index(Qx::Last) - 10 // = Index(Qx::Last) 4 | Index(5) + Index(Qx::Last) // = Index(Qx::Last) 5 | Index(1087) - Index(Qx::Last) // = 0 6 | Index(Qx::Last) * 130 // = Index(Qx::Last) 7 | Index(Qx::Last) / 58 // = Index(Qx::Last) 8 | Index(Qx::Last) / Index(Qx::Last) // = 1 9 | Index(98) / Index(Qx::Last) // = 0 10 | //! [0] -------------------------------------------------------------------------------- /lib/core/doc/res/snippets/qx-table.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | Qx::Table table({ 3 | {0, 1, 2}, 4 | {3, 4, 5}, 5 | {6, 7, 8} 6 | }); 7 | 8 | Qx::DsvTable sectionTable({ 9 | {1, 2}, 10 | {4, 5}, 11 | {7, 8} 12 | }); 13 | 14 | qDebug() << sectionTable == table.section(0, 1, 3, 2); 15 | // true 16 | //! [0] -------------------------------------------------------------------------------- /lib/core/doc/res/snippets/qx-threadsafesingleton.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | class MySingleton : Qx::ThreadSafeSingleton 3 | { 4 | QX_THREAD_SAFE_SINGLETON(MySingleton); 5 | private: 6 | std::string mData; 7 | MySingleton() = default; // Generally should be private 8 | 9 | public: 10 | doStuffSafely() { mData = "I'm for sure set while not being read!"; } 11 | checkStuffSafely() { return mData; // Not being written to when returned } 12 | } 13 | 14 | //... 15 | 16 | void functionInArbitraryThread() 17 | { 18 | auto singleton = MySingleton::instance(); 19 | // This function now has a exclusive access to MySingleton (i.e. a mutex lock is established) 20 | singleton->doStuffSafely(); 21 | 22 | // Unlocked when 'singleton' goes out of scope, or is manually unlocked. 23 | } 24 | 25 | void functionInAnotherThread() 26 | { 27 | // Safely lock and read. It's guarenteed that no other thread is using MySingleton 28 | // after the instance is obtained. 29 | auto singleton = MySingleton::instance(); 30 | std::string info = singleton->checkStuffSafely(); 31 | //... 32 | } 33 | //! [0] 34 | -------------------------------------------------------------------------------- /lib/core/doc/res/snippets/qx-versionnumber.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | VersionNumber v1(3,0,0,0); 3 | VersionNumber v2(10,1,0); 4 | VersionNumber v3(1,2,0,0); 5 | VersionNumber n1 = v1.normalized(2); 6 | VersionNumber n2 = v2.normalized(8); 7 | VersionNumber n3 = v3.normalized(); 8 | // n1 is 3.0 9 | // n2 is 10.1.0 10 | // n3 is 1.2 11 | //! [0] -------------------------------------------------------------------------------- /lib/core/include/qx/core/__private/qx-internalerror.h: -------------------------------------------------------------------------------- 1 | // Shared Lib Support 2 | #include "qx/core/qx_core_export.h" 3 | 4 | // Intra-component Includes 5 | #include "qx/core/qx-abstracterror.h" 6 | 7 | /*! @cond */ 8 | namespace QxPrivate 9 | { 10 | 11 | // Basically a copy of GenericError for internal use only 12 | class QX_CORE_EXPORT InternalError final : public Qx::AbstractError<"Qx::InternalError", 0> 13 | { 14 | //-Public Variables------------------------------------------------------------------------------------------ 15 | public: 16 | enum Value 17 | { 18 | VAL_SSL_ERR = 1 19 | }; 20 | 21 | //-Instance Members------------------------------------------------------------------------------------------ 22 | private: 23 | quint32 mValue; 24 | Qx::Severity mSeverity; 25 | QString mCaption; 26 | QString mPrimary; 27 | QString mSecondary; 28 | QString mDetails; 29 | 30 | //-Constructor---------------------------------------------------------------------------------------------- 31 | public: 32 | InternalError(); 33 | InternalError(Qx::Severity severity, quint32 value, const QString& primary, 34 | const QString& secondary = {}, const QString& details = {}, const QString& caption = {}); 35 | 36 | //-Instance Functions---------------------------------------------------------------------------------------------- 37 | private: 38 | quint32 deriveValue() const override; 39 | Qx::Severity deriveSeverity() const override; 40 | QString deriveCaption() const override; 41 | QString derivePrimary() const override; 42 | QString deriveSecondary() const override; 43 | QString deriveDetails() const override; 44 | 45 | public: 46 | bool isValid() const; 47 | quint32 value() const; 48 | Qx::Severity severity() const; 49 | QString caption() const; 50 | QString primary() const; 51 | QString secondary() const; 52 | QString details() const; 53 | 54 | InternalError& setSeverity(Qx::Severity sv); 55 | InternalError withSeverity(Qx::Severity sv); 56 | InternalError& setCaption(const QString& caption); 57 | InternalError& setPrimary(const QString& primary); 58 | InternalError& setSecondary(const QString& secondary); 59 | InternalError& setDetails(const QString& details); 60 | }; 61 | 62 | } 63 | /*! @endcond */ 64 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-array.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_ARRAY_H 2 | #define QX_ARRAY_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Extra-component Includes 8 | #include "qx/utility/qx-concepts.h" 9 | 10 | // TODO: These functions are pretty underwhelming, see if more flexible ones that make use 11 | // of range/iterator based functions from std can be made instead. 12 | 13 | namespace Qx 14 | { 15 | 16 | class Array 17 | { 18 | //-Class Functions---------------------------------------------------------------------------------------------- 19 | public: 20 | template 21 | static constexpr int constDim(const T(&)[N]) { return N; } // Allows using the size of a const array at runtime 22 | 23 | template 24 | static int indexOf(const T(&array) [N], const T query) 25 | { 26 | for(int i = 0; i < N; i++) 27 | if(array[i] == query) 28 | return i; 29 | 30 | return -1; 31 | } 32 | 33 | template 34 | requires arithmetic 35 | static T maxOf(const T(&array) [N]) 36 | { 37 | T max = array[0]; 38 | 39 | for(int i = 1; i < N; i++) 40 | if(array[i] > max) 41 | max = array[i]; 42 | 43 | return max; 44 | } 45 | 46 | template 47 | requires arithmetic 48 | static T minOf(const T(&array) [N]) 49 | { 50 | T min = array[0]; 51 | 52 | for(int i = 1; i < N; i++) 53 | if(array[i] < min) 54 | min = array[i]; 55 | 56 | return min; 57 | } 58 | 59 | template 60 | static T mostFrequent(const T(&array) [N]) 61 | { 62 | /* TODO: The use of a hash here means that if more 63 | * than one element is tied for the highest frequency that 64 | * the one this function returns will essentially be random 65 | * instead of something well defined like always being 66 | * the first one. 67 | */ 68 | 69 | // Load all array elements into a hash 70 | QHash hash; 71 | for(int i = 0; i < N; i++) 72 | hash[array[i]]++; 73 | 74 | // Determine greatest frequency 75 | int maxFreq = 0; 76 | T maxFreqVal = array[0]; // Assume first value is most frequent to start 77 | QHashIterator i(hash); 78 | 79 | while(i.hasNext()) 80 | { 81 | i.next(); 82 | if(maxFreq < i.value()) 83 | { 84 | maxFreqVal = i.key(); 85 | maxFreq = i.value(); 86 | } 87 | } 88 | 89 | return maxFreqVal; 90 | } 91 | }; 92 | 93 | } 94 | 95 | #endif // QX_ARRAY_H 96 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-bitarray.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_BITARRAY_H 2 | #define QX_BITARRAY_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_CORE_EXPORT BitArray : public QBitArray 14 | { 15 | //-Constructor-------------------------------------------------------------------------------------------------- 16 | public: 17 | BitArray(); 18 | BitArray(int size, bool value = false); 19 | 20 | //-Class Functions---------------------------------------------------------------------------------------------- 21 | public: 22 | template 23 | requires std::integral 24 | static BitArray fromInteger(const T& integer) 25 | { 26 | int bitCount = sizeof(T)*8; 27 | 28 | BitArray bitRep(bitCount); 29 | 30 | for(int i = 0; i < bitCount; ++i) 31 | if(integer & 0b1 << i) 32 | bitRep.setBit(i); 33 | 34 | return bitRep; 35 | } 36 | 37 | //-Instance Functions------------------------------------------------------------------------------------------- 38 | public: 39 | template 40 | requires std::integral 41 | T toInteger() 42 | { 43 | int bitCount = sizeof(T)*8; 44 | T integer = 0; 45 | 46 | for(int i = 0; i < bitCount && i < count(); ++i) 47 | integer |= (testBit(i) ? 0b1 : 0b0) << i; 48 | 49 | return integer; 50 | } 51 | 52 | QByteArray toByteArray(QSysInfo::Endian endianness = QSysInfo::BigEndian); 53 | 54 | void append(bool bit = false); 55 | void replace(const BitArray& bits, int start = 0, int length = -1); 56 | 57 | template 58 | requires std::integral 59 | void replace(T integer, int start = 0, int length = -1) 60 | { 61 | BitArray converted = BitArray::fromInteger(integer); 62 | replace(converted, start, length); 63 | } 64 | 65 | BitArray subArray(int start, int length = -1); 66 | BitArray takeFromStart(int length = -1); 67 | BitArray takeFromEnd(int length = -1); 68 | 69 | BitArray operator<<(int n); 70 | void operator<<=(int n); 71 | BitArray operator>>(int n); 72 | void operator>>=(int n); 73 | BitArray operator+(BitArray rhs); 74 | void operator+=(const BitArray& rhs); 75 | }; 76 | 77 | 78 | } 79 | 80 | #endif // QX_BITARRAY_H 81 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-bytearray.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_BYTEARRAY_H 2 | #define QX_BYTEARRAY_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Standard Library Includes 8 | #include 9 | 10 | // Qt Includes 11 | #include 12 | #include 13 | 14 | // Extra-component Includes 15 | #include "qx/utility/qx-concepts.h" 16 | 17 | namespace Qx 18 | { 19 | 20 | class QX_CORE_EXPORT ByteArray 21 | { 22 | //-Class Functions---------------------------------------------------------------------------------------------- 23 | public: 24 | template 25 | requires arithmetic 26 | static QByteArray fromPrimitive(T primitive, QSysInfo::Endian endianness = QSysInfo::ByteOrder) 27 | { 28 | // Ensure correct byte order 29 | if(endianness == QSysInfo::LittleEndian) 30 | primitive = qToLittleEndian(primitive); 31 | else 32 | primitive = qToBigEndian(primitive); 33 | 34 | // Return QByteArray constructed from primitive viewed as a char array 35 | return QByteArray(reinterpret_cast(&primitive), sizeof(T)); 36 | } 37 | 38 | /* 39 | * This is valid C++17 syntax for explicit template specialization, but due to an outstanding 40 | * bug this won't compile with GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282 41 | * 42 | * The workaround is to fake partial template specialization using a dummy template parameter. 43 | */ 44 | #if defined __GNUC__ && !defined __clang__ // If using G++ 45 | template 46 | inline QByteArray fromPrimitive(bool primitive, QSysInfo::Endian endianness) 47 | #else 48 | template<> 49 | inline QByteArray fromPrimitive(bool primitive, QSysInfo::Endian endianness) 50 | #endif 51 | { 52 | Q_UNUSED(endianness); 53 | // Ensures true -> 0x01 and false -> 0x00 54 | return primitive ? QByteArray(1, '\x01') : QByteArray(1, '\x00'); 55 | } 56 | 57 | template 58 | requires arithmetic 59 | static T toPrimitive(QByteArray ba, QSysInfo::Endian endianness = QSysInfo::ByteOrder) 60 | { 61 | if(endianness == QSysInfo::LittleEndian) 62 | { 63 | if(ba.size() < sizeof(T)) 64 | ba.append(sizeof(T) - ba.size(),'\x00'); 65 | return qFromLittleEndian(ba); 66 | } 67 | else 68 | { 69 | if(ba.size() < sizeof(T)) 70 | ba.prepend(sizeof(T) - ba.size(),'\x00'); 71 | return qFromBigEndian(ba); 72 | } 73 | } 74 | }; 75 | 76 | } 77 | 78 | #endif // QX_BYTEARRAY_H 79 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-char.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_CHAR_H 2 | #define QX_CHAR_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_CORE_EXPORT Char 14 | { 15 | //-Class Functions---------------------------------------------------------------------------------------------- 16 | public: 17 | static bool isHexNumber(QChar hexNum); 18 | static bool isSpace(const QChar& ch); 19 | static bool isSpace(char chr); 20 | static bool isSpace(unsigned char ch); 21 | static bool isSpace(signed char ch); 22 | static bool isSpace(wchar_t ch); 23 | static int compare(QChar cOne, QChar cTwo, Qt::CaseSensitivity cs = Qt::CaseSensitive); 24 | }; 25 | 26 | } 27 | 28 | #endif // QX_CHAR_H 29 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-datetime.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_DATETIME_H 2 | #define QX_DATETIME_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_CORE_EXPORT DateTime 14 | { 15 | //-Class Variables---------------------------------------------------------------------------------------------- 16 | private: 17 | static const qint64 FILETIME_EPOCH_OFFSET_MS = 11644473600000; // Milliseconds between FILETIME 0 and Unix Epoch 0 18 | 19 | //-Class Functions---------------------------------------------------------------------------------------------- 20 | public: 21 | static QDateTime fromMSFileTime(quint64 fileTime); 22 | }; 23 | 24 | } 25 | 26 | #endif // QX_DATETIME_H 27 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-dsvtable.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_DSVTABLE_H 2 | #define QX_DSVTABLE_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | 11 | // Intra-component Includes 12 | #include "qx/core/qx-table.h" 13 | 14 | using namespace Qt::Literals::StringLiterals; 15 | 16 | namespace Qx 17 | { 18 | 19 | class QX_CORE_EXPORT DsvParseError 20 | { 21 | //-Class Enum----------------------------------------------------------------------------------------------------------- 22 | public: 23 | enum ParseError{ 24 | NoError, 25 | IllegalEscape, 26 | UnterminatedField, 27 | UnevenColumns, 28 | InternalError 29 | }; 30 | 31 | //-Class Variables------------------------------------------------------------------------------------------------------ 32 | private: 33 | static inline const QHash ERROR_STR_MAP{ 34 | {NoError, u"No error occurred."_s}, 35 | {IllegalEscape, u"Illegal use of an escape character."_s}, 36 | {UnterminatedField, u"An escaped field was not properly terminated."_s}, 37 | {UnevenColumns, u"A row contained a different number of fields than the header row."_s}, 38 | {InternalError, u"An internal parser error occurred."_s} 39 | }; 40 | 41 | //-Instance Variables------------------------------------------------------------------------------------------------------------ 42 | private: 43 | ParseError mError; 44 | qsizetype mOffset; 45 | 46 | //-Constructor------------------------------------------------------------------------------------------------- 47 | public: 48 | DsvParseError(); 49 | DsvParseError(ParseError error, qsizetype offset); 50 | 51 | //-Instance Functions--------------------------------------------------------------------------------------------------------- 52 | public: 53 | ParseError error() const; 54 | QString errorString() const; 55 | qsizetype offset() const; 56 | }; 57 | 58 | class QX_CORE_EXPORT DsvTable : public Table 59 | { 60 | //-Constructor---------------------------------------------------------------------------------------------- 61 | public: 62 | DsvTable(); 63 | DsvTable(QSize size); 64 | DsvTable(QSize size, const QVariant& value); 65 | DsvTable(std::initializer_list> table); 66 | 67 | //-Class Functions---------------------------------------------------------------------------------------------- 68 | public: 69 | static DsvTable fromDsv(const QByteArray& dsv, QChar delim = ',', QChar esc = '"', DsvParseError* error = nullptr); 70 | 71 | //-Instance Functions---------------------------------------------------------------------------------------------- 72 | public: 73 | QByteArray toDsv(QChar delim = ',', QChar esc = '"'); 74 | }; 75 | 76 | } 77 | 78 | #endif // QX_DSVTABLE_H 79 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-freeindextracker.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_FREEINDEXTRACKER_H 2 | #define QX_FREEINDEXTRACKER_H 3 | 4 | // Standard Library Includes 5 | #include 6 | 7 | // Qt Includes 8 | #include 9 | 10 | // Intra-component Includes 11 | #include 12 | 13 | namespace Qx 14 | { 15 | 16 | class QX_CORE_EXPORT FreeIndexTracker 17 | { 18 | //-Instance Members---------------------------------------------------------------------------------------------- 19 | private: 20 | // std::vector Used over QList since it's is often optimized by std library implementations to use individual bits per element 21 | std::vector mReserved; 22 | quint64 mFree; 23 | quint64 mMin; 24 | quint64 mMax; 25 | 26 | //-Constructor--------------------------------------------------------------------------------------------------- 27 | public: 28 | FreeIndexTracker(quint64 min = 0, quint64 max = 1, QSet reserved = QSet()); 29 | 30 | //-Instance Functions---------------------------------------------------------------------------------------------- 31 | private: 32 | quint64 internalIdx(quint64 extIdx) const; 33 | quint64 externalIdx(quint64 intIdx) const; 34 | bool resrv(quint64 extIdx); 35 | bool relse(quint64 extIdx); 36 | 37 | public: 38 | bool isReserved(quint64 index) const; 39 | quint64 minimum() const; 40 | quint64 maximum() const; 41 | quint64 range() const; 42 | quint64 free() const; 43 | quint64 reserved() const; 44 | bool isBooked() const; 45 | 46 | std::optional firstReserved() const; 47 | std::optional lastReserved() const; 48 | std::optional firstFree() const; 49 | std::optional lastFree() const; 50 | std::optional previousFree(quint64 index) const; 51 | std::optional nextFree(quint64 index) const; 52 | std::optional nearestFree(quint64 index) const; 53 | 54 | bool reserve(quint64 index); 55 | std::optional reserveFirstFree(); 56 | std::optional reserveLastFree(); 57 | std::optional reserveNextFree(quint64 index); 58 | std::optional reservePreviousFree(quint64 index); 59 | std::optional reserveNearestFree(quint64 index); 60 | bool reserveAll(); 61 | 62 | bool release(quint64 index); 63 | bool releaseAll(); 64 | }; 65 | 66 | } 67 | 68 | #endif // QX_FREEINDEXTRACKER_H 69 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-genericerror.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_GENERICERROR_H 2 | #define QX_GENERICERROR_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Intra-component Includes 8 | #include "qx/core/qx-abstracterror.h" 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_CORE_EXPORT GenericError final : public AbstractError<"Qx::GenericError", 999> 14 | { 15 | //-Instance Variables------------------------------------------------------------------------------------------ 16 | private: 17 | quint32 mValue; 18 | Severity mSeverity; 19 | QString mCaption; 20 | QString mPrimary; 21 | QString mSecondary; 22 | QString mDetails; 23 | 24 | //-Constructor---------------------------------------------------------------------------------------------- 25 | public: 26 | GenericError(); 27 | GenericError(Severity severity, quint32 value, const QString& primary, 28 | const QString& secondary = {}, const QString& details = {}, const QString& caption = {}); 29 | 30 | //-Instance Functions---------------------------------------------------------------------------------------------- 31 | private: 32 | quint32 deriveValue() const override; 33 | Severity deriveSeverity() const override; 34 | QString deriveCaption() const override; 35 | QString derivePrimary() const override; 36 | QString deriveSecondary() const override; 37 | QString deriveDetails() const override; 38 | 39 | public: 40 | bool isValid() const; 41 | quint32 value() const; 42 | Severity severity() const; 43 | QString caption() const; 44 | QString primary() const; 45 | QString secondary() const; 46 | QString details() const; 47 | 48 | GenericError& setSeverity(Severity sv); 49 | GenericError withSeverity(Severity sv); 50 | GenericError& setCaption(const QString& caption); 51 | GenericError& setPrimary(const QString& primary); 52 | GenericError& setSecondary(const QString& secondary); 53 | GenericError& setDetails(const QString& details); 54 | 55 | //-Operators------------------------------------------------------------------------------------------------------- 56 | public: 57 | bool operator==(const GenericError& other) const = default; 58 | bool operator!=(const GenericError& other) const = default; 59 | 60 | }; 61 | 62 | } 63 | 64 | #endif // QX_GENERICERROR_H 65 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-global.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_GLOBAL_H 2 | #define QX_GLOBAL_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | namespace Qx 8 | { 9 | //-Namespace Types----------------------------------------------------------------------------------------------------------- 10 | enum Severity 11 | { 12 | Warning = 1, 13 | Err = 2, 14 | Critical = 3 15 | }; 16 | 17 | enum Extent 18 | { 19 | First, 20 | Start = First, 21 | Last, 22 | End = Last 23 | }; 24 | 25 | //-Namespace Functions----------------------------------------------------------------------------------------------------------- 26 | QString severityString(Severity sv, bool uc = true); 27 | 28 | } 29 | 30 | #endif // QX_GLOBAL_H 31 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-groupedprogressmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_GROUPEDPROGRESSMANAGER_H 2 | #define QX_GROUPEDPROGRESSMANAGER_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | 11 | // Intra-component Includes 12 | #include "qx/core/qx-progressgroup.h" 13 | 14 | namespace Qx 15 | { 16 | 17 | class QX_CORE_EXPORT GroupedProgressManager : public QObject 18 | { 19 | //-QObject Macro (Required for all QObject Derived Classes)----------------------------------------------------------- 20 | Q_OBJECT 21 | 22 | //-Class Members--------------------------------------------------------------------------------------------- 23 | private: 24 | // TODO: Consider increasing this to 100,000 for finer granularity of overall progress and more 25 | // frequent emissions of valueChanged() (for things like QProgressBar::setValue()) 26 | static const quint64 UNIFIED_MAXIMUM = 100; 27 | 28 | //-Instance Properties------------------------------------------------------------------------------------------------------- 29 | private: 30 | Q_PROPERTY(quint64 value READ value NOTIFY valueChanged); 31 | Q_PROPERTY(quint64 maximum READ maximum CONSTANT); 32 | 33 | //-Instance Members------------------------------------------------------------------------------------------ 34 | private: 35 | quint64 mCurrentValue; 36 | QHash mGroups; 37 | QHash mRelativePortions; 38 | 39 | //-Constructor---------------------------------------------------------------------------------------------- 40 | public: 41 | explicit GroupedProgressManager(QObject* parent = nullptr); 42 | 43 | //-Instance Functions---------------------------------------------------------------------------------------------- 44 | private: 45 | void updateRelativePortions(); 46 | void updateValue(); 47 | 48 | public: 49 | void addGroup(ProgressGroup* progressGroup); 50 | ProgressGroup* addGroup(const QString& name); 51 | ProgressGroup* group(const QString& name); 52 | void removeGroup(const QString& name); 53 | 54 | quint64 value() const; 55 | quint64 maximum() const; 56 | 57 | //-Slots------------------------------------------------------------------------------------------------------------ 58 | private slots: 59 | void childValueChanged(quint64 value); 60 | void childMaximumChanged(quint64 maximum); 61 | void childWeightChanged(); 62 | 63 | //-Signals------------------------------------------------------------------------------------------------------------ 64 | signals: 65 | void valueChanged(quint64 value); 66 | void progressUpdated(quint64 currentValue); 67 | void groupValueChanged(Qx::ProgressGroup* group, quint64 value); 68 | void groupMaximumChanged(Qx::ProgressGroup* group, quint64 maximum); 69 | }; 70 | 71 | } 72 | 73 | #endif // QX_GROUPEDPROGRESSMANAGER_H 74 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-integrity.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_INTEGRITY_H 2 | #define QX_INTEGRITY_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | 11 | namespace Qx 12 | { 13 | 14 | class QX_CORE_EXPORT Integrity 15 | { 16 | //-Class Functions--------------------------------------------------------------------------------------------- 17 | public: 18 | static QString generateChecksum(QByteArray& data, QCryptographicHash::Algorithm hashAlgorithm); 19 | static quint32 crc32(QByteArrayView data); 20 | }; 21 | 22 | } 23 | 24 | #endif // QX_INTEGRITY_H 25 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-iostream.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_IOSTREAM_H 2 | #define QX_IOSTREAM_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | //-Namespace Members-------------------------------------------------------------------------------------------- 13 | inline QTextStream cout = QTextStream(stdout); // QTextStream version of std::cout 14 | inline QTextStream cerr = QTextStream(stderr); // QTextStream version of std::cerr 15 | inline QTextStream cin = QTextStream(stdin); // QTextStream version of std::cin 16 | 17 | //-Namespace Functions------------------------------------------------------------------------------------------ 18 | #if defined _WIN32 || (defined __linux__ && __has_include()) 19 | QX_CORE_EXPORT void setUserInputEchoEnabled(bool enabled); 20 | #endif 21 | } 22 | 23 | #endif // QX_IOSTREAM_H 24 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-list.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_LIST_H 2 | #define QX_LIST_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Extra-component Includes 8 | #include "qx/utility/qx-concepts.h" 9 | 10 | namespace Qx 11 | { 12 | 13 | class List 14 | { 15 | //-Class Functions---------------------------------------------------------------------------------------------- 16 | public: 17 | template 18 | static QList* subListThatContains(T element, QList*> listOfLists) 19 | { 20 | // Returns pointer to the first list that contains "element". Returns nullptr if none 21 | for(QList* currentList : listOfLists) 22 | if(currentList->contains(element)) 23 | return currentList; 24 | 25 | return nullptr; 26 | } 27 | 28 | template static QList difference(QList& listA, QList& listB) 29 | { 30 | // Difference list to fill 31 | QList differenceList; 32 | 33 | for(T entry : listA) 34 | { 35 | if(!listB.contains(entry)) 36 | differenceList << entry; 37 | } 38 | return differenceList; 39 | } 40 | 41 | template 42 | requires static_castable_to 43 | QList static_pointer_cast(const QList fromList) 44 | { 45 | QList toList; 46 | toList.reserve(fromList.size()); 47 | for(F* item : std::as_const(fromList)) 48 | toList.append(static_cast(item)); 49 | 50 | return toList; 51 | } 52 | 53 | }; 54 | 55 | } 56 | 57 | #endif // QX_LIST_H 58 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-regularexpression.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_REGULAREXPRESSION_H 2 | #define QX_REGULAREXPRESSION_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | using namespace Qt::Literals::StringLiterals; 8 | 9 | namespace Qx 10 | { 11 | 12 | class RegularExpression 13 | { 14 | //-Class Variables--------------------------------------------------------------------------------------------- 15 | public: 16 | static inline const QRegularExpression HEX_ONLY = QRegularExpression(u"^[a-fA-F0-9]+$"_s, QRegularExpression::CaseInsensitiveOption); 17 | static inline const QRegularExpression ANY_NON_HEX = QRegularExpression(u"[^a-fA-F0-9 -]"_s, QRegularExpression::CaseInsensitiveOption); 18 | static inline const QRegularExpression NUMBERS_ONLY = QRegularExpression(u"^[0-9]*$"_s, QRegularExpression::CaseInsensitiveOption); // a digit (\d) 19 | static inline const QRegularExpression ALPHANUMERIC_ONLY = QRegularExpression(u"^[a-zA-Z0-9]*$"_s, QRegularExpression::CaseInsensitiveOption); 20 | static inline const QRegularExpression LETTERS_ONLY = QRegularExpression(u"^[a-zA-Z]+$"_s, QRegularExpression::CaseInsensitiveOption); 21 | static inline const QRegularExpression SEMANTIC_VERSION = QRegularExpression( 22 | u"(?P0|[1-9]\\d*)"_s 23 | u"\\."_s 24 | u"(?P0|[1-9]\\d*)"_s 25 | u"\\."_s 26 | u"(?P0|[1-9]\\d*)"_s 27 | u"(?:-(?P(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?"_s 28 | u"(?:\\+(?P[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?"_s); 29 | static inline const QRegularExpression LONG_SEMANTIC_VERSION = QRegularExpression( 30 | u"(?P0|[1-9]\\d*)"_s 31 | u"\\."_s 32 | u"(?P0|[1-9]\\d*)"_s 33 | u"\\."_s 34 | u"(?P0|[1-9]\\d*)"_s 35 | u"\\."_s 36 | u"(?P0|[1-9]\\d*)"_s 37 | u"(?:-(?P(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?"_s 38 | u"(?:\\+(?P[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?"_s); 39 | static inline const QRegularExpression LINE_BREAKS = QRegularExpression(u"[\\r\\n\\v]"_s); 40 | static inline const QRegularExpression WHITESPACE = QRegularExpression(u"[\\f\\n\\r\\t\\v\x20\xA0\x00A0\u2028\u2029]"_s); 41 | }; 42 | 43 | } 44 | 45 | #endif // QX_REGULAREXPRESSION_H 46 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-string.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_STRING_H 2 | #define QX_STRING_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | 11 | // Project Includes 12 | #include "qx/utility/qx-concepts.h" 13 | 14 | namespace Qx 15 | { 16 | 17 | class QX_CORE_EXPORT String 18 | { 19 | //-Class Functions---------------------------------------------------------------------------------------------- 20 | public: 21 | static bool isOnlyNumbers(QString checkStr); 22 | static bool isHexNumber(QString hexNum); 23 | static bool isValidChecksum(QString checksum, QCryptographicHash::Algorithm hashAlgorithm); 24 | static QString stripToHexOnly(QString string); 25 | 26 | template 27 | requires defines_call_for_s 28 | static QString join(QList list, F&& toStringFunc, QString separator = {}, QString prefix = {}) 29 | { 30 | QString conjuction; 31 | 32 | for(int i = 0; i < list.length(); ++i) 33 | { 34 | conjuction += prefix; 35 | conjuction += toStringFunc(list.at(i)); 36 | if(i < list.length() - 1) 37 | conjuction += separator; 38 | } 39 | 40 | return conjuction; 41 | } 42 | 43 | static QString join(QList list, QString separator = {}, QString prefix = {}); // Overload for T = QString 44 | 45 | template 46 | requires defines_call_for_s 47 | static QString join(QSet set, F&& toStringFunc, QString separator = {}, QString prefix = {}) 48 | { 49 | QString conjuction; 50 | 51 | typename QSet::const_iterator i = set.constBegin(); 52 | while(i != set.constEnd()) 53 | { 54 | conjuction += prefix; 55 | conjuction += toStringFunc(*i); 56 | if(++i != set.constEnd()) 57 | conjuction += separator; 58 | } 59 | 60 | return conjuction; 61 | } 62 | 63 | static QString join(QSet set, QString separator = {}, QString prefix = {}); // Overload for T = QString 64 | 65 | static QString trimLeading(const QStringView string); 66 | static QString trimTrailing(const QStringView string); 67 | 68 | static QString mapArg(QAnyStringView s, const QMap& map, Qt::CaseSensitivity cs = Qt::CaseSensitive); 69 | }; 70 | 71 | } 72 | 73 | #endif // QX_STRING_H 74 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-system.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_SYSTEM_H 2 | #define QX_SYSTEM_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #ifdef __linux 10 | #include 11 | #endif 12 | 13 | // Inner-component Includes 14 | #include "qx/core/qx-systemerror.h" 15 | 16 | namespace Qx 17 | { 18 | 19 | //-Namespace Structs------------------------------------------------------------------------------------------------------------- 20 | struct ExecuteResult 21 | { 22 | // TODO: Maybe move this and execute to a Process class/file 23 | int exitCode; 24 | QString output; 25 | }; 26 | 27 | //-Namespace Functions------------------------------------------------------------------------------------------------------------- 28 | QX_CORE_EXPORT quint32 processId(QString processName); 29 | QX_CORE_EXPORT QString processName(quint32 processId); 30 | QX_CORE_EXPORT QList processChildren(quint32 processId, bool recursive = false); 31 | 32 | QX_CORE_EXPORT bool processIsRunning(QString processName); 33 | QX_CORE_EXPORT bool processIsRunning(quint32 processId); 34 | 35 | QX_CORE_EXPORT SystemError cleanKillProcess(quint32 processId); 36 | QX_CORE_EXPORT SystemError forceKillProcess(quint32 processId); 37 | 38 | QX_CORE_EXPORT bool enforceSingleInstance(QString uniqueAppId); 39 | 40 | QX_CORE_EXPORT bool setDefaultProtocolHandler(const QString& scheme, const QString& name, const QString& path = {}, const QStringList& args = {}); 41 | QX_CORE_EXPORT bool isDefaultProtocolHandler(const QString& scheme, const QString& path = {}); 42 | QX_CORE_EXPORT bool removeDefaultProtocolHandler(const QString& scheme, const QString& path = {}); 43 | 44 | QX_CORE_EXPORT ExecuteResult execute(const QString& program, const QStringList& arguments = {}, uint timeout = 2'000); 45 | QX_CORE_EXPORT ExecuteResult shellExecute(const QString& command, const QString& arguments = {}, uint timeout = 2'000); 46 | 47 | #ifdef __linux__ 48 | // Temporary means to and end, will replace with full parser eventually 49 | QX_CORE_EXPORT QSettings::Format xdgSettingsFormat(); 50 | QX_CORE_EXPORT QSettings::Format xdgDesktopSettingsFormat(); 51 | #endif 52 | } 53 | 54 | #endif // QX_SYSTEM_H 55 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-systemerror.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_SYSTEMERROR_H 2 | #define QX_SYSTEMERROR_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Intra-component Includes 8 | #include "qx/core/qx-abstracterror.h" 9 | 10 | /*! @cond */ 11 | #ifdef _WIN32 12 | typedef long LONG; 13 | using HRESULT = LONG; 14 | using NTSTATUS = LONG; 15 | #endif 16 | /*! @endcond */ 17 | 18 | namespace Qx 19 | { 20 | 21 | class QX_CORE_EXPORT SystemError final : public AbstractError<"Qx::SystemError", 2> 22 | { 23 | //-Class Enums------------------------------------------------------------------------------------------------ 24 | public: 25 | enum OriginalFormat 26 | { 27 | Invalid, 28 | Hresult, 29 | NtStatus, 30 | Errno 31 | }; 32 | 33 | //-Class Variables------------------------------------------------------------------------------------------------ 34 | private: 35 | static inline const QString UKNOWN_CAUSE = u"An unknown error occured"_s; 36 | 37 | //-Instance Variables------------------------------------------------------------------------------------------------ 38 | private: 39 | quint32 mValue; 40 | OriginalFormat mOriginalFormat; 41 | QString mActionError; 42 | QString mCause; 43 | Severity mSeverity; 44 | 45 | //-Constructor---------------------------------------------------------------------------------------------------------- 46 | public: 47 | SystemError(); 48 | 49 | //-Class Functions-------------------------------------------------------------------------------------------- 50 | public: 51 | #ifdef _WIN32 52 | static SystemError fromHresult(HRESULT res, QString aError = u"System Error"_s); 53 | static SystemError fromNtStatus(NTSTATUS res, QString aError = u"System Error"_s); 54 | #endif 55 | 56 | #ifdef __linux__ 57 | static SystemError fromErrno(int err, QString aError = "System Error"); 58 | #endif 59 | 60 | //-Instance Functions--------------------------------------------------------------------------------------------------- 61 | private: 62 | quint32 deriveValue() const override; 63 | Severity deriveSeverity() const override; 64 | QString derivePrimary() const override; 65 | QString deriveSecondary() const override; 66 | 67 | public: 68 | bool isValid() const; 69 | OriginalFormat originalFormat() const; 70 | quint32 value() const; 71 | QString actionError() const; 72 | QString cause() const; 73 | }; 74 | 75 | } 76 | 77 | #endif // QX_SYSTEMERROR_H 78 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-systemsignalwatcher.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_SYSTEMSIGNALWATCHER_H 2 | #define QX_SYSTEMSIGNALWATCHER_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | class SystemSignalWatcherPrivate; 14 | 15 | class QX_CORE_EXPORT SystemSignalWatcher : public QObject 16 | { 17 | Q_OBJECT; 18 | Q_DECLARE_PRIVATE(SystemSignalWatcher); 19 | 20 | //-Class Enums------------------------------------------------------------------------------------------------- 21 | public: 22 | /* For now we only support signals that can be mapped cross-platform. In the future we could support more 23 | * with a doc note that the additional signals will never be received outside of Linux 24 | */ 25 | enum Signal 26 | { 27 | None = 0x0, 28 | Interrupt = 0x1, 29 | HangUp = 0x2, 30 | Quit = 0x4, 31 | Terminate = 0x8, 32 | Abort = 0x10, 33 | }; 34 | Q_DECLARE_FLAGS(Signals, Signal); 35 | 36 | 37 | //-Instance Variables------------------------------------------------------------------------------------------------- 38 | private: 39 | std::unique_ptr d_ptr; 40 | 41 | //-Constructor------------------------------------------------------------------------------------------------- 42 | public: 43 | SystemSignalWatcher(); 44 | 45 | //-Destructor------------------------------------------------------------------------------------------------- 46 | public: 47 | ~SystemSignalWatcher(); // Required for d_ptr destructor to compile 48 | 49 | //-Instance Functions-------------------------------------------------------------------------------------------- 50 | public: 51 | void watch(Signals s); 52 | void stop(); 53 | void yield(); 54 | 55 | Signals watching() const; 56 | bool isWatching() const; 57 | bool isRegistered() const; 58 | 59 | //-Signals & Slots------------------------------------------------------------------------------------------------ 60 | signals: 61 | void signaled(Signal s, bool* handled); 62 | }; 63 | Q_DECLARE_OPERATORS_FOR_FLAGS(SystemSignalWatcher::Signals); 64 | 65 | } 66 | 67 | #endif // QX_SYSTEMSIGNALWATCHER_H 68 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-threadsafesingleton.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_THREAD_SAFE_SINGLETON_H 2 | #define QX_THREAD_SAFE_SINGLETON_H 3 | 4 | // Qt Includes 5 | #include 6 | #include 7 | 8 | // Intra-component Includes 9 | #include "qx/core/qx-exclusiveaccess.h" 10 | 11 | // Extra-component Includes 12 | #include "qx/utility/qx-concepts.h" 13 | 14 | namespace Qx 15 | { 16 | 17 | template 18 | requires any_of 19 | class ThreadSafeSingleton 20 | { 21 | //-Class Members--------------------------------------------------------------------------------------------- 22 | private: 23 | // Needs to be static so it can be locked before the the singleton is created, or else a race in instance() could occur. 24 | static inline constinit Mutex smMutex; 25 | 26 | //-Constructor---------------------------------------------------------------------------------------------- 27 | protected: 28 | ThreadSafeSingleton() = default; 29 | 30 | //-Class Functions---------------------------------------------------------------------------------------------- 31 | public: 32 | static Qx::ExclusiveAccess instance() 33 | { 34 | static Singleton s; 35 | return Qx::ExclusiveAccess(&s, &smMutex); // Provides locked access to singleton, that unlocks when destroyed 36 | } 37 | }; 38 | 39 | } 40 | 41 | //-Macros---------------------------------------------------------------------------------------------------------- 42 | // Macro to be used in all derivatives 43 | #define QX_THREAD_SAFE_SINGLETON(...) friend ThreadSafeSingleton<__VA_ARGS__> 44 | 45 | #endif // QX_THREAD_SAFE_SINGLETON_H 46 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-traverser.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_STRINGTRAVERSER_H 2 | #define QX_STRINGTRAVERSER_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Extra-component Includes 8 | #include "qx/utility/qx-concepts.h" 9 | 10 | namespace Qx 11 | { 12 | 13 | template 14 | requires traverseable 15 | class Traverser 16 | { 17 | //-Instance Members---------------------------------------------------------------------------------------------------- 18 | private: 19 | typename T::const_iterator mIterator; 20 | typename T::const_iterator mStart; 21 | typename T::const_iterator mEnd; 22 | qsizetype mIndex; 23 | qsizetype mLastIndex; 24 | 25 | //-Constructor------------------------------------------------------------------------------------------------------- 26 | public: 27 | Traverser(const T& traverseable) : 28 | mIterator(traverseable.cbegin()), 29 | mStart(traverseable.cbegin()), 30 | mEnd(traverseable.cend()), 31 | mIndex(mIterator == mEnd ? -1 : 0), // -1 for empty traverseable 32 | mLastIndex(traverseable.size() - 1) 33 | {} 34 | 35 | //-Instance Functions-------------------------------------------------------------------------------------------------- 36 | public: 37 | void advance(quint32 count = 1) 38 | { 39 | // Set to end if over end, otherwise advance to target 40 | if(mIndex + count > mLastIndex) 41 | mIterator = mEnd; 42 | else 43 | { 44 | mIterator += count; 45 | mIndex += count; 46 | } 47 | } 48 | 49 | void retreat(quint32 count = 1) 50 | { 51 | // Set to beginning if before start, otherwise retreat to target 52 | if(mIndex - count < 0) 53 | mIterator = mStart; 54 | else 55 | { 56 | mIterator -= count; 57 | mIndex -= count; 58 | } 59 | } 60 | 61 | bool atEnd() const { return mIterator == mEnd; } 62 | 63 | std::iter_value_t currentValue() const { return *mIterator; } 64 | quint32 currentIndex() const { return mIndex; } 65 | 66 | std::iter_value_t lookAhead(quint32 count = 1) const 67 | { 68 | // Return default constructed object if over end, otherwise return target 69 | return (mIndex + count > mLastIndex) ? std::iter_value_t() : *(mIterator + count); 70 | } 71 | 72 | std::iter_value_t lookBehind(quint32 count = 1) const 73 | { 74 | // Return default constructed object if before start, otherwise return target 75 | return (mIndex - count < mLastIndex) ? std::iter_value_t() : *(mIterator - count); 76 | } 77 | }; 78 | 79 | typedef Traverser StringTraverser; 80 | 81 | } 82 | 83 | #endif // QX_STRINGTRAVERSER_H 84 | -------------------------------------------------------------------------------- /lib/core/include/qx/core/qx-versionnumber.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_VERSIONNUMBER_H 2 | #define QX_VERSIONNUMBER_H 3 | 4 | // Shared Lib Support 5 | #include "qx/core/qx_core_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_CORE_EXPORT VersionNumber : public QVersionNumber 14 | { 15 | //-Constructor------------------------------------------------------------------------------------------------- 16 | public: 17 | VersionNumber(int maj, int min, int mic, int nan); 18 | VersionNumber(int maj, int min, int mic); 19 | VersionNumber(int maj, int min); 20 | VersionNumber(int maj); 21 | VersionNumber(std::initializer_list args); 22 | VersionNumber(QList&& seg); 23 | VersionNumber(const QList& seg); 24 | VersionNumber(const QVersionNumber vn); 25 | VersionNumber(); 26 | 27 | //-Member Functions-------------------------------------------------------------------------------------------- 28 | public: 29 | VersionNumber first(qsizetype n) const; 30 | int nanoVersion() const; 31 | VersionNumber normalized(qsizetype min = 0) const; 32 | 33 | //-Class Functions--------------------------------------------------------------------------------------------- 34 | public: 35 | static VersionNumber commonPrefix(const VersionNumber& v1, const VersionNumber& v2); 36 | static VersionNumber fromString(const QAnyStringView& string, qsizetype* suffixIndex = nullptr); 37 | }; 38 | 39 | } 40 | 41 | #endif // QX_VERSIONNUMBER_H 42 | -------------------------------------------------------------------------------- /lib/core/src/__private/qx-generalworkerthread.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_GENERALWORKERTHREAD_H 2 | #define QX_GENERALWORKERTHREAD_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Intra-component Includes 8 | #include "qx/core/qx-threadsafesingleton.h" 9 | 10 | /*! @cond */ 11 | namespace Qx 12 | { 13 | 14 | /* A dedicated thread for Qx worker objects so that we can be sure the thread they run on is never blocked 15 | * for long periods. Automatically starts up when objects are added, and stops when the last one is removed. 16 | * 17 | * Although this is called "GeneralWorkerThread", it's more so its manager. The real thread is created 18 | * by QThread. So, this class can be called anywhere, at anytime; therefore, we make it TSS 19 | */ 20 | class GeneralWorkerThread : public ThreadSafeSingleton 21 | { 22 | QX_THREAD_SAFE_SINGLETON(GeneralWorkerThread); 23 | //-Instance Variables------------------------------------------------------------------------------------------------- 24 | private: 25 | QThread mThread; 26 | uint mWorkerCount; 27 | 28 | //-Constructor------------------------------------------------------------------------------------------------- 29 | private: 30 | GeneralWorkerThread(); 31 | 32 | //-Destructor------------------------------------------------------------------------------------------------- 33 | public: 34 | ~GeneralWorkerThread(); 35 | 36 | //-Class Functions--------------------------------------------------------------------------------------------- 37 | public: 38 | 39 | 40 | //-Instance Functions-------------------------------------------------------------------------------------------- 41 | private: 42 | void startThread(); 43 | void stopThread(bool wait = false); 44 | void workerDestroyed(); 45 | 46 | public: 47 | void moveTo(QObject* object); 48 | }; 49 | 50 | } 51 | /*! @endcond */ 52 | 53 | #endif // QX_GENERALWORKERTHREAD_H 54 | -------------------------------------------------------------------------------- /lib/core/src/__private/qx-internalerror.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/core/__private/qx-internalerror.h" 3 | 4 | /*! @cond */ 5 | namespace QxPrivate 6 | { 7 | 8 | //=============================================================================================================== 9 | // InternalError 10 | //=============================================================================================================== 11 | 12 | //-Constructor---------------------------------------------------------------------------------------------- 13 | //Public: 14 | InternalError::InternalError() : 15 | mValue(0), 16 | mSeverity(Qx::Err) 17 | {} 18 | 19 | InternalError::InternalError(Qx::Severity severity, quint32 value, const QString& primary, 20 | const QString& secondary, const QString& details , const QString& caption) : 21 | mValue(value), 22 | mSeverity(severity), 23 | mCaption(caption), 24 | mPrimary(primary), 25 | mSecondary(secondary), 26 | mDetails(details) 27 | {} 28 | 29 | //-Instance Functions---------------------------------------------------------------------------------------------- 30 | //Private: 31 | quint32 InternalError::deriveValue() const { return mValue; } 32 | Qx::Severity InternalError::deriveSeverity() const { return mSeverity; }; 33 | QString InternalError::deriveCaption() const { return mCaption; }; 34 | QString InternalError::derivePrimary() const { return mPrimary; }; 35 | QString InternalError::deriveSecondary() const { return mSecondary; }; 36 | QString InternalError::deriveDetails() const { return mDetails; }; 37 | 38 | //Public: 39 | bool InternalError::isValid() const { return mValue > 0; } 40 | 41 | quint32 InternalError::value() const { return mValue; } 42 | 43 | Qx::Severity InternalError::severity() const { return mSeverity; } 44 | 45 | QString InternalError::caption() const { return mCaption; } 46 | 47 | QString InternalError::primary() const { return mPrimary; } 48 | 49 | QString InternalError::secondary() const { return mSecondary; } 50 | 51 | QString InternalError::details() const { return mDetails; } 52 | 53 | InternalError& InternalError::setSeverity(Qx::Severity sv) { mSeverity = sv; return *this; } 54 | 55 | InternalError InternalError::withSeverity(Qx::Severity sv) 56 | { 57 | InternalError ge = *this; 58 | ge.mSeverity = sv; 59 | 60 | return ge; 61 | }; 62 | 63 | InternalError& InternalError::setCaption(const QString& caption) { mCaption = caption; return *this; } 64 | 65 | InternalError& InternalError::setPrimary(const QString& primary) { mPrimary = primary; return *this; } 66 | 67 | InternalError& InternalError::setSecondary(const QString& secondary) { mSecondary = secondary; return *this; } 68 | 69 | InternalError& InternalError::setDetails(const QString& details) { mDetails = details; return *this; } 70 | 71 | } 72 | /*! @endcond */ 73 | -------------------------------------------------------------------------------- /lib/core/src/__private/qx-processwaiter.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx-processwaiter.h" 3 | 4 | namespace Qx 5 | { 6 | /*! @cond */ 7 | 8 | //=============================================================================================================== 9 | // AbstractProcessWaiter 10 | //=============================================================================================================== 11 | 12 | //-Constructor---------------------------------------------------------------------------------------------- 13 | //Public: 14 | AbstractProcessWaiter::AbstractProcessWaiter(QObject* parent) : 15 | QObject(parent), 16 | mId(0) 17 | {} 18 | 19 | //-Instance Functions--------------------------------------------------------------------------------------------- 20 | //Private: 21 | void AbstractProcessWaiter::postDeadWait(bool died) 22 | { 23 | // Move out callback incase the callback replaces itself 24 | auto cb = std::move(mDeadWaitCallback); 25 | mDeadWaitCallback = {}; 26 | 27 | // Call 28 | cb(died); 29 | } 30 | 31 | void AbstractProcessWaiter::timerEvent(QTimerEvent* event) 32 | { 33 | Q_UNUSED(event); 34 | mDeadWaitTimer.stop(); 35 | postDeadWait(false); 36 | } 37 | 38 | //Protected: 39 | void AbstractProcessWaiter::waitForDead(std::chrono::milliseconds timeout, std::function callback) 40 | { 41 | Q_ASSERT(!mDeadWaitCallback); // Current implementation doesn't support multiple callbacks 42 | 43 | // Store callback 44 | mDeadWaitCallback = std::move(callback); 45 | 46 | // One-shot wait on dead signal 47 | connect(this, &AbstractProcessWaiter::dead, this, [this]{ 48 | if(mDeadWaitTimer.isActive()) // In case timer already expired and this was behind in queue 49 | { 50 | mDeadWaitTimer.stop(); 51 | postDeadWait(true); 52 | } 53 | }, Qt::ConnectionType(Qt::DirectConnection | Qt::SingleShotConnection)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange) 54 | mDeadWaitTimer.start(timeout, this); 55 | } 56 | 57 | //Public: 58 | void AbstractProcessWaiter::close(std::chrono::milliseconds timeout, bool force) 59 | { 60 | // If waiting happened to stop, ignore 61 | if(!isWaiting()) 62 | return; 63 | 64 | closeImpl(timeout, force); 65 | } 66 | 67 | void AbstractProcessWaiter::setId(quint32 id) { mId = id; } 68 | 69 | /*! @endcond */ 70 | } 71 | -------------------------------------------------------------------------------- /lib/core/src/__private/qx-processwaiter.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_PROCCESSWAITER_H 2 | #define QX_PROCCESSWAITER_H 3 | 4 | // Qt Includes 5 | #include 6 | #include 7 | 8 | namespace Qx 9 | { 10 | /*! @cond */ 11 | 12 | class AbstractProcessWaiter : public QObject 13 | { 14 | Q_OBJECT 15 | //-Class Members------------------------------------------------------------------------------------------ 16 | protected: 17 | static const int CLEAN_KILL_GRACE_MS = 5000; 18 | 19 | //-Instance Members------------------------------------------------------------------------------------------ 20 | protected: 21 | // Data 22 | quint32 mId; 23 | 24 | // Functional 25 | QBasicTimer mDeadWaitTimer; 26 | std::function mDeadWaitCallback; 27 | 28 | //-Constructor---------------------------------------------------------------------------------------------- 29 | public: 30 | explicit AbstractProcessWaiter(QObject* parent); 31 | 32 | //-Instance Functions---------------------------------------------------------------------------------------------- 33 | private: 34 | void postDeadWait(bool died); 35 | void timerEvent(QTimerEvent* event) override; 36 | 37 | protected: 38 | void waitForDead(std::chrono::milliseconds timeout, std::function callback); 39 | virtual void closeImpl(std::chrono::milliseconds timeout, bool force) = 0; 40 | 41 | public: 42 | virtual bool wait() = 0; 43 | virtual bool isWaiting() const = 0; 44 | void close(std::chrono::milliseconds timeout, bool force); 45 | void setId(quint32 id); 46 | 47 | //-Slots------------------------------------------------------------------------------------------------------------ 48 | protected slots: 49 | virtual void handleProcessSignaled() = 0; 50 | 51 | //-Signals------------------------------------------------------------------------------------------------------------ 52 | signals: 53 | void dead(); 54 | void closeFailed(); 55 | }; 56 | 57 | /*! @endcond */ 58 | } 59 | 60 | #endif // QX_PROCCESSWAITER_H 61 | -------------------------------------------------------------------------------- /lib/core/src/__private/qx-processwaiter_linux.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_PROCCESSBIDER_P_LINUX_H 2 | #define QX_PROCCESSBIDER_P_LINUX_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Inter-component Includes 8 | #include "qx-processwaiter.h" 9 | 10 | namespace Qx 11 | { 12 | /*! @cond */ 13 | 14 | class ProcessPollerManager; 15 | 16 | class ProcessWaiter : public AbstractProcessWaiter 17 | { 18 | Q_OBJECT 19 | 20 | //-Instance Members------------------------------------------------------------------------------------------ 21 | private: 22 | std::chrono::milliseconds mPollRate; 23 | bool mWaiting; 24 | 25 | //-Constructor---------------------------------------------------------------------------------------------- 26 | public: 27 | explicit ProcessWaiter(QObject* parent); 28 | 29 | //-Class Functions---------------------------------------------------------------------------------------------- 30 | private: 31 | static ProcessPollerManager* pollerManager(); 32 | 33 | //-Instance Functions---------------------------------------------------------------------------------------------- 34 | private: 35 | void closeImpl(std::chrono::milliseconds timeout, bool force) override; 36 | 37 | public: 38 | quint32 id() const; 39 | void setPollRate(std::chrono::milliseconds rate); 40 | std::chrono::milliseconds pollRate() const; 41 | bool wait() override; 42 | bool isWaiting() const override; 43 | 44 | //-Slots------------------------------------------------------------------------------------------------------------ 45 | public slots: 46 | void handleProcessSignaled() override; 47 | }; 48 | 49 | /*! @endcond */ 50 | } 51 | 52 | #endif // QX_PROCCESSBIDER_P_LINUX_H 53 | -------------------------------------------------------------------------------- /lib/core/src/__private/qx-processwaiter_win.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_PROCCESSBIDER_P_WIN_H 2 | #define QX_PROCCESSBIDER_P_WIN_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Inter-component Includes 8 | #include "qx-processwaiter.h" 9 | 10 | /*! @cond */ 11 | 12 | typedef void* HANDLE; 13 | typedef unsigned char BOOLEAN; 14 | #define CALLBACK __stdcall 15 | 16 | namespace Qx 17 | { 18 | 19 | /* It's critical in the design of this that these objects are never destroyed (more specifically, never completely destroyed, so 20 | * cleanup in destructor is fine) while they have a registered wait */ 21 | class ProcessWaiter : public AbstractProcessWaiter 22 | { 23 | Q_OBJECT 24 | //-Instance Members------------------------------------------------------------------------------------------ 25 | private: 26 | HANDLE mProcessHandle; 27 | HANDLE mWaitHandle; 28 | HANDLE mTaskKillHandle; 29 | HANDLE mAdminCloseHandle; 30 | std::function mAdminCloseCallback; 31 | bool mCleaningUp; 32 | 33 | //-Constructor---------------------------------------------------------------------------------------------- 34 | public: 35 | explicit ProcessWaiter(QObject* parent); 36 | 37 | //-Destructor---------------------------------------------------------------------------------------------- 38 | public: 39 | ~ProcessWaiter(); 40 | 41 | //-Class Functions---------------------------------------------------------------------------------------------- 42 | private: 43 | static void CALLBACK waitCallback(void* context, BOOLEAN timedOut); 44 | static void CALLBACK adminCloseNativeCallback(void* context, BOOLEAN timedOut); 45 | static bool processIsElevated(bool def); 46 | static bool processIsElevated(HANDLE pHandle, bool def); 47 | 48 | //-Instance Functions---------------------------------------------------------------------------------------------- 49 | private: 50 | void closeImpl(std::chrono::milliseconds timeout, bool force) override; 51 | void closeAdmin(bool force, std::function callback); 52 | bool startAdminClose(bool force); 53 | void cleanupAdminCloseHandles(); 54 | void cleanup(); 55 | 56 | public: 57 | bool wait() override; 58 | bool isWaiting() const override; 59 | 60 | //-Slots------------------------------------------------------------------------------------------------------------ 61 | public slots: 62 | void handleProcessSignaled() override; 63 | void handleAdminCloseFinsihed(bool timeout); 64 | }; 65 | 66 | } 67 | 68 | /*! @endcond */ 69 | 70 | #endif // QX_PROCCESSBIDER_P_WIN_H 71 | -------------------------------------------------------------------------------- /lib/core/src/__private/qx-signaldaemon.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_SIGNALDAEMON_H 2 | #define QX_SIGNALDAEMON_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Inter-component Includes 8 | #include "qx/core/qx-systemsignalwatcher.h" 9 | 10 | /*! @cond */ 11 | namespace Qx 12 | { 13 | 14 | class AbstractSignalDaemon 15 | { 16 | //-Aliases-------------------------------------------------------------------------------------------------- 17 | protected: 18 | using Signal = SystemSignalWatcher::Signal; 19 | 20 | //-Instance Functions-------------------------------------------------------------------------------------------- 21 | public: 22 | virtual void addSignal(Signal signal) = 0; 23 | virtual void removeSignal(Signal signal) = 0; 24 | virtual void callDefaultHandler(Signal signal) = 0; 25 | }; 26 | 27 | } 28 | /*! @endcond */ 29 | 30 | #endif // QX_SIGNALDAEMON_H 31 | -------------------------------------------------------------------------------- /lib/core/src/__private/qx-signaldaemon_linux.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_SIGNALDAEMON_LINUX_H 2 | #define QX_SIGNALDAEMON_LINUX_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Inter-component Includes 8 | #include "qx-signaldaemon.h" 9 | #include "qx/core/qx-bimap.h" 10 | 11 | // System Includes 12 | #include 13 | 14 | /*! @cond */ 15 | class QSocketNotifier; 16 | 17 | namespace Qx 18 | { 19 | 20 | /* Can't use thread-safe singleton with this without resorting to the somewhat costly QRecursiveMutex as 21 | * the class gets reentered by the same thread while locked; however we get around that and the need for 22 | * manual mutex since with a trick in processNativeSignal. 23 | */ 24 | class SignalDaemon : public AbstractSignalDaemon 25 | { 26 | //-Class Variables------------------------------------------------------------------------------------------------- 27 | private: 28 | static inline const Bimap SIGNAL_MAP{ 29 | {Signal::HangUp, SIGHUP}, 30 | {Signal::Interrupt, SIGINT}, 31 | {Signal::Terminate, SIGTERM}, 32 | {Signal::Quit, SIGQUIT}, 33 | {Signal::Abort, SIGABRT}, 34 | }; 35 | 36 | // Process local sockets for escaping the signal handler 37 | static inline int smHandlerFds[2] = {0, 0}; 38 | 39 | //-Instance Variables------------------------------------------------------------------------------------------------- 40 | private: 41 | QSocketNotifier* mNotifier; 42 | QSet mActiveSigs; 43 | 44 | //-Destructor------------------------------------------------------------------------------------------------- 45 | public: 46 | ~SignalDaemon(); 47 | 48 | //-Class Functions---------------------------------------------------------------------------------------------- 49 | private: 50 | static void handler(int signal); 51 | 52 | public: 53 | static SignalDaemon* instance(); 54 | 55 | //-Instance Functions-------------------------------------------------------------------------------------------- 56 | private: 57 | void installHandler(int sig); 58 | void restoreDefaultHandler(int sig); 59 | void startupNotifier(); 60 | void shutdownNotifier(); 61 | 62 | public: 63 | void addSignal(Signal signal) override; 64 | void removeSignal(Signal signal) override; 65 | void callDefaultHandler(Signal signal) override; 66 | 67 | void processNativeSignal(int sig) const; 68 | }; 69 | 70 | } 71 | /*! @endcond */ 72 | 73 | #endif // QX_SIGNALDAEMON_LINUX_H 74 | -------------------------------------------------------------------------------- /lib/core/src/__private/qx-signaldaemon_win.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_SIGNALDAEMON_WIN_H 2 | #define QX_SIGNALDAEMON_WIN_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Inter-component Includes 8 | #include "__private/qx-signaldaemon.h" 9 | #include "qx/core/qx-bimap.h" 10 | 11 | // Windows Includes 12 | #define WIN32_LEAN_AND_MEAN 13 | #include "windows.h" 14 | 15 | /*! @cond */ 16 | namespace Qx 17 | { 18 | 19 | /* Can't use thread-safe singleton with this without resorting to the somewhat costly QRecursiveMutex as 20 | * the class gets reentered by the same thread while locked; however we get around that and the need for 21 | * manual mutex since with a trick in processNativeSignal. 22 | */ 23 | class SignalDaemon : public AbstractSignalDaemon 24 | { 25 | //-Class Variables------------------------------------------------------------------------------------------------- 26 | private: 27 | static inline const Bimap SIGNAL_MAP{ 28 | {Signal::HangUp, CTRL_CLOSE_EVENT}, 29 | {Signal::Interrupt, CTRL_C_EVENT}, 30 | {Signal::Terminate, CTRL_SHUTDOWN_EVENT}, 31 | {Signal::Quit, CTRL_BREAK_EVENT}, 32 | {Signal::Abort, CTRL_LOGOFF_EVENT}, 33 | }; 34 | 35 | //-Instance Variables------------------------------------------------------------------------------------------------- 36 | private: 37 | QSet mActiveCtrlTypes; 38 | 39 | //-Destructor------------------------------------------------------------------------------------------------- 40 | public: 41 | ~SignalDaemon(); 42 | 43 | //-Class Functions---------------------------------------------------------------------------------------------- 44 | private: 45 | static BOOL handler(DWORD dwCtrlType); 46 | 47 | public: 48 | static SignalDaemon* instance(); 49 | 50 | //-Instance Functions-------------------------------------------------------------------------------------------- 51 | private: 52 | void installHandler(); 53 | void removeHandler(); 54 | 55 | public: 56 | void addSignal(Signal signal) override; 57 | void removeSignal(Signal signal) override; 58 | void callDefaultHandler(Signal signal) override; 59 | 60 | bool processNativeSignal(DWORD dwCtrlType) const; 61 | }; 62 | 63 | } 64 | /*! @endcond */ 65 | 66 | #endif // QX_SIGNALDAEMON_WIN_H 67 | -------------------------------------------------------------------------------- /lib/core/src/qx-array.dox: -------------------------------------------------------------------------------- 1 | namespace Qx 2 | { 3 | //=============================================================================================================== 4 | // Array 5 | //=============================================================================================================== 6 | 7 | /*! 8 | * @class Array qx/core/qx-array.h 9 | * @ingroup qx-core 10 | * 11 | * @brief The Array class is a collection of static functions pertaining to C-style arrays. 12 | */ 13 | 14 | //-Class Functions---------------------------------------------------------------------------------------------- 15 | //Public: 16 | /*! 17 | * @fn int Array::constDim(T(&)[N]) 18 | * 19 | * Returns the size of the given statically-sized array; therefore, this only works for arrays who's size are 20 | * determined at compile time. 21 | */ 22 | 23 | /*! 24 | * @fn int Array::indexOf(T(&array) [N], T query) 25 | * 26 | * Finds and returns the position of @a query within @a array, or -1 if it could not be found. 27 | */ 28 | 29 | /*! 30 | * @fn T Array::maxOf(T(&array) [N]) 31 | * 32 | * Returns the highest value in @a array. 33 | */ 34 | 35 | /*! 36 | * @fn T Array::minOf(T(&array) [N]) 37 | * 38 | * Returns the lowest value in @a array. 39 | */ 40 | 41 | /*! 42 | * @fn T Array::mostFrequent(T(&array) [N]) 43 | * 44 | * Returns the most frequently occurring value of @a array. 45 | */ 46 | } 47 | -------------------------------------------------------------------------------- /lib/core/src/qx-bytearray.dox: -------------------------------------------------------------------------------- 1 | namespace Qx 2 | { 3 | //=============================================================================================================== 4 | // ByteArray 5 | //=============================================================================================================== 6 | 7 | /*! 8 | * @class ByteArray qx/core/qx-bytearray.h 9 | * @ingroup qx-core 10 | * 11 | * @brief The ByteArray class is a collection of static functions pertaining to QByteArray. 12 | */ 13 | 14 | //-Class Functions---------------------------------------------------------------------------------------------- 15 | //Public: 16 | /*! 17 | * @fn QByteArray ByteArray::fromPrimitive(T primitive, QSysInfo::Endian endianness = QSysInfo::ByteOrder) 18 | * 19 | * Creates a byte array from the integer value @a primitive, using @a endianness byte-ordering if @a T requires 20 | * multiple bytes to store, and returns it. 21 | * 22 | * @note The exact representation for floating-point types depends on the underlying system, but most often 23 | * the IEEE-754 standard is used. 24 | */ 25 | 26 | /*! 27 | * @fn QByteArray ByteArray::fromPrimitive(bool primitive, QSysInfo::Endian endianness) 28 | * @overload 29 | * 30 | * Template specialization of the above for T == bool. 31 | * 32 | * Returns a byte array consisting of the single byte @c 0x01 or @c 0x00 for @c true and @c false respectively. 33 | * 34 | * @a endianness is ignored. 35 | */ 36 | 37 | /*! 38 | * @fn T ByteArray::toPrimitive(QByteArray ba, QSysInfo::Endian endianness = QSysInfo::ByteOrder) 39 | * 40 | * Returns the raw binary data in @a ba reinterpreted as fundamental type @a T, according to the byte-order 41 | * specified by @a endianness for multi-byte values. 42 | * 43 | * If the requested type is not large enough to store the reinterpreted contents of @a ba, the conversion will 44 | * be performed on the first n-bytes that will fit instead. 45 | * 46 | * If the requested type is stored using more bytes than are present within @a ba, the conversion will be 47 | * performed as if @a ba was padded with zeros to reach that size, in accordance with @a endianness, 48 | * 49 | * @note When T == bool, this function will return @c false if the first byte of @a ba is zero, or 50 | * @c true if it is any other value. 51 | * 52 | * @note The exact interpretation for floating-point types depends on the underlying system, but most often 53 | * the IEEE-754 standard is used. 54 | */ 55 | } 56 | -------------------------------------------------------------------------------- /lib/core/src/qx-char.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/core/qx-char.h" 3 | 4 | // Intra-component Includes 5 | #include "qx/core/qx-regularexpression.h" 6 | 7 | // Standard Library Includes 8 | #include 9 | #include 10 | 11 | namespace Qx 12 | { 13 | 14 | //=============================================================================================================== 15 | // Char 16 | //=============================================================================================================== 17 | /*! 18 | * @class Char qx/core/qx-char.h 19 | * @ingroup qx-core 20 | * 21 | * @brief The Char class is a collection of static functions pertaining to character types 22 | */ 23 | 24 | //-Class Functions----------------------------------------------------------------------------------------------- 25 | //Public: 26 | /*! 27 | * Returns @c true if @a hexNum is a numeric digit, or a letter A through F (case-insensitive); 28 | * otherwise returns @c false. 29 | */ 30 | bool Char::isHexNumber(QChar hexNum) { return RegularExpression::HEX_ONLY.match(hexNum).hasMatch(); } 31 | 32 | /*! 33 | * Returns @c true if @a ch is a whitespace character as classified by the current locale; otherwise, 34 | * returns @c false. 35 | * 36 | * This function, along with its overloads provide a standard interface through which to check if a 37 | * character is a whitespace character, which can be useful for templates. 38 | */ 39 | bool Char::isSpace(char ch) { return static_cast(std::isspace(ch)); } 40 | 41 | /*! 42 | * @overload 43 | */ 44 | bool Char::isSpace(const QChar& ch) { return ch.isSpace(); } 45 | 46 | /*! 47 | * @overload 48 | */ 49 | bool Char::isSpace(signed char ch) { return static_cast(std::isspace(ch)); } 50 | 51 | /*! 52 | * @overload 53 | */ 54 | bool Char::isSpace(unsigned char ch) { return std::isspace(ch); } 55 | 56 | /*! 57 | * @overload 58 | */ 59 | bool Char::isSpace(wchar_t ch) { return std::iswspace(ch); } 60 | 61 | /*! 62 | * Compares cOne with cTwo and returns an integer less than, equal to, or greater than zero if cOne is less than, equal to, 63 | * or greater than cTwo. 64 | * 65 | * If cs is Qt::CaseSensitive, the comparison is case sensitive; otherwise the comparison is case insensitive. 66 | * 67 | * Case sensitive comparison is based exclusively on the numeric Unicode values of the characters and is very fast, 68 | * but is not always what a human would expect. 69 | */ 70 | int Char::compare(QChar cOne, QChar cTwo, Qt::CaseSensitivity cs) 71 | { 72 | // Equalize case if case-insensitive 73 | if(cs == Qt::CaseInsensitive) 74 | { 75 | cOne = cOne.toCaseFolded(); 76 | cTwo = cTwo.toCaseFolded(); 77 | } 78 | 79 | return cOne.unicode() - cTwo.unicode(); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /lib/core/src/qx-global.cpp: -------------------------------------------------------------------------------- 1 | // Unit Include 2 | #include "qx/core/qx-global.h" 3 | 4 | // Qt Includes 5 | #include 6 | 7 | using namespace Qt::Literals::StringLiterals; 8 | 9 | namespace Qx 10 | { 11 | //-Namespace Enums---------------------------------------------------------------------------------------------- 12 | /*! 13 | * @enum Severity 14 | * 15 | * This enum represents the the severity of an error/outcome. 16 | * 17 | * @var Severity Warning 18 | * A warning. 19 | * 20 | * @var Severity Err 21 | * An error. 22 | * 23 | * @var Severity Critical 24 | * A critical/fatal error. 25 | */ 26 | 27 | /*! 28 | * @enum Extent 29 | * 30 | * Used to refer the extents of a range. 31 | * 32 | * @var Extent First 33 | * The beginning of a range, or its first unit. 34 | * 35 | * @var Extent Start 36 | * Equivalent to First. 37 | * 38 | * @var Extent Last 39 | * The end of a range, or its last unit. 40 | * 41 | * @var Extent End 42 | * Equivalent to Last. 43 | */ 44 | 45 | //-Namespace Functions----------------------------------------------------------------------------------------------------------- 46 | /*! 47 | * Returns the string representation of @a sv. 48 | * 49 | * If @a uc is set to @c true, the returned string is entirely in uppercase. 50 | */ 51 | QString severityString(Severity sv, bool uc) 52 | { 53 | static const QHash SEVERITY_STRING_MAP{ 54 | {Severity::Warning, u"Warning"_s}, 55 | {Severity::Err, u"Error"_s}, 56 | {Severity::Critical, u"Critical"_s}, 57 | }; 58 | 59 | const QString str = SEVERITY_STRING_MAP.value(sv); 60 | return uc? str.toUpper() : str; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /lib/core/src/qx-integrity.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/core/qx-integrity.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // Integrity 9 | //=============================================================================================================== 10 | 11 | /*! 12 | * @class Integrity qx/core/qx-integrity.h 13 | * @ingroup qx-core 14 | * 15 | * @brief The Integrity class is a collection of static functions pertaining to data completeness 16 | */ 17 | 18 | //-Class Functions--------------------------------------------------------------------------------------------- 19 | //Public: 20 | 21 | /*! 22 | * Computes the checksum of @a data using @a hashAlgorithm and returns it as a hexadecimal string. 23 | */ 24 | QString Integrity::generateChecksum(QByteArray& data, QCryptographicHash::Algorithm hashAlgorithm) 25 | { 26 | QCryptographicHash checksumHash(hashAlgorithm); 27 | checksumHash.addData(data); 28 | return QString::fromLatin1(checksumHash.result().toHex()); 29 | } 30 | 31 | /*! 32 | * Returns the ISO 3309/ITU-T V.42 compliant CRC-32 checksum of @a data. 33 | * 34 | * @note This function will return @c 0 if @a data is empty. 35 | */ 36 | quint32 Integrity::crc32(QByteArrayView data) 37 | { 38 | if(data.isEmpty()) 39 | return 0; 40 | 41 | // LSB-first implementation 42 | static constexpr quint32 lsbPolynomial = 0xEDB88320; 43 | 44 | uint32_t crc = 0xFFFFFFFF; 45 | 46 | for(quint8 byte : data) 47 | { 48 | crc ^= byte; 49 | for(size_t bit = 8; bit > 0; bit--) 50 | crc = crc & 1 ? (crc >> 1) ^ lsbPolynomial : crc >> 1; 51 | } 52 | 53 | // Return compliment 54 | return ~crc; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /lib/core/src/qx-iostream.dox: -------------------------------------------------------------------------------- 1 | namespace Qx 2 | { 3 | 4 | //-Namespace Members-------------------------------------------------------------------------------------------- 5 | /*! 6 | * @var QTextStream cout 7 | * 8 | * QTextStream equivalent of std::cout. 9 | */ 10 | 11 | /*! 12 | * @var QTextStream cerr 13 | * 14 | * QTextStream equivalent of std::cerr. 15 | */ 16 | 17 | /*! 18 | * @var QTextStream cin 19 | * 20 | * QTextStream equivalent of std::cin. 21 | */ 22 | 23 | //-Namespace Functions------------------------------------------------------------------------------------------ 24 | /*! @fn void setUserInputEchoEnabled(bool enabled) 25 | * 26 | * This function only pertains to console applications. 27 | * 28 | * Enables or disables the echoing of user input (stdin) to the console depending on the value 29 | * of @a enabled. 30 | * 31 | * By default echoing is enabled. 32 | * 33 | * @note On Linux this function is only available on systems that utilize the 'termios' terminal interface. 34 | */ 35 | 36 | } 37 | -------------------------------------------------------------------------------- /lib/core/src/qx-iostream_linux.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/core/qx-iostream.h" 3 | 4 | // System Includes 5 | #if __has_include() 6 | #include 7 | #endif 8 | 9 | namespace Qx 10 | { 11 | 12 | //-Namespace Functions------------------------------------------------------------------------------------------ 13 | #if __has_include() 14 | void setUserInputEchoEnabled(bool enabled) 15 | { 16 | termios ts; 17 | int stdinFileno = fileno(stdin); 18 | tcgetattr(stdinFileno, &ts); 19 | 20 | if(enabled) 21 | ts.c_lflag |= ECHO; 22 | else 23 | ts.c_lflag &= ~ECHO; 24 | 25 | tcsetattr(stdinFileno, TCSANOW, &ts); 26 | } 27 | #endif 28 | 29 | } 30 | -------------------------------------------------------------------------------- /lib/core/src/qx-iostream_win.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/core/qx-iostream.h" 3 | 4 | // Windows Includes 5 | #define WIN32_LEAN_AND_MEAN 6 | #include 7 | 8 | namespace Qx 9 | { 10 | 11 | //-Namespace Functions------------------------------------------------------------------------------------------ 12 | void setUserInputEchoEnabled(bool enabled) 13 | { 14 | HANDLE stdinHandle; 15 | DWORD consoleMode; 16 | 17 | stdinHandle = GetStdHandle(STD_INPUT_HANDLE); 18 | if(GetConsoleMode(stdinHandle, &consoleMode)) 19 | { 20 | if(enabled) 21 | consoleMode |= ENABLE_ECHO_INPUT; 22 | else 23 | consoleMode &= ~ENABLE_ECHO_INPUT; 24 | 25 | SetConsoleMode(stdinHandle, consoleMode); 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /lib/core/src/qx-json_p.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx-json_p.h" 3 | 4 | // Qt Includes 5 | #include 6 | #include 7 | 8 | namespace Qx 9 | { 10 | /*! @cond */ 11 | 12 | void recursiveValueFinder(QList& hits, QJsonValue currentValue, QStringView key) 13 | { 14 | if(currentValue.isObject()) 15 | { 16 | QJsonObject obj = currentValue.toObject(); 17 | for(auto i = obj.constBegin(); i != obj.constEnd(); i++) 18 | { 19 | if(i.key() == key) 20 | hits.append(*i); 21 | 22 | recursiveValueFinder(hits, *i, key); 23 | } 24 | } 25 | else if(currentValue.isArray()) 26 | { 27 | QJsonArray array = currentValue.toArray(); 28 | for(auto i = array.constBegin(); i != array.constEnd(); i++) 29 | recursiveValueFinder(hits, *i, key); 30 | } 31 | } 32 | 33 | /*! @endcond */ 34 | } 35 | -------------------------------------------------------------------------------- /lib/core/src/qx-json_p.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_JSON_P_H 2 | #define QX_JSON_P_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | namespace Qx 8 | { 9 | /*! @cond */ 10 | 11 | //-Component Private Functions-------------------------------------------------------------------- 12 | void recursiveValueFinder(QList& hits, QJsonValue currentValue, QStringView key); 13 | 14 | /*! @endcond */ 15 | } 16 | 17 | #endif // QX_JSON_P_H 18 | -------------------------------------------------------------------------------- /lib/core/src/qx-list.dox: -------------------------------------------------------------------------------- 1 | namespace Qx 2 | { 3 | //=============================================================================================================== 4 | // List 5 | //=============================================================================================================== 6 | 7 | /*! 8 | * @class List qx/core/qx-list.h 9 | * @ingroup qx-core 10 | * 11 | * @brief The List class is a collection of static functions pertaining to lists. 12 | */ 13 | 14 | //-Class Functions---------------------------------------------------------------------------------------------- 15 | //Public: 16 | /*! 17 | * @fn QList* List::subListThatContains(T element, QList*> listOfLists) 18 | * 19 | * Returns a pointer to the first list found within @a listOfLists that contains @a element, or @c nullptr if 20 | * none were found. 21 | */ 22 | 23 | /*! 24 | * @fn QList List::difference(QList& listA, QList& listB) 25 | * 26 | * Returns a new list that contains the elements of @a listA that are not present in @a listB. 27 | */ 28 | 29 | /*! 30 | * @fn QList List::static_pointer_cast(const QList fromList) 31 | * 32 | * Returns a new list with each pointer in @a fromList converted to T* using @c static_cast(F*). 33 | */ 34 | } 35 | -------------------------------------------------------------------------------- /lib/core/src/qx-regularexpression.dox: -------------------------------------------------------------------------------- 1 | namespace Qx 2 | { 3 | //=============================================================================================================== 4 | // RegularExpression 5 | //=============================================================================================================== 6 | 7 | /*! 8 | * @class RegularExpression qx/core/qx-regularexpression.h 9 | * @ingroup qx-core 10 | * 11 | * @brief The RegularExpression class is a collection of convenient regular expression statements. 12 | */ 13 | 14 | //-Class Functions---------------------------------------------------------------------------------------------- 15 | //Public: 16 | /*! 17 | * @var QRegularExpression RegularExpression::HEX_ONLY 18 | * 19 | * Matches text that only contains valid hexadecimal characters (case-insensitive). 20 | */ 21 | 22 | /*! 23 | * @var QRegularExpression RegularExpression::ANY_NON_HEX 24 | * 25 | * Matches text that contains at least a single non-hexadecimal character. 26 | */ 27 | 28 | /*! 29 | * @var QRegularExpression RegularExpression::NUMBERS_ONLY 30 | * 31 | * Matches text that only contains numeric characters. 32 | */ 33 | 34 | /*! 35 | * @var QRegularExpression RegularExpression::ALPHANUMERIC_ONLY 36 | * 37 | * Matches text that only contains Latin letters and numeric characters. 38 | */ 39 | 40 | /*! 41 | * @var QRegularExpression RegularExpression::LETTERS_ONLY 42 | * 43 | * Matches text that only contains Latin letters. 44 | */ 45 | 46 | /*! 47 | * @var QRegularExpression RegularExpression::SEMANTIC_VERSION 48 | * 49 | * Matches text that denotes a semantic version in accordance with the 50 | * Semantic Version 2.0.0 specification. 51 | * 52 | * The resulting match is valid for VersionNumber::fromString(). 53 | * 54 | * Provides the following capture groups: 55 | * @li major 56 | * @li minor 57 | * @li patch 58 | * @li prerelease 59 | * @li buildmetadata 60 | * 61 | * @note Unlike the officially recommended regular expression, this one does not use @c ^ or @c $ 62 | * so that the semantic version section of a larger string may be matched. 63 | * 64 | * @sa VersionNumber. 65 | */ 66 | 67 | /*! 68 | * @var QRegularExpression RegularExpression::LONG_SEMANTIC_VERSION 69 | * 70 | * Same as @ref SEMANTIC_VERSION except that 4 digits are expected instead of 3, with the fourth 71 | * digit corresponding to the additional capture group 'revision'. 72 | */ 73 | 74 | /*! 75 | * @var QRegularExpression RegularExpression::LINE_BREAKS 76 | * 77 | * Matches any line break character. 78 | */ 79 | 80 | /*! 81 | * @var QRegularExpression RegularExpression::WHITESPACE 82 | * 83 | * Matches any whitespace character. Specifically: 84 | * @li @c \\f 85 | * @li @c \\n 86 | * @li @c \\r 87 | * @li @c \\t 88 | * @li @c \\v 89 | * @li @c \\x20 90 | * @li @c \\xA0 91 | * @li @c \\u00A0 92 | * @li @c \\u2028 93 | * @li @c \\u2029 94 | */ 95 | } 96 | -------------------------------------------------------------------------------- /lib/core/src/qx-system_p.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_SYSTEM_P_H 2 | #define QX_SYSTEM_P_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | class QProcess; 8 | 9 | namespace Qx 10 | { 11 | /*! @cond */ 12 | 13 | //-Component Private Functions-------------------------------------------------------------------- 14 | bool registerUriSchemeHandler(const QString& scheme, const QString& name, const QString& command); 15 | bool checkUriSchemeHandler(const QString& scheme, const QString& path); 16 | bool removeUriSchemeHandler(const QString& scheme, const QString& path); 17 | 18 | void prepareShellProcess(QProcess& proc, const QString& command, const QString& arguments); 19 | 20 | /*! @endcond */ 21 | } 22 | 23 | #endif // QX_SYSTEM_P_H 24 | -------------------------------------------------------------------------------- /lib/core/src/qx-systemerror_linux.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/core/qx-systemerror.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // SystemError 9 | //=============================================================================================================== 10 | 11 | //-Class Functions-------------------------------------------------------------------------------------------- 12 | //Public: 13 | /*! 14 | * Returns a system error based on the errno value @a err and with the action error @a aError. 15 | * 16 | * The error's value is set directly to the value of @a err, while it's cause() will contain a 17 | * string representation of the value. 18 | * 19 | * @note This function is only available on Linux. 20 | */ 21 | SystemError SystemError::fromErrno(int err, QString aError) 22 | { 23 | /* TODO: Once moving to Ubuntu 22.04 LTS as a reference (and therefore using a higher version of 24 | * glibc, use strerrorname_np() to get the text name of the error number 25 | */ 26 | 27 | //NOTE: If ever used in other UNIX systems, the POSIX version of this needs to differ as noted here: 28 | // http://www.club.cc.cmu.edu/~cmccabe/blog_strerror.html 29 | char buffer[128]; // No need to initialize, GNU strerror_r() guarantees result is null terminated 30 | QString desc = QString::fromLatin1(strerror_r(err, buffer, sizeof(buffer)), -1); 31 | 32 | // Return translated error 33 | SystemError se; 34 | se.mValue = static_cast(err); 35 | se.mOriginalFormat = Hresult; 36 | se.mActionError = aError; 37 | se.mCause = desc; 38 | se.mSeverity = Err; 39 | 40 | return se; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /lib/core/src/qx-threadsafesingleton.dox: -------------------------------------------------------------------------------- 1 | namespace Qx 2 | { 3 | //=============================================================================================================== 4 | // ThreadSafeSingleton 5 | //=============================================================================================================== 6 | 7 | /*! 8 | * @class ThreadSafeSingleton qx/core/qx-threadsafesingleton.h 9 | * @ingroup qx-core 10 | * 11 | * @brief The ThreadSafeSingleton template class provides access to a static singleton instance in a thread-safe 12 | * manner. 13 | * 14 | * This class allows one to easily utilize the singleton pattern while ensuring that access to the global shared 15 | * instance remains thread-safe. This is achieved by providing basic scaffolding through a base class from which 16 | * the actual singleton should derive. The instance() method provides a mutex protected pointer to the 17 | * singleton instance via Qx::ExclusiveAccess. By declaring the final class' constructor as private, and accessing 18 | * the class through instance(), one can be certain that the instance is only ever being used by one thread at a 19 | * time. 20 | * 21 | * If code in your singleton calls external code that in turn results in instance() being called again 22 | * from within the same thread, be sure to use QRecursiveMutex when instantiating this template or else you 23 | * may cause a dead-lock. 24 | * 25 | * The following is a complete example for using Qx::ThreadSafeSingleton: 26 | * 27 | * @snippet qx-threadsafesingleton.cpp 0 28 | */ 29 | 30 | //-Constructor---------------------------------------------------------------------------------------------- 31 | //Protected: 32 | /*! 33 | * @fn ThreadSafeSingleton::ThreadSafeSingleton() 34 | * 35 | * Constructs a ThreadSafeSingleton. 36 | * 37 | * @sa instance(). 38 | */ 39 | 40 | //-Class Functions---------------------------------------------------------------------------------------------- 41 | //Public: 42 | /*! 43 | * @fn Qx::ExclusiveAccess ThreadSafeSingleton::instance() 44 | * 45 | * Returns a handle to the singleton instance. 46 | */ 47 | 48 | //-Macros---------------------------------------------------------------------------------------------------------- 49 | /*! 50 | * @def QX_THREAD_SAFE_SINGLETON(Singleton) 51 | * 52 | * This macro must be used within the class definition of any singleton that derived from this class, similar to 53 | * Q_OBJECT for classes derived from QObject. 54 | * 55 | * The argument is to be the name of the derived class itself (similar to CRTP). 56 | */ 57 | 58 | } 59 | -------------------------------------------------------------------------------- /lib/core/src/qx-traverser.dox: -------------------------------------------------------------------------------- 1 | namespace Qx 2 | { 3 | //=============================================================================================================== 4 | // Traverser 5 | //=============================================================================================================== 6 | 7 | /*! 8 | * @class Traverser qx/core/qx-traverser.h 9 | * @ingroup qx-core 10 | * 11 | * @brief The Traverser template class provides a const_iterator wrapper for an alternate approach to 12 | * iterating over a type. 13 | * 14 | * A traverser acts as an interface for iterating over a traversable type using more functional semantics 15 | * instead of directly manipulating an iterator via operators. 16 | * 17 | * Like with regular iterators, the end position of a traverser is an imaginary element one position further 18 | * than the last. 19 | */ 20 | 21 | //-Constructor---------------------------------------------------------------------------------------------- 22 | //Public: 23 | /*! 24 | * @fn Traverser::Traverser(const T& traverseable) 25 | * 26 | * Creates an traverser for iterating over @a traverseable, initialized to the beginning. 27 | */ 28 | 29 | //-Class Functions---------------------------------------------------------------------------------------------- 30 | //Public: 31 | /*! 32 | * @fn void Traverser::advance(quint32 count = 1) 33 | * 34 | * Advances the traverser @a count elements, stopping at the end if it is reached. 35 | */ 36 | 37 | /*! 38 | * @fn void Traverser::retreat(quint32 count = 1) 39 | * 40 | * Reverses the traverser @a count elements, stopping at the beginning if it is reached. 41 | */ 42 | 43 | /*! 44 | * @fn bool Traverser::atEnd() const 45 | * 46 | * Reverses @c true if the traverser is at the end of the traversable; otherwise, returns @c false. 47 | */ 48 | 49 | /*! 50 | * @fn std::iter_value_t Traverser::currentValue() const 51 | * 52 | * Returns the value at the traverser's current position. 53 | */ 54 | 55 | /*! 56 | * @fn quint32 Traverser::currentIndex() const 57 | * 58 | * Returns the traverser's current position as an index. 59 | */ 60 | 61 | /*! 62 | * @fn std::iter_value_t Traverser::lookAhead(quint32 count = 1) const 63 | * 64 | * Returns the value at the position @a count ahead of the traverser's current position if that position is 65 | * valid; otherwise returns a default-constructed value. 66 | */ 67 | 68 | /*! 69 | * @fn std::iter_value_t Traverser::lookBehind(quint32 count = 1) const 70 | * 71 | * Returns the value at the position @a count behind of the traverser's current position if that position is 72 | * valid; otherwise returns a default-constructed value. 73 | */ 74 | 75 | //-Outer Class Types---------------------------------------------------------------------------------------- 76 | /*! 77 | * @typedef StringTraverser 78 | * 79 | * A convenience synonym for @ref Qx::Traverser 80 | */ 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /lib/gui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================= Add Component ========================== 2 | qx_add_component("Gui" 3 | HEADERS_API 4 | qx-color.h 5 | IMPLEMENTATION 6 | qx-color.cpp 7 | LINKS 8 | PUBLIC 9 | ${Qt}::Core 10 | ${Qt}::Gui 11 | ) 12 | -------------------------------------------------------------------------------- /lib/gui/cmake/depends_qt: -------------------------------------------------------------------------------- 1 | Core 2 | Gui -------------------------------------------------------------------------------- /lib/gui/doc/general/gui.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @defgroup qx-gui Qx GUI 3 | * 4 | * @brief The GUI component contains implementation pertaining to OS UI integration, 2D graphics, basic imaging, 5 | * fonts, and text. 6 | * 7 | * @component{Gui,gui.h} 8 | * 9 | * This component roughly mirrors Qt GUI in terms of scope and organization. 10 | * 11 | * @todo This component is quite bare and for now exists solely to keep dependents of Qt GUI in a separate 12 | * component so that console applications don't end up with a UI dependency when using Qx Core. 13 | */ 14 | -------------------------------------------------------------------------------- /lib/gui/include/qx/gui/qx-color.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_COLOR_H 2 | #define QX_COLOR_H 3 | 4 | // Shared Lib Support 5 | #include "qx/gui/qx_gui_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_GUI_EXPORT Color 14 | { 15 | //-Class Functions---------------------------------------------------------------------------------------------- 16 | public: 17 | static QColor textFromBackground(QColor bgColor); 18 | }; 19 | 20 | } 21 | 22 | #endif // QX_COLOR_H 23 | -------------------------------------------------------------------------------- /lib/gui/src/qx-color.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/gui/qx-color.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // Color 9 | //=============================================================================================================== 10 | 11 | /*! 12 | * @class Color qx/gui/qx-color.h 13 | * @ingroup qx-gui 14 | * 15 | * @brief The Color class is a collection of static functions pertaining to colors. 16 | */ 17 | 18 | //-Class Functions----------------------------------------------------------------------------------------------- 19 | //Public: 20 | 21 | /*! 22 | * Returns a pure black or pure white, whichever is more ideal for maximum visibility when displayed on top of 23 | * @a bgColor. 24 | * 25 | * The choice is calculated according to version 2.0 of the WC3 Web Content Accessibility Guidelines. 26 | */ 27 | QColor Color::textFromBackground(QColor bgColor) 28 | { 29 | // Based on W3C recommendations, using black & white text 30 | // See: https://www.w3.org/TR/WCAG20/ and https://www.w3.org/TR/WCAG20/#relativeluminancedef 31 | double contrastThreshold = 0.179; 32 | std::function componentFunc = [](double ch) { return ch < 0.03928 ? ch/12.92 : std::pow((ch+0.055)/1.055, 2.4); }; 33 | 34 | // Ensure color is using RGB 35 | if(bgColor.spec() != QColor::Rgb) 36 | bgColor = bgColor.toRgb(); 37 | 38 | // Calculate Y709 luminance 39 | double Rc = componentFunc(bgColor.redF()); 40 | double Gc = componentFunc(bgColor.greenF()); 41 | double Bc = componentFunc(bgColor.blueF()); 42 | 43 | double L = 0.2126 * Rc + 0.7152 * Gc + 0.0722 * Bc; 44 | 45 | // Return black or white text 46 | return L > contrastThreshold ? QColorConstants::Black : QColorConstants::White; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /lib/io/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================= Add Component ========================== 2 | qx_add_component("Io" 3 | HEADERS_API 4 | qx-applicationlogger.h 5 | qx-common-io.h 6 | qx-filestreamreader.h 7 | qx-filestreamwriter.h 8 | qx-ioopreport.h 9 | qx-textpos.h 10 | qx-textquery.h 11 | qx-textstream.h 12 | qx-textstreamreader.h 13 | qx-textstreamwriter.h 14 | IMPLEMENTATION 15 | qx-applicationlogger.cpp 16 | qx-common-io.cpp 17 | qx-common-io_win.cpp 18 | qx-common-io_linux.cpp 19 | qx-common-io_p.h 20 | qx-filestreamreader.cpp 21 | qx-filestreamwriter.cpp 22 | qx-ioopreport.cpp 23 | qx-textpos.cpp 24 | qx-textquery.cpp 25 | qx-textstream.cpp 26 | qx-textstreamreader.cpp 27 | qx-textstreamwriter.cpp 28 | LINKS 29 | PUBLIC 30 | Qt::Core 31 | Qx::Core 32 | ) 33 | 34 | -------------------------------------------------------------------------------- /lib/io/cmake/depends_qt: -------------------------------------------------------------------------------- 1 | Core -------------------------------------------------------------------------------- /lib/io/cmake/depends_siblings: -------------------------------------------------------------------------------- 1 | Core -------------------------------------------------------------------------------- /lib/io/doc/general/io.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @defgroup qx-io Qx IO 3 | * 4 | * @brief The IO component implements functionality centered around reading and writing files in many capacities. 5 | * 6 | * @component{Io,io.h} 7 | * 8 | * Qx IO presents a multitude of functions and classes that are designed to simplify file IO in various contexts, 9 | * while also providing a standard operation feedback interface to improve ease of error handling. 10 | */ 11 | -------------------------------------------------------------------------------- /lib/io/doc/res/snippets/qx-applicationlogger.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | [ My Application Execution Log ] (1.0.8) : Sun Oct 9 00:53:51 2022 3 | Arguments: -i input_file.bin 4 | Events: 5 | - <00:53:51> [Main] App started 6 | - <00:53:51> [Main] CRITICAL) Bad thing happened! 7 | - <00:53:51> [Main] App closing... 8 | ---------- Execution finished prematurely (Code -1) ---------- 9 | //! [0] -------------------------------------------------------------------------------- /lib/io/include/qx/io/qx-filestreamreader.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_FILESTREAMREADER_H 2 | #define QX_FILESTREAMREADER_H 3 | 4 | // Shared Lib Support 5 | #include "qx/io/qx_io_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | 11 | // Intra-component Includes 12 | #include "qx/io/qx-ioopreport.h" 13 | 14 | // Extra-component Includes 15 | #include "qx/utility/qx-concepts.h" 16 | 17 | namespace Qx 18 | { 19 | 20 | class QX_IO_EXPORT FileStreamReader // Specialized wrapper for QDataStream 21 | { 22 | //-Class Variables------------------------------------------------------------------------------------------------ 23 | private: 24 | static inline const IoOpReport NULL_FILE_REPORT = IoOpReport(IO_OP_READ, IO_ERR_NULL, static_cast(nullptr)); 25 | 26 | //-Instance Variables------------------------------------------------------------------------------------------------ 27 | private: 28 | QFile* mFile; 29 | QDataStream mStreamReader; 30 | IoOpReport mStatus; 31 | 32 | //-Constructor------------------------------------------------------------------------------------------------------- 33 | public: 34 | FileStreamReader(); 35 | FileStreamReader(const QString& filePath); 36 | 37 | //-Destructor------------------------------------------------------------------------------------------------------- 38 | public: 39 | ~FileStreamReader(); 40 | 41 | //-Instance Functions------------------------------------------------------------------------------------------------ 42 | private: 43 | IoOpReport statusFromNative(); 44 | IoOpReport preReadErrorCheck(); 45 | void setFile(const QString& filePath); 46 | void unsetFile(); 47 | 48 | public: 49 | // Stock functions 50 | bool atEnd() const; 51 | QDataStream::ByteOrder byteOrder() const; 52 | const QFile* file() const; 53 | QDataStream::FloatingPointPrecision floatingPointPrecision() const; 54 | IoOpReport readRawData(QByteArray& data, int len); 55 | void resetStatus(); 56 | void setByteOrder(QDataStream::ByteOrder bo); 57 | void setFloatingPointPrecision(QDataStream::FloatingPointPrecision precision); 58 | IoOpReport skipRawData(int len); 59 | IoOpReport status() const; 60 | 61 | template 62 | requires defines_right_shift_for 63 | FileStreamReader& operator>>(T& d) 64 | { 65 | IoOpReport check = preReadErrorCheck(); 66 | 67 | if(!check.isFailure()) 68 | { 69 | mStreamReader >> d; 70 | mStatus = statusFromNative(); 71 | } 72 | 73 | return *this; 74 | } 75 | 76 | QString filePath() const; 77 | void setFilePath(const QString& filePath); 78 | 79 | // New functions 80 | bool hasError() const; 81 | IoOpReport openFile(); 82 | void closeFile(); 83 | bool fileIsOpen() const; 84 | }; 85 | 86 | } 87 | 88 | #endif // QX_FILESTREAMREADER_H 89 | -------------------------------------------------------------------------------- /lib/io/include/qx/io/qx-filestreamwriter.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_FILESTREAMWRITER_H 2 | #define QX_FILESTREAMWRITER_H 3 | 4 | // Shared Lib Support 5 | #include "qx/io/qx_io_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | 11 | // Intra-component Includes 12 | #include "qx/io/qx-common-io.h" 13 | 14 | namespace Qx 15 | { 16 | 17 | class QX_IO_EXPORT FileStreamWriter // Specialized wrapper for QDataStream 18 | { 19 | //-Class Variables------------------------------------------------------------------------------------------------ 20 | private: 21 | static inline const IoOpReport NULL_FILE_REPORT = IoOpReport(IO_OP_WRITE, IO_ERR_NULL, static_cast(nullptr)); 22 | 23 | //-Instance Variables------------------------------------------------------------------------------------------------ 24 | private: 25 | QFile* mFile; 26 | QDataStream mStreamWriter; 27 | WriteMode mWriteMode; 28 | WriteOptions mWriteOptions; 29 | IoOpReport mStatus; 30 | 31 | //-Constructor------------------------------------------------------------------------------------------------------- 32 | public: 33 | FileStreamWriter(WriteMode writeMode = Append, WriteOptions writeOptions = NoWriteOptions); 34 | FileStreamWriter(const QString& filePath, WriteMode writeMode = Append, WriteOptions writeOptions = NoWriteOptions); 35 | 36 | //-Destructor------------------------------------------------------------------------------------------------------- 37 | public: 38 | ~FileStreamWriter(); 39 | 40 | //-Instance Functions------------------------------------------------------------------------------------------------ 41 | private: 42 | IoOpReport statusFromNative(); 43 | IoOpReport preWriteErrorCheck(); 44 | void setFile(const QString& filePath); 45 | void unsetFile(); 46 | 47 | public: 48 | // Stock functions 49 | QDataStream::ByteOrder byteOrder() const; 50 | const QFile* file() const; 51 | QDataStream::FloatingPointPrecision floatingPointPrecision() const; 52 | void resetStatus(); 53 | void setByteOrder(QDataStream::ByteOrder bo); 54 | void setFloatingPointPrecision(QDataStream::FloatingPointPrecision precision); 55 | IoOpReport status() const; 56 | IoOpReport writeRawData(const QByteArray& data); 57 | 58 | template 59 | requires defines_left_shift_for 60 | FileStreamWriter& operator<<(T d) 61 | { 62 | IoOpReport check = preWriteErrorCheck(); 63 | 64 | if(!check.isFailure()) 65 | { 66 | mStreamWriter << d; 67 | mStatus = statusFromNative(); 68 | } 69 | 70 | return *this; 71 | } 72 | 73 | QString filePath() const; 74 | void setFilePath(const QString& filePath); 75 | 76 | // New functions 77 | bool hasError() const; 78 | IoOpReport openFile(); 79 | void closeFile(); 80 | bool fileIsOpen() const; 81 | }; 82 | 83 | } 84 | 85 | #endif // QX_FILESTREAMWRITER_H 86 | -------------------------------------------------------------------------------- /lib/io/include/qx/io/qx-textpos.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_TEXTPOS_H 2 | #define QX_TEXTPOS_H 3 | 4 | // Shared Lib Support 5 | #include "qx/io/qx_io_export.h" 6 | 7 | // Extra-component Includes 8 | #include "qx/core/qx-index.h" 9 | 10 | // TODO: This class should probably be constexpr construable, though this 11 | // would mean it cant have separate implementation files which is somewhat ugly. 12 | // probably should reconsider this once using modules. 13 | 14 | namespace Qx 15 | { 16 | 17 | class QX_IO_EXPORT TextPos 18 | { 19 | //-Instance Variables------------------------------------------------------------------------------------------------ 20 | private: 21 | Index32 mLine; 22 | Index32 mCharacter; 23 | 24 | //-Constructor------------------------------------------------------------------------------------------------------- 25 | public: 26 | TextPos(); 27 | TextPos(Extent e); 28 | TextPos(Index32 line, Index32 character); 29 | 30 | //-Instance Functions------------------------------------------------------------------------------------------------ 31 | public: 32 | Index32 line() const; 33 | Index32 character() const; 34 | void setLine(Index32 line); 35 | void setCharacter(Index32 character); 36 | bool isNull() const; 37 | 38 | bool operator==(const TextPos& other) const noexcept = default; 39 | std::strong_ordering operator<=>(const TextPos& other) const noexcept; 40 | }; 41 | 42 | } 43 | 44 | #endif // QX_TEXTPOS_H 45 | -------------------------------------------------------------------------------- /lib/io/include/qx/io/qx-textquery.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_TEXTQUERY_H 2 | #define QX_TEXTQUERY_H 3 | 4 | // Shared Lib Support 5 | #include "qx/io/qx_io_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | // Intra-component Includes 11 | #include "qx/io/qx-textpos.h" 12 | 13 | namespace Qx 14 | { 15 | 16 | class QX_IO_EXPORT TextQuery 17 | { 18 | //-Instance Variables------------------------------------------------------------------------------------------------ 19 | private: 20 | QString mString; 21 | Qt::CaseSensitivity mCaseSensitivity; 22 | TextPos mStartPos; 23 | int mHitsToSkip; 24 | int mHitLimit; 25 | bool mAllowSplit; 26 | 27 | //-Constructor------------------------------------------------------------------------------------------------------- 28 | public: 29 | TextQuery(const QString& string, Qt::CaseSensitivity cs = Qt::CaseSensitive); 30 | 31 | //-Instance Functions------------------------------------------------------------------------------------------------ 32 | public: 33 | const QString& string() const; 34 | Qt::CaseSensitivity caseSensitivity() const; 35 | TextPos startPosition() const; 36 | int hitsToSkip() const; 37 | int hitLimit() const; 38 | bool allowSplit() const; 39 | 40 | void setString(QString string); 41 | void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity); 42 | void setStartPosition(TextPos startPosition); 43 | void setHitsToSkip(int hitsToSkip); 44 | void setHitLimit(int hitLimit); 45 | void setAllowSplit(bool allowSplit); 46 | }; 47 | 48 | } 49 | 50 | #endif // QX_TEXTQUERY_H 51 | -------------------------------------------------------------------------------- /lib/io/include/qx/io/qx-textstream.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_TEXTSTREAM_H 2 | #define QX_TEXTSTREAM_H 3 | 4 | // Shared Lib Support 5 | #include "qx/io/qx_io_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | 11 | namespace Qx 12 | { 13 | 14 | class QX_IO_EXPORT TextStream : public QTextStream 15 | { 16 | //-Instance Variables------------------------------------------------------------------------------------------------ 17 | private: 18 | int mMinCharWidth = 1; 19 | QStringConverter::Encoding mLastEncoding = QStringConverter::Utf8; 20 | 21 | //-Constructor------------------------------------------------------------------------------------------------------- 22 | public: 23 | TextStream(const QByteArray& array, QIODevice::OpenMode openMode = QIODevice::ReadOnly); 24 | TextStream(QByteArray* array, QIODevice::OpenMode openMode = QIODevice::ReadWrite); 25 | TextStream(QString* string, QIODevice::OpenMode openMode = QIODevice::ReadWrite); 26 | TextStream(FILE* fileHandle, QIODevice::OpenMode openMode = QIODevice::ReadWrite); 27 | TextStream(QIODevice* device); 28 | 29 | //-Instance Functions------------------------------------------------------------------------------------------------ 30 | public: 31 | bool precedingBreak(); 32 | QString readLineWithBreak(qint64 maxlen = 0); 33 | }; 34 | 35 | } 36 | 37 | #endif // QX_TEXTSTREAM_H 38 | -------------------------------------------------------------------------------- /lib/io/src/qx-common-io_linux.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/io/qx-common-io.h" 3 | 4 | // System Includes 5 | #include 6 | 7 | namespace Qx 8 | { 9 | 10 | bool createFile(const QString& fileName) 11 | { 12 | QByteArray nativeFilename = fileName.toLocal8Bit(); 13 | /* The perms here get modified by umask such that the final perms are 14 | * '(mode & ~umask)'. Typical 'mode' perms for files in this context 15 | * are 666. 16 | */ 17 | return mknod(nativeFilename.constData(), S_IFREG|00666, 0) == 0; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /lib/io/src/qx-common-io_p.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_IO_COMMON_P_H 2 | #define QX_IO_COMMON_P_H 3 | 4 | // Qt Includes 5 | #include 6 | #include 7 | 8 | // Intra-component Includes 9 | #include "qx/io/qx-ioopreport.h" 10 | #include "qx/io/qx-common-io.h" 11 | 12 | namespace Qx 13 | { 14 | /*! @cond */ 15 | 16 | //-Component Private Enums ------------------------------------------------------------------------------------------------- 17 | enum class Existance {Exist, NotExist, Either}; 18 | 19 | //-Component Private Variables --------------------------------------------------------------------------------------------- 20 | extern const QHash FILE_DEV_ERR_MAP; 21 | extern const QHash TXT_STRM_STAT_MAP; 22 | extern const QHash DATA_STRM_STAT_MAP; 23 | 24 | //-Component Private Functions----------------------------------------------------------------------------------------------------- 25 | Existance existanceReqFromWriteOptions(WriteOptions wo); 26 | IoOpResultType parsedOpen(QFileDevice* file, QIODevice::OpenMode openMode); 27 | IoOpResultType fileCheck(const QFileInfo& fileInfo, Existance existanceRequirement); 28 | IoOpResultType directoryCheck(const QFileInfo& dirInfo); 29 | IoOpReport handlePathCreation(const QFileInfo& fileInfo, bool createPaths); 30 | IoOpReport writePrep(const QFileInfo& fileInfo, WriteOptions writeOptions); 31 | void matchAppendConditionParams(WriteMode& writeMode, TextPos& startPos); 32 | 33 | template 34 | void matchAppendConditionParams(WriteMode& writeMode, Index& startPos) 35 | { 36 | // Match append condition parameters 37 | if(startPos.isLast()) 38 | writeMode = Append; 39 | else if(writeMode == Append) 40 | startPos = Index(Last); 41 | } 42 | /*! @endcond */ 43 | } 44 | 45 | #endif // QX_IO_COMMON_P_H 46 | -------------------------------------------------------------------------------- /lib/io/src/qx-common-io_win.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/io/qx-common-io.h" 3 | 4 | // Windows Includes 5 | #define WIN32_LEAN_AND_MEAN 6 | #include "windows.h" 7 | 8 | namespace Qx 9 | { 10 | 11 | bool createFile(const QString& fileName) 12 | { 13 | HANDLE h = CreateFileW( 14 | (const wchar_t*)fileName.utf16(), 15 | 0, 16 | 0, 17 | nullptr, 18 | CREATE_NEW, 19 | FILE_ATTRIBUTE_NORMAL, 20 | nullptr 21 | ); 22 | 23 | if(h != INVALID_HANDLE_VALUE) 24 | { 25 | CloseHandle(h); 26 | return true; 27 | } 28 | else 29 | return false; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /lib/linux/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================= Add Component ========================== 2 | qx_add_component("Linux" 3 | HEADERS_API 4 | qx-desktopentry.h 5 | qx-applicationdesktopentry.h 6 | qx-linkdesktopentry.h 7 | qx-directorydesktopentry.h 8 | IMPLEMENTATION 9 | qx-desktopentry.cpp 10 | qx-applicationdesktopentry.cpp 11 | qx-linkdesktopentry.cpp 12 | qx-directorydesktopentry.cpp 13 | LINKS 14 | PUBLIC 15 | ${Qt}::Core 16 | Qx::Core 17 | Qx::Io 18 | ) 19 | -------------------------------------------------------------------------------- /lib/linux/cmake/depends_qt: -------------------------------------------------------------------------------- 1 | Core -------------------------------------------------------------------------------- /lib/linux/cmake/depends_siblings: -------------------------------------------------------------------------------- 1 | Core 2 | Io -------------------------------------------------------------------------------- /lib/linux/doc/general/linux.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @defgroup qx-linux Qx Linux 3 | * 4 | * @brief The Linux component provides functionality centered around Linux specific programming. 5 | * 6 | * @component{Linux,linux.h} 7 | * 8 | * @note This component is only available when Qx is built to target Linux 9 | * 10 | * Qx Linux contains classes and functions that generally either wrap existing Linux system functionality 11 | * into a more user friendly interface, other otherwise make various programming tasks on Linux more 12 | * convenient. 13 | */ 14 | -------------------------------------------------------------------------------- /lib/linux/include/qx/linux/qx-directorydesktopentry.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_DIRECTORY_DESKTOP_ENTRY_H 2 | #define QX_DIRECTORY_DESKTOP_ENTRY_H 3 | 4 | // Shared Lib Support 5 | #include "qx/linux/qx_linux_export.h" 6 | 7 | // Intra-component Includes 8 | #include "qx/linux/qx-desktopentry.h" 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_LINUX_EXPORT DirectoryDesktopEntry : public DesktopEntry 14 | { 15 | //-Class Members------------------------------------------------------------------------------------------------- 16 | private: 17 | static inline const QString TYPE = u"Directory"_s; 18 | static inline const QString EXTENSION = u"directory"_s; 19 | 20 | //-Constructor----------------------------------------------------------------------------------------------------- 21 | public: 22 | DirectoryDesktopEntry(); 23 | 24 | //-Instance Functions---------------------------------------------------------------------------------------------- 25 | public: 26 | QString type() const override; 27 | QString extension() const override; 28 | QString toString() const override; 29 | }; 30 | 31 | } 32 | 33 | #endif // QX_DIRECTORY_DESKTOP_ENTRY_H 34 | -------------------------------------------------------------------------------- /lib/linux/include/qx/linux/qx-linkdesktopentry.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_LINK_DESKTOP_ENTRY_H 2 | #define QX_LINK_DESKTOP_ENTRY_H 3 | 4 | // Shared Lib Support 5 | #include "qx/linux/qx_linux_export.h" 6 | 7 | // Intra-component Includes 8 | #include "qx/linux/qx-desktopentry.h" 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_LINUX_EXPORT LinkDesktopEntry : public DesktopEntry 14 | { 15 | //-Class Members------------------------------------------------------------------------------------------------- 16 | private: 17 | static inline const QString TYPE = u"Link"_s; 18 | static inline const QString EXTENSION = u"desktop"_s; 19 | 20 | //-Instance Members------------------------------------------------------------------------------------------------- 21 | private: 22 | QUrl mUrl; 23 | 24 | //-Constructor------------------------------------------------------------------------------------------------------- 25 | public: 26 | LinkDesktopEntry(); 27 | 28 | //-Instance Functions---------------------------------------------------------------------------------------------- 29 | public: 30 | QString type() const override; 31 | QString extension() const override; 32 | QString toString() const override; 33 | 34 | QUrl url(); 35 | 36 | void setUrl(const QUrl& url); 37 | }; 38 | 39 | } 40 | 41 | #endif // QX_LINK_DESKTOP_ENTRY_H 42 | -------------------------------------------------------------------------------- /lib/linux/src/qx-directorydesktopentry.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/linux/qx-directorydesktopentry.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // DirectoryDesktopEntry 9 | //=============================================================================================================== 10 | 11 | /*! 12 | * @class DirectoryDesktopEntry qx/linux/qx-directorydesktopentry.h 13 | * @ingroup qx-linux 14 | * 15 | * @brief The DirectoryDesktopEntry class represents the a Directory type desktop entry. 16 | * 17 | * @sa DesktopEntry. 18 | */ 19 | 20 | //-Constructor--------------------------------------------------------------------------------------------------- 21 | //Public: 22 | DirectoryDesktopEntry::DirectoryDesktopEntry() {} 23 | 24 | //-Instance Functions-------------------------------------------------------------------------------------------- 25 | //Public: 26 | QString DirectoryDesktopEntry::type() const { return TYPE; } 27 | QString DirectoryDesktopEntry::extension() const { return EXTENSION; } 28 | 29 | QString DirectoryDesktopEntry::toString() const 30 | { 31 | // There are no extra keys for this class 32 | return DesktopEntry::toString(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /lib/linux/src/qx-linkdesktopentry.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/linux/qx-linkdesktopentry.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // LinkDesktopEntry 9 | //=============================================================================================================== 10 | 11 | /*! 12 | * @class LinkDesktopEntry qx/linux/qx-linkdesktopentry.h 13 | * @ingroup qx-linux 14 | * 15 | * @brief The LinkDesktopEntry class represents the a Link type desktop entry. 16 | * 17 | * @sa DesktopEntry. 18 | */ 19 | 20 | //-Constructor--------------------------------------------------------------------------------------------------- 21 | //Public: 22 | /*! 23 | * Constructs an empty link desktop entry. 24 | */ 25 | LinkDesktopEntry::LinkDesktopEntry() {} 26 | 27 | //-Instance Functions-------------------------------------------------------------------------------------------- 28 | //Public: 29 | QString LinkDesktopEntry::type() const { return TYPE; } 30 | QString LinkDesktopEntry::extension() const { return EXTENSION; } 31 | 32 | QString LinkDesktopEntry::toString() const 33 | { 34 | // Get base string portion 35 | QString entryString = DesktopEntry::toString(); 36 | 37 | // Add link key/value 38 | entryString += keyValueString(u"URL"_s, mUrl.toString()) + '\n'; 39 | 40 | return entryString; 41 | } 42 | 43 | /*! 44 | * Returns the URL this entry links to. 45 | */ 46 | QUrl LinkDesktopEntry::url() { return mUrl; } 47 | 48 | /*! 49 | * Sets the URL this linked to by this entry to @a url. 50 | */ 51 | void LinkDesktopEntry::setUrl(const QUrl& url) { mUrl = url; } 52 | } 53 | -------------------------------------------------------------------------------- /lib/network/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================= Add Component ========================== 2 | qx_add_component("Network" 3 | HEADERS_API 4 | qx-networkreplyerror.h 5 | qx-downloadmanager.h 6 | qx-downloadmanagerreport.h 7 | qx-downloadopreport.h 8 | qx-downloadtask.h 9 | IMPLEMENTATION 10 | qx-networkreplyerror.cpp 11 | qx-downloadmanager.cpp 12 | qx-downloadmanagerreport.cpp 13 | qx-downloadopreport.cpp 14 | qx-downloadtask.cpp 15 | LINKS 16 | PUBLIC 17 | ${Qt}::Core 18 | ${Qt}::Network 19 | Qx::Core 20 | Qx::Io 21 | ) 22 | -------------------------------------------------------------------------------- /lib/network/cmake/depends_qt: -------------------------------------------------------------------------------- 1 | Core 2 | Network -------------------------------------------------------------------------------- /lib/network/cmake/depends_siblings: -------------------------------------------------------------------------------- 1 | Core 2 | Io -------------------------------------------------------------------------------- /lib/network/doc/general/network.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @defgroup qx-network Qx Network 3 | * 4 | * @brief The Network component further specializes and refines the TCP/IP programming APIs provided 5 | * by Qt Network. 6 | * 7 | * @component{Network,network.h} 8 | * 9 | * This component roughly mirrors Qt Network in terms of scope and organization. 10 | * 11 | * @note Qx must be built using a build of Qt with SSL support enabled in order for this component 12 | * to handle secure connections (e.g. HTTPS). 13 | * 14 | * @note It is recommended to configure Qt with @c -ssl on Linux and @c -schannel on Windows. 15 | */ 16 | -------------------------------------------------------------------------------- /lib/network/include/qx/network/qx-downloadopreport.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_DOWNLOADOPREPORT_H 2 | #define QX_DOWNLOADOPREPORT_H 3 | 4 | // Shared Lib Support 5 | #include "qx/network/qx_network_export.h" 6 | 7 | // Intra-component Includes 8 | #include "qx/network/qx-downloadtask.h" 9 | 10 | // Extra-component Includes 11 | #include "qx/core/qx-abstracterror.h" 12 | 13 | namespace Qx 14 | { 15 | 16 | class QX_NETWORK_EXPORT DownloadOpReport final : public AbstractError<"Qx::DownloadOpReport", 4> 17 | { 18 | //-Class Enums------------------------------------------------------------------------------------------------------ 19 | public: 20 | enum Result{ 21 | Completed = 0, 22 | Skipped = 1, 23 | Aborted = 2, 24 | Failed = 3, 25 | }; 26 | 27 | //-Class Members---------------------------------------------------------------------------------------------------- 28 | private: 29 | static inline const QString COMPLETE = u"The download [%1] -> [%2] did completed succesfully"_s; 30 | static inline const QString INCOMPLETE = u"The download [%1] -> [%2] did not complete"_s; 31 | static inline const QString FAILED = u"Error: %1"_s; 32 | static inline const QString ABORTED = u"Task was aborted."_s; 33 | static inline const QString SKIPPED = u"Task was skipped due to previous errors."_s; 34 | 35 | //-Instance Members--------------------------------------------------------------------------------------------------- 36 | private: 37 | Result mResult; 38 | QString mResultString; 39 | DownloadTask mTask; 40 | 41 | //-Constructor------------------------------------------------------------------------------------------------------- 42 | private: 43 | DownloadOpReport(Result result, const QString& resultStr, const DownloadTask& task); 44 | 45 | //-Class Functions------------------------------------------------------------------------------------------------ 46 | public: 47 | static DownloadOpReport completedDownload(const DownloadTask& task); 48 | static DownloadOpReport failedDownload(const DownloadTask& task, QString error); 49 | static DownloadOpReport skippedDownload(const DownloadTask& task); 50 | static DownloadOpReport abortedDownload(const DownloadTask& task); 51 | 52 | //-Instance Functions---------------------------------------------------------------------------------------------- 53 | private: 54 | quint32 deriveValue() const override; 55 | Severity deriveSeverity() const override; 56 | QString derivePrimary() const override; 57 | QString deriveSecondary() const override; 58 | 59 | public: 60 | Result result() const; 61 | QString resultString() const; 62 | DownloadTask task() const; 63 | bool wasSuccessful() const; 64 | }; 65 | 66 | } 67 | 68 | #endif // QX_DOWNLOADOPREPORT_H 69 | -------------------------------------------------------------------------------- /lib/network/include/qx/network/qx-downloadtask.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_DOWNLOADTASK_H 2 | #define QX_DOWNLOADTASK_H 3 | 4 | // Shared Lib Support 5 | #include "qx/network/qx_network_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | struct QX_NETWORK_EXPORT DownloadTask 14 | { 15 | QUrl target; 16 | QString dest; 17 | QString checksum = {}; 18 | 19 | friend QX_NETWORK_EXPORT bool operator== (const DownloadTask& lhs, const DownloadTask& rhs) noexcept = default; 20 | friend QX_NETWORK_EXPORT size_t qHash(const DownloadTask& key, size_t seed) noexcept; 21 | }; 22 | 23 | } 24 | 25 | #endif // QX_DOWNLOADTASK_H 26 | -------------------------------------------------------------------------------- /lib/network/include/qx/network/qx-networkreplyerror.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_NETWORKREPLYERROR_H 2 | #define QX_NETWORKREPLYERROR_H 3 | 4 | // Shared Lib Support 5 | #include "qx/network/qx_network_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | #include 11 | 12 | namespace Qx 13 | { 14 | 15 | class QX_NETWORK_EXPORT NetworkReplyError 16 | { 17 | //-Instance Members---------------------------------------------------------------------------------------------- 18 | private: 19 | QNetworkReply::NetworkError mErrorType; 20 | QUrl mUrl; 21 | QString mErrorText; 22 | 23 | //-Constructor--------------------------------------------------------------------------------------------------- 24 | public: 25 | NetworkReplyError(); 26 | NetworkReplyError(QNetworkReply* reply, QUrl url); 27 | 28 | //-Instance Functions-------------------------------------------------------------------------------------------- 29 | public: 30 | bool isValid(); 31 | QNetworkReply::NetworkError type(); 32 | QUrl url(); 33 | QString text(); 34 | }; 35 | 36 | } 37 | 38 | #endif // QX_NETWORKREPLYERROR_H 39 | -------------------------------------------------------------------------------- /lib/network/src/qx-downloadtask.cpp: -------------------------------------------------------------------------------- 1 | // Unit Include 2 | #include "qx/network/qx-downloadtask.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // DownloadTask 9 | //=============================================================================================================== 10 | 11 | /*! 12 | * @struct DownloadTask 13 | * @ingroup qx-network 14 | * 15 | * @brief The DownloadTask struct contains the information necessary to download a file from a URL. 16 | */ 17 | 18 | /*! 19 | * @var QUrl DownloadTask::target 20 | * 21 | * The full URL of file to download from a remote server. 22 | */ 23 | 24 | /*! 25 | * @var QString DownloadTask::dest 26 | * 27 | * The full local path to download the file to. 28 | */ 29 | 30 | /*! 31 | * @var QString DownloadTask::checksum 32 | * 33 | * An optional checksum in hexadecimal format to compare the completed file against. An empty string disables 34 | * verification. 35 | */ 36 | 37 | //-Operators---------------------------------------------------------------------------------------------------- 38 | //Public: 39 | /*! 40 | * @fn bool DownloadTask::operator==(const DownloadTask& lhs, const DownloadTask& rhs) noexcept 41 | * 42 | * Returns @c true if the target and destination of @a lhs are the same as in @a rhs; otherwise returns @c false 43 | */ 44 | 45 | //-Hashing------------------------------------------------------------------------------------------------------ 46 | /*! 47 | * Hashes the download task @a key with the initial @a seed. 48 | */ 49 | size_t qHash(const DownloadTask& key, size_t seed) noexcept 50 | { 51 | QtPrivate::QHashCombine hash; 52 | seed = hash(seed, key.target); 53 | seed = hash(seed, key.dest); 54 | seed = hash(seed, key.checksum); 55 | 56 | return seed; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /lib/network/src/qx-networkreplyerror.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/network/qx-networkreplyerror.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // NetworkReplyError 9 | //=============================================================================================================== 10 | 11 | /*! 12 | * @class NetworkReplyError qx/network/qx-networkreplyerror.h 13 | * @ingroup qx-network 14 | * 15 | * @brief The NetworkReplyError class provides a full error object for QNetworkReply, similar to other Qt 16 | * classes, that can be more convenient for processing errors than just QNetworkReply::NetworkError. 17 | */ 18 | 19 | //-Constructor--------------------------------------------------------------------------------------------------- 20 | //Public: 21 | /*! 22 | * Constructs an invalid network reply error that is equivalent to QNetworkReply::NetworkError::NoError. 23 | */ 24 | NetworkReplyError::NetworkReplyError() : 25 | mErrorType(QNetworkReply::NoError), 26 | mUrl(QUrl()), mErrorText(QString()) 27 | {} 28 | 29 | /*! 30 | * Constructs a network reply error from @a reply and @a url. 31 | */ 32 | NetworkReplyError::NetworkReplyError(QNetworkReply* reply, QUrl url) : 33 | mErrorType(reply->error()), 34 | mUrl(url), mErrorText(reply->errorString()) 35 | {} 36 | 37 | //-Instance Functions-------------------------------------------------------------------------------------------- 38 | //Public: 39 | /*! 40 | * Returns @c true if the error is valid; otherwise returns @c false. 41 | * 42 | * A network reply error is valid if its underlying type isn't QNetworkReply::NetworkError::NoError. 43 | */ 44 | bool NetworkReplyError::isValid() { return mErrorType != QNetworkReply::NetworkError::NoError; } 45 | 46 | /*! 47 | * Returns the error's underlying type. 48 | */ 49 | QNetworkReply::NetworkError NetworkReplyError::type() { return mErrorType; } 50 | 51 | /*! 52 | * Returns the URL that the error pertains to. 53 | */ 54 | QUrl NetworkReplyError::url() { return mUrl; } 55 | 56 | /*! 57 | * Returns the textual representation of the error. 58 | */ 59 | QString NetworkReplyError::text() { return mErrorText; } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /lib/utility/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================= Add Component ========================== 2 | qx_add_component("Utility" 3 | TARGET_VAR utility_target 4 | HEADERS_API 5 | qx-concepts.h 6 | qx-helpers.h 7 | qx-macros.h 8 | qx-stringliteral.h 9 | qx-typetraits.h 10 | DOC_ONLY 11 | qx-concepts.dox 12 | qx-helpers.dox 13 | qx-macros.dox 14 | qx-stringliteral.dox 15 | qx-typetraits.dox 16 | ) 17 | 18 | # Force conforming preprocessor for MSVC, required for 19 | # some macros (e.g. QX_FOR_EACH) to work 20 | if(MSVC) 21 | target_compile_options(${utility_target} INTERFACE "/Zc:preprocessor") 22 | endif() 23 | -------------------------------------------------------------------------------- /lib/utility/doc/general/utility.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @defgroup qx-utility Qx Utility 3 | * 4 | * @brief The Utility component provides functionality centered around language support and simplifying the syntax 5 | * of common programming tasks. 6 | * 7 | * @component{Utility,utility.h} 8 | * 9 | * Qx Utility largely consists of convenience functions, macros, and instances of languages features that simplify 10 | * or improve the usability of C++ or Qt themselves, such as C++20 Concepts & Constraints. 11 | */ 12 | -------------------------------------------------------------------------------- /lib/utility/doc/res/snippets/qx-stringliteral.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | #include 3 | #include 4 | 5 | template 6 | void printString() { std::cout << "The string is: " << S.value } 7 | 8 | int main() 9 | { 10 | printString<"Hello World">(); 11 | return 0; 12 | } 13 | //! [0] -------------------------------------------------------------------------------- /lib/utility/include/qx/utility/qx-macros.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_MACROS_H 2 | #define QX_MACROS_H 3 | 4 | // Helper 5 | /*! @cond */ 6 | #define __QX_MACRO_EXPAND1(...) __VA_ARGS__ 7 | #define __QX_MACRO_EXPAND2(...) __QX_MACRO_EXPAND1(__QX_MACRO_EXPAND1(__VA_ARGS__)) 8 | #define __QX_MACRO_EXPAND4(...) __QX_MACRO_EXPAND2(__QX_MACRO_EXPAND2(__VA_ARGS__)) 9 | #define __QX_MACRO_EXPAND8(...) __QX_MACRO_EXPAND4(__QX_MACRO_EXPAND4(__VA_ARGS__)) 10 | #define __QX_MACRO_EXPAND16(...) __QX_MACRO_EXPAND8(__QX_MACRO_EXPAND8(__VA_ARGS__)) 11 | #define __QX_MACRO_EXPAND32(...) __QX_MACRO_EXPAND8(__QX_MACRO_EXPAND8(__VA_ARGS__)) 12 | #define __QX_MACRO_EXPAND64(...) __QX_MACRO_EXPAND8(__QX_MACRO_EXPAND8(__VA_ARGS__)) 13 | #define __QX_MACRO_EXPAND128(...) __QX_MACRO_EXPAND8(__QX_MACRO_EXPAND8(__VA_ARGS__)) 14 | #define __QX_MACRO_EXPAND256(...) __QX_MACRO_EXPAND8(__QX_MACRO_EXPAND8(__VA_ARGS__)) 15 | #define __QX_MACRO_EVALUATE(...) __QX_MACRO_EXPAND256(__VA_ARGS__) 16 | 17 | #define __QX_MACRO_CALL () 18 | 19 | #define __QX_FOR_EACH_NEXT() __QX_FOR_EACH_APPLY_AND_ITERATE 20 | #define __QX_FOR_EACH_NEXT_DELIM() __QX_FOR_EACH_APPLY_AND_ITERATE_DELIM 21 | 22 | #define __QX_FOR_EACH_APPLY_AND_ITERATE(macro, first, ...) \ 23 | macro(first) \ 24 | __VA_OPT__(__QX_FOR_EACH_NEXT __QX_MACRO_CALL (macro, __VA_ARGS__)) 25 | 26 | #define __QX_FOR_EACH_APPLY_AND_ITERATE_DELIM(macro, first, ...) \ 27 | macro(first) \ 28 | __VA_OPT__(, __QX_FOR_EACH_NEXT_DELIM __QX_MACRO_CALL (macro, __VA_ARGS__)) 29 | /*! @endcond */ 30 | 31 | // User 32 | #define QX_SCOPED_ENUM_HASH_FUNC(T) \ 33 | inline size_t qHash(const T& t, size_t seed) { \ 34 | return ::qHash(static_cast::type>(t), seed); \ 35 | } 36 | 37 | #define QSL QStringLiteral 38 | #define QBAL QByteArrayLiteral 39 | 40 | #define QX_FOR_EACH(macro, ...) \ 41 | __VA_OPT__(__QX_MACRO_EVALUATE(__QX_FOR_EACH_APPLY_AND_ITERATE(macro, __VA_ARGS__))) 42 | 43 | #define QX_FOR_EACH_DELIM(macro, ...) \ 44 | __VA_OPT__(__QX_MACRO_EVALUATE(__QX_FOR_EACH_APPLY_AND_ITERATE_DELIM(macro, __VA_ARGS__))) 45 | 46 | #endif // QX_MACROS_H 47 | -------------------------------------------------------------------------------- /lib/utility/include/qx/utility/qx-stringliteral.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_STRINGLITERAL_H 2 | #define QX_STRINGLITERAL_H 3 | 4 | #include 5 | 6 | namespace Qx 7 | { 8 | 9 | template 10 | struct StringLiteral 11 | { 12 | //-Instance Fields--------------------------------------------------------------------------------------------------- 13 | char value[N]; 14 | 15 | //-Constructor---------------------------------------------------------------------------------------------------------- 16 | constexpr StringLiteral(const char (&str)[N]) 17 | { 18 | std::copy_n(str, N, value); 19 | } 20 | }; 21 | 22 | template 23 | struct StringLiteral16 24 | { 25 | char16_t value[N]; 26 | 27 | constexpr StringLiteral16(const char16_t (&str)[N]) 28 | { 29 | std::copy_n(str, N, value); 30 | } 31 | }; 32 | 33 | } 34 | 35 | #endif // QX_STRINGLITERAL_H 36 | -------------------------------------------------------------------------------- /lib/utility/include/qx/utility/qx-typetraits.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_TYPETRAITS_H 2 | #define QX_TYPETRAITS_H 3 | 4 | // Standard Library Includes 5 | #include 6 | 7 | namespace Qx 8 | { 9 | 10 | // Specialization 11 | template class B> 12 | struct is_specialization_of : std::false_type {}; 13 | 14 | template class B> 15 | struct is_specialization_of, B> : std::true_type {}; 16 | 17 | template class B> 18 | inline constexpr bool is_specialization_of_v = is_specialization_of::value; 19 | 20 | // Qualifiers 21 | template 22 | using target_type = std::remove_pointer_t>; 23 | 24 | } 25 | 26 | #endif // QX_TYPETRAITS_H 27 | -------------------------------------------------------------------------------- /lib/utility/src/qx-macros.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file qx-macros.h 3 | * @ingroup qx-utility 4 | * 5 | * @brief The qx-concepts header file provides a set of various object-like and function-like 6 | * macros that are designed to minimize the syntactic footprint of common tasks. 7 | */ 8 | 9 | /*! 10 | * @def QX_SCOPED_ENUM_HASH_FUNC(T) 11 | * 12 | * This function-like macro defines a qHash() overload for the provided scoped-enum type @a T. 13 | */ 14 | 15 | /*! 16 | * @def QSL 17 | * 18 | * This convenience macro is an alias for QStringLiteral. 19 | */ 20 | 21 | /*! 22 | * @def QBAL 23 | * 24 | * This convenience macro is an alias for QByteArrayLiteral. 25 | */ 26 | 27 | /*! 28 | * @def QX_FOR_EACH(macro, ...) 29 | * 30 | * This function-like macro acts like a fold expression for its variadic arguments. 31 | * It produces the result of calling the macro @a macro once for each argument that 32 | * follows. 33 | * 34 | * For example: 35 | * @code{.cpp} 36 | * #define F(x) //... 37 | * QX_FOR_EACH(F, 1, 4, 10) // -> F(1) F(4) F(10) 38 | * @endcode 39 | * 40 | * @sa QX_FOR_EACH_DELIM() 41 | */ 42 | 43 | /*! 44 | * @def QX_FOR_EACH_DELIM(macro, ...) 45 | * 46 | * Same as QX_FOR_EACH(), but a comma in placed between each resultant element. 47 | * 48 | * @code{.cpp} 49 | * #define F(x) //... 50 | * QX_FOR_EACH_DELIM(F, 1, 4, 10) // -> F(1), F(4), F(10) 51 | * @endcode 52 | */ 53 | -------------------------------------------------------------------------------- /lib/utility/src/qx-stringliteral.dox: -------------------------------------------------------------------------------- 1 | namespace Qx 2 | { 3 | //=============================================================================================================== 4 | // StringLiteral 5 | //=============================================================================================================== 6 | 7 | /*! 8 | * @struct StringLiteral qx/utility/qx-stringliteral.h 9 | * @ingroup qx-utility 10 | * 11 | * @brief The StringLiteral template struct acts as a literal class type wrapper around a C-style string 12 | * that effectively allows the string to be used as a non-type template parameter. 13 | * 14 | * @snippet qx-stringliteral.cpp 0 15 | */ 16 | 17 | //-Instance Fields--------------------------------------------------------------------------------------------- 18 | /*! 19 | * @var StringLiteral::value 20 | * 21 | * The wrapped C-Style string. 22 | */ 23 | 24 | //-Constructor------------------------------------------------------------------------------------------------- 25 | //Public: 26 | /*! 27 | * @fn StringLiteral::StringLiteral(const char (&str)[N]) 28 | * 29 | * Wraps the C-Style string @a str of length @a N. 30 | */ 31 | } 32 | -------------------------------------------------------------------------------- /lib/utility/src/qx-typetraits.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file qx-typetraits.h 3 | * @ingroup qx-utility 4 | * 5 | * @brief The qx-typetraits header file provides a library of general purpose type-traits as an extension of 6 | * the standard type-traits library. 7 | */ 8 | 9 | namespace Qx 10 | { 11 | // Specialization 12 | /*! 13 | * @struct is_specialization_of 14 | * @brief Checks whether A is a specialization of B. 15 | * @sa is_specialization_of_v 16 | * 17 | * @var is_specialization_of_v 18 | * @brief See is_specialization_of. 19 | */ 20 | 21 | // Qualifiers 22 | /*! 23 | * @typedef target_type 24 | * 25 | * Returns T with the top most reference and pointer removed so that: 26 | * - @c U& 27 | * - @c U* 28 | * - @c U*& 29 | * - @c U 30 | * 31 | * all become @c U. 32 | * 33 | * In other words, returns type U that type T "targets", unless T is already a pure type. 34 | * 35 | * Does not influence constness or other qualifiers. 36 | */ 37 | 38 | } 39 | -------------------------------------------------------------------------------- /lib/widgets/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================= Add Component ========================== 2 | qx_add_component("Widgets" 3 | HEADERS_API 4 | qx-buttongroup.h 5 | qx-common-widgets.h 6 | qx-logindialog.h 7 | qx-standarditemmodel.h 8 | qx-treeinputdialog.h 9 | IMPLEMENTATION 10 | qx-buttongroup.cpp 11 | qx-common-widgets.cpp 12 | qx-common-widgets_p.h 13 | qx-common-widgets_p.cpp 14 | qx-logindialog.cpp 15 | qx-standarditemmodel.cpp 16 | qx-treeinputdialog.cpp 17 | LINKS 18 | PUBLIC 19 | ${Qt}::Core 20 | ${Qt}::Widgets 21 | Qx::Core 22 | ) 23 | -------------------------------------------------------------------------------- /lib/widgets/cmake/depends_qt: -------------------------------------------------------------------------------- 1 | Core 2 | Widgets -------------------------------------------------------------------------------- /lib/widgets/cmake/depends_siblings: -------------------------------------------------------------------------------- 1 | Core -------------------------------------------------------------------------------- /lib/widgets/doc/general/widgets.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @defgroup qx-widgets Qx Widgets 3 | * 4 | * @brief The Widgets component provides additional UI elements and supporting functionality on top of 5 | * the set already provided by Qt Widgets. 6 | * 7 | * @component{Widgets,widgets.h} 8 | * 9 | * This component roughly mirrors Qt Widgets in terms of scope and organization. 10 | */ 11 | -------------------------------------------------------------------------------- /lib/widgets/doc/res/images/qx-common-widgets-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/lib/widgets/doc/res/images/qx-common-widgets-0.png -------------------------------------------------------------------------------- /lib/widgets/doc/res/images/qx-logindialog-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/lib/widgets/doc/res/images/qx-logindialog-0.png -------------------------------------------------------------------------------- /lib/widgets/doc/res/images/qx-treeinputdialog-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/lib/widgets/doc/res/images/qx-treeinputdialog-0.png -------------------------------------------------------------------------------- /lib/widgets/doc/res/snippets/qx-common-widgets.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | Qx::GenericError ge; 3 | ge.setErrorLevel(Qx::GenericError::Warning); 4 | ge.setCaption("Warning"); 5 | ge.setPrimaryInfo("Watch out for something!"); 6 | ge.setSecondaryInfo("Oops"); 7 | ge.setDetailedInfo("Problems"); 8 | 9 | Qx::postError(ge); 10 | //! [0] -------------------------------------------------------------------------------- /lib/widgets/include/qx/widgets/qx-buttongroup.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_BUTTONGROUP_H 2 | #define QX_BUTTONGROUP_H 3 | 4 | // Shared Lib Support 5 | #include "qx/widgets/qx_widgets_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | 11 | namespace Qx 12 | { 13 | 14 | // Just adds a property and signal 15 | class QX_WIDGETS_EXPORT ButtonGroup : public QButtonGroup 16 | { 17 | Q_OBJECT 18 | Q_PROPERTY(QAbstractButton* checkedButton READ checkedButton NOTIFY checkedButtonChanged); 19 | //-Instance Members--------------------------------------------------------------------------------------------------- 20 | private: 21 | QAbstractButton* mCheckedButton; 22 | 23 | //-Constructor------------------------------------------------------------------------------------------------------- 24 | public: 25 | explicit ButtonGroup(QObject* parent = nullptr); 26 | 27 | //-Instance Functions---------------------------------------------------------------------------------------------- 28 | private: 29 | void updateCheckedButton(); 30 | 31 | public: 32 | void addButton(QAbstractButton* button, int id = -1); 33 | void removeButton(QAbstractButton* button); 34 | 35 | //-Signals & Slots---------------------------------------------------------------------------------------------------------- 36 | signals: 37 | void checkedButtonChanged(QAbstractButton* button); 38 | }; 39 | 40 | } 41 | 42 | #endif // QX_BUTTONGROUP_H 43 | -------------------------------------------------------------------------------- /lib/widgets/include/qx/widgets/qx-common-widgets.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_WIDGETS_COMMON_H 2 | #define QX_WIDGETS_COMMON_H 3 | 4 | // Shared Lib Support 5 | #include "qx/widgets/qx_widgets_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | // Extra-component Includes 11 | #include "qx/core/qx-error.h" 12 | 13 | namespace Qx 14 | { 15 | //-Namespace Functions------------------------------------------------------------------------------------------------- 16 | QX_WIDGETS_EXPORT void postError(const Error& error); 17 | QX_WIDGETS_EXPORT int postBlockingError(const Error& error, 18 | QMessageBox::StandardButtons choices = QMessageBox::Ok, 19 | QMessageBox::StandardButton defChoice = QMessageBox::NoButton); 20 | 21 | } 22 | 23 | #endif // QX_WIDGETS_COMMON_H 24 | -------------------------------------------------------------------------------- /lib/widgets/include/qx/widgets/qx-logindialog.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_LOGINDIALOG_H 2 | #define QX_LOGINDIALOG_H 3 | 4 | // Shared Lib Support 5 | #include "qx/widgets/qx_widgets_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace Qt::Literals::StringLiterals; 14 | 15 | namespace Qx 16 | { 17 | 18 | class QX_WIDGETS_EXPORT LoginDialog : public QDialog 19 | { 20 | //-QObject Macro (Required for all QObject Derived Classes)----------------------------------------------------------- 21 | Q_OBJECT 22 | 23 | //-Class Members------------------------------------------------------------------------------------------------------- 24 | private: 25 | static inline const QString LABEL_DEF_PRMT= u"Login Required"_s; 26 | static inline const QString LABEL_USRNAME = u"&Username"_s; 27 | static inline const QString LABEL_PSSWD = u"&Password"_s; 28 | 29 | //-Instance Members--------------------------------------------------------------------------------------------------- 30 | private: 31 | QLabel* mPromptLabel; 32 | QLabel* mUsernameLabel; 33 | QLabel* mPasswordLabel; 34 | QLineEdit* mUsernameLineEdit; 35 | QLineEdit* mPasswordLineEdit; 36 | QDialogButtonBox* mButtonBox; 37 | 38 | //-Constructor------------------------------------------------------------------------------------------------------- 39 | public: 40 | explicit LoginDialog(QWidget* parent = nullptr, QString prompt = LABEL_DEF_PRMT); 41 | 42 | //-Instance Functions---------------------------------------------------------------------------------------------- 43 | public: 44 | void setPrompt(QString prompt); 45 | QString username(); 46 | QString password(); 47 | 48 | //-Slots---------------------------------------------------------------------------------------------------------- 49 | private slots: 50 | void acceptHandler(); 51 | void rejectHandler(); 52 | }; 53 | 54 | } 55 | 56 | #endif // QX_LOGINDIALOG_H 57 | -------------------------------------------------------------------------------- /lib/widgets/include/qx/widgets/qx-standarditemmodel.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_STANDARDITEMMODEL_H 2 | #define QX_STANDARDITEMMODEL_H 3 | 4 | // Shared Lib Support 5 | #include "qx/widgets/qx_widgets_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_WIDGETS_EXPORT StandardItemModel : public QStandardItemModel 14 | { 15 | //-Instance Members--------------------------------------------------------------------------------------------------- 16 | private: 17 | bool mUpdatingParentTristate = false; 18 | bool mAutoTristate = false; 19 | 20 | //-Constructor------------------------------------------------------------------------------------------------------- 21 | public: 22 | StandardItemModel(int rows, int columns, QObject* parent = nullptr); 23 | StandardItemModel(QObject* parent = nullptr); 24 | 25 | //-Instance Functions----------------------------------------------------------------------------------------------- 26 | private: 27 | void autoTristateChildren(QStandardItem* changingItem, const QVariant& value, int role); 28 | void autoTristateParents(QStandardItem* changingItem, const QVariant& changingValue); 29 | 30 | public: 31 | virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; 32 | bool isAutoTristate(); 33 | void setAutoTristate(bool autoTristate); 34 | void forEachItem(const std::function& func, QModelIndex parent = QModelIndex()) const; 35 | 36 | void selectAll(); 37 | void selectNone(); 38 | }; 39 | 40 | } 41 | 42 | #endif // QX_STANDARDITEMMODEL_H 43 | -------------------------------------------------------------------------------- /lib/widgets/include/qx/widgets/qx-treeinputdialog.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_TREEINPUTDIALOG_H 2 | #define QX_TREEINPUTDIALOG_H 3 | 4 | // Shared Lib Support 5 | #include "qx/widgets/qx_widgets_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | #include 11 | 12 | namespace Qx 13 | { 14 | 15 | class QX_WIDGETS_EXPORT TreeInputDialog : public QDialog 16 | { 17 | //-QObject Macro (Required for all QObject Derived Classes)----------------------------------------------------------- 18 | Q_OBJECT 19 | 20 | //-Instance Members--------------------------------------------------------------------------------------------------- 21 | private: 22 | QTreeView* mTreeView; 23 | QDialogButtonBox* mButtonBox; 24 | 25 | //-Constructor------------------------------------------------------------------------------------------------------- 26 | public: 27 | explicit TreeInputDialog(QWidget* parent = nullptr); 28 | 29 | //-Instance Functions---------------------------------------------------------------------------------------------- 30 | public: 31 | void setModel(QAbstractItemModel* model); 32 | 33 | //-Signals--------------------------------------------------------------------------------------------------------- 34 | signals: 35 | void selectAllClicked(); 36 | void selectNoneClicked(); 37 | }; 38 | 39 | } 40 | 41 | #endif // QX_TREEINPUTDIALOG_H 42 | -------------------------------------------------------------------------------- /lib/widgets/src/qx-buttongroup.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/widgets/qx-buttongroup.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // ButtonGroup 9 | //=============================================================================================================== 10 | 11 | /*! 12 | * @class LoginDialog qx/widgets/qx-buttongroup.h 13 | * @ingroup qx-widgets 14 | * 15 | * @brief The ButtonGroup class provides a container to organize groups of button widgets 16 | * 17 | * This class is the same as QButtonGroup, with a property and change signal for the currently checked button 18 | */ 19 | 20 | //-Constructor--------------------------------------------------------------------------------------------------- 21 | //Public: 22 | /*! 23 | * Constructs a new, empty button group with the given parent. 24 | * 25 | * @sa addButton() and setExclusive(). 26 | */ 27 | ButtonGroup::ButtonGroup(QObject* parent) : 28 | QButtonGroup(parent), 29 | mCheckedButton(nullptr) 30 | { 31 | connect(this, &QButtonGroup::buttonToggled, this, &ButtonGroup::updateCheckedButton); 32 | } 33 | 34 | //-Instance Functions-------------------------------------------------------------------------------------------- 35 | //Private: 36 | void ButtonGroup::updateCheckedButton() 37 | { 38 | auto baseChecked = QButtonGroup::checkedButton(); 39 | if(mCheckedButton != baseChecked) 40 | { 41 | mCheckedButton = baseChecked; 42 | emit checkedButtonChanged(mCheckedButton); 43 | } 44 | } 45 | 46 | //Public: 47 | /*! 48 | * Adds the given button to the button group. If id is -1, an id will be assigned to the button. 49 | * Automatically assigned ids are guaranteed to be negative, starting with -2. If you are assigning 50 | * your own ids, use positive values to avoid conflicts. 51 | * 52 | * @sa removeButton() and buttons(). 53 | */ 54 | void ButtonGroup::addButton(QAbstractButton* button, int id) 55 | { 56 | QButtonGroup::addButton(button, id); 57 | updateCheckedButton(); 58 | } 59 | 60 | /*! 61 | * Removes the given button from the button group. 62 | * 63 | * @sa addButton() and buttons(). 64 | */ 65 | void ButtonGroup::removeButton(QAbstractButton* button) 66 | { 67 | QButtonGroup::removeButton(button); 68 | updateCheckedButton(); 69 | } 70 | 71 | //-Signals & Slots--------------------------------------------------------------------------------------------- 72 | //Public Signals: 73 | /*! 74 | * @fn void ButtonGroup::checkedButtonChanged(QAbstractButton* button) 75 | * 76 | * This signal is emitted whenever the button group's checked button changes. @a button can be @c nullptr. 77 | */ 78 | 79 | } 80 | -------------------------------------------------------------------------------- /lib/widgets/src/qx-common-widgets.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/widgets/qx-common-widgets.h" 3 | #include "qx-common-widgets_p.h" 4 | 5 | /*! 6 | * @file qx-common-widgets.h 7 | * @ingroup qx-widgets 8 | * 9 | * @brief The qx-common-widgets header file provides various types, variables, and functions related to 10 | * Qt widgets. 11 | */ 12 | 13 | namespace Qx 14 | { 15 | //-Namespace Functions------------------------------------------------------------------------------------------------- 16 | 17 | /*! 18 | * Displays @a error using a QMessageBox with an @c OK button. 19 | * 20 | * As an example, this code: 21 | * @snippet qx-common-widgets.cpp 0 22 | * 23 | * results in the following message box: 24 | * 25 | * @image{inline} html qx-common-widgets-0.png 26 | * 27 | * @note This function does not block and returns immediately. The QMessageBox object is automatically deleted 28 | * after it is closed. 29 | * 30 | * @sa postBlockingError(), QTextStream& operator<<(QTextStream& ts, const Qx::Error& e). 31 | */ 32 | void postError(const Error& error) 33 | { 34 | // Prepare dialog 35 | QMessageBox* genericErrorMessage = new QMessageBox(); 36 | prepareErrorPostBox(error, *genericErrorMessage); 37 | genericErrorMessage->setStandardButtons(QMessageBox::Ok); 38 | genericErrorMessage->setDefaultButton(QMessageBox::Ok); 39 | genericErrorMessage->setAttribute(Qt::WA_DeleteOnClose); // Prevents memory leak 40 | 41 | // Show dialog 42 | genericErrorMessage->show(); 43 | } 44 | 45 | /*! 46 | * Displays @a error using a QMessageBox, blocks until it's closed, and finally returns the button that was selected. 47 | * 48 | * @param error The error to display. 49 | * @param choices The different option buttons to display. 50 | * @param defChoice The default button that is selected. 51 | * @return The value of the selected button. 52 | * 53 | * @note This function only works with QMessageBox::StandardButton, not with custom buttons. 54 | * 55 | * @sa postError(). 56 | */ 57 | int postBlockingError(const Error& error, QMessageBox::StandardButtons choices, QMessageBox::StandardButton defChoice) 58 | { 59 | // Prepare dialog 60 | QMessageBox genericErrorMessage; 61 | prepareErrorPostBox(error, genericErrorMessage); 62 | genericErrorMessage.setStandardButtons(choices); 63 | genericErrorMessage.setDefaultButton(defChoice); 64 | 65 | // Show dialog and return user response 66 | return genericErrorMessage.exec(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /lib/widgets/src/qx-common-widgets_p.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx-common-widgets_p.h" 3 | 4 | namespace Qx 5 | { 6 | /*! @cond */ 7 | void prepareErrorPostBox(const Error& error, QMessageBox& msgBox) 8 | { 9 | // Determine icon 10 | QMessageBox::Icon icon{}; // Default init to silence "uninitialized" warning 11 | 12 | switch(error.severity()) 13 | { 14 | case Severity::Warning: 15 | icon = QMessageBox::Warning; 16 | break; 17 | 18 | case Severity::Err: 19 | icon = QMessageBox::Critical; 20 | break; 21 | 22 | case Severity::Critical: 23 | icon = QMessageBox::Critical; 24 | break; 25 | default: 26 | qFatal("Unhandled error severity!"); 27 | } 28 | 29 | // Prepare dialog 30 | msgBox.setText(error.primary()); 31 | 32 | msgBox.setIcon(icon); 33 | 34 | if(!error.caption().isEmpty()) 35 | msgBox.setWindowTitle(error.caption()); 36 | if(!error.secondary().isEmpty()) 37 | msgBox.setInformativeText(error.secondary()); 38 | if(!error.details().isEmpty()) 39 | msgBox.setDetailedText(error.details()); 40 | 41 | } 42 | /*! @endcond */ 43 | } 44 | -------------------------------------------------------------------------------- /lib/widgets/src/qx-common-widgets_p.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_WIDGETS_COMMON_P_H 2 | #define QX_WIDGETS_COMMON_P_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Extra-component Includes 8 | #include "qx/core/qx-error.h" 9 | 10 | namespace Qx 11 | { 12 | /*! @cond */ 13 | void prepareErrorPostBox(const Error& error, QMessageBox& msgBox); 14 | /*! @endcond */ 15 | } 16 | 17 | 18 | #endif // QX_WIDGETS_COMMON_P_H 19 | -------------------------------------------------------------------------------- /lib/windows-gui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================= Add Component ========================== 2 | qx_add_component("Windows-gui" 3 | HEADERS_API 4 | qx-taskbarbutton.h 5 | qx-winguievent.h 6 | IMPLEMENTATION 7 | qx-taskbarbutton.cpp 8 | qx-winguievent.cpp 9 | qx-winguieventfilter_p.h 10 | qx-winguieventfilter.cpp 11 | LINKS 12 | PRIVATE 13 | Qx::Windows 14 | Qx::Core 15 | PUBLIC 16 | ${Qt}::Core 17 | ${Qt}::Gui 18 | ) 19 | -------------------------------------------------------------------------------- /lib/windows-gui/cmake/depends_qt: -------------------------------------------------------------------------------- 1 | Core 2 | Gui -------------------------------------------------------------------------------- /lib/windows-gui/cmake/depends_siblings: -------------------------------------------------------------------------------- 1 | Core 2 | Windows -------------------------------------------------------------------------------- /lib/windows-gui/doc/general/windows-gui.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @defgroup qx-windows-gui Qx Windows GUI 3 | * 4 | * @brief The Windows-gui component provides functionality centered around Windows specific GUI programming. 5 | * 6 | * @component{Windows-gui,windows-gui.h} 7 | * 8 | * @note This component is only available when Qx is built to target Windows 9 | * 10 | * Qx Windows-gui contains classes and functions that generally either wrap existing UI related Win32 API 11 | * functionality into a more user friendly interface, other otherwise make various UI related programming 12 | * tasks on Windows more convenient. 13 | */ 14 | -------------------------------------------------------------------------------- /lib/windows-gui/doc/res/images/qx-taskbarbutton-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/lib/windows-gui/doc/res/images/qx-taskbarbutton-0.png -------------------------------------------------------------------------------- /lib/windows-gui/doc/res/images/qx-taskbarbutton-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/lib/windows-gui/doc/res/images/qx-taskbarbutton-1.png -------------------------------------------------------------------------------- /lib/windows-gui/doc/res/images/qx-taskbarbutton-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/lib/windows-gui/doc/res/images/qx-taskbarbutton-2.png -------------------------------------------------------------------------------- /lib/windows-gui/doc/res/images/qx-taskbarbutton-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/lib/windows-gui/doc/res/images/qx-taskbarbutton-3.png -------------------------------------------------------------------------------- /lib/windows-gui/doc/res/images/qx-taskbarbutton-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/lib/windows-gui/doc/res/images/qx-taskbarbutton-4.png -------------------------------------------------------------------------------- /lib/windows-gui/doc/res/images/qx-taskbarbutton-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/lib/windows-gui/doc/res/images/qx-taskbarbutton-5.png -------------------------------------------------------------------------------- /lib/windows-gui/doc/res/snippets/qx-taskbarbutton.cpp: -------------------------------------------------------------------------------- 1 | //! [0] 2 | // Create a taskbar button interface 3 | TaskbarButton* button = new TaskbarButton(widget); 4 | 5 | // Connect the window to the widgets window 6 | button->setWindow(widget->windowHandle()); 7 | 8 | // Change the button's overlay icon 9 | button->setOverlayIcon(QIcon(":/loading.png")); 10 | 11 | // Change the button's progress indicator 12 | button->setProgressState(Qx::TaskbarButton::ProgressState::Normal); 13 | progress->setValue(50); 14 | //! [0] -------------------------------------------------------------------------------- /lib/windows-gui/include/qx/windows-gui/qx-winguievent.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_WINGUIEVENT_H 2 | #define QX_WINGUIEVENT_H 3 | 4 | // Shared Lib Support 5 | #include "qx/windows-gui/qx_windows-gui_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_WINDOWS_GUI_EXPORT WinGuiEvent : public QEvent 14 | { 15 | //-Class Members------------------------------------------------------------------------------------------------------ 16 | public: 17 | // Types 18 | static inline const int TaskbarButtonCreated = QEvent::registerEventType(); 19 | 20 | //-Constructor------------------------------------------------------------------------------------------------------- 21 | public: 22 | explicit WinGuiEvent(int type); 23 | }; 24 | 25 | } 26 | 27 | #endif // QX_WINGUIEVENT_H 28 | -------------------------------------------------------------------------------- /lib/windows-gui/src/qx-winguievent.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/windows-gui/qx-winguievent.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // WinGuiEvent 9 | //=============================================================================================================== 10 | 11 | /*! 12 | * @class WinGuiEvent qx/windows-gui/qx-winguievent.h 13 | * @ingroup qx-windows-gui 14 | * 15 | * @brief The WinGuiEvent class encapsulates messages that are sent directly to an application window by the 16 | * system on the Windows platform. 17 | * 18 | * @warning The filter that generates these events is not installed to an application by default due to 19 | * limitations with QCoreApplication and statically linked libraries. As such, the filter is currently only 20 | * initialized internally by Qx classes that need them, meaning these events will not be available in user 21 | * code. 22 | */ 23 | 24 | //-Class Members---------------------------------------------------------------------------------------------------- 25 | //Public: 26 | /*! 27 | * @var int WinGuiEvent::TaskbarButtonCreated 28 | * 29 | * The ID for the event that signifies a taskbar button has been created for a given window. 30 | */ 31 | 32 | //-Constructor--------------------------------------------------------------------------------------------------- 33 | //Public: 34 | /*! 35 | * Constructs a windows gui event of the given @a type. 36 | * 37 | * The type is specified by ID. 38 | */ 39 | WinGuiEvent::WinGuiEvent(int type) : 40 | QEvent(static_cast(type)) 41 | {} 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /lib/windows-gui/src/qx-winguieventfilter_p.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_WINGUIEVENTFILTER_H 2 | #define QX_WINGUIEVENTFILTER_H 3 | 4 | // Qt Includes 5 | #include 6 | #include 7 | 8 | namespace Qx 9 | { 10 | /*! @cond */ // So doxygen ignores this class 11 | 12 | // Singleton class for filtering GUI related Windows events 13 | class WinGuiEventFilter : public QAbstractNativeEventFilter 14 | { 15 | //-Class Members------------------------------------------------------------------------------------------------------ 16 | private: 17 | static inline WinGuiEventFilter* instance = nullptr; 18 | 19 | //-Instance Members--------------------------------------------------------------------------------------------------- 20 | private: 21 | unsigned int mTaskbarButtonCreatedMsgId; 22 | 23 | //-Constructor------------------------------------------------------------------------------------------------------- 24 | private: 25 | WinGuiEventFilter(); 26 | 27 | //-Class Functions--------------------------------------------------------------------------------------------------- 28 | public: 29 | static void installGlobally(); 30 | 31 | //-Instance Functions--------------------------------------------------------------------------------------------------- 32 | private: 33 | QWindow* getQtWindow(HWND nativeWindowHandle); 34 | 35 | public: 36 | bool nativeEventFilter(const QByteArray& eventType, void* message, qintptr* result) override; 37 | }; 38 | 39 | /*! @endcond */ // So doxygen ignores this class 40 | } 41 | 42 | #endif // QX_WINGUIEVENTFILTER_H 43 | -------------------------------------------------------------------------------- /lib/windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================= Add Component ========================== 2 | qx_add_component("Windows" 3 | HEADERS_API 4 | qx-common-windows.h 5 | qx-filedetails.h 6 | qx-windefs.h 7 | IMPLEMENTATION 8 | qx-common-windows.cpp 9 | qx-common-windows_p.h 10 | qx-common-windows_p.cpp 11 | qx-filedetails.cpp 12 | DOC_ONLY 13 | qx-windefs.dox 14 | LINKS 15 | PRIVATE 16 | Qx::Io 17 | PUBLIC 18 | ${Qt}::Core 19 | Version.lib 20 | Qx::Core 21 | ) 22 | -------------------------------------------------------------------------------- /lib/windows/cmake/depends_qt: -------------------------------------------------------------------------------- 1 | Core -------------------------------------------------------------------------------- /lib/windows/cmake/depends_siblings: -------------------------------------------------------------------------------- 1 | Core 2 | Io -------------------------------------------------------------------------------- /lib/windows/doc/general/qx_windows.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file qx_windows.h 3 | * @ingroup qx-windows 4 | * 5 | * @brief The qx_windows header file acts as a lightweight alias for windows.h. 6 | * 7 | * Including this header provides access to a subset of the Win32 API that consists of the most 8 | * frequently used components, and can be used as a less cumbersome drop-in replacement for windows.h 9 | * most of the time. 10 | * 11 | * It is specifically designed to avoid well-known issues that can arise when simply including 12 | * windows.h, such as non-portable definitions of @c min and @c max. 13 | * 14 | * Generally, any specific Windows API headers that are not included by this one can simply be 15 | * included afterwards to keep bloat to a minimum. 16 | * 17 | * @warning This header will not work if you need to use Windows GDI+ due to their reliance on 18 | * Microsoft's definition of @c min and @c max. 19 | */ 20 | -------------------------------------------------------------------------------- /lib/windows/doc/general/windows.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @defgroup qx-windows Qx Windows 3 | * 4 | * @brief The Windows component provides functionality centered around Windows specific programming. 5 | * 6 | * @component{Windows,windows.h} 7 | * 8 | * @note This component is only available when Qx is built to target Windows 9 | * 10 | * Qx Windows contains classes and functions that generally either wrap existing Win32 API functionality 11 | * into a more user friendly interface, other otherwise make various programming tasks on Windows more 12 | * convenient. 13 | * 14 | * Not to be confused with @c , this component also provides the header qx_windows.h as 15 | * an alternative to the standard windows.h. 16 | */ 17 | -------------------------------------------------------------------------------- /lib/windows/include/qx/windows/qx-common-windows.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_WINDOWS_COMMON_H 2 | #define QX_WINDOWS_COMMON_H 3 | 4 | // Shared Lib Support 5 | #include "qx/windows/qx_windows_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | // Intra-component Includes 11 | #include "qx/windows/qx-windefs.h" 12 | 13 | // Extra-component Includes 14 | #include "qx/core/qx-systemerror.h" 15 | 16 | namespace Qx 17 | { 18 | 19 | //-Namespace Structs--------------------------------------------------------------------------------------------------------------- 20 | struct QX_WINDOWS_EXPORT ShortcutProperties 21 | { 22 | enum ShowMode { 23 | NORMAL, 24 | MAXIMIZED, 25 | MINIMIZED 26 | }; 27 | 28 | QString target; 29 | QString targetArgs; 30 | QString startIn; 31 | QString comment; 32 | QString iconFilePath; 33 | int iconIndex = 0; 34 | ShowMode showMode = NORMAL; 35 | }; 36 | 37 | //-Namespace Functions------------------------------------------------------------------------------------------------------------- 38 | 39 | // Processes 40 | QX_WINDOWS_EXPORT QList processThreadIds(DWORD processId); 41 | 42 | /* TODO: DWORD processMainThreadId(DWORD processId); 43 | * 44 | * The best way known so far to figure this out is to use processThreadIds as a baseline and while checking 45 | * the threads, use NtQueryInformationThread to get their start addresses and find the one that matches 46 | * the processes start address from its PE modules header. GetModuleInformation seems to be the key. 47 | * 48 | * See https://docs.microsoft.com/en-us/windows/win32/psapi/module-information 49 | */ 50 | 51 | QX_WINDOWS_EXPORT bool processIsRunning(HANDLE processHandle); 52 | 53 | QX_WINDOWS_EXPORT SystemError processIsElevated(bool& elevated); 54 | QX_WINDOWS_EXPORT SystemError processIsElevated(bool& elevated, HANDLE processHandle); 55 | QX_WINDOWS_EXPORT SystemError processIsElevated(bool& elevated, DWORD processId); 56 | 57 | QX_WINDOWS_EXPORT SystemError cleanKillProcess(HANDLE processHandle); 58 | QX_WINDOWS_EXPORT SystemError forceKillProcess(HANDLE processHandle); 59 | 60 | // Error codes 61 | QX_WINDOWS_EXPORT SystemError getLastError(); 62 | 63 | // Filesystem 64 | QX_WINDOWS_EXPORT SystemError createShortcut(QString shortcutPath, ShortcutProperties sp); 65 | 66 | } 67 | 68 | #endif // QX_WINDOWS_COMMON_H 69 | -------------------------------------------------------------------------------- /lib/windows/include/qx/windows/qx-windefs.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_WINDEFS_H 2 | #define QX_WINDEFS_H 3 | 4 | typedef unsigned long DWORD; 5 | typedef long LONG; 6 | typedef LONG HRESULT; 7 | typedef LONG NTSTATUS; 8 | typedef void* HANDLE; 9 | 10 | #endif // QX_WINDEFS_H 11 | -------------------------------------------------------------------------------- /lib/windows/include/qx_windows.h: -------------------------------------------------------------------------------- 1 | // ifdefs are to avoid macro redefinition warnings 2 | #ifndef WIN32_LEAN_AND_MEAN 3 | #define WIN32_LEAN_AND_MEAN 4 | #endif 5 | #ifndef NOATOM 6 | #define NOATOM 7 | #endif 8 | #ifndef NOGDI 9 | #define NOGDI 10 | #endif 11 | #ifndef NOMINMAX 12 | #define NOMINMAX 13 | #endif 14 | #ifndef NOSOUND 15 | #define NOSOUND 16 | #endif 17 | #ifndef NOHELP 18 | #define NOHELP 19 | #endif 20 | #ifndef NOMCX 21 | #define NOMCX 22 | #endif 23 | 24 | #include "windows.h" 25 | 26 | // See windows.h for more "NOXXX" options 27 | -------------------------------------------------------------------------------- /lib/windows/src/qx-common-windows_p.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx-common-windows_p.h" 3 | 4 | // Qt Includes 5 | #include 6 | #include 7 | 8 | // Windows Includes 9 | #include "combaseapi.h" 10 | 11 | namespace Qx 12 | { 13 | /*! @cond */ 14 | //=============================================================================================================== 15 | // ScopedCom 16 | //=============================================================================================================== 17 | 18 | //-Constructor-------------------------------------------------------------------------------------------------- 19 | //Public: 20 | ScopedCom::ScopedCom() : 21 | mThreadId(GetCurrentThreadId()), 22 | mCleanup(false) 23 | { 24 | // Check if COM is initialized (parameter return values are ignored) 25 | APTTYPE aptType; 26 | APTTYPEQUALIFIER aptTypeQualifier; 27 | HRESULT hRes = CoGetApartmentType(&aptType, &aptTypeQualifier); 28 | if(SUCCEEDED(hRes)) 29 | return; // COM is ready, do nothing 30 | else if(hRes != CO_E_NOTINITIALIZED) 31 | { 32 | // True error 33 | mError = SystemError::fromHresult(hRes); 34 | return; 35 | } 36 | 37 | // Init COM (shouldn't ever be needed in the main thread, but we check just in-case) 38 | auto app = QCoreApplication::instance(); 39 | bool inMainThread = app && app->thread() == QThread::currentThread(); // TODO: Use Qt 6.8 isMainThread() 40 | int tm = (inMainThread ? COINIT_APARTMENTTHREADED : COINIT_MULTITHREADED) | COINIT_DISABLE_OLE1DDE; 41 | hRes = CoInitializeEx(NULL, tm); 42 | if(!SUCCEEDED(hRes)) // Should never fail, but hey... 43 | { 44 | mError = SystemError::fromHresult(hRes); 45 | return; 46 | } 47 | 48 | mCleanup = true; 49 | } 50 | 51 | //-Destructor-------------------------------------------------------------------------------------------------- 52 | //Public: 53 | ScopedCom::~ScopedCom() 54 | { 55 | Q_ASSERT(mThreadId == GetCurrentThreadId()); 56 | if(mCleanup) 57 | CoUninitialize(); 58 | } 59 | 60 | //-Instance Functions-------------------------------------------------------------------------------------------- 61 | //Public: 62 | bool ScopedCom::hasError() const { return mError.isValid(); } 63 | SystemError ScopedCom::error() const { return mError; } 64 | 65 | //-Operators-------------------------------------------------------------------------------------------- 66 | //Public: 67 | ScopedCom::operator bool() const { return !hasError(); } 68 | 69 | /*! @endcond */ 70 | } 71 | -------------------------------------------------------------------------------- /lib/windows/src/qx-common-windows_p.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_WINDOWS_COMMON_P_H 2 | #define QX_WINDOWS_COMMON_P_H 3 | 4 | // Qt Includes 5 | #include 6 | 7 | // Inter-component Includes 8 | #include "qx/windows/qx-windefs.h" 9 | 10 | // Extra-component Includes 11 | #include "qx/core/qx-systemerror.h" 12 | 13 | namespace Qx 14 | { 15 | /*! @cond */ 16 | 17 | // Makes sure COM is initialized, and cleans up on deletion. 18 | // Based on QComHelper, but slightly more flexible in that it just cares COM is initialized one way or another. 19 | class ScopedCom 20 | { 21 | Q_DISABLE_COPY_MOVE(ScopedCom); 22 | private: 23 | SystemError mError; 24 | DWORD mThreadId; // For safety check 25 | bool mCleanup; 26 | 27 | public: 28 | ScopedCom(); 29 | ~ScopedCom(); 30 | 31 | bool hasError() const; 32 | SystemError error() const; 33 | explicit operator bool() const; 34 | }; 35 | 36 | /*! @endcond */ 37 | } 38 | #endif // QX_WINDOWS_COMMON_P_H 39 | -------------------------------------------------------------------------------- /lib/windows/src/qx-windefs.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file qx-windefs.h 3 | * @ingroup qx-windows 4 | * 5 | * @brief The qx-windefs header file provides a subset of Windows data types definitions. 6 | * 7 | * @note This header exists largely as an implementation detail and is unlikely to be useful in 8 | * external projects. 9 | * 10 | * The purpose of this header is to allow the Qx API to refer to Windows data types without polluting 11 | * user code with the entirety of windows.h and related headers. 12 | * 13 | * @sa https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types 14 | */ 15 | 16 | /*! 17 | * @typedef DWORD 18 | * An unsigned 32-bit integer 19 | */ 20 | 21 | /*! 22 | * @typedef @ref LONG 23 | * A signed 32-bit integer 24 | */ 25 | 26 | /*! 27 | * @typedef HRESULT 28 | * Same as @ref LONG 29 | * 30 | * Used to hold the results of Win32 related operations. 31 | */ 32 | 33 | /*! 34 | * @typedef NTSTATUS 35 | * Same as @ref LONG 36 | * 37 | * Used to hold the results of WinNT related operations 38 | */ 39 | 40 | /*! 41 | * @typedef HANDLE 42 | * A void pointer. 43 | * 44 | * Used as a reference to a Windows object. 45 | */ 46 | -------------------------------------------------------------------------------- /lib/xml/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #================= Add Component ========================== 2 | qx_add_component("Xml" 3 | HEADERS_API 4 | qx-common-xml.h 5 | qx-xmlstreamreadererror.h 6 | qx-xmlstreamwritererror.h 7 | IMPLEMENTATION 8 | qx-common-xml.cpp 9 | qx-xmlstreamreadererror.cpp 10 | qx-xmlstreamwritererror.cpp 11 | LINKS 12 | PUBLIC 13 | ${Qt}::Core 14 | ${Qt}::Xml 15 | ) 16 | -------------------------------------------------------------------------------- /lib/xml/cmake/depends_qt: -------------------------------------------------------------------------------- 1 | Core 2 | Xml 3 | -------------------------------------------------------------------------------- /lib/xml/doc/general/xml.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * @defgroup qx-xml Qx XML 3 | * 4 | * @brief The XML component provides classes and mechanisms that enhance and compliment the XML interfaces 5 | * provided by Qt XML. 6 | * 7 | * @component{Xml,xml.h} 8 | * 9 | * This component roughly mirrors Qt XML in terms of scope and organization. 10 | */ 11 | -------------------------------------------------------------------------------- /lib/xml/include/qx/xml/qx-common-xml.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_XML_COMMON_H 2 | #define QX_XML_COMMON_H 3 | 4 | // Shared Lib Support 5 | #include "qx/xml/qx_xml_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | //-Namespace Functions------------------------------------------------------------------------------------------------------------- 14 | QX_XML_EXPORT QString xmlSanitized(const QString& string); 15 | 16 | } 17 | 18 | #endif // QX_XML_COMMON_H 19 | -------------------------------------------------------------------------------- /lib/xml/include/qx/xml/qx-xmlstreamreadererror.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_STREAMREADERERROR_H 2 | #define QX_STREAMREADERERROR_H 3 | 4 | // Shared Lib Support 5 | #include "qx/xml/qx_xml_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | #include 10 | 11 | using namespace Qt::Literals::StringLiterals; 12 | 13 | namespace Qx 14 | { 15 | 16 | class QX_XML_EXPORT XmlStreamReaderError 17 | { 18 | //-Class Members-------------------------------------------------------------------------------------------------- 19 | private: 20 | static inline const QHash STD_ERR_TXT = { 21 | {QXmlStreamReader::NoError, u"No error has occurred."_s}, 22 | {QXmlStreamReader::CustomError, u"A custom error has been raised with raiseError()."_s}, 23 | {QXmlStreamReader::NotWellFormedError, u"The parser internally raised an error due to the read XML not being well-formed."_s}, 24 | {QXmlStreamReader::PrematureEndOfDocumentError, u"The input stream ended before a well-formed XML document was parsed."_s}, 25 | {QXmlStreamReader::UnexpectedElementError, u"The parser encountered an element that was different to those it expected."_s} 26 | }; 27 | //TODO: See if there is a better way to get strings of these errors, but it seems doubtful (there's a slight chance 28 | // that calling device().errorString() on the reader might give these) 29 | 30 | //-Instance Members---------------------------------------------------------------------------------------------- 31 | private: 32 | QXmlStreamReader::Error mErrorType; 33 | QString mErrorText; 34 | 35 | //-Constructor--------------------------------------------------------------------------------------------------- 36 | public: 37 | XmlStreamReaderError(); 38 | XmlStreamReaderError(QXmlStreamReader::Error standardError); 39 | XmlStreamReaderError(QString customError); 40 | XmlStreamReaderError(const QXmlStreamReader& streamReader); 41 | 42 | //-Instance Functions-------------------------------------------------------------------------------------------- 43 | public: 44 | bool isValid(); 45 | QXmlStreamReader::Error type(); 46 | QString text(); 47 | }; 48 | 49 | } 50 | 51 | #endif // QX_STREAMREADERERROR_H 52 | -------------------------------------------------------------------------------- /lib/xml/include/qx/xml/qx-xmlstreamwritererror.h: -------------------------------------------------------------------------------- 1 | #ifndef QX_XMLSTREAMWRITERERROR_H 2 | #define QX_XMLSTREAMWRITERERROR_H 3 | 4 | // Shared Lib Support 5 | #include "qx/xml/qx_xml_export.h" 6 | 7 | // Qt Includes 8 | #include 9 | 10 | namespace Qx 11 | { 12 | 13 | class QX_XML_EXPORT XmlStreamWriterError 14 | { 15 | //-Instance Members---------------------------------------------------------------------------------------------- 16 | private: 17 | QString mErrorText; 18 | 19 | //-Constructor--------------------------------------------------------------------------------------------------- 20 | public: 21 | XmlStreamWriterError(); 22 | XmlStreamWriterError(QString errorText); 23 | 24 | //-Instance Functions-------------------------------------------------------------------------------------------- 25 | public: 26 | bool isValid(); 27 | QString text(); 28 | }; 29 | 30 | } 31 | 32 | #endif // QX_XMLSTREAMWRITERERROR_H 33 | -------------------------------------------------------------------------------- /lib/xml/src/qx-common-xml.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/xml/qx-common-xml.h" 3 | 4 | // Qt Includes 5 | #include 6 | 7 | /*! 8 | * @file qx-common-xml.h 9 | * @ingroup qx-xml 10 | * 11 | * @brief The qx-common-xml header file provides various types, variables, and functions related to 12 | * manipulating XML data. 13 | * 14 | */ 15 | 16 | using namespace Qt::Literals::StringLiterals; 17 | 18 | namespace Qx 19 | { 20 | 21 | namespace // Anonymous namespace for effectively private (to this cpp) 22 | { 23 | //-Unit Variables----------------------------------------------------------------------------------------------------- 24 | const QRegularExpression illegalXmlChar(u"[\u0001-\u0008\u000B\u000C\u000E-\u001F\u007f-\u0084\u0086-\u009f\uFDD0-\uFDFF\uFFFF\uC008]"_s); 25 | } 26 | 27 | //-Namespace Functions---------------------------------------------------------------------------------------------------- 28 | /*! 29 | * Returns a copy of @a string with all non-legal XML characters removed 30 | */ 31 | QString xmlSanitized(const QString& string){ return QString(string).remove(illegalXmlChar); } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /lib/xml/src/qx-xmlstreamreadererror.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/xml/qx-xmlstreamreadererror.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // XmlStreamReaderError 9 | //=============================================================================================================== 10 | 11 | /*! 12 | * @class XmlStreamReaderError qx/xml/qx-xmlstreamreadererror.h 13 | * @ingroup qx-xml 14 | * 15 | * @brief The XmlStreamReaderError class provides a full error object for QXmlStreamReader, similar to other Qt 16 | * classes, that can be more convenient for processing errors than just QXmlStreamReader::Error. 17 | * 18 | * @sa XmlStreamWriterError 19 | */ 20 | 21 | //-Constructor--------------------------------------------------------------------------------------------------- 22 | //Public: 23 | /*! 24 | * Constructs an invalid XML stream reader error that is equivalent to QXmlStreamReader::Error::NoError. 25 | */ 26 | XmlStreamReaderError::XmlStreamReaderError() : 27 | mErrorType(QXmlStreamReader::NoError), 28 | mErrorText(STD_ERR_TXT.value(QXmlStreamReader::NoError)) 29 | {} 30 | 31 | /*! 32 | * Constructs a XML stream reader error from @a standardError. 33 | */ 34 | XmlStreamReaderError::XmlStreamReaderError(QXmlStreamReader::Error standardError) : 35 | mErrorType(standardError), 36 | mErrorText(STD_ERR_TXT.value(standardError)) 37 | {} 38 | 39 | /*! 40 | * Constructs a custom XML stream reader error from the string @a customError. 41 | * 42 | * This sets the error type to QXmlStreamReader::Error::CustomError. 43 | */ 44 | XmlStreamReaderError::XmlStreamReaderError(QString customError) : 45 | mErrorType(QXmlStreamReader::Error::CustomError), 46 | mErrorText(customError) 47 | {} 48 | 49 | /*! 50 | * Constructs a custom XML stream reader error from the current error state of stream @a streamReader. 51 | */ 52 | XmlStreamReaderError::XmlStreamReaderError(const QXmlStreamReader& streamReader) : 53 | mErrorType(streamReader.error()), 54 | mErrorText(mErrorType == QXmlStreamReader::CustomError ? streamReader.errorString() : STD_ERR_TXT.value(mErrorType)) 55 | {} 56 | 57 | //-Instance Functions-------------------------------------------------------------------------------------------- 58 | //Public: 59 | /*! 60 | * Returns @c true if the error is valid; otherwise returns @c false. 61 | * 62 | * A xml stream reader error is valid if its underlying type isn't QXmlStreamReader::Error::NoError. 63 | */ 64 | bool XmlStreamReaderError::isValid() { return mErrorType != QXmlStreamReader::Error::NoError; } 65 | 66 | /*! 67 | * Returns the error's underlying type. 68 | */ 69 | QXmlStreamReader::Error XmlStreamReaderError::type() { return mErrorType; } 70 | 71 | /*! 72 | * Returns the textual representation of the error. 73 | */ 74 | QString XmlStreamReaderError::text() { return mErrorText; } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /lib/xml/src/qx-xmlstreamwritererror.cpp: -------------------------------------------------------------------------------- 1 | // Unit Includes 2 | #include "qx/xml/qx-xmlstreamwritererror.h" 3 | 4 | namespace Qx 5 | { 6 | 7 | //=============================================================================================================== 8 | // XmlStreamWriterError 9 | //=============================================================================================================== 10 | 11 | /*! 12 | * @class XmlStreamWriterError qx/xml/qx-xmlstreamwritererror.h 13 | * @ingroup qx-xml 14 | * 15 | * @brief The XmlStreamWriterError class provides a full error object for QXmlStreamWriterError, similar to other 16 | * Qt classes. QXmlStreamWriter doesn't have an intrinsic error type, but this class can be useful for passing 17 | * contextual error information when writing XML data so that intent is more clear. 18 | * 19 | * @sa XmlStreamReaderError 20 | */ 21 | 22 | //-Constructor--------------------------------------------------------------------------------------------------- 23 | //Public: 24 | /*! 25 | * Constructs an invalid XML stream writer error. 26 | */ 27 | XmlStreamWriterError::XmlStreamWriterError() : 28 | mErrorText() 29 | {} 30 | 31 | /*! 32 | * Constructs a XML stream writer error from @a errorText. 33 | */ 34 | XmlStreamWriterError::XmlStreamWriterError(QString errorText) : 35 | mErrorText(errorText) 36 | {} 37 | 38 | //-Instance Functions-------------------------------------------------------------------------------------------- 39 | //Public: 40 | /*! 41 | * Returns @c true if the error is valid; otherwise returns @c false. 42 | */ 43 | bool XmlStreamWriterError::isValid() { return !mErrorText.isNull(); } 44 | 45 | /*! 46 | * Returns error's text. 47 | */ 48 | QString XmlStreamWriterError::text() { return mErrorText; } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(_common) 2 | 3 | # Add tests for each configured component 4 | foreach(comp ${QX_COMPONENTS_FULL}) 5 | string(TOLOWER ${comp} comp_lc) 6 | add_subdirectory(${comp_lc}) 7 | endforeach() 8 | -------------------------------------------------------------------------------- /tests/_common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #=== TESTS INTERFACE HELPER LIB === 2 | 3 | # Setup lib target 4 | add_library(${TESTS_COMMON_TARGET} INTERFACE) 5 | 6 | target_sources(${TESTS_COMMON_TARGET} 7 | PRIVATE 8 | include/qx_test_common.h 9 | ) 10 | 11 | target_include_directories(${TESTS_COMMON_TARGET} 12 | INTERFACE 13 | $ 14 | ) 15 | 16 | target_link_libraries(${TESTS_COMMON_TARGET} 17 | INTERFACE 18 | ${Qt}::Test 19 | ) 20 | -------------------------------------------------------------------------------- /tests/_common/include/qx_test_common.h: -------------------------------------------------------------------------------- 1 | // Macros 2 | #define C_STR(q_str) q_str.toStdString().c_str() 3 | 4 | // Test debug helpers (enables more helpful print-outs from test failures) 5 | namespace Qx 6 | { 7 | 8 | 9 | /* Copy pasted from STARpp as example for this 10 | QString qnn(const QString& s) { return s.isNull() ? s : '"' + s + '"'; } 11 | 12 | QString elecResStr(const QList& seats) 13 | { 14 | static const QString seatTempl = QStringLiteral( 15 | "\n" 16 | "Seat (%1)\n" 17 | "---------\n" 18 | "Winner: %2\n" 19 | "First Seed: %3\n" 20 | "Second Seed: %4\n" 21 | "Simultaneous: %5\n" 22 | "Overflow: {%6}\n" 23 | "\n" 24 | ); 25 | 26 | QString resStr; 27 | resStr.reserve(seatTempl.size() * seats.size()); // Roughly final size 28 | 29 | for(auto i = 0; i < seats.size(); i++) 30 | { 31 | const Seat& seat = seats.at(i); 32 | QString winner = seat.winner(); 33 | QualifierResult qr = seat.qualifierResult(); 34 | 35 | resStr.append( 36 | seatTempl.arg(i) 37 | .arg(qnn(seat.winner()), qnn(qr.firstSeed()), qnn(qr.secondSeed())) 38 | .arg(qr.isSeededSimultaneously() ? "true" : "false") 39 | .arg(qr.overflow().isEmpty() ? "" : '"' + Qx::String::join(qr.overflow(), R"(", ")") + '"') 40 | ); 41 | } 42 | 43 | return resStr; 44 | } 45 | 46 | char* toString(const ExpectedElectionResult& eer) 47 | { 48 | QString string = elecResStr(eer.seats()); 49 | return qstrdup(string.toUtf8().constData()); 50 | } 51 | 52 | char* toString(const ElectionResult& er) 53 | { 54 | QString string = elecResStr(er.seats()); 55 | return qstrdup(string.toUtf8().constData()); 56 | } 57 | */ 58 | } 59 | -------------------------------------------------------------------------------- /tests/core/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(qx_array) 2 | add_subdirectory(qx_freeindextracker) 3 | add_subdirectory(qx_integrity) 4 | add_subdirectory(qx_json) 5 | -------------------------------------------------------------------------------- /tests/core/qx_array/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(OB/Test) 2 | 3 | ob_add_basic_standard_test( 4 | TARGET_PREFIX "${TESTS_TARGET_PREFIX}" 5 | LINKS 6 | PRIVATE 7 | ${TESTS_COMMON_TARGET} 8 | Qx::Core 9 | ) 10 | -------------------------------------------------------------------------------- /tests/core/qx_array/tst_qx_array.cpp: -------------------------------------------------------------------------------- 1 | // Qt Includes 2 | #include 3 | 4 | // Qx Includes 5 | #include 6 | 7 | // Test Includes 8 | //#include 9 | 10 | class tst_qx_array : public QObject 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | tst_qx_array(); 16 | 17 | private slots: 18 | // Init 19 | // void initTestCase(); 20 | // void initTestCase_data(); 21 | // void cleanupTestCase(); 22 | // void init() 23 | // void cleanup(); 24 | 25 | // Test cases 26 | void mostFrequent(); 27 | }; 28 | 29 | // Setup 30 | tst_qx_array::tst_qx_array() {} 31 | 32 | // Cases 33 | void tst_qx_array::mostFrequent() 34 | { 35 | int a[8] = {1,1,2,3,4,5,5,5}; 36 | int b[5] = {1,2,2,3,4}; 37 | int c[5] = {1,1,2,3,3}; 38 | QVERIFY(Qx::Array::mostFrequent(a) == 5); 39 | QVERIFY(Qx::Array::mostFrequent(b) == 2); 40 | int cRes = Qx::Array::mostFrequent(c); 41 | QVERIFY( cRes == 1 || cRes == 3); 42 | } 43 | 44 | QTEST_APPLESS_MAIN(tst_qx_array) 45 | #include "tst_qx_array.moc" 46 | -------------------------------------------------------------------------------- /tests/core/qx_freeindextracker/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(OB/Test) 2 | 3 | ob_add_basic_standard_test( 4 | TARGET_PREFIX "${TESTS_TARGET_PREFIX}" 5 | LINKS 6 | PRIVATE 7 | ${TESTS_COMMON_TARGET} 8 | Qx::Core 9 | ) 10 | -------------------------------------------------------------------------------- /tests/core/qx_integrity/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(OB/Test) 2 | 3 | ob_add_basic_standard_test( 4 | TARGET_PREFIX "${TESTS_TARGET_PREFIX}" 5 | LINKS 6 | PRIVATE 7 | ${TESTS_COMMON_TARGET} 8 | Qx::Core 9 | ) 10 | -------------------------------------------------------------------------------- /tests/core/qx_integrity/tst_qx_integrity.cpp: -------------------------------------------------------------------------------- 1 | // Qt Includes 2 | #include 3 | 4 | // Qx Includes 5 | #include 6 | 7 | // Test Includes 8 | //#include 9 | 10 | class tst_qx_integrity : public QObject 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | tst_qx_integrity(); 16 | 17 | private slots: 18 | // Init 19 | // void initTestCase(); 20 | // void initTestCase_data(); 21 | // void cleanupTestCase(); 22 | // void init() 23 | // void cleanup(); 24 | 25 | // Test cases 26 | // void generateCheckum(); 27 | void crc32(); 28 | }; 29 | 30 | // Setup 31 | tst_qx_integrity::tst_qx_integrity() {} 32 | 33 | // Cases 34 | void tst_qx_integrity::crc32() 35 | { 36 | quint32 res = Qx::Integrity::crc32(QByteArrayLiteral("ThisIsForCRC32Testing")); 37 | QCOMPARE(res, 0x926CE4A1); 38 | } 39 | 40 | QTEST_APPLESS_MAIN(tst_qx_integrity) 41 | #include "tst_qx_integrity.moc" 42 | -------------------------------------------------------------------------------- /tests/core/qx_json/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(OB/Test) 2 | 3 | ob_add_basic_standard_test( 4 | TARGET_PREFIX "${TESTS_TARGET_PREFIX}" 5 | LINKS 6 | PRIVATE 7 | ${TESTS_COMMON_TARGET} 8 | Qx::Core 9 | ) 10 | -------------------------------------------------------------------------------- /tests/gui/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/tests/gui/CMakeLists.txt -------------------------------------------------------------------------------- /tests/io/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(qx_common_io) -------------------------------------------------------------------------------- /tests/io/qx_common_io/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(OB/Test) 2 | 3 | ob_add_basic_standard_test( 4 | TARGET_PREFIX "${TESTS_TARGET_PREFIX}" 5 | TARGET_VAR test_target 6 | LINKS 7 | PRIVATE 8 | ${TESTS_COMMON_TARGET} 9 | Qx::Io 10 | ) 11 | 12 | # Bundle test data 13 | file(GLOB_RECURSE text_data 14 | RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 15 | "data/*.*" 16 | ) 17 | 18 | qt_add_resources(${test_target} "tst_qx_common_io_data" 19 | PREFIX "/" 20 | FILES 21 | ${text_data} 22 | ) 23 | -------------------------------------------------------------------------------- /tests/io/qx_common_io/data/writeStringToFile/overwrite_expected.txt: -------------------------------------------------------------------------------- 1 | 0123456789 2 | 01Jishy 3 | SaltSalivaMan 4 | test456789 5 | 0123456789 -------------------------------------------------------------------------------- /tests/io/qx_common_io/data/writeStringToFile/overwrite_input.txt: -------------------------------------------------------------------------------- 1 | Jishy 2 | SaltSalivaMan 3 | test -------------------------------------------------------------------------------- /tests/io/qx_common_io/data/writeStringToFile/overwrite_original.txt: -------------------------------------------------------------------------------- 1 | 0123456789 2 | 0123456789 3 | 0123456789 4 | 0123456789 5 | 0123456789 -------------------------------------------------------------------------------- /tests/io/qx_common_io/tst_qx_common_io.cpp: -------------------------------------------------------------------------------- 1 | // Qt Includes 2 | #include 3 | 4 | // Qx Includes 5 | #include 6 | 7 | // Test Includes 8 | //#include 9 | 10 | class tst_qx_common_io : public QObject 11 | { 12 | Q_OBJECT 13 | 14 | private: 15 | QTemporaryDir mWriteDir; 16 | 17 | public: 18 | tst_qx_common_io(); 19 | 20 | private slots: 21 | // Init 22 | // void initTestCase(); 23 | // void initTestCase_data(); 24 | // void cleanupTestCase(); 25 | // void init() 26 | // void cleanup(); 27 | 28 | // Test cases 29 | void writeStringToFile_data(); 30 | void writeStringToFile(); 31 | }; 32 | 33 | // Setup 34 | tst_qx_common_io::tst_qx_common_io() 35 | { 36 | QVERIFY(mWriteDir.isValid()); 37 | } 38 | 39 | // Cases 40 | void tst_qx_common_io::writeStringToFile_data() 41 | { 42 | QTest::addColumn("file"); 43 | QTest::addColumn("input"); 44 | QTest::addColumn("expected"); 45 | 46 | // TODO: Make this more generic with helper functions once more test files are added 47 | 48 | // Overwrite 49 | QString overwritePath = mWriteDir.filePath("overwrite_file.txt"); 50 | QVERIFY(QFile::copy(u":/data/writeStringToFile/overwrite_original.txt"_s, overwritePath)); 51 | auto p = QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser; 52 | QFile::setPermissions(overwritePath, p); // Required since copying from a file marked read-only 53 | 54 | QFile inputFile(u":/data/writeStringToFile/overwrite_input.txt"_s); 55 | QVERIFY(inputFile.open(QIODevice::ReadOnly | QIODevice::Text)); 56 | QString input = inputFile.readAll(); 57 | inputFile.close(); 58 | 59 | QFile expectedFile(u":/data/writeStringToFile/overwrite_expected.txt"_s); 60 | QVERIFY(expectedFile.open(QIODevice::ReadOnly | QIODevice::Text)); 61 | QString expected = expectedFile.readAll(); 62 | expectedFile.close(); 63 | 64 | QTest::newRow("Overwrite") << new QFile(overwritePath, this) << input << expected; 65 | } 66 | 67 | void tst_qx_common_io::writeStringToFile() 68 | { 69 | // Fetch data from test table 70 | QFETCH(QFile*, file); 71 | QFETCH(QString, input); 72 | QFETCH(QString, expected); 73 | 74 | // Write to file 75 | // TODO: Handle different arguments for writeStringToFile in _data 76 | Qx::IoOpReport rp = Qx::writeStringToFile(*file, input, Qx::Overwrite, Qx::TextPos(1,2)); 77 | QVERIFY2(!rp.isFailure(), qPrintable(rp.outcomeInfo())); 78 | 79 | // Get file's new contents and compare 80 | QVERIFY(file->open(QIODevice::ReadOnly | QIODevice::Text)); 81 | QTextStream ts(file); // Handles proper conversion of \r\n to \n 82 | QString newData = ts.readAll(); 83 | QCOMPARE(newData, expected); 84 | file->close(); 85 | } 86 | 87 | QTEST_APPLESS_MAIN(tst_qx_common_io) 88 | #include "tst_qx_common_io.moc" 89 | -------------------------------------------------------------------------------- /tests/linux/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/tests/linux/CMakeLists.txt -------------------------------------------------------------------------------- /tests/network/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/tests/network/CMakeLists.txt -------------------------------------------------------------------------------- /tests/utility/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/tests/utility/CMakeLists.txt -------------------------------------------------------------------------------- /tests/widgets/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/tests/widgets/CMakeLists.txt -------------------------------------------------------------------------------- /tests/windows-gui/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/tests/windows-gui/CMakeLists.txt -------------------------------------------------------------------------------- /tests/windows/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/tests/windows/CMakeLists.txt -------------------------------------------------------------------------------- /tests/xml/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oblivioncth/Qx/25f5d0c0bd4fa7d4c77f0ae31c8f06722190be0e/tests/xml/CMakeLists.txt --------------------------------------------------------------------------------