# -*- coding: utf-8 -*-
# @+leo-ver=5-thin
# @+node:ekr.20081121105001.80: * @file ./obsolete/ironPythonGui.py
# @@first

"""A plugin to use IronPython and .Net Forms as Leo's gui."""

__version__ = '0.6'

# print ('IronPythonGui 1')

# @+<< version history >>
# @+node:ekr.20081121105001.81: ** << version history >>
# @@nocolor
# @+at
# - Work begins: February 15, 2007
# @-<< version history >>
# @+<< imports >>
# @+node:ekr.20081121105001.82: ** << imports >>
import leo.core.leoGlobals as g
import leo.core.leoPlugins as leoPlugins

import sys
import System

import leo.core.leoGui as leoGui

# import Sytem.Windows.Forms

# sys.LoadAssemblyByName("System.Windows.Forms")
# @-<< imports >>

# print ('IronPythonGui 2')


# @+others
# @+node:ekr.20081121105001.83: ** Module level
# @+node:ekr.20081121105001.84: *3* init
def init():
    ok = (
        not g.app.unitTesting and System is not None
        # and System.Windows.Forms is not None
    )

    g.pr('ironPythonGui: init ok:', ok)

    if ok:
        g.app.gui = ironPythonGui()
        g.app.root = g.app.gui.createRootWindow()
        g.app.gui.finishCreate()
        g.plugin_signon(__name__)

    return ok


# @+node:ekr.20081121105001.85: ** ironPythonGui class
class ironPythonGui(leoGui.leoGui):
    # @+others
    # @+node:ekr.20081121105001.86: *3* gui birth & death
    # @+node:ekr.20081121105001.87: *4*  ipGui.__init__
    def __init__(self):
        # g.trace("ironPytonGui")

        # Initialize the base class.
        leoGui.leoGui.__init__(self, "IronPython")

    # @+node:ekr.20081121105001.88: *4* ip.Gui.createKeyHandlerClass
    def createKeyHandlerClass(self, c, useGlobalKillbuffer=True, useGlobalRegisters=True):
        return wxKeyHandlerClass(c, useGlobalKillbuffer, useGlobalRegisters)

    # @+node:ekr.20081121105001.89: *4* ip.createRootWindow
    def createRootWindow(self):
        self.root = f = System.Windows.Forms.Form()

        def click(*args):
            g.pr(args)

        f.Click += click

        if 0:  # Not ready yet.
            self.getDefaultConfigFont(g.app.config)
            self.setEncoding()

        return f

    # @+node:ekr.20081121105001.90: *4* createLeoFrame
    def createLeoFrame(self, title):
        """Create a new Leo frame."""

        return None  # ironPythonLeoFrame(title)

    # @+node:ekr.20081121105001.91: *4* destroySelf
    def destroySelf(self):
        pass  # Nothing more needs to be done once all windows have been destroyed.

    # @+node:ekr.20081121105001.92: *4* finishCreate
    def finishCreate(self):
        pass  # g.trace('ironPython gui')

    # @+node:ekr.20081121105001.93: *4* killGui
    def killGui(self, exitFlag=True):
        """Destroy a gui and terminate Leo if exitFlag is True."""

        pass  # Not ready yet.

    # @+node:ekr.20081121105001.94: *4* recreateRootWindow
    def recreateRootWindow(self):
        """A do-nothing base class to create the hidden root window of a gui

        after a previous gui has terminated with killGui(False)."""

        pass

    # @+node:ekr.20081121105001.95: *4* runMainLoop
    def runMainLoop(self):
        '''Run IronPython's main loop.'''

        System.Windows.Forms.Application.Run(g.app.root)

    # @+node:ekr.20081121105001.96: *3* gui dialogs
    # @+node:ekr.20081121105001.97: *4* runAboutLeoDialog
    def runAboutLeoDialog(self, c, version, copyright, url, email):
        """Create and run a wxPython About Leo dialog."""

        if g.app.unitTesting:
            return

        message = "%s\n\n%s\n\n%s\n\n%s" % (
            version.strip(),
            copyright.strip(),
            url.strip(),
            email.strip(),
        )

        wx.MessageBox(message, "About Leo", wx.Center, self.root)

    # @+node:ekr.20081121105001.98: *4* runAskOkDialog
    def runAskOkDialog(self, c, title, message=None, text="Ok"):
        """Create and run a wxPython askOK dialog ."""

        if g.app.unitTesting:
            return 'ok'

        d = wx.MessageDialog(self.root, message, "Leo", wx.OK)
        d.ShowModal()
        return "ok"

    # @+node:ekr.20081121105001.99: *4* runAskLeoIDDialog
    def runAskLeoIDDialog(self):
        """Create and run a dialog to get g.app.LeoID."""

        if g.app.unitTesting:
            return 'ekr'

        # to do

    # @+node:ekr.20081121105001.100: *4* runAskOkCancelNumberDialog (to do)
    def runAskOkCancelNumberDialog(self, c, title, message):
        """Create and run a wxPython askOkCancelNumber dialog ."""

        if g.app.unitTesting:
            return 666

        # to do.

    # @+node:ekr.20081121105001.101: *4* runAskOkCancelStringDialog (to do)
    def runAskOkCancelStringDialog(self, c, title, message):
        """Create and run a wxPython askOkCancelNumber dialog ."""

        if g.app.unitTesting:
            return 'xyzzy'

        # to do

    # @+node:ekr.20081121105001.102: *4* runAskYesNoDialog
    def runAskYesNoDialog(self, c, title, message=None):
        """Create and run a wxPython askYesNo dialog."""

        if g.app.unitTesting:
            return 'yes'

        d = wx.MessageDialog(self.root, message, "Leo", wx.YES_NO)
        answer = d.ShowModal()

        return g.choose(answer == wx.YES, "yes", "no")

    # @+node:ekr.20081121105001.103: *4* runAskYesNoCancelDialog
    def runAskYesNoCancelDialog(
        self, c, title, message=None, yesMessage="Yes", noMessage="No", defaultButton="Yes"
    ):
        """Create and run a wxPython askYesNoCancel dialog ."""

        if g.app.unitTesting:
            return 'yes'

        d = wx.MessageDialog(self.root, message, "Leo", wx.YES_NO | wx.CANCEL)
        answer = d.ShowModal()

        if answer == wx.ID_YES:
            return "yes"
        elif answer == wx.ID_NO:
            return "no"
        else:
            assert answer == wx.ID_CANCEL
            return "cancel"

    # @+node:ekr.20081121105001.104: *4* runCompareDialog
    def runCompareDialog(self, c):
        if g.app.unitTesting:
            return

        # To do

    # @+node:ekr.20081121105001.105: *4* runOpenFileDialog
    def runOpenFileDialog(self, title, filetypes, defaultextension):
        """Create and run a wxPython open file dialog ."""

        if g.app.unitTesting:
            return None

        wildcard = self.getWildcardList(filetypes)

        d = wx.FileDialog(
            parent=None,
            message=title,
            defaultDir="",
            defaultFile="",
            wildcard=wildcard,
            style=wx.OPEN | wx.CHANGE_DIR | wx.HIDE_READONLY,
        )

        val = d.ShowModal()
        if val == wx.ID_OK:
            file = d.GetFilename()
            return file
        else:
            return None

    # @+node:ekr.20081121105001.106: *4* runSaveFileDialog
    def runSaveFileDialog(self, initialfile, title, filetypes, defaultextension):
        """Create and run a wxPython save file dialog ."""

        if g.app.unitTesting:
            return None

        wildcard = self.getWildcardList(filetypes)

        d = wx.FileDialog(
            parent=None,
            message=title,
            defaultDir="",
            defaultFile="",
            wildcard=wildcard,
            style=wx.SAVE | wx.CHANGE_DIR | wx.OVERWRITE_PROMPT,
        )

        val = d.ShowModal()
        if val == wx.ID_OK:
            file = d.GetFilename()
            return file
        else:
            return None

    # @+node:ekr.20081121105001.107: *4* simulateDialog
    def simulateDialog(self, key, defaultVal=None):
        return defaultVal

    # @+node:ekr.20081121105001.108: *4* getWildcardList
    def getWildcardList(self, filetypes):
        """Create a wxWindows wildcard string for open/save dialogs."""

        if not filetypes:
            return "*.leo"

        if 1:  # Too bad: this is sooo wimpy.
            a, b = filetypes[0]
            return b

        else:  # This _sometimes_ works: wxWindows is driving me crazy!
            # wildcards = ["%s (%s)" % (a,b) for a,b in filetypes]
            wildcards = ["%s" % (b) for a, b in filetypes]
            wildcard = "|".join(wildcards)
            g.trace(wildcard)
            return wildcard

    # @+node:ekr.20081121105001.109: *3* gui events
    def event_generate(self, w, kind, *args, **keys):
        '''Generate an event.'''
        return w.event_generate(kind, *args, **keys)

    # @+node:ekr.20081121105001.110: *4* class leoKeyEvent (wxGui)
    class leoKeyEvent:
        '''A gui-independent wrapper for gui events.'''

        def __init__(self, event, c):
            gui = g.app.gui
            self.c = c
            self.actualEvent = event
            self.char = gui.eventChar(event)
            self.keysym = gui.eventKeysym(event)
            self.widget = gui.eventWidget(event)
            self.x, self.y = gui.eventXY(event)

            self.w = self.widget

    # @+node:ekr.20081121105001.111: *4* wxKeyDict
    wxKeyDict = {
        # Keys are wxWidgets key codes.  Values are the standard (Tk) names.
        wx.WXK_DECIMAL: '.',
        wx.WXK_BACK: '\b',  # 'BackSpace',
        wx.WXK_TAB: '\t',  # 'Tab',
        wx.WXK_RETURN: '\n',  # 'Return',
        wx.WXK_ESCAPE: 'Escape',
        wx.WXK_SPACE: ' ',
        wx.WXK_DELETE: 'Delete',
        wx.WXK_LEFT: 'Left',
        wx.WXK_UP: 'Up',
        wx.WXK_RIGHT: 'Right',
        wx.WXK_DOWN: 'Down',
        wx.WXK_F1: 'F1',
        wx.WXK_F2: 'F2',
        wx.WXK_F3: 'F3',
        wx.WXK_F4: 'F4',
        wx.WXK_F5: 'F5',
        wx.WXK_F6: 'F6',
        wx.WXK_F7: 'F7',
        wx.WXK_F8: 'F8',
        wx.WXK_F9: 'F9',
        wx.WXK_F10: 'F10',
        wx.WXK_F11: 'F11',
        wx.WXK_F12: 'F12',
        wx.WXK_END: 'End',
        wx.WXK_HOME: 'Home',
        wx.WXK_PAGEUP: 'Prior',
        wx.WXK_PAGEDOWN: 'Next',
        wx.WXK_NUMPAD_DELETE: 'Delete',
        wx.WXK_NUMPAD_SPACE: ' ',
        wx.WXK_NUMPAD_TAB: '\t',  # 'Tab',
        wx.WXK_NUMPAD_ENTER: '\n',  # 'Return',
        wx.WXK_NUMPAD_PAGEUP: 'Prior',
        wx.WXK_NUMPAD_PAGEDOWN: 'Next',
        wx.WXK_NUMPAD_END: 'End',
        wx.WXK_NUMPAD_BEGIN: 'Home',
    }

    # @+at These are by design not compatible with unicode characters.
    # If you want to get a unicode character from a key event use
    # wxKeyEvent::GetUnicodeKey instead.
    #
    # WXK_START   = 300
    # WXK_LBUTTON
    # WXK_RBUTTON
    # WXK_CANCEL
    # WXK_MBUTTON
    # WXK_CLEAR
    # WXK_SHIFT
    # WXK_ALT
    # WXK_CONTROL
    # WXK_MENU
    # WXK_PAUSE
    # WXK_CAPITAL
    # WXK_SELECT
    # WXK_PRINT
    # WXK_EXECUTE
    # WXK_SNAPSHOT
    # WXK_INSERT
    # WXK_HELP
    # WXK_NUMPAD0
    # WXK_NUMPAD1
    # WXK_NUMPAD2
    # WXK_NUMPAD3
    # WXK_NUMPAD4
    # WXK_NUMPAD5
    # WXK_NUMPAD6
    # WXK_NUMPAD7
    # WXK_NUMPAD8
    # WXK_NUMPAD9
    # WXK_MULTIPLY
    # WXK_ADD
    # WXK_SEPARATOR
    # WXK_SUBTRACT
    # WXK_DECIMAL
    # WXK_DIVIDE
    # WXK_F13
    # WXK_F14
    # WXK_F15
    # WXK_F16
    # WXK_F17
    # WXK_F18
    # WXK_F19
    # WXK_F20
    # WXK_F21
    # WXK_F22
    # WXK_F23
    # WXK_F24
    # WXK_NUMLOCK
    # WXK_SCROLL
    # WXK_NUMPAD_F1,
    # WXK_NUMPAD_F2,
    # WXK_NUMPAD_F3,
    # WXK_NUMPAD_F4,
    # WXK_NUMPAD_HOME,
    # WXK_NUMPAD_LEFT,
    # WXK_NUMPAD_UP,
    # WXK_NUMPAD_RIGHT,
    # WXK_NUMPAD_DOWN,
    # WXK_NUMPAD_INSERT,
    # WXK_NUMPAD_EQUAL,
    # WXK_NUMPAD_MULTIPLY,
    # WXK_NUMPAD_ADD,
    # WXK_NUMPAD_SEPARATOR,
    # WXK_NUMPAD_SUBTRACT,
    # WXK_NUMPAD_DECIMAL,
    # WXK_NUMPAD_DIVIDE,
    #
    # // the following key codes are only generated under Windows currently
    # WXK_WINDOWS_LEFT,
    # WXK_WINDOWS_RIGHT,
    # WXK_WINDOWS_MENU,
    # WXK_COMMAND,
    #
    # // Hardware-specific buttons
    # WXK_SPECIAL1 = 193,
    # WXK_SPECIAL2,
    # WXK_SPECIAL3,
    # WXK_SPECIAL4,
    # WXK_SPECIAL5,
    # WXK_SPECIAL6,
    # WXK_SPECIAL7,
    # WXK_SPECIAL8,
    # WXK_SPECIAL9,
    # WXK_SPECIAL10,
    # WXK_SPECIAL11,
    # WXK_SPECIAL12,
    # WXK_SPECIAL13,
    # WXK_SPECIAL14,
    # WXK_SPECIAL15,
    # WXK_SPECIAL16,
    # WXK_SPECIAL17,
    # WXK_SPECIAL18,
    # WXK_SPECIAL19,
    # WXK_SPECIAL20
    # @+node:ekr.20081121105001.112: *4* eventChar & eventKeysym & helper
    def eventChar(self, event):
        '''Return the char field of an event, either a wx event or a converted Leo event.'''

        if hasattr(event, 'char'):
            return event.char  # A leoKeyEvent.
        else:
            return self.keysymHelper(event, kind='char')

    def eventKeysym(self, event):
        if hasattr(event, 'keysym'):
            return event.keysym  # A leoKeyEvent: we have already computed the result.
        else:
            return self.keysymHelper(event, kind='keysym')

    # @+node:ekr.20081121105001.113: *5* keysymHelper
    def keysymHelper(self, event, kind):
        gui = self

        keycode = event.GetKeyCode()

        # g.trace(repr(keycode),kind)

        if keycode in (wx.WXK_SHIFT, wx.WXK_ALT, wx.WXK_CONTROL):
            return ''

        keysym = gui.wxKeyDict.get(keycode) or ''
        keyDownModifiers = hasattr(event, 'keyDownModifiers') and event.keyDownModifiers or None
        alt = event.AltDown() or keyDownModifiers == wx.MOD_ALT
        cmd = event.CmdDown() or keyDownModifiers == wx.MOD_CMD
        ctrl = event.ControlDown() or keyDownModifiers == wx.MOD_CONTROL
        meta = event.MetaDown() or keyDownModifiers == wx.MOD_META
        shift = event.ShiftDown() or keyDownModifiers == wx.MOD_SHIFT

        # Set the char field.
        char = keysym or ''
        if not char:
            # Avoid GetUnicodeKey if possible.  It crashes on '.' (!)
            try:
                char = chr(keycode)
            except ValueError:
                char = ''
        if not char and hasattr(event, 'GetUnicodeKey'):
            i = event.GetUnicodeKey()
            if i is None:
                char = ''
            else:
                try:
                    char = unichr(i)
                except Exception:
                    g.es('No translation for', repr(i))
                    char = repr(i)

        # Adjust the case, but only for plain ascii characters characters.
        if len(char) == 1:
            if char.isalpha():
                if shift:  # Case is also important for ctrl keys. # or alt or cmd or ctrl or meta:
                    char = char.upper()
                else:
                    char = char.lower()
            elif shift:
                char = self.getShiftChar(char)
            else:
                char = self.getUnshiftChar(char)

        # Create a value compatible with Leo's core.
        val = (
            g.choose(alt, 'Alt+', '')
            +
            # g.choose(cmd,'Cmd+','') +
            g.choose(ctrl, 'Ctrl+', '')
            + g.choose(meta, 'Meta+', '')
            + g.choose((alt or cmd or ctrl or meta) and shift, 'Shift+', '')
            + (char or '')
        )

        # if kind == 'char':  g.trace(repr(keycode),repr(val)) # Tracing just val can crash!
        return val

    # @+node:ekr.20081121105001.114: *5* getShiftChar
    def getShiftChar(self, char):
        d = {
            '1': '!',
            '2': '@',
            '3': '#',
            '4': '$',
            '5': '%',
            '6': '^',
            '7': '&',
            '8': '*',
            '9': '(',
            '0': ')',
            '-': '_',
            '=': '+',
            '[': '{',
            ']': '}',
            '\\': '|',
            ';': ':',
            "'": '"',
            ',': '<',
            '.': '>',
            '/': '?',
        }
        return d.get(char, char)  # There must be a better way.

    # @+node:ekr.20081121105001.115: *5* getUnshiftChar
    def getUnshiftChar(self, char):
        d = {'+': '='}
        return d.get(char, char)

    # @+node:ekr.20081121105001.116: *4* eventWidget
    def eventWidget(self, event):
        '''Return the widget field of an event.
        The event may be a wx event a converted Leo event or a manufactured event (a g.Bunch).'''

        if isinstance(event, self.leoKeyEvent):  # a leoKeyEvent.
            return event.widget
        elif isinstance(event, g.Bunch):  # A manufactured event.
            if hasattr(event, 'c'):
                return event.c.frame.body.bodyCtrl
            else:
                g.trace('k.generalModeHandler event')
                return None
        elif hasattr(event, 'GetEventObject'):  # A wx Event.
            return event.GetEventObject()
        else:
            g.trace('no event widget', event)
            return None

    # @+node:ekr.20081121105001.117: *4* eventXY
    def eventXY(self, event, c=None):
        if hasattr(event, 'x') and hasattr(event, 'y'):
            return event.x, event.y
        if hasattr(event, 'GetX') and hasattr(event, 'GetY'):
            return event.GetX(), event.GetY()
        else:
            return 0, 0

    # @+node:ekr.20081121105001.118: *3* gui panels (to do)
    # @+node:ekr.20081121105001.119: *4* createColorPanel
    def createColorPanel(self, c):
        """Create Color panel."""

        g.trace("not ready yet")

    # @+node:ekr.20081121105001.120: *4* createComparePanel
    def createComparePanel(self, c):
        """Create Compare panel."""

        g.trace("not ready yet")

    # @+node:ekr.20081121105001.121: *4* createFindPanel
    def createFindPanel(self):
        """Create a hidden Find panel."""

        return wxFindFrame()

    # @+node:ekr.20081121105001.122: *4* createFindTab
    def createFindTab(self, c, parentFrame):
        '''Create a wxWidgets find tab in the indicated frame.'''

        # g.trace(self.findTabHandler)

        if not self.findTabHandler:
            self.findTabHandler = wxFindTab(c, parentFrame)

        return self.findTabHandler

    # @+node:ekr.20081121105001.123: *4* createFontPanel
    def createFontPanel(self, c):
        """Create a Font panel."""

        g.trace("not ready yet")

    # @+node:ekr.20081121105001.124: *4* createSpellTab
    def createSpellTab(self, c, parentFrame):
        '''Create a wxWidgets spell tab in the indicated frame.'''

        if not self.spellTabHandler:
            self.spellTabHandler = wxSpellTab(c, parentFrame)

        return self.findTabHandler

    # @+node:ekr.20081121105001.125: *4* destroyLeoFrame (NOT USED)
    def destroyLeoFrame(self, frame):
        frame.Close()

    # @+node:ekr.20081121105001.126: *3* gui utils (must add several)
    # @+node:ekr.20081121105001.127: *4* Clipboard
    def replaceClipboardWith(self, s):
        cb = wx.TheClipboard
        if cb.Open():
            cb.Clear()
            cb.SetData(wx.TextDataObject(s))
            cb.Close()

    def getTextFromClipboard(self):
        cb = wx.TheClipboard
        if cb.Open():
            data = wx.TextDataObject()
            ok = cb.GetData(data)
            cb.Close()
            return ok and data.GetText() or ''
        else:
            return ''

    # @+node:ekr.20081121105001.128: *4* Constants
    # g.es calls gui.color to do the translation,
    # so most code in Leo's core can simply use Tk color names.

    def color(self, color):
        '''Return the gui-specific color corresponding to the Tk color name.'''
        return color  # Do not call oops: this method is essential for the config classes.

    # @+node:ekr.20081121105001.129: *4* Dialog
    # @+node:ekr.20081121105001.130: *5* bringToFront
    def bringToFront(self, window):
        if window.IsIconized():
            window.Maximize()
        window.Raise()
        window.Show(True)

    # @+node:ekr.20081121105001.131: *5* get_window_info
    def get_window_info(self, window):
        # Get the information about top and the screen.
        x, y = window.GetPosition()
        w, h = window.GetSize()

        return w, h, x, y

    # @+node:ekr.20081121105001.132: *5* center_dialog
    def center_dialog(window):
        window.Center()

    # @+node:ekr.20081121105001.133: *4* Focus
    # @+node:ekr.20081121105001.134: *5* get_focus
    def get_focus(self, top):
        """Returns the widget that has focus, or body if None."""

        return self.focus_widget

    # @+node:ekr.20081121105001.135: *5* set_focus
    def set_focus(self, c, w):
        """Set the focus of the widget in the given commander if it needs to be changed."""

        c.frame.setFocus(w)

    # @+node:ekr.20081121105001.136: *4* Font (wxGui) (to do)
    # @+node:ekr.20081121105001.137: *5* getFontFromParams
    def getFontFromParams(self, family, size, slant, weight):
        ## g.trace(g.app.config.defaultFont)

        return g.app.config.defaultFont  ##

        family_name = family

        try:
            font = tkFont.Font(family=family, size=size, slant=slant, weight=weight)
            # g.pr(family_name,family,size,slant,weight)
            # g.pr("actual_name:",font.cget("family"))
            return font
        except:
            g.es("exception setting font from " + repr(family_name))
            g.es(
                "family,size,slant,weight:"
                + repr(family)
                + ':'
                + repr(size)
                + ':'
                + repr(slant)
                + ':'
                + repr(weight)
            )
            g.es_exception()
            return g.app.config.defaultFont

    # @+node:ekr.20081121105001.138: *4* Icons (wxGui) (to do)
    # @+node:ekr.20081121105001.139: *5* attachLeoIcon
    def attachLeoIcon(self, w):
        """Try to attach a Leo icon to the Leo Window.

        Use tk's wm_iconbitmap function if available (tk 8.3.4 or greater).
        Otherwise, try to use the Python Imaging Library and the tkIcon package."""

        if self.bitmap != None:
            # We don't need PIL or tkicon: this is tk 8.3.4 or greater.
            try:
                w.wm_iconbitmap(self.bitmap)
            except:
                self.bitmap = None

        if self.bitmap == None:
            try:
                # @+<< try to use the PIL and tkIcon packages to draw the icon >>
                # @+node:ekr.20081121105001.140: *6* << try to use the PIL and tkIcon packages to draw the icon >>
                # @+at This code requires Fredrik Lundh's PIL and tkIcon packages:
                #
                # Download PIL    from http://www.pythonware.com/downloads/index.htm#pil
                # Download tkIcon from http://www.effbot.org/downloads/#tkIcon
                #
                # Many thanks to Jonathan M. Gilligan for suggesting this code.
                # @@c

                import Image, tkIcon, _tkicon

                # Wait until the window has been drawn once before attaching the icon in OnVisiblity.
                def visibilityCallback(event, self=self, w=w):
                    try:
                        self.leoIcon.attach(w.winfo_id())
                    except:
                        pass

                # Don't use c.bind here: c is not available.
                w.bind("<Visibility>", visibilityCallback)
                if not self.leoIcon:
                    # Load a 16 by 16 gif.  Using .gif rather than an .ico allows us to specify transparency.
                    icon_file_name = os.path.join(g.app.loadDir, '..', 'Icons', 'LeoWin.gif')
                    icon_file_name = os.path.normpath(icon_file_name)
                    icon_image = Image.open(icon_file_name)
                    if 1:  # Doesn't resize.
                        self.leoIcon = self.createLeoIcon(icon_image)
                    else:  # Assumes 64x64
                        self.leoIcon = tkIcon.Icon(icon_image)
                # @-<< try to use the PIL and tkIcon packages to draw the icon >>
            except:
                # traceback.print_exc()
                self.leoIcon = None

    # @+node:ekr.20081121105001.141: *5* createLeoIcon
    # This code is adapted from tkIcon.__init__
    # Unlike the tkIcon code, this code does _not_ resize the icon file.

    def createLeoIcon(self, icon):
        try:
            import Image, tkIcon, _tkicon

            i = icon
            m = None
            # create transparency mask
            if i.mode == "P":
                try:
                    t = i.info["transparency"]
                    m = i.point(lambda i, t=t: i == t, "1")
                except KeyError:
                    pass
            elif i.mode == "RGBA":
                # get transparency layer
                m = i.split()[3].point(lambda i: i == 0, "1")
            if not m:
                m = Image.new("1", i.size, 0)  # opaque
            # clear unused parts of the original image
            i = i.convert("RGB")
            i.paste((0, 0, 0), (0, 0), m)
            # create icon
            m = m.tostring("raw", ("1", 0, 1))
            c = i.tostring("raw", ("BGRX", 0, -1))
            return _tkicon.new(i.size, c, m)
        except:
            return None

    # @+node:ekr.20081121105001.142: *4* Idle time (wxGui) (to do)
    # @+node:ekr.20081121105001.143: *5* setIdleTimeHook
    def setIdleTimeHook(self, idleTimeHookHandler, *args, **keys):
        pass  # g.trace(idleTimeHookHandler)

    # @+node:ekr.20081121105001.144: *5* setIdleTimeHookAfterDelay
    def setIdleTimeHookAfterDelay(self, idleTimeHookHandler, *args, **keys):
        g.trace(idleTimeHookHandler)

    # @+node:ekr.20081121105001.145: *4* isTextWidget
    def isTextWidget(self, w):
        for theClass in (wx.TextCtrl, wx.richtext.RichTextCtrl, wx.stc.StyledTextCtrl):
            if isinstance(w, theClass):
                return True
        else:
            return False

    # @+node:ekr.20081121105001.146: *4* widget_name
    def widget_name(self, w):
        # First try the wxWindow.GetName method.
        # All wx Text widgets, including wx.stc.StyledControl, have this method.
        if hasattr(w, 'GetName'):
            name = w.GetName()
        else:
            name = repr(w)
        return name

    # @-others


# @-others
# @-leo
