# Programmer: Daniel Pozmanter
# E-mail: drpython@bluebottle.com
# Note: You must reply to the verification e-mail to get through.
#
# Copyright 2003-2005 Daniel Pozmanter
#
# Distributed under the terms of the GPL (GNU Public License)
#
# DrPython 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#drScript Menu
import os.path
import wx
import drFileDialog
import drScrolledMessageDialog
from drPrefsFile import ExtractPreferenceFromText
import drShortcutsFile
import drShortcuts
from drMenu import drMenu
def updatescripts(scriptfile, paths, titles):
l = len(paths)
x = 0
f = open(scriptfile, 'w')
while (x < l):
f.write("" + paths[x] + "
" + titles[x] + "\n")
x = x + 1
f.close()
class drNewShellDialog(wx.Dialog):
def __init__(self, parent, title):
wx.Dialog.__init__(self, parent, -1, title, wx.Point(50, 50), wx.Size(375, 250), wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.THICK_FRAME | wx.RESIZE_BORDER)
self.ID_SAVE = 1005
self.theSizer = wx.FlexGridSizer(6, 3, 5, 10)
self.btnSave = wx.Button(self, self.ID_SAVE, "&Save")
self.parent = parent
self.txtTitle = wx.TextCtrl(self, -1, "", wx.Point(15, 325), wx.Size(250, -1))
self.txtCommand = wx.TextCtrl(self, -1, "", wx.Point(15, 325), wx.Size(250, -1))
self.txtArguments = wx.TextCtrl(self, -1, "", wx.Point(15, 325), wx.Size(250, -1))
self.txtDirectory = wx.TextCtrl(self, -1, "", wx.Point(15, 325), wx.Size(250, -1))
self.chkRunInPrompt = wx.CheckBox(self, -1, "")
self.chkRunInPrompt.SetValue(True)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, "Title:"), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(self.txtTitle, 0, wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, "Command:"), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(self.txtCommand, 0, wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, "Arguments:"), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(self.txtArguments, 0, wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, "Directory:"), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(self.txtDirectory, 0, wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, "Run In Prompt:"), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(self.chkRunInPrompt, 0, wx.SHAPED)
self.btnClose = wx.Button(self, 101, "&Close")
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(wx.StaticText(self, -1, " "), 0, wx.ALIGN_CENTER | wx.SHAPED)
self.theSizer.Add(self.btnClose, 0, wx.SHAPED | wx.ALIGN_CENTER)
self.theSizer.Add(self.btnSave, 0, wx.SHAPED | wx.ALIGN_RIGHT)
self.txtTitle.SetFocus()
self.btnSave.SetDefault()
self.SetAutoLayout(True)
self.SetSizer(self.theSizer)
self.exitstatus = 0
self.Bind(wx.EVT_BUTTON, self.OnbtnSave, id=self.ID_SAVE)
self.Bind(wx.EVT_BUTTON, self.OnbtnClose, id=101)
def GetExitStatus(self):
return self.exitstatus
def GetShellTuple(self):
return self.txtTitle.GetValue(), self.txtCommand.GetValue(), self.txtArguments.GetValue(), self.txtDirectory.GetValue(), int(self.chkRunInPrompt.GetValue())
def OnbtnClose(self, event):
self.exitstatus = 0
self.Close(1)
def OnbtnSave(self, event):
self.exitstatus = 1
self.Close(1)
def SetShellTuple(self, title, command, args, dir, inprompt):
self.txtTitle.SetValue(title)
self.txtCommand.SetValue(command)
self.txtArguments.SetValue(args)
self.txtDirectory.SetValue(dir)
self.chkRunInPrompt.SetValue(inprompt)
class drScriptMenu(drMenu):
def __init__(self, parent):
drMenu.__init__(self, parent)
self.dynamicscriptext = ""
self.ID_ADD_SCRIPT = 3100
self.ID_NEW_SCRIPT = 3101
self.ID_EXISTING_SCRIPT = 3102
self.ID_SHELL_COMMAND = 3103
self.ID_EDIT_SCRIPT = 3003
self.ID_REMOVE_SCRIPT = 3005
self.ID_DYNAMIC_SCRIPT = 3006
self.ID_EXAMPLE_SCRIPTS = 3010
self.ID_SCRIPT_BASE = parent.ID_SCRIPT_BASE
self.ID_SCRIPT_MENU = 3500
self.parent = parent
self.userpreferencesdirectory = parent.userpreferencesdirectory
self.programdirectory = parent.programdirectory
self.scriptcount = 0
self.scripts = []
self.titles = []
self.setupMenu()
self.ExampleScriptCount = 0
self.loadscripts()
def getdrscriptmenulabel(self, label):
shortcuttext = ''
if len(self.parent.DrScriptShortcuts) == 0:
return label
if label in self.titles:
i = self.titles.index(label)
shortcuttext = drShortcuts.GetShortcutLabel(self.parent.DrScriptShortcuts[i])
if len(shortcuttext) > 1:
return label + '\t' + shortcuttext
return label
def loadscripts(self, SyncShortcuts = 1):
self.scriptcount = 0
if self.parent.prefs.drscriptloadexamples:
self.examplemenu = wx.Menu()
self.loadscriptsfromfile(self.programdirectory + "/examples/DrScript/drscript.dat", self.examplemenu, 1)
self.AppendMenu(self.ID_EXAMPLE_SCRIPTS, "Examples", self.examplemenu)
self.AppendSeparator()
self.ExampleScriptCount = self.scriptcount
self.loadscriptsfromfile(self.userpreferencesdirectory + "/drscript.dat", self)
#Either there is no shortcuts file, or it is out of sync.
if SyncShortcuts:
l = len(self.titles)
if not (l == len(self.parent.DrScriptShortcuts)):
self.parent.DrScriptShortcuts = []
self.parent.DrScriptShortcutNames = []
x = 0
while (x < l):
self.parent.DrScriptShortcuts.append(' #')
self.parent.DrScriptShortcutNames.append(self.titles[x])
x = x + 1
def loadscriptsfromfile(self, scriptfile, target, appendprogpath = 0):
if (os.path.exists(scriptfile)):
folders = [target]
folderindex = 0
menuTitles = []
menuTitleindex = -1
lastCount = 0
try:
#Read from the file
f = open(scriptfile, 'rb')
#Initialize
line = f.readline()
while (len(line) > 0):
c = line.count('\t')
line = line[c:].rstrip()
while (lastCount > c):
folders[(folderindex - 1)].AppendMenu(self.ID_SCRIPT_MENU, menuTitles.pop(), folders.pop())
folderindex = folderindex - 1
menuTitleindex = menuTitleindex - 1
lastCount = lastCount - 1
if (line[0] == '>'):
folders.append(wx.Menu())
menuTitles.append(line[1:])
folderindex = folderindex + 1
menuTitleindex = menuTitleindex + 1
c = c + 1
else:
line_path = ExtractPreferenceFromText(line, "path")
if appendprogpath:
line_path = self.programdirectory + "/" + line_path.replace('\\', '/')
line_title = ExtractPreferenceFromText(line, "title")
if (os.path.exists(line_path)):
self.titles.append(line_title)
folders[folderindex].Append((self.ID_SCRIPT_BASE + self.scriptcount), self.getdrscriptmenulabel(line_title))
self.parent.Bind(wx.EVT_MENU, self.OnScript, id=(self.ID_SCRIPT_BASE + self.scriptcount))
self.scripts.append(line_path)
self.scriptcount = self.scriptcount + 1
lastCount = c
line = f.readline()
f.close()
#Add any menus not yet added:
c = 0
while (lastCount > c):
folders[(folderindex - 1)].AppendMenu(self.ID_SCRIPT_MENU, menuTitles.pop(), folders.pop())
folderindex = folderindex - 1
menuTitleindex = menuTitleindex - 1
lastCount = lastCount - 1
except:
drScrolledMessageDialog.ShowMessage(self.parent, ("Your drscript file is a tad messed up.\n"), "Error")
def OnAddExistingScript(self, event):
scriptfile = self.userpreferencesdirectory + "/drscript.dat"
dlg = drFileDialog.FileDialog(self.parent, "Select Script File", self.parent.prefs.wildcard)
if (len(self.parent.prefs.drscriptdefaultdirectory) > 0):
try:
dlg.SetDirectory(self.parent.prefs.drscriptdefaultdirectory)
except:
drScrolledMessageDialog.ShowMessage(self.parent, ("Error Setting Default Directory To: " + self.parent.prefs.drscriptdefaultdirectory), "DrPython Error")
if (dlg.ShowModal() == wx.ID_OK):
filen = dlg.GetPath().replace("\\", "/")
d = wx.TextEntryDialog(self.parent, 'Enter Script Title:', 'Add DrScript: Title', '')
title = ""
if (d.ShowModal() == wx.ID_OK):
title = d.GetValue()
d.Destroy()
if (len(title) < 1):
drScrolledMessageDialog.ShowMessage(self.parent, ("Bad script title.\nDrPython will politely ignore your request to add this script."), "Error")
return
self.Append((self.ID_SCRIPT_BASE + self.scriptcount), title, title)
self.parent.Bind(wx.EVT_MENU, self.OnScript, id=(self.ID_SCRIPT_BASE + self.scriptcount))
self.scripts.append(filen)
self.titles.append(title)
x = len(self.parent.DrScriptShortcuts)
self.parent.DrScriptShortcuts.append('')
self.parent.DrScriptShortcutNames.append(title)
self.scriptcount = self.scriptcount + 1
try:
f = open(scriptfile, 'a')
f.write("" + filen + "" + title + "\n")
f.close()
#Update the shortcuts Too.
shortcutsfile = self.userpreferencesdirectory + "/drscript.shortcuts.dat"
drShortcutsFile.WriteShortcuts(shortcutsfile, self.parent.DrScriptShortcuts, self.parent.DrScriptShortcutNames, "", False)
except:
drScrolledMessageDialog.ShowMessage(self.parent, ("Problem saving script.\n"), "Error")
dlg.Destroy()
def OnAddNewScript(self, event):
scriptfile = self.userpreferencesdirectory + "/drscript.dat"
dlg = drFileDialog.FileDialog(self.parent, "Save New Script File As", self.parent.prefs.wildcard, IsASaveDialog=True)
if (len(self.parent.prefs.drscriptdefaultdirectory) > 0):
try:
dlg.SetDirectory(self.parent.prefs.drscriptdefaultdirectory)
except:
drScrolledMessageDialog.ShowMessage(self.parent, ("Error Setting Default Directory To: " + self.parent.prefs.drscriptdefaultdirectory), "DrPython Error")
if (dlg.ShowModal() == wx.ID_OK):
filen = dlg.GetPath().replace("\\", "/")
d = wx.TextEntryDialog(self.parent, "Enter Script Title:", "Add DrScript: Title", "")
title = ""
if (d.ShowModal() == wx.ID_OK):
title = d.GetValue()
d.Destroy()
if (len(title) < 1):
drScrolledMessageDialog.ShowMessage(self.parent, ("Bad script title.\nDrPython will politely ignore your request to add this script."), "Error")
return
cfile = file(filen, 'wb')
cfile.write("#drscript\n\n")
cfile.close()
self.Append((self.ID_SCRIPT_BASE + self.scriptcount), title, title)
self.parent.Bind(wx.EVT_MENU, self.OnScript, id=(self.ID_SCRIPT_BASE + self.scriptcount))
self.scripts.append(filen)
self.titles.append(title)
x = len(self.parent.DrScriptShortcuts)
self.parent.DrScriptShortcuts.append('')
self.parent.DrScriptShortcutNames.append(title)
self.scriptcount = self.scriptcount + 1
try:
f = open(scriptfile, 'a')
f.write("" + filen + "" + title + "\n")
f.close()
shortcutsfile = self.userpreferencesdirectory + "/drscript.shortcuts.dat"
drShortcutsFile.WriteShortcuts(shortcutsfile, self.parent.DrScriptShortcuts, self.parent.DrScriptShortcutNames, "", False)
except:
drScrolledMessageDialog.ShowMessage(self.parent, ("Problem saving script.\n"), "Error")
old = self.parent.txtDocument.filename
filename = filen
if (len(old) > 0) or (self.parent.txtDocument.GetModify()):
self.parent.OpenFile(filename, True)
else:
self.parent.OpenFile(filename, False)
dlg.Destroy()
def OnAddShellCommand(self, event):
scriptfile = self.userpreferencesdirectory + "/drscript.dat"
dlg = drFileDialog.FileDialog(self.parent, "Save New Shell Command As", self.parent.prefs.wildcard, IsASaveDialog=True)
if (len(self.parent.prefs.drscriptdefaultdirectory) > 0):
try:
dlg.SetDirectory(self.parent.prefs.drscriptdefaultdirectory)
except:
drScrolledMessageDialog.ShowMessage(self.parent, ("Error Setting Default Directory To: " + self.parent.prefs.drscriptdefaultdirectory), "DrPython Error")
if (dlg.ShowModal() == wx.ID_OK):
filen = dlg.GetPath().replace("\\", "/")
d = drNewShellDialog(self.parent, "New Shell Command")
if self.parent.prefs.platform_is_windows:
d.SetSize(wx.Size(425, 350))
d.ShowModal()
if d.GetExitStatus():
title, cmd, args, dir, inprompt = d.GetShellTuple()
d.Destroy()
else:
d.Destroy()
return
if (len(title) < 1):
drScrolledMessageDialog.ShowMessage(self.parent, ("Bad shell title.\nDrPython will politely ignore your request to add this shell command."), "Error")
return
if args.find("") > -1:
args = args.replace("", self.parent.txtDocument.filename)
if args.find("") > -1:
args = args.replace("", os.path.split(self.parent.txtDocument.filename)[0])
if dir.find("") > -1:
dir = dir.replace("", os.path.split(self.parent.txtDocument.filename)[0])
cfile = file(filen, 'wb')
scripttext = "#drscript shell command\n\n"
if len(dir) > 0:
scripttext = scripttext + 'import os\n\nos.chdir("' + dir + '")\n\n'
if inprompt:
scripttext = scripttext + 'DrFrame.Execute("' + cmd + ' ' + args + '", "Running Shell Command")\n\n'
else:
scripttext = scripttext + 'wx.Shell("' + cmd + ' ' + args + '")\n\n'
cfile.write(scripttext)
cfile.close()
self.Append((self.ID_SCRIPT_BASE + self.scriptcount), title, title)
self.parent.Bind(wx.EVT_MENU, self.OnScript, id=(self.ID_SCRIPT_BASE + self.scriptcount))
self.scripts.append(filen)
self.titles.append(title)
x = len(self.parent.DrScriptShortcuts)
self.parent.DrScriptShortcuts.append('')
self.parent.DrScriptShortcutNames.append(title)
self.scriptcount = self.scriptcount + 1
try:
f = open(scriptfile, 'a')
f.write("" + filen + "" + title + "\n")
f.close()
shortcutsfile = self.userpreferencesdirectory + "/drscript.shortcuts.dat"
drShortcutsFile.WriteShortcuts(shortcutsfile, self.parent.DrScriptShortcuts, self.parent.DrScriptShortcutNames, "", False)
except:
drScrolledMessageDialog.ShowMessage(self.parent, ("Problem saving script.\n"), "Error")
dlg.Destroy()
def OnDynamicScript(self, event):
from drDynamicDrScriptDialog import drDynamicDrScriptDialog
d = drDynamicDrScriptDialog(self.parent, self.dynamicscriptext)
d.ShowModal()
self.dynamicscriptext = d.GetText()
d.Destroy()
def OnEditScript(self, event):
if (len(self.scripts) > 0):
def tuplify(x, y):
return (x, y)
def detuplify(x):
return x[0]
array = map(tuplify, self.titles, self.scripts)
array.sort()
titles = map(detuplify, array)
d = wx.SingleChoiceDialog(self.parent, "Select the Script to Edit:", "Edit Script", titles, wx.OK|wx.CANCEL)
d.SetSize(wx.Size(250, 250))
answer = d.ShowModal()
d.Destroy()
if (answer == wx.ID_OK):
i = d.GetSelection()
old = self.parent.txtDocument.filename
filename = array[i][1].replace("\\", "/")
alreadyopen = map(lambda x: x.filename.replace("\\", "/"), self.parent.txtDocumentArray)
if filename in alreadyopen:
self.parent.setDocumentTo(alreadyopen.index(filename))
return
if (len(old) > 0) or (self.parent.txtDocument.GetModify()):
self.parent.OpenFile(filename, True, False)
else:
self.parent.OpenFile(filename, False, False)
else:
drScrolledMessageDialog.ShowMessage(self.parent, ("There aren't any scripts to edit.\nTry \"New Script\" or \"Add Script\" Instead."), "Error")
def OnScript(self, event):
scriptindex = event.GetId() - self.ID_SCRIPT_BASE
f = open(self.scripts[scriptindex], 'r')
scripttext = f.read()
f.close()
if (scripttext.find("DrFilename") > -1):
scripttext = scripttext.replace("DrFilename", "self.parent.txtDocument.filename")
if (scripttext.find("DrScript") > -1):
scripttext = scripttext.replace("DrScript", "self.parent.DrScript")
if (scripttext.find("DrDocument") > -1):
scripttext = scripttext.replace("DrDocument", "self.parent.txtDocument")
if (scripttext.find("DrPrompt") > -1):
scripttext = scripttext.replace("DrPrompt", "self.parent.txtPrompt")
if (scripttext.find("DrFrame") > -1):
scripttext = scripttext.replace("DrFrame", "self.parent")
try:
code = compile((scripttext + '\n'), self.scripts[scriptindex], 'exec')
except:
drScrolledMessageDialog.ShowMessage(self.parent, ("Error compiling script."), "Error", wx.DefaultPosition, wx.Size(550,300))
return
try:
exec(code)
except:
drScrolledMessageDialog.ShowMessage(self.parent, ("Error running script."), "Error", wx.DefaultPosition, wx.Size(550,300))
return
def setupMenu(self):
addscriptmenu = wx.Menu()
addscriptmenu.Append(self.ID_NEW_SCRIPT, "&New Script...")
addscriptmenu.Append(self.ID_EXISTING_SCRIPT, "&Existing Script...")
addscriptmenu.Append(self.ID_SHELL_COMMAND, "&Shell Command...")
self.AppendMenu(self.ID_ADD_SCRIPT, "&Add Script", addscriptmenu)
self.Append(self.ID_EDIT_SCRIPT, "&Edit Script...")
self.Append(self.ID_DYNAMIC_SCRIPT, "&Dynamic DrScript...")
self.AppendSeparator()
self.parent.Bind(wx.EVT_MENU, self.OnAddExistingScript, id=self.ID_EXISTING_SCRIPT)
self.parent.Bind(wx.EVT_MENU, self.OnAddNewScript, id=self.ID_NEW_SCRIPT)
self.parent.Bind(wx.EVT_MENU, self.OnAddShellCommand, id=self.ID_SHELL_COMMAND)
self.parent.Bind(wx.EVT_MENU, self.OnEditScript, id=self.ID_EDIT_SCRIPT)
self.parent.Bind(wx.EVT_MENU, self.OnDynamicScript, id=self.ID_DYNAMIC_SCRIPT)
def reloadscripts(self, oldlength = -1, SyncShortcuts = 1):
if oldlength < 0:
oldlength = len(self.scripts)
mnuitems = self.GetMenuItems()
num = len(mnuitems)
x = 0
while (x < num):
self.Remove(mnuitems[x].GetId())
#mnuitems[x].Destroy()
x = x + 1
self.scripts = []
self.titles = []
self.setupMenu()
self.loadscripts(SyncShortcuts)