Merge branch 'master' into HEAD

git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5368 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d
This commit is contained in:
jriegel 2011-12-31 14:16:51 +00:00
commit 50ae86e595
9 changed files with 425 additions and 510 deletions

View File

@ -51,7 +51,7 @@ class _CommandWindow:
def GetResources(self):
return {'Pixmap' : 'Arch_Window',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Arch_Window","Window"),
'Accel': "W, I",
'Accel': "W, N",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Arch_Window","Creates a window object from scratch or from a selected object (wire, rectangle or sketch)")}
def Activated(self):

View File

@ -1931,6 +1931,10 @@ class _Wire:
"The base object is the wire is formed from 2 objects")
obj.addProperty("App::PropertyLink","Tool","Base",
"The tool object is the wire is formed from 2 objects")
obj.addProperty("App::PropertyVector","Start","Base",
"The start point of this line")
obj.addProperty("App::PropertyVector","End","Base",
"The end point of this line")
obj.Proxy = self
obj.Closed = False
self.Type = "Wire"
@ -1941,6 +1945,26 @@ class _Wire:
def onChanged(self, fp, prop):
if prop in ["Points","Closed","Base","Tool"]:
self.createGeometry(fp)
if prop == "Points":
if fp.Start != fp.Points[0]:
fp.Start = fp.Points[0]
if fp.End != fp.Points[-1]:
fp.End = fp.Points[-1]
if len(fp.Points) > 2:
fp.setEditorMode('Start',2)
fp.setEditorMode('End',2)
elif prop == "Start":
pts = fp.Points
if pts:
if pts[0] != fp.Start:
pts[0] = fp.Start
fp.Points = pts
elif prop == "End":
pts = fp.Points
if len(pts) > 1:
if pts[-1] != fp.End:
pts[-1] = fp.End
fp.Points = pts
def createGeometry(self,fp):
plm = fp.Placement

View File

@ -533,11 +533,10 @@ class DraftToolBar:
self.radiusValue.selectAll()
def offUi(self):
todo.delay(FreeCADGui.Control.closeDialog,None)
if self.taskmode:
self.isTaskOn = False
todo.delay(FreeCADGui.Control.closeDialog,None)
self.baseWidget = QtGui.QWidget()
# print "UI turned off"
else:
self.setTitle(translate("draft", "None"))
self.labelx.setText(translate("draft", "X"))
@ -637,6 +636,7 @@ class DraftToolBar:
if not self.taskmode:
self.labelx.setText(translate("draft", "Pick Object"))
self.labelx.show()
self.makeDumbTask()
def editUi(self):
self.taskUi(translate("draft", "Edit"))
@ -701,6 +701,15 @@ class DraftToolBar:
else:
self.layout.setDirection(QtGui.QBoxLayout.LeftToRight)
def makeDumbTask(self):
"create a dumb taskdialog to prevent deleting the temp object"
class TaskPanel:
def __init__(self):
pass
def getStandardButtons(self):
return 0
panel = TaskPanel()
FreeCADGui.Control.showDialog(panel)
#---------------------------------------------------------------------------
# Processing functions

View File

@ -38,7 +38,17 @@ class Snapper:
and arch module to manage object snapping. It is responsible for
finding snap points and displaying snap markers. Usually You
only need to invoke it's snap() function, all the rest is taken
care of."""
care of.
3 functions are useful for the scriptwriter: snap(), constrain()
or getPoint() which is an all-in-one combo.
The indivudual snapToXXX() functions return a snap definition in
the form [real_point,marker_type,visual_point], and are not
meant to be used directly, they are all called when necessary by
the general snap() function.
"""
def __init__(self):
self.lastObj = [None,None]
@ -57,6 +67,7 @@ class Snapper:
self.extLine = None
self.grid = None
self.constrainLine = None
self.trackLine = None
# the snapmarker has "dot","circle" and "square" available styles
self.mk = {'passive':'circle',
@ -98,6 +109,8 @@ class Snapper:
self.unconstrain()
return point
snaps = []
# type conversion if needed
if isinstance(screenpos,list):
screenpos = tuple(screenpos)
@ -141,7 +154,7 @@ class Snapper:
info = FreeCADGui.ActiveDocument.ActiveView.getObjectInfo((screenpos[0],screenpos[1]))
# checking if parallel to one of the edges of the last objects
point = self.snapToExtensions(point,lastpoint)
point = self.snapToExtensions(point,lastpoint,constrain)
if not info:
@ -152,7 +165,6 @@ class Snapper:
else:
# we have an object to snap to
snaps = []
obj = FreeCAD.ActiveDocument.getObject(info['Object'])
if not obj:
@ -213,6 +225,9 @@ class Snapper:
self.lastObj[0] = self.lastObj[1]
self.lastObj[1] = obj.Name
if not snaps:
return point
# calculating the nearest snap point
shortest = 1000000000000000000
origin = Vector(info['x'],info['y'],info['z'])
@ -241,8 +256,22 @@ class Snapper:
# return the final point
return cstr(winner[2])
def snapToExtensions(self,point,last):
def snapToExtensions(self,point,last,constrain):
"returns a point snapped to extension or parallel line to last object, if any"
tsnap = self.snapToExtOrtho(last,constrain)
if tsnap:
if (tsnap[0].sub(point)).Length < self.radius:
if self.tracker:
self.tracker.setCoords(tsnap[2])
self.tracker.setMarker(self.mk[tsnap[1]])
self.tracker.on()
if self.extLine:
self.extLine.p2(tsnap[2])
self.extLine.on()
self.setCursor(tsnap[1])
return tsnap[2]
for o in [self.lastObj[1],self.lastObj[0]]:
if o:
ob = FreeCAD.ActiveDocument.getObject(o)
@ -333,24 +362,30 @@ class Snapper:
def snapToOrtho(self,shape,last,constrain):
"returns a list of ortho snap locations"
snaps = []
if constrain != None:
if constrain:
if isinstance(shape,Part.Edge):
if last:
if isinstance(shape.Curve,Part.Line):
p1 = shape.Vertexes[0].Point
p2 = shape.Vertexes[-1].Point
if (constrain == 0):
if ((last.y > p1.y) and (last.y < p2.y) or (last.y > p2.y) and (last.y < p1.y)):
pc = (last.y-p1.y)/(p2.y-p1.y)
cp = (Vector(p1.x+pc*(p2.x-p1.x),p1.y+pc*(p2.y-p1.y),p1.z+pc*(p2.z-p1.z)))
snaps.append([cp,'ortho',cp])
elif (constrain == 1):
if ((last.x > p1.x) and (last.x < p2.x) or (last.x > p2.x) and (last.x < p1.x)):
pc = (last.x-p1.x)/(p2.x-p1.x)
cp = (Vector(p1.x+pc*(p2.x-p1.x),p1.y+pc*(p2.y-p1.y),p1.z+pc*(p2.z-p1.z)))
snaps.append([cp,'ortho',cp])
if self.constraintAxis:
tmpEdge = Part.Line(last,last.add(self.constraintAxis)).toShape()
# get the intersection points
pt = fcgeo.findIntersection(tmpEdge,shape,True,True)
if pt:
for p in pt:
snaps.append([p,'ortho',p])
return snaps
def snapToExtOrtho(self,last,constrain):
"returns an ortho X extension snap location"
if constrain and last and self.constraintAxis and self.extLine:
tmpEdge1 = Part.Line(last,last.add(self.constraintAxis)).toShape()
tmpEdge2 = Part.Line(self.extLine.p1(),self.extLine.p2()).toShape()
# get the intersection points
pt = fcgeo.findIntersection(tmpEdge1,tmpEdge2,True,True)
if pt:
return [pt[0],'ortho',pt[0]]
return None
def snapToAngles(self,shape):
"returns a list of angle snap locations"
snaps = []
@ -511,316 +546,54 @@ class Snapper:
self.affinity = None
if self.constrainLine:
self.constrainLine.off()
# deprecated ##################################################################
# last snapped objects, for quick intersection calculation
lastObj = [0,0]
def getPoint(self,last=None,callback=None):
"""getPoint([last],[callback]) : gets a 3D point from the screen. You can provide an existing point,
in that case additional snap options and a tracker are available. You can also passa function as
callback, which will get called with the resulting point as argument, when a point is clicked:
def cb(point):
print "got a 3D point: ",point
FreeCADGui.Snapper.getPoint(callback=cb)
"""
self.pt = None
self.ui = FreeCADGui.draftToolBar
self.view = FreeCADGui.ActiveDocument.ActiveView
# setting a track line if we got an existing point
if last:
if not self.trackLine:
self.trackLine = DraftTrackers.lineTracker()
self.trackLine.p1(last)
self.trackLine.on()
def move(event_cb):
event = event_cb.getEvent()
mousepos = event.getPosition()
ctrl = event.wasCtrlDown()
shift = event.wasShiftDown()
self.pt = FreeCADGui.Snapper.snap(mousepos,lastpoint=last,active=ctrl,constrain=shift)
self.ui.displayPoint(self.pt,last,plane=FreeCAD.DraftWorkingPlane,mask=FreeCADGui.Snapper.affinity)
if self.trackLine:
self.trackLine.p2(self.pt)
def snapPoint(target,point,cursor,ctrl=False):
'''
Snap function used by the Draft tools
Currently has two modes: passive and active. Pressing CTRL while
clicking puts you in active mode:
- In passive mode (an open circle appears), your point is
snapped to the nearest point on any underlying geometry.
- In active mode (ctrl pressed, a filled circle appears), your point
can currently be snapped to the following points:
- Nodes and midpoints of all Part shapes
- Nodes and midpoints of lines/wires
- Centers and quadrant points of circles
- Endpoints of arcs
- Intersection between line, wires segments, arcs and circles
- When constrained (SHIFT pressed), Intersections between
constraining axis and lines/wires
'''
def getConstrainedPoint(edge,last,constrain):
"check for constrained snappoint"
p1 = edge.Vertexes[0].Point
p2 = edge.Vertexes[-1].Point
ar = []
if (constrain == 0):
if ((last.y > p1.y) and (last.y < p2.y) or (last.y > p2.y) and (last.y < p1.y)):
pc = (last.y-p1.y)/(p2.y-p1.y)
cp = (Vector(p1.x+pc*(p2.x-p1.x),p1.y+pc*(p2.y-p1.y),p1.z+pc*(p2.z-p1.z)))
ar.append([cp,1,cp]) # constrainpoint
if (constrain == 1):
if ((last.x > p1.x) and (last.x < p2.x) or (last.x > p2.x) and (last.x < p1.x)):
pc = (last.x-p1.x)/(p2.x-p1.x)
cp = (Vector(p1.x+pc*(p2.x-p1.x),p1.y+pc*(p2.y-p1.y),p1.z+pc*(p2.z-p1.z)))
ar.append([cp,1,cp]) # constrainpoint
return ar
def getPassivePoint(info):
"returns a passive snap point"
cur = Vector(info['x'],info['y'],info['z'])
return [cur,2,cur]
def getScreenDist(dist,cursor):
"returns a 3D distance from a screen pixels distance"
p1 = FreeCADGui.ActiveDocument.ActiveView.getPoint(cursor)
p2 = FreeCADGui.ActiveDocument.ActiveView.getPoint((cursor[0]+dist,cursor[1]))
return (p2.sub(p1)).Length
def getGridSnap(target,point):
"returns a grid snap point if available"
if target.grid:
return target.grid.getClosestNode(point)
return None
def getPerpendicular(edge,last):
"returns a point on an edge, perpendicular to the given point"
dv = last.sub(edge.Vertexes[0].Point)
nv = fcvec.project(dv,fcgeo.vec(edge))
np = (edge.Vertexes[0].Point).add(nv)
return np
# checking if alwaySnap setting is on
extractrl = False
if Draft.getParam("alwaysSnap"):
extractrl = ctrl
ctrl = True
# setting Radius
radius = getScreenDist(Draft.getParam("snapRange"),cursor)
# checking if parallel to one of the edges of the last objects
target.snap.off()
target.extsnap.off()
if (len(target.node) > 0):
for o in [lastObj[1],lastObj[0]]:
if o:
ob = target.doc.getObject(o)
if ob:
if ob.isDerivedFrom("Part::Feature"):
edges = ob.Shape.Edges
if len(edges)<10:
for e in edges:
if isinstance(e.Curve,Part.Line):
last = target.node[len(target.node)-1]
de = Part.Line(last,last.add(fcgeo.vec(e))).toShape()
np = getPerpendicular(e,point)
if (np.sub(point)).Length < radius:
target.snap.coords.point.setValue((np.x,np.y,np.z))
target.snap.setMarker("circle")
target.snap.on()
target.extsnap.p1(e.Vertexes[0].Point)
target.extsnap.p2(np)
target.extsnap.on()
point = np
else:
last = target.node[len(target.node)-1]
de = Part.Line(last,last.add(fcgeo.vec(e))).toShape()
np = getPerpendicular(de,point)
if (np.sub(point)).Length < radius:
target.snap.coords.point.setValue((np.x,np.y,np.z))
target.snap.setMarker("circle")
target.snap.on()
point = np
# check if we snapped to something
snapped=target.view.getObjectInfo((cursor[0],cursor[1]))
if (snapped == None):
# nothing has been snapped, check fro grid snap
gpt = getGridSnap(target,point)
if gpt:
if radius != 0:
dv = point.sub(gpt)
if dv.Length <= radius:
target.snap.coords.point.setValue((gpt.x,gpt.y,gpt.z))
target.snap.setMarker("point")
target.snap.on()
return gpt
return point
else:
# we have something to snap
obj = target.doc.getObject(snapped['Object'])
if hasattr(obj.ViewObject,"Selectable"):
if not obj.ViewObject.Selectable:
return point
if not ctrl:
# are we in passive snap?
snapArray = [getPassivePoint(snapped)]
else:
snapArray = []
comp = snapped['Component']
if obj.isDerivedFrom("Part::Feature"):
if "Edge" in comp:
# get the stored objects to calculate intersections
intedges = []
if lastObj[0]:
lo = target.doc.getObject(lastObj[0])
if lo:
if lo.isDerivedFrom("Part::Feature"):
intedges = lo.Shape.Edges
nr = int(comp[4:])-1
edge = obj.Shape.Edges[nr]
for v in edge.Vertexes:
snapArray.append([v.Point,0,v.Point])
if isinstance(edge.Curve,Part.Line):
# the edge is a line
midpoint = fcgeo.findMidpoint(edge)
snapArray.append([midpoint,1,midpoint])
if (len(target.node) > 0):
last = target.node[len(target.node)-1]
snapArray.extend(getConstrainedPoint(edge,last,target.constrain))
np = getPerpendicular(edge,last)
snapArray.append([np,1,np])
elif isinstance (edge.Curve,Part.Circle):
# the edge is an arc
rad = edge.Curve.Radius
pos = edge.Curve.Center
for i in [0,30,45,60,90,120,135,150,180,210,225,240,270,300,315,330]:
ang = math.radians(i)
cur = Vector(math.sin(ang)*rad+pos.x,math.cos(ang)*rad+pos.y,pos.z)
snapArray.append([cur,1,cur])
for i in [15,37.5,52.5,75,105,127.5,142.5,165,195,217.5,232.5,255,285,307.5,322.5,345]:
ang = math.radians(i)
cur = Vector(math.sin(ang)*rad+pos.x,math.cos(ang)*rad+pos.y,pos.z)
snapArray.append([cur,0,pos])
for e in intedges:
# get the intersection points
pt = fcgeo.findIntersection(e,edge)
if pt:
for p in pt:
snapArray.append([p,3,p])
elif "Vertex" in comp:
# directly snapped to a vertex
p = Vector(snapped['x'],snapped['y'],snapped['z'])
snapArray.append([p,0,p])
elif comp == '':
# workaround for the new view provider
p = Vector(snapped['x'],snapped['y'],snapped['z'])
snapArray.append([p,2,p])
else:
snapArray = [getPassivePoint(snapped)]
elif Draft.getType(obj) == "Dimension":
for pt in [obj.Start,obj.End,obj.Dimline]:
snapArray.append([pt,0,pt])
elif Draft.getType(obj) == "Mesh":
for v in obj.Mesh.Points:
snapArray.append([v.Vector,0,v.Vector])
if not lastObj[0]:
lastObj[0] = obj.Name
lastObj[1] = obj.Name
if (lastObj[1] != obj.Name):
lastObj[0] = lastObj[1]
lastObj[1] = obj.Name
# calculating shortest distance
shortest = 1000000000000000000
spt = Vector(snapped['x'],snapped['y'],snapped['z'])
newpoint = [Vector(0,0,0),0,Vector(0,0,0)]
for pt in snapArray:
if pt[0] == None: print "snapPoint: debug 'i[0]' is 'None'"
di = pt[0].sub(spt)
if di.Length < shortest:
shortest = di.Length
newpoint = pt
if radius != 0:
dv = point.sub(newpoint[2])
if (not extractrl) and (dv.Length > radius):
newpoint = getPassivePoint(snapped)
target.snap.coords.point.setValue((newpoint[2].x,newpoint[2].y,newpoint[2].z))
if (newpoint[1] == 1):
target.snap.setMarker("square")
elif (newpoint[1] == 0):
target.snap.setMarker("point")
elif (newpoint[1] == 3):
target.snap.setMarker("square")
else:
target.snap.setMarker("circle")
target.snap.on()
return newpoint[2]
def constrainPoint (target,pt,mobile=False,sym=False):
'''
Constrain function used by the Draft tools
On commands that need to enter several points (currently only line/wire),
you can constrain the next point to be picked to the last drawn point by
pressing SHIFT. The vertical or horizontal constraining depends on the
position of your mouse in relation to last point at the moment you press
SHIFT. if mobile=True, mobile behaviour applies. If sym=True, x alway = y
'''
point = Vector(pt)
if len(target.node) > 0:
last = target.node[-1]
dvec = point.sub(last)
affinity = FreeCAD.DraftWorkingPlane.getClosestAxis(dvec)
if ((target.constrain == None) or mobile):
if affinity == "x":
dv = fcvec.project(dvec,FreeCAD.DraftWorkingPlane.u)
point = last.add(dv)
if sym:
l = dv.Length
if dv.getAngle(FreeCAD.DraftWorkingPlane.u) > 1:
l = -l
point = last.add(FreeCAD.DraftWorkingPlane.getGlobalCoords(Vector(l,l,l)))
target.constrain = 0 #x direction
target.ui.xValue.setEnabled(True)
target.ui.yValue.setEnabled(False)
target.ui.zValue.setEnabled(False)
target.ui.xValue.setFocus()
elif affinity == "y":
dv = fcvec.project(dvec,FreeCAD.DraftWorkingPlane.v)
point = last.add(dv)
if sym:
l = dv.Length
if dv.getAngle(FreeCAD.DraftWorkingPlane.v) > 1:
l = -l
point = last.add(FreeCAD.DraftWorkingPlane.getGlobalCoords(Vector(l,l,l)))
target.constrain = 1 #y direction
target.ui.xValue.setEnabled(False)
target.ui.yValue.setEnabled(True)
target.ui.zValue.setEnabled(False)
target.ui.yValue.setFocus()
elif affinity == "z":
dv = fcvec.project(dvec,FreeCAD.DraftWorkingPlane.axis)
point = last.add(dv)
if sym:
l = dv.Length
if dv.getAngle(FreeCAD.DraftWorkingPlane.axis) > 1:
l = -l
point = last.add(FreeCAD.DraftWorkingPlane.getGlobalCoords(Vector(l,l,l)))
target.constrain = 2 #z direction
target.ui.xValue.setEnabled(False)
target.ui.yValue.setEnabled(False)
target.ui.zValue.setEnabled(True)
target.ui.zValue.setFocus()
else: target.constrain = 3
elif (target.constrain == 0):
dv = fcvec.project(dvec,FreeCAD.DraftWorkingPlane.u)
point = last.add(dv)
if sym:
l = dv.Length
if dv.getAngle(FreeCAD.DraftWorkingPlane.u) > 1:
l = -l
point = last.add(FreeCAD.DraftWorkingPlane.getGlobalCoords(Vector(l,l,l)))
elif (target.constrain == 1):
dv = fcvec.project(dvec,FreeCAD.DraftWorkingPlane.v)
point = last.add(dv)
if sym:
l = dv.Length
if dv.getAngle(FreeCAD.DraftWorkingPlane.u) > 1:
l = -l
point = last.add(FreeCAD.DraftWorkingPlane.getGlobalCoords(Vector(l,l,l)))
elif (target.constrain == 2):
dv = fcvec.project(dvec,FreeCAD.DraftWorkingPlane.axis)
point = last.add(dv)
if sym:
l = dv.Length
if dv.getAngle(FreeCAD.DraftWorkingPlane.u) > 1:
l = -l
point = last.add(FreeCAD.DraftWorkingPlane.getGlobalCoords(Vector(l,l,l)))
return point
def click(event_cb):
event = event_cb.getEvent()
if event.getState() == coin.SoMouseButtonEvent.DOWN:
self.view.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),self.callbackClick)
self.view.removeEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),self.callbackMove)
FreeCADGui.Snapper.off()
self.ui.offUi()
if self.trackLine:
self.trackLine.off()
if callback:
callback(self.pt)
self.pt = None
# adding 2 callback functions
self.ui.pointUi()
self.callbackClick = self.view.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),click)
self.callbackMove = self.view.addEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),move)
if not hasattr(FreeCADGui,"Snapper"):
FreeCADGui.Snapper = Snapper()

View File

@ -389,24 +389,11 @@ class Line(Creator):
self.obj=self.doc.addObject("Part::Feature",self.featureName)
# self.obj.ViewObject.Selectable = False
Draft.formatObject(self.obj)
if not Draft.getParam("UiMode"): self.makeDumbTask()
self.call = self.view.addEventCallback("SoEvent",self.action)
msg(translate("draft", "Pick first point:\n"))
def makeDumbTask(self):
"create a dumb taskdialog to prevent deleting the temp object"
class TaskPanel:
def __init__(self):
pass
def getStandardButtons(self):
return 0
panel = TaskPanel()
FreeCADGui.Control.showDialog(panel)
def finish(self,closed=False,cont=False):
"terminates the operation and closes the poly if asked"
if not Draft.getParam("UiMode"):
FreeCADGui.Control.closeDialog()
if self.obj:
old = self.obj.Name
todo.delay(self.doc.removeObject,old)
@ -1627,6 +1614,12 @@ class Modifier:
def __init__(self):
self.commitList = []
def IsActive(self):
if Draft.getSelection():
return True
else:
return False
def Activated(self,name="None"):
if FreeCAD.activeDraftCommand:
@ -1655,12 +1648,6 @@ class Modifier:
self.snap = snapTracker()
self.extsnap = lineTracker(dotted=True)
self.planetrack = PlaneTracker()
def IsActive(self):
if FreeCADGui.ActiveDocument:
return True
else:
return False
def finish(self):
self.node = []

View File

@ -503,7 +503,10 @@ class wireTracker(Tracker):
def update(self,wire):
if wire:
self.line.numVertices.setValue(len(wire.Vertexes))
if self.closed:
self.line.numVertices.setValue(len(wire.Vertexes)+1)
else:
self.line.numVertices.setValue(len(wire.Vertexes))
for i in range(len(wire.Vertexes)):
p=wire.Vertexes[i].Point
self.coords.point.set1Value(i,[p.x,p.y,p.z])

View File

@ -56,6 +56,7 @@ FeaturePage::FeaturePage(void)
ADD_PROPERTY_TYPE(PageResult ,(0),group,App::Prop_Output,"Resulting SVG document of that page");
ADD_PROPERTY_TYPE(Template ,(""),group,App::Prop_None ,"Template for the page");
ADD_PROPERTY_TYPE(EditableTexts,(""),group,App::Prop_None,"Substitution values for the editable strings in the template");
}
FeaturePage::~FeaturePage()
@ -74,6 +75,11 @@ void FeaturePage::onChanged(const App::Property* prop)
return;
}
}
if (prop == &Template) {
if (!this->isRestoring()) {
EditableTexts.setValues(getEditableTextsFromTemplate());
}
}
App::DocumentObjectGroup::onChanged(prop);
}
@ -103,7 +109,8 @@ App::DocumentObjectExecReturn *FeaturePage::execute(void)
// make a temp file for FileIncluded Property
string tempName = PageResult.getExchangeTempFile();
ofstream ofile(tempName.c_str());
ostringstream ofile;
string tempendl = "--endOfLine--";
while (!file.eof())
{
@ -111,7 +118,7 @@ App::DocumentObjectExecReturn *FeaturePage::execute(void)
// check if the marker in the template is found
if(line.find("<!-- DrawingContent -->") == string::npos)
// if not - write through
ofile << line << endl;
ofile << line << tempendl;
else
{
// get through the children and collect all the views
@ -120,14 +127,42 @@ App::DocumentObjectExecReturn *FeaturePage::execute(void)
if ((*It)->getTypeId().isDerivedFrom(Drawing::FeatureView::getClassTypeId())) {
Drawing::FeatureView *View = dynamic_cast<Drawing::FeatureView *>(*It);
ofile << View->ViewResult.getValue();
ofile << endl << endl << endl;
ofile << tempendl << tempendl << tempendl;
}
}
}
}
file.close();
ofile.close();
// checking for freecad editable texts
string outfragment(ofile.str());
if (EditableTexts.getSize() > 0) {
boost::regex e1 ("<text.*?freecad:editable=\"(.*?)\".*?<tspan.*?>(.*?)</tspan>");
string::const_iterator begin, end;
begin = outfragment.begin();
end = outfragment.end();
boost::match_results<std::string::const_iterator> what;
int count = 0;
while (boost::regex_search(begin, end, what, e1)) {
if (count < EditableTexts.getSize()) {
// change values of editable texts
boost::regex e2 ("(<text.*?freecad:editable=\""+what[1].str()+"\".*?<tspan.*?)>(.*?)(</tspan>)");
outfragment = boost::regex_replace(outfragment, e2, "$1>"+EditableTexts.getValues()[count]+"$3");
}
count ++;
begin = what[0].second;
}
}
// restoring linebreaks and saving the file
boost::regex e3 ("--endOfLine--");
string fmt = "\\n";
outfragment = boost::regex_replace(outfragment, e3, fmt);
ofstream outfinal(tempName.c_str());
outfinal << outfragment;
outfinal.close();
PageResult.setValue(tempName.c_str());
@ -140,3 +175,39 @@ App::DocumentObjectExecReturn *FeaturePage::execute(void)
//}
return App::DocumentObject::StdReturn;
}
std::vector<std::string> FeaturePage::getEditableTextsFromTemplate(void) const {
//getting editable texts from "freecad:editable" attributes in SVG template
std::vector<string> eds;
if (Template.getValue() != "") {
Base::FileInfo tfi(Template.getValue());
if (!tfi.isReadable()) {
// if there is a old absolute template file set use a redirect
tfi.setFile(App::Application::getResourceDir() + "Mod/Drawing/Templates/" + tfi.fileName());
// try the redirect
if (!tfi.isReadable()) {
return eds;
}
}
string tline, tfrag;
ifstream tfile (tfi.filePath().c_str());
while (!tfile.eof()) {
getline (tfile,tline);
tfrag += tline;
tfrag += "--endOfLine--";
}
tfile.close();
boost::regex e ("<text.*?freecad:editable=\"(.*?)\".*?<tspan.*?>(.*?)</tspan>");
string::const_iterator tbegin, tend;
tbegin = tfrag.begin();
tend = tfrag.end();
boost::match_results<std::string::const_iterator> twhat;
while (boost::regex_search(tbegin, tend, twhat, e)) {
eds.push_back(twhat[2]);
tbegin = twhat[0].second;
}
}
return eds;
}

View File

@ -47,7 +47,7 @@ public:
App::PropertyFileIncluded PageResult;
App::PropertyFile Template;
App::PropertyStringList EditableTexts;
/** @name methods overide Feature */
//@{
@ -59,6 +59,7 @@ public:
virtual const char* getViewProviderName(void) const {
return "DrawingGui::ViewProviderDrawingPage";
}
virtual std::vector<std::string> getEditableTextsFromTemplate(void) const;
protected:
void onChanged(const App::Property* prop);
@ -68,5 +69,4 @@ protected:
} //namespace Drawing
#endif

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 126 KiB