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}