#!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0
# exported-sql-viewer.py: view data from sql database
# Copyright (c) 2014-2018, Intel Corporation.

# To use this script you will need to have exported data using either the
# export-to-sqlite.py or the export-to-postgresql.py script.  Refer to those
# scripts for details.
#
# Following on from the example in the export scripts, a
# call-graph can be displayed for the pt_example database like this:
#
#	python tools/perf/scripts/python/exported-sql-viewer.py pt_example
#
# Note that for PostgreSQL, this script supports connecting to remote databases
# by setting hostname, port, username, password, and dbname e.g.
#
#	python tools/perf/scripts/python/exported-sql-viewer.py "hostname=myhost username=myuser password=mypassword dbname=pt_example"
#
# The result is a GUI window with a tree representing a context-sensitive
# call-graph.  Expanding a couple of levels of the tree and adjusting column
# widths to suit will display something like:
#
#                                         Call Graph: pt_example
# Call Path                          Object      Count   Time(ns)  Time(%)  Branch Count   Branch Count(%)
# v- ls
#     v- 2638:2638
#         v- _start                  ld-2.19.so    1     10074071   100.0         211135            100.0
#           |- unknown               unknown       1        13198     0.1              1              0.0
#           >- _dl_start             ld-2.19.so    1      1400980    13.9          19637              9.3
#           >- _d_linit_internal     ld-2.19.so    1       448152     4.4          11094              5.3
#           v-__libc_start_main@plt  ls            1      8211741    81.5         180397             85.4
#              >- _dl_fixup          ld-2.19.so    1         7607     0.1            108              0.1
#              >- __cxa_atexit       libc-2.19.so  1        11737     0.1             10              0.0
#              >- __libc_csu_init    ls            1        10354     0.1             10              0.0
#              |- _setjmp            libc-2.19.so  1            0     0.0              4              0.0
#              v- main               ls            1      8182043    99.6         180254             99.9
#
# Points to note:
#	The top level is a command name (comm)
#	The next level is a thread (pid:tid)
#	Subsequent levels are functions
#	'Count' is the number of calls
#	'Time' is the elapsed time until the function returns
#	Percentages are relative to the level above
#	'Branch Count' is the total number of branches for that function and all
#       functions that it calls

# There is also a "All branches" report, which displays branches and
# possibly disassembly.  However, presently, the only supported disassembler is
# Intel XED, and additionally the object code must be present in perf build ID
# cache. To use Intel XED, libxed.so must be present. To build and install
# libxed.so:
#            git clone https://github.com/intelxed/mbuild.git mbuild
#            git clone https://github.com/intelxed/xed
#            cd xed
#            ./mfile.py --share
#            sudo ./mfile.py --prefix=/usr/local install
#            sudo ldconfig
#
# Example report:
#
# Time           CPU  Command  PID    TID    Branch Type            In Tx  Branch
# 8107675239590  2    ls       22011  22011  return from interrupt  No     ffffffff86a00a67 native_irq_return_iret ([kernel]) -> 7fab593ea260 _start (ld-2.19.so)
#                                                                              7fab593ea260 48 89 e7                                        mov %rsp, %rdi
# 8107675239899  2    ls       22011  22011  hardware interrupt     No         7fab593ea260 _start (ld-2.19.so) -> ffffffff86a012e0 page_fault ([kernel])
# 8107675241900  2    ls       22011  22011  return from interrupt  No     ffffffff86a00a67 native_irq_return_iret ([kernel]) -> 7fab593ea260 _start (ld-2.19.so)
#                                                                              7fab593ea260 48 89 e7                                        mov %rsp, %rdi
#                                                                              7fab593ea263 e8 c8 06 00 00                                  callq  0x7fab593ea930
# 8107675241900  2    ls       22011  22011  call                   No         7fab593ea263 _start+0x3 (ld-2.19.so) -> 7fab593ea930 _dl_start (ld-2.19.so)
#                                                                              7fab593ea930 55                                              pushq  %rbp
#                                                                              7fab593ea931 48 89 e5                                        mov %rsp, %rbp
#                                                                              7fab593ea934 41 57                                           pushq  %r15
#                                                                              7fab593ea936 41 56                                           pushq  %r14
#                                                                              7fab593ea938 41 55                                           pushq  %r13
#                                                                              7fab593ea93a 41 54                                           pushq  %r12
#                                                                              7fab593ea93c 53                                              pushq  %rbx
#                                                                              7fab593ea93d 48 89 fb                                        mov %rdi, %rbx
#                                                                              7fab593ea940 48 83 ec 68                                     sub $0x68, %rsp
#                                                                              7fab593ea944 0f 31                                           rdtsc
#                                                                              7fab593ea946 48 c1 e2 20                                     shl $0x20, %rdx
#                                                                              7fab593ea94a 89 c0                                           mov %eax, %eax
#                                                                              7fab593ea94c 48 09 c2                                        or %rax, %rdx
#                                                                              7fab593ea94f 48 8b 05 1a 15 22 00                            movq  0x22151a(%rip), %rax
# 8107675242232  2    ls       22011  22011  hardware interrupt     No         7fab593ea94f _dl_start+0x1f (ld-2.19.so) -> ffffffff86a012e0 page_fault ([kernel])
# 8107675242900  2    ls       22011  22011  return from interrupt  No     ffffffff86a00a67 native_irq_return_iret ([kernel]) -> 7fab593ea94f _dl_start+0x1f (ld-2.19.so)
#                                                                              7fab593ea94f 48 8b 05 1a 15 22 00                            movq  0x22151a(%rip), %rax
#                                                                              7fab593ea956 48 89 15 3b 13 22 00                            movq  %rdx, 0x22133b(%rip)
# 8107675243232  2    ls       22011  22011  hardware interrupt     No         7fab593ea956 _dl_start+0x26 (ld-2.19.so) -> ffffffff86a012e0 page_fault ([kernel])

from __future__ import print_function

import sys
# Only change warnings if the python -W option was not used
if not sys.warnoptions:
	import warnings
	# PySide2 causes deprecation warnings, ignore them.
	warnings.filterwarnings("ignore", category=DeprecationWarning)
import argparse
import weakref
import threading
import string
try:
	# Python2
	import cPickle as pickle
	# size of pickled integer big enough for record size
	glb_nsz = 8
except ImportError:
	import pickle
	glb_nsz = 16
import re
import os
import random
import copy
import math

pyside_version_1 = True
if not "--pyside-version-1" in sys.argv:
	try:
		from PySide2.QtCore import *
		from PySide2.QtGui import *
		from PySide2.QtSql import *
		from PySide2.QtWidgets import *
		pyside_version_1 = False
	except:
		pass

if pyside_version_1:
	from PySide.QtCore import *
	from PySide.QtGui import *
	from PySide.QtSql import *

from decimal import Decimal, ROUND_HALF_UP
from ctypes import CDLL, Structure, create_string_buffer, addressof, sizeof, \
		   c_void_p, c_bool, c_byte, c_char, c_int, c_uint, c_longlong, c_ulonglong
from multiprocessing import Process, Array, Value, Event

# xrange is range in Python3
try:
	xrange
except NameError:
	xrange = range

def printerr(*args, **keyword_args):
	print(*args, file=sys.stderr, **keyword_args)

# Data formatting helpers

def tohex(ip):
	if ip < 0:
		ip += 1 << 64
	return "%x" % ip

def offstr(offset):
	if offset:
		return "+0x%x" % offset
	return ""

def dsoname(name):
	if name == "[kernel.kallsyms]":
		return "[kernel]"
	return name

def findnth(s, sub, n, offs=0):
	pos = s.find(sub)
	if pos < 0:
		return pos
	if n <= 1:
		return offs + pos
	return findnth(s[pos + 1:], sub, n - 1, offs + pos + 1)

# Percent to one decimal place

def PercentToOneDP(n, d):
	if not d:
		return "0.0"
	x = (n * Decimal(100)) / d
	return str(x.quantize(Decimal(".1"), rounding=ROUND_HALF_UP))

# Helper for queries that must not fail

def QueryExec(query, stmt):
	ret = query.exec_(stmt)
	if not ret:
		raise Exception("Query failed: " + query.lastError().text())

# Background thread

class Thread(QThread):

	done = Signal(object)

	def __init__(self, task, param=None, parent=None):
		super(Thread, self).__init__(parent)
		self.task = task
		self.param = param

	def run(self):
		while True:
			if self.param is None:
				done, result = self.task()
			else:
				done, result = self.task(self.param)
			self.done.emit(result)
			if done:
				break

# Tree data model

class TreeModel(QAbstractItemModel):

	def __init__(self, glb, params, parent=None):
		super(TreeModel, self).__init__(parent)
		self.glb = glb
		self.params = params
		self.root = self.GetRoot()
		self.last_row_read = 0

	def Item(self, parent):
		if parent.isValid():
			return parent.internalPointer()
		else:
			return self.root

	def rowCount(self, parent):
		result = self.Item(parent).childCount()
		if result < 0:
			result = 0
			self.dataChanged.emit(parent, parent)
		return result

	def hasChildren(self, parent):
		return self.Item(parent).hasChildren()

	def headerData(self, section, orientation, role):
		if role == Qt.TextAlignmentRole:
			return self.columnAlignment(section)
		if role != Qt.DisplayRole:
			return None
		if orientation != Qt.Horizontal:
			return None
		return self.columnHeader(section)

	def parent(self, child):
		child_item = child.internalPointer()
		if child_item is self.root:
			return QModelIndex()
		parent_item = child_item.getParentItem()
		return self.createIndex(parent_item.getRow(), 0, parent_item)

	def index(self, row, column, parent):
		child_item = self.Item(parent).getChildItem(row)
		return self.createIndex(row, column, child_item)

	def DisplayData(self, item, index):
		return item.getData(index.column())

	def FetchIfNeeded(self, row):
		if row > self.last_row_read:
			self.last_row_read = row
			if row + 10 >= self.root.child_count:
				self.fetcher.Fetch(glb_chunk_sz)

	def columnAlignment(self, column):
		return Qt.AlignLeft

	def columnFont(self, column):
		return None

	def data(self, index, role):
		if role == Qt.TextAlignmentRole:
			return self.columnAlignment(index.column())
		if role == Qt.FontRole:
			return self.columnFont(index.column())
		if role != Qt.DisplayRole:
			return None
		item = index.internalPointer()
		return self.DisplayData(item, index)

# Table data model

class TableModel(QAbstractTableModel):

	def __init__(self, parent=None):
		super(TableModel, self).__init__(parent)
		self.child_count = 0
		self.child_items = []
		self.last_row_read = 0

	def Item(self, parent):
		if parent.isValid():
			return parent.internalPointer()
		else:
			return self

	def rowCount(self, parent):
		return self.child_count

	def headerData(self, section, orientation, role):
		if role == Qt.TextAlignmentRole:
			return self.columnAlignment(section)
		if role != Qt.DisplayRole:
			return None
		if orientation != Qt.Horizontal:
			return None
		return self.columnHeader(section)

	def index(self, row, column, parent):
		return self.createIndex(row, column, self.child_items[row])

	def DisplayData(self, item, index):
		return item.getData(index.column())

	def FetchIfNeeded(self, row):
		if row > self.last_row_read:
			self.last_row_read = row
			if row + 10 >= self.child_count:
				self.fetcher.Fetch(glb_chunk_sz)

	def columnAlignment(self, column):
		return Qt.AlignLeft

	def columnFont(self, column):
		return None

	def data(self, index, role):
		if role == Qt.TextAlignmentRole:
			return self.columnAlignment(index.column())
		if role == Qt.FontRole:
			return self.columnFont(index.column())
		if role != Qt.DisplayRole:
			return None
		item = index.internalPointer()
		return self.DisplayData(item, index)

# Model cache

model_cache = weakref.WeakValueDictionary()
model_cache_lock = threading.Lock()

def LookupCreateModel(model_name, create_fn):
	model_cache_lock.acquire()
	try:
		model = model_cache[model_name]
	except:
		model = None
	if model is None:
		model = create_fn()
		model_cache[model_name] = model
	model_cache_lock.release()
	return model

def LookupModel(model_name):
	model_cache_lock.acquire()
	try:
		model = model_cache[model_name]
	except:
		model = None
	model_cache_lock.release()
	return model

# Find bar

class FindBar():

	def __init__(self, parent, finder, is_reg_expr=False):
		self.finder = finder
		self.context = []
		self.last_value = None
		self.last_pattern = None

		label = QLabel("Find:")
		label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

		self.textbox = QComboBox()
		self.textbox.setEditable(True)
		self.textbox.currentIndexChanged.connect(self.ValueChanged)

		self.progress = QProgressBar()
		self.progress.setRange(0, 0)
		self.progress.hide()

		if is_reg_expr:
			self.pattern = QCheckBox("Regular Expression")
		else:
			self.pattern = QCheckBox("Pattern")
		self.pattern.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

		self.next_button = QToolButton()
		self.next_button.setIcon(parent.style().standardIcon(QStyle.SP_ArrowDown))
		self.next_button.released.connect(lambda: self.NextPrev(1))

		self.prev_button = QToolButton()
		self.prev_button.setIcon(parent.style().standardIcon(QStyle.SP_ArrowUp))
		self.prev_button.released.connect(lambda: self.NextPrev(-1))

		self.close_button = QToolButton()
		self.close_button.setIcon(parent.style().standardIcon(QStyle.SP_DockWidgetCloseButton))
		self.close_button.released.connect(self.Deactivate)

		self.hbox = QHBoxLayout()
		self.hbox.setContentsMargins(0, 0, 0, 0)

		self.hbox.addWidget(label)
		self.hbox.addWidget(self.textbox)
		self.hbox.addWidget(self.progress)
		self.hbox.addWidget(self.pattern)
		self.hbox.addWidget(self.next_button)
		self.hbox.addWidget(self.prev_button)
		self.hbox.addWidget(self.close_button)

		self.bar = QWidget()
		self.bar.setLayout(self.hbox)
		self.bar.hide()

	def Widget(self):
		return self.bar

	def Activate(self):
		self.bar.show()
		self.textbox.lineEdit().selectAll()
		self.textbox.setFocus()

	def Deactivate(self):
		self.bar.hide()

	def Busy(self):
		self.textbox.setEnabled(False)
		self.pattern.hide()
		self.next_button.hide()
		self.prev_button.hide()
		self.progress.show()

	def Idle(self):
		self.textbox.setEnabled(True)
		self.progress.hide()
		self.pattern.show()
		self.next_button.show()
		self.prev_button.show()

	def Find(self, direction):
		value = self.textbox.currentText()
		pattern = self.pattern.isChecked()
		self.last_value = value
		self.last_pattern = pattern
		self.finder.Find(value, direction, pattern, self.context)

	def ValueChanged(self):
		value = self.textbox.currentText()
		pattern = self.pattern.isChecked()
		index = self.textbox.currentIndex()
		data = self.textbox.itemData(index)
		# Store the pattern in the combo box to keep it with the text value
		if data == None:
			self.textbox.setItemData(index, pattern)
		else:
			self.pattern.setChecked(data)
		self.Find(0)

	def NextPrev(self, direction):
		value = self.textbox.currentText()
		pattern = self.pattern.isChecked()
		if value != self.last_value:
			index = self.textbox.findText(value)
			# Allow for a button press before the value has been added to the combo box
			if index < 0:
				index = self.textbox.count()
				self.textbox.addItem(value, pattern)
				self.textbox.setCurrentIndex(index)
				return
			else:
				self.textbox.setItemData(index, pattern)
		elif pattern != self.last_pattern:
			# Keep the pattern recorded in the combo box up to date
			index = self.textbox.currentIndex()
			self.textbox.setItemData(index, pattern)
		self.Find(direction)

	def NotFound(self):
		QMessageBox.information(self.bar, "Find", "'" + self.textbox.currentText() + "' not found")

# Context-sensitive call graph data model item base

class CallGraphLevelItemBase(object):

	def __init__(self, glb, params, row, parent_item):
		self.glb = glb
		self.params = params
		self.row = row
		self.parent_item = parent_item
		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]

	def getParentItem(self):
		return self.parent_item

	def getRow(self):
		return self.row

	def childCount(self):
		if not self.query_done:
			self.Select()
			if not self.child_count:
				return -1
		return self.child_count

	def hasChildren(self):
		if not self.query_done:
			return True
		return self.child_count > 0

	def getData(self, column):
		return self.data[column]

# Context-sensitive call graph data model level 2+ item base

class CallGraphLevelTwoPlusItemBase(CallGraphLevelItemBase):

	def __init__(self, glb, params, row, comm_id, thread_id, call_path_id, time, insn_cnt, cyc_cnt, branch_count, parent_item):
		super(CallGraphLevelTwoPlusItemBase, self).__init__(glb, params, row, parent_item)
		self.comm_id = comm_id
		self.thread_id = thread_id
		self.call_path_id = call_path_id
		self.insn_cnt = insn_cnt
		self.cyc_cnt = cyc_cnt
		self.branch_count = branch_count
		self.time = time

	def Select(self):
		self.query_done = True
		query = QSqlQuery(self.glb.db)
		if self.params.have_ipc:
			ipc_str = ", SUM(insn_count), SUM(cyc_count)"
		else:
			ipc_str = ""
		QueryExec(query, "SELECT call_path_id, name, short_name, COUNT(calls.id), SUM(return_time - call_time)" + ipc_str + ", SUM(branch_count)"
					" 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"
					" WHERE parent_call_path_id = " + str(self.call_path_id) +
					" AND comm_id = " + str(self.comm_id) +
					" AND thread_id = " + str(self.thread_id) +
					" GROUP BY call_path_id, name, short_name"
					" ORDER BY call_path_id")
		while query.next():
			if self.params.have_ipc:
				insn_cnt = int(query.value(5))
				cyc_cnt = int(query.value(6))
				branch_count = int(query.value(7))
			else:
				insn_cnt = 0
				cyc_cnt = 0
				branch_count = int(query.value(5))
			child_item = CallGraphLevelThreeItem(self.glb, self.params, self.child_count, self.comm_id, self.thread_id, query.value(0), query.value(1), query.value(2), query.value(3), int(query.value(4)), insn_cnt, cyc_cnt, branch_count, self)
			self.child_items.append(child_item)
			self.child_count += 1

# Context-sensitive call graph data model level three item

class CallGraphLevelThreeItem(CallGraphLevelTwoPlusItemBase):

	def __init__(self, glb, params, row, comm_id, thread_id, call_path_id, name, dso, count, time, insn_cnt, cyc_cnt, branch_count, parent_item):
		super(CallGraphLevelThreeItem, self).__init__(glb, params, row, comm_id, thread_id, call_path_id, time, insn_cnt, cyc_cnt, branch_count, parent_item)
		dso = dsoname(dso)
		if self.params.have_ipc:
			insn_pcnt = PercentToOneDP(insn_cnt, parent_item.insn_cnt)
			cyc_pcnt = PercentToOneDP(cyc_cnt, parent_item.cyc_cnt)
			br_pcnt = PercentToOneDP(branch_count, parent_item.branch_count)
			ipc = CalcIPC(cyc_cnt, insn_cnt)
			self.data = [ name, dso, str(count), str(time), PercentToOneDP(time, parent_item.time), str(insn_cnt), insn_pcnt, str(cyc_cnt), cyc_pcnt, ipc, str(branch_count), br_pcnt ]
		else:
			self.data = [ name, dso, str(count), str(time), PercentToOneDP(time, parent_item.time), str(branch_count), PercentToOneDP(branch_count, parent_item.branch_count) ]
		self.dbid = call_path_id

# Context-sensitive call graph data model level two item

class CallGraphLevelTwoItem(CallGraphLevelTwoPlusItemBase):

	def __init__(self, glb, params, row, comm_id, thread_id, pid, tid, parent_item):
		super(CallGraphLevelTwoItem, self).__init__(glb, params, row, comm_id, thread_id, 1, 0, 0, 0, 0, parent_item)
		if self.params.have_ipc:
			self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", "", "", "", "", "", ""]
		else:
			self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", ""]
		self.dbid = thread_id

	def Select(self):
		super(CallGraphLevelTwoItem, self).Select()
		for child_item in self.child_items:
			self.time += child_item.time
			self.insn_cnt += child_item.insn_cnt
			self.cyc_cnt += child_item.cyc_cnt
			self.branch_count += child_item.branch_count
		for child_item in self.child_items:
			child_item.data[4] = PercentToOneDP(child_item.time, self.time)
			if self.params.have_ipc:
				child_item.data[6] = PercentToOneDP(child_item.insn_cnt, self.insn_cnt)
				child_item.data[8] = PercentToOneDP(child_item.cyc_cnt, self.cyc_cnt)
				child_item.data[11] = PercentToOneDP(child_item.branch_count, self.branch_count)
			else:
				child_item.data[6] = PercentToOneDP(child_item.branch_count, self.branch_count)

# Context-sensitive call graph data model level one item

class CallGraphLevelOneItem(CallGraphLevelItemBase):

	def __init__(self, glb, params, row, comm_id, comm, parent_item):
		super(CallGraphLevelOneItem, self).__init__(glb, params, row, parent_item)
		if self.params.have_ipc:
			self.data = [comm, "", "", "", "", "", "", "", "", "", "", ""]
		else:
			self.data = [comm, "", "", "", "", "", ""]
		self.dbid = comm_id

	def Select(self):
		self.query_done = True
		query = QSqlQuery(self.glb.db)
		QueryExec(query, "SELECT thread_id, pid, tid"
					" FROM comm_threads"
					" INNER JOIN threads ON thread_id = threads.id"
					" WHERE comm_id = " + str(self.dbid))
		while query.next():
			child_item = CallGraphLevelTwoItem(self.glb, self.params, self.child_count, self.dbid, query.value(0), query.value(1), query.value(2), self)
			self.child_items.append(child_item)
			self.child_count += 1

# Context-sensitive call graph data model root item

class CallGraphRootItem(CallGraphLevelItemBase):

	def __init__(self, glb, params):
		super(CallGraphRootItem, self).__init__(glb, params, 0, None)
		self.dbid = 0
		self.query_done = True
		if_has_calls = ""
		if IsSelectable(glb.db, "comms", columns = "has_calls"):
			if_has_calls = " WHERE has_calls = " + glb.dbref.TRUE
		query = QSqlQuery(glb.db)
		QueryExec(query, "SELECT id, comm FROM comms" + if_has_calls)
		while query.next():
			if not query.value(0):
				continue
			child_item = CallGraphLevelOneItem(glb, params, self.child_count, query.value(0), query.value(1), self)
			self.child_items.append(child_item)
			self.child_count += 1

# Call graph model parameters

class CallGraphModelParams():

	def __init__(self, glb, parent=None):
		self.have_ipc = IsSelectable(glb.db, "calls", columns = "insn_count, cyc_count")

# Context-sensitive call graph data model base

class CallGraphModelBase(TreeModel):

	def __init__(self, glb, parent=None):
		super(CallGraphModelBase, self).__init__(glb, CallGraphModelParams(glb), parent)

	def FindSelect(self, value, pattern, query):
		if pattern:
			# postgresql and sqlite pattern patching differences:
			#   postgresql LIKE is case sensitive but sqlite LIKE is not
			#   postgresql LIKE allows % and _ to be escaped with \ but sqlite LIKE does not
			#   postgresql supports ILIKE which is case insensitive
			#   sqlite supports GLOB (text only) which uses * and ? and is case sensitive
			if not self.glb.dbref.is_sqlite3:
				# Escape % and _
				s = value.replace("%", "\%")
				s = s.replace("_", "\_")
				# Translate * and ? into SQL LIKE pattern characters % and _
				trans = string.maketrans("*?", "%_")
				match = " LIKE '" + str(s).translate(trans) + "'"
			else:
				match = " GLOB '" + str(value) + "'"
		else:
			match = " = '" + str(value) + "'"
		self.DoFindSelect(query, match)

	def Found(self, query, found):
		if found:
			return self.FindPath(query)
		return []

	def FindValue(self, value, pattern, query, last_value, last_pattern):
		if last_value == value and pattern == last_pattern:
			found = query.first()
		else:
			self.FindSelect(value, pattern, query)
			found = query.next()
		return self.Found(query, found)

	def FindNext(self, query):
		found = query.next()
		if not found:
			found = query.first()
		return self.Found(query, found)

	def FindPrev(self, query):
		found = query.previous()
		if not found:
			found = query.last()
		return self.Found(query, found)

	def FindThread(self, c):
		if c.direction == 0 or c.value != c.last_value or c.pattern != c.last_pattern:
			ids = self.FindValue(c.value, c.pattern, c.query, c.last_value, c.last_pattern)
		elif c.direction > 0:
			ids = self.FindNext(c.query)
		else:
			ids = self.FindPrev(c.query)
		return (True, ids)

	def Find(self, value, direction, pattern, context, callback):
		class Context():
			def __init__(self, *x):
				self.value, self.direction, self.pattern, self.query, self.last_value, self.last_pattern = x
			def Update(self, *x):
				self.value, self.direction, self.pattern, self.last_value, self.last_pattern = x + (self.value, self.pattern)
		if len(context):
			context[0].Update(value, direction, pattern)
		else:
			context.append(Context(value, direction, pattern, QSqlQuery(self.glb.db), None, None))
		# Use a thread so the UI is not blocked during the SELECT
		thread = Thread(self.FindThread, context[0])
		thread.done.connect(lambda ids, t=thread, c=callback: self.FindDone(t, c, ids), Qt.QueuedConnection)
		thread.start()

	def FindDone(self, thread, callback, ids):
		callback(ids)

# Context-sensitive call graph data model

class CallGraphModel(CallGraphModelBase):

	def __init__(self, glb, parent=None):
		super(CallGraphModel, self).__init__(glb, parent)

	def GetRoot(self):
		return CallGraphRootItem(self.glb, self.params)

	def columnCount(self, parent=None):
		if self.params.have_ipc:
			return 12
		else:
			return 7

	def columnHeader(self, column):
		if self.params.have_ipc:
			headers = ["Call Path", "Object", "Count ", "Time (ns) ", "Time (%) ", "Insn Cnt", "Insn Cnt (%)", "Cyc Cnt", "Cyc Cnt (%)", "IPC", "Branch Count ", "Branch Count (%) "]
		else:
			headers = ["Call Path", "Object", "Count ", "Time (ns) ", "Time (%) ", "Branch Count ", "Branch Count (%) "]
		return headers[column]

	def columnAlignment(self, column):
		if self.params.have_ipc:
			alignment = [ Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight ]
		else:
			alignment = [ Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight ]
		return alignment[column]

	def DoFindSelect(self, query, match):
		QueryExec(query, "SELECT call_path_id, comm_id, thread_id"
						" FROM calls"
						" INNER JOIN call_paths ON calls.call_path_id = call_paths.id"
						" INNER JOIN symbols ON call_paths.symbol_id = symbols.id"
						" WHERE calls.id <> 0"
						" AND symbols.name" + match +
						" GROUP BY comm_id, thread_id, call_path_id"
						" ORDER BY comm_id, thread_id, call_path_id")

	def FindPath(self, query):
		# Turn the query result into a list of ids that the tree view can walk
		# to open the tree at the right place.
		ids = []
		parent_id = query.value(0)
		while parent_id:
			ids.insert(0, parent_id)
			q2 = QSqlQuery(self.glb.db)
			QueryExec(q2, "SELECT parent_id"
					" FROM call_paths"
					" WHERE id = " + str(parent_id))
			if not q2.next():
				break
			parent_id = q2.value(0)
		# The call path root is not used
		if ids[0] == 1:
			del ids[0]
		ids.insert(0, query.value(2))
		ids.insert(0, query.value(1))
		return ids

# Call tree data model level 2+ item base

class CallTreeLevelTwoPlusItemBase(CallGraphLevelItemBase):

	def __init__(self, glb, params, row, comm_id, thread_id, calls_id, call_time, time, insn_cnt, cyc_cnt, branch_count, parent_item):
		super(CallTreeLevelTwoPlusItemBase, self).__init__(glb, params, row, parent_item)
		self.comm_id = comm_id
		self.thread_id = thread_id
		self.calls_id = calls_id
		self.call_time = call_time
		self.time = time
		self.insn_cnt = insn_cnt
		self.cyc_cnt = cyc_cnt
		self.branch_count = branch_count

	def Select(self):
		self.query_done = True
		if self.calls_id == 0:
			comm_thread = " AND comm_id = " + str(self.comm_id) + " AND thread_id = " + str(self.thread_id)
		else:
			comm_thread = ""
		if self.params.have_ipc:
			ipc_str = ", insn_count, cyc_count"
		else:
			ipc_str = ""
		query = QSqlQuery(self.glb.db)
		QueryExec(query, "SELECT calls.id, name, short_name, call_time, return_time - call_time" + ipc_str + ", branch_count"
					" 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"
					" WHERE calls.parent_id = " + str(self.calls_id) + comm_thread +
					" ORDER BY call_time, calls.id")
		while query.next():
			if self.params.have_ipc:
				insn_cnt = int(query.value(5))
				cyc_cnt = int(query.value(6))
				branch_count = int(query.value(7))
			else:
				insn_cnt = 0
				cyc_cnt = 0
				branch_count = int(query.value(5))
			child_item = CallTreeLevelThreeItem(self.glb, self.params, self.child_count, self.comm_id, self.thread_id, query.value(0), query.value(1), query.value(2), query.value(3), int(query.value(4)), insn_cnt, cyc_cnt, branch_count, self)
			self.child_items.append(child_item)
			self.child_count += 1

# Call tree data model level three item

class CallTreeLevelThreeItem(CallTreeLevelTwoPlusItemBase):

	def __init__(self, glb, params, row, comm_id, thread_id, calls_id, name, dso, call_time, time, insn_cnt, cyc_cnt, branch_count, parent_item):
		super(CallTreeLevelThreeItem, self).__init__(glb, params, row, comm_id, thread_id, calls_id, call_time, time, insn_cnt, cyc_cnt, branch_count, parent_item)
		dso = dsoname(dso)
		if self.params.have_ipc:
			insn_pcnt = PercentToOneDP(insn_cnt, parent_item.insn_cnt)
			cyc_pcnt = PercentToOneDP(cyc_cnt, parent_item.cyc_cnt)
			br_pcnt = PercentToOneDP(branch_count, parent_item.branch_count)
			ipc = CalcIPC(cyc_cnt, insn_cnt)
			self.data = [ name, dso, str(call_time), str(time), PercentToOneDP(time, parent_item.time), str(insn_cnt), insn_pcnt, str(cyc_cnt), cyc_pcnt, ipc, str(branch_count), br_pcnt ]
		else:
			self.data = [ name, dso, str(call_time), str(time), PercentToOneDP(time, parent_item.time), str(branch_count), PercentToOneDP(branch_count, parent_item.branch_count) ]
		self.dbid = calls_id

# Call tree data model level two item

class CallTreeLevelTwoItem(CallTreeLevelTwoPlusItemBase):

	def __init__(self, glb, params, row, comm_id, thread_id, pid, tid, parent_item):
		super(CallTreeLevelTwoItem, self).__init__(glb, params, row, comm_id, thread_id, 0, 0, 0, 0, 0, 0, parent_item)
		if self.params.have_ipc:
			self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", "", "", "", "", "", ""]
		else:
			self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", ""]
		self.dbid = thread_id

	def Select(self):
		super(CallTreeLevelTwoItem, self).Select()
		for child_item in self.child_items:
			self.time += child_item.time
			self.insn_cnt += child_item.insn_cnt
			self.cyc_cnt += child_item.cyc_cnt
			self.branch_count += child_item.branch_count
		for child_item in self.child_items:
			child_item.data[4] = PercentToOneDP(child_item.time, self.time)
			if self.params.have_ipc:
				child_item.data[6] = PercentToOneDP(child_item.insn_cnt, self.insn_cnt)
				child_item.data[8] = PercentToOneDP(child_item.cyc_cnt, self.cyc_cnt)
				child_item.data[11] = PercentToOneDP(child_item.branch_count, self.branch_count)
			else:
				child_item.data[6] = PercentToOneDP(child_item.branch_count, self.branch_count)

# Call tree data model level one item

class CallTreeLevelOneItem(CallGraphLevelItemBase):

	def __init__(self, glb, params, row, comm_id, comm, parent_item):
		super(CallTreeLevelOneItem, self).__init__(glb, params, row, parent_item)
		if self.params.have_ipc:
			self.data = [comm, "", "", "", "", "", "", "", "", "", "", ""]
		else:
			self.data = [comm, "", "", "", "", "", ""]
		self.dbid = comm_id

	def Select(self):
		self.query_done = True
		query = QSqlQuery(self.glb.db)
		QueryExec(query, "SELECT thread_id, pid, tid"
					" FROM comm_threads"
					" INNER JOIN threads ON thread_id = threads.id"
					" WHERE comm_id = " + str(self.dbid))
		while query.next():
			child_item = CallTreeLevelTwoItem(self.glb, self.params, self.child_count, self.dbid, query.value(0), query.value(1), query.value(2), self)
			self.child_items.append(child_item)
			self.child_count += 1

# Call tree data model root item

class CallTreeRootItem(CallGraphLevelItemBase):

	def __init__(self, glb, params):
		super(CallTreeRootItem, self).__init__(glb, params, 0, None)
		self.dbid = 0
		self.query_done = True
		if_has_calls = ""
		if IsSelectable(glb.db, "comms", columns = "has_calls"):
			if_has_calls = " WHERE has_calls = " + glb.dbref.TRUE
		query = QSqlQuery(glb.db)
		QueryExec(query, "SELECT id, comm FROM comms" + if_has_calls)
		while query.next():
			if not query.value(0):
				continue
			child_item = CallTreeLevelOneItem(glb, params, self.child_count, query.value(0), query.value(1), self)
			self.child_items.append(child_item)
			self.child_count += 1

# Call Tree data model

class CallTreeModel(CallGraphModelBase):

	def __init__(self, glb, parent=None):
		super(CallTreeModel, self).__init__(glb, parent)

	def GetRoot(self):
		return CallTreeRootItem(self.glb, self.params)

	def columnCount(self, parent=None):
		if self.params.have_ipc:
			return 12
		else:
			return 7

	def columnHeader(self, column):
		if self.params.have_ipc:
			headers = ["Call Path", "Object", "Call Time", "Time (ns) ", "Time (%) ", "Insn Cnt", "Insn Cnt (%)", "Cyc Cnt", "Cyc Cnt (%)", "IPC", "Branch Count ", "Branch Count (%) "]
		else:
			headers = ["Call Path", "Object", "Call Time", "Time (ns) ", "Time (%) ", "Branch Count ", "Branch Count (%) "]
		return headers[column]

	def columnAlignment(self, column):
		if self.params.have_ipc:
			alignment = [ Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight ]
		else:
			alignment = [ Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight ]
		return alignment[column]

	def DoFindSelect(self, query, match):
		QueryExec(query, "SELECT calls.id, comm_id, thread_id"
						" FROM calls"
						" INNER JOIN call_paths ON calls.call_path_id = call_paths.id"
						" INNER JOIN symbols ON call_paths.symbol_id = symbols.id"
						" WHERE calls.id <> 0"
						" AND symbols.name" + match +
						" ORDER BY comm_id, thread_id, call_time, calls.id")

	def FindPath(self, query):
		# Turn the query result into a list of ids that the tree view can walk
		# to open the tree at the right place.
		ids = []
		parent_id = query.value(0)
		while parent_id:
			ids.insert(0, parent_id)
			q2 = QSqlQuery(self.glb.db)
			QueryExec(q2, "SELECT parent_id"
					" FROM calls"
					" WHERE id = " + str(parent_id))
			if not q2.next():
				break
			parent_id = q2.value(0)
		ids.insert(0, query.value(2))
		ids.insert(0, query.value(1))
		return ids

# Vertical layout

class HBoxLayout(QHBoxLayout):

	def __init__(self, *children):
		super(HBoxLayout, self).__init__()

		self.layout().setContentsMargins(0, 0, 0, 0)
		for child in children:
			if child.isWidgetType():
				self.layout().addWidget(child)
			else:
				self.layout().addLayout(child)

# Horizontal layout

class VBoxLayout(QVBoxLayout):

	def __init__(self, *children):
		super(VBoxLayout, self).__init__()

		self.layout().setContentsMargins(0, 0, 0, 0)
		for child in children:
			if child.isWidgetType():
				self.layout().addWidget(child)
			else:
				self.layout().addLayout(child)

# Vertical layout widget

class VBox():

	def __init__(self, *children):
		self.vbox = QWidget()
		self.vbox.setLayout(VBoxLayout(*children))

	def Widget(self):
		return self.vbox

# Tree window base

class TreeWindowBase(QMdiSubWindow):

	def __init__(self, parent=None):
		super(TreeWindowBase, self).__init__(parent)

		self.model = 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
		parent = QModelIndex()
		for dbid in ids:
			found = False
			n = self.model.rowCount(parent)
			for row in xrange(n):
				child = self.model.index(row, 0, parent)
				if child.internalPointer().dbid == dbid:
					found = True
					self.view.setExpanded(parent, True)
					self.view.setCurrentIndex(child)
					parent = child
					break
			if not found:
				break
		return found

	def Find(self, value, direction, pattern, context):
		self.view.setFocus()
		self.find_bar.Busy()
		self.model.Find(value, direction, pattern, context, self.FindDone)

	def FindDone(self, ids):
		found = True
		if not self.DisplayFound(ids):
			found = False
		self.find_bar.Idle()
		if not found:
			self.find_bar.NotFound()


# Context-sensitive call graph window

class CallGraphWindow(TreeWindowBase):

	def __init__(self, glb, parent=None):
		super(CallGraphWindow, self).__init__(parent)

		self.model = LookupCreateModel("Context-Sensitive Call Graph", lambda x=glb: CallGraphModel(x))

		self.view.setModel(self.model)

		for c, w in ((0, 250), (1, 100), (2, 60), (3, 70), (4, 70), (5, 100)):
			self.view.setColumnWidth(c, w)

		self.find_bar = FindBar(self, self)

		self.vbox = VBox(self.view, self.find_bar.Widget())

		self.setWidget(self.vbox.Widget())

		AddSubWindow(glb.mainwindow.mdi_area, self, "Context-Sensitive Call Graph")

# Call tree window

class CallTreeWindow(TreeWindowBase):

	def __init__(self, glb, parent=None, thread_at_time=None):
		super(CallTreeWindow, self).__init__(parent)

		self.model = LookupCreateModel("Call Tree", lambda x=glb: CallTreeModel(x))

		self.view.setModel(self.model)

		for c, w in ((0, 230), (1, 100), (2, 100), (3, 70), (4, 70), (5, 100)):
			self.view.setColumnWidth(c, w)

		self.find_bar = FindBar(self, self)

		self.vbox = VBox(self.view, self.find_bar.Widget())

		self.setWidget(self.vbox.Widget())

		AddSubWindow(glb.mainwindow.mdi_area, self, "Call Tree")

		if thread_at_time:
			self.DisplayThreadAtTime(*thread_at_time)

	def DisplayThreadAtTime(self, comm_id, thread_id, time):
		parent = QModelIndex()
		for dbid in (comm_id, thread_id):
			found = False
			n = self.model.rowCount(parent)
			for row in xrange(n):
				child = self.model.index(row, 0, parent)
				if child.internalPointer().dbid == dbid:
					found = True
					self.view.setExpanded(parent, True)
					self.view.setCurrentIndex(child)
					parent = child
					break
			if not found:
				return
		found = False
		while True:
			n = self.model.rowCount(parent)
			if not n:
				return
			last_child = None
			for row in xrange(n):
				self.view.setExpanded(parent, True)
				child = self.model.index(row, 0, parent)
				child_call_time = child.internalPointer().call_time
				if child_call_time < time:
					last_child = child
				elif child_call_time == time:
					self.view.setCurrentIndex(child)
					return
				elif child_call_time > time:
					break
			if not last_child:
				if not found:
					child = self.model.index(0, 0, parent)
					self.view.setExpanded(parent, True)
					self.view.setCurrentIndex(child)
				return
			found = True
			self.view.setExpanded(parent, True)
			self.view.setCurrentIndex(last_child)
			parent = last_child

# ExecComm() gets the comm_id of the command string that was set when the process exec'd i.e. the program name

def ExecComm(db, thread_id, time):
	query = QSqlQuery(db)
	QueryExec(query, "SELECT comm_threads.comm_id, comms.c_time, comms.exec_flag"
				" FROM comm_threads"
				" INNER JOIN comms ON comms.id = comm_threads.comm_id"
				" WHERE comm_threads.thread_id = " + str(thread_id) +
				" ORDER BY comms.c_time, comms.id")
	first = None
	last = None
	while query.next():
		if first is None:
			first = query.value(0)
		if query.value(2) and Decimal(query.value(1)) <= Decimal(time):
			last = query.value(0)
	if not(last is None):
		return last
	return first

# Container for (x, y) data

class XY():
	def __init__(self, x=0, y=0):
		self.x = x
		self.y = y

	def __str__(self):
		return "XY({}, {})".format(str(self.x), str(self.y))

# Container for sub-range data

class Subrange():
	def __init__(self, lo=0, hi=0):
		self.lo = lo
		self.hi = hi

	def __str__(self):
		return "Subrange({}, {})".format(str(self.lo), str(self.hi))

# Graph data region base class

class GraphDataRegion(object):

	def __init__(self, key, title = "", ordinal = ""):
		self.key = key
		self.title = title
		self.ordinal = ordinal

# Function to sort GraphDataRegion

def GraphDataRegionOrdinal(data_region):
	return data_region.ordinal

# Attributes for a graph region

class GraphRegionAttribute():

	def __init__(self, colour):
		self.colour = colour

# Switch graph data region represents a task

class SwitchGraphDataRegion(GraphDataRegion):

	def __init__(self, key, exec_comm_id, pid, tid, comm, thread_id, comm_id):
		super(SwitchGraphDataRegion, self).__init__(key)

		self.title = str(pid) + " / " + str(tid) + " " + comm
		# Order graph legend within exec comm by pid / tid / time
		self.ordinal = str(pid).rjust(16) + str(exec_comm_id).rjust(8) + str(tid).rjust(16)
		self.exec_comm_id = exec_comm_id
		self.pid = pid
		self.tid = tid
		self.comm = comm
		self.thread_id = thread_id
		self.comm_id = comm_id

# Graph data point

class GraphDataPoint():

	def __init__(self, data, index, x, y, altx=None, alty=None, hregion=None, vregion=None):
		self.data = data
		self.index = index
		self.x = x
		self.y = y
		self.altx = altx
		self.alty = alty
		self.hregion = hregion
		self.vregion = vregion

# Graph data (single graph) base class

class GraphData(object):

	def __init__(self, collection, xbase=Decimal(0), ybase=Decimal(0)):
		self.collection = collection
		self.points = []
		self.xbase = xbase
		self.ybase = ybase
		self.title = ""

	def AddPoint(self, x, y, altx=None, alty=None, hregion=None, vregion=None):
		index = len(self.points)

		x = float(Decimal(x) - self.xbase)
		y = float(Decimal(y) - self.ybase)

		self.points.append(GraphDataPoint(self, index, x, y, altx, alty, hregion, vregion))

	def XToData(self, x):
		return Decimal(x) + self.xbase

	def YToData(self, y):
		return Decimal(y) + self.ybase

# Switch graph data (for one CPU)

class SwitchGraphData(GraphData):

	def __init__(self, db, collection, cpu, xbase):
		super(SwitchGraphData, self).__init__(collection, xbase)

		self.cpu = cpu
		self.title = "CPU " + str(cpu)
		self.SelectSwitches(db)

	def SelectComms(self, db, thread_id, last_comm_id, start_time, end_time):
		query = QSqlQuery(db)
		QueryExec(query, "SELECT id, c_time"
					" FROM comms"
					" WHERE c_thread_id = " + str(thread_id) +
					"   AND exec_flag = " + self.collection.glb.dbref.TRUE +
					"   AND c_time >= " + str(start_time) +
					"   AND c_time <= " + str(end_time) +
					" ORDER BY c_time, id")
		while query.next():
			comm_id = query.value(0)
			if comm_id == last_comm_id:
				continue
			time = query.value(1)
			hregion = self.HRegion(db, thread_id, comm_id, time)
			self.AddPoint(time, 1000, None, None, hregion)

	def SelectSwitches(self, db):
		last_time = None
		last_comm_id = None
		last_thread_id = None
		query = QSqlQuery(db)
		QueryExec(query, "SELECT time, thread_out_id, thread_in_id, comm_out_id, comm_in_id, flags"
					" FROM context_switches"
					" WHERE machine_id = " + str(self.collection.machine_id) +
					"   AND cpu = " + str(self.cpu) +
					" ORDER BY time, id")
		while query.next():
			flags = int(query.value(5))
			if flags & 1:
				# Schedule-out: detect and add exec's
				if last_thread_id == query.value(1) and last_comm_id is not None and last_comm_id != query.value(3):
					self.SelectComms(db, last_thread_id, last_comm_id, last_time, query.value(0))
				continue
			# Schedule-in: add data point
			if len(self.points) == 0:
				start_time = self.collection.glb.StartTime(self.collection.machine_id)
				hregion = self.HRegion(db, query.value(1), query.value(3), start_time)
				self.AddPoint(start_time, 1000, None, None, hregion)
			time = query.value(0)
			comm_id = query.value(4)
			thread_id = query.value(2)
			hregion = self.HRegion(db, thread_id, comm_id, time)
			self.AddPoint(time, 1000, None, None, hregion)
			last_time = time
			last_comm_id = comm_id
			last_thread_id = thread_id

	def NewHRegion(self, db, key, thread_id, comm_id, time):
		exec_comm_id = ExecComm(db, thread_id, time)
		query = QSqlQuery(db)
		QueryExec(query, "SELECT pid, tid FROM threads WHERE id = " + str(thread_id))
		if query.next():
			pid = query.value(0)
			tid = query.value(1)
		else:
			pid = -1
			tid = -1
		query = QSqlQuery(db)
		QueryExec(query, "SELECT comm FROM comms WHERE id = " + str(comm_id))
		if query.next():
			comm = query.value(0)
		else:
			comm = ""
		return SwitchGraphDataRegion(key, exec_comm_id, pid, tid, comm, thread_id, comm_id)

	def HRegion(self, db, thread_id, comm_id, time):
		key = str(thread_id) + ":" + str(comm_id)
		hregion = self.collection.LookupHRegion(key)
		if hregion is None:
			hregion = self.NewHRegion(db, key, thread_id, comm_id, time)
			self.collection.AddHRegion(key, hregion)
		return hregion

# Graph data collection (multiple related graphs) base class

class GraphDataCollection(object):

	def __init__(self, glb):
		self.glb = glb
		self.data = []
		self.hregions = {}
		self.xrangelo = None
		self.xrangehi = None
		self.yrangelo = None
		self.yrangehi = None
		self.dp = XY(0, 0)

	def AddGraphData(self, data):
		self.data.append(data)

	def LookupHRegion(self, key):
		if key in self.hregions:
			return self.hregions[key]
		return None

	def AddHRegion(self, key, hregion):
		self.hregions[key] = hregion

# Switch graph data collection (SwitchGraphData for each CPU)

class SwitchGraphDataCollection(GraphDataCollection):

	def __init__(self, glb, db, machine_id):
		super(SwitchGraphDataCollection, self).__init__(glb)

		self.machine_id = machine_id
		self.cpus = self.SelectCPUs(db)

		self.xrangelo = glb.StartTime(machine_id)
		self.xrangehi = glb.FinishTime(machine_id)

		self.yrangelo = Decimal(0)
		self.yrangehi = Decimal(1000)

		for cpu in self.cpus:
			self.AddGraphData(SwitchGraphData(db, self, cpu, self.xrangelo))

	def SelectCPUs(self, db):
		cpus = []
		query = QSqlQuery(db)
		QueryExec(query, "SELECT DISTINCT cpu"
					" FROM context_switches"
					" WHERE machine_id = " + str(self.machine_id))
		while query.next():
			cpus.append(int(query.value(0)))
		return sorted(cpus)

# Switch graph data graphics item displays the graphed data

class SwitchGraphDataGraphicsItem(QGraphicsItem):

	def __init__(self, data, graph_width, graph_height, attrs, event_handler, parent=None):
		super(SwitchGraphDataGraphicsItem, self).__init__(parent)

		self.data = data
		self.graph_width = graph_width
		self.graph_height = graph_height
		self.attrs = attrs
		self.event_handler = event_handler
		self.setAcceptHoverEvents(True)

	def boundingRect(self):
		return QRectF(0, 0, self.graph_width, self.graph_height)

	def PaintPoint(self, painter, last, x):
		if not(last is None or last.hregion.pid == 0 or x < self.attrs.subrange.x.lo):
			if last.x < self.attrs.subrange.x.lo:
				x0 = self.attrs.subrange.x.lo
			else:
				x0 = last.x
			if x > self.attrs.subrange.x.hi:
				x1 = self.attrs.subrange.x.hi
			else:
				x1 = x - 1
			x0 = self.attrs.XToPixel(x0)
			x1 = self.attrs.XToPixel(x1)

			y0 = self.attrs.YToPixel(last.y)

			colour = self.attrs.region_attributes[last.hregion.key].colour

			width = x1 - x0 + 1
			if width < 2:
				painter.setPen(colour)
				painter.drawLine(x0, self.graph_height - y0, x0, self.graph_height)
			else:
				painter.fillRect(x0, self.graph_height - y0, width, self.graph_height - 1, colour)

	def paint(self, painter, option, widget):
		last = None
		for point in self.data.points:
			self.PaintPoint(painter, last, point.x)
			if point.x > self.attrs.subrange.x.hi:
				break;
			last = point
		self.PaintPoint(painter, last, self.attrs.subrange.x.hi + 1)

	def BinarySearchPoint(self, target):
		lower_pos = 0
		higher_pos = len(self.data.points)
		while True:
			pos = int((lower_pos + higher_pos) / 2)
			val = self.data.points[pos].x
			if target >= val:
				lower_pos = pos
			else:
				higher_pos = pos
			if higher_pos <= lower_pos + 1:
				return lower_pos

	def XPixelToData(self, x):
		x = self.attrs.PixelToX(x)
		if x < self.data.points[0].x:
			x = 0
			pos = 0
			low = True
		else:
			pos = self.BinarySearchPoint(x)
			low = False
		return (low, pos, self.data.XToData(x))

	def EventToData(self, event):
		no_data = (None,) * 4
		if len(self.data.points) < 1:
			return no_data
		x = event.pos().x()
		if x < 0:
			return no_data
		low0, pos0, time_from = self.XPixelToData(x)
		low1, pos1, time_to = self.XPixelToData(x + 1)
		hregions = set()
		hregion_times = []
		if not low1:
			for i in xrange(pos0, pos1 + 1):
				hregion = self.data.points[i].hregion
				hregions.add(hregion)
				if i == pos0:
					time = time_from
				else:
					time = self.data.XToData(self.data.points[i].x)
				hregion_times.append((hregion, time))
		return (time_from, time_to, hregions, hregion_times)

	def hoverMoveEvent(self, event):
		time_from, time_to, hregions, hregion_times = self.EventToData(event)
		if time_from is not None:
			self.event_handler.PointEvent(self.data.cpu, time_from, time_to, hregions)

	def hoverLeaveEvent(self, event):
		self.event_handler.NoPointEvent()

	def mousePressEvent(self, event):
		if event.button() != Qt.RightButton:
			super(SwitchGraphDataGraphicsItem, self).mousePressEvent(event)
			return
		time_from, time_to, hregions, hregion_times = self.EventToData(event)
		if hregion_times:
			self.event_handler.RightClickEvent(self.data.cpu, hregion_times, event.screenPos())

# X-axis graphics item

class XAxisGraphicsItem(QGraphicsItem):

	def __init__(self, width, parent=None):
		super(XAxisGraphicsItem, self).__init__(parent)

		self.width = width
		self.max_mark_sz = 4
		self.height = self.max_mark_sz + 1

	def boundingRect(self):
		return QRectF(0, 0, self.width, self.height)

	def Step(self):
		attrs = self.parentItem().attrs
		subrange = attrs.subrange.x
		t = subrange.hi - subrange.lo
		s = (3.0 * t) / self.width
		n = 1.0
		while s > n:
			n = n * 10.0
		return n

	def PaintMarks(self, painter, at_y, lo, hi, step, i):
		attrs = self.parentItem().attrs
		x = lo
		while x <= hi:
			xp = attrs.XToPixel(x)
			if i % 10:
				if i % 5:
					sz = 1
				else:
					sz = 2
			else:
				sz = self.max_mark_sz
				i = 0
			painter.drawLine(xp, at_y, xp, at_y + sz)
			x += step
			i += 1

	def paint(self, painter, option, widget):
		# Using QPainter::drawLine(int x1, int y1, int x2, int y2) so x2 = width -1
		painter.drawLine(0, 0, self.width - 1, 0)
		n = self.Step()
		attrs = self.parentItem().attrs
		subrange = attrs.subrange.x
		if subrange.lo:
			x_offset = n - (subrange.lo % n)
		else:
			x_offset = 0.0
		x = subrange.lo + x_offset
		i = (x / n) % 10
		self.PaintMarks(painter, 0, x, subrange.hi, n, i)

	def ScaleDimensions(self):
		n = self.Step()
		attrs = self.parentItem().attrs
		lo = attrs.subrange.x.lo
		hi = (n * 10.0) + lo
		width = attrs.XToPixel(hi)
		if width > 500:
			width = 0
		return (n, lo, hi, width)

	def PaintScale(self, painter, at_x, at_y):
		n, lo, hi, width = self.ScaleDimensions()
		if not width:
			return
		painter.drawLine(at_x, at_y, at_x + width, at_y)
		self.PaintMarks(painter, at_y, lo, hi, n, 0)

	def ScaleWidth(self):
		n, lo, hi, width = self.ScaleDimensions()
		return width

	def ScaleHeight(self):
		return self.height

	def ScaleUnit(self):
		return self.Step() * 10

# Scale graphics item base class

class ScaleGraphicsItem(QGraphicsItem):

	def __init__(self, axis, parent=None):
		super(ScaleGraphicsItem, self).__init__(parent)
		self.axis = axis

	def boundingRect(self):
		scale_width = self.axis.ScaleWidth()
		if not scale_width:
			return QRectF()
		return QRectF(0, 0, self.axis.ScaleWidth() + 100, self.axis.ScaleHeight())

	def paint(self, painter, option, widget):
		scale_width = self.axis.ScaleWidth()
		if not scale_width:
			return
		self.axis.PaintScale(painter, 0, 5)
		x = scale_width + 4
		painter.drawText(QPointF(x, 10), self.Text())

	def Unit(self):
		return self.axis.ScaleUnit()

	def Text(self):
		return ""

# Switch graph scale graphics item

class SwitchScaleGraphicsItem(ScaleGraphicsItem):

	def __init__(self, axis, parent=None):
		super(SwitchScaleGraphicsItem, self).__init__(axis, parent)

	def Text(self):
		unit = self.Unit()
		if unit >= 1000000000:
			unit = int(unit / 1000000000)
			us = "s"
		elif unit >= 1000000:
			unit = int(unit / 1000000)
			us = "ms"
		elif unit >= 1000:
			unit = int(unit / 1000)
			us = "us"
		else:
			unit = int(unit)
			us = "ns"
		return " = " + str(unit) + " " + us

# Switch graph graphics item contains graph title, scale, x/y-axis, and the graphed data

class SwitchGraphGraphicsItem(QGraphicsItem):

	def __init__(self, collection, data, attrs, event_handler, first, parent=None):
		super(SwitchGraphGraphicsItem, self).__init__(parent)
		self.collection = collection
		self.data = data
		self.attrs = attrs
		self.event_handler = event_handler

		margin = 20
		title_width = 50

		self.title_graphics = QGraphicsSimpleTextItem(data.title, self)

		self.title_graphics.setPos(margin, margin)
		graph_width = attrs.XToPixel(attrs.subrange.x.hi) + 1
		graph_height = attrs.YToPixel(attrs.subrange.y.hi) + 1

		self.graph_origin_x = margin + title_width + margin
		self.graph_origin_y = graph_height + margin

		x_axis_size = 1
		y_axis_size = 1
		self.yline = QGraphicsLineItem(0, 0, 0, graph_height, self)

		self.x_axis = XAxisGraphicsItem(graph_width, self)
		self.x_axis.setPos(self.graph_origin_x, self.graph_origin_y + 1)

		if first:
			self.scale_item = SwitchScaleGraphicsItem(self.x_axis, self)
			self.scale_item.setPos(self.graph_origin_x, self.graph_origin_y + 10)

		self.yline.setPos(self.graph_origin_x - y_axis_size, self.graph_origin_y - graph_height)

		self.axis_point = QGraphicsLineItem(0, 0, 0, 0, self)
		self.axis_point.setPos(self.graph_origin_x - 1, self.graph_origin_y +1)

		self.width = self.graph_origin_x + graph_width + margin
		self.height = self.graph_origin_y + margin

		self.graph = SwitchGraphDataGraphicsItem(data, graph_width, graph_height, attrs, event_handler, self)
		self.graph.setPos(self.graph_origin_x, self.graph_origin_y - graph_height)

		if parent and 'EnableRubberBand' in dir(parent):
			parent.EnableRubberBand(self.graph_origin_x, self.graph_origin_x + graph_width - 1, self)

	def boundingRect(self):
		return QRectF(0, 0, self.width, self.height)

	def paint(self, painter, option, widget):
		pass

	def RBXToPixel(self, x):
		return self.attrs.PixelToX(x - self.graph_origin_x)

	def RBXRangeToPixel(self, x0, x1):
		return (self.RBXToPixel(x0), self.RBXToPixel(x1 + 1))

	def RBPixelToTime(self, x):
		if x < self.data.points[0].x:
			return self.data.XToData(0)
		return self.data.XToData(x)

	def RBEventTimes(self, x0, x1):
		x0, x1 = self.RBXRangeToPixel(x0, x1)
		time_from = self.RBPixelToTime(x0)
		time_to = self.RBPixelToTime(x1)
		return (time_from, time_to)

	def RBEvent(self, x0, x1):
		time_from, time_to = self.RBEventTimes(x0, x1)
		self.event_handler.RangeEvent(time_from, time_to)

	def RBMoveEvent(self, x0, x1):
		if x1 < x0:
			x0, x1 = x1, x0
		self.RBEvent(x0, x1)

	def RBReleaseEvent(self, x0, x1, selection_state):
		if x1 < x0:
			x0, x1 = x1, x0
		x0, x1 = self.RBXRangeToPixel(x0, x1)
		self.event_handler.SelectEvent(x0, x1, selection_state)

# Graphics item to draw a vertical bracket (used to highlight "forward" sub-range)

class VerticalBracketGraphicsItem(QGraphicsItem):

	def __init__(self, parent=None):
		super(VerticalBracketGraphicsItem, self).__init__(parent)

		self.width = 0
		self.height = 0
		self.hide()

	def SetSize(self, width, height):
		self.width = width + 1
		self.height = height + 1

	def boundingRect(self):
		return QRectF(0, 0, self.width, self.height)

	def paint(self, painter, option, widget):
		colour = QColor(255, 255, 0, 32)
		painter.fillRect(0, 0, self.width, self.height, colour)
		x1 = self.width - 1
		y1 = self.height - 1
		painter.drawLine(0, 0, x1, 0)
		painter.drawLine(0, 0, 0, 3)
		painter.drawLine(x1, 0, x1, 3)
		painter.drawLine(0, y1, x1, y1)
		painter.drawLine(0, y1, 0, y1 - 3)
		painter.drawLine(x1, y1, x1, y1 - 3)

# Graphics item to contain graphs arranged vertically

class VertcalGraphSetGraphicsItem(QGraphicsItem):

	def __init__(self, collection, attrs, event_handler, child_class, parent=None):
		super(VertcalGraphSetGraphicsItem, self).__init__(parent)

		self.collection = collection

		self.top = 10

		self.width = 0
		self.height = self.top

		self.rubber_band = None
		self.rb_enabled = False

		first = True
		for data in collection.data:
			child = child_class(collection, data, attrs, event_handler, first, self)
			child.setPos(0, self.height + 1)
			rect = child.boundingRect()
			if rect.right() > self.width:
				self.width = rect.right()
			self.height = self.height + rect.bottom() + 1
			first = False

		self.bracket = VerticalBracketGraphicsItem(self)

	def EnableRubberBand(self, xlo, xhi, rb_event_handler):
		if self.rb_enabled:
			return
		self.rb_enabled = True
		self.rb_in_view = False
		self.setAcceptedMouseButtons(Qt.LeftButton)
		self.rb_xlo = xlo
		self.rb_xhi = xhi
		self.rb_event_handler = rb_event_handler
		self.mousePressEvent = self.MousePressEvent
		self.mouseMoveEvent = self.MouseMoveEvent
		self.mouseReleaseEvent = self.MouseReleaseEvent

	def boundingRect(self):
		return QRectF(0, 0, self.width, self.height)

	def paint(self, painter, option, widget):
		pass

	def RubberBandParent(self):
		scene = self.scene()
		view = scene.views()[0]
		viewport = view.viewport()
		return viewport

	def RubberBandSetGeometry(self, rect):
		scene_rectf = self.mapRectToScene(QRectF(rect))
		scene = self.scene()
		view = scene.views()[0]
		poly = view.mapFromScene(scene_rectf)
		self.rubber_band.setGeometry(poly.boundingRect())

	def SetSelection(self, selection_state):
		if self.rubber_band:
			if selection_state:
				self.RubberBandSetGeometry(selection_state)
				self.rubber_band.show()
			else:
				self.rubber_band.hide()

	def SetBracket(self, rect):
		if rect:
			x, y, width, height = rect.x(), rect.y(), rect.width(), rect.height()
			self.bracket.setPos(x, y)
			self.bracket.SetSize(width, height)
			self.bracket.show()
		else:
			self.bracket.hide()

	def RubberBandX(self, event):
		x = event.pos().toPoint().x()
		if x < self.rb_xlo:
			x = self.rb_xlo
		elif x > self.rb_xhi:
			x = self.rb_xhi
		else:
			self.rb_in_view = True
		return x

	def RubberBandRect(self, x):
		if self.rb_origin.x() <= x:
			width = x - self.rb_origin.x()
			rect = QRect(self.rb_origin, QSize(width, self.height))
		else:
			width = self.rb_origin.x() - x
			top_left = QPoint(self.rb_origin.x() - width, self.rb_origin.y())
			rect = QRect(top_left, QSize(width, self.height))
		return rect

	def MousePressEvent(self, event):
		self.rb_in_view = False
		x = self.RubberBandX(event)
		self.rb_origin = QPoint(x, self.top)
		if self.rubber_band is None:
			self.rubber_band = QRubberBand(QRubberBand.Rectangle, self.RubberBandParent())
		self.RubberBandSetGeometry(QRect(self.rb_origin, QSize(0, self.height)))
		if self.rb_in_view:
			self.rubber_band.show()
			self.rb_event_handler.RBMoveEvent(x, x)
		else:
			self.rubber_band.hide()

	def MouseMoveEvent(self, event):
		x = self.RubberBandX(event)
		rect = self.RubberBandRect(x)
		self.RubberBandSetGeometry(rect)
		if self.rb_in_view:
			self.rubber_band.show()
			self.rb_event_handler.RBMoveEvent(self.rb_origin.x(), x)

	def MouseReleaseEvent(self, event):
		x = self.RubberBandX(event)
		if self.rb_in_view:
			selection_state = self.RubberBandRect(x)
		else:
			selection_state = None
		self.rb_event_handler.RBReleaseEvent(self.rb_origin.x(), x, selection_state)

# Switch graph legend data model

class SwitchGraphLegendModel(QAbstractTableModel):

	def __init__(self, collection, region_attributes, parent=None):
		super(SwitchGraphLegendModel, self).__init__(parent)

		self.region_attributes = region_attributes

		self.child_items = sorted(collection.hregions.values(), key=GraphDataRegionOrdinal)
		self.child_count = len(self.child_items)

		self.highlight_set = set()

		self.column_headers = ("pid", "tid", "comm")

	def rowCount(self, parent):
		return self.child_count

	def headerData(self, section, orientation, role):
		if role != Qt.DisplayRole:
			return None
		if orientation != Qt.Horizontal:
			return None
		return self.columnHeader(section)

	def index(self, row, column, parent):
		return self.createIndex(row, column, self.child_items[row])

	def columnCount(self, parent=None):
		return len(self.column_headers)

	def columnHeader(self, column):
		return self.column_headers[column]

	def data(self, index, role):
		if role == Qt.BackgroundRole:
			child = self.child_items[index.row()]
			if child in self.highlight_set:
				return self.region_attributes[child.key].colour
			return None
		if role == Qt.ForegroundRole:
			child = self.child_items[index.row()]
			if child in self.highlight_set:
				return QColor(255, 255, 255)
			return self.region_attributes[child.key].colour
		if role != Qt.DisplayRole:
			return None
		hregion = self.child_items[index.row()]
		col = index.column()
		if col == 0:
			return hregion.pid
		if col == 1:
			return hregion.tid
		if col == 2:
			return hregion.comm
		return None

	def SetHighlight(self, row, set_highlight):
		child = self.child_items[row]
		top_left = self.createIndex(row, 0, child)
		bottom_right = self.createIndex(row, len(self.column_headers) - 1, child)
		self.dataChanged.emit(top_left, bottom_right)

	def Highlight(self, highlight_set):
		for row in xrange(self.child_count):
			child = self.child_items[row]
			if child in self.highlight_set:
				if child not in highlight_set:
					self.SetHighlight(row, False)
			elif child in highlight_set:
				self.SetHighlight(row, True)
		self.highlight_set = highlight_set

# Switch graph legend is a table

class SwitchGraphLegend(QWidget):

	def __init__(self, collection, region_attributes, parent=None):
		super(SwitchGraphLegend, self).__init__(parent)

		self.data_model = SwitchGraphLegendModel(collection, region_attributes)

		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.view.resizeColumnsToContents()
		self.view.resizeRowsToContents()

		self.vbox = VBoxLayout(self.view)
		self.setLayout(self.vbox)

		sz1 = self.view.columnWidth(0) + self.view.columnWidth(1) + self.view.columnWidth(2) + 2
		sz1 = sz1 + self.view.verticalScrollBar().sizeHint().width()
		self.saved_size = sz1

	def resizeEvent(self, event):
		self.saved_size = self.size().width()
		super(SwitchGraphLegend, self).resizeEvent(event)

	def Highlight(self, highlight_set):
		self.data_model.Highlight(highlight_set)
		self.update()

	def changeEvent(self, event):
		if event.type() == QEvent.FontChange:
			self.view.resizeRowsToContents()
			self.view.resizeColumnsToContents()
			# Need to resize rows again after column resize
			self.view.resizeRowsToContents()
		super(SwitchGraphLegend, self).changeEvent(event)

# Random colour generation

def RGBColourTooLight(r, g, b):
	if g > 230:
		return True
	if g <= 160:
		return False
	if r <= 180 and g <= 180:
		return False
	if r < 60:
		return False
	return True

def GenerateColours(x):
	cs = [0]
	for i in xrange(1, x):
		cs.append(int((255.0 / i) + 0.5))
	colours = []
	for r in cs:
		for g in cs:
			for b in cs:
				# Exclude black and colours that look too light against a white background
				if (r, g, b) == (0, 0, 0) or RGBColourTooLight(r, g, b):
					continue
				colours.append(QColor(r, g, b))
	return colours

def GenerateNColours(n):
	for x in xrange(2, n + 2):
		colours = GenerateColours(x)
		if len(colours) >= n:
			return colours
	return []

def GenerateNRandomColours(n, seed):
	colours = GenerateNColours(n)
	random.seed(seed)
	random.shuffle(colours)
	return colours

# Graph attributes, in particular the scale and subrange that change when zooming

class GraphAttributes():

	def __init__(self, scale, subrange, region_attributes, dp):
		self.scale = scale
		self.subrange = subrange
		self.region_attributes = region_attributes
		# Rounding avoids errors due to finite floating point precision
		self.dp = dp	# data decimal places
		self.Update()

	def XToPixel(self, x):
		return int(round((x - self.subrange.x.lo) * self.scale.x, self.pdp.x))

	def YToPixel(self, y):
		return int(round((y - self.subrange.y.lo) * self.scale.y, self.pdp.y))

	def PixelToXRounded(self, px):
		return round((round(px, 0) / self.scale.x), self.dp.x) + self.subrange.x.lo

	def PixelToYRounded(self, py):
		return round((round(py, 0) / self.scale.y), self.dp.y) + self.subrange.y.lo

	def PixelToX(self, px):
		x = self.PixelToXRounded(px)
		if self.pdp.x == 0:
			rt = self.XToPixel(x)
			if rt > px:
				return x - 1
		return x

	def PixelToY(self, py):
		y = self.PixelToYRounded(py)
		if self.pdp.y == 0:
			rt = self.YToPixel(y)
			if rt > py:
				return y - 1
		return y

	def ToPDP(self, dp, scale):
		# Calculate pixel decimal places:
		#    (10 ** dp) is the minimum delta in the data
		#    scale it to get the minimum delta in pixels
		#    log10 gives the number of decimals places negatively
		#    subtrace 1 to divide by 10
		#    round to the lower negative number
		#    change the sign to get the number of decimals positively
		x = math.log10((10 ** dp) * scale)
		if x < 0:
			x -= 1
			x = -int(math.floor(x) - 0.1)
		else:
			x = 0
		return x

	def Update(self):
		x = self.ToPDP(self.dp.x, self.scale.x)
		y = self.ToPDP(self.dp.y, self.scale.y)
		self.pdp = XY(x, y) # pixel decimal places

# Switch graph splitter which divides the CPU graphs from the legend

class SwitchGraphSplitter(QSplitter):

	def __init__(self, parent=None):
		super(SwitchGraphSplitter, self).__init__(parent)

		self.first_time = False

	def resizeEvent(self, ev):
		if self.first_time:
			self.first_time = False
			sz1 = self.widget(1).view.columnWidth(0) + self.widget(1).view.columnWidth(1) + self.widget(1).view.columnWidth(2) + 2
			sz1 = sz1 + self.widget(1).view.verticalScrollBar().sizeHint().width()
			sz0 = self.size().width() - self.handleWidth() - sz1
			self.setSizes([sz0, sz1])
		elif not(self.widget(1).saved_size is None):
			sz1 = self.widget(1).saved_size
			sz0 = self.size().width() - self.handleWidth() - sz1
			self.setSizes([sz0, sz1])
		super(SwitchGraphSplitter, self).resizeEvent(ev)

# Graph widget base class

class GraphWidget(QWidget):

	graph_title_changed = Signal(object)

	def __init__(self, parent=None):
		super(GraphWidget, self).__init__(parent)

	def GraphTitleChanged(self, title):
		self.graph_title_changed.emit(title)

	def Title(self):
		return ""

# Display time in s, ms, us or ns

def ToTimeStr(val):
	val = Decimal(val)
	if val >= 1000000000:
		return "{} s".format((val / 1000000000).quantize(Decimal("0.000000001")))
	if val >= 1000000:
		return "{} ms".format((val / 1000000).quantize(Decimal("0.000001")))
	if val >= 1000:
		return "{} us".format((val / 1000).quantize(Decimal("0.001")))
	return "{} ns".format(val.quantize(Decimal("1")))

# Switch (i.e. context switch i.e. Time Chart by CPU) graph widget which contains the CPU graphs and the legend and control buttons

class SwitchGraphWidget(GraphWidget):

	def __init__(self, glb, collection, parent=None):
		super(SwitchGraphWidget, self).__init__(parent)

		self.glb = glb
		self.collection = collection

		self.back_state = []
		self.forward_state = []
		self.selection_state = (None, None)
		self.fwd_rect = None
		self.start_time = self.glb.StartTime(collection.machine_id)

		i = 0
		hregions = collection.hregions.values()
		colours = GenerateNRandomColours(len(hregions), 1013)
		region_attributes = {}
		for hregion in hregions:
			if hregion.pid == 0 and hregion.tid == 0:
				region_attributes[hregion.key] = GraphRegionAttribute(QColor(0, 0, 0))
			else:
				region_attributes[hregion.key] = GraphRegionAttribute(colours[i])
				i = i + 1

		# Default to entire range
		xsubrange = Subrange(0.0, float(collection.xrangehi - collection.xrangelo) + 1.0)
		ysubrange = Subrange(0.0, float(collection.yrangehi - collection.yrangelo) + 1.0)
		subrange = XY(xsubrange, ysubrange)

		scale = self.GetScaleForRange(subrange)

		self.attrs = GraphAttributes(scale, subrange, region_attributes, collection.dp)

		self.item = VertcalGraphSetGraphicsItem(collection, self.attrs, self, SwitchGraphGraphicsItem)

		self.scene = QGraphicsScene()
		self.scene.addItem(self.item)

		self.view = QGraphicsView(self.scene)
		self.view.centerOn(0, 0)
		self.view.setAlignment(Qt.AlignLeft | Qt.AlignTop)

		self.legend = SwitchGraphLegend(collection, region_attributes)

		self.splitter = SwitchGraphSplitter()
		self.splitter.addWidget(self.view)
		self.splitter.addWidget(self.legend)

		self.point_label = QLabel("")
		self.point_label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)

		self.back_button = QToolButton()
		self.back_button.setIcon(self.style().standardIcon(QStyle.SP_ArrowLeft))
		self.back_button.setDisabled(True)
		self.back_button.released.connect(lambda: self.Back())

		self.forward_button = QToolButton()
		self.forward_button.setIcon(self.style().standardIcon(QStyle.SP_ArrowRight))
		self.forward_button.setDisabled(True)
		self.forward_button.released.connect(lambda: self.Forward())

		self.zoom_button = QToolButton()
		self.zoom_button.setText("Zoom")
		self.zoom_button.setDisabled(True)
		self.zoom_button.released.connect(lambda: self.Zoom())

		self.hbox = HBoxLayout(self.back_button, self.forward_button, self.zoom_button, self.point_label)

		self.vbox = VBoxLayout(self.splitter, self.hbox)

		self.setLayout(self.vbox)

	def GetScaleForRangeX(self, xsubrange):
		# Default graph 1000 pixels wide
		dflt = 1000.0
		r = xsubrange.hi - xsubrange.lo
		return dflt / r

	def GetScaleForRangeY(self, ysubrange):
		# Default graph 50 pixels high
		dflt = 50.0
		r = ysubrange.hi - ysubrange.lo
		return dflt / r

	def GetScaleForRange(self, subrange):
		# Default graph 1000 pixels wide, 50 pixels high
		xscale = self.GetScaleForRangeX(subrange.x)
		yscale = self.GetScaleForRangeY(subrange.y)
		return XY(xscale, yscale)

	def PointEvent(self, cpu, time_from, time_to, hregions):
		text = "CPU: " + str(cpu)
		time_from = time_from.quantize(Decimal(1))
		rel_time_from = time_from - self.glb.StartTime(self.collection.machine_id)
		text = text + " Time: " + str(time_from) + " (+" + ToTimeStr(rel_time_from) + ")"
		self.point_label.setText(text)
		self.legend.Highlight(hregions)

	def RightClickEvent(self, cpu, hregion_times, pos):
		if not IsSelectable(self.glb.db, "calls", "WHERE parent_id >= 0"):
			return
		menu = QMenu(self.view)
		for hregion, time in hregion_times:
			thread_at_time = (hregion.exec_comm_id, hregion.thread_id, time)
			menu_text = "Show Call Tree for {} {}:{} at {}".format(hregion.comm, hregion.pid, hregion.tid, time)
			menu.addAction(CreateAction(menu_text, "Show Call Tree", lambda a=None, args=thread_at_time: self.RightClickSelect(args), self.view))
		menu.exec_(pos)

	def RightClickSelect(self, args):
		CallTreeWindow(self.glb, self.glb.mainwindow, thread_at_time=args)

	def NoPointEvent(self):
		self.point_label.setText("")
		self.legend.Highlight({})

	def RangeEvent(self, time_from, time_to):
		time_from = time_from.quantize(Decimal(1))
		time_to = time_to.quantize(Decimal(1))
		if time_to <= time_from:
			self.point_label.setText("")
			return
		rel_time_from = time_from - self.start_time
		rel_time_to = time_to - self.start_time
		text = " Time: " + str(time_from) + " (+" + ToTimeStr(rel_time_from) + ") to: " + str(time_to) + " (+" + ToTimeStr(rel_time_to) + ")"
		text = text + " duration: " + ToTimeStr(time_to - time_from)
		self.point_label.setText(text)

	def BackState(self):
		return (self.attrs.subrange, self.attrs.scale, self.selection_state, self.fwd_rect)

	def PushBackState(self):
		state = copy.deepcopy(self.BackState())
		self.back_state.append(state)
		self.back_button.setEnabled(True)

	def PopBackState(self):
		self.attrs.subrange, self.attrs.scale, self.selection_state, self.fwd_rect = self.back_state.pop()
		self.attrs.Update()
		if not self.back_state:
			self.back_button.setDisabled(True)

	def PushForwardState(self):
		state = copy.deepcopy(self.BackState())
		self.forward_state.append(state)
		self.forward_button.setEnabled(True)

	def PopForwardState(self):
		self.attrs.subrange, self.attrs.scale, self.selection_state, self.fwd_rect = self.forward_state.pop()
		self.attrs.Update()
		if not self.forward_state:
			self.forward_button.setDisabled(True)

	def Title(self):
		time_from = self.collection.xrangelo + Decimal(self.attrs.subrange.x.lo)
		time_to = self.collection.xrangelo + Decimal(self.attrs.subrange.x.hi)
		rel_time_from = time_from - self.start_time
		rel_time_to = time_to - self.start_time
		title = "+" + ToTimeStr(rel_time_from) + " to +" + ToTimeStr(rel_time_to)
		title = title + " (" + ToTimeStr(time_to - time_from) + ")"
		return title

	def Update(self):
		selected_subrange, selection_state = self.selection_state
		self.item.SetSelection(selection_state)
		self.item.SetBracket(self.fwd_rect)
		self.zoom_button.setDisabled(selected_subrange is None)
		self.GraphTitleChanged(self.Title())
		self.item.update(self.item.boundingRect())

	def Back(self):
		if not self.back_state:
			return
		self.PushForwardState()
		self.PopBackState()
		self.Update()

	def Forward(self):
		if not self.forward_state:
			return
		self.PushBackState()
		self.PopForwardState()
		self.Update()

	def SelectEvent(self, x0, x1, selection_state):
		if selection_state is None:
			selected_subrange = None
		else:
			if x1 - x0 < 1.0:
				x1 += 1.0
			selected_subrange = Subrange(x0, x1)
		self.selection_state = (selected_subrange, selection_state)
		self.zoom_button.setDisabled(selected_subrange is None)

	def Zoom(self):
		selected_subrange, selection_state = self.selection_state
		if selected_subrange is None:
			return
		self.fwd_rect = selection_state
		self.item.SetSelection(None)
		self.PushBackState()
		self.attrs.subrange.x = selected_subrange
		self.forward_state = []
		self.forward_button.setDisabled(True)
		self.selection_state = (None, None)
		self.fwd_rect = None
		self.attrs.scale.x = self.GetScaleForRangeX(self.attrs.subrange.x)
		self.attrs.Update()
		self.Update()

# Slow initialization - perform non-GUI initialization in a separate thread and put up a modal message box while waiting

class SlowInitClass():

	def __init__(self, glb, title, init_fn):
		self.init_fn = init_fn
		self.done = False
		self.result = None

		self.msg_box = QMessageBox(glb.mainwindow)
		self.msg_box.setText("Initializing " + title + ". Please wait.")
		self.msg_box.setWindowTitle("Initializing " + title)
		self.msg_box.setWindowIcon(glb.mainwindow.style().standardIcon(QStyle.SP_MessageBoxInformation))

		self.init_thread = Thread(self.ThreadFn, glb)
		self.init_thread.done.connect(lambda: self.Done(), Qt.QueuedConnection)

		self.init_thread.start()

	def Done(self):
		self.msg_box.done(0)

	def ThreadFn(self, glb):
		conn_name = "SlowInitClass" + str(os.getpid())
		db, dbname = glb.dbref.Open(conn_name)
		self.result = self.init_fn(db)
		self.done = True
		return (True, 0)

	def Result(self):
		while not self.done:
			self.msg_box.exec_()
		self.init_thread.wait()
		return self.result

def SlowInit(glb, title, init_fn):
	init = SlowInitClass(glb, title, init_fn)
	return init.Result()

# Time chart by CPU window

class TimeChartByCPUWindow(QMdiSubWindow):

	def __init__(self, glb, parent=None):
		super(TimeChartByCPUWindow, self).__init__(parent)

		self.glb = glb
		self.machine_id = glb.HostMachineId()
		self.collection_name = "SwitchGraphDataCollection " + str(self.machine_id)

		collection = LookupModel(self.collection_name)
		if collection is None:
			collection = SlowInit(glb, "Time Chart", self.Init)

		self.widget = SwitchGraphWidget(glb, collection, self)
		self.view = self.widget

		self.base_title = "Time Chart by CPU"
		self.setWindowTitle(self.base_title + self.widget.Title())
		self.widget.graph_title_changed.connect(self.GraphTitleChanged)

		self.setWidget(self.widget)

		AddSubWindow(glb.mainwindow.mdi_area, self, self.windowTitle())

	def Init(self, db):
		return LookupCreateModel(self.collection_name, lambda : SwitchGraphDataCollection(self.glb, db, self.machine_id))

	def GraphTitleChanged(self, title):
		self.setWindowTitle(self.base_title + " : " + title)

# Child data item  finder

class ChildDataItemFinder():

	def __init__(self, root):
		self.root = root
		self.value, self.direction, self.pattern, self.last_value, self.last_pattern = (None,) * 5
		self.rows = []
		self.pos = 0

	def FindSelect(self):
		self.rows = []
		if self.pattern:
			pattern = re.compile(self.value)
			for child in self.root.child_items:
				for column_data in child.data:
					if re.search(pattern, str(column_data)) is not None:
						self.rows.append(child.row)
						break
		else:
			for child in self.root.child_items:
				for column_data in child.data:
					if self.value in str(column_data):
						self.rows.append(child.row)
						break

	def FindValue(self):
		self.pos = 0
		if self.last_value != self.value or self.pattern != self.last_pattern:
			self.FindSelect()
		if not len(self.rows):
			return -1
		return self.rows[self.pos]

	def FindThread(self):
		if self.direction == 0 or self.value != self.last_value or self.pattern != self.last_pattern:
			row = self.FindValue()
		elif len(self.rows):
			if self.direction > 0:
				self.pos += 1
				if self.pos >= len(self.rows):
					self.pos = 0
			else:
				self.pos -= 1
				if self.pos < 0:
					self.pos = len(self.rows) - 1
			row = self.rows[self.pos]
		else:
			row = -1
		return (True, row)

	def Find(self, value, direction, pattern, context, callback):
		self.value, self.direction, self.pattern, self.last_value, self.last_pattern = (value, direction,pattern, self.value, self.pattern)
		# Use a thread so the UI is not blocked
		thread = Thread(self.FindThread)
		thread.done.connect(lambda row, t=thread, c=callback: self.FindDone(t, c, row), Qt.QueuedConnection)
		thread.start()

	def FindDone(self, thread, callback, row):
		callback(row)

# Number of database records to fetch in one go

glb_chunk_sz = 10000

# Background process for SQL data fetcher

class SQLFetcherProcess():

	def __init__(self, dbref, sql, buffer, head, tail, fetch_count, fetching_done, process_target, wait_event, fetched_event, prep):
		# Need a unique connection name
		conn_name = "SQLFetcher" + str(os.getpid())
		self.db, dbname = dbref.Open(conn_name)
		self.sql = sql
		self.buffer = buffer
		self.head = head
		self.tail = tail
		self.fetch_count = fetch_count
		self.fetching_done = fetching_done
		self.process_target = process_target
		self.wait_event = wait_event
		self.fetched_event = fetched_event
		self.prep = prep
		self.query = QSqlQuery(self.db)
		self.query_limit = 0 if "$$last_id$$" in sql else 2
		self.last_id = -1
		self.fetched = 0
		self.more = True
		self.local_head = self.head.value
		self.local_tail = self.tail.value

	def Select(self):
		if self.query_limit:
			if self.query_limit == 1:
				return
			self.query_limit -= 1
		stmt = self.sql.replace("$$last_id$$", str(self.last_id))
		QueryExec(self.query, stmt)

	def Next(self):
		if not self.query.next():
			self.Select()
			if not self.query.next():
				return None
		self.last_id = self.query.value(0)
		return self.prep(self.query)

	def WaitForTarget(self):
		while True:
			self.wait_event.clear()
			target = self.process_target.value
			if target > self.fetched or target < 0:
				break
			self.wait_event.wait()
		return target

	def HasSpace(self, sz):
		if self.local_tail <= self.local_head:
			space = len(self.buffer) - self.local_head
			if space > sz:
				return True
			if space >= glb_nsz:
				# Use 0 (or space < glb_nsz) to mean there is no more at the top of the buffer
				nd = pickle.dumps(0, pickle.HIGHEST_PROTOCOL)
				self.buffer[self.local_head : self.local_head + len(nd)] = nd
			self.local_head = 0
		if self.local_tail - self.local_head > sz:
			return True
		return False

	def WaitForSpace(self, sz):
		if self.HasSpace(sz):
			return
		while True:
			self.wait_event.clear()
			self.local_tail = self.tail.value
			if self.HasSpace(sz):
				return
			self.wait_event.wait()

	def AddToBuffer(self, obj):
		d = pickle.dumps(obj, pickle.HIGHEST_PROTOCOL)
		n = len(d)
		nd = pickle.dumps(n, pickle.HIGHEST_PROTOCOL)
		sz = n + glb_nsz
		self.WaitForSpace(sz)
		pos = self.local_head
		self.buffer[pos : pos + len(nd)] = nd
		self.buffer[pos + glb_nsz : pos + sz] = d
		self.local_head += sz

	def FetchBatch(self, batch_size):
		fetched = 0
		while batch_size > fetched:
			obj = self.Next()
			if obj is None:
				self.more = False
				break
			self.AddToBuffer(obj)
			fetched += 1
		if fetched:
			self.fetched += fetched
			with self.fetch_count.get_lock():
				self.fetch_count.value += fetched
			self.head.value = self.local_head
			self.fetched_event.set()

	def Run(self):
		while self.more:
			target = self.WaitForTarget()
			if target < 0:
				break
			batch_size = min(glb_chunk_sz, target - self.fetched)
			self.FetchBatch(batch_size)
		self.fetching_done.value = True
		self.fetched_event.set()

def SQLFetcherFn(*x):
	process = SQLFetcherProcess(*x)
	process.Run()

# SQL data fetcher

class SQLFetcher(QObject):

	done = Signal(object)

	def __init__(self, glb, sql, prep, process_data, parent=None):
		super(SQLFetcher, self).__init__(parent)
		self.process_data = process_data
		self.more = True
		self.target = 0
		self.last_target = 0
		self.fetched = 0
		self.buffer_size = 16 * 1024 * 1024
		self.buffer = Array(c_char, self.buffer_size, lock=False)
		self.head = Value(c_longlong)
		self.tail = Value(c_longlong)
		self.local_tail = 0
		self.fetch_count = Value(c_longlong)
		self.fetching_done = Value(c_bool)
		self.last_count = 0
		self.process_target = Value(c_longlong)
		self.wait_event = Event()
		self.fetched_event = Event()
		glb.AddInstanceToShutdownOnExit(self)
		self.process = Process(target=SQLFetcherFn, args=(glb.dbref, sql, self.buffer, self.head, self.tail, self.fetch_count, self.fetching_done, self.process_target, self.wait_event, self.fetched_event, prep))
		self.process.start()
		self.thread = Thread(self.Thread)
		self.thread.done.connect(self.ProcessData, Qt.QueuedConnection)
		self.thread.start()

	def Shutdown(self):
		# Tell the thread and process to exit
		self.process_target.value = -1
		self.wait_event.set()
		self.more = False
		self.fetching_done.value = True
		self.fetched_event.set()

	def Thread(self):
		if not self.more:
			return True, 0
		while True:
			self.fetched_event.clear()
			fetch_count = self.fetch_count.value
			if fetch_count != self.last_count:
				break
			if self.fetching_done.value:
				self.more = False
				return True, 0
			self.fetched_event.wait()
		count = fetch_count - self.last_count
		self.last_count = fetch_count
		self.fetched += count
		return False, count

	def Fetch(self, nr):
		if not self.more:
			# -1 inidcates there are no more
			return -1
		result = self.fetched
		extra = result + nr - self.target
		if extra > 0:
			self.target += extra
			# process_target < 0 indicates shutting down
			if self.process_target.value >= 0:
				self.process_target.value = self.target
			self.wait_event.set()
		return result

	def RemoveFromBuffer(self):
		pos = self.local_tail
		if len(self.buffer) - pos < glb_nsz:
			pos = 0
		n = pickle.loads(self.buffer[pos : pos + glb_nsz])
		if n == 0:
			pos = 0
			n = pickle.loads(self.buffer[0 : glb_nsz])
		pos += glb_nsz
		obj = pickle.loads(self.buffer[pos : pos + n])
		self.local_tail = pos + n
		return obj

	def ProcessData(self, count):
		for i in xrange(count):
			obj = self.RemoveFromBuffer()
			self.process_data(obj)
		self.tail.value = self.local_tail
		self.wait_event.set()
		self.done.emit(count)

# Fetch more records bar

class FetchMoreRecordsBar():

	def __init__(self, model, parent):
		self.model = model

		self.label = QLabel("Number of records (x " + "{:,}".format(glb_chunk_sz) + ") to fetch:")
		self.label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

		self.fetch_count = QSpinBox()
		self.fetch_count.setRange(1, 1000000)
		self.fetch_count.setValue(10)
		self.fetch_count.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

		self.fetch = QPushButton("Go!")
		self.fetch.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
		self.fetch.released.connect(self.FetchMoreRecords)

		self.progress = QProgressBar()
		self.progress.setRange(0, 100)
		self.progress.hide()

		self.done_label = QLabel("All records fetched")
		self.done_label.hide()

		self.spacer = QLabel("")

		self.close_button = QToolButton()
		self.close_button.setIcon(parent.style().standardIcon(QStyle.SP_DockWidgetCloseButton))
		self.close_button.released.connect(self.Deactivate)

		self.hbox = QHBoxLayout()
		self.hbox.setContentsMargins(0, 0, 0, 0)

		self.hbox.addWidget(self.label)
		self.hbox.addWidget(self.fetch_count)
		self.hbox.addWidget(self.fetch)
		self.hbox.addWidget(self.spacer)
		self.hbox.addWidget(self.progress)
		self.hbox.addWidget(self.done_label)
		self.hbox.addWidget(self.close_button)

		self.bar = QWidget()
		self.bar.setLayout(self.hbox)
		self.bar.show()

		self.in_progress = False
		self.model.progress.connect(self.Progress)

		self.done = False

		if not model.HasMoreRecords():
			self.Done()

	def Widget(self):
		return self.bar

	def Activate(self):
		self.bar.show()
		self.fetch.setFocus()

	def Deactivate(self):
		self.bar.hide()

	def Enable(self, enable):
		self.fetch.setEnabled(enable)
		self.fetch_count.setEnabled(enable)

	def Busy(self):
		self.Enable(False)
		self.fetch.hide()
		self.spacer.hide()
		self.progress.show()

	def Idle(self):
		self.in_progress = False
		self.Enable(True)
		self.progress.hide()
		self.fetch.show()
		self.spacer.show()

	def Target(self):
		return self.fetch_count.value() * glb_chunk_sz

	def Done(self):
		self.done = True
		self.Idle()
		self.label.hide()
		self.fetch_count.hide()
		self.fetch.hide()
		self.spacer.hide()
		self.done_label.show()

	def Progress(self, count):
		if self.in_progress:
			if count:
				percent = ((count - self.start) * 100) / self.Target()
				if percent >= 100:
					self.Idle()
				else:
					self.progress.setValue(percent)
		if not count:
			# Count value of zero means no more records
			self.Done()

	def FetchMoreRecords(self):
		if self.done:
			return
		self.progress.setValue(0)
		self.Busy()
		self.in_progress = True
		self.start = self.model.FetchMoreRecords(self.Target())

# Brance data model level two item

class BranchLevelTwoItem():

	def __init__(self, row, col, text, parent_item):
		self.row = row
		self.parent_item = parent_item
		self.data = [""] * (col + 1)
		self.data[col] = text
		self.level = 2

	def getParentItem(self):
		return self.parent_item

	def getRow(self):
		return self.row

	def childCount(self):
		return 0

	def hasChildren(self):
		return False

	def getData(self, column):
		return self.data[column]

# Brance data model level one item

class BranchLevelOneItem():

	def __init__(self, glb, row, data, parent_item):
		self.glb = glb
		self.row = row
		self.parent_item = parent_item
		self.child_count = 0
		self.child_items = []
		self.data = data[1:]
		self.dbid = data[0]
		self.level = 1
		self.query_done = False
		self.br_col = len(self.data) - 1

	def getChildItem(self, row):
		return self.child_items[row]

	def getParentItem(self):
		return self.parent_item

	def getRow(self):
		return self.row

	def Select(self):
		self.query_done = True

		if not self.glb.have_disassembler:
			return

		query = QSqlQuery(self.glb.db)

		QueryExec(query, "SELECT cpu, to_dso_id, to_symbol_id, to_sym_offset, short_name, long_name, build_id, sym_start, to_ip"
				  " FROM samples"
				  " INNER JOIN dsos ON samples.to_dso_id = dsos.id"
				  " INNER JOIN symbols ON samples.to_symbol_id = symbols.id"
				  " WHERE samples.id = " + str(self.dbid))
		if not query.next():
			return
		cpu = query.value(0)
		dso = query.value(1)
		sym = query.value(2)
		if dso == 0 or sym == 0:
			return
		off = query.value(3)
		short_name = query.value(4)
		long_name = query.value(5)
		build_id = query.value(6)
		sym_start = query.value(7)
		ip = query.value(8)

		QueryExec(query, "SELECT samples.dso_id, symbol_id, sym_offset, sym_start"
				  " FROM samples"
				  " INNER JOIN symbols ON samples.symbol_id = symbols.id"
				  " WHERE samples.id > " + str(self.dbid) + " AND cpu = " + str(cpu) +
				  " ORDER BY samples.id"
				  " LIMIT 1")
		if not query.next():
			return
		if query.value(0) != dso:
			# Cannot disassemble from one dso to another
			return
		bsym = query.value(1)
		boff = query.value(2)
		bsym_start = query.value(3)
		if bsym == 0:
			return
		tot = bsym_start + boff + 1 - sym_start - off
		if tot <= 0 or tot > 16384:
			return

		inst = self.glb.disassembler.Instruction()
		f = self.glb.FileFromNamesAndBuildId(short_name, long_name, build_id)
		if not f:
			return
		mode = 0 if Is64Bit(f) else 1
		self.glb.disassembler.SetMode(inst, mode)

		buf_sz = tot + 16
		buf = create_string_buffer(tot + 16)
		f.seek(sym_start + off)
		buf.value = f.read(buf_sz)
		buf_ptr = addressof(buf)
		i = 0
		while tot > 0:
			cnt, text = self.glb.disassembler.DisassembleOne(inst, buf_ptr, buf_sz, ip)
			if cnt:
				byte_str = tohex(ip).rjust(16)
				for k in xrange(cnt):
					byte_str += " %02x" % ord(buf[i])
					i += 1
				while k < 15:
					byte_str += "   "
					k += 1
				self.child_items.append(BranchLevelTwoItem(0, self.br_col, byte_str + " " + text, self))
				self.child_count += 1
			else:
				return
			buf_ptr += cnt
			tot -= cnt
			buf_sz -= cnt
			ip += cnt

	def childCount(self):
		if not self.query_done:
			self.Select()
			if not self.child_count:
				return -1
		return self.child_count

	def hasChildren(self):
		if not self.query_done:
			return True
		return self.child_count > 0

	def getData(self, column):
		return self.data[column]

# Brance data model root item

class BranchRootItem():

	def __init__(self):
		self.child_count = 0
		self.child_items = []
		self.level = 0

	def getChildItem(self, row):
		return self.child_items[row]

	def getParentItem(self):
		return None

	def getRow(self):
		return 0

	def childCount(self):
		return self.child_count

	def hasChildren(self):
		return self.child_count > 0

	def getData(self, column):
		return ""

# Calculate instructions per cycle

def CalcIPC(cyc_cnt, insn_cnt):
	if cyc_cnt and insn_cnt:
		ipc = Decimal(float(insn_cnt) / cyc_cnt)
		ipc = str(ipc.quantize(Decimal(".01"), rounding=ROUND_HALF_UP))
	else:
		ipc = "0"
	return ipc

# Branch data preparation

def BranchDataPrepBr(query, data):
	data.append(tohex(query.value(8)).rjust(16) + " " + query.value(9) + offstr(query.value(10)) +
			" (" + dsoname(query.value(11)) + ")" + " -> " +
			tohex(query.value(12)) + " " + query.value(13) + offstr(query.value(14)) +
			" (" + dsoname(query.value(15)) + ")")

def BranchDataPrepIPC(query, data):
	insn_cnt = query.value(16)
	cyc_cnt = query.value(17)
	ipc = CalcIPC(cyc_cnt, insn_cnt)
	data.append(insn_cnt)
	data.append(cyc_cnt)
	data.append(ipc)

def BranchDataPrep(query):
	data = []
	for i in xrange(0, 8):
		data.append(query.value(i))
	BranchDataPrepBr(query, data)
	return data

def BranchDataPrepWA(query):
	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, 8):
		data.append(query.value(i))
	BranchDataPrepBr(query, data)
	return data

def BranchDataWithIPCPrep(query):
	data = []
	for i in xrange(0, 8):
		data.append(query.value(i))
	BranchDataPrepIPC(query, data)
	BranchDataPrepBr(query, data)
	return data

def BranchDataWithIPCPrepWA(query):
	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, 8):
		data.append(query.value(i))
	BranchDataPrepIPC(query, data)
	BranchDataPrepBr(query, data)
	return data

# Branch data model

class BranchModel(TreeModel):

	progress = Signal(object)

	def __init__(self, glb, event_id, where_clause, parent=None):
		super(BranchModel, self).__init__(glb, None, parent)
		self.event_id = event_id
		self.more = True
		self.populated = 0
		self.have_ipc = IsSelectable(glb.db, "samples", columns = "insn_count, cyc_count")
		if self.have_ipc:
			select_ipc = ", insn_count, cyc_count"
			prep_fn = BranchDataWithIPCPrep
			prep_wa_fn = BranchDataWithIPCPrepWA
		else:
			select_ipc = ""
			prep_fn = BranchDataPrep
			prep_wa_fn = BranchDataPrepWA
		sql = ("SELECT samples.id, time, cpu, comm, pid, tid, branch_types.name,"
			" CASE WHEN in_tx = '0' THEN 'No' ELSE 'Yes' END,"
			" ip, symbols.name, sym_offset, dsos.short_name,"
			" to_ip, to_symbols.name, to_sym_offset, to_dsos.short_name"
			+ select_ipc +
			" FROM samples"
			" INNER JOIN comms ON comm_id = comms.id"
			" INNER JOIN threads ON thread_id = threads.id"
			" INNER JOIN branch_types ON branch_type = branch_types.id"
			" INNER JOIN symbols ON symbol_id = symbols.id"
			" INNER JOIN symbols to_symbols ON to_symbol_id = to_symbols.id"
			" INNER JOIN dsos ON samples.dso_id = dsos.id"
			" INNER JOIN dsos AS to_dsos ON samples.to_dso_id = to_dsos.id"
			" WHERE samples.id > $$last_id$$" + where_clause +
			" AND evsel_id = " + str(self.event_id) +
			" ORDER BY samples.id"
			" LIMIT " + str(glb_chunk_sz))
		if pyside_version_1 and sys.version_info[0] == 3:
			prep = prep_fn
		else:
			prep = prep_wa_fn
		self.fetcher = SQLFetcher(glb, sql, prep, self.AddSample)
		self.fetcher.done.connect(self.Update)
		self.fetcher.Fetch(glb_chunk_sz)

	def GetRoot(self):
		return BranchRootItem()

	def columnCount(self, parent=None):
		if self.have_ipc:
			return 11
		else:
			return 8

	def columnHeader(self, column):
		if self.have_ipc:
			return ("Time", "CPU", "Command", "PID", "TID", "Branch Type", "In Tx", "Insn Cnt", "Cyc Cnt", "IPC", "Branch")[column]
		else:
			return ("Time", "CPU", "Command", "PID", "TID", "Branch Type", "In Tx", "Branch")[column]

	def columnFont(self, column):
		if self.have_ipc:
			br_col = 10
		else:
			br_col = 7
		if column != br_col:
			return None
		return QFont("Monospace")

	def DisplayData(self, item, index):
		if item.level == 1:
			self.FetchIfNeeded(item.row)
		return item.getData(index.column())

	def AddSample(self, data):
		child = BranchLevelOneItem(self.glb, self.populated, data, self.root)
		self.root.child_items.append(child)
		self.populated += 1

	def Update(self, fetched):
		if not fetched:
			self.more = False
			self.progress.emit(0)
		child_count = self.root.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.root.child_count += count
			self.endInsertRows()
			self.progress.emit(self.root.child_count)

	def FetchMoreRecords(self, count):
		current = self.root.child_count
		if self.more:
			self.fetcher.Fetch(count)
		else:
			self.progress.emit(0)
		return current

	def HasMoreRecords(self):
		return self.more

# Report Variables

class ReportVars():

	def __init__(self, name = "", where_clause = "", limit = ""):
		self.name = name
		self.where_clause = where_clause
		self.limit = limit

	def UniqueId(self):
		return str(self.where_clause + ";" + self.limit)

# Branch window

class BranchWindow(QMdiSubWindow):

	def __init__(self, glb, event_id, report_vars, parent=None):
		super(BranchWindow, self).__init__(parent)

		model_name = "Branch Events " + str(event_id) +  " " + report_vars.UniqueId()

		self.model = LookupCreateModel(model_name, lambda: BranchModel(glb, event_id, report_vars.where_clause))

		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)

		self.fetch_bar = FetchMoreRecordsBar(self.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 + " Branch Events")

	def ResizeColumnToContents(self, column, n):
		# Using the view's resizeColumnToContents() here is extrememly slow
		# so implement a crude alternative
		mm = "MM" if column else "MMMM"
		font = self.view.font()
		metrics = QFontMetrics(font)
		max = 0
		for row in xrange(n):
			val = self.model.root.child_items[row].data[column]
			len = metrics.width(str(val) + mm)
			max = len if len > max else max
		val = self.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.model.root.child_count, 100)
		if n < 1:
			# No data yet, so connect a signal to notify when there is
			self.model.rowsInserted.connect(self.UpdateColumnWidths)
			return
		columns = self.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.model.rowsInserted.disconnect(self.UpdateColumnWidths)
		self.ResizeColumnsToContents()

	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()

# Line edit data item

class LineEditDataItem(object):

	def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""):
		self.glb = glb
		self.label = label
		self.placeholder_text = placeholder_text
		self.parent = parent
		self.id = id

		self.value = default

		self.widget = QLineEdit(default)
		self.widget.editingFinished.connect(self.Validate)
		self.widget.textChanged.connect(self.Invalidate)
		self.red = False
		self.error = ""
		self.validated = True

		if placeholder_text:
			self.widget.setPlaceholderText(placeholder_text)

	def TurnTextRed(self):
		if not self.red:
			palette = QPalette()
			palette.setColor(QPalette.Text,Qt.red)
			self.widget.setPalette(palette)
			self.red = True

	def TurnTextNormal(self):
		if self.red:
			palette = QPalette()
			self.widget.setPalette(palette)
			self.red = False

	def InvalidValue(self, value):
		self.value = ""
		self.TurnTextRed()
		self.error = self.label + " invalid value '" + value + "'"
		self.parent.ShowMessage(self.error)

	def Invalidate(self):
		self.validated = False

	def DoValidate(self, input_string):
		self.value = input_string.strip()

	def Validate(self):
		self.validated = True
		self.error = ""
		self.TurnTextNormal()
		self.parent.ClearMessage()
		input_string = self.widget.text()
		if not len(input_string.strip()):
			self.value = ""
			return
		self.DoValidate(input_string)

	def IsValid(self):
		if not self.validated:
			self.Validate()
		if len(self.error):
			self.parent.ShowMessage(self.error)
			return False
		return True

	def IsNumber(self, value):
		try:
			x = int(value)
		except:
			x = 0
		return str(x) == value

# Non-negative integer ranges dialog data item

class NonNegativeIntegerRangesDataItem(LineEditDataItem):

	def __init__(self, glb, label, placeholder_text, column_name, parent):
		super(NonNegativeIntegerRangesDataItem, self).__init__(glb, label, placeholder_text, parent)

		self.column_name = column_name

	def DoValidate(self, input_string):
		singles = []
		ranges = []
		for value in [x.strip() for x in input_string.split(",")]:
			if "-" in value:
				vrange = value.split("-")
				if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
					return self.InvalidValue(value)
				ranges.append(vrange)
			else:
				if not self.IsNumber(value):
					return self.InvalidValue(value)
				singles.append(value)
		ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges]
		if len(singles):
			ranges.append(self.column_name + " IN (" + ",".join(singles) + ")")
		self.value = " OR ".join(ranges)

# Positive integer dialog data item

class PositiveIntegerDataItem(LineEditDataItem):

	def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""):
		super(PositiveIntegerDataItem, self).__init__(glb, label, placeholder_text, parent, id, default)

	def DoValidate(self, input_string):
		if not self.IsNumber(input_string.strip()):
			return self.InvalidValue(input_string)
		value = int(input_string.strip())
		if value <= 0:
			return self.InvalidValue(input_string)
		self.value = str(value)

# Dialog data item converted and validated using a SQL table

class SQLTableDataItem(LineEditDataItem):

	def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent):
		super(SQLTableDataItem, self).__init__(glb, label, placeholder_text, parent)

		self.table_name = table_name
		self.match_column = match_column
		self.column_name1 = column_name1
		self.column_name2 = column_name2

	def ValueToIds(self, value):
		ids = []
		query = QSqlQuery(self.glb.db)
		stmt = "SELECT id FROM " + self.table_name + " WHERE " + self.match_column + " = '" + value + "'"
		ret = query.exec_(stmt)
		if ret:
			while query.next():
				ids.append(str(query.value(0)))
		return ids

	def DoValidate(self, input_string):
		all_ids = []
		for value in [x.strip() for x in input_string.split(",")]:
			ids = self.ValueToIds(value)
			if len(ids):
				all_ids.extend(ids)
			else:
				return self.InvalidValue(value)
		self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")"
		if self.column_name2:
			self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )"

# Sample time ranges dialog data item converted and validated using 'samples' SQL table

class SampleTimeRangesDataItem(LineEditDataItem):

	def __init__(self, glb, label, placeholder_text, column_name, parent):
		self.column_name = column_name

		self.last_id = 0
		self.first_time = 0
		self.last_time = 2 ** 64

		query = QSqlQuery(glb.db)
		QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1")
		if query.next():
			self.last_id = int(query.value(0))
		self.first_time = int(glb.HostStartTime())
		self.last_time = int(glb.HostFinishTime())
		if placeholder_text:
			placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time)

		super(SampleTimeRangesDataItem, self).__init__(glb, label, placeholder_text, parent)

	def IdBetween(self, query, lower_id, higher_id, order):
		QueryExec(query, "SELECT id FROM samples WHERE id > " + str(lower_id) + " AND id < " + str(higher_id) + " ORDER BY id " + order + " LIMIT 1")
		if query.next():
			return True, int(query.value(0))
		else:
			return False, 0

	def BinarySearchTime(self, lower_id, higher_id, target_time, get_floor):
		query = QSqlQuery(self.glb.db)
		while True:
			next_id = int((lower_id + higher_id) / 2)
			QueryExec(query, "SELECT time FROM samples WHERE id = " + str(next_id))
			if not query.next():
				ok, dbid = self.IdBetween(query, lower_id, next_id, "DESC")
				if not ok:
					ok, dbid = self.IdBetween(query, next_id, higher_id, "")
					if not ok:
						return str(higher_id)
				next_id = dbid
				QueryExec(query, "SELECT time FROM samples WHERE id = " + str(next_id))
			next_time = int(query.value(0))
			if get_floor:
				if target_time > next_time:
					lower_id = next_id
				else:
					higher_id = next_id
				if higher_id <= lower_id + 1:
					return str(higher_id)
			else:
				if target_time >= next_time:
					lower_id = next_id
				else:
					higher_id = next_id
				if higher_id <= lower_id + 1:
					return str(lower_id)

	def ConvertRelativeTime(self, val):
		mult = 1
		suffix = val[-2:]
		if suffix == "ms":
			mult = 1000000
		elif suffix == "us":
			mult = 1000
		elif suffix == "ns":
			mult = 1
		else:
			return val
		val = val[:-2].strip()
		if not self.IsNumber(val):
			return val
		val = int(val) * mult
		if val >= 0:
			val += self.first_time
		else:
			val += self.last_time
		return str(val)

	def ConvertTimeRange(self, vrange):
		if vrange[0] == "":
			vrange[0] = str(self.first_time)
		if vrange[1] == "":
			vrange[1] = str(self.last_time)
		vrange[0] = self.ConvertRelativeTime(vrange[0])
		vrange[1] = self.ConvertRelativeTime(vrange[1])
		if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
			return False
		beg_range = max(int(vrange[0]), self.first_time)
		end_range = min(int(vrange[1]), self.last_time)
		if beg_range > self.last_time or end_range < self.first_time:
			return False
		vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True)
		vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False)
		return True

	def AddTimeRange(self, value, ranges):
		n = value.count("-")
		if n == 1:
			pass
		elif n == 2:
			if value.split("-")[1].strip() == "":
				n = 1
		elif n == 3:
			n = 2
		else:
			return False
		pos = findnth(value, "-", n)
		vrange = [value[:pos].strip() ,value[pos+1:].strip()]
		if self.ConvertTimeRange(vrange):
			ranges.append(vrange)
			return True
		return False

	def DoValidate(self, input_string):
		ranges = []
		for value in [x.strip() for x in input_string.split(",")]:
			if not self.AddTimeRange(value, ranges):
				return self.InvalidValue(value)
		ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges]
		self.value = " OR ".join(ranges)

# Report Dialog Base

class ReportDialogBase(QDialog):

	def __init__(self, glb, title, items, partial, parent=None):
		super(ReportDialogBase, self).__init__(parent)

		self.glb = glb

		self.report_vars = ReportVars()

		self.setWindowTitle(title)
		self.setMinimumWidth(600)

		self.data_items = [x(glb, self) for x in items]

		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 = "", columns = "*"):
	query = QSqlQuery(db)
	try:
		QueryExec(query, "SELECT " + columns + " 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()

# 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, Qt.DisplayRole)
			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):

	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.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)

		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.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
		self.view.CopyCellsToClipboard = CopyTableCellsToClipboard

		self.context_menu = ContextMenu(self.view)

		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
			action = self.window_menu.addAction(label)
			action.setCheckable(True)
			action.setChecked(sub_window == self.mdi_area.activeSubWindow())
			action.triggered.connect(lambda a=None,x=nr: self.setActiveSubWindow(x))
			self.window_menu.addAction(action)
			nr += 1

	def setActiveSubWindow(self, nr):
		self.mdi_area.setActiveSubWindow(self.mdi_area.subWindowList()[nr - 1])

# Help text

glb_help_text = """
<h1>Contents</h1>
<style>
p.c1 {
    text-indent: 40px;
}
p.c2 {
    text-indent: 80px;
}
}
</style>
<p class=c1><a href=#reports>1. Reports</a></p>
<p class=c2><a href=#callgraph>1.1 Context-Sensitive Call Graph</a></p>
<p class=c2><a href=#calltree>1.2 Call Tree</a></p>
<p class=c2><a href=#allbranches>1.3 All branches</a></p>
<p class=c2><a href=#selectedbranches>1.4 Selected branches</a></p>
<p class=c2><a href=#topcallsbyelapsedtime>1.5 Top calls by elapsed time</a></p>
<p class=c1><a href=#charts>2. Charts</a></p>
<p class=c2><a href=#timechartbycpu>2.1 Time chart by CPU</a></p>
<p class=c1><a href=#tables>3. Tables</a></p>
<h1 id=reports>1. Reports</h1>
<h2 id=callgraph>1.1 Context-Sensitive Call Graph</h2>
The result is a GUI window with a tree representing a context-sensitive
call-graph. Expanding a couple of levels of the tree and adjusting column
widths to suit will display something like:
<pre>
                                         Call Graph: pt_example
Call Path                          Object      Count   Time(ns)  Time(%)  Branch Count   Branch Count(%)
v- ls
    v- 2638:2638
        v- _start                  ld-2.19.so    1     10074071   100.0         211135            100.0
          |- unknown               unknown       1        13198     0.1              1              0.0
          >- _dl_start             ld-2.19.so    1      1400980    13.9          19637              9.3
          >- _d_linit_internal     ld-2.19.so    1       448152     4.4          11094              5.3
          v-__libc_start_main@plt  ls            1      8211741    81.5         180397             85.4
             >- _dl_fixup          ld-2.19.so    1         7607     0.1            108              0.1
             >- __cxa_atexit       libc-2.19.so  1        11737     0.1             10              0.0
             >- __libc_csu_init    ls            1        10354     0.1             10              0.0
             |- _setjmp            libc-2.19.so  1            0     0.0              4              0.0
             v- main               ls            1      8182043    99.6         180254             99.9
</pre>
<h3>Points to note:</h3>
<ul>
<li>The top level is a command name (comm)</li>
<li>The next level is a thread (pid:tid)</li>
<li>Subsequent levels are functions</li>
<li>'Count' is the number of calls</li>
<li>'Time' is the elapsed time until the function returns</li>
<li>Percentages are relative to the level above</li>
<li>'Branch Count' is the total number of branches for that function and all functions that it calls
</ul>
<h3>Find</h3>
Ctrl-F displays a Find bar which finds function names by either an exact match or a pattern match.
The pattern matching symbols are ? for any character and * for zero or more characters.
<h2 id=calltree>1.2 Call Tree</h2>
The Call Tree report is very similar to the Context-Sensitive Call Graph, but the data is not aggregated.
Also the 'Count' column, which would be always 1, is replaced by the 'Call Time'.
<h2 id=allbranches>1.3 All branches</h2>
The All branches report displays all branches in chronological order.
Not all data is fetched immediately. More records can be fetched using the Fetch bar provided.
<h3>Disassembly</h3>
Open a branch to display disassembly. This only works if:
<ol>
<li>The disassembler is available. Currently, only Intel XED is supported - see <a href=#xed>Intel XED Setup</a></li>
<li>The object code is available. Currently, only the perf build ID cache is searched for object code.
The default directory ~/.debug can be overridden by setting environment variable PERF_BUILDID_DIR.
One exception is kcore where the DSO long name is used (refer dsos_view on the Tables menu),
or alternatively, set environment variable PERF_KCORE to the kcore file name.</li>
</ol>
<h4 id=xed>Intel XED Setup</h4>
To use Intel XED, libxed.so must be present.  To build and install libxed.so:
<pre>
git clone https://github.com/intelxed/mbuild.git mbuild
git clone https://github.com/intelxed/xed
cd xed
./mfile.py --share
sudo ./mfile.py --prefix=/usr/local install
sudo ldconfig
</pre>
<h3>Instructions per Cycle (IPC)</h3>
If available, IPC information is displayed in columns 'insn_cnt', 'cyc_cnt' and 'IPC'.
<p><b>Intel PT note:</b> The information applies to the blocks of code ending with, and including, that branch.
Due to the granularity of timing information, the number of cycles for some code blocks will not be known.
In that case, 'insn_cnt', 'cyc_cnt' and 'IPC' are zero, but when 'IPC' is displayed it covers the period
since the previous displayed 'IPC'.
<h3>Find</h3>
Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match.
Refer to Python documentation for the regular expression syntax.
All columns are searched, but only currently fetched rows are searched.
<h2 id=selectedbranches>1.4 Selected branches</h2>
This is the same as the <a href=#allbranches>All branches</a> report but with the data reduced
by various selection criteria. A dialog box displays available criteria which are AND'ed together.
<h3>1.4.1 Time ranges</h3>
The time ranges hint text shows the total time range. Relative time ranges can also be entered in
ms, us or ns. Also, negative values are relative to the end of trace.  Examples:
<pre>
	81073085947329-81073085958238	From 81073085947329 to 81073085958238
	100us-200us		From 100us to 200us
	10ms-			From 10ms to the end
	-100ns			The first 100ns
	-10ms-			The last 10ms
</pre>
N.B. Due to the granularity of timestamps, there could be no branches in any given time range.
<h2 id=topcallsbyelapsedtime>1.5 Top calls by elapsed time</h2>
The Top calls by elapsed time report displays calls in descending order of time elapsed between when the function was called and when it returned.
The data is reduced by various selection criteria. A dialog box displays available criteria which are AND'ed together.
If not all data is fetched, a Fetch bar is provided. Ctrl-F displays a Find bar.
<h1 id=charts>2. Charts</h1>
<h2 id=timechartbycpu>2.1 Time chart by CPU</h2>
This chart displays context switch information when that data is available. Refer to context_switches_view on the Tables menu.
<h3>Features</h3>
<ol>
<li>Mouse over to highight the task and show the time</li>
<li>Drag the mouse to select a region and zoom by pushing the Zoom button</li>
<li>Go back and forward by pressing the arrow buttons</li>
<li>If call information is available, right-click to show a call tree opened to that task and time.
Note, the call tree may take some time to appear, and there may not be call information for the task or time selected.
</li>
</ol>
<h3>Important</h3>
The graph can be misleading in the following respects:
<ol>
<li>The graph shows the first task on each CPU as running from the beginning of the time range.
Because tracing might start on different CPUs at different times, that is not necessarily the case.
Refer to context_switches_view on the Tables menu to understand what data the graph is based upon.</li>
<li>Similarly, the last task on each CPU can be showing running longer than it really was.
Again, refer to context_switches_view on the Tables menu to understand what data the graph is based upon.</li>
<li>When the mouse is over a task, the highlighted task might not be visible on the legend without scrolling if the legend does not fit fully in the window</li>
</ol>
<h1 id=tables>3. Tables</h1>
The Tables menu shows all tables and views in the database. Most tables have an associated view
which displays the information in a more friendly way. Not all data for large tables is fetched
immediately. More records can be fetched using the Fetch bar provided. Columns can be sorted,
but that can be slow for large tables.
<p>There are also tables of database meta-information.
For SQLite3 databases, the sqlite_master table is included.
For PostgreSQL databases, information_schema.tables/views/columns are included.
<h3>Find</h3>
Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match.
Refer to Python documentation for the regular expression syntax.
All columns are searched, but only currently fetched rows are searched.
<p>N.B. Results are found in id order, so if the table is re-ordered, find-next and find-previous
will go to the next/previous result in id order, instead of display order.
"""

# Help window

class HelpWindow(QMdiSubWindow):

	def __init__(self, glb, parent=None):
		super(HelpWindow, self).__init__(parent)

		self.text = QTextBrowser()
		self.text.setHtml(glb_help_text)
		self.text.setReadOnly(True)
		self.text.setOpenExternalLinks(True)

		self.setWidget(self.text)

		AddSubWindow(glb.mainwindow.mdi_area, self, "Exported SQL Viewer Help")

# Main window that only displays the help text

class HelpOnlyWindow(QMainWindow):

	def __init__(self, parent=None):
		super(HelpOnlyWindow, self).__init__(parent)

		self.setMinimumSize(200, 100)
		self.resize(800, 600)
		self.setWindowTitle("Exported SQL Viewer Help")
		self.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation))

		self.text = QTextBrowser()
		self.text.setHtml(glb_help_text)
		self.text.setReadOnly(True)
		self.text.setOpenExternalLinks(True)

		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):
	font = widget.font()
	sz = font.pointSize()
	font.setPointSize(sz + diff)
	widget.setFont(font)

def ShrinkFont(widget):
	ResizeFont(widget, -1)

def EnlargeFont(widget):
	ResizeFont(widget, 1)

# Unique name for sub-windows

def NumberedWindowName(name, nr):
	if nr > 1:
		name += " <" + str(nr) + ">"
	return name

def UniqueSubWindowName(mdi_area, name):
	nr = 1
	while True:
		unique_name = NumberedWindowName(name, nr)
		ok = True
		for sub_window in mdi_area.subWindowList():
			if sub_window.name == unique_name:
				ok = False
				break
		if ok:
			return unique_name
		nr += 1

# Add a sub-window

def AddSubWindow(mdi_area, sub_window, name):
	unique_name = UniqueSubWindowName(mdi_area, name)
	sub_window.setMinimumSize(200, 100)
	sub_window.resize(800, 600)
	sub_window.setWindowTitle(unique_name)
	sub_window.setAttribute(Qt.WA_DeleteOnClose)
	sub_window.setWindowIcon(sub_window.style().standardIcon(QStyle.SP_FileIcon))
	sub_window.name = unique_name
	mdi_area.addSubWindow(sub_window)
	sub_window.show()

# Main window

class MainWindow(QMainWindow):

	def __init__(self, glb, parent=None):
		super(MainWindow, self).__init__(parent)

		self.glb = glb

		self.setWindowTitle("Exported SQL Viewer: " + glb.dbname)
		self.setWindowIcon(self.style().standardIcon(QStyle.SP_ComputerIcon))
		self.setMinimumSize(200, 100)

		self.mdi_area = QMdiArea()
		self.mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
		self.mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

		self.setCentralWidget(self.mdi_area)

		menu = self.menuBar()

		file_menu = menu.addMenu("&File")
		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+-")]))
		edit_menu.addAction(CreateAction("&Enlarge Font", "Make text bigger", self.EnlargeFont, self, [QKeySequence("Ctrl++")]))

		reports_menu = menu.addMenu("&Reports")
		if IsSelectable(glb.db, "calls"):
			reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self))

		if IsSelectable(glb.db, "calls", "WHERE parent_id >= 0"):
			reports_menu.addAction(CreateAction("Call &Tree", "Create a new window containing a call tree", self.NewCallTree, self))

		self.EventMenu(GetEventList(glb.db), reports_menu)

		if IsSelectable(glb.db, "calls"):
			reports_menu.addAction(CreateAction("&Top calls by elapsed time", "Create a new window displaying top calls by elapsed time", self.NewTopCalls, self))

		if IsSelectable(glb.db, "context_switches"):
			charts_menu = menu.addMenu("&Charts")
			charts_menu.addAction(CreateAction("&Time chart by CPU", "Create a new window displaying time charts by CPU", self.TimeChartByCPU, self))

		self.TableMenu(GetTableList(glb), menu)

		self.window_menu = WindowMenu(self.mdi_area, menu)

		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()
		if win:
			try:
				win.find_bar.Activate()
			except:
				pass

	def FetchMoreRecords(self):
		win = self.mdi_area.activeSubWindow()
		if win:
			try:
				win.fetch_bar.Activate()
			except:
				pass

	def ShrinkFont(self):
		self.Try(ShrinkFont)

	def EnlargeFont(self):
		self.Try(EnlargeFont)

	def EventMenu(self, events, reports_menu):
		branches_events = 0
		for event in events:
			event = event.split(":")[0]
			if event == "branches":
				branches_events += 1
		dbid = 0
		for event in events:
			dbid += 1
			event = event.split(":")[0]
			if event == "branches":
				label = "All branches" if branches_events == 1 else "All branches " + "(id=" + dbid + ")"
				reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda a=None,x=dbid: self.NewBranchView(x), self))
				label = "Selected branches" if branches_events == 1 else "Selected branches " + "(id=" + dbid + ")"
				reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda a=None,x=dbid: self.NewSelectedBranchView(x), self))

	def TimeChartByCPU(self):
		TimeChartByCPUWindow(self.glb, self)

	def TableMenu(self, tables, menu):
		table_menu = menu.addMenu("&Tables")
		for table in tables:
			table_menu.addAction(CreateAction(table, "Create a new window containing a table view", lambda a=None,t=table: self.NewTableView(t), self))

	def NewCallGraph(self):
		CallGraphWindow(self.glb, self)

	def NewCallTree(self):
		CallTreeWindow(self.glb, self)

	def NewTopCalls(self):
		dialog = TopCallsDialog(self.glb, self)
		ret = dialog.exec_()
		if ret:
			TopCallsWindow(self.glb, dialog.report_vars, self)

	def NewBranchView(self, event_id):
		BranchWindow(self.glb, event_id, ReportVars(), self)

	def NewSelectedBranchView(self, event_id):
		dialog = SelectedBranchDialog(self.glb, self)
		ret = dialog.exec_()
		if ret:
			BranchWindow(self.glb, event_id, dialog.report_vars, self)

	def NewTableView(self, table_name):
		TableWindow(self.glb, table_name, self)

	def Help(self):
		HelpWindow(self.glb, self)

	def About(self):
		dialog = AboutDialog(self.glb, self)
		dialog.exec_()

# XED Disassembler

class xed_state_t(Structure):

	_fields_ = [
		("mode", c_int),
		("width", c_int)
	]

class XEDInstruction():

	def __init__(self, libxed):
		# Current xed_decoded_inst_t structure is 192 bytes. Use 512 to allow for future expansion
		xedd_t = c_byte * 512
		self.xedd = xedd_t()
		self.xedp = addressof(self.xedd)
		libxed.xed_decoded_inst_zero(self.xedp)
		self.state = xed_state_t()
		self.statep = addressof(self.state)
		# Buffer for disassembled instruction text
		self.buffer = create_string_buffer(256)
		self.bufferp = addressof(self.buffer)

class LibXED():

	def __init__(self):
		try:
			self.libxed = CDLL("libxed.so")
		except:
			self.libxed = None
		if not self.libxed:
			self.libxed = CDLL("/usr/local/lib/libxed.so")

		self.xed_tables_init = self.libxed.xed_tables_init
		self.xed_tables_init.restype = None
		self.xed_tables_init.argtypes = []

		self.xed_decoded_inst_zero = self.libxed.xed_decoded_inst_zero
		self.xed_decoded_inst_zero.restype = None
		self.xed_decoded_inst_zero.argtypes = [ c_void_p ]

		self.xed_operand_values_set_mode = self.libxed.xed_operand_values_set_mode
		self.xed_operand_values_set_mode.restype = None
		self.xed_operand_values_set_mode.argtypes = [ c_void_p, c_void_p ]

		self.xed_decoded_inst_zero_keep_mode = self.libxed.xed_decoded_inst_zero_keep_mode
		self.xed_decoded_inst_zero_keep_mode.restype = None
		self.xed_decoded_inst_zero_keep_mode.argtypes = [ c_void_p ]

		self.xed_decode = self.libxed.xed_decode
		self.xed_decode.restype = c_int
		self.xed_decode.argtypes = [ c_void_p, c_void_p, c_uint ]

		self.xed_format_context = self.libxed.xed_format_context
		self.xed_format_context.restype = c_uint
		self.xed_format_context.argtypes = [ c_int, c_void_p, c_void_p, c_int, c_ulonglong, c_void_p, c_void_p ]

		self.xed_tables_init()

	def Instruction(self):
		return XEDInstruction(self)

	def SetMode(self, inst, mode):
		if mode:
			inst.state.mode = 4 # 32-bit
			inst.state.width = 4 # 4 bytes
		else:
			inst.state.mode = 1 # 64-bit
			inst.state.width = 8 # 8 bytes
		self.xed_operand_values_set_mode(inst.xedp, inst.statep)

	def DisassembleOne(self, inst, bytes_ptr, bytes_cnt, ip):
		self.xed_decoded_inst_zero_keep_mode(inst.xedp)
		err = self.xed_decode(inst.xedp, bytes_ptr, bytes_cnt)
		if err:
			return 0, ""
		# Use AT&T mode (2), alternative is Intel (3)
		ok = self.xed_format_context(2, inst.xedp, inst.bufferp, sizeof(inst.buffer), ip, 0, 0)
		if not ok:
			return 0, ""
		if sys.version_info[0] == 2:
			result = inst.buffer.value
		else:
			result = inst.buffer.value.decode()
		# Return instruction length and the disassembled instruction text
		# For now, assume the length is in byte 166
		return inst.xedd[166], result

def TryOpen(file_name):
	try:
		return open(file_name, "rb")
	except:
		return None

def Is64Bit(f):
	result = sizeof(c_void_p)
	# ELF support only
	pos = f.tell()
	f.seek(0)
	header = f.read(7)
	f.seek(pos)
	magic = header[0:4]
	if sys.version_info[0] == 2:
		eclass = ord(header[4])
		encoding = ord(header[5])
		version = ord(header[6])
	else:
		eclass = header[4]
		encoding = header[5]
		version = header[6]
	if magic == chr(127) + "ELF" and eclass > 0 and eclass < 3 and encoding > 0 and encoding < 3 and version == 1:
		result = True if eclass == 2 else False
	return result

# Global data

class Glb():

	def __init__(self, dbref, db, dbname):
		self.dbref = dbref
		self.db = db
		self.dbname = dbname
		self.home_dir = os.path.expanduser("~")
		self.buildid_dir = os.getenv("PERF_BUILDID_DIR")
		if self.buildid_dir:
			self.buildid_dir += "/.build-id/"
		else:
			self.buildid_dir = self.home_dir + "/.debug/.build-id/"
		self.app = None
		self.mainwindow = None
		self.instances_to_shutdown_on_exit = weakref.WeakSet()
		try:
			self.disassembler = LibXED()
			self.have_disassembler = True
		except:
			self.have_disassembler = False
		self.host_machine_id = 0
		self.host_start_time = 0
		self.host_finish_time = 0

	def FileFromBuildId(self, build_id):
		file_name = self.buildid_dir + build_id[0:2] + "/" + build_id[2:] + "/elf"
		return TryOpen(file_name)

	def FileFromNamesAndBuildId(self, short_name, long_name, build_id):
		# Assume current machine i.e. no support for virtualization
		if short_name[0:7] == "[kernel" and os.path.basename(long_name) == "kcore":
			file_name = os.getenv("PERF_KCORE")
			f = TryOpen(file_name) if file_name else None
			if f:
				return f
			# For now, no special handling if long_name is /proc/kcore
			f = TryOpen(long_name)
			if f:
				return f
		f = self.FileFromBuildId(build_id)
		if f:
			return f
		return None

	def AddInstanceToShutdownOnExit(self, instance):
		self.instances_to_shutdown_on_exit.add(instance)

	# Shutdown any background processes or threads
	def ShutdownInstances(self):
		for x in self.instances_to_shutdown_on_exit:
			try:
				x.Shutdown()
			except:
				pass

	def GetHostMachineId(self):
		query = QSqlQuery(self.db)
		QueryExec(query, "SELECT id FROM machines WHERE pid = -1")
		if query.next():
			self.host_machine_id = query.value(0)
		else:
			self.host_machine_id = 0
		return self.host_machine_id

	def HostMachineId(self):
		if self.host_machine_id:
			return self.host_machine_id
		return self.GetHostMachineId()

	def SelectValue(self, sql):
		query = QSqlQuery(self.db)
		try:
			QueryExec(query, sql)
		except:
			return None
		if query.next():
			return Decimal(query.value(0))
		return None

	def SwitchesMinTime(self, machine_id):
		return self.SelectValue("SELECT time"
					" FROM context_switches"
					" WHERE time != 0 AND machine_id = " + str(machine_id) +
					" ORDER BY id LIMIT 1")

	def SwitchesMaxTime(self, machine_id):
		return self.SelectValue("SELECT time"
					" FROM context_switches"
					" WHERE time != 0 AND machine_id = " + str(machine_id) +
					" ORDER BY id DESC LIMIT 1")

	def SamplesMinTime(self, machine_id):
		return self.SelectValue("SELECT time"
					" FROM samples"
					" WHERE time != 0 AND machine_id = " + str(machine_id) +
					" ORDER BY id LIMIT 1")

	def SamplesMaxTime(self, machine_id):
		return self.SelectValue("SELECT time"
					" FROM samples"
					" WHERE time != 0 AND machine_id = " + str(machine_id) +
					" ORDER BY id DESC LIMIT 1")

	def CallsMinTime(self, machine_id):
		return self.SelectValue("SELECT calls.call_time"
					" FROM calls"
					" INNER JOIN threads ON threads.thread_id = calls.thread_id"
					" WHERE calls.call_time != 0 AND threads.machine_id = " + str(machine_id) +
					" ORDER BY calls.id LIMIT 1")

	def CallsMaxTime(self, machine_id):
		return self.SelectValue("SELECT calls.return_time"
					" FROM calls"
					" INNER JOIN threads ON threads.thread_id = calls.thread_id"
					" WHERE calls.return_time != 0 AND threads.machine_id = " + str(machine_id) +
					" ORDER BY calls.return_time DESC LIMIT 1")

	def GetStartTime(self, machine_id):
		t0 = self.SwitchesMinTime(machine_id)
		t1 = self.SamplesMinTime(machine_id)
		t2 = self.CallsMinTime(machine_id)
		if t0 is None or (not(t1 is None) and t1 < t0):
			t0 = t1
		if t0 is None or (not(t2 is None) and t2 < t0):
			t0 = t2
		return t0

	def GetFinishTime(self, machine_id):
		t0 = self.SwitchesMaxTime(machine_id)
		t1 = self.SamplesMaxTime(machine_id)
		t2 = self.CallsMaxTime(machine_id)
		if t0 is None or (not(t1 is None) and t1 > t0):
			t0 = t1
		if t0 is None or (not(t2 is None) and t2 > t0):
			t0 = t2
		return t0

	def HostStartTime(self):
		if self.host_start_time:
			return self.host_start_time
		self.host_start_time = self.GetStartTime(self.HostMachineId())
		return self.host_start_time

	def HostFinishTime(self):
		if self.host_finish_time:
			return self.host_finish_time
		self.host_finish_time = self.GetFinishTime(self.HostMachineId())
		return self.host_finish_time

	def StartTime(self, machine_id):
		if machine_id == self.HostMachineId():
			return self.HostStartTime()
		return self.GetStartTime(machine_id)

	def FinishTime(self, machine_id):
		if machine_id == self.HostMachineId():
			return self.HostFinishTime()
		return self.GetFinishTime(machine_id)

# Database reference

class DBRef():

	def __init__(self, is_sqlite3, dbname):
		self.is_sqlite3 = is_sqlite3
		self.dbname = dbname
		self.TRUE = "TRUE"
		self.FALSE = "FALSE"
		# SQLite prior to version 3.23 does not support TRUE and FALSE
		if self.is_sqlite3:
			self.TRUE = "1"
			self.FALSE = "0"

	def Open(self, connection_name):
		dbname = self.dbname
		if self.is_sqlite3:
			db = QSqlDatabase.addDatabase("QSQLITE", connection_name)
		else:
			db = QSqlDatabase.addDatabase("QPSQL", connection_name)
			opts = dbname.split()
			for opt in opts:
				if "=" in opt:
					opt = opt.split("=")
					if opt[0] == "hostname":
						db.setHostName(opt[1])
					elif opt[0] == "port":
						db.setPort(int(opt[1]))
					elif opt[0] == "username":
						db.setUserName(opt[1])
					elif opt[0] == "password":
						db.setPassword(opt[1])
					elif opt[0] == "dbname":
						dbname = opt[1]
				else:
					dbname = opt

		db.setDatabaseName(dbname)
		if not db.open():
			raise Exception("Failed to open database " + dbname + " error: " + db.lastError().text())
		return db, dbname

# Main

def Main():
	usage_str =	"exported-sql-viewer.py [--pyside-version-1] <database name>\n" \
			"   or: exported-sql-viewer.py --help-only"
	ap = argparse.ArgumentParser(usage = usage_str, add_help = False)
	ap.add_argument("--pyside-version-1", action='store_true')
	ap.add_argument("dbname", nargs="?")
	ap.add_argument("--help-only", action='store_true')
	args = ap.parse_args()

	if args.help_only:
		app = QApplication(sys.argv)
		mainwindow = HelpOnlyWindow()
		mainwindow.show()
		err = app.exec_()
		sys.exit(err)

	dbname = args.dbname
	if dbname is None:
		ap.print_usage()
		print("Too few arguments")
		sys.exit(1)

	is_sqlite3 = False
	try:
		f = open(dbname, "rb")
		if f.read(15) == b'SQLite format 3':
			is_sqlite3 = True
		f.close()
	except:
		pass

	dbref = DBRef(is_sqlite3, dbname)
	db, dbname = dbref.Open("main")
	glb = Glb(dbref, db, dbname)
	app = QApplication(sys.argv)
	glb.app = app
	mainwindow = MainWindow(glb)
	glb.mainwindow = mainwindow
	mainwindow.show()
	err = app.exec_()
	glb.ShutdownInstances()
	db.close()
	sys.exit(err)

if __name__ == "__main__":
	Main()
