001: /*
002: * File : $Source: /usr/local/cvs/opencms/src-modules/org/opencms/editors/fckeditor/CmsFCKEditorWidget.java,v $
003: * Date : $Date: 2008-02-27 12:05:30 $
004: * Version: $Revision: 1.7 $
005: *
006: * This library is part of OpenCms -
007: * the Open Source Content Management System
008: *
009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
010: *
011: * This library is free software; you can redistribute it and/or
012: * modify it under the terms of the GNU Lesser General Public
013: * License as published by the Free Software Foundation; either
014: * version 2.1 of the License, or (at your option) any later version.
015: *
016: * This library is distributed in the hope that it will be useful,
017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: * Lesser General Public License for more details.
020: *
021: * For further information about Alkacon Software GmbH, please see the
022: * company website: http://www.alkacon.com
023: *
024: * For further information about OpenCms, please see the
025: * project website: http://www.opencms.org
026: *
027: * You should have received a copy of the GNU Lesser General Public
028: * License along with this library; if not, write to the Free Software
029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
030: */
031:
032: package org.opencms.editors.fckeditor;
033:
034: import org.opencms.file.CmsObject;
035: import org.opencms.i18n.CmsEncoder;
036: import org.opencms.main.OpenCms;
037: import org.opencms.util.CmsStringUtil;
038: import org.opencms.widgets.A_CmsHtmlWidget;
039: import org.opencms.widgets.CmsHtmlWidgetOption;
040: import org.opencms.widgets.I_CmsWidget;
041: import org.opencms.widgets.I_CmsWidgetDialog;
042: import org.opencms.widgets.I_CmsWidgetParameter;
043: import org.opencms.workplace.CmsWorkplace;
044: import org.opencms.workplace.editors.CmsEditor;
045: import org.opencms.workplace.editors.I_CmsEditorCssHandler;
046: import org.opencms.workplace.galleries.A_CmsGallery;
047: import org.opencms.xml.types.I_CmsXmlContentValue;
048:
049: import java.util.ArrayList;
050: import java.util.Collections;
051: import java.util.HashMap;
052: import java.util.Iterator;
053: import java.util.List;
054: import java.util.Map;
055:
056: /**
057: * Provides a widget that creates a rich input field using the "FCKeditor" component, for use on a widget dialog.<p>
058: *
059: * For configuration options, have a look at the documentation of {@link CmsHtmlWidgetOption}.<p>
060: *
061: * @author Andreas Zahner
062: *
063: * @version $Revision: 1.7 $
064: *
065: * @since 6.1.7
066: */
067: public class CmsFCKEditorWidget extends A_CmsHtmlWidget {
068:
069: /** Request parameter name for the toolbar configuration parameter. */
070: public static final String PARAM_CONFIGURATION = "config";
071:
072: /**
073: * Creates a new FCKeditor widget.<p>
074: */
075: public CmsFCKEditorWidget() {
076:
077: // empty constructor is required for class registration
078: this ("");
079: }
080:
081: /**
082: * Creates a new FCKeditor widget with the given configuration.<p>
083: *
084: * @param configuration the configuration to use
085: */
086: public CmsFCKEditorWidget(CmsHtmlWidgetOption configuration) {
087:
088: super (configuration);
089: }
090:
091: /**
092: * Creates a new FCKeditor widget with the given configuration.<p>
093: *
094: * @param configuration the configuration to use
095: */
096: public CmsFCKEditorWidget(String configuration) {
097:
098: super (configuration);
099: }
100:
101: /**
102: * Builds the toolbar button configuration String for the OpenCms specific buttons of the editor widget.<p>
103: *
104: * @param toolbar the toolbar configuration defining the buttons to show
105: * @param widgetOptionsString the options String containing the button names to show
106: * @return true if at least one button was added to the toolbar, otherwise false
107: */
108: public static boolean buildOpenCmsButtonRow(StringBuffer toolbar,
109: String widgetOptionsString) {
110:
111: boolean buttonRendered = false;
112:
113: if (CmsStringUtil
114: .isNotEmptyOrWhitespaceOnly(widgetOptionsString)) {
115: // configuration String found, build buttons to show
116: CmsHtmlWidgetOption option = new CmsHtmlWidgetOption(
117: widgetOptionsString);
118: StringBuffer custom = new StringBuffer(512);
119:
120: // show source button if configured
121: if (option.showSourceEditor()) {
122: custom.append("\"Source\"");
123: buttonRendered = true;
124: }
125:
126: // show format selector if configured
127: boolean showFormatSelect = false;
128: if (option.showFormatSelect()) {
129: if (buttonRendered) {
130: custom.append(",\"-\",");
131: }
132: custom.append("\"FontFormat\"");
133: buttonRendered = true;
134: showFormatSelect = true;
135: }
136:
137: // show style selector if configured
138: if (option.showStylesXml()) {
139: if (!showFormatSelect && buttonRendered) {
140: custom.append(",\"-\",");
141: } else if (buttonRendered) {
142: custom.append(",");
143: }
144: custom.append("\"Style\"");
145: buttonRendered = true;
146: }
147:
148: // build the link and/or anchor buttons
149: boolean showLink = false;
150: if (option.showLinkDialog()) {
151: if (buttonRendered) {
152: custom.append(",");
153: }
154: custom.append("\"oc-link\"");
155: buttonRendered = true;
156: showLink = true;
157: }
158: if (option.showAnchorDialog()) {
159: if (buttonRendered) {
160: custom.append(",");
161: }
162: custom.append("\"Anchor\"");
163: buttonRendered = true;
164: showLink = true;
165: }
166: if (showLink) {
167: // append the unlink button if at least one link button is configured
168: custom.append(", \"Unlink\"");
169: }
170:
171: // build the gallery button row
172: Map galleryMap = OpenCms.getWorkplaceManager()
173: .getGalleries();
174: List galleries = new ArrayList(galleryMap.size());
175: Map typeMap = new HashMap(galleryMap.size());
176:
177: Iterator i = galleryMap.entrySet().iterator();
178: while (i.hasNext()) {
179: Map.Entry entry = (Map.Entry) i.next();
180: String key = (String) entry.getKey();
181: A_CmsGallery currGallery = (A_CmsGallery) entry
182: .getValue();
183: galleries.add(currGallery);
184: // put the type name to the type Map
185: typeMap.put(currGallery, key);
186: }
187:
188: // sort the found galleries by their order
189: Collections.sort(galleries);
190:
191: StringBuffer galleryResult = new StringBuffer(8);
192: boolean showGallery = false;
193: for (int k = 0; k < galleries.size(); k++) {
194: A_CmsGallery currGallery = (A_CmsGallery) galleries
195: .get(k);
196: String galleryType = (String) typeMap.get(currGallery);
197: if (option.getDisplayGalleries().contains(galleryType)) {
198: // gallery is shown, build row configuration String
199: if (galleryResult.length() > 0) {
200: galleryResult.append(", ");
201: }
202: galleryResult.append("\"oc-");
203: galleryResult.append(galleryType);
204: galleryResult.append("\"");
205: showGallery = true;
206: }
207: }
208:
209: if (showGallery) {
210: // show the galleries
211: if (buttonRendered) {
212: custom.append("],[");
213: }
214: custom.append(galleryResult);
215: buttonRendered = true;
216: }
217:
218: // show image button if configured
219: if (option.showImageDialog()) {
220: if (buttonRendered) {
221: custom.append(",\"-\",");
222: }
223: custom.append("\"OcmsImage\"");
224: buttonRendered = true;
225: }
226:
227: // show table button if configured
228: if (option.showTableDialog()) {
229: if (buttonRendered) {
230: custom.append(",\"-\",");
231: }
232: custom.append("\"Table\"");
233: buttonRendered = true;
234: }
235:
236: if (buttonRendered) {
237: // insert grouping bracket if at least one button was rendered
238: custom.insert(0, ",[");
239: // append custom buttons to toolbar
240: toolbar.append(custom);
241: }
242:
243: }
244:
245: return buttonRendered;
246: }
247:
248: /**
249: * Returns if the given button is configured to be shown.<p>
250: *
251: * @param buttonName the name of the button to check
252: * @param widgetOptions the options List containing the button names to show
253: * @return true if the given button is configured to be shown
254: */
255: protected static boolean showButton(String buttonName,
256: List widgetOptions) {
257:
258: return (widgetOptions.contains(buttonName));
259: }
260:
261: /**
262: * @see org.opencms.widgets.I_CmsWidget#getDialogIncludes(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog)
263: */
264: public String getDialogIncludes(CmsObject cms,
265: I_CmsWidgetDialog widgetDialog) {
266:
267: StringBuffer result = new StringBuffer(128);
268: // general FCKeditor JS
269: result.append(getJSIncludeFile(CmsWorkplace.getSkinUri()
270: + "editors/fckeditor/fckeditor.js"));
271: result.append("\n");
272: // special FCKeditor widget functions
273: result.append(getJSIncludeFile(CmsWorkplace.getSkinUri()
274: + "components/widgets/fckeditor.js"));
275: return result.toString();
276: }
277:
278: /**
279: * @see org.opencms.widgets.I_CmsWidget#getDialogInitCall(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog)
280: */
281: public String getDialogInitCall(CmsObject cms,
282: I_CmsWidgetDialog widgetDialog) {
283:
284: // creates the FCKeditor instances
285: return "\tinitFCKeditor();\n";
286: }
287:
288: /**
289: * @see org.opencms.widgets.I_CmsWidget#getDialogInitMethod(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog)
290: */
291: public String getDialogInitMethod(CmsObject cms,
292: I_CmsWidgetDialog widgetDialog) {
293:
294: StringBuffer result = new StringBuffer(64);
295: result.append("function initFCKeditor() {\n");
296: // set time out for IE to avoid toolbar error message on direct publish button click
297: result
298: .append("\tif (navigator.userAgent.toLowerCase().indexOf(\"msie\") != -1) {\n");
299: result.append("\t\tsetTimeout(\"generateEditors();\", 50);\n");
300: result.append("\t} else {");
301: result.append("\t\tgenerateEditors();\n");
302: result.append("\t}\n");
303: result.append("}\n");
304: return result.toString();
305: }
306:
307: /**
308: * @see org.opencms.widgets.I_CmsWidget#getDialogWidget(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog, org.opencms.widgets.I_CmsWidgetParameter)
309: */
310: public String getDialogWidget(CmsObject cms,
311: I_CmsWidgetDialog widgetDialog, I_CmsWidgetParameter param) {
312:
313: String id = param.getId();
314: String value = param.getStringValue(cms);
315: StringBuffer result = new StringBuffer(4096);
316:
317: result.append("<td class=\"xmlTd\">");
318:
319: result
320: .append("<textarea class=\"xmlInput maxwidth\" name=\"ta_");
321: result.append(id);
322: result.append("\" id=\"ta_");
323: result.append(id);
324: result.append("\" style=\"height: ");
325: result.append(getHtmlWidgetOption().getEditorHeight());
326: result.append(";\" rows=\"20\" cols=\"60\">");
327: result.append(CmsEncoder.escapeXml(value));
328: result.append("</textarea>");
329: result.append("<input type=\"hidden\" name=\"");
330: result.append(id);
331: result.append("\" id=\"");
332: result.append(id);
333: result.append("\" value=\"");
334: result.append(CmsEncoder.encode(value));
335: result.append("\">");
336:
337: // generate the special configuration object for the current editor widget
338: result.append("<script type=\"text/javascript\">\n");
339: result.append("var editor = new FCKeditor(\"ta_").append(id)
340: .append("\");\n");
341: result.append("editor.BasePath = \"").append(
342: CmsWorkplace.getSkinUri()).append(
343: "editors/fckeditor/\";\n");
344:
345: // set CSS style sheet for current editor widget if configured
346: boolean cssConfigured = false;
347: String cssPath = "";
348: if (getHtmlWidgetOption().useCss()) {
349: cssPath = getHtmlWidgetOption().getCssPath();
350: // set the css path to null (the created config String passed to JS will not include this path then)
351: getHtmlWidgetOption().setCssPath(null);
352: cssConfigured = true;
353: } else if (OpenCms.getWorkplaceManager().getEditorCssHandlers()
354: .size() > 0) {
355: Iterator i = OpenCms.getWorkplaceManager()
356: .getEditorCssHandlers().iterator();
357: try {
358: // cast param to I_CmsXmlContentValue
359: I_CmsXmlContentValue contentValue = (I_CmsXmlContentValue) param;
360: // now extract the absolute path of the edited resource
361: String editedResource = cms.getSitePath(contentValue
362: .getDocument().getFile());
363: while (i.hasNext()) {
364: I_CmsEditorCssHandler handler = (I_CmsEditorCssHandler) i
365: .next();
366: if (handler.matches(cms, editedResource)) {
367: cssPath = handler.getUriStyleSheet(cms,
368: editedResource);
369: if (CmsStringUtil
370: .isNotEmptyOrWhitespaceOnly(cssPath)) {
371: cssConfigured = true;
372: }
373: break;
374: }
375: }
376: } catch (Exception e) {
377: // ignore, CSS could not be set
378: }
379: }
380: if (cssConfigured) {
381: result.append("editor.Config[\"EditorAreaCSS\"] = \"");
382: result.append(OpenCms.getLinkManager().substituteLink(cms,
383: cssPath));
384: result.append("\";\n");
385: }
386:
387: // set styles XML for current editor widget if configured
388: if (getHtmlWidgetOption().showStylesXml()) {
389: result.append("editor.Config[\"StylesXmlPath\"] = \"");
390: result.append(OpenCms.getLinkManager().substituteLink(cms,
391: getHtmlWidgetOption().getStylesXmlPath()));
392: result.append("\";\n");
393: // set the styles XML path to a value that the JS will create the selector
394: getHtmlWidgetOption().setStylesXmlPath("true");
395: }
396:
397: // set full page mode for current editor widget if configured
398: if (getHtmlWidgetOption().isFullPage()) {
399: result.append("editor.Config[\"FullPage\"] = true;\n");
400: }
401:
402: result.append("editor.Width = \"100%\";\n");
403: result.append("editor.Height = \"").append(
404: getHtmlWidgetOption().getEditorHeight())
405: .append("\";\n");
406: result.append("editor.ToolbarSet = \"OpenCmsWidget\";\n");
407:
408: // generate the special configuration JS call for the current dialog widget
409: StringBuffer configJs = new StringBuffer(128);
410: configJs.append(CmsEditor.PATH_EDITORS);
411: configJs.append("fckeditor/configwidget.js");
412: configJs.append("?");
413: configJs.append(PARAM_CONFIGURATION);
414: configJs.append("=");
415: configJs.append(CmsHtmlWidgetOption
416: .createConfigurationString(getHtmlWidgetOption()));
417: result
418: .append("editor.Config[\"CustomConfigurationsPath\"] = \"");
419: result.append(OpenCms.getLinkManager().substituteLink(cms,
420: configJs.toString()));
421: result.append("\";\n");
422: result
423: .append("editorInstances[editorInstances.length] = editor;\n");
424: result
425: .append(
426: "contentFields[contentFields.length] = document.getElementById(\"")
427: .append(id).append("\");\n");
428: result.append("</script>\n");
429:
430: result.append("</td>");
431:
432: return result.toString();
433: }
434:
435: /**
436: * @see org.opencms.widgets.I_CmsWidget#newInstance()
437: */
438: public I_CmsWidget newInstance() {
439:
440: return new CmsFCKEditorWidget(getHtmlWidgetOption());
441: }
442:
443: }
|