contactlist.java.svn-base

来自「开源项目openfire的完整源程序」· SVN-BASE 代码 · 共 1,679 行 · 第 1/5 页

SVN-BASE
1,679
字号
/**
 * $Revision: $
 * $Date: $
 *
 * Copyright (C) 2006 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Lesser Public License (LGPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.spark.ui;

import org.jivesoftware.MainWindowListener;
import org.jivesoftware.Spark;
import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.packet.StreamError;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.SharedGroupManager;
import org.jivesoftware.smackx.packet.LastActivity;
import org.jivesoftware.spark.ChatManager;
import org.jivesoftware.spark.PresenceManager;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.Workspace;
import org.jivesoftware.spark.component.InputDialog;
import org.jivesoftware.spark.component.RolloverButton;
import org.jivesoftware.spark.component.VerticalFlowLayout;
import org.jivesoftware.spark.plugin.ContextMenuListener;
import org.jivesoftware.spark.plugin.Plugin;
import org.jivesoftware.spark.ui.status.StatusBar;
import org.jivesoftware.spark.util.ModelUtil;
import org.jivesoftware.spark.util.ResourceUtils;
import org.jivesoftware.spark.util.TaskEngine;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.profile.VCardManager;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public final class ContactList extends JPanel implements ActionListener, ContactGroupListener, Plugin, RosterListener, ConnectionListener {
    private JPanel mainPanel = new JPanel();
    private JScrollPane contactListScrollPane;
    private final List<ContactGroup> groupList = new ArrayList<ContactGroup>();
    private final RolloverButton addingGroupButton;

    private ContactItem activeItem;
    private ContactGroup activeGroup;
    private ContactGroup unfiledGroup = new ContactGroup("Unfiled");


    // Create Menus
    private JMenuItem addContactMenu;
    private JMenuItem addContactGroupMenu;
    private JMenuItem removeContactFromGroupMenu;
    private JMenuItem chatMenu;
    private JMenuItem renameMenu;

    private ContactGroup offlineGroup;
    private final JCheckBoxMenuItem showHideMenu = new JCheckBoxMenuItem();
    private final JCheckBoxMenuItem showOfflineGroupMenu = new JCheckBoxMenuItem();

    private List sharedGroups = new ArrayList();

    private final List<ContextMenuListener> contextListeners = new ArrayList<ContextMenuListener>();

    private List initialPresences = new ArrayList();
    private final Timer presenceTimer = new Timer();
    private final List dndListeners = new ArrayList();
    private final List<ContactListListener> contactListListeners = new ArrayList<ContactListListener>();
    private Properties props;
    private File propertiesFile;

    private LocalPreferences localPreferences;


    public static final String RETRY_PANEL = "RETRY_PANEL";


    private RetryPanel retryPanel;

    private Workspace workspace;

    public static KeyEvent activeKeyEvent;

    /**
     * Creates a new instance of ContactList.
     */
    public ContactList() {
        // Load Local Preferences
        localPreferences = SettingsManager.getLocalPreferences();

        offlineGroup = new ContactGroup("Offline Group");

        JToolBar toolbar = new JToolBar();
        toolbar.setFloatable(false);
        addContactMenu = new JMenuItem(Res.getString("menuitem.add.contact"), SparkRes.getImageIcon(SparkRes.USER1_ADD_16x16));
        addContactGroupMenu = new JMenuItem(Res.getString("menuitem.add.contact.group"), SparkRes.getImageIcon(SparkRes.SMALL_ADD_IMAGE));

        removeContactFromGroupMenu = new JMenuItem(Res.getString("menuitem.remove.from.group"), SparkRes.getImageIcon(SparkRes.SMALL_DELETE));
        chatMenu = new JMenuItem(Res.getString("menuitem.start.a.chat"), SparkRes.getImageIcon(SparkRes.SMALL_MESSAGE_IMAGE));
        renameMenu = new JMenuItem(Res.getString("menuitem.rename"), SparkRes.getImageIcon(SparkRes.DESKTOP_IMAGE));

        addContactMenu.addActionListener(this);
        removeContactFromGroupMenu.addActionListener(this);
        chatMenu.addActionListener(this);
        renameMenu.addActionListener(this);


        setLayout(new BorderLayout());

        addingGroupButton = new RolloverButton(SparkRes.getImageIcon(SparkRes.ADD_CONTACT_IMAGE));

        RolloverButton groupChatButton = new RolloverButton(SparkRes.getImageIcon(SparkRes.JOIN_GROUPCHAT_IMAGE));
        toolbar.add(addingGroupButton);
        toolbar.add(groupChatButton);

        addingGroupButton.addActionListener(this);

        mainPanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 0, true, false));
        mainPanel.setBackground((Color)UIManager.get("List.background"));
        contactListScrollPane = new JScrollPane(mainPanel);
        contactListScrollPane.setAutoscrolls(true);

        contactListScrollPane.setBorder(BorderFactory.createEmptyBorder());
        contactListScrollPane.getVerticalScrollBar().setBlockIncrement(50);
        contactListScrollPane.getVerticalScrollBar().setUnitIncrement(20);

        retryPanel = new RetryPanel();

        workspace = SparkManager.getWorkspace();

        workspace.getCardPanel().add(RETRY_PANEL, retryPanel);


        add(contactListScrollPane, BorderLayout.CENTER);

        // Load Properties file
        props = new Properties();
        // Save to properties file.
        propertiesFile = new File(Spark.getSparkUserHome() + "/groups.properties");
        try {
            props.load(new FileInputStream(propertiesFile));
        }
        catch (IOException e) {
            // File does not exist.
        }

        // Add ActionListener(s) to menus
        addContactGroup(unfiledGroup);
        addContactGroup(offlineGroup);

        showHideMenu.setSelected(false);

        // Add KeyMappings
        SparkManager.getMainWindow().getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("control F"), "searchContacts");
        SparkManager.getMainWindow().getRootPane().getActionMap().put("searchContacts", new AbstractAction("searchContacts") {
            public void actionPerformed(ActionEvent evt) {
                SparkManager.getUserManager().searchContacts("", SparkManager.getMainWindow());
            }
        });

        // Handle Command-F on Macs
        SparkManager.getMainWindow().getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), "appleStrokeF");
        SparkManager.getMainWindow().getRootPane().getActionMap().put("appleStrokeF", new AbstractAction("appleStrokeF") {
            public void actionPerformed(ActionEvent evt) {
                SparkManager.getUserManager().searchContacts("", SparkManager.getMainWindow());
            }
        });

        // Save state on shutdown.
        SparkManager.getMainWindow().addMainWindowListener(new MainWindowListener() {
            public void shutdown() {
                saveState();
            }

            public void mainWindowActivated() {

            }

            public void mainWindowDeactivated() {

            }
        });

        SparkManager.getConnection().addConnectionListener(this);

        // Get command panel and add View Online/Offline, Add Contact
//        StatusBar statusBar = SparkManager.getWorkspace().getStatusBar();
        final JPanel commandPanel = SparkManager.getWorkspace().getCommandPanel();


        final RolloverButton addContactButton = new RolloverButton(SparkRes.getImageIcon(SparkRes.USER1_ADD_16x16));
        commandPanel.add(addContactButton);
        addContactButton.setToolTipText(Res.getString("message.add.a.contact"));
        addContactButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                new RosterDialog().showRosterDialog();
            }
        });


    }

    /**
     * Updates the users presence.
     *
     * @param presence the user to update.
     */
    private synchronized void updateUserPresence(Presence presence) throws Exception {
        if (presence.getError() != null) {
            // We ignore this.
            return;
        }

        final Roster roster = SparkManager.getConnection().getRoster();

        final String bareJID = StringUtils.parseBareAddress(presence.getFrom());

        RosterEntry entry = roster.getEntry(bareJID);
        boolean isPending = entry != null && (entry.getType() == RosterPacket.ItemType.none || entry.getType() == RosterPacket.ItemType.from)
            && RosterPacket.ItemStatus.SUBSCRIPTION_PENDING == entry.getStatus();

        // If online, check to see if they are in the offline group.
        // If so, remove from offline group and add to all groups they
        // belong to.

        if (presence.getType() == Presence.Type.available && offlineGroup.getContactItemByJID(bareJID) != null || (presence.getFrom().indexOf("workgroup.") != -1)) {
            changeOfflineToOnline(bareJID, entry, presence);
        }
        else if (presence.getType() == Presence.Type.available) {
            updateContactItemsPresence(presence, entry, bareJID);
        }
        else if (presence.getType() == Presence.Type.unavailable && !isPending) {
            // If not available, move to offline group.
            Presence rosterPresence = PresenceManager.getPresence(bareJID);
            if (!rosterPresence.isAvailable()) {
                moveToOfflineGroup(presence, bareJID);
            }
            else {
                updateContactItemsPresence(rosterPresence, entry, bareJID);
            }
        }

    }

    /**
     * Updates the presence of one individual based on their JID.
     *
     * @param presence the users presence.
     * @param bareJID  the bare jid of the user.
     */
    private void updateContactItemsPresence(Presence presence, RosterEntry entry, String bareJID) {
        final Iterator groupIterator = groupList.iterator();
        while (groupIterator.hasNext()) {
            ContactGroup group = (ContactGroup)groupIterator.next();
            ContactItem item = group.getContactItemByJID(bareJID);
            if (item != null) {
                if (group == offlineGroup) {
                    changeOfflineToOnline(bareJID, entry, presence);
                    continue;
                }
                item.setPresence(presence);
                group.fireContactGroupUpdated();
            }
        }
    }

    /**
     * Moves every <code>ContactItem</code> associated with the given bareJID to offline.
     *
     * @param presence the users presence.
     * @param bareJID  the bareJID of the user.
     */
    private void moveToOfflineGroup(final Presence presence, final String bareJID) {
        final Iterator groupIterator = new ArrayList(groupList).iterator();
        while (groupIterator.hasNext()) {
            final ContactGroup group = (ContactGroup)groupIterator.next();
            final ContactItem item = group.getContactItemByJID(bareJID);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?