Ignore:
Timestamp:
2008-08-17T12:36:04+02:00 (16 years ago)
Author:
stoecker
Message:

second try for sorting in relation editor

File:
1 edited

Legend:

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

    r792 r803  
    11package org.openstreetmap.josm.gui.dialogs;
    22
     3import static org.openstreetmap.josm.tools.I18n.marktr;
    34import static org.openstreetmap.josm.tools.I18n.tr;
    4 import static org.openstreetmap.josm.tools.I18n.marktr;
    55
    66import java.awt.BorderLayout;
     
    1414import java.beans.PropertyChangeListener;
    1515import java.io.IOException;
     16import java.text.Collator;
    1617import java.util.ArrayList;
     18import java.util.Collections;
     19import java.util.Comparator;
    1720import java.util.Map.Entry;
    1821
    1922import javax.swing.JButton;
    20 import javax.swing.JDialog;
    2123import javax.swing.JFrame;
    2224import javax.swing.JLabel;
     
    4850/**
    4951 * This dialog is for editing relations.
    50  * 
     52 *
    5153 * In the basic form, it provides two tables, one with the relation tags
    52  * and one with the relation members. (Relation tags can be edited through 
    53  * the normal properties dialog as well, if you manage to get a relation 
     54 * and one with the relation members. (Relation tags can be edited through
     55 * the normal properties dialog as well, if you manage to get a relation
    5456 * selected!)
    55  * 
     57 *
    5658 * @author Frederik Ramm <frederik@remote.org>
    5759 *
     
    6668        private final Relation clone;
    6769        private JLabel status;
    68        
     70
    6971        /**
    7072         * The property data.
     
    9092                }
    9193        };
    92        
     94
    9395        /**
    9496         * The properties and membership lists.
     
    9698        private final JTable propertyTable = new JTable(propertyData);
    9799        private final JTable memberTable = new JTable(memberData);
    98        
     100
     101        /**
     102         * Collator for sorting the roles and entries of the member table.
     103         */
     104        private static final Collator collator;
     105        static {
     106                collator = Collator.getInstance();
     107                collator.setStrength(Collator.PRIMARY);
     108        }
     109
     110        /**
     111         * Compare role strings.
     112         */
     113        private static int compareRole(String s1, String s2) {
     114                int last1 = s1.lastIndexOf('_');
     115                if (last1 > 0) {
     116                        int last2 = s2.lastIndexOf('_');
     117                        if (last2 == last1) {
     118                                String prefix1 = s1.substring(0, last1);
     119                                String prefix2 = s2.substring(0, last2);
     120
     121                                if (prefix1.equalsIgnoreCase(prefix2)) {
     122                                        // Both roles have the same prefix, now determine the
     123                                        // suffix.
     124                                        String suffix1 = s1.substring(last1 + 1, s1.length());
     125                                        String suffix2 = s2.substring(last2 + 1, s2.length());
     126
     127                                        if (suffix1.matches("\\d+") && suffix2.matches("\\d+")) {
     128                                                // Suffix is an number -> compare it.
     129                                                int i1 = Integer.parseInt(suffix1);
     130                                                int i2 = Integer.parseInt(suffix2);
     131
     132                                                return i1 - i2;
     133                                        }
     134                                }
     135                        }
     136                }
     137
     138                // Default handling if the role name is nothing like "stop_xx"
     139                return collator.compare(s1, s2);
     140        }
     141
     142
     143        /**
     144         * Compare two OsmPrimitives.
     145         */
     146        private static int compareMemebers(OsmPrimitive o1, OsmPrimitive o2) {
     147                return collator.compare(o1.getName(), o2.getName());
     148        }
     149
     150        private final Comparator<RelationMember> memberComparator = new Comparator<RelationMember>() {
     151                public int compare(RelationMember r1, RelationMember r2) {
     152                        int roleResult = compareRole(r1.role, r2.role);
     153
     154                        if (roleResult == 0) {
     155                                return compareMemebers(r1.member, r2.member);
     156                        }
     157
     158                        return roleResult;
     159                }
     160        };
     161
    99162        /**
    100163         * Creates a new relation editor for the given relation. The relation
    101164         * will be saved if the user selects "ok" in the editor.
    102          * 
     165         *
    103166         * If no relation is given, will create an editor for a new relation.
    104          * 
     167         *
    105168         * @param relation relation to edit, or null to create a new one.
    106169         */
    107170        public RelationEditor(Relation relation)
    108171        {
    109                 super(relation == null ? tr("Create new relation") : 
     172                super(relation == null ? tr("Create new relation") :
    110173                        relation.id == 0 ? tr ("Edit new relation") :
    111174                        tr("Edit relation #{0}", relation.id));
    112175                this.relation = relation;
    113                
     176
    114177                if (relation == null) {
    115178                        // create a new relation
     
    117180                } else {
    118181                        // edit an existing relation
    119                         this.clone = new Relation(relation);   
    120                 }
    121                
     182                        this.clone = new Relation(relation);
     183                        Collections.sort(this.clone.members, memberComparator);
     184                }
     185
    122186                getContentPane().setLayout(new BorderLayout());
    123187                JTabbedPane tabPane = new JTabbedPane();
    124188                getContentPane().add(tabPane, BorderLayout.CENTER);
    125                
     189
    126190                // (ab)use JOptionPane to make this look familiar;
    127191                // hook up with JOptionPane's property change event
    128192                // to detect button click
    129                 final JOptionPane okcancel = new JOptionPane("", 
     193                final JOptionPane okcancel = new JOptionPane("",
    130194                        JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null);
    131195                getContentPane().add(okcancel, BorderLayout.SOUTH);
    132                
     196
    133197                okcancel.addPropertyChangeListener(new PropertyChangeListener() {
    134198                        public void propertyChange(PropertyChangeEvent event) {
     
    155219                getContentPane().add(help, BorderLayout.NORTH);
    156220                try { setAlwaysOnTop(true); } catch (SecurityException sx) {}
    157                
    158                 // Basic Editor panel has two blocks; 
     221
     222                // Basic Editor panel has two blocks;
    159223                // a tag table at the top and a membership list below.
    160224
    161225                // setting up the properties table
    162                
     226
    163227                propertyData.setColumnIdentifiers(new String[]{tr("Key"),tr("Value")});
    164228                propertyTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     
    167231                                if (tme.getType() == TableModelEvent.UPDATE) {
    168232                                        int row = tme.getFirstRow();
    169                        
     233
    170234                                        if (!(tme.getColumn() == 0 && row == propertyData.getRowCount() -1)) {
    171235                                                clone.entrySet().clear();
     
    181245                });
    182246                propertyTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
    183                
     247
    184248                // setting up the member table
    185                
     249
    186250                memberData.setColumnIdentifiers(new String[]{tr("Role"),tr("Occupied By")});
    187251                memberTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    188252                memberTable.getColumnModel().getColumn(1).setCellRenderer(new OsmPrimitivRenderer());
    189                 /*
    190                 memberTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
    191                         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    192                                 Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
    193                                 if (c instanceof JLabel) {
    194                                         ((OsmPrimitive)value).visit(nameVisitor);
    195                                         ((JLabel)c).setText(nameVisitor.name);
    196                                 }
    197                                 return c;
    198                         }
    199                 });     
    200                 */
    201253                memberData.addTableModelListener(new TableModelListener() {
    202254                        public void tableChanged(TableModelEvent tme) {
     
    209261                memberTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
    210262
    211                
     263
    212264                // combine both tables and wrap them in a scrollPane
    213265                JPanel bothTables = new JPanel();
     
    217269                bothTables.add(status = new JLabel(tr("Members")), GBC.eol().fill(GBC.HORIZONTAL));
    218270                bothTables.add(new JScrollPane(memberTable), GBC.eol().fill(GBC.BOTH));
    219                
     271
    220272                JPanel buttonPanel = new JPanel(new GridLayout(1,3));
    221                
    222                 buttonPanel.add(createButton(marktr("Add Selected"),"addselected", tr("Add all currently selected objects as members"), KeyEvent.VK_A, new ActionListener() {
     273
     274                buttonPanel.add(createButton(marktr("Add Selected"),"addselected",
     275                tr("Add all currently selected objects as members"), KeyEvent.VK_A, new ActionListener() {
    223276                        public void actionPerformed(ActionEvent e) {
    224277                                addSelected();
     
    226279                }));
    227280
    228                 buttonPanel.add(createButton(marktr("Delete Selected"),"deleteselected", tr("Delete all currently selected objects from releation"), KeyEvent.VK_R, new ActionListener() {
     281                buttonPanel.add(createButton(marktr("Delete Selected"),"deleteselected",
     282                tr("Delete all currently selected objects from releation"), KeyEvent.VK_R, new ActionListener() {
    229283                        public void actionPerformed(ActionEvent e) {
    230284                                deleteSelected();
     
    232286                }));
    233287
    234                 buttonPanel.add(createButton(marktr("Delete"),"delete", tr("Remove the member in the current table row from this relation"), KeyEvent.VK_D, new ActionListener() {
     288                buttonPanel.add(createButton(marktr("Delete"),"delete",
     289                tr("Remove the member in the current table row from this relation"), KeyEvent.VK_D, new ActionListener() {
    235290                        public void actionPerformed(ActionEvent e) {
    236291                                int[] rows = memberTable.getSelectedRows();
     
    245300                }));
    246301
    247                 buttonPanel.add(createButton(marktr("Select"),"select", tr("Highlight the member from the current table row as JOSM's selection"), KeyEvent.VK_S, new ActionListener() {
     302                buttonPanel.add(createButton(marktr("Select"),"select",
     303                tr("Highlight the member from the current table row as JOSM's selection"), KeyEvent.VK_S, new ActionListener() {
    248304                        public void actionPerformed(ActionEvent e) {
    249305                                int[] rows = memberTable.getSelectedRows();
     
    253309                        }
    254310                }));
    255                 buttonPanel.add(createButton(marktr("Download Members"),"down", tr("Download all incomplete ways and nodes in relation"), KeyEvent.VK_L, new ActionListener() {
     311                buttonPanel.add(createButton(marktr("Download Members"),"down",
     312                tr("Download all incomplete ways and nodes in relation"), KeyEvent.VK_L, new ActionListener() {
    256313                        public void actionPerformed(ActionEvent e) {
    257314                                downloadRelationMembers();
     
    269326                setLocationRelativeTo(Main.parent);
    270327        }
    271        
     328
    272329        private void refreshTables() {
    273                
    274330                // re-load property data
    275                
     331
    276332                propertyData.setRowCount(0);
    277333                for (Entry<String, String> e : clone.entrySet()) {
     
    279335                }
    280336                propertyData.addRow(new Object[]{"", ""});
    281                
     337
    282338                // re-load membership data
    283                
     339
    284340                memberData.setRowCount(0);
    285341                for (RelationMember em : clone.members) {
     
    288344                status.setText(tr("Members: {0}", clone.members.size()));
    289345        }
    290        
     346
    291347        private JButton createButton(String name, String iconName, String tooltip, int mnemonic, ActionListener actionListener) {
    292348                JButton b = new JButton(tr(name), ImageProvider.get("dialogs", iconName));
     
    298354                return b;
    299355        }
    300        
     356
    301357        private void addSelected() {
    302358                for (OsmPrimitive p : Main.ds.getSelected()) {
     
    336392        }
    337393
    338     private void downloadRelationMembers() {
    339 
    340         boolean download = false;
    341         for (RelationMember member : clone.members) {
    342             if (member.member.incomplete) {
    343                 download = true;
    344                 break;
    345             }
    346         }
    347         if (download) {
    348             OsmServerObjectReader reader = new OsmServerObjectReader();
    349             try {
    350                 DataSet dataSet = reader.parseOsm(clone.id,
    351                         OsmServerObjectReader.TYPE_REL, true);
    352                 if (dataSet != null) {
    353                     final MergeVisitor visitor = new MergeVisitor(Main.main
    354                             .editLayer().data, dataSet);
    355                     for (final OsmPrimitive osm : dataSet.allPrimitives())
    356                         osm.visit(visitor);
    357                     visitor.fixReferences();
    358 
    359                     // copy the merged layer's data source info
    360                     for (DataSource src : dataSet.dataSources)
    361                         Main.main.editLayer().data.dataSources.add(src);
    362                     Main.main.editLayer().fireDataChange();
    363 
    364                     if (visitor.conflicts.isEmpty())
    365                         return;
    366                     final ConflictDialog dlg = Main.map.conflictDialog;
    367                     dlg.add(visitor.conflicts);
    368                     JOptionPane.showMessageDialog(Main.parent,
    369                             tr("There were conflicts during import."));
    370                     if (!dlg.isVisible())
    371                         dlg.action
    372                                 .actionPerformed(new ActionEvent(this, 0, ""));
    373                 }
    374 
    375             } catch (SAXException e) {
    376                 e.printStackTrace();
    377                 JOptionPane.showMessageDialog(this,tr("Error parsing server response.")+": "+e.getMessage(), tr("Error"), JOptionPane.ERROR_MESSAGE);       
    378             } catch (IOException e) {
    379                 e.printStackTrace();               
    380                 JOptionPane.showMessageDialog(this,tr("Cannot connect to server.")+": "+e.getMessage(), tr("Error"), JOptionPane.ERROR_MESSAGE);
    381             }
    382         }
    383 
    384     }
     394        private void downloadRelationMembers() {
     395                boolean download = false;
     396                for (RelationMember member : clone.members) {
     397                        if (member.member.incomplete) {
     398                                download = true;
     399                                break;
     400                        }
     401                }
     402                if (download) {
     403                        OsmServerObjectReader reader = new OsmServerObjectReader();
     404                        try {
     405                                DataSet dataSet = reader.parseOsm(clone.id,
     406                                                OsmServerObjectReader.TYPE_REL, true);
     407                                if (dataSet != null) {
     408                                        final MergeVisitor visitor = new MergeVisitor(Main.main
     409                                                        .editLayer().data, dataSet);
     410                                        for (final OsmPrimitive osm : dataSet.allPrimitives())
     411                                                osm.visit(visitor);
     412                                        visitor.fixReferences();
     413
     414                                        // copy the merged layer's data source info
     415                                        for (DataSource src : dataSet.dataSources)
     416                                                Main.main.editLayer().data.dataSources.add(src);
     417                                        Main.main.editLayer().fireDataChange();
     418
     419                                        if (visitor.conflicts.isEmpty())
     420                                                return;
     421                                        final ConflictDialog dlg = Main.map.conflictDialog;
     422                                        dlg.add(visitor.conflicts);
     423                                        JOptionPane.showMessageDialog(Main.parent,
     424                                                        tr("There were conflicts during import."));
     425                                        if (!dlg.isVisible())
     426                                                dlg.action
     427                                                                .actionPerformed(new ActionEvent(this, 0, ""));
     428                                }
     429
     430                        } catch (SAXException e) {
     431                                e.printStackTrace();
     432                                JOptionPane.showMessageDialog(this,tr("Error parsing server response.")+": "+e.getMessage(),
     433                                tr("Error"), JOptionPane.ERROR_MESSAGE);
     434                        } catch (IOException e) {
     435                                e.printStackTrace();
     436                                JOptionPane.showMessageDialog(this,tr("Cannot connect to server.")+": "+e.getMessage(),
     437                                tr("Error"), JOptionPane.ERROR_MESSAGE);
     438                        }
     439                }
     440        }
    385441}
Note: See TracChangeset for help on using the changeset viewer.