FreeCAD
513 строк · 21.2 Кб
1# ***************************************************************************
2# * Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
3# * Copyright (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de> *
4# * *
5# * This file is part of the FreeCAD CAx development system. *
6# * *
7# * This program is free software; you can redistribute it and/or modify *
8# * it under the terms of the GNU Lesser General Public License (LGPL) *
9# * as published by the Free Software Foundation; either version 2 of *
10# * the License, or (at your option) any later version. *
11# * for detail see the LICENCE text file. *
12# * *
13# * This program is distributed in the hope that it will be useful, *
14# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16# * GNU Library General Public License for more details. *
17# * *
18# * You should have received a copy of the GNU Library General Public *
19# * License along with this program; if not, write to the Free Software *
20# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
21# * USA *
22# * *
23# ***************************************************************************
24"""Provides GUI tools to create Layer objects."""
25## @package gui_layers
26# \ingroup draftguitools
27# \brief Provides GUI tools to create Layer objects.
28
29## \addtogroup draftguitools
30# @{
31from PySide.QtCore import QT_TRANSLATE_NOOP32
33import os34import FreeCAD35import FreeCADGui as Gui36import Draft37import Draft_rc38from draftguitools import gui_base39from draftutils import params40from draftutils import utils41from draftutils.translate import translate42
43# The module is used to prevent complaints from code checkers (flake8)
44bool(Draft_rc.__name__)45
46
47def getColorIcon(color):48
49"returns a QtGui.QIcon from a color 3-float tuple"50
51from PySide import QtCore,QtGui52c = QtGui.QColor(int(color[0]*255),int(color[1]*255),int(color[2]*255))53im = QtGui.QImage(48,48,QtGui.QImage.Format_ARGB32)54im.fill(c)55px = QtGui.QPixmap.fromImage(im)56return QtGui.QIcon(px)57
58
59class Layer(gui_base.GuiCommandSimplest):60"""GuiCommand to create a Layer object in the document."""61
62def __init__(self):63super(Layer, self).__init__(name=translate("draft","Layer"))64
65def GetResources(self):66"""Set icon, menu and tooltip."""67return {'Pixmap': 'Draft_Layer',68'MenuText': QT_TRANSLATE_NOOP("Draft_Layer", "Layer"),69'ToolTip': QT_TRANSLATE_NOOP("Draft_Layer", "Adds a layer to the document.\nObjects added to this layer can share the same visual properties such as line color, line width, and shape color.")}70
71def Activated(self):72"""Execute when the command is called.73
74It calls the `finish(False)` method of the active Draft command.
75"""
76super(Layer, self).Activated()77
78self.doc.openTransaction("Create Layer")79Gui.addModule("Draft")80Gui.doCommand("_layer_ = Draft.make_layer(name=None, line_color=None, shape_color=None, line_width=None, draw_style=None, transparency=None)")81Gui.doCommand("FreeCAD.ActiveDocument.recompute()")82self.doc.commitTransaction()83
84
85class LayerManager:86
87"""GuiCommand that displays a Layers manager dialog"""88
89def GetResources(self):90
91return {'Pixmap' : 'Draft_LayerManager',92'MenuText': QT_TRANSLATE_NOOP("Draft_LayerManager", "Manage layers..."),93'ToolTip' : QT_TRANSLATE_NOOP("Draft_LayerManager", "Set/modify the different layers of this document")}94
95def Activated(self):96
97from PySide import QtCore, QtGui, QtWidgets98
99# store changes to be committed100self.deleteList = []101
102# create the dialog103self.dialog = Gui.PySideUic.loadUi(":/ui/dialogLayers.ui")104
105# set nice icons106self.dialog.setWindowIcon(QtGui.QIcon(":/icons/Draft_Layer.svg"))107self.dialog.buttonNew.setIcon(QtGui.QIcon(":/icons/document-new.svg"))108self.dialog.buttonDelete.setIcon(QtGui.QIcon(":/icons/delete.svg"))109self.dialog.buttonSelectAll.setIcon(QtGui.QIcon(":/icons/edit-select-all.svg"))110self.dialog.buttonToggle.setIcon(QtGui.QIcon(":/icons/dagViewVisible.svg"))111self.dialog.buttonIsolate.setIcon(QtGui.QIcon(":/icons/view-refresh.svg"))112self.dialog.buttonCancel.setIcon(QtGui.QIcon(":/icons/edit_Cancel.svg"))113self.dialog.buttonOK.setIcon(QtGui.QIcon(":/icons/edit_OK.svg"))114
115# restore window geometry from stored state116w = params.get_param("LayersManagerWidth")117h = params.get_param("LayersManagerHeight")118self.dialog.resize(w,h)119
120# center the dialog over FreeCAD window121mw = Gui.getMainWindow()122self.dialog.move(mw.frameGeometry().topLeft() + mw.rect().center() - self.dialog.rect().center())123
124# connect signals/slots125self.dialog.buttonNew.clicked.connect(self.addItem)126self.dialog.buttonDelete.clicked.connect(self.onDelete)127self.dialog.buttonSelectAll.clicked.connect(self.dialog.tree.selectAll)128self.dialog.buttonToggle.clicked.connect(self.onToggle)129self.dialog.buttonCancel.clicked.connect(self.dialog.reject)130self.dialog.buttonIsolate.clicked.connect(self.onIsolate)131self.dialog.buttonOK.clicked.connect(self.accept)132self.dialog.rejected.connect(self.reject)133
134# set the model up135self.model = QtGui.QStandardItemModel()136self.dialog.tree.setModel(self.model)137self.dialog.tree.setUniformRowHeights(True)138self.dialog.tree.setItemDelegate(Layers_Delegate())139self.dialog.tree.setItemsExpandable(False)140self.dialog.tree.setRootIsDecorated(False) # removes spacing in first column141self.dialog.tree.setSelectionMode(QtWidgets.QTreeView.ExtendedSelection) # allow to select many142
143# fill the tree view144self.update()145
146# rock 'n roll!!!147self.dialog.exec_()148
149def accept(self):150
151"when OK button is pressed"152
153changed = False154
155# delete layers156for name in self.deleteList:157if not changed:158FreeCAD.ActiveDocument.openTransaction("Layers change")159changed = True160FreeCAD.ActiveDocument.removeObject(name)161
162# apply changes163for row in range(self.model.rowCount()):164
165# get or create layer166name = self.model.item(row,1).toolTip()167obj = None168if name:169obj = FreeCAD.ActiveDocument.getObject(name)170if not obj:171if not changed:172FreeCAD.ActiveDocument.openTransaction("Layers change")173changed = True174obj = Draft.make_layer(name=None, line_color=None, shape_color=None,175line_width=None, draw_style=None, transparency=None)176
177# visibility178checked = True if self.model.item(row,0).checkState() == QtCore.Qt.Checked else False179if checked != obj.ViewObject.Visibility:180if not changed:181FreeCAD.ActiveDocument.openTransaction("Layers change")182changed = True183obj.ViewObject.Visibility = checked184
185# label186label = self.model.item(row,1).text()187if label:188if obj.Label != label:189if not changed:190FreeCAD.ActiveDocument.openTransaction("Layers change")191changed = True192obj.Label = label193
194# line width195width = self.model.item(row,2).data(QtCore.Qt.DisplayRole)196if width:197if obj.ViewObject.LineWidth != width:198if not changed:199FreeCAD.ActiveDocument.openTransaction("Layers change")200changed = True201obj.ViewObject.LineWidth = width202
203# draw style204style = self.model.item(row,3).text()205if style:206if obj.ViewObject.DrawStyle != style:207if not changed:208FreeCAD.ActiveDocument.openTransaction("Layers change")209changed = True210obj.ViewObject.DrawStyle = style211
212# line color213color = self.model.item(row,4).data(QtCore.Qt.UserRole)214if color:215if obj.ViewObject.LineColor[3:] != color:216if not changed:217FreeCAD.ActiveDocument.openTransaction("Layers change")218changed = True219obj.ViewObject.LineColor = color220
221# shape color222color = self.model.item(row,5).data(QtCore.Qt.UserRole)223if color:224if obj.ViewObject.ShapeColor[3:] != color:225if not changed:226FreeCAD.ActiveDocument.openTransaction("Layers change")227changed = True228obj.ViewObject.ShapeColor = color229
230# transparency231transparency = self.model.item(row,6).data(QtCore.Qt.DisplayRole)232if transparency:233if obj.ViewObject.Transparency != transparency:234if not changed:235FreeCAD.ActiveDocument.openTransaction("Layers change")236changed = True237obj.ViewObject.Transparency = transparency238
239# line print color240color = self.model.item(row,7).data(QtCore.Qt.UserRole)241if color:242if not "LinePrintColor" in obj.ViewObject.PropertiesList:243if hasattr(obj.ViewObject.Proxy,"set_properties"):244obj.ViewObject.Proxy.set_properties(obj.ViewObject)245if "LinePrintColor" in obj.ViewObject.PropertiesList:246if obj.ViewObject.LinePrintColor[3:] != color:247if not changed:248FreeCAD.ActiveDocument.openTransaction("Layers change")249changed = True250obj.ViewObject.LinePrintColor = color251
252# recompute253if changed:254FreeCAD.ActiveDocument.commitTransaction()255FreeCAD.ActiveDocument.recompute()256
257# exit258self.dialog.reject()259
260def reject(self):261
262"when Cancel button is pressed or dialog is closed"263
264# save dialog size265params.set_param("LayersManagerWidth", self.dialog.width())266params.set_param("LayersManagerHeight", self.dialog.height())267
268return True269
270def update(self):271
272"rebuild the model from document contents"273
274self.model.clear()275
276# set header277self.model.setHorizontalHeaderLabels([translate("Draft","On"),278translate("Draft","Name"),279translate("Draft","Line width"),280translate("Draft","Draw style"),281translate("Draft","Line color"),282translate("Draft","Face color"),283translate("Draft","Transparency"),284translate("Draft","Line print color")])285self.dialog.tree.header().setDefaultSectionSize(72)286self.dialog.tree.setColumnWidth(0,32) # on/off column287self.dialog.tree.setColumnWidth(1,128) # name column288
289# populate290objs = [obj for obj in FreeCAD.ActiveDocument.Objects if Draft.getType(obj) == "Layer"]291objs.sort(key=lambda o:o.Label)292for obj in objs:293self.addItem(obj)294
295def addItem(self,obj=None):296
297"adds a row to the model"298
299from PySide import QtCore, QtGui300
301# create row with default values302onItem = QtGui.QStandardItem()303onItem.setCheckable(True)304onItem.setCheckState(QtCore.Qt.Checked)305nameItem = QtGui.QStandardItem(translate("Draft", "New Layer"))306widthItem = QtGui.QStandardItem()307widthItem.setData(params.get_param_view("DefaultShapeLineWidth"), QtCore.Qt.DisplayRole)308styleItem = QtGui.QStandardItem(utils.DRAW_STYLES[params.get_param("DefaultDrawStyle")])309lineColorItem = QtGui.QStandardItem()310lineColorItem.setData(311utils.get_rgba_tuple(params.get_param_view("DefaultShapeLineColor"))[:3],312QtCore.Qt.UserRole313)314shapeColorItem = QtGui.QStandardItem()315shapeColorItem.setData(316utils.get_rgba_tuple(params.get_param_view("DefaultShapeColor"))[:3],317QtCore.Qt.UserRole318)319transparencyItem = QtGui.QStandardItem()320transparencyItem.setData(321params.get_param_view("DefaultShapeTransparency"),322QtCore.Qt.DisplayRole323)324linePrintColorItem = QtGui.QStandardItem()325linePrintColorItem.setData(326utils.get_rgba_tuple(params.get_param("DefaultPrintColor"))[:3],327QtCore.Qt.UserRole328)329
330# populate with object data331if obj:332onItem.setCheckState(QtCore.Qt.Checked if obj.ViewObject.Visibility else QtCore.Qt.Unchecked)333nameItem.setText(obj.Label)334nameItem.setToolTip(obj.Name)335widthItem.setData(obj.ViewObject.LineWidth,QtCore.Qt.DisplayRole)336styleItem.setText(obj.ViewObject.DrawStyle)337lineColorItem.setData(obj.ViewObject.LineColor[:3],QtCore.Qt.UserRole)338shapeColorItem.setData(obj.ViewObject.ShapeColor[:3],QtCore.Qt.UserRole)339transparencyItem.setData(obj.ViewObject.Transparency,QtCore.Qt.DisplayRole)340if hasattr(obj.ViewObject,"LinePrintColor"):341linePrintColorItem.setData(obj.ViewObject.LinePrintColor[:3],QtCore.Qt.UserRole)342lineColorItem.setIcon(getColorIcon(lineColorItem.data(QtCore.Qt.UserRole)))343shapeColorItem.setIcon(getColorIcon(shapeColorItem.data(QtCore.Qt.UserRole)))344linePrintColorItem.setIcon(getColorIcon(linePrintColorItem.data(QtCore.Qt.UserRole)))345
346# append row347self.model.appendRow([onItem,348nameItem,349widthItem,350styleItem,351lineColorItem,352shapeColorItem,353transparencyItem,354linePrintColorItem])355
356def onDelete(self):357
358"delete selected rows"359
360rows = []361for index in self.dialog.tree.selectedIndexes():362if not index.row() in rows:363rows.append(index.row())364
365# append layer name to the delete list366if index.column() == 1:367name = self.model.itemFromIndex(index).toolTip()368if name:369if not name in self.deleteList:370self.deleteList.append(name)371
372# delete rows starting from the lowest, to not alter row indexes while deleting373rows.sort()374rows.reverse()375for row in rows:376self.model.takeRow(row)377
378def onToggle(self):379
380"toggle selected layers on/off"381
382from PySide import QtCore383
384state = None385for index in self.dialog.tree.selectedIndexes():386if index.column() == 0:387# get state from first selected row388if state is None:389if self.model.itemFromIndex(index).checkState() == QtCore.Qt.Checked:390state = QtCore.Qt.Unchecked391else:392state = QtCore.Qt.Checked393self.model.itemFromIndex(index).setCheckState(state)394
395def onIsolate(self):396
397"isolates the selected layers (turns all the others off"398
399from PySide import QtCore400
401onrows = []402for index in self.dialog.tree.selectedIndexes():403if not index.row() in onrows:404onrows.append(index.row())405for row in range(self.model.rowCount()):406if not row in onrows:407self.model.item(row,0).setCheckState(QtCore.Qt.Unchecked)408
409
410if FreeCAD.GuiUp:411
412from PySide import QtCore, QtGui, QtWidgets413
414class Layers_Delegate(QtWidgets.QStyledItemDelegate):415
416"model delegate"417
418def __init__(self, parent=None, *args):419
420QtWidgets.QStyledItemDelegate.__init__(self, parent, *args)421# setEditorData() is triggered several times.422# But we want to show the color dialog only the first time423self.first = True424
425def createEditor(self,parent,option,index):426
427if index.column() == 0: # Layer on/off428editor = QtWidgets.QCheckBox(parent)429if index.column() == 1: # Layer name430editor = QtWidgets.QLineEdit(parent)431elif index.column() == 2: # Line width432editor = QtWidgets.QSpinBox(parent)433editor.setMaximum(99)434elif index.column() == 3: # Line style435editor = QtWidgets.QComboBox(parent)436editor.addItems(utils.DRAW_STYLES)437elif index.column() == 4: # Line color438editor = QtWidgets.QLineEdit(parent)439self.first = True440elif index.column() == 5: # Shape color441editor = QtWidgets.QLineEdit(parent)442self.first = True443elif index.column() == 6: # Transparency444editor = QtWidgets.QSpinBox(parent)445editor.setMaximum(100)446elif index.column() == 7: # Line print color447editor = QtWidgets.QLineEdit(parent)448self.first = True449return editor450
451def setEditorData(self, editor, index):452
453if index.column() == 0: # Layer on/off454editor.setChecked(index.data())455elif index.column() == 1: # Layer name456editor.setText(index.data())457elif index.column() == 2: # Line width458editor.setValue(index.data())459elif index.column() == 3: # Line style460editor.setCurrentIndex(utils.DRAW_STYLES.index(index.data()))461elif index.column() == 4: # Line color462editor.setText(str(index.data(QtCore.Qt.UserRole)))463if self.first:464c = index.data(QtCore.Qt.UserRole)465color = QtWidgets.QColorDialog.getColor(QtGui.QColor(int(c[0]*255),int(c[1]*255),int(c[2]*255)))466editor.setText(str(color.getRgbF()))467self.first = False468elif index.column() == 5: # Shape color469editor.setText(str(index.data(QtCore.Qt.UserRole)))470if self.first:471c = index.data(QtCore.Qt.UserRole)472color = QtWidgets.QColorDialog.getColor(QtGui.QColor(int(c[0]*255),int(c[1]*255),int(c[2]*255)))473editor.setText(str(color.getRgbF()))474self.first = False475elif index.column() == 6: # Transparency476editor.setValue(index.data())477elif index.column() == 7: # Line print color478editor.setText(str(index.data(QtCore.Qt.UserRole)))479if self.first:480c = index.data(QtCore.Qt.UserRole)481color = QtWidgets.QColorDialog.getColor(QtGui.QColor(int(c[0]*255),int(c[1]*255),int(c[2]*255)))482editor.setText(str(color.getRgbF()))483self.first = False484
485def setModelData(self, editor, model, index):486
487if index.column() == 0: # Layer on/off488model.setData(index,editor.isChecked())489elif index.column() == 1: # Layer name490model.setData(index,editor.text())491elif index.column() == 2: # Line width492model.setData(index,editor.value())493elif index.column() == 3: # Line style494model.setData(index,utils.DRAW_STYLES[editor.currentIndex()])495elif index.column() == 4: # Line color496model.setData(index,eval(editor.text()),QtCore.Qt.UserRole)497model.itemFromIndex(index).setIcon(getColorIcon(eval(editor.text())))498elif index.column() == 5: # Shape color499model.setData(index,eval(editor.text()),QtCore.Qt.UserRole)500model.itemFromIndex(index).setIcon(getColorIcon(eval(editor.text())))501elif index.column() == 6: # Transparency502model.setData(index,editor.value())503elif index.column() == 7: # Line prin color504model.setData(index,eval(editor.text()),QtCore.Qt.UserRole)505model.itemFromIndex(index).setIcon(getColorIcon(eval(editor.text())))506
507
508
509
510Gui.addCommand('Draft_Layer', Layer())511Gui.addCommand('Draft_LayerManager', LayerManager())512
513## @}
514