Merge pull request #5130 from Roy-043/Draft-Fix-merge-layers
Draft: Fix merge layers
This commit is contained in:
@@ -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) 2021 FreeCAD Developers *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -37,7 +38,7 @@ import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
|
||||
from draftutils.messages import _msg
|
||||
from draftutils.translate import translate
|
||||
from draftutils.translate import _tr
|
||||
from draftobjects.layer import Layer
|
||||
|
||||
|
||||
@@ -355,13 +356,13 @@ class ViewProviderLayer:
|
||||
def setupContextMenu(self, vobj, menu):
|
||||
"""Set up actions to perform in the context menu."""
|
||||
action1 = QtGui.QAction(QtGui.QIcon(":/icons/button_right.svg"),
|
||||
translate("draft", "Activate this layer"),
|
||||
_tr("Activate this layer"),
|
||||
menu)
|
||||
action1.triggered.connect(self.activate)
|
||||
menu.addAction(action1)
|
||||
|
||||
action2 = QtGui.QAction(QtGui.QIcon(":/icons/Draft_SelectGroup.svg"),
|
||||
translate("draft", "Select layer contents"),
|
||||
_tr("Select layer contents"),
|
||||
menu)
|
||||
action2.triggered.connect(self.select_contents)
|
||||
menu.addAction(action2)
|
||||
@@ -399,80 +400,76 @@ class ViewProviderLayerContainer:
|
||||
def setupContextMenu(self, vobj, menu):
|
||||
"""Set up actions to perform in the context menu."""
|
||||
action1 = QtGui.QAction(QtGui.QIcon(":/icons/Draft_Layer.svg"),
|
||||
translate("Draft", "Merge layer duplicates"),
|
||||
_tr("Merge layer duplicates"),
|
||||
menu)
|
||||
action1.triggered.connect(self.merge_by_name)
|
||||
menu.addAction(action1)
|
||||
action2 = QtGui.QAction(QtGui.QIcon(":/icons/Draft_NewLayer.svg"),
|
||||
translate("Draft", "Add new layer"),
|
||||
_tr("Add new layer"),
|
||||
menu)
|
||||
action2.triggered.connect(self.add_layer)
|
||||
menu.addAction(action2)
|
||||
|
||||
def merge_by_name(self):
|
||||
"""Merge the layers that have the same name."""
|
||||
"""Merge the layers that have the same base label."""
|
||||
if not hasattr(self, "Object") or not hasattr(self.Object, "Group"):
|
||||
return
|
||||
|
||||
obj = self.Object
|
||||
doc = App.ActiveDocument
|
||||
doc.openTransaction(_tr("Merge layer duplicates"))
|
||||
|
||||
layers = list()
|
||||
for iobj in obj.Group:
|
||||
if hasattr(iobj, "Proxy") and isinstance(iobj.Proxy, Layer):
|
||||
layers.append(iobj)
|
||||
layer_container = self.Object
|
||||
layers = []
|
||||
for obj in layer_container.Group:
|
||||
if hasattr(obj, "Proxy") and isinstance(obj.Proxy, Layer):
|
||||
layers.append(obj)
|
||||
|
||||
to_delete = list()
|
||||
to_delete = []
|
||||
for layer in layers:
|
||||
# Test the last three characters of the layer's Label to see
|
||||
# if it's a number, like `'Layer017'`
|
||||
if (layer.Label[-1].isdigit()
|
||||
and layer.Label[-2].isdigit()
|
||||
and layer.Label[-3].isdigit()):
|
||||
# If the object inside the layer has the same Label
|
||||
# as the layer, save this object
|
||||
orig = None
|
||||
for ol in layer.OutList:
|
||||
if ol.Label == layer.Label[:-3].strip():
|
||||
orig = ol
|
||||
break
|
||||
# Remove trailing digits (usually 3 but there might be more) and
|
||||
# trailing spaces from Label before comparing:
|
||||
base_label = layer.Label.rstrip("0123456789 ")
|
||||
|
||||
# Go into the objects that reference this layer object
|
||||
# and set the layer property with the previous `orig`
|
||||
# object found
|
||||
# Editor: when is this possible? Maybe if a layer is inside
|
||||
# another layer? Currently the code doesn't allow this
|
||||
# so maybe this was a previous behavior that was disabled
|
||||
# in `ViewProviderLayer`.
|
||||
if orig:
|
||||
for par in layer.InList:
|
||||
for prop in par.PropertiesList:
|
||||
if getattr(par, prop) == layer:
|
||||
_msg("Changed property '" + prop
|
||||
+ "' of object " + par.Label
|
||||
+ " from " + layer.Label
|
||||
+ " to " + orig.Label)
|
||||
setattr(par, prop, orig)
|
||||
to_delete.append(layer)
|
||||
# Try to find the `'base'` layer:
|
||||
base = None
|
||||
for other_layer in layers:
|
||||
if ((not other_layer in to_delete) # Required if there are duplicate labels.
|
||||
and other_layer != layer
|
||||
and other_layer.Label.upper() == base_label.upper()):
|
||||
base = other_layer
|
||||
break
|
||||
|
||||
if base:
|
||||
if layer.Group:
|
||||
base_group = base.Group
|
||||
for obj in layer.Group:
|
||||
if not obj in base_group:
|
||||
base_group.append(obj)
|
||||
base.Group = base_group
|
||||
to_delete.append(layer)
|
||||
elif layer.Label != base_label:
|
||||
_msg(_tr("Relabeling layer:")
|
||||
+ " '{}' -> '{}'".format(layer.Label, base_label))
|
||||
layer.Label = base_label
|
||||
|
||||
for layer in to_delete:
|
||||
if not layer.InList:
|
||||
_msg("Merging duplicate layer: " + layer.Label)
|
||||
App.ActiveDocument.removeObject(layer.Name)
|
||||
elif len(layer.InList) == 1:
|
||||
first = layer.InList[0]
|
||||
_msg(_tr("Merging layer:") + " '{}'".format(layer.Label))
|
||||
doc.removeObject(layer.Name)
|
||||
|
||||
if first.isDerivedFrom("App::DocumentObjectGroup"):
|
||||
_msg("Merging duplicate layer: " + layer.Label)
|
||||
App.ActiveDocument.removeObject(layer.Name)
|
||||
else:
|
||||
_msg("InList not empty. "
|
||||
"Unable to delete layer: " + layer.Label)
|
||||
doc.recompute()
|
||||
doc.commitTransaction()
|
||||
|
||||
def add_layer(self):
|
||||
"""Creates a new layer"""
|
||||
import Draft
|
||||
|
||||
doc = App.ActiveDocument
|
||||
doc.openTransaction(_tr("Add new layer"))
|
||||
|
||||
Draft.make_layer()
|
||||
App.ActiveDocument.recompute()
|
||||
|
||||
doc.recompute()
|
||||
doc.commitTransaction()
|
||||
|
||||
def __getstate__(self):
|
||||
"""Return a tuple of objects to save or None."""
|
||||
|
||||
Reference in New Issue
Block a user