/* * Copyright (c) 2003,2009 Declarative Engineering LLC. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Declarative Engineering LLC * verson 1 which accompanies this distribution, and is available at * http://declarativeengineering.com/legal/DE_Developer_License_v1.txt */ package com.foundation.tcv.swt.server; import com.common.util.*; import com.common.util.optimized.*; import com.foundation.tcv.swt.*; import com.foundation.tcv.view.*; /* * Extends the CollectionComponent to provide indexing of the collection items. * This is an abstract class that is meant to reduce the end control complexity. */ public abstract class IndexedCollectionComponent extends CollectionComponent implements IIndexedCollectionComponent { /** * IndexedCollectionComponent constructor. * @param parent The parent container. * @param name The name of the component. */ public IndexedCollectionComponent(Container parent, String name, int style) { super(parent, name, style); }//IndexedCollectionComponent()// /** * Refreshes the item data. * @param item The collection item whose data needs refreshing. */ protected void internalViewRefreshItem(Object item) { RowObject rowObject = getRowObject(item); if(rowObject != null) { sendMessage(MESSAGE_SET_ITEM, new Object[] {new Integer(rowObject.objectId), getItemData(rowObject)}); }//if// else { //Do nothing. It may simply be a stray event (fired before we removed event listeners, but received after they were removed).// }//else// }//internalViewRefreshItem()// /* (non-Javadoc) * @see com.foundation.view.swt.CollectionComponent#internalViewRefreshCollection(com.common.util.ICollection, com.common.util.ICollection) */ protected void internalViewRefreshCollection(ICollection newCollection, ICollection oldCollection) { //Remove all listeners, mappings, and metadata.// itemAllRemoved(); if((newCollection != null) && (newCollection.getSize() > 0)) { IIterator iterator = newCollection.iterator(); // Object[] itemData = newCollection.getSize() > 0 ? new Object[newCollection.getSize()] : null; // Object[] hiddenData = newCollection.getSize() > 0 && getHiddenDataCount() > 0 ? new Object[newCollection.getSize()][getHiddenDataCount()] : null; // int[] objectIds = itemData != null ? new int[itemData.length] : null; int index = 0; //Get the array of strings representing the list contents.// while(iterator.hasNext()) { Object value = iterator.next(); itemAdded(value, index++, true); // RowObject rowObject = itemAdded(value, index, false); // // //Add the item mappings without notifying the client.// // if(rowObject.isFirstReference()) { // //Add the value to the item array.// // itemData[index] = getItemData(rowObject); // // if(hiddenData != null) { // hiddenData[index] = getItemHiddenData(value); // }//if// // }//if// // // objectIds[index] = rowObject.objectId; // // index++; }//while// //Set the collection contents.// // sendMessage(MESSAGE_SET_ITEMS, new Object[] {itemData, objectIds, hiddenData}); //If the selection was invalid previously then refresh the selection since it may no longer be invalid.// if(isSelectionInvalid) { internalViewRefreshSelection(); }//if// }//if// else { //Remove all collection contents.// sendMessage(MESSAGE_REMOVE_ALL, null); }//else// }//internalViewRefreshCollection()// /* (non-Javadoc) * @see com.foundation.view.swt.CollectionComponent#internalViewRefreshSelection(java.lang.Object) */ protected void internalViewRefreshSelection(Object selectedItem) { //Send selection index or indices to the remote control where it will determine whether the selection should be changed.// //Again: What to do about impossible selections?// Object currentSelection = getModelSelection(); int objectId; if(currentSelection != null) { RowObject rowObject = getRowObject(currentSelection); objectId = rowObject == null ? INVALID_OBJECT_ID : rowObject.objectId; if((objectId == -1) && (getAllowUserItems())) { sendMessage(MESSAGE_SET_SELECTION, currentSelection.toString()); }//if// else if(objectId == -1) { isSelectionInvalid = true; //Note: We are no longer invalidating the model selection since this may be a valid action given that the selection may be attached to an attribute that is also attached to another component.// sendMessage(MESSAGE_SET_SELECTION, null); }//else if// else { isSelectionInvalid = false; //Send selection.// sendMessage(MESSAGE_SET_SELECTION, new int[] {objectId}); }//else// }//if// else { //No selection.// sendMessage(MESSAGE_SET_SELECTION, null); }//else// }//internalViewRefreshSelection()// /* (non-Javadoc) * @see com.foundation.view.swt.CollectionComponent#internalViewRefreshSelections(com.common.util.ICollection, com.common.util.ICollection) */ protected void internalViewRefreshSelections(ICollection newSelections, ICollection oldSelections) { //Collect indexes and collections of indexes for each selection and send all to control. Control will then apply necessary changes.// //How to deal with impossible selections? We could send back a deselect message?// if(newSelections != null) { IntArray selectionIndices = new IntArray(newSelections.getSize()); IIterator modelSelectionIterator = null; modelSelectionIterator = newSelections.iterator(); //Apply differences between the selection collection and the control selection. Also remove all impossible selections.// while(modelSelectionIterator.hasNext()) { Object modelSelection = modelSelectionIterator.next(); RowObject rowObject = getRowObject(modelSelection); if(rowObject == null) { //An invalid selection because the selection is not in the collection of displayed values.// modelSelectionIterator.remove(); }//if// else { selectionIndices.add(rowObject.objectId); }//else// }//while// sendMessage(MESSAGE_SET_SELECTION, selectionIndices.toArray()); }//if// else { //Remove all selections.// sendMessage(MESSAGE_REMOVE_SELECTIONS, null); }//else// }//internalViewRefreshSelections()// /* (non-Javadoc) * @see com.foundation.tcv.swt.server.CollectionComponent#registerItem(com.foundation.tcv.swt.server.RowObject) */ protected void registerItem(RowObject rowObject) { super.registerItem(rowObject); }//registerItem()// /* (non-Javadoc) * @see com.foundation.tcv.swt.server.CollectionComponent#unregisterItem(com.foundation.tcv.swt.server.RowObject) */ protected void unregisterItem(RowObject rowObject) { super.unregisterItem(rowObject); }//unregisterItem()// /* (non-Javadoc) * @see com.foundation.tcv.swt.server.CollectionComponent#unregisterItems() */ protected void unregisterItems() { super.unregisterItems(); }//unregisterItems()// /* (non-Javadoc) * @see com.foundation.view.swt.CollectionComponent#itemSorted(int[]) */ protected void itemSorted(int[] mapping) { //TODO: Re-order the indicies in the control and rebuild the mappings.// }//itemSorted()// /* (non-Javadoc) * @see com.foundation.view.swt.CollectionComponent#selectionAdded(java.lang.Object) */ protected void selectionAdded(Object value) { RowObject rowObject = getRowObject(value); if(rowObject != null) { sendMessage(MESSAGE_ADD_SELECTION, new int[] {rowObject.objectId}); }//if// }//selectionAdded()// /* (non-Javadoc) * @see com.foundation.view.swt.CollectionComponent#selectionRemoved(java.lang.Object) */ protected void selectionRemoved(Object value) { RowObject rowObject = getRowObject(value); if(rowObject != null) { sendMessage(MESSAGE_REMOVE_SELECTION, new int[] {rowObject.objectId}); }//if// }//selectionRemoved()// /* (non-Javadoc) * @see com.foundation.view.swt.CollectionComponent#selectionAllRemoved() */ protected void selectionAllRemoved() { sendMessage(MESSAGE_REMOVE_SELECTIONS, null); }//selectionAllRemoved()// /* (non-Javadoc) * @see com.foundation.tcv.view.IViewComponent#processMessage(com.foundation.tcv.model.ViewMessage) */ public Object processMessage(ViewMessage viewMessage) { Object retVal = null; switch(viewMessage.getMessageNumber()) { case MESSAGE_VIEW_SYNCHRONIZE_SELECTION: { //Receive the selection information from the client.// Object messageData = viewMessage.getMessageData(); if(getAllowMultiSelection()) { int[] selectionObjectIds = (int[]) messageData; ICollection modelSelections = getModelSelections(); //Prevent the selection additions from causing a feedback loop.// suspendSelectionHooks = true; try { if(modelSelections != null) { Object[] controlSelectionObjects = new Object[selectionObjectIds.length]; boolean[] markedControlSelections = new boolean[controlSelectionObjects.length]; IIterator modelSelectionIterator = modelSelections.iterator(); LiteList removed = new LiteList(modelSelections.getSize()); LiteList added = new LiteList(selectionObjectIds.length); for(int index = 0; index < selectionObjectIds.length; index++) { controlSelectionObjects[index] = getRowObject(selectionObjectIds[index]).value; markedControlSelections[index] = false; }//for// //Add selected items to the selection collection.// while(modelSelectionIterator.hasNext()) { Object modelSelection = modelSelectionIterator.next(); boolean found = false; for(int index = 0; (!found) && (index < markedControlSelections.length); index++) { if(!markedControlSelections[index]) { if(controlSelectionObjects[index] == modelSelection) { markedControlSelections[index] = true; found = true; }//if// }//if// }//for// if(!found) { removed.add(modelSelection); }//if// }//while// for(int index = 0; index < markedControlSelections.length; index++) { if(!markedControlSelections[index]) { added.add(controlSelectionObjects[index]); }//if// }//for// modelSelections.replaceAll(removed, added); }//if// }//try// finally { suspendSelectionHooks = false; }//finally// }//if// else { int selectedObjectId = (messageData != null) && !(messageData instanceof String) ? ((Integer) messageData).intValue() : -1; if(selectedObjectId == -1) { if((getAllowUserItems()) && (((String) messageData).length() > 0)) { //TODO: If the user wants numbers only, should the conversion occur on the server or the client?// //Set the custom value.// setModelSelection((String) messageData); }//if// else { setModelSelection(null); }//else// }//if// else { setModelSelection(getRowObject(selectedObjectId).value); }//else// }//else// if(getAutoValidate()) { postSynchronizeValidate(); }//if// break; }//case// default: { retVal = super.processMessage(viewMessage); }//default// }//switch// return retVal; }//processMessage()// }//IndexedCollectionComponent//