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

Last change on this file since 5576 was 5576, checked in by bastiK, 11 years ago

add *.zip to FileFilter (closes #8184)

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