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

Last change on this file since 6426 was 6426, checked in by simon04, 10 years ago

see #9309 - provide direct menu items to preset/imagery preferences

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