├── .gitignore ├── avogadro ├── avogadroappconfig.h.in ├── icons │ ├── avogadro.rc │ ├── cml.icns │ ├── cml.ico │ ├── doc.icns │ ├── doc.ico │ ├── Assets.car │ ├── cjson.icns │ ├── cjson.ico │ ├── cml_512.png │ ├── doc_512.png │ ├── 3dx_pivot.png │ ├── AppIcon.icns │ ├── avogadro.icns │ ├── avogadro.ico │ ├── avogadro.png │ ├── cjson_512.png │ ├── avogadro2_44.png │ ├── avogadro2_64.png │ ├── avogadro2_71.png │ ├── avogadro@2x.png │ ├── avogadro2_1024.png │ ├── avogadro2_128.png │ ├── avogadro2_150.png │ ├── avogadro2_256.png │ ├── avogadro2_310.png │ ├── avogadro2_512.png │ ├── Avogadro2-310x150.png │ ├── Avogadro2-about-dark.png │ ├── Avogadro2-about-light.png │ ├── Avogadro2-about-dark@2x.png │ └── Avogadro2-about-light@2x.png ├── avogadro.qrc ├── metainfo │ └── org.openchemistry.Avogadro2.desktop ├── tooltipfilter.h ├── application.h ├── aboutdialog.h ├── tooltipfilter.cpp ├── viewfactory.h ├── mac.mm ├── renderingdialog.h ├── viewfactory.cpp ├── rpclistener.h ├── application.cpp ├── backgroundfileformat.h ├── menubuilder.h ├── lastinstall │ └── CMakeLists.txt ├── aboutdialog.cpp ├── backgroundfileformat.cpp ├── renderingdialog.cpp └── tdxcontroller.h ├── .codacy.yaml ├── .gitmodules ├── .github ├── FUNDING.yml ├── dependabot.yml ├── move.yml ├── workflows │ ├── add_artifact_urls.yml │ ├── release-drafter.yml │ ├── update-i18n-templates.yml │ ├── clang-format-check.yml │ ├── codacy.yml │ ├── clang-tidy.yml │ ├── build_flatpak.yml │ ├── build_linux_arm64.yml │ ├── build_windows.yml │ ├── build_win_arm.yml │ └── build_linux.yml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── release-drafter.yml ├── config.yml ├── PULL_REQUEST_TEMPLATE └── actions │ └── checkout-repositories │ └── action.yml ├── thirdparty └── 3DConnexion │ ├── README.txt │ ├── src │ ├── navlib_load.cpp │ └── navlib_stub.c │ └── inc │ ├── SpaceMouse │ ├── IActionAccessors.hpp │ ├── IAccessors.hpp │ ├── IState.hpp │ ├── CCommandSet.hpp │ ├── CCategory.hpp │ ├── ISpace3D.hpp │ ├── CCommand.hpp │ ├── IEvents.hpp │ ├── IPivot.hpp │ ├── IHit.hpp │ ├── INavlib.hpp │ ├── CCookieCollection.hpp │ ├── CHitTest.hpp │ ├── IModel.hpp │ └── IView.hpp │ └── navlib │ ├── navlib_defines.h │ ├── navlib_error.h │ └── navlib_operators.h ├── CTestConfig.cmake ├── .clang-format ├── scripts ├── travis │ └── run_clang_format_diff.sh ├── copy-default.py ├── avogadro-remote.py ├── extract-messages.sh └── filter_sarif.py ├── cmake ├── Entitlements.plist ├── BuildLocation.cmake ├── BuildType.cmake ├── AvogadroCPackOptions.cmake.in ├── BuildPackageTest.cmake ├── deploy-osx.cmake.in ├── BuildPackage.cmake.in ├── InstallLocation.cmake ├── CompilerFlags.cmake ├── DetermineVersion.cmake ├── AppxManifest.xml.in └── AvogadroCPack.cmake ├── docs └── CMakeLists.txt ├── CONTRIBUTING.md ├── SECURITY.md ├── .clang-tidy ├── tests └── CMakeLists.txt ├── LICENSE ├── CMakeLists.txt ├── README.md └── flatpak └── org.openchemistry.Avogadro2.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | cmake-build-*/ 3 | -------------------------------------------------------------------------------- /avogadro/avogadroappconfig.h.in: -------------------------------------------------------------------------------- 1 | #cmakedefine AvogadroApp_VERSION "@AvogadroApp_VERSION@" 2 | -------------------------------------------------------------------------------- /avogadro/icons/avogadro.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON "avogadro.ico" 2 | -------------------------------------------------------------------------------- /avogadro/icons/cml.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/cml.icns -------------------------------------------------------------------------------- /avogadro/icons/cml.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/cml.ico -------------------------------------------------------------------------------- /avogadro/icons/doc.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/doc.icns -------------------------------------------------------------------------------- /avogadro/icons/doc.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/doc.ico -------------------------------------------------------------------------------- /avogadro/icons/Assets.car: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/Assets.car -------------------------------------------------------------------------------- /avogadro/icons/cjson.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/cjson.icns -------------------------------------------------------------------------------- /avogadro/icons/cjson.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/cjson.ico -------------------------------------------------------------------------------- /avogadro/icons/cml_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/cml_512.png -------------------------------------------------------------------------------- /avogadro/icons/doc_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/doc_512.png -------------------------------------------------------------------------------- /.codacy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | engines: 3 | cppcheck: 4 | language: c++ 5 | exclude_paths: 6 | - "thirdparty/**" 7 | -------------------------------------------------------------------------------- /avogadro/icons/3dx_pivot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/3dx_pivot.png -------------------------------------------------------------------------------- /avogadro/icons/AppIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/AppIcon.icns -------------------------------------------------------------------------------- /avogadro/icons/avogadro.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro.icns -------------------------------------------------------------------------------- /avogadro/icons/avogadro.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro.ico -------------------------------------------------------------------------------- /avogadro/icons/avogadro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro.png -------------------------------------------------------------------------------- /avogadro/icons/cjson_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/cjson_512.png -------------------------------------------------------------------------------- /avogadro/icons/avogadro2_44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro2_44.png -------------------------------------------------------------------------------- /avogadro/icons/avogadro2_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro2_64.png -------------------------------------------------------------------------------- /avogadro/icons/avogadro2_71.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro2_71.png -------------------------------------------------------------------------------- /avogadro/icons/avogadro@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro@2x.png -------------------------------------------------------------------------------- /avogadro/icons/avogadro2_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro2_1024.png -------------------------------------------------------------------------------- /avogadro/icons/avogadro2_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro2_128.png -------------------------------------------------------------------------------- /avogadro/icons/avogadro2_150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro2_150.png -------------------------------------------------------------------------------- /avogadro/icons/avogadro2_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro2_256.png -------------------------------------------------------------------------------- /avogadro/icons/avogadro2_310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro2_310.png -------------------------------------------------------------------------------- /avogadro/icons/avogadro2_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/avogadro2_512.png -------------------------------------------------------------------------------- /avogadro/icons/Avogadro2-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/Avogadro2-310x150.png -------------------------------------------------------------------------------- /avogadro/icons/Avogadro2-about-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/Avogadro2-about-dark.png -------------------------------------------------------------------------------- /avogadro/icons/Avogadro2-about-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/Avogadro2-about-light.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "flatpak/shared-modules"] 2 | path = flatpak/shared-modules 3 | url = https://github.com/flathub/shared-modules.git 4 | -------------------------------------------------------------------------------- /avogadro/icons/Avogadro2-about-dark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/Avogadro2-about-dark@2x.png -------------------------------------------------------------------------------- /avogadro/icons/Avogadro2-about-light@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenChemistry/avogadroapp/HEAD/avogadro/icons/Avogadro2-about-light@2x.png -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | open_collective: avogadro # Replace with a single Open Collective username 4 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/README.txt: -------------------------------------------------------------------------------- 1 | This directory contains part of the the 3Dconnexion 3DxWare_SDK v4 2 | The full sdk can be obtained from https://3dconnexion.com/software-developer-program/ 3 | 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Set update schedule for GitHub Actions 2 | 3 | version: 2 4 | updates: 5 | 6 | - package-ecosystem: "github-actions" 7 | directory: "/" 8 | schedule: 9 | # Check for updates to GitHub Actions every weekday 10 | interval: "daily" 11 | -------------------------------------------------------------------------------- /CTestConfig.cmake: -------------------------------------------------------------------------------- 1 | set(CTEST_PROJECT_NAME "AvogadroApp") 2 | set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") 3 | 4 | set(CTEST_DROP_METHOD "http") 5 | set(CTEST_DROP_SITE "cdash.openchemistry.org") 6 | set(CTEST_DROP_LOCATION "/submit.php?project=AvogadroApp") 7 | set(CTEST_DROP_SITE_CDASH TRUE) 8 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | # This configuration requires clang-format 3.8 or higher. 3 | BasedOnStyle: Mozilla 4 | AlwaysBreakAfterReturnType: None 5 | AlwaysBreakAfterDefinitionReturnType: None 6 | BinPackArguments: true 7 | BinPackParameters: true 8 | BreakConstructorInitializersBeforeComma: false 9 | ... 10 | -------------------------------------------------------------------------------- /scripts/travis/run_clang_format_diff.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DIFF=`git diff -U0 $1...$2 -- '*.h' '*.cpp' | clang-format-diff-6.0 -p1` 3 | if [ -z "$DIFF" ]; then 4 | exit 0 5 | else 6 | printf "ERROR: clang-format-diff detected formatting issues. Please run clang-format on your branch.\nThe following formatting changes are suggested:\n\n%s" "$DIFF" 7 | exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /cmake/Entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.disable-library-validation 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /avogadro/avogadro.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | icons/avogadro.png 4 | icons/avogadro@2x.png 5 | icons/Avogadro2-about-dark.png 6 | icons/Avogadro2-about-dark@2x.png 7 | icons/Avogadro2-about-light.png 8 | icons/Avogadro2-about-light@2x.png 9 | 10 | 11 | -------------------------------------------------------------------------------- /avogadro/metainfo/org.openchemistry.Avogadro2.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Type=Application 4 | Name=Avogadro 5 | Comment=Advanced molecular editor 6 | Comment[hu]=Fejlett molekuláris szerkesztő 7 | Icon=org.openchemistry.Avogadro2 8 | Categories=Science;Chemistry;Physics;Education;Qt; 9 | MimeType=chemical/x-cml;chemical/x-xyz; 10 | Exec=avogadro2 %f 11 | Terminal=false 12 | StartupNotify=true 13 | -------------------------------------------------------------------------------- /cmake/BuildLocation.cmake: -------------------------------------------------------------------------------- 1 | # Set up our directory structure for output libraries and binaries 2 | if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) 3 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") 4 | endif() 5 | if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) 6 | if(UNIX) 7 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") 8 | else() 9 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") 10 | endif() 11 | endif() 12 | -------------------------------------------------------------------------------- /docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Doxygen REQUIRED) 2 | 3 | set(doxygen_source_dirs "${ChemData_SOURCE_DIR}/avogadro") 4 | set(doxygen_output_dir "${ChemData_BINARY_DIR}/docs") 5 | 6 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/doxyfile.in" 7 | "${CMAKE_CURRENT_BINARY_DIR}/doxyfile") 8 | 9 | add_custom_target(documentation 10 | COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_BINARY_DIR}/html 11 | COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxyfile) 12 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/src/navlib_load.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | 4 | Copyright (c) 2014-2023 3Dconnexion. 5 | 6 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 7 | ******************************************************************************/ 8 | 9 | extern "C" { 10 | extern long NlLoadLibrary(); 11 | extern const long NlErrorCode = NlLoadLibrary(); 12 | } 13 | -------------------------------------------------------------------------------- /avogadro/tooltipfilter.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #include 7 | #include 8 | 9 | class ToolTipFilter : public QObject 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | ToolTipFilter(QObject *parent); 15 | 16 | bool eventFilter(QObject *object, QEvent *event); 17 | }; -------------------------------------------------------------------------------- /.github/move.yml: -------------------------------------------------------------------------------- 1 | # Configuration for move-issues - https://github.com/dessant/move-issues 2 | 3 | # Delete the command comment when it contains no other content 4 | deleteCommand: true 5 | 6 | # Close the source issue after moving 7 | closeSourceIssue: true 8 | 9 | # Lock the source issue after moving 10 | lockSourceIssue: false 11 | 12 | # Mention issue and comment authors 13 | mentionAuthors: true 14 | 15 | # Preserve mentions in the issue content 16 | keepContentMentions: false 17 | 18 | # Set custom aliases for targets 19 | # aliases: 20 | # r: repo 21 | # or: owner/repo 22 | 23 | # Repository to extend settings from 24 | # _extends: repo 25 | -------------------------------------------------------------------------------- /cmake/BuildType.cmake: -------------------------------------------------------------------------------- 1 | # Set a default build type if none was specified 2 | set(_build_type "Release") 3 | if(EXISTS "${CMAKE_SOURCE_DIR}/.git") 4 | set(_build_type "Debug") 5 | endif() 6 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 7 | message(STATUS "Setting build type to '${_build_type}' as none was specified.") 8 | set(CMAKE_BUILD_TYPE ${_build_type} 9 | CACHE STRING "Choose the type of build." FORCE) 10 | # Set the possible values of build type for cmake-gui 11 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" 12 | "MinSizeRel" "RelWithDebInfo" "ASAN" "TSAN" "MSAN" "LSAN" "UBSAN") 13 | endif() 14 | -------------------------------------------------------------------------------- /.github/workflows/add_artifact_urls.yml: -------------------------------------------------------------------------------- 1 | name: add artifact links to pull request 2 | on: 3 | workflow_run: 4 | workflows: ['Qt5 Build Matrix'] 5 | types: [completed] 6 | 7 | jobs: 8 | artifacts-url-comments: 9 | name: add artifact links to pull request job 10 | runs-on: windows-latest 11 | steps: 12 | - name: add artifact links to pull request step 13 | uses: tonyhallett/artifacts-url-comments@0965ff1a7ae03c5c1644d3c30f956effea4e05ef # v1.1.0 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | with: 17 | prefix: Here are the build results 18 | suffix: Artifacts will only be retained for 90 days. 19 | format: name 20 | addTo: pull 21 | continue-on-error: true 22 | -------------------------------------------------------------------------------- /avogadro/application.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #ifndef AVOGADRO_APPLICATION_H 7 | #define AVOGADRO_APPLICATION_H 8 | 9 | #include 10 | 11 | namespace Avogadro { 12 | 13 | class Application : public QApplication 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | Application(int& argc, char** argv); 19 | bool loadFile(const QString& fileName); 20 | 21 | protected: 22 | bool event(QEvent* event); 23 | 24 | private: 25 | }; 26 | 27 | } // end namespace Avogadro 28 | #endif 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I wish Avogadro calculated XYQ moments to render with .. 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. Please be detailed. How might this feature work (e.g., first a window would open and you'd click to …) 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | 19 | Please consider opening a topic on https://discuss.avogadro.cc/ to allow further public discussion 20 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: 'Avogadro $RESOLVED_VERSION' 2 | tag-template: '$RESOLVED_VERSION' 3 | categories: 4 | - title: 'Features' 5 | labels: 6 | - 'feature' 7 | - 'enhancement' 8 | - title: '🐛 Bug Fixes' 9 | labels: 10 | - 'fix' 11 | - 'bugfix' 12 | - 'bug' 13 | - title: '🧰 Maintenance' 14 | labels: 15 | - 'chore' 16 | - 'build' 17 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)' 18 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. 19 | version-resolver: 20 | major: 21 | labels: 22 | - 'major' 23 | minor: 24 | labels: 25 | - 'minor' 26 | patch: 27 | labels: 28 | - 'patch' 29 | default: minor 30 | template: | 31 | ## Changes 32 | 33 | $CHANGES 34 | 35 | ## Credits 36 | 37 | Thanks to many contributors, including: $CONTRIBUTORS 38 | 39 | -------------------------------------------------------------------------------- /avogadro/aboutdialog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #ifndef AVOGADRO_ABOUTDIALOG_H 7 | #define AVOGADRO_ABOUTDIALOG_H 8 | 9 | #include 10 | 11 | namespace Ui { 12 | class AboutDialog; 13 | } 14 | 15 | namespace Avogadro { 16 | 17 | class AboutDialog : public QDialog 18 | { 19 | Q_OBJECT 20 | public: 21 | AboutDialog(QWidget* Parent); 22 | ~AboutDialog(); 23 | 24 | void loadImage(const QString& theme); 25 | 26 | // handle theme changes 27 | void changeEvent(QEvent* event) override; 28 | 29 | private: 30 | Ui::AboutDialog* m_ui; 31 | }; 32 | 33 | } // End Avogadro namespace 34 | 35 | #endif // AVOGADRO_ABOUTDIALOG_H 36 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ------------ 3 | 4 | Our project uses the standard GitHub pull request process for code review 5 | and integration. Please check our [development][Development] guide for more 6 | details on developing and contributing to the project. The GitHub issue 7 | tracker can be used to report bugs, make feature requests, etc. 8 | 9 | Our [wiki][Wiki] is used to document features, flesh out designs and host other 10 | documentation. Our API is documented using Doxygen with updated 11 | documentation generated nightly. We have several [mailing lists][MailingLists] 12 | to coordinate development and to provide support. 13 | 14 | [Development]: http://wiki.openchemistry.org/Development "Development guide" 15 | [Wiki]: http://wiki.openchemistry.org/ "Open Chemistry wiki" 16 | [Doxygen]: http://doc.openchemistry.org/avogadrolibs/api/ "API documentation" 17 | [MailingLists]: http://openchemistry.org/mailing-lists "Mailing Lists" 18 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | At the moment, Avogadro2 is in beta release. As such, we can most easily support 6 | security updates on the most recent release and current nightly snapshots. 7 | We will work with distributions (e.g., Ubuntu, FreeBSD, etc.) to provide security 8 | patches for widely used long-term-support OS. 9 | 10 | | Version | Supported | 11 | | ------- | ------------------ | 12 | | 1.102.x | :white_check_mark: | 13 | | 1.101.x | :white_check_mark: | 14 | | < 1.101 | :x: | 15 | 16 | ## Reporting a Vulnerability 17 | 18 | We currently support private security vulnerability reporting through our 19 | [GitHub](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability) 20 | pages. We will work to verify the security vulnerability within 14 days 21 | and a patch or new release within 30 days of reporting. 22 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: 'clang-analyzer*,modernize-avoid-bind,modernize-concat-nested-namespaces, 2 | modernize-loop-convert,modernize-macro-to-enum,modernize-use-bool-literals, 3 | modernize-use-auto,modernize-use-nullptr,modernize-use-override, 4 | modernize-raw-string-literal,modernize-use-emplace,modernize-pass-by-value 5 | misc-unused-using-decls, 6 | misc-unused-alias-decls, 7 | misc-redundant-expression, 8 | performance-for-range-copy, 9 | performance-inefficient*,performance-type-promotion*, 10 | performance-unnecessary-copy-initialization, 11 | performance-move-const-arg, 12 | readability-const-return-type, 13 | readability-delete-null-pointer, 14 | readability-redundant-string-cstr, 15 | readability-simplify* 16 | -readability-else-after-return, 17 | -portability-restrict-system-includes, 18 | -modernize-use-trailing-return-type' 19 | FormatStyle: file 20 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | # https://github.com/release-drafter/release-drafter 3 | 4 | on: 5 | push: 6 | # branches to consider in the event; optional, defaults to all 7 | branches: 8 | - master 9 | # pull_request event is required only for autolabeler 10 | pull_request: 11 | # Only following types are handled by the action, but one can default to all as well 12 | types: [opened, reopened, synchronize] 13 | 14 | jobs: 15 | update_release_draft: 16 | runs-on: ubuntu-latest 17 | steps: 18 | # Drafts your next Release notes as Pull Requests are merged into "master" 19 | - uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0 20 | # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml 21 | # with: 22 | # config-name: my-config.yml 23 | # disable-autolabeler: true 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Avogadro version: (please complete the following information from the About box):** 8 | - Avogadrolibs: (e.g. 1.90.0-316-g6d14770) 9 | - Qt: (e.g., 5.9.5) 10 | 11 | **Desktop version: (please complete the following information):** 12 | - OS: [e.g. MacOS] 13 | - Version [e.g. 10.12.4] 14 | - Compiler (if you built from source) 15 | 16 | **Describe the bug** 17 | A clear and concise description of what the bug is. 18 | 19 | **To Reproduce** 20 | Steps to reproduce the behavior: 21 | 1. Go to '...' 22 | 2. Click on '....' 23 | 3. Scroll down to '....' 24 | 4. See error 25 | 26 | **Expected behavior** 27 | A clear and concise description of what you expected to happen. 28 | 29 | **Screenshots** 30 | If applicable, add screenshots to help explain your problem. 31 | 32 | **Additional context** 33 | Add any other context about the problem here. **Please consider uploading or linking test files.** 34 | -------------------------------------------------------------------------------- /avogadro/tooltipfilter.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #include "tooltipfilter.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | ToolTipFilter::ToolTipFilter(QObject* parent) 14 | : QObject(parent) 15 | {} 16 | 17 | bool ToolTipFilter::eventFilter(QObject* object, QEvent* event) 18 | { 19 | // Fire off a toolTip item for an enter event 20 | if (event->type() == QEvent::Enter) { 21 | QWidget* target = qobject_cast(object); 22 | auto* ee = dynamic_cast(event); 23 | if (target && ee) { 24 | QToolTip::showText(ee->globalPos(), target->toolTip(), target); 25 | return true; 26 | } 27 | } 28 | 29 | return false; 30 | } 31 | -------------------------------------------------------------------------------- /avogadro/viewfactory.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #ifndef AVOGADRO_VIEWFACTORY_H 7 | #define AVOGADRO_VIEWFACTORY_H 8 | 9 | #include 10 | #include 11 | #ifdef AVO_USE_VTK 12 | #include 13 | #endif 14 | 15 | namespace Avogadro { 16 | 17 | class ViewFactory : public QtGui::ViewFactory 18 | { 19 | public: 20 | ViewFactory(); 21 | ~ViewFactory(); 22 | 23 | QStringList views() const; 24 | QWidget* createView(const QString& view); 25 | void setGLWidget(QtOpenGL::GLWidget* glWidget) { m_glWidget = glWidget; } 26 | 27 | protected: 28 | QtOpenGL::GLWidget* m_glWidget = nullptr; 29 | }; 30 | 31 | } // End namespace Avogadro 32 | 33 | #endif // AVOGADRO_AVOGADROVIEWFACTORY_H 34 | -------------------------------------------------------------------------------- /.github/config.yml: -------------------------------------------------------------------------------- 1 | # Configuration for welcome - https://github.com/behaviorbot/welcome 2 | 3 | # Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome 4 | 5 | # Comment to be posted to on first time issues 6 | newIssueWelcomeComment: > 7 | Thanks for opening your first issue here! Please try to include example files and screenshots if possible. 8 | If you're looking for support, please post on our forum: https://discuss.avogadro.cc/ 9 | # Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome 10 | 11 | # Comment to be posted to on PRs from first time contributors in your repository 12 | newPRWelcomeComment: > 13 | Thanks for opening this pull request! Please check out our contributing guidelines and check for the automated tests. 14 | # Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge 15 | 16 | # Comment to be posted to on pull requests merged by a first time user 17 | firstPRMergeComment: > 18 | Congrats on merging your first pull request! 🎉 Thanks for making Avogadro better for everyone! 19 | -------------------------------------------------------------------------------- /.github/workflows/update-i18n-templates.yml: -------------------------------------------------------------------------------- 1 | name: update-i18n-templates 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | schedule: 7 | # * is a special character in YAML so you have to quote this string 8 | # run weekly, every Sunday at 01:23 9 | - cron: '23 1 * * 0' 10 | 11 | jobs: 12 | update-i18n: 13 | name: Update translation templates 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 17 | 18 | - name: Install packages 19 | run: | 20 | sudo apt-get -qq update 21 | sudo apt-get -qq install gettext 22 | 23 | - name: Run extract-messages 24 | run: | 25 | sh scripts/extract-messages.sh 26 | 27 | - name: Create pull request 28 | uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 29 | with: 30 | commit-message: "Automated translation updates" 31 | signoff: true 32 | title: "Automated translation updates" 33 | branch: update-i18n-templates 34 | delete-branch: true 35 | labels: i18n 36 | -------------------------------------------------------------------------------- /cmake/AvogadroCPackOptions.cmake.in: -------------------------------------------------------------------------------- 1 | # This file is configured at cmake time, loaded at cpack time. 2 | 3 | # NSIS specific settings 4 | if(CPACK_GENERATOR MATCHES "NSIS") 5 | set(CPACK_NSIS_MUI_ICON "@CMAKE_SOURCE_DIR@/avogadro/icons\\\\avogadro.ico") 6 | set(CPACK_NSIS_HELP_LINK "https:\\\\two.avogadro.cc") 7 | set(CPACK_NSIS_URL_INFO_ABOUT "https:\\\\two.avogadro.cc") 8 | set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\Avogadro2.exe") 9 | set(CPACK_NSIS_MENU_LINKS 10 | "https://two.avogadro.cc/" "Avogadro Project") 11 | set(CPACK_NSIS_MODIFY_PATH ON) 12 | endif() 13 | 14 | # Mac DMG specific settings 15 | if(CPACK_GENERATOR MATCHES "DragNDrop") 16 | set(CPACK_DMG_FORMAT "UDBZ") 17 | # check if the environment variable "SNAPSHOT_DATE" is set 18 | if(DEFINED ENV{SNAPSHOT_DATE}) 19 | set(VERSION "$ENV{SNAPSHOT_DATE}") 20 | else() 21 | set(VERSION "${CPACK_PACKAGE_VERSION}") 22 | endif() 23 | # this also sets the volume name 24 | set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${VERSION}") 25 | endif() 26 | 27 | if("${CPACK_GENERATOR}" STREQUAL "PackageMaker") 28 | set(CPACK_PACKAGE_DEFAULT_LOCATION "/Applications") 29 | endif() 30 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(AvogadroLibs REQUIRED NO_MODULE) 2 | # The data repository should be at the side of ours. 3 | find_path(AVOGADRO_DATA_ROOT .avogadro.data 4 | ${AvogadroApp_SOURCE_DIR}/../avogadrodata 5 | $ENV{AVOGADRO_DATA_ROOT} 6 | DOC "The repository for data used for testing." 7 | ) 8 | mark_as_advanced(AVOGADRO_DATA_ROOT) 9 | 10 | if(AVOGADRO_DATA_ROOT) 11 | set(AVOGADRO_DATA ${AVOGADRO_DATA_ROOT}) 12 | else() 13 | message("No data root found, please set to run the tests.") 14 | return() 15 | endif() 16 | 17 | file(GLOB test_xml 18 | RELATIVE "${AVOGADRO_DATA}/tests/avogadro/xml" 19 | "${AVOGADRO_DATA}/tests/avogadro/xml/*.xml") 20 | 21 | foreach(xml ${test_xml}) 22 | get_filename_component(name "${xml}" NAME_WE) 23 | message("Adding test: ${name} from XML") 24 | add_test(NAME avogadro-${name} 25 | COMMAND avogadro 26 | --disable-settings 27 | --test-file "${AVOGADRO_DATA}/tests/avogadro/xml/${xml}") 28 | # Ensure we pass in an absolute path to the prefix so that we find the plugins 29 | set_tests_properties(avogadro-${name} PROPERTIES 30 | ENVIRONMENT "AVOGADRO_PLUGIN_DIR=${AvogadroLibs_INSTALL_PREFIX}") 31 | endforeach() 32 | -------------------------------------------------------------------------------- /avogadro/mac.mm: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #import 7 | 8 | // Set some Mac compatibility bits using Objective-C++ 9 | // From https://forum.qt.io/topic/60623/qt-5-4-2-os-x-10-11-el-capitan-how-to-remove-the-enter-full-screen-menu-item/ 10 | // From https://github.com/opencor/opencor/blob/master/src/misc/macos.mm 11 | void removeMacSpecificMenuItems() { 12 | // Remove (disable) the "Start Dictation..." and "Emoji & Symbols" menu items 13 | // from the "Edit" menu 14 | [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSDisabledDictationMenuItem"]; 15 | [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSDisabledCharacterPaletteMenuItem"]; 16 | 17 | #ifdef AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER 18 | if ([NSWindow respondsToSelector:@selector(allowsAutomaticWindowTabbing)]) 19 | NSWindow.allowsAutomaticWindowTabbing = NO; 20 | #endif 21 | 22 | return; 23 | } 24 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/IActionAccessors.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IActionAccessors_HPP_INCLUDED 2 | #define IActionAccessors_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id$ 17 | // 18 | // 19 | 20 | #include 21 | 22 | namespace TDx { 23 | namespace SpaceMouse { 24 | namespace ActionInput { 25 | /// 26 | /// The accessor interface to the client action input properties. 27 | /// 28 | class IActionAccessors : public Navigation3D::IEvents { 29 | }; 30 | } // namespace ActionInput 31 | } // namespace SpaceMouse 32 | } // namespace TDx 33 | #endif // IActionAccessors_HPP_INCLUDED 34 | -------------------------------------------------------------------------------- /cmake/BuildPackageTest.cmake: -------------------------------------------------------------------------------- 1 | get_filename_component(_BuildPackageTest_self_dir 2 | "${CMAKE_CURRENT_LIST_FILE}" PATH) 3 | 4 | 5 | if("$ENV{DASHBOARD_TEST_FROM_CTEST}" STREQUAL "") 6 | # Not a dashboard, do not add BuildPackage* tests by default: 7 | set(BUILD_PACKAGE_TEST_DEFAULT OFF) 8 | else() 9 | # Dashboard, do add BuildPackage* tests by default: 10 | set(BUILD_PACKAGE_TEST_DEFAULT ON) 11 | endif() 12 | 13 | 14 | option(BUILD_PACKAGE_TEST "Add BuildPackage* tests..." 15 | ${BUILD_PACKAGE_TEST_DEFAULT}) 16 | 17 | 18 | function(BuildPackageTest_Add projname binary_dir) 19 | if (NOT BUILD_PACKAGE_TEST) 20 | return() 21 | endif() 22 | 23 | # Use the NAME/COMMAND form of add_test and pass $. 24 | # However, using this form requires passing -C when running ctest 25 | # from the command line, or setting CTEST_CONFIGURATION_TYPE 26 | # in a -S script. 27 | 28 | configure_file( 29 | ${_BuildPackageTest_self_dir}/BuildPackage.cmake.in 30 | ${binary_dir}/BuildPackage${projname}.cmake 31 | @ONLY 32 | ) 33 | 34 | add_test( 35 | NAME BuildPackage${projname} 36 | COMMAND ${CMAKE_COMMAND} 37 | -D config=$ 38 | -P ${binary_dir}/BuildPackage${projname}.cmake 39 | ) 40 | endfunction() 41 | -------------------------------------------------------------------------------- /avogadro/renderingdialog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #ifndef AVOGADRO_RENDERINGDIALOG_H 7 | #define AVOGADRO_RENDERINGDIALOG_H 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace Ui { 14 | class RenderingDialog; 15 | } 16 | 17 | namespace Avogadro { 18 | 19 | using Rendering::SolidPipeline; 20 | 21 | class RenderingDialog : public QDialog 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | RenderingDialog(QWidget *parent, SolidPipeline &pipeline); 27 | ~RenderingDialog() override; 28 | 29 | bool aoEnabled(); 30 | float fogPosition(); 31 | float aoStrength(); 32 | float fogStrength(); 33 | bool fogEnabled(); 34 | bool dofEnabled(); 35 | float dofStrength(); 36 | float dofPosition(); 37 | bool edEnabled(); 38 | 39 | protected slots: 40 | void aoEnableCheckBoxChanged(int state); 41 | void fogEnableCheckBoxChanged(int state); 42 | void dofEnableCheckBoxChanged(int state); 43 | void saveButtonClicked(); 44 | void closeButtonClicked(); 45 | 46 | private: 47 | Ui::RenderingDialog *m_ui; 48 | SolidPipeline &m_solidPipeline; 49 | }; 50 | 51 | } // End namespace Avogadro 52 | 53 | #endif // AVOGADRO_RENDERINGDIALOG_H 54 | -------------------------------------------------------------------------------- /cmake/deploy-osx.cmake.in: -------------------------------------------------------------------------------- 1 | set(APP_BUNDLE_PATH "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/Avogadro2.app") 2 | set(APP_ZIP_PATH "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/Avogadro2.zip") 3 | 4 | include(BundleUtilities) 5 | fixup_bundle("${CPACK_TEMPORARY_INSTALL_DIRECTORY}/Avogadro2.app" "" "") 6 | 7 | if (DEFINED ENV{CODESIGN_IDENTITY}) 8 | # sign the Open Babel SO files 9 | file(GLOB OB_PLUGINS ${APP_BUNDLE_PATH}/Contents/lib/openbabel/*.so) 10 | 11 | foreach(ob_plugin ${OB_PLUGINS}) 12 | set(OB_ARGS 13 | codesign 14 | --force 15 | --timestamp 16 | --sign "$ENV{CODESIGN_IDENTITY}" 17 | ${ob_plugin} 18 | ) 19 | execute_process(COMMAND ${OB_ARGS} RESULT_VARIABLE EXIT_CODE) 20 | if(NOT EXIT_CODE EQUAL 0) 21 | message(FATAL_ERROR 22 | \"Running ${OB_ARGS} failed with exit code \${EXIT_CODE}.\") 23 | endif() 24 | endforeach() 25 | 26 | set(COMMAND_ARGS 27 | codesign 28 | --force 29 | --deep 30 | --timestamp 31 | --options runtime 32 | --entitlements "@CMAKE_SOURCE_DIR@/cmake/Entitlements.plist" 33 | --sign "$ENV{CODESIGN_IDENTITY}" 34 | ${APP_BUNDLE_PATH} 35 | ) 36 | execute_process(COMMAND ${COMMAND_ARGS} RESULT_VARIABLE EXIT_CODE) 37 | if(NOT EXIT_CODE EQUAL 0) 38 | message(FATAL_ERROR 39 | \"Running ${COMMAND_ARGS} failed with exit code \${EXIT_CODE}.\") 40 | endif() 41 | endif() -------------------------------------------------------------------------------- /avogadro/viewfactory.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #include "viewfactory.h" 7 | 8 | #include 9 | #ifdef AVO_USE_VTK 10 | #include 11 | #endif 12 | 13 | namespace Avogadro { 14 | 15 | ViewFactory::ViewFactory() {} 16 | 17 | ViewFactory::~ViewFactory() {} 18 | 19 | QStringList ViewFactory::views() const 20 | { 21 | QStringList views; 22 | views << QObject::tr("3D View"); 23 | #ifdef AVO_USE_VTK 24 | views << QObject::tr("VTK"); 25 | #endif 26 | return views; 27 | } 28 | 29 | QWidget* ViewFactory::createView(const QString& view) 30 | { 31 | if (view == QObject::tr("3D View")) { 32 | // get the background color, etc. 33 | if (m_glWidget != nullptr) { 34 | auto newWidget = new QtOpenGL::GLWidget(m_glWidget); 35 | // set the background color, etc. 36 | auto bgColor = m_glWidget->renderer().scene().backgroundColor(); 37 | newWidget->renderer().scene().setBackgroundColor(bgColor); 38 | return newWidget; 39 | } else 40 | return new QtOpenGL::GLWidget; 41 | } 42 | #ifdef AVO_USE_VTK 43 | else if (view == QObject::tr("VTK")) 44 | return new VTK::vtkGLWidget; 45 | #endif 46 | return nullptr; 47 | } 48 | 49 | } // End Avogadro namespace 50 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | Developer Certificate of Origin 2 | Version 1.1 3 | 4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 5 | 1 Letterman Drive 6 | Suite D4700 7 | San Francisco, CA, 94129 8 | 9 | Everyone is permitted to copy and distribute verbatim copies of this 10 | license document, but changing it is not allowed. 11 | 12 | 13 | Developer's Certificate of Origin 1.1 14 | 15 | By making a contribution to this project, I certify that: 16 | 17 | (a) The contribution was created in whole or in part by me and I 18 | have the right to submit it under the open source license 19 | indicated in the file; or 20 | 21 | (b) The contribution is based upon previous work that, to the best 22 | of my knowledge, is covered under an appropriate open source 23 | license and I have the right under that license to submit that 24 | work with modifications, whether created in whole or in part 25 | by me, under the same open source license (unless I am 26 | permitted to submit under a different license), as indicated 27 | in the file; or 28 | 29 | (c) The contribution was provided directly to me by some other 30 | person who certified (a), (b) or (c) and I have not modified 31 | it. 32 | 33 | (d) I understand and agree that this project and the contribution 34 | are public and that a record of the contribution (including all 35 | personal information I submit with it, including my sign-off) is 36 | maintained indefinitely and may be redistributed consistent with 37 | this project or the open source license(s) involved. 38 | -------------------------------------------------------------------------------- /cmake/BuildPackage.cmake.in: -------------------------------------------------------------------------------- 1 | # 2 | # Script used by the BuildPackageTest.cmake module. 3 | # 4 | 5 | message(STATUS "Running script '${CMAKE_CURRENT_LIST_FILE}'") 6 | message(STATUS " executing command '\"${CMAKE_COMMAND}\" --build . --config \"${config}\" --target package'") 7 | message(STATUS " in binary_dir='@binary_dir@'") 8 | message(STATUS "") 9 | 10 | set(results_script "@binary_dir@/BuildPackageTestResults.cmake") 11 | file(REMOVE "${results_script}") 12 | 13 | execute_process( 14 | COMMAND ${CMAKE_COMMAND} --build . --config "${config}" --target package 15 | WORKING_DIRECTORY "@binary_dir@" 16 | OUTPUT_VARIABLE output 17 | RESULT_VARIABLE result 18 | ) 19 | 20 | message(STATUS "output:") 21 | message(STATUS "${output}") 22 | message(STATUS "") 23 | 24 | if(NOT "${result}" STREQUAL "0") 25 | message(FATAL_ERROR "error: --build package call returned '${result}'") 26 | endif() 27 | 28 | 29 | # 30 | # Construct a list of package files by scraping individual file names from 31 | # the 'make package' output: 32 | # 33 | set(packages) 34 | set(regex "package: ([^\n]+) generated") 35 | 36 | string(REGEX MATCHALL "${regex}" package_lines "${output}") 37 | foreach(line ${package_lines}) 38 | string(REGEX REPLACE "${regex}" "\\1" package "${line}") 39 | list(APPEND packages "${package}") 40 | endforeach() 41 | 42 | 43 | # 44 | # Write out a helper script that can be used later to upload these: 45 | # 46 | file(WRITE "${results_script}" "# BuildPackageTestResults.cmake 47 | # generated by \"${CMAKE_CURRENT_LIST_FILE}\" 48 | # 49 | set(package_files \"${packages}\") 50 | ") 51 | -------------------------------------------------------------------------------- /scripts/copy-default.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Fill empty msgstr entries in PO files with msgid values. 4 | Usage: python copy-default.py [po-file] [--backup] 5 | 6 | Requires: pip install polib 7 | """ 8 | 9 | import sys 10 | from pathlib import Path 11 | 12 | try: 13 | import polib 14 | except ImportError: 15 | print("Error: polib module not found.", file=sys.stderr) 16 | print("Install it with: pip install polib", file=sys.stderr) 17 | sys.exit(1) 18 | 19 | 20 | def fill_empty_translations(filepath): 21 | """Fill empty msgstr with msgid values.""" 22 | path = Path(filepath) 23 | 24 | if not path.exists(): 25 | print(f"Error: File '{filepath}' not found.", file=sys.stderr) 26 | return False 27 | 28 | po = polib.pofile(filepath) 29 | filled_count = 0 30 | 31 | for entry in po: 32 | # Skip the header entry 33 | if entry.msgid == '': 34 | continue 35 | 36 | # If msgstr is empty, fill with msgid 37 | if entry.msgstr == '': 38 | entry.msgstr = entry.msgid 39 | filled_count += 1 40 | 41 | po.save(filepath) 42 | 43 | print(f"Processed: {path.name}") 44 | print(f"Filled {filled_count} empty msgstr entries.") 45 | return True 46 | 47 | 48 | if __name__ == '__main__': 49 | if len(sys.argv) < 2: 50 | print("Usage: python copy-default.py [po-file]") 51 | print("\nOptions:") 52 | sys.exit(1) 53 | 54 | po_file = sys.argv[1] 55 | 56 | success = fill_empty_translations(po_file) 57 | sys.exit(0 if success else 1) 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2020, Kitware, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors 15 | may be used to endorse or promote products derived from this software 16 | without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 26 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/IAccessors.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IAccessors_HPP_INCLUDED 2 | #define IAccessors_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: IAccessors.hpp 16047 2019-04-05 12:51:24Z mbonk $ 17 | // 18 | // 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace TDx { 29 | namespace SpaceMouse { 30 | namespace Navigation3D { 31 | /// 32 | /// The accessor interface to the client 3D properties. 33 | /// 34 | class IAccessors : public ISpace3D, 35 | public IView, 36 | public IModel, 37 | public IPivot, 38 | public IHit, 39 | public IEvents, 40 | public IState {}; 41 | } // namespace Navigation3D 42 | } // namespace SpaceMouse 43 | } // namespace TDx 44 | #endif // IAccessors_HPP_INCLUDED 45 | -------------------------------------------------------------------------------- /avogadro/rpclistener.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #ifndef AVOGADRO_RPCLISTENER_H 7 | #define AVOGADRO_RPCLISTENER_H 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace MoleQueue { 15 | class JsonRpc; 16 | class JsonRpcClient; 17 | class Message; 18 | } 19 | 20 | namespace Avogadro { 21 | 22 | namespace QtGui { 23 | class Molecule; 24 | } 25 | 26 | class MainWindow; 27 | 28 | /** 29 | * @brief The RpcListener class is used to implement the remote procedure call 30 | * interface for the Avogadro application. 31 | */ 32 | 33 | class RpcListener : public QObject 34 | { 35 | Q_OBJECT 36 | 37 | public: 38 | explicit RpcListener(QObject* parent = 0); 39 | ~RpcListener(); 40 | 41 | void start(); 42 | 43 | signals: 44 | /** 45 | * Calls the MainWidow::setMolecule() method with @p molecule. 46 | */ 47 | void callSetMolecule(Avogadro::QtGui::Molecule* molecule); 48 | 49 | private slots: 50 | void connectionError(MoleQueue::ConnectionListener::Error, const QString&); 51 | void receivePingResponse(const QJsonObject& response = QJsonObject()); 52 | void messageReceived(const MoleQueue::Message& message); 53 | 54 | private: 55 | MoleQueue::JsonRpc* m_rpc; 56 | MoleQueue::ConnectionListener* m_connectionListener; 57 | MainWindow* m_window; 58 | MoleQueue::JsonRpcClient* m_pingClient; 59 | }; 60 | 61 | } // End Avogadro namespace 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /avogadro/application.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #include "application.h" 7 | #include "mainwindow.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | namespace Avogadro { 19 | 20 | Application::Application(int& argc, char** argv) 21 | : QApplication(argc, argv) 22 | { } 23 | 24 | // Handle open events (e.g., Mac OS X open files) 25 | bool Application::event(QEvent* event) 26 | { 27 | switch (event->type()) { 28 | case QEvent::FileOpen: 29 | return loadFile(static_cast(event)->file()); 30 | default: 31 | return QGuiApplication::event(event); 32 | } 33 | } 34 | 35 | bool Application::loadFile(const QString& fileName) 36 | { 37 | if (fileName.isEmpty()) { 38 | return false; 39 | } 40 | 41 | // check to see if we already have an open window 42 | // (we'll let MainWindow handle the real work) 43 | const MainWindow* window = nullptr; 44 | foreach (const QWidget* item, topLevelWidgets()) { 45 | window = qobject_cast(item); 46 | if (window) 47 | break; 48 | } 49 | 50 | // if not, need to make this spawn a new instance 51 | if (!window) { 52 | qDebug() << " don't have a window! "; 53 | return false; 54 | } 55 | 56 | if (!const_cast(window)->openFile(fileName)) { 57 | qDebug() << " failed to open through MainWindow"; 58 | return false; 59 | } 60 | 61 | return true; 62 | } 63 | 64 | } // end namespace Avogadro 65 | -------------------------------------------------------------------------------- /cmake/InstallLocation.cmake: -------------------------------------------------------------------------------- 1 | # Some default installation locations. These should be global, with any project 2 | # specific locations added to the end. These paths are all relative to the 3 | # install prefix. 4 | # 5 | # These paths attempt to adhere to the FHS, and are similar to those provided 6 | # by autotools and used in many Linux distributions. 7 | # 8 | # Use GNU install directories 9 | include(GNUInstallDirs) 10 | if(NOT INSTALL_RUNTIME_DIR) 11 | set(INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}") 12 | endif() 13 | if(NOT INSTALL_LIBRARY_DIR) 14 | set(INSTALL_LIBRARY_DIR "${CMAKE_INSTALL_LIBDIR}") 15 | endif() 16 | if(NOT INSTALL_ARCHIVE_DIR) 17 | set(INSTALL_ARCHIVE_DIR "${CMAKE_INSTALL_LIBDIR}") 18 | endif() 19 | if(NOT INSTALL_INCLUDE_DIR) 20 | set(INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}") 21 | endif() 22 | if(NOT INSTALL_DATA_DIR) 23 | set(INSTALL_DATA_DIR "${CMAKE_INSTALL_DATAROOTDIR}") 24 | endif() 25 | if(NOT INSTALL_DOC_DIR) 26 | set(INSTALL_DOC_DIR "${CMAKE_INSTALL_DOCDIR}") 27 | endif() 28 | if(NOT INSTALL_MAN_DIR) 29 | set(INSTALL_MAN_DIR "${CMAKE_INSTALL_MANDIR}") 30 | endif() 31 | if(UNIX AND NOT APPLE) 32 | if(NOT INSTALL_XDG_APP_DIR) 33 | set(INSTALL_XDG_APPS_DIR "${INSTALL_DATA_DIR}/applications") 34 | endif() 35 | if(NOT INSTALL_XDG_ICON_DIR) 36 | set(INSTALL_XDG_ICON_DIR "${INSTALL_DATA_DIR}/icons") 37 | endif() 38 | endif() 39 | 40 | # Set up RPATH for the project too. 41 | option(ENABLE_RPATH "Enable rpath support on Linux and Mac" ON) 42 | if(NOT CMAKE_INSTALL_RPATH) 43 | set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBRARY_DIR}") 44 | endif() 45 | if(APPLE AND NOT CMAKE_INSTALL_NAME_DIR) 46 | set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBRARY_DIR}") 47 | endif() 48 | if(UNIX AND ENABLE_RPATH) 49 | set(CMAKE_SKIP_BUILD_RPATH FALSE) 50 | set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 51 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 52 | endif() 53 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/IState.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IState_HPP_INCLUDED 2 | #define IState_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: IState.hpp 16047 2019-04-05 12:51:24Z mbonk $ 17 | // 18 | // 19 | #include 20 | 21 | namespace TDx { 22 | namespace SpaceMouse { 23 | namespace Navigation3D { 24 | /// 25 | /// Interface to access the navigation state. 26 | /// 27 | class IState { 28 | public: 29 | #if !defined(_MSC_VER) || (_MSC_VER > 1700) 30 | virtual ~IState() = default; 31 | #else 32 | virtual ~IState() = 0 { 33 | } 34 | #endif 35 | 36 | /// 37 | /// Is called when the navigation library starts or stops a navigation transaction. 38 | /// 39 | /// The transaction number: >0 begin, ==0 end. 40 | /// 0 = no error, otherwise <0. 41 | virtual long SetTransaction(long transaction) = 0; 42 | 43 | /// 44 | /// Is called when the navigation instance starts or stops a sequence of motion frames. 45 | /// 46 | /// The motion flag: true = start, false = end. 47 | /// 0 = no error, otherwise <0. 48 | /// This can be used to start an animation loop. 49 | virtual long SetMotionFlag(bool motion) = 0; 50 | }; 51 | } // namespace Navigation3D 52 | } // namespace SpaceMouse 53 | } // namespace TDx 54 | #endif // IState_HPP_INCLUDED 55 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/CCommandSet.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CCommandSet_HPP_INCLUDED 2 | #define CCommandSet_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: CCommandSet.hpp 16056 2019-04-10 13:42:31Z mbonk $ 17 | // 18 | // 19 | #include 20 | 21 | #ifndef _MSC_VER 22 | #pragma GCC diagnostic push 23 | #pragma GCC diagnostic ignored "-Wshadow" 24 | #endif 25 | 26 | namespace TDx { 27 | namespace SpaceMouse { 28 | /// 29 | /// The helper class implements the node type. 30 | /// 31 | class CCommandSet : public CCommandTreeNode { 32 | typedef CCommandTreeNode base_type; 33 | 34 | public: 35 | CCommandSet() { 36 | } 37 | 38 | explicit CCommandSet(std::string id, std::string name) 39 | : base_type(std::move(id), std::move(name), SiActionNodeType_t::SI_ACTIONSET_NODE) { 40 | } 41 | #if defined(_MSC_VER) && _MSC_VER < 1900 42 | CCommandSet(CCommandSet &&other) : base_type(std::forward(other)) { 43 | } 44 | CCommandSet &operator=(CCommandSet &&other) { 45 | base_type::operator=(std::forward(other)); 46 | return *this; 47 | } 48 | #else 49 | CCommandSet(CCommandSet &&) = default; 50 | CCommandSet &operator=(CCommandSet &&) = default; 51 | #endif 52 | }; 53 | } // namespace SpaceMouse 54 | } // namespace TDx 55 | 56 | #ifndef _MSC_VER 57 | #pragma GCC diagnostic pop 58 | #endif 59 | 60 | #endif // CCommandSet_HPP_INCLUDED 61 | -------------------------------------------------------------------------------- /cmake/CompilerFlags.cmake: -------------------------------------------------------------------------------- 1 | if(CMAKE_COMPILER_IS_GNUCXX) 2 | 3 | include(CheckCXXCompilerFlag) 4 | 5 | # Addtional warnings for GCC 6 | set(CMAKE_CXX_FLAGS_WARN "-Wnon-virtual-dtor -Wno-long-long -Wcast-align -Wchar-subscripts -Wall -Wpointer-arith -Wformat-security -Woverloaded-virtual -fno-check-new -fno-common") 7 | 8 | # This flag is useful as not returning from a non-void function is an error 9 | # with MSVC, but it is not supported on all GCC compiler versions 10 | check_cxx_compiler_flag("-Werror=return-type" HAVE_GCC_ERROR_RETURN_TYPE) 11 | if(HAVE_GCC_ERROR_RETURN_TYPE) 12 | set(CMAKE_CXX_FLAGS_ERROR "-Werror=return-type") 13 | endif() 14 | set(CMAKE_CXX_FLAGS_WARN "${CMAKE_CXX_FLAGS_WARN} -pedantic -Wshadow -Wextra") 15 | 16 | # If we are compiling on Linux then set some extra linker flags too 17 | if(CMAKE_SYSTEM_NAME MATCHES Linux) 18 | set(CMAKE_SHARED_LINKER_FLAGS 19 | "-Wl,--fatal-warnings -Wl,--no-undefined -lc ${CMAKE_SHARED_LINKER_FLAGS}") 20 | set(CMAKE_MODULE_LINKER_FLAGS 21 | "-Wl,--fatal-warnings -Wl,--no-undefined -lc ${CMAKE_MODULE_LINKER_FLAGS}") 22 | set (CMAKE_EXE_LINKER_FLAGS 23 | "-Wl,--fatal-warnings -Wl,--no-undefined -lc ${CMAKE_EXE_LINKER_FLAGS}") 24 | endif() 25 | 26 | # Set up the debug CXX_FLAGS for extra warnings 27 | set(CMAKE_CXX_FLAGS_RELWITHDEBINFO 28 | "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CMAKE_CXX_FLAGS_WARN}") 29 | set(CMAKE_CXX_FLAGS_DEBUG 30 | "${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_WARN} ${CMAKE_CXX_FLAGS_ERROR}") 31 | set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") 32 | 33 | # Sanitizers 34 | set(CMAKE_CXX_FLAGS_TSAN "-fsanitize=thread -g -O1") 35 | set(CMAKE_CXX_FLAGS_ASAN "-fsanitize=address -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer -g -O1") 36 | set(CMAKE_CXX_FLAGS_LSAN "-fsanitize=leak -fno-omit-frame-pointer -g -O1") 37 | set(CMAKE_CXX_FLAGS_MSAN "-fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2") 38 | set(CMAKE_CXX_FLAGS_UBSAN "-fsanitize=undefined") 39 | endif() 40 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/CCategory.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CCategory_HPP_INCLUDED 2 | #define CCategory_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: CCategory.hpp 16056 2019-04-10 13:42:31Z mbonk $ 17 | // 18 | // 19 | #include 20 | 21 | #ifndef _MSC_VER 22 | #pragma GCC diagnostic push 23 | #pragma GCC diagnostic ignored "-Wshadow" 24 | #endif 25 | 26 | namespace TDx { 27 | /// 28 | /// Contains types used for programming the SpaceMouse. 29 | /// 30 | namespace SpaceMouse { 31 | /// 32 | /// The helper class implements the node type. 33 | /// 34 | class CCategory : public CCommandTreeNode { 35 | typedef CCommandTreeNode base_type; 36 | 37 | public: 38 | CCategory() { 39 | } 40 | 41 | explicit CCategory(std::string id, std::string name) 42 | : base_type(std::move(id), std::move(name), SiActionNodeType_t::SI_CATEGORY_NODE) { 43 | } 44 | 45 | #if defined(_MSC_VER) && _MSC_VER < 1900 46 | CCategory(CCategory &&other) : base_type(std::forward(other)) { 47 | } 48 | CCategory &operator=(CCategory &&other) { 49 | base_type::operator=(std::forward(other)); 50 | return *this; 51 | } 52 | #else 53 | CCategory(CCategory &&) = default; 54 | CCategory &operator=(CCategory &&) = default; 55 | #endif 56 | }; 57 | } // namespace SpaceMouse 58 | } // namespace TDx 59 | 60 | #ifndef _MSC_VER 61 | #pragma GCC diagnostic pop 62 | #endif 63 | 64 | #endif // CCategory_HPP_INCLUDED 65 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/ISpace3D.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ISpace3D_HPP_INCLUDED 2 | #define ISpace3D_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: ISpace3D.hpp 16047 2019-04-05 12:51:24Z mbonk $ 17 | // 18 | // 19 | #include 20 | 21 | namespace TDx { 22 | namespace SpaceMouse { 23 | namespace Navigation3D { 24 | /// 25 | /// The interface to access the client coordinate system. 26 | /// 27 | class ISpace3D { 28 | public: 29 | #if !defined(_MSC_VER) || (_MSC_VER > 1700) 30 | virtual ~ISpace3D() = default; 31 | #else 32 | virtual ~ISpace3D() = 0 { 33 | } 34 | #endif 35 | 36 | /// 37 | /// Gets the coordinate system used by the client. 38 | /// 39 | /// The coordinate system . 40 | /// 0 = no error, otherwise <0. 41 | /// The matrix describes the applications coordinate frame in the navlib coordinate 42 | /// system. i.e. the application to navlib transform. 43 | virtual long GetCoordinateSystem(navlib::matrix_t &matrix) const = 0; 44 | 45 | /// 46 | /// Gets the orientation of the front view. 47 | /// 48 | /// The front view transform . 49 | /// 0 = no error, otherwise <0. 50 | virtual long GetFrontView(navlib::matrix_t &matrix) const = 0; 51 | }; 52 | } // namespace Navigation3D 53 | } // namespace SpaceMouse 54 | } // namespace TDx 55 | #endif // ISpace3D_HPP_INCLUDED 56 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/CCommand.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CCommand_HPP_INCLUDED 2 | #define CCommand_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: CCommand.hpp 16056 2019-04-10 13:42:31Z mbonk $ 17 | // 18 | // 19 | #include 20 | 21 | #ifndef _MSC_VER 22 | #pragma GCC diagnostic push 23 | #pragma GCC diagnostic ignored "-Wshadow" 24 | #endif 25 | 26 | namespace TDx { 27 | namespace SpaceMouse { 28 | /// 29 | /// The class implements the application command node. 30 | /// 31 | class CCommand : public CCommandTreeNode { 32 | typedef CCommandTreeNode base_type; 33 | 34 | public: 35 | CCommand() { 36 | } 37 | 38 | explicit CCommand(std::string id, std::string name, std::string description) 39 | : base_type(std::move(id), std::move(name), std::move(description), 40 | SiActionNodeType_t::SI_ACTION_NODE) { 41 | } 42 | explicit CCommand(std::string id, std::string name) 43 | : base_type(std::move(id), std::move(name), SiActionNodeType_t::SI_ACTION_NODE) { 44 | } 45 | #if defined(_MSC_VER) && _MSC_VER < 1900 46 | CCommand(CCommand &&other) : base_type(std::forward(other)) { 47 | } 48 | CCommand &operator=(CCommand &&other) { 49 | base_type::operator=(std::forward(other)); 50 | return *this; 51 | } 52 | #else 53 | CCommand(CCommand &&) = default; 54 | CCommand &operator=(CCommand &&) = default; 55 | #endif 56 | }; 57 | } // namespace SpaceMouse 58 | } // namespace TDx 59 | 60 | #ifndef _MSC_VER 61 | #pragma GCC diagnostic pop 62 | #endif 63 | 64 | #endif // CCommand_HPP_INCLUDED 65 | -------------------------------------------------------------------------------- /.github/actions/checkout-repositories/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Checkout Avogadro Repositories' 2 | description: 'Checks out all required Avogadro repositories' 3 | inputs: 4 | checkout-submodules: 5 | description: 'Whether to checkout submodules for openchemistry' 6 | required: false 7 | default: 'recursive' 8 | checkout-avogadroapp-path: 9 | description: 'Path for avogadroapp checkout' 10 | required: false 11 | default: 'openchemistry/avogadroapp' 12 | 13 | runs: 14 | using: "composite" 15 | steps: 16 | - name: Checkout openchemistry 17 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 18 | with: 19 | repository: openchemistry/openchemistry 20 | submodules: ${{ inputs.checkout-submodules }} 21 | path: openchemistry 22 | 23 | - name: Checkout avogadroapp 24 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 25 | with: 26 | path: openchemistry/avogadroapp 27 | 28 | - name: Checkout avogadrolibs 29 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 30 | with: 31 | repository: openchemistry/avogadrolibs 32 | path: openchemistry/avogadrolibs 33 | 34 | - name: Checkout i18n 35 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 36 | with: 37 | repository: openchemistry/avogadro-i18n 38 | path: openchemistry/avogadro-i18n 39 | 40 | - name: Checkout avogenerators 41 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 42 | with: 43 | repository: openchemistry/avogenerators 44 | path: openchemistry/avogenerators 45 | 46 | - name: Checkout crystals 47 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 48 | with: 49 | repository: openchemistry/crystals 50 | path: openchemistry/crystals 51 | 52 | - name: Checkout fragments 53 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 54 | with: 55 | repository: openchemistry/fragments 56 | path: openchemistry/fragments 57 | 58 | - name: Checkout molecules 59 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 60 | with: 61 | repository: openchemistry/molecules 62 | path: openchemistry/molecules 63 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/navlib/navlib_defines.h: -------------------------------------------------------------------------------- 1 | #ifndef NAVLIB_DEFINES_H_INCLUDED_ 2 | #define NAVLIB_DEFINES_H_INCLUDED_ 3 | // 4 | // ------------------------------------------------------------------------------------------------- 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------- 11 | // 12 | // 13 | // ************************************************************************************************* 14 | // File History 15 | // 16 | // $Id: navlib_defines.h 19940 2023-01-25 07:17:44Z mbonk $ 17 | // 18 | // 01/23/14 MSB Initial design 19 | // 20 | // 21 | // ************************************************************************************************* 22 | // File Description 23 | // 24 | // This header file defines the macros used in the 3dconnexion interface and header files. 25 | // 26 | // ************************************************************************************************* 27 | // 28 | 29 | // Invalid handle 30 | #define INVALID_NAVLIB_HANDLE 0 31 | 32 | // Navlib facility used to generate error codes 33 | // Note this is identical to FACILITY_ITF on windows 34 | #define FACILITY_NAVLIB 4 35 | 36 | // resources 37 | #define NAVLIB_IDB_ManualPivot 0x6004 38 | #define NAVLIB_IDB_AutoPivot 0x6005 39 | 40 | #if defined(__cplusplus) 41 | #define NAVLIB_BEGIN_ namespace navlib { 42 | #define NAVLIB_END_ } 43 | #define NAVLIB_ ::navlib:: 44 | #define USING_NAVLIB_ using namespace navlib; 45 | #else 46 | #define NAVLIB_BEGIN_ 47 | #define NAVLIB_END_ 48 | #define NAVLIB_ 49 | #define USING_NAVLIB_ 50 | #endif 51 | 52 | #if defined(_MSC_VER) && defined(NAVLIB_EXPORTS) 53 | #define NAVLIB_DLLAPI_ extern "C" __declspec(dllexport) 54 | #elif defined(__cplusplus) 55 | #define NAVLIB_DLLAPI_ extern "C" 56 | #else 57 | #define NAVLIB_DLLAPI_ 58 | #endif 59 | 60 | #ifndef NOEXCEPT 61 | #if defined(_MSC_VER) && (_MSC_VER <= 1800) 62 | #ifdef _NOEXCEPT 63 | #define NOEXCEPT _NOEXCEPT 64 | #else 65 | #define NOEXCEPT 66 | #endif 67 | #else 68 | #define NOEXCEPT noexcept 69 | #endif 70 | #endif 71 | 72 | #endif // NAVLIB_DEFINES_H_INCLUDED_ 73 | -------------------------------------------------------------------------------- /cmake/DetermineVersion.cmake: -------------------------------------------------------------------------------- 1 | # Used to determine the version for OpenChemistry source using "git describe", if git 2 | # is found. On success sets following variables in caller's scope: 3 | # ${var_prefix}_VERSION 4 | # ${var_prefix}_VERSION_MAJOR 5 | # ${var_prefix}_VERSION_MINOR 6 | # ${var_prefix}_VERSION_PATCH 7 | # ${var_prefix}_VERSION_PATCH_EXTRA 8 | # ${var_prefix}_VERSION_IS_RELEASE is patch-extra is empty. 9 | # 10 | # If git is not found, or git describe cannot be run successfully, then these 11 | # variables are left unchanged and status message is printed. 12 | # 13 | # Arguments are: 14 | # source_dir : Source directory 15 | # git_command : git executable 16 | # var_prefix : prefix for variables e.g. "AvogadroApp". 17 | function(determine_version source_dir git_command var_prefix) 18 | set (major) 19 | set (minor) 20 | set (patch) 21 | set (full) 22 | set (patch_extra) 23 | 24 | if (EXISTS ${git_command}) 25 | execute_process( 26 | COMMAND ${git_command} describe 27 | WORKING_DIRECTORY ${source_dir} 28 | RESULT_VARIABLE result 29 | OUTPUT_VARIABLE output 30 | ERROR_QUIET 31 | OUTPUT_STRIP_TRAILING_WHITESPACE 32 | ERROR_STRIP_TRAILING_WHITESPACE) 33 | if (${result} EQUAL 0) 34 | string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)[-]*(.*)" 35 | version_matches ${output}) 36 | if (CMAKE_MATCH_0) 37 | message(STATUS "Determined Source Version : ${CMAKE_MATCH_0}") 38 | set (full ${CMAKE_MATCH_0}) 39 | set (major ${CMAKE_MATCH_1}) 40 | set (minor ${CMAKE_MATCH_2}) 41 | set (patch ${CMAKE_MATCH_3}) 42 | set (patch_extra ${CMAKE_MATCH_4}) 43 | endif() 44 | endif() 45 | endif() 46 | 47 | if (full) 48 | set (${var_prefix}_VERSION ${full} PARENT_SCOPE) 49 | set (${var_prefix}_VERSION_MAJOR ${major} PARENT_SCOPE) 50 | set (${var_prefix}_VERSION_MINOR ${minor} PARENT_SCOPE) 51 | set (${var_prefix}_VERSION_PATCH ${patch} PARENT_SCOPE) 52 | set (${var_prefix}_VERSION_PATCH_EXTRA ${patch_extra} PARENT_SCOPE) 53 | if ("${major}.${minor}.${patch}" EQUAL "${full}") 54 | set (${var_prefix}_VERSION_IS_RELEASE TRUE PARENT_SCOPE) 55 | else () 56 | set (${var_prefix}_VERSION_IS_RELEASE FALSE PARENT_SCOPE) 57 | endif() 58 | else() 59 | message(STATUS 60 | "Could not use git to determine source version, using version ${${var_prefix}_VERSION}" 61 | ) 62 | endif() 63 | endfunction() -------------------------------------------------------------------------------- /scripts/avogadro-remote.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys 3 | import json 4 | import socket 5 | import struct 6 | import tempfile 7 | class Connection: 8 | '''Process a JSON-RPC request''' 9 | def __init__(self, name="avogadro"): 10 | """ 11 | Connect to the local named pipe 12 | 13 | :param name: The name of the named pipe. 14 | """ 15 | # create socket 16 | self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 17 | # connect 18 | try: 19 | self.sock.connect(tempfile.gettempdir() + "/" + name) 20 | # print the connection statement 21 | print("CONNECTION ESTABLISHED SUCCESSFULLY") 22 | except Exception as exception: 23 | print("error while connecting: " + str(exception)) 24 | sys.exit(1) 25 | def __json(self, method, file): 26 | """ 27 | Send a JSON-RPC request to the named pipe. 28 | :param method: The JSON-RPC request method. 29 | Send a message to the named pipe 30 | :param file: file corresponding to method. 31 | 32 | """ 33 | if method == "recv_msg": 34 | size = 1024 35 | packet = self.sock.recv(size) 36 | print("reply:" + str(packet[4: ])) 37 | else: 38 | msg = { 39 | "jsonrpc": "2.0", 40 | "id": 0, 41 | "method": method, 42 | "params": {"fileName": file}, 43 | } 44 | json_msg = json.dumps(msg) 45 | size = len(json_msg) 46 | header = struct.pack(">I", size) 47 | packet = header + json_msg.encode("ascii") 48 | self.sock.send(packet) 49 | def open_file(self, file): 50 | """Opens file""" 51 | # param: file is filename input by the user in string 52 | method = "openFile" 53 | self.__json(method, file) 54 | self.__json("recv_msg", None) 55 | def save_graphic(self, file): 56 | """Save Graphic""" 57 | method = "saveGraphic" 58 | self.__json(method, file) 59 | self.__json("recv_msg", None) 60 | def kill(self): 61 | """To kill the current operation""" 62 | method = "kill" 63 | self.__json(method, None) 64 | self.__json("recv_msg", None) 65 | def close(self): 66 | '''Close the socket to the named pipe''' 67 | self.sock.close() 68 | print("CONNECTION CLOSED SUCCESSFULLY") 69 | -------------------------------------------------------------------------------- /avogadro/backgroundfileformat.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #ifndef AVOGADRO_BACKGROUNDFILEFORMAT_H 7 | #define AVOGADRO_BACKGROUNDFILEFORMAT_H 8 | 9 | #include 10 | #include 11 | 12 | namespace Avogadro { 13 | 14 | namespace Core { 15 | class Molecule; 16 | } 17 | 18 | namespace Io { 19 | class FileFormat; 20 | } 21 | 22 | /** 23 | * @brief The BackgroundFileFormat class provides a thin QObject wrapper around 24 | * an instance of Io::FileFormat. 25 | */ 26 | class BackgroundFileFormat : public QObject 27 | { 28 | Q_OBJECT 29 | public: 30 | /** 31 | * This class takes ownership of @a format and will delete it when destructed. 32 | */ 33 | explicit BackgroundFileFormat(Io::FileFormat* format, QObject* aparent = 0); 34 | ~BackgroundFileFormat(); 35 | 36 | /** 37 | * The molecule instance to read/write. 38 | * @{ 39 | */ 40 | void setMolecule(Core::Molecule* mol) { m_molecule = mol; } 41 | Core::Molecule* molecule() const { return m_molecule; } 42 | /**@}*/ 43 | 44 | /** 45 | * The name of the file to read/write. 46 | * @{ 47 | */ 48 | void setFileName(const QString& filename) { m_fileName = filename; } 49 | QString fileName() const { return m_fileName; } 50 | /**@}*/ 51 | 52 | /** 53 | * The Io::FileFormat to use. 54 | */ 55 | Io::FileFormat* fileFormat() const { return m_format; } 56 | 57 | /** 58 | * @return True if the operation was successful. 59 | */ 60 | bool success() const { return m_success; } 61 | 62 | /** 63 | * @return An error string, set if success() is false. 64 | */ 65 | QString error() const { return m_error; } 66 | 67 | signals: 68 | 69 | /** 70 | * Emitted when a call to read or write is called. 71 | */ 72 | void finished(); 73 | 74 | public slots: 75 | 76 | /** 77 | * Use the fileFormat() to read fileName() into molecule(). 78 | */ 79 | void read(); 80 | 81 | /** 82 | * Use the fileFormat() to write fileName() from molecule(). 83 | */ 84 | void write(); 85 | 86 | private: 87 | Io::FileFormat* m_format; 88 | Core::Molecule* m_molecule; 89 | QString m_fileName; 90 | QString m_error; 91 | bool m_success; 92 | }; 93 | 94 | } // namespace Avogadro 95 | 96 | #endif // AVOGADRO_BACKGROUNDFILEFORMAT_H 97 | -------------------------------------------------------------------------------- /.github/workflows/clang-format-check.yml: -------------------------------------------------------------------------------- 1 | name: clang-format Check 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | formatting-check: 6 | name: Formatting Check 7 | runs-on: ubuntu-latest 8 | if: ${{ github.ref != 'refs/heads/master' }} 9 | steps: 10 | - name: 'Install clang-format' 11 | run: sudo apt-get -qq install clang-format 12 | 13 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 14 | 15 | - name: 'Run clang-format-diff' 16 | run: | 17 | git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/openchemistry/avogadrolibs 18 | git fetch origin master:master 19 | 20 | echo `which clang-format-diff` 21 | export MASTER_SHA=`cat .git/refs/heads/master` 22 | echo MASTER_SHA=${MASTER_SHA} 23 | 24 | git diff `cat .git/refs/heads/master` --name-only 25 | DIFF=`git diff -U0 ${MASTER_SHA} -- '*.h' '*.cpp' | clang-format-diff -p1` 26 | if [ -z "$DIFF" ]; then 27 | printf "clang-format-diff reports no problems" 28 | exit 0 29 | else 30 | git diff -U0 ${MASTER_SHA} -- '*.h' '*.cpp' | clang-format-diff -p1 >${{ runner.workspace }}/clang-format.diff 31 | exit 1 32 | fi 33 | 34 | - name: Upload patch 35 | if: failure() 36 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 37 | with: 38 | path: ${{ runner.workspace }}/clang-format.diff 39 | name: clang-format.diff 40 | 41 | - name: Comment on diff 42 | if: failure() 43 | run: | 44 | export NAME=`curl "https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts" | jq '.artifacts[].name'` 45 | export DL=`curl "https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts" | jq '.artifacts[].archive_download_url'` 46 | export URL="https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts" 47 | echo URL=${URL} 48 | echo NAME=${NAME} 49 | echo DL=${DL} 50 | curl "https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts" 51 | 52 | jq -nc "{\"body\": \"ERROR: clang-format-diff detected formatting issues. See the artifact for a patch or run clang-format on your branch.\"}" | \ 53 | curl -sL -X POST -d @- \ 54 | -H "Content-Type: application/json" \ 55 | -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 56 | "https://api.github.com/repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/comments" 57 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/IEvents.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IEvents_HPP_INCLUDED 2 | #define IEvents_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: IEvents.hpp 16047 2019-04-05 12:51:24Z mbonk $ 17 | // 18 | // 19 | 20 | // navlib 21 | #include 22 | 23 | //stdlib 24 | #include 25 | 26 | namespace TDx { 27 | namespace SpaceMouse { 28 | namespace Navigation3D { 29 | /// 30 | /// The Events interface 31 | /// 32 | class IEvents { 33 | public: 34 | #if !defined(_MSC_VER) || (_MSC_VER > 1700) 35 | virtual ~IEvents() = default; 36 | #else 37 | virtual ~IEvents() = 0 { 38 | } 39 | #endif 40 | 41 | /// 42 | /// Is called when the user invokes an application command from the SpaceMouse. 43 | /// 44 | /// The id of the command to invoke. 45 | /// The result of the function: 0 = no error, otherwise <0. 46 | virtual long SetActiveCommand(std::string commandId) = 0; 47 | 48 | /// 49 | /// Is called when the navigation settings change. 50 | /// 51 | /// The change count. 52 | /// 0 = no error, otherwise <0. 53 | virtual long SetSettingsChanged(long count) = 0; 54 | 55 | /// 56 | /// Is invoked when the user releases a key on the 3D Mouse, which has been programmed to send a 57 | /// virtual key code. 58 | /// 59 | /// The virtual key code of the key pressed. 60 | /// 0 = no error, otherwise <0. 61 | virtual long SetKeyPress(long vkey) = 0; 62 | 63 | /// 64 | /// Is invoked when the user releases a key on the 3D Mouse, which has been programmed to send a 65 | /// virtual key code. 66 | /// 67 | /// The virtual key code of the key released. 68 | /// 0 = no error, otherwise <0. 69 | virtual long SetKeyRelease(long vkey) = 0; 70 | }; 71 | } // namespace Navigation3D 72 | } // namespace SpaceMouse 73 | } // namespace TDx 74 | #endif // IEvents_HPP_INCLUDED 75 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/IPivot.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IPivot_HPP_INCLUDED 2 | #define IPivot_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: IPivot.hpp 16047 2019-04-05 12:51:24Z mbonk $ 17 | // 18 | // 19 | #include 20 | 21 | namespace TDx { 22 | namespace SpaceMouse { 23 | namespace Navigation3D { 24 | /// 25 | /// The interface to access the pivot. 26 | /// 27 | class IPivot { 28 | public: 29 | #if !defined(_MSC_VER) || (_MSC_VER > 1700) 30 | virtual ~IPivot() = default; 31 | #else 32 | virtual ~IPivot() = 0 { 33 | } 34 | #endif 35 | 36 | /// 37 | /// Gets the position of the rotation pivot. 38 | /// 39 | /// The pivot in world coordinates. 40 | /// 0 = no error, otherwise <0. 41 | virtual long GetPivotPosition(navlib::point_t &position) const = 0; 42 | 43 | /// 44 | /// Queries if the user has manually set a pivot point. 45 | /// 46 | /// true if the user has set a pivot otherwise false. 47 | /// 0 = no error, otherwise <0. 48 | virtual long IsUserPivot(navlib::bool_t &userPivot) const = 0; 49 | 50 | /// 51 | /// Sets the position of the rotation pivot. 52 | /// 53 | /// The pivot in world coordinates. 54 | /// 0 = no error, otherwise <0. 55 | virtual long SetPivotPosition(const navlib::point_t& position) = 0; 56 | 57 | /// 58 | /// Queries the visibility of the pivot image. 59 | /// 60 | /// true if the pivot is visible otherwise false. 61 | /// 0 = no error, otherwise <0. 62 | virtual long GetPivotVisible(navlib::bool_t &visible) const = 0; 63 | 64 | /// 65 | /// Sets the visibility of the pivot image. 66 | /// 67 | /// true if the pivot is visible otherwise false. 68 | /// 0 = no error, otherwise <0. 69 | virtual long SetPivotVisible(bool visible) = 0; 70 | }; 71 | } // namespace Navigation3D 72 | } // namespace SpaceMouse 73 | } // namespace TDx 74 | #endif // IPivot_HPP_INCLUDED 75 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.19 FATAL_ERROR) 2 | 3 | # Use the new policy for linking to qtmain 4 | if(POLICY CMP0020) 5 | # cmake_policy(SET CMP0020 NEW) 6 | endif() 7 | 8 | # Set CMP0080 to OLD for now for BundleUtilities, this needs porting to NEW. 9 | if(POLICY CMP0080) 10 | cmake_policy(SET CMP0080 OLD) 11 | endif() 12 | 13 | project(AvogadroApp) 14 | 15 | set(CMAKE_MODULE_PATH ${AvogadroApp_SOURCE_DIR}/cmake) 16 | 17 | # Request C++17 standard, using new CMake variables. 18 | set(CMAKE_CXX_STANDARD 17) 19 | set(CMAKE_CXX_STANDARD_REQUIRED True) 20 | set(CMAKE_CXX_EXTENSIONS False) 21 | # Set symbol visibility defaults for all targets. 22 | set(CMAKE_CXX_VISIBILITY_PRESET "hidden") 23 | set(CMAKE_VISIBILITY_INLINES_HIDDEN True) 24 | 25 | include(BuildType) 26 | include(BuildLocation) 27 | include(CompilerFlags) 28 | include(InstallLocation) 29 | include(DetermineVersion) 30 | 31 | # Set up our version. 32 | set(AvogadroApp_VERSION_MAJOR "1") 33 | set(AvogadroApp_VERSION_MINOR "102") 34 | set(AvogadroApp_VERSION_PATCH "1") 35 | set(AvogadroApp_VERSION 36 | "${AvogadroApp_VERSION_MAJOR}.${AvogadroApp_VERSION_MINOR}.${AvogadroApp_VERSION_PATCH}") 37 | find_package(Git) 38 | determine_version(${AvogadroApp_SOURCE_DIR} ${GIT_EXECUTABLE} "AvogadroApp") 39 | 40 | if(APPLE) 41 | set(MACOSX_BUNDLE_NAME "Avogadro2") 42 | set(prefix "${MACOSX_BUNDLE_NAME}.app/Contents") 43 | set(INSTALL_INCLUDE_DIR "${prefix}/${INSTALL_INCLUDE_DIR}") 44 | set(INSTALL_RUNTIME_DIR "${prefix}/MacOS") 45 | set(INSTALL_LIBRARY_DIR "${prefix}/${INSTALL_LIBRARY_DIR}") 46 | set(INSTALL_ARCHIVE_DIR "${prefix}/${INSTALL_ARCHIVE_DIR}") 47 | set(INSTALL_DATA_DIR "${prefix}/${INSTALL_DATA_DIR}") 48 | set(INSTALL_DOC_DIR "${prefix}/${INSTALL_DOC_DIR}") 49 | set(INSTALL_CMAKE_DIR "${prefix}/Resources") 50 | endif() 51 | 52 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 53 | 54 | set(QT_VERSION "6" CACHE STRING "What major version of Qt") 55 | set(QT_VERSIONS_SUPPORTED 6) 56 | set_property(CACHE QT_VERSION PROPERTY STRINGS 6) 57 | if(NOT QT_VERSION IN_LIST QT_VERSIONS_SUPPORTED) 58 | message(FATAL_ERROR "Qt version must be one of ${QT_VERSIONS_SUPPORTED}") 59 | endif() 60 | option(ENABLE_TESTING "Enable testing and building the tests." OFF) 61 | 62 | if(ENABLE_TESTING) 63 | include(CTest) 64 | enable_testing() 65 | endif() 66 | 67 | option(Avogadro_ENABLE_RPC "Enable RPC server" ON) 68 | 69 | add_subdirectory(avogadro) 70 | 71 | option(BUILD_DOCUMENTATION "Build project documentation" OFF) 72 | 73 | if(BUILD_DOCUMENTATION) 74 | add_subdirectory(docs) 75 | endif() 76 | 77 | install( 78 | FILES 79 | README.md 80 | CONTRIBUTING.md 81 | LICENSE 82 | DESTINATION "${INSTALL_DOC_DIR}/avogadro2") 83 | 84 | include(AvogadroCPack) 85 | 86 | if(ENABLE_TESTING) 87 | include(BuildPackageTest) 88 | BuildPackageTest_Add("AvogadroApp" "${CMAKE_CURRENT_BINARY_DIR}") 89 | add_subdirectory(tests) 90 | endif() 91 | -------------------------------------------------------------------------------- /avogadro/menubuilder.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #ifndef AVOGADRO_MENUBUILDER_H 7 | #define AVOGADRO_MENUBUILDER_H 8 | 9 | #include 10 | #include 11 | 12 | class QAction; 13 | class QMenu; 14 | class QMenuBar; 15 | 16 | /** 17 | * @brief The MenuBuilder class helps to dynamically build up the application 18 | * menus. 19 | * 20 | * This class allows you to build up a list of menu entries, order them by 21 | * priority/section and then add them to a QMenu once all elements have been 22 | * added. 23 | * 24 | * Separators are inserted as needed when priorities cross multiples of 100 25 | * (e.g. The ranges ..., (-100)-(-1), 0-99, 100-199, ... will be grouped 26 | * together). 27 | */ 28 | 29 | namespace Avogadro { 30 | 31 | class MenuBuilder : public QObject 32 | { 33 | Q_OBJECT 34 | 35 | public: 36 | MenuBuilder(); 37 | 38 | /** 39 | * @brief Add a new action to the menu builder object. 40 | * @param path The menu path, where each element specifies a menu level. 41 | * @param action The action that will be added at the path. 42 | * @param priority The priority of the entry, higher will be at the top. 43 | */ 44 | void addAction(const QStringList& path, QAction* action, int priority = -1); 45 | 46 | /** 47 | * @brief Populate the supplied menu bar with the items added to builder. 48 | * Ordering 49 | * is attempted, ensuring File is first, Help is last and ordering by priority 50 | * and then alphanumerically. 51 | * @param menu The menu to be populated. 52 | */ 53 | void buildMenuBar(QMenuBar* menuBar); 54 | 55 | /** 56 | * @brief Populate a menu with the appropriate sub-entries. 57 | */ 58 | void buildMenu(QMenu* menu, const QString& path); 59 | 60 | /** 61 | * @brief Print the contents of the MenuBuilder, intended for debug. 62 | */ 63 | void print(); 64 | 65 | /** 66 | * @brief Get the map of string to action lists. 67 | */ 68 | const QMap>& getMenuActions() const 69 | { 70 | return m_menuActions; 71 | }; 72 | 73 | private: 74 | /** A map of string to action lists. */ 75 | QMap> m_menuActions; 76 | /** Mapping QString from m_menuActions to QStringLists. */ 77 | QMap m_menuPaths; 78 | /** Store entry priority orders mapped to the QActions. */ 79 | QMap m_priorities; 80 | /** Top level menus mapped to text. */ 81 | QMap m_topLevelMenus; 82 | 83 | /** Get the priority of a submenu (takes the highest priority). */ 84 | int priorityGroup(const QString& path); 85 | 86 | /** Should we show icons in the menu? */ 87 | bool m_showIcons = true; 88 | }; 89 | 90 | } // End namespace Avogadro. 91 | 92 | #endif // AVOGADRO_MENUBUILDER_H 93 | -------------------------------------------------------------------------------- /cmake/AppxManifest.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 13 | 14 | 15 | Avogadro2 16 | Avogadro Project 17 | Molecular editor and visualizer 18 | share\icons\avogadro.png 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 37 | 38 | 44 | 45 | 46 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | .cjson 59 | .cml 60 | .xyz 61 | .pdb 62 | .mol 63 | .mol2 64 | .sdf 65 | 66 | Molecule File 67 | share\icons\avogadro2_44.png 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /.github/workflows/codacy.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | # This workflow checks out code, performs a Codacy security scan 7 | # and integrates the results with the 8 | # GitHub Advanced Security code scanning feature. For more information on 9 | # the Codacy security scan action usage and parameters, see 10 | # https://github.com/codacy/codacy-analysis-cli-action. 11 | # For more information on Codacy Analysis CLI in general, see 12 | # https://github.com/codacy/codacy-analysis-cli. 13 | 14 | name: Codacy Security Scan 15 | 16 | on: 17 | workflow_dispatch: 18 | # push: 19 | # branches: [ master ] 20 | # pull_request: 21 | # # The branches below must be a subset of the branches above 22 | # branches: [ master ] 23 | # schedule: 24 | # - cron: '28 10 * * 6' 25 | 26 | permissions: 27 | contents: read 28 | 29 | jobs: 30 | codacy-security-scan: 31 | name: Codacy Security Scan 32 | permissions: 33 | contents: read # for actions/checkout to fetch code 34 | security-events: write # for github/codeql-action/upload-sarif to upload SARIF results 35 | runs-on: ubuntu-latest 36 | concurrency: 37 | group: ${{ github.workflow }}-${{ github.ref }} 38 | cancel-in-progress: true 39 | steps: 40 | # Checkout the repository to the GitHub Actions runner 41 | - name: Checkout code 42 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 43 | 44 | # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis 45 | - name: Run Codacy Analysis CLI 46 | uses: codacy/codacy-analysis-cli-action@562ee3e92b8e92df8b67e0a5ff8aa8e261919c08 # v4.4.7 47 | with: 48 | # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository 49 | # You can also omit the token and run the tools that support default configurations 50 | project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} 51 | verbose: true 52 | output: results.sarif 53 | format: sarif 54 | # Adjust severity of non-security issues 55 | gh-code-scanning-compat: true 56 | # Force 0 exit code to allow SARIF file generation 57 | # This will handover control about PR rejection to the GitHub side 58 | max-allowed-issues: 2147483647 59 | 60 | - name: Filter out MISRA 61 | run: | 62 | pip install globber 63 | python3 scripts/github-actions/filter_sarif.py --input results.sarif --output filtered.sarif --split-lines -- "-**/*.*:cppcheck_misra*" 64 | 65 | # Upload the SARIF file generated in the previous step 66 | - name: Upload SARIF results file 67 | uses: github/codeql-action/upload-sarif@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7 68 | with: 69 | sarif_file: filtered.sarif 70 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/navlib/navlib_error.h: -------------------------------------------------------------------------------- 1 | #ifndef NAVLIB_ERROR_H_INCLUDED_ 2 | #define NAVLIB_ERROR_H_INCLUDED_ 3 | // 4 | // ------------------------------------------------------------------------------------------------- 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------- 11 | // 12 | // 13 | // ************************************************************************************************* 14 | // File History 15 | // 16 | // $Id: navlib_error.h 19940 2023-01-25 07:17:44Z mbonk $ 17 | // 18 | // 01/23/14 MSB Initial design 19 | // 20 | // 21 | // ************************************************************************************************* 22 | // File Description 23 | // 24 | // This header file defines the classes used for error reporting. 25 | // 26 | // ************************************************************************************************* 27 | // 28 | 29 | #include 30 | 31 | #include 32 | 33 | 34 | namespace std { 35 | template <> struct is_error_code_enum : true_type {}; 36 | } // namespace std 37 | 38 | namespace { // Anonymous namespace 39 | /// 40 | /// Navigation library error category. 41 | /// 42 | struct navlib_error_category : public std::error_category { 43 | typedef std::error_category base_type; 44 | 45 | public: 46 | navlib_error_category() NOEXCEPT { 47 | } 48 | 49 | const char *name() const NOEXCEPT override { 50 | return "navlib"; 51 | } 52 | 53 | std::string message(int errorValue) const override { 54 | namespace navlib_errc = navlib::navlib_errc; 55 | switch (static_cast(errorValue)) { 56 | case navlib_errc::property_not_found: 57 | return "Cannot locate the requested navlib property."; 58 | 59 | case navlib_errc::invalid_function: 60 | return "The requested function is not valid."; 61 | 62 | case navlib_errc::insufficient_buffer: 63 | return "Insufficient buffer space."; 64 | 65 | default: 66 | return std::generic_category().message(errorValue); 67 | } 68 | } 69 | }; 70 | 71 | /// 72 | /// Navigation library error category. 73 | /// 74 | static const navlib_error_category navlib_category; 75 | } // namespace 76 | 77 | NAVLIB_BEGIN_ 78 | /// 79 | /// Makes a . 80 | /// 81 | /// The Navigation library error. 82 | /// A with the Navigation library category. 83 | inline std::error_code make_error_code(navlib_errc::navlib_errc_t errc) { 84 | std::error_code ec(static_cast(errc), navlib_category); 85 | return ec; 86 | } 87 | NAVLIB_END_ // namespace navlib 88 | #endif /* NAVLIB_ERROR_H_INCLUDED_ */ 89 | -------------------------------------------------------------------------------- /avogadro/lastinstall/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if((APPLE OR WIN32) AND NOT ${CMAKE_VERSION} VERSION_LESS 2.8.8) 2 | set(pfx "") 3 | if(NOT APPLE) 4 | set(pfx "bin/") 5 | endif() 6 | 7 | set(sfx "") 8 | if(APPLE) 9 | set(sfx ".app") 10 | elseif(WIN32) 11 | set(sfx ".exe") 12 | endif() 13 | 14 | get_target_property(output_name avogadro OUTPUT_NAME) 15 | if(output_name) 16 | set(exe "${pfx}${output_name}${sfx}") 17 | else() 18 | set(exe "${pfx}avogadro${sfx}") 19 | endif() 20 | 21 | set(dirs "") 22 | if(CMAKE_PREFIX_PATH) 23 | foreach(dir ${CMAKE_PREFIX_PATH}) 24 | list(APPEND dirs "${dir}/bin" "${dir}/lib") 25 | endforeach() 26 | endif() 27 | 28 | if(USE_VTK) 29 | # The VTK dlls are not in the CMAKE_PREFIX_PATH when built against 30 | # a "build tree" of VTK: 31 | get_property(loc TARGET VTK::ChartsCore PROPERTY LOCATION_RELEASE) 32 | get_filename_component(vtk_dlls_dir "${loc}" PATH) 33 | set(dirs ${dirs} "${vtk_dlls_dir}") 34 | endif() 35 | 36 | # grab OpenSSL for Windows 37 | if(WIN32) 38 | find_package(OpenSSL REQUIRED) 39 | if (DEFINED OPENSSL_FOUND) 40 | set(OPENSSL_ROOT_DIR "${OPENSSL_INCLUDE_DIR}/.." CACHE PATH "OpenSSL root directory") 41 | message(STATUS "Using OpenSSL from ${OPENSSL_ROOT_DIR}") 42 | file(GLOB OPENSSL_DLL ${OPENSSL_ROOT_DIR}/bin/*.dll) 43 | install(FILES ${OPENSSL_DLL} DESTINATION ${INSTALL_RUNTIME_DIR}) 44 | endif() 45 | endif() 46 | 47 | set(plugins "") 48 | foreach(plugin ${AvogadroLibs_PLUGINS}) 49 | get_property(location TARGET ${plugin} PROPERTY LOCATION) 50 | list(APPEND plugins ${location}) 51 | endforeach() 52 | # make sure to include the core image formats 53 | # likely only be required on Mac / Windows since Qt package on Unix provides 54 | if(APPLE OR WIN32) 55 | # JPG BMP, WebP, GIF plus default of PNG, etc. 56 | # .. for whatever reason, they don't have a Qt::QJpegPlugin 57 | # .. only the versioned Qt6::QJpegPlugin, etc. 58 | if(QT_VERSION EQUAL 6) 59 | foreach(qt_plugin Qt6::QJpegPlugin Qt6::QGifPlugin) 60 | get_property(location TARGET ${qt_plugin} PROPERTY LOCATION_RELEASE) 61 | list(APPEND plugins ${location}) 62 | endforeach() 63 | endif() 64 | endif() 65 | 66 | # Find and fixup the Open Babel plugins (if installed) 67 | find_program(OBABEL_EXE obabel) 68 | if(INSTALL_BUNDLE_FILES AND OBABEL_EXE AND APPLE) 69 | get_filename_component(BABEL_DIR "${OBABEL_EXE}" PATH) 70 | file(GLOB BABEL_PLUGINS 71 | RELATIVE ${BABEL_DIR}/../lib/openbabel/ 72 | ${BABEL_DIR}/../lib/openbabel/*.so) 73 | foreach(plugin ${BABEL_PLUGINS}) 74 | list(APPEND ob_plugins ${INSTALL_LIBRARY_DIR}/openbabel/${plugin}) 75 | endforeach() 76 | endif() 77 | set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) 78 | include(InstallRequiredSystemLibraries) 79 | 80 | if (INSTALL_BUNDLE_FILES) 81 | # Fixup the bundle 82 | install(CODE " 83 | include(BundleUtilities) 84 | get_property(bundle TARGET avogadro PROPERTY LOCATION_RELEASE) 85 | fixup_bundle(\"${bundle}/..\" \"${plugins}\" \"${dirs}\") 86 | " COMPONENT Runtime) 87 | endif() 88 | endif() 89 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/IHit.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IHit_HPP_INCLUDED 2 | #define IHit_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: IHit.hpp 16047 2019-04-05 12:51:24Z mbonk $ 17 | // 18 | // 19 | #include 20 | 21 | namespace TDx { 22 | namespace SpaceMouse { 23 | namespace Navigation3D { 24 | /// 25 | /// The hit-testing interface. 26 | /// 27 | class IHit { 28 | public: 29 | #if !defined(_MSC_VER) || (_MSC_VER > 1700) 30 | virtual ~IHit() = default; 31 | #else 32 | virtual ~IHit() = 0 { 33 | } 34 | #endif 35 | 36 | /// 37 | /// Is called when the navigation library queries the result of the hit-testing. 38 | /// 39 | /// The hit in world coordinates. 40 | /// 0 =no error, otherwise <0 . 41 | virtual long GetHitLookAt(navlib::point_t &position) const = 0; 42 | 43 | /// 44 | /// Is called when the navigation library sets the aperture of the hit-testing ray/cone. 45 | /// 46 | /// The aperture of the ray/cone on the near plane. 47 | /// 0 =no error, otherwise <0 . 48 | virtual long SetHitAperture(double aperture) = 0; 49 | 50 | /// 51 | /// Is called when the navigation library sets the direction of the hit-testing ray/cone. 52 | /// 53 | /// The direction of the ray/cone. 54 | /// 0 =no error, otherwise <0 . 55 | virtual long SetHitDirection(const navlib::vector_t& direction) = 0; 56 | 57 | /// 58 | /// Is called when the navigation library sets the source of the hit-testing ray/cone. 59 | /// 60 | /// The source of the hit cone. 61 | /// 0 =no error, otherwise <0 . 62 | virtual long SetHitLookFrom(const navlib::point_t& eye) = 0; 63 | 64 | /// 65 | /// Is called when the navigation library sets the selection filter for hit-testing. 66 | /// 67 | /// true = ignore non-selected items. 68 | /// 0 =no error, otherwise <0 . 69 | virtual long SetHitSelectionOnly(bool onlySelection) = 0; 70 | }; 71 | } // namespace Navigation3D 72 | } // namespace SpaceMouse 73 | } // namespace TDx 74 | #endif // IHit_HPP_INCLUDED 75 | -------------------------------------------------------------------------------- /avogadro/aboutdialog.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #include "aboutdialog.h" 7 | #include "avogadroappconfig.h" 8 | #include "ui_aboutdialog.h" 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace Avogadro { 15 | 16 | AboutDialog::AboutDialog(QWidget* parent_) 17 | : QDialog(parent_) 18 | , m_ui(new Ui::AboutDialog) 19 | { 20 | m_ui->setupUi(this); 21 | 22 | // description text 23 | // mostly to get picked up for the installer 24 | // and Linux .desktop file 25 | QString description(tr("Molecular editor and visualizer")); 26 | 27 | QString html("

" 28 | "%2" 29 | "

"); 30 | 31 | // Add the labels 32 | m_ui->versionLabel->setText(html.arg("20").arg(tr("Version:"))); 33 | m_ui->libsLabel->setText(html.arg("10").arg(tr("Avogadro Library Version:"))); 34 | m_ui->qtVersionLabel->setText(html.arg("10").arg(tr("Qt Version:"))); 35 | m_ui->sslVersionLabel->setText(html.arg("10").arg(tr("SSL Version:"))); 36 | 37 | // Add the version numbers 38 | m_ui->version->setText(html.arg("20").arg(AvogadroApp_VERSION)); 39 | m_ui->libsVersion->setText(html.arg("10").arg(version())); 40 | m_ui->qtVersion->setText(html.arg("10").arg(qVersion())); 41 | m_ui->sslVersion->setText( 42 | html.arg("10").arg(QSslSocket::sslLibraryVersionString())); 43 | 44 | // check for light or dark mode 45 | const QPalette defaultPalette; 46 | // is the text lighter than the window color? 47 | bool darkMode = (defaultPalette.color(QPalette::WindowText).lightness() > 48 | defaultPalette.color(QPalette::Window).lightness()); 49 | QString theme = darkMode ? "dark" : "light"; 50 | loadImage(theme); 51 | } 52 | 53 | void AboutDialog::loadImage(const QString& theme) 54 | { 55 | QString pixels = window()->devicePixelRatio() == 2 ? "@2x" : ""; 56 | 57 | QString path(":/icons/Avogadro2-about-" + theme + pixels + ".png"); 58 | QPixmap pix(path); 59 | 60 | if (window()->devicePixelRatio() == 2) 61 | pix.setDevicePixelRatio(2); 62 | 63 | m_ui->Image->setPixmap(QPixmap(path)); 64 | } 65 | 66 | void AboutDialog::changeEvent(QEvent* e) 67 | { 68 | // it's supposed to be through a theme change 69 | // but on macOS, it seems to be triggered 70 | // by a palette change, so we handle both 71 | if (e->type() == QEvent::ApplicationPaletteChange || 72 | e->type() == QEvent::PaletteChange || e->type() == QEvent::ThemeChange) { 73 | e->accept(); 74 | 75 | const QPalette defaultPalette; 76 | // is the text lighter than the window color? 77 | bool darkMode = (defaultPalette.color(QPalette::WindowText).lightness() > 78 | defaultPalette.color(QPalette::Window).lightness()); 79 | 80 | QString theme = darkMode ? "dark" : "light"; 81 | loadImage(theme); 82 | } 83 | } 84 | 85 | AboutDialog::~AboutDialog() 86 | { 87 | delete m_ui; 88 | } 89 | 90 | } /* namespace Avogadro */ 91 | -------------------------------------------------------------------------------- /scripts/extract-messages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | BASEDIR="avogadro/" # root of translatable sources 3 | PROJECT="avogadroapp" # project name 4 | PACKAGE="Avogadro" # user-readable package name 5 | # user-readable version 6 | MAJORVERSION=`grep 'set(AvogadroApp_VERSION_MAJOR' CMakeLists.txt | cut -f 2 -d '"'` 7 | MINORVERSION=`grep 'set(AvogadroApp_VERSION_MINOR' CMakeLists.txt | cut -f 2 -d '"'` 8 | PATCHVERSION=`grep 'set(AvogadroApp_VERSION_PATCH' CMakeLists.txt | cut -f 2 -d '"'` 9 | VERSION="${MAJORVERSION}.${MINORVERSION}.${PATCHVERSION}" 10 | BUGADDR="avogadro-devel@lists.sourceforge.net" # MSGID-Bugs 11 | WDIR=`pwd` # working dir 12 | I18NDIR="i18n/" # i18n dir 13 | 14 | echo "Preparing rc files" 15 | cd ${BASEDIR} 16 | # we use simple sorting to make sure the lines do not jump around too much from system to system 17 | find . -name '*.rc' -o -name '*.ui' -o -name '*.kcfg' | grep -v 'test' | grep -v 'example' | sort > ${WDIR}/rcfiles.list 18 | cat ${WDIR}/rcfiles.list | xargs ${WDIR}/scripts/extractrc.sh > ${WDIR}/rc.cpp 19 | # additional string for KAboutData 20 | echo 'i18nc("NAME OF TRANSLATORS","Your names");' >> ${WDIR}/rc.cpp 21 | echo 'i18nc("EMAIL OF TRANSLATORS","Your emails");' >> ${WDIR}/rc.cpp 22 | cd ${WDIR} 23 | echo "Done preparing rc files" 24 | 25 | 26 | echo "Extracting messages" 27 | cd ${BASEDIR} 28 | # see above on sorting 29 | find . -name '*.cpp' -o -name '*.h' -o -name '*.c' | grep -v 'test' | grep -v "example" | sort > ${WDIR}/infiles.list 30 | echo "rc.cpp" >> ${WDIR}/infiles.list 31 | cd ${WDIR} 32 | xgettext --from-code=UTF-8 -C -T --qt -kde -ci18n -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -ktr2i18n:1 \ 33 | -kI18N_NOOP:1 -kI18N_NOOP2:1c,2 -kaliasLocale -kki18n:1 -kki18nc:1c,2 -kki18np:1,2 -kki18ncp:1c,2,3 \ 34 | -ktrUtf8:1,2c -ktr:1,1t -ktr:1,2c,2t -ktr:1,1,2c,3t -ktrUtf8:1 \ 35 | --package-name=${PACKAGE} --package-version=${VERSION} \ 36 | --msgid-bugs-address="${BUGADDR}" --foreign-user --copyright-holder="The Avogadro Project" \ 37 | --files-from=infiles.list -D ${BASEDIR} -D ${WDIR} -o ${PROJECT}.pot || { echo "error while calling xgettext. aborting."; exit 1; } 38 | echo "Done extracting messages" 39 | 40 | # Replace some boilerplate strings 41 | sed -e "s/SOME DESCRIPTIVE TITLE/Translations for the Avogadro molecular builder/" <${PROJECT}.pot >${PROJECT}.new 42 | mv ${PROJECT}.new ${PROJECT}.pot 43 | year=`date "+%Y"` 44 | sed -e "s/Copyright (C) YEAR/Copyright (C) 2006-$year/" <${PROJECT}.pot >${PROJECT}.new 45 | mv ${PROJECT}.new ${PROJECT}.pot 46 | sed -e 's/as the PACKAGE package/as the Avogadro package/' <${PROJECT}.pot >${PROJECT}.new 47 | mv ${PROJECT}.new ${PROJECT}.pot 48 | sed -e 's/^#. i18n: .\//#: /' <${PROJECT}.pot >${PROJECT}.new 49 | mv ${PROJECT}.new ${PROJECT}.pot 50 | sed -e '/^#: rc.cpp/ d' <${PROJECT}.pot >${PROJECT}.new 51 | mv ${PROJECT}.new ${PROJECT}.pot 52 | sed -e 's/rc\.cpp//' <${PROJECT}.pot >${PROJECT}.new 53 | mv ${PROJECT}.new ${PROJECT}.pot 54 | 55 | mv ${PROJECT}.pot ${I18NDIR} 56 | 57 | cd ${I18NDIR} 58 | #echo "Merging translations" 59 | #catalogs=`find . -name '*.po'` 60 | #for cat in $catalogs; do 61 | # # remove any \r escapes 62 | # sed -e 's/\\r//' <$cat >$cat.new 63 | # mv $cat.new $cat 64 | # echo $cat 65 | # msgmerge -o $cat.new $cat ${PROJECT}.pot 66 | # mv $cat.new $cat 67 | # msgmerge -U $cat ${PROJECT}.pot 68 | #done 69 | #echo "Done merging translations" 70 | 71 | 72 | echo "Cleaning up" 73 | cd ${WDIR} 74 | rm rcfiles.list 75 | rm infiles.list 76 | rm rc.cpp 77 | echo "Done" 78 | -------------------------------------------------------------------------------- /.github/workflows/clang-tidy.yml: -------------------------------------------------------------------------------- 1 | name: Clang-Tidy Static Analysis 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | env: 7 | FEATURES: -DUSE_VTK=ON -DBUILD_GPL_PLUGINS=ON -DWITH_COORDGEN=OFF -DUSE_YAEHMOP=ON 8 | BUILD_TYPE: RelWithDebInfo 9 | QT_VERSION: 6.8.3 10 | 11 | jobs: 12 | build: 13 | name: ${{ matrix.config.name }} 14 | runs-on: ${{ matrix.config.os }} 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | config: 19 | - { 20 | name: "Ubuntu Analysis", 21 | os: ubuntu-latest, 22 | cc: "clang", cxx: "clang++", 23 | cmake_flags: "-G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DUSE_SYSTEM_LIBXML2=ON -USE_SYSTEM_ZLIB=ON", 24 | cpack: "", 25 | } 26 | 27 | steps: 28 | 29 | - name: Install Dependencies (Linux) 30 | if: runner.os == 'Linux' 31 | run: | 32 | sudo apt-get -qq update 33 | sudo apt-get -qq install ninja-build bear libeigen3-dev libboost-all-dev libglew-dev libxml2-dev 34 | sudo apt-get -qq install clang-tidy 35 | 36 | - name: Install Qt 37 | uses: jurplel/install-qt-action@b7840a6733f49e2a39c4355260d2375063d39b61 # v3 38 | with: 39 | cache: true 40 | version: ${{ env.QT_VERSION }} 41 | 42 | - name: Checkout Repositories 43 | uses: ./.github/actions/checkout-repositories 44 | 45 | - name: Grab cache files 46 | uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 47 | if: runner.os != 'Windows' 48 | with: 49 | path: | 50 | ${{ runner.workspace }}/build/thirdparty 51 | ${{ runner.workspace }}/build/Downloads 52 | key: ${{ matrix.config.name }}-thirdparty 53 | 54 | - name: Configure 55 | run: | 56 | if [ ! -d "${{ runner.workspace }}/build" ]; then mkdir "${{ runner.workspace }}/build"; fi 57 | cd "${{ runner.workspace }}/build" 58 | CC=${{matrix.config.cc}} CXX=${{matrix.config.cxx}} cmake $GITHUB_WORKSPACE ${{env.FEATURES}} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} ${{matrix.config.cmake_flags}} 59 | shell: bash 60 | 61 | - name: Build 62 | run: | 63 | CC=${{matrix.config.cc}} CXX=${{matrix.config.cxx}} ninja 64 | # only re-compile avogadrolibs 65 | (cd avogadrolibs; ninja clean) 66 | bear -- ninja 67 | shell: bash 68 | working-directory: ${{ runner.workspace }}/build 69 | 70 | - name: Create results directory 71 | run: | 72 | mkdir ${{ runner.workspace }}/clang-tidy-result 73 | 74 | - name: Analyze 75 | run: | 76 | # generate the fixes and we'll make a diff 77 | run-clang-tidy -p ../build -fix 78 | cd avogadrolibs 79 | pwd 80 | echo "Generating diff" 81 | git diff >${{ runner.workspace }}/clang-tidy-result/tidy.patch 82 | working-directory: ${{ runner.workspace }}/avogadrolibs 83 | 84 | - name: Save PR metadata 85 | run: | 86 | echo ${{ github.event.number }} > ${{ runner.workspace }}/clang-tidy-result/pr-id.txt 87 | echo ${{ github.event.pull_request.head.repo.full_name }} > ${{ runner.workspace }}/clang-tidy-result/pr-head-repo.txt 88 | echo ${{ github.event.pull_request.head.ref }} > ${{ runner.workspace }}/clang-tidy-result/pr-head-ref.txt 89 | 90 | - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 91 | with: 92 | name: clang-tidy-result 93 | path: ${{ runner.workspace }}/clang-tidy-result/ 94 | 95 | - name: Setup tmate session 96 | if: ${{ failure() }} 97 | uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23 98 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/navlib/navlib_operators.h: -------------------------------------------------------------------------------- 1 | #ifndef NAVLIB_OPERATORS_H_INCLUDED_ 2 | #define NAVLIB_OPERATORS_H_INCLUDED_ 3 | // 4 | // ------------------------------------------------------------------------------------------------- 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------- 11 | // 12 | // 13 | // ************************************************************************************************* 14 | // File History 15 | // 16 | // $Id: navlib_operators.h 19944 2023-01-25 14:56:02Z mbonk $ 17 | // 18 | // 01/23/14 MSB Initial design 19 | // 20 | // 21 | // ************************************************************************************************* 22 | // File Description 23 | // 24 | // This header file defines the operator overloads for variable types used in the 3dconnexion 25 | // interface. 26 | // 27 | // ************************************************************************************************* 28 | // 29 | #include 30 | 31 | // stdlib 32 | #include 33 | #include 34 | 35 | NAVLIB_BEGIN_ 36 | 37 | /// 38 | /// Compare floating point numbers. 39 | /// 40 | /// First value to compare. 41 | /// Second value to compare. 42 | /// Maximum relative error. 43 | /// 44 | /// 45 | /// From https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition. 46 | /// Copyright Bruce Dawson. 47 | /// 48 | template bool equals(T a, T b, T epsilon = static_cast(FLT_EPSILON)) { 49 | T diff = fabs(a - b); 50 | if (diff < epsilon) { 51 | return true; 52 | } 53 | a = fabs(a); 54 | b = fabs(b); 55 | T largest = (a > b) ? a : b; 56 | if (diff <= largest * epsilon) { 57 | return true; 58 | } 59 | return false; 60 | } 61 | 62 | inline bool operator==(const vector_t &lhs, const vector_t &rhs) { 63 | return (equals(lhs.x, rhs.x) && equals(lhs.y, rhs.y) && equals(lhs.z, rhs.z)); 64 | } 65 | 66 | inline bool operator!=(const vector_t &lhs, const vector_t &rhs) { 67 | return !(lhs == rhs); 68 | } 69 | 70 | inline bool operator==(const point_t &lhs, const point_t &rhs) { 71 | return (equals(lhs.x, rhs.x) && equals(lhs.y, rhs.y) && equals(lhs.z, rhs.z)); 72 | } 73 | 74 | inline bool operator!=(const point_t &lhs, const point_t &rhs) { 75 | return !(lhs == rhs); 76 | } 77 | 78 | inline bool operator==(const box_t &lhs, const box_t &rhs) { 79 | return lhs.min == rhs.min && lhs.max == rhs.max; 80 | } 81 | 82 | inline bool operator!=(const box_t &lhs, const box_t &rhs) { 83 | return !(lhs == rhs); 84 | } 85 | 86 | inline bool operator==(const matrix_t &lhs, const matrix_t &rhs) { 87 | for (size_t i = 0; i < sizeof(rhs) / sizeof(rhs[0]); ++i) { 88 | if (!equals(lhs[i], rhs[i])) { 89 | return false; 90 | } 91 | } 92 | return true; 93 | } 94 | 95 | inline bool operator!=(const matrix_t &lhs, const matrix_t &rhs) { 96 | return !(lhs == rhs); 97 | } 98 | 99 | inline nlOptions_t operator|(nlOptions_t lhs, nlOptions_t rhs) { 100 | return static_cast(static_cast(lhs) | static_cast(rhs)); 101 | } 102 | 103 | NAVLIB_END_ 104 | 105 | #endif /* NAVLIB_OPERATORS_H_INCLUDED_ */ -------------------------------------------------------------------------------- /.github/workflows/build_flatpak.yml: -------------------------------------------------------------------------------- 1 | name: Build Flatpak 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | jobs: 6 | flatpak: 7 | name: "Flatpak" 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - name: Install dependencies 12 | run: sudo apt update -qq && sudo apt install -y -qq flatpak 13 | 14 | - name: Configure flatpak 15 | run: flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo 16 | 17 | - name: Install flatpak-builder 18 | run: flatpak --user install --or-update --noninteractive flathub org.flatpak.Builder 19 | 20 | - name: Configure git 21 | run: git config --global protocol.file.allow always 22 | # Have to do this because for a while git's handling of submodules was broken 23 | # See https://github.com/flatpak/flatpak-builder/issues/495 24 | 25 | - name: Checkout openchemistry 26 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 27 | with: 28 | repository: openchemistry/openchemistry 29 | submodules: false 30 | path: openchemistry 31 | 32 | - name: Checkout avogadroapp 33 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 34 | with: 35 | path: openchemistry/avogadroapp 36 | 37 | - name: Checkout avogadrolibs 38 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 39 | with: 40 | repository: openchemistry/avogadrolibs 41 | path: openchemistry/avogadrolibs 42 | 43 | - name: Checkout i18n 44 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 45 | with: 46 | repository: openchemistry/avogadro-i18n 47 | path: openchemistry/avogadro-i18n 48 | 49 | - name: Checkout avogenerators 50 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 51 | with: 52 | repository: openchemistry/avogenerators 53 | path: openchemistry/avogenerators 54 | 55 | - name: Checkout crystals 56 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 57 | with: 58 | repository: openchemistry/crystals 59 | path: openchemistry/crystals 60 | 61 | - name: Checkout fragments 62 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 63 | with: 64 | repository: openchemistry/fragments 65 | path: openchemistry/fragments 66 | 67 | - name: Checkout molecules 68 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 69 | with: 70 | repository: openchemistry/molecules 71 | path: openchemistry/molecules 72 | 73 | - name: Checkout Flathub shared-modules 74 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 75 | with: 76 | repository: flathub/shared-modules 77 | path: shared-modules 78 | 79 | - name: Set up tmate session 80 | if: failure() 81 | uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23 82 | timeout-minutes: 60 83 | 84 | - name: Move manifest 85 | run: mv openchemistry/avogadroapp/flatpak/org.openchemistry.Avogadro2.yaml ./ 86 | 87 | - name: Build with flatpak-builder 88 | run: dbus-run-session flatpak run org.flatpak.Builder --force-clean --user --install-deps-from=flathub --arch=x86_64 --default-branch=test --repo=repo builddir org.openchemistry.Avogadro2.yaml 89 | 90 | - name: Create bundle 91 | run: flatpak build-bundle repo Avogadro2.flatpak org.openchemistry.Avogadro2 test 92 | 93 | - name: Upload bundle 94 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 95 | with: 96 | path: Avogadro2.flatpak 97 | 98 | - name: Cleanup 99 | if: ${{ always() }} # To ensure this step runs even when earlier steps fail 100 | shell: bash 101 | run: | 102 | ls -la ./ 103 | rm -rf ./* || true 104 | rm -rf ./.??* || true 105 | ls -la ./ 106 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/INavlib.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INavlib_HPP_INCLUDED 2 | #define INavlib_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: INavlib.hpp 16047 2019-04-05 12:51:24Z mbonk $ 17 | // 18 | // 19 | #include 20 | 21 | // stdlib 22 | #include 23 | 24 | namespace TDx { 25 | namespace SpaceMouse { 26 | namespace Navigation3D { 27 | /// 28 | /// The interface to access the navigation library properties. 29 | /// 30 | class INavlibProperty { 31 | public: 32 | #if !defined(_MSC_VER) || (_MSC_VER > 1700) 33 | virtual ~INavlibProperty() = default; 34 | #else 35 | virtual ~INavlibProperty() = 0 { 36 | } 37 | #endif 38 | 39 | /// 40 | /// Writes the value of a property to the navlib. 41 | /// 42 | /// The name of the navlib property to 43 | /// write. 44 | /// The to write. 45 | /// 0 =no error, otherwise a value from . 46 | /// No connection to the navlib / 3D Mouse. 47 | virtual long Write(const std::string &propertyName, const navlib::value &value) = 0; 48 | 49 | /// 50 | /// Reads the value of a navlib property. 51 | /// 52 | /// The name of the navlib property to 53 | /// read. 54 | /// The to read. 55 | /// 0 =no error, otherwise a value from . 56 | /// No connection to the navlib / 3D Mouse. 57 | virtual long Read(const std::string &propertyName, navlib::value &value) const = 0; 58 | 59 | /// 60 | /// Reads the value of a navlib string property. 61 | /// 62 | /// The name of the navlib property to 63 | /// read. 64 | /// The value of the property. 65 | /// 0 =no error, otherwise a value from . 66 | /// No connection to the navlib. 67 | virtual long Read(const std::string &propertyName, std::string &string) const = 0; 68 | }; 69 | 70 | /// 71 | /// The interface to access the navigation library. 72 | /// 73 | class INavlib : public INavlibProperty { 74 | public: 75 | /// 76 | /// Close the connection to the 3D navigation library. 77 | /// 78 | virtual void Close() = 0; 79 | 80 | /// 81 | /// Opens a connection to the 3D navigation library. 82 | /// 83 | virtual void Open() = 0; 84 | 85 | /// 86 | /// Opens a connection to the 3D navigation library 87 | /// 88 | /// The name of the 3Dconnexion profile to use. 89 | /// The connection to the library is already open. 90 | /// Cannot create a connection to the library. 91 | /// The name of the profile is empty. 92 | virtual void Open(std::string profileName) = 0; 93 | }; 94 | } // namespace Navigation3D 95 | } // namespace SpaceMouse 96 | } // namespace TDx 97 | #endif // INavlib_HPP_INCLUDED 98 | 99 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/CCookieCollection.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CCookieCollection_HPP_INCLUDED 2 | #define CCookieCollection_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: CCookieCollection.hpp 16047 2019-04-05 12:51:24Z mbonk $ 17 | // 18 | // 19 | #include 20 | // stdlib 21 | #include 22 | #include 23 | #include 24 | 25 | #if (!defined(_MSC_VER) || (_MSC_VER > 1600)) 26 | #include 27 | #include 28 | #else 29 | #pragma warning(disable : 4482) // non-standard 30 | #include 31 | #include 32 | #include 33 | namespace std { 34 | using boost::lock_guard; 35 | using boost::mutex; 36 | using boost::unique_lock; 37 | namespace chromo = boost : chrono; 38 | using boost::milli; 39 | } // namespace std 40 | #endif 41 | 42 | namespace TDx { 43 | namespace SpaceMouse { 44 | /// 45 | /// The class maps a cookie to a shared_ptr. 46 | /// 47 | template 48 | class CCookieCollection 49 | : protected std::map> 50 | { 51 | typedef std::map> map_t; 52 | 53 | public: 54 | typedef typename map_t::size_type size_type; 55 | 56 | /// 57 | /// Gets the corresponding to the passed in 58 | /// cookie. 59 | /// 60 | /// The to search 61 | /// for. The . 62 | /// If the cookie does not 63 | /// exist. 64 | std::shared_ptr at(const navlib::param_t& cookie) 65 | { 66 | std::lock_guard guard(m_mutex); 67 | typename map_t::iterator iter = map_t::find(cookie); 68 | if (iter != map_t::end()) { 69 | return iter->second; 70 | } 71 | 72 | throw std::out_of_range("Cookie does not exist in the Collection"); 73 | } 74 | 75 | /// 76 | /// Removes the elements that match the cookie. 77 | /// 78 | /// The cookie entry to remove. 79 | /// The number of elements that have been removed. 80 | size_type erase(const navlib::param_t& cookie) 81 | { 82 | std::lock_guard guard(m_mutex); 83 | return map_t::erase(cookie); 84 | } 85 | 86 | /// 87 | /// Inserts a and returns a cookie that is 88 | /// needed to retrieve it later. 89 | /// 90 | /// The to insert. 91 | /// A cookie that is needed to find the shared pointer. 92 | navlib::param_t insert(std::shared_ptr sp) 93 | { 94 | navlib::param_t param = 0; 95 | if (sp) { 96 | std::lock_guard guard(m_mutex); 97 | do { 98 | using namespace std::chrono; 99 | param = static_cast( 100 | duration_cast( 101 | high_resolution_clock::now().time_since_epoch()) 102 | .count()); 103 | } while (map_t::find(param) != map_t::end()); 104 | (*this)[param] = std::move(sp); 105 | } 106 | return param; 107 | } 108 | 109 | protected: 110 | /// 111 | /// When changing the contents of the collection always use the mutex as a 112 | /// guard 113 | /// 114 | std::mutex m_mutex; 115 | }; 116 | } // namespace SpaceMouse 117 | } // namespace TDx 118 | #endif // CCookieCollection_HPP_INCLUDED 119 | -------------------------------------------------------------------------------- /avogadro/backgroundfileformat.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #include "backgroundfileformat.h" 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace Avogadro { 15 | 16 | BackgroundFileFormat::BackgroundFileFormat(Io::FileFormat* format, 17 | QObject* aparent) 18 | : QObject(aparent) 19 | , m_format(format) 20 | , m_molecule(nullptr) 21 | , m_success(false) 22 | { 23 | } 24 | 25 | BackgroundFileFormat::~BackgroundFileFormat() 26 | { 27 | delete m_format; 28 | } 29 | 30 | void BackgroundFileFormat::read() 31 | { 32 | m_success = false; 33 | m_error.clear(); 34 | 35 | if (!m_molecule) 36 | m_error = tr("No molecule set in BackgroundFileFormat!"); 37 | 38 | if (!m_format) 39 | m_error = tr("No file format set in BackgroundFileFormat!"); 40 | 41 | if (m_fileName.isEmpty()) 42 | m_error = tr("No file name set in BackgroundFileFormat!"); 43 | 44 | if (m_error.isEmpty()) { 45 | // sometimes we hit UTF-16 files, so we need to convert them to UTF-8 46 | // first check whether the file is UTF-16 47 | QFile file(m_fileName); 48 | QTextStream in(&file); 49 | QString text; 50 | bool isUTF16 = false; 51 | if (file.open(QIODevice::ReadOnly)) { 52 | QByteArray data = file.read(2); 53 | // look for a byte-order mark 54 | if ((data.size() == 2 && data[0] == '\xff' && data[1] == '\xfe') || 55 | (data.size() == 2 && data[0] == '\xfe' && data[1] == '\xff')) { 56 | // UTF-16, read the file and let QString handle decoding 57 | isUTF16 = true; 58 | file.close(); 59 | file.open(QIODevice::ReadOnly | QIODevice::Text); 60 | #if QT_VERSION < 0x060000 61 | in.setCodec("UTF-16"); 62 | #endif 63 | text = in.readAll(); 64 | file.close(); 65 | } 66 | } 67 | 68 | if (!isUTF16) 69 | m_success = 70 | m_format->readFile(m_fileName.toLocal8Bit().data(), *m_molecule); 71 | else { 72 | // write it to a temporary file and we'll read it back in 73 | // some formats (like the generic output) need a file 74 | // not just a string buffer 75 | 76 | // first, we need the *name* of the file, not the full path 77 | // because we're going to save a copy in a temp directory 78 | QTemporaryDir tempDir; 79 | QString tempFileName = tempDir.filePath(QFileInfo(m_fileName).fileName()); 80 | QFile tempFile(tempFileName); 81 | if (tempFile.open(QIODevice::WriteOnly | QIODevice::Text)) { 82 | QTextStream out(&tempFile); 83 | // set it to UTF-8 84 | #if QT_VERSION > 0x060000 85 | out.setEncoding(QStringConverter::Utf8); 86 | #else 87 | out.setCodec("UTF-8"); 88 | #endif 89 | out << text; 90 | out.flush(); 91 | tempFile.close(); 92 | m_success = 93 | m_format->readFile(tempFileName.toLocal8Bit().data(), *m_molecule); 94 | tempFile.remove(); 95 | } else // try just reading the string 96 | m_success = 97 | m_format->readString(text.toLocal8Bit().data(), *m_molecule); 98 | } 99 | 100 | if (!m_success) 101 | m_error = QString::fromStdString(m_format->error()); 102 | } 103 | 104 | emit finished(); 105 | } 106 | 107 | void BackgroundFileFormat::write() 108 | { 109 | m_success = false; 110 | m_error.clear(); 111 | 112 | if (!m_molecule) 113 | m_error = tr("No molecule set in BackgroundFileFormat!"); 114 | 115 | if (!m_format) 116 | m_error = tr("No file format set in BackgroundFileFormat!"); 117 | 118 | if (m_fileName.isEmpty()) 119 | m_error = tr("No file name set in BackgroundFileFormat!"); 120 | 121 | if (m_error.isEmpty()) { 122 | m_success = 123 | m_format->writeFile(m_fileName.toLocal8Bit().data(), *m_molecule); 124 | 125 | if (!m_success) 126 | m_error = QString::fromStdString(m_format->error()); 127 | } 128 | 129 | emit finished(); 130 | } 131 | 132 | } // namespace Avogadro 133 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/CHitTest.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CHitTest_HPP_INCLUDED 2 | #define CHitTest_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: CHitTest.hpp 16056 2019-04-10 13:42:31Z mbonk $ 17 | // 18 | // 01/20/14 MSB Initial design 19 | // 20 | 21 | // 3dxware 22 | #include 23 | 24 | namespace TDx { 25 | namespace SpaceMouse { 26 | /// 27 | /// Class can be used to hold the hit-test properties. 28 | /// 29 | template class CHitTest { 30 | public: 31 | typedef point_ point_type; 32 | typedef vector_ vector_type; 33 | 34 | public: 35 | /// 36 | /// Creates a new instance of the class. 37 | /// 38 | CHitTest() : m_aperture(1), m_dirty(false), m_selectionOnly(false) { 39 | } 40 | 41 | #if defined(_MSC_EXTENSIONS) 42 | /// 43 | /// Property accessors 44 | /// 45 | __declspec(property(get = GetDirection, put = PutDirection)) vector_type Direction; 46 | __declspec(property(get = GetLookFrom, put = PutLookFrom)) point_type LookFrom; 47 | __declspec(property(get = GetLookingAt, put = PutLookingAt)) point_type LookingAt; 48 | __declspec(property(get = GetIsDirty, put = PutIsDirty)) bool IsDirty; 49 | __declspec(property(get = GetAperture, put = PutAperture)) double Aperture; 50 | __declspec(property(get = GetSelectionOnly, put = PutSelectionOnly)) bool SelectionOnly; 51 | #endif 52 | 53 | /// 54 | /// Gets or sets the ray direction. 55 | /// 56 | void PutDirection(vector_type value) { 57 | if (!m_dirty) { 58 | m_dirty = static_cast(m_direction != value); 59 | } 60 | m_direction = std::move(value); 61 | } 62 | vector_type GetDirection() const { 63 | return m_direction; 64 | } 65 | 66 | /// 67 | /// Gets or sets the ray origin. 68 | /// 69 | void PutLookFrom(point_type value) { 70 | if (!m_dirty) { 71 | m_dirty = static_cast(m_lookFrom != value); 72 | } 73 | m_lookFrom = std::move(value); 74 | } 75 | const point_type GetLookFrom() const { 76 | return m_lookFrom; 77 | } 78 | 79 | /// 80 | /// Gets or sets the ray hit test result location. 81 | /// 82 | void PutLookingAt(point_type value) { 83 | m_lookingAt = std::move(value); 84 | m_dirty = false; 85 | } 86 | const point_type GetLookingAt() const { 87 | return m_lookingAt; 88 | } 89 | 90 | /// 91 | /// Gets or sets a value indicating if a the parameters have changed since the last hit calculation. 92 | /// 93 | void PutIsDirty(bool value) { 94 | m_dirty = value; 95 | } 96 | bool GetIsDirty() const { 97 | return m_dirty; 98 | } 99 | 100 | /// 101 | /// Gets or sets the ray diameter / aperture on the near clipping plane. 102 | /// 103 | void PutAperture(double value) { 104 | m_dirty = (m_aperture != value); 105 | m_aperture = value; 106 | } 107 | double GetAperture() const { 108 | return m_aperture; 109 | } 110 | 111 | /// 112 | /// Gets or sets a value indicating whether the hit-testing is limited to the selection set. 113 | /// 114 | void PutSelectionOnly(bool value) { 115 | m_selectionOnly = value; 116 | } 117 | bool GetSelectionOnly() const { 118 | return m_selectionOnly; 119 | } 120 | 121 | private: 122 | double m_aperture; 123 | mutable bool m_dirty; 124 | vector_type m_direction; 125 | point_type m_lookFrom; 126 | mutable point_type m_lookingAt; 127 | bool m_selectionOnly; 128 | }; 129 | } // namespace SpaceMouse 130 | } // namespace TDx 131 | #endif // CHitTest_HPP_INCLUDED 132 | 133 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/IModel.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IModel_HPP_INCLUDED 2 | #define IModel_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: IModel.hpp 16047 2019-04-05 12:51:24Z mbonk $ 17 | // 18 | // 19 | #include 20 | 21 | namespace TDx { 22 | namespace SpaceMouse { 23 | namespace Navigation3D { 24 | /// 25 | /// The Model interface 26 | /// 27 | class IModel { 28 | public: 29 | #if !defined(_MSC_VER) || (_MSC_VER > 1700) 30 | virtual ~IModel() = default; 31 | #else 32 | virtual ~IModel() = 0 { 33 | } 34 | #endif 35 | 36 | /// 37 | /// Is called when the navigation library needs to get the extents of the model. 38 | /// 39 | /// A representing the extents of the 40 | /// model. 41 | /// 0 = no error, otherwise <0. 42 | virtual long GetModelExtents(navlib::box_t &extents) const = 0; 43 | 44 | /// 45 | /// Is called when the navigation library needs to get the extents of the selection. 46 | /// 47 | /// A representing the extents of the 48 | /// selection. 49 | /// 0 = no error, otherwise <0. 50 | virtual long GetSelectionExtents(navlib::box_t &extents) const = 0; 51 | 52 | /// 53 | /// Is called to get the selections's transform . 54 | /// 55 | /// The world affine of the 56 | /// selection. 57 | /// 0 = no error, otherwise <0. 58 | virtual long GetSelectionTransform(navlib::matrix_t &transform) const = 0; 59 | 60 | /// 61 | /// Is called to query if the selection is empty. 62 | /// 63 | /// true if nothing is selected. 64 | /// 0 = no error, otherwise <0. 65 | virtual long GetIsSelectionEmpty(navlib::bool_t &empty) const = 0; 66 | 67 | /// 68 | /// Is called to set the selections's transform . 69 | /// 70 | /// The world affine of the selection. 71 | /// 0 = no error, otherwise <0. 72 | virtual long SetSelectionTransform(const navlib::matrix_t& matrix) = 0; 73 | 74 | /// 75 | /// Is called to retrieve the length of the model/world units in meters. 76 | /// 77 | /// The length of a model/world unit in meters. 78 | /// 0 = no error, otherwise <0. 79 | /// 80 | /// The conversion factor is used by the Navigation Library to calculate the height above 81 | /// the floor in walk mode and the speed in the first-person motion model. 82 | /// The Navigation Library assumes that this value does not change and it is only queried 83 | /// once. 84 | /// 85 | virtual long GetUnitsToMeters(double &meters) const = 0; 86 | 87 | /// 88 | /// Is called to retrieve the plane equation of the floor. 89 | /// 90 | /// The plane equation of the floor plane. 91 | /// 0 = no error, otherwise <0. 92 | /// 93 | /// The plane equation is used by the Navigation Library to determine the floor for the 94 | /// walk navigation mode, where the height of the eye is fixed to 1.5m above the floor plane. 95 | /// The floor need not be parallel to the world ground plane. 96 | /// 97 | virtual long GetFloorPlane(navlib::plane_t &floor) const = 0; 98 | }; 99 | } // namespace Navigation3D 100 | } // namespace SpaceMouse 101 | } // namespace TDx 102 | #endif // IModel_HPP_INCLUDED 103 | -------------------------------------------------------------------------------- /cmake/AvogadroCPack.cmake: -------------------------------------------------------------------------------- 1 | set(CPACK_PACKAGE_NAME "Avogadro2") 2 | set(CPACK_PACKAGE_VERSION_MAJOR ${AvogadroApp_VERSION_MAJOR}) 3 | set(CPACK_PACKAGE_VERSION_MINOR ${AvogadroApp_VERSION_MINOR}) 4 | set(CPACK_PACKAGE_VERSION_PATCH ${AvogadroApp_VERSION_PATCH}) 5 | set(CPACK_PACKAGE_VERSION ${AvogadroApp_VERSION}) 6 | set(CPACK_PACKAGE_INSTALL_DIRECTORY "Avogadro2") 7 | set(CPACK_PACKAGE_VENDOR "https://avogadro.cc/") 8 | set(CPACK_PACKAGE_DESCRIPTION 9 | "An advanced molecule editor and visualization application.") 10 | 11 | if(APPLE) 12 | configure_file("${AvogadroApp_SOURCE_DIR}/LICENSE" 13 | "${AvogadroApp_BINARY_DIR}/COPYING.txt" @ONLY) 14 | set(CPACK_RESOURCE_FILE_LICENSE "${AvogadroApp_BINARY_DIR}/COPYING.txt") 15 | set(CPACK_PACKAGE_ICON 16 | "${AvogadroApp_SOURCE_DIR}/avogadro/icons/avogadro.icns") 17 | set(CPACK_BUNDLE_ICON "${CPACK_PACKAGE_ICON}") 18 | 19 | if(${CMAKE_VERSION} VERSION_GREATER "3.19.0") 20 | # add the codesign options to the package 21 | configure_file("${CMAKE_CURRENT_LIST_DIR}/deploy-osx.cmake.in" "${AvogadroApp_BINARY_DIR}/deploy-osx.cmake" @ONLY) 22 | set(CPACK_PRE_BUILD_SCRIPTS "${AvogadroApp_BINARY_DIR}/deploy-osx.cmake") 23 | endif() 24 | 25 | else() 26 | set(CPACK_RESOURCE_FILE_LICENSE "${AvogadroApp_SOURCE_DIR}/LICENSE") 27 | endif() 28 | 29 | set(CPACK_PACKAGE_EXECUTABLES "avogadro2" "Avogadro2") 30 | set(CPACK_CREATE_DESKTOP_LINKS "avogadro2") 31 | 32 | configure_file("${CMAKE_CURRENT_LIST_DIR}/AvogadroCPackOptions.cmake.in" 33 | "${AvogadroApp_BINARY_DIR}/AvogadroCPackOptions.cmake" @ONLY) 34 | set(CPACK_PROJECT_CONFIG_FILE 35 | "${AvogadroApp_BINARY_DIR}/AvogadroCPackOptions.cmake") 36 | 37 | # Should we add extra install rules to make a self-contained bundle, this is 38 | # usually only required when attempting to create self-contained installers. 39 | if(APPLE OR WIN32) 40 | set(INSTALL_BUNDLE_FILES ON) 41 | else() 42 | option(INSTALL_BUNDLE_FILES "Add install rules to bundle files" OFF) 43 | endif() 44 | if(INSTALL_BUNDLE_FILES) 45 | include(BundleUtilities) 46 | # First the AvogadroLibs files that are not detected. 47 | find_package(AvogadroLibs REQUIRED NO_MODULE) 48 | install(DIRECTORY "${AvogadroLibs_LIBRARY_DIR}/avogadro2" 49 | DESTINATION ${INSTALL_LIBRARY_DIR}) 50 | 51 | install(DIRECTORY "${AvogadroLibs_DATA_DIR}/avogadro2" 52 | DESTINATION ${INSTALL_DATA_DIR}) 53 | 54 | # grab OpenSSL for Windows 55 | if(WIN32) 56 | find_package(OpenSSL REQUIRED) 57 | if (DEFINED OPENSSL_FOUND) 58 | set(OPENSSL_ROOT_DIR "${OPENSSL_INCLUDE_DIR}/.." CACHE PATH "OpenSSL root directory") 59 | message(STATUS "Using OpenSSL from ${OPENSSL_ROOT_DIR}") 60 | file(GLOB OPENSSL_DLL ${OPENSSL_ROOT_DIR}/bin/*.dll) 61 | install(FILES ${OPENSSL_DLL} DESTINATION ${INSTALL_RUNTIME_DIR}) 62 | endif() 63 | endif() 64 | 65 | # create a list of exe to run fixup_bundle on 66 | set(BUNDLE_EXE_LIST "") 67 | 68 | # look for genXrd 69 | find_program(GENXRD_EXE genXrdPattern) 70 | if (GENXRD_EXE) 71 | list(APPEND BUNDLE_EXE_LIST ${GENXRD_EXE}) 72 | install(PROGRAMS ${GENXRD_EXE} DESTINATION ${INSTALL_RUNTIME_DIR}) 73 | endif() 74 | 75 | # look for yaehmop (eht_bind) 76 | find_program(EHT_BIND_EXE eht_bind) 77 | if(EHT_BIND_EXE) 78 | list(APPEND BUNDLE_EXE_LIST ${EHT_BIND_EXE}) 79 | install(PROGRAMS ${EHT_BIND_EXE} DESTINATION ${INSTALL_RUNTIME_DIR}) 80 | endif() 81 | 82 | find_program(OBABEL_EXE obabel) 83 | if(OBABEL_EXE) 84 | find_program(OBMM_EXE obmm) 85 | list(APPEND BUNDLE_EXE_LIST ${OBABEL_EXE} ${OBMM_EXE}) 86 | install(PROGRAMS ${OBABEL_EXE} ${OBMM_EXE} DESTINATION ${INSTALL_RUNTIME_DIR}) 87 | get_filename_component(BABEL_DIR "${OBABEL_EXE}" PATH) 88 | if(WIN32) 89 | file(GLOB BABEL_PLUGINS ${BABEL_DIR}/*.obf) 90 | file(GLOB BABEL_LIB ${BABEL_DIR}/openbabel*.dll) 91 | install( 92 | FILES 93 | ${BABEL_PLUGINS} 94 | ${BABEL_LIB} 95 | ${BABEL_DIR}/inchi.dll 96 | ${BABEL_DIR}/libxml2.dll 97 | DESTINATION ${INSTALL_RUNTIME_DIR}) 98 | install(DIRECTORY "${BABEL_DIR}/data" 99 | DESTINATION ${INSTALL_RUNTIME_DIR}) 100 | elseif(APPLE) 101 | file(GLOB LIBINCHI ${BABEL_DIR}/../lib/libinchi.*) 102 | file(GLOB BABEL_LIB ${BABEL_DIR}/../lib/libopenbabel.*) 103 | install(FILES ${LIBINCHI} ${BABEL_LIB} DESTINATION ${INSTALL_LIBRARY_DIR}/../Frameworks/) 104 | install(DIRECTORY "${BABEL_DIR}/../lib/openbabel" 105 | DESTINATION ${INSTALL_LIBRARY_DIR}) 106 | install(DIRECTORY "${BABEL_DIR}/../share/openbabel" 107 | DESTINATION ${INSTALL_DATA_DIR}) 108 | endif() 109 | install(FILES ${AvogadroApp_SOURCE_DIR}/cmake/COPYING.openbabel 110 | DESTINATION ${INSTALL_DOC_DIR}/openbabel) 111 | file(READ "${AvogadroApp_SOURCE_DIR}/cmake/COPYING.openbabel" ob_license) 112 | file(READ "${AvogadroApp_SOURCE_DIR}/LICENSE" avo_license) 113 | file(WRITE "${AvogadroApp_BINARY_DIR}/COPYING.txt" 114 | "${avo_license}\n\nOpen Babel components licensed under GPLv2\n\n" 115 | "${ob_license}") 116 | set(CPACK_RESOURCE_FILE_LICENSE "${AvogadroApp_BINARY_DIR}/COPYING.txt") 117 | endif() 118 | endif() 119 | 120 | include(CPack) 121 | -------------------------------------------------------------------------------- /.github/workflows/build_linux_arm64.yml: -------------------------------------------------------------------------------- 1 | name: Linux ARM64 Build Matrix 2 | # Many thanks to Cristian Adam for examples 3 | # e.g. https://github.com/cristianadam/HelloWorld/blob/master/.github/workflows/build_cmake.yml 4 | # https://cristianadam.eu/20191222/using-github-actions-with-c-plus-plus-and-cmake/ 5 | 6 | on: [push, pull_request, workflow_dispatch] 7 | 8 | env: 9 | QT_VERSION: 6.8.3 10 | FEATURES: -DBUILD_GPL_PLUGINS=ON -DBUILD_MOLEQUEUE=OFF -DWITH_COORDGEN=OFF -DQT_VERSION=6 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.ref }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | build: 18 | name: ${{ matrix.config.name }} 19 | runs-on: ${{ matrix.config.os }} 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | config: 24 | - { 25 | name: "Ubuntu ARM", artifact: "", 26 | os: ubuntu-24.04-arm, 27 | cc: "gcc", cxx: "g++", 28 | build_type: "Debug", 29 | cmake_flags: "-G Ninja -DUSE_SYSTEM_EIGEN=TRUE", 30 | } 31 | - { 32 | name: "AppImage ARM", artifact: "Avogadro2-arm64.AppImage", 33 | os: ubuntu-24.04-arm, 34 | cc: "gcc", cxx: "g++", 35 | build_type: "Release", 36 | cmake_flags: "-G Ninja -DINSTALL_BUNDLE_FILES=ON", 37 | } 38 | 39 | steps: 40 | - name: Checkout workflow repository 41 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 42 | 43 | - name: Checkout Repositories 44 | uses: ./.github/actions/checkout-repositories 45 | 46 | - name: Install Dependencies 47 | run: | 48 | sudo apt-get -qq update 49 | sudo apt-get -qq install ninja-build libeigen3-dev libboost-all-dev libglew-dev libxml2-dev 50 | sudo apt-get -qq install libfuse2 51 | 52 | - name: Install Qt 53 | uses: jurplel/install-qt-action@d325aaf2a8baeeda41ad0b5d39f84a6af9bcf005 # v4.3.0 54 | with: 55 | cache: true 56 | version: ${{ env.QT_VERSION }} 57 | 58 | - name: Configure 59 | run: | 60 | if [ ! -d "${{ runner.workspace }}/build" ]; then mkdir "${{ runner.workspace }}/build"; fi 61 | cd "${{ runner.workspace }}/build" 62 | CC=${{matrix.config.cc}} CXX=${{matrix.config.cxx}} cmake $GITHUB_WORKSPACE/openchemistry ${{env.FEATURES}} -DCMAKE_BUILD_TYPE=${{matrix.config.build_type}} ${{matrix.config.cmake_flags}} 63 | shell: bash 64 | 65 | - name: Build 66 | run: | 67 | CC=${{matrix.config.cc}} CXX=${{matrix.config.cxx}} cmake --build . --config ${{matrix.config.build_type}} ${{matrix.config.build_flags}} 68 | shell: bash 69 | working-directory: ${{ runner.workspace }}/build 70 | 71 | - name: Run tests 72 | if: (matrix.config.build_type != 'Release') 73 | shell: cmake -P {0} 74 | run: | 75 | include(ProcessorCount) 76 | ProcessorCount(N) 77 | set(ENV{CTEST_OUTPUT_ON_FAILURE} "ON") 78 | set(ENV{ASAN_OPTIONS} "new_delete_type_mismatch=0") 79 | execute_process( 80 | COMMAND ctest -j ${N} 81 | WORKING_DIRECTORY ${{ runner.workspace }}/build/avogadrolibs 82 | RESULT_VARIABLE result 83 | ) 84 | if (NOT result EQUAL 0) 85 | message(FATAL_ERROR "Running tests failed!") 86 | endif() 87 | 88 | - name: Package AppImage 89 | if: matrix.config.name == 'AppImage ARM' 90 | shell: bash 91 | run: | 92 | mkdir appdir 93 | mv prefix appdir/usr 94 | 95 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:appdir/usr/lib 96 | 97 | wget -c -nv "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-aarch64.AppImage" 98 | wget -c -nv "https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-aarch64.AppImage" 99 | wget -c -nv "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-aarch64.AppImage" 100 | chmod a+x *.AppImage 101 | 102 | # get pixi 103 | # wget -c -nv "https://github.com/prefix-dev/pixi/releases/latest/download/pixi-aarch64-unknown-linux-musl" 104 | # mv pixi-aarch64-unknown-linux-musl appdir/usr/bin/pixi 105 | 106 | ./linuxdeploy-aarch64.AppImage -d appdir/usr/share/applications/*.desktop --plugin qt --library /usr/lib/aarch64-linux-gnu/libssl.so.3 --library /usr/lib/aarch64-linux-gnu/libcrypto.so.3 --appdir appdir 107 | # add the custom AppRun 108 | rm appdir/AppRun 109 | cp ../${{ github.event.repository.name }}/openchemistry/avogadrolibs/scripts/AppImage.sh appdir/AppRun 110 | chmod a+x appdir/AppRun 111 | ./appimagetool-aarch64.AppImage appdir 112 | mv Avogadro*.AppImage avogadroapp/Avogadro2-aarch64.AppImage # for upload 113 | working-directory: ${{ runner.workspace }}/build 114 | 115 | - name: Upload 116 | if: matrix.config.artifact != 0 117 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 118 | with: 119 | path: ${{ runner.workspace }}/build/avogadroapp/Avogadro2*.* 120 | name: ${{ matrix.config.artifact }} 121 | 122 | - name: Setup tmate session 123 | if: ${{ failure() }} 124 | uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23 125 | timeout-minutes: 60 126 | -------------------------------------------------------------------------------- /scripts/filter_sarif.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # From https://github.com/zbazztian/filter-sarif/blob/master/filter_sarif.py 4 | # Some modifications by Geoffrey Hutchison 5 | 6 | import argparse 7 | import json 8 | import re 9 | from globber import match 10 | 11 | 12 | def match_path_and_rule(path, rule, patterns): 13 | result = True 14 | for sign, file_pattern, rule_pattern in patterns: 15 | if match(rule_pattern, rule) and match(file_pattern, path): 16 | result = sign 17 | return result 18 | 19 | 20 | def parse_pattern(line): 21 | sep_char = ":" 22 | esc_char = "\\" 23 | file_pattern = "" 24 | rule_pattern = "" 25 | seen_separator = False 26 | sign = True 27 | 28 | # inclusion or exclusion pattern? 29 | uline = line 30 | if line: 31 | if line[0] == "-": 32 | sign = False 33 | uline = line[1:] 34 | elif line[0] == "+": 35 | uline = line[1:] 36 | 37 | i = 0 38 | while i < len(uline): 39 | char = uline[i] 40 | i = i + 1 41 | if char == sep_char: 42 | if seen_separator: 43 | raise Exception( 44 | 'Invalid pattern: "' + line + '" Contains more than one separator!' 45 | ) 46 | seen_separator = True 47 | continue 48 | 49 | if char == esc_char: 50 | next_char = uline[i] if (i < len(uline)) else None 51 | if next_char in ["+", "-", esc_char, sep_char]: 52 | i = i + 1 53 | char = next_char 54 | 55 | if seen_separator: 56 | rule_pattern = rule_pattern + char 57 | else: 58 | file_pattern = file_pattern + char 59 | 60 | if not rule_pattern: 61 | rule_pattern = "**" 62 | 63 | return sign, file_pattern, rule_pattern 64 | 65 | 66 | def filter_sarif(args): 67 | if args.split_lines: 68 | tmp = [] 69 | for pattern in args.patterns: 70 | tmp = tmp + re.split("\r?\n", pattern) 71 | args.patterns = tmp 72 | 73 | args.patterns = [parse_pattern(pattern) for pattern in args.patterns if pattern] 74 | 75 | print("Given patterns:") 76 | for sign, file_pattern, rule_pattern in args.patterns: 77 | sign_text = "positive" if sign else "negative" 78 | print(f"files: {file_pattern} rules: {rule_pattern} ({sign_text})") 79 | 80 | with open(args.input, "r", encoding="UTF-8") as file: 81 | sarif = json.load(file) 82 | 83 | for run in sarif.get("runs", []): 84 | if run.get("results", []): 85 | new_results = [] 86 | for result in run["results"]: 87 | if result.get("locations", []): 88 | new_locations = [] 89 | for location in result["locations"]: 90 | # TODO: The uri field is optional. We might have to fetch the 91 | # actual uri from "artifacts" via "index" 92 | # (https://github.com/microsoft/sarif-tutorials/blob/main/docs/2-Basics.md) 93 | uri = ( 94 | location.get("physicalLocation", {}) 95 | .get("artifactLocation", {}) 96 | .get("uri", None) 97 | ) 98 | # TODO: The ruleId field is optional and potentially ambiguous. 99 | # We might have to fetch the actual ruleId from the rule metadata 100 | # via the ruleIndex field. 101 | # (https://github.com/microsoft/sarif-tutorials/blob/main/docs/2-Basics.md) 102 | rule_id = result["ruleId"] 103 | if uri is None or match_path_and_rule( 104 | uri, rule_id, args.patterns 105 | ): 106 | new_locations.append(location) 107 | result["locations"] = new_locations 108 | if new_locations: 109 | new_results.append(result) 110 | else: 111 | # locations array doesn't exist or is empty, so we can't match on anything 112 | # therefore, we include the result in the output 113 | new_results.append(result) 114 | run["results"] = new_results 115 | 116 | with open(args.output, "w", encoding="UTF-8") as file: 117 | json.dump(sarif, file, indent=args.indent) 118 | 119 | 120 | def main(): 121 | parser = argparse.ArgumentParser(prog="filter-sarif") 122 | parser.add_argument("--input", help="Input SARIF file", required=True) 123 | parser.add_argument("--output", help="Output SARIF file", required=True) 124 | parser.add_argument( 125 | "--split-lines", 126 | default=False, 127 | action="store_true", 128 | help="Split given patterns on newlines.", 129 | ) 130 | parser.add_argument( 131 | "--indent", default=None, type=int, help="Indentation level for JSON output." 132 | ) 133 | parser.add_argument("patterns", help="Inclusion and exclusion patterns.", nargs="+") 134 | 135 | def print_usage(): 136 | print(parser.format_usage()) 137 | 138 | args = parser.parse_args() 139 | filter_sarif(args) 140 | 141 | 142 | if __name__ == "__main__": 143 | main() 144 | -------------------------------------------------------------------------------- /avogadro/renderingdialog.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #include "renderingdialog.h" 7 | #include "ui_renderingdialog.h" 8 | 9 | namespace Avogadro { 10 | 11 | RenderingDialog::RenderingDialog(QWidget *parent_, SolidPipeline &pipeline) 12 | : QDialog(parent_), m_ui(new Ui::RenderingDialog), m_solidPipeline(pipeline) 13 | { 14 | m_ui->setupUi(this); 15 | 16 | m_ui->aoEnableCheckBox->setCheckState(pipeline.getAoEnabled()? Qt::Checked : Qt::Unchecked); 17 | m_ui->dofEnableCheckBox->setCheckState(pipeline.getDofEnabled()? Qt::Checked : Qt::Unchecked); 18 | m_ui->fogEnableCheckBox->setCheckState(pipeline.getFogEnabled()? Qt::Checked : Qt::Unchecked); 19 | m_ui->aoStrengthDoubleSpinBox->setMinimum(0.0); 20 | m_ui->aoStrengthDoubleSpinBox->setValue(pipeline.getAoStrength()); 21 | m_ui->aoStrengthDoubleSpinBox->setMaximum(2.0); 22 | m_ui->aoStrengthDoubleSpinBox->setDecimals(1); 23 | m_ui->aoStrengthDoubleSpinBox->setSingleStep(0.1); 24 | m_ui->dofStrengthDoubleSpinBox->setMinimum(0.0); 25 | m_ui->dofStrengthDoubleSpinBox->setValue(pipeline.getDofStrength()); 26 | m_ui->dofStrengthDoubleSpinBox->setMaximum(2.0); 27 | m_ui->dofStrengthDoubleSpinBox->setDecimals(1); 28 | m_ui->dofStrengthDoubleSpinBox->setSingleStep(0.1); 29 | m_ui->dofPositionDoubleSpinBox->setMinimum(0.0); 30 | m_ui->dofPositionDoubleSpinBox->setValue(pipeline.getDofPosition()); 31 | // We can adjust the max and min value 32 | // after testing with several molecules 33 | m_ui->dofPositionDoubleSpinBox->setMaximum(20.0); 34 | m_ui->dofPositionDoubleSpinBox->setDecimals(1); 35 | m_ui->dofPositionDoubleSpinBox->setSingleStep(0.1); 36 | m_ui->fogStrengthDoubleSpinBox->setMinimum(-20.0); 37 | m_ui->fogStrengthDoubleSpinBox->setValue(pipeline.getFogStrength()); 38 | m_ui->fogStrengthDoubleSpinBox->setMaximum(20.0); 39 | m_ui->fogStrengthDoubleSpinBox->setDecimals(1); 40 | m_ui->fogStrengthDoubleSpinBox->setSingleStep(0.1); 41 | m_ui->fogPositionDoubleSpinBox->setMinimum(-20.0); 42 | m_ui->fogPositionDoubleSpinBox->setValue(pipeline.getFogPosition()); 43 | m_ui->fogPositionDoubleSpinBox->setMaximum(20.0); 44 | m_ui->fogPositionDoubleSpinBox->setDecimals(1); 45 | m_ui->fogPositionDoubleSpinBox->setSingleStep(0.1); 46 | m_ui->edEnableCheckBox->setCheckState(pipeline.getEdEnabled()? Qt::Checked : Qt::Unchecked); 47 | 48 | connect(m_ui->aoEnableCheckBox, SIGNAL(stateChanged(int)), 49 | SLOT(aoEnableCheckBoxChanged(int))); 50 | connect(m_ui->dofEnableCheckBox, SIGNAL(stateChanged(int)), 51 | SLOT(dofEnableCheckBoxChanged(int))); 52 | connect(m_ui->fogEnableCheckBox, SIGNAL(stateChanged(int)), 53 | SLOT(fogEnableCheckBoxChanged(int))); 54 | connect(m_ui->saveButton, SIGNAL(clicked()), 55 | SLOT(saveButtonClicked())); 56 | connect(m_ui->closeButton, SIGNAL(clicked()), 57 | SLOT(closeButtonClicked())); 58 | } 59 | 60 | RenderingDialog::~RenderingDialog() 61 | { 62 | delete m_ui; 63 | } 64 | 65 | bool RenderingDialog::aoEnabled() 66 | { 67 | return m_ui->aoEnableCheckBox->checkState() == Qt::Checked; 68 | } 69 | 70 | bool RenderingDialog::dofEnabled() 71 | { 72 | return m_ui->dofEnableCheckBox->checkState() == Qt::Checked; 73 | } 74 | bool RenderingDialog::fogEnabled() 75 | { 76 | return m_ui->fogEnableCheckBox->checkState() == Qt::Checked; 77 | } 78 | 79 | float RenderingDialog::aoStrength() 80 | { 81 | return m_ui->aoStrengthDoubleSpinBox->value(); 82 | } 83 | 84 | float RenderingDialog::dofStrength() 85 | { 86 | return m_ui->dofStrengthDoubleSpinBox->value(); 87 | } 88 | 89 | float RenderingDialog::dofPosition() 90 | { 91 | return m_ui->dofPositionDoubleSpinBox->value(); 92 | } 93 | float RenderingDialog::fogStrength() 94 | { 95 | return m_ui->fogStrengthDoubleSpinBox->value(); 96 | } 97 | 98 | float RenderingDialog::fogPosition() 99 | { 100 | return m_ui->fogPositionDoubleSpinBox->value(); 101 | } 102 | 103 | bool RenderingDialog::edEnabled() 104 | { 105 | return m_ui->edEnableCheckBox->checkState() == Qt::Checked; 106 | } 107 | 108 | 109 | void RenderingDialog::dofEnableCheckBoxChanged(int state) 110 | { 111 | if (state == Qt::Unchecked){ 112 | m_ui->dofStrengthDoubleSpinBox->setEnabled(false); 113 | m_ui->dofPositionDoubleSpinBox->setEnabled(false); 114 | } 115 | else{ 116 | m_ui->dofStrengthDoubleSpinBox->setEnabled(true); 117 | m_ui->dofPositionDoubleSpinBox->setEnabled(true); 118 | } 119 | } 120 | 121 | void RenderingDialog::fogEnableCheckBoxChanged(int state) 122 | { 123 | if (state == Qt::Unchecked){ 124 | m_ui->fogPositionDoubleSpinBox->setEnabled(false); 125 | m_ui->fogStrengthDoubleSpinBox->setEnabled(false); 126 | } 127 | else{ 128 | m_ui->fogStrengthDoubleSpinBox->setEnabled(true); 129 | m_ui->fogPositionDoubleSpinBox->setEnabled(true); 130 | } 131 | } 132 | 133 | void RenderingDialog::aoEnableCheckBoxChanged(int state) 134 | { 135 | if (state == Qt::Unchecked) 136 | m_ui->aoStrengthDoubleSpinBox->setEnabled(false); 137 | else 138 | m_ui->aoStrengthDoubleSpinBox->setEnabled(true); 139 | } 140 | 141 | void RenderingDialog::saveButtonClicked() 142 | { 143 | m_solidPipeline.setAoEnabled(aoEnabled()); 144 | m_solidPipeline.setDofEnabled(dofEnabled()); 145 | m_solidPipeline.setAoStrength(aoStrength()); 146 | m_solidPipeline.setDofStrength(dofStrength()); 147 | m_solidPipeline.setDofPosition(dofPosition()); 148 | m_solidPipeline.setFogStrength(fogStrength()); 149 | m_solidPipeline.setFogEnabled(fogEnabled()); 150 | m_solidPipeline.setFogPosition(fogPosition()); 151 | m_solidPipeline.setEdEnabled(edEnabled()); 152 | this->accept(); 153 | } 154 | 155 | void RenderingDialog::closeButtonClicked() 156 | { 157 | this->reject(); 158 | } 159 | 160 | } /* namespace Avogadro */ 161 | -------------------------------------------------------------------------------- /thirdparty/3DConnexion/src/navlib_stub.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | 4 | Copyright (c) 2014-2023 3Dconnexion. 5 | 6 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 7 | ******************************************************************************/ 8 | 9 | /** 10 | * @file navlib_stub.c 11 | * @brief interface routines to the navlib library routines. 12 | */ 13 | 14 | /*----------------------------------------------------------------------------- 15 | * The module contains interface routines to the navlib library routines 16 | * contained in the associated Dynamic Link Library. The DLL is loaded 17 | * explicitly when NlLoadLibrary is invoked. When the DLL is loaded, the 18 | * initialization routine finds the addresses of the routines that it exposes 19 | * and allows them to be used in this code. 20 | */ 21 | 22 | #if _WIN32 23 | 24 | // windows 25 | #include 26 | #include 27 | #elif __APPLE__ 28 | #include 29 | #include 30 | #include 31 | #endif 32 | 33 | #ifndef EISCONN 34 | #define EISCONN 113 35 | #define ENOBUFS 119 36 | #define ENODATA 120 37 | #define EOPNOTSUPP 130 38 | #endif 39 | 40 | // navlib 41 | #include 42 | 43 | /* DLL library name */ 44 | #ifdef _WIN32 45 | static const char *TheLibrary = "TDxNavLib"; 46 | #elif __APPLE__ 47 | static const char *TheLibrary = "/Library/Frameworks/3DconnexionNavlib.framework/3DconnexionNavlib"; 48 | #endif 49 | 50 | /* Names of functions contained in DLL; used to find their addresses at load time */ 51 | static const char *cNlCreate = "NlCreate"; 52 | static const char *cNlClose = "NlClose"; 53 | static const char *cNlReadValue = "NlReadValue"; 54 | static const char *cNlWriteValue = "NlWriteValue"; 55 | static const char *cNlGetType = "NlGetType"; 56 | 57 | typedef long(__cdecl *PFN_NLCREATE)(nlHandle_t *pnh, const char *appname, 58 | const accessor_t accessors[], size_t accessor_count, 59 | nlCreateOptions_t const *options); 60 | typedef long(__cdecl *PFN_NLCLOSE)(nlHandle_t nh); 61 | typedef long(__cdecl *PFN_NLREADVALUE)(nlHandle_t nh, property_t name, value_t *value); 62 | typedef long(__cdecl *PFN_NLWRITEVALUE)(nlHandle_t nh, property_t name, const value_t *value); 63 | typedef propertyType_t(__cdecl *PFN_NLGETTYPE)(property_t name); 64 | 65 | /* Function pointers to functions in DLL */ 66 | static PFN_NLCREATE pfnNlCreate = NULL; 67 | static PFN_NLCLOSE pfnNlClose = NULL; 68 | static PFN_NLREADVALUE pfnNlReadValue = NULL; 69 | static PFN_NLWRITEVALUE pfnNlWriteValue = NULL; 70 | static PFN_NLGETTYPE pfnNlGetType = NULL; 71 | 72 | extern const long NlErrorCode; 73 | 74 | #if _WIN32 75 | 76 | long NlLoadLibrary() { 77 | long error = 0; 78 | HMODULE h = LoadLibraryA(TheLibrary); 79 | if (!h) { 80 | error = HRESULT_FROM_WIN32(GetLastError()); 81 | } 82 | else { 83 | /* load up the function pointer table */ 84 | if (((pfnNlCreate = (PFN_NLCREATE)GetProcAddress(h, cNlCreate)) == NULL) || 85 | ((pfnNlClose = (PFN_NLCLOSE)GetProcAddress(h, cNlClose)) == NULL) || 86 | ((pfnNlReadValue = (PFN_NLREADVALUE)GetProcAddress(h, cNlReadValue)) == NULL) || 87 | ((pfnNlWriteValue = (PFN_NLWRITEVALUE)GetProcAddress(h, cNlWriteValue)) == NULL) || 88 | ((pfnNlGetType = (PFN_NLGETTYPE)GetProcAddress(h, cNlGetType)) == NULL)) { 89 | error = HRESULT_FROM_WIN32(GetLastError()); 90 | FreeLibrary(h); 91 | h = NULL; 92 | } 93 | } 94 | return error; 95 | } 96 | 97 | #elif __APPLE__ 98 | 99 | long NlLoadLibrary() { 100 | long error = 0; 101 | void *libHandle = dlopen(TheLibrary, RTLD_LAZY | RTLD_LOCAL); 102 | if (NULL == libHandle) { 103 | error = -1; // whatever error it's an error dlopen() does not set errno 104 | fprintf(stderr, "Error: Failed to open library \"%s\"! Error: %s!\n", TheLibrary, dlerror()); 105 | } 106 | else { 107 | /* load up the function pointer table */ 108 | if (((pfnNlCreate = (PFN_NLCREATE)dlsym(libHandle, cNlCreate)) == NULL) || 109 | ((pfnNlClose = (PFN_NLCLOSE)dlsym(libHandle, cNlClose)) == NULL) || 110 | ((pfnNlReadValue = (PFN_NLREADVALUE)dlsym(libHandle, cNlReadValue)) == NULL) || 111 | ((pfnNlWriteValue = (PFN_NLWRITEVALUE)dlsym(libHandle, cNlWriteValue)) == NULL) || 112 | ((pfnNlGetType = (PFN_NLGETTYPE)dlsym(libHandle, cNlGetType)) == NULL)) { 113 | error = -2; // whatever error it is - it's an error dlsym() does not set errno 114 | fprintf(stderr, "Error: Failed to fetch symbols from \"%s\"! Error: %s!\n", TheLibrary, 115 | dlerror()); 116 | 117 | dlclose(libHandle); 118 | libHandle = NULL; 119 | } 120 | } 121 | return error; 122 | } 123 | 124 | #else 125 | 126 | long NlLoadLibrary() { 127 | return EOPNOTSUPP; 128 | } 129 | 130 | #endif 131 | 132 | long __cdecl NlCreate(nlHandle_t *pnh, const char *appname, const accessor_t accessors[], 133 | size_t accessor_count, const nlCreateOptions_t *options) { 134 | if (pfnNlCreate) { 135 | return pfnNlCreate(pnh, appname, accessors, accessor_count, options); 136 | } 137 | 138 | return NlErrorCode; 139 | } 140 | 141 | long __cdecl NlClose(nlHandle_t nh) { 142 | if (pfnNlClose) { 143 | return pfnNlClose(nh); 144 | } 145 | 146 | return NlErrorCode; 147 | } 148 | 149 | long __cdecl NlReadValue(nlHandle_t nh, property_t name, value_t *value) { 150 | if (pfnNlReadValue) { 151 | return pfnNlReadValue(nh, name, value); 152 | } 153 | 154 | return NlErrorCode; 155 | } 156 | 157 | long __cdecl NlWriteValue(nlHandle_t nh, property_t name, const value_t *value) { 158 | if (pfnNlWriteValue) { 159 | return pfnNlWriteValue(nh, name, value); 160 | } 161 | 162 | return NlErrorCode; 163 | } 164 | 165 | propertyType_t __cdecl NlGetType(property_t name) { 166 | if (pfnNlGetType) { 167 | return pfnNlGetType(name); 168 | } 169 | 170 | return unknown_type; 171 | } 172 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![Avogadro 2][Avogadro2Logo] Avogadro 2 2 | 3 | [![Latest Release](https://img.shields.io/github/v/release/openchemistry/avogadrolibs)](https://github.com/OpenChemistry/avogadrolibs/releases) [![BSD License](https://img.shields.io/github/license/openchemistry/avogadrolibs)](https://github.com/OpenChemistry/avogadrolibs/blob/master/LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/status/openchemistry/avogadrolibs/build_cmake.yml?branch=master)](https://github.com/OpenChemistry/avogadrolibs/actions) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/44bb12662c564ed8a27ee8a7fd89ed50)](https://app.codacy.com/gh/OpenChemistry/avogadrolibs/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) 4 | [![Download Count](https://avogadro.cc/downloads.svg?readme)](https://github.com/OpenChemistry/avogadrolibs/releases) [![Citation Count](https://avogadro.cc/citations.svg?readme)](http://doi.org/10.1186/1758-2946-4-17) 5 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](http://makeapullrequest.com) [![GitHub contributors](https://img.shields.io/github/contributors/openchemistry/avogadrolibs.svg?style=flat&color=0bf)](https://github.com/OpenChemistry/avogadrolibs/graphs/contributors) [![OpenCollective Backers](https://img.shields.io/opencollective/all/open-chemistry)](https://opencollective.com/open-chemistry) 6 | 7 | ## Introduction 8 | 9 | Avogadro is an advanced molecular editor designed for cross-platform use in 10 | computational chemistry, molecular modeling, education, bioinformatics, 11 | materials science, and related areas. 12 | It offers flexible rendering and a powerful plugin architecture. 13 | 14 | Core features and goals of the Avogadro project include: 15 | 16 | * Open-source, distributed under the liberal 3-clause BSD license 17 | * Cross-platform, with builds on Linux, Mac OS X and Windows 18 | * An intuitive interface designed to be useful to the whole community 19 | * Fast and efficient, embracing the latest technologies 20 | * Extensible, making extensive use of a plugin architecture 21 | * Flexible, supporting a range of chemical data formats and packages 22 | 23 | Avogadro 2 began as a rewrite of the original [Avogadro 1.x][Avogadro1], which 24 | is now unsupported. 25 | The successor is faster, better, much more stable, and more featureful. 26 | A final couple of features yet to be ported will be implemented by the time of 27 | the 2.0 release, but in the meantime Avogadro 2 already has 28 | [much new functionality of its own](https://two.avogadro.cc/docs/whats-new-in-avogadro-2/). 29 | 30 | Avogadro's codebase is split across a 31 | [libraries repository](https://github.com/openchemistry/avogadrolibs) 32 | and an [application repository](https://github.com/openchemistry/avogadroapp). 33 | The new code architecture provides a high-performance rendering engine, modern 34 | code development, and significantly improved speed and stability. 35 | 36 | Avogadro is being developed as part of the [Open Chemistry][OpenChemistry] 37 | project by an open community, which was started at [Kitware][Kitware] as 38 | an open-source community project. 39 | 40 | ## Installing 41 | 42 | For the most up-to-date experience use the nightly builds prepared by GitHub 43 | actions for: 44 | 45 | * [Linux (AppImage)](https://nightly.link/OpenChemistry/avogadrolibs/workflows/build_linux/master/Avogadro2-x86_64.AppImage.zip) 46 | * [macOS (Apple Silicon)](https://nightly.link/OpenChemistry/avogadrolibs/workflows/build_mac/master/macOS-arm64.zip) 47 | * [macOS (Intel)](https://nightly.link/OpenChemistry/avogadrolibs/workflows/build_mac/master/macOS-intel.zip) 48 | * [Windows](https://nightly.link/OpenChemistry/avogadrolibs/workflows/build_windows/master/Win64.exe.zip) 49 | 50 | We also maintain a 51 | [`beta` Flatpak](https://two.avogadro.cc/install/flatpak.html#install-flatpak-beta) 52 | for Linux that is updated with the lastest changes every week or two. 53 | 54 | For full releases and an overview of all available ways to obtain Avogadro see 55 | the [overview](Install) on the Avogadro website. 56 | 57 | Binaries and the source code for each release can be found on the 58 | [GitHub releases page](https://github.com/OpenChemistry/avogadrolibs/releases). 59 | 60 | If you would like to build from source we recommend that you follow our 61 | [build guide][Build]. 62 | 63 | ## User guide 64 | 65 | Our [user documentation](https://two.avogadro.cc/docs/) can be found on the 66 | Avogadro website, as well as a brief guide to 67 | [getting started](https://two.avogadro.cc/docs/getting-started/). 68 | 69 | ## Contributing 70 | 71 | We welcome *all* kinds of contributions as a community project, from bug 72 | reports, feature suggestions, language translations, Python plugins, 73 | and C++ code development. 74 | 75 | Our project uses the standard GitHub pull request process for code review 76 | and integration. Please check our [contribution][Contribution] guide for more 77 | details on developing and contributing to the project. The [GitHub issue 78 | tracker](https://github.com/openchemistry/avogadrolibs/issues/) 79 | can be used to report bugs, make feature requests, etc. Our API is 80 | [documented online][API] with updated documentation generated nightly. 81 | 82 | To introduce yourself, ask for help, or general discussion, we welcome everyone 83 | to our [forum](https://discuss.avogadro.cc/) 84 | 85 | Contributors Hall of Fame: 86 | 87 | 88 | 89 | 90 | [Avogadro2Logo]: https://raw.githubusercontent.com/OpenChemistry/avogadrolibs/master/docs/avogadro2_64.png "Avogadro2" 91 | [OpenChemistry]: https://openchemistry.org/ "Open Chemistry Project" 92 | [OpenChemistryLogo]: https://raw.githubusercontent.com/OpenChemistry/avogadrolibs/master/docs/OpenChemistry128.png "Open Chemistry" 93 | [Kitware]: https://kitware.com/ "Kitware, Inc." 94 | [Avogadro1]: https://avogadro.cc/ "Avogadro 1" 95 | [Build]: https://two.avogadro.cc/develop/build/ "Building Avogadro" 96 | [Install]: https://two.avogadro.cc/install/ "Installing Avogadro" 97 | [Contribution]: https://two.avogadro.cc/contrib/ "Contribution guide" 98 | [API]: https://two.avogadro.cc/develop/classlist/ "API documentation" 99 | -------------------------------------------------------------------------------- /flatpak/org.openchemistry.Avogadro2.yaml: -------------------------------------------------------------------------------- 1 | app-id: org.openchemistry.Avogadro2 2 | runtime: org.kde.Platform 3 | sdk: org.kde.Sdk 4 | runtime-version: "6.8" 5 | command: avogadro2 6 | appdata-license: BSD-3-Clause AND GPL-2.0-only 7 | finish-args: 8 | - --socket=wayland 9 | - --socket=fallback-x11 # To support X11 10 | - --share=ipc # Bad performance on X11 without 11 | - --device=dri # OpenGL rendering 12 | - --share=network # For plugin downloads 13 | cleanup: 14 | - /lib/cmake 15 | - '*.la' 16 | - '*.a' 17 | 18 | modules: 19 | # Needed to compile glew apparently 20 | - shared-modules/glu/glu-9.json 21 | 22 | # Open Babel is broken without patched rapidjson 23 | - name: rapidjson 24 | buildsystem: cmake-ninja 25 | builddir: true 26 | config-opts: 27 | - -DRAPIDJSON_BUILD_DOC=OFF 28 | - -DRAPIDJSON_BUILD_EXAMPLES=OFF 29 | - -DRAPIDJSON_BUILD_TESTS=OFF 30 | sources: 31 | - type: git 32 | url: https://github.com/Tencent/rapidjson.git 33 | # Commit used was simply most recent at the time of writing 34 | # Would rather use 4d6cb08189cf7336821f04090b612baa2ca6a90d (same commit as openSUSE 35 | # Tumbleweed) as known to be good, but older commits like that don't seem to compile 36 | commit: 7c73dd7de7c4f14379b781418c6e947ad464c818 37 | 38 | - name: openbabel 39 | buildsystem: cmake-ninja 40 | builddir: true 41 | config-opts: 42 | # Match the way Avogadro builds Open Babel 43 | - -DCMAKE_BUILD_TYPE=Release 44 | - -DENABLE_TESTS=OFF 45 | - -DBUILD_GUI=OFF 46 | - -DOPTIMIZE_NATIVE=OFF 47 | - -DOB_USE_PREBUILT_BINARIES=OFF 48 | - -DENABLE_VERSIONED_FORMATS=OFF 49 | - -DWITH_JSON=ON 50 | - -DWITH_COORDGEN=OFF 51 | - -DWITH_MAEPARSER=OFF 52 | sources: 53 | - type: git 54 | url: https://github.com/openbabel/openbabel.git 55 | commit: 32cf131444c1555c749b356dab44fb9fe275271f 56 | 57 | - name: avogadro2 58 | buildsystem: cmake-ninja 59 | builddir: true # Build outside of source tree, just like other builds 60 | no-make-install: true # Superbuild doesn't have `install` command defined 61 | config-opts: 62 | # Match GitHub builds as much as possible, which generally means using defaults 63 | - -DCMAKE_BUILD_TYPE=Debug 64 | - -DBUILD_GPL_PLUGINS=ON 65 | - -DBUILD_MOLEQUEUE=OFF 66 | - -DQT_VERSION=6 67 | - -DDOWNLOAD_TO_SOURCE_DIR=ON 68 | - -DUSE_SYSTEM_OPENBABEL=ON 69 | sources: 70 | # Avogadro stuff all already collected together as part of GitHub Actions 71 | # This means that if using this to build the Flatpak locally, the openchemistry repo and 72 | # its submodules must be cloned into ./openchemistry in advance of running flatpak-builder 73 | # with this manifest 74 | - type: dir 75 | path: openchemistry 76 | 77 | # Now fetch third-party stuff where the source is expected in `openchemistry/thirdparty` 78 | # JKQtPlotter 79 | - type: archive 80 | url: https://github.com/jkriege2/JKQtPlotter/archive/5fd8951edc73a077096c84c5a4474c29f239ed66.tar.gz 81 | sha256: 0deba5af19525f5411b12064c79469337651268b22d48e39fda469303b38539a 82 | dest: thirdparty/jkqtplotter 83 | 84 | # Other third-party sources would normally be downloaded by Avogadro build on the fly 85 | # Flatpaks aren't allowed network access during build so have to download source archives 86 | # ahead of time to download_dir (which we've indicated using `-DDOWNLOAD_TO_SOURCE_DIR=ON`) 87 | # Match order in projects.cmake 88 | # glew 89 | # (Should be able to use shared module but not picked up for whatever reason) 90 | - type: file 91 | url: https://github.com/nigels-com/glew/releases/download/glew-2.2.0/glew-2.2.0.tgz 92 | sha256: d4fc82893cfb00109578d0a1a2337fb8ca335b3ceccf97b97e5cc7f08e4353e1 93 | dest: Downloads 94 | # Eigen3 95 | - type: file 96 | url: https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz 97 | sha256: 8586084f71f9bde545ee7fa6d00288b264a2b7ac3607b974e54d13e7162c1c72 98 | dest: Downloads 99 | # OpenBabel 100 | - type: file 101 | url: https://github.com/openbabel/openbabel/archive/32cf131444c1555c749b356dab44fb9fe275271f.tar.gz 102 | sha256: 7b471015df510b30057b8356f42729a35dfd1f4fa85f205c56bbaf3c64e85071 103 | dest: Downloads 104 | # spglib 105 | - type: file 106 | url: https://github.com/spglib/spglib/archive/v2.5.0.tar.gz 107 | sha256: b6026f5e85106c0c9ee57e54b9399890d0f29982e20e96ede0428b3efbe6b914 108 | dest: Downloads 109 | # libarchive 110 | - type: file 111 | url: https://github.com/libarchive/libarchive/archive/v3.7.7.tar.gz 112 | sha256: fa62384995e8aa4f5a901c184fb5c91e56a29e24c05b6881a7f8fd5bbea694d2 113 | dest: Downloads 114 | # msgpackc 115 | - type: file 116 | url: https://github.com/msgpack/msgpack-c/releases/download/cpp-3.3.0/msgpack-3.3.0.tar.gz 117 | sha256: 6e114d12a5ddb8cb11f669f83f32246e484a8addd0ce93f274996f1941c1f07b 118 | dest: Downloads 119 | # mmtf-cpp 120 | - type: file 121 | url: https://github.com/rcsb/mmtf-cpp/archive/refs/tags/v1.1.0.tar.gz 122 | sha256: 021173bdc1814b1d0541c4426277d39df2b629af53151999b137e015418f76c0 123 | dest: Downloads 124 | # libmsym 125 | - type: file 126 | url: https://github.com/mcodev31/libmsym/archive/85e47232376a8e735c2a7b5283f40b59b3953db1.tar.gz 127 | sha256: 456e2c1e0c78e212115d4d332f557f108b6d41b730d5fd6639c2452df31b7096 128 | dest: Downloads 129 | 130 | post-install: 131 | # Manually copy contents of prefix dir over into main build dir 132 | # -a option is recursive, should preserve permissions and symlinks 133 | - cp -a prefix/bin -t ${FLATPAK_DEST}/ 134 | - cp -a prefix/lib -t ${FLATPAK_DEST}/ 135 | - cp -a prefix/lib64/* -t ${FLATPAK_DEST}/lib/ # Merge with lib 136 | - ln -rs ${FLATPAK_DEST}/lib ${FLATPAK_DEST}/lib64 # Add a symlink so plugins get found 137 | - cp -a prefix/share -t ${FLATPAK_DEST}/ 138 | -------------------------------------------------------------------------------- /.github/workflows/build_windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows Build 2 | # Many thanks to Cristian Adam for examples 3 | # e.g. https://github.com/cristianadam/HelloWorld/blob/master/.github/workflows/build_cmake.yml 4 | # https://cristianadam.eu/20191222/using-github-actions-with-c-plus-plus-and-cmake/ 5 | 6 | # This workflow will build and (optionally) sign releases for Windows 7 | # .. since SignPath requires only a Windows build in the action 8 | # .. to successfully sign 9 | 10 | on: [push, pull_request, workflow_dispatch] 11 | 12 | env: 13 | QT_VERSION: 6.10.0 14 | # this is different from MACOSX_DEPLOYMENT_TARGET to prevent build problems 15 | # we set MACOSX_DEPLOYMENT_TARGET later 16 | FEATURES: -DBUILD_GPL_PLUGINS=ON -DWITH_COORDGEN=OFF -DQT_VERSION=6 -DUSE_3DCONNEXION=OFF -DBUILD_MOLEQUEUE=OFF 17 | 18 | concurrency: 19 | group: ${{ github.workflow }}-${{ github.ref }} 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | build: 24 | name: ${{ matrix.config.name }} 25 | runs-on: ${{ matrix.config.os }} 26 | strategy: 27 | fail-fast: false 28 | matrix: 29 | config: 30 | - { 31 | name: "Windows Qt6", artifact: "Win64.exe", 32 | os: windows-latest, 33 | cc: "cl", cxx: "cl", 34 | build_type: "Release", 35 | cmake_flags: "-DCMAKE_TOOLCHAIN_FILE=/c/vcpkg/scripts/buildsystems/vcpkg.cmake -DUSE_SYSTEM_EIGEN=ON -DUSE_SYSTEM_LIBARCHIVE=ON -DUSE_SYSTEM_LIBXML2=ON -DUSE_SYSTEM_ZLIB=ON", 36 | build_flags: "-j 2", 37 | } 38 | 39 | steps: 40 | - name: Checkout workflow repository 41 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 42 | 43 | - name: Checkout Repositories 44 | uses: ./.github/actions/checkout-repositories 45 | 46 | - name: Install Qt 47 | uses: jurplel/install-qt-action@d325aaf2a8baeeda41ad0b5d39f84a6af9bcf005 # v4.3.0 48 | with: 49 | cache: true 50 | version: ${{ env.QT_VERSION }} 51 | 52 | - name: Configure MSVC Command Prompt 53 | if: runner.os == 'Windows' 54 | uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 55 | with: 56 | arch: x64 57 | 58 | - name: Install Dependencies (Windows) 59 | if: runner.os == 'Windows' 60 | run: | 61 | choco install nsis 62 | cd /c/vcpkg 63 | git pull origin master 64 | vcpkg install libarchive eigen3 libxml2 zlib 65 | shell: bash 66 | 67 | - name: Configure 68 | run: | 69 | if [ ! -d "${{ runner.workspace }}/build" ]; then mkdir "${{ runner.workspace }}/build"; fi 70 | cd "${{ runner.workspace }}/build" 71 | CC=${{matrix.config.cc}} CXX=${{matrix.config.cxx}} cmake $GITHUB_WORKSPACE/openchemistry ${{env.FEATURES}} -DCMAKE_BUILD_TYPE=${{matrix.config.build_type}} ${{matrix.config.cmake_flags}} 72 | shell: bash 73 | 74 | - name: Build 75 | run: | 76 | CC=${{matrix.config.cc}} CXX=${{matrix.config.cxx}} cmake --build . --config ${{matrix.config.build_type}} ${{matrix.config.build_flags}} 77 | shell: bash 78 | working-directory: ${{ runner.workspace }}/build 79 | 80 | - name: Create Windows Packages 81 | if: runner.os == 'Windows' 82 | shell: bash 83 | run: | 84 | gh release download -R prefix-dev/pixi -p "pixi-x86_64-pc-windows-msvc.exe" 85 | # wget https://github.com/prefix-dev/pixi/releases/latest/download/pixi-x86_64-pc-windows-msvc.exe 86 | # move pixi to prefix/bin 87 | mv pixi-x86_64-pc-windows-msvc.exe prefix/bin/pixi.exe 88 | # run windeployqt 89 | windeployqt --release prefix/bin/avogadro2.exe 90 | mv prefix avogadro2 91 | # 7z a Avogadro2-windows.zip avogadro2 92 | cd avogadro2 93 | # create NSIS 94 | /c/Program\ Files\ \(x86\)/NSIS/bin/makensis avogadro2.nsi 95 | if [[ "${GITHUB_REF}" == refs/tags/* ]]; then 96 | # This is a tag - extract version 97 | VERSION="${GITHUB_REF#refs/tags/}" 98 | VERSION="${VERSION#v}" # Remove 'v' prefix if present 99 | else 100 | # This is a nightly build - use current date 101 | VERSION=$(date +%Y-%m-%d) 102 | fi 103 | 104 | mv Avogadro2-Setup.exe ../Avogadro2-${VERSION}.exe 105 | working-directory: ${{ runner.workspace }}/build/ 106 | env: 107 | GH_TOKEN: ${{ github.token }} 108 | 109 | - name: Upload 110 | if: matrix.config.artifact != 0 111 | id: upload-artifact 112 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 113 | with: 114 | path: ${{ runner.workspace }}/build/Avogadro2*.* 115 | name: ${{ matrix.config.artifact }} 116 | 117 | - name: Sign Windows release 118 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/') 119 | uses: signpath/github-action-submit-signing-request@3f9250c56651ff692d6729a2fbb0603a42d7d322 # v2.0 120 | continue-on-error: true 121 | with: 122 | api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' 123 | organization-id: '${{ secrets.SIGNPATH_ORG_ID }}' 124 | project-slug: 'avogadrolibs' 125 | signing-policy-slug: 'release-signing' 126 | github-artifact-id: '${{ steps.upload-artifact.outputs.artifact-id }}' 127 | wait-for-completion: false 128 | output-artifact-directory: '../build/' 129 | 130 | - name: Create MSIX 131 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/') 132 | shell: powershell 133 | run: 134 | # create MSIX 135 | makeappx pack /v /d . /p ../Avogadro2.msix 136 | working-directory: ${{ runner.workspace }}/build/avogadro2 137 | env: 138 | GH_TOKEN: ${{ github.token }} 139 | 140 | - name: Upload MSIX 141 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 142 | with: 143 | path: ${{ runner.workspace }}/build/Avogadro2.msix 144 | name: Avogadro2.msix 145 | 146 | - name: Setup tmate session 147 | if: failure() 148 | uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23 149 | timeout-minutes: 60 150 | -------------------------------------------------------------------------------- /.github/workflows/build_win_arm.yml: -------------------------------------------------------------------------------- 1 | name: Windows ARM Build 2 | # Many thanks to Cristian Adam for examples 3 | # e.g. https://github.com/cristianadam/HelloWorld/blob/master/.github/workflows/build_cmake.yml 4 | # https://cristianadam.eu/20191222/using-github-actions-with-c-plus-plus-and-cmake/ 5 | 6 | # This workflow will build and (optionally) sign releases for Windows 7 | # .. since SignPath requires only a Windows build in the action 8 | # .. to successfully sign 9 | 10 | on: [push, pull_request, workflow_dispatch] 11 | 12 | env: 13 | QT_VERSION: 6.10.0 14 | # this is different from MACOSX_DEPLOYMENT_TARGET to prevent build problems 15 | # we set MACOSX_DEPLOYMENT_TARGET later 16 | FEATURES: -DBUILD_GPL_PLUGINS=ON -DWITH_COORDGEN=OFF -DQT_VERSION=6 -DUSE_3DCONNEXION=OFF -DBUILD_MOLEQUEUE=OFF 17 | 18 | concurrency: 19 | group: ${{ github.workflow }}-${{ github.ref }} 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | build: 24 | name: ${{ matrix.config.name }} 25 | runs-on: ${{ matrix.config.os }} 26 | strategy: 27 | fail-fast: false 28 | matrix: 29 | config: 30 | - { 31 | name: "Windows Qt6 ARM", artifact: "Win-ARM.exe", 32 | os: windows-11-arm, 33 | cc: "cl", cxx: "cl", 34 | build_type: "Release", 35 | cmake_flags: "-DCMAKE_TOOLCHAIN_FILE=/c/vcpkg/scripts/buildsystems/vcpkg.cmake -DUSE_SYSTEM_EIGEN=ON -DUSE_SYSTEM_LIBARCHIVE=ON -DUSE_SYSTEM_LIBXML2=ON -DUSE_SYSTEM_ZLIB=ON", 36 | build_flags: "-j 2", 37 | } 38 | 39 | steps: 40 | - name: Checkout workflow repository 41 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 42 | 43 | - name: Checkout Repositories 44 | uses: ./.github/actions/checkout-repositories 45 | 46 | - name: Install Qt 47 | uses: jurplel/install-qt-action@d325aaf2a8baeeda41ad0b5d39f84a6af9bcf005 # v4.3.0 48 | with: 49 | cache: true 50 | version: ${{ env.QT_VERSION }} 51 | 52 | - name: Configure MSVC Command Prompt 53 | if: runner.os == 'Windows' 54 | uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 55 | with: 56 | arch: arm64 57 | 58 | - name: Install Dependencies (Windows) 59 | if: runner.os == 'Windows' 60 | run: | 61 | choco install nsis 62 | cd /c/vcpkg 63 | git pull origin master 64 | vcpkg install libarchive eigen3 libxml2 zlib 65 | shell: bash 66 | 67 | - name: Configure 68 | run: | 69 | if [ ! -d "${{ runner.workspace }}/build" ]; then mkdir "${{ runner.workspace }}/build"; fi 70 | cd "${{ runner.workspace }}/build" 71 | CC=${{matrix.config.cc}} CXX=${{matrix.config.cxx}} cmake $GITHUB_WORKSPACE/openchemistry ${{env.FEATURES}} -DCMAKE_BUILD_TYPE=${{matrix.config.build_type}} ${{matrix.config.cmake_flags}} 72 | shell: bash 73 | 74 | - name: Build 75 | run: | 76 | CC=${{matrix.config.cc}} CXX=${{matrix.config.cxx}} cmake --build . --config ${{matrix.config.build_type}} ${{matrix.config.build_flags}} 77 | shell: bash 78 | working-directory: ${{ runner.workspace }}/build 79 | 80 | - name: Create Windows Packages 81 | if: runner.os == 'Windows' 82 | shell: bash 83 | run: | 84 | gh release download -R prefix-dev/pixi -p "pixi-aarch64-pc-windows-msvc.exe" 85 | # wget https://github.com/prefix-dev/pixi/releases/latest/download/pixi-aarch64-pc-windows-msvc.exe 86 | # move pixi to prefix/bin 87 | mv pixi-aarch64-pc-windows-msvc.exe prefix/bin/pixi.exe 88 | # run windeployqt 89 | windeployqt --release prefix/bin/avogadro2.exe 90 | mv prefix avogadro2 91 | # 7z a Avogadro2-windows.zip avogadro2 92 | cd avogadro2 93 | # create NSIS 94 | /c/Program\ Files\ \(x86\)/NSIS/bin/makensis avogadro2.nsi 95 | if [[ "${GITHUB_REF}" == refs/tags/* ]]; then 96 | # This is a tag - extract version 97 | VERSION="${GITHUB_REF#refs/tags/}" 98 | VERSION="${VERSION#v}" # Remove 'v' prefix if present 99 | else 100 | # This is a nightly build - use current date 101 | VERSION=$(date +%Y-%m-%d) 102 | fi 103 | 104 | mv Avogadro2-Setup.exe ../Avogadro2-${VERSION}.exe 105 | working-directory: ${{ runner.workspace }}/build/ 106 | env: 107 | GH_TOKEN: ${{ github.token }} 108 | 109 | - name: Upload 110 | if: matrix.config.artifact != 0 111 | id: upload-artifact 112 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 113 | with: 114 | path: ${{ runner.workspace }}/build/Avogadro2*.* 115 | name: ${{ matrix.config.artifact }} 116 | 117 | - name: Sign Windows release 118 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/') 119 | uses: signpath/github-action-submit-signing-request@3f9250c56651ff692d6729a2fbb0603a42d7d322 # v2.0 120 | continue-on-error: true 121 | with: 122 | api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' 123 | organization-id: '${{ secrets.SIGNPATH_ORG_ID }}' 124 | project-slug: 'avogadrolibs' 125 | signing-policy-slug: 'release-signing' 126 | github-artifact-id: '${{ steps.upload-artifact.outputs.artifact-id }}' 127 | wait-for-completion: false 128 | output-artifact-directory: '../build/' 129 | 130 | - name: Create MSIX 131 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/') 132 | shell: powershell 133 | run: 134 | # create MSIX 135 | makeappx pack /v /d . /p ../Avogadro2.msix 136 | working-directory: ${{ runner.workspace }}/build/avogadro2 137 | env: 138 | GH_TOKEN: ${{ github.token }} 139 | 140 | - name: Upload MSIX 141 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 142 | with: 143 | path: ${{ runner.workspace }}/build/Avogadro2.msix 144 | name: Avogadro2.msix 145 | 146 | - name: Setup tmate session 147 | if: failure() 148 | uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23 149 | timeout-minutes: 60 150 | -------------------------------------------------------------------------------- /avogadro/tdxcontroller.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This source file is part of the Avogadro project. 3 | This source code is released under the 3-Clause BSD License, (see "LICENSE"). 4 | ******************************************************************************/ 5 | 6 | #ifdef _3DCONNEXION 7 | #ifndef AVOGADRO_TDXCONTROLLER_H 8 | #define AVOGADRO_TDXCONTROLLER_H 9 | 10 | #include 11 | #include 12 | 13 | #include "mainwindow.h" 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | constexpr uint32_t rayCount = 50; 21 | 22 | class QAction; 23 | 24 | namespace Avogadro { 25 | 26 | namespace Rendering { 27 | class Camera; 28 | class GLRenderer; 29 | } 30 | 31 | namespace QtOpenGL { 32 | class GLWidget; 33 | } 34 | 35 | namespace QtGui { 36 | class Molecule; 37 | class ToolPlugin; 38 | } 39 | 40 | /** 41 | * This class is responsible for handling the TDx navigation in Avogadro2. 42 | */ 43 | class TDxController 44 | : private TDx::SpaceMouse::Navigation3D::CNavigation3D 45 | , public QObject 46 | { 47 | public: 48 | TDxController(MainWindow* const mainWindow, 49 | Avogadro::QtOpenGL::GLWidget* const pGLWidget); 50 | /** 51 | * Enables the TDx navigation. 52 | */ 53 | void enableController(); 54 | 55 | /** 56 | * Disables the TDx navigation. 57 | */ 58 | void disableController(); 59 | 60 | /** 61 | * Exports interface utilities to the TDx wizard. 62 | * @param &actionsMap A map that contains pairs which constists of a string 63 | * and an action list. The string represents a path through UI menus and 64 | * submenus, to reach corresponding actions. Submenus names are expected 65 | * to be separated by '|' char. 66 | */ 67 | void exportCommands(const QMap>& actionsMap); 68 | 69 | void updateMolecule(QtGui::Molecule* const pMolecule); 70 | 71 | private: 72 | struct ActionTreeNode 73 | { 74 | std::string m_nodeName; 75 | std::vector> m_children; 76 | std::vector m_actions; 77 | explicit ActionTreeNode(const std::string& nodeName) 78 | : m_nodeName(nodeName) 79 | { 80 | } 81 | }; 82 | std::shared_ptr m_pRootNode; 83 | QtOpenGL::GLWidget* m_pGLWidget; 84 | Rendering::GLRenderer* m_pGLRenderer; 85 | QtGui::Molecule* m_pMolecule; 86 | navlib::point_t m_eyePosition; 87 | navlib::vector_t m_lookDirection; 88 | QImage m_pivotImage; 89 | #ifdef WIN32 90 | std::vector m_utilityIcons; 91 | #endif 92 | double m_hitTestRadius; 93 | std::array m_rayOrigins; 94 | std::error_code errorCode; 95 | 96 | /** 97 | * Adds a actions list to the action tree. 98 | * @param &path describes the recursive traversal through tree nodes 99 | * to the destination node. Nodes that does not exist will be created. 100 | * @param &pNode traversal starting point 101 | * @param &actions action list to add to the tree node 102 | */ 103 | void addActions(const std::string& path, 104 | const std::shared_ptr& pNode, 105 | const QList& actions); 106 | 107 | /** 108 | * Returns CCategory hierarchy which reflects the actions tree. 109 | * Created CCommand's ID's are encoded paths to the actions in the tree. 110 | * @param &pNode root of the action tree 111 | */ 112 | TDx::SpaceMouse::CCategory getCategory( 113 | const std::string& pathCode, const std::shared_ptr& pNode); 114 | 115 | /** 116 | * Recursively decodes a path from provided code and returns a QAction pointer 117 | * that has been reached in the actions tree. If the code is invalid, then 118 | * nullptr is returned. 119 | * @param &pathCode encoded path to the action in the actions tree 120 | * @param &pNode node from which the decoding begins 121 | */ 122 | QAction* decodeAction(const std::string& pathCode, 123 | const std::shared_ptr& pNode) const; 124 | 125 | // Inherited via CNavigation3D 126 | // Getters 127 | 128 | virtual long GetCameraMatrix(navlib::matrix_t& matrix) const override; 129 | virtual long GetPointerPosition(navlib::point_t& position) const override; 130 | virtual long GetViewExtents(navlib::box_t& extents) const override; 131 | virtual long GetViewFOV(double& fov) const override; 132 | virtual long GetViewFrustum(navlib::frustum_t& frustum) const override; 133 | virtual long GetIsViewPerspective(navlib::bool_t& perspective) const override; 134 | virtual long GetModelExtents(navlib::box_t& extents) const override; 135 | virtual long GetSelectionExtents(navlib::box_t& extents) const override; 136 | virtual long GetSelectionTransform( 137 | navlib::matrix_t& transform) const override; 138 | virtual long GetIsSelectionEmpty(navlib::bool_t& empty) const override; 139 | virtual long GetPivotPosition(navlib::point_t& position) const override; 140 | virtual long GetPivotVisible(navlib::bool_t& visible) const override; 141 | virtual long GetHitLookAt(navlib::point_t& position) const override; 142 | 143 | // Setters 144 | 145 | virtual long SetCameraMatrix(const navlib::matrix_t& matrix) override; 146 | virtual long SetViewExtents(const navlib::box_t& extents) override; 147 | virtual long SetViewFOV(double fov) override; 148 | virtual long SetViewFrustum(const navlib::frustum_t& frustum) override; 149 | virtual long SetSelectionTransform(const navlib::matrix_t& matrix) override; 150 | virtual long IsUserPivot(navlib::bool_t& userPivot) const override; 151 | virtual long SetPivotPosition(const navlib::point_t& position) override; 152 | virtual long SetPivotVisible(bool visible) override; 153 | virtual long SetHitAperture(double aperture) override; 154 | virtual long SetHitDirection(const navlib::vector_t& direction) override; 155 | virtual long SetHitLookFrom(const navlib::point_t& eye) override; 156 | virtual long SetHitSelectionOnly(bool onlySelection) override; 157 | virtual long SetActiveCommand(std::string commandId) override; 158 | virtual long SetTransaction(long value) override; 159 | }; 160 | } 161 | 162 | #endif // ! AVOGADRO_TDXCONTROLLER_H 163 | #endif // _3DCONNEXION -------------------------------------------------------------------------------- /thirdparty/3DConnexion/inc/SpaceMouse/IView.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IView_HPP_INCLUDED 2 | #define IView_HPP_INCLUDED 3 | // 4 | // ------------------------------------------------------------------------------------------------ 5 | // This source file is part of the Avogadro project. 6 | // 7 | // Copyright (c) 2014-2023 3Dconnexion. 8 | // 9 | // This source code is released under the 3-Clause BSD License, (see "LICENSE"). 10 | // ------------------------------------------------------------------------------------------------ 11 | // 12 | // 13 | // ************************************************************************************************ 14 | // File History 15 | // 16 | // $Id: IView.hpp 16047 2019-04-05 12:51:24Z mbonk $ 17 | // 18 | // 19 | #include 20 | 21 | namespace TDx { 22 | namespace SpaceMouse { 23 | namespace Navigation3D { 24 | /// 25 | /// View callback interface. 26 | /// 27 | class IView { 28 | public: 29 | #if !defined(_MSC_VER) || (_MSC_VER > 1700) 30 | virtual ~IView() = default; 31 | #else 32 | virtual ~IView() = 0 { 33 | } 34 | #endif 35 | 36 | /// 37 | /// Gets the camera matrix of the view. 38 | /// 39 | /// The camera/view . 40 | /// 0 = no error, otherwise <0. 41 | virtual long GetCameraMatrix(navlib::matrix_t &matrix) const = 0; 42 | 43 | /// 44 | /// Gets the camera's target point. 45 | /// 46 | /// The position of the camera target in world coordinates. 47 | /// 0 = no error, otherwise <0. 48 | /// Free cameras do not have a target. 49 | virtual long GetCameraTarget(navlib::point_t &target) const = 0; 50 | 51 | /// 52 | /// Gets the position of the pointer on the near clipping plane. 53 | /// 54 | /// The in world coordinates of the 55 | /// pointer. 0 = no error, otherwise <0. 56 | virtual long GetPointerPosition(navlib::point_t &position) const = 0; 57 | 58 | /// 59 | /// Gets the view's construction plane. 60 | /// 61 | /// The plane equation of the construction plane. 62 | /// 0 = no error, otherwise <0. 63 | virtual long GetViewConstructionPlane(navlib::plane_t &plane) const = 0; 64 | 65 | /// 66 | /// Gets the extents of the view. 67 | /// 68 | /// A representing the extents of the 69 | /// view. 70 | /// 0 = no error, otherwise <0. 71 | virtual long GetViewExtents(navlib::box_t &extents) const = 0; 72 | 73 | /// 74 | /// Gets the camera's/view's distance to the focused object. 75 | /// 76 | /// The distance in world units. 77 | /// 0 = no error, otherwise <0. 78 | virtual long GetViewFocusDistance(double &distance) const = 0; 79 | 80 | /// 81 | /// Gets the camera's/view's field of view. 82 | /// 83 | /// The field of view in radians. 84 | /// 0 = no error, otherwise <0. 85 | virtual long GetViewFOV(double &fov) const = 0; 86 | 87 | /// 88 | /// Gets the camera/view frustum. 89 | /// 90 | /// The camera/view . 91 | /// 0 = no error, otherwise <0. 92 | virtual long GetViewFrustum(navlib::frustum_t &frustum) const = 0; 93 | 94 | /// 95 | /// Get's the view's projection type 96 | /// 97 | /// true for a perspective view, false for an orthographic view. 98 | /// 0 = no error, otherwise <0. 99 | virtual long GetIsViewPerspective(navlib::bool_t &perspective) const = 0; 100 | 101 | /// 102 | /// Gets a value indicating whether the view can be rotated. 103 | /// 104 | /// true if the view can be rotated, false otherwise. 105 | /// 0 = no error, otherwise <0. 106 | virtual long GetIsViewRotatable(navlib::bool_t &isRotatable) const = 0; 107 | 108 | /// 109 | /// Sets the camera affine matrix. 110 | /// 111 | /// The camera/view . 112 | /// 0 = no error, otherwise <0. 113 | virtual long SetCameraMatrix(const navlib::matrix_t& matrix) = 0; 114 | 115 | /// 116 | /// Sets the camera's target position. 117 | /// 118 | /// The position of the camera target in world coordinates. 119 | /// 0 = no error, otherwise <0. 120 | /// Free cameras do not have a target. 121 | virtual long SetCameraTarget(const navlib::point_t &target) = 0; 122 | 123 | /// 124 | /// Sets the position of the pointer on the near clipping plane. 125 | /// 126 | /// The in world coordinates of the 127 | /// pointer. 128 | /// 0 = no error, otherwise <0. 129 | virtual long SetPointerPosition(const navlib::point_t& position) = 0; 130 | 131 | /// 132 | /// Sets the extents of the view. 133 | /// 134 | /// A representing the extents of the 135 | /// view. 136 | /// 0 = no error, otherwise <0. 137 | virtual long SetViewExtents(const navlib::box_t& extents) = 0; 138 | 139 | /// 140 | /// Sets the camera's/view's field of view. 141 | /// 142 | /// The field of view in radians. 143 | /// 0 = no error, otherwise <0. 144 | virtual long SetViewFOV(double fov) = 0; 145 | 146 | /// 147 | /// Sets the camera/view frustum. 148 | /// 149 | /// The camera/view . 150 | /// 0 = no error, otherwise <0. 151 | virtual long SetViewFrustum(const navlib::frustum_t& frustum) = 0; 152 | }; 153 | } // namespace Navigation3D 154 | } // namespace SpaceMouse 155 | } // namespace TDx 156 | #endif // IView_HPP_INCLUDED 157 | -------------------------------------------------------------------------------- /.github/workflows/build_linux.yml: -------------------------------------------------------------------------------- 1 | name: Linux Build Matrix 2 | # Many thanks to Cristian Adam for examples 3 | # e.g. https://github.com/cristianadam/HelloWorld/blob/master/.github/workflows/build_cmake.yml 4 | # https://cristianadam.eu/20191222/using-github-actions-with-c-plus-plus-and-cmake/ 5 | 6 | on: [push, pull_request, workflow_dispatch] 7 | 8 | env: 9 | QT_VERSION: 6.8.3 10 | FEATURES: -DBUILD_GPL_PLUGINS=ON -DBUILD_MOLEQUEUE=OFF -DWITH_COORDGEN=OFF -DQT_VERSION=6 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.ref }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | build: 18 | name: ${{ matrix.config.name }} 19 | runs-on: ${{ matrix.config.os }} 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | config: 24 | - { 25 | name: "Ubuntu x86", artifact: "", 26 | os: ubuntu-latest, 27 | cc: "gcc", cxx: "g++", 28 | build_type: "Release", 29 | cmake_flags: "-G Ninja -DUSE_SYSTEM_EIGEN=TRUE", 30 | } 31 | - { 32 | name: "AppImage x86", artifact: "Avogadro2-x86_64.AppImage", 33 | os: ubuntu-22.04, 34 | cc: "gcc", cxx: "g++", 35 | build_type: "Release", 36 | cmake_flags: "-G Ninja -DUSE_SYSTEM_EIGEN=TRUE -DINSTALL_BUNDLE_FILES=ON -DUSE_YAEHMOP=ON", 37 | } 38 | - { 39 | name: "Ubuntu Address Sanitizer", artifact: "", 40 | os: ubuntu-latest, 41 | cc: "gcc", cxx: "g++", 42 | build_type: "asan", 43 | cmake_flags: "-G Ninja -DUSE_SYSTEM_EIGEN=TRUE -DENABLE_TESTING=ON -DTEST_QTGL=OFF -USE_SYSTEM_ZLIB=ON", 44 | } 45 | - { 46 | name: "Ubuntu Undefined Behavior Sanitizer", artifact: "", 47 | os: ubuntu-latest, 48 | cc: "gcc", cxx: "g++", 49 | build_type: "ubsan", 50 | cmake_flags: "-G Ninja -DUSE_SYSTEM_EIGEN=TRUE -DENABLE_TESTING=ON -DTEST_QTGL=OFF -USE_SYSTEM_ZLIB=ON", 51 | } 52 | - { 53 | name: "Ubuntu Leak Sanitizer", artifact: "", 54 | os: ubuntu-latest, 55 | cc: "gcc", cxx: "g++", 56 | build_type: "lsan", 57 | cmake_flags: "-G Ninja -DUSE_SYSTEM_EIGEN=TRUE -DENABLE_TESTING=ON -DTEST_QTGL=OFF -USE_SYSTEM_ZLIB=ON", 58 | } 59 | - { 60 | name: "Ubuntu Thread Sanitizer", artifact: "", 61 | os: ubuntu-latest, 62 | cc: "gcc", cxx: "g++", 63 | build_type: "tsan", 64 | cmake_flags: "-G Ninja -DUSE_SYSTEM_EIGEN=TRUE -DENABLE_TESTING=ON -DTEST_QTGL=OFF -USE_SYSTEM_ZLIB=ON", 65 | } 66 | 67 | steps: 68 | - name: Checkout workflow repository 69 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 70 | 71 | - name: Checkout Repositories 72 | uses: ./.github/actions/checkout-repositories 73 | 74 | - name: Install Dependencies 75 | run: | 76 | sudo apt-get -qq update 77 | sudo apt-get -qq install ninja-build libeigen3-dev libboost-all-dev libglew-dev libxml2-dev 78 | sudo apt-get -qq install libfuse2 79 | 80 | - name: Install Qt 81 | uses: jurplel/install-qt-action@d325aaf2a8baeeda41ad0b5d39f84a6af9bcf005 # v4.3.0 82 | with: 83 | cache: true 84 | version: ${{ env.QT_VERSION }} 85 | 86 | - name: Configure 87 | run: | 88 | if [ ! -d "${{ runner.workspace }}/build" ]; then mkdir "${{ runner.workspace }}/build"; fi 89 | cd "${{ runner.workspace }}/build" 90 | CC=${{matrix.config.cc}} CXX=${{matrix.config.cxx}} cmake $GITHUB_WORKSPACE/openchemistry ${{env.FEATURES}} -DCMAKE_BUILD_TYPE=${{matrix.config.build_type}} ${{matrix.config.cmake_flags}} 91 | shell: bash 92 | 93 | - name: Build 94 | run: | 95 | CC=${{matrix.config.cc}} CXX=${{matrix.config.cxx}} cmake --build . --config ${{matrix.config.build_type}} ${{matrix.config.build_flags}} 96 | shell: bash 97 | working-directory: ${{ runner.workspace }}/build 98 | 99 | - name: Run tests 100 | if: (matrix.config.build_type != 'Release') 101 | shell: cmake -P {0} 102 | run: | 103 | include(ProcessorCount) 104 | ProcessorCount(N) 105 | set(ENV{CTEST_OUTPUT_ON_FAILURE} "ON") 106 | set(ENV{ASAN_OPTIONS} "new_delete_type_mismatch=0") 107 | execute_process( 108 | COMMAND ctest -j ${N} 109 | WORKING_DIRECTORY ${{ runner.workspace }}/build/avogadrolibs 110 | RESULT_VARIABLE result 111 | ) 112 | if (NOT result EQUAL 0) 113 | message(FATAL_ERROR "Running tests failed!") 114 | endif() 115 | 116 | - name: Package AppImage 117 | if: matrix.config.name == 'AppImage x86' 118 | shell: bash 119 | run: | 120 | mkdir appdir 121 | mv prefix appdir/usr 122 | 123 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:appdir/usr/lib 124 | 125 | wget -c -nv "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" 126 | wget -c -nv "https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage" 127 | wget -c -nv "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" 128 | chmod a+x *.AppImage 129 | 130 | # get pixi 131 | # wget -c -nv "https://github.com/prefix-dev/pixi/releases/latest/download/pixi-x86_64-unknown-linux-musl" 132 | # mv pixi-x86_64-unknown-linux-musl appdir/usr/bin/pixi 133 | 134 | # Though it is not great security practice, bundle libssl and libcrypto 135 | ./linuxdeploy-x86_64.AppImage -d appdir/usr/share/applications/*.desktop --plugin qt --library /lib/x86_64-linux-gnu/libssl.so.3 --library /lib/x86_64-linux-gnu/libcrypto.so.3 --appdir appdir 136 | # add the custom AppRun 137 | rm appdir/AppRun 138 | cp ../${{ github.event.repository.name }}/openchemistry/avogadrolibs/scripts/AppImage.sh appdir/AppRun 139 | chmod a+x appdir/AppRun 140 | ./appimagetool-x86_64.AppImage appdir 141 | mv Avogadro*.AppImage avogadroapp/Avogadro2-x86_64.AppImage # for upload 142 | working-directory: ${{ runner.workspace }}/build 143 | 144 | - name: Upload 145 | if: matrix.config.artifact != 0 146 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 147 | with: 148 | path: ${{ runner.workspace }}/build/avogadroapp/Avogadro2*.* 149 | name: ${{ matrix.config.artifact }} 150 | 151 | - name: Setup tmate session 152 | if: ${{ failure() }} 153 | uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23 154 | timeout-minutes: 60 155 | --------------------------------------------------------------------------------