class FECScheduleSheet(Sheet): "A sheet to display the list of itemized schedules in a filing." rowtype = "schedules" columns = [ ColumnAttr("schedule", "schedule_name", width=14), ColumnAttr("name", width=0), ColumnAttr("size", type=int), ] nKeys = 1 @asyncthread def reload(self): self.rows = [] for schedule_name in self.source.keys(): vs = FECItemizationSheet( joinSheetnames(self.name, schedule_name), schedule_name=schedule_name, source=self.source[schedule_name], size=len(self.source[schedule_name]), ) self.addRow(vs)
class ProfileSheet(Sheet): columns = [ Column('funcname', getter=lambda col, row: codestr(row.code)), Column('filename', getter=lambda col, row: os.path.split(row.code.co_filename)[-1] if not isinstance(row.code, str) else ''), Column('linenum', type=int, getter=lambda col, row: row.code.co_firstlineno if not isinstance(row.code, str) else None), Column('inlinetime_us', type=int, getter=lambda col, row: row.inlinetime * 1000000), Column('totaltime_us', type=int, getter=lambda col, row: row.totaltime * 1000000), ColumnAttr('callcount', type=int), ColumnAttr('reccallcount', type=int), ColumnAttr('calls'), Column('callers', getter=lambda col, row: col.sheet.callers[row.code]), ] nKeys = 3 def reload(self): self.rows = self.source self.orderBy(self.column('inlinetime_us'), reverse=True) self.callers = collections.defaultdict( list) # [row.code] -> list(code) for r in self.rows: calls = getattr(r, 'calls', None) if calls: for callee in calls: self.callers[callee.code].append(r)
class StaticFrameIndexSheet(IndexSheet): rowtype = 'sheets' columns = [ Column('sheet', getter=lambda col, row: row.source.name), ColumnAttr('name', width=0), ColumnAttr('nRows', type=int), ColumnAttr('nCols', type=int), ] def iterload(self): for sheetname in self.source.keys(): # this will combine self.name, sheetname into one name yield StaticFrameSheet(self.name, sheetname, source=self.source[sheetname])
class ThreadsSheet(Sheet): rowtype = 'threads' precious = False columns = [ ColumnAttr('name'), Column('process_time', type=float, getter=lambda col, row: elapsed_s(row)), ColumnAttr('profile'), ColumnAttr('status'), ColumnAttr('exception'), ] def reload(self): self.rows = vd.threads
class OptionsSheet(Sheet): _rowtype = Option # rowdef: Option rowtype = 'options' precious = False columns = ( ColumnAttr('option', 'name'), Column( 'value', getter=lambda col, row: col.sheet.diffOption(row.name), setter=lambda col, row, val: options.set(row.name, val, col.sheet. source), ), Column('default', getter=lambda col, row: options.get(row.name, 'global')), Column( 'description', width=40, getter=lambda col, row: options._get(row.name, 'global').helpstr), ColumnAttr('replayable'), ) colorizers = [ CellColorizer( 3, None, lambda s, c, r, v: v.value if r and c in s.columns[1:3] and r.name.startswith('color_') else None), ] nKeys = 1 def diffOption(self, optname): val = options.get(optname, self.source) default = options.get(optname, 'global') return val if val != default else '' def editOption(self, row): currentValue = options.get(row.name, self.source) vd.addUndo(options.set, row.name, currentValue, self.source) if isinstance(row.value, bool): options.set(row.name, not currentValue, self.source) else: options.set(row.name, self.editCell(1, value=currentValue), self.source) def reload(self): self.rows = [] for k in options.keys(): opt = options._get(k) self.addRow(opt) self.columns[ 1].name = 'global_value' if self.source == 'override' else 'sheet_value'
class ColumnsSheet(Sheet): rowtype = 'columns' _rowtype = Column _coltype = ColumnAttr precious = False class ValueColumn(Column): 'passthrough to the value on the source cursorRow' def calcValue(self, srcCol): return srcCol.getDisplayValue(srcCol.sheet.cursorRow) def setValue(self, srcCol, val): srcCol.setValue(srcCol.sheet.cursorRow, val) columns = [ ColumnAttr('sheet', type=str), ColumnAttr('name', width=options.default_width), ColumnAttr('width', type=int), ColumnEnum('type', getGlobals(), default=anytype), ColumnAttr('fmtstr'), ValueColumn('value', width=options.default_width), Column('expr', getter=lambda col, row: getattr(row, 'expr', ''), setter=lambda col, row, val: setattr(row, 'expr', val)), ] nKeys = 2 colorizers = [ RowColorizer(7, 'color_key_col', lambda s, c, r, v: r and r.keycol), RowColorizer(8, 'color_hidden_col', lambda s, c, r, v: r and r.hidden), ] def reload(self): if len(self.source) == 1: self.rows = self.source[0].columns self.cursorRowIndex = self.source[0].cursorColIndex self.columns[0].hide() # hide 'sheet' column if only one sheet else: self.rows = [ col for vs in self.source for col in vs.visibleCols if vs is not self ] def newRow(self): c = type(self.source[0])._coltype() c.sheet = self.source[0] return c
class SheetsSheet(IndexSheet): columns = [ ColumnAttr('name'), ColumnAttr('type', '__class__.__name__'), ColumnAttr('shortcut'), ColumnAttr('nRows', type=int), ColumnAttr('nCols', type=int), ColumnAttr('nVisibleCols', type=int), ColumnAttr('cursorDisplay'), ColumnAttr('keyColNames'), ColumnAttr('source'), ColumnAttr('progressPct'), # ColumnAttr('threads', 'currentThreads', type=vlen), ] nKeys = 1 def reload(self): self.rows = self.source
class VisiDataSheet(IndexSheet): rowtype = 'metasheets' precious = False columns = [ ColumnAttr('items', 'nRows', type=int), ColumnAttr('name', width=0), ColumnAttr('description', width=50), ColumnAttr('command', 'longname', width=0), ColumnAttr('shortcut', 'shortcut_en', width=11), ] nKeys = 0 def reload(self): self.rows = [] for vdattr, sheetname, longname, shortcut, desc in [ ('currentDirSheet', '.', 'open-dir-current', '', 'DirSheet for the current directory'), ('sheetsSheet', 'sheets', 'sheets-stack', 'Shift+S', 'current sheet stack'), ('allSheetsSheet', 'sheets_all', 'sheets-all', 'g Shift+S', 'all sheets ever opened'), ('cmdlog', 'cmdlog', 'cmdlog-all', 'g Shift+D', 'log of all commands this session'), ('globalOptionsSheet', 'options_global', 'open-global', 'g Shift+O', 'default option values applying to every sheet'), ('recentErrorsSheet', 'errors', 'open-errors', 'Ctrl+E', 'stacktrace of most recent error'), ('statusHistorySheet', 'statuses', 'open-statuses', 'Ctrl+P', 'status messages from current session'), ('threadsSheet', 'threads', 'open-threads', 'Ctrl+T', 'threads and profiling'), ('pluginsSheet', 'plugins', 'open-plugins', '', 'plugins bazaar'), ]: vs = getattr(vd, vdattr) vs.description = desc vs.shortcut_en = shortcut vs.longname = longname vs.ensureLoaded() self.addRow(vs)
class HelpSheet(Sheet): 'Show all commands available to the source sheet.' rowtype = 'commands' precious = False columns = [ ColumnAttr('sheet'), ColumnAttr('longname'), Column('keystrokes', getter=lambda col, row: col.sheet.revbinds.get(row.longname)), Column('description', getter=lambda col, row: col.sheet.cmddict[ (row.sheet, row.longname)].helpstr), ColumnAttr('execstr', width=0), ColumnAttr('logged', 'replayable', width=0), ] nKeys = 2 @asyncthread def reload(self): from pkg_resources import resource_filename cmdlist = TsvSheet('cmdlist', source=Path( resource_filename(__name__, 'commands.tsv'))) cmdlist.reload_sync() self.cmddict = {} for cmdrow in cmdlist.rows: self.cmddict[(cmdrow.sheet, cmdrow.longname)] = cmdrow self.revbinds = { longname: keystrokes for (keystrokes, _), longname in bindkeys.iter(self.source) if keystrokes not in self.revbinds } self.rows = [] for (k, o), v in commands.iter(self.source): self.addRow(v) v.sheet = o
class IndexSheet(Sheet): rowtype = 'sheets' precious = False columns = [ ColumnAttr('name'), ColumnAttr('rows', 'nRows', type=int), ColumnAttr('cols', 'nCols', type=int), ColumnAttr('keys', 'keyColNames'), ColumnAttr('source'), ] nKeys = 1 def newRow(self): return Sheet('', columns=[ColumnItem('', 0)], rows=[]) def openRow(self, row): return row # rowdef is Sheet def getSheet(self, k): for vs in self.rows: if vs.name == k: return vs
class SheetsSheet(Sheet): rowtype = 'sheets' precious = False columns = [ ColumnAttr('name', width=30), ColumnAttr('nRows', type=int), ColumnAttr('nCols', type=int), ColumnAttr('nVisibleCols', type=int), ColumnAttr('cursorDisplay'), ColumnAttr('keyColNames'), ColumnAttr('source'), ColumnAttr('progressPct'), ] nKeys = 1 def newRow(self): return Sheet('', columns=[ColumnItem('', 0)], rows=[]) def reload(self): self.rows = self.source
class FECFiling(Sheet): "A sheet representing an entire .fec file." rowtype = "components" filing = None columns = [ ColumnAttr("component", "component_name", width=14), ColumnAttr("name", width=0), ColumnAttr("size", type=int), ] nKeys = 1 @asyncthread def reload(self): from fecfile import fecparser self.rows = [] row_dict = {} itemization_subsheets = {} def addSheetRow(component_name): "On first encountering a component, add a row to the filing sheet" cls = COMPONENT_SHEET_CLASSES[component_name] source_cls = list if cls in [FECItemizationSheet, TextSheet ] else dict vs = cls( joinSheetnames(self.name, component_name), component_name=component_name, source=source_cls(), size=0, ) vs.reload() row_dict[component_name] = vs self.addRow(vs) src = Path(self.source.resolve()) item_iter = fecparser.iter_lines(src, {"as_strings": True}) for item in item_iter: dtype = item.data_type if dtype not in row_dict.keys(): addSheetRow(dtype) sheet_row = row_dict[dtype] if dtype in ["header", "summary"]: sheet_row.source = item.data sheet_row.reload() elif dtype == "text": if len(sheet_row.source) == 0: sheet_row.set_columns_from_row(item.data) sheet_row.source.append(item.data) sheet_row.addRow(item.data) sheet_row.size += 1 elif dtype == "F99_text": sheet_row.source = item.data.split("\n") sheet_row.size = len(sheet_row.source) elif dtype == "itemization": form_type = item.data["form_type"] if form_type[0] == "S": form_type = "Schedule " + item.data["form_type"][1] if form_type not in sheet_row.source: sheet_row.source[form_type] = [] subsheet = FECItemizationSheet( joinSheetnames(sheet_row.name, form_type), schedule_name=form_type, source=[], size=0, ) subsheet.reload() subsheet.set_columns_from_row(item.data) sheet_row.addRow(subsheet) itemization_subsheets[form_type] = subsheet else: subsheet = itemization_subsheets[form_type] subsheet.addRow(item.data) subsheet.source.append(item.data) subsheet.size += 1 sheet_row.source[form_type].append(item.data) sheet_row.size += 1