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.upload.client.ui; 029 030import org.opencms.ade.upload.client.I_CmsUploadContext; 031import org.opencms.ade.upload.client.Messages; 032import org.opencms.ade.upload.client.ui.css.I_CmsLayoutBundle; 033import org.opencms.ade.upload.client.ui.css.I_CmsLayoutBundle.I_CmsUploadCss; 034import org.opencms.gwt.client.CmsCoreProvider; 035import org.opencms.gwt.client.rpc.CmsRpcAction; 036import org.opencms.gwt.client.ui.CmsErrorDialog; 037import org.opencms.gwt.client.ui.CmsList; 038import org.opencms.gwt.client.ui.CmsListItem; 039import org.opencms.gwt.client.ui.CmsListItemWidget; 040import org.opencms.gwt.client.ui.CmsListItemWidget.Background; 041import org.opencms.gwt.client.ui.CmsLoadingAnimation; 042import org.opencms.gwt.client.ui.CmsNotification; 043import org.opencms.gwt.client.ui.CmsNotification.Type; 044import org.opencms.gwt.client.ui.CmsPopup; 045import org.opencms.gwt.client.ui.CmsPushButton; 046import org.opencms.gwt.client.ui.CmsScrollPanel; 047import org.opencms.gwt.client.ui.CmsToggleButton; 048import org.opencms.gwt.client.ui.FontOpenCms; 049import org.opencms.gwt.client.ui.I_CmsButton; 050import org.opencms.gwt.client.ui.I_CmsListItem; 051import org.opencms.gwt.client.ui.css.I_CmsConstantsBundle; 052import org.opencms.gwt.client.ui.input.CmsCheckBox; 053import org.opencms.gwt.client.ui.input.upload.CmsFileInfo; 054import org.opencms.gwt.client.ui.input.upload.CmsFileInput; 055import org.opencms.gwt.client.ui.input.upload.CmsUploadButton; 056import org.opencms.gwt.client.ui.input.upload.CmsUploadProgressInfo; 057import org.opencms.gwt.client.ui.input.upload.CmsUploader; 058import org.opencms.gwt.client.ui.input.upload.I_CmsUploadButton; 059import org.opencms.gwt.client.ui.input.upload.I_CmsUploadDialog; 060import org.opencms.gwt.client.util.CmsChangeHeightAnimation; 061import org.opencms.gwt.client.util.CmsDomUtil; 062import org.opencms.gwt.shared.CmsListInfoBean; 063import org.opencms.gwt.shared.CmsUploadFileBean; 064import org.opencms.gwt.shared.CmsUploadProgessInfo; 065import org.opencms.gwt.shared.CmsUploadRestrictionInfo; 066import org.opencms.gwt.shared.I_CmsUploadConstants; 067import org.opencms.gwt.shared.rpc.I_CmsUploadService; 068import org.opencms.gwt.shared.rpc.I_CmsUploadServiceAsync; 069import org.opencms.util.CmsStringUtil; 070 071import java.util.ArrayList; 072import java.util.Arrays; 073import java.util.Collections; 074import java.util.HashMap; 075import java.util.HashSet; 076import java.util.List; 077import java.util.Map; 078import java.util.Set; 079 080import com.google.common.base.Supplier; 081import com.google.gwt.core.client.GWT; 082import com.google.gwt.core.client.Scheduler; 083import com.google.gwt.core.client.Scheduler.ScheduledCommand; 084import com.google.gwt.dom.client.Style.Display; 085import com.google.gwt.dom.client.Style.Unit; 086import com.google.gwt.event.dom.client.ClickEvent; 087import com.google.gwt.event.dom.client.ClickHandler; 088import com.google.gwt.event.logical.shared.CloseEvent; 089import com.google.gwt.event.logical.shared.CloseHandler; 090import com.google.gwt.event.shared.HandlerRegistration; 091import com.google.gwt.json.client.JSONArray; 092import com.google.gwt.json.client.JSONObject; 093import com.google.gwt.json.client.JSONParser; 094import com.google.gwt.json.client.JSONString; 095import com.google.gwt.json.client.JSONValue; 096import com.google.gwt.user.client.Command; 097import com.google.gwt.user.client.Timer; 098import com.google.gwt.user.client.rpc.ServiceDefTarget; 099import com.google.gwt.user.client.ui.FlowPanel; 100import com.google.gwt.user.client.ui.FormPanel; 101import com.google.gwt.user.client.ui.HTML; 102import com.google.gwt.user.client.ui.PopupPanel; 103import com.google.gwt.user.client.ui.UIObject; 104import com.google.gwt.user.client.ui.Widget; 105 106/** 107 * Provides an upload dialog.<p> 108 * 109 * @since 8.0.0 110 */ 111public abstract class A_CmsUploadDialog extends CmsPopup implements I_CmsUploadDialog { 112 113 /** The minimal height of the content wrapper. */ 114 private static final int MIN_CONTENT_HEIGHT = 110; 115 116 /** Text metrics key. */ 117 private static final String TM_FILE_UPLOAD_LIST = "FileUploadList"; 118 119 /** The interval for updating the progress information in milliseconds. */ 120 private static final int UPDATE_PROGRESS_INTERVALL = 1000; 121 122 /** The upload context. */ 123 protected I_CmsUploadContext m_context; 124 125 /** The drag and drop message. */ 126 protected HTML m_dragAndDropMessage; 127 128 /** The scroll panel. */ 129 protected CmsScrollPanel m_scrollPanel; 130 131 /** The uploaded file names. */ 132 protected List<String> m_uploadedFiles; 133 134 /** Signals that the upload dialog was canceled. */ 135 boolean m_canceled; 136 137 /** True if the target folder is given as a root path. */ 138 boolean m_isTargetRootPath; 139 140 /** Stores all files that were added. */ 141 private Map<String, CmsFileInfo> m_allFiles; 142 143 /** Signals that the client currently loading. */ 144 private boolean m_clientLoading; 145 146 /** The close handler. */ 147 private CloseHandler<PopupPanel> m_closeHandler; 148 149 /** The sum of all file sizes. */ 150 private long m_contentLength; 151 152 /** A flow panel with a dynamic height. */ 153 private FlowPanel m_contentWrapper; 154 155 /** The user information text widget. */ 156 private HTML m_dialogInfo; 157 158 /** The list of file item widgets. */ 159 private CmsList<I_CmsListItem> m_fileList; 160 161 /** The list of filenames that should be unziped on the server. */ 162 private List<String> m_filesToUnzip; 163 164 /** The Map of files to upload. */ 165 private Map<String, CmsFileInfo> m_filesToUpload; 166 167 /** Stores the content height of the selection dialog. */ 168 private int m_firstContentHeight; 169 170 /** Stores the height of the user information text widget of the selection dialog. */ 171 private int m_firstInfoHeight; 172 173 /** Stores the height of the summary. */ 174 private int m_firstSummaryHeight; 175 176 /** A local reference to the default gwt CSS. */ 177 private org.opencms.gwt.client.ui.css.I_CmsLayoutBundle m_gwtCss = org.opencms.gwt.client.ui.css.I_CmsLayoutBundle.INSTANCE; 178 179 /** The close handler registration. */ 180 private HandlerRegistration m_handlerReg; 181 182 /** Stores the list items of all added files. */ 183 private Map<String, CmsListItem> m_listItems; 184 185 /** A panel for showing client loading. */ 186 private FlowPanel m_loadingPanel; 187 188 /** A timer to delay the loading animation. */ 189 private Timer m_loadingTimer; 190 191 /** The main panel. */ 192 private FlowPanel m_mainPanel; 193 194 /** The OK button. */ 195 private CmsPushButton m_okButton; 196 197 /** The post-create handler. */ 198 private String m_postCreateHandler; 199 200 /** The progress bar for the upload process. */ 201 private CmsUploadProgressInfo m_progressInfo; 202 203 /** The names of restricted upload files. */ 204 private Set<String> m_restricted = new HashSet<>(); 205 206 /** Signals whether the selection is done or not. */ 207 private boolean m_selectionDone; 208 209 /** The user information text widget. */ 210 private HTML m_selectionSummary; 211 212 /** The target folder to upload the selected files. */ 213 private String m_targetFolder; 214 215 /** The timer for updating the progress. */ 216 private Timer m_updateProgressTimer = new Timer() { 217 218 /** 219 * @see com.google.gwt.user.client.Timer#run() 220 */ 221 @Override 222 public void run() { 223 224 updateProgress(); 225 } 226 }; 227 228 /** The upload button of this dialog. */ 229 private I_CmsUploadButton m_uploadButton; 230 231 /** The upload service instance. */ 232 private I_CmsUploadServiceAsync m_uploadService; 233 234 /** 235 * Default constructor.<p> 236 */ 237 public A_CmsUploadDialog() { 238 239 super(Messages.get().key(Messages.GUI_UPLOAD_DIALOG_TITLE_1)); 240 241 I_CmsLayoutBundle.INSTANCE.uploadCss().ensureInjected(); 242 setModal(true); 243 setGlassEnabled(true); 244 catchNotifications(); 245 setWidth(CmsPopup.DEFAULT_WIDTH); 246 247 // create a map that stores all files (upload, existing, invalid) 248 m_allFiles = new HashMap<String, CmsFileInfo>(); 249 // create a map the holds all the list items for the selection dialog 250 m_listItems = new HashMap<String, CmsListItem>(); 251 m_filesToUnzip = new ArrayList<String>(); 252 m_fileList = new CmsList<I_CmsListItem>(); 253 m_fileList.truncate(TM_FILE_UPLOAD_LIST, CmsPopup.DEFAULT_WIDTH - 50); 254 255 // initialize a map that stores all the files that should be uploaded 256 m_filesToUpload = new HashMap<String, CmsFileInfo>(); 257 258 // create the main panel 259 m_mainPanel = new FlowPanel(); 260 261 // add the user info to the main panel 262 m_dialogInfo = new HTML(); 263 m_dialogInfo.addStyleName(I_CmsLayoutBundle.INSTANCE.uploadCss().dialogInfo()); 264 m_mainPanel.add(m_dialogInfo); 265 m_scrollPanel = GWT.create(CmsScrollPanel.class); 266 m_scrollPanel.getElement().getStyle().setPropertyPx("minHeight", MIN_CONTENT_HEIGHT); 267 m_scrollPanel.addStyleName(I_CmsLayoutBundle.INSTANCE.uploadCss().mainContentWidget()); 268 m_scrollPanel.addStyleName(m_gwtCss.generalCss().cornerAll()); 269 m_mainPanel.add(m_scrollPanel); 270 // add the content wrapper 271 m_contentWrapper = new FlowPanel(); 272 m_contentWrapper.add(m_fileList); 273 m_scrollPanel.add(m_contentWrapper); 274 275 m_selectionSummary = new HTML(); 276 m_selectionSummary.addStyleName(I_CmsLayoutBundle.INSTANCE.uploadCss().summary()); 277 m_mainPanel.add(m_selectionSummary); 278 279 // set the main panel as content of the popup 280 setMainContent(m_mainPanel); 281 282 addCloseHandler(new CloseHandler<PopupPanel>() { 283 284 /** 285 * @see com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt.event.logical.shared.CloseEvent) 286 */ 287 public void onClose(CloseEvent<PopupPanel> e) { 288 289 if (m_context != null) { 290 m_context.onUploadFinished(m_uploadedFiles); 291 } 292 } 293 }); 294 295 // create and add the "OK", "Cancel" and upload button 296 createButtons(); 297 } 298 299 /** 300 * @see org.opencms.gwt.client.ui.CmsPopup#addCloseHandler(com.google.gwt.event.logical.shared.CloseHandler) 301 */ 302 @Override 303 public HandlerRegistration addCloseHandler(CloseHandler<PopupPanel> handler) { 304 305 m_closeHandler = handler; 306 m_handlerReg = super.addCloseHandler(handler); 307 return m_handlerReg; 308 } 309 310 /** 311 * Creates a bean that can be used for the list item widget.<p> 312 * 313 * @param file the info to create the bean for 314 * 315 * @return a list info bean 316 */ 317 public abstract CmsListInfoBean createInfoBean(CmsFileInfo file); 318 319 /** 320 * Returns the massage for too large files.<p> 321 * 322 * @param file the file 323 * 324 * @return the message 325 */ 326 public abstract String getFileSizeTooLargeMessage(CmsFileInfo file); 327 328 /** 329 * Returns <code>true</code> if the file is too large, <code>false</code> otherwise.<p> 330 * 331 * @param cmsFileInfo the file to check 332 * 333 * @return <code>true</code> if the file is too large, <code>false</code> otherwise 334 */ 335 public abstract boolean isTooLarge(CmsFileInfo cmsFileInfo); 336 337 /** 338 * Loads and shows this dialog.<p> 339 */ 340 public void loadAndShow() { 341 342 // enable or disable the OK button 343 if (getFilesToUpload().isEmpty()) { 344 disableOKButton(Messages.get().key(Messages.GUI_UPLOAD_NOTIFICATION_NO_FILES_0)); 345 setDragAndDropMessage(); 346 } else { 347 enableOKButton(); 348 removeDragAndDropMessage(); 349 } 350 m_uploadedFiles = null; 351 // set the user info 352 displayDialogInfo(Messages.get().key(Messages.GUI_UPLOAD_INFO_SELECTION_0), false); 353 // set the selection summary 354 updateSummary(); 355 356 // add a upload button 357 m_uploadButton.createFileInput(); 358 359 // show the popup 360 if (!isShowing()) { 361 Scheduler.get().scheduleDeferred(new ScheduledCommand() { 362 363 /** 364 * @see com.google.gwt.core.client.Scheduler.ScheduledCommand#execute() 365 */ 366 public void execute() { 367 368 setContentWrapperHeight(); 369 center(); 370 } 371 }); 372 } 373 center(); 374 } 375 376 /** 377 * Parses the upload response of the server and decides what to do.<p> 378 * 379 * @param results a JSON Object 380 */ 381 public void parseResponse(String results) { 382 383 cancelUpdateProgress(); 384 stopLoadingAnimation(); 385 386 if ((!m_canceled) && CmsStringUtil.isNotEmptyOrWhitespaceOnly(results)) { 387 JSONObject jsonObject = JSONParser.parseStrict(results).isObject(); 388 boolean success = jsonObject.get(I_CmsUploadConstants.KEY_SUCCESS).isBoolean().booleanValue(); 389 // If the upload is done so fast that we did not receive any progress information, then 390 // the content length is unknown. For that reason take the request size to show how 391 // much bytes were uploaded. 392 double size = jsonObject.get(I_CmsUploadConstants.KEY_REQUEST_SIZE).isNumber().doubleValue(); 393 long requestSize = Double.valueOf(size).longValue(); 394 if (m_contentLength == 0) { 395 m_contentLength = requestSize; 396 } 397 if (success) { 398 m_uploadedFiles = new ArrayList<String>(); 399 List<String> uploadedFileIds = new ArrayList<String>(); 400 displayDialogInfo( 401 org.opencms.gwt.client.Messages.get().key( 402 org.opencms.gwt.client.Messages.GUI_UPLOAD_INFO_FINISHING_0), 403 false); 404 JSONValue uploadedFilesVal = jsonObject.get(I_CmsUploadConstants.KEY_UPLOADED_FILE_NAMES); 405 JSONValue uploadHook = jsonObject.get(I_CmsUploadConstants.KEY_UPLOAD_HOOK); 406 String hookUri = null; 407 if ((uploadHook != null) && (uploadHook.isString() != null)) { 408 hookUri = uploadHook.isString().stringValue(); 409 JSONValue uploadedFileIdsVal = jsonObject.get(I_CmsUploadConstants.KEY_UPLOADED_FILES); 410 JSONArray uploadedFileIdsArray = uploadedFileIdsVal.isArray(); 411 if (uploadedFileIdsArray != null) { 412 for (int i = 0; i < uploadedFileIdsArray.size(); i++) { 413 JSONString entry = uploadedFileIdsArray.get(i).isString(); 414 if (entry != null) { 415 uploadedFileIds.add(entry.stringValue()); 416 } 417 } 418 } 419 } 420 JSONArray uploadedFilesArray = uploadedFilesVal.isArray(); 421 if (uploadedFilesArray != null) { 422 for (int i = 0; i < uploadedFilesArray.size(); i++) { 423 JSONString entry = uploadedFilesArray.get(i).isString(); 424 if (entry != null) { 425 m_uploadedFiles.add(entry.stringValue()); 426 } 427 } 428 } 429 m_progressInfo.finish(); 430 final I_CmsUploadContext context = m_context; 431 closeOnSuccess(); 432 if (hookUri != null) { 433 // Set the context to be null so that it isn't called when the upload dialog closed; 434 // we want it to be called when the upload property dialog is closed instead.<p> 435 m_context = null; 436 CloseHandler<PopupPanel> closeHandler; 437 closeHandler = new CloseHandler<PopupPanel>() { 438 439 public void onClose(CloseEvent<PopupPanel> event) { 440 441 if (context != null) { 442 context.onUploadFinished(m_uploadedFiles); 443 } 444 } 445 }; 446 447 String title = Messages.get().key(Messages.GUI_UPLOAD_HOOK_DIALOG_TITLE_0); 448 CmsUploadHookDialog.openDialog(title, hookUri, uploadedFileIds, closeHandler); 449 } 450 } else { 451 String message = jsonObject.get(I_CmsUploadConstants.KEY_MESSAGE).isString().stringValue(); 452 String stacktrace = jsonObject.get(I_CmsUploadConstants.KEY_STACKTRACE).isString().stringValue(); 453 showErrorReport(message, stacktrace); 454 } 455 } 456 } 457 458 /** 459 * Sets the upload context.<p> 460 * 461 * @param context the new upload context 462 */ 463 public void setContext(I_CmsUploadContext context) { 464 465 m_context = context; 466 } 467 468 /** 469 * Sets the boolean flag to control whether the target folder is interpreted as a root path.<p> 470 * 471 * @param isTargetRootPath true if the target folder should be treated as a root path 472 */ 473 public void setIsTargetRootPath(boolean isTargetRootPath) { 474 475 m_isTargetRootPath = isTargetRootPath; 476 } 477 478 /** 479 * Sets the post-create handler. 480 * 481 * @param postCreateHandler the post-create handler 482 */ 483 public void setPostCreateHandler(String postCreateHandler) { 484 485 m_postCreateHandler = postCreateHandler; 486 } 487 488 /** 489 * Sets the target folder.<p> 490 * 491 * @param target the target folder to set 492 */ 493 public void setTargetFolder(String target) { 494 495 m_targetFolder = target; 496 setCaption(Messages.get().key(Messages.GUI_UPLOAD_DIALOG_TITLE_1, m_targetFolder)); 497 } 498 499 /** 500 * Shows the error report.<p> 501 * 502 * @param message the message to show 503 * @param stacktrace the stacktrace to show 504 */ 505 public void showErrorReport(final String message, final String stacktrace) { 506 507 if (!m_canceled) { 508 CmsErrorDialog errDialog = new CmsErrorDialog(message, stacktrace); 509 if (m_handlerReg != null) { 510 m_handlerReg.removeHandler(); 511 } 512 if (m_closeHandler != null) { 513 errDialog.addCloseHandler(m_closeHandler); 514 } 515 hide(); 516 errDialog.center(); 517 } 518 } 519 520 /** 521 * Executes the submit action.<p> 522 */ 523 public void submit() { 524 525 // create a JsArray containing the files to upload 526 List<CmsFileInfo> filesToUpload = new ArrayList<CmsFileInfo>(getFilesToUpload().values()); 527 Collections.sort(filesToUpload, CmsFileInfo.INFO_COMPARATOR); 528 529 CmsUploader uploader = new CmsUploader(); 530 uploader.uploadFiles( 531 getUploadUri(), 532 getTargetFolder(), 533 m_isTargetRootPath, 534 getPostCreateHandler(), 535 filesToUpload, 536 getFilesToUnzip(false), 537 false, 538 this); 539 } 540 541 /** 542 * Updates the button handler. 543 */ 544 public void updateHandler() { 545 546 CmsDialogUploadButtonHandler handler = new CmsDialogUploadButtonHandler( 547 () -> m_context, 548 m_targetFolder, 549 m_isTargetRootPath); 550 handler.setUploadDialog(this); 551 m_uploadButton.reinitButton(handler); 552 } 553 554 /** 555 * Updates the file summary.<p> 556 */ 557 public abstract void updateSummary(); 558 559 /** 560 * Adds the given file input field to this dialog.<p> 561 * 562 * @param fileInput the file input field to add 563 */ 564 protected void addFileInput(CmsFileInput fileInput) { 565 566 // add the files selected by the user to the list of files to upload 567 if (fileInput != null) { 568 addFiles(Arrays.asList(fileInput.getFiles())); 569 } else { 570 loadAndShow(); 571 } 572 } 573 574 /** 575 * Adds the given file input field to this dialog.<p> 576 * 577 * @param fileInfos the file info objects 578 */ 579 protected void addFiles(List<CmsFileInfo> fileInfos) { 580 581 if (fileInfos != null) { 582 for (CmsFileInfo file : fileInfos) { 583 584 // store all files 585 m_allFiles.put(file.getFileName(), file); 586 CmsUploadRestrictionInfo restriction = CmsCoreProvider.get().getUploadRestriction(); 587 588 String targetRootPath = getTargetRootPath(); 589 boolean restricted = !restriction.isUploadEnabled(targetRootPath) 590 || !restriction.checkTypeAllowed(targetRootPath, file.getFileSuffix()); 591 if (restricted) { 592 m_restricted.add(file.getFileName()); 593 } 594 595 // add those files to the list of files to upload that potential candidates 596 if (!isTooLarge(file) && (file.getFileSize() != 0) && !restricted) { 597 m_filesToUpload.put(file.getFileName(), file); 598 } 599 600 // remove those files from the list to upload that were previously unchecked by the user 601 if ((m_listItems.get(file.getFileName()) != null) 602 && (m_listItems.get(file.getFileName()).getCheckBox() != null) 603 && !m_listItems.get(file.getFileName()).getCheckBox().isChecked()) { 604 m_filesToUpload.remove(file.getFileName()); 605 } 606 } 607 608 // now rebuild the list: handle all files 609 m_fileList.clearList(); 610 List<String> sortedFileNames = new ArrayList<String>(m_allFiles.keySet()); 611 Collections.sort(sortedFileNames, String.CASE_INSENSITIVE_ORDER); 612 for (String filename : sortedFileNames) { 613 CmsFileInfo file = m_allFiles.get(filename); 614 addFileToList(file, false, false, isTooLarge(file), m_restricted.contains(file.getFileName())); 615 } 616 doResize(); 617 } 618 loadAndShow(); 619 } 620 621 /** 622 * Cancels the upload progress timer.<p> 623 */ 624 protected void cancelUpdateProgress() { 625 626 m_updateProgressTimer.cancel(); 627 } 628 629 /** 630 * Cancels the upload.<p> 631 */ 632 protected void cancelUpload() { 633 634 m_canceled = true; 635 cancelUpdateProgress(); 636 637 CmsRpcAction<Boolean> callback = new CmsRpcAction<Boolean>() { 638 639 /** 640 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 641 */ 642 @Override 643 public void execute() { 644 645 getUploadService().cancelUpload(this); 646 } 647 648 /** 649 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 650 */ 651 @Override 652 protected void onResponse(Boolean result) { 653 654 hide(); 655 } 656 }; 657 callback.execute(); 658 } 659 660 /** 661 * Creates the loading animation HTML and adds is to the content wrapper.<p> 662 * 663 * @param msg the message to display below the animation 664 */ 665 protected void createLoadingAnimation(String msg) { 666 667 m_clientLoading = true; 668 if (m_loadingPanel != null) { 669 m_loadingPanel.removeFromParent(); 670 } 671 m_loadingPanel = new FlowPanel(); 672 m_loadingPanel.addStyleName( 673 org.opencms.gwt.client.ui.css.I_CmsLayoutBundle.INSTANCE.uploadButton().loadingPanel()); 674 m_loadingPanel.addStyleName(m_gwtCss.generalCss().cornerAll()); 675 676 CmsLoadingAnimation animationDiv = new CmsLoadingAnimation(); 677 animationDiv.addStyleName( 678 org.opencms.gwt.client.ui.css.I_CmsLayoutBundle.INSTANCE.uploadButton().loadingAnimation()); 679 m_loadingPanel.add(animationDiv); 680 681 HTML messageDiv = new HTML(); 682 messageDiv.addStyleName(org.opencms.gwt.client.ui.css.I_CmsLayoutBundle.INSTANCE.uploadButton().loadingText()); 683 messageDiv.setHTML(msg); 684 m_loadingPanel.add(messageDiv); 685 686 m_contentWrapper.add(m_loadingPanel); 687 doResize(); 688 } 689 690 /** 691 * Disables the OK button.<p> 692 * 693 * @param disabledReason the reason for disabling the OK button 694 */ 695 protected void disableOKButton(String disabledReason) { 696 697 m_okButton.disable(disabledReason); 698 } 699 700 /** 701 * Required to be called when the content has changed.<p> 702 */ 703 protected void doResize() { 704 705 m_scrollPanel.onResizeDescendant(); 706 } 707 708 /** 709 * Enables the OK button.<p> 710 */ 711 protected void enableOKButton() { 712 713 m_okButton.enable(); 714 } 715 716 /** 717 * Returns the contentLength.<p> 718 * 719 * @return the contentLength 720 */ 721 protected long getContentLength() { 722 723 return m_contentLength; 724 } 725 726 /** 727 * Returns the contentWrapper.<p> 728 * 729 * @return the contentWrapper 730 */ 731 protected FlowPanel getContentWrapper() { 732 733 return m_contentWrapper; 734 } 735 736 /** 737 * Returns the list of file names that have to unziped.<p> 738 * 739 * @param all <code>true</code> if the returned list should contain those filenames that 740 * are not inside the map of files to upload. <code>false</code> only those filenames are 741 * returned that are also inside the map of files to upload 742 * 743 * @return the list of file names that have to unziped 744 */ 745 protected List<String> getFilesToUnzip(boolean all) { 746 747 if (!all) { 748 List<String> result = new ArrayList<String>(); 749 for (String fileName : m_filesToUnzip) { 750 if (m_filesToUpload.keySet().contains(fileName)) { 751 result.add(fileName); 752 } 753 } 754 return result; 755 } 756 return m_filesToUnzip; 757 } 758 759 /** 760 * Returns the filesToUpload.<p> 761 * 762 * @return the filesToUpload 763 */ 764 protected Map<String, CmsFileInfo> getFilesToUpload() { 765 766 return m_filesToUpload; 767 } 768 769 /** 770 * Returns "files" or "file" depending on the files to upload.<p> 771 * 772 * @return "files" or "file" depending on the files to upload 773 */ 774 protected String getFileText() { 775 776 if (m_filesToUpload.size() == 1) { 777 return org.opencms.gwt.client.Messages.get().key( 778 org.opencms.gwt.client.Messages.GUI_UPLOAD_FILES_SINGULAR_0); 779 } 780 return org.opencms.gwt.client.Messages.get().key(org.opencms.gwt.client.Messages.GUI_UPLOAD_FILES_PLURAL_0); 781 } 782 783 /** 784 * Gets the post-create handler. 785 * 786 * @return the post-create handler 787 */ 788 protected String getPostCreateHandler() { 789 790 return m_postCreateHandler; 791 } 792 793 /** 794 * Returns the resource type name for a given filename.<p> 795 * 796 * @param file the file info 797 * 798 * @return the resource type name 799 */ 800 protected String getResourceType(CmsFileInfo file) { 801 802 return CmsCoreProvider.get().getResourceType(file); 803 } 804 805 /** 806 * Returns the targetFolder.<p> 807 * 808 * @return the targetFolder 809 */ 810 protected String getTargetFolder() { 811 812 return m_targetFolder; 813 } 814 815 /** 816 * Returns the upload service instance.<p> 817 * 818 * @return the upload service instance 819 */ 820 protected I_CmsUploadServiceAsync getUploadService() { 821 822 if (m_uploadService == null) { 823 m_uploadService = GWT.create(I_CmsUploadService.class); 824 String serviceUrl = CmsCoreProvider.get().link("org.opencms.ade.upload.CmsUploadService.gwt"); 825 ((ServiceDefTarget)m_uploadService).setServiceEntryPoint(serviceUrl); 826 } 827 return m_uploadService; 828 } 829 830 /** 831 * Returns the upload JSP uri.<p> 832 * 833 * @return the upload JSP uri 834 */ 835 protected String getUploadUri() { 836 837 return CmsCoreProvider.get().link(I_CmsUploadConstants.UPLOAD_ACTION_JSP_URI); 838 } 839 840 /** 841 * Inserts a hidden form into.<p> 842 * 843 * @param form the form to insert 844 */ 845 protected void insertUploadForm(FormPanel form) { 846 847 form.getElement().getStyle().setDisplay(Display.NONE); 848 m_contentWrapper.add(form); 849 } 850 851 /** 852 * The action that is executed if the user clicks on the OK button.<p> 853 * 854 * If the selection dialog is currently shown the selected files are checked 855 * otherwise the upload is triggered.<p> 856 */ 857 protected void onOkClick() { 858 859 if (!m_selectionDone) { 860 checkSelection(); 861 } else { 862 commit(); 863 } 864 } 865 866 /** 867 * Required to be called when the content has changed.<p> 868 */ 869 protected void onResize() { 870 871 m_scrollPanel.onResize(); 872 } 873 874 /** 875 * Decides how to go on depending on the information of the server response.<p> 876 * 877 * Shows a warning if there is another upload process active (inside the same session).<p> 878 * 879 * Otherwise if the list of files to upload contains already existent resources on the VFS or if there 880 * are files selected that have invalid file names the overwrite dialog is shown.<p> 881 * 882 * Only if there is no other upload process running and none of the selected files 883 * is already existent on the VFS the upload is triggered.<p> 884 * 885 * @param result the bean that contains the information to evaluate 886 */ 887 protected void proceedWorkflow(CmsUploadFileBean result) { 888 889 if (result.isActive()) { 890 m_okButton.enable(); 891 CmsNotification.get().send(Type.WARNING, Messages.get().key(Messages.GUI_UPLOAD_NOTIFICATION_RUNNING_0)); 892 } else { 893 if (!result.getExistingResourceNames().isEmpty() 894 || !result.getInvalidFileNames().isEmpty() 895 || !result.getExistingDeletedFileNames().isEmpty()) { 896 showOverwriteDialog(result); 897 } else { 898 commit(); 899 } 900 } 901 } 902 903 /** 904 * Removes the drag and drop message.<p> 905 */ 906 protected void removeDragAndDropMessage() { 907 908 if (m_dragAndDropMessage != null) { 909 m_dragAndDropMessage.removeFromParent(); 910 m_dragAndDropMessage = null; 911 getContentWrapper().getElement().getStyle().clearBackgroundColor(); 912 } 913 } 914 915 /** 916 * Sets the contentLength.<p> 917 * 918 * @param contentLength the contentLength to set 919 */ 920 protected void setContentLength(long contentLength) { 921 922 m_contentLength = contentLength; 923 } 924 925 /** 926 * Execute to set the content wrapper height.<p> 927 */ 928 protected void setContentWrapperHeight() { 929 930 // set the max height of the content panel 931 int fixedContent = 0; 932 if (m_dialogInfo.isVisible()) { 933 fixedContent += m_dialogInfo.getOffsetHeight(); 934 } 935 if (m_selectionSummary.isVisible()) { 936 fixedContent += m_selectionSummary.getOffsetHeight(); 937 } 938 m_scrollPanel.getElement().getStyle().setPropertyPx("maxHeight", getAvailableHeight(fixedContent)); 939 doResize(); 940 } 941 942 /** 943 * Displays the 'use drag and drop' / 'no drag and drop available' message.<p> 944 */ 945 protected void setDragAndDropMessage() { 946 947 if (m_dragAndDropMessage == null) { 948 m_dragAndDropMessage = new HTML(); 949 m_dragAndDropMessage.setStyleName(I_CmsLayoutBundle.INSTANCE.uploadCss().dragAndDropMessage()); 950 m_dragAndDropMessage.setText(Messages.get().key(Messages.GUI_UPLOAD_DRAG_AND_DROP_DISABLED_0)); 951 } 952 getContentWrapper().add(m_dragAndDropMessage); 953 getContentWrapper().getElement().getStyle().setBackgroundColor( 954 I_CmsConstantsBundle.INSTANCE.css().notificationErrorBg()); 955 doResize(); 956 } 957 958 /** 959 * Sets the HTML of the selection summary.<p> 960 * 961 * @param html the HTML to set as String 962 */ 963 protected void setSummaryHTML(String html) { 964 965 m_selectionSummary.setHTML(html); 966 } 967 968 /** 969 * Retrieves the progress information from the server.<p> 970 */ 971 protected void updateProgress() { 972 973 CmsRpcAction<CmsUploadProgessInfo> callback = new CmsRpcAction<CmsUploadProgessInfo>() { 974 975 /** 976 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 977 */ 978 @Override 979 public void execute() { 980 981 getUploadService().getUploadProgressInfo(this); 982 } 983 984 /** 985 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onFailure(java.lang.Throwable) 986 */ 987 @Override 988 public void onFailure(Throwable t) { 989 990 super.onFailure(t); 991 cancelUpdateProgress(); 992 } 993 994 /** 995 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 996 */ 997 @Override 998 protected void onResponse(CmsUploadProgessInfo result) { 999 1000 updateProgressBar(result); 1001 } 1002 }; 1003 callback.execute(); 1004 } 1005 1006 /** 1007 * Updates the progress bar.<p> 1008 * 1009 * @param info the progress info 1010 */ 1011 protected void updateProgressBar(CmsUploadProgessInfo info) { 1012 1013 switch (info.getState()) { 1014 case notStarted: 1015 break; 1016 case running: 1017 m_progressInfo.setProgress(info); 1018 stopLoadingAnimation(); 1019 break; 1020 case finished: 1021 m_progressInfo.finish(); 1022 displayDialogInfo( 1023 org.opencms.gwt.client.Messages.get().key( 1024 org.opencms.gwt.client.Messages.GUI_UPLOAD_INFO_FINISHING_0), 1025 false); 1026 startLoadingAnimation( 1027 org.opencms.gwt.client.Messages.get().key( 1028 org.opencms.gwt.client.Messages.GUI_UPLOAD_INFO_CREATING_RESOURCES_0), 1029 1500); 1030 break; 1031 default: 1032 break; 1033 } 1034 } 1035 1036 /** 1037 * Adds a click handler for the given check box.<p> 1038 * 1039 * @param check the check box 1040 * @param unzipWidget the un-zip check box 1041 * @param file the file 1042 */ 1043 private void addClickHandlerToCheckBox(final CmsCheckBox check, final Widget unzipWidget, final CmsFileInfo file) { 1044 1045 check.addClickHandler(new ClickHandler() { 1046 1047 /** 1048 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent) 1049 */ 1050 public void onClick(ClickEvent event) { 1051 1052 // add or remove the file from the list of files to upload 1053 if (check.isChecked()) { 1054 getFilesToUpload().put(file.getFileName(), file); 1055 if (unzipWidget != null) { 1056 enableUnzip(unzipWidget); 1057 } 1058 } else { 1059 getFilesToUpload().remove(file.getFileName()); 1060 if (unzipWidget != null) { 1061 disableUnzip(unzipWidget); 1062 } 1063 } 1064 1065 // disable or enable the OK button 1066 if (getFilesToUpload().isEmpty()) { 1067 disableOKButton(Messages.get().key(Messages.GUI_UPLOAD_NOTIFICATION_NO_FILES_0)); 1068 } else { 1069 enableOKButton(); 1070 } 1071 1072 // update summary 1073 updateSummary(); 1074 1075 } 1076 1077 /** 1078 * Disables the 'unzip' button 1079 * 1080 * @param unzip the unzip button 1081 */ 1082 private void disableUnzip(Widget unzip) { 1083 1084 ((CmsToggleButton)unzip).setEnabled(false); 1085 } 1086 1087 /** 1088 * Enables the 'unzip' button 1089 * 1090 * @param unzip the unzip button 1091 */ 1092 private void enableUnzip(Widget unzip) { 1093 1094 ((CmsToggleButton)unzip).setEnabled(true); 1095 } 1096 }); 1097 } 1098 1099 /** 1100 * Adds a file to the list.<p> 1101 * 1102 * @param file the file to add 1103 * @param invalid signals if the filename is invalid 1104 * @param existingDeleted in case of existing files marked as deleted 1105 * @param isTooLarge signals if the file size limit is exceeded 1106 * @param forbiddenType true if the file has a forbidden type 1107 */ 1108 private void addFileToList( 1109 final CmsFileInfo file, 1110 boolean invalid, 1111 boolean existingDeleted, 1112 boolean isTooLarge, 1113 boolean forbiddenType) { 1114 1115 CmsListInfoBean infoBean = createInfoBean(file); 1116 CmsListItemWidget listItemWidget = new CmsListItemWidget(infoBean); 1117 listItemWidget.setIcon(CmsCoreProvider.get().getResourceTypeIcon(file)); 1118 CmsCheckBox check = new CmsCheckBox(); 1119 check.setChecked(false); 1120 if (!invalid && !isTooLarge && !existingDeleted && !forbiddenType) { 1121 if (file.getFileSize() == 0) { 1122 check.setChecked(false); 1123 } 1124 check.setChecked(m_filesToUpload.containsKey(file.getFileName())); 1125 check.setTitle(file.getFileName()); 1126 if (!m_selectionDone && file.getFileName().toLowerCase().endsWith(".zip")) { 1127 final Widget unzip = createUnzipCheckBox(file); 1128 addClickHandlerToCheckBox(check, unzip, file); 1129 listItemWidget.addButton(unzip); 1130 } else { 1131 addClickHandlerToCheckBox(check, null, file); 1132 } 1133 } else if (forbiddenType) { 1134 String message = Messages.get().key(Messages.GUI_UPLOAD_RESTRICTED_0); 1135 check.disable(message); 1136 listItemWidget.setBackground(Background.RED); 1137 listItemWidget.setSubtitleLabel(message); 1138 } else if (existingDeleted) { 1139 // is invalid 1140 String message = Messages.get().key(Messages.GUI_UPLOAD_FILE_EXISTING_DELETED_1, file.getFileName()); 1141 check.disable(message); 1142 listItemWidget.setBackground(Background.RED); 1143 listItemWidget.setSubtitleLabel(message); 1144 } else if (isTooLarge) { 1145 String message = getFileSizeTooLargeMessage(file); 1146 check.disable(message); 1147 listItemWidget.setBackground(Background.RED); 1148 listItemWidget.setSubtitleLabel(message); 1149 } else { 1150 // is invalid 1151 String message = Messages.get().key( 1152 Messages.GUI_UPLOAD_FILE_INVALID_NAME_2, 1153 file.getFileName(), 1154 CmsUploadButton.formatBytes(file.getFileSize())); 1155 check.disable(message); 1156 listItemWidget.setBackground(Background.RED); 1157 listItemWidget.setSubtitleLabel(message); 1158 } 1159 1160 CmsListItem listItem = new CmsListItem(check, listItemWidget); 1161 m_fileList.addItem(listItem); 1162 m_listItems.put(file.getFileName(), listItem); 1163 doResize(); 1164 } 1165 1166 /** 1167 * Changes the height of the content wrapper so that the dialog finally has the 1168 * same height that the dialog has when the min height is set on the selection screen.<p> 1169 */ 1170 private void changeHeight() { 1171 1172 int firstHeight = MIN_CONTENT_HEIGHT + m_firstInfoHeight + m_firstSummaryHeight + 2; 1173 int currentHeight = CmsDomUtil.getCurrentStyleInt(m_mainPanel.getElement(), CmsDomUtil.Style.height); 1174 int targetHeight = firstHeight - m_dialogInfo.getOffsetHeight() - m_selectionSummary.getOffsetHeight(); 1175 if (currentHeight > firstHeight) { 1176 CmsChangeHeightAnimation.change(m_scrollPanel.getElement(), targetHeight, new Command() { 1177 1178 public void execute() { 1179 1180 doResize(); 1181 } 1182 }, 750); 1183 } 1184 } 1185 1186 /** 1187 * Before the upload data is effectively submited we have to check 1188 * for already existent resources in the VFS.<p> 1189 * 1190 * Executes the RPC call that checks the VFS for existing resources. 1191 * Passes the response object to a method that evaluates the result.<p> 1192 */ 1193 private void checkSelection() { 1194 1195 m_okButton.disable(Messages.get().key(Messages.GUI_UPLOAD_BUTTON_OK_DISABLE_CHECKING_0)); 1196 1197 if (!m_selectionDone) { 1198 m_firstContentHeight = CmsDomUtil.getCurrentStyleInt(m_scrollPanel.getElement(), CmsDomUtil.Style.height); 1199 m_firstInfoHeight = m_dialogInfo.getOffsetHeight(); 1200 m_firstSummaryHeight = m_selectionSummary.getOffsetHeight(); 1201 } 1202 1203 CmsRpcAction<CmsUploadFileBean> callback = new CmsRpcAction<CmsUploadFileBean>() { 1204 1205 /** 1206 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 1207 */ 1208 @Override 1209 public void execute() { 1210 1211 List<String> filesToCheck = new ArrayList<String>(getFilesToUpload().keySet()); 1212 filesToCheck.removeAll(getFilesToUnzip(false)); 1213 getUploadService().checkUploadFiles(filesToCheck, getTargetFolder(), m_isTargetRootPath, this); 1214 } 1215 1216 /** 1217 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 1218 */ 1219 @Override 1220 protected void onResponse(CmsUploadFileBean result) { 1221 1222 proceedWorkflow(result); 1223 } 1224 }; 1225 callback.execute(); 1226 } 1227 1228 /** 1229 * Closes the dialog after a delay.<p> 1230 */ 1231 private void closeOnSuccess() { 1232 1233 Timer closeTimer = new Timer() { 1234 1235 /** 1236 * @see com.google.gwt.user.client.Timer#run() 1237 */ 1238 @Override 1239 public void run() { 1240 1241 A_CmsUploadDialog.this.hide(); 1242 } 1243 }; 1244 closeTimer.schedule(1500); 1245 } 1246 1247 /** 1248 * Calls the submit action if there are any files selected for upload.<p> 1249 */ 1250 private void commit() { 1251 1252 m_selectionDone = true; 1253 if (!m_filesToUpload.isEmpty()) { 1254 m_okButton.disable(Messages.get().key(Messages.GUI_UPLOAD_BUTTON_OK_DISABLE_UPLOADING_0)); 1255 if (m_uploadButton instanceof UIObject) { 1256 ((UIObject)m_uploadButton).getElement().getStyle().setDisplay(Display.NONE); 1257 } 1258 showProgress(); 1259 submit(); 1260 } 1261 } 1262 1263 /** 1264 * Creates the "OK", the "Cancel" and the "Upload" button.<p> 1265 */ 1266 private void createButtons() { 1267 1268 addDialogClose(new Command() { 1269 1270 public void execute() { 1271 1272 cancelUpload(); 1273 } 1274 }); 1275 1276 CmsPushButton cancelButton = new CmsPushButton(); 1277 cancelButton.setTitle(org.opencms.gwt.client.Messages.get().key(org.opencms.gwt.client.Messages.GUI_CANCEL_0)); 1278 cancelButton.setText(org.opencms.gwt.client.Messages.get().key(org.opencms.gwt.client.Messages.GUI_CANCEL_0)); 1279 cancelButton.setSize(I_CmsButton.Size.medium); 1280 cancelButton.setUseMinWidth(true); 1281 cancelButton.addClickHandler(new ClickHandler() { 1282 1283 /** 1284 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent) 1285 */ 1286 public void onClick(ClickEvent event) { 1287 1288 cancelUpload(); 1289 } 1290 }); 1291 addButton(cancelButton); 1292 1293 m_okButton = new CmsPushButton(); 1294 m_okButton.setTitle(org.opencms.gwt.client.Messages.get().key(org.opencms.gwt.client.Messages.GUI_OK_0)); 1295 m_okButton.setText(org.opencms.gwt.client.Messages.get().key(org.opencms.gwt.client.Messages.GUI_OK_0)); 1296 m_okButton.setSize(I_CmsButton.Size.medium); 1297 m_okButton.setUseMinWidth(true); 1298 m_okButton.addClickHandler(new ClickHandler() { 1299 1300 /** 1301 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent) 1302 */ 1303 public void onClick(ClickEvent event) { 1304 1305 onOkClick(); 1306 } 1307 }); 1308 addButton(m_okButton); 1309 1310 CmsDialogUploadButtonHandler buttonHandler = new CmsDialogUploadButtonHandler( 1311 new Supplier<I_CmsUploadContext>() { 1312 1313 public I_CmsUploadContext get() { 1314 1315 return m_context; 1316 } 1317 }); 1318 buttonHandler.setUploadDialog(this); 1319 // add a new upload button 1320 CmsUploadButton uploadButton = new CmsUploadButton(buttonHandler); 1321 uploadButton.addStyleName(I_CmsLayoutBundle.INSTANCE.uploadCss().uploadDialogButton()); 1322 uploadButton.setText(Messages.get().key(Messages.GUI_UPLOAD_BUTTON_ADD_FILES_0)); 1323 addButton(uploadButton); 1324 m_uploadButton = uploadButton; 1325 } 1326 1327 /** 1328 * Creates the unzip checkbox.<p> 1329 * 1330 * @param file the file to create the checkbox for 1331 * 1332 * @return the unzip checkbox 1333 */ 1334 private Widget createUnzipCheckBox(final CmsFileInfo file) { 1335 1336 final CmsToggleButton unzip = new CmsToggleButton(); 1337 I_CmsUploadCss uploadCss = I_CmsLayoutBundle.INSTANCE.uploadCss(); 1338 String caption = Messages.get().key(Messages.GUI_UNZIP_BUTTON_TEXT_0); 1339 unzip.setUpFace(caption, uploadCss.unzipButtonUpFace()); 1340 unzip.setDownFace(caption, uploadCss.unzipButtonDownFace()); 1341 unzip.addStyleName(uploadCss.unzipButton()); 1342 unzip.addStyleName(org.opencms.gwt.client.ui.css.I_CmsLayoutBundle.INSTANCE.listItemWidgetCss().permaVisible()); 1343 unzip.setDown(getFilesToUnzip(true).contains(file.getFileName())); 1344 if (!m_filesToUpload.containsKey(file.getFileName())) { 1345 unzip.disable(Messages.get().key(Messages.GUI_UPLOAD_FILE_NOT_SELECTED_0)); 1346 } 1347 unzip.addClickHandler(new ClickHandler() { 1348 1349 /** 1350 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent) 1351 */ 1352 public void onClick(ClickEvent event) { 1353 1354 // add or remove the file from the list of files to upload 1355 if (unzip.isDown()) { 1356 getFilesToUnzip(true).add(file.getFileName()); 1357 } else { 1358 getFilesToUnzip(true).remove(file.getFileName()); 1359 } 1360 } 1361 }); 1362 return unzip; 1363 } 1364 1365 /** 1366 * Sets the user info.<p> 1367 * 1368 * @param msg the message to display 1369 * @param warning signals whether the message should be a warning or nor 1370 */ 1371 private void displayDialogInfo(String msg, boolean warning) { 1372 1373 StringBuffer buffer = new StringBuffer(64); 1374 if (!warning) { 1375 buffer.append("<p class=\""); 1376 buffer.append(org.opencms.gwt.client.ui.css.I_CmsLayoutBundle.INSTANCE.uploadButton().dialogMessage()); 1377 buffer.append("\">"); 1378 buffer.append(msg); 1379 buffer.append("</p>"); 1380 } else { 1381 buffer.append(FontOpenCms.WARNING.getHtml(32, I_CmsConstantsBundle.INSTANCE.css().colorWarning())); 1382 buffer.append("<p class=\""); 1383 buffer.append(org.opencms.gwt.client.ui.css.I_CmsLayoutBundle.INSTANCE.uploadButton().warningMessage()); 1384 buffer.append("\">"); 1385 buffer.append(msg); 1386 buffer.append("</p>"); 1387 } 1388 m_dialogInfo.setHTML(buffer.toString()); 1389 } 1390 1391 /** 1392 * Gets the target root path. 1393 * 1394 * @return the target root path 1395 */ 1396 private String getTargetRootPath() { 1397 1398 if (m_isTargetRootPath) { 1399 return m_targetFolder; 1400 } else { 1401 return CmsCoreProvider.get().addSiteRoot(m_targetFolder); 1402 } 1403 } 1404 1405 /** 1406 * Removes all widgets from the content wrapper.<p> 1407 */ 1408 private void removeContent() { 1409 1410 m_contentWrapper.clear(); 1411 doResize(); 1412 } 1413 1414 /** 1415 * Sets the height for the content so that the dialog finally has the same height 1416 * as the dialog has on the selection screen.<p> 1417 */ 1418 private void setHeight() { 1419 1420 int infoDiff = m_firstInfoHeight - m_dialogInfo.getOffsetHeight(); 1421 int summaryDiff = m_firstSummaryHeight - m_selectionSummary.getOffsetHeight(); 1422 int height = m_firstContentHeight + infoDiff + summaryDiff; 1423 m_scrollPanel.getElement().getStyle().setHeight(height, Unit.PX); 1424 m_scrollPanel.getElement().getStyle().clearProperty("minHeight"); 1425 m_scrollPanel.getElement().getStyle().clearProperty("maxHeight"); 1426 doResize(); 1427 } 1428 1429 /** 1430 * Shows the overwrite dialog.<p> 1431 * 1432 * @param infoBean the info bean containing the existing and invalid file names 1433 */ 1434 private void showOverwriteDialog(CmsUploadFileBean infoBean) { 1435 1436 // update the dialog 1437 m_selectionDone = true; 1438 m_okButton.enable(); 1439 if (infoBean.getInvalidFileNames().isEmpty() && infoBean.getExistingDeletedFileNames().isEmpty()) { 1440 displayDialogInfo(Messages.get().key(Messages.GUI_UPLOAD_INFO_OVERWRITE_0), true); 1441 } else { 1442 displayDialogInfo(Messages.get().key(Messages.GUI_UPLOAD_INFO_INVALID_0), true); 1443 } 1444 if (m_uploadButton instanceof UIObject) { 1445 ((UIObject)m_uploadButton).getElement().getStyle().setDisplay(Display.NONE); 1446 } 1447 // clear the list 1448 m_fileList.clearList(); 1449 1450 // handle existing files 1451 List<String> existings = new ArrayList<String>(infoBean.getExistingResourceNames()); 1452 Collections.sort(existings, String.CASE_INSENSITIVE_ORDER); 1453 for (String filename : existings) { 1454 addFileToList(m_filesToUpload.get(filename), false, false, false, false); 1455 } 1456 1457 // handle the invalid files 1458 List<String> invalids = new ArrayList<String>(infoBean.getInvalidFileNames()); 1459 Collections.sort(invalids, String.CASE_INSENSITIVE_ORDER); 1460 for (String filename : invalids) { 1461 addFileToList(m_filesToUpload.get(filename), true, false, false, false); 1462 m_filesToUpload.remove(filename); 1463 } 1464 1465 // handle the invalid files 1466 List<String> existingDeleted = new ArrayList<String>(infoBean.getExistingDeletedFileNames()); 1467 Collections.sort(existingDeleted, String.CASE_INSENSITIVE_ORDER); 1468 for (String filename : existingDeleted) { 1469 addFileToList(m_filesToUpload.get(filename), false, true, false, false); 1470 m_filesToUpload.remove(filename); 1471 } 1472 1473 // set the height of the content 1474 setHeight(); 1475 } 1476 1477 /** 1478 * Starts the upload progress bar.<p> 1479 */ 1480 private void showProgress() { 1481 1482 removeContent(); 1483 displayDialogInfo( 1484 org.opencms.gwt.client.Messages.get().key(org.opencms.gwt.client.Messages.GUI_UPLOAD_INFO_UPLOADING_0), 1485 false); 1486 m_selectionSummary.removeFromParent(); 1487 List<String> files = new ArrayList<String>(getFilesToUpload().keySet()); 1488 Collections.sort(files, String.CASE_INSENSITIVE_ORDER); 1489 m_progressInfo = new CmsUploadProgressInfo(files); 1490 m_progressInfo.setContentLength(m_contentLength); 1491 m_contentWrapper.add(m_progressInfo); 1492 m_updateProgressTimer.scheduleRepeating(UPDATE_PROGRESS_INTERVALL); 1493 startLoadingAnimation(Messages.get().key(Messages.GUI_UPLOAD_CLIENT_LOADING_0), 0); 1494 setHeight(); 1495 changeHeight(); 1496 } 1497 1498 /** 1499 * Starts the loading animation.<p> 1500 * 1501 * Used while client is loading files from hard disk into memory.<p> 1502 * 1503 * @param msg the message that should be displayed below the loading animation (can also be HTML as String) 1504 * @param delayMillis the delay to start the animation with 1505 */ 1506 private void startLoadingAnimation(final String msg, int delayMillis) { 1507 1508 m_loadingTimer = new Timer() { 1509 1510 @Override 1511 public void run() { 1512 1513 createLoadingAnimation(msg); 1514 } 1515 }; 1516 if (delayMillis > 0) { 1517 m_loadingTimer.schedule(delayMillis); 1518 } else { 1519 m_loadingTimer.run(); 1520 } 1521 } 1522 1523 /** 1524 * Stops the client loading animation.<p> 1525 */ 1526 private void stopLoadingAnimation() { 1527 1528 if (m_loadingTimer != null) { 1529 m_loadingTimer.cancel(); 1530 } 1531 if (m_clientLoading) { 1532 m_contentWrapper.remove(m_loadingPanel); 1533 doResize(); 1534 m_clientLoading = false; 1535 } 1536 } 1537}