package org.geogebra.common.main;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeSet;
import org.geogebra.common.euclidian.EuclidianViewInterfaceCommon;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.Path;
import org.geogebra.common.kernel.Region;
import org.geogebra.common.kernel.geos.GProperty;
import org.geogebra.common.kernel.geos.GeoCurveCartesian;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoFunction;
import org.geogebra.common.kernel.geos.GeoFunctionNVar;
import org.geogebra.common.kernel.geos.GeoInputBox;
import org.geogebra.common.kernel.geos.GeoList;
import org.geogebra.common.kernel.geos.GeoNumberValue;
import org.geogebra.common.kernel.geos.GeoNumeric;
import org.geogebra.common.kernel.geos.GeoPolyLine;
import org.geogebra.common.kernel.geos.GeoPolygon;
import org.geogebra.common.kernel.implicit.GeoImplicit;
import org.geogebra.common.kernel.kernelND.GeoConicND;
import org.geogebra.common.kernel.kernelND.GeoCoordSys;
import org.geogebra.common.kernel.kernelND.GeoDirectionND;
import org.geogebra.common.kernel.kernelND.GeoElementND;
import org.geogebra.common.kernel.kernelND.GeoImplicitSurfaceND;
import org.geogebra.common.kernel.kernelND.GeoLineND;
import org.geogebra.common.kernel.kernelND.GeoPlaneND;
import org.geogebra.common.kernel.kernelND.GeoPointND;
import org.geogebra.common.kernel.kernelND.GeoPolyhedronInterface;
import org.geogebra.common.kernel.kernelND.GeoQuadric3DLimitedInterface;
import org.geogebra.common.kernel.kernelND.GeoQuadricND;
import org.geogebra.common.kernel.kernelND.GeoSegmentND;
import org.geogebra.common.kernel.kernelND.GeoVectorND;
import org.geogebra.common.plugin.EventType;
import org.geogebra.common.plugin.GeoClass;
import org.geogebra.common.util.debug.Log;
/**
* Keeps lists of selected geos (global, per type)
*
*/
public class SelectionManager {
/** list of selected geos */
protected final ArrayList<GeoElement> selectedGeos = new ArrayList<GeoElement>();
private final Kernel kernel;
private final UpdateSelection listener;
private ArrayList<GeoElementSelectionListener> selectionListeners;
private final ArrayList<GeoPointND> selectedPoints = new ArrayList<GeoPointND>();
private final ArrayList<GeoNumeric> selectedNumbers = new ArrayList<GeoNumeric>();
private final ArrayList<GeoNumberValue> selectedNumberValues = new ArrayList<GeoNumberValue>();
private final ArrayList<GeoLineND> selectedLines = new ArrayList<GeoLineND>();
private final ArrayList<GeoDirectionND> selectedDirections = new ArrayList<GeoDirectionND>();
private final ArrayList<GeoSegmentND> selectedSegments = new ArrayList<GeoSegmentND>();
private final ArrayList<Region> selectedRegions = new ArrayList<Region>();
private final ArrayList<Path> selectedPaths = new ArrayList<Path>();
private final ArrayList<GeoConicND> selectedConicsND = new ArrayList<GeoConicND>();
private final ArrayList<GeoImplicit> selectedImplicitpoly = new ArrayList<GeoImplicit>();
private final ArrayList<GeoImplicitSurfaceND> selectedImplicitSurface = new ArrayList<GeoImplicitSurfaceND>();
private final ArrayList<GeoFunction> selectedFunctions = new ArrayList<GeoFunction>();
private final ArrayList<GeoFunctionNVar> selectedFunctionsNVar = new ArrayList<GeoFunctionNVar>();
private final ArrayList<GeoCurveCartesian> selectedCurves = new ArrayList<GeoCurveCartesian>();
private final ArrayList<GeoVectorND> selectedVectors = new ArrayList<GeoVectorND>();
private final ArrayList<GeoPolygon> selectedPolygons = new ArrayList<GeoPolygon>();
private final ArrayList<GeoPolyLine> selectedPolyLines = new ArrayList<GeoPolyLine>();
private final ArrayList<GeoElement> selectedGeosEuclidian = new ArrayList<GeoElement>();
private final ArrayList<GeoList> selectedLists = new ArrayList<GeoList>();
private final ArrayList<GeoCoordSys> selectedCS2D = new ArrayList<GeoCoordSys>();
private final ArrayList<GeoQuadricND> selectedQuadric = new ArrayList<GeoQuadricND>();
private final ArrayList<GeoQuadric3DLimitedInterface> selectedQuadricLimited = new ArrayList<GeoQuadric3DLimitedInterface>();
private final ArrayList<GeoPolyhedronInterface> selectedPolyhedron = new ArrayList<GeoPolyhedronInterface>();
private ArrayList<GeoPlaneND> selectedPlane = new ArrayList<GeoPlaneND>();
private boolean geoToggled = false;
private ArrayList<GeoElement> tempMoveGeoList;
/**
* @param kernel
* kernel
* @param listener
* listener to be notified on selection updates
*/
public SelectionManager(Kernel kernel, UpdateSelection listener) {
this.kernel = kernel;
this.listener = listener;
selectionListeners = new ArrayList<GeoElementSelectionListener>();
}
/**
* Clears selection and selects given geos.
*
* @param geos
* geos
*/
final public void setSelectedGeos(ArrayList<GeoElement> geos) {
setSelectedGeos(geos, true);
}
/**
* Clears selection and selects given geos.
*
* @param geos
* geos
* @param updateSelection
* says if selection has to be updated
*/
final public void setSelectedGeos(ArrayList<GeoElement> geos,
boolean updateSelection) {
// special case -- happens when we set the same selection on mouse down
// and mouse up; we don't want too many events
if (geos != null && geos.size() == 1 && selectedGeos.size() == 1
&& geos.get(0) == selectedGeos.get(0)) {
return;
}
clearSelectedGeos(false);
if (geos != null) {
for (int i = 0; i < geos.size(); i++) {
GeoElement geo = geos.get(i);
addSelectedGeo(geo, false, false);
}
}
kernel.notifyRepaint();
if (updateSelection) {
updateSelection();
}
}
/**
* Clears selection and repaints all views
*/
final public void clearSelectedGeos() {
clearSelectedGeos(true);
}
/**
* Clear selection
*
* @param repaint
* whether all views need repainting afterwards
*/
public void clearSelectedGeos(boolean repaint) {
clearSelectedGeos(repaint, repaint);
}
/**
* Clear selection
*
* @param repaint
* whether all views need repainting afterwards
* @param updateSelection
* call (or not) updateSelection()
*/
public void clearSelectedGeos(boolean repaint, boolean updateSelection) {
int size = selectedGeos.size();
if (size > 0) {
for (int i = 0; i < size; i++) {
GeoElement geo = selectedGeos.get(i);
boolean oldSelected = geo.isSelected();
geo.setSelected(false);
if (geo.getKernel().getApplication()
.has(Feature.DYNAMIC_STYLEBAR)
&& oldSelected) {
notifyListeners(geo);
}
}
selectedGeos.clear();
if (repaint) {
kernel.notifyRepaint();
}
if (updateSelection) {
updateSelection();
}
kernel.getApplication().getEventDispatcher()
.dispatchEvent(EventType.DESELECT, null);
}
}
private void notifyListeners(GeoElement geo) {
for (GeoElementSelectionListener sl : getSelectionListeners()) {
if (sl != null) {
sl.geoElementSelected(geo, false);
}
}
}
/**
* Removes geo from selection
*
* @param geo
* geo to be removed
* @param repaint
* whether views must be repainted after
* @param updateSelection
* whether update selection needs to be done after
*/
final public void removeSelectedGeo(GeoElement geo, boolean repaint,
boolean updateSelection) {
if (geo == null) {
return;
}
kernel.getApplication().getEventDispatcher()
.dispatchEvent(EventType.DESELECT, geo);
if (selectedGeos.remove(geo)) {
// update only if selectedGeos contained geo
geo.setSelected(false);
if (updateSelection) {
updateSelection();
}
if (repaint) {
kernel.notifyRepaint();
}
}
}
/**
* @return list of selected geos
*/
public final ArrayList<GeoElement> getSelectedGeos() {
return selectedGeos;
}
/**
* Adds geo to selection
*
* @param geoND
* geo to be added to selection
* @param repaint
* whether repaint is needed
* @param updateSelection
* whether selection update is needed
*/
public final void addSelectedGeo(GeoElementND geoND, boolean repaint,
boolean updateSelection) {
if ((geoND == null) || selectedGeos.contains(geoND)) {
return;
}
GeoElement geo = geoND.toGeoElement();
dispatchSelected(geo);
selectedGeos.add(geo);
geo.setSelected(true);
if (repaint) {
kernel.notifyRepaint();
}
if (updateSelection) {
updateSelection();
}
// notify all registered selection listeners
for (GeoElementSelectionListener sl : getSelectionListeners()) {
if (sl != null) {
sl.geoElementSelected(geo, true);
}
}
}
private void dispatchSelected(GeoElement geo) {
kernel.getApplication().getEventDispatcher()
.dispatchEvent(EventType.SELECT, geo);
}
private void setGeoToggled(boolean flag) {
geoToggled = flag;
}
/**
* Resets the flag for selection change, see {@link #isGeoToggled()}
*/
public void resetGeoToggled() {
setGeoToggled(false);
}
/**
* @return the flag for selection change since last object creation (using
* tool)
*/
public boolean isGeoToggled() {
return geoToggled;
}
/**
* Michael Borcherds 2008-03-03
*
* @return -1 if nothing selected return -2 if objects from more than one
* layer selected return layer number if objects from exactly one
* layer are selected
*/
public int getSelectedLayer() {
if (getSelectedGeos().size() == 0)
{
return -1; // return -1 if nothing selected
}
int layer = getSelectedGeos().get(0).getLayer();
for (int i = 1; i < getSelectedGeos().size(); i++) {
GeoElement geo = getSelectedGeos().get(i);
if (geo.getLayer() != layer)
{
return -2; // return -2 if more than one layer selected
}
}
return layer;
}
/**
* Selects all geos in given layer
*
* @param layer
* 0 - 9 for particular layer, -1 for all layers (Michael
* Borcherds, 2008-03-03)
*/
final public void selectAll(int layer) {
clearSelectedGeos(false);
Iterator<GeoElement> it = kernel.getConstruction().getGeoSetLabelOrder()
.iterator();
while (it.hasNext()) {
GeoElement geo = it.next();
if ((layer == -1) || (geo.getLayer() == layer)) {
addSelectedGeo(geo, false, false);
}
}
kernel.notifyRepaint();
updateSelection();
}
/**
* Select objects that were not selected so far and vice versa.
*/
final public void invertSelection() {
Iterator<GeoElement> it = kernel.getConstruction().getGeoSetLabelOrder()
.iterator();
while (it.hasNext()) {
GeoElement geo = it.next();
if (selectedGeos.contains(geo)) {
removeSelectedGeo(geo, false, false);
} else {
addSelectedGeo(geo, false, false);
}
}
kernel.notifyRepaint();
updateSelection();
}
/**
* Select all predecessors of all selected geos
*/
final public void selectAllPredecessors() {
for (int i = 0; i < selectedGeos.size(); i++) {
GeoElement geo = selectedGeos.get(i);
TreeSet<GeoElement> tree = geo.getAllPredecessors();
Iterator<GeoElement> it2 = tree.iterator();
while (it2.hasNext()) {
geo = it2.next();
if (geo.isLabelSet()) {
addSelectedGeo(geo, false, false);
}
}
}
kernel.notifyRepaint();
updateSelection();
}
/**
* @return whether one or more of selected geos have predecessors
*/
final public boolean hasPredecessors() {
for (int i = 0; i < selectedGeos.size(); i++) {
GeoElement geo = selectedGeos.get(i);
TreeSet<GeoElement> tree = geo.getAllPredecessors();
Iterator<GeoElement> it2 = tree.iterator();
while (it2.hasNext()) {
geo = it2.next();
if (geo.isLabelSet()) {
return true;
}
}
}
return false;
}
/**
* Selects descendants of all visible objects
*/
final public void selectAllDescendants() {
for (int i = 0; i < selectedGeos.size(); i++) {
GeoElement geo = selectedGeos.get(i);
TreeSet<GeoElement> tree = geo.getAllChildren();
Iterator<GeoElement> it2 = tree.iterator();
while (it2.hasNext()) {
geo = it2.next();
if (geo.isLabelSet()) {
addSelectedGeo(geo, false, false);
}
}
}
kernel.notifyRepaint();
updateSelection();
}
/**
* @return whether one or more of selected geos have descendants
*/
final public boolean hasDescendants() {
for (int i = 0; i < selectedGeos.size(); i++) {
GeoElement geo = selectedGeos.get(i);
TreeSet<GeoElement> tree = geo.getAllChildren();
Iterator<GeoElement> it2 = tree.iterator();
while (it2.hasNext()) {
geo = it2.next();
if (geo.isLabelSet()) {
return true;
}
}
}
return false;
}
/**
* Invert visibility of all selected objects
*/
final public void showHideSelection() {
// GeoElements may have other GeoElements as subelements,
// and this means that the subelements should be tackled first,
// in order to prevent them being tackled twice, and this way
// negating the negative, doing nothing and other complications
for (int i = 0; i < selectedGeos.size(); i++) {
GeoElement geo = selectedGeos.get(i);
if (!geo.isGeoPolygon() && !geo.isGeoPolyhedron()
&& !geo.isGeoPolyLine()
&& geo.getGeoClassType() != GeoClass.QUADRIC_LIMITED
&& geo.getGeoClassType() != GeoClass.NET) {
geo.setEuclidianVisible(!geo.isEuclidianVisible());
geo.updateVisualStyle(GProperty.VISIBLE);
}
}
for (int i = 0; i < selectedGeos.size(); i++) {
GeoElement geo = selectedGeos.get(i);
if (geo.isGeoPolygon() || geo.isGeoPolyLine()
|| geo.getGeoClassType() == GeoClass.QUADRIC_LIMITED) {
geo.setEuclidianVisible(!geo.isEuclidianVisible());
geo.updateVisualStyle(GProperty.VISIBLE);
}
}
for (int i = 0; i < selectedGeos.size(); i++) {
GeoElement geo = selectedGeos.get(i);
if (geo.isGeoPolyhedron()
|| geo.getGeoClassType() == GeoClass.NET) {
geo.setEuclidianVisible(!geo.isEuclidianVisible());
geo.updateVisualStyle(GProperty.VISIBLE);
}
}
kernel.notifyRepaint();
updateSelection();
}
/**
* Invert visibility of labels of all selected objects
*/
final public void showHideSelectionLabels() {
for (int i = 0; i < selectedGeos.size(); i++) {
GeoElement geo = selectedGeos.get(i);
geo.setLabelVisible(!geo.isLabelVisible());
geo.updateVisualStyle(GProperty.LABEL_STYLE);
}
kernel.notifyRepaint();
updateSelection();
}
/**
* @param geo
* geo
* @return whether given geo belongs to selection
*/
final public boolean containsSelectedGeo(GeoElement geo) {
return selectedGeos.contains(geo);
}
/**
* @param geos
* geos
* @return whether given geos belongs to selection
*/
final public boolean containsSelectedGeos(ArrayList<GeoElement> geos) {
return selectedGeos.containsAll(geos);
}
/**
* Removes geo from selection
*
* @param geo
* geo to be removed
*/
final public void removeSelectedGeo(GeoElement geo) {
removeSelectedGeo(geo, true, true);
}
/**
* @return number of selected geos
*/
public final int selectedGeosSize() {
return selectedGeos.size();
}
/**
* Selects the first geo in the construction. Previous selected geos are
* unselected (used e.g. for xAxis).
*
* @return first geo or null
*/
final public GeoElement setFirstGeoSelectedForPropertiesView() {
GeoElement geo = kernel.getFirstGeo();
if (geo == null) {
return null;
}
clearSelectedGeos(false);
selectedGeos.add(geo);
geo.setSelected(true);
kernel.notifyRepaint();
listener.updateSelection(false);
return geo;
}
/**
* Adds given geo to selection
*
* @param geo
* geo
*/
public final void addSelectedGeo(GeoElementND geo) {
addSelectedGeo(geo, true, true);
}
/**
* Adds geos to selection
*
* @param geos
* geos to be added to selection
* @param repaint
* whether repaint is needed
*/
public final void addSelectedGeos(ArrayList<GeoElement> geos,
boolean repaint) {
selectedGeos.addAll(geos);
for (int i = 0; i < geos.size(); i++) {
geos.get(i).setSelected(true);
dispatchSelected(geos.get(i));
}
if (repaint) {
kernel.notifyRepaint();
}
updateSelection();
}
/**
* Removes or adds given geo to selection
*
* @param geo
* geo to be added / removed
* @param repaint
* whether we want to repaint afterwards
*/
final public void toggleSelectedGeo(GeoElement geo, boolean repaint) {
if (geo == null) {
return;
}
setGeoToggled(true);
boolean contains = selectedGeos.contains(geo);
if (contains) {
selectedGeos.remove(geo);
kernel.getApplication().getEventDispatcher()
.dispatchEvent(EventType.DESELECT, geo);
geo.setSelected(false);
} else {
selectedGeos.add(geo);
dispatchSelected(geo);
geo.setSelected(true);
}
if (repaint) {
kernel.notifyRepaint();
}
updateSelection();
}
/**
* Removes or adds given geo to selection and repaints views
*
* @param geo
* geo to be added / removed
*/
final public void toggleSelectedGeo(GeoElement geo) {
toggleSelectedGeo(geo, true);
}
/**
* Select geo next to the selected one in construction order. If none is
* selected before, first geo is selected.
*
* @param ev
* view that should get focus after (if we did not selct
* textfield)
* @param cycle
* whether to jump back to 0 from the last one
*
* @return whether the operation is successful (e.g. in case of no cycle)
*/
final public boolean selectNextGeo(EuclidianViewInterfaceCommon ev,
boolean cycle) {
TreeSet<GeoElement> tree = kernel.getConstruction()
.getGeoSetLabelOrder();
tree = new TreeSet<GeoElement>(tree);
TreeSet<GeoElement> copy = new TreeSet<GeoElement>(tree);
Iterator<GeoElement> it = copy.iterator();
// remove geos that don't have isSelectionAllowed()==true
// or are not visible in the view
while (it.hasNext()) {
GeoElement geo = it.next();
if (!geo.isSelectionAllowed(ev) || !geo.isEuclidianVisible()
|| !geo.isVisibleInView(ev.getViewID())) {
tree.remove(geo);
}
}
it = tree.iterator();
// none selected, select first geo
if (selectedGeos.size() == 0) {
if (it.hasNext()) {
addSelectedGeo(it.next());
}
return false;
}
GeoElement selGeo = null;
if (selectedGeos.size() != 1) {
if (cycle) {
return false;
}
GeoElement actual = null;
// in case of no cycle, it also means that this
// was called from Web, in Graphics views, so
// in this case, it's better to change selection
// to remove all geos except the first one that
// is also part of this view, and continue
// as if it were always the case...
Iterator<GeoElement> itt = tree.iterator();
while (itt.hasNext()) {
actual = itt.next();
if (selectedGeos.contains(actual)) {// && (selGeo == null) //
// redundant
selGeo = actual;
break;
}
}
if (selGeo == null) {
// no selected geo in this view,
// maybe better to handle this as if
// there were no geo selected!
// but also clear selected geos!
itt = selectedGeos.iterator();
while (itt.hasNext()) {
// does something more than simple clear
removeSelectedGeo(itt.next(), false, true);
}
if (it.hasNext()) {
addSelectedGeo(it.next());
}
return false;
// old behaviour
// selGeo = selectedGeos.get(0);
}
// remove every GeoElement from the selection
// that is not "selGeo"
itt = selectedGeos.iterator();
while (itt.hasNext()) {
// does something more than simple clear
removeSelectedGeo(itt.next(), false, true);
}
// and put selGeo back
addSelectedGeo(selGeo);
// make sure it is fresh, for a bug when points
// A and C are selected, it gone to B and C
it = tree.iterator();
}
if (selGeo == null) {
// at least one selected, select next one
selGeo = selectedGeos.get(0);
}
// maybe selGeo is there in Graphics View 2,
// but it is not there in "tree", since we're
// in Graphics View 1! Then we probably want
// the same thing as when nothing is selected here!
if (!tree.contains(selGeo)) {
// but only after clearing the selection properly!
Iterator<GeoElement> itt = selectedGeos.iterator();
while (itt.hasNext()) {
// does something more than simple clear
removeSelectedGeo(itt.next(), false, true);
}
if (it.hasNext()) {
addSelectedGeo(it.next());
}
return false;
}
while (it.hasNext()) {
GeoElement geo = it.next();
if (selGeo == geo) {
removeSelectedGeo(selGeo);
if (!it.hasNext()) {
if (cycle) {
it = tree.iterator();
} else {
return false;
}
}
GeoElement next = it.next();
addSelectedGeo(next);
// make sure Input Boxes lose focus on <TAB>
if (!(next instanceof GeoInputBox)) {
ev.requestFocus();
} else {
Log.debug("[TF][TAB] next: " + next);
kernel.getApplication().getActiveEuclidianView()
.focusAndShowTextField((GeoInputBox) next);
}
break;
}
}
return true;
}
/**
* Select last created geo
*
* @param ev
* view that should get focus after (if we did not selct
* textfield)
*/
final public void selectLastGeo(EuclidianViewInterfaceCommon ev) {
if (selectedGeos.size() != 1) {
return;
}
GeoElement selGeo = selectedGeos.get(0);
GeoElement lastGeo = null;
TreeSet<GeoElement> tree = kernel.getConstruction()
.getGeoSetLabelOrder();
tree = new TreeSet<GeoElement>(tree);
TreeSet<GeoElement> copy = new TreeSet<GeoElement>(tree);
Iterator<GeoElement> it = copy.iterator();
// remove geos that don't have isSelectionAllowed()==true
while (it.hasNext()) {
GeoElement geo = it.next();
if (!geo.isSelectionAllowed(ev) || !geo.isEuclidianVisible()
|| !geo.isVisibleInView(ev.getViewID())) {
tree.remove(geo);
}
}
it = tree.iterator();
while (it.hasNext()) {
lastGeo = it.next();
}
it = tree.iterator();
while (it.hasNext()) {
GeoElement geo = it.next();
if (selGeo == geo) {
removeSelectedGeo(selGeo);
addSelectedGeo(lastGeo);
// make sure Input Boxes lose focus on <SHIFT><TAB>
if (!(lastGeo instanceof GeoInputBox)) {
ev.requestFocus();
} else {
kernel.getApplication().getActiveEuclidianView()
.focusAndShowTextField((GeoInputBox) lastGeo);
}
break;
}
lastGeo = geo;
}
}
/**
* Update stylebars, menubar and properties view to match selection
*/
public void updateSelection() {
updateSelection(true);
}
/**
* Update stylebars, menubar and properties view to match selection
*
* @param updatePropertiesView
* whether to update properties view
*/
public void updateSelection(boolean updatePropertiesView) {
listener.updateSelection(updatePropertiesView);
}
/**
* Add a selection listener
*
* @param sl
* GeoElementSelectionListener to be added
*/
public void addSelectionListener(GeoElementSelectionListener sl) {
selectionListeners.add(sl);
}
/**
* Remove a selection listener
*
* @param sl
* GeoElementSelectionListener to be removed
*/
public void removeSelectionListener(GeoElementSelectionListener sl) {
selectionListeners.remove(sl);
}
/**
* @return Set of all registered SelectionListeners
*/
public ArrayList<GeoElementSelectionListener> getSelectionListeners() {
return selectionListeners;
}
/**
* @return selected points
*/
public ArrayList<GeoPointND> getSelectedPointList() {
return selectedPoints;
}
/**
* @return selected numerics
*/
public ArrayList<GeoNumeric> getSelectedNumberList() {
return selectedNumbers;
}
/**
* @return selected numbers
*/
public ArrayList<GeoNumberValue> getSelectedNumberValueList() {
return selectedNumberValues;
}
/**
* @return selected lines
*/
public ArrayList<GeoLineND> getSelectedLineList() {
return selectedLines;
}
/**
* @return selected paths
*/
public ArrayList<Path> getSelectedPathList() {
return selectedPaths;
}
/**
* @return selected conics
*/
public ArrayList<GeoConicND> getSelectedConicNDList() {
return selectedConicsND;
}
/**
* @return selected direction geos
*/
public ArrayList<GeoDirectionND> getSelectedDirectionList() {
return selectedDirections;
}
/**
* @return selected segments
*/
public ArrayList<GeoSegmentND> getSelectedSegmentList() {
return selectedSegments;
}
/**
* @return selected regions
*/
public ArrayList<Region> getSelectedRegionList() {
return selectedRegions;
}
/**
* @return selected implicit curves
*/
public ArrayList<GeoImplicit> getSelectedImplicitpolyList() {
return selectedImplicitpoly;
}
/**
* @return selected implicit surfaces
*/
public ArrayList<GeoImplicitSurfaceND> getSelectedImplicitSurfaceList() {
return selectedImplicitSurface;
}
/**
* @return selected functions
*/
public ArrayList<GeoFunction> getSelectedFunctionList() {
return selectedFunctions;
}
/**
* @return selected nvar functions
*/
public ArrayList<GeoFunctionNVar> getSelectedFunctionNVarList() {
return selectedFunctionsNVar;
}
public ArrayList<GeoCurveCartesian> getSelectedCurveList() {
return selectedCurves;
}
public ArrayList<GeoVectorND> getSelectedVectorList() {
return selectedVectors;
}
public ArrayList<GeoPolygon> getSelectedPolygonList() {
return selectedPolygons;
}
public ArrayList<GeoPolyLine> getSelectedPolyLineList() {
return selectedPolyLines;
}
public ArrayList<GeoElement> getSelectedGeoList() {
return selectedGeosEuclidian;
}
public ArrayList<GeoList> getSelectedListList() {
return selectedLists;
}
public ArrayList<GeoElement> getTempMoveGeoList() {
if (tempMoveGeoList == null) {
tempMoveGeoList = new ArrayList<GeoElement>();
}
return tempMoveGeoList;
}
public <T> int addToSelectionList(ArrayList<T> selectionList, T geo,
int max) {
if (geo == null) {
return 0;
}
int ret = 0;
if (selectionList.contains(geo)) { // remove from selection
selectionList.remove(geo);
if (!selectionList.equals(getSelectedGeoList())) {
getSelectedGeoList().remove(geo);
}
removeSelectedGeo((GeoElement) geo, true, true);
ret = -1;
} else { // new element: add to selection
if (selectionList.size() < max) {
selectionList.add(geo);
if (!selectionList.equals(getSelectedGeoList())) {
getSelectedGeoList().add((GeoElement) geo);
}
addSelectedGeo((GeoElement) geo, true, true);
ret = 1;
}
}
if (ret != 0) {
setGeoToggled(true);
}
return ret;
}
public ArrayList<GeoCoordSys> getSelectedCS2DList() {
return selectedCS2D;
}
public ArrayList<GeoPlaneND> getSelectedPlaneList() {
return selectedPlane;
}
public ArrayList<GeoQuadricND> getSelectedQuadricList() {
return selectedQuadric;
}
public ArrayList<GeoQuadric3DLimitedInterface> getSelectedQuadricLimitedList() {
return selectedQuadricLimited;
}
public ArrayList<GeoPolyhedronInterface> getSelectedPolyhedronList() {
return selectedPolyhedron;
}
public final void clearSelection(ArrayList<?> selectionList,
boolean doUpdateSelection) {
// unselect
selectionList.clear();
getSelectedGeoList().clear();
if (doUpdateSelection) {
clearSelectedGeos();
}
}
public void clearLists() {
clearSelection(getSelectedNumberList(), false);
clearSelection(getSelectedNumberValueList(), false);
clearSelection(getSelectedPointList(), false);
clearSelection(getSelectedLineList(), false);
clearSelection(getSelectedSegmentList(), false);
clearSelection(getSelectedConicNDList(), false);
clearSelection(getSelectedVectorList(), false);
clearSelection(getSelectedPolygonList(), false);
clearSelection(getSelectedGeoList(), false);
clearSelection(getSelectedFunctionList(), false);
clearSelection(getSelectedCurveList(), false);
clearSelection(getSelectedListList(), false);
clearSelection(getSelectedPathList(), false);
clearSelection(getSelectedRegionList(), false);
clearSelection(getSelectedCS2DList(), false);
clearSelection(getSelectedPlaneList(), false);
clearSelection(getSelectedPolyhedronList(), false);
clearSelection(getSelectedQuadricList(), false);
clearSelection(getSelectedQuadricLimitedList(), false);
}
/** selected geos names just before undo/redo */
private ArrayList<String> selectedGeosNames = new ArrayList<String>();
/**
* store selected geos names
*/
public void storeSelectedGeosNames() {
selectedGeosNames.clear();
for (GeoElement geo : getSelectedGeos()) {
selectedGeosNames.add(geo.getLabelSimple());
}
}
/**
* set geos selected from their names
*/
public void recallSelectedGeosNames(Kernel kernel) {
ArrayList<GeoElement> list = new ArrayList<GeoElement>();
for (String name : selectedGeosNames) {
GeoElement geo = kernel.lookupLabel(name);
if (geo != null) {
list.add(geo);
}
}
setSelectedGeos(list);
}
}