eric6/Graphics/ClassItem.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
child 7229
53054eb5b15a
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2007 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing an UML like class item.
8 """
9
10 from __future__ import unicode_literals
11
12 from PyQt5.QtGui import QFont
13 from PyQt5.QtWidgets import QGraphicsSimpleTextItem, QStyle
14
15 from .UMLItem import UMLModel, UMLItem
16
17 import Utilities
18
19
20 class ClassModel(UMLModel):
21 """
22 Class implementing the class model.
23 """
24 def __init__(self, name, methods=None, attributes=None):
25 """
26 Constructor
27
28 @param name the class name (string)
29 @param methods list of method names of the class
30 (list of strings)
31 @param attributes list of attribute names of the class
32 (list of strings)
33 """
34 super(ClassModel, self).__init__(name)
35
36 self.methods = [] if methods is None else methods[:]
37 self.attributes = [] if attributes is None else attributes[:]
38
39 def addMethod(self, method):
40 """
41 Public method to add a method to the class model.
42
43 @param method method name to be added (string)
44 """
45 self.methods.append(method)
46
47 def addAttribute(self, attribute):
48 """
49 Public method to add an attribute to the class model.
50
51 @param attribute attribute name to be added (string)
52 """
53 self.attributes.append(attribute)
54
55 def getMethods(self):
56 """
57 Public method to retrieve the methods of the class.
58
59 @return list of class methods (list of strings)
60 """
61 return self.methods[:]
62
63 def getAttributes(self):
64 """
65 Public method to retrieve the attributes of the class.
66
67 @return list of class attributes (list of strings)
68 """
69 return self.attributes[:]
70
71
72 class ClassItem(UMLItem):
73 """
74 Class implementing an UML like class item.
75 """
76 ItemType = "class"
77
78 def __init__(self, model=None, external=False, x=0, y=0,
79 rounded=False, noAttrs=False, parent=None, scene=None):
80 """
81 Constructor
82
83 @param model class model containing the class data (ClassModel)
84 @param external flag indicating a class defined outside our scope
85 (boolean)
86 @param x x-coordinate (integer)
87 @param y y-coordinate (integer)
88 @keyparam rounded flag indicating a rounded corner (boolean)
89 @keyparam noAttrs flag indicating, that no attributes should be shown
90 (boolean)
91 @keyparam parent reference to the parent object (QGraphicsItem)
92 @keyparam scene reference to the scene object (QGraphicsScene)
93 """
94 UMLItem.__init__(self, model, x, y, rounded, parent)
95
96 self.external = external
97 self.noAttrs = noAttrs
98
99 scene.addItem(self)
100
101 if self.model:
102 self.__createTexts()
103 self.__calculateSize()
104
105 def __createTexts(self):
106 """
107 Private method to create the text items of the class item.
108 """
109 if self.model is None:
110 return
111
112 boldFont = QFont(self.font)
113 boldFont.setBold(True)
114
115 attrs = self.model.getAttributes()
116 meths = self.model.getMethods()
117
118 x = self.margin + self.rect().x()
119 y = self.margin + self.rect().y()
120 self.header = QGraphicsSimpleTextItem(self)
121 self.header.setFont(boldFont)
122 self.header.setText(self.model.getName())
123 self.header.setPos(x, y)
124 y += self.header.boundingRect().height() + self.margin
125 if not self.noAttrs and not self.external:
126 if attrs:
127 txt = "\n".join(attrs)
128 else:
129 txt = " "
130 self.attrs = QGraphicsSimpleTextItem(self)
131 self.attrs.setFont(self.font)
132 self.attrs.setText(txt)
133 self.attrs.setPos(x, y)
134 y += self.attrs.boundingRect().height() + self.margin
135 else:
136 self.attrs = None
137 if meths:
138 txt = "\n".join(meths)
139 else:
140 txt = " "
141 self.meths = QGraphicsSimpleTextItem(self)
142 self.meths.setFont(self.font)
143 self.meths.setText(txt)
144 self.meths.setPos(x, y)
145
146 def __calculateSize(self):
147 """
148 Private method to calculate the size of the class item.
149 """
150 if self.model is None:
151 return
152
153 width = self.header.boundingRect().width()
154 height = self.header.boundingRect().height()
155 if self.attrs:
156 width = max(width, self.attrs.boundingRect().width())
157 height = height + self.attrs.boundingRect().height() + self.margin
158 if self.meths:
159 width = max(width, self.meths.boundingRect().width())
160 height = height + self.meths.boundingRect().height()
161 self.setSize(width + 2 * self.margin, height + 2 * self.margin)
162
163 def setModel(self, model):
164 """
165 Public method to set the class model.
166
167 @param model class model containing the class data (ClassModel)
168 """
169 self.scene().removeItem(self.header)
170 self.header = None
171 if self.attrs:
172 self.scene().removeItem(self.attrs)
173 self.attrs = None
174 if self.meths:
175 self.scene().removeItem(self.meths)
176 self.meths = None
177 self.model = model
178 self.__createTexts()
179 self.__calculateSize()
180
181 def paint(self, painter, option, widget=None):
182 """
183 Public method to paint the item in local coordinates.
184
185 @param painter reference to the painter object (QPainter)
186 @param option style options (QStyleOptionGraphicsItem)
187 @param widget optional reference to the widget painted on (QWidget)
188 """
189 pen = self.pen()
190 if (option.state & QStyle.State_Selected) == \
191 QStyle.State(QStyle.State_Selected):
192 pen.setWidth(2)
193 else:
194 pen.setWidth(1)
195
196 painter.setPen(pen)
197 painter.setBrush(self.brush())
198 painter.setFont(self.font)
199
200 offsetX = self.rect().x()
201 offsetY = self.rect().y()
202 w = self.rect().width()
203 h = self.rect().height()
204
205 painter.drawRect(offsetX, offsetY, w, h)
206 y = self.margin + self.header.boundingRect().height()
207 painter.drawLine(offsetX, offsetY + y, offsetX + w - 1, offsetY + y)
208 if self.attrs:
209 y += self.margin + self.attrs.boundingRect().height()
210 painter.drawLine(offsetX, offsetY + y,
211 offsetX + w - 1, offsetY + y)
212
213 self.adjustAssociations()
214
215 def isExternal(self):
216 """
217 Public method returning the external state.
218
219 @return external state (boolean)
220 """
221 return self.external
222
223 def buildItemDataString(self):
224 """
225 Public method to build a string to persist the specific item data.
226
227 This string must start with ", " and should be built like
228 "attribute=value" with pairs separated by ", ". value must not
229 contain ", " or newlines.
230
231 @return persistence data (string)
232 """
233 entries = [
234 "is_external={0}".format(self.external),
235 "no_attributes={0}".format(self.noAttrs),
236 "name={0}".format(self.model.getName()),
237 ]
238 attributes = self.model.getAttributes()
239 if attributes:
240 entries.append("attributes={0}".format("||".join(attributes)))
241 methods = self.model.getMethods()
242 if methods:
243 entries.append("methods={0}".format("||".join(methods)))
244
245 return ", " + ", ".join(entries)
246
247 def parseItemDataString(self, version, data):
248 """
249 Public method to parse the given persistence data.
250
251 @param version version of the data (string)
252 @param data persisted data to be parsed (string)
253 @return flag indicating success (boolean)
254 """
255 parts = data.split(", ")
256 if len(parts) < 3:
257 return False
258
259 name = ""
260 attributes = []
261 methods = []
262
263 for part in parts:
264 key, value = part.split("=", 1)
265 if key == "is_external":
266 self.external = Utilities.toBool(value.strip())
267 elif key == "no_attributes":
268 self.noAttrs = Utilities.toBool(value.strip())
269 elif key == "name":
270 name = value.strip()
271 elif key == "attributes":
272 attributes = value.strip().split("||")
273 elif key == "methods":
274 methods = value.strip().split("||")
275 else:
276 return False
277
278 self.model = ClassModel(name, methods, attributes)
279 self.__createTexts()
280 self.__calculateSize()
281
282 return True

eric ide

mercurial