/******************************************************************************* * Copyright (c) 2010 Stefan A. Tzeggai. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * Stefan A. Tzeggai - initial API and implementation ******************************************************************************/ package org.geopublishing.atlasStyler.swing; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.concurrent.ExecutionException; import javax.swing.DefaultListModel; import javax.swing.Icon; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.SwingWorker; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; import org.geopublishing.atlasStyler.ASUtil; import org.geopublishing.atlasStyler.AtlasStylerVector; import org.geopublishing.atlasStyler.rulesLists.SingleRuleList; import org.geopublishing.atlasViewer.swing.Icons; import org.geotools.data.DataUtilities; import de.schmitzm.geotools.feature.FeatureUtil.GeometryForm; import de.schmitzm.io.IOUtil; import de.schmitzm.lang.LangUtil; import de.schmitzm.swing.swingworker.AtlasStatusDialog; import de.schmitzm.swing.swingworker.AtlasSwingWorker; /** * A special {@link JScrollPane} that does threaded filling of the GUI with SLD * Symbol buttons. * * @author <a href="mailto:skpublic@wikisquare.de">Stefan Alfons Tzeggai</a> * */ public class JScrollPaneSymbolsLocal extends JScrollPaneSymbols { protected Logger LOGGER = LangUtil.createLogger(this); protected final File dir; /** * * @param attType * The {@link GeometryAttributeType} determines which folder will * be scanned for SLD fragments. * * @author <a href="mailto:skpublic@wikisquare.de">Stefan Alfons Tzeggai</a> */ public JScrollPaneSymbolsLocal(GeometryForm geoForm) { super(geoForm); dir = AtlasStylerVector.getSymbolsDir(geoForm); rescan(false); } @Override protected JPopupMenu getPopupMenu() { if (popupMenu == null) { popupMenu = new JPopupMenu(); /******************************************************************* * Rename a Symbol from disk */ JMenuItem rename = new JMenuItem( AtlasStylerVector .R("SymbolSelector.Tabs.LocalSymbols.Action.Rename")); rename.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int index = getJListSymbols().locationToIndex( mouseCLickEvent.getPoint()); SingleRuleList singleLocalRulesList = (SingleRuleList) ((DefaultListModel) getJListSymbols() .getModel()).get(index); String symbolFileName = singleLocalRulesList.getStyleName() + ".sld"; File symbolFile = new File(AtlasStylerVector .getSymbolsDir(singleLocalRulesList .getGeometryForm()), symbolFileName); String newName = ASUtil.askForString( JScrollPaneSymbolsLocal.this, singleLocalRulesList.getStyleName(), AtlasStylerVector .R("SymbolSelector.Tabs.LocalSymbols.Action.Rename.AskForNewName")); if ((newName == null) || (newName.trim().equals("")) || (newName.equals(singleLocalRulesList .getStyleName()))) return; if (!newName.toLowerCase().endsWith(".sld")) { newName += ".sld"; } File newSymbolFile = new File(AtlasStylerVector .getSymbolsDir(singleLocalRulesList .getGeometryForm()), newName); try { FileUtils.moveFile(symbolFile, newSymbolFile); } catch (IOException e1) { LOGGER.error("rename failed", e1); rescan(true); String message = AtlasStylerVector .R("SymbolSelector.Tabs.LocalSymbols.Action.Rename.Error", symbolFile.getAbsolutePath(), newSymbolFile.getAbsolutePath()); LOGGER.warn(message); JOptionPane.showMessageDialog( JScrollPaneSymbolsLocal.this, message); } // Update the JListSymbols singleLocalRulesList.setStyleName(newName.substring(0, newName.length() - 4)); getJListSymbols().repaint(); } }); popupMenu.add(rename); /******************************************************************* * Delete a Symbol on disk */ JMenuItem remove = new JMenuItem( AtlasStylerVector .R("SymbolSelector.Tabs.LocalSymbols.Action.Delete")); remove.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int index = getJListSymbols().locationToIndex( mouseCLickEvent.getPoint()); SingleRuleList singleLocalRulesList = (SingleRuleList) ((DefaultListModel) getJListSymbols() .getModel()).get(index); String symbolFileName = singleLocalRulesList.getStyleName() + ".sld"; File symbolFile = new File(AtlasStylerVector .getSymbolsDir(singleLocalRulesList .getGeometryForm()), symbolFileName); int res = JOptionPane.showConfirmDialog( JScrollPaneSymbolsLocal.this, AtlasStylerVector .R("SymbolSelector.Tabs.LocalSymbols.Action.Delete.Ask", singleLocalRulesList.getStyleName(), symbolFile.getName()), "", JOptionPane.YES_NO_OPTION); if (res != JOptionPane.YES_OPTION) return; if (!symbolFile.delete()) { String message = AtlasStylerVector .R("SymbolSelector.Tabs.LocalSymbols.Action.Delete.Error", symbolFile.getName()); LOGGER.warn(message); JOptionPane.showMessageDialog( JScrollPaneSymbolsLocal.this, message); rescan(true); } else { // Delete the entry from the JListSymbols ((DefaultListModel) getJListSymbols().getModel()) .remove(index); // rescan(true); } } }); popupMenu.add(remove); popupMenu.add(new JPopupMenu.Separator()); /******************************************************************* * Rescan directory */ JMenuItem rescan = new JMenuItem( AtlasStylerVector .R("SymbolSelector.Tabs.LocalSymbols.Action.Rescan")); rescan.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { rescan(true); } }); popupMenu.add(rescan); } return popupMenu; } /** * @return A {@link SwingWorker} used in {@link #rescan(boolean)} * * @author <a href="mailto:skpublic@wikisquare.de">Stefan Alfons Tzeggai</a> */ @Override protected AtlasSwingWorker<List<SingleRuleList<?>>> getWorker() { final AtlasStatusDialog sd = new AtlasStatusDialog( JScrollPaneSymbolsLocal.this, AtlasStylerVector.R("LocalSymbolsSelector.process.loading_title"), AtlasStylerVector .R("LocalSymbolsSelector.process.loading_description")); // SwingWorkers may never be reused. Create it fresh! AtlasSwingWorker<List<SingleRuleList<?>>> swingWorker = new AtlasSwingWorker<List<SingleRuleList<?>>>( sd) { final DefaultListModel model = (DefaultListModel) getJListSymbols() .getModel(); @Override protected void done() { super.done(); try { /** * Create RulesLists and render the images */ List<SingleRuleList<?>> newlyFoundEntries = get(); /** * Finally add the RulesLists to the GUI */ for (SingleRuleList<?> newOne : newlyFoundEntries) { final Enumeration<?> existingObjects = model.elements(); boolean alreadyIn = false; while (existingObjects.hasMoreElements()) { String styleName = ((SingleRuleList) existingObjects .nextElement()).getStyleName(); // LOGGER.debug("comparing "+styleName + " vs " // + newOne.getStyleName()); if (styleName.equals(newOne.getStyleName())) { // A Symbol with the same StyleName already // exits alreadyIn = true; break; } } if (alreadyIn) continue; model.addElement(newOne); } } catch (InterruptedException e) { LOGGER.error( "While adding the newly found icons to the table model", e); } catch (ExecutionException e) { LOGGER.error( "While adding the newly found icons to the table model", e); } setViewportView(getJListSymbols()); doLayout(); repaint(); setVisible(true); } @Override protected List<SingleRuleList<?>> doInBackground() throws Exception { LOGGER.info("Seaching for local symbols on SwingWoker in " + IOUtil.escapePath(dir)); /** * Create RulesLists and render the images */ List<SingleRuleList<?>> entriesForTheList = new ArrayList<SingleRuleList<?>>(); String[] symbolPaths = dir.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { if ((name.endsWith(".sld")) || (name.endsWith(".SLD"))) return true; return false; } }); // i8n if (symbolPaths == null) throw new RuntimeException( "Error reading " + IOUtil.escapePath(dir) + ". Please check permissions or broken link? Access to local symbols is broken."); final List<String> symbolPathsList = Arrays.asList(symbolPaths); Collections.sort(symbolPathsList); /** * Add every symbol as a SymbolButton */ for (final String s : symbolPathsList) { // LOGGER.debug("s="+s); final File file = new File(dir, s); URL url = DataUtilities.fileToURL(file); String newNameWithOUtSLD = nameWithoutSld(url); sd.setDescription(newNameWithOUtSLD); cacheUrl(entriesForTheList, url); } return entriesForTheList; } }; return swingWorker; } @Override public String getDesc() { return AtlasStylerVector.R("SymbolSelector.Tabs.LocalSymbols"); } @Override public Icon getIcon() { return Icons.ICON_LOCAL; } @Override protected String getToolTip() { File symbolsDir = AtlasStylerVector.getSymbolsDir(geometryForm); // Be more windows friendly return AtlasStylerVector.R("SymbolSelector.Tabs.LocalSymbols.TT", IOUtil.escapePath(symbolsDir)); } }