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 boolean hasGroupTypeOption = isEditableModelGroup 287 && ((m_controller.getModelGroupElementId() == null) 288 || CmsContainerpageController.getServerId(elementBean.getClientId()).equals( 289 m_controller.getModelGroupElementId())) 290 && !m_elementWidget.hasModelGroupParent(); 291 292 boolean isDeveloper = CmsCoreProvider.get().getUserInfo().isDeveloper(); 293 m_originalFormatter = currentFormatterConfig.getKeyOrId(); 294 295 if (m_contextInfo.shouldShowElementTemplateContextSelection() 296 || isDeveloper 297 || m_elementBean.hasAlternativeFormatters(m_containerId)) { 298 CmsFieldsetFormFieldPanel fieldSetPanel = new FieldPanel( 299 infoBean, 300 Messages.get().key(Messages.GUI_SETTINGS_LEGEND_0)); 301 formFieldPanel = fieldSetPanel; 302 if (m_elementBean.hasAlternativeFormatters(m_containerId)) { 303 CmsFieldSet formatterFieldset = new CmsFieldSet(); 304 // insert as first field-set after the element info box 305 fieldSetPanel.getMainPanel().insert(formatterFieldset, 1); 306 formatterFieldset.setLegend(Messages.get().key(Messages.GUI_FORMATTERS_LEGEND_0)); 307 formatterFieldset.getElement().getStyle().setMarginTop(10, Style.Unit.PX); 308 LinkedHashMap<String, String> formatters = new LinkedHashMap<String, String>(); 309 CmsElementSettingsFormatterWidget formatterWidget = new CmsElementSettingsFormatterWidget(); 310 m_formatterSelect = formatterWidget.getFormatterSelect(); 311 CmsFormatterConfigCollection formattersForContainer = m_elementBean.getFormatters().get(m_containerId); 312 for (CmsFormatterConfig formatter : formattersForContainer) { 313 formatters.put(formatter.getKeyOrId(), formatter.getLabel()); 314 m_formatterSelect.setTitle(formatter.getKeyOrId(), formatter.getJspRootPath()); 315 } 316 m_formatterSelect.setItems(formatters); 317 String currentFormatterValue = m_elementBean.getFormatterConfig(m_containerId).getKeyOrId(); 318 m_formatter = currentFormatterValue; 319 m_formatterSelect.selectValue(currentFormatterValue); 320 m_formatterSelect.addValueChangeHandler(new ValueChangeHandler<String>() { 321 322 public void onValueChange(ValueChangeEvent<String> event) { 323 324 onFormatterChange(event.getValue()); 325 } 326 }); 327 328 // set up formatter help tooltip 329 final FlowPanel help = formatterWidget.getHelp(); 330 for (String style : CmsFormRow.ICON_STYLES) { 331 help.addStyleName(style); 332 } 333 final Map<String, CmsFieldTooltip.Data> tooltips = Maps.newHashMap(); 334 for (CmsFormatterConfig formatterConfig : formattersForContainer) { 335 String description = formatterConfig.getDescription(); 336 if (description == null) { 337 description = formatterConfig.getLabel(); 338 } 339 tooltips.put(formatterConfig.getKeyOrId(), new Data(help, description, true)); 340 } 341 Supplier<CmsFieldTooltip.Data> tooltipProvider = new Supplier<CmsFieldTooltip.Data>() { 342 343 @SuppressWarnings("synthetic-access") 344 public Data get() { 345 346 return tooltips.get(m_formatter); 347 } 348 }; 349 CmsFormRow.installTooltipEventHandlers(help, tooltipProvider); 350 formatterFieldset.add(formatterWidget); 351 } 352 if (m_controller.getData().isModelPage() || isEditableModelGroup) { 353 CmsFieldSet modelGroupFieldSet = new CmsFieldSet(); 354 modelGroupFieldSet.setLegend(Messages.get().key(Messages.GUI_CREATE_NEW_LEGEND_0 355 356 )); 357 modelGroupFieldSet.getElement().getStyle().setMarginTop(10, Unit.PX); 358 359 if (hasGroupTypeOption) { 360 addModelGroupSettings(elementBean, elementWidget, modelGroupFieldSet); 361 } 362 if (!elementWidget.isModelGroup() && !hasGroupTypeOption) { 363 if (!isEditableModelGroup || settingsConfig.isCopyGroup()) { 364 addCreateNewCheckbox(elementBean, modelGroupFieldSet); 365 } 366 } 367 if (modelGroupFieldSet.getWidgetCount() > 0) { 368 fieldSetPanel.getMainPanel().insert(modelGroupFieldSet, 1); 369 } 370 371 } else if (elementWidget.isModelGroup()) { 372 CmsFieldSet modelGroupFieldSet = new CmsFieldSet(); 373 modelGroupFieldSet.setLegend(Messages.get().key(Messages.GUI_CREATE_NEW_LEGEND_0 374 375 )); 376 modelGroupFieldSet.getElement().getStyle().setMarginTop(10, Unit.PX); 377 m_modelGroupBreakUp = new CmsCheckBox(Messages.get().key(Messages.GUI_MODEL_GROUP_BREAK_UP_0)); 378 m_modelGroupBreakUp.setDisplayInline(false); 379 m_modelGroupBreakUp.getElement().getStyle().setMarginTop(7, Style.Unit.PX); 380 modelGroupFieldSet.add(m_modelGroupBreakUp); 381 fieldSetPanel.getMainPanel().insert(modelGroupFieldSet, 1); 382 } 383 384 if (m_contextInfo.shouldShowElementTemplateContextSelection()) { 385 String templateContexts = m_settings.get(CmsTemplateContextInfo.SETTING); 386 if (templateContexts == null) { 387 templateContexts = CmsStringUtil.listAsString( 388 new ArrayList<String>( 389 CmsContainerpageController.get().getData().getTemplateContextInfo().getContextLabels().keySet()), 390 "|"); 391 } else if (templateContexts.equals(CmsTemplateContextInfo.EMPTY_VALUE)) { 392 // translate "none" to an empty selection 393 templateContexts = ""; 394 } 395 m_settings.put(CmsTemplateContextInfo.SETTING, templateContexts); 396 397 CmsFieldSet contextsFieldset = new CmsFieldSet(); 398 contextsFieldset.setLegend(m_contextInfo.getSettingDefinition().getNiceName()); 399 contextsFieldset.getElement().getStyle().setMarginTop(10, Style.Unit.PX); 400 m_contextsWidget = new CmsMultiCheckBox( 401 CmsStringUtil.splitOptions(m_contextInfo.getSettingDefinition().getWidgetConfiguration())); 402 for (CmsCheckBox checkbox : m_contextsWidget.getCheckboxes()) { 403 Style checkboxStyle = checkbox.getElement().getStyle(); 404 checkbox.getButton().getElement().getStyle().setFontWeight(Style.FontWeight.NORMAL); 405 checkboxStyle.setMarginTop(7, Style.Unit.PX); 406 } 407 m_contextsWidget.setFormValueAsString(m_settings.get(CmsTemplateContextInfo.SETTING)); 408 m_contextsWidget.addValueChangeHandler(new ValueChangeHandler<String>() { 409 410 public void onValueChange(ValueChangeEvent<String> event) { 411 412 setTemplateContextChanged(true); 413 } 414 }); 415 contextsFieldset.add(m_contextsWidget); 416 fieldSetPanel.getMainPanel().add(contextsFieldset); 417 } 418 } else { 419 formFieldPanel = new CmsInfoBoxFormFieldPanel(infoBean); 420 } 421 422 CmsUUID serverId = null; 423 if (elementBean.isModelGroup()) { 424 serverId = elementBean.getModelGroupId(); 425 } else { 426 String id = CmsContainerpageController.getServerId(elementBean.getClientId()); 427 if (CmsUUID.isValidUUID(id) && !(new CmsUUID(id).isNullUUID())) { 428 serverId = new CmsUUID(id); 429 } 430 } 431 if (serverId != null) { 432 CmsContextMenuButton menuButton = new CmsContextMenuButton( 433 serverId, 434 new CmsDialogContextMenuHandler(), 435 AdeContext.resourceinfo); 436 menuButton.addStyleName(I_CmsLayoutBundle.INSTANCE.listItemWidgetCss().permaVisible()); 437 formFieldPanel.getInfoWidget().addButton(menuButton); 438 } 439 440 getForm().setWidget(formFieldPanel); 441 formFieldPanel.addStyleName(I_CmsInputLayoutBundle.INSTANCE.inputCss().formGradientBackground()); 442 I_CmsFormSubmitHandler submitHandler = new I_CmsFormSubmitHandler() { 443 444 /** 445 * @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) 446 */ 447 public void onSubmitForm( 448 CmsForm formParam, 449 final Map<String, String> fieldValues, 450 Set<String> editedFields) { 451 452 submitForm(formParam, fieldValues, editedFields); 453 } 454 }; 455 CmsDialogFormHandler formHandler = new CmsDialogFormHandler(); 456 formHandler.setSubmitHandler(submitHandler); 457 getForm().setFormHandler(formHandler); 458 formHandler.setDialog(this); 459 renderSettingsForm( 460 m_elementBean.getSettingConfig(m_containerId), 461 m_elementBean.getFormatterConfig(m_containerId).getNestedFormatterPrefixes()); 462 } 463 464 /** 465 * @see org.opencms.gwt.client.ui.input.form.CmsFormDialog#center() 466 */ 467 @Override 468 public void center() { 469 470 show(); 471 } 472 473 /** 474 * @see org.opencms.gwt.client.ui.input.form.I_CmsFormWidgetMultiFactory#createFormWidget(java.lang.String, java.util.Map, com.google.common.base.Optional) 475 */ 476 public I_CmsFormWidget createFormWidget( 477 String key, 478 Map<String, String> widgetParams, 479 Optional<String> defaultValue) { 480 481 if (CmsSelectBox.WIDGET_TYPE.equals(key) || CmsSelectComboBox.WIDGET_TYPE.equals(key)) { 482 if ((defaultValue != null) && defaultValue.isPresent() && widgetParams.containsKey(defaultValue.get())) { 483 key = key + CmsSelectBox.NOTNULL_SUFFIX; 484 } 485 Map<String, String> newParams = new HashMap<>(); 486 newParams.putAll(widgetParams); 487 newParams.put(CmsSelectBox.OPTION_RESIZABLE, "false"); 488 widgetParams = newParams; 489 } 490 491 return CmsWidgetFactoryRegistry.instance().createFormWidget(key, widgetParams, defaultValue); 492 } 493 494 /** 495 * @see com.google.gwt.user.client.ui.PopupPanel#setPopupPosition(int, int) 496 */ 497 @Override 498 public void setPopupPosition(int left, int top) { 499 500 // positioning handled via CSS 501 } 502 503 /** 504 * @see org.opencms.gwt.client.ui.input.form.CmsFormDialog#show() 505 */ 506 @Override 507 public void show() { 508 509 super.show(); 510 // positioning handled by CSS 511 getElement().getStyle().clearPosition(); 512 getElement().getStyle().clearLeft(); 513 getElement().getStyle().clearTop(); 514 515 } 516 517 /** 518 * Returns if the template context has been changed.<p> 519 * 520 * @return <code>true</code> if the template context has been changed 521 */ 522 boolean isTemplateContextChanged() { 523 524 return m_changedContext; 525 } 526 527 /** 528 * Handles the formatter selection changes.<p> 529 * 530 * @param formatterId the formatter id 531 */ 532 void onFormatterChange(String formatterId) { 533 534 m_formatter = formatterId; 535 CmsFormatterConfig config = m_elementBean.getFormatters().get(m_containerId).get(formatterId); 536 renderSettingsForm(config.getSettingConfig(), config.getNestedFormatterPrefixes()); 537 } 538 539 /** 540 * Renders the settings form.<p> 541 * 542 * @param settingsConfig the settings configuration 543 * @param nestedFormatterPrefixes the nested formatter prefixes 544 */ 545 void renderSettingsForm( 546 Map<String, CmsXmlContentProperty> settingsConfig, 547 Map<String, String> nestedFormatterPrefixes) { 548 549 Map<String, String> presets = m_presets; 550 if (presets == null) { 551 presets = new HashMap<String, String>(); 552 } 553 List<String> groups = new ArrayList<String>(getForm().getGroups()); 554 for (String group : groups) { 555 getForm().removeGroup(group); 556 } 557 558 CmsFieldsetFormFieldPanel formFieldPanel = null; 559 if (getForm().getWidget() instanceof CmsFieldsetFormFieldPanel) { 560 formFieldPanel = ((CmsFieldsetFormFieldPanel)getForm().getWidget()); 561 } 562 if ((formFieldPanel != null) && (nestedFormatterPrefixes != null) && !nestedFormatterPrefixes.isEmpty()) { 563 for (Entry<String, String> entry : nestedFormatterPrefixes.entrySet()) { 564 CmsFieldSet fieldSet = new CmsFieldSet(); 565 fieldSet.setLegend(entry.getValue()); 566 fieldSet.getElement().getStyle().setMarginTop(10, Style.Unit.PX); 567 formFieldPanel.addGroupFieldSet(entry.getKey(), fieldSet); 568 } 569 } 570 // using LinkedHashMap to preserve the order 571 Map<String, I_CmsFormField> formFields = new LinkedHashMap<String, I_CmsFormField>(); 572 for (CmsXmlContentProperty propConfig : settingsConfig.values()) { 573 if (m_presets.containsKey(propConfig.getName())) { 574 // settings configured as presets on the container are not user-editable 575 continue; 576 } 577 CmsBasicFormField currentField = CmsBasicFormField.createField( 578 propConfig, 579 propConfig.getName(), 580 this, 581 Collections.<String, String> emptyMap(), 582 false); 583 formFields.put(propConfig.getName(), currentField); 584 585 } 586 for (I_CmsFormField field : formFields.values()) { 587 588 String fieldId = field.getId(); 589 CmsXmlContentProperty propDef = settingsConfig.get(fieldId); 590 // skip hidden fields 591 if (!CmsGwtConstants.HIDDEN_SETTINGS_WIDGET_NAME.equals(propDef.getWidget())) { 592 String initialValue = m_settings.get(fieldId); 593 if (initialValue == null) { 594 595 initialValue = propDef.getDefault(); 596 } 597 String group = ""; 598 if ((nestedFormatterPrefixes != null) && !nestedFormatterPrefixes.isEmpty()) { 599 for (String prefix : nestedFormatterPrefixes.keySet()) { 600 if (fieldId.startsWith(prefix)) { 601 group = prefix; 602 break; 603 } 604 } 605 } 606 607 getForm().addField(group, field, initialValue); 608 } 609 } 610 getForm().render(); 611 } 612 613 /** 614 * Sets the template context changed flag.<p> 615 * @param changed the template context changed flag 616 */ 617 void setTemplateContextChanged(boolean changed) { 618 619 m_changedContext = changed; 620 } 621 622 /** 623 * Submits the settings form.<p> 624 * 625 * @param formParam the form 626 * @param fieldValues the field values 627 * @param editedFields the changed fields 628 */ 629 void submitForm(CmsForm formParam, final Map<String, String> fieldValues, Set<String> editedFields) { 630 631 String modelGroupId = null; 632 633 if (CmsInheritanceContainerEditor.getInstance() != null) { 634 CmsInheritanceContainerEditor.getInstance().onSettingsEdited(); 635 } 636 if (m_contextsWidget != null) { 637 String newTemplateContexts = m_contextsWidget.getFormValueAsString(); 638 if ((newTemplateContexts == null) || "".equals(newTemplateContexts)) { 639 newTemplateContexts = CmsTemplateContextInfo.EMPTY_VALUE; 640 // translate an empty selection to "none" 641 } 642 fieldValues.put(CmsTemplateContextInfo.SETTING, newTemplateContexts); 643 } 644 final boolean hasFormatterChanges; 645 if (m_formatterSelect != null) { 646 fieldValues.put( 647 CmsFormatterConfig.getSettingsKeyForContainer(m_containerId), 648 m_formatterSelect.getFormValueAsString()); 649 hasFormatterChanges = true; 650 } else { 651 hasFormatterChanges = false; 652 if (m_originalFormatter != null) { 653 // in case there is only 1 formatter, we still want to send the formatter key to the server to avoid cases 654 // where the element is removed because no default formatter can be found in the active sitemap config. 655 fieldValues.put(CmsFormatterConfig.getSettingsKeyForContainer(m_containerId), m_originalFormatter); 656 } 657 } 658 if (m_createNewCheckBox != null) { 659 m_elementWidget.setCreateNew(m_createNewCheckBox.isChecked()); 660 fieldValues.put(CmsContainerElement.CREATE_AS_NEW, Boolean.toString(m_createNewCheckBox.isChecked())); 661 } 662 if (m_modelGroupSelect != null) { 663 GroupOption group = GroupOption.valueOf(m_modelGroupSelect.getFormValueAsString()); 664 switch (group) { 665 case disabled: 666 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.noGroup.name()); 667 fieldValues.put(CmsContainerElement.USE_AS_COPY_MODEL, Boolean.toString(false)); 668 break; 669 case copy: 670 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.isModelGroup.name()); 671 fieldValues.put(CmsContainerElement.USE_AS_COPY_MODEL, Boolean.toString(true)); 672 break; 673 case reuse: 674 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.isModelGroup.name()); 675 fieldValues.put(CmsContainerElement.USE_AS_COPY_MODEL, Boolean.toString(false)); 676 break; 677 default: 678 break; 679 } 680 if (group != GroupOption.disabled) { 681 modelGroupId = CmsContainerpageController.getServerId(m_elementBean.getClientId()); 682 } 683 } 684 685 if ((m_modelGroupBreakUp != null) && m_modelGroupBreakUp.isChecked()) { 686 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.noGroup.name()); 687 } 688 689 final Map<String, String> filteredFieldValues = new HashMap<String, String>(); 690 for (Map.Entry<String, String> entry : fieldValues.entrySet()) { 691 String key = entry.getKey(); 692 String value = entry.getValue(); 693 if ((value != null) && (value.length() > 0)) { 694 filteredFieldValues.put(key, value); 695 } 696 } 697 final String changeModelGroupId = modelGroupId; 698 I_ReloadHandler reloadHandler = new I_ReloadHandler() { 699 700 CmsContainerPageElementPanel m_newElement; 701 CmsContainerPageElementPanel m_oldElement; 702 703 @Override 704 public void finish() { 705 706 if (isTemplateContextChanged()) { 707 // if the context multiselect box isn't displayed, of course it can't change values, 708 // and this code won't be executed. 709 CmsContainerpageController.get().handleChangeTemplateContext( 710 m_newElement, 711 filteredFieldValues.get(CmsTemplateContextInfo.SETTING)); 712 } 713 if (hasFormatterChanges) { 714 updateCss(); 715 } 716 if (m_newElement.getElement().getInnerHTML().contains(CmsGwtConstants.FORMATTER_RELOAD_MARKER) 717 && !CmsContainerpageController.get().isGroupcontainerEditing()) { 718 CmsContainerpageController.get().reloadPage(); 719 } 720 if (m_modelGroupSelect != null) { 721 m_controller.setModelGroupElementId(changeModelGroupId); 722 } 723 m_controller.sendElementEditedSettings(m_newElement, m_oldElement); 724 } 725 726 @Override 727 public void onReload(CmsContainerPageElementPanel oldElement, CmsContainerPageElementPanel newElement) { 728 729 m_oldElement = oldElement; 730 m_newElement = newElement; 731 } 732 733 }; 734 m_controller.reloadElementWithSettings( 735 m_elementWidget, 736 m_elementBean.getClientId(), 737 filteredFieldValues, 738 reloadHandler); 739 } 740 741 /** 742 * Updates the CSS resources for the selected formatter.<p> 743 */ 744 void updateCss() { 745 746 String formatterId = m_formatterSelect.getFormValueAsString(); 747 CmsFormatterConfig formatter = m_elementBean.getFormatters().get(m_containerId).get(formatterId); 748 Set<String> cssResources = formatter.getCssResources(); 749 for (String cssResource : cssResources) { 750 CmsDomUtil.ensureStyleSheetIncluded(cssResource); 751 } 752 if (formatter.hasInlineCss()) { 753 ensureInlineCss(formatterId, formatter.getInlineCss()); 754 } 755 } 756 757 /** 758 * Adds the create new checkbox to the given field set.<p> 759 * 760 * @param elementBean the element bean 761 * @param fieldSet the field set 762 */ 763 private void addCreateNewCheckbox(CmsContainerElementData elementBean, CmsFieldSet fieldSet) { 764 765 m_createNewCheckBox = new CmsCheckBox(Messages.get().key(Messages.GUI_CREATE_NEW_LABEL_0)); 766 m_createNewCheckBox.setDisplayInline(false); 767 m_createNewCheckBox.getElement().getStyle().setMarginTop(7, Style.Unit.PX); 768 m_createNewCheckBox.setChecked(elementBean.isCreateNew()); 769 fieldSet.add(m_createNewCheckBox); 770 } 771 772 /** 773 * Adds the model group settings fields to the given field set.<p> 774 * 775 * @param elementBean the element bean 776 * @param elementWidget the element widget 777 * @param fieldSet the field set 778 */ 779 private void addModelGroupSettings( 780 CmsContainerElementData elementBean, 781 CmsContainerPageElementPanel elementWidget, 782 CmsFieldSet fieldSet) { 783 784 Map<String, String> groupOptions = new LinkedHashMap<String, String>(); 785 groupOptions.put(GroupOption.disabled.name(), GroupOption.disabled.getLabel()); 786 groupOptions.put(GroupOption.copy.name(), GroupOption.copy.getLabel()); 787 groupOptions.put(GroupOption.reuse.name(), GroupOption.reuse.getLabel()); 788 m_modelGroupSelect = new CmsSelectBox(groupOptions); 789 if (elementWidget.isModelGroup()) { 790 if (Boolean.valueOf(elementBean.getSettings().get(CmsContainerElement.USE_AS_COPY_MODEL)).booleanValue()) { 791 m_modelGroupSelect.selectValue(GroupOption.copy.name()); 792 } else { 793 m_modelGroupSelect.selectValue(GroupOption.reuse.name()); 794 } 795 } 796 CmsFormRow selectRow = new CmsFormRow(); 797 selectRow.getLabel().setText(Messages.get().key(Messages.GUI_USE_AS_MODEL_GROUP_LABEL_0)); 798 selectRow.getWidgetContainer().add(m_modelGroupSelect); 799 fieldSet.add(selectRow); 800 } 801 802 /** 803 * Ensures the CSS snippet with the given ID is present.<p> 804 * 805 * @param formatterId the ID 806 * @param cssContent the CSS snippet 807 */ 808 private native void ensureInlineCss(String formatterId, String cssContent)/*-{ 809 var styles = $wnd.document.styleSheets; 810 for (var i = 0; i < styles.length; i++) { 811 // IE uses the owningElement property 812 var styleNode = styles[i].owningElement ? styles[i].owningElement 813 : styles[i].ownerNode; 814 if (styleNode != null && styleNode.rel == formatterId) { 815 // inline css is present 816 return; 817 } 818 } 819 // include inline css into head 820 var headID = $wnd.document.getElementsByTagName("head")[0]; 821 var cssNode = $wnd.document.createElement('style'); 822 cssNode.type = 'text/css'; 823 cssNode.rel = formatterId; 824 if (cssNode.styleSheet) { 825 // in case of IE 826 cssNode.styleSheet.cssText = cssContent; 827 } else { 828 // otherwise 829 cssNode.appendChild(document.createTextNode(cssContent)); 830 } 831 headID.appendChild(cssNode); 832 }-*/; 833}