Ignore:
Timestamp:
2014-10-29T20:52:03+01:00 (10 years ago)
Author:
donvip
Message:

[josm-merge_overlap] update to JOSM 7674

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/merge-overlap/src/mergeoverlap/hack/MyCombinePrimitiveResolverDialog.java

    r30766 r30778  
    22package mergeoverlap.hack;
    33
    4 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    5 import static org.openstreetmap.josm.tools.I18n.tr;
    6 
    7 import java.awt.BorderLayout;
    84import java.awt.Component;
    9 import java.awt.Dimension;
    10 import java.awt.FlowLayout;
    11 import java.awt.event.ActionEvent;
    12 import java.awt.event.HierarchyBoundsListener;
    13 import java.awt.event.HierarchyEvent;
    14 import java.awt.event.WindowAdapter;
    15 import java.awt.event.WindowEvent;
    165import java.beans.PropertyChangeEvent;
    17 import java.beans.PropertyChangeListener;
    18 import java.util.HashSet;
    196import java.util.LinkedList;
    207import java.util.List;
    218import java.util.Map;
    22 import java.util.Set;
    239
    24 import javax.swing.AbstractAction;
    25 import javax.swing.Action;
    26 import javax.swing.JDialog;
    27 import javax.swing.JLabel;
    28 import javax.swing.JOptionPane;
    2910import javax.swing.JPanel;
    30 import javax.swing.JSplitPane;
    3111
    3212import org.openstreetmap.josm.Main;
    3313import org.openstreetmap.josm.command.ChangePropertyCommand;
    3414import org.openstreetmap.josm.command.Command;
    35 import org.openstreetmap.josm.data.osm.Node;
    3615import org.openstreetmap.josm.data.osm.OsmPrimitive;
    3716import org.openstreetmap.josm.data.osm.Relation;
    3817import org.openstreetmap.josm.data.osm.TagCollection;
    3918import org.openstreetmap.josm.data.osm.Way;
    40 import org.openstreetmap.josm.gui.DefaultNameFormatter;
    41 import org.openstreetmap.josm.gui.SideButton;
    42 import org.openstreetmap.josm.gui.conflict.tags.MultiValueResolutionDecision;
    43 import org.openstreetmap.josm.gui.conflict.tags.RelationMemberConflictDecision;
    44 import org.openstreetmap.josm.gui.conflict.tags.RelationMemberConflictDecisionType;
     19import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog;
    4520import org.openstreetmap.josm.gui.conflict.tags.RelationMemberConflictResolver;
    46 import org.openstreetmap.josm.gui.conflict.tags.TagConflictResolver;
    47 import org.openstreetmap.josm.gui.conflict.tags.TagConflictResolverModel;
    48 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
    49 import org.openstreetmap.josm.gui.help.HelpUtil;
    5021import org.openstreetmap.josm.gui.util.GuiHelper;
    51 import org.openstreetmap.josm.tools.ImageProvider;
    52 import org.openstreetmap.josm.tools.WindowGeometry;
    5322
    5423/**
     
    7948 * see {@link #buildResolutionCommands()}
    8049 */
    81 public class MyCombinePrimitiveResolverDialog extends JDialog {
     50public class MyCombinePrimitiveResolverDialog extends CombinePrimitiveResolverDialog {
    8251
    8352    /** the unique instance of the dialog */
     
    10069    }
    10170
    102     private AutoAdjustingSplitPane spTagConflictTypes;
    103     private TagConflictResolver pnlTagConflictResolver;
    104     private RelationMemberConflictResolver pnlRelationMemberConflictResolver;
    105     private boolean canceled;
    106     private JPanel pnlButtons;
    107     private OsmPrimitive targetPrimitive;
    108 
    109     /** the private help action */
    110     private ContextSensitiveHelpAction helpAction;
    111     /** the apply button */
    112     private SideButton btnApply;
    113 
    114     /**
    115      * Replies the target primitive the collection of primitives is merged
    116      * or combined to.
    117      *
    118      * @return the target primitive
    119      */
    120     public OsmPrimitive getTargetPrimitmive() {
    121         return targetPrimitive;
    122     }
    123 
    124     /**
    125      * Sets the primitive the collection of primitives is merged or combined to.
    126      *
    127      * @param primitive the target primitive
    128      */
    129     public void setTargetPrimitive(final OsmPrimitive primitive) {
    130         this.targetPrimitive = primitive;
    131         GuiHelper.runInEDTAndWait(new Runnable() {
    132             @Override public void run() {
    133                 updateTitle();
    134                 if (primitive instanceof Way) {
    135                     pnlRelationMemberConflictResolver.initForWayCombining();
    136                 } else if (primitive instanceof Node) {
    137                     pnlRelationMemberConflictResolver.initForNodeMerging();
    138                 }
    139             }
    140         });
    141     }
    142 
    143     protected void updateTitle() {
    144         if (targetPrimitive == null) {
    145             setTitle(tr("Conflicts when combining primitives"));
    146             return;
    147         }
    148         if (targetPrimitive instanceof Way) {
    149             setTitle(tr("Conflicts when combining ways - combined way is ''{0}''", targetPrimitive
    150                     .getDisplayName(DefaultNameFormatter.getInstance())));
    151             helpAction.setHelpTopic(ht("/Action/CombineWay#ResolvingConflicts"));
    152             getRootPane().putClientProperty("help", ht("/Action/CombineWay#ResolvingConflicts"));
    153         } else if (targetPrimitive instanceof Node) {
    154             setTitle(tr("Conflicts when merging nodes - target node is ''{0}''", targetPrimitive
    155                     .getDisplayName(DefaultNameFormatter.getInstance())));
    156             helpAction.setHelpTopic(ht("/Action/MergeNodes#ResolvingConflicts"));
    157             getRootPane().putClientProperty("help", ht("/Action/MergeNodes#ResolvingConflicts"));
    158         }
    159     }
    160 
    161     protected final void build() {
    162         getContentPane().setLayout(new BorderLayout());
    163         updateTitle();
    164         spTagConflictTypes = new AutoAdjustingSplitPane(JSplitPane.VERTICAL_SPLIT);
    165         spTagConflictTypes.setTopComponent(buildTagConflictResolverPanel());
    166         spTagConflictTypes.setBottomComponent(buildRelationMemberConflictResolverPanel());
    167         getContentPane().add(pnlButtons = buildButtonPanel(), BorderLayout.SOUTH);
    168         addWindowListener(new AdjustDividerLocationAction());
    169         HelpUtil.setHelpContext(getRootPane(), ht("/"));
    170     }
    171 
    172     protected JPanel buildTagConflictResolverPanel() {
    173         pnlTagConflictResolver = new TagConflictResolver();
    174         return pnlTagConflictResolver;
    175     }
    176 
     71    @Override
    17772    protected JPanel buildRelationMemberConflictResolverPanel() {
    17873        pnlRelationMemberConflictResolver = new RelationMemberConflictResolver(new MyRelationMemberConflictResolverModel());
     
    18075    }
    18176
    182     protected JPanel buildButtonPanel() {
    183         JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
    184 
    185         // -- apply button
    186         ApplyAction applyAction = new ApplyAction();
    187         pnlTagConflictResolver.getModel().addPropertyChangeListener(applyAction);
    188         pnlRelationMemberConflictResolver.getModel().addPropertyChangeListener(applyAction);
    189         btnApply = new SideButton(applyAction);
    190         btnApply.setFocusable(true);
    191         pnl.add(btnApply);
    192 
    193         // -- cancel button
    194         CancelAction cancelAction = new CancelAction();
    195         pnl.add(new SideButton(cancelAction));
    196 
    197         // -- help button
    198         helpAction = new ContextSensitiveHelpAction();
    199         pnl.add(new SideButton(helpAction));
    200 
    201         return pnl;
     77    @Override
     78    protected ApplyAction buildApplyAction() {
     79        return new ApplyAction() {
     80            @Override
     81            public void propertyChange(PropertyChangeEvent evt) {
     82                super.propertyChange(evt);
     83                if (evt.getPropertyName().equals(MyRelationMemberConflictResolverModel.NUM_CONFLICTS_PROP)) {
     84                    updateEnabledState();
     85                }
     86            }
     87        };
    20288    }
    20389
     
    20793     */
    20894    public MyCombinePrimitiveResolverDialog(Component parent) {
    209         super(JOptionPane.getFrameForComponent(parent), ModalityType.DOCUMENT_MODAL);
    210         build();
    211     }
    212 
    213     /**
    214      * Replies the tag conflict resolver model.
    215      * @return The tag conflict resolver model.
    216      */
    217     public TagConflictResolverModel getTagConflictResolverModel() {
    218         return pnlTagConflictResolver.getModel();
     95        super(parent);
    21996    }
    22097
     
    223100     * @return The relation membership conflict resolver model.
    224101     */
     102    @Override
    225103    public MyRelationMemberConflictResolverModel getRelationMemberConflictResolverModel() {
    226104        return (MyRelationMemberConflictResolverModel) pnlRelationMemberConflictResolver.getModel();
    227105    }
    228106
    229     protected List<Command> buildTagChangeCommand(OsmPrimitive primitive, TagCollection tc) {
    230         LinkedList<Command> cmds = new LinkedList<>();
    231         for (String key : tc.getKeys()) {
    232             if (tc.hasUniqueEmptyValue(key)) {
    233                 if (primitive.get(key) != null) {
    234                     cmds.add(new ChangePropertyCommand(primitive, key, null));
    235                 }
    236             } else {
    237                 String value = tc.getJoinedValues(key);
    238                 if (!value.equals(primitive.get(key))) {
    239                     cmds.add(new ChangePropertyCommand(primitive, key, value));
    240                 }
    241             }
    242         }
    243         return cmds;
    244     }
    245 
     107    /**
     108     * Replies the list of {@link Command commands} needed to apply resolution choices.
     109     * @return The list of {@link Command commands} needed to apply resolution choices.
     110     */
    246111    public List<Command> buildWayResolutionCommands() {
    247112        List<Command> cmds = new LinkedList<>();
     
    266131        getRelationMemberConflictResolverModel().buildRelationCorrespondance(targetPrimitive, newRelations, oldWays);
    267132    }
    268    
    269     protected void prepareDefaultTagDecisions() {
    270         TagConflictResolverModel model = getTagConflictResolverModel();
    271         for (int i = 0; i < model.getRowCount(); i++) {
    272             MultiValueResolutionDecision decision = model.getDecision(i);
    273             List<String> values = decision.getValues();
    274             values.remove("");
    275             if (values.size() == 1) {
    276                 decision.keepOne(values.get(0));
    277             } else {
    278                 decision.keepAll();
    279             }
    280         }
    281         model.rebuild();
    282     }
    283 
    284     protected void prepareDefaultRelationDecisions() {
    285         MyRelationMemberConflictResolverModel model = getRelationMemberConflictResolverModel();
    286         Set<Relation> relations = new HashSet<>();
    287         for (int i = 0; i < model.getNumDecisions(); i++) {
    288             RelationMemberConflictDecision decision = model.getDecision(i);
    289             if (!relations.contains(decision.getRelation())) {
    290                 decision.decide(RelationMemberConflictDecisionType.KEEP);
    291                 relations.add(decision.getRelation());
    292             } else {
    293                 decision.decide(RelationMemberConflictDecisionType.REMOVE);
    294             }
    295         }
    296         model.refresh();
    297     }
    298 
    299     /**
    300      * Prepares the default decisions for populated tag and relation membership conflicts.
    301      */
    302     public void prepareDefaultDecisions() {
    303         prepareDefaultTagDecisions();
    304         prepareDefaultRelationDecisions();
    305     }
    306 
    307     protected JPanel buildEmptyConflictsPanel() {
    308         JPanel pnl = new JPanel(new BorderLayout());
    309         pnl.add(new JLabel(tr("No conflicts to resolve")));
    310         return pnl;
    311     }
    312 
    313     protected void prepareGUIBeforeConflictResolutionStarts() {
    314         MyRelationMemberConflictResolverModel relModel = getRelationMemberConflictResolverModel();
    315         TagConflictResolverModel tagModel = getTagConflictResolverModel();
    316         getContentPane().removeAll();
    317 
    318         if (relModel.getNumDecisions() > 0 && tagModel.getNumDecisions() > 0) {
    319             // display both, the dialog for resolving relation conflicts and for resolving tag conflicts
    320             spTagConflictTypes.setTopComponent(pnlTagConflictResolver);
    321             spTagConflictTypes.setBottomComponent(pnlRelationMemberConflictResolver);
    322             getContentPane().add(spTagConflictTypes, BorderLayout.CENTER);
    323         } else if (relModel.getNumDecisions() > 0) {
    324             // relation conflicts only
    325             getContentPane().add(pnlRelationMemberConflictResolver, BorderLayout.CENTER);
    326         } else if (tagModel.getNumDecisions() > 0) {
    327             // tag conflicts only
    328             getContentPane().add(pnlTagConflictResolver, BorderLayout.CENTER);
    329         } else {
    330             getContentPane().add(buildEmptyConflictsPanel(), BorderLayout.CENTER);
    331         }
    332 
    333         getContentPane().add(pnlButtons, BorderLayout.SOUTH);
    334         validate();
    335         int numTagDecisions = getTagConflictResolverModel().getNumDecisions();
    336         int numRelationDecisions = getRelationMemberConflictResolverModel().getNumDecisions();
    337         if (numTagDecisions > 0 && numRelationDecisions > 0) {
    338             spTagConflictTypes.setDividerLocation(0.5);
    339         }
    340         pnlRelationMemberConflictResolver.prepareForEditing();
    341     }
    342 
    343     protected void setCanceled(boolean canceled) {
    344         this.canceled = canceled;
    345     }
    346 
    347     /**
    348      * Determines if this dialog has been cancelled.
    349      * @return true if this dialog has been cancelled, false otherwise.
    350      */
    351     public boolean isCanceled() {
    352         return canceled;
    353     }
    354 
    355     @Override
    356     public void setVisible(boolean visible) {
    357         if (visible) {
    358             prepareGUIBeforeConflictResolutionStarts();
    359             new WindowGeometry(getClass().getName() + ".geometry", WindowGeometry.centerInWindow(Main.parent,
    360                     new Dimension(600, 400))).applySafe(this);
    361             setCanceled(false);
    362             btnApply.requestFocusInWindow();
    363         } else if (isShowing()) { // Avoid IllegalComponentStateException like in #8775
    364             new WindowGeometry(this).remember(getClass().getName() + ".geometry");
    365         }
    366         super.setVisible(visible);
    367     }
    368 
    369     class CancelAction extends AbstractAction {
    370 
    371         public CancelAction() {
    372             putValue(Action.SHORT_DESCRIPTION, tr("Cancel conflict resolution"));
    373             putValue(Action.NAME, tr("Cancel"));
    374             putValue(Action.SMALL_ICON, ImageProvider.get("", "cancel"));
    375             setEnabled(true);
    376         }
    377 
    378         @Override
    379         public void actionPerformed(ActionEvent arg0) {
    380             setCanceled(true);
    381             setVisible(false);
    382         }
    383     }
    384 
    385     class ApplyAction extends AbstractAction implements PropertyChangeListener {
    386 
    387         public ApplyAction() {
    388             putValue(Action.SHORT_DESCRIPTION, tr("Apply resolved conflicts"));
    389             putValue(Action.NAME, tr("Apply"));
    390             putValue(Action.SMALL_ICON, ImageProvider.get("ok"));
    391             updateEnabledState();
    392         }
    393 
    394         @Override
    395         public void actionPerformed(ActionEvent arg0) {
    396             setVisible(false);
    397             pnlTagConflictResolver.rememberPreferences();
    398         }
    399 
    400         protected final void updateEnabledState() {
    401             setEnabled(pnlTagConflictResolver.getModel().getNumConflicts() == 0
    402                     && pnlRelationMemberConflictResolver.getModel().getNumConflicts() == 0);
    403         }
    404 
    405         @Override
    406         public void propertyChange(PropertyChangeEvent evt) {
    407             if (evt.getPropertyName().equals(TagConflictResolverModel.NUM_CONFLICTS_PROP)) {
    408                 updateEnabledState();
    409             }
    410             if (evt.getPropertyName().equals(MyRelationMemberConflictResolverModel.NUM_CONFLICTS_PROP)) {
    411                 updateEnabledState();
    412             }
    413         }
    414     }
    415 
    416     class AdjustDividerLocationAction extends WindowAdapter {
    417         @Override
    418         public void windowOpened(WindowEvent e) {
    419             int numTagDecisions = getTagConflictResolverModel().getNumDecisions();
    420             int numRelationDecisions = getRelationMemberConflictResolverModel().getNumDecisions();
    421             if (numTagDecisions > 0 && numRelationDecisions > 0) {
    422                 spTagConflictTypes.setDividerLocation(0.5);
    423             }
    424         }
    425     }
    426 
    427     static class AutoAdjustingSplitPane extends JSplitPane implements PropertyChangeListener, HierarchyBoundsListener {
    428         private double dividerLocation;
    429 
    430         public AutoAdjustingSplitPane(int newOrientation) {
    431             super(newOrientation);
    432             addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, this);
    433             addHierarchyBoundsListener(this);
    434         }
    435 
    436         @Override
    437         public void ancestorResized(HierarchyEvent e) {
    438             setDividerLocation((int) (dividerLocation * getHeight()));
    439         }
    440 
    441         @Override
    442         public void ancestorMoved(HierarchyEvent e) {
    443             // do nothing
    444         }
    445 
    446         @Override
    447         public void propertyChange(PropertyChangeEvent evt) {
    448             if (evt.getPropertyName().equals(JSplitPane.DIVIDER_LOCATION_PROPERTY)) {
    449                 int newVal = (Integer) evt.getNewValue();
    450                 if (getHeight() != 0) {
    451                     dividerLocation = (double) newVal / (double) getHeight();
    452                 }
    453             }
    454         }
    455     }
    456133}
Note: See TracChangeset for help on using the changeset viewer.