source: osm/applications/editors/josm/plugins/reltoolbox/src/relcontext/RelContextDialog.java@ 29535

Last change on this file since 29535 was 29535, checked in by donvip, 11 years ago

[josm_reltoolbox] Fix some warnings

File size: 30.8 KB
Line 
1package relcontext;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.awt.BorderLayout;
6import java.awt.Color;
7import java.awt.Component;
8import java.awt.Dialog.ModalityType;
9import java.awt.Dimension;
10import java.awt.GridBagLayout;
11import java.awt.Point;
12import java.awt.event.ActionEvent;
13import java.awt.event.ActionListener;
14import java.awt.event.ItemEvent;
15import java.awt.event.ItemListener;
16import java.awt.event.KeyEvent;
17import java.awt.event.MouseAdapter;
18import java.awt.event.MouseEvent;
19import java.awt.event.MouseListener;
20import java.beans.PropertyChangeEvent;
21import java.beans.PropertyChangeListener;
22import java.io.BufferedReader;
23import java.io.InputStream;
24import java.io.InputStreamReader;
25import java.util.ArrayList;
26import java.util.Collection;
27import java.util.Collections;
28import java.util.HashMap;
29import java.util.List;
30import java.util.Map;
31import java.util.Set;
32import java.util.StringTokenizer;
33import java.util.TreeSet;
34
35import javax.swing.AbstractListModel;
36import javax.swing.Action;
37import javax.swing.Box;
38import javax.swing.ComboBoxModel;
39import javax.swing.JButton;
40import javax.swing.JCheckBoxMenuItem;
41import javax.swing.JComboBox;
42import javax.swing.JComponent;
43import javax.swing.JDialog;
44import javax.swing.JLabel;
45import javax.swing.JOptionPane;
46import javax.swing.JPanel;
47import javax.swing.JPopupMenu;
48import javax.swing.JScrollPane;
49import javax.swing.JTable;
50import javax.swing.ListSelectionModel;
51import javax.swing.SwingUtilities;
52import javax.swing.event.ListSelectionEvent;
53import javax.swing.event.ListSelectionListener;
54import javax.swing.table.DefaultTableCellRenderer;
55import javax.swing.table.DefaultTableModel;
56import javax.swing.table.TableColumnModel;
57
58import org.openstreetmap.josm.Main;
59import org.openstreetmap.josm.actions.JosmAction;
60import org.openstreetmap.josm.command.ChangeRelationMemberRoleCommand;
61import org.openstreetmap.josm.command.Command;
62import org.openstreetmap.josm.command.SequenceCommand;
63import org.openstreetmap.josm.data.SelectionChangedListener;
64import org.openstreetmap.josm.data.osm.OsmPrimitive;
65import org.openstreetmap.josm.data.osm.Relation;
66import org.openstreetmap.josm.data.osm.RelationMember;
67import org.openstreetmap.josm.data.osm.event.DatasetEventManager;
68import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
69import org.openstreetmap.josm.data.osm.event.SelectionEventManager;
70import org.openstreetmap.josm.gui.DefaultNameFormatter;
71import org.openstreetmap.josm.gui.MapView;
72import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
73import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
74import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
75import org.openstreetmap.josm.gui.layer.OsmDataLayer;
76import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingComboBox;
77import org.openstreetmap.josm.tools.GBC;
78import org.openstreetmap.josm.tools.Shortcut;
79
80import relcontext.actions.AddRemoveMemberAction;
81import relcontext.actions.ClearChosenRelationAction;
82import relcontext.actions.CreateMultipolygonAction;
83import relcontext.actions.CreateRelationAction;
84import relcontext.actions.DeleteChosenRelationAction;
85import relcontext.actions.DownloadChosenRelationAction;
86import relcontext.actions.DownloadParentsAction;
87import relcontext.actions.DuplicateChosenRelationAction;
88import relcontext.actions.EditChosenRelationAction;
89import relcontext.actions.FindRelationAction;
90import relcontext.actions.ReconstructPolygonAction;
91import relcontext.actions.RelationHelpAction;
92import relcontext.actions.SelectInRelationPanelAction;
93import relcontext.actions.SelectMembersAction;
94import relcontext.actions.SelectRelationAction;
95import relcontext.actions.SortAndFixAction;
96
97/**
98 * The new, advanced relation editing panel.
99 *
100 * @author Zverik
101 */
102public class RelContextDialog extends ToggleDialog implements EditLayerChangeListener, ChosenRelationListener, SelectionChangedListener {
103
104 public final static String PREF_PREFIX = "reltoolbox";
105
106 private final DefaultTableModel relationsData;
107 private ChosenRelation chosenRelation;
108 private JPanel chosenRelationPanel;
109 private ChosenRelationPopupMenu popupMenu;
110 private MultipolygonSettingsPopup multiPopupMenu;
111 private RoleComboBoxModel roleBoxModel;
112 private SortAndFixAction sortAndFixAction;
113 // actions saved for unregistering on dialog destroying
114 private final EnterRoleAction enterRoleAction;
115 private final FindRelationAction findRelationAction;
116 private final CreateMultipolygonAction createMultipolygonAction;
117 private final CreateRelationAction createRelationAction;
118 private final AddRemoveMemberAction addRemoveMemberAction;
119
120 public RelContextDialog() {
121 super(tr("Relation Toolbox"), PREF_PREFIX, tr("Open relation/multipolygon editor panel"), null, 150, true);
122
123 chosenRelation = new ChosenRelation();
124 chosenRelation.addChosenRelationListener(this);
125 MapView.addEditLayerChangeListener(chosenRelation);
126
127 popupMenu = new ChosenRelationPopupMenu(chosenRelation);
128 multiPopupMenu = new MultipolygonSettingsPopup();
129
130 JPanel rcPanel = new JPanel(new BorderLayout());
131
132 relationsData = new RelationTableModel();
133 relationsData.setColumnIdentifiers(new String[] {tr("Member Of"), tr("Role")});
134 final JTable relationsTable = new JTable(relationsData);
135 configureRelationsTable(relationsTable);
136 rcPanel.add(new JScrollPane(relationsTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.CENTER);
137
138 final MouseListener relationMouseAdapter = new ChosenRelationMouseAdapter();
139 final JComboBox roleBox = new JComboBox();
140 roleBoxModel = new RoleComboBoxModel(roleBox);
141 roleBox.setModel(roleBoxModel);
142 roleBox.addMouseListener(relationMouseAdapter);
143 roleBox.addItemListener(new ItemListener() {
144 public void itemStateChanged( ItemEvent e ) {
145 if( e.getStateChange() == ItemEvent.DESELECTED ) return;
146 String memberRole = roleBoxModel.getSelectedMembersRole();
147 String selectedRole = roleBoxModel.isAnotherRoleSelected() ? askForRoleName() : roleBoxModel.getSelectedRole();
148 if( memberRole != null && selectedRole != null && !memberRole.equals(selectedRole) ) {
149 applyRoleToSelection(selectedRole.trim());
150 }
151 }
152 });
153 roleBox.setVisible(false);
154 enterRoleAction = new EnterRoleAction(); // just for the shortcut
155 sortAndFixAction = new SortAndFixAction(chosenRelation);
156
157 // [±][X] relation U [AZ][Down][Edit]
158 chosenRelationPanel = new JPanel(new GridBagLayout());
159 addRemoveMemberAction = new AddRemoveMemberAction(chosenRelation, sortAndFixAction);
160 chosenRelationPanel.add(new JButton(addRemoveMemberAction), GBC.std());
161 chosenRelationPanel.add(sizeButton(new JButton(new ClearChosenRelationAction(chosenRelation)), 32, 0), GBC.std());
162 final ChosenRelationComponent chosenRelationComponent = new ChosenRelationComponent(chosenRelation);
163 chosenRelationComponent.addMouseListener(relationMouseAdapter);
164 chosenRelationPanel.add(chosenRelationComponent, GBC.std().fill().insets(5, 0, 5, 0));
165 chosenRelationPanel.add(roleBox, GBC.std().fill().insets(5, 0, 5, 0));
166 final JButton sortAndFixButton = (JButton) sizeButton(new JButton(sortAndFixAction), 32, 0);
167 chosenRelationPanel.add(sortAndFixButton, GBC.std().fill(GBC.VERTICAL));
168 final Action downloadChosenRelationAction = new DownloadChosenRelationAction(chosenRelation);
169 final JButton downloadButton = (JButton) sizeButton(new JButton(downloadChosenRelationAction), 32, 0);
170 chosenRelationPanel.add(downloadButton, GBC.std().fill(GBC.VERTICAL));
171 chosenRelationPanel.add(new JButton(new EditChosenRelationAction(chosenRelation)), GBC.eol().fill(GBC.VERTICAL));
172
173 rcPanel.add(chosenRelationPanel, BorderLayout.NORTH);
174
175 roleBox.addPropertyChangeListener("enabled", new PropertyChangeListener() {
176 public void propertyChange( PropertyChangeEvent evt ) {
177 boolean showRoleBox = roleBox.isEnabled();
178 roleBox.setVisible(showRoleBox);
179 chosenRelationComponent.setVisible(!showRoleBox);
180 }
181 });
182
183 sortAndFixAction.addPropertyChangeListener(new PropertyChangeListener() {
184 public void propertyChange( PropertyChangeEvent evt ) {
185 sortAndFixButton.setVisible(sortAndFixAction.isEnabled());
186 }
187 });
188 sortAndFixButton.setVisible(false);
189
190 downloadChosenRelationAction.addPropertyChangeListener(new PropertyChangeListener() {
191 public void propertyChange( PropertyChangeEvent evt ) {
192 downloadButton.setVisible(downloadChosenRelationAction.isEnabled());
193 }
194 });
195 downloadButton.setVisible(false);
196 if( Main.pref.getBoolean(PREF_PREFIX + ".hidetopline", false) )
197 chosenRelationPanel.setVisible(false);
198
199 // [+][Multi] [X]Adm [X]Tags [X]1
200 JPanel bottomLine = new JPanel(new GridBagLayout());
201 createRelationAction = new CreateRelationAction(chosenRelation);
202 bottomLine.add(new JButton(createRelationAction), GBC.std());
203 createMultipolygonAction = new CreateMultipolygonAction(chosenRelation);
204 final JButton multipolygonButton = new JButton(createMultipolygonAction);
205 bottomLine.add(multipolygonButton, GBC.std());
206// bottomLine.add(sizeButton(new JButton(new MultipolygonSettingsAction()), 16, 0), GBC.std().fill(GBC.VERTICAL));
207 bottomLine.add(Box.createHorizontalGlue(), GBC.std().fill());
208 findRelationAction = new FindRelationAction(chosenRelation);
209 bottomLine.add(new JButton(findRelationAction), GBC.eol());
210 rcPanel.add(sizeButton(bottomLine, 0, 24), BorderLayout.SOUTH);
211
212 multipolygonButton.addMouseListener(new MouseAdapter() {
213 @Override
214 public void mousePressed( MouseEvent e ) {
215 checkPopup(e);
216 }
217
218 @Override
219 public void mouseReleased( MouseEvent e ) {
220 checkPopup(e);
221 }
222
223 private void checkPopup( MouseEvent e ) {
224 if( e.isPopupTrigger() )
225 multiPopupMenu.show(e.getComponent(), e.getX(), e.getY());
226 }
227 });
228
229 createLayout(rcPanel, false, null);
230 }
231
232 private static final Color CHOSEN_RELATION_COLOR = new Color(255, 255, 128);
233
234 private void configureRelationsTable( final JTable relationsTable ) {
235 relationsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
236 relationsTable.setTableHeader(null);
237 relationsTable.addMouseListener(new MouseAdapter() {
238 @Override
239 public void mouseClicked( MouseEvent e ) {
240 Point p = e.getPoint();
241 int row = relationsTable.rowAtPoint(p);
242 if( SwingUtilities.isLeftMouseButton(e) && row >= 0 ) {
243 Relation relation = (Relation)relationsData.getValueAt(row, 0);
244 if( e.getClickCount() > 1 ) {
245 Main.map.mapView.getEditLayer().data.setSelected(relation);
246 }
247 }
248 }
249
250 @Override
251 public void mousePressed( MouseEvent e ) {
252 checkPopup(e);
253 }
254
255 @Override
256 public void mouseReleased( MouseEvent e ) {
257 checkPopup(e);
258 }
259
260 public void checkPopup( MouseEvent e ) {
261 if( e.isPopupTrigger() ) {
262 Point p = e.getPoint();
263 int row = relationsTable.rowAtPoint(p);
264 if (row > -1) {
265 Relation relation = (Relation)relationsData.getValueAt(row, 0);
266 JPopupMenu menu = chosenRelation.isSame(relation) ? popupMenu
267 : new ChosenRelationPopupMenu(new StaticChosenRelation(relation));
268 menu.show(relationsTable, p.x, p.y-5);
269 }
270 }
271 }
272 });
273
274 TableColumnModel columns = relationsTable.getColumnModel();
275 columns.getColumn(0).setCellRenderer(new OsmPrimitivRenderer() {
276 @Override
277 protected String getComponentToolTipText( OsmPrimitive value ) {
278 return null;
279 }
280
281 @Override
282 public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) {
283 Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
284 if( !isSelected && value instanceof Relation && chosenRelation.isSame(value) )
285 c.setBackground(CHOSEN_RELATION_COLOR);
286 else
287 c.setBackground(table.getBackground());
288 return c;
289 }
290
291 });
292 columns.getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
293 @Override
294 public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) {
295 Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
296 if( !isSelected && chosenRelation.isSame(table.getValueAt(row, 0)) )
297 c.setBackground(CHOSEN_RELATION_COLOR);
298 else
299 c.setBackground(table.getBackground());
300 return c;
301 }
302 });
303 columns.getColumn(1).setPreferredWidth(40);
304 columns.getColumn(0).setPreferredWidth(220);
305 relationsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
306 public void valueChanged( ListSelectionEvent e ) {
307 int selectedRow = relationsTable.getSelectedRow();
308 if( selectedRow >= 0 ) {
309 chosenRelation.set((Relation)relationsData.getValueAt(selectedRow, 0));
310 relationsTable.clearSelection();
311 }
312 }
313 });
314 }
315
316 private JComponent sizeButton( JComponent b, int width, int height ) {
317 Dimension pref = b.getPreferredSize();
318 b.setPreferredSize(new Dimension(width <= 0 ? pref.width : width, height <= 0 ? pref.height : height));
319 return b;
320 }
321
322 @Override
323 public void hideNotify() {
324 SelectionEventManager.getInstance().removeSelectionListener(this);
325 MapView.removeEditLayerChangeListener(this);
326 DatasetEventManager.getInstance().removeDatasetListener(chosenRelation);
327 chosenRelation.clear();
328 }
329
330 @Override
331 public void showNotify() {
332 SelectionEventManager.getInstance().addSelectionListener(this, FireMode.IN_EDT_CONSOLIDATED);
333 MapView.addEditLayerChangeListener(this);
334 DatasetEventManager.getInstance().addDatasetListener(chosenRelation, FireMode.IN_EDT);
335 }
336
337 public ChosenRelation getChosenRelation() {
338 return chosenRelation;
339 }
340
341 public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
342 if( chosenRelationPanel != null && Main.pref.getBoolean(PREF_PREFIX + ".hidetopline", false) )
343 chosenRelationPanel.setVisible(newRelation != null);
344 if( Main.main.getCurrentDataSet() != null )
345 selectionChanged(Main.main.getCurrentDataSet().getSelected());
346 roleBoxModel.update();
347 // ?
348 }
349
350 public void selectionChanged( Collection<? extends OsmPrimitive> newSelection ) {
351 if( !isVisible() || relationsData == null )
352 return;
353 roleBoxModel.update();
354 // repopulate relations table
355 relationsData.setRowCount(0);
356 sortAndFixAction.chosenRelationChanged(chosenRelation.get(), chosenRelation.get());
357 if( newSelection == null )
358 return;
359
360 Set<Relation> relations = new TreeSet<Relation>(
361 DefaultNameFormatter.getInstance().getRelationComparator());
362 for( OsmPrimitive element : newSelection ) {
363 for( OsmPrimitive ref : element.getReferrers() ) {
364 if( ref instanceof Relation && !ref.isIncomplete() && !ref.isDeleted() ) {
365 relations.add((Relation) ref);
366 }
367 }
368 }
369
370 for( Relation rel : relations ) {
371 String role = null;
372 for( RelationMember m : rel.getMembers() ) {
373 for( OsmPrimitive element : newSelection ) {
374 if( m.getMember().equals(element) ) {
375 if( role == null )
376 role = m.getRole();
377 else if( !role.equals(m.getRole()) ) {
378 role = tr("<different>");
379 break;
380 }
381 }
382 }
383 }
384 relationsData.addRow(new Object[] {rel, role == null ? "" : role});
385 }
386 for( OsmPrimitive element : newSelection )
387 if( element instanceof Relation && !chosenRelation.isSame(element) )
388 relationsData.addRow(new Object[] {element, ""});
389 }
390
391 private void updateSelection() {
392 if (Main.main.getCurrentDataSet() == null) {
393 selectionChanged(Collections.<OsmPrimitive>emptyList());
394 } else {
395 selectionChanged(Main.main.getCurrentDataSet().getSelected());
396 }
397 }
398
399 public void editLayerChanged( OsmDataLayer oldLayer, OsmDataLayer newLayer ) {
400 updateSelection();
401 }
402
403 @Override
404 public void destroy() {
405 enterRoleAction.destroy();
406 findRelationAction.destroy();
407 createMultipolygonAction.destroy();
408 createRelationAction.destroy();
409 addRemoveMemberAction.destroy();
410 super.destroy();
411 }
412
413 private static final String POSSIBLE_ROLES_FILE = "relcontext/possible_roles.txt";
414 private static final Map<String, List<String>> possibleRoles = loadRoles();
415
416 private static Map<String, List<String>> loadRoles() {
417 Map<String, List<String>> result = new HashMap<String, List<String>>();
418 try {
419 ClassLoader classLoader = RelContextDialog.class.getClassLoader();
420 final InputStream possibleRolesStream = classLoader.getResourceAsStream(POSSIBLE_ROLES_FILE);
421 BufferedReader r = new BufferedReader(new InputStreamReader(possibleRolesStream));
422 while( r.ready() ) {
423 String line = r.readLine();
424 StringTokenizer t = new StringTokenizer(line, " ,;:\"");
425 if( t.hasMoreTokens() ) {
426 String type = t.nextToken();
427 List<String> roles = new ArrayList<String>();
428 while( t.hasMoreTokens() )
429 roles.add(t.nextToken());
430 result.put(type, roles);
431 }
432 }
433 r.close();
434 } catch( Exception e ) {
435 System.err.println("[RelToolbox] Error reading possible roles file.");
436 e.printStackTrace();
437 }
438 return result;
439 }
440
441 private String askForRoleName() {
442 JPanel panel = new JPanel(new GridBagLayout());
443
444 List<String> items = new ArrayList<String>();
445 for( String role : roleBoxModel.getRoles() ) {
446 if( role.length() > 1 )
447 items.add(role);
448 }
449 final AutoCompletingComboBox role = new AutoCompletingComboBox();
450 role.setPossibleItems(items);
451 role.setEditable(true);
452
453 panel.add(new JLabel(tr("Role")), GBC.std());
454 panel.add(Box.createHorizontalStrut(10), GBC.std());
455 panel.add(role, GBC.eol().fill(GBC.HORIZONTAL));
456
457 final JOptionPane optionPane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
458 @Override
459 public void selectInitialValue() {
460 role.requestFocusInWindow();
461 role.getEditor().selectAll();
462 }
463 };
464 final JDialog dlg = optionPane.createDialog(Main.parent, tr("Specify role"));
465 dlg.setModalityType(ModalityType.DOCUMENT_MODAL);
466
467 role.getEditor().addActionListener(new ActionListener() {
468 public void actionPerformed( ActionEvent e ) {
469 dlg.setVisible(false);
470 optionPane.setValue(JOptionPane.OK_OPTION);
471 }
472 });
473
474 dlg.setVisible(true);
475
476 Object answer = optionPane.getValue();
477 if( answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
478 || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION) ) {
479 return null;
480 }
481
482 return role.getEditor().getItem().toString().trim();
483 }
484
485 private class ChosenRelationMouseAdapter extends MouseAdapter {
486 @Override
487 public void mouseClicked( MouseEvent e ) {
488 if( e.isControlDown() || !(e.getComponent() instanceof JComboBox ) ) // do not use left click handler on combo box
489 if( SwingUtilities.isLeftMouseButton(e) && chosenRelation.get() != null && Main.map.mapView.getEditLayer() != null ) {
490 Main.map.mapView.getEditLayer().data.setSelected(chosenRelation.get());
491 }
492 }
493
494 @Override
495 public void mousePressed( MouseEvent e ) {
496 checkPopup(e);
497 }
498
499 @Override
500 public void mouseReleased( MouseEvent e ) {
501 checkPopup(e);
502 }
503
504 private void checkPopup( MouseEvent e ) {
505 if( e.isPopupTrigger() && chosenRelation.get() != null ) {
506 popupMenu.show(e.getComponent(), e.getX(), e.getY() - 5);
507 }
508 }
509 }
510
511 private class ChosenRelationPopupMenu extends JPopupMenu {
512 public ChosenRelationPopupMenu( ChosenRelation chosenRelation ) {
513 add(new SelectMembersAction(chosenRelation));
514 add(new SelectRelationAction(chosenRelation));
515 add(new DuplicateChosenRelationAction(chosenRelation));
516 add(new DeleteChosenRelationAction(chosenRelation));
517 add(new DownloadParentsAction(chosenRelation));
518 add(new ReconstructPolygonAction(chosenRelation));
519 addSeparator();
520 add(new SelectInRelationPanelAction(chosenRelation));
521 add(new RelationHelpAction(chosenRelation));
522 }
523 }
524
525 protected void applyRoleToSelection( String role ) {
526 if( chosenRelation != null && chosenRelation.get() != null && Main.main.getCurrentDataSet() != null && !Main.main.getCurrentDataSet().selectionEmpty() ) {
527 Collection<OsmPrimitive> selected = Main.main.getCurrentDataSet().getSelected();
528 Relation r = chosenRelation.get();
529 List<Command> commands = new ArrayList<Command>();
530 for( int i = 0; i < r.getMembersCount(); i++ ) {
531 RelationMember m = r.getMember(i);
532 if( selected.contains(m.getMember()) ) {
533 if( !role.equals(m.getRole()) ) {
534// r.setMember(i, new RelationMember(role, m.getMember()));
535 commands.add(new ChangeRelationMemberRoleCommand(r, i, role));
536 }
537 }
538 }
539 if( !commands.isEmpty() ) {
540// Main.main.undoRedo.add(new ChangeCommand(chosenRelation.get(), r));
541 Main.main.undoRedo.add(new SequenceCommand(tr("Change relation member roles to {0}", role), commands));
542 }
543 }
544 }
545
546 private static class RelationTableModel extends DefaultTableModel {
547 @Override
548 public boolean isCellEditable(int row, int column) {
549 return false;
550 }
551
552 @Override
553 public Class<?> getColumnClass(int columnIndex) {
554 return columnIndex == 0 ? Relation.class : String.class;
555 }
556 }
557/*
558 private class MultipolygonSettingsAction extends AbstractAction {
559 public MultipolygonSettingsAction() {
560 super();
561 putValue(SMALL_ICON, ImageProvider.get("svpRight"));
562 putValue(SHORT_DESCRIPTION, tr("Change multipolygon creation settings"));
563 }
564
565 public void actionPerformed( ActionEvent e ) {
566 Component c = e.getSource() instanceof Component ? (Component)e.getSource() : Main.parent;
567 multiPopupMenu.show(c, 0, 0);
568 }
569 }*/
570
571 private class MultipolygonSettingsPopup extends JPopupMenu implements ActionListener {
572 public MultipolygonSettingsPopup() {
573 super();
574 addMenuItem("boundary", tr("Create administrative boundary relations"));
575 addMenuItem("boundaryways", tr("Add tags boundary and admin_level to boundary relation ways"));
576 addMenuItem("tags", tr("Move area tags from contour to relation"));
577 addMenuItem("alltags", tr("When moving tags, consider even non-repeating ones"));
578 addMenuItem("allowsplit", tr("Always split ways of neighbouring multipolygons"));
579 }
580
581 protected final JCheckBoxMenuItem addMenuItem( String property, String title ) {
582 String fullProperty = PREF_PREFIX + ".multipolygon." + property;
583 JCheckBoxMenuItem item = new JCheckBoxMenuItem(tr(title));
584 item.setSelected(Main.pref.getBoolean(fullProperty, CreateMultipolygonAction.getDefaultPropertyValue(property)));
585 item.setActionCommand(fullProperty);
586 item.addActionListener(this);
587 add(item);
588 return item;
589 }
590
591 public void actionPerformed( ActionEvent e ) {
592 String property = e.getActionCommand();
593 if( property != null && property.length() > 0 && e.getSource() instanceof JCheckBoxMenuItem ) {
594 boolean value = ((JCheckBoxMenuItem)e.getSource()).isSelected();
595 Main.pref.put(property, value);
596 show(getInvoker(), getX(), getY());
597 }
598 }
599 }
600
601 private class EnterRoleAction extends JosmAction implements ChosenRelationListener {
602
603 public EnterRoleAction() {
604 super(tr("Change role"), (String)null, tr("Enter role for selected members"),
605 Shortcut.registerShortcut("reltoolbox:changerole", tr("Relation Toolbox: {0}", tr("Enter role for selected members")),
606 KeyEvent.VK_R, Shortcut.ALT_CTRL), false, "relcontext/enterrole", true);
607 chosenRelation.addChosenRelationListener(this);
608 updateEnabledState();
609 }
610
611 public void actionPerformed( ActionEvent e ) {
612 if( roleBoxModel.membersRole != null ) {
613 String role = askForRoleName();
614 if( role != null )
615 applyRoleToSelection(role);
616 }
617 }
618
619 public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
620 setEnabled(newRelation != null);
621 }
622 }
623
624 private class RoleComboBoxModel extends AbstractListModel implements ComboBoxModel {
625 private List<String> roles = new ArrayList<String>();
626 private int selectedIndex = -1;
627 private JComboBox combobox;
628 private String membersRole;
629 private final String EMPTY_ROLE = tr("<empty>");
630 private final String ANOTHER_ROLE = tr("another...");
631
632 public RoleComboBoxModel( JComboBox combobox ) {
633 super();
634 this.combobox = combobox;
635 update();
636 }
637
638 public void update() {
639 membersRole = getSelectedMembersRoleIntl();
640 if( membersRole == null ) {
641 if( combobox.isEnabled() )
642 combobox.setEnabled(false);
643 return;
644 }
645 if( !combobox.isEnabled() )
646 combobox.setEnabled(true);
647
648 List<String> items = new ArrayList<String>();
649 if( chosenRelation != null && chosenRelation.get() != null ) {
650 if( chosenRelation.isMultipolygon() ) {
651 items.add("outer");
652 items.add("inner");
653 }
654 if( chosenRelation.get().get("type") != null ) {
655 List<String> values = possibleRoles.get(chosenRelation.get().get("type"));
656 if( values != null )
657 items.addAll(values);
658 }
659 for( RelationMember m : chosenRelation.get().getMembers() )
660 if( m.getRole().length() > 0 && !items.contains(m.getRole()) )
661 items.add(m.getRole());
662 }
663 items.add(EMPTY_ROLE);
664 if( !items.contains(membersRole) )
665 items.add(0, membersRole);
666 items.add(ANOTHER_ROLE);
667 roles = Collections.unmodifiableList(items);
668
669 if( membersRole != null )
670 setSelectedItem(membersRole);
671 else
672 fireContentsChanged(this, -1, -1);
673 combobox.repaint();
674 }
675
676 public String getSelectedMembersRole() {
677 return membersRole == EMPTY_ROLE ? "" : membersRole;
678 }
679
680 public boolean isAnotherRoleSelected() {
681 return getSelectedRole() != null && getSelectedRole().equals(ANOTHER_ROLE);
682 }
683
684 private String getSelectedMembersRoleIntl() {
685 String role = null;
686 if( chosenRelation != null && chosenRelation.get() != null && Main.main.getCurrentDataSet() != null && !Main.main.getCurrentDataSet().selectionEmpty() ) {
687 Collection<OsmPrimitive> selected = Main.main.getCurrentDataSet().getSelected();
688 for( RelationMember m : chosenRelation.get().getMembers() ) {
689 if( selected.contains(m.getMember()) ) {
690 if( role == null )
691 role = m.getRole();
692 else if( m.getRole() != null && !role.equals(m.getRole()) ) {
693 role = tr("<different>");
694 break;
695 }
696 }
697 }
698 }
699 return role == null ? null : role.length() == 0 ? EMPTY_ROLE : role;
700 }
701
702 public List<String> getRoles() {
703 return roles;
704 }
705
706 public int getSize() {
707 return roles.size();
708 }
709
710 public Object getElementAt( int index ) {
711 return getRole(index);
712 }
713
714 public String getRole( int index ) {
715 return roles.get(index);
716 }
717
718 public void setSelectedItem( Object anItem ) {
719 int newIndex = anItem == null ? -1 : roles.indexOf(anItem);
720 if( newIndex != selectedIndex ) {
721 selectedIndex = newIndex;
722 fireContentsChanged(this, -1, -1);
723 }
724 }
725
726 public Object getSelectedItem() {
727 return selectedIndex < 0 || selectedIndex >= getSize() ? null : getRole(selectedIndex);
728 }
729
730 public String getSelectedRole() {
731 String role = selectedIndex < 0 || selectedIndex >= getSize() ? null : getRole(selectedIndex);
732 return role != null && role.equals(EMPTY_ROLE) ? "" : role;
733 }
734 }
735}
Note: See TracBrowser for help on using the repository browser.