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; 029 030import org.opencms.ade.containerpage.client.CmsContainerpageController.ElementRemoveMode; 031import org.opencms.ade.containerpage.client.ui.CmsContainerPageContainer; 032import org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel; 033import org.opencms.ade.containerpage.client.ui.CmsElementSettingsDialog; 034import org.opencms.ade.containerpage.client.ui.CmsElementSettingsDialog.NoFormatterException; 035import org.opencms.ade.containerpage.client.ui.CmsGroupContainerElementPanel; 036import org.opencms.ade.containerpage.client.ui.CmsListAddDialog; 037import org.opencms.ade.containerpage.client.ui.CmsSmallElementsHandler; 038import org.opencms.ade.containerpage.client.ui.I_CmsDropContainer; 039import org.opencms.ade.containerpage.shared.CmsContainerElement; 040import org.opencms.ade.containerpage.shared.CmsContainerElementData; 041import org.opencms.ade.containerpage.shared.CmsElementSettingsConfig; 042import org.opencms.ade.containerpage.shared.CmsElementViewInfo; 043import org.opencms.ade.containerpage.shared.CmsLocaleLinkBean; 044import org.opencms.ade.publish.client.CmsPublishDialog; 045import org.opencms.ade.publish.shared.CmsPublishOptions; 046import org.opencms.ade.upload.client.I_CmsUploadContext; 047import org.opencms.ade.upload.client.lists.CmsUploadPopup; 048import org.opencms.gwt.client.CmsCoreProvider; 049import org.opencms.gwt.client.I_CmsEditableData; 050import org.opencms.gwt.client.dnd.I_CmsDNDController; 051import org.opencms.gwt.client.rpc.CmsRpcAction; 052import org.opencms.gwt.client.ui.A_CmsToolbarHandler; 053import org.opencms.gwt.client.ui.A_CmsToolbarMenu; 054import org.opencms.gwt.client.ui.CmsAcceptDeclineCancelDialog; 055import org.opencms.gwt.client.ui.CmsAlertDialog; 056import org.opencms.gwt.client.ui.CmsConfirmDialog; 057import org.opencms.gwt.client.ui.CmsListItem; 058import org.opencms.gwt.client.ui.CmsLockReportDialog; 059import org.opencms.gwt.client.ui.CmsModelSelectDialog; 060import org.opencms.gwt.client.ui.CmsNotification; 061import org.opencms.gwt.client.ui.CmsNotification.Type; 062import org.opencms.gwt.client.ui.I_CmsAcceptDeclineCancelHandler; 063import org.opencms.gwt.client.ui.I_CmsConfirmDialogHandler; 064import org.opencms.gwt.client.ui.I_CmsModelSelectHandler; 065import org.opencms.gwt.client.ui.I_CmsToolbarButton; 066import org.opencms.gwt.client.ui.contenteditor.I_CmsContentEditorHandler; 067import org.opencms.gwt.client.ui.contextmenu.A_CmsContextMenuItem; 068import org.opencms.gwt.client.ui.contextmenu.CmsContextMenuEntry; 069import org.opencms.gwt.client.ui.contextmenu.CmsPreview; 070import org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuCommand; 071import org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuEntry; 072import org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuHandler; 073import org.opencms.gwt.client.ui.css.I_CmsInputCss; 074import org.opencms.gwt.client.ui.css.I_CmsInputLayoutBundle; 075import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 076import org.opencms.gwt.client.ui.input.CmsSelectBox; 077import org.opencms.gwt.client.ui.resourceinfo.CmsResourceInfoDialog; 078import org.opencms.gwt.client.util.CmsDomUtil; 079import org.opencms.gwt.client.util.CmsStyleVariable; 080import org.opencms.gwt.client.util.I_CmsSimpleCallback; 081import org.opencms.gwt.shared.CmsClientVariantInfo; 082import org.opencms.gwt.shared.CmsContextMenuEntryBean; 083import org.opencms.gwt.shared.CmsCoreData; 084import org.opencms.gwt.shared.CmsCoreData.AdeContext; 085import org.opencms.gwt.shared.CmsGwtConstants; 086import org.opencms.gwt.shared.CmsListElementCreationDialogData; 087import org.opencms.gwt.shared.CmsListElementCreationOption; 088import org.opencms.gwt.shared.CmsLockInfo; 089import org.opencms.gwt.shared.CmsModelResourceInfo; 090import org.opencms.gwt.shared.CmsTemplateContextInfo; 091import org.opencms.gwt.shared.I_CmsEditableDataExtensions; 092import org.opencms.util.CmsStringUtil; 093import org.opencms.util.CmsUUID; 094 095import java.util.ArrayList; 096import java.util.Arrays; 097import java.util.Date; 098import java.util.HashMap; 099import java.util.Iterator; 100import java.util.List; 101import java.util.Map; 102 103import com.google.common.base.Objects; 104import com.google.common.collect.Lists; 105import com.google.common.collect.Maps; 106import com.google.gwt.dom.client.Style; 107import com.google.gwt.dom.client.Style.Position; 108import com.google.gwt.dom.client.Style.Unit; 109import com.google.gwt.event.logical.shared.CloseEvent; 110import com.google.gwt.event.logical.shared.CloseHandler; 111import com.google.gwt.event.logical.shared.ValueChangeEvent; 112import com.google.gwt.event.logical.shared.ValueChangeHandler; 113import com.google.gwt.http.client.UrlBuilder; 114import com.google.gwt.user.client.Command; 115import com.google.gwt.user.client.Cookies; 116import com.google.gwt.user.client.Window; 117import com.google.gwt.user.client.rpc.AsyncCallback; 118import com.google.gwt.user.client.ui.PopupPanel; 119import com.google.gwt.user.client.ui.RootPanel; 120import com.google.gwt.user.client.ui.SimplePanel; 121 122/** 123 * The container-page handler.<p> 124 * 125 * @since 8.0.0 126 */ 127public class CmsContainerpageHandler extends A_CmsToolbarHandler { 128 129 /** 130 * Action which is executed when the user selects a client variant.<p> 131 */ 132 class ClientVariantSelectAction implements Runnable { 133 134 /** The template context name. */ 135 private String m_context; 136 137 /** The variant bean. */ 138 private CmsClientVariantInfo m_variant; 139 140 /** 141 * Creates a new instance.<p> 142 * 143 * @param context the context name 144 * @param variant the variant information 145 */ 146 public ClientVariantSelectAction(String context, CmsClientVariantInfo variant) { 147 148 m_context = context; 149 m_variant = variant; 150 } 151 152 /** 153 * @see java.lang.Runnable#run() 154 */ 155 public void run() { 156 157 deactivateCurrentButton(); 158 m_clientVariantDisplay.show(m_context, m_variant); 159 } 160 } 161 162 /** 163 * Action which does nothing.<p> 164 */ 165 public static final Runnable DO_NOTHING = new Runnable() { 166 167 /** 168 * @see java.lang.Runnable#run() 169 */ 170 public void run() { 171 172 // do nothing 173 174 } 175 176 }; 177 178 /** The container-page controller. */ 179 protected CmsContainerpageController m_controller; 180 181 /** The container-page editor. */ 182 protected CmsContainerpageEditor m_editor; 183 184 /** The widget used for displaying the client variants. */ 185 CmsClientVariantDisplay m_clientVariantDisplay = new CmsClientVariantDisplay(this); 186 187 /** The currently active tool-bar button. */ 188 private I_CmsToolbarButton m_activeButton; 189 190 /** The edit button visibility style variable. */ 191 private CmsStyleVariable m_editButtonVibility; 192 193 /** Overlay to prevent user actions while shown. */ 194 private SimplePanel m_overlay; 195 196 /** Field to store the 'prefill' context menu entry that gets manually moved to a different location later by the context menu code. */ 197 private CmsContextMenuEntryBean m_prefill; 198 199 /** 200 * Constructor.<p> 201 * 202 * @param controller the container-page controller 203 * @param editor the container-page editor 204 */ 205 public CmsContainerpageHandler(CmsContainerpageController controller, CmsContainerpageEditor editor) { 206 207 m_controller = controller; 208 m_editor = editor; 209 m_editButtonVibility = new CmsStyleVariable(RootPanel.get()); 210 } 211 212 /** 213 * Activates the selection button.<p> 214 */ 215 public void activateSelection() { 216 217 m_editor.getSelection().setActive(true); 218 setEditButtonsVisible(true); 219 reInitInlineEditing(); 220 } 221 222 /** 223 * Adds the given list item widget to the favorite list widget.<p> 224 * 225 * @param listItem the list item 226 */ 227 public void addToFavorites(CmsListItem listItem) { 228 229 m_editor.getClipboard().addToFavorites(listItem); 230 } 231 232 /** 233 * Adds the element with the given id to the favorite list.<p> 234 * 235 * @param clientId the client id 236 */ 237 public void addToFavorites(String clientId) { 238 239 m_controller.addToFavoriteList(clientId); 240 } 241 242 /** 243 * Adds the given list item widget to the recent list widget.<p> 244 * 245 * @param listItem the list item 246 */ 247 public void addToRecent(CmsListItem listItem) { 248 249 m_editor.getClipboard().addToRecent(listItem); 250 } 251 252 /** 253 * Adds the element with the given id to the favorite list.<p> 254 * 255 * @param clientId the client id 256 */ 257 public void addToRecent(String clientId) { 258 259 m_controller.addToRecentList(clientId, null); 260 } 261 262 /** 263 * Switches the template context.<p> 264 * 265 * @param cookieName the cookie name 266 * @param value the new template context 267 */ 268 @SuppressWarnings("deprecation") 269 public void changeTemplateContextManually(final String cookieName, final String value) { 270 271 if (value != null) { 272 Cookies.setCookie(cookieName, value, new Date(300, 0, 1), null, "/", false); 273 } else { 274 Cookies.removeCookie(cookieName, "/"); 275 } 276 Window.Location.reload(); 277 } 278 279 /** 280 * Checks whether GWT widgets are available for all fields of a content.<p> 281 * 282 * @param structureId the structure id of the content 283 * 284 * @param asyncCallback the callback for the result 285 */ 286 public void checkNewWidgetsAvailable(CmsUUID structureId, AsyncCallback<Boolean> asyncCallback) { 287 288 m_controller.checkNewWidgetsAvailable(structureId, asyncCallback); 289 } 290 291 /** 292 * Creates a context menu entry.<p> 293 * 294 * @param structureId structure id of the resource 295 * @param name the label 296 * @param checked true if checkbox should be displayed 297 * @param action the action to execute 298 * 299 * @return the menu entry 300 */ 301 public CmsContextMenuEntry createSimpleContextMenuEntry( 302 CmsUUID structureId, 303 String name, 304 boolean checked, 305 final Runnable action) { 306 307 CmsContextMenuEntry entry = createRawMenuEntry(structureId, action); 308 decorateMenuEntry(entry, name, checked); 309 return entry; 310 } 311 312 /** 313 * Creates a select box used to switch between views from the gallery dialog.<p> 314 * 315 * @return the created select box 316 */ 317 public CmsSelectBox createViewSelectorForGalleryDialog() { 318 319 List<CmsElementViewInfo> elementViews = m_controller.getData().getElementViews(); 320 if (elementViews.size() <= 1) { 321 return null; 322 } 323 CmsUUID currentView = m_controller.getElementView().getElementViewId(); 324 Map<String, String> options = Maps.newHashMap(); 325 for (CmsElementViewInfo view : elementViews) { 326 options.put("" + view.getElementViewId(), view.getTitle()); 327 } 328 CmsSelectBox result = new CmsSelectBox(options); 329 result.setFormValueAsString(currentView.toString()); 330 result.addValueChangeHandler(new ValueChangeHandler<String>() { 331 332 public void onValueChange(ValueChangeEvent<String> event) { 333 334 m_editor.getAdd().setActive(false); 335 CmsElementViewInfo newValue = m_controller.getView(event.getValue()); 336 setElementView(newValue, new Runnable() { 337 338 public void run() { 339 340 m_editor.getAdd().setActive(true); 341 } 342 }); 343 } 344 }); 345 result.getElement().getStyle().setWidth(250, Unit.PX); 346 347 return result; 348 } 349 350 /** 351 * De-activates the current button.<p> 352 */ 353 public void deactivateCurrentButton() { 354 355 if (m_activeButton != null) { 356 if (m_activeButton == m_editor.getSelection()) { 357 m_controller.disableInlineEditing(null); 358 } 359 m_activeButton.setActive(false); 360 m_activeButton = null; 361 } 362 setEditButtonsVisible(false); 363 } 364 365 /** 366 * De-activates menu button.<p> 367 */ 368 public void deactivateMenuButton() { 369 370 if ((m_activeButton != null) && (m_activeButton instanceof A_CmsToolbarMenu<?>)) { 371 ((A_CmsToolbarMenu<?>)m_activeButton).setActive(false); 372 } 373 } 374 375 /** 376 * Deactivates the selection.<p> 377 */ 378 public void deactivateSelection() { 379 380 m_editor.getSelection().setActive(false); 381 } 382 383 /** 384 * Deactivates all toolbar buttons.<p> 385 */ 386 public void disableToolbarButtons() { 387 388 m_editor.disableToolbarButtons(); 389 } 390 391 /** 392 * Starts the property editor for the given container element.<p> 393 * 394 * @param elementWidget the container element widget for which the properties should be edited 395 */ 396 public void editElementSettings(final CmsContainerPageElementPanel elementWidget) { 397 398 m_controller.getElementSettingsConfig( 399 elementWidget.getId(), 400 elementWidget.getParentTarget().getContainerId(), 401 new I_CmsSimpleCallback<CmsElementSettingsConfig>() { 402 403 public void execute(final CmsElementSettingsConfig settingsConfig) { 404 405 CmsContainerElementData elementBean = settingsConfig.getElementData(); 406 407 if (!elementBean.getClientId().equals(elementWidget.getId())) { 408 // the client id may have changed, update the element widget 409 elementWidget.setId(elementBean.getClientId()); 410 } 411 Map<String, String> settingPresets = getSettingPresets(elementWidget); 412 try { 413 CmsElementSettingsDialog dialog = new CmsElementSettingsDialog( 414 m_controller, 415 elementWidget, 416 settingsConfig, 417 settingPresets); 418 dialog.show(); 419 } catch (NoFormatterException e) { 420 String ctype = "???"; 421 String cname = "???"; 422 String schema = "???"; 423 if (settingsConfig.getSchema() != null) { 424 schema = settingsConfig.getSchema(); 425 } 426 try { 427 I_CmsDropContainer dropContainer = elementWidget.getParentTarget(); 428 if (dropContainer instanceof CmsContainerPageContainer) { 429 CmsContainerPageContainer cpc = (CmsContainerPageContainer)dropContainer; 430 ctype = cpc.getContainerType(); 431 cname = cpc.getContainerId(); 432 } 433 } catch (Exception e2) { 434 /*ignore*/ 435 } 436 String path = "???"; 437 try { 438 path = elementBean.getSitePath(); 439 } catch (Exception e2) { 440 /*ignore*/ 441 } 442 CmsAlertDialog alert = new CmsAlertDialog( 443 org.opencms.gwt.client.Messages.get().key(org.opencms.gwt.client.Messages.GUI_ERROR_0), 444 Messages.get().key(Messages.GUI_NO_FORMATTER_4, path, cname, ctype, schema)); 445 alert.center(); 446 } 447 } 448 449 /** 450 * Gets the map of setting presets.<p> 451 * 452 * @param elementWidget2 the element widget 453 * @return the setting presets 454 */ 455 private Map<String, String> getSettingPresets(CmsContainerPageElementPanel elementWidget2) { 456 457 I_CmsDropContainer dropContainer = elementWidget2.getParentTarget(); 458 if (dropContainer instanceof CmsContainerPageContainer) { 459 CmsContainerPageContainer container = (CmsContainerPageContainer)dropContainer; 460 return container.getSettingPresets(); 461 } else { 462 return new HashMap<String, String>(); 463 } 464 } 465 }); 466 } 467 468 /** 469 * Enables the favorites editing drag and drop controller.<p> 470 * 471 * @param enable if <code>true</code> favorites editing will enabled, otherwise disabled 472 * @param dndController the favorites editing drag and drop controller 473 */ 474 public void enableFavoriteEditing(boolean enable, I_CmsDNDController dndController) { 475 476 m_controller.enableFavoriteEditing(enable, dndController); 477 } 478 479 /** 480 * Enables the toolbar buttons.<p> 481 */ 482 public void enableToolbarButtons() { 483 484 m_editor.enableToolbarButtons(m_controller.hasPageChanged(), m_controller.getData().getNoEditReason()); 485 } 486 487 /** 488 * @see org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuHandler#ensureLockOnResource(org.opencms.util.CmsUUID, org.opencms.gwt.client.util.I_CmsSimpleCallback) 489 */ 490 public void ensureLockOnResource(CmsUUID structureId, I_CmsSimpleCallback<Boolean> callback) { 491 492 m_controller.lockContainerpage(callback); 493 } 494 495 /** 496 * @see org.opencms.gwt.client.ui.I_CmsToolbarHandler#getActiveButton() 497 */ 498 public I_CmsToolbarButton getActiveButton() { 499 500 return m_activeButton; 501 } 502 503 /** 504 * @see org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuHandler#getContextMenuCommands() 505 */ 506 public Map<String, I_CmsContextMenuCommand> getContextMenuCommands() { 507 508 return m_editor.getContextMenuCommands(); 509 } 510 511 /** 512 * @see org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuHandler#getContextType() 513 */ 514 public String getContextType() { 515 516 return CmsGwtConstants.CONTEXT_TYPE_CONTAINERPAGE_TOOLBAR; 517 } 518 519 /** 520 * @see org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuHandler#getEditorHandler() 521 */ 522 public I_CmsContentEditorHandler getEditorHandler() { 523 524 return m_controller.getContentEditorHandler(); 525 } 526 527 /** 528 * Leaves the current page and opens the site-map.<p> 529 */ 530 public void gotoSitemap() { 531 532 final String sitemapUri = CmsCoreProvider.get().link(m_controller.getData().getSitemapUri()); 533 if (sitemapUri.equals("")) { 534 return; // normally, we shouldn't even get to this point because the sitemap button should be disabled 535 } 536 Command leaveCommand = new Command() { 537 538 public void execute() { 539 540 Window.Location.replace( 541 sitemapUri 542 + "?" 543 + CmsCoreData.PARAM_PATH 544 + "=" 545 + CmsContainerpageController.getCurrentUri() 546 + "&" 547 + CmsCoreData.PARAM_RETURNCODE 548 + "=" 549 + m_controller.getReturnCode()); 550 } 551 552 }; 553 leavePage(leaveCommand); 554 } 555 556 /** 557 * Returns if the selection button is active.<p> 558 * 559 * @return <code>true</code> if the selection button is active 560 */ 561 public boolean hasActiveSelection() { 562 563 return m_editor.getSelection().isActive(); 564 } 565 566 /** 567 * Hides any open menu.<p> 568 */ 569 public void hideMenu() { 570 571 if ((m_activeButton != null) && (m_activeButton instanceof A_CmsToolbarMenu<?>)) { 572 ((A_CmsToolbarMenu<?>)m_activeButton).hideMenu(); 573 } 574 } 575 576 /** 577 * Removes page overlay if present.<p> 578 */ 579 public void hidePageOverlay() { 580 581 if (m_overlay != null) { 582 m_overlay.removeFromParent(); 583 } 584 } 585 586 /** 587 * Inserts the context menu.<p> 588 * 589 * @param menuBeans the menu beans from the server 590 * @param structureId the structure id of the resource for which the context menu entries should be generated 591 */ 592 public void insertContextMenu(List<CmsContextMenuEntryBean> menuBeans, CmsUUID structureId) { 593 594 List<I_CmsContextMenuEntry> menuEntries = transformEntries(menuBeans, structureId); 595 m_editor.getContext().showMenu(menuEntries); 596 } 597 598 /** 599 * Call to leave the page. Will open save/leave/cancel dialog if page contains any changes.<p> 600 * 601 * @param leavingCommand the page leaving command 602 */ 603 public void leavePage(final Command leavingCommand) { 604 605 if (!m_controller.hasPageChanged() || m_controller.isEditingDisabled()) { 606 leavingCommand.execute(); 607 return; 608 } 609 CmsAcceptDeclineCancelDialog leavingDialog = getLeaveDialog(); 610 leavingDialog.setHandler(new I_CmsAcceptDeclineCancelHandler() { 611 612 /** 613 * @see org.opencms.gwt.client.ui.I_CmsAcceptDeclineCancelHandler#onAccept() 614 */ 615 public void onAccept() { 616 617 m_controller.saveAndLeave(leavingCommand); 618 } 619 620 /** 621 * @see org.opencms.gwt.client.ui.I_CmsCloseDialogHandler#onClose() 622 */ 623 public void onClose() { 624 625 deactivateCurrentButton(); 626 activateSelection(); 627 } 628 629 /** 630 * @see org.opencms.gwt.client.ui.I_CmsAcceptDeclineCancelHandler#onDecline() 631 */ 632 public void onDecline() { 633 634 m_controller.setPageChanged(false, true); 635 leavingCommand.execute(); 636 } 637 }); 638 leavingDialog.center(); 639 } 640 641 /** 642 * Call to leave the page. Will open save/leave/cancel dialog if page contains any changes.<p> 643 * 644 * @param target the target 645 */ 646 public void leavePage(final String target) { 647 648 if (!m_controller.hasPageChanged() || m_controller.isEditingDisabled()) { 649 m_controller.leaveUnsaved(target); 650 return; 651 } 652 CmsAcceptDeclineCancelDialog leavingDialog = getLeaveDialog(); 653 leavingDialog.setHandler(new I_CmsAcceptDeclineCancelHandler() { 654 655 /** 656 * @see org.opencms.gwt.client.ui.I_CmsAcceptDeclineCancelHandler#onAccept() 657 */ 658 public void onAccept() { 659 660 m_controller.saveAndLeave(target); 661 } 662 663 /** 664 * @see org.opencms.gwt.client.ui.I_CmsCloseDialogHandler#onClose() 665 */ 666 public void onClose() { 667 668 deactivateCurrentButton(); 669 activateSelection(); 670 } 671 672 /** 673 * @see org.opencms.gwt.client.ui.I_CmsAcceptDeclineCancelHandler#onDecline() 674 */ 675 public void onDecline() { 676 677 m_controller.leaveUnsaved(target); 678 } 679 }); 680 leavingDialog.center(); 681 } 682 683 /** 684 * Loads the context menu entries for a given URI.<p> 685 * 686 * @param structureId the structure id of the resource for which the context menu should be loaded 687 * @param context the ade context (sitemap or containerpage) 688 */ 689 public void loadContextMenu(CmsUUID structureId, final AdeContext context) { 690 691 m_controller.loadContextMenu(structureId, context); 692 } 693 694 /** 695 * Loads the favorite list from the server and adds it's items to the clip-board.<p> 696 */ 697 public void loadFavorites() { 698 699 m_controller.loadFavorites(new I_CmsSimpleCallback<List<CmsContainerElementData>>() { 700 701 /** 702 * Generating the list item widgets and inserting them into the favorite list.<p> 703 * 704 * @param arg the element data 705 */ 706 public void execute(List<CmsContainerElementData> arg) { 707 708 m_editor.getClipboard().clearFavorites(); 709 Iterator<CmsContainerElementData> it = arg.iterator(); 710 while (it.hasNext()) { 711 addToFavorites(m_controller.getContainerpageUtil().createListItem(it.next())); 712 } 713 m_editor.getClipboard().updateSize(); 714 } 715 }); 716 } 717 718 /** 719 * Loads the recent list from the server and adds it's items to the clip-board.<p> 720 */ 721 public void loadRecent() { 722 723 m_controller.loadRecent(new I_CmsSimpleCallback<List<CmsContainerElementData>>() { 724 725 /** 726 * Generating the list item widgets and inserting them into the recent list.<p> 727 * 728 * @param arg the element data 729 */ 730 public void execute(List<CmsContainerElementData> arg) { 731 732 m_editor.getClipboard().clearRecent(); 733 Iterator<CmsContainerElementData> it = arg.iterator(); 734 while (it.hasNext()) { 735 addToRecent(m_controller.getContainerpageUtil().createListItem(it.next())); 736 } 737 m_editor.getClipboard().updateSize(); 738 } 739 }); 740 } 741 742 /** 743 * Should be called when locking the container page failed.<p> 744 * 745 * @param errorMessage the locking information 746 */ 747 public void onLockFail(String errorMessage) { 748 749 m_editor.disableEditing(errorMessage); 750 CmsAlertDialog alert = new CmsAlertDialog( 751 Messages.get().key(Messages.ERR_LOCK_TITLE_RESOURCE_LOCKED_0), 752 errorMessage); 753 alert.addCloseHandler(new CloseHandler<PopupPanel>() { 754 755 public void onClose(CloseEvent<PopupPanel> event) { 756 757 m_controller.reloadPage(); 758 } 759 }); 760 761 alert.center(); 762 } 763 764 /** 765 * @see org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuHandler#onSiteOrProjectChange(java.lang.String, java.lang.String) 766 */ 767 public void onSiteOrProjectChange(String sitePath, String serverLink) { 768 769 leavePage(serverLink); 770 } 771 772 /** 773 * Opens the edit dialog for the specified element.<p> 774 * 775 * @param element the element to edit 776 * @param inline <code>true</code> to open the inline editor for the given element if available 777 * @param wasNew <code>true</code> in case this is a newly created element not previously edited 778 */ 779 public void openEditorForElement(final CmsContainerPageElementPanel element, boolean inline, boolean wasNew) { 780 781 if (element.isNew()) { 782 //openEditorForElement will be called again asynchronously when the RPC for creating the element has finished 783 m_controller.createAndEditNewElement(element, inline); 784 return; 785 } 786 787 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(element.getNoEditReason())) { 788 CmsNotification.get().send( 789 CmsNotification.Type.WARNING, 790 "should be deactivated: " + element.getNoEditReason()); 791 return; 792 } 793 794 if (CmsDomUtil.hasClass(CmsContainerElement.CLASS_GROUP_CONTAINER_ELEMENT_MARKER, element.getElement())) { 795 openGroupEditor((CmsGroupContainerElementPanel)element); 796 } else { 797 m_controller.setContentEditing(true); 798 m_controller.disableInlineEditing(element); 799 m_controller.getContentEditorHandler().openDialog(element, inline, wasNew); 800 element.removeHighlighting(); 801 } 802 } 803 804 /** 805 * Triggers creation/editing of a new content after an option has been selected. 806 * 807 * @param option the type option selected by the user 808 * @param reloadId the id of the element to be reloaded after editing 809 * @param postCreateHandler the post-create handler (for assigning categories or similar) 810 */ 811 public void openEditorForNewListContent( 812 CmsListElementCreationOption option, 813 String reloadId, 814 String postCreateHandler) { 815 816 I_CmsEditableData editableData = new I_CmsEditableData() { 817 818 public String getContextId() { 819 820 return null; 821 } 822 823 public String getEditId() { 824 825 return null; 826 } 827 828 public String getElementId() { 829 830 return null; 831 } 832 833 public String getElementLanguage() { 834 835 return null; 836 } 837 838 public String getElementName() { 839 840 return null; 841 } 842 843 public I_CmsEditableDataExtensions getExtensions() { 844 845 return null; 846 } 847 848 public String getNewLink() { 849 850 return option.getNewLink(); 851 } 852 853 public String getNewTitle() { 854 855 return null; 856 } 857 858 public String getNoEditReason() { 859 860 return null; 861 } 862 863 public String getPostCreateHandler() { 864 865 return postCreateHandler; 866 } 867 868 public String getSitePath() { 869 870 return null; 871 } 872 873 public CmsUUID getStructureId() { 874 875 return CmsCoreProvider.get().getStructureId(); 876 } 877 878 public boolean hasEditHandler() { 879 880 return false; 881 } 882 883 public boolean hasResource() { 884 885 return false; 886 } 887 888 public boolean isUnreleasedOrExpired() { 889 890 return false; 891 } 892 893 public void setSitePath(String sitePath) { 894 895 // no-op 896 897 } 898 }; 899 900 CmsContainerpageController.get().getContentEditorHandler().openDialog( 901 editableData, 902 true/*isNew*/, 903 reloadId /*dependingElementId*/, 904 null /*mode*/, 905 null /*handlerData*/); 906 } 907 908 /** 909 * Opens the elements info dialog.<p> 910 */ 911 public void openElementsInfo() { 912 913 CmsResourceInfoDialog.load( 914 CmsCoreProvider.get().getStructureId(), 915 true, 916 CmsContainerpageController.get().getData().getDetailId(), 917 new HashMap<String, String>(), 918 new CloseHandler<PopupPanel>() { 919 920 public void onClose(CloseEvent<PopupPanel> event) { 921 922 deactivateCurrentButton(); 923 activateSelection(); 924 } 925 926 }); 927 } 928 929 /** 930 * Opens the dialog for adding a new list content. 931 * 932 * @param structureId the structure id of the container element 933 * @param listAddMetadata the list-add metadata read from the container element 934 */ 935 public void openListAddDialog(CmsUUID structureId, String listAddMetadata) { 936 937 CmsRpcAction<CmsListElementCreationDialogData> action = new CmsRpcAction<CmsListElementCreationDialogData>() { 938 939 @Override 940 public void execute() { 941 942 start(0, false); 943 CmsContainerpageHandler.this.m_controller.getContainerpageService().getListElementCreationOptions( 944 structureId, 945 listAddMetadata, 946 this); 947 948 } 949 950 @Override 951 protected void onResponse(CmsListElementCreationDialogData result) { 952 953 stop(false); 954 final CmsUploadPopup[] popupArray = {null}; 955 if (result.isUpload()) { 956 I_CmsUploadContext context = new I_CmsUploadContext() { 957 958 public void onUploadFinished(List<String> uploadedFiles) { 959 960 popupArray[0].hide(); 961 CmsContainerpageController.get().reloadElements( 962 Arrays.asList("" + structureId), 963 DO_NOTHING); 964 } 965 }; 966 CmsUploadPopup popup = new CmsUploadPopup( 967 result.getUploadFolder(), 968 result.getPostCreateHandler(), 969 context, 970 result.getListInfo()); 971 popupArray[0] = popup; 972 popup.center(); 973 } else if (result.getOptions().size() == 1) { 974 // skip the selection dialog, immediately create and edit the content 975 openEditorForNewListContent( 976 result.getOptions().get(0), 977 "" + structureId, 978 result.getPostCreateHandler()); 979 } else { 980 // "0 options" case is handled by the dialog 981 CmsListAddDialog dialog = new CmsListAddDialog( 982 structureId, 983 result, 984 option -> openEditorForNewListContent(option, "" + structureId, result.getPostCreateHandler())); 985 dialog.center(); 986 } 987 } 988 }; 989 action.execute(); 990 991 } 992 993 /** 994 * Opens the lock report for the given element.<p> 995 * 996 * @param element the element 997 */ 998 public void openLockReportForElement(final CmsContainerPageElementPanel element) { 999 1000 CmsLockReportDialog.openDialogForResource(null, element.getStructureId(), new Command() { 1001 1002 public void execute() { 1003 1004 m_controller.reloadElements( 1005 new String[] {element.getStructureId().toString()}, 1006 () -> { /*do nothing*/}); 1007 } 1008 }, null); 1009 } 1010 1011 /** 1012 * Opens the model select dialog for the given new element.<p> 1013 * 1014 * @param element the element widget 1015 * @param modelResources the available resource models 1016 */ 1017 public void openModelResourceSelect( 1018 final CmsContainerPageElementPanel element, 1019 List<CmsModelResourceInfo> modelResources) { 1020 1021 I_CmsModelSelectHandler handler = new I_CmsModelSelectHandler() { 1022 1023 public void onModelSelect(CmsUUID modelStructureId) { 1024 1025 m_controller.createAndEditNewElement(element, modelStructureId); 1026 } 1027 }; 1028 String title = org.opencms.gwt.client.Messages.get().key( 1029 org.opencms.gwt.client.Messages.GUI_MODEL_SELECT_TITLE_0); 1030 String message = org.opencms.gwt.client.Messages.get().key( 1031 org.opencms.gwt.client.Messages.GUI_MODEL_SELECT_MESSAGE_0); 1032 CmsModelSelectDialog dialog = new CmsModelSelectDialog(handler, modelResources, title, message); 1033 dialog.center(); 1034 } 1035 1036 /** 1037 * @see org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuHandler#refreshResource(org.opencms.util.CmsUUID) 1038 */ 1039 public void refreshResource(CmsUUID structureId) { 1040 1041 if (!m_controller.hasPageChanged()) { 1042 m_controller.resetPage(); 1043 return; 1044 } 1045 StringBuffer message = new StringBuffer(); 1046 message.append("<p>" + Messages.get().key(Messages.GUI_DIALOG_RELOAD_TEXT_0) + "</p>"); 1047 message.append("<p>" + Messages.get().key(Messages.GUI_DIALOG_SAVE_QUESTION_0) + "</p>"); 1048 CmsConfirmDialog dialog = new CmsConfirmDialog( 1049 Messages.get().key(Messages.GUI_DIALOG_RELOAD_TITLE_0), 1050 message.toString()); 1051 dialog.setOkText(Messages.get().key(Messages.GUI_BUTTON_SAVE_TEXT_0)); 1052 dialog.setHandler(new I_CmsConfirmDialogHandler() { 1053 1054 public void onClose() { 1055 1056 // do nothing 1057 } 1058 1059 public void onOk() { 1060 1061 m_controller.saveContainerpage(); 1062 } 1063 }); 1064 dialog.center(); 1065 1066 } 1067 1068 /** 1069 * Re-initializes the inline editing.<p> 1070 */ 1071 public void reInitInlineEditing() { 1072 1073 m_controller.reInitInlineEditing(); 1074 } 1075 1076 /** 1077 * Reloads the content for the given element and all related elements.<p> 1078 * 1079 * @param elementIds the element id's 1080 * @param callback the callback to execute after reloading 1081 */ 1082 public void reloadElements(String[] elementIds, Runnable callback) { 1083 1084 m_controller.reloadElements(elementIds, callback); 1085 } 1086 1087 /** 1088 * Removes the given container-page element.<p> 1089 * 1090 * @param element the element 1091 * 1092 */ 1093 public void removeElement(CmsContainerPageElementPanel element) { 1094 1095 m_controller.removeElement(element); 1096 } 1097 1098 /** 1099 * Removes the given container-page element.<p> 1100 * 1101 * @param element the element 1102 * @param removeMode the element remove mode 1103 * 1104 */ 1105 public void removeElement(CmsContainerPageElementPanel element, ElementRemoveMode removeMode) { 1106 1107 m_controller.removeElement(element, removeMode); 1108 } 1109 1110 /** 1111 * Replaces the given element with another content while keeping it's settings.<p> 1112 * 1113 * @param element the element to replace 1114 * @param elementId the id of the replacing content 1115 * @param callback the callback to execute after replacing the element 1116 */ 1117 public void replaceElement(CmsContainerPageElementPanel element, String elementId, Runnable callback) { 1118 1119 m_controller.replaceElement(element, elementId, callback); 1120 } 1121 1122 /** 1123 * Shows list collector direct edit buttons (old direct edit style), if present.<p> 1124 */ 1125 public void resetEditableListButtons() { 1126 1127 m_controller.resetEditButtons(); 1128 } 1129 1130 /** 1131 * Resets the container-page to it's previous state.<p> 1132 */ 1133 public void resetPage() { 1134 1135 CmsConfirmDialog dialog = new CmsConfirmDialog( 1136 Messages.get().key(Messages.GUI_DIALOG_RESET_TITLE_0), 1137 "<p>" + Messages.get().key(Messages.GUI_DIALOG_PAGE_RESET_0) + "</p>"); 1138 dialog.setCloseText(Messages.get().key(Messages.GUI_BUTTON_CANCEL_TEXT_0)); 1139 dialog.setOkText(Messages.get().key(Messages.GUI_BUTTON_DISCARD_TEXT_0)); 1140 dialog.setHandler(new I_CmsConfirmDialogHandler() { 1141 1142 /** 1143 * @see org.opencms.gwt.client.ui.I_CmsCloseDialogHandler#onClose() 1144 */ 1145 public void onClose() { 1146 1147 deactivateCurrentButton(); 1148 activateSelection(); 1149 } 1150 1151 /** 1152 * @see org.opencms.gwt.client.ui.I_CmsConfirmDialogHandler#onOk() 1153 */ 1154 public void onOk() { 1155 1156 m_controller.resetPage(); 1157 } 1158 }); 1159 dialog.center(); 1160 } 1161 1162 /** 1163 * Saves the favorite list.<p> 1164 * 1165 * @param clientIds the client id's of the list's elements 1166 * 1167 * @see org.opencms.ade.containerpage.client.CmsContainerpageController#saveFavoriteList(java.util.List) 1168 */ 1169 public void saveFavoriteList(List<String> clientIds) { 1170 1171 m_controller.saveFavoriteList(clientIds); 1172 } 1173 1174 /** 1175 * Saves the current state of the container-page.<p> 1176 */ 1177 public void savePage() { 1178 1179 m_controller.saveContainerpage(); 1180 1181 deactivateCurrentButton(); 1182 activateSelection(); 1183 } 1184 1185 /** 1186 * Sets the currently active tool-bar button.<p> 1187 * 1188 * @param button the button 1189 */ 1190 public void setActiveButton(I_CmsToolbarButton button) { 1191 1192 m_activeButton = button; 1193 setEditButtonsVisible((button == null) || m_editor.getSelection().equals(button)); 1194 } 1195 1196 /** 1197 * Sets the edit button visible.<p> 1198 * 1199 * @param visible the visibility 1200 */ 1201 public void setEditButtonsVisible(boolean visible) { 1202 1203 if (visible) { 1204 m_editButtonVibility.setValue( 1205 org.opencms.ade.containerpage.client.ui.css.I_CmsLayoutBundle.INSTANCE.containerpageCss().editButtonsVisible()); 1206 } else { 1207 m_editButtonVibility.setValue( 1208 org.opencms.ade.containerpage.client.ui.css.I_CmsLayoutBundle.INSTANCE.containerpageCss().editButtonsInvisible()); 1209 } 1210 } 1211 1212 /** 1213 * Shows resource information for a given element.<p> 1214 * 1215 * @param element the element for which to show the information 1216 */ 1217 public void showElementInfo(final CmsContainerPageElementPanel element) { 1218 1219 CmsUUID structureId; 1220 if (element.isModelGroup() && !element.getModelGroupId().isNullUUID()) { 1221 structureId = element.getModelGroupId(); 1222 } else { 1223 structureId = element.getStructureId(); 1224 } 1225 I_CmsDropContainer dropContainer = element.getParentTarget(); 1226 Map<String, String> contextParams = new HashMap<>(); 1227 if (dropContainer instanceof CmsContainerPageContainer) { 1228 CmsContainerPageContainer cnt = (CmsContainerPageContainer)dropContainer; 1229 String containerId = cnt.getContainerId(); 1230 String elemId = element.getId(); 1231 contextParams.put(CmsGwtConstants.ATTR_ELEMENT_ID, elemId); 1232 contextParams.put(CmsGwtConstants.ATTR_CONTAINER_ID, containerId); 1233 String pageRootPath = CmsStringUtil.joinPaths( 1234 CmsCoreProvider.get().getSiteRoot(), 1235 CmsCoreProvider.get().getUri()); 1236 contextParams.put(CmsGwtConstants.ATTR_PAGE_ROOT_PATH, pageRootPath); 1237 } 1238 CmsResourceInfoDialog.load(structureId, true, null, contextParams, new CloseHandler<PopupPanel>() { 1239 1240 public void onClose(CloseEvent<PopupPanel> event) { 1241 1242 reloadElements(new String[] {element.getId()}, () -> {/*do nothing*/}); 1243 } 1244 }); 1245 } 1246 1247 /** 1248 * Shows a page overlay preventing user actions.<p> 1249 */ 1250 public void showPageOverlay() { 1251 1252 if (m_overlay == null) { 1253 m_overlay = new SimplePanel(); 1254 m_overlay.setStyleName(I_CmsLayoutBundle.INSTANCE.dialogCss().popupOverlay()); 1255 Style style = m_overlay.getElement().getStyle(); 1256 style.setWidth(100, Unit.PCT); 1257 style.setHeight(100, Unit.PCT); 1258 style.setPosition(Position.FIXED); 1259 } 1260 RootPanel.get().add(m_overlay); 1261 } 1262 1263 /** 1264 * Toggles the tool-bars visibility.<p> 1265 * 1266 * @param buttonLeft the selection button absolute left position, needed to show the leave preview button in the same location 1267 */ 1268 public void showPreview(int buttonLeft) { 1269 1270 UrlBuilder location = Window.Location.createUrlBuilder(); 1271 location.setParameter(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT, Boolean.toString(true)); 1272 location.setParameter(CmsGwtConstants.PARAM_BUTTON_LEFT, Integer.toString(buttonLeft)); 1273 CmsUUID detailId = CmsContainerpageController.get().getData().getDetailId(); 1274 if (detailId != null) { 1275 // current URL may no longer be valid because the field mapped to URL name may have been edited. 1276 CmsRpcAction<String> action = new CmsRpcAction<String>() { 1277 1278 @Override 1279 public void execute() { 1280 1281 start(0, false); 1282 CmsCoreProvider.getVfsService().getDetailName(detailId, CmsCoreProvider.get().getLocale(), this); 1283 } 1284 1285 @Override 1286 protected void onResponse(String name) { 1287 1288 stop(false); 1289 String path = Window.Location.getPath(); 1290 path = path.replaceFirst("/[^/]+(/?)$", "/" + name + "$1"); 1291 location.setPath(path); 1292 Window.Location.assign(location.buildString()); 1293 } 1294 }; 1295 action.execute(); 1296 1297 } else { 1298 Window.Location.assign(location.buildString()); 1299 } 1300 } 1301 1302 /** 1303 * Shows the publish dialog.<p> 1304 */ 1305 public void showPublishDialog() { 1306 1307 if (m_controller.hasPageChanged()) { 1308 1309 StringBuffer warningMessage = new StringBuffer(); 1310 warningMessage.append("<p>" + Messages.get().key(Messages.GUI_DIALOG_PUBLISH_NOT_SAVED_0) + "</p>"); 1311 warningMessage.append("<p>" + Messages.get().key(Messages.GUI_DIALOG_SAVE_QUESTION_0) + "</p>"); 1312 1313 CmsAcceptDeclineCancelDialog leavingDialog = new CmsAcceptDeclineCancelDialog( 1314 Messages.get().key(Messages.GUI_DIALOG_NOT_SAVED_TITLE_0), 1315 warningMessage.toString()); 1316 leavingDialog.setAcceptText(Messages.get().key(Messages.GUI_BUTTON_SAVE_TEXT_0)); 1317 leavingDialog.setDeclineText(Messages.get().key(Messages.GUI_BUTTON_DISCARD_TEXT_0)); 1318 leavingDialog.setCloseText(Messages.get().key(Messages.GUI_BUTTON_RETURN_TEXT_0)); 1319 1320 leavingDialog.setHandler(new I_CmsAcceptDeclineCancelHandler() { 1321 1322 /** 1323 * @see org.opencms.gwt.client.ui.I_CmsAcceptDeclineCancelHandler#onAccept() 1324 */ 1325 public void onAccept() { 1326 1327 m_controller.saveContainerpage(new Runnable() { 1328 1329 public void run() { 1330 1331 openPublish(); 1332 } 1333 }); 1334 } 1335 1336 /** 1337 * @see org.opencms.gwt.client.ui.I_CmsCloseDialogHandler#onClose() 1338 */ 1339 public void onClose() { 1340 1341 deactivateCurrentButton(); 1342 activateSelection(); 1343 } 1344 1345 /** 1346 * @see org.opencms.gwt.client.ui.I_CmsAcceptDeclineCancelHandler#onDecline() 1347 */ 1348 public void onDecline() { 1349 1350 openPublish(); 1351 } 1352 }); 1353 leavingDialog.center(); 1354 } else { 1355 openPublish(); 1356 } 1357 } 1358 1359 /** 1360 * @see org.opencms.gwt.client.ui.A_CmsToolbarHandler#transformSingleEntry(org.opencms.util.CmsUUID, org.opencms.gwt.shared.CmsContextMenuEntryBean) 1361 */ 1362 @Override 1363 public I_CmsContextMenuEntry transformSingleEntry(CmsUUID structureId, CmsContextMenuEntryBean menuEntryBean) { 1364 1365 String name = menuEntryBean.getName(); 1366 if (name == null) { 1367 return super.transformSingleEntry(structureId, menuEntryBean); 1368 } 1369 if (name.equals(CmsGwtConstants.TEMPLATECONTEXT_MENU_PLACEHOLDER)) { 1370 return createTemplateContextSelectionMenuEntry(structureId); 1371 } else if ((menuEntryBean.getParams() != null) 1372 && menuEntryBean.getParams().containsKey(CmsGwtConstants.PREFILL_MENU_PLACEHOLDER)) { 1373 // hack: this comes before the template contexts option in the context menu order, so we have it ready when we get there 1374 m_prefill = menuEntryBean; 1375 return null; 1376 } else if (name.equals(CmsGwtConstants.ACTION_EDITSMALLELEMENTS)) { 1377 return createToggleEditSmallElementsMenuEntry(); 1378 } else if (name.equals(CmsGwtConstants.ACTION_SELECTELEMENTVIEW)) { 1379 return createElementViewSelectionMenuEntry(); 1380 } else if (name.equals(CmsGwtConstants.ACTION_SHOWLOCALE)) { 1381 return createShowLocaleMenuEntry(); 1382 } else if (name.equals(CmsGwtConstants.ACTION_VIEW_ONLINE)) { 1383 return createViewOnlineEntry(); 1384 } else if (name.equals(CmsPreview.class.getName())) { 1385 return null; 1386 } else { 1387 return super.transformSingleEntry(structureId, menuEntryBean); 1388 } 1389 } 1390 1391 /** 1392 * @see org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuHandler#unlockResource(org.opencms.util.CmsUUID) 1393 */ 1394 public void unlockResource(CmsUUID structureId) { 1395 1396 // only unlock the container page, if nothing has changed yet 1397 if (!m_controller.hasPageChanged()) { 1398 m_controller.unlockContainerpage(); 1399 } 1400 } 1401 1402 /** 1403 * Updates the clip board elements is necessary.<p> 1404 * 1405 * @param elements the elements data 1406 */ 1407 public void updateClipboard(Map<String, CmsContainerElementData> elements) { 1408 1409 if (m_editor.getClipboard().isOpen()) { 1410 for (CmsContainerElementData elementData : elements.values()) { 1411 m_editor.getClipboard().replaceFavoriteItem( 1412 m_controller.getContainerpageUtil().createListItem(elementData)); 1413 m_editor.getClipboard().replaceRecentItem( 1414 m_controller.getContainerpageUtil().createListItem(elementData)); 1415 } 1416 } 1417 } 1418 1419 /** 1420 * Creates the element view selection menu entry, returns <code>null</code> in case no other views available.<p> 1421 * 1422 * @return the menu entry 1423 */ 1424 protected I_CmsContextMenuEntry createElementViewSelectionMenuEntry() { 1425 1426 List<CmsElementViewInfo> elementViews = m_controller.getData().getElementViews(); 1427 if (elementViews.size() > 1) { 1428 CmsContextMenuEntry parentEntry = new CmsContextMenuEntry(this, null, new I_CmsContextMenuCommand() { 1429 1430 public void execute( 1431 CmsUUID innerStructureId, 1432 I_CmsContextMenuHandler handler, 1433 CmsContextMenuEntryBean bean) { 1434 1435 // do nothing 1436 } 1437 1438 public A_CmsContextMenuItem getItemWidget( 1439 CmsUUID innerStructureId, 1440 I_CmsContextMenuHandler handler, 1441 CmsContextMenuEntryBean bean) { 1442 1443 return null; 1444 } 1445 1446 public boolean hasItemWidget() { 1447 1448 return false; 1449 } 1450 1451 }); 1452 CmsContextMenuEntryBean parentBean = new CmsContextMenuEntryBean(); 1453 1454 parentBean.setLabel(Messages.get().key(Messages.GUI_SELECT_ELEMENT_VIEW_0)); 1455 parentBean.setActive(true); 1456 parentBean.setVisible(true); 1457 parentEntry.setBean(parentBean); 1458 List<I_CmsContextMenuEntry> viewEntries = new ArrayList<I_CmsContextMenuEntry>(); 1459 for (CmsElementViewInfo viewInfo : elementViews) { 1460 if (viewInfo.isRoot()) { 1461 viewEntries.add( 1462 createMenuEntryForElementView( 1463 viewInfo, 1464 m_controller.matchRootView(viewInfo.getElementViewId()), 1465 this)); 1466 } 1467 } 1468 1469 parentEntry.setSubMenu(viewEntries); 1470 return parentEntry; 1471 } else { 1472 return null; 1473 } 1474 } 1475 1476 /** 1477 * Creates a menu entry based on a structure id and action without anything else.<p> 1478 * 1479 * @param structureId the structure id 1480 * @param action the action for the menu entry 1481 * 1482 * @return the new menu entry 1483 */ 1484 protected CmsContextMenuEntry createRawMenuEntry(CmsUUID structureId, final Runnable action) { 1485 1486 CmsContextMenuEntry entry = new CmsContextMenuEntry(this, structureId, new I_CmsContextMenuCommand() { 1487 1488 public void execute( 1489 CmsUUID innerStructureId, 1490 I_CmsContextMenuHandler handler, 1491 CmsContextMenuEntryBean bean) { 1492 1493 if (action != null) { 1494 action.run(); 1495 } 1496 } 1497 1498 public A_CmsContextMenuItem getItemWidget( 1499 CmsUUID innerStructureId, 1500 I_CmsContextMenuHandler handler, 1501 CmsContextMenuEntryBean bean) { 1502 1503 return null; 1504 } 1505 1506 public boolean hasItemWidget() { 1507 1508 return false; 1509 } 1510 1511 }); 1512 return entry; 1513 } 1514 1515 /** 1516 * Creates the template context selection entry for the context menu.<p> 1517 * 1518 * @param structureId the structure id of the page 1519 * 1520 * @return the new context menu entry 1521 */ 1522 protected I_CmsContextMenuEntry createTemplateContextSelectionMenuEntry(CmsUUID structureId) { 1523 1524 final CmsTemplateContextInfo info = m_controller.getData().getTemplateContextInfo(); 1525 if ((info.getCookieName() != null) && info.shouldShowTemplateContextContextMenuEntry()) { 1526 CmsContextMenuEntry parentEntry = new CmsContextMenuEntry(this, structureId, new I_CmsContextMenuCommand() { 1527 1528 public void execute( 1529 CmsUUID innerStructureId, 1530 I_CmsContextMenuHandler handler, 1531 CmsContextMenuEntryBean bean) { 1532 1533 // do nothing 1534 } 1535 1536 public A_CmsContextMenuItem getItemWidget( 1537 CmsUUID innerStructureId, 1538 I_CmsContextMenuHandler handler, 1539 CmsContextMenuEntryBean bean) { 1540 1541 return null; 1542 } 1543 1544 public boolean hasItemWidget() { 1545 1546 return false; 1547 } 1548 1549 }); 1550 CmsContextMenuEntryBean parentBean = new CmsContextMenuEntryBean(); 1551 1552 String parentLabel = info.getMenuLabel(); 1553 if (parentLabel == null) { 1554 parentLabel = org.opencms.gwt.client.Messages.get().key( 1555 org.opencms.gwt.client.Messages.GUI_TEMPLATE_CONTEXT_PARENT_0); 1556 } 1557 parentBean.setLabel(parentLabel); 1558 parentBean.setActive(true); 1559 parentBean.setVisible(true); 1560 parentEntry.setBean(parentBean); 1561 1562 Map<String, String> contextNames = info.getContextLabels(); 1563 1564 List<I_CmsContextMenuEntry> templateContextEntries = new ArrayList<I_CmsContextMenuEntry>(); 1565 for (Map.Entry<String, String> entry : contextNames.entrySet()) { 1566 final String key = entry.getKey(); 1567 final String label = entry.getValue(); 1568 if (info.hasClientVariants(key)) { 1569 CmsContextMenuEntry singleContextEntry = createRawMenuEntry(structureId, DO_NOTHING); 1570 boolean showCheckbox = Objects.equal(info.getSelectedContext(), entry.getKey()); 1571 decorateMenuEntry(singleContextEntry, label, showCheckbox); 1572 List<I_CmsContextMenuEntry> variantEntries = new ArrayList<I_CmsContextMenuEntry>(); 1573 CmsContextMenuEntry editVariantEntry = createMenuEntryForTemplateContext( 1574 info.getCookieName(), 1575 key, 1576 org.opencms.ade.containerpage.client.Messages.get().key( 1577 org.opencms.ade.containerpage.client.Messages.GUI_TEMPLATE_CONTEXT_NO_VARIANT_0), 1578 false, 1579 this, 1580 structureId); 1581 variantEntries.add(editVariantEntry); 1582 Map<String, CmsClientVariantInfo> variants = info.getClientVariants(key); 1583 for (CmsClientVariantInfo variant : variants.values()) { 1584 CmsContextMenuEntry currentVariantEntry = createRawMenuEntry( 1585 structureId, 1586 new ClientVariantSelectAction(key, variant)); 1587 decorateMenuEntry(currentVariantEntry, variant.getNiceName(), false); 1588 variantEntries.add(currentVariantEntry); 1589 } 1590 singleContextEntry.setSubMenu(variantEntries); 1591 templateContextEntries.add(singleContextEntry); 1592 1593 } else { 1594 1595 CmsContextMenuEntry menuEntry = createMenuEntryForTemplateContext( 1596 info.getCookieName(), 1597 key, 1598 label, 1599 Objects.equal(key, info.getSelectedContext()), 1600 this, 1601 structureId); 1602 templateContextEntries.add(menuEntry); 1603 } 1604 } 1605 String autoLabel = org.opencms.gwt.client.Messages.get().key( 1606 org.opencms.gwt.client.Messages.GUI_TEMPLATE_CONTEXT_NONE_0); 1607 if (info.getDefaultLabel() != null) { 1608 autoLabel = info.getDefaultLabel(); 1609 } 1610 templateContextEntries.add( 1611 createMenuEntryForTemplateContext( 1612 info.getCookieName(), 1613 null, 1614 autoLabel, 1615 Objects.equal(null, info.getSelectedContext()), 1616 this, 1617 structureId)); 1618 if ((m_prefill != null) && (info.getSelectedContext() != null)) { 1619 String name = m_prefill.getName(); 1620 I_CmsContextMenuCommand command = null; 1621 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(name)) { 1622 command = getContextMenuCommands().get(name); 1623 } 1624 CmsContextMenuEntry entry = new CmsContextMenuEntry(this, structureId, command); 1625 entry.setBean(m_prefill); 1626 templateContextEntries.add(entry); 1627 } 1628 parentEntry.setSubMenu(templateContextEntries); 1629 1630 return parentEntry; 1631 1632 } else { 1633 return null; 1634 } 1635 } 1636 1637 /** 1638 * Creates the context menu entry for enabling or disabling editing of small elements.<p> 1639 * 1640 * @return the created context menu entry 1641 */ 1642 protected I_CmsContextMenuEntry createToggleEditSmallElementsMenuEntry() { 1643 1644 final CmsSmallElementsHandler smallElementsHandler = m_controller.getSmallElementsHandler(); 1645 final boolean isActive = smallElementsHandler.areSmallElementsEditable(); 1646 CmsContextMenuEntryBean entryBean = new CmsContextMenuEntryBean(); 1647 String baseMessage = Messages.get().key(Messages.GUI_EDIT_SMALL_ELEMENTS_0); 1648 String msgEdit = baseMessage; 1649 String msgDisable = baseMessage; 1650 String label = isActive ? msgDisable : msgEdit; 1651 entryBean.setLabel(label); 1652 entryBean.setActive(smallElementsHandler.hasSmallElements()); 1653 entryBean.setVisible(true); 1654 I_CmsInputCss inputCss = I_CmsInputLayoutBundle.INSTANCE.inputCss(); 1655 entryBean.setIconClass(isActive ? inputCss.checkBoxImageChecked() : inputCss.checkBoxImageUnchecked()); 1656 I_CmsContextMenuCommand command = new I_CmsContextMenuCommand() { 1657 1658 public void execute(CmsUUID structureId, I_CmsContextMenuHandler handler, CmsContextMenuEntryBean bean) { 1659 1660 smallElementsHandler.setEditSmallElements(!isActive, true); 1661 } 1662 1663 public A_CmsContextMenuItem getItemWidget( 1664 CmsUUID structureId, 1665 I_CmsContextMenuHandler handler, 1666 CmsContextMenuEntryBean bean) { 1667 1668 return null; 1669 } 1670 1671 public boolean hasItemWidget() { 1672 1673 return false; 1674 } 1675 }; 1676 CmsContextMenuEntry entry = new CmsContextMenuEntry(this, null, command); 1677 entry.setBean(entryBean); 1678 return entry; 1679 } 1680 1681 /** 1682 * Creates the view online entry, if an online link is available.<p> 1683 * 1684 * @return the menu entry or null, if not available 1685 */ 1686 protected I_CmsContextMenuEntry createViewOnlineEntry() { 1687 1688 final String onlineLink = m_controller.getData().getOnlineLink(); 1689 CmsContextMenuEntry entry = null; 1690 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(onlineLink)) { 1691 I_CmsContextMenuCommand command = new I_CmsContextMenuCommand() { 1692 1693 public void execute( 1694 CmsUUID structureId, 1695 I_CmsContextMenuHandler handler, 1696 CmsContextMenuEntryBean bean) { 1697 1698 Window.open(onlineLink, "opencms-online", null); 1699 } 1700 1701 public A_CmsContextMenuItem getItemWidget( 1702 CmsUUID structureId, 1703 I_CmsContextMenuHandler handler, 1704 CmsContextMenuEntryBean bean) { 1705 1706 return null; 1707 } 1708 1709 public boolean hasItemWidget() { 1710 1711 return false; 1712 } 1713 }; 1714 entry = new CmsContextMenuEntry(this, null, command); 1715 CmsContextMenuEntryBean entryBean = new CmsContextMenuEntryBean(); 1716 entryBean.setLabel(Messages.get().key(Messages.GUI_VIEW_ONLINE_0)); 1717 entryBean.setActive(true); 1718 entryBean.setVisible(true); 1719 entry.setBean(entryBean); 1720 } 1721 return entry; 1722 } 1723 1724 /** 1725 * Fills in label and checkbox of a menu entry.<p> 1726 * 1727 * @param entry the menu entry 1728 * @param name the label 1729 * @param checked true if checkbox should be shown 1730 */ 1731 protected void decorateMenuEntry(CmsContextMenuEntry entry, String name, boolean checked) { 1732 1733 CmsContextMenuEntryBean bean = new CmsContextMenuEntryBean(); 1734 bean.setLabel(name); 1735 bean.setActive(true); 1736 bean.setVisible(true); 1737 I_CmsInputCss inputCss = I_CmsInputLayoutBundle.INSTANCE.inputCss(); 1738 bean.setIconClass(checked ? inputCss.checkBoxImageChecked() : ""); 1739 entry.setBean(bean); 1740 } 1741 1742 /** 1743 * Helper method for getting the error message for a locking error.<p> 1744 * 1745 * @param lockInfo the lock information 1746 * @return the error message 1747 */ 1748 protected String getLockErrorMessage(CmsLockInfo lockInfo) { 1749 1750 switch (lockInfo.getState()) { 1751 case changed: 1752 return Messages.get().key(Messages.ERR_LOCK_RESOURCE_CHANGED_BY_1, lockInfo.getUser()); 1753 case locked: 1754 return Messages.get().key(Messages.ERR_LOCK_RESOURCE_LOCKED_BY_1, lockInfo.getUser()); 1755 case other: 1756 return lockInfo.getErrorMessage(); 1757 case success: 1758 default: 1759 return ""; 1760 } 1761 } 1762 1763 /** 1764 * Helper method for getting the error message box title for a locking error.<p> 1765 * 1766 * @param lockInfo the lock information 1767 * @return the error message box title 1768 */ 1769 protected String getLockErrorTitle(CmsLockInfo lockInfo) { 1770 1771 switch (lockInfo.getState()) { 1772 case changed: 1773 return Messages.get().key(Messages.ERR_LOCK_TITLE_RESOURCE_CHANGED_0); 1774 case locked: 1775 return Messages.get().key(Messages.ERR_LOCK_TITLE_RESOURCE_LOCKED_0); 1776 case other: 1777 case success: 1778 default: 1779 return Messages.get().key(Messages.GUI_LOCK_FAIL_0); 1780 } 1781 } 1782 1783 /** 1784 * Opens the publish dialog without changes check.<p> 1785 */ 1786 protected void openPublish() { 1787 1788 HashMap<String, String> params = Maps.newHashMap(); 1789 params.put(CmsPublishOptions.PARAM_CONTAINERPAGE, "" + CmsCoreProvider.get().getStructureId()); 1790 params.put(CmsPublishOptions.PARAM_START_WITH_CURRENT_PAGE, ""); 1791 params.put(CmsPublishOptions.PARAM_DETAIL, "" + m_controller.getData().getDetailId()); 1792 CmsPublishDialog.showPublishDialog(params, new CloseHandler<PopupPanel>() { 1793 1794 /** 1795 * @see com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt.event.logical.shared.CloseEvent) 1796 */ 1797 public void onClose(CloseEvent<PopupPanel> event) { 1798 1799 deactivateCurrentButton(); 1800 activateSelection(); 1801 1802 } 1803 }, new Runnable() { 1804 1805 public void run() { 1806 1807 openPublish(); 1808 } 1809 1810 }, m_controller.getContentEditorHandler()); 1811 } 1812 1813 /** 1814 * Sets the element view.<p> 1815 * 1816 * @param elementView the element view 1817 * @param nextAction the action to execute after setting the view 1818 */ 1819 protected void setElementView(CmsElementViewInfo elementView, Runnable nextAction) { 1820 1821 m_controller.setElementView(elementView, nextAction); 1822 } 1823 1824 /** 1825 * Creates the menu entry for a single element view.<p> 1826 * 1827 * @param elementView the element view 1828 * @param isActive if the group is the currently active group 1829 * @param handler the menu handler 1830 * 1831 * @return the menu entry 1832 */ 1833 private CmsContextMenuEntry createMenuEntryForElementView( 1834 final CmsElementViewInfo elementView, 1835 boolean isActive, 1836 I_CmsContextMenuHandler handler) { 1837 1838 CmsContextMenuEntry menuEntry = new CmsContextMenuEntry(handler, null, new I_CmsContextMenuCommand() { 1839 1840 public void execute( 1841 CmsUUID innerStructureId, 1842 I_CmsContextMenuHandler innerHandler, 1843 CmsContextMenuEntryBean bean) { 1844 1845 setElementView(elementView, null); 1846 } 1847 1848 public A_CmsContextMenuItem getItemWidget( 1849 CmsUUID innerStructureId, 1850 I_CmsContextMenuHandler innerHandler, 1851 CmsContextMenuEntryBean bean) { 1852 1853 return null; 1854 } 1855 1856 public boolean hasItemWidget() { 1857 1858 return false; 1859 } 1860 }); 1861 CmsContextMenuEntryBean bean = new CmsContextMenuEntryBean(); 1862 bean.setLabel(elementView.getTitle()); 1863 1864 I_CmsInputCss inputCss = I_CmsInputLayoutBundle.INSTANCE.inputCss(); 1865 bean.setIconClass(isActive ? inputCss.checkBoxImageChecked() : ""); 1866 bean.setActive(!isActive); 1867 bean.setVisible(true); 1868 menuEntry.setBean(bean); 1869 return menuEntry; 1870 1871 } 1872 1873 /** 1874 * Creates a context menu entry for selecting a template context.<p> 1875 * 1876 * @param cookieName the name of the cookie 1877 * @param value the value of the cookie 1878 * @param label the text for the menu entry 1879 * @param isActive true if context is currently active 1880 * @param handler the context menu handler 1881 * @param structureId the current page's structure id 1882 * 1883 * @return the created context menu entry 1884 */ 1885 private CmsContextMenuEntry createMenuEntryForTemplateContext( 1886 final String cookieName, 1887 final String value, 1888 String label, 1889 boolean isActive, 1890 I_CmsContextMenuHandler handler, 1891 CmsUUID structureId) { 1892 1893 CmsContextMenuEntry menuEntry = new CmsContextMenuEntry(handler, structureId, new I_CmsContextMenuCommand() { 1894 1895 public void execute( 1896 CmsUUID innerStructureId, 1897 I_CmsContextMenuHandler innerHandler, 1898 CmsContextMenuEntryBean bean) { 1899 1900 changeTemplateContextManually(cookieName, value); 1901 } 1902 1903 public A_CmsContextMenuItem getItemWidget( 1904 CmsUUID innerStructureId, 1905 I_CmsContextMenuHandler innerHandler, 1906 CmsContextMenuEntryBean bean) { 1907 1908 return null; 1909 } 1910 1911 public boolean hasItemWidget() { 1912 1913 return false; 1914 } 1915 }); 1916 CmsContextMenuEntryBean bean = new CmsContextMenuEntryBean(); 1917 bean.setLabel(label); 1918 1919 I_CmsInputCss inputCss = I_CmsInputLayoutBundle.INSTANCE.inputCss(); 1920 bean.setIconClass(isActive ? inputCss.checkBoxImageChecked() : ""); 1921 bean.setActive(true); 1922 bean.setVisible(true); 1923 menuEntry.setBean(bean); 1924 return menuEntry; 1925 1926 } 1927 1928 /** 1929 * Creates the real entries for the "Show locale" option.<p> 1930 * 1931 * @return the real entry 1932 */ 1933 private I_CmsContextMenuEntry createShowLocaleMenuEntry() { 1934 1935 Map<String, CmsLocaleLinkBean> localeLinkBeans = CmsContainerpageController.get().getData().getLocaleLinkBeans(); 1936 if ((localeLinkBeans == null) || localeLinkBeans.isEmpty()) { 1937 return null; 1938 } 1939 1940 CmsContextMenuEntry parentEntry = new CmsContextMenuEntry(this, null, new I_CmsContextMenuCommand() { 1941 1942 public void execute( 1943 CmsUUID innerStructureId, 1944 I_CmsContextMenuHandler handler, 1945 CmsContextMenuEntryBean bean) { 1946 1947 // do nothing 1948 } 1949 1950 public A_CmsContextMenuItem getItemWidget( 1951 CmsUUID innerStructureId, 1952 I_CmsContextMenuHandler handler, 1953 CmsContextMenuEntryBean bean) { 1954 1955 return null; 1956 } 1957 1958 public boolean hasItemWidget() { 1959 1960 return false; 1961 } 1962 1963 }); 1964 CmsContextMenuEntryBean parentBean = new CmsContextMenuEntryBean(); 1965 1966 parentBean.setLabel( 1967 org.opencms.ade.containerpage.client.Messages.get().key( 1968 org.opencms.ade.containerpage.client.Messages.GUI_SHOW_LOCALE_0)); 1969 parentBean.setActive(true); 1970 parentBean.setVisible(true); 1971 parentEntry.setBean(parentBean); 1972 List<I_CmsContextMenuEntry> subEntries = Lists.newArrayList(); 1973 1974 for (Map.Entry<String, CmsLocaleLinkBean> entry : localeLinkBeans.entrySet()) { 1975 String label = entry.getKey(); 1976 final CmsLocaleLinkBean linkBean = entry.getValue(); 1977 CmsContextMenuEntry childEntry = new CmsContextMenuEntry(this, null, new I_CmsContextMenuCommand() { 1978 1979 public void execute( 1980 CmsUUID structureId, 1981 I_CmsContextMenuHandler handler, 1982 CmsContextMenuEntryBean bean) { 1983 1984 if (linkBean.getError() != null) { 1985 CmsNotification.get().sendAlert(Type.WARNING, linkBean.getError()); 1986 } else if (linkBean.getLink() != null) { 1987 Window.Location.assign(linkBean.getLink()); 1988 } 1989 } 1990 1991 public A_CmsContextMenuItem getItemWidget( 1992 CmsUUID structureId, 1993 I_CmsContextMenuHandler handler, 1994 CmsContextMenuEntryBean bean) { 1995 1996 return null; 1997 } 1998 1999 public boolean hasItemWidget() { 2000 2001 return false; 2002 } 2003 }); 2004 CmsContextMenuEntryBean childBean = new CmsContextMenuEntryBean(); 2005 childBean.setLabel(label); 2006 childBean.setActive(true); 2007 childBean.setVisible(true); 2008 childEntry.setBean(childBean); 2009 subEntries.add(childEntry); 2010 } 2011 parentEntry.setSubMenu(subEntries); 2012 if (subEntries.isEmpty()) { 2013 return null; 2014 } else { 2015 return parentEntry; 2016 } 2017 } 2018 2019 /** 2020 * Returns the page leaving dialog.<p> 2021 * 2022 * @return the page leaving dialog 2023 */ 2024 private CmsAcceptDeclineCancelDialog getLeaveDialog() { 2025 2026 StringBuffer message = new StringBuffer(); 2027 message.append("<p>" + Messages.get().key(Messages.GUI_DIALOG_LEAVE_NOT_SAVED_0) + "</p>"); 2028 message.append("<p>" + Messages.get().key(Messages.GUI_DIALOG_SAVE_QUESTION_0) + "</p>"); 2029 2030 CmsAcceptDeclineCancelDialog leavingDialog = new CmsAcceptDeclineCancelDialog( 2031 Messages.get().key(Messages.GUI_DIALOG_NOT_SAVED_TITLE_0), 2032 message.toString()); 2033 leavingDialog.setAcceptText(Messages.get().key(Messages.GUI_BUTTON_SAVE_TEXT_0)); 2034 leavingDialog.setDeclineText(Messages.get().key(Messages.GUI_BUTTON_DISCARD_TEXT_0)); 2035 leavingDialog.setCloseText(Messages.get().key(Messages.GUI_BUTTON_RETURN_TEXT_0)); 2036 return leavingDialog; 2037 } 2038 2039 /** 2040 * Opens the group-container element editor.<p> 2041 * 2042 * @param groupContainer the group-container element 2043 */ 2044 private void openGroupEditor(CmsGroupContainerElementPanel groupContainer) { 2045 2046 m_controller.startEditingGroupcontainer(groupContainer, groupContainer.isGroupContainer()); 2047 } 2048}