FreeCAD

Форк
0
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
# @{
31
from PySide.QtCore import QT_TRANSLATE_NOOP
32

33
import os
34
import FreeCAD
35
import FreeCADGui as Gui
36
import Draft
37
import Draft_rc
38
from draftguitools import gui_base
39
from draftutils import params
40
from draftutils import utils
41
from draftutils.translate import translate
42

43
# The module is used to prevent complaints from code checkers (flake8)
44
bool(Draft_rc.__name__)
45

46

47
def getColorIcon(color):
48

49
    "returns a QtGui.QIcon from a color 3-float tuple"
50

51
    from PySide import QtCore,QtGui
52
    c = QtGui.QColor(int(color[0]*255),int(color[1]*255),int(color[2]*255))
53
    im = QtGui.QImage(48,48,QtGui.QImage.Format_ARGB32)
54
    im.fill(c)
55
    px = QtGui.QPixmap.fromImage(im)
56
    return QtGui.QIcon(px)
57

58

59
class Layer(gui_base.GuiCommandSimplest):
60
    """GuiCommand to create a Layer object in the document."""
61

62
    def __init__(self):
63
        super(Layer, self).__init__(name=translate("draft","Layer"))
64

65
    def GetResources(self):
66
        """Set icon, menu and tooltip."""
67
        return {'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

71
    def Activated(self):
72
        """Execute when the command is called.
73

74
        It calls the `finish(False)` method of the active Draft command.
75
        """
76
        super(Layer, self).Activated()
77

78
        self.doc.openTransaction("Create Layer")
79
        Gui.addModule("Draft")
80
        Gui.doCommand("_layer_ = Draft.make_layer(name=None, line_color=None, shape_color=None, line_width=None, draw_style=None, transparency=None)")
81
        Gui.doCommand("FreeCAD.ActiveDocument.recompute()")
82
        self.doc.commitTransaction()
83

84

85
class LayerManager:
86

87
    """GuiCommand that displays a Layers manager dialog"""
88

89
    def GetResources(self):
90

91
        return {'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

95
    def Activated(self):
96

97
        from PySide import QtCore, QtGui, QtWidgets
98

99
        # store changes to be committed
100
        self.deleteList = []
101

102
        # create the dialog
103
        self.dialog = Gui.PySideUic.loadUi(":/ui/dialogLayers.ui")
104

105
        # set nice icons
106
        self.dialog.setWindowIcon(QtGui.QIcon(":/icons/Draft_Layer.svg"))
107
        self.dialog.buttonNew.setIcon(QtGui.QIcon(":/icons/document-new.svg"))
108
        self.dialog.buttonDelete.setIcon(QtGui.QIcon(":/icons/delete.svg"))
109
        self.dialog.buttonSelectAll.setIcon(QtGui.QIcon(":/icons/edit-select-all.svg"))
110
        self.dialog.buttonToggle.setIcon(QtGui.QIcon(":/icons/dagViewVisible.svg"))
111
        self.dialog.buttonIsolate.setIcon(QtGui.QIcon(":/icons/view-refresh.svg"))
112
        self.dialog.buttonCancel.setIcon(QtGui.QIcon(":/icons/edit_Cancel.svg"))
113
        self.dialog.buttonOK.setIcon(QtGui.QIcon(":/icons/edit_OK.svg"))
114

115
        # restore window geometry from stored state
116
        w = params.get_param("LayersManagerWidth")
117
        h = params.get_param("LayersManagerHeight")
118
        self.dialog.resize(w,h)
119

120
        # center the dialog over FreeCAD window
121
        mw = Gui.getMainWindow()
122
        self.dialog.move(mw.frameGeometry().topLeft() + mw.rect().center() - self.dialog.rect().center())
123

124
        # connect signals/slots
125
        self.dialog.buttonNew.clicked.connect(self.addItem)
126
        self.dialog.buttonDelete.clicked.connect(self.onDelete)
127
        self.dialog.buttonSelectAll.clicked.connect(self.dialog.tree.selectAll)
128
        self.dialog.buttonToggle.clicked.connect(self.onToggle)
129
        self.dialog.buttonCancel.clicked.connect(self.dialog.reject)
130
        self.dialog.buttonIsolate.clicked.connect(self.onIsolate)
131
        self.dialog.buttonOK.clicked.connect(self.accept)
132
        self.dialog.rejected.connect(self.reject)
133

134
        # set the model up
135
        self.model = QtGui.QStandardItemModel()
136
        self.dialog.tree.setModel(self.model)
137
        self.dialog.tree.setUniformRowHeights(True)
138
        self.dialog.tree.setItemDelegate(Layers_Delegate())
139
        self.dialog.tree.setItemsExpandable(False)
140
        self.dialog.tree.setRootIsDecorated(False) # removes spacing in first column
141
        self.dialog.tree.setSelectionMode(QtWidgets.QTreeView.ExtendedSelection) # allow to select many
142

143
        # fill the tree view
144
        self.update()
145

146
        # rock 'n roll!!!
147
        self.dialog.exec_()
148

149
    def accept(self):
150

151
        "when OK button is pressed"
152

153
        changed = False
154

155
        # delete layers
156
        for name in self.deleteList:
157
            if not changed:
158
                FreeCAD.ActiveDocument.openTransaction("Layers change")
159
                changed = True
160
            FreeCAD.ActiveDocument.removeObject(name)
161

162
        # apply changes
163
        for row in range(self.model.rowCount()):
164

165
            # get or create layer
166
            name = self.model.item(row,1).toolTip()
167
            obj = None
168
            if name:
169
                obj = FreeCAD.ActiveDocument.getObject(name)
170
            if not obj:
171
                if not changed:
172
                    FreeCAD.ActiveDocument.openTransaction("Layers change")
173
                    changed = True
174
                obj = Draft.make_layer(name=None, line_color=None, shape_color=None,
175
                                       line_width=None, draw_style=None, transparency=None)
176

177
            # visibility
178
            checked = True if self.model.item(row,0).checkState() == QtCore.Qt.Checked else False
179
            if checked != obj.ViewObject.Visibility:
180
                if not changed:
181
                    FreeCAD.ActiveDocument.openTransaction("Layers change")
182
                    changed = True
183
                obj.ViewObject.Visibility = checked
184

185
            # label
186
            label = self.model.item(row,1).text()
187
            if label:
188
                if obj.Label != label:
189
                    if not changed:
190
                        FreeCAD.ActiveDocument.openTransaction("Layers change")
191
                        changed = True
192
                    obj.Label = label
193

194
            # line width
195
            width = self.model.item(row,2).data(QtCore.Qt.DisplayRole)
196
            if width:
197
                if obj.ViewObject.LineWidth != width:
198
                    if not changed:
199
                        FreeCAD.ActiveDocument.openTransaction("Layers change")
200
                        changed = True
201
                    obj.ViewObject.LineWidth = width
202

203
            # draw style
204
            style = self.model.item(row,3).text()
205
            if style:
206
                if obj.ViewObject.DrawStyle != style:
207
                    if not changed:
208
                        FreeCAD.ActiveDocument.openTransaction("Layers change")
209
                        changed = True
210
                    obj.ViewObject.DrawStyle = style
211

212
            # line color
213
            color = self.model.item(row,4).data(QtCore.Qt.UserRole)
214
            if color:
215
                if obj.ViewObject.LineColor[3:] != color:
216
                    if not changed:
217
                        FreeCAD.ActiveDocument.openTransaction("Layers change")
218
                        changed = True
219
                    obj.ViewObject.LineColor = color
220

221
            # shape color
222
            color = self.model.item(row,5).data(QtCore.Qt.UserRole)
223
            if color:
224
                if obj.ViewObject.ShapeColor[3:] != color:
225
                    if not changed:
226
                        FreeCAD.ActiveDocument.openTransaction("Layers change")
227
                        changed = True
228
                    obj.ViewObject.ShapeColor = color
229

230
            # transparency
231
            transparency = self.model.item(row,6).data(QtCore.Qt.DisplayRole)
232
            if transparency:
233
                if obj.ViewObject.Transparency != transparency:
234
                    if not changed:
235
                        FreeCAD.ActiveDocument.openTransaction("Layers change")
236
                        changed = True
237
                    obj.ViewObject.Transparency = transparency
238

239
            # line print color
240
            color = self.model.item(row,7).data(QtCore.Qt.UserRole)
241
            if color:
242
                if not "LinePrintColor" in obj.ViewObject.PropertiesList:
243
                    if hasattr(obj.ViewObject.Proxy,"set_properties"):
244
                        obj.ViewObject.Proxy.set_properties(obj.ViewObject)
245
                if "LinePrintColor" in obj.ViewObject.PropertiesList:
246
                    if obj.ViewObject.LinePrintColor[3:] != color:
247
                        if not changed:
248
                            FreeCAD.ActiveDocument.openTransaction("Layers change")
249
                            changed = True
250
                        obj.ViewObject.LinePrintColor = color
251

252
        # recompute
253
        if changed:
254
            FreeCAD.ActiveDocument.commitTransaction()
255
            FreeCAD.ActiveDocument.recompute()
256

257
        # exit
258
        self.dialog.reject()
259

260
    def reject(self):
261

262
        "when Cancel button is pressed or dialog is closed"
263

264
        # save dialog size
265
        params.set_param("LayersManagerWidth", self.dialog.width())
266
        params.set_param("LayersManagerHeight", self.dialog.height())
267

268
        return True
269

270
    def update(self):
271

272
        "rebuild the model from document contents"
273

274
        self.model.clear()
275

276
        # set header
277
        self.model.setHorizontalHeaderLabels([translate("Draft","On"),
278
                                              translate("Draft","Name"),
279
                                              translate("Draft","Line width"),
280
                                              translate("Draft","Draw style"),
281
                                              translate("Draft","Line color"),
282
                                              translate("Draft","Face color"),
283
                                              translate("Draft","Transparency"),
284
                                              translate("Draft","Line print color")])
285
        self.dialog.tree.header().setDefaultSectionSize(72)
286
        self.dialog.tree.setColumnWidth(0,32) # on/off column
287
        self.dialog.tree.setColumnWidth(1,128) # name column
288

289
        # populate
290
        objs = [obj for obj in FreeCAD.ActiveDocument.Objects if Draft.getType(obj) == "Layer"]
291
        objs.sort(key=lambda o:o.Label)
292
        for obj in objs:
293
            self.addItem(obj)
294

295
    def addItem(self,obj=None):
296

297
        "adds a row to the model"
298

299
        from PySide import QtCore, QtGui
300

301
        # create row with default values
302
        onItem = QtGui.QStandardItem()
303
        onItem.setCheckable(True)
304
        onItem.setCheckState(QtCore.Qt.Checked)
305
        nameItem = QtGui.QStandardItem(translate("Draft", "New Layer"))
306
        widthItem = QtGui.QStandardItem()
307
        widthItem.setData(params.get_param_view("DefaultShapeLineWidth"), QtCore.Qt.DisplayRole)
308
        styleItem = QtGui.QStandardItem(utils.DRAW_STYLES[params.get_param("DefaultDrawStyle")])
309
        lineColorItem = QtGui.QStandardItem()
310
        lineColorItem.setData(
311
            utils.get_rgba_tuple(params.get_param_view("DefaultShapeLineColor"))[:3],
312
            QtCore.Qt.UserRole
313
        )
314
        shapeColorItem = QtGui.QStandardItem()
315
        shapeColorItem.setData(
316
            utils.get_rgba_tuple(params.get_param_view("DefaultShapeColor"))[:3],
317
            QtCore.Qt.UserRole
318
        )
319
        transparencyItem = QtGui.QStandardItem()
320
        transparencyItem.setData(
321
            params.get_param_view("DefaultShapeTransparency"),
322
            QtCore.Qt.DisplayRole
323
        )
324
        linePrintColorItem = QtGui.QStandardItem()
325
        linePrintColorItem.setData(
326
            utils.get_rgba_tuple(params.get_param("DefaultPrintColor"))[:3],
327
            QtCore.Qt.UserRole
328
        )
329

330
        # populate with object data
331
        if obj:
332
            onItem.setCheckState(QtCore.Qt.Checked if obj.ViewObject.Visibility else QtCore.Qt.Unchecked)
333
            nameItem.setText(obj.Label)
334
            nameItem.setToolTip(obj.Name)
335
            widthItem.setData(obj.ViewObject.LineWidth,QtCore.Qt.DisplayRole)
336
            styleItem.setText(obj.ViewObject.DrawStyle)
337
            lineColorItem.setData(obj.ViewObject.LineColor[:3],QtCore.Qt.UserRole)
338
            shapeColorItem.setData(obj.ViewObject.ShapeColor[:3],QtCore.Qt.UserRole)
339
            transparencyItem.setData(obj.ViewObject.Transparency,QtCore.Qt.DisplayRole)
340
            if hasattr(obj.ViewObject,"LinePrintColor"):
341
                linePrintColorItem.setData(obj.ViewObject.LinePrintColor[:3],QtCore.Qt.UserRole)
342
        lineColorItem.setIcon(getColorIcon(lineColorItem.data(QtCore.Qt.UserRole)))
343
        shapeColorItem.setIcon(getColorIcon(shapeColorItem.data(QtCore.Qt.UserRole)))
344
        linePrintColorItem.setIcon(getColorIcon(linePrintColorItem.data(QtCore.Qt.UserRole)))
345

346
        # append row
347
        self.model.appendRow([onItem,
348
                              nameItem,
349
                              widthItem,
350
                              styleItem,
351
                              lineColorItem,
352
                              shapeColorItem,
353
                              transparencyItem,
354
                              linePrintColorItem])
355

356
    def onDelete(self):
357

358
        "delete selected rows"
359

360
        rows = []
361
        for index in self.dialog.tree.selectedIndexes():
362
            if not index.row() in rows:
363
                rows.append(index.row())
364

365
            # append layer name to the delete list
366
            if index.column() == 1:
367
                name = self.model.itemFromIndex(index).toolTip()
368
                if name:
369
                    if not name in self.deleteList:
370
                        self.deleteList.append(name)
371

372
        # delete rows starting from the lowest, to not alter row indexes while deleting
373
        rows.sort()
374
        rows.reverse()
375
        for row in rows:
376
            self.model.takeRow(row)
377

378
    def onToggle(self):
379

380
        "toggle selected layers on/off"
381

382
        from PySide import QtCore
383

384
        state = None
385
        for index in self.dialog.tree.selectedIndexes():
386
            if index.column() == 0:
387
                # get state from first selected row
388
                if state is None:
389
                    if self.model.itemFromIndex(index).checkState() == QtCore.Qt.Checked:
390
                        state = QtCore.Qt.Unchecked
391
                    else:
392
                        state = QtCore.Qt.Checked
393
                self.model.itemFromIndex(index).setCheckState(state)
394

395
    def onIsolate(self):
396

397
        "isolates the selected layers (turns all the others off"
398

399
        from PySide import QtCore
400

401
        onrows = []
402
        for index in self.dialog.tree.selectedIndexes():
403
            if not index.row() in onrows:
404
                onrows.append(index.row())
405
        for row in range(self.model.rowCount()):
406
            if not row in onrows:
407
                self.model.item(row,0).setCheckState(QtCore.Qt.Unchecked)
408

409

410
if FreeCAD.GuiUp:
411

412
    from PySide import QtCore, QtGui, QtWidgets
413

414
    class Layers_Delegate(QtWidgets.QStyledItemDelegate):
415

416
        "model delegate"
417

418
        def __init__(self, parent=None, *args):
419

420
            QtWidgets.QStyledItemDelegate.__init__(self, parent, *args)
421
            # setEditorData() is triggered several times.
422
            # But we want to show the color dialog only the first time
423
            self.first = True
424

425
        def createEditor(self,parent,option,index):
426

427
            if index.column() == 0: # Layer on/off
428
                editor = QtWidgets.QCheckBox(parent)
429
            if index.column() == 1: # Layer name
430
                editor = QtWidgets.QLineEdit(parent)
431
            elif index.column() == 2: # Line width
432
                editor = QtWidgets.QSpinBox(parent)
433
                editor.setMaximum(99)
434
            elif index.column() == 3: # Line style
435
                editor = QtWidgets.QComboBox(parent)
436
                editor.addItems(utils.DRAW_STYLES)
437
            elif index.column() == 4: # Line color
438
                editor = QtWidgets.QLineEdit(parent)
439
                self.first = True
440
            elif index.column() == 5: # Shape color
441
                editor = QtWidgets.QLineEdit(parent)
442
                self.first = True
443
            elif index.column() == 6: # Transparency
444
                editor = QtWidgets.QSpinBox(parent)
445
                editor.setMaximum(100)
446
            elif index.column() == 7: # Line print color
447
                editor = QtWidgets.QLineEdit(parent)
448
                self.first = True
449
            return editor
450

451
        def setEditorData(self, editor, index):
452

453
            if index.column() == 0: # Layer on/off
454
                editor.setChecked(index.data())
455
            elif index.column() == 1: # Layer name
456
                editor.setText(index.data())
457
            elif index.column() == 2: # Line width
458
                editor.setValue(index.data())
459
            elif index.column() == 3: # Line style
460
                editor.setCurrentIndex(utils.DRAW_STYLES.index(index.data()))
461
            elif index.column() == 4: # Line color
462
                editor.setText(str(index.data(QtCore.Qt.UserRole)))
463
                if self.first:
464
                    c = index.data(QtCore.Qt.UserRole)
465
                    color = QtWidgets.QColorDialog.getColor(QtGui.QColor(int(c[0]*255),int(c[1]*255),int(c[2]*255)))
466
                    editor.setText(str(color.getRgbF()))
467
                    self.first = False
468
            elif index.column() == 5: # Shape color
469
                editor.setText(str(index.data(QtCore.Qt.UserRole)))
470
                if self.first:
471
                    c = index.data(QtCore.Qt.UserRole)
472
                    color = QtWidgets.QColorDialog.getColor(QtGui.QColor(int(c[0]*255),int(c[1]*255),int(c[2]*255)))
473
                    editor.setText(str(color.getRgbF()))
474
                    self.first = False
475
            elif index.column() == 6: # Transparency
476
                editor.setValue(index.data())
477
            elif index.column() == 7:  # Line print color
478
                editor.setText(str(index.data(QtCore.Qt.UserRole)))
479
                if self.first:
480
                    c = index.data(QtCore.Qt.UserRole)
481
                    color = QtWidgets.QColorDialog.getColor(QtGui.QColor(int(c[0]*255),int(c[1]*255),int(c[2]*255)))
482
                    editor.setText(str(color.getRgbF()))
483
                    self.first = False
484

485
        def setModelData(self, editor, model, index):
486

487
            if index.column() == 0: # Layer on/off
488
                model.setData(index,editor.isChecked())
489
            elif index.column() == 1: # Layer name
490
                model.setData(index,editor.text())
491
            elif index.column() == 2: # Line width
492
                model.setData(index,editor.value())
493
            elif index.column() == 3: # Line style
494
                model.setData(index,utils.DRAW_STYLES[editor.currentIndex()])
495
            elif index.column() == 4: # Line color
496
                model.setData(index,eval(editor.text()),QtCore.Qt.UserRole)
497
                model.itemFromIndex(index).setIcon(getColorIcon(eval(editor.text())))
498
            elif index.column() == 5: # Shape color
499
                model.setData(index,eval(editor.text()),QtCore.Qt.UserRole)
500
                model.itemFromIndex(index).setIcon(getColorIcon(eval(editor.text())))
501
            elif index.column() == 6: # Transparency
502
                model.setData(index,editor.value())
503
            elif index.column() == 7: # Line prin color
504
                model.setData(index,eval(editor.text()),QtCore.Qt.UserRole)
505
                model.itemFromIndex(index).setIcon(getColorIcon(eval(editor.text())))
506

507

508

509

510
Gui.addCommand('Draft_Layer', Layer())
511
Gui.addCommand('Draft_LayerManager', LayerManager())
512

513
## @}
514

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.