|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2006 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the Breakpoint model. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 from PyQt5.QtCore import pyqtSignal, Qt, QAbstractItemModel, QModelIndex |
|
13 |
|
14 |
|
15 class BreakPointModel(QAbstractItemModel): |
|
16 """ |
|
17 Class implementing a custom model for breakpoints. |
|
18 |
|
19 @signal dataAboutToBeChanged(QModelIndex, QModelIndex) emitted to indicate |
|
20 a change of the data |
|
21 """ |
|
22 dataAboutToBeChanged = pyqtSignal(QModelIndex, QModelIndex) |
|
23 |
|
24 def __init__(self, parent=None): |
|
25 """ |
|
26 Constructor |
|
27 |
|
28 @param parent reference to the parent widget (QObject) |
|
29 """ |
|
30 super(BreakPointModel, self).__init__(parent) |
|
31 |
|
32 self.breakpoints = [] |
|
33 self.header = [ |
|
34 self.tr("Filename"), |
|
35 self.tr("Line"), |
|
36 self.tr('Condition'), |
|
37 self.tr('Temporary'), |
|
38 self.tr('Enabled'), |
|
39 self.tr('Ignore Count'), |
|
40 ] |
|
41 self.alignments = [Qt.Alignment(Qt.AlignLeft), |
|
42 Qt.Alignment(Qt.AlignRight), |
|
43 Qt.Alignment(Qt.AlignLeft), |
|
44 Qt.Alignment(Qt.AlignHCenter), |
|
45 Qt.Alignment(Qt.AlignHCenter), |
|
46 Qt.Alignment(Qt.AlignRight), |
|
47 Qt.Alignment(Qt.AlignHCenter), |
|
48 ] |
|
49 |
|
50 def columnCount(self, parent=None): |
|
51 """ |
|
52 Public method to get the current column count. |
|
53 |
|
54 @param parent reference to parent index (QModelIndex) (Unused) |
|
55 @return column count (integer) |
|
56 """ |
|
57 return len(self.header) |
|
58 |
|
59 def rowCount(self, parent=None): |
|
60 """ |
|
61 Public method to get the current row count. |
|
62 |
|
63 @param parent reference to parent index (QModelIndex) |
|
64 @return row count (integer) |
|
65 """ |
|
66 # we do not have a tree, parent should always be invalid |
|
67 if parent is None or not parent.isValid(): |
|
68 return len(self.breakpoints) |
|
69 else: |
|
70 return 0 |
|
71 |
|
72 def data(self, index, role=Qt.DisplayRole): |
|
73 """ |
|
74 Public method to get the requested data. |
|
75 |
|
76 @param index index of the requested data (QModelIndex) |
|
77 @param role role of the requested data (Qt.ItemDataRole) |
|
78 @return the requested data |
|
79 """ |
|
80 if not index.isValid(): |
|
81 return None |
|
82 |
|
83 if role == Qt.DisplayRole: |
|
84 if index.column() in [0, 1, 2, 5]: |
|
85 return self.breakpoints[index.row()][index.column()] |
|
86 |
|
87 if role == Qt.CheckStateRole: |
|
88 if index.column() in [3, 4]: |
|
89 return self.breakpoints[index.row()][index.column()] |
|
90 |
|
91 if role == Qt.ToolTipRole: |
|
92 if index.column() in [0, 2]: |
|
93 return self.breakpoints[index.row()][index.column()] |
|
94 |
|
95 if role == Qt.TextAlignmentRole: |
|
96 if index.column() < len(self.alignments): |
|
97 return self.alignments[index.column()] |
|
98 |
|
99 return None |
|
100 |
|
101 def setData(self, index, value, role=Qt.EditRole): |
|
102 """ |
|
103 Public method to change data in the model. |
|
104 |
|
105 @param index index of the changed data (QModelIndex) |
|
106 @param value value of the changed data |
|
107 @param role role of the changed data (Qt.ItemDataRole) |
|
108 @return flag indicating success (boolean) |
|
109 """ |
|
110 if not index.isValid() or \ |
|
111 index.column() >= len(self.header) or \ |
|
112 index.row() >= len(self.breakpoints): |
|
113 return False |
|
114 |
|
115 self.dataAboutToBeChanged.emit(index, index) |
|
116 self.breakpoints[index.row()][index.column()] = value |
|
117 self.dataChanged.emit(index, index) |
|
118 return True |
|
119 |
|
120 def flags(self, index): |
|
121 """ |
|
122 Public method to get item flags. |
|
123 |
|
124 @param index index of the requested flags (QModelIndex) |
|
125 @return item flags for the given index (Qt.ItemFlags) |
|
126 """ |
|
127 if not index.isValid(): |
|
128 return Qt.ItemIsEnabled |
|
129 |
|
130 return Qt.ItemIsEnabled | Qt.ItemIsSelectable |
|
131 |
|
132 def headerData(self, section, orientation, role=Qt.DisplayRole): |
|
133 """ |
|
134 Public method to get header data. |
|
135 |
|
136 @param section section number of the requested header data (integer) |
|
137 @param orientation orientation of the header (Qt.Orientation) |
|
138 @param role role of the requested data (Qt.ItemDataRole) |
|
139 @return header data |
|
140 """ |
|
141 if orientation == Qt.Horizontal and role == Qt.DisplayRole: |
|
142 if section >= len(self.header): |
|
143 return "" |
|
144 else: |
|
145 return self.header[section] |
|
146 |
|
147 return None |
|
148 |
|
149 def index(self, row, column, parent=None): |
|
150 """ |
|
151 Public method to create an index. |
|
152 |
|
153 @param row row number for the index (integer) |
|
154 @param column column number for the index (integer) |
|
155 @param parent index of the parent item (QModelIndex) |
|
156 @return requested index (QModelIndex) |
|
157 """ |
|
158 if (parent and parent.isValid()) or \ |
|
159 row < 0 or row >= len(self.breakpoints) or \ |
|
160 column < 0 or column >= len(self.header): |
|
161 return QModelIndex() |
|
162 |
|
163 return self.createIndex(row, column, self.breakpoints[row]) |
|
164 |
|
165 def parent(self, index): |
|
166 """ |
|
167 Public method to get the parent index. |
|
168 |
|
169 @param index index of item to get parent (QModelIndex) |
|
170 @return index of parent (QModelIndex) |
|
171 """ |
|
172 return QModelIndex() |
|
173 |
|
174 def hasChildren(self, parent=None): |
|
175 """ |
|
176 Public method to check for the presence of child items. |
|
177 |
|
178 @param parent index of parent item (QModelIndex) |
|
179 @return flag indicating the presence of child items (boolean) |
|
180 """ |
|
181 if parent is None or not parent.isValid(): |
|
182 return len(self.breakpoints) > 0 |
|
183 else: |
|
184 return False |
|
185 |
|
186 ########################################################################### |
|
187 |
|
188 def addBreakPoint(self, fn, line, properties): |
|
189 """ |
|
190 Public method to add a new breakpoint to the list. |
|
191 |
|
192 @param fn filename of the breakpoint (string) |
|
193 @param line line number of the breakpoint (integer) |
|
194 @param properties properties of the breakpoint |
|
195 (tuple of condition (string), temporary flag (bool), |
|
196 enabled flag (bool), ignore count (integer)) |
|
197 """ |
|
198 bp = [fn, line] + list(properties) |
|
199 cnt = len(self.breakpoints) |
|
200 self.beginInsertRows(QModelIndex(), cnt, cnt) |
|
201 self.breakpoints.append(bp) |
|
202 self.endInsertRows() |
|
203 |
|
204 def setBreakPointByIndex(self, index, fn, line, properties): |
|
205 """ |
|
206 Public method to set the values of a breakpoint given by index. |
|
207 |
|
208 @param index index of the breakpoint (QModelIndex) |
|
209 @param fn filename of the breakpoint (string) |
|
210 @param line line number of the breakpoint (integer) |
|
211 @param properties properties of the breakpoint |
|
212 (tuple of condition (string), temporary flag (bool), |
|
213 enabled flag (bool), ignore count (integer)) |
|
214 """ |
|
215 if index.isValid(): |
|
216 row = index.row() |
|
217 index1 = self.createIndex(row, 0, self.breakpoints[row]) |
|
218 index2 = self.createIndex( |
|
219 row, len(self.breakpoints[row]), self.breakpoints[row]) |
|
220 self.dataAboutToBeChanged.emit(index1, index2) |
|
221 self.breakpoints[row] = [fn, line] + list(properties) |
|
222 self.dataChanged.emit(index1, index2) |
|
223 |
|
224 def setBreakPointEnabledByIndex(self, index, enabled): |
|
225 """ |
|
226 Public method to set the enabled state of a breakpoint given by index. |
|
227 |
|
228 @param index index of the breakpoint (QModelIndex) |
|
229 @param enabled flag giving the enabled state (boolean) |
|
230 """ |
|
231 if index.isValid(): |
|
232 row = index.row() |
|
233 col = 4 |
|
234 index1 = self.createIndex(row, col, self.breakpoints[row]) |
|
235 self.dataAboutToBeChanged.emit(index1, index1) |
|
236 self.breakpoints[row][col] = enabled |
|
237 self.dataChanged.emit(index1, index1) |
|
238 |
|
239 def deleteBreakPointByIndex(self, index): |
|
240 """ |
|
241 Public method to set the values of a breakpoint given by index. |
|
242 |
|
243 @param index index of the breakpoint (QModelIndex) |
|
244 """ |
|
245 if index.isValid(): |
|
246 row = index.row() |
|
247 self.beginRemoveRows(QModelIndex(), row, row) |
|
248 del self.breakpoints[row] |
|
249 self.endRemoveRows() |
|
250 |
|
251 def deleteBreakPoints(self, idxList): |
|
252 """ |
|
253 Public method to delete a list of breakpoints given by their indexes. |
|
254 |
|
255 @param idxList list of breakpoint indexes (list of QModelIndex) |
|
256 """ |
|
257 rows = [] |
|
258 for index in idxList: |
|
259 if index.isValid(): |
|
260 rows.append(index.row()) |
|
261 rows.sort(reverse=True) |
|
262 for row in rows: |
|
263 self.beginRemoveRows(QModelIndex(), row, row) |
|
264 del self.breakpoints[row] |
|
265 self.endRemoveRows() |
|
266 |
|
267 def deleteAll(self): |
|
268 """ |
|
269 Public method to delete all breakpoints. |
|
270 """ |
|
271 if self.breakpoints: |
|
272 self.beginRemoveRows(QModelIndex(), 0, len(self.breakpoints) - 1) |
|
273 self.breakpoints = [] |
|
274 self.endRemoveRows() |
|
275 |
|
276 def getBreakPointByIndex(self, index): |
|
277 """ |
|
278 Public method to get the values of a breakpoint given by index. |
|
279 |
|
280 @param index index of the breakpoint (QModelIndex) |
|
281 @return breakpoint (list of seven values (filename, line number, |
|
282 condition, temporary flag, enabled flag, ignore count)) |
|
283 """ |
|
284 if index.isValid(): |
|
285 return self.breakpoints[index.row()][:] # return a copy |
|
286 else: |
|
287 return [] |
|
288 |
|
289 def getBreakPointIndex(self, fn, lineno): |
|
290 """ |
|
291 Public method to get the index of a breakpoint given by filename and |
|
292 line number. |
|
293 |
|
294 @param fn filename of the breakpoint (string) |
|
295 @param lineno line number of the breakpoint (integer) |
|
296 @return index (QModelIndex) |
|
297 """ |
|
298 for row in range(len(self.breakpoints)): |
|
299 bp = self.breakpoints[row] |
|
300 if bp[0] == fn and bp[1] == lineno: |
|
301 return self.createIndex(row, 0, self.breakpoints[row]) |
|
302 |
|
303 return QModelIndex() |
|
304 |
|
305 def isBreakPointTemporaryByIndex(self, index): |
|
306 """ |
|
307 Public method to test, if a breakpoint given by its index is temporary. |
|
308 |
|
309 @param index index of the breakpoint to test (QModelIndex) |
|
310 @return flag indicating a temporary breakpoint (boolean) |
|
311 """ |
|
312 if index.isValid(): |
|
313 return self.breakpoints[index.row()][3] |
|
314 else: |
|
315 return False |