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

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

see #4429 - Right click menu "undo, cut, copy, paste, delete, select all" for each text component (originally based on patch by NooN)

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