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.galleries.client.ui;
029
030import org.opencms.ade.galleries.client.Messages;
031import org.opencms.ade.galleries.client.ui.css.I_CmsLayoutBundle;
032import org.opencms.ade.galleries.client.ui.css.I_CmsLayoutBundle.I_CmsGalleryDialogCss;
033import org.opencms.ade.galleries.shared.CmsGallerySearchBean;
034import org.opencms.ade.galleries.shared.CmsResourceTypeBean;
035import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants.GalleryTabId;
036import org.opencms.ade.upload.client.I_CmsUploadContext;
037import org.opencms.ade.upload.client.ui.CmsDialogUploadButtonHandler;
038import org.opencms.gwt.client.ui.CmsList;
039import org.opencms.gwt.client.ui.CmsPushButton;
040import org.opencms.gwt.client.ui.CmsScrollPanel;
041import org.opencms.gwt.client.ui.I_CmsButton;
042import org.opencms.gwt.client.ui.I_CmsButton.ButtonStyle;
043import org.opencms.gwt.client.ui.I_CmsListItem;
044import org.opencms.gwt.client.ui.I_CmsTruncable;
045import org.opencms.gwt.client.ui.externallink.CmsEditExternalLinkDialog;
046import org.opencms.gwt.client.ui.input.CmsCheckBox;
047import org.opencms.gwt.client.ui.input.CmsSelectBox;
048import org.opencms.gwt.client.ui.input.CmsTextBox;
049import org.opencms.gwt.client.ui.input.upload.CmsUploadButton;
050import org.opencms.gwt.client.ui.tree.CmsTreeItem;
051import org.opencms.util.CmsStringUtil;
052import org.opencms.util.CmsUUID;
053
054import java.util.LinkedHashMap;
055import java.util.List;
056
057import com.google.common.base.Supplier;
058import com.google.gwt.core.client.GWT;
059import com.google.gwt.core.client.Scheduler;
060import com.google.gwt.core.client.Scheduler.ScheduledCommand;
061import com.google.gwt.dom.client.Style;
062import com.google.gwt.dom.client.Style.Unit;
063import com.google.gwt.event.dom.client.ClickEvent;
064import com.google.gwt.event.dom.client.ClickHandler;
065import com.google.gwt.event.dom.client.DoubleClickEvent;
066import com.google.gwt.event.dom.client.DoubleClickHandler;
067import com.google.gwt.event.dom.client.KeyCodes;
068import com.google.gwt.event.dom.client.KeyPressEvent;
069import com.google.gwt.event.dom.client.KeyPressHandler;
070import com.google.gwt.event.logical.shared.CloseEvent;
071import com.google.gwt.event.logical.shared.CloseHandler;
072import com.google.gwt.event.logical.shared.ValueChangeEvent;
073import com.google.gwt.event.logical.shared.ValueChangeHandler;
074import com.google.gwt.event.shared.HandlerRegistration;
075import com.google.gwt.uibinder.client.UiBinder;
076import com.google.gwt.uibinder.client.UiField;
077import com.google.gwt.user.client.Timer;
078import com.google.gwt.user.client.ui.FlowPanel;
079import com.google.gwt.user.client.ui.HasText;
080import com.google.gwt.user.client.ui.Label;
081import com.google.gwt.user.client.ui.PopupPanel;
082import com.google.gwt.user.client.ui.Widget;
083
084/**
085 * Provides a widget for the content of a tab.<p>
086 *
087 * @since 8.0.
088 */
089public abstract class A_CmsListTab extends A_CmsTab implements ValueChangeHandler<String>, I_CmsTruncable {
090
091    /** Selection handler to handle check box click events and double clicks on the list items. */
092    protected abstract class A_SelectionHandler implements ClickHandler {
093
094        /** The reference to the checkbox. */
095        private CmsCheckBox m_checkBox;
096
097        /** The the select button, can be used instead of a double click to select and search. */
098        private CmsPushButton m_selectButton;
099
100        /**
101         * Constructor.<p>
102         *
103         * @param checkBox the item check box
104         */
105        protected A_SelectionHandler(CmsCheckBox checkBox) {
106
107            m_checkBox = checkBox;
108        }
109
110        /**
111         * Returns the select button.<p>
112         *
113         * @return the select button
114         */
115        public CmsPushButton getSelectButton() {
116
117            return m_selectButton;
118        }
119
120        /**
121         * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
122         */
123        public void onClick(ClickEvent event) {
124
125            if (event.getSource().equals(m_checkBox)) {
126                onSelectionChange();
127            } else {
128                selectBeforeGoingToResultTab();
129                getTabHandler().selectResultTab();
130            }
131        }
132
133        /**
134         * Sets the select button, can be used instead of a double click to select and search.<p>
135         *
136         * @param button the select button
137         */
138        public void setSelectButton(CmsPushButton button) {
139
140            m_selectButton = button;
141        }
142
143        /**
144         * Returns the check box.<p>
145         *
146         * @return the check box
147         */
148        protected CmsCheckBox getCheckBox() {
149
150            return m_checkBox;
151        }
152
153        /**
154         * Executed on selection change. Either when the check box was clicked or on double click on a list item.<p>
155         */
156        protected abstract void onSelectionChange();
157
158        /**
159         * This method is called if a list item is selected in a way such that the result tab should be displayed
160         * immediately.<p>
161         */
162        protected void selectBeforeGoingToResultTab() {
163
164            m_checkBox.setChecked(true);
165            onSelectionChange();
166        }
167    }
168
169    /**
170     * Special click handler to use with select button.<p>
171     */
172    protected class SelectHandler implements ClickHandler, DoubleClickHandler {
173
174        /** The id of the selected item. */
175        private String m_resourcePath;
176
177        /** The resource type of the selected item. */
178        private String m_resourceType;
179
180        /** The structure id. */
181        private CmsUUID m_structureId;
182
183        /** The resource title. */
184        private String m_title;
185
186        /**
187         * Constructor.<p>
188         *
189         * @param resourcePath the item resource path
190         * @param structureId the structure id
191         * @param title the resource title
192         * @param resourceType the item resource type
193         */
194        public SelectHandler(String resourcePath, CmsUUID structureId, String title, String resourceType) {
195
196            m_resourcePath = resourcePath;
197            m_structureId = structureId;
198            m_resourceType = resourceType;
199            m_title = title;
200        }
201
202        /**
203         * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
204         */
205        public void onClick(ClickEvent event) {
206
207            getTabHandler().selectResource(m_resourcePath, m_structureId, m_title, m_resourceType);
208        }
209
210        /**
211         * @see com.google.gwt.event.dom.client.DoubleClickHandler#onDoubleClick(com.google.gwt.event.dom.client.DoubleClickEvent)
212         */
213        public void onDoubleClick(DoubleClickEvent event) {
214
215            getTabHandler().selectResource(m_resourcePath, m_structureId, m_title, m_resourceType);
216        }
217    }
218
219    /**
220     * @see com.google.gwt.uibinder.client.UiBinder
221     */
222    interface I_CmsListTabUiBinder extends UiBinder<Widget, A_CmsListTab> {
223        // GWT interface, nothing to do here
224    }
225
226    /** The css bundle used for this widget. */
227    protected static final I_CmsGalleryDialogCss DIALOG_CSS = I_CmsLayoutBundle.INSTANCE.galleryDialogCss();
228
229    /** The filtering delay. */
230    private static final int FILTER_DELAY = 200;
231
232    /** Text metrics key. */
233    private static final String TM_GALLERY_SORT = "gallerySort";
234
235    /** Text metrics key. */
236    private static final String TM_LIST_TAB = "ListTab";
237
238    /** The ui-binder instance for this class. */
239    private static I_CmsListTabUiBinder uiBinder = GWT.create(I_CmsListTabUiBinder.class);
240
241    /** A label for displaying additional information about the tab. */
242    protected HasText m_infoLabel;
243
244    /** The borded panel to hold the scrollable list. */
245    @UiField
246    protected CmsScrollPanel m_list;
247
248    /** The option panel. */
249    @UiField
250    protected FlowPanel m_options;
251
252    /** The quick search box. */
253    protected CmsTextBox m_quickSearch;
254
255    /** The scrollable list panel. */
256    protected CmsList<? extends I_CmsListItem> m_scrollList;
257
258    /** The quick search button. */
259    protected CmsPushButton m_searchButton;
260
261    /** The select box to change the sort order. */
262    protected CmsSelectBox m_sortSelectBox;
263
264    /** The option panel. */
265    @UiField
266    protected FlowPanel m_tab;
267
268    /** The quick filter timer. */
269    private Timer m_filterTimer;
270
271    /** The last quick search value. */
272    private String m_lastQuickSearchValue;
273
274    /** The quick search handler registration. */
275    private HandlerRegistration m_quickSearchRegistration;
276
277    /**
278     * The default constructor with drag handler.<p>
279     *
280     * @param tabId the tab id
281     */
282    public A_CmsListTab(GalleryTabId tabId) {
283
284        this(tabId.name());
285    }
286
287    /**
288     * Sets up a list tab with a given tab id.<p>
289     *
290     * @param tabId the tab id
291     */
292    public A_CmsListTab(String tabId) {
293
294        super(tabId);
295        uiBinder.createAndBindUi(this);
296        initWidget(uiBinder.createAndBindUi(this));
297        m_scrollList = createScrollList();
298        m_list.add(m_scrollList);
299    }
300
301    /**
302     * Returns the list.<p>
303     *
304     * @return the list
305     */
306    public CmsScrollPanel getList() {
307
308        return m_list;
309    }
310
311    /**
312     * @see org.opencms.ade.galleries.client.ui.A_CmsTab#getRequiredHeight()
313     */
314    @Override
315    public int getRequiredHeight() {
316
317        int list = m_scrollList.getOffsetHeight();
318        list = list > 82 ? list : 82;
319        return list + 47;
320    }
321
322    /**
323     * Call on content change to update the layout.<p>
324     */
325    public void onContentChange() {
326
327        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
328
329            public void execute() {
330
331                Widget parent = getParent();
332                while (parent != null) {
333                    if (parent instanceof CmsGalleryDialog) {
334                        ((CmsGalleryDialog)parent).updateSizes();
335                        parent = null;
336                    } else {
337                        parent = parent.getParent();
338                    }
339                }
340            }
341        });
342    }
343
344    /**
345     * @see org.opencms.ade.galleries.client.ui.A_CmsTab#onResize()
346     */
347    @Override
348    public void onResize() {
349
350        m_list.onResizeDescendant();
351    }
352
353    /**
354     * Will be triggered if the value in the select box changes.<p>
355     *
356     * @see com.google.gwt.event.logical.shared.ValueChangeHandler#onValueChange(com.google.gwt.event.logical.shared.ValueChangeEvent)
357     */
358    public void onValueChange(ValueChangeEvent<String> event) {
359
360        cancelQuickFilterTimer();
361        if (event.getSource() == m_sortSelectBox) {
362            // depending on the sort value the tab may or may not have the quick filter ability
363            if (hasQuickFilter()) {
364                if (m_quickSearch == null) {
365                    createQuickBox();
366                }
367            } else {
368                removeQuickBox();
369            }
370            getTabHandler().onSort(event.getValue(), hasQuickFilter() ? m_quickSearch.getFormValueAsString() : null);
371        }
372        if ((event.getSource() == m_quickSearch)) {
373            if (hasQuickFilter()) {
374
375                if ((CmsStringUtil.isEmptyOrWhitespaceOnly(event.getValue()) || (event.getValue().length() >= 3))) {
376                    // only act if filter length is at least 3 characters or empty
377                    if ((m_lastQuickSearchValue == null) || !m_lastQuickSearchValue.equals(event.getValue())) {
378                        scheduleQuickFilterTimer();
379                    }
380                    m_lastQuickSearchValue = event.getValue();
381                }
382            } else {
383                checkQuickSearchStatus();
384            }
385        }
386    }
387
388    /**
389     * Sets the value selected in the sort select box, if possible.<p>
390     *
391     * @param value the new value for the sort select box
392     * @param fireEvents if true, the change event of the select box is fired
393     */
394    public void setSortSelectBoxValue(String value, boolean fireEvents) {
395
396        if ((m_sortSelectBox != null) && (value != null)) {
397            m_sortSelectBox.setFormValue(value, fireEvents);
398        }
399    }
400
401    /**
402     * @see org.opencms.gwt.client.ui.I_CmsTruncable#truncate(java.lang.String, int)
403     */
404    public void truncate(String textMetricsKey, int clientWidth) {
405
406        m_scrollList.truncate(TM_LIST_TAB, clientWidth);
407    }
408
409    /**
410     * Adds a widget to the front of the list.<p>
411     *
412     * @param listItem the list item to add
413     */
414    protected void addWidgetToFrontOfList(Widget listItem) {
415
416        m_scrollList.insert(listItem, 0);
417    }
418
419    /**
420     * Add a list item widget to the list panel.<p>
421     *
422     * @param listItem the list item to add
423     */
424    protected void addWidgetToList(Widget listItem) {
425
426        m_scrollList.add(listItem);
427    }
428
429    /**
430     * Add a widget to the option panel.<p>
431     *
432     * The option panel should contain drop down boxes or other list options.
433     *
434     * @param widget the widget to add
435     */
436    protected void addWidgetToOptions(Widget widget) {
437
438        m_options.add(widget);
439    }
440
441    /**
442     * Cancels the quick filter timer.<p>
443     */
444    protected void cancelQuickFilterTimer() {
445
446        if (m_filterTimer != null) {
447            m_filterTimer.cancel();
448        }
449    }
450
451    /**
452     * Checks the quick search input and enables/disables the search button accordingly.<p>
453     */
454    protected void checkQuickSearchStatus() {
455
456        if ((m_quickSearch != null) && (m_searchButton != null)) {
457            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_quickSearch.getFormValueAsString())) {
458                m_searchButton.enable();
459            } else {
460                m_searchButton.disable("Enter a search query");
461            }
462        }
463    }
464
465    /**
466     * Clears the list panel.<p>
467     */
468    protected void clearList() {
469
470        m_scrollList.clearList();
471        onContentChange();
472    }
473
474    /**
475     * Generates a button to create new external link resources.<p>
476     *
477     * @param parentPath the parent folder site path
478     *
479     * @return the button widget
480     */
481    protected CmsPushButton createNewExternalLinkButton(final String parentPath) {
482
483        final CmsResourceTypeBean typeInfo = getTabHandler().getTypeInfo(
484            CmsEditExternalLinkDialog.POINTER_RESOURCE_TYPE_NAME);
485        CmsPushButton createNewButton = null;
486        if (typeInfo != null) {
487            createNewButton = new CmsPushButton(I_CmsButton.ADD_SMALL);
488            createNewButton.setTitle(
489                org.opencms.gwt.client.Messages.get().key(
490                    org.opencms.gwt.client.Messages.GUI_CREATE_NEW_LINK_DIALOG_TITLE_0));
491            createNewButton.setButtonStyle(ButtonStyle.FONT_ICON, null);
492            createNewButton.addClickHandler(new ClickHandler() {
493
494                public void onClick(ClickEvent event) {
495
496                    CmsEditExternalLinkDialog dialog = CmsEditExternalLinkDialog.showNewLinkDialog(
497                        typeInfo,
498                        parentPath);
499                    dialog.addCloseHandler(new CloseHandler<PopupPanel>() {
500
501                        public void onClose(CloseEvent<PopupPanel> closeEvent) {
502
503                            getTabHandler().updateIndex();
504                        }
505                    });
506                }
507            });
508        }
509        return createNewButton;
510    }
511
512    /**
513     * Creates the list which should contain the list items of the tab.<p>
514     *
515     * @return the newly created list widget
516     */
517    protected CmsList<? extends I_CmsListItem> createScrollList() {
518
519        return new CmsList<I_CmsListItem>();
520    }
521
522    /**
523     * Creates a select button.<p>
524     *
525     * @param selectionHandler the selction handler
526     *
527     * @return the select button
528     */
529    protected CmsPushButton createSelectButton(A_SelectionHandler selectionHandler) {
530
531        CmsPushButton selectButton = new CmsPushButton();
532        selectButton.setImageClass(I_CmsButton.SEARCH_SMALL);
533        selectButton.setTitle(Messages.get().key(Messages.GUI_TAB_SEARCH_SEARCH_EXISTING_0));
534        selectButton.setButtonStyle(ButtonStyle.FONT_ICON, null);
535        selectionHandler.setSelectButton(selectButton);
536        selectButton.addClickHandler(selectionHandler);
537        return selectButton;
538    }
539
540    /**
541     * Creates a button widget to select the specified resource.<p>
542     *
543     * @param resourcePath the item resource path
544     * @param structureId the structure id
545     * @param title the resource title
546     * @param resourceType the item resource type
547     *
548     * @return the initialized select resource button
549     */
550    protected CmsPushButton createSelectResourceButton(
551        String resourcePath,
552        CmsUUID structureId,
553        String title,
554        String resourceType) {
555
556        CmsPushButton result = new CmsPushButton();
557        result.setImageClass(I_CmsButton.CHECK_SMALL);
558        result.setButtonStyle(ButtonStyle.FONT_ICON, null);
559        result.setTitle(Messages.get().key(Messages.GUI_PREVIEW_BUTTON_SELECT_0));
560        result.addClickHandler(new SelectHandler(resourcePath, structureId, title, resourceType));
561        return result;
562    }
563
564    /**
565     * Creates an upload button for the given target.<p>
566     *
567     * @param target the upload target folder
568     * @param isRootPath true if target is a root path
569     *
570     * @return the upload button
571     */
572    protected CmsUploadButton createUploadButtonForTarget(String target, boolean isRootPath) {
573
574        CmsDialogUploadButtonHandler buttonHandler = new CmsDialogUploadButtonHandler(
575
576            new Supplier<I_CmsUploadContext>() {
577
578                public I_CmsUploadContext get() {
579
580                    return new I_CmsUploadContext() {
581
582                        public void onUploadFinished(List<String> uploadedFiles) {
583
584                            getTabHandler().updateIndex();
585                        }
586
587                    };
588                }
589            });
590
591        buttonHandler.setTargetFolder(target);
592        buttonHandler.setIsTargetRootPath(isRootPath);
593        CmsUploadButton uploadButton = new CmsUploadButton(buttonHandler);
594        uploadButton.setText(null);
595        uploadButton.setTitle(Messages.get().key(Messages.GUI_GALLERY_UPLOAD_TITLE_1, target));
596        uploadButton.setButtonStyle(ButtonStyle.FONT_ICON, null);
597        uploadButton.setImageClass(I_CmsButton.UPLOAD_SMALL);
598        return uploadButton;
599    }
600
601    /**
602     * Returns a list with sort values for this tab.<p>
603     *
604     * @return list of sort order value/text pairs
605     */
606    protected abstract LinkedHashMap<String, String> getSortList();
607
608    /**
609     * Returns if this tab has quick filter enabled.<p>
610     *
611     * @return <code>true</code> if this tab has quick filter enabled
612     */
613    protected boolean hasQuickFilter() {
614
615        return false;
616    }
617
618    /**
619     * Returns if the tab has the quick search box.<p>
620     *
621     * @return <code>true</code> if the tab has the quick search box
622     */
623    protected boolean hasQuickSearch() {
624
625        return false;
626    }
627
628    /**
629     * Call after all handlers have been set.<p>
630     */
631    protected void init() {
632
633        LinkedHashMap<String, String> sortList = getSortList();
634        if (sortList != null) {
635            m_sortSelectBox = new CmsSelectBox(sortList);
636            m_sortSelectBox.addValueChangeHandler(this);
637            m_sortSelectBox.addStyleName(DIALOG_CSS.selectboxWidth());
638            m_sortSelectBox.truncate(TM_GALLERY_SORT, 200);
639            m_options.add(m_sortSelectBox);
640            Label infoLabel = new Label();
641            infoLabel.setStyleName(DIALOG_CSS.infoLabel());
642            m_infoLabel = infoLabel;
643            m_options.insert(infoLabel, 0);
644        }
645        createQuickBox();
646
647    }
648
649    /**
650     * Sets the search query an selects the result tab.<p>
651     */
652    protected void quickSearch() {
653
654        if ((m_quickSearch != null) && CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_quickSearch.getFormValueAsString())) {
655            getTabHandler().setSearchQuery(m_quickSearch.getFormValueAsString());
656            getTabHandler().selectResultTab();
657        }
658    }
659
660    /**
661     * Schedules the quick filter action.<p>
662     */
663    protected void scheduleQuickFilterTimer() {
664
665        m_filterTimer.schedule(FILTER_DELAY);
666    }
667
668    /**
669     * Searches in the categories tree or list the item and returns it.<p>
670     *
671     * @param list the list of items to start from
672     * @param categoryPath the category id to search
673     * @return the category item widget
674     */
675    protected CmsTreeItem searchTreeItem(CmsList<? extends I_CmsListItem> list, String categoryPath) {
676
677        CmsTreeItem resultItem = (CmsTreeItem)list.getItem(categoryPath);
678        // item is not in this tree level
679        if (resultItem == null) {
680            // if list is not empty
681            for (int i = 0; i < list.getWidgetCount(); i++) {
682                CmsTreeItem listItem = (CmsTreeItem)list.getWidget(i);
683                if (listItem.getChildCount() == 0) {
684                    continue;
685                }
686                // continue search in children
687                resultItem = searchTreeItem(listItem.getChildren(), categoryPath);
688                // break the search if result item is found
689                if (resultItem != null) {
690                    break;
691                }
692            }
693        }
694        return resultItem;
695    }
696
697    /**
698     * Creates the quick search/finder box.<p>
699     */
700    private void createQuickBox() {
701
702        if (hasQuickSearch() || hasQuickFilter()) {
703            m_quickSearch = new CmsTextBox();
704            //   m_quickFilter.setVisible(hasQuickFilter());
705            m_quickSearch.addStyleName(DIALOG_CSS.quickFilterBox());
706            m_quickSearch.setTriggerChangeOnKeyPress(true);
707            String message = hasQuickFilter()
708            ? Messages.get().key(Messages.GUI_QUICK_FINDER_FILTER_0)
709            : Messages.get().key(Messages.GUI_QUICK_FINDER_SEARCH_0);
710            m_quickSearch.setGhostValue(message, true);
711            m_quickSearch.setGhostModeClear(true);
712            m_options.insert(m_quickSearch, 0);
713            m_searchButton = new CmsPushButton();
714            m_searchButton.setImageClass(hasQuickFilter() ? I_CmsButton.FILTER : I_CmsButton.SEARCH_SMALL);
715            m_searchButton.setButtonStyle(ButtonStyle.FONT_ICON, null);
716            m_searchButton.getElement().getStyle().setFloat(Style.Float.RIGHT);
717            m_searchButton.getElement().getStyle().setMarginTop(4, Unit.PX);
718            m_options.insert(m_searchButton, 0);
719            m_quickSearch.addValueChangeHandler(this);
720            if (hasQuickFilter()) {
721                m_filterTimer = new Timer() {
722
723                    @Override
724                    public void run() {
725
726                        getTabHandler().onSort(
727                            m_sortSelectBox.getFormValueAsString(),
728                            m_quickSearch.getFormValueAsString());
729                        onContentChange();
730                    }
731                };
732                m_searchButton.setTitle(message);
733            } else {
734                m_quickSearch.addKeyPressHandler(new KeyPressHandler() {
735
736                    public void onKeyPress(KeyPressEvent event) {
737
738                        if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
739                            quickSearch();
740                        }
741                    }
742                });
743                m_searchButton.addClickHandler(new ClickHandler() {
744
745                    public void onClick(ClickEvent arg0) {
746
747                        quickSearch();
748                    }
749                });
750                m_quickSearchRegistration = getTabHandler().addSearchChangeHandler(
751                    new ValueChangeHandler<CmsGallerySearchBean>() {
752
753                        public void onValueChange(ValueChangeEvent<CmsGallerySearchBean> event) {
754
755                            m_quickSearch.setFormValueAsString(event.getValue().getQuery());
756                        }
757                    });
758                m_searchButton.setTitle(Messages.get().key(Messages.GUI_TAB_SEARCH_SEARCH_EXISTING_0));
759            }
760        }
761    }
762
763    /**
764     * Removes the quick search/finder box.<p>
765     */
766    private void removeQuickBox() {
767
768        if (m_quickSearch != null) {
769            m_quickSearch.removeFromParent();
770            m_quickSearch = null;
771        }
772        if (m_searchButton != null) {
773            m_searchButton.removeFromParent();
774            m_searchButton = null;
775        }
776        if (m_quickSearchRegistration != null) {
777            m_quickSearchRegistration.removeHandler();
778            m_quickSearchRegistration = null;
779        }
780    }
781}