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

Last change on this file since 2621 was 2621, checked in by Gubaer, 15 years ago

Moved layer listener management from Layer to MapView
Made sure that listeners also unregister when they register for layer change events.

This will certainly break plugins. Plugin updates will follow later.

File size: 9.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Component;
8import java.awt.Dimension;
9import java.awt.FlowLayout;
10import java.awt.Point;
11import java.awt.event.ActionEvent;
12import java.beans.PropertyChangeEvent;
13import java.beans.PropertyChangeListener;
14import java.util.logging.Logger;
15
16import javax.swing.AbstractAction;
17import javax.swing.Action;
18import javax.swing.BorderFactory;
19import javax.swing.JButton;
20import javax.swing.JDialog;
21import javax.swing.JOptionPane;
22import javax.swing.JPanel;
23
24import org.openstreetmap.josm.Main;
25import org.openstreetmap.josm.command.Command;
26import org.openstreetmap.josm.data.osm.OsmPrimitive;
27import org.openstreetmap.josm.gui.DefaultNameFormatter;
28import org.openstreetmap.josm.gui.conflict.pair.ConflictResolver;
29import org.openstreetmap.josm.gui.conflict.pair.properties.OperationCancelledException;
30import org.openstreetmap.josm.gui.help.HelpBrowserProxy;
31import org.openstreetmap.josm.gui.help.HelpUtil;
32import org.openstreetmap.josm.tools.ImageProvider;
33
34/**
35 * This is an extended dialog for resolving conflict between {@see OsmPrimitive}s.
36 *
37 */
38public class ConflictResolutionDialog extends JDialog implements PropertyChangeListener {
39 private static final Logger logger = Logger.getLogger(ConflictResolutionDialog.class.getName());
40 public final static Dimension DEFAULT_SIZE = new Dimension(600,400);
41
42 /** the conflict resolver component */
43 private ConflictResolver resolver;
44
45 /**
46 * restore position and size on screen from preference settings
47 *
48 */
49 protected void restorePositionAndDimension() {
50 Point p = new Point();
51 Dimension d = new Dimension();
52 try {
53 p.x = Integer.parseInt(Main.pref.get("conflictresolutiondialog.x", "0"));
54 p.x = Math.max(0,p.x);
55 } catch(Exception e) {
56 logger.warning("unexpected value for preference conflictresolutiondialog.x, assuming 0");
57 p.x = 0;
58 }
59 try {
60 p.y = Integer.parseInt(Main.pref.get("conflictresolutiondialog.y", "0"));
61 p.y = Math.max(0,p.y);
62 } catch(Exception e) {
63 logger.warning("unexpected value for preference conflictresolutiondialog.x, assuming 0");
64 p.y = 0;
65 }
66 try {
67 d.width = Integer.parseInt(Main.pref.get("conflictresolutiondialog.width", Integer.toString(DEFAULT_SIZE.width)));
68 d.width = Math.max(0,d.width);
69 } catch(Exception e) {
70 logger.warning("unexpected value for preference conflictresolutiondialog.width, assuming " + DEFAULT_SIZE.width);
71 p.y = 0;
72 }
73 try {
74 d.height = Integer.parseInt(Main.pref.get("conflictresolutiondialog.height", Integer.toString(DEFAULT_SIZE.height)));
75 d.height = Math.max(0,d.height);
76 } catch(Exception e) {
77 logger.warning("unexpected value for preference conflictresolutiondialog.height, assuming " + + DEFAULT_SIZE.height);
78 p.y = 0;
79 }
80
81 setLocation(p);
82 setSize(d);
83 }
84
85 /**
86 * remember position and size on screen in the preferences
87 *
88 */
89 protected void rememberPositionAndDimension() {
90 Point p = getLocation();
91 Main.pref.put("conflictresolutiondialog.x", Integer.toString(p.x));
92 Main.pref.put("conflictresolutiondialog.y", Integer.toString(p.y));
93
94 Dimension d = getSize();
95 Main.pref.put("conflictresolutiondialog.width", Integer.toString(d.width));
96 Main.pref.put("conflictresolutiondialog.height", Integer.toString(d.height));
97 }
98
99 @Override
100 public void setVisible(boolean isVisible) {
101 if (isVisible){
102 restorePositionAndDimension();
103 toFront();
104 } else {
105 rememberPositionAndDimension();
106 }
107 super.setVisible(isVisible);
108 }
109
110 /**
111 * builds the sub panel with the control buttons
112 *
113 * @return the panel
114 */
115 protected JPanel buildButtonRow() {
116 JPanel pnl = new JPanel();
117 pnl.setLayout(new FlowLayout(FlowLayout.CENTER));
118
119 ApplyResolutionAction applyResolutionAction = new ApplyResolutionAction();
120 resolver.addPropertyChangeListener(applyResolutionAction);
121 JButton btn = new JButton(applyResolutionAction);
122 btn.setName("button.apply");
123 pnl.add(btn);
124
125 btn = new JButton(new CancelAction());
126 btn.setName("button.cancel");
127 pnl.add(btn);
128
129 btn = new JButton(new HelpAction());
130 btn.setName("button.help");
131 pnl.add(btn);
132
133 pnl.setBorder(BorderFactory.createLoweredBevelBorder());
134 return pnl;
135 }
136
137 /**
138 * builds the GUI
139 */
140 protected void build() {
141 updateTitle();
142 getContentPane().setLayout(new BorderLayout());
143
144 resolver = new ConflictResolver();
145 resolver.setName("panel.conflictresolver");
146 getContentPane().add(resolver, BorderLayout.CENTER);
147 getContentPane().add(buildButtonRow(), BorderLayout.SOUTH);
148
149 resolver.addPropertyChangeListener(this);
150 HelpUtil.setHelpContext(this.getRootPane(), "Dialog/ConflictDialog");
151 }
152
153 public ConflictResolutionDialog(Component parent) {
154 super(JOptionPane.getFrameForComponent(parent), true /* modal */);
155 build();
156 }
157
158 public ConflictResolver getConflictResolver() {
159 return resolver;
160 }
161
162 /**
163 * Action for canceling conflict resolution
164 */
165 class CancelAction extends AbstractAction {
166 public CancelAction() {
167 putValue(Action.SHORT_DESCRIPTION, tr("Cancel conflict resolution and close the dialog"));
168 putValue(Action.NAME, tr("Cancel"));
169 putValue(Action.SMALL_ICON, ImageProvider.get("", "cancel"));
170 setEnabled(true);
171 }
172
173 public void actionPerformed(ActionEvent arg0) {
174 setVisible(false);
175 }
176 }
177
178 /**
179 * Action for canceling conflict resolution
180 */
181 class HelpAction extends AbstractAction {
182 public HelpAction() {
183 putValue(Action.SHORT_DESCRIPTION, tr("Show help information"));
184 putValue(Action.NAME, tr("Help"));
185 putValue(Action.SMALL_ICON, ImageProvider.get("help"));
186 setEnabled(true);
187 }
188
189 public void actionPerformed(ActionEvent arg0) {
190 HelpBrowserProxy.getInstance().setUrlForHelpTopic("/Dialog/ConflictDialog");
191 }
192 }
193
194 /**
195 * Action for applying resolved differences in a conflict
196 *
197 */
198 class ApplyResolutionAction extends AbstractAction implements PropertyChangeListener {
199 public ApplyResolutionAction() {
200 putValue(Action.SHORT_DESCRIPTION, tr("Apply resolved conflicts and close the dialog"));
201 putValue(Action.NAME, tr("Apply Resolution"));
202 putValue(Action.SMALL_ICON, ImageProvider.get("dialogs", "conflict"));
203 updateEnabledState();
204 }
205
206 protected void updateEnabledState() {
207 setEnabled(resolver.isResolvedCompletely());
208 }
209
210 public void actionPerformed(ActionEvent arg0) {
211 if (! resolver.isResolvedCompletely()) {
212 Object[] options = {
213 tr("Close anyway"),
214 tr("Continue resolving")};
215 int ret = JOptionPane.showOptionDialog(Main.parent,
216 tr("<html>You didn''t finish to merge the differences in this conflict.<br>"
217 + "Conflict resolutions won't be applied unless all differences<br>"
218 + "are resolved."
219 + "Click <strong>{0}</strong> to close anyway.<strong>Already<br>"
220 + "resolved differences won't be applied.</strong><br>"
221 + "Click <strong>{1}</strong> to return to resolving conflicts.</html>"
222 , options[0].toString(), options[1].toString()
223 ),
224 tr("Conflict not resolved completely"),
225 JOptionPane.YES_NO_OPTION,
226 JOptionPane.WARNING_MESSAGE,
227 null,
228 options,
229 options[1]
230 );
231 switch(ret) {
232 case JOptionPane.YES_OPTION:
233 setVisible(false);
234 break;
235 default:
236 return;
237 }
238 }
239 try {
240 Command cmd = resolver.buildResolveCommand();
241 Main.main.undoRedo.add(cmd);
242 setVisible(false);
243 } catch(OperationCancelledException e) {
244 // do nothing. Exception already reported
245 }
246 }
247
248 public void propertyChange(PropertyChangeEvent evt) {
249 if (evt.getPropertyName().equals(ConflictResolver.RESOLVED_COMPLETELY_PROP)) {
250 updateEnabledState();
251 }
252 }
253 }
254
255 protected void updateTitle() {
256 updateTitle(null);
257 }
258
259 protected void updateTitle(OsmPrimitive my) {
260 if (my == null) {
261 setTitle(tr("Resolve conflicts"));
262 } else {
263 setTitle(tr("Resolve conflicts for ''{0}''", my.getDisplayName(DefaultNameFormatter.getInstance())));
264 }
265 }
266
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.