[Python-checkins] r65572 - in sandbox/trunk/ttk-gsoc/src/idlelib: EditorWindow.py OutputWindow.py PyShell.py editorpage.py
guilherme.polo
python-checkins at python.org
Thu Aug 7 15:55:28 CEST 2008
Author: guilherme.polo
Date: Thu Aug 7 15:55:27 2008
New Revision: 65572
Log:
Added a new method in EditorWindow to remove tab controls from its window (the
code was in PyShell before this);
rmenu is controlled by EditorPage instance now;
ispythonsource coded moved from EditorWindow to EditorPage, but PyShell still
has its own ispythonsource due to not having a dedicated Page class for it;
When a new tab is created, it gets selected now;
Moved great part of OutputWindow's code to a new class named OutputPage living
in the editorpage module now;
Modified:
sandbox/trunk/ttk-gsoc/src/idlelib/EditorWindow.py
sandbox/trunk/ttk-gsoc/src/idlelib/OutputWindow.py
sandbox/trunk/ttk-gsoc/src/idlelib/PyShell.py
sandbox/trunk/ttk-gsoc/src/idlelib/editorpage.py
Modified: sandbox/trunk/ttk-gsoc/src/idlelib/EditorWindow.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/idlelib/EditorWindow.py (original)
+++ sandbox/trunk/ttk-gsoc/src/idlelib/EditorWindow.py Thu Aug 7 15:55:27 2008
@@ -20,7 +20,7 @@
TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
if TTK:
- from ttk import Scrollbar
+ from ttk import Style, Scrollbar
# The default tab setting for a Text widget, in average-width characters.
TK_TABWIDTH_DEFAULT = 8
@@ -30,11 +30,6 @@
from UndoDelegator import UndoDelegator # overridden by PyShell
help_url = None
- rmenu = None
- rmenu_specs = [
- # ("Label", "<<virtual-event>>"), ...
- ("Close", "<<close-window>>"), # Example
- ]
menu_specs = [
("file", "_File"),
("edit", "_Edit"),
@@ -49,7 +44,8 @@
del menu_specs[-3]
menu_specs[-2] = ("windows", "_Window")
- def __init__(self, flist=None, filename=None, key=None, root=None):
+ def __init__(self, flist=None, filename=None, key=None, root=None,
+ start_page=EditorPage):
if EditorWindow.help_url is None:
dochome = os.path.join(sys.prefix, 'Doc', 'index.html')
if sys.platform.count('linux'):
@@ -114,7 +110,7 @@
self.text_notebook = TabbedPageSet(self.top)
self.text_notebook.pack(fill=BOTH, expand=True)
self.text_notebook.bind('<<NotebookTabChanged>>', self._update_controls)
- self.new_tab(filename=filename, load_ext=False)
+ self.new_tab(filename=filename, load_ext=False, ptype=start_page)
self.text = self.current_page.text # XXX
self.top.focused_widget = self.text
self.top.bind('<<tab-closed>>', self._post_tab_close)
@@ -165,7 +161,11 @@
# Making the initial values larger slows things down more often.
self.num_context_lines = 50, 500, 5000000
- self.set_indentation_params(self.ispythonsource(filename))
+ if hasattr(self, 'ispythonsource'): # PyShell
+ self.set_indentation_params(self.ispythonsource(filename))
+ else:
+ self.set_indentation_params(
+ self.current_page.ispythonsource(filename))
self.extensions = {}
self._load_extensions()
@@ -200,9 +200,37 @@
page = self.text_notebook.pages[curr_tab].editpage
return page
+ def remove_tab_controls(self):
+ """Remove tab area and most tab bindings from this window."""
+ if TTK:
+ self.text_notebook['style'] = 'PyShell.TNotebook'
+ style = Style(self.top)
+ style.layout('PyShell.TNotebook.Tab', [('null', '')])
+ else:
+ self.text_notebook._tab_set.grid_forget()
+
+ # remove commands related to tab
+ if 'file' in self.menudict:
+ menu = self.menudict['file']
+ curr_entry = None
+ i = 0
+ while True:
+ last_entry, curr_entry = curr_entry, menu.entryconfigure(i)
+ if last_entry == curr_entry:
+ # no more menu entries
+ break
+
+ if 'label' in curr_entry and 'Tab' in curr_entry['label'][-1]:
+ if 'Close' not in ' '.join(curr_entry['label'][-1]):
+ menu.delete(i)
+ i += 1
+
+ self.current_page.text.unbind('<<new-tab>>')
+ # close-tab is still available!
+
def short_title(self):
# overriden by PyShell
- self.current_page.short_title()
+ return self.current_page.short_title()
def next_tab(self, event):
"""Show next tab if not in the last tab already."""
@@ -218,13 +246,14 @@
return
self.text_notebook.select(index - 1)
- def new_tab(self, event=None, filename=None, load_ext=True):
+ def new_tab(self, event=None, filename=None, load_ext=True, ptype=None):
"""Create a new EditorPage and insert it into the notebook."""
page_title = "#%d" % (len(self.text_notebook.pages) + 1)
page = self.text_notebook.add_page(page_title)
vbar = Scrollbar(page.frame, name='vbar')
- page.editpage = EditorPage(page.frame, self, title=page_title,
+ ptype = ptype or EditorPage
+ page.editpage = ptype(page.frame, self, title=page_title,
name='text', padx=5, wrap='none')
firstpage = False # don't update window's title
@@ -240,8 +269,7 @@
underline=0, menu=self.recent_files_menu)
self.update_recent_files_list()
- page.editpage.post_init(filename=filename, update_window_title=firstpage)
-
+ # pack widgets
text = page.editpage.text
vbar['command'] = text.yview
vbar.pack(side=RIGHT, fill=Y)
@@ -258,6 +286,13 @@
self.apply_bindings(tab=page)
if load_ext:
self._load_extensions()
+
+ # select the just created page
+ self.text_notebook.select(len(self.text_notebook.pages) - 1)
+
+ page.editpage.post_init(filename=filename,
+ update_window_title=firstpage)
+
self.top.event_generate('<<tab-created>>')
return "break"
@@ -308,20 +343,6 @@
text.tag_add("sel", "insert", "insert +1l")
page.center()
- def ispythonsource(self, filename):
- if not filename or os.path.isdir(filename):
- return True
- base, ext = os.path.splitext(os.path.basename(filename))
- if os.path.normcase(ext) in (".py", ".pyw"):
- return True
- try:
- f = open(filename)
- line = f.readline()
- f.close()
- except IOError:
- return False
- return line.startswith('#!') and line.find('python') >= 0
-
def close_hook(self):
if self.flist:
self.flist.unregister_maybe_terminate(self)
@@ -605,7 +626,7 @@
self.extensions = {}
def _load_extension(self, name, tab):
- ext_loaded = self.extensions.get(name, None)
+ ext_loaded = self.extensions.get(name)
try:
mod = __import__(name, globals(), locals(), [])
Modified: sandbox/trunk/ttk-gsoc/src/idlelib/OutputWindow.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/idlelib/OutputWindow.py (original)
+++ sandbox/trunk/ttk-gsoc/src/idlelib/OutputWindow.py Thu Aug 7 15:55:27 2008
@@ -3,10 +3,10 @@
import utils
import IOBinding
+from editorpage import OutputPage
from EditorWindow import EditorWindow
class OutputWindow(EditorWindow):
-
"""An editor window that can serve as an output file.
Also the future base class for the Python shell window.
@@ -14,36 +14,14 @@
"""
def __init__(self, *args):
- EditorWindow.__init__(self, *args)
- self.top.bind("<<tab-created>>", self.__configure_new_tab)
- # configure the tab created in EditorWindow.__init__
- self.__configure_new_tab()
-
- def __configure_new_tab(self, event=None):
- page = self.text_notebook.last_page().editpage
- page.text.bind("<<goto-file-line>>", utils.callback(self.goto_file_line,
- page.text))
-
- # Customize EditorWindow
-
- def ispythonsource(self, filename):
- # No colorization needed
- return 0
-
- def short_title(self):
- return "Output"
-
- def maybesave(self):
- # Override base class method -- don't ask any questions
- if self.get_saved():
- return "yes"
- else:
- return "no"
+ EditorWindow.__init__(self, start_page=OutputPage, *args)
+ self.remove_tab_controls()
# Act as output file
def write(self, s, tags=(), mark="insert", text=None):
- assert text is not None
+ if text is None:
+ text = self.current_page.text
# Tk assumes that byte strings are Latin-1;
# we assume that they are in the locale's encoding
if isinstance(s, str):
@@ -61,60 +39,3 @@
def flush(self):
pass
-
- # Our own right-button menu
-
- rmenu_specs = [
- ("Go to file/line", "<<goto-file-line>>"),
- ]
-
- file_line_pats = [
- r'file "([^"]*)", line (\d+)',
- r'([^\s]+)\((\d+)\)',
- r'([^\s]+):\s*(\d+):',
- ]
-
- file_line_progs = None
-
- def goto_file_line(self, event, text):
- if self.file_line_progs is None:
- l = []
- for pat in self.file_line_pats:
- l.append(re.compile(pat, re.IGNORECASE))
- self.file_line_progs = l
-
- line = text.get("insert linestart", "insert lineend")
- result = self._file_line_helper(line)
- if not result:
- # Try the previous line. This is handy e.g. in tracebacks,
- # where you tend to right-click on the displayed source line
- line = text.get("insert -1line linestart", "insert -1line ineend")
- result = self._file_line_helper(line)
- if not result:
- tkMessageBox.showerror(
- "No special line",
- "The line you point at doesn't look like "
- "a valid file name followed by a line number.",
- master=text)
- return
- filename, lineno = result
- edit = self.flist.open(filename)
- edit.gotoline(lineno)
-
- def _file_line_helper(self, line):
- for prog in self.file_line_progs:
- m = prog.search(line)
- if m:
- break
- else:
- return None
- filename, lineno = m.group(1, 2)
- try:
- f = open(filename, "r")
- f.close()
- except IOError:
- return None
- try:
- return filename, int(lineno)
- except TypeError:
- return None
Modified: sandbox/trunk/ttk-gsoc/src/idlelib/PyShell.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/idlelib/PyShell.py (original)
+++ sandbox/trunk/ttk-gsoc/src/idlelib/PyShell.py Thu Aug 7 15:55:27 2008
@@ -112,9 +112,6 @@
class PyShellEditorWindow(EditorWindow):
"Regular text edit window in IDLE, supports breakpoints"
- rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
- ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
-
def __init__(self, *args):
EditorWindow.__init__(self, *args)
@@ -833,31 +830,7 @@
OutputWindow.__init__(self, flist, None, None)
# remove things related to tabs. The window running the shell is
# considered special enough to have a single window for it.
-
- # remove tabs area
- if TTK:
- self.text_notebook['style'] = 'PyShell.TNotebook'
- style = Style(self.top)
- style.layout('PyShell.TNotebook.Tab', [('null', '')])
- else:
- self.text_notebook._tab_set.grid_forget()
-
- # remove commands related to tab
- if 'file' in self.menudict:
- menu = self.menudict['file']
- curr_entry = None
- i = 0
- while True:
- last_entry, curr_entry = curr_entry, menu.entryconfigure(i)
- if last_entry == curr_entry:
- break
-
- if 'label' in curr_entry and 'Tab' in curr_entry['label'][-1]:
- if 'New' in ' '.join(curr_entry['label'][-1]):
- menu.delete(i)
- i += 1
- self.text.unbind('<<new-tab>>')
- #self.text.unbind('<<close-tab>>')
+ self.remove_tab_controls()
#
self.usetabs = True
Modified: sandbox/trunk/ttk-gsoc/src/idlelib/editorpage.py
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/idlelib/editorpage.py (original)
+++ sandbox/trunk/ttk-gsoc/src/idlelib/editorpage.py Thu Aug 7 15:55:27 2008
@@ -73,6 +73,12 @@
return file, filename, descr
class EditorPage(object):
+ rmenu = None
+ rmenu_specs = [
+ ("Set Breakpoint", "<<set-breakpoint-here>>"),
+ ("Clear Breakpoint", "<<clear-breakpoint-here>>")
+ ]
+
def __init__(self, parent_frame, editwin, title=None, **kwargs):
self.editwin = editwin
self.title = title
@@ -228,6 +234,20 @@
newtop = max(1, lineno - height//2)
text.yview(float(newtop))
+ def ispythonsource(self, filename):
+ if not filename or os.path.isdir(filename):
+ return True
+ base, ext = os.path.splitext(os.path.basename(filename))
+ if os.path.normcase(ext) in (".py", ".pyw"):
+ return True
+ try:
+ f = open(filename)
+ line = f.readline()
+ f.close()
+ except IOError:
+ return False
+ return line.startswith('#!') and line.find('python') >= 0
+
def newline_and_indent_event(self, event):
# Used by EditorWindow.newline_and_indent_event which is used by PyShell
text = self.text
@@ -474,15 +494,8 @@
f.close()
if self.editwin.flist:
if idleConf.GetOption('main', 'EditorWindow', 'file-in-tab',
- default=1, type='bool'):
- if hasattr(self.editwin, 'interp'):
- # PyShell window must open a module in a new window
- action = None
- else:
- action = self.editwin.new_tab
- else:
- action = None
- self.editwin.flist.open(file, action)
+ default=1, type='bool'):
+ self.editwin.flist.open(file)
else:
self.io.loadfile(file)
@@ -499,8 +512,7 @@
return "break"
def _find_in_files_event(self, event):
- # XXX not expected to work correctly for now
- GrepDialog.grep(self.text, self.editwin.io, self.editwin.flist)
+ GrepDialog.grep(self.text, self.io, self.editwin.flist)
return "break"
def _replace_event(self, event):
@@ -810,10 +822,10 @@
self.text.tag_remove("sel", "1.0", "end")
self.text.mark_set("insert", "@%d,%d" % (event.x, event.y))
- if not self.editwin.rmenu:
+ if not self.rmenu:
self.__make_rmenu()
- rmenu = self.editwin.rmenu
+ rmenu = self.rmenu
self.event = event
iswin = sys.platform[:3] == 'win'
if iswin:
@@ -825,12 +837,12 @@
def __make_rmenu(self):
rmenu = Menu(self.text, tearoff=False)
- for label, eventname in self.editwin.rmenu_specs:
+ for label, eventname in self.rmenu_specs:
def command(text=self.text, eventname=eventname):
text.event_generate(eventname)
rmenu.add_command(label=label, command=command)
- self.editwin.rmenu = rmenu
+ self.rmenu = rmenu
def __rmcolorizer(self):
if not self.color:
@@ -842,7 +854,12 @@
def __addcolorizer(self):
if self.color:
return
- if self.editwin.ispythonsource(self.io.filename):
+
+ if hasattr(self.editwin, 'ispythonsource'): # PyShell window
+ pychecker = self.editwin.ispythonsource
+ else:
+ pychecker = self.ispythonsource
+ if pychecker(self.io.filename):
self.color = self.editwin.ColorDelegator()
# can add more colorizers here...
@@ -923,3 +940,84 @@
else:
# The colorizer is missing: assume the worst
return 1
+
+
+import re
+
+class OutputPage(EditorPage):
+ rmenu_specs = [
+ ("Go to file/line", "<<goto-file-line>>"),
+ ]
+
+ file_line_pats = [
+ r'file "([^"]*)", line (\d+)',
+ r'([^\s]+)\((\d+)\)',
+ r'([^\s]+):\s*(\d+):',
+ ]
+
+ file_line_progs = None
+
+ def __init__(self, parent_frame, editwin, title=None, **kwargs):
+ EditorPage.__init__(self, parent_frame, editwin, title, **kwargs)
+ self.text.bind("<<goto-file-line>>", self.goto_file_line)
+
+ def ispythonsource(self, filename):
+ # No colorization needed
+ return 0
+
+ def short_title(self):
+ return "Output"
+
+ def maybesave(self):
+ # Override base class method -- don't ask any questions
+ if self.get_saved():
+ return "yes"
+ else:
+ return "no"
+
+ def goto_file_line(self, event):
+ text = self.text
+ if self.file_line_progs is None:
+ l = []
+ for pat in self.file_line_pats:
+ l.append(re.compile(pat, re.IGNORECASE))
+ self.file_line_progs = l
+
+ line = text.get("insert linestart", "insert lineend")
+ result = self._file_line_helper(line)
+ if not result:
+ # Try the previous line. This is handy e.g. in tracebacks,
+ # where you tend to right-click on the displayed source line
+ line = text.get("insert -1line linestart", "insert -1line ineend")
+ result = self._file_line_helper(line)
+ if not result:
+ tkMessageBox.showerror("No special line",
+ "The line you point at doesn't look like "
+ "a valid file name followed by a line number.",
+ master=text)
+ return
+ filename, lineno = result
+ self._open_file_at_line(filename, lineno)
+
+ def _file_line_helper(self, line):
+ for prog in self.file_line_progs:
+ m = prog.search(line)
+ if m:
+ break
+ else:
+ return None
+
+ filename, lineno = m.group(1, 2)
+ try:
+ f = open(filename, "r")
+ f.close()
+ except IOError:
+ return None
+ try:
+ return filename, int(lineno)
+ except TypeError:
+ return None
+
+ def _open_file_at_line(self, filename, lineno):
+ edit = self.editwin.flist.open(filename)
+ edit.gotoline(lineno)
More information about the Python-checkins
mailing list