diff -r 14dc2103a631 -r ed1c9f64298a trace/tracebuilder/com.nokia.tracebuilder.view/src/com/nokia/tracebuilder/view/ListWrapper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trace/tracebuilder/com.nokia.tracebuilder.view/src/com/nokia/tracebuilder/view/ListWrapper.java Wed Jun 23 14:35:40 2010 +0300 @@ -0,0 +1,417 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +* Base class for wrappers containing a list of other wrappers +* +*/ +package com.nokia.tracebuilder.view; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.nokia.tracebuilder.engine.TraceBuilderConfiguration; + +/** + * Base class for wrappers containing a list of other wrappers + * + */ +abstract class ListWrapper extends WrapperBase implements Iterable { + + /** + * Number of visible elements in the tree viewer + */ + private final static int TREE_VIEW_VISIBLE_ELEMENTS = 100; // CodForChk_Dis_Magic + + /** + * The full list of wrappers. + */ + private ArrayList fullList = new ArrayList(); + + /** + * Sublist which is shown in view + */ + private ArrayList subList = new ArrayList(); + + /** + * Sub-list start index + */ + private int subListStartIndex = 0; + + /** + * Navigator if there are more children that can be shown in view at a time + */ + private ListNavigator navigator; + + /** + * Constructor takes the parent as parameter. + * + * @param parent + * the parent wrapper + * @param updater + * the update notifier + */ + ListWrapper(WrapperBase parent, WrapperUpdater updater) { + super(parent, updater); + } + + /* + * (non-Javadoc) + * + * @see com.nokia.tracebuilder.view.WrapperBase#getChildren() + */ + @Override + Object[] getChildren() { + return subList.toArray(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Iterable#iterator() + */ + public Iterator iterator() { + return fullList.iterator(); + } + + /** + * Gets the wrappers that are currently visible + * + * @return the wrappers + */ + Iterator getVisibleWrappers() { + return subList.iterator(); + } + + /* + * (non-Javadoc) + * + * @see com.nokia.tracebuilder.view.WrapperBase#hasChildren() + */ + @Override + boolean hasChildren() { + return !fullList.isEmpty(); + } + + /* + * (non-Javadoc) + * + * @see com.nokia.tracebuilder.view.WrapperBase#delete() + */ + @Override + void delete() { + for (WrapperBase wrapper : fullList) { + wrapper.delete(); + } + fullList.clear(); + subList.clear(); + } + + /** + * Adds a child to this model + * + * @param child + */ + void add(WrapperBase child) { + fullList.add(child); + if (getSubListSize() < TREE_VIEW_VISIBLE_ELEMENTS) { + subList.add(child); + } else { + showSubList(fullList.size() - TREE_VIEW_VISIBLE_ELEMENTS); + } + } + + /** + * Removes the child from the list but does not call delete + * + * @param child + * the child to be removed + */ + void hide(WrapperBase child) { + fullList.remove(child); + subList.remove(child); + } + + /** + * Checks if the wrapper is in this list + * + * @param wrapper + * the wrapper + * @return true if the wrapper exists, false otherwise + */ + boolean contains(WrapperBase wrapper) { + return fullList.contains(wrapper); + } + + /** + * Resets and removes the child + * + * @param child + * the child to be removed + */ + void remove(WrapperBase child) { + child.delete(); + int index = fullList.indexOf(child); + if (index >= 0) { + fullList.remove(index); + // If the item was removed prior to sublist, the sublist index is + // changed. If item is in sublist, it is removed from it and a + // replacement is added to the sub-list + if (index < subListStartIndex) { + subListStartIndex--; + } else if (index < subListStartIndex + getSubListSize()) { + removeFromSubList(child); + } + } + } + + /** + * Removes the element from the visible list and replaces it with a new one + * + * @param child + * the child element to be removed + */ + private void removeFromSubList(WrapperBase child) { + subList.remove(child); + if (fullList.size() > getSubListSize()) { + int end = subListStartIndex + getSubListSize(); + // If the sub-list is at the end, previous element is added to it + // Otherwise the next element is added prior to the navigator + if (end == fullList.size()) { + subList.add(0, fullList.get(subListStartIndex - 1)); + subListStartIndex--; + } else { + subList.add(getSubListSize() - 1, fullList.get(end)); + } + } else if (!subList.isEmpty()) { + // If the sub-list covers the entire list, the navigator is removed + // if it exists + if (subList.get(subList.size() - 1) == navigator) { + subList.remove(subList.size() - 1); + } + } + } + + /** + * Removes and calls delete on all children + */ + void clear() { + for (WrapperBase wrapper : fullList) { + wrapper.delete(); + } + fullList.clear(); + subList.clear(); + } + + /* + * (non-Javadoc) + * + * @see com.nokia.tracebuilder.view.WrapperBase#setInView(boolean) + */ + @Override + void setInView(boolean flag) { + super.setInView(flag); + // When an element is hidden, all its children are also hidden + // When element is shown, its children are not necessarily shown + if (!flag) { + setChildrenInView(false); + } else { + restoreChildrenIntoView(); + } + } + + /** + * Sets the shown in view flag for child elements that are currently shown + * in view + * + * @param isInView + * the shown in view flag + */ + void setChildrenInView(boolean isInView) { + for (WrapperBase wrapper : subList) { + wrapper.setInView(isInView); + } + } + + /** + * Sets the shown in view flag for child elements that have the + * restoreIntoView flag + */ + void restoreChildrenIntoView() { + if (isRestoredIntoView()) { + super.setInView(true); + super.setRestoreIntoView(false); + } + for (WrapperBase wrapper : subList) { + if (wrapper instanceof ListWrapper) { + ((ListWrapper) wrapper).restoreChildrenIntoView(); + } else { + if (wrapper.isRestoredIntoView()) { + wrapper.setRestoreIntoView(false); + wrapper.setInView(true); + } + } + } + } + + /* + * (non-Javadoc) + * + * @see com.nokia.tracebuilder.view.WrapperBase#setRestoreIntoView(boolean) + */ + @Override + void setRestoreIntoView(boolean flag) { + super.setRestoreIntoView(flag); + for (WrapperBase wrapper : subList) { + wrapper.setRestoreIntoView(flag); + } + } + + /** + * Updates the sub-list in view + * + * @param start + * the start of sub-list + */ + private void showSubList(int start) { + subList.clear(); + if (start < 0) { + start = 0; + } else if (start > fullList.size() - TREE_VIEW_VISIBLE_ELEMENTS) { + start = fullList.size() - TREE_VIEW_VISIBLE_ELEMENTS; + } + subListStartIndex = start; + int end = subListStartIndex + TREE_VIEW_VISIBLE_ELEMENTS; + for (int i = 0; i < fullList.size(); i++) { + if (i >= start && i < end) { + subList.add(fullList.get(i)); + } else { + fullList.get(i).setInView(false); + } + } + if (navigator == null) { + createNavigator(); + } + navigator + .setIndex(subListStartIndex, getSubListSize(), fullList.size()); + subList.add(navigator); + } + + /** + * Creates the navigator + */ + private void createNavigator() { + navigator = new ListNavigator(this, getUpdater()); + } + + /* + * (non-Javadoc) + * + * @see com.nokia.tracebuilder.view.WrapperBase# dumpToSystemOut(int, + * com.nokia.tracebuilder.view.TraceLabelProvider) + */ + @Override + void dumpToSystemOut(int indentLevel, TraceLabelProvider provider) { + if (TraceBuilderConfiguration.TRACE_VIEW_STATE) { + super.dumpToSystemOut(indentLevel, provider); + indentLevel++; + // This uses the full list -> Verifies that items do not contain + // visible flag unless they actually are in the sub-list and visible + for (WrapperBase wrapper : fullList) { + if (wrapper.isInView()) { + wrapper.dumpToSystemOut(indentLevel, provider); + } + } + } + } + + /** + * Shows the next elements in the list + */ + void showNext() { + int start = subListStartIndex + TREE_VIEW_VISIBLE_ELEMENTS; + showSubList(start); + // showSubList does not change the in-view flag to true, since it is + // used also with hidden lists + int size = getSubListSize(); + for (int i = 0; i < size; i++) { + subList.get(i).setInView(true); + } + getUpdater().update(this); + } + + /** + * Shows the previous elements in the list + */ + void showPrevious() { + int start = subListStartIndex - TREE_VIEW_VISIBLE_ELEMENTS; + showSubList(start); + // showSubList does not change the in-view flag to true, since it is + // used also with hidden lists + int size = getSubListSize(); + for (int i = 0; i < size; i++) { + subList.get(i).setInView(true); + } + getUpdater().update(this); + } + + /** + * Gets the size of the sub-list + * + * @return the size + */ + private int getSubListSize() { + int size = subList.size(); + if (size > 0) { + if (subList.get(size - 1) == navigator) { + size--; + } + } + return size; + } + + /** + * Moves a child wrapper to the sub-list that is shown in view. Note that + * this does not expand the tree to actually show the child + * + * @param child + * the child to be revealed + * @return the wrapper that needs to be updated + */ + WrapperBase moveChildToView(WrapperBase child) { + WrapperBase retval = null; + if (!child.isInView()) { + int index = fullList.indexOf(child); + if (index < subListStartIndex + || index >= subListStartIndex + getSubListSize()) { + showSubList(index); + // If the list changes, this wrapper needs to be updated + retval = this; + } + } + WrapperBase parent = getParent(); + if (parent instanceof ListWrapper) { + // Delegates the call also to parent lists in case this list is not + // currently in the view. If a parent list changes, the return value + // is changed so it gets updated instead of this list + WrapperBase updatedParent = ((ListWrapper) parent) + .moveChildToView(this); + if (updatedParent != null) { + retval = updatedParent; + } + } + return retval; + } + +}