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.ade.containerpage.client.ui; 029 030import org.opencms.ade.containerpage.client.CmsContainerpageController; 031import org.opencms.ade.containerpage.client.CmsContainerpageController.I_ReloadHandler; 032import org.opencms.ade.containerpage.client.Messages; 033import org.opencms.ade.containerpage.client.ui.groupeditor.CmsInheritanceContainerEditor; 034import org.opencms.ade.containerpage.shared.CmsContainerElement; 035import org.opencms.ade.containerpage.shared.CmsContainerElement.ModelGroupState; 036import org.opencms.ade.containerpage.shared.CmsContainerElementData; 037import org.opencms.ade.containerpage.shared.CmsElementSettingsConfig; 038import org.opencms.ade.containerpage.shared.CmsFormatterConfig; 039import org.opencms.ade.containerpage.shared.CmsFormatterConfigCollection; 040import org.opencms.gwt.client.CmsCoreProvider; 041import org.opencms.gwt.client.ui.CmsFieldSet; 042import org.opencms.gwt.client.ui.contextmenu.CmsContextMenuButton; 043import org.opencms.gwt.client.ui.contextmenu.CmsDialogContextMenuHandler; 044import org.opencms.gwt.client.ui.css.I_CmsInputLayoutBundle; 045import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 046import org.opencms.gwt.client.ui.input.CmsCheckBox; 047import org.opencms.gwt.client.ui.input.CmsMultiCheckBox; 048import org.opencms.gwt.client.ui.input.CmsSelectBox; 049import org.opencms.gwt.client.ui.input.CmsSelectComboBox; 050import org.opencms.gwt.client.ui.input.I_CmsFormField; 051import org.opencms.gwt.client.ui.input.I_CmsFormWidget; 052import org.opencms.gwt.client.ui.input.form.A_CmsFormFieldPanel; 053import org.opencms.gwt.client.ui.input.form.CmsBasicFormField; 054import org.opencms.gwt.client.ui.input.form.CmsDialogFormHandler; 055import org.opencms.gwt.client.ui.input.form.CmsFieldTooltip; 056import org.opencms.gwt.client.ui.input.form.CmsFieldTooltip.Data; 057import org.opencms.gwt.client.ui.input.form.CmsFieldsetFormFieldPanel; 058import org.opencms.gwt.client.ui.input.form.CmsForm; 059import org.opencms.gwt.client.ui.input.form.CmsFormDialog; 060import org.opencms.gwt.client.ui.input.form.CmsFormRow; 061import org.opencms.gwt.client.ui.input.form.CmsInfoBoxFormFieldPanel; 062import org.opencms.gwt.client.ui.input.form.CmsWidgetFactoryRegistry; 063import org.opencms.gwt.client.ui.input.form.I_CmsFormSubmitHandler; 064import org.opencms.gwt.client.ui.input.form.I_CmsFormWidgetMultiFactory; 065import org.opencms.gwt.client.util.CmsDomUtil; 066import org.opencms.gwt.shared.CmsAdditionalInfoBean; 067import org.opencms.gwt.shared.CmsCoreData.AdeContext; 068import org.opencms.gwt.shared.CmsGwtConstants; 069import org.opencms.gwt.shared.CmsListInfoBean; 070import org.opencms.gwt.shared.CmsTemplateContextInfo; 071import org.opencms.util.CmsStringUtil; 072import org.opencms.util.CmsUUID; 073import org.opencms.xml.content.CmsXmlContentProperty; 074 075import java.util.ArrayList; 076import java.util.Collections; 077import java.util.HashMap; 078import java.util.LinkedHashMap; 079import java.util.List; 080import java.util.Map; 081import java.util.Map.Entry; 082import java.util.Set; 083 084import com.google.common.base.Optional; 085import com.google.common.base.Supplier; 086import com.google.common.collect.Maps; 087import com.google.gwt.dom.client.Style; 088import com.google.gwt.dom.client.Style.Unit; 089import com.google.gwt.event.logical.shared.ValueChangeEvent; 090import com.google.gwt.event.logical.shared.ValueChangeHandler; 091import com.google.gwt.user.client.ui.FlowPanel; 092import com.google.gwt.user.client.ui.Widget; 093 094/** 095 * The element settings dialog.<p> 096 */ 097public class CmsElementSettingsDialog extends CmsFormDialog implements I_CmsFormWidgetMultiFactory { 098 099 /** 100 * A panel which adds icons with tooltips containing the field description to the rows.<p> 101 */ 102 public static class FieldPanel extends CmsFieldsetFormFieldPanel { 103 104 /** 105 * Creates a new instance.<p> 106 * 107 * @param info the list info bean for an element 108 * @param legend the legend for the fieldset 109 */ 110 public FieldPanel(CmsListInfoBean info, String legend) { 111 112 super(info, legend); 113 } 114 115 /** 116 * @see org.opencms.gwt.client.ui.input.form.A_CmsFormFieldPanel#createRow(org.opencms.gwt.client.ui.input.I_CmsFormField) 117 */ 118 @Override 119 protected CmsFormRow createRow(I_CmsFormField field) { 120 121 final String htmlDesc = field.getDescription(); 122 CmsFormRow row = createRow( 123 field.getLabel(), 124 A_CmsFormFieldPanel.NO_DESCRIPTION, 125 (Widget)field.getWidget(), 126 htmlDesc, 127 true); 128 return row; 129 } 130 131 } 132 133 /** 134 * Exception for the case where no formatter configuration is available.<p> 135 */ 136 public static class NoFormatterException extends Exception { 137 138 /** uid. */ 139 private static final long serialVersionUID = -5735428472483535958L; 140 141 /** 142 * Creates a new instance.<p> 143 */ 144 public NoFormatterException() { 145 146 // nothing here 147 } 148 } 149 150 /** The model group options. */ 151 protected enum GroupOption { 152 153 /** The copy elements option. */ 154 copy(Messages.get().key(Messages.GUI_MODEL_GROUP_OPTION_COPY_0)), 155 156 /** The disabled option. */ 157 disabled(Messages.get().key(Messages.GUI_MODEL_GROUP_OPTION_DISABLED_0)), 158 159 /** The reuse option. */ 160 reuse(Messages.get().key(Messages.GUI_MODEL_GROUP_OPTION_REUSE_0)); 161 162 /** The option label. */ 163 private String m_label; 164 165 /** 166 * Constructor.<p> 167 * 168 * @param label the label 169 */ 170 GroupOption(String label) { 171 172 m_label = label; 173 } 174 175 /** 176 * Returns the option label.<p> 177 * 178 * @return the option label 179 */ 180 protected String getLabel() { 181 182 return m_label; 183 } 184 } 185 186 /** The container page controller. */ 187 CmsContainerpageController m_controller; 188 189 /** Checkbox to set the 'model group' status. */ 190 CmsSelectBox m_modelGroupSelect; 191 192 /** The template context changed flag. */ 193 private boolean m_changedContext; 194 195 /** The current container id. */ 196 private String m_containerId; 197 198 /** The template context info. */ 199 private CmsTemplateContextInfo m_contextInfo; 200 201 /** The template context widget. */ 202 private CmsMultiCheckBox m_contextsWidget; 203 204 /** Checkbox to set the 'createNew' status. */ 205 private CmsCheckBox m_createNewCheckBox; 206 207 /** The element data bean. */ 208 private CmsContainerElementData m_elementBean; 209 210 /** The element panel. */ 211 private CmsContainerPageElementPanel m_elementWidget; 212 213 /** Id of currently selected formatter. */ 214 private String m_formatter; 215 216 /** The formatter select widget. */ 217 private CmsSelectBox m_formatterSelect; 218 219 /** The break up model group checkbox. */ 220 private CmsCheckBox m_modelGroupBreakUp; 221 222 /** The original formatter key. */ 223 private String m_originalFormatter; 224 225 /** Setting presets. */ 226 private Map<String, String> m_presets; 227 228 /** The element setting values. */ 229 private Map<String, String> m_settings; 230 231 /** 232 * Constructor.<p> 233 * 234 * @param controller the container page controller 235 * @param elementWidget the element panel 236 * @param settingsConfig the element setting configuration 237 * @param settingPresets the presets for settings 238 * 239 * @throws NoFormatterException if no formatter configuration is found for the element 240 */ 241 public CmsElementSettingsDialog( 242 CmsContainerpageController controller, 243 CmsContainerPageElementPanel elementWidget, 244 CmsElementSettingsConfig settingsConfig, 245 Map<String, String> settingPresets) 246 throws NoFormatterException { 247 248 super(Messages.get().key(Messages.GUI_PROPERTY_DIALOG_TITLE_0), new CmsForm(false), null); 249 setAnimationEnabled(false); 250 setUseAnimation(false); 251 addStyleName(I_CmsLayoutBundle.INSTANCE.elementSettingsDialogCss().elementSettingsDialog()); 252 m_presets = settingPresets != null ? settingPresets : new HashMap<String, String>(); 253 CmsContainerElementData elementBean = settingsConfig.getElementData(); 254 m_elementWidget = elementWidget; 255 m_controller = controller; 256 m_elementBean = elementBean; 257 m_contextInfo = m_controller.getData().getTemplateContextInfo(); 258 m_containerId = m_elementWidget.getParentTarget().getContainerId(); 259 CmsListInfoBean infoBean = new CmsListInfoBean(); 260 infoBean.setResourceState(settingsConfig.getState()); 261 infoBean.setTitle(elementBean.getTitle()); 262 infoBean.setSubTitle(elementBean.getSitePath()); 263 infoBean.setResourceType(elementBean.getResourceType()); 264 infoBean.setBigIconClasses(elementBean.getBigIconClasses()); 265 m_settings = elementBean.getSettings(); 266 A_CmsFormFieldPanel formFieldPanel = null; 267 CmsFormatterConfig currentFormatterConfig = m_elementBean.getFormatterConfig(m_containerId); 268 if (currentFormatterConfig == null) { 269 throw new NoFormatterException(); 270 } 271 for (CmsAdditionalInfoBean addInfo : settingsConfig.getAdditionalInfo()) { 272 infoBean.addAdditionalInfo(addInfo.getName(), addInfo.getValue(), addInfo.getStyle()); 273 } 274 // infoBean.addAdditionalInfo(Messages.get().key(Messages.GUI_ADDINFO_FORMATTER_PATH_0), formatterPath); 275 I_CmsDropContainer dropContainer = elementWidget.getParentTarget(); 276 if (dropContainer instanceof CmsContainerPageContainer) { 277 CmsContainerPageContainer cpc = (CmsContainerPageContainer)dropContainer; 278 String type = cpc.getContainerType(); 279 String name = cpc.getContainerId(); 280 infoBean.addAdditionalInfo(Messages.get().key(Messages.GUI_ADDINFO_FORMATTER_CONTAINER_0), name); 281 infoBean.addAdditionalInfo(Messages.get().key(Messages.GUI_ADDINFO_FORMATTER_CONTAINER_TYPE_0), type); 282 } 283 284 boolean isEditableModelGroup = CmsCoreProvider.get().getUserInfo().isDeveloper() 285 && m_controller.getData().isModelGroup() 286 && ((m_controller.getModelGroupElementId() == null) 287 || CmsContainerpageController.getServerId(elementBean.getClientId()).equals( 288 m_controller.getModelGroupElementId())); 289 boolean isDeveloper = CmsCoreProvider.get().getUserInfo().isDeveloper(); 290 m_originalFormatter = currentFormatterConfig.getKeyOrId(); 291 292 if (m_contextInfo.shouldShowElementTemplateContextSelection() 293 || isDeveloper 294 || m_elementBean.hasAlternativeFormatters(m_containerId)) { 295 CmsFieldsetFormFieldPanel fieldSetPanel = new FieldPanel( 296 infoBean, 297 Messages.get().key(Messages.GUI_SETTINGS_LEGEND_0)); 298 formFieldPanel = fieldSetPanel; 299 if (m_elementBean.hasAlternativeFormatters(m_containerId)) { 300 CmsFieldSet formatterFieldset = new CmsFieldSet(); 301 // insert as first field-set after the element info box 302 fieldSetPanel.getMainPanel().insert(formatterFieldset, 1); 303 formatterFieldset.setLegend(Messages.get().key(Messages.GUI_FORMATTERS_LEGEND_0)); 304 formatterFieldset.getElement().getStyle().setMarginTop(10, Style.Unit.PX); 305 LinkedHashMap<String, String> formatters = new LinkedHashMap<String, String>(); 306 CmsElementSettingsFormatterWidget formatterWidget = new CmsElementSettingsFormatterWidget(); 307 m_formatterSelect = formatterWidget.getFormatterSelect(); 308 CmsFormatterConfigCollection formattersForContainer = m_elementBean.getFormatters().get(m_containerId); 309 for (CmsFormatterConfig formatter : formattersForContainer) { 310 formatters.put(formatter.getKeyOrId(), formatter.getLabel()); 311 m_formatterSelect.setTitle(formatter.getKeyOrId(), formatter.getJspRootPath()); 312 } 313 m_formatterSelect.setItems(formatters); 314 String currentFormatterValue = m_elementBean.getFormatterConfig(m_containerId).getKeyOrId(); 315 m_formatter = currentFormatterValue; 316 m_formatterSelect.selectValue(currentFormatterValue); 317 m_formatterSelect.addValueChangeHandler(new ValueChangeHandler<String>() { 318 319 public void onValueChange(ValueChangeEvent<String> event) { 320 321 onFormatterChange(event.getValue()); 322 } 323 }); 324 325 // set up formatter help tooltip 326 final FlowPanel help = formatterWidget.getHelp(); 327 for (String style : CmsFormRow.ICON_STYLES) { 328 help.addStyleName(style); 329 } 330 final Map<String, CmsFieldTooltip.Data> tooltips = Maps.newHashMap(); 331 for (CmsFormatterConfig formatterConfig : formattersForContainer) { 332 String description = formatterConfig.getDescription(); 333 if (description == null) { 334 description = formatterConfig.getLabel(); 335 } 336 tooltips.put(formatterConfig.getKeyOrId(), new Data(help, description, true)); 337 } 338 Supplier<CmsFieldTooltip.Data> tooltipProvider = new Supplier<CmsFieldTooltip.Data>() { 339 340 @SuppressWarnings("synthetic-access") 341 public Data get() { 342 343 return tooltips.get(m_formatter); 344 } 345 }; 346 CmsFormRow.installTooltipEventHandlers(help, tooltipProvider); 347 formatterFieldset.add(formatterWidget); 348 } 349 if (m_controller.getData().isModelPage() || isEditableModelGroup) { 350 CmsFieldSet modelGroupFieldSet = new CmsFieldSet(); 351 modelGroupFieldSet.setLegend(Messages.get().key(Messages.GUI_CREATE_NEW_LEGEND_0 352 353 )); 354 modelGroupFieldSet.getElement().getStyle().setMarginTop(10, Unit.PX); 355 356 if (isEditableModelGroup && !elementWidget.hasModelGroupParent()) { 357 addModelGroupSettings(elementBean, elementWidget, modelGroupFieldSet); 358 } else if (!elementWidget.isModelGroup()) { 359 addCreateNewCheckbox(elementBean, modelGroupFieldSet); 360 } 361 if (modelGroupFieldSet.getWidgetCount() > 0) { 362 fieldSetPanel.getMainPanel().insert(modelGroupFieldSet, 1); 363 } 364 365 } else if (elementWidget.isModelGroup()) { 366 CmsFieldSet modelGroupFieldSet = new CmsFieldSet(); 367 modelGroupFieldSet.setLegend(Messages.get().key(Messages.GUI_CREATE_NEW_LEGEND_0 368 369 )); 370 modelGroupFieldSet.getElement().getStyle().setMarginTop(10, Unit.PX); 371 m_modelGroupBreakUp = new CmsCheckBox(Messages.get().key(Messages.GUI_MODEL_GROUP_BREAK_UP_0)); 372 m_modelGroupBreakUp.setDisplayInline(false); 373 m_modelGroupBreakUp.getElement().getStyle().setMarginTop(7, Style.Unit.PX); 374 modelGroupFieldSet.add(m_modelGroupBreakUp); 375 fieldSetPanel.getMainPanel().insert(modelGroupFieldSet, 1); 376 } 377 378 if (m_contextInfo.shouldShowElementTemplateContextSelection()) { 379 String templateContexts = m_settings.get(CmsTemplateContextInfo.SETTING); 380 if (templateContexts == null) { 381 templateContexts = CmsStringUtil.listAsString( 382 new ArrayList<String>( 383 CmsContainerpageController.get().getData().getTemplateContextInfo().getContextLabels().keySet()), 384 "|"); 385 } else if (templateContexts.equals(CmsTemplateContextInfo.EMPTY_VALUE)) { 386 // translate "none" to an empty selection 387 templateContexts = ""; 388 } 389 m_settings.put(CmsTemplateContextInfo.SETTING, templateContexts); 390 391 CmsFieldSet contextsFieldset = new CmsFieldSet(); 392 contextsFieldset.setLegend(m_contextInfo.getSettingDefinition().getNiceName()); 393 contextsFieldset.getElement().getStyle().setMarginTop(10, Style.Unit.PX); 394 m_contextsWidget = new CmsMultiCheckBox( 395 CmsStringUtil.splitOptions(m_contextInfo.getSettingDefinition().getWidgetConfiguration())); 396 for (CmsCheckBox checkbox : m_contextsWidget.getCheckboxes()) { 397 Style checkboxStyle = checkbox.getElement().getStyle(); 398 checkbox.getButton().getElement().getStyle().setFontWeight(Style.FontWeight.NORMAL); 399 checkboxStyle.setMarginTop(7, Style.Unit.PX); 400 } 401 m_contextsWidget.setFormValueAsString(m_settings.get(CmsTemplateContextInfo.SETTING)); 402 m_contextsWidget.addValueChangeHandler(new ValueChangeHandler<String>() { 403 404 public void onValueChange(ValueChangeEvent<String> event) { 405 406 setTemplateContextChanged(true); 407 } 408 }); 409 contextsFieldset.add(m_contextsWidget); 410 fieldSetPanel.getMainPanel().add(contextsFieldset); 411 } 412 } else { 413 formFieldPanel = new CmsInfoBoxFormFieldPanel(infoBean); 414 } 415 416 CmsUUID serverId = null; 417 if (elementBean.isModelGroup()) { 418 serverId = elementBean.getModelGroupId(); 419 } else { 420 String id = CmsContainerpageController.getServerId(elementBean.getClientId()); 421 if (CmsUUID.isValidUUID(id) && !(new CmsUUID(id).isNullUUID())) { 422 serverId = new CmsUUID(id); 423 } 424 } 425 if (serverId != null) { 426 CmsContextMenuButton menuButton = new CmsContextMenuButton( 427 serverId, 428 new CmsDialogContextMenuHandler(), 429 AdeContext.resourceinfo); 430 menuButton.addStyleName(I_CmsLayoutBundle.INSTANCE.listItemWidgetCss().permaVisible()); 431 formFieldPanel.getInfoWidget().addButton(menuButton); 432 } 433 434 getForm().setWidget(formFieldPanel); 435 formFieldPanel.addStyleName(I_CmsInputLayoutBundle.INSTANCE.inputCss().formGradientBackground()); 436 I_CmsFormSubmitHandler submitHandler = new I_CmsFormSubmitHandler() { 437 438 /** 439 * @see org.opencms.gwt.client.ui.input.form.I_CmsFormSubmitHandler#onSubmitForm(org.opencms.gwt.client.ui.input.form.CmsForm, java.util.Map, java.util.Set) 440 */ 441 public void onSubmitForm( 442 CmsForm formParam, 443 final Map<String, String> fieldValues, 444 Set<String> editedFields) { 445 446 submitForm(formParam, fieldValues, editedFields); 447 } 448 }; 449 CmsDialogFormHandler formHandler = new CmsDialogFormHandler(); 450 formHandler.setSubmitHandler(submitHandler); 451 getForm().setFormHandler(formHandler); 452 formHandler.setDialog(this); 453 renderSettingsForm( 454 m_elementBean.getSettingConfig(m_containerId), 455 m_elementBean.getFormatterConfig(m_containerId).getNestedFormatterPrefixes()); 456 } 457 458 /** 459 * @see org.opencms.gwt.client.ui.input.form.CmsFormDialog#center() 460 */ 461 @Override 462 public void center() { 463 464 show(); 465 } 466 467 /** 468 * @see org.opencms.gwt.client.ui.input.form.I_CmsFormWidgetMultiFactory#createFormWidget(java.lang.String, java.util.Map, com.google.common.base.Optional) 469 */ 470 public I_CmsFormWidget createFormWidget( 471 String key, 472 Map<String, String> widgetParams, 473 Optional<String> defaultValue) { 474 475 if (CmsSelectBox.WIDGET_TYPE.equals(key) || CmsSelectComboBox.WIDGET_TYPE.equals(key)) { 476 if ((defaultValue != null) && defaultValue.isPresent() && widgetParams.containsKey(defaultValue.get())) { 477 key = key + CmsSelectBox.NOTNULL_SUFFIX; 478 } 479 Map<String, String> newParams = new HashMap<>(); 480 newParams.putAll(widgetParams); 481 newParams.put(CmsSelectBox.OPTION_RESIZABLE, "false"); 482 widgetParams = newParams; 483 } 484 485 return CmsWidgetFactoryRegistry.instance().createFormWidget(key, widgetParams, defaultValue); 486 } 487 488 /** 489 * @see com.google.gwt.user.client.ui.PopupPanel#setPopupPosition(int, int) 490 */ 491 @Override 492 public void setPopupPosition(int left, int top) { 493 494 // positioning handled via CSS 495 } 496 497 /** 498 * @see org.opencms.gwt.client.ui.input.form.CmsFormDialog#show() 499 */ 500 @Override 501 public void show() { 502 503 super.show(); 504 // positioning handled by CSS 505 getElement().getStyle().clearPosition(); 506 getElement().getStyle().clearLeft(); 507 getElement().getStyle().clearTop(); 508 509 } 510 511 /** 512 * Returns if the template context has been changed.<p> 513 * 514 * @return <code>true</code> if the template context has been changed 515 */ 516 boolean isTemplateContextChanged() { 517 518 return m_changedContext; 519 } 520 521 /** 522 * Handles the formatter selection changes.<p> 523 * 524 * @param formatterId the formatter id 525 */ 526 void onFormatterChange(String formatterId) { 527 528 m_formatter = formatterId; 529 CmsFormatterConfig config = m_elementBean.getFormatters().get(m_containerId).get(formatterId); 530 renderSettingsForm(config.getSettingConfig(), config.getNestedFormatterPrefixes()); 531 } 532 533 /** 534 * Renders the settings form.<p> 535 * 536 * @param settingsConfig the settings configuration 537 * @param nestedFormatterPrefixes the nested formatter prefixes 538 */ 539 void renderSettingsForm( 540 Map<String, CmsXmlContentProperty> settingsConfig, 541 Map<String, String> nestedFormatterPrefixes) { 542 543 Map<String, String> presets = m_presets; 544 if (presets == null) { 545 presets = new HashMap<String, String>(); 546 } 547 List<String> groups = new ArrayList<String>(getForm().getGroups()); 548 for (String group : groups) { 549 getForm().removeGroup(group); 550 } 551 552 CmsFieldsetFormFieldPanel formFieldPanel = null; 553 if (getForm().getWidget() instanceof CmsFieldsetFormFieldPanel) { 554 formFieldPanel = ((CmsFieldsetFormFieldPanel)getForm().getWidget()); 555 } 556 if ((formFieldPanel != null) && (nestedFormatterPrefixes != null) && !nestedFormatterPrefixes.isEmpty()) { 557 for (Entry<String, String> entry : nestedFormatterPrefixes.entrySet()) { 558 CmsFieldSet fieldSet = new CmsFieldSet(); 559 fieldSet.setLegend(entry.getValue()); 560 fieldSet.getElement().getStyle().setMarginTop(10, Style.Unit.PX); 561 formFieldPanel.addGroupFieldSet(entry.getKey(), fieldSet); 562 } 563 } 564 // using LinkedHashMap to preserve the order 565 Map<String, I_CmsFormField> formFields = new LinkedHashMap<String, I_CmsFormField>(); 566 for (CmsXmlContentProperty propConfig : settingsConfig.values()) { 567 if (m_presets.containsKey(propConfig.getName())) { 568 // settings configured as presets on the container are not user-editable 569 continue; 570 } 571 CmsBasicFormField currentField = CmsBasicFormField.createField( 572 propConfig, 573 propConfig.getName(), 574 this, 575 Collections.<String, String> emptyMap(), 576 false); 577 formFields.put(propConfig.getName(), currentField); 578 579 } 580 for (I_CmsFormField field : formFields.values()) { 581 582 String fieldId = field.getId(); 583 CmsXmlContentProperty propDef = settingsConfig.get(fieldId); 584 // skip hidden fields 585 if (!CmsGwtConstants.HIDDEN_SETTINGS_WIDGET_NAME.equals(propDef.getWidget())) { 586 String initialValue = m_settings.get(fieldId); 587 if (initialValue == null) { 588 589 initialValue = propDef.getDefault(); 590 } 591 String group = ""; 592 if ((nestedFormatterPrefixes != null) && !nestedFormatterPrefixes.isEmpty()) { 593 for (String prefix : nestedFormatterPrefixes.keySet()) { 594 if (fieldId.startsWith(prefix)) { 595 group = prefix; 596 break; 597 } 598 } 599 } 600 601 getForm().addField(group, field, initialValue); 602 } 603 } 604 getForm().render(); 605 } 606 607 /** 608 * Sets the template context changed flag.<p> 609 * @param changed the template context changed flag 610 */ 611 void setTemplateContextChanged(boolean changed) { 612 613 m_changedContext = changed; 614 } 615 616 /** 617 * Submits the settings form.<p> 618 * 619 * @param formParam the form 620 * @param fieldValues the field values 621 * @param editedFields the changed fields 622 */ 623 void submitForm(CmsForm formParam, final Map<String, String> fieldValues, Set<String> editedFields) { 624 625 String modelGroupId = null; 626 627 if (CmsInheritanceContainerEditor.getInstance() != null) { 628 CmsInheritanceContainerEditor.getInstance().onSettingsEdited(); 629 } 630 if (m_contextsWidget != null) { 631 String newTemplateContexts = m_contextsWidget.getFormValueAsString(); 632 if ((newTemplateContexts == null) || "".equals(newTemplateContexts)) { 633 newTemplateContexts = CmsTemplateContextInfo.EMPTY_VALUE; 634 // translate an empty selection to "none" 635 } 636 fieldValues.put(CmsTemplateContextInfo.SETTING, newTemplateContexts); 637 } 638 final boolean hasFormatterChanges; 639 if (m_formatterSelect != null) { 640 fieldValues.put( 641 CmsFormatterConfig.getSettingsKeyForContainer(m_containerId), 642 m_formatterSelect.getFormValueAsString()); 643 hasFormatterChanges = true; 644 } else { 645 hasFormatterChanges = false; 646 if (m_originalFormatter != null) { 647 // in case there is only 1 formatter, we still want to send the formatter key to the server to avoid cases 648 // where the element is removed because no default formatter can be found in the active sitemap config. 649 fieldValues.put(CmsFormatterConfig.getSettingsKeyForContainer(m_containerId), m_originalFormatter); 650 } 651 } 652 if (m_createNewCheckBox != null) { 653 m_elementWidget.setCreateNew(m_createNewCheckBox.isChecked()); 654 fieldValues.put(CmsContainerElement.CREATE_AS_NEW, Boolean.toString(m_createNewCheckBox.isChecked())); 655 } 656 if (m_modelGroupSelect != null) { 657 GroupOption group = GroupOption.valueOf(m_modelGroupSelect.getFormValueAsString()); 658 switch (group) { 659 case disabled: 660 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.noGroup.name()); 661 fieldValues.put(CmsContainerElement.USE_AS_COPY_MODEL, Boolean.toString(false)); 662 break; 663 case copy: 664 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.isModelGroup.name()); 665 fieldValues.put(CmsContainerElement.USE_AS_COPY_MODEL, Boolean.toString(true)); 666 break; 667 case reuse: 668 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.isModelGroup.name()); 669 fieldValues.put(CmsContainerElement.USE_AS_COPY_MODEL, Boolean.toString(false)); 670 break; 671 default: 672 break; 673 } 674 if (group != GroupOption.disabled) { 675 modelGroupId = CmsContainerpageController.getServerId(m_elementBean.getClientId()); 676 } 677 } 678 679 if ((m_modelGroupBreakUp != null) && m_modelGroupBreakUp.isChecked()) { 680 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.noGroup.name()); 681 } 682 683 final Map<String, String> filteredFieldValues = new HashMap<String, String>(); 684 for (Map.Entry<String, String> entry : fieldValues.entrySet()) { 685 String key = entry.getKey(); 686 String value = entry.getValue(); 687 if ((value != null) && (value.length() > 0)) { 688 filteredFieldValues.put(key, value); 689 } 690 } 691 final String changeModelGroupId = modelGroupId; 692 I_ReloadHandler reloadHandler = new I_ReloadHandler() { 693 694 CmsContainerPageElementPanel m_oldElement; 695 CmsContainerPageElementPanel m_newElement; 696 697 @Override 698 public void finish() { 699 700 if (isTemplateContextChanged()) { 701 // if the context multiselect box isn't displayed, of course it can't change values, 702 // and this code won't be executed. 703 CmsContainerpageController.get().handleChangeTemplateContext( 704 m_newElement, 705 filteredFieldValues.get(CmsTemplateContextInfo.SETTING)); 706 } 707 if (hasFormatterChanges) { 708 updateCss(); 709 } 710 if (m_newElement.getElement().getInnerHTML().contains(CmsGwtConstants.FORMATTER_RELOAD_MARKER) 711 && !CmsContainerpageController.get().isGroupcontainerEditing()) { 712 CmsContainerpageController.get().reloadPage(); 713 } 714 if (m_modelGroupSelect != null) { 715 m_controller.setModelGroupElementId(changeModelGroupId); 716 } 717 m_controller.sendElementEditedSettings(m_newElement, m_oldElement); 718 } 719 720 @Override 721 public void onReload(CmsContainerPageElementPanel oldElement, CmsContainerPageElementPanel newElement) { 722 m_oldElement = oldElement; 723 m_newElement = newElement; 724 } 725 726 } ; 727 m_controller.reloadElementWithSettings( 728 m_elementWidget, 729 m_elementBean.getClientId(), 730 filteredFieldValues, 731 reloadHandler); 732 } 733 734 /** 735 * Updates the CSS resources for the selected formatter.<p> 736 */ 737 void updateCss() { 738 739 String formatterId = m_formatterSelect.getFormValueAsString(); 740 CmsFormatterConfig formatter = m_elementBean.getFormatters().get(m_containerId).get(formatterId); 741 Set<String> cssResources = formatter.getCssResources(); 742 for (String cssResource : cssResources) { 743 CmsDomUtil.ensureStyleSheetIncluded(cssResource); 744 } 745 if (formatter.hasInlineCss()) { 746 ensureInlineCss(formatterId, formatter.getInlineCss()); 747 } 748 } 749 750 /** 751 * Adds the create new checkbox to the given field set.<p> 752 * 753 * @param elementBean the element bean 754 * @param fieldSet the field set 755 */ 756 private void addCreateNewCheckbox(CmsContainerElementData elementBean, CmsFieldSet fieldSet) { 757 758 m_createNewCheckBox = new CmsCheckBox(Messages.get().key(Messages.GUI_CREATE_NEW_LABEL_0)); 759 m_createNewCheckBox.setDisplayInline(false); 760 m_createNewCheckBox.getElement().getStyle().setMarginTop(7, Style.Unit.PX); 761 m_createNewCheckBox.setChecked(elementBean.isCreateNew()); 762 fieldSet.add(m_createNewCheckBox); 763 } 764 765 /** 766 * Adds the model group settings fields to the given field set.<p> 767 * 768 * @param elementBean the element bean 769 * @param elementWidget the element widget 770 * @param fieldSet the field set 771 */ 772 private void addModelGroupSettings( 773 CmsContainerElementData elementBean, 774 CmsContainerPageElementPanel elementWidget, 775 CmsFieldSet fieldSet) { 776 777 Map<String, String> groupOptions = new LinkedHashMap<String, String>(); 778 groupOptions.put(GroupOption.disabled.name(), GroupOption.disabled.getLabel()); 779 groupOptions.put(GroupOption.copy.name(), GroupOption.copy.getLabel()); 780 groupOptions.put(GroupOption.reuse.name(), GroupOption.reuse.getLabel()); 781 m_modelGroupSelect = new CmsSelectBox(groupOptions); 782 if (elementWidget.isModelGroup()) { 783 if (Boolean.valueOf(elementBean.getSettings().get(CmsContainerElement.USE_AS_COPY_MODEL)).booleanValue()) { 784 m_modelGroupSelect.selectValue(GroupOption.copy.name()); 785 } else { 786 m_modelGroupSelect.selectValue(GroupOption.reuse.name()); 787 } 788 } 789 CmsFormRow selectRow = new CmsFormRow(); 790 selectRow.getLabel().setText(Messages.get().key(Messages.GUI_USE_AS_MODEL_GROUP_LABEL_0)); 791 selectRow.getWidgetContainer().add(m_modelGroupSelect); 792 fieldSet.add(selectRow); 793 } 794 795 /** 796 * Ensures the CSS snippet with the given ID is present.<p> 797 * 798 * @param formatterId the ID 799 * @param cssContent the CSS snippet 800 */ 801 private native void ensureInlineCss(String formatterId, String cssContent)/*-{ 802 var styles = $wnd.document.styleSheets; 803 for (var i = 0; i < styles.length; i++) { 804 // IE uses the owningElement property 805 var styleNode = styles[i].owningElement ? styles[i].owningElement 806 : styles[i].ownerNode; 807 if (styleNode != null && styleNode.rel == formatterId) { 808 // inline css is present 809 return; 810 } 811 } 812 // include inline css into head 813 var headID = $wnd.document.getElementsByTagName("head")[0]; 814 var cssNode = $wnd.document.createElement('style'); 815 cssNode.type = 'text/css'; 816 cssNode.rel = formatterId; 817 if (cssNode.styleSheet) { 818 // in case of IE 819 cssNode.styleSheet.cssText = cssContent; 820 } else { 821 // otherwise 822 cssNode.appendChild(document.createTextNode(cssContent)); 823 } 824 headID.appendChild(cssNode); 825 }-*/; 826}