001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.util; 003 004import java.util.Collection; 005import java.util.Collections; 006import java.util.HashSet; 007import java.util.Iterator; 008import java.util.Set; 009 010import org.openstreetmap.josm.Main; 011import org.openstreetmap.josm.data.osm.DataSet; 012import org.openstreetmap.josm.data.osm.OsmPrimitive; 013import org.openstreetmap.josm.data.osm.Relation; 014 015/** 016 * This class stores the set of highlited primitives and 017 * allows easy and fast change of highlighting 018 */ 019public class HighlightHelper { 020 Set<OsmPrimitive> highlightedPrimitives = new HashSet<>(); 021 022 /** 023 * Highlight and remember given primitives 024 * @param prims - primitives to highlight/unhighlight 025 */ 026 public boolean highlight(Collection <? extends OsmPrimitive> prims) { 027 return highlight(prims, false); 028 } 029 030 /** 031 * Highlight and remember given primitives 032 * @param prims - primitives to highlight/unhighlight 033 * @param only - remove previous highlighting 034 */ 035 public boolean highlight(Collection <? extends OsmPrimitive> prims, boolean only) { 036 boolean needsRepaint = false; 037 if (only) { 038 Iterator<OsmPrimitive> it = highlightedPrimitives.iterator(); 039 while (it.hasNext()) { 040 OsmPrimitive p = it.next(); 041 if (!prims.contains(p)) { 042 p.setHighlighted(false); 043 it.remove(); 044 needsRepaint = true; 045 } 046 } 047 } 048 for (OsmPrimitive p: prims) { 049 needsRepaint |= setHighlight(p, true); 050 } 051 052 return needsRepaint; 053 } 054 055 /** 056 * Highlight and remember given primitives, forgetting previously highlighted by this instance 057 * @param prims - primitives to highlight/unhighlight 058 */ 059 public boolean highlightOnly(Collection <? extends OsmPrimitive> prims) { 060 return highlight(prims, true); 061 } 062 063 /** 064 * Highlight and remember given primitive, forgetting previously highlighted by this instance 065 * @param p - primitives to highlight/unhighlight 066 */ 067 public boolean highlightOnly(OsmPrimitive p) { 068 return highlight(Collections.singleton(p), true); 069 } 070 071 /** 072 * Highlight and remember given primitive 073 * @param p - primitive to highlight/unhighlight 074 * @param flag - true to highlight 075 */ 076 public boolean setHighlight(OsmPrimitive p, boolean flag) { 077 return setHighlight(p, flag, new HashSet<Relation>()); 078 } 079 080 private boolean setHighlight(OsmPrimitive p, boolean flag, Set<Relation> seenRelations) { 081 if (p instanceof Relation) { 082 Relation r = (Relation) p; 083 seenRelations.add(r); 084 boolean needRepaint = false; 085 for (OsmPrimitive m : r.getMemberPrimitives()) { 086 if (!(m instanceof Relation) || !seenRelations.contains(m)) { 087 needRepaint |= setHighlight(m, flag, seenRelations); 088 } 089 } 090 return needRepaint; 091 } else if (flag) { 092 if (highlightedPrimitives.add(p)) { 093 p.setHighlighted(true); 094 return true; 095 } 096 } else { 097 if (highlightedPrimitives.remove(p)) { 098 p.setHighlighted(false); 099 return true; 100 } 101 } 102 return false; 103 } 104 105 /** 106 * Clear highlighting of all remembered primitives 107 */ 108 public void clear() { 109 for (OsmPrimitive p: highlightedPrimitives) { 110 p.setHighlighted(false); 111 } 112 highlightedPrimitives.clear(); 113 } 114 115 /** 116 * Slow method to import all currently highlighted primitives into this instance 117 */ 118 public void findAllHighlighted() { 119 DataSet ds = Main.main.getCurrentDataSet(); 120 if (ds!=null) { 121 highlightedPrimitives.addAll( ds.allNonDeletedPrimitives() ); 122 } 123 } 124 125 /** 126 * Slow method to remove highlights from all primitives 127 */ 128 public static void clearAllHighlighted() { 129 DataSet ds = Main.main.getCurrentDataSet(); 130 if (ds!=null) { 131 for (OsmPrimitive p: ds.allNonDeletedPrimitives()) { 132 p.setHighlighted(false); 133 } 134 } 135 } 136}