diff --git a/src/Mod/Spreadsheet/InitGui.py b/src/Mod/Spreadsheet/InitGui.py index 7bd9f8109..13de247fe 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 1ef25a0d4..4ad2c81fd 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 000000000..94988cb08 --- /dev/null +++ b/src/Mod/Spreadsheet/Resources/icons/SpreadsheetPropertyController.svg @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/Spreadsheet/Spreadsheet.py b/src/Mod/Spreadsheet/Spreadsheet.py index 75b90b571..58c99181b 100644 --- a/src/Mod/Spreadsheet/Spreadsheet.py +++ b/src/Mod/Spreadsheet/Spreadsheet.py @@ -215,6 +215,7 @@ class Spreadsheet: 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 @@ class Spreadsheet: 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 @@ class Spreadsheet: 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 @@ class Spreadsheet: 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 @@ class Spreadsheet: 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 @@ class ViewProviderSpreadsheet(object): return True def unsetEdit(self,vobj,mode): + del self.editor return False def claimChildren(self): @@ -590,6 +639,39 @@ class ViewProviderSpreadsheetController: 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 @@ class SpreadsheetView(QtGui.QWidget): "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 @@ class SpreadsheetView(QtGui.QWidget): 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 @@ class _Command_Spreadsheet_Controller: 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 2ca5227c9..05df8fcca 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 \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a image/svg+xml\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a\x0a\x00\x00\x14w\x0a\x0a\x0a\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a image/svg+xml\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \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 \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a image/svg+xml\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a\x0a\x00\x00\x1f\x01\x0a\x0a\x0a\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a image/svg+xml\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a\x0a\x00\x00\x14w\x0a\x0a\x0a\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a image/svg+xml\x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \x0a \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)