Merge branch 'broadcast-layout' of github.com:mconf/bigbluebutton into broadcast-layout

Conflicts:
	bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/layout/LayoutApplication.java
	bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/layout/LayoutService.java
	bigbluebutton-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java
	bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala
	bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala
	bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/layout/LayoutApp.scala
	bigbluebutton-client/src/org/bigbluebutton/modules/layout/events/LayoutEvent.as
	bigbluebutton-client/src/org/bigbluebutton/modules/layout/services/LayoutService.as
	bigbluebutton-client/src/org/bigbluebutton/modules/layout/services/MessageReceiver.as
This commit is contained in:
Richard Alam 2014-05-29 11:21:01 -07:00
commit 04c271996d
22 changed files with 184 additions and 112 deletions

View File

@ -19,7 +19,7 @@
package org.bigbluebutton.conference.service.layout; package org.bigbluebutton.conference.service.layout;
import org.bigbluebutton.core.api.IBigBlueButtonInGW; import org.bigbluebutton.core.api.IBigBlueButtonInGW;
public class LayoutApplication { public class LayoutApplication {
private IBigBlueButtonInGW bbbInGW; private IBigBlueButtonInGW bbbInGW;
@ -31,8 +31,8 @@ public class LayoutApplication {
bbbInGW.syncLayout(meetingID, requesterID, layoutID); bbbInGW.syncLayout(meetingID, requesterID, layoutID);
} }
public void lockLayout(String meetingID, String requesterID, String layoutID) { public void broadcastLayout(String meetingID, String requesterID, String layoutID, Boolean locked) {
bbbInGW.lockLayout(meetingID, requesterID, layoutID); bbbInGW.broadcastLayout(meetingID, requesterID, layoutID, locked);
} }
public void unlockLayout(String meetingID, String requesterID) { public void unlockLayout(String meetingID, String requesterID) {

View File

@ -25,7 +25,7 @@ import org.bigbluebutton.conference.Constants;
import org.red5.logging.Red5LoggerFactory; import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.Red5; import org.red5.server.api.Red5;
import org.slf4j.Logger; import org.slf4j.Logger;
public class LayoutService { public class LayoutService {
private static Logger log = Red5LoggerFactory.getLogger( LayoutService.class, "bigbluebutton" ); private static Logger log = Red5LoggerFactory.getLogger( LayoutService.class, "bigbluebutton" );
@ -43,9 +43,9 @@ public class LayoutService {
application.syncLayout(meetingID, getBbbSession().getInternalUserID(), (String) message.get("layout")); application.syncLayout(meetingID, getBbbSession().getInternalUserID(), (String) message.get("layout"));
} }
public void lock(Map<String, Object> message) { public void broadcast(Map<String, Object> message) {
String meetingID = Red5.getConnectionLocal().getScope().getName(); String meetingID = Red5.getConnectionLocal().getScope().getName();
application.lockLayout(meetingID, (String) message.get("setByUserID"), (String) message.get("layout")); application.broadcastLayout(meetingID, (String) message.get("setByUserID"), (String) message.get("layout"), (Boolean) message.get("locked"));
} }
public void unlock() { public void unlock() {

View File

@ -95,7 +95,7 @@ public interface IBigBlueButtonInGW {
void getCurrentLayout(String meetingID, String requesterID); void getCurrentLayout(String meetingID, String requesterID);
void setLayout(String meetingID, String requesterID, String layoutID); void setLayout(String meetingID, String requesterID, String layoutID);
void syncLayout(String meetingID, String requesterID, String layoutID); void syncLayout(String meetingID, String requesterID, String layoutID);
void lockLayout(String meetingID, String requesterID, String layoutID); void broadcastLayout(String meetingID, String requesterID, String layoutID, Boolean locked);
void unlockLayout(String meetingID, String requesterID); void unlockLayout(String meetingID, String requesterID);
// Chat // Chat

View File

@ -37,7 +37,7 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway) extends IBigBlueButtonInGW
bbbGW.accept(new PreuploadedPresentations(meetingID, presentations.values.toSeq)) bbbGW.accept(new PreuploadedPresentations(meetingID, presentations.values.toSeq))
} }
*/ */
} }
@ -349,8 +349,8 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway) extends IBigBlueButtonInGW
layoutGW.setLayout(meetingID, requesterID, layoutID) layoutGW.setLayout(meetingID, requesterID, layoutID)
} }
def lockLayout(meetingID: String, requesterID: String, layoutID: String) { def broadcastLayout(meetingID: String, requesterID: String, layoutID: String, locked: java.lang.Boolean) {
layoutGW.lockLayout(meetingID, requesterID, layoutID) layoutGW.broadcastLayout(meetingID, requesterID, layoutID, locked)
} }
def unlockLayout(meetingID: String, requesterID: String) { def unlockLayout(meetingID: String, requesterID: String) {
@ -461,4 +461,4 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway) extends IBigBlueButtonInGW
voiceGW.voiceRecording(meetingId, recordingFile, voiceGW.voiceRecording(meetingId, recordingFile,
timestamp, recording) timestamp, recording)
} }
} }

View File

@ -52,7 +52,7 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
case msg: SendPrivateMessageRequest => handleSendPrivateMessageRequest(msg) case msg: SendPrivateMessageRequest => handleSendPrivateMessageRequest(msg)
case msg: GetCurrentLayoutRequest => handleGetCurrentLayoutRequest(msg) case msg: GetCurrentLayoutRequest => handleGetCurrentLayoutRequest(msg)
case msg: SetLayoutRequest => handleSetLayoutRequest(msg) case msg: SetLayoutRequest => handleSetLayoutRequest(msg)
case msg: LockLayoutRequest => handleLockLayoutRequest(msg) case msg: BroadcastLayoutRequest => handleBroadcastLayoutRequest(msg)
case msg: UnlockLayoutRequest => handleUnlockLayoutRequest(msg) case msg: UnlockLayoutRequest => handleUnlockLayoutRequest(msg)
case msg: PreCreatedPoll => handlePreCreatedPoll(msg) case msg: PreCreatedPoll => handlePreCreatedPoll(msg)
case msg: CreatePoll => handleCreatePoll(msg) case msg: CreatePoll => handleCreatePoll(msg)
@ -144,7 +144,7 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
case msg: SendPrivateMessageEvent => handleSendPrivateMessageEvent(msg) case msg: SendPrivateMessageEvent => handleSendPrivateMessageEvent(msg)
case msg: GetCurrentLayoutReply => handleGetCurrentLayoutReply(msg) case msg: GetCurrentLayoutReply => handleGetCurrentLayoutReply(msg)
case msg: SetLayoutEvent => handleSetLayoutEvent(msg) case msg: SetLayoutEvent => handleSetLayoutEvent(msg)
case msg: LockLayoutEvent => handleLockLayoutEvent(msg) case msg: BroadcastLayoutEvent => handleBroadcastLayoutEvent(msg)
case msg: UnlockLayoutEvent => handleUnlockLayoutEvent(msg) case msg: UnlockLayoutEvent => handleUnlockLayoutEvent(msg)
case msg: GetPollResultReply => handleGetPollResultReply(msg) case msg: GetPollResultReply => handleGetPollResultReply(msg)
case msg: GetPollsReplyOutMsg => handleGetPollsReplyOutMsg(msg) case msg: GetPollsReplyOutMsg => handleGetPollsReplyOutMsg(msg)
@ -644,17 +644,18 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
dispatcher.dispatch(buildJson(header, payload)) dispatcher.dispatch(buildJson(header, payload))
} }
private def handleLockLayoutRequest(msg: LockLayoutRequest) { private def handleBroadcastLayoutRequest(msg: BroadcastLayoutRequest) {
val payload = new java.util.HashMap[String, Any]() val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID) payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.REQUESTER_ID, msg.requesterID) payload.put(Constants.REQUESTER_ID, msg.requesterID)
payload.put(Constants.LAYOUT_ID, msg.layoutID) payload.put(Constants.LAYOUT_ID, msg.layoutID)
payload.put(Constants.LOCKED, msg.locked)
val header = new java.util.HashMap[String, Any]() val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.LOCK_LAYOUT) header.put(Constants.NAME, MessageNames.BROADCAST_LAYOUT)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp) header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
println("***** DISPATCHING LOCK LAYOUT REQUEST *****************") println("***** DISPATCHING BROADCAST LAYOUT REQUEST *****************")
dispatcher.dispatch(buildJson(header, payload)) dispatcher.dispatch(buildJson(header, payload))
} }
@ -1812,7 +1813,7 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
dispatcher.dispatch(buildJson(header, payload)) dispatcher.dispatch(buildJson(header, payload))
} }
private def handleLockLayoutEvent(msg: LockLayoutEvent) { private def handleBroadcastLayoutEvent(msg: BroadcastLayoutEvent) {
val payload = new java.util.HashMap[String, Any]() val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID) payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.RECORDED, msg.recorded) payload.put(Constants.RECORDED, msg.recorded)
@ -1822,10 +1823,10 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
payload.put(Constants.SET_BY_USER_ID, msg.setByUserID) payload.put(Constants.SET_BY_USER_ID, msg.setByUserID)
val header = new java.util.HashMap[String, Any]() val header = new java.util.HashMap[String, Any]()
header.put(Constants.NAME, MessageNames.LOCK_LAYOUT_REPLY) header.put(Constants.NAME, MessageNames.BROADCAST_LAYOUT_REPLY)
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp) header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
println("***** DISPATCHING LOCK LAYOUT EVENT *****************") println("***** DISPATCHING BROADCAST LAYOUT EVENT *****************")
dispatcher.dispatch(buildJson(header, payload)) dispatcher.dispatch(buildJson(header, payload))
} }
@ -2132,4 +2133,4 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
val json = WhiteboardMessageToJsonConverter.isWhiteboardEnabledReplyToJson(msg) val json = WhiteboardMessageToJsonConverter.isWhiteboardEnabledReplyToJson(msg)
dispatcher.dispatch(json) dispatcher.dispatch(json)
} }
} }

View File

@ -72,10 +72,10 @@ class MeetingActor(val meetingID: String, meetingName: String, val recorded: Boo
case msg: UserConnectedToGlobalAudio => handleUserConnectedToGlobalAudio(msg) case msg: UserConnectedToGlobalAudio => handleUserConnectedToGlobalAudio(msg)
case msg: UserDisconnectedFromGlobalAudio => handleUserDisconnectedFromGlobalAudio(msg) case msg: UserDisconnectedFromGlobalAudio => handleUserDisconnectedFromGlobalAudio(msg)
case msg: GetCurrentLayoutRequest => handleGetCurrentLayoutRequest(msg) case msg: GetCurrentLayoutRequest => handleGetCurrentLayoutRequest(msg)
case msg: LayoutLockSettings => handleLayoutLockSettings(msg) // case msg: LayoutLockSettings => handleLayoutLockSettings(msg)
case msg: SetLayoutRequest => handleSetLayoutRequest(msg) case msg: SetLayoutRequest => handleSetLayoutRequest(msg)
case msg: LockLayoutRequest => handleLockLayoutRequest(msg) case msg: BroadcastLayoutRequest => handleBroadcastLayoutRequest(msg)
case msg: UnlockLayoutRequest => handleUnlockLayoutRequest(msg) // case msg: UnlockLayoutRequest => handleUnlockLayoutRequest(msg)
case msg: InitializeMeeting => handleInitializeMeeting(msg) case msg: InitializeMeeting => handleInitializeMeeting(msg)
case msg: ClearPresentation => handleClearPresentation(msg) case msg: ClearPresentation => handleClearPresentation(msg)
case msg: PresentationConversionUpdate => handlePresentationConversionUpdate(msg) case msg: PresentationConversionUpdate => handlePresentationConversionUpdate(msg)

View File

@ -201,10 +201,11 @@ case class LayoutLockSettings(
locked: Boolean locked: Boolean
) extends InMessage ) extends InMessage
case class LockLayoutRequest( case class BroadcastLayoutRequest(
meetingID: String, meetingID: String,
requesterID: String, requesterID: String,
layoutID: String layoutID: String,
locked: Boolean
) extends InMessage ) extends InMessage
case class UnlockLayoutRequest( case class UnlockLayoutRequest(

View File

@ -30,7 +30,7 @@ object MessageNames {
val SEND_PRIVATE_MESSAGE = "send_private_chat_message_request" val SEND_PRIVATE_MESSAGE = "send_private_chat_message_request"
val GET_CURRENT_LAYOUT = "get_current_layout_request" val GET_CURRENT_LAYOUT = "get_current_layout_request"
val SET_LAYOUT = "set_layout_request" val SET_LAYOUT = "set_layout_request"
val LOCK_LAYOUT = "lock_layout_request" val BROADCAST_LAYOUT = "broadcast_layout_request"
val UNLOCK_LAYOUT = "unlock_layout_request" val UNLOCK_LAYOUT = "unlock_layout_request"
val PRECREATED_POLL = "precreated_poll_request" val PRECREATED_POLL = "precreated_poll_request"
val CREATE_POLL = "create_poll_request" val CREATE_POLL = "create_poll_request"
@ -121,7 +121,7 @@ object MessageNames {
val SEND_PRIVATE_CHAT_MESSAGE = "send_private_chat_message" val SEND_PRIVATE_CHAT_MESSAGE = "send_private_chat_message"
val GET_CURRENT_LAYOUT_REPLY = "get_current_layout_reply" val GET_CURRENT_LAYOUT_REPLY = "get_current_layout_reply"
val SET_LAYOUT_REPLY = "set_layout_reply" val SET_LAYOUT_REPLY = "set_layout_reply"
val LOCK_LAYOUT_REPLY = "lock_layout_reply" val BROADCAST_LAYOUT_REPLY = "broadcast_layout_reply"
val UNLOCK_LAYOUT_REPLY = "unlock_layout_reply" val UNLOCK_LAYOUT_REPLY = "unlock_layout_reply"
val GET_POLL_RESULT_REPLY = "get_poll_result_reply" val GET_POLL_RESULT_REPLY = "get_poll_result_reply"
val POLL_CLEARED = "poll_cleared_message" val POLL_CLEARED = "poll_cleared_message"

View File

@ -345,7 +345,7 @@ case class SetLayoutEvent(
applyTo: Array[UserVO] applyTo: Array[UserVO]
) extends IOutMessage ) extends IOutMessage
case class LockLayoutEvent( case class BroadcastLayoutEvent(
meetingID: String, meetingID: String,
recorded: Boolean, recorded: Boolean,
requesterID: String, requesterID: String,

View File

@ -9,9 +9,9 @@ trait LayoutApp {
val outGW: MessageOutGateway val outGW: MessageOutGateway
private var _locked:Boolean = false; private var _locked:Boolean = false;
private var _setByUserID:String = "system"; private var _setByUserID:String = "system";
private var _currentLayoutID = ""; private var _currentLayoutID = "";
def handleGetCurrentLayoutRequest(msg: GetCurrentLayoutRequest) { def handleGetCurrentLayoutRequest(msg: GetCurrentLayoutRequest) {
outGW.send(new GetCurrentLayoutReply(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID)) outGW.send(new GetCurrentLayoutReply(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID))
@ -22,16 +22,16 @@ trait LayoutApp {
outGW.send(new SetLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers)) outGW.send(new SetLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
} }
def handleLayoutLockSettings(msg: LayoutLockSettings) { def handleBroadcastLayoutRequest(msg: BroadcastLayoutRequest) {
if (msg.locked) { _locked = msg.locked
_locked = true _currentLayoutID = msg.layoutID
_setByUserID = msg.requesterId outGW.send(new BroadcastLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
outGW.send(new LockLayoutEvent(msg.meetingID, recorded, msg.requesterId, _currentLayoutID, _locked, _setByUserID, affectedUsers)) }
} else {
_locked = false def handleUnlockLayoutRequest(msg: UnlockLayoutRequest) {
_setByUserID = msg.requesterId _locked = false
outGW.send(new UnlockLayoutEvent(msg.meetingID, recorded, msg.requesterId, _currentLayoutID, _locked, _setByUserID, affectedUsers)) _setByUserID = msg.requesterID
} outGW.send(new UnlockLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
} }
def affectedUsers():Array[UserVO] = { def affectedUsers():Array[UserVO] = {
@ -44,14 +44,4 @@ trait LayoutApp {
au.toArray au.toArray
} }
def handleLockLayoutRequest(msg: LockLayoutRequest) { }
_locked = true
_currentLayoutID = msg.layoutID
outGW.send(new LockLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
}
def handleUnlockLayoutRequest(msg: UnlockLayoutRequest) {
_locked = false
outGW.send(new UnlockLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
}
}

View File

@ -13,8 +13,8 @@ class LayoutInGateway(bbbGW: BigBlueButtonGateway) {
bbbGW.accept(new SetLayoutRequest(meetingID, requesterID, layoutID)) bbbGW.accept(new SetLayoutRequest(meetingID, requesterID, layoutID))
} }
def lockLayout(meetingID: String, requesterID: String, layoutID: String) { def broadcastLayout(meetingID: String, requesterID: String, layoutID: String, locked: Boolean) {
bbbGW.accept(new LockLayoutRequest(meetingID, requesterID, layoutID)) bbbGW.accept(new BroadcastLayoutRequest(meetingID, requesterID, layoutID, locked))
} }
def unlockLayout(meetingID: String, requesterID: String) { def unlockLayout(meetingID: String, requesterID: String) {

View File

@ -12,7 +12,7 @@ class LayoutClientMessageSender(service: ConnectionInvokerService) extends OutMe
msg match { msg match {
case msg:GetCurrentLayoutReply => handleGetCurrentLayoutReply(msg) case msg:GetCurrentLayoutReply => handleGetCurrentLayoutReply(msg)
case msg:SetLayoutEvent => handleSetLayoutEvent(msg) case msg:SetLayoutEvent => handleSetLayoutEvent(msg)
case msg:LockLayoutEvent => handleLockLayoutEvent(msg) case msg:BroadcastLayoutEvent => handleBroadcastLayoutEvent(msg)
case msg:UnlockLayoutEvent => handleUnlockLayoutEvent(msg) case msg:UnlockLayoutEvent => handleUnlockLayoutEvent(msg)
case _ => // do nothing case _ => // do nothing
} }
@ -38,7 +38,7 @@ class LayoutClientMessageSender(service: ConnectionInvokerService) extends OutMe
service.sendMessage(m); service.sendMessage(m);
} }
private def handleLockLayoutEvent(msg: LockLayoutEvent) { private def handleBroadcastLayoutEvent(msg: BroadcastLayoutEvent) {
val message = new java.util.HashMap[String, Object]() val message = new java.util.HashMap[String, Object]()
message.put("locked", msg.locked:java.lang.Boolean); message.put("locked", msg.locked:java.lang.Boolean);
message.put("setByUserID", msg.setByUserID); message.put("setByUserID", msg.setByUserID);

View File

@ -230,6 +230,7 @@ bbb.toolbar.deskshare.toolTip.stop = Stop Sharing My Desktop
bbb.toolbar.video.toolTip.start = Share My Webcam bbb.toolbar.video.toolTip.start = Share My Webcam
bbb.toolbar.video.toolTip.stop = Stop Sharing My Webcam bbb.toolbar.video.toolTip.stop = Stop Sharing My Webcam
bbb.layout.addButton.toolTip = Add the custom layout to the list bbb.layout.addButton.toolTip = Add the custom layout to the list
bbb.layout.broadcastButton.toolTip = Apply Current Layout to All Viewers
bbb.layout.combo.toolTip = Change the current layout bbb.layout.combo.toolTip = Change the current layout
bbb.layout.loadButton.toolTip = Load layouts from a file bbb.layout.loadButton.toolTip = Load layouts from a file
bbb.layout.saveButton.toolTip = Save layouts to a file bbb.layout.saveButton.toolTip = Save layouts to a file

View File

@ -18,30 +18,30 @@
*/ */
package org.bigbluebutton.modules.layout.events package org.bigbluebutton.modules.layout.events
{ {
import flash.events.Event; import flash.events.Event;
public class LayoutEvent extends Event
{
public static const REMOTE_LOCK_LAYOUT_EVENT:String = 'REMOTE_LOCK_LAYOUT_EVENT';
public static const REMOTE_UNLOCK_LAYOUT_EVENT:String = 'REMOTE_UNLOCK_LAYOUT_EVENT';
public class LayoutEvent extends Event
{
public static const REMOTE_LOCK_LAYOUT_EVENT:String = 'REMOTE_LOCK_LAYOUT_EVENT';
public static const REMOTE_UNLOCK_LAYOUT_EVENT:String = 'REMOTE_UNLOCK_LAYOUT_EVENT';
public static const SYNC_LAYOUT_EVENT:String = 'SYNC_LAYOUT_EVENT'; public static const SYNC_LAYOUT_EVENT:String = 'SYNC_LAYOUT_EVENT';
public static const LOCK_LAYOUT_EVENT:String = 'LOCK_LAYOUT_EVENT'; public static const BROADCAST_LAYOUT_EVENT:String = 'BROADCAST_LAYOUT_EVENT';
public static const UNLOCK_LAYOUT_EVENT:String = 'UNLOCK_LAYOUT_EVENT'; public static const LOCK_LAYOUT_EVENT:String = 'LOCK_LAYOUT_EVENT';
public static const STOP_LAYOUT_MODULE_EVENT:String = 'STOP_LAYOUT_MODULE_EVENT'; public static const UNLOCK_LAYOUT_EVENT:String = 'UNLOCK_LAYOUT_EVENT';
public static const VIEW_INITIALIZED_EVENT:String = 'VIEW_INITIALIZED_EVENT'; public static const STOP_LAYOUT_MODULE_EVENT:String = 'STOP_LAYOUT_MODULE_EVENT';
public static const VIEW_INITIALIZED_EVENT:String = 'VIEW_INITIALIZED_EVENT';
public static const SAVE_LAYOUTS_EVENT:String = 'SAVE_LAYOUTS_EVENT';
public static const LOAD_LAYOUTS_EVENT:String = 'LOAD_LAYOUTS_EVENT'; public static const SAVE_LAYOUTS_EVENT:String = 'SAVE_LAYOUTS_EVENT';
public static const ADD_CURRENT_LAYOUT_EVENT:String = 'ADD_CURRENT_LAYOUT_EVENT'; public static const LOAD_LAYOUTS_EVENT:String = 'LOAD_LAYOUTS_EVENT';
public static const FILE_LOADED_SUCCESSFULLY_EVENT:String = 'FILE_LOADED_SUCCESSFULLY_EVENT'; public static const ADD_CURRENT_LAYOUT_EVENT:String = 'ADD_CURRENT_LAYOUT_EVENT';
public static const APPLY_DEFAULT_LAYOUT_EVENT:String = 'APPLY_DEFAULT_LAYOUT_EVENT'; public static const FILE_LOADED_SUCCESSFULLY_EVENT:String = 'FILE_LOADED_SUCCESSFULLY_EVENT';
public static const INVALIDATE_LAYOUT_EVENT:String = 'INVALIDATE_LAYOUT_EVENT'; public static const APPLY_DEFAULT_LAYOUT_EVENT:String = 'APPLY_DEFAULT_LAYOUT_EVENT';
public static const INVALIDATE_LAYOUT_EVENT:String = 'INVALIDATE_LAYOUT_EVENT';
public function LayoutEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{ public function LayoutEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
super(type, bubbles, cancelable); {
} super(type, bubbles, cancelable);
}
}
} }
}

View File

@ -26,6 +26,7 @@ package org.bigbluebutton.modules.layout.events
{ {
public static const UPDATE_LAYOUT_EVENT:String = 'UPDATE_LAYOUT_EVENT'; public static const UPDATE_LAYOUT_EVENT:String = 'UPDATE_LAYOUT_EVENT';
public var layout:LayoutDefinition; public var layout:LayoutDefinition;
public var locked:Boolean;
public function UpdateLayoutEvent(type:String=UPDATE_LAYOUT_EVENT, bubbles:Boolean=true, cancelable:Boolean=false) public function UpdateLayoutEvent(type:String=UPDATE_LAYOUT_EVENT, bubbles:Boolean=true, cancelable:Boolean=false)
{ {

View File

@ -259,11 +259,20 @@ package org.bigbluebutton.modules.layout.managers
sendLayoutUpdate(_currentLayout); sendLayoutUpdate(_currentLayout);
} }
public function broadcastLayout():void {
LogUtil.debug("LayoutManager: layout broadcasted by myself");
var e:UpdateLayoutEvent = new UpdateLayoutEvent();
e.layout = _currentLayout;
e.locked = _locked;
_globalDispatcher.dispatchEvent(e);
}
private function sendLayoutUpdate(layout:LayoutDefinition):void { private function sendLayoutUpdate(layout:LayoutDefinition):void {
if (UsersUtil.amIModerator() || UsersUtil.amIPresenter()) { if (UsersUtil.amIModerator() || UsersUtil.amIPresenter()) {
trace("LayoutManager: sending layout to remotes"); trace("LayoutManager: sending layout to remotes");
var e:UpdateLayoutEvent = new UpdateLayoutEvent(); var e:UpdateLayoutEvent = new UpdateLayoutEvent();
e.layout = layout; e.layout = layout;
e.locked = _locked;
_globalDispatcher.dispatchEvent(e); _globalDispatcher.dispatchEvent(e);
} }
} }

View File

@ -20,7 +20,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
--> -->
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/"> <EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/">
<mx:Script> <mx:Script>
<![CDATA[ <![CDATA[
import mx.events.FlexEvent; import mx.events.FlexEvent;
import org.bigbluebutton.core.EventConstants; import org.bigbluebutton.core.EventConstants;
@ -37,7 +37,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.layout.managers.LayoutManager; import org.bigbluebutton.modules.layout.managers.LayoutManager;
import org.bigbluebutton.modules.layout.services.LayoutService; import org.bigbluebutton.modules.layout.services.LayoutService;
import org.bigbluebutton.modules.layout.services.MessageReceiver; import org.bigbluebutton.modules.layout.services.MessageReceiver;
import org.bigbluebutton.modules.layout.services.MessageSender; import org.bigbluebutton.modules.layout.services.MessageSender;
]]> ]]>
</mx:Script> </mx:Script>
@ -70,7 +70,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
</EventHandlers> </EventHandlers>
<EventHandlers type="{LayoutEvent.LOCK_LAYOUT_EVENT}"> <EventHandlers type="{LayoutEvent.LOCK_LAYOUT_EVENT}">
<MethodInvoker generator="{LayoutManager}" method="lockLayout" /> <MethodInvoker generator="{LayoutManager}" method="lockLayout" />
</EventHandlers> </EventHandlers>
<EventHandlers type="{EventConstants.LOCK_LAYOUT_REQ}"> <EventHandlers type="{EventConstants.LOCK_LAYOUT_REQ}">
@ -85,8 +85,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<MethodInvoker generator="{LayoutService}" method="unlockLayout"/> <MethodInvoker generator="{LayoutService}" method="unlockLayout"/>
</EventHandlers> </EventHandlers>
<EventHandlers type="{LayoutEvent.BROADCAST_LAYOUT_EVENT}">
<MethodInvoker generator="{LayoutManager}" method="broadcastLayout" />
</EventHandlers>
<EventHandlers type="{UpdateLayoutEvent.UPDATE_LAYOUT_EVENT}"> <EventHandlers type="{UpdateLayoutEvent.UPDATE_LAYOUT_EVENT}">
<MethodInvoker generator="{LayoutService}" method="lockLayout" arguments="{event.layout}" /> <MethodInvoker generator="{LayoutService}" method="broadcastLayout" arguments="{[event.layout, event.locked]}" />
</EventHandlers> </EventHandlers>
<EventHandlers type="{SyncLayoutEvent.SYNC_LAYOUT_EVENT}"> <EventHandlers type="{SyncLayoutEvent.SYNC_LAYOUT_EVENT}">

View File

@ -18,30 +18,31 @@
*/ */
package org.bigbluebutton.modules.layout.services package org.bigbluebutton.modules.layout.services
{ {
import flash.events.IEventDispatcher; import flash.events.IEventDispatcher;
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.modules.layout.model.LayoutDefinition;
import org.bigbluebutton.common.LogUtil; public class LayoutService
import org.bigbluebutton.modules.layout.model.LayoutDefinition; {
public class LayoutService
{
public var sender:MessageSender; public var sender:MessageSender;
public var receiver:MessageReceiver; public var receiver:MessageReceiver;
public function getCurrentLayout():void { public function getCurrentLayout():void {
sender.getCurrentLayout(); sender.getCurrentLayout();
} }
public function syncLayout(layout:LayoutDefinition):void { public function syncLayout(layout:LayoutDefinition):void {
sender.syncLayout(layout); sender.syncLayout(layout);
} }
public function lockLayout(layout:LayoutDefinition):void {
sender.lockLayout(layout);
}
public function unlockLayout():void { public function broadcastLayout(layout:LayoutDefinition, locked:Boolean):void {
sender.unlockLayout(); sender.broadcastLayout(layout, locked);
} }
}
} public function unlockLayout():void {
sender.unlockLayout();
}
}
}

View File

@ -10,6 +10,7 @@ package org.bigbluebutton.modules.layout.services
import org.bigbluebutton.core.EventConstants; import org.bigbluebutton.core.EventConstants;
import org.bigbluebutton.core.events.CoreEvent; import org.bigbluebutton.core.events.CoreEvent;
import org.bigbluebutton.core.managers.UserManager; import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.events.ModuleLoadEvent; import org.bigbluebutton.main.events.ModuleLoadEvent;
import org.bigbluebutton.main.model.users.IMessageListener; import org.bigbluebutton.main.model.users.IMessageListener;
import org.bigbluebutton.modules.layout.events.LayoutEvent; import org.bigbluebutton.modules.layout.events.LayoutEvent;
@ -100,11 +101,9 @@ package org.bigbluebutton.modules.layout.services
_dispatcher.dispatchEvent(new CoreEvent(EventConstants.REMOTE_UNLOCKED_LAYOUT)); _dispatcher.dispatchEvent(new CoreEvent(EventConstants.REMOTE_UNLOCKED_LAYOUT));
} }
if (locked && !dispatchedByMe) { if (!dispatchedByMe && !UsersUtil.amIModerator()) {
trace("LayoutService: handling remote layout= [" + layout + "]"); LogUtil.debug("LayoutService: handling remote layout");
LogUtil.debug(layout);
if (layout == "") return;
var layoutDefinition:LayoutDefinition = new LayoutDefinition(); var layoutDefinition:LayoutDefinition = new LayoutDefinition();
layoutDefinition.load(new XML(layout)); layoutDefinition.load(new XML(layout));
layoutDefinition.name = "[" + ResourceUtil.getInstance().getString('bbb.layout.combo.remote') + "] " + layoutDefinition.name; layoutDefinition.name = "[" + ResourceUtil.getInstance().getString('bbb.layout.combo.remote') + "] " + layoutDefinition.name;
@ -117,4 +116,4 @@ package org.bigbluebutton.modules.layout.services
_locked = locked; _locked = locked;
} }
} }
} }

View File

@ -37,13 +37,14 @@ package org.bigbluebutton.modules.layout.services
); );
} }
public function lockLayout(layout:LayoutDefinition):void { public function broadcastLayout(layout:LayoutDefinition, locked:Boolean):void {
var message:Object = new Object(); var message:Object = new Object();
message["setByUserID"] = UserManager.getInstance().getConference().getMyUserId(); message["setByUserID"] = UserManager.getInstance().getConference().getMyUserId();
message["layout"] = layout.toXml().toXMLString(); message["layout"] = layout.toXml().toXMLString();
message["locked"] = locked;
var _nc:ConnectionManager = BBB.initConnectionManager(); var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage("layout.lock", _nc.sendMessage("layout.broadcast",
function(result:String):void { // On successful result function(result:String):void { // On successful result
LogUtil.debug(result); LogUtil.debug(result);
}, },

View File

@ -0,0 +1,61 @@
<?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/>.
-->
<views:LayoutButton xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="init()"
xmlns:mate="http://mate.asfusion.com/"
xmlns:views="org.bigbluebutton.modules.layout.views.*"
toolTip="{ResourceUtil.getInstance().getString('bbb.layout.broadcastButton.toolTip')}"
icon="{_icon}"
click="onClick(event)"
enabled="{UserManager.getInstance().getConference().amIModerator()}">
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import flash.events.Event;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.modules.layout.events.LayoutEvent;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.ShortcutEvent;
import flash.events.FocusEvent;
private var _dispatcher:Dispatcher = new Dispatcher();
private var _images:Images = new Images();
[Bindable] private var _icon:Class = _images.raisehand;
private function init():void {
if (!UserManager.getInstance().getConference().amIModerator()) {
this.visible = false;
}
}
private function onClick(e:Event):void {
_dispatcher.dispatchEvent(new LayoutEvent(LayoutEvent.BROADCAST_LAYOUT_EVENT));
}
]]>
</mx:Script>
</views:LayoutButton>

View File

@ -27,9 +27,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Script> <mx:Script>
<![CDATA[ <![CDATA[
import com.asfusion.mate.events.Dispatcher; import com.asfusion.mate.events.Dispatcher;
import flexlib.mdi.containers.MDICanvas; import flexlib.mdi.containers.MDICanvas;
import org.bigbluebutton.core.managers.UserManager; import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.views.MainToolbar; import org.bigbluebutton.main.views.MainToolbar;
import org.bigbluebutton.modules.layout.events.ViewInitializedEvent; import org.bigbluebutton.modules.layout.events.ViewInitializedEvent;
@ -92,6 +90,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
includeInLayout="{_enableEdit}" includeInLayout="{_enableEdit}"
visible="{_enableEdit}" visible="{_enableEdit}"
tabIndex="{baseIndex+3}"/> tabIndex="{baseIndex+3}"/>
<views:BroadcastButton id="broadcastButton"
tabIndex="{baseIndex+4}"
enabled="{!lockButton.selected}"/>
<views:LockButton id="lockButton" <views:LockButton id="lockButton"
tabIndex="{baseIndex+4}"/> tabIndex="{baseIndex+5}"
visible="false"
includeInLayout="false"/>
</mx:HBox> </mx:HBox>