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, 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.gwt.client.ui.input.category;
029
030import org.opencms.gwt.client.ui.I_CmsTruncable;
031import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle;
032import org.opencms.gwt.client.ui.input.CmsLabelLeftTruncating;
033
034import com.google.gwt.core.client.GWT;
035import com.google.gwt.dom.client.Style.Unit;
036import com.google.gwt.event.dom.client.ClickEvent;
037import com.google.gwt.event.dom.client.ClickHandler;
038import com.google.gwt.event.dom.client.HasClickHandlers;
039import com.google.gwt.event.shared.HandlerRegistration;
040import com.google.gwt.resources.client.CssResource;
041import com.google.gwt.uibinder.client.UiBinder;
042import com.google.gwt.uibinder.client.UiField;
043import com.google.gwt.user.client.ui.Composite;
044import com.google.gwt.user.client.ui.FlexTable;
045import com.google.gwt.user.client.ui.FlowPanel;
046import com.google.gwt.user.client.ui.Label;
047import com.google.gwt.user.client.ui.SimplePanel;
048import com.google.gwt.user.client.ui.Widget;
049
050/**
051 * Widget to generate an single row of values.<p>
052 *
053 * */
054public class CmsDataValue extends Composite implements I_CmsTruncable, HasClickHandlers {
055
056    /**
057     * @see com.google.gwt.uibinder.client.UiBinder
058     */
059    interface I_CmsDataValueUiBinder extends UiBinder<Widget, CmsDataValue> {
060        // GWT interface, nothing to do here
061    }
062
063    /** Internal CSS style interface. */
064    interface I_Style extends CssResource {
065
066        /**
067         * Returns the CSS style name.<p>
068         *
069         * @return the CSS style name
070         */
071        String buttonPanel();
072
073        /**
074         * Returns the CSS style name.<p>
075         *
076         * @return the CSS style name
077         */
078        String icon();
079
080        /**
081         * Returns the CSS style name.<p>
082         *
083         * @return the CSS style name
084         */
085        String label();
086
087        /**
088         * Returns the CSS style name.<p>
089         *
090         * @return the CSS style name
091         */
092        String parameter();
093
094        /**
095         * Returns the CSS style name.<p>
096         *
097         * @return the CSS style name
098         */
099        String rtl();
100
101        /**
102         * Returns the CSS style name.<p>
103         *
104         * @return the CSS style name
105         */
106        String searchMatch();
107
108        /**
109         * Returns the CSS style name.<p>
110         *
111         * @return the CSS style name
112         */
113        String table();
114    }
115
116    /** The ui-binder instance for this class. */
117    private static I_CmsDataValueUiBinder uiBinder = GWT.create(I_CmsDataValueUiBinder.class);
118
119    /** The button panel. */
120    @UiField
121    FlowPanel m_buttonPanel;
122
123    /**The image panel. */
124    @UiField
125    SimplePanel m_imagePanel;
126
127    /** The label field. */
128    @UiField
129    Label m_label;
130
131    /** The CSS bundle instance. */
132    @UiField
133    I_Style m_style;
134
135    /** The table. */
136    @UiField
137    FlexTable m_table;
138
139    /** The css string for the image that is shown in front of the label. */
140    private String m_image;
141
142    /** The values that should be shown in this widget. The first value is used for the label*/
143    private String[] m_parameters;
144
145    /** The part of the width that should be used for the label. */
146    private int m_part;
147
148    /** The width of this widget. */
149    private int m_width;
150
151    /** Flag indicating if the label width should be (part-1)/part instead of 1/part. */
152    private boolean m_complementPartWidth;
153
154    /**
155     * Constructor to generate the DataValueWidget with image.<p>
156     *
157     * @param width the width of this widget.
158     * @param part the part of the width that should be used for the label
159     * @param image the css string for the image that is shown in front of the label
160     * @param complementPartWidth if true, the label has width if (part-1)/part instead of 1/part.
161     * @param parameters the values that should be shown in this widget. The first value is used for the label
162     */
163    public CmsDataValue(int width, int part, String image, boolean complementPartWidth, String... parameters) {
164
165        initWidget(uiBinder.createAndBindUi(this));
166        m_part = part;
167        m_complementPartWidth = complementPartWidth;
168        m_parameters = parameters;
169        m_image = image;
170        generateDataValue();
171        setWidth(width);
172    }
173
174    /**
175     * Constructor to generate the DataValueWidget with image.<p>
176     *
177     * @param width the width of this widget.
178     * @param part the part of the width that should be used for the label
179     * @param image the css string for the image that is shown in front of the label
180     * @param parameters the values that should be shown in this widget. The first value is used for the label
181     */
182    public CmsDataValue(int width, int part, String image, String... parameters) {
183
184        this(width, part, image, false, parameters);
185    }
186
187    /**
188     * Adds buttons to the view.
189     *
190     * @param buttons the buttons that should be added
191     * */
192    public void addButton(Widget... buttons) {
193
194        for (Widget button : buttons) {
195            m_buttonPanel.add(button);
196        }
197    }
198
199    /**
200     * @see com.google.gwt.event.dom.client.HasClickHandlers#addClickHandler(com.google.gwt.event.dom.client.ClickHandler)
201     */
202    public HandlerRegistration addClickHandler(ClickHandler clickHandler) {
203
204        return addDomHandler(clickHandler, ClickEvent.getType());
205    }
206
207    /**
208     * Returns the label of this widget.<p>
209     * @return the label of this widget
210     */
211    public String getLabel() {
212
213        return m_parameters[0];
214    }
215
216    /**
217     * Gets the label widget.<p>
218     *
219     * @return the label widget
220     */
221    public Label getLabelWidget() {
222
223        return m_label;
224    }
225
226    /**
227     * Returns the requested parameter.<p>
228     * @param i the index of the parameter
229     * @return the requested parameter
230     */
231    public String getParameter(int i) {
232
233        return m_parameters[i];
234    }
235
236    /**
237     * Returns if the category matches the given filter.<p>
238     *
239     * @param filter the filter to match
240     * @param param the search value
241     * @return <code>true</code> if the gallery matches the given filter.<p>
242     */
243    public boolean matchesFilter(String filter, int param) {
244
245        filter = filter.toLowerCase();
246        return m_parameters[param].toLowerCase().contains(filter);
247    }
248
249    /**
250     * Returns if the category matches the given filter.<p>
251     *
252     * @param filter the filter to match
253     * @param priValue the first search value
254     * @param secValue the second search value
255     *
256     * @return <code>true</code> if the gallery matches the given filter.<p>
257     */
258    public boolean matchesFilter(String filter, int priValue, int secValue) {
259
260        filter = filter.toLowerCase();
261        return m_parameters[priValue].toLowerCase().contains(filter)
262            || m_parameters[secValue].toLowerCase().contains(filter);
263    }
264
265    /**
266     * Sets the color.<p>
267     *
268     * @param color the color that should be set
269     * */
270    public void setColor(String color) {
271
272        m_label.getElement().getStyle().setColor(color);
273    }
274
275    /**
276     * Sets the style if the data value should be inactive.<p>
277     * */
278    public void setInactive() {
279
280        getElement().getStyle().setBorderColor(I_CmsLayoutBundle.INSTANCE.constants().css().borderColor());
281        getElement().getStyle().setColor(I_CmsLayoutBundle.INSTANCE.constants().css().textColorDisabled());
282    }
283
284    /**
285     * Enables / disables the 'search match' style for this widget.<p>
286     *
287     * @param isSearchMatch true if 'search match' style should be enabled
288     */
289    public void setSearchMatch(boolean isSearchMatch) {
290
291        if (isSearchMatch) {
292            addStyleName(m_style.searchMatch());
293        } else {
294            removeStyleName(m_style.searchMatch());
295        }
296    }
297
298    /**
299     * Makes the content of the list info box unselectable.<p>
300     */
301    public void setUnselectable() {
302
303        getWidget().addStyleName(I_CmsLayoutBundle.INSTANCE.listItemWidgetCss().unselectable());
304    }
305
306    /**
307     * @see org.opencms.gwt.client.ui.I_CmsTruncable#truncate(java.lang.String, int)
308     */
309    public void truncate(String textMetricsKey, int clientWidth) {
310
311        int tableWidth = setWidth(clientWidth);
312        for (int i = 0; i < m_table.getRowCount(); i++) {
313            for (int j = 0; j < m_table.getCellCount(i); j++) {
314                Widget w = m_table.getWidget(i, j);
315                if (w instanceof I_CmsTruncable) {
316                    I_CmsTruncable truncable = ((I_CmsTruncable)w);
317
318                    truncable.truncate(textMetricsKey, tableWidth);
319                }
320            }
321        }
322    }
323
324    /**
325     * Generates the widget an adds all parameter to the right place.<p>
326     */
327    private void generateDataValue() {
328
329        if (m_image == null) {
330            m_imagePanel.removeFromParent();
331        } else {
332            m_imagePanel.addStyleName(m_image);
333        }
334        m_table.insertRow(0);
335        int i = 0;
336        for (String parameter : m_parameters) {
337            if (i > 0) {
338                boolean rtl = false;
339                if (parameter.startsWith("rtl:")) {
340                    parameter = parameter.substring(4);
341                    m_parameters[i] = parameter;
342                    rtl = true;
343                }
344                if (parameter.startsWith("hide:")) {
345                    m_parameters[i] = parameter.substring(5);
346                } else {
347                    Label label = rtl ? new CmsLabelLeftTruncating(parameter) : new Label(parameter);
348                    label.setStyleName(m_style.parameter());
349                    label.addStyleName(m_style.rtl());
350                    label.setTitle(parameter);
351                    m_table.setWidget(0, i - 1, label);
352                }
353            } else {
354                m_label.setText(parameter);
355                m_label.setTitle(parameter);
356            }
357            i++;
358        }
359    }
360
361    /**
362     * Sets the widget width.<p>
363     *
364     * @param width the widget width
365     *
366     * @return the width set for the table that is part of the widget
367     */
368    private int setWidth(int width) {
369
370        m_width = width;
371        int width_label = (m_width / m_part);
372        if (m_complementPartWidth) {
373            int complementaryWidth = m_width - width_label;
374            width_label = complementaryWidth < 30 ? 30 : complementaryWidth;
375        }
376        int width_table = (m_width - 30) - width_label;
377        m_table.getElement().getStyle().setWidth(width_table, Unit.PX);
378        return width_table;
379    }
380
381}