From 1918b6f78959585e7d141aadc49bedfd5d0511f1 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Sat, 1 Dec 2001 02:25:39 +0000 Subject: [PATCH] Updated PyCrust contrib from Patrick O'Brian. Added an enhanced wxEditor from Steve Howell and Adam Feuer. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12782 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/CHANGES.txt | 2 + wxPython/MANIFEST.in | 1 + wxPython/demo/wxEditor.py | 47 +- wxPython/distrib/make_installer.py | 3 + wxPython/samples/frogedit/FrogEdit.py | 366 +++++ wxPython/samples/frogedit/FrogEditor.py | 92 ++ wxPython/samples/frogedit/StatusBar.py | 22 + .../lib/PyCrust/{PyCrust.py => PyCrustApp.py} | 8 +- .../PyCrust/{PyFilling.py => PyFillingApp.py} | 16 +- .../lib/PyCrust/{PyShell.py => PyShellApp.py} | 7 +- wxPython/wxPython/lib/PyCrust/README.txt | 8 +- wxPython/wxPython/lib/PyCrust/crust.py | 11 +- wxPython/wxPython/lib/PyCrust/filling.py | 12 +- wxPython/wxPython/lib/PyCrust/interpreter.py | 3 +- wxPython/wxPython/lib/PyCrust/introspect.py | 2 +- wxPython/wxPython/lib/PyCrust/pseudo.py | 2 +- wxPython/wxPython/lib/PyCrust/shell.py | 60 +- wxPython/wxPython/lib/PyCrust/version.py | 2 +- wxPython/wxPython/lib/editor/README.txt | 83 +- wxPython/wxPython/lib/editor/__init__.py | 1 - wxPython/wxPython/lib/editor/editor.py | 1295 ++++++++++------- wxPython/wxPython/lib/editor/images.py | 20 + wxPython/wxPython/lib/editor/py_editor.py | 211 --- wxPython/wxPython/lib/editor/selection.py | 42 + wxPython/wxPython/lib/editor/tokenizer.py | 60 - 25 files changed, 1522 insertions(+), 854 deletions(-) create mode 100644 wxPython/samples/frogedit/FrogEdit.py create mode 100644 wxPython/samples/frogedit/FrogEditor.py create mode 100644 wxPython/samples/frogedit/StatusBar.py rename wxPython/wxPython/lib/PyCrust/{PyCrust.py => PyCrustApp.py} (78%) mode change 100644 => 100755 rename wxPython/wxPython/lib/PyCrust/{PyFilling.py => PyFillingApp.py} (72%) mode change 100644 => 100755 rename wxPython/wxPython/lib/PyCrust/{PyShell.py => PyShellApp.py} (88%) mode change 100644 => 100755 create mode 100644 wxPython/wxPython/lib/editor/images.py delete mode 100644 wxPython/wxPython/lib/editor/py_editor.py create mode 100644 wxPython/wxPython/lib/editor/selection.py delete mode 100644 wxPython/wxPython/lib/editor/tokenizer.py diff --git a/wxPython/CHANGES.txt b/wxPython/CHANGES.txt index f504f9d0f0..87dffdbac0 100644 --- a/wxPython/CHANGES.txt +++ b/wxPython/CHANGES.txt @@ -95,6 +95,8 @@ same document. Added wxEditableListBox gizmo. +Added a greatly enhanced wxEditor from Steve Howell and Adam Feuer. + diff --git a/wxPython/MANIFEST.in b/wxPython/MANIFEST.in index fd87a7b4c0..60183f925c 100644 --- a/wxPython/MANIFEST.in +++ b/wxPython/MANIFEST.in @@ -50,6 +50,7 @@ include samples/StyleEditor/*.txt include samples/StyleEditor/*.cfg include samples/pySketch/*.py include samples/pySketch/images/*.bmp +include samples/frogedit/*.py include wxPython/lib/*.py diff --git a/wxPython/demo/wxEditor.py b/wxPython/demo/wxEditor.py index a55dc9def2..756b46e3f7 100644 --- a/wxPython/demo/wxEditor.py +++ b/wxPython/demo/wxEditor.py @@ -1,42 +1,63 @@ from wxPython.wx import * -from wxPython.lib.editor import wxEditor, wxPyEditor +from wxPython.lib.editor import wxEditor #---------------------------------------------------------------------- def runTest(frame, nb, log): win = wxPanel(nb, -1) ed = wxEditor(win, -1, style=wxSUNKEN_BORDER) - pyed = wxPyEditor(win, -1, style=wxSUNKEN_BORDER) box = wxBoxSizer(wxVERTICAL) box.Add(ed, 1, wxALL|wxGROW, 5) - box.Add(pyed, 1, wxALL|wxGROW, 5) win.SetSizer(box) win.SetAutoLayout(true) ed.SetText(["", "This is a simple text editor, the class name is", "wxEditor. Type a few lines and try it out.", + "", + "It uses Windows-style key commands that can be overriden by subclassing.", + "Mouse select works. Here are the key commands:", + "", + "Cursor movement: Arrow keys or mouse", + "Beginning of line: Home", + "End of line: End", + "Beginning of buffer: Control-Home", + "End of the buffer: Control-End", + "Select text: Hold down Shift while moving the cursor", + "Copy: Control-Insert, Control-C", + "Cut: Shift-Delete, Control-X", + "Paste: Shift-Insert, Control-V", ""]) - pyed.SetText(["# This one is a derived class named wxPyEditor.", - "# It adds syntax highlighting, folding (press", - "# F12 on the \"def\" line below) and other stuff.", - "import sys", - "def hello():", - " print 'hello'", - " for x in sys.path:", - " print x", - ""]) return win #---------------------------------------------------------------------- +overview = """ +The wxEditor class implements a simple text editor using wxPython. You +can create a custom editor by subclassing wxEditor. Even though much of +the editor is implemented in Python, it runs surprisingly smoothly on +normal hardware with small files. +How to use it +------------- +The demo code (demo/wxEditor.py) shows how to use wxEditor as a simple text +box. Use the SetText() and GetText() methods to set or get text from +the component; these both use a list of strings. + +The samples/FrogEdit directory has an example of a simple text editor +application that uses the wxEditor component. + +Subclassing +----------- +To add or change functionality, you can subclass this +component. One example of this might be to change the key +Alt key commands. In that case you would (for example) override the +SetAltFuncs() method. -overview = """\ """ diff --git a/wxPython/distrib/make_installer.py b/wxPython/distrib/make_installer.py index 8687e17cef..08e1aba4e2 100644 --- a/wxPython/distrib/make_installer.py +++ b/wxPython/distrib/make_installer.py @@ -151,6 +151,7 @@ Source: "samples\StyleEditor\*.cfg"; DestDir: "{app}\wxPython\samples\ Source: "samples\pySketch\*.py"; DestDir: "{app}\wxPython\samples\pySketch"; Components: samples Source: "samples\pySketch\images\*.bmp"; DestDir: "{app}\wxPython\samples\pySketch\images"; Components: samples +Source: "samples\frogedit\*.py"; DestDir: "{app}\wxPython\samples\frogedit"; Components: samples ;;------------------------------------------------------------ @@ -192,6 +193,8 @@ Type: files; Name: "{app}\wxPython\samples\stxview\*.pyc"; Type: files; Name: "{app}\wxPython\samples\stxview\*.pyo"; Type: files; Name: "{app}\wxPython\samples\stxview\StructuredText\*.pyc"; Type: files; Name: "{app}\wxPython\samples\stxview\StructuredText\*.pyo"; +Type: files; Name: "{app}\wxPython\samples\frogedit\*.pyc"; +Type: files; Name: "{app}\wxPython\samples\frogedit\*.pyo"; ''' diff --git a/wxPython/samples/frogedit/FrogEdit.py b/wxPython/samples/frogedit/FrogEdit.py new file mode 100644 index 0000000000..68f3e27a04 --- /dev/null +++ b/wxPython/samples/frogedit/FrogEdit.py @@ -0,0 +1,366 @@ +#!/usr/local/bin/python + +# simple text editor +# +# Copyright 2001 Adam Feuer and Steve Howell +# +# License: Python + +import os, string, re +import sys +from wxPython.wx import * +from StatusBar import * +from FrogEditor import FrogEditor + +TRUE = 1 +FALSE = 0 + +ABOUT_TEXT = """FrogEdit : Copyright 2001 Adam Feuer and Steve Howell +wxEditor component : Copyright 1999 - 2001 Dirk Holtwic, Robin Dunn, Adam Feuer, Steve Howell + +FrogEdit was built using Python, wxPython, and wxWindows.""" + + +##--------------------------------------------------------------------- + +def chomp(line): + line = string.split(line,'\n')[0] + return string.split(line,'\r')[0] + +##--------------------------------------------------------------------- + +class OutlinerPanel(wxPanel): + + def Close(self, event): + self.parent.Close() + wxPanel.Close(self) + +##---------------------------------------------------------------------- + + +class FrogEditFrame(wxFrame): + def __init__(self, parent, ID, title, pos=wxDefaultPosition, + size=wxDefaultSize, style=wxDEFAULT_FRAME_STYLE): + + wxFrame.__init__(self, parent, ID, title, pos, size, style) + + splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D) + win = OutlinerPanel(splitter, -1, style=wxCLIP_CHILDREN) + win.parent = self + log = self.MakeLogWindow(splitter) + + self.MakeStatusbar() + self.MakeEditorWindow(win, log) + self.SetUpSplitter(splitter, win, log) + self.MakeMenus() + self.MakeMainWindow(win) + self.RegisterEventHandlers() + self.InitVariables() + + +##------------- Init Misc + + def RegisterEventHandlers(self): + EVT_CLOSE(self,self.OnCloseWindow) + + def InitVariables(self): + self.fileName = None + self.edl.UnTouchBuffer() + + def MakeMenus(self): + self.MainMenu = wxMenuBar() + self.AddMenus(self.MainMenu) + self.SetMenuBar(self.MainMenu) + +##------------- Init Subwindows + + def MakeEditorWindow(self, win, log): + self.edl = FrogEditor(win, -1, style=wxSUNKEN_BORDER, statusBar = self.sb) + self.edl.SetControlFuncs = self.SetControlFuncs + self.edl.SetAltFuncs = self.SetAltFuncs + self.edl.SetStatus(log) + + def MakeStatusbar(self): + self.sb = CustomStatusBar(self) + self.SetStatusBar(self.sb) + + def MakeLogWindow(self, container): + log = wxTextCtrl(container, -1, + style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL) + wxLog_SetActiveTarget(wxLogTextCtrl(log)) + wxLogMessage('window handle: %s' % self.GetHandle()) + return log + + def SetUpSplitter(self, splitter, win, log): + splitter.SplitHorizontally(win, log) + splitter.SetSashPosition(360, true) + splitter.SetMinimumPaneSize(40) + + def MakeToolbar(self, win): + toolbarBox = wxBoxSizer(wxHORIZONTAL) + self.AddButtons(win, toolbarBox) + return toolbarBox + + def MakeMainWindow(self, win): + mainBox = wxBoxSizer(wxVERTICAL) + mainBox.Add(self.MakeToolbar(win)) + borderWidth = 5 + mainBox.Add(self.edl, 1, wxALL|wxGROW, borderWidth) + win.SetSizer(mainBox) + win.SetAutoLayout(true) + +##-------------- Init Menus + + # override this to add more menus + def AddMenus(self, menu): + self.AddFileMenu(menu) + self.AddEditMenu(menu) + self.AddHelpMenu(menu) + + def AddMenuItem(self, menu, itemText, itemDescription, itemHandler): + menuId = wxNewId() + menu.Append(menuId, itemText, itemDescription) + EVT_MENU(self, menuId, itemHandler) + return menuId + + def AddFileMenu(self, menu): + fileMenu = wxMenu() + self.AddMenuItem(fileMenu, '&New File\tCtrl-N', 'New File', self.OnNewFile) + self.AddMenuItem(fileMenu, '&Open File\tCtrl-O', 'Open File', self.OnOpenFile) + self.AddMenuItem(fileMenu, '&Save File\tCtrl-S', 'Save File', self.OnSaveFile) + self.AddMenuItem(fileMenu, 'Save File &As\tCtrl-A', 'Save File As',self.OnSaveFileAs) + self.AddMenuItem(fileMenu, 'E&xit\tAlt-X', 'Exit', self.OnFileExit) + menu.Append(fileMenu, 'File') + + def AddEditMenu(self, menu): + editMenu = wxMenu() + self.AddMenuItem(editMenu, 'Cut\tCtrl-X', 'Cut', self.edl.OnCutSelection) + self.AddMenuItem(editMenu, '&Copy\tCtrl-C', 'Copy', self.edl.OnCopySelection) + self.AddMenuItem(editMenu, 'Paste\tCtrl-V', 'Paste', self.edl.OnPaste) + self.AddMenuItem(editMenu, 'Edit preferences', 'Edit Preferences', self.OnEditPreferences) + menu.Append(editMenu, 'Edit') + + def AddHelpMenu(self, menu): + helpMenu = wxMenu() + self.AddMenuItem(helpMenu, 'About', 'About the program', self.OnHelpAbout) + menu.Append(helpMenu, 'Help') + +##---------------- Init Buttons + + + def NewButton(self, window, container, name, pos, size, handler): + buttonId = wxNewId() + if pos == None or size == None: + container.Add(wxButton(window, buttonId, name), 0, 0) + else: + container.Add(wxButton(window, buttonId, name, pos, size), 0, 0) + EVT_BUTTON(self, buttonId, handler) + return buttonId + + # override this to make more buttons + def AddButtons(self, window, container): + buttonPos = None + buttonSize = None + self.NewButton(window, container, "New", buttonPos, buttonSize, self.OnNewFile) + self.NewButton(window, container, "Open", buttonPos, buttonSize, self.OnOpenFile) + self.NewButton(window, container, "Save", buttonPos, buttonSize, self.OnSaveFile) + + +##-------------- Init Dialogs + + def MessageDialog(self, text, title): + messageDialog = wxMessageDialog(self, text, title, wxOK | wxICON_INFORMATION) + messageDialog.ShowModal() + messageDialog.Destroy() + + def OkCancelDialog(self, text, title): + dialog = wxMessageDialog(self, text, title, wxOK | wxCANCEL | wxICON_INFORMATION) + result = dialog.ShowModal() + dialog.Destroy() + if result == wxID_OK: + return TRUE + else: + return FALSE + + def SelectFileDialog(self, defaultDir=None, defaultFile=None, wildCard=None): + if defaultDir == None: + defaultDir = "." + if defaultFile == None: + defaultFile = "" + if wildCard == None: + wildCard = "*.*" + fileName = None + fileDialog = wxFileDialog(self, "Choose a file", defaultDir, defaultFile, wildCard, wxOPEN|wxMULTIPLE) + result = fileDialog.ShowModal() + if result == wxID_OK: + fileName = fileDialog.GetPath() + wxLogMessage('You selected: %s\n' % fileName) + fileDialog.Destroy() + return fileName + + def OpenFileError(self, fileName): + wxLogMessage('Open file error.') + self.MessageDialog("Error opening file '%s'!" % fileName, "Error") + + + def SaveFileError(self, fileName): + wxLogMessage('Save file error.') + self.MessageDialog("Error saving file '%s'!" % fileName, "Error") + +##---------------- Utility functions + + + def SetControlFuncs(self, action): + "for overriding editor's keys" + FrogEditor.SetControlFuncs(self.edl, action) + action['a'] = self.OnSaveFileAs + action['o'] = self.OnOpenFile + action['n'] = self.OnNewFile + action['s'] = self.OnSaveFile + + def SetAltFuncs(self, action): + FrogEditor.SetAltFuncs(self.edl, action) + action['x'] = self.OnFileExit + + def GetCurrentDir(self): + if self.fileName is not None: + return os.path.split(self.fileName)[0] + return "." + + def GetFileName(self): + if self.fileName is not None: + return os.path.split(self.fileName)[1] + return "" + + def NewFile(self): + self.edl.SetText([""]) + self.fileName = None + self.sb.setFileName("") + + def SaveFile(self, fileName): + try: + contents = string.join(self.edl.GetText(), '\n') + f = open(fileName, 'w') + f.write(contents) + f.close() + self.edl.UnTouchBuffer() + self.sb.setFileName(fileName) + return TRUE + except: + return FALSE + + def OpenFile(self, fileName): + try: + f = open(fileName, 'r') + contents = f.readlines() + f.close() + contents = [chomp(line) for line in contents] + if len(contents) == 0: + contents = [""] + self.edl.SetText(contents) + self.fileName = fileName + self.sb.setFileName(fileName) + return TRUE + except: + return FALSE + + + +##---------------- Event handlers + + + def OnCloseWindow(self, event): + self.edl.OnCloseWindow(event) + self.Destroy() + + def OnNewFile(self, event): + if self.edl.BufferWasTouched(): + if not self.OkCancelDialog("New file - abandon changes?", "New File"): + return + self.NewFile() + self.edl.SetFocus() + + def OnOpenFile(self, event): + if self.edl.BufferWasTouched(): + if not self.OkCancelDialog("Open file - abandon changes?", "Open File"): + return + fileName = self.SelectFileDialog(self.GetCurrentDir()) + if fileName is not None: + if self.OpenFile(fileName) is FALSE: + self.OpenFileError(fileName) + self.edl.SetFocus() + + def OnSaveFile(self, event): + if self.fileName is None: + return self.OnSaveFileAs(event) + wxLogMessage("Saving %s..." % self.fileName) + if self.SaveFile(self.fileName) is not TRUE: + self.SaveFileError(self.fileName) + self.edl.SetFocus() + + def OnSaveFileAs(self, event): + fileName = self.SelectFileDialog(self.GetCurrentDir(),self.GetFileName()) + if fileName is not None: + self.fileName = fileName + wxLogMessage("Saving %s..." % self.fileName) + if self.SaveFile(self.fileName) is not TRUE: + self.SaveFileError(self.fileName) + self.edl.SetFocus() + + def OnFileExit(self, event): + if self.edl.BufferWasTouched(): + if not self.OkCancelDialog("Exit program - abandon changes?", "Exit"): + return + self.OnCloseWindow(event) + + def OnEditPreferences(self, event): + self.MessageDialog("Edit preferences is not implemented yet.", "Not implemented.") + pass + + def OnHelpAbout(self, event): + self.MessageDialog(ABOUT_TEXT, "About FrogEdit") + pass + + def Show(self, show): + wxFrame.Show(self, show) + self.edl.SetFocus() + +##------------- Startup stuff + + def LoadInitialFile(self, fileName): + if fileName is not None: + if self.OpenFile(fileName) is FALSE: + self.OpenFileError(fileName) + + + + +##-------------- Application Launcher utility class + +class FrogEditLauncher: + + def MakeAppFrame(self): + return FrogEditFrame(None, -1, "FrogEdit", size=(640, 480), + style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE) + def GetArgvFilename(self): + if len(sys.argv) > 1: + return sys.argv[1] + else: + return None + + def Main(self): + win = self.MakeAppFrame() + app = wxPySimpleApp() + win.Show(true) + win.LoadInitialFile(self.GetArgvFilename()) + app.MainLoop() + + +##-------------- Main program + + +if __name__ == '__main__': + + launcher = FrogEditLauncher() + launcher.Main() + diff --git a/wxPython/samples/frogedit/FrogEditor.py b/wxPython/samples/frogedit/FrogEditor.py new file mode 100644 index 0000000000..d94e83c6e6 --- /dev/null +++ b/wxPython/samples/frogedit/FrogEditor.py @@ -0,0 +1,92 @@ +#!/usr/local/bin/python + +# simple text editor +# +# Copyright 2001 Adam Feuer and Steve Howell +# +# License: Python + +import re +from wxPython.wx import * +from wxPython.lib.editor import wxEditor + +#--------------------------------------------------------------------- + +class FrogEditor(wxEditor): + def __init__(self, parent, id, + pos=wxDefaultPosition, size=wxDefaultSize, style=0, statusBar=None): + self.StatusBar = statusBar + wxEditor.__init__(self, parent, id, pos, size, style) + self.parent = parent + + ##------------------------------------ + + def TouchBuffer(self): + wxEditor.TouchBuffer(self) + self.StatusBar.setDirty(1) + + def UnTouchBuffer(self): + wxEditor.UnTouchBuffer(self) + self.StatusBar.setDirty(0) + + + #--------- utility function ------------- + + # override our base class method + def DrawCursor(self, dc = None): + wxEditor.DrawCursor(self,dc) + self.StatusBar.setRowCol(self.cy,self.cx) + + def lastLine(self): + lastline = self.sy + self.sh - 1 + return min(lastline, self.LinesInFile() - 1) + + def rawLines(self): + return [l.text for l in self.text] + + def save(self): + if self.page: + self.ds.store(self.page,self.rawLines()) + + def SetRawText(self, rawtext=""): + self.rawText= rawtext + self.SetText(self.RenderText()) + + def RenderText(self): + return(self.rawText) + + #---------- logging ------------- + + def SetStatus(self, log): + self.log = log + self.status = [] + + def PrintSeparator(self, event): + self.Print("..........................") + + def Print(self, data): + self.status.append(data) + if data[-1:] == '\n': + data = data[:-1] + wxLogMessage(data) + + #--------- wxEditor keyboard overrides + + def SetControlFuncs(self, action): + wxEditor.SetControlFuncs(self, action) + action['-'] = self.PrintSeparator + + def SetAltFuncs(self, action): + wxEditor.SetAltFuncs(self, action) + action['x'] = self.Exit + + #----------- commands ----------- + + def OnCloseWindow(self, event): + # xxx - We don't fully understand how exit logic works. + # This event is actually called by our parent frame. + pass + + def Exit(self,event): + self.parent.Close(None) + diff --git a/wxPython/samples/frogedit/StatusBar.py b/wxPython/samples/frogedit/StatusBar.py new file mode 100644 index 0000000000..d8c45d452e --- /dev/null +++ b/wxPython/samples/frogedit/StatusBar.py @@ -0,0 +1,22 @@ +from wxPython.wx import * + +import os.path + +class CustomStatusBar(wxStatusBar): + def __init__(self, parent): + wxStatusBar.__init__(self, parent, -1) + self.SetFieldsCount(3) + + def setFileName(self, fn): + path, fileName = os.path.split(fn) + self.SetStatusText(fileName, 0) + + def setRowCol(self, row, col): + self.SetStatusText("%d,%d" % (row,col), 1) + + def setDirty(self, dirty): + if dirty: + self.SetStatusText("...", 2) + else: + self.SetStatusText(" ", 2) + diff --git a/wxPython/wxPython/lib/PyCrust/PyCrust.py b/wxPython/wxPython/lib/PyCrust/PyCrustApp.py old mode 100644 new mode 100755 similarity index 78% rename from wxPython/wxPython/lib/PyCrust/PyCrust.py rename to wxPython/wxPython/lib/PyCrust/PyCrustApp.py index 5c82403795..135b86a116 --- a/wxPython/wxPython/lib/PyCrust/PyCrust.py +++ b/wxPython/wxPython/lib/PyCrust/PyCrustApp.py @@ -1,13 +1,12 @@ #!/usr/bin/env python -"""PyCrust is a python shell and namespace browser application.""" +"""PyCrustApp is a python shell and namespace browser application.""" __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" -__date__ = "July 1, 2001" __version__ = "$Revision$"[11:-2] from wxPython.wx import * -from crust import CrustFrame +from PyCrust.crust import CrustFrame class App(wxApp): @@ -17,8 +16,6 @@ class App(wxApp): locals = {'__app__': 'PyCrust Standalone Application'} self.crustFrame = CrustFrame(locals=locals) self.crustFrame.Show(true) - # Set focus to the shell editor. - #self.crustFrame.crust.shell.SetFocus() self.SetTopWindow(self.crustFrame) # Add the application object to the sys module's namespace. # This allows a shell user to do: @@ -36,3 +33,4 @@ def main(): if __name__ == '__main__': main() + diff --git a/wxPython/wxPython/lib/PyCrust/PyFilling.py b/wxPython/wxPython/lib/PyCrust/PyFillingApp.py old mode 100644 new mode 100755 similarity index 72% rename from wxPython/wxPython/lib/PyCrust/PyFilling.py rename to wxPython/wxPython/lib/PyCrust/PyFillingApp.py index bb2c72b79b..62cea73e1c --- a/wxPython/wxPython/lib/PyCrust/PyFilling.py +++ b/wxPython/wxPython/lib/PyCrust/PyFillingApp.py @@ -1,22 +1,21 @@ #!/usr/bin/env python -"""PyFilling is a python namespace inspection application.""" +"""PyFillingApp is a python namespace inspection application.""" __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" -__date__ = "August 21, 2001" __version__ = "$Revision$"[11:-2] # We use this object to get more introspection when run standalone. application = None -import filling +from PyCrust import filling # These are imported just to have something interesting to inspect. -import crust -import interpreter -import introspect -import pseudo -import shell +from PyCrust import crust +from PyCrust import interpreter +from PyCrust import introspect +from PyCrust import pseudo +from PyCrust import shell import sys from wxPython import wx @@ -33,3 +32,4 @@ def main(): if __name__ == '__main__': main() + \ No newline at end of file diff --git a/wxPython/wxPython/lib/PyCrust/PyShell.py b/wxPython/wxPython/lib/PyCrust/PyShellApp.py old mode 100644 new mode 100755 similarity index 88% rename from wxPython/wxPython/lib/PyCrust/PyShell.py rename to wxPython/wxPython/lib/PyCrust/PyShellApp.py index 0fea2d5d10..9b3f945fa8 --- a/wxPython/wxPython/lib/PyCrust/PyShell.py +++ b/wxPython/wxPython/lib/PyCrust/PyShellApp.py @@ -1,13 +1,12 @@ #!/usr/bin/env python -"""PyShell is a python shell application.""" +"""PyShellApp is a python shell application.""" __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" -__date__ = "July 1, 2001" __version__ = "$Revision$"[11:-2] from wxPython.wx import * -from shell import ShellFrame +from PyCrust.shell import ShellFrame class App(wxApp): @@ -34,3 +33,5 @@ def main(): if __name__ == '__main__': main() + + \ No newline at end of file diff --git a/wxPython/wxPython/lib/PyCrust/README.txt b/wxPython/wxPython/lib/PyCrust/README.txt index df1431c41e..828b99a46b 100644 --- a/wxPython/wxPython/lib/PyCrust/README.txt +++ b/wxPython/wxPython/lib/PyCrust/README.txt @@ -1,6 +1,10 @@ PyCrust - The Flakiest Python Shell Half-baked by Patrick K. O'Brien (pobrien@orbtech.com) -====================================================== + +============================================================== +* Orbtech - "Your Source For Python Development Services" * +* Sample all our half-baked Python goods at www.orbtech.com. * +============================================================== What is PyCrust? ---------------- @@ -20,7 +24,7 @@ shouldn't build a Python program without a PyCrust either. Where can I get the latest release of PyCrust? ------------------------------------------------------------- +---------------------------------------------- The latest PyCrust releases are available at: http://sourceforge.net/project/showfiles.php?group_id=31263 diff --git a/wxPython/wxPython/lib/PyCrust/crust.py b/wxPython/wxPython/lib/PyCrust/crust.py index ceb62dc6d7..a97ac7fba7 100644 --- a/wxPython/wxPython/lib/PyCrust/crust.py +++ b/wxPython/wxPython/lib/PyCrust/crust.py @@ -2,7 +2,6 @@ __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" -__date__ = "July 1, 2001" __version__ = "$Revision$"[11:-2] from wxPython.wx import * @@ -46,15 +45,20 @@ class CrustFrame(wxFrame, ShellMenu): revision = __version__ def __init__(self, parent=None, id=-1, title='PyCrust', \ + pos=wxDefaultPosition, size=wxDefaultSize, \ + style=wxDEFAULT_FRAME_STYLE, \ rootObject=None, rootLabel=None, rootIsNamespace=1, \ locals=None, InterpClass=None, *args, **kwds): """Create a PyCrust CrustFrame instance.""" - wxFrame.__init__(self, parent, id, title) + wxFrame.__init__(self, parent, id, title, pos, size, style) intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION + intro += '\nSponsored by Orbtech.com – Your Source For Python Development Services' self.CreateStatusBar() self.SetStatusText(intro) if wxPlatform == '__WXMSW__': - icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO) + import os + filename = os.path.join(os.path.dirname(__file__), 'PyCrust.ico') + icon = wxIcon(filename, wxBITMAP_TYPE_ICO) self.SetIcon(icon) self.crust = Crust(parent=self, intro=intro, \ rootObject=rootObject, \ @@ -75,3 +79,4 @@ class CrustFrame(wxFrame, ShellMenu): self.createMenus() + diff --git a/wxPython/wxPython/lib/PyCrust/filling.py b/wxPython/wxPython/lib/PyCrust/filling.py index f0f24eb952..c49708c8d8 100644 --- a/wxPython/wxPython/lib/PyCrust/filling.py +++ b/wxPython/wxPython/lib/PyCrust/filling.py @@ -3,7 +3,6 @@ the local namespace or any object.""" __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" -__date__ = "August 21, 2001" __version__ = "$Revision$"[11:-2] from wxPython.wx import * @@ -217,6 +216,7 @@ class FillingText(wxStyledTextCtrl): self.SetViewWhiteSpace(0) self.SetTabWidth(4) self.SetUseTabs(0) + self.SetReadOnly(1) def setStyles(self, faces): """Configure font size, typeface and color for lexer.""" @@ -248,6 +248,11 @@ class FillingText(wxStyledTextCtrl): self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F") self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces) + def SetText(self, *args, **kwds): + self.SetReadOnly(0) + wxStyledTextCtrl.SetText(self, *args, **kwds) + self.SetReadOnly(1) + class Filling(wxSplitterWindow): """PyCrust Filling based on wxSplitterWindow.""" @@ -288,7 +293,9 @@ class FillingFrame(wxFrame): self.CreateStatusBar() self.SetStatusText(intro) if wxPlatform == '__WXMSW__': - icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO) + import os + filename = os.path.join(os.path.dirname(__file__), 'PyCrust.ico') + icon = wxIcon(filename, wxBITMAP_TYPE_ICO) self.SetIcon(icon) self.filling = Filling(parent=self, rootObject=rootObject, \ rootLabel=rootLabel, \ @@ -308,3 +315,4 @@ class App(wxApp): + \ No newline at end of file diff --git a/wxPython/wxPython/lib/PyCrust/interpreter.py b/wxPython/wxPython/lib/PyCrust/interpreter.py index 1454495d46..8274e35ed1 100644 --- a/wxPython/wxPython/lib/PyCrust/interpreter.py +++ b/wxPython/wxPython/lib/PyCrust/interpreter.py @@ -2,7 +2,6 @@ __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" -__date__ = "July 1, 2001" __version__ = "$Revision$"[11:-2] import os @@ -103,4 +102,4 @@ class InterpreterAlaCarte(Interpreter): sys.ps1 = ps1 sys.ps2 = ps2 - \ No newline at end of file + \ No newline at end of file diff --git a/wxPython/wxPython/lib/PyCrust/introspect.py b/wxPython/wxPython/lib/PyCrust/introspect.py index 5c48cb8da0..4139ec66c8 100644 --- a/wxPython/wxPython/lib/PyCrust/introspect.py +++ b/wxPython/wxPython/lib/PyCrust/introspect.py @@ -3,7 +3,6 @@ like call tips and command auto completion.""" __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" -__date__ = "August 8, 2001" __version__ = "$Revision$"[11:-2] import inspect @@ -168,3 +167,4 @@ def getRoot(command, terminator=None): return root + \ No newline at end of file diff --git a/wxPython/wxPython/lib/PyCrust/pseudo.py b/wxPython/wxPython/lib/PyCrust/pseudo.py index c709a8351c..d231dc2647 100644 --- a/wxPython/wxPython/lib/PyCrust/pseudo.py +++ b/wxPython/wxPython/lib/PyCrust/pseudo.py @@ -2,7 +2,6 @@ __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" -__date__ = "July 1, 2001" __version__ = "$Revision$"[11:-2] class PseudoKeyword: @@ -88,3 +87,4 @@ class PseudoFileErr(PseudoFile): return 1 + \ No newline at end of file diff --git a/wxPython/wxPython/lib/PyCrust/shell.py b/wxPython/wxPython/lib/PyCrust/shell.py index a071fb7ea1..8fe9f1caa0 100644 --- a/wxPython/wxPython/lib/PyCrust/shell.py +++ b/wxPython/wxPython/lib/PyCrust/shell.py @@ -5,7 +5,6 @@ SourceForge project page at http://sourceforge.net/projects/pycrust/.""" __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" -__date__ = "July 1, 2001" __version__ = "$Revision$"[11:-2] from wxPython.wx import * @@ -326,6 +325,20 @@ class Shell(wxStyledTextCtrl): # If the auto-complete window is up let it do its thing. elif self.AutoCompActive(): event.Skip() + # Cut to the clipboard. + elif event.ControlDown() and key in (ord('X'), ord('x')): + self.Cut() + # Copy to the clipboard. + elif event.ControlDown() and not event.ShiftDown() \ + and key in (ord('C'), ord('c')): + self.Copy() + # Copy to the clipboard, including prompts. + elif event.ControlDown() and event.ShiftDown() \ + and key in (ord('C'), ord('c')): + self.CopyWithPrompts() + # Paste from the clipboard. + elif event.ControlDown() and key in (ord('V'), ord('v')): + self.Paste() # Retrieve the previous command from the history buffer. elif (event.ControlDown() and key == WXK_UP) \ or (event.AltDown() and key in (ord('P'), ord('p'))): @@ -363,6 +376,9 @@ class Shell(wxStyledTextCtrl): # Don't toggle between insert mode and overwrite mode. elif key == WXK_INSERT: pass + # Protect the readonly portion of the shell. + elif not self.CanEdit(): + pass else: event.Skip() @@ -509,22 +525,26 @@ class Shell(wxStyledTextCtrl): The command may not necessarily be valid Python syntax.""" if not text: text = self.GetCurLine()[0] - # XXX Need to extract real prompts here. Need to keep track of the - # prompt every time a command is issued. + # Strip the prompt off the front of text leaving just the command. + command = self.lstripPrompt(text) + if command == text: + command = '' # Real commands have prompts. + if rstrip: + command = command.rstrip() + return command + + def lstripPrompt(self, text): + """Return text without a leading prompt.""" ps1 = str(sys.ps1) ps1size = len(ps1) ps2 = str(sys.ps2) ps2size = len(ps2) - # Strip the prompt off the front of text leaving just the command. + # Strip the prompt off the front of text. if text[:ps1size] == ps1: - command = text[ps1size:] + text = text[ps1size:] elif text[:ps2size] == ps2: - command = text[ps2size:] - else: - command = '' - if rstrip: - command = command.rstrip() - return command + text = text[ps2size:] + return text def push(self, command): """Send command to the interpreter for execution.""" @@ -738,6 +758,17 @@ class Shell(wxStyledTextCtrl): if self.CanCopy(): command = self.GetSelectedText() command = command.replace(os.linesep + sys.ps2, os.linesep) + command = command.replace(os.linesep + sys.ps1, os.linesep) + command = self.lstripPrompt(text=command) + data = wxTextDataObject(command) + if wxTheClipboard.Open(): + wxTheClipboard.SetData(data) + wxTheClipboard.Close() + + def CopyWithPrompts(self): + """Copy selection, including prompts, and place it on the clipboard.""" + if self.CanCopy(): + command = self.GetSelectedText() data = wxTextDataObject(command) if wxTheClipboard.Open(): wxTheClipboard.SetData(data) @@ -752,6 +783,7 @@ class Shell(wxStyledTextCtrl): if wxTheClipboard.GetData(data): command = data.GetText() command = self.fixLineEndings(command) + command = self.lstripPrompt(text=command) command = command.replace(os.linesep + sys.ps2, '\n') command = command.replace(os.linesep, '\n') command = command.replace('\n', os.linesep + sys.ps2) @@ -952,10 +984,13 @@ class ShellFrame(wxFrame, ShellMenu): """Create a PyCrust ShellFrame instance.""" wxFrame.__init__(self, parent, id, title, pos, size, style) intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION + intro += '\nSponsored by Orbtech.com – Your Source For Python Development Services' self.CreateStatusBar() self.SetStatusText(intro) if wxPlatform == '__WXMSW__': - icon = wxIcon('PyCrust.ico', wxBITMAP_TYPE_ICO) + import os + filename = os.path.join(os.path.dirname(__file__), 'PyCrust.ico') + icon = wxIcon(filename, wxBITMAP_TYPE_ICO) self.SetIcon(icon) self.shell = Shell(parent=self, id=-1, introText=intro, \ locals=locals, InterpClass=InterpClass, \ @@ -966,3 +1001,4 @@ class ShellFrame(wxFrame, ShellMenu): + diff --git a/wxPython/wxPython/lib/PyCrust/version.py b/wxPython/wxPython/lib/PyCrust/version.py index 177f1155bb..09d515a5cd 100644 --- a/wxPython/wxPython/lib/PyCrust/version.py +++ b/wxPython/wxPython/lib/PyCrust/version.py @@ -4,7 +4,7 @@ interpreter, each have a revision property based on the CVS Revision.""" __author__ = "Patrick K. O'Brien " __cvsid__ = "$Id$" -__date__ = "July 1, 2001" __version__ = "$Revision$"[11:-2] VERSION = '0.7' + \ No newline at end of file diff --git a/wxPython/wxPython/lib/editor/README.txt b/wxPython/wxPython/lib/editor/README.txt index 6072b4360d..6bf61637c7 100644 --- a/wxPython/wxPython/lib/editor/README.txt +++ b/wxPython/wxPython/lib/editor/README.txt @@ -1,10 +1,77 @@ -PLEASE NOTE: This is experimental code. It needs an overhall in the - drawing and update code, and there is occasionally a - mysteriously disappearing line... +wxEditor component +------------------ - I am working on a StyledTextEditor that will likely - render this editor obsolete... But this one is at - least somewhat functional now while the other is still - vapor. +The wxEditor class implements a simple text editor using wxPython. You +can create a custom editor by subclassing wxEditor. Even though much of +the editor is implemented in Python, it runs surprisingly smoothly on +normal hardware with small files. - - Robin + +Keys +---- +Keys are similar to Windows-based editors: + +Tab: 1 to 4 spaces (to next tab stop) +Cursor movement: Arrow keys +Beginning of line: Home +End of line: End +Beginning of buffer: Control-Home +End of the buffer: Control-End +Select text: Hold down Shift while moving the cursor +Copy: Shift-Insert, Control-C +Cut: Shift-Delete, Control-X +Paste: Control-Insert, Control-V + +How to use it +------------- +The demo code (demo/wxEditor.py) shows how to use it as a simple text +box. Use the SetText() and GetText() methods to set or get text from +the component; these both return a list of strings. + +The samples/FrogEdit directory has an example of a simple text editor +application that uses the wxEditor component. + +Subclassing +----------- +To add or change functionality, you can subclass this +component. One example of this might be to change the key +Alt key commands. In that case you would (for example) override the +SetAltFuncs() method. + +History +------- +The original author of this component was Dirk Holtwic. It originally +had limited support for syntax highlighting, but was not a usable text +editor, as it didn't implement select (with keys or mouse), or any of +the usual key sequences you'd expect in an editor. Robin Dunn did some +refactoring work to make it more usable. Steve Howell and Adam Feuer +did a lot of refactoring, and added some functionality, including +keyboard and mouse select, properly working scrollbars, and +overridable keys. Adam and Steve also removed support for +syntax-highlighting while refactoring the code. + +To do +----- +Alt/Ctrl Arrow keys move by word +Descriptive help text for keys +Speed improvements +Different fonts/colors + + +Authors +------- +Steve Howell, Adam Feuer, Dirk Holtwic, Robin Dunn + + +Contact +------- +You can find the latest code for wxEditor here: +http://www.pobox.com/~adamf/software/ + +We're not actively maintaining this code, but we can answer +questions about it. You can email us at: + +Adam Feuer +Steve Howell + +29 November 2001 diff --git a/wxPython/wxPython/lib/editor/__init__.py b/wxPython/wxPython/lib/editor/__init__.py index 30bd0310d0..c3b75eb2ad 100644 --- a/wxPython/wxPython/lib/editor/__init__.py +++ b/wxPython/wxPython/lib/editor/__init__.py @@ -15,4 +15,3 @@ # import the main classes into the package namespace. from editor import wxEditor -from py_editor import wxPyEditor diff --git a/wxPython/wxPython/lib/editor/editor.py b/wxPython/wxPython/lib/editor/editor.py index bfae392817..e531bff7ff 100644 --- a/wxPython/wxPython/lib/editor/editor.py +++ b/wxPython/wxPython/lib/editor/editor.py @@ -2,7 +2,18 @@ # Name: wxPython.lib.editor.wxEditor # Purpose: An intelligent text editor with colorization capabilities. # -# Author: Dirk Holtwic, Robin Dunn +# Original +# Authors: Dirk Holtwic, Robin Dunn +# +# New +# Authors: Adam Feuer, Steve Howell +# +# History: +# This code used to support a fairly complex subclass that did +# syntax coloring and outliner collapse mode. Adam and Steve +# inherited the code, and added a lot of basic editor +# functionality that had not been there before, such as cut-and-paste. +# # # Created: 15-Dec-1999 # RCS-ID: $Id$ @@ -10,35 +21,40 @@ # Licence: wxWindows license #---------------------------------------------------------------------- - -# PLEASE NOTE: This is experimental code. It needs an overhall in the -# drawing and update code, and there is occasionally a -# mysteriously disappearing line... -# -# I am working on a StyledTextEditor that will likely -# render this editor obsolete... But this one is at -# least somewhat functional now while the other is still -# vapor. -# -# - Robin - +import os, time from wxPython.wx import * from string import * -from keyword import * -from regsub import * -from tokenizer import * -#--------------------------------------------------------------------------- +import selection +import images +#---------------------------- -class Line: - def __init__(self, text=""): - self.text = text # the string itself - self.syntax = [] # the colors of the line - self.editable = true # edit? - self.visible = 0 # will be incremented if not - self.indent = 0 # not used yet +def ForceBetween(min, val, max): + if val > max: + return max + if val < min: + return min + return val + +#---------------------------- + +class Scroller: + def __init__(self, parent): + self.parent = parent + self.ow = 0 + self.oh = 0 + self.ox = 0 + self.oy = 0 + + def SetScrollbars(self, fw, fh, w, h, x, y): + if (self.ow != w or self.oh != h or self.ox != x or self.oy != y): + self.parent.SetScrollbars(fw, fh, w, h, x, y) + self.ow = w + self.oh = h + self.ox = x + self.oy = y #---------------------------------------------------------------------- @@ -46,229 +62,180 @@ class wxEditor(wxScrolledWindow): def __init__(self, parent, id, pos=wxDefaultPosition, size=wxDefaultSize, style=0): - ############################################################### - """ - Alles hat einen Anfang - """ wxScrolledWindow.__init__(self, parent, id, pos, size, style|wxWANTS_CHARS) - # the syntax informations, if they don't exist, - # all syntax stuff will be ignored + self.InitCoords() + self.InitFonts() + self.SetColors() + self.MapEvents() + self.LoadImages() + self.InitDoubleBuffering() + self.InitScrolling() + self.SelectOff() + self.CopiedData = None + self.SetFocus() + self.SetText([""]) + self.SpacesPerTab = 4 + +##------------------ Init stuff - # cursor pos + def InitCoords(self): self.cx = 0 self.cy = 0 - - # the lines that are visible - self.lines = [] - self.line = 0 - self.len = 0 - - self.ocy = 0 - - # border pos - #self.bx = 0 - #self.by = 0 - - # screen + self.oldCx = 0 + self.oldCy = 0 self.sx = 0 self.sy = 0 self.sw = 0 self.sh = 0 - self.osx= 0 - self.osy= 0 - - # font - dc = wxClientDC(self) - - if wxPlatform == "__WXMSW__": - self.font = wxFont(10, wxMODERN, wxNORMAL, wxNORMAL) - else: - self.font = wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, false) - dc.SetFont(self.font) - - # font weight, height - self.fw = dc.GetCharWidth() - self.fh = dc.GetCharHeight() - - # back, for colour - self.bcol = wxNamedColour('white') - self.fcol = wxNamedColour('black') - - self.cfcol = wxNamedColour('black') - self.cbcol = wxNamedColour('red') - - # nicht edierbare zeile (hintergrund) - self.nedcol = wxNamedColour('grey') - - self.SetBackgroundColour(self.bcol) - #dc.SetForegroundColour(self.fcol) + self.sco_x = 0 + self.sco_y = 0 - # events - EVT_LEFT_DOWN(self, self.OnMouseClick) - EVT_RIGHT_DOWN(self, self.OnMouseClick) + def MapEvents(self): + EVT_LEFT_DOWN(self, self.OnLeftDown) + EVT_LEFT_UP(self, self.OnLeftUp) + EVT_MOTION(self, self.OnMotion) EVT_SCROLLWIN(self, self.OnScroll) EVT_CHAR(self, self.OnChar) EVT_PAINT(self, self.OnPaint) + EVT_SIZE(self, self.OnSize) + EVT_WINDOW_DESTROY(self, self.OnDestroy) - self.o_cx = self.cx - self.o_cy = self.cy - self.o_sx = self.sx - self.o_sy = self.sy - self.o_line = self.line - self.sco_x = 0 - self.sco_y = 0 - - self.tabsize = 4 +##------------------- Platform-specific stuff - self.update = true - self.in_scroll =FALSE - self.inUpdate = FALSE - - - bw,bh = self.GetSizeTuple() - # double buffering - self.mdc = wxMemoryDC() - self.mdc.SelectObject(wxEmptyBitmap(bw,bh)) - # disable physical scrolling because invisible parts are not drawn - self.EnableScrolling(FALSE, FALSE) - - # the ordinary text as it is - self.SetText() + def NiceFontForPlatform(self): + if wxPlatform == "__WXMSW__": + return wxFont(10, wxMODERN, wxNORMAL, wxNORMAL) + else: + return wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, false) + + def UnixKeyHack(self, key): + # this will be obsolete when we get the new wxWindows patch + if key <= 26: + key += ord('a') - 1 + return key + +##-------------------- UpdateView/Cursor code + + def OnSize(self, event): + self.AdjustScrollbars() self.SetFocus() + def SetCharDimensions(self): + # TODO: We need a code review on this. It appears that Linux + # improperly reports window dimensions when the scrollbar's there. + self.bw, self.bh = self.GetClientSizeTuple() -#--------------------------------------------------------------------------- - - def CalcLines(self): - ############################################################### - self.lines = [] - x =maxlen =0 - for line in self.text: - if line.visible==0: - self.lines.append(x) - else: - if len(line.text) >maxlen: - maxlen =len(line.text) - x = x + 1 - self.len = len(self.lines) - self.max_linelength =maxlen - - - def SetFontTab(self, fonttab): - ############################################################### - """ Fonttabelle zum schnellen Zugriff """ - self.ftab = fonttab - - - def SetText(self, text = [""]): - ############################################################### - """ Text mittels Liste setzen """ - self.cx = 0 - self.cy = 0 - self.text = [] - - for t in text: - self.text.append(Line(t)) - - for l in range(0,len(text)-1): - #self.UpdateSyntax(l) - self.OnUpdateHighlight(l) - - self.OnInit() - - self.update = true - self.UpdateView(None, true) - - - # show new text - def GetText(self): - ############################################################### - """ Der gesamte Text als Liste """ - text = [] - for line in self.text: - text.append(line.text) - return text - + if wxPlatform == "__WXMSW__": + self.sh = self.bh / self.fh + self.sw = (self.bw / self.fw) - 1 + else: + self.sh = self.bh / self.fh + if self.LinesInFile() >= self.sh: + self.bw = self.bw - wxSystemSettings_GetSystemMetric(wxSYS_VSCROLL_X) + self.sw = (self.bw / self.fw) - 1 - def IsEmpty(self): - ############################################################### - """see if at least one text line is not empty""" - for line in self.text: - if line.text: return 0 - return 1 + self.sw = (self.bw / self.fw) - 1 + if self.CalcMaxLineLen() >= self.sw: + self.bh = self.bh - wxSystemSettings_GetSystemMetric(wxSYS_HSCROLL_Y) + self.sh = self.bh / self.fh - def IsLine(self, line): - ############################################################### - """ Schauen, ob alles im grünen Bereich ist """ - return (line>=0) and (line Cursor setzen - """ - self.SetFocus() + def LoadImages(self): + self.eofMarker = images.GetBitmap(images.EofImageData) - self.cy = self.sy + (event.GetY() / self.fh) - if self.cy >= self.len: self.cy =max(self.len -1, 0) - linelen =len(self.text[self.GetLine(self.cy)].text) - self.cx = self.sx + (event.GetX() / self.fw) - # allow positioning right behind the last character - if self.cx > linelen: self.cx =linelen - if event.GetEventType() ==wxEVT_RIGHT_DOWN: - self.update = true - self.OnFold() - self.UpdateView() + def DrawEofMarker(self,dc): + x = 0 + y = (len(self.lines) - self.sy) * self.fh + hasTransparency = 1 + dc.DrawBitmap(self.eofMarker, x, y, hasTransparency) +##------------------ cursor-related functions def DrawCursor(self, dc = None): - ############################################################### - """ - Auch der Cursor muß ja irgendwie gezeichnet werden - """ if not dc: dc = wxClientDC(self) - if (self.len)maxlen: + maxlen = len(line) + return maxlen + + def KeepCursorOnScreen(self): + self.sy = ForceBetween(max(0, self.cy-self.sh), self.sy, self.cy) + self.sx = ForceBetween(max(0, self.cx-self.sw), self.sx, self.cx) + self.AdjustScrollbars() + + def HorizBoundaries(self): + self.SetCharDimensions() + maxLineLen = self.CalcMaxLineLen() + self.sx = ForceBetween(0, self.sx, max(self.sw, maxLineLen - self.sw + 1)) + self.cx = ForceBetween(self.sx, self.cx, self.sx + self.sw - 1) + + def VertBoundaries(self): + self.SetCharDimensions() + self.sy = ForceBetween(0, self.sy, max(self.sh, self.LinesInFile() - self.sh + 1)) + self.cy = ForceBetween(self.sy, self.cy, self.sy + self.sh - 1) + + def cVert(self, num): + self.cy = self.cy + num + self.cy = ForceBetween(0, self.cy, self.LinesInFile() - 1) + self.sy = ForceBetween(self.cy - self.sh + 1, self.sy, self.cy) + self.cx = min(self.cx, self.CurrentLineLength()) - def OnScroll(self, event): - dir =event.GetOrientation() - evt =event.GetEventType() - if dir ==wxHORIZONTAL: - if evt ==wxEVT_SCROLLWIN_LINEUP: self.sx =self.sx -1 - elif evt ==wxEVT_SCROLLWIN_LINEDOWN: self.sx =self.sx +1 - elif evt ==wxEVT_SCROLLWIN_PAGEUP: self.sx =self.sx -self.sw - elif evt ==wxEVT_SCROLLWIN_PAGEDOWN: self.sx =self.sx +self.sw - elif evt ==wxEVT_SCROLLWIN_TOP: self.sx =self.cx =0 - elif evt ==wxEVT_SCROLLWIN_BOTTOM: - self.sx =self.max_linelength -self.sw - self.cx =self.max_linelength - else: - self.sx =event.GetPosition() - - if self.sx >(self.max_linelength -self.sw +1): - self.sx =self.max_linelength -self.sw +1 - if self.sx <0: self.sx =0 - if self.cx >(self.sx +self.sw -1): self.cx =self.sx +self.sw -1 - if self.cx (self.len -self.sh +1): - self.sy =self.len -self.sh +1 - if self.sy <0: self.sy =0 - if self.cy >(self.sy +self.sh -1): self.cy =self.sy +self.sh -1 - if self.cy