Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorslewis2005-02-21 01:43:04 +0000
committerslewis2005-02-21 01:43:04 +0000
commit9ffc6c9c92d294ca16bc4578101579a6b957748e (patch)
tree99c5cd7ca80be99209daa38e4faf0cab6aaff98f
parent10f9b763a07a4d43030b5f663f4505e7183d8a99 (diff)
downloadorg.eclipse.ecf-9ffc6c9c92d294ca16bc4578101579a6b957748e.tar.gz
org.eclipse.ecf-9ffc6c9c92d294ca16bc4578101579a6b957748e.tar.xz
org.eclipse.ecf-9ffc6c9c92d294ca16bc4578101579a6b957748e.zip
Added ChatWindow, TextChatComposite and supporting classes/interfaces in org.eclipse.ecf.ui.views.
-rw-r--r--framework/bundles/org.eclipse.ecf.provider/plugin.xml5
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/.options1
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/META-INF/MANIFEST.MF3
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/icons/person.gifbin0 -> 139 bytes
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/UiPlugin.java2
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatLayout.java62
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatLine.java93
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatWindow.java306
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ILocalUserSettable.java8
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ITextInputHandler.java8
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/MessageLoader.java51
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/MessageLoader.properties4
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterView.java715
-rw-r--r--framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/TextChatComposite.java286
14 files changed, 1279 insertions, 265 deletions
diff --git a/framework/bundles/org.eclipse.ecf.provider/plugin.xml b/framework/bundles/org.eclipse.ecf.provider/plugin.xml
index d4a347175..1f2f154c0 100644
--- a/framework/bundles/org.eclipse.ecf.provider/plugin.xml
+++ b/framework/bundles/org.eclipse.ecf.provider/plugin.xml
@@ -5,7 +5,7 @@
point="org.eclipse.ecf.containerFactory">
<containerFactory
class="org.eclipse.ecf.provider.generic.ContainerInstantiator"
- description="Generic ECF Provider"
+ description="ECF Generic Provider"
name="org.eclipse.ecf.provider.generic.Client">
<defaultargument
type="org.eclipse.ecf.core.identity.ID"
@@ -23,6 +23,9 @@
<property
value="true"
name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.isClient"/>
+ <property
+ value="true"
+ name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.usenickname"/>
</containerFactory>
</extension>
<extension
diff --git a/framework/bundles/org.eclipse.ecf.ui/.options b/framework/bundles/org.eclipse.ecf.ui/.options
index 59c50a370..9300504ce 100644
--- a/framework/bundles/org.eclipse.ecf.ui/.options
+++ b/framework/bundles/org.eclipse.ecf.ui/.options
@@ -1,3 +1,4 @@
org.eclipse.ecf.ui/debug = true
org.eclipse.ecf.ui/debug/filter = *
org.eclipse.ecf.ui/debug/flag = true
+org.eclipse.ecf.ui/debug/textchatcomposite = true
diff --git a/framework/bundles/org.eclipse.ecf.ui/META-INF/MANIFEST.MF b/framework/bundles/org.eclipse.ecf.ui/META-INF/MANIFEST.MF
index 80713c40e..c6dbf533a 100644
--- a/framework/bundles/org.eclipse.ecf.ui/META-INF/MANIFEST.MF
+++ b/framework/bundles/org.eclipse.ecf.ui/META-INF/MANIFEST.MF
@@ -8,7 +8,8 @@ Bundle-Vendor: Eclipse.org
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui;reprovide=true,
org.eclipse.ecf,
- org.eclipse.core.runtime
+ org.eclipse.core.runtime,
+ org.eclipse.jface.text
Eclipse-AutoStart: true
Provide-Package: org.eclipse.ecf.ui.presence,
org.eclipse.ecf.ui,
diff --git a/framework/bundles/org.eclipse.ecf.ui/icons/person.gif b/framework/bundles/org.eclipse.ecf.ui/icons/person.gif
new file mode 100644
index 000000000..608d2d165
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.ui/icons/person.gif
Binary files differ
diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/UiPlugin.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/UiPlugin.java
index 0e2f6e890..eaa383513 100644
--- a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/UiPlugin.java
+++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/UiPlugin.java
@@ -11,6 +11,8 @@ public class UiPlugin extends AbstractUIPlugin {
public static final String PLUGIN_ID = "org.eclipse.ecf.ui";
+ public static final String PREF_DISPLAY_TIMESTAMP = "TextChatComposite.displaytimestamp";
+
//The shared instance.
private static UiPlugin plugin;
//Resource bundle.
diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatLayout.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatLayout.java
new file mode 100644
index 000000000..e5de2098c
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatLayout.java
@@ -0,0 +1,62 @@
+/****************************************************************************
+* Copyright (c) 2004 Composent, Inc. and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Composent, Inc. - initial API and implementation
+*****************************************************************************/
+
+package org.eclipse.ecf.ui.views;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Layout;
+
+
+class ChatLayout extends Layout {
+ protected static final int TEXT_HEIGHT_FUDGE = 8;
+ Point iExtent, tExtent;
+ int inputSize = 15;
+ int separatorSize = 5;
+ int textHeight = -1;
+ ChatLayout(int defaultInputSize, int sepSize) {
+ this.inputSize = defaultInputSize;
+ this.separatorSize = sepSize;
+ }
+ protected Point computeSize(Composite composite, int wHint, int hHint,
+ boolean changed) {
+ Control[] children = composite.getChildren();
+ if (changed || iExtent == null || tExtent == null) {
+ iExtent = children[0].computeSize(SWT.DEFAULT, SWT.DEFAULT,
+ false);
+ tExtent = children[1].computeSize(SWT.DEFAULT, SWT.DEFAULT,
+ false);
+ }
+ int width = iExtent.x + 5 + tExtent.x;
+ int height = Math.max(iExtent.y, tExtent.y);
+ return new Point(width + 2, height + 200);
+ }
+ protected void layout(Composite composite, boolean changed) {
+ Control[] children = composite.getChildren();
+ Point windowSize = composite.getSize();
+ children[0].setBounds(1, 1, windowSize.x, windowSize.y
+ - (inputSize + separatorSize));
+ children[1].setBounds(1, children[0].getSize().y + separatorSize,
+ windowSize.x, inputSize);
+ if (changed || iExtent == null || tExtent == null) {
+ iExtent = children[0].computeSize(SWT.DEFAULT, SWT.DEFAULT,
+ false);
+ tExtent = children[1].computeSize(SWT.DEFAULT, SWT.DEFAULT,
+ false);
+ }
+ }
+ protected void setInputTextHeight(int height) {
+ textHeight = height;
+ inputSize = textHeight + TEXT_HEIGHT_FUDGE;
+ }
+} \ No newline at end of file
diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatLine.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatLine.java
new file mode 100644
index 000000000..1034517a0
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatLine.java
@@ -0,0 +1,93 @@
+/*
+ * Created on Feb 18, 2005
+ *
+ */
+package org.eclipse.ecf.ui.views;
+
+import org.eclipse.ecf.core.user.IUser;
+
+/**
+ * @author kgilmer
+ *
+ */
+public class ChatLine {
+ private IUser originator = null; //
+ private String text = null;
+ private boolean isPrivate = false;
+ private boolean isRaw = false;
+ private boolean noCRLF = false;
+
+ public ChatLine() {
+
+ }
+
+ public ChatLine(String text) {
+ this.text = text;
+
+ }
+
+ public ChatLine(String text, IUser user) {
+ this.text = text;
+ this.originator = user;
+ }
+ /**
+ * @return Returns the originator.
+ */
+ public IUser getOriginator() {
+ return originator;
+ }
+ /**
+ * @param originator The originator to set.
+ */
+ public void setOriginator(IUser originator) {
+ this.originator = originator;
+ }
+ /**
+ * @return Returns the text.
+ */
+ public String getText() {
+ return text;
+ }
+ /**
+ * @param text The text to set.
+ */
+ public void setText(String text) {
+ this.text = text;
+ }
+ /**
+ * @return Returns the isPrivate.
+ */
+ public boolean isPrivate() {
+ return isPrivate;
+ }
+ /**
+ * @param isPrivate The isPrivate to set.
+ */
+ public void setPrivate(boolean isPrivate) {
+ this.isPrivate = isPrivate;
+ }
+ /**
+ * @return Returns the isRaw.
+ */
+ public boolean isRaw() {
+ return isRaw;
+ }
+ /**
+ * @param isRaw The isRaw to set.
+ */
+ public void setRaw(boolean isRaw) {
+ this.isRaw = isRaw;
+ }
+ /**
+ * @return Returns the noCRLF.
+ */
+ public boolean isNoCRLF() {
+ return noCRLF;
+ }
+ /**
+ * @param noCRLF The noCRLF to set.
+ */
+ public void setNoCRLF(boolean noCRLF) {
+ this.noCRLF = noCRLF;
+ }
+}
diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatWindow.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatWindow.java
new file mode 100644
index 000000000..49a1c2328
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ChatWindow.java
@@ -0,0 +1,306 @@
+/****************************************************************************
+* Copyright (c) 2004 Composent, Inc. and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Composent, Inc. - initial API and implementation
+*****************************************************************************/
+
+package org.eclipse.ecf.ui.views;
+
+import org.eclipse.core.runtime.Path;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.user.IUser;
+import org.eclipse.ecf.ui.UiPlugin;
+import org.eclipse.ecf.ui.messaging.IMessageViewer;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * @author pnehrer
+ *
+ */
+public class ChatWindow extends ApplicationWindow implements IMessageViewer {
+
+ protected static final String ICONS_PERSON_GIF = "icons/person.gif";
+ private static final long FLASH_INTERVAL = 600;
+
+ private String initText;
+ private TextChatComposite chat;
+ private Image image;
+ private Image blank;
+ private boolean flashing;
+
+ private String titleBarText;
+
+ protected ViewPart view;
+ protected IUser localUser;
+ protected IUser remoteUser;
+
+ protected IUser getLocalUser() {
+ return localUser;
+ }
+
+ protected IUser getRemoteUser() {
+ return remoteUser;
+ }
+ private final Runnable flipImage = new Runnable() {
+ public void run() {
+ Shell shell = getShell();
+ if (!shell.isDisposed())
+ if (blank == shell.getImage()) {
+ if (image != null && !image.isDisposed())
+ shell.setImage(image);
+ } else {
+ if (blank != null && !blank.isDisposed())
+ shell.setImage(blank);
+ }
+ }
+ };
+
+ private final Runnable showImageRunnable = new Runnable() {
+ public void run() {
+ Shell shell = getShell();
+ if (!shell.isDisposed() && image != null && !image.isDisposed())
+ shell.setImage(image);
+ }
+ };
+
+ private Flash flash;
+
+ private class Flash implements Runnable {
+
+ private final Display display;
+
+ public Flash(Display display) {
+ this.display = display;
+ }
+
+ public void run() {
+ while (true) {
+ synchronized (this) {
+ try {
+ while (!flashing)
+ wait();
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+
+ if (display.isDisposed())
+ break;
+
+ display.syncExec(flipImage);
+ synchronized (this) {
+ try {
+ wait(FLASH_INTERVAL);
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+ }
+ }
+ };
+
+ public ChatWindow(ViewPart view, String titleBarText, String initOutputText, IUser localUser, IUser remoteUser) {
+ super(null);
+ this.view = view;
+ this.titleBarText = titleBarText;
+ this.initText = initOutputText;
+ this.localUser = localUser;
+ this.remoteUser = remoteUser;
+ addStatusLine();
+ }
+
+ public void setStatus(final String status) {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ ChatWindow.super.setStatus(status);
+ }
+ });
+ }
+ protected String getShellName() {
+ return chat.getShellName();
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+ */
+ protected void configureShell(final Shell newShell) {
+ super.configureShell(newShell);
+ String shellTitlePrefix = MessageLoader.getString("ChatWindow.titleprefix");
+ if (shellTitlePrefix != null && !shellTitlePrefix.equals("")) {
+ shellTitlePrefix = shellTitlePrefix + ": ";
+ }
+ titleBarText = shellTitlePrefix + titleBarText;
+ newShell.setText(titleBarText);
+ image = ImageDescriptor.createFromURL(
+ UiPlugin.getDefault().find(new Path(ICONS_PERSON_GIF)))
+ .createImage();
+ newShell.setImage(image);
+ RGB[] colors = new RGB[2];
+ colors[0] = new RGB(0, 0, 0);
+ colors[1] = new RGB(255, 255, 255);
+ ImageData data = new ImageData(16, 16, 1, new PaletteData(colors));
+ data.transparentPixel = 0;
+ blank = new Image(newShell.getDisplay(), data);
+
+ flash = new Flash(newShell.getDisplay());
+ new Thread(flash).start();
+
+ newShell.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ flash();
+ if (image != null)
+ image.dispose();
+
+ if (blank != null)
+ blank.dispose();
+ }
+ });
+
+ newShell.addShellListener(new ShellAdapter() {
+ public void shellActivated(ShellEvent e) {
+ stopFlashing();
+ if (!chat.isDisposed())
+ chat.textinput.setFocus();
+ }
+ });
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
+ */
+ protected Control createContents(Composite parent) {
+ if (view == null) throw new NullPointerException("view cannot be null");
+ // Get ITextInputHandler from view
+ ITextInputHandler inputHandler = null;
+ Object obj = view.getAdapter(ITextInputHandler.class);
+ if (obj == null) {
+ throw new NullPointerException("view "+view+" did not provide ITextInputHandler adapter");
+ } else if (obj instanceof ITextInputHandler) {
+ inputHandler = (ITextInputHandler) obj;
+ }
+ chat = new TextChatComposite(parent, SWT.NORMAL, initText, inputHandler,getLocalUser(),getRemoteUser());
+ chat.setLayoutData(new GridData(GridData.FILL_BOTH));
+ chat.setFont(parent.getFont());
+ return chat;
+ }
+
+ public void setLocalUser(IUser localUser) {
+ this.localUser = localUser;
+ chat.setLocalUser(localUser);
+ }
+ public void setRemoteUser(IUser remoteUser) {
+ this.remoteUser = remoteUser;
+ chat.setRemoteUser(remoteUser);
+ }
+ protected TextChatComposite getTextChatComposite() {
+ return chat;
+ }
+
+ private boolean hasFocus = false;
+
+ public boolean hasFocus() {
+ boolean result = false;
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ if (getShell().isDisposed())
+ hasFocus = false;
+ else
+ hasFocus = hasFocus(getShell());
+ }
+ });
+ return hasFocus;
+ }
+
+ private boolean hasFocus(Composite composite) {
+ if (composite.isFocusControl())
+ return true;
+ else {
+ Control[] children = composite.getChildren();
+ for (int i = 0; i < children.length; ++i)
+ if (children[i] instanceof Composite
+ && hasFocus((Composite) children[i]))
+ return true;
+ else if (children[i].isFocusControl())
+ return true;
+ }
+
+ return false;
+ }
+
+ public void flash() {
+ synchronized (flash) {
+ if (!flashing) {
+ flashing = true;
+ flash.notify();
+ }
+ }
+ }
+
+ private void stopFlashing() {
+ synchronized (flash) {
+ if (flashing) {
+ flashing = false;
+ if (!getShell().isDisposed() && image != null && !image.isDisposed())
+ getShell().setImage(image);
+ flash.notify();
+ }
+ }
+ }
+
+ public void openAndFlash() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ flash();
+ if (!getShell().isVisible()) {
+ open();
+ }
+ }
+ });
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.window.Window#handleShellCloseEvent()
+ */
+ protected void handleShellCloseEvent() {
+ if (!getShell().isDisposed())
+ getShell().setVisible(false);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.ui.messaging.IMessageViewer#showMessage(org.eclipse.ecf.core.identity.ID, org.eclipse.ecf.core.identity.ID, org.eclipse.ecf.ui.messaging.IMessageViewer.Type, java.lang.String, java.lang.String)
+ */
+ public void showMessage(final ID fromID, ID toID, Type type, String subject, final String message) {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ if (chat != null) {
+ chat.appendText(new ChatLine(message,getRemoteUser()));
+ }
+ }
+ });
+ }
+} \ No newline at end of file
diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ILocalUserSettable.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ILocalUserSettable.java
new file mode 100644
index 000000000..1a6d423bd
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ILocalUserSettable.java
@@ -0,0 +1,8 @@
+package org.eclipse.ecf.ui.views;
+
+import org.eclipse.ecf.core.user.IUser;
+
+public interface ILocalUserSettable {
+
+ public void setLocalUser(IUser user, ITextInputHandler inputHandler);
+}
diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ITextInputHandler.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ITextInputHandler.java
new file mode 100644
index 000000000..4dd1901f5
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/ITextInputHandler.java
@@ -0,0 +1,8 @@
+package org.eclipse.ecf.ui.views;
+
+import org.eclipse.ecf.core.identity.ID;
+
+public interface ITextInputHandler {
+ public void handleTextLine(ID userID, String text);
+ public void handleStartTyping(ID userID);
+}
diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/MessageLoader.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/MessageLoader.java
new file mode 100644
index 000000000..76ea52960
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/MessageLoader.java
@@ -0,0 +1,51 @@
+/****************************************************************************
+* Copyright (c) 2004 Composent, Inc. and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Composent, Inc. - initial API and implementation
+*****************************************************************************/
+
+package org.eclipse.ecf.ui.views;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+
+public class MessageLoader {
+
+ private static final String RESOURCE_BUNDLE= MessageLoader.class.getName();
+ private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+ private MessageLoader() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return fgResourceBundle.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+
+ /**
+ * Gets a string from the resource bundle and formats it with the argument
+ *
+ * @param key the string used to get the bundle value, must not be null
+ */
+ public static String getFormattedString(String key, Object arg) {
+ return MessageFormat.format(getString(key), new Object[] { arg });
+ }
+
+ /**
+ * Gets a string from the resource bundle and formats it with arguments
+ */
+ public static String getFormattedString(String key, Object[] args) {
+ return MessageFormat.format(getString(key), args);
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/MessageLoader.properties b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/MessageLoader.properties
new file mode 100644
index 000000000..8f6b73c5a
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/MessageLoader.properties
@@ -0,0 +1,4 @@
+TextChatComposite.textinputinit=<input chat text here>
+ChatWindow.titleprefix=
+
+
diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterView.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterView.java
index c846bf65f..33431ad3d 100644
--- a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterView.java
+++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterView.java
@@ -1,266 +1,330 @@
package org.eclipse.ecf.ui.views;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
+import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
-
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.part.*;
-import org.eclipse.jface.viewers.*;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.jface.action.*;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.ui.*;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.SWT;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.user.IUser;
+import org.eclipse.ecf.core.user.User;
+import org.eclipse.ecf.ui.messaging.IMessageViewer;
import org.eclipse.ecf.ui.presence.IPresence;
import org.eclipse.ecf.ui.presence.IPresenceViewer;
import org.eclipse.ecf.ui.presence.IRosterEntry;
import org.eclipse.ecf.ui.presence.IRosterGroup;
import org.eclipse.ecf.ui.presence.IRosterViewer;
import org.eclipse.ecf.ui.presence.RosterEntry;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
/**
- * WARNING: IN PROGRESS
- *
+ * WARNING: IN PROGRESS
+ *
*/
-public class RosterView extends ViewPart implements IRosterViewer, IPresenceViewer {
-
+public class RosterView extends ViewPart implements ILocalUserSettable,
+ IRosterViewer, IPresenceViewer, IMessageViewer {
protected static final int TREE_EXPANSION_LEVELS = 1;
-
private TreeViewer viewer;
- private Action action1;
- private Action doubleClickAction;
-
- class TreeObject implements IAdaptable {
- private String name;
- private TreeParent parent;
-
- public TreeObject(String name) {
- this.name = name;
- }
- public String getName() {
- return name;
- }
- public void setParent(TreeParent parent) {
- this.parent = parent;
- }
- public TreeParent getParent() {
- return parent;
- }
- public String toString() {
- return getName();
- }
- public Object getAdapter(Class key) {
- return null;
- }
- }
-
- class TreeParent extends TreeObject {
- private ArrayList children;
- public TreeParent(String name) {
- super(name);
- children = new ArrayList();
- }
- public void addChild(TreeObject child) {
- children.add(child);
- child.setParent(this);
- }
- public void removeChild(TreeObject child) {
- children.remove(child);
- child.setParent(null);
- }
+ private Action chatAction;
+ private Action selectedDoubleClickAction;
+ private Action disconnectAction;
+
+ protected IUser localUser;
+ protected ITextInputHandler textInputHandler;
+ protected Hashtable chatThreads = new Hashtable();
+
+ protected IUser getLocalUser() {
+ return localUser;
+ }
+
+ class TreeObject implements IAdaptable {
+ private String name;
+ private TreeParent parent;
+ private ID userID;
+
+ public TreeObject(String name, ID userID) {
+ this.name = name;
+ this.userID = userID;
+ }
+
+ public TreeObject(String name) {
+ this(name, null);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public ID getUserID() {
+ return userID;
+ }
+
+ public void setParent(TreeParent parent) {
+ this.parent = parent;
+ }
+
+ public TreeParent getParent() {
+ return parent;
+ }
+
+ public String toString() {
+ return getName();
+ }
+
+ public Object getAdapter(Class key) {
+ return null;
+ }
+ }
+
+ class TreeParent extends TreeObject {
+ private ArrayList children;
+
+ public TreeParent(String name) {
+ super(name);
+ children = new ArrayList();
+ }
+
+ public TreeParent(String name, ID userID) {
+ super(name, userID);
+ children = new ArrayList();
+ }
+
+ public void addChild(TreeObject child) {
+ children.add(child);
+ child.setParent(this);
+ }
+
+ public void removeChild(TreeObject child) {
+ children.remove(child);
+ child.setParent(null);
+ }
+
public void removeChildren() {
- for(Iterator i=children.iterator(); i.hasNext(); ) {
+ for (Iterator i = children.iterator(); i.hasNext();) {
TreeObject obj = (TreeObject) i.next();
obj.setParent(null);
}
children.clear();
}
- public TreeObject [] getChildren() {
- return (TreeObject [])children.toArray(new TreeObject[children.size()]);
- }
- public boolean hasChildren() {
- return children.size()>0;
- }
- }
-
- class ViewContentProvider implements IStructuredContentProvider,
- ITreeContentProvider {
- private TreeParent invisibleRoot;
+
+ public TreeObject[] getChildren() {
+ return (TreeObject[]) children.toArray(new TreeObject[children
+ .size()]);
+ }
+
+ public boolean hasChildren() {
+ return children.size() > 0;
+ }
+ }
+
+ class ViewContentProvider implements IStructuredContentProvider,
+ ITreeContentProvider {
+ private TreeParent invisibleRoot;
private TreeParent root;
-
- public void inputChanged(Viewer v, Object oldInput, Object newInput) {
- }
- public void dispose() {
- }
- public Object[] getElements(Object parent) {
- if (parent.equals(getViewSite())) {
- if (root==null) initialize();
- return getChildren(root);
- }
- return getChildren(parent);
- }
- public Object getParent(Object child) {
- if (child instanceof TreeObject) {
- return ((TreeObject)child).getParent();
- }
- return null;
- }
- public Object [] getChildren(Object parent) {
- if (parent instanceof TreeParent) {
- return ((TreeParent)parent).getChildren();
- }
- return new Object[0];
- }
- public boolean hasChildren(Object parent) {
- if (parent instanceof TreeParent)
- return ((TreeParent)parent).hasChildren();
- return false;
- }
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput) {
+ }
+
+ public void dispose() {
+ }
+
+ public Object[] getElements(Object parent) {
+ if (parent.equals(getViewSite())) {
+ if (root == null)
+ initialize();
+ return getChildren(root);
+ }
+ return getChildren(parent);
+ }
+
+ public Object getParent(Object child) {
+ if (child instanceof TreeObject) {
+ return ((TreeObject) child).getParent();
+ }
+ return null;
+ }
+
+ public Object[] getChildren(Object parent) {
+ if (parent instanceof TreeParent) {
+ return ((TreeParent) parent).getChildren();
+ }
+ return new Object[0];
+ }
+
+ public boolean hasChildren(Object parent) {
+ if (parent instanceof TreeParent)
+ return ((TreeParent) parent).hasChildren();
+ return false;
+ }
+
public TreeParent hasGroup(IRosterGroup group) {
- if (group == null) return null;
- TreeObject [] children = root.getChildren();
- if (children == null) return null;
- for(int i=0; i < children.length; i++) {
+ if (group == null)
+ return null;
+ TreeObject[] children = root.getChildren();
+ if (children == null)
+ return null;
+ for (int i = 0; i < children.length; i++) {
if (group.getName().equals(children[i].getName())) {
return (TreeParent) children[i];
}
}
return null;
}
-
+
public TreeParent fillPresence(TreeParent obj, IPresence presence) {
- if (presence == null) return obj;
- TreeObject type = new TreeObject("Status: "+presence.getType().toString());
+ if (presence == null)
+ return obj;
+ TreeObject type = new TreeObject("Status: "
+ + presence.getType().toString());
obj.addChild(type);
- TreeObject mode = new TreeObject("Mode: "+presence.getMode().toString());
+ TreeObject mode = new TreeObject("Mode: "
+ + presence.getMode().toString());
obj.addChild(mode);
String status = presence.getStatus();
if (status != null && !status.equals("")) {
- TreeObject stat = new TreeObject("Status Details: "+status);
+ TreeObject stat = new TreeObject("Status Details: " + status);
obj.addChild(stat);
}
int priority = presence.getPriority();
if (priority != -1) {
- TreeObject prior = new TreeObject("Priority: "+priority);
+ TreeObject prior = new TreeObject("Priority: " + priority);
obj.addChild(prior);
}
Map props = presence.getProperties();
- for(Iterator i=props.keySet().iterator(); i.hasNext(); ) {
+ for (Iterator i = props.keySet().iterator(); i.hasNext();) {
String key = (String) i.next();
String value = (String) props.get(key);
if (key != null && value != null) {
- TreeObject prop = new TreeObject(key+": "+value);
+ TreeObject prop = new TreeObject(key + ": " + value);
obj.addChild(prop);
}
}
return obj;
}
+
public TreeParent fillWithEntry(TreeParent obj, IRosterEntry entry) {
obj.removeChildren();
String name = entry.getName();
if (name != null) {
- obj.addChild(new TreeObject("Name: "+name));
+ obj.addChild(new TreeObject("Name: " + name));
}
- return fillPresence(obj,entry.getPresenceState());
+ return fillPresence(obj, entry.getPresenceState());
}
+
public void addEntry(TreeParent parent, IRosterEntry entry) {
- TreeObject [] objs = parent.getChildren();
+ TreeObject[] objs = parent.getChildren();
TreeParent found = null;
if (objs != null) {
- for(int i=0; i < objs.length; i++) {
+ for (int i = 0; i < objs.length; i++) {
if (objs[i].getName().equals(entry.getUserID().getName())) {
- // Found it...replace values with new
- found = fillWithEntry((TreeParent) objs[i],entry);
+ // Found it...replace values with new
+ found = fillWithEntry((TreeParent) objs[i], entry);
}
}
}
if (found == null) {
- found = new TreeParent(entry.getUserID().getName());
- found = fillWithEntry(found,entry);
+ found = new TreeParent(entry.getUserID().getName(), entry
+ .getUserID());
+ found = fillWithEntry(found, entry);
parent.addChild(found);
} else {
parent.removeChild(found);
parent.addChild(found);
}
}
+
public TreeParent addEntriesToGroup(TreeParent grp, IRosterGroup group) {
Iterator i = group.getRosterEntries();
- for( ; i.hasNext(); ) {
+ for (; i.hasNext();) {
IRosterEntry entry = (IRosterEntry) i.next();
if (entry != null) {
- addEntry(grp,entry);
+ addEntry(grp, entry);
}
}
return grp;
}
-
+
public void addEntry(IRosterEntry entry) {
- addEntry(root,entry);
+ addEntry(root, entry);
}
- public void addGroup(IRosterGroup group) {
+
+ public void addGroup(IRosterGroup group) {
TreeParent grp = hasGroup(group);
if (grp == null) {
// Need to add it
grp = new TreeParent(group.getName());
}
- grp = addEntriesToGroup(grp,group);
+ grp = addEntriesToGroup(grp, group);
root.addChild(grp);
}
+
private void initialize() {
- /*
- TreeObject to1 = new TreeObject("Leaf 1");
- TreeObject to2 = new TreeObject("Leaf 2");
- TreeObject to3 = new TreeObject("Leaf 3");
- TreeParent p1 = new TreeParent("Parent 1");
- p1.addChild(to1);
- p1.addChild(to2);
- p1.addChild(to3);
-
- TreeObject to4 = new TreeObject("Leaf 4");
- TreeParent p2 = new TreeParent("Parent 2");
- p2.addChild(to4);
- */
root = new TreeParent("Buddy List");
/*
- root.addChild(p1);
- root.addChild(p2);
- */
- invisibleRoot = new TreeParent("");
- invisibleRoot.addChild(root);
- }
- }
- class ViewLabelProvider extends LabelProvider {
-
- public String getText(Object obj) {
- return obj.toString();
- }
- public Image getImage(Object obj) {
- String imageKey = null;
- if (obj instanceof TreeParent)
- imageKey = ISharedImages.IMG_OBJ_FOLDER;
- return PlatformUI.getWorkbench().getSharedImages().getImage(imageKey);
- }
- }
- class NameSorter extends ViewerSorter {
- }
-
- public RosterView() {
- }
+ * root.addChild(p1); root.addChild(p2);
+ */
+ invisibleRoot = new TreeParent("");
+ invisibleRoot.addChild(root);
+ }
+ }
+
+ class ViewLabelProvider extends LabelProvider {
+ public String getText(Object obj) {
+ return obj.toString();
+ }
+
+ public Image getImage(Object obj) {
+ String imageKey = null;
+ if (obj instanceof TreeParent)
+ imageKey = ISharedImages.IMG_OBJ_FOLDER;
+ return PlatformUI.getWorkbench().getSharedImages().getImage(
+ imageKey);
+ }
+ }
+
+ class NameSorter extends ViewerSorter {
+ }
+
+ public RosterView() {
+ }
protected void refreshView() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
- try {
- viewer.refresh();
- expandAll();
- } catch (Exception e) {
- }
+ try {
+ viewer.refresh();
+ expandAll();
+ } catch (Exception e) {
}
+ }
});
}
@@ -268,112 +332,237 @@ public class RosterView extends ViewPart implements IRosterViewer, IPresenceView
viewer.expandToLevel(TREE_EXPANSION_LEVELS);
}
- public void createPartControl(Composite parent) {
- viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
- viewer.setContentProvider(new ViewContentProvider());
- viewer.setLabelProvider(new ViewLabelProvider());
- viewer.setSorter(new NameSorter());
- viewer.setInput(getViewSite());
+ public void createPartControl(Composite parent) {
+ viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+ viewer.setContentProvider(new ViewContentProvider());
+ viewer.setLabelProvider(new ViewLabelProvider());
+ viewer.setSorter(new NameSorter());
+ viewer.setInput(getViewSite());
viewer.setAutoExpandLevel(2);
- makeActions();
- hookContextMenu();
- hookDoubleClickAction();
- contributeToActionBars();
- }
-
- private void hookContextMenu() {
- MenuManager menuMgr = new MenuManager("#PopupMenu");
- menuMgr.setRemoveAllWhenShown(true);
- menuMgr.addMenuListener(new IMenuListener() {
- public void menuAboutToShow(IMenuManager manager) {
- RosterView.this.fillContextMenu(manager);
- }
- });
- Menu menu = menuMgr.createContextMenu(viewer.getControl());
- viewer.getControl().setMenu(menu);
- getSite().registerContextMenu(menuMgr, viewer);
- }
-
- private void contributeToActionBars() {
- IActionBars bars = getViewSite().getActionBars();
- fillLocalPullDown(bars.getMenuManager());
- fillLocalToolBar(bars.getToolBarManager());
- }
-
- private void fillLocalPullDown(IMenuManager manager) {
- manager.add(action1);
- manager.add(new Separator());
- }
-
- private void fillContextMenu(IMenuManager manager) {
- manager.add(action1);
- manager.add(new Separator());
- // Other plug-ins can contribute there actions here
- manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
- }
-
- private void fillLocalToolBar(IToolBarManager manager) {
- manager.add(action1);
- manager.add(new Separator());
- }
-
- private void makeActions() {
- action1 = new Action() {
- public void run() {
- showMessage("Action 1 executed");
- }
- };
- action1.setText("Action 1");
- action1.setToolTipText("Action 1 tooltip");
- action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
- getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
-
- doubleClickAction = new Action() {
- public void run() {
- ISelection selection = viewer.getSelection();
- Object obj = ((IStructuredSelection)selection).getFirstElement();
- showMessage("Double-click detected on "+obj.toString());
- }
- };
- }
-
- private void hookDoubleClickAction() {
- viewer.addDoubleClickListener(new IDoubleClickListener() {
- public void doubleClick(DoubleClickEvent event) {
- doubleClickAction.run();
- }
- });
- }
- private void showMessage(String message) {
- MessageDialog.openInformation(
- viewer.getControl().getShell(),
- "Roster View",
- message);
- }
-
- /**
- * Passing the focus request to the viewer's control.
- */
- public void setFocus() {
- viewer.getControl().setFocus();
- }
-
- /* (non-Javadoc)
+ makeActions();
+ hookContextMenu();
+ hookDoubleClickAction();
+ contributeToActionBars();
+ }
+
+ private void hookContextMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ RosterView.this.fillContextMenu(manager);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(viewer.getControl());
+ viewer.getControl().setMenu(menu);
+ getSite().registerContextMenu(menuMgr, viewer);
+ }
+
+ private void contributeToActionBars() {
+ IActionBars bars = getViewSite().getActionBars();
+ fillLocalPullDown(bars.getMenuManager());
+ fillLocalToolBar(bars.getToolBarManager());
+ }
+
+ private void fillLocalPullDown(IMenuManager manager) {
+ manager.add(chatAction);
+ manager.add(new Separator());
+ manager.add(disconnectAction);
+ }
+
+ private void fillContextMenu(IMenuManager manager) {
+ TreeObject treeObject = getSelectedTreeObject();
+ if (treeObject != null) {
+ chatAction.setText("IM with "+treeObject.getUserID().getName());
+ manager.add(chatAction);
+ }
+ manager.add(new Separator());
+ manager.add(disconnectAction);
+ // Other plug-ins can contribute there actions here
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+
+ protected TreeObject getSelectedTreeObject() {
+ ISelection selection = viewer.getSelection();
+ Object obj = ((IStructuredSelection) selection)
+ .getFirstElement();
+ TreeObject treeObject = (TreeObject) obj;
+ return treeObject;
+ }
+ private void fillLocalToolBar(IToolBarManager manager) {
+ manager.add(chatAction);
+ manager.add(new Separator());
+ //manager.add(disconnectAction);
+ }
+
+ private void makeActions() {
+ chatAction = new Action() {
+ public void run() {
+ TreeObject treeObject = getSelectedTreeObject();
+ if (treeObject != null) openChatWindowForTarget(treeObject.getUserID());
+ }
+ };
+ chatAction.setText("IM");
+ chatAction.setToolTipText("IM with selected user");
+ chatAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
+ .getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
+ selectedDoubleClickAction = new Action() {
+ public void run() {
+ chatAction.run();
+ }
+ };
+
+ disconnectAction = new Action() {
+ public void run() {
+ // XXX disconnect from server and dispose everything here
+ showMessage("Disconnecting");
+ }
+ };
+ disconnectAction.setText("Disconnect");
+ disconnectAction.setToolTipText("Disconnect from server");
+
+ }
+
+ protected ChatWindow openChatWindowForTarget(ID targetID) {
+ if (targetID == null)
+ return null;
+ ChatWindow window = null;
+ synchronized (chatThreads) {
+ window = (ChatWindow) chatThreads.get(targetID);
+ if (window == null) {
+ window = makeChatWindowForTarget(targetID);
+ window.open();
+ } else {
+ if (!window.hasFocus()) {
+ window.openAndFlash();
+ }
+ }
+ window.setStatus("chat with "+targetID.getName());
+ }
+ return window;
+ }
+
+ protected ChatWindow makeChatWindowForTarget(ID targetID) {
+ ChatWindow window = new ChatWindow(RosterView.this, targetID.getName(),
+ getWindowInitText(targetID), getLocalUser(), new User(targetID));
+ window.create();
+ chatThreads.put(targetID, window);
+ return window;
+ }
+
+ private void hookDoubleClickAction() {
+ viewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ selectedDoubleClickAction.run();
+ }
+ });
+ }
+
+ private void showMessage(String message) {
+ MessageDialog.openInformation(viewer.getControl().getShell(),
+ "Roster View", message);
+ }
+
+ /**
+ * Passing the focus request to the viewer's control.
+ */
+ public void setFocus() {
+ viewer.getControl().setFocus();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.eclipse.ecf.ui.presence.IRosterViewer#receiveRosterEntry(org.eclipse.ecf.ui.presence.IRosterEntry)
*/
public void receiveRosterEntry(IRosterEntry entry) {
- if (entry == null) return;
- ViewContentProvider vcp = (ViewContentProvider) viewer.getContentProvider();
- vcp.addEntry(entry);
- refreshView();
+ if (entry == null)
+ return;
+ ViewContentProvider vcp = (ViewContentProvider) viewer
+ .getContentProvider();
+ if (vcp != null) {
+ vcp.addEntry(entry);
+ refreshView();
+ }
}
- /* (non-Javadoc)
- * @see org.eclipse.ecf.ui.presence.IPresenceViewer#receivePresence(org.eclipse.ecf.core.identity.ID, org.eclipse.ecf.ui.presence.IPresence)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.ui.presence.IPresenceViewer#receivePresence(org.eclipse.ecf.core.identity.ID,
+ * org.eclipse.ecf.ui.presence.IPresence)
*/
public void receivePresence(ID userID, IPresence presence) {
- IRosterEntry entry = new RosterEntry(userID,null,presence);
+ IRosterEntry entry = new RosterEntry(userID, null, presence);
receiveRosterEntry(entry);
refreshView();
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.ui.views.ILocalUserSettable#setUser(org.eclipse.ecf.core.user.IUser)
+ */
+ public void setLocalUser(IUser user, ITextInputHandler textInputHandler) {
+ this.localUser = user;
+ this.textInputHandler = textInputHandler;
+ }
+
+ public Object getAdapter(Class clazz) {
+ if (clazz != null && clazz.equals(ITextInputHandler.class)) {
+ return new ITextInputHandler() {
+ public void handleTextLine(ID userID, String text) {
+ if (textInputHandler != null) {
+ textInputHandler.handleTextLine(userID, text);
+ } else
+ System.out.println("handleTextLine(" + text + ")");
+ }
+
+ public void handleStartTyping(ID userID) {
+ if (textInputHandler != null) {
+ textInputHandler.handleStartTyping(userID);
+ } else
+ System.out.println("handleStartTyping()");
+ }
+ };
+ } else if (clazz.equals(ILocalUserSettable.class)) {
+ return this;
+ } else if (clazz.equals(IRosterViewer.class)) {
+ return this;
+ } else if (clazz.equals(IMessageViewer.class)) {
+ return this;
+ } else if (clazz.equals(IPresenceViewer.class)) {
+ return this;
+ } else
+ return null;
+ }
+
+ protected String getWindowInitText(ID targetID) {
+ String result = "chat with " + targetID.getName() + " started "
+ + getDateAndTime() + "\n";
+ return result;
+ }
+
+ protected String getDateAndTime() {
+ SimpleDateFormat sdf = new SimpleDateFormat("MM:dd hh:mm:ss");
+ return sdf.format(new Date());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.ui.messaging.IMessageViewer#showMessage(org.eclipse.ecf.core.identity.ID,
+ * org.eclipse.ecf.core.identity.ID,
+ * org.eclipse.ecf.ui.messaging.IMessageViewer.Type, java.lang.String,
+ * java.lang.String)
+ */
+ public void showMessage(ID fromID, ID toID, Type type, String subject,
+ String message) {
+ ChatWindow window = openChatWindowForTarget(fromID);
+ // finally, show message
+ if (window != null) {
+ window.showMessage(fromID, toID, type, subject, message);
+ window.setStatus("last message received at "+(new SimpleDateFormat("hh:mm:ss").format(new Date())));
+ }
+ }
} \ No newline at end of file
diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/TextChatComposite.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/TextChatComposite.java
new file mode 100644
index 000000000..699d0218a
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/TextChatComposite.java
@@ -0,0 +1,286 @@
+/*
+ * Created on Feb 19, 2005
+ *
+ */
+package org.eclipse.ecf.ui.views;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ecf.core.user.IUser;
+import org.eclipse.ecf.ui.Trace;
+import org.eclipse.ecf.ui.UiPlugin;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+public class TextChatComposite extends Composite {
+
+ public static final Trace trace = Trace.create("textchatcomposite");
+
+ protected static final int DEFAULT_INPUT_HEIGHT = 25;
+ protected static final int DEFAULT_INPUT_SEPARATOR = 5;
+
+ protected String TEXT_INPUT_INIT = MessageLoader
+ .getString("TextChatComposite.textinputinit");
+
+ protected Color meColor = null;
+ protected Color otherColor = null;
+ protected Color systemColor = null;
+
+ protected StyledText styledText;
+ protected TextViewer textoutput;
+ protected Text textinput;
+
+ protected int [] sashWeights = new int[] { 90, 10 };
+
+ protected ChatLayout cl = null;
+ protected boolean isTyping;
+ protected String initText;
+ protected ITextInputHandler inputHandler;
+ SimpleDateFormat df = new SimpleDateFormat("hh:mm a");
+ protected IUser localUser;
+ protected IUser remoteUser;
+ protected boolean showTimestamp = true;
+
+ public TextChatComposite(Composite parent, int style, String initText, ITextInputHandler handler, IUser localUser, IUser remoteUser) {
+ super(parent, style);
+
+ this.initText = initText;
+ this.inputHandler = handler;
+
+ this.localUser = localUser;
+ this.remoteUser = remoteUser;
+
+ this.meColor = new Color(getShell().getDisplay(), 23, 135, 65);
+ this.otherColor = new Color(getShell().getDisplay(), 65, 13, 165);
+ this.systemColor = new Color(getShell().getDisplay(), 123, 135, 165);
+
+ this.addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ meColor.dispose();
+ otherColor.dispose();
+ systemColor.dispose();
+ }
+
+ });
+
+ // Setup layout
+ cl = new ChatLayout(DEFAULT_INPUT_HEIGHT, DEFAULT_INPUT_SEPARATOR);
+ setLayout(cl);
+
+ // Setup text output
+ textoutput = new TextViewer(this, SWT.BORDER | SWT.V_SCROLL | SWT.WRAP);
+ styledText = textoutput.getTextWidget();
+ styledText.setEditable(false);
+ textoutput.setDocument(new Document(this.initText));
+
+ textoutput.setEditable(false);
+
+ // Setup text input
+ textinput = new Text(this, SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL);
+ cl.setInputTextHeight(textinput.getFont().getFontData()[0]
+ .getHeight() + 2);
+ textinput.setText(TEXT_INPUT_INIT);
+
+ textinput.selectAll();
+ textinput.addKeyListener(new KeyListener() {
+ public void keyPressed(KeyEvent evt) {
+ handleKeyPressed(evt);
+ }
+
+ public void keyReleased(KeyEvent evt) {
+ }
+ });
+ textinput.addFocusListener(new FocusListener() {
+ public void focusGained(FocusEvent e) {
+ String t = textinput.getText();
+ if (t.equals(TEXT_INPUT_INIT)) {
+ textinput.selectAll();
+ }
+ }
+
+ public void focusLost(FocusEvent e) {
+ }
+ });
+ textinput.addMouseListener(new MouseListener() {
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+
+ public void mouseDown(MouseEvent e) {
+ }
+
+ public void mouseUp(MouseEvent e) {
+ String t = textinput.getText();
+ if (t.equals(TEXT_INPUT_INIT)) {
+ textinput.selectAll();
+ }
+ }
+ });
+ textinput.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ if (isTyping && textinput.getText().trim().length() == 0)
+ isTyping = false;
+ else if (!isTyping) {
+ isTyping = true;
+ sendStartedTyping();
+ }
+ }
+ });
+
+ UiPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().equals(UiPlugin.PREF_DISPLAY_TIMESTAMP)) {
+ showTimestamp = ((Boolean)event.getNewValue()).booleanValue();
+ }
+ }
+
+ });
+
+ }
+
+ public void setLocalUser(IUser newUser) {
+ this.localUser = newUser;
+ }
+ public void setRemoteUser(IUser remoteUser) {
+ this.remoteUser = remoteUser;
+ }
+ public IUser getRemoteUser() {
+ return this.remoteUser;
+ }
+ protected String getCurrentDateTime() {
+ StringBuffer sb = new StringBuffer("(");
+ sb.append(df.format(new Date())).append(") ");
+ return sb.toString();
+ }
+ private String makeLineWithTimestamp(String line) {
+ if (showTimestamp) {
+ return getCurrentDateTime() + line;
+ }
+ return line;
+ }
+
+ public IUser getLocalUser() {
+ return localUser;
+ }
+ public void appendText(ChatLine text) {
+ StyledText st = textoutput.getTextWidget();
+
+ if (text == null || textoutput == null || st == null)
+ return;
+
+ int startRange = st.getText().length();
+ StringBuffer sb = new StringBuffer();
+
+ if (text.getOriginator() != null) {
+ sb.append(makeLineWithTimestamp(text.getOriginator().getName() + ": "));
+ StyleRange sr = new StyleRange();
+ sr.start = startRange;
+ sr.length = sb.length();
+ IUser localUser = getLocalUser();
+ if (localUser != null && localUser.getID().equals(text.getOriginator().getID())) {
+ sr.foreground = meColor;
+ } else {
+ sr.foreground = otherColor;
+ }
+ st.append(sb.toString());
+ st.setStyleRange(sr);
+ }
+
+ int beforeMessageIndex = st.getText().length();
+
+ st.append(text.getText());
+
+ if (text.getOriginator() == null) {
+ StyleRange sr = new StyleRange();
+ sr.start = beforeMessageIndex;
+ sr.length = text.getText().length();
+ sr.foreground = systemColor;
+ st.setStyleRange(sr);
+ }
+
+ if (!text.isNoCRLF()) {
+ st.append("\n");
+ }
+
+ String t = st.getText();
+ if (t == null)
+ return;
+ st.setSelection(t.length());
+ }
+
+ protected void handleKeyPressed(KeyEvent evt) {
+ if (evt.keyCode == SWT.CR) {
+ handleEnter();
+ }
+ }
+
+ protected void handleEnter() {
+ String text = textinput.getText().trim();
+ if(text.length() > 0) sendTextLineInput(text);
+
+ clearInput();
+ isTyping = false;
+ }
+
+ protected void clearInput() {
+ textinput.setText("");
+ }
+
+ protected void sendTextLineInput(String text) {
+ if (inputHandler != null) {
+ IUser localUser = getLocalUser();
+ IUser remoteUser = getRemoteUser();
+ if (localUser != null && remoteUser != null) {
+ inputHandler.handleTextLine(remoteUser.getID(),text);
+ appendText(new ChatLine(text,localUser));
+ } else {
+ UiPlugin.getDefault().getLog().log(new Status(Status.ERROR,UiPlugin.PLUGIN_ID,100,"Null localUser or remoteUser for textchatcomposite",new NullPointerException()));
+ }
+ } else {
+ UiPlugin.getDefault().getLog().log(new Status(Status.ERROR,UiPlugin.PLUGIN_ID,100,"No inputhandler available for textchatcomposite",new NullPointerException()));
+ }
+ }
+
+ protected void sendStartedTyping() {
+ if (inputHandler != null) {
+ IUser localUser = getLocalUser();
+ IUser remoteUser = getRemoteUser();
+ if (localUser != null && remoteUser != null) {
+ inputHandler.handleStartTyping(remoteUser.getID());
+ } else {
+ UiPlugin.getDefault().getLog().log(new Status(Status.ERROR,UiPlugin.PLUGIN_ID,100,"Null localUser or remoteUser for textchatcomposite",new NullPointerException()));
+ }
+ } else {
+ UiPlugin.getDefault().getLog().log(new Status(Status.ERROR,UiPlugin.PLUGIN_ID,100,"No inputhandler available for textchatcomposite",new NullPointerException()));
+ }
+ }
+
+ protected String getShellName() {
+ return "org.eclipse.ecf.ui.views.TextChatComposite";
+ }
+ public void dispose() {
+ super.dispose();
+ }
+
+ protected void checkSubclass() {
+ }
+}

Back to the top