11 |
11 |
12 import os |
12 import os |
13 import pickle |
13 import pickle |
14 |
14 |
15 from PyQt4.QtCore import Qt |
15 from PyQt4.QtCore import Qt |
16 from PyQt4.QtGui import QDialog, QDialogButtonBox, QMenu, QHeaderView, QTreeWidgetItem, \ |
16 from PyQt4.QtGui import QDialog, QDialogButtonBox, QMenu, QHeaderView, \ |
17 QApplication |
17 QTreeWidgetItem, QApplication |
18 |
18 |
19 from E5Gui import E5MessageBox |
19 from E5Gui import E5MessageBox |
20 |
20 |
21 from .Ui_PyProfileDialog import Ui_PyProfileDialog |
21 from .Ui_PyProfileDialog import Ui_PyProfileDialog |
22 import Utilities |
22 import Utilities |
23 |
23 |
24 |
24 |
25 class ProfileTreeWidgetItem(QTreeWidgetItem): |
25 class ProfileTreeWidgetItem(QTreeWidgetItem): |
26 """ |
26 """ |
27 Class implementing a custom QTreeWidgetItem to allow sorting on numeric values. |
27 Class implementing a custom QTreeWidgetItem to allow sorting on numeric |
|
28 values. |
28 """ |
29 """ |
29 def __getNC(self, itm): |
30 def __getNC(self, itm): |
30 """ |
31 """ |
31 Private method to get the value to compare on for the first column. |
32 Private method to get the value to compare on for the first column. |
32 |
33 |
33 @param itm item to operate on (ProfileTreeWidgetItem) |
34 @param itm item to operate on (ProfileTreeWidgetItem) |
|
35 @return comparison value for the first column (integer) |
34 """ |
36 """ |
35 s = itm.text(0) |
37 s = itm.text(0) |
36 return int(s.split('/')[0]) |
38 return int(s.split('/')[0]) |
37 |
39 |
38 def __lt__(self, other): |
40 def __lt__(self, other): |
39 """ |
41 """ |
40 Public method to check, if the item is less than the other one. |
42 Public method to check, if the item is less than the other one. |
41 |
43 |
42 @param other reference to item to compare against (ProfileTreeWidgetItem) |
44 @param other reference to item to compare against |
|
45 (ProfileTreeWidgetItem) |
43 @return true, if this item is less than other (boolean) |
46 @return true, if this item is less than other (boolean) |
44 """ |
47 """ |
45 column = self.treeWidget().sortColumn() |
48 column = self.treeWidget().sortColumn() |
46 if column == 0: |
49 if column == 0: |
47 return self.__getNC(self) < self.__getNC(other) |
50 return self.__getNC(self) < self.__getNC(other) |
66 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) |
69 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) |
67 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) |
70 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) |
68 |
71 |
69 self.cancelled = False |
72 self.cancelled = False |
70 self.exclude = True |
73 self.exclude = True |
71 self.ericpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
74 self.ericpath = os.path.dirname( |
|
75 os.path.dirname(os.path.abspath(__file__))) |
72 self.pyLibPath = Utilities.getPythonLibPath() |
76 self.pyLibPath = Utilities.getPythonLibPath() |
73 |
77 |
74 self.summaryList.headerItem().setText(self.summaryList.columnCount(), "") |
78 self.summaryList.headerItem().setText( |
|
79 self.summaryList.columnCount(), "") |
75 self.resultList.headerItem().setText(self.resultList.columnCount(), "") |
80 self.resultList.headerItem().setText(self.resultList.columnCount(), "") |
76 self.resultList.header().setSortIndicator(0, Qt.DescendingOrder) |
81 self.resultList.header().setSortIndicator(0, Qt.DescendingOrder) |
77 |
82 |
78 self.__menu = QMenu(self) |
83 self.__menu = QMenu(self) |
79 self.filterItm = self.__menu.addAction(self.trUtf8('Exclude Python Library'), |
84 self.filterItm = self.__menu.addAction( |
|
85 self.trUtf8('Exclude Python Library'), |
80 self.__filter) |
86 self.__filter) |
81 self.__menu.addSeparator() |
87 self.__menu.addSeparator() |
82 self.__menu.addAction(self.trUtf8('Erase Profiling Info'), |
88 self.__menu.addAction(self.trUtf8('Erase Profiling Info'), |
83 self.__eraseProfile) |
89 self.__eraseProfile) |
84 self.__menu.addAction(self.trUtf8('Erase Timing Info'), self.__eraseTiming) |
90 self.__menu.addAction(self.trUtf8('Erase Timing Info'), |
|
91 self.__eraseTiming) |
85 self.__menu.addSeparator() |
92 self.__menu.addSeparator() |
86 self.__menu.addAction(self.trUtf8('Erase All Infos'), self.__eraseAll) |
93 self.__menu.addAction(self.trUtf8('Erase All Infos'), self.__eraseAll) |
87 self.resultList.setContextMenuPolicy(Qt.CustomContextMenu) |
94 self.resultList.setContextMenuPolicy(Qt.CustomContextMenu) |
88 self.resultList.customContextMenuRequested.connect(self.__showContextMenu) |
95 self.resultList.customContextMenuRequested.connect( |
|
96 self.__showContextMenu) |
89 self.summaryList.setContextMenuPolicy(Qt.CustomContextMenu) |
97 self.summaryList.setContextMenuPolicy(Qt.CustomContextMenu) |
90 self.summaryList.customContextMenuRequested.connect(self.__showContextMenu) |
98 self.summaryList.customContextMenuRequested.connect( |
91 |
99 self.__showContextMenu) |
92 def __createResultItem(self, calls, totalTime, totalTimePerCall, cumulativeTime, |
100 |
93 cumulativeTimePerCall, file, line, functionName): |
101 def __createResultItem(self, calls, totalTime, totalTimePerCall, |
|
102 cumulativeTime, cumulativeTimePerCall, file, line, |
|
103 functionName): |
94 """ |
104 """ |
95 Private method to create an entry in the result list. |
105 Private method to create an entry in the result list. |
96 |
106 |
97 @param calls number of calls (integer) |
107 @param calls number of calls (integer) |
98 @param totalTime total time (double) |
108 @param totalTime total time (double) |
129 def __resortResultList(self): |
139 def __resortResultList(self): |
130 """ |
140 """ |
131 Private method to resort the tree. |
141 Private method to resort the tree. |
132 """ |
142 """ |
133 self.resultList.sortItems(self.resultList.sortColumn(), |
143 self.resultList.sortItems(self.resultList.sortColumn(), |
134 self.resultList.header().sortIndicatorOrder()) |
144 self.resultList.header() |
|
145 .sortIndicatorOrder()) |
135 |
146 |
136 def __populateLists(self, exclude=False): |
147 def __populateLists(self, exclude=False): |
137 """ |
148 """ |
138 Private method used to populate the listviews. |
149 Private method used to populate the listviews. |
139 |
150 |
159 # now go through all the files |
170 # now go through all the files |
160 for func, (cc, nc, tt, ct, callers) in list(self.stats.items()): |
171 for func, (cc, nc, tt, ct, callers) in list(self.stats.items()): |
161 if self.cancelled: |
172 if self.cancelled: |
162 return |
173 return |
163 |
174 |
164 if not (self.ericpath and func[0].startswith(self.ericpath)) and \ |
175 if not (self.ericpath and |
|
176 func[0].startswith(self.ericpath)) and \ |
165 not func[0].startswith("DebugClients") and \ |
177 not func[0].startswith("DebugClients") and \ |
166 func[0] != "profile" and \ |
178 func[0] != "profile" and \ |
167 not (exclude and ( |
179 not (exclude and ( |
168 func[0].startswith(self.pyLibPath) or func[0] == "")): |
180 func[0].startswith(self.pyLibPath) or func[0] == "")): |
169 if self.file is None or func[0].startswith(self.file) or \ |
181 if self.file is None or func[0].startswith(self.file) or \ |
196 self.resultList.setSortingEnabled(True) |
208 self.resultList.setSortingEnabled(True) |
197 self.resultList.setUpdatesEnabled(True) |
209 self.resultList.setUpdatesEnabled(True) |
198 self.__resortResultList() |
210 self.__resortResultList() |
199 |
211 |
200 # now do the summary stuff |
212 # now do the summary stuff |
201 self.__createSummaryItem(self.trUtf8("function calls"), str(total_calls)) |
213 self.__createSummaryItem(self.trUtf8("function calls"), |
|
214 str(total_calls)) |
202 if total_calls != prim_calls: |
215 if total_calls != prim_calls: |
203 self.__createSummaryItem(self.trUtf8("primitive calls"), str(prim_calls)) |
216 self.__createSummaryItem(self.trUtf8("primitive calls"), |
204 self.__createSummaryItem(self.trUtf8("CPU seconds"), "{0:.3f}".format(total_tt)) |
217 str(prim_calls)) |
|
218 self.__createSummaryItem(self.trUtf8("CPU seconds"), |
|
219 "{0:.3f}".format(total_tt)) |
205 |
220 |
206 def start(self, pfn, fn=None): |
221 def start(self, pfn, fn=None): |
207 """ |
222 """ |
208 Public slot to start the calculation of the profile data. |
223 Public slot to start the calculation of the profile data. |
209 |
224 |