diff --git a/gui/Gui/Mainwindow.py b/gui/Gui/Mainwindow.py index b00ce1c..4d411cd 100644 --- a/gui/Gui/Mainwindow.py +++ b/gui/Gui/Mainwindow.py @@ -25,6 +25,10 @@ import wx import os.path +from time import sleep + +import threading + #--------------------------------------------------------------------------- """ Import scyther-gui components """ @@ -42,6 +46,8 @@ ID_VERIFY = 100 ID_AUTOVERIFY = 101 ID_CHARACTERIZE = 102 ID_CHECK = 103 +ID_WATCH = 104 +ID_STOP_WATCH = 105 #--------------------------------------------------------------------------- @@ -63,6 +69,9 @@ class MainWindow(wx.Frame): self.filename = '' self.filepath = "" + self.watchfile = None + self.watchThread = None + self.load = False # test @@ -162,6 +171,8 @@ class MainWindow(wx.Frame): (wx.ID_NEW, '&New\tCTRL-N', 'Create a new file', self.OnNew), (wx.ID_OPEN, '&Open\tCTRL-O', 'Open a new file', self.OnOpen), (wx.ID_SAVE, '&Save\tCTRL-S', 'Save the current file', self.OnSave), + (ID_WATCH, 'Watch', 'Whatch a file for changes', self.OnWatch), + (ID_STOP_WATCH, 'Stop Watch', 'Stop watching for changes', self.OnStopWatch), (wx.ID_SAVEAS, 'Save &As', 'Save the file under a different name', self.OnSaveAs), (None, None, None, None), @@ -281,6 +292,60 @@ class MainWindow(wx.Frame): return True return False + def OnWatch(self, event): + if self.watchfile != None or self.watchThread != None: + self.watchfile = None + self.watchThread.join() + self.watchThread = None + + if self.ConfirmLoss(): + if self.askUserForFilename(style=wx.FD_OPEN, **self.defaultFileDialogOptions()): + + self.editor.SetText("") + self.editor.SetOpened() + + self.editor.control.Enable(False) + + name = str(self.filename) + + self.watchfile = name + + def runMain(): + while name == self.watchfile: + textfile = open(os.path.join(self.dirname, self.filename), 'r') + + data = textfile.read() + + if data != self.editor.GetText(): + self.editor.SetText(data) + textfile.close() + self.editor.SetOpened() + + # Clear errors before verification + self.editor.SetErrors(None) + # Verify spdl + s = Scytherthread.ScytherRun(self,"verify",data,self.editor.SetErrors, watchMode=True, watchModeFile=self.filename) + + sleep(0.9) + + self.watchThread = threading.Thread(target=runMain) + + self.watchThread.start() + + return True + + return False + + def OnStopWatch(self, event): + self.watchfile = None + thread = self.watchThread + self.watchThread = None + thread.join() + self.editor.control.Enable(True) + self.editor.SetText("") + self.editor.SetOpened() + return True + def OnSave(self, event): if self.filename=='': return self.OnSaveAs(event) diff --git a/gui/Gui/Scytherthread.py b/gui/Gui/Scytherthread.py index 0924e85..77dcae9 100644 --- a/gui/Gui/Scytherthread.py +++ b/gui/Gui/Scytherthread.py @@ -24,6 +24,7 @@ """ Import externals """ import wx import threading +import subprocess #--------------------------------------------------------------------------- @@ -39,6 +40,8 @@ from . import Icon from . import Error from . import Makeimage +from .Misc import dotOutputWrite + #--------------------------------------------------------------------------- if Preference.havePIL: import Image @@ -254,7 +257,7 @@ class ResultWindow(wx.Frame): def __init__( self, parent, parentwindow, title, pos=wx.DefaultPosition, size=wx.DefaultSize, - style=wx.DEFAULT_DIALOG_STYLE + style=wx.DEFAULT_DIALOG_STYLE, watchMode = False, watchModeFile = None ): wx.Frame.__init__(self,parentwindow,-1,title,pos,size,style) @@ -263,6 +266,8 @@ class ResultWindow(wx.Frame): self.parent = parent self.thread = None + self.watchMode = watchMode + self.watchModeFile = watchModeFile aTable = wx.AcceleratorTable([ (wx.ACCEL_CTRL, ord('W'), wx.ID_CLOSE), (wx.ACCEL_NORMAL, wx.WXK_ESCAPE, wx.ID_CLOSE), @@ -277,12 +282,18 @@ class ResultWindow(wx.Frame): def onViewButton(self,evt): btn = evt.GetEventObject() - try: - w = Attackwindow.AttackWindow(btn.claim) - w.Show(True) - except Error.PILError: - Error.ShowAndReturn("Problem with PIL imaging library: disabled zooming. Please retry to verify the protocol again.") - self.onCloseWindow(None) + + if self.watchMode: + print("Watching generating image") + dotOutputWrite(btn.claim.attacks[0].scytherDot, self.watchModeFile + ".png",["-Tpng"]) + subprocess.run(['xdg-open', self.watchModeFile + ".png"]) + else: + try: + w = Attackwindow.AttackWindow(btn.claim) + w.Show(True) + except Error.PILError: + Error.ShowAndReturn("Problem with PIL imaging library: disabled zooming. Please retry to verify the protocol again.") + self.onCloseWindow(None) def onCloseWindow(self,evt): """ TODO we should kill self.thread """ @@ -423,8 +434,10 @@ class ResultWindow(wx.Frame): class ScytherRun(object): - def __init__(self,mainwin,mode,spdl,errorcallback=None): + def __init__(self,mainwin,mode,spdl,errorcallback=None, watchMode=False, watchModeFile = None): + self.watchMode = watchMode + self.watchModeFile = watchModeFile self.mainwin = mainwin self.mode = mode self.spdl = spdl @@ -505,7 +518,7 @@ class ScytherRun(object): # Great, we verified stuff, progress to the claim report title = "Scyther results : %s" % self.mode - self.resultwin = resultwin = ResultWindow(self,self.mainwin,title) + self.resultwin = resultwin = ResultWindow(self,self.mainwin,title, watchMode=self.watchMode, watchModeFile=self.watchModeFile) def attackDone(attack,total,done): if resultwin: diff --git a/gui/nsl3-broken.spdl.png b/gui/nsl3-broken.spdl.png new file mode 100644 index 0000000..cf0a1d8 Binary files /dev/null and b/gui/nsl3-broken.spdl.png differ diff --git a/gui/scyther-gui.py b/gui/scyther-gui.py index 249b7eb..f6b0d4f 100755 --- a/gui/scyther-gui.py +++ b/gui/scyther-gui.py @@ -157,45 +157,6 @@ def parseArgs(): #--------------------------------------------------------------------------- -class MySplashScreen(WXPYTHONINFREQ.SplashScreen): - def __init__(self,basedir): - path = os.path.join(basedir,"Images") - image = os.path.join(path,"scyther-splash.png") - bmp = wx.Image(image).ConvertToBitmap() - wx.SplashScreen.__init__(self, bmp, - wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT, - 5000, None, -1) - self.Bind(wx.EVT_CLOSE, self.OnClose) - self.fc = wx.FutureCall(2000, self.ShowMain) - - def OnClose(self, evt): - # Make sure the default handler runs too so this window gets - # destroyed - evt.Skip() - self.Hide() - - # if the timer is still running then go ahead and show the - # main frame now - if self.fc.IsRunning(): - self.fc.Stop() - self.ShowMain() - - - def ShowMain(self): - if self.fc.IsRunning(): - self.Raise() - - -#--------------------------------------------------------------------------- - -def isSplashNeeded(opts): - if not opts.command: - if opts.splashscreen and not (Preference.get('splashscreen') in ['false','off','disable','0']): - return True - return False - -#--------------------------------------------------------------------------- - class ScytherApp(wx.App): def OnInit(self): import os, inspect @@ -232,11 +193,6 @@ class ScytherApp(wx.App): self.SetTopWindow(self.mainWindow) self.mainWindow.Show() - if isSplashNeeded(opts): - dlg = About.AboutScyther(self.mainWindow,basedir) - dlg.ShowModal() - dlg.Destroy() - return True #def OnExit(self): diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000..06a90e1 --- /dev/null +++ b/src/version.h @@ -0,0 +1 @@ +#define TAGVERSION "b'v1.2-25-g2a698fa'"