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, 4 weeks 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.