123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- # toolmenu.py
- import win32ui
- import win32con
- import win32api
- from . import app
- import sys
- import string
- tools = {}
- idPos = 100
- # The default items should no tools menu exist in the INI file.
- defaultToolMenuItems = [
- ('Browser', 'win32ui.GetApp().OnViewBrowse(0,0)'),
- ('Browse PythonPath', 'from pywin.tools import browseProjects;browseProjects.Browse()'),
- ('Edit Python Path', 'from pywin.tools import regedit;regedit.EditRegistry()'),
- ('COM Makepy utility', 'from win32com.client import makepy;makepy.main()'),
- ('COM Browser', 'from win32com.client import combrowse;combrowse.main()'),
- ('Trace Collector Debugging tool', 'from pywin.tools import TraceCollector;TraceCollector.MakeOutputWindow()'),
- ]
- def LoadToolMenuItems():
- # Load from the registry.
- items = []
- lookNo = 1
- while 1:
- menu = win32ui.GetProfileVal("Tools Menu\\%s" % lookNo, "", "")
- if menu=="":
- break
- cmd = win32ui.GetProfileVal("Tools Menu\\%s" % lookNo, "Command", "")
- items.append((menu, cmd))
- lookNo = lookNo + 1
- if len(items)==0:
- items = defaultToolMenuItems
- return items
- def WriteToolMenuItems( items ):
- # Items is a list of (menu, command)
- # Delete the entire registry tree.
- try:
- mainKey = win32ui.GetAppRegistryKey()
- toolKey = win32api.RegOpenKey(mainKey, "Tools Menu")
- except win32ui.error:
- toolKey = None
- if toolKey is not None:
- while 1:
- try:
- subkey = win32api.RegEnumKey(toolKey, 0)
- except win32api.error:
- break
- win32api.RegDeleteKey(toolKey, subkey)
- # Keys are now removed - write the new ones.
- # But first check if we have the defaults - and if so, dont write anything!
- if items==defaultToolMenuItems:
- return
- itemNo = 1
- for menu, cmd in items:
- win32ui.WriteProfileVal("Tools Menu\\%s" % itemNo, "", menu)
- win32ui.WriteProfileVal("Tools Menu\\%s" % itemNo, "Command", cmd)
- itemNo = itemNo + 1
-
- def SetToolsMenu(menu, menuPos = None):
- global tools
- global idPos
-
- # todo - check the menu does not already exist.
- # Create the new menu
- toolsMenu = win32ui.CreatePopupMenu()
-
- # Load from the ini file.
- items = LoadToolMenuItems()
- for menuString, cmd in items:
- tools[idPos] = (menuString, cmd, menuString)
- toolsMenu.AppendMenu(win32con.MF_ENABLED|win32con.MF_STRING,idPos, menuString)
- win32ui.GetMainFrame().HookCommand(HandleToolCommand, idPos)
- idPos=idPos+1
- # Find the correct spot to insert the new tools menu.
- if menuPos is None:
- menuPos = menu.GetMenuItemCount()-2
- if menuPos<0: menuPos=0
- menu.InsertMenu(menuPos, win32con.MF_BYPOSITION|win32con.MF_ENABLED|win32con.MF_STRING|win32con.MF_POPUP, toolsMenu.GetHandle(), '&Tools')
- def HandleToolCommand(cmd, code):
- import traceback
- import re
- global tools
- (menuString, pyCmd, desc) = tools[cmd]
- win32ui.SetStatusText("Executing tool %s" % desc, 1)
- pyCmd = re.sub('\\\\n','\n', pyCmd)
- win32ui.DoWaitCursor(1)
- oldFlag = None
- try:
- oldFlag = sys.stdout.template.writeQueueing
- sys.stdout.template.writeQueueing = 0
- except (NameError, AttributeError):
- pass
-
- try:
- exec("%s\n" % pyCmd)
- worked=1
- except SystemExit:
- # The program raised a SystemExit - ignore it.
- worked = 1
- except:
- print("Failed to execute command:\n%s" % pyCmd)
- traceback.print_exc()
- worked=0
- if oldFlag is not None:
- sys.stdout.template.writeQueueing = oldFlag
- win32ui.DoWaitCursor(0)
- if worked:
- text = "Completed successfully."
- else:
- text = "Error executing %s." % desc
- win32ui.SetStatusText(text, 1)
- # The property page for maintaing the items on the Tools menu.
- import commctrl
- from pywin.mfc import dialog
- if win32ui.UNICODE:
- LVN_ENDLABELEDIT = commctrl.LVN_ENDLABELEDITW
- else:
- LVN_ENDLABELEDIT = commctrl.LVN_ENDLABELEDITA
- class ToolMenuPropPage(dialog.PropertyPage):
- def __init__(self):
- self.bImChangingEditControls = 0 # Am I programatically changing the controls?
- dialog.PropertyPage.__init__(self, win32ui.IDD_PP_TOOLMENU)
- def OnInitDialog(self):
- self.editMenuCommand = self.GetDlgItem(win32ui.IDC_EDIT2)
- self.butNew = self.GetDlgItem(win32ui.IDC_BUTTON3)
-
- # Now hook the change notification messages for the edit controls.
- self.HookCommand(self.OnCommandEditControls, win32ui.IDC_EDIT1)
- self.HookCommand(self.OnCommandEditControls, win32ui.IDC_EDIT2)
- self.HookNotify(self.OnNotifyListControl, commctrl.LVN_ITEMCHANGED)
- self.HookNotify(self.OnNotifyListControlEndLabelEdit, commctrl.LVN_ENDLABELEDIT)
-
- # Hook the button clicks.
- self.HookCommand(self.OnButtonNew, win32ui.IDC_BUTTON3) # New Item
- self.HookCommand(self.OnButtonDelete, win32ui.IDC_BUTTON4) # Delete item
- self.HookCommand(self.OnButtonMove, win32ui.IDC_BUTTON1) # Move up
- self.HookCommand(self.OnButtonMove, win32ui.IDC_BUTTON2) # Move down
- # Setup the columns in the list control
- lc = self.GetDlgItem(win32ui.IDC_LIST1)
- rect = lc.GetWindowRect()
- cx = rect[2] - rect[0]
- colSize = cx/2 - win32api.GetSystemMetrics(win32con.SM_CXBORDER) - 1
- item = commctrl.LVCFMT_LEFT, colSize, "Menu Text"
- lc.InsertColumn(0, item)
- item = commctrl.LVCFMT_LEFT, colSize, "Python Command"
- lc.InsertColumn(1, item)
- # Insert the existing tools menu
- itemNo = 0
- for desc, cmd in LoadToolMenuItems():
- lc.InsertItem(itemNo, desc)
- lc.SetItemText(itemNo, 1, cmd)
- itemNo = itemNo + 1
- self.listControl = lc
- return dialog.PropertyPage.OnInitDialog(self)
- def OnOK(self):
- # Write the menu back to the registry.
- items = []
- itemLook = 0
- while 1:
- try:
- text = self.listControl.GetItemText(itemLook, 0);
- if not text:
- break
- items.append( (text, self.listControl.GetItemText(itemLook, 1)) )
- except win32ui.error:
- # no more items!
- break
- itemLook = itemLook + 1
- WriteToolMenuItems( items )
- return self._obj_.OnOK()
- def OnCommandEditControls(self, id, cmd):
- # print "OnEditControls", id, cmd
- if cmd==win32con.EN_CHANGE and not self.bImChangingEditControls:
- itemNo = self.listControl.GetNextItem(-1, commctrl.LVNI_SELECTED)
- newText = self.editMenuCommand.GetWindowText()
- self.listControl.SetItemText(itemNo, 1, newText)
- return 0
-
- def OnNotifyListControlEndLabelEdit(self, id, cmd):
- newText = self.listControl.GetEditControl().GetWindowText()
- itemNo = self.listControl.GetNextItem(-1, commctrl.LVNI_SELECTED)
- self.listControl.SetItemText(itemNo, 0, newText)
- def OnNotifyListControl(self, id, cmd):
- # print id, cmd
- try:
- itemNo = self.listControl.GetNextItem(-1, commctrl.LVNI_SELECTED)
- except win32ui.error: # No selection!
- return
- self.bImChangingEditControls = 1
- try:
- item = self.listControl.GetItem(itemNo, 1)
- self.editMenuCommand.SetWindowText(item[4])
- finally:
- self.bImChangingEditControls = 0
-
- return 0 # we have handled this!
- def OnButtonNew(self, id, cmd):
- if cmd==win32con.BN_CLICKED:
- newIndex = self.listControl.GetItemCount()
- self.listControl.InsertItem(newIndex, "Click to edit the text")
- self.listControl.EnsureVisible(newIndex, 0)
- def OnButtonMove(self, id, cmd):
- if cmd==win32con.BN_CLICKED:
- try:
- itemNo = self.listControl.GetNextItem(-1, commctrl.LVNI_SELECTED)
- except win32ui.error:
- return
- menu = self.listControl.GetItemText(itemNo, 0)
- cmd = self.listControl.GetItemText(itemNo, 1)
- if id == win32ui.IDC_BUTTON1:
- # Move up
- if itemNo > 0:
- self.listControl.DeleteItem(itemNo)
- # reinsert it.
- self.listControl.InsertItem(itemNo-1, menu)
- self.listControl.SetItemText(itemNo-1, 1, cmd)
- else:
- # Move down.
- if itemNo < self.listControl.GetItemCount()-1:
- self.listControl.DeleteItem(itemNo)
- # reinsert it.
- self.listControl.InsertItem(itemNo+1, menu)
- self.listControl.SetItemText(itemNo+1, 1, cmd)
- def OnButtonDelete(self, id, cmd):
- if cmd==win32con.BN_CLICKED:
- try:
- itemNo = self.listControl.GetNextItem(-1, commctrl.LVNI_SELECTED)
- except win32ui.error: # No selection!
- return
- self.listControl.DeleteItem(itemNo)
|