| /******************************************************************************* |
| * Copyright (c) 2004, 2008 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 |
| * Jacek Pospychala <jacek.pospychala@pl.ibm.com> - bug 192762, 197329, 190851 |
| * Abner Ballardo <modlost@modlost.net> - bug 192756, 199336, 200630 |
| * Jakub Jurkiewicz <jakub.jurkiewicz@pl.ibm.com> - bug 197332 |
| * Hiroyuki Inaba <Hiroyuki <hiroyuki.inaba@gmail.com> - bug 222253 |
| ******************************************************************************/ |
| package org.eclipse.ecf.presence.ui.chatroom; |
| |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.text.SimpleDateFormat; |
| import java.util.*; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.ecf.core.IContainerListener; |
| import org.eclipse.ecf.core.events.*; |
| import org.eclipse.ecf.core.identity.*; |
| import org.eclipse.ecf.core.security.ConnectContextFactory; |
| import org.eclipse.ecf.core.user.IUser; |
| import org.eclipse.ecf.core.util.ECFException; |
| import org.eclipse.ecf.internal.presence.ui.*; |
| import org.eclipse.ecf.internal.presence.ui.preferences.PreferenceConstants; |
| import org.eclipse.ecf.presence.*; |
| import org.eclipse.ecf.presence.chatroom.*; |
| import org.eclipse.ecf.presence.im.IChatID; |
| import org.eclipse.ecf.presence.im.IChatMessage; |
| import org.eclipse.ecf.presence.ui.MessagesView; |
| import org.eclipse.jface.action.*; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.text.*; |
| import org.eclipse.jface.text.source.SourceViewer; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.viewers.*; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.*; |
| import org.eclipse.swt.events.*; |
| import org.eclipse.swt.graphics.*; |
| import org.eclipse.swt.layout.*; |
| import org.eclipse.swt.widgets.*; |
| import org.eclipse.ui.*; |
| import org.eclipse.ui.editors.text.EditorsUI; |
| import org.eclipse.ui.part.ViewPart; |
| import org.eclipse.ui.progress.IWorkbenchSiteProgressService; |
| |
| public class ChatRoomManagerView extends ViewPart implements IChatRoomInvitationListener { |
| |
| private static final String ATSIGN = "@"; //$NON-NLS-1$ |
| |
| public static final String VIEW_ID = "org.eclipse.ecf.presence.ui.chatroom.ChatRoomManagerView"; //$NON-NLS-1$ |
| |
| public static final String PARTICIPANTS_MENU_ID = "org.eclipse.ecf.presence.ui.chatroom.participantsView"; //$NON-NLS-1$ |
| |
| private static final int RATIO_READ_WRITE_PANE = 85; |
| |
| private static final int RATIO_PRESENCE_PANE = 15; |
| |
| protected static final int DEFAULT_INPUT_HEIGHT = 25; |
| |
| protected static final int DEFAULT_INPUT_SEPARATOR = 5; |
| |
| private CTabFolder rootTabFolder = null; |
| |
| private ChatRoomTab rootChannelTab = null; |
| |
| private IChatRoomViewCloseListener rootCloseListener = null; |
| |
| private IChatRoomMessageSender rootMessageSender = null; |
| |
| /** |
| * UI independent renderer, that is aware of displaying any special fragments |
| * of message, like formatting, graphical attachments, emotional content, etc. |
| */ |
| private IMessageRenderer messageRenderer = null; |
| |
| Action outputClear = null; |
| |
| Action outputCopy = null; |
| |
| Action outputPaste = null; |
| |
| Action outputSelectAll = null; |
| |
| boolean rootDisposed = false; |
| |
| private boolean rootEnabled = false; |
| |
| private Hashtable chatRooms = new Hashtable(); |
| |
| private IChatRoomCommandListener commandListener = null; |
| |
| private IChatRoomContainer container = null; |
| |
| private String localUserName = Messages.ChatRoomManagerView_DEFAULT_USER; |
| |
| private String hostName = Messages.ChatRoomManagerView_DEFAULT_HOST; |
| |
| class ChatRoomTab { |
| private SashForm fullChat; |
| |
| private CTabItem tabItem; |
| |
| private Composite rightComposite; |
| |
| private StyledText subjectText; |
| |
| private StyledText outputText; |
| |
| private Text inputText; |
| |
| private Label participantsNumberLabel; |
| |
| private TableViewer participantsTable; |
| |
| private Action tabSelectAll; |
| private Action tabCopy; |
| private Action tabClear; |
| private Action tabPaste; |
| |
| private boolean withParticipants; |
| |
| ChatRoomTab(CTabFolder parent, String name) { |
| this(true, parent, name, null); |
| } |
| |
| ChatRoomTab(boolean withParticipantsList, CTabFolder parent, String name, KeyListener keyListener) { |
| withParticipants = withParticipantsList; |
| tabItem = new CTabItem(parent, SWT.NULL); |
| tabItem.setText(name); |
| if (withParticipants) { |
| fullChat = new SashForm(parent, SWT.HORIZONTAL); |
| fullChat.setLayout(new FillLayout()); |
| |
| Composite memberComp = new Composite(fullChat, SWT.NONE); |
| GridLayout layout = new GridLayout(1, true); |
| layout.marginWidth = 0; |
| layout.marginHeight = 0; |
| memberComp.setLayout(layout); |
| |
| participantsNumberLabel = new Label(memberComp, SWT.BORDER | SWT.READ_ONLY); |
| participantsNumberLabel.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); |
| participantsNumberLabel.setAlignment(SWT.CENTER); |
| participantsTable = new TableViewer(memberComp, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI); |
| participantsTable.setSorter(new ViewerSorter()); |
| participantsTable.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| participantsTable.addOpenListener(new IOpenListener() { |
| public void open(OpenEvent event) { |
| IStructuredSelection selection = (IStructuredSelection) event.getSelection(); |
| String user = ((ChatRoomParticipant) selection.getFirstElement()).getName(); |
| if (!ChatRoomManagerView.this.localUserName.equals(user)) { |
| try { |
| MessagesView messagesView = getMessagesView(); |
| messagesView.selectTab(container.getPrivateMessageSender(), null, createStringID(localUserName), createStringID(user)); |
| getSite().getPage().activate(messagesView); |
| } catch (PartInitException e) { |
| Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, NLS.bind(Messages.ChatRoomManagerView_EXCEPTION_MESSAGE_VIEW_INITIALIZATION, user), e)); |
| } |
| } |
| } |
| }); |
| |
| rightComposite = new Composite(fullChat, SWT.NONE); |
| layout = new GridLayout(1, true); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| rightComposite.setLayout(layout); |
| |
| subjectText = createStyledTextWidget(rightComposite, SWT.SINGLE | SWT.BORDER); |
| subjectText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
| /* |
| * The sendSubjectChange method in Smack 2.2.1 does not seem to be working correctly, so this whole block |
| * can be temporily removed. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=223560 |
| subjectText.addKeyListener(new KeyAdapter() { |
| public void keyPressed(KeyEvent evt) { |
| if (evt.character == SWT.CR || evt.character == SWT.KEYPAD_CR) { |
| ChatRoom chatroom = (ChatRoom) chatRooms.get(tabItem.getText()); |
| if (chatroom != null) { |
| IChatRoomAdminSender chatRoomAdminSender = chatroom.chatRoomContainer.getChatRoomAdminSender(); |
| try { |
| if (chatRoomAdminSender != null) { |
| chatRoomAdminSender.sendSubjectChange(subjectText.getText()); |
| } |
| } catch (ECFException e) { |
| Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, "sendSubjectChange", e));disconnected(); //$NON-NLS-1$ |
| } |
| } |
| } |
| } |
| }); |
| */ |
| subjectText.setEditable(false); |
| subjectText.setEnabled(false); |
| } else { |
| rightComposite = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(1, true); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| rightComposite.setLayout(layout); |
| } |
| |
| outputText = createStyledTextWidget(rightComposite, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL | SWT.MULTI | SWT.READ_ONLY); |
| outputText.setEditable(false); |
| outputText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| |
| inputText = new Text(rightComposite, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); |
| GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); |
| GC gc = new GC(inputText); |
| gc.setFont(inputText.getFont()); |
| FontMetrics fontMetrics = gc.getFontMetrics(); |
| gc.dispose(); |
| gd.heightHint = fontMetrics.getHeight() * 2; |
| inputText.setLayoutData(gd); |
| |
| if (keyListener != null) |
| inputText.addKeyListener(keyListener); |
| if (withParticipants) { |
| fullChat.setWeights(new int[] {RATIO_PRESENCE_PANE, RATIO_READ_WRITE_PANE}); |
| tabItem.setControl(fullChat); |
| } else |
| tabItem.setControl(rightComposite); |
| |
| parent.setSelection(tabItem); |
| |
| makeActions(); |
| hookContextMenu(); |
| if (withParticipants) { |
| hookParticipantsContextMenu(); |
| } |
| |
| StyledText st = getOutputText(); |
| if (st != null) { |
| ScrollBar vsb = st.getVerticalBar(); |
| if (vsb != null) { |
| vsb.addSelectionListener(scrollSelectionListener); |
| vsb.addDisposeListener(new DisposeListener() { |
| public void widgetDisposed(DisposeEvent e) { |
| StyledText ot = getOutputText(); |
| if (ot != null) { |
| ScrollBar sb = ot.getVerticalBar(); |
| if (sb != null) |
| sb.removeSelectionListener(scrollSelectionListener); |
| } |
| } |
| }); |
| } |
| } |
| |
| } |
| |
| private SelectionListener scrollSelectionListener = new SelectionListener() { |
| |
| public void widgetDefaultSelected(SelectionEvent e) { |
| // do nothing |
| } |
| |
| public void widgetSelected(SelectionEvent e) { |
| if (!isLastOutputInvisible(getOutputText())) { |
| makeTabItemNormal(); |
| } |
| } |
| |
| }; |
| |
| protected void makeTabItemBold() { |
| changeTabItem(true); |
| } |
| |
| protected void makeTabItemNormal() { |
| changeTabItem(false); |
| } |
| |
| protected void changeTabItem(boolean bold) { |
| CTabItem item = tabItem; |
| Font oldFont = item.getFont(); |
| FontData[] fd = oldFont.getFontData(); |
| item.setFont(new Font(oldFont.getDevice(), fd[0].getName(), fd[0].getHeight(), (bold) ? SWT.BOLD : SWT.NORMAL)); |
| } |
| |
| private StyledText createStyledTextWidget(Composite parent, int styles) { |
| SourceViewer result = null; |
| try { |
| result = new SourceViewer(parent, null, null, true, styles); |
| } catch (NoClassDefFoundError e) { |
| Activator.getDefault().getLog().log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, IStatus.WARNING, Messages.ChatRoomManagerView_WARNING_HYPERLINKING_NOT_AVAILABLE, e)); |
| return new StyledText(parent, styles); |
| } |
| result.configure(new ChatRoomViewerConfiguration(EditorsUI.getPreferenceStore(), container, ChatRoomManagerView.this)); |
| result.setDocument(new Document()); |
| return result.getTextWidget(); |
| } |
| |
| protected void outputClear() { |
| if (MessageDialog.openConfirm(null, Messages.ChatRoomManagerView_CONFIRM_CLEAR_TEXT_OUTPUT_TITLE, Messages.ChatRoomManagerView_CONFIRM_CLEAR_TEXT_OUTPUT_MESSAGE)) { |
| outputText.setText(""); //$NON-NLS-1$ |
| } |
| } |
| |
| protected void outputCopy() { |
| String t = outputText.getSelectionText(); |
| if (t == null || t.length() == 0) { |
| outputText.selectAll(); |
| } |
| outputText.copy(); |
| outputText.setSelection(outputText.getText().length()); |
| } |
| |
| private void fillContextMenu(IMenuManager manager) { |
| manager.add(tabCopy); |
| manager.add(tabPaste); |
| manager.add(tabClear); |
| manager.add(new Separator()); |
| manager.add(tabSelectAll); |
| manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
| } |
| |
| private void hookContextMenu() { |
| MenuManager menuMgr = new MenuManager(); |
| menuMgr.setRemoveAllWhenShown(true); |
| menuMgr.addMenuListener(new IMenuListener() { |
| public void menuAboutToShow(IMenuManager manager) { |
| fillContextMenu(manager); |
| } |
| }); |
| Menu menu = menuMgr.createContextMenu(outputText); |
| outputText.setMenu(menu); |
| ISelectionProvider selectionProvider = new ISelectionProvider() { |
| |
| public void addSelectionChangedListener(ISelectionChangedListener listener) { |
| // do nothing |
| } |
| |
| public ISelection getSelection() { |
| ISelection selection = new TextSelection(outputText.getSelectionRange().x, outputText.getSelectionRange().y); |
| |
| return selection; |
| } |
| |
| public void removeSelectionChangedListener(ISelectionChangedListener listener) { |
| // do nothing |
| } |
| |
| public void setSelection(ISelection selection) { |
| if (selection instanceof ITextSelection) { |
| ITextSelection textSelection = (ITextSelection) selection; |
| outputText.setSelection(textSelection.getOffset(), textSelection.getOffset() + textSelection.getLength()); |
| } |
| } |
| |
| }; |
| getSite().registerContextMenu(menuMgr, selectionProvider); |
| } |
| |
| private void hookParticipantsContextMenu() { |
| MenuManager menuMgr = new MenuManager(); |
| menuMgr.addMenuListener(new IMenuListener() { |
| public void menuAboutToShow(IMenuManager manager) { |
| manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
| } |
| }); |
| menuMgr.setRemoveAllWhenShown(true); |
| Control control = participantsTable.getControl(); |
| Menu menu = menuMgr.createContextMenu(control); |
| control.setMenu(menu); |
| getSite().registerContextMenu(PARTICIPANTS_MENU_ID, menuMgr, participantsTable); |
| } |
| |
| private void makeActions() { |
| tabSelectAll = new Action() { |
| public void run() { |
| outputText.selectAll(); |
| } |
| }; |
| tabSelectAll.setText(Messages.ChatRoomManagerView_SELECT_ALL_TEXT); |
| tabSelectAll.setToolTipText(Messages.ChatRoomManagerView_SELECT_ALL_TOOLTIP); |
| tabSelectAll.setAccelerator(SWT.CTRL | 'A'); |
| tabCopy = new Action() { |
| public void run() { |
| outputCopy(); |
| } |
| }; |
| tabCopy.setText(Messages.ChatRoomManagerView_COPY_TEXT); |
| tabCopy.setToolTipText(Messages.ChatRoomManagerView_COPY_TOOLTIP); |
| tabCopy.setAccelerator(SWT.CTRL | 'C'); |
| tabCopy.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); |
| tabClear = new Action() { |
| public void run() { |
| outputClear(); |
| } |
| }; |
| tabClear.setText(Messages.ChatRoomManagerView_CLEAR_TEXT); |
| tabClear.setToolTipText(Messages.ChatRoomManagerView_CLEAR_TOOLTIP); |
| tabPaste = new Action() { |
| public void run() { |
| getInputText().paste(); |
| } |
| }; |
| tabPaste.setText(Messages.ChatRoomManagerView_PASTE_TEXT); |
| tabPaste.setToolTipText(Messages.ChatRoomManagerView_PASTE_TOOLTIP); |
| tabPaste.setAccelerator(SWT.CTRL | 'V'); |
| tabPaste.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_PASTE)); |
| |
| } |
| |
| protected Text getInputText() { |
| return inputText; |
| } |
| |
| protected void setKeyListener(KeyListener listener) { |
| if (listener != null) |
| inputText.addKeyListener(listener); |
| } |
| |
| protected Label getParticipantsLabel() { |
| return participantsNumberLabel; |
| } |
| |
| protected TableViewer getParticipantsViewer() { |
| return participantsTable; |
| } |
| |
| /** |
| * @return the <tt>StyledText</tt> widget that is displaying the output of the chatroom |
| */ |
| public StyledText getOutputText() { |
| return outputText; |
| } |
| |
| public void setSubject(String subject) { |
| subjectText.setText(subject); |
| } |
| } |
| |
| public void createPartControl(Composite parent) { |
| Composite rootComposite = new Composite(parent, SWT.NONE); |
| rootComposite.setLayout(new FillLayout()); |
| boolean useTraditionalTabFolder = PlatformUI.getPreferenceStore().getBoolean(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS); |
| rootTabFolder = new CTabFolder(rootComposite, SWT.NORMAL | SWT.CLOSE); |
| rootTabFolder.setUnselectedCloseVisible(false); |
| rootTabFolder.setSimple(useTraditionalTabFolder); |
| PlatformUI.getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() { |
| public void propertyChange(PropertyChangeEvent event) { |
| if (event.getProperty().equals(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS) && !rootTabFolder.isDisposed()) { |
| rootTabFolder.setSimple(((Boolean) event.getNewValue()).booleanValue()); |
| rootTabFolder.redraw(); |
| } |
| } |
| }); |
| |
| rootTabFolder.addCTabFolder2Listener(new CTabFolder2Adapter() { |
| public void close(CTabFolderEvent event) { |
| event.doit = closeTabItem((CTabItem) event.item); |
| } |
| }); |
| } |
| |
| private boolean closeTabItem(CTabItem tabItem) { |
| ChatRoom chatRoom = findChatRoomForTabItem(tabItem); |
| if (chatRoom == null) { |
| return true; |
| } |
| if (MessageDialog.openQuestion(getSite().getShell(), Messages.ChatRoomManagerView_CLOSE_CHAT_ROOM_TITLE, NLS.bind(Messages.ChatRoomManagerView_CLOSE_CHAT_ROOM_MESSAGE, tabItem.getText()))) { |
| chatRoom.chatRoomDisconnect(); |
| return true; |
| } |
| return false; |
| } |
| |
| public IChatRoomContainer getRootChatRoomContainer() { |
| return container; |
| } |
| |
| /** |
| * @return chat room container of currently selected tab or null if none found. |
| */ |
| public IChatRoomContainer getActiveChatRoomContainer() { |
| CTabItem selection = rootTabFolder.getSelection(); |
| if (selection != null) { |
| ChatRoom chatRoom = findChatRoomForTabItem(selection); |
| if (chatRoom != null) { |
| return chatRoom.chatRoomContainer; |
| } |
| } |
| |
| return null; |
| } |
| |
| private ChatRoom findChatRoomForTabItem(CTabItem tabItem) { |
| for (Iterator i = chatRooms.values().iterator(); i.hasNext();) { |
| ChatRoom cr = (ChatRoom) i.next(); |
| if (tabItem == cr.chatRoomTab.tabItem) |
| return cr; |
| } |
| return null; |
| } |
| |
| private Text getRootTextInput() { |
| if (rootChannelTab == null) |
| return null; |
| return rootChannelTab.getInputText(); |
| } |
| |
| private StyledText getRootTextOutput() { |
| if (rootChannelTab == null) |
| return null; |
| return rootChannelTab.getOutputText(); |
| } |
| |
| public void initializeWithoutManager(String username, String hostname, final IChatRoomCommandListener commandListener1, final IChatRoomViewCloseListener closeListener) { |
| initializeWithManager(username, hostname, null, commandListener1, closeListener); |
| } |
| |
| public void initializeWithManager(String localUserName1, String hostName1, final IChatRoomContainer rootChatRoomContainer, final IChatRoomCommandListener commandListener1, final IChatRoomViewCloseListener closeListener) { |
| ChatRoomManagerView.this.localUserName = (localUserName1 == null) ? Messages.ChatRoomManagerView_DEFAULT_USER : localUserName1; |
| ChatRoomManagerView.this.hostName = (hostName1 == null) ? Messages.ChatRoomManagerView_DEFAULT_HOST : hostName1; |
| ChatRoomManagerView.this.rootCloseListener = closeListener; |
| ChatRoomManagerView.this.commandListener = commandListener1; |
| String viewTitle = localUserName1 + ATSIGN + hostName1; |
| ChatRoomManagerView.this.setPartName(NLS.bind(Messages.ChatRoomManagerView_VIEW_TITLE, viewTitle)); |
| ChatRoomManagerView.this.setTitleToolTip(Messages.ChatRoomManagerView_VIEW_TITLE_HOST_PREFIX + ChatRoomManagerView.this.hostName); |
| if (rootChatRoomContainer != null) { |
| ChatRoomManagerView.this.container = rootChatRoomContainer; |
| ChatRoomManagerView.this.rootMessageSender = rootChatRoomContainer.getChatRoomMessageSender(); |
| rootChannelTab = new ChatRoomTab(false, rootTabFolder, ChatRoomManagerView.this.hostName, new KeyListener() { |
| public void keyPressed(KeyEvent evt) { |
| handleKeyPressed(evt); |
| } |
| |
| public void keyReleased(KeyEvent evt) { |
| // do nothing |
| } |
| }); |
| makeActions(); |
| hookContextMenu(); |
| if (rootChatRoomContainer.getConnectedID() == null) { |
| StyledText outputText = getRootTextOutput(); |
| if (!outputText.isDisposed()) |
| outputText.setText(new SimpleDateFormat(Messages.ChatRoomManagerView_CONNECT_DATE_TIME_FORMAT).format(new Date()) + NLS.bind(Messages.ChatRoomManagerView_CONNECT_MESSAGE, viewTitle)); |
| } |
| } |
| setEnabled(false); |
| } |
| |
| public void setEnabled(boolean enabled) { |
| this.rootEnabled = enabled; |
| Text inputText = getRootTextInput(); |
| if (inputText != null && !inputText.isDisposed()) |
| inputText.setEnabled(enabled); |
| } |
| |
| public boolean isEnabled() { |
| return rootEnabled; |
| } |
| |
| protected void clearInput() { |
| Text textInput = getRootTextInput(); |
| if (textInput != null) |
| textInput.setText(""); //$NON-NLS-1$ |
| } |
| |
| public void sendMessageLine(String line) { |
| try { |
| if (rootMessageSender != null) |
| rootMessageSender.sendMessage(line); |
| } catch (ECFException e) { |
| // And cut ourselves off |
| removeLocalUser(); |
| } |
| } |
| |
| public void disconnected() { |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| if (rootDisposed) |
| return; |
| setEnabled(false); |
| setPartName(NLS.bind(Messages.ChatRoomManagerView_VIEW_DISABLED_NAME, getPartName())); |
| } |
| }); |
| } |
| |
| protected CTabItem getTabItem(String targetName) { |
| CTabItem[] items = rootTabFolder.getItems(); |
| for (int i = 0; i < items.length; i++) { |
| if (items[i].getText().equals(targetName)) { |
| return items[i]; |
| } |
| } |
| return null; |
| } |
| |
| protected void doJoinRoom(final IChatRoomInfo roomInfo, final String password) { |
| final ID targetRoomID = roomInfo.getRoomID(); |
| final String targetRoomName = targetRoomID.getName(); |
| // first, check to see if we already have it open. If so just activate |
| ChatRoom room = (ChatRoom) chatRooms.get(targetRoomName); |
| |
| if (room != null && room.isConnected()) { |
| room.setSelected(); |
| return; |
| } |
| |
| // Then we create a new chatRoomContainer from the roomInfo |
| try { |
| final IChatRoomContainer chatRoomContainer = roomInfo.createChatRoomContainer(); |
| |
| // Setup new user interface (new tab) |
| final ChatRoom chatroom = new ChatRoom(chatRoomContainer, new ChatRoomTab(rootTabFolder, targetRoomName)); |
| // setup message listener |
| chatRoomContainer.addMessageListener(new IIMMessageListener() { |
| public void handleMessageEvent(IIMMessageEvent messageEvent) { |
| if (messageEvent instanceof IChatRoomMessageEvent) { |
| IChatRoomMessage m = ((IChatRoomMessageEvent) messageEvent).getChatRoomMessage(); |
| chatroom.handleMessage(m.getFromID(), m.getMessage()); |
| } |
| } |
| }); |
| // setup participant listener |
| chatRoomContainer.addChatRoomParticipantListener(new IChatRoomParticipantListener() { |
| public void handlePresenceUpdated(ID fromID, IPresence presence) { |
| chatroom.handlePresence(fromID, presence); |
| } |
| |
| public void handleArrived(IUser participant) { |
| // do nothing |
| } |
| |
| public void handleUpdated(IUser updatedParticipant) { |
| // do nothing |
| } |
| |
| public void handleDeparted(IUser participant) { |
| // do nothing |
| } |
| }); |
| chatRoomContainer.addListener(new IContainerListener() { |
| public void handleEvent(IContainerEvent evt) { |
| if (evt instanceof IContainerDisconnectedEvent || evt instanceof IContainerEjectedEvent) { |
| chatroom.disconnected(); |
| } |
| } |
| }); |
| // Now connect/join |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| try { |
| chatRoomContainer.connect(targetRoomID, ConnectContextFactory.createPasswordConnectContext(password)); |
| chatRooms.put(targetRoomName, chatroom); |
| } catch (Exception e) { |
| MessageDialog.openError(getSite().getShell(), "Connect Error", //$NON-NLS-1$ |
| NLS.bind("Could not connect to {0}.\n\nError is {1}.", //$NON-NLS-1$ |
| targetRoomName, e.getLocalizedMessage())); |
| } |
| } |
| }); |
| } catch (Exception e) { |
| MessageDialog.openError(getSite().getShell(), "Container Create Error", //$NON-NLS-1$ |
| NLS.bind("Could not create chatRoomContainer for {0}.\n\nError is {1}.", //$NON-NLS-1$ |
| targetRoomName, e.getLocalizedMessage())); |
| } |
| } |
| |
| class ChatRoom implements IChatRoomInvitationListener, KeyListener { |
| |
| private IChatRoomContainer chatRoomContainer; |
| |
| private ChatRoomTab chatRoomTab; |
| |
| private IChatRoomMessageSender chatRoomMessageSender; |
| |
| private IUser localUser; |
| |
| private Label chatRoomParticipantsLabel; |
| |
| private TableViewer chatRoomParticipantViewer = null; |
| |
| /** |
| * A list of available nicknames for nickname completion via the 'tab' |
| * key. |
| */ |
| private ArrayList options; |
| |
| /** |
| * Denotes the number of options that should be available for the user |
| * to cycle through when pressing the 'tab' key to perform nickname |
| * completion. The default value is set to 5. |
| */ |
| private int maximumCyclingOptions = 5; |
| |
| /** |
| * The length of a nickname's prefix that has already been typed in by |
| * the user. This is used to remove the beginning part of the available |
| * nickname choices. |
| */ |
| private int prefixLength; |
| |
| /** |
| * The index of the next nickname to select from {@link #options}. |
| */ |
| private int choice = 0; |
| |
| /** |
| * The length of the user's nickname that remains resulting from |
| * subtracting the nickname's length from the prefix that the user has |
| * keyed in already. |
| */ |
| private int nickRemainder; |
| |
| /** |
| * The caret position when the user first started |
| * cycling through nickname completion options. |
| */ |
| private int caret; |
| |
| /** |
| * The character to enter after the user's nickname has been |
| * autocompleted. The default value is a colon (':'). |
| */ |
| private char nickCompletionSuffix = ':'; |
| |
| /** |
| * Indicates whether the user is currently cycling over the list of |
| * nicknames for nickname completion. |
| */ |
| private boolean isCycling = false; |
| |
| /** |
| * Check to see whether the user is currently starting the line of text |
| * with a nickname at the beginning of the message. This determines |
| * whether {@link #nickCompletionSuffix} should be inserted when |
| * performing autocompletion. If the user is not at the beginning of the |
| * message, it is likely that the user is typing another user's name to |
| * reference that person and not to direct the message to said person, |
| * as such, the <code>nickCompletionSuffix</code> does not need to be |
| * appended. |
| */ |
| private boolean isAtStart = false; |
| |
| private CTabItem itemSelected = null; |
| |
| private Text getInputText() { |
| return chatRoomTab.getInputText(); |
| } |
| |
| private StyledText getOutputText() { |
| return chatRoomTab.getOutputText(); |
| } |
| |
| ChatRoom(IChatRoomContainer container, ChatRoomTab tabItem) { |
| Assert.isNotNull(container); |
| Assert.isNotNull(tabItem); |
| this.chatRoomContainer = container; |
| this.chatRoomMessageSender = container.getChatRoomMessageSender(); |
| this.chatRoomTab = tabItem; |
| options = new ArrayList(); |
| this.chatRoomTab.setKeyListener(this); |
| this.chatRoomParticipantsLabel = tabItem.getParticipantsLabel(); |
| this.chatRoomParticipantViewer = tabItem.getParticipantsViewer(); |
| |
| chatRoomContainer.addChatRoomAdminListener(new IChatRoomAdminListener() { |
| public void handleSubjectChange(ID from, final String newSubject) { |
| if (!chatRoomTab.getInputText().isDisposed()) { |
| chatRoomTab.getInputText().getDisplay().asyncExec(new Runnable() { |
| public void run() { |
| chatRoomTab.setSubject(newSubject); |
| } |
| }); |
| } |
| } |
| }); |
| |
| rootTabFolder.setUnselectedCloseVisible(true); |
| |
| rootTabFolder.addSelectionListener(new SelectionListener() { |
| |
| public void widgetDefaultSelected(SelectionEvent e) { |
| // do nothing |
| } |
| |
| public void widgetSelected(SelectionEvent e) { |
| itemSelected = (CTabItem) e.item; |
| if (itemSelected == chatRoomTab.tabItem) |
| makeTabItemNormal(); |
| if (rootChannelTab != null && itemSelected == rootChannelTab.tabItem) |
| rootChannelTab.makeTabItemNormal(); |
| } |
| }); |
| |
| StyledText st = getOutputText(); |
| if (st != null) { |
| ScrollBar vsb = st.getVerticalBar(); |
| if (vsb != null) { |
| vsb.addSelectionListener(scrollSelectionListener); |
| vsb.addDisposeListener(new DisposeListener() { |
| public void widgetDisposed(DisposeEvent e) { |
| StyledText ot = getOutputText(); |
| if (ot != null) { |
| ScrollBar vb = ot.getVerticalBar(); |
| if (vb != null) |
| vb.removeSelectionListener(scrollSelectionListener); |
| } |
| } |
| }); |
| } |
| } |
| } |
| |
| private SelectionListener scrollSelectionListener = new SelectionListener() { |
| |
| public void widgetDefaultSelected(SelectionEvent e) { |
| // do nothing |
| } |
| |
| public void widgetSelected(SelectionEvent e) { |
| if (!isLastOutputInvisible(getOutputText())) { |
| makeTabItemNormal(); |
| } |
| } |
| |
| }; |
| |
| protected void makeTabItemBold() { |
| changeTabItem(true); |
| } |
| |
| protected void makeTabItemNormal() { |
| changeTabItem(false); |
| } |
| |
| protected void changeTabItem(boolean bold) { |
| CTabItem item = chatRoomTab.tabItem; |
| Font oldFont = item.getFont(); |
| FontData[] fd = oldFont.getFontData(); |
| item.setFont(new Font(oldFont.getDevice(), fd[0].getName(), fd[0].getHeight(), (bold) ? SWT.BOLD : SWT.NORMAL)); |
| } |
| |
| public void handleMessage(final ID fromID, final String messageBody) { |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| if (rootDisposed) |
| return; |
| appendText(chatRoomTab, getOutputText(), new ChatLine(messageBody, new ChatRoomParticipant(fromID))); |
| } |
| }); |
| } |
| |
| public void handleInvitationReceived(ID roomID, ID from, String subject, String body) { |
| // XXX TODO show UI for invitation |
| } |
| |
| public void keyPressed(KeyEvent e) { |
| handleKeyPressed(e); |
| } |
| |
| public void keyReleased(KeyEvent e) { |
| handleKeyReleased(e); |
| } |
| |
| protected void handleKeyPressed(KeyEvent evt) { |
| Text inputText = getInputText(); |
| if (evt.character == SWT.CR) { |
| if (inputText.getText().trim().length() > 0) |
| handleTextInput(inputText.getText()); |
| clearInput(); |
| makeTabItemNormal(); |
| if (Activator.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.PREFERENCES_SCROLLONINPUT)) |
| scrollToEnd(getOutputText()); |
| evt.doit = false; |
| isCycling = false; |
| } else if (evt.character == SWT.TAB) { |
| // don't propogate the event upwards and insert a tab character |
| evt.doit = false; |
| int pos = inputText.getCaretPosition(); |
| // if the user is at the beginning of the line, do nothing |
| if (pos == 0) |
| return; |
| String text = inputText.getText(); |
| // check to see if the user is currently cycling through the |
| // available nicknames |
| if (isCycling) { |
| // if everything's been cycled over, start over at zero |
| if (choice == options.size()) { |
| choice = 0; |
| } |
| |
| String append = ((String) options.get(choice++)) + (isAtStart ? nickCompletionSuffix + " " : " "); //$NON-NLS-1$ //$NON-NLS-2$ |
| // remove the previous completion proposal and insert the new one |
| inputText.setText(text.substring(0, caret - prefixLength) + append + text.substring(caret + nickRemainder)); |
| // subtract the prefix so we remember where we were originally |
| nickRemainder = append.length() - prefixLength; |
| // set the caret position to be the place where the nickname |
| // completion ended |
| inputText.setSelection(caret + nickRemainder); |
| } else { |
| // the user is not cycling, so we need to identify what the |
| // user has typed based on the current caret position |
| int count = pos - 1; |
| // keep looping until the whitespace has been identified or |
| // the beginning of the message has been reached |
| while (count > -1 && !Character.isWhitespace(text.charAt(count))) { |
| count--; |
| } |
| count++; |
| // remove all previous options |
| options.clear(); |
| // get the prefix that the user typed as a lowercase string |
| String prefix = text.substring(count, pos).toLowerCase(); |
| isAtStart = count == 0; |
| // if what's found was actually whitespace, do nothing |
| if (prefix.trim().equals("")) { //$NON-NLS-1$ |
| return; |
| } |
| // get all of the users in this room and store them if they |
| // start with the prefix that the user has typed |
| TableItem[] participants = chatRoomParticipantViewer.getTable().getItems(); |
| for (int i = 0; i < participants.length; i++) { |
| String name = participants[i].getText(); |
| // do a lowercase comparison because we should display options that differ in casing |
| if (name.toLowerCase().startsWith(prefix)) { |
| options.add(name); |
| } |
| } |
| |
| // simply return if no matches have been found |
| if (options.isEmpty()) |
| return; |
| |
| prefixLength = prefix.length(); |
| if (options.size() == 1) { |
| String nickname = (String) options.get(0); |
| // since only one nickname is available, we'll select |
| // the prefix that has been entered and then replace it |
| // with the nickname option |
| inputText.setSelection(pos - prefixLength, pos); |
| inputText.insert(nickname + (isAtStart ? nickCompletionSuffix + " " : " ")); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else if (options.size() <= maximumCyclingOptions) { |
| // note that the user is currently cycling through |
| // options and also store the current caret position |
| isCycling = true; |
| caret = pos; |
| choice = 0; |
| // insert the nickname after removing the prefix |
| String nickname = options.get(choice++) + (isAtStart ? nickCompletionSuffix + " " : " "); //$NON-NLS-1$ //$NON-NLS-2$ |
| // select the prefix of the proposal |
| inputText.setSelection(pos - prefixLength, pos); |
| // and then replace it with a proposal |
| inputText.insert(nickname); |
| // store the length of this truncated nickname so that |
| // it can be removed when the user is cycling |
| nickRemainder = nickname.length() - prefixLength; |
| } else { |
| // as there are too many choices for the user to pick |
| // from, simply display all of the available ones on the |
| // chat window so that the user can get a visual |
| // indicator of what's available and narrow down the |
| // choices by typing a few more additional characters |
| StringBuffer choices = new StringBuffer(); |
| synchronized (choices) { |
| for (int i = 0; i < options.size(); i++) { |
| choices.append(options.get(i)).append(' '); |
| } |
| choices.delete(choices.length() - 1, choices.length()); |
| } |
| appendText(chatRoomTab, getOutputText(), new ChatLine(choices.toString())); |
| } |
| } |
| } else { |
| // remove the cycling marking for any other key pressed |
| isCycling = false; |
| } |
| } |
| |
| protected void handleKeyReleased(KeyEvent evt) { |
| if (evt.character == SWT.TAB) { |
| // don't move to the next widget or try to add tabs |
| evt.doit = false; |
| } |
| } |
| |
| protected void handleTextInput(String text) { |
| if (chatRoomMessageSender == null) { |
| MessageDialog.openError(getViewSite().getShell(), Messages.ChatRoomManagerView_NOT_CONNECTED_TITLE, Messages.ChatRoomManagerView_NOT_CONNECTED_MESSAGE); |
| return; |
| } |
| String output = processForCommand(chatRoomContainer, text); |
| if (output != null) |
| sendMessageLine(output); |
| } |
| |
| protected void chatRoomDisconnect() { |
| if (chatRoomContainer != null) |
| chatRoomContainer.disconnect(); |
| } |
| |
| protected void clearInput() { |
| getInputText().setText(""); //$NON-NLS-1$ |
| } |
| |
| protected void sendMessageLine(String line) { |
| try { |
| chatRoomMessageSender.sendMessage(line); |
| } catch (ECFException e) { |
| disconnected(); |
| } |
| } |
| |
| public void handlePresence(final ID fromID, final IPresence presence) { |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| if (rootDisposed) |
| return; |
| boolean isAdd = presence.getType().equals(IPresence.Type.AVAILABLE); |
| ChatRoomParticipant p = new ChatRoomParticipant(fromID); |
| if (isAdd) { |
| if (localUser == null) |
| localUser = p; |
| addParticipant(p); |
| } else |
| removeParticipant(p); |
| } |
| }); |
| } |
| |
| public void disconnected() { |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| if (rootDisposed) |
| return; |
| Text inputText = getInputText(); |
| if (!inputText.isDisposed()) |
| inputText.setEnabled(false); |
| } |
| }); |
| } |
| |
| protected boolean isConnected() { |
| Text inputText = getInputText(); |
| return !inputText.isDisposed() && inputText.isEnabled(); |
| } |
| |
| protected void setSelected() { |
| rootTabFolder.setSelection(chatRoomTab.tabItem); |
| } |
| |
| protected void addParticipant(IUser p) { |
| if (p != null) { |
| ID id = p.getID(); |
| if (id != null) { |
| Preferences prefs = Activator.getDefault().getPluginPreferences(); |
| |
| if (prefs.getBoolean(PreferenceConstants.CHATROOM_SHOW_USER_PRESENCE)) |
| appendText(chatRoomTab, getOutputText(), new ChatLine(NLS.bind(Messages.ChatRoomManagerView_ENTERED_MESSAGE, getUsernameFromID(id)), null)); |
| chatRoomParticipantViewer.add(p); |
| chatRoomParticipantsLabel.setText(NLS.bind(Messages.ChatRoomManagerView_USERS_IN_CHAT_ROOM, String.valueOf(chatRoomContainer.getChatRoomParticipants().length))); |
| } |
| } |
| } |
| |
| protected boolean isLocalUser(ID id) { |
| if (localUser == null) |
| return false; |
| else if (localUser.getID().equals(id)) |
| return true; |
| else |
| return false; |
| } |
| |
| protected void removeLocalUser() { |
| // It's us that's gone away... so we're outta here |
| String title = getPartName(); |
| setPartName(NLS.bind(Messages.ChatRoomManagerView_VIEW_DISABLED_NAME, title)); |
| removeAllParticipants(); |
| disconnect(); |
| setEnabled(false); |
| } |
| |
| protected void removeParticipant(IUser p) { |
| if (p != null) { |
| ID id = p.getID(); |
| if (id != null) { |
| Preferences prefs = Activator.getDefault().getPluginPreferences(); |
| |
| if (prefs.getBoolean(PreferenceConstants.CHATROOM_SHOW_USER_PRESENCE)) |
| appendText(chatRoomTab, getOutputText(), new ChatLine(NLS.bind(Messages.ChatRoomManagerView_LEFT_MESSAGE, getUsernameFromID(id)), null)); |
| chatRoomParticipantViewer.remove(p); |
| chatRoomParticipantsLabel.setText(NLS.bind(Messages.ChatRoomManagerView_USERS_IN_CHAT_ROOM, String.valueOf(chatRoomContainer.getChatRoomParticipants().length))); |
| } |
| } |
| } |
| |
| protected void removeAllParticipants() { |
| Table t = chatRoomParticipantViewer.getTable(); |
| for (int i = 0; i < t.getItemCount(); i++) { |
| Object o = chatRoomParticipantViewer.getElementAt(i); |
| if (o != null) |
| chatRoomParticipantViewer.remove(o); |
| } |
| chatRoomParticipantsLabel.setText(NLS.bind(Messages.ChatRoomManagerView_USERS_IN_CHAT_ROOM, String.valueOf(chatRoomContainer.getChatRoomParticipants().length))); |
| } |
| } |
| |
| protected void handleTextInput(String text) { |
| if (rootMessageSender == null) { |
| MessageDialog.openError(getViewSite().getShell(), Messages.ChatRoomManagerView_NOT_CONNECTED_TITLE, Messages.ChatRoomManagerView_NOT_CONNECTED_MESSAGE); |
| } else { |
| String output = processForCommand(null, text); |
| if (output != null) |
| sendMessageLine(output); |
| } |
| } |
| |
| protected String processForCommand(IChatRoomContainer chatRoomContainer, String text) { |
| IChatRoomCommandListener l = commandListener; |
| if (l != null) |
| return l.handleCommand(chatRoomContainer, text); |
| return text; |
| } |
| |
| protected void handleEnter() { |
| Text inputText = getRootTextInput(); |
| if (inputText.getText().trim().length() > 0) |
| handleTextInput(inputText.getText()); |
| clearInput(); |
| scrollToEnd(getRootTextOutput()); |
| if (rootChannelTab != null) |
| rootChannelTab.makeTabItemNormal(); |
| } |
| |
| protected void handleKeyPressed(KeyEvent evt) { |
| if (evt.character == SWT.CR) { |
| handleEnter(); |
| evt.doit = false; |
| } |
| } |
| |
| public void setFocus() { |
| Text text = getRootTextInput(); |
| if (text != null) |
| text.setFocus(); |
| } |
| |
| public void joinRoom(final IChatRoomInfo info, final String password) { |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| if (rootDisposed) |
| return; |
| doJoinRoom(info, password); |
| } |
| }); |
| } |
| |
| public void dispose() { |
| disconnect(); |
| rootDisposed = true; |
| super.dispose(); |
| } |
| |
| protected String getMessageString(ID fromID, String text) { |
| return NLS.bind(Messages.ChatRoomManagerView_MESSAGE, fromID.getName(), text); |
| } |
| |
| private ID createStringID(String str) { |
| try { |
| return IDFactory.getDefault().createStringID(str); |
| } catch (IDCreateException e) { |
| // Should not happen |
| } |
| |
| return null; |
| } |
| |
| private MessagesView getMessagesView() throws PartInitException { |
| IWorkbenchPage page = getSite().getPage(); |
| MessagesView messageView = (MessagesView) page.findView(MessagesView.VIEW_ID); |
| if (messageView == null) { |
| messageView = (MessagesView) page.showView(MessagesView.VIEW_ID, null, IWorkbenchPage.VIEW_CREATE); |
| } |
| |
| return messageView; |
| } |
| |
| /** |
| * A delegate method to handle chat messages. |
| * @param message the chat message that has been received |
| * @since 1.1 |
| */ |
| public void handleChatMessage(final IChatMessage message) { |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| try { |
| ID targetID = createStringID(localUserName); |
| MessagesView messageView = getMessagesView(); |
| |
| IWorkbenchSiteProgressService service = (IWorkbenchSiteProgressService) messageView.getSite().getAdapter(IWorkbenchSiteProgressService.class); |
| |
| if (container.getPrivateMessageSender() != null) { |
| messageView.openTab(container.getPrivateMessageSender(), null, targetID, message.getFromID()); |
| |
| messageView.showMessage(message); |
| service.warnOfContentChange(); |
| } |
| } catch (Exception e) { |
| Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.ChatRoomManagerView_EXCEPTION_MESSAGE_VIEW_INITIALIZATION + message.getFromID(), e)); |
| } |
| } |
| }); |
| } |
| |
| public void handleMessage(final ID fromID, final String messageBody) { |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| if (rootDisposed) |
| return; |
| if (rootChannelTab != null) { |
| appendText(rootChannelTab, getRootTextOutput(), new ChatLine(messageBody, new ChatRoomParticipant(fromID))); |
| rootChannelTab.makeTabItemBold(); |
| } |
| } |
| }); |
| } |
| |
| /** |
| * @return String username for given <code>targetID</code> |
| */ |
| public static String getUsernameFromID(ID targetID) { |
| IChatID chatID = (IChatID) targetID.getAdapter(IChatID.class); |
| if (chatID != null) |
| return chatID.getUsername(); |
| try { |
| URI uri = new URI(targetID.getName()); |
| String user = uri.getUserInfo(); |
| return user == null ? targetID.getName() : user; |
| } catch (URISyntaxException e) { |
| String userAtHost = targetID.getName(); |
| int atIndex = userAtHost.lastIndexOf(ATSIGN); |
| if (atIndex != -1) |
| userAtHost = userAtHost.substring(0, atIndex); |
| return userAtHost; |
| } |
| } |
| |
| /** |
| * @return String hostname for given <code>targetID</code> |
| */ |
| public static String getHostnameFromID(ID targetID) { |
| IChatID chatID = (IChatID) targetID.getAdapter(IChatID.class); |
| if (chatID != null) |
| return chatID.getHostname(); |
| try { |
| URI uri = new URI(targetID.getName()); |
| String host = uri.getHost(); |
| return host == null ? targetID.getName() : host; |
| } catch (URISyntaxException e) { |
| String userAtHost = targetID.getName(); |
| int atIndex = userAtHost.lastIndexOf(ATSIGN); |
| if (atIndex != -1) |
| userAtHost = userAtHost.substring(atIndex + 1); |
| return userAtHost; |
| } |
| } |
| |
| class ChatRoomParticipant implements IUser, IActionFilter { |
| private static final long serialVersionUID = 2008114088656711572L; |
| |
| ID id; |
| |
| public ChatRoomParticipant(ID id) { |
| this.id = id; |
| } |
| |
| public ID getID() { |
| return id; |
| } |
| |
| public String getName() { |
| return toString(); |
| } |
| |
| public boolean equals(Object other) { |
| if (!(other instanceof ChatRoomParticipant)) |
| return false; |
| ChatRoomParticipant o = (ChatRoomParticipant) other; |
| if (id.equals(o.id)) |
| return true; |
| return false; |
| } |
| |
| public int hashCode() { |
| return id.hashCode(); |
| } |
| |
| public String toString() { |
| return getUsernameFromID(id); |
| } |
| |
| public Map getProperties() { |
| return null; |
| } |
| |
| public Object getAdapter(Class adapter) { |
| return null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ecf.core.user.IUser#getNickname() |
| */ |
| public String getNickname() { |
| return getName(); |
| } |
| |
| public boolean testAttribute(Object target, String name, String value) { |
| if (name.equals("scheme")) { //$NON-NLS-1$ |
| IChatRoomContainer c = ChatRoomManagerView.this.container; |
| String scheme = c.getConnectedID().getNamespace().getScheme(); |
| return scheme.equalsIgnoreCase(value); |
| } |
| return false; |
| } |
| } |
| |
| public void disconnect() { |
| if (rootCloseListener != null) { |
| rootCloseListener.chatRoomViewClosing(); |
| } |
| // disconnect from each chat room container |
| for (Iterator i = chatRooms.values().iterator(); i.hasNext();) { |
| ChatRoom chatRoom = (ChatRoom) i.next(); |
| IChatRoomContainer c = chatRoom.chatRoomContainer; |
| if (c != null) |
| c.disconnect(); |
| } |
| rootMessageSender = null; |
| rootCloseListener = null; |
| chatRooms.clear(); |
| } |
| |
| protected void removeLocalUser() { |
| // It's us that's gone away... so we're outta here |
| String title = getPartName(); |
| setPartName(NLS.bind(Messages.ChatRoomManagerView_VIEW_DISABLED_NAME, title)); |
| disconnect(); |
| setEnabled(false); |
| } |
| |
| public void handleInvitationReceived(ID roomID, ID from, String subject, String body) { |
| // XXX TODO |
| } |
| |
| private boolean isLastOutputInvisible(StyledText chatText) { |
| Point locAtEnd = chatText.getLocationAtOffset(chatText.getText().length()); |
| Rectangle bounds = chatText.getBounds(); |
| return (locAtEnd.y > bounds.height + 5); |
| } |
| |
| private void scrollToEnd(StyledText chatText) { |
| chatText.setSelection(chatText.getText().length()); |
| } |
| |
| protected void appendText(ChatRoomTab chatRoomTab, StyledText st, ChatLine text) { |
| if (st == null || text == null) { |
| return; |
| } |
| |
| boolean isAtEndBeforeAppend = !isLastOutputInvisible(st); |
| |
| String originator = null; |
| if (text.getOriginator() != null) { |
| originator = text.getOriginator().getNickname(); |
| } |
| |
| if (messageRenderer == null) |
| messageRenderer = new MessageRenderer(); |
| |
| String output = messageRenderer.render(text.getText(), originator, localUserName); |
| StyleRange[] ranges = messageRenderer.getStyleRanges(); |
| |
| if (output == null) { |
| return; |
| } |
| |
| int startRange = st.getText().length(); |
| |
| if (!text.isNoCRLF()) { |
| output += "\n"; //$NON-NLS-1$ |
| } |
| |
| st.append(output); |
| |
| if (ranges != null) { |
| |
| // set all ranges to start as message line starts |
| for (int i = 0; i < ranges.length; i++) { |
| ranges[i].start += startRange; |
| } |
| st.replaceStyleRanges(startRange, output.length(), ranges); |
| } |
| |
| if (isAtEndBeforeAppend) |
| scrollToEnd(st); |
| |
| if (isCurrentlyActive(chatRoomTab)) |
| chatRoomTab.makeTabItemNormal(); |
| else |
| chatRoomTab.makeTabItemBold(); |
| } |
| |
| protected void outputClear() { |
| if (MessageDialog.openConfirm(null, Messages.ChatRoomManagerView_CLEAR_CONFIRM_TITLE, Messages.ChatRoomManagerView_CLEAR_CONFIRM_MESSAGE)) { |
| getRootTextOutput().setText(""); //$NON-NLS-1$ |
| } |
| } |
| |
| protected void outputCopy() { |
| StyledText outputText = getRootTextOutput(); |
| String t = outputText.getSelectionText(); |
| if (t == null || t.length() == 0) { |
| outputText.selectAll(); |
| } |
| outputText.copy(); |
| outputText.setSelection(outputText.getText().length()); |
| } |
| |
| protected void outputSelectAll() { |
| getRootTextOutput().selectAll(); |
| } |
| |
| protected void makeActions() { |
| |
| outputSelectAll = new Action() { |
| public void run() { |
| outputSelectAll(); |
| } |
| }; |
| outputSelectAll.setText(Messages.ChatRoomManagerView_SELECT_ALL_TEXT); |
| outputSelectAll.setToolTipText(Messages.ChatRoomManagerView_SELECT_ALL_TOOLTIP); |
| outputSelectAll.setAccelerator(SWT.CTRL | 'A'); |
| outputCopy = new Action() { |
| public void run() { |
| outputCopy(); |
| } |
| }; |
| outputCopy.setText(Messages.ChatRoomManagerView_COPY_TEXT); |
| outputCopy.setToolTipText(Messages.ChatRoomManagerView_COPY_TOOLTIP); |
| outputCopy.setAccelerator(SWT.CTRL | 'C'); |
| outputCopy.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); |
| outputClear = new Action() { |
| public void run() { |
| outputClear(); |
| } |
| }; |
| outputClear.setText(Messages.ChatRoomManagerView_CLEAR_TEXT); |
| outputClear.setToolTipText(Messages.ChatRoomManagerView_CLEAR_TOOLTIP); |
| outputPaste = new Action() { |
| public void run() { |
| getRootTextInput().paste(); |
| } |
| }; |
| outputPaste.setText(Messages.ChatRoomManagerView_PASTE_TEXT); |
| outputPaste.setToolTipText(Messages.ChatRoomManagerView_PASTE_TOOLTIP); |
| outputPaste.setAccelerator(SWT.CTRL | 'V'); |
| outputPaste.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_PASTE)); |
| } |
| |
| 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(IWorkbenchActionConstants.MB_ADDITIONS)); |
| } |
| |
| private void hookContextMenu() { |
| MenuManager menuMgr = new MenuManager(); |
| menuMgr.setRemoveAllWhenShown(true); |
| menuMgr.addMenuListener(new IMenuListener() { |
| public void menuAboutToShow(IMenuManager manager) { |
| fillContextMenu(manager); |
| } |
| }); |
| StyledText outputText = getRootTextOutput(); |
| Menu menu = menuMgr.createContextMenu(outputText); |
| outputText.setMenu(menu); |
| ISelectionProvider selectionProvider = new ISelectionProvider() { |
| |
| public void addSelectionChangedListener(ISelectionChangedListener listener) { |
| // do nothing |
| } |
| |
| public ISelection getSelection() { |
| StyledText ot = getRootTextOutput(); |
| ISelection selection = new TextSelection(ot.getSelectionRange().x, ot.getSelectionRange().y); |
| |
| return selection; |
| } |
| |
| public void removeSelectionChangedListener(ISelectionChangedListener listener) { |
| // do nothing |
| } |
| |
| public void setSelection(ISelection selection) { |
| if (selection instanceof ITextSelection) { |
| ITextSelection textSelection = (ITextSelection) selection; |
| StyledText ot = getRootTextOutput(); |
| ot.setSelection(textSelection.getOffset(), textSelection.getOffset() + textSelection.getLength()); |
| } |
| } |
| |
| }; |
| getSite().registerContextMenu(menuMgr, selectionProvider); |
| } |
| |
| public void setMessageRenderer(IMessageRenderer defaultMessageRenderer) { |
| this.messageRenderer = defaultMessageRenderer; |
| } |
| |
| private boolean isCurrentlyActive(ChatRoomTab chatRoomTab) { |
| int selected = rootTabFolder.getSelectionIndex(); |
| if (selected != -1) { |
| CTabItem item = rootTabFolder.getItem(selected); |
| if (item == chatRoomTab.tabItem) |
| return true; |
| } |
| return false; |
| } |
| } |