001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (C) Alkacon Software (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.acacia.client.ui; 029 030import org.opencms.acacia.client.CmsAttributeHandler; 031import org.opencms.acacia.client.CmsButtonBarHandler; 032import org.opencms.acacia.client.CmsChoiceMenuEntryBean; 033import org.opencms.acacia.client.CmsEditorBase; 034import org.opencms.acacia.client.I_CmsInlineFormParent; 035import org.opencms.acacia.client.I_CmsInlineHtmlUpdateHandler; 036import org.opencms.acacia.client.I_CmsWidgetService; 037import org.opencms.acacia.client.css.I_CmsLayoutBundle; 038import org.opencms.acacia.client.entity.CmsEntityBackend; 039import org.opencms.acacia.shared.CmsEntity; 040import org.opencms.acacia.shared.CmsType; 041import org.opencms.gwt.client.ui.CmsHighlightingBorder; 042import org.opencms.gwt.client.ui.CmsPopup; 043import org.opencms.gwt.client.ui.CmsPushButton; 044import org.opencms.gwt.client.ui.I_CmsButton; 045import org.opencms.gwt.client.ui.I_CmsButton.ButtonStyle; 046import org.opencms.gwt.client.util.CmsPositionBean; 047 048import java.util.List; 049 050import com.google.gwt.core.shared.GWT; 051import com.google.gwt.dom.client.Element; 052import com.google.gwt.dom.client.Style.Display; 053import com.google.gwt.dom.client.Style.Unit; 054import com.google.gwt.event.dom.client.ClickEvent; 055import com.google.gwt.event.dom.client.ClickHandler; 056import com.google.gwt.event.dom.client.MouseOutEvent; 057import com.google.gwt.event.dom.client.MouseOverEvent; 058import com.google.gwt.event.logical.shared.CloseEvent; 059import com.google.gwt.event.logical.shared.CloseHandler; 060import com.google.gwt.event.logical.shared.ResizeEvent; 061import com.google.gwt.event.logical.shared.ResizeHandler; 062import com.google.gwt.event.logical.shared.ValueChangeEvent; 063import com.google.gwt.event.logical.shared.ValueChangeHandler; 064import com.google.gwt.event.shared.HandlerRegistration; 065import com.google.gwt.uibinder.client.UiBinder; 066import com.google.gwt.uibinder.client.UiField; 067import com.google.gwt.uibinder.client.UiHandler; 068import com.google.gwt.user.client.Command; 069import com.google.gwt.user.client.Timer; 070import com.google.gwt.user.client.Window; 071import com.google.gwt.user.client.rpc.AsyncCallback; 072import com.google.gwt.user.client.ui.Composite; 073import com.google.gwt.user.client.ui.FlowPanel; 074import com.google.gwt.user.client.ui.PopupPanel; 075import com.google.gwt.user.client.ui.RootPanel; 076 077/** 078 * Widget allowing form based editing for parts of a content to enhance the in-line editing.<p> 079 */ 080public final class CmsInlineEntityWidget extends Composite { 081 082 /** 083 * Flow panel with handling descendant resizes to reposition pop-up.<p> 084 */ 085 protected class FormPanel extends FlowPanel implements org.opencms.gwt.client.I_CmsDescendantResizeHandler { 086 087 /** 088 * Constructor.<p> 089 */ 090 protected FormPanel() { 091 092 } 093 094 /** 095 * @see org.opencms.gwt.client.I_CmsDescendantResizeHandler#onResizeDescendant() 096 */ 097 public void onResizeDescendant() { 098 099 positionPopup(); 100 } 101 } 102 103 /** 104 * Timer to update the HTML.<p> 105 */ 106 protected class UpdateTimer extends Timer { 107 108 /** Indicates if the timer is scheduled. */ 109 private boolean m_scheduled; 110 111 /** 112 * @see com.google.gwt.user.client.Timer#cancel() 113 */ 114 @Override 115 public void cancel() { 116 117 m_scheduled = false; 118 super.cancel(); 119 } 120 121 /** 122 * Returns if the timer is already scheduled.<p> 123 * 124 * @return <code>true</code> if the timer is scheduled 125 */ 126 public boolean isScheduled() { 127 128 return m_scheduled; 129 } 130 131 /** 132 * @see com.google.gwt.user.client.Timer#run() 133 */ 134 @Override 135 public void run() { 136 137 m_scheduled = false; 138 runHtmlUpdate(); 139 } 140 141 /** 142 * @see com.google.gwt.user.client.Timer#schedule(int) 143 */ 144 @Override 145 public void schedule(int delayMillis) { 146 147 m_scheduled = true; 148 super.schedule(delayMillis); 149 } 150 } 151 152 /** 153 * The UI binder interface.<p> 154 */ 155 interface I_InlineEntityWidgetUiBinder extends UiBinder<FlowPanel, CmsInlineEntityWidget> { 156 // nothing to do 157 } 158 159 /** The height required by edit buttons. */ 160 private static final int REQUIRED_BUTTON_HEIGHT = 20; 161 162 /** The UI binder instance. */ 163 private static I_InlineEntityWidgetUiBinder uiBinder = GWT.create(I_InlineEntityWidgetUiBinder.class); 164 165 /** The add button. */ 166 @UiField 167 protected CmsAttributeChoiceWidget m_addButton; 168 169 /** The attribute choice button. */ 170 @UiField 171 protected CmsAttributeChoiceWidget m_attributeChoice; 172 173 /** The down button. */ 174 @UiField 175 protected CmsPushButton m_downButton; 176 177 /** The injected button. */ 178 @UiField 179 protected CmsPushButton m_editButton; 180 181 /** The remove button. */ 182 @UiField 183 protected CmsPushButton m_removeButton; 184 185 /** The up button. */ 186 @UiField 187 protected CmsPushButton m_upButton; 188 189 /** The highlighting border widget. */ 190 CmsHighlightingBorder m_highlighting; 191 192 /** The pop-up panel. */ 193 CmsPopup m_popup; 194 195 /** The handler of the attribute to edit. */ 196 private CmsAttributeHandler m_attributeHandler; 197 198 /** The attribute value index. */ 199 private int m_attributeIndex; 200 201 /** The change handler registration. */ 202 private HandlerRegistration m_entityChangeHandlerRegistration; 203 204 /** The parent widget. */ 205 private I_CmsInlineFormParent m_formParent; 206 207 /** Indicates if the content has been changed while the edit pop-up was shown. */ 208 private boolean m_hasChanges; 209 210 /** Handles HTML updates if required. */ 211 private I_CmsInlineHtmlUpdateHandler m_htmlUpdateHandler; 212 213 /** A timer to update the overlay position. */ 214 private Timer m_overlayTimer; 215 216 /** The parent of the entity to edit. */ 217 private CmsEntity m_parentEntity; 218 219 /** Flag indicating the popup has been closed. */ 220 private boolean m_popupClosed; 221 222 /** The reference DOM element, will be highlighted during editing. */ 223 private Element m_referenceElement; 224 225 /** Flag indicating it is required to open the edit popup aftera HTML update. */ 226 private boolean m_requireShowPopup; 227 228 /** Flag indicating an HTML update is running. */ 229 private boolean m_runningUpdate; 230 231 /** The dialog title. */ 232 private String m_title; 233 234 /** Schedules the HTML update. */ 235 private UpdateTimer m_updateTimer; 236 237 /** The widget service. */ 238 private I_CmsWidgetService m_widgetService; 239 240 /** 241 * Constructor.<p> 242 * 243 * @param referenceElement the reference DOM element, will be highlighted during editing 244 * @param formParent the parent widget 245 * @param parentEntity the parent of the entity to edit 246 * @param attributeHandler the attribute handler 247 * @param attributeIndex the attribute value index 248 * @param htmlUpdateHandler handles HTML updates if required 249 * @param widgetService the widget service 250 */ 251 private CmsInlineEntityWidget( 252 Element referenceElement, 253 I_CmsInlineFormParent formParent, 254 CmsEntity parentEntity, 255 CmsAttributeHandler attributeHandler, 256 int attributeIndex, 257 I_CmsInlineHtmlUpdateHandler htmlUpdateHandler, 258 I_CmsWidgetService widgetService) { 259 260 initWidget(uiBinder.createAndBindUi(this)); 261 m_parentEntity = parentEntity; 262 m_attributeHandler = attributeHandler; 263 m_attributeIndex = attributeIndex; 264 m_referenceElement = referenceElement; 265 m_formParent = formParent; 266 m_htmlUpdateHandler = htmlUpdateHandler; 267 m_widgetService = widgetService; 268 m_title = ""; 269 m_updateTimer = new UpdateTimer(); 270 m_popupClosed = true; 271 initButtons(); 272 addDomHandler(CmsButtonBarHandler.INSTANCE, MouseOverEvent.getType()); 273 addDomHandler(CmsButtonBarHandler.INSTANCE, MouseOutEvent.getType()); 274 } 275 276 /** 277 * Creates the inline edit widget and injects it next to the context element.<p> 278 * 279 * @param element the context element 280 * @param formParent the parent widget 281 * @param parentEntity the parent entity 282 * @param attributeHandler the attribute handler 283 * @param attributeIndex the attribute value index 284 * @param htmlUpdateHandler handles HTML updates if required 285 * @param widgetService the widget service 286 * 287 * @return the widget instance 288 */ 289 public static CmsInlineEntityWidget createWidgetForEntity( 290 Element element, 291 I_CmsInlineFormParent formParent, 292 CmsEntity parentEntity, 293 CmsAttributeHandler attributeHandler, 294 int attributeIndex, 295 I_CmsInlineHtmlUpdateHandler htmlUpdateHandler, 296 I_CmsWidgetService widgetService) { 297 298 CmsInlineEntityWidget widget = new CmsInlineEntityWidget( 299 element, 300 formParent, 301 parentEntity, 302 attributeHandler, 303 attributeIndex, 304 htmlUpdateHandler, 305 widgetService); 306 CmsInlineEditOverlay.getRootOverlay().addButton(widget, getButtonTop(element)); 307 attributeHandler.updateButtonVisibilty(widget); 308 return widget; 309 } 310 311 /** 312 * Returns the button top position for the given reference element.<p> 313 * 314 * @param element the reference element 315 * 316 * @return the button position 317 */ 318 private static int getButtonTop(Element element) { 319 320 int top = element.getAbsoluteTop(); 321 int height = element.getClientHeight(); 322 if ((height < REQUIRED_BUTTON_HEIGHT) && (top > REQUIRED_BUTTON_HEIGHT)) { 323 top = top - REQUIRED_BUTTON_HEIGHT; 324 } 325 return top; 326 } 327 328 /** 329 * Returns the attribute value index.<p> 330 * 331 * @return the attribute value index 332 */ 333 public int getAttributeIndex() { 334 335 return m_attributeIndex; 336 } 337 338 /** 339 * Sets the visibility of the reference element highlighting border.<p> 340 * 341 * @param visible <code>true</code> to show the highlighting 342 */ 343 public void setContentHighlightingVisible(boolean visible) { 344 345 if (visible) { 346 if (m_highlighting == null) { 347 m_highlighting = new CmsHighlightingBorder( 348 CmsPositionBean.getBoundingClientRect(m_referenceElement), 349 CmsHighlightingBorder.BorderColor.red); 350 RootPanel.get().add(m_highlighting); 351 } else { 352 m_highlighting.setPosition(CmsPositionBean.getBoundingClientRect(m_referenceElement)); 353 } 354 } else { 355 if (m_highlighting != null) { 356 m_highlighting.removeFromParent(); 357 m_highlighting = null; 358 } 359 } 360 } 361 362 /** 363 * Updates the visibility of the add, remove, up and down buttons.<p> 364 * 365 * @param hasEditButton <code>true</code> if the edit button should be visible 366 * @param hasAddButton <code>true</code> if the add button should be visible 367 * @param hasRemoveButton <code>true</code> if the remove button should be visible 368 * @param hasSortButtons <code>true</code> if the sort buttons should be visible 369 */ 370 public void updateButtonVisibility( 371 boolean hasEditButton, 372 boolean hasAddButton, 373 boolean hasRemoveButton, 374 boolean hasSortButtons) { 375 376 if (hasEditButton) { 377 m_editButton.getElement().getStyle().clearDisplay(); 378 } else { 379 m_editButton.getElement().getStyle().setDisplay(Display.NONE); 380 } 381 // if (hasAddButton && m_isChoice) { 382 // m_attributeChoice.getElement().getStyle().clearDisplay(); 383 // } else { 384 m_attributeChoice.getElement().getStyle().setDisplay(Display.NONE); 385 // } 386 if (hasAddButton) { 387 m_addButton.getElement().getStyle().clearDisplay(); 388 } else { 389 m_addButton.getElement().getStyle().setDisplay(Display.NONE); 390 } 391 392 if (hasRemoveButton) { 393 m_removeButton.getElement().getStyle().clearDisplay(); 394 } else { 395 m_removeButton.getElement().getStyle().setDisplay(Display.NONE); 396 } 397 if (hasSortButtons && (m_attributeIndex != 0)) { 398 m_upButton.getElement().getStyle().clearDisplay(); 399 } else { 400 m_upButton.getElement().getStyle().setDisplay(Display.NONE); 401 } 402 if (hasSortButtons && (getElement().getNextSibling() != null)) { 403 m_downButton.getElement().getStyle().clearDisplay(); 404 } else { 405 m_downButton.getElement().getStyle().setDisplay(Display.NONE); 406 } 407 408 if (hasEditButton && (hasAddButton || hasRemoveButton || hasSortButtons)) { 409 // set multi button mode 410 addStyleName(I_CmsLayoutBundle.INSTANCE.form().multiButtonBar()); 411 } else { 412 removeStyleName(I_CmsLayoutBundle.INSTANCE.form().multiButtonBar()); 413 } 414 } 415 416 /** 417 * Positions the widget button above the reference element.<p> 418 */ 419 protected void positionWidget() { 420 421 CmsInlineEditOverlay.getRootOverlay().setButtonPosition(this, getButtonTop(m_referenceElement)); 422 } 423 424 /** Adds a new attribute value. */ 425 void addNewAttributeValue() { 426 427 m_attributeHandler.addNewAttributeValueToEntity(m_attributeIndex); 428 m_requireShowPopup = true; 429 m_attributeIndex += 1; 430 runHtmlUpdate(); 431 } 432 433 /** 434 * Repositions the edit overlay after the HTML has been updated.<p> 435 */ 436 void afterHtmlUpdate() { 437 438 if (m_overlayTimer != null) { 439 m_overlayTimer.cancel(); 440 m_overlayTimer = null; 441 } 442 m_runningUpdate = false; 443 List<Element> elements = CmsEntityBackend.getInstance().getAttributeElements( 444 m_parentEntity, 445 m_attributeHandler.getAttributeName(), 446 m_formParent.getElement()); 447 if (m_popupClosed) { 448 // the form popup has already been closed, reinitialize the editing widgets for updated HTML 449 CmsInlineEditOverlay.updateCurrentOverlayPosition(); 450 if (m_requireShowPopup) { 451 if (elements.size() > m_attributeIndex) { 452 m_referenceElement = elements.get(m_attributeIndex); 453 } 454 showEditPopup(null); 455 m_hasChanges = true; 456 } else { 457 CmsInlineEditOverlay.getRootOverlay().clearButtonPanel(); 458 m_htmlUpdateHandler.reinitWidgets(m_formParent); 459 } 460 461 } else { 462 if (m_referenceElement != null) { 463 CmsInlineEditOverlay.removeLastOverlay(); 464 } 465 if (elements.size() > m_attributeIndex) { 466 m_referenceElement = elements.get(m_attributeIndex); 467 CmsInlineEditOverlay.addOverlayForElement(m_referenceElement); 468 } else { 469 m_referenceElement = m_formParent.getElement(); 470 CmsInlineEditOverlay.addOverlayForElement(m_referenceElement); 471 } 472 } 473 // schedule to update the ovelay position 474 m_overlayTimer = new Timer() { 475 476 /** Timer run counter. */ 477 private int m_timerRuns; 478 479 /** 480 * @see com.google.gwt.user.client.Timer#run() 481 */ 482 @Override 483 public void run() { 484 485 CmsInlineEditOverlay.updateCurrentOverlayPosition(); 486 if (m_timerRuns > 3) { 487 cancel(); 488 } 489 m_timerRuns++; 490 } 491 }; 492 m_overlayTimer.scheduleRepeating(100); 493 } 494 495 /** 496 * Sets the changed flag.<p> 497 */ 498 void onEntityChange() { 499 500 if (m_updateTimer.isScheduled()) { 501 m_updateTimer.cancel(); 502 } 503 m_updateTimer.schedule(150); 504 m_hasChanges = true; 505 } 506 507 /** 508 * Cleanup after the edit pop-up was opened.<p> 509 */ 510 void onPopupClose() { 511 512 if (m_referenceElement != null) { 513 CmsInlineEditOverlay.removeLastOverlay(); 514 } 515 CmsInlineEditOverlay.updateCurrentOverlayPosition(); 516 if (m_entityChangeHandlerRegistration != null) { 517 m_entityChangeHandlerRegistration.removeHandler(); 518 } 519 CmsAttributeHandler.setResizeHandler(null); 520 if (!m_runningUpdate) { 521 if (m_hasChanges) { 522 CmsInlineEditOverlay.getRootOverlay().clearButtonPanel(); 523 m_htmlUpdateHandler.reinitWidgets(m_formParent); 524 } 525 } 526 m_popup = null; 527 } 528 529 /** Handles the remove attribute click.<p> 530 * 531 * @param event the click event 532 */ 533 @UiHandler("m_removeButton") 534 void onRemoveClick(ClickEvent event) { 535 536 m_attributeHandler.removeAttributeValueFromEntity(m_attributeIndex); 537 setContentHighlightingVisible(false); 538 runHtmlUpdate(); 539 } 540 541 /** 542 * Positions the given pop-up relative to the reference element.<p> 543 */ 544 void positionPopup() { 545 546 if (m_popup != null) { 547 if (m_referenceElement != null) { 548 CmsPositionBean referencePosition = CmsPositionBean.getBoundingClientRect(m_referenceElement); 549 int currentTop = m_popup.getAbsoluteTop(); 550 int windowHeight = Window.getClientHeight(); 551 int scrollTop = Window.getScrollTop(); 552 int contentHeight = m_popup.getOffsetHeight(); 553 int top = referencePosition.getTop(); 554 if (((windowHeight + scrollTop) < (top + referencePosition.getHeight() + contentHeight + 20)) 555 && ((contentHeight + 40) < top)) { 556 top = top - contentHeight - 5; 557 if ((currentTop < top) && ((top - currentTop) < 200)) { 558 // keep the current position 559 top = currentTop; 560 } 561 } else { 562 top = top + referencePosition.getHeight() + 5; 563 if ((currentTop > top) && ((currentTop - top) < 200)) { 564 // keep the current position 565 top = currentTop; 566 } 567 } 568 m_popup.center(); 569 m_popup.setPopupPosition(m_popup.getPopupLeft(), top); 570 if (((contentHeight + top) - scrollTop) > windowHeight) { 571 Window.scrollTo(Window.getScrollLeft(), ((contentHeight + top) - windowHeight) + 20); 572 } 573 } else { 574 m_popup.center(); 575 } 576 } 577 } 578 579 /** 580 * Updates the HTML according to the entity data.<p> 581 */ 582 void runHtmlUpdate() { 583 584 if (m_runningUpdate) { 585 m_updateTimer.schedule(50); 586 } else { 587 m_runningUpdate = true; 588 m_htmlUpdateHandler.updateHtml(m_formParent, new Command() { 589 590 public void execute() { 591 592 afterHtmlUpdate(); 593 } 594 }); 595 } 596 } 597 598 /** 599 * Opens the form popup.<p> 600 * 601 * @param clickEvent the click event 602 */ 603 @UiHandler("m_editButton") 604 void showEditPopup(ClickEvent clickEvent) { 605 606 m_editButton.clearHoverState(); 607 m_popup = new CmsPopup(m_title, -1); 608 m_popup.setModal(true); 609 m_popup.setAutoHideEnabled(true); 610 m_popup.removePadding(); 611 m_popup.addCloseHandler(new CloseHandler<PopupPanel>() { 612 613 public void onClose(CloseEvent<PopupPanel> event) { 614 615 onPopupClose(); 616 } 617 }); 618 m_hasChanges = false; 619 m_requireShowPopup = false; 620 m_entityChangeHandlerRegistration = m_parentEntity.addValueChangeHandler(new ValueChangeHandler<CmsEntity>() { 621 622 public void onValueChange(ValueChangeEvent<CmsEntity> event) { 623 624 onEntityChange(); 625 } 626 }); 627 CmsType type = CmsEntityBackend.getInstance().getType(m_parentEntity.getTypeName()); 628 FlowPanel formPanel = new FormPanel(); 629 formPanel.setStyleName(I_CmsLayoutBundle.INSTANCE.form().formParent()); 630 formPanel.getElement().getStyle().setMargin(0, Unit.PX); 631 formPanel.getElement().getStyle().setBorderWidth(0, Unit.PX); 632 formPanel.getElement().getStyle().setPropertyPx("minHeight", 30); 633 m_popup.add(formPanel); 634 m_popup.addDialogClose(null); 635 I_CmsLayoutBundle.INSTANCE.dialogCss().ensureInjected(); 636 m_popup.show(); 637 CmsAttributeHandler.setScrollElement(formPanel.getElement()); 638 CmsAttributeHandler.setResizeHandler(new ResizeHandler() { 639 640 public void onResize(ResizeEvent event) { 641 642 positionPopup(); 643 } 644 }); 645 m_widgetService.getRendererForType( 646 type).renderAttributeValue(m_parentEntity, m_attributeHandler, m_attributeIndex, formPanel); 647 CmsInlineEditOverlay.addOverlayForElement(m_referenceElement); 648 positionPopup(); 649 m_popup.getElement().getStyle().setZIndex(I_CmsLayoutBundle.INSTANCE.constants().css().zIndexPopup()); 650 m_popupClosed = false; 651 } 652 653 /** 654 * Initializes the button styling.<p> 655 */ 656 private void initButtons() { 657 658 m_addButton.addChoice( 659 m_attributeHandler.getWidgetService(), 660 new CmsChoiceMenuEntryBean(m_attributeHandler.getAttributeName()), 661 new AsyncCallback<CmsChoiceMenuEntryBean>() { 662 663 public void onFailure(Throwable caught) { 664 665 // will not be called 666 667 } 668 669 public void onSuccess(CmsChoiceMenuEntryBean selectedEntry) { 670 671 // nothing to do 672 } 673 }); 674 m_addButton.addDomHandler(new ClickHandler() { 675 676 public void onClick(ClickEvent event) { 677 678 m_addButton.hide(); 679 addNewAttributeValue(); 680 event.preventDefault(); 681 event.stopPropagation(); 682 683 } 684 }, ClickEvent.getType()); 685 686 m_editButton.setImageClass(I_CmsButton.PEN_SMALL); 687 m_editButton.setButtonStyle(ButtonStyle.FONT_ICON, null); 688 689 m_removeButton.setImageClass(I_CmsButton.CUT_SMALL); 690 m_removeButton.setButtonStyle(ButtonStyle.FONT_ICON, null); 691 692 m_upButton.setImageClass(I_CmsButton.EDIT_UP_SMALL); 693 m_upButton.setButtonStyle(ButtonStyle.FONT_ICON, null); 694 695 m_downButton.setImageClass(I_CmsButton.EDIT_DOWN_SMALL); 696 m_downButton.setButtonStyle(ButtonStyle.FONT_ICON, null); 697 698 if (CmsEditorBase.hasDictionary()) { 699 String label = m_widgetService.getAttributeLabel(m_attributeHandler.getAttributeName()); 700 m_addButton.setTitle(CmsEditorBase.getMessageForKey(CmsEditorBase.GUI_VIEW_ADD_1, label)); 701 m_removeButton.setTitle(CmsEditorBase.getMessageForKey(CmsEditorBase.GUI_VIEW_DELETE_1, label)); 702 m_upButton.setTitle(CmsEditorBase.getMessageForKey(CmsEditorBase.GUI_VIEW_MOVE_UP_0)); 703 m_downButton.setTitle(CmsEditorBase.getMessageForKey(CmsEditorBase.GUI_VIEW_MOVE_DOWN_0)); 704 m_title = CmsEditorBase.getMessageForKey(CmsEditorBase.GUI_VIEW_EDIT_1, label); 705 m_editButton.setTitle(m_title); 706 } 707 } 708}