source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java@ 8308

Last change on this file since 8308 was 8308, checked in by Don-vip, 9 years ago

fix potential NPEs and Sonar issues related to serialization

  • Property svn:eol-style set to native
File size: 26.4 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.Component;
7import java.awt.Dimension;
8import java.awt.Font;
9import java.awt.GridBagLayout;
10import java.awt.Insets;
11import java.awt.Point;
12import java.awt.Rectangle;
13import java.awt.event.ActionEvent;
14import java.awt.event.ActionListener;
15import java.awt.event.KeyEvent;
16import java.awt.event.MouseEvent;
17import java.io.BufferedInputStream;
18import java.io.BufferedOutputStream;
19import java.io.BufferedReader;
20import java.io.File;
21import java.io.FileOutputStream;
22import java.io.IOException;
23import java.io.InputStream;
24import java.io.InputStreamReader;
25import java.io.OutputStream;
26import java.nio.charset.StandardCharsets;
27import java.util.ArrayList;
28import java.util.Arrays;
29import java.util.List;
30
31import javax.swing.AbstractAction;
32import javax.swing.DefaultButtonModel;
33import javax.swing.DefaultListSelectionModel;
34import javax.swing.JCheckBox;
35import javax.swing.JFileChooser;
36import javax.swing.JLabel;
37import javax.swing.JMenu;
38import javax.swing.JPanel;
39import javax.swing.JPopupMenu;
40import javax.swing.JScrollPane;
41import javax.swing.JTabbedPane;
42import javax.swing.JTable;
43import javax.swing.JViewport;
44import javax.swing.ListSelectionModel;
45import javax.swing.SingleSelectionModel;
46import javax.swing.SwingConstants;
47import javax.swing.SwingUtilities;
48import javax.swing.UIManager;
49import javax.swing.border.EmptyBorder;
50import javax.swing.event.ChangeEvent;
51import javax.swing.event.ChangeListener;
52import javax.swing.event.ListSelectionEvent;
53import javax.swing.event.ListSelectionListener;
54import javax.swing.filechooser.FileFilter;
55import javax.swing.table.AbstractTableModel;
56import javax.swing.table.DefaultTableCellRenderer;
57import javax.swing.table.TableCellRenderer;
58import javax.swing.table.TableModel;
59
60import org.openstreetmap.josm.Main;
61import org.openstreetmap.josm.actions.ExtensionFileFilter;
62import org.openstreetmap.josm.actions.JosmAction;
63import org.openstreetmap.josm.actions.PreferencesAction;
64import org.openstreetmap.josm.gui.ExtendedDialog;
65import org.openstreetmap.josm.gui.PleaseWaitRunnable;
66import org.openstreetmap.josm.gui.SideButton;
67import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
68import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.MapPaintSylesUpdateListener;
69import org.openstreetmap.josm.gui.mappaint.StyleSetting;
70import org.openstreetmap.josm.gui.mappaint.StyleSource;
71import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
72import org.openstreetmap.josm.gui.preferences.SourceEntry;
73import org.openstreetmap.josm.gui.preferences.map.MapPaintPreference;
74import org.openstreetmap.josm.gui.util.FileFilterAllFiles;
75import org.openstreetmap.josm.gui.util.GuiHelper;
76import org.openstreetmap.josm.gui.widgets.AbstractFileChooser;
77import org.openstreetmap.josm.gui.widgets.FileChooserManager;
78import org.openstreetmap.josm.gui.widgets.HtmlPanel;
79import org.openstreetmap.josm.gui.widgets.JosmTextArea;
80import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
81import org.openstreetmap.josm.tools.GBC;
82import org.openstreetmap.josm.tools.ImageProvider;
83import org.openstreetmap.josm.tools.InputMapUtils;
84import org.openstreetmap.josm.tools.Shortcut;
85import org.openstreetmap.josm.tools.Utils;
86
87public class MapPaintDialog extends ToggleDialog {
88
89 protected StylesTable tblStyles;
90 protected StylesModel model;
91 protected DefaultListSelectionModel selectionModel;
92
93 protected OnOffAction onoffAction;
94 protected ReloadAction reloadAction;
95 protected MoveUpDownAction upAction;
96 protected MoveUpDownAction downAction;
97 protected JCheckBox cbWireframe;
98
99 public static final JosmAction PREFERENCE_ACTION = PreferencesAction.forPreferenceSubTab(
100 tr("Map paint preferences"), null, MapPaintPreference.class, /* ICON */ "dialogs/mappaintpreference");
101
102 /**
103 * Constructs a new {@code MapPaintDialog}.
104 */
105 public MapPaintDialog() {
106 super(tr("Map Paint Styles"), "mapstyle", tr("configure the map painting style"),
107 Shortcut.registerShortcut("subwindow:mappaint", tr("Toggle: {0}", tr("MapPaint")),
108 KeyEvent.VK_M, Shortcut.ALT_SHIFT), 150, false, MapPaintPreference.class);
109 build();
110 }
111
112 protected void build() {
113 model = new StylesModel();
114
115 cbWireframe = new JCheckBox();
116 JLabel wfLabel = new JLabel(tr("Wireframe View"), ImageProvider.get("dialogs/mappaint", "wireframe_small"), JLabel.HORIZONTAL);
117 wfLabel.setFont(wfLabel.getFont().deriveFont(Font.PLAIN));
118
119 cbWireframe.setModel(new DefaultButtonModel() {
120 @Override
121 public void setSelected(boolean b) {
122 super.setSelected(b);
123 tblStyles.setEnabled(!b);
124 onoffAction.updateEnabledState();
125 upAction.updateEnabledState();
126 downAction.updateEnabledState();
127 }
128 });
129 cbWireframe.addActionListener(new ActionListener() {
130 @Override
131 public void actionPerformed(ActionEvent e) {
132 Main.main.menu.wireFrameToggleAction.actionPerformed(null);
133 }
134 });
135 cbWireframe.setBorder(new EmptyBorder(new Insets(1,1,1,1)));
136
137 tblStyles = new StylesTable(model);
138 tblStyles.setSelectionModel(selectionModel= new DefaultListSelectionModel());
139 tblStyles.addMouseListener(new PopupMenuHandler());
140 tblStyles.putClientProperty("terminateEditOnFocusLost", true);
141 tblStyles.setBackground(UIManager.getColor("Panel.background"));
142 tblStyles.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
143 tblStyles.setTableHeader(null);
144 tblStyles.getColumnModel().getColumn(0).setMaxWidth(1);
145 tblStyles.getColumnModel().getColumn(0).setResizable(false);
146 tblStyles.getColumnModel().getColumn(0).setCellRenderer(new MyCheckBoxRenderer());
147 tblStyles.getColumnModel().getColumn(1).setCellRenderer(new StyleSourceRenderer());
148 tblStyles.setShowGrid(false);
149 tblStyles.setIntercellSpacing(new Dimension(0, 0));
150
151 JPanel p = new JPanel(new GridBagLayout());
152 p.add(cbWireframe, GBC.std(0, 0));
153 p.add(wfLabel, GBC.std(1, 0).weight(1, 0));
154 p.add(tblStyles, GBC.std(0, 1).span(2).fill());
155
156 reloadAction = new ReloadAction();
157 onoffAction = new OnOffAction();
158 upAction = new MoveUpDownAction(false);
159 downAction = new MoveUpDownAction(true);
160 selectionModel.addListSelectionListener(onoffAction);
161 selectionModel.addListSelectionListener(reloadAction);
162 selectionModel.addListSelectionListener(upAction);
163 selectionModel.addListSelectionListener(downAction);
164
165 // Toggle style on Enter and Spacebar
166 InputMapUtils.addEnterAction(tblStyles, onoffAction);
167 InputMapUtils.addSpacebarAction(tblStyles, onoffAction);
168
169 createLayout(p, true, Arrays.asList(
170 new SideButton(onoffAction, false),
171 new SideButton(upAction, false),
172 new SideButton(downAction, false),
173 new SideButton(PREFERENCE_ACTION, false)
174 ));
175 }
176
177 protected static class StylesTable extends JTable {
178
179 public StylesTable(TableModel dm) {
180 super(dm);
181 }
182
183 public void scrollToVisible(int row, int col) {
184 if (!(getParent() instanceof JViewport))
185 return;
186 JViewport viewport = (JViewport) getParent();
187 Rectangle rect = getCellRect(row, col, true);
188 Point pt = viewport.getViewPosition();
189 rect.setLocation(rect.x - pt.x, rect.y - pt.y);
190 viewport.scrollRectToVisible(rect);
191 }
192 }
193
194 @Override
195 public void showNotify() {
196 MapPaintStyles.addMapPaintSylesUpdateListener(model);
197 Main.main.menu.wireFrameToggleAction.addButtonModel(cbWireframe.getModel());
198 }
199
200 @Override
201 public void hideNotify() {
202 Main.main.menu.wireFrameToggleAction.removeButtonModel(cbWireframe.getModel());
203 MapPaintStyles.removeMapPaintSylesUpdateListener(model);
204 }
205
206 protected class StylesModel extends AbstractTableModel implements MapPaintSylesUpdateListener {
207
208 private transient List<StyleSource> data = new ArrayList<>();
209
210 public StylesModel() {
211 data = new ArrayList<>(MapPaintStyles.getStyles().getStyleSources());
212 }
213
214 private StyleSource getRow(int i) {
215 return data.get(i);
216 }
217
218 @Override
219 public int getColumnCount() {
220 return 2;
221 }
222
223 @Override
224 public int getRowCount() {
225 return data.size();
226 }
227
228 @Override
229 public Object getValueAt(int row, int column) {
230 if (column == 0)
231 return getRow(row).active;
232 else
233 return getRow(row);
234 }
235
236 @Override
237 public boolean isCellEditable(int row, int column) {
238 return column == 0;
239 }
240
241 private Class<?>[] columnClasses = {Boolean.class, StyleSource.class};
242
243 @Override
244 public Class<?> getColumnClass(int column) {
245 return columnClasses[column];
246 }
247
248 @Override
249 public void setValueAt(Object aValue, int row, int column) {
250 if (row < 0 || row >= getRowCount() || aValue == null)
251 return;
252 if (column == 0) {
253 MapPaintStyles.toggleStyleActive(row);
254 }
255 }
256
257 /**
258 * Make sure the first of the selected entry is visible in the
259 * views of this model.
260 */
261 public void ensureSelectedIsVisible() {
262 int index = selectionModel.getMinSelectionIndex();
263 if (index < 0) return;
264 if (index >= getRowCount()) return;
265 tblStyles.scrollToVisible(index, 0);
266 tblStyles.repaint();
267 }
268
269 @Override
270 public void mapPaintStylesUpdated() {
271 data = new ArrayList<>(MapPaintStyles.getStyles().getStyleSources());
272 fireTableDataChanged();
273 tblStyles.repaint();
274 }
275
276 @Override
277 public void mapPaintStyleEntryUpdated(int idx) {
278 data = new ArrayList<>(MapPaintStyles.getStyles().getStyleSources());
279 fireTableRowsUpdated(idx, idx);
280 tblStyles.repaint();
281 }
282 }
283
284 private class MyCheckBoxRenderer extends JCheckBox implements TableCellRenderer {
285
286 public MyCheckBoxRenderer() {
287 setHorizontalAlignment(SwingConstants.CENTER);
288 setVerticalAlignment(SwingConstants.CENTER);
289 }
290
291 @Override
292 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int column) {
293 if (value == null)
294 return this;
295 boolean b = (Boolean) value;
296 setSelected(b);
297 setEnabled(!cbWireframe.isSelected());
298 return this;
299 }
300 }
301
302 private class StyleSourceRenderer extends DefaultTableCellRenderer {
303 @Override
304 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
305 if (value == null)
306 return this;
307 StyleSource s = (StyleSource) value;
308 JLabel label = (JLabel)super.getTableCellRendererComponent(table,
309 s.getDisplayString(), isSelected, hasFocus, row, column);
310 label.setIcon(s.getIcon());
311 label.setToolTipText(s.getToolTipText());
312 label.setEnabled(!cbWireframe.isSelected());
313 return label;
314 }
315 }
316
317 protected class OnOffAction extends AbstractAction implements ListSelectionListener {
318 public OnOffAction() {
319 putValue(NAME, tr("On/Off"));
320 putValue(SHORT_DESCRIPTION, tr("Turn selected styles on or off"));
321 putValue(SMALL_ICON, ImageProvider.get("apply"));
322 updateEnabledState();
323 }
324
325 protected void updateEnabledState() {
326 setEnabled(!cbWireframe.isSelected() && tblStyles.getSelectedRowCount() > 0);
327 }
328
329 @Override
330 public void valueChanged(ListSelectionEvent e) {
331 updateEnabledState();
332 }
333
334 @Override
335 public void actionPerformed(ActionEvent e) {
336 int[] pos = tblStyles.getSelectedRows();
337 MapPaintStyles.toggleStyleActive(pos);
338 selectionModel.clearSelection();
339 for (int p: pos) {
340 selectionModel.addSelectionInterval(p, p);
341 }
342 }
343 }
344
345 /**
346 * The action to move down the currently selected entries in the list.
347 */
348 protected class MoveUpDownAction extends AbstractAction implements ListSelectionListener {
349
350 private final int increment;
351
352 public MoveUpDownAction(boolean isDown) {
353 increment = isDown ? 1 : -1;
354 putValue(NAME, isDown?tr("Down"):tr("Up"));
355 putValue(SMALL_ICON, isDown ? ImageProvider.get("dialogs", "down") : ImageProvider.get("dialogs", "up"));
356 putValue(SHORT_DESCRIPTION, isDown ? tr("Move the selected entry one row down.") : tr("Move the selected entry one row up."));
357 updateEnabledState();
358 }
359
360 public void updateEnabledState() {
361 int[] sel = tblStyles.getSelectedRows();
362 setEnabled(!cbWireframe.isSelected() && MapPaintStyles.canMoveStyles(sel, increment));
363 }
364
365 @Override
366 public void actionPerformed(ActionEvent e) {
367 int[] sel = tblStyles.getSelectedRows();
368 MapPaintStyles.moveStyles(sel, increment);
369
370 selectionModel.clearSelection();
371 for (int row: sel) {
372 selectionModel.addSelectionInterval(row + increment, row + increment);
373 }
374 model.ensureSelectedIsVisible();
375 }
376
377 @Override
378 public void valueChanged(ListSelectionEvent e) {
379 updateEnabledState();
380 }
381 }
382
383 protected class ReloadAction extends AbstractAction implements ListSelectionListener {
384 public ReloadAction() {
385 putValue(NAME, tr("Reload from file"));
386 putValue(SHORT_DESCRIPTION, tr("reload selected styles from file"));
387 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
388 setEnabled(getEnabledState());
389 }
390
391 protected boolean getEnabledState() {
392 if (cbWireframe.isSelected())
393 return false;
394 int[] pos = tblStyles.getSelectedRows();
395 if (pos.length == 0)
396 return false;
397 for (int i : pos) {
398 if (!model.getRow(i).isLocal())
399 return false;
400 }
401 return true;
402 }
403
404 @Override
405 public void valueChanged(ListSelectionEvent e) {
406 setEnabled(getEnabledState());
407 }
408
409 @Override
410 public void actionPerformed(ActionEvent e) {
411 final int[] rows = tblStyles.getSelectedRows();
412 MapPaintStyles.reloadStyles(rows);
413 Main.worker.submit(new Runnable() {
414 @Override
415 public void run() {
416 SwingUtilities.invokeLater(new Runnable() {
417 @Override
418 public void run() {
419 selectionModel.clearSelection();
420 for (int r: rows) {
421 selectionModel.addSelectionInterval(r, r);
422 }
423 }
424 });
425
426 }
427 });
428 }
429 }
430
431 protected class SaveAsAction extends AbstractAction {
432
433 public SaveAsAction() {
434 putValue(NAME, tr("Save as..."));
435 putValue(SHORT_DESCRIPTION, tr("Save a copy of this Style to file and add it to the list"));
436 putValue(SMALL_ICON, ImageProvider.get("copy"));
437 setEnabled(tblStyles.getSelectedRows().length == 1);
438 }
439
440 @Override
441 public void actionPerformed(ActionEvent e) {
442 int sel = tblStyles.getSelectionModel().getLeadSelectionIndex();
443 if (sel < 0 || sel >= model.getRowCount())
444 return;
445 final StyleSource s = model.getRow(sel);
446
447 FileChooserManager fcm = new FileChooserManager(false, "mappaint.clone-style.lastDirectory", System.getProperty("user.home"));
448 String suggestion = fcm.getInitialDirectory() + File.separator + s.getFileNamePart();
449
450 FileFilter ff;
451 if (s instanceof MapCSSStyleSource) {
452 ff = new ExtensionFileFilter("mapcss,css,zip", "mapcss", tr("Map paint style file (*.mapcss, *.zip)"));
453 } else {
454 ff = new ExtensionFileFilter("xml,zip", "xml", tr("Map paint style file (*.xml, *.zip)"));
455 }
456 fcm.createFileChooser(false, null, Arrays.asList(ff, FileFilterAllFiles.getInstance()), ff, JFileChooser.FILES_ONLY)
457 .getFileChooser().setSelectedFile(new File(suggestion));
458 AbstractFileChooser fc = fcm.openFileChooser();
459 if (fc == null)
460 return;
461 Main.worker.submit(new SaveToFileTask(s, fc.getSelectedFile()));
462 }
463
464 private class SaveToFileTask extends PleaseWaitRunnable {
465 private StyleSource s;
466 private File file;
467
468 private boolean canceled;
469 private boolean error;
470
471 public SaveToFileTask(StyleSource s, File file) {
472 super(tr("Reloading style sources"));
473 this.s = s;
474 this.file = file;
475 }
476
477 @Override
478 protected void cancel() {
479 canceled = true;
480 }
481
482 @Override
483 protected void realRun() {
484 getProgressMonitor().indeterminateSubTask(
485 tr("Save style ''{0}'' as ''{1}''", s.getDisplayString(), file.getPath()));
486 try {
487 InputStream in = s.getSourceInputStream();
488 try (
489 InputStream bis = new BufferedInputStream(in);
490 OutputStream bos = new BufferedOutputStream(new FileOutputStream(file))
491 ) {
492 byte[] buffer = new byte[4096];
493 int length;
494 while ((length = bis.read(buffer)) > -1 && !canceled) {
495 bos.write(buffer, 0, length);
496 }
497 } finally {
498 s.closeSourceInputStream(in);
499 }
500 } catch (IOException e) {
501 error = true;
502 }
503 }
504
505 @Override
506 protected void finish() {
507 SwingUtilities.invokeLater(new Runnable() {
508 @Override
509 public void run() {
510 if (!error && !canceled) {
511 SourceEntry se = new SourceEntry(s);
512 se.url = file.getPath();
513 MapPaintStyles.addStyle(se);
514 tblStyles.getSelectionModel().setSelectionInterval(model.getRowCount() - 1 , model.getRowCount() - 1);
515 model.ensureSelectedIsVisible();
516 }
517 }
518 });
519 }
520 }
521 }
522
523 protected class InfoAction extends AbstractAction {
524
525 private boolean errorsTabLoaded;
526 private boolean sourceTabLoaded;
527
528 public InfoAction() {
529 putValue(NAME, tr("Info"));
530 putValue(SHORT_DESCRIPTION, tr("view meta information, error log and source definition"));
531 putValue(SMALL_ICON, ImageProvider.get("info"));
532 setEnabled(tblStyles.getSelectedRows().length == 1);
533 }
534
535 @Override
536 public void actionPerformed(ActionEvent e) {
537 int sel = tblStyles.getSelectionModel().getLeadSelectionIndex();
538 if (sel < 0 || sel >= model.getRowCount())
539 return;
540 final StyleSource s = model.getRow(sel);
541 ExtendedDialog info = new ExtendedDialog(Main.parent, tr("Map Style info"), new String[] {tr("Close")});
542 info.setPreferredSize(new Dimension(600, 400));
543 info.setButtonIcons(new String[] {"ok.png"});
544
545 final JTabbedPane tabs = new JTabbedPane();
546
547 tabs.add("Info", buildInfoPanel(s));
548 JLabel lblInfo = new JLabel(tr("Info"));
549 lblInfo.setFont(lblInfo.getFont().deriveFont(Font.PLAIN));
550 tabs.setTabComponentAt(0, lblInfo);
551
552 final JPanel pErrors = new JPanel(new GridBagLayout());
553 tabs.add("Errors", pErrors);
554 JLabel lblErrors;
555 if (s.getErrors().isEmpty()) {
556 lblErrors = new JLabel(tr("Errors"));
557 lblErrors.setFont(lblInfo.getFont().deriveFont(Font.PLAIN));
558 lblErrors.setEnabled(false);
559 tabs.setTabComponentAt(1, lblErrors);
560 tabs.setEnabledAt(1, false);
561 } else {
562 lblErrors = new JLabel(tr("Errors"), ImageProvider.get("misc", "error"), JLabel.HORIZONTAL);
563 tabs.setTabComponentAt(1, lblErrors);
564 }
565
566 final JPanel pSource = new JPanel(new GridBagLayout());
567 tabs.addTab("Source", pSource);
568 JLabel lblSource = new JLabel(tr("Source"));
569 lblSource.setFont(lblSource.getFont().deriveFont(Font.PLAIN));
570 tabs.setTabComponentAt(2, lblSource);
571
572 tabs.getModel().addChangeListener(new ChangeListener() {
573 @Override
574 public void stateChanged(ChangeEvent e) {
575 if (!errorsTabLoaded && ((SingleSelectionModel) e.getSource()).getSelectedIndex() == 1) {
576 errorsTabLoaded = true;
577 buildErrorsPanel(s, pErrors);
578 }
579 if (!sourceTabLoaded && ((SingleSelectionModel) e.getSource()).getSelectedIndex() == 2) {
580 sourceTabLoaded = true;
581 buildSourcePanel(s, pSource);
582 }
583 }
584 });
585 info.setContent(tabs, false);
586 info.showDialog();
587 }
588
589 private JPanel buildInfoPanel(StyleSource s) {
590 JPanel p = new JPanel(new GridBagLayout());
591 StringBuilder text = new StringBuilder("<table cellpadding=3>");
592 text.append(tableRow(tr("Title:"), s.getDisplayString()));
593 if (s.url.startsWith("http://") || s.url.startsWith("https://")) {
594 text.append(tableRow(tr("URL:"), s.url));
595 } else if (s.url.startsWith("resource://")) {
596 text.append(tableRow(tr("Built-in Style, internal path:"), s.url));
597 } else {
598 text.append(tableRow(tr("Path:"), s.url));
599 }
600 if (s.icon != null) {
601 text.append(tableRow(tr("Icon:"), s.icon));
602 }
603 if (s.getBackgroundColorOverride() != null) {
604 text.append(tableRow(tr("Background:"), Utils.toString(s.getBackgroundColorOverride())));
605 }
606 text.append(tableRow(tr("Style is currently active?"), s.active ? tr("Yes") : tr("No")));
607 text.append("</table>");
608 p.add(new JScrollPane(new HtmlPanel(text.toString())), GBC.eol().fill(GBC.BOTH));
609 return p;
610 }
611
612 private String tableRow(String firstColumn, String secondColumn) {
613 return "<tr><td><b>" + firstColumn + "</b></td><td>" + secondColumn + "</td></tr>";
614 }
615
616 private void buildSourcePanel(StyleSource s, JPanel p) {
617 JosmTextArea txtSource = new JosmTextArea();
618 txtSource.setFont(GuiHelper.getMonospacedFont(txtSource));
619 txtSource.setEditable(false);
620 p.add(new JScrollPane(txtSource), GBC.std().fill());
621
622 try {
623 InputStream is = s.getSourceInputStream();
624 try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
625 String line;
626 while ((line = reader.readLine()) != null) {
627 txtSource.append(line + "\n");
628 }
629 } finally {
630 s.closeSourceInputStream(is);
631 }
632 } catch (IOException ex) {
633 txtSource.append("<ERROR: failed to read file!>");
634 }
635 }
636
637 private void buildErrorsPanel(StyleSource s, JPanel p) {
638 JosmTextArea txtErrors = new JosmTextArea();
639 txtErrors.setFont(GuiHelper.getMonospacedFont(txtErrors));
640 txtErrors.setEditable(false);
641 p.add(new JScrollPane(txtErrors), GBC.std().fill());
642 for (Throwable t : s.getErrors()) {
643 txtErrors.append(t.toString() + "\n");
644 }
645 }
646 }
647
648 class PopupMenuHandler extends PopupMenuLauncher {
649 @Override
650 public void launch(MouseEvent evt) {
651 if (cbWireframe.isSelected())
652 return;
653 super.launch(evt);
654 }
655
656 @Override
657 protected void showMenu(MouseEvent evt) {
658 menu = new MapPaintPopup();
659 super.showMenu(evt);
660 }
661 }
662
663 /**
664 * The popup menu displayed when right-clicking a map paint entry
665 */
666 public class MapPaintPopup extends JPopupMenu {
667 /**
668 * Constructs a new {@code MapPaintPopup}.
669 */
670 public MapPaintPopup() {
671 add(reloadAction);
672 add(new SaveAsAction());
673
674 JMenu setMenu = new JMenu(tr("Style settings"));
675 setMenu.setIcon(ImageProvider.overlay(ImageProvider.get("preference"),
676 ImageProvider.get("dialogs/mappaint", "pencil"),
677 ImageProvider.OverlayPosition.SOUTHEAST));
678 setMenu.setToolTipText(tr("Customize the style"));
679 add(setMenu);
680
681 int sel = tblStyles.getSelectionModel().getLeadSelectionIndex();
682 StyleSource style = null;
683 if (sel >= 0 && sel < model.getRowCount()) {
684 style = model.getRow(sel);
685 }
686 if (style == null || style.settings.isEmpty()) {
687 setMenu.setEnabled(false);
688 } else {
689 for (StyleSetting s : style.settings) {
690 s.addMenuEntry(setMenu);
691 }
692 }
693
694 addSeparator();
695 add(new InfoAction());
696 }
697 }
698}
Note: See TracBrowser for help on using the repository browser.