"""
CommentEditor: Small HTML editor for online comments with preview feature.
Based on wxWidgets.
"""
__author__=["Jack Trainor (jacktrainor@gmail.com)",]
__version__="June 2009"
import sys
import os, os.path
import re
import wx, wx.html
DIALOG_WIDTH = 600
DIALOG_HEIGHT = 300
def create_button(frame, panel, buttonTitle, method, id=wx.ID_ANY):
button = wx.Button(panel, id, buttonTitle)
frame.Bind(wx.EVT_BUTTON, method, button)
return button
class PreviewHtmlWindow(wx.html.HtmlWindow):
def __init__(self, parent, id, frame):
wx.html.HtmlWindow.__init__(self,parent,id)
class PreviewPanel(wx.Panel):
def __init__(self, parent, id, frame):
wx.Panel.__init__(self, parent, id)
self.frame = frame
self.html = PreviewHtmlWindow(self, -1, self.frame)
self.box = wx.BoxSizer(wx.VERTICAL)
self.box.Add(self.html, 1, wx.GROW)
subbox = wx.BoxSizer(wx.HORIZONTAL)
self.backButton = create_button(parent, self, "Back", self.OnBack)
subbox.Add(self.backButton, 1, wx.GROW | wx.ALL, 2)
self.forwardButton = create_button(parent, self, "Forward", self.OnForward)
subbox.Add(self.forwardButton, 1, wx.GROW | wx.ALL, 2)
self.box.Add(subbox, 0, wx.GROW)
self.SetSizer(self.box)
self.SetAutoLayout(True)
def OnBack(self, event):
if not self.html.HistoryBack():
wx.MessageBox("No more items in history!")
def OnForward(self, event):
if not self.html.HistoryForward():
wx.MessageBox("No more items in history!")
class PreviewFrame(wx.Frame):
def __init__(self, app, parent, title):
self.app = app
screen_pos = parent.ScreenPosition
screen_pos.y += parent.Size.y
wx.Frame.__init__(self, parent, -1, title, screen_pos, parent.Size)
self.panel = PreviewPanel(self, wx.ID_ANY, self)
def OnTimeToClose(self, evt=None):
self.Close()
class EditorPanel(wx.Panel):
def __init__(self, parent, id=wx.ID_ANY):
wx.Panel.__init__(self, parent, id)
font = wx.Font(10, -1, wx.NORMAL, wx.FONTSTYLE_NORMAL, faceName="Courier New")
self.editText = wx.TextCtrl(self, -1, "", size=(DIALOG_WIDTH-20, DIALOG_HEIGHT-96), style=wx.TE_MULTILINE)
self.editText.SetFont(font)
self.anchorButton = create_button(parent, self, "Anchor", parent.OnAnchor)
self.anchorEntry = wx.TextCtrl(self, -1, "" , wx.DefaultPosition, wx.Size(DIALOG_WIDTH-100, -1))
self.anchorEntry.SetFont(font)
self.boldButton = create_button(parent, self, "Bold", parent.OnBold)
self.italicButton = create_button(parent, self, "Italic", parent.OnItalic)
self.blockquoteButton = create_button(parent, self, "Blockquote", parent.OnBlockquote)
self.previewButton = create_button(parent, self, "Preview", parent.OnPreview)
self.quitButton = create_button(parent, self, "Quit", parent.OnTimeToClose)
anchorSizer = wx.BoxSizer(wx.HORIZONTAL)
anchorSizer.Add(self.anchorButton, 0, wx.GROW | wx.ALL, 2)
anchorSizer.Add(self.anchorEntry, 0, wx.GROW | wx.ALL, 2)
buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
buttonSizer.Add(self.boldButton, 0, wx.GROW | wx.ALL, 2)
buttonSizer.Add(self.italicButton, 0, wx.GROW | wx.ALL, 2)
buttonSizer.Add(self.blockquoteButton, 0, wx.GROW | wx.ALL, 2)
buttonSizer.Add(self.previewButton, 0, wx.GROW | wx.ALL, 2)
buttonSizer.Add(self.quitButton, 0, wx.GROW | wx.ALL, 2)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.editText, 1, wx.GROW | wx.ALL, 2)
sizer.Add(anchorSizer, 0, wx.ALL, 2)
sizer.Add(buttonSizer, 0, wx.ALL, 2)
self.SetSizer(sizer)
self.Layout()
def GetText(self):
return self.editText.GetValue()
def GetAnchorText(self):
return self.anchorEntry.GetValue()
def SetText(self, text):
self.editText.SetValue(text)
self.editText.SetSelection(0, 0)
def TagSelection(self, tag, attributes={}):
from_pos, to_pos = self.editText.GetSelection()
s = self.editText.GetStringSelection()
if s:
attrs_list = []
for key, val in attributes.items():
if type(val) == str:
val = '"%s"' % (key)
attrs_list.append('%s=%s' % (key, str(val)))
open_tag = "<" + tag
if attrs_list:
open_tag += " " + " ".join(attrs_list)
open_tag += ">"
end_tag = "" + tag + ">"
s = open_tag + s + end_tag
self.editText.Replace(from_pos, to_pos, s)
class EditorFrame(wx.Frame):
def __init__(self, app, parent, title):
self.app = app
wx.Frame.__init__(self, parent, -1, title, pos=(0, 0), size=(DIALOG_WIDTH, DIALOG_HEIGHT))
self.panel = EditorPanel(self)
self.previewFrame = None
def OnBold(self, evt):
self.panel.TagSelection("b")
def OnItalic(self, evt):
self.panel.TagSelection("i")
def OnBlockquote(self, evt):
self.panel.TagSelection("blockquote")
def OnAnchor(self, evt):
anchorText = self.panel.GetAnchorText()
if anchorText and anchorText.find("http:") == 0:
self.panel.TagSelection("a", {"href":anchorText})
def OnPreview(self, evt):
if self.previewFrame:
self.previewFrame.OnTimeToClose()
self.previewFrame = PreviewFrame(self.app, self, "Preview")
self.previewFrame.Show(True)
text = self.GetText()
text = text.replace("\n", "
")
text = "