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.acacia.client.widgets;
029
030import org.opencms.acacia.client.css.I_CmsLayoutBundle;
031import org.opencms.gwt.client.util.CmsDomUtil;
032import org.opencms.util.CmsStringUtil;
033
034import com.google.gwt.core.client.GWT;
035import com.google.gwt.core.client.Scheduler;
036import com.google.gwt.core.client.Scheduler.ScheduledCommand;
037import com.google.gwt.dom.client.Element;
038import com.google.gwt.event.dom.client.BlurEvent;
039import com.google.gwt.event.dom.client.BlurHandler;
040import com.google.gwt.event.dom.client.ClickEvent;
041import com.google.gwt.event.dom.client.FocusEvent;
042import com.google.gwt.event.dom.client.FocusHandler;
043import com.google.gwt.event.dom.client.KeyUpEvent;
044import com.google.gwt.event.dom.client.KeyUpHandler;
045import com.google.gwt.event.logical.shared.ValueChangeEvent;
046import com.google.gwt.event.logical.shared.ValueChangeHandler;
047import com.google.gwt.event.shared.HandlerRegistration;
048import com.google.gwt.uibinder.client.UiBinder;
049import com.google.gwt.uibinder.client.UiField;
050import com.google.gwt.uibinder.client.UiHandler;
051import com.google.gwt.user.client.ui.Composite;
052import com.google.gwt.user.client.ui.FocusPanel;
053import com.google.gwt.user.client.ui.HTMLPanel;
054import com.google.gwt.user.client.ui.TextBox;
055
056/**
057 * Provides a display only widget, for use on a widget dialog.<p>
058 *
059 * */
060public class CmsTextboxWidget extends Composite implements I_CmsEditWidget {
061
062    /**
063     * The UI binder interface.<p>
064     */
065    interface I_CmsTextboxWidgetUiBinder extends UiBinder<HTMLPanel, CmsTextboxWidget> {
066        // nothing to do
067    }
068
069    /** The UI binder instance. */
070    private static I_CmsTextboxWidgetUiBinder uiBinder = GWT.create(I_CmsTextboxWidgetUiBinder.class);
071
072    /** The fader of this widget. */
073    @UiField
074    FocusPanel m_fadePanel;
075
076    /**The main panel of this widget. */
077    HTMLPanel m_mainPanel;
078
079    /** The input test area.*/
080    @UiField
081    TextBox m_textbox;
082
083    /** The token to control activation. */
084    private boolean m_active = true;
085
086    /** Default value. */
087    private String m_defaultValue = "";
088
089    /** The previous value. */
090    private String m_previousValue;
091
092    /** The value changed handler initialized flag. */
093    private boolean m_valueChangeHandlerInitialized;
094
095    /**
096     * Creates a new display widget.<p>
097     *
098     * @param config the widget configuration
099     */
100    public CmsTextboxWidget(String config) {
101
102        m_mainPanel = uiBinder.createAndBindUi(this);
103        initWidget(m_mainPanel);
104        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(config)) {
105            parseConfig(config);
106        }
107    }
108
109    /**
110     * @see com.google.gwt.event.dom.client.HasFocusHandlers#addFocusHandler(com.google.gwt.event.dom.client.FocusHandler)
111     */
112    public HandlerRegistration addFocusHandler(FocusHandler handler) {
113
114        return addDomHandler(handler, FocusEvent.getType());
115    }
116
117    /**
118     * @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler)
119     */
120    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
121
122        // Initialization code
123        if (!m_valueChangeHandlerInitialized) {
124            m_valueChangeHandlerInitialized = true;
125            addDomHandler(new KeyUpHandler() {
126
127                public void onKeyUp(KeyUpEvent event) {
128
129                    // schedule the change event, so the key press can take effect
130                    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
131
132                        public void execute() {
133
134                            fireValueChange(false);
135                        }
136                    });
137                }
138            }, KeyUpEvent.getType());
139            addDomHandler(new BlurHandler() {
140
141                public void onBlur(BlurEvent event) {
142
143                    fireValueChange(false);
144                }
145            }, BlurEvent.getType());
146        }
147        return addHandler(handler, ValueChangeEvent.getType());
148    }
149
150    /**
151     * Represents a value change event.<p>
152     *
153     */
154    public void fireChangeEvent() {
155
156        String result = "";
157        if (m_textbox.getText() != null) {
158            result = m_textbox.getText();
159        }
160
161        ValueChangeEvent.fire(this, result);
162    }
163
164    /**
165     * @see com.google.gwt.user.client.ui.HasValue#getValue()
166     */
167    public String getValue() {
168
169        return m_textbox.getText();
170    }
171
172    /**
173     * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#isActive()
174     */
175    public boolean isActive() {
176
177        return m_active;
178    }
179
180    /**
181     * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#onAttachWidget()
182     */
183    public void onAttachWidget() {
184
185        super.onAttach();
186    }
187
188    /**
189     * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#owns(com.google.gwt.dom.client.Element)
190     */
191    public boolean owns(Element element) {
192
193        // TODO implement this in case we want the delete behavior for optional fields
194        return false;
195
196    }
197
198    /**
199     * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#setActive(boolean)
200     */
201    public void setActive(boolean active) {
202
203        if (m_active == active) {
204            return;
205        }
206
207        m_active = active;
208        if (m_active) {
209            getElement().removeClassName(I_CmsLayoutBundle.INSTANCE.form().inActive());
210            getElement().focus();
211            m_textbox.setText(m_defaultValue);
212        } else {
213            getElement().addClassName(I_CmsLayoutBundle.INSTANCE.form().inActive());
214        }
215        if (active) {
216            fireChangeEvent();
217        }
218
219    }
220
221    /**
222     * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#setName(java.lang.String)
223     */
224    public void setName(String name) {
225
226        m_textbox.setName(name);
227
228    }
229
230    /**
231     * @see com.google.gwt.user.client.ui.UIObject#setTitle(java.lang.String)
232     */
233    @Override
234    public void setTitle(String title) {
235
236        if ((title.length() * 6.88) > m_mainPanel.getOffsetWidth()) {
237            m_mainPanel.getElement().setTitle(title);
238        } else {
239            m_mainPanel.getElement().setTitle("");
240        }
241    }
242
243    /**
244     * @see com.google.gwt.user.client.ui.HasValue#setValue(java.lang.Object)
245     */
246    public void setValue(String value) {
247
248        m_textbox.setText(value);
249    }
250
251    /**
252     * @see com.google.gwt.user.client.ui.HasValue#setValue(java.lang.Object, boolean)
253     */
254    public void setValue(String value, boolean fireEvents) {
255
256        // set the saved value to the textArea
257        m_textbox.setText(value);
258        m_previousValue = value;
259        if (fireEvents) {
260            fireChangeEvent();
261        }
262    }
263
264    /**
265     * Fires the value change event, if the value has changed.<p>
266     *
267     * @param force <code>true</code> to force firing the event, not regarding an actually changed value
268     */
269    protected void fireValueChange(boolean force) {
270
271        String currentValue = getValue();
272        if (force || !currentValue.equals(m_previousValue)) {
273            m_previousValue = currentValue;
274            ValueChangeEvent.fire(this, currentValue);
275        }
276    }
277
278    /**
279     * Handles fade panel clicks.<p>
280     *
281     * @param event the click event
282     */
283    @UiHandler("m_fadePanel")
284    void onFadeClick(ClickEvent event) {
285
286        m_textbox.setFocus(true);
287        m_textbox.setCursorPos(m_textbox.getText().length());
288    }
289
290    /**
291     * Handles text box blur.<p>
292     *
293     * @param event the blur event
294     */
295    @UiHandler("m_textbox")
296    void onTextboxBlur(BlurEvent event) {
297
298        m_mainPanel.add(m_fadePanel);
299        setTitle(m_textbox.getText());
300    }
301
302    /**
303     * Handles text box focus.<p>
304     *
305     * @param event the focus event
306     */
307    @UiHandler("m_textbox")
308    void onTextboxFocus(FocusEvent event) {
309
310        m_mainPanel.remove(m_fadePanel);
311        setTitle("");
312        CmsDomUtil.fireFocusEvent(this);
313    }
314
315    /**
316     * Handles text box value change.<p>
317     *
318     * @param event the value change event
319     */
320    @UiHandler("m_textbox")
321    void onTextboxValueChange(ValueChangeEvent<String> event) {
322
323        fireValueChange(false);
324    }
325
326    /**
327     * Parse the configuration String.<p>
328     * @param config the configuration String
329     */
330    private void parseConfig(String config) {
331
332        m_defaultValue = config;
333        setValue(m_defaultValue);
334    }
335
336}