# Copyright 2015.
# Michael A. DeJesus, Chaitra Ambadipudi, and Thomas R. Ioerger.
#
#
# This file is part of TRANSIT.
#
# TRANSIT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License.
#
#
# TRANSIT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with TRANSIT. If not, see <http://www.gnu.org/licenses/>.
import wx
import wx.xrc
import wx.lib.mixins.listctrl as listmix
import ntpath
import subprocess
import os
import sys
from functools import partial
import trash
import wx.grid
import pytransit
import pytransit.analysis
[docs]def fetch_name(filepath):
return os.path.splitext(ntpath.basename(filepath))[0]
[docs]def ShowError(MSG=""):
dial = wx.MessageDialog(None, MSG, 'Error',
wx.OK | wx.ICON_ERROR)
dial.ShowModal()
[docs]def sortColumn(item1, item2):
try:
i1 = float(item1)
i2 = float(item2)
except ValueError:
return cmp(item1, item2)
else:
return cmp(i1, i2)
########################################################################
[docs]class SortableListCtrl(wx.ListCtrl):
#----------------------------------------------------------------------
def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=0):
wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
#########################################
#menu_titles = [ "Display Histogram",
# "Display Tracks",]
#
#menu_title_by_id = {}
#for title in menu_titles:
# menu_title_by_id[ wx.NewId() ] = title
#
##########################################
[docs]class ImgFrame(wx.Frame):
def __init__(self, parent, filePath):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = "%s" % (filePath), pos = wx.DefaultPosition, size = wx.Size( 1150,740 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
bSizer1 = wx.BoxSizer( wx.VERTICAL )
self.m_bitmap1 = wx.StaticBitmap( self, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer1.Add( self.m_bitmap1, 1, wx.ALL|wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
img = wx.Image(filePath, wx.BITMAP_TYPE_ANY)
self.m_bitmap1.SetBitmap(wx.BitmapFromImage(img))
self.Refresh()
self.Fit()
[docs]def unknownColNames(path):
colNames = []
for line in open(path):
if line.startswith("#"):
colNames = line.split("\t")
else:
final_line = line
tmp = final_line.split("\t")
if len(colNames) < len(tmp):
colNames = ["Col%d" % (i) for i in range(len(tmp))]
return colNames
[docs]def unknownTableData(path, colnames):
row = 0
data = []
for line in open(path):
if line.startswith("#"): continue
tmp = line.split("\t")
tmp[-1] = tmp[-1].strip()
rowdict = dict([(colnames[i], tmp[i]) for i in range(len(colnames))])
data.append((row, rowdict))
row+=1
return data
[docs]def getInfoFromFileType(X):
for method in pytransit.analysis.methods:
for filetype in pytransit.analysis.methods[method].filetypes:
FT = filetype()
if X == FT.identifier:
return (method, FT)
return ("unknown", pytransit.analysis.base.TransitFile())
[docs]class TransitTable(wx.grid.PyGridTableBase):
"""
A custom wx.Grid Table using user supplied data
"""
def __init__(self, data, colnames):
"""data is a list of the form
[(rowname, dictionary),
dictionary.get(colname, None) returns the data for column
colname
"""
# The base class must be initialized *first*
wx.grid.PyGridTableBase.__init__(self)
self.data = data
self.colnames = colnames
# XXX
# we need to store the row length and column length to
# see if the table has changed size
self._rows = self.GetNumberRows()
self._cols = self.GetNumberCols()
self.sorted_col = None
self.sorted_dir = None
[docs] def GetNumberCols(self):
return len(self.colnames)
[docs] def GetNumberRows(self):
return len(self.data)
[docs] def GetColLabelValue(self, col):
return self.colnames[col]
[docs] def GetRowLabelValue(self, row):
return "R%d" % int(self.data[row][0])
[docs] def GetValue(self, row, col):
return str(self.data[row][1].get(self.GetColLabelValue(col), ""))
[docs] def GetRawValue(self, row, col):
return self.data[row][1].get(self.GetColLabelValue(col), "")
[docs] def SetValue(self, row, col, value):
self.data[row][1][self.GetColLabelValue(col)] = value
[docs] def SortColumn(self, col):
if self.sorted_col == col:
self.sorted_dir = not self.sorted_dir
else:
self.sorted_col = col
self.sorted_dir = False
name = self.colnames[col]
tempdata = []
for row in self.data:
rowname, entry = row
tempdata.append((entry.get(name, None), row))
tempdata.sort(reverse=self.sorted_dir)
self.data = []
for sortvalue, row in tempdata:
self.data.append(row)
[docs]class TransitGridFrame(wx.Frame):
def __init__(self, parent, path, size=(-1,-1)):
wx.Frame.__init__(self, parent, size=size)
bSizer1 = wx.BoxSizer( wx.VERTICAL )
sbSizer1 = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"Information" ), wx.HORIZONTAL )
self.parent = parent
self.path = path
self.col = 0
self.row = 0
self.ctrldata = self.parent.ctrlSelected()
self.expdata = self.parent.expSelected()
self.annotation = self.parent.annotation
#print "Parent:", self.parent
#print "Ctrl:", self.ctrldata
#print "Exp:", self.expdata
#print "Annotation:", self.annotation
line = open(self.path).readline().strip()
(method, FT) = getInfoFromFileType(line)
self.filetype = FT
if self.filetype.identifier == "#Unknown":
self.columnlabels = unknownColNames(self.path)
else:
self.columnlabels = self.filetype.colnames
data = self.filetype.getData(self.path, self.columnlabels)
wxheader_list = []
text = self.filetype.getHeader(self.path)
wxheader_list.append(wx.StaticText( self, wx.ID_ANY, text, wx.DefaultPosition, wx.DefaultSize, 0 ))
wxheader_list[-1].Wrap( -1 )
sbSizer1.Add( wxheader_list[-1], 0, wx.ALL, 5 )
self.grid = wx.grid.Grid(self, -1)
bSizer1.Add( sbSizer1, 0, wx.EXPAND, 5 )
bSizer1.Add( self.grid, 0, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Centre( wx.BOTH )
#self.Layout()
self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_DCLICK, self.OnLabelDoubleClicked)
self.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self.OnCellRightClicked)
mytable = TransitTable(data, self.columnlabels)
self.grid.SetTable(mytable)
self.grid.EnableEditing(False)
self.grid.AdjustScrollbars()
self.grid.SetColLabelSize(wx.grid.GRID_AUTOSIZE)
#self.grid.AutoSizeColumns()
self.AutoResizeCols()
self.grid.ForceRefresh()
(width, height) = bSizer1.GetMinSize()
max_width = 1500
max_height = 800
width = min(width+50, max_width)
height = min(height, max_height)
self.SetMinSize((width, height))
self.Layout()
self.Show()
[docs] def AutoResizeCols(self):
max_column_size = 200
min_column_size = 100
self.grid.AutoSizeColumns(False)
for i,label in enumerate(self.columnlabels):
size = self.grid.GetColSize(i)
if size > max_column_size:
self.grid.SetColSize(i, max_column_size)
elif size < min_column_size:
self.grid.SetColSize(i, min_column_size)
[docs] def OnLabelDoubleClicked(self, evt):
col = evt.GetCol()
if col != -1:
self.grid.GetTable().SortColumn(col)
self.grid.ForceRefresh()
[docs] def OnCellRightClicked(self, evt):
menu = wx.Menu()
id1 = wx.NewId()
sortID = wx.NewId()
xo, yo = evt.GetPosition()
self.row = self.grid.YToRow(yo) - 1
self.col = 0
val = self.grid.GetCellValue(self.row, 0)
#print "Row:", self.row
#print "Col:", self.col
#print "Val:", val
self.Refresh()
for (menuname, menufunc) in self.filetype.getMenus():
newid = wx.NewId()
#print newid, menufunc
menu.Append(newid, menuname)
newmenufunc = partial(menufunc, self)
self.Bind(wx.EVT_MENU, newmenufunc, id=newid)
self.PopupMenu(menu)
menu.Destroy()