001/* 002 003 * This library is part of OpenCms - 004 * the Open Source Content Management System 005 * 006 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 007 * 008 * This library is free software; you can redistribute it and/or 009 * modify it under the terms of the GNU Lesser General Public 010 * License as published by the Free Software Foundation; either 011 * version 2.1 of the License, or (at your option) any later version. 012 * 013 * This library is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 016 * Lesser General Public License for more details. 017 * 018 * For further information about Alkacon Software, please see the 019 * company website: http://www.alkacon.com 020 * 021 * For further information about OpenCms, please see the 022 * project website: http://www.opencms.org 023 * 024 * You should have received a copy of the GNU Lesser General Public 025 * License along with this library; if not, write to the Free Software 026 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 027 */ 028 029package org.opencms.ade.galleries.client.ui; 030 031import org.opencms.ade.galleries.client.CmsVfsTabHandler; 032import org.opencms.ade.galleries.client.Messages; 033import org.opencms.ade.galleries.shared.CmsGallerySearchBean; 034import org.opencms.ade.galleries.shared.CmsVfsEntryBean; 035import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants; 036import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants.GalleryTabId; 037import org.opencms.file.CmsResource; 038import org.opencms.gwt.client.CmsCoreProvider; 039import org.opencms.gwt.client.ui.CmsList; 040import org.opencms.gwt.client.ui.I_CmsListItem; 041import org.opencms.gwt.client.ui.input.A_CmsSelectBox; 042import org.opencms.gwt.client.ui.input.CmsCheckBox; 043import org.opencms.gwt.client.ui.input.CmsFilterSelectBox; 044import org.opencms.gwt.client.ui.input.category.CmsDataValue; 045import org.opencms.gwt.client.ui.tree.A_CmsLazyOpenHandler; 046import org.opencms.gwt.client.ui.tree.CmsLazyTree; 047import org.opencms.gwt.client.ui.tree.CmsLazyTreeItem; 048import org.opencms.util.CmsStringUtil; 049import org.opencms.util.CmsUUID; 050 051import java.util.ArrayList; 052import java.util.Collection; 053import java.util.Collections; 054import java.util.HashMap; 055import java.util.HashSet; 056import java.util.LinkedHashMap; 057import java.util.List; 058import java.util.Map; 059import java.util.Set; 060 061import com.google.gwt.event.dom.client.ClickEvent; 062import com.google.gwt.event.logical.shared.CloseEvent; 063import com.google.gwt.event.logical.shared.CloseHandler; 064import com.google.gwt.event.logical.shared.OpenEvent; 065import com.google.gwt.event.logical.shared.OpenHandler; 066import com.google.gwt.user.client.rpc.AsyncCallback; 067 068/** 069 * The tab widget for selecting folders from the VFS tree.<p> 070 * 071 * @since 8.0.0 072 */ 073public class CmsVfsTab extends A_CmsListTab { 074 075 /** 076 * Handles the change of the item selection.<p> 077 */ 078 private class SelectionHandler extends A_SelectionHandler { 079 080 /** The category path as id for the selected category. */ 081 private CmsVfsEntryBean m_vfsEntry; 082 083 /** 084 * Constructor.<p> 085 * 086 * @param vfsEntry the vfs entry represented by the list item 087 * @param checkBox the reference to the checkbox 088 */ 089 public SelectionHandler(CmsVfsEntryBean vfsEntry, CmsCheckBox checkBox) { 090 091 super(checkBox); 092 m_vfsEntry = vfsEntry; 093 m_selectionHandlers.add(this); 094 } 095 096 /** 097 * @see org.opencms.ade.galleries.client.ui.A_CmsListTab.A_SelectionHandler#onClick(com.google.gwt.event.dom.client.ClickEvent) 098 */ 099 @Override 100 public void onClick(ClickEvent event) { 101 102 if (isIncludeFiles()) { 103 super.onClick(event); 104 } else if (getTabHandler().hasSelectResource()) { 105 String selectPath = m_tabHandler.getSelectPath(m_vfsEntry); 106 getTabHandler().selectResource( 107 selectPath, 108 m_vfsEntry.getStructureId(), 109 m_vfsEntry.getDisplayName(), 110 I_CmsGalleryProviderConstants.RESOURCE_TYPE_FOLDER); 111 } 112 } 113 114 /** 115 * @see org.opencms.ade.galleries.client.ui.A_CmsListTab.A_SelectionHandler#onSelectionChange() 116 */ 117 @Override 118 protected void onSelectionChange() { 119 120 if (isIncludeFiles()) { 121 getTabHandler().onSelectFolder(m_vfsEntry.getRootPath(), getCheckBox().isChecked()); 122 } 123 } 124 125 /** 126 * @see org.opencms.ade.galleries.client.ui.A_CmsListTab.A_SelectionHandler#selectBeforeGoingToResultTab() 127 */ 128 @Override 129 protected void selectBeforeGoingToResultTab() { 130 131 for (SelectionHandler otherHandler : m_selectionHandlers) { 132 if ((otherHandler != this) 133 && (otherHandler.getCheckBox() != null) 134 && otherHandler.getCheckBox().isChecked()) { 135 otherHandler.getCheckBox().setChecked(false); 136 otherHandler.onSelectionChange(); 137 } 138 } 139 getCheckBox().setChecked(true); 140 onSelectionChange(); 141 } 142 } 143 144 /** The tab handler. */ 145 protected CmsVfsTabHandler m_tabHandler; 146 147 /** The selection handlers for the current tab. */ 148 List<SelectionHandler> m_selectionHandlers = new ArrayList<SelectionHandler>(); 149 150 /** Flag indicating files are included. */ 151 private boolean m_includeFiles; 152 153 /** Flag which indicates whether the tab has been initialized. */ 154 private boolean m_initialized; 155 156 /** A map of tree items indexed by VFS path. */ 157 private Map<String, CmsLazyTreeItem> m_itemsByPath = new HashMap<String, CmsLazyTreeItem>(); 158 159 /** The list of tree items. */ 160 private List<CmsLazyTreeItem> m_treeItems = new ArrayList<CmsLazyTreeItem>(); 161 162 /** 163 * Constructor.<p> 164 * 165 * @param tabHandler the tab handler 166 * @param includeFiles the include files flag 167 */ 168 public CmsVfsTab(CmsVfsTabHandler tabHandler, boolean includeFiles) { 169 170 super(GalleryTabId.cms_tab_vfstree); 171 m_tabHandler = tabHandler; 172 m_includeFiles = includeFiles; 173 init(); 174 } 175 176 /** 177 * Checks the check boxes for the selected folders.<p> 178 * 179 * @param folders the folders for which to check the check boxes 180 */ 181 public void checkFolders(Set<String> folders) { 182 183 if (folders != null) { 184 for (String folder : folders) { 185 CmsLazyTreeItem item = m_itemsByPath.get(folder); 186 if ((item != null) && (item.getCheckBox() != null)) { 187 item.getCheckBox().setChecked(true); 188 } 189 } 190 } 191 192 } 193 194 /** 195 * Sets the initial folders in the VFS tab.<p> 196 * 197 * @param entries the root folders to display 198 */ 199 public void fillInitially(List<CmsVfsEntryBean> entries) { 200 201 fillInitially(entries, null); 202 } 203 204 /** 205 * Sets the initial folders in the VFS tab.<p> 206 * 207 * @param entries the root folders to display 208 * @param selectedSiteRoot site root that should be selected in the select box 209 */ 210 public void fillInitially(List<CmsVfsEntryBean> entries, String selectedSiteRoot) { 211 212 clear(); 213 for (CmsVfsEntryBean entry : entries) { 214 if (entry != null) { 215 CmsLazyTreeItem item = createItem(entry); 216 addWidgetToList(item); 217 } 218 } 219 if (null != selectedSiteRoot) { 220 selectSite(selectedSiteRoot); 221 } 222 m_initialized = true; 223 } 224 225 /** 226 * @see org.opencms.ade.galleries.client.ui.A_CmsTab#getParamPanels(org.opencms.ade.galleries.shared.CmsGallerySearchBean) 227 */ 228 @Override 229 public List<CmsSearchParamPanel> getParamPanels(CmsGallerySearchBean searchObj) { 230 231 List<CmsSearchParamPanel> result = new ArrayList<CmsSearchParamPanel>(); 232 for (String folder : searchObj.getFolders()) { 233 CmsSearchParamPanel panel = new CmsSearchParamPanel( 234 Messages.get().key(Messages.GUI_PARAMS_LABEL_FOLDERS_0), 235 this); 236 panel.setContent(folder, folder); 237 result.add(panel); 238 } 239 return result; 240 } 241 242 /** 243 * Checks if the tab is initialized.<p> 244 * 245 * @return true if the tab is initialized 246 */ 247 public boolean isInitialized() { 248 249 return m_initialized; 250 } 251 252 /** 253 * This method is called when the VFS tree preload data is received.<p> 254 * 255 * @param vfsPreloadData the VFS tree preload data 256 */ 257 public void onReceiveVfsPreloadData(CmsVfsEntryBean vfsPreloadData) { 258 259 String siteRoot = vfsPreloadData.getSiteRoot(); 260 fillInitially(Collections.singletonList(vfsPreloadData), siteRoot); 261 } 262 263 /** 264 * Un-checks the check boxes for each folder passed in the <code>folders</code> parameter.<p> 265 * 266 * @param folders the folders for which the check boxes should be unchecked 267 */ 268 public void uncheckFolders(Collection<String> folders) { 269 270 for (String folder : folders) { 271 CmsLazyTreeItem item = m_itemsByPath.get(folder); 272 if ((item != null) && (item.getCheckBox() != null)) { 273 item.getCheckBox().setChecked(false); 274 } 275 } 276 } 277 278 /** 279 * Clears the contents of the tab and resets the mapping from tree items to VFS beans.<p> 280 */ 281 protected void clear() { 282 283 clearList(); 284 m_selectionHandlers.clear(); 285 m_treeItems.clear(); 286 } 287 288 /** 289 * Helper method for creating a VFS tree item widget from a VFS entry bean.<p> 290 * 291 * @param vfsEntry the VFS entry bean 292 * 293 * @return the tree item widget 294 */ 295 protected CmsLazyTreeItem createItem(final CmsVfsEntryBean vfsEntry) { 296 297 String name = null; 298 String rootPath = vfsEntry.getRootPath(); 299 if (rootPath.equals("/") || rootPath.equals("")) { 300 name = "/"; 301 } else { 302 name = CmsResource.getName(vfsEntry.getRootPath()); 303 304 if (name.endsWith("/")) { 305 name = name.substring(0, name.length() - 1); 306 } 307 } 308 CmsDataValue dataValue = new CmsDataValue( 309 600, 310 3, 311 vfsEntry.getSmallIconClasses(), 312 name, 313 vfsEntry.getDisplayName()); 314 if (vfsEntry.isSearchMatch()) { 315 dataValue.setSearchMatch(true); 316 } 317 dataValue.setUnselectable(); 318 if (vfsEntry.isEditable()) { 319 if (!CmsCoreProvider.get().isUploadDisabled()) { 320 if (CmsCoreProvider.get().getUploadRestriction().isUploadEnabled(vfsEntry.getRootPath())) { 321 dataValue.addButton(createUploadButtonForTarget(vfsEntry.getRootPath(), true)); 322 } 323 } 324 } 325 CmsLazyTreeItem result; 326 SelectionHandler selectionHandler; 327 CmsCheckBox checkbox = null; 328 if (isIncludeFiles()) { 329 checkbox = new CmsCheckBox(); 330 result = new CmsLazyTreeItem(checkbox, dataValue, true); 331 selectionHandler = new SelectionHandler(vfsEntry, checkbox); 332 checkbox.addClickHandler(selectionHandler); 333 dataValue.addClickHandler(selectionHandler); 334 dataValue.addButton(createSelectButton(selectionHandler)); 335 } else { 336 result = new CmsLazyTreeItem(dataValue, true); 337 selectionHandler = new SelectionHandler(vfsEntry, null); 338 } 339 // we need this in a final variable to access it in the click handler 340 if (getTabHandler().hasSelectResource()) { 341 String selectPath = m_tabHandler.getSelectPath(vfsEntry); 342 dataValue.addButton( 343 createSelectResourceButton( 344 selectPath, 345 vfsEntry.getStructureId(), 346 vfsEntry.getDisplayName(), 347 I_CmsGalleryProviderConstants.RESOURCE_TYPE_FOLDER)); 348 } 349 result.setData(vfsEntry); 350 m_itemsByPath.put(vfsEntry.getRootPath(), result); 351 result.setLeafStyle(false); 352 result.setSmallView(true); 353 m_treeItems.add(result); 354 if (vfsEntry.getChildren() != null) { 355 for (CmsVfsEntryBean child : vfsEntry.getChildren()) { 356 result.addChild(createItem(child)); 357 } 358 result.onFinishLoading(); 359 result.setOpen(true, false); 360 if (vfsEntry.getChildren().isEmpty()) { 361 result.setLeafStyle(true); 362 } 363 } 364 365 return result; 366 } 367 368 /** 369 * @see org.opencms.ade.galleries.client.ui.A_CmsListTab#createScrollList() 370 */ 371 @Override 372 protected CmsList<? extends I_CmsListItem> createScrollList() { 373 374 CmsLazyTree<CmsLazyTreeItem> tree = new CmsLazyTree<CmsLazyTreeItem>( 375 new A_CmsLazyOpenHandler<CmsLazyTreeItem>() { 376 377 /** 378 * @see org.opencms.gwt.client.ui.tree.I_CmsLazyOpenHandler#load(org.opencms.gwt.client.ui.tree.CmsLazyTreeItem, java.lang.Runnable) 379 */ 380 public void load(final CmsLazyTreeItem target, final Runnable loadCallback) { 381 382 CmsVfsEntryBean entry = target.getData(); 383 String path = entry.getRootPath(); 384 AsyncCallback<List<CmsVfsEntryBean>> callback = new AsyncCallback<List<CmsVfsEntryBean>>() { 385 386 /** 387 * @see com.google.gwt.user.client.rpc.AsyncCallback#onFailure(java.lang.Throwable) 388 */ 389 public void onFailure(Throwable caught) { 390 391 // should never be called 392 393 } 394 395 /** 396 * @see com.google.gwt.user.client.rpc.AsyncCallback#onSuccess(java.lang.Object) 397 */ 398 public void onSuccess(List<CmsVfsEntryBean> result) { 399 400 for (CmsVfsEntryBean childEntry : result) { 401 CmsLazyTreeItem item = createItem(childEntry); 402 target.addChild(item); 403 } 404 target.onFinishLoading(); 405 loadCallback.run(); 406 } 407 }; 408 409 m_tabHandler.getSubFolders(path, callback); 410 411 } 412 413 @Override 414 public void onFinishOpen(CmsLazyTreeItem target) { 415 416 onContentChange(); 417 } 418 419 }); 420 tree.addOpenHandler(new OpenHandler<CmsLazyTreeItem>() { 421 422 public void onOpen(OpenEvent<CmsLazyTreeItem> event) { 423 424 Set<CmsUUID> ids = getOpenElementIds(); 425 CmsVfsEntryBean entry = event.getTarget().getData(); 426 ids.add(entry.getStructureId()); 427 getTabHandler().onChangeTreeState(ids); 428 onContentChange(); 429 } 430 431 }); 432 tree.addCloseHandler(new CloseHandler<CmsLazyTreeItem>() { 433 434 public void onClose(CloseEvent<CmsLazyTreeItem> event) { 435 436 Set<CmsUUID> ids = getOpenElementIds(); 437 CmsVfsEntryBean entry = event.getTarget().getData(); 438 ids.remove(entry.getStructureId()); 439 getTabHandler().onChangeTreeState(ids); 440 } 441 442 }); 443 return tree; 444 } 445 446 /** 447 * @see org.opencms.ade.galleries.client.ui.A_CmsListTab#createSelectBox(java.util.LinkedHashMap) 448 */ 449 @Override 450 protected A_CmsSelectBox<?> createSelectBox(LinkedHashMap<String, String> options) { 451 452 CmsFilterSelectBox box = new CmsFilterSelectBox(options); 453 return box; 454 } 455 456 /** 457 * @see org.opencms.ade.galleries.client.ui.A_CmsListTab#getSortList() 458 */ 459 @Override 460 protected LinkedHashMap<String, String> getSortList() { 461 462 return m_tabHandler.getSortList(); 463 } 464 465 /** 466 * @see org.opencms.ade.galleries.client.ui.A_CmsTab#getTabHandler() 467 */ 468 @Override 469 protected CmsVfsTabHandler getTabHandler() { 470 471 return m_tabHandler; 472 } 473 474 /** 475 * @see org.opencms.ade.galleries.client.ui.A_CmsListTab#hasQuickFilter() 476 */ 477 @Override 478 protected boolean hasQuickFilter() { 479 480 return true; 481 } 482 483 /** 484 * Returns if files are included.<p> 485 * 486 * @return <code>true</code> if files are included 487 */ 488 protected boolean isIncludeFiles() { 489 490 return m_includeFiles; 491 } 492 493 /** 494 * Collects the structure ids belonging to open tree entries.<p> 495 * 496 * @return the structure ids for the open tree entries 497 */ 498 Set<CmsUUID> getOpenElementIds() { 499 500 Set<CmsUUID> ids = new HashSet<CmsUUID>(); 501 for (CmsLazyTreeItem item : m_treeItems) { 502 CmsVfsEntryBean entry = item.getData(); 503 if (item.isOpen()) { 504 ids.add(entry.getStructureId()); 505 } 506 } 507 return ids; 508 } 509 510 /** 511 * Selects a specific site.<p> 512 * 513 * @param siteRoot the site root 514 */ 515 private void selectSite(String siteRoot) { 516 517 if (m_sortSelectBox == null) { 518 return; 519 } 520 Map<String, String> options = ((CmsFilterSelectBox)m_sortSelectBox).getItems(); 521 String option = null; 522 for (Map.Entry<String, String> entry : options.entrySet()) { 523 if (CmsStringUtil.comparePaths(entry.getKey(), siteRoot)) { 524 option = entry.getKey(); 525 break; 526 } 527 } 528 if (option != null) { 529 m_sortSelectBox.setFormValue(option, false); 530 } 531 } 532 533}