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

Last change on this file since 12620 was 12620, checked in by Don-vip, 7 years ago

see #15182 - deprecate all Main logging methods and introduce suitable replacements in Logging for most of them

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