Changeset 1822 in josm


Ignore:
Timestamp:
2009-07-21T20:42:50+02:00 (15 years ago)
Author:
Gubaer
Message:

applied #2953: patch by cjw - Sorting a relation adds new members or crashes
applied the patch but disabled the sort action because first smoke test resulted in an exception

Location:
trunk/src/org/openstreetmap/josm/gui/dialogs/relation
Files:
3 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java

    r1819 r1822  
    3939import javax.swing.JTextField;
    4040import javax.swing.KeyStroke;
    41 import javax.swing.ListSelectionModel;
    4241import javax.swing.SwingUtilities;
    4342import javax.swing.event.DocumentEvent;
     
    7372import org.xml.sax.SAXException;
    7473
    75 
    7674/**
    7775 * This dialog is for editing relations.
    78  *
    79  * In the basic form, it provides two tables, one with the relation tags
    80  * and one with the relation members. (Relation tags can be edited through
    81  * the normal properties dialog as well, if you manage to get a relation
    82  * selected!)
    83  *
     76 *
     77 * In the basic form, it provides two tables, one with the relation tags and one with the relation
     78 * members. (Relation tags can be edited through the normal properties dialog as well, if you manage
     79 * to get a relation selected!)
     80 *
    8481 * @author Frederik Ramm <frederik@remote.org>
    85  *
     82 * 
    8683 */
    8784public class GenericRelationEditor extends RelationEditor {
    8885
    8986    static private final Logger logger = Logger.getLogger(GenericRelationEditor.class.getName());
    90     static private final Dimension DEFAULT_EDITOR_DIMENSION = new Dimension(700,500);
     87    static private final Dimension DEFAULT_EDITOR_DIMENSION = new Dimension(700, 500);
    9188
    9289    /** the tag table and its model */
     
    107104
    108105    /**
    109      * Creates a new relation editor for the given relation. The relation
    110      * will be saved if the user selects "ok" in the editor.
    111      *
     106     * Creates a new relation editor for the given relation. The relation will be saved if the user
     107     * selects "ok" in the editor.
     108     * 
    112109     * If no relation is given, will create an editor for a new relation.
    113      *
     110     * 
    114111     * @param layer the {@see OsmDataLayer} the new or edited relation belongs to
    115112     * @param relation relation to edit, or null to create a new one.
    116113     * @param selectedMembers a collection of members which shall be selected initially
    117114     */
    118     public GenericRelationEditor(OsmDataLayer layer, Relation relation, Collection<RelationMember> selectedMembers )
    119     {
     115    public GenericRelationEditor(OsmDataLayer layer, Relation relation, Collection<RelationMember> selectedMembers) {
    120116        super(layer, relation, selectedMembers);
    121117
     
    149145        JPanel pnl = new JPanel();
    150146        pnl.setLayout(new BorderLayout());
    151         pnl.add(pane,BorderLayout.CENTER);
     147        pnl.add(pane, BorderLayout.CENTER);
    152148        pnl.setBorder(BorderFactory.createRaisedBevelBorder());
    153149
     
    159155        }
    160156
    161         getContentPane().add(tabbedPane,BorderLayout.CENTER);
     157        getContentPane().add(tabbedPane, BorderLayout.CENTER);
    162158        getContentPane().add(buildOkCancelButtonPanel(), BorderLayout.SOUTH);
    163159
     
    165161        try {
    166162            setAlwaysOnTop(true);
    167         } catch(SecurityException e) {
    168             logger.warning(tr("Caught security exception for setAlwaysOnTop(). Ignoring. Exception was: {0}", e.toString()));
    169         }
    170     }
    171 
    172     /**
    173      * builds the panel with the OK and  the Cancel button
    174      *
    175      * @return the panel with the OK and  the Cancel button
     163        } catch (SecurityException e) {
     164            logger.warning(tr("Caught security exception for setAlwaysOnTop(). Ignoring. Exception was: {0}", e
     165                    .toString()));
     166        }
     167    }
     168
     169    /**
     170     * builds the panel with the OK and the Cancel button
     171     *
     172     * @return the panel with the OK and the Cancel button
    176173     */
    177174    protected JPanel buildOkCancelButtonPanel() {
     
    187184    /**
    188185     * build the panel with the buttons on the left
    189      *
     186     * 
    190187     * @return
    191188     */
     
    197194        gc.gridx = 0;
    198195        gc.gridy = 0;
    199         gc.gridheight  =1;
     196        gc.gridheight = 1;
    200197        gc.gridwidth = 1;
    201         gc.insets = new Insets(0,5,0,5);
     198        gc.insets = new Insets(0, 5, 0, 5);
    202199        gc.fill = GridBagConstraints.HORIZONTAL;
    203200        gc.anchor = GridBagConstraints.CENTER;
     
    220217        gc.weighty = 1.0;
    221218        gc.fill = GridBagConstraints.BOTH;
    222         pnl.add(new JPanel(),gc);
     219        pnl.add(new JPanel(), gc);
    223220        return pnl;
    224221    }
     
    226223    /**
    227224     * builds the panel with the tag editor
    228      *
     225     * 
    229226     * @return the panel with the tag editor
    230227     */
     
    237234        tagTable = new TagTable(tagEditorModel);
    238235        acCache.initFromJOSMDataset();
    239         TagCellEditor editor = ((TagCellEditor)tagTable.getColumnModel().getColumn(0).getCellEditor());
     236        TagCellEditor editor = ((TagCellEditor) tagTable.getColumnModel().getColumn(0).getCellEditor());
    240237        editor.setAutoCompletionCache(acCache);
    241238        editor.setAutoCompletionList(acList);
    242         editor = ((TagCellEditor)tagTable.getColumnModel().getColumn(1).getCellEditor());
     239        editor = ((TagCellEditor) tagTable.getColumnModel().getColumn(1).getCellEditor());
    243240        editor.setAutoCompletionCache(acCache);
    244241        editor.setAutoCompletionList(acList);
     
    250247        // getPreferredViewportSize() in JTable, but did not work.
    251248        //
    252         scrollPane.addComponentListener(
    253                 new ComponentAdapter() {
    254                     @Override public void componentResized(ComponentEvent e) {
    255                         super.componentResized(e);
    256                         Dimension d = scrollPane.getViewport().getExtentSize();
    257                         tagTable.adjustColumnWidth(d.width);
    258                     }
    259                 }
    260         );
     249        scrollPane.addComponentListener(new ComponentAdapter() {
     250            @Override
     251            public void componentResized(ComponentEvent e) {
     252                super.componentResized(e);
     253                Dimension d = scrollPane.getViewport().getExtentSize();
     254                tagTable.adjustColumnWidth(d.width);
     255            }
     256        });
    261257
    262258        GridBagConstraints gc = new GridBagConstraints();
    263259        gc.gridx = 0;
    264260        gc.gridy = 0;
    265         gc.gridheight  =1;
     261        gc.gridheight = 1;
    266262        gc.gridwidth = 3;
    267263        gc.fill = GridBagConstraints.HORIZONTAL;
     
    273269        gc.gridx = 0;
    274270        gc.gridy = 1;
    275         gc.gridheight  =1;
     271        gc.gridheight = 1;
    276272        gc.gridwidth = 1;
    277273        gc.fill = GridBagConstraints.VERTICAL;
     
    293289    /**
    294290     * builds the panel for the relation member editor
    295      *
     291     * 
    296292     * @return the panel for the relation member editor
    297293     */
     
    310306        // getPreferredViewportSize() in JTable, but did not work.
    311307        //
    312         scrollPane.addComponentListener(
    313                 new ComponentAdapter() {
    314                     @Override public void componentResized(ComponentEvent e) {
    315                         super.componentResized(e);
    316                         Dimension d = scrollPane.getViewport().getExtentSize();
    317                         memberTable.adjustColumnWidth(d.width);
    318                     }
    319                 }
    320         );
     308        scrollPane.addComponentListener(new ComponentAdapter() {
     309            @Override
     310            public void componentResized(ComponentEvent e) {
     311                super.componentResized(e);
     312                Dimension d = scrollPane.getViewport().getExtentSize();
     313                memberTable.adjustColumnWidth(d.width);
     314            }
     315        });
    321316
    322317        GridBagConstraints gc = new GridBagConstraints();
    323318        gc.gridx = 0;
    324319        gc.gridy = 0;
    325         gc.gridheight  =1;
     320        gc.gridheight = 1;
    326321        gc.gridwidth = 3;
    327322        gc.fill = GridBagConstraints.HORIZONTAL;
     
    333328        gc.gridx = 0;
    334329        gc.gridy = 1;
    335         gc.gridheight  =1;
     330        gc.gridheight = 1;
    336331        gc.gridwidth = 1;
    337332        gc.fill = GridBagConstraints.VERTICAL;
     
    354349        gc.gridx = 0;
    355350        gc.gridy = 0;
    356         gc.gridheight  =1;
     351        gc.gridheight = 1;
    357352        gc.gridwidth = 3;
    358353        gc.fill = GridBagConstraints.HORIZONTAL;
     
    364359        gc.gridx = 0;
    365360        gc.gridy = 1;
    366         gc.gridheight  =1;
     361        gc.gridheight = 1;
    367362        gc.gridwidth = 1;
    368363        gc.fill = GridBagConstraints.VERTICAL;
     
    379374        pnl2.add(buildSelectionTablePanel(), gc);
    380375
    381         final JSplitPane splitPane = new  JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
     376        final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
    382377        splitPane.setLeftComponent(pnl);
    383378        splitPane.setRightComponent(pnl2);
    384379        splitPane.setOneTouchExpandable(false);
    385         addWindowListener(
    386                 new WindowAdapter() {
    387                     @Override
    388                     public void windowOpened(WindowEvent e) {
    389                         // has to be called when the window is visible, otherwise
    390                         // no effect
    391                         splitPane.setDividerLocation(0.6);
    392                     }
    393                 }
    394         );
     380        addWindowListener(new WindowAdapter() {
     381            @Override
     382            public void windowOpened(WindowEvent e) {
     383                // has to be called when the window is visible, otherwise
     384                // no effect
     385                splitPane.setDividerLocation(0.6);
     386            }
     387        });
    395388
    396389        JPanel pnl3 = new JPanel();
     
    403396    /**
    404397     * builds the panel with the table displaying the currently selected primitives
    405      *
     398     * 
    406399     * @return
    407400     */
     
    409402        JPanel pnl = new JPanel();
    410403        pnl.setLayout(new BorderLayout());
    411         JTable tbl = new JTable(selectionTableModel,new SelectionTableColumnModel(memberTableModel));
     404        JTable tbl = new JTable(selectionTableModel, new SelectionTableColumnModel(memberTableModel));
    412405        tbl.setEnabled(false);
    413406        JScrollPane pane = new JScrollPane(tbl);
     
    417410
    418411    /**
    419      * builds the {@see JSplitPane} which divides the editor in an upper and a lower
    420      * half
    421      *
     412     * builds the {@see JSplitPane} which divides the editor in an upper and a lower half
     413     *
    422414     * @return the split panel
    423415     */
     
    427419        pane.setBottomComponent(buildMemberEditorPanel());
    428420        pane.setOneTouchExpandable(true);
    429         addWindowListener(
    430                 new WindowAdapter() {
    431                     @Override
    432                     public void windowOpened(WindowEvent e) {
    433                         // has to be called when the window is visible, otherwise
    434                         // no effect
    435                         pane.setDividerLocation(0.3);
    436                     }
    437                 }
    438         );
     421        addWindowListener(new WindowAdapter() {
     422            @Override
     423            public void windowOpened(WindowEvent e) {
     424                // has to be called when the window is visible, otherwise
     425                // no effect
     426                pane.setDividerLocation(0.3);
     427            }
     428        });
    439429        return pane;
    440430    }
     
    442432    /**
    443433     * build the panel with the buttons on the left
    444      *
     434     * 
    445435     * @return
    446436     */
     
    452442        gc.gridx = 0;
    453443        gc.gridy = 0;
    454         gc.gridheight  =1;
     444        gc.gridheight = 1;
    455445        gc.gridwidth = 1;
    456         gc.insets = new Insets(0,5,0,5);
     446        gc.insets = new Insets(0, 5, 0, 5);
    457447        gc.fill = GridBagConstraints.HORIZONTAL;
    458448        gc.anchor = GridBagConstraints.CENTER;
     
    473463        RemoveAction removeSelectedAction = new RemoveAction();
    474464        memberTable.getSelectionModel().addListSelectionListener(removeSelectedAction);
    475         pnl.add(new JButton(removeSelectedAction),gc);
     465        pnl.add(new JButton(removeSelectedAction), gc);
     466
     467        // ------
     468        gc.gridy = 3;
     469        SortAction sortAction = new SortAction();
     470        pnl.add(new JButton(sortAction), gc);
    476471
    477472        // ------
    478473        // just grab the remaining space
    479         gc.gridy = 3;
     474        gc.gridy = 4;
    480475        gc.weighty = 1.0;
    481476        gc.fill = GridBagConstraints.BOTH;
    482         pnl.add(new JPanel(),gc);
     477        pnl.add(new JPanel(), gc);
    483478        return pnl;
    484479    }
     
    486481    /**
    487482     * build the panel with the buttons for adding or removing the current selection
    488      *
     483     * 
    489484     * @return
    490485     */
     
    496491        gc.gridx = 0;
    497492        gc.gridy = 0;
    498         gc.gridheight  =1;
     493        gc.gridheight = 1;
    499494        gc.gridwidth = 1;
    500         gc.insets = new Insets(0,5,0,5);
     495        gc.insets = new Insets(0, 5, 0, 5);
    501496        gc.fill = GridBagConstraints.HORIZONTAL;
    502497        gc.anchor = GridBagConstraints.CENTER;
     
    538533        gc.weighty = 1.0;
    539534        gc.fill = GridBagConstraints.BOTH;
    540         pnl.add(new JPanel(),gc);
     535        pnl.add(new JPanel(), gc);
    541536
    542537        return pnl;
     
    552547        buttonPanel.add(new JLabel(tr("Role:")));
    553548        tfRole = new JTextField(10);
    554         tfRole.addFocusListener(
    555                 new FocusAdapter() {
    556                     @Override
    557                     public void focusGained(FocusEvent e) {
    558                         tfRole.selectAll();
    559                     }
    560                 }
    561         );
     549        tfRole.addFocusListener(new FocusAdapter() {
     550            @Override
     551            public void focusGained(FocusEvent e) {
     552                tfRole.selectAll();
     553            }
     554        });
    562555        buttonPanel.add(tfRole);
    563556        SetRoleAction setRoleAction = new SetRoleAction();
     
    566559        tfRole.getDocument().addDocumentListener(setRoleAction);
    567560
    568         //--- copy relation action
     561        // --- copy relation action
    569562        buttonPanel.add(new SideButton(new DuplicateRelationAction()));
    570563
     
    580573     */
    581574    protected void applyChanges() {
    582         if (getRelation()== null) {
     575        if (getRelation() == null) {
    583576            // If the user wanted to create a new relation, but hasn't added any members or
    584577            // tags, don't add an empty relation
    585             if(memberTableModel.getRowCount() == 0 && tagEditorModel.getKeys().isEmpty())
     578            if (memberTableModel.getRowCount() == 0 && tagEditorModel.getKeys().isEmpty())
    586579                return;
    587580            Relation newRelation = new Relation();
     
    590583            Main.main.undoRedo.add(new AddCommand(newRelation));
    591584            DataSet.fireSelectionChanged(getLayer().data.getSelected());
    592         } else if (! memberTableModel.hasSameMembersAs(getRelation()) || tagEditorModel.isDirty()) {
     585        } else if (!memberTableModel.hasSameMembersAs(getRelation()) || tagEditorModel.isDirty()) {
    593586            Relation editedRelation = new Relation(getRelation());
    594587            tagEditorModel.applyToPrimitive(editedRelation);
     
    597590                Conflict<Relation> conflict = new Conflict<Relation>(getRelation(), editedRelation);
    598591                getLayer().getConflicts().add(conflict);
    599                 JOptionPane op = new JOptionPane(
    600                         tr("<html>The relation has changed outside of the editor.<br>"
    601                                 + "Your edit can't be applied directly, a conflict has been created instead.</html>"
    602                         ),
    603                         JOptionPane.WARNING_MESSAGE
    604                 );
     592                JOptionPane op = new JOptionPane(tr("<html>The relation has changed outside of the editor.<br>"
     593                        + "Your edit can't be applied directly, a conflict has been created instead.</html>"),
     594                        JOptionPane.WARNING_MESSAGE);
    605595                JDialog dialog = op.createDialog(this, tr("Conflict created"));
    606596                dialog.setAlwaysOnTop(true);
     
    626616    /**
    627617     * Asynchronously download the members of the currently edited relation
    628      *
     618     * 
    629619     */
    630620    private void downloadRelationMembers() {
     
    650640    class AddSelectedAtStartAction extends AbstractAction implements TableModelListener {
    651641        public AddSelectedAtStartAction() {
    652             putValue(SHORT_DESCRIPTION,  tr("Add all primitives selected in the current dataset before the first member"));
     642            putValue(SHORT_DESCRIPTION,
     643                    tr("Add all primitives selected in the current dataset before the first member"));
    653644            putValue(SMALL_ICON, ImageProvider.get("dialogs/conflict", "copystartright"));
    654             //putValue(NAME, tr("Add Selected"));
     645            // putValue(NAME, tr("Add Selected"));
    655646            refreshEnabled();
    656647        }
    657648
    658649        protected void refreshEnabled() {
    659             setEnabled(selectionTableModel.getRowCount() >  0);
     650            setEnabled(selectionTableModel.getRowCount() > 0);
    660651        }
    661652
     
    671662    class AddSelectedAtEndAction extends AbstractAction implements TableModelListener {
    672663        public AddSelectedAtEndAction() {
    673             putValue(SHORT_DESCRIPTION,  tr("Add all primitives selected in the current dataset after the last member"));
     664            putValue(SHORT_DESCRIPTION, tr("Add all primitives selected in the current dataset after the last member"));
    674665            putValue(SMALL_ICON, ImageProvider.get("dialogs/conflict", "copyendright"));
    675             //putValue(NAME, tr("Add Selected"));
     666            // putValue(NAME, tr("Add Selected"));
    676667            refreshEnabled();
    677668        }
    678669
    679670        protected void refreshEnabled() {
    680             setEnabled(selectionTableModel.getRowCount() >  0);
     671            setEnabled(selectionTableModel.getRowCount() > 0);
    681672        }
    682673
     
    692683    class AddSelectedBeforeSelection extends AbstractAction implements TableModelListener, ListSelectionListener {
    693684        public AddSelectedBeforeSelection() {
    694             putValue(SHORT_DESCRIPTION,  tr("Add all primitives selected in the current dataset before the first selected member"));
     685            putValue(SHORT_DESCRIPTION,
     686                    tr("Add all primitives selected in the current dataset before the first selected member"));
    695687            putValue(SMALL_ICON, ImageProvider.get("dialogs/conflict", "copybeforecurrentright"));
    696             //putValue(NAME, tr("Add Selected"));
     688            // putValue(NAME, tr("Add Selected"));
    697689            refreshEnabled();
    698690        }
    699691
    700692        protected void refreshEnabled() {
    701             setEnabled(selectionTableModel.getRowCount() >  0
     693            setEnabled(selectionTableModel.getRowCount() > 0
    702694                    && memberTableModel.getSelectionModel().getMinSelectionIndex() >= 0);
    703695        }
    704696
    705697        public void actionPerformed(ActionEvent e) {
    706             memberTableModel.addMembersBeforeIdx(selectionTableModel.getSelection(), memberTableModel.getSelectionModel().getMinSelectionIndex());
     698            memberTableModel.addMembersBeforeIdx(selectionTableModel.getSelection(), memberTableModel
     699                    .getSelectionModel().getMinSelectionIndex());
    707700        }
    708701
     
    718711    class AddSelectedAfterSelection extends AbstractAction implements TableModelListener, ListSelectionListener {
    719712        public AddSelectedAfterSelection() {
    720             putValue(SHORT_DESCRIPTION,  tr("Add all primitives selected in the current dataset after the last selected member"));
     713            putValue(SHORT_DESCRIPTION,
     714                    tr("Add all primitives selected in the current dataset after the last selected member"));
    721715            putValue(SMALL_ICON, ImageProvider.get("dialogs/conflict", "copyaftercurrentright"));
    722             //putValue(NAME, tr("Add Selected"));
     716            // putValue(NAME, tr("Add Selected"));
    723717            refreshEnabled();
    724718        }
    725719
    726720        protected void refreshEnabled() {
    727             setEnabled(selectionTableModel.getRowCount() >  0
     721            setEnabled(selectionTableModel.getRowCount() > 0
    728722                    && memberTableModel.getSelectionModel().getMinSelectionIndex() >= 0);
    729723        }
    730724
    731725        public void actionPerformed(ActionEvent e) {
    732             memberTableModel.addMembersAfterIdx(selectionTableModel.getSelection(), memberTableModel.getSelectionModel().getMaxSelectionIndex());
     726            memberTableModel.addMembersAfterIdx(selectionTableModel.getSelection(), memberTableModel
     727                    .getSelectionModel().getMaxSelectionIndex());
    733728        }
    734729
     
    744739    class RemoveSelectedAction extends AbstractAction implements TableModelListener {
    745740        public RemoveSelectedAction() {
    746             putValue(SHORT_DESCRIPTION,  tr("Remove all currently selected objects from relation"));
     741            putValue(SHORT_DESCRIPTION, tr("Remove all currently selected objects from relation"));
    747742            putValue(SMALL_ICON, ImageProvider.get("dialogs", "removeselected"));
    748743            // putValue(NAME, tr("Remove Selected"));
    749             Shortcut.registerShortcut("relationeditor:removeselected",
    750                     tr("Relation Editor: Remove Selected"),
    751                     KeyEvent.VK_S,
    752                     Shortcut.GROUP_MNEMONIC);
     744            Shortcut.registerShortcut("relationeditor:removeselected", tr("Relation Editor: Remove Selected"),
     745                    KeyEvent.VK_S, Shortcut.GROUP_MNEMONIC);
    753746
    754747            DataSet ds = getLayer().data;
     
    761754
    762755        public void tableChanged(TableModelEvent e) {
    763             setEnabled(selectionTableModel.getRowCount() >0);
     756            setEnabled(selectionTableModel.getRowCount() > 0);
     757        }
     758    }
     759
     760    class SortAction extends AbstractAction {
     761        public SortAction() {
     762            putValue(SHORT_DESCRIPTION, tr("Sort the relation members"));
     763            putValue(SMALL_ICON, ImageProvider.get("dialogs", "sort"));
     764            // putValue(NAME, tr("Sort"));
     765            Shortcut.registerShortcut("relationeditor:sort", tr("Relation Editor: Sort"), KeyEvent.VK_T,
     766                    Shortcut.GROUP_MNEMONIC);
     767            setEnabled(false);
     768        }
     769
     770        public void actionPerformed(ActionEvent e) {
     771            memberTableModel.sort();
    764772        }
    765773    }
     
    767775    class MoveUpAction extends AbstractAction implements ListSelectionListener {
    768776        public MoveUpAction() {
    769             putValue(SHORT_DESCRIPTION,  tr("Move the currently selected members up"));
     777            putValue(SHORT_DESCRIPTION, tr("Move the currently selected members up"));
    770778            putValue(SMALL_ICON, ImageProvider.get("dialogs", "moveup"));
    771             //putValue(NAME, tr("Move Up"));
    772             Shortcut.registerShortcut("relationeditor:moveup",
    773                     tr("Relation Editor: Move Up"),
    774                     KeyEvent.VK_N,
     779            // putValue(NAME, tr("Move Up"));
     780            Shortcut.registerShortcut("relationeditor:moveup", tr("Relation Editor: Move Up"), KeyEvent.VK_N,
    775781                    Shortcut.GROUP_MNEMONIC);
    776782            setEnabled(false);
     
    788794    class MoveDownAction extends AbstractAction implements ListSelectionListener {
    789795        public MoveDownAction() {
    790             putValue(SHORT_DESCRIPTION,  tr("Move the currently selected members down"));
     796            putValue(SHORT_DESCRIPTION, tr("Move the currently selected members down"));
    791797            putValue(SMALL_ICON, ImageProvider.get("dialogs", "movedown"));
    792             //putValue(NAME, tr("Move Down"));
    793             Shortcut.registerShortcut("relationeditor:moveup",
    794                     tr("Relation Editor: Move Down"),
    795                     KeyEvent.VK_J,
     798            // putValue(NAME, tr("Move Down"));
     799            Shortcut.registerShortcut("relationeditor:moveup", tr("Relation Editor: Move Down"), KeyEvent.VK_J,
    796800                    Shortcut.GROUP_MNEMONIC);
    797801            setEnabled(false);
     
    809813    class RemoveAction extends AbstractAction implements ListSelectionListener {
    810814        public RemoveAction() {
    811             putValue(SHORT_DESCRIPTION,  tr("Remove the member in the current table row from this relation"));
     815            putValue(SHORT_DESCRIPTION, tr("Remove the member in the current table row from this relation"));
    812816            putValue(SMALL_ICON, ImageProvider.get("dialogs", "remove"));
    813             //putValue(NAME, tr("Remove"));
    814             Shortcut.registerShortcut("relationeditor:remove",
    815                     tr("Relation Editor: Remove"),
    816                     KeyEvent.VK_J,
     817            // putValue(NAME, tr("Remove"));
     818            Shortcut.registerShortcut("relationeditor:remove", tr("Relation Editor: Remove"), KeyEvent.VK_J,
    817819                    Shortcut.GROUP_MNEMONIC);
    818820            setEnabled(false);
     
    830832    class OKAction extends AbstractAction {
    831833        public OKAction() {
    832             putValue(SHORT_DESCRIPTION,  tr("Apply the updates and close the dialog"));
     834            putValue(SHORT_DESCRIPTION, tr("Apply the updates and close the dialog"));
    833835            putValue(SMALL_ICON, ImageProvider.get("ok"));
    834836            putValue(NAME, tr("Apply"));
     
    844846    class CancelAction extends AbstractAction {
    845847        public CancelAction() {
    846             putValue(SHORT_DESCRIPTION,  tr("Cancel the updates and close the dialog"));
     848            putValue(SHORT_DESCRIPTION, tr("Cancel the updates and close the dialog"));
    847849            putValue(SMALL_ICON, ImageProvider.get("cancel"));
    848850            putValue(NAME, tr("Cancel"));
     
    861863    class AddTagAction extends AbstractAction {
    862864        public AddTagAction() {
    863             putValue(SHORT_DESCRIPTION,  tr("Add an empty tag"));
    864             putValue(SMALL_ICON, ImageProvider.get("dialogs","add"));
    865             //putValue(NAME, tr("Cancel"));
     865            putValue(SHORT_DESCRIPTION, tr("Add an empty tag"));
     866            putValue(SMALL_ICON, ImageProvider.get("dialogs", "add"));
     867            // putValue(NAME, tr("Cancel"));
    866868            setEnabled(true);
    867869        }
     870
    868871        public void actionPerformed(ActionEvent e) {
    869872            tagEditorModel.appendNewTag();
     
    871874    }
    872875
    873     class DeleteTagAction extends AbstractAction implements ListSelectionListener{
     876    class DeleteTagAction extends AbstractAction implements ListSelectionListener {
    874877        public DeleteTagAction() {
    875             putValue(SHORT_DESCRIPTION,  tr("Delete the currently selected tags"));
    876             putValue(SMALL_ICON, ImageProvider.get("dialogs","delete"));
    877             //putValue(NAME, tr("Cancel"));
     878            putValue(SHORT_DESCRIPTION, tr("Delete the currently selected tags"));
     879            putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
     880            // putValue(NAME, tr("Cancel"));
    878881            refreshEnabled();
    879882        }
     
    917920                    // should not happen
    918921                    //
    919                     throw new IllegalStateException("unexpected selected clolumn: getSelectedColumn() is " + tagTable.getSelectedColumn());
     922                    throw new IllegalStateException("unexpected selected clolumn: getSelectedColumn() is "
     923                            + tagTable.getSelectedColumn());
    920924            } else if (tagTable.getSelectedColumnCount() == 2) {
    921925                deleteTags();
     
    927931
    928932        protected void refreshEnabled() {
    929             setEnabled(tagTable.getSelectedRowCount()>0 || tagTable.getSelectedColumnCount() > 0);
     933            setEnabled(tagTable.getSelectedRowCount() > 0 || tagTable.getSelectedColumnCount() > 0);
    930934        }
    931935
     
    937941    class DownlaodAction extends AbstractAction {
    938942        public DownlaodAction() {
    939             putValue(SHORT_DESCRIPTION,   tr("Download all incomplete ways and nodes in relation"));
    940             putValue(SMALL_ICON, ImageProvider.get("dialogs","downloadincomplete"));
     943            putValue(SHORT_DESCRIPTION, tr("Download all incomplete ways and nodes in relation"));
     944            putValue(SMALL_ICON, ImageProvider.get("dialogs", "downloadincomplete"));
    941945            putValue(NAME, tr("Download Members"));
    942             Shortcut.registerShortcut("relationeditor:downloadincomplete",
    943                     tr("Relation Editor: Download Members"),
    944                     KeyEvent.VK_K,
    945                     Shortcut.GROUP_MNEMONIC);
     946            Shortcut.registerShortcut("relationeditor:downloadincomplete", tr("Relation Editor: Download Members"),
     947                    KeyEvent.VK_K, Shortcut.GROUP_MNEMONIC);
    946948            setEnabled(true);
    947949        }
     950
    948951        public void actionPerformed(ActionEvent e) {
    949952            downloadRelationMembers();
     
    951954    }
    952955
    953     class SetRoleAction extends AbstractAction implements ListSelectionListener, DocumentListener{
     956    class SetRoleAction extends AbstractAction implements ListSelectionListener, DocumentListener {
    954957        public SetRoleAction() {
    955             putValue(SHORT_DESCRIPTION,   tr("Sets a role for the selected members"));
     958            putValue(SHORT_DESCRIPTION, tr("Sets a role for the selected members"));
    956959            // FIXME: find better icon
    957960            putValue(SMALL_ICON, ImageProvider.get("ok"));
     
    987990    /**
    988991     * Creates a new relation with a copy of the current editor state
    989      *
     992     * 
    990993     */
    991994    class DuplicateRelationAction extends AbstractAction {
    992995        public DuplicateRelationAction() {
    993             putValue(SHORT_DESCRIPTION,   tr("Create a copy of this relation and open it in another editor window"));
     996            putValue(SHORT_DESCRIPTION, tr("Create a copy of this relation and open it in another editor window"));
    994997            // FIXME provide an icon
    995998            putValue(SMALL_ICON, ImageProvider.get("duplicate"));
     
    9971000            setEnabled(true);
    9981001        }
     1002
    9991003        public void actionPerformed(ActionEvent e) {
    10001004            Relation copy = new Relation();
     
    10101014    /**
    10111015     * Action for editing the currently selected relation
    1012      *
    1013      *
     1016     * 
     1017     * 
    10141018     */
    10151019    class EditAction extends AbstractAction implements ListSelectionListener {
     
    10221026
    10231027        protected void refreshEnabled() {
    1024             setEnabled(memberTable.getSelectedRowCount() == 1 && memberTableModel.isEditableRelation(memberTable.getSelectedRow()));
    1025         }
    1026 
    1027         public void run()  {
     1028            setEnabled(memberTable.getSelectedRowCount() == 1
     1029                    && memberTableModel.isEditableRelation(memberTable.getSelectedRow()));
     1030        }
     1031
     1032        public void run() {
    10281033            int idx = memberTable.getSelectedRow();
    1029             if (idx < 0) return;
     1034            if (idx < 0)
     1035                return;
    10301036            OsmPrimitive primitive = memberTableModel.getReferredPrimitive(idx);
    1031             if (! (primitive instanceof Relation)) return;
    1032             Relation r= (Relation)primitive;
    1033             if (r.incomplete) return;
     1037            if (!(primitive instanceof Relation))
     1038                return;
     1039            Relation r = (Relation) primitive;
     1040            if (r.incomplete)
     1041                return;
    10341042            RelationEditor editor = RelationEditor.getEditor(getLayer(), r, null);
    10351043            editor.setVisible(true);
     
    10601068            ArrayList<OsmPrimitive> sel;
    10611069            int cnt = memberTable.getSelectedRowCount();
    1062             if (cnt <=0) return;
     1070            if (cnt <= 0)
     1071                return;
    10631072            sel = new ArrayList<OsmPrimitive>(cnt);
    10641073            for (int i : memberTable.getSelectedRows()) {
     
    10711080    /**
    10721081     * The asynchronous task for downloading relation members.
    1073      *
    1074      *
     1082     * 
     1083     * 
    10751084     */
    10761085    class DownloadTask extends PleaseWaitRunnable {
     
    10801089
    10811090        public DownloadTask(Dialog parent) {
    1082             super(tr("Download relation members"), new PleaseWaitProgressMonitor(parent), false /* don't ignore exception */);
    1083         }
     1091            super(tr("Download relation members"), new PleaseWaitProgressMonitor(parent), false /*
     1092             * don't
     1093             * ignore
     1094             * exception
     1095             */);
     1096        }
     1097
    10841098        @Override
    10851099        protected void cancel() {
     
    10931107                msg = lastException.toString();
    10941108            }
    1095             JOptionPane.showMessageDialog(
    1096                     null,
    1097                     msg,
    1098                     tr("Error"),
    1099                     JOptionPane.ERROR_MESSAGE
    1100             );
     1109            JOptionPane.showMessageDialog(null, msg, tr("Error"), JOptionPane.ERROR_MESSAGE);
    11011110        }
    11021111
    11031112        @Override
    11041113        protected void finish() {
    1105             if (cancelled) return;
     1114            if (cancelled)
     1115                return;
    11061116            memberTableModel.updateMemberReferences(getLayer().data);
    11071117            if (lastException != null) {
     
    11101120
    11111121            if (conflictsCount > 0) {
    1112                 JOptionPane op = new JOptionPane(
    1113                         tr("There were {0} conflicts during import.",
    1114                                 conflictsCount),
    1115                                 JOptionPane.WARNING_MESSAGE
    1116                 );
     1122                JOptionPane op = new JOptionPane(tr("There were {0} conflicts during import.", conflictsCount),
     1123                        JOptionPane.WARNING_MESSAGE);
    11171124                JDialog dialog = op.createDialog(GenericRelationEditor.this, tr("Conflicts in data"));
    11181125                dialog.setAlwaysOnTop(true);
     
    11271134            try {
    11281135                progressMonitor.indeterminateSubTask("");
    1129                 OsmServerObjectReader reader = new OsmServerObjectReader(getRelation().id, OsmPrimitiveType.RELATION, true);
    1130                 DataSet dataSet = reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
     1136                OsmServerObjectReader reader = new OsmServerObjectReader(getRelation().id, OsmPrimitiveType.RELATION,
     1137                        true);
     1138                DataSet dataSet = reader.parseOsm(progressMonitor
     1139                        .createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
    11311140                if (dataSet != null) {
    11321141                    final MergeVisitor visitor = new MergeVisitor(getLayer().data, dataSet);
     
    11371146                        getLayer().data.dataSources.add(src);
    11381147                    }
    1139                     // FIXME: this is necessary because there are  dialogs listening
     1148                    // FIXME: this is necessary because there are dialogs listening
    11401149                    // for DataChangeEvents which manipulate Swing components on this
    11411150                    // thread.
    11421151                    //
    1143                     SwingUtilities.invokeLater(
    1144                             new Runnable() {
    1145                                 public void run() {
    1146                                     getLayer().fireDataChange();
    1147                                 }
    1148                             }
    1149                     );
     1152                    SwingUtilities.invokeLater(new Runnable() {
     1153                        public void run() {
     1154                            getLayer().fireDataChange();
     1155                        }
     1156                    });
    11501157                    if (!visitor.getConflicts().isEmpty()) {
    11511158                        getLayer().getConflicts().add(visitor.getConflicts());
     
    11531160                    }
    11541161                }
    1155             } catch(Exception e) {
     1162            } catch (Exception e) {
    11561163                if (cancelled) {
    1157                     System.out.println(tr("Warning: ignoring exception because task is cancelled. Exception: {0}", e.toString()));
     1164                    System.out.println(tr("Warning: ignoring exception because task is cancelled. Exception: {0}", e
     1165                            .toString()));
    11581166                    return;
    11591167                }
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableCellRenderer.java

    r1814 r1822  
    66import java.util.ArrayList;
    77import java.util.Collections;
    8 import java.util.HashMap;
    98
    10 import javax.swing.ImageIcon;
    119import javax.swing.JLabel;
    1210import javax.swing.JTable;
     
    1412
    1513import org.openstreetmap.josm.data.osm.OsmPrimitive;
    16 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    17 import org.openstreetmap.josm.gui.PrimitiveNameFormatter;
    18 import org.openstreetmap.josm.tools.ImageProvider;
    1914
    2015/**
     
    2217 *
    2318 */
    24 public  class MemberTableCellRenderer extends JLabel implements TableCellRenderer {
    25     static private final PrimitiveNameFormatter NAME_FORMATTER = new PrimitiveNameFormatter();
     19public abstract class MemberTableCellRenderer extends JLabel implements TableCellRenderer {
     20    public final static Color BGCOLOR_SELECTED = new Color(143, 170, 255);
     21    public final static Color BGCOLOR_EMPTY_ROW = new Color(234, 234, 234);
    2622
    27     public final static Color BGCOLOR_SELECTED = new Color(143,170,255);
    28     public final static Color BGCOLOR_EMPTY_ROW = new Color(234,234,234);
    29 
    30     public final static Color BGCOLOR_NOT_IN_OPPOSITE = new Color(255,197,197);
    31     public final static Color BGCOLOR_DOUBLE_ENTRY = new Color(255,234,213);
    32 
    33 
    34     private HashMap<OsmPrimitiveType, ImageIcon>  icons;
    35 
    36     /**
    37      * Load the image icon for an OSM primitive of type node
    38      *
    39      * @return the icon; null, if not found
    40      */
    41     protected void loadIcons() {
    42         icons = new HashMap<OsmPrimitiveType, ImageIcon>();
    43         icons.put(OsmPrimitiveType.NODE,ImageProvider.get("data", "node"));
    44         icons.put(OsmPrimitiveType.WAY, ImageProvider.get("data", "way"));
    45         icons.put(OsmPrimitiveType.RELATION, ImageProvider.get("data", "relation"));
    46     }
     23    public final static Color BGCOLOR_NOT_IN_OPPOSITE = new Color(255, 197, 197);
     24    public final static Color BGCOLOR_DOUBLE_ENTRY = new Color(255, 234, 213);
    4725
    4826    /**
     
    5230        setIcon(null);
    5331        setOpaque(true);
    54         loadIcons();
    5532    }
    5633
     
    5835        StringBuilder sb = new StringBuilder();
    5936        sb.append("<html>");
    60         sb.append("<strong>id</strong>=")
    61         .append(primitive.id)
    62         .append("<br>");
     37        sb.append("<strong>id</strong>=").append(primitive.id).append("<br>");
    6338        ArrayList<String> keyList = new ArrayList<String>(primitive.keySet());
    6439        Collections.sort(keyList);
     
    6843            }
    6944            String key = keyList.get(i);
    70             sb.append("<strong>")
    71             .append(key)
    72             .append("</strong>")
    73             .append("=");
     45            sb.append("<strong>").append(key).append("</strong>").append("=");
    7446            String value = primitive.get(key);
    75             while(value.length() != 0) {
    76                 sb.append(value.substring(0,Math.min(50, value.length())));
     47            while (value.length() != 0) {
     48                sb.append(value.substring(0, Math.min(50, value.length())));
    7749                if (value.length() > 50) {
    7850                    sb.append("<br>");
     
    9870    }
    9971
    100     protected void renderBackground( MemberTableModel model, OsmPrimitive primitive, boolean isSelected) {
     72    protected void renderBackground(MemberTableModel model, OsmPrimitive primitive, boolean isSelected) {
    10173        Color bgc = Color.WHITE;
    10274        if (isSelected) {
     
    11385    }
    11486
    115     protected void renderPrimitive(OsmPrimitive primitive) {
    116         setIcon(icons.get(OsmPrimitiveType.from(primitive)));
    117         setText(NAME_FORMATTER.getName(primitive));
    118         setToolTipText(buildToolTipText(primitive));
    119     }
    120 
    121     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
    122             int row, int column) {
    123 
    124         reset();
    125 
    126         renderForeground(isSelected);
    127         switch(column) {
    128         case 0:
    129             String role = (String)value;
    130             renderBackground(getModel(table), null, isSelected);
    131             setText(role);
    132             break;
    133         case 1:
    134             OsmPrimitive primitive = (OsmPrimitive)value;
    135             renderBackground(getModel(table), primitive, isSelected);
    136             renderPrimitive(primitive);
    137             break;
    138         case 2:
    139             setText("");
    140             renderBackground(getModel(table), null, isSelected);
    141             break;
    142         default:
    143             // should not happen
    144         }
    145         return this;
    146     }
     87    abstract public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
     88            boolean hasFocus, int row, int column);
    14789
    14890    /**
    14991     * replies the model
    150      * @param table  the table
     92     * @param table the table
    15193     * @return the table model
    15294     */
    15395    protected MemberTableModel getModel(JTable table) {
    154         return (MemberTableModel)table.getModel();
     96        return (MemberTableModel) table.getModel();
    15597    }
    15698}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableColumnModel.java

    r1814 r1822  
    77import javax.swing.table.TableColumn;
    88
    9 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
    10 
    11 public class MemberTableColumnModel extends DefaultTableColumnModel{
     9public class MemberTableColumnModel extends DefaultTableColumnModel {
    1210
    1311    public MemberTableColumnModel() {
    1412        TableColumn col = null;
    15         MemberTableCellRenderer renderer = new MemberTableCellRenderer();
    1613
    1714        // column 0 - the member role
     
    1916        col.setHeaderValue(tr("Role"));
    2017        col.setResizable(true);
    21         col.setCellRenderer(renderer);
     18        col.setCellRenderer(new MemberTableRoleCellRenderer());
    2219
    2320        addColumn(col);
     
    2724        col.setHeaderValue(tr("Refers to"));
    2825        col.setResizable(true);
    29         col.setCellRenderer(new OsmPrimitivRenderer());
    30         col.setCellRenderer(renderer);
     26        // col.setCellRenderer(new OsmPrimitivRenderer());
     27        col.setCellRenderer(new MemberTableMemberCellRenderer());
    3128        addColumn(col);
    3229
     
    3532        col.setHeaderValue(tr("Linked"));
    3633        col.setResizable(true);
    37         col.setCellRenderer(renderer);
     34        col.setCellRenderer(new MemberTableLinkedCellRenderer());
    3835        addColumn(col);
    3936    }
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java

    r1806 r1822  
    77import java.util.Collections;
    88import java.util.Iterator;
     9import java.util.LinkedList;
    910import java.util.List;
     11import java.util.Vector;
    1012import java.util.concurrent.CopyOnWriteArrayList;
    1113
     
    1517
    1618import org.openstreetmap.josm.data.osm.DataSet;
     19import org.openstreetmap.josm.data.osm.Node;
    1720import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1821import org.openstreetmap.josm.data.osm.Relation;
    1922import org.openstreetmap.josm.data.osm.RelationMember;
    20 
    21 public class MemberTableModel extends AbstractTableModel{
    22 
    23     private Relation relation;
     23import org.openstreetmap.josm.data.osm.Way;
     24
     25public class MemberTableModel extends AbstractTableModel {
     26
    2427    private ArrayList<RelationMember> members;
    25     private ArrayList<String> memberLinkingInfo;
    2628    private DefaultListSelectionModel listSelectionModel;
    2729    private CopyOnWriteArrayList<IMemberModelListener> listeners;
     
    3032     * constructor
    3133     */
    32     public MemberTableModel(){
     34    public MemberTableModel() {
    3335        members = new ArrayList<RelationMember>();
    34         memberLinkingInfo = new ArrayList<String>();
    3536        listeners = new CopyOnWriteArrayList<IMemberModelListener>();
    3637    }
    3738
    3839    public void addMemberModelListener(IMemberModelListener listener) {
    39         synchronized(listeners) {
    40             if (listener != null && ! listeners.contains(listener)) {
     40        synchronized (listeners) {
     41            if (listener != null && !listeners.contains(listener)) {
    4142                listeners.add(listener);
    4243            }
     
    4546
    4647    public void removeMemberModelListener(IMemberModelListener listener) {
    47         synchronized(listeners) {
     48        synchronized (listeners) {
    4849            if (listener != null && listeners.contains(listener)) {
    4950                listeners.remove(listener);
     
    5354
    5455    protected void fireMakeMemberVisible(int index) {
    55         synchronized(listeners) {
    56             for (IMemberModelListener listener: listeners) {
     56        synchronized (listeners) {
     57            for (IMemberModelListener listener : listeners) {
    5758                listener.makeMemberVisible(index);
    5859            }
     
    6566            members.addAll(relation.members);
    6667        }
    67         this.relation = relation;
    6868        fireTableDataChanged();
    6969    }
     
    7878
    7979    public Object getValueAt(int rowIndex, int columnIndex) {
    80         switch(columnIndex) {
    81         case 0: return members.get(rowIndex).role;
    82         case 1: return members.get(rowIndex).member;
    83         case 2: return "";
     80        switch (columnIndex) {
     81        case 0:
     82            return members.get(rowIndex).role;
     83        case 1:
     84            return members.get(rowIndex).member;
     85        case 2:
     86            return linked(rowIndex);
    8487        }
    8588        // should not happen
     
    98101    }
    99102
    100 
    101103    public OsmPrimitive getReferredPrimitive(int idx) {
    102104        return members.get(idx).member;
     
    104106
    105107    public void moveUp(int[] selectedRows) {
    106         if (! canMoveUp(selectedRows))
     108        if (!canMoveUp(selectedRows))
    107109            return;
    108110
    109111        for (int row : selectedRows) {
    110112            RelationMember member1 = members.get(row);
    111             RelationMember member2 = members.get(row-1);
     113            RelationMember member2 = members.get(row - 1);
    112114            members.set(row, member2);
    113             members.set(row-1, member1);
     115            members.set(row - 1, member1);
    114116        }
    115117        fireTableDataChanged();
     
    120122            listSelectionModel.addSelectionInterval(row, row);
    121123        }
    122         fireMakeMemberVisible(selectedRows[0] -1);
     124        fireMakeMemberVisible(selectedRows[0] - 1);
    123125    }
    124126
    125127    public void moveDown(int[] selectedRows) {
    126         if (! canMoveDown(selectedRows))
    127             return;
    128 
    129         for (int i=selectedRows.length-1; i >=0; i--) {
     128        if (!canMoveDown(selectedRows))
     129            return;
     130
     131        for (int i = selectedRows.length - 1; i >= 0; i--) {
    130132            int row = selectedRows[i];
    131133            RelationMember member1 = members.get(row);
    132             RelationMember member2 = members.get(row+1);
     134            RelationMember member2 = members.get(row + 1);
    133135            members.set(row, member2);
    134             members.set(row+1, member1);
     136            members.set(row + 1, member1);
    135137        }
    136138        fireTableDataChanged();
     
    145147
    146148    public void remove(int[] selectedRows) {
    147         if (! canRemove(selectedRows))
     149        if (!canRemove(selectedRows))
    148150            return;
    149151        int offset = 0;
     
    156158    }
    157159
    158     public boolean canMoveUp(int [] rows) {
    159         if (rows == null || rows.length == 0) return false;
     160    public boolean canMoveUp(int[] rows) {
     161        if (rows == null || rows.length == 0)
     162            return false;
    160163        Arrays.sort(rows);
    161164        return rows[0] > 0 && members.size() > 0;
    162165    }
    163166
    164     public boolean canMoveDown(int [] rows) {
    165         if (rows == null || rows.length == 0) return false;
     167    public boolean canMoveDown(int[] rows) {
     168        if (rows == null || rows.length == 0)
     169            return false;
    166170        Arrays.sort(rows);
    167         return members.size() >0 && rows[rows.length-1] < members.size() - 1;
    168     }
    169 
    170     public boolean canRemove(int [] rows) {
    171         if (rows == null || rows.length == 0) return false;
     171        return members.size() > 0 && rows[rows.length - 1] < members.size() - 1;
     172    }
     173
     174    public boolean canRemove(int[] rows) {
     175        if (rows == null || rows.length == 0)
     176            return false;
    172177        return true;
    173178    }
     
    195200
    196201    public void removeMembersReferringTo(List<? extends OsmPrimitive> primitives) {
    197         if (primitives == null) return;
     202        if (primitives == null)
     203            return;
    198204        Iterator<RelationMember> it = members.iterator();
    199         while(it.hasNext()) {
     205        while (it.hasNext()) {
    200206            RelationMember member = it.next();
    201207            if (primitives.contains(member.member)) {
     
    212218
    213219    public boolean hasSameMembersAs(Relation relation) {
    214         if (relation == null) return false;
    215         if (relation.members.size() != members.size()) return false;
    216         for (int i=0; i<relation.members.size();i++) {
    217             if (! relation.members.get(i).equals(members.get(i)))
     220        if (relation == null)
     221            return false;
     222        if (relation.members.size() != members.size())
     223            return false;
     224        for (int i = 0; i < relation.members.size(); i++) {
     225            if (!relation.members.get(i).equals(members.get(i)))
    218226                return false;
    219227        }
     
    222230
    223231    public boolean hasIncompleteMembers() {
    224         for (RelationMember member: members) {
     232        for (RelationMember member : members) {
    225233            if (member.member.incomplete)
    226234                return true;
     
    231239    protected List<Integer> getSelectedIndices() {
    232240        ArrayList<Integer> selectedIndices = new ArrayList<Integer>();
    233         for (int i=0; i< members.size();i++) {
     241        for (int i = 0; i < members.size(); i++) {
    234242            if (getSelectionModel().isSelectedIndex(i)) {
    235243                selectedIndices.add(i);
     
    240248
    241249    public void addMembersAtBeginning(List<? extends OsmPrimitive> primitives) {
    242         if (primitives == null) return;
    243         for (OsmPrimitive primitive: primitives) {
    244             RelationMember member = new RelationMember(null,primitive);
    245             members.add(0,member);
     250        if (primitives == null)
     251            return;
     252        for (OsmPrimitive primitive : primitives) {
     253            RelationMember member = new RelationMember(null, primitive);
     254            members.add(0, member);
    246255        }
    247256        fireTableDataChanged();
    248257        getSelectionModel().clearSelection();
    249         for (int i=0; i<primitives.size();i++) {
    250             getSelectionModel().addSelectionInterval(i,i);
     258        for (int i = 0; i < primitives.size(); i++) {
     259            getSelectionModel().addSelectionInterval(i, i);
    251260        }
    252261        fireMakeMemberVisible(0);
     
    254263
    255264    public void addMembersAtEnd(List<? extends OsmPrimitive> primitives) {
    256         if (primitives == null) return;
    257 
    258         for (OsmPrimitive primitive: primitives) {
    259             RelationMember member = new RelationMember(null,primitive);
     265        if (primitives == null)
     266            return;
     267
     268        for (OsmPrimitive primitive : primitives) {
     269            RelationMember member = new RelationMember(null, primitive);
    260270            members.add(member);
    261271        }
    262272        fireTableDataChanged();
    263273        getSelectionModel().clearSelection();
    264         for (int i=0; i<primitives.size();i++) {
    265             getSelectionModel().addSelectionInterval(members.size()-1-i,members.size()-1-i);
    266         }
    267         fireMakeMemberVisible(members.size() -1);
     274        for (int i = 0; i < primitives.size(); i++) {
     275            getSelectionModel().addSelectionInterval(members.size() - 1 - i, members.size() - 1 - i);
     276        }
     277        fireMakeMemberVisible(members.size() - 1);
    268278    }
    269279
    270280    public void addMembersBeforeIdx(List<? extends OsmPrimitive> primitives, int idx) {
    271         if (primitives == null) return;
    272 
    273         for (OsmPrimitive primitive: primitives) {
    274             RelationMember member = new RelationMember(null,primitive);
    275             members.add(idx,member);
     281        if (primitives == null)
     282            return;
     283
     284        for (OsmPrimitive primitive : primitives) {
     285            RelationMember member = new RelationMember(null, primitive);
     286            members.add(idx, member);
    276287        }
    277288        fireTableDataChanged();
    278289        getSelectionModel().clearSelection();
    279         for (int i=0; i<primitives.size();i++) {
    280             getSelectionModel().addSelectionInterval(idx+i,idx+i);
     290        for (int i = 0; i < primitives.size(); i++) {
     291            getSelectionModel().addSelectionInterval(idx + i, idx + i);
    281292        }
    282293        fireMakeMemberVisible(idx);
     
    284295
    285296    public void addMembersAfterIdx(List<? extends OsmPrimitive> primitives, int idx) {
    286         if (primitives == null) return;
    287         int j =1;
    288         for (OsmPrimitive primitive: primitives) {
    289             RelationMember member = new RelationMember(null,primitive);
    290             members.add(idx+j,member);
     297        if (primitives == null)
     298            return;
     299        int j = 1;
     300        for (OsmPrimitive primitive : primitives) {
     301            RelationMember member = new RelationMember(null, primitive);
     302            members.add(idx + j, member);
    291303            j++;
    292304        }
    293305        fireTableDataChanged();
    294306        getSelectionModel().clearSelection();
    295         for (int i=0; i<primitives.size();i++) {
    296             getSelectionModel().addSelectionInterval(idx+1 + i,idx+1 +i);
    297         }
    298         fireMakeMemberVisible(idx+1);
     307        for (int i = 0; i < primitives.size(); i++) {
     308            getSelectionModel().addSelectionInterval(idx + 1 + i, idx + 1 + i);
     309        }
     310        fireMakeMemberVisible(idx + 1);
    299311    }
    300312
     
    306318     */
    307319    public int getNumMembersWithPrimitive(OsmPrimitive primitive) {
    308         int count  = 0;
     320        int count = 0;
    309321        for (RelationMember member : members) {
    310322            if (member.member.equals(primitive)) {
     
    321333     * @param role the new role
    322334     */
    323     public void updateRole(int [] idx, String role) {
    324         if (idx == null || idx.length == 0) return;
    325         for (int row: idx) {
     335    public void updateRole(int[] idx, String role) {
     336        if (idx == null || idx.length == 0)
     337            return;
     338        for (int row : idx) {
    326339            members.get(row).role = role;
    327340        }
    328341        fireTableDataChanged();
    329         for (int row: idx) {
     342        for (int row : idx) {
    330343            getSelectionModel().addSelectionInterval(row, row);
    331344        }
     
    333346
    334347    /**
    335      * Replies a collection with the currently selected relation members
     348     * Get the currently selected relation members
    336349     *
    337350     * @return a collection with the currently selected relation members
     
    339352    public Collection<RelationMember> getSelectedMembers() {
    340353        ArrayList<RelationMember> selectedMembers = new ArrayList<RelationMember>();
    341         for (int i: getSelectedIndices()) {
     354        for (int i : getSelectedIndices()) {
    342355            selectedMembers.add(members.get(i));
    343356        }
     
    345358    }
    346359
    347 
    348360    /**
    349      * Selectes the members in the collection selectedMembers
     361     * Selects the members in the collection selectedMembers
    350362     *
    351363     * @param selectedMembers the collection of selected members
     
    358370        //
    359371        ArrayList<Integer> selectedIndices = new ArrayList<Integer>();
    360         for (RelationMember member: selectedMembers) {
     372        for (RelationMember member : selectedMembers) {
    361373            int idx = members.indexOf(member);
    362374            if (idx >= 0 && !selectedIndices.contains(idx)) {
     
    381393
    382394    public boolean isEditableRelation(int row) {
    383         if (row < 0 || row >= members.size()) return false;
     395        if (row < 0 || row >= members.size())
     396            return false;
    384397        RelationMember member = members.get(row);
    385         if (!(member.member instanceof Relation)) return false;
    386         Relation r = (Relation)member.member;
    387         return ! r.incomplete;
     398        if (!(member.member instanceof Relation))
     399            return false;
     400        Relation r = (Relation) member.member;
     401        return !r.incomplete;
     402    }
     403
     404    void sort() {
     405        RelationNodeMap map = new RelationNodeMap(members);
     406        Vector<LinkedList<Integer>> segments;
     407        LinkedList<Integer> segment;
     408        Node startSearchNode;
     409        Node endSearchNode;
     410        boolean something_done;
     411
     412        /*
     413         * sort any 2 or more connected elements together may be slow with many unconnected members
     414         * TODO: cleanup again, too much code in 1 method
     415         */
     416
     417        if (map.isEmpty())
     418            // empty relation or incomplete members
     419            return;
     420        segments = new Vector<LinkedList<Integer>>();
     421        // add first member of relation, not strictly necessary
     422        if (map.remove(0, members.get(0))) {
     423            segment = new LinkedList<Integer>();
     424            segment.add(Integer.valueOf(0));
     425            segments.add(segment);
     426        }
     427        while (!map.isEmpty()) {
     428            segment = segments.lastElement();
     429
     430            do {
     431                something_done = false;
     432                startSearchNode = null;
     433                endSearchNode = null;
     434                if (segment.size() == 1) {
     435                    RelationMember m = members.get(segment.getFirst());
     436                    if (m.member instanceof Way) {
     437                        Way w = (Way) m.member;
     438                        endSearchNode = w.lastNode();
     439                        startSearchNode = w.firstNode();
     440                    } else if (m.member instanceof Node) {
     441                        Node n = (Node) m.member;
     442                        endSearchNode = n;
     443                    }
     444                } else {
     445                    // add unused node of first element and unused node of last element
     446                    // start with the first element
     447                    RelationMember element = members.get(segment.getFirst());
     448                    RelationMember other_element = members.get(segment.get(1));
     449
     450                    if (element.member instanceof Way) {
     451                        Way w = (Way) element.member;
     452                        if (other_element.member instanceof Way) {
     453                            Way x = (Way) other_element.member;
     454                            if ((w.firstNode() == x.firstNode()) || (w.firstNode() == x.lastNode())) {
     455                                startSearchNode = w.lastNode();
     456                            } else {
     457                                startSearchNode = w.firstNode();
     458                            }
     459                        } else if (other_element.member instanceof Node) {
     460                            Node m = (Node) other_element.member;
     461                            if (w.firstNode() == m) {
     462                                startSearchNode = w.lastNode();
     463                            } else {
     464                                startSearchNode = w.firstNode();
     465                            }
     466                        }
     467                    } else if (element.member instanceof Node) {
     468                        Node n = (Node) element.member;
     469                        startSearchNode = n;
     470                    }
     471
     472                    // now the same for the last element
     473                    element = members.get(segment.getLast());
     474                    other_element = members.get(segment.get(segment.size() - 2));
     475
     476                    if (element.member instanceof Way) {
     477                        Way w = (Way) element.member;
     478                        if (other_element.member instanceof Way) {
     479                            Way x = (Way) other_element.member;
     480                            if ((w.firstNode() == x.firstNode()) || (w.firstNode() == x.lastNode())) {
     481                                endSearchNode = w.lastNode();
     482                            } else {
     483                                endSearchNode = w.firstNode();
     484                            }
     485                        } else if (other_element.member instanceof Node) {
     486                            Node m = (Node) other_element.member;
     487                            if (w.firstNode() == m) {
     488                                endSearchNode = w.lastNode();
     489                            } else {
     490                                endSearchNode = w.firstNode();
     491                            }
     492                        }
     493                    } else if (element.member instanceof Node) {
     494                        Node n = (Node) element.member;
     495                        endSearchNode = n;
     496                    }
     497                }
     498
     499                // let's see if we can find connected elements for endSearchNode and startSearchNode
     500                if (startSearchNode != null) {
     501                    Integer m2 = map.find(startSearchNode, segment.getFirst());
     502                    if (m2 != null) {
     503                        segment.add(0, m2);
     504                        map.remove(m2, members.get(m2));
     505                        something_done = true;
     506                    }
     507                }
     508                if (endSearchNode != null) {
     509                    Integer m2 = map.find(endSearchNode, segment.getLast());
     510                    if (m2 != null) {
     511                        segment.add(segment.size(), m2);
     512                        map.remove(m2, members.get(m2));
     513                        something_done = true;
     514                    }
     515                }
     516            } while (something_done);
     517
     518            Integer next = map.pop();
     519            if (next == null) {
     520                break;
     521            }
     522
     523            segment = new LinkedList<Integer>();
     524            segment.add(next);
     525            segments.add(segment);
     526        }
     527        // append map.remaining() to segments list (as a single segment)
     528        segment = new LinkedList<Integer>();
     529        segment.addAll(map.getRemaining());
     530        segments.add(segment);
     531
     532        // now we need to actually re-order the relation members
     533        ArrayList<RelationMember> newmembers = new ArrayList<RelationMember>();
     534        for (LinkedList<Integer> segment2 : segments) {
     535            for (Integer p : segment2) {
     536                newmembers.add(members.get(p));
     537            }
     538        }
     539        members.clear();
     540        members.addAll(newmembers);
     541
     542        fireTableDataChanged();
     543    }
     544
     545    // simple version of code that was removed from GenericReleationEditor
     546    // no recursion and no forward/backward support
     547    // TODO: add back the number of linked elements
     548    private WayConnectionType linked(int i) {
     549        // this method is aimed at finding out whether the
     550        // relation member is "linked" with the next, i.e. whether
     551        // (if both are ways) these ways are connected. It should
     552        // really produce a much more beautiful output (with a linkage
     553        // symbol somehow placed between the two member lines!),
     554        // so... FIXME ;-)
     555
     556        WayConnectionType link = WayConnectionType.none;
     557        RelationMember m1 = members.get(i);
     558        RelationMember m2 = members.get((i + 1) % members.size());
     559        Way way1 = null;
     560        Way way2 = null;
     561
     562        if (m1.member instanceof Way) {
     563            way1 = (Way) m1.member;
     564        }
     565        if (m2.member instanceof Way) {
     566            way2 = (Way) m2.member;
     567        }
     568        if ((way1 != null) && (way2 != null)) {
     569            Node way1first = way1.firstNode();
     570            Node way1last = way1.lastNode();
     571            Node way2first = way2.firstNode();
     572            Node way2last = way2.lastNode();
     573            if (way1first != null && way2first != null && (way1first == way2first)) {
     574                link = WayConnectionType.tail_to_tail;
     575            } else if (way1first != null && way2last != null && (way1first == way2last)) {
     576                link = WayConnectionType.tail_to_head;
     577            } else if (way1last != null && way2first != null && (way1last == way2first)) {
     578                link = WayConnectionType.head_to_tail;
     579            } else if (way1last != null && way2last != null && (way1last == way2last)) {
     580                link = WayConnectionType.head_to_head;
     581            }
     582        }
     583
     584        return link;
    388585    }
    389586}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationNodeMap.java

    r1785 r1822  
    11package org.openstreetmap.josm.gui.dialogs.relation;
    22
     3import java.util.ArrayList;
     4
    35import org.openstreetmap.josm.data.osm.Node;
    4 import org.openstreetmap.josm.data.osm.Relation;
    56import org.openstreetmap.josm.data.osm.RelationMember;
    67import org.openstreetmap.josm.data.osm.Way;
    78
    89/**
    9  * A mapping from Node positions to elements in a Relation
    10  * (currently Nodes and Ways only)
     10 * A mapping from Node positions to elements in a Relation (currently Nodes and Ways only)
    1111 *
    1212 * @author Christiaan Welvaart <cjw@time4t.net>
    13  *
     13 * 
    1414 */
    1515public class RelationNodeMap {
    16     private java.util.HashMap<Node, java.util.TreeSet<Integer>>   points;
    17     private java.util.HashMap<Node, Integer>   nodes;
    18     private java.util.Vector<Integer>          remaining;
    19     private Relation                           relation;
     16    private java.util.HashMap<Node, java.util.TreeSet<Integer>> points;
     17    private java.util.HashMap<Node, Integer> nodes;
     18    private java.util.Vector<Integer> remaining;
     19    private ArrayList<RelationMember> members;
    2020
    21     RelationNodeMap(Relation relation)
    22     {
    23         int     i;
     21    RelationNodeMap(ArrayList<RelationMember> members) {
     22        int i;
    2423
    25         this.relation = relation;
     24        this.members = members;
    2625        points = new java.util.HashMap<Node, java.util.TreeSet<Integer>>();
    2726        nodes = new java.util.HashMap<Node, Integer>();
    2827        remaining = new java.util.Vector<Integer>();
    2928
    30         for (i = 0; i < relation.members.size(); ++i)
    31         {
    32             RelationMember  m = relation.members.get(i);
     29        for (i = 0; i < members.size(); ++i) {
     30            RelationMember m = members.get(i);
    3331            if (m.member.incomplete)
    34             {
    3532                // throw an exception?
    3633                return;
    37             }
    3834            add(i, m);
    3935        }
    4036    }
    4137
    42     Integer find(Node node, int current)
    43     {
     38    Integer find(Node node, int current) {
    4439        Integer result = null;
    4540
    4641        try {
    4742            result = nodes.get(node);
    48             if (result == null)
    49             {
     43            if (result == null) {
    5044                result = points.get(node).first();
    51                 if (relation.members.get(current).member == relation.members.get(result).member)
    52                 {
     45                if (members.get(current).member == members.get(result).member) {
    5346                    result = points.get(node).last();
    5447                }
    5548            }
    56         } catch(NullPointerException f) {}
    57         catch(java.util.NoSuchElementException e) {}
    58 
    59         return result;
    60     }
    61 
    62     void add(int n, RelationMember m)
    63     {
    64         try
    65         {
    66             Way w = (Way)m.member;
    67             if (!points.containsKey(w.firstNode()))
    68             {
    69                 points.put(w.firstNode(), new java.util.TreeSet<Integer>());
    70             }
    71             points.get(w.firstNode()).add(Integer.valueOf(n));
    72 
    73             if (!points.containsKey(w.lastNode()))
    74             {
    75                 points.put(w.lastNode(), new java.util.TreeSet<Integer>());
    76             }
    77             points.get(w.lastNode()).add(Integer.valueOf(n));
    78         }
    79         catch(ClassCastException e1)
    80         {
    81             try
    82             {
    83                 Node        node = (Node)m.member;
    84                 nodes.put(node, Integer.valueOf(n));
    85             }
    86             catch(ClassCastException e2)
    87             {
    88                 remaining.add(Integer.valueOf(n));
    89             }
    90         }
    91     }
    92 
    93     boolean remove(int n, RelationMember a)
    94     {
    95         boolean result;
    96 
    97         try
    98         {
    99             result = points.get(((Way)a.member).firstNode()).remove(n);
    100             result &= points.get(((Way)a.member).lastNode()).remove(n);
    101         }
    102         catch(ClassCastException e1)
    103         {
    104             result = (nodes.remove(a.member) != null);
     49        } catch (NullPointerException f) {
     50        } catch (java.util.NoSuchElementException e) {
    10551        }
    10652
     
    10854    }
    10955
    110     void move(int from, int to)
    111     {
    112         if (from != to)
    113         {
    114             RelationMember  b = relation.members.get(from);
    115             RelationMember  a = relation.members.get(to);
     56    void add(int n, RelationMember m) {
     57        if (m.member instanceof Way) {
     58            Way w = (Way) m.member;
     59            if (!points.containsKey(w.firstNode())) {
     60                points.put(w.firstNode(), new java.util.TreeSet<Integer>());
     61            }
     62            points.get(w.firstNode()).add(Integer.valueOf(n));
     63
     64            if (!points.containsKey(w.lastNode())) {
     65                points.put(w.lastNode(), new java.util.TreeSet<Integer>());
     66            }
     67            points.get(w.lastNode()).add(Integer.valueOf(n));
     68        } else if (m.member instanceof Node) {
     69            Node node = (Node) m.member;
     70            nodes.put(node, Integer.valueOf(n));
     71        } else {
     72            remaining.add(Integer.valueOf(n));
     73        }
     74    }
     75
     76    boolean remove(int n, RelationMember a) {
     77        boolean result;
     78        if (a.member instanceof Way) {
     79            result = points.get(((Way) a.member).firstNode()).remove(n);
     80            result &= points.get(((Way) a.member).lastNode()).remove(n);
     81        } else {
     82            result = (nodes.remove(a.member) != null);
     83        }
     84        return result;
     85    }
     86
     87    void move(int from, int to) {
     88        if (from != to) {
     89            RelationMember b = members.get(from);
     90            RelationMember a = members.get(to);
    11691
    11792            remove(to, b);
     
    12196
    12297    // no node-mapped entries left
    123     boolean isEmpty()
    124     {
     98    boolean isEmpty() {
    12599        return points.isEmpty() && nodes.isEmpty();
    126100    }
    127101
    128     java.util.Vector<Integer> getRemaining()
    129     {
     102    java.util.Vector<Integer> getRemaining() {
    130103        return remaining;
    131104    }
    132105
    133     Integer pop()
    134     {
     106    Integer pop() {
     107        Node node = null;
    135108        Integer result = null;
    136109
    137         if (!nodes.isEmpty())
    138         {
    139             result = nodes.values().iterator().next();
    140             nodes.remove(result);
    141         }
    142         else if (!points.isEmpty())
    143         {
    144             for (java.util.TreeSet<Integer> set : points.values())
    145             {
    146                 if (!set.isEmpty())
    147                 {
     110        if (!nodes.isEmpty()) {
     111            node = nodes.keySet().iterator().next();
     112            result = nodes.get(node);
     113            nodes.remove(node);
     114        } else if (!points.isEmpty()) {
     115            for (java.util.TreeSet<Integer> set : points.values()) {
     116                if (!set.isEmpty()) {
    148117                    result = set.first();
     118                    Way w = (Way) members.get(result).member;
     119                    points.get(w.firstNode()).remove(result);
     120                    points.get(w.lastNode()).remove(result);
    149121                    break;
    150122                }
     
    154126        return result;
    155127    }
    156 
    157128}
Note: See TracChangeset for help on using the changeset viewer.