dia r3942 - in trunk: . lib plug-ins/python



Author: hans
Date: Sun Apr 13 16:37:17 2008
New Revision: 3942
URL: http://svn.gnome.org/viewvc/dia?rev=3942&view=rev

Log:
	* lib/diatypes.h lib/widgets.h : moved #include "units.h" to widgets.h
	diatypes.h is supposed to contain _only_ type forward declares 

	* plug-ins/python/diagx.py : importer for XML generated by gccxml


Added:
   trunk/plug-ins/python/diagx.py   (contents, props changed)
Modified:
   trunk/ChangeLog
   trunk/lib/diatypes.h
   trunk/lib/widgets.h

Modified: trunk/lib/diatypes.h
==============================================================================
--- trunk/lib/diatypes.h	(original)
+++ trunk/lib/diatypes.h	Sun Apr 13 16:37:17 2008
@@ -21,7 +21,8 @@
 #ifndef TYPES_H
 #define TYPES_H
 
-#include "units.h"
+/* THIS HEADER MUST NOT INCLUDE ANY OTHER HEADER! */
+//#include "units.h"
 
 /* In diagramdata.h: */
 typedef struct _DiagramData DiagramData;
@@ -76,6 +77,10 @@
 typedef struct _DiaRenderer DiaRenderer;
 typedef struct _DiaRendererClass DiaRendererClass;
 typedef struct _DiaInteractiveRendererInterface DiaInteractiveRendererInterface;
+
+/* In diacellrendererproperty.h: */
+typedef struct _DiaCellRendererProperty DiaCellRendererProperty;
+
 /* In diasvgrenderer.h: */
 typedef struct _DiaSvgRenderer DiaSvgRenderer;
 typedef struct _DiaSvgRendererClass DiaSvgRendererClass;

Modified: trunk/lib/widgets.h
==============================================================================
--- trunk/lib/widgets.h	(original)
+++ trunk/lib/widgets.h	Sun Apr 13 16:37:17 2008
@@ -36,6 +36,7 @@
 #include "font.h"
 #include "color.h"
 #include "arrows.h"
+#include "units.h"
 
 /* DiaFontSelector: */
 #define DIAFONTSELECTOR(obj)          GTK_CHECK_CAST (obj, dia_font_selector_get_type (), DiaFontSelector)

Added: trunk/plug-ins/python/diagx.py
==============================================================================
--- (empty file)
+++ trunk/plug-ins/python/diagx.py	Sun Apr 13 16:37:17 2008
@@ -0,0 +1,362 @@
+#  PyDia C++ Import
+#  Copyright (c) 2006 Hans Breuer <hans breuer org>
+
+# Another attempt to import C++ into a diagram. This time it is not trying to parse C++ directly
+# but the XML generated by GCC_XML ( http://www.gccxml.org/ ). 
+
+#    This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import string, sys
+
+class Node :
+	def __init__ (self, name) :
+		self.name = name
+		self.context = None
+	def IsMethod (self) :
+		return 0
+	def IsUnion (self) :
+		return 0
+	def Name (self) :
+		return self.name
+
+class Type(Node) :
+	def __init__ (self, name) :
+		Node.__init__(self, name)
+
+class Union(Node) :
+	def __init__ (self, name) :
+		Node.__init__(self, name)
+		self.names = []
+	def IsUnion (self) :
+		return 1
+	def AddMember (self, name) :
+		self.names.append(name)
+	def Name (self) :
+		ms = []
+		for s in self.names :
+			ms.append (g_nodes[s].Name())
+		return string.join(ms, "; ")
+
+class Fassade(Node) :
+	def __init__ (self, type, pre, post) :
+		self.type = type
+		self.pre = pre
+		self.post = post
+	def Name (self) :
+		if self.pre != "" :
+			return self.pre + " " + g_nodes[self.type].Name() + self.post
+		else :
+			return g_nodes[self.type].Name() + self.post
+
+class Argument(Node) :
+	def __init__ (self, name, type) :
+		Node.__init__(self, name)
+		self.type = type
+		self.access = "public"
+		self.static = 0
+	def Type (self) :
+		if g_nodes.has_key (self.type) :
+			return g_nodes[self.type].Name()
+		return "?"
+	def Visibility (self) :
+		"This function is mapping from string to dia enum; should probably not be done here"
+		if "protected" == self.access : return 2 #UML_PROTECTED
+		elif "private" == self.access : return 1 #UML_PRIVATE
+		return 0 #UML_PUBLIC
+
+class Method(Node) :
+	def __init__ (self, name, type) :
+		Node.__init__(self, name)
+		self.returns = type
+		self.params = []
+		self.const = 0
+		self.static = 0
+		self.access = "public"
+		self.virtual = 0
+	def IsMethod (self) :
+		return 1
+	def AddArg (self, arg) :
+		self.params.append (arg)
+	def Type (self) :
+		if g_nodes.has_key (self.returns) :
+			return g_nodes[self.returns].Name()
+		return ""
+	def Visibility (self) :
+		"This function is mapping from string to dia enum; should probably not be done here"
+		if "protected" == self.access : return 2 #UML_PROTECTED
+		elif "private" == self.access : return 1 #UML_PRIVATE
+		return 0 #UML_PUBLIC
+	def InheritanceType (self) :
+		if self.virtual > 1 : return 0 #UML_ABSTRACT
+		if self.virtual > 0 : return 1 #UML_POLYMORPHIC
+		return 2
+	def Signature (self) :
+		args = []
+		ret = ""
+		for p in self.params :
+			try :
+				args.append (p.name + ":" + g_nodes[p.type].Name())
+			except AttributeError :
+				args.append (":" + p.Name())
+			except :
+				print "E:", p, p.name, p.type
+		if self.returns : 
+			ret = g_nodes[self.returns].Name() + " "
+		return ret + self.name + " (" + string.join(args, ", ") + ")"
+
+class Klass(Node) :
+	def __init__ (self, name) :
+		Node.__init__(self, name)
+		self.parents = []
+		self.members = []
+		self.abstract = 0
+	def AddParent (self, id) :
+		self.parents.append (id)
+	def AddMember (self, id) :
+		self.members.append (id)
+	def Name (self) :
+		if g_nodes.has_key (self.context) and g_nodes[self.context].Name() != "" :
+			return g_nodes[self.context].Name() + "::" + self.name
+		else :
+			return self.name
+	def Parents (self) :
+		# full qualified names
+		names = []
+		for p in self.parents :
+			if g_nodes.has_key(p) :
+				names.append (g_nodes[p].Name())
+		return names
+	def Dump (self) :
+		ps = ""
+		for id in self.parents :
+			if g_nodes.has_key (id) :
+				ps = ps + " " + g_nodes[id].Name()
+		print self.Name() + "(" + ps + " )"
+		for id in self.members :
+			print "\t", g_nodes[id], id
+			if g_nodes[id].IsMethod() :
+				print "\t" + g_nodes[id].Signature()
+			elif g_nodes[id].IsUnion() :
+				print "\t" + g_nodes[id].Name() 
+			else :
+				print "\t" + g_nodes[id].Name() + ":" + g_nodes[g_nodes[id].type].Name()			
+
+class Namespace(Node) :
+	def __init__ (self, name) :
+		Node.__init__(self, name)
+		self.name = name
+	def Name (self) :
+		id = self.context
+		if  g_nodes.has_key (id) and g_nodes[id].Name() != "" :
+			return g_nodes[id].Name() + "::" + self.name
+		else :
+			return self.name
+	
+g_nodes = {}
+g_classes = []
+
+def Parse (sFile, nodes) :
+
+	import xml.parsers.expat
+	global g_classes
+
+	ctx = [] 
+	def start_element(name, attrs) :
+		o = None
+		if name in ["Class", "Struct"] :
+			#print attrs["name"], attrs["id"]
+			o = Klass(attrs["name"])
+			if attrs.has_key("bases") :
+				bs = string.split (attrs["bases"], " ")
+				for s in bs :
+					o.AddParent (s)
+			if attrs.has_key("members") :
+				ms = string.split (attrs["members"], " ")
+				for s in ms :
+					if s != "" :
+						o.AddMember (s)
+			if attrs.has_key("abstract") :
+				o.abstract = string.atoi(attrs["abstract"])
+			g_classes.append (o)
+		elif "Union" == name :
+			o = Union(attrs["name"])
+			if attrs.has_key("members") :
+				ms = string.split (attrs["members"], " ")
+				for s in ms :
+					if s != "" :
+						o.AddMember (s)
+			# FIXME: this creates a dup
+		elif "Namespace" == name :
+			#print attrs["name"], attrs["id"], "::"
+			if attrs["name"] == "::" :
+				o = Namespace("")
+			else :
+				o = Namespace(attrs["name"])
+		elif name in ["Method", "OperatorMethod", "Constructor", "Destructor"] :
+			if "Constructor" == name : o = Method (attrs["name"], None)
+			elif "Destructor" == name : o = Method ("~" + attrs["name"], None)
+			else : o = Method (attrs["name"], attrs["returns"])
+			
+			if attrs.has_key("virtual") : o.virtual += string.atoi(attrs["virtual"])
+			if attrs.has_key("pure_virtual") : o.virtual += string.atoi(attrs["pure_virtual"])
+			if attrs.has_key("access") : o.access = attrs["access"]
+		elif name in ["Field", "Typedef"] :
+			o = Argument (attrs["name"], attrs["type"])
+			if attrs.has_key("access") : o.access = attrs["access"]
+			if attrs.has_key("static") : o.static = attrs["static"]
+		elif name in ["FundamentalType", "Enumeration"] :
+			o = Type (attrs["name"])
+		elif "ReferenceType" == name :
+			o = Fassade (attrs["type"], "", "&")
+		elif "PointerType" == name :
+			o = Fassade (attrs["type"], "", "*")
+		elif "ArrayType" == name :
+			o = Fassade (attrs["type"], "", "[]")
+		elif "CvQualifiedType" == name :
+			o = Fassade (attrs["type"], "const", "")
+		elif "Argument" == name :
+			if attrs.has_key("name") :
+				o = Argument (attrs["name"], attrs["type"])
+			else :
+				o = Fassade (attrs["type"], "", "")
+			if ctx[-1][1] :
+				ctx[-1][1].AddArg (o)
+			o = None # lookup not possible
+			
+		if o :
+			if attrs.has_key("context") :
+				#print attrs["context"]
+				o.context = attrs["context"]
+			nodes[attrs["id"]] = o
+		ctx.append((name, o)) #push
+		
+	def end_element(name) :
+		del ctx[-1] # pop
+	def char_data(data) :
+		pass
+
+	p = xml.parsers.expat.ParserCreate()
+	p.StartElementHandler = start_element
+	p.EndElementHandler = end_element
+	p.CharacterDataHandler = char_data
+
+	p.Parse(sFile)
+
+def Process (sName) :
+	global g_nodes
+	f = open (sName)
+	Parse(f.read(), g_nodes)
+
+def ImportCpp (sFile, diagramData) :
+	# process the c++ file with GCC_XML to get XML
+	# TODO
+	ImportXml (sXmlFile, diagramData)
+
+def ImportXml (sFile, diagramData) :
+	# XML to internal representation
+	global g_nodes, g_classes
+	g_nodes = {} # these are not interchangeable between diagrams
+	g_classes = [] # neither are these
+	Process (sFile)
+	# internal representation to diagram
+	layer = diagramData.active_layer
+	# we need some kind of filter to not always generate the whole stl diagram 
+	theLinks = {}
+	nTotal = 0
+	for c in g_classes :
+		theLinks[c.Name()] = 0
+	for c in g_classes :
+		bUsed = 0
+		for p in c.Parents() :
+			if c.Name()[:5] == "std::" : continue # is this too drastic ?
+			if theLinks.has_key(p) :
+				theLinks[p] += 1
+				bUsed = 1
+		if bUsed :
+			# to have bottom most visible as well
+			theLinks[c.Name()] += 1
+			nTotal += 1
+	if nTotal < 2 : # arbitrary limit to generate simple diagrams not using inheritance at all
+		for c in g_classes :
+			if theLinks.has_key(c.Name) :
+				theLinks[c.Name()] += 1
+	# now everything interesting should be in theLinks with a 'ref count' above zero
+	for c in g_classes :
+		if not theLinks.has_key(c.Name()) : continue
+		if theLinks[c.Name()] :
+			theLinks[c.Name()] = c
+		else :
+			del theLinks[c.Name()]
+	theObjects = {}
+	for s in theLinks.keys() :
+		o, h1, h2 = dia.get_object_type("UML - Class").create(0,0)
+		layer.add_object(o)
+		o.properties["name"] = s.encode("UTF-8")
+		if c.abstract :
+			o.properties["abstract"] = 1
+		methods = []
+		attributes = []
+		c = theLinks[s]
+		for mid in c.members :
+			if not g_nodes.has_key(mid) :
+				continue #HACK
+			m = g_nodes[mid]
+			#print m
+			if m.IsMethod () : # (name, type, comment, stereotype, visibility, inheritance_type, query,class_scope, params)
+				params = []
+				for a in m.params :
+					# (name, type, value, comment, kind)
+					try  :
+						print a.name, a.Type()
+						params.append ((a.name.encode("UTF-8"), a.Type().encode("UTF-8"), None, "", 0))
+					except :
+						pass
+				methods.append ((m.name.encode("UTF-8"), m.Type().encode("UTF-8"), "", "", m.Visibility(),m.InheritanceType(),0,0, params))
+			elif m.IsUnion () :
+				pass
+			else : # (name,type,value,comment,visibility,abstract,class_scope)
+				try  :
+					attributes.append ((m.Name().encode("UTF-8"), m.Type().encode("UTF-8"), "", "", m.Visibility(),0,m.static))
+				except  :
+					print "Error", m.name
+		# set some properties 
+		o.properties["operations"] = methods
+		o.properties["attributes"] = attributes
+		
+		theObjects[s] = o
+	# class connections
+	for s in theLinks.keys() :
+		o1 = theObjects[s]
+		c = theLinks[s]
+		for p in c.Parents() :
+			o, h1, h2 = dia.get_object_type("UML - Generalization").create(0,0)
+			layer.add_object(o)
+			o2 = theObjects[p]
+			h1.connect (o2.connections[6])
+			h2.connect (o1.connections[1])
+	# update placement depending on number of parents ?
+	
+	layer.update_extents()
+	#dia.active_display().add_update_all()
+			
+if __name__ == '__main__': 
+	Process(sys.argv[1])
+	for c in g_classes :
+		if c.Name()[:5] == "OBS::" :
+			c.Dump()
+
+import dia
+#dia.register_import("Cpp via GCC_XML", "cpp", ImportCpp)
+dia.register_import("XML from GCC_XML", "xml", ImportXml)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]