Changeset 23192 in osm for applications/editors/josm/plugins/turnrestrictions/src
- Timestamp:
- 2010-09-15T18:59:53+02:00 (14 years ago)
- Location:
- applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions
- Files:
-
- 58 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/CreateOrEditTurnRestrictionAction.java
r20701 r23192 29 29 */ 30 30 public class CreateOrEditTurnRestrictionAction extends JosmAction { 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 } 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 31 static private final Logger logger = Logger.getLogger(CreateOrEditTurnRestrictionAction.class.getName()); 32 33 /** 34 * Installs the global key stroke with which creating/editing a turn restriction 35 * is triggered. 36 * 37 * @param keyStroke the key stroke 38 */ 39 static public void install(KeyStroke keyStroke){ 40 InputMap im = Main.contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 41 Object actionMapKey = im.get(keyStroke); 42 if (actionMapKey != null && !actionMapKey.toString().equals("turnrestrictions:create-or-edit")) { 43 System.out.println(tr("Warning: turnrestrictions plugin replaces already existing action ''{0}'' behind shortcut ''{1}'' by action ''{2}''", actionMapKey.toString(), keyStroke.toString(), "turnrestrictions:create-or-edit")); 44 } 45 KeyStroke[] keys = im.keys(); 46 if (keys != null){ 47 for(KeyStroke ks: im.keys()){ 48 if (im.get(ks).equals("turnrestrictions:create-or-edit")) { 49 im.remove(ks); 50 } 51 } 52 } 53 im.put(keyStroke, "turnrestrictions:create-or-edit"); 54 ActionMap am = Main.contentPane.getActionMap(); 55 am.put("turnrestrictions:create-or-edit", getInstance()); 56 } 57 58 /** 59 * Installs global key stroke configured in the preferences. 60 * 61 * @param keyStroke the key stroke 62 */ 63 static public void install(){ 64 String value = Main.pref.get(PreferenceKeys.EDIT_SHORTCUT, "shift ctrl T"); 65 KeyStroke key = KeyStroke.getKeyStroke(value); 66 if (key == null){ 67 System.out.println(tr("Warning: illegal value ''{0}'' for preference key ''{1}''. Falling back to default value ''shift ctrl T''.", value, PreferenceKeys.EDIT_SHORTCUT)); 68 key = KeyStroke.getKeyStroke("shift ctrl T"); 69 } 70 install(key); 71 } 72 73 /** the singleton instance of this action */ 74 private static CreateOrEditTurnRestrictionAction instance; 75 76 /** 77 * Replies the unique instance of this action 78 * 79 * @return 80 */ 81 public static CreateOrEditTurnRestrictionAction getInstance() { 82 if (instance == null){ 83 instance = new CreateOrEditTurnRestrictionAction(); 84 } 85 return instance; 86 } 87 88 protected CreateOrEditTurnRestrictionAction() { 89 super( 90 tr("Create/Edit turn restriction..."), 91 null, 92 tr("Create or edit a turn restriction."), 93 null, // shortcut is going to be registered later 94 false 95 ); 96 } 97 98 public void actionPerformed(ActionEvent e) { 99 OsmDataLayer layer = Main.main.getEditLayer(); 100 if (layer == null) return; 101 Collection<Relation> trs = TurnRestrictionSelectionPopupPanel.getTurnRestrictionsParticipatingIn(layer.data.getSelected()); 102 if (layer == null) return; 103 if (trs.isEmpty()){ 104 // current selection isn't participating in turn restrictions. Launch 105 // an editor for a new turn restriction 106 // 107 Relation tr = new TurnRestrictionBuilder().buildFromSelection(layer); 108 TurnRestrictionEditor editor = new TurnRestrictionEditor(Main.map.mapView,layer,tr); 109 TurnRestrictionEditorManager.getInstance().positionOnScreen(editor); 110 TurnRestrictionEditorManager.getInstance().register(layer, tr, editor); 111 editor.setVisible(true); 112 } else { 113 // let the user choose whether he wants to create a new turn restriction or 114 // edit one of the turn restrictions participating in the current selection 115 TurnRestrictionSelectionPopupPanel pnl = new TurnRestrictionSelectionPopupPanel( 116 layer 117 ); 118 pnl.launch(); 119 } 120 } 121 121 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionBuilder.java
r20724 r23192 21 21 public class TurnRestrictionBuilder { 22 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 23 private Way from; 24 private Way to; 25 private final ArrayList<OsmPrimitive> vias = new ArrayList<OsmPrimitive>(); 26 27 public TurnRestrictionBuilder(){ 28 } 29 30 /** 31 * Initializes the 'from' leg. Proposes the first element 32 * in {@code primitives} as 'from' leg if this element is a 33 * non-deleted, visible way. 34 * 35 * @param primitives 36 */ 37 protected void initFromLeg(List<OsmPrimitive> primitives){ 38 if (primitives == null || primitives.isEmpty()) return; 39 OsmPrimitive p = primitives.get(0); 40 if (! (p instanceof Way)) return; 41 Way fromLeg = (Way)p; 42 if (fromLeg.isDeleted() || ! fromLeg.isVisible()) return; 43 this.from = fromLeg; 44 } 45 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 } 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 46 /** 47 * Initializes the 'to' leg. Proposes the last element 48 * in {@code primitives} as 'to' leg if this element is a 49 * non-deleted, visible way. 50 * 51 * @param primitives 52 */ 53 protected void initToLeg(List<OsmPrimitive> primitives){ 54 if (primitives == null || primitives.isEmpty()) return; 55 if (primitives.size() < 2) return; 56 OsmPrimitive p = primitives.get(primitives.size()-1); 57 if (! (p instanceof Way)) return; 58 Way toLeg = (Way)p; 59 if (toLeg.isDeleted() || ! toLeg.isVisible()) return; 60 this.to = toLeg; 61 } 62 63 /** 64 * Initializes the vias from the two turn restriction legs. The two 65 * legs have to be defined, otherwise no via is proposed. This methods 66 * proposes exactly one node as via, if the two turn restriction 67 * legs intersect at exactly one node. 68 */ 69 protected void initViaFromLegs(){ 70 if (from == null || to == null) return; 71 // check whether 'from' and 'to' have exactly one intersecting 72 // node. This node is proposed as via node. The turn restriction 73 // node will also provide functionality to split either or both 74 // of 'from' and 'to' way if they aren't connected from tail to 75 // head 76 // 77 HashSet<Node> nodes = new HashSet<Node>(); 78 nodes.addAll(from.getNodes()); 79 nodes.retainAll(to.getNodes()); 80 if (nodes.size() == 1){ 81 vias.add(nodes.iterator().next()); 82 } 83 } 84 85 /** 86 * Initializes the vias with the primitives (1..size-2), provided 87 * these primitives aren't relations and they are visible and non-deleted. 88 * 89 * @param primitives 90 */ 91 protected void initViasFromPrimitives(List<OsmPrimitive> primitives) { 92 if (primitives == null || primitives.size() <=2) return; 93 // if we didn't find a from or a to way, we don't propose via objects 94 // either 95 if (from == null || to == null) return; 96 for(int i=1; i< primitives.size() -2;i++){ 97 OsmPrimitive p = primitives.get(i); 98 if (p == null) continue; 99 if (p instanceof Relation) continue; 100 if (p.isDeleted() || ! p.isVisible()) continue; 101 vias.add(p); 102 } 103 } 104 105 /** 106 * Resets the builder 107 */ 108 protected void reset() { 109 this.from = null; 110 this.to = null; 111 this.vias.clear(); 112 } 113 114 /** 115 * Creates and initializes a new turn restriction based on the primitives 116 * currently selected in layer {@code layer}. 117 * 118 * @param layer the layer. Must not be null. 119 * @return the new initialized turn restriction. The turn restriction isn't 120 * added to the layer yet. 121 * @throws IllegalArgumentException thrown if layer is null 122 */ 123 public synchronized Relation buildFromSelection(OsmDataLayer layer) { 124 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 125 List<OsmPrimitive> selection = new ArrayList<OsmPrimitive>(layer.data.getSelected()); 126 return build(selection); 127 } 128 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 } 129 /** 130 * Creates and initializes a new turn restriction based on primitives 131 * in {@code primitives}. 132 * 133 * @param primitives the primitives 134 * @return the new initialized turn restriction. The turn restriction isn't 135 * added to the layer yet. 136 */ 137 public synchronized Relation build(List<OsmPrimitive> primitives){ 138 Relation tr = new Relation(); 139 tr.put("type", "restriction"); 140 if (primitives == null || primitives.isEmpty()) return tr; 141 if (primitives.size() <=2){ 142 initFromLeg(primitives); 143 initToLeg(primitives); 144 initViaFromLegs(); 145 } else if (primitives.size() > 2) { 146 initFromLeg(primitives); 147 initToLeg(primitives); 148 initViasFromPrimitives(primitives); 149 } 150 151 if (from != null){ 152 tr.addMember(new RelationMember("from", from)); 153 } 154 if (to != null){ 155 tr.addMember(new RelationMember("to", to)); 156 } 157 for(OsmPrimitive via: vias){ 158 tr.addMember(new RelationMember("via", via)); 159 } 160 return tr; 161 } 162 162 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsPlugin.java
r20701 r23192 13 13 */ 14 14 public class TurnRestrictionsPlugin extends Plugin{ 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 15 16 public TurnRestrictionsPlugin(PluginInformation info) { 17 super(info); 18 } 19 20 /** 21 * Called when the JOSM map frame is created or destroyed. 22 */ 23 @Override 24 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) { 25 if (oldFrame == null && newFrame != null) { // map frame added 26 TurnRestrictionsListDialog dialog = new TurnRestrictionsListDialog(); 27 // add the dialog 28 newFrame.addToggleDialog(dialog); 29 CreateOrEditTurnRestrictionAction.install(); 30 } 31 } 32 32 33 34 35 36 33 @Override 34 public PreferenceSetting getPreferenceSetting() { 35 return new PreferenceEditor(); 36 } 37 37 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdListProvider.java
r20489 r23192 5 5 import org.openstreetmap.josm.data.osm.PrimitiveId;; 6 6 public interface PrimitiveIdListProvider { 7 8 9 10 11 12 13 7 /** 8 * Replies the list of currently selected primitive IDs. Replies an empty list if no primitive IDs 9 * are selected. 10 * 11 * @return the list of currently selected primitive IDs 12 */ 13 List<PrimitiveId> getSelectedPrimitiveIds(); 14 14 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdListTransferHandler.java
r20724 r23192 20 20 */ 21 21 public class PrimitiveIdListTransferHandler extends TransferHandler { 22 23 24 25 26 22 static private final Logger logger = Logger.getLogger(PrimitiveIdListTransferHandler.class.getName()); 23 private PrimitiveIdListProvider provider; 24 25 /** 26 * Replies true if {@code transferFlavors} includes the data flavor {@see PrimitiveIdTransferable#PRIMITIVE_ID_LIST_FLAVOR}. 27 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 28 * @param transferFlavors an array of transferFlavors 29 * @return true if {@code transferFlavors} includes the data flavor {@see PrimitiveIdTransferable#PRIMITIVE_ID_LIST_FLAVOR}. 30 */ 31 public static boolean isSupportedFlavor(DataFlavor[] transferFlavors) { 32 for (DataFlavor df: transferFlavors) { 33 if (df.equals(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR)) return true; 34 } 35 return false; 36 } 37 38 /** 39 * Creates the transfer handler 40 * 41 * @param provider the provider of the primitive IDs. Must not be null. 42 * @throws IllegalArgumentException thrown if provider is null. 43 */ 44 public PrimitiveIdListTransferHandler(PrimitiveIdListProvider provider) throws IllegalArgumentException{ 45 CheckParameterUtil.ensureParameterNotNull(provider, "provider"); 46 this.provider = provider; 47 } 48 48 49 50 51 52 53 49 50 51 protected Transferable createTransferable(JComponent c) { 52 return new PrimitiveIdTransferable(provider.getSelectedPrimitiveIds()); 53 } 54 54 55 56 57 55 public int getSourceActions(JComponent c) { 56 return COPY; 57 } 58 58 59 60 61 62 } 59 @Override 60 public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { 61 return isSupportedFlavor(transferFlavors); 62 } 63 63 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdTransferable.java
r20489 r23192 18 18 */ 19 19 public class PrimitiveIdTransferable implements Transferable{ 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 20 21 /** the data flower for the set of of primitive ids */ 22 static public final DataFlavor PRIMITIVE_ID_LIST_FLAVOR = 23 new DataFlavor(Set.class, "a set of OSM primitive ids"); 24 25 /** 26 * this transferable supports two flavors: (1) {@see #PRIMITIVE_ID_LIST_FLAVOR} and 27 * (2) {@see DataFlavor#stringFlavor}. 28 * 29 * See also {@see #getPrimitiveIds()} and {@see #getAsString()} 30 */ 31 static public final DataFlavor[] SUPPORTED_FLAVORS = new DataFlavor[] { 32 PRIMITIVE_ID_LIST_FLAVOR, 33 DataFlavor.stringFlavor 34 }; 35 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 36 37 private List<PrimitiveId> ids = new ArrayList<PrimitiveId>(); 38 39 /** 40 * Creates a transferable from a collection of {@see PrimitiveId}s 41 * 42 * @param ids 43 */ 44 public PrimitiveIdTransferable(List<PrimitiveId> ids) { 45 if (ids == null) return; 46 for(PrimitiveId id: ids) { 47 this.ids.add(new SimplePrimitiveId(id.getUniqueId(), id.getType())); 48 } 49 } 50 51 /** 52 * If flavor is {@see #PRIMITIVE_ID_SET_FLAVOR}, replies a the list of 53 * transferred {@see PrimitiveId}s 54 * 55 * If flavor is {@see DataFlavor#stringFlavor}, replies a string representation 56 * of the list of transferred {@see PrimitiveId}s 57 */ 58 public Object getTransferData(DataFlavor flavor) 59 throws UnsupportedFlavorException, IOException { 60 if (PRIMITIVE_ID_LIST_FLAVOR.equals(flavor)) { 61 return getPrimitiveIds(); 62 } else if (DataFlavor.stringFlavor.equals(flavor)) { 63 return getAsString(); 64 } 65 throw new UnsupportedFlavorException(flavor); 66 } 67 68 /** 69 * Replies the list of OSM primitive ids 70 * 71 * @return the list of OSM primitive ids 72 */ 73 public List<PrimitiveId> getPrimitiveIds() { 74 return ids; 75 } 76 77 /** 78 * Replies a string representation of the list of OSM primitive ids 79 * 80 * @return a string representation of the list of OSM primitive ids 81 */ 82 public String getAsString() { 83 StringBuffer sb = new StringBuffer(); 84 for(PrimitiveId id: ids) { 85 if (sb.length() > 0) sb.append(","); 86 sb.append(id.getType().getAPIName()).append("/").append(id.getUniqueId()); 87 } 88 return sb.toString(); 89 } 90 90 91 92 93 91 public DataFlavor[] getTransferDataFlavors() { 92 return SUPPORTED_FLAVORS; 93 } 94 94 95 96 97 98 99 100 } 95 public boolean isDataFlavorSupported(DataFlavor flavor) { 96 for(DataFlavor df: SUPPORTED_FLAVORS) { 97 if (df.equals(flavor)) return true; 98 } 99 return false; 100 } 101 101 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/AdvancedEditorPanel.java
r20735 r23192 23 23 */ 24 24 public class AdvancedEditorPanel extends JPanel { 25 25 private static final Logger logger = Logger.getLogger(AdvancedEditorPanel.class.getName()); 26 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 } 120 } 121 27 private TurnRestrictionEditorModel model; 28 private TagEditorPanel pnlTagEditor; 29 private JPanel pnlRelationMemberEditor; 30 private JTable tblRelationMemberEditor; 31 private JSplitPane spEditors; 32 33 /** 34 * Creates the panel with the tag editor 35 * 36 * @return 37 */ 38 protected JPanel buildTagEditorPanel() { 39 JPanel pnl = new JPanel(new BorderLayout()); 40 HtmlPanel msg = new HtmlPanel(); 41 msg.setText("<html><body>" + 42 tr("In the following table you can edit the <strong>raw tags</strong>" 43 + " of the OSM relation representing this turn restriction.") 44 + "</body></html>" 45 ); 46 pnl.add(msg, BorderLayout.NORTH); 47 pnlTagEditor = new TagEditorPanel(model.getTagEditorModel()); 48 pnlTagEditor.initAutoCompletion(model.getLayer()); 49 pnl.add(pnlTagEditor, BorderLayout.CENTER); 50 return pnl; 51 } 52 53 /** 54 * Builds the panel with the table for editing relation members 55 * 56 * @return 57 */ 58 protected JPanel buildMemberEditorPanel() { 59 JPanel pnl = new JPanel(new BorderLayout()); 60 HtmlPanel msg = new HtmlPanel(); 61 msg.setText("<html><body>" 62 + tr("In the following table you can edit the <strong>raw members</strong>" 63 + " of the OSM relation representing this turn restriction.") + "</body></html>" 64 ); 65 pnl.add(msg, BorderLayout.NORTH); 66 67 tblRelationMemberEditor = new RelationMemberTable(model); 68 JScrollPane pane = new JScrollPane(tblRelationMemberEditor); 69 pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 70 pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 71 pnl.add(pane); 72 return pnl; 73 } 74 75 /** 76 * Creates the main split panel 77 * @return 78 */ 79 protected JSplitPane buildSplitPane() { 80 spEditors = new JSplitPane(JSplitPane.VERTICAL_SPLIT); 81 spEditors.setTopComponent(buildTagEditorPanel()); 82 spEditors.setBottomComponent(buildMemberEditorPanel()); 83 spEditors.setOneTouchExpandable(false); 84 spEditors.setDividerSize(5); 85 spEditors.addHierarchyListener(new SplitPaneDividerInitializer()); 86 return spEditors; 87 } 88 89 /** 90 * Builds the user interface 91 */ 92 protected void build() { 93 setLayout(new BorderLayout()); 94 add(buildSplitPane(), BorderLayout.CENTER); 95 } 96 97 /** 98 * Creates the advanced editor 99 * 100 * @param model the editor model. Must not be null. 101 * @throws IllegalArgumentException thrown if model is null 102 */ 103 public AdvancedEditorPanel(TurnRestrictionEditorModel model) throws IllegalArgumentException{ 104 CheckParameterUtil.ensureParameterNotNull(model, "model"); 105 this.model = model; 106 build(); 107 HelpUtil.setHelpContext(this, HelpUtil.ht("/Plugins/turnrestrictions#AdvancedEditor")); 108 } 109 110 /** 111 * Initializes the divider location when the components becomes visible the 112 * first time 113 */ 114 class SplitPaneDividerInitializer implements HierarchyListener { 115 public void hierarchyChanged(HierarchyEvent e) { 116 if (isShowing()) { 117 spEditors.setDividerLocation(0.5); 118 spEditors.removeHierarchyListener(this); 119 } 120 } 121 } 122 122 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/BasicEditorPanel.java
r20917 r23192 28 28 public class BasicEditorPanel extends VerticallyScrollablePanel { 29 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 30 /** the turn restriction model */ 31 private TurnRestrictionEditorModel model; 32 33 /** the UI widgets */ 34 private TurnRestrictionLegEditor fromEditor; 35 private TurnRestrictionLegEditor toEditor; 36 private ViaList lstVias; 37 private JLabel lblVias; 38 private JScrollPane spVias; 39 private TurnRestrictionComboBox cbTurnRestrictions; 40 private VehicleExceptionEditor vehicleExceptionsEditor; 41 42 /** 43 * builds the UI 44 */ 45 protected void build() { 46 setLayout(new GridBagLayout()); 47 GridBagConstraints gc = new GridBagConstraints(); 48 gc.anchor = GridBagConstraints.WEST; 49 gc.fill = GridBagConstraints.HORIZONTAL; 50 gc.weightx = 0.0; 51 52 // the editor for selecting the 'from' leg 53 gc.insets = new Insets(0,0,5,5); 54 add(new JLabel(tr("Type:")), gc); 55 56 gc.gridx = 1; 57 gc.weightx = 1.0; 58 add(cbTurnRestrictions = new TurnRestrictionComboBox(new TurnRestrictionComboBoxModel(model)), gc); 59 59 60 61 62 63 64 65 66 67 68 60 // the editor for selecting the 'from' leg 61 gc.gridx = 0; 62 gc.gridy = 1; 63 gc.weightx = 0.0; 64 add(new JLabel(tr("From:")), gc); 65 66 gc.gridx = 1; 67 gc.weightx = 1.0; 68 add(fromEditor = new TurnRestrictionLegEditor(model, TurnRestrictionLegRole.FROM),gc); 69 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 } 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 70 // the editor for selecting the 'to' leg 71 gc.gridx = 0; 72 gc.gridy = 2; 73 gc.weightx = 0.0; 74 gc.insets = new Insets(0,0,5,5); 75 add(new JLabel(tr("To:")), gc); 76 77 gc.gridx = 1; 78 gc.weightx = 1.0; 79 add(toEditor = new TurnRestrictionLegEditor(model, TurnRestrictionLegRole.TO),gc); 80 81 // the editor for selecting the 'vias' 82 gc.gridx = 0; 83 gc.gridy = 3; 84 gc.weightx = 0.0; 85 gc.insets = new Insets(0,0,5,5); 86 add(lblVias = new JLabel(tr("Vias:")), gc); 87 88 gc.gridx = 1; 89 gc.weightx = 1.0; 90 DefaultListSelectionModel selectionModel = new DefaultListSelectionModel(); 91 add(spVias = new JScrollPane(lstVias = new ViaList(new ViaListModel(model, selectionModel), selectionModel)),gc); 92 if (!Main.pref.getBoolean(PreferenceKeys.SHOW_VIAS_IN_BASIC_EDITOR, false)) { 93 lblVias.setVisible(false); 94 spVias.setVisible(false); 95 } 96 97 // the editor for vehicle exceptions 98 vehicleExceptionsEditor = new VehicleExceptionEditor(model); 99 gc.gridx = 0; 100 gc.gridy = 4; 101 gc.weightx = 1.0; 102 gc.gridwidth = 2; 103 gc.insets = new Insets(0,0,5,5); 104 add(vehicleExceptionsEditor, gc); 105 106 // just a filler - grabs remaining space 107 gc.gridx = 0; 108 gc.gridy = 5; 109 gc.gridwidth = 2; 110 gc.weighty = 1.0; 111 gc.fill = GridBagConstraints.BOTH; 112 add(new JPanel(), gc); 113 114 setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 115 } 116 117 118 /** 119 * Creates the panel. 120 * 121 * @param model the editor model. Must not be null. 122 * @throws IllegalArgumentException thrown if model is null 123 */ 124 public BasicEditorPanel(TurnRestrictionEditorModel model) { 125 CheckParameterUtil.ensureParameterNotNull(model, "model"); 126 this.model = model; 127 build(); 128 HelpUtil.setHelpContext(this, HelpUtil.ht("/Plugins/turnrestrictions#BasicEditor")); 129 } 130 131 /** 132 * Requests the focus on one of the input widgets for turn 133 * restriction data. 134 * 135 * @param focusTarget the target component to request focus for. 136 * Ignored if null. 137 */ 138 public void requestFocusFor(BasicEditorFokusTargets focusTarget){ 139 if (focusTarget == null) return; 140 switch(focusTarget){ 141 case RESTRICION_TYPE: 142 cbTurnRestrictions.requestFocusInWindow(); 143 break; 144 case FROM: 145 fromEditor.requestFocusInWindow(); 146 break; 147 case TO: 148 toEditor.requestFocusInWindow(); 149 break; 150 case VIA: 151 lstVias.requestFocusInWindow(); 152 break; 153 } 154 } 155 156 /** 157 * Initializes the set of icons used from the preference key 158 * {@see PreferenceKeys#ROAD_SIGNS}. 159 * 160 * @param prefs the JOSM preferences 161 */ 162 public void initIconSetFromPreferences(Preferences prefs){ 163 cbTurnRestrictions.initIconSetFromPreferences(prefs); 164 } 165 166 /** 167 * Initializes the visibility of the list of via-objects depending 168 * on values in the JOSM preferences 169 * 170 * @param prefs the JOSM preferences 171 */ 172 public void initViasVisibilityFromPreferences(Preferences prefs){ 173 boolean value = prefs.getBoolean(PreferenceKeys.SHOW_VIAS_IN_BASIC_EDITOR, false); 174 if (value != lblVias.isVisible()){ 175 lblVias.setVisible(value); 176 spVias.setVisible(value); 177 } 178 } 179 179 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ExceptValueModel.java
r20586 r23192 14 14 */ 15 15 public class ExceptValueModel { 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 } 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 } 16 /** 17 * The set of standard vehicle types which can be used in the 18 * 'except' tag 19 */ 20 static public final Set<String> STANDARD_VEHICLE_EXCEPTION_VALUES; 21 static { 22 HashSet<String> s = new HashSet<String>(); 23 s.add("psv"); 24 s.add("hgv"); 25 s.add("bicycle"); 26 s.add("motorcar"); 27 STANDARD_VEHICLE_EXCEPTION_VALUES = Collections.unmodifiableSet(s); 28 } 29 30 /** 31 * Replies true, if {@code v} is a standard vehicle type. Replies 32 * false if {@code v} is null 33 * 34 * @param v the vehicle type. 35 * @return true, if {@code v} is a standard vehicle type. 36 */ 37 static public boolean isStandardVehicleExceptionValue(String v){ 38 if (v == null) return false; 39 v = v.trim().toLowerCase(); 40 return STANDARD_VEHICLE_EXCEPTION_VALUES.contains(v); 41 } 42 43 private String value = ""; 44 private boolean isStandard = true; 45 private final Set<String> vehicleExceptions = new HashSet<String>(); 46 47 48 protected void parseValue(String value) { 49 if (value == null || value.trim().equals("")) value = ""; 50 this.value = value; 51 isStandard = true; 52 vehicleExceptions.clear(); 53 if (value.equals("")) return; 54 String[] values = value.split(";"); 55 for (String v: values){ 56 v = v.trim().toLowerCase(); 57 if (isStandardVehicleExceptionValue(v)) { 58 vehicleExceptions.add(v); 59 } else { 60 isStandard = false; 61 } 62 } 63 } 64 65 /** 66 * Creates a new model for an empty standard value 67 */ 68 public ExceptValueModel() {} 69 70 /** 71 * Creates a new model for the tag value {@code value}. 72 * 73 * @param value the tag value 74 * @see #parseValue(String) 75 */ 76 public ExceptValueModel(String value){ 77 if (value == null || value.trim().equals("")) 78 return; 79 parseValue(value); 80 } 81 82 /** 83 * Replies the tag value representing the state of this model. 84 * 85 * @return 86 */ 87 public String getValue() { 88 if (isStandard){ 89 StringBuffer sb = new StringBuffer(); 90 // we use an ordered list because equals() 91 // is based on getValue() 92 // 93 List<String> values = new ArrayList<String>(vehicleExceptions); 94 Collections.sort(values); 95 for (String v: values){ 96 if (sb.length() > 0) { 97 sb.append(";"); 98 } 99 sb.append(v); 100 } 101 return sb.toString(); 102 } else { 103 return value; 104 } 105 } 106 107 /** 108 * Sets the value in this model 109 * 110 * @param value 111 */ 112 public void setValue(String value) { 113 parseValue(value); 114 } 115 116 /** 117 * Replies true if this model currently holds a standard 'except' value 118 * 119 * @return 120 */ 121 public boolean isStandard() { 122 return isStandard; 123 } 124 125 /** 126 * Tells this model to use standard values only. 127 * 128 */ 129 public void setStandard(boolean isStandard) { 130 this.isStandard = isStandard; 131 } 132 133 /** 134 * Replies true if {@code vehicleType} is currently set as exception in this 135 * model. 136 * 137 * @param vehicleType one of the standard vehicle types from {@see #STANDARD_VEHICLE_EXCEPTION_VALUES} 138 * @return true if {@code vehicleType} is currently set as exception in this 139 * model. 140 * @exception IllegalArgumentException thrown if {@code vehicleType} isn't a standard vehicle type 141 */ 142 public boolean isVehicleException(String vehicleType) throws IllegalArgumentException{ 143 if (vehicleType == null) return false; 144 if (!isStandardVehicleExceptionValue(vehicleType)) { 145 throw new IllegalArgumentException(MessageFormat.format("vehicleType ''{0}'' isn''t a valid standard vehicle type", vehicleType)); 146 } 147 vehicleType = vehicleType.trim().toLowerCase(); 148 return vehicleExceptions.contains(vehicleType); 149 } 150 151 /** 152 * Sets the {@code vehicleType} as exception in this turn restriction. 153 * 154 * @param vehicleType one of the standard vehicle types from {@see #STANDARD_VEHICLE_EXCEPTION_VALUES} 155 * @exception IllegalArgumentException thrown if {@code vehicleType} isn't a standard vehicle type 156 */ 157 public void setVehicleException(String vehicleType) throws IllegalArgumentException{ 158 if (!isStandardVehicleExceptionValue(vehicleType)) { 159 throw new IllegalArgumentException(MessageFormat.format("vehicleType ''{0}'' isn''t a valid standard vehicle type", vehicleType)); 160 } 161 vehicleExceptions.add(vehicleType.trim().toLowerCase()); 162 } 163 164 165 /** 166 * Sets or removes the {@code vehicleType} as exception in this turn restriction, depending 167 * on whether {@code setOrRemove} is true or false, respectively. 168 * 169 * @param vehicleType one of the standard vehicle types from {@see #STANDARD_VEHICLE_EXCEPTION_VALUES} 170 * @param setOrRemove if true, the exception is set; otherwise, it is removed 171 * @exception IllegalArgumentException thrown if {@code vehicleType} isn't a standard vehicle type 172 */ 173 public void setVehicleException(String vehicleType, boolean setOrRemove) throws IllegalArgumentException{ 174 if (setOrRemove){ 175 setVehicleException(vehicleType); 176 } else { 177 removeVehicleException(vehicleType); 178 } 179 } 180 181 /** 182 * Removes the {@code vehicleType} as exception in this turn restriction 183 * 184 * @param vehicleType one of the standard vehicle types from {@see #STANDARD_VEHICLE_EXCEPTION_VALUES} 185 * @exception IllegalArgumentException thrown if {@code vehicleType} isn't a standard vehicle type 186 */ 187 public void removeVehicleException(String vehicleType) throws IllegalArgumentException{ 188 if (!isStandardVehicleExceptionValue(vehicleType)) { 189 throw new IllegalArgumentException(MessageFormat.format("vehicleType ''{0}'' isn''t a valid standard vehicle type", vehicleType)); 190 } 191 vehicleExceptions.remove(vehicleType.trim().toLowerCase()); 192 } 193 194 @Override 195 public int hashCode() { 196 final int prime = 31; 197 int result = 1; 198 result = prime * result + getValue().hashCode(); 199 return result; 200 } 201 202 @Override 203 public boolean equals(Object obj) { 204 if (this == obj) 205 return true; 206 if (obj == null) 207 return false; 208 if (getClass() != obj.getClass()) 209 return false; 210 ExceptValueModel other = (ExceptValueModel) obj; 211 return getValue().equals(other.getValue()); 212 } 213 213 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/JosmSelectionListModel.java
r20735 r23192 40 40 */ 41 41 public class JosmSelectionListModel extends AbstractListModel implements EditLayerChangeListener, SelectionChangedListener, DataSetListener, PrimitiveIdListProvider{ 42 43 42 static private final Logger logger = Logger.getLogger(JosmSelectionListModel.class.getName()); 43 44 44 private final List<OsmPrimitive> selection = new ArrayList<OsmPrimitive>(); 45 45 private DefaultListSelectionModel selectionModel; … … 55 55 */ 56 56 public JosmSelectionListModel(OsmDataLayer layer, DefaultListSelectionModel selectionModel) { 57 58 59 57 CheckParameterUtil.ensureParameterNotNull(selectionModel, "selectionModel"); 58 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 59 this.layer = layer; 60 60 this.selectionModel = selectionModel; 61 61 setJOSMSelection(layer.data.getSelected()); … … 115 115 */ 116 116 public void setJOSMSelection(Collection<? extends OsmPrimitive> selection) { 117 117 Collection<OsmPrimitive> sel = getSelected(); 118 118 this.selection.clear(); 119 119 if (selection == null) { … … 150 150 public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) { 151 151 if (newLayer == null) { 152 152 // don't show a JOSM selection if we don't have a data layer 153 153 setJOSMSelection(null); 154 154 } else if (newLayer != layer){ 155 156 157 155 // don't show a JOSM selection if this turn restriction editor doesn't 156 // manipulate data in the current data layer 157 setJOSMSelection(null); 158 158 } else { 159 159 setJOSMSelection(newLayer.data.getSelected()); … … 165 165 /* ------------------------------------------------------------------------ */ 166 166 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 167 168 169 170 171 167 // only update the JOSM selection if it is changed in the same data layer 168 // this turn restriction editor is working on 169 OsmDataLayer layer = Main.main.getEditLayer(); 170 if(layer == null) return; 171 if (layer != this.layer) return; 172 172 setJOSMSelection(newSelection); 173 173 } … … 184 184 if (event.getDataset() != layer.data) return; 185 185 // may influence the display name of primitives, update the data 186 186 update(event.getPrimitives()); 187 187 } 188 188 … … 217 217 /* interface PrimitiveIdListProvider */ 218 218 /* ------------------------------------------------------------------------ */ 219 220 221 222 223 224 225 226 227 219 public List<PrimitiveId> getSelectedPrimitiveIds() { 220 List<PrimitiveId> ret = new ArrayList<PrimitiveId>(getSelected().size()); 221 for(int i=0; i< selection.size(); i++) { 222 if (selectionModel.isSelectedIndex(i)) { 223 ret.add(selection.get(i).getPrimitiveId()); 224 } 225 } 226 return ret; 227 } 228 228 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/JosmSelectionPanel.java
r20586 r23192 42 42 */ 43 43 public class JosmSelectionPanel extends JPanel { 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 } 108 109 110 111 112 113 114 115 116 44 /** the list view */ 45 private JList lstSelection; 46 /** the model managing the selection */ 47 private JosmSelectionListModel model; 48 49 private CopyAction actCopy; 50 private TransferHandler transferHandler; 51 52 /** 53 * builds the UI for the panel 54 */ 55 protected void build(OsmDataLayer layer) { 56 setLayout(new BorderLayout()); 57 DefaultListSelectionModel selectionModel = new DefaultListSelectionModel(); 58 model = new JosmSelectionListModel(layer,selectionModel); 59 lstSelection = new JList(model); 60 lstSelection.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 61 lstSelection.setSelectionModel(selectionModel); 62 lstSelection.setCellRenderer(new OsmPrimitivRenderer()); 63 lstSelection.setTransferHandler(transferHandler = new JosmSelectionTransferHandler(model)); 64 lstSelection.setDragEnabled(true); 65 66 add(new JScrollPane(lstSelection), BorderLayout.CENTER); 67 add(new JLabel(tr("Selection")), BorderLayout.NORTH); 68 69 setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 70 actCopy = new CopyAction(); 71 lstSelection.addMouseListener(new PopupLauncher()); 72 } 73 74 /** 75 * Creates the JOSM selection panel for the selection in an OSM data layer 76 * 77 * @param layer the data layer. Must not be null. 78 * @exception IllegalArgumentException thrown if {@code layer} is null 79 */ 80 public JosmSelectionPanel(OsmDataLayer layer) throws IllegalArgumentException{ 81 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 82 build(layer); 83 } 84 85 /** 86 * wires the UI as listener to global event sources 87 */ 88 public void wireListeners() { 89 MapView.addEditLayerChangeListener(model); 90 DatasetEventManager.getInstance().addDatasetListener(model, FireMode.IN_EDT); 91 SelectionEventManager.getInstance().addSelectionListener(model, FireMode.IN_EDT_CONSOLIDATED); 92 } 93 94 /** 95 * removes the UI as listener to global event sources 96 */ 97 public void unwireListeners() { 98 MapView.removeEditLayerChangeListener(model); 99 DatasetEventManager.getInstance().removeDatasetListener(model); 100 SelectionEventManager.getInstance().removeSelectionListener(model); 101 } 102 103 class PopupLauncher extends PopupMenuLauncher { 104 @Override 105 public void launch(MouseEvent evt) { 106 new PopupMenu().show(lstSelection, evt.getX(), evt.getY()); 107 } 108 } 109 110 class PopupMenu extends JPopupMenu { 111 public PopupMenu() { 112 JMenuItem item = add(actCopy); 113 item.setTransferHandler(transferHandler); 114 actCopy.setEnabled(!model.getSelected().isEmpty()); 115 } 116 } 117 117 118 119 120 121 122 123 124 125 126 127 118 class CopyAction extends AbstractAction { 119 private Action delegate; 120 121 public CopyAction(){ 122 putValue(NAME, tr("Copy")); 123 putValue(SHORT_DESCRIPTION, tr("Copy to the clipboard")); 124 putValue(SMALL_ICON, ImageProvider.get("copy")); 125 putValue(ACCELERATOR_KEY, Shortcut.getCopyKeyStroke()); 126 delegate = lstSelection.getActionMap().get("copy"); 127 } 128 128 129 130 131 132 133 134 135 136 137 129 public void actionPerformed(ActionEvent e) { 130 delegate.actionPerformed(e); 131 } 132 } 133 134 static private class JosmSelectionTransferHandler extends PrimitiveIdListTransferHandler { 135 public JosmSelectionTransferHandler(PrimitiveIdListProvider provider) { 136 super(provider); 137 } 138 138 139 140 141 142 143 144 145 139 @Override 140 public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { 141 // the JOSM selection list is read-only. Don't allow to drop or paste 142 // data on it 143 return false; 144 } 145 } 146 146 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/NavigationControler.java
r20586 r23192 2 2 3 3 public interface NavigationControler { 4 5 6 7 8 9 } 10 11 12 4 public enum BasicEditorFokusTargets { 5 RESTRICION_TYPE, 6 FROM, 7 TO, 8 VIA 9 } 10 void gotoBasicEditor(); 11 void gotoAdvancedEditor(); 12 void gotoBasicEditor(BasicEditorFokusTargets focusTarget); 13 13 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberColumnModel.java
r20724 r23192 14 14 */ 15 15 public class RelationMemberColumnModel extends DefaultTableColumnModel{ 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 16 protected void build() { 17 TableColumn col = new TableColumn(); 18 19 // the role column 20 col.setHeaderValue(tr("Role")); 21 col.setResizable(true); 22 col.setPreferredWidth(100); 23 col.setCellEditor(new MemberRoleCellEditor()); 24 col.setCellRenderer(new RelationMemberRoleCellRenderer()); 25 addColumn(col); 26 27 // column 1 - the member 28 col = new TableColumn(1); 29 col.setHeaderValue(tr("Refers to")); 30 col.setResizable(true); 31 col.setPreferredWidth(300); 32 col.setCellRenderer(new RelationMemberTargetCellRenderer()); 33 addColumn(col); 34 } 35 36 /** 37 * Creates the column model with a given column selection model. 38 * 39 * @param colSelectionModel the column selection model. Must not be null. 40 * @throws IllegalArgumentException thrown if {@code colSelectionModel} is null 41 */ 42 public RelationMemberColumnModel(DefaultListSelectionModel colSelectionModel) throws IllegalArgumentException{ 43 CheckParameterUtil.ensureParameterNotNull(colSelectionModel, "colSelectionModel"); 44 setSelectionModel(colSelectionModel); 45 build(); 46 } 47 47 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberEditorModel.java
r20724 r23192 24 24 import org.openstreetmap.josm.tools.CheckParameterUtil; 25 25 26 public class RelationMemberEditorModel extends AbstractTableModel{ 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 } 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 26 public class RelationMemberEditorModel extends AbstractTableModel{ 27 static private final Logger logger = Logger.getLogger(RelationMemberEditorModel.class.getName()); 28 private final ArrayList<RelationMemberModel> members = new ArrayList<RelationMemberModel>(); 29 private OsmDataLayer layer; 30 private DefaultListSelectionModel rowSelectionModel; 31 private DefaultListSelectionModel colSelectionModel; 32 33 /** 34 * Creates a new model in the context of an {@see OsmDataLayer}. Internally allocates 35 * a row and a column selection model, see {@see #getRowSelectionModel()} and 36 * {@see #getColSelectionModel()}. 37 * 38 * @param layer the data layer. Must not be null. 39 * @exception IllegalArgumentException thrown if layer is null 40 */ 41 public RelationMemberEditorModel(OsmDataLayer layer) throws IllegalArgumentException{ 42 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 43 this.layer = layer; 44 rowSelectionModel = new DefaultListSelectionModel(); 45 colSelectionModel = new DefaultListSelectionModel(); 46 } 47 48 /** 49 * Creates a new model in the context of an {@see OsmDataLayer} 50 * 51 * @param layer layer the data layer. Must not be null. 52 * @param rowSelectionModel the row selection model. Must not be null. 53 * @param colSelectionModel the column selection model. Must not be null. 54 * @throws IllegalArgumentException thrown if layer is null 55 * @throws IllegalArgumentException thrown if rowSelectionModel is null 56 * @throws IllegalArgumentException thrown if colSelectionModel is null 57 */ 58 public RelationMemberEditorModel(OsmDataLayer layer, DefaultListSelectionModel rowSelectionModel, DefaultListSelectionModel colSelectionModel) throws IllegalArgumentException{ 59 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 60 CheckParameterUtil.ensureParameterNotNull(rowSelectionModel, "rowSelectionModel"); 61 CheckParameterUtil.ensureParameterNotNull(colSelectionModel, "colSelectionModel"); 62 this.layer = layer; 63 this.rowSelectionModel = rowSelectionModel; 64 this.colSelectionModel = colSelectionModel; 65 } 66 67 /** 68 * Replies the row selection model used in this table model. 69 * 70 * @return the row selection model 71 */ 72 public DefaultListSelectionModel getRowSelectionModel() { 73 return rowSelectionModel; 74 } 75 76 /** 77 * Replies the column selection model used in this table model. 78 * 79 * @return the col selection model 80 */ 81 public DefaultListSelectionModel getColSelectionModel() { 82 return colSelectionModel; 83 } 84 85 /** 86 * Replies the set of {@see OsmPrimitive}s with the role {@code role}. If no 87 * such primitives exists, the empty set is returned. 88 * 89 * @return the set of {@see OsmPrimitive}s with the role {@code role} 90 */ 91 protected Set<OsmPrimitive> getPrimitivesWithRole(String role) { 92 HashSet<OsmPrimitive> ret = new HashSet<OsmPrimitive>(); 93 for (RelationMemberModel rm: members){ 94 if (rm.getRole().equals(role)){ 95 OsmPrimitive p = layer.data.getPrimitiveById(rm.getTarget()); 96 if (p != null){ 97 ret.add(p); 98 } 99 } 100 } 101 return ret; 102 } 103 104 /** 105 * Replies the list of {@see RelationMemberModel}s with the role {@code role}. If no 106 * such primitives exists, the empty set is returned. 107 * 108 * @return the set of {@see RelationMemberModel}s with the role {@code role} 109 */ 110 protected List<RelationMemberModel> getRelationMembersWithRole(String role) { 111 ArrayList<RelationMemberModel> ret = new ArrayList<RelationMemberModel>(); 112 for (RelationMemberModel rm: members){ 113 if (rm.getRole().equals(role)){ 114 ret.add(rm); 115 } 116 } 117 return ret; 118 } 119 120 /** 121 * Removes all members with role {@code role}. 122 * 123 * @param role the role. Ignored if null. 124 * @return true if the list of members was modified; false, otherwise 125 */ 126 protected boolean removeMembersWithRole(String role){ 127 if (role == null) return false; 128 boolean isChanged = false; 129 for(Iterator<RelationMemberModel> it = members.iterator(); it.hasNext(); ){ 130 RelationMemberModel rm = it.next(); 131 if (rm.getRole().equals(role)) { 132 it.remove(); 133 isChanged = true; 134 } 135 } 136 return isChanged; 137 } 138 139 /** 140 * Replies the set of {@see OsmPrimitive}s with the role 'from'. If no 141 * such primitives exists, the empty set is returned. 142 * 143 * @return the set of {@see OsmPrimitive}s with the role 'from' 144 */ 145 public Set<OsmPrimitive> getFromPrimitives() { 146 return getPrimitivesWithRole("from"); 147 } 148 149 /** 150 * Replies the set of {@see OsmPrimitive}s with the role 'to'. If no 151 * such primitives exists, the empty set is returned. 152 * 153 * @return the set of {@see OsmPrimitive}s with the role 'from' 154 */ 155 public Set<OsmPrimitive> getToPrimitives() { 156 return getPrimitivesWithRole("to"); 157 } 158 159 /** 160 * Replies the list of 'via' objects in the order they occur in the 161 * member list. Replies an empty list if no vias exist 162 * 163 * @return 164 */ 165 public List<OsmPrimitive> getVias() { 166 ArrayList<OsmPrimitive> ret = new ArrayList<OsmPrimitive>(); 167 for (RelationMemberModel rm: getRelationMembersWithRole("via")){ 168 ret.add(layer.data.getPrimitiveById(rm.getTarget())); 169 } 170 return ret; 171 } 172 173 /** 174 * Sets the list of vias. Removes all 'vias' if {@code vias} is null. 175 * 176 * null vias are skipped. A via must belong to the dataset of the layer in whose context 177 * this editor is working, otherwise an {@see IllegalArgumentException} is thrown. 178 * 179 * @param vias the vias. 180 * @exception IllegalArgumentException thrown if a via doesn't belong to the dataset of the layer 181 * in whose context this editor is working 182 */ 183 public void setVias(List<OsmPrimitive> vias) throws IllegalArgumentException{ 184 boolean viasDeleted = removeMembersWithRole("via"); 185 if (vias == null || vias.isEmpty()){ 186 if (viasDeleted){ 187 fireTableDataChanged(); 188 } 189 return; 190 } 191 // check vias 192 for (OsmPrimitive via: vias) { 193 if (via == null) continue; 194 if (via.getDataSet() == null || via.getDataSet() != layer.data){ 195 throw new IllegalArgumentException(MessageFormat.format("via object ''{0}'' must belong to dataset of layer ''{1}''", via.getDisplayName(DefaultNameFormatter.getInstance()), layer.getName())); 196 } 197 } 198 // add vias 199 for (OsmPrimitive via: vias) { 200 if (via == null) continue; 201 RelationMemberModel model = new RelationMemberModel("via", via); 202 members.add(model); 203 } 204 fireTableDataChanged(); 205 } 206 207 /** 208 * Sets the turn restriction member with role {@code role}. Removes all 209 * members with role {@code role} if {@code id} is null. 210 * 211 * @param id the id 212 * @return true if the model was modified; false, otherwise 213 */ 214 protected boolean setPrimitiveWithRole(PrimitiveId id, String role){ 215 if (id == null){ 216 return removeMembersWithRole(role); 217 } 218 219 List<RelationMemberModel> fromMembers = getRelationMembersWithRole(role); 220 if (fromMembers.isEmpty()){ 221 RelationMemberModel rm = new RelationMemberModel(role, id); 222 members.add(rm); 223 return true; 224 } else if (fromMembers.size() == 1){ 225 RelationMemberModel rm = fromMembers.get(0); 226 if (!rm.getTarget().equals(id)){ 227 rm.setTarget(id); 228 return true; 229 } 230 return false; 231 } else { 232 removeMembersWithRole(role); 233 RelationMemberModel rm = new RelationMemberModel(role, id); 234 members.add(rm); 235 return true; 236 } 237 } 238 239 /** 240 * Sets the turn restriction member with role 'from'. Removes all 241 * members with role 'from' if {@code id} is null. 242 * 243 * @param id the id 244 */ 245 public void setFromPrimitive(PrimitiveId id){ 246 if (setPrimitiveWithRole(id, "from")) { 247 fireTableDataChanged(); 248 } 249 } 250 251 /** 252 * Sets the turn restriction member with role 'to'. Removes all 253 * members with role 'to' if {@code id} is null. 254 * 255 * @param id the id 256 */ 257 public void setToPrimitive(PrimitiveId id){ 258 if (setPrimitiveWithRole(id, "to")) { 259 fireTableDataChanged(); 260 } 261 } 262 263 /** 264 * Replies the set of {@see OsmPrimitive}s referred to by members in 265 * this model. 266 * 267 * @return the set of {@see OsmPrimitive}s referred to by members in 268 * this model. 269 */ 270 public Set<OsmPrimitive> getMemberPrimitives() { 271 Set<OsmPrimitive> ret = new HashSet<OsmPrimitive>(); 272 for (RelationMemberModel rm: members){ 273 OsmPrimitive p = layer.data.getPrimitiveById(rm.getTarget()); 274 if (p != null) ret.add(p); 275 } 276 return ret; 277 } 278 279 /** 280 * Populates the model with the relation member of a turn restriction. Clears 281 * the model if {@code tr} is null. 282 * 283 * @param tr the turn restriction 284 */ 285 public void populate(Relation tr){ 286 members.clear(); 287 if (tr == null){ 288 fireTableDataChanged(); 289 return; 290 } 291 for(RelationMember rm: tr.getMembers()){ 292 members.add(new RelationMemberModel(rm)); 293 } 294 fireTableDataChanged(); 295 } 296 297 /** 298 * Replaces the member of turn restriction {@code tr} by the relation members currently 299 * edited in this model. 300 * 301 * @param tr the turn restriction. Ignored if null. 302 */ 303 public void applyTo(Relation tr){ 304 if (tr == null) return; 305 List<RelationMember> newMembers = new ArrayList<RelationMember>(); 306 for(RelationMemberModel model: members){ 307 RelationMember rm = new RelationMember(model.getRole(), layer.data.getPrimitiveById(model.getTarget())); 308 newMembers.add(rm); 309 } 310 tr.setMembers(newMembers); 311 } 312 313 /** 314 * Clears the roles of all relation members currently selected in the 315 * table. 316 */ 317 protected void clearSelectedRoles(){ 318 for(int i=0; i < getRowCount();i++){ 319 if (rowSelectionModel.isSelectedIndex(i)) { 320 members.get(i).setRole(""); 321 } 322 } 323 } 324 325 /** 326 * Removes the currently selected rows from the model 327 */ 328 protected void removedSelectedMembers() { 329 for(int i=getRowCount()-1; i >= 0;i--){ 330 if (rowSelectionModel.isSelectedIndex(i)) { 331 members.remove(i); 332 } 333 } 334 } 335 336 /** 337 * Deletes the current selection. 338 * 339 * If only cells in the first column are selected, the roles of the selected 340 * members are reset to the empty string. Otherwise the selected members are 341 * removed from the model. 342 * 343 */ 344 public void deleteSelected() { 345 if (colSelectionModel.isSelectedIndex(0) && !colSelectionModel.isSelectedIndex(1)) { 346 clearSelectedRoles(); 347 } else if (rowSelectionModel.getMinSelectionIndex() >= 0){ 348 removedSelectedMembers(); 349 } 350 fireTableDataChanged(); 351 } 352 353 protected List<Integer> getSelectedIndices() { 354 ArrayList<Integer> ret = new ArrayList<Integer>(); 355 for(int i =0; i < members.size(); i++){ 356 if (rowSelectionModel.isSelectedIndex(i)) 357 ret.add(i); 358 } 359 return ret; 360 } 361 362 public boolean canMoveUp() { 363 List<Integer> sel = getSelectedIndices(); 364 if (sel.isEmpty()) return false; 365 return sel.get(0) > 0; 366 } 367 368 public boolean canMoveDown() { 369 List<Integer> sel = getSelectedIndices(); 370 if (sel.isEmpty()) return false; 371 return sel.get(sel.size()-1) < members.size()-1; 372 } 373 374 public void moveUpSelected() { 375 if (!canMoveUp()) return; 376 List<Integer> sel = getSelectedIndices(); 377 for (int idx: sel){ 378 RelationMemberModel m = members.remove(idx); 379 members.add(idx-1, m); 380 } 381 fireTableDataChanged(); 382 rowSelectionModel.clearSelection(); 383 colSelectionModel.setSelectionInterval(0, 1); 384 for (int idx: sel){ 385 rowSelectionModel.addSelectionInterval(idx-1, idx-1); 386 } 387 } 388 389 public void moveDownSelected() { 390 if (!canMoveDown()) return; 391 List<Integer> sel = getSelectedIndices(); 392 for (int i = sel.size()-1; i>=0;i--){ 393 int idx = sel.get(i); 394 RelationMemberModel m = members.remove(idx); 395 members.add(idx+1, m); 396 } 397 fireTableDataChanged(); 398 rowSelectionModel.clearSelection(); 399 colSelectionModel.setSelectionInterval(0, 1); 400 for (int idx: sel){ 401 rowSelectionModel.addSelectionInterval(idx+1, idx+1); 402 } 403 } 404 405 /** 406 * Inserts a list of new relation members with the empty role for the primitives 407 * with id in {@code ids}. Inserts the new primitives at the position of the first 408 * selected row. If no row is selected, at the end of the list. 409 * 410 * null values are skipped. If there is an id for which there is no primitive in the context 411 * layer, if the primitive is deleted or invisible, an {@see IllegalArgumentException} 412 * is thrown and nothing is inserted. 413 * 414 * @param ids the list of ids. Ignored if null. 415 * @throws IllegalArgumentException thrown if one of the ids can't be inserted 416 */ 417 public void insertMembers(Collection<PrimitiveId> ids) throws IllegalArgumentException { 418 if (ids == null) return; 419 ArrayList<RelationMemberModel> newMembers = new ArrayList<RelationMemberModel>(); 420 for (PrimitiveId id: ids){ 421 OsmPrimitive p = layer.data.getPrimitiveById(id); 422 if (p == null){ 423 throw new IllegalArgumentException(tr("Cannot find object with id ''{0}'' in layer ''{1}''", id.toString(), layer.getName())); 424 } 425 if (p.isDeleted() || ! p.isVisible()) { 426 throw new IllegalArgumentException(tr("Cannot add object ''{0}'' as relation member because it is deleted or invisible in layer ''{1}''", p.getDisplayName(DefaultNameFormatter.getInstance()), layer.getName())); 427 } 428 newMembers.add(new RelationMemberModel("",id)); 429 } 430 if (newMembers.isEmpty()) return; 431 int insertPos = rowSelectionModel.getMinSelectionIndex(); 432 if ( insertPos >=0){ 433 members.addAll(insertPos, newMembers); 434 } else { 435 members.addAll(newMembers); 436 } 437 fireTableDataChanged(); 438 if (insertPos < 0) insertPos = 0; 439 colSelectionModel.setSelectionInterval(0, 1); // select both columns 440 rowSelectionModel.setSelectionInterval(insertPos, insertPos + newMembers.size()-1); 441 } 442 443 public int getColumnCount() { 444 return 2; 445 } 446 447 public int getRowCount() { 448 if (members.size() > 0) return members.size(); 449 450 // we display an empty row if the model is empty because otherwise 451 // we can't drag/drop into the empty table. 452 // FIXME: use JTable.setFillsViewportHeight(boolean) after the migration 453 // to Java 6. 454 return 1; 455 } 456 457 public Object getValueAt(int rowIndex, int columnIndex) { 458 if (members.size() == 0 && rowIndex == 0){ 459 // we display an empty row if the model is empty because otherwise 460 // we can't drag/drop into the empty table. 461 // FIXME: use JTable.setFillsViewportHeight(boolean) after the migration 462 // to Java 6. 463 return null; 464 } 465 switch(columnIndex){ 466 case 0: return members.get(rowIndex).getRole(); 467 case 1: return layer.data.getPrimitiveById(members.get(rowIndex).getTarget()); 468 } 469 return null; 470 } 471 472 @Override 473 public boolean isCellEditable(int rowIndex, int columnIndex) { 474 // we display an empty row if the model is empty because otherwise 475 // we can't drag/drop into the empty table. This row isn't editable 476 // FIXME: use JTable.setFillsViewportHeight(boolean) after the migration 477 // to Java 6. 478 if (members.size() == 0 && rowIndex == 0) return false; 479 480 // otherwise only the column with the member roles is editable 481 return columnIndex == 0; 482 } 483 484 @Override 485 public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 486 if (columnIndex !=0)return; 487 String role = (String)aValue; 488 RelationMemberModel model = members.get(rowIndex); 489 model.setRole(role); 490 fireTableCellUpdated(rowIndex, columnIndex); 491 } 492 492 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberModel.java
r20527 r23192 16 16 */ 17 17 public class RelationMemberModel implements Serializable{ 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 18 private String role; 19 private SimplePrimitiveId target; 20 21 /** 22 * Creates a new relation member model 23 * 24 * @param role the member role. Reset to "" if null. 25 * @param target the id of the target object. Must not be null. 26 * @throws IllegalArgumentException thrown if {@code target} is null 27 */ 28 public RelationMemberModel(String role, PrimitiveId target) throws IllegalArgumentException { 29 CheckParameterUtil.ensureParameterNotNull(target, "target"); 30 this.role = role == null? "" : role; 31 this.target = new SimplePrimitiveId(target.getUniqueId(), target.getType()); 32 } 33 34 /** 35 * Creates a new relation member model from a relation member 36 * 37 * @param member the relation member. Must not be null. 38 * @throws IllegalArgumentException thrown if {@code member} is null 39 */ 40 public RelationMemberModel(RelationMember member) throws IllegalArgumentException{ 41 CheckParameterUtil.ensureParameterNotNull(member, "member"); 42 this.role = member.getRole(); 43 setTarget(member.getMember().getPrimitiveId()); 44 } 45 45 46 47 48 49 50 51 52 53 46 /** 47 * Replies the current role in this model. Never null. 48 * 49 * @return the current role in this model 50 */ 51 public String getRole() { 52 return role; 53 } 54 54 55 56 57 58 59 60 61 62 55 /** 56 * Sets the current role in this model. 57 * 58 * @param role the role. Reset to "" if null. 59 */ 60 public void setRole(String role) { 61 this.role = role == null? "" : role; 62 } 63 63 64 65 66 67 68 69 70 71 64 /** 65 * Replies the id of the target object of this relation member. 66 * 67 * @return the id of the target object of this relation member. 68 */ 69 public PrimitiveId getTarget() { 70 return target; 71 } 72 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 73 /** 74 * Sets the id of the target object. 75 * 76 * @param target the id of the target object. Must not be null. 77 * @throws IllegalArgumentException thrown if {@code target} is null 78 */ 79 public void setTarget(PrimitiveId target) throws IllegalArgumentException{ 80 CheckParameterUtil.ensureParameterNotNull(target, "target"); 81 this.target = new SimplePrimitiveId(target.getUniqueId(), target.getType()); 82 } 83 84 @Override 85 public int hashCode() { 86 final int prime = 31; 87 int result = 1; 88 result = prime * result + ((role == null) ? 0 : role.hashCode()); 89 result = prime * result + ((target == null) ? 0 : target.hashCode()); 90 return result; 91 } 92 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 93 @Override 94 public boolean equals(Object obj) { 95 if (this == obj) 96 return true; 97 if (obj == null) 98 return false; 99 if (getClass() != obj.getClass()) 100 return false; 101 RelationMemberModel other = (RelationMemberModel) obj; 102 if (role == null) { 103 if (other.role != null) 104 return false; 105 } else if (!role.equals(other.role)) 106 return false; 107 if (target == null) { 108 if (other.target != null) 109 return false; 110 } else if (!target.equals(other.target)) 111 return false; 112 return true; 113 } 114 114 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberRoleCellRenderer.java
r20724 r23192 10 10 public class RelationMemberRoleCellRenderer extends DefaultTableCellRenderer{ 11 11 private JLabel mockCell; 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 } 36 37 12 13 public RelationMemberRoleCellRenderer() { 14 mockCell = new JLabel(); 15 mockCell.setText(""); 16 mockCell.setOpaque(true); 17 } 18 19 public Component getTableCellRendererComponent(JTable table, Object value, 20 boolean isSelected, boolean hasFocus, int row, int column) { 21 if (value != null){ 22 return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 23 } 24 25 // FIXME: required to always draw a mock row, even if the table is empty. 26 // Otherwise, drag and drop onto the table fails. 27 // Replace with JTable.setFillsViewportHeight(boolean) after the migration 28 // to Java 6. 29 if (isSelected){ 30 mockCell.setBackground(UIManager.getColor("Table.selectionBackground")); 31 mockCell.setForeground(UIManager.getColor("Table.selectionForeground")); 32 } else { 33 mockCell.setBackground(UIManager.getColor("Panel.background")); 34 mockCell.setForeground(UIManager.getColor("Panel.foreground")); 35 } 36 return mockCell; 37 } 38 38 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberTable.java
r20675 r23192 46 46 */ 47 47 public class RelationMemberTable extends JTable { 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 48 static private final Logger logger = Logger.getLogger(RelationMemberTable.class.getName()); 49 50 private TurnRestrictionEditorModel model; 51 private DeleteAction actDelete; 52 private PasteAction actPaste; 53 private MoveUpAction actMoveUp; 54 private MoveDownAction actMoveDown; 55 private TransferHandler transferHandler; 56 57 public RelationMemberTable(TurnRestrictionEditorModel model) { 58 super( 59 model.getRelationMemberEditorModel(), 60 new RelationMemberColumnModel(model.getRelationMemberEditorModel().getColSelectionModel()), 61 model.getRelationMemberEditorModel().getRowSelectionModel() 62 ); 63 this.model = model; 64 setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 65 65 setRowSelectionAllowed(true); 66 66 setColumnSelectionAllowed(true); 67 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 } 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 } 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 } 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 } 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 } 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 68 // register the popup menu launcher 69 addMouseListener(new TablePopupLauncher()); 70 71 // transfer handling 72 setDragEnabled(true); 73 setTransferHandler(new RelationMemberTransferHandler()); 74 setDropTarget(new RelationMemberTableDropTarget()); 75 76 // initialize the delete action 77 // 78 actDelete = new DeleteAction(); 79 model.getRelationMemberEditorModel().getRowSelectionModel().addListSelectionListener(actDelete); 80 registerKeyboardAction(actDelete, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0), WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 81 82 // initialize the paste action (will be used in the popup, the action map already includes 83 // the standard paste action for transfer handling) 84 actPaste = new PasteAction(); 85 86 actMoveUp = new MoveUpAction(); 87 model.getRelationMemberEditorModel().getRowSelectionModel().addListSelectionListener(actMoveUp); 88 registerKeyboardAction(actMoveUp,actMoveUp.getKeyStroke(), WHEN_FOCUSED); 89 90 actMoveDown = new MoveDownAction(); 91 model.getRelationMemberEditorModel().getRowSelectionModel().addListSelectionListener(actMoveDown); 92 registerKeyboardAction(actMoveDown, actMoveDown.getKeyStroke(), WHEN_FOCUSED); 93 } 94 95 /** 96 * The action for deleting the selected table cells 97 * 98 */ 99 class DeleteAction extends AbstractAction implements ListSelectionListener{ 100 public DeleteAction() { 101 putValue(NAME, tr("Delete")); 102 putValue(SHORT_DESCRIPTION, tr("Clear the selected roles or delete the selected members")); 103 putValue(SMALL_ICON, ImageProvider.get("deletesmall")); 104 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0)); 105 updateEnabledState(); 106 } 107 108 public void updateEnabledState() { 109 setEnabled(model.getRelationMemberEditorModel().getRowSelectionModel().getMinSelectionIndex()>=0); 110 } 111 112 public void actionPerformed(ActionEvent e) { 113 model.getRelationMemberEditorModel().deleteSelected(); 114 } 115 116 public void valueChanged(ListSelectionEvent e) { 117 updateEnabledState(); 118 } 119 } 120 121 /** 122 * The action for pasting into the relation member table 123 * 124 */ 125 class PasteAction extends AbstractAction{ 126 public PasteAction() { 127 putValue(NAME, tr("Paste")); 128 putValue(SHORT_DESCRIPTION, tr("Insert new relation members from object in the clipboard")); 129 putValue(SMALL_ICON, ImageProvider.get("paste")); 130 putValue(ACCELERATOR_KEY, Shortcut.getPasteKeyStroke()); 131 updateEnabledState(); 132 } 133 134 public void updateEnabledState() { 135 DataFlavor[] flavors = Toolkit.getDefaultToolkit().getSystemClipboard().getAvailableDataFlavors(); 136 setEnabled(PrimitiveIdListTransferHandler.isSupportedFlavor(flavors)); 137 } 138 139 public void actionPerformed(ActionEvent evt) { 140 // tried to delegate to 'paste' action in the action map of the 141 // table, but didn't work. Now duplicating the logic of importData(...) in 142 // the transfer handler. 143 // 144 Clipboard cp = Toolkit.getDefaultToolkit().getSystemClipboard(); 145 if (!PrimitiveIdListTransferHandler.isSupportedFlavor(cp.getAvailableDataFlavors())) return; 146 try { 147 List<PrimitiveId> ids; 148 ids = (List<PrimitiveId>)cp.getData(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR); 149 try { 150 model.getRelationMemberEditorModel().insertMembers(ids); 151 } catch(IllegalArgumentException e){ 152 e.printStackTrace(); 153 // FIXME: provide user feedback 154 } 155 } catch(IOException e){ 156 e.printStackTrace(); 157 } catch(UnsupportedFlavorException e){ 158 e.printStackTrace(); 159 } 160 } 161 } 162 163 class MoveDownAction extends AbstractAction implements ListSelectionListener{ 164 private KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_DOWN_MASK); 165 public MoveDownAction(){ 166 putValue(NAME, tr("Move down")); 167 putValue(SHORT_DESCRIPTION, tr("Move the selected relation members down by one position")); 168 putValue(ACCELERATOR_KEY,keyStroke); 169 putValue(SMALL_ICON, ImageProvider.get("dialogs", "movedown")); 170 updateEnabledState(); 171 } 172 173 public void actionPerformed(ActionEvent e) { 174 model.getRelationMemberEditorModel().moveDownSelected(); 175 } 176 177 public void updateEnabledState(){ 178 setEnabled(model.getRelationMemberEditorModel().canMoveDown()); 179 } 180 181 public void valueChanged(ListSelectionEvent e) { 182 updateEnabledState(); 183 } 184 public KeyStroke getKeyStroke() { 185 return keyStroke; 186 } 187 } 188 189 class MoveUpAction extends AbstractAction implements ListSelectionListener{ 190 private KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_DOWN_MASK); 191 192 public MoveUpAction() { 193 putValue(NAME, tr("Move up")); 194 putValue(SHORT_DESCRIPTION, tr("Move the selected relation members up by one position")); 195 putValue(ACCELERATOR_KEY,keyStroke); 196 putValue(SMALL_ICON, ImageProvider.get("dialogs", "moveup")); 197 updateEnabledState(); 198 } 199 200 public void actionPerformed(ActionEvent e) { 201 model.getRelationMemberEditorModel().moveUpSelected(); 202 } 203 204 public void updateEnabledState(){ 205 setEnabled(model.getRelationMemberEditorModel().canMoveUp()); 206 } 207 208 public void valueChanged(ListSelectionEvent e) { 209 updateEnabledState(); 210 } 211 public KeyStroke getKeyStroke() { 212 return keyStroke; 213 } 214 } 215 216 class TablePopupLauncher extends PopupMenuLauncher { 217 @Override 218 public void launch(MouseEvent evt) { 219 int row = rowAtPoint(evt.getPoint()); 220 if (getSelectionModel().getMinSelectionIndex() < 0 && row >=0){ 221 getSelectionModel().setSelectionInterval(row, row); 222 getColumnModel().getSelectionModel().setSelectionInterval(0, 1); 223 } 224 new PopupMenu().show(RelationMemberTable.this, evt.getX(), evt.getY()); 225 } 226 } 227 228 class PopupMenu extends JPopupMenu { 229 public PopupMenu() { 230 JMenuItem item = add(actPaste); 231 item.setTransferHandler(transferHandler); 232 actPaste.updateEnabledState(); 233 addSeparator(); 234 add(actDelete); 235 addSeparator(); 236 add(actMoveUp); 237 add(actMoveDown); 238 } 239 } 240 241 /** 242 * The transfer handler for the relation member table. 243 * 244 */ 245 class RelationMemberTransferHandler extends TransferHandler { 246 247 @Override 248 public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { 249 return PrimitiveIdListTransferHandler.isSupportedFlavor(transferFlavors); 250 } 251 252 @Override 253 public boolean importData(JComponent comp, Transferable t) { 254 try { 255 List<PrimitiveId> ids; 256 ids = (List<PrimitiveId>)t.getTransferData(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR); 257 try { 258 model.getRelationMemberEditorModel().insertMembers(ids); 259 } catch(IllegalArgumentException e){ 260 e.printStackTrace(); 261 // FIXME: provide user feedback 262 return false; 263 } 264 return true; 265 } catch(IOException e){ 266 e.printStackTrace(); 267 } catch(UnsupportedFlavorException e){ 268 e.printStackTrace(); 269 } 270 return false; 271 } 272 273 @Override 274 public int getSourceActions(JComponent c) { 275 return COPY_OR_MOVE; 276 } 277 } 278 279 /** 280 * A custom drop target for the relation member table. During dragging we need to 281 * disable colum selection model. 282 * 283 */ 284 class RelationMemberTableDropTarget extends DropTarget{ 285 private boolean dropAccepted = false; 286 287 /** 288 * Replies true if {@code transferFlavors} includes the data flavor {@see PrimitiveIdTransferable#PRIMITIVE_ID_LIST_FLAVOR}. 289 290 * @param transferFlavors an array of transferFlavors 291 * @return 292 */ 293 protected boolean isSupportedFlavor(DataFlavor[] transferFlavors) { 294 for (DataFlavor df: transferFlavors) { 295 if (df.equals(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR)) return true; 296 } 297 return false; 298 } 299 300 public synchronized void dragEnter(DropTargetDragEvent dtde) { 301 if (isSupportedFlavor(dtde.getCurrentDataFlavors())) { 302 if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY_OR_MOVE) != 0){ 303 dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); 304 setColumnSelectionAllowed(false); 305 dropAccepted = true; 306 } else { 307 dtde.rejectDrag(); 308 } 309 } else { 310 dtde.rejectDrag(); 311 } 312 } 313 314 public synchronized void dragExit(DropTargetEvent dte) { 315 setColumnSelectionAllowed(true); 316 dropAccepted = false; 317 } 318 319 @Override 320 public synchronized void dragOver(DropTargetDragEvent dtde) { 321 int row = rowAtPoint(dtde.getLocation()); 322 int selectedRow = getSelectionModel().getMinSelectionIndex(); 323 if (row >= 0 && row != selectedRow){ 324 getSelectionModel().setSelectionInterval(row, row); 325 } 326 } 327 328 public synchronized void drop(DropTargetDropEvent dtde) { 329 try { 330 if (!dropAccepted) return; 331 if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY_OR_MOVE) == 0) { 332 return; 333 } 334 List<PrimitiveId> ids; 335 ids = (List<PrimitiveId>)dtde.getTransferable().getTransferData(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR); 336 try { 337 model.getRelationMemberEditorModel().insertMembers(ids); 338 } catch(IllegalArgumentException e){ 339 e.printStackTrace(); 340 // FIXME: provide user feedback 341 } 342 } catch(IOException e){ 343 e.printStackTrace(); 344 } catch(UnsupportedFlavorException e){ 345 e.printStackTrace(); 346 } finally { 347 setColumnSelectionAllowed(true); 348 } 349 } 350 351 public synchronized void dropActionChanged(DropTargetDragEvent dtde) { 352 if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY_OR_MOVE) == 0) { 353 dtde.rejectDrag(); 354 } else { 355 dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); 356 } 357 } 358 } 359 359 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberTargetCellRenderer.java
r20724 r23192 11 11 12 12 public class RelationMemberTargetCellRenderer extends OsmPrimitivRenderer{ 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 } 40 41 13 static private final Logger logger = Logger.getLogger(RelationMemberTargetCellRenderer.class.getName()); 14 private JLabel mockCell; 15 16 public RelationMemberTargetCellRenderer() { 17 mockCell = new JLabel(); 18 mockCell.setText(""); 19 mockCell.setOpaque(true); 20 } 21 22 @Override 23 public Component getTableCellRendererComponent(JTable table, Object value, 24 boolean isSelected, boolean hasFocus, int row, int column) { 25 if (value != null){ 26 return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 27 } 28 29 // FIXME: required to always draw a mock row, even if the table is empty. 30 // Otherwise, drag and drop onto the table fails. 31 // Replace with JTable.setFillsViewportHeight(boolean) after the migration 32 // to Java 6. 33 if (isSelected){ 34 mockCell.setBackground(UIManager.getColor("Table.selectionBackground")); 35 mockCell.setForeground(UIManager.getColor("Table.selectionForeground")); 36 } else { 37 mockCell.setBackground(UIManager.getColor("Panel.background")); 38 mockCell.setForeground(UIManager.getColor("Panel.foreground")); 39 } 40 return mockCell; 41 } 42 42 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionComboBox.java
r20666 r23192 9 9 */ 10 10 public class TurnRestrictionComboBox extends JComboBox{ 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 11 12 /** 13 * Constructor 14 * 15 * @param model the combo box model. Must not be null. 16 */ 17 public TurnRestrictionComboBox(TurnRestrictionComboBoxModel model){ 18 super(model); 19 setEditable(false); 20 setRenderer(new TurnRestrictionTypeRenderer()); 21 } 22 23 /** 24 * Replies the turn restriction combo box model 25 * 26 * @return the turn restriction combo box model 27 */ 28 public TurnRestrictionComboBoxModel getTurnRestrictionComboBoxModel() { 29 return (TurnRestrictionComboBoxModel)getModel(); 30 } 31 32 /** 33 * Initializes the set of icons used from the preference key 34 * {@see PreferenceKeys#ROAD_SIGNS}. 35 * 36 * @param prefs the JOSM preferences 37 */ 38 public void initIconSetFromPreferences(Preferences prefs){ 39 TurnRestrictionTypeRenderer renderer = (TurnRestrictionTypeRenderer)getRenderer(); 40 renderer.initIconSetFromPreferences(prefs); 41 repaint(); 42 } 43 43 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionComboBoxModel.java
r20606 r23192 21 21 */ 22 22 public class TurnRestrictionComboBoxModel implements ComboBoxModel, Observer{ 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 } 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 23 static private final Logger logger = Logger.getLogger(TurnRestrictionComboBoxModel.class.getName()); 24 25 private TurnRestrictionEditorModel model; 26 final private List<Object> values = new ArrayList<Object>(); 27 private String selectedTagValue = null; 28 private final transient EventListenerList listeners = new EventListenerList(); 29 30 /** 31 * Populates the model with the list of standard values. If the 32 * data contains a non-standard value it is displayed in the combo 33 * box as an additional element. 34 */ 35 protected void populate() { 36 values.clear(); 37 for (TurnRestrictionType type: TurnRestrictionType.values()) { 38 values.add(type); 39 } 40 41 String tagValue = model.getRestrictionTagValue(); 42 if (tagValue.trim().equals("")) { 43 selectedTagValue = null; 44 } else { 45 TurnRestrictionType type = TurnRestrictionType.fromTagValue(tagValue); 46 if (type == null) { 47 values.add(0, tagValue); 48 selectedTagValue = tagValue; 49 } else { 50 selectedTagValue = type.getTagValue(); 51 } 52 } 53 fireContentsChanged(); 54 } 55 56 /** 57 * Creates the combo box model. 58 * 59 * @param model the turn restriction editor model. Must not be null. 60 */ 61 public TurnRestrictionComboBoxModel(TurnRestrictionEditorModel model){ 62 CheckParameterUtil.ensureParameterNotNull(model, "model"); 63 this.model = model; 64 model.addObserver(this); 65 populate(); 66 } 67 67 68 69 70 71 72 68 public Object getSelectedItem() { 69 TurnRestrictionType type = TurnRestrictionType.fromTagValue(selectedTagValue); 70 if (type != null) return type; 71 return selectedTagValue; 72 } 73 73 74 75 76 77 78 79 80 81 82 74 public void setSelectedItem(Object anItem) { 75 String tagValue = null; 76 if (anItem instanceof String) { 77 tagValue = (String)anItem; 78 } else if (anItem instanceof TurnRestrictionType){ 79 tagValue = ((TurnRestrictionType)anItem).getTagValue(); 80 } 81 model.setRestrictionTagValue(tagValue); 82 } 83 83 84 85 86 84 public Object getElementAt(int index) { 85 return values.get(index); 86 } 87 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 88 public int getSize() { 89 return values.size(); 90 } 91 92 public void addListDataListener(ListDataListener l) { 93 listeners.add(ListDataListener.class, l); 94 } 95 96 public void removeListDataListener(ListDataListener l) { 97 listeners.remove(ListDataListener.class, l); 98 } 99 100 protected void fireContentsChanged() { 101 for(ListDataListener l: listeners.getListeners(ListDataListener.class)) { 102 l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, getSize())); 103 } 104 } 105 106 /* ------------------------------------------------------------------------------------ */ 107 /* interface Observer */ 108 /* ------------------------------------------------------------------------------------ */ 109 public void update(Observable o, Object arg) { 110 String tagValue = model.getRestrictionTagValue(); 111 if (tagValue == null && selectedTagValue != null) { 112 populate(); 113 } else if (tagValue != null && selectedTagValue == null){ 114 populate(); 115 } else if (tagValue != null) { 116 if (!tagValue.equals(selectedTagValue)) { 117 populate(); 118 } 119 } 120 } 121 121 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditor.java
r20916 r23192 58 58 59 59 public class TurnRestrictionEditor extends JDialog implements NavigationControler{ 60 61 60 final private static Logger logger = Logger.getLogger(TurnRestrictionEditor.class.getName()); 61 62 62 /** the property name for the current turn restriction 63 63 * @see #setRelation(Relation) … … 84 84 /** the data layer the turn restriction belongs to */ 85 85 private OsmDataLayer layer; 86 86 87 87 private JosmSelectionPanel pnlJosmSelection; 88 88 private BasicEditorPanel pnlBasicEditor; … … 114 114 */ 115 115 protected JPanel buildJOSMSelectionPanel() { 116 117 116 pnlJosmSelection = new JosmSelectionPanel(layer); 117 return pnlJosmSelection; 118 118 } 119 119 … … 125 125 */ 126 126 protected JPanel buildEditorPanel() { 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 127 JPanel pnl = new JPanel(new BorderLayout()); 128 tpEditors = new JTabbedPane(); 129 JScrollPane pane = new JScrollPane(pnlBasicEditor =new BasicEditorPanel(editorModel)); 130 pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 131 pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 132 tpEditors.add(pane); 133 tpEditors.setTitleAt(0, tr("Basic")); 134 tpEditors.setToolTipTextAt(0, tr("Edit basic attributes of a turn restriction")); 135 136 tpEditors.add(pnlAdvancedEditor = new AdvancedEditorPanel(editorModel)); 137 tpEditors.setTitleAt(1, tr("Advanced")); 138 tpEditors.setToolTipTextAt(1, tr("Edit the raw tags and members of this turn restriction")); 139 140 tpEditors.add(pnlIssuesView = new IssuesView(editorModel.getIssuesModel())); 141 tpEditors.setTitleAt(2, tr("Errors/Warnings")); 142 tpEditors.setToolTipTextAt(2, tr("Show errors and warnings related to this turn restriction")); 143 144 pnl.add(tpEditors, BorderLayout.CENTER); 145 return pnl; 146 146 } 147 147 … … 153 153 */ 154 154 protected JPanel buildContentPanel() { 155 156 157 158 159 155 JPanel pnl = new JPanel(new BorderLayout()); 156 final JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); 157 pnl.add(sp, BorderLayout.CENTER); 158 sp.setLeftComponent(buildEditorPanel()); 159 sp.setRightComponent(buildJOSMSelectionPanel()); 160 160 addWindowListener(new WindowAdapter() { 161 161 @Override … … 167 167 }); 168 168 169 169 return pnl; 170 170 } 171 171 … … 197 197 * builds the UI 198 198 */ 199 protected void build() { 200 201 202 203 204 205 206 207 208 199 protected void build() { 200 editorModel = new TurnRestrictionEditorModel(getLayer(), this); 201 Container c = getContentPane(); 202 c.setLayout(new BorderLayout()); 203 c.add(buildToolBar(), BorderLayout.NORTH); 204 c.add(buildContentPanel(), BorderLayout.CENTER); 205 c.add(buildOkCancelButtonPanel(), BorderLayout.SOUTH); 206 207 editorModel.getIssuesModel().addObserver(new IssuesModelObserver()); 208 setSize(600,600); 209 209 } 210 211 210 211 /** 212 212 * Creates a new turn restriction editor 213 213 * … … 216 216 * @throws IllegalArgumentException thrown if layer is null 217 217 */ 218 219 220 221 222 218 public TurnRestrictionEditor(Component owner, OsmDataLayer layer) { 219 this(owner, layer, null); 220 } 221 222 /** 223 223 * Creates a new turn restriction editor 224 224 * … … 229 229 */ 230 230 public TurnRestrictionEditor(Component owner, OsmDataLayer layer, Relation turnRestriction) throws IllegalArgumentException{ 231 231 super(JOptionPane.getFrameForComponent(owner),false /* not modal */); 232 232 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 233 233 this.layer = layer; … … 260 260 protected void setTurnRestriction(Relation turnRestriction) { 261 261 if (turnRestriction == null) { 262 262 editorModel.populate(new Relation()); 263 263 } else if (turnRestriction.getDataSet() == null || turnRestriction.getDataSet() == getLayer().data) { 264 264 editorModel.populate(turnRestriction); 265 265 } else { 266 266 throw new IllegalArgumentException(MessageFormat.format("turnRestriction must belong to layer ''{0}''", getLayer().getName())); 267 267 } 268 268 setTurnRestrictionSnapshot(turnRestriction == null ? null : new Relation(turnRestriction)); … … 332 332 */ 333 333 public TurnRestrictionEditorModel getModel() { 334 334 return editorModel; 335 335 } 336 336 337 337 public void setVisible(boolean visible) { 338 339 340 341 342 343 344 345 346 347 348 349 350 351 338 if (visible && ! isVisible()) { 339 pnlJosmSelection.wireListeners(); 340 editorModel.registerAsEventListener(); 341 Main.pref.addPreferenceChangeListener(this.preferenceChangeHandler = new PreferenceChangeHandler()); 342 pnlBasicEditor.initIconSetFromPreferences(Main.pref); 343 } else if (!visible && isVisible()) { 344 pnlJosmSelection.unwireListeners(); 345 editorModel.unregisterAsEventListener(); 346 Main.pref.removePreferenceChangeListener(preferenceChangeHandler); 347 } 348 super.setVisible(visible); 349 if (!visible){ 350 dispose(); 351 } 352 352 } 353 353 … … 371 371 /* ----------------------------------------------------------------------- */ 372 372 public void gotoBasicEditor() { 373 374 373 tpEditors.setSelectedIndex(0); 374 } 375 375 376 376 public void gotoAdvancedEditor() { 377 378 379 380 381 382 383 384 385 377 tpEditors.setSelectedIndex(1); 378 } 379 380 public void gotoBasicEditor(BasicEditorFokusTargets focusTarget) { 381 tpEditors.setSelectedIndex(0); 382 pnlBasicEditor.requestFocusFor(focusTarget); 383 } 384 385 /** 386 386 * The abstract base action for applying the updates of a turn restriction 387 387 * to the dataset. 388 388 */ 389 abstract class SavingAction extends AbstractAction { 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 );525 526 527 389 abstract class SavingAction extends AbstractAction { 390 protected boolean confirmSaveDespiteOfErrorsAndWarnings(){ 391 int numErrors = editorModel.getIssuesModel().getNumErrors(); 392 int numWarnings = editorModel.getIssuesModel().getNumWarnings(); 393 if (numErrors + numWarnings == 0) return true; 394 395 StringBuffer sb = new StringBuffer(); 396 sb.append("<html>"); 397 sb.append(trn( 398 "There is still an unresolved error or warning identified for this turn restriction. " 399 + "You are recommended to resolve this issue first.", 400 "There are still {0} errors and/or warnings identified for this turn restriction. " 401 + "You are recommended to resolve these issues first.", 402 numErrors + numWarnings, 403 numErrors + numWarnings 404 )); 405 sb.append("<br>"); 406 sb.append(tr("Do you want to save anyway?")); 407 ButtonSpec[] options = new ButtonSpec[] { 408 new ButtonSpec( 409 tr("Yes, save anyway"), 410 ImageProvider.get("ok"), 411 tr("Save the turn restriction despite of errors and/or warnings"), 412 null // no specific help topic 413 ), 414 new ButtonSpec( 415 tr("No, resolve issues first"), 416 ImageProvider.get("cancel"), 417 tr("Cancel saving and start resolving pending issues first"), 418 null // no specific help topic 419 ) 420 }; 421 422 int ret = HelpAwareOptionPane.showOptionDialog( 423 JOptionPane.getFrameForComponent(TurnRestrictionEditor.this), 424 sb.toString(), 425 tr("Pending errors and warnings"), 426 JOptionPane.WARNING_MESSAGE, 427 null, // no special icon 428 options, 429 options[1], // cancel is default operation 430 HelpUtil.ht("/Plugins/turnrestrictions#PendingErrorsAndWarnings") 431 ); 432 return ret == 0 /* OK */; 433 } 434 435 /** 436 * Replies the list of relation members in {@code r} which refer to 437 * a deleted or invisible primitives. 438 * 439 * @param r the relation 440 * @return the list of relation members in {@code r} which refer to 441 * a deleted or invisible member 442 */ 443 protected List<RelationMember> getDeletedRelationMembers(Relation r) { 444 List<RelationMember> ret = new ArrayList<RelationMember>(); 445 for(RelationMember rm: r.getMembers()) { 446 if (rm.getMember().isDeleted() || !rm.getMember().isVisible()) { 447 ret.add(rm); 448 } 449 } 450 return ret; 451 } 452 453 /** 454 * Removes all members referring to deleted or invisible primitives 455 * from the turn restriction {@code tr}. 456 * 457 * @param tr the turn restriction 458 */ 459 protected void removeDeletedMembers(Relation tr) { 460 List<RelationMember> members = tr.getMembers(); 461 for(Iterator<RelationMember> it = members.iterator(); it.hasNext();) { 462 RelationMember rm = it.next(); 463 if (rm.getMember().isDeleted() || !rm.getMember().isVisible()) { 464 it.remove(); 465 } 466 } 467 tr.setMembers(members); 468 } 469 470 /** 471 * Asks the user how to proceed if a turn restriction refers to deleted or invisible 472 * primitives. 473 * 474 * If this method returns true the respective members should be removed and the turn 475 * restriction should be saved anyway. If it replies false, the turn restriction must not 476 * be saved. 477 * 478 * @param deletedMembers the list of members referring to deleted or invisible primitives 479 * @return the confirmation 480 */ 481 protected boolean confirmSaveTurnRestrictionWithDeletePrimitives(List<RelationMember> deletedMembers) { 482 StringBuffer sb = new StringBuffer(); 483 sb.append("<html>"); 484 sb.append(trn("This turn restriction refers to an object which was deleted outside " 485 + "of this turn restriction editor:", 486 "This turn restriction refers to {0} which were deleted outside " 487 + "of this turn restriction editor:", deletedMembers.size(), deletedMembers.size())); 488 sb.append("<ul>"); 489 for(RelationMember rm: deletedMembers){ 490 sb.append("<li>"); 491 if (!rm.getRole().equals("")) { 492 sb.append(rm.getRole()).append(": "); 493 } 494 sb.append(rm.getMember().getDisplayName(DefaultNameFormatter.getInstance())); 495 sb.append("</li>"); 496 } 497 sb.append(tr("Updates to this turn restriction can''t be saved unless deleted members are removed.<br>" 498 + "How to you want to proceed?")); 499 500 ButtonSpec[] options = new ButtonSpec[] { 501 new ButtonSpec( 502 tr("Remove deleted members and save"), 503 ImageProvider.get("OK"), 504 tr("Remove deleted members and save"), 505 null 506 ), 507 new ButtonSpec( 508 tr("Cancel and return to editor"), 509 ImageProvider.get("cancel"), 510 tr("Cancel and return to editor"), 511 null 512 ) 513 }; 514 515 int ret = HelpAwareOptionPane.showOptionDialog( 516 TurnRestrictionEditor.this, 517 sb.toString(), 518 tr("Deleted members in turn restriction"), 519 JOptionPane.WARNING_MESSAGE, 520 null, // no special icon 521 options, 522 options[1], // cancel is default 523 null // FIXME: provide help topic 524 ); 525 return ret == 0 /* OK button */; 526 } 527 528 528 /** 529 529 * apply updates to a new turn restriction 530 530 */ 531 protected boolean applyNewTurnRestriction() { 531 protected boolean applyNewTurnRestriction() { 532 532 Relation newTurnRestriction = new Relation(); 533 533 editorModel.apply(newTurnRestriction); … … 541 541 List<RelationMember> deletedMembers = getDeletedRelationMembers(newTurnRestriction); 542 542 if (!deletedMembers.isEmpty()) { 543 544 545 546 543 if (!confirmSaveTurnRestrictionWithDeletePrimitives(deletedMembers)) { 544 return false; 545 } 546 removeDeletedMembers(newTurnRestriction); 547 547 } 548 548 … … 576 576 * outside of the turn restriction editor. 577 577 */ 578 protected void applyExistingNonConflictingTurnRestriction() { 578 protected void applyExistingNonConflictingTurnRestriction() { 579 579 if (getTurnRestriction().getDataSet() == null) { 580 581 580 editorModel.apply(getTurnRestriction()); 581 Main.main.undoRedo.add(new AddCommand(getTurnRestriction())); 582 582 } else { 583 583 Relation toUpdate = new Relation(getTurnRestriction()); 584 584 editorModel.apply(toUpdate); 585 585 Main.main.undoRedo.add(new ChangeCommand(getTurnRestriction(), toUpdate)); 586 586 } 587 587 // this will refresh the snapshot and update the dialog title … … 646 646 647 647 public void run() { 648 649 650 651 648 if (!confirmSaveDespiteOfErrorsAndWarnings()){ 649 tpEditors.setSelectedIndex(2); // show the errors and warnings 650 return; 651 } 652 652 if (getTurnRestriction() == null) { 653 653 applyNewTurnRestriction(); … … 658 658 editorModel.apply(toUpdate); 659 659 if (TurnRestrictionEditorModel.hasSameMembersAndTags(toUpdate, getTurnRestriction())) 660 661 660 // nothing to update 661 return; 662 662 663 663 if (isDirtyTurnRestriction()) { … … 689 689 690 690 public void run() { 691 692 693 694 691 if (!confirmSaveDespiteOfErrorsAndWarnings()){ 692 tpEditors.setSelectedIndex(2); // show the errors and warnings 693 return; 694 } 695 695 if (getTurnRestriction() == null) { 696 696 // it's a new turn restriction. Try to save it and close the dialog 697 697 if (applyNewTurnRestriction()) { 698 698 setVisible(false); 699 699 } 700 700 return; … … 704 704 editorModel.apply(toUpdate); 705 705 if (TurnRestrictionEditorModel.hasSameMembersAndTags(toUpdate, getTurnRestriction())){ 706 707 708 706 // nothing to update 707 setVisible(false); 708 return; 709 709 } 710 710 711 711 if (isDirtyTurnRestriction()) { 712 713 712 // the turn restriction this editor is working on has changed outside 713 // of the editor. 714 714 if (confirmClosingBecauseOfDirtyState()) { 715 715 if (getLayer().getConflicts().hasConflictForMy(getTurnRestriction())) { … … 750 750 751 751 class DeleteAction extends AbstractAction implements PropertyChangeListener{ 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 752 public DeleteAction() { 753 putValue(NAME, tr("Delete")); 754 putValue(SHORT_DESCRIPTION, tr("Delete this turn restriction")); 755 putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete")); 756 updateEnabledState(); 757 } 758 759 protected void updateEnabledState() { 760 Relation tr = getTurnRestriction(); 761 setEnabled(tr != null && tr.getDataSet() != null); 762 } 763 764 public void actionPerformed(ActionEvent e) { 765 Relation tr = getTurnRestriction(); 766 if (tr == null || tr.getDataSet() == null) return; 767 org.openstreetmap.josm.actions.mapmode.DeleteAction.deleteRelation( 768 768 getLayer(), 769 769 tr 770 770 ); 771 772 773 774 775 776 777 778 771 setVisible(false); 772 } 773 774 public void propertyChange(PropertyChangeEvent evt) { 775 if (evt.getPropertyName().equals(TURN_RESTRICION_PROP)){ 776 updateEnabledState(); 777 } 778 } 779 779 } 780 780 781 781 class SelectAction extends AbstractAction implements PropertyChangeListener{ 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 782 public SelectAction() { 783 putValue(NAME, tr("Select")); 784 putValue(SHORT_DESCRIPTION, tr("Select this turn restriction")); 785 putValue(SMALL_ICON, ImageProvider.get("dialogs", "select")); 786 updateEnabledState(); 787 } 788 789 protected void updateEnabledState() { 790 Relation tr = getTurnRestriction(); 791 setEnabled(tr != null && tr.getDataSet() != null); 792 } 793 794 public void actionPerformed(ActionEvent e) { 795 Relation tr = getTurnRestriction(); 796 if (tr == null || tr.getDataSet() == null) return; 797 getLayer().data.setSelected(tr); 798 } 799 800 public void propertyChange(PropertyChangeEvent evt) { 801 if (evt.getPropertyName().equals(TURN_RESTRICION_PROP)){ 802 updateEnabledState(); 803 } 804 } 805 805 } 806 806 807 807 class ZoomToAction extends AbstractAction implements PropertyChangeListener{ 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 808 public ZoomToAction() { 809 putValue(NAME, tr("Zoom to")); 810 putValue(SHORT_DESCRIPTION, tr("Activate the layer this turn restriction belongs to and zoom to it")); 811 putValue(SMALL_ICON, ImageProvider.get("dialogs/autoscale", "data")); 812 updateEnabledState(); 813 } 814 815 protected void updateEnabledState() { 816 Relation tr = getTurnRestriction(); 817 setEnabled(tr != null && tr.getDataSet() != null); 818 } 819 820 public void actionPerformed(ActionEvent e) { 821 if (Main.main.getActiveLayer() != getLayer()){ 822 Main.map.mapView.setActiveLayer(getLayer()); 823 } 824 Relation tr = getTurnRestriction(); 825 if (tr == null || tr.getDataSet() == null) return; 826 getLayer().data.setSelected(tr); 827 AutoScaleAction.zoomToSelection(); 828 } 829 830 public void propertyChange(PropertyChangeEvent evt) { 831 if (evt.getPropertyName().equals(TURN_RESTRICION_PROP)){ 832 updateEnabledState(); 833 } 834 } 835 835 } 836 836 837 837 class IssuesModelObserver implements Observer { 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 } 838 public void update(Observable o, Object arg) { 839 int numWarnings = editorModel.getIssuesModel().getNumWarnings(); 840 int numErrors = editorModel.getIssuesModel().getNumErrors(); 841 String warningText = null; 842 if (numWarnings > 0){ 843 warningText = trn("{0} warning", "{0} warnings", numWarnings, numWarnings); 844 } 845 String errorText = null; 846 if (numErrors > 0){ 847 errorText = trn("{0} error", "{0} errors", numErrors, numErrors); 848 } 849 String title = ""; 850 if (errorText != null) { 851 title += errorText; 852 } 853 if (warningText != null){ 854 if (title.length() > 0){ 855 title += "/"; 856 } 857 title += warningText; 858 } 859 if (title.length() == 0){ 860 title = tr("no issues"); 861 } 862 tpEditors.setTitleAt(2, title); 863 tpEditors.setEnabledAt(2, numWarnings + numErrors > 0); 864 } 865 865 } 866 866 … … 874 874 * 875 875 */ 876 class PreferenceChangeHandler implements PreferenceChangedListener { 877 878 879 880 881 882 883 884 885 886 } 887 876 class PreferenceChangeHandler implements PreferenceChangedListener { 877 public void refreshIconSet() { 878 pnlBasicEditor.initIconSetFromPreferences(Main.pref); 879 } 880 881 public void preferenceChanged(PreferenceChangeEvent evt) { 882 if (evt.getKey().equals(PreferenceKeys.ROAD_SIGNS)){ 883 refreshIconSet(); 884 } else if (evt.getKey().equals(PreferenceKeys.SHOW_VIAS_IN_BASIC_EDITOR)) { 885 pnlBasicEditor.initViasVisibilityFromPreferences(Main.pref); 886 } 887 } 888 888 } 889 889 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditorManager.java
r20489 r23192 23 23 */ 24 24 public class TurnRestrictionEditorManager extends WindowAdapter implements MapView.LayerChangeListener{ 25 25 static private final Logger logger = Logger.getLogger(TurnRestrictionEditorManager.class.getName()); 26 26 27 27 /** keeps track of open relation editors */ … … 55 55 56 56 @Override 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 57 public int hashCode() { 58 final int prime = 31; 59 int result = 1; 60 result = prime * result + ((layer == null) ? 0 : layer.hashCode()); 61 result = prime * result 62 + ((primitiveId == null) ? 0 : primitiveId.hashCode()); 63 return result; 64 } 65 66 @Override 67 public boolean equals(Object obj) { 68 if (this == obj) 69 return true; 70 if (obj == null) 71 return false; 72 if (getClass() != obj.getClass()) 73 return false; 74 DialogContext other = (DialogContext) obj; 75 if (layer == null) { 76 if (other.layer != null) 77 return false; 78 } else if (!layer.equals(other.layer)) 79 return false; 80 if (primitiveId == null) { 81 if (other.primitiveId != null) 82 return false; 83 } else if (!primitiveId.equals(other.primitiveId)) 84 return false; 85 return true; 86 } 87 88 public boolean matchesLayer(OsmDataLayer layer) { 89 89 if (layer == null) return false; 90 90 return this.layer.equals(layer); … … 187 187 @Override 188 188 public void windowClosed(WindowEvent e) { 189 189 TurnRestrictionEditor editor = (TurnRestrictionEditor)e.getWindow(); 190 190 DialogContext context = null; 191 191 for (DialogContext c : openDialogs.keySet()) { … … 200 200 } 201 201 202 202 /** 203 203 * Positions an {@see TurnRestrictionEditor} centered on the screen 204 204 * … … 286 286 Entry<DialogContext,TurnRestrictionEditor> entry = it.next(); 287 287 if (entry.getKey().matchesLayer(dataLayer)) { 288 288 TurnRestrictionEditor editor = entry.getValue(); 289 289 it.remove(); 290 290 editor.setVisible(false); -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditorModel.java
r20735 r23192 40 40 */ 41 41 public class TurnRestrictionEditorModel extends Observable implements DataSetListener{ 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 } 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 } 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 } 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 } 425 } 426 427 428 429 430 431 } 432 433 434 435 436 437 438 439 440 441 } 442 42 static private final Logger logger = Logger.getLogger(TurnRestrictionEditorModel.class.getName()); 43 44 /** 45 * Replies true if {@code tp1} and {@code tp2} have the same tags and 46 * the same members 47 * 48 * @param tp1 a turn restriction. Must not be null. 49 * @param tp2 a turn restriction . Must not be null. 50 * @return true if {@code tp1} and {@code tp2} have the same tags and 51 * the same members 52 * @throws IllegalArgumentException thrown if {@code tp1} is null 53 * @throws IllegalArgumentException thrown if {@code tp2} is null 54 */ 55 static public boolean hasSameMembersAndTags(Relation tp1, Relation tp2) throws IllegalArgumentException { 56 CheckParameterUtil.ensureParameterNotNull(tp1, "tp1"); 57 CheckParameterUtil.ensureParameterNotNull(tp2, "tp2"); 58 if (!TagCollection.from(tp1).asSet().equals(TagCollection.from(tp2).asSet())) return false; 59 if (tp1.getMembersCount() != tp2.getMembersCount()) return false; 60 for(int i=0; i < tp1.getMembersCount();i++){ 61 if (!tp1.getMember(i).equals(tp2.getMember(i))) return false; 62 } 63 return true; 64 } 65 66 private OsmDataLayer layer; 67 private final TagEditorModel tagEditorModel = new TagEditorModel(); 68 private RelationMemberEditorModel memberModel; 69 private IssuesModel issuesModel; 70 private NavigationControler navigationControler; 71 72 /** 73 * Creates a model in the context of a {@see OsmDataLayer} 74 * 75 * @param layer the layer. Must not be null. 76 * @param navigationControler control to direct the user to specific UI components. Must not be null 77 * @throws IllegalArgumentException thrown if {@code layer} is null 78 */ 79 public TurnRestrictionEditorModel(OsmDataLayer layer, NavigationControler navigationControler) throws IllegalArgumentException{ 80 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 81 CheckParameterUtil.ensureParameterNotNull(navigationControler, "navigationControler"); 82 this.layer = layer; 83 this.navigationControler = navigationControler; 84 memberModel = new RelationMemberEditorModel(layer); 85 memberModel.addTableModelListener(new RelationMemberModelListener()); 86 issuesModel = new IssuesModel(this); 87 addObserver(issuesModel); 88 tagEditorModel.addTableModelListener(new TagEditorModelObserver()); 89 } 90 91 /** 92 * Sets the way participating in the turn restriction in a given role. 93 * 94 * @param role the role. Must not be null. 95 * @param way the way which participates in the turn restriction in the respective role. 96 * null, to remove the way with the given role. 97 * @exception IllegalArgumentException thrown if role is null 98 */ 99 public void setTurnRestrictionLeg(TurnRestrictionLegRole role, Way way) { 100 CheckParameterUtil.ensureParameterNotNull(role, "role"); 101 switch(role){ 102 case FROM: 103 memberModel.setFromPrimitive(way); 104 break; 105 case TO: 106 memberModel.setToPrimitive(way); 107 break; 108 } 109 } 110 111 /** 112 * Sets the way participating in the turn restriction in a given role. 113 * 114 * @param role the role. Must not be null. 115 * @param wayId the id of the way to set 116 * @exception IllegalArgumentException thrown if role is null 117 * @exception IllegalArgumentException thrown if wayId != null isn't the id of a way 118 * @exception IllegalStateException thrown the no way with this id was found in the dataset 119 */ 120 public void setTurnRestrictionLeg(TurnRestrictionLegRole role, PrimitiveId wayId) { 121 CheckParameterUtil.ensureParameterNotNull(role, "role"); 122 if (wayId == null) { 123 setTurnRestrictionLeg(role, (Way)null); 124 return; 125 } 126 if (!wayId.getType().equals(OsmPrimitiveType.WAY)) { 127 throw new IllegalArgumentException(MessageFormat.format("parameter ''wayId'' of type {0} expected, got {1}", OsmPrimitiveType.WAY, wayId.getType())); 128 } 129 130 OsmPrimitive p = layer.data.getPrimitiveById(wayId); 131 if (p == null) { 132 throw new IllegalStateException(MessageFormat.format("didn''t find way with id {0} in layer ''{1}''", wayId, layer.getName())); 133 } 134 setTurnRestrictionLeg(role, (Way)p); 135 } 136 137 /** 138 * "Officially" a turn restriction should have exactly one member with 139 * role {@see TurnRestrictionLegRole#FROM} and one member with role {@see TurnRestrictionLegRole#TO}, 140 * both referring to an OSM {@see Way}. In order to deals with turn restrictions where these 141 * integrity constraints are violated, this model also supports relation with multiple or no 142 * 'from' or 'to' members. 143 * 144 * Replies the turn restriction legs with role {@code role}. If no leg with this 145 * role exists, an empty set is returned. If multiple legs exists, the set of referred 146 * primitives is returned. 147 * 148 * @param role the role. Must not be null. 149 * @return the set of turn restriction legs with role {@code role}. The empty set, if 150 * no such turn restriction leg exists 151 * @throws IllegalArgumentException thrown if role is null 152 */ 153 public Set<OsmPrimitive>getTurnRestrictionLeg(TurnRestrictionLegRole role){ 154 CheckParameterUtil.ensureParameterNotNull(role, "role"); 155 switch(role){ 156 case FROM: return memberModel.getFromPrimitives(); 157 case TO: return memberModel.getToPrimitives(); 158 } 159 // should not happen 160 return null; 161 } 162 163 /** 164 * Initializes the model from a relation representing a turn 165 * restriction 166 * 167 * @param turnRestriction the turn restriction 168 */ 169 protected void initFromTurnRestriction(Relation turnRestriction) { 170 171 // populate the member model 172 memberModel.populate(turnRestriction); 173 174 // make sure we have a restriction tag 175 TagCollection tags = TagCollection.from(turnRestriction); 176 tags.setUniqueForKey("type", "restriction"); 177 tagEditorModel.initFromTags(tags); 178 179 setChanged(); 180 notifyObservers(); 181 } 182 183 /** 184 * Populates the turn restriction editor model with a turn restriction. 185 * {@code turnRestriction} is an arbitrary relation. A tag type=restriction 186 * isn't required. If it is missing, it is added here. {@code turnRestriction} 187 * must not be null and it must belong to a dataset. 188 * 189 * @param turnRestriction the turn restriction 190 * @throws IllegalArgumentException thrown if turnRestriction is null 191 * @throws IllegalArgumentException thrown if turnRestriction doesn't belong to a dataset 192 */ 193 public void populate(Relation turnRestriction) { 194 CheckParameterUtil.ensureParameterNotNull(turnRestriction, "turnRestriction"); 195 if (turnRestriction.getDataSet() != null && turnRestriction.getDataSet() != layer.data) { 196 throw new IllegalArgumentException( 197 // don't translate - it's a technical message 198 MessageFormat.format("turnRestriction {0} must not belong to a different dataset than the dataset of layer ''{1}''", turnRestriction.getId(), layer.getName()) 199 ); 200 } 201 initFromTurnRestriction(turnRestriction); 202 } 203 204 205 /** 206 * Applies the current state in the model to a turn restriction 207 * 208 * @param turnRestriction the turn restriction. Must not be null. 209 */ 210 public void apply(Relation turnRestriction) { 211 CheckParameterUtil.ensureParameterNotNull(turnRestriction, "turnRestriction"); 212 TagCollection tags = tagEditorModel.getTagCollection(); 213 turnRestriction.removeAll(); 214 tags.applyTo(turnRestriction); 215 memberModel.applyTo(turnRestriction); 216 } 217 218 /** 219 * Replies the current tag value for the tag <tt>restriction</tt>. 220 * The empty tag, if there isn't a tag <tt>restriction</tt>. 221 * 222 * @return the tag value 223 */ 224 public String getRestrictionTagValue() { 225 TagCollection tags = tagEditorModel.getTagCollection(); 226 if (!tags.hasTagsFor("restriction")) return ""; 227 return tags.getJoinedValues("restriction"); 228 } 229 230 /** 231 * Sets the current value for the restriction tag. If {@code value} is 232 * null or an empty string, the restriction tag is removed. 233 * 234 * @param value the value of the restriction tag 235 */ 236 public void setRestrictionTagValue(String value){ 237 if (value == null || value.trim().equals("")) { 238 tagEditorModel.delete("restriction"); 239 } else { 240 TagModel tm = tagEditorModel.get("restriction"); 241 if (tm != null){ 242 tm.setValue(value); 243 } else { 244 tagEditorModel.prepend(new TagModel("restriction", value.trim().toLowerCase())); 245 } 246 } 247 setChanged(); 248 notifyObservers(); 249 } 250 251 /** 252 * Replies the list of 'via' objects. The return value is an 253 * unmodifiable list. 254 * 255 * @return the list of 'via' objects 256 */ 257 public List<OsmPrimitive> getVias() { 258 return memberModel.getVias(); 259 } 260 261 /** 262 * Sets the list of vias for the edited turn restriction. 263 * 264 * If {@code vias} is null, all vias are removed. All primitives 265 * in {@code vias} must be assigned to a dataset and the dataset 266 * must be equal to the dataset of this editor model, see {@see #getDataSet()} 267 * 268 * null values in {@see vias} are skipped. 269 * 270 * @param vias the list of vias 271 * @throws IllegalArgumentException thrown if one of the via objects belongs to the wrong dataset 272 */ 273 public void setVias(List<OsmPrimitive> vias) throws IllegalArgumentException{ 274 memberModel.setVias(vias); 275 } 276 277 /** 278 * Replies the layer in whose context this editor is working 279 * 280 * @return the layer in whose context this editor is working 281 */ 282 public OsmDataLayer getLayer() { 283 return layer; 284 } 285 286 /** 287 * Registers this model with global event sources like {@see DatasetEventManager} 288 */ 289 public void registerAsEventListener(){ 290 DatasetEventManager.getInstance().addDatasetListener(this, FireMode.IN_EDT); 291 } 292 293 /** 294 * Removes this model as listener from global event sources like {@see DatasetEventManager} 295 */ 296 public void unregisterAsEventListener() { 297 DatasetEventManager.getInstance().removeDatasetListener(this); 298 } 299 300 /** 301 * Replies the tag editor model 302 * 303 * @return the tag editor model 304 */ 305 public TagEditorModel getTagEditorModel() { 306 return tagEditorModel; 307 } 308 309 /** 310 * Replies the editor model for the relation members 311 * 312 * @return the editor model for the relation members 313 */ 314 public RelationMemberEditorModel getRelationMemberEditorModel() { 315 return memberModel; 316 } 317 318 /** 319 * Replies the model for the open issues in this turn restriction 320 * editor. 321 * 322 * @return the model for the open issues in this turn restriction 323 * editor 324 */ 325 public IssuesModel getIssuesModel() { 326 return issuesModel; 327 } 328 329 public NavigationControler getNavigationControler() { 330 return navigationControler; 331 } 332 333 /** 334 * Replies the current value of the tag "except", or the empty string 335 * if the tag doesn't exist. 336 * 337 * @return 338 */ 339 public ExceptValueModel getExcept() { 340 TagModel tag = tagEditorModel.get("except"); 341 if (tag == null) return new ExceptValueModel(""); 342 return new ExceptValueModel(tag.getValue()); 343 } 344 345 /** 346 * Sets the current value of the tag "except". Removes the 347 * tag is {@code value} is null or consists of white 348 * space only. 349 * 350 * @param value the new value for 'except' 351 */ 352 public void setExcept(ExceptValueModel value){ 353 if (value == null || value.getValue().equals("")) { 354 if (tagEditorModel.get("except") != null){ 355 tagEditorModel.delete("except"); 356 setChanged(); 357 notifyObservers(); 358 } 359 return; 360 } 361 TagModel tag = tagEditorModel.get("except"); 362 if (tag == null) { 363 tagEditorModel.prepend(new TagModel("except", value.getValue())); 364 setChanged(); 365 notifyObservers(); 366 } else { 367 if (!tag.getValue().equals(value.getValue())) { 368 tag.setValue(value.getValue().trim()); 369 setChanged(); 370 notifyObservers(); 371 } 372 } 373 } 374 375 /* ----------------------------------------------------------------------------------------- */ 376 /* interface DataSetListener */ 377 /* ----------------------------------------------------------------------------------------- */ 378 protected boolean isAffectedByDataSetUpdate(DataSet ds, List<? extends OsmPrimitive> updatedPrimitives) { 379 if (ds != layer.data) return false; 380 if (updatedPrimitives == null || updatedPrimitives.isEmpty()) return false; 381 Set<OsmPrimitive> myPrimitives = memberModel.getMemberPrimitives(); 382 int size1 = myPrimitives.size(); 383 myPrimitives.retainAll(updatedPrimitives); 384 return size1 != myPrimitives.size(); 385 } 386 387 public void dataChanged(DataChangedEvent event) { 388 // refresh the views 389 setChanged(); 390 notifyObservers(); 391 } 392 393 public void nodeMoved(NodeMovedEvent event) { 394 // may affect the display name of node in the list of vias 395 if (isAffectedByDataSetUpdate(event.getDataset(), event.getPrimitives())) { 396 setChanged(); 397 notifyObservers(); 398 } 399 } 400 401 public void otherDatasetChange(AbstractDatasetChangedEvent event) {/* irrelevant in this context */} 402 403 public void primtivesAdded(PrimitivesAddedEvent event) {/* irrelevant in this context */} 404 public void primtivesRemoved(PrimitivesRemovedEvent event) { 405 // relevant for the state of this model but not handled here. When the 406 // state of this model is applied to the dataset we check whether the 407 // the turn restriction refers to deleted or invisible primitives 408 } 409 410 public void relationMembersChanged(RelationMembersChangedEvent event) {/* irrelevant in this context */} 411 public void tagsChanged(TagsChangedEvent event) { 412 // may affect the display name of 'from', 'to' or 'via' elements 413 if (isAffectedByDataSetUpdate(event.getDataset(), event.getPrimitives())) { 414 setChanged(); 415 notifyObservers(); 416 } 417 } 418 419 public void wayNodesChanged(WayNodesChangedEvent event) { 420 // may affect the display name of 'from', 'to' or 'via' elements 421 if (isAffectedByDataSetUpdate(event.getDataset(), event.getPrimitives())) { 422 setChanged(); 423 notifyObservers(); 424 } 425 } 426 427 class RelationMemberModelListener implements TableModelListener { 428 public void tableChanged(TableModelEvent e) { 429 setChanged(); 430 notifyObservers(); 431 } 432 } 433 434 /* ----------------------------------------------------------------------------------------- */ 435 /* inner classes */ 436 /* ----------------------------------------------------------------------------------------- */ 437 class TagEditorModelObserver implements TableModelListener { 438 public void tableChanged(TableModelEvent e) { 439 setChanged(); 440 notifyObservers(); 441 } 442 } 443 443 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionLegEditor.java
r20701 r23192 55 55 */ 56 56 public class TurnRestrictionLegEditor extends JPanel implements Observer, PrimitiveIdListProvider { 57 57 static private final Logger logger = Logger.getLogger(TurnRestrictionLegEditor.class.getName()); 58 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 } 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 } 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 } 231 232 233 234 235 236 237 } 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 } 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 } 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 } 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 59 private JLabel lblOsmObject; 60 private final Set<OsmPrimitive> legs = new HashSet<OsmPrimitive>(); 61 private TurnRestrictionEditorModel model; 62 private TurnRestrictionLegRole role; 63 private DeleteAction actDelete; 64 private CopyAction actCopy; 65 private PasteAction actPaste; 66 private TransferHandler transferHandler; 67 68 /** 69 * builds the UI 70 */ 71 protected void build() { 72 setLayout(new BorderLayout()); 73 add(lblOsmObject = new JLabel(), BorderLayout.CENTER); 74 lblOsmObject.setOpaque(true); 75 lblOsmObject.setBorder(null); 76 setBorder( 77 BorderFactory.createCompoundBorder( 78 BorderFactory.createEtchedBorder(), 79 BorderFactory.createEmptyBorder(1,1,1,1) 80 ) 81 ); 82 83 JButton btn; 84 actDelete = new DeleteAction(); 85 add(btn = new JButton(actDelete), BorderLayout.EAST); 86 btn.setFocusable(false); 87 btn.setText(null); 88 btn.setBorder(BorderFactory.createRaisedBevelBorder()); 89 90 // focus handling 91 FocusHandler fh = new FocusHandler(); 92 lblOsmObject.setFocusable(true); 93 lblOsmObject.addFocusListener(fh); 94 this.addFocusListener(fh); 95 96 // mouse event handling 97 MouseEventHandler meh = new MouseEventHandler(); 98 lblOsmObject.addMouseListener(meh); 99 addMouseListener(meh); 100 lblOsmObject.addMouseListener(new PopupLauncher()); 101 102 // enable DEL to remove the object from the turn restriction 103 registerKeyboardAction(actDelete,KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0) , JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 104 105 getInputMap().put(Shortcut.getCopyKeyStroke(), TransferHandler.getCopyAction().getValue(Action.NAME));; 106 getInputMap().put(Shortcut.getPasteKeyStroke(), TransferHandler.getPasteAction().getValue(Action.NAME));; 107 getActionMap().put(TransferHandler.getCopyAction().getValue(Action.NAME), TransferHandler.getCopyAction()); 108 getActionMap().put(TransferHandler.getPasteAction().getValue(Action.NAME), TransferHandler.getPasteAction()); 109 lblOsmObject.setTransferHandler(transferHandler = new LegEditorTransferHandler(this)); 110 lblOsmObject.addMouseMotionListener(new MouseMotionAdapter(){ 111 @Override 112 public void mouseDragged(MouseEvent e) { 113 JComponent c = (JComponent)e.getSource(); 114 TransferHandler th = c.getTransferHandler(); 115 th.exportAsDrag(c, e, TransferHandler.COPY); 116 } 117 }); 118 actCopy = new CopyAction(); 119 actPaste = new PasteAction(); 120 } 121 122 /** 123 * Constructor 124 * 125 * @param model the model. Must not be null. 126 * @param role the leg role of the leg this editor is editing. Must not be null. 127 * @exception IllegalArgumentException thrown if model is null 128 * @exception IllegalArgumentException thrown if role is null 129 */ 130 public TurnRestrictionLegEditor(TurnRestrictionEditorModel model, TurnRestrictionLegRole role) { 131 CheckParameterUtil.ensureParameterNotNull(model, "model"); 132 CheckParameterUtil.ensureParameterNotNull(role, "role"); 133 134 this.model = model; 135 this.role = role; 136 build(); 137 model.addObserver(this); 138 refresh(); 139 } 140 141 protected void refresh(){ 142 legs.clear(); 143 legs.addAll(model.getTurnRestrictionLeg(role)); 144 if (legs.isEmpty()) { 145 lblOsmObject.setFont(UIManager.getFont("Label.font").deriveFont(Font.ITALIC)); 146 lblOsmObject.setIcon(null); 147 lblOsmObject.setText(tr("please select a way")); 148 lblOsmObject.setToolTipText(null); 149 } else if (legs.size() == 1){ 150 OsmPrimitive leg = legs.iterator().next(); 151 lblOsmObject.setFont(UIManager.getFont("Label.font")); 152 lblOsmObject.setIcon(ImageProvider.get("data", "way")); 153 lblOsmObject.setText(leg.getDisplayName(DefaultNameFormatter.getInstance())); 154 lblOsmObject.setToolTipText(DefaultNameFormatter.getInstance().buildDefaultToolTip(leg)); 155 } else { 156 lblOsmObject.setFont(UIManager.getFont("Label.font").deriveFont(Font.ITALIC)); 157 lblOsmObject.setIcon(null); 158 lblOsmObject.setText(tr("multiple objects with role ''{0}''",this.role.getOsmRole())); 159 lblOsmObject.setToolTipText(null); 160 } 161 renderColors(); 162 actDelete.updateEnabledState(); 163 } 164 165 /** 166 * Render the foreground and background color 167 */ 168 protected void renderColors() { 169 if (lblOsmObject.hasFocus()) { 170 setBackground(UIManager.getColor("List.selectionBackground")); 171 setForeground(UIManager.getColor("List.selectionForeground")); 172 lblOsmObject.setBackground(UIManager.getColor("List.selectionBackground")); 173 lblOsmObject.setForeground(UIManager.getColor("List.selectionForeground")); 174 } else { 175 lblOsmObject.setBackground(UIManager.getColor("List.background")); 176 lblOsmObject.setForeground(UIManager.getColor("List.foreground")); 177 } 178 } 179 180 /** 181 * Replies the model for this editor 182 * 183 * @return the model 184 */ 185 public TurnRestrictionEditorModel getModel() { 186 return model; 187 } 188 189 /** 190 * Replies the role of this editor 191 * 192 * @return the role 193 */ 194 public TurnRestrictionLegRole getRole() { 195 return role; 196 } 197 198 /* ----------------------------------------------------------------------------- */ 199 /* interface Observer */ 200 /* ----------------------------------------------------------------------------- */ 201 public void update(Observable o, Object arg) { 202 refresh(); 203 } 204 205 /* ----------------------------------------------------------------------------- */ 206 /* interface PrimitiveIdListProvider */ 207 /* ----------------------------------------------------------------------------- */ 208 public List<PrimitiveId> getSelectedPrimitiveIds() { 209 if (legs.size() == 1) { 210 return Collections.singletonList(legs.iterator().next().getPrimitiveId()); 211 } 212 return Collections.emptyList(); 213 } 214 215 /* ----------------------------------------------------------------------------- */ 216 /* inner classes */ 217 /* ----------------------------------------------------------------------------- */ 218 /** 219 * Responds to focus change events 220 */ 221 class FocusHandler extends FocusAdapter { 222 @Override 223 public void focusGained(FocusEvent e) { 224 renderColors(); 225 } 226 227 @Override 228 public void focusLost(FocusEvent e) { 229 renderColors(); 230 } 231 } 232 233 class MouseEventHandler extends MouseAdapter { 234 @Override 235 public void mouseClicked(MouseEvent e) { 236 lblOsmObject.requestFocusInWindow(); 237 } 238 } 239 240 /** 241 * Deletes the way from the turn restriction 242 */ 243 class DeleteAction extends AbstractAction { 244 public DeleteAction() { 245 putValue(SHORT_DESCRIPTION, tr("Delete from turn restriction")); 246 putValue(NAME, tr("Delete")); 247 putValue(SMALL_ICON, ImageProvider.get("deletesmall")); 248 putValue(ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0)); 249 updateEnabledState(); 250 } 251 252 public void actionPerformed(ActionEvent e) { 253 model.setTurnRestrictionLeg(role, null); 254 } 255 256 public void updateEnabledState() { 257 setEnabled(legs.size()>0); 258 } 259 } 260 261 /** 262 * The transfer handler for Drag-and-Drop. 263 */ 264 class LegEditorTransferHandler extends PrimitiveIdListTransferHandler { 265 Logger logger = Logger.getLogger(LegEditorTransferHandler.class.getName()); 266 267 public LegEditorTransferHandler(PrimitiveIdListProvider provider){ 268 super(provider); 269 } 270 271 @SuppressWarnings("unchecked") 272 @Override 273 public boolean importData(JComponent comp, Transferable t) { 274 try { 275 List<PrimitiveId> ids = (List<PrimitiveId>)t.getTransferData(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR); 276 if (ids.size() !=1) { 277 return false; 278 } 279 PrimitiveId id = ids.get(0); 280 if (!id.getType().equals(OsmPrimitiveType.WAY)) return false; 281 model.setTurnRestrictionLeg(role, id); 282 return true; 283 } catch(IOException e) { 284 // ignore 285 return false; 286 } catch(UnsupportedFlavorException e) { 287 // ignore 288 return false; 289 } 290 } 291 292 @Override 293 protected Transferable createTransferable(JComponent c) { 294 if (legs.size() != 1) return null; 295 return super.createTransferable(c); 296 } 297 } 298 299 class PopupLauncher extends PopupMenuLauncher { 300 @Override 301 public void launch(MouseEvent evt) { 302 new PopupMenu().show(lblOsmObject, evt.getX(), evt.getY()); 303 } 304 } 305 306 class PopupMenu extends JPopupMenu { 307 public PopupMenu() { 308 actCopy.updateEnabledState(); 309 JMenuItem item = add(actCopy); 310 item.setTransferHandler(transferHandler); 311 actPaste.updateEnabledState(); 312 item = add(actPaste); 313 item.setTransferHandler(transferHandler); 314 addSeparator(); 315 add(actDelete); 316 } 317 } 318 319 class CopyAction extends AbstractAction { 320 private Action delegate; 321 322 public CopyAction(){ 323 putValue(NAME, tr("Copy")); 324 putValue(SHORT_DESCRIPTION, tr("Copy to the clipboard")); 325 putValue(SMALL_ICON, ImageProvider.get("copy")); 326 putValue(ACCELERATOR_KEY, Shortcut.getCopyKeyStroke()); 327 delegate = TurnRestrictionLegEditor.this.getActionMap().get("copy"); 328 updateEnabledState(); 329 } 330 331 public void actionPerformed(ActionEvent e) { 332 delegate.actionPerformed(e); 333 } 334 335 public void updateEnabledState() { 336 setEnabled(legs.size() == 1); 337 } 338 } 339 340 class PasteAction extends AbstractAction { 341 private Action delegate; 342 343 public boolean canPaste() { 344 Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 345 for (DataFlavor df: clipboard.getAvailableDataFlavors()) { 346 if (df.equals(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR)) return true; 347 } 348 // FIXME: check whether there are selected objects in the JOSM copy/paste buffer 349 return false; 350 } 351 352 public PasteAction(){ 353 putValue(NAME, tr("Paste")); 354 putValue(SHORT_DESCRIPTION, tr("Paste from the clipboard")); 355 putValue(SMALL_ICON, ImageProvider.get("paste")); 356 putValue(ACCELERATOR_KEY, Shortcut.getPasteKeyStroke()); 357 delegate = TurnRestrictionLegEditor.this.getActionMap().get("paste"); 358 } 359 360 public void updateEnabledState() { 361 setEnabled(canPaste()); 362 } 363 364 public void actionPerformed(ActionEvent e) { 365 delegate.actionPerformed(e); 366 } 367 } 368 368 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionLegRole.java
r20622 r23192 4 4 * Enumerates the two roles a "leg" in a turn restriction can have. 5 5 */ 6 public enum TurnRestrictionLegRole { 7 8 9 10 11 12 13 14 15 16 17 18 6 public enum TurnRestrictionLegRole { 7 FROM("from"), 8 TO("to"); 9 10 private String osmRoleName; 11 12 private TurnRestrictionLegRole(String osmRoleName) { 13 this.osmRoleName = osmRoleName; 14 } 15 16 public String getOsmRole() { 17 return osmRoleName; 18 } 19 19 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionSelectionPopupPanel.java
r20606 r23192 50 50 */ 51 51 public class TurnRestrictionSelectionPopupPanel extends JPanel{ 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 } 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 } 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 52 static private final Logger logger = Logger.getLogger(TurnRestrictionSelectionPopupPanel.class.getName()); 53 54 /** the parent popup */ 55 private Popup parentPopup; 56 /** the button for creating a new turn restriction */ 57 private JButton btnNew; 58 /** the table with the turn restrictions which can be edited */ 59 private JTable tblTurnRestrictions; 60 private OsmDataLayer layer; 61 62 63 64 /** 65 * Replies the collection of turn restrictions the primitives in {@code primitives} 66 * currently participate in. 67 * 68 * @param primitives the collection of primitives. May be null. 69 * @return the collection of "parent" turn restrictions. 70 */ 71 static public Collection<Relation> getTurnRestrictionsParticipatingIn(Collection<OsmPrimitive> primitives){ 72 HashSet<Relation> ret = new HashSet<Relation>(); 73 if (primitives == null) return ret; 74 for (OsmPrimitive p: primitives){ 75 if (p == null) continue; 76 if (p.isDeleted() || !p.isVisible()) continue; 77 for (OsmPrimitive parent: p.getReferrers()){ 78 if (!(parent instanceof Relation)) continue; 79 String type = parent.get("type"); 80 if (type == null || ! type.equals("restriction")) continue; 81 if (parent.isDeleted() || ! parent.isVisible()) continue; 82 ret.add((Relation)parent); 83 } 84 } 85 return ret; 86 } 87 88 /** 89 * Registers 1..9 shortcuts for the first 9 turn restrictions to 90 * edit 91 * 92 * @param editCandiates the edit candidates 93 */ 94 protected void registerEditShortcuts(Collection<Relation> editCandiates){ 95 for(int i=1; i <= Math.min(editCandiates.size(),9);i++){ 96 int vkey = 0; 97 switch(i){ 98 case 1: vkey = KeyEvent.VK_1; break; 99 case 2: vkey = KeyEvent.VK_2; break; 100 case 3: vkey = KeyEvent.VK_3; break; 101 case 4: vkey = KeyEvent.VK_4; break; 102 case 5: vkey = KeyEvent.VK_5; break; 103 case 6: vkey = KeyEvent.VK_6; break; 104 case 7: vkey = KeyEvent.VK_7; break; 105 case 8: vkey = KeyEvent.VK_8; break; 106 case 9: vkey = KeyEvent.VK_9; break; 107 } 108 registerKeyboardAction(new EditTurnRestrictionAction(i-1), KeyStroke.getKeyStroke(vkey,0), WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 109 } 110 } 111 /** 112 * Builds the panel with the turn restrictions table 113 * 114 * @param editCandiates the list of edit candiates 115 * @return the panel 116 */ 117 protected JPanel buildTurnRestrictionTablePanel(Collection<Relation> editCandiates) { 118 tblTurnRestrictions = new JTable(new TurnRestrictionTableModel(editCandiates), new TurnRestrictionTableColumnModel()); 119 tblTurnRestrictions.setColumnSelectionAllowed(false); 120 tblTurnRestrictions.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); 121 TurnRestrictionCellRenderer renderer = new TurnRestrictionCellRenderer(); 122 tblTurnRestrictions.setRowHeight((int)renderer.getPreferredSize().getHeight()); 123 124 // create a scroll pane, remove the table header 125 JScrollPane pane = new JScrollPane(tblTurnRestrictions); 126 pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 127 pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 128 tblTurnRestrictions.setTableHeader(null); 129 pane.setColumnHeaderView(null); 130 131 // respond to double click and ENTER 132 EditSelectedTurnRestrictionAction action = new EditSelectedTurnRestrictionAction(); 133 tblTurnRestrictions.addMouseListener(action); 134 tblTurnRestrictions.registerKeyboardAction(action, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), WHEN_FOCUSED); 135 136 tblTurnRestrictions.addFocusListener(new FocusHandler()); 137 138 JPanel pnl = new JPanel(new BorderLayout()); 139 pnl.add(pane, BorderLayout.CENTER); 140 141 pnl.setBackground(UIManager.getColor("Table.background")); 142 pane.setBackground(UIManager.getColor("Table.background")); 143 return pnl; 144 } 145 146 /** 147 * Builds the panel 148 * 149 * @param editCandiates the edit candidates 150 */ 151 protected void build(Collection<Relation> editCandiates) { 152 setLayout(new BorderLayout()); 153 add(btnNew = new JButton(new NewAction()), BorderLayout.NORTH); 154 btnNew.setFocusable(true); 155 btnNew.registerKeyboardAction(btnNew.getAction(), KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), WHEN_FOCUSED); 156 registerKeyboardAction(new CloseAction(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0), WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 157 registerKeyboardAction(btnNew.getAction(), KeyStroke.getKeyStroke(KeyEvent.VK_N,0), WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 158 159 btnNew.addFocusListener(new FocusHandler()); 160 161 if (editCandiates != null && ! editCandiates.isEmpty()) { 162 add(buildTurnRestrictionTablePanel(editCandiates), BorderLayout.CENTER); 163 registerEditShortcuts(editCandiates); 164 } 165 166 setBackground(UIManager.getColor("Table.background")); 167 } 168 169 170 /** 171 * Creates the panel 172 * 173 * @param layer the reference OSM data layer. Must not be null. 174 * @throws IllegalArgumentException thrown if {@code layer} is null 175 */ 176 public TurnRestrictionSelectionPopupPanel(OsmDataLayer layer) throws IllegalArgumentException { 177 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 178 this.layer = layer; 179 build(getTurnRestrictionsParticipatingIn(layer.data.getSelected())); 180 } 181 182 /** 183 * Creates the panel 184 * 185 * @param layer the reference OSM data layer. Must not be null. 186 * @param editCandidates a collection of turn restrictions as edit candidates. May be null. 187 * @throws IllegalArgumentException thrown if {@code layer} is null 188 */ 189 public TurnRestrictionSelectionPopupPanel(OsmDataLayer layer, Collection<Relation> editCandiates) { 190 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 191 this.layer = layer; 192 build(editCandiates); 193 } 194 195 /** 196 * Launches a popup with this panel as content 197 */ 198 public void launch(){ 199 PointerInfo info = MouseInfo.getPointerInfo(); 200 Point pt = info.getLocation(); 201 parentPopup = PopupFactory.getSharedInstance().getPopup(Main.map.mapView,this, pt.x, pt.y); 202 parentPopup.show(); 203 btnNew.requestFocusInWindow(); 204 } 205 206 @Override 207 public Dimension getPreferredSize() { 208 int bestheight = (int)btnNew.getPreferredSize().getHeight() 209 + Math.min(2, tblTurnRestrictions.getRowCount()) * tblTurnRestrictions.getRowHeight() 210 + 5; 211 return new Dimension(300, bestheight); 212 } 213 214 /* --------------------------------------------------------------------------------------- */ 215 /* inner classes */ 216 /* --------------------------------------------------------------------------------------- */ 217 218 private class NewAction extends AbstractAction { 219 public NewAction() { 220 putValue(NAME, tr("Create new turn restriction")); 221 putValue(SHORT_DESCRIPTION, tr("Launch the turn restriction editor to create a new turn restriction")); 222 putValue(SMALL_ICON, ImageProvider.get("new")); 223 putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N, 0)); 224 } 225 226 public void actionPerformed(ActionEvent e) { 227 Relation tr = new TurnRestrictionBuilder().buildFromSelection(layer); 228 TurnRestrictionEditor editor = new TurnRestrictionEditor(Main.map.mapView,layer,tr); 229 TurnRestrictionEditorManager.getInstance().positionOnScreen(editor); 230 TurnRestrictionEditorManager.getInstance().register(layer, tr, editor); 231 if (parentPopup != null){ 232 parentPopup.hide(); 233 } 234 editor.setVisible(true); 235 } 236 } 237 238 abstract private class AbstractEditTurnRestrictionAction extends AbstractAction { 239 protected void launchEditor(Relation tr){ 240 TurnRestrictionEditorManager manager = TurnRestrictionEditorManager.getInstance(); 241 TurnRestrictionEditor editor = manager.getEditorForRelation(layer, tr); 242 if (parentPopup != null){ 243 parentPopup.hide(); 244 } 245 if (editor != null) { 246 editor.setVisible(true); 247 editor.toFront(); 248 } else { 249 editor = new TurnRestrictionEditor(Main.map.mapView, layer,tr); 250 manager.positionOnScreen(editor); 251 manager.register(layer, tr,editor); 252 editor.setVisible(true); 253 } 254 } 255 } 256 257 private class EditTurnRestrictionAction extends AbstractEditTurnRestrictionAction { 258 private int idx; 259 260 public EditTurnRestrictionAction(int idx){ 261 this.idx = idx; 262 } 263 264 public void actionPerformed(ActionEvent e) { 265 Relation tr = (Relation)tblTurnRestrictions.getModel().getValueAt(idx, 1); 266 launchEditor(tr); 267 } 268 } 269 270 private class EditSelectedTurnRestrictionAction extends AbstractEditTurnRestrictionAction implements MouseListener{ 271 public void editTurnRestrictionAtRow(int row){ 272 if (row < 0) return; 273 Relation tr = (Relation)tblTurnRestrictions.getModel().getValueAt(row, 1); 274 launchEditor(tr); 275 } 276 public void actionPerformed(ActionEvent e) { 277 int row = tblTurnRestrictions.getSelectedRow(); 278 editTurnRestrictionAtRow(row); 279 } 280 public void mouseClicked(MouseEvent e) { 281 if (!(SwingUtilities.isLeftMouseButton(e) && e.getClickCount() >= 2)) return; 282 int row = tblTurnRestrictions.rowAtPoint(e.getPoint()); 283 if (row < 0) return; 284 editTurnRestrictionAtRow(row); 285 } 286 public void mouseEntered(MouseEvent e) {} 287 public void mouseExited(MouseEvent e) {} 288 public void mousePressed(MouseEvent e) {} 289 public void mouseReleased(MouseEvent e) {} 290 } 291 292 private class CloseAction extends AbstractAction { 293 public void actionPerformed(ActionEvent e) { 294 if (parentPopup != null){ 295 parentPopup.hide(); 296 } 297 } 298 } 299 300 private static class TurnRestrictionTableModel extends AbstractTableModel { 301 private final ArrayList<Relation> turnrestrictions = new ArrayList<Relation>(); 302 303 public TurnRestrictionTableModel(Collection<Relation> turnrestrictions){ 304 this.turnrestrictions.clear(); 305 if (turnrestrictions != null){ 306 this.turnrestrictions.addAll(turnrestrictions); 307 } 308 fireTableDataChanged(); 309 } 310 311 public int getRowCount() { 312 return turnrestrictions.size(); 313 } 314 315 public int getColumnCount() { 316 return 2; 317 } 318 319 public Object getValueAt(int rowIndex, int columnIndex) { 320 switch(columnIndex){ 321 case 0: 322 if (rowIndex <=8 ) { 323 return Integer.toString(rowIndex+1); 324 } else { 325 return ""; 326 } 327 case 1: 328 return turnrestrictions.get(rowIndex); 329 } 330 // should not happen 331 return null; 332 } 333 } 334 335 private static class TurnRestrictionTableColumnModel extends DefaultTableColumnModel { 336 public TurnRestrictionTableColumnModel() { 337 // the idx column 338 TableColumn col = new TableColumn(0); 339 col.setResizable(false); 340 col.setWidth(50); 341 addColumn(col); 342 343 // the column displaying turn restrictions 344 col = new TableColumn(1); 345 col.setResizable(false); 346 col.setPreferredWidth(400); 347 col.setCellRenderer(new TurnRestrictionCellRenderer()); 348 addColumn(col); 349 } 350 } 351 352 private class FocusHandler extends FocusAdapter { 353 @Override 354 public void focusLost(FocusEvent e) { 355 // if we loose the focus to a component outside of the popup panel 356 // we hide the popup 357 if (e.getOppositeComponent() == null ||!SwingUtilities.isDescendingFrom(e.getOppositeComponent(), TurnRestrictionSelectionPopupPanel.this)) { 358 if (parentPopup != null){ 359 parentPopup.hide(); 360 } 361 } 362 } 363 } 364 364 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionType.java
r20586 r23192 9 9 */ 10 10 public enum TurnRestrictionType { 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 } 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 11 NO_RIGHT_TURN("no_right_turn", tr("No Right Turn")), 12 NO_LEFT_TURN("no_left_turn", tr("No Left Turn")), 13 NO_U_TURN("no_u_turn", tr("No U-Turn")), 14 NO_STRAIGHT_ON("no_straight_on", tr("No Straight On")), 15 ONLY_RIGHT_TURN("only_right_turn", tr("Only Right Turn")), 16 ONLY_LEFT_TURN("only_left_turn", tr("Only Left Turn")), 17 ONLY_STRAIGHT_ON("only_straight_on", tr("Only Straight On")); 18 19 private String tagValue; 20 private String displayName; 21 22 TurnRestrictionType(String tagValue, String displayName) { 23 this.tagValue = tagValue; 24 this.displayName = displayName; 25 } 26 27 /** 28 * Replies the tag value for a specific turn restriction type 29 * 30 * @return the tag value for a specific turn restriction type 31 */ 32 public String getTagValue() { 33 return tagValue; 34 } 35 36 /** 37 * Replies the localized display name for a turn restriction type 38 */ 39 public String getDisplayName() { 40 return displayName; 41 } 42 43 /** 44 * Replies the enumeration value for a given tag value. null, 45 * if {@code tagValue} is null or if there isnt an enumeration value 46 * for this {@code tagValue} 47 * 48 * @param tagValue the tag value, i.e. <tt>no_left_turn</tt> 49 * @return the enumeration value 50 */ 51 static public TurnRestrictionType fromTagValue(String tagValue) { 52 if (tagValue == null) return null; 53 for(TurnRestrictionType type: values()) { 54 if(type.getTagValue().equals(tagValue)) return type; 55 } 56 return null; 57 } 58 58 59 60 61 62 63 64 65 66 67 59 /** 60 * Replies true if {@code tagValue} is a standard restriction type. 61 * 62 * @param tagValue the tag value 63 * @return true if {@code tagValue} is a standard restriction type 64 */ 65 static public boolean isStandardTagValue(String tagValue){ 66 return fromTagValue(tagValue) != null; 67 } 68 68 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionTypeRenderer.java
r20666 r23192 20 20 public class TurnRestrictionTypeRenderer extends JLabel implements ListCellRenderer{ 21 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 } 22 final private Map<TurnRestrictionType, ImageIcon> icons = new HashMap<TurnRestrictionType, ImageIcon>(); 23 private String iconSet = "set-a"; 24 25 /** 26 * Loads the image icons for the rendered turn restriction types 27 */ 28 protected void loadImages() { 29 for(TurnRestrictionType type: TurnRestrictionType.values()) { 30 try { 31 ImageIcon icon = new ImageIcon(ImageProvider.get("types/" + iconSet, type.getTagValue()).getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH)); 32 icons.put(type,icon); 33 } catch(Exception e){ 34 System.out.println(tr("Warning: failed to load icon for turn restriction type ''{0}''", type.getTagValue())); 35 e.printStackTrace(); 36 } 37 } 38 } 39 40 public TurnRestrictionTypeRenderer() { 41 setOpaque(true); 42 loadImages(); 43 } 44 45 protected void renderColors(boolean isSelected){ 46 if (isSelected){ 47 setBackground(UIManager.getColor("List.selectionBackground")); 48 setForeground(UIManager.getColor("List.selectionForeground")); 49 } else { 50 setBackground(UIManager.getColor("List.background")); 51 setForeground(UIManager.getColor("List.foreground")); 52 } 53 } 54 55 /** 56 * Initializes the set of icons used from the preference key 57 * {@see PreferenceKeys#ROAD_SIGNS}. 58 * 59 * @param prefs the JOSM preferences 60 */ 61 public void initIconSetFromPreferences(Preferences prefs){ 62 iconSet = prefs.get(PreferenceKeys.ROAD_SIGNS, "set-a"); 63 iconSet = iconSet.trim().toLowerCase(); 64 if (!iconSet.equals("set-a") && !iconSet.equals("set-b")) { 65 iconSet = "set-a"; 66 } 67 loadImages(); 68 } 69 70 public Component getListCellRendererComponent(JList list, Object value, 71 int index, boolean isSelected, boolean cellHasFocus) { 72 73 renderColors(isSelected); 74 if (value == null) { 75 setText(tr("please select a turn restriction type")); 76 setIcon(null); 77 } else if (value instanceof String){ 78 setText((String)value); 79 setIcon(null); // FIXME: special icon for non-standard types? 80 } else if (value instanceof TurnRestrictionType){ 81 TurnRestrictionType type = (TurnRestrictionType)value; 82 setText(type.getDisplayName()); 83 setIcon(icons.get(type)); 84 } 85 return this; 86 } 87 87 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/VehicleExceptionEditor.java
r20648 r23192 36 36 */ 37 37 public class VehicleExceptionEditor extends JPanel implements Observer{ 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 38 static private final Logger logger = Logger.getLogger(VehicleExceptionEditor.class.getName()); 39 40 private TurnRestrictionEditorModel model; 41 private JCheckBox cbPsv; 42 private JCheckBox cbBicyle; 43 private JCheckBox cbHgv; 44 private JCheckBox cbMotorcar; 45 private JTextField tfNonStandardValue; 46 private ButtonGroup bgStandardOrNonStandard; 47 private JRadioButton rbStandardException; 48 private JRadioButton rbNonStandardException; 49 private JPanel pnlStandard; 50 private JPanel pnlNonStandard; 51 private ExceptValueModel exceptValue = new ExceptValueModel(); 52 53 private JPanel buildMessagePanel() { 54 JPanel pnl = new JPanel(new BorderLayout()); 55 HtmlPanel msg = new HtmlPanel(); 56 pnl.add(msg, BorderLayout.CENTER); 57 msg.setText( 58 "<html><body>" 59 + tr("Select the vehicle types this turn restriction is <strong>not</strong> applicable for.") 60 + "</body></html>" 61 ); 62 return pnl; 63 } 64 65 private JPanel buildStandardInputPanel() { 66 if (pnlStandard != null) 67 return pnlStandard; 68 69 StandardVehicleTypeChangeListener changeHandler = new StandardVehicleTypeChangeListener(); 70 71 GridBagConstraints gc = new GridBagConstraints(); 72 gc.anchor = GridBagConstraints.NORTHWEST; 73 gc.fill = GridBagConstraints.HORIZONTAL; 74 gc.gridx = 0; 75 gc.gridy = 0; 76 77 pnlStandard = new JPanel(new GridBagLayout()); 78 JLabel lbl; 79 cbPsv = new JCheckBox(); 80 cbPsv.addItemListener(changeHandler); 81 lbl = new JLabel(); 82 lbl.setText(tr("Public Service Vehicles")); 83 lbl.setToolTipText(tr("Public service vehicles like buses, tramways, etc.")); 84 lbl.setIcon(ImageProvider.get("vehicle", "psv")); 85 86 gc.weightx = 0.0; 87 pnlStandard.add(cbPsv, gc); 88 gc.weightx = 1.0; 89 gc.gridx++; 90 pnlStandard.add(lbl, gc); 91 92 cbHgv = new JCheckBox(); 93 cbHgv.addItemListener(changeHandler); 94 lbl = new JLabel(); 95 lbl.setText(tr("Heavy Goods Vehicles")); 96 lbl.setIcon(ImageProvider.get("vehicle", "hgv")); 97 98 gc.weightx = 0.0; 99 gc.gridx++; 100 pnlStandard.add(cbHgv, gc); 101 gc.weightx = 1.0; 102 gc.gridx++; 103 pnlStandard.add(lbl, gc); 104 105 cbMotorcar = new JCheckBox(); 106 cbMotorcar.addItemListener(changeHandler); 107 lbl = new JLabel(); 108 lbl.setText(tr("Motorcars")); 109 lbl.setIcon(ImageProvider.get("vehicle", "motorcar")); 110 111 gc.weightx = 0.0; 112 gc.gridx = 0; 113 gc.gridy = 1; 114 pnlStandard.add(cbMotorcar, gc); 115 gc.weightx = 1.0; 116 gc.gridx++; 117 pnlStandard.add(lbl, gc); 118 119 cbBicyle = new JCheckBox(); 120 cbBicyle.addItemListener(changeHandler); 121 lbl = new JLabel(); 122 lbl.setText(tr("Bicycles")); 123 lbl.setIcon(ImageProvider.get("vehicle", "bicycle")); 124 125 126 gc.weightx = 0.0; 127 gc.gridx++; 128 pnlStandard.add(cbBicyle, gc); 129 gc.weightx = 1.0; 130 gc.gridx++; 131 pnlStandard.add(lbl, gc); 132 133 return pnlStandard; 134 } 135 136 private JPanel buildNonStandardInputPanel() { 137 if (pnlNonStandard != null) 138 return pnlNonStandard; 139 pnlNonStandard = new JPanel(new GridBagLayout()); 140 GridBagConstraints gc = new GridBagConstraints(); 141 gc.anchor = GridBagConstraints.NORTHWEST; 142 gc.fill = GridBagConstraints.HORIZONTAL; 143 gc.weightx = 0.0; 144 gc.insets = new Insets(0, 0, 4, 0); 145 gc.gridx = 0; 146 gc.gridy = 0; 147 148 pnlNonStandard.add(new JLabel(tr("Value:")), gc); 149 gc.gridx = 1; 150 gc.weightx = 1.0; 151 pnlNonStandard.add(tfNonStandardValue = new JTextField(), gc); 152 SelectAllOnFocusGainedDecorator.decorate(tfNonStandardValue); 153 154 NonStandardVehicleTypesHandler inputChangedHandler = new NonStandardVehicleTypesHandler(); 155 tfNonStandardValue.addActionListener(inputChangedHandler); 156 tfNonStandardValue.addFocusListener(inputChangedHandler); 157 return pnlNonStandard; 158 } 159 160 /** 161 * Builds the UI for entering standard values 162 */ 163 protected void buildStandard() { 164 setLayout(new GridBagLayout()); 165 GridBagConstraints gc = new GridBagConstraints(); 166 gc.anchor = GridBagConstraints.NORTHWEST; 167 gc.fill = GridBagConstraints.HORIZONTAL; 168 gc.weightx = 1.0; 169 gc.gridx = 0; 170 gc.gridy = 0; 171 add(buildMessagePanel(), gc); 172 173 gc.gridy=1; 174 add(buildStandardInputPanel(), gc); 175 } 176 177 /** 178 * Builds the UI for entering either standard or non-standard values 179 */ 180 protected void buildNonStandard() { 181 setLayout(new GridBagLayout()); 182 GridBagConstraints gc = new GridBagConstraints(); 183 gc.anchor = GridBagConstraints.NORTHWEST; 184 gc.fill = GridBagConstraints.HORIZONTAL; 185 gc.weightx = 1.0; 186 gc.gridx = 0; 187 gc.gridy = 0; 188 add(buildMessagePanel(), gc); 189 190 gc.gridx=0; 191 gc.gridy=1; 192 gc.insets = new Insets(0,0,0,0); 193 add(rbStandardException = new JRadioButton(tr("Use standard exceptions")), gc); 194 195 gc.gridx=0; 196 gc.gridy=2; 197 gc.insets = new Insets(0, 20, 0,0); 198 add(buildStandardInputPanel(), gc); 199 200 gc.gridx=0; 201 gc.gridy=3; 202 gc.insets = new Insets(0,0,0,0); 203 add(rbNonStandardException = new JRadioButton(tr("Use non-standard exceptions")), gc); 204 205 gc.gridx=0; 206 gc.gridy=4; 207 gc.insets = new Insets(0, 20, 0,0); 208 add(buildNonStandardInputPanel(), gc); 209 210 bgStandardOrNonStandard = new ButtonGroup(); 211 bgStandardOrNonStandard.add(rbNonStandardException); 212 bgStandardOrNonStandard.add(rbStandardException); 213 214 StandardNonStandardChangeHander changeHandler = new StandardNonStandardChangeHander(); 215 rbNonStandardException.addItemListener(changeHandler); 216 rbStandardException.addItemListener(changeHandler); 217 } 218 219 protected void build() { 220 removeAll(); 221 buildNonStandardInputPanel(); 222 buildStandardInputPanel(); 223 if (exceptValue.isStandard()){ 224 buildStandard(); 225 } else { 226 buildNonStandard(); 227 } 228 init(); 229 invalidate(); 230 } 231 232 protected void init() { 233 cbPsv.setSelected(exceptValue.isVehicleException("psv")); 234 cbBicyle.setSelected(exceptValue.isVehicleException("bicycle")); 235 cbMotorcar.setSelected(exceptValue.isVehicleException("motorcar")); 236 cbHgv.setSelected(exceptValue.isVehicleException("hgv")); 237 if (!exceptValue.isStandard()){ 238 rbNonStandardException.setSelected(true); 239 tfNonStandardValue.setText(exceptValue.getValue()); 240 setEnabledNonStandardInputPanel(true); 241 setEnabledStandardInputPanel(false); 242 } else { 243 setEnabledNonStandardInputPanel(false); 244 setEnabledStandardInputPanel(true); 245 } 246 } 247 248 protected void setEnabledStandardInputPanel(boolean enabled) { 249 for (Component c: pnlStandard.getComponents()){ 250 c.setEnabled(enabled); 251 } 252 } 253 254 protected void setEnabledNonStandardInputPanel(boolean enabled) { 255 for (Component c: pnlNonStandard.getComponents()){ 256 c.setEnabled(enabled); 257 } 258 } 259 260 261 /** 262 * Creates the editor 263 * 264 * @param model the editor model. Must not be null. 265 * @throws IllegalArgumentException thrown if {@code model} is null 266 */ 267 public VehicleExceptionEditor(TurnRestrictionEditorModel model) throws IllegalArgumentException { 268 CheckParameterUtil.ensureParameterNotNull(model, "model"); 269 this.model = model; 270 build(); 271 model.addObserver(this); 272 } 273 274 /* ------------------------------------------------------------------------------------ */ 275 /* interface Observer */ 276 /* ------------------------------------------------------------------------------------ */ 277 public void update(Observable o, Object arg) { 278 if (!this.exceptValue.equals(model.getExcept())) { 279 this.exceptValue = model.getExcept(); 280 build(); 281 } 282 } 283 284 /* ------------------------------------------------------------------------------------ */ 285 /* inner classes */ 286 /* ------------------------------------------------------------------------------------ */ 287 class StandardNonStandardChangeHander implements ItemListener { 288 public void itemStateChanged(ItemEvent e) { 289 if (rbNonStandardException.isSelected()){ 290 setEnabledNonStandardInputPanel(true); 291 setEnabledStandardInputPanel(false); 292 exceptValue.setStandard(false); 293 } else { 294 setEnabledNonStandardInputPanel(false); 295 setEnabledStandardInputPanel(true); 296 exceptValue.setStandard(true); 297 } 298 model.setExcept(exceptValue); 299 } 300 } 301 302 class StandardVehicleTypeChangeListener implements ItemListener { 303 public void itemStateChanged(ItemEvent e) { 304 exceptValue.setVehicleException("bicycle", cbBicyle.isSelected()); 305 exceptValue.setVehicleException("hgv", cbHgv.isSelected()); 306 exceptValue.setVehicleException("psv", cbPsv.isSelected()); 307 exceptValue.setVehicleException("motorcar", cbMotorcar.isSelected()); 308 model.setExcept(exceptValue); 309 } 310 } 311 312 class NonStandardVehicleTypesHandler implements ActionListener, FocusListener { 313 public void persist() { 314 exceptValue.setValue(tfNonStandardValue.getText()); 315 model.setExcept(exceptValue); 316 } 317 318 public void focusGained(FocusEvent e) {} 319 public void focusLost(FocusEvent e) { 320 persist(); 321 } 322 323 public void actionPerformed(ActionEvent e) { 324 persist(); 325 } 326 } 327 327 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ViaList.java
r20489 r23192 46 46 */ 47 47 public class ViaList extends JList{ 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 } 150 } 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 } 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 } 306 } 48 49 static private final Logger logger = Logger.getLogger(ViaList.class.getName()); 50 51 private ViaListModel model; 52 private DeleteAction actDelete; 53 private MoveUpAction actMoveUp; 54 private MoveDownAction actMoveDown; 55 private CopyAction actCopy; 56 private PasteAction actPaste; 57 private TransferHandler transferHandler; 58 59 /** 60 * Constructor 61 * 62 * @param model the via list model. Must not be null. 63 * @param selectionModel the selection model. Must not be null. 64 * 65 */ 66 public ViaList(ViaListModel model, DefaultListSelectionModel selectionModel) { 67 super(model); 68 this.model = model; 69 setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 70 setSelectionModel(selectionModel); 71 setCellRenderer(new OsmPrimitivRenderer()); 72 setDragEnabled(true); 73 setTransferHandler(transferHandler =new ViaListTransferHandler(model)); 74 setVisibleRowCount(4); 75 76 actDelete = new DeleteAction(); 77 selectionModel.addListSelectionListener(actDelete); 78 registerKeyboardAction(actDelete, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 79 80 actMoveDown = new MoveDownAction(); 81 selectionModel.addListSelectionListener(actMoveDown); 82 registerKeyboardAction(actMoveDown, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_DOWN_MASK), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 83 84 actMoveUp = new MoveUpAction(); 85 selectionModel.addListSelectionListener(actMoveUp); 86 registerKeyboardAction(actMoveUp, KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_DOWN_MASK), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 87 88 actCopy = new CopyAction(); 89 actPaste = new PasteAction(); 90 getSelectionModel().addListSelectionListener(actCopy); 91 92 addMouseListener(new ViaListPopupMenuLaucher()); 93 } 94 95 /** 96 * The transfer handler for Drag-and-Drop. 97 */ 98 class ViaListTransferHandler extends PrimitiveIdListTransferHandler { 99 Logger logger = Logger.getLogger(ViaListTransferHandler.class.getName()); 100 101 private boolean isViaListInDragOperation = false; 102 private List<Integer> selectedRowsMemento = null; 103 104 public ViaListTransferHandler(PrimitiveIdListProvider provider) { 105 super(provider); 106 } 107 108 @Override 109 public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { 110 // a drag operation on itself is always allowed 111 if (isViaListInDragOperation) return true; 112 return isSupportedFlavor(transferFlavors); 113 } 114 115 @SuppressWarnings("unchecked") 116 @Override 117 public boolean importData(JComponent comp, Transferable t) { 118 if (!isSupportedFlavor(t.getTransferDataFlavors())) return false; 119 if (isViaListInDragOperation) { 120 // this is a drag operation on itself 121 int targetRow = getSelectedIndex(); 122 if (targetRow <0) return true; 123 model.moveVias(selectedRowsMemento, targetRow); 124 } else { 125 // this is a drag operation from another component 126 try { 127 List<PrimitiveId> idsToAdd = (List<PrimitiveId>)t.getTransferData(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR); 128 model.insertVias(idsToAdd); 129 } catch(IOException e){ 130 e.printStackTrace(); 131 } catch(UnsupportedFlavorException e){ 132 e.printStackTrace(); 133 } 134 } 135 return true; 136 } 137 138 @Override 139 protected void exportDone(JComponent source, Transferable data, int action) { 140 isViaListInDragOperation = false; 141 super.exportDone(source, data, action); 142 } 143 144 @Override 145 public void exportAsDrag(JComponent comp, InputEvent e, int action) { 146 isViaListInDragOperation = true; 147 selectedRowsMemento = model.getSelectedRows(); 148 super.exportAsDrag(comp, e, action); 149 } 150 } 151 152 class DeleteAction extends AbstractAction implements ListSelectionListener { 153 public DeleteAction() { 154 putValue(NAME, tr("Remove")); 155 putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete")); 156 putValue(SHORT_DESCRIPTION,tr("Remove the currently selected vias")); 157 putValue(ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0)); 158 updateEnabledState(); 159 } 160 161 public void valueChanged(ListSelectionEvent e) { 162 updateEnabledState(); 163 } 164 165 public void updateEnabledState() { 166 setEnabled(getSelectedIndex() >= 0); 167 } 168 169 public void actionPerformed(ActionEvent e) { 170 model.removeSelectedVias(); 171 } 172 } 173 174 class MoveDownAction extends AbstractAction implements ListSelectionListener{ 175 public MoveDownAction(){ 176 putValue(NAME, tr("Move down")); 177 putValue(SHORT_DESCRIPTION, tr("Move the selected vias down by one position")); 178 putValue(ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_DOWN_MASK)); 179 putValue(SMALL_ICON, ImageProvider.get("dialogs", "movedown")); 180 updateEnabledState(); 181 } 182 183 public void actionPerformed(ActionEvent e) { 184 model.moveDown(); 185 } 186 187 public void updateEnabledState(){ 188 if (getSelectedIndex() < 0) { 189 setEnabled(false); 190 return; 191 } 192 setEnabled(getSelectionModel().getMaxSelectionIndex() < getModel().getSize() -1); 193 } 194 195 public void valueChanged(ListSelectionEvent e) { 196 updateEnabledState(); 197 } 198 } 199 200 class MoveUpAction extends AbstractAction implements ListSelectionListener{ 201 public MoveUpAction() { 202 putValue(NAME, tr("Move up")); 203 putValue(SHORT_DESCRIPTION, tr("Move the selected vias up by one position")); 204 putValue(ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_DOWN_MASK)); 205 putValue(SMALL_ICON, ImageProvider.get("dialogs", "moveup")); 206 updateEnabledState(); 207 } 208 209 public void actionPerformed(ActionEvent e) { 210 model.moveUp(); 211 } 212 213 public void updateEnabledState(){ 214 if (getSelectedIndex() < 0) { 215 setEnabled(false); 216 return; 217 } 218 setEnabled(getSelectionModel().getMinSelectionIndex() > 0); 219 } 220 221 public void valueChanged(ListSelectionEvent e) { 222 updateEnabledState(); 223 } 224 } 225 226 class CopyAction extends AbstractAction implements ListSelectionListener { 227 private Action delegate; 228 229 public CopyAction(){ 230 putValue(NAME, tr("Copy")); 231 putValue(SHORT_DESCRIPTION, tr("Copy the selected vias to the clipboard")); 232 putValue(SMALL_ICON, ImageProvider.get("copy")); 233 putValue(ACCELERATOR_KEY, Shortcut.getCopyKeyStroke()); 234 delegate = ViaList.this.getActionMap().get("copy"); 235 } 236 237 public void actionPerformed(ActionEvent e) { 238 delegate.actionPerformed(e); 239 } 240 241 protected void updateEnabledState() { 242 setEnabled(!model.getSelectedVias().isEmpty()); 243 } 244 245 public void valueChanged(ListSelectionEvent e) { 246 updateEnabledState(); 247 } 248 } 249 250 class PasteAction extends AbstractAction { 251 private Action delegate; 252 253 public boolean canPaste() { 254 Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 255 for (DataFlavor df: clipboard.getAvailableDataFlavors()) { 256 if (df.equals(PrimitiveIdTransferable.PRIMITIVE_ID_LIST_FLAVOR)) return true; 257 } 258 // FIXME: check whether there are selected objects in the JOSM copy/paste buffer 259 return false; 260 } 261 262 public PasteAction(){ 263 putValue(NAME, tr("Paste")); 264 putValue(SHORT_DESCRIPTION, tr("Insert 'via' objects from the clipboard")); 265 putValue(SMALL_ICON, ImageProvider.get("paste")); 266 putValue(ACCELERATOR_KEY, Shortcut.getPasteKeyStroke()); 267 delegate = ViaList.this.getActionMap().get("paste"); 268 updateEnabledState(); 269 } 270 271 public void updateEnabledState() { 272 setEnabled(canPaste()); 273 } 274 275 public void actionPerformed(ActionEvent e) { 276 delegate.actionPerformed(e); 277 } 278 } 279 280 class ViaListPopupMenu extends JPopupMenu { 281 public ViaListPopupMenu() { 282 JMenuItem item = add(actCopy); 283 item.setTransferHandler(transferHandler); 284 item = add(actPaste); 285 actPaste.updateEnabledState(); 286 item.setTransferHandler(transferHandler); 287 addSeparator(); 288 add(actDelete); 289 addSeparator(); 290 add(actMoveUp); 291 add(actMoveDown); 292 } 293 } 294 295 class ViaListPopupMenuLaucher extends PopupMenuLauncher { 296 @Override 297 public void launch(MouseEvent evt) { 298 if (getSelectedIndex() <0) { 299 int idx = locationToIndex(evt.getPoint()); 300 if (idx >=0) { 301 setSelectedIndex(idx); 302 } 303 } 304 new ViaListPopupMenu().show(ViaList.this, evt.getX(), evt.getY()); 305 } 306 } 307 307 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ViaListModel.java
r20527 r23192 23 23 */ 24 24 public class ViaListModel extends AbstractListModel implements PrimitiveIdListProvider, Observer{ 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 } 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 } 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 } 25 static private final Logger logger = Logger.getLogger(ViaListModel.class.getName()); 26 27 private DefaultListSelectionModel selectionModel; 28 private final ArrayList<OsmPrimitive> vias = new ArrayList<OsmPrimitive>(); 29 private TurnRestrictionEditorModel model; 30 31 /** 32 * Constructor 33 * 34 * @param model the turn restriction editor model. Must not be null. 35 * @param selectionModel the selection model. Must not be null. 36 * @throws IllegalArgumentException thrown if model is null 37 * @throws IllegalArgumentException thrown if selectionModel is null 38 */ 39 public ViaListModel(TurnRestrictionEditorModel model, DefaultListSelectionModel selectionModel) { 40 CheckParameterUtil.ensureParameterNotNull(model, "model"); 41 CheckParameterUtil.ensureParameterNotNull(selectionModel, "selectionModel"); 42 this.model = model; 43 this.selectionModel = selectionModel; 44 model.addObserver(this); 45 refresh(); 46 } 47 48 /** 49 * Replies the list of currently selected vias 50 * 51 * @return the list of currently selected vias 52 */ 53 public List<OsmPrimitive> getSelectedVias() { 54 ArrayList<OsmPrimitive> ret = new ArrayList<OsmPrimitive>(); 55 for (int i=0; i < getSize(); i++) { 56 if (selectionModel.isSelectedIndex(i)) { 57 ret.add(vias.get(i)); 58 } 59 } 60 return ret; 61 } 62 63 /** 64 * Sets the collection of currently selected vias 65 * 66 * @param vias a collection of vias 67 */ 68 public void setSelectedVias(Collection<OsmPrimitive> vias) { 69 selectionModel.clearSelection(); 70 if (vias == null) return; 71 for(OsmPrimitive via: vias) { 72 int idx = this.vias.indexOf(via); 73 if (idx < 0) continue; 74 selectionModel.addSelectionInterval(idx, idx); 75 } 76 } 77 78 /** 79 * Replies the list of selected rows 80 * 81 * @return the list of selected rows 82 */ 83 public List<Integer> getSelectedRows() { 84 ArrayList<Integer> ret = new ArrayList<Integer>(); 85 for (int i=0; i < getSize(); i++) { 86 if (selectionModel.isSelectedIndex(i)) { 87 ret.add(i); 88 } 89 } 90 return ret; 91 } 92 93 protected List<Integer> moveUp(List<Integer> rows, int targetRow) { 94 List<Integer> ret = new ArrayList<Integer>(rows.size()); 95 int delta = rows.get(0) - targetRow; 96 for(int row: rows) { 97 OsmPrimitive via = vias.remove(row); 98 vias.add(row - delta, via); 99 ret.add(row - delta); 100 } 101 return ret; 102 } 103 104 protected List<Integer> moveDown(List<Integer> rows, int targetRow) { 105 List<Integer> ret = new ArrayList<Integer>(rows.size()); 106 int delta = targetRow - rows.get(0); 107 for(int i = rows.size()-1; i >=0; i--) { 108 int row = rows.get(i); 109 OsmPrimitive via = vias.remove(row); 110 vias.add(row + delta, via); 111 ret.add(row + delta); 112 } 113 return ret; 114 } 115 116 public void moveVias(List<Integer> selectedRows, int targetRow){ 117 if (selectedRows == null) return; 118 if (selectedRows.size() == 1){ 119 int sourceRow = selectedRows.get(0); 120 if (sourceRow == targetRow) return; 121 OsmPrimitive via = vias.remove(sourceRow); 122 vias.add(targetRow, via); 123 fireContentsChanged(this, 0, getSize()); 124 selectionModel.setSelectionInterval(targetRow, targetRow); 125 return; 126 } 127 int min = selectedRows.get(0); 128 int max = selectedRows.get(selectedRows.size()-1); 129 if (targetRow < min) { 130 selectedRows = moveUp(selectedRows, targetRow); 131 } else if (targetRow == min){ 132 // do nothing 133 } else if (targetRow - min < getSize() - max){ 134 int delta = Math.min(targetRow - min, getSize()-1 - max); 135 targetRow = min + delta; 136 if (targetRow > min) { 137 selectedRows = moveDown(selectedRows, targetRow); 138 } 139 } 140 fireContentsChanged(this, 0, getSize()); 141 selectionModel.clearSelection(); 142 for(int row: selectedRows) { 143 selectionModel.addSelectionInterval(row, row); 144 } 145 } 146 147 /** 148 * Move the currently selected vias up by one position 149 */ 150 public void moveUp() { 151 List<Integer> sel = getSelectedRows(); 152 if (sel.isEmpty() || sel.get(0) == 0) return; 153 moveVias(sel, sel.get(0)-1); 154 } 155 156 /** 157 * Move the currently selected vias down by one position 158 */ 159 public void moveDown() { 160 List<Integer> sel = getSelectedRows(); 161 if (sel.isEmpty() || sel.get(sel.size()-1) == getSize()-1) return; 162 moveVias(sel, sel.get(sel.size()-1)+1); 163 } 164 165 /** 166 * Inserts a list of OSM objects given by OSM primitive ids. 167 * 168 * @param idsToInsert the ids of the objects to insert 169 */ 170 public void insertVias(List<PrimitiveId> idsToInsert) { 171 if (idsToInsert == null) return; 172 List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>(idsToInsert.size()); 173 DataSet ds = model.getLayer().data; 174 for(PrimitiveId id: idsToInsert){ 175 OsmPrimitive p = ds.getPrimitiveById(id); 176 if (p == null){ 177 System.out.println(tr("Failed to retrieve OSM object with id {0} from dataset {1}. Cannot add it as ''via''.", id, ds)); 178 continue; 179 } 180 primitives.add(p); 181 } 182 int targetRow = Math.max(selectionModel.getMinSelectionIndex(),0); 183 List<OsmPrimitive> newVias = new ArrayList<OsmPrimitive>(vias); 184 newVias.addAll(targetRow, primitives); 185 model.setVias(newVias); 186 fireContentsChanged(this, 0, getSize()); 187 selectionModel.clearSelection(); 188 for(int i=targetRow; i< targetRow + primitives.size();i++) { 189 selectionModel.addSelectionInterval(i, i); 190 } 191 } 192 193 /** 194 * Removes the currently selected vias 195 */ 196 public void removeSelectedVias() { 197 ArrayList<OsmPrimitive> newVias = new ArrayList<OsmPrimitive>(vias); 198 int j = 0; 199 for(int i=0; i< getSize();i++){ 200 if (!selectionModel.isSelectedIndex(i)) continue; 201 newVias.remove(i-j); 202 j++; 203 } 204 if (j == 0) return; // nothing selected, nothing deleted 205 model.setVias(newVias); 206 } 207 208 /** 209 * Refreshes the list of 'vias' in this model with the current list of 210 * vias from the turn restriction model. 211 */ 212 protected void refresh() { 213 List<OsmPrimitive> sel = getSelectedVias(); 214 vias.clear(); 215 vias.addAll(model.getVias()); 216 fireContentsChanged(this, 0, getSize()); 217 setSelectedVias(sel); 218 } 219 220 public Object getElementAt(int index) { 221 return vias.get(index); 222 } 223 224 public int getSize() { 225 return vias.size(); 226 } 227 228 /* ----------------------------------------------------------------------- */ 229 /* interface PrimitiveIdListProvider */ 230 /* ----------------------------------------------------------------------- */ 231 public List<PrimitiveId> getSelectedPrimitiveIds() { 232 ArrayList<PrimitiveId> ids = new ArrayList<PrimitiveId>(); 233 for (OsmPrimitive p: getSelectedVias()) { 234 ids.add(p.getPrimitiveId()); 235 } 236 return ids; 237 } 238 239 /* ----------------------------------------------------------------------- */ 240 /* interface Observer */ 241 /* ----------------------------------------------------------------------- */ 242 public void update(Observable o, Object arg) { 243 refresh(); 244 } 245 245 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/AbstractTurnRestrictionsListView.java
r20666 r23192 15 15 */ 16 16 abstract class AbstractTurnRestrictionsListView extends JPanel { 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 17 protected TurnRestrictionsListModel model; 18 protected JList lstTurnRestrictions; 19 20 public TurnRestrictionsListModel getModel(){ 21 return model; 22 } 23 24 public JList getList() { 25 return lstTurnRestrictions; 26 } 27 28 public void addListSelectionListener(ListSelectionListener listener) { 29 lstTurnRestrictions.addListSelectionListener(listener); 30 } 31 32 public void removeListSelectionListener(ListSelectionListener listener) { 33 lstTurnRestrictions.addListSelectionListener(listener); 34 } 35 36 public void initIconSetFromPreferences(Preferences prefs){ 37 TurnRestrictionCellRenderer renderer = (TurnRestrictionCellRenderer)lstTurnRestrictions.getCellRenderer(); 38 renderer.initIconSetFromPreferences(prefs); 39 } 40 40 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionCellRenderer.java
r20701 r23192 41 41 */ 42 42 public class TurnRestrictionCellRenderer extends JPanel implements ListCellRenderer, TableCellRenderer{ 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 } 43 static private final Logger logger = Logger.getLogger(TurnRestrictionCellRenderer.class.getName()); 44 45 /** the names of restriction types */ 46 static private Set<String> RESTRICTION_TYPES = new HashSet<String>( 47 Arrays.asList(new String[] { 48 "no_left_turn", 49 "no_right_turn", 50 "no_straight_on", 51 "no_u_turn", 52 "only_left_turn", 53 "only_right_turn", 54 "only_straight_on" 55 }) 56 ); 57 58 /** components used to render the turn restriction */ 59 private JLabel icon; 60 private JLabel from; 61 private JLabel to; 62 private String iconSet = "set-a"; 63 64 public TurnRestrictionCellRenderer() { 65 build(); 66 } 67 68 /** 69 * Replies true if {@code restrictionType} is a valid restriction 70 * type. 71 * 72 * @param restrictionType the restriction type 73 * @return true if {@code restrictionType} is a valid restriction 74 * type 75 */ 76 protected boolean isValidRestrictionType(String restrictionType) { 77 if (restrictionType == null) return false; 78 restrictionType = restrictionType.trim().toLowerCase(); 79 return RESTRICTION_TYPES.contains(restrictionType); 80 } 81 82 /** 83 * Builds the icon name for a given restriction type 84 * 85 * @param restrictionType the restriction type 86 * @return the icon name 87 */ 88 protected String buildImageName(String restrictionType) { 89 return "types/" + iconSet + "/" + restrictionType; 90 } 91 92 /** 93 * Replies the icon for a given restriction type 94 * @param restrictionType the restriction type 95 * @return the icon 96 */ 97 protected ImageIcon getIcon(String restrictionType) { 98 if (!isValidRestrictionType(restrictionType)) { 99 return ImageProvider.get("types", "non-standard-type"); 100 } 101 return ImageProvider.get(buildImageName(restrictionType)); 102 } 103 104 /** 105 * Builds the UI used to render turn restrictions 106 */ 107 protected void build() { 108 setLayout(new GridBagLayout()); 109 GridBagConstraints gc = new GridBagConstraints(); 110 111 // the turn restriction icon 112 gc.fill = GridBagConstraints.HORIZONTAL; 113 gc.weightx = 0.0; 114 gc.gridheight = 2; 115 gc.anchor = GridBagConstraints.CENTER; 116 gc.insets = new Insets(0,0,2,2); 117 add(icon = new JLabel(), gc); 118 119 120 // the name of the way with role "from" 121 gc.anchor = GridBagConstraints.NORTHWEST; 122 gc.gridx = 1; 123 gc.gridheight = 1; 124 gc.weightx = 0.0; 125 add(new JMultilineLabel("<html><strong>" + trc("turnrestrictions","From:") + "</strong></html>"), gc); 126 127 gc.gridx = 2; 128 gc.weightx = 1.0; 129 add(from = new JLabel(), gc); 130 131 // the name of the way with role "to" 132 gc.anchor = GridBagConstraints.NORTHWEST; 133 gc.gridx = 1; 134 gc.gridy = 1; 135 gc.weightx = 0.0; 136 add(new JMultilineLabel("<html><strong>" + trc("turnrestriction", "To:") + "</strong></html>"), gc); 137 138 gc.gridx = 2; 139 gc.weightx = 1.0; 140 add(to = new JLabel(), gc); 141 } 142 143 /** 144 * Renders the icon for the turn restriction 145 * 146 * @param tr the turn restriction 147 */ 148 protected void renderIcon(Relation tr) { 149 String restrictionType = tr.get("restriction"); 150 icon.setIcon(getIcon(restrictionType)); 151 } 152 153 /** 154 * Replies a way participating in this turn restriction in a given role 155 * 156 * @param tr the turn restriction 157 * @param role the role (either "from" or "to") 158 * @return the participating way; null, if no way is participating in this role 159 */ 160 private Way getParticipatingWay(Relation tr, String role){ 161 for(RelationMember rm: tr.getMembers()){ 162 if (rm.getRole().trim().toLowerCase().equals(role) && rm.getType().equals(OsmPrimitiveType.WAY)) { 163 return (Way)rm.getMember(); 164 } 165 } 166 return null; 167 } 168 169 protected void renderFrom(Relation tr) { 170 Way from = getParticipatingWay(tr, "from"); 171 if (from == null) { 172 // FIXME: render as warning/error (red background?) 173 this.from.setText(tr("no participating way with role ''from''")); 174 return; 175 } 176 this.from.setText(DefaultNameFormatter.getInstance().format(from)); 177 } 178 179 protected void renderTo(Relation tr) { 180 Way to = getParticipatingWay(tr, "to"); 181 if (to == null) { 182 // FIXME: render as warning/error (red background?) 183 this.to.setText(tr("no participating way with role ''to''")); 184 return; 185 } 186 this.to.setText(DefaultNameFormatter.getInstance().format(to)); 187 } 188 189 /** 190 * Renders the foreground and background color depending on whether 191 * the turn restriction is selected 192 * 193 * @param isSelected true if the turn restriction is selected; false, 194 * otherwise 195 */ 196 protected void renderColor(boolean isSelected) { 197 Color bg; 198 Color fg; 199 if (isSelected) { 200 bg = UIManager.getColor("List.selectionBackground"); 201 fg = UIManager.getColor("List.selectionForeground"); 202 } else { 203 bg = UIManager.getColor("background"); 204 fg = UIManager.getColor("foreground"); 205 } 206 setBackground(bg); 207 this.icon.setBackground(bg); 208 this.from.setBackground(bg); 209 this.to.setBackground(bg); 210 211 setForeground(fg); 212 this.icon.setForeground(fg); 213 this.from.setForeground(fg); 214 this.to.setForeground(fg); 215 } 216 217 /** 218 * Initializes the set of icons used from the preference key 219 * {@see PreferenceKeys#ROAD_SIGNS}. 220 * 221 * @param prefs the JOSM preferences 222 */ 223 public void initIconSetFromPreferences(Preferences prefs){ 224 225 iconSet = prefs.get(PreferenceKeys.ROAD_SIGNS, "set-a"); 226 iconSet = iconSet.trim().toLowerCase(); 227 if (!iconSet.equals("set-a") && !iconSet.equals("set-b")) { 228 iconSet = "set-a"; 229 } 230 } 231 232 /* ---------------------------------------------------------------------------------- */ 233 /* interface ListCellRenderer */ 234 /* ---------------------------------------------------------------------------------- */ 235 public Component getListCellRendererComponent(JList list, Object value, 236 int index, boolean isSelected, boolean cellHasFocus) { 237 238 renderColor(isSelected); 239 Relation tr = (Relation)value; 240 renderIcon(tr); 241 renderFrom(tr); 242 renderTo(tr); 243 return this; 244 } 245 246 /* ---------------------------------------------------------------------------------- */ 247 /* interface TableCellRenderer */ 248 /* ---------------------------------------------------------------------------------- */ 249 public Component getTableCellRendererComponent(JTable table, Object value, 250 boolean isSelected, boolean hasFocus, int row, int column) { 251 renderColor(isSelected); 252 Relation tr = (Relation)value; 253 renderIcon(tr); 254 renderFrom(tr); 255 renderTo(tr); 256 return this; 257 } 258 258 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInDatasetListModel.java
r20489 r23192 34 34 */ 35 35 public class TurnRestrictionsInDatasetListModel extends TurnRestrictionsListModel implements EditLayerChangeListener, DataSetListener { 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 36 private static final Logger logger = Logger.getLogger(TurnRestrictionsInDatasetListModel.class.getName()); 37 38 public TurnRestrictionsInDatasetListModel( 39 DefaultListSelectionModel selectionModel) { 40 super(selectionModel); 41 } 42 43 /** 44 * Filters the list of turn restrictions from a collection of OSM primitives. 45 * 46 * @param primitives the primitives 47 * @return the list of turn restrictions 48 */ 49 protected List<Relation> filterTurnRestrictions(Collection<? extends OsmPrimitive> primitives) { 50 List<Relation> ret = new LinkedList<Relation>(); 51 if (primitives == null) return ret; 52 for(OsmPrimitive p: primitives){ 53 if (!isTurnRestriction(p)) continue; 54 ret.add((Relation)p); 55 } 56 return ret; 57 } 58 59 /* --------------------------------------------------------------------------- */ 60 /* interface EditLayerChangeListener */ 61 /* --------------------------------------------------------------------------- */ 62 public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) { 63 if (newLayer == null) { 64 setTurnRestrictions(null); 65 return; 66 } 67 List<Relation> turnRestrictions = new LinkedList<Relation>(); 68 for (Relation r: newLayer.data.getRelations()) { 69 if (isValid(r) && isTurnRestriction(r)) { 70 turnRestrictions.add(r); 71 } 72 } 73 setTurnRestrictions(turnRestrictions); 74 } 75 76 /* --------------------------------------------------------------------------- */ 77 /* interface DataSetListener */ 78 /* --------------------------------------------------------------------------- */ 79 public void dataChanged(DataChangedEvent event) { 80 OsmDataLayer layer = Main.map.mapView.getEditLayer(); 81 if (layer == null) { 82 setTurnRestrictions(null); 83 } else { 84 List<Relation> turnRestrictions = filterTurnRestrictions(layer.data.getRelations()); 85 setTurnRestrictions(turnRestrictions); 86 } 87 } 88 88 89 90 91 92 93 94 89 public void primtivesAdded(PrimitivesAddedEvent event) { 90 List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives()); 91 if (!turnRestrictions.isEmpty()) { 92 addTurnRestrictions(turnRestrictions); 93 } 94 } 95 95 96 97 98 99 100 101 96 public void primtivesRemoved(PrimitivesRemovedEvent event) { 97 List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives()); 98 if (!turnRestrictions.isEmpty()) { 99 removeTurnRestrictions(turnRestrictions); 100 } 101 } 102 102 103 104 105 106 107 108 109 110 111 112 113 114 103 public void relationMembersChanged(RelationMembersChangedEvent event) { 104 List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives()); 105 if (!turnRestrictions.isEmpty()) { 106 List<Relation> sel = getSelectedTurnRestrictions(); 107 for(Relation tr: turnRestrictions) { 108 // enforce a repaint of the respective turn restriction 109 int idx = getTurnRestrictionIndex(tr); 110 fireContentsChanged(this, idx,idx); 111 } 112 setSelectedTurnRestrictions(sel); 113 } 114 } 115 115 116 117 118 119 120 121 122 123 124 125 126 } 127 116 public void tagsChanged(TagsChangedEvent event) { 117 List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives()); 118 if (!turnRestrictions.isEmpty()) { 119 List<Relation> sel = getSelectedTurnRestrictions(); 120 for(Relation tr: turnRestrictions) { 121 // enforce a repaint of the respective turn restriction 122 int idx = getTurnRestrictionIndex(tr); 123 fireContentsChanged(this, idx,idx); 124 } 125 setSelectedTurnRestrictions(sel); 126 } 127 } 128 128 129 130 131 129 public void wayNodesChanged(WayNodesChangedEvent event) {/* ignore */} 130 public void nodeMoved(NodeMovedEvent event) {/* ignore */} 131 public void otherDatasetChange(AbstractDatasetChangedEvent event) {/* ignore */} 132 132 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInDatasetView.java
r20711 r23192 18 18 * This is the view for the list of turn restrictions in the current data set. 19 19 */ 20 public class TurnRestrictionsInDatasetView extends AbstractTurnRestrictionsListView{ 21 22 23 24 25 26 27 28 29 30 31 20 public class TurnRestrictionsInDatasetView extends AbstractTurnRestrictionsListView{ 21 protected void build() { 22 DefaultListSelectionModel selectionModel = new DefaultListSelectionModel(); 23 model = new TurnRestrictionsInDatasetListModel(selectionModel); 24 lstTurnRestrictions = new JList(model); 25 lstTurnRestrictions.setSelectionModel(selectionModel); 26 lstTurnRestrictions.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 27 lstTurnRestrictions.setCellRenderer(new TurnRestrictionCellRenderer()); 28 29 setLayout(new BorderLayout()); 30 add(new JScrollPane(lstTurnRestrictions), BorderLayout.CENTER); 31 } 32 32 33 34 35 36 37 38 39 33 protected void registerAsListener() { 34 MapView.addEditLayerChangeListener((EditLayerChangeListener)model); 35 DatasetEventManager.getInstance().addDatasetListener((DataSetListener)model, FireMode.IN_EDT); 36 if (Main.main.getEditLayer() != null) { 37 model.setTurnRestrictions(Main.main.getEditLayer().data.getRelations()); 38 } 39 } 40 40 41 42 43 44 41 protected void unregisterAsListener() { 42 MapView.removeEditLayerChangeListener((EditLayerChangeListener)model); 43 DatasetEventManager.getInstance().removeDatasetListener((DataSetListener)model); 44 } 45 45 46 47 48 46 public TurnRestrictionsInDatasetView() { 47 build(); 48 } 49 49 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInSelectionListModel.java
r20489 r23192 19 19 */ 20 20 public class TurnRestrictionsInSelectionListModel extends TurnRestrictionsListModel implements EditLayerChangeListener, SelectionChangedListener { 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 21 private static final Logger logger = Logger.getLogger(TurnRestrictionsInSelectionListModel.class.getName()); 22 23 public TurnRestrictionsInSelectionListModel( 24 DefaultListSelectionModel selectionModel) { 25 super(selectionModel); 26 } 27 28 /** 29 * Initializes the model with the turn restrictions the primitives in 30 * {@code selection} participate. 31 * 32 * @param selection the collection of selected primitives 33 */ 34 public void initFromSelection(Collection<? extends OsmPrimitive> selection) { 35 Set<Relation> turnRestrictions = new HashSet<Relation>(); 36 if (selection == null) return; 37 for (OsmPrimitive p: selection) { 38 for (OsmPrimitive parent: p.getReferrers()) { 39 if (isTurnRestriction(parent)) 40 turnRestrictions.add((Relation)parent); 41 } 42 } 43 setTurnRestrictions(turnRestrictions); 44 } 45 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 46 /* --------------------------------------------------------------------------- */ 47 /* interface EditLayerChangeListener */ 48 /* --------------------------------------------------------------------------- */ 49 public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) { 50 if (newLayer == null) { 51 setTurnRestrictions(null); 52 return; 53 } 54 initFromSelection(newLayer.data.getSelected()); 55 } 56 57 /* --------------------------------------------------------------------------- */ 58 /* interface SelectionChangedListener */ 59 /* --------------------------------------------------------------------------- */ 60 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 61 initFromSelection(newSelection); 62 } 63 63 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInSelectionView.java
r20711 r23192 24 24 public class TurnRestrictionsInSelectionView extends AbstractTurnRestrictionsListView { 25 25 26 27 28 29 30 31 32 33 34 35 36 26 protected void build() { 27 DefaultListSelectionModel selectionModel = new DefaultListSelectionModel(); 28 model = new TurnRestrictionsInSelectionListModel(selectionModel); 29 lstTurnRestrictions = new JList(model); 30 lstTurnRestrictions.setSelectionModel(selectionModel); 31 lstTurnRestrictions.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 32 lstTurnRestrictions.setCellRenderer(new TurnRestrictionCellRenderer()); 33 34 setLayout(new BorderLayout()); 35 add(new JScrollPane(lstTurnRestrictions), BorderLayout.CENTER); 36 } 37 37 38 39 40 41 42 43 44 45 46 47 38 protected void registerAsListener() { 39 MapView.addEditLayerChangeListener((EditLayerChangeListener)model); 40 SelectionEventManager.getInstance().addSelectionListener((SelectionChangedListener)model, FireMode.IN_EDT_CONSOLIDATED); 41 TurnRestrictionsInSelectionListModel m = (TurnRestrictionsInSelectionListModel)model; 42 if (Main.main.getEditLayer() != null){ 43 m.initFromSelection(Main.main.getEditLayer().data.getSelected()); 44 } else { 45 m.initFromSelection(Collections.<OsmPrimitive>emptyList()); 46 } 47 } 48 48 49 50 51 52 49 protected void unregisterAsListener() { 50 MapView.removeEditLayerChangeListener((EditLayerChangeListener)model); 51 SelectionEventManager.getInstance().removeSelectionListener((SelectionChangedListener)model); 52 } 53 53 54 55 56 54 public TurnRestrictionsInSelectionView() { 55 build(); 56 } 57 57 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsListDialog.java
r20735 r23192 52 52 */ 53 53 public class TurnRestrictionsListDialog extends ToggleDialog{ 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 } 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 54 private static final Logger logger = Logger.getLogger(TurnRestrictionsListDialog.class.getName()); 55 56 /** checkbox for switching between the two list views */ 57 private JCheckBox cbInSelectionOnly; 58 /** the view for the turn restrictions in the current data set */ 59 private TurnRestrictionsInDatasetView pnlTurnRestrictionsInDataSet; 60 /** the view for the turn restrictions related to the current selection */ 61 private TurnRestrictionsInSelectionView pnlTurnRestrictionsInSelection; 62 63 /** three actions */ 64 private NewAction actNew; 65 private EditAction actEdit; 66 private DeleteAction actDelete; 67 private SelectSelectedTurnRestrictions actSelectSelectedTurnRestrictions; 68 private ZoomToAction actZoomTo; 69 private SwitchListViewHandler switchListViewHandler; 70 71 private AbstractTurnRestrictionsListView currentListView = null; 72 73 /** the main content panel in this toggle dialog */ 74 private JPanel pnlContent; 75 private PreferenceChangeHandler preferenceChangeHandler; 76 77 @Override 78 public void showNotify() { 79 pnlTurnRestrictionsInDataSet.registerAsListener(); 80 pnlTurnRestrictionsInSelection.registerAsListener(); 81 MapView.addEditLayerChangeListener(actNew); 82 actNew.updateEnabledState(); 83 Main.pref.addPreferenceChangeListener(preferenceChangeHandler); 84 preferenceChangeHandler.refreshIconSet(); 85 } 86 87 @Override 88 public void hideNotify() { 89 pnlTurnRestrictionsInDataSet.unregisterAsListener(); 90 pnlTurnRestrictionsInSelection.unregisterAsListener(); 91 MapView.removeEditLayerChangeListener(actNew); 92 Main.pref.removePreferenceChangeListener(preferenceChangeHandler); 93 } 94 95 /** 96 * Builds the panel with the checkbox for switching between the two 97 * list views 98 * 99 * @return the panel 100 */ 101 protected JPanel buildInSelectionOnlyTogglePanel(){ 102 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0)); 103 pnl.setBorder(null); 104 pnl.add(cbInSelectionOnly = new JCheckBox(tr("Only participating in selection"))); 105 cbInSelectionOnly.setToolTipText(tr( 106 "<html>Select to display turn restrictions related to object in the current selection only.<br>" 107 + "Deselect to display all turn restrictions in the current data set.</html>")); 108 return pnl; 109 } 110 111 /** 112 * Builds the panel with the action buttons 113 * 114 * @return the panel 115 */ 116 protected JPanel buildCommandPanel() { 117 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0)); 118 pnl.setBorder(null); 119 pnl.add(new SideButton(actNew = new NewAction(), false /* don't show the name */)); 120 pnl.add(new SideButton(actEdit = new EditAction(), false /* don't show the name */)); 121 pnl.add(new SideButton(actDelete = new DeleteAction(), false /* don't show the name */)); 122 123 actSelectSelectedTurnRestrictions = new SelectSelectedTurnRestrictions(); 124 actZoomTo = new ZoomToAction(); 125 return pnl; 126 } 127 128 /** 129 * Builds the UI 130 */ 131 protected void build() { 132 pnlContent = new JPanel(new BorderLayout(0,0)); 133 pnlContent.setBorder(null); 134 pnlContent.add(buildInSelectionOnlyTogglePanel(), BorderLayout.NORTH); 135 pnlContent.add(buildCommandPanel(), BorderLayout.SOUTH); 136 137 add(pnlContent, BorderLayout.CENTER); 138 139 // create the two list views 140 pnlTurnRestrictionsInDataSet = new TurnRestrictionsInDatasetView(); 141 pnlTurnRestrictionsInSelection = new TurnRestrictionsInSelectionView(); 142 143 // wire the handler for switching between list views 144 switchListViewHandler = new SwitchListViewHandler(); 145 switchListViewHandler.activateListView(pnlTurnRestrictionsInDataSet); 146 cbInSelectionOnly.addItemListener(switchListViewHandler); 147 148 // wire the popup menu launcher to the two turn restriction lists 149 TurnRestrictionsPopupLauncher launcher = new TurnRestrictionsPopupLauncher(); 150 pnlTurnRestrictionsInDataSet.getList().addMouseListener(launcher); 151 pnlTurnRestrictionsInSelection.getList().addMouseListener(launcher); 152 153 preferenceChangeHandler = new PreferenceChangeHandler(); 154 155 } 156 157 /** 158 * Constructor 159 */ 160 public TurnRestrictionsListDialog() { 161 super( 162 tr("Turn Restrictions"), 163 "turnrestrictions", 164 tr("Display and manage turn restrictions in the current data set"), 165 null, // no shortcut 166 150 // default height 167 ); 168 build(); 169 HelpUtil.setHelpContext(this, HelpUtil.ht("/Plugins/turnrestrictions#TurnRestrictionToggleDialog")); 170 } 171 172 /** 173 * Switches between the two list view. 174 */ 175 class SwitchListViewHandler implements ItemListener { 176 public void activateListView(AbstractTurnRestrictionsListView view) { 177 if (currentListView != null) { 178 currentListView.removeListSelectionListener(actEdit); 179 currentListView.removeListSelectionListener(actDelete); 180 currentListView.removeListSelectionListener(actSelectSelectedTurnRestrictions); 181 currentListView.removeListSelectionListener(actZoomTo); 182 pnlContent.remove(currentListView); 183 } 184 pnlContent.add(view,BorderLayout.CENTER); 185 currentListView = view; 186 view.addListSelectionListener(actEdit); 187 view.addListSelectionListener(actDelete); 188 view.addListSelectionListener(actSelectSelectedTurnRestrictions); 189 view.addListSelectionListener(actZoomTo); 190 actEdit.updateEnabledState(); 191 actDelete.updateEnabledState(); 192 actSelectSelectedTurnRestrictions.updateEnabledState(); 193 actZoomTo.updateEnabledState(); 194 currentListView.revalidate(); 195 currentListView.repaint(); 196 } 197 198 public void itemStateChanged(ItemEvent e) { 199 switch(e.getStateChange()) { 200 case ItemEvent.SELECTED: 201 activateListView(pnlTurnRestrictionsInSelection); 202 break; 203 204 case ItemEvent.DESELECTED: 205 activateListView(pnlTurnRestrictionsInDataSet); 206 break; 207 } 208 } 209 } 210 211 /** 212 212 * The edit action 213 213 * … … 231 231 } 232 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 233 public void launchEditor(Relation toEdit) { 234 if (toEdit == null) 235 return; 236 OsmDataLayer layer = Main.main.getEditLayer(); 237 TurnRestrictionEditorManager manager = TurnRestrictionEditorManager.getInstance(); 238 TurnRestrictionEditor editor = manager.getEditorForRelation(layer, toEdit); 239 if (editor != null) { 240 editor.setVisible(true); 241 editor.toFront(); 242 } else { 243 editor = new TurnRestrictionEditor( 244 TurnRestrictionsListDialog.this, layer,toEdit); 245 manager.positionOnScreen(editor); 246 manager.register(layer, toEdit,editor); 247 editor.setVisible(true); 248 } 249 } 250 250 251 251 public void actionPerformed(ActionEvent e) { … … 258 258 259 259 public void updateEnabledState() { 260 260 setEnabled(currentListView!= null && currentListView.getModel().getSelectedTurnRestrictions().size() == 1); 261 261 } 262 262 … … 298 298 299 299 public void updateEnabledState() { 300 300 setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty()); 301 301 } 302 302 303 303 public void valueChanged(ListSelectionEvent e) { 304 304 updateEnabledState(); 305 305 } 306 306 } … … 319 319 320 320 public void run() { 321 322 323 324 321 OsmDataLayer layer = Main.main.getEditLayer(); 322 if (layer == null) return; 323 Relation tr = new TurnRestrictionBuilder().buildFromSelection(layer); 324 TurnRestrictionEditor editor = new TurnRestrictionEditor(TurnRestrictionsListDialog.this, layer, tr); 325 325 TurnRestrictionEditorManager.getInstance().positionOnScreen(editor); 326 326 TurnRestrictionEditorManager.getInstance().register(layer, tr, editor); … … 336 336 } 337 337 338 339 340 updateEnabledState(); 341 338 public void editLayerChanged(OsmDataLayer oldLayer, 339 OsmDataLayer newLayer) { 340 updateEnabledState(); 341 } 342 342 } 343 343 … … 367 367 368 368 public void updateEnabledState() { 369 369 setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty()); 370 370 } 371 371 372 372 public void valueChanged(ListSelectionEvent e) { 373 373 updateEnabledState(); 374 374 } 375 375 } … … 401 401 402 402 public void updateEnabledState() { 403 403 setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty()); 404 404 } 405 405 406 406 public void valueChanged(ListSelectionEvent e) { 407 407 updateEnabledState(); 408 408 } 409 409 } … … 448 448 * 449 449 */ 450 class PreferenceChangeHandler implements PreferenceChangedListener { 451 452 453 454 455 456 457 458 459 460 450 class PreferenceChangeHandler implements PreferenceChangedListener { 451 public void refreshIconSet() { 452 pnlTurnRestrictionsInDataSet.initIconSetFromPreferences(Main.pref); 453 pnlTurnRestrictionsInSelection.initIconSetFromPreferences(Main.pref); 454 repaint(); 455 } 456 457 public void preferenceChanged(PreferenceChangeEvent evt) { 458 if (!evt.getKey().equals(PreferenceKeys.ROAD_SIGNS)) return; 459 refreshIconSet(); 460 } 461 461 } 462 462 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsListModel.java
r20489 r23192 73 73 */ 74 74 protected boolean isTurnRestriction(OsmPrimitive primitive) { 75 76 77 78 79 75 if (primitive == null) return false; 76 if (! (primitive instanceof Relation)) return false; 77 String type = primitive.get("type"); 78 if (type == null || ! type.equals("restriction")) return false; 79 return true; 80 80 } 81 81 … … 122 122 continue; 123 123 } 124 125 124 turnrestrictions.add(r); 125 added = true; 126 126 } 127 127 if (added) { … … 143 143 Set<Relation> removedTurnRestrictions = new HashSet<Relation>(); 144 144 for (OsmPrimitive p: removedPrimitives) { 145 145 if (!isTurnRestriction(p)) continue; 146 146 removedTurnRestrictions.add((Relation)p); 147 147 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/preferences/PreferenceEditor.java
r20675 r23192 31 31 */ 32 32 public class PreferenceEditor extends JPanel implements PreferenceSetting{ 33 34 33 34 private PreferencesPanel pnlIconPreferences; 35 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 36 /** 37 * builds the panel with the sponsoring information 38 * 39 * @return 40 */ 41 protected JPanel buildCreditPanel() { 42 JPanel pnl = new JPanel(new GridBagLayout()); 43 pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 44 GridBagConstraints gc = new GridBagConstraints(); 45 gc.anchor = GridBagConstraints.NORTHWEST; 46 gc.fill = GridBagConstraints.HORIZONTAL; 47 gc.insets = new Insets(0, 0,0, 5); 48 gc.weightx = 0.0; 49 JLabel lbl = new JLabel(); 50 pnl.add(lbl, gc); 51 lbl.setIcon(ImageProvider.get("skobbler-logo")); 52 53 gc.gridx = 1; 54 gc.weightx = 1.0; 55 HtmlPanel msg =new HtmlPanel(); 56 msg.setText("<html><body>" 57 + tr("Development of the turn restriction plugin was sponsored " 58 + "by <a href=\"http://www.skobbler.de\">skobbler GmbH</a>.") 59 +"</body></html>"); 60 pnl.add(msg, gc); 61 62 // filler - grab remaining space 63 gc.gridy = 1; 64 gc.gridx = 0; 65 gc.gridwidth = 2; 66 gc.weightx = 1.0; 67 gc.weighty = 1.0; 68 pnl.add(new JPanel(), gc); 69 70 SkobblerUrlLauncher urlLauncher = new SkobblerUrlLauncher(); 71 msg.getEditorPane().addHyperlinkListener(urlLauncher); 72 lbl.addMouseListener(urlLauncher); 73 return pnl; 74 } 75 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 76 protected JPanel buildIconPreferencePanel() { 77 JPanel pnl = new JPanel(new BorderLayout()); 78 79 pnlIconPreferences = new PreferencesPanel(); 80 pnlIconPreferences.initFromPreferences(Main.pref); 81 82 JScrollPane sp = new JScrollPane(pnlIconPreferences); 83 sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 84 sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 85 86 pnl.add(sp, BorderLayout.CENTER); 87 return pnl; 88 } 89 90 protected void build() { 91 setLayout(new BorderLayout()); 92 JTabbedPane tp = new JTabbedPane(); 93 tp.add(buildIconPreferencePanel()); 94 tp.add(buildCreditPanel()); 95 tp.setTitleAt(0, tr("Preferences")); 96 tp.setToolTipTextAt(0,tr("Configure the preferences for the turnrestrictions plugin")); 97 tp.setTitleAt(1, tr("Sponsor")); 98 add(tp, BorderLayout.CENTER); 99 } 100 101 public PreferenceEditor() { 102 build(); 103 } 104 105 public void addGui(PreferenceTabbedPane gui) { 106 String description = tr("An OSM plugin for editing turn restrictions."); 107 JPanel tab = gui.createPreferenceTab("turnrestrictions", tr("Turn Restrictions"), description); 108 108 tab.add(this, GBC.eol().fill(GBC.BOTH)); 109 109 } 110 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 111 public boolean ok() { 112 pnlIconPreferences.saveToPreferences(Main.pref); 113 return false; 114 } 115 116 /** 117 * Launches an external browser with the sponsors home page 118 */ 119 class SkobblerUrlLauncher extends MouseAdapter implements HyperlinkListener { 120 protected void launchBrowser() { 121 OpenBrowser.displayUrl("http://www.skobbler.de"); 122 } 123 124 public void hyperlinkUpdate(HyperlinkEvent e) { 125 if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { 126 launchBrowser(); 127 } 128 } 129 129 130 131 132 133 134 130 @Override 131 public void mouseClicked(MouseEvent e) { 132 launchBrowser(); 133 } 134 } 135 135 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/preferences/PreferenceKeys.java
r20701 r23192 9 9 */ 10 10 public interface PreferenceKeys { 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 11 /** 12 * Indicates which of two sets of road sign icons to use. Supported 13 * values are: 14 * <ul> 15 * <li><tt>set-a</tt> - the set of icons in the directory <tt>/images/types/set-a</tt></li> 16 * <li><tt>set-b</tt> - the set of icons in the directory <tt>/images/types/set-b</tt></li> 17 * </ul> 18 * 19 */ 20 String ROAD_SIGNS = "turnrestrictions.road-signs"; 21 22 /** 23 * Indicates whether the Basic Editor should include a widget for for displaying 24 * and editing the via-objects of a turn restriction. 25 * 26 * Supported values are: 27 * <ul> 28 * <li><tt>true</tt> - display the list of vias in the basic editor </li> 29 * <li><tt>false</tt> - don't display the list of vias in the basic editor </li> 30 * </ul> 31 */ 32 String SHOW_VIAS_IN_BASIC_EDITOR = "turnrestrictions.show-vias-in-basic-editor"; 33 34 /** 35 * The shortcut which triggers creating a new or editing and existing turn 36 * restriction. The value must be parseable by {@see KeyStroke#getKeyStroke(String)}. 37 * If missing, the default value "ctrl shift T" is assumed. 38 */ 39 String EDIT_SHORTCUT= "turnrestrictions.edit-shortcut"; 40 40 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/preferences/PreferencesPanel.java
r20701 r23192 30 30 */ 31 31 public class PreferencesPanel extends VerticallyScrollablePanel { 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 } 225 226 227 228 229 230 231 } 32 private static final Logger logger = Logger.getLogger(PreferencesPanel.class.getName()); 33 private JRadioButton rbSetA; 34 private JRadioButton rbSetB; 35 private ButtonGroup bgIconSet; 36 private JCheckBox cbShowViaListInBasicEditor; 37 private ShortcutPreferencePanel pnlShortcutPreference; 38 39 protected JPanel buildShowViaListInBasicEditorPanel() { 40 JPanel pnl = new JPanel(new GridBagLayout()); 41 GridBagConstraints gc = new GridBagConstraints(); 42 gc.anchor = GridBagConstraints.NORTHWEST; 43 gc.fill = GridBagConstraints.HORIZONTAL; 44 gc.weightx = 1.0; 45 gc.gridx = 0; 46 gc.gridy = 0; 47 48 HtmlPanel msg = new HtmlPanel(); 49 msg.setText("<html><body>" 50 + tr("The Basic Editor can optionally display the list of via-objects " 51 + "of a turn restriction. If enabled, one can edit them " 52 + "in the Basic editor too. If disabled, editing of via-objects is " 53 + "possible in the Advanced Editor only." 54 ) 55 + "</body></html>" 56 ); 57 pnl.add(msg, gc); 58 59 gc.gridy++; 60 pnl.add(cbShowViaListInBasicEditor = new JCheckBox(tr("Display and edit list of via-objects in the Basic Editor")), gc); 61 return pnl; 62 } 63 64 /** 65 * Builds the panel for the icon set "set-a" 66 * 67 * @return 68 */ 69 protected JPanel buildSetAPanel() { 70 JPanel pnl = new JPanel(new GridBagLayout());; 71 GridBagConstraints gc = new GridBagConstraints(); 72 gc.anchor = GridBagConstraints.NORTHWEST; 73 gc.fill = GridBagConstraints.HORIZONTAL; 74 gc.weightx = 1.0; 75 gc.gridx = 0; 76 gc.gridy = 0; 77 78 pnl.add(rbSetA = new JRadioButton(tr("Road signs - Set A")),gc); 79 80 JPanel icons = new JPanel(new FlowLayout(FlowLayout.LEFT)); 81 for (TurnRestrictionType type: TurnRestrictionType.values()){ 82 JLabel lbl = new JLabel(); 83 icons.add(lbl); 84 lbl.setIcon(ImageProvider.get("types/set-a",type.getTagValue())); 85 } 86 87 gc.gridy = 1; 88 gc.insets = new Insets(0,20,0,0); 89 pnl.add(icons, gc); 90 return pnl; 91 } 92 93 /** 94 * Builds the panel for the icon set "set-b" 95 * 96 * @return 97 */ 98 protected JPanel buildSetBPanel() { 99 JPanel pnl = new JPanel(new GridBagLayout());; 100 GridBagConstraints gc = new GridBagConstraints(); 101 gc.anchor = GridBagConstraints.NORTHWEST; 102 gc.fill = GridBagConstraints.HORIZONTAL; 103 gc.weightx = 1.0; 104 gc.gridx = 0; 105 gc.gridy = 0; 106 107 pnl.add(rbSetB = new JRadioButton(tr("Road signs - Set B")),gc); 108 109 JPanel icons = new JPanel(new FlowLayout(FlowLayout.LEFT)); 110 for (TurnRestrictionType type: TurnRestrictionType.values()){ 111 JLabel lbl = new JLabel(); 112 icons.add(lbl); 113 lbl.setIcon(ImageProvider.get("types/set-b",type.getTagValue())); 114 } 115 116 gc.gridy = 1; 117 gc.insets = new Insets(0,20,0,0); 118 pnl.add(icons, gc); 119 return pnl; 120 } 121 122 /** 123 * Builds the message panel at the top 124 * 125 * @return 126 */ 127 protected JPanel buildMessagePanel() { 128 HtmlPanel pnl = new HtmlPanel(); 129 pnl.setText( 130 "<html><body>" 131 + tr("Please select the set of road sign icons to be used in the plugin.") 132 + "</body></html>" 133 ); 134 return pnl; 135 } 136 137 /** 138 * Builds the UI 139 * 140 * @return 141 */ 142 protected void build() { 143 setLayout(new GridBagLayout()); 144 GridBagConstraints gc = new GridBagConstraints(); 145 gc.anchor = GridBagConstraints.NORTHWEST; 146 gc.fill = GridBagConstraints.HORIZONTAL; 147 gc.weightx = 1.0; 148 gc.gridx = 0; 149 gc.gridy = 0; 150 151 add(buildMessagePanel(), gc); 152 gc.gridy++; 153 add(buildSetAPanel(), gc); 154 gc.gridy++; 155 add(buildSetBPanel(), gc); 156 gc.gridy++; 157 add(new JSeparator(), gc); 158 gc.gridy++; 159 add(buildShowViaListInBasicEditorPanel(), gc); 160 gc.gridy++; 161 add(new JSeparator(), gc); 162 gc.gridy++; 163 add(pnlShortcutPreference = new ShortcutPreferencePanel(), gc); 164 165 // filler - just grab remaining space 166 gc.gridy++; 167 gc.fill = GridBagConstraints.BOTH; 168 gc.weighty = 1.0; 169 add(new JPanel(), gc); 170 171 bgIconSet = new ButtonGroup(); 172 bgIconSet.add(rbSetA); 173 bgIconSet.add(rbSetB); 174 175 setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 176 } 177 178 /** 179 * Initializes the UI from the current settings in the JOSM preferences 180 * {@code prefs} 181 * 182 * @param prefs the preferences 183 */ 184 public void initFromPreferences(Preferences prefs){ 185 String set = prefs.get(PreferenceKeys.ROAD_SIGNS, "set-a"); 186 set = set.trim().toLowerCase(); 187 if (! set.equals("set-a") && ! set.equals("set-b")) { 188 System.out.println(tr("Warning: the preference with key ''{0}'' has an unsupported value ''{1}''. Assuming the default value ''set-a''.", PreferenceKeys.ROAD_SIGNS, set)); 189 set = "set-a"; 190 } 191 if (set.equals("set-a")){ 192 rbSetA.setSelected(true); 193 } else { 194 rbSetB.setSelected(true); 195 } 196 197 boolean b = prefs.getBoolean(PreferenceKeys.SHOW_VIAS_IN_BASIC_EDITOR, false); 198 cbShowViaListInBasicEditor.setSelected(b); 199 200 pnlShortcutPreference.initFromPreferences(prefs); 201 } 202 203 /** 204 * Saves the current settings to the JOSM preferences {@code prefs}. 205 * 206 * @param prefs the preferences 207 */ 208 public void saveToPreferences(Preferences prefs){ 209 String set = null; 210 if (rbSetA.isSelected()){ 211 set = "set-a"; 212 } else { 213 set = "set-b"; 214 } 215 String oldSet = prefs.get(PreferenceKeys.ROAD_SIGNS, "set-a"); 216 if (!set.equals(oldSet)){ 217 prefs.put(PreferenceKeys.ROAD_SIGNS, set); 218 } 219 220 boolean newValue = cbShowViaListInBasicEditor.isSelected(); 221 boolean oldValue = prefs.getBoolean(PreferenceKeys.SHOW_VIAS_IN_BASIC_EDITOR, false); 222 if (newValue != oldValue){ 223 prefs.put(PreferenceKeys.SHOW_VIAS_IN_BASIC_EDITOR, newValue); 224 } 225 226 pnlShortcutPreference.saveToPreferences(prefs); 227 } 228 229 public PreferencesPanel() { 230 build(); 231 } 232 232 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/preferences/ShortcutPreferencePanel.java
r20701 r23192 36 36 */ 37 37 public class ShortcutPreferencePanel extends JPanel { 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 } 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 } 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 } 223 } 224 38 39 private JCheckBox cbCtrl; 40 private JCheckBox cbAlt; 41 private JCheckBox cbShift; 42 private JCheckBox cbMeta; 43 private JComboBox cmKeyCodes; 44 45 protected JPanel buildMessagePanel() { 46 HtmlPanel pnl = new HtmlPanel(); 47 pnl.setText("<html><body>" 48 + tr("Please configure the <strong>keyboard shortcut</strong> which triggers " 49 + "creating/editing a turn restriction from the current JOSM selection.") 50 + "</body></html>" 51 ); 52 return pnl; 53 } 54 55 protected JPanel buildShortCutConfigPanel() { 56 JPanel pnl = new JPanel(new GridBagLayout()); 57 GridBagConstraints gc = new GridBagConstraints(); 58 gc.anchor = GridBagConstraints.NORTHWEST; 59 gc.fill = GridBagConstraints.HORIZONTAL; 60 gc.weightx = 0.0; 61 gc.gridx = 0; 62 gc.gridy = 0; 63 64 pnl.add(new JLabel(trc("keyboard-key", "Key:")), gc); 65 gc.gridx++; 66 gc.gridwidth=4; 67 gc.weightx = 1.0; 68 pnl.add(cmKeyCodes = new JComboBox(new VKeyComboBoxModel()), gc); 69 cmKeyCodes.setRenderer(new VKeyCellRenderer()); 70 71 gc.gridx = 0; 72 gc.gridy = 1; 73 gc.gridwidth = 1; 74 gc.weightx = 0.0; 75 pnl.add(new JLabel(trc("keyboard-modifiers", "Modifiers:")), gc); 76 77 gc.gridx++; 78 pnl.add(cbShift = new JCheckBox(trc("keyboard-modifiers", "Shift")), gc); 79 gc.gridx++; 80 pnl.add(cbCtrl = new JCheckBox(trc("keyboard-modifiers", "Ctrl")), gc); 81 gc.gridx++; 82 pnl.add(cbAlt = new JCheckBox(trc("keyboard-modifiers", "Alt")), gc); 83 gc.gridx++; 84 gc.weightx = 1.0; 85 pnl.add(cbMeta = new JCheckBox(trc("keyboard-modifiers", "Meta")), gc); 86 87 return pnl; 88 } 89 90 protected void build() { 91 setLayout(new GridBagLayout()); 92 GridBagConstraints gc = new GridBagConstraints(); 93 gc.anchor = GridBagConstraints.NORTHWEST; 94 gc.fill = GridBagConstraints.HORIZONTAL; 95 gc.weightx = 1.0; 96 gc.gridx = 0; 97 gc.gridy = 0; 98 add(buildMessagePanel(), gc); 99 gc.gridy++; 100 add(buildShortCutConfigPanel(), gc); 101 } 102 103 public ShortcutPreferencePanel() { 104 build(); 105 } 106 107 public void initFromPreferences(Preferences pref){ 108 String value = pref.get(PreferenceKeys.EDIT_SHORTCUT, "shift ctrl T"); 109 KeyStroke key = KeyStroke.getKeyStroke(value); 110 if (key == null){ 111 System.out.println(tr("Warning: illegal value ''{0}'' for preference key ''{1}''. Falling back to default value ''shift ctrl T''.", value, PreferenceKeys.EDIT_SHORTCUT)); 112 key = KeyStroke.getKeyStroke("shift ctrl T"); 113 } 114 cmKeyCodes.getModel().setSelectedItem(key.getKeyCode()); 115 cbAlt.setSelected((key.getModifiers() & KeyEvent.ALT_DOWN_MASK) != 0); 116 cbCtrl.setSelected((key.getModifiers() & KeyEvent.CTRL_DOWN_MASK) != 0); 117 cbShift.setSelected((key.getModifiers() & KeyEvent.SHIFT_DOWN_MASK) != 0); 118 cbMeta.setSelected((key.getModifiers() & KeyEvent.META_DOWN_MASK) != 0); 119 } 120 121 public void saveToPreferences(Preferences pref){ 122 Integer code = (Integer)cmKeyCodes.getModel().getSelectedItem(); 123 if (code == null) { 124 code = KeyEvent.VK_T; 125 } 126 int modifiers = 0; 127 if (cbAlt.isSelected()) modifiers |= KeyEvent.ALT_DOWN_MASK; 128 if (cbCtrl.isSelected()) modifiers |= KeyEvent.CTRL_DOWN_MASK; 129 if (cbShift.isSelected()) modifiers |= KeyEvent.SHIFT_DOWN_MASK; 130 if (cbMeta.isSelected()) modifiers |= KeyEvent.META_DOWN_MASK; 131 KeyStroke ks = KeyStroke.getKeyStroke(code, modifiers); 132 133 pref.put(PreferenceKeys.EDIT_SHORTCUT, ks.toString()); 134 CreateOrEditTurnRestrictionAction.install(ks); 135 } 136 137 static private class VKeyComboBoxModel extends AbstractListModel implements ComboBoxModel { 138 private final ArrayList<Integer> keys = new ArrayList<Integer>(); 139 private Integer selected = null; 140 141 public VKeyComboBoxModel() { 142 populate(); 143 } 144 145 public void populate() { 146 for (Field f :KeyEvent.class.getFields()) { 147 if (! Modifier.isStatic(f.getModifiers())) continue; 148 if (! f.getName().startsWith("VK_")) continue; 149 try { 150 keys.add((Integer)f.get(null)); 151 } catch(IllegalAccessException e){ 152 // ignore 153 } 154 } 155 156 Collections.sort(keys, new KeyCodeComparator()); 157 } 158 159 public Object getSelectedItem() { 160 return selected; 161 } 162 163 public void setSelectedItem(Object anItem) { 164 this.selected = (Integer)anItem; 165 } 166 167 public Object getElementAt(int index) { 168 return keys.get(index); 169 } 170 171 public int getSize() { 172 return keys.size(); 173 } 174 } 175 176 static private class VKeyCellRenderer extends JLabel implements ListCellRenderer { 177 public Component getListCellRendererComponent(JList list, Object value, 178 int index, boolean isSelected, boolean cellHasFocus) { 179 if (isSelected) { 180 setBackground(UIManager.getColor("ComboBox.selectionBackground")); 181 setForeground(UIManager.getColor("ComboBox.selectionForeground")); 182 } else { 183 setBackground(UIManager.getColor("ComboBox.background")); 184 setForeground(UIManager.getColor("ComboBox.foreground")); 185 } 186 setText(KeyEvent.getKeyText((Integer)value)); 187 return this; 188 } 189 } 190 191 static private class KeyCodeComparator implements Comparator<Integer> { 192 private final static Map<Integer, String> keyNames = new HashMap<Integer, String>(); 193 194 protected String keyName(Integer code){ 195 String name = keyNames.get(code); 196 if (name == null){ 197 name = KeyEvent.getKeyText(code); 198 keyNames.put(code, name); 199 } 200 return name; 201 } 202 /** 203 * Make sure single letter keys (A-Z, 0-9) are at the top of the list. 204 * Make sure function key F1-F19 are sorted numerically, not lexicografically. 205 * 206 */ 207 public int compare(Integer kc1, Integer kc2) { 208 String n1 = keyName(kc1); 209 String n2 = keyName(kc2); 210 if (n1.length() == 1 && n2.length()==1){ 211 return n1.compareTo(n2); 212 } else if (n1.length() == 1){ 213 return -1; 214 } else if (n2.length() == 1){ 215 return 1; 216 } else if (n1.matches("F\\d+") && n2.matches("F\\d+")){ 217 int f1 = Integer.parseInt(n1.substring(1)); 218 int f2 = Integer.parseInt(n2.substring(1)); 219 return new Integer(f1).compareTo(f2); 220 } else { 221 return n1.compareTo(n2); 222 } 223 } 224 } 225 225 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IdenticalTurnRestrictionLegsError.java
r20701 r23192 15 15 */ 16 16 public class IdenticalTurnRestrictionLegsError extends Issue{ 17 18 19 20 21 22 23 24 25 17 private OsmPrimitive leg; 18 19 public IdenticalTurnRestrictionLegsError(IssuesModel parent, OsmPrimitive leg) { 20 super(parent, Severity.ERROR); 21 actions.add(new DeleteFromAction()); 22 actions.add(new DeleteToAction()); 23 actions.add(new FixInEditorAction()); 24 this.leg = leg; 25 } 26 26 27 28 29 30 31 32 ); 33 34 35 36 37 38 39 40 41 42 } 43 44 45 46 47 48 49 50 51 52 } 53 54 55 56 57 58 59 60 61 62 } 63 27 @Override 28 public String getText() { 29 return tr("This turn restriction uses the OSM way <span class=\"object-name\">{0}</span> with role <tt>from</tt> <strong>and</strong> with role <tt>to</tt>. " 30 + "In a turn restriction, the way with role <tt>from</tt> should be different from the way with role <tt>to</tt>, though.", 31 leg.getDisplayName(DefaultNameFormatter.getInstance()) 32 ); 33 } 34 35 class DeleteFromAction extends AbstractAction { 36 public DeleteFromAction() { 37 putValue(NAME, tr("Delete ''from''")); 38 putValue(SHORT_DESCRIPTION, tr("Removes the member with role ''from''")); 39 } 40 public void actionPerformed(ActionEvent e) { 41 getIssuesModel().getEditorModel().getRelationMemberEditorModel().setFromPrimitive(null); 42 } 43 } 44 45 class DeleteToAction extends AbstractAction { 46 public DeleteToAction() { 47 putValue(NAME, tr("Delete ''to''")); 48 putValue(SHORT_DESCRIPTION, tr("Removes the member with role ''to''")); 49 } 50 public void actionPerformed(ActionEvent e) { 51 getIssuesModel().getEditorModel().getRelationMemberEditorModel().setToPrimitive(null); 52 } 53 } 54 55 class FixInEditorAction extends AbstractAction { 56 public FixInEditorAction() { 57 putValue(NAME, tr("Fix in editor")); 58 putValue(SHORT_DESCRIPTION, tr("Go to Basic Editor and manually choose members with roles ''from'' and ''to''")); 59 } 60 public void actionPerformed(ActionEvent e) { 61 getIssuesModel().getNavigationControler().gotoBasicEditor(); 62 } 63 } 64 64 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IllegalRestrictionTypeError.java
r20622 r23192 15 15 */ 16 16 public class IllegalRestrictionTypeError extends Issue{ 17 18 19 20 21 22 23 17 private String value; 18 19 public IllegalRestrictionTypeError(IssuesModel parent, String value) { 20 super(parent, Severity.ERROR); 21 actions.add(new FixInEditorAction()); 22 this.value = value; 23 } 24 24 25 26 27 28 29 30 ); 31 32 33 34 35 36 37 38 39 40 } 41 25 @Override 26 public String getText() { 27 return tr("This turn restriction uses a non-standard restriction type <tt>{0}</tt> for the tag key <tt>restriction</tt>. " 28 + "It is recommended to use standard values only. Please select one in the Basic editor.", 29 value 30 ); 31 } 32 33 class FixInEditorAction extends AbstractAction { 34 public FixInEditorAction() { 35 putValue(NAME, tr("Fix in editor")); 36 putValue(SHORT_DESCRIPTION, tr("Go to Basic Editor and manually choose a turn restriction type")); 37 } 38 public void actionPerformed(ActionEvent e) { 39 getIssuesModel().getNavigationControler().gotoBasicEditor(NavigationControler.BasicEditorFokusTargets.RESTRICION_TYPE); 40 } 41 } 42 42 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IntersectionMissingAsViaError.java
r20701 r23192 20 20 */ 21 21 public class IntersectionMissingAsViaError extends Issue{ 22 23 24 25 26 27 28 29 30 31 32 33 22 private Way from; 23 private Way to; 24 private Node interesect; 25 26 public IntersectionMissingAsViaError(IssuesModel parent, Way from, Way to, Node intersect) { 27 super(parent, Severity.ERROR); 28 this.from = from; 29 this.to = to; 30 this.interesect = intersect; 31 actions.add(new SetVia()); 32 actions.add(new FixInEditorAction()); 33 } 34 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 } 55 56 57 58 59 60 61 62 63 64 } 65 35 @Override 36 public String getText() { 37 String msg = tr("The <strong>from</strong>-way <span class=\"object-name\">{0}</span> and the <strong>to</strong>-way <span class=\"object-name\">{1}</span> " 38 + "interesect at node <span class=\"object-name\">{2}</span> but <span class=\"object-name\">{2}</span> isn''t a <strong>via</strong>-object.<br> " 39 + "It is recommended to set <span class=\"object-name\">{2}</span> as unique <strong>via</strong>-object.", 40 this.from.getDisplayName(DefaultNameFormatter.getInstance()), 41 this.to.getDisplayName(DefaultNameFormatter.getInstance()), 42 this.interesect.getDisplayName(DefaultNameFormatter.getInstance()) 43 ); 44 return msg; 45 } 46 47 class SetVia extends AbstractAction { 48 public SetVia() { 49 putValue(NAME, tr("Set via-Object")); 50 putValue(SHORT_DESCRIPTION, tr("Replaces the currently configured via-objects with the node at the intersection")); 51 } 52 public void actionPerformed(ActionEvent e) { 53 getIssuesModel().getEditorModel().setVias(Collections.<OsmPrimitive>singletonList(interesect)); 54 } 55 } 56 57 class FixInEditorAction extends AbstractAction { 58 public FixInEditorAction() { 59 putValue(NAME, tr("Fix in editor")); 60 putValue(SHORT_DESCRIPTION, tr("Go to Basic Editor and manually fix the list of via-objects")); 61 } 62 public void actionPerformed(ActionEvent e) { 63 getIssuesModel().getNavigationControler().gotoBasicEditor(BasicEditorFokusTargets.VIA); 64 } 65 } 66 66 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/Issue.java
r20622 r23192 18 18 */ 19 19 abstract public class Issue { 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 20 /** the parent model for this issue */ 21 protected IssuesModel parent; 22 protected Severity severity; 23 protected final ArrayList<Action> actions = new ArrayList<Action>(); 24 25 /** 26 * Creates a new issue associated with a parent model. Severity is 27 * initialized to {@see Severity#WARNING}. 28 * 29 * @param parent the parent model. Must not be null. 30 * @throws IllegalArgumentException thrown if parent is null 31 */ 32 public Issue(IssuesModel parent) throws IllegalArgumentException{ 33 CheckParameterUtil.ensureParameterNotNull(parent, "parent"); 34 this.parent = parent; 35 this.severity = Severity.WARNING; 36 } 37 38 /** 39 * Creates a new issue of severity {@code severity} associated with 40 * the parent model {@code parent}. 41 * 42 * @param parent the parent model. Must not be null. 43 * @param severity the severity. Must not be null. 44 * @throws IllegalArgumentException thrown if parent is null 45 * @throws IllegalArgumentException thrown if severity is null 46 */ 47 public Issue(IssuesModel parent, Severity severity){ 48 CheckParameterUtil.ensureParameterNotNull(parent, "parent"); 49 CheckParameterUtil.ensureParameterNotNull(severity, "severity"); 50 this.parent = parent; 51 this.severity = severity; 52 } 53 53 54 55 56 57 58 59 60 61 54 /** 55 * Replies the parent model this issue is associated with 56 * 57 * @return the parent model 58 */ 59 public IssuesModel getIssuesModel() { 60 return parent; 61 } 62 62 63 64 65 66 67 68 69 70 63 /** 64 * Replies the severity of this issue 65 * 66 * @return the severity 67 */ 68 public Severity getSeverity() { 69 return severity; 70 } 71 71 72 73 74 75 76 77 78 79 80 81 72 /** 73 * Sets the severity of this issue. 74 * 75 * @param severity the severity. Must not be null. 76 * @throws IllegalArgumentException thrown if severity is null 77 */ 78 public void setSeverity(Severity severity) throws IllegalArgumentException { 79 CheckParameterUtil.ensureParameterNotNull(severity, "severity"); 80 this.severity = severity; 81 } 82 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 83 /** 84 * Replies the HTML formatted description of the issue. The text should neither include 85 * the <html>, nor the <body> tag. 86 * 87 * @return the HTML formatted description of the issue. 88 */ 89 public abstract String getText(); 90 91 /** 92 * Replies a list of actions which can be applied to this issue in order to fix 93 * it. The default implementation replies an empty list. 94 * 95 * @return a list of action 96 */ 97 public List<Action> getActions() { 98 return Collections.unmodifiableList(actions); 99 } 100 100 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IssueView.java
r20645 r23192 26 26 public class IssueView extends JPanel{ 27 27 28 29 30 31 32 33 34 28 private HtmlPanel pnlMessage; 29 private JPanel pnlActions; 30 private Issue issue; 31 private JLabel lblIcon; 32 private StyleSheet styleSheet; 33 34 /** 35 35 * Builds the style sheet used in the internal help browser 36 36 * … … 43 43 ss.addRule(".object-name {background-color:rgb(240,240,240); color: blue;}"); 44 44 } 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 45 46 protected void build() { 47 setLayout(new GridBagLayout()); 48 setBackground(Color.WHITE); 49 setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1)); 50 51 // add the icon for the severity 52 GridBagConstraints gc = new GridBagConstraints(); 53 gc.anchor = GridBagConstraints.NORTHWEST; 54 gc.fill = GridBagConstraints.VERTICAL; 55 gc.gridheight = 2; 56 gc.weightx = 0.0; 57 gc.weighty = 1.0; 58 gc.gridx = 0; 59 gc.gridy = 0; 60 gc.insets = new Insets(2,2,2,2); 61 add(lblIcon = new JLabel(), gc); 62 lblIcon.setVerticalAlignment(SwingConstants.TOP); 63 lblIcon.setHorizontalAlignment(SwingConstants.CENTER); 64 lblIcon.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 65 65 66 67 68 69 70 71 72 73 74 75 76 77 78 66 // add the html panel with the issue description 67 gc.insets = new Insets(0,0,0,0); 68 gc.anchor = GridBagConstraints.NORTHWEST; 69 gc.fill = GridBagConstraints.BOTH; 70 gc.gridx = 1; 71 gc.gridy = 0; 72 gc.gridheight = 1; 73 gc.weightx = 1.0; 74 gc.weighty = 1.0; 75 add(pnlMessage = new HtmlPanel(), gc); 76 initStyleSheet(pnlMessage); 77 pnlMessage.setBackground(Color.white); 78 pnlMessage.setText("<html><body>" + issue.getText() + "</html></bod>"); 79 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 } 96 97 98 99 100 101 102 103 104 105 } 106 107 108 109 110 111 112 113 114 115 116 117 118 80 81 // if there are any actions available to resolve the issue, add a panel with action buttons 82 if (!issue.getActions().isEmpty()) { 83 pnlActions = new JPanel(new FlowLayout(FlowLayout.LEFT)); 84 pnlActions.setBackground(Color.WHITE); 85 for (Action action: issue.getActions()){ 86 JButton btn = new JButton(action); 87 pnlActions.add(btn); 88 } 89 90 gc.gridx = 1; 91 gc.gridy = 1; 92 gc.fill = GridBagConstraints.HORIZONTAL; 93 gc.weighty = 0.0; 94 add(pnlActions,gc); 95 } 96 97 // set the severity icon 98 switch(issue.getSeverity()){ 99 case WARNING: 100 lblIcon.setIcon(ImageProvider.get("warning-small")); 101 break; 102 case ERROR: 103 lblIcon.setIcon(ImageProvider.get("error")); 104 break; 105 } 106 } 107 108 /** 109 * Creates an issue view for an issue. 110 * 111 * @param issue the issue. Must not be null. 112 * @throws IllegalArgumentException thrown if issue is null. 113 */ 114 public IssueView(Issue issue) throws IllegalArgumentException{ 115 CheckParameterUtil.ensureParameterNotNull(issue, "issue"); 116 this.issue = issue; 117 build(); 118 } 119 119 120 121 122 123 120 @Override 121 public Dimension getMinimumSize() { 122 return super.getPreferredSize(); 123 } 124 124 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IssuesModel.java
r20724 r23192 31 31 */ 32 32 public class IssuesModel extends Observable implements Observer{ 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 } 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 } 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 33 private final ArrayList<Issue> issues = new ArrayList<Issue>(); 34 private TurnRestrictionEditorModel editorModel; 35 36 /** 37 * Creates the model 38 * 39 * {@code controler} is used in resolution actions for issues in 40 * this model to direct the user to a specific input field in one 41 * of the editor tabs in order to fix an issue. 42 * 43 * @param editorModel the editor model. Must not be null. 44 * @throws IllegalArgumentException thrown if controler is null 45 */ 46 public IssuesModel(TurnRestrictionEditorModel editorModel) throws IllegalArgumentException{ 47 CheckParameterUtil.ensureParameterNotNull(editorModel, "editorModel"); 48 this.editorModel = editorModel; 49 this.editorModel.addObserver(this); 50 } 51 52 /** 53 * Populates the model with a list of issues. Just clears the model 54 * if {@code issues} is null or empty. 55 * 56 * @param issues the list of issues. 57 */ 58 public void populate(List<Issue> issues){ 59 this.issues.clear(); 60 if (issues != null){ 61 this.issues.addAll(issues); 62 } 63 setChanged(); 64 notifyObservers(); 65 } 66 67 /** 68 * Replies the (unmodifiable) list of issues in this model. 69 * 70 * @return the (unmodifiable) list of issues in this model. 71 */ 72 public List<Issue> getIssues() { 73 return Collections.unmodifiableList(issues); 74 } 75 76 /** 77 * Replies the turn restriction editor model 78 * 79 * @return 80 */ 81 public TurnRestrictionEditorModel getEditorModel() { 82 return editorModel; 83 } 84 85 /** 86 * Populates this model with issues derived from the state of the 87 * turn restriction editor model. If {@code editorModel} is null, the 88 * list of issues is cleared. 89 * 90 * @param editorModel the editor model. 91 */ 92 public void populate() { 93 issues.clear(); 94 if (editorModel != null) { 95 checkTags(editorModel); 96 checkFromLeg(editorModel); 97 checkToLeg(editorModel); 98 checkFromAndToEquals(editorModel); 99 checkVias(editorModel); 100 } 101 setChanged(); 102 notifyObservers(); 103 } 104 105 /** 106 * Checks whether there are required tags missing. 107 * 108 * @param editorModel 109 */ 110 protected void checkTags(TurnRestrictionEditorModel editorModel) { 111 TagEditorModel tagEditorModel = editorModel.getTagEditorModel(); 112 TagModel tag = tagEditorModel.get("type"); 113 114 // missing marker tag for a turn restriction 115 if (tag == null || ! tag.getValue().trim().equals("restriction")) { 116 issues.add(new RequiredTagMissingError(this, "type", "restriction")); 117 } 118 119 // missing or illegal restriction type ? 120 tag = tagEditorModel.get("restriction"); 121 if (tag == null) { 122 issues.add(new MissingRestrictionTypeError(this)); 123 } else if (!TurnRestrictionType.isStandardTagValue(tag.getValue())) { 124 issues.add(new IllegalRestrictionTypeError(this, tag.getValue())); 125 } 126 127 // non-standard value for the 'except' tag? 128 ExceptValueModel except = getEditorModel().getExcept(); 129 if (!except.isStandard()) { 130 issues.add(new NonStandardExceptWarning(this, except)); 131 } 132 } 133 134 /** 135 * Checks various data integrity restriction for the relation member with 136 * role 'from'. 137 * 138 */ 139 protected void checkFromLeg(TurnRestrictionEditorModel editorModel) { 140 Set<OsmPrimitive> froms = editorModel.getTurnRestrictionLeg(TurnRestrictionLegRole.FROM); 141 if (froms.isEmpty()){ 142 issues.add(new MissingTurnRestrictionLegError(this, TurnRestrictionLegRole.FROM)); 143 return; 144 } else if (froms.size() > 1){ 145 issues.add(new MultipleTurnRestrictionLegError(this, TurnRestrictionLegRole.FROM, froms.size())); 146 return; 147 } 148 OsmPrimitive p = froms.iterator().next(); 149 if (! (p instanceof Way)) { 150 issues.add(new WrongTurnRestrictionLegTypeError(this, TurnRestrictionLegRole.FROM, p)); 151 } 152 } 153 154 /** 155 * Checks various data integrity restriction for the relation member with 156 * role 'to'. 157 * 158 */ 159 protected void checkToLeg(TurnRestrictionEditorModel editorModel) { 160 Set<OsmPrimitive> toLegs = editorModel.getTurnRestrictionLeg(TurnRestrictionLegRole.TO); 161 if (toLegs.isEmpty()){ 162 issues.add(new MissingTurnRestrictionLegError(this, TurnRestrictionLegRole.TO)); 163 return; 164 } else if (toLegs.size() > 1){ 165 issues.add(new MultipleTurnRestrictionLegError(this, TurnRestrictionLegRole.TO, toLegs.size())); 166 return; 167 } 168 OsmPrimitive p = toLegs.iterator().next(); 169 if (! (p instanceof Way)) { 170 issues.add(new WrongTurnRestrictionLegTypeError(this, TurnRestrictionLegRole.TO, p)); 171 } 172 } 173 174 /** 175 * Creates an issue if this turn restriction has identical 'from' and to'. 176 * 177 * @param editorModel 178 */ 179 protected void checkFromAndToEquals(TurnRestrictionEditorModel editorModel){ 180 Set<OsmPrimitive> toLegs = editorModel.getTurnRestrictionLeg(TurnRestrictionLegRole.TO); 181 Set<OsmPrimitive> fromLegs = editorModel.getTurnRestrictionLeg(TurnRestrictionLegRole.FROM); 182 if (toLegs.size() != 1 || fromLegs.size() != 1) return; 183 184 OsmPrimitive from = fromLegs.iterator().next(); 185 OsmPrimitive to = toLegs.iterator().next(); 186 187 if (! (from instanceof Way)) return; 188 if (! (to instanceof Way)) return; 189 if (from.equals(to) && ! "no_u_turn".equals(editorModel.getRestrictionTagValue())){ 190 // identical from and to allowed for "no_u_turn" only 191 // 192 issues.add(new IdenticalTurnRestrictionLegsError(this, from)); 193 } 194 } 195 196 protected Node getNodeAtIntersection(Way from, Way to){ 197 Set<Node> fromNodes = new HashSet<Node>(from.getNodes()); 198 fromNodes.retainAll(to.getNodes()); 199 if (fromNodes.size() == 1){ 200 return fromNodes.iterator().next(); 201 } else { 202 return null; 203 } 204 } 205 206 /** 207 * Checks the 'via' members in the turn restriction 208 * 209 * @param editorModel the editor model 210 */ 211 protected void checkVias(TurnRestrictionEditorModel editorModel){ 212 Set<OsmPrimitive> toLegs = editorModel.getTurnRestrictionLeg(TurnRestrictionLegRole.TO); 213 Set<OsmPrimitive> fromLegs = editorModel.getTurnRestrictionLeg(TurnRestrictionLegRole.FROM); 214 // we only check vias if 'to' and 'from' are already OK 215 if (toLegs.size() != 1 || fromLegs.size() != 1) return; 216 if (! (toLegs.iterator().next() instanceof Way)) return; 217 if (! (fromLegs.iterator().next() instanceof Way)) return; 218 219 Way from = (Way)fromLegs.iterator().next(); 220 Way to = (Way)toLegs.iterator().next(); 221 Node intersect = getNodeAtIntersection(from, to); 222 if (intersect != null){ 223 if (!editorModel.getVias().contains(intersect)) { 224 issues.add(new IntersectionMissingAsViaError(this, from, to, intersect)); 225 } 226 } 227 228 // 'from' intersects with 'to' - should be split 229 if (intersect != null && from.getNode(0) != intersect && from.getNode(from.getNodesCount()-1) != intersect){ 230 issues.add(new TurnRestrictionLegSplitRequiredError(this, TurnRestrictionLegRole.FROM, from, to, intersect)); 231 } 232 // 'to' intersects with 'from' - should be split 233 if (intersect != null && to.getNode(0) != intersect && to.getNode(to.getNodesCount()-1) != intersect){ 234 issues.add(new TurnRestrictionLegSplitRequiredError(this, TurnRestrictionLegRole.TO, from, to, intersect)); 235 } 236 } 237 238 public NavigationControler getNavigationControler() { 239 return editorModel.getNavigationControler(); 240 } 241 242 public int getNumWarnings() { 243 int ret = 0; 244 for (Issue issue: issues){ 245 if (issue.getSeverity().equals(Severity.WARNING)) ret++; 246 } 247 return ret; 248 } 249 250 public int getNumErrors() { 251 int ret = 0; 252 for (Issue issue: issues){ 253 if (issue.getSeverity().equals(Severity.ERROR)) ret++; 254 } 255 return ret; 256 } 257 258 /* ------------------------------------------------------------------------------------- */ 259 /* interface Observer */ 260 /* ------------------------------------------------------------------------------------- */ 261 public void update(Observable o, Object arg) { 262 populate(); 263 } 264 264 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IssuesView.java
r20735 r23192 17 17 */ 18 18 public class IssuesView extends VerticallyScrollablePanel implements Observer{ 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 19 static private final Logger logger = Logger.getLogger(IssuesView.class.getName()); 20 21 /** the issues model */ 22 private IssuesModel model; 23 24 protected void build(){ 25 setLayout(new GridBagLayout()); 26 } 27 28 /** 29 * Creates the view 30 * 31 * @param model the model. Must not be null. 32 * @exception IllegalArgumentException thrown if model is null 33 */ 34 public IssuesView(IssuesModel model) throws IllegalArgumentException{ 35 CheckParameterUtil.ensureParameterNotNull(model, "model"); 36 this.model = model; 37 model.addObserver(this); 38 build(); 39 HelpUtil.setHelpContext(this, HelpUtil.ht("/Plugins/turnrestrictions#ErrorsAndWarnings")); 40 } 41 42 /** 43 * Refreshes the view with the current state in the model 44 */ 45 public void refresh() { 46 removeAll(); 47 if (! model.getIssues().isEmpty()){ 48 GridBagConstraints gc = new GridBagConstraints(); 49 gc.anchor = GridBagConstraints.NORTHWEST; 50 gc.fill = GridBagConstraints.HORIZONTAL; 51 gc.weightx = 1.0; 52 gc.weighty = 0.0; 53 gc.gridx = 0; 54 gc.gridy = 0; 55 for (Issue issue: model.getIssues()){ 56 add(new IssueView(issue), gc); 57 gc.gridy++; 58 } 59 // filler - grabs remaining space 60 gc.weighty = 1.0; 61 add(new JPanel(), gc); 62 } 63 invalidate(); 64 } 65 65 66 67 68 69 70 71 66 /* ------------------------------------------------------------------------------- */ 67 /* interface Observer */ 68 /* ------------------------------------------------------------------------------- */ 69 public void update(Observable o, Object arg) { 70 refresh(); 71 } 72 72 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/MissingRestrictionTypeError.java
r20586 r23192 15 15 */ 16 16 public class MissingRestrictionTypeError extends Issue{ 17 18 19 20 21 17 18 public MissingRestrictionTypeError(IssuesModel parent) { 19 super(parent, Severity.ERROR); 20 actions.add(new FixInEditorAction()); 21 } 22 22 23 24 25 26 27 28 29 30 31 32 33 34 35 } 36 23 @Override 24 public String getText() { 25 return tr("A turn restriction must declare the type of restriction. Please select a type in the Basic Editor."); 26 } 27 28 class FixInEditorAction extends AbstractAction { 29 public FixInEditorAction() { 30 putValue(NAME, tr("Fix in editor")); 31 putValue(SHORT_DESCRIPTION, tr("Go to Basic Editor and manually choose a turn restriction type")); 32 } 33 public void actionPerformed(ActionEvent e) { 34 getIssuesModel().getNavigationControler().gotoBasicEditor(NavigationControler.BasicEditorFokusTargets.RESTRICION_TYPE); 35 } 36 } 37 37 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/MissingTurnRestrictionLegError.java
r20633 r23192 15 15 */ 16 16 public class MissingTurnRestrictionLegError extends Issue { 17 17 private TurnRestrictionLegRole role; 18 18 19 20 21 22 23 24 25 26 27 28 29 19 /** 20 * Creates the issue. 21 * 22 * @param parent the parent model 23 * @param role the role of the missing way 24 */ 25 public MissingTurnRestrictionLegError(IssuesModel parent, TurnRestrictionLegRole role) { 26 super(parent, Severity.ERROR); 27 this.role = role; 28 actions.add(new FixAction()); 29 } 30 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 31 @Override 32 public String getText() { 33 String msg = ""; 34 switch(role){ 35 case FROM: 36 msg = tr("An OSM way with role <tt>from</tt> is required in a turn restriction."); 37 break; 38 case TO: 39 msg = tr("An OSM way with role <tt>to</tt> is required in a turn restriction."); 40 break; 41 } 42 msg += " " + tr("Please go to the Basic editor and manually choose an OSM way."); 43 return msg; 44 } 45 45 46 47 48 49 50 51 52 53 54 55 break; 56 } 57 58 59 60 61 62 63 64 65 break; 66 } 67 } 68 46 class FixAction extends AbstractAction { 47 public FixAction() { 48 putValue(NAME, tr("Add in editor")); 49 switch(role){ 50 case FROM: 51 putValue(SHORT_DESCRIPTION, tr("Add an OSM way with role ''from''")); 52 break; 53 case TO: 54 putValue(SHORT_DESCRIPTION, tr("Add an OSM way with role ''to''")); 55 break; 56 } 57 } 58 public void actionPerformed(ActionEvent e) { 59 switch(role){ 60 case FROM: 61 getIssuesModel().getNavigationControler().gotoBasicEditor(FROM); 62 break; 63 case TO: 64 getIssuesModel().getNavigationControler().gotoBasicEditor(TO); 65 break; 66 } 67 } 68 } 69 69 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/MultipleTurnRestrictionLegError.java
r20701 r23192 14 14 */ 15 15 public class MultipleTurnRestrictionLegError extends Issue { 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 16 private TurnRestrictionLegRole role; 17 private int numLegs; 18 19 /** 20 * Create the issue 21 * 22 * @param parent the parent model 23 * @param role the role of the turn restriction leg with multiple entries 24 * @param numLegs the number of legs 25 */ 26 public MultipleTurnRestrictionLegError(IssuesModel parent, TurnRestrictionLegRole role, int numLegs) { 27 super(parent, Severity.ERROR); 28 this.role = role; 29 this.numLegs = numLegs; 30 actions.add(new FixAction()); 31 } 32 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 33 @Override 34 public String getText() { 35 switch(role){ 36 case FROM: 37 return tr("A turn restriction requires exactly one way with role <tt>from</tt>. " 38 + "This turn restriction has {0} ways in this role. Please remove " 39 + "{1} of them.", 40 numLegs, 41 numLegs -1 42 ); 43 case TO: 44 return tr("A turn restriction requires exactly one way with role <tt>to</tt>. " 45 + "This turn restriction has {0} ways in this role. Please remove " 46 + "{1} of them.", 47 numLegs, 48 numLegs -1 49 ); 50 } 51 return ""; 52 } 53 53 54 55 56 57 58 59 60 61 } 62 54 class FixAction extends AbstractAction { 55 public FixAction() { 56 putValue(NAME, tr("Fix in editor")); 57 putValue(SHORT_DESCRIPTION, tr("Go to the Advanced Editor and remove the members")); 58 } 59 public void actionPerformed(ActionEvent e) { 60 getIssuesModel().getNavigationControler().gotoAdvancedEditor(); 61 } 62 } 63 63 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/NonStandardExceptWarning.java
r20586 r23192 14 14 */ 15 15 public class NonStandardExceptWarning extends Issue{ 16 17 18 19 20 21 16 private ExceptValueModel value; 17 public NonStandardExceptWarning(IssuesModel parent, ExceptValueModel value) { 18 super(parent, Severity.WARNING); 19 actions.add(new FixInEditorAction()); 20 this.value = value; 21 } 22 22 23 24 25 26 27 28 ); 29 30 31 32 33 34 35 36 37 38 } 39 23 @Override 24 public String getText() { 25 return tr("The tag <tt>except</tt> has the non-standard value <tt>{0}</tt>. " 26 + "It is recommended to use standard values for <tt>except</tt> only.", 27 value.getValue() 28 ); 29 } 30 31 class FixInEditorAction extends AbstractAction { 32 public FixInEditorAction() { 33 putValue(NAME, tr("Fix in editor")); 34 putValue(SHORT_DESCRIPTION, tr("Go to Basic Editor and select standard vehicle type based exceptions")); 35 } 36 public void actionPerformed(ActionEvent e) { 37 getIssuesModel().getNavigationControler().gotoBasicEditor(); 38 } 39 } 40 40 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/RequiredTagMissingError.java
r20586 r23192 15 15 */ 16 16 public class RequiredTagMissingError extends Issue { 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 17 static private final Logger logger = Logger.getLogger(RequiredTagMissingError.class.getName()); 18 private String tagKey; 19 private String tagValue; 20 21 /** 22 * Create the issue 23 * 24 * @param parent the issues model 25 * @param tagKey the tag key 26 * @param tagValue the tag value 27 */ 28 public RequiredTagMissingError(IssuesModel parent, String tagKey, String tagValue) { 29 super(parent, Severity.ERROR); 30 this.tagKey = tagKey; 31 this.tagValue = tagValue; 32 actions.add(new AddTagAction()); 33 } 34 34 35 36 37 38 39 40 41 35 @Override 36 public String getText() { 37 return tr("The required tag <tt>{0}={1}</tt> is missing.", 38 this.tagKey, 39 this.tagValue 40 ); 41 } 42 42 43 44 45 46 47 48 49 50 51 52 53 54 55 } 56 }57 43 private class AddTagAction extends AbstractAction { 44 public AddTagAction(){ 45 putValue(NAME,tr("Add missing tag")); 46 putValue(SHORT_DESCRIPTION, tr("Add the missing tag {0}={1}", tagKey, tagValue)); 47 } 48 49 public void actionPerformed(ActionEvent e) { 50 TagEditorModel model = getIssuesModel().getEditorModel().getTagEditorModel(); 51 TagModel t = model.get(tagKey); 52 if (t == null){ 53 t = new TagModel(tagKey, tagValue); 54 model.prepend(t); 55 } 56 } 57 } 58 58 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/Severity.java
r20586 r23192 2 2 3 3 public enum Severity { 4 5 4 WARNING, 5 ERROR 6 6 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/TurnRestrictionLegSplitRequiredError.java
r22477 r23192 23 23 */ 24 24 public class TurnRestrictionLegSplitRequiredError extends Issue{ 25 26 27 28 25 private TurnRestrictionLegRole role; 26 private Way from; 27 private Way to; 28 private Node interesect; 29 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 30 /** 31 * Create the issue 32 * 33 * @param parent the parent model 34 * @param role the role of the way which should be splitted 35 * @param from the way with role 'from' 36 * @param to the way with role 'to' 37 * @param interesect the node at the intersection 38 */ 39 public TurnRestrictionLegSplitRequiredError(IssuesModel parent, TurnRestrictionLegRole role, Way from, Way to, Node intersect) { 40 super(parent, Severity.ERROR); 41 this.role = role; 42 this.from = from; 43 this.to = to; 44 this.interesect = intersect; 45 actions.add(new SplitAction()); 46 } 47 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 48 @Override 49 public String getText() { 50 String msg = null; 51 switch(role){ 52 case FROM: 53 msg = tr("The OSM way <span class=\"object-name\">{0}</span> with role <tt>{1}</tt> should be split " 54 + "at node <span class=\"object-name\">{2}</span> where it connects to way <span class=\"object-name\">{3}</span>.", 55 from.getDisplayName(DefaultNameFormatter.getInstance()), 56 role.getOsmRole(), 57 interesect.getDisplayName(DefaultNameFormatter.getInstance()), 58 to.getDisplayName(DefaultNameFormatter.getInstance()) 59 ); 60 break; 61 case TO: 62 msg = tr("The OSM way <span class=\"object-name\">{0}</span> with role <tt>{1}</tt> should be split " 63 + "at node <span class=\"object-name\">{2}</span> where it connects to way <span class=\"object-name\">{3}</span>.", 64 to.getDisplayName(DefaultNameFormatter.getInstance()), 65 role.getOsmRole(), 66 interesect.getDisplayName(DefaultNameFormatter.getInstance()), 67 from.getDisplayName(DefaultNameFormatter.getInstance()) 68 ); 69 break; 70 } 71 return msg; 72 } 73 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 74 class SplitAction extends AbstractAction { 75 public SplitAction() { 76 putValue(NAME, tr("Split now")); 77 putValue(SHORT_DESCRIPTION, tr("Splits the way")); 78 } 79 public void actionPerformed(ActionEvent e) { 80 Way way = null; 81 switch(role){ 82 case FROM: way = from; break; 83 case TO: way = to; break; 84 } 85 SplitWayResult result = SplitWayAction.split( 86 parent.getEditorModel().getLayer(), 87 way, 88 Collections.singletonList(interesect), 89 Collections.<OsmPrimitive>emptyList() 90 ); 91 if (result != null){ 92 Main.main.undoRedo.add(result.getCommand()); 93 } 94 } 95 } 96 96 } -
applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/WrongTurnRestrictionLegTypeError.java
r20622 r23192 19 19 */ 20 20 public class WrongTurnRestrictionLegTypeError extends Issue { 21 22 21 private TurnRestrictionLegRole role; 22 private OsmPrimitive leg; 23 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 24 /** 25 * Create the issue 26 * 27 * @param parent the parent model 28 * @param role the role of the turn restriction leg 29 * @param leg the leg 30 */ 31 public WrongTurnRestrictionLegTypeError(IssuesModel parent, TurnRestrictionLegRole role, OsmPrimitive leg) { 32 super(parent, Severity.ERROR); 33 this.role = role; 34 this.leg = leg; 35 actions.add(new DeleteAction()); 36 actions.add(new FixInEditorAction()); 37 } 38 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 ); 55 break; 56 57 58 39 @Override 40 public String getText() { 41 String msg = null; 42 switch(leg.getType()){ 43 case NODE: 44 msg = tr( 45 "This turn restriction uses the OSM node <span class=\"object-name\">{0}</span> as member with role <tt>{1}</tt>.", 46 leg.getDisplayName(DefaultNameFormatter.getInstance()), 47 role.toString() 48 ); 49 break; 50 case RELATION: 51 msg = tr("This turn restriction uses the OSM relation <span class=\"object-name\">{0}</span> as member with role <tt>{1}</tt>.", 52 leg.getDisplayName(DefaultNameFormatter.getInstance()), 53 role.toString() 54 ); 55 break; 56 } 57 return msg + " " + tr("An OSM way is required instead."); 58 } 59 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 } 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 } 94 60 class DeleteAction extends AbstractAction { 61 public DeleteAction() { 62 putValue(NAME, tr("Delete")); 63 putValue(SHORT_DESCRIPTION, tr("Delete the member from the turn restriction")); 64 } 65 public void actionPerformed(ActionEvent e) { 66 RelationMemberEditorModel model = getIssuesModel().getEditorModel().getRelationMemberEditorModel(); 67 switch(role){ 68 case FROM: 69 model.setFromPrimitive(null); 70 break; 71 case TO: 72 model.setToPrimitive(null); 73 break; 74 } 75 } 76 } 77 78 class FixInEditorAction extends AbstractAction { 79 public FixInEditorAction() { 80 putValue(NAME, tr("Fix in editor")); 81 putValue(SHORT_DESCRIPTION, tr("Change to the Basic Editor and select an OSM way")); 82 } 83 public void actionPerformed(ActionEvent e) { 84 NavigationControler controler = getIssuesModel().getNavigationControler(); 85 switch(role){ 86 case FROM: 87 controler.gotoBasicEditor(BasicEditorFokusTargets.FROM); 88 break; 89 case TO: 90 controler.gotoBasicEditor(BasicEditorFokusTargets.TO); 91 break; 92 } 93 } 94 } 95 95 }
Note:
See TracChangeset
for help on using the changeset viewer.