Package net.sphene.goim.rcp.simpleui

Source Code of net.sphene.goim.rcp.simpleui.SimpleContactList$ContactListMouseListener

/*
* Gamers Own Instant Messenger
* Copyright (C) 2005-2006 Herbert Poul (kahless@sphene.net)
* http://goim.sphene.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/
package net.sphene.goim.rcp.simpleui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import net.sphene.goim.rcp.GOIMPlugin;
import net.sphene.goim.rcp.beans.GOIMAccount;
import net.sphene.goim.rcp.beans.GOIMAccountList;
import net.sphene.goim.rcp.beans.GOIMGameItem;
import net.sphene.goim.rcp.beans.GOIMRosterListener;
import net.sphene.goim.rcp.extensionpoints.IContactListView;
import net.sphene.goim.rcp.extensionpoints.GameExtensionPoint.GameExtensionProxy;
import net.sphene.goim.rcp.extensionpoints.IGame.IGameExtension;
import net.sphene.goim.rcp.preferences.PreferenceConstants;
import net.sphene.goim.rcp.ui.AbstractContactList;
import net.sphene.goim.rcp.ui.GOIMIcons;
import net.sphene.goim.rcp.ui.ContactList.EntryMenu;
import net.sphene.goim.rcp.xmpp.StatusChangedEvent;
import net.sphene.libs.SpheneEvent;
import net.sphene.libs.SpheneListener;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;

/**
* This is the default contact list. Called 'simple' because it simply uses
* a TreeView and not a custom widget, or a a combination of widgets like the 'fancy'
* contact list ({@link net.sphene.goim.rcp.ui.ContactList})<br><br>
*
* It uses a {@link org.eclipse.swt.custom.TreeEditor} to overlay gaim icons.
*/
public class SimpleContactList extends AbstractContactList implements
    IContactListView {
  public static final String NO_GROUP_NAME = "Default";

  public static final String NO_GROUP_COMPONENT = "Components (Transports)";

  /**
   * If this SimpleContactList handles all accounts in one list .. this list of accounts
   * is set.
   * @see #account
   */
  GOIMAccountList accountList;
  public GOIMAccountList getAccountList() { return accountList; }

  private Tree contactList;

  /**
   * The GOIMAccount - only set if this SimpleContactList handles only ONE account ..
   * @see #accountList
   * @see AbstractContactList#getActiveAccount()
   */
  GOIMAccount account;

  IContactListView container;

  boolean wasInit = false;

  boolean hideOffline = false;

  EntryMenu entryMenu;
 
  public void setColorsFromStore() {
    IPreferenceStore store = GOIMPlugin.getDefault().getPreferenceStore();
    // should not happen.. but .. it does.. so .. test it..
    if(contactList.isDisposed()) return;
    if(store.getBoolean(PreferenceConstants.P_SIMPLE_CONTACTLIST_CUSTOMIZE_COLORS)) {
      RGB rgb = PreferenceConverter.getColor(store,PreferenceConstants.P_SIMPLE_CONTACTLIST_COLORS_BACKGROUND);
      contactList.getParent().setBackground(new Color(contactList.getDisplay(),rgb));
      contactList.setBackground(new Color(contactList.getDisplay(),rgb));
      rgb = PreferenceConverter.getColor(store,PreferenceConstants.P_SIMPLE_CONTACTLIST_COLORS_TEXT);
      contactList.setForeground(new Color(contactList.getDisplay(),rgb));
    } else {
      contactList.setBackground(null);
      contactList.getParent().setBackground(contactList.getBackground());
      contactList.setForeground(null);
     
    }
    if(store.getBoolean(PreferenceConstants.P_SIMPLE_CONTACTLIST_CUSTOMIZE_FONTS)) {
      contactList.setFont(new Font(contactList.getDisplay(),PreferenceConverter.getFontData(store,PreferenceConstants.P_SIMPLE_CONTACTLIST_FONTS_DEFAULT)));
    } else {
      contactList.setFont(null);
    }
  }

  public class TreeGroup {
    public RosterGroup group;
    public String groupname;
    public List<TreeEntry> entries;
    public GOIMAccount account;
    public TreeItem item;
    public TreeItem parent;

    public TreeGroup(GOIMAccount account, TreeItem parent, RosterGroup group, String groupName) {
      this.account = account;
      this.group = group;
      this.parent = parent;
      this.groupname = groupName;
      this.entries = new LinkedList<TreeEntry>();
      this.item = null;
    }

    public void remove(RosterEntry entry) {
      ListIterator<TreeEntry> i = entries.listIterator();
      while (i.hasNext()) {
        TreeEntry treeEntryCompare = i.next();
        if (treeEntryCompare.entry.getUser().equals(entry.getUser())) {
          i.remove();
          treeEntryCompare.dispose();
          break;
        }
      }
    }

    public boolean updateSelf(Roster roster, RosterGroup group) {
      Iterator i;
      if(group == null) {
        if(this.group != null) {
          item.dispose();
          return true;
        }
        i = roster.getUnfiledEntries();
      } else
        i = group.getEntries();
      this.group = group;
      LinkedList<TreeEntry> oldEntries = new LinkedList<TreeEntry>(this.entries);
      while(i.hasNext()) {
        RosterEntry entry = (RosterEntry)i.next();
        if(group == null) {
          if(groupname.equals(NO_GROUP_COMPONENT)) {
            if(entry.getUser().indexOf('@') > -1 && !entry.getUser().equals(GOIMAccount.STATSCONTACTJID))
              continue;
          } else if(groupname.equals(NO_GROUP_NAME)) {
            if(entry.getUser().indexOf('@') < 0 || entry.getUser().equals(GOIMAccount.STATSCONTACTJID))
              continue;
          }
        }
        Iterator<TreeEntry> j = oldEntries.iterator();
        boolean found = false;
        while(j.hasNext()) {
          TreeEntry treeEntry = j.next();
          if(treeEntry.entry.getUser().equals(entry.getUser())) {
            j.remove();
            update(treeEntry);
            found = true;
            break;
          }
        }
        if(!found)
          update(new TreeEntry(account,this,entry));
      }
      if(oldEntries.size() > 0) {
        Iterator<TreeEntry> j = oldEntries.iterator();
        while(j.hasNext()) {
          TreeEntry treeEntry = j.next();
          entries.remove(treeEntry);
          treeEntry.dispose();
        }
      }
      return false;
    }
    public void update(TreeEntry treeEntry) {
      ListIterator<TreeEntry> i = entries.listIterator();
      boolean found = false;
      while (i.hasNext()) {
        TreeEntry treeEntryCompare = i.next();
        if (treeEntryCompare.equals(treeEntry)) {
          found = true;
          treeEntry = treeEntryCompare;
         
          if(!treeEntry.wantsToBeVisible()) {
//            i.remove();
//            treeEntry.dispose();
          } else {
            if(treeEntry.item != null && !treeEntry.item.isDisposed()) {
              RosterEntry entry = treeEntry.entry;
              Roster roster = account.xmpp.getRoster();
              Presence presence = (roster == null ? null : roster.getPresence(entry.getUser()));
              if(item.getData("presence") == presence) return;
//              updatePresenceOfItem(item, entry, (roster == null ? null : presence));
//              return;
            }
          }
          i.remove();
          treeEntry.dispose();
          break;
        }
      }
      if (!found) {
      }
      if (treeEntry.wantsToBeVisible()) {
        // Find place to insert treeEntry
        testVisibility(true);
        i = entries.listIterator();
        int j = 0;
        while (i.hasNext()) {
          TreeEntry treeEntryCompare = i.next();
          if (treeEntry.comesBefore(treeEntryCompare)) {
            i.previous();
            break;
          }
          j++;
        }
        i.add(treeEntry);
        treeEntry.createTreeItem(j);
        item.setExpanded(true);
      } else {
        testVisibility(false);
      }
    }

    public int getIndexOfItem() {
      TreeItem[] items;
      if (parent != null)
        items = parent.getItems();
      else
        items = contactList.getItems();
      if (groupname.equals(NO_GROUP_COMPONENT))
        return items.length;
      int i = 0;
      for (TreeItem item : items) {
        if (item.getData("entryjid") == null
            && // Own Presence Entry is always first in the list
            (item.getText().compareToIgnoreCase(groupname) > 0 || item
                .getText().equals(NO_GROUP_COMPONENT))) // Components
          // are
          // last
          return i;
        i++;
      }
      return i;
    }

    public void testVisibility(boolean needsCreation) {
      if (needsCreation && item == null) {
        int index = getIndexOfItem();
        if (parent != null) {
          item = new TreeItem(parent, SWT.NULL, index);
        } else {
          item = new TreeItem(contactList, SWT.NULL, index);
        }
        item.setData("account",account);
        item.setText(groupname);
        item.setImage(GOIMIcons.getImage(GOIMIcons.FOLDER_ICON));
      } else if (!needsCreation && item != null) {
        if (entries.size() < 1) {
          item.dispose();
          item = null;
        }
      }
    }
  }

  public class TreeEntry {
    protected GOIMAccount account;
    protected RosterEntry entry;
    protected TreeItem item;
    protected TreeGroup parent;

    public TreeEntry(GOIMAccount account, TreeGroup parent,
        RosterEntry entry) {
      this.account = account;
      this.entry = entry;
      this.parent = parent;
    }

    public boolean equals(Object obj) {
      if (obj == this)
        return true;
      if (obj instanceof TreeEntry) {
        return (((TreeEntry) obj).entry.getUser().equals(entry
            .getUser()));
      }
      return false;
    }

    public void dispose() {
      if (item != null) {
        item.dispose();
        item = null;
      }
    }

    // public boolean wantsToBeVisible() {
    // boolean visible = wantsToBeVisibleInt();
    // if(!visible && item != null) {
    // item.dispose(); item = null;
    // }
    // return visible;
    // }
    // private boolean wantsToBeVisibleInt() {
    public boolean wantsToBeVisible() {
      if (!hideOffline || entry.getUser().indexOf('@') < 0)
        return true;
      Roster roster = account.xmpp.getRoster();
      if (roster == null)
        return false;
      Presence p = roster.getPresence(entry.getUser());
      if (p == null || p.getType() != Presence.Type.AVAILABLE)
        return false;
      return true;
    }

    public boolean comesBefore(TreeEntry treeEntry) {
      int p1val = 0;
      int p2val = 0;
      Roster roster = account.xmpp.getRoster();
      if (roster != null) {
        p1val = getPresenceValue(roster.getPresence(entry.getUser()));
        p2val = getPresenceValue(roster.getPresence(treeEntry.entry
            .getUser()));
      }
      if (p1val > p2val)
        return true;
      if (p1val == p2val)
        return getRosterLabel(entry).compareToIgnoreCase(
            getRosterLabel(treeEntry.entry)) < 0;
      return false;
    }

    public void createTreeItem(int index) {
      item = new TreeItem(parent.item, SWT.NULL, index);
      item.setText(getRosterLabel(entry));
      item.setData("entry", entry);
      item.setData("account", account);
      Roster roster = account.xmpp.getRoster();
      Presence presence = roster == null ? null : roster.getPresence(entry.getUser());
      item.setData("presence",presence);
      updatePresenceOfItem(item, entry, presence);
    }
  }
 
  public SimpleContactList(Composite parent, int style,
      IContactListView container) {
    super(parent, style);
    this.container = container;
  }
 
  public void init() {
    if(wasInit)
      for(Control control : getChildren()) control.dispose();
    setLayout(new GridLayout(1,false));
   
//    Composite topComposite = new Composite(this,SWT.NULL);
//    RowLayout topCompositeLayout = new RowLayout();
//    topComposite.setLayout(topCompositeLayout);
   
//    final Button hideOfflineContacts = new Button(topComposite,SWT.TOGGLE);
//    hideOfflineContacts.setText("Hide Offline Contacts");
//    hideOfflineContacts.setSelection(hideOffline);
//    hideOfflineContacts.addListener(SWT.Selection,new Listener(){
//      public void handleEvent(Event event) {
//        setHideOfflineContacts(!getHideOfflineContacts());
//      }});

//    Group contactListGroup = new Group(this,SWT.SHADOW_NONE);
    Composite contactListGroup = new Composite(this,SWT.BORDER);
    contactListGroup.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true));
    GridLayout contactListGroupLayout = new GridLayout(1,false);
    contactListGroupLayout.marginHeight =
      contactListGroupLayout.marginWidth = 5;
    contactListGroup.setLayout(contactListGroupLayout);
   
    contactList = new Tree(contactListGroup,SWT.FULL_SELECTION);
    contactList.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true));
   
    contactListGroup.setBackground(contactList.getBackground());
   
    entryMenu = new EntryMenu(contactList);
   
    final TreeColumn jid = new TreeColumn(contactList,SWT.LEFT);
    jid.setText("JID");
    contactList.addListener(SWT.Resize,new Listener() {

      public void handleEvent(Event event) {
        jid.setWidth(contactList.getClientArea().width-10);
      } });
    contactList.addListener(SWT.KeyDown,new Listener() {
      public void handleEvent(Event event) {
        switch(event.keyCode) {
        case SWT.DEL:
          TreeItem[] items = contactList.getSelection();
          if(items == null || items.length < 1) return;
          RosterEntry entry = (RosterEntry)items[0].getData("entry");
          if(entry != null)
            getActiveAccount().xmpp.removeContact(entry,contactList.getShell());
          break;
        }
      }
    });
//    TreeColumn games = new TreeColumn(contactList,SWT.CENTER);
//    games.setText("Games");
    // jid.pack();
//    jid.setWidth(200);
//    games.pack();
   
   
    contactList.setHeaderVisible(false);
   
    createMenu(getShell());
    ContactListMouseListener mouseListener = new ContactListMouseListener();
    contactList.addMouseListener(mouseListener);
    contactList.addMouseMoveListener(mouseListener);
   
   
    IPreferenceStore store = GOIMPlugin.getDefault().getPreferenceStore();
    final IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent event) {
        setColorsFromStore();
      } };
    store.addPropertyChangeListener(propertyChangeListener);
    contactList.addListener(SWT.Dispose,new Listener() {
      public void handleEvent(Event event) {
        IPreferenceStore store = GOIMPlugin.getDefault().getPreferenceStore();
        store.removePropertyChangeListener(propertyChangeListener);
      }
    });
    setColorsFromStore();
  }
  public class ContactListMouseListener implements MouseMoveListener, MouseListener {
    Point dragLastPoint;
    //Point relativeMousePosition;
    Rectangle shellPosition;

    public void mouseDoubleClick(MouseEvent e) {
      TreeItem[] items = contactList.getSelection();
      if(items.length < 1) return;
      TreeItem item = items[0];
      RosterEntry entry = (RosterEntry)item.getData("entry");
      GOIMAccount account = (GOIMAccount)item.getData("account");
      if(entry == null) return;
      account.chatWindowExtensionManager.openChatWindow(entry.getUser(),true);
    }

    public void mouseDown(MouseEvent e) {
      if(e.button == 1) {
        Point point = new Point(e.x,e.y);
//        TreeItem item = contactList.getItem(point);
//        if(item == null) {
          dragLastPoint = point;
          shellPosition = contactList.getShell().getBounds();
//        }
//      } else if((e.stateMask & SWT.BUTTON3) != 0 ||
//          (e.stateMask & SWT.BUTTON2) != 0) {
      } else if(e.button == 3 || e.button == 2) {
        TreeItem item = contactList.getItem(new Point(e.x,e.y));
//        TreeItem[] items = contactList.getSelection();
        if(item == null) {
          contactList.setSelection(new TreeItem[]{});
          contextMenu.setVisible(true);
          return;
        }
        contactList.setSelection(new TreeItem[]{item});
//        TreeItem item = items[0];
        setActiveAccount((GOIMAccount)item.getData("account"));
        if(getActiveAccount() == null) {
          contextMenu.setVisible(true);
          return;
        }
        RosterEntry entry = (RosterEntry) item.getData("entry");
        GOIMAccount account = (GOIMAccount) item.getData("account");
        if(entry == null)
          contextMenu.setVisible(true);
        else {
          entryMenu.open(account,entry,null);
        }
      }
    }
    public void mouseUp(MouseEvent e) {
      dragLastPoint = null;
    }
    public void mouseMove(MouseEvent e) {
      if(dragLastPoint != null) {
        Shell shell = contactList.getShell();
        //Rectangle bounds = shell.getBounds();
        //System.out.println("Moved: " + (e.x - dragLastPoint.x) + " / " + (e.y - dragLastPoint.y));
        shellPosition.x += e.x - dragLastPoint.x;
        shellPosition.y += e.y - dragLastPoint.y;
        shell.setBounds(shellPosition);
//        shell.setBounds(e.x,e.y,bounds.width,bounds.height);
//        shell.setBounds(bounds.x + (e.x - dragLastPoint.x),
//            bounds.y + (e.y - dragLastPoint.y),
//            bounds.width,bounds.height);
//        dragLastPoint.x = e.x;
//        dragLastPoint.y = e.y;
      } else {
        TreeItem item = contactList.getItem(new Point(e.x,e.y));
        if(item != null) {
          GOIMAccount account = (GOIMAccount)item.getData("account");
          RosterEntry entry = (RosterEntry)item.getData("entry");
          if(entry != null) {
            String toolTipText = getToolTipTextForEntry(account,entry);
            if(!toolTipText.equals(contactList.getToolTipText())) {
              contactList.setToolTipText(toolTipText);
            }
          } else
            contactList.setToolTipText(null);
        } else {
          contactList.setToolTipText(null);
        }
      }
    }

  }
 
  public String getToolTipTextForEntry(GOIMAccount account, RosterEntry entry) {
    StringBuffer buf = new StringBuffer();
    if (entry.getName() != null) {
      buf.append(entry.getName()).append("\n");
    }
    buf.append('[').append(entry.getUser()).append("]\nSubscription: ");
    buf.append(entry.getType().toString());
    Roster roster = account.xmpp.getRoster();
    if (roster != null) {
      Iterator i = roster.getPresences(entry.getUser());
      if (i == null)
        buf.append("\n\nOffline");
      else
        while (i.hasNext()) {
          Presence p = (Presence) i.next();
          buf.append("\n\nPresence: ").append(p.getFrom()).append(
              "\n").append(p.getType().toString()).append(" ")
              .append(p.getMode().toString()).append("\n");
          if (p.getStatus() != null)
            buf.append(p.getStatus());
        }
    }
    return buf.toString();
  }

  public void initWithAccountList(GOIMAccountList list) {
    GOIMPlugin.getDefault().registerContactListOfAllAccounts(container);
    init();
    this.accountList = list;
    loadList();
    layout(true);
  }

  public void initWithAccount(final GOIMAccount account) {
    GOIMPlugin.getDefault().registerContactList(account, container);
    init();
    this.account = account;
    Composite presenceComposite = new Group(this, SWT.SHADOW_NONE);
    presenceComposite.setLayoutData(new GridData(SWT.FILL,SWT.CENTER,true,false));
    GridLayout presenceCompositeLayout = new GridLayout(3, false);
//    presenceCompositeLayout.marginHeight = 0;
//    presenceCompositeLayout.marginWidth = 0;
    presenceComposite.setLayout(presenceCompositeLayout);
    final Label presence = new Label(presenceComposite, SWT.NULL);
    GridData presenceData = new GridData(SWT.CENTER,SWT.CENTER,false,false);
    presence.setLayoutData(presenceData);
    final Label presenceLabel = new Label(presenceComposite, SWT.NULL);
    presenceLabel.setLayoutData(new GridData(SWT.FILL,SWT.CENTER,true,false));
    Button presenceButton = new Button(presenceComposite, SWT.ARROW | SWT.DOWN);
    presence.setImage(GOIMIcons.getImageForPresence(null, account.xmpp
        .getOwnPresence()));
    presenceLabel.setText(GOIMIcons.getShowTextForPresence(account.xmpp
        .getOwnPresence()));
    presenceLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
        false));
    setActiveAccount(account);
    SpheneListener<StatusChangedEvent> ownPresenceChangedListener = new SpheneListener<StatusChangedEvent>() {
      public void handleEvent(StatusChangedEvent arg0) {
        presence.getDisplay().asyncExec(new Runnable() {
          public void run() {
            Presence p = account.xmpp.getOwnPresence();
            presence.setImage(GOIMIcons
                .getImageForPresence(null, p));
            presenceLabel.setText(GOIMIcons
                .getShowTextForPresence(account.xmpp
                    .getOwnPresence()));
          }
        });
      }
    };
    account.xmpp.ownPresenceChanged.addListener(ownPresenceChangedListener);
    presence.setMenu(contextMenu);
    presenceLabel.setMenu(contextMenu);
    Listener showMenuListener;
    presence.addListener(SWT.MouseDown, showMenuListener = new Listener() {
      public void handleEvent(Event event) {
        contextMenu.setVisible(true);
      }
    });
    presenceLabel.addListener(SWT.MouseDown, showMenuListener);
    presenceButton.addListener(SWT.MouseDown, showMenuListener);
    presenceComposite.addListener(SWT.MouseDown, showMenuListener);
    addAccount(account);
    layout(true);
    this.addListener(SWT.Dispose, RemoveListener.getRemoveListener(
        account.xmpp.ownPresenceChanged, ownPresenceChangedListener));
  }

  public void initWithout() {
    wasInit = true;
    this.setLayout(new RowLayout(SWT.VERTICAL));
    Button button = new Button(this, SWT.PUSH);
    button.setText("Manage all Accounts");
    Listener listener = new Listener() {
      public void handleEvent(Event event) {
        GOIMAccount account = (GOIMAccount) event.widget
            .getData("account");
        if (account == null)
          container.initWithAccountList(GOIMPlugin
              .getPreferenceObject(GOIMAccountList.class));
        else
          container.initWithAccount(account);
      }
    };
    button.addListener(SWT.Selection, listener);
    for (GOIMAccount account : GOIMPlugin
        .getPreferenceObject(GOIMAccountList.class)) {
      button = new Button(this, SWT.PUSH);
      button.setText("Manage Account: " + account.name);
      button.setData("account", account);
      button.addListener(SWT.Selection, listener);
    }
  }

  public void loadList() {
    if (accountList == null)
      return;
    for (GOIMAccount acc : accountList) {
      addAccount(acc);
    }
  }

  public void addAccount(final GOIMAccount account) {
    // account.defaultWorkbenchPage =
    // PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
    final TreeItem accItem = (accountList == null ? null : new TreeItem(contactList, SWT.NULL));
    if (accountList != null) {
      accItem.setData("account", account);
      accItem.setText(account.name);
      accItem.setImage(GOIMIcons.getImageForPresence(null, account.xmpp
          .getOwnPresence()));
    }
    SpheneListener<StatusChangedEvent> ownPresenceChangedListener;
    account.xmpp.ownPresenceChanged
        .addListener(ownPresenceChangedListener = new SpheneListener<StatusChangedEvent>() {
          public void handleEvent(final StatusChangedEvent event) {
            getDisplay().asyncExec(new Runnable() {
              public void run() {
                if(event.previousPresence == null) {
                  Map<String, TreeGroup> groupTreeItems = getGroupTreeItems(accItem);
                  for(TreeGroup treeGroup : groupTreeItems.values())
                    if(treeGroup.item != null)
                      treeGroup.item.dispose();
                  groupTreeItems.clear();
                }
                Presence p = account.xmpp.getOwnPresence();
                if(accItem != null) {
                  accItem.setImage(GOIMIcons
                      .getImageForPresence(null,p));
                }
                for (TreeItem item : (accItem == null ? contactList.getItems() : accItem.getItems())) {
                  if (item.getData("entryjid") != null
                      && item.getData("entryjid").equals(
                          account.jid + "/"
                              + account.resource)) {
                    updatePresenceOfItem(item, null, p);
                  }
                }
              }
            });
          }
        });
    GOIMRosterListener rosterListener = new GOIMRosterListener() {
      public void rosterModified() {
        getDisplay().asyncExec(new Runnable() {
          public void run() {
            updateAccountRoster(account);
//            System.out.println("RosterModified (asyncExec): "
//                + Thread.currentThread().toString());
          }
        });
      }

      public void presenceChanged(final String jid) {
        getDisplay().asyncExec(new Runnable() {
          public void run() {
            // updateAccountRoster(account);
//            System.out.println("presenceChanged: " + jid);
            String id = StringUtils.parseBareAddress(jid);
            RosterEntry entry = account.xmpp.getRoster().getEntry(
                id);
            if (entry == null)
              entry = account.xmpp.getRoster().getEntry(jid);
            updateRosterEntry(account,
                getGroupTreeItems(getAccountTreeItem(account)),
                entry);
          }
        });
      }
    };
    account.xmpp.rosterListener.addListener(rosterListener);
    updateAccountRoster(account);
    this.addListener(SWT.Dispose, RemoveListener.getRemoveListener(
        account.xmpp.ownPresenceChanged, ownPresenceChangedListener));
    this.addListener(SWT.Dispose, RemoveListener.getRemoveListener(
        account.xmpp.rosterListener, rosterListener));
  }

  protected TreeItem getAccountTreeItem(GOIMAccount account) {
    if (accountList == null)
      return null;
    for (TreeItem item : contactList.getItems())
      if (item.getData("account") == account)
        return item;
    return null;
  }

  @SuppressWarnings("unchecked")
  protected Map<String, TreeGroup> getGroupTreeItems(TreeItem item) {
    Map<String, TreeGroup> groupTreeItems = null;
    if (item == null) {
      groupTreeItems = (Map<String, TreeGroup>) contactList
          .getData("groupTreeItems");
      if (groupTreeItems == null)
        contactList.setData("groupTreeItems",
            groupTreeItems = new HashMap<String, TreeGroup>());
    } else {
      groupTreeItems = (Map<String, TreeGroup>) item
          .getData("groupTreeItems");
      if (groupTreeItems == null)
        item.setData("groupTreeItems",
            groupTreeItems = new HashMap<String, TreeGroup>());
    }
    return groupTreeItems;
  }

  protected void updateAccountRoster(final GOIMAccount account) {
    Roster roster = account.xmpp.getRoster();
    TreeItem item = null;
    boolean createOwnPresence = false;
    if (managesAllAccounts()) {
      item = getAccountTreeItem(account);
      // item.removeAll();
      createOwnPresence = item.getItemCount() < 1;
    } else {
      createOwnPresence = contactList.getItemCount() < 1;
      // contactList.removeAll();
    }
    Map<String, TreeGroup> groupTreeItems = getGroupTreeItems(item);
    if (createOwnPresence) {
      final TreeItem ownPresence = (item == null ? new TreeItem(
          contactList, SWT.NULL) : new TreeItem(item, SWT.NULL));
      ownPresence.setText(account.getUsername() + " (Self)");
      // ownPresence.setImage(GOIMIcons.getImageForPresence(null,account.xmpp.getOwnPresence()));
      ownPresence.setData("account",account);
      ownPresence.setData("entryjid", account.jid + "/"
          + account.resource);
      updatePresenceOfItem(ownPresence, null, account.xmpp
          .getOwnPresence());
      SpheneListener<SpheneEvent> changeListener;
      account.changeListenerList
          .addListener(changeListener = new SpheneListener<SpheneEvent>() {
            public void handleEvent(SpheneEvent event) {
              ownPresence.setText(account.getUsername()
                  + " (Self)");
              ownPresence.setData("entryjid", account.jid + "/"
                  + account.resource);
            }
          });
      ownPresence.addListener(SWT.Dispose, RemoveListener
          .getRemoveListener(account.changeListenerList,
              changeListener));
    }
    if (roster == null)
      return;

    List<String> displayedGroups = new ArrayList<String>(groupTreeItems.keySet());
    Iterator groups = roster.getGroups();
    while (groups.hasNext()) {
      RosterGroup group = (RosterGroup) groups.next();
      updateRosterGroup(account, roster, groupTreeItems, item, group, group
          .getName());
      displayedGroups.remove(group.getName());
    }
    updateRosterGroup(account, roster, groupTreeItems, item, null, NO_GROUP_NAME);
    displayedGroups.remove(NO_GROUP_NAME);
    updateRosterGroup(account, roster, groupTreeItems, item, null,
        NO_GROUP_COMPONENT);
    displayedGroups.remove(NO_GROUP_COMPONENT);
   
    for(String remainingGroup : displayedGroups)
      if(groupTreeItems.get(remainingGroup).updateSelf(roster,null))
        groupTreeItems.remove(remainingGroup);
    // createRosterGroup(account, contactList, item, null, roster
    // .getUnfiledEntries());
  }

  protected void updateRosterGroup(GOIMAccount account, Roster roster,
      Map<String, TreeGroup> groupTreeItems, TreeItem parent,
      RosterGroup group, String name) {
    // String name = (group == null ? NO_GROUP_NAME :group.getName());
    TreeGroup treeGroup = groupTreeItems.get(name);
    if (treeGroup == null) {
      // TreeItem item = (parent == null ? new
      // TreeItem(contactList,SWT.NULL) :
      // new TreeItem(parent,SWT.NULL));
      // item.setText(name);
      treeGroup = new TreeGroup(account, parent, group, name);
      if(!treeGroup.updateSelf(roster,group))
        groupTreeItems.put(name, treeGroup);
    } else {
      if(treeGroup.updateSelf(roster,group))
        groupTreeItems.remove(name);
    }
  }

  protected void updateRosterEntry(GOIMAccount account,
      Map<String, TreeGroup> groupTreeItems, RosterEntry entry) {
    Iterator i = entry.getGroups();
    int count = 0;
    while (i.hasNext()) {
      RosterGroup group = (RosterGroup) i.next();
      insertRosterEntryIntoGroup(account, groupTreeItems, entry, group
          .getName());
      count++;
    }
    if (count == 0)
      if (entry.getUser().indexOf('@') > -1 && !entry.getUser().equals(GOIMAccount.STATSCONTACTJID))
        insertRosterEntryIntoGroup(account, groupTreeItems, entry,
            NO_GROUP_NAME);
      else
        insertRosterEntryIntoGroup(account, groupTreeItems, entry,
            NO_GROUP_COMPONENT);
  }

  protected void insertRosterEntryIntoGroup(GOIMAccount account,
      Map<String, TreeGroup> groupTreeItems, RosterEntry entry,
      String groupName) {
    TreeGroup treeGroup = groupTreeItems.get(groupName);
    if(treeGroup == null)
      throw new RuntimeException("treeGroup is null ?! " + groupName);
    treeGroup.update(new TreeEntry(account, treeGroup, entry));
  }

  public int getPresenceValue(Presence p) {
    if (p == null)
      return -1;
    if (p.getType() == Presence.Type.UNAVAILABLE)
      return -1;
    if (p.getType() != Presence.Type.AVAILABLE)
      return -2;
    if (p.getMode() == Presence.Mode.INVISIBLE)
      return 0;
    if (p.getMode() == Presence.Mode.AVAILABLE)
      return 10;
    if (p.getMode() == Presence.Mode.CHAT)
      return 9;
    if (p.getMode() == Presence.Mode.AWAY)
      return 8;
    if (p.getMode() == Presence.Mode.EXTENDED_AWAY)
      return 7;
    if (p.getMode() == Presence.Mode.DO_NOT_DISTURB)
      return 6;
    return 0;
  }

  protected String getRosterLabel(RosterEntry entry) {
    return entry.getName() == null ? entry.getUser() : entry.getName();
  }

  public boolean managesAllAccounts() {
    return accountList != null;
  }

  public GOIMAccount getAccount() {
    return getActiveAccount();
  }

  public void closeContactList() {
    if (accountList != null)
      GOIMPlugin.getDefault().unregisterContactListOfAllAccounts(
          container);
    else
      GOIMPlugin.getDefault().unregisterContactList(account, container);
  }

  private void updatePresenceOfItem(TreeItem item, RosterEntry entry,
      Presence presence) {
    item.setImage(GOIMIcons.getImageForPresence(entry, presence));
    int extensions = 0;
    TreeEditor editor = getEditor(item, false);
    if (presence != null) {
      Iterator iterator = presence.getExtensions();
      if (editor != null)
        if (editor.getEditor() == null) {
          System.err.println("editor.getEditor() is null !! "
              + this.getClass().toString());
        } else {
          for (Control control : ((Composite) editor.getEditor())
              .getChildren())
            control.dispose();
        }
      while (iterator.hasNext()) {
        PacketExtension ex = (PacketExtension) iterator.next();
        if (ex instanceof IGameExtension) {
          extensions++;
          if (editor == null)
            editor = getEditor(item, true);
          final IGameExtension gameEx = (IGameExtension) ex;
          final GOIMGameItem game = gameEx.getGameItem();
          final GameExtensionProxy proxy = gameEx.getGameExtension();
          // final InetSocketAddress target = gameEx.getDestination();
          Label label = new Label((Composite) editor.getEditor(),
              SWT.NULL);
          // Button label = new
          // Button((Composite)editor.getEditor(),SWT.PUSH);
          try {
            label.setImage(proxy.getIcon().createImage());
          } catch(SWTError error) {
            error.printStackTrace();
            // Since we still want the user to know about the error .. i throw an exception for now ..
            throw new RuntimeException("An SWT Error occurred during setting game icon",error);
          }
          label.setToolTipText(proxy.getTooltipText(game, gameEx));
          System.out.println("Addin label with image: " + proxy.icon
              + ": " + label.computeSize(-1, -1));
          // label.setEnabled(true);
          // label.setText("Muh");
          label.setLayoutData(new RowData(16,16));
          if (game != null) {
            label.addListener(SWT.MouseUp, new Listener() {

              public void handleEvent(Event event) {
                //System.out.println("mouseup");
                proxy.execute(game, gameEx);
              }
            });
            label.setFocus();
          } else {
            label.setToolTipText("Game not installed: "
                + label.getToolTipText());
          }
          ((Composite) editor.getEditor()).layout(true, true);
          ((Composite) editor.getEditor()).pack(true);
          editor.minimumWidth = editor.getEditor().getSize().x;
          editor.layout();
        }
      }
    }
    if (extensions < 1 && editor != null) {
      editor.getEditor().dispose();
      editor.dispose();
      item.setData("editor",null);
    }
    contactList.redraw();
  }

  public TreeEditor getEditor(TreeItem item, boolean create) {
    TreeEditor editor = (TreeEditor) item.getData("editor");
    if (create && (editor == null || editor.getEditor() == null)) {
      if (item.getParent() == null)
        System.err.println("tree is null ?!");
      item.setData("editor", editor = new TreeEditor(item.getParent()));
      final Composite c = new Composite(contactList, SWT.NULL);
      c.setBackground(contactList.getBackground());
      RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL);
      rowLayout.marginBottom = rowLayout.marginLeft = rowLayout.marginTop = rowLayout.marginRight = 0;
      rowLayout.spacing = 2;
      rowLayout.wrap = rowLayout.pack = false;
      rowLayout.pack = true;
      c.setLayout(rowLayout);
      editor.setEditor(c, item, 0);
      editor.grabHorizontal = false;editor.horizontalAlignment = SWT.RIGHT;
      final TreeEditor _editor = editor;
      item.addListener(SWT.Dispose, new Listener() {
        public void handleEvent(Event event) {
          if (!c.isDisposed()) {
            c.dispose();
          }
          if (_editor.getEditor() == null)
            System.out.println("TreeEditor already disposed ?!");
          else
            _editor.dispose();
        }
      });
    }
    return editor;
  }

  @Override
  public void setHideOfflineContacts(boolean hideOfflineContacts) {
    hideOffline = hideOfflineContacts;//hideOfflineContacts.getSelection();
    if(accountList != null)
      for(GOIMAccount acc : accountList)
        updateAccountRoster(acc);
    else
      updateAccountRoster(account);
  }

  @Override
  public boolean getHideOfflineContacts() {
    return hideOffline;
  }

}
TOP

Related Classes of net.sphene.goim.rcp.simpleui.SimpleContactList$ContactListMouseListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.