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