keybindings.py :  » Development » Leo » Leo-4.7.1-final » leo » plugins » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » Leo 
Leo » Leo 4.7.1 final » leo » plugins » keybindings.py
#@+leo-ver=4-thin
#@+node:ekr.20060703162506:@thin keybindings.py
#@<< docstring >>
#@+node:pap.20060703102546.1:<< docstring >>
"""KeyBindings - shows what key bindings are in effect.

The plugin allows you to explore the current bindings
and search for particular keys or bindings. You can also
see what commands are available but not bound currently.

The plugin includes a "Print" function to print out
a subset of the bindings so that you can create a handy
reference chart.

At a future time it might even allow editing!

"""
#@nonl
#@-node:pap.20060703102546.1:<< docstring >>
#@nl

__version__ = '0.2'
__plugin_name__ = "KeyBindings"
__plugin_priority__ = 1
__plugin_requires__ = ["plugin_menu"]
__plugin_group__ = "Helpers"


#@<< version history >>
#@+node:pap.20060703102546.2:<< version history >>
#@@killcolor
#@+at
# 
# Version 0.1 - (Paul Paterson) First created
# v 0.2 EKR: Use g.app.loadDir as a stable starting point for computing 
# plugins directory.
#@-at
#@nonl
#@-node:pap.20060703102546.2:<< version history >>
#@nl

#@<< imports >>
#@+node:pap.20060703102546.3:<< imports >>
import leo.core.leoGlobals as g
import leo.core.leoPlugins as leoPlugins
import leo.core.leoEditCommands as leoEditCommands

Pmw = g.importExtension('Pmw',    pluginName=__name__,verbose=True,required=True)
Tk  = g.importExtension('Tkinter',pluginName=__name__,verbose=True,required=True)

# Whatever other imports your plugins uses.
import fnmatch
import os
import webbrowser
#@nonl
#@-node:pap.20060703102546.3:<< imports >>
#@nl

thePluginController = None

#@+others
#@+node:pap.20060703102546.4:init
def init ():

    ok = Pmw and Tk

    if ok:
        if g.app.gui is None:
            g.app.createTkGui(__file__)

        ok = g.app.gui.guiName() == "tkinter"

        if ok:
            if 1: # Use this if you want to create the commander class before the frame is fully created.
                leoPlugins.registerHandler('before-create-leo-frame',onCreate)
            else: # Use this if you want to create the commander class after the frame is fully created.
                leoPlugins.registerHandler('after-create-leo-frame',onCreate)
            g.plugin_signon(__name__)

    return ok
#@nonl
#@-node:pap.20060703102546.4:init
#@+node:pap.20060703102546.5:onCreate
def onCreate (tag, keys):

    c = keys.get('c')
    if not c: return

    global thePluginController
    thePluginController = pluginController(c)

#@-node:pap.20060703102546.5:onCreate
#@+node:pap.20060703102832:topLevelMenu
# This is called from plugins_menu plugin.

def topLevelMenu(c):   
    """Show all key bindgins"""
    thePluginController.onClick()
#@nonl
#@-node:pap.20060703102832:topLevelMenu
#@+node:pap.20060703104701:inColumns
def inColumns(data, columnwidths):
    """Return the items of data with the specified column widths

    The list of widths should be one less than the list of data, eg
        inColumns((10,20,30), (5,5))
    """
    format = ""
    for col in columnwidths:
        format += "%%-%ds" % col
    format += "%s"
    #
    return format % data
#@-node:pap.20060703104701:inColumns
#@+node:pap.20060703103820:class KeyHandlerDialog
class KeyHandlerDialog:
    """The dialog to show the key handlers"""

    #@    @+others
    #@+node:pap.20060703103942:__init__
    def __init__ (self,c):

        self.c = c
        # Warning: hook handlers must use keywords.get('c'), NOT self.c.

        #@    << Main window >>
        #@+node:pap.20060703130408:<< Main window >>
        root = g.app.root
        top = Tk.Toplevel(root)

        self.root = root
        self.top = top

        g.app.gui.attachLeoIcon(top)
        top.title("Leo Key Bindings")
        #@nonl
        #@-node:pap.20060703130408:<< Main window >>
        #@nl

        self.filter_pane = "Bound only"
        self.filter_keys = "*"
        self.filter_commands = "*"
        self.sort_by = "By key"

        self.getAllCommands()    
        self.populateKeys()

        #@    << Frames >>
        #@+node:pap.20060703105742:<< Frames >>
        self.upper = Pmw.Group(top,
            tag_text='Filtering',
        )
        self.upper.pack(side="top", fill='both', expand=0, padx=5, pady=5)
        upper = self.upper.interior()

        self.middle = middle = Tk.Frame(top)
        self.middle.pack(side="top", fill='both', expand=1, padx=5, pady=5)

        #@-node:pap.20060703105742:<< Frames >>
        #@nl
        #@    << Filtering >>
        #@+node:pap.20060703112856:<< Filtering >>
        self.pane = Pmw.OptionMenu(upper,
                labelpos = 'w',
                label_text = 'Pane:',
                items = self.pane_list,
                menubutton_width = 16,
                command=self.filterPane,
        )    
        self.pane.pack(side="left")

        self.keys = Pmw.EntryField(upper,
                labelpos = 'w',
                value = '',
                label_text = 'Key:',
                modifiedcommand = self.filterKey)
        self.keys.pack(side="left", padx=10)

        self.commands = Pmw.EntryField(upper,
                labelpos = 'w',
                value = '',
                label_text = 'Commands:',
                modifiedcommand = self.filterCommands)
        self.commands.pack(side="left", padx=10)

        self.sorting = Pmw.OptionMenu(upper,
                labelpos = 'w',
                label_text = 'Sort:',
                items = ['By key', 'By command', 'By pane'],
                menubutton_width = 16,
                command = self.sortItems)
        self.sorting.pack(side="left", padx=10)


        self.printable = Tk.Button(upper, 
                text = "Print", 
                width = 16,
                command = self.printKeys)
        self.printable.pack(side="right", fill="none", expand=0, padx=20)


        #@-node:pap.20060703112856:<< Filtering >>
        #@nl
        #@    << List >>
        #@+node:pap.20060703123943:<< List >>
        self.box = Pmw.ScrolledListBox(middle,
                labelpos='nw',
                label_text='Active key bindings:',
                listbox_height = 6,
                selectioncommand=self.onClick,
                usehullsize = 1,
                hull_width = 300,
                hull_height = 600,
        )
        #@nonl
        #@-node:pap.20060703123943:<< List >>
        #@nl

        self.box.setlist(self.bindings)    
        self.box.component("listbox").configure(font=("Courier", 8))
        self.box.pack(side="bottom", fill='both', expand=1)    

        #top.grab_set() # Make the dialog a modal dialog.
        #top.focus_force() # Get all keystrokes.
        #root.wait_window(top)
    #@nonl
    #@-node:pap.20060703103942:__init__
    #@+node:pap.20060703104556:populateKeys
    def populateKeys(self):
        """Populate the list of keys"""
        dct = self.c.keyHandler.masterBindingsDict
        bindings = []
        self.pane_list = ["Bound only", "Unbound only", "Show all", "---"] + dct.keys()
        #
        match = fnmatch.fnmatch
        #
        for pane in dct:
            if self.filter_pane in ("Show all", "Bound only", pane):
                for binding in dct[pane].values():
                    if match(binding.stroke, self.filter_keys) and match(binding.commandName, self.filter_commands):
                        bindings.append([
                            inColumns(
                                (binding.pane, binding.stroke, binding.commandName),
                                (10, 25)),
                            binding.stroke,
                            binding.commandName,
                            binding.pane,
                        ])

        if self.filter_pane in ("Show all", "Unbound only"):
            self.addUnboundCommands(bindings)

        sorter = {
            "By key" : lambda item1, item2 : cmp(item1[1], item2[1]),
            "By command" : lambda item1, item2 : cmp(item1[2], item2[2]),
            "By pane" : lambda item1, item2 : cmp(item1[3], item2[3]),
    }

        bindings.sort(sorter[self.sort_by])
        self.full_bindings = bindings

        self.bindings = [item[0] for item in bindings] 
    #@nonl
    #@-node:pap.20060703104556:populateKeys
    #@+node:pap.20060703104111:onClick
    def onClick(self):
        """The menu item was clicked"""
        #import pdb; pdb.set_trace()
    #@nonl
    #@-node:pap.20060703104111:onClick
    #@+node:pap.20060703105742.1:filterPane
    def filterPane(self, filter="Show all"):
        """Filter the list on panes"""
        self.filter_pane = filter
        self.populateKeys()
        self.box.setlist(self.bindings)
    #@-node:pap.20060703105742.1:filterPane
    #@+node:pap.20060703111744:filterKey
    def filterKey(self):
        """Filter the list on the keystroke"""
        self.filter_keys = "*%s*" % self.keys.getvalue()
        self.populateKeys()
        self.box.setlist(self.bindings)
    #@-node:pap.20060703111744:filterKey
    #@+node:pap.20060703112417:filterCommands
    def filterCommands(self):
        """Filter the list on the command"""
        self.filter_commands = "*%s*" % self.commands.getvalue()
        self.populateKeys()
        self.box.setlist(self.bindings)
    #@-node:pap.20060703112417:filterCommands
    #@+node:pap.20060703113646:sortItems
    def sortItems(self, sort="By key"):
        """Sort the items"""
        self.sort_by = sort
        self.populateKeys()
        self.box.setlist(self.bindings)
    #@-node:pap.20060703113646:sortItems
    #@+node:pap.20060703123659:printKeys
    def printKeys(self):
        """Print the keys"""
        fname = os.path.abspath(g.os_path_join(g.app.loadDir,"..", "plugins", "keyreport.html"))
        f = file(fname, "w")
        report = ["<html><title>Leo Key Bindings</title><body>"
                  '<link type="text/css" rel="stylesheet" href="keys.css" />',
                  "<table>",
                    "<tr><th colspan=2>Report</th></tr>"
                    "<tr><td>Pane</td><td>%(filter_pane)s</td></tr>"
                    "<tr><td>Key filter</td><td>%(filter_keys)s</td></tr>"
                    "<tr><td>Command filter</td><td>%(filter_commands)s</td></tr>"
                    "<tr><td>Sorted</td><td>%(sort_by)s</td></tr>" 
                  "</table>" % self.__dict__,
                  "<table>",
                    "<tr><th>Pane</th><th>Key</th><th>Command</th></tr>",
        ]

        for item in self.full_bindings:
            _, key, command, pane = item
            report.append("<tr><td>%s</td><td>%s</td><td>%s</td></tr>" % (pane, key, command))

        report.append("</table>")

        f.write("\n".join(report))
        f.close()

        webbrowser.open(fname)
    #@-node:pap.20060703123659:printKeys
    #@+node:pap.20060703131850:getAllCommands
    def getAllCommands(self):
        """Get a list of all the command that Leo understands"""
        classes = [item[1](self.c) for item in leoEditCommands.classesList]
        self.all_commands = []
        for cls in classes:
            cls.finishCreate()
            self.all_commands.extend(cls.getPublicCommands().keys())
    #@nonl
    #@-node:pap.20060703131850:getAllCommands
    #@+node:pap.20060703132904:addUnboundCommands
    def addUnboundCommands(self, bindings):
        """Add the unbound commands in there"""
        match = fnmatch.fnmatch
        for cmd in self.all_commands:
            if match(cmd, self.filter_commands):
                bindings.append([
                    inColumns(
                        ("unbound", "no key", cmd),
                        (10, 25)),
                    "no key",
                    cmd,
                    "unbound",
                ])
    #@-node:pap.20060703132904:addUnboundCommands
    #@-others
#@nonl
#@-node:pap.20060703103820:class KeyHandlerDialog
#@+node:pap.20060703102546.6:class pluginController
class pluginController:

    #@    @+others
    #@+node:pap.20060703102546.7:__init__
    def __init__ (self,c):

        self.c = c
        # Warning: hook handlers must use keywords.get('c'), NOT self.c.


    #@-node:pap.20060703102546.7:__init__
    #@+node:pap.20060703103603:onClick
    def onClick(self):
        """The menu item was clicked"""
        dialog = KeyHandlerDialog(self.c)
    #@-node:pap.20060703103603:onClick
    #@-others
#@nonl
#@-node:pap.20060703102546.6:class pluginController
#@-others
#@nonl
#@-node:ekr.20060703162506:@thin keybindings.py
#@-leo
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.