├── .clang-format ├── .github └── FUNDING.yml ├── .gitignore ├── AUTHORS ├── CHANGELOG ├── CMakeLists.txt ├── CONTRIBUTING.md ├── COPYING ├── InstallLinux.cmake ├── InstallWindows.cmake ├── Jenkinsfile ├── Jenkinsfile-Snap ├── README.md ├── data ├── icons │ ├── WindowsHeimer.rc │ ├── heimer.ico │ ├── heimer.png │ └── icons.qrc ├── images │ ├── about.png │ └── images.qrc └── translations │ └── translations.qrc ├── examples ├── Company.alz ├── Family.alz ├── Heimer.alz ├── Large.alz └── Matrix.alz ├── meta.qrc ├── packaging └── README ├── screenshots ├── 0.0.0 │ ├── Company.png │ ├── Family.png │ └── Heimer.png ├── 1.0.0 │ └── Heimer.png ├── 1.14.0 │ └── Heimer.png ├── 1.2.0 │ ├── About.png │ ├── Empty.png │ └── Heimer.png ├── 3.6.2 │ └── Heimer.png └── 4.4.0 │ ├── Family_TextSearch.png │ ├── Heimer.png │ ├── Large.png │ └── Matrix.png ├── scripts ├── allow-docker-network ├── apply-clang-format ├── build-app-image ├── build-archive ├── build-snap-lxd ├── build-snap-multipass ├── build-windows-nsis ├── build-windows-zip ├── copy-artifacts ├── update-version └── upload-snap ├── snapcraft.yaml └── src ├── CMakeLists.txt ├── application ├── application.cpp ├── application.hpp ├── application_service.cpp ├── application_service.hpp ├── control_strategy.cpp ├── control_strategy.hpp ├── editor_service.cpp ├── editor_service.hpp ├── hash_seed.cpp ├── hash_seed.hpp ├── language_service.cpp ├── language_service.hpp ├── progress_manager.cpp ├── progress_manager.hpp ├── recent_files_manager.cpp ├── recent_files_manager.hpp ├── service_container.cpp ├── service_container.hpp ├── settings_proxy.cpp ├── settings_proxy.hpp ├── state_machine.cpp ├── state_machine.hpp ├── user_exception.hpp └── version.hpp ├── common ├── constants.cpp ├── constants.hpp ├── test_mode.cpp ├── test_mode.hpp ├── types.hpp ├── utils.cpp └── utils.hpp ├── contrib ├── Argengine │ ├── .clang-format │ ├── .gitignore │ ├── CHANGELOG │ ├── CMakeLists.txt │ ├── Jenkinsfile │ ├── LICENSE │ ├── README.md │ └── src │ │ ├── CMakeLists.txt │ │ ├── argengine.cpp │ │ ├── argengine.hpp │ │ ├── examples │ │ ├── CMakeLists.txt │ │ ├── ex1 │ │ │ ├── CMakeLists.txt │ │ │ └── ex1.cpp │ │ └── ex2 │ │ │ ├── CMakeLists.txt │ │ │ └── ex2.cpp │ │ └── tests │ │ ├── CMakeLists.txt │ │ ├── conflicting_arguments_test │ │ ├── CMakeLists.txt │ │ └── conflicting_arguments_test.cpp │ │ ├── help_test │ │ ├── CMakeLists.txt │ │ └── help_test.cpp │ │ ├── positional_argument_test │ │ ├── CMakeLists.txt │ │ └── positional_argument_test.cpp │ │ ├── single_value_test │ │ ├── CMakeLists.txt │ │ └── single_value_test.cpp │ │ ├── unknown_argument_test │ │ ├── CMakeLists.txt │ │ └── unknown_argument_test.cpp │ │ └── valueless_test │ │ ├── CMakeLists.txt │ │ └── valueless_test.cpp └── SimpleLogger │ ├── .clang-format │ ├── CHANGELOG │ ├── CMakeLists.txt │ ├── Jenkinsfile │ ├── LICENSE │ ├── README.md │ └── src │ ├── CMakeLists.txt │ ├── simple_logger.cpp │ ├── simple_logger.hpp │ └── tests │ ├── CMakeLists.txt │ ├── file_test │ ├── CMakeLists.txt │ └── file_test.cpp │ └── stream_test │ ├── CMakeLists.txt │ └── stream_test.cpp ├── domain ├── copy_context.cpp ├── copy_context.hpp ├── graph.cpp ├── graph.hpp ├── image.cpp ├── image.hpp ├── image_manager.cpp ├── image_manager.hpp ├── layout_optimizer.cpp ├── layout_optimizer.hpp ├── mind_map_data.cpp ├── mind_map_data.hpp ├── mind_map_data_base.cpp ├── mind_map_data_base.hpp ├── mind_map_stats.hpp ├── undo_stack.cpp └── undo_stack.hpp ├── heimer.appdata.xml ├── heimer.desktop.in ├── images ├── add.svg ├── colors.svg ├── colorsText.svg ├── drag.svg └── icon.svg ├── infra ├── export_params.hpp ├── io │ ├── alz_file_io.cpp │ ├── alz_file_io.hpp │ ├── alz_file_io_version.hpp │ ├── alz_file_io_worker.cpp │ ├── alz_file_io_worker.hpp │ ├── file_exception.hpp │ ├── file_io.hpp │ ├── xml_reader.cpp │ ├── xml_reader.hpp │ ├── xml_writer.cpp │ └── xml_writer.hpp ├── settings.cpp ├── settings.hpp ├── version_checker.cpp └── version_checker.hpp ├── main.cpp ├── translations ├── .gitkeep ├── heimer_de.ts ├── heimer_en.ts ├── heimer_es.ts ├── heimer_eu.ts ├── heimer_fi.ts ├── heimer_fr.ts ├── heimer_it.ts ├── heimer_nl.ts ├── heimer_pt_Br.ts ├── heimer_pt_Pt.ts └── heimer_zh.ts ├── unit_tests ├── CMakeLists.txt ├── alz_file_io_test │ ├── CMakeLists.txt │ ├── alz_file_io_test.cpp │ └── alz_file_io_test.hpp ├── editor_service_test │ ├── CMakeLists.txt │ ├── editor_service_test.cpp │ └── editor_service_test.hpp ├── graph_test │ ├── CMakeLists.txt │ ├── graph_test.cpp │ └── graph_test.hpp ├── layout_optimizer_test │ ├── CMakeLists.txt │ ├── layout_optimizer_test.cpp │ └── layout_optimizer_test.hpp ├── node_test │ ├── CMakeLists.txt │ ├── node_test.cpp │ └── node_test.hpp ├── selection_group_test │ ├── CMakeLists.txt │ ├── selection_group_test.cpp │ └── selection_group_test.hpp ├── unit_test_base.cpp ├── unit_test_base.hpp └── version_test │ ├── CMakeLists.txt │ ├── version_test.cpp │ └── version_test.hpp └── view ├── dialogs ├── about_dialog.cpp ├── about_dialog.hpp ├── color_dialog.cpp ├── color_dialog.hpp ├── color_setting_button.cpp ├── color_setting_button.hpp ├── defaults_tab.cpp ├── defaults_tab.hpp ├── editing_tab.cpp ├── editing_tab.hpp ├── effects_tab.cpp ├── effects_tab.hpp ├── export │ ├── png_export_dialog.cpp │ ├── png_export_dialog.hpp │ ├── svg_export_dialog.cpp │ └── svg_export_dialog.hpp ├── layout_optimization_dialog.cpp ├── layout_optimization_dialog.hpp ├── scene_color_dialog.cpp ├── scene_color_dialog.hpp ├── settings_dialog.cpp ├── settings_dialog.hpp ├── settings_tab_base.cpp ├── settings_tab_base.hpp ├── spinner_dialog.cpp ├── spinner_dialog.hpp ├── whats_new_dialog.cpp ├── whats_new_dialog.hpp ├── widget_factory.cpp └── widget_factory.hpp ├── edge_action.hpp ├── edge_selection_group.cpp ├── edge_selection_group.hpp ├── editor_scene.cpp ├── editor_scene.hpp ├── editor_view.cpp ├── editor_view.hpp ├── grid.cpp ├── grid.hpp ├── item_filter.cpp ├── item_filter.hpp ├── magic_zoom.cpp ├── magic_zoom.hpp ├── main_window.cpp ├── main_window.hpp ├── menus ├── edge_context_menu.cpp ├── edge_context_menu.hpp ├── main_context_menu.cpp ├── main_context_menu.hpp ├── main_menu.cpp ├── main_menu.hpp ├── recent_files_menu.cpp ├── recent_files_menu.hpp ├── tool_bar.cpp ├── tool_bar.hpp ├── widget_factory.cpp └── widget_factory.hpp ├── mouse_action.cpp ├── mouse_action.hpp ├── node_action.hpp ├── node_selection_group.cpp ├── node_selection_group.hpp ├── scene_items ├── edge.cpp ├── edge.hpp ├── edge_dot.cpp ├── edge_dot.hpp ├── edge_model.hpp ├── edge_point.hpp ├── edge_text_edit.cpp ├── edge_text_edit.hpp ├── graphics_factory.cpp ├── graphics_factory.hpp ├── layers.hpp ├── node.cpp ├── node.hpp ├── node_handle.cpp ├── node_handle.hpp ├── node_model.hpp ├── scene_item_base.cpp ├── scene_item_base.hpp ├── text_edit.cpp └── text_edit.hpp ├── shadow_effect_params.hpp └── widgets ├── font_button.cpp ├── font_button.hpp ├── status_label.cpp └── status_label.hpp /.clang-format: -------------------------------------------------------------------------------- 1 | AccessModifierOffset: -4 2 | AlignAfterOpenBracket: true 3 | AllowShortFunctionsOnASingleLine: false 4 | AlwaysBreakTemplateDeclarations: true 5 | BasedOnStyle: WebKit 6 | BreakBeforeBinaryOperators: NonAssignment 7 | BreakBeforeBraces: Custom 8 | BreakConstructorInitializersBeforeComma: false 9 | BreakConstructorInitializers: BeforeComma 10 | BraceWrapping: 11 | AfterClass: true 12 | AfterControlStatement: false 13 | AfterEnum: true 14 | AfterFunction: true 15 | AfterNamespace: false 16 | AfterObjCDeclaration: false 17 | AfterStruct: true 18 | AfterUnion: false 19 | BeforeCatch: false 20 | BeforeElse: false 21 | IndentBraces: false 22 | ColumnLimit: 0 23 | CommentPragmas: "^!|^:" 24 | CompactNamespaces: false 25 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 26 | ConstructorInitializerIndentWidth: 2 27 | ContinuationIndentWidth: 2 28 | FixNamespaceComments: true 29 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ] 30 | IndentWidth: 4 31 | NamespaceIndentation: None 32 | PointerAlignment: Middle 33 | PointerBindsToType: false 34 | SortIncludes: true 35 | SpaceAfterTemplateKeyword: false 36 | Standard: Cpp11 37 | 38 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # juzzlin 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: 'https://paypal.me/juzzlin' 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.cxx 3 | *.o 4 | *.a 5 | *moc_* 6 | *_automoc* 7 | *qrc_* 8 | *.tar.gz 9 | *.zip 10 | *.exe 11 | *.json 12 | log.txt 13 | manifest* 14 | .excludes 15 | *__* 16 | Makefile 17 | bin/ 18 | heimer.pro.user 19 | heimer.pro.user.2.1pre1 20 | src/Makefile 21 | *.cbp 22 | test/ 23 | CTestTestfile.cmake 24 | cmake_install.cmake 25 | src/CTestTestfile.cmake 26 | src/cmake_install.cmake 27 | CPackConfig.cmake 28 | CPackSourceConfig.cmake 29 | release/ 30 | *_plugin_import* 31 | *.Debug 32 | *.Release 33 | CMakeLists.txt.user 34 | *build* 35 | 36 | .qmake.stash 37 | docker/ 38 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | People who have contributed to Heimer 2 | ======================================= 3 | 4 | Programming: 5 | * Jussi Lind 6 | 7 | Graphics: 8 | * Jussi Lind 9 | 10 | Translations: 11 | * Jussi Lind (fi) 12 | * olielvewen (fr) 13 | * Albano Battistella (it) 14 | 15 | -------------------------------------------------------------------------------- /InstallLinux.cmake: -------------------------------------------------------------------------------- 1 | # **** Install targets for Linux **** 2 | function(setup_install_targets) 3 | 4 | set(DEFAULT_DATA_PATH_BASE share/applications/heimer) 5 | if(NOT BIN_PATH) 6 | set(BIN_PATH bin) 7 | endif() 8 | 9 | message(STATUS "Linux/Unix build with system install targets.") 10 | 11 | # Install binaries and data 12 | install(PROGRAMS ${CMAKE_BINARY_DIR}/${BINARY_NAME} DESTINATION ${BIN_PATH}) 13 | 14 | # Install .desktop files 15 | install(FILES ${CMAKE_BINARY_DIR}/heimer.desktop DESTINATION share/applications) 16 | 17 | # Install app store meta data 18 | install(FILES src/heimer.appdata.xml DESTINATION share/metainfo) 19 | 20 | # Install icons 21 | install(FILES data/icons/heimer.png DESTINATION share/pixmaps) 22 | install(FILES data/icons/heimer.png DESTINATION share/icons/hicolor/256x256/apps) 23 | 24 | set(CPACK_DEBIAN_PACKAGE_NAME "heimer") 25 | set(CPACK_DEBIAN_PACKAGE_VERSION ${APPLICATION_VERSION}) 26 | set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") 27 | set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Jussi Lind ") 28 | set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Simple mind map creation tool.") 29 | set(CPACK_DEBIAN_PACKAGE_SECTION "Education") 30 | set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") 31 | 32 | set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS YES) 33 | 34 | if(DISTRO_VERSION) 35 | message(STATUS "Distro version: ${DISTRO_VERSION}") 36 | set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}-${DISTRO_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}) 37 | else() 38 | set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}) 39 | endif() 40 | 41 | include(CPack) 42 | 43 | endfunction() 44 | 45 | -------------------------------------------------------------------------------- /InstallWindows.cmake: -------------------------------------------------------------------------------- 1 | # **** Instal targets for Windows **** 2 | function(setup_install_targets) 3 | 4 | message(STATUS "Windows build.") 5 | 6 | set(BIN_PATH .) 7 | set(DOC_PATH .) 8 | 9 | # Add target to copy files to the binary dir. 10 | add_custom_target(docs ALL 11 | COMMAND cmake -E copy_directory ${CMAKE_SOURCE_DIR}/data ${CMAKE_BINARY_DIR}/data 12 | COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/AUTHORS ${CMAKE_BINARY_DIR}/AUTHORS 13 | COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/CHANGELOG ${CMAKE_BINARY_DIR}/CHANGELOG 14 | COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/COPYING ${CMAKE_BINARY_DIR}/COPYING 15 | COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/README.md ${CMAKE_BINARY_DIR}/README.md 16 | DEPENDS ${BINARY_NAME}) 17 | 18 | # Add target to copy data files to the binary dir. 19 | add_custom_target(data ALL 20 | COMMAND cmake -E copy_directory ${CMAKE_SOURCE_DIR}/data ${CMAKE_BINARY_DIR}/data 21 | DEPENDS ${BINARY_NAME}) 22 | 23 | install(PROGRAMS ${CMAKE_BINARY_DIR}/${BINARY_NAME}.exe DESTINATION ${BIN_PATH}) 24 | install(FILES AUTHORS CHANGELOG COPYING README.md DESTINATION ${DOC_PATH}) 25 | 26 | set(CPACK_PACKAGE_INSTALL_DIRECTORY Heimer) 27 | 28 | set(CPACK_NSIS_MUI_ICON ${CMAKE_SOURCE_DIR}/data/icons/heimer.ico) 29 | set(CPACK_NSIS_MUI_UNIICON ${CMAKE_SOURCE_DIR}/data/icons/heimer.ico) 30 | set(CPACK_NSIS_DISPLAY_NAME Heimer) 31 | set(CPACK_NSIS_PACKAGE_NAME Heimer) 32 | set(CPACK_NSIS_HELP_LINK http://juzzlin.github.io/Heimer/) 33 | set(CPACK_NSIS_URL_INFO_ABOUT http://juzzlin.github.io/Heimer/) 34 | 35 | set(CPACK_NSIS_CREATE_ICONS_EXTRA 36 | "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${BINARY_NAME}.lnk' '$INSTDIR\\\\${BINARY_NAME}.exe'" 37 | ) 38 | 39 | set(CPACK_NSIS_DELETE_ICONS_EXTRA 40 | "Delete '$SMPROGRAMS\\\\$START_MENU\\\\${BINARY_NAME}.lnk'" 41 | ) 42 | 43 | include(CPack) 44 | 45 | endfunction() 46 | 47 | -------------------------------------------------------------------------------- /Jenkinsfile-Snap: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent none 3 | stages { 4 | stage('Snap') { 5 | agent any 6 | steps { 7 | lock(resource: 'snapLock') { 8 | sh "./scripts/build-snap-lxd" 9 | } 10 | } 11 | post { 12 | always { 13 | archiveArtifacts artifacts: '*.snap', fingerprint: true 14 | } 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /data/icons/WindowsHeimer.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "heimer.ico" 2 | -------------------------------------------------------------------------------- /data/icons/heimer.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/data/icons/heimer.ico -------------------------------------------------------------------------------- /data/icons/heimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/data/icons/heimer.png -------------------------------------------------------------------------------- /data/icons/icons.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | heimer.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /data/images/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/data/images/about.png -------------------------------------------------------------------------------- /data/images/images.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | about.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /data/translations/translations.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | heimer_de.qm 4 | heimer_en.qm 5 | heimer_es.qm 6 | heimer_eu.qm 7 | heimer_fi.qm 8 | heimer_fr.qm 9 | heimer_it.qm 10 | heimer_nl.qm 11 | heimer_pt_Br.qm 12 | heimer_pt_Pt.qm 13 | heimer_zh.qm 14 | 15 | 16 | -------------------------------------------------------------------------------- /meta.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | CHANGELOG 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /packaging/README: -------------------------------------------------------------------------------- 1 | README 2 | ====== 3 | 4 | windows/ contains NSIS packaging script for Windows. 5 | 6 | Linux packages are generated with CPack. 7 | -------------------------------------------------------------------------------- /screenshots/0.0.0/Company.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/0.0.0/Company.png -------------------------------------------------------------------------------- /screenshots/0.0.0/Family.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/0.0.0/Family.png -------------------------------------------------------------------------------- /screenshots/0.0.0/Heimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/0.0.0/Heimer.png -------------------------------------------------------------------------------- /screenshots/1.0.0/Heimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/1.0.0/Heimer.png -------------------------------------------------------------------------------- /screenshots/1.14.0/Heimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/1.14.0/Heimer.png -------------------------------------------------------------------------------- /screenshots/1.2.0/About.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/1.2.0/About.png -------------------------------------------------------------------------------- /screenshots/1.2.0/Empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/1.2.0/Empty.png -------------------------------------------------------------------------------- /screenshots/1.2.0/Heimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/1.2.0/Heimer.png -------------------------------------------------------------------------------- /screenshots/3.6.2/Heimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/3.6.2/Heimer.png -------------------------------------------------------------------------------- /screenshots/4.4.0/Family_TextSearch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/4.4.0/Family_TextSearch.png -------------------------------------------------------------------------------- /screenshots/4.4.0/Heimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/4.4.0/Heimer.png -------------------------------------------------------------------------------- /screenshots/4.4.0/Large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/4.4.0/Large.png -------------------------------------------------------------------------------- /screenshots/4.4.0/Matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/screenshots/4.4.0/Matrix.png -------------------------------------------------------------------------------- /scripts/allow-docker-network: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo iptables -I DOCKER-USER -j ACCEPT 4 | -------------------------------------------------------------------------------- /scripts/apply-clang-format: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CLANG_FORMAT=clang-format 4 | 5 | FILES=$(find src -name *hpp -or -name *cpp | grep -v contrib) 6 | ${CLANG_FORMAT} -i -style=file ${FILES} 7 | 8 | echo "Done." 9 | 10 | -------------------------------------------------------------------------------- /scripts/build-app-image: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Builds AppImage in Docker 4 | 5 | HEIMER_VERSION=4.5.0 6 | 7 | CMD="export LANG=en_US.UTF-8 && \ 8 | export LC_ALL=en_US.UTF-8 && \ 9 | rm -rf /heimer-build-appimage && mkdir -p /heimer/build-appimage && \ 10 | cd /heimer/build-appimage && \ 11 | cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTS=OFF -DPACKAGE_TYPE=AppImage && \ 12 | make -j$(nproc) && \ 13 | make DESTDIR=appdir -j$(nproc) install && find appdir/ && \ 14 | wget -c -nv "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" && \ 15 | chmod a+x linuxdeployqt-continuous-x86_64.AppImage && \ 16 | unset QTDIR && unset QT_PLUGIN_PATH && unset LD_LIBRARY_PATH && \ 17 | export VERSION=${HEIMER_VERSION} && \ 18 | ./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -bundle-non-qt-libs && \ 19 | ./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -appimage" 20 | 21 | if [ -f /.dockerenv ]; then 22 | echo "Script inside Docker" 23 | bash -c "${CMD}" 24 | else 25 | echo "Script outside Docker" 26 | docker run --privileged -t -v $(pwd):/heimer juzzlin/qt5-18.04:latest bash -c "${CMD}" 27 | fi 28 | 29 | -------------------------------------------------------------------------------- /scripts/build-archive: -------------------------------------------------------------------------------- 1 | git archive --format=tar.gz --prefix=heimer-4.5.0/ HEAD > heimer-4.5.0.tar.gz 2 | -------------------------------------------------------------------------------- /scripts/build-snap-lxd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Builds Snap package with LXD. Assumes Ubuntu 20.04 LTS. 4 | 5 | rm -f *.snap && snapcraft clean --use-lxd && snapcraft --use-lxd 6 | 7 | -------------------------------------------------------------------------------- /scripts/build-snap-multipass: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Builds Snap package with multipass. Assumes Ubuntu 20.04 LTS. 4 | 5 | rm -f *.snap && snapcraft --provider multipass clean && snapcraft --provider multipass 6 | 7 | -------------------------------------------------------------------------------- /scripts/build-windows-nsis: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Builds NSIS installer for Windows in Docker 4 | 5 | CMAKE=/mxe/usr/bin/i686-w64-mingw32.static-cmake 6 | CPACK=/mxe/usr/bin/i686-w64-mingw32.static-cpack 7 | 8 | CMD="export LANG=en_US.UTF-8 && \ 9 | export LC_ALL=en_US.UTF-8 && \ 10 | export PATH='$PATH':/mxe/usr/bin && \ 11 | export CCACHE_DISABLE=1 && \ 12 | cd /heimer && \ 13 | rm -rf build-windows-nsis && mkdir -p build-windows-nsis && \ 14 | cd build-windows-nsis && ${CMAKE} -GNinja -DBUILD_WITH_QT6=ON -DPACKAGE_TYPE=NSIS .. && \ 15 | ninja && ${CPACK} -G NSIS" 16 | 17 | if [ -f /.dockerenv ]; then 18 | echo "Script inside Docker" 19 | bash -c "${CMD}" 20 | else 21 | echo "Script outside Docker" 22 | docker run --user $(id -u):$(id -g) -t -v $(pwd):/heimer juzzlin/mxe-qt6-22.04:latest bash -c "${CMD}" 23 | fi 24 | 25 | -------------------------------------------------------------------------------- /scripts/build-windows-zip: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Builds ZIP archive for Windows in Docker 4 | 5 | VERSION=4.5.0 6 | 7 | CMAKE=/mxe/usr/bin/i686-w64-mingw32.static-cmake 8 | 9 | CMD="export LANG=en_US.UTF-8 && \ 10 | export LC_ALL=en_US.UTF-8 && \ 11 | export PATH='$PATH':/mxe/usr/bin && \ 12 | export CCACHE_DISABLE=1 && \ 13 | cd /heimer && \ 14 | rm -rf build-windows-zip && mkdir -p build-windows-zip && \ 15 | cd build-windows-zip && ${CMAKE} -GNinja -DBUILD_WITH_QT6=ON -DPACKAGE_TYPE=ZIP .. && \ 16 | ninja && \ 17 | mkdir zip && cd zip && \ 18 | cp -v ../AUTHORS . && \ 19 | cp -v ../CHANGELOG . && \ 20 | cp -v ../COPYING . && \ 21 | cp -v ../README.md . && \ 22 | cp -v ../heimer.exe . && \ 23 | zip -r heimer-${VERSION}-win32.zip *" 24 | 25 | if [ -f /.dockerenv ]; then 26 | echo "Script inside Docker" 27 | bash -c "${CMD}" 28 | else 29 | echo "Script outside Docker" 30 | docker run --user $(id -u):$(id -g) -t -v $(pwd):/heimer juzzlin/mxe-qt6-22.04:latest bash -c "${CMD}" 31 | fi 32 | 33 | -------------------------------------------------------------------------------- /scripts/copy-artifacts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import os 5 | import shutil 6 | import glob 7 | 8 | # Define the file patterns to be copied 9 | filePatterns = ["build-deb-ubuntu-18.04/heimer*.deb", 10 | "build-deb-ubuntu-20.04/heimer*.deb", 11 | "build-deb-ubuntu-22.04-qt5/heimer*.deb", 12 | "build-deb-ubuntu-22.04-qt6/heimer*.deb", 13 | "build-appimage/Heimer*.AppImage", 14 | "build-windows-nsis/heimer*win32.exe", 15 | "build-windows-zip/zip/heimer*-win32.zip", 16 | "*.tar.gz"] 17 | 18 | def copyFiles(sourceDir, targetDir): 19 | 20 | # Create the target directory if it doesn't exist 21 | if not os.path.exists(targetDir): 22 | os.makedirs(targetDir) 23 | 24 | # Copy files matching the patterns from the source directory to the target directory 25 | for pattern in filePatterns: 26 | files = glob.glob(os.path.join(sourceDir, pattern)) 27 | for filePath in files: 28 | fileName = os.path.basename(filePath) 29 | targetPath = os.path.join(targetDir, fileName) 30 | shutil.copy2(filePath, targetPath) 31 | print(f"Copied '{fileName}' to '{targetDir}'") 32 | 33 | def main(): 34 | 35 | # Parse command-line arguments 36 | parser = argparse.ArgumentParser(description="Copy files from source directory to target directory") 37 | parser.add_argument("-s", "--source", required=True, help="Source directory path") 38 | parser.add_argument("-t", "--target", required=True, help="Target directory path") 39 | 40 | args = parser.parse_args() 41 | copyFiles(args.source, args.target) 42 | 43 | if __name__ == "__main__": 44 | main() 45 | print("Done.") 46 | 47 | -------------------------------------------------------------------------------- /scripts/update-version: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Updates Heimer version in all build and packaging scripts. 4 | # Must be run in the project root. 5 | 6 | VERSION_MAJOR=$1 7 | VERSION_MINOR=$2 8 | VERSION_PATCH=$3 9 | 10 | if [[ ! $1 || ! $2 || ! $3 ]]; then 11 | echo "Usage: $0 VERSION_MAJOR VERSION_MINOR VERSION_PATCH" 12 | exit 1 13 | fi 14 | 15 | FILE=CMakeLists.txt 16 | echo "Updating ${FILE} .." 17 | sed -i "s/^set(APPLICATION_VERSION_MAJOR.*/set(APPLICATION_VERSION_MAJOR ${VERSION_MAJOR})/" ${FILE} || exit 1 18 | sed -i "s/^set(APPLICATION_VERSION_MINOR.*/set(APPLICATION_VERSION_MINOR ${VERSION_MINOR})/" ${FILE} || exit 1 19 | sed -i "s/^set(APPLICATION_VERSION_PATCH.*/set(APPLICATION_VERSION_PATCH ${VERSION_PATCH})/" ${FILE} || exit 1 20 | 21 | for FILE in snapcraft.yaml scripts/build-app-image scripts/build-archive scripts/build-windows-zip; do 22 | echo "Updating ${FILE} .." 23 | sed -i -E "s/[0-9]+\.[0-9]+\.[0-9]+/$VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH/g" ${FILE} || exit 1 24 | done 25 | 26 | git diff 27 | 28 | echo "Done." 29 | 30 | -------------------------------------------------------------------------------- /scripts/upload-snap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import os 5 | import subprocess 6 | 7 | def copyAndUploadSnap(snapBuildPath): 8 | 9 | # Find the latest SNAP file in the SNAP_BUILD_PATH directory 10 | snapFiles = sorted([file for file in os.listdir(snapBuildPath) if file.startswith("heimer") and file.endswith(".snap")]) 11 | if not snapFiles: 12 | print("No SNAP files found in the specified directory.") 13 | exit(1) 14 | 15 | latestSnapFile = os.path.join(snapBuildPath, snapFiles[-1]) 16 | 17 | # Copy the latest SNAP file to the current directory 18 | try: 19 | subprocess.check_output(["cp", "-v", latestSnapFile, "./"]) 20 | except subprocess.CalledProcessError: 21 | print("Failed to copy the SNAP file.") 22 | exit(1) 23 | 24 | snapFileName = os.path.basename(latestSnapFile) 25 | 26 | # Upload the SNAP file using snapcraft 27 | try: 28 | subprocess.check_output(["snapcraft", "upload", "--release=stable", snapFileName]) 29 | except subprocess.CalledProcessError: 30 | print("Failed to upload the SNAP file.") 31 | exit(1) 32 | 33 | def main(): 34 | 35 | # Parse command-line arguments 36 | parser = argparse.ArgumentParser(description="Copy and upload the latest SNAP file") 37 | parser.add_argument("-s", "--snap-build-path", required=True, help="SNAP build directory path") 38 | args = parser.parse_args() 39 | 40 | # Call the copyAndUploadSnap function with the provided SNAP build path 41 | copyAndUploadSnap(args.snap_build_path) 42 | 43 | if __name__ == '__main__': 44 | main() 45 | print("Done.") 46 | 47 | -------------------------------------------------------------------------------- /snapcraft.yaml: -------------------------------------------------------------------------------- 1 | name: heimer 2 | version: '4.5.0' 3 | summary: Heimer is a simple cross-platform mind map tool. 4 | description: | 5 | Heimer is a simple cross-platform mind map creation tool. 6 | Emphasis on easy diagram creation, simplicity, and speed. 7 | grade: stable 8 | confinement: strict 9 | base: core20 10 | icon: data/icons/heimer.png 11 | 12 | apps: 13 | heimer: 14 | command: bin/desktop-launch heimer 15 | environment: 16 | DISABLE_WAYLAND: 1 # UI completely broken on Ubuntu 22.04 without this 17 | desktop: usr/share/applications/heimer.desktop 18 | plugs: [home, desktop, desktop-legacy, removable-media, unity7, x11, wayland, opengl] 19 | 20 | plugs: # additional plug to fix mouse cursor theme 21 | icon-themes: 22 | interface: content 23 | target: $SNAP/data-dir/icons 24 | default-provider: gtk-common-themes 25 | 26 | parts: 27 | desktop-qt5: 28 | source: https://github.com/ubuntu/snapcraft-desktop-helpers.git 29 | source-subdir: qt 30 | plugin: make 31 | make-parameters: ["FLAVOR=qt5"] 32 | build-packages: 33 | - build-essential 34 | - qtbase5-dev 35 | - dpkg-dev 36 | stage-packages: 37 | - libxkbcommon0 38 | - ttf-ubuntu-font-family 39 | - dmz-cursor-theme 40 | - light-themes 41 | - adwaita-icon-theme 42 | - gnome-themes-standard 43 | - shared-mime-info 44 | - libqt5gui5 45 | - libgdk-pixbuf2.0-0 46 | - libqt5xml5 47 | - libqt5svg5 # for loading icon themes which are svg 48 | - locales-all 49 | - xdg-user-dirs 50 | - fcitx-frontend-qt5 51 | - qt5-style-plugins # for mouse cursor theme fix 52 | - qtwayland5 # Needed in Ubuntu 22.04 53 | gnu-heimer: 54 | source: . 55 | plugin: cmake 56 | cmake-parameters: 57 | - -DCMAKE_BUILD_TYPE=Release 58 | - -DCMAKE_INSTALL_PREFIX=/usr 59 | - -DBUILD_TESTS=OFF 60 | - -DPACKAGE_TYPE=Snap 61 | build-packages: 62 | - qtbase5-dev 63 | - qttools5-dev 64 | - qttools5-dev-tools 65 | - libqt5svg5-dev 66 | stage-packages: 67 | - libqt5gui5 68 | - libqt5svg5 69 | - libqt5xml5 70 | after: [desktop-qt5] 71 | override-prime: | 72 | set -eu 73 | 74 | snapcraftctl prime 75 | 76 | # Fix-up application icon lookup 77 | sed --in-place 's|^Icon=.*|Icon=\${SNAP}/meta/gui/icon.png|' usr/share/applications/heimer.desktop 78 | -------------------------------------------------------------------------------- /src/application/control_strategy.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "control_strategy.hpp" 17 | 18 | #include "service_container.hpp" 19 | #include "settings_proxy.hpp" 20 | 21 | #include 22 | #include 23 | 24 | ControlStrategy::ControlStrategy() 25 | { 26 | } 27 | 28 | bool ControlStrategy::isModifierPressed() const 29 | { 30 | return (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier) || // 31 | QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)); 32 | } 33 | 34 | bool ControlStrategy::backgroundDragInitiated(QMouseEvent & event) const 35 | { 36 | const bool invertedControls = SC::instance().settingsProxy()->invertedControls(); 37 | 38 | return (invertedControls == isModifierPressed()) && event.button() == Qt::LeftButton; 39 | } 40 | 41 | bool ControlStrategy::rubberBandInitiated(QMouseEvent & event) const 42 | { 43 | const bool invertedControls = SC::instance().settingsProxy()->invertedControls(); 44 | 45 | return ((!invertedControls ^ !isModifierPressed()) && (event.button() == Qt::LeftButton)) || event.button() == Qt::MiddleButton; 46 | } 47 | 48 | bool ControlStrategy::primaryButtonClicked(QMouseEvent & event) const 49 | { 50 | return event.button() == Qt::LeftButton; 51 | } 52 | 53 | bool ControlStrategy::secondaryButtonClicked(QMouseEvent & event) const 54 | { 55 | return event.button() == Qt::RightButton; 56 | } 57 | 58 | void ControlStrategy::setInvertedMode(bool invertedMode) 59 | { 60 | m_invertedMode = invertedMode; 61 | } 62 | 63 | QString ControlStrategy::mirrorLayoutHorizontallyShortcut() const 64 | { 65 | return "Ctrl+Shift+H"; 66 | } 67 | 68 | QString ControlStrategy::mirrorLayoutVerticallyShortcut() const 69 | { 70 | return "Ctrl+Shift+V"; 71 | } 72 | 73 | ControlStrategy::~ControlStrategy() = default; 74 | -------------------------------------------------------------------------------- /src/application/control_strategy.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef CONTROL_STRATEGY_HPP 17 | #define CONTROL_STRATEGY_HPP 18 | 19 | class QMouseEvent; 20 | class QString; 21 | 22 | class ControlStrategy 23 | { 24 | public: 25 | ControlStrategy(); 26 | 27 | virtual ~ControlStrategy(); 28 | 29 | bool backgroundDragInitiated(QMouseEvent & event) const; 30 | 31 | bool rubberBandInitiated(QMouseEvent & event) const; 32 | 33 | bool primaryButtonClicked(QMouseEvent & event) const; 34 | 35 | bool secondaryButtonClicked(QMouseEvent & event) const; 36 | 37 | void setInvertedMode(bool invertedMode); 38 | 39 | QString mirrorLayoutHorizontallyShortcut() const; 40 | 41 | QString mirrorLayoutVerticallyShortcut() const; 42 | 43 | private: 44 | bool isModifierPressed() const; 45 | 46 | bool m_invertedMode = false; 47 | }; 48 | 49 | #endif // CONTROL_STRATEGY_HPP 50 | -------------------------------------------------------------------------------- /src/application/hash_seed.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "hash_seed.hpp" 17 | 18 | void HashSeed::init() 19 | { 20 | #if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) 21 | qt_qhash_seed.store(0); 22 | #else 23 | #if QT_VERSION < QT_VERSION_CHECK(6, 2, 0) 24 | qSetGlobalQHashSeed(0); 25 | #else 26 | QHashSeed::setDeterministicGlobalSeed(); 27 | #endif 28 | #endif 29 | } 30 | -------------------------------------------------------------------------------- /src/application/hash_seed.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef HASH_SEED_HPP 17 | #define HASH_SEED_HPP 18 | 19 | #include 20 | 21 | #if QT_VERSION < 0x50600 22 | extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; 23 | #endif 24 | 25 | namespace HashSeed { 26 | 27 | void init(); 28 | 29 | } // namespace HashSeed 30 | 31 | #endif // HASH_SEED_HPP 32 | -------------------------------------------------------------------------------- /src/application/language_service.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2024 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef LANGUAGE_SERVICE_HPP 17 | #define LANGUAGE_SERVICE_HPP 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | class QCoreApplication; 24 | 25 | class LanguageService : public QObject 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | QString activeLanguage() const; 31 | 32 | void setActiveLanguage(QString activeLanguage); 33 | 34 | QString commandLineLanguage() const; 35 | 36 | void setCommandLineLanguage(QString cliLanguage); 37 | 38 | void initializeTranslations(QCoreApplication & application); 39 | 40 | QStringList selectableLanguages() const; 41 | 42 | QStringList selectableLanguagesWithoutActiveLanguage() const; 43 | 44 | QStringList uiLanguages() const; 45 | 46 | QString savedUserLanguage() const; 47 | 48 | signals: 49 | void activeLanguageChanged(QString language); 50 | 51 | private: 52 | QStringList commandLineLanguageOrSavedLanguageOrAvailableSystemUiLanguages() const; 53 | 54 | void installTranslatorForApplicationTranslations(QCoreApplication & application, QStringList languages); 55 | 56 | void installTranslatorForBuiltInQtTranslations(QCoreApplication & application, QStringList languages); 57 | 58 | QString m_activeLanguage; 59 | 60 | QString m_commandLineLanguage; 61 | 62 | QTranslator m_appTranslator; 63 | 64 | QTranslator m_qtTranslator; 65 | }; 66 | 67 | #endif // LANGUAGE_SERVICE_HPP 68 | -------------------------------------------------------------------------------- /src/application/progress_manager.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "progress_manager.hpp" 17 | 18 | #include 19 | 20 | ProgressManager::ProgressManager() = default; 21 | 22 | ProgressManager::~ProgressManager() = default; 23 | 24 | void ProgressManager::updateProgress() 25 | { 26 | if (m_enabled) { 27 | QApplication::processEvents(); 28 | } 29 | } 30 | 31 | void ProgressManager::setEnabled(bool enabled) 32 | { 33 | m_enabled = enabled; 34 | } 35 | -------------------------------------------------------------------------------- /src/application/progress_manager.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef PROGRESS_MANAGER_HPP 17 | #define PROGRESS_MANAGER_HPP 18 | 19 | //! Useless wrapper class for processing graphics thread events. 20 | class ProgressManager 21 | { 22 | public: 23 | ProgressManager(); 24 | 25 | ~ProgressManager(); 26 | 27 | void updateProgress(); 28 | 29 | void setEnabled(bool enabled); 30 | 31 | private: 32 | ProgressManager(const ProgressManager & other) = delete; 33 | 34 | ProgressManager & operator=(const ProgressManager & other) = delete; 35 | 36 | bool m_enabled = false; 37 | }; 38 | 39 | #endif // PROGRESS_MANAGER_HPP 40 | -------------------------------------------------------------------------------- /src/application/recent_files_manager.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "recent_files_manager.hpp" 17 | 18 | #include "../infra/settings.hpp" 19 | 20 | #include "contrib/SimpleLogger/src/simple_logger.hpp" 21 | 22 | #include 23 | #include 24 | 25 | static const auto TAG = "RecentFilesManager"; 26 | 27 | RecentFilesManager::RecentFilesManager() 28 | { 29 | m_recentFiles = Settings::Custom::loadRecentFiles(); 30 | } 31 | 32 | void RecentFilesManager::addRecentFile(QString filePath) 33 | { 34 | const QFileInfo fi(filePath); 35 | 36 | filePath = fi.absoluteFilePath(); 37 | 38 | m_recentFiles.removeAll(filePath); 39 | m_recentFiles.push_front(filePath); 40 | 41 | const int maxFileCount = 8; 42 | while (m_recentFiles.size() > maxFileCount) { 43 | m_recentFiles.pop_back(); 44 | } 45 | 46 | juzzlin::L(TAG).debug() << "Added recent file: " << filePath.toStdString(); 47 | juzzlin::L(TAG).debug() << "Recent file count: " << m_recentFiles.size(); 48 | 49 | Settings::Custom::saveRecentFiles(m_recentFiles); 50 | } 51 | 52 | std::optional RecentFilesManager::recentFile() const 53 | { 54 | return !m_recentFiles.empty() ? m_recentFiles.at(0) : std::optional {}; 55 | } 56 | 57 | QStringList RecentFilesManager::recentFiles() const 58 | { 59 | return m_recentFiles; 60 | } 61 | 62 | bool RecentFilesManager::hasRecentFiles() const 63 | { 64 | return !m_recentFiles.empty(); 65 | } 66 | 67 | void RecentFilesManager::setSelectedFile(QString selectedFile) 68 | { 69 | juzzlin::L(TAG).debug() << "Recent file selected: " << selectedFile.toStdString(); 70 | 71 | m_selectedFile = selectedFile; 72 | } 73 | 74 | QString RecentFilesManager::selectedFile() const 75 | { 76 | return m_selectedFile; 77 | } 78 | -------------------------------------------------------------------------------- /src/application/recent_files_manager.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef RECENT_FILES_MANAGER_HPP 17 | #define RECENT_FILES_MANAGER_HPP 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | class RecentFilesManager : public QObject 26 | { 27 | public: 28 | RecentFilesManager(); 29 | 30 | std::optional recentFile() const; 31 | 32 | QStringList recentFiles() const; 33 | 34 | bool hasRecentFiles() const; 35 | 36 | QString selectedFile() const; 37 | 38 | public slots: 39 | void addRecentFile(QString filePath); 40 | 41 | void setSelectedFile(QString filePath); 42 | 43 | private: 44 | QStringList m_recentFiles; 45 | 46 | QString m_selectedFile; 47 | }; 48 | 49 | #endif // RECENT_FILES_MANAGER_HPP 50 | -------------------------------------------------------------------------------- /src/application/service_container.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef SERVICE_CONTAINER_HPP 17 | #define SERVICE_CONTAINER_HPP 18 | 19 | #include "../common/types.hpp" 20 | 21 | class ApplicationService; 22 | class EditorService; 23 | class ControlStrategy; 24 | class LanguageService; 25 | class RecentFilesManager; 26 | 27 | class ProgressManager; 28 | class SettingsProxy; 29 | 30 | //! A poor man's single instance DI. 31 | class ServiceContainer 32 | { 33 | public: 34 | ServiceContainer(); 35 | 36 | ~ServiceContainer(); 37 | 38 | static ServiceContainer & instance(); 39 | 40 | ApplicationServiceS applicationService(); 41 | 42 | ControlStrategyS controlStrategy(); 43 | 44 | LanguageServiceS languageService(); 45 | 46 | ProgressManagerS progressManager() const; 47 | 48 | RecentFilesManagerS recentFilesManager() const; 49 | 50 | SettingsProxyS settingsProxy(); 51 | 52 | void setMainWindow(MainWindowS mainWindow); 53 | 54 | private: 55 | ServiceContainer(const ServiceContainer & other) = delete; 56 | 57 | ServiceContainer & operator=(const ServiceContainer & other) = delete; 58 | 59 | SettingsProxyS m_settingsProxy; 60 | 61 | ApplicationServiceS m_applicationService; 62 | 63 | ControlStrategyS m_controlStrategy; 64 | 65 | LanguageServiceS m_languageService; 66 | 67 | ProgressManagerS m_progressManager; 68 | 69 | RecentFilesManagerS m_recentFilesManager; 70 | 71 | MainWindowS m_mainWindow; 72 | 73 | static ServiceContainer * m_instance; 74 | }; 75 | 76 | #endif // SERVICE_CONTAINER_HPP 77 | -------------------------------------------------------------------------------- /src/application/user_exception.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef USER_EXCEPTION_HPP 17 | #define USER_EXCEPTION_HPP 18 | 19 | #include 20 | #include 21 | 22 | class UserException : public std::runtime_error 23 | { 24 | public: 25 | explicit UserException(std::string msg) 26 | : runtime_error(msg) 27 | { 28 | } 29 | }; 30 | 31 | #endif // USER_EXCEPTION_HPP 32 | -------------------------------------------------------------------------------- /src/common/test_mode.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "test_mode.hpp" 17 | 18 | #include "simple_logger.hpp" 19 | 20 | static const auto TAG = "TestMode"; 21 | 22 | bool TestMode::m_enabled = false; 23 | 24 | bool TestMode::enabled() 25 | { 26 | return m_enabled; 27 | } 28 | 29 | void TestMode::setEnabled(bool testModeEnabled) 30 | { 31 | m_enabled = testModeEnabled; 32 | } 33 | 34 | void TestMode::logDisabledCode(const std::string & message) 35 | { 36 | juzzlin::L(TAG).debug() << "TestMode: '" << message << "' disabled"; 37 | } 38 | -------------------------------------------------------------------------------- /src/common/test_mode.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef TEST_MODE_HPP 17 | #define TEST_MODE_HPP 18 | 19 | #include 20 | 21 | class TestMode 22 | { 23 | public: 24 | static bool enabled(); 25 | 26 | static void setEnabled(bool enabled); 27 | 28 | static void logDisabledCode(const std::string & message); 29 | 30 | private: 31 | static bool m_enabled; 32 | }; 33 | 34 | #endif // TEST_MODE_HPP 35 | -------------------------------------------------------------------------------- /src/common/types.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef TYPES_HPP 17 | #define TYPES_HPP 18 | 19 | #include 20 | 21 | class ApplicationService; 22 | using ApplicationServiceS = std::shared_ptr; 23 | 24 | class ControlStrategy; 25 | 26 | using ControlStrategyS = std::shared_ptr; 27 | 28 | class EditorService; 29 | 30 | using EditorServiceS = std::shared_ptr; 31 | 32 | class LanguageService; 33 | 34 | using LanguageServiceS = std::shared_ptr; 35 | 36 | namespace SceneItems { 37 | class Edge; 38 | } 39 | 40 | using EdgeCR = const SceneItems::Edge &; 41 | 42 | using EdgeP = SceneItems::Edge *; 43 | 44 | using EdgeR = SceneItems::Edge &; 45 | 46 | using EdgeS = std::shared_ptr; 47 | 48 | using EdgeU = std::unique_ptr; 49 | 50 | class Graph; 51 | class MindMapData; 52 | class ProgressManager; 53 | class SettingsProxy; 54 | 55 | using GraphCR = const Graph &; 56 | 57 | using GraphR = Graph &; 58 | 59 | class MainWindow; 60 | using MainWindowS = std::shared_ptr; 61 | 62 | using MindMapDataR = MindMapData &; 63 | 64 | using MindMapDataCR = const MindMapData &; 65 | 66 | using MindMapDataS = std::shared_ptr; 67 | 68 | using MindMapDataU = std::unique_ptr; 69 | 70 | namespace SceneItems { 71 | class Node; 72 | } 73 | 74 | using NodeCR = const SceneItems::Node &; 75 | 76 | using NodeP = SceneItems::Node *; 77 | 78 | using NodeR = SceneItems::Node &; 79 | 80 | using NodeS = std::shared_ptr; 81 | 82 | using NodeU = std::unique_ptr; 83 | 84 | using ProgressManagerS = std::shared_ptr; 85 | 86 | class RecentFilesManager; 87 | using RecentFilesManagerS = std::shared_ptr; 88 | 89 | using SettingsProxyS = std::shared_ptr; 90 | 91 | class ServiceContainer; 92 | using SC = ServiceContainer; 93 | 94 | #endif // TYPES_HPP 95 | -------------------------------------------------------------------------------- /src/common/utils.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef UTILS_HPP 17 | #define UTILS_HPP 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace Utils { 24 | 25 | size_t tsMs(); 26 | 27 | bool isColorBright(QColor color); 28 | 29 | QFont::Weight intToFontWeight(int value); 30 | 31 | QString exportFileName(QString mindMapFileName, QString exportExtension); 32 | 33 | bool fileExists(QString filePath); 34 | 35 | int fontWeightToInt(QFont::Weight value); 36 | 37 | int fontWeightToInt(int value); 38 | 39 | QColor mixedColor(QColor color1, QColor color2, double balance); 40 | 41 | } // namespace Utils 42 | 43 | #endif // UTILS_HPP 44 | -------------------------------------------------------------------------------- /src/contrib/Argengine/.clang-format: -------------------------------------------------------------------------------- 1 | AccessModifierOffset: -4 2 | AlignAfterOpenBracket: true 3 | AllowShortFunctionsOnASingleLine: false 4 | AlwaysBreakTemplateDeclarations: true 5 | BasedOnStyle: WebKit 6 | BreakBeforeBinaryOperators: NonAssignment 7 | BreakBeforeBraces: Custom 8 | BreakConstructorInitializersBeforeComma: false 9 | BreakConstructorInitializers: BeforeComma 10 | BraceWrapping: 11 | AfterClass: true 12 | AfterControlStatement: false 13 | AfterEnum: true 14 | AfterFunction: true 15 | AfterNamespace: false 16 | AfterObjCDeclaration: false 17 | AfterStruct: true 18 | AfterUnion: false 19 | BeforeCatch: false 20 | BeforeElse: false 21 | IndentBraces: false 22 | ColumnLimit: 0 23 | CommentPragmas: "^!|^:" 24 | CompactNamespaces: false 25 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 26 | ConstructorInitializerIndentWidth: 2 27 | ContinuationIndentWidth: 2 28 | FixNamespaceComments: true 29 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ] 30 | IndentWidth: 4 31 | NamespaceIndentation: None 32 | PointerAlignment: Middle 33 | PointerBindsToType: false 34 | SortIncludes: true 35 | SpaceAfterTemplateKeyword: false 36 | Standard: Cpp11 37 | 38 | -------------------------------------------------------------------------------- /src/contrib/Argengine/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | 3 | -------------------------------------------------------------------------------- /src/contrib/Argengine/CHANGELOG: -------------------------------------------------------------------------------- 1 | x.y.z 2 | ===== 3 | 4 | Release date: 5 | 6 | New features: 7 | 8 | Bug fixes: 9 | 10 | Other: 11 | 12 | 1.2.0 13 | ===== 14 | 15 | Release date: 16 | 17 | Sun, 15 Oct 2023 22:29:51 +0300 18 | 19 | New features: 20 | 21 | * Fix GitHub Issue #1: Implement conflicting options 22 | 23 | 1.1.1 24 | ===== 25 | 26 | Release date: 27 | 28 | Tue, 06 Sep 2022 18:30:37 -0000 29 | 30 | Bug fixes: 31 | 32 | * Fix typo in the unknown option error message 33 | 34 | Other: 35 | 36 | * Fix GitHub Issue #5: Add documentation of option info texts 37 | * Update documentation of ex1 38 | 39 | 1.1.0 40 | ===== 41 | 42 | New features: 43 | 44 | * Fix GitHub Issue #2: Configurable value names for help 45 | * Add getter for help text 46 | 47 | 1.0.1 48 | ===== 49 | 50 | Bug fixes: 51 | 52 | * Fix include path in tests 53 | 54 | 1.0.0 55 | ===== 56 | 57 | New features: 58 | 59 | * Enable/disable tests on top level 60 | * Build shared and static libs 61 | 62 | Other: 63 | 64 | * Documentation updates 65 | 66 | 0.0.1 67 | ===== 68 | 69 | Initial release. 70 | 71 | New features: 72 | 73 | * Valueless options 74 | * Single-value options 75 | * Help generation 76 | 77 | -------------------------------------------------------------------------------- /src/contrib/Argengine/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(Argengine) 2 | 3 | cmake_minimum_required(VERSION 2.8.12) 4 | cmake_policy(VERSION 2.8.12) 5 | 6 | option(BUILD_EXAMPLES "Build example apps" ON) 7 | 8 | option(BUILD_TESTS "Build unit tests" ON) 9 | 10 | # Default to release C++ flags if CMAKE_BUILD_TYPE not set 11 | if(NOT CMAKE_BUILD_TYPE) 12 | set(CMAKE_BUILD_TYPE Release CACHE STRING 13 | "Choose the type of build, options are: None Debug Release RelWithDebInfo 14 | MinSizeRel." FORCE) 15 | endif() 16 | 17 | set(CMAKE_CXX_STANDARD 17) 18 | 19 | if(CMAKE_COMPILER_IS_GNUCXX OR MINGW OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") 20 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") 21 | 22 | # CMAKE_CXX_STANDARD supported only by versions >= 3.1 23 | if (CMAKE_VERSION VERSION_LESS "3.1") 24 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") 25 | endif () 26 | endif() 27 | 28 | set(LIBRARY_NAME "Argengine") 29 | 30 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 31 | 32 | if(BUILD_TESTS) 33 | enable_testing() 34 | add_subdirectory(src/tests) 35 | endif() 36 | 37 | add_subdirectory(src) 38 | 39 | -------------------------------------------------------------------------------- /src/contrib/Argengine/Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent any 3 | stages { 4 | stage('CMake Debug build') { 5 | agent { 6 | docker { 7 | image 'juzzlin/qt5-18.04:latest' 8 | args '--privileged -t -v $WORKSPACE:/Argengine' 9 | } 10 | } 11 | steps { 12 | sh "mkdir -p build-debug" 13 | sh "cd build-debug && cmake -DCMAKE_BUILD_TYPE=Debug .." 14 | sh "cd build-debug && cmake --build . --target all -- -j3 && ctest" 15 | } 16 | } 17 | stage('CMake Release build') { 18 | agent { 19 | docker { 20 | image 'juzzlin/qt5-18.04:latest' 21 | args '--privileged -t -v $WORKSPACE:/Argengine' 22 | } 23 | } 24 | steps { 25 | sh "mkdir -p build-release" 26 | sh "cd build-release && cmake -DCMAKE_BUILD_TYPE=Release .." 27 | sh "cd build-release && cmake --build . --target all -- -j3 && ctest" 28 | } 29 | } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/contrib/Argengine/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Jussi Lind 4 | 5 | https://github.com/juzzlin/Argengine 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SRC argengine.cpp) 2 | set(HDR argengine.hpp) 3 | 4 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 5 | 6 | add_library(ArgengineLib OBJECT ${SRC}) 7 | set_property(TARGET ArgengineLib PROPERTY POSITION_INDEPENDENT_CODE 1) 8 | 9 | set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) 10 | 11 | add_library(${LIBRARY_NAME} SHARED $) 12 | set_target_properties(${LIBRARY_NAME} PROPERTIES PUBLIC_HEADER ${HDR}) 13 | install(TARGETS ${LIBRARY_NAME} 14 | ARCHIVE DESTINATION lib 15 | LIBRARY DESTINATION lib 16 | PUBLIC_HEADER DESTINATION include 17 | ) 18 | 19 | set(STATIC_LIBRARY_NAME ${LIBRARY_NAME}_static) 20 | add_library(${STATIC_LIBRARY_NAME} STATIC $) 21 | set_target_properties(${STATIC_LIBRARY_NAME} PROPERTIES PUBLIC_HEADER ${HDR}) 22 | install(TARGETS ${STATIC_LIBRARY_NAME} 23 | ARCHIVE DESTINATION lib 24 | LIBRARY DESTINATION lib 25 | PUBLIC_HEADER DESTINATION include 26 | ) 27 | 28 | if(BUILD_EXAMPLES) 29 | add_subdirectory(examples) 30 | endif() 31 | 32 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(ex1) 2 | add_subdirectory(ex2) 3 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/examples/ex1/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(ARGENGINE_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${ARGENGINE} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | 4 | set(NAME ex1) 5 | set(SRC ${NAME}.cpp) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) 8 | add_executable(${NAME} ${SRC}) 9 | target_link_libraries(${NAME} ${LIBRARY_NAME}) 10 | 11 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/examples/ex2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(ARGENGINE_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${ARGENGINE} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | 4 | set(NAME ex2) 5 | set(SRC ${NAME}.cpp) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) 8 | add_executable(${NAME} ${SRC}) 9 | target_link_libraries(${NAME} ${LIBRARY_NAME}) 10 | 11 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/examples/ex2/ex2.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2023 Jussi Lind 4 | // 5 | // https://github.com/juzzlin/Argengine 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all 15 | // copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | // SOFTWARE. 24 | 25 | #include "argengine.hpp" 26 | 27 | #include 28 | #include 29 | 30 | using juzzlin::Argengine; 31 | 32 | // 33 | // Ex2: Demonstrate conflicting options. 34 | // 35 | 36 | int main(int argc, char ** argv) 37 | { 38 | // Instantiate Argengine and give it the raw argument data. 39 | Argengine ae(argc, argv); 40 | 41 | // Add a minimal dummy option "foo". 42 | ae.addOption( 43 | { "foo" }, [] { 44 | std::cout << "Foo enabled!" << std::endl; 45 | }); 46 | 47 | // Add a minimal dummy option "bar". 48 | ae.addOption( 49 | { "bar" }, [] { 50 | std::cout << "Bar enabled!" << std::endl; 51 | }); 52 | 53 | // Set "foo" and "bar" as conflicting options. 54 | ae.addConflictingOptions({ "foo", "bar" }); 55 | 56 | // Parse the arguments and store possible error to variable error. 57 | Argengine::Error error; 58 | ae.parse(error); 59 | 60 | // Check error and print the possible error message. 61 | if (error.code != Argengine::Error::Code::Ok) { 62 | std::cerr << error.message << std::endl 63 | << std::endl; 64 | ae.printHelp(); // Print the auto-generated help. 65 | return EXIT_FAILURE; 66 | } 67 | 68 | return EXIT_SUCCESS; 69 | } 70 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(conflicting_arguments_test) 2 | add_subdirectory(help_test) 3 | add_subdirectory(positional_argument_test) 4 | add_subdirectory(single_value_test) 5 | add_subdirectory(unknown_argument_test) 6 | add_subdirectory(valueless_test) 7 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/tests/conflicting_arguments_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(ARGENGINE_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${ARGENGINE} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | 4 | set(NAME conflicting_arguments_test) 5 | set(SRC ${NAME}.cpp) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) 8 | add_executable(${NAME} ${SRC}) 9 | add_test(${NAME} ${CMAKE_BINARY_DIR}/tests/${NAME}) 10 | target_link_libraries(${NAME} ${LIBRARY_NAME}) 11 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/tests/help_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(ARGENGINE_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${ARGENGINE} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | 4 | set(NAME help_test) 5 | set(SRC ${NAME}.cpp) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) 8 | add_executable(${NAME} ${SRC}) 9 | add_test(${NAME} ${CMAKE_BINARY_DIR}/tests/${NAME}) 10 | target_link_libraries(${NAME} ${LIBRARY_NAME}) 11 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/tests/positional_argument_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(ARGENGINE_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${ARGENGINE} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | 4 | set(NAME positional_argument_test) 5 | set(SRC ${NAME}.cpp) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) 8 | add_executable(${NAME} ${SRC}) 9 | add_test(${NAME} ${CMAKE_BINARY_DIR}/tests/${NAME}) 10 | target_link_libraries(${NAME} ${LIBRARY_NAME}) 11 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/tests/single_value_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(ARGENGINE_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${ARGENGINE} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | 4 | set(NAME single_value_test) 5 | set(SRC ${NAME}.cpp) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) 8 | add_executable(${NAME} ${SRC}) 9 | add_test(${NAME} ${CMAKE_BINARY_DIR}/tests/${NAME}) 10 | target_link_libraries(${NAME} ${LIBRARY_NAME}) 11 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/tests/unknown_argument_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(ARGENGINE_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${ARGENGINE} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | 4 | set(NAME unknown_argument_test) 5 | set(SRC ${NAME}.cpp) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) 8 | add_executable(${NAME} ${SRC}) 9 | add_test(${NAME} ${CMAKE_BINARY_DIR}/tests/${NAME}) 10 | target_link_libraries(${NAME} ${LIBRARY_NAME}) 11 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/tests/unknown_argument_test/unknown_argument_test.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Jussi Lind 4 | // 5 | // https://github.com/juzzlin/Argengine 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all 15 | // copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | // SOFTWARE. 24 | 25 | #include "../../argengine.hpp" 26 | 27 | // Don't compile asserts away 28 | #ifdef NDEBUG 29 | #undef NDEBUG 30 | #endif 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | using juzzlin::Argengine; 38 | 39 | const auto name = "Argengine"; 40 | 41 | void testUnknownArgumentBehavior_ShouldThrow() 42 | { 43 | Argengine ae({ "test", "--foo2" }); 44 | ae.addOption({ "--bar" }, [] { 45 | }); 46 | 47 | std::string error; 48 | try { 49 | ae.parse(); 50 | } catch (std::runtime_error & e) { 51 | error = e.what(); 52 | } 53 | assert(error == std::string(name) + ": Unknown option '" + ae.arguments().at(1) + "'!"); 54 | } 55 | 56 | void testUnknownArgument_SingleValueAssignment_ShouldThrow() 57 | { 58 | Argengine ae({ "test", "--foo=42" }); 59 | ae.addOption({ "--bar" }, [](std::string) { 60 | }); 61 | 62 | std::string error; 63 | try { 64 | ae.parse(); 65 | } catch (std::runtime_error & e) { 66 | error = e.what(); 67 | } 68 | assert(error == std::string(name) + ": Unknown option '--foo=42'!"); 69 | } 70 | 71 | int main(int, char **) 72 | { 73 | testUnknownArgumentBehavior_ShouldThrow(); 74 | 75 | testUnknownArgument_SingleValueAssignment_ShouldThrow(); 76 | 77 | return EXIT_SUCCESS; 78 | } 79 | -------------------------------------------------------------------------------- /src/contrib/Argengine/src/tests/valueless_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(ARGENGINE_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${ARGENGINE} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | 4 | set(NAME valueless_test) 5 | set(SRC ${NAME}.cpp) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) 8 | add_executable(${NAME} ${SRC}) 9 | add_test(${NAME} ${CMAKE_BINARY_DIR}/tests/${NAME}) 10 | target_link_libraries(${NAME} ${LIBRARY_NAME}) 11 | -------------------------------------------------------------------------------- /src/contrib/SimpleLogger/.clang-format: -------------------------------------------------------------------------------- 1 | AccessModifierOffset: -4 2 | AlignAfterOpenBracket: true 3 | AllowShortFunctionsOnASingleLine: false 4 | AlwaysBreakTemplateDeclarations: true 5 | BasedOnStyle: WebKit 6 | BreakBeforeBinaryOperators: NonAssignment 7 | BreakBeforeBraces: Custom 8 | BreakConstructorInitializersBeforeComma: false 9 | BreakConstructorInitializers: BeforeComma 10 | BraceWrapping: 11 | AfterClass: true 12 | AfterControlStatement: false 13 | AfterEnum: true 14 | AfterFunction: true 15 | AfterNamespace: false 16 | AfterObjCDeclaration: false 17 | AfterStruct: true 18 | AfterUnion: false 19 | BeforeCatch: false 20 | BeforeElse: false 21 | IndentBraces: false 22 | ColumnLimit: 0 23 | CommentPragmas: "^!|^:" 24 | CompactNamespaces: false 25 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 26 | ConstructorInitializerIndentWidth: 2 27 | ContinuationIndentWidth: 2 28 | FixNamespaceComments: true 29 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ] 30 | IndentWidth: 4 31 | NamespaceIndentation: None 32 | PointerAlignment: Middle 33 | PointerBindsToType: false 34 | SortIncludes: true 35 | SpaceAfterTemplateKeyword: false 36 | Standard: Cpp11 37 | 38 | -------------------------------------------------------------------------------- /src/contrib/SimpleLogger/CHANGELOG: -------------------------------------------------------------------------------- 1 | 2.0.0 2 | ===== 3 | 4 | New features: 5 | 6 | * Fix GitHub Issue #5: Add support for tags 7 | * Add support for customized timestamp format 8 | * Add ISODateTime option to TimestampMode 9 | 10 | Other: 11 | 12 | * Add SimpleLogger::setTimestampSeparator() 13 | * Rename init() to initialize() 14 | * Rename Logger to SimpleLogger 15 | * Require C++17 16 | 17 | 1.4.0 18 | ===== 19 | 20 | New features: 21 | 22 | * Fix GitHub Issue #1: Make the streams configurable 23 | * Add getter for version 24 | 25 | Other: 26 | 27 | * Use std::recursive_mutex 28 | 29 | 1.3.1 30 | ===== 31 | 32 | Bug fixes: 33 | 34 | * Explicitly include chrono 35 | 36 | 1.3.0 37 | ===== 38 | 39 | New features: 40 | 41 | * Fix GitHub Issue #6: Add option to use a microsecond timestamp 42 | - More generic setTimestampMode() replaces enableDateTime() 43 | 44 | 1.2.0 - "Thread-safe Taco" 45 | ========================== 46 | 47 | New features: 48 | 49 | * Make logging thread-safe 50 | 51 | Other changes: 52 | 53 | * Add simple hello world test 54 | 55 | 1.1.0 - "Rename Renegade" 56 | ========================= 57 | 58 | Other changes: 59 | 60 | * Rename src/logger.* to src/simple_logger.* 61 | 62 | 1.0.0 - "Basic Beast" 63 | ===================== 64 | 65 | New features: 66 | 67 | * Based on RAII 68 | * Configurable level symbols 69 | * Date / time 70 | * Logging levels: Trace, Debug, Info, Warning, Error, Fatal 71 | * Log to file and/or console 72 | 73 | -------------------------------------------------------------------------------- /src/contrib/SimpleLogger/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | cmake_policy(VERSION 3.10) 3 | 4 | project(SimpleLogger) 5 | 6 | option(BUILD_TESTS "Build unit tests" ON) 7 | 8 | # Default to release C++ flags if CMAKE_BUILD_TYPE not set 9 | if(NOT CMAKE_BUILD_TYPE) 10 | set(CMAKE_BUILD_TYPE Release CACHE STRING 11 | "Choose the type of build, options are: None Debug Release RelWithDebInfo 12 | MinSizeRel." FORCE) 13 | endif() 14 | 15 | set(CMAKE_CXX_STANDARD 17) 16 | 17 | if(CMAKE_COMPILER_IS_GNUCXX OR MINGW OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") 18 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") 19 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") 20 | endif() 21 | 22 | set(LIBRARY_NAME "SimpleLogger") 23 | 24 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 25 | 26 | if(BUILD_TESTS) 27 | enable_testing() 28 | add_subdirectory(src/tests) 29 | endif() 30 | 31 | add_subdirectory(src) 32 | 33 | -------------------------------------------------------------------------------- /src/contrib/SimpleLogger/Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent none 3 | stages { 4 | stage('Matrix Build') { 5 | matrix { 6 | axes { 7 | axis { 8 | name 'IMAGE' 9 | values 'qt5-20.04', 'qt6-22.04', 'qt6-24.04' 10 | } 11 | axis { 12 | name 'BUILD_TYPE' 13 | values 'Debug', 'Release' 14 | } 15 | } 16 | stages { 17 | stage('Build and Test') { 18 | agent any 19 | steps { 20 | script { 21 | docker.image("juzzlin/${IMAGE}:latest").inside('--privileged -t -v $WORKSPACE:/Argengine') { 22 | def buildDir = "build-${BUILD_TYPE.toLowerCase()}-${IMAGE}" 23 | sh "mkdir -p ${buildDir}" 24 | sh "cd ${buildDir} && cmake -GNinja -DCMAKE_BUILD_TYPE=${BUILD_TYPE} .." 25 | sh "cd ${buildDir} && cmake --build . && ctest" 26 | } 27 | } 28 | } 29 | } 30 | } 31 | } 32 | } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/contrib/SimpleLogger/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jussi Lind 4 | 5 | https://github.com/juzzlin/SimpleLogger 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /src/contrib/SimpleLogger/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SRC simple_logger.cpp) 2 | set(HDR simple_logger.hpp) 3 | 4 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 5 | 6 | add_library(SimpleLoggerLib OBJECT ${SRC}) 7 | set_property(TARGET SimpleLoggerLib PROPERTY POSITION_INDEPENDENT_CODE 1) 8 | 9 | set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) 10 | 11 | add_library(${LIBRARY_NAME} SHARED $) 12 | set_target_properties(${LIBRARY_NAME} PROPERTIES PUBLIC_HEADER ${HDR}) 13 | install(TARGETS ${LIBRARY_NAME} 14 | ARCHIVE DESTINATION lib 15 | LIBRARY DESTINATION lib 16 | PUBLIC_HEADER DESTINATION include 17 | ) 18 | 19 | set(STATIC_LIBRARY_NAME ${LIBRARY_NAME}_static) 20 | add_library(${STATIC_LIBRARY_NAME} STATIC $) 21 | set_target_properties(${STATIC_LIBRARY_NAME} PROPERTIES PUBLIC_HEADER ${HDR}) 22 | install(TARGETS ${STATIC_LIBRARY_NAME} 23 | ARCHIVE DESTINATION lib 24 | LIBRARY DESTINATION lib 25 | PUBLIC_HEADER DESTINATION include 26 | ) 27 | -------------------------------------------------------------------------------- /src/contrib/SimpleLogger/src/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(file_test) 2 | add_subdirectory(stream_test) 3 | -------------------------------------------------------------------------------- /src/contrib/SimpleLogger/src/tests/file_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SIMPLE_LOGGER_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${SIMPLE_LOGGER_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | 4 | set(NAME file_test) 5 | set(SRC ${NAME}.cpp) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) 8 | add_executable(${NAME} ${SRC}) 9 | add_test(${NAME} ${CMAKE_BINARY_DIR}/tests/${NAME}) 10 | target_link_libraries(${NAME} ${LIBRARY_NAME}) 11 | -------------------------------------------------------------------------------- /src/contrib/SimpleLogger/src/tests/stream_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SIMPLE_LOGGER_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${SIMPLE_LOGGER_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | 4 | set(NAME stream_test) 5 | set(SRC ${NAME}.cpp) 6 | 7 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) 8 | add_executable(${NAME} ${SRC}) 9 | add_test(${NAME} ${CMAKE_BINARY_DIR}/tests/${NAME}) 10 | target_link_libraries(${NAME} ${LIBRARY_NAME}) 11 | -------------------------------------------------------------------------------- /src/domain/copy_context.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef COPY_CONTEXT_HPP 17 | #define COPY_CONTEXT_HPP 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "../common/types.hpp" 24 | 25 | class CopyContext 26 | { 27 | public: 28 | CopyContext(); 29 | 30 | void clear(); 31 | 32 | size_t copyStackSize() const; 33 | 34 | using NodePVector = std::vector; 35 | void push(NodePVector nodes, GraphCR graph); 36 | void push(NodeCR node); 37 | 38 | //! Store node indices into a separate metadata structure 39 | //! because Edge instances currently need references to 40 | //! the actual node instances and we are working with copies 41 | //! here.. 42 | struct EdgeMetadata 43 | { 44 | EdgeMetadata(EdgeS edge, int sourceNodeIndex, int targetNodeIndex) 45 | : edge(edge) 46 | , sourceNodeIndex(sourceNodeIndex) 47 | , targetNodeIndex(targetNodeIndex) 48 | { 49 | } 50 | 51 | EdgeS edge; 52 | 53 | int sourceNodeIndex = -1; 54 | 55 | int targetNodeIndex = -1; 56 | }; 57 | 58 | using EdgeVector = std::vector; 59 | using NodeVector = std::vector; 60 | 61 | struct CopiedData 62 | { 63 | QPointF copyReferencePoint; 64 | 65 | EdgeVector edges; 66 | 67 | NodeVector nodes; 68 | }; 69 | 70 | CopiedData copiedData() const; 71 | 72 | private: 73 | CopyContext(const CopyContext & other) = delete; 74 | CopyContext & operator=(const CopyContext & other) = delete; 75 | 76 | void pushEdges(NodePVector nodes, GraphCR graph); 77 | 78 | CopiedData m_copiedData; 79 | }; 80 | 81 | #endif // COPY_CONTEXT_HPP 82 | -------------------------------------------------------------------------------- /src/domain/image.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "image.hpp" 17 | 18 | Image::Image() 19 | { 20 | } 21 | 22 | Image::Image(QImage image, std::string path) 23 | : m_image(image) 24 | , m_path(path) 25 | { 26 | } 27 | 28 | QImage Image::image() const 29 | { 30 | return m_image; 31 | } 32 | 33 | std::string Image::path() const 34 | { 35 | return m_path; 36 | } 37 | 38 | size_t Image::id() const 39 | { 40 | return m_id; 41 | } 42 | 43 | void Image::setId(size_t id) 44 | { 45 | m_id = id; 46 | } 47 | -------------------------------------------------------------------------------- /src/domain/image.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef IMAGE_HPP 17 | #define IMAGE_HPP 18 | 19 | #include 20 | 21 | #include 22 | 23 | class Image 24 | { 25 | public: 26 | Image(); 27 | 28 | Image(QImage image, std::string path); 29 | 30 | QImage image() const; 31 | 32 | std::string path() const; 33 | 34 | size_t id() const; 35 | 36 | void setId(size_t id); 37 | 38 | private: 39 | QImage m_image; 40 | 41 | std::string m_path; 42 | 43 | size_t m_id = 0; 44 | }; 45 | 46 | #endif // IMAGE_HPP 47 | -------------------------------------------------------------------------------- /src/domain/image_manager.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef IMAGE_MANAGER_HPP 17 | #define IMAGE_MANAGER_HPP 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "../common/types.hpp" 25 | #include "image.hpp" 26 | 27 | class ImageManager : public QObject 28 | { 29 | Q_OBJECT 30 | 31 | public: 32 | ImageManager(); 33 | 34 | ImageManager(const ImageManager & other); 35 | 36 | ImageManager & operator=(const ImageManager & other); 37 | 38 | size_t addImage(const Image & image); 39 | 40 | void setImage(const Image & image); 41 | 42 | std::optional getImage(size_t id); 43 | 44 | void handleImageRequest(size_t id, NodeR node); 45 | 46 | using ImageVector = std::vector; 47 | ImageVector images() const; 48 | 49 | private: 50 | std::map m_images; 51 | 52 | size_t m_count = 0; 53 | }; 54 | 55 | #endif // IMAGE_MANAGER_HPP 56 | -------------------------------------------------------------------------------- /src/domain/layout_optimizer.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef LAYOUT_OPTIMIZER_HPP 17 | #define LAYOUT_OPTIMIZER_HPP 18 | 19 | #include 20 | #include 21 | 22 | #include "../common/types.hpp" 23 | 24 | class Grid; 25 | 26 | class LayoutOptimizer 27 | { 28 | public: 29 | LayoutOptimizer(MindMapDataS mindMapData, const Grid & grid); 30 | 31 | ~LayoutOptimizer(); 32 | 33 | bool initialize(double aspectRatio, double minEdgeLength); 34 | 35 | struct OptimizationInfo 36 | { 37 | double acceptRatio = 0; 38 | 39 | double currentCost = 0; 40 | 41 | double finalCost = 0; 42 | 43 | double initialCost = 0; 44 | 45 | double tC = 0; 46 | 47 | double t0 = 0; 48 | 49 | double t1 = 0.05; 50 | 51 | double cS = 0.7; 52 | 53 | size_t accepts = 0; 54 | 55 | size_t changes = 0; 56 | 57 | size_t rejects = 0; 58 | 59 | size_t sliceSize = 0; 60 | 61 | size_t stuckLimit = 5; 62 | 63 | double stuckTh = 0.1; 64 | }; 65 | 66 | OptimizationInfo optimize(); 67 | 68 | void extract(); 69 | 70 | using ProgressCallback = std::function; 71 | void setProgressCallback(ProgressCallback progressCallback); 72 | 73 | private: 74 | class Impl; 75 | std::unique_ptr m_impl; 76 | }; 77 | 78 | #endif // LAYOUT_OPTIMIZER_HPP 79 | -------------------------------------------------------------------------------- /src/domain/mind_map_data_base.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "mind_map_data_base.hpp" 17 | 18 | MindMapDataBase::MindMapDataBase(QString name) 19 | : m_name(name) 20 | { 21 | } 22 | 23 | MindMapDataBase::MindMapDataBase(const MindMapDataBase & other) 24 | : m_name(other.m_name) 25 | { 26 | } 27 | 28 | QString MindMapDataBase::name() const 29 | { 30 | return m_name; 31 | } 32 | 33 | unsigned int MindMapDataBase::index() const 34 | { 35 | return m_index; 36 | } 37 | 38 | void MindMapDataBase::setName(QString name) 39 | { 40 | m_name = name; 41 | } 42 | 43 | void MindMapDataBase::setIndex(unsigned int index) 44 | { 45 | m_index = index; 46 | } 47 | 48 | MindMapDataBase::~MindMapDataBase() = default; 49 | -------------------------------------------------------------------------------- /src/domain/mind_map_stats.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef MIND_MAP_STATS_HPP 17 | #define MIND_MAP_STATS_HPP 18 | 19 | #include 20 | 21 | struct MindMapStats 22 | { 23 | std::optional averageEdgeLength; 24 | 25 | std::optional layoutAspectRatio; 26 | 27 | std::optional maximumEdgeLength; 28 | 29 | std::optional minimumEdgeLength; 30 | }; 31 | 32 | #endif // MIND_MAP_STATS_HPP 33 | -------------------------------------------------------------------------------- /src/domain/undo_stack.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "undo_stack.hpp" 17 | 18 | #include "mind_map_data.hpp" 19 | 20 | UndoStack::UndoStack(size_t maxHistorySize) 21 | : m_maxHistorySize(maxHistorySize) 22 | { 23 | } 24 | 25 | void UndoStack::pushUndoPoint(MindMapDataCR mindMapData) 26 | { 27 | m_undoStack.push_back(std::make_unique(mindMapData)); 28 | 29 | if (m_undoStack.size() > m_maxHistorySize && m_maxHistorySize) { 30 | m_undoStack.pop_front(); 31 | } 32 | } 33 | 34 | void UndoStack::pushRedoPoint(MindMapDataCR mindMapData) 35 | { 36 | m_redoStack.push_back(std::make_unique(mindMapData)); 37 | 38 | if (m_redoStack.size() > m_maxHistorySize && m_maxHistorySize) { 39 | m_redoStack.pop_front(); 40 | } 41 | } 42 | 43 | void UndoStack::clear() 44 | { 45 | m_undoStack.clear(); 46 | m_redoStack.clear(); 47 | } 48 | 49 | void UndoStack::clearRedoStack() 50 | { 51 | m_redoStack.clear(); 52 | } 53 | 54 | bool UndoStack::isUndoable() const 55 | { 56 | return !m_undoStack.empty(); 57 | } 58 | 59 | MindMapDataU UndoStack::undo() 60 | { 61 | if (isUndoable()) { 62 | auto head = std::move(m_undoStack.back()); 63 | m_undoStack.pop_back(); 64 | return head; 65 | } 66 | 67 | return {}; 68 | } 69 | 70 | bool UndoStack::isRedoable() const 71 | { 72 | return !m_redoStack.empty(); 73 | } 74 | 75 | MindMapDataU UndoStack::redo() 76 | { 77 | if (isRedoable()) { 78 | auto head = std::move(m_redoStack.back()); 79 | m_redoStack.pop_back(); 80 | return head; 81 | } 82 | 83 | return {}; 84 | } 85 | -------------------------------------------------------------------------------- /src/domain/undo_stack.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef UNDO_STACK_HPP 17 | #define UNDO_STACK_HPP 18 | 19 | #include "../common/types.hpp" 20 | 21 | #include 22 | 23 | class UndoStack 24 | { 25 | public: 26 | //! \param maxHistorySize The size of undo stack or 0 for "unlimited". 27 | UndoStack(size_t maxHistorySize = 0); 28 | 29 | void pushUndoPoint(MindMapDataCR mindMapData); 30 | 31 | void pushRedoPoint(MindMapDataCR mindMapData); 32 | 33 | void clear(); 34 | 35 | void clearRedoStack(); 36 | 37 | bool isUndoable() const; 38 | 39 | MindMapDataU undo(); 40 | 41 | bool isRedoable() const; 42 | 43 | MindMapDataU redo(); 44 | 45 | private: 46 | using MindMapDataVector = std::list; 47 | 48 | MindMapDataVector m_undoStack; 49 | 50 | MindMapDataVector m_redoStack; 51 | 52 | size_t m_maxHistorySize; 53 | }; 54 | 55 | #endif // UNDO_STACK_HPP 56 | -------------------------------------------------------------------------------- /src/heimer.appdata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | heimer.desktop 4 | CC0-1.0 5 | GPL-3.0 and CC BY-SA-3.0 6 | Heimer 7 | An application for mind map creation and management. 8 | 9 |

10 | Heimer is an application for mind map creation and management written in Qt (C++). 11 |

12 |
13 | 14 | 15 | https://juzzlin.github.io/Heimer/ 16 | jussi.lind@iki.fi 17 |
18 | -------------------------------------------------------------------------------- /src/heimer.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Heimer 3 | GenericName=Mind map application 4 | Comment=Mind map application 5 | Exec=heimer 6 | Icon=heimer 7 | Type=Application 8 | Categories=Education; 9 | StartupNotify=true 10 | 11 | -------------------------------------------------------------------------------- /src/infra/export_params.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include 17 | #include 18 | 19 | struct ExportParams 20 | { 21 | ExportParams(QString fileName) 22 | : fileName(fileName) 23 | { 24 | } 25 | 26 | ExportParams(QString fileName, QSize imageSize, bool transparentBackground) 27 | : fileName(fileName) 28 | , imageSize(imageSize) 29 | , transparentBackground(transparentBackground) 30 | { 31 | } 32 | 33 | QString fileName; 34 | 35 | QSize imageSize; 36 | 37 | bool transparentBackground = false; 38 | }; 39 | -------------------------------------------------------------------------------- /src/infra/io/alz_file_io.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "alz_file_io.hpp" 17 | 18 | #include "../../domain/mind_map_data.hpp" 19 | #include "alz_file_io_worker.hpp" 20 | 21 | #include 22 | #include 23 | 24 | Q_DECLARE_METATYPE(MindMapDataS) 25 | 26 | namespace IO { 27 | 28 | AlzFileIO::AlzFileIO(AlzFormatVersion outputVersion) 29 | : m_worker(std::make_unique(outputVersion)) 30 | , m_workerThread(std::make_unique()) 31 | { 32 | qRegisterMetaType(); 33 | 34 | if (!m_workerThread->isRunning()) { 35 | m_workerThread->start(); 36 | m_worker->moveToThread(m_workerThread.get()); 37 | } 38 | } 39 | 40 | void AlzFileIO::finish() 41 | { 42 | m_workerThread->quit(); 43 | m_workerThread->wait(); 44 | } 45 | 46 | MindMapDataU AlzFileIO::fromFile(QString path) const 47 | { 48 | return m_worker->fromFile(path); 49 | } 50 | 51 | bool AlzFileIO::toFile(MindMapDataS mindMapData, QString path, bool async) const 52 | { 53 | const auto connectionType = async ? Qt::QueuedConnection : Qt::BlockingQueuedConnection; 54 | 55 | return QMetaObject::invokeMethod(m_worker.get(), "toFile", connectionType, 56 | Q_ARG(MindMapDataS, mindMapData), 57 | Q_ARG(QString, path)); 58 | } 59 | 60 | MindMapDataU AlzFileIO::fromXml(QString xml) const 61 | { 62 | return m_worker->fromXml(xml); 63 | } 64 | 65 | QString AlzFileIO::toXml(MindMapDataS mindMapData) const 66 | { 67 | return m_worker->toXml(mindMapData); 68 | } 69 | 70 | AlzFileIO::~AlzFileIO() 71 | { 72 | AlzFileIO::finish(); 73 | } 74 | 75 | } // namespace IO 76 | -------------------------------------------------------------------------------- /src/infra/io/alz_file_io.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef ALZ_FILE_IO_HPP 17 | #define ALZ_FILE_IO_HPP 18 | 19 | #include "../../common/types.hpp" 20 | #include "alz_file_io_version.hpp" 21 | #include "file_io.hpp" 22 | 23 | #include 24 | 25 | class QThread; 26 | 27 | namespace IO { 28 | 29 | class AlzFileIOWorker; 30 | 31 | class AlzFileIO : public FileIO 32 | { 33 | public: 34 | explicit AlzFileIO(AlzFormatVersion outputVersion = AlzFormatVersion::V2); 35 | 36 | ~AlzFileIO(); 37 | 38 | void finish() override; 39 | 40 | MindMapDataU fromFile(QString path) const override; 41 | 42 | bool toFile(MindMapDataS mindMapData, QString path, bool async) const override; 43 | 44 | MindMapDataU fromXml(QString xml) const; 45 | 46 | QString toXml(MindMapDataS mindMapData) const; 47 | 48 | private: 49 | std::unique_ptr m_worker; 50 | 51 | std::unique_ptr m_workerThread; 52 | }; 53 | 54 | } // namespace IO 55 | 56 | #endif // ALZ_FILE_IO_HPP 57 | -------------------------------------------------------------------------------- /src/infra/io/alz_file_io_version.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef ALZ_FILE_IO_VERSION_HPP 17 | #define ALZ_FILE_IO_VERSION_HPP 18 | 19 | namespace IO { 20 | 21 | enum class AlzFormatVersion 22 | { 23 | V1 = 1, 24 | V2 = 2 25 | }; 26 | 27 | } // namespace IO 28 | 29 | #endif // ALZ_FILE_IO_VERSION_HPP 30 | -------------------------------------------------------------------------------- /src/infra/io/alz_file_io_worker.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef ALZ_FILE_IO_WORKER_HPP 17 | #define ALZ_FILE_IO_WORKER_HPP 18 | 19 | #include 20 | #include 21 | 22 | #include "alz_file_io_version.hpp" 23 | 24 | #include "../../common/types.hpp" 25 | 26 | namespace IO { 27 | 28 | class AlzFileIOWorker : public QObject 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | explicit AlzFileIOWorker(AlzFormatVersion outputVersion); 34 | 35 | ~AlzFileIOWorker() override; 36 | 37 | public slots: 38 | 39 | MindMapDataU fromFile(QString path) const; 40 | 41 | bool toFile(MindMapDataS mindMapData, QString path) const; 42 | 43 | MindMapDataU fromXml(QString xml) const; 44 | 45 | QString toXml(MindMapDataS mindMapData) const; 46 | 47 | private: 48 | AlzFormatVersion m_outputVersion; 49 | }; 50 | 51 | } // namespace IO 52 | 53 | #endif // ALZ_FILE_IO_WORKER_HPP 54 | -------------------------------------------------------------------------------- /src/infra/io/file_exception.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef FILE_EXCEPTION_HPP 17 | #define FILE_EXCEPTION_HPP 18 | 19 | #include 20 | #include 21 | 22 | namespace IO { 23 | 24 | class FileException : public std::runtime_error 25 | { 26 | public: 27 | explicit FileException(QString msg) 28 | : runtime_error(msg.toStdString()) 29 | , m_message(msg) 30 | { 31 | } 32 | 33 | QString message() const 34 | { 35 | return m_message; 36 | } 37 | 38 | private: 39 | QString m_message; 40 | }; 41 | 42 | } // namespace IO 43 | 44 | #endif // FILE_EXCEPTION_HPP 45 | -------------------------------------------------------------------------------- /src/infra/io/file_io.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef FILE_IO_HPP 17 | #define FILE_IO_HPP 18 | 19 | #include 20 | 21 | #include "../../common/types.hpp" 22 | 23 | namespace IO { 24 | 25 | class FileIO 26 | { 27 | public: 28 | virtual void finish() = 0; 29 | 30 | virtual MindMapDataU fromFile(QString path) const = 0; 31 | 32 | virtual bool toFile(MindMapDataS mindMapData, QString path, bool async) const = 0; 33 | }; 34 | 35 | } // namespace IO 36 | 37 | #endif // FILE_IO_HPP 38 | -------------------------------------------------------------------------------- /src/infra/io/xml_reader.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "xml_reader.hpp" 17 | 18 | #include "file_exception.hpp" 19 | 20 | #include 21 | #include 22 | 23 | namespace IO { 24 | 25 | QDomDocument XmlReader::readFromFile(QString filePath) 26 | { 27 | QDomDocument doc; 28 | 29 | QFile file(filePath); 30 | if (!file.open(QIODevice::ReadOnly)) { 31 | throw FileException(QObject::tr("Cannot open file: '") + filePath + "'"); 32 | } 33 | 34 | if (!doc.setContent(&file)) { 35 | file.close(); 36 | 37 | throw FileException(QObject::tr("Corrupted file: '") + filePath + "'"); 38 | } 39 | 40 | file.close(); 41 | 42 | return doc; 43 | } 44 | 45 | } // namespace IO 46 | -------------------------------------------------------------------------------- /src/infra/io/xml_reader.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef XML_READER_HPP 17 | #define XML_READER_HPP 18 | 19 | #include 20 | 21 | namespace IO::XmlReader { 22 | QDomDocument readFromFile(QString filePath); 23 | } 24 | 25 | #endif // XML_READER_HPP 26 | -------------------------------------------------------------------------------- /src/infra/io/xml_writer.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "xml_writer.hpp" 17 | 18 | #include 19 | #include 20 | 21 | namespace IO { 22 | 23 | bool XmlWriter::writeToFile(QDomDocument document, QString filePath) 24 | { 25 | QFile file(filePath); 26 | if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { 27 | QTextStream out(&file); 28 | out << document; 29 | file.close(); 30 | return true; 31 | } 32 | 33 | return false; 34 | } 35 | 36 | } // namespace IO 37 | -------------------------------------------------------------------------------- /src/infra/io/xml_writer.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef XML_WRITER_HPP 17 | #define XML_WRITER_HPP 18 | 19 | #include 20 | 21 | namespace IO::XmlWriter { 22 | bool writeToFile(QDomDocument document, QString filePath); 23 | } 24 | 25 | #endif // XML_WRITER_HPP 26 | -------------------------------------------------------------------------------- /src/infra/version_checker.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef VERSION_CHECKER_HPP 17 | #define VERSION_CHECKER_HPP 18 | 19 | #include 20 | 21 | #include "../application/version.hpp" 22 | 23 | class VersionChecker : public QObject 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | explicit VersionChecker(QObject * parent = nullptr); 29 | 30 | void checkForNewReleases(); 31 | 32 | signals: 33 | void newVersionFound(Version version, QString downloadUrl); 34 | }; 35 | 36 | #endif // VERSION_CHECKER_HPP 37 | -------------------------------------------------------------------------------- /src/translations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juzzlin/Heimer/4381ff76ce8df9225d5e431fd9b677c0834c3492/src/translations/.gitkeep -------------------------------------------------------------------------------- /src/unit_tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../contrib/SimpleLogger/src) 2 | set(UNIT_TEST_BASE_DIR ${CMAKE_BINARY_DIR}/unit_tests) 3 | add_subdirectory(alz_file_io_test) 4 | add_subdirectory(editor_service_test) 5 | add_subdirectory(graph_test) 6 | add_subdirectory(layout_optimizer_test) 7 | add_subdirectory(node_test) 8 | add_subdirectory(selection_group_test) 9 | add_subdirectory(version_test) 10 | -------------------------------------------------------------------------------- /src/unit_tests/alz_file_io_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(EDITOR_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${EDITOR_DIR} ${EDITOR_DIR}/contrib ${CMAKE_CURRENT_SOURCE_DIR}) 3 | set(NAME alz_file_io_test) 4 | set(SRC ../unit_test_base.cpp ${NAME}.hpp ${NAME}.cpp) 5 | add_executable(${NAME} ${SRC} ${MOC_SRC}) 6 | set_target_properties(${NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${UNIT_TEST_BASE_DIR}) 7 | add_test(${NAME} ${UNIT_TEST_BASE_DIR}/${NAME}) 8 | target_link_libraries(${NAME} ${HEIMER_LIB_NAME} Qt${QT_VERSION_MAJOR}::Xml Qt${QT_VERSION_MAJOR}::Test) 9 | -------------------------------------------------------------------------------- /src/unit_tests/editor_service_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(EDITOR_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${EDITOR_DIR} ${EDITOR_DIR}/contrib ${CMAKE_CURRENT_SOURCE_DIR}) 3 | set(NAME editor_service_test) 4 | set(SRC ../unit_test_base.cpp ${NAME}.cpp ${NAME}.hpp) 5 | add_executable(${NAME} ${SRC} ${MOC_SRC}) 6 | set_target_properties(${NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${UNIT_TEST_BASE_DIR}) 7 | add_test(${NAME} ${UNIT_TEST_BASE_DIR}/${NAME}) 8 | target_link_libraries(${NAME} ${HEIMER_LIB_NAME} Qt${QT_VERSION_MAJOR}::Test) 9 | -------------------------------------------------------------------------------- /src/unit_tests/graph_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(EDITOR_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${EDITOR_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | set(NAME graph_test) 4 | set(SRC ../unit_test_base.cpp ${NAME}.cpp ${NAME}.hpp) 5 | add_executable(${NAME} ${SRC} ${MOC_SRC}) 6 | set_target_properties(${NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${UNIT_TEST_BASE_DIR}) 7 | add_test(${NAME} ${UNIT_TEST_BASE_DIR}/${NAME}) 8 | target_link_libraries(${NAME} ${HEIMER_LIB_NAME} ${CORE_LIB_NAME} Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Test) 9 | -------------------------------------------------------------------------------- /src/unit_tests/graph_test/graph_test.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef GRAPH_TEST_HPP 17 | #define GRAPH_TEST_HPP 18 | 19 | #include 20 | 21 | #include "../unit_test_base.hpp" 22 | 23 | class GraphTest : public UnitTestBase 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | GraphTest(); 29 | 30 | private slots: 31 | 32 | void testAddEdge(); 33 | 34 | void testAddNode(); 35 | 36 | void testAddTwoNodes(); 37 | 38 | void testAreNodesDirectlyConnected(); 39 | 40 | void testDeleteEdge(); 41 | 42 | void testDeleteNode(); 43 | 44 | void testDeleteNodeInvolvingEdge(); 45 | 46 | void testGetEdges(); 47 | 48 | void testGetNodes(); 49 | 50 | void testGetNodesConnectedToNode(); 51 | 52 | void testGetNodeByIndex(); 53 | 54 | void testGetNodeByIndex_NotFound(); 55 | }; 56 | 57 | #endif // GRAPH_TEST_HPP 58 | -------------------------------------------------------------------------------- /src/unit_tests/layout_optimizer_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(EDITOR_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${EDITOR_DIR} ${EDITOR_DIR}/contrib ${CMAKE_CURRENT_SOURCE_DIR}) 3 | set(NAME layout_optimizer_test) 4 | set(SRC ../unit_test_base.cpp ${NAME}.cpp ${NAME}.hpp) 5 | add_executable(${NAME} ${SRC} ${MOC_SRC}) 6 | set_target_properties(${NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${UNIT_TEST_BASE_DIR}) 7 | add_test(${NAME} ${UNIT_TEST_BASE_DIR}/${NAME}) 8 | target_link_libraries(${NAME} ${HEIMER_LIB_NAME} Qt${QT_VERSION_MAJOR}::Test) 9 | -------------------------------------------------------------------------------- /src/unit_tests/layout_optimizer_test/layout_optimizer_test.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef LAYOUT_OPTIMIZER_TEST_HPP 17 | #define LAYOUT_OPTIMIZER_TEST_HPP 18 | 19 | #include 20 | 21 | #include "../unit_test_base.hpp" 22 | 23 | class LayoutOptimizerTest : public UnitTestBase 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | LayoutOptimizerTest(); 29 | 30 | private slots: 31 | 32 | void testNoNodes_ShouldNotInitialize(); 33 | 34 | void testSingleNode_ShouldNotDoAnything(); 35 | 36 | void testMultipleNodes_ShouldReduceCost(); 37 | 38 | void testMultipleNodes_NoEdges_ShouldSpread(); 39 | }; 40 | 41 | #endif // LAYOUT_OPTIMIZER_TEST_HPP 42 | -------------------------------------------------------------------------------- /src/unit_tests/node_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(EDITOR_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${EDITOR_DIR} ${EDITOR_DIR}/contrib ${CMAKE_CURRENT_SOURCE_DIR}) 3 | set(NAME node_test) 4 | set(SRC ../unit_test_base.cpp ${NAME}.cpp ${NAME}.hpp) 5 | add_executable(${NAME} ${SRC} ${MOC_SRC}) 6 | set_target_properties(${NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${UNIT_TEST_BASE_DIR}) 7 | add_test(${NAME} ${UNIT_TEST_BASE_DIR}/${NAME}) 8 | target_link_libraries(${NAME} ${HEIMER_LIB_NAME} Qt${QT_VERSION_MAJOR}::Test) 9 | -------------------------------------------------------------------------------- /src/unit_tests/node_test/node_test.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "node_test.hpp" 17 | 18 | #include "../../common/test_mode.hpp" 19 | #include "../../view/scene_items/node.hpp" 20 | 21 | using SceneItems::Node; 22 | 23 | NodeTest::NodeTest() 24 | { 25 | TestMode::setEnabled(true); 26 | } 27 | 28 | void NodeTest::testContainsText() 29 | { 30 | Node node; 31 | node.setText("Foobar"); 32 | QVERIFY(node.containsText("Foobar")); 33 | QVERIFY(node.containsText("foobar")); 34 | QVERIFY(node.containsText("foo")); 35 | QVERIFY(node.containsText("bar")); 36 | } 37 | 38 | QTEST_GUILESS_MAIN(NodeTest) 39 | -------------------------------------------------------------------------------- /src/unit_tests/node_test/node_test.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef NODE_TEST_HPP 17 | #define NODE_TEST_HPP 18 | 19 | #include 20 | 21 | #include "../unit_test_base.hpp" 22 | 23 | class NodeTest : public UnitTestBase 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | NodeTest(); 29 | 30 | private slots: 31 | 32 | void testContainsText(); 33 | }; 34 | 35 | #endif // NODE_TEST_HPP 36 | -------------------------------------------------------------------------------- /src/unit_tests/selection_group_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(EDITOR_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${EDITOR_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) 3 | set(NAME selection_group_test) 4 | set(SRC ../unit_test_base.cpp ${NAME}.cpp ${NAME}.hpp) 5 | add_executable(${NAME} ${SRC} ${MOC_SRC}) 6 | set_target_properties(${NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${UNIT_TEST_BASE_DIR}) 7 | add_test(${NAME} ${UNIT_TEST_BASE_DIR}/${NAME}) 8 | target_link_libraries(${NAME} ${HEIMER_LIB_NAME} Qt${QT_VERSION_MAJOR}::Test) 9 | -------------------------------------------------------------------------------- /src/unit_tests/selection_group_test/selection_group_test.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef SELECTION_GROUP_TEST_HPP 17 | #define SELECTION_GROUP_TEST_HPP 18 | 19 | #include 20 | 21 | #include "../unit_test_base.hpp" 22 | 23 | class SelectionGroupTest : public UnitTestBase 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | SelectionGroupTest(); 29 | 30 | private slots: 31 | 32 | void testAddEdges_Explicit(); 33 | 34 | void testAddEdges_Implicit(); 35 | 36 | void testAddEdges_ImplicitAndExplicit(); 37 | 38 | void testEdges(); 39 | 40 | void testSelectedEdge(); 41 | 42 | void testToggleEdge(); 43 | 44 | void testAddNodes_Explicit(); 45 | 46 | void testAddNodes_Implicit(); 47 | 48 | void testAddNodes_ImplicitAndExplicit(); 49 | 50 | void testNodes(); 51 | 52 | void testSelectedNode(); 53 | 54 | void testToggleNode(); 55 | }; 56 | 57 | #endif // SELECTION_GROUP_TEST_HPP 58 | -------------------------------------------------------------------------------- /src/unit_tests/unit_test_base.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "unit_test_base.hpp" 17 | 18 | #include "../application/service_container.hpp" 19 | 20 | UnitTestBase::UnitTestBase() 21 | : m_sc(std::make_unique()) 22 | { 23 | } 24 | 25 | UnitTestBase::~UnitTestBase() = default; 26 | -------------------------------------------------------------------------------- /src/unit_tests/unit_test_base.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef UNIT_TEST_BASE_HPP 17 | #define UNIT_TEST_BASE_HPP 18 | 19 | #include 20 | 21 | #include 22 | 23 | class ServiceContainer; 24 | 25 | class UnitTestBase : public QObject 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | UnitTestBase(); 31 | 32 | virtual ~UnitTestBase() override; 33 | 34 | private: 35 | std::unique_ptr m_sc; 36 | }; 37 | 38 | #endif // UNIT_TEST_BASE_HPP 39 | -------------------------------------------------------------------------------- /src/unit_tests/version_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(EDITOR_DIR ${CMAKE_SOURCE_DIR}/src) 2 | include_directories(${EDITOR_DIR} ${EDITOR_DIR}/contrib ${CMAKE_CURRENT_SOURCE_DIR}) 3 | set(NAME version_test) 4 | set(SRC ${NAME}.cpp ${NAME}.hpp) 5 | add_executable(${NAME} ${SRC} ${MOC_SRC}) 6 | set_target_properties(${NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${UNIT_TEST_BASE_DIR}) 7 | add_test(${NAME} ${UNIT_TEST_BASE_DIR}/${NAME}) 8 | target_link_libraries(${NAME} ${HEIMER_LIB_NAME} Qt${QT_VERSION_MAJOR}::Test) 9 | -------------------------------------------------------------------------------- /src/unit_tests/version_test/version_test.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef VERSION_TEST_HPP 17 | #define VERSION_TEST_HPP 18 | 19 | #include 20 | 21 | class VersionTest : public QObject 22 | { 23 | Q_OBJECT 24 | 25 | private slots: 26 | 27 | void testInitialization_defaultShouldNotBeValid(); 28 | 29 | void testInitialization_copyConstructor(); 30 | 31 | void testInitialization_initializeWithString(); 32 | 33 | void testInitialization_initializeWithVersion(); 34 | 35 | void testEquality(); 36 | }; 37 | 38 | #endif // VERSION_TEST_HPP 39 | -------------------------------------------------------------------------------- /src/view/dialogs/about_dialog.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef ABOUT_DIALOG_HPP 17 | #define ABOUT_DIALOG_HPP 18 | 19 | #include 20 | 21 | namespace Dialogs { 22 | 23 | //! The about dialog. 24 | class AboutDialog : public QDialog 25 | { 26 | Q_OBJECT 27 | 28 | public: 29 | //! Constructor. 30 | explicit AboutDialog(QWidget * parent = nullptr); 31 | 32 | private: 33 | void initWidgets(); 34 | }; 35 | 36 | } // namespace Dialogs 37 | 38 | #endif // ABOUT_DIALOG_HPP 39 | -------------------------------------------------------------------------------- /src/view/dialogs/color_dialog.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef COLOR_DIALOG_HPP 17 | #define COLOR_DIALOG_HPP 18 | 19 | #include 20 | 21 | namespace Dialogs { 22 | 23 | class ColorDialog : public QColorDialog 24 | { 25 | public: 26 | enum class Role 27 | { 28 | Node, 29 | Edge, 30 | Grid, 31 | Text, 32 | Background, 33 | ShadowColor, 34 | SelectedItemShadowColor 35 | }; 36 | 37 | ColorDialog(Role role); 38 | 39 | virtual ~ColorDialog() override; 40 | 41 | const QColor & color() const; 42 | 43 | private: 44 | Role m_role; 45 | 46 | QColor m_color; 47 | }; 48 | 49 | } // namespace Dialogs 50 | 51 | #endif // COLOR_DIALOG_HPP 52 | -------------------------------------------------------------------------------- /src/view/dialogs/color_setting_button.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef COLOR_SETTING_BUTTON_HPP 17 | #define COLOR_SETTING_BUTTON_HPP 18 | 19 | #include "color_dialog.hpp" 20 | #include 21 | #include 22 | 23 | #include "../../common/types.hpp" 24 | 25 | class SettingsProxy; 26 | 27 | namespace Dialogs { 28 | 29 | class ColorSettingButton : public QPushButton 30 | { 31 | Q_OBJECT 32 | 33 | public: 34 | explicit ColorSettingButton(QString text, ColorDialog::Role role, QWidget * parent = nullptr); 35 | 36 | const QColor & selectedColor() const; 37 | 38 | void resetToDefault(); 39 | 40 | void setColor(QColor color); 41 | 42 | signals: 43 | void colorSelected(const QColor & color); 44 | 45 | private: 46 | void apply(QColor color); 47 | 48 | ColorDialog::Role m_role; 49 | 50 | QColor m_selectedColor; 51 | 52 | SettingsProxyS m_settingsProxy; 53 | }; 54 | 55 | } // namespace Dialogs 56 | 57 | #endif // COLOR_SETTING_BUTTON_HPP 58 | -------------------------------------------------------------------------------- /src/view/dialogs/defaults_tab.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef DEFAULTS_TAB_HPP 17 | #define DEFAULTS_TAB_HPP 18 | 19 | #include 20 | #include 21 | 22 | #include "../scene_items/edge_model.hpp" 23 | #include "settings_tab_base.hpp" 24 | 25 | class QCheckBox; 26 | class QDoubleSpinBox; 27 | class QRadioButton; 28 | class QVBoxLayout; 29 | class QSpinBox; 30 | 31 | namespace Widgets { 32 | class FontButton; 33 | } 34 | 35 | namespace Dialogs { 36 | 37 | class ColorSettingButton; 38 | 39 | class DefaultsTab : public SettingsTabBase 40 | { 41 | Q_OBJECT 42 | 43 | public: 44 | explicit DefaultsTab(QString name, QWidget * parent = nullptr); 45 | 46 | void apply() override; 47 | 48 | void reject() override; 49 | 50 | private: 51 | void createColorWidgets(QVBoxLayout & mainLayout); 52 | 53 | void createEdgeWidgets(QVBoxLayout & mainLayout); 54 | 55 | void createTextWidgets(QVBoxLayout & mainLayout); 56 | 57 | void initWidgets(); 58 | 59 | void setActiveDefaults(); 60 | 61 | std::map m_edgeArrowStyleRadioMap; 62 | 63 | QCheckBox * m_edgeDirectionCheckBox = nullptr; 64 | 65 | QDoubleSpinBox * m_arrowSizeSpinBox = nullptr; 66 | 67 | QDoubleSpinBox * m_edgeWidthSpinBox = nullptr; 68 | 69 | ColorSettingButton * m_backgroundColorButton = nullptr; 70 | 71 | ColorSettingButton * m_edgeColorButton = nullptr; 72 | 73 | ColorSettingButton * m_gridColorButton = nullptr; 74 | 75 | ColorSettingButton * m_nodeColorButton = nullptr; 76 | 77 | ColorSettingButton * m_nodeTextColorButton = nullptr; 78 | 79 | std::vector m_colorSettingButtons; 80 | 81 | Widgets::FontButton * m_fontButton = nullptr; 82 | 83 | QSpinBox * m_textSizeSpinBox = nullptr; 84 | }; 85 | 86 | } // namespace Dialogs 87 | 88 | #endif // DEFAULTS_TAB_HPP 89 | -------------------------------------------------------------------------------- /src/view/dialogs/editing_tab.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef EDITING_TAB_HPP 17 | #define EDITING_TAB_HPP 18 | 19 | #include "settings_tab_base.hpp" 20 | 21 | class QCheckBox; 22 | 23 | namespace Dialogs { 24 | 25 | class EditingTab : public SettingsTabBase 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | explicit EditingTab(QString name, QWidget * parent = nullptr); 31 | 32 | void apply() override; 33 | 34 | signals: 35 | void autosaveEnabled(bool enabled); 36 | 37 | private: 38 | void initWidgets(); 39 | 40 | void setActiveSettings(); 41 | 42 | QCheckBox * m_selectNodeGroupByIntersectionCheckBox = nullptr; 43 | 44 | QCheckBox * m_raiseNodeOnMouseHoverCheckBox = nullptr; 45 | 46 | QCheckBox * m_invertedControlsCheckBox = nullptr; 47 | 48 | QCheckBox * m_autoloadCheckBox = nullptr; 49 | 50 | QCheckBox * m_autosaveCheckBox = nullptr; 51 | }; 52 | 53 | } // namespace Dialogs 54 | 55 | #endif // EDITING_TAB_HPP 56 | -------------------------------------------------------------------------------- /src/view/dialogs/effects_tab.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef EFFECTS_TAB_HPP 17 | #define EFFECTS_TAB_HPP 18 | 19 | #include "settings_tab_base.hpp" 20 | 21 | class QCheckBox; 22 | class QSpinBox; 23 | class ShadowEffectParams; 24 | 25 | namespace Dialogs { 26 | 27 | class ColorSettingButton; 28 | 29 | class EffectsTab : public SettingsTabBase 30 | { 31 | Q_OBJECT 32 | 33 | public: 34 | explicit EffectsTab(QString name, QWidget * parent = nullptr); 35 | 36 | void apply() override; 37 | 38 | signals: 39 | void shadowEffectChanged(const ShadowEffectParams & params); 40 | 41 | private: 42 | void apply(const ShadowEffectParams & params); 43 | 44 | void initWidgets(); 45 | 46 | QSpinBox * m_shadowOffsetSpinBox; 47 | 48 | QSpinBox * m_shadowBlurRadiusSpinBox; 49 | 50 | QSpinBox * m_selectedItemShadowBlurRadiusSpinBox; 51 | 52 | ColorSettingButton * m_shadowColorButton; 53 | 54 | ColorSettingButton * m_selectedItemShadowColorButton; 55 | 56 | QCheckBox * m_optimizeShadowsCheckBox; 57 | 58 | const int m_shadowEffectMaxOffset = 10; 59 | 60 | const int m_shadowEffectMinOffset = 0; 61 | 62 | const int m_shadowEffectMaxBlurRadius = 100; 63 | 64 | const int m_shadowEffectMinBlurRadius = 0; 65 | }; 66 | 67 | } // namespace Dialogs 68 | 69 | #endif // EFFECTS_TAB_HPP 70 | -------------------------------------------------------------------------------- /src/view/dialogs/export/png_export_dialog.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef PNG_EXPORT_DIALOG_HPP 17 | #define PNG_EXPORT_DIALOG_HPP 18 | 19 | #include 20 | 21 | class QCheckBox; 22 | class QDialogButtonBox; 23 | class QLineEdit; 24 | class QProgressBar; 25 | class QPushButton; 26 | class QSpinBox; 27 | 28 | class ExportParams; 29 | 30 | namespace Dialogs::Export { 31 | 32 | class PngExportDialog : public QDialog 33 | { 34 | Q_OBJECT 35 | 36 | public: 37 | explicit PngExportDialog(QWidget & parent); 38 | 39 | void setCurrentMindMapFileName(QString fileName); 40 | 41 | void setDefaultImageSize(QSize size); 42 | 43 | int exec() override; 44 | 45 | public slots: 46 | 47 | void finishExport(bool success); 48 | 49 | signals: 50 | 51 | void pngExportRequested(const ExportParams & exportParams); 52 | 53 | private slots: 54 | 55 | void validate(); 56 | 57 | private: 58 | void initWidgets(); 59 | 60 | QLineEdit * m_fileNameLineEdit = nullptr; 61 | 62 | QSpinBox * m_imageHeightSpinBox = nullptr; 63 | 64 | QSpinBox * m_imageWidthSpinBox = nullptr; 65 | 66 | QPushButton * m_fileNameButton = nullptr; 67 | 68 | QDialogButtonBox * m_buttonBox = nullptr; 69 | 70 | QProgressBar * m_progressBar = nullptr; 71 | 72 | QCheckBox * m_transparentBackgroundCheckBox = nullptr; 73 | 74 | QString m_fileNameWithExtension; 75 | 76 | bool m_enableSpinBoxConnection = true; 77 | 78 | double m_aspectRatio = 1.0; 79 | 80 | const QString m_pngFileExtension = ".png"; 81 | 82 | const int m_minImageSize = 1; 83 | 84 | const int m_maxImageSize = 16'384; 85 | }; 86 | 87 | } // namespace Dialogs::Export 88 | 89 | #endif // PNG_EXPORT_DIALOG_HPP 90 | -------------------------------------------------------------------------------- /src/view/dialogs/export/svg_export_dialog.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef SVG_EXPORT_DIALOG_HPP 17 | #define SVG_EXPORT_DIALOG_HPP 18 | 19 | #include 20 | 21 | class ExportParams; 22 | class QCheckBox; 23 | class QDialogButtonBox; 24 | class QLineEdit; 25 | class QProgressBar; 26 | class QPushButton; 27 | class QSpinBox; 28 | 29 | namespace Dialogs::Export { 30 | 31 | class SvgExportDialog : public QDialog 32 | { 33 | Q_OBJECT 34 | 35 | public: 36 | //! Constructor. 37 | explicit SvgExportDialog(QWidget & parent); 38 | 39 | void setCurrentMindMapFileName(QString fileName); 40 | 41 | int exec() override; 42 | 43 | public slots: 44 | 45 | void finishExport(bool success); 46 | 47 | signals: 48 | 49 | void svgExportRequested(const ExportParams & exportParams); 50 | 51 | private slots: 52 | 53 | void validate(); 54 | 55 | private: 56 | void initWidgets(); 57 | 58 | QLineEdit * m_fileNameLineEdit = nullptr; 59 | 60 | QPushButton * m_fileNameButton = nullptr; 61 | 62 | QDialogButtonBox * m_buttonBox = nullptr; 63 | 64 | QProgressBar * m_progressBar = nullptr; 65 | 66 | QString m_fileNameWithExtension; 67 | 68 | const QString m_svgFileExtension = ".svg"; 69 | }; 70 | 71 | } // namespace Dialogs::Export 72 | 73 | #endif // SVG_EXPORT_DIALOG_HPP 74 | -------------------------------------------------------------------------------- /src/view/dialogs/layout_optimization_dialog.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef LAYOUT_OPTIMIZATION_DIALOG_HPP 17 | #define LAYOUT_OPTIMIZATION_DIALOG_HPP 18 | 19 | #include 20 | 21 | #include "../../common/types.hpp" 22 | 23 | class EditorView; 24 | class LayoutOptimizer; 25 | class QDoubleSpinBox; 26 | class QProgressBar; 27 | 28 | namespace Dialogs { 29 | 30 | class LayoutOptimizationDialog : public QDialog 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | //! Constructor. 36 | explicit LayoutOptimizationDialog(QWidget & parent, MindMapDataR mindMapData, LayoutOptimizer & layoutOptimizer, EditorView & editorView); 37 | 38 | int exec() override; 39 | 40 | signals: 41 | 42 | void undoPointRequested(); 43 | 44 | private slots: 45 | 46 | void finishOptimization(); 47 | 48 | private: 49 | void initWidgets(MindMapDataCR mindMapData); 50 | 51 | MindMapDataR m_mindMapData; 52 | 53 | LayoutOptimizer & m_layoutOptimizer; 54 | 55 | EditorView & m_editorView; 56 | 57 | QDoubleSpinBox * m_aspectRatioSpinBox = nullptr; 58 | 59 | QDoubleSpinBox * m_minEdgeLengthSpinBox = nullptr; 60 | 61 | QProgressBar * m_progressBar = nullptr; 62 | }; 63 | 64 | } // namespace Dialogs 65 | 66 | #endif // LAYOUT_OPTIMIZATION_DIALOG_HPP 67 | -------------------------------------------------------------------------------- /src/view/dialogs/scene_color_dialog.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "scene_color_dialog.hpp" 17 | 18 | #include "../../application/application_service.hpp" 19 | #include "../../application/service_container.hpp" 20 | #include "../node_action.hpp" 21 | 22 | namespace Dialogs { 23 | 24 | SceneColorDialog::SceneColorDialog(Role role) 25 | : ColorDialog(role) 26 | { 27 | connect(this, &QColorDialog::colorSelected, [=](QColor color) { 28 | if (!color.isValid()) { 29 | return; 30 | } 31 | switch (role) { 32 | case Role::Background: 33 | SC::instance().applicationService()->setBackgroundColor(color); 34 | break; 35 | case Role::Edge: 36 | SC::instance().applicationService()->setEdgeColor(color); 37 | break; 38 | case Role::Grid: 39 | SC::instance().applicationService()->setGridColor(color); 40 | break; 41 | case Role::Node: 42 | SC::instance().applicationService()->performNodeAction({ NodeAction::Type::SetNodeColor, color }); 43 | break; 44 | case Role::Text: 45 | SC::instance().applicationService()->performNodeAction({ NodeAction::Type::SetTextColor, color }); 46 | break; 47 | case Role::ShadowColor: 48 | case Role::SelectedItemShadowColor: 49 | break; 50 | } 51 | }); 52 | } 53 | 54 | } // namespace Dialogs 55 | -------------------------------------------------------------------------------- /src/view/dialogs/scene_color_dialog.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef SCENE_COLOR_DIALOG_HPP 17 | #define SCENE_COLOR_DIALOG_HPP 18 | 19 | #include "color_dialog.hpp" 20 | 21 | namespace Dialogs { 22 | 23 | class SceneColorDialog : public ColorDialog 24 | { 25 | public: 26 | SceneColorDialog(Role role); 27 | }; 28 | 29 | } // namespace Dialogs 30 | 31 | #endif // SCENE_COLOR_DIALOG_HPP 32 | -------------------------------------------------------------------------------- /src/view/dialogs/settings_dialog.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef SETTINGS_DIALOG_HPP 17 | #define SETTINGS_DIALOG_HPP 18 | 19 | #include 20 | 21 | #include 22 | 23 | class ShadowEffectParams; 24 | 25 | namespace Dialogs { 26 | 27 | class SettingsTabBase; 28 | 29 | class SettingsDialog : public QDialog 30 | { 31 | Q_OBJECT 32 | 33 | public: 34 | explicit SettingsDialog(QWidget * parent = nullptr); 35 | 36 | signals: 37 | void autosaveEnabled(bool enabled); 38 | 39 | void shadowEffectChanged(const ShadowEffectParams & params); 40 | 41 | private: 42 | void accept() override; 43 | 44 | void reject() override; 45 | 46 | void initWidgets(); 47 | 48 | std::vector m_tabs; 49 | }; 50 | 51 | } // namespace Dialogs 52 | 53 | #endif // SETTINGS_DIALOG_HPP 54 | -------------------------------------------------------------------------------- /src/view/dialogs/settings_tab_base.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "settings_tab_base.hpp" 17 | 18 | #include "../../application/service_container.hpp" 19 | #include "../../application/settings_proxy.hpp" 20 | 21 | namespace Dialogs { 22 | 23 | SettingsTabBase::SettingsTabBase(QString name, QWidget * parent) 24 | : QWidget(parent) 25 | , m_name(name) 26 | { 27 | } 28 | 29 | void SettingsTabBase::apply() 30 | { 31 | } 32 | 33 | void SettingsTabBase::reject() 34 | { 35 | } 36 | 37 | QString SettingsTabBase::name() const 38 | { 39 | return m_name; 40 | } 41 | 42 | SettingsProxyS SettingsTabBase::settingsProxy() const 43 | { 44 | return SC::instance().settingsProxy(); 45 | } 46 | 47 | } // namespace Dialogs 48 | -------------------------------------------------------------------------------- /src/view/dialogs/settings_tab_base.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 Jussi Lind 2 | // 3 | // Heimer is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // Heimer is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU General Public License 13 | // along with Heimer. If not, see . 14 | 15 | #ifndef SETTINGS_TAB_BASE_HPP 16 | #define SETTINGS_TAB_BASE_HPP 17 | 18 | #include 19 | 20 | #include "../../common/types.hpp" 21 | 22 | class SettingsProxy; 23 | 24 | namespace Dialogs { 25 | 26 | class SettingsTabBase : public QWidget 27 | { 28 | Q_OBJECT 29 | 30 | public: 31 | explicit SettingsTabBase(QString name, QWidget * parent = nullptr); 32 | 33 | virtual void apply(); 34 | 35 | virtual void reject(); 36 | 37 | QString name() const; 38 | 39 | protected: 40 | SettingsProxyS settingsProxy() const; 41 | 42 | private: 43 | QString m_name; 44 | }; 45 | 46 | } // namespace Dialogs 47 | 48 | #endif // SETTINGS_TAB_BASE_HPP 49 | -------------------------------------------------------------------------------- /src/view/dialogs/spinner_dialog.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "spinner_dialog.hpp" 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace Dialogs { 23 | 24 | SpinnerDialog::SpinnerDialog(QWidget * parent) 25 | : QDialog(parent, Qt::Popup) 26 | , m_messageLabel(new QLabel(this)) 27 | { 28 | setMinimumWidth(400); 29 | initWidgets(); 30 | } 31 | 32 | void SpinnerDialog::initWidgets() 33 | { 34 | const auto vLayout = new QVBoxLayout(this); 35 | const auto spinner = new QProgressBar; 36 | spinner->setMinimum(0); 37 | spinner->setMaximum(0); 38 | vLayout->addWidget(m_messageLabel); 39 | vLayout->addWidget(spinner); 40 | setLayout(vLayout); 41 | } 42 | 43 | void SpinnerDialog::setMessage(QString message) 44 | { 45 | m_messageLabel->setText(message); 46 | update(); 47 | } 48 | 49 | } // namespace Dialogs 50 | -------------------------------------------------------------------------------- /src/view/dialogs/spinner_dialog.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef SPINNER_DIALOG_HPP 17 | #define SPINNER_DIALOG_HPP 18 | 19 | #include 20 | 21 | class QLabel; 22 | 23 | namespace Dialogs { 24 | 25 | //! The spinner dialog. 26 | class SpinnerDialog : public QDialog 27 | { 28 | Q_OBJECT 29 | 30 | public: 31 | //! Constructor. 32 | explicit SpinnerDialog(QWidget * parent = nullptr); 33 | 34 | void setMessage(QString message); 35 | 36 | private: 37 | void initWidgets(); 38 | 39 | QLabel * m_messageLabel; 40 | }; 41 | 42 | } // namespace Dialogs 43 | 44 | #endif // SPINNER_DIALOG_HPP 45 | -------------------------------------------------------------------------------- /src/view/dialogs/whats_new_dialog.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "whats_new_dialog.hpp" 17 | 18 | #include "../../common/constants.hpp" 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace Dialogs { 27 | 28 | WhatsNewDialog::WhatsNewDialog(QWidget * parent) 29 | : QDialog(parent) 30 | { 31 | setWindowTitle(tr("What's New")); 32 | initWidgets(); 33 | } 34 | 35 | QString filterChangeLog(QString data) 36 | { 37 | const auto lines = data.split("\n"); 38 | bool versionFound = false; 39 | QString filteredLines; 40 | for (auto && line : lines) { 41 | if (line.contains(Constants::Application::applicationVersion())) { 42 | versionFound = true; 43 | } 44 | if (versionFound) { 45 | filteredLines.append(line + "\n"); 46 | } 47 | } 48 | return filteredLines; 49 | } 50 | 51 | void WhatsNewDialog::initWidgets() 52 | { 53 | const auto vLayout = new QVBoxLayout(this); 54 | const auto textEdit = new QTextEdit(this); 55 | 56 | QString data; 57 | QFile file(":/CHANGELOG"); 58 | if (file.open(QIODevice::ReadOnly)) { 59 | data = filterChangeLog(file.readAll()); 60 | } 61 | file.close(); 62 | 63 | textEdit->setText(data); 64 | textEdit->setReadOnly(true); 65 | QFont font = textEdit->font(); 66 | font.setFamily("Courier New"); 67 | font.setStyleHint(QFont::Monospace); 68 | textEdit->setFont(font); 69 | vLayout->addWidget(textEdit); 70 | 71 | const auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); 72 | connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); 73 | 74 | vLayout->addWidget(buttonBox); 75 | } 76 | 77 | } // namespace Dialogs 78 | -------------------------------------------------------------------------------- /src/view/dialogs/whats_new_dialog.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef WHATS_NEW_DIALOG_HPP 17 | #define WHATS_NEW_DIALOG_HPP 18 | 19 | #include 20 | 21 | namespace Dialogs { 22 | 23 | //! Dialog that shows the latest changes from CHANGELOG. 24 | class WhatsNewDialog : public QDialog 25 | { 26 | Q_OBJECT 27 | 28 | public: 29 | //! Constructor. 30 | explicit WhatsNewDialog(QWidget * parent = nullptr); 31 | 32 | private: 33 | void initWidgets(); 34 | }; 35 | 36 | } // namespace Dialogs 37 | 38 | #endif // WHATS_NEW_DIALOG_HPP 39 | -------------------------------------------------------------------------------- /src/view/dialogs/widget_factory.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "widget_factory.hpp" 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace Dialogs::WidgetFactory { 29 | 30 | std::pair buildGroupBoxWithVLayout(QString title, QLayout & parentLayout) 31 | { 32 | const auto group = new QGroupBox; 33 | group->setTitle(title); 34 | parentLayout.addWidget(group); 35 | const auto groupLayout = new QVBoxLayout; 36 | group->setLayout(groupLayout); 37 | return { group, groupLayout }; 38 | } 39 | 40 | std::pair buildResetToDefaultsButtonWithHLayout() 41 | { 42 | const auto layout = new QHBoxLayout; 43 | const auto spacer = new QWidget; 44 | spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); 45 | layout->addWidget(spacer); 46 | const auto button = new QPushButton(QObject::tr("Reset to defaults")); 47 | layout->addWidget(button); 48 | return { button, layout }; 49 | } 50 | 51 | QWidget * buildHorizontalLine() 52 | { 53 | const auto line = new QFrame; 54 | line->setFrameShape(QFrame::HLine); 55 | line->setFrameShadow(QFrame::Sunken); 56 | 57 | return line; 58 | } 59 | 60 | } // namespace Dialogs::WidgetFactory 61 | -------------------------------------------------------------------------------- /src/view/dialogs/widget_factory.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef WIDGET_FACTORY_HPP 17 | #define WIDGET_FACTORY_HPP 18 | 19 | #include 20 | 21 | #include 22 | 23 | class QGroupBox; 24 | class QHBoxLayout; 25 | class QLayout; 26 | class QPushButton; 27 | class QVBoxLayout; 28 | class QWidget; 29 | class QWidgetAction; 30 | 31 | namespace Dialogs::WidgetFactory { 32 | 33 | std::pair buildGroupBoxWithVLayout(QString title, QLayout & parentLayout); 34 | 35 | std::pair buildResetToDefaultsButtonWithHLayout(); 36 | 37 | QWidget * buildHorizontalLine(); 38 | 39 | } // namespace Dialogs::WidgetFactory 40 | 41 | #endif // WIDGET_FACTORY_HPP 42 | -------------------------------------------------------------------------------- /src/view/edge_action.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2024 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef EDGE_ACTION_HPP 17 | #define EDGE_ACTION_HPP 18 | 19 | class EdgeAction 20 | { 21 | public: 22 | enum class Type 23 | { 24 | None, 25 | Delete, 26 | }; 27 | 28 | EdgeAction(Type type) 29 | : m_type(type) 30 | { 31 | } 32 | 33 | Type type() const; 34 | 35 | private: 36 | Type m_type = Type::None; 37 | }; 38 | 39 | inline EdgeAction::Type EdgeAction::type() const 40 | { 41 | return m_type; 42 | } 43 | 44 | #endif // EDGE_ACTION_HPP 45 | -------------------------------------------------------------------------------- /src/view/edge_selection_group.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2024 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef EDGE_SELECTION_GROUP_HPP 17 | #define EDGE_SELECTION_GROUP_HPP 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "../common/types.hpp" 26 | 27 | class EdgeSelectionGroup 28 | { 29 | public: 30 | //! Adds edge to the selection group. 31 | //! \param edge Edge to be added. 32 | //! \param isImplicit Tells if the edge is implicitly added e.g. due to some user action. 33 | void add(EdgeR edge, bool isImplicit = false); 34 | 35 | //! Clears the selection group. 36 | //! \param implicitOnly If true, only implicitly added edges are removed from the group. 37 | void clear(bool implicitOnly = false); 38 | 39 | bool contains(EdgeR edgee) const; 40 | 41 | bool isEmpty() const; 42 | 43 | const std::vector edges() const; 44 | 45 | std::optional selectedEdge() const; 46 | 47 | size_t size() const; 48 | 49 | void toggle(EdgeR edge); 50 | 51 | private: 52 | void clearAll(); 53 | 54 | void clearImplicitOnly(); 55 | 56 | // Use vector because we want to keep the order 57 | std::vector m_edges; 58 | 59 | // Map from edge -> is implicitly added 60 | std::unordered_map m_implicitlyAdded; 61 | }; 62 | 63 | #endif // EDGE_SELECTION_GROUP_HPP 64 | -------------------------------------------------------------------------------- /src/view/editor_scene.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef EDITOR_SCENE_HPP 17 | #define EDITOR_SCENE_HPP 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "../common/types.hpp" 24 | 25 | class Node; 26 | 27 | class EditorScene : public QGraphicsScene 28 | { 29 | public: 30 | EditorScene(); 31 | 32 | void adjustSceneRect(); 33 | 34 | QRectF calculateZoomToFitRectangle(bool isForExport = false) const; 35 | 36 | QRectF calculateZoomToFitRectangleByNodes(const std::vector & nodes) const; 37 | 38 | //! Checks if the graphics scene already has the given edge item added 39 | bool hasEdge(NodeR node0, NodeR node1); 40 | 41 | QImage toImage(QSize size, QColor backgroundColor, bool transparentBackground); 42 | 43 | void toSvg(QString fileName, QString title); 44 | 45 | virtual ~EditorScene() override; 46 | 47 | private: 48 | bool containsAll() const; 49 | 50 | void enableGraphicsEffects(bool enable) const; 51 | 52 | void removeItems(); 53 | 54 | using ItemPtr = std::unique_ptr; 55 | std::vector m_ownItems; 56 | 57 | const int m_initialSize = 10000; 58 | }; 59 | 60 | #endif // EDITOR_SCENE_HPP 61 | -------------------------------------------------------------------------------- /src/view/grid.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "grid.hpp" 17 | 18 | #include 19 | 20 | Grid::Grid() 21 | { 22 | m_lines.reserve(1024); 23 | } 24 | 25 | const Grid::LineArray & Grid::calculateLines(const QRectF & sceneRect) const 26 | { 27 | m_lines.clear(); 28 | 29 | if (m_size) { 30 | // Vertical lines 31 | auto x = snapToGrid({ sceneRect.left(), sceneRect.top() }).x(); 32 | while (x < sceneRect.right()) { 33 | m_lines.push_back({ x, sceneRect.top(), x, sceneRect.bottom() }); 34 | x += m_size; 35 | } 36 | // Horizontal lines 37 | auto y = snapToGrid({ sceneRect.left(), sceneRect.top() }).y(); 38 | while (y < sceneRect.bottom()) { 39 | m_lines.push_back({ sceneRect.left(), y, sceneRect.right(), y }); 40 | y += m_size; 41 | } 42 | } 43 | 44 | return m_lines; 45 | } 46 | 47 | void Grid::setSize(int size) 48 | { 49 | m_size = size; 50 | } 51 | 52 | int Grid::size() const 53 | { 54 | return m_size; 55 | } 56 | 57 | QPointF Grid::snapToGrid(QPointF in) const 58 | { 59 | if (!m_size) { 60 | return in; 61 | } 62 | 63 | return { 64 | static_cast(std::round(in.x() / m_size) * m_size), 65 | static_cast(std::round(in.y() / m_size) * m_size) 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /src/view/grid.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef GRID_HPP 17 | #define GRID_HPP 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | class Grid 26 | { 27 | public: 28 | Grid(); 29 | 30 | using LineArray = std::vector; 31 | const LineArray & calculateLines(const QRectF & sceneRect) const; 32 | 33 | void setSize(int gridSize); 34 | 35 | int size() const; 36 | 37 | QPointF snapToGrid(QPointF in) const; 38 | 39 | private: 40 | int m_size = 0; 41 | 42 | mutable LineArray m_lines; 43 | }; 44 | 45 | #endif // GRID_HPP 46 | -------------------------------------------------------------------------------- /src/view/item_filter.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "item_filter.hpp" 17 | 18 | #include "scene_items/edge.hpp" 19 | #include "scene_items/edge_text_edit.hpp" 20 | #include "scene_items/node.hpp" 21 | #include "scene_items/node_handle.hpp" 22 | 23 | #include 24 | 25 | namespace ItemFilter { 26 | 27 | ItemAtPosition getFirstItemAtPosition(QGraphicsScene & scene, QPointF scenePos, double tolerance) 28 | { 29 | ItemAtPosition itemAtPosition; 30 | 31 | const QRectF clickRect(scenePos.x() - tolerance, scenePos.y() - tolerance, tolerance * 2, tolerance * 2); 32 | 33 | if (const auto itemsAtPosition = scene.items(clickRect, Qt::IntersectsItemShape, Qt::DescendingOrder); !itemsAtPosition.empty()) { 34 | const auto firstItem = *itemsAtPosition.begin(); 35 | if (const auto edge = dynamic_cast(firstItem); edge) { 36 | itemAtPosition.itemOptional = edge; 37 | } else if (const auto nodeHandle = dynamic_cast(firstItem); nodeHandle) { 38 | itemAtPosition.itemOptional = nodeHandle; 39 | } else if (const auto node = dynamic_cast(firstItem); node) { 40 | itemAtPosition.itemOptional = node; 41 | } else if (const auto edgeTextEdit = dynamic_cast(firstItem); edgeTextEdit) { 42 | itemAtPosition.itemOptional = edgeTextEdit; 43 | } 44 | } 45 | 46 | return itemAtPosition; 47 | } 48 | 49 | } // namespace ItemFilter 50 | -------------------------------------------------------------------------------- /src/view/item_filter.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef ITEM_FILTER_HPP 17 | #define ITEM_FILTER_HPP 18 | 19 | #include "scene_items/edge.hpp" 20 | #include "scene_items/edge_text_edit.hpp" 21 | #include "scene_items/node.hpp" 22 | #include "scene_items/node_handle.hpp" 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | class QGraphicsScene; 30 | 31 | namespace ItemFilter { 32 | 33 | struct ItemAtPosition 34 | { 35 | template 36 | T * get() const 37 | { 38 | return std::get(*itemOptional); 39 | } 40 | 41 | bool hasItem() const 42 | { 43 | return itemOptional.has_value(); 44 | } 45 | 46 | template 47 | bool is() const 48 | { 49 | return itemOptional.has_value() && std::holds_alternative(*itemOptional); 50 | } 51 | 52 | std::optional> itemOptional; 53 | }; 54 | 55 | ItemAtPosition getFirstItemAtPosition(QGraphicsScene & scene, QPointF scenePos, double tolerance); 56 | 57 | } // namespace ItemFilter 58 | 59 | #endif // ITEM_FILTER_HPP 60 | -------------------------------------------------------------------------------- /src/view/magic_zoom.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef MAGIC_ZOOM_HPP 17 | #define MAGIC_ZOOM_HPP 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include "../common/types.hpp" 25 | 26 | class QGraphicsItem; 27 | 28 | namespace MagicZoom { 29 | 30 | using ItemList = QList; 31 | QRectF calculateRectangleByItems(const ItemList & items, bool isForExport = false); 32 | 33 | using EdgeList = std::vector; 34 | QRectF calculateRectangleByEdges(const EdgeList & edges); 35 | 36 | using NodeList = std::vector; 37 | QRectF calculateRectangleByNodes(const NodeList & nodes, bool isForExport = false); 38 | 39 | } // namespace MagicZoom 40 | 41 | #endif // MAGIC_ZOOM_HPP 42 | -------------------------------------------------------------------------------- /src/view/menus/edge_context_menu.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef EDGE_CONTEXT_MENU_H 17 | #define EDGE_CONTEXT_MENU_H 18 | 19 | #include 20 | 21 | #include "../../common/types.hpp" 22 | 23 | class Edge; 24 | class ApplicationService; 25 | 26 | class QAction; 27 | 28 | namespace Menus { 29 | 30 | class EdgeContextMenu : public QMenu 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | EdgeContextMenu(QWidget * parent); 36 | 37 | protected: 38 | void changeEvent(QEvent * event) override; 39 | 40 | private: 41 | void connectVisibilitySignals(); 42 | 43 | void createActions(); 44 | 45 | void initialize(); 46 | 47 | void populateMenuWithActions(); 48 | 49 | void retranslate(); 50 | 51 | QAction * m_changeEdgeDirectionAction = nullptr; 52 | 53 | QAction * m_showEdgeArrowAction = nullptr; 54 | 55 | QAction * m_doubleArrowAction = nullptr; 56 | 57 | QAction * m_dashedLineAction = nullptr; 58 | 59 | QAction * m_deleteEdgeAction = nullptr; 60 | 61 | EdgeP m_selectedEdge = nullptr; 62 | }; 63 | 64 | } // namespace Menus 65 | 66 | #endif // EDGE_CONTEXT_MENU_H 67 | -------------------------------------------------------------------------------- /src/view/menus/recent_files_menu.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "recent_files_menu.hpp" 17 | 18 | #include "../../application/recent_files_manager.hpp" 19 | #include "../../application/service_container.hpp" 20 | #include "../../common/utils.hpp" 21 | 22 | #include 23 | 24 | namespace Menus { 25 | 26 | RecentFilesMenu::RecentFilesMenu(QWidget * parent) 27 | : QMenu(parent) 28 | { 29 | connect(this, &QMenu::aboutToShow, [=] { 30 | for (auto && action : actions()) { 31 | removeAction(action); 32 | } 33 | for (auto && filePath : SC::instance().recentFilesManager()->recentFiles()) { 34 | const auto action = addAction(filePath); 35 | const auto handler = std::bind([=](QString filePath) { 36 | SC::instance().recentFilesManager()->setSelectedFile(filePath); 37 | fileSelected(filePath); 38 | }, 39 | action->text()); 40 | action->setEnabled(Utils::fileExists(filePath)); 41 | connect(action, &QAction::triggered, handler); 42 | } 43 | }); 44 | } 45 | 46 | } // namespace Menus 47 | -------------------------------------------------------------------------------- /src/view/menus/recent_files_menu.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef RECENT_FILES_MENU_HPP 17 | #define RECENT_FILES_MENU_HPP 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | class QAction; 25 | 26 | namespace Menus { 27 | 28 | class RecentFilesMenu : public QMenu 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | explicit RecentFilesMenu(QWidget * parent = nullptr); 34 | 35 | signals: 36 | void fileSelected(QString filePath); 37 | 38 | private: 39 | std::list m_actions; 40 | }; 41 | 42 | } // namespace Menus 43 | 44 | #endif // RECENT_FILES_MENU_HPP 45 | -------------------------------------------------------------------------------- /src/view/menus/widget_factory.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "widget_factory.hpp" 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | namespace Menus::WidgetFactory { 28 | 29 | std::pair buildToolBarWidgetAction(QWidget & widget, QWidget & parent) 30 | { 31 | const auto action = new QWidgetAction(&parent); 32 | action->setDefaultWidget(&widget); 33 | return { &widget, action }; 34 | } 35 | 36 | std::pair buildToolBarWidgetActionWithLabel(QString labelText, QWidget & widget, QWidget & parent) 37 | { 38 | const auto dummyWidget = new QWidget(&parent); 39 | const auto layout = new QHBoxLayout(dummyWidget); 40 | dummyWidget->setLayout(layout); 41 | layout->addWidget(new QLabel(labelText)); 42 | layout->addWidget(&widget); 43 | layout->setContentsMargins(0, 0, 0, 0); 44 | const auto action = new QWidgetAction(&parent); 45 | action->setDefaultWidget(dummyWidget); 46 | return { dummyWidget, action }; 47 | } 48 | 49 | } // namespace Menus::WidgetFactory 50 | -------------------------------------------------------------------------------- /src/view/menus/widget_factory.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2021 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef WIDGET_FACTORY_HPP 17 | #define WIDGET_FACTORY_HPP 18 | 19 | #include 20 | 21 | #include 22 | 23 | class QGroupBox; 24 | class QHBoxLayout; 25 | class QLayout; 26 | class QPushButton; 27 | class QVBoxLayout; 28 | class QWidget; 29 | class QWidgetAction; 30 | 31 | namespace Menus::WidgetFactory { 32 | 33 | std::pair buildToolBarWidgetAction(QWidget & widget, QWidget & parent); 34 | 35 | std::pair buildToolBarWidgetActionWithLabel(QString label, QWidget & widget, QWidget & parent); 36 | 37 | } // namespace Menus::WidgetFactory 38 | 39 | #endif // WIDGET_FACTORY_HPP 40 | -------------------------------------------------------------------------------- /src/view/mouse_action.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Dust Racing 2D is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Dust Racing 2D is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Dust Racing 2D. If not, see . 15 | 16 | #include "mouse_action.hpp" 17 | 18 | #include "scene_items/node.hpp" 19 | 20 | MouseAction::MouseAction() 21 | { 22 | } 23 | 24 | MouseAction::Action MouseAction::action() const 25 | { 26 | return m_action; 27 | } 28 | 29 | void MouseAction::clear() 30 | { 31 | m_sourceNode = nullptr; 32 | m_sourcePos = QPointF(); 33 | m_sourcePosOnNode = QPointF(); 34 | m_action = Action::None; 35 | } 36 | 37 | void MouseAction::setSourceNode(NodeP node, MouseAction::Action action) 38 | { 39 | m_sourceNode = node; 40 | m_action = action; 41 | } 42 | 43 | NodeP MouseAction::sourceNode() const 44 | { 45 | return m_sourceNode; 46 | } 47 | 48 | void MouseAction::setSourcePos(const QPointF & sourcePos) 49 | { 50 | m_sourcePos = sourcePos; 51 | } 52 | 53 | void MouseAction::setSourcePosOnNode(const QPointF & sourcePos) 54 | { 55 | m_sourcePosOnNode = sourcePos; 56 | } 57 | 58 | QPointF MouseAction::rubberBandOrigin() const 59 | { 60 | return m_rubberBandOrigin; 61 | } 62 | 63 | void MouseAction::setRubberBandOrigin(const QPointF & rubberBandOrigin) 64 | { 65 | m_rubberBandOrigin = rubberBandOrigin; 66 | m_action = Action::RubberBand; 67 | } 68 | 69 | QPointF MouseAction::mappedPos() const 70 | { 71 | return m_mappedPos; 72 | } 73 | 74 | void MouseAction::setMappedPos(const QPointF & mappedPos) 75 | { 76 | m_mappedPos = mappedPos; 77 | } 78 | 79 | QPointF MouseAction::clickedScenePos() const 80 | { 81 | return m_clickedScenePos; 82 | } 83 | 84 | void MouseAction::setClickedScenePos(const QPointF & clickedScenePos) 85 | { 86 | m_clickedScenePos = clickedScenePos; 87 | } 88 | 89 | QPointF MouseAction::sourcePos() const 90 | { 91 | return m_sourcePos; 92 | } 93 | 94 | QPointF MouseAction::sourcePosOnNode() const 95 | { 96 | return m_sourcePosOnNode; 97 | } 98 | -------------------------------------------------------------------------------- /src/view/mouse_action.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Dust Racing 2D is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Dust Racing 2D is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Dust Racing 2D. If not, see . 15 | 16 | #ifndef MOUSE_ACTION_HPP 17 | #define MOUSE_ACTION_HPP 18 | 19 | #include 20 | 21 | #include "../common/types.hpp" 22 | 23 | class MouseAction 24 | { 25 | public: 26 | enum class Action 27 | { 28 | None, 29 | MoveNode, 30 | CreateOrConnectNode, 31 | RubberBand, 32 | Scroll 33 | }; 34 | 35 | MouseAction(); 36 | 37 | void clear(); 38 | 39 | NodeP sourceNode() const; 40 | void setSourceNode(NodeP node, Action action); 41 | 42 | Action action() const; 43 | 44 | QPointF sourcePos() const; 45 | void setSourcePos(const QPointF & sourcePos); 46 | 47 | QPointF sourcePosOnNode() const; 48 | void setSourcePosOnNode(const QPointF & sourcePosOnNode); 49 | 50 | QPointF rubberBandOrigin() const; 51 | void setRubberBandOrigin(const QPointF & rubberBandOrigin); 52 | 53 | QPointF mappedPos() const; 54 | void setMappedPos(const QPointF & mappedPos); 55 | 56 | QPointF clickedScenePos() const; 57 | void setClickedScenePos(const QPointF & clickedScenePos); 58 | 59 | private: 60 | NodeP m_sourceNode = nullptr; 61 | 62 | QPointF m_clickedScenePos; 63 | 64 | QPointF m_mappedPos; 65 | 66 | QPointF m_sourcePos; 67 | 68 | QPointF m_sourcePosOnNode; 69 | 70 | QPointF m_rubberBandOrigin; 71 | 72 | Action m_action = Action::None; 73 | }; 74 | 75 | #endif // MOUSE_ACTION_HPP 76 | -------------------------------------------------------------------------------- /src/view/node_action.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2020 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef NODE_ACTION_HPP 17 | #define NODE_ACTION_HPP 18 | 19 | #include 20 | #include 21 | 22 | class NodeAction 23 | { 24 | public: 25 | enum class Type 26 | { 27 | None, 28 | AttachImage, 29 | ConnectSelected, 30 | Copy, 31 | Delete, 32 | DisconnectSelected, 33 | MirrorLayoutHorizontally, 34 | MirrorLayoutVertically, 35 | Paste, 36 | RemoveAttachedImage, 37 | SetNodeColor, 38 | SetTextColor, 39 | }; 40 | 41 | NodeAction(Type type) 42 | : m_type(type) 43 | { 44 | } 45 | 46 | NodeAction(Type type, QColor color) 47 | : m_type(type) 48 | , m_color(color) 49 | { 50 | } 51 | 52 | NodeAction(Type type, QImage image, QString fileName) 53 | : m_type(type) 54 | , m_image(image) 55 | , m_fileName(fileName) 56 | { 57 | } 58 | 59 | Type type() const; 60 | 61 | QColor color() const; 62 | 63 | QImage image() const; 64 | 65 | QString fileName() const; 66 | 67 | private: 68 | Type m_type = Type::None; 69 | 70 | QColor m_color = Qt::white; 71 | 72 | QImage m_image; 73 | 74 | QString m_fileName; 75 | }; 76 | 77 | inline NodeAction::Type NodeAction::type() const 78 | { 79 | return m_type; 80 | } 81 | 82 | inline QColor NodeAction::color() const 83 | { 84 | return m_color; 85 | } 86 | 87 | inline QImage NodeAction::image() const 88 | { 89 | return m_image; 90 | } 91 | 92 | inline QString NodeAction::fileName() const 93 | { 94 | return m_fileName; 95 | } 96 | 97 | #endif // NODE_ACTION_HPP 98 | -------------------------------------------------------------------------------- /src/view/node_selection_group.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef NODE_SELECTION_GROUP_HPP 17 | #define NODE_SELECTION_GROUP_HPP 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "../common/types.hpp" 26 | 27 | class NodeSelectionGroup 28 | { 29 | public: 30 | //! Adds node to the selection group. 31 | //! \param node Node to be added. 32 | //! \param isImplicit Tells if the node is implicitly added e.g. due to some user action. 33 | void add(NodeR node, bool isImplicit = false); 34 | 35 | //! Clears the selection group. 36 | //! \param implicitOnly If true, only implicitly added nodes are removed from the group. 37 | void clear(bool implicitOnly = false); 38 | 39 | bool contains(NodeR node) const; 40 | 41 | bool isEmpty() const; 42 | 43 | void move(NodeR reference, QPointF location); 44 | 45 | const std::vector nodes() const; 46 | 47 | std::optional selectedNode() const; 48 | 49 | size_t size() const; 50 | 51 | void toggle(NodeR node); 52 | 53 | private: 54 | void clearAll(); 55 | 56 | void clearImplicitOnly(); 57 | 58 | // Use vector because we want to keep the order 59 | std::vector m_nodes; 60 | 61 | // Map from node -> is implicitly added 62 | std::unordered_map m_implicitlyAdded; 63 | }; 64 | 65 | #endif // NODE_SELECTION_GROUP_HPP 66 | -------------------------------------------------------------------------------- /src/view/scene_items/edge_dot.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "edge_dot.hpp" 17 | 18 | namespace SceneItems { 19 | 20 | EdgeDot::EdgeDot(QGraphicsItem * parentItem) 21 | : QGraphicsEllipseItem(parentItem) 22 | { 23 | } 24 | 25 | } // namespace SceneItems 26 | -------------------------------------------------------------------------------- /src/view/scene_items/edge_dot.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef EDGE_DOT_HPP 17 | #define EDGE_DOT_HPP 18 | 19 | #include 20 | #include 21 | 22 | namespace SceneItems { 23 | 24 | class EdgeDot : public QObject, public QGraphicsEllipseItem 25 | { 26 | Q_OBJECT 27 | Q_PROPERTY(qreal scale READ scale WRITE setScale) 28 | 29 | public: 30 | explicit EdgeDot(QGraphicsItem * parentItem = nullptr); 31 | }; 32 | 33 | } // namespace SceneItems 34 | 35 | #endif // EDGE_DOT_HPP 36 | -------------------------------------------------------------------------------- /src/view/scene_items/edge_model.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef EDGE_MODEL_HPP 17 | #define EDGE_MODEL_HPP 18 | 19 | #include 20 | 21 | #include "../../common/constants.hpp" 22 | 23 | namespace SceneItems { 24 | 25 | struct EdgeModel 26 | { 27 | enum class ArrowMode 28 | { 29 | Single = 0, 30 | Double = 1, 31 | Hidden = 2 32 | }; 33 | 34 | struct Style 35 | { 36 | Style(ArrowMode arrowMode) 37 | : arrowMode(arrowMode) 38 | , arrowSize(Constants::Settings::defaultArrowSize()) 39 | , edgeWidth(Constants::Settings::defaultEdgeWidth()) 40 | { 41 | } 42 | 43 | ArrowMode arrowMode; 44 | 45 | double arrowSize; 46 | 47 | bool dashedLine = false; 48 | 49 | double edgeWidth; 50 | }; 51 | 52 | EdgeModel(bool reversed, Style style) 53 | : reversed(reversed) 54 | , style(style) 55 | { 56 | } 57 | 58 | bool reversed; 59 | 60 | Style style; 61 | 62 | QString text; 63 | }; 64 | 65 | } // namespace SceneItems 66 | 67 | #endif // EDGE_MODEL_HPP 68 | -------------------------------------------------------------------------------- /src/view/scene_items/edge_point.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2019 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef EDGE_POINT_HPP 17 | #define EDGE_POINT_HPP 18 | 19 | #include 20 | 21 | namespace SceneItems { 22 | 23 | struct EdgePoint 24 | { 25 | EdgePoint(QPointF location = { 0, 0 }, bool isCorner = false) 26 | : location(location) 27 | , isCorner(isCorner) 28 | { 29 | } 30 | 31 | QPointF location; 32 | 33 | bool isCorner = false; 34 | }; 35 | 36 | } // namespace SceneItems 37 | 38 | #endif // EDGE_POINT_HPP 39 | -------------------------------------------------------------------------------- /src/view/scene_items/edge_text_edit.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef EDGE_TEXT_EDIT_HPP 17 | #define EDGE_TEXT_EDIT_HPP 18 | 19 | #include "../../common/types.hpp" 20 | #include "scene_item_base.hpp" 21 | #include "text_edit.hpp" 22 | 23 | #include 24 | #include 25 | 26 | namespace SceneItems { 27 | 28 | class Edge; 29 | 30 | class EdgeTextEdit : public TextEdit 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | EdgeTextEdit(EdgeP parentItem); 36 | 37 | EdgeP edge() const; 38 | 39 | enum class VisibilityChangeReason 40 | { 41 | Timeout, 42 | Explicit, 43 | Focused, 44 | AvailableSpaceChanged 45 | }; 46 | 47 | void setVisible(bool visible); 48 | 49 | void updateDueToLostFocus(); 50 | 51 | virtual void hoverEnterEvent(QGraphicsSceneHoverEvent * event) override; 52 | 53 | virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent * event) override; 54 | 55 | virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) override; 56 | 57 | //! Used to add some padding the the text field. 58 | QRectF boundingRect() const override; 59 | 60 | signals: 61 | 62 | void hoverEntered(); 63 | 64 | void visibilityTimeout(); 65 | 66 | private: 67 | void setAnimationConfig(bool visible); 68 | 69 | EdgeP m_edge; 70 | 71 | QPropertyAnimation m_opacityAnimation; 72 | 73 | QTimer m_visibilityTimer; 74 | }; 75 | 76 | } // namespace SceneItems 77 | 78 | #endif // EDGE_TEXT_EDIT_HPP 79 | -------------------------------------------------------------------------------- /src/view/scene_items/graphics_factory.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "graphics_factory.hpp" 17 | 18 | #include "../shadow_effect_params.hpp" 19 | 20 | #include 21 | 22 | QGraphicsEffect * GraphicsFactory::createDropShadowEffect(const ShadowEffectParams & params, bool selected) 23 | { 24 | const auto effect = new QGraphicsDropShadowEffect; 25 | updateDropShadowEffect(effect, params, selected, false); 26 | return effect; 27 | } 28 | 29 | QPen GraphicsFactory::createOutlinePen(const QColor & backgroundColor, double brightness) 30 | { 31 | const int width = 1; 32 | return QPen { QColor { static_cast(backgroundColor.red() * brightness), 33 | static_cast(backgroundColor.green() * brightness), 34 | static_cast(backgroundColor.blue() * brightness) }, 35 | width }; 36 | } 37 | 38 | void GraphicsFactory::updateDropShadowEffect(QGraphicsEffect * effect, const ShadowEffectParams & params, bool selected, bool disabled) 39 | { 40 | if (!effect) { 41 | return; 42 | } 43 | 44 | if (const auto shadow = qobject_cast(effect)) { 45 | if (!disabled) { 46 | if (!selected) { 47 | shadow->setOffset(params.offset(), params.offset()); 48 | shadow->setColor(params.shadowColor()); 49 | shadow->setBlurRadius(params.blurRadius()); 50 | } else { 51 | shadow->setOffset({}); 52 | shadow->setColor(params.selectedItemShadowColor()); 53 | shadow->setBlurRadius(params.selectedItemBlurRadius()); 54 | } 55 | } else { 56 | shadow->setOffset({}); 57 | shadow->setColor({}); 58 | shadow->setBlurRadius({}); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/view/scene_items/graphics_factory.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef GRAPHICS_FACTORY_HPP 17 | #define GRAPHICS_FACTORY_HPP 18 | 19 | #include 20 | #include 21 | 22 | class QGraphicsEffect; 23 | class ShadowEffectParams; 24 | 25 | namespace GraphicsFactory { 26 | 27 | QGraphicsEffect * createDropShadowEffect(const ShadowEffectParams & params, bool selected); 28 | 29 | QPen createOutlinePen(const QColor & backgroundColor, double brightness = 0.5); 30 | 31 | void updateDropShadowEffect(QGraphicsEffect * effect, const ShadowEffectParams & params, bool selected, bool disabled = false); 32 | } // namespace GraphicsFactory 33 | 34 | #endif // GRAPHICS_FACTORY_HPP 35 | -------------------------------------------------------------------------------- /src/view/scene_items/layers.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef LAYERS_HPP 17 | #define LAYERS_HPP 18 | 19 | namespace SceneItems { 20 | 21 | enum class Layers 22 | { 23 | Edge = 1, 24 | Node = 10, 25 | EdgeDot = 20, 26 | EdgeCondensedLabel = 25, 27 | NodeHandle = 30, 28 | EdgeLabel = 45, 29 | Last = 50 30 | }; 31 | 32 | } // namespace SceneItems 33 | 34 | #endif // LAYERS_HPP 35 | -------------------------------------------------------------------------------- /src/view/scene_items/node_model.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2022 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef NODE_MODEL_HPP 17 | #define NODE_MODEL_HPP 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace SceneItems { 25 | 26 | struct NodeModel 27 | { 28 | NodeModel(QColor color, QColor textColor) 29 | : color(color) 30 | , textColor(textColor) 31 | { 32 | } 33 | 34 | QColor color; 35 | 36 | int index = -1; 37 | 38 | size_t imageRef = 0; 39 | 40 | QPointF location; 41 | 42 | QSizeF size; 43 | 44 | QColor textColor; 45 | 46 | QString text; 47 | }; 48 | 49 | } // namespace SceneItems 50 | 51 | #endif // NODE_MODEL_HPP 52 | -------------------------------------------------------------------------------- /src/view/scene_items/scene_item_base.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef SCENE_ITEM_BASE_HPP 17 | #define SCENE_ITEM_BASE_HPP 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace SceneItems { 24 | 25 | class SceneItemBase : public QObject, public QGraphicsItem 26 | { 27 | Q_OBJECT 28 | Q_INTERFACES(QGraphicsItem) 29 | Q_PROPERTY(qreal scale READ scale WRITE setScale) 30 | Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) 31 | 32 | public: 33 | SceneItemBase(); 34 | 35 | virtual ~SceneItemBase() override; 36 | 37 | virtual void appearWithAnimation(); 38 | 39 | virtual void disappearWithAnimation(); 40 | 41 | virtual void enableShadowEffect(bool enable); 42 | 43 | virtual void removeFromScene(); 44 | 45 | virtual void removeFromSceneWithAnimation(); 46 | 47 | virtual void raiseWithAnimation(double targetScale); 48 | 49 | virtual void lowerWithAnimation(); 50 | 51 | void setAnimationDuration(int durationMs); 52 | 53 | void setAnimationOpacity(qreal newAnimationOpacity); 54 | 55 | qreal targetScale() const; 56 | 57 | protected slots: 58 | virtual void retranslate(); 59 | 60 | private: 61 | int m_animationDuration = 75; 62 | 63 | qreal m_animationOpacity = 1.0; 64 | 65 | qreal m_targetScale = 1.0; 66 | 67 | QPropertyAnimation m_opacityAnimation; 68 | 69 | QPropertyAnimation m_scaleAnimation; 70 | }; 71 | 72 | } // namespace SceneItems 73 | 74 | #endif // SCENE_ITEM_BASE_HPP 75 | -------------------------------------------------------------------------------- /src/view/scene_items/text_edit.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2018 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef TEXT_EDIT_HPP 17 | #define TEXT_EDIT_HPP 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace SceneItems { 24 | 25 | class TextEdit : public QGraphicsTextItem 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | explicit TextEdit(QGraphicsItem * parentItem); 31 | 32 | QColor backgroundColor() const; 33 | 34 | virtual void setBackgroundColor(const QColor & backgroundColor); 35 | 36 | virtual void selectText(const QString & text); 37 | 38 | virtual void unselectText(); 39 | 40 | virtual void setTextSize(int textSize); 41 | 42 | virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) override; 43 | 44 | QString text() const; 45 | 46 | void setText(const QString & text); 47 | 48 | virtual ~TextEdit() override; 49 | 50 | signals: 51 | 52 | void textChanged(QString text); 53 | 54 | void undoPointRequested(); 55 | 56 | protected: 57 | virtual bool event(QEvent * event) override; 58 | 59 | virtual void keyPressEvent(QKeyEvent * event) override; 60 | 61 | virtual void mousePressEvent(QGraphicsSceneMouseEvent * event) override; 62 | 63 | virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent * event) override; 64 | 65 | private: 66 | double m_maxHeight = 0; 67 | 68 | double m_maxWidth = 0; 69 | 70 | QColor m_backgroundColor = QColor(192, 192, 192, 64); 71 | 72 | QString m_text; 73 | 74 | int m_textSize = 0; 75 | 76 | QTextCharFormat m_unselectedFormat; 77 | }; 78 | 79 | } // namespace SceneItems 80 | 81 | #endif // TEXT_EDIT_HPP 82 | -------------------------------------------------------------------------------- /src/view/widgets/font_button.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #include "font_button.hpp" 17 | 18 | #include "../../common/constants.hpp" 19 | 20 | #include "simple_logger.hpp" 21 | 22 | #include 23 | #include 24 | 25 | namespace Widgets { 26 | 27 | static const auto TAG = "FontButton"; 28 | 29 | FontButton::FontButton(QWidget * parent) 30 | : QPushButton(parent) 31 | { 32 | setText(tr("Font") + Constants::Misc::threeDots()); 33 | 34 | connect(this, &QPushButton::clicked, this, [=] { 35 | bool ok; 36 | auto defaultFont = font(); 37 | emit defaultFontSizeRequested(); 38 | defaultFont.setPointSize(m_defaultPointSize); 39 | const auto font = QFontDialog::getFont(&ok, defaultFont, this); 40 | if (ok) { 41 | // Note: Support for multiple families implemented in Qt 5.13 => 42 | juzzlin::L(TAG).debug() << "Font family selected: '" << font.family().toStdString() << "'"; 43 | juzzlin::L(TAG).debug() << "Font weight selected: " << font.weight(); 44 | updateFont(font); 45 | emit fontSizeChanged(font.pointSize()); 46 | emit fontChanged(font); 47 | } 48 | }); 49 | } 50 | 51 | void FontButton::updateFont(const QFont & font) 52 | { 53 | QFont newFont(font); 54 | newFont.setPointSize(this->font().pointSize()); 55 | setFont(newFont); 56 | } 57 | 58 | void FontButton::setDefaultPointSize(int defaultPointSize) 59 | { 60 | m_defaultPointSize = defaultPointSize; 61 | } 62 | 63 | } // namespace Widgets 64 | -------------------------------------------------------------------------------- /src/view/widgets/font_button.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef FONT_BUTTON_HPP 17 | #define FONT_BUTTON_HPP 18 | 19 | #include 20 | 21 | class QFont; 22 | 23 | namespace Widgets { 24 | 25 | class FontButton : public QPushButton 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | explicit FontButton(QWidget * parent = nullptr); 31 | 32 | void setDefaultPointSize(int defaultPointSize); 33 | 34 | signals: 35 | void defaultFontSizeRequested(); 36 | 37 | void fontChanged(const QFont & font); 38 | 39 | void fontSizeChanged(int pointSize); 40 | 41 | private: 42 | void updateFont(const QFont & font); 43 | 44 | int m_defaultPointSize = 0; 45 | }; 46 | 47 | } // namespace Widgets 48 | 49 | #endif // FONT_BUTTON_HPP 50 | -------------------------------------------------------------------------------- /src/view/widgets/status_label.hpp: -------------------------------------------------------------------------------- 1 | // This file is part of Heimer. 2 | // Copyright (C) 2023 Jussi Lind 3 | // 4 | // Heimer is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // Heimer is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // along with Heimer. If not, see . 15 | 16 | #ifndef STATUS_LABEL_HPP 17 | #define STATUS_LABEL_HPP 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | class EditorView; 26 | 27 | namespace Widgets { 28 | 29 | class StatusLabel : public QLabel 30 | { 31 | Q_OBJECT 32 | Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) 33 | 34 | public: 35 | StatusLabel(EditorView & editorView, QString message); 36 | 37 | void updateGeometry(); 38 | 39 | signals: 40 | void scaleChanged(qreal scale); 41 | 42 | private: 43 | qreal scale() const; 44 | 45 | void setScale(qreal scale); 46 | 47 | EditorView & m_editorView; 48 | 49 | qreal m_scale = 1.0; 50 | 51 | QPropertyAnimation m_scaleAnimation; 52 | 53 | std::optional m_initialSize; 54 | 55 | QTimer m_scaleAnimationDelayTimer; 56 | }; 57 | 58 | } // namespace Widgets 59 | 60 | #endif // STATUS_LABEL_HPP 61 | --------------------------------------------------------------------------------