source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictResolutionDialog.java@ 10357

Last change on this file since 10357 was 10357, checked in by stoecker, 8 years ago

see #9995, see #10684 - remove more hardcoded places of images

  • Property svn:eol-style set to native
File size: 8.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.BorderLayout;
8import java.awt.Component;
9import java.awt.Dimension;
10import java.awt.FlowLayout;
11import java.awt.event.ActionEvent;
12import java.beans.PropertyChangeEvent;
13import java.beans.PropertyChangeListener;
14
15import javax.swing.AbstractAction;
16import javax.swing.Action;
17import javax.swing.BorderFactory;
18import javax.swing.JButton;
19import javax.swing.JDialog;
20import javax.swing.JLabel;
21import javax.swing.JOptionPane;
22import javax.swing.JPanel;
23import javax.swing.WindowConstants;
24
25import org.openstreetmap.josm.Main;
26import org.openstreetmap.josm.command.Command;
27import org.openstreetmap.josm.data.osm.OsmPrimitive;
28import org.openstreetmap.josm.gui.DefaultNameFormatter;
29import org.openstreetmap.josm.gui.conflict.pair.ConflictResolver;
30import org.openstreetmap.josm.gui.help.HelpBrowser;
31import org.openstreetmap.josm.gui.help.HelpUtil;
32import org.openstreetmap.josm.gui.util.GuiHelper;
33import org.openstreetmap.josm.tools.ImageProvider;
34import org.openstreetmap.josm.tools.WindowGeometry;
35
36/**
37 * This is an extended dialog for resolving conflict between {@link OsmPrimitive}s.
38 * @since 1622
39 */
40public class ConflictResolutionDialog extends JDialog implements PropertyChangeListener {
41 /** the conflict resolver component */
42 private ConflictResolver resolver;
43 private JLabel titleLabel;
44
45 private ApplyResolutionAction applyResolutionAction;
46
47 @Override
48 public void removeNotify() {
49 super.removeNotify();
50 unregisterListeners();
51 }
52
53 @Override
54 public void setVisible(boolean isVisible) {
55 String geom = getClass().getName() + ".geometry";
56 if (isVisible) {
57 toFront();
58 new WindowGeometry(geom, WindowGeometry.centerInWindow(Main.parent,
59 new Dimension(600, 400))).applySafe(this);
60 } else {
61 if (isShowing()) { // Avoid IllegalComponentStateException like in #8775
62 new WindowGeometry(this).remember(geom);
63 }
64 unregisterListeners();
65 }
66 super.setVisible(isVisible);
67 }
68
69 private void closeDialog() {
70 setVisible(false);
71 dispose();
72 }
73
74 /**
75 * builds the sub panel with the control buttons
76 *
77 * @return the panel
78 */
79 protected JPanel buildButtonRow() {
80 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
81
82 applyResolutionAction = new ApplyResolutionAction();
83 JButton btn = new JButton(applyResolutionAction);
84 btn.setName("button.apply");
85 pnl.add(btn);
86
87 btn = new JButton(new CancelAction());
88 btn.setName("button.cancel");
89 pnl.add(btn);
90
91 btn = new JButton(new HelpAction());
92 btn.setName("button.help");
93 pnl.add(btn);
94
95 pnl.setBorder(BorderFactory.createLoweredBevelBorder());
96 return pnl;
97 }
98
99 private void registerListeners() {
100 resolver.addPropertyChangeListener(applyResolutionAction);
101 }
102
103 private void unregisterListeners() {
104 resolver.removePropertyChangeListener(applyResolutionAction);
105 resolver.unregisterListeners();
106 }
107
108 /**
109 * builds the GUI
110 */
111 protected void build() {
112 setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
113 getContentPane().setLayout(new BorderLayout());
114
115 titleLabel = new JLabel();
116 titleLabel.setHorizontalAlignment(JLabel.CENTER);
117 getContentPane().add(titleLabel, BorderLayout.NORTH);
118
119 updateTitle();
120
121 resolver = new ConflictResolver();
122 resolver.setName("panel.conflictresolver");
123 getContentPane().add(resolver, BorderLayout.CENTER);
124 getContentPane().add(buildButtonRow(), BorderLayout.SOUTH);
125
126 resolver.addPropertyChangeListener(this);
127 HelpUtil.setHelpContext(this.getRootPane(), ht("Dialog/Conflict"));
128
129 registerListeners();
130 }
131
132 /**
133 * Constructs a new {@code ConflictResolutionDialog}.
134 * @param parent parent component
135 */
136 public ConflictResolutionDialog(Component parent) {
137 super(GuiHelper.getFrameForComponent(parent), ModalityType.DOCUMENT_MODAL);
138 build();
139 pack();
140 if (getInsets().top > 0) {
141 titleLabel.setVisible(false);
142 }
143 }
144
145 /**
146 * Replies the conflict resolver component.
147 * @return the conflict resolver component
148 */
149 public ConflictResolver getConflictResolver() {
150 return resolver;
151 }
152
153 /**
154 * Action for canceling conflict resolution
155 */
156 class CancelAction extends AbstractAction {
157 CancelAction() {
158 putValue(Action.SHORT_DESCRIPTION, tr("Cancel conflict resolution and close the dialog"));
159 putValue(Action.NAME, tr("Cancel"));
160 new ImageProvider("cancel").getResource().getImageIcon(this);
161 setEnabled(true);
162 }
163
164 @Override
165 public void actionPerformed(ActionEvent arg0) {
166 closeDialog();
167 }
168 }
169
170 /**
171 * Action for canceling conflict resolution
172 */
173 static class HelpAction extends AbstractAction {
174 HelpAction() {
175 putValue(Action.SHORT_DESCRIPTION, tr("Show help information"));
176 putValue(Action.NAME, tr("Help"));
177 new ImageProvider("help").getResource().getImageIcon(this);
178 setEnabled(true);
179 }
180
181 @Override
182 public void actionPerformed(ActionEvent arg0) {
183 HelpBrowser.setUrlForHelpTopic(ht("/Dialog/Conflict"));
184 }
185 }
186
187 /**
188 * Action for applying resolved differences in a conflict
189 *
190 */
191 class ApplyResolutionAction extends AbstractAction implements PropertyChangeListener {
192 ApplyResolutionAction() {
193 putValue(Action.SHORT_DESCRIPTION, tr("Apply resolved conflicts and close the dialog"));
194 putValue(Action.NAME, tr("Apply Resolution"));
195 new ImageProvider("dialogs", "conflict").getResource().getImageIcon(this);
196 updateEnabledState();
197 }
198
199 protected void updateEnabledState() {
200 setEnabled(resolver.isResolvedCompletely());
201 }
202
203 @Override
204 public void actionPerformed(ActionEvent arg0) {
205 if (!resolver.isResolvedCompletely()) {
206 Object[] options = {
207 tr("Close anyway"),
208 tr("Continue resolving")};
209 int ret = JOptionPane.showOptionDialog(Main.parent,
210 tr("<html>You did not finish to merge the differences in this conflict.<br>"
211 + "Conflict resolutions will not be applied unless all differences<br>"
212 + "are resolved.<br>"
213 + "Click <strong>{0}</strong> to close anyway.<strong> Already<br>"
214 + "resolved differences will not be applied.</strong><br>"
215 + "Click <strong>{1}</strong> to return to resolving conflicts.</html>",
216 options[0].toString(), options[1].toString()
217 ),
218 tr("Conflict not resolved completely"),
219 JOptionPane.YES_NO_OPTION,
220 JOptionPane.WARNING_MESSAGE,
221 null,
222 options,
223 options[1]
224 );
225 switch(ret) {
226 case JOptionPane.YES_OPTION:
227 closeDialog();
228 break;
229 default:
230 return;
231 }
232 }
233 Command cmd = resolver.buildResolveCommand();
234 Main.main.undoRedo.add(cmd);
235 closeDialog();
236 }
237
238 @Override
239 public void propertyChange(PropertyChangeEvent evt) {
240 if (evt.getPropertyName().equals(ConflictResolver.RESOLVED_COMPLETELY_PROP)) {
241 updateEnabledState();
242 }
243 }
244 }
245
246 protected void updateTitle() {
247 updateTitle(null);
248 }
249
250 protected void updateTitle(OsmPrimitive my) {
251 if (my == null) {
252 setTitle(tr("Resolve conflicts"));
253 } else {
254 setTitle(tr("Resolve conflicts for ''{0}''", my.getDisplayName(DefaultNameFormatter.getInstance())));
255 }
256 }
257
258 @Override
259 public void setTitle(String title) {
260 super.setTitle(title);
261 if (titleLabel != null) {
262 titleLabel.setText(title);
263 }
264 }
265
266 @Override
267 public void propertyChange(PropertyChangeEvent evt) {
268 if (evt.getPropertyName().equals(ConflictResolver.MY_PRIMITIVE_PROP)) {
269 updateTitle((OsmPrimitive) evt.getNewValue());
270 }
271 }
272}
Note: See TracBrowser for help on using the repository browser.