1 #----------------------------------------------------------------------------
2 # Name: STCTextEditor.py
3 # Purpose: Text Editor for wx.lib.pydocview tbat uses the Styled Text Control
5 # Author: Peter Yared, Morgan Hua
9 # Copyright: (c) 2003-2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
16 import wx
.lib
.multisash
17 import wx
.lib
.pydocview
24 #----------------------------------------------------------------------------
26 #----------------------------------------------------------------------------
29 VIEW_WHITESPACE_ID
= wx
.NewId()
30 VIEW_EOL_ID
= wx
.NewId()
31 VIEW_INDENTATION_GUIDES_ID
= wx
.NewId()
32 VIEW_RIGHT_EDGE_ID
= wx
.NewId()
33 VIEW_LINE_NUMBERS_ID
= wx
.NewId()
35 ZOOM_NORMAL_ID
= wx
.NewId()
36 ZOOM_IN_ID
= wx
.NewId()
37 ZOOM_OUT_ID
= wx
.NewId()
38 CHOOSE_FONT_ID
= wx
.NewId()
39 WORD_WRAP_ID
= wx
.NewId()
40 TEXT_STATUS_BAR_ID
= wx
.NewId()
43 #----------------------------------------------------------------------------
45 #----------------------------------------------------------------------------
47 class TextDocument(wx
.lib
.docview
.Document
):
50 def OnSaveDocument(self
, filename
):
51 view
= self
.GetFirstView()
52 docFile
= file(self
._documentFile
, "w")
53 docFile
.write(view
.GetValue())
56 self
.SetDocumentSaved(True)
60 def OnOpenDocument(self
, filename
):
61 view
= self
.GetFirstView()
62 docFile
= file(self
._documentFile
, 'r')
65 self
.SetFilename(filename
, True)
73 view
= self
.GetFirstView()
75 return wx
.lib
.docview
.Document
.IsModified(self
) or view
.IsModified()
77 return wx
.lib
.docview
.Document
.IsModified(self
)
80 def Modify(self
, mod
):
81 view
= self
.GetFirstView()
82 wx
.lib
.docview
.Document
.Modify(self
, mod
)
87 def OnCreateCommandProcessor(self
):
88 # Don't create a command processor, it has its own
91 # Use this to override MultiClient.Select to prevent yellow background.
92 def MultiClientSelectBGNotYellow(a
):
93 a
.GetParent().multiView
.UnSelect()
95 #a.SetBackgroundColour(wx.Colour(255,255,0)) # Yellow
98 class TextView(wx
.lib
.docview
.View
):
102 #----------------------------------------------------------------------------
104 #----------------------------------------------------------------------------
107 wx
.lib
.docview
.View
.__init
__(self
)
108 self
._textEditor
= None
109 self
._markerCount
= 0
110 self
._commandProcessor
= None
111 self
._multiSash
= None
114 def GetCtrlClass(self
):
119 # look for active one first
120 self
._textEditor
= self
._GetActiveCtrl
(self
._multiSash
)
121 if self
._textEditor
== None: # it is possible none are active
122 # look for any existing one
123 self
._textEditor
= self
._FindCtrl
(self
._multiSash
)
124 return self
._textEditor
127 ## def GetCtrls(self, parent = None):
128 ## """ Walk through the MultiSash windows and find all Ctrls """
130 ## if isinstance(parent, self.GetCtrlClass()):
132 ## if hasattr(parent, "GetChildren"):
133 ## for child in parent.GetChildren():
134 ## controls = controls + self.GetCtrls(child)
138 def OnCreate(self
, doc
, flags
):
139 frame
= wx
.GetApp().CreateDocumentFrame(self
, doc
, flags
, style
= wx
.DEFAULT_FRAME_STYLE | wx
.NO_FULL_REPAINT_ON_RESIZE
)
140 wx
.lib
.multisash
.MultiClient
.Select
= MultiClientSelectBGNotYellow
141 self
._multiSash
= wx
.lib
.multisash
.MultiSash(frame
, -1)
142 self
._multiSash
.SetDefaultChildClass(self
.GetCtrlClass()) # wxBug: MultiSash instantiates the first TextCtrl with this call
143 self
._textEditor
= self
.GetCtrl() # wxBug: grab the TextCtrl from the MultiSash datastructure
144 self
._CreateSizer
(frame
)
151 def _GetActiveCtrl(self
, parent
):
152 """ Walk through the MultiSash windows and find the active Control """
153 if isinstance(parent
, wx
.lib
.multisash
.MultiClient
) and parent
.selected
:
155 if hasattr(parent
, "GetChildren"):
156 for child
in parent
.GetChildren():
157 found
= self
._GetActiveCtrl
(child
)
163 def _FindCtrl(self
, parent
):
164 """ Walk through the MultiSash windows and find the first TextCtrl """
165 if isinstance(parent
, self
.GetCtrlClass()):
167 if hasattr(parent
, "GetChildren"):
168 for child
in parent
.GetChildren():
169 found
= self
._FindCtrl
(child
)
175 def _CreateSizer(self
, frame
):
176 sizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
177 sizer
.Add(self
._multiSash
, 1, wx
.EXPAND
)
178 frame
.SetSizer(sizer
)
179 frame
.SetAutoLayout(True)
182 def OnUpdate(self
, sender
= None, hint
= None):
183 if hint
== "ViewStuff":
184 self
.GetCtrl().SetViewDefaults()
186 font
, color
= self
.GetFontAndColorFromConfig()
187 self
.GetCtrl().SetFont(font
)
188 self
.GetCtrl().SetFontColor(color
)
191 def OnActivateView(self
, activate
, activeView
, deactiveView
):
192 if activate
and self
.GetCtrl():
193 # In MDI mode just calling set focus doesn't work and in SDI mode using CallAfter causes an endless loop
194 if self
.GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_SDI
:
195 self
.GetCtrl().SetFocus()
197 wx
.CallAfter(self
.GetCtrl().SetFocus
)
200 def OnClose(self
, deleteWindow
= True):
201 if not wx
.lib
.docview
.View
.OnClose(self
, deleteWindow
):
204 if deleteWindow
and self
.GetFrame():
205 self
.GetFrame().Destroy()
209 def ProcessEvent(self
, event
):
212 self
.GetCtrl().Undo()
214 elif id == wx
.ID_REDO
:
215 self
.GetCtrl().Redo()
217 elif id == wx
.ID_CUT
:
220 elif id == wx
.ID_COPY
:
221 self
.GetCtrl().Copy()
223 elif id == wx
.ID_PASTE
:
224 self
.GetCtrl().OnPaste()
226 elif id == wx
.ID_CLEAR
:
227 self
.GetCtrl().OnClear()
229 elif id == wx
.ID_SELECTALL
:
230 self
.GetCtrl().SetSelection(0, -1)
232 elif id == VIEW_WHITESPACE_ID
:
233 self
.GetCtrl().SetViewWhiteSpace(not self
.GetCtrl().GetViewWhiteSpace())
235 elif id == VIEW_EOL_ID
:
236 self
.GetCtrl().SetViewEOL(not self
.GetCtrl().GetViewEOL())
238 elif id == VIEW_INDENTATION_GUIDES_ID
:
239 self
.GetCtrl().SetViewIndentationGuides(not self
.GetCtrl().GetViewIndentationGuides())
241 elif id == VIEW_RIGHT_EDGE_ID
:
242 self
.GetCtrl().SetViewRightEdge(not self
.GetCtrl().GetViewRightEdge())
244 elif id == VIEW_LINE_NUMBERS_ID
:
245 self
.GetCtrl().SetViewLineNumbers(not self
.GetCtrl().GetViewLineNumbers())
247 elif id == ZOOM_NORMAL_ID
:
248 self
.GetCtrl().SetZoom(0)
250 elif id == ZOOM_IN_ID
:
251 self
.GetCtrl().CmdKeyExecute(wx
.stc
.STC_CMD_ZOOMIN
)
253 elif id == ZOOM_OUT_ID
:
254 self
.GetCtrl().CmdKeyExecute(wx
.stc
.STC_CMD_ZOOMOUT
)
256 elif id == CHOOSE_FONT_ID
:
259 elif id == WORD_WRAP_ID
:
260 self
.GetCtrl().SetWordWrap(not self
.GetCtrl().GetWordWrap())
262 elif id == FindService
.FindService
.FIND_ID
:
265 elif id == FindService
.FindService
.FIND_PREVIOUS_ID
:
266 self
.DoFind(forceFindPrevious
= True)
268 elif id == FindService
.FindService
.FIND_NEXT_ID
:
269 self
.DoFind(forceFindNext
= True)
271 elif id == FindService
.FindService
.REPLACE_ID
:
272 self
.OnFind(replace
= True)
274 elif id == FindService
.FindService
.FINDONE_ID
:
277 elif id == FindService
.FindService
.REPLACEONE_ID
:
278 self
.DoFind(replace
= True)
280 elif id == FindService
.FindService
.REPLACEALL_ID
:
281 self
.DoFind(replaceAll
= True)
283 elif id == FindService
.FindService
.GOTO_LINE_ID
:
284 self
.OnGotoLine(event
)
287 return wx
.lib
.docview
.View
.ProcessEvent(self
, event
)
290 def ProcessUpdateUIEvent(self
, event
):
291 if not self
.GetCtrl():
294 hasSelection
= self
.GetCtrl().GetSelectionStart() != self
.GetCtrl().GetSelectionEnd()
295 hasText
= self
.GetCtrl().GetTextLength() > 0
296 notOnLastChar
= self
.GetCtrl().GetSelectionStart() != self
.GetCtrl().GetTextLength()
300 event
.Enable(self
.GetCtrl().CanUndo())
301 event
.SetText(_("Undo") + '\t' + _('Ctrl+Z'))
303 elif id == wx
.ID_REDO
:
304 event
.Enable(self
.GetCtrl().CanRedo())
305 event
.SetText(_("Redo") + '\t' + _('Ctrl+Y'))
307 elif id == wx
.ID_CUT
:
308 event
.Enable(hasSelection
)
310 elif id == wx
.ID_COPY
:
311 event
.Enable(hasSelection
)
313 elif id == wx
.ID_PASTE
:
314 event
.Enable(self
.GetCtrl().CanPaste())
316 elif id == wx
.ID_CLEAR
:
317 event
.Enable(hasSelection
)
319 elif id == wx
.ID_SELECTALL
:
320 event
.Enable(hasText
)
325 elif id == VIEW_WHITESPACE_ID
:
326 event
.Enable(hasText
)
327 event
.Check(self
.GetCtrl().GetViewWhiteSpace())
329 elif id == VIEW_EOL_ID
:
330 event
.Enable(hasText
)
331 event
.Check(self
.GetCtrl().GetViewEOL())
333 elif id == VIEW_INDENTATION_GUIDES_ID
:
334 event
.Enable(hasText
)
335 event
.Check(self
.GetCtrl().GetIndentationGuides())
337 elif id == VIEW_RIGHT_EDGE_ID
:
338 event
.Enable(hasText
)
339 event
.Check(self
.GetCtrl().GetViewRightEdge())
341 elif id == VIEW_LINE_NUMBERS_ID
:
342 event
.Enable(hasText
)
343 event
.Check(self
.GetCtrl().GetViewLineNumbers())
348 elif id == ZOOM_NORMAL_ID
:
349 event
.Enable(self
.GetCtrl().GetZoom() != 0)
351 elif id == ZOOM_IN_ID
:
352 event
.Enable(self
.GetCtrl().GetZoom() < 20)
354 elif id == ZOOM_OUT_ID
:
355 event
.Enable(self
.GetCtrl().GetZoom() > -10)
357 elif id == CHOOSE_FONT_ID
:
360 elif id == WORD_WRAP_ID
:
361 event
.Enable(self
.GetCtrl().CanWordWrap())
362 event
.Check(self
.GetCtrl().CanWordWrap() and self
.GetCtrl().GetWordWrap())
364 elif id == FindService
.FindService
.FIND_ID
:
365 event
.Enable(hasText
)
367 elif id == FindService
.FindService
.FIND_PREVIOUS_ID
:
368 event
.Enable(hasText
and
369 self
._FindServiceHasString
() and
370 self
.GetCtrl().GetSelection()[0] > 0)
372 elif id == FindService
.FindService
.FIND_NEXT_ID
:
373 event
.Enable(hasText
and
374 self
._FindServiceHasString
() and
375 self
.GetCtrl().GetSelection()[0] < self
.GetCtrl().GetLength())
377 elif id == FindService
.FindService
.REPLACE_ID
:
378 event
.Enable(hasText
)
380 elif id == FindService
.FindService
.GOTO_LINE_ID
:
383 elif id == TEXT_STATUS_BAR_ID
:
384 self
.OnUpdateStatusBar(event
)
387 return wx
.lib
.docview
.View
.ProcessUpdateUIEvent(self
, event
)
390 def _GetParentFrame(self
):
391 return wx
.GetTopLevelParent(self
.GetFrame())
394 #----------------------------------------------------------------------------
395 # Methods for TextDocument to call
396 #----------------------------------------------------------------------------
398 def IsModified(self
):
399 if not self
.GetCtrl():
401 return self
.GetCtrl().GetModify()
404 def SetModifyFalse(self
):
405 self
.GetCtrl().SetSavePoint()
410 return self
.GetCtrl().GetText()
415 def SetValue(self
, value
):
416 self
.GetCtrl().SetText(value
)
417 self
.GetCtrl().UpdateLineNumberMarginWidth()
418 self
.GetCtrl().EmptyUndoBuffer()
421 #----------------------------------------------------------------------------
423 #----------------------------------------------------------------------------
425 def OnUpdateStatusBar(self
, event
):
426 statusBar
= self
._GetParentFrame
().GetStatusBar()
427 statusBar
.SetInsertMode(self
.GetCtrl().GetOvertype() == 0)
428 statusBar
.SetLineNumber(self
.GetCtrl().GetCurrentLine() + 1)
429 statusBar
.SetColumnNumber(self
.GetCtrl().GetColumn(self
.GetCtrl().GetCurrentPos()) + 1)
432 #----------------------------------------------------------------------------
434 #----------------------------------------------------------------------------
436 def OnChooseFont(self
):
438 data
.EnableEffects(True)
439 data
.SetInitialFont(self
.GetCtrl().GetFont())
440 data
.SetColour(self
.GetCtrl().GetFontColor())
441 fontDialog
= wx
.FontDialog(self
.GetFrame(), data
)
442 if fontDialog
.ShowModal() == wx
.ID_OK
:
443 data
= fontDialog
.GetFontData()
444 self
.GetCtrl().SetFont(data
.GetChosenFont())
445 self
.GetCtrl().SetFontColor(data
.GetColour())
446 self
.GetCtrl().UpdateStyles()
450 #----------------------------------------------------------------------------
452 #----------------------------------------------------------------------------
454 def OnFind(self
, replace
= False):
455 findService
= wx
.GetApp().GetService(FindService
.FindService
)
457 findService
.ShowFindReplaceDialog(findString
= self
.GetCtrl().GetSelectedText(), replace
= replace
)
460 def DoFind(self
, forceFindNext
= False, forceFindPrevious
= False, replace
= False, replaceAll
= False):
461 findService
= wx
.GetApp().GetService(FindService
.FindService
)
464 findString
= findService
.GetFindString()
465 if len(findString
) == 0:
467 replaceString
= findService
.GetReplaceString()
468 flags
= findService
.GetFlags()
469 startLoc
, endLoc
= self
.GetCtrl().GetSelection()
471 wholeWord
= flags
& wx
.FR_WHOLEWORD
> 0
472 matchCase
= flags
& wx
.FR_MATCHCASE
> 0
473 regExp
= flags
& FindService
.FindService
.FR_REGEXP
> 0
474 down
= flags
& wx
.FR_DOWN
> 0
475 wrap
= flags
& FindService
.FindService
.FR_WRAP
> 0
477 if forceFindPrevious
: # this is from function keys, not dialog box
479 wrap
= False # user would want to know they're at the end of file
482 wrap
= False # user would want to know they're at the end of file
486 # On replace dialog operations, user is allowed to replace the currently highlighted text to determine if it should be replaced or not.
487 # 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.
488 # If the text is a match, then replace it.
490 result
, start
, end
, replText
= findService
.DoFind(findString
, replaceString
, self
.GetCtrl().GetSelectedText(), 0, 0, True, matchCase
, wholeWord
, regExp
, replace
)
492 self
.GetCtrl().ReplaceSelection(replText
)
493 self
.GetDocument().Modify(True)
494 wx
.GetApp().GetTopWindow().PushStatusText(_("1 occurrence of \"%s\" replaced") % findString
)
496 startLoc
+= len(replText
) # advance start location past replacement string to new text
498 elif result
== FindService
.FIND_SYNTAXERROR
:
500 wx
.GetApp().GetTopWindow().PushStatusText(_("Invalid regular expression \"%s\"") % findString
)
503 text
= self
.GetCtrl().GetText()
505 # Find the next matching text occurance or if it is a ReplaceAll, replace all occurances
506 # 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
507 result
, start
, end
, text
= findService
.DoFind(findString
, replaceString
, text
, startLoc
, endLoc
, down
, matchCase
, wholeWord
, regExp
, False, replaceAll
, wrap
)
509 self
.GetCtrl().SetTargetStart(0)
510 self
.GetCtrl().SetTargetEnd(self
.GetCtrl().GetLength())
511 self
.GetCtrl().ReplaceTarget(text
) # Doing a SetText causes a clear document to be shown when undoing, so using replacetarget instead
512 self
.GetDocument().Modify(True)
514 wx
.GetApp().GetTopWindow().PushStatusText(_("1 occurrence of \"%s\" replaced") % findString
)
516 wx
.GetApp().GetTopWindow().PushStatusText(_("%i occurrences of \"%s\" replaced") % (result
, findString
))
518 self
.GetCtrl().SetSelection(start
, end
)
519 self
.GetCtrl().EnsureVisible(self
.GetCtrl().LineFromPosition(end
)) # show bottom then scroll up to top
520 self
.GetCtrl().EnsureVisible(self
.GetCtrl().LineFromPosition(start
)) # do this after ensuring bottom is visible
521 wx
.GetApp().GetTopWindow().PushStatusText(_("Found \"%s\".") % findString
)
522 elif result
== FindService
.FIND_SYNTAXERROR
:
523 # Dialog for this case gets popped up by the FindService.
524 wx
.GetApp().GetTopWindow().PushStatusText(_("Invalid regular expression \"%s\"") % findString
)
526 wx
.MessageBox(_("Can't find \"%s\".") % findString
, "Find",
527 wx
.OK | wx
.ICON_INFORMATION
)
530 def _FindServiceHasString(self
):
531 findService
= wx
.GetApp().GetService(FindService
.FindService
)
532 if not findService
or not findService
.GetFindString():
537 def OnGotoLine(self
, event
):
538 findService
= wx
.GetApp().GetService(FindService
.FindService
)
540 line
= findService
.GetLineNumber(self
.GetDocumentManager().FindSuitableParent())
543 self
.GetCtrl().EnsureVisible(line
)
544 self
.GetCtrl().GotoLine(line
)
547 def GotoLine(self
, lineNum
):
549 lineNum
= lineNum
- 1 # line numbering for editor is 0 based, we are 1 based.
550 self
.GetCtrl().EnsureVisibleEnforcePolicy(lineNum
)
551 self
.GetCtrl().GotoLine(lineNum
)
554 def SetSelection(self
, start
, end
):
555 self
.GetCtrl().SetSelection(start
, end
)
558 def EnsureVisible(self
, line
):
559 self
.GetCtrl().EnsureVisible(line
-1) # line numbering for editor is 0 based, we are 1 based.
561 def EnsureVisibleEnforcePolicy(self
, line
):
562 self
.GetCtrl().EnsureVisibleEnforcePolicy(line
-1) # line numbering for editor is 0 based, we are 1 based.
564 def LineFromPosition(self
, pos
):
565 return self
.GetCtrl().LineFromPosition(pos
)+1 # line numbering for editor is 0 based, we are 1 based.
568 def PositionFromLine(self
, line
):
569 return self
.GetCtrl().PositionFromLine(line
-1) # line numbering for editor is 0 based, we are 1 based.
572 def GetLineEndPosition(self
, line
):
573 return self
.GetCtrl().GetLineEndPosition(line
-1) # line numbering for editor is 0 based, we are 1 based.
576 def GetLine(self
, lineNum
):
577 return self
.GetCtrl().GetLine(lineNum
-1) # line numbering for editor is 0 based, we are 1 based.
579 def MarkerDefine(self
):
580 """ This must be called after the texteditor is instantiated """
581 self
.GetCtrl().MarkerDefine(TextView
.MARKER_NUM
, wx
.stc
.STC_MARK_CIRCLE
, wx
.BLACK
, wx
.BLUE
)
584 def MarkerToggle(self
, lineNum
= -1, marker_index
=MARKER_NUM
, mask
=MARKER_MASK
):
586 lineNum
= self
.GetCtrl().GetCurrentLine()
587 if self
.GetCtrl().MarkerGet(lineNum
) & mask
:
588 self
.GetCtrl().MarkerDelete(lineNum
, marker_index
)
589 self
._markerCount
-= 1
591 self
.GetCtrl().MarkerAdd(lineNum
, marker_index
)
592 self
._markerCount
+= 1
594 def MarkerAdd(self
, lineNum
= -1, marker_index
=MARKER_NUM
, mask
=MARKER_MASK
):
596 lineNum
= self
.GetCtrl().GetCurrentLine()
597 self
.GetCtrl().MarkerAdd(lineNum
, marker_index
)
598 self
._markerCount
+= 1
601 def MarkerDelete(self
, lineNum
= -1, marker_index
=MARKER_NUM
, mask
=MARKER_MASK
):
603 lineNum
= self
.GetCtrl().GetCurrentLine()
604 if self
.GetCtrl().MarkerGet(lineNum
) & mask
:
605 self
.GetCtrl().MarkerDelete(lineNum
, marker_index
)
606 self
._markerCount
-= 1
608 def MarkerDeleteAll(self
, marker_num
=MARKER_NUM
):
609 self
.GetCtrl().MarkerDeleteAll(marker_num
)
610 if marker_num
== self
.MARKER_NUM
:
611 self
._markerCount
= 0
614 def MarkerNext(self
, lineNum
= -1):
616 lineNum
= self
.GetCtrl().GetCurrentLine() + 1 # start search below current line
617 foundLine
= self
.GetCtrl().MarkerNext(lineNum
, self
.MARKER_MASK
)
619 # wrap to top of file
620 foundLine
= self
.GetCtrl().MarkerNext(0, self
.MARKER_MASK
)
622 wx
.GetApp().GetTopWindow().PushStatusText(_("No markers"))
625 self
.GotoLine(foundLine
+ 1)
628 def MarkerPrevious(self
, lineNum
= -1):
630 lineNum
= self
.GetCtrl().GetCurrentLine() - 1 # start search above current line
632 lineNum
= self
.GetCtrl().GetLineCount()
634 foundLine
= self
.GetCtrl().MarkerPrevious(lineNum
, self
.MARKER_MASK
)
636 # wrap to bottom of file
637 foundLine
= self
.GetCtrl().MarkerPrevious(self
.GetCtrl().GetLineCount(), self
.MARKER_MASK
)
639 wx
.GetApp().GetTopWindow().PushStatusText(_("No markers"))
642 self
.GotoLine(foundLine
+ 1)
645 def MarkerExists(self
, lineNum
= -1, mask
=MARKER_MASK
):
647 lineNum
= self
.GetCtrl().GetCurrentLine()
648 if self
.GetCtrl().MarkerGet(lineNum
) & mask
:
654 def GetMarkerCount(self
):
655 return self
._markerCount
658 class TextService(wx
.lib
.pydocview
.DocService
):
662 wx
.lib
.pydocview
.DocService
.__init
__(self
)
665 def InstallControls(self
, frame
, menuBar
= None, toolBar
= None, statusBar
= None, document
= None):
666 if document
and document
.GetDocumentTemplate().GetDocumentType() != TextDocument
:
668 if not document
and wx
.GetApp().GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_SDI
:
671 statusBar
= TextStatusBar(frame
, TEXT_STATUS_BAR_ID
)
672 frame
.SetStatusBar(statusBar
)
673 wx
.EVT_UPDATE_UI(frame
, TEXT_STATUS_BAR_ID
, frame
.ProcessUpdateUIEvent
)
675 viewMenu
= menuBar
.GetMenu(menuBar
.FindMenu(_("&View")))
677 viewMenu
.AppendSeparator()
679 textMenu
.AppendCheckItem(VIEW_WHITESPACE_ID
, _("&Whitespace"), _("Shows or hides whitespace"))
680 wx
.EVT_MENU(frame
, VIEW_WHITESPACE_ID
, frame
.ProcessEvent
)
681 wx
.EVT_UPDATE_UI(frame
, VIEW_WHITESPACE_ID
, frame
.ProcessUpdateUIEvent
)
682 textMenu
.AppendCheckItem(VIEW_EOL_ID
, _("&End of Line Markers"), _("Shows or hides indicators at the end of each line"))
683 wx
.EVT_MENU(frame
, VIEW_EOL_ID
, frame
.ProcessEvent
)
684 wx
.EVT_UPDATE_UI(frame
, VIEW_EOL_ID
, frame
.ProcessUpdateUIEvent
)
685 textMenu
.AppendCheckItem(VIEW_INDENTATION_GUIDES_ID
, _("&Indentation Guides"), _("Shows or hides indentations"))
686 wx
.EVT_MENU(frame
, VIEW_INDENTATION_GUIDES_ID
, frame
.ProcessEvent
)
687 wx
.EVT_UPDATE_UI(frame
, VIEW_INDENTATION_GUIDES_ID
, frame
.ProcessUpdateUIEvent
)
688 textMenu
.AppendCheckItem(VIEW_RIGHT_EDGE_ID
, _("&Right Edge"), _("Shows or hides the right edge marker"))
689 wx
.EVT_MENU(frame
, VIEW_RIGHT_EDGE_ID
, frame
.ProcessEvent
)
690 wx
.EVT_UPDATE_UI(frame
, VIEW_RIGHT_EDGE_ID
, frame
.ProcessUpdateUIEvent
)
691 textMenu
.AppendCheckItem(VIEW_LINE_NUMBERS_ID
, _("&Line Numbers"), _("Shows or hides the line numbers"))
692 wx
.EVT_MENU(frame
, VIEW_LINE_NUMBERS_ID
, frame
.ProcessEvent
)
693 wx
.EVT_UPDATE_UI(frame
, VIEW_LINE_NUMBERS_ID
, frame
.ProcessUpdateUIEvent
)
695 viewMenu
.AppendMenu(TEXT_ID
, _("&Text"), textMenu
)
696 wx
.EVT_UPDATE_UI(frame
, TEXT_ID
, frame
.ProcessUpdateUIEvent
)
698 isWindows
= (wx
.Platform
== '__WXMSW__')
701 zoomMenu
.Append(ZOOM_NORMAL_ID
, _("Normal Size"), _("Sets the document to its normal size"))
702 wx
.EVT_MENU(frame
, ZOOM_NORMAL_ID
, frame
.ProcessEvent
)
703 wx
.EVT_UPDATE_UI(frame
, ZOOM_NORMAL_ID
, frame
.ProcessUpdateUIEvent
)
705 zoomMenu
.Append(ZOOM_IN_ID
, _("Zoom In\tCtrl+Page Up"), _("Zooms the document to a larger size"))
707 zoomMenu
.Append(ZOOM_IN_ID
, _("Zoom In"), _("Zooms the document to a larger size"))
708 wx
.EVT_MENU(frame
, ZOOM_IN_ID
, frame
.ProcessEvent
)
709 wx
.EVT_UPDATE_UI(frame
, ZOOM_IN_ID
, frame
.ProcessUpdateUIEvent
)
711 zoomMenu
.Append(ZOOM_OUT_ID
, _("Zoom Out\tCtrl+Page Down"), _("Zooms the document to a smaller size"))
713 zoomMenu
.Append(ZOOM_OUT_ID
, _("Zoom Out"), _("Zooms the document to a smaller size"))
714 wx
.EVT_MENU(frame
, ZOOM_OUT_ID
, frame
.ProcessEvent
)
715 wx
.EVT_UPDATE_UI(frame
, ZOOM_OUT_ID
, frame
.ProcessUpdateUIEvent
)
717 viewMenu
.AppendMenu(ZOOM_ID
, _("&Zoom"), zoomMenu
)
718 wx
.EVT_UPDATE_UI(frame
, ZOOM_ID
, frame
.ProcessUpdateUIEvent
)
720 formatMenuIndex
= menuBar
.FindMenu(_("&Format"))
721 if formatMenuIndex
> -1:
722 formatMenu
= menuBar
.GetMenu(formatMenuIndex
)
724 formatMenu
= wx
.Menu()
725 if not menuBar
.FindItemById(CHOOSE_FONT_ID
):
726 formatMenu
.Append(CHOOSE_FONT_ID
, _("&Font..."), _("Sets the font to use"))
727 wx
.EVT_MENU(frame
, CHOOSE_FONT_ID
, frame
.ProcessEvent
)
728 wx
.EVT_UPDATE_UI(frame
, CHOOSE_FONT_ID
, frame
.ProcessUpdateUIEvent
)
729 if not menuBar
.FindItemById(WORD_WRAP_ID
):
730 formatMenu
.AppendCheckItem(WORD_WRAP_ID
, _("Word Wrap"), _("Wraps text horizontally when checked"))
731 wx
.EVT_MENU(frame
, WORD_WRAP_ID
, frame
.ProcessEvent
)
732 wx
.EVT_UPDATE_UI(frame
, WORD_WRAP_ID
, frame
.ProcessUpdateUIEvent
)
733 if formatMenuIndex
== -1:
734 viewMenuIndex
= menuBar
.FindMenu(_("&View"))
735 menuBar
.Insert(viewMenuIndex
+ 1, formatMenu
, _("&Format"))
737 # wxBug: wxToolBar::GetToolPos doesn't exist, need it to find cut tool and then insert find in front of it.
738 toolBar
.AddSeparator()
739 toolBar
.AddTool(ZOOM_IN_ID
, getZoomInBitmap(), shortHelpString
= _("Zoom In"), longHelpString
= _("Zooms the document to a larger size"))
740 toolBar
.AddTool(ZOOM_OUT_ID
, getZoomOutBitmap(), shortHelpString
= _("Zoom Out"), longHelpString
= _("Zooms the document to a smaller size"))
744 def ProcessUpdateUIEvent(self
, event
):
749 elif id == VIEW_WHITESPACE_ID
:
752 elif id == VIEW_EOL_ID
:
755 elif id == VIEW_INDENTATION_GUIDES_ID
:
758 elif id == VIEW_RIGHT_EDGE_ID
:
761 elif id == VIEW_LINE_NUMBERS_ID
:
767 elif id == ZOOM_NORMAL_ID
:
770 elif id == ZOOM_IN_ID
:
773 elif id == ZOOM_OUT_ID
:
776 elif id == CHOOSE_FONT_ID
:
779 elif id == WORD_WRAP_ID
:
786 class TextStatusBar(wx
.StatusBar
):
788 # wxBug: Would be nice to show num key status in statusbar, but can't figure out how to detect if it is enabled or disabled
790 def __init__(self
, parent
, id, style
= wx
.ST_SIZEGRIP
, name
= "statusBar"):
791 wx
.StatusBar
.__init
__(self
, parent
, id, style
, name
)
792 self
.SetFieldsCount(4)
793 self
.SetStatusWidths([-1, 50, 50, 55])
795 def SetInsertMode(self
, insert
= True):
800 if self
.GetStatusText(1) != newText
: # wxBug: Need to check if the text has changed, otherwise it flickers under win32
801 self
.SetStatusText(newText
, 1)
803 def SetLineNumber(self
, lineNumber
):
804 newText
= _("Ln %i") % lineNumber
805 if self
.GetStatusText(2) != newText
:
806 self
.SetStatusText(newText
, 2)
808 def SetColumnNumber(self
, colNumber
):
809 newText
= _("Col %i") % colNumber
810 if self
.GetStatusText(3) != newText
:
811 self
.SetStatusText(newText
, 3)
814 class TextOptionsPanel(wx
.Panel
):
817 def __init__(self
, parent
, id, configPrefix
= "Text", label
= "Text", hasWordWrap
= True, hasTabs
= False, addPage
=True):
818 wx
.Panel
.__init
__(self
, parent
, id)
819 self
._configPrefix
= configPrefix
820 self
._hasWordWrap
= hasWordWrap
821 self
._hasTabs
= hasTabs
824 config
= wx
.ConfigBase_Get()
825 self
._textFont
= wx
.Font(10, wx
.MODERN
, wx
.NORMAL
, wx
.NORMAL
)
826 fontData
= config
.Read(self
._configPrefix
+ "EditorFont", "")
828 nativeFont
= wx
.NativeFontInfo()
829 nativeFont
.FromString(fontData
)
830 self
._textFont
.SetNativeFontInfo(nativeFont
)
831 self
._originalTextFont
= self
._textFont
832 self
._textColor
= wx
.BLACK
833 colorData
= config
.Read(self
._configPrefix
+ "EditorColor", "")
835 red
= int("0x" + colorData
[0:2], 16)
836 green
= int("0x" + colorData
[2:4], 16)
837 blue
= int("0x" + colorData
[4:6], 16)
838 self
._textColor
= wx
.Color(red
, green
, blue
)
839 self
._originalTextColor
= self
._textColor
840 fontLabel
= wx
.StaticText(self
, -1, _("Font:"))
841 self
._sampleTextCtrl
= wx
.TextCtrl(self
, -1, "", size
= (125, 21))
842 self
._sampleTextCtrl
.SetEditable(False)
843 chooseFontButton
= wx
.Button(self
, -1, _("Choose Font..."))
844 wx
.EVT_BUTTON(self
, chooseFontButton
.GetId(), self
.OnChooseFont
)
845 if self
._hasWordWrap
:
846 self
._wordWrapCheckBox
= wx
.CheckBox(self
, -1, _("Wrap words inside text area"))
847 self
._wordWrapCheckBox
.SetValue(wx
.ConfigBase_Get().ReadInt(self
._configPrefix
+ "EditorWordWrap", False))
848 self
._viewWhitespaceCheckBox
= wx
.CheckBox(self
, -1, _("Show whitespace"))
849 self
._viewWhitespaceCheckBox
.SetValue(config
.ReadInt(self
._configPrefix
+ "EditorViewWhitespace", False))
850 self
._viewEOLCheckBox
= wx
.CheckBox(self
, -1, _("Show end of line markers"))
851 self
._viewEOLCheckBox
.SetValue(config
.ReadInt(self
._configPrefix
+ "EditorViewEOL", False))
852 self
._viewIndentationGuideCheckBox
= wx
.CheckBox(self
, -1, _("Show indentation guides"))
853 self
._viewIndentationGuideCheckBox
.SetValue(config
.ReadInt(self
._configPrefix
+ "EditorViewIndentationGuides", False))
854 self
._viewRightEdgeCheckBox
= wx
.CheckBox(self
, -1, _("Show right edge"))
855 self
._viewRightEdgeCheckBox
.SetValue(config
.ReadInt(self
._configPrefix
+ "EditorViewRightEdge", False))
856 self
._viewLineNumbersCheckBox
= wx
.CheckBox(self
, -1, _("Show line numbers"))
857 self
._viewLineNumbersCheckBox
.SetValue(config
.ReadInt(self
._configPrefix
+ "EditorViewLineNumbers", True))
859 self
._hasTabsCheckBox
= wx
.CheckBox(self
, -1, _("Use spaces instead of tabs"))
860 self
._hasTabsCheckBox
.SetValue(not wx
.ConfigBase_Get().ReadInt(self
._configPrefix
+ "EditorUseTabs", False))
861 indentWidthLabel
= wx
.StaticText(self
, -1, _("Indent Width:"))
862 self
._indentWidthChoice
= wx
.Choice(self
, -1, choices
= ["2", "4", "6", "8", "10"])
863 self
._indentWidthChoice
.SetStringSelection(str(config
.ReadInt(self
._configPrefix
+ "EditorIndentWidth", 4)))
864 textPanelBorderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
865 textPanelSizer
= wx
.BoxSizer(wx
.VERTICAL
)
866 textFontSizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
867 textFontSizer
.Add(fontLabel
, 0, wx
.ALIGN_LEFT | wx
.RIGHT | wx
.TOP
, HALF_SPACE
)
868 textFontSizer
.Add(self
._sampleTextCtrl
, 0, wx
.ALIGN_LEFT | wx
.EXPAND | wx
.RIGHT
, HALF_SPACE
)
869 textFontSizer
.Add(chooseFontButton
, 0, wx
.ALIGN_RIGHT | wx
.LEFT
, HALF_SPACE
)
870 textPanelSizer
.Add(textFontSizer
, 0, wx
.ALL
, HALF_SPACE
)
871 if self
._hasWordWrap
:
872 textPanelSizer
.Add(self
._wordWrapCheckBox
, 0, wx
.ALL
, HALF_SPACE
)
873 textPanelSizer
.Add(self
._viewWhitespaceCheckBox
, 0, wx
.ALL
, HALF_SPACE
)
874 textPanelSizer
.Add(self
._viewEOLCheckBox
, 0, wx
.ALL
, HALF_SPACE
)
875 textPanelSizer
.Add(self
._viewIndentationGuideCheckBox
, 0, wx
.ALL
, HALF_SPACE
)
876 textPanelSizer
.Add(self
._viewRightEdgeCheckBox
, 0, wx
.ALL
, HALF_SPACE
)
877 textPanelSizer
.Add(self
._viewLineNumbersCheckBox
, 0, wx
.ALL
, HALF_SPACE
)
879 textPanelSizer
.Add(self
._hasTabsCheckBox
, 0, wx
.ALL
, HALF_SPACE
)
880 textIndentWidthSizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
881 textIndentWidthSizer
.Add(indentWidthLabel
, 0, wx
.ALIGN_LEFT | wx
.RIGHT | wx
.TOP
, HALF_SPACE
)
882 textIndentWidthSizer
.Add(self
._indentWidthChoice
, 0, wx
.ALIGN_LEFT | wx
.EXPAND
, HALF_SPACE
)
883 textPanelSizer
.Add(textIndentWidthSizer
, 0, wx
.ALL
, HALF_SPACE
)
884 textPanelBorderSizer
.Add(textPanelSizer
, 0, wx
.ALL
, SPACE
)
885 ## styleButton = wx.Button(self, -1, _("Choose Style..."))
886 ## wx.EVT_BUTTON(self, styleButton.GetId(), self.OnChooseStyle)
887 ## textPanelBorderSizer.Add(styleButton, 0, wx.ALL, SPACE)
888 self
.SetSizer(textPanelBorderSizer
)
889 self
.UpdateSampleFont()
891 parent
.AddPage(self
, _(label
))
893 def UpdateSampleFont(self
):
894 nativeFont
= wx
.NativeFontInfo()
895 nativeFont
.FromString(self
._textFont
.GetNativeFontInfoDesc())
897 font
.SetNativeFontInfo(nativeFont
)
898 font
.SetPointSize(self
._sampleTextCtrl
.GetFont().GetPointSize()) # Use the standard point size
899 self
._sampleTextCtrl
.SetFont(font
)
900 self
._sampleTextCtrl
.SetForegroundColour(self
._textColor
)
901 self
._sampleTextCtrl
.SetValue(str(self
._textFont
.GetPointSize()) + _(" pt. ") + self
._textFont
.GetFaceName())
902 self
._sampleTextCtrl
.Refresh()
906 ## def OnChooseStyle(self, event):
907 ## import STCStyleEditor
909 ## base = os.path.split(__file__)[0]
910 ## config = os.path.abspath(os.path.join(base, 'stc-styles.rc.cfg'))
912 ## dlg = STCStyleEditor.STCStyleEditDlg(None,
913 ## 'Python', 'python',
923 def OnChooseFont(self
, event
):
925 data
.EnableEffects(True)
926 data
.SetInitialFont(self
._textFont
)
927 data
.SetColour(self
._textColor
)
928 fontDialog
= wx
.FontDialog(self
, data
)
929 if fontDialog
.ShowModal() == wx
.ID_OK
:
930 data
= fontDialog
.GetFontData()
931 self
._textFont
= data
.GetChosenFont()
932 self
._textColor
= data
.GetColour()
933 self
.UpdateSampleFont()
937 def OnOK(self
, optionsDialog
):
938 config
= wx
.ConfigBase_Get()
939 doViewStuffUpdate
= config
.ReadInt(self
._configPrefix
+ "EditorViewWhitespace", False) != self
._viewWhitespaceCheckBox
.GetValue()
940 config
.WriteInt(self
._configPrefix
+ "EditorViewWhitespace", self
._viewWhitespaceCheckBox
.GetValue())
941 doViewStuffUpdate
= doViewStuffUpdate
or config
.ReadInt(self
._configPrefix
+ "EditorViewEOL", False) != self
._viewEOLCheckBox
.GetValue()
942 config
.WriteInt(self
._configPrefix
+ "EditorViewEOL", self
._viewEOLCheckBox
.GetValue())
943 doViewStuffUpdate
= doViewStuffUpdate
or config
.ReadInt(self
._configPrefix
+ "EditorViewIndentationGuides", False) != self
._viewIndentationGuideCheckBox
.GetValue()
944 config
.WriteInt(self
._configPrefix
+ "EditorViewIndentationGuides", self
._viewIndentationGuideCheckBox
.GetValue())
945 doViewStuffUpdate
= doViewStuffUpdate
or config
.ReadInt(self
._configPrefix
+ "EditorViewRightEdge", False) != self
._viewRightEdgeCheckBox
.GetValue()
946 config
.WriteInt(self
._configPrefix
+ "EditorViewRightEdge", self
._viewRightEdgeCheckBox
.GetValue())
947 doViewStuffUpdate
= doViewStuffUpdate
or config
.ReadInt(self
._configPrefix
+ "EditorViewLineNumbers", True) != self
._viewLineNumbersCheckBox
.GetValue()
948 config
.WriteInt(self
._configPrefix
+ "EditorViewLineNumbers", self
._viewLineNumbersCheckBox
.GetValue())
949 if self
._hasWordWrap
:
950 doViewStuffUpdate
= doViewStuffUpdate
or config
.ReadInt(self
._configPrefix
+ "EditorWordWrap", False) != self
._wordWrapCheckBox
.GetValue()
951 config
.WriteInt(self
._configPrefix
+ "EditorWordWrap", self
._wordWrapCheckBox
.GetValue())
953 doViewStuffUpdate
= doViewStuffUpdate
or not config
.ReadInt(self
._configPrefix
+ "EditorUseTabs", True) != self
._hasTabsCheckBox
.GetValue()
954 config
.WriteInt(self
._configPrefix
+ "EditorUseTabs", not self
._hasTabsCheckBox
.GetValue())
955 newIndentWidth
= int(self
._indentWidthChoice
.GetStringSelection())
956 oldIndentWidth
= config
.ReadInt(self
._configPrefix
+ "EditorIndentWidth", 4)
957 if newIndentWidth
!= oldIndentWidth
:
958 doViewStuffUpdate
= True
959 config
.WriteInt(self
._configPrefix
+ "EditorIndentWidth", newIndentWidth
)
960 doFontUpdate
= self
._originalTextFont
!= self
._textFont
or self
._originalTextColor
!= self
._textColor
961 config
.Write(self
._configPrefix
+ "EditorFont", self
._textFont
.GetNativeFontInfoDesc())
962 config
.Write(self
._configPrefix
+ "EditorColor", "%02x%02x%02x" % (self
._textColor
.Red(), self
._textColor
.Green(), self
._textColor
.Blue()))
963 if doViewStuffUpdate
or doFontUpdate
:
964 for document
in optionsDialog
.GetDocManager().GetDocuments():
965 if issubclass(document
.GetDocumentTemplate().GetDocumentType(), TextDocument
):
966 if doViewStuffUpdate
:
967 document
.UpdateAllViews(hint
= "ViewStuff")
969 document
.UpdateAllViews(hint
= "Font")
972 class TextCtrl(wx
.stc
.StyledTextCtrl
):
974 def __init__(self
, parent
, ID
= -1, style
= wx
.NO_FULL_REPAINT_ON_RESIZE
):
977 wx
.stc
.StyledTextCtrl
.__init
__(self
, parent
, ID
, style
= style
)
980 self
._fontColor
= None
982 self
.SetVisiblePolicy(wx
.stc
.STC_VISIBLE_STRICT
,0)
983 self
.SetYCaretPolicy(0, 0)
985 self
.CmdKeyClear(wx
.stc
.STC_KEY_ADD
, wx
.stc
.STC_SCMOD_CTRL
)
986 self
.CmdKeyClear(wx
.stc
.STC_KEY_SUBTRACT
, wx
.stc
.STC_SCMOD_CTRL
)
987 self
.CmdKeyAssign(wx
.stc
.STC_KEY_PRIOR
, wx
.stc
.STC_SCMOD_CTRL
, wx
.stc
.STC_CMD_ZOOMIN
)
988 self
.CmdKeyAssign(wx
.stc
.STC_KEY_NEXT
, wx
.stc
.STC_SCMOD_CTRL
, wx
.stc
.STC_CMD_ZOOMOUT
)
989 self
.Bind(wx
.stc
.EVT_STC_ZOOM
, self
.OnUpdateLineNumberMarginWidth
) # auto update line num width on zoom
990 wx
.EVT_KEY_DOWN(self
, self
.OnKeyPressed
)
997 self
.SetViewWhiteSpace(False)
998 self
.SetEOLMode(wx
.stc
.STC_EOL_LF
)
999 self
.SetEdgeMode(wx
.stc
.STC_EDGE_NONE
)
1000 self
.SetEdgeColumn(78)
1002 self
.SetMarginType(1, wx
.stc
.STC_MARGIN_NUMBER
)
1003 self
.SetMarginWidth(1, self
.EstimatedLineNumberMarginWidth())
1006 self
.SetCaretForeground("BLACK")
1008 self
.SetViewDefaults()
1009 font
, color
= self
.GetFontAndColorFromConfig()
1011 self
.SetFontColor(color
)
1012 self
.MarkerDefineDefault()
1014 # for multisash initialization
1015 if isinstance(parent
, wx
.lib
.multisash
.MultiClient
):
1016 while parent
.GetParent():
1017 parent
= parent
.GetParent()
1018 if hasattr(parent
, "GetView"):
1020 if hasattr(parent
, "GetView"):
1021 textEditor
= parent
.GetView()._textEditor
1023 doc
= textEditor
.GetDocPointer()
1025 self
.SetDocPointer(doc
)
1029 def SetViewDefaults(self
, configPrefix
= "Text", hasWordWrap
= True, hasTabs
= False):
1030 config
= wx
.ConfigBase_Get()
1031 self
.SetViewWhiteSpace(config
.ReadInt(configPrefix
+ "EditorViewWhitespace", False))
1032 self
.SetViewEOL(config
.ReadInt(configPrefix
+ "EditorViewEOL", False))
1033 self
.SetIndentationGuides(config
.ReadInt(configPrefix
+ "EditorViewIndentationGuides", False))
1034 self
.SetViewRightEdge(config
.ReadInt(configPrefix
+ "EditorViewRightEdge", False))
1035 self
.SetViewLineNumbers(config
.ReadInt(configPrefix
+ "EditorViewLineNumbers", True))
1037 self
.SetWordWrap(config
.ReadInt(configPrefix
+ "EditorWordWrap", False))
1038 if hasTabs
: # These methods do not exist in STCTextEditor and are meant for subclasses
1039 self
.SetUseTabs(config
.ReadInt(configPrefix
+ "EditorUseTabs", False))
1040 self
.SetIndent(config
.ReadInt(configPrefix
+ "EditorIndentWidth", 4))
1041 self
.SetTabWidth(config
.ReadInt(configPrefix
+ "EditorIndentWidth", 4))
1043 self
.SetUseTabs(True)
1049 def GetDefaultFont(self
):
1050 """ Subclasses should override this """
1051 return wx
.Font(10, wx
.MODERN
, wx
.NORMAL
, wx
.NORMAL
)
1054 def GetDefaultColor(self
):
1055 """ Subclasses should override this """
1059 def GetFontAndColorFromConfig(self
, configPrefix
= "Text"):
1060 font
= self
.GetDefaultFont()
1061 config
= wx
.ConfigBase_Get()
1062 fontData
= config
.Read(configPrefix
+ "EditorFont", "")
1064 nativeFont
= wx
.NativeFontInfo()
1065 nativeFont
.FromString(fontData
)
1066 font
.SetNativeFontInfo(nativeFont
)
1067 color
= self
.GetDefaultColor()
1068 colorData
= config
.Read(configPrefix
+ "EditorColor", "")
1070 red
= int("0x" + colorData
[0:2], 16)
1071 green
= int("0x" + colorData
[2:4], 16)
1072 blue
= int("0x" + colorData
[4:6], 16)
1073 color
= wx
.Color(red
, green
, blue
)
1080 def SetFont(self
, font
):
1082 self
.StyleSetFont(wx
.stc
.STC_STYLE_DEFAULT
, self
._font
)
1085 def GetFontColor(self
):
1086 return self
._fontColor
1089 def SetFontColor(self
, fontColor
= wx
.BLACK
):
1090 self
._fontColor
= fontColor
1091 self
.StyleSetForeground(wx
.stc
.STC_STYLE_DEFAULT
, "#%02x%02x%02x" % (self
._fontColor
.Red(), self
._fontColor
.Green(), self
._fontColor
.Blue()))
1094 def UpdateStyles(self
):
1095 self
.StyleClearAll()
1099 def EstimatedLineNumberMarginWidth(self
):
1102 lineNum
= self
.GetLineCount()
1103 lineNum
= lineNum
/100
1104 while lineNum
>= 10:
1105 lineNum
= lineNum
/10
1106 baseNumbers
= baseNumbers
+ "0"
1108 return self
.TextWidth(wx
.stc
.STC_STYLE_LINENUMBER
, baseNumbers
) + MARGIN
1111 def OnUpdateLineNumberMarginWidth(self
, event
):
1112 self
.UpdateLineNumberMarginWidth()
1115 def UpdateLineNumberMarginWidth(self
):
1116 if self
.GetViewLineNumbers():
1117 self
.SetMarginWidth(1, self
.EstimatedLineNumberMarginWidth())
1119 def MarkerDefineDefault(self
):
1120 """ This must be called after the textcontrol is instantiated """
1121 self
.MarkerDefine(TextView
.MARKER_NUM
, wx
.stc
.STC_MARK_ROUNDRECT
, wx
.BLACK
, wx
.BLUE
)
1125 # Used when Delete key is hit.
1126 sel
= self
.GetSelection()
1128 # Delete the selection or if no selection, the character after the caret.
1129 if sel
[0] == sel
[1]:
1130 self
.SetSelection(sel
[0], sel
[0] + 1)
1132 # remove any folded lines also.
1133 startLine
= self
.LineFromPosition(sel
[0])
1134 endLine
= self
.LineFromPosition(sel
[1])
1135 endLineStart
= self
.PositionFromLine(endLine
)
1136 if startLine
!= endLine
and sel
[1] - endLineStart
== 0:
1137 while not self
.GetLineVisible(endLine
):
1139 self
.SetSelectionEnd(self
.PositionFromLine(endLine
))
1145 # replace any folded lines also.
1146 sel
= self
.GetSelection()
1147 startLine
= self
.LineFromPosition(sel
[0])
1148 endLine
= self
.LineFromPosition(sel
[1])
1149 endLineStart
= self
.PositionFromLine(endLine
)
1150 if startLine
!= endLine
and sel
[1] - endLineStart
== 0:
1151 while not self
.GetLineVisible(endLine
):
1153 self
.SetSelectionEnd(self
.PositionFromLine(endLine
))
1158 def OnKeyPressed(self
, event
):
1159 key
= event
.GetKeyCode()
1160 if key
== wx
.WXK_NUMPAD_ADD
: #wxBug: For whatever reason, the key accelerators for numpad add and subtract with modifiers are not working so have to trap them here
1161 if event
.ControlDown():
1162 self
.ToggleFoldAll(expand
= True, topLevelOnly
= True)
1163 elif event
.ShiftDown():
1164 self
.ToggleFoldAll(expand
= True)
1166 self
.ToggleFold(self
.GetCurrentLine())
1167 elif key
== wx
.WXK_NUMPAD_SUBTRACT
:
1168 if event
.ControlDown():
1169 self
.ToggleFoldAll(expand
= False, topLevelOnly
= True)
1170 elif event
.ShiftDown():
1171 self
.ToggleFoldAll(expand
= False)
1173 self
.ToggleFold(self
.GetCurrentLine())
1178 #----------------------------------------------------------------------------
1180 #----------------------------------------------------------------------------
1182 def GetViewRightEdge(self
):
1183 return self
.GetEdgeMode() != wx
.stc
.STC_EDGE_NONE
1186 def SetViewRightEdge(self
, viewRightEdge
):
1188 self
.SetEdgeMode(wx
.stc
.STC_EDGE_LINE
)
1190 self
.SetEdgeMode(wx
.stc
.STC_EDGE_NONE
)
1193 def GetViewLineNumbers(self
):
1194 return self
.GetMarginWidth(1) > 0
1197 def SetViewLineNumbers(self
, viewLineNumbers
= True):
1199 self
.SetMarginWidth(1, self
.EstimatedLineNumberMarginWidth())
1201 self
.SetMarginWidth(1, 0)
1204 def CanWordWrap(self
):
1208 def GetWordWrap(self
):
1209 return self
.GetWrapMode() == wx
.stc
.STC_WRAP_WORD
1212 def SetWordWrap(self
, wordWrap
):
1214 self
.SetWrapMode(wx
.stc
.STC_WRAP_WORD
)
1216 self
.SetWrapMode(wx
.stc
.STC_WRAP_NONE
)
1219 #----------------------------------------------------------------------------
1220 # Icon Bitmaps - generated by encode_bitmaps.py
1221 #----------------------------------------------------------------------------
1222 from wx
import ImageFromStream
, BitmapFromImage
1223 from wx
import EmptyIcon
1229 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
1230 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
1231 \x00\x00`IDAT8\x8d\xed\x931\x0e\xc00\x08\x03m\x92\xff\xff8q\xa7JU!$\x12\x1d\
1232 \xeb\t\t8n\x81\xb4\x86J\xfa]h\x0ee\x83\xb4\xc6\x14\x00\x00R\xcc \t\xcd\xa1\
1233 \x08\xd2\xa3\xe1\x08*\t$\x1d\xc4\x012\x0b\x00\xce\xe4\xc8\xe0\t}\xf7\x8f\rV\
1234 \xd9\x1a\xec\xe0\xbf\xc1\xd7\x06\xd9\xf5UX\xfdF+m\x03\xb8\x00\xe4\xc74B"x\
1235 \xf1\xf4\x00\x00\x00\x00IEND\xaeB`\x82'
1238 def getTextBitmap():
1239 return BitmapFromImage(getTextImage())
1242 stream
= cStringIO
.StringIO(getTextData())
1243 return ImageFromStream(stream
)
1247 icon
.CopyFromBitmap(getTextBitmap())
1251 #----------------------------------------------------------------------------
1252 # Menu Bitmaps - generated by encode_bitmaps.py
1253 #----------------------------------------------------------------------------
1254 #----------------------------------------------------------------------
1255 def getZoomInData():
1257 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
1258 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
1259 \x00\x00wIDAT8\x8d\xa5\x93Q\x12\x80 \x08D\xb5\xe9X\xee\xe9\xb7{\xd5Gc\xa9\
1260 \xacX\xca\x1f\xa0\x8fE0\x92<\xc3\x82\xed*\x08\xa0\xf2I~\x07\x000\x17T,\xdb\
1261 \xd6;\x08\xa4\x00\xa4GA\xab\xca\x00\xbc*\x1eD\xb4\x90\xa4O\x1e\xe3\x16f\xcc(\
1262 \xc8\x95F\x95\x8d\x02\xef\xa1n\xa0\xce\xc5v\x91zc\xacU\xbey\x03\xf0.\xa8\xb8\
1263 \x04\x8c\xac\x04MM\xa1lA\xfe\x85?\x90\xe5=X\x06\\\xebCA\xb3Q\xf34\x14\x00\
1264 \x00\x00\x00IEND\xaeB`\x82'
1266 def getZoomInBitmap():
1267 return BitmapFromImage(getZoomInImage())
1269 def getZoomInImage():
1270 stream
= cStringIO
.StringIO(getZoomInData())
1271 return ImageFromStream(stream
)
1273 #----------------------------------------------------------------------
1274 def getZoomOutData():
1276 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
1277 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
1278 \x00\x00qIDAT8\x8d\xa5\x92Q\x0e\xc0 \x08C-z\xff\x13O\xd9\xd7\x16"\x05\x8d\
1279 \xf6O\xa2\x8f"\x05\xa4\x96\x1b5V\xd4\xd1\xd5\x9e!\x15\xdb\x00\x1d]\xe7\x07\
1280 \xac\xf6Iv.B*fW\x0e\x90u\xc9 d\x84\x87v\x82\xb4\xf5\x08\'r\x0e\xa2N\x91~\x07\
1281 \xd9G\x95\xe2W\xeb\x00\x19\xc4\xd6\\FX\x12\xa3 \xb1:\x05\xacdAG[\xb0y9r`u\
1282 \x9d\x83k\xc0\x0b#3@0A\x0c"\x93\x00\x00\x00\x00IEND\xaeB`\x82'
1285 def getZoomOutBitmap():
1286 return BitmapFromImage(getZoomOutImage())
1288 def getZoomOutImage():
1289 stream
= cStringIO
.StringIO(getZoomOutData())
1290 return ImageFromStream(stream
)