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

Last change on this file since 7668 was 7668, checked in by stoecker, 9 years ago

cleanup icons, mark undetected icons, set proper mimetype, delete unused icons, update geticons script

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