Kaydet (Commit) 19302d92 authored tarafından Ronald Oussoren's avatar Ronald Oussoren

This patch improves the L&F of IDLE on OSX. The changes are conditionalized on

being in an IDLE.app bundle on darwin. This does a slight reorganisation of the
menus and adds support for file-open events.
üst 6aaccc6b
...@@ -80,6 +80,32 @@ menudefs = [ ...@@ -80,6 +80,32 @@ menudefs = [
]), ]),
] ]
import sys
if sys.platform == 'darwin' and '.app' in sys.executable:
# Running as a proper MacOS application bundle. This block restructures
# the menus a little to make them conform better to the HIG.
quitItem = menudefs[0][1][-1]
closeItem = menudefs[0][1][-2]
# Remove the last 3 items of the file menu: a separator, close window and
# quit. Close window will be reinserted just above the save item, where
# it should be according to the HIG. Quit is in the application menu.
del menudefs[0][1][-3:]
menudefs[0][1].insert(6, closeItem)
# Remove the 'About' entry from the help menu, it is in the application
# menu
del menudefs[-1][1][0:2]
menudefs.insert(0,
('application', [
('About IDLE', '<<about-idle>>'),
None,
('_Preferences....', '<<open-config-dialog>>'),
]))
default_keydefs = idleConf.GetCurrentKeySet() default_keydefs = idleConf.GetCurrentKeySet()
del sys del sys
...@@ -17,6 +17,7 @@ import ReplaceDialog ...@@ -17,6 +17,7 @@ import ReplaceDialog
import PyParse import PyParse
from configHandler import idleConf from configHandler import idleConf
import aboutDialog, textView, configDialog import aboutDialog, textView, configDialog
import macosxSupport
# The default tab setting for a Text widget, in average-width characters. # The default tab setting for a Text widget, in average-width characters.
TK_TABWIDTH_DEFAULT = 8 TK_TABWIDTH_DEFAULT = 8
...@@ -66,9 +67,18 @@ class EditorWindow(object): ...@@ -66,9 +67,18 @@ class EditorWindow(object):
'Python%d%d.chm' % sys.version_info[:2]) 'Python%d%d.chm' % sys.version_info[:2])
if os.path.isfile(chmfile): if os.path.isfile(chmfile):
dochome = chmfile dochome = chmfile
elif macosxSupport.runningAsOSXApp():
# documentation is stored inside the python framework
dochome = os.path.join(sys.prefix,
'Resources/English.lproj/Documentation/index.html')
dochome = os.path.normpath(dochome) dochome = os.path.normpath(dochome)
if os.path.isfile(dochome): if os.path.isfile(dochome):
EditorWindow.help_url = dochome EditorWindow.help_url = dochome
if sys.platform == 'darwin':
# Safari requires real file:-URLs
EditorWindow.help_url = 'file://' + EditorWindow.help_url
else: else:
EditorWindow.help_url = "http://www.python.org/doc/current" EditorWindow.help_url = "http://www.python.org/doc/current"
currentTheme=idleConf.CurrentTheme() currentTheme=idleConf.CurrentTheme()
...@@ -278,6 +288,10 @@ class EditorWindow(object): ...@@ -278,6 +288,10 @@ class EditorWindow(object):
def set_status_bar(self): def set_status_bar(self):
self.status_bar = self.MultiStatusBar(self.top) self.status_bar = self.MultiStatusBar(self.top)
if macosxSupport.runningAsOSXApp():
# Insert some padding to avoid obscuring some of the statusbar
# by the resize widget.
self.status_bar.set_label('_padding1', ' ', side=RIGHT)
self.status_bar.set_label('column', 'Col: ?', side=RIGHT) self.status_bar.set_label('column', 'Col: ?', side=RIGHT)
self.status_bar.set_label('line', 'Ln: ?', side=RIGHT) self.status_bar.set_label('line', 'Ln: ?', side=RIGHT)
self.status_bar.pack(side=BOTTOM, fill=X) self.status_bar.pack(side=BOTTOM, fill=X)
...@@ -301,6 +315,11 @@ class EditorWindow(object): ...@@ -301,6 +315,11 @@ class EditorWindow(object):
("help", "_Help"), ("help", "_Help"),
] ]
if macosxSupport.runningAsOSXApp():
del menu_specs[-3]
menu_specs[-2] = ("windows", "_Window")
def createmenubar(self): def createmenubar(self):
mbar = self.menubar mbar = self.menubar
self.menudict = menudict = {} self.menudict = menudict = {}
...@@ -308,6 +327,12 @@ class EditorWindow(object): ...@@ -308,6 +327,12 @@ class EditorWindow(object):
underline, label = prepstr(label) underline, label = prepstr(label)
menudict[name] = menu = Menu(mbar, name=name) menudict[name] = menu = Menu(mbar, name=name)
mbar.add_cascade(label=label, menu=menu, underline=underline) mbar.add_cascade(label=label, menu=menu, underline=underline)
if sys.platform == 'darwin' and '.framework' in sys.executable:
# Insert the application menu
menudict['application'] = menu = Menu(mbar, name='apple')
mbar.add_cascade(label='IDLE', menu=menu)
self.fill_menus() self.fill_menus()
self.base_helpmenu_length = self.menudict['help'].index(END) self.base_helpmenu_length = self.menudict['help'].index(END)
self.reset_help_menu_entries() self.reset_help_menu_entries()
......
...@@ -11,6 +11,7 @@ import time ...@@ -11,6 +11,7 @@ import time
import threading import threading
import traceback import traceback
import types import types
import macosxSupport
import linecache import linecache
from code import InteractiveInterpreter from code import InteractiveInterpreter
...@@ -777,6 +778,11 @@ class PyShell(OutputWindow): ...@@ -777,6 +778,11 @@ class PyShell(OutputWindow):
("help", "_Help"), ("help", "_Help"),
] ]
if macosxSupport.runningAsOSXApp():
del menu_specs[-3]
menu_specs[-2] = ("windows", "_Window")
# New classes # New classes
from IdleHistory import History from IdleHistory import History
...@@ -1371,9 +1377,12 @@ def main(): ...@@ -1371,9 +1377,12 @@ def main():
enable_shell = enable_shell or not edit_start enable_shell = enable_shell or not edit_start
# start editor and/or shell windows: # start editor and/or shell windows:
root = Tk(className="Idle") root = Tk(className="Idle")
fixwordbreaks(root) fixwordbreaks(root)
root.withdraw() root.withdraw()
flist = PyShellFileList(root) flist = PyShellFileList(root)
macosxSupport.setupApp(root, flist)
if enable_edit: if enable_edit:
if not (cmd or script): if not (cmd or script):
for filename in args: for filename in args:
...@@ -1381,8 +1390,17 @@ def main(): ...@@ -1381,8 +1390,17 @@ def main():
if not args: if not args:
flist.new() flist.new()
if enable_shell: if enable_shell:
if not flist.open_shell(): shell = flist.open_shell()
if not shell:
return # couldn't open shell return # couldn't open shell
if macosxSupport.runningAsOSXApp() and flist.dict:
# On OSX: when the user has double-clicked on a file that causes
# IDLE to be launched the shell window will open just in front of
# the file she wants to see. Lower the interpreter window when
# there are open files.
shell.top.lower()
shell = flist.pyshell shell = flist.pyshell
# handle remaining options: # handle remaining options:
if debug: if debug:
...@@ -1403,6 +1421,7 @@ def main(): ...@@ -1403,6 +1421,7 @@ def main():
elif script: elif script:
shell.interp.prepend_syspath(script) shell.interp.prepend_syspath(script)
shell.interp.execfile(script) shell.interp.execfile(script)
root.mainloop() root.mainloop()
root.destroy() root.destroy()
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import re import re
import sys import sys
import macosxSupport
class ZoomHeight: class ZoomHeight:
...@@ -29,6 +30,14 @@ def zoom_height(top): ...@@ -29,6 +30,14 @@ def zoom_height(top):
if sys.platform == 'win32': if sys.platform == 'win32':
newy = 0 newy = 0
newheight = newheight - 72 newheight = newheight - 72
elif macosxSupport.runningAsOSXApp():
# The '88' below is a magic number that avoids placing the bottom
# of the window below the panel on my machine. I don't know how
# to calculate the correct value for this with tkinter.
newy = 22
newheight = newheight - newy - 88
else: else:
#newy = 24 #newy = 24
newy = 0 newy = 0
......
#
# After running python setup.py install, run this program from the command
# line like so:
#
# % python2.3 buildapp.py build
#
# A double-clickable IDLE application will be created in the build/ directory.
#
from bundlebuilder import buildapp
buildapp(
name="IDLE",
mainprogram="idle.py",
argv_emulation=1,
iconfile="Icons/idle.icns",
)
...@@ -20,6 +20,7 @@ configuration problem notification and resolution. ...@@ -20,6 +20,7 @@ configuration problem notification and resolution.
import os import os
import sys import sys
import string import string
import macosxSupport
from ConfigParser import ConfigParser, NoOptionError, NoSectionError from ConfigParser import ConfigParser, NoOptionError, NoSectionError
class InvalidConfigType(Exception): pass class InvalidConfigType(Exception): pass
...@@ -495,7 +496,18 @@ class IdleConf: ...@@ -495,7 +496,18 @@ class IdleConf:
return binding return binding
def GetCurrentKeySet(self): def GetCurrentKeySet(self):
return self.GetKeySet(self.CurrentKeys()) result = self.GetKeySet(self.CurrentKeys())
if macosxSupport.runningAsOSXApp():
# We're using AquaTk, replace all keybingings that use the
# Alt key by ones that use the Option key because the former
# don't work reliably.
for k, v in result.items():
v2 = [ x.replace('<Alt-', '<Option-') for x in v ]
if v != v2:
result[k] = v2
return result
def GetKeySet(self,keySetName): def GetKeySet(self,keySetName):
""" """
......
...@@ -133,7 +133,7 @@ class GetKeysDialog(Toplevel): ...@@ -133,7 +133,7 @@ class GetKeysDialog(Toplevel):
config-keys.def must use the same ordering. config-keys.def must use the same ordering.
""" """
import sys import sys
if sys.platform == 'darwin' and sys.executable.count('.app'): if sys.platform == 'darwin' and sys.argv[0].count('.app'):
self.modifiers = ['Shift', 'Control', 'Option', 'Command'] self.modifiers = ['Shift', 'Control', 'Option', 'Command']
else: else:
self.modifiers = ['Control', 'Alt', 'Shift'] self.modifiers = ['Control', 'Alt', 'Shift']
......
"""
A number of function that enhance IDLE on MacOSX when it used as a normal
GUI application (as opposed to an X11 application).
"""
import sys
def runningAsOSXApp():
""" Returns True iff running from the IDLE.app bundle on OSX """
return (sys.platform == 'darwin' and 'IDLE.app' in sys.argv[0])
def addOpenEventSupport(root, flist):
"""
This ensures that the application will respont to open AppleEvents, which
makes is feaseable to use IDLE as the default application for python files.
"""
def doOpenFile(*args):
for fn in args:
flist.open(fn)
# The command below is a hook in aquatk that is called whenever the app
# receives a file open event. The callback can have multiple arguments,
# one for every file that should be opened.
root.createcommand("::tk::mac::OpenDocument", doOpenFile)
def hideTkConsole(root):
root.tk.call('console', 'hide')
def setupApp(root, flist):
"""
Perform setup for the OSX application bundle.
"""
if not runningAsOSXApp(): return
hideTkConsole(root)
addOpenEventSupport(root, flist)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment