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

Last change on this file since 7450 was 7450, checked in by bastiK, 10 years ago

fixed #10421 - User-settings for mapcss mappaint styles

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