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