Merge "Issue #2632 - Implement buddy pounce (Contact Notifiers) Review comments" into development

Former-commit-id: 1a72af70658f288d43e397d12499de1a08ff2ba8
This commit is contained in:
Lee Venable 2014-02-28 13:50:15 -06:00 committed by Gerrit Code Review
commit f171e3adb0
21 changed files with 1803 additions and 133 deletions

View file

@ -20,6 +20,7 @@
package com.raytheon.uf.viz.collaboration.comm.identity.event; package com.raytheon.uf.viz.collaboration.comm.identity.event;
import org.jivesoftware.smack.RosterEntry; import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.packet.Presence;
/** /**
* Event fired when the roster has changed * Event fired when the roster has changed
@ -30,7 +31,8 @@ import org.jivesoftware.smack.RosterEntry;
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Apr 6, 2012 jkorman Initial creation * Apr 06, 2012 jkorman Initial creation.
* Feb 24, 2014 2632 mpduff Added getPresence, changed getItem to getEntry.
* *
* </pre> * </pre>
* *
@ -43,15 +45,22 @@ public interface IRosterChangeEvent {
/** /**
* Get the event type. * Get the event type.
* *
* @return The event type. * @return The event type
*/ */
public RosterChangeType getType(); RosterChangeType getType();
/** /**
* Get the changed entry * Get the changed entry.
* *
* @return The changed entry. * @return The changed entry
*/ */
public RosterEntry getItem(); RosterEntry getEntry();
/**
* Get the Presence object.
*
* @return The Presence object
*/
Presence getPresence();
} }

View file

@ -20,6 +20,7 @@
package com.raytheon.uf.viz.collaboration.comm.provider.event; package com.raytheon.uf.viz.collaboration.comm.provider.event;
import org.jivesoftware.smack.RosterEntry; import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.packet.Presence;
import com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent; import com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent;
import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType; import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType;
@ -34,6 +35,7 @@ import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Apr 11, 2012 jkorman Initial creation * Apr 11, 2012 jkorman Initial creation
* Feb 24, 2014 2632 mpduff Added getPresence, changed getItem to getEntry.
* *
* </pre> * </pre>
* *
@ -45,7 +47,10 @@ public class RosterChangeEvent implements IRosterChangeEvent {
private final RosterChangeType type; private final RosterChangeType type;
private final RosterEntry item; private final RosterEntry entry;
/** The presence object */
private Presence presence;
/** /**
* Create an instance of this event using the given type and entry. * Create an instance of this event using the given type and entry.
@ -55,9 +60,28 @@ public class RosterChangeEvent implements IRosterChangeEvent {
* @param entry * @param entry
* The changed entry. * The changed entry.
*/ */
public RosterChangeEvent(RosterChangeType type, RosterEntry item) { public RosterChangeEvent(RosterChangeType type, RosterEntry entry) {
this.type = type; this.type = type;
this.item = item; this.entry = entry;
}
/**
* Create an instance of this event using the given type, entry, and
* presence.
*
* @param type
* The event type.
* @param entry
* The changed entry.
* @param presence
* The presence object
*/
public RosterChangeEvent(RosterChangeType type, RosterEntry entry,
Presence presence) {
this.type = type;
this.entry = entry;
this.presence = presence;
} }
/** /**
@ -78,8 +102,24 @@ public class RosterChangeEvent implements IRosterChangeEvent {
* @see com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent#getEntry() * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent#getEntry()
*/ */
@Override @Override
public RosterEntry getItem() { public RosterEntry getEntry() {
return item; return entry;
}
/**
* @return the presence
*/
@Override
public Presence getPresence() {
return presence;
}
/**
* @param presence
* the presence to set
*/
public void setPresence(Presence presence) {
this.presence = presence;
} }
} }

View file

@ -113,6 +113,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
* Feb 3, 2014 2699 bclement removed unneeded catch in joinTextOnlyVenue * Feb 3, 2014 2699 bclement removed unneeded catch in joinTextOnlyVenue
* Feb 13, 2014 2751 bclement better types for venueid and invitor * Feb 13, 2014 2751 bclement better types for venueid and invitor
* Feb 18, 2014 2793 bclement improved disconnection notification and handling * Feb 18, 2014 2793 bclement improved disconnection notification and handling
* Feb 24, 2014 2632 mpduff Fix roster change type for presence change.
* *
* </pre> * </pre>
* *
@ -136,9 +137,9 @@ public class CollaborationConnection implements IEventPublisher {
private static Map<CollaborationConnectionData, CollaborationConnection> instanceMap = new HashMap<CollaborationConnectionData, CollaborationConnection>(); private static Map<CollaborationConnectionData, CollaborationConnection> instanceMap = new HashMap<CollaborationConnectionData, CollaborationConnection>();
private Map<String, ISession> sessions; private final Map<String, ISession> sessions;
private UserId user; private final UserId user;
private Presence userPresence; private Presence userPresence;
@ -146,11 +147,11 @@ public class CollaborationConnection implements IEventPublisher {
private IAccountManager accountManager = null; private IAccountManager accountManager = null;
private EventBus eventBus; private final EventBus eventBus;
private ContactsManager contactsMgr; private final ContactsManager contactsMgr;
private CollaborationConnectionData connectionData; private final CollaborationConnectionData connectionData;
private XMPPConnection connection; private XMPPConnection connection;
@ -195,7 +196,7 @@ public class CollaborationConnection implements IEventPublisher {
conConfig.setCompressionEnabled(COMPRESS); conConfig.setCompressionEnabled(COMPRESS);
connection = new XMPPConnection(conConfig); connection = new XMPPConnection(conConfig);
connectInternal(connectionData.getUserName(), password); connectInternal(connectionData.getUserName(), password);
this.user = new UserId(connectionData.getUserName(), this.user = new UserId(connectionData.getUserName(),
@ -423,12 +424,12 @@ public class CollaborationConnection implements IEventPublisher {
*/ */
public IVenueSession joinTextOnlyVenue(String venueName, String handle) public IVenueSession joinTextOnlyVenue(String venueName, String handle)
throws CollaborationException { throws CollaborationException {
VenueSession session = new VenueSession(eventBus, this); VenueSession session = new VenueSession(eventBus, this);
session.configureVenue(venueName, handle); session.configureVenue(venueName, handle);
session.connectToRoom(); session.connectToRoom();
sessions.put(session.getSessionId(), session); sessions.put(session.getSessionId(), session);
postEvent(session); postEvent(session);
return session; return session;
} }
/** /**
@ -482,33 +483,32 @@ public class CollaborationConnection implements IEventPublisher {
private void setupInternalConnectionListeners() { private void setupInternalConnectionListeners() {
final Roster roster = connection.getRoster(); final Roster roster = connection.getRoster();
roster.addRosterListener(new RosterListener() { roster.addRosterListener(new RosterListener() {
@Override @Override
public void presenceChanged(Presence presence) { public void presenceChanged(Presence presence) {
String fromId = presence.getFrom(); String fromId = presence.getFrom();
if (contactsMgr != null) { if (contactsMgr != null) {
UserId u = IDConverter.convertFrom(fromId); UserId u = IDConverter.convertFrom(fromId);
if (u != null) { if (u != null) {
RosterEntry entry = contactsMgr RosterEntry entry = contactsMgr.getRosterEntry(u);
.getRosterEntry(u);
eventBus.post(entry); eventBus.post(entry);
IRosterChangeEvent event = new RosterChangeEvent( IRosterChangeEvent event = new RosterChangeEvent(
RosterChangeType.MODIFY, entry); RosterChangeType.PRESENCE, entry, presence);
eventBus.post(event); eventBus.post(event);
} }
} }
} }
@Override @Override
public void entriesUpdated(Collection<String> addresses) { public void entriesUpdated(Collection<String> addresses) {
send(addresses, RosterChangeType.MODIFY); send(addresses, RosterChangeType.MODIFY);
} }
@Override @Override
public void entriesDeleted(Collection<String> addresses) { public void entriesDeleted(Collection<String> addresses) {
send(addresses, RosterChangeType.DELETE); send(addresses, RosterChangeType.DELETE);
} }
@Override @Override
public void entriesAdded(Collection<String> addresses) { public void entriesAdded(Collection<String> addresses) {
send(addresses, RosterChangeType.ADD); send(addresses, RosterChangeType.ADD);
@ -546,16 +546,17 @@ public class CollaborationConnection implements IEventPublisher {
} }
} }
private void setupConnectionListener(){ private void setupConnectionListener() {
if (isConnected()){ if (isConnected()) {
connection.addConnectionListener(new ConnectionListener() { connection.addConnectionListener(new ConnectionListener() {
@Override @Override
public void reconnectionSuccessful() { public void reconnectionSuccessful() {
statusHandler.debug("Client successfully reconnected to server"); statusHandler
.debug("Client successfully reconnected to server");
postSystemMessageToVenues("Connection to collaboration server reestablished."); postSystemMessageToVenues("Connection to collaboration server reestablished.");
} }
@Override @Override
public void reconnectionFailed(Exception e) { public void reconnectionFailed(Exception e) {
String reason = getErrorReason(e); String reason = getErrorReason(e);
@ -563,12 +564,13 @@ public class CollaborationConnection implements IEventPublisher {
+ reason, e); + reason, e);
sendDisconnectNotice(reason); sendDisconnectNotice(reason);
} }
@Override @Override
public void reconnectingIn(int seconds) { public void reconnectingIn(int seconds) {
statusHandler.debug("Client reconnecting to server in " + seconds + " seconds" ); statusHandler.debug("Client reconnecting to server in "
+ seconds + " seconds");
} }
@Override @Override
public void connectionClosedOnError(Exception e) { public void connectionClosedOnError(Exception e) {
String reason = getErrorReason(e); String reason = getErrorReason(e);
@ -591,7 +593,7 @@ public class CollaborationConnection implements IEventPublisher {
} }
return msg == null ? e.getLocalizedMessage() : msg; return msg == null ? e.getLocalizedMessage() : msg;
} }
@Override @Override
public void connectionClosed() { public void connectionClosed() {
statusHandler.info("Server closed connection"); statusHandler.info("Server closed connection");

View file

@ -163,6 +163,11 @@
id="com.raytheon.uf.viz.collaboration.ui.prefs.collaborationroomchangepreferencepage" id="com.raytheon.uf.viz.collaboration.ui.prefs.collaborationroomchangepreferencepage"
name="Room Alerts" name="Room Alerts"
category="com.raytheon.uf.viz.collaboration.ui.prefs.collaborationpreferencepage"/> category="com.raytheon.uf.viz.collaboration.ui.prefs.collaborationpreferencepage"/>
<page
class="com.raytheon.uf.viz.collaboration.ui.prefs.ContactNotifierPreferencePage"
id="com.raytheon.uf.viz.collaboration.ui.contactnotifierprefs"
name="Contact Notifiers"
category="com.raytheon.uf.viz.collaboration.ui.prefs.collaborationpreferencepage"/>
</extension> </extension>
<extension <extension
point="org.eclipse.ui.contexts"> point="org.eclipse.ui.contexts">

View file

@ -92,6 +92,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager.Grou
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
import com.raytheon.uf.viz.collaboration.comm.provider.user.SharedGroup; import com.raytheon.uf.viz.collaboration.comm.provider.user.SharedGroup;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.ui.actions.AddNotifierAction;
import com.raytheon.uf.viz.collaboration.ui.actions.AddToGroupAction; import com.raytheon.uf.viz.collaboration.ui.actions.AddToGroupAction;
import com.raytheon.uf.viz.collaboration.ui.actions.ArchiveViewerAction; import com.raytheon.uf.viz.collaboration.ui.actions.ArchiveViewerAction;
import com.raytheon.uf.viz.collaboration.ui.actions.ChangeFontAction; import com.raytheon.uf.viz.collaboration.ui.actions.ChangeFontAction;
@ -116,6 +117,7 @@ import com.raytheon.uf.viz.collaboration.ui.actions.UserSearchAction;
import com.raytheon.uf.viz.collaboration.ui.data.AlertWordWrapper; import com.raytheon.uf.viz.collaboration.ui.data.AlertWordWrapper;
import com.raytheon.uf.viz.collaboration.ui.data.CollaborationGroupContainer; import com.raytheon.uf.viz.collaboration.ui.data.CollaborationGroupContainer;
import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer; import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer;
import com.raytheon.uf.viz.collaboration.ui.notifier.NotifierTools;
import com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView; import com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView;
import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.icon.IconUtil; import com.raytheon.uf.viz.core.icon.IconUtil;
@ -142,6 +144,7 @@ import com.raytheon.viz.ui.views.CaveFloatingView;
* Jan 30, 2014 2698 bclement fixed alias not working for roster entries * Jan 30, 2014 2698 bclement fixed alias not working for roster entries
* removed unneeded subscription for nickname changed events * removed unneeded subscription for nickname changed events
* Feb 12, 2014 2799 bclement fixed double click chat not working for roster entries * Feb 12, 2014 2799 bclement fixed double click chat not working for roster entries
* Feb 24, 2014 2632 mpduff Add Notifier actions.
* *
* </pre> * </pre>
* *
@ -272,6 +275,7 @@ public class CollaborationGroupView extends CaveFloatingView implements
}; };
collapseAllAction = new Action("Collapse All") { collapseAllAction = new Action("Collapse All") {
@Override
public void run() { public void run() {
if (usersTreeViewer != null) { if (usersTreeViewer != null) {
usersTreeViewer.collapseAll(); usersTreeViewer.collapseAll();
@ -413,6 +417,7 @@ public class CollaborationGroupView extends CaveFloatingView implements
if (ContactsManager.isBlocked(entry)) { if (ContactsManager.isBlocked(entry)) {
manager.add(new SendSubReqAction(entry)); manager.add(new SendSubReqAction(entry));
} }
manager.add(new AddNotifierAction(this));
} else if (o instanceof UserId) { } else if (o instanceof UserId) {
// the user // the user
UserId user = (UserId) o; UserId user = (UserId) o;
@ -516,6 +521,7 @@ public class CollaborationGroupView extends CaveFloatingView implements
SWT.COLOR_BLACK)); SWT.COLOR_BLACK));
final Text modText = new Text(composite, SWT.NONE); final Text modText = new Text(composite, SWT.NONE);
composite.addListener(SWT.Resize, new Listener() { composite.addListener(SWT.Resize, new Listener() {
@Override
public void handleEvent(Event e) { public void handleEvent(Event e) {
Rectangle rect = composite.getClientArea(); Rectangle rect = composite.getClientArea();
modText.setBounds(rect.x + 1, rect.y + 1, rect.width - 2, modText.setBounds(rect.x + 1, rect.y + 1, rect.width - 2,
@ -523,6 +529,7 @@ public class CollaborationGroupView extends CaveFloatingView implements
} }
}); });
Listener textListener = new Listener() { Listener textListener = new Listener() {
@Override
public void handleEvent(final Event e) { public void handleEvent(final Event e) {
switch (e.type) { switch (e.type) {
case SWT.KeyUp: case SWT.KeyUp:
@ -631,11 +638,13 @@ public class CollaborationGroupView extends CaveFloatingView implements
clearButton.addMouseListener(new MouseAdapter() { clearButton.addMouseListener(new MouseAdapter() {
private MouseMoveListener fMoveListener; private MouseMoveListener fMoveListener;
@Override
public void mouseDown(MouseEvent e) { public void mouseDown(MouseEvent e) {
clearButton.setImage(pressedImage); clearButton.setImage(pressedImage);
fMoveListener = new MouseMoveListener() { fMoveListener = new MouseMoveListener() {
private boolean fMouseInButton = true; private boolean fMouseInButton = true;
@Override
public void mouseMove(MouseEvent e) { public void mouseMove(MouseEvent e) {
boolean mouseInButton = isMouseInButton(e); boolean mouseInButton = isMouseInButton(e);
if (mouseInButton != fMouseInButton) { if (mouseInButton != fMouseInButton) {
@ -648,6 +657,7 @@ public class CollaborationGroupView extends CaveFloatingView implements
clearButton.addMouseMoveListener(fMoveListener); clearButton.addMouseMoveListener(fMoveListener);
} }
@Override
public void mouseUp(MouseEvent e) { public void mouseUp(MouseEvent e) {
if (fMoveListener != null) { if (fMoveListener != null) {
clearButton.removeMouseMoveListener(fMoveListener); clearButton.removeMouseMoveListener(fMoveListener);
@ -670,15 +680,18 @@ public class CollaborationGroupView extends CaveFloatingView implements
} }
}); });
clearButton.addMouseTrackListener(new MouseTrackAdapter() { clearButton.addMouseTrackListener(new MouseTrackAdapter() {
@Override
public void mouseEnter(MouseEvent e) { public void mouseEnter(MouseEvent e) {
clearButton.setImage(activeImage); clearButton.setImage(activeImage);
} }
@Override
public void mouseExit(MouseEvent e) { public void mouseExit(MouseEvent e) {
clearButton.setImage(inactiveImage); clearButton.setImage(inactiveImage);
} }
}); });
clearButton.addDisposeListener(new DisposeListener() { clearButton.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) { public void widgetDisposed(DisposeEvent e) {
inactiveImage.dispose(); inactiveImage.dispose();
activeImage.dispose(); activeImage.dispose();
@ -687,12 +700,14 @@ public class CollaborationGroupView extends CaveFloatingView implements
}); });
clearButton.getAccessible().addAccessibleListener( clearButton.getAccessible().addAccessibleListener(
new AccessibleAdapter() { new AccessibleAdapter() {
@Override
public void getName(AccessibleEvent e) { public void getName(AccessibleEvent e) {
e.result = WorkbenchMessages.FilteredTree_AccessibleListenerClearButton; e.result = WorkbenchMessages.FilteredTree_AccessibleListenerClearButton;
} }
}); });
clearButton.getAccessible().addAccessibleControlListener( clearButton.getAccessible().addAccessibleControlListener(
new AccessibleControlAdapter() { new AccessibleControlAdapter() {
@Override
public void getRole(AccessibleControlEvent e) { public void getRole(AccessibleControlEvent e) {
e.detail = ACC.ROLE_PUSHBUTTON; e.detail = ACC.ROLE_PUSHBUTTON;
} }
@ -767,6 +782,7 @@ public class CollaborationGroupView extends CaveFloatingView implements
* *
* @return * @return
*/ */
@Override
public UserId[] getSelectedUsers() { public UserId[] getSelectedUsers() {
Set<UserId> selectedUsers = new HashSet<UserId>(); Set<UserId> selectedUsers = new HashSet<UserId>();
IStructuredSelection selection = (IStructuredSelection) usersTreeViewer IStructuredSelection selection = (IStructuredSelection) usersTreeViewer
@ -853,6 +869,8 @@ public class CollaborationGroupView extends CaveFloatingView implements
// Refresh the whole tree since there can be instances of the same user // Refresh the whole tree since there can be instances of the same user
// elsewhere that might not .equals this one. // elsewhere that might not .equals this one.
refreshUsersTreeViewerAsync(usersTreeViewer.getInput()); refreshUsersTreeViewerAsync(usersTreeViewer.getInput());
NotifierTools.processNotifiers(rosterChangeEvent.getPresence());
} }
@Subscribe @Subscribe

View file

@ -68,7 +68,7 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
public class CollaborationUtils { public class CollaborationUtils {
private static final transient IUFStatusHandler statusHandler = UFStatus private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(CollaborationUtils.class); .getHandler(CollaborationUtils.class);
public static final Presence.Mode[] statusModes = { Mode.available, public static final Presence.Mode[] statusModes = { Mode.available,
@ -106,7 +106,7 @@ public class CollaborationUtils {
"collaboration" + File.separator "collaboration" + File.separator
+ "collaborationAliases.xml"); + "collaborationAliases.xml");
if (file.exists()) { if (file.exists()) {
UserIdWrapper ids = (UserIdWrapper) JAXB.unmarshal(file.getFile(), UserIdWrapper ids = JAXB.unmarshal(file.getFile(),
UserIdWrapper.class); UserIdWrapper.class);
if (ids.getUserIds() == null) { if (ids.getUserIds() == null) {
return new UserId[0]; return new UserId[0];
@ -159,20 +159,21 @@ public class CollaborationUtils {
file = PathManagerFactory.getPathManager().getLocalizationFile(context, file = PathManagerFactory.getPathManager().getLocalizationFile(context,
"collaboration" + File.separator + "alertWords.xml"); "collaboration" + File.separator + "alertWords.xml");
if (file.exists() || file.getFile().exists()) { if (file.exists() || file.getFile().exists()) {
AlertWordWrapper words = (AlertWordWrapper) JAXB.unmarshal( AlertWordWrapper words = JAXB.unmarshal(file.getFile(),
file.getFile(), AlertWordWrapper.class); AlertWordWrapper.class);
if (words.getAlertWords() == null) { if (words.getAlertWords() == null) {
return new ArrayList<AlertWord>(); return new ArrayList<AlertWord>();
} else {
List<AlertWord> alertWords = new ArrayList<AlertWord>();
for (int i = 0; i < words.getAlertWords().length; i++) {
alertWords.add(words.getAlertWords()[i]);
}
return alertWords;
} }
} else {
return new ArrayList<AlertWord>(); List<AlertWord> alertWords = new ArrayList<AlertWord>();
for (int i = 0; i < words.getAlertWords().length; i++) {
alertWords.add(words.getAlertWords()[i]);
}
return alertWords;
} }
return new ArrayList<AlertWord>();
} }
public static void saveAlertWords(List<AlertWord> words) { public static void saveAlertWords(List<AlertWord> words) {
@ -211,5 +212,4 @@ public class CollaborationUtils {
"Unable to save alert words to localization", e); "Unable to save alert words to localization", e);
} }
} }
} }

View file

@ -0,0 +1,90 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.actions;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.widgets.Display;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.ui.Activator;
import com.raytheon.uf.viz.collaboration.ui.IUserSelector;
import com.raytheon.uf.viz.collaboration.ui.session.AddNotifierDlg;
import com.raytheon.uf.viz.core.icon.IconUtil;
/**
* Launch the AddNotifier dialog.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 20, 2014 2632 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class AddNotifierAction extends Action {
/** The IUserSelector */
private final IUserSelector userSelection;
/**
* Constructor.
*
* @param userSelection
*/
public AddNotifierAction(IUserSelector userSelection) {
super("Add Notifier...", getNotifierImageDescriptor());
this.userSelection = userSelection;
}
/**
* {@inheritDoc}
*/
@Override
public void run() {
List<String> userList = new ArrayList<String>();
for (UserId id : userSelection.getSelectedUsers()) {
userList.add(id.getName());
}
AddNotifierDlg dlg = new AddNotifierDlg(Display.getCurrent()
.getActiveShell(),
userList.toArray(new String[userList.size()]));
dlg.open();
}
/**
* Get the image descriptor.
*
* @return The ImageDescriptor object
*/
public static ImageDescriptor getNotifierImageDescriptor() {
return IconUtil.getImageDescriptor(Activator.getDefault().getBundle(),
"add_correction.gif");
}
}

View file

@ -0,0 +1,64 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.notifier;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlType;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
/**
* Contact Notifier Types.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 20, 2014 2632 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
@XmlType(name = "notifier")
@XmlEnum
@DynamicSerialize
public enum Notifier {
@XmlEnumValue("sendMessage")
SendMessage("Sends Me A Message"), @XmlEnumValue("signOn")
SignOn("Signs On"), @XmlEnumValue("signOff")
SignOff("Signs Off"), @XmlEnumValue("away")
Away("Becomes Unavailable"), @XmlEnumValue("return")
Returns("Becomes Available");
private String description;
Notifier(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}

View file

@ -0,0 +1,237 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.notifier;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
/**
* Notifier Task. Holds a list of {@link Notifier} actions.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 20, 2014 2632 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
@DynamicSerialize
public class NotifierTask {
/** Set of Notifiers for this task */
@XmlElements({ @XmlElement(name = "notifier") })
private Set<Notifier> notifierList;
/** User to whom this task applies */
@XmlElement
private String userName;
/** Path to the sound file */
@XmlElement
private String soundFilePath;
/** Recurring pounce flag */
@XmlElement
private boolean recurring;
/**
* Default Constructor.
*/
public NotifierTask() {
notifierList = new HashSet<Notifier>();
}
/**
* Create with the provided list of Notifiers.
*
* @param notifiers
* List of notifiers
*/
public NotifierTask(Notifier... notifiers) {
for (Notifier notifier : notifiers) {
notifierList.add(notifier);
}
}
/**
* Add a notifier.
*
* @param notifier
* The notifier to add
*/
public void addNotifier(Notifier notifier) {
notifierList.add(notifier);
}
/**
* Get the notifiers.
*
* @return The Set of Notifiers
*/
public Set<Notifier> getNotifiers() {
return notifierList;
}
/**
*
* @return the userName
*/
public String getUserName() {
return userName;
}
/**
* @param userName
* the userName to set
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
* @return the notifierList
*/
public Set<Notifier> getNotifierList() {
return notifierList;
}
/**
* @param notifierList
* the notifierList to set
*/
public void setNotifierList(Set<Notifier> notifierList) {
this.notifierList = notifierList;
}
/**
* @return the soundFilePath
*/
public String getSoundFilePath() {
return soundFilePath;
}
/**
* @param soundFilePath
* the soundFilePath to set
*/
public void setSoundFilePath(String soundFilePath) {
this.soundFilePath = soundFilePath;
}
/**
* @return the recurring
*/
public boolean isRecurring() {
return recurring;
}
/**
* @param recurring
* the recurring to set
*/
public void setRecurring(boolean recurring) {
this.recurring = recurring;
}
public boolean isSoundValid() {
return soundFilePath != null && soundFilePath.length() > 0;
}
public boolean containsSendMessage() {
return notifierList.contains(Notifier.SendMessage);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((notifierList == null) ? 0 : notifierList.hashCode());
result = prime * result + (recurring ? 1231 : 1237);
result = prime * result
+ ((soundFilePath == null) ? 0 : soundFilePath.hashCode());
result = prime * result
+ ((userName == null) ? 0 : userName.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof NotifierTask)) {
return false;
}
NotifierTask other = (NotifierTask) obj;
if (notifierList == null) {
if (other.notifierList != null) {
return false;
}
} else if (!notifierList.equals(other.notifierList)) {
return false;
}
if (recurring != other.recurring) {
return false;
}
if (soundFilePath == null) {
if (other.soundFilePath != null) {
return false;
}
} else if (!soundFilePath.equals(other.soundFilePath)) {
return false;
}
if (userName == null) {
if (other.userName != null) {
return false;
}
} else if (!userName.equals(other.userName)) {
return false;
}
return true;
}
}

View file

@ -0,0 +1,66 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.notifier;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* XML Wrapper for the {@link NotifierTask}s
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 21, 2014 2632 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
@DynamicSerialize
public class NotifierTaskXML {
/** Array of notifier tasks */
@DynamicSerializeElement
private NotifierTask[] notifierTasks;
/**
* @return the notifierTasks
*/
public NotifierTask[] getNotifierTasks() {
if (notifierTasks == null) {
notifierTasks = new NotifierTask[0];
}
return notifierTasks;
}
/**
* @param notifierTasks
* the notifierTasks to set
*/
public void setNotifierTasks(NotifierTask[] notifierTasks) {
this.notifierTasks = notifierTasks;
}
}

View file

@ -0,0 +1,297 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.notifier;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.xml.bind.JAXB;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Mode;
import org.jivesoftware.smack.packet.Presence.Type;
import sun.audio.AudioDataStream;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.core.sounds.SoundUtil;
/**
* Contact Notifier Utility Class.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 24, 2014 2632 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class NotifierTools {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(NotifierTools.class);
/** Set of user names of users currently online */
private static Set<String> usersOnline = new HashSet<String>();
/** Contact notifier config file */
private static final String NOTIFIER_FILE_PATH = "collaboration/contactNotifiers.xml";
/** Sound directory in localization */
private static final String SOUND_DIR = "collaboration/sounds";
/** AudioDataStream object */
private static AudioDataStream ads = null;
/** The contact notifier localization file */
private static LocalizationFile taskFile;
/**
* Process appropriate notifiers for this presence change.
*
* @param presence
* The updated Presence
*/
public static void processNotifiers(Presence presence) {
UserId userId = IDConverter.convertFrom(presence.getFrom());
NotifierTask task = NotifierTools.getNotifierTask(userId.getName());
if (task != null && task.getUserName().equals(userId.getName())) {
Presence rosterPresence = CollaborationConnection.getConnection()
.getContactsManager().getPresence(userId);
Mode mode = rosterPresence.getMode();
Type type = presence.getType();
Set<Notifier> notifiers = task.getNotifierList();
// Sign on/off events
if (!usersOnline.contains(userId.getName())
&& Type.available == type) {
usersOnline.add(userId.getName());
if (notifiers.contains(Notifier.SignOn)) {
executeNotifierTask(task);
NotifierTools.taskExecuted(task);
return;
}
} else if (usersOnline.contains(userId.getName())
&& (Type.unavailable == type)) {
if (notifiers.contains(Notifier.SignOff)) {
executeNotifierTask(task);
usersOnline.remove(userId.getName());
NotifierTools.taskExecuted(task);
return;
}
}
// presence mode change events
for (Notifier n : notifiers) {
if (Notifier.Returns == n && mode == null) {
/*
* Apparently a null mode is the same as available. See
* AbstractUserLabelProvider.getImageName();
*/
executeNotifierTask(task);
NotifierTools.taskExecuted(task);
break;
} else if (Notifier.Away == n
&& (Mode.away == mode || Mode.xa == mode || Mode.dnd == mode)) {
executeNotifierTask(task);
NotifierTools.taskExecuted(task);
break;
}
}
}
}
/**
* Execute the NotifierTask.
*
* @param task
* The NotifierTask to execute
*/
private static void executeNotifierTask(NotifierTask task) {
if (task.isSoundValid()) {
SoundUtil.playSound(task.getSoundFilePath());
}
}
/**
* Save the notifiers.
*
* @param taskList
* List of NotifierTasks
* @return true if saved successfully
*/
public static boolean saveNotifiers(List<NotifierTask> taskList) {
for (NotifierTask notifier : taskList) {
String soundPath = notifier.getSoundFilePath();
if (soundPath != null && !soundPath.isEmpty()) {
String path = copySoundFile(soundPath);
// Reset sound file path the localization
notifier.setSoundFilePath(path);
}
}
NotifierTaskXML wrapper = new NotifierTaskXML();
wrapper.setNotifierTasks(taskList.toArray(new NotifierTask[0]));
LocalizationFile file = null;
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext context = pm.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.USER);
file = PathManagerFactory.getPathManager().getLocalizationFile(context,
NOTIFIER_FILE_PATH);
JAXB.marshal(wrapper, file.getFile());
try {
file.save();
} catch (LocalizationOpFailedException e) {
statusHandler.handle(Priority.PROBLEM,
"Unable to save Contact Notifiers to localization", e);
return false;
}
return true;
}
/**
* Get all the configured NotifierTasks.
*
* @return List of NotifierTasks
*/
public static synchronized List<NotifierTask> getNotifierTasks() {
List<NotifierTask> taskList = new ArrayList<NotifierTask>();
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext context = pm.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.USER);
taskFile = PathManagerFactory.getPathManager().getLocalizationFile(
context, NOTIFIER_FILE_PATH);
if (taskFile.exists() || taskFile.getFile().exists()) {
NotifierTaskXML wrapper = JAXB.unmarshal(taskFile.getFile(),
NotifierTaskXML.class);
if (wrapper != null) {
for (NotifierTask task : wrapper.getNotifierTasks()) {
taskList.add(task);
}
}
}
return taskList;
}
/**
* Copy the sound file to cave static user level localization.
*
* @param soundPath
* The path to the file to copy
* @return The new path
*/
private static String copySoundFile(String soundPath) {
String[] dirs = soundPath.split(File.separator);
String filename = dirs[dirs.length - 1];
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext context = pm.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.USER);
LocalizationFile lFile = pm.getLocalizationFile(context,
FileUtil.join(SOUND_DIR, filename));
if (lFile.exists() && !soundPath.equals(lFile.getFile().getPath())) {
MessageBox messageBox = new MessageBox(Display.getCurrent()
.getActiveShell(), SWT.YES | SWT.NO);
messageBox.setText("File exists");
messageBox
.setMessage("File already exists, overwrite the existing file? ");
int answer = messageBox.open();
if (answer == SWT.YES) {
return copyFile(soundPath, lFile);
}
}
if (!lFile.exists()) {
return copyFile(soundPath, lFile);
}
return soundPath;
}
private static String copyFile(String path, LocalizationFile lFile) {
File soundFile = new File(path);
File destination = lFile.getFile();
try {
FileUtil.copyFile(soundFile, destination);
lFile.save();
} catch (IOException e) {
statusHandler.handle(Priority.PROBLEM,
"Error Occured copying sound file", e);
} catch (LocalizationOpFailedException e) {
statusHandler.handle(Priority.PROBLEM,
"Error Occured copying sound file", e);
}
return destination.getAbsolutePath();
}
/**
* Get a notifier task for the specified user name.
*
* @param name
* The user name
* @return The NotifierTask or null if none
*/
public static NotifierTask getNotifierTask(String name) {
for (NotifierTask task : getNotifierTasks()) {
if (task.getUserName().equals(name)) {
return task;
}
}
return null;
}
public static synchronized void taskExecuted(NotifierTask task) {
if (!task.isRecurring()) {
List<NotifierTask> tasks = getNotifierTasks();
tasks.remove(task);
saveNotifiers(tasks);
}
}
}

View file

@ -32,7 +32,7 @@ import org.eclipse.swt.widgets.Display;
import com.raytheon.uf.viz.collaboration.ui.data.AlertWord; import com.raytheon.uf.viz.collaboration.ui.data.AlertWord;
/** /**
* TODO Add Description * Get the labels for the Alert Words for the preference page.
* *
* <pre> * <pre>
* *
@ -40,7 +40,8 @@ import com.raytheon.uf.viz.collaboration.ui.data.AlertWord;
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* May 17, 2012 mnash Initial creation * May 17, 2012 mnash Initial creation
* Feb 24, 2014 2632 mpduff Renamed from CollaborationPreferencesLabelProvider
* *
* </pre> * </pre>
* *
@ -48,7 +49,7 @@ import com.raytheon.uf.viz.collaboration.ui.data.AlertWord;
* @version 1.0 * @version 1.0
*/ */
public class CollaborationPreferencesLabelProvider extends ColumnLabelProvider { public class AlertWordLabelProvider extends ColumnLabelProvider {
private List<Color> colors = null; private List<Color> colors = null;
@ -57,7 +58,7 @@ public class CollaborationPreferencesLabelProvider extends ColumnLabelProvider {
/** /**
* *
*/ */
public CollaborationPreferencesLabelProvider() { public AlertWordLabelProvider() {
colors = new ArrayList<Color>(); colors = new ArrayList<Color>();
fonts = new ArrayList<Font>(); fonts = new ArrayList<Font>();
} }

View file

@ -57,7 +57,7 @@ import com.raytheon.uf.viz.collaboration.ui.data.AlertWord;
import com.raytheon.uf.viz.collaboration.ui.data.AlertWordWrapper; import com.raytheon.uf.viz.collaboration.ui.data.AlertWordWrapper;
/** /**
* TODO Add Description * The alert words preference page for collaboration.
* *
* <pre> * <pre>
* *
@ -65,7 +65,8 @@ import com.raytheon.uf.viz.collaboration.ui.data.AlertWordWrapper;
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* May 17, 2012 mnash Initial creation * May 17, 2012 mnash Initial creation
* Feb 24, 2014 2632 mpduf Created CollaborationPreferencesAlertWordLabelProvider
* *
* </pre> * </pre>
* *
@ -100,7 +101,7 @@ public class CollaborationAlertWordsPreferencePage extends
viewer = new TableViewer(getFieldEditorParent()); viewer = new TableViewer(getFieldEditorParent());
viewer.setContentProvider(new CollaborationPreferenceContentProvider()); viewer.setContentProvider(new CollaborationPreferenceContentProvider());
viewer.setLabelProvider(new CollaborationPreferencesLabelProvider()); viewer.setLabelProvider(new AlertWordLabelProvider());
viewer.getTable().setLayoutData(data); viewer.getTable().setLayoutData(data);
final StringFieldEditor stringEditor = new StringFieldEditor( final StringFieldEditor stringEditor = new StringFieldEditor(
@ -255,6 +256,7 @@ public class CollaborationAlertWordsPreferencePage extends
viewer.setInput(CollaborationUtils.getAlertWords()); viewer.setInput(CollaborationUtils.getAlertWords());
} }
@Override
public boolean performOk() { public boolean performOk() {
List<AlertWord> words = (List<AlertWord>) viewer.getInput(); List<AlertWord> words = (List<AlertWord>) viewer.getInput();
CollaborationUtils.saveAlertWords(words); CollaborationUtils.saveAlertWords(words);

View file

@ -0,0 +1,51 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.prefs;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import com.raytheon.uf.viz.collaboration.ui.notifier.NotifierTask;
/**
* Get the labels for the NotifierTasks for the preference page.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 21, 2014 2632 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class ContactNotifierLabelProvider extends ColumnLabelProvider {
@Override
public String getText(Object element) {
NotifierTask task = (NotifierTask) element;
return task.getUserName();
}
}

View file

@ -0,0 +1,283 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.prefs;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import com.google.common.collect.Lists;
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager;
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
import com.raytheon.uf.viz.collaboration.comm.provider.user.SharedGroup;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.ui.Activator;
import com.raytheon.uf.viz.collaboration.ui.notifier.NotifierTask;
import com.raytheon.uf.viz.collaboration.ui.notifier.NotifierTools;
import com.raytheon.uf.viz.collaboration.ui.session.AddNotifierDlg;
import com.raytheon.viz.ui.dialogs.ICloseCallback;
/**
* Contact Notifier preferences page.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 20, 2014 2632 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class ContactNotifierPreferencePage extends PreferencePage implements
IWorkbenchPreferencePage {
/** The notifier list control */
private org.eclipse.swt.widgets.List notifierList;
/** Delete notifier button */
private Button deleteBtn;
/** Edit notifier button */
private Button editBtn;
/** New notifier button */
private Button newBtn;
/** Notifier task list */
private java.util.List<NotifierTask> taskList = NotifierTools
.getNotifierTasks();
/** Data map backing the notifier list */
private final Map<String, NotifierTask> dataMap = new HashMap<String, NotifierTask>();
/**
* {@inheritDoc}
*/
@Override
public void init(IWorkbench workbench) {
setPreferenceStore(Activator.getDefault().getPreferenceStore());
}
/**
* {@inheritDoc}
*/
@Override
protected Control createContents(Composite parent) {
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.horizontalSpan = 3;
gd.heightHint = 150;
notifierList = new org.eclipse.swt.widgets.List(parent, SWT.BORDER
| SWT.V_SCROLL);
notifierList.setLayoutData(gd);
notifierList.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setButtonState();
}
});
Composite buttonComp = new Composite(parent, SWT.NONE);
buttonComp.setLayout(new GridLayout(3, false));
gd = new GridData(SWT.RIGHT, SWT.FILL, true, true);
gd.horizontalSpan = 3;
buttonComp.setLayoutData(gd);
gd = new GridData(75, SWT.DEFAULT);
editBtn = new Button(buttonComp, SWT.PUSH);
editBtn.setText("Edit...");
editBtn.setLayoutData(gd);
editBtn.setEnabled(false);
editBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
editNotifierTask();
}
});
gd = new GridData(75, SWT.DEFAULT);
newBtn = new Button(buttonComp, SWT.PUSH);
newBtn.setText("New...");
newBtn.setLayoutData(gd);
newBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
newNotifierTask();
}
});
gd = new GridData(75, SWT.DEFAULT);
deleteBtn = new Button(buttonComp, SWT.PUSH);
deleteBtn.setText("Delete");
deleteBtn.setLayoutData(gd);
deleteBtn.setEnabled(false);
deleteBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
deleteNotifierTask();
}
});
populate();
return null;
}
/**
* Populate the list.
*/
private void populate() {
taskList = NotifierTools.getNotifierTasks();
for (NotifierTask task : taskList) {
dataMap.put(task.getUserName(), task);
}
Collection<String> items = dataMap.keySet();
List<String> dataList = Lists.newArrayList(items);
Collections.sort(dataList);
notifierList.setItems(dataList.toArray(new String[0]));
}
/**
* Edit the notifier task.
*/
private void editNotifierTask() {
String user = notifierList.getItem(notifierList.getSelectionIndex());
NotifierTask task = dataMap.get(user);
if (task != null) {
AddNotifierDlg dlg = new AddNotifierDlg(getShell(),
new String[] { task.getUserName() });
dlg.open();
}
}
/**
* Delete the notifier task.
*/
private void deleteNotifierTask() {
String user = notifierList.getItem(notifierList.getSelectionIndex());
NotifierTask task = dataMap.get(user);
if (task != null) {
taskList.remove(task);
notifierList.remove(notifierList.getSelectionIndex());
}
setButtonState();
}
/**
* Set the state of the buttons.
*/
private void setButtonState() {
if (notifierList.getSelectionCount() > 0) {
deleteBtn.setEnabled(true);
editBtn.setEnabled(true);
} else {
deleteBtn.setEnabled(false);
editBtn.setEnabled(false);
}
}
/**
* Create a new notifier task.
*/
private void newNotifierTask() {
CollaborationConnection conn = CollaborationConnection.getConnection();
if (conn != null) {
String[] contacts = getContacts();
ICloseCallback callback = new ICloseCallback() {
@Override
public void dialogClosed(Object returnValue) {
populate();
}
};
AddNotifierDlg dlg = new AddNotifierDlg(getShell(), contacts,
callback);
dlg.open();
} else {
MessageBox messageDialog = new MessageBox(this.getShell(), SWT.OK);
messageDialog.setText("Must Log In");
messageDialog
.setMessage("User must be logged in to Collaboration to add contact notifiers.");
messageDialog.open();
}
}
/**
* Get the contacts.
*
* @return String[] of contacts
*/
private String[] getContacts() {
Set<String> users = new HashSet<String>();
ContactsManager contactsManager = CollaborationConnection
.getConnection().getContactsManager();
for (RosterGroup rg : contactsManager.getGroups()) {
for (RosterEntry re : rg.getEntries()) {
UserId userId = IDConverter.convertFrom(re);
users.add(userId.getName());
}
}
for (SharedGroup rg : contactsManager.getSharedGroups()) {
for (RosterEntry re : rg.getEntries()) {
UserId userId = IDConverter.convertFrom(re);
users.add(userId.getName());
}
}
for (RosterEntry re : contactsManager.getNonGroupedContacts()) {
UserId userId = IDConverter.convertFrom(re);
users.add(userId.getName());
}
return users.toArray(new String[users.size()]);
}
@Override
public boolean performOk() {
NotifierTools.saveNotifiers(taskList);
return true;
}
}

View file

@ -19,11 +19,6 @@
**/ **/
package com.raytheon.uf.viz.collaboration.ui.session; package com.raytheon.uf.viz.collaboration.ui.session;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -58,15 +53,7 @@ import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService; import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
import sun.audio.AudioData;
import sun.audio.AudioDataStream;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.viz.collaboration.comm.identity.IMessage; import com.raytheon.uf.viz.collaboration.comm.identity.IMessage;
import com.raytheon.uf.viz.collaboration.comm.identity.user.IUser; import com.raytheon.uf.viz.collaboration.comm.identity.user.IUser;
@ -82,6 +69,7 @@ import com.raytheon.uf.viz.collaboration.ui.data.AlertWord;
import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants; import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.icon.IconUtil; import com.raytheon.uf.viz.core.icon.IconUtil;
import com.raytheon.uf.viz.core.sounds.SoundUtil;
import com.raytheon.viz.ui.views.CaveFloatingView; import com.raytheon.viz.ui.views.CaveFloatingView;
/** /**
@ -99,6 +87,7 @@ import com.raytheon.viz.ui.views.CaveFloatingView;
* Jan 30, 2014 2698 bclement get display name from child class * Jan 30, 2014 2698 bclement get display name from child class
* Feb 13, 2014 2751 bclement made generic * Feb 13, 2014 2751 bclement made generic
* Feb 18, 2014 2631 mpduff Add ability to play sounds on join actions * Feb 18, 2014 2631 mpduff Add ability to play sounds on join actions
* Feb 24, 2014 2632 mpduff Moved sound generation code to CollaborationUtils
* *
* </pre> * </pre>
* *
@ -108,9 +97,6 @@ import com.raytheon.viz.ui.views.CaveFloatingView;
public abstract class AbstractSessionView<T extends IUser> extends public abstract class AbstractSessionView<T extends IUser> extends
CaveFloatingView { CaveFloatingView {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(AbstractSessionView.class);
private static final String SESSION_IMAGE_KEY = "sessionId.key"; private static final String SESSION_IMAGE_KEY = "sessionId.key";
private static ThreadLocal<SimpleDateFormat> dateFormatter = TimeUtil private static ThreadLocal<SimpleDateFormat> dateFormatter = TimeUtil
@ -135,8 +121,6 @@ public abstract class AbstractSessionView<T extends IUser> extends
private List<AlertWord> alertWords = null; private List<AlertWord> alertWords = null;
private AudioDataStream ads = null;
private Map<String, Font> fonts = null; private Map<String, Font> fonts = null;
private Map<RGB, Color> colors = null; private Map<RGB, Color> colors = null;
@ -475,53 +459,8 @@ public abstract class AbstractSessionView<T extends IUser> extends
playSound(filename); playSound(filename);
} }
/**
* Play a sound.
*
* @param filename
* The file to play
*/
protected void playSound(String filename) { protected void playSound(String filename) {
if (filename == null || filename.isEmpty()) { SoundUtil.playSound(filename);
return;
}
File soundFile = new File(filename);
InputStream in = null;
AudioStream as = null;
AudioData data = null;
try {
if (ads != null) {
AudioPlayer.player.stop(ads);
ads.close();
ads = null;
}
in = new FileInputStream(soundFile);
as = new AudioStream(in);
data = as.getData();
ads = new AudioDataStream(data);
AudioPlayer.player.start(ads);
} catch (FileNotFoundException e) {
statusHandler.handle(Priority.PROBLEM, "Unable to find sound file",
e);
} catch (IOException e) {
statusHandler.handle(Priority.PROBLEM, "Unable to read sound file",
e);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
// Ignore
}
try {
if (as != null) {
as.close();
}
} catch (IOException e) {
// Ignore
}
}
} }
protected String getJoinFile() { protected String getJoinFile() {
@ -581,13 +520,6 @@ public abstract class AbstractSessionView<T extends IUser> extends
msgArchive = null; msgArchive = null;
} }
try {
if (ads != null) {
ads.close();
}
} catch (IOException e) {
// Ignore
}
super.dispose(); super.dispose();
} }

View file

@ -0,0 +1,436 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.collaboration.ui.session;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import com.google.common.collect.Lists;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManager;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.util.StringUtil;
import com.raytheon.uf.viz.collaboration.ui.notifier.Notifier;
import com.raytheon.uf.viz.collaboration.ui.notifier.NotifierTask;
import com.raytheon.uf.viz.collaboration.ui.notifier.NotifierTools;
import com.raytheon.uf.viz.core.sounds.SoundUtil;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
import com.raytheon.viz.ui.dialogs.ICloseCallback;
/**
* Add Notifier Dialog.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 20, 2014 2632 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class AddNotifierDlg extends CaveSWTDialog {
/** Array of userIds */
private final String[] userIds;
/** Map of buttons to Notifiers */
private final Map<Button, Notifier> buttonMap = new HashMap<Button, Notifier>();
/** Set of NotifierTask objects */
private final Set<NotifierTask> taskSet = new HashSet<NotifierTask>();
/** The user select Combo box */
private Combo userCbo;
/** The sound file path text widget */
private Text soundTxt;
/** Recurring radio button */
private Button recurringRdo;
/** Close callback */
private final ICloseCallback callback;
/** The class return value */
private boolean returnValue = false;
/**
* Constructor.
*
* @param parent
* @param userIds
* @param callback
*/
public AddNotifierDlg(Shell parent, String[] userIds,
ICloseCallback callback) {
super(parent, SWT.DIALOG_TRIM, CAVE.DO_NOT_BLOCK);
setText("Add Notifier");
this.userIds = userIds;
this.callback = callback;
}
public AddNotifierDlg(Shell parent, String[] userIds) {
this(parent, userIds, null);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#constructShellLayout()
*/
@Override
protected Layout constructShellLayout() {
GridLayout mainLayout = new GridLayout(1, true);
mainLayout.marginHeight = 4;
mainLayout.marginWidth = 4;
return mainLayout;
}
/**
* {@inheritDoc}
*/
@Override
protected void initializeComponents(Shell shell) {
createUserComp(shell);
createActionComp(shell);
createBtnComp(shell);
}
/**
* Create the user composite.
*
* @param shell
*/
private void createUserComp(Shell shell) {
GridLayout gl = new GridLayout(2, false);
GridData gd = new GridData(SWT.LEFT, SWT.DEFAULT, false, false);
Composite userComp = new Composite(shell, SWT.NONE);
userComp.setLayout(gl);
userComp.setLayoutData(gd);
gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
Label userLbl = new Label(userComp, SWT.NONE);
userLbl.setText("Add Notifier to: ");
userLbl.setLayoutData(gd);
gd = new GridData(165, SWT.DEFAULT);
userCbo = new Combo(userComp, SWT.NONE);
userCbo.setLayoutData(gd);
userCbo.setItems(getUserIds());
userCbo.select(0);
userCbo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
NotifierTask task = NotifierTools.getNotifierTask(userCbo
.getText());
if (task != null) {
populate(task);
} else {
reset();
}
}
});
}
/**
* Create the action composite
*
* @param shell
*/
private void createActionComp(Shell shell) {
GridLayout gl = new GridLayout(1, false);
GridData gd = new GridData(SWT.LEFT, SWT.DEFAULT, false, false);
Composite lblComp = new Composite(shell, SWT.NONE);
lblComp.setLayout(gl);
lblComp.setLayoutData(gd);
gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
Label actionLbl = new Label(lblComp, SWT.NONE);
actionLbl.setText("Notify when Contact...");
actionLbl.setLayoutData(gd);
gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
gd.horizontalIndent = 20;
gl = new GridLayout(2, false);
Composite btnComp = new Composite(shell, SWT.NONE);
btnComp.setLayout(gl);
btnComp.setLayoutData(gd);
for (Notifier notifier : Notifier.values()) {
Button chk = new Button(btnComp, SWT.CHECK);
chk.setText(notifier.getDescription());
chk.setData(notifier);
buttonMap.put(chk, notifier);
}
gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
gl = new GridLayout(1, false);
Composite lblComp2 = new Composite(shell, SWT.NONE);
lblComp2.setLayout(gl);
lblComp2.setLayoutData(gd);
gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
Label soundLbl = new Label(lblComp2, SWT.NONE);
soundLbl.setText("Play this sound: ");
soundLbl.setLayoutData(gd);
gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
gd.horizontalIndent = 20;
gl = new GridLayout(3, false);
Composite soundComp = new Composite(shell, SWT.NONE);
soundComp.setLayout(gl);
soundComp.setLayoutData(gd);
gd = new GridData(175, SWT.DEFAULT);
soundTxt = new Text(soundComp, SWT.BORDER);
soundTxt.setLayoutData(gd);
gd = new GridData(75, SWT.DEFAULT);
Button browseBtn = new Button(soundComp, SWT.PUSH);
browseBtn.setText("Browse...");
browseBtn.setLayoutData(gd);
browseBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
PathManager manager = (PathManager) PathManagerFactory
.getPathManager();
LocalizationContext context = manager.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.USER);
LocalizationFile file = manager.getLocalizationFile(context,
"collaboration" + File.separator + "sounds"
+ File.separator);
if (!file.exists()) {
file.getFile().mkdirs();
}
FileDialog fileDlg = new FileDialog(Display.getCurrent()
.getActiveShell(), SWT.OPEN);
fileDlg.setFilterPath(file.getFile().getAbsolutePath());
String filePath = fileDlg.open();
if (!StringUtil.isEmptyString(filePath)) {
soundTxt.setText(filePath);
}
}
});
gd = new GridData(75, SWT.DEFAULT);
Button previewBtn = new Button(soundComp, SWT.PUSH);
previewBtn.setText("Preview");
previewBtn.setLayoutData(gd);
previewBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
String soundFile = soundTxt.getText().trim();
if (soundFile.length() > 0) {
SoundUtil.playSound(soundFile);
}
}
});
gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
Label freqLabel = new Label(shell, SWT.NONE);
freqLabel.setText("Notifier Frequency: ");
freqLabel.setLayoutData(gd);
gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
gd.horizontalIndent = 20;
gl = new GridLayout(2, false);
Composite freqComp = new Composite(shell, SWT.NONE);
freqComp.setLayout(gl);
freqComp.setLayoutData(gd);
gd = new GridData(SWT.DEFAULT, SWT.TOP, false, true);
Button singleRdo = new Button(freqComp, SWT.RADIO);
singleRdo.setLayoutData(gd);
singleRdo.setText("Single Instance");
singleRdo.setSelection(true);
gd = new GridData(SWT.DEFAULT, SWT.TOP, false, true);
recurringRdo = new Button(freqComp, SWT.RADIO);
recurringRdo.setLayoutData(gd);
recurringRdo.setText("Recurring");
}
private void createBtnComp(Shell shell) {
Label sl = new Label(shell, SWT.HORIZONTAL | SWT.SEPARATOR);
sl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
GridLayout gl = new GridLayout(2, false);
GridData gd = new GridData(SWT.CENTER, SWT.DEFAULT, false, false);
Composite comp = new Composite(shell, SWT.NONE);
comp.setLayout(gl);
comp.setLayoutData(gd);
GridData btnData = new GridData(75, SWT.DEFAULT);
Button addBtn = new Button(comp, SWT.PUSH);
addBtn.setText("Add");
addBtn.setLayoutData(btnData);
addBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
addNotifierTask();
returnValue = true;
}
});
btnData = new GridData(75, SWT.DEFAULT);
Button cancelBtn = new Button(comp, SWT.PUSH);
cancelBtn.setText("Close");
cancelBtn.setLayoutData(btnData);
cancelBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
returnValue = false;
close();
}
});
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#opened()
*/
@Override
protected void opened() {
// Check for existing notifiers
List<NotifierTask> taskList = NotifierTools.getNotifierTasks();
for (NotifierTask task : taskList) {
taskSet.add(task);
if (task.getUserName().equals(userCbo.getText())) {
this.populate(task);
return;
}
}
}
/**
* Populate the controls based on the provided task.
*
* @param task
* The task to populate the controls from
*/
private void populate(NotifierTask task) {
for (Button b : buttonMap.keySet()) {
if (task.getNotifierList().contains(b.getData())) {
b.setSelection(true);
}
}
soundTxt.setText(task.getSoundFilePath());
}
/**
* Reset the dialog controls.
*/
protected void reset() {
for (Button b : buttonMap.keySet()) {
b.setSelection(false);
}
soundTxt.setText("");
}
/**
* Get the user ids
*
* @return Array of user ids
*/
private String[] getUserIds() {
String[] usernames = new String[this.userIds.length];
for (int i = 0; i < userIds.length; i++) {
usernames[i] = userIds[i];
}
return usernames;
}
/**
* Add a notifier task based on the setting in the dialog.
*/
private void addNotifierTask() {
NotifierTask task = new NotifierTask();
task.setUserName(userCbo.getText());
task.setSoundFilePath(soundTxt.getText());
for (Button b : buttonMap.keySet()) {
if (b.getSelection()) {
task.addNotifier((Notifier) b.getData());
}
}
task.setRecurring(recurringRdo.getSelection());
taskSet.add(task);
if (NotifierTools.saveNotifiers(Lists.newArrayList(taskSet))) {
MessageBox messageDialog = new MessageBox(this.getShell(), SWT.OK);
messageDialog.setText("Notifier Saved");
messageDialog
.setMessage("The contact notifier was successfully saved.");
messageDialog.open();
} else {
MessageBox messageDialog = new MessageBox(this.getShell(), SWT.OK);
messageDialog.setText("Save Failed");
messageDialog.setMessage("The contact notifier failed to save.");
messageDialog.open();
}
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#disposed()
*/
@Override
protected void disposed() {
if (this.callback != null) {
callback.dialogClosed(returnValue);
}
}
}

View file

@ -40,11 +40,15 @@ import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
import com.raytheon.uf.viz.collaboration.comm.identity.IMessage;
import com.raytheon.uf.viz.collaboration.comm.identity.IPeerToPeer; import com.raytheon.uf.viz.collaboration.comm.identity.IPeerToPeer;
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
import com.raytheon.uf.viz.collaboration.comm.provider.user.RosterItem; import com.raytheon.uf.viz.collaboration.comm.provider.user.RosterItem;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionItem; import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionItem;
import com.raytheon.uf.viz.collaboration.ui.notifier.NotifierTask;
import com.raytheon.uf.viz.collaboration.ui.notifier.NotifierTools;
import com.raytheon.uf.viz.core.sounds.SoundUtil;
/** /**
* UI display for one-on-one chat sessions * UI display for one-on-one chat sessions
@ -58,6 +62,7 @@ import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionIt
* Mar 1, 2012 rferrel Initial creation * Mar 1, 2012 rferrel Initial creation
* Jan 30, 2014 2698 bclement added getDisplayName * Jan 30, 2014 2698 bclement added getDisplayName
* Feb 13, 2014 2751 bclement made parent generic * Feb 13, 2014 2751 bclement made parent generic
* Feb 28, 2014 2632 mpduff Override appendMessage for notifiers
* *
* </pre> * </pre>
* *
@ -119,6 +124,27 @@ public class PeerToPeerView extends AbstractSessionView<UserId> implements
sashForm.setWeights(new int[] { 20, 5 }); sashForm.setWeights(new int[] { 20, 5 });
} }
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView#
* appendMessage(com.raytheon.uf.viz.collaboration.comm.identity.IMessage)
*/
@Override
public void appendMessage(IMessage message) {
// Check for message notifiers
NotifierTask task = NotifierTools.getNotifierTask(message.getFrom()
.getName());
if (task != null && task.containsSendMessage()) {
if (task.isSoundValid()) {
SoundUtil.playSound(task.getSoundFilePath());
NotifierTools.taskExecuted(task);
}
}
super.appendMessage(message);
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* *

View file

@ -82,6 +82,7 @@ import com.raytheon.uf.viz.collaboration.ui.Activator;
import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionItem; import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionItem;
import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants; import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.sounds.SoundUtil;
import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
/** /**
@ -100,6 +101,7 @@ import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
* Jan 28, 2014 2698 bclement removed venue info * Jan 28, 2014 2698 bclement removed venue info
* Feb 13, 2014 2751 bclement VenueParticipant refactor * Feb 13, 2014 2751 bclement VenueParticipant refactor
* Feb 18, 2014 2631 mpduff Add processJoinAlert() * Feb 18, 2014 2631 mpduff Add processJoinAlert()
* Feb 24, 2014 2632 mpduff Move playSound to CollaborationUtils
* *
* </pre> * </pre>
* *
@ -785,10 +787,13 @@ public class SessionView extends AbstractSessionView<VenueParticipant>
* Process a room join alert. * Process a room join alert.
*/ */
protected void processJoinAlert() { protected void processJoinAlert() {
boolean enabled = Activator.getDefault().getPreferenceStore() boolean enabled = Activator
.getBoolean(CollabPrefConstants.ENABLE_JOIN_EVENTS_FIELD_EDITOR_ID); .getDefault()
.getPreferenceStore()
.getBoolean(
CollabPrefConstants.ENABLE_JOIN_EVENTS_FIELD_EDITOR_ID);
if (enabled) { if (enabled) {
this.playSound(getJoinFile()); SoundUtil.playSound(getJoinFile());
} }
} }
} }

View file

@ -78,6 +78,7 @@ Export-Package: com.raytheon.uf.viz.core,
com.raytheon.uf.viz.core.rsc.hdf5, com.raytheon.uf.viz.core.rsc.hdf5,
com.raytheon.uf.viz.core.rsc.updater, com.raytheon.uf.viz.core.rsc.updater,
com.raytheon.uf.viz.core.sampling, com.raytheon.uf.viz.core.sampling,
com.raytheon.uf.viz.core.sounds,
com.raytheon.uf.viz.core.status, com.raytheon.uf.viz.core.status,
com.raytheon.uf.viz.core.tile, com.raytheon.uf.viz.core.tile,
com.raytheon.uf.viz.core.time, com.raytheon.uf.viz.core.time,

View file

@ -0,0 +1,105 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.core.sounds;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import sun.audio.AudioData;
import sun.audio.AudioDataStream;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
/**
* Utility class for playing sounds.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 24, 2014 2636 mpduff Initial creation
*
* </pre>
*
* @author mpduff
* @version 1.0
*/
public class SoundUtil {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(SoundUtil.class);
/** AudioDataStream object */
private static AudioDataStream ads = null;
/**
* Play a sound from the file at the provided path.
*
* @param filename
* The filename path
*/
public static void playSound(String filename) {
if (filename == null || filename.isEmpty()) {
return;
}
File soundFile = new File(filename);
InputStream in = null;
AudioStream as = null;
AudioData data = null;
try {
if (ads != null) {
AudioPlayer.player.stop(ads);
ads.close();
ads = null;
}
in = new FileInputStream(soundFile);
as = new AudioStream(in);
data = as.getData();
ads = new AudioDataStream(data);
AudioPlayer.player.start(ads);
} catch (IOException e) {
statusHandler.handle(Priority.PROBLEM, "Unable to read sound file",
e);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
// Ignore
}
try {
if (as != null) {
as.close();
}
} catch (IOException e) {
// Ignore
}
}
}
}