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

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

see #10684 - remove remaining overlay() calls

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