diff options
| author | Sean Paul <seanpaul@chromium.org> | 2019-05-22 16:08:21 -0400 | 
|---|---|---|
| committer | Sean Paul <seanpaul@chromium.org> | 2019-05-22 16:08:21 -0400 | 
| commit | 374ed5429346a021c8e2d26fafce14c5b15dedd0 (patch) | |
| tree | 70739e93443494993197cc11f41c0fd0a0f3aac0 /tools/perf/scripts/python/exported-sql-viewer.py | |
| parent | 270afb37ae34fc1499d166f6edf4bc472f529d96 (diff) | |
| parent | a188339ca5a396acc588e5851ed7e19f66b0ebd9 (diff) | |
Merge drm/drm-next into drm-misc-next
Backmerging 5.2-rc1 to -misc-next for robher
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Diffstat (limited to 'tools/perf/scripts/python/exported-sql-viewer.py')
| -rwxr-xr-x | tools/perf/scripts/python/exported-sql-viewer.py | 340 | 
1 files changed, 333 insertions, 7 deletions
| diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py index 74ef92f1d19a..affed7d149be 100755 --- a/tools/perf/scripts/python/exported-sql-viewer.py +++ b/tools/perf/scripts/python/exported-sql-viewer.py @@ -456,6 +456,10 @@ class CallGraphLevelItemBase(object):  		self.query_done = False;  		self.child_count = 0  		self.child_items = [] +		if parent_item: +			self.level = parent_item.level + 1 +		else: +			self.level = 0  	def getChildItem(self, row):  		return self.child_items[row] @@ -877,9 +881,14 @@ class TreeWindowBase(QMdiSubWindow):  		super(TreeWindowBase, self).__init__(parent)  		self.model = None -		self.view = None  		self.find_bar = None +		self.view = QTreeView() +		self.view.setSelectionMode(QAbstractItemView.ContiguousSelection) +		self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard + +		self.context_menu = TreeContextMenu(self.view) +  	def DisplayFound(self, ids):  		if not len(ids):  			return False @@ -921,7 +930,6 @@ class CallGraphWindow(TreeWindowBase):  		self.model = LookupCreateModel("Context-Sensitive Call Graph", lambda x=glb: CallGraphModel(x)) -		self.view = QTreeView()  		self.view.setModel(self.model)  		for c, w in ((0, 250), (1, 100), (2, 60), (3, 70), (4, 70), (5, 100)): @@ -944,7 +952,6 @@ class CallTreeWindow(TreeWindowBase):  		self.model = LookupCreateModel("Call Tree", lambda x=glb: CallTreeModel(x)) -		self.view = QTreeView()  		self.view.setModel(self.model)  		for c, w in ((0, 230), (1, 100), (2, 100), (3, 70), (4, 70), (5, 100)): @@ -1649,10 +1656,14 @@ class BranchWindow(QMdiSubWindow):  		self.view = QTreeView()  		self.view.setUniformRowHeights(True) +		self.view.setSelectionMode(QAbstractItemView.ContiguousSelection) +		self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard  		self.view.setModel(self.model)  		self.ResizeColumnsToContents() +		self.context_menu = TreeContextMenu(self.view) +  		self.find_bar = FindBar(self, self, True)  		self.finder = ChildDataItemFinder(self.model.root) @@ -2261,6 +2272,240 @@ class ResizeColumnsToContentsBase(QObject):  		self.data_model.rowsInserted.disconnect(self.UpdateColumnWidths)  		self.ResizeColumnsToContents() +# Convert value to CSV + +def ToCSValue(val): +	if '"' in val: +		val = val.replace('"', '""') +	if "," in val or '"' in val: +		val = '"' + val + '"' +	return val + +# Key to sort table model indexes by row / column, assuming fewer than 1000 columns + +glb_max_cols = 1000 + +def RowColumnKey(a): +	return a.row() * glb_max_cols + a.column() + +# Copy selected table cells to clipboard + +def CopyTableCellsToClipboard(view, as_csv=False, with_hdr=False): +	indexes = sorted(view.selectedIndexes(), key=RowColumnKey) +	idx_cnt = len(indexes) +	if not idx_cnt: +		return +	if idx_cnt == 1: +		with_hdr=False +	min_row = indexes[0].row() +	max_row = indexes[0].row() +	min_col = indexes[0].column() +	max_col = indexes[0].column() +	for i in indexes: +		min_row = min(min_row, i.row()) +		max_row = max(max_row, i.row()) +		min_col = min(min_col, i.column()) +		max_col = max(max_col, i.column()) +	if max_col > glb_max_cols: +		raise RuntimeError("glb_max_cols is too low") +	max_width = [0] * (1 + max_col - min_col) +	for i in indexes: +		c = i.column() - min_col +		max_width[c] = max(max_width[c], len(str(i.data()))) +	text = "" +	pad = "" +	sep = "" +	if with_hdr: +		model = indexes[0].model() +		for col in range(min_col, max_col + 1): +			val = model.headerData(col, Qt.Horizontal) +			if as_csv: +				text += sep + ToCSValue(val) +				sep = "," +			else: +				c = col - min_col +				max_width[c] = max(max_width[c], len(val)) +				width = max_width[c] +				align = model.headerData(col, Qt.Horizontal, Qt.TextAlignmentRole) +				if align & Qt.AlignRight: +					val = val.rjust(width) +				text += pad + sep + val +				pad = " " * (width - len(val)) +				sep = "  " +		text += "\n" +		pad = "" +		sep = "" +	last_row = min_row +	for i in indexes: +		if i.row() > last_row: +			last_row = i.row() +			text += "\n" +			pad = "" +			sep = "" +		if as_csv: +			text += sep + ToCSValue(str(i.data())) +			sep = "," +		else: +			width = max_width[i.column() - min_col] +			if i.data(Qt.TextAlignmentRole) & Qt.AlignRight: +				val = str(i.data()).rjust(width) +			else: +				val = str(i.data()) +			text += pad + sep + val +			pad = " " * (width - len(val)) +			sep = "  " +	QApplication.clipboard().setText(text) + +def CopyTreeCellsToClipboard(view, as_csv=False, with_hdr=False): +	indexes = view.selectedIndexes() +	if not len(indexes): +		return + +	selection = view.selectionModel() + +	first = None +	for i in indexes: +		above = view.indexAbove(i) +		if not selection.isSelected(above): +			first = i +			break + +	if first is None: +		raise RuntimeError("CopyTreeCellsToClipboard internal error") + +	model = first.model() +	row_cnt = 0 +	col_cnt = model.columnCount(first) +	max_width = [0] * col_cnt + +	indent_sz = 2 +	indent_str = " " * indent_sz + +	expanded_mark_sz = 2 +	if sys.version_info[0] == 3: +		expanded_mark = "\u25BC " +		not_expanded_mark = "\u25B6 " +	else: +		expanded_mark = unicode(chr(0xE2) + chr(0x96) + chr(0xBC) + " ", "utf-8") +		not_expanded_mark =  unicode(chr(0xE2) + chr(0x96) + chr(0xB6) + " ", "utf-8") +	leaf_mark = "  " + +	if not as_csv: +		pos = first +		while True: +			row_cnt += 1 +			row = pos.row() +			for c in range(col_cnt): +				i = pos.sibling(row, c) +				if c: +					n = len(str(i.data())) +				else: +					n = len(str(i.data()).strip()) +					n += (i.internalPointer().level - 1) * indent_sz +					n += expanded_mark_sz +				max_width[c] = max(max_width[c], n) +			pos = view.indexBelow(pos) +			if not selection.isSelected(pos): +				break + +	text = "" +	pad = "" +	sep = "" +	if with_hdr: +		for c in range(col_cnt): +			val = model.headerData(c, Qt.Horizontal, Qt.DisplayRole).strip() +			if as_csv: +				text += sep + ToCSValue(val) +				sep = "," +			else: +				max_width[c] = max(max_width[c], len(val)) +				width = max_width[c] +				align = model.headerData(c, Qt.Horizontal, Qt.TextAlignmentRole) +				if align & Qt.AlignRight: +					val = val.rjust(width) +				text += pad + sep + val +				pad = " " * (width - len(val)) +				sep = "   " +		text += "\n" +		pad = "" +		sep = "" + +	pos = first +	while True: +		row = pos.row() +		for c in range(col_cnt): +			i = pos.sibling(row, c) +			val = str(i.data()) +			if not c: +				if model.hasChildren(i): +					if view.isExpanded(i): +						mark = expanded_mark +					else: +						mark = not_expanded_mark +				else: +					mark = leaf_mark +				val = indent_str * (i.internalPointer().level - 1) + mark + val.strip() +			if as_csv: +				text += sep + ToCSValue(val) +				sep = "," +			else: +				width = max_width[c] +				if c and i.data(Qt.TextAlignmentRole) & Qt.AlignRight: +					val = val.rjust(width) +				text += pad + sep + val +				pad = " " * (width - len(val)) +				sep = "   " +		pos = view.indexBelow(pos) +		if not selection.isSelected(pos): +			break +		text = text.rstrip() + "\n" +		pad = "" +		sep = "" + +	QApplication.clipboard().setText(text) + +def CopyCellsToClipboard(view, as_csv=False, with_hdr=False): +	view.CopyCellsToClipboard(view, as_csv, with_hdr) + +def CopyCellsToClipboardHdr(view): +	CopyCellsToClipboard(view, False, True) + +def CopyCellsToClipboardCSV(view): +	CopyCellsToClipboard(view, True, True) + +# Context menu + +class ContextMenu(object): + +	def __init__(self, view): +		self.view = view +		self.view.setContextMenuPolicy(Qt.CustomContextMenu) +		self.view.customContextMenuRequested.connect(self.ShowContextMenu) + +	def ShowContextMenu(self, pos): +		menu = QMenu(self.view) +		self.AddActions(menu) +		menu.exec_(self.view.mapToGlobal(pos)) + +	def AddCopy(self, menu): +		menu.addAction(CreateAction("&Copy selection", "Copy to clipboard", lambda: CopyCellsToClipboardHdr(self.view), self.view)) +		menu.addAction(CreateAction("Copy selection as CS&V", "Copy to clipboard as CSV", lambda: CopyCellsToClipboardCSV(self.view), self.view)) + +	def AddActions(self, menu): +		self.AddCopy(menu) + +class TreeContextMenu(ContextMenu): + +	def __init__(self, view): +		super(TreeContextMenu, self).__init__(view) + +	def AddActions(self, menu): +		i = self.view.currentIndex() +		text = str(i.data()).strip() +		if len(text): +			menu.addAction(CreateAction('Copy "' + text + '"', "Copy to clipboard", lambda: QApplication.clipboard().setText(text), self.view)) +		self.AddCopy(menu) +  # Table window  class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase): @@ -2279,9 +2524,13 @@ class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):  		self.view.verticalHeader().setVisible(False)  		self.view.sortByColumn(-1, Qt.AscendingOrder)  		self.view.setSortingEnabled(True) +		self.view.setSelectionMode(QAbstractItemView.ContiguousSelection) +		self.view.CopyCellsToClipboard = CopyTableCellsToClipboard  		self.ResizeColumnsToContents() +		self.context_menu = ContextMenu(self.view) +  		self.find_bar = FindBar(self, self, True)  		self.finder = ChildDataItemFinder(self.data_model) @@ -2395,6 +2644,10 @@ class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase):  		self.view.setModel(self.model)  		self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)  		self.view.verticalHeader().setVisible(False) +		self.view.setSelectionMode(QAbstractItemView.ContiguousSelection) +		self.view.CopyCellsToClipboard = CopyTableCellsToClipboard + +		self.context_menu = ContextMenu(self.view)  		self.ResizeColumnsToContents() @@ -2660,6 +2913,60 @@ class HelpOnlyWindow(QMainWindow):  		self.setCentralWidget(self.text) +# PostqreSQL server version + +def PostqreSQLServerVersion(db): +	query = QSqlQuery(db) +	QueryExec(query, "SELECT VERSION()") +	if query.next(): +		v_str = query.value(0) +		v_list = v_str.strip().split(" ") +		if v_list[0] == "PostgreSQL" and v_list[2] == "on": +			return v_list[1] +		return v_str +	return "Unknown" + +# SQLite version + +def SQLiteVersion(db): +	query = QSqlQuery(db) +	QueryExec(query, "SELECT sqlite_version()") +	if query.next(): +		return query.value(0) +	return "Unknown" + +# About dialog + +class AboutDialog(QDialog): + +	def __init__(self, glb, parent=None): +		super(AboutDialog, self).__init__(parent) + +		self.setWindowTitle("About Exported SQL Viewer") +		self.setMinimumWidth(300) + +		pyside_version = "1" if pyside_version_1 else "2" + +		text = "<pre>" +		text += "Python version:     " + sys.version.split(" ")[0] + "\n" +		text += "PySide version:     " + pyside_version + "\n" +		text += "Qt version:         " + qVersion() + "\n" +		if glb.dbref.is_sqlite3: +			text += "SQLite version:     " + SQLiteVersion(glb.db) + "\n" +		else: +			text += "PostqreSQL version: " + PostqreSQLServerVersion(glb.db) + "\n" +		text += "</pre>" + +		self.text = QTextBrowser() +		self.text.setHtml(text) +		self.text.setReadOnly(True) +		self.text.setOpenExternalLinks(True) + +		self.vbox = QVBoxLayout() +		self.vbox.addWidget(self.text) + +		self.setLayout(self.vbox); +  # Font resize  def ResizeFont(widget, diff): @@ -2732,6 +3039,8 @@ class MainWindow(QMainWindow):  		file_menu.addAction(CreateExitAction(glb.app, self))  		edit_menu = menu.addMenu("&Edit") +		edit_menu.addAction(CreateAction("&Copy", "Copy to clipboard", self.CopyToClipboard, self, QKeySequence.Copy)) +		edit_menu.addAction(CreateAction("Copy as CS&V", "Copy to clipboard as CSV", self.CopyToClipboardCSV, self))  		edit_menu.addAction(CreateAction("&Find...", "Find items", self.Find, self, QKeySequence.Find))  		edit_menu.addAction(CreateAction("Fetch &more records...", "Fetch more records", self.FetchMoreRecords, self, [QKeySequence(Qt.Key_F8)]))  		edit_menu.addAction(CreateAction("&Shrink Font", "Make text smaller", self.ShrinkFont, self, [QKeySequence("Ctrl+-")])) @@ -2755,6 +3064,21 @@ class MainWindow(QMainWindow):  		help_menu = menu.addMenu("&Help")  		help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents)) +		help_menu.addAction(CreateAction("&About Exported SQL Viewer", "About this application", self.About, self)) + +	def Try(self, fn): +		win = self.mdi_area.activeSubWindow() +		if win: +			try: +				fn(win.view) +			except: +				pass + +	def CopyToClipboard(self): +		self.Try(CopyCellsToClipboardHdr) + +	def CopyToClipboardCSV(self): +		self.Try(CopyCellsToClipboardCSV)  	def Find(self):  		win = self.mdi_area.activeSubWindow() @@ -2773,12 +3097,10 @@ class MainWindow(QMainWindow):  				pass  	def ShrinkFont(self): -		win = self.mdi_area.activeSubWindow() -		ShrinkFont(win.view) +		self.Try(ShrinkFont)  	def EnlargeFont(self): -		win = self.mdi_area.activeSubWindow() -		EnlargeFont(win.view) +		self.Try(EnlargeFont)  	def EventMenu(self, events, reports_menu):  		branches_events = 0 @@ -2828,6 +3150,10 @@ class MainWindow(QMainWindow):  	def Help(self):  		HelpWindow(self.glb, self) +	def About(self): +		dialog = AboutDialog(self.glb, self) +		dialog.exec_() +  # XED Disassembler  class xed_state_t(Structure): | 
