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.form; 029 030import org.opencms.gwt.client.Messages; 031import org.opencms.gwt.client.ui.CmsPopup; 032import org.opencms.gwt.client.ui.CmsPushButton; 033import org.opencms.gwt.client.ui.input.I_CmsFormField; 034import org.opencms.gwt.client.util.CmsDomUtil; 035 036import java.util.Map; 037 038import com.google.gwt.core.client.Scheduler; 039import com.google.gwt.core.client.Scheduler.ScheduledCommand; 040import com.google.gwt.dom.client.Element; 041import com.google.gwt.event.dom.client.ClickEvent; 042import com.google.gwt.event.dom.client.ClickHandler; 043import com.google.gwt.event.dom.client.KeyCodes; 044import com.google.gwt.event.logical.shared.CloseEvent; 045import com.google.gwt.event.logical.shared.CloseHandler; 046import com.google.gwt.event.shared.HandlerRegistration; 047import com.google.gwt.user.client.DOM; 048import com.google.gwt.user.client.Event; 049import com.google.gwt.user.client.Event.NativePreviewEvent; 050import com.google.gwt.user.client.Event.NativePreviewHandler; 051import com.google.gwt.user.client.Window; 052import com.google.gwt.user.client.ui.PopupPanel; 053 054/** 055 * A dialog containing a form.<p> 056 * 057 * @since 8.0.0 058 */ 059public class CmsFormDialog extends CmsPopup { 060 061 /** The maximum dialog width. */ 062 public static final int MAX_DIALOG_WIDTH = 930; 063 064 /** The dialog width. */ 065 public static final int STANDARD_DIALOG_WIDTH = 700; 066 067 /** The widget containing the form fields. */ 068 protected CmsForm m_form; 069 070 /** The form handler for this dialog. */ 071 protected I_CmsFormHandler m_formHandler; 072 073 /** The OK button of this dialog. */ 074 private CmsPushButton m_okButton; 075 076 /** The event preview handler registration. */ 077 private HandlerRegistration m_previewHandlerRegistration; 078 079 /** 080 * Constructs a new form dialog with a given title.<p> 081 * 082 * @param title the title of the form dialog 083 * @param form the form to use 084 */ 085 public CmsFormDialog(String title, CmsForm form) { 086 087 this(title, form, -1); 088 } 089 090 /** 091 * Constructs a new form dialog with a given title.<p> 092 * 093 * @param title the title of the form dialog 094 * @param form the form to use 095 * @param dialogWidthObj the dialog width (if null, don't set any width; if negative, set default width) 096 */ 097 public CmsFormDialog(String title, CmsForm form, Integer dialogWidthObj) { 098 099 super(title, -1); 100 setGlassEnabled(true); 101 setAutoHideEnabled(false); 102 setModal(true); 103 // check the available width for this dialog 104 105 if (dialogWidthObj != null) { 106 int dialogWidth = dialogWidthObj.intValue(); 107 int windowWidth = Window.getClientWidth(); 108 if (dialogWidth > 0) { 109 // reduce the dialog width if necessary 110 if ((windowWidth - 50) < dialogWidth) { 111 dialogWidth = windowWidth - 50; 112 } 113 } else { 114 dialogWidth = (windowWidth - 100) > STANDARD_DIALOG_WIDTH ? windowWidth - 100 : STANDARD_DIALOG_WIDTH; 115 dialogWidth = dialogWidth > MAX_DIALOG_WIDTH ? MAX_DIALOG_WIDTH : dialogWidth; 116 } 117 setWidth(dialogWidth); 118 } 119 addButton(createCancelButton()); 120 m_okButton = createOkButton(); 121 addButton(m_okButton); 122 m_form = form; 123 124 addCloseHandler(new CloseHandler<PopupPanel>() { 125 126 public void onClose(CloseEvent<PopupPanel> event) { 127 128 removePreviewHandler(); 129 } 130 }); 131 } 132 133 /** 134 * @see org.opencms.gwt.client.ui.CmsPopup#center() 135 */ 136 @Override 137 public void center() { 138 139 initContent(); 140 registerPreviewHandler(); 141 super.center(); 142 notifyWidgetsOfOpen(); 143 } 144 145 /** 146 * Gets the form of this dialog.<p> 147 * 148 * @return the form of this dialog 149 */ 150 public CmsForm getForm() { 151 152 return m_form; 153 } 154 155 /** 156 * Returns the 'OK' button.<p> 157 * 158 * @return the 'OK' button 159 */ 160 public CmsPushButton getOkButton() { 161 162 return m_okButton; 163 } 164 165 /** 166 * Sets the form handler for this form dialog.<p> 167 * 168 * @param formHandler the new form handler 169 */ 170 public void setFormHandler(I_CmsFormHandler formHandler) { 171 172 m_form.setFormHandler(formHandler); 173 } 174 175 /** 176 * Enables/disables the OK button.<p> 177 * 178 * @param enabled if true, enables the OK button, else disables it 179 */ 180 public void setOkButtonEnabled(final boolean enabled) { 181 182 Scheduler.get().scheduleDeferred(new ScheduledCommand() { 183 184 /** 185 * @see com.google.gwt.core.client.Scheduler.ScheduledCommand#execute() 186 */ 187 public void execute() { 188 189 // The event handling of GWT gets confused if we don't execute this as a scheduled command 190 getOkButton().setDown(false); 191 getOkButton().setEnabled(enabled); 192 } 193 }); 194 195 } 196 197 /** 198 * @see org.opencms.gwt.client.ui.CmsPopup#show() 199 */ 200 @Override 201 public void show() { 202 203 initContent(); 204 registerPreviewHandler(); 205 super.show(); 206 notifyWidgetsOfOpen(); 207 } 208 209 /** 210 * Initializes the form content.<p> 211 */ 212 protected void initContent() { 213 214 setMainContent(m_form.getWidget()); 215 } 216 217 /** 218 * Called when the cancel button is clicked. 219 */ 220 protected void onClickCancel() { 221 222 hide(); 223 } 224 225 /** 226 * The method which should be called when the user clicks on the OK button of the dialog.<p> 227 */ 228 protected void onClickOk() { 229 230 m_form.validateAndSubmit(); 231 } 232 233 /** 234 * Registers the 'Enter' and 'Esc' shortcut action handler.<p> 235 */ 236 protected void registerPreviewHandler() { 237 238 if (m_previewHandlerRegistration == null) { 239 NativePreviewHandler eventPreviewHandler = new NativePreviewHandler() { 240 241 public void onPreviewNativeEvent(NativePreviewEvent event) { 242 243 Event nativeEvent = Event.as(event.getNativeEvent()); 244 if (DOM.eventGetType(nativeEvent) == Event.ONKEYDOWN) { 245 int keyCode = nativeEvent.getKeyCode(); 246 if (keyCode == KeyCodes.KEY_ESCAPE) { 247 onClickCancel(); 248 } else if (keyCode == KeyCodes.KEY_ENTER) { 249 Element element = CmsDomUtil.getActiveElement(); 250 boolean isTextarea = (element != null) && element.getTagName().equalsIgnoreCase("textarea"); 251 if (!isTextarea) { 252 onClickOk(); 253 } 254 } 255 } 256 } 257 }; 258 m_previewHandlerRegistration = Event.addNativePreviewHandler(eventPreviewHandler); 259 } 260 } 261 262 /** 263 * Removes the 'Enter' and 'Esc' shortcut action handler.<p> 264 */ 265 protected void removePreviewHandler() { 266 267 if (m_previewHandlerRegistration != null) { 268 m_previewHandlerRegistration.removeHandler(); 269 m_previewHandlerRegistration = null; 270 } 271 } 272 273 /** 274 * Creates the cancel button.<p> 275 * 276 * @return the cancel button 277 */ 278 private CmsPushButton createCancelButton() { 279 280 addDialogClose(null); 281 282 CmsPushButton button = new CmsPushButton(); 283 button.setText(Messages.get().key(Messages.GUI_CANCEL_0)); 284 button.setUseMinWidth(true); 285 button.addClickHandler(new ClickHandler() { 286 287 /** 288 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent) 289 */ 290 public void onClick(ClickEvent event) { 291 292 onClickCancel(); 293 294 } 295 }); 296 return button; 297 } 298 299 /** 300 * Creates the OK button.<p> 301 * 302 * @return the OK button 303 */ 304 private CmsPushButton createOkButton() { 305 306 CmsPushButton button = new CmsPushButton(); 307 button.setText(Messages.get().key(Messages.GUI_OK_0)); 308 button.setUseMinWidth(true); 309 button.addClickHandler(new ClickHandler() { 310 311 /** 312 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent) 313 */ 314 public void onClick(ClickEvent event) { 315 316 onClickOk(); 317 } 318 }); 319 return button; 320 } 321 322 /** 323 * Tells all widgets that the dialog has been opened.<p> 324 */ 325 private void notifyWidgetsOfOpen() { 326 327 for (Map.Entry<String, I_CmsFormField> fieldEntry : m_form.getFields().entrySet()) { 328 fieldEntry.getValue().getWidget().setAutoHideParent(this); 329 } 330 } 331 332}