pjs/grendel/widgets/MultiSelectionManager.java

303 строки
8.4 KiB
Java

/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is the Grendel mail/news client.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1997
* Netscape Communications Corporation. All Rights Reserved.
*
* Created: Will Scullin <scullin@netscape.com>, 26 Aug 1997.
*
* Contributors: Jeff Galyan <talisman@anamorphic.com>
*/
package grendel.widgets;
import java.awt.event.MouseEvent;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.event.ChangeEvent;
public class MultiSelectionManager implements SelectionManager {
Vector fSelection = new Vector();
Vector fListeners = new Vector();
/**
* Removes all objects from the selection
*/
public synchronized void clearSelection() {
if (!fSelection.isEmpty()) {
Object removedArray[] = new Object[fSelection.size()];
Object nullArray[] = new Object[0];
Enumeration removedEnum = fSelection.elements();
int idx = 0;
while (removedEnum.hasMoreElements()) {
removedArray[idx] = removedEnum.nextElement();
idx++;
}
fSelection.setSize(0);
notifySelectionChanged(nullArray, removedArray);
}
}
/**
* Sets the selection to be a single object
*/
public synchronized void setSelection(Object aObject) {
if (fSelection.size() != 1 || !fSelection.contains(aObject)) {
Object removedArray[];
Object addedArray[];
if (fSelection.contains(aObject)) {
removedArray = new Object[fSelection.size() - 1];
addedArray = new Object[0];
} else {
removedArray = new Object[fSelection.size()];
addedArray = new Object[1];
addedArray[0] = aObject;
}
Enumeration removedEnum = fSelection.elements();
int idx = 0;
while (removedEnum.hasMoreElements()) {
Object element = removedEnum.nextElement();
if (!element.equals(aObject)) {
removedArray[idx] = element;
idx++;
}
}
fSelection.setSize(0);
fSelection.addElement(aObject);
notifySelectionChanged(addedArray, removedArray);
}
}
public synchronized void setSelection(Enumeration aObjects) {
Vector addedVector = new Vector();
Vector removedVector = new Vector();
Vector noopVector = new Vector();
// See which items are being removed
while (aObjects.hasMoreElements()) {
Object object = aObjects.nextElement();
if (fSelection.removeElement(object)) {
addedVector.insertElementAt(object, addedVector.size());
} else {
noopVector.insertElementAt(object, noopVector.size());
}
}
// See which items were not being set
Enumeration removedEnum = fSelection.elements();
while (removedEnum.hasMoreElements()) {
Object element = removedEnum.nextElement();
removedVector.insertElementAt(element, removedVector.size());
}
// Remove everything
fSelection.setSize(0);
// Set everything
int i;
for (i = 0; i < addedVector.size(); i++) {
fSelection.insertElementAt(addedVector.elementAt(i), fSelection.size());
}
for (i = 0; i < noopVector.size(); i++) {
fSelection.insertElementAt(noopVector.elementAt(i), fSelection.size());
}
// If there were deltas, notify
if (addedVector.size() > 0 || removedVector.size() > 0) {
Object removedArray[] = new Object[removedVector.size()];
Object addedArray[] = new Object[addedVector.size()];
removedVector.copyInto(removedArray);
addedVector.copyInto(addedArray);
notifySelectionChanged(addedArray, removedArray);
}
}
/**
* Adds a single object to the selection. Notifies
* listeners if the selection changes.
*/
public synchronized void addSelection(Object aObject) {
if (!fSelection.contains(aObject)) {
fSelection.insertElementAt(aObject, fSelection.size());
Object addedArray[] = new Object[1];
Object removedArray[] = new Object[0];
addedArray[0] = aObject;
notifySelectionChanged(addedArray, removedArray);
}
}
/**
* NYI
*/
public synchronized void addSelection(Enumeration aObjects) {
Vector addedVector = new Vector();
while (aObjects.hasMoreElements()) {
Object object = aObjects.nextElement();
if (!fSelection.contains(object)) {
fSelection.insertElementAt(object, fSelection.size());
addedVector.insertElementAt(object, addedVector.size());
}
}
if (addedVector.size() > 0) {
Object addedArray[] = new Object[addedVector.size()];
Object removedArray[] = new Object[0];
addedVector.copyInto(addedArray);
notifySelectionChanged(addedArray, removedArray);
}
}
/**
* Removes a single object from the selection. Notifies
* listeners if the selection changes.
*/
public synchronized void removeSelection(Object aObject) {
if (fSelection.removeElement(aObject)) {
Object addedArray[] = new Object[0];
Object removedArray[] = new Object[1];
removedArray[0] = aObject;
notifySelectionChanged(addedArray, removedArray);
}
}
public synchronized void removeSelection(Enumeration aObjects) {
Vector removedVector = new Vector();
while (aObjects.hasMoreElements()) {
Object object = aObjects.nextElement();
if (fSelection.removeElement(object)) {
removedVector.insertElementAt(object, removedVector.size());
}
}
if (removedVector.size() > 0) {
Object removedArray[] = new Object[removedVector.size()];
Object addedArray[] = new Object[0];
removedVector.copyInto(removedArray);
notifySelectionChanged(addedArray, removedArray);
}
}
/**
* Returns true if the object is in the selection.
*/
public synchronized boolean isSelected(Object aObject) {
return fSelection.contains(aObject);
}
/**
* Returns the number of objects in the selection
*/
public synchronized int getSelectionCount() {
return fSelection.size();
}
/**
* Returns an enumeration of all objects in the selection
*/
public synchronized Enumeration getSelection() {
return fSelection.elements();
}
/**
* Passed on to listeners
*/
public void doubleClickSelection(MouseEvent aEvent) {
notifySelectionDoubleClicked(aEvent);
}
/**
* Passed on to listeners
*/
public void contextClickSelection(MouseEvent aEvent) {
notifySelectionContextClicked(aEvent);
}
/**
* Passed on to listeners
*/
public void dragSelection(MouseEvent aEvent) {
notifySelectionDragged(aEvent);
}
/**
* Adds a selection listener
*/
public synchronized void addSelectionListener(SelectionListener aListener) {
fListeners.addElement(aListener);
}
/**
* Removes a selection listener
*/
public synchronized void removeSelectionListener(SelectionListener aListener) {
fListeners.removeElement(aListener);
}
void notifySelectionChanged(Object aAdded[], Object aRemoved[]) {
Enumeration listeners = fListeners.elements();
SelectionEvent event = new SelectionEvent(this, aAdded, aRemoved);
while (listeners.hasMoreElements()) {
((SelectionListener) listeners.nextElement()).selectionChanged(event);
}
}
void notifySelectionDoubleClicked(MouseEvent aEvent) {
Enumeration listeners = fListeners.elements();
while (listeners.hasMoreElements()) {
((SelectionListener) listeners.nextElement()).selectionDoubleClicked(aEvent);
}
}
void notifySelectionContextClicked(MouseEvent aEvent) {
Enumeration listeners = fListeners.elements();
while (listeners.hasMoreElements()) {
((SelectionListener) listeners.nextElement()).selectionContextClicked(aEvent);
}
}
void notifySelectionDragged(MouseEvent aEvent) {
Enumeration listeners = fListeners.elements();
while (listeners.hasMoreElements()) {
((SelectionListener) listeners.nextElement()).selectionDragged(aEvent);
}
}
}