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

Last change on this file since 4077 was 3767, checked in by stoecker, 13 years ago

fix help

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