Skip to content

Commit 274621a

Browse files
committed
Technical: genral fix of whitespace, headers
1 parent b7ccf96 commit 274621a

8 files changed

+78
-56
lines changed

technical/ChecklistForNewFeatureC++.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
layout: default
3+
---
4+
15
# Checklist for adding a new feature to an existing workbench in C++
26

37
This checklist is intended as an aid to contributors.

technical/CreatePythonBindingForCpp.md

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
# Background
1+
---
2+
layout: default
3+
---
4+
5+
# Create a Python Binding for C++
6+
7+
## Background
28

39
It becomes necessary at times to expand the FreeCAD API further by exposing functions that are available in the source code in c++ to the python. This process is generally referred to as creating a binding.
410

@@ -18,7 +24,7 @@ The XML file YourClassPy.xml provides information about the functions and attrib
1824

1925
For this example, we will look at the wrapper for the Base::Axis C++ class. The XML description file begins with:
2026

21-
```XML
27+
```xml
2228
<GenerateModel xmlns:xsi##"http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation##"generateMetaModel_Module.xsd">
2329
<PythonExport
2430
Father##"PyObjectBase"
@@ -42,7 +48,7 @@ For this example, we will look at the wrapper for the Base::Axis C++ class. The
4248

4349
Following this preamble, a list of methods and attributes is given. The format of a method is:
4450

45-
```XML
51+
```xml
4652
<Methode Name##"move">
4753
<Documentation>
4854
<UserDocu>
@@ -55,7 +61,7 @@ Following this preamble, a list of methods and attributes is given. The format o
5561

5662
The format of an attribute is:
5763

58-
```XML
64+
```xml
5965
<Attribute Name##"Direction" ReadOnly##"false">
6066
<Documentation>
6167
<UserDocu>Direction vector of the Axis</UserDocu>
@@ -66,24 +72,25 @@ The format of an attribute is:
6672

6773
For an attribute, if "ReadOnly" is false, you will provide both a getter and a setter function. If it is true, only a getter is allowed. In this case we will be required to provide two functions in the implementation C++ file:
6874

69-
```C++
75+
```cpp
7076
Py::Object AxisPy::getDirection(void) const
77+
````
7178
7279
and:
7380
81+
```cpp
7482
void AxisPy::setDirection(Py::Object arg)
7583
```
7684
85+
## Implementation C++ File
7786
78-
## Implementation Cplusplus File
79-
80-
The implementation C++ file YourClassPyImp.cpp provides the "glue" that connects the C++ and Python structures together, effectively translating from one language to the other. The FreeCAD C++-to-Python system provides a number of C++ classes that map to their corresponding Python type. The most fundamental of these is the incode|Py::Object class -- rarely created directly, this class provides the base of the inheritance tree, and is used as the return type for any function that is returning Python data.
87+
The implementation C++ file `YourClassPyImp.cpp` provides the "glue" that connects the C++ and Python structures together, effectively translating from one language to the other. The FreeCAD C++-to-Python system provides a number of C++ classes that map to their corresponding Python type. The most fundamental of these is the incode `Py::Object` class - rarely created directly, this class provides the base of the inheritance tree, and is used as the return type for any function that is returning Python data.
8188
8289
### Include Files
8390
8491
Your C++ implementation file will include the following files:
8592
86-
```C++
93+
```cpp
8794
#include "PreCompiled.h"
8895
8996
#include "YourClass.h"
@@ -99,7 +106,7 @@ Of course, you may include whatever other C++ headers your code requires to func
99106
100107
Your C++ implementation must contain the definition of the PyInit function: for example, for the Axis class wrapper, this is
101108
102-
```C++
109+
```cpp
103110
int AxisPy::PyInit(PyObject* args, PyObject* /*kwd*/)
104111
105112
//Within this function you will most likely need to parse incoming arguments to the constructor: the most important function for this purpose is the Python-provided incode|PyArg_ParseTuple. It takes in the
@@ -123,7 +130,6 @@ For a complete list of format specifiers see [https://docs.python.org/3/c-api/ar
123130
* PyArg_VaParse (PyObject *, const char *, va_list);
124131
* PyArg_VaParseTupleAndKeywords (PyObject *, PyObject *, const char *, char **, va_list);
125132
126-
127133
## Another Explanation
128134
129135
The basic structure of a program to expose functionality to Python is something like this:
@@ -147,14 +153,10 @@ There is a convention for return values from our C++/Python connections:
147153
* xxxxxPyImp routines return a PyObject* pointer (see TopoShapePyImp.cpp)
148154
* AppmyModulePy.cpp routines return a Py::Object (see https://github.com/FreeCAD/FreeCAD/blob/master/src/Mod/Part/App/AppPartPy.cpp and FreeCAD/src/Mod/Part/AppPartPy.cpp.
149155
150-
151156
## See also
152157
153158
* [https://forum.freecadweb.org/viewtopic.php?p##314796#p314617]
154159
* [https://forum.freecadweb.org/viewtopic.php?p##560639#p560639] Forum discussion: Adding Commands in Python to C++ Workbench
155160
* [https://forum.freecadweb.org/viewtopic.php?f##10&t##70750] Another forum thread
156161
* (./Workbench creation.md)
157162
* [https://github.com/FreeCAD/FreeCAD/commit/20b86e55b8dd1873f4c19e036d047528c9ff7f4e] Commit 20b86e5, exposing OCC's precision methods to Python
158-
159-
160-

technical/SourceTreeBasics.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,18 @@
22
layout: default
33
mermaid: true
44
---
5-
# "Partial View of the FreeCAD Source Tree"
65

7-
"A picture of the most commonly encountered branches of the tree."
6+
# Partial View of the FreeCAD Source Tree
7+
8+
A picture of the most commonly encountered branches of the tree.
89

910
{{page.mermaid}}
1011

1112
The full FreeCAD source tree has many other branches, but most Contributors will
1213
only need to deal with these:
1314

14-
1515
![The FreeCAD Source Tree](./SourceTreeBasics.svg)
1616

17-
1817
```mermaid
1918
graph LR
2019
A[src] --- B[App: Documents, DocumentObjects, EventPropagation]
@@ -28,4 +27,3 @@ graph LR
2827
E --- I["..."]
2928
end
3029
```
31-

technical/TheApplicationModule.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
---
22
layout: default
3-
mermaid: true
43
---
54

6-
# "The Application Module"
5+
# The Application Module
76

8-
"An overview of application module structure."
7+
An overview of application module structure.
98

10-
The functionality of FreeCAD is separated into Modules. Some Modules are built into FreeCAD and some are Extension Modules (a form of plug-in). Once installed, Extension Modules behave exactly as built-in Modules.
9+
The functionality of FreeCAD is separated into Modules. Some Modules are built into FreeCAD and some are Extension Modules (a form of plug-in). Once installed, Extension Modules behave exactly as built-in Modules.
1110

12-
Application Modules provide specialized functions and may store specialized data. Examples of Application Modules are Arch (for buildings) and Sketcher (for drawing Sketches).
11+
Application Modules provide specialized functions and may store specialized data. Examples of Application Modules are Arch (for buildings) and Sketcher (for drawing Sketches).
1312

1413
Application Modules are almost always divided into two parts: App which manages the relevant document objects and operations on them, and Gui which handles the display.
1514

technical/developerglossary.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
---
22
layout: default
33
---
4-
# "Developer's Glossary"
54

6-
"Some terms that a developer may run across."
5+
# Developer's Glossary
76

8-
Note that there may be subtle differences in how some terms are used by deveopers vs how they are used by users.
7+
Some terms that a developer may run across.
98

9+
Note that there may be subtle differences in how some terms are used by deveopers vs how they are used by users.
1010

1111
* Binding: the mechanism for linking C++ functionality to and from Python.
1212
* CI (Continuous Integration): the mechanism by which Pull Requests are automatically built and unit tested.
@@ -17,9 +17,6 @@ Note that there may be subtle differences in how some terms are used by deveoper
1717
* Pull Request: how a contributor indicates that they have a change to be merged
1818
* ViewProvider: an object that provides painting services for a Feature. The ViewProvider is notified of changes in a Features properties and, if the change affects the visual representation of the Feature, updates the display. Note that in some modules (ex TechDraw with the Qt GraphicsFramework) there is another layer of functionality that manages the painting.
1919

20-
21-
22-
2320
## See Also
2421

2522
* [FreeCAD glossary wiki entry](https://wiki.freecad.org/Glossary)

technical/index.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
---
22
layout: default
33
---
4+
45
# Technical
56

67
Technical information of interest to Contributors.
78

8-
99
## The Basics
10+
1011
- [Developer's Glossary](./developerglossary.md)
1112
- [Source Tree Basics](./SourceTreeBasics.md)
1213
- [The Application Module](./TheApplicationModule.md)
@@ -19,8 +20,8 @@ Technical information of interest to Contributors.
1920
- [Coin3d](https://www.coin3d.org/): a [scenegraph](https://wiki.freecad.org/Scenegraph) manager based on OpenInventor that handles drawing in the 3d window.
2021
- [Pivy](https://wiki.freecad.org/Pivy): a Python binding for Coin3d
2122

22-
2323
## Modifying FreeCAD
24+
2425
- Contributing to FreeCAD
2526
- The process for submitting changes to FreeCAD is described in the [CONTRIBUTING.md](https://github.com/FreeCAD/FreeCAD/blob/master/CONTRIBUTING.md)
2627
file in the root of the source tree.
@@ -30,11 +31,8 @@ Technical information of interest to Contributors.
3031
- [Create a Python Binding for C++ Class](./CreatePythonBindingForCpp.md)
3132
- [Checklist for Adding a Feature to a Workbench in C++](./ChecklistForNewFeatureC++.md)
3233

34+
## See Also
3335

34-
35-
36-
37-
### See Also
3836
- [Wiki Developer Hub](https://wiki.freecad.org/Developer_hub)
3937
- [Compiling](https://wiki.freecad.org/Developer_hub#Compiling_FreeCAD)
4038
- [Useful Python Modules](https://wiki.freecad.org/Extra_python_modules)

technical/preferences.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
---
22
layout: default
33
---
4+
45
# Handling Preferences
56

6-
How to retrieve and update user preferences
7+
How to retrieve and update user preferences.
78

8-
The user.cfg Xml file contains a hierarchical list of all the preferences used by FreeCAD.
9+
The `user.cfg` XML file contains a hierarchical list of all the preferences used by FreeCAD.
910

1011
Each module has its own branch of the hierarchy starting under Preferences/Mod.
1112

@@ -24,4 +25,5 @@ Good examples of retrieving parameters can be found in:
2425
* C++: [various methods](https://github.com/FreeCAD/FreeCAD/blob/master/src/Mod/TechDraw/App/Preferences.cpp) in /Mod/TechDraw/App/Preferences.cpp
2526

2627
## See also
28+
2729
* [Preference Editor wiki entry](https://wiki.freecad.org/Preferences_Editor)

technical/translation.md

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
---
22
layout: default
33
---
4+
45
# Writing Code for Translation
56

6-
How to write code with strings that should be translated
7+
How to write code with strings that should be translated.
78

89
In most cases, any user-visible text in FreeCAD should be made translatable. Exceptions to this general rule are:
910
1. Text that only appears as log-level messages in the Report View
@@ -16,20 +17,22 @@ Some general guidelines when constructing strings for translation:
1617
* The NOOP-versions of the Qt translation functions extract the string for translation purposes, but *do not* replace the string in place with its translated equivalent. They should generally only be used in classes derived from Gui::Command for things like the menu entry and tooltip. The Command class handles actually loading the translated string.
1718
* In a non-QObject-derived class, use `Q_DECLARE_TR_FUNCTIONS(MyClass)` to give your class access to the `tr()` function. See also [the Qt documentation](https://doc.qt.io/qt-5/i18n-source-translation.html).
1819

19-
# Qt Translation Functions
20+
## Qt Translation Functions
2021

21-
## C++
22+
### C++
2223

2324
The main translation function for C++ code is `tr()`, automatically defined in any class derived from `QObject`. It automatically sets the "context" of the translation to the name of the class, providing disambiguation between the same string in different parts of FreeCAD, where the meaning might be different. It generates a `QString` out of a string literal:
24-
```
25+
26+
```cpp
2527
void SpecialWidget::DoThings()
2628
{
2729
this->labelThing.setText(tr("This will get translated")); // Context is "SpecialWidget"
2830
}
2931
```
3032

3133
If your class is not derived from `QObject`, include the Q_DECLARE_TR_FUNCTIONS macro when defining your class to gain the `tr()` function:
32-
```
34+
35+
```cpp
3336
#include <QCoreApplication>
3437

3538
class NotAWidget
@@ -44,33 +47,42 @@ public:
4447
Technically `tr()` can take an additional string: a "comment" that is displayed to translators, but is not itself translated. This is rarely used.
4548
4649
To do string replacement use `QString::arg()`, for example:
47-
```
50+
51+
```cpp
4852
label.setText(tr("Item %1 of %2 confabulated. Please wait...").arg(i).arg(total));
4953
```
54+
5055
The string "Item %1 of %2 confabulated. Please wait..." will be presented to translators, but CrowdIn will prevent them from removing the placeholders accidentally.
5156

5257
Note that in many places in the FreeCAD source code you will see uses of `QT_TR_NOOP` - this is *only* used in cases where the string is later passed through a separate call to `tr()`. If you aren't sure, check with a Maintainer, and when in doubt, `tr()` is probably what you need.
5358

54-
## Python
59+
### Python
5560

5661
In your Python code, import FreeCAD, then create a function called `translate` with the following code:
57-
```
62+
63+
```python
5864
translate = FreeCAD.Qt.translate
5965
```
66+
6067
It then gets used similarly to `tr()` in C++, but with a manually-specified context:
61-
```
68+
69+
```python
6270
print(translate("MyMod", "This will get translated"))
6371
```
72+
6473
Note that "translate" is not a true function: it is really a tag that the lupdate utility uses to identify strings for translation. You *cannot* rename it, or use it with non-literal strings, etc. You also cannot use f-strings, or Python string concatenation:
65-
```
74+
75+
```python
6676
print(translate(modNameInAVariable, someOtherVariable)) # NO!
6777
print(translate("MyMod", f"This won't {work}")) # NO!
6878
print(translate("MyMod", "This" " also " "won't work")) # NO!
6979
```
7080
To do argument replacement use the `format` function of Python's string class:
71-
```
81+
82+
```python
7283
print(translate("MyMod", "There are {} widgets present, out of {} total").format(present, total))
7384
```
85+
7486
(Note that the string sent to translators is "There are {} widgets present, out of {} total" -- the format function is called on the string that is *returned* from the translate function).
7587

7688
## UI Files
@@ -79,17 +91,21 @@ For the most part, all strings in UI files are automatically subject to translat
7991

8092
## Translating plurals
8193

82-
Many languages have complex pluralization rules. To support this, you can write strings that are designed for pluralization, including in English, by specifying a parameter that indicates how many of a thing there are. The translation system will dynamically select the correct translation (assuming translators wrote one), even for English. For example
83-
```
94+
Many languages have complex pluralization rules. To support this, you can write strings that are designed for pluralization, including in English, by specifying a parameter that indicates how many of a thing there are. The translation system will dynamically select the correct translation (assuming translators wrote one), even for English. For example:
95+
96+
```cpp
8497
int nErrors = getNumberOfErrors(); // Might be zero, might be one, might be some other number.
8598
tr("There were %n errors.", "", nErrors);
8699
```
100+
87101
Translators will be given the opportunity to translate this string in several variants (depending on the language they are translating for). For example, in English we would have:
88-
```
102+
103+
```txt
89104
There were 0 errors.
90105
There was 1 error.
91106
There were 2 errors.
92107
```
108+
93109
In other languages there might be more than two variants, the sentence structure might change completely, etc. Qt and the CrowdIn translation platform support this structure.
94110

95111
## Testing your strings
@@ -99,29 +115,35 @@ The translation process has several steps, each of which you can examine during
99115
### String extraction
100116

101117
To determine whether your strings are being correctly extracted, you can directly run the `lupdate` command on the file you are working on, using a dummy TS output file. `lupdate` is included in your Qt installation (note that internally we use lupdate from Qt 6.4 -- this is particularly important if you are testing Python code, as several major problems were address by a patch we submitted to Qt 6.4).
102-
```
118+
119+
```bash
103120
lupdate MySourceCodeFile.cpp --ts test.ts
104121
```
122+
105123
will generate the file test.ts -- you can examine it to ensure your string appears with the expected context in that file. In particular, make sure that each string makes sense alone: otherwise, without context, translators will not know what they should replace it with.
106124

107125
### String replacement
108126

109127
To determine whether the string is being replaced correctly, you can create a dummy language file from the above test.ts file, and inject it into your FreeCAD instance. To do this you must know the name of the file that the finished translations will be put into. In general this is the name of the module you are working on, an underscore, the language code, and ".ts". For example, "PartDesign_es-ES.ts" is the Spanish (Spain) translation file for the Part Design workbench. An exception is the code in `src/Gui`, which is FreeCAD_xx.ts (where xx is the language code).
110128

111129
For testing purposes, choose a language you are familiar with (or at least, can navigate well enough to deactivate when you are done testing!), and copy the file generated by lupdate into the appropriate filename. Locate the string you want to test:
112-
```
130+
131+
```ts
113132
<message>
114133
<location filename="../CommandDoc.cpp" line="1649"/>
115134
<source>Activates or Deactivates the selected object&apos;s edit mode</source>
116135
<translation type="unfinished"></translation>
117136
</message>
118137
```
138+
119139
Edit this to eliminate the "unfinished" and to add a translation, e.g.
120-
```
140+
141+
```ts
121142
<message>
122143
<location filename="../CommandDoc.cpp" line="1649"/>
123144
<source>Activates or Deactivates the selected object's edit mode</source>
124145
<translation>Activa o desactiva el modo de edición del objeto seleccionado</translation>
125146
</message>
126147
```
148+
127149
Next, this file must be converted to a `*.qm` file using the `lrelease` tool (distributed with Qt). Finally, place the generated QM file in the same location as your user.cfg file, in a subdirectory called "translations", then switch FreeCAD to the language you chose to test with. Your translated string should appear.

0 commit comments

Comments
 (0)