summaryrefslogtreecommitdiffstats
path: root/Tools/idle
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2003-04-29 11:27:16 (GMT)
committerGuido van Rossum <guido@python.org>2003-04-29 11:27:16 (GMT)
commita3c253e83b248df1562c3ac2a5be3cf3504432f8 (patch)
tree9aff2fe100549b3af220796679673e616b9aa8d6 /Tools/idle
parent767d9fedc797fcddb16cdba8ce0268b503ee13d1 (diff)
downloadcpython-a3c253e83b248df1562c3ac2a5be3cf3504432f8.zip
cpython-a3c253e83b248df1562c3ac2a5be3cf3504432f8.tar.gz
cpython-a3c253e83b248df1562c3ac2a5be3cf3504432f8.tar.bz2
Removing new files accidentally checked in on the trunk rather than on the
idlefork-merge-branch.
Diffstat (limited to 'Tools/idle')
-rw-r--r--Tools/idle/CREDITS.txt36
-rw-r--r--Tools/idle/HISTORY.txt180
-rw-r--r--Tools/idle/INSTALL.txt51
-rw-r--r--Tools/idle/LICENSE.txt50
-rw-r--r--Tools/idle/Makefile8
-rw-r--r--Tools/idle/RemoteDebugger.py381
-rw-r--r--Tools/idle/RemoteObjectBrowser.py36
-rw-r--r--Tools/idle/aboutDialog.py126
-rw-r--r--Tools/idle/boolcheck.py9
-rw-r--r--Tools/idle/config-extensions.def54
-rw-r--r--Tools/idle/config-highlight.def60
-rw-r--r--Tools/idle/config-keys.def155
-rw-r--r--Tools/idle/config-main.def65
-rw-r--r--Tools/idle/configDialog.py1134
-rw-r--r--Tools/idle/configHandler.py655
-rw-r--r--Tools/idle/configHelpSourceEdit.py157
-rw-r--r--Tools/idle/configSectionNameDialog.py97
-rw-r--r--Tools/idle/dynOptionMenuWidget.py35
-rw-r--r--Tools/idle/interruptmodule.c49
-rw-r--r--Tools/idle/keybindingDialog.py262
-rw-r--r--Tools/idle/macosx_main.py42
-rw-r--r--Tools/idle/rpc.py580
-rw-r--r--Tools/idle/run.py216
-rw-r--r--Tools/idle/setup.cfg4
-rw-r--r--Tools/idle/tabpage.py113
-rw-r--r--Tools/idle/textView.py77
26 files changed, 0 insertions, 4632 deletions
diff --git a/Tools/idle/CREDITS.txt b/Tools/idle/CREDITS.txt
deleted file mode 100644
index fd7af95..0000000
--- a/Tools/idle/CREDITS.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-IDLEfork Credits
-==================
-
-Guido van Rossum, as well as being the creator of the Python language, is
-the original creator of IDLE. He also developed the RPC code and Remote
-Debugger extension used in IDLEfork.
-
-The IDLEfork project was initiated and brought up to version 0.7.1 primarily
-by David Scherer, with help from Peter Schneider-Kamp and Nicholas Riley.
-Bruce Sherwood has contributed considerable time testing and suggesting
-improvements.
-
-Besides Guido, the main developers who have been active on IDLEfork version
-0.8.1 and later are Stephen M. Gava, who implemented the Configuration GUI, the
-new configuration system, and the new About menu, and Kurt B. Kaiser, who
-completed the integration of the RPC and remote debugger, and made a number of
-usability enhancements.
-
-Other contributors include Raymond Hettinger, Tony Lownds (Mac integration),
-Neal Norwitz (code check and clean-up), and Chui Tey (RPC integration, debugger
-integration and persistent breakpoints).
-
-Hernan Foffani, Christos Georgiou, Jason Orendorff, Josh Robb, and Bruce
-Sherwood have submitted useful patches. Thanks, guys!
-
-There are others who should be included here, especially those who contributed
-to IDLE versions prior to 0.8, principally Mark Hammond, Jeremy Hylton,
-Tim Peters, and Moshe Zadka. For additional details refer to NEWS.txt and
-Changelog.
-
-Please contact the IDLEfork maintainer to have yourself included here if you
-are one of those we missed!
-
-Contact details at http://idlefork.sourceforge.net
-
-
diff --git a/Tools/idle/HISTORY.txt b/Tools/idle/HISTORY.txt
deleted file mode 100644
index 9312f32..0000000
--- a/Tools/idle/HISTORY.txt
+++ /dev/null
@@ -1,180 +0,0 @@
-IDLE History
-============
-
-This file contains the release messages for previous IDLE releases.
-As you read on you go back to the dark ages of IDLE's history.
-
-
-IDLE 0.5 - February 2000 - Release Notes
-----------------------------------------
-
-This is an early release of IDLE, my own attempt at a Tkinter-based
-IDE for Python.
-
-(For a more detailed change log, see the file ChangeLog.)
-
-FEATURES
-
-IDLE has the following features:
-
-- coded in 100% pure Python, using the Tkinter GUI toolkit (i.e. Tcl/Tk)
-
-- cross-platform: works on Windows and Unix (on the Mac, there are
-currently problems with Tcl/Tk)
-
-- multi-window text editor with multiple undo, Python colorizing
-and many other features, e.g. smart indent and call tips
-
-- Python shell window (a.k.a. interactive interpreter)
-
-- debugger (not complete, but you can set breakpoints, view and step)
-
-USAGE
-
-The main program is in the file "idle.py"; on Unix, you should be able
-to run it by typing "./idle.py" to your shell. On Windows, you can
-run it by double-clicking it; you can use idle.pyw to avoid popping up
-a DOS console. If you want to pass command line arguments on Windows,
-use the batch file idle.bat.
-
-Command line arguments: files passed on the command line are executed,
-not opened for editing, unless you give the -e command line option.
-Try "./idle.py -h" to see other command line options.
-
-IDLE requires Python 1.5.2, so it is currently only usable with a
-Python 1.5.2 distribution. (An older version of IDLE is distributed
-with Python 1.5.2; you can drop this version on top of it.)
-
-COPYRIGHT
-
-IDLE is covered by the standard Python copyright notice
-(http://www.python.org/doc/Copyright.html).
-
-
-New in IDLE 0.5 (2/15/2000)
----------------------------
-
-Tons of stuff, much of it contributed by Tim Peters and Mark Hammond:
-
-- Status bar, displaying current line/column (Moshe Zadka).
-
-- Better stack viewer, using tree widget. (XXX Only used by Stack
-Viewer menu, not by the debugger.)
-
-- Format paragraph now recognizes Python block comments and reformats
-them correctly (MH)
-
-- New version of pyclbr.py parses top-level functions and understands
-much more of Python's syntax; this is reflected in the class and path
-browsers (TP)
-
-- Much better auto-indent; knows how to indent the insides of
-multi-line statements (TP)
-
-- Call tip window pops up when you type the name of a known function
-followed by an open parenthesis. Hit ESC or click elsewhere in the
-window to close the tip window (MH)
-
-- Comment out region now inserts ## to make it stand out more (TP)
-
-- New path and class browsers based on a tree widget that looks
-familiar to Windows users
-
-- Reworked script running commands to be more intuitive: I/O now
-always goes to the *Python Shell* window, and raw_input() works
-correctly. You use F5 to import/reload a module: this adds the module
-name to the __main__ namespace. You use Control-F5 to run a script:
-this runs the script *in* the __main__ namespace. The latter also
-sets sys.argv[] to the script name
-
-
-New in IDLE 0.4 (4/7/99)
-------------------------
-
-Most important change: a new menu entry "File -> Path browser", shows
-a 4-column hierarchical browser which lets you browse sys.path,
-directories, modules, and classes. Yes, it's a superset of the Class
-browser menu entry. There's also a new internal module,
-MultiScrolledLists.py, which provides the framework for this dialog.
-
-
-New in IDLE 0.3 (2/17/99)
--------------------------
-
-Most important changes:
-
-- Enabled support for running a module, with or without the debugger.
-Output goes to a new window. Pressing F5 in a module is effectively a
-reload of that module; Control-F5 loads it under the debugger.
-
-- Re-enable tearing off the Windows menu, and make a torn-off Windows
-menu update itself whenever a window is opened or closed.
-
-- Menu items can now be have a checkbox (when the menu label starts
-with "!"); use this for the Debugger and "Auto-open stack viewer"
-(was: JIT stack viewer) menu items.
-
-- Added a Quit button to the Debugger API.
-
-- The current directory is explicitly inserted into sys.path.
-
-- Fix the debugger (when using Python 1.5.2b2) to use canonical
-filenames for breakpoints, so these actually work. (There's still a
-lot of work to be done to the management of breakpoints in the
-debugger though.)
-
-- Closing a window that is still colorizing now actually works.
-
-- Allow dragging of the separator between the two list boxes in the
-class browser.
-
-- Bind ESC to "close window" of the debugger, stack viewer and class
-browser. It removes the selection highlighting in regular text
-windows. (These are standard Windows conventions.)
-
-
-New in IDLE 0.2 (1/8/99)
-------------------------
-
-Lots of changes; here are the highlights:
-
-General:
-
-- You can now write and configure your own IDLE extension modules; see
-extend.txt.
-
-
-File menu:
-
-The command to open the Python shell window is now in the File menu.
-
-
-Edit menu:
-
-New Find dialog with more options; replace dialog; find in files dialog.
-
-Commands to tabify or untabify a region.
-
-Command to format a paragraph.
-
-
-Debug menu:
-
-JIT (Just-In-Time) stack viewer toggle -- if set, the stack viewer
-automaticall pops up when you get a traceback.
-
-Windows menu:
-
-Zoom height -- make the window full height.
-
-
-Help menu:
-
-The help text now show up in a regular window so you can search and
-even edit it if you like.
-
-
-
-IDLE 0.1 was distributed with the Python 1.5.2b1 release on 12/22/98.
-
-======================================================================
diff --git a/Tools/idle/INSTALL.txt b/Tools/idle/INSTALL.txt
deleted file mode 100644
index ed7ac69..0000000
--- a/Tools/idle/INSTALL.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-IDLEfork Installation Notes
-===========================
-
-IDLEfork requires Python Version 2.2 or later.
-
-There are several distribution files (where xx is the subversion):
-
-IDLEfork-0.9xx.win32.exe
- This is a Windows installer which will install IDLEfork in
- ..../site-packages/idleforklib/ and place the idefork startup script
- at ..../scripts/idlefork. Rename this to idlefork.pyw and
- point your launcher icons at it. Installation is as idlefork
- to avoid conflict with the original Python IDLE.
-
-IDLEfork-0.9xx-1.noarch.rpm
- This is an rpm which is designed to install as idleforklib in an
- existing /usr/lib/python2.2 tree. It installs as idlefork to avoid
- conflict with Python IDLE.
-
- Python rpms are available at http://www.python.org/2.2.2/rpms.html and
- http://www.python.org/2.2.1/rpms.html.
-
-IDLEfork-0.9xx.tar.gz
- This is a distutils sdist (source) tarfile which can be used to make
- installations on platforms not supported by the above files.
- ** It remains configured to install as idlelib, not idleforklib. **
-
- Unpack in ..../Tools/, cd to the IDLEfork directory created, and
- "python setup.py install" to install in ....site-packages/idlelib.
- This will overwrite the Python IDLE installation.
-
- If you don't want to overwrite Python IDLE, it is also possible to
- simply call "python idle.py" to run from the IDLEfork source directory
- without making an installation. In this case, IDLE will not be on
- your PATH unless you are in the source directory. Also, it is then
- advisable to remove any Python IDLE installation by removing
- ..../site-packages/idlelib so the two identically named packages don't
- conflict.
-
- On Redhat Linux systems prior to 8.0, /usr/bin/python may be pointing
- at python1.5. If so, change the first line in the /usr/bin/idle
- script to read:
- !# /usr/bin/python2.2
-
-See README.txt for more details on this version of IDLEfork.
-
-
-
-
-
-
diff --git a/Tools/idle/LICENSE.txt b/Tools/idle/LICENSE.txt
deleted file mode 100644
index f7a8395..0000000
--- a/Tools/idle/LICENSE.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-To apply this license to IDLE or IDLEfork, read 'IDLE' or 'IDLEfork'
-for every occurence of 'Python 2.1.1' in the text below.
-
-PSF LICENSE AGREEMENT
----------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using Python 2.1.1 software in source or binary form and its
-associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python 2.1.1
-alone or in any derivative version, provided, however, that PSF's
-License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
-2001 Python Software Foundation; All Rights Reserved" are retained in
-Python 2.1.1 alone or in any derivative version prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python 2.1.1 or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python 2.1.1.
-
-4. PSF is making Python 2.1.1 available to Licensee on an "AS IS"
-basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.1.1 WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-2.1.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.1.1,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee. This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python 2.1.1, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
diff --git a/Tools/idle/Makefile b/Tools/idle/Makefile
deleted file mode 100644
index f118ebf..0000000
--- a/Tools/idle/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# Makefile to build the interrupt module, which is a C extension
-
-PYTHON=python2.3
-
-all: interrupt.so
-
-interrupt.so: interruptmodule.c
- $(PYTHON) setup.py build_ext -i
diff --git a/Tools/idle/RemoteDebugger.py b/Tools/idle/RemoteDebugger.py
deleted file mode 100644
index 41f910f..0000000
--- a/Tools/idle/RemoteDebugger.py
+++ /dev/null
@@ -1,381 +0,0 @@
-"""Support for remote Python debugging.
-
-Some ASCII art to describe the structure:
-
- IN PYTHON SUBPROCESS # IN IDLE PROCESS
- #
- # oid='gui_adapter'
- +----------+ # +------------+ +-----+
- | GUIProxy |--remote#call-->| GUIAdapter |--calls-->| GUI |
-+-----+--calls-->+----------+ # +------------+ +-----+
-| Idb | # /
-+-----+<-calls--+------------+ # +----------+<--calls-/
- | IdbAdapter |<--remote#call--| IdbProxy |
- +------------+ # +----------+
- oid='idb_adapter' #
-
-The purpose of the Proxy and Adapter classes is to translate certain
-arguments and return values that cannot be transported through the RPC
-barrier, in particular frame and traceback objects.
-
-"""
-
-import sys
-import types
-import rpc
-import Debugger
-
-debugging = 0
-
-idb_adap_oid = "idb_adapter"
-gui_adap_oid = "gui_adapter"
-
-#=======================================
-#
-# In the PYTHON subprocess:
-
-frametable = {}
-dicttable = {}
-codetable = {}
-tracebacktable = {}
-
-def wrap_frame(frame):
- fid = id(frame)
- frametable[fid] = frame
- return fid
-
-def wrap_info(info):
- "replace info[2], a traceback instance, by its ID"
- if info is None:
- return None
- else:
- traceback = info[2]
- assert isinstance(traceback, types.TracebackType)
- traceback_id = id(traceback)
- tracebacktable[traceback_id] = traceback
- modified_info = (info[0], info[1], traceback_id)
- return modified_info
-
-class GUIProxy:
-
- def __init__(self, conn, gui_adap_oid):
- self.conn = conn
- self.oid = gui_adap_oid
-
- def interaction(self, message, frame, info=None):
- # calls rpc.SocketIO.remotecall() via run.MyHandler instance
- # pass frame and traceback object IDs instead of the objects themselves
- self.conn.remotecall(self.oid, "interaction",
- (message, wrap_frame(frame), wrap_info(info)),
- {})
-
-class IdbAdapter:
-
- def __init__(self, idb):
- self.idb = idb
-
- #----------called by an IdbProxy----------
-
- def set_step(self):
- self.idb.set_step()
-
- def set_quit(self):
- self.idb.set_quit()
-
- def set_continue(self):
- self.idb.set_continue()
-
- def set_next(self, fid):
- frame = frametable[fid]
- self.idb.set_next(frame)
-
- def set_return(self, fid):
- frame = frametable[fid]
- self.idb.set_return(frame)
-
- def get_stack(self, fid, tbid):
- ##print >>sys.__stderr__, "get_stack(%s, %s)" % (`fid`, `tbid`)
- frame = frametable[fid]
- if tbid is None:
- tb = None
- else:
- tb = tracebacktable[tbid]
- stack, i = self.idb.get_stack(frame, tb)
- ##print >>sys.__stderr__, "get_stack() ->", stack
- stack = [(wrap_frame(frame), k) for frame, k in stack]
- ##print >>sys.__stderr__, "get_stack() ->", stack
- return stack, i
-
- def run(self, cmd):
- import __main__
- self.idb.run(cmd, __main__.__dict__)
-
- def set_break(self, filename, lineno):
- msg = self.idb.set_break(filename, lineno)
- return msg
-
- def clear_break(self, filename, lineno):
- msg = self.idb.clear_break(filename, lineno)
- return msg
-
- def clear_all_file_breaks(self, filename):
- msg = self.idb.clear_all_file_breaks(filename)
- return msg
-
- #----------called by a FrameProxy----------
-
- def frame_attr(self, fid, name):
- frame = frametable[fid]
- return getattr(frame, name)
-
- def frame_globals(self, fid):
- frame = frametable[fid]
- dict = frame.f_globals
- did = id(dict)
- dicttable[did] = dict
- return did
-
- def frame_locals(self, fid):
- frame = frametable[fid]
- dict = frame.f_locals
- did = id(dict)
- dicttable[did] = dict
- return did
-
- def frame_code(self, fid):
- frame = frametable[fid]
- code = frame.f_code
- cid = id(code)
- codetable[cid] = code
- return cid
-
- #----------called by a CodeProxy----------
-
- def code_name(self, cid):
- code = codetable[cid]
- return code.co_name
-
- def code_filename(self, cid):
- code = codetable[cid]
- return code.co_filename
-
- #----------called by a DictProxy----------
-
- def dict_keys(self, did):
- dict = dicttable[did]
- return dict.keys()
-
- def dict_item(self, did, key):
- dict = dicttable[did]
- value = dict[key]
- value = repr(value)
- return value
-
-#----------end class IdbAdapter----------
-
-
-def start_debugger(rpchandler, gui_adap_oid):
- """Start the debugger and its RPC link in the Python subprocess
-
- Start the subprocess side of the split debugger and set up that side of the
- RPC link by instantiating the GUIProxy, Idb debugger, and IdbAdapter
- objects and linking them together. Register the IdbAdapter with the
- RPCServer to handle RPC requests from the split debugger GUI via the
- IdbProxy.
-
- """
- gui_proxy = GUIProxy(rpchandler, gui_adap_oid)
- idb = Debugger.Idb(gui_proxy)
- idb_adap = IdbAdapter(idb)
- rpchandler.register(idb_adap_oid, idb_adap)
- return idb_adap_oid
-
-
-#=======================================
-#
-# In the IDLE process:
-
-
-class FrameProxy:
-
- def __init__(self, conn, fid):
- self._conn = conn
- self._fid = fid
- self._oid = "idb_adapter"
- self._dictcache = {}
-
- def __getattr__(self, name):
- if name[:1] == "_":
- raise AttributeError, name
- if name == "f_code":
- return self._get_f_code()
- if name == "f_globals":
- return self._get_f_globals()
- if name == "f_locals":
- return self._get_f_locals()
- return self._conn.remotecall(self._oid, "frame_attr",
- (self._fid, name), {})
-
- def _get_f_code(self):
- cid = self._conn.remotecall(self._oid, "frame_code", (self._fid,), {})
- return CodeProxy(self._conn, self._oid, cid)
-
- def _get_f_globals(self):
- did = self._conn.remotecall(self._oid, "frame_globals",
- (self._fid,), {})
- return self._get_dict_proxy(did)
-
- def _get_f_locals(self):
- did = self._conn.remotecall(self._oid, "frame_locals",
- (self._fid,), {})
- return self._get_dict_proxy(did)
-
- def _get_dict_proxy(self, did):
- if self._dictcache.has_key(did):
- return self._dictcache[did]
- dp = DictProxy(self._conn, self._oid, did)
- self._dictcache[did] = dp
- return dp
-
-
-class CodeProxy:
-
- def __init__(self, conn, oid, cid):
- self._conn = conn
- self._oid = oid
- self._cid = cid
-
- def __getattr__(self, name):
- if name == "co_name":
- return self._conn.remotecall(self._oid, "code_name",
- (self._cid,), {})
- if name == "co_filename":
- return self._conn.remotecall(self._oid, "code_filename",
- (self._cid,), {})
-
-
-class DictProxy:
-
- def __init__(self, conn, oid, did):
- self._conn = conn
- self._oid = oid
- self._did = did
-
- def keys(self):
- return self._conn.remotecall(self._oid, "dict_keys", (self._did,), {})
-
- def __getitem__(self, key):
- return self._conn.remotecall(self._oid, "dict_item",
- (self._did, key), {})
-
- def __getattr__(self, name):
- ##print >>sys.__stderr__, "failed DictProxy.__getattr__:", name
- raise AttributeError, name
-
-
-class GUIAdapter:
-
- def __init__(self, conn, gui):
- self.conn = conn
- self.gui = gui
-
- def interaction(self, message, fid, modified_info):
- ##print "interaction: (%s, %s, %s)" % (message, fid, modified_info)
- frame = FrameProxy(self.conn, fid)
- self.gui.interaction(message, frame, modified_info)
-
-
-class IdbProxy:
-
- def __init__(self, conn, shell, oid):
- self.oid = oid
- self.conn = conn
- self.shell = shell
-
- def call(self, methodname, *args, **kwargs):
- ##print "**IdbProxy.call %s %s %s" % (methodname, args, kwargs)
- value = self.conn.remotecall(self.oid, methodname, args, kwargs)
- ##print "**IdbProxy.call %s returns %s" % (methodname, `value`)
- return value
-
- def run(self, cmd, locals):
- # Ignores locals on purpose!
- seq = self.conn.asynccall(self.oid, "run", (cmd,), {})
- self.shell.interp.active_seq = seq
-
- def get_stack(self, frame, tbid):
- # passing frame and traceback IDs, not the objects themselves
- stack, i = self.call("get_stack", frame._fid, tbid)
- stack = [(FrameProxy(self.conn, fid), k) for fid, k in stack]
- return stack, i
-
- def set_continue(self):
- self.call("set_continue")
-
- def set_step(self):
- self.call("set_step")
-
- def set_next(self, frame):
- self.call("set_next", frame._fid)
-
- def set_return(self, frame):
- self.call("set_return", frame._fid)
-
- def set_quit(self):
- self.call("set_quit")
-
- def set_break(self, filename, lineno):
- msg = self.call("set_break", filename, lineno)
- return msg
-
- def clear_break(self, filename, lineno):
- msg = self.call("clear_break", filename, lineno)
- return msg
-
- def clear_all_file_breaks(self, filename):
- msg = self.call("clear_all_file_breaks", filename)
- return msg
-
-def start_remote_debugger(rpcclt, pyshell):
- """Start the subprocess debugger, initialize the debugger GUI and RPC link
-
- Request the RPCServer start the Python subprocess debugger and link. Set
- up the Idle side of the split debugger by instantiating the IdbProxy,
- debugger GUI, and debugger GUIAdapter objects and linking them together.
-
- Register the GUIAdapter with the RPCClient to handle debugger GUI
- interaction requests coming from the subprocess debugger via the GUIProxy.
-
- The IdbAdapter will pass execution and environment requests coming from the
- Idle debugger GUI to the subprocess debugger via the IdbProxy.
-
- """
- global idb_adap_oid
-
- idb_adap_oid = rpcclt.remotecall("exec", "start_the_debugger",\
- (gui_adap_oid,), {})
- idb_proxy = IdbProxy(rpcclt, pyshell, idb_adap_oid)
- gui = Debugger.Debugger(pyshell, idb_proxy)
- gui_adap = GUIAdapter(rpcclt, gui)
- rpcclt.register(gui_adap_oid, gui_adap)
- return gui
-
-def close_remote_debugger(rpcclt):
- """Shut down subprocess debugger and Idle side of debugger RPC link
-
- Request that the RPCServer shut down the subprocess debugger and link.
- Unregister the GUIAdapter, which will cause a GC on the Idle process
- debugger and RPC link objects. (The second reference to the debugger GUI
- is deleted in PyShell.close_remote_debugger().)
-
- """
- close_subprocess_debugger(rpcclt)
- rpcclt.unregister(gui_adap_oid)
-
-def close_subprocess_debugger(rpcclt):
- rpcclt.remotecall("exec", "stop_the_debugger", (idb_adap_oid,), {})
-
-def restart_subprocess_debugger(rpcclt):
- idb_adap_oid_ret = rpcclt.remotecall("exec", "start_the_debugger",\
- (gui_adap_oid,), {})
- assert idb_adap_oid_ret == idb_adap_oid, 'Idb restarted with different oid'
diff --git a/Tools/idle/RemoteObjectBrowser.py b/Tools/idle/RemoteObjectBrowser.py
deleted file mode 100644
index 6ba3391..0000000
--- a/Tools/idle/RemoteObjectBrowser.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import rpc
-
-def remote_object_tree_item(item):
- wrapper = WrappedObjectTreeItem(item)
- oid = id(wrapper)
- rpc.objecttable[oid] = wrapper
- return oid
-
-class WrappedObjectTreeItem:
- # Lives in PYTHON subprocess
-
- def __init__(self, item):
- self.__item = item
-
- def __getattr__(self, name):
- value = getattr(self.__item, name)
- return value
-
- def _GetSubList(self):
- list = self.__item._GetSubList()
- return map(remote_object_tree_item, list)
-
-class StubObjectTreeItem:
- # Lives in IDLE process
-
- def __init__(self, sockio, oid):
- self.sockio = sockio
- self.oid = oid
-
- def __getattr__(self, name):
- value = rpc.MethodProxy(self.sockio, self.oid, name)
- return value
-
- def _GetSubList(self):
- list = self.sockio.remotecall(self.oid, "_GetSubList", (), {})
- return [StubObjectTreeItem(self.sockio, oid) for oid in list]
diff --git a/Tools/idle/aboutDialog.py b/Tools/idle/aboutDialog.py
deleted file mode 100644
index 2fc4a42..0000000
--- a/Tools/idle/aboutDialog.py
+++ /dev/null
@@ -1,126 +0,0 @@
-"""
-about box for idle
-"""
-
-from Tkinter import *
-import string, os
-import textView
-import idlever
-
-class AboutDialog(Toplevel):
- """
- modal about dialog for idle
- """
- def __init__(self,parent,title):
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.geometry("+%d+%d" % (parent.winfo_rootx()+30,
- parent.winfo_rooty()+30))
- self.bg="#707070"
- self.fg="#ffffff"
-
- self.CreateWidgets()
- self.resizable(height=FALSE,width=FALSE)
- self.title(title)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Ok)
- self.parent = parent
- self.buttonOk.focus_set()
- #key bindings for this dialog
- self.bind('<Alt-c>',self.CreditsButtonBinding) #credits button
- self.bind('<Alt-l>',self.LicenseButtonBinding) #license button
- self.bind('<Return>',self.Ok) #dismiss dialog
- self.bind('<Escape>',self.Ok) #dismiss dialog
- self.wait_window()
-
- def CreateWidgets(self):
- frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
- frameButtons = Frame(self)
- frameButtons.pack(side=BOTTOM,fill=X)
- frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
- self.buttonOk = Button(frameButtons,text='Ok',
- command=self.Ok)#,default=ACTIVE
- self.buttonOk.pack(padx=5,pady=5)
- #self.picture = Image('photo',data=self.pictureData)
- frameBg = Frame(frameMain,bg=self.bg)
- frameBg.pack(expand=TRUE,fill=BOTH)
- labelTitle = Label(frameBg,text='IDLEfork',fg=self.fg,bg=self.bg,
- font=('courier', 24, 'bold'))
- labelTitle.grid(row=0,column=0,sticky=W,padx=10,pady=10)
- #labelPicture = Label(frameBg,text='[picture]')
- #image=self.picture,bg=self.bg)
- #labelPicture.grid(row=0,column=1,sticky=W,rowspan=2,padx=0,pady=3)
- labelVersion = Label(frameBg,text='version '+idlever.IDLE_VERSION,
- fg=self.fg,bg=self.bg)
- labelVersion.grid(row=1,column=0,sticky=W,padx=10,pady=5)
- labelDesc = Label(frameBg,
- text="A development version of Python's lightweight\n"+
- 'Integrated DeveLopment Environment, IDLE.',
- justify=LEFT,fg=self.fg,bg=self.bg)
- labelDesc.grid(row=2,column=0,sticky=W,columnspan=3,padx=10,pady=5)
- labelCopyright = Label(frameBg,
- text="Copyright (c) 2001 Python Software Foundation;\nAll Rights Reserved",
- justify=LEFT,fg=self.fg,bg=self.bg)
- labelCopyright.grid(row=3,column=0,sticky=W,columnspan=3,padx=10,pady=5)
- labelLicense = Label(frameBg,
- text='Released under the Python 2.1.1 PSF Licence',
- justify=LEFT,fg=self.fg,bg=self.bg)
- labelLicense.grid(row=4,column=0,sticky=W,columnspan=3,padx=10,pady=5)
- Frame(frameBg,height=5,bg=self.bg).grid(row=5,column=0)
- labelEmail = Label(frameBg,text='email: idle-dev@python.org',
- justify=LEFT,fg=self.fg,bg=self.bg)
- labelEmail.grid(row=6,column=0,columnspan=2,sticky=W,padx=10,pady=0)
- labelWWW = Label(frameBg,text='www: http://idlefork.sourceforge.net',
- justify=LEFT,fg=self.fg,bg=self.bg)
- labelWWW.grid(row=7,column=0,columnspan=2,sticky=W,padx=10,pady=0)
- Frame(frameBg,borderwidth=1,relief=SUNKEN,
- height=2,bg=self.bg).grid(row=8,column=0,sticky=EW,
- columnspan=3, padx=5, pady=5)
- labelPythonVer = Label(frameBg,text='Python version: '+
- sys.version.split()[0],fg=self.fg,bg=self.bg)
- labelPythonVer.grid(row=9,column=0,sticky=W,padx=10,pady=0)
- #handle weird tk version num in windoze python >= 1.6 (?!?)
- tkVer = `TkVersion`.split('.')
- tkVer[len(tkVer)-1] = str('%.3g' % (float('.'+tkVer[len(tkVer)-1])))[2:]
- if tkVer[len(tkVer)-1] == '':
- tkVer[len(tkVer)-1] = '0'
- tkVer = string.join(tkVer,'.')
- labelTkVer = Label(frameBg,text='Tk version: '+
- tkVer,fg=self.fg,bg=self.bg)
- labelTkVer.grid(row=9,column=1,sticky=W,padx=2,pady=0)
-
- self.buttonLicense = Button(frameBg,text='View License',underline=5,
- width=14,highlightbackground=self.bg,command=self.ShowLicense)#takefocus=FALSE
- self.buttonLicense.grid(row=10,column=0,sticky=W,padx=10,pady=10)
- self.buttonCredits = Button(frameBg,text='View Credits',underline=5,
- width=14,highlightbackground=self.bg,command=self.ShowCredits)#takefocus=FALSE
- self.buttonCredits.grid(row=10,column=1,columnspan=2,sticky=E,padx=10,pady=10)
-
- def CreditsButtonBinding(self,event):
- self.buttonCredits.invoke()
-
- def LicenseButtonBinding(self,event):
- self.buttonLicense.invoke()
-
- def ShowLicense(self):
- self.ViewFile('About - License','LICENSE.txt')
-
- def ShowCredits(self):
- self.ViewFile('About - Credits','CREDITS.txt')
-
- def ViewFile(self,viewTitle,viewFile):
- fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),viewFile)
- textView.TextViewer(self,viewTitle,fn)
-
- def Ok(self, event=None):
- self.destroy()
-
-if __name__ == '__main__':
- #test the dialog
- root=Tk()
- def run():
- import aboutDialog
- aboutDialog.AboutDialog(root,'About')
- Button(root,text='Dialog',command=run).pack()
- root.mainloop()
diff --git a/Tools/idle/boolcheck.py b/Tools/idle/boolcheck.py
deleted file mode 100644
index f682232..0000000
--- a/Tools/idle/boolcheck.py
+++ /dev/null
@@ -1,9 +0,0 @@
-"boolcheck - import this module to ensure True, False, bool() builtins exist."
-try:
- True
-except NameError:
- import __builtin__
- __builtin__.True = 1
- __builtin__.False = 0
- from operator import truth
- __builtin__.bool = truth
diff --git a/Tools/idle/config-extensions.def b/Tools/idle/config-extensions.def
deleted file mode 100644
index d4905e8..0000000
--- a/Tools/idle/config-extensions.def
+++ /dev/null
@@ -1,54 +0,0 @@
-# IDLE reads several config files to determine user preferences. This
-# file is the default config file for idle extensions settings.
-#
-# Each extension must have at least one section, named after the extension
-# module. This section must contain an 'enable' item (=1 to enable the
-# extension, =0 to disable it) and also contains any other general
-# configuration items for the extension. Each extension may also define up to
-# two optional sections named ExtensionName_bindings and
-# ExtensionName_cfgBindings. If present, ExtensionName_bindings defines virtual
-# event bindings for the extension that are not sensibly re-configurable. If
-# present, ExtensionName_cfgBindings defines virtual event bindings for the
-# extension that may be sensibly re-configured.
-
-# See config-keys.def for notes on specifying keys.
-
-[FormatParagraph]
-enable=1
-[FormatParagraph_cfgBindings]
-format-paragraph=<Alt-Key-q>
-
-[AutoExpand]
-enable=1
-[AutoExpand_cfgBindings]
-expand-word=<Alt-Key-slash>
-
-[ZoomHeight]
-enable=1
-[ZoomHeight_cfgBindings]
-zoom-height=<Alt-Key-2>
-
-[ScriptBinding]
-enable=1
-[ScriptBinding_cfgBindings]
-run-module=<Key-F5>
-check-module=<Alt-Key-x>
-
-[CallTips]
-enable=1
-[CallTips_bindings]
-paren-open=<Key-parenleft>
-paren-close=<Key-parenright>
-check-calltip-cancel=<KeyRelease>
-calltip-cancel=<ButtonPress> <Key-Escape>
-
-[ParenMatch]
-enable=0
-style= expression
-flash-delay= 500
-bell= 1
-hilite-foreground= black
-hilite-background= #43cd80
-[ParenMatch_bindings]
-flash-open-paren=<KeyRelease-parenright> <KeyRelease-bracketright> <KeyRelease-braceright>
-check-restore=<KeyPress>
diff --git a/Tools/idle/config-highlight.def b/Tools/idle/config-highlight.def
deleted file mode 100644
index 2b7deab..0000000
--- a/Tools/idle/config-highlight.def
+++ /dev/null
@@ -1,60 +0,0 @@
-# IDLE reads several config files to determine user preferences. This
-# file is the default config file for idle highlight theme settings.
-
-[IDLE Classic]
-normal-foreground= #000000
-normal-background= #ffffff
-keyword-foreground= #ff7700
-keyword-background= #ffffff
-comment-foreground= #dd0000
-comment-background= #ffffff
-string-foreground= #00aa00
-string-background= #ffffff
-definition-foreground= #0000ff
-definition-background= #ffffff
-hilite-foreground= #000000
-hilite-background= gray
-break-foreground= black
-break-background= #ffff55
-hit-foreground= #ffffff
-hit-background= #000000
-error-foreground= #000000
-error-background= #ff7777
-#cursor (only foreground can be set)
-cursor-foreground= black
-#shell window
-stdout-foreground= blue
-stdout-background= #ffffff
-stderr-foreground= red
-stderr-background= #ffffff
-console-foreground= #770000
-console-background= #ffffff
-
-[IDLE New]
-normal-foreground= #000000
-normal-background= #ffffff
-keyword-foreground= #ff7700
-keyword-background= #ffffff
-comment-foreground= #dd0000
-comment-background= #ffffff
-string-foreground= #00aa00
-string-background= #ffffff
-definition-foreground= #0000ff
-definition-background= #ffffff
-hilite-foreground= #000000
-hilite-background= gray
-break-foreground= black
-break-background= #ffff55
-hit-foreground= #ffffff
-hit-background= #000000
-error-foreground= #000000
-error-background= #ff7777
-#cursor (only foreground can be set)
-cursor-foreground= black
-#shell window
-stdout-foreground= blue
-stdout-background= #ffffff
-stderr-foreground= red
-stderr-background= #ffffff
-console-foreground= #770000
-console-background= #ffffff
diff --git a/Tools/idle/config-keys.def b/Tools/idle/config-keys.def
deleted file mode 100644
index 4f2be59..0000000
--- a/Tools/idle/config-keys.def
+++ /dev/null
@@ -1,155 +0,0 @@
-# IDLE reads several config files to determine user preferences. This
-# file is the default config file for idle key binding settings.
-# Where multiple keys are specified for an action: if they are separated
-# by a space (eg. action=<key1> <key2>) then the keys are altenatives, if
-# there is no space (eg. action=<key1><key2>) then the keys comprise a
-# single 'emacs style' multi-keystoke binding. The tk event specifier 'Key'
-# is used in all cases, for consistency in auto key conflict checking in the
-# configuration gui.
-
-[IDLE Classic Windows]
-copy=<Control-Key-c>
-cut=<Control-Key-x>
-paste=<Control-Key-v>
-beginning-of-line= <Key-Home>
-center-insert=<Control-Key-l>
-close-all-windows=<Control-Key-q>
-close-window=<Alt-Key-F4> <Meta-Key-F4>
-do-nothing=<Control-Key-F12>
-end-of-file=<Control-Key-d>
-python-docs=<Key-F1>
-python-context-help=<Shift-Key-F1>
-history-next=<Alt-Key-n> <Meta-Key-n>
-history-previous=<Alt-Key-p> <Meta-Key-p>
-interrupt-execution=<Control-Key-c>
-view-restart=<Key-F6>
-restart-shell=<Control-Key-F6>
-open-class-browser=<Alt-Key-c> <Meta-Key-c>
-open-module=<Alt-Key-m> <Meta-Key-m>
-open-new-window=<Control-Key-n>
-open-window-from-file=<Control-Key-o>
-plain-newline-and-indent=<Control-Key-j>
-print-window=<Control-Key-p>
-redo=<Control-Shift-Key-z>
-remove-selection=<Key-Escape>
-save-copy-of-window-as-file=<Alt-Shift-Key-s>
-save-window-as-file=<Control-Shift-Key-s>
-save-window=<Control-Key-s>
-select-all=<Control-Key-a>
-toggle-auto-coloring=<Control-Key-slash>
-undo=<Control-Key-z>
-find=<Control-Key-f>
-find-again=<Control-Key-g> <Key-F3>
-find-in-files=<Alt-Key-F3> <Meta-Key-F3>
-find-selection=<Control-Key-F3>
-replace=<Control-Key-h>
-goto-line=<Alt-Key-g> <Meta-Key-g>
-smart-backspace=<Key-BackSpace>
-newline-and-indent=<Key-Return> <Key-KP_Enter>
-smart-indent=<Key-Tab>
-indent-region=<Control-Key-bracketright>
-dedent-region=<Control-Key-bracketleft>
-comment-region=<Alt-Key-3> <Meta-Key-3>
-uncomment-region=<Alt-Key-4> <Meta-Key-4>
-tabify-region=<Alt-Key-5> <Meta-Key-5>
-untabify-region=<Alt-Key-6> <Meta-Key-6>
-toggle-tabs=<Alt-Key-t> <Meta-Key-t>
-change-indentwidth=<Alt-Key-u> <Meta-Key-u>
-
-[IDLE Classic Unix]
-copy=<Alt-Key-w> <Meta-Key-w>
-cut=<Control-Key-w>
-paste=<Control-Key-y>
-beginning-of-line=<Control-Key-a> <Key-Home>
-center-insert=<Control-Key-l>
-close-all-windows=<Control-Key-x><Control-Key-c>
-close-window=<Control-Key-x><Control-Key-0>
-do-nothing=<Control-Key-x>
-end-of-file=<Control-Key-d>
-history-next=<Alt-Key-n> <Meta-Key-n>
-history-previous=<Alt-Key-p> <Meta-Key-p>
-interrupt-execution=<Control-Key-c>
-view-restart=<Key-F6>
-restart-shell=<Control-Key-F6>
-open-class-browser=<Control-Key-x><Control-Key-b>
-open-module=<Control-Key-x><Control-Key-m>
-open-new-window=<Control-Key-x><Control-Key-n>
-open-window-from-file=<Control-Key-x><Control-Key-f>
-plain-newline-and-indent=<Control-Key-j>
-print-window=<Control-x><Control-Key-p>
-python-docs=<Control-Key-h>
-python-context-help=<Control-Shift-Key-h>
-redo=<Alt-Key-z> <Meta-Key-z>
-remove-selection=<Key-Escape>
-save-copy-of-window-as-file=<Control-Key-x><Control-Key-y>
-save-window-as-file=<Control-Key-x><Control-Key-w>
-save-window=<Control-Key-x><Control-Key-s>
-select-all=<Alt-Key-a> <Meta-Key-a>
-toggle-auto-coloring=<Control-Key-slash>
-undo=<Control-Key-z>
-find=<Control-Key-u><Control-Key-u><Control-Key-s>
-find-again=<Control-Key-u><Control-Key-s>
-find-in-files=<Alt-Key-s> <Meta-Key-s>
-find-selection=<Control-Key-s>
-replace=<Control-Key-r>
-goto-line=<Alt-Key-g> <Meta-Key-g>
-smart-backspace=<Key-BackSpace>
-newline-and-indent=<Key-Return> <Key-KP_Enter>
-smart-indent=<Key-Tab>
-indent-region=<Control-Key-bracketright>
-dedent-region=<Control-Key-bracketleft>
-comment-region=<Alt-Key-3>
-uncomment-region=<Alt-Key-4>
-tabify-region=<Alt-Key-5>
-untabify-region=<Alt-Key-6>
-toggle-tabs=<Alt-Key-t>
-change-indentwidth=<Alt-Key-u>
-
-[IDLE Classic Mac]
-copy=<Command-Key-c>
-cut=<Command-Key-x>
-paste=<Command-Key-v>
-beginning-of-line= <Key-Home>
-center-insert=<Control-Key-l>
-close-all-windows=<Command-Key-q>
-close-window=<Command-Key-w>
-do-nothing=<Control-Key-F12>
-end-of-file=<Control-Key-d>
-python-docs=<Key-F1>
-python-context-help=<Shift-Key-F1>
-history-next=<Control-Key-n>
-history-previous=<Control-Key-p>
-interrupt-execution=<Control-Key-c>
-view-restart=<Key-F6>
-restart-shell=<Control-Key-F6>
-open-class-browser=<Command-Key-b>
-open-module=<Command-Key-m>
-open-new-window=<Command-Key-n>
-open-window-from-file=<Command-Key-o>
-plain-newline-and-indent=<Control-Key-j>
-print-window=<Command-Key-p>
-redo=<Shift-Command-Key-z>
-remove-selection=<Key-Escape>
-save-window-as-file=<Shift-Command-Key-s>
-save-window=<Command-Key-s>
-save-copy-of-window-as-file=<Option-Command-Key-s>
-select-all=<Command-Key-a>
-toggle-auto-coloring=<Control-Key-slash>
-undo=<Command-Key-z>
-find=<Command-Key-f>
-find-again=<Command-Key-g> <Key-F3>
-find-in-files=<Command-Key-F3>
-find-selection=<Shift-Command-Key-F3>
-replace=<Command-Key-r>
-goto-line=<Command-Key-j>
-smart-backspace=<Key-BackSpace>
-newline-and-indent=<Key-Return> <Key-KP_Enter>
-smart-indent=<Key-Tab>
-indent-region=<Command-Key-bracketright>
-dedent-region=<Command-Key-bracketleft>
-comment-region=<Control-Key-3>
-uncomment-region=<Control-Key-4>
-tabify-region=<Control-Key-5>
-untabify-region=<Control-Key-6>
-toggle-tabs=<Control-Key-t>
-change-indentwidth=<Control-Key-u>
diff --git a/Tools/idle/config-main.def b/Tools/idle/config-main.def
deleted file mode 100644
index 9d520c1..0000000
--- a/Tools/idle/config-main.def
+++ /dev/null
@@ -1,65 +0,0 @@
-# IDLE reads several config files to determine user preferences. This
-# file is the default config file for general idle settings.
-#
-# When IDLE starts, it will look in
-# the following two sets of files, in order:
-#
-# default configuration
-# ---------------------
-# config-main.def the default general config file
-# config-extensions.def the default extension config file
-# config-highlight.def the default highlighting config file
-# config-keys.def the default keybinding config file
-#
-# user configuration
-# -------------------
-# ~/.idlerc/idle-main.cfg the user general config file
-# ~/.idlerc/idle-extensions.cfg the user extension config file
-# ~/.idlerc/idle-highlight.cfg the user highlighting config file
-# ~/.idlerc/idle-keys.cfg the user keybinding config file
-#
-# Any options the user saves through the config dialog will be saved to
-# the relevant user config file. Reverting any general setting to the
-# default causes that entry to be wiped from the user file and re-read
-# from the default file. User highlighting themes or keybinding sets are
-# retained unless specifically deleted within the config dialog. Choosing
-# one of the default themes or keysets just applies the relevant settings
-# from the default file.
-#
-# Additional help sources are listed in the [HelpFiles] section and must be
-# viewable by a web browser (or the Windows Help viewer in the case of .chm
-# files). These sources will be listed on the Help menu. The pattern is
-# <sequence_number = menu item;/path/to/help/source>
-# You can't use a semi-colon in a menu item or path. The path will be platform
-# specific because of path separators, drive specs etc.
-#
-# It is best to use the Configuration GUI to set up additional help sources!
-# Example:
-#1 = My Extra Help Source;/usr/share/doc/foo/index.html
-#2 = Another Help Source;/path/to/another.pdf
-
-[General]
-editor-on-startup= 0
-print-command-posix=lpr %s
-print-command-win=start /min notepad /p %s
-
-[EditorWindow]
-width= 80
-height= 30
-font= courier
-font-size= 12
-font-bold= 0
-
-[Indent]
-use-spaces= 1
-num-spaces= 4
-
-[Theme]
-default= 1
-name= IDLE Classic
-
-[Keys]
-default= 1
-name= IDLE Classic Windows
-
-[HelpFiles]
diff --git a/Tools/idle/configDialog.py b/Tools/idle/configDialog.py
deleted file mode 100644
index 814689c..0000000
--- a/Tools/idle/configDialog.py
+++ /dev/null
@@ -1,1134 +0,0 @@
-"""IDLE Configuration Dialog: support user customization of IDLE by GUI
-
-Customize font faces, sizes, and colorization attributes. Set indentation
-defaults. Customize keybindings. Colorization and keybindings can be
-saved as user defined sets. Select startup options including shell/editor
-and default window size. Define additional help sources.
-
-Note that tab width in IDLE is currently fixed at eight due to Tk issues.
-Refer to comment in EditorWindow autoindent code for details.
-
-"""
-from Tkinter import *
-import tkMessageBox, tkColorChooser, tkFont
-import string, copy
-
-from configHandler import idleConf
-from dynOptionMenuWidget import DynOptionMenu
-from tabpage import TabPageSet
-from keybindingDialog import GetKeysDialog
-from configSectionNameDialog import GetCfgSectionNameDialog
-from configHelpSourceEdit import GetHelpSourceDialog
-
-class ConfigDialog(Toplevel):
- """
- configuration dialog for idle
- """
- def __init__(self,parent,title):
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.geometry("+%d+%d" % (parent.winfo_rootx()+20,
- parent.winfo_rooty()+30))
- #Theme Elements. Each theme element key is it's display name.
- #The first value of the tuple is the sample area tag name.
- #The second value is the display name list sort index.
- self.themeElements={'Normal Text':('normal','00'),
- 'Python Keywords':('keyword','01'),
- 'Python Definitions':('definition','02'),
- 'Python Comments':('comment','03'),
- 'Python Strings':('string','04'),
- 'Selected Text':('hilite','05'),
- 'Found Text':('hit','06'),
- 'Cursor':('cursor','07'),
- 'Error Text':('error','08'),
- 'Shell Normal Text':('console','09'),
- 'Shell Stdout Text':('stdout','10'),
- 'Shell Stderr Text':('stderr','11')}
- self.ResetChangedItems() #load initial values in changed items dict
- self.CreateWidgets()
- self.resizable(height=FALSE,width=FALSE)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Cancel)
- self.parent = parent
- self.tabPages.focus_set()
- #key bindings for this dialog
- #self.bind('<Escape>',self.Cancel) #dismiss dialog, no save
- #self.bind('<Alt-a>',self.Apply) #apply changes, save
- #self.bind('<F1>',self.Help) #context help
- self.LoadConfigs()
- self.AttachVarCallbacks() #avoid callbacks during LoadConfigs
- self.wait_window()
-
- def CreateWidgets(self):
- self.tabPages = TabPageSet(self,
- pageNames=['Fonts/Tabs','Highlighting','Keys','General'])
- self.tabPages.ChangePage()#activates default (first) page
- frameActionButtons = Frame(self)
- #action buttons
- self.buttonHelp = Button(frameActionButtons,text='Help',
- command=self.Help,takefocus=FALSE)
- self.buttonOk = Button(frameActionButtons,text='Ok',
- command=self.Ok,takefocus=FALSE)
- self.buttonApply = Button(frameActionButtons,text='Apply',
- command=self.Apply,takefocus=FALSE)
- self.buttonCancel = Button(frameActionButtons,text='Cancel',
- command=self.Cancel,takefocus=FALSE)
- self.CreatePageFontTab()
- self.CreatePageHighlight()
- self.CreatePageKeys()
- self.CreatePageGeneral()
- self.buttonHelp.pack(side=RIGHT,padx=5,pady=5)
- self.buttonOk.pack(side=LEFT,padx=5,pady=5)
- self.buttonApply.pack(side=LEFT,padx=5,pady=5)
- self.buttonCancel.pack(side=LEFT,padx=5,pady=5)
- frameActionButtons.pack(side=BOTTOM)
- self.tabPages.pack(side=TOP,expand=TRUE,fill=BOTH)
-
- def CreatePageFontTab(self):
- #tkVars
- self.fontSize=StringVar(self)
- self.fontBold=BooleanVar(self)
- self.fontName=StringVar(self)
- self.spaceNum=IntVar(self)
- #self.tabCols=IntVar(self)
- self.indentBySpaces=BooleanVar(self)
- self.editFont=tkFont.Font(self,('courier',12,'normal'))
- ##widget creation
- #body frame
- frame=self.tabPages.pages['Fonts/Tabs']['page']
- #body section frames
- frameFont=Frame(frame,borderwidth=2,relief=GROOVE)
- frameIndent=Frame(frame,borderwidth=2,relief=GROOVE)
- #frameFont
- labelFontTitle=Label(frameFont,text='Set Base Editor Font')
- frameFontName=Frame(frameFont)
- frameFontParam=Frame(frameFont)
- labelFontNameTitle=Label(frameFontName,justify=LEFT,
- text='Font :')
- self.listFontName=Listbox(frameFontName,height=5,takefocus=FALSE,
- exportselection=FALSE)
- self.listFontName.bind('<ButtonRelease-1>',self.OnListFontButtonRelease)
- scrollFont=Scrollbar(frameFontName)
- scrollFont.config(command=self.listFontName.yview)
- self.listFontName.config(yscrollcommand=scrollFont.set)
- labelFontSizeTitle=Label(frameFontParam,text='Size :')
- self.optMenuFontSize=DynOptionMenu(frameFontParam,self.fontSize,None,
- command=self.SetFontSample)
- checkFontBold=Checkbutton(frameFontParam,variable=self.fontBold,
- onvalue=1,offvalue=0,text='Bold',command=self.SetFontSample)
- frameFontSample=Frame(frameFont,relief=SOLID,borderwidth=1)
- self.labelFontSample=Label(frameFontSample,
- text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]',
- justify=LEFT,font=self.editFont)
- #frameIndent
- labelIndentTitle=Label(frameIndent,text='Set Indentation Defaults')
- frameIndentType=Frame(frameIndent)
- frameIndentSize=Frame(frameIndent)
- labelIndentTypeTitle=Label(frameIndentType,
- text='Choose indentation type :')
- radioUseSpaces=Radiobutton(frameIndentType,variable=self.indentBySpaces,
- value=1,text='Tab key inserts spaces')
- radioUseTabs=Radiobutton(frameIndentType,variable=self.indentBySpaces,
- value=0,text='Tab key inserts tabs')
- labelIndentSizeTitle=Label(frameIndentSize,
- text='Choose indentation size :')
- labelSpaceNumTitle=Label(frameIndentSize,justify=LEFT,
- text='indent width')
- self.scaleSpaceNum=Scale(frameIndentSize,variable=self.spaceNum,
- orient='horizontal',tickinterval=2,from_=2,to=16)
- #labeltabColsTitle=Label(frameIndentSize,justify=LEFT,
- # text='when tab key inserts tabs,\ncolumns per tab')
- #self.scaleTabCols=Scale(frameIndentSize,variable=self.tabCols,
- # orient='horizontal',tickinterval=2,from_=2,to=8)
- #widget packing
- #body
- frameFont.pack(side=LEFT,padx=5,pady=10,expand=TRUE,fill=BOTH)
- frameIndent.pack(side=LEFT,padx=5,pady=10,fill=Y)
- #frameFont
- labelFontTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- frameFontName.pack(side=TOP,padx=5,pady=5,fill=X)
- frameFontParam.pack(side=TOP,padx=5,pady=5,fill=X)
- labelFontNameTitle.pack(side=TOP,anchor=W)
- self.listFontName.pack(side=LEFT,expand=TRUE,fill=X)
- scrollFont.pack(side=LEFT,fill=Y)
- labelFontSizeTitle.pack(side=LEFT,anchor=W)
- self.optMenuFontSize.pack(side=LEFT,anchor=W)
- checkFontBold.pack(side=LEFT,anchor=W,padx=20)
- frameFontSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
- self.labelFontSample.pack(expand=TRUE,fill=BOTH)
- #frameIndent
- labelIndentTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- frameIndentType.pack(side=TOP,padx=5,fill=X)
- frameIndentSize.pack(side=TOP,padx=5,pady=5,fill=BOTH)
- labelIndentTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- radioUseSpaces.pack(side=TOP,anchor=W,padx=5)
- radioUseTabs.pack(side=TOP,anchor=W,padx=5)
- labelIndentSizeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- labelSpaceNumTitle.pack(side=TOP,anchor=W,padx=5)
- self.scaleSpaceNum.pack(side=TOP,padx=5,fill=X)
- #labeltabColsTitle.pack(side=TOP,anchor=W,padx=5)
- #self.scaleTabCols.pack(side=TOP,padx=5,fill=X)
- return frame
-
- def CreatePageHighlight(self):
- self.builtinTheme=StringVar(self)
- self.customTheme=StringVar(self)
- self.fgHilite=BooleanVar(self)
- self.colour=StringVar(self)
- self.fontName=StringVar(self)
- self.themeIsBuiltin=BooleanVar(self)
- self.highlightTarget=StringVar(self)
- ##widget creation
- #body frame
- frame=self.tabPages.pages['Highlighting']['page']
- #body section frames
- frameCustom=Frame(frame,borderwidth=2,relief=GROOVE)
- frameTheme=Frame(frame,borderwidth=2,relief=GROOVE)
- #frameCustom
- self.textHighlightSample=Text(frameCustom,relief=SOLID,borderwidth=1,
- font=('courier',12,''),cursor='hand2',width=21,height=10,
- takefocus=FALSE,highlightthickness=0,wrap=NONE)
- text=self.textHighlightSample
- text.bind('<Double-Button-1>',lambda e: 'break')
- text.bind('<B1-Motion>',lambda e: 'break')
- textAndTags=(('#you can click here','comment'),('\n','normal'),
- ('#to choose items','comment'),('\n','normal'),('def','keyword'),
- (' ','normal'),('func','definition'),('(param):','normal'),
- ('\n ','normal'),('"""string"""','string'),('\n var0 = ','normal'),
- ("'string'",'string'),('\n var1 = ','normal'),("'selected'",'hilite'),
- ('\n var2 = ','normal'),("'found'",'hit'),('\n\n','normal'),
- (' error ','error'),(' ','normal'),('cursor |','cursor'),
- ('\n ','normal'),('shell','console'),(' ','normal'),('stdout','stdout'),
- (' ','normal'),('stderr','stderr'),('\n','normal'))
- for txTa in textAndTags:
- text.insert(END,txTa[0],txTa[1])
- for element in self.themeElements.keys():
- text.tag_bind(self.themeElements[element][0],'<ButtonPress-1>',
- lambda event,elem=element: event.widget.winfo_toplevel()
- .highlightTarget.set(elem))
- text.config(state=DISABLED)
- self.frameColourSet=Frame(frameCustom,relief=SOLID,borderwidth=1)
- frameFgBg=Frame(frameCustom)
- labelCustomTitle=Label(frameCustom,text='Set Custom Highlighting')
- buttonSetColour=Button(self.frameColourSet,text='Choose Colour for :',
- command=self.GetColour,highlightthickness=0)
- self.optMenuHighlightTarget=DynOptionMenu(self.frameColourSet,
- self.highlightTarget,None,highlightthickness=0)#,command=self.SetHighlightTargetBinding
- self.radioFg=Radiobutton(frameFgBg,variable=self.fgHilite,
- value=1,text='Foreground',command=self.SetColourSampleBinding)
- self.radioBg=Radiobutton(frameFgBg,variable=self.fgHilite,
- value=0,text='Background',command=self.SetColourSampleBinding)
- self.fgHilite.set(1)
- buttonSaveCustomTheme=Button(frameCustom,
- text='Save as New Custom Theme',command=self.SaveAsNewTheme)
- #frameTheme
- labelThemeTitle=Label(frameTheme,text='Select a Highlighting Theme')
- labelTypeTitle=Label(frameTheme,text='Select : ')
- self.radioThemeBuiltin=Radiobutton(frameTheme,variable=self.themeIsBuiltin,
- value=1,command=self.SetThemeType,text='a Built-in Theme')
- self.radioThemeCustom=Radiobutton(frameTheme,variable=self.themeIsBuiltin,
- value=0,command=self.SetThemeType,text='a Custom Theme')
- self.optMenuThemeBuiltin=DynOptionMenu(frameTheme,
- self.builtinTheme,None,command=None)
- self.optMenuThemeCustom=DynOptionMenu(frameTheme,
- self.customTheme,None,command=None)
- self.buttonDeleteCustomTheme=Button(frameTheme,text='Delete Custom Theme',
- command=self.DeleteCustomTheme)
- ##widget packing
- #body
- frameCustom.pack(side=LEFT,padx=5,pady=10,expand=TRUE,fill=BOTH)
- frameTheme.pack(side=LEFT,padx=5,pady=10,fill=Y)
- #frameCustom
- labelCustomTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- self.frameColourSet.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=X)
- frameFgBg.pack(side=TOP,padx=5,pady=0)
- self.textHighlightSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,
- fill=BOTH)
- buttonSetColour.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=4)
- self.optMenuHighlightTarget.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=3)
- self.radioFg.pack(side=LEFT,anchor=E)
- self.radioBg.pack(side=RIGHT,anchor=W)
- buttonSaveCustomTheme.pack(side=BOTTOM,fill=X,padx=5,pady=5)
- #frameTheme
- labelThemeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- self.radioThemeBuiltin.pack(side=TOP,anchor=W,padx=5)
- self.radioThemeCustom.pack(side=TOP,anchor=W,padx=5,pady=2)
- self.optMenuThemeBuiltin.pack(side=TOP,fill=X,padx=5,pady=5)
- self.optMenuThemeCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5)
- self.buttonDeleteCustomTheme.pack(side=TOP,fill=X,padx=5,pady=5)
- return frame
-
- def CreatePageKeys(self):
- #tkVars
- self.bindingTarget=StringVar(self)
- self.builtinKeys=StringVar(self)
- self.customKeys=StringVar(self)
- self.keysAreBuiltin=BooleanVar(self)
- self.keyBinding=StringVar(self)
- ##widget creation
- #body frame
- frame=self.tabPages.pages['Keys']['page']
- #body section frames
- frameCustom=Frame(frame,borderwidth=2,relief=GROOVE)
- frameKeySets=Frame(frame,borderwidth=2,relief=GROOVE)
- #frameCustom
- frameTarget=Frame(frameCustom)
- labelCustomTitle=Label(frameCustom,text='Set Custom Key Bindings')
- labelTargetTitle=Label(frameTarget,text='Action - Key(s)')
- scrollTargetY=Scrollbar(frameTarget)
- scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL)
- self.listBindings=Listbox(frameTarget,takefocus=FALSE,
- exportselection=FALSE)
- self.listBindings.bind('<ButtonRelease-1>',self.KeyBindingSelected)
- scrollTargetY.config(command=self.listBindings.yview)
- scrollTargetX.config(command=self.listBindings.xview)
- self.listBindings.config(yscrollcommand=scrollTargetY.set)
- self.listBindings.config(xscrollcommand=scrollTargetX.set)
- self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection',
- command=self.GetNewKeys,state=DISABLED)
- buttonSaveCustomKeys=Button(frameCustom,
- text='Save as New Custom Key Set',command=self.SaveAsNewKeySet)
- #frameKeySets
- labelKeysTitle=Label(frameKeySets,text='Select a Key Set')
- labelTypeTitle=Label(frameKeySets,text='Select : ')
- self.radioKeysBuiltin=Radiobutton(frameKeySets,variable=self.keysAreBuiltin,
- value=1,command=self.SetKeysType,text='a Built-in Key Set')
- self.radioKeysCustom=Radiobutton(frameKeySets,variable=self.keysAreBuiltin,
- value=0,command=self.SetKeysType,text='a Custom Key Set')
- self.optMenuKeysBuiltin=DynOptionMenu(frameKeySets,
- self.builtinKeys,None,command=None)
- self.optMenuKeysCustom=DynOptionMenu(frameKeySets,
- self.customKeys,None,command=None)
- self.buttonDeleteCustomKeys=Button(frameKeySets,text='Delete Custom Key Set',
- command=self.DeleteCustomKeys)
- ##widget packing
- #body
- frameCustom.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
- frameKeySets.pack(side=LEFT,padx=5,pady=5,fill=Y)
- #frameCustom
- labelCustomTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- buttonSaveCustomKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
- self.buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
- frameTarget.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
- #frame target
- frameTarget.columnconfigure(0,weight=1)
- frameTarget.rowconfigure(1,weight=1)
- labelTargetTitle.grid(row=0,column=0,columnspan=2,sticky=W)
- self.listBindings.grid(row=1,column=0,sticky=NSEW)
- scrollTargetY.grid(row=1,column=1,sticky=NS)
- scrollTargetX.grid(row=2,column=0,sticky=EW)
- #frameKeySets
- labelKeysTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- self.radioKeysBuiltin.pack(side=TOP,anchor=W,padx=5)
- self.radioKeysCustom.pack(side=TOP,anchor=W,padx=5,pady=2)
- self.optMenuKeysBuiltin.pack(side=TOP,fill=X,padx=5,pady=5)
- self.optMenuKeysCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5)
- self.buttonDeleteCustomKeys.pack(side=TOP,fill=X,padx=5,pady=5)
- return frame
-
- def CreatePageGeneral(self):
- #tkVars
- self.winWidth=StringVar(self)
- self.winHeight=StringVar(self)
- self.startupEdit=IntVar(self)
- self.userHelpBrowser=BooleanVar(self)
- self.helpBrowser=StringVar(self)
- #widget creation
- #body
- frame=self.tabPages.pages['General']['page']
- #body section frames
- frameRun=Frame(frame,borderwidth=2,relief=GROOVE)
- frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE)
- frameHelp=Frame(frame,borderwidth=2,relief=GROOVE)
- #frameRun
- labelRunTitle=Label(frameRun,text='Startup Preferences')
- labelRunChoiceTitle=Label(frameRun,text='On Startup : ')
- radioStartupEdit=Radiobutton(frameRun,variable=self.startupEdit,
- value=1,command=self.SetKeysType,text="Open Edit Window")
- radioStartupShell=Radiobutton(frameRun,variable=self.startupEdit,
- value=0,command=self.SetKeysType,text='Open Shell Window')
- #frameWinSize
- labelWinSizeTitle=Label(frameWinSize,text='Initial Window Size'+
- ' (in characters)')
- labelWinWidthTitle=Label(frameWinSize,text='Width')
- entryWinWidth=Entry(frameWinSize,textvariable=self.winWidth,
- width=3)
- labelWinHeightTitle=Label(frameWinSize,text='Height')
- entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight,
- width=3)
- #frameHelp
- labelHelpTitle=Label(frameHelp,text='Help Options')
- frameHelpList=Frame(frameHelp)
- frameHelpListButtons=Frame(frameHelpList)
- labelHelpListTitle=Label(frameHelpList,text='Additional Help Sources:')
- scrollHelpList=Scrollbar(frameHelpList)
- self.listHelp=Listbox(frameHelpList,height=5,takefocus=FALSE,
- exportselection=FALSE)
- scrollHelpList.config(command=self.listHelp.yview)
- self.listHelp.config(yscrollcommand=scrollHelpList.set)
- self.listHelp.bind('<ButtonRelease-1>',self.HelpSourceSelected)
- self.buttonHelpListEdit=Button(frameHelpListButtons,text='Edit',
- state=DISABLED,width=8,command=self.HelpListItemEdit)
- self.buttonHelpListAdd=Button(frameHelpListButtons,text='Add',
- width=8,command=self.HelpListItemAdd)
- self.buttonHelpListRemove=Button(frameHelpListButtons,text='Remove',
- state=DISABLED,width=8,command=self.HelpListItemRemove)
- # the following is better handled by the BROWSER environment
- # variable under unix/linux
- #checkHelpBrowser=Checkbutton(frameHelp,variable=self.userHelpBrowser,
- # onvalue=1,offvalue=0,text='user specified (html) help browser:',
- # command=self.OnCheckUserHelpBrowser)
- #self.entryHelpBrowser=Entry(frameHelp,textvariable=self.helpBrowser,
- # width=40)
- #widget packing
- #body
- frameRun.pack(side=TOP,padx=5,pady=5,fill=X)
- frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X)
- frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
- #frameRun
- labelRunTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
- radioStartupEdit.pack(side=LEFT,anchor=W,padx=5,pady=5)
- radioStartupShell.pack(side=LEFT,anchor=W,padx=5,pady=5)
- #frameWinSize
- labelWinSizeTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
- entryWinHeight.pack(side=RIGHT,anchor=E,padx=10,pady=5)
- labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5)
- entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5)
- labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5)
- #frameHelp
- labelHelpTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y)
- frameHelpList.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
- labelHelpListTitle.pack(side=TOP,anchor=W)
- scrollHelpList.pack(side=RIGHT,anchor=W,fill=Y)
- self.listHelp.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH)
- self.buttonHelpListEdit.pack(side=TOP,anchor=W,pady=5)
- self.buttonHelpListAdd.pack(side=TOP,anchor=W)
- self.buttonHelpListRemove.pack(side=TOP,anchor=W,pady=5)
- #checkHelpBrowser.pack(side=TOP,anchor=W,padx=5)
- #self.entryHelpBrowser.pack(side=TOP,anchor=W,padx=5,pady=5)
- return frame
-
- def AttachVarCallbacks(self):
- self.fontSize.trace_variable('w',self.VarChanged_fontSize)
- self.fontName.trace_variable('w',self.VarChanged_fontName)
- self.fontBold.trace_variable('w',self.VarChanged_fontBold)
- self.spaceNum.trace_variable('w',self.VarChanged_spaceNum)
- #self.tabCols.trace_variable('w',self.VarChanged_tabCols)
- self.indentBySpaces.trace_variable('w',self.VarChanged_indentBySpaces)
- self.colour.trace_variable('w',self.VarChanged_colour)
- self.builtinTheme.trace_variable('w',self.VarChanged_builtinTheme)
- self.customTheme.trace_variable('w',self.VarChanged_customTheme)
- self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin)
- self.highlightTarget.trace_variable('w',self.VarChanged_highlightTarget)
- self.keyBinding.trace_variable('w',self.VarChanged_keyBinding)
- self.builtinKeys.trace_variable('w',self.VarChanged_builtinKeys)
- self.customKeys.trace_variable('w',self.VarChanged_customKeys)
- self.keysAreBuiltin.trace_variable('w',self.VarChanged_keysAreBuiltin)
- self.winWidth.trace_variable('w',self.VarChanged_winWidth)
- self.winHeight.trace_variable('w',self.VarChanged_winHeight)
- self.startupEdit.trace_variable('w',self.VarChanged_startupEdit)
-
- def VarChanged_fontSize(self,*params):
- value=self.fontSize.get()
- self.AddChangedItem('main','EditorWindow','font-size',value)
-
- def VarChanged_fontName(self,*params):
- value=self.fontName.get()
- self.AddChangedItem('main','EditorWindow','font',value)
-
- def VarChanged_fontBold(self,*params):
- value=self.fontBold.get()
- self.AddChangedItem('main','EditorWindow','font-bold',value)
-
- def VarChanged_indentBySpaces(self,*params):
- value=self.indentBySpaces.get()
- self.AddChangedItem('main','Indent','use-spaces',value)
-
- def VarChanged_spaceNum(self,*params):
- value=self.spaceNum.get()
- self.AddChangedItem('main','Indent','num-spaces',value)
-
- #def VarChanged_tabCols(self,*params):
- # value=self.tabCols.get()
- # self.AddChangedItem('main','Indent','tab-cols',value)
-
- def VarChanged_colour(self,*params):
- self.OnNewColourSet()
-
- def VarChanged_builtinTheme(self,*params):
- value=self.builtinTheme.get()
- self.AddChangedItem('main','Theme','name',value)
- self.PaintThemeSample()
-
- def VarChanged_customTheme(self,*params):
- value=self.customTheme.get()
- if value != '- no custom themes -':
- self.AddChangedItem('main','Theme','name',value)
- self.PaintThemeSample()
-
- def VarChanged_themeIsBuiltin(self,*params):
- value=self.themeIsBuiltin.get()
- self.AddChangedItem('main','Theme','default',value)
- if value:
- self.VarChanged_builtinTheme()
- else:
- self.VarChanged_customTheme()
-
- def VarChanged_highlightTarget(self,*params):
- self.SetHighlightTarget()
-
- def VarChanged_keyBinding(self,*params):
- value=self.keyBinding.get()
- keySet=self.customKeys.get()
- event=self.listBindings.get(ANCHOR).split()[0]
- if idleConf.IsCoreBinding(event):
- #this is a core keybinding
- self.AddChangedItem('keys',keySet,event,value)
- else: #this is an extension key binding
- extName=idleConf.GetExtnNameForEvent(event)
- extKeybindSection=extName+'_cfgBindings'
- self.AddChangedItem('extensions',extKeybindSection,event,value)
-
- def VarChanged_builtinKeys(self,*params):
- value=self.builtinKeys.get()
- self.AddChangedItem('main','Keys','name',value)
- self.LoadKeysList(value)
-
- def VarChanged_customKeys(self,*params):
- value=self.customKeys.get()
- if value != '- no custom keys -':
- self.AddChangedItem('main','Keys','name',value)
- self.LoadKeysList(value)
-
- def VarChanged_keysAreBuiltin(self,*params):
- value=self.keysAreBuiltin.get()
- self.AddChangedItem('main','Keys','default',value)
- if value:
- self.VarChanged_builtinKeys()
- else:
- self.VarChanged_customKeys()
-
- def VarChanged_winWidth(self,*params):
- value=self.winWidth.get()
- self.AddChangedItem('main','EditorWindow','width',value)
-
- def VarChanged_winHeight(self,*params):
- value=self.winHeight.get()
- self.AddChangedItem('main','EditorWindow','height',value)
-
- def VarChanged_startupEdit(self,*params):
- value=self.startupEdit.get()
- self.AddChangedItem('main','General','editor-on-startup',value)
-
- def ResetChangedItems(self):
- #When any config item is changed in this dialog, an entry
- #should be made in the relevant section (config type) of this
- #dictionary. The key should be the config file section name and the
- #value a dictionary, whose key:value pairs are item=value pairs for
- #that config file section.
- self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
-
- def AddChangedItem(self,type,section,item,value):
- value=str(value) #make sure we use a string
- if not self.changedItems[type].has_key(section):
- self.changedItems[type][section]={}
- self.changedItems[type][section][item]=value
-
- def GetDefaultItems(self):
- dItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
- for configType in dItems.keys():
- sections=idleConf.GetSectionList('default',configType)
- for section in sections:
- dItems[configType][section]={}
- options=idleConf.defaultCfg[configType].GetOptionList(section)
- for option in options:
- dItems[configType][section][option]=(
- idleConf.defaultCfg[configType].Get(section,option))
- return dItems
-
- def SetThemeType(self):
- if self.themeIsBuiltin.get():
- self.optMenuThemeBuiltin.config(state=NORMAL)
- self.optMenuThemeCustom.config(state=DISABLED)
- self.buttonDeleteCustomTheme.config(state=DISABLED)
- else:
- self.optMenuThemeBuiltin.config(state=DISABLED)
- self.radioThemeCustom.config(state=NORMAL)
- self.optMenuThemeCustom.config(state=NORMAL)
- self.buttonDeleteCustomTheme.config(state=NORMAL)
-
- def SetKeysType(self):
- if self.keysAreBuiltin.get():
- self.optMenuKeysBuiltin.config(state=NORMAL)
- self.optMenuKeysCustom.config(state=DISABLED)
- self.buttonDeleteCustomKeys.config(state=DISABLED)
- else:
- self.optMenuKeysBuiltin.config(state=DISABLED)
- self.radioKeysCustom.config(state=NORMAL)
- self.optMenuKeysCustom.config(state=NORMAL)
- self.buttonDeleteCustomKeys.config(state=NORMAL)
-
- def GetNewKeys(self):
- listIndex=self.listBindings.index(ANCHOR)
- binding=self.listBindings.get(listIndex)
- bindName=binding.split()[0] #first part, up to first space
- if self.keysAreBuiltin.get():
- currentKeySetName=self.builtinKeys.get()
- else:
- currentKeySetName=self.customKeys.get()
- currentBindings=idleConf.GetCurrentKeySet()
- if currentKeySetName in self.changedItems['keys'].keys(): #unsaved changes
- keySetChanges=self.changedItems['keys'][currentKeySetName]
- for event in keySetChanges.keys():
- currentBindings[event]=keySetChanges[event].split()
- currentKeySequences=currentBindings.values()
- newKeys=GetKeysDialog(self,'Get New Keys',bindName,
- currentKeySequences).result
- if newKeys: #new keys were specified
- if self.keysAreBuiltin.get(): #current key set is a built-in
- message=('Your changes will be saved as a new Custom Key Set. '+
- 'Enter a name for your new Custom Key Set below.')
- newKeySet=self.GetNewKeysName(message)
- if not newKeySet: #user cancelled custom key set creation
- self.listBindings.select_set(listIndex)
- self.listBindings.select_anchor(listIndex)
- return
- else: #create new custom key set based on previously active key set
- self.CreateNewKeySet(newKeySet)
- self.listBindings.delete(listIndex)
- self.listBindings.insert(listIndex,bindName+' - '+newKeys)
- self.listBindings.select_set(listIndex)
- self.listBindings.select_anchor(listIndex)
- self.keyBinding.set(newKeys)
- else:
- self.listBindings.select_set(listIndex)
- self.listBindings.select_anchor(listIndex)
-
- def GetNewKeysName(self,message):
- usedNames=(idleConf.GetSectionList('user','keys')+
- idleConf.GetSectionList('default','keys'))
- newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set',
- message,usedNames).result
- return newKeySet
-
- def SaveAsNewKeySet(self):
- newKeysName=self.GetNewKeysName('New Key Set Name:')
- if newKeysName:
- self.CreateNewKeySet(newKeysName)
-
- def KeyBindingSelected(self,event):
- self.buttonNewKeys.config(state=NORMAL)
-
- def CreateNewKeySet(self,newKeySetName):
- #creates new custom key set based on the previously active key set,
- #and makes the new key set active
- if self.keysAreBuiltin.get():
- prevKeySetName=self.builtinKeys.get()
- else:
- prevKeySetName=self.customKeys.get()
- prevKeys=idleConf.GetCoreKeys(prevKeySetName)
- newKeys={}
- for event in prevKeys.keys(): #add key set to changed items
- eventName=event[2:-2] #trim off the angle brackets
- binding=string.join(prevKeys[event])
- newKeys[eventName]=binding
- #handle any unsaved changes to prev key set
- if prevKeySetName in self.changedItems['keys'].keys():
- keySetChanges=self.changedItems['keys'][prevKeySetName]
- for event in keySetChanges.keys():
- newKeys[event]=keySetChanges[event]
- #save the new theme
- self.SaveNewKeySet(newKeySetName,newKeys)
- #change gui over to the new key set
- customKeyList=idleConf.GetSectionList('user','keys')
- customKeyList.sort()
- self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName)
- self.keysAreBuiltin.set(0)
- self.SetKeysType()
-
- def LoadKeysList(self,keySetName):
- reselect=0
- newKeySet=0
- if self.listBindings.curselection():
- reselect=1
- listIndex=self.listBindings.index(ANCHOR)
- keySet=idleConf.GetKeySet(keySetName)
- bindNames=keySet.keys()
- bindNames.sort()
- self.listBindings.delete(0,END)
- for bindName in bindNames:
- key=string.join(keySet[bindName]) #make key(s) into a string
- bindName=bindName[2:-2] #trim off the angle brackets
- if keySetName in self.changedItems['keys'].keys():
- #handle any unsaved changes to this key set
- if bindName in self.changedItems['keys'][keySetName].keys():
- key=self.changedItems['keys'][keySetName][bindName]
- self.listBindings.insert(END, bindName+' - '+key)
- if reselect:
- self.listBindings.see(listIndex)
- self.listBindings.select_set(listIndex)
- self.listBindings.select_anchor(listIndex)
-
- def DeleteCustomKeys(self):
- keySetName=self.customKeys.get()
- if not tkMessageBox.askyesno('Delete Key Set','Are you sure you wish '+
- 'to delete the key set '+`keySetName`+' ?',
- parent=self):
- return
- #remove key set from config
- idleConf.userCfg['keys'].remove_section(keySetName)
- if self.changedItems['keys'].has_key(keySetName):
- del(self.changedItems['keys'][keySetName])
- #write changes
- idleConf.userCfg['keys'].Save()
- #reload user key set list
- itemList=idleConf.GetSectionList('user','keys')
- itemList.sort()
- if not itemList:
- self.radioKeysCustom.config(state=DISABLED)
- self.optMenuKeysCustom.SetMenu(itemList,'- no custom keys -')
- else:
- self.optMenuKeysCustom.SetMenu(itemList,itemList[0])
- #revert to default key set
- self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys','default'))
- self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys','name'))
- #user can't back out of these changes, they must be applied now
- self.Apply()
- self.SetKeysType()
-
- def DeleteCustomTheme(self):
- themeName=self.customTheme.get()
- if not tkMessageBox.askyesno('Delete Theme','Are you sure you wish '+
- 'to delete the theme '+`themeName`+' ?',
- parent=self):
- return
- #remove theme from config
- idleConf.userCfg['highlight'].remove_section(themeName)
- if self.changedItems['highlight'].has_key(themeName):
- del(self.changedItems['highlight'][themeName])
- #write changes
- idleConf.userCfg['highlight'].Save()
- #reload user theme list
- itemList=idleConf.GetSectionList('user','highlight')
- itemList.sort()
- if not itemList:
- self.radioThemeCustom.config(state=DISABLED)
- self.optMenuThemeCustom.SetMenu(itemList,'- no custom themes -')
- else:
- self.optMenuThemeCustom.SetMenu(itemList,itemList[0])
- #revert to default theme
- self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme','default'))
- self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme','name'))
- #user can't back out of these changes, they must be applied now
- self.Apply()
- self.SetThemeType()
-
- def GetColour(self):
- target=self.highlightTarget.get()
- prevColour=self.frameColourSet.cget('bg')
- rgbTuplet, colourString = tkColorChooser.askcolor(parent=self,
- title='Pick new colour for : '+target,initialcolor=prevColour)
- if colourString and (colourString!=prevColour):
- #user didn't cancel, and they chose a new colour
- if self.themeIsBuiltin.get(): #current theme is a built-in
- message=('Your changes will be saved as a new Custom Theme. '+
- 'Enter a name for your new Custom Theme below.')
- newTheme=self.GetNewThemeName(message)
- if not newTheme: #user cancelled custom theme creation
- return
- else: #create new custom theme based on previously active theme
- self.CreateNewTheme(newTheme)
- self.colour.set(colourString)
- else: #current theme is user defined
- self.colour.set(colourString)
-
- def OnNewColourSet(self):
- newColour=self.colour.get()
- self.frameColourSet.config(bg=newColour)#set sample
- if self.fgHilite.get(): plane='foreground'
- else: plane='background'
- sampleElement=self.themeElements[self.highlightTarget.get()][0]
- apply(self.textHighlightSample.tag_config,
- (sampleElement,),{plane:newColour})
- theme=self.customTheme.get()
- themeElement=sampleElement+'-'+plane
- self.AddChangedItem('highlight',theme,themeElement,newColour)
-
- def GetNewThemeName(self,message):
- usedNames=(idleConf.GetSectionList('user','highlight')+
- idleConf.GetSectionList('default','highlight'))
- newTheme=GetCfgSectionNameDialog(self,'New Custom Theme',
- message,usedNames).result
- return newTheme
-
- def SaveAsNewTheme(self):
- newThemeName=self.GetNewThemeName('New Theme Name:')
- if newThemeName:
- self.CreateNewTheme(newThemeName)
-
- def CreateNewTheme(self,newThemeName):
- #creates new custom theme based on the previously active theme,
- #and makes the new theme active
- if self.themeIsBuiltin.get():
- themeType='default'
- themeName=self.builtinTheme.get()
- else:
- themeType='user'
- themeName=self.customTheme.get()
- newTheme=idleConf.GetThemeDict(themeType,themeName)
- #apply any of the old theme's unsaved changes to the new theme
- if themeName in self.changedItems['highlight'].keys():
- themeChanges=self.changedItems['highlight'][themeName]
- for element in themeChanges.keys():
- newTheme[element]=themeChanges[element]
- #save the new theme
- self.SaveNewTheme(newThemeName,newTheme)
- #change gui over to the new theme
- customThemeList=idleConf.GetSectionList('user','highlight')
- customThemeList.sort()
- self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName)
- self.themeIsBuiltin.set(0)
- self.SetThemeType()
-
- def OnListFontButtonRelease(self,event):
- self.fontName.set(self.listFontName.get(ANCHOR))
- self.SetFontSample()
-
- def SetFontSample(self,event=None):
- fontName=self.fontName.get()
- if self.fontBold.get():
- fontWeight=tkFont.BOLD
- else:
- fontWeight=tkFont.NORMAL
- self.editFont.config(size=self.fontSize.get(),
- weight=fontWeight,family=fontName)
-
- def SetHighlightTarget(self):
- if self.highlightTarget.get()=='Cursor': #bg not possible
- self.radioFg.config(state=DISABLED)
- self.radioBg.config(state=DISABLED)
- self.fgHilite.set(1)
- else: #both fg and bg can be set
- self.radioFg.config(state=NORMAL)
- self.radioBg.config(state=NORMAL)
- self.fgHilite.set(1)
- self.SetColourSample()
-
- def SetColourSampleBinding(self,*args):
- self.SetColourSample()
-
- def SetColourSample(self):
- #set the colour smaple area
- tag=self.themeElements[self.highlightTarget.get()][0]
- if self.fgHilite.get(): plane='foreground'
- else: plane='background'
- colour=self.textHighlightSample.tag_cget(tag,plane)
- self.frameColourSet.config(bg=colour)
-
- def PaintThemeSample(self):
- if self.themeIsBuiltin.get(): #a default theme
- theme=self.builtinTheme.get()
- else: #a user theme
- theme=self.customTheme.get()
- for elementTitle in self.themeElements.keys():
- element=self.themeElements[elementTitle][0]
- colours=idleConf.GetHighlight(theme,element)
- if element=='cursor': #cursor sample needs special painting
- colours['background']=idleConf.GetHighlight(theme,
- 'normal', fgBg='bg')
- #handle any unsaved changes to this theme
- if theme in self.changedItems['highlight'].keys():
- themeDict=self.changedItems['highlight'][theme]
- if themeDict.has_key(element+'-foreground'):
- colours['foreground']=themeDict[element+'-foreground']
- if themeDict.has_key(element+'-background'):
- colours['background']=themeDict[element+'-background']
- apply(self.textHighlightSample.tag_config,(element,),colours)
- self.SetColourSample()
-
-## def OnCheckUserHelpBrowser(self):
-## if self.userHelpBrowser.get():
-## self.entryHelpBrowser.config(state=NORMAL)
-## else:
-## self.entryHelpBrowser.config(state=DISABLED)
-
- def HelpSourceSelected(self,event):
- self.SetHelpListButtonStates()
-
- def SetHelpListButtonStates(self):
- if self.listHelp.size()<1: #no entries in list
- self.buttonHelpListEdit.config(state=DISABLED)
- self.buttonHelpListRemove.config(state=DISABLED)
- else: #there are some entries
- if self.listHelp.curselection(): #there currently is a selection
- self.buttonHelpListEdit.config(state=NORMAL)
- self.buttonHelpListRemove.config(state=NORMAL)
- else: #there currently is not a selection
- self.buttonHelpListEdit.config(state=DISABLED)
- self.buttonHelpListRemove.config(state=DISABLED)
-
- def HelpListItemAdd(self):
- helpSource=GetHelpSourceDialog(self,'New Help Source').result
- if helpSource:
- self.userHelpList.append( (helpSource[0],helpSource[1]) )
- self.listHelp.insert(END,helpSource[0])
- self.UpdateUserHelpChangedItems()
- self.SetHelpListButtonStates()
-
- def HelpListItemEdit(self):
- itemIndex=self.listHelp.index(ANCHOR)
- helpSource=self.userHelpList[itemIndex]
- newHelpSource=GetHelpSourceDialog(self,'Edit Help Source',
- menuItem=helpSource[0],filePath=helpSource[1]).result
- if (not newHelpSource) or (newHelpSource==helpSource):
- return #no changes
- self.userHelpList[itemIndex]=newHelpSource
- self.listHelp.delete(itemIndex)
- self.listHelp.insert(itemIndex,newHelpSource[0])
- self.UpdateUserHelpChangedItems()
- self.SetHelpListButtonStates()
-
- def HelpListItemRemove(self):
- itemIndex=self.listHelp.index(ANCHOR)
- del(self.userHelpList[itemIndex])
- self.listHelp.delete(itemIndex)
- self.UpdateUserHelpChangedItems()
- self.SetHelpListButtonStates()
-
- def UpdateUserHelpChangedItems(self):
- "Clear and rebuild the HelpFiles section in self.changedItems"
- self.changedItems['main']['HelpFiles'] = {}
- for num in range(1,len(self.userHelpList)+1):
- self.AddChangedItem('main','HelpFiles',str(num),
- string.join(self.userHelpList[num-1][:2],';'))
-
- def LoadFontCfg(self):
- ##base editor font selection list
- fonts=list(tkFont.families(self))
- fonts.sort()
- for font in fonts:
- self.listFontName.insert(END,font)
- configuredFont=idleConf.GetOption('main','EditorWindow','font',
- default='courier')
- self.fontName.set(configuredFont)
- if configuredFont in fonts:
- currentFontIndex=fonts.index(configuredFont)
- self.listFontName.see(currentFontIndex)
- self.listFontName.select_set(currentFontIndex)
- self.listFontName.select_anchor(currentFontIndex)
- ##font size dropdown
- fontSize=idleConf.GetOption('main','EditorWindow','font-size',
- default='12')
- self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14',
- '16','18','20','22'),fontSize )
- ##fontWeight
- self.fontBold.set(idleConf.GetOption('main','EditorWindow',
- 'font-bold',default=0,type='bool'))
- ##font sample
- self.SetFontSample()
-
- def LoadTabCfg(self):
- ##indent type radiobuttons
- spaceIndent=idleConf.GetOption('main','Indent','use-spaces',
- default=1,type='bool')
- self.indentBySpaces.set(spaceIndent)
- ##indent sizes
- spaceNum=idleConf.GetOption('main','Indent','num-spaces',
- default=4,type='int')
- #tabCols=idleConf.GetOption('main','Indent','tab-cols',
- # default=4,type='int')
- self.spaceNum.set(spaceNum)
- #self.tabCols.set(tabCols)
-
- def LoadThemeCfg(self):
- ##current theme type radiobutton
- self.themeIsBuiltin.set(idleConf.GetOption('main','Theme','default',
- type='bool',default=1))
- ##currently set theme
- currentOption=idleConf.CurrentTheme()
- ##load available theme option menus
- if self.themeIsBuiltin.get(): #default theme selected
- itemList=idleConf.GetSectionList('default','highlight')
- itemList.sort()
- self.optMenuThemeBuiltin.SetMenu(itemList,currentOption)
- itemList=idleConf.GetSectionList('user','highlight')
- itemList.sort()
- if not itemList:
- self.radioThemeCustom.config(state=DISABLED)
- self.customTheme.set('- no custom themes -')
- else:
- self.optMenuThemeCustom.SetMenu(itemList,itemList[0])
- else: #user theme selected
- itemList=idleConf.GetSectionList('user','highlight')
- itemList.sort()
- self.optMenuThemeCustom.SetMenu(itemList,currentOption)
- itemList=idleConf.GetSectionList('default','highlight')
- itemList.sort()
- self.optMenuThemeBuiltin.SetMenu(itemList,itemList[0])
- self.SetThemeType()
- ##load theme element option menu
- themeNames=self.themeElements.keys()
- themeNames.sort(self.__ThemeNameIndexCompare)
- self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0])
- self.PaintThemeSample()
- self.SetHighlightTarget()
-
- def __ThemeNameIndexCompare(self,a,b):
- if self.themeElements[a][1]<self.themeElements[b][1]: return -1
- elif self.themeElements[a][1]==self.themeElements[b][1]: return 0
- else: return 1
-
- def LoadKeyCfg(self):
- ##current keys type radiobutton
- self.keysAreBuiltin.set(idleConf.GetOption('main','Keys','default',
- type='bool',default=1))
- ##currently set keys
- currentOption=idleConf.CurrentKeys()
- ##load available keyset option menus
- if self.keysAreBuiltin.get(): #default theme selected
- itemList=idleConf.GetSectionList('default','keys')
- itemList.sort()
- self.optMenuKeysBuiltin.SetMenu(itemList,currentOption)
- itemList=idleConf.GetSectionList('user','keys')
- itemList.sort()
- if not itemList:
- self.radioKeysCustom.config(state=DISABLED)
- self.customKeys.set('- no custom keys -')
- else:
- self.optMenuKeysCustom.SetMenu(itemList,itemList[0])
- else: #user key set selected
- itemList=idleConf.GetSectionList('user','keys')
- itemList.sort()
- self.optMenuKeysCustom.SetMenu(itemList,currentOption)
- itemList=idleConf.GetSectionList('default','keys')
- itemList.sort()
- self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0])
- self.SetKeysType()
- ##load keyset element list
- keySetName=idleConf.CurrentKeys()
- self.LoadKeysList(keySetName)
-
- def LoadGeneralCfg(self):
- #startup state
- self.startupEdit.set(idleConf.GetOption('main','General',
- 'editor-on-startup',default=1,type='bool'))
- #initial window size
- self.winWidth.set(idleConf.GetOption('main','EditorWindow','width'))
- self.winHeight.set(idleConf.GetOption('main','EditorWindow','height'))
- # additional help sources
- self.userHelpList = idleConf.GetAllExtraHelpSourcesList()
- for helpItem in self.userHelpList:
- self.listHelp.insert(END,helpItem[0])
- self.SetHelpListButtonStates()
- #self.userHelpBrowser.set(idleConf.GetOption('main','General',
- # 'user-help-browser',default=0,type='bool'))
- #self.helpBrowser.set(idleConf.GetOption('main','General',
- # 'user-help-browser-command',default=''))
- #self.OnCheckUserHelpBrowser()
-
- def LoadConfigs(self):
- """
- load configuration from default and user config files and populate
- the widgets on the config dialog pages.
- """
- ### fonts / tabs page
- self.LoadFontCfg()
- self.LoadTabCfg()
- ### highlighting page
- self.LoadThemeCfg()
- ### keys page
- self.LoadKeyCfg()
- ### general page
- self.LoadGeneralCfg()
-
- def SaveNewKeySet(self,keySetName,keySet):
- """
- save a newly created core key set.
- keySetName - string, the name of the new key set
- keySet - dictionary containing the new key set
- """
- if not idleConf.userCfg['keys'].has_section(keySetName):
- idleConf.userCfg['keys'].add_section(keySetName)
- for event in keySet.keys():
- value=keySet[event]
- idleConf.userCfg['keys'].SetOption(keySetName,event,value)
-
- def SaveNewTheme(self,themeName,theme):
- """
- save a newly created theme.
- themeName - string, the name of the new theme
- theme - dictionary containing the new theme
- """
- if not idleConf.userCfg['highlight'].has_section(themeName):
- idleConf.userCfg['highlight'].add_section(themeName)
- for element in theme.keys():
- value=theme[element]
- idleConf.userCfg['highlight'].SetOption(themeName,element,value)
-
- def SetUserValue(self,configType,section,item,value):
- if idleConf.defaultCfg[configType].has_option(section,item):
- if idleConf.defaultCfg[configType].Get(section,item)==value:
- #the setting equals a default setting, remove it from user cfg
- return idleConf.userCfg[configType].RemoveOption(section,item)
- #if we got here set the option
- return idleConf.userCfg[configType].SetOption(section,item,value)
-
- def SaveAllChangedConfigs(self):
- "Save configuration changes to the user config file."
- idleConf.userCfg['main'].Save()
- for configType in self.changedItems.keys():
- cfgTypeHasChanges = False
- for section in self.changedItems[configType].keys():
- if section == 'HelpFiles':
- #this section gets completely replaced
- idleConf.userCfg['main'].remove_section('HelpFiles')
- cfgTypeHasChanges = True
- for item in self.changedItems[configType][section].keys():
- value = self.changedItems[configType][section][item]
- if self.SetUserValue(configType,section,item,value):
- cfgTypeHasChanges = True
- if cfgTypeHasChanges:
- idleConf.userCfg[configType].Save()
- self.ResetChangedItems() #clear the changed items dict
-
- def ActivateConfigChanges(self):
- #things that need to be done to make
- #applied config changes dynamic:
- #update editor/shell font and repaint
- #dynamically update indentation setttings
- #update theme and repaint
- #update keybindings and re-bind
- #update user help sources menu
- winInstances=self.parent.instanceDict.keys()
- for instance in winInstances:
- instance.ResetColorizer()
- instance.ResetFont()
- instance.ResetKeybindings()
- instance.reset_help_menu_entries()
-
- def Cancel(self):
- self.destroy()
-
- def Ok(self):
- self.Apply()
- self.destroy()
-
- def Apply(self):
- self.SaveAllChangedConfigs()
- self.ActivateConfigChanges()
-
- def Help(self):
- pass
-
-if __name__ == '__main__':
- #test the dialog
- root=Tk()
- Button(root,text='Dialog',
- command=lambda:ConfigDialog(root,'Settings')).pack()
- root.instanceDict={}
- root.mainloop()
diff --git a/Tools/idle/configHandler.py b/Tools/idle/configHandler.py
deleted file mode 100644
index fd9cbc4..0000000
--- a/Tools/idle/configHandler.py
+++ /dev/null
@@ -1,655 +0,0 @@
-"""Provides access to stored IDLE configuration information.
-
-Refer to the comments at the beginning of config-main.def for a description of
-the available configuration files and the design implemented to update user
-configuration information. In particular, user configuration choices which
-duplicate the defaults will be removed from the user's configuration files,
-and if a file becomes empty, it will be deleted.
-
-The contents of the user files may be altered using the Options/Configure IDLE
-menu to access the configuration GUI (configDialog.py), or manually.
-
-Throughout this module there is an emphasis on returning useable defaults
-when a problem occurs in returning a requested configuration value back to
-idle. This is to allow IDLE to continue to function in spite of errors in
-the retrieval of config information. When a default is returned instead of
-a requested config value, a message is printed to stderr to aid in
-configuration problem notification and resolution.
-
-"""
-import os
-import sys
-import string
-from ConfigParser import ConfigParser, NoOptionError, NoSectionError
-
-class InvalidConfigType(Exception): pass
-class InvalidConfigSet(Exception): pass
-class InvalidFgBg(Exception): pass
-class InvalidTheme(Exception): pass
-
-class IdleConfParser(ConfigParser):
- """
- A ConfigParser specialised for idle configuration file handling
- """
- def __init__(self, cfgFile, cfgDefaults=None):
- """
- cfgFile - string, fully specified configuration file name
- """
- self.file=cfgFile
- ConfigParser.__init__(self,defaults=cfgDefaults)
-
- def Get(self, section, option, type=None, default=None):
- """
- Get an option value for given section/option or return default.
- If type is specified, return as type.
- """
- if type=='bool':
- getVal=self.getboolean
- elif type=='int':
- getVal=self.getint
- else:
- getVal=self.get
- if self.has_option(section,option):
- #return getVal(section, option, raw, vars, default)
- return getVal(section, option)
- else:
- return default
-
- def GetOptionList(self,section):
- """
- Get an option list for given section
- """
- if self.has_section(section):
- return self.options(section)
- else: #return a default value
- return []
-
- def Load(self):
- """
- Load the configuration file from disk
- """
- self.read(self.file)
-
-class IdleUserConfParser(IdleConfParser):
- """
- IdleConfigParser specialised for user configuration handling.
- """
-
- def AddSection(self,section):
- """
- if section doesn't exist, add it
- """
- if not self.has_section(section):
- self.add_section(section)
-
- def RemoveEmptySections(self):
- """
- remove any sections that have no options
- """
- for section in self.sections():
- if not self.GetOptionList(section):
- self.remove_section(section)
-
- def IsEmpty(self):
- """
- Remove empty sections and then return 1 if parser has no sections
- left, else return 0.
- """
- self.RemoveEmptySections()
- if self.sections():
- return 0
- else:
- return 1
-
- def RemoveOption(self,section,option):
- """
- If section/option exists, remove it.
- Returns 1 if option was removed, 0 otherwise.
- """
- if self.has_section(section):
- return self.remove_option(section,option)
-
- def SetOption(self,section,option,value):
- """
- Sets option to value, adding section if required.
- Returns 1 if option was added or changed, otherwise 0.
- """
- if self.has_option(section,option):
- if self.get(section,option)==value:
- return 0
- else:
- self.set(section,option,value)
- return 1
- else:
- if not self.has_section(section):
- self.add_section(section)
- self.set(section,option,value)
- return 1
-
- def RemoveFile(self):
- """
- Removes the user config file from disk if it exists.
- """
- if os.path.exists(self.file):
- os.remove(self.file)
-
- def Save(self):
- """Update user configuration file.
-
- Remove empty sections. If resulting config isn't empty, write the file
- to disk. If config is empty, remove the file from disk if it exists.
-
- """
- if not self.IsEmpty():
- cfgFile=open(self.file,'w')
- self.write(cfgFile)
- else:
- self.RemoveFile()
-
-class IdleConf:
- """
- holds config parsers for all idle config files:
- default config files
- (idle install dir)/config-main.def
- (idle install dir)/config-extensions.def
- (idle install dir)/config-highlight.def
- (idle install dir)/config-keys.def
- user config files
- (user home dir)/.idlerc/config-main.cfg
- (user home dir)/.idlerc/config-extensions.cfg
- (user home dir)/.idlerc/config-highlight.cfg
- (user home dir)/.idlerc/config-keys.cfg
- """
- def __init__(self):
- self.defaultCfg={}
- self.userCfg={}
- self.cfg={}
- self.CreateConfigHandlers()
- self.LoadCfgFiles()
- #self.LoadCfg()
-
- def CreateConfigHandlers(self):
- """
- set up a dictionary of config parsers for default and user
- configurations respectively
- """
- #build idle install path
- if __name__ != '__main__': # we were imported
- idleDir=os.path.dirname(__file__)
- else: # we were exec'ed (for testing only)
- idleDir=os.path.abspath(sys.path[0])
- userDir=self.GetUserCfgDir()
- configTypes=('main','extensions','highlight','keys')
- defCfgFiles={}
- usrCfgFiles={}
- for cfgType in configTypes: #build config file names
- defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def')
- usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg')
- for cfgType in configTypes: #create config parsers
- self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType])
- self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType])
-
- def GetUserCfgDir(self):
- """
- Creates (if required) and returns a filesystem directory for storing
- user config files.
- """
- cfgDir='.idlerc'
- userDir=os.path.expanduser('~')
- if userDir != '~': #'HOME' exists as a key in os.environ
- if not os.path.exists(userDir):
- warn=('\n Warning: HOME environment variable points to\n '+
- userDir+'\n but the path does not exist.\n')
- sys.stderr.write(warn)
- userDir='~'
- if userDir=='~': #we still don't have a home directory
- #traditionally idle has defaulted to os.getcwd(), is this adeqate?
- userDir = os.getcwd() #hack for no real homedir
- userDir=os.path.join(userDir,cfgDir)
- if not os.path.exists(userDir):
- try: #make the config dir if it doesn't exist yet
- os.mkdir(userDir)
- except IOError:
- warn=('\n Warning: unable to create user config directory\n '+
- userDir+'\n')
- sys.stderr.write(warn)
- return userDir
-
- def GetOption(self, configType, section, option, default=None, type=None):
- """
- Get an option value for given config type and given general
- configuration section/option or return a default. If type is specified,
- return as type. Firstly the user configuration is checked, with a
- fallback to the default configuration, and a final 'catch all'
- fallback to a useable passed-in default if the option isn't present in
- either the user or the default configuration.
- configType must be one of ('main','extensions','highlight','keys')
- If a default is returned a warning is printed to stderr.
- """
- if self.userCfg[configType].has_option(section,option):
- return self.userCfg[configType].Get(section, option, type=type)
- elif self.defaultCfg[configType].has_option(section,option):
- return self.defaultCfg[configType].Get(section, option, type=type)
- else: #returning default, print warning
- warning=('\n Warning: configHandler.py - IdleConf.GetOption -\n'+
- ' problem retrieving configration option '+`option`+'\n'+
- ' from section '+`section`+'.\n'+
- ' returning default value: '+`default`+'\n')
- sys.stderr.write(warning)
- return default
-
- def GetSectionList(self, configSet, configType):
- """
- Get a list of sections from either the user or default config for
- the given config type.
- configSet must be either 'user' or 'default'
- configType must be one of ('main','extensions','highlight','keys')
- """
- if not (configType in ('main','extensions','highlight','keys')):
- raise InvalidConfigType, 'Invalid configType specified'
- if configSet == 'user':
- cfgParser=self.userCfg[configType]
- elif configSet == 'default':
- cfgParser=self.defaultCfg[configType]
- else:
- raise InvalidConfigSet, 'Invalid configSet specified'
- return cfgParser.sections()
-
- def GetHighlight(self, theme, element, fgBg=None):
- """
- return individual highlighting theme elements.
- fgBg - string ('fg'or'bg') or None, if None return a dictionary
- containing fg and bg colours (appropriate for passing to Tkinter in,
- e.g., a tag_config call), otherwise fg or bg colour only as specified.
- """
- if self.defaultCfg['highlight'].has_section(theme):
- themeDict=self.GetThemeDict('default',theme)
- else:
- themeDict=self.GetThemeDict('user',theme)
- fore=themeDict[element+'-foreground']
- if element=='cursor': #there is no config value for cursor bg
- back=themeDict['normal-background']
- else:
- back=themeDict[element+'-background']
- highlight={"foreground": fore,"background": back}
- if not fgBg: #return dict of both colours
- return highlight
- else: #return specified colour only
- if fgBg == 'fg':
- return highlight["foreground"]
- if fgBg == 'bg':
- return highlight["background"]
- else:
- raise InvalidFgBg, 'Invalid fgBg specified'
-
- def GetThemeDict(self,type,themeName):
- """
- type - string, 'default' or 'user' theme type
- themeName - string, theme name
- Returns a dictionary which holds {option:value} for each element
- in the specified theme. Values are loaded over a set of ultimate last
- fallback defaults to guarantee that all theme elements are present in
- a newly created theme.
- """
- if type == 'user':
- cfgParser=self.userCfg['highlight']
- elif type == 'default':
- cfgParser=self.defaultCfg['highlight']
- else:
- raise InvalidTheme, 'Invalid theme type specified'
- #foreground and background values are provded for each theme element
- #(apart from cursor) even though all these values are not yet used
- #by idle, to allow for their use in the future. Default values are
- #generally black and white.
- theme={ 'normal-foreground':'#000000',
- 'normal-background':'#ffffff',
- 'keyword-foreground':'#000000',
- 'keyword-background':'#ffffff',
- 'comment-foreground':'#000000',
- 'comment-background':'#ffffff',
- 'string-foreground':'#000000',
- 'string-background':'#ffffff',
- 'definition-foreground':'#000000',
- 'definition-background':'#ffffff',
- 'hilite-foreground':'#000000',
- 'hilite-background':'gray',
- 'break-foreground':'#ffffff',
- 'break-background':'#000000',
- 'hit-foreground':'#ffffff',
- 'hit-background':'#000000',
- 'error-foreground':'#ffffff',
- 'error-background':'#000000',
- #cursor (only foreground can be set)
- 'cursor-foreground':'#000000',
- #shell window
- 'stdout-foreground':'#000000',
- 'stdout-background':'#ffffff',
- 'stderr-foreground':'#000000',
- 'stderr-background':'#ffffff',
- 'console-foreground':'#000000',
- 'console-background':'#ffffff' }
- for element in theme.keys():
- if not cfgParser.has_option(themeName,element):
- #we are going to return a default, print warning
- warning=('\n Warning: configHandler.py - IdleConf.GetThemeDict'+
- ' -\n problem retrieving theme element '+`element`+
- '\n from theme '+`themeName`+'.\n'+
- ' returning default value: '+`theme[element]`+'\n')
- sys.stderr.write(warning)
- colour=cfgParser.Get(themeName,element,default=theme[element])
- theme[element]=colour
- return theme
-
- def CurrentTheme(self):
- """
- Returns the name of the currently active theme
- """
- return self.GetOption('main','Theme','name',default='')
-
- def CurrentKeys(self):
- """
- Returns the name of the currently active key set
- """
- return self.GetOption('main','Keys','name',default='')
-
- def GetExtensions(self, activeOnly=1):
- """
- Gets a list of all idle extensions declared in the config files.
- activeOnly - boolean, if true only return active (enabled) extensions
- """
- extns=self.RemoveKeyBindNames(
- self.GetSectionList('default','extensions'))
- userExtns=self.RemoveKeyBindNames(
- self.GetSectionList('user','extensions'))
- for extn in userExtns:
- if extn not in extns: #user has added own extension
- extns.append(extn)
- if activeOnly:
- activeExtns=[]
- for extn in extns:
- if self.GetOption('extensions',extn,'enable',default=1,
- type='bool'):
- #the extension is enabled
- activeExtns.append(extn)
- return activeExtns
- else:
- return extns
-
- def RemoveKeyBindNames(self,extnNameList):
- #get rid of keybinding section names
- names=extnNameList
- kbNameIndicies=[]
- for name in names:
- if name.endswith('_bindings') or name.endswith('_cfgBindings'):
- kbNameIndicies.append(names.index(name))
- kbNameIndicies.sort()
- kbNameIndicies.reverse()
- for index in kbNameIndicies: #delete each keybinding section name
- del(names[index])
- return names
-
- def GetExtnNameForEvent(self,virtualEvent):
- """
- Returns the name of the extension that virtualEvent is bound in, or
- None if not bound in any extension.
- virtualEvent - string, name of the virtual event to test for, without
- the enclosing '<< >>'
- """
- extName=None
- vEvent='<<'+virtualEvent+'>>'
- for extn in self.GetExtensions(activeOnly=0):
- for event in self.GetExtensionKeys(extn).keys():
- if event == vEvent:
- extName=extn
- return extName
-
- def GetExtensionKeys(self,extensionName):
- """
- returns a dictionary of the configurable keybindings for a particular
- extension,as they exist in the dictionary returned by GetCurrentKeySet;
- that is, where previously used bindings are disabled.
- """
- keysName=extensionName+'_cfgBindings'
- activeKeys=self.GetCurrentKeySet()
- extKeys={}
- if self.defaultCfg['extensions'].has_section(keysName):
- eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
- for eventName in eventNames:
- event='<<'+eventName+'>>'
- binding=activeKeys[event]
- extKeys[event]=binding
- return extKeys
-
- def __GetRawExtensionKeys(self,extensionName):
- """
- returns a dictionary of the configurable keybindings for a particular
- extension, as defined in the configuration files, or an empty dictionary
- if no bindings are found
- """
- keysName=extensionName+'_cfgBindings'
- extKeys={}
- if self.defaultCfg['extensions'].has_section(keysName):
- eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
- for eventName in eventNames:
- binding=self.GetOption('extensions',keysName,
- eventName,default='').split()
- event='<<'+eventName+'>>'
- extKeys[event]=binding
- return extKeys
-
- def GetExtensionBindings(self,extensionName):
- """
- Returns a dictionary of all the event bindings for a particular
- extension. The configurable keybindings are returned as they exist in
- the dictionary returned by GetCurrentKeySet; that is, where re-used
- keybindings are disabled.
- """
- bindsName=extensionName+'_bindings'
- extBinds=self.GetExtensionKeys(extensionName)
- #add the non-configurable bindings
- if self.defaultCfg['extensions'].has_section(bindsName):
- eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName)
- for eventName in eventNames:
- binding=self.GetOption('extensions',bindsName,
- eventName,default='').split()
- event='<<'+eventName+'>>'
- extBinds[event]=binding
-
- return extBinds
-
- def GetKeyBinding(self, keySetName, eventStr):
- """
- returns the keybinding for a specific event.
- keySetName - string, name of key binding set
- eventStr - string, the virtual event we want the binding for,
- represented as a string, eg. '<<event>>'
- """
- eventName=eventStr[2:-2] #trim off the angle brackets
- binding=self.GetOption('keys',keySetName,eventName,default='').split()
- return binding
-
- def GetCurrentKeySet(self):
- return self.GetKeySet(self.CurrentKeys())
-
- def GetKeySet(self,keySetName):
- """
- Returns a dictionary of: all requested core keybindings, plus the
- keybindings for all currently active extensions. If a binding defined
- in an extension is already in use, that binding is disabled.
- """
- keySet=self.GetCoreKeys(keySetName)
- activeExtns=self.GetExtensions(activeOnly=1)
- for extn in activeExtns:
- extKeys=self.__GetRawExtensionKeys(extn)
- if extKeys: #the extension defines keybindings
- for event in extKeys.keys():
- if extKeys[event] in keySet.values():
- #the binding is already in use
- extKeys[event]='' #disable this binding
- keySet[event]=extKeys[event] #add binding
- return keySet
-
- def IsCoreBinding(self,virtualEvent):
- """
- returns true if the virtual event is bound in the core idle keybindings.
- virtualEvent - string, name of the virtual event to test for, without
- the enclosing '<< >>'
- """
- return ('<<'+virtualEvent+'>>') in self.GetCoreKeys().keys()
-
- def GetCoreKeys(self, keySetName=None):
- """
- returns the requested set of core keybindings, with fallbacks if
- required.
- Keybindings loaded from the config file(s) are loaded _over_ these
- defaults, so if there is a problem getting any core binding there will
- be an 'ultimate last resort fallback' to the CUA-ish bindings
- defined here.
- """
- keyBindings={
- '<<copy>>': ['<Control-c>', '<Control-C>'],
- '<<cut>>': ['<Control-x>', '<Control-X>'],
- '<<paste>>': ['<Control-v>', '<Control-V>'],
- '<<beginning-of-line>>': ['<Control-a>', '<Home>'],
- '<<center-insert>>': ['<Control-l>'],
- '<<close-all-windows>>': ['<Control-q>'],
- '<<close-window>>': ['<Alt-F4>'],
- '<<do-nothing>>': ['<Control-x>'],
- '<<end-of-file>>': ['<Control-d>'],
- '<<python-docs>>': ['<F1>'],
- '<<python-context-help>>': ['<Shift-F1>'],
- '<<history-next>>': ['<Alt-n>'],
- '<<history-previous>>': ['<Alt-p>'],
- '<<interrupt-execution>>': ['<Control-c>'],
- '<<view-restart>>': ['<F6>'],
- '<<restart-shell>>': ['<Control-F6>'],
- '<<open-class-browser>>': ['<Alt-c>'],
- '<<open-module>>': ['<Alt-m>'],
- '<<open-new-window>>': ['<Control-n>'],
- '<<open-window-from-file>>': ['<Control-o>'],
- '<<plain-newline-and-indent>>': ['<Control-j>'],
- '<<print-window>>': ['<Control-p>'],
- '<<redo>>': ['<Control-y>'],
- '<<remove-selection>>': ['<Escape>'],
- '<<save-copy-of-window-as-file>>': ['<Alt-Shift-s>'],
- '<<save-window-as-file>>': ['<Alt-s>'],
- '<<save-window>>': ['<Control-s>'],
- '<<select-all>>': ['<Alt-a>'],
- '<<toggle-auto-coloring>>': ['<Control-slash>'],
- '<<undo>>': ['<Control-z>'],
- '<<find-again>>': ['<Control-g>', '<F3>'],
- '<<find-in-files>>': ['<Alt-F3>'],
- '<<find-selection>>': ['<Control-F3>'],
- '<<find>>': ['<Control-f>'],
- '<<replace>>': ['<Control-h>'],
- '<<goto-line>>': ['<Alt-g>'],
- '<<smart-backspace>>': ['<Key-BackSpace>'],
- '<<newline-and-indent>>': ['<Key-Return> <Key-KP_Enter>'],
- '<<smart-indent>>': ['<Key-Tab>'],
- '<<indent-region>>': ['<Control-Key-bracketright>'],
- '<<dedent-region>>': ['<Control-Key-bracketleft>'],
- '<<comment-region>>': ['<Alt-Key-3>'],
- '<<uncomment-region>>': ['<Alt-Key-4>'],
- '<<tabify-region>>': ['<Alt-Key-5>'],
- '<<untabify-region>>': ['<Alt-Key-6>'],
- '<<toggle-tabs>>': ['<Alt-Key-t>'],
- '<<change-indentwidth>>': ['<Alt-Key-u>']
- }
- if keySetName:
- for event in keyBindings.keys():
- binding=self.GetKeyBinding(keySetName,event)
- if binding:
- keyBindings[event]=binding
- else: #we are going to return a default, print warning
- warning=('\n Warning: configHandler.py - IdleConf.GetCoreKeys'+
- ' -\n problem retrieving key binding for event '+
- `event`+'\n from key set '+`keySetName`+'.\n'+
- ' returning default value: '+`keyBindings[event]`+'\n')
- sys.stderr.write(warning)
- return keyBindings
-
- def GetExtraHelpSourceList(self,configSet):
- """Fetch list of extra help sources from a given configSet.
-
- Valid configSets are 'user' or 'default'. Return a list of tuples of
- the form (menu_item , path_to_help_file , option), or return the empty
- list. 'option' is the sequence number of the help resource. 'option'
- values determine the position of the menu items on the Help menu,
- therefore the returned list must be sorted by 'option'.
-
- """
- helpSources=[]
- if configSet=='user':
- cfgParser=self.userCfg['main']
- elif configSet=='default':
- cfgParser=self.defaultCfg['main']
- else:
- raise InvalidConfigSet, 'Invalid configSet specified'
- options=cfgParser.GetOptionList('HelpFiles')
- for option in options:
- value=cfgParser.Get('HelpFiles',option,default=';')
- if value.find(';')==-1: #malformed config entry with no ';'
- menuItem='' #make these empty
- helpPath='' #so value won't be added to list
- else: #config entry contains ';' as expected
- value=string.split(value,';')
- menuItem=value[0].strip()
- helpPath=value[1].strip()
- if menuItem and helpPath: #neither are empty strings
- helpSources.append( (menuItem,helpPath,option) )
- helpSources.sort(self.__helpsort)
- return helpSources
-
- def __helpsort(self, h1, h2):
- if int(h1[2]) < int(h2[2]):
- return -1
- elif int(h1[2]) > int(h2[2]):
- return 1
- else:
- return 0
-
- def GetAllExtraHelpSourcesList(self):
- """
- Returns a list of tuples containing the details of all additional help
- sources configured, or an empty list if there are none. Tuples are of
- the format returned by GetExtraHelpSourceList.
- """
- allHelpSources=( self.GetExtraHelpSourceList('default')+
- self.GetExtraHelpSourceList('user') )
- return allHelpSources
-
- def LoadCfgFiles(self):
- """
- load all configuration files.
- """
- for key in self.defaultCfg.keys():
- self.defaultCfg[key].Load()
- self.userCfg[key].Load() #same keys
-
- def SaveUserCfgFiles(self):
- """
- write all loaded user configuration files back to disk
- """
- for key in self.userCfg.keys():
- self.userCfg[key].Save()
-
-idleConf=IdleConf()
-
-### module test
-if __name__ == '__main__':
- def dumpCfg(cfg):
- print '\n',cfg,'\n'
- for key in cfg.keys():
- sections=cfg[key].sections()
- print key
- print sections
- for section in sections:
- options=cfg[key].options(section)
- print section
- print options
- for option in options:
- print option, '=', cfg[key].Get(section,option)
- dumpCfg(idleConf.defaultCfg)
- dumpCfg(idleConf.userCfg)
- print idleConf.userCfg['main'].Get('Theme','name')
- #print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal')
diff --git a/Tools/idle/configHelpSourceEdit.py b/Tools/idle/configHelpSourceEdit.py
deleted file mode 100644
index b781884..0000000
--- a/Tools/idle/configHelpSourceEdit.py
+++ /dev/null
@@ -1,157 +0,0 @@
-"Dialog to specify or edit the parameters for a user configured help source."
-
-import os
-
-from Tkinter import *
-import tkMessageBox
-import tkFileDialog
-
-class GetHelpSourceDialog(Toplevel):
- def __init__(self, parent, title, menuItem='', filePath=''):
- """Get menu entry and url/ local file location for Additional Help
-
- User selects a name for the Help resource and provides a web url
- or a local file as its source. The user can enter a url or browse
- for the file.
-
- """
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.resizable(height=FALSE, width=FALSE)
- self.title(title)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Cancel)
- self.parent = parent
- self.result = None
- self.CreateWidgets()
- self.menu.set(menuItem)
- self.path.set(filePath)
- self.withdraw() #hide while setting geometry
- #needs to be done here so that the winfo_reqwidth is valid
- self.update_idletasks()
- #centre dialog over parent:
- self.geometry("+%d+%d" %
- ((parent.winfo_rootx() + ((parent.winfo_width()/2)
- -(self.winfo_reqwidth()/2)),
- parent.winfo_rooty() + ((parent.winfo_height()/2)
- -(self.winfo_reqheight()/2)))))
- self.deiconify() #geometry set, unhide
- self.bind('<Return>', self.Ok)
- self.wait_window()
-
- def CreateWidgets(self):
- self.menu = StringVar(self)
- self.path = StringVar(self)
- self.fontSize = StringVar(self)
- self.frameMain = Frame(self, borderwidth=2, relief=GROOVE)
- self.frameMain.pack(side=TOP, expand=TRUE, fill=BOTH)
- labelMenu = Label(self.frameMain, anchor=W, justify=LEFT,
- text='Menu Item:')
- self.entryMenu = Entry(self.frameMain, textvariable=self.menu,
- width=30)
- self.entryMenu.focus_set()
- labelPath = Label(self.frameMain, anchor=W, justify=LEFT,
- text='Help File Path: Enter URL or browse for file')
- self.entryPath = Entry(self.frameMain, textvariable=self.path,
- width=40)
- self.entryMenu.focus_set()
- labelMenu.pack(anchor=W, padx=5, pady=3)
- self.entryMenu.pack(anchor=W, padx=5, pady=3)
- labelPath.pack(anchor=W, padx=5, pady=3)
- self.entryPath.pack(anchor=W, padx=5, pady=3)
- browseButton = Button(self.frameMain, text='Browse', width=8,
- command=self.browseFile)
- browseButton.pack(pady=3)
- frameButtons = Frame(self)
- frameButtons.pack(side=BOTTOM, fill=X)
- self.buttonOk = Button(frameButtons, text='OK',
- width=8, default=ACTIVE, command=self.Ok)
- self.buttonOk.grid(row=0, column=0, padx=5,pady=5)
- self.buttonCancel = Button(frameButtons, text='Cancel',
- width=8, command=self.Cancel)
- self.buttonCancel.grid(row=0, column=1, padx=5, pady=5)
-
- def browseFile(self):
- filetypes = [
- ("HTML Files", "*.htm *.html", "TEXT"),
- ("PDF Files", "*.pdf", "TEXT"),
- ("Windows Help Files", "*.chm"),
- ("Text Files", "*.txt", "TEXT"),
- ("All Files", "*")]
- path = self.path.get()
- if path:
- dir, base = os.path.split(path)
- else:
- base = None
- if sys.platform.count('win') or sys.platform.count('nt'):
- dir = os.path.join(os.path.dirname(sys.executable), 'Doc')
- if not os.path.isdir(dir):
- dir = os.getcwd()
- else:
- dir = os.getcwd()
- opendialog = tkFileDialog.Open(parent=self, filetypes=filetypes)
- file = opendialog.show(initialdir=dir, initialfile=base)
- if file:
- self.path.set(file)
-
- def MenuOk(self):
- "Simple validity check for a sensible menu item name"
- menuOk = True
- menu = self.menu.get()
- menu.strip()
- if not menu:
- tkMessageBox.showerror(title='Menu Item Error',
- message='No menu item specified',
- parent=self)
- self.entryMenu.focus_set()
- menuOk = False
- elif len(menu) > 30:
- tkMessageBox.showerror(title='Menu Item Error',
- message='Menu item too long:'
- '\nLimit 30 characters.',
- parent=self)
- self.entryMenu.focus_set()
- menuOk = False
- return menuOk
-
- def PathOk(self):
- "Simple validity check for menu file path"
- pathOk = True
- path = self.path.get()
- path.strip()
- if not path: #no path specified
- tkMessageBox.showerror(title='File Path Error',
- message='No help file path specified.',
- parent=self)
- self.entryPath.focus_set()
- pathOk = False
- elif path.startswith('www.') or path.startswith('http'):
- pathOk = True
- elif not os.path.exists(path):
- tkMessageBox.showerror(title='File Path Error',
- message='Help file path does not exist.',
- parent=self)
- self.entryPath.focus_set()
- pathOk = False
- return pathOk
-
- def Ok(self, event=None):
- if self.MenuOk() and self.PathOk():
- self.result = (self.menu.get().strip(),
- self.path.get().strip())
- self.destroy()
-
- def Cancel(self, event=None):
- self.result = None
- self.destroy()
-
-if __name__ == '__main__':
- #test the dialog
- root = Tk()
- def run():
- keySeq = ''
- dlg = GetHelpSourceDialog(root, 'Get Help Source')
- print dlg.result
- Button(root,text='Dialog', command=run).pack()
- root.mainloop()
diff --git a/Tools/idle/configSectionNameDialog.py b/Tools/idle/configSectionNameDialog.py
deleted file mode 100644
index 4f1b002..0000000
--- a/Tools/idle/configSectionNameDialog.py
+++ /dev/null
@@ -1,97 +0,0 @@
-"""
-Dialog that allows user to specify a new config file section name.
-Used to get new highlight theme and keybinding set names.
-"""
-from Tkinter import *
-import tkMessageBox
-
-class GetCfgSectionNameDialog(Toplevel):
- def __init__(self,parent,title,message,usedNames):
- """
- message - string, informational message to display
- usedNames - list, list of names already in use for validity check
- """
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.resizable(height=FALSE,width=FALSE)
- self.title(title)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Cancel)
- self.parent = parent
- self.message=message
- self.usedNames=usedNames
- self.result=''
- self.CreateWidgets()
- self.withdraw() #hide while setting geometry
- self.update_idletasks()
- #needs to be done here so that the winfo_reqwidth is valid
- self.messageInfo.config(width=self.frameMain.winfo_reqwidth())
- self.geometry("+%d+%d" %
- ((parent.winfo_rootx()+((parent.winfo_width()/2)
- -(self.winfo_reqwidth()/2)),
- parent.winfo_rooty()+((parent.winfo_height()/2)
- -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent
- self.deiconify() #geometry set, unhide
- self.wait_window()
-
- def CreateWidgets(self):
- self.name=StringVar(self)
- self.fontSize=StringVar(self)
- self.frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
- self.frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
- self.messageInfo=Message(self.frameMain,anchor=W,justify=LEFT,padx=5,pady=5,
- text=self.message)#,aspect=200)
- entryName=Entry(self.frameMain,textvariable=self.name,width=30)
- entryName.focus_set()
- self.messageInfo.pack(padx=5,pady=5)#,expand=TRUE,fill=BOTH)
- entryName.pack(padx=5,pady=5)
- frameButtons=Frame(self)
- frameButtons.pack(side=BOTTOM,fill=X)
- self.buttonOk = Button(frameButtons,text='Ok',
- width=8,command=self.Ok)
- self.buttonOk.grid(row=0,column=0,padx=5,pady=5)
- self.buttonCancel = Button(frameButtons,text='Cancel',
- width=8,command=self.Cancel)
- self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
-
- def NameOk(self):
- #simple validity check for a sensible
- #ConfigParser file section name
- nameOk=1
- name=self.name.get()
- name.strip()
- if not name: #no name specified
- tkMessageBox.showerror(title='Name Error',
- message='No name specified.', parent=self)
- nameOk=0
- elif len(name)>30: #name too long
- tkMessageBox.showerror(title='Name Error',
- message='Name too long. It should be no more than '+
- '30 characters.', parent=self)
- nameOk=0
- elif name in self.usedNames:
- tkMessageBox.showerror(title='Name Error',
- message='This name is already in use.', parent=self)
- nameOk=0
- return nameOk
-
- def Ok(self, event=None):
- if self.NameOk():
- self.result=self.name.get().strip()
- self.destroy()
-
- def Cancel(self, event=None):
- self.result=''
- self.destroy()
-
-if __name__ == '__main__':
- #test the dialog
- root=Tk()
- def run():
- keySeq=''
- dlg=GetCfgSectionNameDialog(root,'Get Name',
- 'The information here should need to be word wrapped. Test.')
- print dlg.result
- Button(root,text='Dialog',command=run).pack()
- root.mainloop()
diff --git a/Tools/idle/dynOptionMenuWidget.py b/Tools/idle/dynOptionMenuWidget.py
deleted file mode 100644
index e81f7ba..0000000
--- a/Tools/idle/dynOptionMenuWidget.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""
-OptionMenu widget modified to allow dynamic menu reconfiguration
-and setting of highlightthickness
-"""
-from Tkinter import OptionMenu
-from Tkinter import _setit
-import copy
-
-class DynOptionMenu(OptionMenu):
- """
- unlike OptionMenu, our kwargs can include highlightthickness
- """
- def __init__(self, master, variable, value, *values, **kwargs):
- #get a copy of kwargs before OptionMenu.__init__ munges them
- kwargsCopy=copy.copy(kwargs)
- if 'highlightthickness' in kwargs.keys():
- del(kwargs['highlightthickness'])
- OptionMenu.__init__(self, master, variable, value, *values, **kwargs)
- self.config(highlightthickness=kwargsCopy.get('highlightthickness'))
- #self.menu=self['menu']
- self.variable=variable
- self.command=kwargs.get('command')
-
- def SetMenu(self,valueList,value=None):
- """
- clear and reload the menu with a new set of options.
- valueList - list of new options
- value - initial value to set the optionmenu's menubutton to
- """
- self['menu'].delete(0,'end')
- for item in valueList:
- self['menu'].add_command(label=item,
- command=_setit(self.variable,item,self.command))
- if value:
- self.variable.set(value)
diff --git a/Tools/idle/interruptmodule.c b/Tools/idle/interruptmodule.c
deleted file mode 100644
index 8e18d5a..0000000
--- a/Tools/idle/interruptmodule.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/***********************************************************************
- * interruptmodule.c
- *
- * Python extension implementing the interrupt module.
- *
- **********************************************************************/
-
-#include "Python.h"
-
-#ifndef PyDoc_STR
-#define PyDoc_VAR(name) static char name[]
-#define PyDoc_STR(str) str
-#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
-#endif
-
-/* module documentation */
-
-PyDoc_STRVAR(module_doc,
-"Provide a way to interrupt the main thread from a subthread.\n\n\
-In threaded Python code the KeyboardInterrupt is always directed to\n\
-the thread which raised it. This extension provides a method,\n\
-interrupt_main, which a subthread can use to raise a KeyboardInterrupt\n\
-in the main thread.");
-
-/* module functions */
-
-static PyObject *
-setinterrupt(PyObject * self, PyObject * args)
-{
- PyErr_SetInterrupt();
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-/* registration table */
-
-static struct PyMethodDef methods[] = {
- {"interrupt_main", setinterrupt, METH_VARARGS,
- PyDoc_STR("Interrupt the main thread")},
- {NULL, NULL}
-};
-
-/* module initialization */
-
-void
-initinterrupt(void)
-{
- (void) Py_InitModule3("interrupt", methods, module_doc);
-}
diff --git a/Tools/idle/keybindingDialog.py b/Tools/idle/keybindingDialog.py
deleted file mode 100644
index df024e7..0000000
--- a/Tools/idle/keybindingDialog.py
+++ /dev/null
@@ -1,262 +0,0 @@
-"""
-dialog for building tkinter accelerator key bindings
-"""
-from Tkinter import *
-import tkMessageBox
-import string, os
-
-class GetKeysDialog(Toplevel):
- def __init__(self,parent,title,action,currentKeySequences):
- """
- action - string, the name of the virtual event these keys will be
- mapped to
- currentKeys - list, a list of all key sequence lists currently mapped
- to virtual events, for overlap checking
- """
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.resizable(height=FALSE,width=FALSE)
- self.title(title)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Cancel)
- self.parent = parent
- self.action=action
- self.currentKeySequences=currentKeySequences
- self.result=''
- self.keyString=StringVar(self)
- self.keyString.set('')
- self.SetModifiersForPlatform()
- self.modifier_vars = []
- for modifier in self.modifiers:
- variable = StringVar(self)
- variable.set('')
- self.modifier_vars.append(variable)
- self.CreateWidgets()
- self.LoadFinalKeyList()
- self.withdraw() #hide while setting geometry
- self.update_idletasks()
- self.geometry("+%d+%d" %
- ((parent.winfo_rootx()+((parent.winfo_width()/2)
- -(self.winfo_reqwidth()/2)),
- parent.winfo_rooty()+((parent.winfo_height()/2)
- -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent
- self.deiconify() #geometry set, unhide
- self.wait_window()
-
- def CreateWidgets(self):
- frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
- frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
- frameButtons=Frame(self)
- frameButtons.pack(side=BOTTOM,fill=X)
- self.buttonOk = Button(frameButtons,text='Ok',
- width=8,command=self.Ok)
- self.buttonOk.grid(row=0,column=0,padx=5,pady=5)
- self.buttonCancel = Button(frameButtons,text='Cancel',
- width=8,command=self.Cancel)
- self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
- self.frameKeySeqBasic = Frame(frameMain)
- self.frameKeySeqAdvanced = Frame(frameMain)
- self.frameControlsBasic = Frame(frameMain)
- self.frameHelpAdvanced = Frame(frameMain)
- self.frameKeySeqAdvanced.grid(row=0,column=0,sticky=NSEW,padx=5,pady=5)
- self.frameKeySeqBasic.grid(row=0,column=0,sticky=NSEW,padx=5,pady=5)
- self.frameKeySeqBasic.lift()
- self.frameHelpAdvanced.grid(row=1,column=0,sticky=NSEW,padx=5)
- self.frameControlsBasic.grid(row=1,column=0,sticky=NSEW,padx=5)
- self.frameControlsBasic.lift()
- self.buttonLevel = Button(frameMain,command=self.ToggleLevel,
- text='Advanced Key Binding Entry >>')
- self.buttonLevel.grid(row=2,column=0,stick=EW,padx=5,pady=5)
- labelTitleBasic = Label(self.frameKeySeqBasic,
- text="New keys for '"+self.action+"' :")
- labelTitleBasic.pack(anchor=W)
- labelKeysBasic = Label(self.frameKeySeqBasic,justify=LEFT,
- textvariable=self.keyString,relief=GROOVE,borderwidth=2)
- labelKeysBasic.pack(ipadx=5,ipady=5,fill=X)
- self.modifier_checkbuttons = {}
- column = 0
- for modifier, variable in zip(self.modifiers, self.modifier_vars):
- label = self.modifier_label.get(modifier, modifier)
- check=Checkbutton(self.frameControlsBasic,
- command=self.BuildKeyString,
- text=label,variable=variable,onvalue=modifier,offvalue='')
- check.grid(row=0,column=column,padx=2,sticky=W)
- self.modifier_checkbuttons[modifier] = check
- column += 1
- labelFnAdvice=Label(self.frameControlsBasic,justify=LEFT,
- text="Select the desired modifier\n"+
- "keys above, and final key\n"+
- "from the list on the right.")
- labelFnAdvice.grid(row=1,column=0,columnspan=4,padx=2,sticky=W)
- self.listKeysFinal=Listbox(self.frameControlsBasic,width=15,height=10,
- selectmode=SINGLE)
- self.listKeysFinal.bind('<ButtonRelease-1>',self.FinalKeySelected)
- self.listKeysFinal.grid(row=0,column=4,rowspan=4,sticky=NS)
- scrollKeysFinal=Scrollbar(self.frameControlsBasic,orient=VERTICAL,
- command=self.listKeysFinal.yview)
- self.listKeysFinal.config(yscrollcommand=scrollKeysFinal.set)
- scrollKeysFinal.grid(row=0,column=5,rowspan=4,sticky=NS)
- self.buttonClear=Button(self.frameControlsBasic,
- text='Clear Keys',command=self.ClearKeySeq)
- self.buttonClear.grid(row=2,column=0,columnspan=4)
- labelTitleAdvanced = Label(self.frameKeySeqAdvanced,justify=LEFT,
- text="Enter new binding(s) for '"+self.action+"' :\n"+
- "(will not be checked for validity)")
- labelTitleAdvanced.pack(anchor=W)
- self.entryKeysAdvanced=Entry(self.frameKeySeqAdvanced,
- textvariable=self.keyString)
- self.entryKeysAdvanced.pack(fill=X)
- labelHelpAdvanced=Label(self.frameHelpAdvanced,justify=LEFT,
- text="Key bindings are specified using tkinter key id's as\n"+
- "in these samples: <Control-f>, <Shift-F2>, <F12>,\n"
- "<Control-space>, <Meta-less>, <Control-Alt-Shift-x>.\n\n"+
- "'Emacs style' multi-keystroke bindings are specified as\n"+
- "follows: <Control-x><Control-y> or <Meta-f><Meta-g>.\n\n"+
- "Multiple separate bindings for one action should be\n"+
- "separated by a space, eg., <Alt-v> <Meta-v>." )
- labelHelpAdvanced.grid(row=0,column=0,sticky=NSEW)
-
- def SetModifiersForPlatform(self):
- """Determine list of names of key modifiers for this platform.
-
- The names are used to build Tk bindings -- it doesn't matter if the
- keyboard has these keys, it matters if Tk understands them. The
- order is also important: key binding equality depends on it, so
- config-keys.def must use the same ordering.
- """
- import sys
- if sys.platform == 'darwin' and sys.executable.count('.app'):
- self.modifiers = ['Shift', 'Control', 'Option', 'Command']
- else:
- self.modifiers = ['Control', 'Alt', 'Shift']
- self.modifier_label = {'Control': 'Ctrl'}
-
- def ToggleLevel(self):
- if self.buttonLevel.cget('text')[:8]=='Advanced':
- self.ClearKeySeq()
- self.buttonLevel.config(text='<< Basic Key Binding Entry')
- self.frameKeySeqAdvanced.lift()
- self.frameHelpAdvanced.lift()
- self.entryKeysAdvanced.focus_set()
- else:
- self.ClearKeySeq()
- self.buttonLevel.config(text='Advanced Key Binding Entry >>')
- self.frameKeySeqBasic.lift()
- self.frameControlsBasic.lift()
-
- def FinalKeySelected(self,event):
- self.BuildKeyString()
-
- def BuildKeyString(self):
- keyList=[]
- modifiers=self.GetModifiers()
- finalKey=self.listKeysFinal.get(ANCHOR)
- if modifiers: modifiers[0]='<'+modifiers[0]
- keyList=keyList+modifiers
- if finalKey:
- if (not modifiers) and (finalKey not
- in self.alphanumKeys+self.punctuationKeys):
- finalKey='<'+self.TranslateKey(finalKey)
- else:
- finalKey=self.TranslateKey(finalKey)
- keyList.append(finalKey+'>')
- keyStr=string.join(keyList,'-')
- self.keyString.set(keyStr)
-
- def GetModifiers(self):
- modList = [variable.get() for variable in self.modifier_vars]
- return filter(None, modList)
-
- def ClearKeySeq(self):
- self.listKeysFinal.select_clear(0,END)
- self.listKeysFinal.yview(MOVETO, '0.0')
- for variable in self.modifier_vars:
- variable.set('')
- self.keyString.set('')
-
- def LoadFinalKeyList(self):
- #these tuples are also available for use in validity checks
- self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9',
- 'F10','F11','F12')
- self.alphanumKeys=tuple(string.ascii_lowercase+string.digits)
- self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,.<>/?')
- self.whitespaceKeys=('Tab','Space','Return')
- self.editKeys=('BackSpace','Delete','Insert')
- self.moveKeys=('Home','End','Page Up','Page Down','Left Arrow',
- 'Right Arrow','Up Arrow','Down Arrow')
- #make a tuple of most of the useful common 'final' keys
- keys=(self.alphanumKeys+self.punctuationKeys+self.functionKeys+
- self.whitespaceKeys+self.editKeys+self.moveKeys)
- apply(self.listKeysFinal.insert,
- (END,)+keys)
-
- def TranslateKey(self,key):
- #translate from key list value to tkinter key-id
- translateDict={'~':'asciitilde','!':'exclam','@':'at','#':'numbersign',
- '%':'percent','^':'asciicircum','&':'ampersand','*':'asterisk',
- '(':'parenleft',')':'parenright','_':'underscore','-':'minus',
- '+':'plus','=':'equal','{':'braceleft','}':'braceright',
- '[':'bracketleft',']':'bracketright','|':'bar',';':'semicolon',
- ':':'colon',',':'comma','.':'period','<':'less','>':'greater',
- '/':'slash','?':'question','Page Up':'Prior','Page Down':'Next',
- 'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up',
- 'Down Arrow': 'Down'}
- if key in translateDict.keys():
- key=translateDict[key]
- key='Key-'+key
- return key
-
- def Ok(self, event=None):
- if self.KeysOk():
- self.result=self.keyString.get()
- self.destroy()
-
- def Cancel(self, event=None):
- self.result=''
- self.destroy()
-
- def KeysOk(self):
- #simple validity check
- keysOk=1
- keys=self.keyString.get()
- keys.strip()
- finalKey=self.listKeysFinal.get(ANCHOR)
- modifiers=self.GetModifiers()
- keySequence=keys.split()#make into a key sequence list for overlap check
- if not keys: #no keys specified
- tkMessageBox.showerror(title='Key Sequence Error',
- message='No keys specified.')
- keysOk=0
- elif not keys.endswith('>'): #no final key specified
- tkMessageBox.showerror(title='Key Sequence Error',
- message='No final key specified.')
- keysOk=0
- elif (not modifiers) and (finalKey in
- self.alphanumKeys+self.punctuationKeys):
- #modifier required
- tkMessageBox.showerror(title='Key Sequence Error',
- message='No modifier key(s) specified.')
- keysOk=0
- elif (modifiers==['Shift']) and (finalKey not
- in self.functionKeys+('Tab',)):
- #shift alone is only a useful modifier with a function key
- tkMessageBox.showerror(title='Key Sequence Error',
- message='Shift alone is not a useful modifier '+
- 'when used with this final key key.')
- keysOk=0
- elif keySequence in self.currentKeySequences: #keys combo already in use
- tkMessageBox.showerror(title='Key Sequence Error',
- message='This key combination is already in use.')
- keysOk=0
- return keysOk
-
-if __name__ == '__main__':
- #test the dialog
- root=Tk()
- def run():
- keySeq=''
- dlg=GetKeysDialog(root,'Get Keys','find-again',[])
- print dlg.result
- Button(root,text='Dialog',command=run).pack()
- root.mainloop()
diff --git a/Tools/idle/macosx_main.py b/Tools/idle/macosx_main.py
deleted file mode 100644
index bc91a0b..0000000
--- a/Tools/idle/macosx_main.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env pythonw
-# IDLE.app
-#
-# Installation:
-# see the install_IDLE target in python/dist/src/Mac/OSX/Makefile
-#
-# Usage:
-#
-# 1. Double clicking IDLE icon will open IDLE.
-# 2. Dropping file on IDLE icon will open that file in IDLE.
-# 3. Launch from command line with files with this command-line:
-#
-# /Applications/Python/IDLE.app/Contents/MacOS/python file1 file2 file3
-#
-#
-
-# Add IDLE.app/Contents/Resources/idlelib to path.
-# __file__ refers to this file when it is used as a module, sys.argv[0]
-# refers to this file when it is used as a script (pythonw macosx_main.py)
-import sys
-
-from os.path import split, join, isdir
-try:
- __file__
-except NameError:
- __file__ = sys.argv[0]
-idlelib = join(split(__file__)[0], 'idlelib')
-if isdir(idlelib):
- sys.path.append(idlelib)
-
-# see if we are being asked to execute the subprocess code
-if '-p' in sys.argv:
- # run expects only the port number in sys.argv
- sys.argv.remove('-p')
-
- # this module will become the namespace used by the interactive
- # interpreter; remove all variables we have defined.
- del sys, __file__, split, join, isdir, idlelib
- __import__('run').main()
-else:
- # Load idlelib/idle.py which starts the application.
- import idle
diff --git a/Tools/idle/rpc.py b/Tools/idle/rpc.py
deleted file mode 100644
index 15946a6..0000000
--- a/Tools/idle/rpc.py
+++ /dev/null
@@ -1,580 +0,0 @@
-"""RPC Implemention, originally written for the Python Idle IDE
-
-For security reasons, GvR requested that Idle's Python execution server process
-connect to the Idle process, which listens for the connection. Since Idle has
-has only one client per server, this was not a limitation.
-
- +---------------------------------+ +-------------+
- | SocketServer.BaseRequestHandler | | SocketIO |
- +---------------------------------+ +-------------+
- ^ | register() |
- | | unregister()|
- | +-------------+
- | ^ ^
- | | |
- | + -------------------+ |
- | | |
- +-------------------------+ +-----------------+
- | RPCHandler | | RPCClient |
- | [attribute of RPCServer]| | |
- +-------------------------+ +-----------------+
-
-The RPCServer handler class is expected to provide register/unregister methods.
-RPCHandler inherits the mix-in class SocketIO, which provides these methods.
-
-See the Idle run.main() docstring for further information on how this was
-accomplished in Idle.
-
-"""
-
-import sys
-import socket
-import select
-import SocketServer
-import struct
-import cPickle as pickle
-import threading
-import traceback
-import copy_reg
-import types
-import marshal
-
-def unpickle_code(ms):
- co = marshal.loads(ms)
- assert isinstance(co, types.CodeType)
- return co
-
-def pickle_code(co):
- assert isinstance(co, types.CodeType)
- ms = marshal.dumps(co)
- return unpickle_code, (ms,)
-
-# XXX KBK 24Aug02 function pickling capability not used in Idle
-# def unpickle_function(ms):
-# return ms
-
-# def pickle_function(fn):
-# assert isinstance(fn, type.FunctionType)
-# return `fn`
-
-copy_reg.pickle(types.CodeType, pickle_code, unpickle_code)
-# copy_reg.pickle(types.FunctionType, pickle_function, unpickle_function)
-
-BUFSIZE = 8*1024
-
-class RPCServer(SocketServer.TCPServer):
-
- def __init__(self, addr, handlerclass=None):
- if handlerclass is None:
- handlerclass = RPCHandler
- SocketServer.TCPServer.__init__(self, addr, handlerclass)
-
- def server_bind(self):
- "Override TCPServer method, no bind() phase for connecting entity"
- pass
-
- def server_activate(self):
- """Override TCPServer method, connect() instead of listen()
-
- Due to the reversed connection, self.server_address is actually the
- address of the Idle Client to which we are connecting.
-
- """
- self.socket.connect(self.server_address)
-
- def get_request(self):
- "Override TCPServer method, return already connected socket"
- return self.socket, self.server_address
-
- def handle_error(self, request, client_address):
- """Override TCPServer method
-
- Error message goes to __stderr__. No error message if exiting
- normally or socket raised EOF. Other exceptions not handled in
- server code will cause os._exit.
-
- """
- try:
- raise
- except SystemExit:
- raise
- except EOFError:
- pass
- except:
- erf = sys.__stderr__
- print>>erf, '\n' + '-'*40
- print>>erf, 'Unhandled server exception!'
- print>>erf, 'Thread: %s' % threading.currentThread().getName()
- print>>erf, 'Client Address: ', client_address
- print>>erf, 'Request: ', repr(request)
- traceback.print_exc(file=erf)
- print>>erf, '\n*** Unrecoverable, server exiting!'
- print>>erf, '-'*40
- import os
- os._exit(0)
-
-
-objecttable = {}
-
-class SocketIO:
-
- nextseq = 0
-
- def __init__(self, sock, objtable=None, debugging=None):
- self.mainthread = threading.currentThread()
- if debugging is not None:
- self.debugging = debugging
- self.sock = sock
- if objtable is None:
- objtable = objecttable
- self.objtable = objtable
- self.cvar = threading.Condition()
- self.responses = {}
- self.cvars = {}
- self.interrupted = False
-
- def close(self):
- sock = self.sock
- self.sock = None
- if sock is not None:
- sock.close()
-
- def debug(self, *args):
- if not self.debugging:
- return
- s = self.location + " " + str(threading.currentThread().getName())
- for a in args:
- s = s + " " + str(a)
- print>>sys.__stderr__, s
-
- def register(self, oid, object):
- self.objtable[oid] = object
-
- def unregister(self, oid):
- try:
- del self.objtable[oid]
- except KeyError:
- pass
-
- def localcall(self, request):
- self.debug("localcall:", request)
- try:
- how, (oid, methodname, args, kwargs) = request
- except TypeError:
- return ("ERROR", "Bad request format")
- assert how == "call"
- if not self.objtable.has_key(oid):
- return ("ERROR", "Unknown object id: %s" % `oid`)
- obj = self.objtable[oid]
- if methodname == "__methods__":
- methods = {}
- _getmethods(obj, methods)
- return ("OK", methods)
- if methodname == "__attributes__":
- attributes = {}
- _getattributes(obj, attributes)
- return ("OK", attributes)
- if not hasattr(obj, methodname):
- return ("ERROR", "Unsupported method name: %s" % `methodname`)
- method = getattr(obj, methodname)
- try:
- ret = method(*args, **kwargs)
- if isinstance(ret, RemoteObject):
- ret = remoteref(ret)
- return ("OK", ret)
- except SystemExit:
- raise
- except socket.error:
- pass
- except:
- self.debug("localcall:EXCEPTION")
- traceback.print_exc(file=sys.__stderr__)
- return ("EXCEPTION", None)
-
- def remotecall(self, oid, methodname, args, kwargs):
- self.debug("remotecall:asynccall: ", oid, methodname)
- # XXX KBK 06Feb03 self.interrupted logic may not be necessary if
- # subprocess is threaded.
- if self.interrupted:
- self.interrupted = False
- raise KeyboardInterrupt
- seq = self.asynccall(oid, methodname, args, kwargs)
- return self.asyncreturn(seq)
-
- def asynccall(self, oid, methodname, args, kwargs):
- request = ("call", (oid, methodname, args, kwargs))
- seq = self.newseq()
- self.debug(("asynccall:%d:" % seq), oid, methodname, args, kwargs)
- self.putmessage((seq, request))
- return seq
-
- def asyncreturn(self, seq):
- self.debug("asyncreturn:%d:call getresponse(): " % seq)
- response = self.getresponse(seq, wait=None)
- self.debug(("asyncreturn:%d:response: " % seq), response)
- return self.decoderesponse(response)
-
- def decoderesponse(self, response):
- how, what = response
- if how == "OK":
- return what
- if how == "EXCEPTION":
- self.debug("decoderesponse: EXCEPTION")
- return None
- if how == "ERROR":
- self.debug("decoderesponse: Internal ERROR:", what)
- raise RuntimeError, what
- raise SystemError, (how, what)
-
- def mainloop(self):
- """Listen on socket until I/O not ready or EOF
-
- Main thread pollresponse() will loop looking for seq number None, which
- never comes, and exit on EOFError.
-
- """
- try:
- self.getresponse(myseq=None, wait=None)
- except EOFError:
- pass
-
- def getresponse(self, myseq, wait):
- response = self._getresponse(myseq, wait)
- if response is not None:
- how, what = response
- if how == "OK":
- response = how, self._proxify(what)
- return response
-
- def _proxify(self, obj):
- if isinstance(obj, RemoteProxy):
- return RPCProxy(self, obj.oid)
- if isinstance(obj, types.ListType):
- return map(self._proxify, obj)
- # XXX Check for other types -- not currently needed
- return obj
-
- def _getresponse(self, myseq, wait):
- self.debug("_getresponse:myseq:", myseq)
- if threading.currentThread() is self.mainthread:
- # Main thread: does all reading of requests or responses
- # Loop here, blocking each time until socket is ready.
- while 1:
- response = self.pollresponse(myseq, wait)
- if response is not None:
- return response
- else:
- # Auxiliary thread: wait for notification from main thread
- self.cvar.acquire()
- self.cvars[myseq] = self.cvar
- while not self.responses.has_key(myseq):
- self.cvar.wait()
- response = self.responses[myseq]
- del self.responses[myseq]
- del self.cvars[myseq]
- self.cvar.release()
- return response
-
- def newseq(self):
- self.nextseq = seq = self.nextseq + 2
- return seq
-
- def putmessage(self, message):
- self.debug("putmessage:%d:" % message[0])
- try:
- s = pickle.dumps(message)
- except:
- print >>sys.__stderr__, "Cannot pickle:", `message`
- raise
- s = struct.pack("<i", len(s)) + s
- while len(s) > 0:
- try:
- n = self.sock.send(s)
- except AttributeError:
- # socket was closed
- raise IOError
- else:
- s = s[n:]
-
- def ioready(self, wait=0.0):
- r, w, x = select.select([self.sock.fileno()], [], [], wait)
- return len(r)
-
- buffer = ""
- bufneed = 4
- bufstate = 0 # meaning: 0 => reading count; 1 => reading data
-
- def pollpacket(self, wait=0.0):
- self._stage0()
- if len(self.buffer) < self.bufneed:
- if not self.ioready(wait):
- return None
- try:
- s = self.sock.recv(BUFSIZE)
- except socket.error:
- raise EOFError
- if len(s) == 0:
- raise EOFError
- self.buffer += s
- self._stage0()
- return self._stage1()
-
- def _stage0(self):
- if self.bufstate == 0 and len(self.buffer) >= 4:
- s = self.buffer[:4]
- self.buffer = self.buffer[4:]
- self.bufneed = struct.unpack("<i", s)[0]
- self.bufstate = 1
-
- def _stage1(self):
- if self.bufstate == 1 and len(self.buffer) >= self.bufneed:
- packet = self.buffer[:self.bufneed]
- self.buffer = self.buffer[self.bufneed:]
- self.bufneed = 4
- self.bufstate = 0
- return packet
-
- def pollmessage(self, wait=0.0):
- packet = self.pollpacket(wait)
- if packet is None:
- return None
- try:
- message = pickle.loads(packet)
- except:
- print >>sys.__stderr__, "-----------------------"
- print >>sys.__stderr__, "cannot unpickle packet:", `packet`
- traceback.print_stack(file=sys.__stderr__)
- print >>sys.__stderr__, "-----------------------"
- raise
- return message
-
- def pollresponse(self, myseq, wait=0.0):
- """Handle messages received on the socket.
-
- Some messages received may be asynchronous 'call' commands, and
- some may be responses intended for other threads.
-
- Loop until message with myseq sequence number is received. Save others
- in self.responses and notify the owning thread, except that 'call'
- commands are handed off to localcall() and the response sent back
- across the link with the appropriate sequence number.
-
- """
- while 1:
- message = self.pollmessage(wait)
- if message is None: # socket not ready
- return None
- #wait = 0.0 # poll on subsequent passes instead of blocking
- seq, resq = message
- self.debug("pollresponse:%d:myseq:%s" % (seq, myseq))
- if resq[0] == "call":
- self.debug("pollresponse:%d:localcall:call:" % seq)
- response = self.localcall(resq)
- self.debug("pollresponse:%d:localcall:response:%s"
- % (seq, response))
- self.putmessage((seq, response))
- continue
- elif seq == myseq:
- return resq
- else:
- self.cvar.acquire()
- cv = self.cvars.get(seq)
- # response involving unknown sequence number is discarded,
- # probably intended for prior incarnation
- if cv is not None:
- self.responses[seq] = resq
- cv.notify()
- self.cvar.release()
- continue
-
-#----------------- end class SocketIO --------------------
-
-class RemoteObject:
- # Token mix-in class
- pass
-
-def remoteref(obj):
- oid = id(obj)
- objecttable[oid] = obj
- return RemoteProxy(oid)
-
-class RemoteProxy:
-
- def __init__(self, oid):
- self.oid = oid
-
-class RPCHandler(SocketServer.BaseRequestHandler, SocketIO):
-
- debugging = False
- location = "#S" # Server
-
- def __init__(self, sock, addr, svr):
- svr.current_handler = self ## cgt xxx
- SocketIO.__init__(self, sock)
- SocketServer.BaseRequestHandler.__init__(self, sock, addr, svr)
-
- def handle(self):
- "handle() method required by SocketServer"
- self.mainloop()
-
- def get_remote_proxy(self, oid):
- return RPCProxy(self, oid)
-
-class RPCClient(SocketIO):
-
- debugging = False
- location = "#C" # Client
-
- nextseq = 1 # Requests coming from the client are odd numbered
-
- def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM):
- self.listening_sock = socket.socket(family, type)
- self.listening_sock.setsockopt(socket.SOL_SOCKET,
- socket.SO_REUSEADDR, 1)
- self.listening_sock.bind(address)
- self.listening_sock.listen(1)
-
- def accept(self):
- working_sock, address = self.listening_sock.accept()
- if self.debugging:
- print>>sys.__stderr__, "****** Connection request from ", address
- if address[0] == '127.0.0.1':
- SocketIO.__init__(self, working_sock)
- else:
- print>>sys.__stderr__, "** Invalid host: ", address
- raise socket.error
-
- def get_remote_proxy(self, oid):
- return RPCProxy(self, oid)
-
-class RPCProxy:
-
- __methods = None
- __attributes = None
-
- def __init__(self, sockio, oid):
- self.sockio = sockio
- self.oid = oid
-
- def __getattr__(self, name):
- if self.__methods is None:
- self.__getmethods()
- if self.__methods.get(name):
- return MethodProxy(self.sockio, self.oid, name)
- if self.__attributes is None:
- self.__getattributes()
- if not self.__attributes.has_key(name):
- raise AttributeError, name
- __getattr__.DebuggerStepThrough=1
-
- def __getattributes(self):
- self.__attributes = self.sockio.remotecall(self.oid,
- "__attributes__", (), {})
-
- def __getmethods(self):
- self.__methods = self.sockio.remotecall(self.oid,
- "__methods__", (), {})
-
-def _getmethods(obj, methods):
- # Helper to get a list of methods from an object
- # Adds names to dictionary argument 'methods'
- for name in dir(obj):
- attr = getattr(obj, name)
- if callable(attr):
- methods[name] = 1
- if type(obj) == types.InstanceType:
- _getmethods(obj.__class__, methods)
- if type(obj) == types.ClassType:
- for super in obj.__bases__:
- _getmethods(super, methods)
-
-def _getattributes(obj, attributes):
- for name in dir(obj):
- attr = getattr(obj, name)
- if not callable(attr):
- attributes[name] = 1
-
-class MethodProxy:
-
- def __init__(self, sockio, oid, name):
- self.sockio = sockio
- self.oid = oid
- self.name = name
-
- def __call__(self, *args, **kwargs):
- value = self.sockio.remotecall(self.oid, self.name, args, kwargs)
- return value
-
-#
-# Self Test
-#
-
-def testServer(addr):
- # XXX 25 Jul 02 KBK needs update to use rpc.py register/unregister methods
- class RemotePerson:
- def __init__(self,name):
- self.name = name
- def greet(self, name):
- print "(someone called greet)"
- print "Hello %s, I am %s." % (name, self.name)
- print
- def getName(self):
- print "(someone called getName)"
- print
- return self.name
- def greet_this_guy(self, name):
- print "(someone called greet_this_guy)"
- print "About to greet %s ..." % name
- remote_guy = self.server.current_handler.get_remote_proxy(name)
- remote_guy.greet("Thomas Edison")
- print "Done."
- print
-
- person = RemotePerson("Thomas Edison")
- svr = RPCServer(addr)
- svr.register('thomas', person)
- person.server = svr # only required if callbacks are used
-
- # svr.serve_forever()
- svr.handle_request() # process once only
-
-def testClient(addr):
- "demonstrates RPC Client"
- # XXX 25 Jul 02 KBK needs update to use rpc.py register/unregister methods
- import time
- clt=RPCClient(addr)
- thomas = clt.get_remote_proxy("thomas")
- print "The remote person's name is ..."
- print thomas.getName()
- # print clt.remotecall("thomas", "getName", (), {})
- print
- time.sleep(1)
- print "Getting remote thomas to say hi..."
- thomas.greet("Alexander Bell")
- #clt.remotecall("thomas","greet",("Alexander Bell",), {})
- print "Done."
- print
- time.sleep(2)
- # demonstrates remote server calling local instance
- class LocalPerson:
- def __init__(self,name):
- self.name = name
- def greet(self, name):
- print "You've greeted me!"
- def getName(self):
- return self.name
- person = LocalPerson("Alexander Bell")
- clt.register("alexander",person)
- thomas.greet_this_guy("alexander")
- # clt.remotecall("thomas","greet_this_guy",("alexander",), {})
-
-def test():
- addr=("localhost",8833)
- if len(sys.argv) == 2:
- if sys.argv[1]=='-server':
- testServer(addr)
- return
- testClient(addr)
-
-if __name__ == '__main__':
- test()
diff --git a/Tools/idle/run.py b/Tools/idle/run.py
deleted file mode 100644
index 497cbbd..0000000
--- a/Tools/idle/run.py
+++ /dev/null
@@ -1,216 +0,0 @@
-import sys
-import time
-import socket
-import traceback
-import threading
-import Queue
-
-import boolcheck
-
-import CallTips
-import RemoteDebugger
-import RemoteObjectBrowser
-import StackViewer
-import rpc
-import interrupt
-
-import __main__
-
-# Thread shared globals: Establish a queue between a subthread (which handles
-# the socket) and the main thread (which runs user code), plus global
-# completion and exit flags:
-
-server = None # RPCServer instance
-queue = Queue.Queue(0)
-execution_finished = False
-exit_requested = False
-
-
-def main():
- """Start the Python execution server in a subprocess
-
- In the Python subprocess, RPCServer is instantiated with handlerclass
- MyHandler, which inherits register/unregister methods from RPCHandler via
- the mix-in class SocketIO.
-
- When the RPCServer 'server' is instantiated, the TCPServer initialization
- creates an instance of run.MyHandler and calls its handle() method.
- handle() instantiates a run.Executive object, passing it a reference to the
- MyHandler object. That reference is saved as attribute rpchandler of the
- Executive instance. The Executive methods have access to the reference and
- can pass it on to entities that they command
- (e.g. RemoteDebugger.Debugger.start_debugger()). The latter, in turn, can
- call MyHandler(SocketIO) register/unregister methods via the reference to
- register and unregister themselves.
-
- """
- global queue, execution_finished, exit_requested
-
- port = 8833
- if sys.argv[1:]:
- port = int(sys.argv[1])
- sys.argv[:] = [""]
- sockthread = threading.Thread(target=manage_socket,
- name='SockThread',
- args=(('localhost', port),))
- sockthread.setDaemon(True)
- sockthread.start()
- while 1:
- try:
- if exit_requested:
- sys.exit()
- # XXX KBK 22Mar03 eventually check queue here!
- pass
- time.sleep(0.05)
- except KeyboardInterrupt:
- ##execution_finished = True
- continue
-
-def manage_socket(address):
- global server, exit_requested
-
- for i in range(6):
- time.sleep(i)
- try:
- server = rpc.RPCServer(address, MyHandler)
- break
- except socket.error, err:
- if i < 3:
- print>>sys.__stderr__, ".. ",
- else:
- print>>sys.__stderr__,"\nPython subprocess socket error: "\
- + err[1] + ", retrying...."
- else:
- print>>sys.__stderr__, "\nConnection to Idle failed, exiting."
- exit_requested = True
- server.handle_request() # A single request only
-
-
-class MyHandler(rpc.RPCHandler):
-
- def handle(self):
- """Override base method"""
- executive = Executive(self)
- self.register("exec", executive)
- sys.stdin = self.get_remote_proxy("stdin")
- sys.stdout = self.get_remote_proxy("stdout")
- sys.stderr = self.get_remote_proxy("stderr")
- rpc.RPCHandler.getresponse(self, myseq=None, wait=0.5)
-
-
-class Executive:
-
- def __init__(self, rpchandler):
- self.rpchandler = rpchandler
- self.locals = __main__.__dict__
- self.calltip = CallTips.CallTips()
-
- def runcode(self, code):
- global queue, execution_finished
-
- execution_finished = False
- queue.put(code)
- # dequeue and run in subthread
- self.runcode_from_queue()
- while not execution_finished:
- time.sleep(0.05)
-
- def runcode_from_queue(self):
- global queue, execution_finished
-
- # poll until queue has code object, using threads, just block?
- while True:
- try:
- code = queue.get(0)
- break
- except Queue.Empty:
- time.sleep(0.05)
- try:
- exec code in self.locals
- except:
- self.flush_stdout()
- efile = sys.stderr
- typ, val, tb = info = sys.exc_info()
- sys.last_type, sys.last_value, sys.last_traceback = info
- tbe = traceback.extract_tb(tb)
- print >>efile, 'Traceback (most recent call last):'
- exclude = ("run.py", "rpc.py", "RemoteDebugger.py", "bdb.py")
- self.cleanup_traceback(tbe, exclude)
- traceback.print_list(tbe, file=efile)
- lines = traceback.format_exception_only(typ, val)
- for line in lines:
- print>>efile, line,
- execution_finished = True
- else:
- self.flush_stdout()
- execution_finished = True
-
- def flush_stdout(self):
- try:
- if sys.stdout.softspace:
- sys.stdout.softspace = 0
- sys.stdout.write("\n")
- except (AttributeError, EOFError):
- pass
-
- def cleanup_traceback(self, tb, exclude):
- "Remove excluded traces from beginning/end of tb; get cached lines"
- orig_tb = tb[:]
- while tb:
- for rpcfile in exclude:
- if tb[0][0].count(rpcfile):
- break # found an exclude, break for: and delete tb[0]
- else:
- break # no excludes, have left RPC code, break while:
- del tb[0]
- while tb:
- for rpcfile in exclude:
- if tb[-1][0].count(rpcfile):
- break
- else:
- break
- del tb[-1]
- if len(tb) == 0:
- # exception was in IDLE internals, don't prune!
- tb[:] = orig_tb[:]
- print>>sys.stderr, "** IDLE Internal Exception: "
- for i in range(len(tb)):
- fn, ln, nm, line = tb[i]
- if nm == '?':
- nm = "-toplevel-"
- if not line and fn.startswith("<pyshell#"):
- line = self.rpchandler.remotecall('linecache', 'getline',
- (fn, ln), {})
- tb[i] = fn, ln, nm, line
-
- def interrupt_the_server(self):
- self.rpchandler.interrupted = True
- ##print>>sys.__stderr__, "** Interrupt main!"
- interrupt.interrupt_main()
-
- def shutdown_the_server(self):
- global exit_requested
-
- exit_requested = True
-
- def start_the_debugger(self, gui_adap_oid):
- return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
-
- def stop_the_debugger(self, idb_adap_oid):
- "Unregister the Idb Adapter. Link objects and Idb then subject to GC"
- self.rpchandler.unregister(idb_adap_oid)
-
- def get_the_calltip(self, name):
- return self.calltip.fetch_tip(name)
-
- def stackviewer(self, flist_oid=None):
- if not hasattr(sys, "last_traceback"):
- return None
- flist = None
- if flist_oid is not None:
- flist = self.rpchandler.get_remote_proxy(flist_oid)
- tb = sys.last_traceback
- while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
- tb = tb.tb_next
- item = StackViewer.StackTreeItem(flist, tb)
- return RemoteObjectBrowser.remote_object_tree_item(item)
diff --git a/Tools/idle/setup.cfg b/Tools/idle/setup.cfg
deleted file mode 100644
index c4b5729..0000000
--- a/Tools/idle/setup.cfg
+++ /dev/null
@@ -1,4 +0,0 @@
-[bdist_rpm]
-release = 1
-packager = Kurt B. Kaiser <kbk@shore.net>
-
diff --git a/Tools/idle/tabpage.py b/Tools/idle/tabpage.py
deleted file mode 100644
index 12f8929..0000000
--- a/Tools/idle/tabpage.py
+++ /dev/null
@@ -1,113 +0,0 @@
-"""
-a couple of classes for implementing partial tabbed-page like behaviour
-"""
-
-from Tkinter import *
-
-class InvalidTabPage(Exception): pass
-class AlreadyExists(Exception): pass
-
-class PageTab(Frame):
- """
- a 'page tab' like framed button
- """
- def __init__(self,parent):
- Frame.__init__(self, parent,borderwidth=2,relief=RIDGE)
- self.button=Radiobutton(self,padx=5,pady=5,takefocus=FALSE,
- indicatoron=FALSE,highlightthickness=0,
- borderwidth=0,selectcolor=self.cget('bg'))
- self.button.pack()
-
-class TabPageSet(Frame):
- """
- a set of 'pages' with TabButtons for controlling their display
- """
- def __init__(self,parent,pageNames=[],**kw):
- """
- pageNames - a list of strings, each string will be the dictionary key
- to a page's data, and the name displayed on the page's tab. Should be
- specified in desired page order. The first page will be the default
- and first active page.
- """
- Frame.__init__(self, parent, kw)
- self.grid_location(0,0)
- self.columnconfigure(0,weight=1)
- self.rowconfigure(1,weight=1)
- self.tabBar=Frame(self)
- self.tabBar.grid(row=0,column=0,sticky=EW)
- self.activePage=StringVar(self)
- self.defaultPage=''
- self.pages={}
- for name in pageNames:
- self.AddPage(name)
-
- def ChangePage(self,pageName=None):
- if pageName:
- if pageName in self.pages.keys():
- self.activePage.set(pageName)
- else:
- raise InvalidTabPage, 'Invalid TabPage Name'
- ## pop up the active 'tab' only
- for page in self.pages.keys():
- self.pages[page]['tab'].config(relief=RIDGE)
- self.pages[self.GetActivePage()]['tab'].config(relief=RAISED)
- ## switch page
- self.pages[self.GetActivePage()]['page'].lift()
-
- def GetActivePage(self):
- return self.activePage.get()
-
- def AddPage(self,pageName):
- if pageName in self.pages.keys():
- raise AlreadyExists, 'TabPage Name Already Exists'
- self.pages[pageName]={'tab':PageTab(self.tabBar),
- 'page':Frame(self,borderwidth=2,relief=RAISED)}
- self.pages[pageName]['tab'].button.config(text=pageName,
- command=self.ChangePage,variable=self.activePage,
- value=pageName)
- self.pages[pageName]['tab'].pack(side=LEFT)
- self.pages[pageName]['page'].grid(row=1,column=0,sticky=NSEW)
- if len(self.pages)==1: # adding first page
- self.defaultPage=pageName
- self.activePage.set(self.defaultPage)
- self.ChangePage()
-
- def RemovePage(self,pageName):
- if not pageName in self.pages.keys():
- raise InvalidTabPage, 'Invalid TabPage Name'
- self.pages[pageName]['tab'].pack_forget()
- self.pages[pageName]['page'].grid_forget()
- self.pages[pageName]['tab'].destroy()
- self.pages[pageName]['page'].destroy()
- del(self.pages[pageName])
- # handle removing last remaining, or default, or active page
- if not self.pages: # removed last remaining page
- self.defaultPage=''
- return
- if pageName==self.defaultPage: # set a new default page
- self.defaultPage=\
- self.tabBar.winfo_children()[0].button.cget('text')
- if pageName==self.GetActivePage(): # set a new active page
- self.activePage.set(self.defaultPage)
- self.ChangePage()
-
-if __name__ == '__main__':
- #test dialog
- root=Tk()
- tabPage=TabPageSet(root,pageNames=['Foobar','Baz'])
- tabPage.pack(expand=TRUE,fill=BOTH)
- Label(tabPage.pages['Foobar']['page'],text='Foo',pady=20).pack()
- Label(tabPage.pages['Foobar']['page'],text='Bar',pady=20).pack()
- Label(tabPage.pages['Baz']['page'],text='Baz').pack()
- entryPgName=Entry(root)
- buttonAdd=Button(root,text='Add Page',
- command=lambda:tabPage.AddPage(entryPgName.get()))
- buttonRemove=Button(root,text='Remove Page',
- command=lambda:tabPage.RemovePage(entryPgName.get()))
- labelPgName=Label(root,text='name of page to add/remove:')
- buttonAdd.pack(padx=5,pady=5)
- buttonRemove.pack(padx=5,pady=5)
- labelPgName.pack(padx=5)
- entryPgName.pack(padx=5)
- tabPage.ChangePage()
- root.mainloop()
diff --git a/Tools/idle/textView.py b/Tools/idle/textView.py
deleted file mode 100644
index 23e8bed..0000000
--- a/Tools/idle/textView.py
+++ /dev/null
@@ -1,77 +0,0 @@
-##---------------------------------------------------------------------------##
-##
-## idle - simple text view dialog
-## elguavas
-##
-##---------------------------------------------------------------------------##
-"""
-simple text browser for idle
-"""
-from Tkinter import *
-import tkMessageBox
-
-class TextViewer(Toplevel):
- """
- simple text viewer dialog for idle
- """
- def __init__(self,parent,title,fileName):
- """
- fileName - string,should be an absoulute filename
- """
- Toplevel.__init__(self, parent)
- self.configure(borderwidth=5)
- self.geometry("+%d+%d" % (parent.winfo_rootx()+10,
- parent.winfo_rooty()+10))
- #elguavas - config placeholders til config stuff completed
- self.bg=None
- self.fg=None
-
- self.CreateWidgets()
- self.title(title)
- self.transient(parent)
- self.grab_set()
- self.protocol("WM_DELETE_WINDOW", self.Ok)
- self.parent = parent
- self.textView.focus_set()
- #key bindings for this dialog
- self.bind('<Return>',self.Ok) #dismiss dialog
- self.bind('<Escape>',self.Ok) #dismiss dialog
- self.LoadTextFile(fileName)
- self.textView.config(state=DISABLED)
- self.wait_window()
-
- def LoadTextFile(self, fileName):
- textFile = None
- try:
- textFile = open(fileName, 'r')
- except IOError:
- tkMessageBox.showerror(title='File Load Error',
- message='Unable to load file '+`fileName`+' .')
- else:
- self.textView.insert(0.0,textFile.read())
-
- def CreateWidgets(self):
- frameText = Frame(self)
- frameButtons = Frame(self)
- self.buttonOk = Button(frameButtons,text='Ok',
- command=self.Ok,takefocus=FALSE,default=ACTIVE)
- self.scrollbarView = Scrollbar(frameText,orient=VERTICAL,
- takefocus=FALSE,highlightthickness=0)
- self.textView = Text(frameText,wrap=WORD,highlightthickness=0)
- self.scrollbarView.config(command=self.textView.yview)
- self.textView.config(yscrollcommand=self.scrollbarView.set)
- self.buttonOk.pack(padx=5,pady=5)
- self.scrollbarView.pack(side=RIGHT,fill=Y)
- self.textView.pack(side=LEFT,expand=TRUE,fill=BOTH)
- frameButtons.pack(side=BOTTOM,fill=X)
- frameText.pack(side=TOP,expand=TRUE,fill=BOTH)
-
- def Ok(self, event=None):
- self.destroy()
-
-if __name__ == '__main__':
- #test the dialog
- root=Tk()
- Button(root,text='View',
- command=lambda:TextViewer(root,'Text','./textView.py')).pack()
- root.mainloop()