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.Messages; 032import org.opencms.ade.containerpage.client.ui.groupeditor.CmsInheritanceContainerEditor; 033import org.opencms.ade.containerpage.shared.CmsContainerElement; 034import org.opencms.ade.containerpage.shared.CmsContainerElement.ModelGroupState; 035import org.opencms.ade.containerpage.shared.CmsContainerElementData; 036import org.opencms.ade.containerpage.shared.CmsElementSettingsConfig; 037import org.opencms.ade.containerpage.shared.CmsFormatterConfig; 038import org.opencms.ade.containerpage.shared.CmsFormatterConfigCollection; 039import org.opencms.gwt.client.CmsCoreProvider; 040import org.opencms.gwt.client.ui.CmsFieldSet; 041import org.opencms.gwt.client.ui.contextmenu.CmsContextMenuButton; 042import org.opencms.gwt.client.ui.contextmenu.CmsDialogContextMenuHandler; 043import org.opencms.gwt.client.ui.css.I_CmsInputLayoutBundle; 044import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 045import org.opencms.gwt.client.ui.input.CmsCheckBox; 046import org.opencms.gwt.client.ui.input.CmsMultiCheckBox; 047import org.opencms.gwt.client.ui.input.CmsSelectBox; 048import org.opencms.gwt.client.ui.input.CmsSelectComboBox; 049import org.opencms.gwt.client.ui.input.I_CmsFormField; 050import org.opencms.gwt.client.ui.input.I_CmsFormWidget; 051import org.opencms.gwt.client.ui.input.form.A_CmsFormFieldPanel; 052import org.opencms.gwt.client.ui.input.form.CmsBasicFormField; 053import org.opencms.gwt.client.ui.input.form.CmsDialogFormHandler; 054import org.opencms.gwt.client.ui.input.form.CmsFieldTooltip; 055import org.opencms.gwt.client.ui.input.form.CmsFieldTooltip.Data; 056import org.opencms.gwt.client.ui.input.form.CmsFieldsetFormFieldPanel; 057import org.opencms.gwt.client.ui.input.form.CmsForm; 058import org.opencms.gwt.client.ui.input.form.CmsFormDialog; 059import org.opencms.gwt.client.ui.input.form.CmsFormRow; 060import org.opencms.gwt.client.ui.input.form.CmsInfoBoxFormFieldPanel; 061import org.opencms.gwt.client.ui.input.form.CmsWidgetFactoryRegistry; 062import org.opencms.gwt.client.ui.input.form.I_CmsFormSubmitHandler; 063import org.opencms.gwt.client.ui.input.form.I_CmsFormWidgetMultiFactory; 064import org.opencms.gwt.client.util.CmsDomUtil; 065import org.opencms.gwt.client.util.I_CmsSimpleCallback; 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 hidden field widget name. */ 187 private static final String HIDDEN_FIELD_WIDGET = "hidden"; 188 189 /** The container page controller. */ 190 CmsContainerpageController m_controller; 191 192 /** Checkbox to set the 'model group' status. */ 193 CmsSelectBox m_modelGroupSelect; 194 195 /** The template context changed flag. */ 196 private boolean m_changedContext; 197 198 /** The current container id. */ 199 private String m_containerId; 200 201 /** The template context info. */ 202 private CmsTemplateContextInfo m_contextInfo; 203 204 /** The template context widget. */ 205 private CmsMultiCheckBox m_contextsWidget; 206 207 /** Checkbox to set the 'createNew' status. */ 208 private CmsCheckBox m_createNewCheckBox; 209 210 /** The element data bean. */ 211 private CmsContainerElementData m_elementBean; 212 213 /** The element panel. */ 214 private CmsContainerPageElementPanel m_elementWidget; 215 216 /** Id of currently selected formatter. */ 217 private String m_formatter; 218 219 /** The formatter select widget. */ 220 private CmsSelectBox m_formatterSelect; 221 222 /** The break up model group checkbox. */ 223 private CmsCheckBox m_modelGroupBreakUp; 224 225 /** The original formatter key. */ 226 private String m_originalFormatter; 227 228 /** Setting presets. */ 229 private Map<String, String> m_presets; 230 231 /** The element setting values. */ 232 private Map<String, String> m_settings; 233 234 /** 235 * Constructor.<p> 236 * 237 * @param controller the container page controller 238 * @param elementWidget the element panel 239 * @param settingsConfig the element setting configuration 240 * @param settingPresets the presets for settings 241 * 242 * @throws NoFormatterException if no formatter configuration is found for the element 243 */ 244 public CmsElementSettingsDialog( 245 CmsContainerpageController controller, 246 CmsContainerPageElementPanel elementWidget, 247 CmsElementSettingsConfig settingsConfig, 248 Map<String, String> settingPresets) 249 throws NoFormatterException { 250 251 super(Messages.get().key(Messages.GUI_PROPERTY_DIALOG_TITLE_0), new CmsForm(false), null); 252 setAnimationEnabled(false); 253 setUseAnimation(false); 254 addStyleName(I_CmsLayoutBundle.INSTANCE.elementSettingsDialogCss().elementSettingsDialog()); 255 m_presets = settingPresets != null ? settingPresets : new HashMap<String, String>(); 256 CmsContainerElementData elementBean = settingsConfig.getElementData(); 257 m_elementWidget = elementWidget; 258 m_controller = controller; 259 m_elementBean = elementBean; 260 m_contextInfo = m_controller.getData().getTemplateContextInfo(); 261 m_containerId = m_elementWidget.getParentTarget().getContainerId(); 262 CmsListInfoBean infoBean = new CmsListInfoBean(); 263 infoBean.setResourceState(settingsConfig.getState()); 264 infoBean.setTitle(elementBean.getTitle()); 265 infoBean.setSubTitle(elementBean.getSitePath()); 266 infoBean.setResourceType(elementBean.getResourceType()); 267 infoBean.setBigIconClasses(elementBean.getBigIconClasses()); 268 m_settings = elementBean.getSettings(); 269 A_CmsFormFieldPanel formFieldPanel = null; 270 CmsFormatterConfig currentFormatterConfig = m_elementBean.getFormatterConfig(m_containerId); 271 if (currentFormatterConfig == null) { 272 throw new NoFormatterException(); 273 } 274 for (CmsAdditionalInfoBean addInfo : settingsConfig.getAdditionalInfo()) { 275 infoBean.addAdditionalInfo(addInfo.getName(), addInfo.getValue(), addInfo.getStyle()); 276 } 277 // infoBean.addAdditionalInfo(Messages.get().key(Messages.GUI_ADDINFO_FORMATTER_PATH_0), formatterPath); 278 I_CmsDropContainer dropContainer = elementWidget.getParentTarget(); 279 if (dropContainer instanceof CmsContainerPageContainer) { 280 CmsContainerPageContainer cpc = (CmsContainerPageContainer)dropContainer; 281 String type = cpc.getContainerType(); 282 String name = cpc.getContainerId(); 283 infoBean.addAdditionalInfo(Messages.get().key(Messages.GUI_ADDINFO_FORMATTER_CONTAINER_0), name); 284 infoBean.addAdditionalInfo(Messages.get().key(Messages.GUI_ADDINFO_FORMATTER_CONTAINER_TYPE_0), type); 285 } 286 287 boolean isEditableModelGroup = CmsCoreProvider.get().getUserInfo().isDeveloper() 288 && m_controller.getData().isModelGroup() 289 && ((m_controller.getModelGroupElementId() == null) 290 || CmsContainerpageController.getServerId(elementBean.getClientId()).equals( 291 m_controller.getModelGroupElementId())); 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 (isEditableModelGroup && !elementWidget.hasModelGroupParent()) { 360 addModelGroupSettings(elementBean, elementWidget, modelGroupFieldSet); 361 } else if (!elementWidget.isModelGroup()) { 362 addCreateNewCheckbox(elementBean, modelGroupFieldSet); 363 } 364 if (modelGroupFieldSet.getWidgetCount() > 0) { 365 fieldSetPanel.getMainPanel().insert(modelGroupFieldSet, 1); 366 } 367 368 } else if (elementWidget.isModelGroup()) { 369 CmsFieldSet modelGroupFieldSet = new CmsFieldSet(); 370 modelGroupFieldSet.setLegend(Messages.get().key(Messages.GUI_CREATE_NEW_LEGEND_0 371 372 )); 373 modelGroupFieldSet.getElement().getStyle().setMarginTop(10, Unit.PX); 374 m_modelGroupBreakUp = new CmsCheckBox(Messages.get().key(Messages.GUI_MODEL_GROUP_BREAK_UP_0)); 375 m_modelGroupBreakUp.setDisplayInline(false); 376 m_modelGroupBreakUp.getElement().getStyle().setMarginTop(7, Style.Unit.PX); 377 modelGroupFieldSet.add(m_modelGroupBreakUp); 378 fieldSetPanel.getMainPanel().insert(modelGroupFieldSet, 1); 379 } 380 381 if (m_contextInfo.shouldShowElementTemplateContextSelection()) { 382 String templateContexts = m_settings.get(CmsTemplateContextInfo.SETTING); 383 if (templateContexts == null) { 384 templateContexts = CmsStringUtil.listAsString( 385 new ArrayList<String>( 386 CmsContainerpageController.get().getData().getTemplateContextInfo().getContextLabels().keySet()), 387 "|"); 388 } else if (templateContexts.equals(CmsTemplateContextInfo.EMPTY_VALUE)) { 389 // translate "none" to an empty selection 390 templateContexts = ""; 391 } 392 m_settings.put(CmsTemplateContextInfo.SETTING, templateContexts); 393 394 CmsFieldSet contextsFieldset = new CmsFieldSet(); 395 contextsFieldset.setLegend(m_contextInfo.getSettingDefinition().getNiceName()); 396 contextsFieldset.getElement().getStyle().setMarginTop(10, Style.Unit.PX); 397 m_contextsWidget = new CmsMultiCheckBox( 398 CmsStringUtil.splitAsMap(m_contextInfo.getSettingDefinition().getWidgetConfiguration(), "|", ":")); 399 for (CmsCheckBox checkbox : m_contextsWidget.getCheckboxes()) { 400 Style checkboxStyle = checkbox.getElement().getStyle(); 401 checkbox.getButton().getElement().getStyle().setFontWeight(Style.FontWeight.NORMAL); 402 checkboxStyle.setMarginTop(7, Style.Unit.PX); 403 } 404 m_contextsWidget.setFormValueAsString(m_settings.get(CmsTemplateContextInfo.SETTING)); 405 m_contextsWidget.addValueChangeHandler(new ValueChangeHandler<String>() { 406 407 public void onValueChange(ValueChangeEvent<String> event) { 408 409 setTemplateContextChanged(true); 410 } 411 }); 412 contextsFieldset.add(m_contextsWidget); 413 fieldSetPanel.getMainPanel().add(contextsFieldset); 414 } 415 } else { 416 formFieldPanel = new CmsInfoBoxFormFieldPanel(infoBean); 417 } 418 419 CmsUUID serverId = null; 420 if (elementBean.isModelGroup()) { 421 serverId = elementBean.getModelGroupId(); 422 } else { 423 String id = CmsContainerpageController.getServerId(elementBean.getClientId()); 424 if (CmsUUID.isValidUUID(id) && !(new CmsUUID(id).isNullUUID())) { 425 serverId = new CmsUUID(id); 426 } 427 } 428 if (serverId != null) { 429 CmsContextMenuButton menuButton = new CmsContextMenuButton( 430 serverId, 431 new CmsDialogContextMenuHandler(), 432 AdeContext.resourceinfo); 433 menuButton.addStyleName(I_CmsLayoutBundle.INSTANCE.listItemWidgetCss().permaVisible()); 434 formFieldPanel.getInfoWidget().addButton(menuButton); 435 } 436 437 getForm().setWidget(formFieldPanel); 438 formFieldPanel.addStyleName(I_CmsInputLayoutBundle.INSTANCE.inputCss().formGradientBackground()); 439 I_CmsFormSubmitHandler submitHandler = new I_CmsFormSubmitHandler() { 440 441 /** 442 * @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) 443 */ 444 public void onSubmitForm( 445 CmsForm formParam, 446 final Map<String, String> fieldValues, 447 Set<String> editedFields) { 448 449 submitForm(formParam, fieldValues, editedFields); 450 } 451 }; 452 CmsDialogFormHandler formHandler = new CmsDialogFormHandler(); 453 formHandler.setSubmitHandler(submitHandler); 454 getForm().setFormHandler(formHandler); 455 formHandler.setDialog(this); 456 renderSettingsForm( 457 m_elementBean.getSettingConfig(m_containerId), 458 m_elementBean.getFormatterConfig(m_containerId).getNestedFormatterPrefixes()); 459 } 460 461 /** 462 * @see org.opencms.gwt.client.ui.input.form.CmsFormDialog#center() 463 */ 464 @Override 465 public void center() { 466 467 show(); 468 } 469 470 /** 471 * @see org.opencms.gwt.client.ui.input.form.I_CmsFormWidgetMultiFactory#createFormWidget(java.lang.String, java.util.Map, com.google.common.base.Optional) 472 */ 473 public I_CmsFormWidget createFormWidget( 474 String key, 475 Map<String, String> widgetParams, 476 Optional<String> defaultValue) { 477 478 if (CmsSelectBox.WIDGET_TYPE.equals(key) || CmsSelectComboBox.WIDGET_TYPE.equals(key)) { 479 if ((defaultValue != null) && defaultValue.isPresent() && widgetParams.containsKey(defaultValue.get())) { 480 key = key + CmsSelectBox.NOTNULL_SUFFIX; 481 } 482 Map<String, String> newParams = new HashMap<>(); 483 newParams.putAll(widgetParams); 484 newParams.put(CmsSelectBox.OPTION_RESIZABLE, "false"); 485 widgetParams = newParams; 486 } 487 488 return CmsWidgetFactoryRegistry.instance().createFormWidget(key, widgetParams, defaultValue); 489 } 490 491 /** 492 * @see com.google.gwt.user.client.ui.PopupPanel#setPopupPosition(int, int) 493 */ 494 @Override 495 public void setPopupPosition(int left, int top) { 496 497 // positioning handled via CSS 498 } 499 500 /** 501 * @see org.opencms.gwt.client.ui.input.form.CmsFormDialog#show() 502 */ 503 @Override 504 public void show() { 505 506 super.show(); 507 // positioning handled by CSS 508 getElement().getStyle().clearPosition(); 509 getElement().getStyle().clearLeft(); 510 getElement().getStyle().clearTop(); 511 512 } 513 514 /** 515 * Returns if the template context has been changed.<p> 516 * 517 * @return <code>true</code> if the template context has been changed 518 */ 519 boolean isTemplateContextChanged() { 520 521 return m_changedContext; 522 } 523 524 /** 525 * Handles the formatter selection changes.<p> 526 * 527 * @param formatterId the formatter id 528 */ 529 void onFormatterChange(String formatterId) { 530 531 m_formatter = formatterId; 532 CmsFormatterConfig config = m_elementBean.getFormatters().get(m_containerId).get(formatterId); 533 renderSettingsForm(config.getSettingConfig(), config.getNestedFormatterPrefixes()); 534 } 535 536 /** 537 * Renders the settings form.<p> 538 * 539 * @param settingsConfig the settings configuration 540 * @param nestedFormatterPrefixes the nested formatter prefixes 541 */ 542 void renderSettingsForm( 543 Map<String, CmsXmlContentProperty> settingsConfig, 544 Map<String, String> nestedFormatterPrefixes) { 545 546 Map<String, String> presets = m_presets; 547 if (presets == null) { 548 presets = new HashMap<String, String>(); 549 } 550 List<String> groups = new ArrayList<String>(getForm().getGroups()); 551 for (String group : groups) { 552 getForm().removeGroup(group); 553 } 554 555 CmsFieldsetFormFieldPanel formFieldPanel = null; 556 if (getForm().getWidget() instanceof CmsFieldsetFormFieldPanel) { 557 formFieldPanel = ((CmsFieldsetFormFieldPanel)getForm().getWidget()); 558 } 559 if ((formFieldPanel != null) && (nestedFormatterPrefixes != null) && !nestedFormatterPrefixes.isEmpty()) { 560 for (Entry<String, String> entry : nestedFormatterPrefixes.entrySet()) { 561 CmsFieldSet fieldSet = new CmsFieldSet(); 562 fieldSet.setLegend(entry.getValue()); 563 fieldSet.getElement().getStyle().setMarginTop(10, Style.Unit.PX); 564 formFieldPanel.addGroupFieldSet(entry.getKey(), fieldSet); 565 } 566 } 567 // using LinkedHashMap to preserve the order 568 Map<String, I_CmsFormField> formFields = new LinkedHashMap<String, I_CmsFormField>(); 569 for (CmsXmlContentProperty propConfig : settingsConfig.values()) { 570 if (m_presets.containsKey(propConfig.getName())) { 571 // settings configured as presets on the container are not user-editable 572 continue; 573 } 574 CmsBasicFormField currentField = CmsBasicFormField.createField( 575 propConfig, 576 propConfig.getName(), 577 this, 578 Collections.<String, String> emptyMap(), 579 false); 580 formFields.put(propConfig.getName(), currentField); 581 582 } 583 for (I_CmsFormField field : formFields.values()) { 584 585 String fieldId = field.getId(); 586 CmsXmlContentProperty propDef = settingsConfig.get(fieldId); 587 // skip hidden fields 588 if (!HIDDEN_FIELD_WIDGET.equals(propDef.getWidget())) { 589 String initialValue = m_settings.get(fieldId); 590 if (initialValue == null) { 591 592 initialValue = propDef.getDefault(); 593 } 594 String group = ""; 595 if ((nestedFormatterPrefixes != null) && !nestedFormatterPrefixes.isEmpty()) { 596 for (String prefix : nestedFormatterPrefixes.keySet()) { 597 if (fieldId.startsWith(prefix)) { 598 group = prefix; 599 break; 600 } 601 } 602 } 603 604 getForm().addField(group, field, initialValue); 605 } 606 } 607 getForm().render(); 608 } 609 610 /** 611 * Sets the template context changed flag.<p> 612 * @param changed the template context changed flag 613 */ 614 void setTemplateContextChanged(boolean changed) { 615 616 m_changedContext = changed; 617 } 618 619 /** 620 * Submits the settings form.<p> 621 * 622 * @param formParam the form 623 * @param fieldValues the field values 624 * @param editedFields the changed fields 625 */ 626 void submitForm(CmsForm formParam, final Map<String, String> fieldValues, Set<String> editedFields) { 627 628 String modelGroupId = null; 629 630 if (CmsInheritanceContainerEditor.getInstance() != null) { 631 CmsInheritanceContainerEditor.getInstance().onSettingsEdited(); 632 } 633 if (m_contextsWidget != null) { 634 String newTemplateContexts = m_contextsWidget.getFormValueAsString(); 635 if ((newTemplateContexts == null) || "".equals(newTemplateContexts)) { 636 newTemplateContexts = CmsTemplateContextInfo.EMPTY_VALUE; 637 // translate an empty selection to "none" 638 } 639 fieldValues.put(CmsTemplateContextInfo.SETTING, newTemplateContexts); 640 } 641 final boolean hasFormatterChanges; 642 if (m_formatterSelect != null) { 643 fieldValues.put( 644 CmsFormatterConfig.getSettingsKeyForContainer(m_containerId), 645 m_formatterSelect.getFormValueAsString()); 646 hasFormatterChanges = true; 647 } else { 648 hasFormatterChanges = false; 649 if (m_originalFormatter != null) { 650 // in case there is only 1 formatter, we still want to send the formatter key to the server to avoid cases 651 // where the element is removed because no default formatter can be found in the active sitemap config. 652 fieldValues.put(CmsFormatterConfig.getSettingsKeyForContainer(m_containerId), m_originalFormatter); 653 } 654 } 655 if (m_createNewCheckBox != null) { 656 m_elementWidget.setCreateNew(m_createNewCheckBox.isChecked()); 657 fieldValues.put(CmsContainerElement.CREATE_AS_NEW, Boolean.toString(m_createNewCheckBox.isChecked())); 658 } 659 if (m_modelGroupSelect != null) { 660 GroupOption group = GroupOption.valueOf(m_modelGroupSelect.getFormValueAsString()); 661 switch (group) { 662 case disabled: 663 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.noGroup.name()); 664 fieldValues.put(CmsContainerElement.USE_AS_COPY_MODEL, Boolean.toString(false)); 665 break; 666 case copy: 667 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.isModelGroup.name()); 668 fieldValues.put(CmsContainerElement.USE_AS_COPY_MODEL, Boolean.toString(true)); 669 break; 670 case reuse: 671 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.isModelGroup.name()); 672 fieldValues.put(CmsContainerElement.USE_AS_COPY_MODEL, Boolean.toString(false)); 673 break; 674 default: 675 break; 676 } 677 if (group != GroupOption.disabled) { 678 modelGroupId = CmsContainerpageController.getServerId(m_elementBean.getClientId()); 679 } 680 } 681 682 if ((m_modelGroupBreakUp != null) && m_modelGroupBreakUp.isChecked()) { 683 fieldValues.put(CmsContainerElement.MODEL_GROUP_STATE, ModelGroupState.noGroup.name()); 684 } 685 686 final Map<String, String> filteredFieldValues = new HashMap<String, String>(); 687 for (Map.Entry<String, String> entry : fieldValues.entrySet()) { 688 String key = entry.getKey(); 689 String value = entry.getValue(); 690 if ((value != null) && (value.length() > 0)) { 691 filteredFieldValues.put(key, value); 692 } 693 } 694 final String changeModelGroupId = modelGroupId; 695 m_controller.reloadElementWithSettings( 696 m_elementWidget, 697 m_elementBean.getClientId(), 698 filteredFieldValues, 699 new I_CmsSimpleCallback<CmsContainerPageElementPanel>() { 700 701 public void execute(CmsContainerPageElementPanel result) { 702 703 if (isTemplateContextChanged()) { 704 // if the context multiselect box isn't displayed, of course it can't change values, 705 // and this code won't be executed. 706 CmsContainerpageController.get().handleChangeTemplateContext( 707 result, 708 filteredFieldValues.get(CmsTemplateContextInfo.SETTING)); 709 } 710 if (hasFormatterChanges) { 711 updateCss(); 712 } 713 if (result.getElement().getInnerHTML().contains(CmsGwtConstants.FORMATTER_RELOAD_MARKER) 714 && !CmsContainerpageController.get().isGroupcontainerEditing()) { 715 CmsContainerpageController.get().reloadPage(); 716 } 717 if (m_modelGroupSelect != null) { 718 m_controller.setModelGroupElementId(changeModelGroupId); 719 } 720 } 721 722 }); 723 } 724 725 /** 726 * Updates the CSS resources for the selected formatter.<p> 727 */ 728 void updateCss() { 729 730 String formatterId = m_formatterSelect.getFormValueAsString(); 731 CmsFormatterConfig formatter = m_elementBean.getFormatters().get(m_containerId).get(formatterId); 732 Set<String> cssResources = formatter.getCssResources(); 733 for (String cssResource : cssResources) { 734 CmsDomUtil.ensureStyleSheetIncluded(cssResource); 735 } 736 if (formatter.hasInlineCss()) { 737 ensureInlineCss(formatterId, formatter.getInlineCss()); 738 } 739 } 740 741 /** 742 * Adds the create new checkbox to the given field set.<p> 743 * 744 * @param elementBean the element bean 745 * @param fieldSet the field set 746 */ 747 private void addCreateNewCheckbox(CmsContainerElementData elementBean, CmsFieldSet fieldSet) { 748 749 m_createNewCheckBox = new CmsCheckBox(Messages.get().key(Messages.GUI_CREATE_NEW_LABEL_0)); 750 m_createNewCheckBox.setDisplayInline(false); 751 m_createNewCheckBox.getElement().getStyle().setMarginTop(7, Style.Unit.PX); 752 m_createNewCheckBox.setChecked(elementBean.isCreateNew()); 753 fieldSet.add(m_createNewCheckBox); 754 } 755 756 /** 757 * Adds the model group settings fields to the given field set.<p> 758 * 759 * @param elementBean the element bean 760 * @param elementWidget the element widget 761 * @param fieldSet the field set 762 */ 763 private void addModelGroupSettings( 764 CmsContainerElementData elementBean, 765 CmsContainerPageElementPanel elementWidget, 766 CmsFieldSet fieldSet) { 767 768 Map<String, String> groupOptions = new LinkedHashMap<String, String>(); 769 groupOptions.put(GroupOption.disabled.name(), GroupOption.disabled.getLabel()); 770 groupOptions.put(GroupOption.copy.name(), GroupOption.copy.getLabel()); 771 groupOptions.put(GroupOption.reuse.name(), GroupOption.reuse.getLabel()); 772 m_modelGroupSelect = new CmsSelectBox(groupOptions); 773 if (elementWidget.isModelGroup()) { 774 if (Boolean.valueOf(elementBean.getSettings().get(CmsContainerElement.USE_AS_COPY_MODEL)).booleanValue()) { 775 m_modelGroupSelect.selectValue(GroupOption.copy.name()); 776 } else { 777 m_modelGroupSelect.selectValue(GroupOption.reuse.name()); 778 } 779 } 780 CmsFormRow selectRow = new CmsFormRow(); 781 selectRow.getLabel().setText(Messages.get().key(Messages.GUI_USE_AS_MODEL_GROUP_LABEL_0)); 782 selectRow.getWidgetContainer().add(m_modelGroupSelect); 783 fieldSet.add(selectRow); 784 } 785 786 /** 787 * Ensures the CSS snippet with the given ID is present.<p> 788 * 789 * @param formatterId the ID 790 * @param cssContent the CSS snippet 791 */ 792 private native void ensureInlineCss(String formatterId, String cssContent)/*-{ 793 var styles = $wnd.document.styleSheets; 794 for (var i = 0; i < styles.length; i++) { 795 // IE uses the owningElement property 796 var styleNode = styles[i].owningElement ? styles[i].owningElement 797 : styles[i].ownerNode; 798 if (styleNode != null && styleNode.rel == formatterId) { 799 // inline css is present 800 return; 801 } 802 } 803 // include inline css into head 804 var headID = $wnd.document.getElementsByTagName("head")[0]; 805 var cssNode = $wnd.document.createElement('style'); 806 cssNode.type = 'text/css'; 807 cssNode.rel = formatterId; 808 if (cssNode.styleSheet) { 809 // in case of IE 810 cssNode.styleSheet.cssText = cssContent; 811 } else { 812 // otherwise 813 cssNode.appendChild(document.createTextNode(cssContent)); 814 } 815 headID.appendChild(cssNode); 816 }-*/; 817}