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}