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

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

sonar - squid:AssignmentInSubExpressionCheck - Assignments should not be made from within sub-expressions

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