DataViews/CodeMetricsDialog.py

changeset 0
de9c2efb9d02
child 12
1d8dd9706f46
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2003 - 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a code metrics dialog.
8 """
9
10 import sys
11 import os
12 import types
13
14 from PyQt4.QtCore import *
15 from PyQt4.QtGui import *
16
17 from Ui_CodeMetricsDialog import Ui_CodeMetricsDialog
18 import CodeMetrics
19 import Utilities
20
21 class CodeMetricsDialog(QDialog, Ui_CodeMetricsDialog):
22 """
23 Class implementing a dialog to display the code metrics.
24 """
25 def __init__(self, parent = None):
26 """
27 Constructor
28
29 @param parent parent widget (QWidget)
30 """
31 QDialog.__init__(self, parent)
32 self.setupUi(self)
33
34 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
35 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
36
37 self.summaryList.headerItem().setText(self.summaryList.columnCount(), "")
38 self.summaryList.header().resizeSection(0, 200)
39 self.summaryList.header().resizeSection(1, 100)
40
41 self.resultList.headerItem().setText(self.resultList.columnCount(), "")
42
43 self.cancelled = False
44
45 self.__menu = QMenu(self)
46 self.__menu.addAction(self.trUtf8("Collapse all"), self.__resultCollapse)
47 self.__menu.addAction(self.trUtf8("Expand all"), self.__resultExpand)
48 self.resultList.setContextMenuPolicy(Qt.CustomContextMenu)
49 self.connect(self.resultList,
50 SIGNAL('customContextMenuRequested(const QPoint &)'),
51 self.__showContextMenu)
52
53 def __resizeResultColumns(self):
54 """
55 Private method to resize the list columns.
56 """
57 self.resultList.header().resizeSections(QHeaderView.ResizeToContents)
58 self.resultList.header().setStretchLastSection(True)
59
60 def __createResultItem(self, parent, strings):
61 """
62 Private slot to create a new item in the result list.
63
64 @param parent parent of the new item (QTreeWidget or QTreeWidgetItem)
65 @param strings strings to be displayed (list of strings)
66 @return the generated item
67 """
68 itm = QTreeWidgetItem(parent, strings)
69 for col in range(1,7):
70 itm.setTextAlignment(col, Qt.Alignment(Qt.AlignRight))
71 return itm
72
73 def __resizeSummaryColumns(self):
74 """
75 Private method to resize the list columns.
76 """
77 self.summaryList.doItemsLayout()
78 self.summaryList.header().resizeSections(QHeaderView.ResizeToContents)
79 self.summaryList.header().setStretchLastSection(True)
80
81 def __createSummaryItem(self, col0, col1):
82 """
83 Private slot to create a new item in the summary list.
84
85 @param col0 string for column 0 (string)
86 @param col1 string for column 1 (string)
87 """
88 itm = QTreeWidgetItem(self.summaryList, [col0, col1])
89 itm.setTextAlignment(1, Qt.Alignment(Qt.AlignRight))
90
91 def start(self, fn):
92 """
93 Public slot to start the code metrics determination.
94
95 @param fn file or list of files or directory to be show
96 the code metrics for (string or list of strings)
97 """
98 loc = QLocale()
99 if type(fn) is types.ListType:
100 files = fn
101 elif os.path.isdir(fn):
102 files = Utilities.direntries(fn, True, '*.py', False)
103 else:
104 files = [fn]
105 files.sort()
106 # check for missing files
107 for f in files[:]:
108 if not os.path.exists(f):
109 files.remove(f)
110
111 self.checkProgress.setMaximum(len(files))
112 QApplication.processEvents()
113
114 total = {}
115 CodeMetrics.summarize(total, 'files', len(files))
116
117 progress = 0
118
119 try:
120 # disable updates of the list for speed
121 self.resultList.setUpdatesEnabled(False)
122 self.resultList.setSortingEnabled(False)
123
124 # now go through all the files
125 for file in files:
126 if self.cancelled:
127 return
128
129 stats = CodeMetrics.analyze(file, total)
130
131 v = self.__getValues(loc, stats, 'TOTAL ')
132 fitm = self.__createResultItem(self.resultList, [file] + v)
133
134 identifiers = stats.identifiers
135 for identifier in identifiers:
136 v = self.__getValues(loc, stats, identifier)
137
138 self.__createResultItem(fitm, [identifier] + v)
139 self.resultList.expandItem(fitm)
140
141 progress += 1
142 self.checkProgress.setValue(progress)
143 QApplication.processEvents()
144 finally:
145 # reenable updates of the list
146 self.resultList.setSortingEnabled(True)
147 self.resultList.setUpdatesEnabled(True)
148 self.__resizeResultColumns()
149
150 # now do the summary stuff
151 docstrings = total['lines'] - total['comments'] - \
152 total['empty lines'] - total['non-commentary lines']
153 self.__createSummaryItem(self.trUtf8("files"), loc.toString(total['files']))
154 self.__createSummaryItem(self.trUtf8("lines"), loc.toString(total['lines']))
155 self.__createSummaryItem(self.trUtf8("bytes"), loc.toString(total['bytes']))
156 self.__createSummaryItem(self.trUtf8("comments"), loc.toString(total['comments']))
157 self.__createSummaryItem(self.trUtf8("empty lines"),
158 loc.toString(total['empty lines']))
159 self.__createSummaryItem(self.trUtf8("non-commentary lines"),
160 loc.toString(total['non-commentary lines']))
161 self.__createSummaryItem(self.trUtf8("documentation lines"),
162 loc.toString(docstrings))
163 self.__resizeSummaryColumns()
164 self.__finish()
165
166 def __getValues(self, loc, stats, identifier):
167 """
168 Private method to extract the code metric values.
169
170 @param loc reference to the locale object (QLocale)
171 @param stats reference to the code metric statistics object
172 @param identifier identifier to get values for
173 @return list of values suitable for display (list of strings)
174 """
175 counters = stats.counters.get(identifier, {})
176 v = []
177 for key in ('start', 'end', 'lines', 'nloc', 'comments', 'empty'):
178 if counters.get(key, 0):
179 v.append("{0:>7}".format(loc.toString(counters[key])))
180 else:
181 v.append('')
182 return v
183
184 def __finish(self):
185 """
186 Private slot called when the action finished or the user pressed the button.
187 """
188 self.cancelled = True
189 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
190 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
191 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
192
193 self.resultList.header().setResizeMode(QHeaderView.Interactive)
194 self.summaryList.header().setResizeMode(QHeaderView.Interactive)
195
196 def on_buttonBox_clicked(self, button):
197 """
198 Private slot called by a button of the button box clicked.
199
200 @param button button that was clicked (QAbstractButton)
201 """
202 if button == self.buttonBox.button(QDialogButtonBox.Close):
203 self.close()
204 elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
205 self.__finish()
206
207 def __showContextMenu(self, coord):
208 """
209 Private slot to show the context menu of the listview.
210
211 @param coord the position of the mouse pointer (QPoint)
212 """
213 if self.resultList.topLevelItemCount() > 0:
214 self.__menu.popup(self.mapToGlobal(coord))
215
216 def __resultCollapse(self):
217 """
218 Private slot to collapse all entries of the resultlist.
219 """
220 for index in range(self.resultList.topLevelItemCount()):
221 self.resultList.topLevelItem(index).setExpanded(False)
222
223 def __resultExpand(self):
224 """
225 Private slot to expand all entries of the resultlist.
226 """
227 for index in range(self.resultList.topLevelItemCount()):
228 self.resultList.topLevelItem(index).setExpanded(True)

eric ide

mercurial