| /**************************************************************************** |
| * 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() { |
| } |
| } |