package pt.ist.renderers.extensions.htmlEditor; import pt.ist.renderers.InputRenderer; import pt.ist.renderers.components.HtmlBlockContainer; import pt.ist.renderers.components.HtmlComponent; import pt.ist.renderers.components.HtmlContainer; import pt.ist.renderers.components.HtmlRadioButton; import pt.ist.renderers.components.HtmlRadioButtonList; import pt.ist.renderers.components.HtmlScript; import pt.ist.renderers.components.HtmlText; import pt.ist.renderers.components.controllers.HtmlController; import pt.ist.renderers.components.state.IViewState; import pt.ist.renderers.extensions.components.TinyMceEditor; import pt.ist.renderers.layouts.Layout; import pt.ist.renderers.model.MetaSlotKey; import pt.ist.renderers.utils.RenderUtils; /** * Allows you to use the TinyMCE * Javascript HTML WYSIWYG editor. * * @author cfgi */ public class RichTextInputRenderer extends InputRenderer { private String config; private Integer width; private Integer height; private Integer columns; private Integer rows; private boolean safe; private boolean showEditorOptions = true; public RichTextInputRenderer() { super(); setColumns(50); setRows(10); } public String getConfig() { return this.config; } /** * Allows you to choose a configuration for the editor. The given name * is used to fetch the properties from a file located in {@value TinyMceEditor#CONFIG_PATH} with * the same name and ending in ".properties". * * @property */ public void setConfig(String config) { this.config = config; } public Integer getColumns() { return this.columns; } /** * The number of column of the textarea. * * @property */ public void setColumns(Integer columns) { this.columns = columns; } public Integer getRows() { return this.rows; } /** * The number of rows of the textarea. * * @property */ public void setRows(Integer rows) { this.rows = rows; } public Integer getHeight() { return this.height; } /** * Chooses the height in pixels of the rich text editor. * * @property */ public void setHeight(Integer height) { this.height = height; } public Integer getWidth() { return this.width; } /** * Chooses the width in pixels of the rich text editor. * * @property */ public void setWidth(Integer width) { this.width = width; } public boolean isSafe() { return this.safe; } /** * If this property is set to true then the input will be filtered and any * unsupported HTML will be removed or escaped to the corresponding entities. * * @property */ public void setSafe(boolean safe) { this.safe = safe; } public boolean isShowEditorOptions() { return showEditorOptions; } public void setShowEditorOptions(boolean showEditorOptions) { this.showEditorOptions = showEditorOptions; } protected String getLocalName(String name, String category) { String prefix = getInputContext().getMetaObject().getKey() + "_"; if (category != null) { return prefix + category + "_" + name; } else { return prefix + name; } } @Override protected Layout getLayout(Object object, Class type) { return new Layout() { @Override public HtmlComponent createComponent(Object object, Class type) { HtmlContainer container = new HtmlBlockContainer(); MetaSlotKey key = (MetaSlotKey) getInputContext().getMetaObject().getKey(); TinyMceEditor editor = new TinyMceEditor(getConfig()); editor.setValue((String) object); editor.setRows(getRows()); editor.setColumns(getColumns()); editor.setHeight(getHeight()); editor.setWidth(getWidth()); editor.setTargetSlot(key); editor.setName(key.toString()); editor.setId(editor.getName()); if (isSafe()) { editor.setConverter(new SafeHtmlConverter()); } if (isShowEditorOptions()) { addEditorControls(container, editor); } container.addChild(editor); return container; } private void addEditorControls(HtmlContainer container, TinyMceEditor editor) { HtmlScript script = new HtmlScript(); script.setContentType("text/javascript"); script.setConditional(true); script.setScript("\n" + "function fenix_removeEditor(editors) {\n" + " for (var i in editors) {\n" + " var editorId = tinyMCE.getEditorId(editors[i]);\n" + " if (! editorId) continue;\n" + " tinyMCE.removeMCEControl(editorId);\n" + " }\n" + "}\n" + "function fenix_addEditor(editors) {\n" + " for (var i in editors) {\n" + " var id = editors[i];\n" + " var editorId = tinyMCE.getEditorId(id);\n" + " if (editorId) continue;\n" + " var element = document.getElementById(id);\n" + " tinyMCE.addMCEControl(element, id);\n" + " }\n" + "}\n"); HtmlRadioButtonList radioList = new HtmlRadioButtonList(); radioList.setName(getLocalName("controls", "editor")); HtmlRadioButton useEditor = radioList.addOption( new HtmlText(RenderUtils.getResourceString("renderers.rich-text.editor.add")), "activate"); HtmlRadioButton removeEditor = radioList.addOption( new HtmlText(RenderUtils.getResourceString("renderers.rich-text.editor.remove")), "disable"); radioList.setClasses("liinline nobullet mbottom05"); // TODO: // use // style? useEditor.setChecked(true); useEditor.setOnClick(String.format("fenix_addEditor(['%s']);", editor.getId())); removeEditor.setOnClick(String.format("fenix_removeEditor(['%s']);", editor.getId())); container.addChild(script); container.addChild(radioList); editor.setController(new DisableEditorController(editor, removeEditor)); } }; } private class DisableEditorController extends HtmlController { private static final long serialVersionUID = 1L; private final HtmlRadioButton control; private final TinyMceEditor editor; public DisableEditorController(TinyMceEditor editor, HtmlRadioButton removeEditor) { this.editor = editor; this.control = removeEditor; } @Override public void execute(IViewState viewState) { if (this.control.isChecked()) { this.editor.disable(); } } } }