Updated docview library modules and sample apps from the ActiveGrid
folks. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33434 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
521
wxPython/samples/pydocview/FindService.py
Normal file
521
wxPython/samples/pydocview/FindService.py
Normal file
@@ -0,0 +1,521 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: FindService.py
|
||||
# Purpose: Find Service for pydocview
|
||||
#
|
||||
# Author: Peter Yared, Morgan Hua
|
||||
#
|
||||
# Created: 8/15/03
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2003-2005 ActiveGrid, Inc.
|
||||
# License: ASL 2.0 http://apache.org/licenses/LICENSE-2.0
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import wx
|
||||
import wx.lib.docview
|
||||
import wx.lib.pydocview
|
||||
import re
|
||||
_ = wx.GetTranslation
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Constants
|
||||
#----------------------------------------------------------------------------
|
||||
FIND_MATCHPATTERN = "FindMatchPattern"
|
||||
FIND_MATCHREPLACE = "FindMatchReplace"
|
||||
FIND_MATCHCASE = "FindMatchCase"
|
||||
FIND_MATCHWHOLEWORD = "FindMatchWholeWordOnly"
|
||||
FIND_MATCHREGEXPR = "FindMatchRegularExpr"
|
||||
FIND_MATCHWRAP = "FindMatchWrap"
|
||||
FIND_MATCHUPDOWN = "FindMatchUpDown"
|
||||
|
||||
FIND_SYNTAXERROR = -2
|
||||
|
||||
SPACE = 10
|
||||
HALF_SPACE = 5
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Classes
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
class FindService(wx.lib.pydocview.DocService):
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Constants
|
||||
#----------------------------------------------------------------------------
|
||||
FIND_ID = wx.NewId() # for bringing up Find dialog box
|
||||
FINDONE_ID = wx.NewId() # for doing Find
|
||||
FIND_PREVIOUS_ID = wx.NewId() # for doing Find Next
|
||||
FIND_NEXT_ID = wx.NewId() # for doing Find Prev
|
||||
REPLACE_ID = wx.NewId() # for bringing up Replace dialog box
|
||||
REPLACEONE_ID = wx.NewId() # for doing a Replace
|
||||
REPLACEALL_ID = wx.NewId() # for doing Replace All
|
||||
GOTO_LINE_ID = wx.NewId() # for bringing up Goto dialog box
|
||||
|
||||
# Extending bitmasks: wx.FR_WHOLEWORD, wx.FR_MATCHCASE, and wx.FR_DOWN
|
||||
FR_REGEXP = max([wx.FR_WHOLEWORD, wx.FR_MATCHCASE, wx.FR_DOWN]) << 1
|
||||
FR_WRAP = FR_REGEXP << 1
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self._replaceDialog = None
|
||||
self._findDialog = None
|
||||
self._findReplaceData = wx.FindReplaceData()
|
||||
self._findReplaceData.SetFlags(wx.FR_DOWN)
|
||||
|
||||
|
||||
def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
|
||||
""" Install Find Service Menu Items """
|
||||
editMenu = menuBar.GetMenu(menuBar.FindMenu(_("&Edit")))
|
||||
editMenu.AppendSeparator()
|
||||
editMenu.Append(FindService.FIND_ID, _("&Find...\tCtrl+F"), _("Finds the specified text"))
|
||||
wx.EVT_MENU(frame, FindService.FIND_ID, frame.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, FindService.FIND_ID, frame.ProcessUpdateUIEvent)
|
||||
editMenu.Append(FindService.FIND_PREVIOUS_ID, _("Find &Previous\tShift+F3"), _("Finds the specified text"))
|
||||
wx.EVT_MENU(frame, FindService.FIND_PREVIOUS_ID, frame.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, FindService.FIND_PREVIOUS_ID, frame.ProcessUpdateUIEvent)
|
||||
editMenu.Append(FindService.FIND_NEXT_ID, _("Find &Next\tF3"), _("Finds the specified text"))
|
||||
wx.EVT_MENU(frame, FindService.FIND_NEXT_ID, frame.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, FindService.FIND_NEXT_ID, frame.ProcessUpdateUIEvent)
|
||||
editMenu.Append(FindService.REPLACE_ID, _("R&eplace...\tCtrl+H"), _("Replaces specific text with different text"))
|
||||
wx.EVT_MENU(frame, FindService.REPLACE_ID, frame.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, FindService.REPLACE_ID, frame.ProcessUpdateUIEvent)
|
||||
editMenu.Append(FindService.GOTO_LINE_ID, _("&Go to Line...\tCtrl+G"), _("Goes to a certain line in the file"))
|
||||
wx.EVT_MENU(frame, FindService.GOTO_LINE_ID, frame.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, FindService.GOTO_LINE_ID, frame.ProcessUpdateUIEvent)
|
||||
|
||||
# wxBug: wxToolBar::GetToolPos doesn't exist, need it to find cut tool and then insert find in front of it.
|
||||
toolBar.InsertTool(6, FindService.FIND_ID, getFindBitmap(), shortHelpString = _("Find"), longHelpString = _("Finds the specified text"))
|
||||
toolBar.InsertSeparator(6)
|
||||
toolBar.Realize()
|
||||
|
||||
frame.Bind(wx.EVT_FIND, frame.ProcessEvent)
|
||||
frame.Bind(wx.EVT_FIND_NEXT, frame.ProcessEvent)
|
||||
frame.Bind(wx.EVT_FIND_REPLACE, frame.ProcessEvent)
|
||||
frame.Bind(wx.EVT_FIND_REPLACE_ALL, frame.ProcessEvent)
|
||||
|
||||
|
||||
def ProcessUpdateUIEvent(self, event):
|
||||
id = event.GetId()
|
||||
if id == FindService.FIND_ID:
|
||||
event.Enable(False)
|
||||
return True
|
||||
elif id == FindService.FIND_PREVIOUS_ID:
|
||||
event.Enable(False)
|
||||
return True
|
||||
elif id == FindService.FIND_NEXT_ID:
|
||||
event.Enable(False)
|
||||
return True
|
||||
elif id == FindService.REPLACE_ID:
|
||||
event.Enable(False)
|
||||
return True
|
||||
elif id == FindService.GOTO_LINE_ID:
|
||||
event.Enable(False)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def ShowFindReplaceDialog(self, findString="", replace = False):
|
||||
""" Display find/replace dialog box.
|
||||
|
||||
Parameters: findString is the default value shown in the find/replace dialog input field.
|
||||
If replace is True, the replace dialog box is shown, otherwise only the find dialog box is shown.
|
||||
"""
|
||||
if replace:
|
||||
if self._findDialog != None:
|
||||
# No reason to have both find and replace dialogs up at the same time
|
||||
self._findDialog.DoClose()
|
||||
self._findDialog = None
|
||||
|
||||
self._replaceDialog = FindReplaceDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Replace"), size=(320,200), findString=findString)
|
||||
self._replaceDialog.Show(True)
|
||||
else:
|
||||
if self._replaceDialog != None:
|
||||
# No reason to have both find and replace dialogs up at the same time
|
||||
self._replaceDialog.DoClose()
|
||||
self._replaceDialog = None
|
||||
|
||||
self._findDialog = FindDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Find"), size=(320,200), findString=findString)
|
||||
self._findDialog.Show(True)
|
||||
|
||||
|
||||
|
||||
def OnFindClose(self, event):
|
||||
""" Cleanup handles when find/replace dialog is closed """
|
||||
if self._findDialog != None:
|
||||
self._findDialog = None
|
||||
elif self._replaceDialog != None:
|
||||
self._replaceDialog = None
|
||||
|
||||
|
||||
def GetCurrentDialog(self):
|
||||
""" return handle to either the find or replace dialog """
|
||||
if self._findDialog != None:
|
||||
return self._findDialog
|
||||
return self._replaceDialog
|
||||
|
||||
|
||||
def GetLineNumber(self, parent):
|
||||
""" Display Goto Line Number dialog box """
|
||||
line = -1
|
||||
dialog = wx.TextEntryDialog(parent, _("Enter line number to go to:"), _("Go to Line"))
|
||||
if dialog.ShowModal() == wx.ID_OK:
|
||||
try:
|
||||
line = int(dialog.GetValue())
|
||||
if line > 65535:
|
||||
line = 65535
|
||||
except:
|
||||
pass
|
||||
dialog.Destroy()
|
||||
# This one is ugly: wx.GetNumberFromUser("", _("Enter line number to go to:"), _("Go to Line"), 1, min = 1, max = 65535, parent = parent)
|
||||
return line
|
||||
|
||||
|
||||
def DoFind(self, findString, replaceString, text, startLoc, endLoc, down, matchCase, wholeWord, regExpr = False, replace = False, replaceAll = False, wrap = False):
|
||||
""" Do the actual work of the find/replace.
|
||||
|
||||
Returns the tuple (count, start, end, newText).
|
||||
count = number of string replacements
|
||||
start = start position of found string
|
||||
end = end position of found string
|
||||
newText = new replaced text
|
||||
"""
|
||||
flags = 0
|
||||
if regExpr:
|
||||
pattern = findString
|
||||
else:
|
||||
pattern = re.escape(findString) # Treat the strings as a literal string
|
||||
if not matchCase:
|
||||
flags = re.IGNORECASE
|
||||
if wholeWord:
|
||||
pattern = r"\b%s\b" % pattern
|
||||
|
||||
try:
|
||||
reg = re.compile(pattern, flags)
|
||||
except:
|
||||
# syntax error of some sort
|
||||
import sys
|
||||
msgTitle = wx.GetApp().GetAppName()
|
||||
if not msgTitle:
|
||||
msgTitle = _("Regular Expression Search")
|
||||
wx.MessageBox(_("Invalid regular expression \"%s\". %s") % (pattern, sys.exc_value),
|
||||
msgTitle,
|
||||
wx.OK | wx.ICON_EXCLAMATION,
|
||||
self.GetView())
|
||||
return FIND_SYNTAXERROR, None, None, None
|
||||
|
||||
if replaceAll:
|
||||
newText, count = reg.subn(replaceString, text)
|
||||
if count == 0:
|
||||
return -1, None, None, None
|
||||
else:
|
||||
return count, None, None, newText
|
||||
|
||||
start = -1
|
||||
if down:
|
||||
match = reg.search(text, endLoc)
|
||||
if match == None:
|
||||
if wrap: # try again, but this time from top of file
|
||||
match = reg.search(text, 0)
|
||||
if match == None:
|
||||
return -1, None, None, None
|
||||
else:
|
||||
return -1, None, None, None
|
||||
start = match.start()
|
||||
end = match.end()
|
||||
else:
|
||||
match = reg.search(text)
|
||||
if match == None:
|
||||
return -1, None, None, None
|
||||
found = None
|
||||
i, j = match.span()
|
||||
while i < startLoc and j <= startLoc:
|
||||
found = match
|
||||
if i == j:
|
||||
j = j + 1
|
||||
match = reg.search(text, j)
|
||||
if match == None:
|
||||
break
|
||||
i, j = match.span()
|
||||
if found == None:
|
||||
if wrap: # try again, but this time from bottom of file
|
||||
match = reg.search(text, startLoc)
|
||||
if match == None:
|
||||
return -1, None, None, None
|
||||
found = None
|
||||
i, j = match.span()
|
||||
end = len(text)
|
||||
while i < end and j <= end:
|
||||
found = match
|
||||
if i == j:
|
||||
j = j + 1
|
||||
match = reg.search(text, j)
|
||||
if match == None:
|
||||
break
|
||||
i, j = match.span()
|
||||
if found == None:
|
||||
return -1, None, None, None
|
||||
else:
|
||||
return -1, None, None, None
|
||||
start = found.start()
|
||||
end = found.end()
|
||||
|
||||
if replace and start != -1:
|
||||
newText, count = reg.subn(replaceString, text, 1)
|
||||
return count, start, end, newText
|
||||
|
||||
return 0, start, end, None
|
||||
|
||||
|
||||
def SaveFindConfig(self, findString, wholeWord, matchCase, regExpr = None, wrap = None, upDown = None, replaceString = None):
|
||||
""" Save find/replace patterns and search flags to registry.
|
||||
|
||||
findString = search pattern
|
||||
wholeWord = match whole word only
|
||||
matchCase = match case
|
||||
regExpr = use regular expressions in search pattern
|
||||
wrap = return to top/bottom of file on search
|
||||
upDown = search up or down from current cursor position
|
||||
replaceString = replace string
|
||||
"""
|
||||
config = wx.ConfigBase_Get()
|
||||
|
||||
config.Write(FIND_MATCHPATTERN, findString)
|
||||
config.WriteInt(FIND_MATCHCASE, matchCase)
|
||||
config.WriteInt(FIND_MATCHWHOLEWORD, wholeWord)
|
||||
if replaceString != None:
|
||||
config.Write(FIND_MATCHREPLACE, replaceString)
|
||||
if regExpr != None:
|
||||
config.WriteInt(FIND_MATCHREGEXPR, regExpr)
|
||||
if wrap != None:
|
||||
config.WriteInt(FIND_MATCHWRAP, wrap)
|
||||
if upDown != None:
|
||||
config.WriteInt(FIND_MATCHUPDOWN, upDown)
|
||||
|
||||
|
||||
def GetFindString(self):
|
||||
""" Load the search pattern from registry """
|
||||
return wx.ConfigBase_Get().Read(FIND_MATCHPATTERN, "")
|
||||
|
||||
|
||||
def GetReplaceString(self):
|
||||
""" Load the replace pattern from registry """
|
||||
return wx.ConfigBase_Get().Read(FIND_MATCHREPLACE, "")
|
||||
|
||||
|
||||
def GetFlags(self):
|
||||
""" Load search parameters from registry """
|
||||
config = wx.ConfigBase_Get()
|
||||
|
||||
flags = 0
|
||||
if config.ReadInt(FIND_MATCHWHOLEWORD, False):
|
||||
flags = flags | wx.FR_WHOLEWORD
|
||||
if config.ReadInt(FIND_MATCHCASE, False):
|
||||
flags = flags | wx.FR_MATCHCASE
|
||||
if config.ReadInt(FIND_MATCHUPDOWN, False):
|
||||
flags = flags | wx.FR_DOWN
|
||||
if config.ReadInt(FIND_MATCHREGEXPR, False):
|
||||
flags = flags | FindService.FR_REGEXP
|
||||
if config.ReadInt(FIND_MATCHWRAP, False):
|
||||
flags = flags | FindService.FR_WRAP
|
||||
return flags
|
||||
|
||||
|
||||
class FindDialog(wx.Dialog):
|
||||
""" Find Dialog with regular expression matching and wrap to top/bottom of file. """
|
||||
|
||||
def __init__(self, parent, id, title, size, findString=None):
|
||||
wx.Dialog.__init__(self, parent, id, title, size=size)
|
||||
|
||||
config = wx.ConfigBase_Get()
|
||||
borderSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
gridSizer = wx.GridBagSizer(SPACE, SPACE)
|
||||
|
||||
lineSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
lineSizer.Add(wx.StaticText(self, -1, _("Find what:")), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, SPACE)
|
||||
if not findString:
|
||||
findString = config.Read(FIND_MATCHPATTERN, "")
|
||||
self._findCtrl = wx.TextCtrl(self, -1, findString, size=(200,-1))
|
||||
lineSizer.Add(self._findCtrl, 0)
|
||||
gridSizer.Add(lineSizer, pos=(0,0), span=(1,2))
|
||||
choiceSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self._wholeWordCtrl = wx.CheckBox(self, -1, _("Match whole word only"))
|
||||
self._wholeWordCtrl.SetValue(config.ReadInt(FIND_MATCHWHOLEWORD, False))
|
||||
self._matchCaseCtrl = wx.CheckBox(self, -1, _("Match case"))
|
||||
self._matchCaseCtrl.SetValue(config.ReadInt(FIND_MATCHCASE, False))
|
||||
self._regExprCtrl = wx.CheckBox(self, -1, _("Regular expression"))
|
||||
self._regExprCtrl.SetValue(config.ReadInt(FIND_MATCHREGEXPR, False))
|
||||
self._wrapCtrl = wx.CheckBox(self, -1, _("Wrap"))
|
||||
self._wrapCtrl.SetValue(config.ReadInt(FIND_MATCHWRAP, False))
|
||||
choiceSizer.Add(self._wholeWordCtrl, 0, wx.BOTTOM, SPACE)
|
||||
choiceSizer.Add(self._matchCaseCtrl, 0, wx.BOTTOM, SPACE)
|
||||
choiceSizer.Add(self._regExprCtrl, 0, wx.BOTTOM, SPACE)
|
||||
choiceSizer.Add(self._wrapCtrl, 0)
|
||||
gridSizer.Add(choiceSizer, pos=(1,0), span=(2,1))
|
||||
|
||||
self._radioBox = wx.RadioBox(self, -1, _("Direction"), choices = ["Up", "Down"])
|
||||
self._radioBox.SetSelection(config.ReadInt(FIND_MATCHUPDOWN, 1))
|
||||
gridSizer.Add(self._radioBox, pos=(1,1), span=(2,1))
|
||||
|
||||
buttonSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
findBtn = wx.Button(self, FindService.FINDONE_ID, _("Find Next"))
|
||||
findBtn.SetDefault()
|
||||
wx.EVT_BUTTON(self, FindService.FINDONE_ID, self.OnActionEvent)
|
||||
cancelBtn = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
|
||||
wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnClose)
|
||||
buttonSizer.Add(findBtn, 0, wx.BOTTOM, HALF_SPACE)
|
||||
buttonSizer.Add(cancelBtn, 0)
|
||||
gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1))
|
||||
|
||||
borderSizer.Add(gridSizer, 0, wx.ALL, SPACE)
|
||||
|
||||
self.Bind(wx.EVT_CLOSE, self.OnClose)
|
||||
|
||||
self.SetSizer(borderSizer)
|
||||
self.Fit()
|
||||
self._findCtrl.SetFocus()
|
||||
|
||||
def SaveConfig(self):
|
||||
""" Save find patterns and search flags to registry. """
|
||||
findService = wx.GetApp().GetService(FindService)
|
||||
if findService:
|
||||
findService.SaveFindConfig(self._findCtrl.GetValue(),
|
||||
self._wholeWordCtrl.IsChecked(),
|
||||
self._matchCaseCtrl.IsChecked(),
|
||||
self._regExprCtrl.IsChecked(),
|
||||
self._wrapCtrl.IsChecked(),
|
||||
self._radioBox.GetSelection(),
|
||||
)
|
||||
|
||||
|
||||
def DoClose(self):
|
||||
self.SaveConfig()
|
||||
self.Destroy()
|
||||
|
||||
|
||||
def OnClose(self, event):
|
||||
findService = wx.GetApp().GetService(FindService)
|
||||
if findService:
|
||||
findService.OnFindClose(event)
|
||||
self.DoClose()
|
||||
|
||||
|
||||
def OnActionEvent(self, event):
|
||||
self.SaveConfig()
|
||||
|
||||
if wx.GetApp().GetDocumentManager().GetFlags() & wx.lib.docview.DOC_MDI:
|
||||
if wx.GetApp().GetTopWindow().ProcessEvent(event):
|
||||
return True
|
||||
else:
|
||||
view = wx.GetApp().GetDocumentManager().GetLastActiveView()
|
||||
if view and view.ProcessEvent(event):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class FindReplaceDialog(FindDialog):
|
||||
""" Find/Replace Dialog with regular expression matching and wrap to top/bottom of file. """
|
||||
|
||||
def __init__(self, parent, id, title, size, findString=None):
|
||||
wx.Dialog.__init__(self, parent, id, title, size=size)
|
||||
|
||||
config = wx.ConfigBase_Get()
|
||||
borderSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
gridSizer = wx.GridBagSizer(SPACE, SPACE)
|
||||
|
||||
gridSizer2 = wx.GridBagSizer(SPACE, SPACE)
|
||||
gridSizer2.Add(wx.StaticText(self, -1, _("Find what:")), flag=wx.ALIGN_CENTER_VERTICAL, pos=(0,0))
|
||||
if not findString:
|
||||
findString = config.Read(FIND_MATCHPATTERN, "")
|
||||
self._findCtrl = wx.TextCtrl(self, -1, findString, size=(200,-1))
|
||||
gridSizer2.Add(self._findCtrl, pos=(0,1))
|
||||
gridSizer2.Add(wx.StaticText(self, -1, _("Replace with:")), flag=wx.ALIGN_CENTER_VERTICAL, pos=(1,0))
|
||||
self._replaceCtrl = wx.TextCtrl(self, -1, config.Read(FIND_MATCHREPLACE, ""), size=(200,-1))
|
||||
gridSizer2.Add(self._replaceCtrl, pos=(1,1))
|
||||
gridSizer.Add(gridSizer2, pos=(0,0), span=(1,2))
|
||||
choiceSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self._wholeWordCtrl = wx.CheckBox(self, -1, _("Match whole word only"))
|
||||
self._wholeWordCtrl.SetValue(config.ReadInt(FIND_MATCHWHOLEWORD, False))
|
||||
self._matchCaseCtrl = wx.CheckBox(self, -1, _("Match case"))
|
||||
self._matchCaseCtrl.SetValue(config.ReadInt(FIND_MATCHCASE, False))
|
||||
self._regExprCtrl = wx.CheckBox(self, -1, _("Regular expression"))
|
||||
self._regExprCtrl.SetValue(config.ReadInt(FIND_MATCHREGEXPR, False))
|
||||
self._wrapCtrl = wx.CheckBox(self, -1, _("Wrap"))
|
||||
self._wrapCtrl.SetValue(config.ReadInt(FIND_MATCHWRAP, False))
|
||||
choiceSizer.Add(self._wholeWordCtrl, 0, wx.BOTTOM, SPACE)
|
||||
choiceSizer.Add(self._matchCaseCtrl, 0, wx.BOTTOM, SPACE)
|
||||
choiceSizer.Add(self._regExprCtrl, 0, wx.BOTTOM, SPACE)
|
||||
choiceSizer.Add(self._wrapCtrl, 0)
|
||||
gridSizer.Add(choiceSizer, pos=(1,0), span=(2,1))
|
||||
|
||||
self._radioBox = wx.RadioBox(self, -1, _("Direction"), choices = ["Up", "Down"])
|
||||
self._radioBox.SetSelection(config.ReadInt(FIND_MATCHUPDOWN, 1))
|
||||
gridSizer.Add(self._radioBox, pos=(1,1), span=(2,1))
|
||||
|
||||
buttonSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
findBtn = wx.Button(self, FindService.FINDONE_ID, _("Find Next"))
|
||||
findBtn.SetDefault()
|
||||
wx.EVT_BUTTON(self, FindService.FINDONE_ID, self.OnActionEvent)
|
||||
cancelBtn = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
|
||||
wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnClose)
|
||||
replaceBtn = wx.Button(self, FindService.REPLACEONE_ID, _("Replace"))
|
||||
wx.EVT_BUTTON(self, FindService.REPLACEONE_ID, self.OnActionEvent)
|
||||
replaceAllBtn = wx.Button(self, FindService.REPLACEALL_ID, _("Replace All"))
|
||||
wx.EVT_BUTTON(self, FindService.REPLACEALL_ID, self.OnActionEvent)
|
||||
buttonSizer.Add(findBtn, 0, wx.BOTTOM, HALF_SPACE)
|
||||
buttonSizer.Add(replaceBtn, 0, wx.BOTTOM, HALF_SPACE)
|
||||
buttonSizer.Add(replaceAllBtn, 0, wx.BOTTOM, HALF_SPACE)
|
||||
buttonSizer.Add(cancelBtn, 0)
|
||||
gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1))
|
||||
|
||||
borderSizer.Add(gridSizer, 0, wx.ALL, SPACE)
|
||||
|
||||
self.Bind(wx.EVT_CLOSE, self.OnClose)
|
||||
|
||||
self.SetSizer(borderSizer)
|
||||
self.Fit()
|
||||
self._findCtrl.SetFocus()
|
||||
|
||||
|
||||
def SaveConfig(self):
|
||||
""" Save find/replace patterns and search flags to registry. """
|
||||
findService = wx.GetApp().GetService(FindService)
|
||||
if findService:
|
||||
findService.SaveFindConfig(self._findCtrl.GetValue(),
|
||||
self._wholeWordCtrl.IsChecked(),
|
||||
self._matchCaseCtrl.IsChecked(),
|
||||
self._regExprCtrl.IsChecked(),
|
||||
self._wrapCtrl.IsChecked(),
|
||||
self._radioBox.GetSelection(),
|
||||
self._replaceCtrl.GetValue()
|
||||
)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Menu Bitmaps - generated by encode_bitmaps.py
|
||||
#----------------------------------------------------------------------------
|
||||
from wx import ImageFromStream, BitmapFromImage
|
||||
import cStringIO
|
||||
|
||||
|
||||
def getFindData():
|
||||
return \
|
||||
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
|
||||
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
|
||||
\x00\x00\x81IDAT8\x8d\xa5S\xc1\x16\xc0\x10\x0ckk\xff\xff\xc7d\x87\xad^U\r\
|
||||
\x93S\xe5U$\n\xb3$:\xc1e\x17(\x19Z\xb3$\x9e\xf1DD\xe2\x15\x01x\xea\x93\xef\
|
||||
\x04\x989\xea\x1b\xf2U\xc0\xda\xb4\xeb\x11\x1f:\xd8\xb5\xff8\x93\xd4\xa9\xae\
|
||||
@/S\xaaUwJ3\x85\xc0\x81\xee\xeb.q\x17C\x81\xd5XU \x1a\x93\xc6\x18\x8d\x90\
|
||||
\xe8}\x89\x00\x9a&\x9b_k\x94\x0c\xdf\xd78\xf8\x0b\x99Y\xb4\x08c\x9e\xfe\xc6\
|
||||
\xe3\x087\xf9\xd0D\x180\xf1#\x8e\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
|
||||
|
||||
def getFindBitmap():
|
||||
return BitmapFromImage(getFindImage())
|
||||
|
||||
|
||||
def getFindImage():
|
||||
stream = cStringIO.StringIO(getFindData())
|
||||
return ImageFromStream(stream)
|
||||
|
95
wxPython/samples/pydocview/PyDocViewDemo.py
Normal file
95
wxPython/samples/pydocview/PyDocViewDemo.py
Normal file
@@ -0,0 +1,95 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: PyDocViewDemo.py
|
||||
# Purpose: Demo of Python extensions to the wxWindows docview framework
|
||||
#
|
||||
# Author: Peter Yared, Morgan Hua
|
||||
#
|
||||
# Created: 5/15/03
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2003-2005 ActiveGrid, Inc.
|
||||
# License: ASL 2.0 http://apache.org/licenses/LICENSE-2.0
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
import sys
|
||||
import wx
|
||||
import wx.lib.docview as docview
|
||||
import wx.lib.pydocview as pydocview
|
||||
import TextEditor
|
||||
import FindService
|
||||
_ = wx.GetTranslation
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Classes
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
class TextEditorApplication(pydocview.DocApp):
|
||||
|
||||
|
||||
def OnInit(self):
|
||||
# Call the super - this is important!!!
|
||||
pydocview.DocApp.OnInit(self)
|
||||
|
||||
# Show the splash dialog while everything is loading up
|
||||
self.ShowSplash("splash.jpg")
|
||||
|
||||
# Set the name and the icon
|
||||
self.SetAppName(_("wxPython PyDocView Demo"))
|
||||
self.SetDefaultIcon(pydocview.getBlankIcon())
|
||||
|
||||
# Initialize the document manager
|
||||
docManager = docview.DocManager(flags = self.GetDefaultDocManagerFlags())
|
||||
self.SetDocumentManager(docManager)
|
||||
|
||||
# Create a template for text documents and associate it with the docmanager
|
||||
textTemplate = docview.DocTemplate(docManager,
|
||||
_("Text"),
|
||||
"*.text;*.txt",
|
||||
_("Text"),
|
||||
_(".txt"),
|
||||
_("Text Document"),
|
||||
_("Text View"),
|
||||
TextEditor.TextDocument,
|
||||
TextEditor.TextView,
|
||||
icon=pydocview.getBlankIcon())
|
||||
docManager.AssociateTemplate(textTemplate)
|
||||
|
||||
# Install services - these can install menu and toolbar items
|
||||
textService = self.InstallService(TextEditor.TextService())
|
||||
findService = self.InstallService(FindService.FindService())
|
||||
optionsService = self.InstallService(pydocview.DocOptionsService())
|
||||
windowMenuService = self.InstallService(pydocview.WindowMenuService())
|
||||
filePropertiesService = self.InstallService(pydocview.FilePropertiesService())
|
||||
aboutService = self.InstallService(pydocview.AboutService(image=wx.Image("splash.jpg")))
|
||||
|
||||
# Install the TextEditor's option panel into the OptionsService
|
||||
optionsService.AddOptionsPanel(TextEditor.TextOptionsPanel)
|
||||
|
||||
# If it is an MDI app open the main frame
|
||||
self.OpenMainFrame()
|
||||
|
||||
# Open any files that were passed via the command line
|
||||
self.OpenCommandLineArgs()
|
||||
|
||||
# If nothing was opened and it is an SDI app, open up an empty text document
|
||||
if not docManager.GetDocuments() and docManager.GetFlags() & wx.lib.docview.DOC_SDI:
|
||||
textTemplate.CreateDocument('', docview.DOC_NEW).OnNewDocument()
|
||||
|
||||
# Close the splash dialog
|
||||
self.CloseSplash()
|
||||
|
||||
# Show the tips dialog
|
||||
wx.CallAfter(self.ShowTip, wx.GetApp().GetTopWindow(), wx.CreateFileTipProvider("tips.txt", 0))
|
||||
|
||||
# Tell the framework that everything is great
|
||||
return True
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Main
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# Run the TextEditorApplication and do not redirect output to the wxPython error dialog
|
||||
app = TextEditorApplication(redirect=False)
|
||||
app.MainLoop()
|
551
wxPython/samples/pydocview/TextEditor.py
Normal file
551
wxPython/samples/pydocview/TextEditor.py
Normal file
@@ -0,0 +1,551 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: TextEditor.py
|
||||
# Purpose: Text Editor for pydocview
|
||||
#
|
||||
# Author: Peter Yared
|
||||
#
|
||||
# Created: 8/15/03
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2003-2005 ActiveGrid, Inc.
|
||||
# License: ASL 2.0 http://apache.org/licenses/LICENSE-2.0
|
||||
#----------------------------------------------------------------------------
|
||||
import wx
|
||||
import wx.lib.docview
|
||||
import wx.lib.pydocview
|
||||
import string
|
||||
import FindService
|
||||
_ = wx.GetTranslation
|
||||
|
||||
class TextDocument(wx.lib.docview.Document):
|
||||
|
||||
|
||||
def OnSaveDocument(self, filename):
|
||||
view = self.GetFirstView()
|
||||
if not view.GetTextCtrl().SaveFile(filename):
|
||||
return False
|
||||
self.Modify(False)
|
||||
self.SetDocumentSaved(True)
|
||||
#if wx.Platform == "__WXMAC__":
|
||||
# fn = wx.Filename(filename)
|
||||
# fn.MacSetDefaultTypeAndCreator()
|
||||
return True
|
||||
|
||||
|
||||
def OnOpenDocument(self, filename):
|
||||
view = self.GetFirstView()
|
||||
if not view.GetTextCtrl().LoadFile(filename):
|
||||
return False
|
||||
self.SetFilename(filename, True)
|
||||
self.Modify(False)
|
||||
self.UpdateAllViews()
|
||||
self._savedYet = True
|
||||
return True
|
||||
|
||||
|
||||
def IsModified(self):
|
||||
view = self.GetFirstView()
|
||||
if view and view.GetTextCtrl():
|
||||
return wx.lib.docview.Document.IsModified(self) or view.GetTextCtrl().IsModified()
|
||||
else:
|
||||
return wx.lib.docview.Document.IsModified(self)
|
||||
|
||||
|
||||
def Modify(self, mod):
|
||||
view = self.GetFirstView()
|
||||
wx.lib.docview.Document.Modify(self, mod)
|
||||
if not mod and view and view.GetTextCtrl():
|
||||
view.GetTextCtrl().DiscardEdits()
|
||||
|
||||
|
||||
class TextView(wx.lib.docview.View):
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Overridden methods
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
def __init__(self):
|
||||
wx.lib.docview.View.__init__(self)
|
||||
self._textCtrl = None
|
||||
self._wordWrap = wx.ConfigBase_Get().ReadInt("TextEditorWordWrap", True)
|
||||
|
||||
|
||||
def OnCreate(self, doc, flags):
|
||||
frame = wx.GetApp().CreateDocumentFrame(self, doc, flags)
|
||||
sizer = wx.BoxSizer()
|
||||
font, color = self._GetFontAndColorFromConfig()
|
||||
self._textCtrl = self._BuildTextCtrl(frame, font, color = color)
|
||||
sizer.Add(self._textCtrl, 1, wx.EXPAND, 0)
|
||||
frame.SetSizer(sizer)
|
||||
frame.Layout()
|
||||
frame.Show(True)
|
||||
self.Activate()
|
||||
return True
|
||||
|
||||
|
||||
def _BuildTextCtrl(self, parent, font, color = wx.BLACK, value = "", selection = [0, 0]):
|
||||
if self._wordWrap:
|
||||
wordWrapStyle = wx.TE_WORDWRAP
|
||||
else:
|
||||
wordWrapStyle = wx.TE_DONTWRAP
|
||||
textCtrl = wx.TextCtrl(parent, -1, pos = wx.DefaultPosition, size = parent.GetClientSize(), style = wx.TE_MULTILINE | wordWrapStyle)
|
||||
textCtrl.SetFont(font)
|
||||
textCtrl.SetForegroundColour(color)
|
||||
textCtrl.SetValue(value)
|
||||
return textCtrl
|
||||
|
||||
|
||||
def _GetFontAndColorFromConfig(self):
|
||||
font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
|
||||
config = wx.ConfigBase_Get()
|
||||
fontData = config.Read("TextEditorFont", "")
|
||||
if fontData:
|
||||
nativeFont = wx.NativeFontInfo()
|
||||
nativeFont.FromString(fontData)
|
||||
font.SetNativeFontInfo(nativeFont)
|
||||
color = wx.BLACK
|
||||
colorData = config.Read("TextEditorColor", "")
|
||||
if colorData:
|
||||
red = int("0x" + colorData[0:2], 16)
|
||||
green = int("0x" + colorData[2:4], 16)
|
||||
blue = int("0x" + colorData[4:6], 16)
|
||||
color = wx.Color(red, green, blue)
|
||||
return font, color
|
||||
|
||||
|
||||
def OnCreateCommandProcessor(self):
|
||||
# Don't create a command processor, it has its own
|
||||
pass
|
||||
|
||||
|
||||
def OnActivateView(self, activate, activeView, deactiveView):
|
||||
if activate and self._textCtrl:
|
||||
# In MDI mode just calling set focus doesn't work and in SDI mode using CallAfter causes an endless loop
|
||||
if self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI:
|
||||
self._textCtrl.SetFocus()
|
||||
else:
|
||||
def SetFocusToTextCtrl():
|
||||
if self._textCtrl: # Need to make sure it is there in case we are in the closeall mode of the MDI window
|
||||
self._textCtrl.SetFocus()
|
||||
wx.CallAfter(SetFocusToTextCtrl)
|
||||
|
||||
|
||||
def OnUpdate(self, sender = None, hint = None):
|
||||
if hint == "Word Wrap":
|
||||
self.SetWordWrap(wx.ConfigBase_Get().ReadInt("TextEditorWordWrap", True))
|
||||
elif hint == "Font":
|
||||
font, color = self._GetFontAndColorFromConfig()
|
||||
self.SetFont(font, color)
|
||||
|
||||
|
||||
def OnClose(self, deleteWindow = True):
|
||||
if not wx.lib.docview.View.OnClose(self, deleteWindow):
|
||||
return False
|
||||
self.Activate(False)
|
||||
if deleteWindow and self.GetFrame():
|
||||
self.GetFrame().Destroy()
|
||||
return True
|
||||
|
||||
|
||||
# Since ProcessEvent is not virtual, we have to trap the relevant events using this pseudo-ProcessEvent instead of EVT_MENU
|
||||
def ProcessEvent(self, event):
|
||||
id = event.GetId()
|
||||
if id == wx.ID_UNDO:
|
||||
if not self._textCtrl:
|
||||
return False
|
||||
self._textCtrl.Undo()
|
||||
return True
|
||||
elif id == wx.ID_REDO:
|
||||
if not self._textCtrl:
|
||||
return False
|
||||
self._textCtrl.Redo()
|
||||
return True
|
||||
elif id == wx.ID_CUT:
|
||||
if not self._textCtrl:
|
||||
return False
|
||||
self._textCtrl.Cut()
|
||||
return True
|
||||
elif id == wx.ID_COPY:
|
||||
if not self._textCtrl:
|
||||
return False
|
||||
self._textCtrl.Copy()
|
||||
return True
|
||||
elif id == wx.ID_PASTE:
|
||||
if not self._textCtrl:
|
||||
return False
|
||||
self._textCtrl.Paste()
|
||||
return True
|
||||
elif id == wx.ID_CLEAR:
|
||||
if not self._textCtrl:
|
||||
return False
|
||||
self._textCtrl.Replace(self._textCtrl.GetSelection()[0], self._textCtrl.GetSelection()[1], '')
|
||||
return True
|
||||
elif id == wx.ID_SELECTALL:
|
||||
if not self._textCtrl:
|
||||
return False
|
||||
self._textCtrl.SetSelection(-1, -1)
|
||||
return True
|
||||
elif id == TextService.CHOOSE_FONT_ID:
|
||||
if not self._textCtrl:
|
||||
return False
|
||||
self.OnChooseFont(event)
|
||||
return True
|
||||
elif id == TextService.WORD_WRAP_ID:
|
||||
if not self._textCtrl:
|
||||
return False
|
||||
self.OnWordWrap(event)
|
||||
return True
|
||||
elif id == FindService.FindService.FIND_ID:
|
||||
self.OnFind()
|
||||
return True
|
||||
elif id == FindService.FindService.FIND_PREVIOUS_ID:
|
||||
self.DoFind(forceFindPrevious = True)
|
||||
return True
|
||||
elif id == FindService.FindService.FIND_NEXT_ID:
|
||||
self.DoFind(forceFindNext = True)
|
||||
return True
|
||||
elif id == FindService.FindService.REPLACE_ID:
|
||||
self.OnFind(replace = True)
|
||||
return True
|
||||
elif id == FindService.FindService.FINDONE_ID:
|
||||
self.DoFind()
|
||||
return True
|
||||
elif id == FindService.FindService.REPLACEONE_ID:
|
||||
self.DoFind(replace = True)
|
||||
return True
|
||||
elif id == FindService.FindService.REPLACEALL_ID:
|
||||
self.DoFind(replaceAll = True)
|
||||
return True
|
||||
elif id == FindService.FindService.GOTO_LINE_ID:
|
||||
self.OnGotoLine(event)
|
||||
return True
|
||||
else:
|
||||
return wx.lib.docview.View.ProcessEvent(self, event)
|
||||
|
||||
|
||||
def ProcessUpdateUIEvent(self, event):
|
||||
if not self._textCtrl:
|
||||
return False
|
||||
|
||||
hasText = len(self._textCtrl.GetValue()) > 0
|
||||
|
||||
id = event.GetId()
|
||||
if id == wx.ID_UNDO:
|
||||
event.Enable(self._textCtrl.CanUndo())
|
||||
return True
|
||||
elif id == wx.ID_REDO:
|
||||
event.Enable(self._textCtrl.CanRedo())
|
||||
return True
|
||||
if id == wx.ID_CUT:
|
||||
event.Enable(self._textCtrl.CanCut())
|
||||
return True
|
||||
elif id == wx.ID_COPY:
|
||||
event.Enable(self._textCtrl.CanCopy())
|
||||
return True
|
||||
elif id == wx.ID_PASTE:
|
||||
event.Enable(self._textCtrl.CanPaste())
|
||||
return True
|
||||
elif id == wx.ID_CLEAR:
|
||||
event.Enable(self._textCtrl.CanCopy())
|
||||
return True
|
||||
elif id == wx.ID_SELECTALL:
|
||||
event.Enable(hasText)
|
||||
return True
|
||||
elif id == TextService.CHOOSE_FONT_ID:
|
||||
event.Enable(True)
|
||||
return True
|
||||
elif id == TextService.WORD_WRAP_ID:
|
||||
event.Enable(True)
|
||||
return True
|
||||
elif id == FindService.FindService.FIND_ID:
|
||||
event.Enable(hasText)
|
||||
return True
|
||||
elif id == FindService.FindService.FIND_PREVIOUS_ID:
|
||||
event.Enable(hasText and
|
||||
self._FindServiceHasString() and
|
||||
self._textCtrl.GetSelection()[0] > 0)
|
||||
return True
|
||||
elif id == FindService.FindService.FIND_NEXT_ID:
|
||||
event.Enable(hasText and
|
||||
self._FindServiceHasString() and
|
||||
self._textCtrl.GetSelection()[0] < len(self._textCtrl.GetValue()))
|
||||
return True
|
||||
elif id == FindService.FindService.REPLACE_ID:
|
||||
event.Enable(hasText)
|
||||
return True
|
||||
elif id == FindService.FindService.GOTO_LINE_ID:
|
||||
event.Enable(True)
|
||||
return True
|
||||
else:
|
||||
return wx.lib.docview.View.ProcessUpdateUIEvent(self, event)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Methods for TextDocument to call
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
def GetTextCtrl(self):
|
||||
return self._textCtrl
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Format methods
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
def OnChooseFont(self, event):
|
||||
data = wx.FontData()
|
||||
data.EnableEffects(True)
|
||||
data.SetInitialFont(self._textCtrl.GetFont())
|
||||
data.SetColour(self._textCtrl.GetForegroundColour())
|
||||
fontDialog = wx.FontDialog(self.GetFrame(), data)
|
||||
if fontDialog.ShowModal() == wx.ID_OK:
|
||||
data = fontDialog.GetFontData()
|
||||
self.SetFont(data.GetChosenFont(), data.GetColour())
|
||||
fontDialog.Destroy()
|
||||
|
||||
|
||||
def SetFont(self, font, color):
|
||||
self._textCtrl.SetFont(font)
|
||||
self._textCtrl.SetForegroundColour(color)
|
||||
self._textCtrl.Refresh()
|
||||
self._textCtrl.Layout()
|
||||
|
||||
|
||||
def OnWordWrap(self, event):
|
||||
self.SetWordWrap(not self.GetWordWrap())
|
||||
|
||||
|
||||
def GetWordWrap(self):
|
||||
return self._wordWrap
|
||||
|
||||
|
||||
def SetWordWrap(self, wordWrap = True):
|
||||
self._wordWrap = wordWrap
|
||||
temp = self._textCtrl
|
||||
self._textCtrl = self._BuildTextCtrl(temp.GetParent(),
|
||||
font = temp.GetFont(),
|
||||
color = temp.GetForegroundColour(),
|
||||
value = temp.GetValue(),
|
||||
selection = temp.GetSelection())
|
||||
self.GetDocument().Modify(temp.IsModified())
|
||||
temp.Destroy()
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Find methods
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
def OnFind(self, replace = False):
|
||||
findService = wx.GetApp().GetService(FindService.FindService)
|
||||
if findService:
|
||||
findService.ShowFindReplaceDialog(findString = self._textCtrl.GetStringSelection(), replace = replace)
|
||||
|
||||
|
||||
def DoFind(self, forceFindNext = False, forceFindPrevious = False, replace = False, replaceAll = False):
|
||||
findService = wx.GetApp().GetService(FindService.FindService)
|
||||
if not findService:
|
||||
return
|
||||
findString = findService.GetFindString()
|
||||
if len(findString) == 0:
|
||||
return -1
|
||||
replaceString = findService.GetReplaceString()
|
||||
flags = findService.GetFlags()
|
||||
startLoc, endLoc = self._textCtrl.GetSelection()
|
||||
|
||||
wholeWord = flags & wx.FR_WHOLEWORD > 0
|
||||
matchCase = flags & wx.FR_MATCHCASE > 0
|
||||
regExp = flags & FindService.FindService.FR_REGEXP > 0
|
||||
down = flags & wx.FR_DOWN > 0
|
||||
wrap = flags & FindService.FindService.FR_WRAP > 0
|
||||
|
||||
if forceFindPrevious: # this is from function keys, not dialog box
|
||||
down = False
|
||||
wrap = False # user would want to know they're at the end of file
|
||||
elif forceFindNext:
|
||||
down = True
|
||||
wrap = False # user would want to know they're at the end of file
|
||||
|
||||
# On replace dialog operations, user is allowed to replace the currently highlighted text to determine if it should be replaced or not.
|
||||
# Typically, it is the text from a previous find operation, but we must check to see if it isn't, user may have moved the cursor or selected some other text accidentally.
|
||||
# If the text is a match, then replace it.
|
||||
if replace:
|
||||
result, start, end, replText = findService.DoFind(findString, replaceString, self._textCtrl.GetStringSelection(), 0, 0, True, matchCase, wholeWord, regExp, replace)
|
||||
if result > 0:
|
||||
self._textCtrl.Replace(startLoc, endLoc, replaceString)
|
||||
self.GetDocument().Modify(True)
|
||||
wx.GetApp().GetTopWindow().PushStatusText(_("1 occurrence of \"%s\" replaced") % findString)
|
||||
if down:
|
||||
startLoc += len(replText) # advance start location past replacement string to new text
|
||||
endLoc = startLoc
|
||||
|
||||
text = self._textCtrl.GetValue()
|
||||
if wx.Platform == "__WXMSW__":
|
||||
text = string.replace(text, '\n', '\r\n')
|
||||
|
||||
# Find the next matching text occurance or if it is a ReplaceAll, replace all occurances
|
||||
# Even if the user is Replacing, we should replace here, but only select the text and let the user replace it with the next Replace operation
|
||||
result, start, end, text = findService.DoFind(findString, replaceString, text, startLoc, endLoc, down, matchCase, wholeWord, regExp, False, replaceAll, wrap)
|
||||
if result > 0:
|
||||
self._textCtrl.SetValue(text)
|
||||
self.GetDocument().Modify(True)
|
||||
if result == 1:
|
||||
wx.GetApp().GetTopWindow().PushStatusText(_("1 occurrence of \"%s\" replaced") % findString)
|
||||
else:
|
||||
wx.GetApp().GetTopWindow().PushStatusText(_("%i occurrences of \"%s\" replaced") % (result, findString))
|
||||
elif result == 0:
|
||||
self._textCtrl.SetSelection(start, end)
|
||||
self._textCtrl.SetFocus()
|
||||
wx.GetApp().GetTopWindow().PushStatusText(_("Found \"%s\"") % findString)
|
||||
else:
|
||||
wx.GetApp().GetTopWindow().PushStatusText(_("Can't find \"%s\"") % findString)
|
||||
|
||||
|
||||
def _FindServiceHasString(self):
|
||||
findService = wx.GetApp().GetService(FindService.FindService)
|
||||
if not findService or not findService.GetFindString():
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def OnGotoLine(self, event):
|
||||
findService = wx.GetApp().GetService(FindService.FindService)
|
||||
if findService:
|
||||
line = findService.GetLineNumber(self.GetDocumentManager().FindSuitableParent())
|
||||
if line > -1:
|
||||
pos = self._textCtrl.XYToPosition(0, line - 1)
|
||||
self._textCtrl.SetSelection(pos, pos)
|
||||
|
||||
|
||||
class TextService(wx.lib.pydocview.DocService):
|
||||
|
||||
|
||||
WORD_WRAP_ID = wx.NewId()
|
||||
CHOOSE_FONT_ID = wx.NewId()
|
||||
|
||||
|
||||
def __init__(self):
|
||||
wx.lib.pydocview.DocService.__init__(self)
|
||||
|
||||
|
||||
def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
|
||||
if document and document.GetDocumentTemplate().GetDocumentType() != TextDocument:
|
||||
return
|
||||
config = wx.ConfigBase_Get()
|
||||
|
||||
formatMenuIndex = menuBar.FindMenu(_("&Format"))
|
||||
if formatMenuIndex > -1:
|
||||
formatMenu = menuBar.GetMenu(formatMenuIndex)
|
||||
else:
|
||||
formatMenu = wx.Menu()
|
||||
formatMenu = wx.Menu()
|
||||
if not menuBar.FindItemById(TextService.WORD_WRAP_ID):
|
||||
formatMenu.AppendCheckItem(TextService.WORD_WRAP_ID, _("Word Wrap"), _("Wraps text horizontally when checked"))
|
||||
formatMenu.Check(TextService.WORD_WRAP_ID, config.ReadInt("TextEditorWordWrap", True))
|
||||
wx.EVT_MENU(frame, TextService.WORD_WRAP_ID, frame.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, TextService.WORD_WRAP_ID, frame.ProcessUpdateUIEvent)
|
||||
if not menuBar.FindItemById(TextService.CHOOSE_FONT_ID):
|
||||
formatMenu.Append(TextService.CHOOSE_FONT_ID, _("Font..."), _("Sets the font to use"))
|
||||
wx.EVT_MENU(frame, TextService.CHOOSE_FONT_ID, frame.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, TextService.CHOOSE_FONT_ID, frame.ProcessUpdateUIEvent)
|
||||
if formatMenuIndex == -1:
|
||||
viewMenuIndex = menuBar.FindMenu(_("&View"))
|
||||
menuBar.Insert(viewMenuIndex + 1, formatMenu, _("&Format"))
|
||||
|
||||
|
||||
def ProcessUpdateUIEvent(self, event):
|
||||
id = event.GetId()
|
||||
if id == TextService.CHOOSE_FONT_ID:
|
||||
event.Enable(False)
|
||||
return True
|
||||
elif id == TextService.WORD_WRAP_ID:
|
||||
event.Enable(False)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class TextOptionsPanel(wx.Panel):
|
||||
|
||||
|
||||
def __init__(self, parent, id):
|
||||
wx.Panel.__init__(self, parent, id)
|
||||
SPACE = 10
|
||||
HALF_SPACE = 5
|
||||
config = wx.ConfigBase_Get()
|
||||
self._textFont = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
|
||||
fontData = config.Read("TextEditorFont", "")
|
||||
if fontData:
|
||||
nativeFont = wx.NativeFontInfo()
|
||||
nativeFont.FromString(fontData)
|
||||
self._textFont.SetNativeFontInfo(nativeFont)
|
||||
self._originalTextFont = self._textFont
|
||||
self._textColor = wx.BLACK
|
||||
colorData = config.Read("TextEditorColor", "")
|
||||
if colorData:
|
||||
red = int("0x" + colorData[0:2], 16)
|
||||
green = int("0x" + colorData[2:4], 16)
|
||||
blue = int("0x" + colorData[4:6], 16)
|
||||
self._textColor = wx.Color(red, green, blue)
|
||||
self._originalTextColor = self._textColor
|
||||
parent.AddPage(self, _("Text"))
|
||||
fontLabel = wx.StaticText(self, -1, _("Font:"))
|
||||
self._sampleTextCtrl = wx.TextCtrl(self, -1, "", size = (125, -1))
|
||||
self._sampleTextCtrl.SetEditable(False)
|
||||
chooseFontButton = wx.Button(self, -1, _("Choose Font..."))
|
||||
wx.EVT_BUTTON(self, chooseFontButton.GetId(), self.OnChooseFont)
|
||||
self._wordWrapCheckBox = wx.CheckBox(self, -1, _("Wrap words inside text area"))
|
||||
self._wordWrapCheckBox.SetValue(wx.ConfigBase_Get().ReadInt("TextEditorWordWrap", True))
|
||||
textPanelBorderSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
textPanelSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
textFontSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
textFontSizer.Add(fontLabel, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.TOP, HALF_SPACE)
|
||||
textFontSizer.Add(self._sampleTextCtrl, 0, wx.ALIGN_LEFT | wx.EXPAND | wx.RIGHT, HALF_SPACE)
|
||||
textFontSizer.Add(chooseFontButton, 0, wx.ALIGN_RIGHT | wx.LEFT, HALF_SPACE)
|
||||
textPanelSizer.Add(textFontSizer, 0, wx.ALL, HALF_SPACE)
|
||||
textPanelSizer.Add(self._wordWrapCheckBox, 0, wx.ALL, HALF_SPACE)
|
||||
textPanelBorderSizer.Add(textPanelSizer, 0, wx.ALL, SPACE)
|
||||
self.SetSizer(textPanelBorderSizer)
|
||||
self.UpdateSampleFont()
|
||||
|
||||
|
||||
def UpdateSampleFont(self):
|
||||
nativeFont = wx.NativeFontInfo()
|
||||
nativeFont.FromString(self._textFont.GetNativeFontInfoDesc())
|
||||
font = wx.NullFont
|
||||
font.SetNativeFontInfo(nativeFont)
|
||||
font.SetPointSize(self._sampleTextCtrl.GetFont().GetPointSize()) # Use the standard point size
|
||||
self._sampleTextCtrl.SetFont(font)
|
||||
self._sampleTextCtrl.SetForegroundColour(self._textColor)
|
||||
self._sampleTextCtrl.SetValue(_("%d pt. %s") % (self._textFont.GetPointSize(), self._textFont.GetFaceName()))
|
||||
self._sampleTextCtrl.Refresh()
|
||||
self.Layout()
|
||||
|
||||
|
||||
def OnChooseFont(self, event):
|
||||
data = wx.FontData()
|
||||
data.EnableEffects(True)
|
||||
data.SetInitialFont(self._textFont)
|
||||
data.SetColour(self._textColor)
|
||||
fontDialog = wx.FontDialog(self, data)
|
||||
if fontDialog.ShowModal() == wx.ID_OK:
|
||||
data = fontDialog.GetFontData()
|
||||
self._textFont = data.GetChosenFont()
|
||||
self._textColor = data.GetColour()
|
||||
self.UpdateSampleFont()
|
||||
fontDialog.Destroy()
|
||||
|
||||
|
||||
def OnOK(self, optionsDialog):
|
||||
config = wx.ConfigBase_Get()
|
||||
doWordWrapUpdate = config.ReadInt("TextEditorWordWrap", True) != self._wordWrapCheckBox.GetValue()
|
||||
config.WriteInt("TextEditorWordWrap", self._wordWrapCheckBox.GetValue())
|
||||
doFontUpdate = self._originalTextFont != self._textFont or self._originalTextColor != self._textColor
|
||||
config.Write("TextEditorFont", self._textFont.GetNativeFontInfoDesc())
|
||||
config.Write("TextEditorColor", "%02x%02x%02x" % (self._textColor.Red(), self._textColor.Green(), self._textColor.Blue()))
|
||||
if doWordWrapUpdate or doFontUpdate:
|
||||
for document in optionsDialog.GetDocManager().GetDocuments():
|
||||
if document.GetDocumentTemplate().GetDocumentType() == TextDocument:
|
||||
if doWordWrapUpdate:
|
||||
document.UpdateAllViews(hint = "Word Wrap")
|
||||
if doFontUpdate:
|
||||
document.UpdateAllViews(hint = "Font")
|
BIN
wxPython/samples/pydocview/splash.jpg
Normal file
BIN
wxPython/samples/pydocview/splash.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
1
wxPython/samples/pydocview/tips.txt
Normal file
1
wxPython/samples/pydocview/tips.txt
Normal file
@@ -0,0 +1 @@
|
||||
wxPython is cool.
|
Reference in New Issue
Block a user