package gdsc.smlm.ij.plugins;
import gdsc.core.utils.UnicodeReader;
import gdsc.smlm.utils.XmlUtils;
import gdsc.smlm.Version;
import ij.IJ;
import ij.gui.GenericDialog;
import ij.macro.ExtensionDescriptor;
import ij.macro.Functions;
import ij.macro.MacroExtension;
import ij.plugin.PlugIn;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.LinkedList;
/**
* Contains help dialogs for the GDSC ImageJ plugins
*/
public class About implements PlugIn, MacroExtension
{
private static String TITLE = "GDSC SMLM ImageJ Plugins";
public static String HELP_URL = "http://www.sussex.ac.uk/gdsc/intranet/microscopy/imagej/smlm_plugins";
private static String YEAR = "2016";
enum ConfigureOption
{
//@formatter:off
INSTALL{ public String getName() { return "Install"; }},
REMOVE{ public String getName() { return "Remove"; }},
EDIT{ public String getName() { return "Edit & Install"; }};
//@formatter:on
@Override
public String toString()
{
return getName();
}
/**
* Gets the name.
*
* @return the name
*/
abstract public String getName();
}
public void run(String arg)
{
SMLMUsageTracker.recordPlugin(this.getClass(), arg);
if (arg.equals("about"))
{
showAbout();
return;
}
if (arg.equals("uninstall"))
{
showUnintallDialog();
return;
}
if (arg.equals("toolset"))
{
installResource("/macros/toolsets/SMLM Tools.txt", "macros", "toolsets" + File.separator + "SMLM Tools.txt",
"SMLM toolset",
"Select the toolset from the ImageJ 'More Tools' menu to load buttons on to the ImageJ menu bar.",
ConfigureOption.INSTALL, ConfigureOption.REMOVE);
return;
}
if (arg.equals("config"))
{
int result = installResource("/gdsc/smlm/plugins.config", "plugins", "smlm.config",
"SMLM Tools Configuration",
"The configuration file is used to specify which plugins to display on the SMLM Tools window. Creating a custom file will need to be repeated when the available plugins change.",
ConfigureOption.INSTALL, ConfigureOption.EDIT, ConfigureOption.REMOVE);
// If install/remove was successful then reload the GDSC SMLM Panel if it is showing.
if (result != -1 && SMLMTools.isFrameVisible())
{
SMLMTools.closeFrame();
new SMLMTools();
}
return;
}
if (arg.equals("ext"))
{
setupExtensions();
return;
}
showAbout();
}
public static void showUnintallDialog()
{
IJ.showMessage(TITLE,
"To uninstall this plugin, move the SMLM jar out\n" + "of the plugins folder and restart ImageJ.");
}
public static void showAbout()
{
// Locate the README.txt file and load that into the dialog. Include revision
Class<About> resourceClass = About.class;
InputStream readmeStream = resourceClass.getResourceAsStream("/gdsc/smlm/README.txt");
StringBuilder msg = new StringBuilder();
String helpURL = HELP_URL;
String version = Version.getVersion();
String buildDate = Version.getBuildDate();
BufferedReader input = null;
try
{
// Read the contents of the README file
input = new BufferedReader(new UnicodeReader(readmeStream, null));
String line;
while ((line = input.readLine()) != null)
{
if (line.contains("http:"))
{
helpURL = line;
}
else
{
if (line.equals(""))
line = " "; // Required to insert a line in the GenericDialog
msg.append(line).append("\n");
}
}
}
catch (IOException e)
{
// Default message
msg.append("GDSC SMLM Plugins for ImageJ\n");
msg.append(" \n");
msg.append("Copyright (C) ").append(YEAR).append(" Alex Herbert\n");
msg.append("MRC Genome Damage and Stability Centre\n");
msg.append("University of Sussex, UK\n");
}
finally
{
try
{
input.close();
}
catch (IOException e)
{
}
}
// Build final message
msg = new StringBuilder(msg.toString().trim());
if (version != Version.UNKNOWN || buildDate != Version.UNKNOWN)
msg.append("\n \n");
if (version != Version.UNKNOWN)
msg.append("Version : ").append(version).append("\n");
if (buildDate != Version.UNKNOWN)
msg.append("Build Date : ").append(buildDate).append("\n");
if (helpURL != null)
msg.append("\n \n(Click help for more information)");
GenericDialog gd = new GenericDialog(TITLE);
gd.addMessage(msg.toString());
gd.addHelp(helpURL);
gd.hideCancelButton();
gd.showDialog();
}
/**
* @param resource
* @param ijDirectory
* @param destinationName
* @param resourceTitle
* @param notes
* @param options
* @return -1 on error, 0 if installed, 1 if removed
*/
private static int installResource(String resource, String ijDirectory, String destinationName,
String resourceTitle, String notes, ConfigureOption... options)
{
Class<About> resourceClass = About.class;
InputStream toolsetStream = resourceClass.getResourceAsStream(resource);
if (toolsetStream == null)
return -1;
String dir = IJ.getDirectory(ijDirectory);
if (dir == null)
{
IJ.error("Unable to locate " + ijDirectory + " directory");
return -1;
}
EnumSet<ConfigureOption> opt = EnumSet.of(options[0], options);
GenericDialog gd = new GenericDialog(TITLE);
String filename = dir + destinationName;
boolean fileExists = new File(filename).exists();
StringBuilder sb = new StringBuilder();
sb.append("Configure resource '").append(resourceTitle).append("' at:\n \n").append(filename);
if (notes != null)
sb.append("\n \n").append(XmlUtils.lineWrap(notes, 80, 0, null));
gd.addMessage(sb.toString());
// Configure the options
String[] choices = new String[3];
ConfigureOption[] optChoices = new ConfigureOption[choices.length];
int count = 0;
if (opt.contains(ConfigureOption.INSTALL))
{
choices[count] = ConfigureOption.INSTALL.toString();
if (fileExists)
choices[count] += " (overwrite)";
optChoices[count] = ConfigureOption.INSTALL;
count++;
}
if (opt.contains(ConfigureOption.EDIT))
{
choices[count] = ConfigureOption.EDIT.toString();
if (fileExists)
choices[count] += " (overwrite)";
optChoices[count] = ConfigureOption.EDIT;
count++;
}
if (opt.contains(ConfigureOption.REMOVE) && fileExists)
{
choices[count] = ConfigureOption.REMOVE.toString();
optChoices[count] = ConfigureOption.REMOVE;
count++;
}
if (count == 0)
return -1;
choices = Arrays.copyOf(choices, count);
gd.addChoice("Option", choices, choices[0]);
gd.showDialog();
if (gd.wasCanceled())
return -1;
ConfigureOption choice = optChoices[gd.getNextChoiceIndex()];
if (choice == ConfigureOption.REMOVE)
{
try
{
new File(filename).delete();
return 1;
}
catch (SecurityException e)
{
IJ.error("Unable to remove existing file");
}
return -1;
}
// Read the file
LinkedList<String> contents = new LinkedList<String>();
BufferedReader input = null;
try
{
// Read
input = new BufferedReader(new UnicodeReader(toolsetStream, null));
String line;
while ((line = input.readLine()) != null)
{
contents.add(line);
}
}
catch (IOException e)
{
IJ.error("Unable to install " + resourceTitle + ".\n \n" + e.getMessage());
return -1;
}
finally
{
close(input);
}
if (choice == ConfigureOption.EDIT)
{
// Allow the user to edit the file contents
gd = new GenericDialog(TITLE);
gd.addMessage("Edit the file contents before install:");
sb.setLength(0);
for (String line : contents)
sb.append(line).append("\n");
gd.addTextAreas(sb.toString(), null, 20, 80);
gd.showDialog();
if (gd.wasOKed())
{
contents.clear();
String text = gd.getNextText();
for (String line : text.split("\n"))
contents.add(line);
}
}
// Install the file
BufferedWriter output = null;
try
{
// Write
FileOutputStream fos = new FileOutputStream(filename);
output = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
for (String content : contents)
{
output.write(content);
output.newLine();
}
}
catch (IOException e)
{
IJ.error("Unable to install " + resourceTitle + ".\n \n" + e.getMessage());
}
finally
{
close(output);
}
return 0;
}
private static void close(BufferedReader input)
{
if (input != null)
{
try
{
input.close();
}
catch (IOException e)
{
}
}
}
private static void close(BufferedWriter output)
{
if (output != null)
{
try
{
output.close();
}
catch (IOException e)
{
}
}
}
private void setupExtensions()
{
Functions.registerExtensions(this);
}
/*
* (non-Javadoc)
*
* @see ij.macro.MacroExtension#handleExtension(java.lang.String, java.lang.Object[])
*/
public String handleExtension(String name, Object[] args)
{
if (name == null)
return "";
if (name.equals("getNumberOfSpecies"))
{
return TraceDiffusion.getNumberOfSpecies(args);
}
if (name.equals("getD"))
{
return TraceDiffusion.getD(args);
}
if (name.equals("getF"))
{
return TraceDiffusion.getF(args);
}
if (name.equals("getSpecies"))
{
return TraceDiffusion.getSpecies(args);
}
return "";
}
/*
* (non-Javadoc)
*
* @see ij.macro.MacroExtension#getExtensionFunctions()
*/
public ExtensionDescriptor[] getExtensionFunctions()
{
ArrayList<ExtensionDescriptor> list = new ArrayList<ExtensionDescriptor>(3);
list.add(ExtensionDescriptor.newDescriptor("getNumberOfSpecies", this,
MacroExtension.ARG_NUMBER + MacroExtension.ARG_OUTPUT));
list.add(ExtensionDescriptor.newDescriptor("getD", this, MacroExtension.ARG_NUMBER,
MacroExtension.ARG_NUMBER + MacroExtension.ARG_OUTPUT));
list.add(ExtensionDescriptor.newDescriptor("getF", this, MacroExtension.ARG_NUMBER,
MacroExtension.ARG_NUMBER + MacroExtension.ARG_OUTPUT));
list.add(ExtensionDescriptor.newDescriptor("getSpecies", this, MacroExtension.ARG_NUMBER,
MacroExtension.ARG_NUMBER + MacroExtension.ARG_OUTPUT,
MacroExtension.ARG_NUMBER + MacroExtension.ARG_OUTPUT));
return list.toArray(new ExtensionDescriptor[list.size()]);
}
}