3 import wx
.richtext
as rt
6 #----------------------------------------------------------------------
8 class RichTextFrame(wx
.Frame
):
9 def __init__(self
, *args
, **kw
):
10 wx
.Frame
.__init
__(self
, *args
, **kw
)
14 self
.CreateStatusBar()
15 self
.SetStatusText("Welcome to wx.richtext.RichTextCtrl!")
17 self
.rtc
= rt
.RichTextCtrl(self
, style
=wx
.VSCROLL|wx
.HSCROLL|wx
.NO_BORDER
);
18 wx
.CallAfter(self
.rtc
.SetFocus
)
21 self
.rtc
.BeginSuppressUndo()
23 self
.rtc
.BeginParagraphSpacing(0, 20)
25 self
.rtc
.BeginAlignment(rt
.TEXT_ALIGNMENT_CENTRE
)
28 self
.rtc
.BeginFontSize(14)
29 self
.rtc
.WriteText("Welcome to wxRichTextCtrl, a wxWidgets control for editing and presenting styled text and images")
30 self
.rtc
.EndFontSize()
33 self
.rtc
.BeginItalic()
34 self
.rtc
.WriteText("by Julian Smart")
40 self
.rtc
.WriteImage(images
.get_rt_zebraImage())
42 self
.rtc
.EndAlignment()
47 self
.rtc
.WriteText("What can you do with this thing? ")
48 self
.rtc
.WriteImage(images
.get_rt_smileyImage())
49 self
.rtc
.WriteText(" Well, you can change text ")
51 self
.rtc
.BeginTextColour((255, 0, 0))
52 self
.rtc
.WriteText("colour, like this red bit.")
53 self
.rtc
.EndTextColour()
55 self
.rtc
.BeginTextColour((0, 0, 255))
56 self
.rtc
.WriteText(" And this blue bit.")
57 self
.rtc
.EndTextColour()
59 self
.rtc
.WriteText(" Naturally you can make things ")
61 self
.rtc
.WriteText("bold ")
63 self
.rtc
.BeginItalic()
64 self
.rtc
.WriteText("or italic ")
66 self
.rtc
.BeginUnderline()
67 self
.rtc
.WriteText("or underlined.")
68 self
.rtc
.EndUnderline()
70 self
.rtc
.BeginFontSize(14)
71 self
.rtc
.WriteText(" Different font sizes on the same line is allowed, too.")
72 self
.rtc
.EndFontSize()
74 self
.rtc
.WriteText(" Next we'll show an indented paragraph.")
76 self
.rtc
.BeginLeftIndent(60)
79 self
.rtc
.WriteText("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable.")
80 self
.rtc
.EndLeftIndent()
84 self
.rtc
.WriteText("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40).")
86 self
.rtc
.BeginLeftIndent(100, -40)
89 self
.rtc
.WriteText("It was in January, the most down-trodden month of an Edinburgh winteself.rtc. An attractive woman came into the cafe, which is nothing remarkable.")
90 self
.rtc
.EndLeftIndent()
94 self
.rtc
.WriteText("Numbered bullets are possible, again using subindents:")
96 self
.rtc
.BeginNumberedBullet(1, 100, 60)
99 self
.rtc
.WriteText("This is my first item. Note that wxRichTextCtrl doesn't automatically do numbering, but this will be added later.")
100 self
.rtc
.EndNumberedBullet()
102 self
.rtc
.BeginNumberedBullet(2, 100, 60)
105 self
.rtc
.WriteText("This is my second item.")
106 self
.rtc
.EndNumberedBullet()
110 self
.rtc
.WriteText("The following paragraph is right-indented:")
112 self
.rtc
.BeginRightIndent(200)
115 self
.rtc
.WriteText("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable.")
116 self
.rtc
.EndRightIndent()
120 self
.rtc
.WriteText("The following paragraph is right-aligned with 1.5 line spacing:")
122 self
.rtc
.BeginAlignment(rt
.TEXT_ALIGNMENT_RIGHT
)
123 self
.rtc
.BeginLineSpacing(rt
.TEXT_ATTR_LINE_SPACING_HALF
)
126 self
.rtc
.WriteText("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable.")
127 self
.rtc
.EndLineSpacing()
128 self
.rtc
.EndAlignment()
131 self
.rtc
.WriteText("Other notable features of wxRichTextCtrl include:")
133 self
.rtc
.BeginSymbolBullet('*', 100, 60)
135 self
.rtc
.WriteText("Compatibility with wxTextCtrl API")
136 self
.rtc
.EndSymbolBullet()
138 self
.rtc
.BeginSymbolBullet('*', 100, 60)
140 self
.rtc
.WriteText("Easy stack-based BeginXXX()...EndXXX() style setting in addition to SetStyle()")
141 self
.rtc
.EndSymbolBullet()
143 self
.rtc
.BeginSymbolBullet('*', 100, 60)
145 self
.rtc
.WriteText("XML loading and saving")
146 self
.rtc
.EndSymbolBullet()
148 self
.rtc
.BeginSymbolBullet('*', 100, 60)
150 self
.rtc
.WriteText("Undo/Redo, with batching option and Undo suppressing")
151 self
.rtc
.EndSymbolBullet()
153 self
.rtc
.BeginSymbolBullet('*', 100, 60)
155 self
.rtc
.WriteText("Clipboard copy and paste")
156 self
.rtc
.EndSymbolBullet()
158 self
.rtc
.BeginSymbolBullet('*', 100, 60)
160 self
.rtc
.WriteText("wxRichTextStyleSheet with named character and paragraph styles, and control for applying named styles")
161 self
.rtc
.EndSymbolBullet()
163 self
.rtc
.BeginSymbolBullet('*', 100, 60)
165 self
.rtc
.WriteText("A design that can easily be extended to other content types, ultimately with text boxes, tables, controls, and so on")
166 self
.rtc
.EndSymbolBullet()
170 self
.rtc
.WriteText("Note: this sample content was generated programmatically from within the MyFrame constructor in the demo. The images were loaded from inline XPMs. Enjoy wxRichTextCtrl!")
172 self
.rtc
.EndParagraphSpacing()
174 self
.rtc
.EndSuppressUndo()
177 def OnFileOpen(self
, evt
):
178 # TODO: Use RichTextBuffer.GetExtWildcard to get the wildcard string
179 dlg
= wx
.FileDialog(self
, "Choose a filename",
180 wildcard
="All files (*.*)|*.*",
182 if dlg
.ShowModal() == wx
.ID_OK
:
185 # TODO: use the filter index to determine what file type to use
186 self
.rtc
.LoadFile(path
, rt
.RICHTEXT_TYPE_TEXT
)
190 def OnFileSave(self
, evt
):
191 if not self
.rtc
.GetFilename():
192 self
.OnFileSaveAs(evt
)
196 def OnFileSaveAs(self
, evt
):
197 # TODO: Use RichTextBuffer.GetExtWildcard to get the wildcard string
198 dlg
= wx
.FileDialog(self
, "Choose a filename",
199 wildcard
="All files (*.*)|*.*",
201 if dlg
.ShowModal() == wx
.ID_OK
:
204 self
.rtc
.SaveFile(path
)
207 def OnFileViewHTML(self
, evt
): pass
210 def OnFileExit(self
, evt
):
214 def OnBold(self
, evt
):
215 self
.rtc
.ApplyBoldToSelection()
217 def OnItalic(self
, evt
):
218 self
.rtc
.ApplyItalicToSelection()
220 def OnUnderline(self
, evt
):
221 self
.rtc
.ApplyUnderlineToSelection()
223 def OnAlignLeft(self
, evt
):
224 self
.rtc
.ApplyAlignmentToSelection(rt
.TEXT_ALIGNMENT_LEFT
)
226 def OnAlignRight(self
, evt
):
227 self
.rtc
.ApplyAlignmentToSelection(rt
.TEXT_ALIGNMENT_RIGHT
)
229 def OnAlignCenter(self
, evt
):
230 self
.rtc
.ApplyAlignmentToSelection(rt
.TEXT_ALIGNMENT_CENTRE
)
232 def OnIndentMore(self
, evt
):
233 attr
= rt
.RichTextAttr()
234 attr
.SetFlags(rt
.TEXT_ATTR_LEFT_INDENT
)
235 ip
= self
.rtc
.GetInsertionPoint()
236 if self
.rtc
.GetStyle(ip
, attr
):
237 r
= rt
.RichTextRange(ip
, ip
)
238 if self
.rtc
.HasSelection():
239 r
= self
.rtc
.GetSelectionRange()
241 attr
.SetLeftIndent(attr
.GetLeftIndent() + 100)
242 attr
.SetFlags(rt
.TEXT_ATTR_LEFT_INDENT
)
243 self
.rtc
.SetStyle(r
, attr
)
246 def OnIndentLess(self
, evt
):
247 attr
= rt
.RichTextAttr()
248 attr
.SetFlags(rt
.TEXT_ATTR_LEFT_INDENT
)
249 ip
= self
.rtc
.GetInsertionPoint()
250 if self
.rtc
.GetStyle(ip
, attr
):
251 r
= rt
.RichTextRange(ip
, ip
)
252 if self
.rtc
.HasSelection():
253 r
= self
.rtc
.GetSelectionRange()
255 if attr
.GetLeftIndent() >= 100:
256 attr
.SetLeftIndent(attr
.GetLeftIndent() - 100)
257 attr
.SetFlags(rt
.TEXT_ATTR_LEFT_INDENT
)
258 self
.rtc
.SetStyle(r
, attr
)
261 def OnParagraphSpacingMore(self
, evt
):
262 attr
= rt
.RichTextAttr()
263 attr
.SetFlags(rt
.TEXT_ATTR_PARA_SPACING_AFTER
)
264 ip
= self
.rtc
.GetInsertionPoint()
265 if self
.rtc
.GetStyle(ip
, attr
):
266 r
= rt
.RichTextRange(ip
, ip
)
267 if self
.rtc
.HasSelection():
268 r
= self
.rtc
.GetSelectionRange()
270 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() + 20);
271 attr
.SetFlags(rt
.TEXT_ATTR_PARA_SPACING_AFTER
)
272 self
.rtc
.SetStyle(r
, attr
)
275 def OnParagraphSpacingLess(self
, evt
):
276 attr
= rt
.RichTextAttr()
277 attr
.SetFlags(rt
.TEXT_ATTR_PARA_SPACING_AFTER
)
278 ip
= self
.rtc
.GetInsertionPoint()
279 if self
.rtc
.GetStyle(ip
, attr
):
280 r
= rt
.RichTextRange(ip
, ip
)
281 if self
.rtc
.HasSelection():
282 r
= self
.rtc
.GetSelectionRange()
284 if attr
.GetParagraphSpacingAfter() >= 20:
285 attr
.SetParagraphSpacingAfter(attr
.GetParagraphSpacingAfter() - 20);
286 attr
.SetFlags(rt
.TEXT_ATTR_PARA_SPACING_AFTER
)
287 self
.rtc
.SetStyle(r
, attr
)
290 def OnLineSpacingSingle(self
, evt
):
291 attr
= rt
.RichTextAttr()
292 attr
.SetFlags(rt
.TEXT_ATTR_LINE_SPACING
)
293 ip
= self
.rtc
.GetInsertionPoint()
294 if self
.rtc
.GetStyle(ip
, attr
):
295 r
= rt
.RichTextRange(ip
, ip
)
296 if self
.rtc
.HasSelection():
297 r
= self
.rtc
.GetSelectionRange()
299 attr
.SetFlags(rt
.TEXT_ATTR_LINE_SPACING
)
300 attr
.SetLineSpacing(10)
301 self
.rtc
.SetStyle(r
, attr
)
304 def OnLineSpacingHalf(self
, evt
):
305 attr
= rt
.RichTextAttr()
306 attr
.SetFlags(rt
.TEXT_ATTR_LINE_SPACING
)
307 ip
= self
.rtc
.GetInsertionPoint()
308 if self
.rtc
.GetStyle(ip
, attr
):
309 r
= rt
.RichTextRange(ip
, ip
)
310 if self
.rtc
.HasSelection():
311 r
= self
.rtc
.GetSelectionRange()
313 attr
.SetFlags(rt
.TEXT_ATTR_LINE_SPACING
)
314 attr
.SetLineSpacing(15)
315 self
.rtc
.SetStyle(r
, attr
)
318 def OnLineSpacingDouble(self
, evt
):
319 attr
= rt
.RichTextAttr()
320 attr
.SetFlags(rt
.TEXT_ATTR_LINE_SPACING
)
321 ip
= self
.rtc
.GetInsertionPoint()
322 if self
.rtc
.GetStyle(ip
, attr
):
323 r
= rt
.RichTextRange(ip
, ip
)
324 if self
.rtc
.HasSelection():
325 r
= self
.rtc
.GetSelectionRange()
327 attr
.SetFlags(rt
.TEXT_ATTR_LINE_SPACING
)
328 attr
.SetLineSpacing(20)
329 self
.rtc
.SetStyle(r
, attr
)
332 def OnFont(self
, evt
):
333 if not self
.rtc
.HasSelection():
336 r
= self
.rtc
.GetSelectionRange()
337 fontData
= wx
.FontData()
338 attr
= rt
.RichTextAttr()
339 attr
.SetFlags(rt
.TEXT_ATTR_FONT
)
340 if self
.rtc
.GetStyle(self
.rtc
.GetInsertionPoint(), attr
):
341 fontData
.SetInitialFont(attr
.CreateFont())
343 dlg
= wx
.FontDialog(self
, fontData
)
344 if dlg
.ShowModal() == wx
.ID_OK
:
345 fontData
= dlg
.GetFontData()
346 font
= fontData
.GetChosenFont()
348 attr
.SetFlags(rt
.TEXT_ATTR_FONT
)
350 self
.rtc
.SetStyle(r
, attr
)
354 def OnUpdateBold(self
, evt
):
355 evt
.Check(self
.rtc
.IsSelectionBold())
357 def OnUpdateItalic(self
, evt
):
358 evt
.Check(self
.rtc
.IsSelectionItalics())
360 def OnUpdateUnderline(self
, evt
):
361 evt
.Check(self
.rtc
.IsSelectionUnderlined())
363 def OnUpdateAlignLeft(self
, evt
):
364 evt
.Check(self
.rtc
.IsSelectionAligned(rt
.TEXT_ALIGNMENT_LEFT
))
366 def OnUpdateAlignCenter(self
, evt
):
367 evt
.Check(self
.rtc
.IsSelectionAligned(rt
.TEXT_ALIGNMENT_CENTRE
))
369 def OnUpdateAlignRight(self
, evt
):
370 evt
.Check(self
.rtc
.IsSelectionAligned(rt
.TEXT_ALIGNMENT_RIGHT
))
373 def ForwardEvent(self
, evt
):
374 # The RichTextCtrl can handle menu and update events for undo,
375 # redo, cut, copy, paste, delete, and select all, so just
376 # forward the event to it.
377 self
.rtc
.ProcessEvent(evt
)
380 def MakeMenuBar(self
):
381 def doBind(item
, handler
, updateUI
=None):
382 self
.Bind(wx
.EVT_MENU
, handler
, item
)
383 if updateUI
is not None:
384 self
.Bind(wx
.EVT_UPDATE_UI
, updateUI
, item
)
387 doBind( fileMenu
.Append(-1, "&Open\tCtrl+O", "Open a file"),
389 doBind( fileMenu
.Append(-1, "&Save\tCtrl+S", "Save a file"),
391 doBind( fileMenu
.Append(-1, "&Save As...\tF12", "Save to a new file"),
393 fileMenu
.AppendSeparator()
394 doBind( fileMenu
.Append(-1, "&View as HTML", "View HTML"),
396 fileMenu
.AppendSeparator()
397 doBind( fileMenu
.Append(-1, "E&xit\tCtrl+Q", "Quit this program"),
401 doBind( editMenu
.Append(wx
.ID_UNDO
, "&Undo\tCtrl+Z"),
402 self
.ForwardEvent
, self
.ForwardEvent
)
403 doBind( editMenu
.Append(wx
.ID_REDO
, "&Redo\tCtrl+Y"),
404 self
.ForwardEvent
, self
.ForwardEvent
)
405 editMenu
.AppendSeparator()
406 doBind( editMenu
.Append(wx
.ID_CUT
, "Cu&t\tCtrl+X"),
407 self
.ForwardEvent
, self
.ForwardEvent
)
408 doBind( editMenu
.Append(wx
.ID_COPY
, "&Copy\tCtrl+C"),
409 self
.ForwardEvent
, self
.ForwardEvent
)
410 doBind( editMenu
.Append(wx
.ID_PASTE
, "&Paste\tCtrl+V"),
411 self
.ForwardEvent
, self
.ForwardEvent
)
412 doBind( editMenu
.Append(wx
.ID_CLEAR
, "&Delete\tDel"),
413 self
.ForwardEvent
, self
.ForwardEvent
)
414 editMenu
.AppendSeparator()
415 doBind( editMenu
.Append(wx
.ID_SELECTALL
, "Select A&ll\tCtrl+A"),
416 self
.ForwardEvent
, self
.ForwardEvent
)
418 #doBind( editMenu.AppendSeparator(), )
419 #doBind( editMenu.Append(-1, "&Find...\tCtrl+F"), )
420 #doBind( editMenu.Append(-1, "&Replace...\tCtrl+R"), )
422 formatMenu
= wx
.Menu()
423 doBind( formatMenu
.AppendCheckItem(-1, "&Bold\tCtrl+B"),
424 self
.OnBold
, self
.OnUpdateBold
)
425 doBind( formatMenu
.AppendCheckItem(-1, "&Italic\tCtrl+I"),
426 self
.OnItalic
, self
.OnUpdateItalic
)
427 doBind( formatMenu
.AppendCheckItem(-1, "&Underline\tCtrl+U"),
428 self
.OnUnderline
, self
.OnUpdateUnderline
)
429 formatMenu
.AppendSeparator()
430 doBind( formatMenu
.AppendCheckItem(-1, "L&eft Align"),
431 self
.OnAlignLeft
, self
.OnUpdateAlignLeft
)
432 doBind( formatMenu
.AppendCheckItem(-1, "&Centre"),
433 self
.OnAlignCenter
, self
.OnUpdateAlignCenter
)
434 doBind( formatMenu
.AppendCheckItem(-1, "&Right Align"),
435 self
.OnAlignRight
, self
.OnUpdateAlignRight
)
436 formatMenu
.AppendSeparator()
437 doBind( formatMenu
.Append(-1, "Indent &More"), self
.OnIndentMore
)
438 doBind( formatMenu
.Append(-1, "Indent &Less"), self
.OnIndentLess
)
439 formatMenu
.AppendSeparator()
440 doBind( formatMenu
.Append(-1, "Increase Paragraph &Spacing"), self
.OnParagraphSpacingMore
)
441 doBind( formatMenu
.Append(-1, "Decrease &Paragraph Spacing"), self
.OnParagraphSpacingLess
)
442 formatMenu
.AppendSeparator()
443 doBind( formatMenu
.Append(-1, "Normal Line Spacing"), self
.OnLineSpacingSingle
)
444 doBind( formatMenu
.Append(-1, "1.5 Line Spacing"), self
.OnLineSpacingHalf
)
445 doBind( formatMenu
.Append(-1, "Double Line Spacing"), self
.OnLineSpacingDouble
)
446 formatMenu
.AppendSeparator()
447 doBind( formatMenu
.Append(-1, "&Font..."), self
.OnFont
)
450 mb
.Append(fileMenu
, "&File")
451 mb
.Append(editMenu
, "&Edit")
452 mb
.Append(formatMenu
, "F&ormat")
456 def MakeToolBar(self
):
457 def doBind(item
, handler
, updateUI
=None):
458 self
.Bind(wx
.EVT_TOOL
, handler
, item
)
459 if updateUI
is not None:
460 self
.Bind(wx
.EVT_UPDATE_UI
, updateUI
, item
)
462 tbar
= self
.CreateToolBar()
463 doBind( tbar
.AddTool(-1, images
.get_rt_openBitmap(),
464 shortHelpString
="Open"), self
.OnFileOpen
)
465 doBind( tbar
.AddTool(-1, images
.get_rt_saveBitmap(),
466 shortHelpString
="Save"), self
.OnFileSave
)
468 doBind( tbar
.AddTool(wx
.ID_CUT
, images
.get_rt_cutBitmap(),
469 shortHelpString
="Cut"), self
.ForwardEvent
, self
.ForwardEvent
)
470 doBind( tbar
.AddTool(wx
.ID_COPY
, images
.get_rt_copyBitmap(),
471 shortHelpString
="Copy"), self
.ForwardEvent
, self
.ForwardEvent
)
472 doBind( tbar
.AddTool(wx
.ID_PASTE
, images
.get_rt_pasteBitmap(),
473 shortHelpString
="Paste"), self
.ForwardEvent
, self
.ForwardEvent
)
475 doBind( tbar
.AddTool(wx
.ID_UNDO
, images
.get_rt_undoBitmap(),
476 shortHelpString
="Undo"), self
.ForwardEvent
, self
.ForwardEvent
)
477 doBind( tbar
.AddTool(wx
.ID_REDO
, images
.get_rt_redoBitmap(),
478 shortHelpString
="Redo"), self
.ForwardEvent
, self
.ForwardEvent
)
480 doBind( tbar
.AddTool(-1, images
.get_rt_boldBitmap(), isToggle
=True,
481 shortHelpString
="Bold"), self
.OnBold
, self
.OnUpdateBold
)
482 doBind( tbar
.AddTool(-1, images
.get_rt_italicBitmap(), isToggle
=True,
483 shortHelpString
="Italic"), self
.OnItalic
, self
.OnUpdateItalic
)
484 doBind( tbar
.AddTool(-1, images
.get_rt_underlineBitmap(), isToggle
=True,
485 shortHelpString
="Underline"), self
.OnUnderline
, self
.OnUpdateUnderline
)
487 doBind( tbar
.AddTool(-1, images
.get_rt_alignleftBitmap(), isToggle
=True,
488 shortHelpString
="Align Left"), self
.OnAlignLeft
, self
.OnUpdateAlignLeft
)
489 doBind( tbar
.AddTool(-1, images
.get_rt_centreBitmap(), isToggle
=True,
490 shortHelpString
="Center"), self
.OnAlignCenter
, self
.OnUpdateAlignCenter
)
491 doBind( tbar
.AddTool(-1, images
.get_rt_alignrightBitmap(), isToggle
=True,
492 shortHelpString
="Align Right"), self
.OnAlignRight
, self
.OnUpdateAlignRight
)
494 doBind( tbar
.AddTool(-1, images
.get_rt_indentlessBitmap(),
495 shortHelpString
="Indent Less"), self
.OnIndentLess
)
496 doBind( tbar
.AddTool(-1, images
.get_rt_indentmoreBitmap(),
497 shortHelpString
="Indent More"), self
.OnIndentMore
)
499 doBind( tbar
.AddTool(-1, images
.get_rt_fontBitmap(),
500 shortHelpString
="Font"), self
.OnFont
)
506 #----------------------------------------------------------------------
508 class TestPanel(wx
.Panel
):
509 def __init__(self
, parent
, log
):
511 wx
.Panel
.__init
__(self
, parent
, -1)
513 b
= wx
.Button(self
, -1, "Show the RichTextCtrl sample", (50,50))
514 self
.Bind(wx
.EVT_BUTTON
, self
.OnButton
, b
)
517 def OnButton(self
, evt
):
518 win
= RichTextFrame(self
, -1, "wx.richtext.RichTextCtrl",
520 style
= wx
.DEFAULT_FRAME_STYLE
)
523 # give easy access to PyShell if it's running
527 #----------------------------------------------------------------------
529 def runTest(frame
, nb
, log
):
530 win
= TestPanel(nb
, log
)
533 #----------------------------------------------------------------------
537 overview
= """<html><body>
538 <h2><center>wx.richtext.RichTextCtrl</center></h2>
545 if __name__
== '__main__':
548 run
.main(['', os
.path
.basename(sys
.argv
[0])] + sys
.argv
[1:])