org.l2x6.eircc.ui.views.IrcAccountsView.java Source code

Java tutorial

Introduction

Here is the source code for org.l2x6.eircc.ui.views.IrcAccountsView.java

Source

/*
 * Copyright (c) 2014 Peter Palaga.
 * 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
 */

package org.l2x6.eircc.ui.views;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.handlers.CollapseAllHandler;
import org.eclipse.ui.handlers.ExpandAllHandler;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.part.ViewPart;
import org.l2x6.eircc.core.IrcException;
import org.l2x6.eircc.core.model.AbstractIrcChannel;
import org.l2x6.eircc.core.model.IrcAccount;
import org.l2x6.eircc.core.model.IrcLog;
import org.l2x6.eircc.core.model.IrcModel;
import org.l2x6.eircc.core.model.PlainIrcChannel;
import org.l2x6.eircc.core.model.event.IrcModelEvent;
import org.l2x6.eircc.core.model.event.IrcModelEventListener;
import org.l2x6.eircc.ui.ContextMenuConstants;
import org.l2x6.eircc.ui.EirccUi;
import org.l2x6.eircc.ui.IrcUiMessages;
import org.l2x6.eircc.ui.actions.AddIrcAccountAction;
import org.l2x6.eircc.ui.actions.IrcTreeAction;
import org.l2x6.eircc.ui.actions.IrcTreeActions;
import org.l2x6.eircc.ui.actions.PromptAndJoinChannelAction;

/**
 * @author <a href="mailto:ppalaga@redhat.com">Peter Palaga</a>
 */
public class IrcAccountsView extends ViewPart implements IrcModelEventListener {
    public static final String ID = "org.l2x6.eircc.ui.views.IrcAccountsView";
    private SashForm accountsDetailsSplitter;
    private Listener accountsTreeSelectionListener;
    private TreeViewer accountsTreeViewer;
    private AddIrcAccountAction addIrcAccountAction;

    private CollapseAllHandler collapseAllAccounts;
    private IrcTreeActions<?> connectAccountAction;

    private IrcTreeActions<?> disconnectAccountAction;

    private Label emptyLabel;

    private ExpandAllHandler expandAllAccounts;
    private ISelectionProvider focusedTreeViewer;
    private IrcTreeActions<?> joinAccountChannelAction;
    private IrcTreeActions<?> joinServerChannelAction;
    private IrcTreeActions<?> leaveAccountChannelAction;
    private IrcTreeActions<?> listChannelsAction;

    private List<ISelectionChangedListener> listeners = Collections.emptyList();
    private PageBook pagebook;
    private PromptAndJoinChannelAction promptChannelAndJoinAction;
    private CLabel serverChannelsLabel;
    private TreeViewer serverChannelsTreeViewer;
    // TODO private TreeViewer serverUsersTreeViewer;
    private ViewForm serverChannelsViewForm;
    private IrcTreeAction[] treeActions;

    private MouseListener treeMouseListener;

    private FocusListener treesFocusListener = new FocusListener() {
        public void focusGained(FocusEvent event) {
            if (accountsTreeViewer.getTree() == event.getSource()) {
                focusedTreeViewer = accountsTreeViewer;
            } else if (serverChannelsTreeViewer.getTree() == event.getSource()) {
                focusedTreeViewer = serverChannelsTreeViewer;
            }
        }

        public void focusLost(FocusEvent event) {
        }
    };
    private ISelectionChangedListener treesSelectionListener = new ISelectionChangedListener() {

        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            // ITreeSelection selection = (ITreeSelection) event.getSelection();
            // TreePath[] selectedPaths = selection.getPaths();
            // List<Object> selectedObjects =
            // Arrays.stream(selectedPaths).map(path -> path.getLastSegment())
            // .collect(Collectors.toList());
            // ISelectionService selectionService =
            // getSite().getWorkbenchWindow().getSelectionService();
            // selectionService.setSelection(selectedObjects);
            if (event.getSelectionProvider() == focusedTreeViewer) {
                for (ISelectionChangedListener l : listeners) {
                    l.selectionChanged(event);
                }
            }
        }
    };
    private IrcTreeActions<?> watchChannelAction;

    @Override
    public void createPartControl(Composite container) {

        pagebook = new PageBook(container, SWT.NONE);

        emptyLabel = new Label(pagebook, SWT.TOP + SWT.LEFT + SWT.WRAP);
        emptyLabel.setText(IrcUiMessages.IrcServersView_empty);

        accountsDetailsSplitter = new SashForm(pagebook, SWT.VERTICAL);
        // accountsDetailsSplitter.setVisible(false);

        /* accounts tree */
        accountsTreeViewer = new TreeViewer(accountsDetailsSplitter, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
        accountsTreeViewer.setLabelProvider(IrcLabelProvider.getInstance());
        accountsTreeViewer.setContentProvider(new IrcAccountsTreeContentProvider());
        accountsTreeViewer.addSelectionChangedListener(treesSelectionListener);

        /* the bottom part */

        /* server channels */
        serverChannelsViewForm = new ViewForm(accountsDetailsSplitter, SWT.NONE);
        accountsDetailsSplitter.setWeights(new int[] { 35, 65 });

        serverChannelsTreeViewer = new TreeViewer(serverChannelsViewForm, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
        serverChannelsTreeViewer.setLabelProvider(IrcLabelProvider.getInstance());
        serverChannelsTreeViewer.setContentProvider(new IrcServerChannelsTreeContentProvider());
        serverChannelsTreeViewer.addSelectionChangedListener(treesSelectionListener);

        serverChannelsViewForm.setContent(serverChannelsTreeViewer.getControl());

        serverChannelsLabel = new CLabel(serverChannelsViewForm, SWT.NONE);
        serverChannelsViewForm.setTopLeft(serverChannelsLabel);
        serverChannelsLabel.setText(IrcUiMessages.IrcAccountsView_serverChannelsLabel_text);

        ToolBar serverChannelsToolbar = new ToolBar(serverChannelsViewForm, SWT.FLAT | SWT.WRAP);
        serverChannelsViewForm.setTopCenter(serverChannelsToolbar);

        /* server users */
        // TODO server users pane

        /* connect the model */
        IrcModel ircModel = EirccUi.getDefault().getModel();
        ircModel.addModelEventListener(this);
        accountsTreeViewer.setInput(ircModel);
        setEmptyLabelVisible(!ircModel.hasAccounts());

        /* actions, tolbars and menus */

        /* acounts related actions */
        Tree accountsTree = accountsTreeViewer.getTree();
        accountsTree.addListener(SWT.Selection, getAccountsTreeSelectionListener());
        accountsTree.addMouseListener(getTreeMouseListener());
        accountsTree.addFocusListener(treesFocusListener);
        addIrcAccountAction = new AddIrcAccountAction();
        listChannelsAction = IrcTreeActions.createListChannelsAction(accountsTree);
        connectAccountAction = IrcTreeActions.createConnectAccountAction(accountsTree);
        disconnectAccountAction = IrcTreeActions.createDisonnectAccountAction(accountsTree);
        joinAccountChannelAction = IrcTreeActions.createJoinAccountChannelAction(accountsTree);
        promptChannelAndJoinAction = new PromptAndJoinChannelAction(accountsTree);
        leaveAccountChannelAction = IrcTreeActions.createLeaveChannelAction(accountsTree);
        watchChannelAction = IrcTreeActions.createWatchChannelAction(accountsTree);

        IViewSite site = getViewSite();
        IToolBarManager accountsTbm = site.getActionBars().getToolBarManager();
        accountsTbm.add(new Separator(ContextMenuConstants.GROUP_IRC_ACCOUNTS));
        accountsTbm.appendToGroup(ContextMenuConstants.GROUP_IRC_ACCOUNTS, addIrcAccountAction);
        accountsTbm.appendToGroup(ContextMenuConstants.GROUP_IRC_ACCOUNTS, connectAccountAction);
        accountsTbm.appendToGroup(ContextMenuConstants.GROUP_IRC_ACCOUNTS, disconnectAccountAction);
        accountsTbm.appendToGroup(ContextMenuConstants.GROUP_IRC_ACCOUNTS, joinAccountChannelAction);
        accountsTbm.appendToGroup(ContextMenuConstants.GROUP_IRC_ACCOUNTS, leaveAccountChannelAction);
        site.getActionBars().updateActionBars();

        /* accounts tree context menu */
        MenuManager accountsMenuManager = new MenuManager("#PopupMenu");
        Menu accountsMenu = accountsMenuManager.createContextMenu(accountsTree);
        accountsMenuManager.add(addIrcAccountAction);
        accountsMenuManager.add(listChannelsAction);
        accountsMenuManager.add(connectAccountAction);
        accountsMenuManager.add(disconnectAccountAction);
        accountsMenuManager.add(joinAccountChannelAction);
        accountsMenuManager.add(promptChannelAndJoinAction);
        accountsMenuManager.add(leaveAccountChannelAction);
        accountsMenuManager.add(watchChannelAction);
        accountsTree.setMenu(accountsMenu);
        site.registerContextMenu(accountsMenuManager, accountsTreeViewer);

        /* server channels related actions */
        Tree serverChannelsTree = serverChannelsTreeViewer.getTree();
        serverChannelsTree.addMouseListener(getTreeMouseListener());
        serverChannelsTree.addFocusListener(treesFocusListener);

        joinServerChannelAction = IrcTreeActions.createJoinServerChannelAction(serverChannelsTree);
        treeActions = new IrcTreeAction[] { listChannelsAction, connectAccountAction, disconnectAccountAction,
                joinAccountChannelAction, promptChannelAndJoinAction, leaveAccountChannelAction,
                joinServerChannelAction, watchChannelAction };

        ToolBarManager serverChannelsTbm = new ToolBarManager(serverChannelsToolbar);
        serverChannelsTbm.add(new Separator(ContextMenuConstants.GROUP_IRC_SERVER_CHANNELS));
        serverChannelsTbm.appendToGroup(ContextMenuConstants.GROUP_IRC_SERVER_CHANNELS, listChannelsAction);
        serverChannelsTbm.appendToGroup(ContextMenuConstants.GROUP_IRC_SERVER_CHANNELS, joinServerChannelAction);
        serverChannelsTbm.update(false);

        /* server channels context menu */
        MenuManager serverChannelsMenuManager = new MenuManager("#PopupMenu");
        Menu serverChannelsMenu = serverChannelsMenuManager.createContextMenu(accountsTree);
        serverChannelsMenuManager.add(listChannelsAction);
        serverChannelsMenuManager.add(joinServerChannelAction);
        serverChannelsTree.setMenu(serverChannelsMenu);
        site.registerContextMenu(serverChannelsMenuManager, serverChannelsTreeViewer);

        if (site != null) {
            IHandlerService handlerService = (IHandlerService) site.getService(IHandlerService.class);
            if (handlerService != null) {
                collapseAllAccounts = new CollapseAllHandler(accountsTreeViewer);
                handlerService.activateHandler(CollapseAllHandler.COMMAND_ID, collapseAllAccounts);
                expandAllAccounts = new ExpandAllHandler(accountsTreeViewer);
                handlerService.activateHandler(ExpandAllHandler.COMMAND_ID, expandAllAccounts);
            }
        }
    }

    @Override
    public void dispose() {
        collapseAllAccounts.dispose();
        expandAllAccounts.dispose();

        accountsTreeViewer.removeSelectionChangedListener(treesSelectionListener);
        Tree accountsTree = accountsTreeViewer.getTree();
        if (!accountsTree.isDisposed()) {
            accountsTree.removeListener(SWT.Selection, getAccountsTreeSelectionListener());
            accountsTree.removeMouseListener(getTreeMouseListener());
            accountsTree.removeFocusListener(treesFocusListener);
        }
        serverChannelsTreeViewer.removeSelectionChangedListener(treesSelectionListener);
        Tree serverChannelsTree = serverChannelsTreeViewer.getTree();
        if (!serverChannelsTree.isDisposed()) {
            serverChannelsTree.removeMouseListener(getTreeMouseListener());
            serverChannelsTree.removeFocusListener(treesFocusListener);
        }
        EirccUi.getDefault().getModel().removeModelEventListener(this);

        Arrays.stream(treeActions).forEach(action -> action.dispose());

        super.dispose();
    }

    private Listener getAccountsTreeSelectionListener() {
        if (accountsTreeSelectionListener == null) {
            accountsTreeSelectionListener = new Listener() {

                @Override
                public void handleEvent(Event event) {
                    if (event.widget instanceof Tree) {
                        Tree tree = (Tree) event.widget;
                        TreeItem[] selection = tree.getSelection();
                        if (selection.length == 1 && selection[0].getData() instanceof IrcAccount) {
                            IrcAccount account = (IrcAccount) selection[0].getData();
                            serverChannelsTreeViewer.setInput(account.getServer());
                        } else {
                            serverChannelsTreeViewer.setInput(null);
                        }
                    }
                }
            };
        }
        return accountsTreeSelectionListener;
    }

    @Override
    public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
        return super.getAdapter(adapter);
    }

    /**
     * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
     */
    public ISelection getSelection() {
        if (focusedTreeViewer != null) {
            return focusedTreeViewer.getSelection();
        }
        return null;
    }

    private MouseListener getTreeMouseListener() {
        if (treeMouseListener == null) {
            treeMouseListener = new MouseListener() {
                @Override
                public void mouseDoubleClick(MouseEvent e) {
                    try {
                        if (e.widget instanceof Tree) {
                            Tree tree = (Tree) e.widget;
                            TreeItem[] selection = tree.getSelection();
                            if (selection.length == 1) {
                                Object data = selection[0].getData();
                                if (data instanceof AbstractIrcChannel) {
                                    AbstractIrcChannel ch = (AbstractIrcChannel) selection[0].getData();
                                    if (!ch.isJoined()) {
                                        EirccUi.getController().joinChannel(ch);
                                    }
                                    EirccUi.getDefault().openEditor(ch, true);
                                } else if (data instanceof PlainIrcChannel) {
                                    PlainIrcChannel ch = (PlainIrcChannel) data;
                                    EirccUi.getController().joinChannel(ch);
                                }
                            }
                        }
                    } catch (Exception e1) {
                        EirccUi.log(e1);
                    }
                }

                @Override
                public void mouseDown(MouseEvent e) {
                }

                @Override
                public void mouseUp(MouseEvent e) {
                }
            };
        }
        return treeMouseListener;
    }

    /**
     * @see org.l2x6.eircc.core.model.event.IrcModelEventListener#handle(org.l2x6.eircc.core.model.event.IrcModelEvent)
     */
    @Override
    public void handle(IrcModelEvent e) {
        switch (e.getEventType()) {
        case ACCOUNT_ADDED:
            accountsTreeViewer.refresh();
            setEmptyLabelVisible(false);
            break;
        case ACCOUNT_REMOVED:
            accountsTreeViewer.refresh();
            if (!EirccUi.getDefault().getModel().hasAccounts()) {
                /* removed the last account */
                setEmptyLabelVisible(true);
            }
            break;
        case ACCOUNT_CHANNEL_ADDED:
            accountsTreeViewer.refresh();
            accountsTreeViewer.expandAll();
            break;
        case ACCOUNT_CHANNEL_REMOVED:
            accountsTreeViewer.refresh();
            break;
        case ACCOUNT_STATE_CHANGED:
            IrcAccount account = (IrcAccount) e.getModelObject();
            accountsTreeViewer.update(account, null);
            accountsTreeViewer.setExpandedState(account, true);
            IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
            switch (account.getState()) {
            case OFFLINE_AFTER_ERROR:
                IrcException lastException = account.getLastException();
                if (lastException != null) {
                    statusLineManager.setMessage(lastException.getLocalizedMessage());
                    break;
                }
            default:
                statusLineManager.setMessage("");
                break;
            }
            Arrays.stream(treeActions).forEach(action -> action.updateEnablement());

            break;
        case CHANNEL_JOINED_CHANGED:
            accountsTreeViewer.refresh();
            serverChannelsTreeViewer.refresh();
            Arrays.stream(treeActions).forEach(action -> action.updateEnablement());
            break;
        case LOG_STATE_CHANGED:
            IrcLog log = (IrcLog) e.getModelObject();
            accountsTreeViewer.update(log.getChannel(), null);
            break;
        case SERVER_CHANNEL_ADDED:
        case SERVER_CHANNELS_ADDED:
        case SERVER_CHANNEL_REMOVED:
            serverChannelsTreeViewer.refresh();
            break;
        case USER_ADDED:
        case USER_REMOVED:
            /* ignore */
            break;
        default:
            break;
        }
    }

    private void setEmptyLabelVisible(boolean visible) {
        if (visible) {
            pagebook.showPage(emptyLabel);
        } else {
            pagebook.showPage(accountsDetailsSplitter);
        }
    }

    @Override
    public void setFocus() {
        accountsTreeViewer.getTree().setFocus();
    }

}