src/eric7/Graphics/PackageItem.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2007 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a package item.
8 """
9
10 from PyQt6.QtGui import QFont
11 from PyQt6.QtWidgets import QGraphicsSimpleTextItem, QStyle
12
13 from .UMLItem import UMLModel, UMLItem
14
15 import Utilities
16
17
18 class PackageModel(UMLModel):
19 """
20 Class implementing the package model.
21 """
22 def __init__(self, name, moduleslist=None):
23 """
24 Constructor
25
26 @param name package name
27 @type str
28 @param moduleslist list of module names
29 @type list of str
30 """
31 super().__init__(name)
32
33 self.moduleslist = [] if moduleslist is None else moduleslist[:]
34
35 def addModule(self, modulename):
36 """
37 Public method to add a module to the package model.
38
39 @param modulename module name to be added
40 @type str
41 """
42 self.moduleslist.append(modulename)
43
44 def getModules(self):
45 """
46 Public method to retrieve the modules of the package.
47
48 @return list of module names
49 @rtype list of str
50 """
51 return self.moduleslist[:]
52
53
54 class PackageItem(UMLItem):
55 """
56 Class implementing a package item.
57 """
58 ItemType = "package"
59
60 def __init__(self, model=None, x=0, y=0, rounded=False,
61 noModules=False, colors=None, parent=None, scene=None):
62 """
63 Constructor
64
65 @param model package model containing the package data
66 @type PackageModel
67 @param x x-coordinate
68 @type int
69 @param y y-coordinate
70 @type int
71 @param rounded flag indicating a rounded corner
72 @type bool
73 @param noModules flag indicating, that no module names should be
74 shown
75 @type bool
76 @param colors tuple containing the foreground and background colors
77 @type tuple of (QColor, QColor)
78 @param parent reference to the parent object
79 @type QGraphicsItem
80 @param scene reference to the scene object
81 @type QGraphicsScene
82 """
83 UMLItem.__init__(self, model, x, y, rounded, colors, parent)
84 self.noModules = noModules
85
86 if scene:
87 scene.addItem(self)
88
89 if self.model:
90 self.__createTexts()
91 self.__calculateSize()
92
93 def __createTexts(self):
94 """
95 Private method to create the text items of the class item.
96 """
97 if self.model is None:
98 return
99
100 boldFont = QFont(self.font)
101 boldFont.setBold(True)
102
103 modules = self.model.getModules()
104
105 x = self.margin + int(self.rect().x())
106 y = self.margin + int(self.rect().y())
107 self.header = QGraphicsSimpleTextItem(self)
108 self.header.setBrush(self._colors[0])
109 self.header.setFont(boldFont)
110 self.header.setText(self.model.getName())
111 self.header.setPos(x, y)
112 y += int(self.header.boundingRect().height()) + self.margin
113
114 if not self.noModules:
115 if modules:
116 txt = "\n".join(modules)
117 else:
118 txt = " "
119 self.modules = QGraphicsSimpleTextItem(self)
120 self.modules.setBrush(self._colors[0])
121 self.modules.setFont(self.font)
122 self.modules.setText(txt)
123 self.modules.setPos(x, y)
124 else:
125 self.modules = None
126
127 def __calculateSize(self):
128 """
129 Private method to calculate the size of the package widget.
130 """
131 if self.model is None:
132 return
133
134 width = int(self.header.boundingRect().width())
135 height = int(self.header.boundingRect().height())
136 if self.modules:
137 width = max(width,
138 int(self.modules.boundingRect().width()))
139 height += int(self.modules.boundingRect().height())
140 latchW = width / 3.0
141 latchH = min(15.0, latchW)
142 self.setSize(width + 2 * self.margin,
143 height + latchH + 2 * self.margin)
144
145 x = self.margin + int(self.rect().x())
146 y = self.margin + int(self.rect().y()) + latchH
147 self.header.setPos(x, y)
148 y += int(self.header.boundingRect().height()) + self.margin
149 if self.modules:
150 self.modules.setPos(x, y)
151
152 def setModel(self, model):
153 """
154 Public method to set the package model.
155
156 @param model package model containing the package data
157 @type PackageModel
158 """
159 self.scene().removeItem(self.header)
160 self.header = None
161 if self.modules:
162 self.scene().removeItem(self.modules)
163 self.modules = None
164 self.model = model
165 self.__createTexts()
166 self.__calculateSize()
167
168 def paint(self, painter, option, widget=None):
169 """
170 Public method to paint the item in local coordinates.
171
172 @param painter reference to the painter object
173 @type QPainter
174 @param option style options
175 @type QStyleOptionGraphicsItem
176 @param widget optional reference to the widget painted on
177 @type QWidget
178 """
179 pen = self.pen()
180 if (
181 (option.state & QStyle.StateFlag.State_Selected) ==
182 QStyle.StateFlag.State_Selected
183 ):
184 pen.setWidth(2)
185 else:
186 pen.setWidth(1)
187
188 offsetX = int(self.rect().x())
189 offsetY = int(self.rect().y())
190 w = int(self.rect().width())
191 latchW = w / 3.0
192 latchH = min(15.0, latchW)
193 h = int(self.rect().height() - latchH + 1)
194
195 painter.setPen(pen)
196 painter.setBrush(self.brush())
197 painter.setFont(self.font)
198
199 painter.drawRect(offsetX, offsetY, int(latchW), int(latchH))
200 painter.drawRect(offsetX, offsetY + int(latchH), w, h)
201 y = int(self.margin + self.header.boundingRect().height() + latchH)
202 painter.drawLine(offsetX, offsetY + y, offsetX + w - 1, offsetY + y)
203
204 self.adjustAssociations()
205
206 def parseItemDataString(self, version, data):
207 """
208 Public method to parse the given persistence data.
209
210 @param version version of the data
211 @type str
212 @param data persisted data to be parsed
213 @type str
214 @return flag indicating success
215 @rtype bool
216 """
217 parts = data.split(", ")
218 if len(parts) < 2:
219 return False
220
221 name = ""
222 modules = []
223
224 for part in parts:
225 key, value = part.split("=", 1)
226 if key == "no_modules":
227 self.external = Utilities.toBool(value.strip())
228 elif key == "name":
229 name = value.strip()
230 elif key == "modules":
231 modules = value.strip().split("||")
232 else:
233 return False
234
235 self.model = PackageModel(name, modules)
236 self.__createTexts()
237 self.__calculateSize()
238
239 return True
240
241 def toDict(self):
242 """
243 Public method to collect data to be persisted.
244
245 @return dictionary containing data to be persisted
246 @rtype dict
247 """
248 return {
249 "id": self.getId(),
250 "x": self.x(),
251 "y": self.y(),
252 "type": self.getItemType(),
253 "model_name": self.model.getName(),
254 "no_nodules": self.noModules,
255 "modules": self.model.getModules(),
256 }
257
258 @classmethod
259 def fromDict(cls, data, colors=None):
260 """
261 Class method to create a class item from persisted data.
262
263 @param data dictionary containing the persisted data as generated
264 by toDict()
265 @type dict
266 @param colors tuple containing the foreground and background colors
267 @type tuple of (QColor, QColor)
268 @return created class item
269 @rtype ClassItem
270 """
271 try:
272 model = PackageModel(data["model_name"],
273 data["modules"])
274 itm = cls(model,
275 x=0,
276 y=0,
277 noModules=data["no_nodules"],
278 colors=colors)
279 itm.setPos(data["x"], data["y"])
280 itm.setId(data["id"])
281 return itm
282 except KeyError:
283 return None

eric ide

mercurial