package ilarkesto.gwt.client.editor; import ilarkesto.core.base.Str; import ilarkesto.gwt.client.AAction; import ilarkesto.gwt.client.AViewEditWidget; import ilarkesto.gwt.client.BetterTextArea; import ilarkesto.gwt.client.Gwt; import ilarkesto.gwt.client.Initializer; import ilarkesto.gwt.client.RichtextFormater; import ilarkesto.gwt.client.ToolbarWidget; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FocusListener; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; public class RichtextEditorWidget extends AViewEditWidget { private HTML viewer; private BetterTextArea editor; private String editorHeight = "300px"; private ToolbarWidget editorToolbar; private String applyButtonLabel = "Apply"; private String restoreText; private ATextEditorModel model; private ToolbarWidget bottomToolbar; public RichtextEditorWidget(ATextEditorModel model) { super(); this.model = model; } @Override protected void onViewerUpdate() { setViewerText(model.getValue()); } @Override protected void onEditorUpdate() { String text = model.getValue(); String template = model.getTemplate(); if (template != null && Str.isBlank(text)) text = template; editor.setText(text); editor.setFocus(true); bottomToolbar.update(); } @Override protected void focusEditor() { editor.setFocus(true); } @Override protected void onEditorSubmit() { String value = getEditorText(); // TODO check lenght // TODO check format/syntax model.changeValue(value); // TODO catch exceptions } @Override protected final Widget onViewerInitialization() { // viewer = new Label(); viewer = new HTML(); viewer.setStyleName("ARichtextViewEditWidget-viewer"); return viewer; } protected void armToolbar(ToolbarWidget toolbar) { String syntaxInfoHtml = getSyntaxInfo(); if (syntaxInfoHtml != null) { Label syntaxInfo = new Label("Syntax Info"); syntaxInfo.getElement().getStyle().setMargin(5, Unit.PX); Gwt.addHtmlTooltip(syntaxInfo, syntaxInfoHtml); toolbar.add(syntaxInfo); } } public void setApplyButtonLabel(String applyButtonLabel) { this.applyButtonLabel = applyButtonLabel; } @Override protected final Widget onEditorInitialization() { editorToolbar = new ToolbarWidget(); armToolbar(editorToolbar); editor = new BetterTextArea(); // editor.addFocusListener(new EditorFocusListener()); editor.addKeyPressHandler(new EditorKeyboardListener()); editor.ensureDebugId("richtext-id"); editor.setStyleName("ARichtextViewEditWidget-editor"); editor.setWidth("97%"); if (editorHeight != null) editor.setHeight(editorHeight); // no toolbar (for scrumtool)! // RichTextToolbar editorToolbar = new RichTextToolbar(editor); bottomToolbar = new ToolbarWidget(); bottomToolbar.addButton(new AAction() { @Override public String getLabel() { return applyButtonLabel; } @Override protected void onExecute() { submitEditor(); } }); bottomToolbar.addButton(new AAction() { @Override public String getLabel() { return "Cancel"; } @Override protected void onExecute() { cancelEditor(); } }); bottomToolbar.addHyperlink(new RestoreAction()); // toolbar.add(Gwt // .createHyperlink("http://en.wikipedia.org/wiki/Wikipedia:Cheatsheet", "Syntax Cheatsheet", true)); FlowPanel editorPanel = new FlowPanel(); editorPanel.setStyleName("AEditableTextareaWidget-editorPanel"); if (!editorToolbar.isEmpty()) editorPanel.add(editorToolbar.update()); editorPanel.add(editor); editorPanel.add(bottomToolbar.update()); Initializer<RichtextEditorWidget> initializer = Gwt.getRichtextEditorEditInitializer(); if (initializer != null) initializer.initialize(this); return editorPanel; } @Override protected void onSwitchToEditModeCompleted() { super.onSwitchToEditModeCompleted(); if (!Str.isBlank(restoreText)) { onEditorUpdate(); } } public ToolbarWidget getEditorToolbar() { return editorToolbar; } public BetterTextArea getEditor() { return editor; } public final void setViewerText(String text) { if (Str.isBlank(text)) { viewer.setHTML("."); return; } String html = getRichtextFormater().richtextToHtml(text); viewer.setHTML(html); } // public final void setViewerHtml(String html) { // if (Str.isBlank(html)) html = "."; // viewer.setHTML(html); // } @Override protected void closeEditor() { boolean submit = Gwt.confirm("You have an open rich text editor. Apply changes?"); if (submit) { submitEditor(); } else { cancelEditor(); } } public final String getEditorText() { return editor.getText(); } @Override public boolean isEditable() { return model.isEditable(); } protected String getSyntaxInfo() { return Gwt.getDefaultRichtextSyntaxInfo(); } protected RichtextFormater getRichtextFormater() { return Gwt.getDefaultRichtextFormater(); } public RichtextEditorWidget setEditorHeight(int pixels) { editorHeight = pixels + "px"; return this; } @Override public String getTooltip() { return model.getTooltip(); } @Override public String getId() { return model.getId(); } public ATextEditorModel getModel() { return model; } public void setRestoreText(String restoreText) { this.restoreText = restoreText; } private class EditorFocusListener implements FocusListener { @Override public void onFocus(Widget sender) {} @Override public void onLostFocus(Widget sender) { submitEditor(); } } private class EditorKeyboardListener implements KeyPressHandler { @Override public void onKeyPress(KeyPressEvent event) { char keyCode = event.getCharCode(); if (keyCode == KeyCodes.KEY_ESCAPE) { cancelEditor(); event.stopPropagation(); } if (event.isControlKeyDown()) { if (keyCode == KeyCodes.KEY_ENTER || keyCode == 10) { submitEditor(); event.stopPropagation(); } } } } private class RestoreAction extends AAction { @Override public String getLabel() { return "Restore lost text"; } @Override public String getTooltip() { String preview = restoreText; if (restoreText != null && restoreText.length() > 100) preview = restoreText.substring(0, 100) + "..."; return "Restore text, which was not saved: \"" + preview + "\""; } @Override public boolean isExecutable() { return !Str.isBlank(restoreText); } @Override protected void onExecute() { editor.setText(restoreText); restoreText = null; bottomToolbar.update(); } } }