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