diff options
| author | slewis | 2005-02-21 01:43:04 +0000 |
|---|---|---|
| committer | slewis | 2005-02-21 01:43:04 +0000 |
| commit | 9ffc6c9c92d294ca16bc4578101579a6b957748e (patch) | |
| tree | 99c5cd7ca80be99209daa38e4faf0cab6aaff98f | |
| parent | 10f9b763a07a4d43030b5f663f4505e7183d8a99 (diff) | |
| download | org.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.
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 Binary files differnew file mode 100644 index 000000000..608d2d165 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf.ui/icons/person.gif 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() { + } +} |
