- Timestamp:
- 2009-06-01T22:20:03+02:00 (16 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 9 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/conflict/ConflictResolver.java
r1626 r1631 7 7 import java.beans.PropertyChangeEvent; 8 8 import java.beans.PropertyChangeListener; 9 import java.net.URL;10 9 import java.util.ArrayList; 11 10 import java.util.logging.Logger; … … 25 24 import org.openstreetmap.josm.gui.conflict.nodes.NodeListMergeModel; 26 25 import org.openstreetmap.josm.gui.conflict.nodes.NodeListMerger; 26 import org.openstreetmap.josm.gui.conflict.relation.RelationMemberListMergeModel; 27 import org.openstreetmap.josm.gui.conflict.relation.RelationMemberMerger; 27 28 import org.openstreetmap.josm.gui.conflict.tags.TagMergeModel; 28 29 import org.openstreetmap.josm.gui.conflict.tags.TagMerger; 30 import org.openstreetmap.josm.tools.ImageProvider; 29 31 30 32 /** 31 33 * An UI component for resolving conflicts between two {@see OsmPrimitive}s. 32 * 33 * 34 * 34 35 */ 35 36 public class ConflictResolver extends JPanel implements PropertyChangeListener { 36 37 private static final Logger logger = Logger.getLogger(ConflictResolver.class.getName()); 37 38 private static final Logger logger = Logger.getLogger(ConflictResolver.class.getName()); 38 39 39 40 private JTabbedPane tabbedPane = null; 40 41 private TagMerger tagMerger; 41 42 private NodeListMerger nodeListMerger; 43 private RelationMemberMerger relationMemberMerger; 42 44 private OsmPrimitive my; 43 45 private OsmPrimitive their; 44 46 45 47 private ImageIcon mergeComplete; 46 48 private ImageIcon mergeIncomplete; 47 48 // FIXME copied code -> refactor 49 /** 50 * load an icon given by iconName 51 * 52 * @param iconName the name of the icon (without path, i.e. <tt>copystartleft.png</tt> 53 * @return the icon; null, if the icon was not found 54 */ 55 protected ImageIcon getIcon(String iconName) { 56 String fullIconName = "/images/dialogs/conflict/" + iconName; 57 URL imageURL = this.getClass().getResource(fullIconName); 58 if (imageURL == null) { 59 System.out.println(tr("WARNING: failed to load resource {0}", fullIconName)); 60 return null; 61 } 62 return new ImageIcon(imageURL); 49 50 protected void loadIcons() { 51 mergeComplete = ImageProvider.get("dialogs/conflict","mergecomplete.png" ); 52 mergeIncomplete = ImageProvider.get("dialogs/conflict","mergeincomplete.png" ); 63 53 } 64 65 protected void loadIcons() { 66 mergeComplete = getIcon("mergecomplete.png"); 67 mergeIncomplete = getIcon("mergeincomplete.png"); 68 } 69 54 70 55 protected void build() { 71 56 tabbedPane = new JTabbedPane(); 72 57 73 58 tagMerger = new TagMerger(); 59 tagMerger.setName("panel.tagmerger"); 74 60 tagMerger.getModel().addPropertyChangeListener(this); 75 61 tabbedPane.add("Tags", tagMerger); 76 62 77 63 nodeListMerger = new NodeListMerger(); 64 nodeListMerger.setName("panel.nodelistmerger"); 78 65 nodeListMerger.getModel().addPropertyChangeListener(this); 79 66 tabbedPane.add("Nodes", nodeListMerger); 80 81 tabbedPane.add("Members", new JPanel()); 82 67 68 relationMemberMerger = new RelationMemberMerger(); 69 relationMemberMerger.setName("panel.relationmembermerger"); 70 relationMemberMerger.getModel().addPropertyChangeListener(this); 71 tabbedPane.add("Members", relationMemberMerger); 72 83 73 setLayout(new BorderLayout()); 84 74 add(tabbedPane, BorderLayout.CENTER); 85 75 } 86 87 76 88 77 public ConflictResolver() { 89 78 build(); … … 92 81 93 82 public void propertyChange(PropertyChangeEvent evt) { 94 83 95 84 if (evt.getPropertyName().equals(TagMergeModel.PROP_NUM_UNDECIDED_TAGS)) { 96 85 int newValue = (Integer)evt.getNewValue(); … … 104 93 tabbedPane.setIconAt(0, mergeIncomplete); 105 94 } 106 } else if (evt.getPropertyName().equals( NodeListMergeModel.PROP_FROZEN)) {95 } else if (evt.getPropertyName().equals(ListMergeModel.PROP_FROZEN)) { 107 96 boolean frozen = (Boolean)evt.getNewValue(); 108 if (frozen) { 97 if (frozen && evt.getSource() == nodeListMerger.getModel()) { 109 98 tabbedPane.setTitleAt(1, tr("Nodes(resolved)")); 110 tabbedPane.setToolTipTextAt(1, tr(" Pending conflicts in the node list of this way"));99 tabbedPane.setToolTipTextAt(1, tr("Merged node list frozen. No pending conflicts in the node list of this way")); 111 100 tabbedPane.setIconAt(1, mergeComplete); 112 101 } else { 113 102 tabbedPane.setTitleAt(1, tr("Nodes(with conflicts)")); 114 tabbedPane.setToolTipTextAt(1, tr("Merged node list frozen. No pending conflicts in the node list of this way"));103 tabbedPane.setToolTipTextAt(1,tr("Pending conflicts in the node list of this way")); 115 104 tabbedPane.setIconAt(1, mergeIncomplete); 105 } 106 if (frozen && evt.getSource() == relationMemberMerger.getModel()) { 107 tabbedPane.setTitleAt(2, tr("Members(resolved)")); 108 tabbedPane.setToolTipTextAt(2, tr("Merged member list frozen. No pending conflicts in the member list of this relation")); 109 tabbedPane.setIconAt(2, mergeComplete); 110 } else { 111 tabbedPane.setTitleAt(2, tr("Members(with conflicts)")); 112 tabbedPane.setToolTipTextAt(2, tr("Pending conflicts in the member list of this relation")); 113 tabbedPane.setIconAt(2, mergeIncomplete); 116 114 } 117 115 } 118 116 } 119 120 public void populate(OsmPrimitive my, OsmPrimitive their) { 117 118 /** 119 * populates the conflict resolver with the conflicts between my and their 120 * 121 * @param my my primitive (i.e. the primitive in the local dataset) 122 * @param their their primitive (i.e. the primitive in the server dataset) 123 * 124 */ 125 public void populate(OsmPrimitive my, OsmPrimitive their) { 121 126 this.my = my; 122 this.their = their; 127 this.their = their; 123 128 tagMerger.getModel().populate(my, their); 124 if (my instanceof Way) { 125 nodeListMerger.populate((Way)my, (Way)their); 126 tabbedPane.setEnabledAt(1, true); 127 tabbedPane.setEnabledAt(2, false); 129 tabbedPane.setEnabledAt(0,true); 130 if (my instanceof Node) { 131 tabbedPane.setEnabledAt(1,false); 132 tabbedPane.setEnabledAt(2,false); 133 } else if (my instanceof Way) { 134 nodeListMerger.populate((Way)my, (Way)their); 135 tabbedPane.setEnabledAt(1, true); 136 tabbedPane.setEnabledAt(2, false); 128 137 } else if (my instanceof Relation) { 138 relationMemberMerger.populate((Relation)my, (Relation)their); 129 139 tabbedPane.setEnabledAt(1, false); 130 tabbedPane.setEnabledAt(2, true); 131 140 tabbedPane.setEnabledAt(2, true); 141 } 132 142 } 133 143 144 /** 145 * Builds the resolution command(s) for for the resolved conflicts in this 146 * ConflictResolver 147 * 148 * @return the resolution command 149 */ 134 150 public Command buildResolveCommand() { 135 151 ArrayList<Command> commands = new ArrayList<Command>(); … … 137 153 commands.add(cmd); 138 154 if (my instanceof Way && nodeListMerger.getModel().isFrozen()) { 139 commands.add(nodeListMerger.getModel().buildResolveCommand((Way)my, (Way)their)); 155 NodeListMergeModel model =(NodeListMergeModel)nodeListMerger.getModel(); 156 commands.add(model.buildResolveCommand((Way)my, (Way)their)); 157 } else if (my instanceof Relation && relationMemberMerger.getModel().isFrozen()) { 158 RelationMemberListMergeModel model =(RelationMemberListMergeModel)relationMemberMerger.getModel(); 159 commands.add(model.buildResolveCommand((Relation)my, (Relation)their)); 140 160 } 141 161 if (my instanceof Node) { 142 // resolve the version conflict if this is a node and all tag 143 // conflicts have been resolved 144 // 162 // resolve the version conflict if this is a node and all tag 163 // conflicts have been resolved 164 // 145 165 if (tagMerger.getModel().isResolvedCompletely()) { 146 166 commands.add( 147 new VersionConflictResolveCommand(my, their) 167 new VersionConflictResolveCommand(my, their) 148 168 ); 149 169 } 150 170 } else if (my instanceof Way) { 151 // resolve the version conflict if this is a way, all tag 171 // resolve the version conflict if this is a way, all tag 152 172 // conflicts have been resolved, and conflicts in the node list 153 // have been resolved 154 // 173 // have been resolved 174 // 155 175 if (tagMerger.getModel().isResolvedCompletely() && nodeListMerger.getModel().isFrozen()) { 156 176 commands.add( 157 new VersionConflictResolveCommand(my, their) 177 new VersionConflictResolveCommand(my, their) 158 178 ); 159 } 179 } 180 } else if (my instanceof Relation) { 181 // resolve the version conflict if this is a relation, all tag 182 // conflicts and all conflicts in the member list 183 // have been resolved 184 // 185 if (tagMerger.getModel().isResolvedCompletely() && relationMemberMerger.getModel().isFrozen()) { 186 commands.add( 187 new VersionConflictResolveCommand(my, their) 188 ); 189 } 160 190 } 161 return new SequenceCommand("Conflict Resolution", commands); 191 192 return new SequenceCommand(tr("Conflict Resolution"), commands); 162 193 } 163 194 } -
trunk/src/org/openstreetmap/josm/gui/conflict/nodes/NodeListColumnModel.java
r1622 r1631 11 11 12 12 protected void createColumns(TableCellRenderer renderer) { 13 13 14 14 TableColumn col = null; 15 16 // column 0 - Node 15 16 // column 0 - Node 17 17 col = new TableColumn(0); 18 18 col.setHeaderValue(tr("Node")); 19 19 col.setResizable(true); 20 20 col.setCellRenderer(renderer); 21 addColumn(col); 21 addColumn(col); 22 22 } 23 23 -
trunk/src/org/openstreetmap/josm/gui/conflict/nodes/NodeListMergeModel.java
r1622 r1631 2 2 package org.openstreetmap.josm.gui.conflict.nodes; 3 3 4 import static org.openstreetmap.josm.tools.I18n.tr;5 6 import java.beans.PropertyChangeEvent;7 import java.beans.PropertyChangeListener;8 4 import java.util.ArrayList; 9 import java.util.List;10 5 import java.util.logging.Logger; 11 6 12 import javax.swing.DefaultListSelectionModel;13 import javax.swing.ListSelectionModel;14 7 import javax.swing.table.DefaultTableModel; 15 import javax.swing.table.TableModel;16 8 17 9 import org.openstreetmap.josm.command.WayNodesConflictResolverCommand; 18 10 import org.openstreetmap.josm.data.osm.Node; 19 11 import org.openstreetmap.josm.data.osm.Way; 12 import org.openstreetmap.josm.gui.conflict.ListMergeModel; 20 13 21 public class NodeListMergeModel { 14 public class NodeListMergeModel extends ListMergeModel<Node>{ 15 22 16 private static final Logger logger = Logger.getLogger(NodeListMergeModel.class.getName()); 23 24 public static final String PROP_FROZEN = NodeListMergeModel.class.getName() + ".frozen";25 26 17 27 private ArrayList<Node> myNodes;28 private ArrayList<Node> theirNodes;29 private ArrayList<Node> mergedNodes;30 31 32 private DefaultTableModel myNodesTableModel;33 private DefaultTableModel theirNodesTableModel;34 private DefaultTableModel mergedNodesTableModel;35 36 private DefaultListSelectionModel myNodesSelectionModel;37 private DefaultListSelectionModel theirNodesSelectionModel;38 private DefaultListSelectionModel mergedNodesSelectionModel;39 40 private ArrayList<PropertyChangeListener> listeners;41 private boolean isFrozen = false;42 43 44 public NodeListMergeModel() {45 myNodes = new ArrayList<Node>();46 theirNodes = new ArrayList<Node>();47 mergedNodes = new ArrayList<Node>();48 49 myNodesTableModel = new NodeListTableModel(myNodes);50 theirNodesTableModel = new NodeListTableModel(theirNodes);51 mergedNodesTableModel = new NodeListTableModel(mergedNodes);52 53 myNodesSelectionModel = new DefaultListSelectionModel();54 theirNodesSelectionModel = new DefaultListSelectionModel();55 mergedNodesSelectionModel = new DefaultListSelectionModel();56 57 listeners = new ArrayList<PropertyChangeListener>();58 59 setFrozen(true);60 }61 62 63 public void addPropertyChangeListener(PropertyChangeListener listener) {64 synchronized(listeners) {65 if (listener != null && ! listeners.contains(listener)) {66 listeners.add(listener);67 }68 }69 }70 71 public void removePropertyChangeListener(PropertyChangeListener listener) {72 synchronized(listeners) {73 if (listener != null && listeners.contains(listener)) {74 listeners.remove(listener);75 }76 }77 }78 79 protected void fireFrozenChanged(boolean oldValue, boolean newValue) {80 synchronized(listeners) {81 PropertyChangeEvent evt = new PropertyChangeEvent(this, PROP_FROZEN, oldValue, newValue);82 for (PropertyChangeListener listener: listeners) {83 listener.propertyChange(evt);84 }85 }86 }87 88 public void setFrozen(boolean isFrozen) {89 boolean oldValue = this.isFrozen;90 this.isFrozen = isFrozen;91 fireFrozenChanged(oldValue, this.isFrozen);92 }93 94 public boolean isFrozen() {95 return isFrozen;96 }97 98 public TableModel getMyNodesTableModel() {99 return myNodesTableModel;100 }101 102 public TableModel getTheirNodesTableModel() {103 return theirNodesTableModel;104 }105 106 public TableModel getMergedNodesTableModel() {107 return mergedNodesTableModel;108 }109 110 public ListSelectionModel getMyNodesSelectionModel() {111 return myNodesSelectionModel;112 }113 18 114 public ListSelectionModel getTheirNodesSelectionModel() {115 return theirNodesSelectionModel;116 }117 118 public ListSelectionModel getMergedNodesSelectionModel() {119 return mergedNodesSelectionModel;120 }121 122 123 protected void fireModelDataChanged() {124 myNodesTableModel.fireTableDataChanged();125 theirNodesTableModel.fireTableDataChanged();126 mergedNodesTableModel.fireTableDataChanged();127 }128 129 protected void copyNodesToTop(List<Node> source, int []rows) {130 if (rows == null || rows.length == 0) {131 return;132 }133 for (int i = rows.length - 1; i >= 0; i--) {134 int row = rows[i];135 Node n = source.get(row);136 mergedNodes.add(0, n);137 }138 fireModelDataChanged();139 mergedNodesSelectionModel.setSelectionInterval(0, rows.length -1);140 }141 142 /**143 * Copies the nodes given by indices in rows from the list of my nodes to the144 * list of merged nodes. Inserts the nodes at the top of the list of merged145 * nodes.146 *147 * @param rows the indices148 */149 public void copyMyNodesToTop(int [] rows) {150 copyNodesToTop(myNodes, rows);151 }152 153 /**154 * Copies the nodes given by indices in rows from the list of their nodes to the155 * list of merged nodes. Inserts the nodes at the top of the list of merged156 * nodes.157 *158 * @param rows the indices159 */160 public void copyTheirNodesToTop(int [] rows) {161 copyNodesToTop(theirNodes, rows);162 }163 164 /**165 * Copies the nodes given by indices in rows from the list of nodes in source to the166 * list of merged nodes. Inserts the nodes at the end of the list of merged167 * nodes.168 *169 * @param source the list of nodes to copy from170 * @param rows the indices171 */172 173 public void copyNodesToEnd(List<Node> source, int [] rows) {174 if (rows == null || rows.length == 0) {175 return;176 }177 for (int row : rows) {178 Node n = source.get(row);179 mergedNodes.add(n);180 }181 fireModelDataChanged();182 mergedNodesSelectionModel.setSelectionInterval(mergedNodes.size()-rows.length, mergedNodes.size() -1);183 184 }185 186 /**187 * Copies the nodes given by indices in rows from the list of my nodes to the188 * list of merged nodes. Inserts the nodes at the end of the list of merged189 * nodes.190 *191 * @param rows the indices192 */193 public void copyMyNodesToEnd(int [] rows) {194 copyNodesToEnd(myNodes, rows);195 }196 197 /**198 * Copies the nodes given by indices in rows from the list of their nodes to the199 * list of merged nodes. Inserts the nodes at the end of the list of merged200 * nodes.201 *202 * @param rows the indices203 */204 public void copyTheirNodesToEnd(int [] rows) {205 copyNodesToEnd(theirNodes, rows);206 }207 208 /**209 * Copies the nodes given by indices in rows from the list of nodes <code>source</code> to the210 * list of merged nodes. Inserts the nodes before row given by current.211 *212 * @param source the list of nodes to copy from213 * @param rows the indices214 * @param current the row index before which the nodes are inserted215 * @exception IllegalArgumentException thrown, if current < 0 or >= #nodes in list of merged nodes216 *217 */218 protected void copyNodesBeforeCurrent(List<Node> source, int [] rows, int current) {219 if (rows == null || rows.length == 0) {220 return;221 }222 if (current < 0 || current >= mergedNodes.size()) {223 throw new IllegalArgumentException(tr("parameter current out of range: got {0}", current));224 }225 for (int i=rows.length -1; i>=0; i--) {226 int row = rows[i];227 Node n = source.get(row);228 mergedNodes.add(current, n);229 }230 fireModelDataChanged();231 mergedNodesSelectionModel.setSelectionInterval(current, current + rows.length-1);232 }233 234 /**235 * Copies the nodes given by indices in rows from the list of my nodes to the236 * list of merged nodes. Inserts the nodes before row given by current.237 *238 * @param rows the indices239 * @param current the row index before which the nodes are inserted240 * @exception IllegalArgumentException thrown, if current < 0 or >= #nodes in list of merged nodes241 *242 */243 public void copyMyNodesBeforeCurrent(int [] rows, int current) {244 copyNodesBeforeCurrent(myNodes,rows,current);245 }246 247 /**248 * Copies the nodes given by indices in rows from the list of their nodes to the249 * list of merged nodes. Inserts the nodes before row given by current.250 *251 * @param rows the indices252 * @param current the row index before which the nodes are inserted253 * @exception IllegalArgumentException thrown, if current < 0 or >= #nodes in list of merged nodes254 *255 */256 public void copyTheirNodesBeforeCurrent(int [] rows, int current) {257 copyNodesBeforeCurrent(theirNodes,rows,current);258 }259 260 /**261 * Copies the nodes given by indices in rows from the list of nodes <code>source</code> to the262 * list of merged nodes. Inserts the nodes after the row given by current.263 *264 * @param source the list of nodes to copy from265 * @param rows the indices266 * @param current the row index after which the nodes are inserted267 * @exception IllegalArgumentException thrown, if current < 0 or >= #nodes in list of merged nodes268 *269 */270 protected void copyNodesAfterCurrent(List<Node> source, int [] rows, int current) {271 if (rows == null || rows.length == 0) {272 return;273 }274 if (current < 0 || current >= mergedNodes.size()) {275 throw new IllegalArgumentException(tr("parameter current out of range: got {0}", current));276 }277 if (current == mergedNodes.size() -1) {278 copyMyNodesToEnd(rows);279 } else {280 for (int i=rows.length -1; i>=0; i--) {281 int row = rows[i];282 Node n = source.get(row);283 mergedNodes.add(current+1, n);284 }285 }286 fireModelDataChanged();287 mergedNodesSelectionModel.setSelectionInterval(current+1, current + rows.length-1);288 }289 290 /**291 * Copies the nodes given by indices in rows from the list of my nodes to the292 * list of merged nodes. Inserts the nodes after the row given by current.293 *294 * @param rows the indices295 * @param current the row index after which the nodes are inserted296 * @exception IllegalArgumentException thrown, if current < 0 or >= #nodes in list of merged nodes297 *298 */299 public void copyMyNodesAfterCurrent(int [] rows, int current) {300 copyNodesAfterCurrent(myNodes, rows, current);301 }302 303 /**304 * Copies the nodes given by indices in rows from the list of my nodes to the305 * list of merged nodes. Inserts the nodes after the row given by current.306 *307 * @param rows the indices308 * @param current the row index after which the nodes are inserted309 * @exception IllegalArgumentException thrown, if current < 0 or >= #nodes in list of merged nodes310 *311 */312 public void copyTheirNodesAfterCurrent(int [] rows, int current) {313 copyNodesAfterCurrent(theirNodes, rows, current);314 }315 316 /**317 * Moves the nodes given by indices in rows up by one position in the list318 * of merged nodes.319 *320 * @param rows the indices321 *322 */323 protected void moveUpMergedNodes(int [] rows) {324 if (rows == null || rows.length == 0) {325 return;326 }327 if (rows[0] == 0) {328 // can't move up329 return;330 }331 for (int row: rows) {332 Node n = mergedNodes.get(row);333 mergedNodes.remove(row);334 mergedNodes.add(row -1, n);335 }336 fireModelDataChanged();337 mergedNodesSelectionModel.clearSelection();338 for (int row: rows) {339 mergedNodesSelectionModel.addSelectionInterval(row-1, row-1);340 }341 }342 343 /**344 * Moves the nodes given by indices in rows down by one position in the list345 * of merged nodes.346 *347 * @param rows the indices348 */349 protected void moveDownMergedNodes(int [] rows) {350 if (rows == null || rows.length == 0) {351 return;352 }353 if (rows[rows.length -1] == mergedNodes.size() -1) {354 // can't move down355 return;356 }357 for (int i = rows.length-1; i>=0;i--) {358 int row = rows[i];359 Node n = mergedNodes.get(row);360 mergedNodes.remove(row);361 mergedNodes.add(row +1, n);362 }363 fireModelDataChanged();364 mergedNodesSelectionModel.clearSelection();365 for (int row: rows) {366 mergedNodesSelectionModel.addSelectionInterval(row+1, row+1);367 }368 }369 370 /**371 * Removes the nodes given by indices in rows from the list372 * of merged nodes.373 *374 * @param rows the indices375 */376 protected void removeMergedNodes(int [] rows) {377 if (rows == null || rows.length == 0) {378 return;379 }380 for (int i = rows.length-1; i>=0;i--) {381 mergedNodes.remove(rows[i]);382 }383 fireModelDataChanged();384 mergedNodesSelectionModel.clearSelection();385 }386 387 388 /**389 * Replies true if the list of my nodes and the list of their390 * nodes are equal, i.e. if they consists of a list of nodes with391 * identical ids in the same order.392 *393 * @return true, if the lists are equal; false otherwise394 */395 protected boolean myAndTheirNodesEqual() {396 if (myNodes.size() != theirNodes.size()) {397 return false;398 }399 for (int i=0; i < myNodes.size(); i++) {400 if (myNodes.get(i).id != theirNodes.get(i).id) {401 return false;402 }403 }404 return true;405 }406 407 19 /** 408 20 * Populates the model with the nodes in the two {@see Way}s <code>my</code> and 409 21 * <code>their</code>. 410 * 411 * @param my my way (i.e. the way in the local dataset) 22 * 23 * @param my my way (i.e. the way in the local dataset) 412 24 * @param their their way (i.e. the way in the server dataset) 413 25 * @exception IllegalArgumentException thrown, if my is null … … 415 27 */ 416 28 public void populate(Way my, Way their) { 417 if (my == null) 29 if (my == null) 418 30 throw new IllegalArgumentException("parameter 'way' must not be null"); 419 if (their == null) 31 if (their == null) 420 32 throw new IllegalArgumentException("parameter 'their' must not be null"); 421 merged Nodes.clear();422 my Nodes.clear();423 their Nodes.clear();33 mergedEntries.clear(); 34 myEntries.clear(); 35 theirEntries.clear(); 424 36 for (Node n : my.nodes) { 425 my Nodes.add(n);37 myEntries.add(n); 426 38 } 427 39 for (Node n : their.nodes) { 428 their Nodes.add(n);40 theirEntries.add(n); 429 41 } 430 if (myAndTheir NodesEqual()) {431 merged Nodes = new ArrayList<Node>(myNodes);42 if (myAndTheirEntriesEqual()) { 43 mergedEntries = new ArrayList<Node>(myEntries); 432 44 setFrozen(true); 433 45 } else { 434 46 setFrozen(false); 435 47 } 436 48 437 49 fireModelDataChanged(); 438 50 } 439 51 440 52 /** 441 53 * Builds the command to resolve conflicts in the node list of a way 442 54 * 443 * @param my my way. Must not be null. 55 * @param my my way. Must not be null. 444 56 * @param their their way. Must not be null 445 57 * @return the command 446 58 * @exception IllegalArgumentException thrown, if my is null or not a {@see Way} 447 59 * @exception IllegalArgumentException thrown, if their is null or not a {@see Way} 448 * @exception IllegalStateException thrown, if the merge is not yet frozen 60 * @exception IllegalStateException thrown, if the merge is not yet frozen 449 61 */ 450 public WayNodesConflictResolverCommand buildResolveCommand(Way my, Way their) { 451 if (my == null) { 452 throw new IllegalArgumentException("parameter my most not be null"); 453 } 454 if (their == null) { 455 throw new IllegalArgumentException("parameter my most not be null"); 456 } 457 if (! isFrozen()) { 62 public WayNodesConflictResolverCommand buildResolveCommand(Way my, Way their) { 63 if (my == null) 64 throw new IllegalArgumentException("parameter my most not be null"); 65 if (their == null) 66 throw new IllegalArgumentException("parameter my most not be null"); 67 if (! isFrozen()) 458 68 throw new IllegalArgumentException("merged nodes not frozen yet. Can't build resolution command"); 459 } 460 return new WayNodesConflictResolverCommand(my, their, mergedNodes); 69 return new WayNodesConflictResolverCommand(my, their, mergedEntries); 461 70 } 462 463 class NodeListTableModel extends DefaultTableModel {464 private ArrayList<Node> nodes;465 466 public NodeListTableModel(ArrayList<Node> nodes) {467 this.nodes = nodes;468 }469 470 @Override471 public int getRowCount() {472 return nodes == null ? 0 : nodes.size();473 }474 475 @Override476 public Object getValueAt(int row, int column) {477 return nodes.get(row);478 }479 480 @Override481 public boolean isCellEditable(int row, int column) {482 return false;483 }484 }485 71 486 72 73 @Override 74 public boolean isEqualEntry(Node e1, Node e2) { 75 return e1.id == e2.id; 76 } 77 78 @Override 79 protected void setValueAt(DefaultTableModel model, Object value, int row, int col) { 80 // do nothing - node list tables are not editable 81 } 82 83 @Override 84 protected Node cloneEntry(Node entry) { 85 Node n = new Node(entry.id); 86 n.cloneFrom(entry); 87 return n; 88 } 487 89 } -
trunk/src/org/openstreetmap/josm/gui/conflict/nodes/NodeListMerger.java
r1626 r1631 1 1 package org.openstreetmap.josm.gui.conflict.nodes; 2 2 3 import static org.openstreetmap.josm.tools.I18n.tr;4 5 import java.awt.GridBagConstraints;6 import java.awt.GridBagLayout;7 import java.awt.event.ActionEvent;8 import java.awt.event.ItemEvent;9 import java.awt.event.ItemListener;10 import java.beans.PropertyChangeEvent;11 import java.beans.PropertyChangeListener;12 import java.net.URL;13 3 import java.util.logging.Logger; 14 4 15 import javax.swing.AbstractAction;16 import javax.swing.Action;17 import javax.swing.ImageIcon;18 import javax.swing.JButton;19 import javax.swing.JLabel;20 import javax.swing.JPanel;21 5 import javax.swing.JScrollPane; 22 6 import javax.swing.JTable; 23 import javax.swing.JToggleButton;24 import javax.swing.event.ListSelectionEvent;25 import javax.swing.event.ListSelectionListener;26 7 8 import org.openstreetmap.josm.data.osm.Node; 27 9 import org.openstreetmap.josm.data.osm.Way; 10 import org.openstreetmap.josm.gui.conflict.ListMerger; 28 11 29 12 /** … … 31 14 * 32 15 */ 33 public class NodeListMerger extends JPanel implements PropertyChangeListener{16 public class NodeListMerger extends ListMerger<Node> { 34 17 private static final Logger logger = Logger.getLogger(NodeListMerger.class.getName()); 35 36 private JTable myNodes;37 private JTable mergedNodes;38 private JTable theirNodes;39 40 private NodeListMergeModel model;41 42 43 private CopyStartLeftAction copyStartLeftAction;44 private CopyBeforeCurrentLeftAction copyBeforeCurrentLeftAction;45 private CopyAfterCurrentLeftAction copyAfterCurrentLeftAction;46 private CopyEndLeftAction copyEndLeftAction;47 18 48 private CopyStartRightAction copyStartRightAction;49 private CopyBeforeCurrentRightAction copyBeforeCurrentRightAction;50 private CopyAfterCurrentRightAction copyAfterCurrentRightAction;51 private CopyEndRightAction copyEndRightAction;52 53 private MoveUpMergedAction moveUpMergedAction;54 private MoveDownMergedAction moveDownMergedAction;55 private RemoveMergedAction removeMergedAction;56 private FreezeAction freezeAction;57 58 19 59 60 protected JScrollPane embeddInScrollPane(JTable table) { 61 JScrollPane pane = new JScrollPane(table); 62 pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 63 pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 64 return pane; 65 } 66 67 protected JScrollPane buildMyNodesTable() { 68 myNodes = new JTable( 69 model.getMyNodesTableModel(), 70 new NodeListColumnModel( 71 new NodeListTableCellRenderer() 72 ), 73 model.getMyNodesSelectionModel() 74 ); 75 myNodes.setName("table.mynodes"); 76 return embeddInScrollPane(myNodes); 20 public NodeListMerger() { 21 super(new NodeListMergeModel()); 77 22 } 78 23 79 protected JScrollPane buildMergedNodesTable() { 80 mergedNodes = new JTable( 81 model.getMergedNodesTableModel(), 82 new NodeListColumnModel( 83 new NodeListTableCellRenderer() 84 ), 85 model.getMergedNodesSelectionModel() 86 ); 87 mergedNodes.setName("table.mergednodes"); 88 return embeddInScrollPane(mergedNodes); 89 } 90 91 protected JScrollPane buildTheirNodesTable() { 92 theirNodes = new JTable( 93 model.getTheirNodesTableModel(), 94 new NodeListColumnModel( 95 new NodeListTableCellRenderer() 96 ), 97 model.getTheirNodesSelectionModel() 98 ); 99 theirNodes.setName("table.theirnodes"); 100 return embeddInScrollPane(theirNodes); 101 } 102 103 protected void wireActionsToSelectionModels() { 104 myNodes.getSelectionModel().addListSelectionListener(copyStartLeftAction); 105 106 myNodes.getSelectionModel().addListSelectionListener(copyBeforeCurrentLeftAction); 107 mergedNodes.getSelectionModel().addListSelectionListener(copyBeforeCurrentLeftAction); 108 109 myNodes.getSelectionModel().addListSelectionListener(copyAfterCurrentLeftAction); 110 mergedNodes.getSelectionModel().addListSelectionListener(copyAfterCurrentLeftAction); 111 112 myNodes.getSelectionModel().addListSelectionListener(copyEndLeftAction); 113 114 115 theirNodes.getSelectionModel().addListSelectionListener(copyStartRightAction); 116 117 theirNodes.getSelectionModel().addListSelectionListener(copyBeforeCurrentRightAction); 118 mergedNodes.getSelectionModel().addListSelectionListener(copyBeforeCurrentRightAction); 119 120 theirNodes.getSelectionModel().addListSelectionListener(copyAfterCurrentRightAction); 121 mergedNodes.getSelectionModel().addListSelectionListener(copyAfterCurrentRightAction); 122 123 theirNodes.getSelectionModel().addListSelectionListener(copyEndRightAction); 124 125 mergedNodes.getSelectionModel().addListSelectionListener(moveUpMergedAction); 126 mergedNodes.getSelectionModel().addListSelectionListener(moveDownMergedAction); 127 mergedNodes.getSelectionModel().addListSelectionListener(removeMergedAction); 128 } 129 130 131 132 protected JPanel buildLeftButtonPanel() { 133 JPanel pnl = new JPanel(); 134 pnl.setLayout(new GridBagLayout()); 135 GridBagConstraints gc = new GridBagConstraints(); 136 137 gc.gridx = 0; 138 gc.gridy = 0; 139 copyStartLeftAction = new CopyStartLeftAction(); 140 JButton btn = new JButton(copyStartLeftAction); 141 btn.setName("button.copystartleft"); 142 pnl.add(btn, gc); 143 144 gc.gridx = 0; 145 gc.gridy = 1; 146 copyBeforeCurrentLeftAction = new CopyBeforeCurrentLeftAction(); 147 btn = new JButton(copyBeforeCurrentLeftAction); 148 btn.setName("button.copybeforecurrentleft"); 149 pnl.add(btn, gc); 150 151 gc.gridx = 0; 152 gc.gridy = 2; 153 copyAfterCurrentLeftAction = new CopyAfterCurrentLeftAction(); 154 btn = new JButton(copyAfterCurrentLeftAction); 155 btn.setName("button.copyaftercurrentleft"); 156 pnl.add(btn, gc); 157 158 gc.gridx = 0; 159 gc.gridy = 3; 160 copyEndLeftAction = new CopyEndLeftAction(); 161 btn = new JButton(copyEndLeftAction); 162 btn.setName("button.copyendleft"); 163 pnl.add(btn, gc); 164 165 166 return pnl; 167 } 168 169 protected JPanel buildRightButtonPanel() { 170 JPanel pnl = new JPanel(); 171 pnl.setLayout(new GridBagLayout()); 172 GridBagConstraints gc = new GridBagConstraints(); 173 174 gc.gridx = 0; 175 gc.gridy = 0; 176 copyStartRightAction = new CopyStartRightAction(); 177 pnl.add(new JButton(copyStartRightAction), gc); 178 179 gc.gridx = 0; 180 gc.gridy = 1; 181 copyBeforeCurrentRightAction = new CopyBeforeCurrentRightAction(); 182 pnl.add(new JButton(copyBeforeCurrentRightAction), gc); 183 184 gc.gridx = 0; 185 gc.gridy = 2; 186 copyAfterCurrentRightAction = new CopyAfterCurrentRightAction(); 187 pnl.add(new JButton(copyAfterCurrentRightAction), gc); 188 189 gc.gridx = 0; 190 gc.gridy = 3; 191 copyEndRightAction = new CopyEndRightAction(); 192 pnl.add(new JButton(copyEndRightAction), gc); 193 194 return pnl; 195 } 196 197 protected JPanel buildMergedListControlButtons() { 198 JPanel pnl = new JPanel(); 199 pnl.setLayout(new GridBagLayout()); 200 GridBagConstraints gc = new GridBagConstraints(); 201 202 gc.gridx = 0; 203 gc.gridy = 0; 204 gc.gridwidth = 1; 205 gc.gridheight = 1; 206 gc.fill = GridBagConstraints.HORIZONTAL; 207 gc.anchor = GridBagConstraints.CENTER; 208 gc.weightx = 0.3; 209 gc.weighty = 0.0; 210 moveUpMergedAction = new MoveUpMergedAction(); 211 pnl.add(new JButton(moveUpMergedAction), gc); 212 213 gc.gridx = 1; 214 gc.gridy = 0; 215 moveDownMergedAction = new MoveDownMergedAction(); 216 pnl.add(new JButton(moveDownMergedAction), gc); 217 218 gc.gridx = 2; 219 gc.gridy = 0; 220 removeMergedAction = new RemoveMergedAction(); 221 pnl.add(new JButton(removeMergedAction), gc); 222 223 gc.gridx = 0; 224 gc.gridy = 1; 225 gc.gridwidth = 3; 226 gc.weightx = 1.0; 227 freezeAction = new FreezeAction(); 228 JToggleButton btn = new JToggleButton(freezeAction); 229 btn.setName("button.freeze"); 230 btn.addItemListener(freezeAction); 231 pnl.add(btn, gc); 232 233 return pnl; 234 } 235 236 237 protected void build() { 238 239 setLayout(new GridBagLayout()); 240 GridBagConstraints gc = new GridBagConstraints(); 241 242 gc.gridx = 0; 243 gc.gridy = 0; 244 gc.gridwidth = 1; 245 gc.gridheight = 1; 246 gc.fill = GridBagConstraints.NONE; 247 gc.anchor = GridBagConstraints.CENTER; 248 gc.weightx = 0.0; 249 gc.weighty = 0.0; 250 JLabel lbl = new JLabel(tr("Nodes in my version (local dataset)")); 251 add(lbl, gc); 252 253 gc.gridx = 2; 254 gc.gridy = 0; 255 gc.gridwidth = 1; 256 gc.gridheight = 1; 257 gc.fill = GridBagConstraints.NONE; 258 gc.anchor = GridBagConstraints.CENTER; 259 gc.weightx = 0.0; 260 gc.weighty = 0.0; 261 lbl = new JLabel(tr("Merged version")); 262 add(lbl, gc); 263 264 gc.gridx = 4; 265 gc.gridy = 0; 266 gc.gridwidth = 1; 267 gc.gridheight = 1; 268 gc.fill = GridBagConstraints.NONE; 269 gc.anchor = GridBagConstraints.CENTER; 270 gc.weightx = 0.0; 271 gc.weighty = 0.0; 272 lbl = new JLabel(tr("Nodes in their version (server dataset)")); 273 add(lbl, gc); 274 275 276 gc.gridx = 0; 277 gc.gridy = 1; 278 gc.gridwidth = 1; 279 gc.gridheight = 1; 280 gc.fill = GridBagConstraints.BOTH; 281 gc.anchor = GridBagConstraints.FIRST_LINE_START; 282 gc.weightx = 0.3; 283 gc.weighty = 1.0; 284 add(buildMyNodesTable(), gc); 285 286 gc.gridx = 1; 287 gc.gridy = 1; 288 gc.gridwidth = 1; 289 gc.gridheight = 1; 290 gc.fill = GridBagConstraints.NONE; 291 gc.anchor = GridBagConstraints.CENTER; 292 gc.weightx = 0.0; 293 gc.weighty = 0.0; 294 add(buildLeftButtonPanel(), gc); 295 296 gc.gridx = 2; 297 gc.gridy = 1; 298 gc.gridwidth = 1; 299 gc.gridheight = 1; 300 gc.fill = GridBagConstraints.BOTH; 301 gc.anchor = GridBagConstraints.FIRST_LINE_START; 302 gc.weightx = 0.3; 303 gc.weighty = 0.0; 304 add(buildMergedNodesTable(), gc); 305 306 gc.gridx = 3; 307 gc.gridy = 1; 308 gc.gridwidth = 1; 309 gc.gridheight = 1; 310 gc.fill = GridBagConstraints.NONE; 311 gc.anchor = GridBagConstraints.CENTER; 312 gc.weightx = 0.0; 313 gc.weighty = 0.0; 314 add(buildRightButtonPanel(), gc); 315 316 gc.gridx = 4; 317 gc.gridy = 1; 318 gc.gridwidth = 1; 319 gc.gridheight = 1; 320 gc.fill = GridBagConstraints.BOTH; 321 gc.anchor = GridBagConstraints.FIRST_LINE_START; 322 gc.weightx = 0.3; 323 gc.weighty = 0.0; 324 add(buildTheirNodesTable(), gc); 325 326 gc.gridx = 2; 327 gc.gridy = 2; 328 gc.gridwidth = 1; 329 gc.gridheight = 1; 330 gc.fill = GridBagConstraints.BOTH; 331 gc.anchor = GridBagConstraints.CENTER; 332 gc.weightx = 0.3; 333 gc.weighty = 0.0; 334 add(buildMergedListControlButtons(), gc); 335 336 wireActionsToSelectionModels(); 337 } 338 339 public NodeListMerger() { 340 model = new NodeListMergeModel(); 341 build(); 342 model.addPropertyChangeListener(this); 343 } 344 345 public void populate(Way my, Way their) { 346 model.populate(my, their); 347 } 348 349 /** 350 * Action for copying selected nodes in the list of my nodes to the list of merged 351 * nodes. Inserts the nodes at the beginning of the list of merged nodes. 352 * 353 */ 354 abstract class AbstractNodeManipulationAction extends AbstractAction { 355 356 /** 357 * load an icon given by iconName 358 * 359 * @param iconName the name of the icon (without path, i.e. <tt>copystartleft.png</tt> 360 * @return the icon; null, if the icon was not found 361 */ 362 protected ImageIcon getIcon(String iconName) { 363 String fullIconName = "/images/dialogs/conflict/" + iconName; 364 URL imageURL = this.getClass().getResource(fullIconName); 365 if (imageURL == null) { 366 System.out.println(tr("WARNING: failed to load resource {0}", fullIconName)); 367 return null; 368 } 369 return new ImageIcon(imageURL); 370 } 24 @Override 25 protected JScrollPane buildMyElementsTable() { 26 myEntriesTable = new JTable( 27 model.getMyTableModel(), 28 new NodeListColumnModel( 29 new NodeListTableCellRenderer() 30 ), 31 model.getMySelectionModel() 32 ); 33 myEntriesTable.setName("table.mynodes"); 34 return embeddInScrollPane(myEntriesTable); 371 35 } 372 36 373 /** 374 * Action for copying selected nodes in the list of my nodes to the list of merged 375 * nodes. Inserts the nodes at the beginning of the list of merged nodes. 376 * 377 */ 378 class CopyStartLeftAction extends AbstractNodeManipulationAction implements ListSelectionListener { 379 380 public CopyStartLeftAction() { 381 ImageIcon icon = getIcon("copystartleft.png"); 382 putValue(Action.SMALL_ICON, icon); 383 if (icon == null) { 384 putValue(Action.NAME, tr("> top")); 385 } 386 putValue(Action.SHORT_DESCRIPTION, tr("Copy my selected nodes to the start of the merged node list")); 387 setEnabled(false); 388 } 389 390 public void actionPerformed(ActionEvent arg0) { 391 int [] rows = myNodes.getSelectedRows(); 392 model.copyMyNodesToTop(rows); 393 } 394 395 public void valueChanged(ListSelectionEvent e) { 396 setEnabled(!myNodes.getSelectionModel().isSelectionEmpty()); 397 } 398 } 399 400 /** 401 * Action for copying selected nodes in the list of my nodes to the list of merged 402 * nodes. Inserts the nodes at the end of the list of merged nodes. 403 * 404 */ 405 class CopyEndLeftAction extends AbstractNodeManipulationAction implements ListSelectionListener { 406 407 public CopyEndLeftAction() { 408 ImageIcon icon = getIcon("copyendleft.png"); 409 putValue(Action.SMALL_ICON, icon); 410 if (icon == null) { 411 putValue(Action.NAME, tr("> bottom")); 412 } 413 putValue(Action.SHORT_DESCRIPTION, tr("Copy my selected nodes to the end of the merged node list")); 414 setEnabled(false); 415 } 416 417 public void actionPerformed(ActionEvent arg0) { 418 int [] rows = myNodes.getSelectedRows(); 419 model.copyMyNodesToEnd(rows); 420 } 421 422 public void valueChanged(ListSelectionEvent e) { 423 setEnabled(!myNodes.getSelectionModel().isSelectionEmpty()); 424 } 425 } 426 427 /** 428 * Action for copying selected nodes in the list of my nodes to the list of merged 429 * nodes. Inserts the nodes before the first selected row in the list of merged nodes. 430 * 431 */ 432 class CopyBeforeCurrentLeftAction extends AbstractNodeManipulationAction implements ListSelectionListener { 433 434 public CopyBeforeCurrentLeftAction() { 435 ImageIcon icon = getIcon("copybeforecurrentleft.png"); 436 putValue(Action.SMALL_ICON, icon); 437 if (icon == null) { 438 putValue(Action.NAME, "> before"); 439 } 440 putValue(Action.SHORT_DESCRIPTION, tr("Copy my selected nodes before the first selected node in the merged node list")); 441 setEnabled(false); 442 } 443 444 public void actionPerformed(ActionEvent arg0) { 445 int [] myRows = myNodes.getSelectedRows(); 446 int [] mergedRows = mergedNodes.getSelectedRows(); 447 if (mergedRows == null || mergedRows.length == 0) { 448 return; 449 } 450 int current = mergedRows[0]; 451 model.copyMyNodesBeforeCurrent(myRows, current); 452 } 453 454 public void valueChanged(ListSelectionEvent e) { 455 setEnabled( 456 !myNodes.getSelectionModel().isSelectionEmpty() 457 && ! mergedNodes.getSelectionModel().isSelectionEmpty() 458 ); 459 } 460 } 461 462 /** 463 * Action for copying selected nodes in the list of my nodes to the list of merged 464 * nodes. Inserts the nodes after the first selected row in the list of merged nodes. 465 * 466 */ 467 class CopyAfterCurrentLeftAction extends AbstractNodeManipulationAction implements ListSelectionListener { 468 469 public CopyAfterCurrentLeftAction() { 470 ImageIcon icon = getIcon("copyaftercurrentleft.png"); 471 putValue(Action.SMALL_ICON, icon); 472 if (icon == null) { 473 putValue(Action.NAME, "> after"); 474 } 475 putValue(Action.SHORT_DESCRIPTION, tr("Copy my selected nodes after the first selected node in the merged node list")); 476 setEnabled(false); 477 } 478 479 public void actionPerformed(ActionEvent arg0) { 480 int [] myRows = myNodes.getSelectedRows(); 481 int [] mergedRows = mergedNodes.getSelectedRows(); 482 if (mergedRows == null || mergedRows.length == 0) { 483 return; 484 } 485 int current = mergedRows[0]; 486 model.copyMyNodesAfterCurrent(myRows, current); 487 } 488 489 public void valueChanged(ListSelectionEvent e) { 490 setEnabled( 491 !myNodes.getSelectionModel().isSelectionEmpty() 492 && ! mergedNodes.getSelectionModel().isSelectionEmpty() 493 ); 494 } 495 } 496 497 498 class CopyStartRightAction extends AbstractNodeManipulationAction implements ListSelectionListener { 499 500 public CopyStartRightAction() { 501 ImageIcon icon = getIcon("copystartright.png"); 502 putValue(Action.SMALL_ICON, icon); 503 if (icon == null) { 504 putValue(Action.NAME, "< top"); 505 } 506 putValue(Action.SHORT_DESCRIPTION, tr("Copy their selected nodes to the start of the merged node list")); 507 setEnabled(false); 508 } 509 510 public void actionPerformed(ActionEvent arg0) { 511 int [] rows = theirNodes.getSelectedRows(); 512 model.copyTheirNodesToTop(rows); 513 } 514 515 public void valueChanged(ListSelectionEvent e) { 516 setEnabled(!theirNodes.getSelectionModel().isSelectionEmpty()); 517 } 518 } 519 520 521 class CopyEndRightAction extends AbstractNodeManipulationAction implements ListSelectionListener { 522 523 public CopyEndRightAction() { 524 ImageIcon icon = getIcon("copyendright.png"); 525 putValue(Action.SMALL_ICON, icon); 526 if (icon == null) { 527 putValue(Action.NAME, "< bottom"); 528 } 529 putValue(Action.SHORT_DESCRIPTION, tr("Copy their selected nodes to the end of the merged node list")); 530 setEnabled(false); 531 } 532 533 public void actionPerformed(ActionEvent arg0) { 534 int [] rows = theirNodes.getSelectedRows(); 535 model.copyTheirNodesToEnd(rows); 536 } 537 538 public void valueChanged(ListSelectionEvent e) { 539 setEnabled(!theirNodes.getSelectionModel().isSelectionEmpty()); 540 } 541 } 542 543 class CopyBeforeCurrentRightAction extends AbstractNodeManipulationAction implements ListSelectionListener { 544 545 public CopyBeforeCurrentRightAction() { 546 ImageIcon icon = getIcon("copybeforecurrentright.png"); 547 putValue(Action.SMALL_ICON, icon); 548 if (icon == null) { 549 putValue(Action.NAME, "< before"); 550 } 551 putValue(Action.SHORT_DESCRIPTION, tr("Copy their selected nodes before the first selected node in the merged node list")); 552 setEnabled(false); 553 } 554 555 public void actionPerformed(ActionEvent arg0) { 556 int [] myRows = theirNodes.getSelectedRows(); 557 int [] mergedRows = mergedNodes.getSelectedRows(); 558 if (mergedRows == null || mergedRows.length == 0) { 559 return; 560 } 561 int current = mergedRows[0]; 562 model.copyTheirNodesBeforeCurrent(myRows, current); 563 } 564 565 public void valueChanged(ListSelectionEvent e) { 566 setEnabled( 567 !theirNodes.getSelectionModel().isSelectionEmpty() 568 && ! mergedNodes.getSelectionModel().isSelectionEmpty() 569 ); 570 } 571 } 572 573 574 class CopyAfterCurrentRightAction extends AbstractNodeManipulationAction implements ListSelectionListener { 575 576 public CopyAfterCurrentRightAction() { 577 ImageIcon icon = getIcon("copyaftercurrentright.png"); 578 putValue(Action.SMALL_ICON, icon); 579 if (icon == null) { 580 putValue(Action.NAME, "< after"); 581 } 582 putValue(Action.SHORT_DESCRIPTION, tr("Copy their selected nodes after the first selected node in the merged node list")); 583 setEnabled(false); 584 } 585 586 public void actionPerformed(ActionEvent arg0) { 587 int [] myRows = theirNodes.getSelectedRows(); 588 int [] mergedRows = mergedNodes.getSelectedRows(); 589 if (mergedRows == null || mergedRows.length == 0) { 590 return; 591 } 592 int current = mergedRows[0]; 593 model.copyTheirNodesAfterCurrent(myRows, current); 594 } 595 596 public void valueChanged(ListSelectionEvent e) { 597 setEnabled( 598 !theirNodes.getSelectionModel().isSelectionEmpty() 599 && ! mergedNodes.getSelectionModel().isSelectionEmpty() 600 ); 601 } 602 } 603 604 605 class MoveUpMergedAction extends AbstractNodeManipulationAction implements ListSelectionListener { 606 607 public MoveUpMergedAction() { 608 ImageIcon icon = getIcon("moveup.png"); 609 putValue(Action.SMALL_ICON, icon); 610 if (icon == null) { 611 putValue(Action.NAME, tr("Up")); 612 } 613 putValue(Action.SHORT_DESCRIPTION, tr("Move up the selected nodes by one position")); 614 setEnabled(false); 615 } 616 617 public void actionPerformed(ActionEvent arg0) { 618 int [] rows = mergedNodes.getSelectedRows(); 619 model.moveUpMergedNodes(rows); 620 } 621 622 public void valueChanged(ListSelectionEvent e) { 623 int [] rows = mergedNodes.getSelectedRows(); 624 setEnabled( 625 rows != null 626 && rows.length > 0 627 && rows[0] != 0 628 ); 629 } 630 } 631 632 class MoveDownMergedAction extends AbstractNodeManipulationAction implements ListSelectionListener { 633 634 public MoveDownMergedAction() { 635 ImageIcon icon = getIcon("movedown.png"); 636 putValue(Action.SMALL_ICON, icon); 637 if (icon == null) { 638 putValue(Action.NAME, tr("Down")); 639 } 640 putValue(Action.SHORT_DESCRIPTION, tr("Move down the selected nodes by one position")); 641 setEnabled(false); 642 } 643 644 public void actionPerformed(ActionEvent arg0) { 645 int [] rows = mergedNodes.getSelectedRows(); 646 model.moveDownMergedNodes(rows); 647 } 648 649 public void valueChanged(ListSelectionEvent e) { 650 int [] rows = mergedNodes.getSelectedRows(); 651 setEnabled( 652 rows != null 653 && rows.length > 0 654 && rows[rows.length -1] != mergedNodes.getRowCount() -1 655 ); 656 } 657 } 658 659 class RemoveMergedAction extends AbstractNodeManipulationAction implements ListSelectionListener { 660 661 public RemoveMergedAction() { 662 ImageIcon icon = getIcon("remove.png"); 663 putValue(Action.SMALL_ICON, icon); 664 if (icon == null) { 665 putValue(Action.NAME, tr("Remove")); 666 } 667 putValue(Action.SHORT_DESCRIPTION, tr("Remove the selected nodes from the list of merged nodes")); 668 setEnabled(false); 669 } 670 671 public void actionPerformed(ActionEvent arg0) { 672 int [] rows = mergedNodes.getSelectedRows(); 673 model.removeMergedNodes(rows); 674 } 675 676 public void valueChanged(ListSelectionEvent e) { 677 int [] rows = mergedNodes.getSelectedRows(); 678 setEnabled( 679 rows != null 680 && rows.length > 0 681 ); 682 } 683 } 684 685 class FreezeAction extends AbstractNodeManipulationAction implements ItemListener { 686 687 public FreezeAction() { 688 // FIXME 689 // ImageIcon icon = getIcon("remove.png"); 690 // putValue(Action.SMALL_ICON, icon); 691 // if (icon == null) { 692 // putValue(Action.NAME, tr("Remove")); 693 // } 694 putValue(Action.NAME, tr("Freeze")); 695 putValue(Action.SHORT_DESCRIPTION, tr("Freeze the current list of merged nodes.")); 696 // putValue(Action.SELECTED_KEY, false); 697 setEnabled(true); 698 699 } 700 701 public void actionPerformed(ActionEvent arg0) { 702 int [] rows = mergedNodes.getSelectedRows(); 703 model.removeMergedNodes(rows); 704 } 705 706 public void itemStateChanged(ItemEvent e) { 707 int state = e.getStateChange(); 708 if (state == ItemEvent.SELECTED) { 709 model.setFrozen(true); 710 putValue(Action.NAME, tr("Unfreeze")); 711 putValue(Action.SHORT_DESCRIPTION, tr("Unfreeze the list of merged nodes and start merging")); 712 } else if (state == ItemEvent.DESELECTED) { 713 model.setFrozen(false); 714 putValue(Action.NAME, tr("Freeze")); 715 putValue(Action.SHORT_DESCRIPTION, tr("Freeze the current list of merged nodes")); 716 } 717 } 37 @Override 38 protected JScrollPane buildMergedElementsTable() { 39 mergedEntriesTable = new JTable( 40 model.getMergedTableModel(), 41 new NodeListColumnModel( 42 new NodeListTableCellRenderer() 43 ), 44 model.getMergedSelectionModel() 45 ); 46 mergedEntriesTable.setName("table.mergednodes"); 47 return embeddInScrollPane(mergedEntriesTable); 718 48 } 719 49 720 protected void handlePropertyChangeFrozen(boolean oldValue, boolean newValue) { 721 myNodes.getSelectionModel().clearSelection(); 722 myNodes.setEnabled(!newValue); 723 theirNodes.getSelectionModel().clearSelection(); 724 theirNodes.setEnabled(!newValue); 725 mergedNodes.getSelectionModel().clearSelection(); 726 mergedNodes.setEnabled(!newValue); 727 // freezeAction.putValue(Action.SELECTED_KEY, newValue); 50 @Override 51 protected JScrollPane buildTheirElementsTable() { 52 theirEntriesTable = new JTable( 53 model.getTheirTableModel(), 54 new NodeListColumnModel( 55 new NodeListTableCellRenderer() 56 ), 57 model.getTheirSelectionModel() 58 ); 59 theirEntriesTable.setName("table.theirnodes"); 60 return embeddInScrollPane(theirEntriesTable); 728 61 } 729 730 public void propertyChange(PropertyChangeEvent evt) { 731 if (evt.getPropertyName().equals(NodeListMergeModel.PROP_FROZEN)) { 732 handlePropertyChangeFrozen((Boolean)evt.getOldValue(), (Boolean)evt.getNewValue()); 733 } 734 735 } 736 737 public NodeListMergeModel getModel() { 738 return model; 62 63 64 public void populate(Way my, Way their) { 65 ((NodeListMergeModel)model).populate(my, their); 739 66 } 740 67 } -
trunk/src/org/openstreetmap/josm/gui/conflict/nodes/NodeListTableCellRenderer.java
r1626 r1631 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.gui.conflict.nodes; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 3 5 4 6 import java.awt.Color; … … 13 15 14 16 import org.openstreetmap.josm.data.osm.Node; 15 import static org.openstreetmap.josm.tools.I18n.tr;16 17 17 18 /** … … 25 26 26 27 /** 27 * Load the image icon for an OSM primitive of type node 28 * Load the image icon for an OSM primitive of type node 28 29 * 29 * @return the icon; null, if not found 30 * @return the icon; null, if not found 30 31 */ 31 32 protected ImageIcon loadIcon() { … … 37 38 return new ImageIcon(url); 38 39 } 39 40 40 41 /** 41 * constructor 42 * constructor 42 43 */ 43 44 public NodeListTableCellRenderer() { … … 45 46 setOpaque(true); 46 47 } 47 48 48 49 /** 49 50 * creates the display name for a node. The name is derived from the nodes id, 50 51 * its name (i.e. the value of the tag with key name) and its coordinates. 51 * 52 * @param node the node 53 * @return the display name 52 * 53 * @param node the node 54 * @return the display name 54 55 */ 55 56 protected String getDisplayName(Node node) { 56 StringBuilder sb = new StringBuilder(); 57 if (node.get("name") != null) { 58 sb.append(node.get("name")); 59 sb.append("/"); 60 sb.append(node.id); 61 } else { 62 sb.append(node.id); 63 } 64 sb.append(" ("); 65 66 if (node.coor != null) { 67 sb.append(COORD_FORMATTER.format(node.coor.lat())); 68 sb.append(","); 69 sb.append(COORD_FORMATTER.format(node.coor.lon())); 70 } else { 71 sb.append("?,?"); 72 } 73 sb.append(")"); 74 return sb.toString(); 57 StringBuilder sb = new StringBuilder(); 58 if (node.get("name") != null) { 59 sb.append(node.get("name")); 60 sb.append("/"); 61 sb.append(node.id); 62 } else { 63 sb.append(node.id); 64 } 65 sb.append(" ("); 66 67 if (node.coor != null) { 68 sb.append(COORD_FORMATTER.format(node.coor.lat())); 69 sb.append(","); 70 sb.append(COORD_FORMATTER.format(node.coor.lon())); 71 } else { 72 sb.append("?,?"); 73 } 74 sb.append(")"); 75 return sb.toString(); 75 76 } 76 77 77 78 /** 78 * reset the renderer 79 * reset the renderer 79 80 */ 80 81 protected void reset() { … … 82 83 setForeground(Color.BLACK); 83 84 } 84 85 85 86 /** 86 * render a node 87 * @param node the node 87 * render a node 88 * @param node the node 88 89 * @param isSelected 89 90 */ … … 91 92 if (isSelected) { 92 93 setBackground(BGCOLOR_SELECTED); 93 } 94 } 94 95 setText(getDisplayName(node)); 95 96 } 96 97 97 98 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 98 99 int row, int column) { 99 100 100 101 Node node = (Node)value; 101 102 reset(); -
trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagMerger.java
r1626 r1631 7 7 import java.awt.GridBagConstraints; 8 8 import java.awt.GridBagLayout; 9 import java.awt.Insets; 9 10 import java.awt.event.ActionEvent; 10 11 import java.awt.event.AdjustmentEvent; … … 29 30 30 31 private JTable mineTable; 31 private JTable undecidedTable;32 private JTable mergedTable; 32 33 private JTable theirTable; 33 private TagMergeModel model; 34 private final TagMergeModel model; 34 35 private JButton btnKeepMine; 35 36 private JButton btnKeepTheir; … … 40 41 pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 41 42 pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 42 43 43 44 adjustmentSynchronizer.synchronizeAdjustment(pane.getVerticalScrollBar()); 44 45 return pane; 45 46 } 46 47 47 48 protected JScrollPane buildMineTagTable() { 48 49 mineTable = new JTable( 49 model, 50 new TagMergeColumnModel( 51 new MineTableCellRenderer() 52 ) 50 model, 51 new TagMergeColumnModel( 52 new MineTableCellRenderer() 53 ) 53 54 ); 55 mineTable.setName("table.my"); 54 56 return embeddInScrollPane(mineTable); 55 57 } … … 57 59 protected JScrollPane buildTheirTable() { 58 60 theirTable = new JTable( 59 model, 60 new TagMergeColumnModel( 61 new TheirTableCellRenderer() 62 ) 63 ); 64 return embeddInScrollPane(theirTable); 65 } 66 61 model, 62 new TagMergeColumnModel( 63 new TheirTableCellRenderer() 64 ) 65 ); 66 theirTable.setName("table.their"); 67 return embeddInScrollPane(theirTable); 68 } 69 67 70 protected JScrollPane buildUndecidedTable() { 68 undecidedTable = new JTable( 69 model, 70 new TagMergeColumnModel( 71 new UndecidedTableCellRenderer() 72 ) 73 ); 74 return embeddInScrollPane(undecidedTable); 75 } 76 71 mergedTable = new JTable( 72 model, 73 new TagMergeColumnModel( 74 new UndecidedTableCellRenderer() 75 ) 76 ); 77 mergedTable.setName("table.merged"); 78 return embeddInScrollPane(mergedTable); 79 } 80 77 81 protected void build() { 78 82 GridBagConstraints gc = new GridBagConstraints(); 79 83 setLayout(new GridBagLayout()); 80 84 81 85 adjustmentSynchronizer = new AdjustmentSynchronizer(); 82 86 83 87 gc.gridx = 0; 84 88 gc.gridy = 0; … … 86 90 gc.gridheight = 1; 87 91 gc.fill = GridBagConstraints.NONE; 88 gc.anchor = GridBagConstraints.CENTER; 89 gc.weightx = 0.0; 90 gc.weighty = 0.0; 92 gc.anchor = GridBagConstraints.CENTER; 93 gc.weightx = 0.0; 94 gc.weighty = 0.0; 95 gc.insets = new Insets(10,0,10,0); 91 96 JLabel lbl = new JLabel(tr("My version (local dataset)")); 92 97 add(lbl, gc); … … 111 116 gc.weightx = 0.0; 112 117 gc.weighty = 0.0; 118 gc.insets = new Insets(0,0,0,0); 113 119 lbl = new JLabel(tr("Their version (server dataset)")); 114 120 add(lbl, gc); … … 123 129 gc.weighty = 1.0; 124 130 add(buildMineTagTable(), gc); 125 131 126 132 gc.gridx = 1; 127 133 gc.gridy = 1; … … 135 141 mineTable.getSelectionModel().addListSelectionListener(keepMineAction); 136 142 btnKeepMine = new JButton(keepMineAction); 143 btnKeepMine.setName("button.keepmine"); 137 144 add(btnKeepMine, gc); 138 145 139 146 gc.gridx = 2; 140 147 gc.gridy = 1; … … 146 153 gc.weighty = 1.0; 147 154 add(buildUndecidedTable(), gc); 148 155 149 156 gc.gridx = 3; 150 157 gc.gridy = 1; … … 157 164 KeepTheirAction keepTheirAction = new KeepTheirAction(); 158 165 btnKeepTheir = new JButton(keepTheirAction); 166 btnKeepTheir.setName("button.keeptheir"); 159 167 add(btnKeepTheir, gc); 160 168 161 169 gc.gridx = 4; 162 170 gc.gridy = 1; … … 169 177 add(buildTheirTable(), gc); 170 178 theirTable.getSelectionModel().addListSelectionListener(keepTheirAction); 171 172 179 180 173 181 DoubleClickAdapter dblClickAdapter = new DoubleClickAdapter(); 174 182 mineTable.addMouseListener(dblClickAdapter); 175 183 theirTable.addMouseListener(dblClickAdapter); 176 177 184 185 178 186 gc.gridx = 2; 179 187 gc.gridy = 2; … … 185 193 gc.weighty = 0.0; 186 194 UndecideAction undecidedAction = new UndecideAction(); 187 undecidedTable.getSelectionModel().addListSelectionListener(undecidedAction);195 mergedTable.getSelectionModel().addListSelectionListener(undecidedAction); 188 196 JButton btnUndecide = new JButton(undecidedAction); 197 btnUndecide.setName("button.undecide"); 189 198 add(btnUndecide, gc); 190 191 } 192 199 200 } 201 193 202 public TagMerger() { 194 203 model = new TagMergeModel(); 195 204 build(); 196 205 } 197 198 206 199 207 public TagMergeModel getModel() { 200 208 return model; 201 209 } 202 210 203 211 protected ImageIcon loadIcon(String name) { 204 String path = "/images/dialogs/conflict/" + name; 205 URL url = this.getClass().getResource(path); 206 if (url == null) { 207 System.out.println(tr("WARNING: failed to load resource {0}", path)); 208 return null; 209 } 210 return new ImageIcon(url); 211 } 212 212 String path = "/images/dialogs/conflict/" + name; 213 URL url = this.getClass().getResource(path); 214 if (url == null) { 215 System.out.println(tr("WARNING: failed to load resource {0}", path)); 216 return null; 217 } 218 return new ImageIcon(url); 219 } 220 213 221 class KeepMineAction extends AbstractAction implements ListSelectionListener { 214 222 215 223 216 224 public KeepMineAction() { 217 225 ImageIcon icon = loadIcon("tagkeepmine.png"); … … 225 233 setEnabled(false); 226 234 } 227 235 228 236 public void actionPerformed(ActionEvent arg0) { 229 237 int rows[] = mineTable.getSelectedRows(); 230 if (rows == null || rows.length == 0) { 231 return; 232 } 233 model.decide(rows, MergeDecisionType.KEEP_MINE); 238 if (rows == null || rows.length == 0) 239 return; 240 model.decide(rows, MergeDecisionType.KEEP_MINE); 234 241 } 235 242 236 243 public void valueChanged(ListSelectionEvent e) { 237 setEnabled(mineTable.getSelectedRowCount() > 0); 238 } 239 } 240 244 setEnabled(mineTable.getSelectedRowCount() > 0); 245 } 246 } 247 241 248 class KeepTheirAction extends AbstractAction implements ListSelectionListener { 242 249 243 250 public KeepTheirAction() { 244 251 ImageIcon icon = loadIcon("tagkeeptheir.png"); … … 252 259 setEnabled(false); 253 260 } 254 261 255 262 public void actionPerformed(ActionEvent arg0) { 256 263 int rows[] = theirTable.getSelectedRows(); 257 if (rows == null || rows.length == 0) { 258 return; 259 } 260 model.decide(rows, MergeDecisionType.KEEP_THEIR); 264 if (rows == null || rows.length == 0) 265 return; 266 model.decide(rows, MergeDecisionType.KEEP_THEIR); 261 267 } 262 268 263 269 public void valueChanged(ListSelectionEvent e) { 264 setEnabled(theirTable.getSelectedRowCount() > 0); 265 } 266 } 267 270 setEnabled(theirTable.getSelectedRowCount() > 0); 271 } 272 } 273 268 274 class AdjustmentSynchronizer implements AdjustmentListener { 269 private ArrayList<Adjustable> synchronizedAdjustables; 270 275 private final ArrayList<Adjustable> synchronizedAdjustables; 276 271 277 public AdjustmentSynchronizer() { 272 278 synchronizedAdjustables = new ArrayList<Adjustable>(); 273 279 } 274 280 275 281 public void synchronizeAdjustment(Adjustable adjustable) { 276 if (adjustable == null) { 277 return; 278 } 279 if (synchronizedAdjustables.contains(adjustable)) { 280 return; 281 } 282 if (adjustable == null) 283 return; 284 if (synchronizedAdjustables.contains(adjustable)) 285 return; 282 286 synchronizedAdjustables.add(adjustable); 283 287 adjustable.addAdjustmentListener(this); … … 292 296 } 293 297 } 294 298 295 299 class DoubleClickAdapter extends MouseAdapter { 296 300 301 @Override 297 302 public void mouseClicked(MouseEvent e) { 298 if (e.getClickCount() != 2) { 299 return; 300 } 303 if (e.getClickCount() != 2) 304 return; 301 305 JTable table = null; 302 306 MergeDecisionType mergeDecision; 303 307 304 308 if (e.getSource() == mineTable) { 305 table = (JTable)mineTable;309 table = mineTable; 306 310 mergeDecision = MergeDecisionType.KEEP_MINE; 307 311 } else if (e.getSource() == theirTable) { 308 table = (JTable)theirTable;312 table = theirTable; 309 313 mergeDecision = MergeDecisionType.KEEP_THEIR; 310 } else if (e.getSource() == undecidedTable) {311 table = (JTable)undecidedTable;314 } else if (e.getSource() == mergedTable) { 315 table = mergedTable; 312 316 mergeDecision = MergeDecisionType.UNDECIDED; 313 } else {317 } else 314 318 // double click in another component; shouldn't happen, 315 // but just in case 316 return; 317 } 319 // but just in case 320 return; 318 321 int row = table.rowAtPoint(e.getPoint()); 319 322 model.decide(row, mergeDecision); 320 323 } 321 } 322 324 } 325 323 326 class UndecideAction extends AbstractAction implements ListSelectionListener { 324 327 … … 334 337 setEnabled(false); 335 338 } 336 339 337 340 public void actionPerformed(ActionEvent arg0) { 338 int rows[] = undecidedTable.getSelectedRows(); 339 if (rows == null || rows.length == 0) { 340 return; 341 } 342 model.decide(rows, MergeDecisionType.UNDECIDED); 341 int rows[] = mergedTable.getSelectedRows(); 342 if (rows == null || rows.length == 0) 343 return; 344 model.decide(rows, MergeDecisionType.UNDECIDED); 343 345 } 344 346 345 347 public void valueChanged(ListSelectionEvent e) { 346 setEnabled( undecidedTable.getSelectedRowCount() > 0);347 } 348 setEnabled(mergedTable.getSelectedRowCount() > 0); 349 } 348 350 } 349 351 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictResolutionDialog.java
r1627 r1631 10 10 import java.awt.Point; 11 11 import java.awt.event.ActionEvent; 12 import java.net.URL;13 12 import java.util.logging.Logger; 14 13 … … 16 15 import javax.swing.Action; 17 16 import javax.swing.BorderFactory; 18 import javax.swing.ImageIcon;19 17 import javax.swing.JButton; 20 18 import javax.swing.JDialog; … … 25 23 import org.openstreetmap.josm.command.Command; 26 24 import org.openstreetmap.josm.gui.conflict.ConflictResolver; 25 import org.openstreetmap.josm.tools.ImageProvider; 27 26 27 /** 28 * This is an extended dialog for resolving conflict between {@see OsmPrimitive}. 29 * 30 * 31 */ 28 32 public class ConflictResolutionDialog extends JDialog { 29 33 private static final Logger logger = Logger.getLogger(ConflictResolutionDialog.class.getName()); 30 34 public final static Dimension DEFAULT_SIZE = new Dimension(600,400); 31 35 36 /** the conflict resolver component */ 32 37 private ConflictResolver resolver; 33 38 39 /** 40 * restore position and size on screen from preference settings 41 * 42 */ 34 43 protected void restorePositionAndDimension() { 35 44 Point p = new Point(); … … 39 48 p.x = Math.max(0,p.x); 40 49 } catch(Exception e) { 41 logger.warning("unexpected value for preference conflictresolutiondialog.x, assuming 0"); 50 logger.warning("unexpected value for preference conflictresolutiondialog.x, assuming 0"); 42 51 p.x = 0; 43 52 } … … 46 55 p.y = Math.max(0,p.y); 47 56 } catch(Exception e) { 48 logger.warning("unexpected value for preference conflictresolutiondialog.x, assuming 0"); 57 logger.warning("unexpected value for preference conflictresolutiondialog.x, assuming 0"); 49 58 p.y = 0; 50 59 } … … 53 62 d.width = Math.max(0,d.width); 54 63 } catch(Exception e) { 55 logger.warning("unexpected value for preference conflictresolutiondialog.width, assuming " + DEFAULT_SIZE.width); 64 logger.warning("unexpected value for preference conflictresolutiondialog.width, assuming " + DEFAULT_SIZE.width); 56 65 p.y = 0; 57 66 } … … 60 69 d.height = Math.max(0,d.height); 61 70 } catch(Exception e) { 62 logger.warning("unexpected value for preference conflictresolutiondialog.height, assuming " + + DEFAULT_SIZE.height); 71 logger.warning("unexpected value for preference conflictresolutiondialog.height, assuming " + + DEFAULT_SIZE.height); 63 72 p.y = 0; 64 73 } 65 74 66 75 setLocation(p); 67 76 setSize(d); 68 77 } 69 78 79 /** 80 * remember position and size on screen in the preferences 81 * 82 */ 70 83 protected void rememberPositionAndDimension() { 71 84 Point p = getLocation(); 72 85 Main.pref.put("conflictresolutiondialog.x", Integer.toString(p.x)); 73 86 Main.pref.put("conflictresolutiondialog.y", Integer.toString(p.y)); 74 87 75 88 Dimension d = getSize(); 76 89 Main.pref.put("conflictresolutiondialog.width", Integer.toString(d.width)); 77 90 Main.pref.put("conflictresolutiondialog.height", Integer.toString(d.height)); 78 91 } 79 92 93 94 @Override 80 95 public void setVisible(boolean isVisible) { 81 96 if (isVisible){ … … 86 101 super.setVisible(isVisible); 87 102 } 88 103 104 /** 105 * builds the sub panel with the control buttons 106 * 107 * @return the panel 108 */ 89 109 protected JPanel buildButtonRow() { 90 110 JPanel pnl = new JPanel(); 91 111 pnl.setLayout(new FlowLayout(FlowLayout.RIGHT)); 92 112 93 113 JButton btn = new JButton(new CancelAction()); 94 114 btn.setName("button.cancel"); 95 115 pnl.add(btn); 96 116 97 117 btn = new JButton(new ApplyResolutionAction()); 98 118 btn.setName("button.apply"); 99 119 pnl.add(btn); 100 120 101 121 pnl.setBorder(BorderFactory.createLoweredBevelBorder()); 102 122 return pnl; 103 123 } 104 124 125 /** 126 * builds the GUI 127 */ 105 128 protected void build() { 106 setTitle(tr("Resolve conflicts")); 107 getContentPane().setLayout(new BorderLayout()); 108 109 resolver = new ConflictResolver(); 110 getContentPane().add(resolver, BorderLayout.CENTER); 111 getContentPane().add(buildButtonRow(), BorderLayout.SOUTH); 129 setTitle(tr("Resolve conflicts")); 130 getContentPane().setLayout(new BorderLayout()); 131 132 resolver = new ConflictResolver(); 133 resolver.setName("panel.conflictresolver"); 134 getContentPane().add(resolver, BorderLayout.CENTER); 135 getContentPane().add(buildButtonRow(), BorderLayout.SOUTH); 112 136 } 113 114 137 138 115 139 public ConflictResolutionDialog(Component parent) { 116 140 super(JOptionPane.getFrameForComponent(parent), true /* modal */); 117 141 build(); 118 142 } 119 143 120 144 public ConflictResolver getConflictResolver() { 121 145 return resolver; 122 146 } 123 124 protected ImageIcon getIcon(String iconPath) {125 URL imageURL = this.getClass().getResource(iconPath);126 if (imageURL == null) {127 System.out.println(tr("WARNING: failed to load resource {0}", iconPath));128 return null;129 }130 return new ImageIcon(imageURL);131 }132 147 133 134 148 class CancelAction extends AbstractAction { 135 136 public CancelAction() { 149 public CancelAction() { 137 150 putValue(Action.SHORT_DESCRIPTION, tr("Cancel conflict resolution and close the dialog")); 138 151 putValue(Action.NAME, tr("Cancel")); 139 putValue(Action.SMALL_ICON, getIcon("/images/cancel.png"));152 putValue(Action.SMALL_ICON, ImageProvider.get("", "cancel")); 140 153 setEnabled(true); 141 154 } 142 155 143 156 144 157 public void actionPerformed(ActionEvent arg0) { 145 158 setVisible(false); 146 } 147 } 148 149 class ApplyResolutionAction extends AbstractAction { 159 } 160 } 161 162 class ApplyResolutionAction extends AbstractAction { 150 163 public ApplyResolutionAction() { 151 164 putValue(Action.SHORT_DESCRIPTION, tr("Apply resolved conflicts and close the dialog")); 152 165 putValue(Action.NAME, tr("Apply Resolution")); 153 putValue(Action.SMALL_ICON, getIcon("/images/dialogs/conflict.png"));154 setEnabled(true); 166 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs", "conflict")); 167 setEnabled(true); 155 168 } 156 169 157 158 170 public void actionPerformed(ActionEvent arg0) { 159 171 Command cmd = resolver.buildResolveCommand(); 160 172 Main.main.undoRedo.add(cmd); 161 173 setVisible(false); 162 } 174 } 163 175 } 164 176 }
Note:
See TracChangeset
for help on using the changeset viewer.