package net.sf.openrocket.gui.util; import java.awt.Desktop; import java.awt.Window; import java.io.File; import java.io.IOException; import java.text.MessageFormat; import net.sf.openrocket.appearance.AppearanceBuilder; import net.sf.openrocket.appearance.DecalImage; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.dialogs.EditDecalDialog; import net.sf.openrocket.gui.watcher.FileWatcher; import net.sf.openrocket.gui.watcher.WatchEvent; import net.sf.openrocket.gui.watcher.WatchService; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.RocketComponent; import com.google.inject.Inject; public class EditDecalHelper { @Inject private WatchService watchService; @Inject private Translator trans; @Inject private SwingPreferences prefs; public static class EditDecalHelperException extends Exception { private String extraMessage = ""; public EditDecalHelperException(String message, Throwable cause) { super(message, cause); } public EditDecalHelperException(String message, String extraMessage, Throwable cause) { super(message, cause); this.extraMessage = extraMessage; } @Override public String getMessage() { if (extraMessage == null || extraMessage.isEmpty()) { return super.getMessage(); } return super.getMessage() + "\n" + getExtraMessage(); } public String getExtraMessage() { return extraMessage; } } /** * Returns the decal which is edited. The decal edited might be different from the one passed in * if only a single copy of a decal should be edited. * * @param parent * @param doc * @param component * @param decal * @return * @throws EditDecalHelperException */ public DecalImage editDecal(Window parent, OpenRocketDocument doc, RocketComponent component, DecalImage decal) throws EditDecalHelperException { boolean sysPrefSet = prefs.isDecalEditorPreferenceSet(); int usageCount = doc.countDecalUsage(decal); //First Check preferences if (sysPrefSet && usageCount == 1) { launchEditor(prefs.isDecalEditorPreferenceSystem(), prefs.getDecalEditorCommandLine(), decal); return decal; } EditDecalDialog dialog = new EditDecalDialog(parent, !sysPrefSet, usageCount); dialog.setVisible(true); if (dialog.isCancel()) { return decal; } // Do we use the System Preference Editor or from the dialog? boolean useSystemEditor = false; String commandLine = ""; if (sysPrefSet) { useSystemEditor = prefs.isDecalEditorPreferenceSystem(); commandLine = prefs.getDecalEditorCommandLine(); } else { useSystemEditor = dialog.isUseSystemEditor(); commandLine = dialog.getCommandLine(); // Do we need to save the preferences? if (dialog.isSavePreferences()) { prefs.setDecalEditorPreference(useSystemEditor, commandLine); } } if (dialog.isEditOne()) { decal = makeDecalUnique(doc, component, decal); } launchEditor(useSystemEditor, commandLine, decal); return decal; } private static DecalImage makeDecalUnique(OpenRocketDocument doc, RocketComponent component, DecalImage decal) { DecalImage newImage = doc.makeUniqueDecal(decal); AppearanceBuilder appearanceBuilder = new AppearanceBuilder(component.getAppearance()); appearanceBuilder.setImage(newImage); component.setAppearance(appearanceBuilder.getAppearance()); return newImage; } private void launchEditor(boolean useSystemEditor, String commandTemplate, final DecalImage decal) throws EditDecalHelperException { String decalId = decal.getName(); // Create Temp File. int dotlocation = decalId.lastIndexOf('.'); String extension = "tmp"; if (dotlocation > 0 && dotlocation < decalId.length()) { extension = decalId.substring(dotlocation); } File tmpFile = null; try { tmpFile = File.createTempFile("OR_graphics", extension); } catch (IOException ioex) { String message = MessageFormat.format(trans.get("EditDecalHelper.createFileException"), tmpFile.getAbsoluteFile()); throw new EditDecalHelperException(message, ioex); } try { decal.exportImage(tmpFile); watchService.register(new FileWatcher(tmpFile) { @Override public void handleEvent(WatchEvent evt) { decal.fireChangeEvent(evt); //System.out.println(this.getFile() + " has changed"); } }); } catch (IOException ioex) { String message = MessageFormat.format(trans.get("EditDecalHelper.createFileException"), tmpFile.getAbsoluteFile()); throw new EditDecalHelperException(message, ioex); } if (useSystemEditor) { try { Desktop.getDesktop().edit(tmpFile); } catch (Exception ioex) { throw new EditDecalHelperException(trans.get("EditDecalHelper.launchSystemEditorException"), trans.get("EditDecalHelper.editPreferencesHelp"), ioex); } } else { String filename = tmpFile.getAbsolutePath(); String command; if (commandTemplate.contains("%%")) { command = commandTemplate.replace("%%", filename); } else { command = commandTemplate + " " + filename; } try { Runtime.getRuntime().exec(command); } catch (IOException ioex) { String message = MessageFormat.format(trans.get("EditDecalHelper.launchCustomEditorException"), command); throw new EditDecalHelperException(message, trans.get("EditDecalHelper.editPreferencesHelp"), ioex); } } } }