diff --git a/src/Mod/Spreadsheet/InitGui.py b/src/Mod/Spreadsheet/InitGui.py
index 7bd9f81091c4..13de247fef21 100644
--- a/src/Mod/Spreadsheet/InitGui.py
+++ b/src/Mod/Spreadsheet/InitGui.py
@@ -54,7 +54,7 @@ class SpreadsheetWorkbench(Workbench):
def Initialize(self):
import Spreadsheet,Spreadsheet_rc
from DraftTools import translate
- commands = ["Spreadsheet_Create","Spreadsheet_Controller"]
+ commands = ["Spreadsheet_Create","Spreadsheet_Controller","Spreadsheet_PropertyController"]
self.appendToolbar(str(translate("Spreadsheet","Spreadsheet tools")),commands)
self.appendMenu(str(translate("Spreadsheet","&Spreadsheet")),commands)
FreeCADGui.addIconPath(":/icons")
diff --git a/src/Mod/Spreadsheet/Resources/Spreadsheet.qrc b/src/Mod/Spreadsheet/Resources/Spreadsheet.qrc
index 1ef25a0d43d8..4ad2c81fd8b6 100644
--- a/src/Mod/Spreadsheet/Resources/Spreadsheet.qrc
+++ b/src/Mod/Spreadsheet/Resources/Spreadsheet.qrc
@@ -2,5 +2,6 @@
icons/Spreadsheet.svg
icons/SpreadsheetController.svg
+ icons/SpreadsheetPropertyController.svg
diff --git a/src/Mod/Spreadsheet/Resources/icons/SpreadsheetPropertyController.svg b/src/Mod/Spreadsheet/Resources/icons/SpreadsheetPropertyController.svg
new file mode 100644
index 000000000000..94988cb08e6b
--- /dev/null
+++ b/src/Mod/Spreadsheet/Resources/icons/SpreadsheetPropertyController.svg
@@ -0,0 +1,198 @@
+
+
+
+
diff --git a/src/Mod/Spreadsheet/Spreadsheet.py b/src/Mod/Spreadsheet/Spreadsheet.py
index 75b90b571f81..58c99181bf17 100644
--- a/src/Mod/Spreadsheet/Spreadsheet.py
+++ b/src/Mod/Spreadsheet/Spreadsheet.py
@@ -215,6 +215,7 @@ def __init__(self,obj=None):
if obj:
obj.Proxy = self
obj.addProperty("App::PropertyLinkList","Controllers","Base","Cell controllers of this object")
+ self.Object = obj.Name
self._cells = {} # this stores cell contents
self._relations = {} # this stores relations - currently not used
self.cols = [] # this stores filled columns
@@ -245,6 +246,7 @@ def __setattr__(self, key, value):
if not r in self.rows:
self.rows.append(r)
self.rows.sort()
+ self.updateControlledProperties(key)
else:
self.__dict__.__setitem__(key,value)
@@ -266,6 +268,8 @@ def __getattr__(self, key):
def __getstate__(self):
self._cells["Type"] = self.Type
+ if hasattr(self,"Object"):
+ self._cells["Object"] = self.Object
return self._cells
def __setstate__(self,state):
@@ -275,6 +279,9 @@ def __setstate__(self,state):
if "Type" in self._cells.keys():
self.Type = self._cells["Type"]
del self._cells["Type"]
+ if "Object" in self._cells.keys():
+ self.Object = self._cells["Object"]
+ del self._cells["Object"]
# updating relation tables
self.rows = []
self.cols = []
@@ -423,16 +430,57 @@ def setControlledCells(self,obj):
if obj:
if hasattr(obj,"Controllers"):
for co in obj.Controllers:
- co.Proxy.setCells(co,obj)
+ import Draft
+ if Draft.getType(co) == "SpreadsheetController":
+ co.Proxy.setCells(co,obj)
def getControlledCells(self,obj):
"returns a list of cells managed by controllers"
cells = []
if hasattr(obj,"Controllers"):
- for c in obj.Controllers:
- cells.extend(c.Proxy.getCells(c,obj))
+ for co in obj.Controllers:
+ import Draft
+ if Draft.getType(co) == "SpreadsheetController":
+ cells.extend(co.Proxy.getCells(co,obj))
return cells
+ def getControllingCells(self,obj):
+ "returns a list of controlling cells managed by controllers"
+ cells = []
+ if hasattr(obj,"Controllers"):
+ for co in obj.Controllers:
+ import Draft
+ if Draft.getType(co) == "SpreadsheetPropertyController":
+ if co.Cell:
+ cells.append(co.Cell.lower())
+ return cells
+
+ def updateControlledProperties(self,key):
+ "updates the properties of controlled objects"
+ if hasattr(self,"Object"):
+ obj = FreeCAD.ActiveDocument.getObject(self.Object)
+ if obj:
+ import Draft
+ if Draft.getType(obj) == "Spreadsheet":
+ if hasattr(obj,"Controllers"):
+ for co in obj.Controllers:
+ if Draft.getType(co) == "SpreadsheetPropertyController":
+ if co.Cell.upper() == key.upper():
+ if co.TargetObject and co.TargetProperty:
+ b = co.TargetObject
+ props = co.TargetProperty.split(".")
+ for p in props:
+ if hasattr(b,p):
+ if p != props[-1]:
+ b = getattr(b,p)
+ else:
+ return
+ try:
+ setattr(b,p,self._cells[key])
+ if DEBUG: print "setting property ",co.TargetProperty, " of object ",co.TargetObject.Name, " to ",self._cells[key]
+ except:
+ if DEBUG: print "unable to set property ",co.TargetProperty, " of object ",co.TargetObject.Name, " to ",self._cells[key]
+
class ViewProviderSpreadsheet(object):
def __init__(self, vobj):
@@ -454,6 +502,7 @@ def setEdit(self,vobj,mode):
return True
def unsetEdit(self,vobj,mode):
+ del self.editor
return False
def claimChildren(self):
@@ -590,6 +639,39 @@ def getIcon(self):
return ":/icons/SpreadsheetController.svg"
+class SpreadsheetPropertyController:
+ "A spreadsheet property controller object"
+ def __init__(self,obj):
+ obj.Proxy = self
+ self.Type = "SpreadsheetPropertyController"
+ obj.addProperty("App::PropertyLink","TargetObject","Base","The object that must be controlled")
+ obj.addProperty("App::PropertyString","TargetProperty","Base","The property of the target object to control")
+ obj.addProperty("App::PropertyString","Cell","Base","The cell that contains the value to apply to the property")
+
+ def execute(self,obj):
+ pass
+
+ def __getstate__(self):
+ return self.Type
+
+ def __setstate__(self,state):
+ if state:
+ self.Type = state
+
+ def onChanged(self,obj,prop):
+ pass
+
+
+class ViewProviderSpreadsheetPropertyController:
+ "A view provider for the spreadsheet property controller"
+ def __init__(self,vobj):
+ vobj.Proxy = self
+
+ def getIcon(self):
+ import Spreadsheet_rc
+ return ":/icons/SpreadsheetPropertyController.svg"
+
+
class SpreadsheetView(QtGui.QWidget):
"A spreadsheet viewer for FreeCAD"
@@ -643,6 +725,7 @@ def update(self):
"updates the cells with the contents of the spreadsheet"
if self.spreadsheet:
controlled = self.spreadsheet.Proxy.getControlledCells(self.spreadsheet)
+ controlling = self.spreadsheet.Proxy.getControllingCells(self.spreadsheet)
for cell in self.spreadsheet.Proxy._cells.keys():
if cell != "Type":
c,r = self.spreadsheet.Proxy.splitKey(cell)
@@ -663,6 +746,11 @@ def update(self):
brush.setStyle(QtCore.Qt.Dense6Pattern)
if self.table.item(r,c):
self.table.item(r,c).setBackground(brush)
+ elif cell in controlling:
+ brush = QtGui.QBrush(QtGui.QColor(0, 0, 255))
+ brush.setStyle(QtCore.Qt.Dense6Pattern)
+ if self.table.item(r,c):
+ self.table.item(r,c).setBackground(brush)
def changeCell(self,r,c,value=None):
"changes the contens of a cell"
@@ -755,6 +843,46 @@ def Activated(self):
FreeCAD.ActiveDocument.recompute()
+class _Command_Spreadsheet_PropertyController:
+ "the Spreadsheet_Controller FreeCAD command"
+ def GetResources(self):
+ return {'Pixmap' : 'SpreadsheetPropertyController',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Spreadsheet_PropertyController","Add property controller"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Spreadsheet_PropertyController","Adds a property controller to a selected spreadsheet")}
+
+ def IsActive(self):
+ if FreeCADGui.Selection.getSelection():
+ return True
+ else:
+ return False
+
+ def Activated(self):
+ import Draft
+ from DraftTools import translate
+ sel = FreeCADGui.Selection.getSelection()
+ if (len(sel) == 1) and Draft.getType(sel[0]) == "Spreadsheet":
+ n = FreeCADGui.Selection.getSelection()[0].Name
+ FreeCAD.ActiveDocument.openTransaction(str(translate("Spreadsheet","Add property controller")))
+ FreeCADGui.doCommand("import Spreadsheet")
+ FreeCADGui.doCommand("Spreadsheet.makeSpreadsheetPropertyController(FreeCAD.ActiveDocument."+n+")")
+ FreeCAD.ActiveDocument.commitTransaction()
+ FreeCAD.ActiveDocument.recompute()
+ elif (len(sel) == 2):
+ if (Draft.getType(sel[0]) == "Spreadsheet") and (Draft.getType(sel[1]) == "SpreadsheetPropertyController"):
+ s = sel[0].Name
+ o = sel[1].Name
+ elif (Draft.getType(sel[1]) == "Spreadsheet") and (Draft.getType(sel[0]) == "SpreadsheetPropertyController"):
+ s = sel[1].Name
+ o = sel[0].Name
+ else:
+ return
+ FreeCAD.ActiveDocument.openTransaction(str(translate("Spreadsheet","Add property controller")))
+ FreeCADGui.doCommand("import Spreadsheet")
+ FreeCADGui.doCommand("Spreadsheet.makeSpreadsheetPropertyController(FreeCAD.ActiveDocument."+s+",FreeCAD.ActiveDocument."+o+")")
+ FreeCAD.ActiveDocument.commitTransaction()
+ FreeCAD.ActiveDocument.recompute()
+
+
def makeSpreadsheet():
"makeSpreadsheet(): adds a spreadsheet object to the active document"
obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython","Spreadsheet")
@@ -782,6 +910,25 @@ def makeSpreadsheetController(spreadsheet,cell=None,direction=None):
return obj
+def makeSpreadsheetPropertyController(spreadsheet,object=None,prop=None,cell=None):
+ """makeSpreadsheetPropertyController(spreadsheet,[object,prop,cell]): adds a
+ property controller, targetting the given object if any, to the given spreadsheet.
+ You can give a property (such as "Length" or "Proxy.Length") and a cell address
+ (such as "B6")."""
+ obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython","PropertyController")
+ SpreadsheetPropertyController(obj)
+ if FreeCAD.GuiUp:
+ ViewProviderSpreadsheetPropertyController(obj.ViewObject)
+ conts = spreadsheet.Controllers
+ conts.append(obj)
+ spreadsheet.Controllers = conts
+ if cell:
+ obj.Cell = cell
+ if prop:
+ obj.Property = prop
+ return obj
+
+
def addSpreadsheetView(view):
"addSpreadsheetView(view): adds the given spreadsheet view to the FreeCAD MDI area"
if FreeCAD.GuiUp:
@@ -873,3 +1020,4 @@ def export(exportList,filename):
FreeCADGui.addCommand('Spreadsheet_Create',_Command_Spreadsheet_Create())
FreeCADGui.addCommand('Spreadsheet_Controller',_Command_Spreadsheet_Controller())
+FreeCADGui.addCommand('Spreadsheet_PropertyController',_Command_Spreadsheet_PropertyController())
diff --git a/src/Mod/Spreadsheet/Spreadsheet_rc.py b/src/Mod/Spreadsheet/Spreadsheet_rc.py
index 2ca5227c9866..05df8fcca59a 100644
--- a/src/Mod/Spreadsheet/Spreadsheet_rc.py
+++ b/src/Mod/Spreadsheet/Spreadsheet_rc.py
@@ -2,16 +2,16 @@
# Resource object code
#
-# Created: Thu Jan 9 18:21:34 2014
+# Created: Sat Mar 29 14:56:48 2014
# by: The Resource Compiler for PySide (Qt v4.8.6)
#
# WARNING! All changes made in this file will be lost!
from PySide import QtCore
-qt_resource_data = "\x00\x00\x18S\x0a\x0a\x0a\x0a\x00\x00\x14w\x0a\x0a\x0a\x0a"
-qt_resource_name = "\x00\x05\x00o\xa6S\x00i\x00c\x00o\x00n\x00s\x00\x19\x02\x18\xed\xa7\x00S\x00p\x00r\x00e\x00a\x00d\x00s\x00h\x00e\x00e\x00t\x00C\x00o\x00n\x00t\x00r\x00o\x00l\x00l\x00e\x00r\x00.\x00s\x00v\x00g\x00\x0f\x0a\xa9@\xe7\x00S\x00p\x00r\x00e\x00a\x00d\x00s\x00h\x00e\x00e\x00t\x00.\x00s\x00v\x00g"
-qt_resource_struct = "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00H\x00\x00\x00\x00\x00\x01\x00\x00\x18W"
+qt_resource_data = "\x00\x00\x18S\x0a\x0a\x0a\x0a\x00\x00\x1f\x01\x0a\x0a\x0a\x0a\x00\x00\x14w\x0a\x0a\x0a\x0a"
+qt_resource_name = "\x00\x05\x00o\xa6S\x00i\x00c\x00o\x00n\x00s\x00\x19\x02\x18\xed\xa7\x00S\x00p\x00r\x00e\x00a\x00d\x00s\x00h\x00e\x00e\x00t\x00C\x00o\x00n\x00t\x00r\x00o\x00l\x00l\x00e\x00r\x00.\x00s\x00v\x00g\x00!\x08o\x93\xa7\x00S\x00p\x00r\x00e\x00a\x00d\x00s\x00h\x00e\x00e\x00t\x00P\x00r\x00o\x00p\x00e\x00r\x00t\x00y\x00C\x00o\x00n\x00t\x00r\x00o\x00l\x00l\x00e\x00r\x00.\x00s\x00v\x00g\x00\x0f\x0a\xa9@\xe7\x00S\x00p\x00r\x00e\x00a\x00d\x00s\x00h\x00e\x00e\x00t\x00.\x00s\x00v\x00g"
+qt_resource_struct = "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00H\x00\x00\x00\x00\x00\x01\x00\x00\x18W\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x007\x5c"
def qInitResources():
QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)