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

Last change on this file since 3501 was 3501, checked in by bastiK, 14 years ago

fixed #4632 - Button Help puts help window under main window

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