001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt.client.ui.contextmenu; 029 030import org.opencms.gwt.client.CmsCoreProvider; 031import org.opencms.gwt.client.property.CmsActiveFieldData; 032import org.opencms.gwt.client.property.CmsPropertySubmitHandler; 033import org.opencms.gwt.client.property.CmsSimplePropertyEditorHandler; 034import org.opencms.gwt.client.property.CmsVfsModePropertyEditor; 035import org.opencms.gwt.client.property.I_CmsPropertySaver; 036import org.opencms.gwt.client.property.definition.CmsPropertyDefinitionButton; 037import org.opencms.gwt.client.rpc.CmsRpcAction; 038import org.opencms.gwt.client.ui.CmsPushButton; 039import org.opencms.gwt.client.ui.I_CmsButton.ButtonColor; 040import org.opencms.gwt.client.ui.I_CmsButton.ButtonStyle; 041import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 042import org.opencms.gwt.client.ui.input.form.CmsDialogFormHandler; 043import org.opencms.gwt.client.ui.input.form.CmsForm; 044import org.opencms.gwt.client.ui.input.form.CmsFormDialog; 045import org.opencms.gwt.client.ui.input.form.I_CmsFormHandler; 046import org.opencms.gwt.client.ui.input.form.I_CmsFormSubmitHandler; 047import org.opencms.gwt.client.util.CmsDebugLog; 048import org.opencms.gwt.shared.CmsContextMenuEntryBean; 049import org.opencms.gwt.shared.property.CmsPropertiesBean; 050import org.opencms.util.CmsUUID; 051 052import java.util.List; 053 054import com.google.common.collect.Lists; 055import com.google.gwt.core.client.Scheduler; 056import com.google.gwt.core.client.Scheduler.RepeatingCommand; 057import com.google.gwt.dom.client.Style.Float; 058import com.google.gwt.event.dom.client.ClickEvent; 059import com.google.gwt.event.dom.client.ClickHandler; 060import com.google.gwt.event.logical.shared.CloseEvent; 061import com.google.gwt.event.logical.shared.CloseHandler; 062import com.google.gwt.user.client.rpc.AsyncCallback; 063import com.google.gwt.user.client.ui.FlowPanel; 064import com.google.gwt.user.client.ui.PopupPanel; 065import com.google.gwt.user.client.ui.Widget; 066 067/** 068 * The class for the "edit properties" context menu entries.<p> 069 * 070 * @since 8.0.0 071 */ 072public final class CmsEditProperties implements I_CmsHasContextMenuCommand { 073 074 /** 075 * Interface used to access the next/previous file for which to edit properties. 076 */ 077 public static interface I_MultiFileNavigation { 078 079 /** 080 * Requests the next / previous file id.<p> 081 * 082 * @param offset should be 1 for the next file, or -1 for the previous file 083 * @param callback the callback to call with the id 084 */ 085 void requestNextFile(int offset, AsyncCallback<CmsUUID> callback); 086 } 087 088 /** 089 * Helper class which encapsulates the differences between the contexts where the property edit dialog is opened.<p> 090 */ 091 public static class PropertyEditingContext { 092 093 /** The cancel handler. */ 094 protected Runnable m_cancelHandler; 095 096 /** The dialog instance. */ 097 protected CmsFormDialog m_formDialog; 098 099 /** The form handler. */ 100 protected I_CmsFormHandler m_formHandler; 101 102 /** Enable/disable property definition button. */ 103 private boolean m_allowCreateProperties = true; 104 105 /** Flag to control whether the file name field should be focused after opening the property dialog. */ 106 private boolean m_focusNameField; 107 108 /** The file navigation. */ 109 private I_MultiFileNavigation m_multiFileNavigation; 110 111 /** The property saver. */ 112 private I_CmsPropertySaver m_propertySaver; 113 114 /** The restart command (used to open the property dialog again after closing e.g. the property definition dialog). */ 115 private Runnable m_restart; 116 117 /** 118 * Returns true if the property definition button should be enabled.<p> 119 * 120 * @return true if the user should be able to define new properties 121 */ 122 public boolean allowCreateProperties() { 123 124 return m_allowCreateProperties; 125 } 126 127 /** 128 * Creates the property definition button.<p> 129 * 130 * @return the property definition button 131 */ 132 public CmsPropertyDefinitionButton createPropertyDefinitionButton() { 133 134 return new CmsPropertyDefinitionButton() { 135 136 /** 137 * @see org.opencms.gwt.client.property.definition.CmsPropertyDefinitionButton#onBeforeEditPropertyDefinition() 138 */ 139 @Override 140 public void onBeforeEditPropertyDefinition() { 141 142 m_formDialog.hide(); 143 } 144 145 /** 146 * @see org.opencms.gwt.client.property.definition.CmsPropertyDefinitionButton#onClosePropertyDefinitionDialog() 147 */ 148 @SuppressWarnings("synthetic-access") 149 @Override 150 public void onClosePropertyDefinitionDialog() { 151 152 if (m_restart != null) { 153 m_restart.run(); 154 } 155 } 156 }; 157 158 } 159 160 /** 161 * Gets the form dialog.<p> 162 * 163 * @return the form dialog 164 */ 165 public CmsFormDialog getDialog() { 166 167 return m_formDialog; 168 } 169 170 /** 171 * Gets the property saver.<p> 172 * 173 * @return the property saver 174 */ 175 public I_CmsPropertySaver getPropertySaver() { 176 177 return m_propertySaver; 178 } 179 180 /** 181 * Initializes the close handler of the dialog.<p> 182 */ 183 public void initCloseHandler() { 184 185 if (m_cancelHandler != null) { 186 m_formDialog.addCloseHandler(new CloseHandler<PopupPanel>() { 187 188 public void onClose(CloseEvent<PopupPanel> event) { 189 190 if (!m_formHandler.isSubmitting()) { 191 m_cancelHandler.run(); 192 } 193 } 194 }); 195 } 196 } 197 198 /** 199 * Return true if the file name field should be focused after opening the dialog.<p> 200 * 201 * @return true if the file name field should be focused 202 */ 203 public boolean isFocusNameField() { 204 205 return m_focusNameField; 206 } 207 208 /** 209 * Enables / disables the 'define property' functionality.<p> 210 * 211 * @param allowCreateProperties true if the user should be able to create new properties 212 */ 213 public void setAllowCreateProperties(boolean allowCreateProperties) { 214 215 m_allowCreateProperties = allowCreateProperties; 216 } 217 218 /** 219 * Sets the cancel handler.<p> 220 * 221 * @param cancelHandler the cancel handler 222 */ 223 public void setCancelHandler(Runnable cancelHandler) { 224 225 m_cancelHandler = cancelHandler; 226 } 227 228 /** 229 * Sets the form dialog.<p> 230 * 231 * @param formDialog the form dialog 232 */ 233 public void setDialog(CmsFormDialog formDialog) { 234 235 m_formDialog = formDialog; 236 } 237 238 /** 239 * Enables / disables focusing on the name field. 240 * 241 * @param focusNameField true if the file name field should be focused after opening the dialog 242 * 243 * */ 244 public void setFocusNameField(boolean focusNameField) { 245 246 m_focusNameField = focusNameField; 247 } 248 249 /** 250 * Sets the form handler.<p> 251 * 252 * @param formHandler the form handler 253 */ 254 public void setFormHandler(I_CmsFormHandler formHandler) { 255 256 m_formHandler = formHandler; 257 } 258 259 /** 260 * Sets the file navigation object.<p> 261 * 262 * @param nav the file navigation object 263 */ 264 public void setMultiFileNavigation(I_MultiFileNavigation nav) { 265 266 m_multiFileNavigation = nav; 267 } 268 269 /** 270 * Sets the property saver.<p> 271 * 272 * @param saver the property saver 273 */ 274 public void setPropertySaver(I_CmsPropertySaver saver) { 275 276 m_propertySaver = saver; 277 } 278 279 /** 280 * Sets the restart command (used to open the property dialog again after a secondary dialog). 281 * 282 * @param command the restart command 283 */ 284 public void setRestart(Runnable command) { 285 286 m_restart = command; 287 } 288 289 /** 290 * Gets the file navigation object.<p> 291 * 292 * @return the file navigation object 293 */ 294 private I_MultiFileNavigation getMultiFileNavigation() { 295 296 return m_multiFileNavigation; 297 298 } 299 300 } 301 302 /** 303 * Helper class for editing properties in the workplace.<p> 304 */ 305 public static class WorkplacePropertyEditorContext implements I_CmsFormHandler { 306 307 /** The cancel handler. */ 308 private Runnable m_cancelHandler; 309 310 /** The context menu handler. */ 311 private I_CmsContextMenuHandler m_contextMenuHandler; 312 313 /** The dialog. */ 314 private PropertiesFormDialog m_dialog; 315 316 /** The edit context. */ 317 private PropertyEditingContext m_editContext; 318 319 /** True if name should be edited. */ 320 private boolean m_editName; 321 322 /** The property editor. */ 323 private CmsVfsModePropertyEditor m_editor; 324 325 /** True if ADE template selection should be enabled. */ 326 private boolean m_enableAdeTemplateSelect; 327 328 /** The editor handler. */ 329 private PropertyEditorHandler m_handler; 330 331 /** True if last button was prev/next. */ 332 private boolean m_isPrevNext; 333 334 /** The active field data. */ 335 private CmsActiveFieldData m_prevFieldData; 336 337 /** Structure id of the current resource. */ 338 private CmsUUID m_structureId; 339 340 /** The submit handler.*/ 341 private I_CmsFormSubmitHandler m_submitHandler; 342 343 /** True if form is currently being submitted. */ 344 private boolean m_submitting; 345 346 /** 347 * Creates a new instance.<p> 348 * 349 * @param structureId the structure id of the resource 350 * @param contextMenuHandler the context menu handler 351 * @param editName true if name should be editable 352 * @param cancelHandler the cancel handler 353 * @param enableAdeTemplateSelect true if ADE template selection should be enabled 354 * @param editContext the edit context 355 * @param prevFieldData the previous field data 356 */ 357 public WorkplacePropertyEditorContext( 358 CmsUUID structureId, 359 I_CmsContextMenuHandler contextMenuHandler, 360 boolean editName, 361 Runnable cancelHandler, 362 boolean enableAdeTemplateSelect, 363 PropertyEditingContext editContext, 364 CmsActiveFieldData prevFieldData) { 365 366 m_structureId = structureId; 367 m_contextMenuHandler = contextMenuHandler; 368 m_editName = editName; 369 m_cancelHandler = cancelHandler; 370 m_enableAdeTemplateSelect = enableAdeTemplateSelect; 371 m_editContext = editContext; 372 m_prevFieldData = prevFieldData; 373 374 m_dialog = new PropertiesFormDialog("XXX", null); 375 376 m_editContext.setDialog(m_dialog); 377 m_dialog.catchNotifications(); 378 @SuppressWarnings("synthetic-access") 379 final I_MultiFileNavigation fileNavigation = m_editContext.getMultiFileNavigation(); 380 List<CmsPushButton> additionalLeftButtons = Lists.newArrayList(); 381 if (fileNavigation != null) { 382 CmsPushButton prevButton = new CmsPushButton(); 383 prevButton.setText("<<"); 384 String prevText = org.opencms.gwt.client.Messages.get().key( 385 org.opencms.gwt.client.Messages.GUI_BUTTON_PREV_RESOURCE_0); 386 prevButton.setTitle(prevText); 387 String nextText = org.opencms.gwt.client.Messages.get().key( 388 org.opencms.gwt.client.Messages.GUI_BUTTON_NEXT_RESOURCE_0); 389 CmsPushButton nextButton = new CmsPushButton(); 390 nextButton.setText(">>"); 391 nextButton.setTitle(nextText); 392 for (CmsPushButton button : new CmsPushButton[] {prevButton, nextButton}) { 393 button.setButtonStyle(ButtonStyle.TEXT, ButtonColor.BLUE); 394 // button.getElement().getStyle().setFloat(Float.LEFT); 395 } 396 397 final AsyncCallback<CmsUUID> loadHandler = new AsyncCallback<CmsUUID>() { 398 399 public void onFailure(Throwable caught) { 400 401 CmsDebugLog.consoleLog("" + caught); 402 } 403 404 @SuppressWarnings("synthetic-access") 405 public void onSuccess(CmsUUID nextId) { 406 407 CmsActiveFieldData fieldData = getActiveFieldData(); 408 m_prevFieldData = fieldData; 409 m_structureId = nextId; 410 editProperties(); 411 } 412 }; 413 prevButton.addClickHandler(new ClickHandler() { 414 415 @SuppressWarnings("synthetic-access") 416 public void onClick(ClickEvent event) { 417 418 m_isPrevNext = true; 419 m_dialog.getForm().validateAndSubmit(); 420 m_handler.setNextAction(new Runnable() { 421 422 public void run() { 423 424 fileNavigation.requestNextFile(-1, loadHandler); 425 } 426 }); 427 } 428 }); 429 nextButton.addClickHandler(new ClickHandler() { 430 431 @SuppressWarnings("synthetic-access") 432 public void onClick(ClickEvent event) { 433 434 m_isPrevNext = true; 435 m_dialog.getForm().validateAndSubmit(); 436 m_handler.setNextAction(new Runnable() { 437 438 public void run() { 439 440 fileNavigation.requestNextFile(1, loadHandler); 441 } 442 }); 443 444 } 445 }); 446 additionalLeftButtons.add(prevButton); 447 additionalLeftButtons.add(nextButton); 448 } 449 450 m_editContext.setRestart(() -> { 451 WorkplacePropertyEditorContext context = new WorkplacePropertyEditorContext( 452 m_structureId, 453 contextMenuHandler, 454 editName, 455 cancelHandler, 456 enableAdeTemplateSelect, 457 new PropertyEditingContext(), 458 prevFieldData); 459 context.editProperties(); 460 461 }); 462 CmsPropertyDefinitionButton defButton = m_editContext.createPropertyDefinitionButton(); 463 464 FlowPanel leftButtonBox = new FlowPanel(); 465 String boxStyle = org.opencms.gwt.client.ui.css.I_CmsLayoutBundle.INSTANCE.dialogCss().leftButtonBox(); 466 leftButtonBox.addStyleName(boxStyle); 467 leftButtonBox.getElement().getStyle().setFloat(Float.LEFT); 468 for (CmsPushButton additionalButton : additionalLeftButtons) { 469 leftButtonBox.add(additionalButton); 470 } 471 if (CmsCoreProvider.get().getUserInfo().isDeveloper()) { 472 defButton.setDialog(m_dialog); 473 leftButtonBox.add(defButton); 474 } 475 m_dialog.addButton(leftButtonBox); 476 477 m_dialog.addCloseHandler(new CloseHandler<PopupPanel>() { 478 479 /** 480 * @see com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt.event.logical.shared.CloseEvent) 481 */ 482 @SuppressWarnings("synthetic-access") 483 public void onClose(CloseEvent<PopupPanel> event) {} 484 }); 485 486 } 487 488 /** 489 * Edits properties for current resource.<p> 490 */ 491 public void editProperties() { 492 493 CmsRpcAction<CmsPropertiesBean> action = new CmsRpcAction<CmsPropertiesBean>() { 494 495 @SuppressWarnings("synthetic-access") 496 @Override 497 public void execute() { 498 499 start(0, true); 500 CmsCoreProvider.getVfsService().loadPropertyData(m_structureId, this); 501 } 502 503 @SuppressWarnings("synthetic-access") 504 @Override 505 protected void onResponse(CmsPropertiesBean result) { 506 507 stop(false); 508 updateData(result); 509 } 510 511 }; 512 action.execute(); 513 514 } 515 516 /** 517 * Gets the structure id. 518 * 519 * @return the structure id 520 */ 521 public CmsUUID getStructureId() { 522 523 return m_structureId; 524 } 525 526 /** 527 * @see org.opencms.gwt.client.ui.input.form.I_CmsFormHandler#isSubmitting() 528 */ 529 public boolean isSubmitting() { 530 531 return m_submitting; 532 } 533 534 /** 535 * @see org.opencms.gwt.client.ui.input.form.I_CmsFormHandler#onSubmitValidationResult(org.opencms.gwt.client.ui.input.form.CmsForm, boolean) 536 */ 537 public void onSubmitValidationResult(CmsForm form, boolean ok) { 538 539 if (ok) { 540 m_submitting = true; 541 if (!m_isPrevNext) { 542 m_contextMenuHandler.refreshResource(CmsUUID.getNullUUID()); 543 m_dialog.hide(); 544 } 545 m_isPrevNext = false; 546 form.handleSubmit(m_submitHandler); 547 } else { 548 m_dialog.setOkButtonEnabled(form.noFieldsInvalid()); 549 } 550 } 551 552 /** 553 * @see org.opencms.gwt.client.ui.input.form.I_CmsFormHandler#onValidationResult(org.opencms.gwt.client.ui.input.form.CmsForm, boolean) 554 */ 555 public void onValidationResult(CmsForm form, boolean ok) { 556 557 m_dialog.setOkButtonEnabled(ok); 558 } 559 560 /** 561 * Gets the active field data.<p> 562 * 563 * @return the active field data 564 */ 565 CmsActiveFieldData getActiveFieldData() { 566 567 if (m_editor != null) { 568 return m_editor.getActiveFieldData(); 569 } else { 570 return null; 571 } 572 } 573 574 /** 575 * Updates the property dialog with the next resource.<p> 576 * 577 * @param result the data for the next resource 578 */ 579 private void updateData(CmsPropertiesBean result) { 580 581 final PropertyEditorHandler handler = new PropertyEditorHandler(null); 582 m_handler = handler; 583 handler.setEnableAdeTemplateSelect(m_enableAdeTemplateSelect); 584 m_editContext.setCancelHandler(m_cancelHandler); 585 586 handler.setPropertiesBean(result); 587 handler.setEditableName(m_editName); 588 final CmsVfsModePropertyEditor editor = new CmsVfsModePropertyEditor( 589 result.getPropertyDefinitions(), 590 handler); 591 m_editor = editor; 592 editor.setShowResourceProperties(!handler.isFolder()); 593 editor.setReadOnly(result.isReadOnly()); 594 595 m_editContext.setFormHandler(this); 596 597 m_submitHandler = new CmsPropertySubmitHandler(handler); 598 editor.getForm().setFormHandler(this); 599 try { 600 CmsVfsModePropertyEditor.disableResize(true); 601 editor.restoreActiveFieldData(m_prevFieldData); 602 editor.initializeWidgets(m_dialog); 603 m_dialog.setForm(editor.getForm()); 604 m_dialog.centerHorizontally(50); 605 } finally { 606 CmsVfsModePropertyEditor.disableResize(false); 607 } 608 609 } 610 611 } 612 613 /** 614 * Property editor handler which uses a text box for the template selection.<p> 615 */ 616 protected static class PropertyEditorHandler extends CmsSimplePropertyEditorHandler { 617 618 /** Enables the ADE template select box for pages. */ 619 private boolean m_enableAdeTemplateSelect; 620 621 /** The stored callback. */ 622 private Runnable m_nextAction; 623 624 /** 625 * Creates a new instance.<p> 626 * 627 * @param handler the handler 628 */ 629 public PropertyEditorHandler(I_CmsContextMenuHandler handler) { 630 631 super(handler); 632 } 633 634 /** 635 * Executes and clears the stored callback.<p> 636 */ 637 public void runAction() { 638 639 if (m_nextAction != null) { 640 m_nextAction.run(); 641 m_nextAction = null; 642 } 643 } 644 645 /** 646 * Enables or disables the ADE template select box for pages.<p> 647 * 648 * @param enableAdeTemplateSelect true if ADE template select box for pages should be enabled 649 */ 650 public void setEnableAdeTemplateSelect(boolean enableAdeTemplateSelect) { 651 652 m_enableAdeTemplateSelect = enableAdeTemplateSelect; 653 } 654 655 /** 656 * Stores an action to execute after successful submits.<p> 657 * 658 * @param runnable the callback 659 */ 660 public void setNextAction(Runnable runnable) { 661 662 m_nextAction = runnable; 663 664 } 665 666 /** 667 * @see org.opencms.gwt.client.property.CmsSimplePropertyEditorHandler#useAdeTemplates() 668 */ 669 @Override 670 public boolean useAdeTemplates() { 671 672 return m_enableAdeTemplateSelect; 673 } 674 675 /** 676 * @see org.opencms.gwt.client.property.CmsSimplePropertyEditorHandler#onSubmitSuccess() 677 */ 678 @Override 679 protected void onSubmitSuccess() { 680 681 super.onSubmitSuccess(); 682 runAction(); 683 } 684 685 } 686 687 /** 688 * Property dialog subclass which keeps track of which way the dialog is exited.<p> 689 */ 690 static class PropertiesFormDialog extends CmsFormDialog { 691 692 /** The content panel. */ 693 private FlowPanel m_content = new FlowPanel(); 694 695 /** True if the dialog should be truly exited. */ 696 private boolean m_maybeExit; 697 698 /** 699 * Creates a new instance.<p> 700 * 701 * @param title the title 702 * @param form the form 703 */ 704 public PropertiesFormDialog(String title, CmsForm form) { 705 706 super(title, form); 707 setMainContent(m_content); 708 } 709 710 /** 711 * Return true if OK or Cancel was clicked previously.<p> 712 * 713 * @return true if OK or Cancel was clicked previously 714 */ 715 public boolean maybeExit() { 716 717 return m_maybeExit; 718 } 719 720 /** 721 * @see org.opencms.gwt.client.ui.input.form.CmsFormDialog#onClickCancel() 722 */ 723 @Override 724 public void onClickCancel() { 725 726 m_maybeExit = true; 727 super.onClickCancel(); 728 } 729 730 /** 731 * Sets the form.<p> 732 * 733 * @param form the form 734 */ 735 public void setForm(CmsForm form) { 736 737 m_form = form; 738 } 739 740 /** 741 * @see org.opencms.gwt.client.ui.input.form.CmsFormDialog#initContent() 742 */ 743 @Override 744 protected void initContent() { 745 746 int prevHeight = m_content.getOffsetHeight(); 747 if (m_content.getWidgetCount() > 0) { 748 int childPrevHeight = m_content.getWidget(0).getOffsetHeight(); 749 if (childPrevHeight > 0) { 750 prevHeight = childPrevHeight; 751 } 752 } 753 final String parentStyle = I_CmsLayoutBundle.INSTANCE.propertiesCss().propertyParentLoading(); 754 if (prevHeight > 0) { 755 m_content.getElement().getStyle().setProperty("minHeight", "" + prevHeight + "px"); 756 } 757 m_content.addStyleName(parentStyle); 758 m_content.clear(); 759 final Widget formWidget = m_form.getWidget(); 760 m_content.add(formWidget); 761 762 Scheduler.get().scheduleFixedDelay(new RepeatingCommand() { 763 764 @SuppressWarnings("synthetic-access") 765 public boolean execute() { 766 767 if (!formWidget.isAttached()) { 768 m_content.removeStyleName(parentStyle); 769 return false; 770 } 771 if (formWidget.getOffsetHeight() > 100) { 772 m_content.getElement().getStyle().clearProperty("minHeight"); 773 m_content.removeStyleName(parentStyle); 774 return false; 775 } 776 return true; 777 } 778 }, 100); 779 } 780 781 /** 782 * @see org.opencms.gwt.client.ui.input.form.CmsFormDialog#onClickOk() 783 */ 784 @Override 785 protected void onClickOk() { 786 787 m_maybeExit = true; 788 super.onClickOk(); 789 } 790 } 791 792 /** 793 * Hidden utility class constructor.<p> 794 */ 795 private CmsEditProperties() { 796 797 // nothing to do 798 } 799 800 /** 801 * Starts the property editor for the resource with the given structure id.<p> 802 * 803 * @param structureId the structure id of a resource 804 * @param contextMenuHandler the context menu handler 805 * @param editName if true, provides a field for changing the file name 806 * @param cancelHandler callback which is executed if the user cancels the property dialog 807 * @param enableAdeTemplateSelect enables/disables special template selector 808 * @param editContext the editing context 809 */ 810 public static void editProperties( 811 final CmsUUID structureId, 812 final I_CmsContextMenuHandler contextMenuHandler, 813 final boolean editName, 814 final Runnable cancelHandler, 815 final boolean enableAdeTemplateSelect, 816 final PropertyEditingContext editContext) { 817 818 CmsRpcAction<CmsPropertiesBean> action = new CmsRpcAction<CmsPropertiesBean>() { 819 820 @Override 821 public void execute() { 822 823 start(0, true); 824 CmsCoreProvider.getVfsService().loadPropertyData(structureId, this); 825 } 826 827 @Override 828 protected void onResponse(CmsPropertiesBean result) { 829 830 stop(false); 831 openPropertyDialog( 832 result, 833 contextMenuHandler, 834 editName, 835 cancelHandler, 836 enableAdeTemplateSelect, 837 editContext); 838 } 839 840 }; 841 action.execute(); 842 } 843 844 /** 845 * Starts the property editor for the resource with the given structure id.<p> 846 * 847 * @param structureId the structure id of a resource 848 * @param contextMenuHandler the context menu handler 849 * @param editName if true, provides a field for changing the file name 850 * @param cancelHandler callback which is executed if the user cancels the property dialog 851 * @param enableAdeTemplateSelect enables/disables special template selector 852 * @param editContext the editing context 853 * @param prevFieldData the previous active field data (may be null) 854 */ 855 public static void editPropertiesWithFileNavigation( 856 final CmsUUID structureId, 857 final I_CmsContextMenuHandler contextMenuHandler, 858 final boolean editName, 859 final Runnable cancelHandler, 860 final boolean enableAdeTemplateSelect, 861 final PropertyEditingContext editContext, 862 final CmsActiveFieldData prevFieldData) { 863 864 new WorkplacePropertyEditorContext( 865 structureId, 866 contextMenuHandler, 867 editName, 868 cancelHandler, 869 enableAdeTemplateSelect, 870 editContext, 871 prevFieldData).editProperties(); 872 873 } 874 875 /** 876 * Returns the context menu command according to 877 * {@link org.opencms.gwt.client.ui.contextmenu.I_CmsHasContextMenuCommand}.<p> 878 * 879 * @return the context menu command 880 */ 881 public static I_CmsContextMenuCommand getContextMenuCommand() { 882 883 return new I_CmsContextMenuCommand() { 884 885 public void execute(CmsUUID structureId, I_CmsContextMenuHandler handler, CmsContextMenuEntryBean bean) { 886 887 editProperties(structureId, handler, false, null, true, new PropertyEditingContext()); 888 } 889 890 public A_CmsContextMenuItem getItemWidget( 891 CmsUUID structureId, 892 I_CmsContextMenuHandler handler, 893 CmsContextMenuEntryBean bean) { 894 895 return null; 896 } 897 898 public boolean hasItemWidget() { 899 900 return false; 901 } 902 }; 903 } 904 905 /** 906 * Opens the property dialog and populates it with the data from a given CmsPropertiesBean.<p> 907 * 908 * @param result the property data 909 * @param contextMenuHandler the context menu handler 910 * @param editName true if the name should be editable 911 * @param cancelHandler the cancel handler 912 * @param enableAdeTemplateSelect true if template selection should be enabled 913 * @param editContext the edit context 914 */ 915 public static void openPropertyDialog( 916 CmsPropertiesBean result, 917 final I_CmsContextMenuHandler contextMenuHandler, 918 final boolean editName, 919 final Runnable cancelHandler, 920 final boolean enableAdeTemplateSelect, 921 final PropertyEditingContext editContext) { 922 923 final PropertyEditorHandler handler = new PropertyEditorHandler(contextMenuHandler); 924 handler.setPropertySaver(editContext.getPropertySaver()); 925 handler.setEnableAdeTemplateSelect(enableAdeTemplateSelect); 926 editContext.setCancelHandler(cancelHandler); 927 928 handler.setPropertiesBean(result); 929 handler.setEditableName(editName); 930 final CmsVfsModePropertyEditor editor = new CmsVfsModePropertyEditor(result.getPropertyDefinitions(), handler); 931 932 editor.setShowResourceProperties(!handler.isFolder()); 933 editor.setReadOnly(result.isReadOnly()); 934 935 final CmsFormDialog dialog = new PropertiesFormDialog(handler.getDialogTitle(), editor.getForm()); 936 editContext.setDialog(dialog); 937 938 if (editContext.allowCreateProperties()) { 939 CmsPropertyDefinitionButton defButton = editContext.createPropertyDefinitionButton(); 940 defButton.installOnDialog(dialog); 941 defButton.getElement().getStyle().setFloat(Float.LEFT); 942 } 943 final CmsDialogFormHandler formHandler = new CmsDialogFormHandler(); 944 editContext.setFormHandler(formHandler); 945 editContext.initCloseHandler(); 946 formHandler.setDialog(dialog); 947 I_CmsFormSubmitHandler submitHandler = new CmsPropertySubmitHandler(handler); 948 formHandler.setSubmitHandler(submitHandler); 949 editor.getForm().setFormHandler(formHandler); 950 editor.initializeWidgets(dialog); 951 952 dialog.centerHorizontally(50); 953 if (editContext.isFocusNameField()) { 954 editor.focusNameField(); 955 } 956 957 dialog.catchNotifications(); 958 } 959 960}