forked from pgilfernandez/FreeCAD_AliasManager
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaliasManager_popup.py
More file actions
374 lines (306 loc) · 16.1 KB
/
aliasManager_popup.py
File metadata and controls
374 lines (306 loc) · 16.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# ============================================================================================================
# ============================================================================================================
# == ==
# == alias Manager ==
# == ==
# ============================================================================================================
# ============================================================================================================
# ABOUT
# ============================================================================================================
# version v1.0
# Macro developed for FreeCAD (http://www.freecadweb.org/).
# This macro helps managing aliases inside FreeCAD Spreadsheet workbench. It is able to:
# - create aliases based on first column (A column)
# - delete aliases placed on a column
# - move aliases from one column to other one
# - create a "part family", that's it, create different files for each column in a range. It will add
# to the original name a suffix based on first row (1)
# More information might be found on FreeCAD forums: http://forum.freecadweb.org/
#
#
# LICENSE
# ============================================================================================================
# Original work done by tarihatari (https://github.com/tarihatari/FreeCAD_Macros)
# Improved by Pablo Gil Fernandez
#
# Copyright (c) 2016 tarihatari & Pablo Gil Fernandez
#
# This work is licensed under GNU Lesser General Public License (LGPL).
# To view a copy of this license, visit https://www.gnu.org/licenses/lgpl-3.0.html.
#
# ============================================================================================================
__title__ = "alias manager"
__author__ = "Pablo Gil Fernandez"
__version__ = "01.00"
__date__ = "20/11/2016"
__Comment__ = "This macro helps managing aliases inside FreeCAD Spreadsheet workbench. It is able to create, delete, move aliases and create a 'part family' group of files"
__Wiki__ = "https://github.com/pgilfernandez/FreeCAD_AliasManager"
__Help__ = "https://github.com/pgilfernandez/FreeCAD_AliasManager"
__Status__ = "stable"
__Requires__ = "FreeCAD 0.16"
from PySide import QtGui, QtCore
from FreeCAD import Gui
import os
import string
App = FreeCAD
Gui = FreeCADGui
# ========================================================
# ===== Info popup window ================================
# ========================================================
class infoPopup(QtGui.QDialog):
def __init__(self, parent=None):
self.dialog = None
self.dialog = QtGui.QDialog()
self.dialog.resize(360,400)
self.dialog.setWindowTitle("About...")
info = QtGui.QTextEdit("<h2>INFORMATION</h2><hr><br>This macro helps managing aliases inside FreeCAD Spreadsheet workbench. It is able to create, delete, move aliases and create a 'part family' group of files.<br><h2>USAGE</h2><hr><ul><li><b>set aliases</b>: based on first column (A column), it will create aliases for the range given. If an alias is already set for any other cell the command won't work, it will be needed to clear them before setting them again.</li><li><b>Clear aliases</b>: it will clear all aliases inside the given range of cells (only one column).</li><li><b>Move aliases</b>: it will clear and set aliases <b>from</b> a given column <b>to</b> a new one.</li><li><b>Generate part family</b>: it will create different files for each column in a range. It will add to the original name a suffix based on first row. If an alias is already set for any other cell the command won't work, it will be needed to clear them before running the command.</li></ul><h2>LICENCE</h2><hr>Original work done by <b>tarihatari</b> (<a href='https://github.com/tarihatari/FreeCAD_Macros'>https://github.com/tarihatari/FreeCAD_Macros</a>)<br>Improved by <b>Pablo Gil Fernandez</b><br><br>Copyright (c) 2016 tarihatari & Pablo Gil Fernandez<br><br>This work is licensed under GNU Lesser General Public License (LGPL).<br>To view a copy of this license, visit <a href='https://www.gnu.org/licenses/lgpl-3.0.html'>https://www.gnu.org/licenses/lgpl-3.0.html</a>.<br>")
info.setReadOnly(True)
info.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
okbox = QtGui.QDialogButtonBox(self.dialog)
okbox.setOrientation(QtCore.Qt.Horizontal)
okbox.setStandardButtons(QtGui.QDialogButtonBox.Close)
okbox.setFocus()
grid2 = QtGui.QGridLayout()
grid2.setSpacing(10)
grid2.addWidget(info, 0, 0)
grid2.addWidget(okbox, 1, 0)
self.dialog.setLayout(grid2)
QtCore.QObject.connect(okbox, QtCore.SIGNAL("rejected()"), self.close)
QtCore.QMetaObject.connectSlotsByName(self.dialog)
self.dialog.show()
self.dialog.exec_()
def close(self):
self.dialog.close()
# ========================================================
# ===== Main code ========================================
# ========================================================
# ===== Global variables ==============================================
alphabet_list = list(string.ascii_uppercase)
class p():
def aliasManager(self):
try:
# ===== Variables ==============================================
mode = self.d1.currentText()
column_from = self.d2.currentText()
column_to = self.d3.currentText()
row_from = self.d4.value()
row_to = self.d5.value()
# ===== Mode - Set ==============================================
if mode == "Set aliases":
for i in range(row_from,row_to+1):
cell_from = 'A' + str(i)
cell_to = str(column_from) + str(i)
App.ActiveDocument.Spreadsheet.setAlias(cell_to, '')
App.ActiveDocument.Spreadsheet.setAlias(cell_to, self.strip_apostrophe(App.ActiveDocument.Spreadsheet.getContents(cell_from)))
App.ActiveDocument.recompute()
FreeCAD.Console.PrintMessage("\nAliases set\n")
# ===== Mode - Clear ==============================================
elif mode == "Clear aliases":
for i in range(row_from,row_to+1):
cell_to = str(column_from) + str(i)
App.ActiveDocument.Spreadsheet.setAlias(cell_to, '')
App.ActiveDocument.recompute()
FreeCAD.Console.PrintMessage("\nAliases cleared\n")
# ===== Mode - Move ==============================================
elif mode == "Move aliases":
self.d3.setDisabled(False)
for i in range(row_from,row_to+1):
cell_reference = 'A'+ str(i)
cell_from = column_from + str(i)
cell_to = column_to + str(i)
App.ActiveDocument.Spreadsheet.setAlias(cell_from, '')
App.ActiveDocument.recompute()
App.ActiveDocument.Spreadsheet.setAlias(cell_to, self.strip_apostrophe(App.ActiveDocument.Spreadsheet.getContents(cell_reference)))
App.ActiveDocument.recompute()
FreeCAD.Console.PrintMessage("\nAliases moved\n")
# ===== Mode - Generate part family ==============================================
elif mode == "Generate part family":
doc = FreeCAD.ActiveDocument
if not doc.FileName:
FreeCAD.Console.PrintError('\nMust save project first\n')
docDir, docFilename = os.path.split(doc.FileName)
filePrefix = os.path.splitext(docFilename)[0]
def char_range(c1, c2):
"""Generates the characters from `c1` to `c2`, inclusive."""
for c in xrange(ord(c1), ord(c2)+1):
yield str.capitalize(chr(c))
fam_range = []
for c in char_range(str(column_from), str(column_to)):
fam_range.append(c)
for index in range(len(fam_range)):
# set aliases
for i in range(row_from,row_to+1):
cell_reference = 'A' + str(i)
cell_from = str(fam_range[index-1]) + str(i)
cell_to = str(fam_range[index]) + str(i)
App.ActiveDocument.Spreadsheet.setAlias(cell_from, '')
App.ActiveDocument.recompute()
App.ActiveDocument.Spreadsheet.setAlias(cell_to, self.strip_apostrophe(App.ActiveDocument.Spreadsheet.getContents(cell_reference)))
App.ActiveDocument.recompute()
sfx = str(fam_range[index]) + '1'
# save file
suffix = App.ActiveDocument.Spreadsheet.getContents(sfx)
filename = filePrefix + '_' + suffix + '.fcstd'
filePath = os.path.join(docDir, filename)
FreeCAD.Console.PrintMessage("\nSaving view to %s\n" % filePath)
App.getDocument(filePrefix).saveAs(filePath)
# Clear last aliases created:
for j in range(row_from,row_to+1):
cell_to = str(column_to) + str(j)
App.ActiveDocument.Spreadsheet.setAlias(cell_to, '')
App.ActiveDocument.recompute()
# Turn working file to original naming:
filename = filePrefix + '.fcstd'
filePath = os.path.join(docDir, filename)
FreeCAD.Console.PrintMessage("\nSaving original view to %s\n" % filePath)
App.getDocument(filePrefix).saveAs(filePath)
FreeCAD.Console.PrintMessage("\nPart family files generated\n")
# ===== If errors ==============================================
else:
FreeCAD.Console.PrintError("\nError or 'TODO'\n")
except:
FreeCAD.Console.PrintError("\nUnable to complete task\n")
self.close()
def close(self):
self.dialog.hide()
def strip_apostrophe(self, txt):
"""Remove leading apostrophe from text.
Starting with FreeCAD 0.21, when user enters cell text in a
spreadsheet, an apostrophe (') will be placed in front of the
text by default. This raises "Illegal Macro" exceptions in
setAlias()
"""
if txt.startswith("'"):
return(txt[1:])
return(txt)
# ========================================================
# ===== GUI menu ========================================
# ========================================================
def __init__(self):
infoIcon = ['16 16 3 1',
' c None',
'+ c #444444',
'. c #e6e6e6',
' ...... ',
' .......... ',
' ......++.... ',
' .......++.....',
' ..............',
'.....+++++......',
'....+++++.......',
'.......++.......',
'.......++.......',
'.......+........',
'......++........',
' .....++.+.....',
' .....++++.....',
' .....++..... ',
' .......... ',
' ...... ']
# Hide/show "to column" label and spinbox based on mode type
def disableWidget(currentIndex):
if self.d1.currentText() == "Set aliases":
iN3.hide()
self.d3.setEnabled(False)
self.d3.hide()
elif self.d1.currentText() == "Clear aliases":
iN3.hide()
self.d3.setEnabled(False)
self.d3.hide()
else:
iN3.show()
self.d3.setEnabled(True)
self.d3.show()
self.dialog = None
self.dialog = QtGui.QDialog()
self.dialog.resize(400,140)
self.dialog.setWindowTitle("Alias manager")
iN1 = QtGui.QLabel("mode:")
iN1.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.d1 = QtGui.QComboBox()
self.d1.addItem("Set aliases")
self.d1.addItem("Clear aliases")
self.d1.addItem("Move aliases")
self.d1.addItem("Generate part family")
self.d1.setCurrentIndex(0) # set default item
self.d1.currentIndexChanged['QString'].connect(disableWidget)
iN2a = QtGui.QLabel("column:")
iN2a.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
iN2b = QtGui.QLabel("from")
iN2b.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter)
self.d2 = QtGui.QComboBox()
for i in range(0,26):
self.d2.addItem(alphabet_list[i])
for i in range(0,26):
for j in range(0,26):
self.d2.addItem(alphabet_list[i] + alphabet_list[j])
self.d2.setCurrentIndex(1) # set default item
iN3 = QtGui.QLabel("to")
iN3.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter)
iN3.hide() # set initial state hidden
self.d3 = QtGui.QComboBox()
for i in range(0,26):
self.d3.addItem(alphabet_list[i])
for i in range(0,26):
for j in range(0,26):
self.d3.addItem(alphabet_list[i] + alphabet_list[j])
self.d3.setCurrentIndex(2) # set default item
self.d3.setEnabled(False) # set initial state to not editable
self.d3.hide() # set initial state hidden
iN4 = QtGui.QLabel("from row:")
iN4.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.d4 = QtGui.QSpinBox()
self.d4.setValue(2.0) # set default item
self.d4.setSingleStep(1.0)
self.d4.setMinimum(1.0)
iN5 = QtGui.QLabel("to row:")
iN5.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.d5 = QtGui.QSpinBox()
self.d5.setValue(4.0) # set default item
self.d5.setSingleStep(1.0)
self.d5.setMinimum(1.0)
# Info button
self.d6 = QtGui.QPushButton("")
self.d6.setFixedWidth(40)
self.d6.setIcon(QtGui.QIcon(QtGui.QPixmap(infoIcon)))
self.d6.clicked.connect(self.popup)
okbox = QtGui.QDialogButtonBox(self.dialog)
okbox.setOrientation(QtCore.Qt.Horizontal)
okbox.setStandardButtons(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Close)
grid = QtGui.QGridLayout()
grid.setSpacing(10)
# Mode
grid.addWidget(self.d1, 0, 0, 1, 3)
# column, column from
grid.addWidget(iN2a, 2, 0, 1, 1)
grid.addWidget(iN2b, 1, 1, 1, 1)
grid.addWidget(self.d2, 2, 1, 1, 1)
# column to
grid.addWidget(iN3, 1, 2, 1, 1)
grid.addWidget(self.d3, 2, 2, 1, 1)
# from row
grid.addWidget(iN4, 3, 0, 1, 1)
grid.addWidget(self.d4, 3, 1, 1, 1)
# to row
grid.addWidget(iN5, 4, 0, 1, 1)
grid.addWidget(self.d5, 4, 1)
# + info
grid.addWidget(self.d6, 6, 0, 1, 1)
# cancel, OK
grid.addWidget(okbox, 6, 1, 1, 2)
self.dialog.setLayout(grid)
# # Set Tab order (not needed anymore because of enabling/disabling spinboxes)
# self.dialog.setTabOrder(self.d3, self.d1)
# self.dialog.setTabOrder(self.d1, self.d2)
# self.dialog.setTabOrder(self.d2, self.d4)
# self.dialog.setTabOrder(self.d4, self.d5)
# self.dialog.setTabOrder(self.d5, self.d3)
QtCore.QObject.connect(okbox, QtCore.SIGNAL("rejected()"), self.close)
QtCore.QObject.connect(okbox, QtCore.SIGNAL("accepted()"), self.aliasManager)
QtCore.QMetaObject.connectSlotsByName(self.dialog)
self.dialog.show()
self.dialog.exec_()
def popup(self):
self.dialog2 = infoPopup()
self.dialog2.exec_()
p()