Compare commits

...

69 Commits

Author SHA1 Message Date
pre-commit-ci[bot] 4b2296936c [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-03-16 20:36:26 +00:00
pre-commit-ci[bot] 56530cd309 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/psf/black-pre-commit-mirror: 2892f1f81088477370d4fbc56545c05d33d2493f → fa505ab9c3e0fedafe1709fd7ac2b5f8996c670d](https://github.com/psf/black-pre-commit-mirror/compare/2892f1f81088477370d4fbc56545c05d33d2493f...fa505ab9c3e0fedafe1709fd7ac2b5f8996c670d)
- [github.com/pre-commit/mirrors-clang-format: 317810f3c6a0ad3572367dc86cb6e41863e16e08 → 88c364bab316f4b6b18f6c298133bbbf32d7cd15](https://github.com/pre-commit/mirrors-clang-format/compare/317810f3c6a0ad3572367dc86cb6e41863e16e08...88c364bab316f4b6b18f6c298133bbbf32d7cd15)
2026-03-16 20:31:17 +00:00
marioalexis 601bcd5e3d App: Fix separator path in safe mode 2026-03-16 21:03:28 +01:00
PaddleStroke dcb380e1ca Sketcher: Text position OVP fix 2026-03-16 19:15:09 +01:00
Alfredo Monclus cfe641fb7d Gui: improve quantitySpinbox / Sketcher OVP (#25978)
* Gui: fix quantity spinbox size not adapting to number of decimals

* Gui: fix quantity spinbox units getting cut (force max chars)

* Gui: editableDatumLabel remove hardcoded values

* fixes

* Gui: sketcher ovp auto adjust size

* Gui: ovp fix cursor jumping behind the unit

* Gui: Refactor changes to QuantitySpinBox

The QuantitySpinBox uses d-pointer (pimpl) to store its private data -
this commit ensures that all state is stored here and exposed via
getters and setters + qproperties.

* Gui: sketcher ovp fix cursor jumping after the unit

* Gui: allow quantitySpinBox to set max digits allowed

Useful for adjustable width in the Sketcher OVP

---------

Co-authored-by: Kacper Donat <kadet1090@gmail.com>
2026-03-16 18:41:00 +01:00
PaddleStroke d384c9d8cb Link : Fix transparent face regression 2026-03-16 18:32:36 +01:00
PaddleStroke 3620b68b21 Assembly: Command: Select joints of component (#27530)
* Assembly: Command: Select joints of component https://github.com/FreeCAD/FreeCAD/issues/23721

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update src/Mod/Assembly/Gui/Commands.cpp

Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
2026-03-16 18:25:05 +01:00
tarman3 20e70f84e1 CAM: ToolController - Default RampFeed after migration (#27191) 2026-03-16 13:10:34 -04:00
Nishendra Singh e28b1ce1ad techdraw: added supplementary angle display 2026-03-16 18:07:32 +01:00
Alfredo Monclus c8efc26982 PartDesign: fix the range of the custom clearance of threads (#26296)
* PartDesign: fix the range of the custom clearance of threads

* PartDesign: hole ensure diameter is on the correct range
2026-03-16 18:02:31 +01:00
Loke Strøm 9abe7b4af1 Sketcher: Fix: Arc of Hyperbola (#27656)
* Sketcher: Fix: Arc of Hyperbola

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Added minor grater than major radius support

* Fixed merge errors

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Improved comments and added a confused points check for S1 and S2 distance.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Added compile check for occ version and check before getting minor radius.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Apply suggestions from code review

OCC version check

Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
2026-03-16 17:49:34 +01:00
Timothy Miller 27f077c62b Part: Fix AttacherEngine property not synced with AttacherType (#15716)
When Part2DObject (e.g., Sketch) is created, it calls setAttacher() to
set up AttachEnginePlane. This updated the internal AttacherType property
but left the user-visible AttacherEngine enum at its default "Engine 3D".

Now setAttacher() also updates AttacherEngine for non-base attachers,
keeping the visible property in sync with the actual engine type.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-16 17:42:36 +01:00
PaddleStroke eabd052c17 Core: Fix freecad when windows path has non ASCII characters (#28222)
* Core: Fix freecad when Windows username has non ASCII characters

* Update ApplicationDirectories.cpp

* Tests: Add tests of pathToString/stringToPath

Validates the fix for non-ASCII characters in filesystem paths (e.g.
Windows usernames with umlauts). Includes Windows-specific tests that
verify pathToString produces UTF-8 from wide-string paths and that
the naive fs::path::string() does not. On Linux these functions are
effectively a no-op, so the tests themselves are only really useful
on Windows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 17:37:43 +01:00
freecad-gh-actions-translation-bot 706b01f607 Update translations from Crowdin 2026-03-16 17:31:49 +01:00
dependabot[bot] 8a2f665430 Bump github/issue-metrics from 4.1.0 to 4.1.1
Bumps [github/issue-metrics](https://github.com/github/issue-metrics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/github/issue-metrics/releases)
- [Commits](https://github.com/github/issue-metrics/compare/41a7961f701cc64490f32e143af8ef479b93e87d...6a35322ff89cee3e1a594d282c27eb34bffa9174)

---
updated-dependencies:
- dependency-name: github/issue-metrics
  dependency-version: 4.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-16 14:05:28 +01:00
sliptonic 9fe630e0c3 Merge pull request #23093 from Connor9220/UpdateCircularHoleBaseGUI
CAM: Circular Hole Improvements - GUI sorting enhancements, and migration fixes
2026-03-15 15:02:28 -05:00
Ladislav Michl 91f015b132 Gui: {get,set}Camera expects utf-8 encoding
Python interface to the setCamera() is using 's' format string, which
converts Unicode object to C string using 'utf-8' encoding. Reflect
that for QString conversion as well.
2026-03-15 20:38:42 +01:00
sliptonic 6d8b98d471 block delete logic 2026-03-14 11:19:14 -04:00
tarman3 03f506c5a5 fix onDocumentRestored 2026-03-14 11:18:54 -04:00
Turan Furkan Topak d90c88f0fc make polar and circular arrays aware of the active working plane (#28324) 2026-03-14 13:18:00 +01:00
Bojan Pejic df8c6b5db9 BIM: fix zero level height warning dialog (#28065)
* BIM: fix zero level height warning dialog
2026-03-14 11:48:49 +00:00
Yash Suthar 5455306a4a Draft: fix angular mode extension lines creation (#27987)
* Draft: fix angular mode extension lines creation

Signed-off-by: Yash Suthar <yashsuthar983@gmail.com>

* Draft: update the agularDimension extlines svg representation

Signed-off-by: Yash Suthar <yashsuthar983@gmail.com>

---------

Signed-off-by: Yash Suthar <yashsuthar983@gmail.com>
2026-03-14 12:34:58 +01:00
Furgo d1476c819c BIM: refactor link processing, add BIM_Link wrapper command (#28104)
* BIM: refactor, introduce link properties override helper

* BIM: add Link support to Arch_Add, Arch_Remove

Fixes: https://github.com/FreeCAD/FreeCAD/issues/26255
Fixes: https://github.com/FreeCAD/FreeCAD/issues/28139

Co-authored-by: Roy-043 <70520633+Roy-043@users.noreply.github.com>

* BIM: add link command wrapper

* BIM: add link addition and removal tests

---------

Co-authored-by: Roy-043 <70520633+Roy-043@users.noreply.github.com>
2026-03-14 12:22:02 +01:00
Billy Huddleston 88a74cfa3a Fix Drag'n drop for QT6.10
Fix Merge conflicts
2026-03-13 18:09:12 -04:00
Billy Huddleston 5e818e961c CAM: Remove "Automatic TSP" mode and improve natural sorting
CAM: CircularHoleBase - Fix onDocumentRestored

Removed the expermental "Automatic TSP" sorting mode and ensured legacy
files are migrated to "Automatic". Start using C++ TSP sorting for
"Automatic" mode for better performance. Refactored natural sorting for
table columns, relocating the utility class for reuse and using a robust
sort key.

src/Mod/CAM/Path/Op/CircularHoleBase.py:
- Removed "Automatic TSP" from SortingMode options and logic
- Added migration logic for legacy "Automatic TSP" values
- Cleaned up redundant assignments

src/Mod/CAM/Path/Op/Gui/CircularHoleBase.py:
- Updated to use relocated NaturalSortTableWidgetItem for feature and
diameter columns
- Improved sorting behavior for mixed text/number columns

src/Mod/CAM/Path/Base/Gui/Util.py:
- Added NaturalSortTableWidgetItem using the existing natural_sort_key
for robust sorting
2026-03-13 15:57:13 -04:00
Billy Huddleston fdef6c35e7 GUI sorting enhancements, and migration fixes
This update enhances the GUI with new sorting modes and manual reordering, and
adds migration logic to ensure robust property

src/Mod/CAM/Gui/Resources/panels/PageBaseHoleGeometryEdit.ui:
- Add Sorting mode combo box with "Automatic", "Automatic TSP", and "Manual" options
- Add UI improvements for hole sorting, selection, and filtering

src/Mod/CAM/Path/Op/CircularHoleBase.py:
- Add migration logic to ensure SortingMode property exists and is up to date
- Use sort_locations_tsp when SortingMode is "Automatic TSP"

src/Mod/CAM/Path/Op/Gui/CircularHoleBase.py:
- Add RowMoveTableWidget for manual row reordering in the GUI
- Update TaskPanelHoleGeometryPage to support new sorting modes and improved UI behavior
2026-03-13 15:56:14 -04:00
Chris Hennes 4ac848aab0 Merge pull request #26031 from pjcreath/split-sketchobject
Split monolithic SketchObject.cpp
2026-03-13 14:37:49 -05:00
sliptonic e1fdc27e7c Merge pull request #28321 from davidgilkaufman/roadmap_clipper
[CAM] Clipper upgrade roadmap epic
2026-03-13 13:35:07 -05:00
sliptonic 0caccde398 Merge pull request #25667 from tarman3/boundary_threshold
CAM: DressupBoundary - RetractThreshold
2026-03-13 12:52:59 -05:00
sliptonic 244dffcfb7 Merge pull request #27514 from tarman3/holes_diameter
CAM: CircularHoleBase - Fix holeDiameter() for face
2026-03-13 12:45:43 -05:00
David Kaufman 5328e74e3d link FPA grant proposal 2026-03-13 13:27:54 -04:00
sliptonic 3c48b4a950 CAM: Machine-based postprocessing (#27507)
CAM: Add template dropdown below machine name in editor

Adds a template selection dropdown to the Machine Editor dialog,
positioned below the machine name field. Dropdown lists user and
built-in templates for new machines only. Adds MachineFactory
template discovery and ensures templates are copied to build directory.

src/Mod/CAM/CMakeLists.txt:
- Copy machine templates to build directory for runtime access

src/Mod/CAM/Machine/models/machine.py:
- Add MachineFactory.list_builtin_templates() for template discovery
- Use FreeCAD install path for built-in templates

src/Mod/CAM/Machine/ui/editor/machine_editor.py:
- Add template dropdown below name field for new machines
- Populate dropdown with user and built-in templates
- Update UI fields when template is selected

Major improvements to the GenericPlasma postprocessor with new dialog-based
mode selection and robust plasma cutting features.

New Features:
- Add pre_processing_dialog() for interactive mode selection
- Replace persistent mark_entry_only property with runtime dialog
- User-friendly choice between Normal Cutting and Mark Entry Points Only
- Enhanced torch control with pierce height movement
- Complete mark_entry_only implementation with proper marking sequence
- Improved error handling and state management

Technical Improvements:
- Add _reset_plasma_state() for clean per-operation tracking
- Fix Z direction detection with proper null checking
- Enhanced height extraction from StartDepth/FinalDepth/ClearanceHeight
- Better error handling with debug logging
- Graceful fallback when GUI not available

Bug Fixes:
- Fix torch control to move to pierce height before ignition
- Fix force_rapid_feeds to remove F parameters (revert from override)
- Fix state tracking initialization and null value handling
- Add proper state reset for each operationUses a dialog to set mark_only.

Co-authored-by: tarman3 <joice501790018@tutamail.com>
2026-03-13 13:18:45 -04:00
sliptonic a78c31be69 Merge pull request #28274 from Connor9220/FixToolbitSubClass
CAM: Fix saving of _shape_type for toolbits
2026-03-13 12:11:19 -05:00
sliptonic c2495411b7 Merge pull request #28173 from tarman3/linking_opti
CAM: Linking - Minor optimization for simple solid
2026-03-13 12:01:50 -05:00
sliptonic 1a8e2fb333 Merge pull request #28172 from tarman3/maneuver_toCommand
CAM: Maneuver - Move instruction_to_command() to class
2026-03-13 12:00:07 -05:00
sliptonic 73c3c78474 Merge pull request #28167 from tarman3/machinestate
CAM: MachineState - Allow process list of commands
2026-03-13 11:57:49 -05:00
sliptonic 509c881ea0 Merge pull request #28140 from tarman3/linking_tolerance
CAM: Linking - Tolerance in get_linking_moves()
2026-03-13 11:55:08 -05:00
David Kaufman d690dcb1d3 Clipper upgrade roadmap 2026-03-13 11:47:33 -04:00
dependabot[bot] 493829b376 Bump actions/download-artifact from 8.0.0 to 8.0.1
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 8.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-12 21:46:11 -05:00
pre-commit-ci[bot] 0819d776d7 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-03-12 20:25:01 +00:00
pjcreath 79aca8950f Sketch: [5/5] Fix up files after splitting SketchObject.cpp
Remove stale includes and make other adjustments for compilation.
2026-03-12 16:17:08 -04:00
pjcreath 8efe9964e7 Sketch: [4/5] Move code from SketchObject.cpp to SketchObjectExternal.cpp.
This is a purely mechanical reorganization with no functional changes.
Use "git blame -C --minimal" to trace line origins prior to this commit.
2026-03-12 16:17:08 -04:00
pjcreath eda87a7efe Sketch: [3/5] Move code from SketchObject.cpp to SketchObjectGeometry.cpp.
This is a purely mechanical reorganization with no functional changes.
Use "git blame -C --minimal" to trace line origins prior to this commit.
2026-03-12 16:17:08 -04:00
pjcreath e1815f10ff Sketch: [2/5] Move code from SketchObject.cpp to SketchObjectConstraints.cpp.
This is a purely mechanical reorganization with no functional changes.
Use "git blame -C --minimal" to trace line origins prior to this commit.
2026-03-12 16:17:08 -04:00
pjcreath 7d39a9d59a Sketch: [1/5] Move code from SketchObject.cpp to SketchObjectOperations.cpp.
This is a purely mechanical reorganization with no functional changes.
Use "git blame -C --minimal" to trace line origins prior to this commit.
2026-03-12 16:17:08 -04:00
wmayer baa47bd606 Sketch: Refactor SketchObject::getPoint
Add the helper class SketchGeometryType and the interface SketchGeometry with the needed sub-classes to
remove the cascaded if-else construct
2026-03-12 16:17:08 -04:00
wmayer 51b37da53e Sketch: Fix crash when moving sketch with hidden constraints
Clicking the eye icon on the constraints panel hides all constraints. This calls SketchObject::setVirtualSpace where the existing Constraint
objects will be replaced. However, the Constraint objects are also stored inside the member 'solvedSketch' but won't be replaced so that the
pointers there will become dangling.

If the user starts to drag the sketch the pointers are still dangling and cause a crash when calling 'solvedSketch.moveGeometries'.

The crash can be reproduced with:
1. Create a sketch
2. Add a single line
3. Set a length constraint
4. Make it a non-driving constraint
5. Hide it with the eye icon or by unticking the check box
6. Move the line

The same crash also occurs when calling the methods setLabelDistance() or setLabelPosition() from Python and then trying to move the sketch.

Solution:

To fix the problem add the lightweight method 'Sketch::updateConstraints' and call it inside SketchObject::setVirtualSpace to quickly update
the pointers after invalidating them.

This fixes issue 19566
2026-03-12 16:17:08 -04:00
André Lopes 8ce3c4a1cc Fix #24079: clarify TechDraw Scale tooltip (#28293) 2026-03-12 18:12:02 +00:00
Roy-043 037ce3bffd BIM: update tooltips in BIM Setup to match current prefs
Related to #25004

Updated the tooltips to point to correct pref pages.

Additionally:
* Minor text tweaks.
* Replaced "Gui::PrefColorButton" with "Gui::ColorButton".
2026-03-12 18:28:48 +01:00
Roy-043 b9306c6f63 BIM: fix BuildingPart color issues including v1.0 regressions (#28001)
* BIM: fix BuildingPart color issues including v1.0 regressions

Fixes #27136.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-03-12 14:39:24 +00:00
tarman3 7b2b972efa CAM: MachineState - Allow process list of commands 2026-03-12 10:28:31 +02:00
filippor 6d66721582 fix CAM missing python file in cmake 2026-03-11 22:03:23 -04:00
Billy Huddleston 448235cd2b CAM: Fix saving of _shape_type for toolbits
Corrects logic so that the _shape_type is saved properly and not always
defaulted to the primary toolbit type. Ensures subclass/alias
information is preserved when saving toolbits.

src/Mod/CAM/Path/Tool/toolbit/models/base.py:
- Fix fallback logic for _shape_type to correctly save subclass/alias
when present
- Only default to primary type if _shape_type is missing or matches the
main class

src/Mod/CAM/Path/Tool/docobject/ui/docobject.py:
- Improve label formatting by handling underscores, hyphens, and extra
spaces

src/Mod/CAM/Path/Tool/toolbit/ui/typefilter.py:
- Simplify type filter mapping and display logic for toolbit subtypes
2026-03-11 21:58:32 -04:00
Bojan a729bb4bc1 Material: add transaction support to Std_SetMaterial task 2026-03-11 20:00:39 -05:00
Chris Hennes 03fc08d02e Revert "[Weekly Build] Update IfcOpenShell to 0.8.4"
This reverts commit 5e7bbe15e3.
2026-03-11 08:18:44 +01:00
WandererFan e44c1ce75a TechDraw: Allow 3d dimension references to use point objects (#28199)
* [TD]fix 3d point object reference in dimension

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-03-11 06:08:35 +01:00
marioalexis 4083c7c616 Fem: Add name to examples dock widget 2026-03-11 06:05:07 +01:00
PaddleStroke 76a84f63ab Sketcher: Dimension tool: don't update distance type based on position for horizontal/vert 2026-03-11 05:36:10 +01:00
WandererFan 065315d7a4 TechDraw: fix crash in area dim for face with nested voids (#28097) 2026-03-10 22:57:59 -05:00
PaddleStroke 451072f0d7 Sketcher : arc with symmetric + 2 coincidence fix (#28120) 2026-03-10 22:13:02 -05:00
Roy-043 0b232ac1ff Draft: Avoid import of whole Draft module (#25386) 2026-03-10 21:59:36 -05:00
Grzegorz Kwacz 737cab44f2 Gui/View: Move (get|set)Camera to methods (#27801) 2026-03-10 21:57:34 -05:00
tarman3 1182be91bc CAM: Maneuver - Move instruction_to_command() to class 2026-03-10 15:52:35 +02:00
tarman3 e561950ff8 CAM: Linking - Minor optimization for simple solid 2026-03-10 09:06:14 +02:00
tarman3 bf98221885 CAM: Linking - Tolerance in get_linking_moves() 2026-03-10 06:52:28 +02:00
tarman3 f7939beee0 CAM: Linking - Tolerance in get_linking_moves() 2026-03-08 21:30:24 +02:00
tarman3 0702616895 CAM: BoundaryDressup - RetractThreshold 2026-03-08 12:47:43 +02:00
tarman3 eb0d7ba6a5 CAM: CircularHoleBase.holeDiameter() - Remove useless obj 2026-02-27 20:43:56 +02:00
tarman3 eaf76e4d0a CAM: CircularHoleBase.holeDiameter() - Fix face 2026-02-27 20:41:07 +02:00
808 changed files with 68454 additions and 51946 deletions
+1
View File
@@ -16,6 +16,7 @@ If FREECAD_EXEC is an executable path, it is used directly.
This script returns 0 if all GUI modules run successfully. Otherwise it returns the last non-zero
exit code.
"""
from __future__ import annotations
import sys
import subprocess
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
- name: Run issue-metrics tool
uses: github/issue-metrics@41a7961f701cc64490f32e143af8ef479b93e87d # v4.1.0
uses: github/issue-metrics@6a35322ff89cee3e1a594d282c27eb34bffa9174 # v4.1.1
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SEARCH_QUERY: 'repo:FreeCAD/FreeCAD is:issue created:${{ env.last_month }}'
+1 -1
View File
@@ -62,7 +62,7 @@ jobs:
run: |
mkdir -p ${{ env.artifactsDownloadDir }}
- name: Download artifacts
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: ${{ env.artifactsDownloadDir }}
- name: Save input data to file
+2 -2
View File
@@ -70,11 +70,11 @@ repos:
- id: check-added-large-files
- id: mixed-line-ending
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 2892f1f81088477370d4fbc56545c05d33d2493f # frozen: 25.11.0
rev: fa505ab9c3e0fedafe1709fd7ac2b5f8996c670d # frozen: 26.3.1
hooks:
- id: black
args: ['--line-length', '100']
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: 317810f3c6a0ad3572367dc86cb6e41863e16e08 # frozen: v21.1.5
rev: 88c364bab316f4b6b18f6c298133bbbf32d7cd15 # frozen: v22.1.1
hooks:
- id: clang-format
+10 -10
View File
@@ -90,7 +90,7 @@ environments:
- conda: https://prefix.dev/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
- conda: https://prefix.dev/conda-forge/linux-64/icu-75.1-he02047a_0.conda
- conda: https://prefix.dev/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
- conda: https://prefix.dev/conda-forge/linux-64/ifcopenshell-0.8.4-py311hfa9dd64_2.conda
- conda: https://prefix.dev/conda-forge/linux-64/ifcopenshell-0.8.2-py311hfea35e5_0.conda
- conda: https://prefix.dev/conda-forge/linux-64/imath-3.1.12-h7955e40_0.conda
- conda: https://prefix.dev/conda-forge/linux-64/jasper-4.2.8-he3c4edf_0.conda
- conda: https://prefix.dev/conda-forge/linux-64/jsoncpp-1.9.6-hf42df4d_1.conda
@@ -422,7 +422,7 @@ environments:
- conda: https://prefix.dev/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
- conda: https://prefix.dev/conda-forge/linux-aarch64/icu-75.1-hf9b3779_0.conda
- conda: https://prefix.dev/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
- conda: https://prefix.dev/conda-forge/linux-aarch64/ifcopenshell-0.8.4-py311h9ffcc0b_2.conda
- conda: https://prefix.dev/conda-forge/linux-aarch64/ifcopenshell-0.8.2-py311h9a0e4cb_0.conda
- conda: https://prefix.dev/conda-forge/linux-aarch64/imath-3.1.12-hf428078_0.conda
- conda: https://prefix.dev/conda-forge/linux-aarch64/jasper-4.2.8-h27a9ab5_0.conda
- conda: https://prefix.dev/conda-forge/linux-aarch64/jsoncpp-1.9.6-h34915d9_1.conda
@@ -741,7 +741,7 @@ environments:
- conda: https://prefix.dev/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
- conda: https://prefix.dev/conda-forge/osx-64/icu-75.1-h120a0e1_0.conda
- conda: https://prefix.dev/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
- conda: https://prefix.dev/conda-forge/osx-64/ifcopenshell-0.8.4-py311hbba92a7_2.conda
- conda: https://prefix.dev/conda-forge/osx-64/ifcopenshell-0.8.2-py311h2fdbcd7_0.conda
- conda: https://prefix.dev/conda-forge/osx-64/imath-3.1.12-h2016aa1_0.conda
- conda: https://prefix.dev/conda-forge/osx-64/jasper-4.2.8-h9ce442b_0.conda
- conda: https://prefix.dev/conda-forge/osx-64/jsoncpp-1.9.6-h466cfd8_1.conda
@@ -1011,7 +1011,7 @@ environments:
- conda: https://prefix.dev/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
- conda: https://prefix.dev/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda
- conda: https://prefix.dev/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
- conda: https://prefix.dev/conda-forge/osx-arm64/ifcopenshell-0.8.4-py311h5dd451c_2.conda
- conda: https://prefix.dev/conda-forge/osx-arm64/ifcopenshell-0.8.2-py311h30f7335_0.conda
- conda: https://prefix.dev/conda-forge/osx-arm64/imath-3.1.12-h025cafa_0.conda
- conda: https://prefix.dev/conda-forge/osx-arm64/jasper-4.2.8-hc0e5025_0.conda
- conda: https://prefix.dev/conda-forge/osx-arm64/jsoncpp-1.9.6-h726d253_1.conda
@@ -1274,7 +1274,7 @@ environments:
- conda: https://prefix.dev/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda
- conda: https://prefix.dev/conda-forge/win-64/icu-75.1-he0c23c2_0.conda
- conda: https://prefix.dev/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda
- conda: https://prefix.dev/conda-forge/win-64/ifcopenshell-0.8.4-py311h5252d0d_2.conda
- conda: https://prefix.dev/conda-forge/win-64/ifcopenshell-0.8.2-py311ha1ff2f0_0.conda
- conda: https://prefix.dev/conda-forge/win-64/imath-3.1.12-hbb528cf_0.conda
- conda: https://prefix.dev/conda-forge/win-64/jasper-4.2.8-h8ad263b_0.conda
- conda: https://prefix.dev/conda-forge/win-64/jsoncpp-1.9.6-hda1637e_1.conda
@@ -6121,7 +6121,7 @@ packages:
license_family: BSD
size: 50721
timestamp: 1760286526795
- conda: https://prefix.dev/conda-forge/linux-64/ifcopenshell-0.8.4-py311hfa9dd64_2.conda
- conda: https://prefix.dev/conda-forge/linux-64/ifcopenshell-0.8.2-py311hfea35e5_0.conda
sha256: 45ce07c412cb1d4b8bfd0fde785e9f3751381b4e3d6a28686a174559f0628e69
md5: 25bcf0826fc3b896d07afbe35982a500
depends:
@@ -6145,7 +6145,7 @@ packages:
license_family: LGPL
size: 43852878
timestamp: 1745412691720
- conda: https://prefix.dev/conda-forge/linux-aarch64/ifcopenshell-0.8.4-py311h9ffcc0b_2.conda
- conda: https://prefix.dev/conda-forge/linux-aarch64/ifcopenshell-0.8.2-py311h9a0e4cb_0.conda
sha256: 5b0d7760899ffa8ae91169bff49c9d6cd435b1cb8957e7622d9bd765a9c2d577
md5: fc1ebe0deebc32d2d42b8dc257afb836
depends:
@@ -6168,7 +6168,7 @@ packages:
license_family: LGPL
size: 46059599
timestamp: 1745412697613
- conda: https://prefix.dev/conda-forge/osx-64/ifcopenshell-0.8.4-py311hbba92a7_2.conda
- conda: https://prefix.dev/conda-forge/osx-64/ifcopenshell-0.8.2-py311h2fdbcd7_0.conda
sha256: d52f4bd7cec3cf1cbcd7cf9c6a21ec6d2331425972c4cd7f88d3df64a4a3cd72
md5: d0352d59f66ec49a974177e1efc749df
depends:
@@ -6190,7 +6190,7 @@ packages:
license_family: LGPL
size: 39452121
timestamp: 1745412590610
- conda: https://prefix.dev/conda-forge/osx-arm64/ifcopenshell-0.8.4-py311h5dd451c_2.conda
- conda: https://prefix.dev/conda-forge/osx-arm64/ifcopenshell-0.8.2-py311h30f7335_0.conda
sha256: 15d5d080aa54c1b5aeed0e4827d5a6b4521b8a2599e3bc06af5318575d2b7a8f
md5: b550b7b3c4a8f543fb3c0c15f8ec5967
depends:
@@ -6213,7 +6213,7 @@ packages:
license_family: LGPL
size: 40077397
timestamp: 1745412613454
- conda: https://prefix.dev/conda-forge/win-64/ifcopenshell-0.8.4-py311h5252d0d_2.conda
- conda: https://prefix.dev/conda-forge/win-64/ifcopenshell-0.8.2-py311ha1ff2f0_0.conda
sha256: 4e3c4d0d3749b761267b9ac9f9c3262c2b690d1908a6a6db734dcd4eecd43b2e
md5: e178c988f7034d08d27fe14a62bdbe12
depends:
+3 -1
View File
@@ -2492,7 +2492,9 @@ void processProgramOptions(const boost::program_options::variables_map& vm, std:
void Application::initConfig(int argc, char ** argv)
{
// find the home path....
mConfig["AppHomePath"] = ApplicationDirectories::findHomePath(argv[0]).string();
mConfig["AppHomePath"] = Base::FileInfo::pathToString(
ApplicationDirectories::findHomePath(argv[0])
);
// Version of the application extracted from SubWCRef into src/Build/Version.h
// We only set these keys if not yet defined. Therefore it suffices to search
+9 -5
View File
@@ -80,12 +80,16 @@ const fs::path& ApplicationDirectories::getTempPath() const {
return this->_temp;
}
fs::path ApplicationDirectories::getTempFileName(const std::string & filename) const {
fs::path ApplicationDirectories::getTempFileName(const std::string & filename) const
{
auto tempPath = Base::FileInfo::pathToString(getTempPath());
if (filename.empty()) {
return Base::FileInfo::getTempFileName(nullptr, tempPath.c_str());
return Base::FileInfo::stringToPath(Base::FileInfo::getTempFileName(nullptr, tempPath.c_str())
);
}
return Base::FileInfo::getTempFileName(filename.c_str(), tempPath.c_str());
return Base::FileInfo::stringToPath(
Base::FileInfo::getTempFileName(filename.c_str(), tempPath.c_str())
);
}
const fs::path& ApplicationDirectories::getUserCachePath() const
@@ -182,7 +186,7 @@ void ApplicationDirectories::configurePaths(std::map<std::string,std::string>& m
bool keepDeprecatedPaths = mConfig.contains("KeepDeprecatedPaths");
// std paths
_home = fs::path(mConfig.at("AppHomePath"));
_home = Base::FileInfo::stringToPath(mConfig.at("AppHomePath"));
mConfig["BinPath"] = mConfig.at("AppHomePath") + "bin" + PATHSEP;
mConfig["DocPath"] = mConfig.at("AppHomePath") + "doc" + PATHSEP;
@@ -298,7 +302,7 @@ void ApplicationDirectories::configureResourceDirectory(const std::map<std::stri
_resource = Base::FileInfo::stringToPath(mConfig.at("AppHomePath")) / path;
}
#else
_resource = fs::path(mConfig.at("AppHomePath"));
_resource = Base::FileInfo::stringToPath(mConfig.at("AppHomePath"));
#endif
}
+1 -1
View File
@@ -75,7 +75,7 @@ Man bør derefter klikke på Opdater knappen i hovedværktøjslinjen.
<message>
<location filename="../../Datums.cpp" line="271"/>
<source>Origin</source>
<translation>Origo</translation>
<translation>Nulpunkt</translation>
</message>
</context>
</TS>
+11 -11
View File
@@ -4,7 +4,7 @@
<context>
<name>LinkParams</name>
<message>
<location filename="../../Link.cpp" line="135"/>
<location filename="../../Link.cpp" line="131"/>
<source>Stores the last user choice of whether to apply CopyOnChange setup to all links
that reference the same configurable object</source>
<translation>Menyimpan pilihan terakhir pengguna sama ada untuk menerapkan tetapan CopyOnChange kepada semua pautan yang merujuk kepada objek boleh dikonfigurasikan yang sama</translation>
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="457"/>
<location filename="../../Application.cpp" line="458"/>
<source>Unnamed</source>
<translation>Tidak bernama</translation>
</message>
@@ -21,7 +21,7 @@ that reference the same configurable object</source>
<context>
<name>App::OriginGroupExtension</name>
<message>
<location filename="../../OriginGroupExtension.cpp" line="162"/>
<location filename="../../OriginGroupExtension.cpp" line="161"/>
<source>Origin</source>
<translation>Asal</translation>
</message>
@@ -29,7 +29,7 @@ that reference the same configurable object</source>
<context>
<name>Notifications</name>
<message>
<location filename="../../Document.cpp" line="1095"/>
<location filename="../../Document.cpp" line="1117"/>
<source>
It is recommended that the user right-click the root of the document and select Mark to recompute.
The user should then click the Refresh button in the main toolbar.
@@ -41,37 +41,37 @@ Pengguna kemudiannya perlu mengklik butang Muat semula dalam bar alat utama.</tr
<context>
<name>App::LocalCoordinateSystem</name>
<message>
<location filename="../../Datums.cpp" line="250"/>
<location filename="../../Datums.cpp" line="265"/>
<source>X-axis</source>
<translation>Paksi-X</translation>
</message>
<message>
<location filename="../../Datums.cpp" line="251"/>
<location filename="../../Datums.cpp" line="266"/>
<source>Y-axis</source>
<translation>Paksi-Y</translation>
</message>
<message>
<location filename="../../Datums.cpp" line="252"/>
<location filename="../../Datums.cpp" line="267"/>
<source>Z-axis</source>
<translation>Paksi-Z</translation>
</message>
<message>
<location filename="../../Datums.cpp" line="253"/>
<location filename="../../Datums.cpp" line="268"/>
<source>XY-plane</source>
<translation>Pesawat-XY</translation>
</message>
<message>
<location filename="../../Datums.cpp" line="254"/>
<location filename="../../Datums.cpp" line="269"/>
<source>XZ-plane</source>
<translation>Pesawat-XZ</translation>
</message>
<message>
<location filename="../../Datums.cpp" line="255"/>
<location filename="../../Datums.cpp" line="270"/>
<source>YZ-plane</source>
<translation>Pesawat-YZ</translation>
</message>
<message>
<location filename="../../Datums.cpp" line="256"/>
<location filename="../../Datums.cpp" line="271"/>
<source>Origin</source>
<translation>Asal</translation>
</message>
+3 -3
View File
@@ -58,10 +58,10 @@ static void _replaceDirs()
};
for (auto const d : dirs) {
auto const path = temp_base + PATHSEP + d + PATHSEP;
auto const qpath = QString::fromStdString(path);
auto const path = temp_base + "/" + d + "/";
auto const qpath = QDir::cleanPath(QString::fromStdString(path));
QDir().mkpath(qpath);
config[d] = path;
config[d] = QDir::toNativeSeparators(qpath).toStdString();
}
}
+2 -4
View File
@@ -22,14 +22,12 @@ class ScaleType(IntEnum):
NumberProtocol=True,
RichCompare=True,
)
@class_declarations(
"""public:
@class_declarations("""public:
MatrixPy(const Matrix4D & mat, PyTypeObject *T = &Type)
:PyObjectBase(new Matrix4D(mat),T){}
Matrix4D value() const
{ return *(getMatrixPtr()); }
"""
)
""")
class Matrix(PyObjectBase):
"""
Base.Matrix class.
+2 -4
View File
@@ -15,14 +15,12 @@ from typing import Sequence, overload
NumberProtocol=True,
RichCompare=True,
)
@class_declarations(
"""public:
@class_declarations("""public:
PlacementPy(const Placement & pla, PyTypeObject *T = &Type)
:PyObjectBase(new Placement(pla),T){}
Placement value() const
{ return *(getPlacementPtr()); }
"""
)
""")
class Placement(PyObjectBase):
"""
Base.Placement class.
+23 -23
View File
@@ -4,54 +4,54 @@
<context>
<name>UnitsApi</name>
<message>
<location filename="../../UnitsSchemasData.h" line="85"/>
<location filename="../../UnitsSchemasData.h" line="90"/>
<source>Standard (mm, kg, s, °)</source>
<translation type="unfinished">Standard (mm, kg, s, °)</translation>
<translation>Standard (mm, kg, s, °)</translation>
</message>
<message>
<location filename="../../UnitsSchemasData.h" line="315"/>
<location filename="../../UnitsSchemasData.h" line="326"/>
<source>MKS (m, kg, s, °)</source>
<translation type="unfinished">MKS (m, kg, s, °)</translation>
<translation>MKS (m, kg, s, °)</translation>
</message>
<message>
<location filename="../../UnitsSchemasData.h" line="579"/>
<location filename="../../UnitsSchemasData.h" line="593"/>
<source>US customary (in, lb)</source>
<translation type="unfinished">US customary (in, lb)</translation>
<translation>Adat AS (in, lb)</translation>
</message>
<message>
<location filename="../../UnitsSchemasData.h" line="70"/>
<location filename="../../UnitsSchemasData.h" line="642"/>
<source>Imperial for Civil Eng (ft, lb, mph)</source>
<translation>Imperial Civil Eng (ft, lb, mph)</translation>
</message>
<message>
<location filename="../../UnitsSchemasData.h" line="75"/>
<source>Imperial decimal (in, lb)</source>
<translation type="unfinished">Imperial decimal (in, lb)</translation>
<translation>Imperial decimal (in, lb)</translation>
</message>
<message>
<location filename="../../UnitsSchemasData.h" line="540"/>
<location filename="../../UnitsSchemasData.h" line="554"/>
<source>Building Euro (cm, m², m³)</source>
<translation type="unfinished">Building Euro (cm, m², m³)</translation>
<translation>Bagunan Euro (cm, m², m³)</translation>
</message>
<message>
<location filename="../../UnitsSchemasData.h" line="617"/>
<location filename="../../UnitsSchemasData.h" line="631"/>
<source>Building US (ft-in, sqft, cft)</source>
<translation type="unfinished">Building US (ft-in, sqft, cft)</translation>
<translation>Membina AS (ft-in, sqft, cft)</translation>
</message>
<message>
<location filename="../../UnitsSchemasData.h" line="48"/>
<location filename="../../UnitsSchemasData.h" line="53"/>
<source>Metric small parts &amp; CNC (mm, mm/min)</source>
<translation type="unfinished">Metric small parts &amp; CNC (mm, mm/min)</translation>
<translation>Bahagian kecil metrik &amp; CNC (mm, mm/min)</translation>
</message>
<message>
<location filename="../../UnitsSchemasData.h" line="628"/>
<source>Imperial for Civil Eng (ft, ft/s)</source>
<translation type="unfinished">Imperial for Civil Eng (ft, ft/s)</translation>
</message>
<message>
<location filename="../../UnitsSchemasData.h" line="567"/>
<location filename="../../UnitsSchemasData.h" line="581"/>
<source>FEM (mm, N, s)</source>
<translation type="unfinished">FEM (mm, N, s)</translation>
<translation>FEM (mm, N, s)</translation>
</message>
<message>
<location filename="../../UnitsSchemasData.h" line="57"/>
<location filename="../../UnitsSchemasData.h" line="62"/>
<source>Meter decimal (m, m², m³)</source>
<translation type="unfinished">Meter decimal (m, m², m³)</translation>
<translation>Perpuluhan meter (m, m², m³)</translation>
</message>
</context>
</TS>
+2 -4
View File
@@ -14,14 +14,12 @@ from typing import overload, Tuple, List, Final
NumberProtocol=True,
RichCompare=True,
)
@class_declarations(
"""public:
@class_declarations("""public:
RotationPy(const Rotation & mat, PyTypeObject *T = &Type)
:PyObjectBase(new Rotation(mat),T){}
Rotation value() const
{ return *(getRotationPtr()); }
"""
)
""")
class Rotation(PyObjectBase):
"""
Base.Rotation class.
+2 -4
View File
@@ -603,8 +603,7 @@ public:
{
}
#endif
~ofstream() override
= default;
~ofstream() override = default;
void open(const FileInfo& fi, ios_base::openmode mode = std::ios::out | std::ios::trunc)
{
#ifdef _MSC_VER
@@ -638,8 +637,7 @@ public:
{
}
#endif
~ifstream() override
= default;
~ifstream() override = default;
void open(const FileInfo& fi, ios_base::openmode mode = std::ios::in)
{
#ifdef _MSC_VER
+2 -4
View File
@@ -11,12 +11,10 @@ from typing import List, Final
TwinPointer="BaseType",
Delete=True,
)
@forward_declarations(
"""
@forward_declarations("""
namespace Base {
using BaseType = Type;
}"""
)
}""")
class Type(PyObjectBase):
"""
BaseTypePy class.
+2 -4
View File
@@ -26,8 +26,7 @@ from typing import overload, Sequence
sq_inplace_concat=False,
sq_inplace_repeat=False,
)
@class_declarations(
"""public:
@class_declarations("""public:
VectorPy(const Vector3d & vec, PyTypeObject *T = &Type)
:PyObjectBase(new Vector3d(vec),T){}
VectorPy(const Vector3f & vec, PyTypeObject *T = &Type)
@@ -36,8 +35,7 @@ from typing import overload, Sequence
{ return *(getVectorPtr()); }
private:
Py::List sequence;
"""
)
""")
class Vector(PyObjectBase):
"""
Base.Vector class.
+6 -8
View File
@@ -876,10 +876,8 @@ void Application::importFrom(const char* FileName, const char* DocName, const ch
"User parameter:BaseApp/Preferences/View"
);
if (hGrp->GetBool("AutoFitToView", true)) {
MDIView* view = doc->getActiveView();
if (view) {
const char* ret = nullptr;
if (view->onMsg("ViewFit", &ret)) {
if (MDIView* view = doc->getActiveView()) {
if (view->onMsg("ViewFit")) {
updateActions(true);
}
}
@@ -1404,10 +1402,10 @@ void Application::onLastWindowClosed(Gui::Document* pcDoc)
}
/// send Messages to the active view
bool Application::sendMsgToActiveView(const char* pMsg, const char** ppReturn)
bool Application::sendMsgToActiveView(const char* pMsg)
{
MDIView* pView = getMainWindow()->activeWindow();
bool res = pView ? pView->onMsg(pMsg, ppReturn) : false;
bool res = pView ? pView->onMsg(pMsg) : false;
updateActions(true);
return res;
}
@@ -1419,7 +1417,7 @@ bool Application::sendHasMsgToActiveView(const char* pMsg)
}
/// send Messages to the active view
bool Application::sendMsgToFocusView(const char* pMsg, const char** ppReturn)
bool Application::sendMsgToFocusView(const char* pMsg)
{
MDIView* pView = getMainWindow()->activeWindow();
if (!pView) {
@@ -1427,7 +1425,7 @@ bool Application::sendMsgToFocusView(const char* pMsg, const char** ppReturn)
}
for (auto focus = qApp->focusWidget(); focus; focus = focus->parentWidget()) {
if (focus == pView) {
bool res = pView->onMsg(pMsg, ppReturn);
bool res = pView->onMsg(pMsg);
updateActions(true);
return res;
}
+2 -2
View File
@@ -91,11 +91,11 @@ public:
/** @name methods for View handling */
//@{
/// send Messages to the active view
bool sendMsgToActiveView(const char* pMsg, const char** ppReturn = nullptr);
bool sendMsgToActiveView(const char* pMsg);
/// send Messages test to the active view
bool sendHasMsgToActiveView(const char* pMsg);
/// send Messages to the focused view
bool sendMsgToFocusView(const char* pMsg, const char** ppReturn = nullptr);
bool sendMsgToFocusView(const char* pMsg);
/// send Messages test to the focused view
bool sendHasMsgToFocusView(const char* pMsg);
/// Attach a view (get called by the FCView constructor)
+4 -16
View File
@@ -253,7 +253,7 @@ PyMethodDef ApplicationPy::Methods[] = {
{"SendMsgToActiveView",
(PyCFunction)ApplicationPy::sSendActiveView,
METH_VARARGS,
"SendMsgToActiveView(name, suppress=False) -> str or None\n"
"SendMsgToActiveView(name, suppress=False) -> None\n"
"\n"
"Send message to the active view. Deprecated, use class View.\n"
"\n"
@@ -262,7 +262,7 @@ PyMethodDef ApplicationPy::Methods[] = {
{"sendMsgToFocusView",
(PyCFunction)ApplicationPy::sSendFocusView,
METH_VARARGS,
"sendMsgToFocusView(name, suppress=False) -> str or None\n"
"sendMsgToFocusView(name, suppress=False) -> None\n"
"\n"
"Send message to the focused view.\n"
"\n"
@@ -928,18 +928,12 @@ PyObject* ApplicationPy::sSendActiveView(PyObject* /*self*/, PyObject* args)
return nullptr;
}
const char* ppReturn = nullptr;
if (!Application::Instance->sendMsgToActiveView(psCommandStr, &ppReturn)) {
if (!Application::Instance->sendMsgToActiveView(psCommandStr)) {
if (!Base::asBoolean(suppress)) {
Base::Console().warning("Unknown view command: %s\n", psCommandStr);
}
}
// Print the return value to the output
if (ppReturn) {
return Py_BuildValue("s", ppReturn);
}
Py_Return;
}
@@ -952,18 +946,12 @@ PyObject* ApplicationPy::sSendFocusView(PyObject* /*self*/, PyObject* args)
return nullptr;
}
const char* ppReturn = nullptr;
if (!Application::Instance->sendMsgToFocusView(psCommandStr, &ppReturn)) {
if (!Application::Instance->sendMsgToFocusView(psCommandStr)) {
if (!Base::asBoolean(suppress)) {
Base::Console().warning("Unknown view command: %s\n", psCommandStr);
}
}
// Print the return value to the output
if (ppReturn) {
return Py_BuildValue("s", ppReturn);
}
Py_Return;
}
+4 -3
View File
@@ -698,9 +698,10 @@ bool CallTipsList::eventFilter(QObject* watched, QEvent* event)
Q_EMIT itemActivated(currentItem());
return false;
}
else if (ke->key() == Qt::Key_Shift || ke->key() == Qt::Key_Control
|| ke->key() == Qt::Key_Meta || ke->key() == Qt::Key_Alt
|| ke->key() == Qt::Key_AltGr) {
else if (
ke->key() == Qt::Key_Shift || ke->key() == Qt::Key_Control
|| ke->key() == Qt::Key_Meta || ke->key() == Qt::Key_Alt || ke->key() == Qt::Key_AltGr
) {
// filter these meta keys to avoid to call keyboardSearch()
return true;
}
+4 -2
View File
@@ -116,8 +116,10 @@ PyObject* CommandPy::listByShortcut(PyObject* args)
matches.emplace_back(c->getName());
}
}
else if (action->shortcut().toString().remove(spc).toUpper()
== QString::fromLatin1(shortcut_to_find).remove(spc).toUpper()) {
else if (
action->shortcut().toString().remove(spc).toUpper()
== QString::fromLatin1(shortcut_to_find).remove(spc).toUpper()
) {
matches.emplace_back(c->getName());
}
}
+48 -37
View File
@@ -393,8 +393,15 @@ void StdCmdFreezeViews::activated(int iMsg)
}
else if (iMsg == 3) {
// Create a new view
const char* ppReturn = nullptr;
getGuiApplication()->sendMsgToActiveView("GetCamera", &ppReturn);
auto* view3d = freecad_cast<View3DInventor*>(getGuiApplication()->activeView());
if (view3d == nullptr) {
Base::Console().developerError(
"StdCmdFreezeViews",
"Expected the active view to be View3DInventor\n"
);
return;
}
const std::string& camera = view3d->getCamera();
QList<QAction*> acts = pcAction->actions();
int index = 1;
@@ -403,7 +410,7 @@ void StdCmdFreezeViews::activated(int iMsg)
savedViews++;
QString viewnr = QString(QObject::tr("Restore View &%1")).arg(index);
(*it)->setText(viewnr);
(*it)->setToolTip(QString::fromLatin1(ppReturn));
(*it)->setToolTip(QString::fromStdString(camera));
(*it)->setVisible(true);
if (index < 10) {
(*it)->setShortcut(QKeySequence(QStringLiteral("CTRL+%1").arg(index)));
@@ -423,11 +430,28 @@ void StdCmdFreezeViews::activated(int iMsg)
// Activate a view
QList<QAction*> acts = pcAction->actions();
QString data = acts[iMsg]->toolTip();
QString send = QStringLiteral("SetCamera %1").arg(data);
getGuiApplication()->sendMsgToActiveView(send.toLatin1());
MDIView* view = getGuiApplication()->activeView();
if (auto* view3D = freecad_cast<View3DInventor*>(view)) {
view3D->setCamera(data.toStdString().c_str());
}
}
}
bool StdCmdFreezeViews::isActive()
{
auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
separator->setVisible(savedViews > 0);
if (view) {
saveView->setEnabled(savedViews > 0);
freezeView->setEnabled(savedViews < maxViews);
clearView->setEnabled(savedViews > 0);
return true;
}
return false;
}
void StdCmdFreezeViews::onSaveViews()
{
// Save the views to an XML file
@@ -589,23 +613,6 @@ void StdCmdFreezeViews::onRestoreViews()
}
}
bool StdCmdFreezeViews::isActive()
{
auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
if (view) {
saveView->setEnabled(savedViews > 0);
freezeView->setEnabled(savedViews < maxViews);
clearView->setEnabled(savedViews > 0);
separator->setVisible(savedViews > 0);
return true;
}
else {
separator->setVisible(savedViews > 0);
}
return false;
}
void StdCmdFreezeViews::languageChange()
{
Command::languageChange();
@@ -2630,34 +2637,38 @@ StdCmdViewIvIssueCamPos::StdCmdViewIvIssueCamPos()
void StdCmdViewIvIssueCamPos::activated(int iMsg)
{
Q_UNUSED(iMsg);
std::string Temp, Temp2;
std::string::size_type pos;
const char* ppReturn = nullptr;
getGuiApplication()->sendMsgToActiveView("GetCamera", &ppReturn);
auto* view3d = freecad_cast<View3DInventor*>(getGuiApplication()->activeView());
if (view3d == nullptr) {
Base::Console().developerError(
"StdCmdViewIvIssueCameraPos",
"Expected the active view to be View3DInventor\n"
);
return;
}
std::string camera = view3d->getCamera();
// remove the #inventor line...
Temp2 = ppReturn;
pos = Temp2.find_first_of("\n");
Temp2.erase(0, pos);
std::string::size_type pos = camera.find_first_of('\n');
camera.erase(0, pos);
// remove all returns
while ((pos = Temp2.find('\n')) != std::string::npos) {
Temp2.replace(pos, 1, " ");
while ((pos = camera.find('\n')) != std::string::npos) {
camera.replace(pos, 1, " ");
}
// build up the command string
Temp += "Gui.SendMsgToActiveView(\"SetCamera ";
Temp += Temp2;
Temp += "\")";
std::string command = "Gui.activeView().setCamera(\"";
command += camera;
command += "\")";
Base::Console().message("%s\n", Temp2.c_str());
getGuiApplication()->macroManager()->addLine(MacroManager::Gui, Temp.c_str());
Base::Console().message("%s\n", camera.c_str());
getGuiApplication()->macroManager()->addLine(MacroManager::Gui, command.c_str());
}
bool StdCmdViewIvIssueCamPos::isActive()
{
return getGuiApplication()->sendHasMsgToActiveView("GetCamera");
return freecad_cast<View3DInventor*>(getGuiApplication()->activeView());
}
+4 -12
View File
@@ -344,33 +344,25 @@ void DlgParameterImp::onGroupSelected(QTreeWidgetItem* item)
// filling up Int nodes
std::vector<std::pair<std::string, long>> mcIntMap = _hcGrp->GetIntMap();
for (const auto& It3 : mcIntMap) {
(
void
)new ParameterInt(paramValue, QString::fromUtf8(It3.first.c_str()), It3.second, _hcGrp);
(void)new ParameterInt(paramValue, QString::fromUtf8(It3.first.c_str()), It3.second, _hcGrp);
}
// filling up Float nodes
std::vector<std::pair<std::string, double>> mcFloatMap = _hcGrp->GetFloatMap();
for (const auto& It4 : mcFloatMap) {
(
void
)new ParameterFloat(paramValue, QString::fromUtf8(It4.first.c_str()), It4.second, _hcGrp);
(void)new ParameterFloat(paramValue, QString::fromUtf8(It4.first.c_str()), It4.second, _hcGrp);
}
// filling up bool nodes
std::vector<std::pair<std::string, bool>> mcBoolMap = _hcGrp->GetBoolMap();
for (const auto& It5 : mcBoolMap) {
(
void
)new ParameterBool(paramValue, QString::fromUtf8(It5.first.c_str()), It5.second, _hcGrp);
(void)new ParameterBool(paramValue, QString::fromUtf8(It5.first.c_str()), It5.second, _hcGrp);
}
// filling up UInt nodes
std::vector<std::pair<std::string, unsigned long>> mcUIntMap = _hcGrp->GetUnsignedMap();
for (const auto& It6 : mcUIntMap) {
(
void
)new ParameterUInt(paramValue, QString::fromUtf8(It6.first.c_str()), It6.second, _hcGrp);
(void)new ParameterUInt(paramValue, QString::fromUtf8(It6.first.c_str()), It6.second, _hcGrp);
}
paramValue->setSortingEnabled(sortingEnabled);
}
+1 -1
View File
@@ -71,7 +71,7 @@ public:
return "DockWindow";
}
/// Message handler
bool onMsg(const char*, const char**) override
bool onMsg(const char*) override
{
return false;
}
+17 -24
View File
@@ -1898,11 +1898,9 @@ void Document::RestoreDocFile(Base::Reader& reader)
if (!Base::Tools::isNullOrEmpty(ppReturn)) {
saveCameraSettings(ppReturn);
try {
const char** pReturnIgnore = nullptr;
std::list<MDIView*> mdi = getMDIViews();
for (const auto& it : mdi) {
if (it->onHasMsg("SetCamera")) {
it->onMsg(cameraSettings.c_str(), pReturnIgnore);
for (const auto& it : getMDIViews()) {
if (auto* view3D = freecad_cast<View3DInventor*>(it)) {
view3D->setCamera(cameraSettings.c_str());
}
}
}
@@ -2023,12 +2021,10 @@ void Document::SaveDocFile(Base::Writer& writer) const
writer.decInd(); // indentation for 'ViewProviderData Count'
// save camera settings
std::list<MDIView*> mdi = getMDIViews();
for (const auto& it : mdi) {
if (it->onHasMsg("GetCamera")) {
const char* ppReturn = nullptr;
it->onMsg("GetCamera", &ppReturn);
if (saveCameraSettings(ppReturn)) {
for (const auto& it : getMDIViews()) {
if (auto* view3D = freecad_cast<View3DInventor*>(it)) {
const std::string& camera = view3D->getCamera();
if (saveCameraSettings(camera.c_str())) {
break;
}
}
@@ -2217,9 +2213,8 @@ MDIView* Document::createView(const Base::Type& typeId, CreateViewMode mode)
auto firstView = static_cast<View3DInventor*>(theViews.front());
shareWidget = qobject_cast<QOpenGLWidget*>(firstView->getViewer()->getGLWidget());
const char* ppReturn = nullptr;
firstView->onMsg("GetCamera", &ppReturn);
saveCameraSettings(ppReturn);
const std::string& camera = firstView->getCamera();
saveCameraSettings(camera.c_str());
}
auto view3D = new View3DInventor(this, getMainWindow(), shareWidget);
@@ -2265,8 +2260,7 @@ MDIView* Document::createView(const Base::Type& typeId, CreateViewMode mode)
view3D->resize(400, 300);
if (!cameraSettings.empty()) {
const char* ppReturn = nullptr;
view3D->onMsg(cameraSettings.c_str(), &ppReturn);
view3D->setCamera(cameraSettings.c_str());
}
// When cloning the view, don't add the view to the main window. The whole purpose of the
@@ -2284,7 +2278,7 @@ MDIView* Document::createView(const Base::Type& typeId, CreateViewMode mode)
const char* Document::getCameraSettings() const
{
return cameraSettings.size() > 10 ? cameraSettings.c_str() + 10 : cameraSettings.c_str();
return cameraSettings.c_str();
}
bool Document::saveCameraSettings(const char* settings) const
@@ -2314,7 +2308,7 @@ bool Document::saveCameraSettings(const char* settings) const
return false;
}
cameraSettings = std::string("SetCamera ") + settings;
cameraSettings = settings;
return true;
}
@@ -2531,16 +2525,15 @@ std::list<MDIView*> Document::getMDIViewsOfType(const Base::Type& typeId) const
bool Document::sendMsgToViews(const char* pMsg)
{
std::list<Gui::BaseView*>::iterator it;
const char** pReturnIgnore = nullptr;
for (it = d->baseViews.begin(); it != d->baseViews.end(); ++it) {
if ((*it)->onMsg(pMsg, pReturnIgnore)) {
if ((*it)->onMsg(pMsg)) {
return true;
}
}
for (it = d->passiveViews.begin(); it != d->passiveViews.end(); ++it) {
if ((*it)->onMsg(pMsg, pReturnIgnore)) {
if ((*it)->onMsg(pMsg)) {
return true;
}
}
@@ -2548,12 +2541,12 @@ bool Document::sendMsgToViews(const char* pMsg)
return false;
}
bool Document::sendMsgToFirstView(const Base::Type& typeId, const char* pMsg, const char** ppReturn)
bool Document::sendMsgToFirstView(const Base::Type& typeId, const char* pMsg)
{
// first try the active view
Gui::MDIView* view = getActiveView();
if (view && view->isDerivedFrom(typeId)) {
if (view->onMsg(pMsg, ppReturn)) {
if (view->onMsg(pMsg)) {
return true;
}
}
@@ -2561,7 +2554,7 @@ bool Document::sendMsgToFirstView(const Base::Type& typeId, const char* pMsg, co
// now try the other views
std::list<Gui::MDIView*> views = getMDIViewsOfType(typeId);
for (const auto& it : views) {
if ((it != view) && it->onMsg(pMsg, ppReturn)) {
if ((it != view) && it->onMsg(pMsg)) {
return true;
}
}
+1 -1
View File
@@ -218,7 +218,7 @@ public:
* first checked view is the current active view.
* If a view supports the message true is returned and false otherwise.
*/
bool sendMsgToFirstView(const Base::Type& typeId, const char* pMsg, const char** ppReturn);
bool sendMsgToFirstView(const Base::Type& typeId, const char* pMsg);
/// Attach a view (get called by the MDIView constructor)
void attachView(Gui::BaseView* pcView, bool bPassiv = false);
/// Detach a view (get called by the MDIView destructor)
+56 -50
View File
@@ -29,9 +29,11 @@
#include <Inventor/nodes/SoSwitch.h>
#include <QEvent>
#include <QFontMetrics>
#include <QKeyEvent>
#include <QPixmap>
#include <QLabel>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QString>
@@ -41,6 +43,8 @@
#include <Gui/View3DInventorViewer.h>
#include "EditableDatumLabel.h"
#include "Base/Console.h"
#include "Gui/QuantitySpinBox.h"
using namespace Gui;
@@ -175,6 +179,8 @@ void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj, bool
spinBox->setAutoNormalize(false);
spinBox->setKeyboardTracking(true);
spinBox->installEventFilter(this);
spinBox->setAutoAdjustWidth(true);
spinBox->setMaxExpectedDigits(16);
if (eventFilteringObj) {
spinBox->installEventFilter(eventFilteringObj);
@@ -185,10 +191,7 @@ void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj, bool
}
spinBox->show();
setSpinboxValue(val);
// Note: adjustSize apparently uses the Min/Max values to set the size. So if we don't set them
// to INT_MAX, the spinbox are much too big.
spinBox->adjustSize();
updateGeometry();
setFocusToSpinbox();
const auto validateAndFinish = [this]() {
@@ -217,6 +220,9 @@ void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj, bool
};
connect(spinBox, qOverload<double>(&QuantitySpinBox::valueChanged), this, validateAndFinish);
if (auto* edit = spinBox->findChild<QLineEdit*>()) {
connect(edit, &QLineEdit::textChanged, this, &EditableDatumLabel::updateGeometry);
}
}
bool EditableDatumLabel::eventFilter(QObject* watched, QEvent* event)
@@ -364,8 +370,9 @@ void EditableDatumLabel::positionSpinbox()
// Update lock icon position inside the spinbox if it exists and is visible
if (lockIconLabel && lockIconLabel->isVisible()) {
int iconSize = 14;
int padding = 4;
const QFontMetrics fm(spinBox->fontMetrics());
int iconSize = fm.height();
int padding = spinBox->getMargin();
QSize spinboxSize = spinBox->size();
lockIconLabel->setGeometry(
spinboxSize.width() - iconSize - padding,
@@ -424,6 +431,14 @@ void EditableDatumLabel::setPlacement(const Base::Placement& plc)
label->norm.setValue(SbVec3f(float(RN.x), float(RN.y), float(RN.z)));
}
void EditableDatumLabel::updateGeometry()
{
if (!spinBox) {
return;
}
spinBox->adjustSize();
}
// NOLINTNEXTLINE
void EditableDatumLabel::setColor(SbColor color)
{
@@ -510,56 +525,47 @@ void EditableDatumLabel::setSpinboxVisibleToMouse(bool val)
void EditableDatumLabel::setLockedAppearance(bool locked)
{
if (!locked) {
this->hasFinishedEditing = false;
}
if (!spinBox) {
return;
}
const QFontMetrics fm(spinBox->fontMetrics());
int iconSize = fm.height();
int padding = spinBox->getMargin();
if (locked) {
if (spinBox) {
spinBox->addIconSpace(true);
spinBox->adjustSize();
// create lock icon label it it doesn't exist, if it does - show it
if (!lockIconLabel) {
lockIconLabel = new QLabel(spinBox);
lockIconLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true);
lockIconLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
// create lock icon label it it doesn't exist, if it does - show it
if (!lockIconLabel) {
lockIconLabel = new QLabel(spinBox);
lockIconLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true);
lockIconLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
// load icon and scale it to fit in spinbox
QPixmap lockIcon = Gui::BitmapFactory().pixmap("Constraint_Lock");
QPixmap scaledIcon
= lockIcon.scaled(iconSize, iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
lockIconLabel->setPixmap(scaledIcon);
// load icon and scale it to fit in spinbox
QPixmap lockIcon = Gui::BitmapFactory().pixmap("Constraint_Lock");
QPixmap scaledIcon
= lockIcon.scaled(14, 14, Qt::KeepAspectRatio, Qt::SmoothTransformation);
lockIconLabel->setPixmap(scaledIcon);
// position lock icon inside the spinbox
int iconSize = 14;
int padding = 4;
QSize spinboxSize = spinBox->size();
lockIconLabel->setGeometry(
spinboxSize.width() - iconSize - padding,
(spinboxSize.height() - iconSize) / 2,
iconSize,
iconSize
);
// style spinbox and add padding for lock
QString styleSheet = QString::fromLatin1(
"QSpinBox { "
"padding-right: %1px; "
"}"
)
.arg(iconSize + padding + 2);
spinBox->setStyleSheet(styleSheet);
}
lockIconLabel->show();
// position lock icon inside the spinbox
QSize spinboxSize = spinBox->size();
lockIconLabel->setGeometry(
spinboxSize.width() - iconSize - padding,
(spinboxSize.height() - iconSize) / 2,
iconSize,
iconSize
);
}
lockIconLabel->show();
}
else {
this->hasFinishedEditing = false;
// if spinbox exists, reset its appearance
if (spinBox) {
spinBox->setStyleSheet(QString());
// hide lock icon if it exists for later reuse
if (lockIconLabel) {
lockIconLabel->hide();
}
// hide lock icon if it exists for later reuse
if (lockIconLabel) {
lockIconLabel->hide();
spinBox->addIconSpace(false);
spinBox->adjustSize();
}
}
}
+1
View File
@@ -92,6 +92,7 @@ public:
void setLockedAppearance(bool locked); ///< Sets visual appearance to indicate locked state
///< (finished editing)
void resetLockedState(); ///< Resets both hasFinishedEditing flag and locked appearance
void updateGeometry();
Function getFunction();
+4 -4
View File
@@ -233,7 +233,7 @@ void EditorView::checkTimestamp()
/**
* Runs the action specified by \a pMsg.
*/
bool EditorView::onMsg(const char* pMsg, const char** /*ppReturn*/)
bool EditorView::onMsg(const char* pMsg)
{
// don't allow any actions if the editor is being closed
if (d->aboutToClose) {
@@ -663,7 +663,7 @@ PythonEditorView::~PythonEditorView()
/**
* Runs the action specified by \a pMsg.
*/
bool PythonEditorView::onMsg(const char* pMsg, const char** ppReturn)
bool PythonEditorView::onMsg(const char* pMsg)
{
if (strcmp(pMsg, "Run") == 0) {
executeScript();
@@ -677,7 +677,7 @@ bool PythonEditorView::onMsg(const char* pMsg, const char** ppReturn)
toggleBreakpoint();
return true;
}
return EditorView::onMsg(pMsg, ppReturn);
return EditorView::onMsg(pMsg);
}
/**
@@ -705,7 +705,7 @@ void PythonEditorView::executeScript()
{
// always save the macro when it is modified
if (EditorView::onHasMsg("Save")) {
EditorView::onMsg("Save", nullptr);
EditorView::onMsg("Save");
}
try {
getMainWindow()->setCursor(Qt::WaitCursor);
+2 -2
View File
@@ -76,7 +76,7 @@ public:
void onUpdate() override
{}
bool onMsg(const char* pMsg, const char** ppReturn) override;
bool onMsg(const char* pMsg) override;
bool onHasMsg(const char* pMsg) const override;
bool canClose() override;
@@ -135,7 +135,7 @@ public:
PythonEditorView(PythonEditor* editor, QWidget* parent);
~PythonEditorView() override;
bool onMsg(const char* pMsg, const char** ppReturn) override;
bool onMsg(const char* pMsg) override;
bool onHasMsg(const char* pMsg) const override;
public Q_SLOTS:
+2 -4
View File
@@ -430,10 +430,8 @@ def GeneratePackageIcon(
return
absolute_filename = Path(subdirectory) / Path(relative_filename)
if hasattr(wb_handle, "Icon") and wb_handle.Icon:
Log(
f"Init: Packaged workbench {workbench_metadata.Name} specified icon\
in class {workbench_metadata.Classname}"
)
Log(f"Init: Packaged workbench {workbench_metadata.Name} specified icon\
in class {workbench_metadata.Classname}")
Log(" ... replacing with icon from package.xml data.\n")
wb_handle.__dict__["Icon"] = str(absolute_filename.resolve())
+1 -1
View File
@@ -471,7 +471,7 @@ QByteArray GraphvizView::exportGraph(const QString& format)
return dotProc.readAll();
}
bool GraphvizView::onMsg(const char* pMsg, const char**)
bool GraphvizView::onMsg(const char* pMsg)
{
if (strcmp("Save", pMsg) == 0 || strcmp("SaveAs", pMsg) == 0) {
QList<QPair<QString, QString>> formatMap;
+1 -1
View File
@@ -48,7 +48,7 @@ public:
QByteArray exportGraph(const QString& filter);
/// Message handler
bool onMsg(const char* pMsg, const char** ppReturn) override;
bool onMsg(const char* pMsg) override;
/// Message handler test
bool onHasMsg(const char* pMsg) const override;
/** @name Printing */
+1 -2
View File
@@ -311,9 +311,8 @@ void ImageView::print(QPrinter* printer)
painter.drawPixmap(0, 0, pixmap);
}
bool ImageView::onMsg(const char* pMsg, const char** ppReturn)
bool ImageView::onMsg(const char* pMsg)
{
Q_UNUSED(ppReturn)
if (strcmp("ViewFit", pMsg) == 0) {
fitToWindow(true);
return true;
+1 -1
View File
@@ -48,7 +48,7 @@ public:
}
/// Message handler
bool onMsg(const char* pMsg, const char** ppReturn) override;
bool onMsg(const char* pMsg) override;
/// Message handler test
bool onHasMsg(const char* pMsg) const override;
+2 -2
View File
@@ -315,7 +315,7 @@
<location filename="../Dialogs/DlgCustomizeSpNavSettings.ui" line="318"/>
<location filename="../Dialogs/DlgCustomizeSpNavSettings.ui" line="342"/>
<source>Reverse</source>
<translation>Omvendt</translation>
<translation>Modsat</translation>
</message>
</context>
<context>
@@ -9279,7 +9279,7 @@ i den aktuelle kopi vil gå tabt.
<message>
<location filename="../CommandDoc.cpp" line="434"/>
<source>No selection</source>
<translation>Ingen valg</translation>
<translation>Ingen valgt</translation>
</message>
<message>
<location filename="../CommandDoc.cpp" line="435"/>
+1 -1
View File
@@ -6387,7 +6387,7 @@ sur Alt + bouton droit de la souris OU les touches Pg.Suiv/Pg.Préc du clavier</
<message>
<location filename="../Widgets.cpp" line="409"/>
<source>Press modifier keys</source>
<translation>Appuyez sur les touches de modification</translation>
<translation>Appuyer sur les touches de modificateur</translation>
</message>
</context>
<context>
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -12161,7 +12161,7 @@ the region are non-opaque.</source>
<message>
<location filename="../PreferencePages/DlgSettingsUI.cpp" line="124"/>
<source>No style sheet</source>
<translation type="unfinished">No style sheet</translation>
<translation>Немає таблиці стилів</translation>
</message>
</context>
<context>
@@ -14649,7 +14649,7 @@ This makes the docked panel stay transparent at all times.</translation>
<message>
<location filename="../Dialogs/DlgVersionMigrator.cpp" line="140"/>
<source>Welcome to %1 %2.%3</source>
<translation type="unfinished">Welcome to %1 %2.%3</translation>
<translation>Ласкаво просимо до %1 %2.%3</translation>
</message>
<message>
<location filename="../Dialogs/DlgVersionMigrator.cpp" line="143"/>
+1 -2
View File
@@ -202,10 +202,9 @@ void MDIView::viewAll()
{}
/// receive a message
bool MDIView::onMsg(const char* pMsg, const char** ppReturn)
bool MDIView::onMsg(const char* pMsg)
{
Q_UNUSED(pMsg);
Q_UNUSED(ppReturn);
return false;
}
+1 -1
View File
@@ -81,7 +81,7 @@ public:
void setWindowTitle(const QString& title);
/// Message handler
bool onMsg(const char* pMsg, const char** ppReturn) override;
bool onMsg(const char* pMsg) override;
/// Message handler test
bool onHasMsg(const char* pMsg) const override;
/// overwrite when checking on close state
+1 -2
View File
@@ -179,7 +179,6 @@ Py::Object MDIViewPy::redoActions(const Py::Tuple& args)
Py::Object MDIViewPy::sendMessage(const Py::Tuple& args)
{
const char** ppReturn = nullptr;
char* psMsgStr;
if (!PyArg_ParseTuple(args.ptr(), "s;Message string needed (string)", &psMsgStr)) {
throw Py::Exception();
@@ -188,7 +187,7 @@ Py::Object MDIViewPy::sendMessage(const Py::Tuple& args)
try {
bool ok = false;
if (_view) {
ok = _view->onMsg(psMsgStr, ppReturn);
ok = _view->onMsg(psMsgStr);
}
return Py::Boolean(ok);
}
+3 -3
View File
@@ -212,16 +212,16 @@ PyObject* MDIViewPyWrap::getPyObject()
return MDIView::getPyObject();
}
bool MDIViewPyWrap::onMsg(const char* pMsg, const char** ppReturn)
bool MDIViewPyWrap::onMsg(const char* pMsg)
{
try {
if (ptr->onMsg(pMsg)) {
return true;
}
return MDIView::onMsg(pMsg, ppReturn);
return MDIView::onMsg(pMsg);
}
catch (const std::exception&) {
return MDIView::onMsg(pMsg, ppReturn);
return MDIView::onMsg(pMsg);
}
catch (Py::Exception&) {
Base::PyGILStateLocker lock;
+1 -1
View File
@@ -55,7 +55,7 @@ public:
~MDIViewPyWrap() override;
/// Message handler
bool onMsg(const char* pMsg, const char** ppReturn) override;
bool onMsg(const char* pMsg) override;
/// Message handler test
bool onHasMsg(const char* pMsg) const override;
/// overwrite when checking on close state
+3 -2
View File
@@ -1360,8 +1360,9 @@ void ManualAlignment::probePickedCallback(void* ud, SoEventCallback* n)
Gui::getMainWindow()->showMessage(tr("No point was picked"));
}
}
else if (mbe->getButton() == SoMouseButtonEvent::BUTTON2
&& mbe->getState() == SoButtonEvent::UP) {
else if (
mbe->getButton() == SoMouseButtonEvent::BUTTON2 && mbe->getState() == SoButtonEvent::UP
) {
ManualAlignment* self = ManualAlignment::instance();
if (self->myAlignModel.isEmpty() || self->myFixedGroup.isEmpty()) {
return;
@@ -123,9 +123,11 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent* const ev)
this->seekToPoint(pos); // implicitly calls interactiveCountInc()
processed = true;
}
else if (press
&& (this->currentmode == NavigationStyle::PANNING
|| this->currentmode == NavigationStyle::ZOOMING)) {
else if (
press
&& (this->currentmode == NavigationStyle::PANNING
|| this->currentmode == NavigationStyle::ZOOMING)
) {
newmode = NavigationStyle::DRAGGING;
saveCursorPosition(ev);
this->centerTime = ev->getTime();
+5 -3
View File
@@ -120,9 +120,11 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent* const ev)
this->seekToPoint(pos); // implicitly calls interactiveCountInc()
processed = true;
}
else if (press
&& (this->currentmode == NavigationStyle::PANNING
|| this->currentmode == NavigationStyle::ZOOMING)) {
else if (
press
&& (this->currentmode == NavigationStyle::PANNING
|| this->currentmode == NavigationStyle::ZOOMING)
) {
newmode = NavigationStyle::DRAGGING;
saveCursorPosition(ev);
this->centerTime = ev->getTime();
@@ -129,8 +129,9 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent* const ev)
setupPanningPlane(getCamera());
this->lockrecenter = false;
}
else if (!press && ev->wasShiftDown()
&& (this->currentmode != NavigationStyle::SELECTION)) {
else if (
!press && ev->wasShiftDown() && (this->currentmode != NavigationStyle::SELECTION)
) {
SbTime tmp = (ev->getTime() - this->centerTime);
float dci = (float)QApplication::doubleClickInterval() / 1000.0f;
// is it just a left click?
@@ -325,9 +326,11 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent* const ev)
if (ev->isOfType(SoMouseWheelEvent::getClassTypeId())) {
processed = inherited::processSoEvent(ev);
}
else if ((curmode == NavigationStyle::SELECTION || newmode == NavigationStyle::SELECTION
|| viewer->isEditing())
&& !processed) {
else if (
(curmode == NavigationStyle::SELECTION || newmode == NavigationStyle::SELECTION
|| viewer->isEditing())
&& !processed
) {
processed = inherited::processSoEvent(ev);
}
else {
+5 -3
View File
@@ -125,9 +125,11 @@ SbBool RevitNavigationStyle::processSoEvent(const SoEvent* const ev)
this->seekToPoint(pos); // implicitly calls interactiveCountInc()
processed = true;
}
else if (press
&& (this->currentmode == NavigationStyle::PANNING
|| this->currentmode == NavigationStyle::ZOOMING)) {
else if (
press
&& (this->currentmode == NavigationStyle::PANNING
|| this->currentmode == NavigationStyle::ZOOMING)
) {
newmode = NavigationStyle::DRAGGING;
saveCursorPosition(ev);
this->centerTime = ev->getTime();
@@ -123,9 +123,11 @@ SbBool SolidWorksNavigationStyle::processSoEvent(const SoEvent* const ev)
this->seekToPoint(pos); // implicitly calls interactiveCountInc()
processed = true;
}
else if (press
&& (this->currentmode == NavigationStyle::PANNING
|| this->currentmode == NavigationStyle::ZOOMING)) {
else if (
press
&& (this->currentmode == NavigationStyle::PANNING
|| this->currentmode == NavigationStyle::ZOOMING)
) {
newmode = NavigationStyle::DRAGGING;
saveCursorPosition(ev);
this->centerTime = ev->getTime();
@@ -122,9 +122,11 @@ SbBool TouchpadNavigationStyle::processSoEvent(const SoEvent* const ev)
this->seekToPoint(pos); // implicitly calls interactiveCountInc()
processed = true;
}
else if (press
&& (this->currentmode == NavigationStyle::PANNING
|| this->currentmode == NavigationStyle::ZOOMING)) {
else if (
press
&& (this->currentmode == NavigationStyle::PANNING
|| this->currentmode == NavigationStyle::ZOOMING)
) {
newmode = NavigationStyle::DRAGGING;
saveCursorPosition(ev);
this->centerTime = ev->getTime();
+42 -36
View File
@@ -183,36 +183,38 @@ inline void Gui::Notify(TNotifier&& notifier, TCaption&& caption, TMessage&& mes
// Send also to log for developer only
auto msg = std::string(message).append("\n"); // use untranslated message
if constexpr (std::is_base_of_v<
App::DocumentObject,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
if constexpr (
std::is_base_of_v<App::DocumentObject, std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console()
.send<type, Base::IntendedRecipient::Developer, Base::ContentType::Untranslated>(
notifier->getFullLabel(),
msg.c_str()
);
}
else if constexpr (std::is_base_of_v<
Gui::ViewProviderDocumentObject,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
else if constexpr (
std::is_base_of_v<
Gui::ViewProviderDocumentObject,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console()
.send<type, Base::IntendedRecipient::Developer, Base::ContentType::Untranslated>(
notifier->getObject()->getFullLabel(),
msg.c_str()
);
}
else if constexpr (std::is_base_of_v<
Gui::Document,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
else if constexpr (
std::is_base_of_v<Gui::Document, std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console()
.send<type, Base::IntendedRecipient::Developer, Base::ContentType::Untranslated>(
notifier->getDocument()->Label.getStrValue(),
msg.c_str()
);
}
else if constexpr (std::is_base_of_v<
App::Document,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
else if constexpr (
std::is_base_of_v<App::Document, std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console()
.send<type, Base::IntendedRecipient::Developer, Base::ContentType::Untranslated>(
notifier->Label.getStrValue(),
@@ -269,30 +271,32 @@ inline void Gui::Notify(TNotifier&& notifier, TCaption&& caption, TMessage&& mes
// trailing newline is not necessary as translated messages are not shown in logs
auto msg = QStringLiteral("%1. %2").arg(caption).arg(message); // QString
if constexpr (std::is_base_of_v<
App::DocumentObject,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
if constexpr (
std::is_base_of_v<App::DocumentObject, std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console().send<type, recipient, content>(notifier->getFullLabel(), msg.toUtf8());
}
else if constexpr (std::is_base_of_v<
Gui::ViewProviderDocumentObject,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
else if constexpr (
std::is_base_of_v<
Gui::ViewProviderDocumentObject,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console().send<type, recipient, content>(
notifier->getObject()->getFullLabel(),
msg.toUtf8()
);
}
else if constexpr (std::is_base_of_v<
Gui::Document,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
else if constexpr (
std::is_base_of_v<Gui::Document, std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console().send<type, recipient, content>(
notifier->getDocument()->Label.getStrValue(),
msg.toUtf8()
);
}
else if constexpr (std::is_base_of_v<
App::Document,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
else if constexpr (
std::is_base_of_v<App::Document, std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console().send<type, recipient, content>(
notifier->Label.getStrValue(),
msg.toUtf8()
@@ -307,30 +311,32 @@ inline void Gui::Notify(TNotifier&& notifier, TCaption&& caption, TMessage&& mes
// (depending on the configuration).
auto msg = std::string(message).append("\n");
if constexpr (std::is_base_of_v<
App::DocumentObject,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
if constexpr (
std::is_base_of_v<App::DocumentObject, std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console().send<type, recipient, content>(notifier->getFullLabel(), msg.c_str());
}
else if constexpr (std::is_base_of_v<
Gui::ViewProviderDocumentObject,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
else if constexpr (
std::is_base_of_v<
Gui::ViewProviderDocumentObject,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console().send<type, recipient, content>(
notifier->getObject()->getFullLabel(),
msg.c_str()
);
}
else if constexpr (std::is_base_of_v<
Gui::Document,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
else if constexpr (
std::is_base_of_v<Gui::Document, std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console().send<type, recipient, content>(
notifier->getDocument()->Label.getStrValue(),
msg.c_str()
);
}
else if constexpr (std::is_base_of_v<
App::Document,
std::remove_pointer_t<typename std::decay<TNotifier>::type>>) {
else if constexpr (
std::is_base_of_v<App::Document, std::remove_pointer_t<typename std::decay<TNotifier>::type>>
) {
Base::Console().send<type, recipient, content>(
notifier->Label.getStrValue(),
msg.c_str()
+15 -8
View File
@@ -1807,8 +1807,10 @@ bool OverlayManager::eventFilter(QObject* o, QEvent* ev)
if (auto titleBar = qobject_cast<OverlayTitleBar*>(OverlayTabWidget::_Dragging)) {
titleBar->endDrag();
}
else if (auto splitHandle
= qobject_cast<OverlaySplitterHandle*>(OverlayTabWidget::_Dragging)) {
else if (
auto splitHandle
= qobject_cast<OverlaySplitterHandle*>(OverlayTabWidget::_Dragging)
) {
splitHandle->endDrag();
}
}
@@ -1861,8 +1863,9 @@ bool OverlayManager::eventFilter(QObject* o, QEvent* ev)
if (auto titleBar = qobject_cast<OverlayTitleBar*>(OverlayTabWidget::_Dragging)) {
titleBar->endDrag();
}
else if (auto splitHandle
= qobject_cast<OverlaySplitterHandle*>(OverlayTabWidget::_Dragging)) {
else if (
auto splitHandle = qobject_cast<OverlaySplitterHandle*>(OverlayTabWidget::_Dragging)
) {
splitHandle->endDrag();
}
}
@@ -1909,8 +1912,10 @@ bool OverlayManager::eventFilter(QObject* o, QEvent* ev)
// probably do not matter.
return true;
}
else if (ev->type() != QEvent::MouseButtonPress && ev->type() != QEvent::MouseButtonDblClick
&& QApplication::mouseButtons() != Qt::NoButton) {
else if (
ev->type() != QEvent::MouseButtonPress && ev->type() != QEvent::MouseButtonDblClick
&& QApplication::mouseButtons() != Qt::NoButton
) {
return false;
}
@@ -1925,8 +1930,10 @@ bool OverlayManager::eventFilter(QObject* o, QEvent* ev)
&& pos == d->_lastPos) {
hit = 1;
}
else if (ev->type() == QEvent::Wheel && !d->wheelDelay.isNull()
&& (isNear(pos, d->wheelPos) || d->wheelDelay > QTime::currentTime())) {
else if (
ev->type() == QEvent::Wheel && !d->wheelDelay.isNull()
&& (isNear(pos, d->wheelPos) || d->wheelDelay > QTime::currentTime())
) {
d->wheelDelay = QTime::currentTime().addMSecs(
OverlayParams::getDockOverlayWheelDelay()
);
+13 -24
View File
@@ -19,6 +19,7 @@
# * *
# ***************************************************************************
"""Auto code generator for overlay widgets related parameters in Preferences/View"""
import cog
import inspect, sys
from os import path
@@ -101,12 +102,10 @@ class ParamAnimationCurve(ParamProxy):
def init_widget(self, param, row, group_name):
super().init_widget(param, row, group_name)
cog.out(
f"""
cog.out(f"""
{auto_comment()}
for (const auto &item : OverlayParams::AnimationCurveTypes)
{param.widget_name}->addItem(item);"""
)
{param.widget_name}->addItem(item);""")
cog.out(
f"""
{param.widget_name}->setCurrentIndex({param.namespace}::{param.class_name}::default{param.name}());"""
@@ -295,40 +294,30 @@ Params = [
def declare():
cog.out(
f"""
cog.out(f"""
{auto_comment()}
#include <QString>
"""
)
""")
params_utils.declare_begin(sys.modules[__name__])
cog.out(
f"""
cog.out(f"""
{auto_comment()}
static const std::vector<QString> AnimationCurveTypes;
"""
)
""")
params_utils.declare_end(sys.modules[__name__])
def define():
params_utils.define(sys.modules[__name__])
cog.out(
f"""
cog.out(f"""
{auto_comment()}
const std::vector<QString> OverlayParams::AnimationCurveTypes = {{"""
)
const std::vector<QString> OverlayParams::AnimationCurveTypes = {{""")
for item in AnimationCurveTypes:
cog.out(
f"""
QStringLiteral("{item}"),"""
)
cog.out(
f"""
cog.out(f"""
QStringLiteral("{item}"),""")
cog.out(f"""
}};
"""
)
""")
params_utils.init_params(Params, NameSpace, ClassName, ParamPath)
+4 -2
View File
@@ -1549,8 +1549,10 @@ void OverlayTabWidget::setOverlayMode(bool enable)
if (!enable && isTransparent()) {
option = OverlayOption::ShowTab;
}
else if (enable && !isTransparent()
&& (autoMode == AutoMode::EditShow || autoMode == AutoMode::AutoHide)) {
else if (
enable && !isTransparent()
&& (autoMode == AutoMode::EditShow || autoMode == AutoMode::AutoHide)
) {
option = OverlayOption::Disable;
}
else {
+4 -2
View File
@@ -548,8 +548,10 @@ static void copyTemplateParameters(
}
}
static void copyTemplateParameters(/*const*/ ParameterManager& templateParameterManager,
ParameterManager& outputParameterManager)
static void copyTemplateParameters(
/*const*/ ParameterManager& templateParameterManager,
ParameterManager& outputParameterManager
)
{
auto groups = templateParameterManager.GetGroups();
for (auto& group : groups) {
@@ -19,6 +19,7 @@
# * *
# ***************************************************************************
"""Auto code generator for preference page of Display/UI"""
import cog, sys
from os import path
+4 -2
View File
@@ -585,8 +585,10 @@ void PythonConsole::keyPressEvent(QKeyEvent* e)
|| e->matches(QKeySequence::SelectAll)) {
PythonTextEditor::keyPressEvent(e);
}
else if (!e->text().isEmpty()
&& (e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::ShiftModifier)) {
else if (
!e->text().isEmpty()
&& (e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::ShiftModifier)
) {
this->moveCursor(QTextCursor::End);
PythonTextEditor::keyPressEvent(e);
}
+99 -26
View File
@@ -66,6 +66,9 @@ public:
, pendingEmit(false)
, normalize(true)
, checkRangeInExpression(false)
, adjustableWidth(false)
, maxExpectedDigits(4)
, addIconSpace(false)
, unitValue(0)
, maximum(std::numeric_limits<double>::max())
, minimum(-std::numeric_limits<double>::max())
@@ -306,6 +309,9 @@ public:
bool pendingEmit;
bool normalize;
bool checkRangeInExpression;
bool adjustableWidth;
int maxExpectedDigits;
bool addIconSpace;
QString validStr;
Base::Quantity quantity;
Base::Quantity cached;
@@ -341,6 +347,9 @@ void QuantitySpinBox::bind(const App::ObjectIdentifier& _path)
void QuantitySpinBox::showIcon()
{
addIconSpace(true);
adjustSize();
iconLabel->show();
}
@@ -444,6 +453,19 @@ void QuantitySpinBox::resizeEvent(QResizeEvent* event)
{
QAbstractSpinBox::resizeEvent(event);
resizeWidget();
moveCursor();
}
void QuantitySpinBox::moveCursor()
{
Q_D(QuantitySpinBox);
QLineEdit* edit = lineEdit();
int cursor = edit->cursorPosition();
const int maxCursor = qMax(0, edit->displayText().size() - 1 /*space*/ - d->unitStr.size());
if (cursor > maxCursor) {
edit->setCursorPosition(maxCursor);
}
}
void Gui::QuantitySpinBox::keyPressEvent(QKeyEvent* event)
@@ -467,6 +489,9 @@ void Gui::QuantitySpinBox::keyPressEvent(QKeyEvent* event)
if (isEnter) {
returnPressed();
}
else {
moveCursor();
}
}
void Gui::QuantitySpinBox::paintEvent(QPaintEvent*)
@@ -504,7 +529,7 @@ void QuantitySpinBox::updateEdit(const QString& text)
edit->setSelection(0, cursor);
}
else {
edit->setCursorPosition(empty ? 0 : cursor);
moveCursor();
}
}
@@ -601,6 +626,42 @@ void QuantitySpinBox::setAutoNormalize(bool normalize)
d->normalize = normalize;
}
bool QuantitySpinBox::autoAdjustWidth() const
{
Q_D(const QuantitySpinBox);
return d->adjustableWidth;
}
void QuantitySpinBox::setAutoAdjustWidth(bool adjust)
{
Q_D(QuantitySpinBox);
d->adjustableWidth = adjust;
}
bool QuantitySpinBox::isIconSpaceAdded() const
{
Q_D(const QuantitySpinBox);
return d->addIconSpace;
}
void QuantitySpinBox::addIconSpace(bool addIconSpace)
{
Q_D(QuantitySpinBox);
d->addIconSpace = addIconSpace;
}
int QuantitySpinBox::getMaxExpectedDigits()
{
Q_D(const QuantitySpinBox);
return d->maxExpectedDigits;
}
void QuantitySpinBox::setMaxExpectedDigits(int digits)
{
Q_D(QuantitySpinBox);
d->maxExpectedDigits = digits;
}
bool QuantitySpinBox::hasValidInput() const
{
Q_D(const QuantitySpinBox);
@@ -611,7 +672,6 @@ bool QuantitySpinBox::hasValidInput() const
void QuantitySpinBox::userInput(const QString& text)
{
Q_D(QuantitySpinBox);
d->pendingEmit = true;
QString tmp = text;
@@ -911,44 +971,57 @@ QSize QuantitySpinBox::sizeForText(const QString& txt) const
QSize QuantitySpinBox::sizeHint() const
{
return sizeHintCalculator(lineEdit()->sizeHint().height());
Q_D(const QuantitySpinBox);
auto le = lineEdit();
if (le && d->adjustableWidth) {
// limit number of typed characters to keep unit visible
le->setMaxLength(getMaxStrLength(d->maxExpectedDigits));
}
return sizeHintForDigits(d->maxExpectedDigits);
}
QSize QuantitySpinBox::minimumSizeHint() const
{
return sizeHintCalculator(lineEdit()->minimumSizeHint().height());
}
QSize QuantitySpinBox::sizeHintCalculator(int h) const
QSize QuantitySpinBox::sizeHintForDigits(int digits) const
{
Q_D(const QuantitySpinBox);
ensurePolished();
const int maxLen = getMaxStrLength(digits);
int length = maxLen;
if (d->adjustableWidth) {
int currenLen = qMax(lineEdit()->text().length(), 4);
length = currenLen < maxLen ? currenLen : maxLen;
}
QString longestString = QStringLiteral("8").repeated(length);
const QFontMetrics fm(fontMetrics());
int w = 0;
constexpr int maxStrLen = 9;
QString s;
QString fixedContent = QLatin1String(" ");
Base::Quantity q(d->quantity);
q.setValue(d->maximum);
s = textFromValue(q);
s.truncate(maxStrLen);
s += fixedContent;
w = qMax(w, QtTools::horizontalAdvance(fm, s));
w += 2; // cursor blinking space
w += iconHeight;
int w = qMax(0, QtTools::horizontalAdvance(fm, longestString));
w += 4; // cursor blinking space
if (d->addIconSpace) {
w += iconHeight;
}
QStyleOptionSpinBox opt;
initStyleOption(&opt);
QSize hint(w, h);
QSize hint(w, lineEdit()->sizeHint().height());
QSize size = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this);
return size;
}
int QuantitySpinBox::getMaxStrLength(int digits) const
{
// Calculates the length of the longest string allowed
Q_D(const QuantitySpinBox);
ensurePolished();
QString unit = QString::fromStdString(d->unit.getString());
int decimals = App::GetApplication()
.GetUserParameter()
.GetGroup("BaseApp/Preferences/Units")
->GetInt("Decimals", 2);
return digits + 1 /*separator*/ + decimals + 1 /*space*/ + unit.length();
}
void QuantitySpinBox::showEvent(QShowEvent* event)
{
Q_D(QuantitySpinBox);
+28 -2
View File
@@ -54,6 +54,15 @@ class GuiExport QuantitySpinBox: public QAbstractSpinBox, public ExpressionSpinB
Q_PROPERTY(
bool autoNormalize READ autoNormalize WRITE setAutoNormalize
) // clazy:exclude=qproperty-without-notify
Q_PROPERTY(
bool autoAdjustWidth READ autoAdjustWidth WRITE setAutoAdjustWidth
) // clazy:exclude=qproperty-without-notify
Q_PROPERTY(
bool addIconSpace READ isIconSpaceAdded WRITE addIconSpace
) // clazy:exclude=qproperty-without-notify
Q_PROPERTY(
int maxExpectedDigits READ getMaxExpectedDigits WRITE setMaxExpectedDigits
) // clazy:exclude=qproperty-without-notify
public:
explicit QuantitySpinBox(QWidget* parent = nullptr);
@@ -99,6 +108,11 @@ public:
/// Sets the value of the maximum property
void setMaximum(double max);
/// Adjust how many digits in the integer part we should expect
/// Affects minimum size if width is not adjustable
void setMaxExpectedDigits(int digits);
int getMaxExpectedDigits();
/// Gets the number of decimals
int decimals() const;
/// Sets the number of decimals
@@ -109,6 +123,16 @@ public:
/// Enables or disables automatic normalization on enter
void setAutoNormalize(bool normalize);
/// Returns if automatic width adjustment is enabled for this input
bool autoAdjustWidth() const;
/// Enables or disables automatic width adjustement
void setAutoAdjustWidth(bool adjust);
/// Returns if icon space is added for this input
bool isIconSpaceAdded() const;
/// Enables or disables icon space addition
void addIconSpace(bool addIconSpace);
/// Sets a specific unit schema to handle quantities.
/// The system-wide schema won't be used any more.
void setSchema(int s);
@@ -142,7 +166,6 @@ public:
/// This is a helper function to determine the size this widget requires to fully display the text
QSize sizeForText(const QString&) const;
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
bool event(QEvent* event) override;
void setNumberExpression(App::NumberExpression*) override;
@@ -175,13 +198,16 @@ protected:
void paintEvent(QPaintEvent* event) override;
private:
void moveCursor();
void validateInput() override;
void updateText(const Base::Quantity&);
void updateEdit(const QString& text);
void updateFromCache(bool notify, bool updateUnit = true);
QString getUserString(const Base::Quantity& val, double& factor, QString& unitString) const;
QString getUserString(const Base::Quantity& val) const;
QSize sizeHintCalculator(int height) const;
QSize sizeHintForDigits(int digits) const;
int getMaxStrLength(int digits) const;
Q_SIGNALS:
/** Gets emitted if the user has entered a VALID input
+6 -10
View File
@@ -2499,7 +2499,9 @@ PyObject* SelectionSingleton::sAddSelection(PyObject* /*self*/, PyObject* args)
char* docname;
char* subname = nullptr;
float x = 0, y = 0, z = 0;
if (PyArg_ParseTuple(args, "ss|sfffO!", &docname, &objname, &subname, &x, &y, &z, &PyBool_Type, &clearPreselect)) {
if (
PyArg_ParseTuple(args, "ss|sfffO!", &docname, &objname, &subname, &x, &y, &z, &PyBool_Type, &clearPreselect)
) {
Selection()
.addSelection(docname, objname, subname, x, y, z, nullptr, Base::asBoolean(clearPreselect));
Py_Return;
@@ -2593,15 +2595,9 @@ PyObject* SelectionSingleton::sUpdateSelection(PyObject* /*self*/, PyObject* arg
PyObject* show;
PyObject* object;
char* subname = nullptr;
if (!PyArg_ParseTuple(
args,
"O!O!|s",
&PyBool_Type,
&show,
&(App::DocumentObjectPy::Type),
&object,
&subname
)) {
if (
!PyArg_ParseTuple(args, "O!O!|s", &PyBool_Type, &show, &(App::DocumentObjectPy::Type), &object, &subname)
) {
return nullptr;
}
+8 -4
View File
@@ -264,8 +264,10 @@ int yyi;
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
# if (defined __cplusplus && !defined _STDLIB_H \
&& !((defined YYMALLOC || defined malloc) && (defined YYFREE || defined free)))
# if ( \
defined __cplusplus && !defined _STDLIB_H \
&& !((defined YYMALLOC || defined malloc) && (defined YYFREE || defined free)) \
)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef _STDLIB_H
# define _STDLIB_H 1
@@ -289,8 +291,10 @@ void free(void*); /* INFRINGES ON USER NAME SPACE */
#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
#if (!defined yyoverflow \
&& (!defined __cplusplus || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
#if ( \
!defined yyoverflow \
&& (!defined __cplusplus || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)) \
)
/* A type that is properly aligned for any stack member. */
union yyalloc
+1 -1
View File
@@ -687,7 +687,7 @@ void SelectionView::onItemContextMenu(const QPoint& point)
void SelectionView::onUpdate()
{}
bool SelectionView::onMsg(const char* /*pMsg*/, const char** /*ppReturn*/)
bool SelectionView::onMsg(const char* /*pMsg*/)
{
return false;
}
+1 -1
View File
@@ -75,7 +75,7 @@ public:
void leaveEvent(QEvent*) override;
bool onMsg(const char* pMsg, const char** ppReturn) override;
bool onMsg(const char* pMsg) override;
const char* getName() const override
{
+4 -2
View File
@@ -188,8 +188,10 @@ void SoFCSelection::doAction(SoAction* action)
}
}
}
else if (selaction->getType() == Gui::SoSelectionElementAction::None
|| selaction->getType() == Gui::SoSelectionElementAction::Remove) {
else if (
selaction->getType() == Gui::SoSelectionElementAction::None
|| selaction->getType() == Gui::SoSelectionElementAction::Remove
) {
SelContextPtr ctx
= Gui::SoFCSelectionRoot::getActionContext(action, this, selContext, false);
if (ctx && ctx->isSelected()) {
+9 -6
View File
@@ -1130,9 +1130,11 @@ void SoBoxSelectionRenderAction::apply(SoNode* node)
}
PRIVATE(this)->selectsearch->reset();
}
else if (selection->isHighlighted()
&& selection->selected.getValue() == SoFCSelection::NOTSELECTED
&& selection->style.getValue() == SoFCSelection::BOX) {
else if (
selection->isHighlighted()
&& selection->selected.getValue() == SoFCSelection::NOTSELECTED
&& selection->style.getValue() == SoFCSelection::BOX
) {
PRIVATE(this)->basecolor->rgb.setValue(selection->colorHighlight.getValue());
if (!PRIVATE(this)->selectsearch) {
@@ -1177,9 +1179,10 @@ void SoBoxSelectionRenderAction::apply(SoPath* path)
// because this will destroy the box immediately
selection->touch(); // force a redraw when dehighlighting
}
else if (selection->isHighlighted()
&& selection->selected.getValue() == SoFCSelection::NOTSELECTED
&& selection->style.getValue() == SoFCSelection::BOX) {
else if (
selection->isHighlighted() && selection->selected.getValue() == SoFCSelection::NOTSELECTED
&& selection->style.getValue() == SoFCSelection::BOX
) {
PRIVATE(this)->basecolor->rgb.setValue(selection->colorHighlight.getValue());
if (!PRIVATE(this)->selectsearch) {
+15 -8
View File
@@ -380,8 +380,10 @@ void SoFCUnifiedSelection::doAction(SoAction* action)
currentHighlightPath = nullptr;
}
}
else if (preselectionMode.getValue() != OFF
&& preselectAction->SelChange.Type == SelectionChanges::SetPreselect) {
else if (
preselectionMode.getValue() != OFF
&& preselectAction->SelChange.Type == SelectionChanges::SetPreselect
) {
if (currentHighlightPath) {
SoHighlightElementAction highlightAction;
highlightAction.apply(currentHighlightPath);
@@ -529,8 +531,10 @@ void SoFCUnifiedSelection::doAction(SoAction* action)
selectionAction.apply(this->getChild(i));
}
}
else if (selectionMode.getValue() == ON
&& selectionAction->SelChange.Type == SelectionChanges::SetSelection) {
else if (
selectionMode.getValue() == ON
&& selectionAction->SelChange.Type == SelectionChanges::SetSelection
) {
std::vector<ViewProvider*> vps;
if (this->pcDocument) {
vps = this->pcDocument->getViewProvidersOfType(
@@ -921,8 +925,10 @@ void SoFCUnifiedSelection::handleEvent(SoHandleEventAction* action)
}
}
// mouse press events for (de)selection
else if (event->isOfType(SoMouseButtonEvent::getClassTypeId())
&& selectionMode.getValue() == SoFCUnifiedSelection::ON) {
else if (
event->isOfType(SoMouseButtonEvent::getClassTypeId())
&& selectionMode.getValue() == SoFCUnifiedSelection::ON
) {
const auto e = static_cast<const SoMouseButtonEvent*>(event);
if (SoMouseButtonEvent::isButtonReleaseEvent(e, SoMouseButtonEvent::BUTTON1)) {
// check to see if the mouse is over a geometry...
@@ -1810,8 +1816,9 @@ bool SoFCSelectionRoot::doActionPrivate(Stack& stack, SoAction* action)
return true;
}
}
else if (action->getWhatAppliedTo() != SoAction::NODE
&& action->getCurPathCode() != SoAction::BELOW_PATH) {
else if (
action->getWhatAppliedTo() != SoAction::NODE && action->getCurPathCode() != SoAction::BELOW_PATH
) {
return true;
}
+4 -2
View File
@@ -246,8 +246,10 @@ public:
|| label->datumtype.getValue() == SoDatumLabel::DISTANCEY) {
corners = computeDistanceBBox();
}
else if (label->datumtype.getValue() == SoDatumLabel::RADIUS
|| label->datumtype.getValue() == SoDatumLabel::DIAMETER) {
else if (
label->datumtype.getValue() == SoDatumLabel::RADIUS
|| label->datumtype.getValue() == SoDatumLabel::DIAMETER
) {
corners = computeRadiusDiameterBBox();
}
else if (label->datumtype.getValue() == SoDatumLabel::ANGLE) {
+1 -1
View File
@@ -45,6 +45,7 @@ public:
void bind(const App::ObjectIdentifier& _path) override;
void setExpression(std::shared_ptr<App::Expression> expr) override;
int getMargin();
protected:
/*! Expression handling */
@@ -65,7 +66,6 @@ protected:
virtual void showIcon();
virtual void validateInput();
void resizeWidget();
int getMargin();
bool handleKeyEvent(const QString&);
virtual void openFormulaDialog();
+9 -9
View File
@@ -141,7 +141,7 @@ const char* AbstractSplitView::getName() const
return "SplitView3DInventor";
}
bool AbstractSplitView::onMsg(const char* pMsg, const char**)
bool AbstractSplitView::onMsg(const char* pMsg)
{
if (strcmp("ViewFit", pMsg) == 0) {
viewAll();
@@ -374,7 +374,7 @@ Py::Object AbstractSplitViewPy::fitAll(const Py::Tuple& args)
}
try {
getSplitViewPtr()->onMsg("ViewFit", nullptr);
getSplitViewPtr()->onMsg("ViewFit");
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
@@ -395,7 +395,7 @@ Py::Object AbstractSplitViewPy::viewBottom(const Py::Tuple& args)
}
try {
getSplitViewPtr()->onMsg("ViewBottom", nullptr);
getSplitViewPtr()->onMsg("ViewBottom");
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
@@ -417,7 +417,7 @@ Py::Object AbstractSplitViewPy::viewFront(const Py::Tuple& args)
}
try {
getSplitViewPtr()->onMsg("ViewFront", nullptr);
getSplitViewPtr()->onMsg("ViewFront");
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
@@ -439,7 +439,7 @@ Py::Object AbstractSplitViewPy::viewLeft(const Py::Tuple& args)
}
try {
getSplitViewPtr()->onMsg("ViewLeft", nullptr);
getSplitViewPtr()->onMsg("ViewLeft");
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
@@ -461,7 +461,7 @@ Py::Object AbstractSplitViewPy::viewRear(const Py::Tuple& args)
}
try {
getSplitViewPtr()->onMsg("ViewRear", nullptr);
getSplitViewPtr()->onMsg("ViewRear");
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
@@ -483,7 +483,7 @@ Py::Object AbstractSplitViewPy::viewRight(const Py::Tuple& args)
}
try {
getSplitViewPtr()->onMsg("ViewRight", nullptr);
getSplitViewPtr()->onMsg("ViewRight");
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
@@ -505,7 +505,7 @@ Py::Object AbstractSplitViewPy::viewTop(const Py::Tuple& args)
}
try {
getSplitViewPtr()->onMsg("ViewTop", nullptr);
getSplitViewPtr()->onMsg("ViewTop");
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
@@ -527,7 +527,7 @@ Py::Object AbstractSplitViewPy::viewIsometric(const Py::Tuple& args)
}
try {
getSplitViewPtr()->onMsg("ViewAxo", nullptr);
getSplitViewPtr()->onMsg("ViewAxo");
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
+1 -1
View File
@@ -55,7 +55,7 @@ public:
const char* getName() const override;
/// Message handler
bool onMsg(const char* pMsg, const char** ppReturn) override;
bool onMsg(const char* pMsg) override;
bool onHasMsg(const char* pMsg) const override;
void onUpdate() override;
void deleteSelf() override;
+2 -4
View File
@@ -326,8 +326,7 @@ void TaskTransform::updatePositionAndRotationUi() const
auto setPositionValues = [&](const Base::Vector3d& vec, auto* x, auto* y, auto* z) {
[[maybe_unused]]
auto blockers
= {QSignalBlocker(x), QSignalBlocker(y), QSignalBlocker(z)};
auto blockers = {QSignalBlocker(x), QSignalBlocker(y), QSignalBlocker(z)};
x->setValue(fixNegativeZero(vec.x));
y->setValue(fixNegativeZero(vec.y));
@@ -336,8 +335,7 @@ void TaskTransform::updatePositionAndRotationUi() const
auto setRotationValues = [&](const Base::Rotation& rot, auto* x, auto* y, auto* z) {
[[maybe_unused]]
auto blockers
= {QSignalBlocker(x), QSignalBlocker(y), QSignalBlocker(z)};
auto blockers = {QSignalBlocker(x), QSignalBlocker(y), QSignalBlocker(z)};
double alpha, beta, gamma;
rot.getEulerAngles(eulerSequence(), alpha, beta, gamma);
+1 -3
View File
@@ -177,10 +177,8 @@ bool TextDocumentEditorView::onHasMsg(const char* msg) const
return false;
}
bool TextDocumentEditorView::onMsg(const char* msg, const char** output)
bool TextDocumentEditorView::onMsg(const char* msg)
{
Q_UNUSED(output)
// don't allow any actions if the editor is being closed
if (aboutToClose) {
return false;
+1 -1
View File
@@ -44,7 +44,7 @@ public:
{
return "TextDocumentEditorView";
}
bool onMsg(const char* msg, const char** output) override;
bool onMsg(const char* msg) override;
bool onHasMsg(const char* msg) const override;
QPlainTextEdit* getEditor() const
+4 -2
View File
@@ -628,8 +628,10 @@ int ToolBarManager::toolBarIconSize(QWidget* widget) const
s *= 0.6;
}
}
else if (widget->parentWidget() == menuBarLeftAreaWidget
|| widget->parentWidget() == menuBarRightAreaWidget) {
else if (
widget->parentWidget() == menuBarLeftAreaWidget
|| widget->parentWidget() == menuBarRightAreaWidget
) {
if (_menuBarIconSize > 0) {
s = _menuBarIconSize;
}
+8 -9
View File
@@ -2232,8 +2232,10 @@ Qt::DropAction getDropAction(int size, const int type)
if (QApplication::keyboardModifiers() == Qt::ControlModifier) {
return Qt::CopyAction;
}
else if (QApplication::keyboardModifiers() == Qt::AltModifier
&& (size == 1 || type == TreeWidget::DocumentType)) {
else if (
QApplication::keyboardModifiers() == Qt::AltModifier
&& (size == 1 || type == TreeWidget::DocumentType)
) {
return Qt::LinkAction;
}
else {
@@ -4746,13 +4748,10 @@ void DocumentItem::populateItem(DocumentObjectItem* item, bool refresh, bool del
auto it = ObjectMap.find(child);
if (it == ObjectMap.end() || it->second->items.empty()) {
auto vp = getViewProvider(child);
if (!vp
|| !createNewItem(
*vp,
item,
i,
it == ObjectMap.end() ? DocumentObjectDataPtr() : it->second
)) {
if (
!vp
|| !createNewItem(*vp, item, i, it == ObjectMap.end() ? DocumentObjectDataPtr() : it->second)
) {
--i;
}
else {
+1
View File
@@ -19,6 +19,7 @@
# * *
# ***************************************************************************
"""Auto code generator for parameters in Preferences/TreeView"""
import sys
from os import path
+1 -1
View File
@@ -104,7 +104,7 @@ public:
return "Base view";
}
/// Message handler
virtual bool onMsg(const char* pMsg, const char** ppReturn) = 0;
virtual bool onMsg(const char* pMsg) = 0;
/// Message handler test
virtual bool onHasMsg(const char* pMsg) const = 0;
/// overwrite when checking on close state
+11 -18
View File
@@ -58,6 +58,7 @@
#include <Gui/PreferencePages/DlgSettingsPDF.h>
#include "View3DInventor.h"
#include "Base/Exception.h"
#include "View3DSettings.h"
#include "Application.h"
#include "BitmapFactory.h"
@@ -350,7 +351,7 @@ bool View3DInventor::containsViewProvider(const ViewProvider* vp) const
// **********************************************************************************
bool View3DInventor::onMsg(const char* pMsg, const char** ppReturn)
bool View3DInventor::onMsg(const char* pMsg)
{
if (strcmp("ViewFit", pMsg) == 0) {
_viewer->viewAll();
@@ -385,17 +386,6 @@ bool View3DInventor::onMsg(const char* pMsg, const char** ppReturn)
_viewer->setStereoMode(Quarter::SoQTQuarterAdaptor::MONO);
return true;
}
else if (strcmp("GetCamera", pMsg) == 0) {
SoCamera* Cam = _viewer->getSoRenderManager()->getCamera();
if (!Cam) {
return false;
}
*ppReturn = SoFCDB::writeNodesToString(Cam).c_str();
return true;
}
else if (strncmp("SetCamera", pMsg, 9) == 0) {
return setCamera(pMsg + 10);
}
else if (strncmp("Dump", pMsg, 4) == 0) {
dump(pMsg + 5);
return true;
@@ -561,12 +551,6 @@ bool View3DInventor::onHasMsg(const char* pMsg) const
else if (strcmp("ViewAxo", pMsg) == 0) {
return true;
}
else if (strcmp("GetCamera", pMsg) == 0) {
return true;
}
else if (strncmp("SetCamera", pMsg, 9) == 0) {
return true;
}
else if (strncmp("Dump", pMsg, 4) == 0) {
return true;
}
@@ -586,6 +570,15 @@ bool View3DInventor::onHasMsg(const char* pMsg) const
return false;
}
const std::string& View3DInventor::getCamera() const
{
SoCamera* Cam = _viewer->getSoRenderManager()->getCamera();
if (!Cam) {
throw Base::RuntimeError("Could not find reference to 3D View camera");
}
return SoFCDB::writeNodesToString(Cam);
}
bool View3DInventor::setCamera(const char* pCamera)
{
SoCamera* CamViewer = _viewer->getSoRenderManager()->getCamera();
+2 -1
View File
@@ -96,7 +96,7 @@ public:
View3DInventor* clone() override;
/// Message handler
bool onMsg(const char* pMsg, const char** ppReturn) override;
bool onMsg(const char* pMsg) override;
bool onHasMsg(const char* pMsg) const override;
void deleteSelf() override;
/// get called when the document is updated
@@ -121,6 +121,7 @@ public:
*/
void setCurrentViewMode(ViewMode b) override;
RayPickInfo getObjInfoRay(Base::Vector3d* startvec, Base::Vector3d* dirvec);
const std::string& getCamera() const;
bool setCamera(const char* pCamera);
void toggleClippingPlane();
bool hasClippingPlane() const;
+9 -5
View File
@@ -416,8 +416,10 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType& rCaller, ParameterGrp::
_viewer->setEnabledNaviCube(rGrp.GetBool("ShowNaviCube", true));
}
}
else if (strcmp(Reason, "AxisXColor") == 0 || strcmp(Reason, "AxisYColor") == 0
|| strcmp(Reason, "AxisZColor") == 0) {
else if (
strcmp(Reason, "AxisXColor") == 0 || strcmp(Reason, "AxisYColor") == 0
|| strcmp(Reason, "AxisZColor") == 0
) {
for (auto _viewer : _viewers) {
_viewer->updateColors();
}
@@ -653,9 +655,11 @@ void NaviCubeSettings::parameterChanged(const char* Name)
float opacity = static_cast<float>(hGrp->GetInt("InactiveOpacity", 50)) / 100;
nc->setInactiveOpacity(opacity);
}
else if (strcmp(Name, "TextTop") == 0 || strcmp(Name, "TextBottom") == 0
|| strcmp(Name, "TextFront") == 0 || strcmp(Name, "TextRear") == 0
|| strcmp(Name, "TextLeft") == 0 || strcmp(Name, "TextRight") == 0) {
else if (
strcmp(Name, "TextTop") == 0 || strcmp(Name, "TextBottom") == 0
|| strcmp(Name, "TextFront") == 0 || strcmp(Name, "TextRear") == 0
|| strcmp(Name, "TextLeft") == 0 || strcmp(Name, "TextRight") == 0
) {
std::vector<std::string> labels;
QByteArray frontByteArray = tr("FRONT").toUtf8();
labels.push_back(hGrp->GetASCII("TextFront", frontByteArray.constData()));
+8 -4
View File
@@ -363,16 +363,20 @@ Base::Rotation Gui::ViewProviderDragger::orthonormalize(
z = x.Cross(y);
z.Normalize();
}
else if (components.testFlag(Gui::ViewProviderDragger::DraggerComponent::XRot)
&& components.testFlag(Gui::ViewProviderDragger::DraggerComponent::ZRot)) {
else if (
components.testFlag(Gui::ViewProviderDragger::DraggerComponent::XRot)
&& components.testFlag(Gui::ViewProviderDragger::DraggerComponent::ZRot)
) {
x.Normalize();
z = z - x * (x * z);
z.Normalize();
y = z.Cross(x);
y.Normalize();
}
else if (components.testFlag(Gui::ViewProviderDragger::DraggerComponent::YRot)
&& components.testFlag(Gui::ViewProviderDragger::DraggerComponent::ZRot)) {
else if (
components.testFlag(Gui::ViewProviderDragger::DraggerComponent::YRot)
&& components.testFlag(Gui::ViewProviderDragger::DraggerComponent::ZRot)
) {
y.Normalize();
z = z - y * (y * z);
z.Normalize();
+4 -2
View File
@@ -393,8 +393,10 @@ void ViewProviderGeometryObject::handleChangedPropertyName(
prop.Restore(reader);
ShapeAppearance.setDiffuseColor(prop.getValue());
}
else if (strcmp(PropName, "ShapeMaterial") == 0
&& strcmp(TypeName, App::PropertyMaterial::getClassTypeId().getName()) == 0) {
else if (
strcmp(PropName, "ShapeMaterial") == 0
&& strcmp(TypeName, App::PropertyMaterial::getClassTypeId().getName()) == 0
) {
App::PropertyMaterial prop;
prop.Restore(reader);
ShapeAppearance.setValue(prop.getValue());
+3 -2
View File
@@ -126,8 +126,9 @@ void ViewProviderInventorObject::updateData(const App::Property* prop)
}
}
}
else if (prop->isDerivedFrom<App::PropertyPlacement>()
&& strcmp(prop->getName(), "Placement") == 0) {
else if (
prop->isDerivedFrom<App::PropertyPlacement>() && strcmp(prop->getName(), "Placement") == 0
) {
// Note: If R is the rotation, c the rotation center and t the translation
// vector then Inventor applies the following transformation: R*(x-c)+c+t
// In FreeCAD a placement only has a rotation and a translation part but
+11 -1
View File
@@ -1173,15 +1173,25 @@ void LinkView::renderDoubleSide(bool enable)
{
if (!pcShapeHints) {
pcShapeHints = new SoShapeHints;
pcShapeHints->shapeType = SoShapeHints::SOLID;
// Explicitly ignore fields we don't want to override.
pcShapeHints->shapeType.setIgnored(true);
pcShapeHints->faceType.setIgnored(true);
pcShapeHints->creaseAngle.setIgnored(true);
pcLinkRoot->insertChild(pcShapeHints, 0);
}
// Set the proper winding order based on the transform determinant
if (enable) {
pcShapeHints->vertexOrdering = SoShapeHints::CLOCKWISE;
}
else {
pcShapeHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
}
// Force the override, but because the other fields are ignored,
// this will ONLY override the vertexOrdering.
pcShapeHints->setOverride(true);
}
+3 -1
View File
@@ -226,7 +226,9 @@ PyObject* ViewProviderPy::canDropObject(PyObject* args, PyObject* kw)
PyObject* pyElements = Py_None;
const char* subname = nullptr;
static const std::array<const char*, 5> kwlist {"obj", "owner", "subname", "elem", nullptr};
if (!Base::Wrapped_ParseTupleAndKeywords(args, kw, "|OOsO", kwlist, &obj, &owner, &subname, &pyElements)) {
if (
!Base::Wrapped_ParseTupleAndKeywords(args, kw, "|OOsO", kwlist, &obj, &owner, &subname, &pyElements)
) {
return nullptr;
}
+3 -2
View File
@@ -252,8 +252,9 @@ void ViewProviderVRMLObject::updateData(const App::Property* prop)
SoInput::removeDirectory(subpath.constData());
}
}
else if (prop->isDerivedFrom<App::PropertyPlacement>()
&& strcmp(prop->getName(), "Placement") == 0) {
else if (
prop->isDerivedFrom<App::PropertyPlacement>() && strcmp(prop->getName(), "Placement") == 0
) {
// Note: If R is the rotation, c the rotation center and t the translation
// vector then Inventor applies the following transformation: R*(x-c)+c+t
// In FreeCAD a placement only has a rotation and a translation part but
+3 -2
View File
@@ -1206,8 +1206,9 @@ bool ToolTip::eventFilter(QObject* o, QEvent* e)
// removeEventFilter();
this->hidden = true;
}
else if (e->type() == QEvent::Timer && !this->hidden
&& displayTime.elapsed() < 5000) {
else if (
e->type() == QEvent::Timer && !this->hidden && displayTime.elapsed() < 5000
) {
return true;
}
}
+8 -4
View File
@@ -1285,8 +1285,10 @@ bool PropertyEditor::eventFilter(QObject* object, QEvent* event)
}
}
}
else if (mouse_event->type() == QEvent::MouseButtonPress
&& mouse_event->button() == Qt::LeftButton && !dragInProgress) {
else if (
mouse_event->type() == QEvent::MouseButtonPress
&& mouse_event->button() == Qt::LeftButton && !dragInProgress
) {
if (indexResizable(mouse_event->pos()).isValid()) {
dragInProgress = true;
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -1298,8 +1300,10 @@ bool PropertyEditor::eventFilter(QObject* object, QEvent* event)
return true;
}
}
else if (mouse_event->type() == QEvent::MouseButtonRelease
&& mouse_event->button() == Qt::LeftButton && dragInProgress) {
else if (
mouse_event->type() == QEvent::MouseButtonRelease
&& mouse_event->button() == Qt::LeftButton && dragInProgress
) {
dragInProgress = false;
auto hGrp = App::GetApplication().GetParameterGroupByPath(
+4 -4
View File
@@ -222,8 +222,7 @@ DistanceType getDistanceType(App::DocumentObject* joint)
}
}
else if (isFaceType(obj1, elt1, GeomAbs_Cylinder)
|| isFaceType(obj2, elt2, GeomAbs_Cylinder)) {
else if (isFaceType(obj1, elt1, GeomAbs_Cylinder) || isFaceType(obj2, elt2, GeomAbs_Cylinder)) {
if (!isFaceType(obj1, elt1, GeomAbs_Cylinder)) {
swapJCS(joint); // make sure cylinder is first if its not 2 cylinders.
std::swap(elt1, elt2);
@@ -789,8 +788,9 @@ void collectComponentsRecursively(
}
}
else if (obj->isDerivedFrom<App::GeoFeature>()
&& !obj->isDerivedFrom<App::LocalCoordinateSystem>()) {
else if (
obj->isDerivedFrom<App::GeoFeature>() && !obj->isDerivedFrom<App::LocalCoordinateSystem>()
) {
results.push_back(obj);
}
}
-1
View File
@@ -38,7 +38,6 @@ if App.GuiUp:
import UtilsAssembly
import Preferences
__title__ = "Assembly Command Create Exploded View"
__author__ = "Ondsel"
__url__ = "https://www.freecad.org"
-1
View File
@@ -36,7 +36,6 @@ import UtilsAssembly
import Preferences
import CommandCreateJoint
__title__ = "Assembly Command Insert Component"
__author__ = "Ondsel"
__url__ = "https://www.freecad.org"
-1
View File
@@ -33,7 +33,6 @@ if App.GuiUp:
import UtilsAssembly
import Assembly_rc
__title__ = "Assembly Command to Solve Assembly"
__author__ = "Ondsel"
__url__ = "https://www.freecad.org"
+66
View File
@@ -298,6 +298,71 @@ bool CmdAssemblySelectComponentsWithDoFs::isActive()
return getActiveAssembly() != nullptr;
}
// ================================================================================
// Select Joints of Component
// ================================================================================
DEF_STD_CMD_A(CmdAssemblySelectJointsOfComponent)
CmdAssemblySelectJointsOfComponent::CmdAssemblySelectJointsOfComponent()
: Command("Assembly_SelectJointsOfComponent")
{
sGroup = QT_TR_NOOP("Assembly");
sMenuText = QT_TR_NOOP("Select component joints");
sToolTipText = QT_TR_NOOP("Selects all joints referencing the selected component");
sWhatsThis = "Assembly_SelectJointsOfComponent";
sStatusTip = sToolTipText;
sPixmap = "Assembly_SelectJointsOfComponent";
eType = ForEdit;
}
void CmdAssemblySelectJointsOfComponent::activated(int iMsg)
{
Q_UNUSED(iMsg);
AssemblyObject* assembly = getActiveAssembly();
if (!assembly) {
return;
}
auto selection = Gui::Selection().getSelectionEx(
"",
App::DocumentObject::getClassTypeId(),
Gui::ResolveMode::NoResolve
);
if (selection.empty()) {
return;
}
std::set<App::DocumentObject*> components;
App::Document* doc = assembly->getDocument();
for (auto& sel : selection) {
const std::vector<std::string> subs = sel.getSubNames();
std::string sub = subs.empty() ? "" : subs.front();
if (App::DocumentObject* comp = getMovingPartFromSel(assembly, sel.getObject(), sub)) {
components.insert(comp);
}
}
if (components.empty()) {
return;
}
std::vector<App::DocumentObject*> jointsToSelect;
for (auto* comp : components) {
std::vector<App::DocumentObject*> partJoints = assembly->getJointsOfPart(comp);
jointsToSelect.insert(jointsToSelect.end(), partJoints.begin(), partJoints.end());
}
selectObjects(jointsToSelect);
}
bool CmdAssemblySelectJointsOfComponent::isActive()
{
return getActiveAssembly() != nullptr && !Gui::Selection().getSelection().empty();
}
// ================================================================================
// Command Creation
@@ -312,4 +377,5 @@ void AssemblyGui::CreateAssemblyCommands()
rcCmdMgr.addCommand(new CmdAssemblySelectRedundantConstraints());
rcCmdMgr.addCommand(new CmdAssemblySelectMalformedConstraints());
rcCmdMgr.addCommand(new CmdAssemblySelectComponentsWithDoFs());
rcCmdMgr.addCommand(new CmdAssemblySelectJointsOfComponent());
}
@@ -23,6 +23,7 @@
<file>icons/Assembly_CreateJointRackPinion.svg</file>
<file>icons/Assembly_CreateJointScrew.svg</file>
<file>icons/Assembly_ExportASMT.svg</file>
<file>icons/Assembly_SelectJointsOfComponent.svg</file>
<file>icons/Assembly_SolveAssembly.svg</file>
<file>icons/Assembly_JointGroup.svg</file>
<file>icons/Assembly_ExplodedView.svg</file>
@@ -0,0 +1,446 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="64"
height="64"
version="1.1"
viewBox="0 0 64 64"
id="svg96"
sodipodi:docname="Assembly_SelectJointsOfComponent.svg"
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="1571"
id="namedview98"
showgrid="false"
inkscape:zoom="7.375"
inkscape:cx="-46.033898"
inkscape:cy="36.135593"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="svg96"
inkscape:pagecheckerboard="0"
inkscape:showpageshadow="0"
inkscape:deskcolor="#505050ff" />
<defs
id="defs26">
<linearGradient
id="linearGradient5">
<stop
style="stop-color:#3465a4;stop-opacity:1;"
offset="0"
id="stop3" />
<stop
style="stop-color:#729fcf;stop-opacity:1;"
offset="1"
id="stop5" />
</linearGradient>
<linearGradient
id="linearGradient4383">
<stop
stop-color="#3465a4"
offset="0"
id="stop2" />
<stop
stop-color="#729fcf"
offset="1"
id="stop4" />
</linearGradient>
<linearGradient
id="linearGradient4389"
x1="20.244"
x2="17.244"
y1="37.588"
y2="27.588"
gradientTransform="translate(-1.2435,-2.5881)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3774" />
<linearGradient
id="linearGradient4399"
x1="48.714"
x2="44.714"
y1="45.586"
y2="34.586"
gradientTransform="translate(1.2856,1.4142)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#c4a000"
offset="0"
id="stop8" />
<stop
stop-color="#edd400"
offset="1"
id="stop10" />
</linearGradient>
<linearGradient
id="linearGradient69042"
x1="48.714"
x2="44.714"
y1="45.586"
y2="34.586"
gradientTransform="translate(-12.714,-17.586)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3774" />
<linearGradient
id="linearGradient69056"
x1="27.244"
x2="22.244"
y1="54.588"
y2="40.588"
gradientTransform="translate(-1.2435,-2.5881)"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#c4a000"
offset="0"
id="stop14" />
<stop
stop-color="#fce94f"
offset="1"
id="stop16" />
</linearGradient>
<linearGradient
id="linearGradient69709"
x1="20.244"
x2="17.244"
y1="37.588"
y2="27.588"
gradientTransform="matrix(1,-0.026667,0,1,-4.9583303,13.035246)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4383" />
<linearGradient
id="linearGradient69717"
x1="50.714"
x2="48.714"
y1="25.586"
y2="20.586"
gradientTransform="translate(-25.42873,19.444346)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4383" />
<linearGradient
id="linearGradient3774">
<stop
stop-color="#4e9a06"
offset="0"
id="stop21" />
<stop
stop-color="#8ae234"
offset="1"
id="stop23" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient4383"
id="linearGradient14"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.21101776,-0.38855873,0.36549348,-0.22433449,55.738696,89.232256)"
x1="74.090889"
y1="36.438313"
x2="98.940155"
y2="39.402027"
spreadMethod="reflect" />
<linearGradient
xlink:href="#linearGradient4383"
id="linearGradient1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.21101776,-0.38855873,0.36549348,-0.22433449,49.945687,92.628304)"
x1="74.090889"
y1="36.438313"
x2="98.940155"
y2="39.402027"
spreadMethod="reflect" />
<linearGradient
xlink:href="#linearGradient3801-5"
id="linearGradient3807"
x1="74.090889"
y1="36.438313"
x2="98.940155"
y2="39.402027"
gradientUnits="userSpaceOnUse"
spreadMethod="reflect"
gradientTransform="matrix(0.91296596,0,0,0.91296596,-53.260025,-10.845327)" />
<linearGradient
id="linearGradient3801-5">
<stop
style="stop-color:#c4a000;stop-opacity:1"
offset="0"
id="stop3803-3" />
<stop
style="stop-color:#fce94f;stop-opacity:1"
offset="1"
id="stop3805-5" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5"
id="linearGradient3807-8"
x1="110"
y1="35"
x2="85"
y2="35"
gradientUnits="userSpaceOnUse"
spreadMethod="reflect"
gradientTransform="matrix(0.46639319,0,0,0.46639319,3.7503584,-8.1314081)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3801-5"
id="linearGradient2"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-61,-0.19620034)"
x1="110"
y1="35"
x2="85"
y2="35"
spreadMethod="reflect" />
</defs>
<metadata
id="metadata28">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Path-Stock</dc:title>
<dc:date>2015-07-04</dc:date>
<dc:relation>https://www.freecad.org/wiki/index.php?title=Artwork</dc:relation>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/Path/Gui/Resources/icons/Path-Stock.svg</dc:identifier>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="g1"
transform="translate(0.86290997,0.28763666)">
<path
d="m 4.3456697,51.908746 -0.02739,-38.214 12.9670003,4.3352 v 38.5 z"
id="path54"
style="fill:url(#linearGradient69709);stroke:#0b1521;stroke-width:2;stroke-linejoin:round"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
d="m 6.2726697,50.437746 0.04731,-34.141 8.9272003,3.29 0.0781,34.042 z"
id="path56"
inkscape:connector-curvature="0"
style="fill:none;stroke:#729fcf;stroke-width:2"
sodipodi:nodetypes="ccccc" />
<path
d="m 17.28567,56.529746 v -38.5 l 11,-9 0.06,37.379 z"
id="path58"
style="fill:url(#linearGradient69717);stroke:#0b1521;stroke-width:2;stroke-linejoin:round"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
d="m 19.28567,52.029746 v -33 l 7,-6 -0.0122,32.5816 z"
id="path60"
inkscape:connector-curvature="0"
style="fill:none;stroke:#729fcf;stroke-width:2"
sodipodi:nodetypes="ccccc" />
<path
d="m 4.3186697,13.694746 11.0270003,-9.2862 12.94,4.6214 -11,9 z"
id="path62"
inkscape:connector-curvature="0"
style="fill:#729fcf;stroke:#0b1521;stroke-width:2;stroke-linejoin:round"
sodipodi:nodetypes="ccccc" />
</g>
<g
display="none"
fill="#ef2929"
fill-rule="evenodd"
opacity=".588"
stroke="#ef2929"
stroke-width="1px"
id="g94">
<path
d="m9 35v14"
id="path66" />
<path
d="m9 35 28 10"
id="path68" />
<path
d="m55 28v13"
id="path70" />
<path
d="m37 45 18-17"
id="path72" />
<path
d="m23 40v-14"
id="path74" />
<path
d="m29 5 13 5"
id="path76" />
<path
d="m23 26 19-16"
id="path78" />
<path
d="m19 13 10-8"
id="path80" />
<path
d="m55 15-9 8"
id="path82" />
<path
d="m42 23v-13"
id="path84" />
<path
d="m42 23 14 5"
id="path86" />
<path
d="m23 40 19-17"
id="path88" />
<path
d="m23 10h19"
id="path90" />
<path
d="m34 17v13"
id="path92" />
</g>
<path
style="fill:#729fcf;stroke:#302b00;stroke-width:0.920557;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 49.530247,32.427747 c 1.614852,-0.991172 5.191369,2.380453 7.988374,7.530734 2.797006,5.150281 3.75533,10.128913 2.140479,11.120085 L 50.923166,56.440554 40.794313,37.789735 Z"
id="path10" />
<path
style="fill:url(#linearGradient14);fill-opacity:1;stroke:#729fcf;stroke-width:0.920557;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 49.48711,33.490382 c 1.468047,-0.901066 4.736602,2.195675 7.300525,6.916768 2.563921,4.721092 3.452303,9.27875 1.984256,10.179816 l -7.632608,4.684783 -9.284782,-17.096585 z"
id="path11" />
<path
style="fill:none;stroke:#fce94f;stroke-width:0.920557;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 42.745026,37.628573 c 1.618196,0.04293 4.005615,2.644344 6.569538,7.365438 2.563921,4.721091 3.27835,7.831285 2.715243,9.731146"
id="path12" />
<ellipse
style="fill:#fce94f;stroke:#302b00;stroke-width:0.806052;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dasharray:none;stroke-dashoffset:20.4;stroke-opacity:1"
id="ellipse12"
cx="-64.233864"
cy="17.839087"
rx="10.611865"
ry="3.4307916"
transform="matrix(-0.47724187,-0.87877198,0.85226618,-0.52310837,0,0)" />
<path
style="fill:url(#linearGradient1);fill-opacity:1;stroke:#729fcf;stroke-width:0.920557;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 43.694101,36.88643 c 1.468047,-0.901066 4.736602,2.195675 7.300525,6.916768 2.563922,4.721091 3.589396,9.354221 2.121349,10.255286"
id="path1" />
<g
id="g3"
transform="matrix(-0.23113431,-0.42560046,0.40033637,-0.24572054,40.478828,68.374637)"
style="stroke-width:1.05775">
<path
style="fill:#fce94f;stroke:#302b00;stroke-width:1.93138;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 53.556993,35.317428 c 0,4.033737 -9.809971,7.303728 -21.911183,7.303728 -12.101212,0 -21.9111824,-3.269991 -21.9111824,-7.303728 l -1.8e-6,-21.821485 H 53.556992 Z"
id="path2994-3" />
<path
style="fill:url(#linearGradient3807);fill-opacity:1;stroke:#fce94f;stroke-width:1.93138;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 51.73106,34.155472 c 0,3.667033 -8.992468,6.639752 -20.085251,6.639752 -11.092778,0 -20.085251,-2.972719 -20.085251,-6.639752 l -1e-6,-19.06549 H 51.73106 Z"
id="path2994-3-6" />
<path
style="fill:none;stroke:#fce94f;stroke-width:1.93138;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 51.73106,17.314424 c -1.825932,2.987888 -8.992468,4.81382 -20.085251,4.81382 -11.092778,0 -17.346353,-1.825932 -20.085251,-4.81382"
id="path2994-3-6-9" />
<ellipse
style="fill:#fce94f;stroke:#302b00;stroke-width:1.68995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dasharray:none;stroke-dashoffset:20.4;stroke-opacity:1"
id="path2994"
cx="31.645807"
cy="13.495944"
rx="21.911182"
ry="7.3037271" />
</g>
<g
id="g3894"
transform="matrix(-0.28197722,0.1854423,-0.1854423,-0.28197722,63.457932,47.485473)">
<path
id="path3034"
style="fill:#cc0000;stroke:#280000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 39.727861,59.856357 -7.931696,1.051156 16.468003,13.415414 9.308602,-16.824452 -7.931071,1.047948 c 0,0 -4.769344,-11.438514 -4.482124,-23.814377 0.28722,-12.375864 2.122864,-21.560053 5.002308,-27.8806611 L 58.035007,8.2705416 49.401308,-9.8243533 32.447357,3.658281 40.32048,5.0774383 c -2.215519,7.1939257 -4.944461,17.7161567 -5.097129,29.4339847 -0.152668,11.717827 4.50451,25.344934 4.50451,25.344934 z" />
<path
id="path3034-3"
style="fill:none;stroke:#ef2929;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 42.294596,61.458559 36.569302,62.26303 47.6973,71.281842 53.888294,59.977938 47.993171,60.40505 c 0,0 -5.098096,-12.019738 -4.755572,-25.591292 C 43.580123,21.242204 44.972361,12.57644 49.056995,4.8823104 L 54.501933,5.7523283 48.673377,-6.64344 37.040489,2.5499919 l 5.69744,1.262008 C 40.115582,12.087163 37.884178,20.2052 37.277916,34.520587 c -0.606263,14.315386 5.01668,26.937972 5.01668,26.937972 z" />
</g>
<g
id="g1-2"
inkscape:label="Part"
transform="matrix(0.46639319,0,0,0.46639319,32.200343,1.1012781)">
<path
style="fill:#fce94f;stroke:#302b00;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 56.000001,52.8038 c 0,4.418278 -10.745166,8 -24,8 -13.254833,0 -23.9999985,-3.581722 -23.9999985,-8 l -2e-6,-22.788679 L 56,30.015122 Z"
id="path2994-3-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sscccs" />
<path
style="fill:url(#linearGradient2);fill-opacity:1;stroke:#fce94f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 54,51.531073 c 0,4.016616 -9.84973,7.272727 -22,7.272727 -12.150264,0 -21.999999,-3.256111 -21.999999,-7.272727 l -1.5e-6,-17.675951 H 54 Z"
id="path2994-3-6-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sscccs" />
<path
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 53.883463,36.735122 c -2.106548,1.373238 -5.918402,2.880001 -9.403465,3.127242 l -0.005,9.10552 c 0,0 -4.321609,1.454482 -12.474967,1.454482 -8.153358,0 -12.5599,-1.348891 -12.5599,-1.348891 l 0.07989,-9.211111 c -2.251676,-0.247241 -6.445502,-1.207241 -9.370239,-3.127242"
id="path2994-3-6-9-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccczccc" />
<ellipse
style="fill:#fce94f;stroke:#302b00;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dasharray:none;stroke-dashoffset:20.4;stroke-opacity:1"
id="path2994-1"
cx="32"
cy="31.700123"
ry="7.9999995"
rx="24" />
</g>
<path
d="m 52.040371,18.21664 0.01255,4.919407 c 0,0 -1.478401,0.544511 -4.927996,0.520661 -3.449596,-0.02385 -4.928002,-0.520661 -4.928002,-0.520661 l -0.01084,-4.923169"
style="fill:none;fill-opacity:1;stroke:#302b00;stroke-width:1.03602;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
id="path1-6"
sodipodi:nodetypes="ccscc" />
<path
style="fill:#729fcf;fill-opacity:1;stroke:#0b1521;stroke-width:0.932786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 58.318362,15.100126 c -10e-7,1.531479 -2.768068,2.847452 -6.727467,3.42234 l 0.0114,4.045106 c 0,0 -1.343214,0.447737 -4.477373,0.428126 -3.134159,-0.01961 -4.477378,-0.428126 -4.477378,-0.428126 l -0.0098,-4.0482 C 38.689693,17.942866 35.931526,16.628863 35.931526,15.100126 V 8.0909575 h 22.386873 z"
id="path1-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="scczcccccs" />
<path
style="fill:url(#linearGradient3807-8);fill-opacity:1;stroke:#729fcf;stroke-width:0.783541;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dasharray:none;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 57.422886,14.652388 c 0.0089,1.461235 -2.759506,2.658723 -6.678752,3.135924 V 21.722 c 0,0 -1.048334,0.363129 -3.619211,0.363129 -2.570876,0 -3.544589,-0.267179 -3.544589,-0.267179 v -3.952999 c -3.837888,-0.49083 -6.678748,-1.770602 -6.678748,-3.212563 l -0.03731,-6.0976626 h 20.5213 z"
id="path2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="scczcccccs" />
<path
style="fill:none;stroke:#729fcf;stroke-width:0.932786;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dashoffset:20.4;stroke-opacity:1"
d="m 57.385575,10.07277 c -0.932786,1.526377 -4.593847,2.459164 -10.26065,2.459164 -5.6668,0 -8.861471,-0.932787 -10.26065,-2.459164"
id="path3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc" />
<ellipse
style="fill:#729fcf;fill-opacity:1;stroke:#0b1521;stroke-width:0.816188;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dasharray:none;stroke-dashoffset:20.4;stroke-opacity:1"
id="ellipse3"
cx="47.124924"
cy="7.9952431"
rx="11.193437"
ry="3.7311454" />
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

@@ -763,7 +763,7 @@ SLOPE definerer udglatnigen af overgangen mellem henholdsvis 0 og H1 og H2 til 0
<message>
<location filename="../panels/TaskAssemblyCreateJoint.ui" line="234"/>
<source>Reverse</source>
<translation>Omvendt</translation>
<translation>Modsat</translation>
</message>
<message>
<location filename="../panels/TaskAssemblyCreateJoint.ui" line="245"/>
File diff suppressed because it is too large Load Diff
@@ -1476,12 +1476,12 @@ The files are named "runPreDrag.asmt" and "dragging.log" and are located in the
<message>
<location filename="../../../CommandInsertLink.py" line="219"/>
<source>Partially loaded</source>
<translation type="unfinished">Partially loaded</translation>
<translation>Частково завантажено</translation>
</message>
<message>
<location filename="../../../CommandInsertLink.py" line="609"/>
<source>Fully load document</source>
<translation type="unfinished">Fully load document</translation>
<translation>Завантажити документ повністю</translation>
</message>
</context>
<context>

Some files were not shown because too many files have changed in this diff Show More