diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt
index 02f2d4e9aa..d62862af72 100644
--- a/src/Mod/Draft/CMakeLists.txt
+++ b/src/Mod/Draft/CMakeLists.txt
@@ -102,6 +102,7 @@ SET(Creator_tools
SET(Draft_GUI_tools
draftguitools/__init__.py
+ draftguitools/gui_annotationstyleeditor.py
draftguitools/gui_base.py
draftguitools/gui_base_original.py
draftguitools/gui_tool_utils.py
diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py
index a107284705..398666b2de 100644
--- a/src/Mod/Draft/DraftTools.py
+++ b/src/Mod/Draft/DraftTools.py
@@ -92,6 +92,7 @@ from draftguitools.gui_heal import Heal
from draftguitools.gui_dimension_ops import Draft_FlipDimension
from draftguitools.gui_lineslope import Draft_Slope
import draftguitools.gui_arrays
+import draftguitools.gui_annotationstyleeditor
# import DraftFillet
import drafttaskpanels.task_scale as task_scale
diff --git a/src/Mod/Draft/Resources/ui/dialog_AnnotationStyleEditor.ui b/src/Mod/Draft/Resources/ui/dialog_AnnotationStyleEditor.ui
index eddf18cecc..01cf23af84 100644
--- a/src/Mod/Draft/Resources/ui/dialog_AnnotationStyleEditor.ui
+++ b/src/Mod/Draft/Resources/ui/dialog_AnnotationStyleEditor.ui
@@ -6,12 +6,12 @@
0
0
- 418
- 694
+ 453
+ 424
- Dialog
+ Annotation Styles Editor
-
@@ -82,307 +82,314 @@
-
-
-
- Text
+
+
+ QFrame::Plain
-
-
-
-
-
- Font size
-
-
-
- -
-
-
- Font name
-
-
-
- -
-
-
- Line spacing
-
-
-
- -
-
-
- The size of the text in real-world units
-
-
-
-
-
-
- -
-
-
- The spacing between lines of text in real-world units
-
-
-
-
-
-
- -
-
-
- The font to use for texts and dimensions
-
-
-
-
-
-
- -
-
-
- Units
+
+ Qt::ScrollBarAsNeeded
-
-
-
-
-
- Scale multiplier
-
-
-
- -
-
-
- Decimals
-
-
-
- -
-
-
- Únit override
-
-
-
- -
-
-
- Show unit
-
-
-
- -
-
-
- A multiplier value that affects distances shown by dimensions
-
-
- 4
-
-
- 1.000000000000000
-
-
-
- -
-
-
- Forces dimensions to be shown in a specific unit
-
-
-
- -
-
-
- The number of decimals to show on dimensions
-
-
-
- -
-
-
- Shows the units suffix on dimensions or not
-
-
- Qt::RightToLeft
-
-
-
-
-
-
-
-
-
- -
-
-
- Line and arrows
+
+ true
-
-
-
-
-
- Line width
-
-
-
- -
-
-
- Extension overshoot
-
-
-
- -
-
-
- Arrow size
-
-
-
- -
-
-
- Show lines
-
-
-
- -
-
-
- Dimension overshoot
-
-
-
- -
-
-
- Extension lines
-
-
-
- -
-
-
- Arrow type
-
-
-
- -
-
-
- Line / text color
-
-
-
- -
-
-
- Shows the dimension line or not
-
-
- Qt::RightToLeft
-
-
-
-
-
- true
-
-
-
- -
-
-
- The width of the dimension lines
-
-
- px
-
-
- 1
-
-
-
- -
-
-
- The color of dimension lines, arrows and texts
-
-
-
- 0
- 0
- 0
-
-
-
-
- -
-
-
- The typeof arrows to use for dimensions
-
-
-
-
- Dot
+
+
+
+ 0
+ -110
+ 420
+ 589
+
+
+
+
-
+
+
+ Text
-
- -
-
- Arrow
+
+
-
+
+
+ Font size
+
+
+
+ -
+
+
+ Line spacing
+
+
+
+ -
+
+
+ Font name
+
+
+
+ -
+
+
+ The font to use for texts and dimensions
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Units
-
- -
-
- Tick
+
+
-
+
+
+ Scale multiplier
+
+
+
+ -
+
+
+ Decimals
+
+
+
+ -
+
+
+ Unit override
+
+
+
+ -
+
+
+ Show unit
+
+
+
+ -
+
+
+ A multiplier value that affects distances shown by dimensions
+
+
+ 4
+
+
+ 1.000000000000000
+
+
+
+ -
+
+
+ Forces dimensions to be shown in a specific unit
+
+
+
+ -
+
+
+ The number of decimals to show on dimensions
+
+
+
+ -
+
+
+ Shows the units suffix on dimensions or not
+
+
+ Qt::RightToLeft
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Line and arrows
-
-
-
- -
-
-
- The size of dimension arrows
-
-
-
-
-
-
- -
-
-
- How far must the main dimension line extend pass the measured points
-
-
-
-
-
-
- -
-
-
- The length of extension lines
-
-
-
-
-
-
- -
-
-
- How far must the extension lines extend above the main dimension line
-
-
-
-
-
-
-
+
+ -
+
+
+ Line width
+
+
+
+ -
+
+
+ Extension overshoot
+
+
+
+ -
+
+
+ Arrow size
+
+
+
+ -
+
+
+ Show lines
+
+
+
+ -
+
+
+ Dimension overshoot
+
+
+
+ -
+
+
+ Extension lines
+
+
+
+ -
+
+
+ Arrow type
+
+
+
+ -
+
+
+ Line / text color
+
+
+
+ -
+
+
+ Shows the dimension line or not
+
+
+ Qt::RightToLeft
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ The width of the dimension lines
+
+
+ px
+
+
+ 1
+
+
+
+ -
+
+
+ The color of dimension lines, arrows and texts
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+ -
+
+
+ The typeof arrows to use for dimensions
+
+
-
+
+ Dot
+
+
+ -
+
+ Arrow
+
+
+ -
+
+ Tick
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
-
@@ -399,9 +406,9 @@
- Gui::QuantitySpinBox
- QWidget
-
+ Gui::InputField
+ QLineEdit
+
Gui::ColorButton
diff --git a/src/Mod/Draft/draftguitools/gui_annotationstyleeditor.py b/src/Mod/Draft/draftguitools/gui_annotationstyleeditor.py
index 08c1dd698b..5198549a18 100644
--- a/src/Mod/Draft/draftguitools/gui_annotationstyleeditor.py
+++ b/src/Mod/Draft/draftguitools/gui_annotationstyleeditor.py
@@ -29,22 +29,26 @@ Provides Draft_AnnotationStyleEditor command
import FreeCAD,FreeCADGui
import json
-EMPTYSTYLE = {
- "FontName":"Sans",
- "FontSize":0,
- "LineSpacing":0,
- "ScaleMultiplier":1,
- "ShowUnit":False,
- "UnitOverride":"",
- "Decimals":0,
- "ShowLines":True,
- "LineWidth":1,
- "LineColor":255,
- "ArrowType":0,
- "ArrowSize":0,
- "DimensionOvershoot":0,
- "ExtensionLines":0,
- "ExtensionOvershoot":0,
+def QT_TRANSLATE_NOOP(ctx,txt): return txt
+
+param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
+
+DEFAULT = {
+ "FontName":("font",param.GetString("textfont","Sans")),
+ "FontSize":("str",str(param.GetFloat("textheight",100))),
+ "LineSpacing":("str","1 cm"),
+ "ScaleMultiplier":("float",1),
+ "ShowUnit":("bool",False),
+ "UnitOverride":("str",""),
+ "Decimals":("int",2),
+ "ShowLines":("bool",True),
+ "LineWidth":("int",param.GetInt("linewidth",1)),
+ "LineColor":("color",param.GetInt("color",255)),
+ "ArrowType":("index",param.GetInt("dimsymbol",0)),
+ "ArrowSize":("str",str(param.GetFloat("arrowsize",20))),
+ "DimensionOvershoot":("str",str(param.GetFloat("dimovershoot",20))),
+ "ExtensionLines":("str",str(param.GetFloat("extlines",300))),
+ "ExtensionOvershoot":("str",str(param.GetFloat("extovershoot",20))),
}
@@ -53,10 +57,11 @@ class Draft_AnnotationStyleEditor:
def __init__(self):
self.styles = {}
+ self.renamed = {}
def GetResources(self):
- return {'Pixmap' : ":icons/Draft_AnnotationStyleEditor.svg",
+ return {'Pixmap' : ":icons/Draft_Annotation_Style.svg",
'MenuText': QT_TRANSLATE_NOOP("Draft_AnnotationStyleEditor", "Annotation styles..."),
'ToolTip' : QT_TRANSLATE_NOOP("Draft_AnnotationStyleEditor", "Manage or create annotation styles")}
@@ -68,16 +73,25 @@ class Draft_AnnotationStyleEditor:
from PySide import QtGui
+ # reset rename table
+ self.renamed = {}
+
# load dialog
self.form = FreeCADGui.PySideUic.loadUi(":/ui/dialog_AnnotationStyleEditor.ui")
+ # restore stored size
+ w = param.GetInt("AnnotationStyleEditorWidth",450)
+ h = param.GetInt("AnnotationStyleEditorHeight",450)
+ self.form.resize(w,h)
+
# center the dialog over FreeCAD window
mw = FreeCADGui.getMainWindow()
self.form.move(mw.frameGeometry().topLeft() + mw.rect().center() - self.form.rect().center())
# set icons
+ self.form.setWindowIcon(QtGui.QIcon(":/icons/Draft_Annotation_Style.svg"))
self.form.pushButtonDelete.setIcon(QtGui.QIcon(":/icons/edit_Cancel.svg"))
- self.form.pushButtonRename.setIcon(QtGui.QIcon(":/icons/edit_Cancel.svg"))
+ self.form.pushButtonRename.setIcon(QtGui.QIcon(":/icons/accessories-text-editor.svg"))
# fill the styles combo
self.styles = self.read_meta()
@@ -88,9 +102,9 @@ 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)
- for attr in EMPTYSTYLE.keys():
+ for attr in DEFAULT.keys():
control = getattr(self.form,attr)
- for signal in ["textChanged","valueChanged","stateChanged"]:
+ for signal in ["clicked","textChanged","valueChanged","stateChanged","currentIndexChanged"]:
if hasattr(control,signal):
getattr(control,signal).connect(self.update_style)
break
@@ -102,6 +116,10 @@ class Draft_AnnotationStyleEditor:
if result:
self.save_meta(self.styles)
+ # store dialog size
+ param.SetInt("AnnotationStyleEditorWidth",self.form.width())
+ param.SetInt("AnnotationStyleEditorHeight",self.form.height())
+
return
def read_meta(self):
@@ -123,60 +141,78 @@ class Draft_AnnotationStyleEditor:
changedstyles = []
meta = FreeCAD.ActiveDocument.Meta
for key,value in styles.items():
- strvalue = json.dumps(value)
- if meta["Draft_Style_"+key] and (meta["Draft_Style_"+key] != strvalue):
- changedstyles.append(style)
+ try:
+ strvalue = json.dumps(value)
+ except:
+ print("debug: unable to serialize this:",value)
+ if ("Draft_Style_"+key in meta) and (meta["Draft_Style_"+key] != strvalue):
+ changedstyles.append(key)
meta["Draft_Style_"+key] = strvalue
+ # remove deleted styles
+ todelete = []
+ for key,value in meta.items():
+ if key.startswith("Draft_Style_"):
+ if key[12:] not in styles:
+ todelete.append(key)
+ for key in todelete:
+ del meta[key]
+
FreeCAD.ActiveDocument.Meta = meta
# propagate changes to all annotations
for obj in self.get_annotations():
+ if obj.ViewObject.AnnotationStyle in self.renamed.keys():
+ # temporarily add the new style and switch to it
+ obj.ViewObject.AnnotationStyle = obj.ViewObject.AnnotationStyle+[self.renamed[obj.ViewObject.AnnotationStyle]]
+ obj.ViewObject.AnnotationStyle = self.renamed[obj.ViewObject.AnnotationStyle]
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()
+ 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]:
+ if reply[1]:
# OK or Enter pressed
name = reply[0]
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.styles[name] = {}
+ for key,val in DEFAULT.items():
+ self.styles[name][key] = val[1]
self.form.comboBoxStyles.addItem(name)
self.form.comboBoxStyles.setCurrentIndex(self.form.comboBoxStyles.count()-1)
- elif index > 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):
-
+
"""called when the Delete button is pressed"""
from PySide import QtGui
- index = self.form.comboBox.currentIndex()
+ index = self.form.comboBoxStyles.currentIndex()
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?",
@@ -187,48 +223,86 @@ class Draft_AnnotationStyleEditor:
del self.styles[style]
def on_rename(self):
-
+
"""called when the Rename button is pressed"""
from PySide import QtGui
- index = self.form.comboBox.currentIndex()
+ index = self.form.comboBoxStyles.currentIndex()
style = self.form.comboBoxStyles.itemText(index)
reply = QtGui.QInputDialog.getText(None, "Rename style","New name:",QtGui.QLineEdit.Normal,style)
- if reply[1]:
+ 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
+ if newname in self.styles:
+ reply = QtGui.QMessageBox.information(None,"Style exists","This style name already exists")
+ else:
+ self.form.comboBoxStyles.setItemText(index,newname)
+ value = self.styles[style]
+ del self.styles[style]
+ self.styles[newname] = value
+ self.renamed[style] = newname
def fill_editor(self,style):
-
+
"""fills the editor fields with the contents of a style"""
+ from PySide import QtGui
+
if style is None:
- style = EMPTYSTYLE
+ style = {}
+ for key,val in DEFAULT.items():
+ style[key] = val[1]
+ if not isinstance(style,dict):
+ if style in self.styles:
+ style = self.styles[style]
+ else:
+ print("debug: unable to fill dialog from style",style)
for key,value in style.items():
- setattr(self.form,key,value)
+ control = getattr(self.form,key)
+ if DEFAULT[key][0] == "str":
+ control.setText(value)
+ elif DEFAULT[key][0] == "font":
+ control.setCurrentFont(QtGui.QFont(value))
+ elif DEFAULT[key][0] == "color":
+ r = ((value>>24)&0xFF)/255.0
+ g = ((value>>16)&0xFF)/255.0
+ b = ((value>>8)&0xFF)/255.0
+ color = QtGui.QColor.fromRgbF(r,g,b)
+ control.setProperty("color",color)
+ elif DEFAULT[key][0] in ["int","float"]:
+ control.setValue(value)
+ elif DEFAULT[key][0] == "bool":
+ control.setChecked(value)
+ elif DEFAULT[key][0] == "index":
+ control.setCurrentIndex(value)
def update_style(self,arg=None):
-
+
"""updates the current style with the values from the editor"""
-
- index = self.form.comboBox.currentIndex()
+
+ index = self.form.comboBoxStyles.currentIndex()
if index > 1:
values = {}
style = self.form.comboBoxStyles.itemText(index)
- for key in EMPTYSTYLE.keys():
+ for key in DEFAULT.keys():
control = getattr(self.form,key)
- for attr in ["text","value","state"]:
- if hasattr(control,attr):
- values[key] = getattr(control,attr)
+ if DEFAULT[key][0] == "str":
+ values[key] = control.text()
+ elif DEFAULT[key][0] == "font":
+ values[key] = control.currentFont().family()
+ elif DEFAULT[key][0] == "color":
+ values[key] = control.property("color").rgb()<<8
+ elif DEFAULT[key][0] in ["int","float"]:
+ values[key] = control.value()
+ elif DEFAULT[key][0] == "bool":
+ values[key] = control.isChecked()
+ elif DEFAULT[key][0] == "index":
+ values[key] = control.currentIndex()
self.styles[style] = values
def get_annotations(self):
-
+
"""gets all the objects that support annotation styles"""
users = []
@@ -239,14 +313,14 @@ class Draft_AnnotationStyleEditor:
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())
diff --git a/src/Mod/Draft/draftobjects/draft_annotation.py b/src/Mod/Draft/draftobjects/draft_annotation.py
index 1ee3ab5432..4cf03ee57a 100644
--- a/src/Mod/Draft/draftobjects/draft_annotation.py
+++ b/src/Mod/Draft/draftobjects/draft_annotation.py
@@ -48,7 +48,10 @@ class DraftAnnotation(object):
def __setstate__(self,state):
if state:
- self.Type = state
+ if isinstance(state,dict) and ("Type" in state):
+ self.Type = state["Type"]
+ else:
+ self.Type = state
def execute(self,obj):
diff --git a/src/Mod/Draft/draftutils/init_tools.py b/src/Mod/Draft/draftutils/init_tools.py
index c7f484286d..1a93dc2474 100644
--- a/src/Mod/Draft/draftutils/init_tools.py
+++ b/src/Mod/Draft/draftutils/init_tools.py
@@ -49,7 +49,7 @@ def get_draft_drawing_commands():
def get_draft_annotation_commands():
"""Return the annotation commands list."""
return ["Draft_Text", "Draft_Dimension",
- "Draft_Label"]
+ "Draft_Label","Draft_AnnotationStyleEditor"]
def get_draft_array_commands():