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