Merge pull request #19427 from Roy-043/Draft-implement-Draft_AddToLayer-command

Draft: implement Draft_AddToLayer command
This commit is contained in:
Roy-043
2025-02-07 18:40:34 +01:00
committed by GitHub
4 changed files with 337 additions and 21 deletions

View File

@@ -4,6 +4,7 @@
<file>icons/Draft_AddConstruction.svg</file>
<file>icons/Draft_AddPoint.svg</file>
<file>icons/Draft_AddToGroup.svg</file>
<file>icons/Draft_AddToLayer.svg</file>
<file>icons/Draft_AddNamedGroup.svg</file>
<file>icons/Draft_Annotation_Style.svg</file>
<file>icons/Draft_Apply.svg</file>

View File

@@ -0,0 +1,217 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg2985"
height="64px"
width="64px"
sodipodi:docname="Draft_AddToLayer.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
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
id="namedview11517"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="10.429825"
inkscape:cx="23.442388"
inkscape:cy="37.632463"
inkscape:window-width="1280"
inkscape:window-height="971"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg2985" />
<title
id="title853">Draft_Layer</title>
<defs
id="defs2987">
<linearGradient
id="linearGradient1852">
<stop
id="stop1848"
offset="0"
style="stop-color:#06989a;stop-opacity:1;" />
<stop
id="stop1850"
offset="1"
style="stop-color:#34e0e2;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3815">
<stop
id="stop3817"
offset="0"
style="stop-color:#d3d7cf;stop-opacity:1;" />
<stop
id="stop3819"
offset="1"
style="stop-color:#ffffff;stop-opacity:1" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3815"
id="linearGradient2"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.64426076,0,0,0.63928583,17.931015,13.729721)"
x1="53.257175"
y1="19.086002"
x2="25.928942"
y2="-1.3815211" />
<linearGradient
xlink:href="#linearGradient1852"
id="linearGradient1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.66067504,0,0,0.63929414,18.06576,5.8678762)"
x1="53.257175"
y1="19.086002"
x2="25.928942"
y2="-1.3815211" />
<linearGradient
xlink:href="#linearGradient3815"
id="linearGradient3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.66067504,0,0,0.63929414,18.06576,-1.9839915)"
x1="53.257175"
y1="19.086002"
x2="25.928942"
y2="-1.3815211" />
<linearGradient
xlink:href="#linearGradient3057"
id="linearGradient3053"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.9455392,0,0,1.9455392,-47.998185,-58.673094)"
x1="41.511921"
y1="26.271811"
x2="42.984806"
y2="49.460072" />
<linearGradient
id="linearGradient3057">
<stop
style="stop-color:#8ae234;stop-opacity:1"
offset="0.0000000"
id="stop3059" />
<stop
style="stop-color:#4e9a06;stop-opacity:1"
offset="1.0000000"
id="stop3061" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3057"
id="linearGradient3053-3"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.9455392,0,0,1.9455392,-47.998185,-58.673094)"
x1="41.511921"
y1="26.271811"
x2="42.984806"
y2="49.460072" />
</defs>
<metadata
id="metadata5826">
<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>Draft_Layer</dc:title>
<dc:date>Tue Jun 10 10:21:01 2014 -0300</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>[Yorik van Havre]</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/Draft/Resources/icons/Draft_Layer.svg</dc:identifier>
<dc:relation>https://www.freecad.org/wiki/index.php?title=Artwork</dc:relation>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
<dc:subject>
<rdf:Bag>
<rdf:li>page</rdf:li>
<rdf:li>pages</rdf:li>
<rdf:li>rectangles</rdf:li>
<rdf:li>stack</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:description>Three pages or rectangles stacked on top of each other. Previously VisGroup.</dc:description>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer2"
style="display:inline;stroke-width:0.653981"
transform="matrix(1.5298962,0,0,1.5282988,-17.190014,-6.6523599)">
<path
d="M 27.250224,20.840975 50.127593,30.001487 37.05481,40.470644 14.177442,31.310132 Z"
style="display:inline;overflow:visible;fill:url(#linearGradient1);fill-rule:evenodd;stroke:#2e3436;stroke-width:1.30796;stroke-linejoin:round;stroke-dasharray:none;marker:none;enable-background:accumulate"
id="path1-2-9" />
<path
id="path3-5"
style="display:inline;fill:none;stroke:#34e0e2;stroke-width:1.30796;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 16.744141,30.928014 c 6.697265,2.682292 13.394531,5.364583 20.091797,8.046875 3.574869,-2.863281 7.149739,-5.726563 10.724609,-8.589844 -6.697266,-2.682292 -13.394531,-5.364583 -20.091797,-8.046875 -3.57487,2.863281 -7.14974,5.726563 -10.724609,8.589844 z" />
</g>
<path
style="fill:none;stroke:#042a2a;stroke-width:8;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 6.05697,18.049229 H 29.844572"
id="path853" />
<path
id="path851"
d="M 17.950771,6.1554283 V 29.94303"
style="fill:none;stroke:#042a2a;stroke-width:8;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path847"
d="M 6.05697,18.049229 H 29.844572"
style="fill:none;stroke:#34e0e2;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:none;stroke:#34e0e2;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 17.950771,6.1554283 V 29.94303"
id="path849" />
<path
id="path855"
d="M 17.950771,6.1554283 V 29.94303"
style="fill:none;stroke:#179a9b;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:none;stroke:#0aa0a2;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 6.05697,18.049229 H 29.844572"
id="path857" />
</svg>

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1,6 +1,7 @@
# ***************************************************************************
# * Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
# * Copyright (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de> *
# * Copyright (c) 2025 FreeCAD Project Association *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
@@ -33,9 +34,10 @@ from PySide.QtCore import QT_TRANSLATE_NOOP
import os
import FreeCAD as App
import FreeCADGui as Gui
import Draft
import Draft_rc
from draftguitools import gui_base
from draftmake import make_layer
from draftobjects import layer
from draftutils import params
from draftutils import utils
from draftutils.translate import translate
@@ -60,12 +62,12 @@ class Layer(gui_base.GuiCommandSimplest):
"""GuiCommand to create a Layer object in the document."""
def __init__(self):
super().__init__(name=translate("draft", "Layer"))
super().__init__(name="Draft_Layer")
def GetResources(self):
"""Set icon, menu and tooltip."""
return {"Pixmap": "Draft_Layer",
"MenuText": QT_TRANSLATE_NOOP("Draft_Layer", "Layer"),
"MenuText": QT_TRANSLATE_NOOP("Draft_Layer", "New layer"),
"ToolTip": QT_TRANSLATE_NOOP("Draft_Layer", "Adds a layer to the document.\nObjects added to this layer can share the same visual properties.")}
def Activated(self):
@@ -75,13 +77,101 @@ class Layer(gui_base.GuiCommandSimplest):
"""
super().Activated()
self.doc.openTransaction("Create Layer")
self.doc.openTransaction(translate("draft", "Create layer"))
Gui.addModule("Draft")
Gui.doCommand("_layer_ = Draft.make_layer(name=None, line_color=None, shape_color=None, line_width=None, draw_style=None, transparency=None)")
Gui.doCommand("layer = Draft.make_layer(name=None, line_color=None, shape_color=None, line_width=None, draw_style=None, transparency=None)")
Gui.doCommand("FreeCAD.ActiveDocument.recompute()")
self.doc.commitTransaction()
class AddToLayer(gui_base.GuiCommandNeedsSelection):
"""GuiCommand for the Draft_AddToLayer tool."""
def __init__(self):
super().__init__(name="Draft_AddToLayer")
def GetResources(self):
"""Set icon, menu and tooltip."""
return {"Pixmap": "Draft_AddToLayer",
"MenuText": QT_TRANSLATE_NOOP("Draft_AddToLayer", "Add to layer..."),
"ToolTip": QT_TRANSLATE_NOOP("Draft_AddToLayer", "Adds the selected objects to a layer, or removes them from any layer.")}
def Activated(self):
"""Execute when the command is called."""
super().Activated()
if not hasattr(Gui, "draftToolBar"):
return
self.ui = Gui.draftToolBar
objs = [obj for obj in App.ActiveDocument.Objects if utils.get_type(obj) == "Layer"]
objs.sort(key=lambda obj: obj.Label)
self.objects = [None] \
+ [None] \
+ objs
self.labels = [translate("draft", "Remove from layer")] \
+ ["---"] \
+ [obj.Label for obj in objs] \
+ ["---"] \
+ [translate("draft", "Add to new layer...")]
self.icons = [self.ui.getIcon(":/icons/list-remove.svg")] \
+ [None] \
+ [obj.ViewObject.Icon for obj in objs] \
+ [None] \
+ [self.ui.getIcon(":/icons/list-add.svg")]
self.ui.sourceCmd = self
self.ui.popupMenu(self.labels, self.icons)
def proceed(self, option):
self.ui.sourceCmd = None
if option == self.labels[0]:
# "Remove from layer"
changed = False
for obj in Gui.Selection.getSelection():
lyr = layer.get_layer(obj)
if lyr is not None:
if not changed:
self.doc.openTransaction(translate("draft", "Remove from layer"))
changed = True
lyr.Proxy.removeObject(lyr, obj)
if changed:
self.doc.commitTransaction()
self.doc.recompute()
return
if option == self.labels[-1]:
# "Add to new layer..."
from PySide import QtWidgets
txt, ok = QtWidgets.QInputDialog.getText(
None,
translate("draft", "Create new layer"),
translate("draft", "Layer name:"),
text=translate("draft", "Layer", "Object label")
)
if not ok:
return
if not txt:
return
self.doc.openTransaction(translate("draft", "Add to new layer"))
lyr = make_layer.make_layer(name=txt, line_color=None, shape_color=None,
line_width=None, draw_style=None, transparency=None)
for obj in Gui.Selection.getSelection():
lyr.Proxy.addObject(lyr, obj)
self.doc.commitTransaction()
self.doc.recompute()
return
# Layer has been selected
i = self.labels.index(option)
lyr = self.objects[i]
self.doc.openTransaction(translate("draft", "Add to layer"))
for obj in Gui.Selection.getSelection():
lyr.Proxy.addObject(lyr, obj)
self.doc.commitTransaction()
self.doc.recompute()
class LayerManager:
"""GuiCommand that displays a Layers manager dialog"""
@@ -156,11 +246,12 @@ class LayerManager:
doc = App.ActiveDocument
changed = False
trans_name = translate("draft", "Layers change")
# delete layers
for name in self.deleteList:
if not changed:
doc.openTransaction("Layers change")
doc.openTransaction(trans_name)
changed = True
doc.removeObject(name)
@@ -174,17 +265,17 @@ class LayerManager:
obj = doc.getObject(name)
if not obj:
if not changed:
doc.openTransaction("Layers change")
doc.openTransaction(trans_name)
changed = True
obj = Draft.make_layer(name=None, line_color=None, shape_color=None,
line_width=None, draw_style=None, transparency=None)
obj = make_layer.make_layer(name=None, line_color=None, shape_color=None,
line_width=None, draw_style=None, transparency=None)
vobj = obj.ViewObject
# visibility
checked = self.model.item(row, 0).checkState() == QtCore.Qt.Checked
if checked != vobj.Visibility:
if not changed:
doc.openTransaction("Layers change")
doc.openTransaction(trans_name)
changed = True
vobj.Visibility = checked
@@ -193,7 +284,7 @@ class LayerManager:
# Setting Label="" is possible in the Property editor but we avoid it here:
if label and obj.Label != label:
if not changed:
doc.openTransaction("Layers change")
doc.openTransaction(trans_name)
changed = True
obj.Label = label
@@ -202,7 +293,7 @@ class LayerManager:
# Setting LineWidth=0 is possible in the Property editor but we avoid it here:
if width and vobj.LineWidth != width:
if not changed:
doc.openTransaction("Layers change")
doc.openTransaction(trans_name)
changed = True
vobj.LineWidth = width
@@ -210,7 +301,7 @@ class LayerManager:
style = self.model.item(row, 3).text()
if style is not None and vobj.DrawStyle != style:
if not changed:
doc.openTransaction("Layers change")
doc.openTransaction(trans_name)
changed = True
vobj.DrawStyle = style
@@ -218,7 +309,7 @@ class LayerManager:
color = self.model.item(row, 4).data(QtCore.Qt.UserRole)
if color is not None and vobj.LineColor[:3] != color:
if not changed:
doc.openTransaction("Layers change")
doc.openTransaction(trans_name)
changed = True
vobj.LineColor = color
@@ -226,7 +317,7 @@ class LayerManager:
color = self.model.item(row, 5).data(QtCore.Qt.UserRole)
if color is not None and vobj.ShapeColor[:3] != color:
if not changed:
doc.openTransaction("Layers change")
doc.openTransaction(trans_name)
changed = True
vobj.ShapeColor = color
@@ -234,7 +325,7 @@ class LayerManager:
transparency = self.model.item(row, 6).data(QtCore.Qt.DisplayRole)
if transparency is not None and vobj.Transparency != transparency:
if not changed:
doc.openTransaction("Layers change")
doc.openTransaction(trans_name)
changed = True
vobj.Transparency = transparency
@@ -242,7 +333,7 @@ class LayerManager:
color = self.model.item(row, 7).data(QtCore.Qt.UserRole)
if color is not None and vobj.LinePrintColor[:3] != color:
if not changed:
doc.openTransaction("Layers change")
doc.openTransaction(trans_name)
changed = True
vobj.LinePrintColor = color
@@ -284,7 +375,7 @@ class LayerManager:
self.dialog.tree.setColumnWidth(1,128) # name column
# populate
objs = [obj for obj in App.ActiveDocument.Objects if Draft.getType(obj) == "Layer"]
objs = [obj for obj in App.ActiveDocument.Objects if utils.get_type(obj) == "Layer"]
objs.sort(key=lambda o:o.Label)
for obj in objs:
self.addItem(obj)
@@ -504,6 +595,7 @@ if App.GuiUp:
Gui.addCommand('Draft_Layer', Layer())
Gui.addCommand('Draft_AddToLayer', AddToLayer())
Gui.addCommand('Draft_LayerManager', LayerManager())
## @}

View File

@@ -114,9 +114,11 @@ def get_draft_utility_commands_menu():
"Draft_Layer",
"Draft_LayerManager",
"Draft_AddNamedGroup",
"Draft_AddToGroup",
"Draft_SelectGroup",
"Draft_ToggleConstructionMode",
"Separator",
"Draft_AddToLayer",
"Draft_AddToGroup",
"Draft_AddConstruction",
"Separator",
"Draft_ToggleDisplayMode",
@@ -132,8 +134,9 @@ def get_draft_utility_commands_toolbar():
"""Return the utility commands list for the toolbar."""
return ["Draft_LayerManager",
"Draft_AddNamedGroup",
"Draft_AddToGroup",
"Draft_SelectGroup",
"Draft_AddToLayer",
"Draft_AddToGroup",
"Draft_AddConstruction",
"Draft_ToggleDisplayMode",
"Draft_WorkingPlaneProxy"]
@@ -169,10 +172,13 @@ def get_draft_context_commands():
"Draft_ApplyStyle",
"Separator",
"Draft_Layer",
"Draft_LayerManager",
"Draft_AddNamedGroup",
"Draft_AddToGroup",
"Draft_SelectGroup",
"Draft_ToggleConstructionMode",
"Separator",
"Draft_AddToLayer",
"Draft_AddToGroup",
"Draft_AddConstruction",
"Separator",
"Draft_ToggleDisplayMode",