From d51363fefe370e5cb7ba0f201bdbacc409c102cc Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 17 Apr 2020 18:51:30 +0200 Subject: [PATCH] Draft: Annotation styles editor --- .../gui_annotationstyleeditor.py | 145 ++++++++++++++---- 1 file changed, 111 insertions(+), 34 deletions(-) diff --git a/src/Mod/Draft/draftguitools/gui_annotationstyleeditor.py b/src/Mod/Draft/draftguitools/gui_annotationstyleeditor.py index eed1d8daf8..08c1dd698b 100644 --- a/src/Mod/Draft/draftguitools/gui_annotationstyleeditor.py +++ b/src/Mod/Draft/draftguitools/gui_annotationstyleeditor.py @@ -88,7 +88,12 @@ class Draft_AnnotationStyleEditor: self.form.comboBoxStyles.currentIndexChanged.connect(self.on_style_changed) self.form.pushButtonDelete.clicked.connect(self.on_delete) self.form.pushButtonRename.clicked.connect(self.on_rename) - # TODO connect all other controls to a function that saves to self.styles + for attr in EMPTYSTYLE.keys(): + control = getattr(self.form,attr) + for signal in ["textChanged","valueChanged","stateChanged"]: + if hasattr(control,signal): + getattr(control,signal).connect(self.update_style) + break # show editor dialog result = self.form.exec_() @@ -101,75 +106,147 @@ class Draft_AnnotationStyleEditor: def read_meta(self): + """reads the document Meta property and returns a dict""" + styles = {} meta = FreeCAD.ActiveDocument.Meta - for key,value in meta.keys: + for key,value in meta.items(): if key.startswith("Draft_Style_"): styles[key[12:]] = json.loads(value) return styles def save_meta(self,styles): + """saves a dict to the document Meta property and updates objects""" + + # save meta + changedstyles = [] meta = FreeCAD.ActiveDocument.Meta - for key,value in styles: - meta["Draft_Style_"+key] = json.dumps(value) + for key,value in styles.items(): + strvalue = json.dumps(value) + if meta["Draft_Style_"+key] and (meta["Draft_Style_"+key] != strvalue): + changedstyles.append(style) + meta["Draft_Style_"+key] = strvalue FreeCAD.ActiveDocument.Meta = meta - # TODO must also save meta and also update the styles - # of comboboxes of all dimensions and texts - # found in the doc. If a dimension/text uses a style - # that has now been deleted, that case must also be handled - # maybe warn the user if the style is in use in on_delete? - + # propagate changes to all annotations + for obj in self.get_annotations(): + if obj.ViewObject.AnnotationStyle in styles.keys(): + if obj.ViewObject.AnnotationStyle in changedstyles: + for attr,attrvalue in styles[obj.ViewObject.AnnotationStyle].items(): + if hasattr(obj.ViewObject,attr): + setattr(obj.ViewObject,attr,attrvalue) + else: + obj.ViewObject.AnnotationStyle = " " + obj.ViewObject.AnnotationStyle == [" "] + styles.keys() def on_style_changed(self,index): + + """called when the styles combobox is changed""" from PySide import QtGui - if index <= 1: + if index <= 1: + # nothing happens self.form.pushButtonDelete.setEnabled(False) self.form.pushButtonRename.setEnabled(False) self.fill_editor(None) - if index == 1: + if index == 1: + # Add new... entry reply = QtGui.QInputDialog.getText(None, "Create new style","Style name:") - if reply[1]: # OK or Enter pressed + if reply[1]: + # OK or Enter pressed name = reply[0] - self.form.comboBoxStyles.addItem(name) - self.form.comboBoxStyles.setCurrentIndex(self.form.comboBoxStyles.count()-1) - elif index > 1: + if name in self.styles: + reply = QtGui.QMessageBox.information(None,"Style exists","This style name already exists") + else: + # create new default style + self.styles[name] = EMPTYSTYLE + self.form.comboBoxStyles.addItem(name) + self.form.comboBoxStyles.setCurrentIndex(self.form.comboBoxStyles.count()-1) + elif index > 1: + # Existing style self.form.pushButtonDelete.setEnabled(True) self.form.pushButtonRename.setEnabled(True) self.fill_editor(self.form.comboBoxStyles.itemText(index)) def on_delete(self): - - index = self.form.comboBox.currentIndex() - if index > 1: - style = self.form.comboBoxStyles.itemText(index) - self.form.comboBoxStyles.removeItem(index) - del self.styles[style] - - def on_rename(self): + + """called when the Delete button is pressed""" from PySide import QtGui index = self.form.comboBox.currentIndex() - if index > 1: - style = self.form.comboBoxStyles.itemText(index) - reply = QtGui.QInputDialog.getText(None, "Rename style","New name:",QtGui.QLineEdit.Normal,style) - if reply[1]: # OK or Enter pressed - newname = reply[0] - self.form.comboBoxStyles.setItemText(index,newname) - value = self.styles[style] - del self.styles[style] - self.styles[newname] = value + style = self.form.comboBoxStyles.itemText(index) + if self.get_style_users(style): + reply = QtGui.QMessageBox.question(None, "Style in use", "This style is used by some objects in this document. Are you sure?", + QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) + if reply == QtGui.QMessageBox.No: + return + self.form.comboBoxStyles.removeItem(index) + del self.styles[style] + + def on_rename(self): + + """called when the Rename button is pressed""" + + from PySide import QtGui + + index = self.form.comboBox.currentIndex() + style = self.form.comboBoxStyles.itemText(index) + reply = QtGui.QInputDialog.getText(None, "Rename style","New name:",QtGui.QLineEdit.Normal,style) + if reply[1]: + # OK or Enter pressed + newname = reply[0] + self.form.comboBoxStyles.setItemText(index,newname) + value = self.styles[style] + del self.styles[style] + self.styles[newname] = value def fill_editor(self,style): + + """fills the editor fields with the contents of a style""" if style is None: style = EMPTYSTYLE - for key,value in style: + for key,value in style.items(): setattr(self.form,key,value) + def update_style(self,arg=None): + + """updates the current style with the values from the editor""" + + index = self.form.comboBox.currentIndex() + if index > 1: + values = {} + style = self.form.comboBoxStyles.itemText(index) + for key in EMPTYSTYLE.keys(): + control = getattr(self.form,key) + for attr in ["text","value","state"]: + if hasattr(control,attr): + values[key] = getattr(control,attr) + self.styles[style] = values + + def get_annotations(self): + + """gets all the objects that support annotation styles""" + + users = [] + for obj in FreeCAD.ActiveDocument.Objects: + vobj = obj.ViewObject + if hasattr(vobj,"AnnotationStyle"): + users.append(obj) + return users + + def get_style_users(self,style): + + """get all objects using a certain style""" + + users = [] + for obj in self.get_annotations(): + if obj.ViewObject.AnnotationStyle == style: + users.append(obj) + return users + FreeCADGui.addCommand('Draft_AnnotationStyleEditor', Draft_AnnotationStyleEditor())