Ignore:
Timestamp:
2010-09-15T18:59:53+02:00 (14 years ago)
Author:
stoecker
Message:

remove tabs

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  
    2929 */
    3030public class CreateOrEditTurnRestrictionAction extends JosmAction {
    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         }
     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    }
    121121}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionBuilder.java

    r20724 r23192  
    2121public class TurnRestrictionBuilder {
    2222
    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         }
     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    }
    4545
    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         }
     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    }
    128128
    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         }               
     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    }       
    162162}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/TurnRestrictionsPlugin.java

    r20701 r23192  
    1313 */
    1414public class TurnRestrictionsPlugin extends Plugin{
    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         }
     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    }
    3232
    33         @Override
    34         public PreferenceSetting getPreferenceSetting() {
    35                 return new PreferenceEditor();
    36         }
     33    @Override
     34    public PreferenceSetting getPreferenceSetting() {
     35        return new PreferenceEditor();
     36    }
    3737}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdListProvider.java

    r20489 r23192  
    55import org.openstreetmap.josm.data.osm.PrimitiveId;;
    66public interface PrimitiveIdListProvider {
    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();
     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();
    1414}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdListTransferHandler.java

    r20724 r23192  
    2020 */
    2121public class PrimitiveIdListTransferHandler extends TransferHandler {
    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}.
     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}.
    2727
    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         }
     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    }
    4848
    49        
    50        
    51         protected Transferable createTransferable(JComponent c) {
    52                 return new PrimitiveIdTransferable(provider.getSelectedPrimitiveIds());                 
    53         }
     49   
     50   
     51    protected Transferable createTransferable(JComponent c) {
     52        return new PrimitiveIdTransferable(provider.getSelectedPrimitiveIds());         
     53    }
    5454
    55         public int getSourceActions(JComponent c) {
    56                 return COPY;
    57         }
     55    public int getSourceActions(JComponent c) {
     56        return COPY;
     57    }
    5858
    59         @Override
    60         public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
    61                 return isSupportedFlavor(transferFlavors);     
    62         }       
     59    @Override
     60    public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
     61        return isSupportedFlavor(transferFlavors); 
     62    }   
    6363}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/dnd/PrimitiveIdTransferable.java

    r20489 r23192  
    1818 */
    1919public class PrimitiveIdTransferable implements Transferable{
    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         };
     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    };
    3535
    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         }
     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    }
    9090
    91         public DataFlavor[] getTransferDataFlavors() {
    92                 return SUPPORTED_FLAVORS;
    93         }
     91    public DataFlavor[] getTransferDataFlavors() {
     92        return SUPPORTED_FLAVORS;
     93    }
    9494
    95         public boolean isDataFlavorSupported(DataFlavor flavor) {
    96                 for(DataFlavor df: SUPPORTED_FLAVORS) {
    97                         if (df.equals(flavor)) return true;
    98                 }
    99                 return false;
    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    }           
    101101}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/AdvancedEditorPanel.java

    r20735 r23192  
    2323 */
    2424public class AdvancedEditorPanel extends JPanel {
    25         private static final Logger logger = Logger.getLogger(AdvancedEditorPanel.class.getName());
     25    private static final Logger logger = Logger.getLogger(AdvancedEditorPanel.class.getName());
    2626
    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         }
     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    }
    122122}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/BasicEditorPanel.java

    r20917 r23192  
    2828public class BasicEditorPanel extends VerticallyScrollablePanel {
    2929
    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);
     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);
    5959
    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);
     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);
    6969
    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         }
     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    }
    179179}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ExceptValueModel.java

    r20586 r23192  
    1414 */
    1515public class ExceptValueModel {
    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         }               
     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    }       
    213213}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/JosmSelectionListModel.java

    r20735 r23192  
    4040 */
    4141public class JosmSelectionListModel extends AbstractListModel implements EditLayerChangeListener, SelectionChangedListener, DataSetListener, PrimitiveIdListProvider{
    42         static private final Logger logger = Logger.getLogger(JosmSelectionListModel.class.getName());
    43        
     42    static private final Logger logger = Logger.getLogger(JosmSelectionListModel.class.getName());
     43   
    4444    private final List<OsmPrimitive> selection = new ArrayList<OsmPrimitive>();
    4545    private DefaultListSelectionModel selectionModel;
     
    5555     */
    5656    public JosmSelectionListModel(OsmDataLayer layer, DefaultListSelectionModel selectionModel) {
    57         CheckParameterUtil.ensureParameterNotNull(selectionModel, "selectionModel");
    58         CheckParameterUtil.ensureParameterNotNull(layer, "layer");
    59         this.layer = layer;
     57        CheckParameterUtil.ensureParameterNotNull(selectionModel, "selectionModel");
     58        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
     59        this.layer = layer;
    6060        this.selectionModel = selectionModel;
    6161        setJOSMSelection(layer.data.getSelected());
     
    115115     */
    116116    public void setJOSMSelection(Collection<? extends OsmPrimitive> selection) {
    117         Collection<OsmPrimitive> sel = getSelected();
     117        Collection<OsmPrimitive> sel = getSelected();
    118118        this.selection.clear();
    119119        if (selection == null) {
     
    150150    public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
    151151        if (newLayer == null) {
    152                 // don't show a JOSM selection if we don't have a data layer
     152            // don't show a JOSM selection if we don't have a data layer
    153153            setJOSMSelection(null);
    154154        } else if (newLayer != layer){
    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);
     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);
    158158        } else {
    159159            setJOSMSelection(newLayer.data.getSelected());
     
    165165    /* ------------------------------------------------------------------------ */
    166166    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
    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;
     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;
    172172        setJOSMSelection(newSelection);
    173173    }
     
    184184        if (event.getDataset() != layer.data) return;
    185185        // may influence the display name of primitives, update the data
    186         update(event.getPrimitives());
     186        update(event.getPrimitives());
    187187    }
    188188
     
    217217    /* interface PrimitiveIdListProvider                                        */
    218218    /* ------------------------------------------------------------------------ */
    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         }
     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    }
    228228}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/JosmSelectionPanel.java

    r20586 r23192  
    4242 */
    4343public class JosmSelectionPanel extends JPanel {
    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         }
     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    }
    117117
    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                 }
     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        }
    128128
    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                 }
     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        }
    138138
    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         }
     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    }
    146146}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/NavigationControler.java

    r20586 r23192  
    22
    33public interface NavigationControler {
    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);     
     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); 
    1313}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberColumnModel.java

    r20724 r23192  
    1414 */
    1515public class RelationMemberColumnModel extends DefaultTableColumnModel{
    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         }
     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    }
    4747}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberEditorModel.java

    r20724 r23192  
    2424import org.openstreetmap.josm.tools.CheckParameterUtil;
    2525
    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         }
     26public 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    }
    492492}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberModel.java

    r20527 r23192  
    1616 */
    1717public class RelationMemberModel implements Serializable{
    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         }
     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    }
    4545
    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         }
     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    }
    5454
    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         }
     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    }
    6363
    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         }
     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    }
    7272
    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         }
     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    }
    9292
    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         }
     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    }
    114114}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberRoleCellRenderer.java

    r20724 r23192  
    1010public class RelationMemberRoleCellRenderer extends DefaultTableCellRenderer{
    1111private JLabel mockCell;
    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         }
     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    }
    3838}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberTable.java

    r20675 r23192  
    4646 */
    4747public class RelationMemberTable extends JTable {
    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);
     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);
    6565        setRowSelectionAllowed(true);
    6666        setColumnSelectionAllowed(true);
    6767
    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         }
     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    }
    359359}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/RelationMemberTargetCellRenderer.java

    r20724 r23192  
    1111
    1212public class RelationMemberTargetCellRenderer extends OsmPrimitivRenderer{
    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         }
     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    }
    4242}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionComboBox.java

    r20666 r23192  
    99 */
    1010public class TurnRestrictionComboBox extends JComboBox{
    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         }
     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    }
    4343}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionComboBoxModel.java

    r20606 r23192  
    2121 */
    2222public class TurnRestrictionComboBoxModel implements ComboBoxModel, Observer{
    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         }
     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    }
    6767
    68         public Object getSelectedItem() {
    69                 TurnRestrictionType type = TurnRestrictionType.fromTagValue(selectedTagValue);
    70                 if (type != null) return type;
    71                 return selectedTagValue;
    72         }
     68    public Object getSelectedItem() {
     69        TurnRestrictionType type = TurnRestrictionType.fromTagValue(selectedTagValue);
     70        if (type != null) return type;
     71        return selectedTagValue;
     72    }
    7373
    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         }
     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    }
    8383
    84         public Object getElementAt(int index) {
    85                 return values.get(index);
    86         }
     84    public Object getElementAt(int index) {
     85        return values.get(index);
     86    }
    8787
    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         }
     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    }
    121121}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditor.java

    r20916 r23192  
    5858
    5959public class TurnRestrictionEditor extends JDialog implements NavigationControler{
    60         final private static Logger logger = Logger.getLogger(TurnRestrictionEditor.class.getName());
    61        
     60    final private static Logger logger = Logger.getLogger(TurnRestrictionEditor.class.getName());
     61   
    6262    /** the property name for the current turn restriction
    6363     * @see #setRelation(Relation)
     
    8484    /** the data layer the turn restriction belongs to */
    8585    private OsmDataLayer layer;
    86        
     86   
    8787    private JosmSelectionPanel pnlJosmSelection;
    8888    private BasicEditorPanel pnlBasicEditor;
     
    114114     */
    115115    protected JPanel buildJOSMSelectionPanel() {
    116         pnlJosmSelection = new JosmSelectionPanel(layer);
    117         return pnlJosmSelection;
     116        pnlJosmSelection = new JosmSelectionPanel(layer);
     117        return pnlJosmSelection;
    118118    }
    119119   
     
    125125     */
    126126    protected JPanel buildEditorPanel() {
    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;
     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;
    146146    }
    147147   
     
    153153     */
    154154    protected JPanel buildContentPanel() {
    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());
     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());
    160160        addWindowListener(new WindowAdapter() {
    161161            @Override
     
    167167        });
    168168
    169         return pnl;
     169        return pnl;
    170170    }
    171171   
     
    197197     * builds the UI
    198198     */
    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);       
     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);       
    209209    }   
    210        
    211         /**
     210   
     211    /**
    212212    * Creates a new turn restriction editor
    213213    *
     
    216216    * @throws IllegalArgumentException thrown if layer is null
    217217    */
    218         public TurnRestrictionEditor(Component owner, OsmDataLayer layer) {
    219                 this(owner, layer, null);
    220         }
    221        
    222         /**
     218    public TurnRestrictionEditor(Component owner, OsmDataLayer layer) {
     219        this(owner, layer, null);
     220    }
     221   
     222    /**
    223223     * Creates a new turn restriction editor
    224224     *
     
    229229     */
    230230    public TurnRestrictionEditor(Component owner, OsmDataLayer layer, Relation turnRestriction)  throws IllegalArgumentException{
    231         super(JOptionPane.getFrameForComponent(owner),false /* not modal */);
     231        super(JOptionPane.getFrameForComponent(owner),false /* not modal */);
    232232        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
    233233        this.layer = layer;
     
    260260    protected void setTurnRestriction(Relation turnRestriction) {     
    261261        if (turnRestriction == null) {
    262                 editorModel.populate(new Relation());
     262            editorModel.populate(new Relation());
    263263        } else if (turnRestriction.getDataSet() == null || turnRestriction.getDataSet() == getLayer().data) {
    264                 editorModel.populate(turnRestriction);
     264            editorModel.populate(turnRestriction);
    265265        } else {
    266                 throw new IllegalArgumentException(MessageFormat.format("turnRestriction must belong to layer ''{0}''", getLayer().getName()));
     266            throw new IllegalArgumentException(MessageFormat.format("turnRestriction must belong to layer ''{0}''", getLayer().getName()));
    267267        }
    268268        setTurnRestrictionSnapshot(turnRestriction == null ? null : new Relation(turnRestriction));
     
    332332     */
    333333    public TurnRestrictionEditorModel getModel() {
    334         return editorModel;
     334        return editorModel;
    335335    }
    336336   
    337337    public void setVisible(boolean visible) {
    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         }
     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        }
    352352    }
    353353   
     
    371371    /* ----------------------------------------------------------------------- */
    372372    public void gotoBasicEditor() {
    373         tpEditors.setSelectedIndex(0);
    374         }
     373        tpEditors.setSelectedIndex(0);
     374    }
    375375
    376376    public void gotoAdvancedEditor() {
    377         tpEditors.setSelectedIndex(1);
    378         }
    379 
    380         public void gotoBasicEditor(BasicEditorFokusTargets focusTarget) {
    381                 tpEditors.setSelectedIndex(0);
    382                 pnlBasicEditor.requestFocusFor(focusTarget);
    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    /**
    386386     * The abstract base action for applying the updates of a turn restriction
    387387     * to the dataset.
    388388     */
    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        
     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       
    528528        /**
    529529         * apply updates to a new turn restriction
    530530         */
    531         protected boolean applyNewTurnRestriction() {           
     531        protected boolean applyNewTurnRestriction() {           
    532532            Relation newTurnRestriction = new Relation();
    533533            editorModel.apply(newTurnRestriction);
     
    541541            List<RelationMember> deletedMembers = getDeletedRelationMembers(newTurnRestriction);
    542542            if (!deletedMembers.isEmpty()) {
    543                 if (!confirmSaveTurnRestrictionWithDeletePrimitives(deletedMembers)) {
    544                         return false;
    545                 }
    546                 removeDeletedMembers(newTurnRestriction);
     543                if (!confirmSaveTurnRestrictionWithDeletePrimitives(deletedMembers)) {
     544                    return false;
     545                }
     546                removeDeletedMembers(newTurnRestriction);
    547547            }
    548548           
     
    576576         * outside of the turn restriction editor.
    577577         */
    578         protected void applyExistingNonConflictingTurnRestriction() {           
     578        protected void applyExistingNonConflictingTurnRestriction() {           
    579579            if (getTurnRestriction().getDataSet() == null) {
    580                 editorModel.apply(getTurnRestriction());
    581                 Main.main.undoRedo.add(new AddCommand(getTurnRestriction()));
     580                editorModel.apply(getTurnRestriction());
     581                Main.main.undoRedo.add(new AddCommand(getTurnRestriction()));
    582582            } else {
    583                 Relation toUpdate = new Relation(getTurnRestriction());
     583                Relation toUpdate = new Relation(getTurnRestriction());
    584584                editorModel.apply(toUpdate);           
    585                 Main.main.undoRedo.add(new ChangeCommand(getTurnRestriction(), toUpdate));
     585                Main.main.undoRedo.add(new ChangeCommand(getTurnRestriction(), toUpdate));
    586586            }
    587587            // this will refresh the snapshot and update the dialog title
     
    646646
    647647        public void run() {
    648                 if (!confirmSaveDespiteOfErrorsAndWarnings()){
    649                         tpEditors.setSelectedIndex(2); // show the errors and warnings
    650                         return;
    651                 }
     648            if (!confirmSaveDespiteOfErrorsAndWarnings()){
     649                tpEditors.setSelectedIndex(2); // show the errors and warnings
     650                return;
     651            }
    652652            if (getTurnRestriction() == null) {
    653653                applyNewTurnRestriction();
     
    658658            editorModel.apply(toUpdate);
    659659            if (TurnRestrictionEditorModel.hasSameMembersAndTags(toUpdate, getTurnRestriction()))
    660                 // nothing to update
    661                 return;
     660                // nothing to update
     661                return;
    662662           
    663663            if (isDirtyTurnRestriction()) {
     
    689689
    690690        public void run() {
    691                 if (!confirmSaveDespiteOfErrorsAndWarnings()){
    692                         tpEditors.setSelectedIndex(2); // show the errors and warnings
    693                         return;
    694                 }
     691            if (!confirmSaveDespiteOfErrorsAndWarnings()){
     692                tpEditors.setSelectedIndex(2); // show the errors and warnings
     693                return;
     694            }
    695695            if (getTurnRestriction() == null) {
    696                 // it's a new turn restriction. Try to save it and close the dialog
     696                // it's a new turn restriction. Try to save it and close the dialog
    697697                if (applyNewTurnRestriction()) {
    698                         setVisible(false);
     698                    setVisible(false);
    699699                }
    700700                return;
     
    704704            editorModel.apply(toUpdate);
    705705            if (TurnRestrictionEditorModel.hasSameMembersAndTags(toUpdate, getTurnRestriction())){
    706                 // nothing to update
    707                 setVisible(false);
    708                 return;
     706                // nothing to update
     707                setVisible(false);
     708                return;
    709709            }
    710710           
    711711            if (isDirtyTurnRestriction()) {
    712                 // the turn restriction this editor is working on has changed outside
    713                 // of the editor.
     712                // the turn restriction this editor is working on has changed outside
     713                // of the editor.
    714714                if (confirmClosingBecauseOfDirtyState()) {
    715715                    if (getLayer().getConflicts().hasConflictForMy(getTurnRestriction())) {
     
    750750   
    751751    class DeleteAction extends AbstractAction implements PropertyChangeListener{
    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(
     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(
    768768                    getLayer(),
    769769                    tr
    770770            );
    771                 setVisible(false);
    772                 }
    773 
    774                 public void propertyChange(PropertyChangeEvent evt) {
    775                         if (evt.getPropertyName().equals(TURN_RESTRICION_PROP)){
    776                                 updateEnabledState();
    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        }
    779779    }
    780780   
    781781    class SelectAction extends AbstractAction implements PropertyChangeListener{
    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                 }
     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        }
    805805    }
    806806   
    807807    class ZoomToAction extends AbstractAction implements PropertyChangeListener{
    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                 }
     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        }
    835835    }
    836836   
    837837    class IssuesModelObserver implements Observer {
    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                 }       
     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        }       
    865865    }
    866866   
     
    874874     *
    875875     */
    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                 }
     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        }
    888888    }
    889889}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditorManager.java

    r20489 r23192  
    2323 */
    2424public class TurnRestrictionEditorManager extends WindowAdapter implements MapView.LayerChangeListener{
    25         static private final Logger logger = Logger.getLogger(TurnRestrictionEditorManager.class.getName());
     25    static private final Logger logger = Logger.getLogger(TurnRestrictionEditorManager.class.getName());
    2626
    2727    /** keeps track of open relation editors */
     
    5555
    5656        @Override
    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) {
     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) {
    8989            if (layer == null) return false;
    9090            return this.layer.equals(layer);
     
    187187    @Override
    188188    public void windowClosed(WindowEvent e) {
    189         TurnRestrictionEditor editor = (TurnRestrictionEditor)e.getWindow();
     189        TurnRestrictionEditor editor = (TurnRestrictionEditor)e.getWindow();
    190190        DialogContext context = null;
    191191        for (DialogContext c : openDialogs.keySet()) {
     
    200200    }
    201201
    202         /**
     202    /**
    203203     * Positions an {@see TurnRestrictionEditor} centered on the screen
    204204     *
     
    286286            Entry<DialogContext,TurnRestrictionEditor> entry = it.next();
    287287            if (entry.getKey().matchesLayer(dataLayer)) {
    288                 TurnRestrictionEditor editor = entry.getValue();
     288                TurnRestrictionEditor editor = entry.getValue();
    289289                it.remove();
    290290                editor.setVisible(false);
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionEditorModel.java

    r20735 r23192  
    4040 */
    4141public class TurnRestrictionEditorModel extends Observable implements DataSetListener{
    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         }
     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    }
    443443}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionLegEditor.java

    r20701 r23192  
    5555 */
    5656public class TurnRestrictionLegEditor extends JPanel implements Observer, PrimitiveIdListProvider {
    57         static private final Logger logger = Logger.getLogger(TurnRestrictionLegEditor.class.getName());
     57    static private final Logger logger = Logger.getLogger(TurnRestrictionLegEditor.class.getName());
    5858 
    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         }
     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    }
    368368}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionLegRole.java

    r20622 r23192  
    44 * Enumerates the two roles a "leg" in a turn restriction can have.
    55 */
    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         }
     6public 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    }
    1919}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionSelectionPopupPanel.java

    r20606 r23192  
    5050 */
    5151public class TurnRestrictionSelectionPopupPanel extends JPanel{
    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         }
     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    }
    364364}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionType.java

    r20586 r23192  
    99 */
    1010public enum TurnRestrictionType {
    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         }
     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    }
    5858
    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         }
     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    }
    6868}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/TurnRestrictionTypeRenderer.java

    r20666 r23192  
    2020public class TurnRestrictionTypeRenderer extends JLabel implements ListCellRenderer{
    2121 
    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         }       
     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    }   
    8787}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/VehicleExceptionEditor.java

    r20648 r23192  
    3636 */
    3737public class VehicleExceptionEditor extends JPanel implements Observer{
    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         }
     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    }
    327327}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ViaList.java

    r20489 r23192  
    4646 */
    4747public class ViaList extends JList{
    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         }       
     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    }   
    307307}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/editor/ViaListModel.java

    r20527 r23192  
    2323 */
    2424public class ViaListModel extends AbstractListModel implements PrimitiveIdListProvider, Observer{
    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         }       
     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    }   
    245245}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/AbstractTurnRestrictionsListView.java

    r20666 r23192  
    1515 */
    1616abstract class AbstractTurnRestrictionsListView extends JPanel {
    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         }
     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    }
    4040}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionCellRenderer.java

    r20701 r23192  
    4141 */
    4242public class TurnRestrictionCellRenderer extends JPanel implements ListCellRenderer, TableCellRenderer{
    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         }       
     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    }   
    258258}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInDatasetListModel.java

    r20489 r23192  
    3434 */
    3535public class TurnRestrictionsInDatasetListModel extends TurnRestrictionsListModel implements EditLayerChangeListener, DataSetListener {
    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         }
     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    }
    8888
    89         public void primtivesAdded(PrimitivesAddedEvent event) {
    90                 List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
    91                 if (!turnRestrictions.isEmpty()) {
    92                         addTurnRestrictions(turnRestrictions);
    93                 }
    94         }
     89    public void primtivesAdded(PrimitivesAddedEvent event) {
     90        List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
     91        if (!turnRestrictions.isEmpty()) {
     92            addTurnRestrictions(turnRestrictions);
     93        }
     94    }
    9595
    96         public void primtivesRemoved(PrimitivesRemovedEvent event) {
    97                 List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
    98                 if (!turnRestrictions.isEmpty()) {
    99                         removeTurnRestrictions(turnRestrictions);
    100                 }
    101         }
     96    public void primtivesRemoved(PrimitivesRemovedEvent event) {
     97        List<Relation> turnRestrictions = filterTurnRestrictions(event.getPrimitives());
     98        if (!turnRestrictions.isEmpty()) {
     99            removeTurnRestrictions(turnRestrictions);
     100        }
     101    }
    102102
    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         }
     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    }
    115115
    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         }
     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    }
    128128
    129         public void wayNodesChanged(WayNodesChangedEvent event) {/* ignore */}
    130         public void nodeMoved(NodeMovedEvent event) {/* ignore */}
    131         public void otherDatasetChange(AbstractDatasetChangedEvent event) {/* ignore */}
     129    public void wayNodesChanged(WayNodesChangedEvent event) {/* ignore */}
     130    public void nodeMoved(NodeMovedEvent event) {/* ignore */}
     131    public void otherDatasetChange(AbstractDatasetChangedEvent event) {/* ignore */}
    132132}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInDatasetView.java

    r20711 r23192  
    1818 * This is the view for the list of turn restrictions in the current data set.
    1919 */
    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         }
     20public 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    }
    3232
    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         }
     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    }
    4040
    41         protected void unregisterAsListener() {
    42                 MapView.removeEditLayerChangeListener((EditLayerChangeListener)model);
    43                 DatasetEventManager.getInstance().removeDatasetListener((DataSetListener)model);
    44         }
     41    protected void unregisterAsListener() {
     42        MapView.removeEditLayerChangeListener((EditLayerChangeListener)model);
     43        DatasetEventManager.getInstance().removeDatasetListener((DataSetListener)model);
     44    }
    4545
    46         public TurnRestrictionsInDatasetView() {
    47                 build();
    48         }
     46    public TurnRestrictionsInDatasetView() {
     47        build();
     48    }
    4949}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInSelectionListModel.java

    r20489 r23192  
    1919 */
    2020public class TurnRestrictionsInSelectionListModel extends TurnRestrictionsListModel implements EditLayerChangeListener, SelectionChangedListener {
    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         }
     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    }
    4545
    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         }
     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    }
    6363}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsInSelectionView.java

    r20711 r23192  
    2424public class TurnRestrictionsInSelectionView extends AbstractTurnRestrictionsListView {
    2525
    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         }
     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    }
    3737
    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         }
     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    }
    4848
    49         protected void unregisterAsListener() {
    50                 MapView.removeEditLayerChangeListener((EditLayerChangeListener)model);
    51                 SelectionEventManager.getInstance().removeSelectionListener((SelectionChangedListener)model);           
    52         }
     49    protected void unregisterAsListener() {
     50        MapView.removeEditLayerChangeListener((EditLayerChangeListener)model);
     51        SelectionEventManager.getInstance().removeSelectionListener((SelectionChangedListener)model);       
     52    }
    5353
    54         public TurnRestrictionsInSelectionView() {
    55                 build();
    56         }
     54    public TurnRestrictionsInSelectionView() {
     55        build();
     56    }
    5757}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsListDialog.java

    r20735 r23192  
    5252 */
    5353public class TurnRestrictionsListDialog extends ToggleDialog{
    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         /**
     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    /**
    212212     * The edit action
    213213     *
     
    231231        }
    232232
    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                 }
     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        }
    250250
    251251        public void actionPerformed(ActionEvent e) {
     
    258258
    259259        public void updateEnabledState() {
    260                 setEnabled(currentListView!= null && currentListView.getModel().getSelectedTurnRestrictions().size() == 1);
     260            setEnabled(currentListView!= null && currentListView.getModel().getSelectedTurnRestrictions().size() == 1);
    261261        }
    262262       
     
    298298       
    299299        public void updateEnabledState() {
    300                 setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
     300            setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
    301301        }
    302302
    303303        public void valueChanged(ListSelectionEvent e) {
    304                 updateEnabledState();
     304            updateEnabledState();
    305305        }
    306306    }
     
    319319
    320320        public void run() {
    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);
     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);
    325325             TurnRestrictionEditorManager.getInstance().positionOnScreen(editor);             
    326326             TurnRestrictionEditorManager.getInstance().register(layer, tr, editor);
     
    336336        }
    337337
    338                 public void editLayerChanged(OsmDataLayer oldLayer,
    339                                 OsmDataLayer newLayer) {
    340             updateEnabledState();
    341                 }
     338        public void editLayerChanged(OsmDataLayer oldLayer,
     339                OsmDataLayer newLayer) {
     340            updateEnabledState();
     341        }
    342342    }
    343343   
     
    367367       
    368368        public void updateEnabledState() {
    369                 setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
     369            setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
    370370        }
    371371
    372372        public void valueChanged(ListSelectionEvent e) {
    373                 updateEnabledState();
     373            updateEnabledState();
    374374        }
    375375    }
     
    401401       
    402402        public void updateEnabledState() {
    403                 setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
     403            setEnabled(currentListView != null && !currentListView.getModel().getSelectedTurnRestrictions().isEmpty());
    404404        }
    405405
    406406        public void valueChanged(ListSelectionEvent e) {
    407                 updateEnabledState();
     407            updateEnabledState();
    408408        }
    409409    }
     
    448448     *
    449449     */
    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                 }
     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        }
    461461    }
    462462}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/list/TurnRestrictionsListModel.java

    r20489 r23192  
    7373     */
    7474    protected boolean isTurnRestriction(OsmPrimitive primitive) {
    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;
     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;
    8080    }
    8181   
     
    122122                continue;
    123123            }
    124                         turnrestrictions.add(r);
    125                         added = true;
     124            turnrestrictions.add(r);
     125            added = true;
    126126        }
    127127        if (added) {
     
    143143        Set<Relation> removedTurnRestrictions = new HashSet<Relation>();
    144144        for (OsmPrimitive p: removedPrimitives) {
    145                 if (!isTurnRestriction(p)) continue;
     145            if (!isTurnRestriction(p)) continue;
    146146            removedTurnRestrictions.add((Relation)p);
    147147        }
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/preferences/PreferenceEditor.java

    r20675 r23192  
    3131 */
    3232public class PreferenceEditor extends JPanel implements PreferenceSetting{
    33        
    34         private PreferencesPanel pnlIconPreferences;
     33   
     34    private PreferencesPanel pnlIconPreferences;
    3535
    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         }
     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    }
    7575
    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);
     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);
    108108        tab.add(this, GBC.eol().fill(GBC.BOTH));
    109         }
     109    }
    110110
    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                 }
     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        }
    129129
    130                 @Override
    131                 public void mouseClicked(MouseEvent e) {
    132                         launchBrowser();
    133                 }
    134         }
     130        @Override
     131        public void mouseClicked(MouseEvent e) {
     132            launchBrowser();
     133        }
     134    }
    135135}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/preferences/PreferenceKeys.java

    r20701 r23192  
    99 */
    1010public interface PreferenceKeys {
    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";
     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";
    4040}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/preferences/PreferencesPanel.java

    r20701 r23192  
    3030 */
    3131public class PreferencesPanel extends VerticallyScrollablePanel {
    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         }       
     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    }   
    232232}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/preferences/ShortcutPreferencePanel.java

    r20701 r23192  
    3636 */
    3737public class ShortcutPreferencePanel extends JPanel {
    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         }
     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    }
    225225}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IdenticalTurnRestrictionLegsError.java

    r20701 r23192  
    1515 */
    1616public class IdenticalTurnRestrictionLegsError extends Issue{
    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         }
     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    }
    2626
    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         }
     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    }
    6464}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IllegalRestrictionTypeError.java

    r20622 r23192  
    1515 */
    1616public class IllegalRestrictionTypeError extends Issue{
    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         }
     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    }
    2424
    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         }
     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    }
    4242}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IntersectionMissingAsViaError.java

    r20701 r23192  
    2020 */
    2121public class IntersectionMissingAsViaError extends Issue{
    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         }
     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    }
    3434
    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         }
     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    }
    6666}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/Issue.java

    r20622 r23192  
    1818 */
    1919abstract public class Issue {
    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         }
     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    }
    5353
    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         }
     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    }
    6262
    63         /**
    64         * Replies the severity of this issue
    65         *
    66         * @return the severity
    67         */
    68         public Severity getSeverity() {
    69                 return severity;
    70         }
     63    /**
     64    * Replies the severity of this issue
     65    *
     66    * @return the severity
     67    */
     68    public Severity getSeverity() {
     69        return severity;
     70    }
    7171
    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         }
     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    }
    8282
    83         /**
    84         * Replies the HTML formatted description of the issue. The text should neither include
    85         * the &lt;html&gt;, nor the &lt;body&gt; 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         }
     83    /**
     84    * Replies the HTML formatted description of the issue. The text should neither include
     85    * the &lt;html&gt;, nor the &lt;body&gt; 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    }
    100100}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IssueView.java

    r20645 r23192  
    2626public class IssueView extends JPanel{
    2727
    28         private HtmlPanel pnlMessage;
    29         private JPanel pnlActions;
    30         private Issue issue;
    31         private JLabel lblIcon;
    32         private StyleSheet styleSheet;
    33        
    34         /**
     28    private HtmlPanel pnlMessage;
     29    private JPanel pnlActions;
     30    private Issue issue;
     31    private JLabel lblIcon;
     32    private StyleSheet styleSheet;
     33   
     34    /**
    3535     * Builds the style sheet used in the internal help browser
    3636     *
     
    4343        ss.addRule(".object-name {background-color:rgb(240,240,240); color: blue;}");
    4444    }
    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));
     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));
    6565
    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>");
     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>");
    7979
    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         }
     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    }
    119119
    120         @Override
    121         public Dimension getMinimumSize() {
    122                 return super.getPreferredSize();
    123         }
     120    @Override
     121    public Dimension getMinimumSize() {
     122        return super.getPreferredSize();
     123    }
    124124}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IssuesModel.java

    r20724 r23192  
    3131 */
    3232public class IssuesModel extends Observable implements Observer{
    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         }
     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    }
    264264}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/IssuesView.java

    r20735 r23192  
    1717 */
    1818public class IssuesView extends VerticallyScrollablePanel implements Observer{
    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         }
     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    }
    6565
    66         /* ------------------------------------------------------------------------------- */
    67         /* interface Observer                                                              */
    68         /* ------------------------------------------------------------------------------- */
    69         public void update(Observable o, Object arg) {
    70                 refresh();             
    71         }
     66    /* ------------------------------------------------------------------------------- */
     67    /* interface Observer                                                              */
     68    /* ------------------------------------------------------------------------------- */
     69    public void update(Observable o, Object arg) {
     70        refresh();     
     71    }
    7272}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/MissingRestrictionTypeError.java

    r20586 r23192  
    1515 */
    1616public class MissingRestrictionTypeError extends Issue{
    17        
    18         public MissingRestrictionTypeError(IssuesModel parent) {
    19                 super(parent, Severity.ERROR);
    20                 actions.add(new FixInEditorAction());
    21         }
     17   
     18    public MissingRestrictionTypeError(IssuesModel parent) {
     19        super(parent, Severity.ERROR);
     20        actions.add(new FixInEditorAction());
     21    }
    2222
    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         }
     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    }
    3737}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/MissingTurnRestrictionLegError.java

    r20633 r23192  
    1515 */
    1616public class MissingTurnRestrictionLegError extends Issue {
    17         private TurnRestrictionLegRole role;
     17    private TurnRestrictionLegRole role;
    1818
    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         }
     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    }
    3030
    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         }
     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    }
    4545
    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         }
     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    }
    6969}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/MultipleTurnRestrictionLegError.java

    r20701 r23192  
    1414 */
    1515public class MultipleTurnRestrictionLegError extends Issue {
    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         }
     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    }
    3232
    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         }
     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    }
    5353
    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         }
     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    }
    6363}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/NonStandardExceptWarning.java

    r20586 r23192  
    1414 */
    1515public class NonStandardExceptWarning extends Issue{
    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         }
     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    }
    2222
    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         }
     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    }
    4040}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/RequiredTagMissingError.java

    r20586 r23192  
    1515 */
    1616public class RequiredTagMissingError extends Issue {
    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         }
     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    }
    3434
    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         }
     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    }
    4242
    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         }
     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    }
    5858}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/Severity.java

    r20586 r23192  
    22
    33public enum Severity {
    4         WARNING,
    5         ERROR
     4    WARNING,
     5    ERROR
    66}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/TurnRestrictionLegSplitRequiredError.java

    r22477 r23192  
    2323 */
    2424public class TurnRestrictionLegSplitRequiredError extends Issue{
    25         private TurnRestrictionLegRole role;
    26         private Way from;
    27         private Way to;
    28         private Node interesect;
     25    private TurnRestrictionLegRole role;
     26    private Way from;
     27    private Way to;
     28    private Node interesect;
    2929
    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         }
     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    }
    4747
    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         }
     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    }
    7373
    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         }
     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    }
    9696}
  • applications/editors/josm/plugins/turnrestrictions/src/org/openstreetmap/josm/plugins/turnrestrictions/qa/WrongTurnRestrictionLegTypeError.java

    r20622 r23192  
    1919 */
    2020public class WrongTurnRestrictionLegTypeError extends Issue {
    21         private TurnRestrictionLegRole role;
    22         private OsmPrimitive leg;
     21    private TurnRestrictionLegRole role;
     22    private OsmPrimitive leg;
    2323
    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         }
     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    }
    3838
    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         }
     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    }
    5959
    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         }
     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    }
    9595}
Note: See TracChangeset for help on using the changeset viewer.