Merging with mconf old branch

This commit is contained in:
Pedro Beschorner Marin 2014-11-03 14:12:47 -02:00
commit 2c5ff4f7cd
20 changed files with 582 additions and 240 deletions

View File

@ -57,9 +57,9 @@ public class PresentationApplication {
public void sendConversionCompleted(String messageKey, String meetingId,
String code, String presentation, int numberOfPages,
String presName, String presBaseUrl) {
String presName, String presBaseUrl, Boolean presDownloadable) {
bbbInGW.sendConversionCompleted(messageKey, meetingId,
code, presentation, numberOfPages, presName, presBaseUrl);
code, presentation, numberOfPages, presName, presBaseUrl, presDownloadable);
}
public void removePresentation(String meetingID, String presentationID){

View File

@ -148,6 +148,7 @@ bbb.presentation.quickLink.label = Presentation Window
bbb.presentation.fitToWidth.toolTip = Fit Presentation To Width
bbb.presentation.fitToPage.toolTip = Fit Presentation To Page
bbb.presentation.uploadPresBtn.toolTip = Upload Presentation
bbb.presentation.downloadPresBtn.toolTip = Click here to download the presentations
bbb.presentation.backBtn.toolTip = Previous slide
bbb.presentation.btnSlideNum.toolTip = Select a slide
bbb.presentation.forwardBtn.toolTip = Next slide
@ -190,6 +191,13 @@ bbb.fileupload.okCancelBtn.toolTip = Close the File Upload dialog box
bbb.fileupload.genThumbText = Generating thumbnails..
bbb.fileupload.progBarLbl = Progress:
bbb.fileupload.fileFormatHint = Upload any office document or Portable Document Format (PDF) file. For best results upload PDF.
bbb.fileupload.letUserDownload = Let the users download the presentation
bbb.fileupload.letUserDownload.tooltip = Check here if you want the other users to download your presentation
bbb.filedownload.title = Download the Presentations
bbb.filedownload.fileLbl = Choose File to Download:
bbb.filedownload.downloadBtn = Download
bbb.filedownload.downloadBtn.toolTip = Download Presentation
bbb.filedownload.thisFileIsDownloadable = File is downloadable
bbb.chat.title = Chat
bbb.chat.quickLink.label = Chat Window
bbb.chat.cmpColorPicker.toolTip = Text Color

View File

@ -271,7 +271,10 @@ package org.bigbluebutton.common
public var pollIcon:Class;
[Embed(source="assets/images/disk.png")]
public var disk:Class;
public var disk:Class;
[Embed(source="assets/images/disk_grayscale.png")]
public var disk_grayscale:Class;
[Embed(source="assets/images/folder.png")]
public var folder:Class;

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

View File

@ -66,8 +66,9 @@ package org.bigbluebutton.modules.present.business
* @param file - The FileReference class of the file we wish to send
*
*/
public function upload(presentationName:String, file:FileReference):void {
public function upload(presentationName:String, file:FileReference, downloadable:Boolean):void {
sendVars.presentation_name = presentationName;
sendVars.is_downloadable = downloadable;
var fileToUpload : FileReference = new FileReference();
fileToUpload = file;

View File

@ -23,6 +23,7 @@ package org.bigbluebutton.modules.present.business
import flash.events.TimerEvent;
import flash.net.NetConnection;
import flash.utils.Timer;
import flash.net.navigateToURL;
import mx.collections.ArrayCollection;
@ -43,6 +44,7 @@ package org.bigbluebutton.modules.present.business
import org.bigbluebutton.modules.present.events.PresenterCommands;
import org.bigbluebutton.modules.present.events.RemovePresentationEvent;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.modules.present.events.DownloadEvent;
import org.bigbluebutton.modules.present.managers.PresentationSlides;
import org.bigbluebutton.modules.present.model.Page;
import org.bigbluebutton.modules.present.model.Presentation;
@ -51,6 +53,11 @@ package org.bigbluebutton.modules.present.business
import org.bigbluebutton.modules.present.services.messaging.MessageReceiver;
import org.bigbluebutton.modules.present.services.messaging.MessageSender;
import flash.events.*;
import flash.net.FileReference;
import flash.net.URLRequest;
import flash.errors.*;
public class PresentProxy {
private static const LOG:String = "Present::PresentProxy - ";
@ -150,9 +157,25 @@ package org.bigbluebutton.modules.present.business
if (uploadService == null) {
uploadService = new FileUploadService(host + "/bigbluebutton/presentation/upload", conference, room);
}
uploadService.upload(e.filename, e.file);
uploadService.upload(e.filename, e.file, e.isDownloadable);
}
/**
* Start downloading the selected file
* @param e
*
*/
public function startDownload(e:DownloadEvent):void {
var presentationName:String = getPresentationName(e.fileNameToDownload)
var downloadUri:String = host + "/bigbluebutton/presentation/" + conference + "/" + room + "/" + presentationName + "/download";
LogUtil.debug("PresentationApplication::downloadPresentation()... " + downloadUri);
var req:URLRequest = new URLRequest(downloadUri);
navigateToURL(req,"_blank");
}
/**
* To to the specified slide
* @param e - The event which holds the slide number

View File

@ -0,0 +1,37 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.present.events
{
import flash.events.Event;
public class DownloadEvent extends Event {
public static const OPEN_DOWNLOAD_WINDOW:String = "OPEN_DOWNLOAD_WINDOW";
public static const CLOSE_DOWNLOAD_WINDOW:String = "CLOSE_DOWNLOAD_WINDOW";
public static const DOWNLOAD_PRESENTATION:String = "DOWNLOAD_PRESENTATION";
public static const UPDATE_FILE_NAMES:String = "UPDATE_FILE_NAMES";
public static const ADD_NEW_FILENAME:String = "ADD_NEW_FILENAME";
public var fileNameToDownload:String;
public function DownloadEvent(type:String) {
super(type, true, false);
}
}
}

View File

@ -33,6 +33,7 @@ package org.bigbluebutton.modules.present.events
public var data:Object;
public var completedSlides:Number;
public var totalSlides:Number;
public var isDownloadable:Boolean;
public var percentageComplete:Number;
public var maximumSupportedNumberOfSlides:int;
public var maxFileSize:Number;

View File

@ -1,91 +1,113 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.present.managers
{
import com.asfusion.mate.events.Dispatcher;
import flash.display.DisplayObject;
import flash.geom.Point;
import mx.collections.ArrayCollection;
import mx.core.*;
import mx.managers.PopUpManager;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.model.users.BBBUser;
import org.bigbluebutton.main.model.users.Conference;
import org.bigbluebutton.main.model.users.events.RoleChangeEvent;
import org.bigbluebutton.modules.present.events.PresentModuleEvent;
import org.bigbluebutton.modules.present.events.RemovePresentationEvent;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.modules.present.model.PresentationModel;
import org.bigbluebutton.modules.present.ui.views.FileUploadWindow;
import org.bigbluebutton.modules.present.ui.views.PresentationWindow;
public class PresentManager
{
private var globalDispatcher:Dispatcher;
private var uploadWindow:FileUploadWindow;
private var presentWindow:PresentationWindow;
public function PresentManager() {
globalDispatcher = new Dispatcher();
}
public function handleStartModuleEvent(e:PresentModuleEvent):void{
if (presentWindow != null){
return;
}
presentWindow = new PresentationWindow();
presentWindow.visible = (e.data.showPresentWindow == "true");
presentWindow.showControls = (e.data.showWindowControls == "true");
openWindow(presentWindow);
}
public function handleStopModuleEvent():void{
presentWindow.close();
}
private function openWindow(window:IBbbModuleWindow):void{
var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.present.managers
{
import com.asfusion.mate.events.Dispatcher;
import flash.display.DisplayObject;
import flash.geom.Point;
import mx.collections.ArrayCollection;
import mx.core.*;
import mx.managers.PopUpManager;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.model.users.BBBUser;
import org.bigbluebutton.main.model.users.Conference;
import org.bigbluebutton.main.model.users.events.RoleChangeEvent;
import org.bigbluebutton.modules.present.events.PresentModuleEvent;
import org.bigbluebutton.modules.present.events.RemovePresentationEvent;
import org.bigbluebutton.modules.present.events.DownloadEvent;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.modules.present.model.PresentationModel;
import org.bigbluebutton.modules.present.ui.views.FileDownloadWindow;
import org.bigbluebutton.modules.present.ui.views.FileUploadWindow;
import org.bigbluebutton.modules.present.ui.views.PresentationWindow;
public class PresentManager
{
private var globalDispatcher:Dispatcher;
private var downloadWindow:FileDownloadWindow;
private var uploadWindow:FileUploadWindow;
private var presentWindow:PresentationWindow;
public function PresentManager() {
globalDispatcher = new Dispatcher();
}
public function handleStartModuleEvent(e:PresentModuleEvent):void{
if (presentWindow != null){
return;
}
presentWindow = new PresentationWindow();
presentWindow.visible = (e.data.showPresentWindow == "true");
presentWindow.showControls = (e.data.showWindowControls == "true");
openWindow(presentWindow);
}
public function handleStopModuleEvent():void{
presentWindow.close();
}
private function openWindow(window:IBbbModuleWindow):void{
var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function handleOpenUploadWindow(e:UploadEvent):void{
if (uploadWindow != null) return;
uploadWindow = FileUploadWindow(PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, FileUploadWindow, true));
uploadWindow.maxFileSize = e.maxFileSize;
var point1:Point = new Point();
point1.x = FlexGlobals.topLevelApplication.width / 2;
point1.y = FlexGlobals.topLevelApplication.height / 2;
uploadWindow.x = point1.x - (uploadWindow.width/2);
uploadWindow.y = point1.y - (uploadWindow.height/2);
}
public function handleCloseUploadWindow():void{
PopUpManager.removePopUp(uploadWindow);
uploadWindow = null;
}
}
}
public function handleOpenDownloadWindow():void{
if (downloadWindow != null) return;
downloadWindow = new FileDownloadWindow();
var width:int = Application(FlexGlobals.topLevelApplication).systemManager.screen.width;
var height:int = Application(FlexGlobals.topLevelApplication).systemManager.screen.height;
downloadWindow.x = (width - downloadWindow.width) / 2;
downloadWindow.y = (height - downloadWindow.height) / 2;
mx.managers.PopUpManager.addPopUp(downloadWindow, presentWindow, true);
}
public function handleCloseDownloadWindow():void{
PopUpManager.removePopUp(downloadWindow);
downloadWindow = null;
}
public function handleOpenUploadWindow(e:UploadEvent):void{
if (uploadWindow != null) return;
uploadWindow = FileUploadWindow(PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, FileUploadWindow, true));
uploadWindow.maxFileSize = e.maxFileSize;
var point1:Point = new Point();
point1.x = FlexGlobals.topLevelApplication.width / 2;
point1.y = FlexGlobals.topLevelApplication.height / 2;
uploadWindow.x = point1.x - (uploadWindow.width/2);
uploadWindow.y = point1.y - (uploadWindow.height/2);
}
public function handleCloseUploadWindow():void{
PopUpManager.removePopUp(uploadWindow);
uploadWindow = null;
}
}
}

View File

@ -40,6 +40,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.present.events.PresentationEvent;
import org.bigbluebutton.modules.present.events.PresenterCommands;
import org.bigbluebutton.modules.present.events.RemovePresentationEvent;
import org.bigbluebutton.modules.present.events.DownloadEvent;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.modules.present.managers.PresentManager;
import org.bigbluebutton.modules.present.services.PageLoaderService;
@ -70,6 +71,18 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<EventHandlers type="{PresentModuleEvent.STOP_MODULE}" >
<MethodInvoker generator="{PresentManager}" method="handleStopModuleEvent" />
</EventHandlers>
<EventHandlers type="{DownloadEvent.OPEN_DOWNLOAD_WINDOW}" >
<MethodInvoker generator="{PresentManager}" method="handleOpenDownloadWindow" />
</EventHandlers>
<EventHandlers type="{DownloadEvent.CLOSE_DOWNLOAD_WINDOW}" >
<MethodInvoker generator="{PresentManager}" method="handleCloseDownloadWindow" />
</EventHandlers>
<EventHandlers type="{DownloadEvent.DOWNLOAD_PRESENTATION}" >
<MethodInvoker generator="{PresentProxy}" method="startDownload" arguments="{event}" />
</EventHandlers>
<EventHandlers type="{UploadEvent.OPEN_UPLOAD_WINDOW}" >
<MethodInvoker generator="{PresentManager}" method="handleOpenUploadWindow" arguments="{event}" />

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" width="90%" verticalAlign="middle">
<mx:Script>
<![CDATA[
import org.bigbluebutton.common.LogUtil;
import com.asfusion.mate.events.Dispatcher;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.modules.present.events.DownloadEvent;
private var globalDispatch:Dispatcher = new Dispatcher();
private function downloadPresentation():void {
LogUtil.debug("FileDownloadWindow::downloadPresentation() " + data);
var downloadEvent:DownloadEvent = new DownloadEvent(DownloadEvent.DOWNLOAD_PRESENTATION);
downloadEvent.fileNameToDownload = data as String;
globalDispatch.dispatchEvent(downloadEvent);
}
]]>
</mx:Script>
<mx:Label id="presentationNameLabel" text="{data as String}" styleName="presentationNameLabelStyle" width="80%"/>
<mx:Button id="downloadBtn" label="{ResourceUtil.getInstance().getString('bbb.filedownload.downloadBtn')}"
toolTip="{ResourceUtil.getInstance().getString('bbb.filedownload.downloadBtn')}"
styleName="presentationUploadShowButtonStyle"
click="downloadPresentation()" enabled="true"/>
</mx:HBox>

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3.0 of the License, or (at your option) any later
version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
x="168" y="86" layout="absolute" width="700" height="410" styleName="presentationFileUploadWindowStyle"
initialize="initData();">
<mate:Dispatcher id="globalDispatch" />
<mx:Script>
<![CDATA[
import org.bigbluebutton.common.LogUtil;
import com.asfusion.mate.events.Dispatcher;
import mx.collections.*;
import mx.events.FlexEvent;
import mx.events.ValidationResultEvent;
import mx.managers.PopUpManager;
import mx.utils.*;
import mx.validators.*;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.modules.present.events.RemovePresentationEvent;
import org.bigbluebutton.modules.present.events.DownloadEvent
import org.bigbluebutton.util.i18n.ResourceUtil;
[Bindable] public var fileNamesToDownload:ArrayCollection;
override public function move(x:Number, y:Number):void
{
return;
}
private function initData():void {
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:Label text="{ResourceUtil.getInstance().getString('bbb.filedownload.title')}" styleName="presentationUploadTitleStyle"/>
<mx:Spacer height="10"/>
<mx:HBox width="100%">
<mx:Spacer height="5"/>
<mx:Label id="fileLbl" text="{ResourceUtil.getInstance().getString('bbb.filedownload.fileLbl')}" styleName="presentationUploadChooseFileLabelStyle"/>
<mx:Spacer width="100%"/>
</mx:HBox>
<mx:Spacer height="5"/>
<mx:HBox width="90%" height="200">
<mx:Spacer width="10"/>
<mx:List id="presentationNamesList" width="90%" height="200" alternatingItemColors="[#EFEFEF, #FEFEFE]" allowMultipleSelection="false"
itemRenderer="org.bigbluebutton.modules.present.ui.views.DownloadPresentationRenderer"
dragEnabled="false" dataProvider="{fileNamesToDownload}">
</mx:List>
</mx:HBox>
<mx:Spacer height="5"/>
<mx:HBox width="100%">
<mx:Spacer width="100%"/>
<mx:Button id="okCancelBtn" label="{ResourceUtil.getInstance().getString('bbb.fileupload.okCancelBtn')}"
styleName="presentationUploadCancelButtonStyle"
click="globalDispatch.dispatchEvent(new DownloadEvent(DownloadEvent.CLOSE_DOWNLOAD_WINDOW))"
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.okCancelBtn.toolTip')}"/>
<mx:Spacer width="5"/>
</mx:HBox>
</mx:VBox>
</mx:TitleWindow>

View File

@ -22,7 +22,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
layout="absolute" width="580" height="400" styleName="presentationFileUploadWindowStyle"
layout="absolute" width="580" height="415" styleName="presentationFileUploadWindowStyle"
initialize="initData();">
<mate:Dispatcher id="globalDispatch" />
@ -172,12 +172,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
progBarLbl.visible = true;
lblFileName.enabled = false;
var isDownloadable:Boolean = new Boolean(letUserDownload.selected);
var uploadCmd:UploadFileCommand = new UploadFileCommand();
uploadCmd.filename = presentationName;
uploadCmd.file = fileToUpload;
globalDispatch.dispatchEvent(uploadCmd);
letUserDownload.visible = false;
}
}
@ -258,6 +260,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
selectBtn.enabled = true;
uploadBtn.enabled = true;
lblFileName.enabled = true;
letUserDownload.visible = true;
}
private function handleConvertUpdate(e:ConversionUpdateEvent):void{
@ -303,7 +306,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.uploadBtn.toolTip')}" click="startUpload()"
enabled="false" icon="{bulletGoIcon}"/>
</mx:HBox>
<mx:HBox id="progressReportBox" width="100%" paddingLeft="10" paddingTop="5" paddingBottom="10" includeInLayout="true" visible="false">
<mx:HBox>
<mx:Spacer width="3"/>
<mx:CheckBox id="letUserDownload" label="{ResourceUtil.getInstance().getString('bbb.fileupload.letUserDownload')}" selected="true" toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.letUserDownload.tooltip')}"/>
</mx:HBox>
<mx:HBox id="progressReportBox" width="100%" paddingLeft="10" paddingTop="0" paddingBottom="5" includeInLayout="true" visible="false">
<mx:Label id="progBarLbl" text="{ResourceUtil.getInstance().getString('bbb.fileupload.progBarLbl')}"
styleName="presentationUploadProgressBarLabelStyle" visible="false"/>
<mx:ProgressBar id="progressBar" mode="manual" label="{ResourceUtil.getInstance().getString('bbb.fileupload.progBarLbl')}"

View File

@ -92,6 +92,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.present.events.PresentationEvent;
import org.bigbluebutton.modules.present.events.PresenterCommands;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.modules.present.events.DownloadEvent;
import org.bigbluebutton.modules.present.events.WindowResizedEvent;
import org.bigbluebutton.modules.present.managers.Slide;
import org.bigbluebutton.modules.present.model.Page;
@ -155,6 +156,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
minimizeBtn.tabIndex = baseIndex+1;
maximizeRestoreBtn.tabIndex = baseIndex+2;
closeBtn.tabIndex = baseIndex+3;
var images:Images = new Images();
downloadPres.setStyle("icon", images.disk_grayscale);
slideView.slideLoader.tabIndex = baseIndex+4;
hotkeyCapture();
@ -357,6 +361,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function setupPresenter(isPresenter:Boolean):void {
uploadPres.visible = isPresenter;
downloadPres.visible = true;
var page:Page = PresentationModel.getInstance().getCurrentPage();
if (page != null) {
displaySlideNumber(page.num);
@ -591,6 +596,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
onFitToPage(true);
}
}
private function onDownloadButtonClicked():void {
openDownloadWindow();
}
private function openDownloadWindow():void {
var event:DownloadEvent = new DownloadEvent(DownloadEvent.OPEN_DOWNLOAD_WINDOW);
dispatchEvent(event);
}
private function onUploadButtonClicked():void {
openUploadWindow();
@ -618,6 +633,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<views:SlideView id="slideView" width="100%" height="100%" visible="false" mouseDown="mouseDown = true"
mouseUp="mouseDown = false" verticalScrollPolicy="off" horizontalScrollPolicy="off" tabIndex="{baseIndex+4}"/>
<mx:ControlBar id="presCtrlBar" name="presCtrlBar" width="100%" height="{CONTROL_BAR_HEIGHT}" styleName="presentationWindowControlsStyle" >
<mx:Button id="downloadPres" visible="true" height="30"
toolTip="{ResourceUtil.getInstance().getString('bbb.presentation.downloadPresBtn.toolTip')}"
click="onDownloadButtonClicked()" tabIndex="{baseIndex+5}"/>
<mx:Button id="uploadPres" visible="false" height="30" styleName="presentationUploadButtonStyle"
toolTip="{ResourceUtil.getInstance().getString('bbb.presentation.uploadPresBtn.toolTip')}"
click="onUploadButtonClicked()" tabIndex="{baseIndex+5}"/>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="90%"
creationComplete="onCreationComplete()"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
toolTip="{data as String}"
@ -13,9 +14,16 @@
import org.bigbluebutton.modules.present.events.RemovePresentationEvent;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.common.Images;
private var globalDispatch:Dispatcher = new Dispatcher();
private function onCreationComplete():void {
var images:Images = new Images();
isDownloadable.source = images.disk_grayscale;
}
private function showPresentation():void {
trace("FileUploadWindow::showPresentation() " + data.id);
var changePresCommand:ChangePresentationCommand = new ChangePresentationCommand(data.id);
@ -34,6 +42,9 @@
]]>
</mx:Script>
<mx:Label id="presentationNameLabel" width="{this.width-showBtn.width-deleteBtn.width-30}" text="{data.name as String}" styleName="presentationNameLabelStyle"/>
<mx:Image id="isDownloadable" visible="{data.isDownloadable as Boolean}"
toolTip="{ResourceUtil.getInstance().getString('bbb.filedownload.thisFileIsDownloadable')}"
verticalAlign="middle" />
<mx:Button id="showBtn" label="{ResourceUtil.getInstance().getString('bbb.fileupload.showBtn')}"
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.showBtn.toolTip')}"
styleName="presentationUploadShowButtonStyle" height="26"

View File

@ -1,61 +1,65 @@
class UrlMappings {
static mappings = {
"/presentation/upload"(controller:"presentation") {
action = [GET:'show', POST:'upload', DELETE:'delete']
}
"/presentation/test-convert"(controller:"presentation") {
action = [GET:'testConversion']
}
"/presentation/$conference/$room/$presentation_name/slides"(controller:"presentation") {
action = [GET:'numberOfSlides']
}
"/presentation/$conference/$room/$presentation_name/slide/$id"(controller:"presentation") {
action = [GET:'showSlide']
}
"/presentation/$conference/$room/$presentation_name/thumbnails"(controller:"presentation") {
action = [GET:'numberOfThumbnails']
}
"/presentation/$conference/$room/$presentation_name/thumbnail/$id"(controller:"presentation") {
action = [GET:'showThumbnail']
}
"/presentation/$conference/$room/$presentation_name/textfiles"(controller:"presentation") {
action = [GET:'numberOfTextfiles']
}
"/presentation/$conference/$room/$presentation_name/textfile/$id"(controller:"presentation") {
action = [GET:'showTextfile']
}
"/api/setConfigXML"(controller:"api") {
action = [POST:'setConfigXML']
}
"/api/setPollXML"(controller:"api") {
action = [POST:'setPollXML']
}
"/api/getMeetings"(controller:"api") {
action = [GET:'getMeetingsHandler']
}
"/api/getRecordings"(controller:"api") {
action = [GET:'getRecordingsHandler']
}
"/$controller/$action?/$id?(.${format})?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
}
class UrlMappings {
static mappings = {
"/presentation/upload"(controller:"presentation") {
action = [GET:'show', POST:'upload', DELETE:'delete']
}
"/presentation/test-convert"(controller:"presentation") {
action = [GET:'testConversion']
}
"/presentation/$conference/$room/$presentation_name/slides"(controller:"presentation") {
action = [GET:'numberOfSlides']
}
"/presentation/$conference/$room/$presentation_name/slide/$id"(controller:"presentation") {
action = [GET:'showSlide']
}
"/presentation/$conference/$room/$presentation_name/thumbnails"(controller:"presentation") {
action = [GET:'numberOfThumbnails']
}
"/presentation/$conference/$room/$presentation_name/thumbnail/$id"(controller:"presentation") {
action = [GET:'showThumbnail']
}
"/presentation/$conference/$room/$presentation_name/textfiles"(controller:"presentation") {
action = [GET:'numberOfTextfiles']
}
"/presentation/$conference/$room/$presentation_name/textfile/$id"(controller:"presentation") {
action = [GET:'showTextfile']
}
"/presentation/$conference/$room/$presentation_name/download"(controller:"presentation") {
action = [GET:'downloadFile']
}
"/api/setConfigXML"(controller:"api") {
action = [POST:'setConfigXML']
}
"/api/setPollXML"(controller:"api") {
action = [POST:'setPollXML']
}
"/api/getMeetings"(controller:"api") {
action = [GET:'getMeetingsHandler']
}
"/api/getRecordings"(controller:"api") {
action = [GET:'getRecordingsHandler']
}
"/$controller/$action?/$id?(.${format})?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
}

View File

@ -79,10 +79,29 @@ class PresentationController {
def newFilename = Util.createNewFilename(presId, filenameExt)
def pres = new File(uploadDir.absolutePath + File.separatorChar + newFilename )
file.transferTo(pres)
def isDownloadable = params.boolean('is_downloadable') //instead of params.is_downloadable
if(isDownloadable) {
log.debug "@Creating download directory..."
File downloadDir = presentationService.downloadPresentationDirectory(uploadDir.absolutePath)
if (downloadDir != null) {
def notValidCharsRegExp = /[^0-9a-zA-Z_\.]/
def downloadableFileName = presFilename.replaceAll(notValidCharsRegExp, '-')
def downloadableFile = new File( downloadDir.absolutePath + File.separatorChar + downloadableFileName )
downloadableFile << pres.newInputStream()
}
}
def presentationBaseUrl = presentationService.presentationBaseUrl
UploadedPresentation uploadedPres = new UploadedPresentation(meetingId, presId, presFilename, presentationBaseUrl);
uploadedPres.setUploadedFile(pres);
if(isDownloadable) {
log.debug "@Setting file to be downloadable..."
uploadedPres.setDownloadable();
}
uploadedPres.setUploadedFile(pres);
presentationService.processUploadedPresentation(uploadedPres)
}
} else {
@ -211,6 +230,33 @@ class PresentationController {
return null;
}
def downloadFile = {
def presentationName = params.presentation_name
def conf = params.conference
def rm = params.room
println "Controller: Download request for $presentationName"
InputStream is = null;
try {
def pres = presentationService.getFile(conf, rm, presentationName)
if (pres.exists()) {
println "Controller: Sending pdf reply for $presentationName"
def bytes = pres.readBytes()
def responseName = pres.getName();
response.addHeader("content-disposition", "filename=$responseName")
response.addHeader("Cache-Control", "no-cache")
response.outputStream << bytes;
} else {
println "$pres does not exist."
}
} catch (IOException e) {
println("Error reading file.\n" + e.getMessage());
}
return null;
}
def show = {
//def filename = params.id.replace('###', '.')

View File

@ -16,15 +16,15 @@
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.web.services
import java.util.concurrent.*;
package org.bigbluebutton.web.services
import java.util.concurrent.*;
import java.lang.InterruptedException
import org.bigbluebutton.presentation.DocumentConversionService
import org.bigbluebutton.presentation.UploadedPresentation
class PresentationService {
class PresentationService {
static transactional = false
DocumentConversionService documentConversionService
def presentationDir
@ -34,81 +34,89 @@ class PresentationService {
def testUploadedPresentation
def defaultUploadedPresentation
def presentationBaseUrl
def deletePresentation = {conf, room, filename ->
def directory = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + filename)
deleteDirectory(directory)
}
def deleteDirectory = {directory ->
log.debug "delete = ${directory}"
/**
* Go through each directory and check if it's not empty.
* We need to delete files inside a directory before a
* directory can be deleted.
**/
File[] files = directory.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i])
} else {
files[i].delete()
}
}
// Now that the directory is empty. Delete it.
directory.delete()
}
def listPresentations = {conf, room ->
def presentationsList = []
def directory = roomDirectory(conf, room)
log.debug "directory ${directory.absolutePath}"
if( directory.exists() ){
directory.eachFile(){ file->
System.out.println(file.name)
if( file.isDirectory() )
presentationsList.add( file.name )
}
}
return presentationsList
}
def deletePresentation = {conf, room, filename ->
def directory = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + filename)
deleteDirectory(directory)
}
def deleteDirectory = {directory ->
log.debug "delete = ${directory}"
/**
* Go through each directory and check if it's not empty.
* We need to delete files inside a directory before a
* directory can be deleted.
**/
File[] files = directory.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i])
} else {
files[i].delete()
}
}
// Now that the directory is empty. Delete it.
directory.delete()
}
def listPresentations = {conf, room ->
def presentationsList = []
def directory = roomDirectory(conf, room)
log.debug "directory ${directory.absolutePath}"
if( directory.exists() ){
directory.eachFile(){ file->
System.out.println(file.name)
if( file.isDirectory() )
presentationsList.add( file.name )
}
}
return presentationsList
}
def getPresentationDir = {
return presentationDir
}
def processUploadedPresentation = {uploadedPres ->
}
public File downloadPresentationDirectory(String uploadDirectory) {
File dir = new File(uploadDirectory + File.separatorChar + "download")
dir.mkdirs()
assert dir.exists()
return dir
}
def processUploadedPresentation = {uploadedPres ->
// Run conversion on another thread.
Timer t = new Timer(uploadedPres.getName(), false)
t.runAfter(1000) {
t.runAfter(1000) {
try {
documentConversionService.processDocument(uploadedPres)
} finally {
t.cancel()
}
}
}
def showSlide(String conf, String room, String presentationName, String id) {
new File(roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar + "slide-${id}.swf")
}
}
def showSlide(String conf, String room, String presentationName, String id) {
new File(roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar + "slide-${id}.swf")
}
def showPngImage(String conf, String room, String presentationName, String id) {
new File(roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar + "pngs" + File.separatorChar + id)
}
def showPresentation = {conf, room, filename ->
new File(roomDirectory(conf, room).absolutePath + File.separatorChar + filename + File.separatorChar + "slides.swf")
}
}
def showPresentation = {conf, room, filename ->
new File(roomDirectory(conf, room).absolutePath + File.separatorChar + filename + File.separatorChar + "slides.swf")
}
def showThumbnail = {conf, room, presentationName, thumb ->
println "Show thumbnails request for $presentationName $thumb"
def thumbFile = roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar +
"thumbnails" + File.separatorChar + "thumb-${thumb}.png"
log.debug "showing $thumbFile"
new File(thumbFile)
println "Show thumbnails request for $presentationName $thumb"
def thumbFile = roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar +
"thumbnails" + File.separatorChar + "thumb-${thumb}.png"
log.debug "showing $thumbFile"
new File(thumbFile)
}
def showTextfile = {conf, room, presentationName, textfile ->
@ -118,19 +126,32 @@ class PresentationService {
log.debug "showing $txt"
new File(txt)
}
def numberOfThumbnails = {conf, room, name ->
def thumbDir = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + name + File.separatorChar + "thumbnails")
thumbDir.listFiles().length
}
def getFile = {conf, room, presentationName ->
println "download request for $presentationName"
def fileDirectory = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + presentationName + File.separatorChar +
"download")
//list the files of the download directory ; it must have only 1 file to download
def list = fileDirectory.listFiles()
//new File(pdfFile)
list[0]
}
def numberOfThumbnails = {conf, room, name ->
def thumbDir = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + name + File.separatorChar + "thumbnails")
thumbDir.listFiles().length
}
def numberOfTextfiles = {conf, room, name ->
log.debug roomDirectory(conf, room).absolutePath + File.separatorChar + name + File.separatorChar + "textfiles"
def textfilesDir = new File(roomDirectory(conf, room).absolutePath + File.separatorChar + name + File.separatorChar + "textfiles")
textfilesDir.listFiles().length
}
}
def roomDirectory = {conf, room ->
return new File(presentationDir + File.separatorChar + conf + File.separatorChar + room)
}
@ -156,14 +177,14 @@ class PresentationService {
}
}
}
/*** Helper classes **/
import java.io.FilenameFilter;
import java.io.File;
class PngFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return (name.endsWith(".png"));
}
}
/*** Helper classes **/
import java.io.FilenameFilter;
import java.io.File;
class PngFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return (name.endsWith(".png"));
}
}

View File

@ -44,6 +44,7 @@ public class ConversionUpdateMessage {
message.put("presentationName", pres.getId());
message.put("presentationId", pres.getId());
message.put("filename", pres.getName());
message.put("presDownloadable", pres.isDownloadable());
}
public MessageBuilder entry(String key, Object value) {

View File

@ -30,6 +30,7 @@ public final class UploadedPresentation {
private int numberOfPages = 0;
private boolean lastStepSuccessful = false;
private final String baseUrl;
private boolean isDownloadable = false;
public UploadedPresentation(String meetingId, String id,
String name,
@ -38,6 +39,15 @@ public final class UploadedPresentation {
this.id = id;
this.name = name;
this.baseUrl = baseUrl;
this.isDownloadable = false;
}
public boolean isDownloadable() {
return isDownloadable;
}
public void setDownloadable() {
this.isDownloadable = true;
}
public File getUploadedFile() {