3073 lines · 96.5 KB · Python
RawDownload
		self.partial = partial 		self.grid = QGridLayout() 		for row in xrange(len(self.data_items)):			self.grid.addWidget(QLabel(self.data_items[row].label), row, 0)			self.grid.addWidget(self.data_items[row].widget, row, 1) 		self.status = QLabel() 		self.ok_button = QPushButton("Ok", self)		self.ok_button.setDefault(True)		self.ok_button.released.connect(self.Ok)		self.ok_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) 		self.cancel_button = QPushButton("Cancel", self)		self.cancel_button.released.connect(self.reject)		self.cancel_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) 		self.hbox = QHBoxLayout()		#self.hbox.addStretch()		self.hbox.addWidget(self.status)		self.hbox.addWidget(self.ok_button)		self.hbox.addWidget(self.cancel_button) 		self.vbox = QVBoxLayout()		self.vbox.addLayout(self.grid)		self.vbox.addLayout(self.hbox) 		self.setLayout(self.vbox); 	def Ok(self):		vars = self.report_vars		for d in self.data_items:			if d.id == "REPORTNAME":				vars.name = d.value		if not vars.name:			self.ShowMessage("Report name is required")			return		for d in self.data_items:			if not d.IsValid():				return		for d in self.data_items[1:]:			if d.id == "LIMIT":				vars.limit = d.value			elif len(d.value):				if len(vars.where_clause):					vars.where_clause += " AND "				vars.where_clause += d.value		if len(vars.where_clause):			if self.partial:				vars.where_clause = " AND ( " + vars.where_clause + " ) "			else:				vars.where_clause = " WHERE " + vars.where_clause + " "		self.accept() 	def ShowMessage(self, msg):		self.status.setText("<font color=#FF0000>" + msg) 	def ClearMessage(self):		self.status.setText("") # Selected branch report creation dialog class SelectedBranchDialog(ReportDialogBase): 	def __init__(self, glb, parent=None):		title = "Selected Branches"		items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"),			 lambda g, p: SampleTimeRangesDataItem(g, "Time ranges:", "Enter time ranges", "samples.id", p),			 lambda g, p: NonNegativeIntegerRangesDataItem(g, "CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "cpu", p),			 lambda g, p: SQLTableDataItem(g, "Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", "", p),			 lambda g, p: SQLTableDataItem(g, "PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", "", p),			 lambda g, p: SQLTableDataItem(g, "TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", "", p),			 lambda g, p: SQLTableDataItem(g, "DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id", p),			 lambda g, p: SQLTableDataItem(g, "Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id", p),			 lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p))		super(SelectedBranchDialog, self).__init__(glb, title, items, True, parent) # Event list def GetEventList(db):	events = []	query = QSqlQuery(db)	QueryExec(query, "SELECT name FROM selected_events WHERE id > 0 ORDER BY id")	while query.next():		events.append(query.value(0))	return events # Is a table selectable def IsSelectable(db, table, sql = ""):	query = QSqlQuery(db)	try:		QueryExec(query, "SELECT * FROM " + table + " " + sql + " LIMIT 1")	except:		return False	return True # SQL table data model item class SQLTableItem(): 	def __init__(self, row, data):		self.row = row		self.data = data 	def getData(self, column):		return self.data[column] # SQL table data model class SQLTableModel(TableModel): 	progress = Signal(object) 	def __init__(self, glb, sql, column_headers, parent=None):		super(SQLTableModel, self).__init__(parent)		self.glb = glb		self.more = True		self.populated = 0		self.column_headers = column_headers		self.fetcher = SQLFetcher(glb, sql, lambda x, y=len(column_headers): self.SQLTableDataPrep(x, y), self.AddSample)		self.fetcher.done.connect(self.Update)		self.fetcher.Fetch(glb_chunk_sz) 	def DisplayData(self, item, index):		self.FetchIfNeeded(item.row)		return item.getData(index.column()) 	def AddSample(self, data):		child = SQLTableItem(self.populated, data)		self.child_items.append(child)		self.populated += 1 	def Update(self, fetched):		if not fetched:			self.more = False			self.progress.emit(0)		child_count = self.child_count		count = self.populated - child_count		if count > 0:			parent = QModelIndex()			self.beginInsertRows(parent, child_count, child_count + count - 1)			self.insertRows(child_count, count, parent)			self.child_count += count			self.endInsertRows()			self.progress.emit(self.child_count) 	def FetchMoreRecords(self, count):		current = self.child_count		if self.more:			self.fetcher.Fetch(count)		else:			self.progress.emit(0)		return current 	def HasMoreRecords(self):		return self.more 	def columnCount(self, parent=None):		return len(self.column_headers) 	def columnHeader(self, column):		return self.column_headers[column] 	def SQLTableDataPrep(self, query, count):		data = []		for i in xrange(count):			data.append(query.value(i))		return data # SQL automatic table data model class SQLAutoTableModel(SQLTableModel): 	def __init__(self, glb, table_name, parent=None):		sql = "SELECT * FROM " + table_name + " WHERE id > $$last_id$$ ORDER BY id LIMIT " + str(glb_chunk_sz)		if table_name == "comm_threads_view":			# For now, comm_threads_view has no id column			sql = "SELECT * FROM " + table_name + " WHERE comm_id > $$last_id$$ ORDER BY comm_id LIMIT " + str(glb_chunk_sz)		column_headers = []		query = QSqlQuery(glb.db)		if glb.dbref.is_sqlite3:			QueryExec(query, "PRAGMA table_info(" + table_name + ")")			while query.next():				column_headers.append(query.value(1))			if table_name == "sqlite_master":				sql = "SELECT * FROM " + table_name		else:			if table_name[:19] == "information_schema.":				sql = "SELECT * FROM " + table_name				select_table_name = table_name[19:]				schema = "information_schema"			else:				select_table_name = table_name				schema = "public"			QueryExec(query, "SELECT column_name FROM information_schema.columns WHERE table_schema = '" + schema + "' and table_name = '" + select_table_name + "'")			while query.next():				column_headers.append(query.value(0))		if pyside_version_1 and sys.version_info[0] == 3:			if table_name == "samples_view":				self.SQLTableDataPrep = self.samples_view_DataPrep			if table_name == "samples":				self.SQLTableDataPrep = self.samples_DataPrep		super(SQLAutoTableModel, self).__init__(glb, sql, column_headers, parent) 	def samples_view_DataPrep(self, query, count):		data = []		data.append(query.value(0))		# Workaround pyside failing to handle large integers (i.e. time) in python3 by converting to a string		data.append("{:>19}".format(query.value(1)))		for i in xrange(2, count):			data.append(query.value(i))		return data 	def samples_DataPrep(self, query, count):		data = []		for i in xrange(9):			data.append(query.value(i))		# Workaround pyside failing to handle large integers (i.e. time) in python3 by converting to a string		data.append("{:>19}".format(query.value(9)))		for i in xrange(10, count):			data.append(query.value(i))		return data # Base class for custom ResizeColumnsToContents class ResizeColumnsToContentsBase(QObject): 	def __init__(self, parent=None):		super(ResizeColumnsToContentsBase, self).__init__(parent) 	def ResizeColumnToContents(self, column, n):		# Using the view's resizeColumnToContents() here is extrememly slow		# so implement a crude alternative		font = self.view.font()		metrics = QFontMetrics(font)		max = 0		for row in xrange(n):			val = self.data_model.child_items[row].data[column]			len = metrics.width(str(val) + "MM")			max = len if len > max else max		val = self.data_model.columnHeader(column)		len = metrics.width(str(val) + "MM")		max = len if len > max else max		self.view.setColumnWidth(column, max) 	def ResizeColumnsToContents(self):		n = min(self.data_model.child_count, 100)		if n < 1:			# No data yet, so connect a signal to notify when there is			self.data_model.rowsInserted.connect(self.UpdateColumnWidths)			return		columns = self.data_model.columnCount()		for i in xrange(columns):			self.ResizeColumnToContents(i, n) 	def UpdateColumnWidths(self, *x):		# This only needs to be done once, so disconnect the signal now		self.data_model.rowsInserted.disconnect(self.UpdateColumnWidths)		self.ResizeColumnsToContents() # Table window class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase): 	def __init__(self, glb, table_name, parent=None):		super(TableWindow, self).__init__(parent) 		self.data_model = LookupCreateModel(table_name + " Table", lambda: SQLAutoTableModel(glb, table_name)) 		self.model = QSortFilterProxyModel()		self.model.setSourceModel(self.data_model) 		self.view = QTableView()		self.view.setModel(self.model)		self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)		self.view.verticalHeader().setVisible(False)		self.view.sortByColumn(-1, Qt.AscendingOrder)		self.view.setSortingEnabled(True) 		self.ResizeColumnsToContents() 		self.find_bar = FindBar(self, self, True) 		self.finder = ChildDataItemFinder(self.data_model) 		self.fetch_bar = FetchMoreRecordsBar(self.data_model, self) 		self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget()) 		self.setWidget(self.vbox.Widget()) 		AddSubWindow(glb.mainwindow.mdi_area, self, table_name + " Table") 	def Find(self, value, direction, pattern, context):		self.view.setFocus()		self.find_bar.Busy()		self.finder.Find(value, direction, pattern, context, self.FindDone) 	def FindDone(self, row):		self.find_bar.Idle()		if row >= 0:			self.view.setCurrentIndex(self.model.mapFromSource(self.data_model.index(row, 0, QModelIndex())))		else:			self.find_bar.NotFound() # Table list def GetTableList(glb):	tables = []	query = QSqlQuery(glb.db)	if glb.dbref.is_sqlite3:		QueryExec(query, "SELECT name FROM sqlite_master WHERE type IN ( 'table' , 'view' ) ORDER BY name")	else:		QueryExec(query, "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type IN ( 'BASE TABLE' , 'VIEW' ) ORDER BY table_name")	while query.next():		tables.append(query.value(0))	if glb.dbref.is_sqlite3:		tables.append("sqlite_master")	else:		tables.append("information_schema.tables")		tables.append("information_schema.views")		tables.append("information_schema.columns")	return tables # Top Calls data model class TopCallsModel(SQLTableModel): 	def __init__(self, glb, report_vars, parent=None):		text = ""		if not glb.dbref.is_sqlite3:			text = "::text"		limit = ""		if len(report_vars.limit):			limit = " LIMIT " + report_vars.limit		sql = ("SELECT comm, pid, tid, name,"			" CASE"			" WHEN (short_name = '[kernel.kallsyms]') THEN '[kernel]'" + text +			" ELSE short_name"			" END AS dso,"			" call_time, return_time, (return_time - call_time) AS elapsed_time, branch_count, "			" CASE"			" WHEN (calls.flags = 1) THEN 'no call'" + text +			" WHEN (calls.flags = 2) THEN 'no return'" + text +			" WHEN (calls.flags = 3) THEN 'no call/return'" + text +			" ELSE ''" + text +			" END AS flags"			" FROM calls"			" INNER JOIN call_paths ON calls.call_path_id = call_paths.id"			" INNER JOIN symbols ON call_paths.symbol_id = symbols.id"			" INNER JOIN dsos ON symbols.dso_id = dsos.id"			" INNER JOIN comms ON calls.comm_id = comms.id"			" INNER JOIN threads ON calls.thread_id = threads.id" +			report_vars.where_clause +			" ORDER BY elapsed_time DESC" +			limit			)		column_headers = ("Command", "PID", "TID", "Symbol", "Object", "Call Time", "Return Time", "Elapsed Time (ns)", "Branch Count", "Flags")		self.alignment = (Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignLeft)		super(TopCallsModel, self).__init__(glb, sql, column_headers, parent) 	def columnAlignment(self, column):		return self.alignment[column] # Top Calls report creation dialog class TopCallsDialog(ReportDialogBase): 	def __init__(self, glb, parent=None):		title = "Top Calls by Elapsed Time"		items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"),			 lambda g, p: SQLTableDataItem(g, "Commands:", "Only calls with these commands will be included", "comms", "comm", "comm_id", "", p),			 lambda g, p: SQLTableDataItem(g, "PIDs:", "Only calls with these process IDs will be included", "threads", "pid", "thread_id", "", p),			 lambda g, p: SQLTableDataItem(g, "TIDs:", "Only calls with these thread IDs will be included", "threads", "tid", "thread_id", "", p),			 lambda g, p: SQLTableDataItem(g, "DSOs:", "Only calls with these DSOs will be included", "dsos", "short_name", "dso_id", "", p),			 lambda g, p: SQLTableDataItem(g, "Symbols:", "Only calls with these symbols will be included", "symbols", "name", "symbol_id", "", p),			 lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p),			 lambda g, p: PositiveIntegerDataItem(g, "Record limit:", "Limit selection to this number of records", p, "LIMIT", "100"))		super(TopCallsDialog, self).__init__(glb, title, items, False, parent) # Top Calls window class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase): 	def __init__(self, glb, report_vars, parent=None):		super(TopCallsWindow, self).__init__(parent) 		self.data_model = LookupCreateModel("Top Calls " + report_vars.UniqueId(), lambda: TopCallsModel(glb, report_vars))		self.model = self.data_model 		self.view = QTableView()		self.view.setModel(self.model)		self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)		self.view.verticalHeader().setVisible(False) 		self.ResizeColumnsToContents() 		self.find_bar = FindBar(self, self, True) 		self.finder = ChildDataItemFinder(self.model) 		self.fetch_bar = FetchMoreRecordsBar(self.data_model, self) 		self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget()) 		self.setWidget(self.vbox.Widget()) 		AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name) 	def Find(self, value, direction, pattern, context):		self.view.setFocus()		self.find_bar.Busy()		self.finder.Find(value, direction, pattern, context, self.FindDone) 	def FindDone(self, row):		self.find_bar.Idle()		if row >= 0:			self.view.setCurrentIndex(self.model.index(row, 0, QModelIndex()))		else:			self.find_bar.NotFound() # Action Definition def CreateAction(label, tip, callback, parent=None, shortcut=None):	action = QAction(label, parent)	if shortcut != None:		action.setShortcuts(shortcut)	action.setStatusTip(tip)	action.triggered.connect(callback)	return action # Typical application actions def CreateExitAction(app, parent=None):	return CreateAction("&Quit", "Exit the application", app.closeAllWindows, parent, QKeySequence.Quit) # Typical MDI actions def CreateCloseActiveWindowAction(mdi_area):	return CreateAction("Cl&ose", "Close the active window", mdi_area.closeActiveSubWindow, mdi_area) def CreateCloseAllWindowsAction(mdi_area):	return CreateAction("Close &All", "Close all the windows", mdi_area.closeAllSubWindows, mdi_area) def CreateTileWindowsAction(mdi_area):	return CreateAction("&Tile", "Tile the windows", mdi_area.tileSubWindows, mdi_area) def CreateCascadeWindowsAction(mdi_area):	return CreateAction("&Cascade", "Cascade the windows", mdi_area.cascadeSubWindows, mdi_area) def CreateNextWindowAction(mdi_area):	return CreateAction("Ne&xt", "Move the focus to the next window", mdi_area.activateNextSubWindow, mdi_area, QKeySequence.NextChild) def CreatePreviousWindowAction(mdi_area):	return CreateAction("Pre&vious", "Move the focus to the previous window", mdi_area.activatePreviousSubWindow, mdi_area, QKeySequence.PreviousChild) # Typical MDI window menu class WindowMenu(): 	def __init__(self, mdi_area, menu):		self.mdi_area = mdi_area		self.window_menu = menu.addMenu("&Windows")		self.close_active_window = CreateCloseActiveWindowAction(mdi_area)		self.close_all_windows = CreateCloseAllWindowsAction(mdi_area)		self.tile_windows = CreateTileWindowsAction(mdi_area)		self.cascade_windows = CreateCascadeWindowsAction(mdi_area)		self.next_window = CreateNextWindowAction(mdi_area)		self.previous_window = CreatePreviousWindowAction(mdi_area)		self.window_menu.aboutToShow.connect(self.Update) 	def Update(self):		self.window_menu.clear()		sub_window_count = len(self.mdi_area.subWindowList())		have_sub_windows = sub_window_count != 0		self.close_active_window.setEnabled(have_sub_windows)		self.close_all_windows.setEnabled(have_sub_windows)		self.tile_windows.setEnabled(have_sub_windows)		self.cascade_windows.setEnabled(have_sub_windows)		self.next_window.setEnabled(have_sub_windows)		self.previous_window.setEnabled(have_sub_windows)		self.window_menu.addAction(self.close_active_window)		self.window_menu.addAction(self.close_all_windows)		self.window_menu.addSeparator()		self.window_menu.addAction(self.tile_windows)		self.window_menu.addAction(self.cascade_windows)		self.window_menu.addSeparator()		self.window_menu.addAction(self.next_window)		self.window_menu.addAction(self.previous_window)		if sub_window_count == 0:			return		self.window_menu.addSeparator()		nr = 1		for sub_window in self.mdi_area.subWindowList():			label = str(nr) + " " + sub_window.name			if nr < 10:				label = "&" + label

Lines 2001–2500 of 3073. Previous lines

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t