blob: 9c1204304a7a49a950a7b4f68065763337b41844 [file] [log] [blame]
/****************************************************************************
* 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.internal.ui.deprecated.views;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ecf.core.user.IUser;
import org.eclipse.ecf.internal.ui.Activator;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
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.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
import org.eclipse.ui.part.ViewPart;
public class TextChatComposite extends Composite {
protected static final int DEFAULT_INPUT_HEIGHT = 25;
protected static final int DEFAULT_INPUT_SEPARATOR = 5;
protected String TEXT_INPUT_INIT = "<input chat text here>";
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[] { 7, 2 };
protected boolean isTyping;
protected String initText;
protected ILocalInputHandler inputHandler;
SimpleDateFormat df = new SimpleDateFormat("hh:mm a");
protected IUser localUser;
protected IUser remoteUser;
protected boolean showTimestamp = true;
private Action outputClear = null;
private Action outputCopy = null;
private Action outputPaste = null;
private Action outputSelectAll = null;
private ViewPart view = null;
public TextChatComposite(ViewPart view, Composite parent, int style,
String initText, ILocalInputHandler handler, IUser localUser,
IUser remoteUser) {
super(parent, style);
this.view = view;
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();
}
});
setLayout(new GridLayout());
SashForm sash = new SashForm(this, SWT.VERTICAL | SWT.SMOOTH);
sash.setLayoutData(new GridData(GridData.FILL_BOTH));
styledText = createStyledTextWidget(sash);
styledText.setEditable(false);
// Setup text input
textinput = new Text(sash, SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
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();
}
}
});
sash.setWeights(sashWeights);
makeActions();
hookContextMenu();
Activator.getDefault().getPreferenceStore().addPropertyChangeListener(
new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(
Activator.PREF_DISPLAY_TIMESTAMP)) {
showTimestamp = ((Boolean) event.getNewValue())
.booleanValue();
}
}
});
}
private StyledText createStyledTextWidget(Composite parent) {
try {
SourceViewer result = new SourceViewer(parent, null, null,
true, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL | SWT.MULTI
| SWT.READ_ONLY);
result.configure(new TextSourceViewerConfiguration(EditorsUI
.getPreferenceStore()));
result.setDocument(new Document());
return result.getTextWidget();
} catch (Exception e) {
Activator
.getDefault()
.getLog()
.log(
new Status(
IStatus.WARNING,
Activator.PLUGIN_ID,
IStatus.WARNING,
"Source viewer not available. Hyperlinking will be disabled.",
e));
return new StyledText(parent, SWT.BORDER | SWT.WRAP
| SWT.V_SCROLL | SWT.MULTI | SWT.READ_ONLY);
}
}
private void makeActions() {
outputSelectAll = new Action() {
public void run() {
outputSelectAll();
}
};
outputSelectAll.setText("Select All");
outputSelectAll.setAccelerator(SWT.CTRL | 'A');
outputCopy = new Action() {
public void run() {
outputCopy();
}
};
outputCopy.setText("Copy");
outputCopy.setAccelerator(SWT.CTRL | 'C');
outputCopy.setImageDescriptor(PlatformUI.getWorkbench()
.getSharedImages().getImageDescriptor(
ISharedImages.IMG_TOOL_COPY));
outputClear = new Action() {
public void run() {
outputClear();
}
};
outputClear.setText("Clear");
outputPaste = new Action() {
public void run() {
outputPaste();
}
};
outputPaste.setText("Paste");
outputCopy.setAccelerator(SWT.CTRL | 'V');
outputPaste.setImageDescriptor(PlatformUI.getWorkbench()
.getSharedImages().getImageDescriptor(
ISharedImages.IMG_TOOL_PASTE));
}
protected void outputClear() {
if (MessageDialog.openConfirm(null, "Confirm Clear Text Output",
"Are you sure you want to clear output?"))
styledText.setText("");
}
protected void outputCopy() {
String t = styledText.getSelectionText();
if (t == null || t.length() == 0) {
styledText.selectAll();
}
styledText.copy();
styledText.setSelection(styledText.getText().length());
}
protected void outputPaste() {
textinput.paste();
}
protected void outputSelectAll() {
styledText.selectAll();
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
fillContextMenu(manager);
}
});
Menu menu = menuMgr.createContextMenu(styledText);
styledText.setMenu(menu);
ISelectionProvider selectionProvider = new ISelectionProvider() {
public void addSelectionChangedListener(
ISelectionChangedListener listener) {
}
public ISelection getSelection() {
ISelection selection = new TextSelection(styledText
.getSelectionRange().x,
styledText.getSelectionRange().y);
return selection;
}
public void removeSelectionChangedListener(
ISelectionChangedListener listener) {
}
public void setSelection(ISelection selection) {
if (selection instanceof ITextSelection) {
ITextSelection textSelection = (ITextSelection) selection;
styledText.setSelection(textSelection.getOffset(),
textSelection.getOffset()
+ textSelection.getLength());
}
}
};
view.getSite().registerContextMenu(menuMgr, selectionProvider);
}
private void fillContextMenu(IMenuManager manager) {
manager.add(outputCopy);
manager.add(outputPaste);
manager.add(outputClear);
manager.add(new Separator());
manager.add(outputSelectAll);
manager.add(new Separator());
manager.add(new Separator());
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
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 createLineWithTimestamp(String line) {
if (showTimestamp)
return getCurrentDateTime() + line;
return line;
}
public IUser getLocalUser() {
return localUser;
}
public void appendText(ChatLine text) {
StyledText st = styledText;
if (text == null || st == null)
return;
int startRange = st.getText().length();
StringBuffer sb = new StringBuffer();
if (text.getOriginator() != null) {
sb.append(createLineWithTimestamp(text.getOriginator().getName()
+ ": "));
StyleRange sr = new StyleRange();
sr.start = startRange;
sr.length = sb.length();
IUser lu = getLocalUser();
if (lu != null && lu.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().trim());
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.character == SWT.CR) {
handleEnter();
evt.doit = false;
}
}
protected void handleEnter() {
String text = textinput.getText().trim();
if (text != null)
sendTextLineInput(text);
clearInput();
isTyping = false;
}
protected void clearInput() {
textinput.setText("");
}
protected void sendTextLineInput(String text) {
if (inputHandler != null) {
IUser lu = getLocalUser();
IUser ru = getRemoteUser();
if (lu != null && ru != null) {
inputHandler.inputText(ru.getID(), text);
appendText(new ChatLine(text, lu));
} else {
Activator
.getDefault()
.getLog()
.log(
new Status(
IStatus.ERROR,
Activator.PLUGIN_ID,
100,
"Null localUser or remoteUser for textchatcomposite",
new NullPointerException()));
}
} else {
Activator.getDefault().getLog().log(
new Status(IStatus.ERROR, Activator.PLUGIN_ID, 100,
"No inputhandler available for textchatcomposite",
new NullPointerException()));
}
}
protected void sendStartedTyping() {
if (inputHandler != null) {
IUser lu = getLocalUser();
IUser ru = getRemoteUser();
if (lu != null && ru != null) {
inputHandler.startTyping(ru.getID());
} else {
Activator
.getDefault()
.getLog()
.log(
new Status(
IStatus.ERROR,
Activator.PLUGIN_ID,
100,
"Null localUser or remoteUser for textchatcomposite",
new NullPointerException()));
}
} else {
Activator.getDefault().getLog().log(
new Status(IStatus.ERROR, Activator.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 setDisposed() {
textinput.setEnabled(false);
}
protected void checkSubclass() {
}
}