svg2q-0.3.2: Translate.hs
module Translate where
import Data.Generics.Aliases (orElse)
import Helpers (split)
import Data.List (find)
import Text.XML.Light.Types as XML
import Language.C.Data.Ident
import Language.C.Data.Node
import Language.C.Data.Position
import Language.C.Syntax.AST
import Language.C.Pretty
import Types hiding (strokeWidth)
import Debug.Trace (trace)
import Color
import Data.Maybe (mapMaybe,fromJust,catMaybes)
import Data.Char (toLower)
import Prelude hiding (id)
import Point
import PathCommand
import TextElement
noNodeInfo :: NodeInfo
noNodeInfo = OnlyPos (Position "nopos" 0 0)
noIdent :: Ident
noIdent = Ident "" 0 noNodeInfo
createGraphicsFromContent :: Content -> Maybe GraphicsElement
createGraphicsFromContent (Elem e) = Just $ fromXML e
createGraphicsFromContent _ = Nothing
createGroup :: Element -> GraphicsElement
createGroup e = Group (mapMaybe createGraphicsFromContent (elContent e))
(getId (getString "id" (elAttribs e)))
createDescription :: Element -> GraphicsElement
createDescription _ = Description
createDefinition :: Element -> GraphicsElement
createDefinition _ = Definition
createPath :: [Attr] -> GraphicsElement
createPath a = Path (createPathCommands (getString "d" a))
(getId (getString "id" a))
(getColor (getString "fill" a))
(getFloat "stroke-width" a)
(getColor (getString "stroke" a))
kvpFromCSSAttr :: Maybe Attr -> [KeyValuePair]
kvpFromCSSAttr Nothing = []
kvpFromCSSAttr (Just a) =
let f = map (g . split ":")
g (x:y:[]) = KeyValuePair x y
g (x:y:_) = trace ("Warning: too many values for \
\Key "++x++", using "++y)
(KeyValuePair x y)
g (x:_) = error ("Error: No value for key "++x)
g [] = trace "Warning, something went wront with \
\kvpFromCSSAttr. Probably no Attributes."
KeyValuePair "" ""
sl = split ";" (attrVal a)
in
f sl
getStyleString :: String -> [Attr] -> Maybe String
getStyleString s a =
getStringFromKVP
s
(kvpFromCSSAttr (find (\x -> qName (attrKey x) == "style")
a))
getXMLString :: String -> [Attr] -> Maybe String
getXMLString s l = let sr = (find (\x -> qName (attrKey x) == s) l)
in
if sr == Nothing
then Nothing
else Just (attrVal (fromJust sr))
getStyleFloat :: String -> [Attr] -> Maybe Float
getStyleFloat s a = let sr = (getStyleString s a)
in
if sr == Nothing
then Nothing
else Just (read (fromJust sr))
getXMLFloat :: String -> [Attr] -> Maybe Float
getXMLFloat s a = let sr = (getXMLString s a)
in
if sr == Nothing
then Nothing
else Just (read (fromJust sr))
getString :: String -> [Attr] -> Maybe String
getString s a = let xml = getXMLString s a
style = getStyleString s a
in
orElse style xml
getFloat :: String -> [Attr] -> Float
getFloat s a = let xml = getXMLFloat s a
style = getStyleFloat s a
r = orElse style xml
in
if r == Nothing
then if s `elem` ["rx", "ry"]
then 0
else error ("Error: expected value for key \""++s++"\"\
\, but none found.")
else fromJust r
getText :: [Content] -> String
getText (Text x:_) = cdData x
getText (_:xs) = getText xs
getText _ = ""
fromXML :: XML.Element -> GraphicsElement
fromXML e = let name = qName (elName e)
a = elAttribs e
in
case name of
"rect" -> Rect (Point (getFloat "x" a)
(getFloat "y" a))
(getFloat "width" a)
(getFloat "height" a)
(getFloat "rx" a)
(getFloat "ry" a)
(getColor (getString "fill" a))
(getFloat "stroke-width" a)
(getColor (getString "stroke" a))
(getId (getString "id" a))
"circle" -> Circle (Point (getFloat "cx" a)
(getFloat "cy" a))
(getFloat "r" a)
(getColor (getString "fill" a))
(getFloat "stroke-width" a)
(getColor (getString "stroke" a))
(getId (getString "id" a))
"ellipse" -> Ellipse (Point (getFloat "cx" a)
(getFloat "cy" a))
(getFloat "rx" a)
(getFloat "ry" a)
(getColor (getString "fill" a))
(getFloat "stroke-width" a)
(getColor (getString "stroke" a))
(getId (getString "id" a))
"line" -> Line (Point (getFloat "x1" a)
(getFloat "y1" a))
(Point (getFloat "x2" a)
(getFloat "y2" a))
(getFloat "stroke-width" a)
(getColor (getString "stroke" a))
(getId (getString "id" a))
"polyline" -> mkPolyline (getPoints (getString "points" a))
(getColor (getString "fill" a))
(getFloat "stroke-width" a)
(getColor (getString "stroke" a))
(getId (getString "id" a))
"polygon" -> let p = getPoints (getString "points" a) in
mkPolyline (p++[head p])
(getColor (getString "fill" a))
(getFloat "stroke-width" a)
(getColor (getString "stroke" a))
(getId (getString "id" a))
"g" -> createGroup e
"desc" -> createDescription e
"defs" -> createDefinition e
"path" -> createPath a
"text" -> TextElement (TextElem (getText (elContent e))
(getFloat "font-size" a)
(getString "font-family" a)
(Point (getFloat "x" a)
(getFloat "y" a))
(getColor (getString "stroke" a))
(getFloat "stroke-width" a)
(getColor (getString "fill" a)))
(getId (getString "id" a))
-- die on unknown tags, but promt them
_ -> error $ "unknown tag: "++ name
-- pretty prints a list of CBlockItems
printCode :: [CBlockItem] -> IO()
printCode l= let mpaa "" p = (show.pretty) p
mpaa s p = s ++ "\n" ++ (show.pretty) p
string = foldl mpaa "" l
in putStrLn string
-- creates code for color of name s representing Color c.
colorSetup :: String -> Maybe Color -> [CBlockItem]
colorSetup _ Nothing = []
colorSetup s (Just c) = let
inits = map CBlockDecl
[cDecl "CGColorSpaceRef" (s++"Colorspace"),
cDecl "CGColorRef" (s++"Color"),
cDecl "CGFloat" (s++"ColorComponents[4]")]
assigns =
[assign (var (s++"Colorspace")) (call "CGColorSpaceCreateDeviceRGB" []),
assign (var (s++"ColorComponents[0]"))
(var (show (red c))),
assign (var (s++"ColorComponents[1]"))
(var (show (green c))),
assign (var (s++"ColorComponents[2]"))
(var (show (blue c))),
assign (var (s++"ColorComponents[3]"))
(var "1"),
assign (var (s++"Color"))
(call "CGColorCreate" [s++"Colorspace", s++"ColorComponents"])]
in
inits++assigns
transparentSetup :: String -> [CBlockItem]
transparentSetup s= let
inits = map CBlockDecl
[cDecl "CGColorSpaceRef" (s++"Colorspace"),
cDecl "CGColorRef" (s++"Color"),
cDecl "CGFloat" (s++"ColorComponents[4]")]
assigns =
[assign (var (s++"Colorspace")) (call "CGColorSpaceCreateDeviceRGB" []),
assign (var (s++"ColorComponents[0]"))
(var "0"),
assign (var (s++"ColorComponents[1]"))
(var "0"),
assign (var (s++"ColorComponents[2]"))
(var "0"),
assign (var (s++"ColorComponents[3]"))
(var "0"),
assign (var (s++"Color"))
(call "CGColorCreate" [s++"Colorspace", s++"ColorComponents"])]
in
inits++assigns
release :: [String] -> [CBlockItem]
release =
foldr
(\ s ->
(++)
[CBlockStmt
(createStat (call "CGColorSpaceRelease" [s ++ "Colorspace"])),
CBlockStmt (createStat (call "CGColorRelease" [s ++ "Color"]))])
[]
draw :: [CBlockItem]
draw = [CBlockStmt (createStat (call "CGContextDrawPath" ["context", "kCGPathFillStroke"]))]
drawEmpty :: [CBlockItem]
drawEmpty = [CBlockStmt (createStat (call "CGContextStrokePath"
["context"]))]
drawRoundedRect :: [String] -> [CBlockItem]
drawRoundedRect s
| length s == 9 = [CBlockStmt (createStat (call "drawRoundedRect" s))]
| length s == 10 = [CBlockStmt (createStat (call "drawRoundedRectFill" s))]
createStat :: CExpr -> CStat
createStat e = CExpr (Just e) noNodeInfo
createBlStmt :: CExpr -> CBlockItem
createBlStmt e = CBlockStmt (createStat e)
setStrokeColor :: String -> CExpr
setStrokeColor s = call "CGContextSetStrokeColorWithColor"
["context", s++"Color"]
setFillColor :: String -> CExpr
setFillColor s = call "CGContextSetFillColorWithColor"
["context", s++"Color"]
fillPath :: CExpr
fillPath = call "CGContextFillPath" ["context"]
strokePath :: CExpr
strokePath = call "CGContextStrokePath" ["context"]
fillRect :: CExpr
fillRect = call "CGContextFillRect" ["context", "rect"]
fillEllipse :: CExpr
fillEllipse = call "CGContextFillEllipseInRect" ["context", "rect"]
setFont :: Maybe String -> Float -> CExpr
setFont _ f = call "CGContextSelectFont"
["context"
,show "Helvetica"
,show f
,"kCGEncodingMacRoman"]
setFont' :: Maybe String -> String -> CExpr
setFont' _ s = call "CGContextSelectFont"
["context"
,show "Helvetica"
,s
, "kCGEncodingMacRoman"]
textAtPoint :: Point -> String -> CExpr
textAtPoint (Point x y) s =
call "CGContextShowTextAtPoint"
["context"
,show x
,show y
,show s
, show (length s)]
varTextAtPoint :: Point -> String -> CExpr
varTextAtPoint (Point x y) s =
let len = '[':s++" length]"
cstr = '[':s++" UTF8String]"
in
call "CGContextShowTextAtPoint"
["context"
, show x
, show y
, cstr
, len]
setLineWidth :: Float -> CExpr
setLineWidth f = call "CGContextSetLineWidth"
["context", show f]
setLineWidth' :: String -> CExpr
setLineWidth' s = call "CGContextSetLineWidth"
["context", s]
cMove :: Point -> CExpr
cMove (Point x y) = call "CGContextMoveToPoint"
["context", show x, show y]
cLine :: Point -> CExpr
cLine (Point x y) = call "CGContextAddLineToPoint"
["context",show x, show y]
rrectcall :: Float -> Float -> Float -> Float -> Float -> Float -> Float -> CBlockItem
rrectcall x y rx ry w h sw =
CBlockStmt (CExpr (Just (var ("[QRect drawWithContext:context andX:"
++show x++" andY:"
++show y++" andRadiusX:"
++show rx++" andRadiusY:"
++show ry++" andWidth:"
++show w++" andHeight:"
++show h++" andStrokeWidth:"
++show sw++" andStrokeColor: strokeColor]")))
noNodeInfo)
frrectcall :: Float -> Float -> Float -> Float -> Float -> Float -> Float -> CBlockItem
frrectcall x y rx ry w h sw =
CBlockStmt (CExpr (Just (var ("[QRect drawWithContext:context andX:"
++show x++" andY:"
++show y++" andRadiusX:"
++show rx++" andRadiusY:"
++show ry++" andWidth:"
++show w++" andHeight:"
++show h++" andStrokeWidth:"
++show sw++" andStrokeColor: strokeColor"
++" andFillColor: fillColor]")))
noNodeInfo)
codeString :: GraphicsElement -> Maybe String
codeString (Group xs _) = Nothing -- future works.
codeString Description = Nothing
codeString Definition = Nothing
codeString x = if id x == Nothing
then Just $ prettyCode (catMaybes [createCode x])
else genVarCode x
createCode :: GraphicsElement -> Maybe CBlockItem
createCode (Rect (Point x y)
width
height
rx
ry
fillColor
strokeWidth
strokeColor
Nothing) =
let color = colorSetup "stroke" strokeColor
++ colorSetup "fill" fillColor
in
if fillColor == Nothing
then Just $ createComp (color
++ [rrectcall x y rx ry width height strokeWidth])
else Just $ createComp (color
++ [frrectcall x y rx ry width height strokeWidth])
createCode (Circle (Point cx cy)
r
fillColor
strokeWidth
strokeColor
Nothing) =
let
x = cx - r
y = cy - r
color = colorSetup "stroke" strokeColor ++colorSetup "fill" fillColor
crel = release ["stroke", "fill"]
cbl = [CBlockDecl (cDecl "CGRect" "rect"),
assign (var "rect")
(call "CGRectMake"
(map show [x, y, r*2, r*2]))]
str = map createBlStmt
[setFillColor "fill",
setStrokeColor "stroke",
call "CGContextAddEllipseInRect"
["context", "rect"],
setLineWidth strokeWidth]
in
if fillColor == Nothing
then Just $ createComp (color
++ cbl ++ tail str
++ drawEmpty
++ release ["stroke"])
else Just $createComp (color
++ cbl ++ str
++ draw
++ crel)
createCode (Ellipse (Point cx cy)
rx
ry
fillColor
strokeWidth
strokeColor
Nothing) =
let
x = cx - rx
y = cy - ry
color = colorSetup "stroke" strokeColor ++ colorSetup "fill" fillColor
crel = release ["stroke", "fill"]
cbl = [CBlockDecl (cDecl "CGRect" "rect"),
assign (var "rect")
(call "CGRectMake"
(map show [x, y, rx*2, ry*2]))]
str = map createBlStmt
[setFillColor "fill",
setStrokeColor "stroke",
call "CGContextAddEllipseInRect" ["context", "rect"],
setLineWidth strokeWidth]
in
if fillColor == Nothing
then Just $ createComp (color
++ cbl ++ tail str
++ drawEmpty
++ release ["stroke"])
else Just $ createComp (color
++ cbl ++ str
++ draw
++ crel)
createCode (Line p1
p2
width
strokeColor
Nothing) =
let color = (colorSetup "stroke" strokeColor)
crel = release ["stroke"]
stroke = map createBlStmt
[setStrokeColor "stroke",
cMove p1,
cLine p2,
setLineWidth width]
in
Just $ createComp (color++stroke++draw++crel)
createCode (Path pc
Nothing
fillColor
strokeWidth
strokeColor) =
let color = colorSetup "stroke" strokeColor++colorSetup "fill" fillColor
crel = release ["stroke", "fill"]
stroke = map createBlStmt
([setFillColor "fill",
setLineWidth strokeWidth,
setStrokeColor "stroke"]++
pathCommands pc)
in
if fillColor == Nothing
then Just $ createComp (color
++ tail stroke
++ drawEmpty
++ release ["stroke"])
else Just $ createComp (color
++ stroke
++ draw
++ crel)
createCode (TextElement (TextElem text
fontSize
_
start
strokeColor
strokeWidth
fillColor)
Nothing) =
let color = colorSetup "stroke" strokeColor++colorSetup "fill" fillColor
a = map createBlStmt [setFillColor "fill"
,setLineWidth strokeWidth
,setStrokeColor "stroke"
,call "CGContextSetTextMatrix"
["context"
,"CGAffineTransformMakeScale(1,-1)"]
,call "CGContextSetTextDrawingMode"
["context"
,"kCGTextFillStroke"]
,setFont (Just "Helvetica") fontSize
,textAtPoint start text]
in
Just $ createComp (color
++ a)
createCode (Group xs id) = Just (createComp (mapMaybe createCode xs))
createCode Description = Nothing
createCode e = trace ("Note: createCode: Not yet implemented: "++show e) Nothing
cid :: Id -> String
cid x = let x' = concatMap idTable x
in toLower (head x') : tail x'
idTable :: Char -> String
idTable '@' = "At"
idTable ':' = "Colon"
idTable '-' = "Dash"
idTable '.' = "Dot"
idTable ',' = "Comma"
idTable c = [c]
genVarCode :: GraphicsElement -> Maybe String
genVarCode (Group xs _) = Nothing -- future works.
genVarCode Description = Nothing
genVarCode Definition = Nothing
genVarCode (Path pc
(Just id)
_
_
_) =
let id' = cid id
stroke = map createBlStmt
([setFillColor (id'++"Element.fill"),
setLineWidth' (id'++"Element.strokeWidth"),
setStrokeColor (id'++"Element.stroke")]++
pathCommands pc)
in Just (prettyCode [createComp (stroke
++ draw)])
genVarCode x =
if id x /= Nothing
then
let id' = cid (fromJust (id x))
in
Just $ "\t["++id'++"Element drawWithContext:context];\n"
else
Nothing
createComp :: [CBlockItem] -> CBlockItem
createComp bil = CBlockStmt $ CCompound [] bil noNodeInfo
var :: String -> CExpr
var s = CVar (Ident s 0 noNodeInfo) noNodeInfo
call :: String -> [String] -> CExpr
call s0 s1 = CCall (var s0) (map var s1) noNodeInfo
assign :: CExpr -> CExpr -> CBlockItem
assign e1 e2 = CBlockStmt (CExpr (Just (CAssign CAssignOp e1 e2 noNodeInfo)) noNodeInfo)
-- produces delaration of type s1, name s2
cDecl :: String -> String -> CDecl
cDecl s1 s2 = CDecl [typeDef s1] [(Just (nameDeclr s2),Nothing, Nothing)] noNodeInfo
-- produces declarator of input string
nameDeclr :: String -> CDeclr
nameDeclr s = CDeclr (Just (Ident s 0 noNodeInfo)) [] Nothing [] noNodeInfo
-- produces type of input string
typeDef :: String -> CDeclSpec
typeDef s = CTypeSpec (CTypeDef (Ident s 0 noNodeInfo) noNodeInfo)
pathCommands :: [PathCommand] -> [CExpr]
pathCommands [] = []
pathCommands pc = map helper pc
where
helper (PathMoveTo x) = cMove x
helper (PathLineTo x) = cLine x
helper (PathCurveTo (Point cp1x cp1y)
(Point cp2x cp2y)
(Point p1x p1y)) =
call "CGContextAddCurveToPoint"
("context":map show [cp1x, cp1y, cp2x, cp2y, p1x, p1y])
helper (PathQuadraticCurveTo (Point cx cy)
(Point x y)) =
call "CGContextAddQuadCurveToPoint"
("context":map show [cx, cy,x,y])
helper PathClosePath = call "CGContextClosePath" ["context"]
helper x = error ("pathCommands: not yet implemented: "++show x)
prettyCode :: [CBlockItem] -> String
prettyCode cbi = let
f "" p = (show.pretty) p
f s p = s ++ "\n" ++ (show.pretty) p
in
foldl f "" cbi ++ "\n"
convertId :: Maybe Id -> String
convertId (Just id) = toLower (head id) : tail id
convertId Nothing = []
mkInitVals :: GraphicsElement -> Maybe CBlockItem
mkInitVals (Rect (Point x y)
width
height
rx
ry
fill
strokeWidth
stroke
id)
| id == Nothing = Nothing
| fill == Nothing =
let color = colorSetup "stroke" stroke
++ transparentSetup "fill"
f s1 s2 = assign (var (cid (fromJust id)++"Element."++s1)) (var s2)
in
Just $ createComp (color ++ [ f "x" (show x)
, f "y" (show y)
, f "width" (show width)
, f "height" (show height)
, f "radiusX" (show rx)
, f "radiusY" (show ry)
, f "strokeWidth" (show strokeWidth)
, f "fillColor" "fillColor"
, f "strokeColor" "strokeColor"])
| otherwise =
let color = colorSetup "stroke" stroke ++ colorSetup "fill" fill
f s1 s2 = assign (var (cid (fromJust id)++"Element."++s1)) (var s2)
in
Just $ createComp (color ++ [ f "x" (show x)
, f "y" (show y)
, f "width" (show width)
, f "height" (show height)
, f "radiusX" (show rx)
, f "radiusY" (show ry)
, f "strokeWidth" (show strokeWidth)
, f "strokeColor" "strokeColor"
, f "fillColor" "fillColor"])
mkInitVals (Ellipse (Point x y)
rx
ry
fill
strokeWidth
stroke
id)
| id == Nothing = Nothing
| otherwise =
let color = colorSetup "stroke" stroke
++ colorSetup "fill" fill
++ transparentSetup "trans"
f s1 s2 = assign (var (cid (fromJust id)++"Element."++s1)) (var s2)
l = color ++ [f "x" (show x)
, f "y" (show y)
, f "radiusX" (show rx)
, f "radiusY" (show ry)
, f "strokeWidth" (show strokeWidth)
, f "strokeColor" "strokeColor"]
in
if fill == Nothing
then Just $ createComp (l++[f "fillColor" "transColor"])
else Just $ createComp (l++[f "fillColor" "fillColor"])
mkInitVals (Path _
id
fill
strokeWidth
stroke)
| id == Nothing = Nothing
| otherwise =
let color = colorSetup "stroke" stroke
++ colorSetup "fill" fill
++ transparentSetup "trans"
f s1 s2 = assign (var (cid (fromJust id)++"Element."++s1)) (var s2)
l = color ++ [f "strokeColor" "strokeColor"
,f "strokeWidth" (show strokeWidth)]
in
if fill == Nothing
then Just $ createComp (l++[f "fillColor" "transColor"])
else Just $ createComp (l++[f "fillColor" "fillColor"])
mkInitVals (Circle (Point x y)
radius
fill
strokeWidth
stroke
id)
| id == Nothing = Nothing
| otherwise =
let color = colorSetup "stroke" stroke
++ colorSetup "fill" fill
++ transparentSetup "trans"
f s1 s2 = assign (var (cid (fromJust id)++"Element."++s1)) (var s2)
l = color ++ [f "x" (show x)
,f "y" (show y)
,f "radiusX" (show radius)
,f "radiusY" (show radius)
,f "strokeWidth" (show strokeWidth)
,f "strokeColor" "strokeColor"]
in
if fill == Nothing
then Just $ createComp (l
++[f "fillColor"
"transColor"])
else Just $ createComp (l
++[f "fillColor" "fillColor"])
mkInitVals (Line (Point x1 y1)
(Point x2 y2)
strokeWidth
stroke
id)
| id == Nothing = Nothing
| otherwise =
let color = colorSetup "stroke" stroke
f s1 s2 = assign (var (cid (fromJust id)++"Element."++s1)) (var s2)
l = color ++ [f "x1" (show x1)
,f "x2" (show x2)
,f "y1" (show y1)
,f "y2" (show y2)
,f "strokeWidth" (show strokeWidth)
,f "strokeColor" "strokeColor"]
in Just $ createComp l
mkInitVals (TextElement elem id)
| id == Nothing = Nothing
| otherwise =
let color = colorSetup "stroke" (strokeColor elem)
++ colorSetup "fill" (fillColor elem)
f s1 s2 = assign (var (cid (fromJust id)++"Element."++s1)) (var s2)
l = color ++ [f "text" ('@':show (content elem))
,f "fillColor" "fillColor"
,f "strokeColor" "strokeColor"
,f "strokeWidth" (show (strokeWidth elem))
,f "fontSize" (show (fontSize elem))
, f "x" (show (xCood (start elem)))
,f "y" (show (yCood (start elem)))]
in
Just $ createComp l
mkInitVals e
| e == Description = Nothing
| e == Definition = Nothing
| id e == Nothing = Nothing
| otherwise = trace ("Note: mkInitVals: not yet: "++show e) Nothing
mkAllocs :: GraphicsElement -> Maybe String
mkAllocs (Rect _ _ _ _ _ _ _ _ (Just id)) =
Just $ "\t\t"++cid id++"Element = [[QRect alloc] init];\n"
mkAllocs (Circle _ _ _ _ _ (Just id)) =
Just $ "\t\t"++cid id++"Element = [[QEllipse alloc] init];\n"
mkAllocs (Ellipse _ _ _ _ _ _ (Just id)) =
Just $ "\t\t"++cid id++"Element = [[QEllipse alloc] init];\n"
mkAllocs (Line _ _ _ _ (Just id)) =
Just $ "\t\t"++cid id++"Element = [[QLine alloc] init];\n"
mkAllocs (Path _ (Just id) _ _ _) =
Just $ "\t\t"++cid id++"Element = [[QPath alloc] init];\n"
mkAllocs (TextElement _ (Just id)) =
Just $ "\t\t"++cid id++"Element = [[QText alloc] init];\n"
mkAllocs _ = Nothing
varNames :: GraphicsElement -> Maybe String
varNames Description = Nothing
varNames Definition = Nothing
varNames x
| id x /= Nothing =
Just $ cid (fromJust (id x))++"Element"
| otherwise = Nothing
mkMember :: GraphicsElement -> Maybe String
mkMember (Rect _ _ _ _ _ _ _ _ (Just id)) =
Just $ "\tQRect* "++cid id++"Element;\n"
mkMember (Circle _ _ _ _ _ (Just id)) =
Just $ "\tQEllipse* "++cid id++"Element;\n"
mkMember (Ellipse _ _ _ _ _ _ (Just id)) =
Just $ "\tQEllipse* "++cid id++"Element;\n"
mkMember (Line _ _ _ _ (Just id)) =
Just $ "\tQLine* "++cid id++"Element;\n"
mkMember (Path _ (Just id) _ _ _) =
Just $ "\tQPath* "++cid id++"Element;\n"
mkMember (TextElement _ (Just id)) =
Just $ "\tQText* "++cid id++"Element;\n"
mkMember _ = Nothing