Spreadsheet: Added CSV import/export

This commit is contained in:
Yorik van Havre 2013-08-10 19:26:03 -03:00
parent 4376491e38
commit 58dd79e79b
2 changed files with 111 additions and 23 deletions

View File

@ -26,6 +26,7 @@ ParGrp = App.ParamGet("System parameter:Modules").GetGroup("Spreadsheet")
# Set the needed information
ParGrp.SetString("HelpIndex","http://free-cad.sf.net")
# import types
#FreeCAD.addImportType("Spreadsheet data (*.csv)","importCSV")
# Supported file types
FreeCAD.addImportType("Spreadsheet (*.csv)","Spreadsheet")
FreeCAD.addExportType("Spreadsheet (*.csv)","Spreadsheet")

View File

@ -24,10 +24,12 @@ import re, math, FreeCAD, FreeCADGui
from PyQt4 import QtCore,QtGui
DEBUG = True # set to True to show debug messages
if open.__module__ == '__builtin__':
pyopen = open # because we'll redefine open below
class MathParser:
"A math expression parser"
# code borrowed from http://www.nerdparadise.com/tech/python/parsemath/
# code adapted from http://www.nerdparadise.com/tech/python/parsemath/
def __init__(self, string, vars={}):
self.string = string
self.index = 0
@ -199,11 +201,14 @@ class Spreadsheet:
FreeCAD object or as a standalone python object.
Cells of the spreadsheet can be got/set as arguments, as:
myspreadsheet = Spreadsheet()
myspreadsheet.a1 = 54
print(myspreadsheet.a1)
myspreadsheet.a2 = "My text"
myspreadsheet.b1 = "=a1*3"
print(myspreadsheet.b1)
The cell names are case-insensitive (a1 = A1)
"""
def __init__(self,obj=None):
@ -275,7 +280,7 @@ class Spreadsheet:
self.cols = []
self._relations = {}
for key in self._cells.keys():
r,c = self.splitKey(key)
c,r = self.splitKey(key)
if not r in self.rows:
self.rows.append(r)
self.rows.sort()
@ -305,7 +310,8 @@ class Spreadsheet:
def isFunction(self,key):
"isFunction(cell): returns True if the given cell or value is a function"
if key in self._cells:
if str(key).lower() in self._cells:
key = key.lower()
if str(self._cells[key])[0] == "=":
return True
elif str(key)[0] == "=":
@ -315,6 +321,7 @@ class Spreadsheet:
def isNumeric(self,key):
"isNumeric(cell): returns True if the given cell returns a number"
key = key.lower()
if self.isFunction(key):
res = self.evaluate(key)
else:
@ -366,6 +373,7 @@ class Spreadsheet:
def getFunction(self,key):
"getFunction(cell): returns the function contained in the given cell, instead of the value"
key = key.lower()
if key in self._cells:
return self._cells[key]
else:
@ -386,6 +394,7 @@ class Spreadsheet:
def evaluate(self,key):
"evaluate(key): evaluates the given formula"
key = key.lower()
elts = re.split(r'(\W+)',self._cells[key][1:])
result = ""
for e in elts:
@ -397,7 +406,7 @@ class Spreadsheet:
print "Error evaluating formula"
return
elif self.isNumeric(e):
result += str(self._cells[e])
result += str(self._cells[e.lower()])
else:
result += e
if DEBUG: print "Evaluating ",result
@ -589,23 +598,24 @@ class SpreadsheetView(QtGui.QWidget):
if self.spreadsheet:
controlled = self.spreadsheet.Proxy.getControlledCells(self.spreadsheet)
for cell in self.spreadsheet.Proxy._cells.keys():
c,r = self.spreadsheet.Proxy.splitKey(cell)
c = "abcdefghijklmnopqrstuvwxyz".index(c)
r = int(str(r))-1
content = getattr(self.spreadsheet.Proxy,cell)
if self.spreadsheet.Proxy.isFunction(cell):
self.doNotChange = True
if content == None:
content = ""
if DEBUG: print "Updating ",cell," to ",content
if self.table.item(r,c):
self.table.item(r,c).setText(str(content))
else:
self.table.setItem(r,c,QtGui.QTableWidgetItem(str(content)))
if cell in controlled:
brush = QtGui.QBrush(QtGui.QColor(255, 0, 0))
brush.setStyle(QtCore.Qt.Dense6Pattern)
self.table.item(r,c).setBackground(brush)
if cell != "Type":
c,r = self.spreadsheet.Proxy.splitKey(cell)
c = "abcdefghijklmnopqrstuvwxyz".index(c)
r = int(str(r))-1
content = getattr(self.spreadsheet.Proxy,cell)
if self.spreadsheet.Proxy.isFunction(cell):
self.doNotChange = True
if content == None:
content = ""
if DEBUG: print "Updating ",cell," to ",content
if self.table.item(r,c):
self.table.item(r,c).setText(str(content))
else:
self.table.setItem(r,c,QtGui.QTableWidgetItem(str(content)))
if cell in controlled:
brush = QtGui.QBrush(QtGui.QColor(255, 0, 0))
brush.setStyle(QtCore.Qt.Dense6Pattern)
self.table.item(r,c).setBackground(brush)
def changeCell(self,r,c,value=None):
"changes the contens of a cell"
@ -742,5 +752,82 @@ def addSpreadsheetView(view):
mdi.setActiveSubWindow(sw)
def open(filename):
"called when freecad opens a csv file"
import os
docname = os.path.splitext(os.path.basename(filename))[0]
doc = FreeCAD.newDocument(docname)
FreeCAD.ActiveDocument = doc
read(filename)
doc.recompute()
return doc
def insert(filename,docname):
"called when freecad wants to import a csv file"
try:
doc = FreeCAD.getDocument(docname)
except:
doc = FreeCAD.newDocument(docname)
FreeCAD.ActiveDocument = doc
read(filename)
doc.recompute()
return doc
def read(filename):
"creates a spreadsheet with the contents of a csv file"
sp = makeSpreadsheet()
import csv
with pyopen(filename, 'rb') as csvfile:
csvfile = csv.reader(csvfile)
rn = 1
for row in csvfile:
cn = 0
for c in row[:26]:
cl = "abcdefghijklmnopqrstuvwxyz"[cn]
#print "setting ",cl+str(rn)," ",c
try:
c = int(c)
except:
try:
c = float(c)
except:
c = str(c)
setattr(sp.Proxy,cl+str(rn),c)
cn += 1
rn += 1
print "successfully imported ",filename
def export(exportList,filename):
"called when freecad exports a csv file"
import csv, Draft
if not exportList:
print "Spreadsheet: Nothing to export"
return
obj = exportList[0]
if Draft.getType(obj) != "Spreadsheet":
print "Spreadhseet: The selected object is not a spreadsheet"
return
if not obj.Proxy._cells:
print "Spreadsheet: The selected spreadsheet contains no cell"
return
numcols = ("abcdefghijklmnopqrstuvwxyz".index(str(obj.Proxy.cols[-1])))+1
numrows = int(obj.Proxy.rows[-1])
with pyopen(filename, 'wb') as csvfile:
csvfile = csv.writer(csvfile)
for i in range(numrows):
r = []
for j in range(numcols):
key = "abcdefghijklmnopqrstuvwxyz"[j]+str(i+1)
if key in obj.Proxy._cells.keys():
r.append(str(obj.Proxy.getFunction(key)))
else:
r.append("")
csvfile.writerow(r)
print "successfully exported ",filename
FreeCADGui.addCommand('Spreadsheet_Create',_Command_Spreadsheet_Create())
FreeCADGui.addCommand('Spreadsheet_Controller',_Command_Spreadsheet_Controller())