# Programmer: Franz Steinhaeusler
# E-mail: francescoa@users.sourceforge.net
# Note: You must reply to the verification e-mail to get through.
#
# Copyright 2004-2005 Franz Steinhaeusler
#
# 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
#Plugin
#ListShortCuts
#Version 0.0.0, 10.01.2005:
#Version 0.0.1, 11.01.2005:
#Version 0.0.2, 22.02.2005: adapted to DrPython 3.10.8
#Version 0.0.3, 23.02.2005: adapted to DrPython 3.10.10
import wx
import re
#table copied from wxPython demo Keycodes
keyMap = {
wx.WXK_BACK : "wx.WXK_BACK",
wx.WXK_TAB : "wx.WXK_TAB",
wx.WXK_RETURN : "wx.WXK_RETURN",
wx.WXK_ESCAPE : "wx.WXK_ESCAPE",
wx.WXK_SPACE : "wx.WXK_SPACE",
wx.WXK_DELETE : "wx.WXK_DELETE",
wx.WXK_START : "wx.WXK_START",
wx.WXK_LBUTTON : "wx.WXK_LBUTTON",
wx.WXK_RBUTTON : "wx.WXK_RBUTTON",
wx.WXK_CANCEL : "wx.WXK_CANCEL",
wx.WXK_MBUTTON : "wx.WXK_MBUTTON",
wx.WXK_CLEAR : "wx.WXK_CLEAR",
wx.WXK_SHIFT : "wx.WXK_SHIFT",
wx.WXK_ALT : "wx.WXK_ALT",
wx.WXK_CONTROL : "wx.WXK_CONTROL",
wx.WXK_MENU : "wx.WXK_MENU",
wx.WXK_PAUSE : "wx.WXK_PAUSE",
wx.WXK_CAPITAL : "wx.WXK_CAPITAL",
wx.WXK_PRIOR : "wx.WXK_PRIOR",
wx.WXK_NEXT : "wx.WXK_NEXT",
wx.WXK_END : "wx.WXK_END",
wx.WXK_HOME : "wx.WXK_HOME",
wx.WXK_LEFT : "wx.WXK_LEFT",
wx.WXK_UP : "wx.WXK_UP",
wx.WXK_RIGHT : "wx.WXK_RIGHT",
wx.WXK_DOWN : "wx.WXK_DOWN",
wx.WXK_SELECT : "wx.WXK_SELECT",
wx.WXK_PRINT : "wx.WXK_PRINT",
wx.WXK_EXECUTE : "wx.WXK_EXECUTE",
wx.WXK_SNAPSHOT : "wx.WXK_SNAPSHOT",
wx.WXK_INSERT : "wx.WXK_INSERT",
wx.WXK_HELP : "wx.WXK_HELP",
wx.WXK_NUMPAD0 : "wx.WXK_NUMPAD0",
wx.WXK_NUMPAD1 : "wx.WXK_NUMPAD1",
wx.WXK_NUMPAD2 : "wx.WXK_NUMPAD2",
wx.WXK_NUMPAD3 : "wx.WXK_NUMPAD3",
wx.WXK_NUMPAD4 : "wx.WXK_NUMPAD4",
wx.WXK_NUMPAD5 : "wx.WXK_NUMPAD5",
wx.WXK_NUMPAD6 : "wx.WXK_NUMPAD6",
wx.WXK_NUMPAD7 : "wx.WXK_NUMPAD7",
wx.WXK_NUMPAD8 : "wx.WXK_NUMPAD8",
wx.WXK_NUMPAD9 : "wx.WXK_NUMPAD9",
wx.WXK_MULTIPLY : "wx.WXK_MULTIPLY",
wx.WXK_ADD : "wx.WXK_ADD",
wx.WXK_SEPARATOR : "wx.WXK_SEPARATOR",
wx.WXK_SUBTRACT : "wx.WXK_SUBTRACT",
wx.WXK_DECIMAL : "wx.WXK_DECIMAL",
wx.WXK_DIVIDE : "wx.WXK_DIVIDE",
wx.WXK_F1 : "wx.WXK_F1",
wx.WXK_F2 : "wx.WXK_F2",
wx.WXK_F3 : "wx.WXK_F3",
wx.WXK_F4 : "wx.WXK_F4",
wx.WXK_F5 : "wx.WXK_F5",
wx.WXK_F6 : "wx.WXK_F6",
wx.WXK_F7 : "wx.WXK_F7",
wx.WXK_F8 : "wx.WXK_F8",
wx.WXK_F9 : "wx.WXK_F9",
wx.WXK_F10 : "wx.WXK_F10",
wx.WXK_F11 : "wx.WXK_F11",
wx.WXK_F12 : "wx.WXK_F12",
wx.WXK_F13 : "wx.WXK_F13",
wx.WXK_F14 : "wx.WXK_F14",
wx.WXK_F15 : "wx.WXK_F15",
wx.WXK_F16 : "wx.WXK_F16",
wx.WXK_F17 : "wx.WXK_F17",
wx.WXK_F18 : "wx.WXK_F18",
wx.WXK_F19 : "wx.WXK_F19",
wx.WXK_F20 : "wx.WXK_F20",
wx.WXK_F21 : "wx.WXK_F21",
wx.WXK_F22 : "wx.WXK_F22",
wx.WXK_F23 : "wx.WXK_F23",
wx.WXK_F24 : "wx.WXK_F24",
wx.WXK_NUMLOCK : "wx.WXK_NUMLOCK",
wx.WXK_SCROLL : "wx.WXK_SCROLL",
wx.WXK_PAGEUP : "wx.WXK_PAGEUP",
wx.WXK_PAGEDOWN : "wx.WXK_PAGEDOWN",
wx.WXK_NUMPAD_SPACE : "wx.WXK_NUMPAD_SPACE",
wx.WXK_NUMPAD_TAB : "wx.WXK_NUMPAD_TAB",
wx.WXK_NUMPAD_ENTER : "wx.WXK_NUMPAD_ENTER",
wx.WXK_NUMPAD_F1 : "wx.WXK_NUMPAD_F1",
wx.WXK_NUMPAD_F2 : "wx.WXK_NUMPAD_F2",
wx.WXK_NUMPAD_F3 : "wx.WXK_NUMPAD_F3",
wx.WXK_NUMPAD_F4 : "wx.WXK_NUMPAD_F4",
wx.WXK_NUMPAD_HOME : "wx.WXK_NUMPAD_HOME",
wx.WXK_NUMPAD_LEFT : "wx.WXK_NUMPAD_LEFT",
wx.WXK_NUMPAD_UP : "wx.WXK_NUMPAD_UP",
wx.WXK_NUMPAD_RIGHT : "wx.WXK_NUMPAD_RIGHT",
wx.WXK_NUMPAD_DOWN : "wx.WXK_NUMPAD_DOWN",
wx.WXK_NUMPAD_PRIOR : "wx.WXK_NUMPAD_PRIOR",
wx.WXK_NUMPAD_PAGEUP : "wx.WXK_NUMPAD_PAGEUP",
wx.WXK_NUMPAD_NEXT : "wx.WXK_NUMPAD_NEXT",
wx.WXK_NUMPAD_PAGEDOWN : "wx.WXK_NUMPAD_PAGEDOWN",
wx.WXK_NUMPAD_END : "wx.WXK_NUMPAD_END",
wx.WXK_NUMPAD_BEGIN : "wx.WXK_NUMPAD_BEGIN",
wx.WXK_NUMPAD_INSERT : "wx.WXK_NUMPAD_INSERT",
wx.WXK_NUMPAD_DELETE : "wx.WXK_NUMPAD_DELETE",
wx.WXK_NUMPAD_EQUAL : "wx.WXK_NUMPAD_EQUAL",
wx.WXK_NUMPAD_MULTIPLY : "wx.WXK_NUMPAD_MULTIPLY",
wx.WXK_NUMPAD_ADD : "wx.WXK_NUMPAD_ADD",
wx.WXK_NUMPAD_SEPARATOR : "wx.WXK_NUMPAD_SEPARATOR",
wx.WXK_NUMPAD_SUBTRACT : "wx.WXK_NUMPAD_SUBTRACT",
wx.WXK_NUMPAD_DECIMAL : "wx.WXK_NUMPAD_DECIMAL",
wx.WXK_NUMPAD_DIVIDE : "wx.WXK_NUMPAD_DIVIDE",
#added Franz(don't know a constant)
226 : "wx.WXK_<",
}
def Plugin(DrFrame):
class ListShortCutsDialog(wx.Dialog):
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title, wx.DefaultPosition, (800, 438),\
wx.DEFAULT_DIALOG_STYLE | wx.MAXIMIZE_BOX | wx.THICK_FRAME | wx.RESIZE_BORDER)
self.results = wx.ListCtrl (self, -1, wx.DefaultPosition, (780, 400), wx.LC_REPORT|wx.SUNKEN_BORDER )
self.results.InsertColumn(0, "Function", wx.LIST_FORMAT_LEFT, 200)
self.results.InsertColumn(1, "Ass.", wx.LIST_FORMAT_LEFT, 40)
self.results.InsertColumn(2, "Shift", wx.LIST_FORMAT_LEFT, 40)
self.results.InsertColumn(3, "Ctrl", wx.LIST_FORMAT_LEFT, 40)
self.results.InsertColumn(4, "Alt", wx.LIST_FORMAT_LEFT, 40)
self.results.InsertColumn(5, "Meta", wx.LIST_FORMAT_LEFT, 40)
self.results.InsertColumn(6, "key", wx.LIST_FORMAT_LEFT, 130)
self.results.InsertColumn(7, "kcode", wx.LIST_FORMAT_LEFT, 50)
self.results.InsertColumn(8, "Source", wx.LIST_FORMAT_LEFT, 180)
self.data = []
shortcuts = [DrFrame.Shortcuts, DrFrame.STCShortcuts, DrFrame.DrScriptShortcuts, DrFrame.PluginShortcuts]
shortcutname = [DrFrame.ShortcutNames, DrFrame.STCShortcutNames, DrFrame.DrScriptShortcutNames, DrFrame.PluginShortcutNames]
self.rekeycode = re.compile('\d+')
n_ass = 0
for i in range (4):
for j in range (len (shortcuts[i])):
fn = ""
if i < 3:
fn = shortcutname [i][j]
ass = ""
if shortcuts[i][j] != '':
ass = "*"
n_ass += 1
shift = ""
if shortcuts[i][j].find ("Shift") != -1:
shift = "Shift"
control = ""
if shortcuts[i][j].find ("Control") != -1:
control = "Ctrl"
alt = ""
if shortcuts[i][j].find ("Alt") != -1:
alt = "Alt"
meta = ""
if shortcuts[i][j].find ("Meta") != -1:
meta = "Meta"
k = -1
try:
k = self.GetKeycodeFromShortcut(shortcuts[i][j])
except:
pass
keycode = ""
if k != -1 and ass != "":
if k < 127 and k > 32:
key = chr(k)
else:
keyname = keyMap.get(k, None)
if keyname is None:
keycode = k
if keycode < 256:
if keycode == 0:
keyname = "NUL"
elif keycode < 27:
keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
else:
keyname = "\"%s\"" % chr(keycode)
else:
keyname = "unknown (%s)" % keycode
else:
keyname = keyname [7:]
key = keyname
keycode = str(k)
#sourcename
sname = ""
if i == 0:
sname = "Standard"
elif i == 1:
sname = "Text Control"
elif i == 2:
sname = "DrScript"
elif i == 3:
pos = shortcutname [i][j].find (':')
if pos != -1:
sname = shortcutname [i][j][:pos]
fn = shortcutname [i][j][pos+1:]
else:
sname = "Plugin?"
ass = ""
self.data.append ([fn, ass, shift, control, alt, meta, key, keycode, sname])
self.SetTitle (self.GetTitle() + " [Total: %d, thereof assigned: %d]" % (len (self.data), n_ass))
for i in range (len(self.data)):
self.results.InsertStringItem(i, self.data [i][0])
self.results.SetStringItem(i, 1, self.data [i][1])
self.results.SetStringItem(i, 2, self.data [i][2])
self.results.SetStringItem(i, 3, self.data [i][3])
self.results.SetStringItem(i, 4, self.data [i][4])
self.results.SetStringItem(i, 5, self.data [i][5])
self.results.SetStringItem(i, 6, self.data [i][6])
self.results.SetStringItem(i, 7, self.data [i][7])
self.results.SetStringItem(i, 8, self.data [i][8])
self.results.SetItemData(i, i)
for i in range (len(self.data)):
if self.data [i][1] != "":
sname = self.data [i][8]
item = self.results.GetItem (i)
if sname == "Standard":
#item.SetTextColour (wx.Colour(208, 255, 255))
item.SetBackgroundColour(wx.Colour(255, 255, 208))
elif sname == "Text Control":
item.SetBackgroundColour(wx.Colour(208, 255, 255))
elif sname == "DrScript":
item.SetBackgroundColour(wx.Colour(208, 255, 208))
else:
item.SetBackgroundColour(wx.Colour(255, 208, 255))
self.results.SetItem(item)
self.oldsortcolumn = 1
self.nCol = 1
self.sort_asc = True
self.SortHeader()
self.Bind(wx.EVT_LIST_KEY_DOWN, self.OnChar, id = -1)
self.Bind(wx.EVT_LIST_COL_CLICK, self.OnHeaderClick, id = -1)
self.results.Bind (wx.EVT_RIGHT_DOWN, self.OnRightDown)
# for wxMSW
self.results.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
# for wxGTK
self.results.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
def GetKeycodeFromShortcut(self, shortcut):
kstr = self.rekeycode.search(shortcut)
if kstr is not None:
try:
k = int(kstr.group())
except:
return 0
return k
return 0
def OnRightDown (self, event):
self.x = event.GetX()
self.y = event.GetY()
lx, ly = self.results.GetPosition()
self.y += ly
self.x += lx
item, flags = self.results.HitTest((self.x, self.y))
if flags & wx.LIST_HITTEST_ONITEM:
self.results.Select(item)
event.Skip()
def OnRightClick(self, event):
# only do this part the first time so the events are only bound once
if not hasattr(self, "popupID1"):
self.popupID1 = wx.NewId()
self.results.Bind(wx.EVT_MENU, self.OnPopupExportCSV, id = self.popupID1)
menu = wx.Menu()
menu.Append(self.popupID1, "Export as Csv")
self.results.PopupMenu(menu, (self.x, self.y))
menu.Destroy()
def OnPopupExportCSV (self, event):
dlg = wx.FileDialog(DrFrame, "Export Csv to:", DrFrame.ddirectory, "shortcuts.csv", ".csv", wx.SAVE)
if dlg.ShowModal() == wx.ID_OK:
sfile = dlg.GetPath().replace("\\", '/')
f = file(sfile, 'w')
f.write ("Function;Ass.;Shift;Ctrl;Alt;Meta;key;kcode;Source\n")
for i in self.data:
for j in i:
f.write (j +';')
f.write ('\n')
f.close()
def OnChar (self, event):
if event.GetKeyCode() == wx.WXK_ESCAPE:
self.Destroy()
else:
event.Skip()
def OnHeaderClick(self, event):
self.nCol = event.GetColumn()
self.SortHeader()
event.Skip()
def SortHeader(self):
if self.oldsortcolumn != self.nCol:
self.sort_asc = True
self.oldsortcolumn = self.nCol
else:
self.sort_asc = not self.sort_asc
self.results.SortItems(self.columnSorter)
def columnSorter(self, key1, key2):
if not self.sort_asc:
key1, key2 = key2, key1
if self.nCol == 7:
try:
item1 = int (self.data[key1][self.nCol])
except:
item1 = 1000
try:
item2 = int (self.data[key2][self.nCol])
except:
item2 = 1000
else:
item1 = self.data[key1][self.nCol].lower()
item2 = self.data[key2][self.nCol].lower()
if self.nCol == 1:
if item1 == item2:
item1 = self.data[key1][2].lower()
item2 = self.data[key2][2].lower()
if item1 == item2:
item1 = self.data[key1][3].lower()
item2 = self.data[key2][3].lower()
if item1 == item2:
item1 = self.data[key1][4].lower()
item2 = self.data[key2][4].lower()
if item1 == item2:
try:
item1 = int (self.data[key1][7])
except:
item1 = -1
try:
item2 = int (self.data[key2][7])
except:
item2 = -1
if item1 == item2:
return 0
elif item1 > item2:
return -1
else:
return 1
return 0
elif item1 > item2:
return -1
else:
return 1
elif item1 > item2:
return -1
else:
return 1
elif item1 > item2:
return -1
else:
return 1
return 0
elif item1 < item2:
return -1
else:
return 1
else:
if item1 == item2:
return 0
elif item1 < item2:
return -1
else:
return 1
def OnListShortCuts (event):
d = ListShortCutsDialog(DrFrame, -1, "List Shortcuts")
d.Show()
ID_LISTSHORTCUTS = DrFrame.GetNewId()
DrFrame.Bind(wx.EVT_MENU, OnListShortCuts, id = ID_LISTSHORTCUTS)
DrFrame.AddPluginShortcutFunction("ListShortCuts", "List ShortCuts", OnListShortCuts)
DrFrame.AddPluginPopUpMenuFunction("ListShortCuts", "List ShortCuts", OnListShortCuts)
DrFrame.LoadPluginShortcuts('ListShortCuts')
DrFrame.optionsmenu.AppendSeparator()
DrFrame.optionsmenu.Append(ID_LISTSHORTCUTS, DrFrame.GetPluginMenuLabel('ListShortCuts', 'List ShortCuts', 'List ShortCuts'))