diff --git a/pythonturtle/application.py b/pythonturtle/application.py index 74f4066..6047686 100644 --- a/pythonturtle/application.py +++ b/pythonturtle/application.py @@ -44,7 +44,6 @@ def __init__(self, *args, **keywords): self.turtle_process = turtleprocess.TurtleProcess() self.turtle_process.start() self.turtle_queue = self.turtle_process.turtle_queue - self.init_menu_bar() self.init_about_dialog_info() @@ -108,6 +107,12 @@ def init_menu_bar(self): self.menu_bar = wx.MenuBar() self.file_menu = wx.Menu() + + self.open_menu_item = wx.MenuItem(self.file_menu, -1, 'O&pen...') + self.file_menu.Append(self.open_menu_item) + self.Bind(wx.EVT_MENU, self.on_open, source=self.open_menu_item) + self.file_menu.AppendSeparator() + self.exit_menu_item = wx.MenuItem(self.file_menu, -1, 'E&xit') self.file_menu.Append(self.exit_menu_item) self.Bind(wx.EVT_MENU, self.on_exit, source=self.exit_menu_item) @@ -193,6 +198,21 @@ def toggle_help(self, event=None): else: self.show_help() + def on_open(self, event=None): + #ptf = python turtle functions + with wx.FileDialog(self, "Open PythonTurtle file", wildcard="PTF files (*.ptf)|*.ptf", + style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog: + + if fileDialog.ShowModal() == wx.ID_CANCEL: + return + + pathname = fileDialog.GetPath() + try: + with open(pathname, 'r') as file: + self.loadFunctionsFromFile(file) + except IOError: + wx.LogError("Cannot open file '%s'." % newfile) + def on_exit(self, event=None): return self.Close() @@ -216,6 +236,15 @@ def init_about_dialog_info(self): def on_about(self, event=None): wx.adv.AboutBox(self.about_dialog_info, self) + def loadFunctionsFromFile(self, file): + commands = file.read() + self.shell.EnterFromFile(commands) + + + + + def saveAs(self, file): + wx.adv.AboutBox(self.about_dialog_info, self) def run(): multiprocessing.freeze_support() diff --git a/pythonturtle/helppages.py b/pythonturtle/helppages.py index c318571..bc992e7 100644 --- a/pythonturtle/helppages.py +++ b/pythonturtle/helppages.py @@ -69,6 +69,7 @@ def page_list(parent=None): ["Level 2", resource_filename("help2.png")], ["Level 3", resource_filename("help3.png")], ["Level 4", resource_filename("help4.png")], + ["Using Files", resource_filename("UsingFilesHelp.png")], ] pages = [ diff --git a/pythonturtle/resources/UsingFilesHelp.png b/pythonturtle/resources/UsingFilesHelp.png new file mode 100644 index 0000000..1ac84fe Binary files /dev/null and b/pythonturtle/resources/UsingFilesHelp.png differ diff --git a/pythonturtle/resources/UsingFilesHelp.txt b/pythonturtle/resources/UsingFilesHelp.txt new file mode 100644 index 0000000..a383e5f --- /dev/null +++ b/pythonturtle/resources/UsingFilesHelp.txt @@ -0,0 +1,27 @@ +PythonTurtle can load a file with functions already in it. These functions +will then be available to use in your programs. +Note: The file can contain only functions; it can't contain direct commands +like "go". It can only contain functions that start with "def". Other +items will cause a "syntax error" when loading. + +How to load functions from a file: + +-Create a file, using a text editor. + +-Add functions to the file; for example: + +def polygon(n): + for i in range(n): + go(50) + turn(360.0/n) + +def polygon100(n): + for i in range(n): + go(100) + turn(360.0/n) + +-Save the file with the extension ".ptf" + +-From PythonTurtle, select File->Open... + +-Select your file and open. \ No newline at end of file diff --git a/pythonturtle/shelltoprocess/forkedpyshell.py b/pythonturtle/shelltoprocess/forkedpyshell.py index 36fb94d..6c75641 100644 --- a/pythonturtle/shelltoprocess/forkedpyshell.py +++ b/pythonturtle/shelltoprocess/forkedpyshell.py @@ -1347,22 +1347,46 @@ def _clip(self, data): wx.TheClipboard.SetData(data) wx.TheClipboard.Flush() wx.TheClipboard.Close() + + def FormatCommand(self, command): + ps2 = str(sys.ps2) + command = command.rstrip() + command = self.fixLineEndings(command) + command = self.lstripPrompt(text=command) + command = command.replace(os.linesep + ps2, '\n') + command = command.replace(os.linesep, '\n') + command = command.replace('\n', os.linesep + ps2) + return command + + def EnterFromFile(self, commands): + """take contents of ptf (python turtle function) file, split into + separate functions, and enter them""" + + #can't handle it if multiple defs are fed in at once; split them, + #and handle them individually + commandList = commands.split("def") + for command in commandList: + #split results in some blank strings where def was + if(len(command) > 0): + #split above removes def, so need to add it back + command = "def" + command + command = self.FormatCommand(command) + self.write(command) + self.processLine() + self.prompt() + self.processLine() + self.prompt() def Paste(self): """Replace selection with clipboard contents.""" if self.CanPaste() and wx.TheClipboard.Open(): - ps2 = str(sys.ps2) + if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)): data = wx.TextDataObject() if wx.TheClipboard.GetData(data): self.ReplaceSelection('') command = data.GetText() - command = command.rstrip() - command = self.fixLineEndings(command) - command = self.lstripPrompt(text=command) - command = command.replace(os.linesep + ps2, '\n') - command = command.replace(os.linesep, '\n') - command = command.replace('\n', os.linesep + ps2) + command = self.FormatCommand(command) self.write(command) wx.TheClipboard.Close()