001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH & Co. KG, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.widgets;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsResource;
032import org.opencms.i18n.CmsMessages;
033import org.opencms.util.CmsStringUtil;
034import org.opencms.workplace.CmsWorkplace;
035import org.opencms.xml.content.I_CmsXmlContentHandler.DisplayType;
036import org.opencms.xml.types.A_CmsXmlContentValue;
037import org.opencms.xml.types.CmsXmlColorValue;
038
039import java.util.List;
040import java.util.Locale;
041import java.util.Map;
042
043/**
044 * Provides a HTML "color picker" widget, for use on a widget dialog.<p>
045 *
046 * @since 6.0.0
047 */
048public class CmsColorpickerWidget extends A_CmsWidget implements I_CmsADEWidget {
049
050    /**
051     * Creates a new color picker widget.<p>
052     */
053    public CmsColorpickerWidget() {
054
055        // empty constructor is required for class registration
056        this("");
057    }
058
059    /**
060     * Creates a new color picker widget with the given configuration.<p>
061     *
062     * @param configuration the configuration to use
063     */
064    public CmsColorpickerWidget(String configuration) {
065
066        super(configuration);
067    }
068
069    /**
070     * @see org.opencms.widgets.I_CmsADEWidget#getConfiguration(org.opencms.file.CmsObject, org.opencms.xml.types.A_CmsXmlContentValue, org.opencms.i18n.CmsMessages, org.opencms.file.CmsResource, java.util.Locale)
071     */
072    public String getConfiguration(
073        CmsObject cms,
074        A_CmsXmlContentValue schemaType,
075        CmsMessages messages,
076        CmsResource resource,
077        Locale contentLocale) {
078
079        return getConfiguration();
080    }
081
082    /**
083     * @see org.opencms.widgets.I_CmsADEWidget#getCssResourceLinks(org.opencms.file.CmsObject)
084     */
085    public List<String> getCssResourceLinks(CmsObject cms) {
086
087        return null;
088    }
089
090    /**
091     * @see org.opencms.widgets.I_CmsADEWidget#getDefaultDisplayType()
092     */
093    public DisplayType getDefaultDisplayType() {
094
095        return DisplayType.singleline;
096    }
097
098    /**
099     * @see org.opencms.widgets.I_CmsWidget#getDialogIncludes(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog)
100     */
101    @Override
102    public String getDialogIncludes(CmsObject cms, I_CmsWidgetDialog widgetDialog) {
103
104        return getJSIncludeFile(CmsWorkplace.getSkinUri() + "components/widgets/colorpicker.js");
105    }
106
107    /**
108     * @see org.opencms.widgets.I_CmsWidget#getDialogInitCall(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog)
109     */
110    @Override
111    public String getDialogInitCall(CmsObject cms, I_CmsWidgetDialog widgetDialog) {
112
113        return "\tinitColorPicker();\n";
114    }
115
116    /**
117     * @see org.opencms.widgets.I_CmsWidget#getDialogInitMethod(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog)
118     */
119    @Override
120    public String getDialogInitMethod(CmsObject cms, I_CmsWidgetDialog widgetDialog) {
121
122        StringBuffer result = new StringBuffer(128);
123        result.append("function initColorPicker() {\n");
124        result.append("\tcolorPicker.title = \"");
125        result.append(Messages.get().getBundle(widgetDialog.getLocale()).key(Messages.GUI_DIALOG_COLOR_TITLE_0));
126        result.append("\";\n");
127        result.append("\tcolorPicker.url=\"");
128        result.append(CmsWorkplace.getSkinUri());
129        result.append("components/js_colorpicker/index.html\";\n");
130        result.append("}\n");
131        return result.toString();
132    }
133
134    /**
135     * @see org.opencms.widgets.I_CmsWidget#getDialogWidget(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog, org.opencms.widgets.I_CmsWidgetParameter)
136     */
137    public String getDialogWidget(CmsObject cms, I_CmsWidgetDialog widgetDialog, I_CmsWidgetParameter param) {
138
139        StringBuffer result = new StringBuffer(16);
140        result.append("<td class=\"xmlTd\">");
141        String colorValue = param.getStringValue(cms);
142        String id = param.getId();
143
144        result.append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr><td>");
145        result.append("<input type=\"text\"");
146        result.append(" class=\"xmlInputSmall\" name=\"");
147        result.append(id);
148        result.append("\" value=\"");
149        result.append(colorValue);
150        // 19 chars for "InactiveCaptionText"
151        result.append("\" maxlength=\"19\" onkeyup=\"previewColor('");
152        result.append(id);
153        result.append("');\"");
154        result.append(" style=\"background-color: ");
155        result.append(checkColor(colorValue));
156        result.append("; color: ");
157        result.append(getInputFontColor(colorValue));
158        result.append(";\"></td>");
159
160        result.append(widgetDialog.dialogHorizontalSpacer(10));
161        result.append(
162            "<td><table class=\"editorbuttonbackground\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>");
163        result.append(
164            widgetDialog.button(
165                "javascript:showColorPicker('" + id + "');",
166                null,
167                "color_fill",
168                Messages.GUI_BUTTON_COLOR_0,
169                widgetDialog.getButtonStyle()));
170        result.append("</tr></table>");
171
172        result.append("</td></tr></table>");
173
174        result.append("</td>");
175        return result.toString();
176    }
177
178    /**
179     * @see org.opencms.widgets.I_CmsADEWidget#getInitCall()
180     */
181    public String getInitCall() {
182
183        return null;
184    }
185
186    /**
187     * @see org.opencms.widgets.I_CmsADEWidget#getJavaScriptResourceLinks(org.opencms.file.CmsObject)
188     */
189    public List<String> getJavaScriptResourceLinks(CmsObject cms) {
190
191        return null;
192    }
193
194    /**
195     * @see org.opencms.widgets.I_CmsADEWidget#getWidgetName()
196     */
197    public String getWidgetName() {
198
199        return CmsColorpickerWidget.class.getName();
200    }
201
202    /**
203     * @see org.opencms.widgets.I_CmsADEWidget#isInternal()
204     */
205    public boolean isInternal() {
206
207        return true;
208    }
209
210    /**
211     * @see org.opencms.widgets.I_CmsWidget#newInstance()
212     */
213    public I_CmsWidget newInstance() {
214
215        return new CmsColorpickerWidget(getConfiguration());
216    }
217
218    /**
219     * @see org.opencms.widgets.I_CmsWidget#setEditorValue(org.opencms.file.CmsObject, java.util.Map, org.opencms.widgets.I_CmsWidgetDialog, org.opencms.widgets.I_CmsWidgetParameter)
220     */
221    @Override
222    public void setEditorValue(
223        CmsObject cms,
224        Map<String, String[]> formParameters,
225        I_CmsWidgetDialog widgetDialog,
226        I_CmsWidgetParameter param) {
227
228        String[] values = formParameters.get(param.getId());
229        if ((values != null) && (values.length > 0)) {
230            CmsXmlColorValue castValue = (CmsXmlColorValue)param;
231            String castColorValue = castValue.getStringValue(cms);
232            String colorValue = values[0].trim();
233            if (CmsStringUtil.isNotEmpty(colorValue)) {
234                castColorValue = colorValue;
235            }
236            param.setStringValue(cms, String.valueOf(castColorValue));
237        }
238    }
239
240    /**
241     * Check the stored color value to prevent display issues in the generated HTML ouput.<p>
242     *
243     * @param color the color value to check
244     * @return the checked color value
245     */
246    private String checkColor(String color) {
247
248        if (color != null) {
249            if (color.indexOf("#") == -1) {
250                // add the "#" to the color string
251                color = "#" + color;
252            }
253            int colLength = color.length();
254            if ((colLength == 4) || (colLength == 7)) {
255                return color;
256            }
257        }
258        return "#FFFFFF";
259    }
260
261    /**
262     * Returns the font color of the input field depending on the selected color value.<p>
263     *
264     * @param backgroundColor the selected color value which is displayed as the input field background
265     * @return the font color to use
266     */
267    private String getInputFontColor(String backgroundColor) {
268
269        if ((backgroundColor != null) && (backgroundColor.indexOf("#") == 0)) {
270            // remove the "#" from the color string
271            backgroundColor = backgroundColor.substring(1);
272            int colorValue = 50001;
273            try {
274                // calculate int value of color
275                colorValue = Integer.parseInt(backgroundColor, 16);
276            } catch (NumberFormatException nf) {
277                // this should never happen
278            }
279            if (colorValue < 50000) {
280                // for dark colors set font color to white
281                return "#FFFFFF";
282            } else {
283                // for other colors use black
284                return "#000000";
285            }
286        }
287        return "#000000";
288    }
289}