001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (C) Alkacon Software (https://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: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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.gwt.client.CmsCoreProvider; 032import org.opencms.gwt.client.ui.CmsErrorDialog; 033import org.opencms.gwt.client.ui.input.upload.CmsFileInfo; 034import org.opencms.gwt.client.ui.input.upload.CmsFileInput; 035import org.opencms.gwt.client.ui.input.upload.I_CmsUploadButton; 036import org.opencms.gwt.client.ui.input.upload.I_CmsUploadButtonHandler; 037import org.opencms.gwt.shared.CmsUploadRestrictionInfo; 038 039import java.util.List; 040 041import com.google.common.base.Supplier; 042import com.google.gwt.core.client.GWT; 043import com.google.gwt.core.client.Scheduler; 044import com.google.gwt.dom.client.Style.Unit; 045import com.google.gwt.event.logical.shared.CloseHandler; 046import com.google.gwt.event.shared.HandlerRegistration; 047import com.google.gwt.user.client.Event; 048import com.google.gwt.user.client.rpc.AsyncCallback; 049import com.google.gwt.user.client.ui.PopupPanel; 050 051/** 052 * Default upload button handler which is used for the upload dialog.<p> 053 */ 054public class CmsDialogUploadButtonHandler implements I_CmsUploadButtonHandler { 055 056 /** Handler registration for the user interaction detection. */ 057 private static HandlerRegistration m_userInteractionCheckRegistration; 058 059 /** Records if user interaction has occurred. */ 060 private static boolean m_userInteraction; 061 062 /** The upload button instance. */ 063 private I_CmsUploadButton m_button; 064 065 /** The close handler for the upload dialog. */ 066 private CloseHandler<PopupPanel> m_closeHandler; 067 068 /** The handler registration for the close handler of the dialog. */ 069 private HandlerRegistration m_closeHandlerRegistration; 070 071 /** Factory for creating upload contexts. */ 072 private Supplier<I_CmsUploadContext> m_contextFactory; 073 074 /** True if the the target folder should be treated as a root path. */ 075 private boolean m_isTargetRootPath; 076 077 /** The post-create handler. **/ 078 private String m_postCreateHandler; 079 080 /** The target folder for the upload dialog. */ 081 private String m_targetFolder; 082 083 /** The upload dialog instance. */ 084 private A_CmsUploadDialog m_uploadDialog; 085 086 /** 087 * Creates a new upload button handler.<p> 088 * 089 * @param contextFactory the context factory to use for upload contexts 090 */ 091 public CmsDialogUploadButtonHandler(Supplier<I_CmsUploadContext> contextFactory) { 092 093 m_contextFactory = contextFactory; 094 } 095 096 /** 097 * Creates a new upload button handler.<p> 098 * 099 * @param contextFactory the context factory to use for upload contexts 100 * @param targetFolder the target folder 101 * @param isRootPath true fi the target folder is a root path 102 */ 103 public CmsDialogUploadButtonHandler( 104 Supplier<I_CmsUploadContext> contextFactory, 105 String targetFolder, 106 boolean isRootPath) { 107 108 m_contextFactory = contextFactory; 109 m_targetFolder = targetFolder; 110 m_isTargetRootPath = isRootPath; 111 } 112 113 /** 114 * @see org.opencms.gwt.client.ui.input.upload.I_CmsUploadButtonHandler#initializeFileInput(org.opencms.gwt.client.ui.input.upload.CmsFileInput) 115 */ 116 public void initializeFileInput(CmsFileInput fileInput) { 117 118 CmsUploadRestrictionInfo restriction = CmsCoreProvider.get().getUploadRestriction(); 119 120 // Set up a repeating job (every 10s) to update the upload restriction info if user interaction was detected 121 // (which we detect in a native preview handler). 122 // We do all this here because we don't need it if no file input is ever initialized. 123 if (m_userInteractionCheckRegistration == null) { 124 Scheduler.get().scheduleFixedDelay(() -> { 125 if (m_userInteraction) { 126 m_userInteraction = false; 127 CmsCoreProvider.get(); 128 CmsCoreProvider.getService().loadUploadRestrictionInfo( 129 new AsyncCallback<CmsUploadRestrictionInfo>() { 130 131 @Override 132 public void onFailure(Throwable caught) { 133 134 CmsErrorDialog.handleException(caught); 135 } 136 137 @Override 138 public void onSuccess(CmsUploadRestrictionInfo result) { 139 140 CmsCoreProvider.get().setUploadRestrictionInfo(result); 141 142 } 143 }); 144 } 145 return true; 146 147 }, 10000); 148 m_userInteractionCheckRegistration = Event.addNativePreviewHandler(event -> { 149 if ((event.getTypeInt() == Event.ONMOUSEMOVE) 150 || (event.getTypeInt() == Event.ONTOUCHSTART) 151 || (event.getTypeInt() == Event.ONKEYDOWN) 152 || (event.getTypeInt() == Event.ONSCROLL)) { 153 m_userInteraction = true; 154 155 } 156 157 }); 158 159 } 160 161 if (m_targetFolder != null) { 162 163 String realTargetFolder = m_targetFolder; 164 if (!m_isTargetRootPath) { 165 realTargetFolder = CmsCoreProvider.get().addSiteRoot(m_targetFolder); 166 } 167 168 boolean enabled = restriction.isUploadEnabled(realTargetFolder); 169 m_button.setEnabled(enabled, ""); 170 fileInput.setDisabled(!enabled); 171 String accept = restriction.getAcceptAttribute(realTargetFolder); 172 fileInput.setAccept(accept); 173 } else { 174 // CmsGwtLog.log("target folder is null"); 175 } 176 // important to set font-size as inline style, as IE7 and IE8 will not accept it otherwise 177 fileInput.getElement().getStyle().setFontSize(200, Unit.PX); 178 fileInput.getElement().getStyle().setProperty("minHeight", "200px"); 179 fileInput.setAllowMultipleFiles(true); 180 fileInput.setName("upload"); 181 fileInput.addStyleName( 182 org.opencms.gwt.client.ui.css.I_CmsLayoutBundle.INSTANCE.uploadButton().uploadFileInput()); 183 } 184 185 /** 186 * @see org.opencms.gwt.client.ui.input.upload.I_CmsUploadButtonHandler#onChange(org.opencms.gwt.client.ui.input.upload.CmsFileInput) 187 */ 188 public void onChange(CmsFileInput fileInput) { 189 190 if (m_uploadDialog == null) { 191 try { 192 m_uploadDialog = GWT.create(CmsUploadDialogImpl.class); 193 I_CmsUploadContext context = m_contextFactory.get(); 194 m_uploadDialog.setContext(context); 195 updateDialog(); 196 // the current upload button is located outside the dialog, reinitialize it with a new button handler instance 197 m_button.reinitButton( 198 new CmsDialogUploadButtonHandler(m_contextFactory, m_targetFolder, m_isTargetRootPath)); 199 } catch (Exception e) { 200 CmsErrorDialog.handleException( 201 new Exception( 202 "Deserialization of dialog data failed. This may be caused by expired java-script resources, please clear your browser cache and try again.", 203 e)); 204 return; 205 } 206 } 207 m_uploadDialog.addFileInput(fileInput); 208 m_button.createFileInput(); 209 } 210 211 /** 212 * Opens the upload dialog for the given file references.<p> 213 * 214 * @param files the file references 215 */ 216 public void openDialogWithFiles(List<CmsFileInfo> files) { 217 218 if (m_uploadDialog == null) { 219 try { 220 m_uploadDialog = GWT.create(CmsUploadDialogImpl.class); 221 I_CmsUploadContext context = m_contextFactory.get(); 222 m_uploadDialog.setContext(context); 223 updateDialog(); 224 if (m_button != null) { 225 // the current upload button is located outside the dialog, reinitialize it with a new button handler instance 226 m_button.reinitButton( 227 new CmsDialogUploadButtonHandler(m_contextFactory, m_targetFolder, m_isTargetRootPath)); 228 } 229 } catch (Exception e) { 230 CmsErrorDialog.handleException( 231 new Exception( 232 "Deserialization of dialog data failed. This may be caused by expired java-script resources, please clear your browser cache and try again.", 233 e)); 234 return; 235 } 236 } 237 m_uploadDialog.addFiles(files); 238 if (m_button != null) { 239 m_button.createFileInput(); 240 } 241 } 242 243 /** 244 * @see org.opencms.gwt.client.ui.input.upload.I_CmsUploadButtonHandler#setButton(org.opencms.gwt.client.ui.input.upload.I_CmsUploadButton) 245 */ 246 public void setButton(I_CmsUploadButton button) { 247 248 m_button = button; 249 } 250 251 /** 252 * Sets the close handler for the dialog.<p> 253 * 254 * @param closeHandler the close handler 255 */ 256 public void setCloseHandler(CloseHandler<PopupPanel> closeHandler) { 257 258 m_closeHandler = closeHandler; 259 updateDialog(); 260 261 } 262 263 /** 264 * Chooses whether the target folder should be interpreted as a root path.<p> 265 * 266 * @param isTargetRootPath true if the target folder should be treated as a root path 267 */ 268 public void setIsTargetRootPath(boolean isTargetRootPath) { 269 270 m_isTargetRootPath = isTargetRootPath; 271 } 272 273 /** 274 * Sets the post-create handler. 275 * 276 * @param postCreateHandler the post-create handler 277 */ 278 public void setPostCreateHandler(String postCreateHandler) { 279 280 m_postCreateHandler = postCreateHandler; 281 } 282 283 /** 284 * Sets the upload target folder.<p> 285 * 286 * @param targetFolder the upload target folder 287 */ 288 public void setTargetFolder(String targetFolder) { 289 290 m_targetFolder = targetFolder; 291 updateDialog(); 292 } 293 294 /** 295 * Sets the upload dialog instance.<p> 296 * 297 * @param uploadDialog the upload dialog instance 298 */ 299 public void setUploadDialog(A_CmsUploadDialog uploadDialog) { 300 301 m_uploadDialog = uploadDialog; 302 } 303 304 /** 305 * Updates the dialog with the current close handler and target folder.<p> 306 */ 307 protected void updateDialog() { 308 309 if (m_uploadDialog != null) { 310 if ((m_closeHandler != null)) { 311 if (m_closeHandlerRegistration != null) { 312 m_closeHandlerRegistration.removeHandler(); 313 } 314 m_closeHandlerRegistration = m_uploadDialog.addCloseHandler(m_closeHandler); 315 } 316 if ((m_targetFolder != null)) { 317 m_uploadDialog.setTargetFolder(m_targetFolder); 318 } 319 m_uploadDialog.setPostCreateHandler(m_postCreateHandler); 320 m_uploadDialog.setIsTargetRootPath(m_isTargetRootPath); 321 m_uploadDialog.updateHandler(); 322 } 323 } 324}