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

Last change on this file since 19050 was 19050, checked in by taylor.smock, 15 months ago

Revert most var changes from r19048, fix most new compile warnings and checkstyle issues

Also, document why various ErrorProne checks were originally disabled and fix
generic SonarLint issues.

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