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    /** Panel to put additional widgets. */
278    @UiField
279    FlowPanel m_additionalWidgets;
280
281    /**
282     * The default constructor with drag handler.<p>
283     *
284     * @param tabId the tab id
285     */
286    public A_CmsListTab(GalleryTabId tabId) {
287
288        this(tabId.name());
289    }
290
291    /**
292     * Sets up a list tab with a given tab id.<p>
293     *
294     * @param tabId the tab id
295     */
296    public A_CmsListTab(String tabId) {
297
298        super(tabId);
299        uiBinder.createAndBindUi(this);
300        initWidget(uiBinder.createAndBindUi(this));
301        m_scrollList = createScrollList();
302        m_list.add(m_scrollList);
303    }
304
305    /**
306     * Returns the list.<p>
307     *
308     * @return the list
309     */
310    public CmsScrollPanel getList() {
311
312        return m_list;
313    }
314
315    /**
316     * @see org.opencms.ade.galleries.client.ui.A_CmsTab#getRequiredHeight()
317     */
318    @Override
319    public int getRequiredHeight() {
320
321        int list = m_scrollList.getOffsetHeight();
322        list = list > 82 ? list : 82;
323        return list + 47;
324    }
325
326    /**
327     * Call on content change to update the layout.<p>
328     */
329    public void onContentChange() {
330
331        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
332
333            public void execute() {
334
335                Widget parent = getParent();
336                while (parent != null) {
337                    if (parent instanceof CmsGalleryDialog) {
338                        ((CmsGalleryDialog)parent).updateSizes();
339                        parent = null;
340                    } else {
341                        parent = parent.getParent();
342                    }
343                }
344            }
345        });
346    }
347
348    /**
349     * @see org.opencms.ade.galleries.client.ui.A_CmsTab#onResize()
350     */
351    @Override
352    public void onResize() {
353
354        m_list.onResizeDescendant();
355    }
356
357    /**
358     * Will be triggered if the value in the select box changes.<p>
359     *
360     * @see com.google.gwt.event.logical.shared.ValueChangeHandler#onValueChange(com.google.gwt.event.logical.shared.ValueChangeEvent)
361     */
362    public void onValueChange(ValueChangeEvent<String> event) {
363
364        cancelQuickFilterTimer();
365        if (event.getSource() == m_sortSelectBox) {
366            // depending on the sort value the tab may or may not have the quick filter ability
367            if (hasQuickFilter()) {
368                if (m_quickSearch == null) {
369                    createQuickBox();
370                }
371            } else {
372                removeQuickBox();
373            }
374            getTabHandler().onSort(event.getValue(), hasQuickFilter() ? m_quickSearch.getFormValueAsString() : null);
375        }
376        if ((event.getSource() == m_quickSearch)) {
377            if (hasQuickFilter()) {
378
379                if ((CmsStringUtil.isEmptyOrWhitespaceOnly(event.getValue()) || (event.getValue().length() >= 3))) {
380                    // only act if filter length is at least 3 characters or empty
381                    if ((m_lastQuickSearchValue == null) || !m_lastQuickSearchValue.equals(event.getValue())) {
382                        scheduleQuickFilterTimer();
383                    }
384                    m_lastQuickSearchValue = event.getValue();
385                }
386            } else {
387                checkQuickSearchStatus();
388            }
389        }
390    }
391
392    /**
393     * Sets the value selected in the sort select box, if possible.<p>
394     *
395     * @param value the new value for the sort select box
396     * @param fireEvents if true, the change event of the select box is fired
397     */
398    public void setSortSelectBoxValue(String value, boolean fireEvents) {
399
400        if ((m_sortSelectBox != null) && (value != null)) {
401            m_sortSelectBox.setFormValue(value, fireEvents);
402        }
403    }
404
405    /**
406     * @see org.opencms.gwt.client.ui.I_CmsTruncable#truncate(java.lang.String, int)
407     */
408    public void truncate(String textMetricsKey, int clientWidth) {
409
410        m_scrollList.truncate(TM_LIST_TAB, clientWidth);
411    }
412
413    /**
414     * Adds a widget to the front of the list.<p>
415     *
416     * @param listItem the list item to add
417     */
418    protected void addWidgetToFrontOfList(Widget listItem) {
419
420        m_scrollList.insert(listItem, 0);
421    }
422
423    /**
424     * Add a list item widget to the list panel.<p>
425     *
426     * @param listItem the list item to add
427     */
428    protected void addWidgetToList(Widget listItem) {
429
430        m_scrollList.add(listItem);
431    }
432
433    /**
434     * Add a widget to the option panel.<p>
435     *
436     * The option panel should contain drop down boxes or other list options.
437     *
438     * @param widget the widget to add
439     */
440    protected void addWidgetToOptions(Widget widget) {
441
442        m_options.add(widget);
443    }
444
445    /**
446     * Cancels the quick filter timer.<p>
447     */
448    protected void cancelQuickFilterTimer() {
449
450        if (m_filterTimer != null) {
451            m_filterTimer.cancel();
452        }
453    }
454
455    /**
456     * Checks the quick search input and enables/disables the search button accordingly.<p>
457     */
458    protected void checkQuickSearchStatus() {
459
460        if ((m_quickSearch != null) && (m_searchButton != null)) {
461            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_quickSearch.getFormValueAsString())) {
462                m_searchButton.enable();
463            } else {
464                m_searchButton.disable("Enter a search query");
465            }
466        }
467    }
468
469    /**
470     * Clears the list panel.<p>
471     */
472    protected void clearList() {
473
474        m_scrollList.clearList();
475        onContentChange();
476    }
477
478    /**
479     * Generates a new custom upload button.<p>
480     *
481     * @param nativeMethod the name of the custom JS upload action
482     * @param target the upload target
483     *
484     * @return the button widget
485     */
486    protected CmsPushButton createCustomUploadButton(final String nativeMethod, final String target) {
487
488        CmsPushButton uploadButton = new CmsPushButton(I_CmsButton.UPLOAD_SMALL);
489        uploadButton.setText(null);
490        uploadButton.setTitle(Messages.get().key(Messages.GUI_GALLERY_UPLOAD_TITLE_1, target));
491        uploadButton.setButtonStyle(ButtonStyle.FONT_ICON, null);
492        uploadButton.addClickHandler(new ClickHandler() {
493
494            public void onClick(ClickEvent event) {
495
496                customUploadAction(nativeMethod, target); /** TODO: Callback */
497            }
498        });
499        return uploadButton;
500
501    }
502
503    /**
504     * Generates a button to create new external link resources.<p>
505     *
506     * @param parentPath the parent folder site path
507     *
508     * @return the button widget
509     */
510    protected CmsPushButton createNewExternalLinkButton(final String parentPath) {
511
512        final CmsResourceTypeBean typeInfo = getTabHandler().getTypeInfo(
513            CmsEditExternalLinkDialog.POINTER_RESOURCE_TYPE_NAME);
514        CmsPushButton createNewButton = null;
515        if (typeInfo != null) {
516            createNewButton = new CmsPushButton(I_CmsButton.ADD_SMALL);
517            createNewButton.setTitle(
518                org.opencms.gwt.client.Messages.get().key(
519                    org.opencms.gwt.client.Messages.GUI_CREATE_NEW_LINK_DIALOG_TITLE_0));
520            createNewButton.setButtonStyle(ButtonStyle.FONT_ICON, null);
521            createNewButton.addClickHandler(new ClickHandler() {
522
523                public void onClick(ClickEvent event) {
524
525                    CmsEditExternalLinkDialog dialog = CmsEditExternalLinkDialog.showNewLinkDialog(
526                        typeInfo,
527                        parentPath);
528                    dialog.addCloseHandler(new CloseHandler<PopupPanel>() {
529
530                        public void onClose(CloseEvent<PopupPanel> closeEvent) {
531
532                            getTabHandler().updateIndex();
533                        }
534                    });
535                }
536            });
537        }
538        return createNewButton;
539    }
540
541    /**
542     * Creates the 'optmize gallery' button.
543     *
544     * @param selectionHandler the selection handler
545     * @return the created button
546     */
547    protected CmsPushButton createOptimizeButton(A_SelectionHandler selectionHandler) {
548
549        CmsPushButton selectButton = new CmsPushButton();
550        selectButton.setImageClass(I_CmsButton.EDIT_SMALL);
551        selectButton.setTitle("Edit");
552        selectButton.setButtonStyle(ButtonStyle.FONT_ICON, null);
553        selectionHandler.setSelectButton(selectButton);
554        selectButton.addClickHandler(selectionHandler);
555        return selectButton;
556    }
557
558    /**
559     * Creates the list which should contain the list items of the tab.<p>
560     *
561     * @return the newly created list widget
562     */
563    protected CmsList<? extends I_CmsListItem> createScrollList() {
564
565        return new CmsList<I_CmsListItem>();
566    }
567
568    /**
569     * Creates a select button.<p>
570     *
571     * @param selectionHandler the selction handler
572     *
573     * @return the select button
574     */
575    protected CmsPushButton createSelectButton(A_SelectionHandler selectionHandler) {
576
577        CmsPushButton selectButton = new CmsPushButton();
578        selectButton.setImageClass(I_CmsButton.SEARCH_SMALL);
579        selectButton.setTitle(Messages.get().key(Messages.GUI_TAB_SEARCH_SEARCH_EXISTING_0));
580        selectButton.setButtonStyle(ButtonStyle.FONT_ICON, null);
581        selectionHandler.setSelectButton(selectButton);
582        selectButton.addClickHandler(selectionHandler);
583        return selectButton;
584    }
585
586    /**
587     * Creates a button widget to select the specified resource.<p>
588     *
589     * @param resourcePath the item resource path
590     * @param structureId the structure id
591     * @param title the resource title
592     * @param resourceType the item resource type
593     *
594     * @return the initialized select resource button
595     */
596    protected CmsPushButton createSelectResourceButton(
597        String resourcePath,
598        CmsUUID structureId,
599        String title,
600        String resourceType) {
601
602        CmsPushButton result = new CmsPushButton();
603        result.setImageClass(I_CmsButton.CHECK_SMALL);
604        result.setButtonStyle(ButtonStyle.FONT_ICON, null);
605        result.setTitle(Messages.get().key(Messages.GUI_PREVIEW_BUTTON_SELECT_0));
606        result.addClickHandler(new SelectHandler(resourcePath, structureId, title, resourceType));
607        return result;
608    }
609
610    /**
611     * Creates an upload button for the given target.<p>
612     *
613     * @param target the upload target folder
614     * @param isRootPath true if target is a root path
615     *
616     * @return the upload button
617     */
618    protected CmsUploadButton createUploadButtonForTarget(String target, boolean isRootPath) {
619
620        CmsDialogUploadButtonHandler buttonHandler = new CmsDialogUploadButtonHandler(
621
622            new Supplier<I_CmsUploadContext>() {
623
624                public I_CmsUploadContext get() {
625
626                    return new I_CmsUploadContext() {
627
628                        public void onUploadFinished(List<String> uploadedFiles) {
629
630                            getTabHandler().updateIndex();
631                        }
632
633                    };
634                }
635            });
636
637        buttonHandler.setTargetFolder(target);
638        buttonHandler.setIsTargetRootPath(isRootPath);
639        CmsUploadButton uploadButton = new CmsUploadButton(buttonHandler);
640        uploadButton.setText(null);
641        uploadButton.setTitle(Messages.get().key(Messages.GUI_GALLERY_UPLOAD_TITLE_1, target));
642        uploadButton.setButtonStyle(ButtonStyle.FONT_ICON, null);
643        uploadButton.setImageClass(I_CmsButton.UPLOAD_SMALL);
644        return uploadButton;
645    }
646
647    /**
648     * Returns a list with sort values for this tab.<p>
649     *
650     * @return list of sort order value/text pairs
651     */
652    protected abstract LinkedHashMap<String, String> getSortList();
653
654    /**
655     * Returns if this tab has quick filter enabled.<p>
656     *
657     * @return <code>true</code> if this tab has quick filter enabled
658     */
659    protected boolean hasQuickFilter() {
660
661        return false;
662    }
663
664    /**
665     * Returns if the tab has the quick search box.<p>
666     *
667     * @return <code>true</code> if the tab has the quick search box
668     */
669    protected boolean hasQuickSearch() {
670
671        return false;
672    }
673
674    /**
675     * Call after all handlers have been set.<p>
676     */
677    protected void init() {
678
679        LinkedHashMap<String, String> sortList = getSortList();
680        if (sortList != null) {
681            m_sortSelectBox = new CmsSelectBox(sortList);
682            m_sortSelectBox.addValueChangeHandler(this);
683            m_sortSelectBox.addStyleName(DIALOG_CSS.selectboxWidth());
684            m_sortSelectBox.truncate(TM_GALLERY_SORT, 200);
685            m_options.add(m_sortSelectBox);
686            Label infoLabel = new Label();
687            infoLabel.setStyleName(DIALOG_CSS.infoLabel());
688            m_infoLabel = infoLabel;
689            m_options.insert(infoLabel, 0);
690        }
691        createQuickBox();
692
693    }
694
695    /**
696     * Sets the search query an selects the result tab.<p>
697     */
698    protected void quickSearch() {
699
700        if ((m_quickSearch != null) && CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_quickSearch.getFormValueAsString())) {
701            getTabHandler().setSearchQuery(m_quickSearch.getFormValueAsString());
702            getTabHandler().selectResultTab();
703        }
704    }
705
706    /**
707     * Schedules the quick filter action.<p>
708     */
709    protected void scheduleQuickFilterTimer() {
710
711        m_filterTimer.schedule(FILTER_DELAY);
712    }
713
714    /**
715     * Searches in the categories tree or list the item and returns it.<p>
716     *
717     * @param list the list of items to start from
718     * @param categoryPath the category id to search
719     * @return the category item widget
720     */
721    protected CmsTreeItem searchTreeItem(CmsList<? extends I_CmsListItem> list, String categoryPath) {
722
723        CmsTreeItem resultItem = (CmsTreeItem)list.getItem(categoryPath);
724        // item is not in this tree level
725        if (resultItem == null) {
726            // if list is not empty
727            for (int i = 0; i < list.getWidgetCount(); i++) {
728                CmsTreeItem listItem = (CmsTreeItem)list.getWidget(i);
729                if (listItem.getChildCount() == 0) {
730                    continue;
731                }
732                // continue search in children
733                resultItem = searchTreeItem(listItem.getChildren(), categoryPath);
734                // break the search if result item is found
735                if (resultItem != null) {
736                    break;
737                }
738            }
739        }
740        return resultItem;
741    }
742
743    /**
744     * Runs the native custom uplod handler.
745     *
746     * @param nativeMethod the native method name
747     * @param target the upload target
748     */
749    native void customUploadAction(String nativeMethod, String target) /*-{
750
751        var uploadAction = $wnd[nativeMethod];
752        nativeMethod(target);
753
754    }-*/;
755
756    /**
757     * Creates the quick search/finder box.<p>
758     */
759    private void createQuickBox() {
760
761        if (hasQuickSearch() || hasQuickFilter()) {
762            m_quickSearch = new CmsTextBox();
763            //   m_quickFilter.setVisible(hasQuickFilter());
764            m_quickSearch.addStyleName(DIALOG_CSS.quickFilterBox());
765            m_quickSearch.setTriggerChangeOnKeyPress(true);
766            String message = hasQuickFilter()
767            ? Messages.get().key(Messages.GUI_QUICK_FINDER_FILTER_0)
768            : Messages.get().key(Messages.GUI_QUICK_FINDER_SEARCH_0);
769            m_quickSearch.setGhostValue(message, true);
770            m_quickSearch.setGhostModeClear(true);
771            m_options.insert(m_quickSearch, 0);
772            m_searchButton = new CmsPushButton();
773            m_searchButton.setImageClass(hasQuickFilter() ? I_CmsButton.FILTER : I_CmsButton.SEARCH_SMALL);
774            m_searchButton.setButtonStyle(ButtonStyle.FONT_ICON, null);
775            m_searchButton.getElement().getStyle().setFloat(Style.Float.RIGHT);
776            m_searchButton.getElement().getStyle().setMarginTop(4, Unit.PX);
777            m_options.insert(m_searchButton, 0);
778            m_quickSearch.addValueChangeHandler(this);
779            if (hasQuickFilter()) {
780                m_filterTimer = new Timer() {
781
782                    @Override
783                    public void run() {
784
785                        getTabHandler().onSort(
786                            m_sortSelectBox.getFormValueAsString(),
787                            m_quickSearch.getFormValueAsString());
788                        onContentChange();
789                    }
790                };
791                m_searchButton.setTitle(message);
792            } else {
793                m_quickSearch.addKeyPressHandler(new KeyPressHandler() {
794
795                    public void onKeyPress(KeyPressEvent event) {
796
797                        if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
798                            quickSearch();
799                        }
800                    }
801                });
802                m_searchButton.addClickHandler(new ClickHandler() {
803
804                    public void onClick(ClickEvent arg0) {
805
806                        quickSearch();
807                    }
808                });
809                m_quickSearchRegistration = getTabHandler().addSearchChangeHandler(
810                    new ValueChangeHandler<CmsGallerySearchBean>() {
811
812                        public void onValueChange(ValueChangeEvent<CmsGallerySearchBean> event) {
813
814                            m_quickSearch.setFormValueAsString(event.getValue().getQuery());
815                        }
816                    });
817                m_searchButton.setTitle(Messages.get().key(Messages.GUI_TAB_SEARCH_SEARCH_EXISTING_0));
818            }
819
820        }
821    }
822
823    /**
824     * Removes the quick search/finder box.<p>
825     */
826    private void removeQuickBox() {
827
828        if (m_quickSearch != null) {
829            m_quickSearch.removeFromParent();
830            m_quickSearch = null;
831        }
832        if (m_searchButton != null) {
833            m_searchButton.removeFromParent();
834            m_searchButton = null;
835        }
836        if (m_quickSearchRegistration != null) {
837            m_quickSearchRegistration.removeHandler();
838            m_quickSearchRegistration = null;
839        }
840    }
841}