comparison src/browser/sat_browser/richtext.py @ 738:caad07bdb659

browser_side: simplify RichTextEditor initialization
author souliane <souliane@mailoo.org>
date Thu, 19 Nov 2015 13:14:01 +0100
parents 398b54bd97f0
children b6510fd9ae15
comparison
equal deleted inserted replaced
737:398b54bd97f0 738:caad07bdb659
23 log = getLogger(__name__) 23 log = getLogger(__name__)
24 24
25 from pyjamas.ui.TextArea import TextArea 25 from pyjamas.ui.TextArea import TextArea
26 from pyjamas.ui.Button import Button 26 from pyjamas.ui.Button import Button
27 from pyjamas.ui.CheckBox import CheckBox 27 from pyjamas.ui.CheckBox import CheckBox
28 from pyjamas.ui.DialogBox import DialogBox
29 from pyjamas.ui.Label import Label 28 from pyjamas.ui.Label import Label
30 from pyjamas.ui.HTML import HTML
31 from pyjamas.ui.FlexTable import FlexTable 29 from pyjamas.ui.FlexTable import FlexTable
32 from pyjamas.ui.HorizontalPanel import HorizontalPanel 30 from pyjamas.ui.HorizontalPanel import HorizontalPanel
31 from pyjamas.ui.KeyboardListener import KeyboardHandler
33 from pyjamas import Window 32 from pyjamas import Window
34 from pyjamas.ui.KeyboardListener import KeyboardHandler
35 from __pyjamas__ import doc 33 from __pyjamas__ import doc
36 34
37 from constants import Const as C 35 from constants import Const as C
38 import dialog 36 import dialog
39 import base_panel 37 import base_panel
40 import editor_widget 38 import editor_widget
41 import list_manager
42 import html_tools 39 import html_tools
43 import blog
44 import chat
45 40
46 41
47 class RichTextEditor(editor_widget.BaseTextEditor, FlexTable): 42 class RichTextEditor(editor_widget.BaseTextEditor, FlexTable):
48 """Panel for the rich text editor.""" 43 """Panel for the rich text editor."""
49 44
50 def __init__(self, host, content=None, modifiedCb=None, afterEditCb=None, options=None, style=None): 45 STYLE = {'main': 'richTextEditor',
51 """ 46 'title': 'richTextTitle',
52 @param host: the SatWebFrontend instance 47 'toolbar': 'richTextToolbar',
53 @param content: dict with at least a 'text' key 48 'textarea': 'richTextArea'
54 @param modifiedCb: method to be called when the text has been modified 49 }
55 @param afterEditCb: method to be called when the edition is done 50
56 @param options: list of UI options (see self.readOptions) 51 def __init__(self, host, content=None, modifiedCb=None, afterEditCb=None, options=None):
52 """
53
54 @param host (SatWebFrontend): host instance
55 @param content (dict): dict with at least a 'text' key
56 @param modifiedCb (callable): to be called when the text has been modified
57 @param afterEditCb (callable): to be called when the edition is done
58 @param options (list[unicode]): UI options ("read_only", "update_msg")
57 """ 59 """
58 FlexTable.__init__(self) # FIXME 60 FlexTable.__init__(self) # FIXME
59 self.host = host 61 self.host = host
60 self._debug = False # TODO: don't forget to set it False before commit
61 self.wysiwyg = False 62 self.wysiwyg = False
62 self.__readOptions(options)
63 self.style = {'main': 'richTextEditor',
64 'title': 'richTextTitle',
65 'toolbar': 'richTextToolbar',
66 'textarea': 'richTextArea'}
67 if isinstance(style, dict):
68 self.style.update(style)
69 self._prepareUI()
70 editor_widget.BaseTextEditor.__init__(self, content, None, modifiedCb, afterEditCb)
71
72 def __readOptions(self, options):
73 """Set the internal flags according to the given options."""
74 if options is None:
75 options = []
76 self.read_only = 'read_only' in options 63 self.read_only = 'read_only' in options
77 self.update_msg = 'update_msg' in options 64 self.update_msg = 'update_msg' in options
78 self.no_title = 'no_title' in options or self.read_only 65
79 self.no_command = 'no_command' in options or self.read_only 66 indices = (-1, -1, 0, -1) if self.read_only else (0, 1, 2, 3)
80 67 self.title_offset, self.toolbar_offset, self.content_offset, self.command_offset = indices
81 def _prepareUI(self, y_offset=0): 68 self.addStyleName(self.STYLE['main'])
82 """Prepare the UI to host title panel, toolbar, text area... 69
83 @param y_offset: Y offset to start from (extra rows on top)""" 70 editor_widget.BaseTextEditor.__init__(self, content, None, modifiedCb, afterEditCb)
84 if not self.read_only:
85 self.title_offset = y_offset
86 self.toolbar_offset = self.title_offset + (0 if self.no_title else 1)
87 self.content_offset = self.toolbar_offset + (len(composition.RICH_SYNTAXES) if self._debug else 1)
88 self.command_offset = self.content_offset + 1
89 else:
90 self.title_offset = self.toolbar_offset = self.content_offset = y_offset
91 self.command_offset = self.content_offset + 1
92 # FlexTable.__init__(self, rowspan=self.command_offset + (0 if self.no_command else 1), colspan=2) # FIXME
93 self.addStyleName(self.style['main'])
94 71
95 def addEditListener(self, listener): 72 def addEditListener(self, listener):
96 """Add a method to be called whenever the text is edited. 73 """Add a method to be called whenever the text is edited.
97 @param listener: method taking two arguments: sender, keycode""" 74
75 @param listener: method taking two arguments: sender, keycode
76 """
98 editor_widget.BaseTextEditor.addEditListener(self, listener) 77 editor_widget.BaseTextEditor.addEditListener(self, listener)
99 if hasattr(self, 'display'): 78 if hasattr(self, 'display'):
100 self.display.addEditListener(listener) 79 self.display.addEditListener(listener)
101 80
102 def refresh(self, edit=None): 81 def refresh(self, edit=None):
103 """Refresh the UI for edition/display mode 82 """Refresh the UI for edition/display mode.
104 @param edit: set to True to display the edition mode""" 83
84 @param edit: set to True to display the edition mode
85 """
105 if edit is None: 86 if edit is None:
106 edit = hasattr(self, 'textarea') and self.textarea.getVisible() 87 edit = hasattr(self, 'textarea') and self.textarea.getVisible()
107 88
108 for widget in ['title_panel', 'command']: 89 for widget in ['title_panel', 'command']:
109 if hasattr(self, widget): 90 if hasattr(self, widget):
110 getattr(self, widget).setVisible(edit) 91 getattr(self, widget).setVisible(edit)
111 92
112 if hasattr(self, 'toolbar'): 93 if hasattr(self, 'toolbar'):
113 self.toolbar.setVisible(False) 94 self.toolbar.setVisible(False)
95
114 if not hasattr(self, 'display'): 96 if not hasattr(self, 'display'):
115 self.display = editor_widget.HTMLTextEditor(options={'enhance_display': False, 'listen_keyboard': False}) # for display mode 97 self.display = editor_widget.HTMLTextEditor(options={'enhance_display': False, 'listen_keyboard': False}) # for display mode
116 for listener in self.edit_listeners: 98 for listener in self.edit_listeners:
117 self.display.addEditListener(listener) 99 self.display.addEditListener(listener)
100
118 if not self.read_only and not hasattr(self, 'textarea'): 101 if not self.read_only and not hasattr(self, 'textarea'):
119 self.textarea = EditTextArea(self) # for edition mode 102 self.textarea = EditTextArea(self) # for edition mode
120 self.textarea.addStyleName(self.style['textarea']) 103 self.textarea.addStyleName(self.STYLE['textarea'])
121 104
122 self.getFlexCellFormatter().setColSpan(self.content_offset, 0, 2) 105 self.getFlexCellFormatter().setColSpan(self.content_offset, 0, 2)
123 if edit and not self.wysiwyg: 106 if edit and not self.wysiwyg:
124 self.textarea.setWidth('100%') # CSS width doesn't do it, don't know why 107 self.textarea.setWidth('100%') # CSS width doesn't do it, don't know why
125 self.setWidget(self.content_offset, 0, self.textarea) 108 self.setWidget(self.content_offset, 0, self.textarea)
126 else: 109 else:
127 self.setWidget(self.content_offset, 0, self.display) 110 self.setWidget(self.content_offset, 0, self.display)
128 if not edit: 111 if not edit:
129 return 112 return
130 113
131 if not self.no_title and not hasattr(self, 'title_panel'): 114 if not self.read_only and not hasattr(self, 'title_panel'):
132 self.title_panel = base_panel.TitlePanel() 115 self.title_panel = base_panel.TitlePanel()
133 self.title_panel.addStyleName(self.style['title']) 116 self.title_panel.addStyleName(self.STYLE['title'])
134 self.getFlexCellFormatter().setColSpan(self.title_offset, 0, 2) 117 self.getFlexCellFormatter().setColSpan(self.title_offset, 0, 2)
135 self.setWidget(self.title_offset, 0, self.title_panel) 118 self.setWidget(self.title_offset, 0, self.title_panel)
136 119
137 if not self.no_command and not hasattr(self, 'command'): 120 if not self.read_only and not hasattr(self, 'command'):
138 self.command = HorizontalPanel() 121 self.command = HorizontalPanel()
139 self.command.addStyleName("marginAuto") 122 self.command.addStyleName("marginAuto")
140 self.command.add(Button("Cancel", lambda: self.edit(True, True))) 123 self.command.add(Button("Cancel", lambda: self.edit(True, True)))
141 self.command.add(Button("Update" if self.update_msg else "Send message", lambda: self.edit(False))) 124 self.command.add(Button("Update" if self.update_msg else "Send message", lambda: self.edit(False)))
142 self.getFlexCellFormatter().setColSpan(self.command_offset, 0, 2) 125 self.getFlexCellFormatter().setColSpan(self.command_offset, 0, 2)
150 if syntax is None or syntax not in composition.RICH_SYNTAXES.keys(): 133 if syntax is None or syntax not in composition.RICH_SYNTAXES.keys():
151 syntax = composition.RICH_SYNTAXES.keys()[0] 134 syntax = composition.RICH_SYNTAXES.keys()[0]
152 if hasattr(self, "toolbar") and self.toolbar.syntax == syntax: 135 if hasattr(self, "toolbar") and self.toolbar.syntax == syntax:
153 self.toolbar.setVisible(True) 136 self.toolbar.setVisible(True)
154 return 137 return
155 count = 0 138 self.toolbar = HorizontalPanel()
156 for syntax in composition.RICH_SYNTAXES.keys() if self._debug else [syntax]: 139 self.toolbar.syntax = syntax
157 self.toolbar = HorizontalPanel() 140 self.toolbar.addStyleName(self.STYLE['toolbar'])
158 self.toolbar.syntax = syntax 141 for key in composition.RICH_SYNTAXES[syntax].keys():
159 self.toolbar.addStyleName(self.style['toolbar']) 142 self.addToolbarButton(syntax, key)
160 for key in composition.RICH_SYNTAXES[syntax].keys(): 143 self.wysiwyg_button = CheckBox(_('preview'))
161 self.addToolbarButton(syntax, key) 144 wysiywgCb = lambda sender: self.setWysiwyg(sender.getChecked())
162 self.wysiwyg_button = CheckBox(_('preview')) 145 self.wysiwyg_button.addClickListener(wysiywgCb)
163 wysiywgCb = lambda sender: self.setWysiwyg(sender.getChecked()) 146 self.toolbar.add(self.wysiwyg_button)
164 self.wysiwyg_button.addClickListener(wysiywgCb) 147 self.syntax_label = Label(_("Syntax: %s") % syntax)
165 self.toolbar.add(self.wysiwyg_button) 148 self.syntax_label.addStyleName("richTextSyntaxLabel")
166 self.syntax_label = Label(_("Syntax: %s") % syntax) 149 self.toolbar.add(self.syntax_label)
167 self.syntax_label.addStyleName("richTextSyntaxLabel") 150 self.toolbar.setCellWidth(self.syntax_label, "100%")
168 self.toolbar.add(self.syntax_label) 151 self.getFlexCellFormatter().setColSpan(self.toolbar_offset, 0, 2)
169 self.toolbar.setCellWidth(self.syntax_label, "100%") 152 self.setWidget(self.toolbar_offset, 0, self.toolbar)
170 self.getFlexCellFormatter().setColSpan(self.toolbar_offset + count, 0, 2)
171 self.setWidget(self.toolbar_offset + count, 0, self.toolbar)
172 count += 1
173 153
174 def setWysiwyg(self, wysiwyg, init=False): 154 def setWysiwyg(self, wysiwyg, init=False):
175 """Toggle the edition mode between rich content syntax and wysiwyg. 155 """Toggle the edition mode between rich content syntax and wysiwyg.
176 @param wysiwyg: boolean value 156 @param wysiwyg: boolean value
177 @param init: set to True to re-init without switching the widgets.""" 157 @param init: set to True to re-init without switching the widgets."""