You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2017/03/08 16:51:44 UTC

svn commit: r1786024 - in /openmeetings/application: branches/3.2.x/ branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/ branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/ branches/3.2.x/ope...

Author: solomax
Date: Wed Mar  8 16:51:44 2017
New Revision: 1786024

URL: http://svn.apache.org/viewvc?rev=1786024&view=rev
Log:
[OPENMEETINGS-690] 'have question' button is implemented

Added:
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/hand.png   (with props)
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/hand.png   (with props)
Modified:
    openmeetings/application/branches/3.2.x/NOTICE
    openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/Activity.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css
    openmeetings/application/trunk/NOTICE
    openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/Activity.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css

Modified: openmeetings/application/branches/3.2.x/NOTICE
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/NOTICE?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/NOTICE (original)
+++ openmeetings/application/branches/3.2.x/NOTICE Wed Mar  8 16:51:44 2017
@@ -1,5 +1,5 @@
 Apache OpenMeetings
-Copyright 2011-2014 The Apache Software Foundation
+Copyright 2011-2017 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).

Modified: openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java Wed Mar  8 16:51:44 2017
@@ -45,6 +45,7 @@ public class RoomMessage implements IWeb
 		, requestRightAv
 		, requestRightMute
 		, requestRightExclusive
+		, haveQuestion
 		, kick
 	}
 	private final Date timestamp;

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java Wed Mar  8 16:51:44 2017
@@ -408,9 +408,11 @@ public class RoomPanel extends BasePanel
 						activities.add(new Activity((TextRoomMessage)m, Activity.Type.reqRightExclusive), handler);
 						break;
 					case activityRemove:
-						{
-							TextRoomMessage tm = (TextRoomMessage)m;
-							activities.remove(tm.getText(), handler);
+						activities.remove(((TextRoomMessage)m).getText(), handler);
+						break;
+					case haveQuestion:
+						if (getClient().hasRight(Room.Right.moderator)) {
+							activities.add(new Activity(m, Activity.Type.haveQuestion), handler);
 						}
 						break;
 					case kick:

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java Wed Mar  8 16:51:44 2017
@@ -26,12 +26,11 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
 import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
 
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
+import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room.Right;
@@ -67,12 +66,7 @@ public class ActivitiesPanel extends Bas
 	private enum Action {
 		accept, decline, close
 	};
-	private static ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
-		@Override
-		protected DateFormat initialValue() {
-			return new SimpleDateFormat("HH:mm:ss");
-		};
-	};
+	private static final FastDateFormat df = FastDateFormat.getInstance("HH:mm:ss");
 	private final Map<String, Activity> activities = new LinkedHashMap<>();
 	private final RoomPanel room;
 	private final WebMarkupContainer container = new WebMarkupContainer("container");
@@ -175,8 +169,9 @@ public class ActivitiesPanel extends Bas
 					if (room.getClient().hasRight(Right.moderator)) {
 						accept.setVisible(true);
 						decline.setVisible(true);
-						break;
 					}
+					break;
+				case haveQuestion:
 				case roomEnter:
 				case roomExit:
 					accept.setVisible(false);
@@ -191,31 +186,34 @@ public class ActivitiesPanel extends Bas
 					item.setVisible(false);
 					break;
 				case roomExit:
-					text = String.format("%s %s [%s]", name, getString("1367"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("1367"), df.format(a.getCreated()));
 					break;
 				case reqRightModerator:
-					text = String.format("%s %s [%s]", name, getString("room.action.request.right.moderator"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("room.action.request.right.moderator"), df.format(a.getCreated()));
 					break;
 				case reqRightWb:
-					text = String.format("%s %s [%s]", name, getString("694"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("694"), df.format(a.getCreated()));
 					break;
 				case reqRightShare:
-					text = String.format("%s %s [%s]", name, getString("1070"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("1070"), df.format(a.getCreated()));
 					break;
 				case reqRightRemote:
-					text = String.format("%s %s [%s]", name, getString("1082"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("1082"), df.format(a.getCreated()));
 					break;
 				case reqRightA:
-					text = String.format("%s %s [%s]", name, getString("1603"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("1603"), df.format(a.getCreated()));
 					break;
 				case reqRightAv:
-					text = String.format("%s %s [%s]", name, getString("695"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("695"), df.format(a.getCreated()));
 					break;
 				case reqRightMute:
-					text = String.format("%s %s [%s]", name, getString("1399"), df.get().format(a.getCreated()));//TODO un-mute 1398
+					text = String.format("%s %s [%s]", name, getString("1399"), df.format(a.getCreated()));//TODO un-mute 1398
 					break;
 				case reqRightExclusive:
-					text = String.format("%s %s [%s]", name, getString("1427"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("1427"), df.format(a.getCreated()));
+					break;
+				case haveQuestion:
+					text = String.format("%s %s [%s]", name, getString("693"), df.format(a.getCreated()));
 					break;
 			}
 			item.add(new WebMarkupContainer("close").add(new AttributeAppender("onclick", String.format("activityAction(%s, '%s', '%s');", roomId, Action.close.name(), a.getId()))));
@@ -234,6 +232,7 @@ public class ActivitiesPanel extends Bas
 				case reqRightAv:
 				case reqRightMute:
 				case reqRightExclusive:
+				case haveQuestion:
 					cls = "ui-state-highlight";
 					break;
 				case roomEnter:

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/Activity.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/Activity.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/Activity.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/Activity.java Wed Mar  8 16:51:44 2017
@@ -37,21 +37,22 @@ public class Activity implements Seriali
 		, reqRightAv
 		, reqRightMute
 		, reqRightExclusive
+		, haveQuestion
 	}
 	private final String id;
 	private final String uid;
 	private final Long sender;
 	private final Date created;
 	private final Type type;
-	
+
 	public Activity(RoomMessage m, Type type) {
 		this(m.getUid(), null, m.getUserId(), type);
 	}
-	
+
 	public Activity(TextRoomMessage m, Type type) {
 		this(m.getUid(), m.getText(), m.getUserId(), type);
 	}
-	
+
 	public Activity(String id, String uid, Long sender, Type type) {
 		this.id = id;
 		this.uid = uid;
@@ -63,7 +64,7 @@ public class Activity implements Seriali
 	public String getId() {
 		return id;
 	}
-	
+
 	public String getUid() {
 		return uid;
 	}

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java Wed Mar  8 16:51:44 2017
@@ -29,6 +29,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.commons.lang3.time.FastDateFormat;
+import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.room.PollDao;
 import org.apache.openmeetings.db.dao.server.ISessionManager;
@@ -37,6 +38,7 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.room.RoomPoll;
 import org.apache.openmeetings.db.entity.user.Group;
 import org.apache.openmeetings.db.entity.user.User;
+import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.ImagePanel;
@@ -79,7 +81,7 @@ public class RoomMenuPanel extends Panel
 		}
 		@Override
 		public void onClick(AjaxRequestTarget target) {
-			room.requestRight(Room.Right.moderator, target);
+			WebSocketHelper.sendRoom(new RoomMessage(room.getRoom().getId(), getUserId(), RoomMessage.Type.haveQuestion));
 		}
 	};
 	private final RoomPanel room;
@@ -115,7 +117,7 @@ public class RoomMenuPanel extends Panel
 
 		@Override
 		public void onClick(AjaxRequestTarget target) {
-			askBtn.onClick(target);
+			room.requestRight(Room.Right.moderator, target);
 		}
 	};
 	private final RoomMenuItem applyWbMenuItem = new RoomMenuItem(Application.getString(785), Application.getString(1492), false) {
@@ -195,7 +197,6 @@ public class RoomMenuPanel extends Panel
 		Room r = room.getRoom();
 		setVisible(!r.isHidden(RoomElement.TopBar));
 		add((menuPanel = new MenuPanel("menu", getMenu())).setVisible(isVisible()));
-		add(askBtn.setOutputMarkupPlaceholderTag(true).setOutputMarkupId(true));
 		add((roomName = new Label("roomName", r.getName())).setOutputMarkupPlaceholderTag(true).setOutputMarkupId(true));
 		String tag = getGroup().getTag();
 		add(logo, new Label("tag", tag).setVisible(!Strings.isEmpty(tag)));
@@ -213,7 +214,7 @@ public class RoomMenuPanel extends Panel
 	@Override
 	protected void onInitialize() {
 		super.onInitialize();
-		askBtn.add(new AttributeAppender("title", getString("906")));
+		add(askBtn.add(new AttributeAppender("title", getString("84"))));
 		Label demo = new Label("demo", Model.of(""));
 		Room r = room.getRoom();
 		add(demo.setVisible(r.isDemoRoom() && r.getDemoTime() != null && room.getRoom().getDemoTime().intValue() > 0));

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java Wed Mar  8 16:51:44 2017
@@ -50,8 +50,10 @@ public abstract class RoomRightIcon exte
 	}
 
 	protected boolean visible() {
-		return !client.hasRight(Right.superModerator) &&
-				((self && !hasRight()) || (!self && room.getClient().hasRight(Right.moderator)));
+		return !client.hasRight(Right.superModerator) && (
+				(self && !hasRight() && room.getRoom().isAllowUserQuestions())
+				|| (!self && room.getClient().hasRight(Right.moderator))
+			);
 	}
 
 	@Override

Added: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/hand.png
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/hand.png?rev=1786024&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/images/hand.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/css/room.css Wed Mar  8 16:51:44 2017
@@ -179,9 +179,12 @@
 .audio-activity.ui-icon.speaking, .ui-icon.granted {
 	opacity: 1;
 }
-.right.moderator.ui-icon, .room.menu.right .icon.ask {
+.right.moderator.ui-icon {
 	background-image: url(images/user_add.png);
 }
+.room.menu.right .icon.ask {
+	background-image: url(images/hand.png);
+}
 .right.moderator.ui-icon.granted {
 	background-image: url(images/user_delete.png);
 }

Modified: openmeetings/application/trunk/NOTICE
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/NOTICE?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/trunk/NOTICE (original)
+++ openmeetings/application/trunk/NOTICE Wed Mar  8 16:51:44 2017
@@ -1,5 +1,5 @@
 Apache OpenMeetings
-Copyright 2011-2014 The Apache Software Foundation
+Copyright 2011-2017 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).

Modified: openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java (original)
+++ openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java Wed Mar  8 16:51:44 2017
@@ -45,6 +45,7 @@ public class RoomMessage implements IWeb
 		, requestRightAv
 		, requestRightMute
 		, requestRightExclusive
+		, haveQuestion
 		, kick
 	}
 	private final Date timestamp;

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java Wed Mar  8 16:51:44 2017
@@ -420,9 +420,11 @@ public class RoomPanel extends BasePanel
 						activities.add(new Activity((TextRoomMessage)m, Activity.Type.reqRightExclusive), handler);
 						break;
 					case activityRemove:
-						{
-							TextRoomMessage tm = (TextRoomMessage)m;
-							activities.remove(tm.getText(), handler);
+						activities.remove(((TextRoomMessage)m).getText(), handler);
+						break;
+					case haveQuestion:
+						if (getClient().hasRight(Room.Right.moderator)) {
+							activities.add(new Activity(m, Activity.Type.haveQuestion), handler);
 						}
 						break;
 					case kick:

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java Wed Mar  8 16:51:44 2017
@@ -26,12 +26,11 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
 import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
 
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
+import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room.Right;
@@ -67,12 +66,7 @@ public class ActivitiesPanel extends Bas
 	private enum Action {
 		accept, decline, close
 	};
-	private static ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
-		@Override
-		protected DateFormat initialValue() {
-			return new SimpleDateFormat("HH:mm:ss");
-		};
-	};
+	private static final FastDateFormat df = FastDateFormat.getInstance("HH:mm:ss");
 	private final Map<String, Activity> activities = new LinkedHashMap<>();
 	private final RoomPanel room;
 	private final WebMarkupContainer container = new WebMarkupContainer("container");
@@ -175,8 +169,9 @@ public class ActivitiesPanel extends Bas
 					if (room.getClient().hasRight(Right.moderator)) {
 						accept.setVisible(true);
 						decline.setVisible(true);
-						break;
 					}
+					break;
+				case haveQuestion:
 				case roomEnter:
 				case roomExit:
 					accept.setVisible(false);
@@ -191,31 +186,34 @@ public class ActivitiesPanel extends Bas
 					item.setVisible(false);
 					break;
 				case roomExit:
-					text = String.format("%s %s [%s]", name, getString("1367"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("1367"), df.format(a.getCreated()));
 					break;
 				case reqRightModerator:
-					text = String.format("%s %s [%s]", name, getString("room.action.request.right.moderator"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("room.action.request.right.moderator"), df.format(a.getCreated()));
 					break;
 				case reqRightWb:
-					text = String.format("%s %s [%s]", name, getString("694"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("694"), df.format(a.getCreated()));
 					break;
 				case reqRightShare:
-					text = String.format("%s %s [%s]", name, getString("1070"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("1070"), df.format(a.getCreated()));
 					break;
 				case reqRightRemote:
-					text = String.format("%s %s [%s]", name, getString("1082"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("1082"), df.format(a.getCreated()));
 					break;
 				case reqRightA:
-					text = String.format("%s %s [%s]", name, getString("1603"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("1603"), df.format(a.getCreated()));
 					break;
 				case reqRightAv:
-					text = String.format("%s %s [%s]", name, getString("695"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("695"), df.format(a.getCreated()));
 					break;
 				case reqRightMute:
-					text = String.format("%s %s [%s]", name, getString("1399"), df.get().format(a.getCreated()));//TODO un-mute 1398
+					text = String.format("%s %s [%s]", name, getString("1399"), df.format(a.getCreated()));//TODO un-mute 1398
 					break;
 				case reqRightExclusive:
-					text = String.format("%s %s [%s]", name, getString("1427"), df.get().format(a.getCreated()));
+					text = String.format("%s %s [%s]", name, getString("1427"), df.format(a.getCreated()));
+					break;
+				case haveQuestion:
+					text = String.format("%s %s [%s]", name, getString("693"), df.format(a.getCreated()));
 					break;
 			}
 			item.add(new WebMarkupContainer("close").add(new AttributeAppender("onclick", String.format("activityAction(%s, '%s', '%s');", roomId, Action.close.name(), a.getId()))));
@@ -234,6 +232,7 @@ public class ActivitiesPanel extends Bas
 				case reqRightAv:
 				case reqRightMute:
 				case reqRightExclusive:
+				case haveQuestion:
 					cls = "ui-state-highlight";
 					break;
 				case roomEnter:

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/Activity.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/Activity.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/Activity.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/Activity.java Wed Mar  8 16:51:44 2017
@@ -37,21 +37,22 @@ public class Activity implements Seriali
 		, reqRightAv
 		, reqRightMute
 		, reqRightExclusive
+		, haveQuestion
 	}
 	private final String id;
 	private final String uid;
 	private final Long sender;
 	private final Date created;
 	private final Type type;
-	
+
 	public Activity(RoomMessage m, Type type) {
 		this(m.getUid(), null, m.getUserId(), type);
 	}
-	
+
 	public Activity(TextRoomMessage m, Type type) {
 		this(m.getUid(), m.getText(), m.getUserId(), type);
 	}
-	
+
 	public Activity(String id, String uid, Long sender, Type type) {
 		this.id = id;
 		this.uid = uid;
@@ -63,7 +64,7 @@ public class Activity implements Seriali
 	public String getId() {
 		return id;
 	}
-	
+
 	public String getUid() {
 		return uid;
 	}

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java Wed Mar  8 16:51:44 2017
@@ -29,6 +29,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.commons.lang3.time.FastDateFormat;
+import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.room.PollDao;
 import org.apache.openmeetings.db.dao.server.ISessionManager;
@@ -37,6 +38,7 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.room.RoomPoll;
 import org.apache.openmeetings.db.entity.user.Group;
 import org.apache.openmeetings.db.entity.user.User;
+import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.ImagePanel;
@@ -79,7 +81,7 @@ public class RoomMenuPanel extends Panel
 		}
 		@Override
 		public void onClick(AjaxRequestTarget target) {
-			room.requestRight(Room.Right.moderator, target);
+			WebSocketHelper.sendRoom(new RoomMessage(room.getRoom().getId(), getUserId(), RoomMessage.Type.haveQuestion));
 		}
 	};
 	private final RoomPanel room;
@@ -115,7 +117,7 @@ public class RoomMenuPanel extends Panel
 
 		@Override
 		public void onClick(AjaxRequestTarget target) {
-			askBtn.onClick(target);
+			room.requestRight(Room.Right.moderator, target);
 		}
 	};
 	private final RoomMenuItem applyWbMenuItem = new RoomMenuItem(Application.getString(785), Application.getString(1492), false) {
@@ -195,7 +197,6 @@ public class RoomMenuPanel extends Panel
 		Room r = room.getRoom();
 		setVisible(!r.isHidden(RoomElement.TopBar));
 		add((menuPanel = new MenuPanel("menu", getMenu())).setVisible(isVisible()));
-		add(askBtn.setOutputMarkupPlaceholderTag(true).setOutputMarkupId(true));
 		add((roomName = new Label("roomName", r.getName())).setOutputMarkupPlaceholderTag(true).setOutputMarkupId(true));
 		String tag = getGroup().getTag();
 		add(logo, new Label("tag", tag).setVisible(!Strings.isEmpty(tag)));
@@ -213,7 +214,7 @@ public class RoomMenuPanel extends Panel
 	@Override
 	protected void onInitialize() {
 		super.onInitialize();
-		askBtn.add(new AttributeAppender("title", getString("906")));
+		add(askBtn.add(new AttributeAppender("title", getString("84"))));
 		Label demo = new Label("demo", Model.of(""));
 		Room r = room.getRoom();
 		add(demo.setVisible(r.isDemoRoom() && r.getDemoTime() != null && room.getRoom().getDemoTime().intValue() > 0));

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java Wed Mar  8 16:51:44 2017
@@ -50,8 +50,10 @@ public abstract class RoomRightIcon exte
 	}
 
 	protected boolean visible() {
-		return !client.hasRight(Right.superModerator) &&
-				((self && !hasRight()) || (!self && room.getClient().hasRight(Right.moderator)));
+		return !client.hasRight(Right.superModerator) && (
+				(self && !hasRight() && room.getRoom().isAllowUserQuestions())
+				|| (!self && room.getClient().hasRight(Right.moderator))
+			);
 	}
 
 	@Override

Added: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/hand.png
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/hand.png?rev=1786024&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/images/hand.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css?rev=1786024&r1=1786023&r2=1786024&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/webapp/css/room.css Wed Mar  8 16:51:44 2017
@@ -179,9 +179,12 @@
 .audio-activity.ui-icon.speaking, .ui-icon.granted {
 	opacity: 1;
 }
-.right.moderator.ui-icon, .room.menu.right .icon.ask {
+.right.moderator.ui-icon {
 	background-image: url(images/user_add.png);
 }
+.room.menu.right .icon.ask {
+	background-image: url(images/hand.png);
+}
 .right.moderator.ui-icon.granted {
 	background-image: url(images/user_delete.png);
 }