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_CmsWidgetsLayoutBundle; 031import org.opencms.gwt.client.ui.CmsScrollPanel; 032import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 033import org.opencms.gwt.client.ui.input.CmsRadioButton; 034import org.opencms.gwt.client.ui.input.CmsRadioButtonGroup; 035import org.opencms.gwt.client.util.CmsClientStringUtil; 036import org.opencms.gwt.client.util.CmsDomUtil; 037 038import java.util.LinkedList; 039import java.util.List; 040import java.util.Map; 041 042import com.google.gwt.core.client.GWT; 043import com.google.gwt.dom.client.Element; 044import com.google.gwt.event.dom.client.ClickEvent; 045import com.google.gwt.event.dom.client.ClickHandler; 046import com.google.gwt.event.dom.client.FocusEvent; 047import com.google.gwt.event.dom.client.FocusHandler; 048import com.google.gwt.event.logical.shared.ValueChangeEvent; 049import com.google.gwt.event.logical.shared.ValueChangeHandler; 050import com.google.gwt.event.shared.HandlerRegistration; 051import com.google.gwt.user.client.ui.Composite; 052import com.google.gwt.user.client.ui.FlowPanel; 053 054/** 055 * Provides a widget for a standard HTML form for a group of radio buttons.<p> 056 * 057 * Regarding widget configuration, see <code>{@link org.opencms.acacia.client.widgets.CmsSelectConfigurationParser}</code>.<p> 058 * */ 059public class CmsRadioSelectWidget extends Composite implements I_CmsEditWidget { 060 061 /** Default value of rows to be shown. */ 062 private static final int DEFAULT_ROWS_SHOWN = 10; 063 064 /** The main panel of this widget. */ 065 FlowPanel m_panel = new FlowPanel(); 066 067 /** The scroll panel around the radio buttons. */ 068 CmsScrollPanel m_scrollPanel = GWT.create(CmsScrollPanel.class); 069 070 /** Value of the activation. */ 071 private boolean m_active = true; 072 073 /** The default radio button set in xsd. */ 074 private CmsRadioButton m_defaultRadioButton; 075 076 /** Value of the radio group. */ 077 private CmsRadioButtonGroup m_group; 078 079 /** List of all radio button. */ 080 private List<CmsRadioButton> m_radioButtons; 081 082 /** The parameter set from configuration.*/ 083 private int m_rowsToShow = DEFAULT_ROWS_SHOWN; 084 085 /** 086 * Constructs an OptionalTextBox with the given caption on the check.<p> 087 * @param config the configuration string. 088 */ 089 public CmsRadioSelectWidget(String config) { 090 091 // generate a list of all radio button. 092 m_group = new CmsRadioButtonGroup(); 093 // move the list to the array of all radio button. 094 m_radioButtons = parseConfiguration(config); 095 // add separate style to the panel. 096 m_scrollPanel.addStyleName(I_CmsWidgetsLayoutBundle.INSTANCE.widgetCss().radioButtonPanel()); 097 FocusHandler focusHandler = new FocusHandler() { 098 099 public void onFocus(FocusEvent event) { 100 101 CmsDomUtil.fireFocusEvent(CmsRadioSelectWidget.this); 102 } 103 }; 104 // iterate about all radio button. 105 for (CmsRadioButton radiobutton : m_radioButtons) { 106 // add a separate style each radio button. 107 radiobutton.addStyleName(I_CmsWidgetsLayoutBundle.INSTANCE.widgetCss().radioButtonlabel()); 108 radiobutton.getRadioButton().addFocusHandler(focusHandler); 109 // add the radio button to the panel. 110 m_panel.add(radiobutton); 111 } 112 m_scrollPanel.add(m_panel); 113 m_scrollPanel.setResizable(false); 114 int lineHeight = CmsClientStringUtil.parseInt(I_CmsLayoutBundle.INSTANCE.constants().css().lineHeightBig()); 115 if (lineHeight <= 0) { 116 lineHeight = 17; 117 } 118 int height = (m_rowsToShow * lineHeight); 119 if (m_radioButtons.size() < m_rowsToShow) { 120 height = (m_radioButtons.size() * lineHeight); 121 } 122 // account for padding 123 height += 8; 124 m_scrollPanel.setDefaultHeight(height); 125 m_scrollPanel.setHeight(height + "px"); 126 initWidget(m_scrollPanel); 127 } 128 129 /** 130 * @see com.google.gwt.event.dom.client.HasFocusHandlers#addFocusHandler(com.google.gwt.event.dom.client.FocusHandler) 131 */ 132 public HandlerRegistration addFocusHandler(FocusHandler handler) { 133 134 return addDomHandler(handler, FocusEvent.getType()); 135 } 136 137 /** 138 * @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler) 139 */ 140 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) { 141 142 return addHandler(handler, ValueChangeEvent.getType()); 143 } 144 145 /** 146 * Represents a value change event.<p> 147 * 148 */ 149 public void fireChangeEvent() { 150 151 String result = ""; 152 // check if there is a radio button selected. 153 if (m_group.getSelectedButton() != null) { 154 // set the name of the selected radio button. 155 result = m_group.getSelectedButton().getName(); 156 } 157 158 ValueChangeEvent.fire(this, result); 159 } 160 161 /** 162 * @see com.google.gwt.user.client.ui.HasValue#getValue() 163 */ 164 public String getValue() { 165 166 return m_group.getSelectedButton().getName(); 167 } 168 169 /** 170 * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#isActive() 171 */ 172 public boolean isActive() { 173 174 return m_active; 175 } 176 177 /** 178 * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#onAttachWidget() 179 */ 180 public void onAttachWidget() { 181 182 super.onAttach(); 183 } 184 185 /** 186 * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#owns(com.google.gwt.dom.client.Element) 187 */ 188 public boolean owns(Element element) { 189 190 // TODO implement this in case we want the delete behavior for optional fields 191 return false; 192 193 } 194 195 /** 196 * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#setActive(boolean) 197 */ 198 public void setActive(boolean active) { 199 200 // check if the value has changed. If there is no change do nothing. 201 if (m_active == active) { 202 // if the value is initial activated set the default value. 203 if (active) { 204 fireChangeEvent(); 205 } 206 return; 207 } 208 // set the new value. 209 m_active = active; 210 // Iterate about all radio button. 211 for (CmsRadioButton radiobutton : m_radioButtons) { 212 // set the radio button active / inactive. 213 radiobutton.setEnabled(active); 214 // if this widget is set inactive. 215 if (active) { 216 // select the default value if set. 217 if (m_defaultRadioButton != null) { 218 m_defaultRadioButton.setChecked(active); 219 fireChangeEvent(); 220 } 221 } 222 } 223 // fire value change event. 224 if (active) { 225 fireChangeEvent(); 226 } 227 228 } 229 230 /** 231 * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#setName(java.lang.String) 232 */ 233 public void setName(String name) { 234 235 // no input field so nothing to do 236 237 } 238 239 /** 240 * @see com.google.gwt.user.client.ui.HasValue#setValue(java.lang.Object) 241 */ 242 public void setValue(String value) { 243 244 setValue(value, false); 245 246 } 247 248 /** 249 * @see com.google.gwt.user.client.ui.HasValue#setValue(java.lang.Object, boolean) 250 */ 251 public void setValue(String value, boolean fireEvents) { 252 253 // iterate about all the radio button. 254 for (CmsRadioButton radiobutton : m_radioButtons) { 255 // if the value is the name of a radio button active it. 256 if (radiobutton.getName().equals(value)) { 257 m_group.selectButton(radiobutton); 258 } 259 // fire change event. 260 if (fireEvents) { 261 fireChangeEvent(); 262 } 263 } 264 265 } 266 267 /** 268 * Helper class for parsing the configuration in to a list of Radiobuttons. <p> 269 * 270 * @param config the configuration string. 271 * @return List of CmsRadioButtons 272 * */ 273 private List<CmsRadioButton> parseConfiguration(String config) { 274 275 // generate an empty list off radio button. 276 List<CmsRadioButton> result = new LinkedList<CmsRadioButton>(); 277 278 CmsSelectConfigurationParser parser = new CmsSelectConfigurationParser(config); 279 for (Map.Entry<String, String> entry : parser.getOptions().entrySet()) { 280 // create a new radio button with the given name and label. 281 CmsRadioButton radiobutton = new CmsRadioButton(entry.getKey(), entry.getValue()); 282 // add click handler. 283 radiobutton.addClickHandler(new ClickHandler() { 284 285 public void onClick(ClickEvent event) { 286 287 fireChangeEvent(); 288 } 289 }); 290 // add this radio button to the group 291 radiobutton.setGroup(m_group); 292 // check if this value is default set. 293 if (entry.getKey().equals(parser.getDefaultValue())) { 294 radiobutton.setChecked(true); 295 m_defaultRadioButton = radiobutton; 296 } 297 // add this radio button to the list. 298 result.add(radiobutton); 299 } 300 return result; 301 } 302}