scyther/gui/Gui/Mainwindow.py

333 lines
11 KiB
Python
Raw Normal View History

2006-08-02 13:59:57 +01:00
#!/usr/bin/python
#---------------------------------------------------------------------------
""" Import externals """
import wx
import os.path
import sys
import wx.lib.mixins.listctrl as listmix
#---------------------------------------------------------------------------
""" Import scyther-gui components """
import Preference
import Attackwindow
import Scytherthread
import Icon
import Scyther.Claim as Claim
2006-08-02 13:59:57 +01:00
#---------------------------------------------------------------------------
""" Some constants """
ID_VERIFY = 100
ID_AUTOVERIFY = 101
ID_STATESPACE = 102
ID_CHECK = 103
#---------------------------------------------------------------------------
class MainWindow(wx.Frame):
def __init__(self, opts, args):
2006-08-02 13:59:57 +01:00
super(MainWindow, self).__init__(None, size=(600,800))
self.opts = opts
self.args = args
self.dirname = os.path.abspath('.')
2006-08-02 13:59:57 +01:00
self.filename = 'noname.spdl'
self.load = False
# test
if opts.test:
self.filename = 'scythergui-default.spdl'
2006-08-02 13:59:57 +01:00
self.load = True
# if there is an argument (file), we load it
if len(args) > 0:
filename = args[0]
if filename != '' and os.path.isfile(filename):
self.filename = filename
self.load = True
2006-08-02 13:59:57 +01:00
Icon.ScytherIcon(self)
self.CreateInteriorWindowComponents()
self.CreateExteriorWindowComponents()
aTable = wx.AcceleratorTable([
2006-08-10 15:42:51 +01:00
(wx.ACCEL_ALT, ord('X'), wx.ID_EXIT),
(wx.ACCEL_CTRL, ord('Q'), wx.ID_EXIT),
2006-08-02 13:59:57 +01:00
(wx.ACCEL_NORMAL, wx.WXK_F1,
ID_VERIFY),
(wx.ACCEL_NORMAL, wx.WXK_F2,
ID_STATESPACE),
(wx.ACCEL_NORMAL, wx.WXK_F5,
ID_CHECK),
(wx.ACCEL_NORMAL, wx.WXK_F6,
ID_AUTOVERIFY),
])
self.SetAcceleratorTable(aTable)
self.claimlist = []
self.pnglist = []
#self.SetTitle(self.title)
self.firstCommand()
2006-08-02 13:59:57 +01:00
def CreateInteriorWindowComponents(self):
''' Create "interior" window components. In this case it is just a
simple multiline text control. '''
2006-08-09 11:21:30 +01:00
## Make zoom buttons
#sizer = wx.BoxSizer(wx.VERTICAL)
#buttons = wx.BoxSizer(wx.HORIZONTAL)
#bt = wx.Button(self,ID_VERIFY)
#buttons.Add(bt,0)
#self.Bind(wx.EVT_BUTTON, self.OnVerify, bt)
#bt = wx.Button(self,ID_STATESPACE)
#buttons.Add(bt,0)
#self.Bind(wx.EVT_BUTTON, self.OnStatespace, bt)
#sizer.Add(buttons, 0, wx.ALIGN_LEFT)
2006-08-02 13:59:57 +01:00
# Top: input
2006-08-03 13:06:43 +01:00
self.top = wx.Notebook(self,-1)
2006-08-02 13:59:57 +01:00
self.control = wx.TextCtrl(self.top, style=wx.TE_MULTILINE)
if self.load:
textfile = open(os.path.join(self.dirname, self.filename), 'r')
self.control.SetValue(textfile.read())
os.chdir(self.dirname)
textfile.close()
2006-08-03 13:06:43 +01:00
self.top.AddPage(self.control,"Protocol description")
2006-08-02 13:59:57 +01:00
self.settings = SettingsWindow(self.top,self)
2006-08-03 13:06:43 +01:00
self.top.AddPage(self.settings,"Verification parameters")
2006-08-02 13:59:57 +01:00
2006-08-09 11:21:30 +01:00
#sizer.Add(self.top,1,wx.EXPAND,1)
#self.SetSizer(sizer)
2006-08-02 13:59:57 +01:00
def CreateExteriorWindowComponents(self):
''' Create "exterior" window components, such as menu and status
bar. '''
self.CreateMenus()
self.SetTitle()
def CreateMenu(self, bar, name, list):
fileMenu = wx.Menu()
for id, label, helpText, handler in list:
if id == None:
fileMenu.AppendSeparator()
else:
item = fileMenu.Append(id, label, helpText)
self.Bind(wx.EVT_MENU, handler, item)
bar.Append(fileMenu, name) # Add the fileMenu to the MenuBar
def CreateMenus(self):
menuBar = wx.MenuBar()
self.CreateMenu(menuBar, '&File', [
(wx.ID_OPEN, '&Open', 'Open a new file', self.OnOpen),
(wx.ID_SAVE, '&Save', 'Save the current file', self.OnSave),
(wx.ID_SAVEAS, 'Save &As', 'Save the file under a different name',
self.OnSaveAs),
(None, None, None, None),
2006-08-10 15:42:51 +01:00
(wx.ID_EXIT, 'E&xit\tCTRL-Q', 'Terminate the program',
2006-08-02 13:59:57 +01:00
self.OnExit)])
self.CreateMenu(menuBar, '&Verify',
[(ID_VERIFY, '&Verify protocol\tF1','Verify the protocol in the buffer using Scyther',
self.OnVerify) ,
(ID_STATESPACE, 'Generate &statespace\tF2','TODO' ,
2006-08-09 10:41:14 +01:00
self.OnStatespace) ,
2006-08-02 13:59:57 +01:00
(None, None, None, None),
(ID_CHECK, '&Check protocol\tF5','TODO',
2006-08-09 10:41:14 +01:00
self.OnCheck) ,
2006-08-02 13:59:57 +01:00
(ID_AUTOVERIFY, 'Verify &automatic claims\tF6','TODO',
2006-08-09 10:41:14 +01:00
self.OnAutoVerify)
2006-08-02 13:59:57 +01:00
])
self.CreateMenu(menuBar, '&Help',
[(wx.ID_ABOUT, '&About', 'Information about this program',
self.OnAbout) ])
self.SetMenuBar(menuBar) # Add the menuBar to the Frame
def SetTitle(self):
# MainWindow.SetTitle overrides wx.Frame.SetTitle, so we have to
# call it using super:
2006-08-09 11:21:30 +01:00
super(MainWindow, self).SetTitle('Scyther: %s'%self.filename)
2006-08-02 13:59:57 +01:00
# Helper methods:
def defaultFileDialogOptions(self):
''' Return a dictionary with file dialog options that can be
used in both the save file dialog as well as in the open
file dialog. '''
return dict(message='Choose a file', defaultDir=self.dirname,
wildcard='*.spdl')
def askUserForFilename(self, **dialogOptions):
dialog = wx.FileDialog(self, **dialogOptions)
if dialog.ShowModal() == wx.ID_OK:
userProvidedFilename = True
self.filename = dialog.GetFilename()
self.dirname = dialog.GetDirectory()
self.SetTitle() # Update the window title with the new filename
else:
userProvidedFilename = False
dialog.Destroy()
return userProvidedFilename
# Event handlers:
def OnAbout(self, event):
msg = "Scyther GUI\n\nScyther and Scyther GUI\ndeveloped by Cas Cremers"
dialog = wx.MessageDialog(self,msg, 'About scyther-gui', wx.OK)
dialog.ShowModal()
dialog.Destroy()
def OnExit(self, event):
self.Close() # Close the main window.
def OnSave(self, event):
textfile = open(os.path.join(self.dirname, self.filename), 'w')
textfile.write(self.control.GetValue())
textfile.close()
def OnOpen(self, event):
if self.askUserForFilename(style=wx.OPEN,
**self.defaultFileDialogOptions()):
textfile = open(os.path.join(self.dirname, self.filename), 'r')
self.control.SetValue(textfile.read())
textfile.close()
def OnSaveAs(self, event):
if self.askUserForFilename(defaultFile=self.filename, style=wx.SAVE,
**self.defaultFileDialogOptions()):
self.OnSave(event)
os.chdir(self.dirname)
def RunScyther(self, mode):
2006-08-04 23:00:22 +01:00
s = Scytherthread.ScytherRun(self,mode)
2006-08-02 13:59:57 +01:00
def OnVerify(self, event):
self.RunScyther("verify")
def OnAutoVerify(self, event):
self.RunScyther("autoverify")
def OnStatespace(self, event):
self.RunScyther("statespace")
def OnCheck(self, event):
self.RunScyther("check")
def firstCommand(self):
if self.opts.command:
# Trigger a command automatically
2006-08-09 11:21:30 +01:00
self.Show(True)
self.RunScyther(self.opts.command)
2006-08-02 13:59:57 +01:00
#---------------------------------------------------------------------------
class SettingsWindow(wx.Panel):
def __init__(self,parent,daddy):
wx.Panel.__init__(self,parent,-1)
self.win = daddy
# Bound on the number of runs
self.maxruns = int(Preference.get('maxruns','5'))
r1 = wx.StaticText(self,-1,"Maximum number of runs (0 disables bound)")
2006-08-07 17:25:47 +01:00
l1 = wx.SpinCtrl(self, -1, "",style=wx.RIGHT)
2006-08-02 13:59:57 +01:00
l1.SetRange(0,100)
l1.SetValue(self.maxruns)
self.Bind(wx.EVT_SPINCTRL,self.EvtRuns,l1)
# Matchin options
self.match = int(Preference.get('match','0'))
claimoptions = ['typed matching','find basic type flaws','find all type flaws']
r2 = wx.StaticText(self,-1,"Matching type")
2006-08-07 17:25:47 +01:00
l2 = self.ch = wx.Choice(self,-1,choices=claimoptions)
2006-08-02 13:59:57 +01:00
l2.SetSelection(self.match)
2006-08-09 12:54:37 +01:00
self.Bind(wx.EVT_CHOICE,self.EvtMatch,l2)
2006-08-02 13:59:57 +01:00
### MISC expert stuff
# Bound on the number of classes/attacks
self.maxattacks = int(Preference.get('maxattacks','100'))
stname = Claim.stateDescription(True,2,False)
atname = Claim.stateDescription(False,2,False)
txt = "%s/%s" % (stname,atname)
r9 = wx.StaticText(self,-1,"Maximum number of %s for all claims combined (0 disables maximum)" % txt)
l9 = wx.SpinCtrl(self, -1, "",style=wx.RIGHT)
l9.SetRange(0,100)
l9.SetValue(self.maxattacks)
self.Bind(wx.EVT_SPINCTRL,self.EvtMaxAttacks,l9)
2006-08-02 13:59:57 +01:00
self.misc = Preference.get('scytheroptions','')
r10 = wx.StaticText(self,-1,"Additional parameters for the Scyther tool")
l10 = wx.TextCtrl(self,-1,self.misc,size=(150,-1))
self.Bind(wx.EVT_TEXT,self.EvtMisc,l10)
# Combine
space = 10
sizer = wx.FlexGridSizer(cols=3, hgap=space,vgap=space)
sizer.AddMany([ l1,r1, (0,0),
l2,r2, (0,0),
l9,r9, (0,0),
2006-08-02 13:59:57 +01:00
l10,r10, (0,0),
])
self.SetSizer(sizer)
self.SetAutoLayout(True)
def EvtMatch(self,evt):
self.match = evt.GetInt()
def EvtRuns(self,evt):
self.maxruns = evt.GetInt()
def EvtMaxAttacks(self,evt):
self.maxattacks = evt.GetInt()
2006-08-02 13:59:57 +01:00
def EvtMisc(self,evt):
self.misc = evt.GetString()
2006-08-04 23:00:22 +01:00
def ScytherArguments(self,mode):
2006-08-02 13:59:57 +01:00
""" Note: constructed strings should have a space at the end to
correctly separate the options.
"""
tstr = ""
# Number of runs
tstr += "--max-runs=%s " % (str(self.maxruns))
# Matching type
tstr += "--match=%s " % (str(self.match))
# Max attacks/classes
if self.maxattacks != 0:
tstr += "--max-attacks=%s " % (str(self.maxattacks))
2006-08-02 13:59:57 +01:00
# Verification type
2006-08-04 23:00:22 +01:00
if mode == "check":
2006-08-02 13:59:57 +01:00
tstr += "--check "
2006-08-04 23:00:22 +01:00
elif mode == "autoverify":
2006-08-02 13:59:57 +01:00
tstr += "--auto-claims "
2006-08-04 23:00:22 +01:00
elif mode == "statespace":
2006-08-02 13:59:57 +01:00
tstr += "--state-space "
# Anything else?
if self.misc != "":
tstr += " " + self.misc + " "
return tstr
#---------------------------------------------------------------------------