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

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

sonar - squid:S1166 - Exception handlers should preserve the original exceptions

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