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.ui.components; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsResource; 032import org.opencms.file.CmsResourceFilter; 033import org.opencms.main.CmsException; 034import org.opencms.main.CmsLog; 035import org.opencms.main.OpenCms; 036import org.opencms.site.CmsSite; 037import org.opencms.ui.A_CmsDialogContext; 038import org.opencms.ui.A_CmsUI; 039import org.opencms.ui.CmsVaadinUtils; 040import org.opencms.ui.FontOpenCms; 041import org.opencms.ui.I_CmsDialogContext; 042import org.opencms.ui.apps.CmsAppWorkplaceUi; 043import org.opencms.ui.apps.CmsDefaultAppButtonProvider; 044import org.opencms.ui.apps.CmsFileExplorer; 045import org.opencms.ui.apps.I_CmsAppUIContext; 046import org.opencms.ui.apps.I_CmsWorkplaceAppConfiguration; 047import org.opencms.ui.apps.Messages; 048import org.opencms.ui.components.CmsBasicDialog.DialogWidth; 049import org.opencms.ui.components.CmsUploadButton.I_UploadListener; 050import org.opencms.ui.contextmenu.CmsContextMenuTreeBuilder; 051import org.opencms.ui.contextmenu.I_CmsContextMenuItem; 052import org.opencms.ui.favorites.CmsExplorerFavoriteContext; 053import org.opencms.ui.favorites.CmsFavoriteDAO; 054import org.opencms.ui.favorites.CmsFavoriteDialog; 055import org.opencms.util.CmsStringUtil; 056import org.opencms.util.CmsTreeNode; 057import org.opencms.util.CmsUUID; 058import org.opencms.workplace.CmsWorkplace; 059 060import java.util.Collections; 061import java.util.List; 062import java.util.Locale; 063 064import org.apache.commons.logging.Log; 065 066import com.google.common.collect.Lists; 067import com.vaadin.server.ExternalResource; 068import com.vaadin.server.FontIcon; 069import com.vaadin.server.Page; 070import com.vaadin.server.Page.BrowserWindowResizeEvent; 071import com.vaadin.server.Page.BrowserWindowResizeListener; 072import com.vaadin.server.Resource; 073import com.vaadin.shared.ui.ContentMode; 074import com.vaadin.ui.AbstractOrderedLayout; 075import com.vaadin.ui.Alignment; 076import com.vaadin.ui.Button; 077import com.vaadin.ui.Component; 078import com.vaadin.ui.CssLayout; 079import com.vaadin.ui.HorizontalLayout; 080import com.vaadin.ui.Label; 081import com.vaadin.ui.MenuBar; 082import com.vaadin.ui.MenuBar.Command; 083import com.vaadin.ui.MenuBar.MenuItem; 084import com.vaadin.ui.PopupView; 085import com.vaadin.ui.UI; 086import com.vaadin.ui.VerticalLayout; 087import com.vaadin.ui.Window; 088import com.vaadin.ui.declarative.Design; 089import com.vaadin.ui.themes.ValoTheme; 090 091/** 092 * The workplace toolbar.<p> 093 */ 094public class CmsToolBar extends CssLayout implements BrowserWindowResizeListener { 095 096 /** Toolbar dialog context. */ 097 protected class ToolbarContext extends A_CmsDialogContext { 098 099 /** 100 * Constructor.<p> 101 * 102 * @param appId the app id 103 */ 104 protected ToolbarContext(String appId) { 105 106 super(appId, ContextType.appToolbar, Collections.<CmsResource> emptyList()); 107 } 108 109 /** 110 * @see org.opencms.ui.I_CmsDialogContext#focus(org.opencms.util.CmsUUID) 111 */ 112 public void focus(CmsUUID structureId) { 113 114 // nothing to do 115 } 116 117 /** 118 * @see org.opencms.ui.I_CmsDialogContext#getAllStructureIdsInView() 119 */ 120 public List<CmsUUID> getAllStructureIdsInView() { 121 122 return Lists.newArrayList(); 123 } 124 125 /** 126 * @see org.opencms.ui.I_CmsDialogContext#updateUserInfo() 127 */ 128 public void updateUserInfo() { 129 130 refreshUserInfoDropDown(); 131 } 132 } 133 134 /** Logger instance for this class. */ 135 private static final Log LOG = CmsLog.getLog(CmsToolBar.class); 136 137 /** The serial version id. */ 138 private static final long serialVersionUID = -4551194983054069395L; 139 140 /** The app UI context. */ 141 protected I_CmsAppUIContext m_appContext; 142 143 /** The app indicator. */ 144 private Label m_appIndicator; 145 146 /** Flag indicating the toolbar buttons are folded into a sub menu. */ 147 private boolean m_buttonsFolded; 148 149 /** The context menu component. */ 150 private MenuBar m_contextMenu; 151 152 /** The dialog context. */ 153 private I_CmsDialogContext m_dialogContext; 154 155 /** The favorite button. */ 156 private Button m_favButton; 157 158 /** The sub menu displaying the folded buttons. */ 159 private PopupView m_foldedButtonsMenu; 160 161 /** The browser window width that is required to display all toolbar buttons. */ 162 private int m_foldingThreshhold; 163 164 /** Toolbar items left. */ 165 private HorizontalLayout m_itemsLeft; 166 167 /** Toolbar items right. */ 168 private HorizontalLayout m_itemsRight; 169 170 /** The contains the buttons from the left side, displayed in the folded buttons sub menu. */ 171 private VerticalLayout m_leftButtons; 172 173 /** The quick launch drop down. */ 174 private Component m_quickLaunchDropDown; 175 176 /** The contains the buttons from the right side, displayed in the folded buttons sub menu. */ 177 private VerticalLayout m_rightButtons; 178 179 /** The user drop down. */ 180 private Component m_userDropDown; 181 182 /** 183 * Constructor.<p> 184 */ 185 public CmsToolBar() { 186 187 m_quickLaunchDropDown = createQuickLaunchDropDown(); 188 m_userDropDown = createUserInfoDropDown(); 189 m_favButton = CmsToolBar.createButton( 190 FontOpenCms.BOOKMARKS, 191 CmsVaadinUtils.getMessageText(org.opencms.ui.Messages.GUI_FAVORITES_BUTTON_0), 192 true); 193 m_leftButtons = new VerticalLayout(); 194 m_rightButtons = new VerticalLayout(); 195 VerticalLayout layout = new VerticalLayout(); 196 layout.addComponent(m_leftButtons); 197 layout.addComponent(m_rightButtons); 198 m_foldedButtonsMenu = new PopupView(getDropDownButtonHtml(FontOpenCms.CONTEXT_MENU_DOTS), layout); 199 m_foldedButtonsMenu.addStyleName(OpenCmsTheme.NAVIGATOR_DROPDOWN); 200 m_foldedButtonsMenu.setHideOnMouseOut(false); 201 Design.read("CmsToolBar.html", this); 202 203 m_favButton.addClickListener(evt -> { 204 CmsFileExplorer explorer = (CmsFileExplorer)m_appContext.getAttribute(CmsFileExplorer.ATTR_KEY); 205 openFavoriteDialog(explorer); 206 }); 207 } 208 209 /** 210 * Creates a properly styled toolbar button.<p> 211 * 212 * @param icon the button icon 213 * @param title the button title, will be used for the tooltip 214 * 215 * @return the button 216 */ 217 public static Button createButton(Resource icon, String title) { 218 219 return createButton(icon, title, false); 220 } 221 222 /** 223 * Creates a properly styled toolbar button.<p> 224 * 225 * @param icon the button icon 226 * @param title the button title, will be used for the tooltip 227 * @param alwaysShow <code>true</code> to prevent the button to be folded into a sub menu for small screens 228 * 229 * @return the button 230 */ 231 public static Button createButton(Resource icon, String title, boolean alwaysShow) { 232 233 Button button = new Button(icon); 234 button.setDescription(title); 235 button.addStyleName(ValoTheme.BUTTON_BORDERLESS); 236 button.addStyleName(OpenCmsTheme.TOOLBAR_BUTTON); 237 if (alwaysShow) { 238 button.addStyleName(OpenCmsTheme.REQUIRED_BUTTON); 239 } 240 return button; 241 } 242 243 /** 244 * Creates a drop down menu.<p> 245 * 246 * @param icon the button icon 247 * @param content the drop down content 248 * @param title the button title 249 * 250 * @return the component 251 */ 252 public static Component createDropDown(ExternalResource icon, Component content, String title) { 253 254 return createDropDown(getDropDownButtonHtml(icon), content, title); 255 } 256 257 /** 258 * Creates a drop down menu.<p> 259 * 260 * @param icon the button icon 261 * @param content the drop down content 262 * @param title the drop down title 263 * 264 * @return the component 265 */ 266 public static Component createDropDown(FontIcon icon, Component content, String title) { 267 268 return createDropDown(getDropDownButtonHtml(icon), content, title); 269 } 270 271 /** 272 * Creates a drop down menu.<p> 273 * 274 * @param buttonHtml the button HTML 275 * @param content the drop down content 276 * @param title the button title 277 * 278 * @return the component 279 */ 280 public static Component createDropDown(String buttonHtml, Component content, String title) { 281 282 PopupView pv = new PopupView(buttonHtml, content); 283 pv.setDescription(title); 284 pv.addStyleName(OpenCmsTheme.NAVIGATOR_DROPDOWN); 285 pv.setHideOnMouseOut(false); 286 return pv; 287 } 288 289 /** 290 * Opens the favorite dialog. 291 * 292 * @param explorer the explorer instance (null if not currently in explorer) 293 */ 294 public static void openFavoriteDialog(CmsFileExplorer explorer) { 295 296 try { 297 CmsExplorerFavoriteContext context = new CmsExplorerFavoriteContext(A_CmsUI.getCmsObject(), explorer); 298 CmsFavoriteDialog dialog = new CmsFavoriteDialog(context, new CmsFavoriteDAO(A_CmsUI.getCmsObject())); 299 Window window = CmsBasicDialog.prepareWindow(DialogWidth.max); 300 window.setContent(dialog); 301 window.setCaption(CmsVaadinUtils.getMessageText(org.opencms.ui.Messages.GUI_FAVORITES_DIALOG_TITLE_0)); 302 A_CmsUI.get().addWindow(window); 303 window.center(); 304 } catch (CmsException e) { 305 CmsErrorDialog.showErrorDialog(e); 306 } 307 } 308 309 /** 310 * Creates the button HTML for the given icon resource.<p> 311 * 312 * @param icon the icon 313 * 314 * @return the HTML 315 */ 316 static String getDropDownButtonHtml(ExternalResource icon) { 317 318 return "<div tabindex=\"0\" role=\"button\" class=\"v-button v-widget borderless v-button-borderless " 319 + OpenCmsTheme.TOOLBAR_BUTTON 320 + " v-button-" 321 + OpenCmsTheme.TOOLBAR_BUTTON 322 + "\"><span class=\"v-button-wrap\"><img width=\"32\" height=\"32\" class=\"v-icon\" src=\"" 323 + icon.getURL() 324 + "\" /></span></div>"; 325 } 326 327 /** 328 * Creates the button HTML for the given icon resource.<p> 329 * 330 * @param icon the icon 331 * 332 * @return the HTML 333 */ 334 static String getDropDownButtonHtml(FontIcon icon) { 335 336 return "<div tabindex=\"0\" role=\"button\" class=\"v-button v-widget borderless v-button-borderless " 337 + OpenCmsTheme.TOOLBAR_BUTTON 338 + " v-button-" 339 + OpenCmsTheme.TOOLBAR_BUTTON 340 + "\"><span class=\"v-button-wrap\">" 341 + icon.getHtml() 342 + "</span></div>"; 343 } 344 345 /** 346 * Adds a button to left toolbar side.<p> 347 * 348 * @param button the button 349 */ 350 public void addButtonLeft(Component button) { 351 352 if (m_buttonsFolded && !isAlwaysShow(button)) { 353 m_leftButtons.addComponent(button); 354 } else { 355 m_itemsLeft.addComponent(button); 356 } 357 updateFoldingThreshhold(); 358 } 359 360 /** 361 * Adds a button to right toolbar side.<p> 362 * 363 * @param button the button 364 */ 365 public void addButtonRight(Component button) { 366 367 if (m_buttonsFolded && !isAlwaysShow(button)) { 368 m_rightButtons.addComponent(button); 369 } else { 370 int dropDownIndex = m_itemsRight.getComponentIndex(m_userDropDown); 371 if (dropDownIndex >= 0) { 372 m_itemsRight.addComponent(button, dropDownIndex); 373 } else { 374 m_itemsRight.addComponent(button); 375 } 376 } 377 updateFoldingThreshhold(); 378 } 379 380 /** 381 * @see com.vaadin.server.Page.BrowserWindowResizeListener#browserWindowResized(com.vaadin.server.Page.BrowserWindowResizeEvent) 382 */ 383 public void browserWindowResized(BrowserWindowResizeEvent event) { 384 385 updateButtonVisibility(event.getWidth()); 386 } 387 388 /** 389 * Clears the left toolbar buttons.<p> 390 */ 391 public void clearButtonsLeft() { 392 393 m_itemsLeft.removeAllComponents(); 394 m_leftButtons.removeAllComponents(); 395 // in case the app title is set, make sure to keep the label in the button bar 396 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_appIndicator.getValue())) { 397 m_itemsLeft.addComponent(m_appIndicator); 398 } 399 updateFoldingThreshhold(); 400 } 401 402 /** 403 * Clears the right toolbar buttons.<p> 404 */ 405 public void clearButtonsRight() { 406 407 m_itemsRight.removeAllComponents(); 408 m_rightButtons.removeAllComponents(); 409 updateFoldingThreshhold(); 410 } 411 412 /** 413 * Closes all visible popup views.<p> 414 */ 415 public void closePopupViews() { 416 417 closePopupViews(m_itemsLeft); 418 closePopupViews(m_itemsRight); 419 } 420 421 /** 422 * Enables or removes the default toolbar buttons.<p> 423 * These are the context menu and the quick launch drop down.<p> 424 * The default is <code>enabled = true</code>.<p> 425 * 426 * @param enabled <code>true</code> to enable the buttons 427 */ 428 public void enableDefaultButtons(boolean enabled) { 429 430 if (enabled) { 431 m_itemsRight.addComponent(m_contextMenu, 0); 432 m_itemsRight.addComponent(m_favButton, 1); 433 m_itemsRight.addComponent(m_quickLaunchDropDown, 2); 434 } else { 435 m_itemsRight.removeComponent(m_contextMenu); 436 m_itemsRight.removeComponent(m_favButton); 437 m_itemsRight.removeComponent(m_quickLaunchDropDown); 438 } 439 updateFoldingThreshhold(); 440 } 441 442 /** 443 * Refreshes the user drop down.<p> 444 */ 445 public void refreshUserInfoDropDown() { 446 447 Component oldVersion = m_userDropDown; 448 m_userDropDown = createUserInfoDropDown(); 449 m_itemsRight.replaceComponent(oldVersion, m_userDropDown); 450 } 451 452 /** 453 * Removes the given button from the toolbar.<p> 454 * 455 * @param button the button to remove 456 */ 457 public void removeButton(Component button) { 458 459 m_itemsLeft.removeComponent(button); 460 m_itemsRight.removeComponent(button); 461 m_leftButtons.removeComponent(button); 462 m_rightButtons.removeComponent(button); 463 updateFoldingThreshhold(); 464 } 465 466 /** 467 * Sets the app context. 468 * 469 * @param context the app context 470 */ 471 public void setAppContext(I_CmsAppUIContext context) { 472 473 m_appContext = context; 474 } 475 476 /** 477 * Sets the app title.<p> 478 * 479 * @param appTitle the app title 480 */ 481 public void setAppTitle(String appTitle) { 482 483 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(appTitle)) { 484 m_appIndicator.setValue(appTitle); 485 updateAppIndicator(); 486 m_appIndicator.setVisible(true); 487 } else { 488 m_appIndicator.setVisible(false); 489 } 490 } 491 492 /** 493 * Updates the app indicator site and project info.<p> 494 */ 495 public void updateAppIndicator() { 496 497 if (CmsAppWorkplaceUi.isOnlineProject()) { 498 m_appIndicator.addStyleName(OpenCmsTheme.TOOLABER_APP_INDICATOR_ONLINE); 499 500 } else { 501 m_appIndicator.removeStyleName(OpenCmsTheme.TOOLABER_APP_INDICATOR_ONLINE); 502 } 503 CmsObject cms = A_CmsUI.getCmsObject(); 504 String siteRoot = cms.getRequestContext().getSiteRoot(); 505 CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(siteRoot); 506 String siteName = null; 507 if (site != null) { 508 siteName = site.getTitle(); 509 } else { 510 try { 511 CmsResource folder = cms.readResource("/", CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 512 513 siteName = OpenCms.getSiteManager().getSiteTitle(cms, folder); 514 } catch (CmsException e) { 515 LOG.warn("Error reading site title.", e); 516 } 517 } 518 if (CmsStringUtil.isEmptyOrWhitespaceOnly(siteName)) { 519 siteName = siteRoot; 520 } else { 521 siteName = CmsWorkplace.substituteSiteTitleStatic(siteName, UI.getCurrent().getLocale()); 522 } 523 m_appIndicator.setDescription( 524 CmsVaadinUtils.getMessageText( 525 Messages.GUI_TOOLBAR_PROJECT_SITE_INFO_2, 526 A_CmsUI.getCmsObject().getRequestContext().getCurrentProject().getName(), 527 siteName), 528 ContentMode.HTML); 529 } 530 531 /** 532 * Initializes the toolbar.<p> 533 * 534 * @param appId the app id 535 * @param context the app UI context 536 */ 537 protected void init(String appId, I_CmsAppUIContext context) { 538 539 m_dialogContext = new ToolbarContext(appId); 540 m_appContext = context; 541 initContextMenu(); 542 m_itemsRight.addComponent(m_quickLaunchDropDown); 543 m_itemsRight.addComponent(m_userDropDown); 544 enableDefaultButtons(true); 545 } 546 547 /** 548 * Sets the dialog context.<p> 549 * 550 * @param context the dialog context 551 */ 552 protected void setDialogContext(I_CmsDialogContext context) { 553 554 m_dialogContext = context; 555 556 // reinit context menu 557 initContextMenu(); 558 } 559 560 /** 561 * Updates the button visibility according o the given widow width.<p> 562 * 563 * @param width the window width 564 */ 565 protected void updateButtonVisibility(int width) { 566 567 if (!m_buttonsFolded && (m_foldingThreshhold > width)) { 568 foldButtons(); 569 } else if (m_buttonsFolded && (width > m_foldingThreshhold)) { 570 unfoldButtons(); 571 } 572 } 573 574 /** 575 * Recalculates the space required by the toolbar buttons.<p> 576 */ 577 protected void updateFoldingThreshhold() { 578 579 int left = estimateRequiredWidth(m_itemsLeft) + estimateRequiredWidth(m_leftButtons); 580 int right = estimateRequiredWidth(m_itemsRight) + estimateRequiredWidth(m_rightButtons); 581 int requiredWidth = left > right ? left : right; 582 if (requiredWidth < 350) { 583 // folding not required at any width 584 m_foldingThreshhold = 0; 585 } else if (requiredWidth < 400) { 586 m_foldingThreshhold = 984; 587 } else if (requiredWidth <= 520) { 588 m_foldingThreshhold = 1240; 589 } else { 590 // always fold 591 m_foldingThreshhold = 10000; 592 } 593 updateButtonVisibility(Page.getCurrent().getBrowserWindowWidth()); 594 } 595 596 /** 597 * Returns the dialog context.<p> 598 * 599 * @return the dialog context 600 */ 601 I_CmsDialogContext getDialogContext() { 602 603 return m_dialogContext; 604 } 605 606 /** 607 * Handles the user image file upload.<p> 608 * 609 * @param uploadedFiles the uploaded file names 610 */ 611 void handleUpload(List<String> uploadedFiles) { 612 613 CmsObject cms = A_CmsUI.getCmsObject(); 614 boolean success = OpenCms.getWorkplaceAppManager().getUserIconHelper().handleImageUpload(cms, uploadedFiles); 615 if (success) { 616 refreshUserInfoDropDown(); 617 } 618 } 619 620 /** 621 * Closes the visible popup view children of the given layout.<p> 622 * 623 * @param layout the layout 624 */ 625 private void closePopupViews(AbstractOrderedLayout layout) { 626 627 for (Component item : layout) { 628 if (item instanceof PopupView) { 629 ((PopupView)item).setPopupVisible(false); 630 } 631 } 632 } 633 634 /** 635 * Creates the context menu entry and it's children.<p> 636 * 637 * @param parent the entry parent 638 * @param node the item tree node 639 * @param treeBuilder the tree builder 640 */ 641 private void createMenuEntry( 642 MenuItem parent, 643 final CmsTreeNode<I_CmsContextMenuItem> node, 644 CmsContextMenuTreeBuilder treeBuilder) { 645 646 Command entryCommand = null; 647 if (node.getChildren().size() == 0) { 648 entryCommand = new Command() { 649 650 private static final long serialVersionUID = 1L; 651 652 public void menuSelected(MenuItem selectedItem) { 653 654 node.getData().executeAction(getDialogContext()); 655 } 656 }; 657 } 658 MenuItem entry = parent.addItem((node.getData().getTitle(A_CmsUI.get().getLocale())), entryCommand); 659 for (CmsTreeNode<I_CmsContextMenuItem> child : node.getChildren()) { 660 createMenuEntry(entry, child, treeBuilder); 661 } 662 if (treeBuilder.getVisibility(node.getData()).isInActive()) { 663 entry.setEnabled(false); 664 } 665 } 666 667 /** 668 * Creates the app select drop down.<p> 669 * 670 * @return the drop down component 671 */ 672 private Component createQuickLaunchDropDown() { 673 674 PopupView pv = new PopupView(new PopupView.Content() { 675 676 private static final long serialVersionUID = 1L; 677 678 public String getMinimizedValueAsHTML() { 679 680 return getDropDownButtonHtml(FontOpenCms.APPS); 681 } 682 683 public Component getPopupComponent() { 684 685 CmsObject cms = A_CmsUI.getCmsObject(); 686 Locale locale = UI.getCurrent().getLocale(); 687 HorizontalLayout layout = new HorizontalLayout(); 688 layout.addStyleName(ValoTheme.LAYOUT_HORIZONTAL_WRAPPING); 689 layout.addStyleName(OpenCmsTheme.QUICK_LAUNCH); 690 layout.setSpacing(false); 691 layout.setMargin(true); 692 for (I_CmsWorkplaceAppConfiguration config : OpenCms.getWorkplaceAppManager().getQuickLaunchConfigurations( 693 cms)) { 694 layout.addComponent(CmsDefaultAppButtonProvider.createAppButton(cms, config, locale)); 695 } 696 return layout; 697 } 698 }); 699 pv.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_QUICK_LAUNCH_TITLE_0)); 700 pv.addStyleName(OpenCmsTheme.NAVIGATOR_DROPDOWN); 701 pv.setHideOnMouseOut(false); 702 703 return pv; 704 705 } 706 707 /** 708 * Creates the user info drop down.<p> 709 * 710 * @return the drop down component 711 */ 712 private Component createUserInfoDropDown() { 713 714 PopupView pv = new PopupView(new PopupView.Content() { 715 716 private static final long serialVersionUID = 1L; 717 718 public String getMinimizedValueAsHTML() { 719 720 CmsObject cms = A_CmsUI.getCmsObject(); 721 return getDropDownButtonHtml( 722 new ExternalResource( 723 OpenCms.getWorkplaceAppManager().getUserIconHelper().getSmallIconPath( 724 cms, 725 cms.getRequestContext().getCurrentUser()))); 726 } 727 728 public Component getPopupComponent() { 729 730 return new CmsUserInfo(new I_UploadListener() { 731 732 public void onUploadFinished(List<String> uploadedFiles) { 733 734 handleUpload(uploadedFiles); 735 } 736 }, getDialogContext()); 737 } 738 }); 739 pv.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_USER_INFO_TITLE_0)); 740 pv.addStyleName(OpenCmsTheme.NAVIGATOR_DROPDOWN); 741 pv.setHideOnMouseOut(false); 742 pv.addStyleName(OpenCmsTheme.USER_INFO); 743 return pv; 744 } 745 746 /** 747 * Calculates the width required by the layout components.<p> 748 * 749 * @param items the layout 750 * 751 * @return the width 752 */ 753 private int estimateRequiredWidth(AbstractOrderedLayout items) { 754 755 int result = 0; 756 if (items != null) { 757 for (Component comp : items) { 758 if (comp == m_foldedButtonsMenu) { 759 continue; 760 } else if ((comp instanceof Button) || (comp instanceof PopupView) || (comp instanceof MenuBar)) { 761 // assume all buttons have a with of 50px 762 result += 50; 763 } else if (comp == m_appIndicator) { 764 // assume app indicator requires 150px 765 result += 50; 766 } else { 767 float compWidth = comp.getWidth(); 768 if ((compWidth > 0) && (comp.getWidthUnits() == Unit.PIXELS)) { 769 // also add 10px margin 770 result += compWidth + 10; 771 } else { 772 result += 200; 773 } 774 } 775 } 776 } 777 return result; 778 } 779 780 /** 781 * Folds the toolbar buttons into a sub menu.<p> 782 */ 783 private void foldButtons() { 784 785 VerticalLayout mainPV = (VerticalLayout)m_foldedButtonsMenu.getContent().getPopupComponent(); 786 for (int i = m_itemsLeft.getComponentCount() - 1; i > -1; i--) { 787 Component comp = m_itemsLeft.getComponent(i); 788 if (!isAlwaysShow(comp)) { 789 m_itemsLeft.removeComponent(comp); 790 m_leftButtons.addComponent(comp, 0); 791 m_leftButtons.setComponentAlignment(comp, Alignment.MIDDLE_CENTER); 792 } 793 } 794 if (m_leftButtons.getComponentCount() == 0) { 795 mainPV.removeComponent(m_leftButtons); 796 } else { 797 mainPV.addComponent(m_leftButtons, 0); 798 } 799 for (int i = m_itemsRight.getComponentCount() - 1; i > -1; i--) { 800 Component comp = m_itemsRight.getComponent(i); 801 if (!isAlwaysShow(comp)) { 802 m_itemsRight.removeComponent(comp); 803 m_rightButtons.addComponent(comp, 0); 804 m_rightButtons.setComponentAlignment(comp, Alignment.MIDDLE_CENTER); 805 } 806 } 807 if (m_rightButtons.getComponentCount() == 0) { 808 mainPV.removeComponent(m_rightButtons); 809 } else { 810 mainPV.addComponent(m_rightButtons); 811 } 812 m_itemsRight.addComponent(m_foldedButtonsMenu, 0); 813 m_buttonsFolded = true; 814 markAsDirtyRecursive(); 815 } 816 817 /** 818 * Initializes the context menu entries.<p> 819 */ 820 private void initContextMenu() { 821 822 m_contextMenu.removeItems(); 823 MenuItem main = m_contextMenu.addItem("", null); 824 main.setIcon(FontOpenCms.CONTEXT_MENU); 825 main.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_MENU_TITLE_0)); 826 CmsContextMenuTreeBuilder treeBuilder = new CmsContextMenuTreeBuilder(getDialogContext()); 827 CmsTreeNode<I_CmsContextMenuItem> tree = treeBuilder.buildAll( 828 OpenCms.getWorkplaceAppManager().getMenuItemProvider().getMenuItems()); 829 for (CmsTreeNode<I_CmsContextMenuItem> node : tree.getChildren()) { 830 createMenuEntry(main, node, treeBuilder); 831 } 832 } 833 834 /** 835 * Checks whether the given component may be placed into the buttons sub menu.<p> 836 * 837 * @param comp the component to check 838 * 839 * @return <code>true</code> in case the component should always be displayed in the toolbar 840 */ 841 private boolean isAlwaysShow(Component comp) { 842 843 return ((comp == m_appIndicator) 844 || (comp == m_contextMenu) 845 || (comp == m_userDropDown) 846 || (comp == m_quickLaunchDropDown) 847 || comp.getStyleName().contains(OpenCmsTheme.REQUIRED_BUTTON)); 848 } 849 850 /** 851 * Places the buttons formerly moved to the sub menu back into the toolbar.<p> 852 */ 853 private void unfoldButtons() { 854 855 m_itemsRight.removeComponent(m_foldedButtonsMenu); 856 while (m_leftButtons.getComponentCount() > 0) { 857 Component comp = m_leftButtons.getComponent(0); 858 if (!isAlwaysShow(comp)) { 859 m_leftButtons.removeComponent(comp); 860 m_itemsLeft.addComponent(comp); 861 } 862 } 863 int index = 0; 864 while (m_rightButtons.getComponentCount() > 0) { 865 Component comp = m_rightButtons.getComponent(0); 866 m_rightButtons.removeComponent(comp); 867 m_itemsRight.addComponent(comp, index); 868 index++; 869 } 870 m_buttonsFolded = false; 871 markAsDirtyRecursive(); 872 } 873}