|
From: <pat...@us...> - 2011-03-01 20:10:37
|
Revision: 1231
http://cishell.svn.sourceforge.net/cishell/?rev=1231&view=rev
Author: pataphil
Date: 2011-03-01 20:10:28 +0000 (Tue, 01 Mar 2011)
Log Message:
-----------
* Implemented the FileLoaderService and the FileSaverService.
* Reviewed by Joseph.
Modified Paths:
--------------
trunk/core/org.cishell.framework/META-INF/MANIFEST.MF
trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadException.java
trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoaderService.java
trunk/core/org.cishell.reference/META-INF/MANIFEST.MF
trunk/core/org.cishell.reference/OSGI-INF/fileloader.properties
trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileFormatSelector.java
trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileLoaderServiceImpl.java
trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileSelectorRunnable.java
Added Paths:
-----------
trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/
trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/AbstractFileSaverService.java
trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaveException.java
trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaveListener.java
trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaverService.java
trunk/core/org.cishell.reference/OSGI-INF/filesaver.properties
trunk/core/org.cishell.reference/OSGI-INF/filesaver.xml
trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/
trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/DataFormatChooser.java
trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/FileSaverServiceImpl.java
trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/SaveAsController.java
trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/persistence/
trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/persistence/AbstractDialog.java
Removed Paths:
-------------
trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/AbstractDialog.java
Modified: trunk/core/org.cishell.framework/META-INF/MANIFEST.MF
===================================================================
--- trunk/core/org.cishell.framework/META-INF/MANIFEST.MF 2011-03-01 20:09:46 UTC (rev 1230)
+++ trunk/core/org.cishell.framework/META-INF/MANIFEST.MF 2011-03-01 20:10:28 UTC (rev 1231)
@@ -11,6 +11,7 @@
org.osgi.service.prefs
Export-Package: org.cishell.app.service.datamanager;version="1.0.0",
org.cishell.app.service.fileloader,
+ org.cishell.app.service.filesaver,
org.cishell.app.service.scheduler;version="1.0.0",
org.cishell.framework;version="1.0.0",
org.cishell.framework.algorithm;version="1.0.0",
Modified: trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadException.java
===================================================================
--- trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadException.java 2011-03-01 20:09:46 UTC (rev 1230)
+++ trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoadException.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -14,8 +14,4 @@
public FileLoadException(String message) {
super(message);
}
-
- public FileLoadException() {
- this("Algorithm canceled by user.");
- }
}
Modified: trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoaderService.java
===================================================================
--- trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoaderService.java 2011-03-01 20:09:46 UTC (rev 1230)
+++ trunk/core/org.cishell.framework/src/org/cishell/app/service/fileloader/FileLoaderService.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -13,11 +13,15 @@
public void registerListener(FileLoadListener listener);
public void unregisterListener(FileLoadListener listener);
+ /* TODO make abstract default class, template method pattern, blah blah */
+ public File[] getFilesToLoadFromUser(
+ boolean selectSingleFile, String[] filterExtensions) throws FileLoadException;
public Data[] loadFilesFromUserSelection(
BundleContext bundleContext,
CIShellContext ciShellContext,
LogService logger,
- ProgressMonitor progressMonitor) throws FileLoadException;
+ ProgressMonitor progressMonitor,
+ boolean selectSingleFile) throws FileLoadException;
public Data[] loadFiles(
BundleContext bundleContext,
CIShellContext ciShellContext,
Added: trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/AbstractFileSaverService.java
===================================================================
--- trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/AbstractFileSaverService.java (rev 0)
+++ trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/AbstractFileSaverService.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -0,0 +1,80 @@
+package org.cishell.app.service.filesaver;
+
+import java.io.File;
+import java.util.Collection;
+
+import org.cishell.framework.data.Data;
+import org.cishell.service.conversion.ConversionException;
+import org.cishell.service.conversion.Converter;
+
+public abstract class AbstractFileSaverService implements FileSaverService {
+ private Collection<FileSaveListener> listeners;
+
+ public void registerListener(FileSaveListener listener) {
+ this.listeners.add(listener);
+ }
+
+ public void unregisterListener(FileSaveListener listener) {
+ this.listeners.remove(listener);
+ }
+
+ public File promptForTargetFile() throws FileSaveException {
+ return promptForTargetFile("");
+ }
+
+ public File promptForTargetFile(Data datum) throws FileSaveException {
+ return promptForTargetFile((File) datum.getData());
+ }
+
+ public File promptForTargetFile(File outputFile) throws FileSaveException {
+ return promptForTargetFile(outputFile.getAbsolutePath()); // TODO getName?
+ }
+
+ public File save(Data sourceDatum) throws FileSaveException {
+ return save((File) sourceDatum.getData());
+ }
+
+ public File save(File sourceFile) throws FileSaveException {
+ File targetFile = promptForTargetFile(sourceFile);
+ saveTo(sourceFile, targetFile);
+
+ return targetFile;
+ }
+
+ public Data save(Data sourceDatum, String targetMimeType)
+ throws FileSaveException {
+ Converter converter = promptForConverter(sourceDatum, targetMimeType);
+
+ if (converter != null) {
+ return save(converter, sourceDatum);
+ } else {
+ // TODO: CanceledException?
+ return null;
+ }
+ }
+
+ // TODO: What to actually return here? Maybe Pair<Data, File> (LOL)?
+ public Data save(Converter converter, Data sourceDatum)
+ throws FileSaveException {
+ File targetFile = promptForTargetFile(sourceDatum);
+
+ if (targetFile != null) {
+ return save(converter, sourceDatum, targetFile);
+ } else {
+ // TODO: CanceledException?
+ return null;
+ }
+ }
+
+ public Data save(
+ Converter converter, Data sourceDatum, File targetFile) throws FileSaveException {
+ try {
+ Data convertedDatum = converter.convert(sourceDatum);
+ saveTo((File) convertedDatum.getData(), targetFile);
+
+ return convertedDatum;
+ } catch (ConversionException e) {
+ throw new FileSaveException(e.getMessage(), e);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaveException.java
===================================================================
--- trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaveException.java (rev 0)
+++ trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaveException.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -0,0 +1,17 @@
+package org.cishell.app.service.filesaver;
+
+public class FileSaveException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public FileSaveException(String message, Throwable exception) {
+ super(message, exception);
+ }
+
+ public FileSaveException(Throwable exception) {
+ super(exception);
+ }
+
+ public FileSaveException(String message) {
+ super(message);
+ }
+}
Added: trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaveListener.java
===================================================================
--- trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaveListener.java (rev 0)
+++ trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaveListener.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -0,0 +1,7 @@
+package org.cishell.app.service.filesaver;
+
+import java.io.File;
+
+public interface FileSaveListener {
+ void fileSaved(File file);
+}
\ No newline at end of file
Added: trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaverService.java
===================================================================
--- trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaverService.java (rev 0)
+++ trunk/core/org.cishell.framework/src/org/cishell/app/service/filesaver/FileSaverService.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -0,0 +1,40 @@
+package org.cishell.app.service.filesaver;
+
+import java.io.File;
+
+import org.cishell.framework.data.Data;
+import org.cishell.service.conversion.Converter;
+
+/* TODO Push down methods with an obvious implementation in terms of the "atomic" methods
+ * (choose converter, choose file, perform save) into an abstract class that implements this.
+ * Then FileSaverServiceImpl extends the abstract class.
+ */
+public interface FileSaverService {
+ public void registerListener(FileSaveListener listener);
+ public void unregisterListener(FileSaveListener listener);
+
+ public Converter promptForConverter(final Data outDatum, String targetMimeType)
+ throws FileSaveException;
+
+ public File promptForTargetFile() throws FileSaveException;
+ public File promptForTargetFile(Data datum) throws FileSaveException;
+ public File promptForTargetFile(File outputFile) throws FileSaveException;
+ public File promptForTargetFile(String fileName) throws FileSaveException;
+
+ /* TODO I'm seriously tempted to recommend that all methods beyond this point be called
+ * "save" or "saveToFile" or something, and just have a bit of very concise Javadoc that
+ * explains what may be prompted for? Alternatively, ask another dev about doing the null
+ * arguments idea.
+ */
+ // TODO (NEW): Just Javadoc these really well?
+ public File save(Data sourceDatum) throws FileSaveException;
+ public File save(File sourceFile) throws FileSaveException;
+ public void saveTo(File sourceFile, File targetFile) throws FileSaveException;
+
+ // TODO: What to actually return here? the File object for the one on disk
+ /* TODO sourceDatum always first, targetType/File last */
+ public Data save(Data sourceDatum, String targetMimeType) throws FileSaveException;
+ public Data save(Converter converter, Data sourceDatum) throws FileSaveException;
+ public Data save(
+ Converter converter, Data sourceDatum, File targetFile) throws FileSaveException;
+}
\ No newline at end of file
Modified: trunk/core/org.cishell.reference/META-INF/MANIFEST.MF
===================================================================
--- trunk/core/org.cishell.reference/META-INF/MANIFEST.MF 2011-03-01 20:09:46 UTC (rev 1230)
+++ trunk/core/org.cishell.reference/META-INF/MANIFEST.MF 2011-03-01 20:10:28 UTC (rev 1231)
@@ -2,8 +2,11 @@
Bundle-Name: CIShell Reference Service Implementations
Bundle-SymbolicName: org.cishell.reference
Bundle-Version: 1.0.0
-Import-Package: org.cishell.app.service.datamanager,
+Import-Package: com.google.common.base,
+ com.google.common.collect,
+ org.cishell.app.service.datamanager,
org.cishell.app.service.fileloader,
+ org.cishell.app.service.filesaver,
org.cishell.app.service.scheduler;version="1.0.0",
org.cishell.framework;version="1.0.0",
org.cishell.framework.algorithm;version="1.0.0",
@@ -13,12 +16,15 @@
org.cishell.service.guibuilder;version="1.0.0",
org.osgi.framework,
org.osgi.service.cm;version="1.2.0",
+ org.osgi.service.component;version="1.0.0",
org.osgi.service.log,
org.osgi.service.metatype;version="1.1.0",
org.osgi.service.prefs
Export-Package: org.cishell.reference.app.service.algorithminvocation,
org.cishell.reference.app.service.datamanager,
org.cishell.reference.app.service.fileloader,
+ org.cishell.reference.app.service.filesaver,
+ org.cishell.reference.app.service.persistence,
org.cishell.reference.app.service.scheduler,
org.cishell.reference.service.conversion,
org.cishell.reference.service.metatype
@@ -27,6 +33,6 @@
org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.update.ui
-Service-Component: OSGI-INF/fileloader.xml
+Service-Component: OSGI-INF/fileloader.xml, OSGI-INF/filesaver.xml
Bundle-RequiredExecutionEnvironment: J2SE-1.5
X-AutoStart: true
Modified: trunk/core/org.cishell.reference/OSGI-INF/fileloader.properties
===================================================================
--- trunk/core/org.cishell.reference/OSGI-INF/fileloader.properties 2011-03-01 20:09:46 UTC (rev 1230)
+++ trunk/core/org.cishell.reference/OSGI-INF/fileloader.properties 2011-03-01 20:10:28 UTC (rev 1231)
@@ -4,7 +4,7 @@
#description=This allows users to select files from the file system and load them to Data Model window.
#in_data=null
#out_data=java.lang.Object
-service.pid=org.cishell.reference.app.service.fileloader.FileLoadServiceImpl
+service.pid=org.cishell.reference.app.service.fileloader.FileLoaderServiceImpl
remoteable=true
prefs_published=local
receive_prefs=true
Added: trunk/core/org.cishell.reference/OSGI-INF/filesaver.properties
===================================================================
--- trunk/core/org.cishell.reference/OSGI-INF/filesaver.properties (rev 0)
+++ trunk/core/org.cishell.reference/OSGI-INF/filesaver.properties 2011-03-01 20:10:28 UTC (rev 1231)
@@ -0,0 +1,11 @@
+#menu_path=File/start
+#label=Load...
+#shortcut=ctrl+alt+o
+#description=This allows users to select files from the file system and load them to Data Model window.
+#in_data=null
+#out_data=java.lang.Object
+service.pid=org.cishell.reference.app.service.filesaver.FileSaverServiceImpl
+remoteable=true
+prefs_published=local
+receive_prefs=true
+#documentation_url=http://wiki.slis.indiana.edu:8080/display/ALGDOC/Data+Formats
\ No newline at end of file
Added: trunk/core/org.cishell.reference/OSGI-INF/filesaver.xml
===================================================================
--- trunk/core/org.cishell.reference/OSGI-INF/filesaver.xml (rev 0)
+++ trunk/core/org.cishell.reference/OSGI-INF/filesaver.xml 2011-03-01 20:10:28 UTC (rev 1231)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component name="org.cishell.reference.app.service.filesaver.FileSaverServiceImpl.component" immediate="true">
+ <implementation class="org.cishell.reference.app.service.filesaver.FileSaverServiceImpl"/>
+ <reference name="DCS" interface="org.cishell.service.conversion.DataConversionService"/>
+ <reference name="GBS" interface="org.cishell.service.guibuilder.GUIBuilderService"/>
+ <reference name="LOG" interface="org.osgi.service.log.LogService"/>
+
+ <service>
+ <provide interface="org.cishell.app.service.filesaver.FileSaverService"/>
+ </service>
+</component>
\ No newline at end of file
Deleted: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/AbstractDialog.java
===================================================================
--- trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/AbstractDialog.java 2011-03-01 20:09:46 UTC (rev 1230)
+++ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/AbstractDialog.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -1,490 +0,0 @@
-/*
- * InfoVis CyberInfrastructure: A Data-Code-Compute Resource for Research
- * and Education in Information Visualization (http://iv.slis.indiana.edu/).
- *
- * Created on Feb 22, 2005 at Indiana University.
- */
-package org.cishell.reference.app.service.fileloader;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-
-/**
- * This class provides a DialogBox structure that can be extended to create Dialogs for CIShell.
- * This framework will enforce consistency in the look and feel of Dialogs in CIShell by providing a
- * standard layout of description, content, and buttons[, along with a choice of icon images
- * defined as constants in this class]. An optional details section allows the Dialog designer
- * to provide additional information when the details button is pressed.
- *
- * @author Team IVC
- */
-public abstract class AbstractDialog extends Dialog {
- private static final int DETAILS_HEIGHT = 75;
-
- public static Image INFORMATION;
- public static Image WARNING;
- public static Image ERROR;
- public static Image QUESTION;
- public static Image WORKING;
-
- static {
- Runnable runner = new Runnable() {
- public void run() {
- INFORMATION = Display.getDefault().getSystemImage(SWT.ICON_INFORMATION);
- WARNING = Display.getDefault().getSystemImage(SWT.ICON_WARNING);
- ERROR = Display.getDefault().getSystemImage(SWT.ICON_ERROR);
- QUESTION = Display.getDefault().getSystemImage(SWT.ICON_QUESTION);
- WORKING = Display.getDefault().getSystemImage(SWT.ICON_WORKING);
- }};
-
- if (Display.getDefault().getThread() == Thread.currentThread()) {
- runner.run();
- } else {
- Display.getDefault().asyncExec(runner);
- }
- }
-
-
- private String description = "";
- private String detailsString = "";
- private Text detailsText;
- private Shell shell;
- private Image image;
- private boolean success;
- private Composite header;
- private Composite content;
- private Composite buttons;
- private Shell parent;
-
- /**
- * Creates a new AbstractDialog object.
- *
- * @param parent the parent Shell of this AbstractDialog
- * @param title the title to put in the title bar of this AbstractDialog
- * @param image the Image to display to the left of the description specified
- * for this AbstractDialog. This will usually be one of:
- * <ul>
- * <li>AbstractDialog.WARNING</li>
- * <li>AbstractDialog.INFORMATION</li>
- * <li>AbstractDialog.ERROR</li>
- * <li>AbstractDialog.WORKING</li>
- * <li>AbstractDialog.QUESTION</li>
- * </ul>
- */
- public AbstractDialog(Shell parent, String title, Image image) {
- super(parent, 0);
- setText(title);
- this.image = image;
- this.parent = parent;
- init();
- }
-
- /**
- * Closes this AbstractDialog.
- *
- * @param success true if the dialog was successful, false if it
- * was cancelled by the user (or closed prematurely)
- */
- public void close(boolean success){
- shell.dispose();
- this.success = success;
- }
-
- /**
- * Returns the shell used by this AbstractDialog
- *
- * @return the shell used by this AbstractDialog
- */
- public Shell getShell(){
- return shell;
- }
-
- /**
- * Initializes this AbstractDialog. This consists of resetting all of the
- * customizable components like the content area, details pane, buttons,
- * and description label, and readying the dialog to be refilled with
- * new content.
- */
- public void init(){
- if(shell != null)
- shell.dispose();
-
- shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE);
-
- if (parent != null)
- shell.setImage(parent.getImage());
-
- shell.setText(getText());
- GridLayout layout = new GridLayout();
- layout.numColumns = 1;
- shell.setLayout(layout);
- }
-
- /**
- * Opens this AbstractDialog.
- *
- * @return true if this AbstractDialog was closed by clicking the 'x' in the upper right
- * corner of the window, signifying a cancellation, false if the dialog is exited otherwise.
- */
- public boolean open() {
- if (shell.getDisplay().getThread() == Thread.currentThread()) {
- doOpen();
- } else {
- shell.getDisplay().syncExec(new Runnable() {
- public void run() {
- doOpen();
- }});
- }
-
- Display display = getParent().getDisplay();
-
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- }
-
- return success;
- }
-
- protected void doOpen() {
- success = true;
-
- setupHeader();
- setupContent();
- setupButtons();
-
- shell.pack();
- setLocation();
- shell.open();
- shell.addShellListener(new ShellAdapter(){
- public void shellClosed(ShellEvent e) {
- success = false;
- }
- });
- }
-
- /*
- * centers the dialog on its parents shell
- */
- private void setLocation(){
- Point parentLocation = parent.getLocation();
- int parentWidth = parent.getSize().x;
- int parentHeight = parent.getSize().y;
- int shellWidth = shell.getSize().x;
- int shellHeight = shell.getSize().y;
-
- int x = parentLocation.x + (parentWidth - shellWidth)/2;
- int y = parentLocation.y + (parentHeight - shellHeight)/2;
- shell.setLocation(x, y);
- }
-
- /**
- * Sets the Description of this AbstractDialog. This is the textField that is displayed in the
- * top section of the Dialog window, giving information about the question that is being
- * asked or the information that is being given.
- *
- * @param description the description for this AbstractDialog to use
- */
- public void setDescription(String description) {
- this.description = description;
- }
-
- /**
- * Sets the details textField of this AbstractDialog. This is the textField that is displayed in the lower
- * section of the Dialog window when the user presses the "Details >>" button. If this String
- * is null or the empty string, the details button will be disabled.
- *
- * @param details DOCUMENT ME!
- */
- public void setDetails(String details) {
- this.detailsString = details;
- }
-
- /**
- * Creates the Buttons to use in this AbstractDialog based on the given parent. These are
- * the buttons that show up at the bottom of the dialog for user input, such as a
- * "Yes/No" group or "Continue/Cancel" or something like that. This does not encompass all
- * Buttons created in the dialog (such as those created in the content section), just those
- * to display at the bottom of the dialog.
- *
- * @param parent the parent to be used to create the Buttons for this AbstractDialog
- */
- public abstract void createDialogButtons(Composite parent);
-
- /**
- * Creates the content section of this AbstractDialog based on the given parent.
- * This section is where all of the "guts" of the AbstractDialog go, specifying the controls
- * that are needed to interact with the user and provide whatever questions or information
- * are needed.
- *
- * @param parent the parent to be used to create the Buttosn for this AbstractDialog
- *
- * @return the Composite that is created to display the content of this AbstractDialog
- */
- public abstract Composite createContent(Composite parent);
-
- /*
- * Sets up the header section of the dialog. This section contains the image for the
- * type of dialog it is, as well as the description label
- */
- private void setupHeader() {
- header = new Composite(shell, SWT.NONE);
- header.setLayoutData(new GridData(GridData.FILL_BOTH));
- GridLayout layout = new GridLayout();
- layout.numColumns = 2;
- header.setLayout(layout);
-
- Label canvas = new Label(header, SWT.NONE);
- if (image != null) {
- canvas.setImage(image);
- }
- GridData canvasData = new GridData();
- canvasData.heightHint = image.getBounds().height;
- canvas.setLayoutData(canvasData);
-
- Label desc = new Label(header, SWT.WRAP);
-
- if ((description != null) && !description.equals("")) {
- desc.setText(description);
- }
- }
-
- /*
- * sets up the content section of the dialog, this calls the abstract method to
- * create the content that must be implemented by all subclasses
- */
- private void setupContent() {
- content = createContent(shell);
-
- if (content != null) {
- content.setLayoutData(new GridData(GridData.FILL_BOTH));
- }
- }
-
- /*
- * sets up the button section in the bottom of the dialog. These buttons
- * are created in the abstract method createDialogButtons(parent). In addition to
- * any created buttons, a "Details >>" button is added to allow the user to see any
- * details that are available in the current Dialog.
- */
- private void setupButtons() {
- buttons = new Composite(shell, SWT.NONE);
- buttons.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_END));
-
- //there are two sections, all the user stuff to the left, and
- //then the details button on the far right
- //User Buttons Section
- createDialogButtons(buttons);
- Control[] controls = buttons.getChildren();
- GridLayout buttonsLayout = new GridLayout();
- buttonsLayout.numColumns = controls.length + 1;
- buttonsLayout.makeColumnsEqualWidth = true;
- buttons.setLayout(buttonsLayout);
-
- //setup the grid data for each button for standard look
- for (int i = 0; i < controls.length; i++) {
- controls[i].setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- }
-
- //Details Button section
- final Button details = new Button(buttons, SWT.PUSH);
- details.setText("Details >>");
- details.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- details.addSelectionListener(new SelectionAdapter() {
- public synchronized void widgetSelected(SelectionEvent e) {
- GridData data = (GridData) detailsText.getLayoutData();
-
- if (detailsText.getVisible()) {
- detailsText.setText("");
- details.setText("Details >>");
- data.heightHint = 0;
- data.grabExcessHorizontalSpace = false;
- data.grabExcessVerticalSpace = false;
- } else {
- detailsText.setText(detailsString);
- details.setText("Details <<");
- data.heightHint = DETAILS_HEIGHT;
- data.grabExcessHorizontalSpace = true;
- data.grabExcessVerticalSpace = true;
- }
-
- detailsText.setLayoutData(data);
- detailsText.setVisible(!detailsText.getVisible());
-
- shell.setSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));
- shell.layout();
- }
- });
-
- setupDetails();
- details.setEnabled(detailsString != null && !detailsString.equals(""));
- }
-
- /*
- * creates the details textField box when the "Details >>" button is toggled
- */
- private void setupDetails() {
- detailsText = new Text(shell, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL);
- detailsText.setEditable(false);
- detailsText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
-
- GridData data = new GridData(GridData.FILL_BOTH |
- GridData.GRAB_VERTICAL | GridData.GRAB_HORIZONTAL);
- data.widthHint = 400;
-
- detailsText.setLayoutData(data);
- detailsText.setVisible(false);
- }
-
- /**
- * Open a standard error dialog with OK button
- *
- * @param parent the parent Shell of this dialog
- * @param title the textField to display in the title bar of this dialog
- * @param message the message to give in the dialog's body
- * @param details the textField to put in the details pane to be visible when the
- * "Details >>" button is pressed (can be null or empty, resulting
- * in the "Details >>" button not being enabled)
- * @return true if the dialog was exited by pressing the OK button, false
- * if it was cancelled by pressing the 'x' in the title bar
- */
- public static boolean openError(Shell parent, String title, String message, String details){
- return openOKDialog(parent, ERROR, title, message, details);
- }
-
- /**
- * Open a standard information dialog with OK button
- *
- * @param parent the parent Shell of this dialog
- * @param title the textField to display in the title bar of this dialog
- * @param message the message to give in the dialog's body
- * @param details the textField to put in the details pane to be visible when the
- * "Details >>" button is pressed (can be null or empty, resulting
- * in the "Details >>" button not being enabled) * @return true if the dialog was exited by pressing the OK button, false
- * if it was cancelled by pressing the 'x' in the title bar
- */
- public static boolean openInformation(Shell parent, String title, String message, String details){
- return openOKDialog(parent, INFORMATION, title, message, details);
- }
-
- /**
- * Open a standard warning dialog with OK button
- *
- * @param parent the parent Shell of this dialog
- * @param title the textField to display in the title bar of this dialog
- * @param message the message to give in the dialog's body
- * @param details the textField to put in the details pane to be visible when the
- * "Details >>" button is pressed (can be null or empty, resulting
- * in the "Details >>" button not being enabled) * @return true if the dialog was exited by pressing the OK button, false
- * if it was cancelled by pressing the 'x' in the title bar
- */
- public static boolean openWarning(Shell parent, String title, String message, String details){
- return openOKDialog(parent, WARNING, title, message, details);
- }
-
- /**
- * Open a standard question dialog with Yes/No buttons
- *
- * @param parent the parent Shell of this dialog
- * @param title the textField to display in the title bar of this dialog
- * @param message the message to give in the dialog's body
- * @param details the textField to put in the details pane to be visible when the
- * "Details >>" button is pressed (can be null or empty, resulting
- * in the "Details >>" button not being enabled) * @return true if the dialog was exited by pressing the OK button, false
- * if it was cancelled by pressing the 'x' in the title bar or pressing the
- * No button
- */
- public static boolean openQuestion(Shell parent, String title, String message, String details){
- return openConfirmDenyDialog(parent, QUESTION, title, message, details, "Yes", "No");
- }
-
- /**
- * Open a standard confirmation dialog with OK/Cancel buttons
- *
- * @param parent the parent Shell of this dialog
- * @param title the textField to display in the title bar of this dialog
- * @param message the message to give in the dialog's body
- * @param details the textField to put in the details pane to be visible when the
- * "Details >>" button is pressed (can be null or empty, resulting
- * in the "Details >>" button not being enabled) * @return true if the dialog was exited by pressing the OK button, false
- * if it was cancelled by pressing the 'x' in the title bar or pressing
- * the Cancel button
- */
- public static boolean openConfirm(Shell parent, String title, String message, String details){
- return openConfirmDenyDialog(parent, QUESTION, title, message, details, "OK", "Cancel");
- }
-
- /*
- * helper to create OK dialogs: error, warning, information
- */
- private static boolean openOKDialog(Shell parent, Image image, String title, String message, String details){
- AbstractDialog okDialog = new AbstractDialog(parent, title, image){
- public void createDialogButtons(Composite parent) {
- Button ok = new Button(parent, SWT.PUSH);
- ok.setText("OK");
- ok.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e) {
- close(true);
- }
- });
- }
-
- public Composite createContent(Composite parent) {
- return null;
- }
- };
- okDialog.setDescription(message);
- okDialog.setDetails(details);
- return okDialog.open();
- }
-
- /*
- * helper to create confirm/deny dialogs: question, confirmation
- */
- private static boolean openConfirmDenyDialog(Shell parent, Image image, String title, String message, String details, final String confirmLabel, final String denyLabel){
- AbstractDialog dialog = new AbstractDialog(parent, title, image){
- public void createDialogButtons(Composite parent) {
- Button confirm = new Button(parent, SWT.PUSH);
- if(confirmLabel != null)
- confirm.setText(confirmLabel);
- confirm.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e) {
- close(true);
- }
- });
- Button deny = new Button(parent, SWT.PUSH);
- if(denyLabel != null)
- deny.setText(denyLabel);
- deny.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e) {
- close(false);
- }
- });
- }
-
- public Composite createContent(Composite parent) {
- return null;
- }
- };
- dialog.setDescription(message);
- dialog.setDetails(details);
- return dialog.open();
- }
-}
Modified: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileFormatSelector.java
===================================================================
--- trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileFormatSelector.java 2011-03-01 20:09:46 UTC (rev 1230)
+++ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileFormatSelector.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -3,6 +3,7 @@
import java.io.File;
import org.cishell.framework.algorithm.AlgorithmFactory;
+import org.cishell.reference.app.service.persistence.AbstractDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
Modified: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileLoaderServiceImpl.java
===================================================================
--- trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileLoaderServiceImpl.java 2011-03-01 20:09:46 UTC (rev 1230)
+++ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileLoaderServiceImpl.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -43,18 +43,25 @@
}
}
+ public File[] getFilesToLoadFromUser(boolean selectSingleFile, String[] filterExtensions)
+ throws FileLoadException {
+ IWorkbenchWindow window = getFirstWorkbenchWindow();
+ Display display = PlatformUI.getWorkbench().getDisplay();
+
+ return getFilesToLoadFromUserInternal(window, display, selectSingleFile, filterExtensions);
+ }
+
public Data[] loadFilesFromUserSelection(
BundleContext bundleContext,
CIShellContext ciShellContext,
LogService logger,
- ProgressMonitor progressMonitor) throws FileLoadException {
+ ProgressMonitor progressMonitor,
+ boolean selectSingleFile) throws FileLoadException {
if ("".equals(defaultLoadDirectory)) {
defaultLoadDirectory = determineDefaultLoadDirectory();
}
- IWorkbenchWindow window = getFirstWorkbenchWindow();
- Display display = PlatformUI.getWorkbench().getDisplay();
- File[] files = getFilesToLoadFromUser(window, display);
+ File[] files = getFilesToLoadFromUser(selectSingleFile, null);
if (files != null) {
return loadFiles(bundleContext, ciShellContext, logger, progressMonitor, files);
@@ -255,8 +262,13 @@
}
}
- private File[] getFilesToLoadFromUser(IWorkbenchWindow window, Display display) {
- FileSelectorRunnable fileSelector = new FileSelectorRunnable(window);
+ private File[] getFilesToLoadFromUserInternal(
+ IWorkbenchWindow window,
+ Display display,
+ boolean selectSingleFile,
+ String[] filterExtensions) {
+ FileSelectorRunnable fileSelector =
+ new FileSelectorRunnable(window, selectSingleFile, filterExtensions);
if (Thread.currentThread() != display.getThread()) {
display.syncExec(fileSelector);
Modified: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileSelectorRunnable.java
===================================================================
--- trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileSelectorRunnable.java 2011-03-01 20:09:46 UTC (rev 1230)
+++ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/fileloader/FileSelectorRunnable.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -8,11 +8,15 @@
public final class FileSelectorRunnable implements Runnable {
private IWorkbenchWindow window;
-
+ private boolean selectSingleFile;
+ private String[] filterExtensions;
private File[] files;
- public FileSelectorRunnable(IWorkbenchWindow window) {
+ public FileSelectorRunnable(
+ IWorkbenchWindow window, boolean selectSingleFile, String[] filterExtensions) {
this.window = window;
+ this.selectSingleFile = selectSingleFile;
+ this.filterExtensions = filterExtensions;
}
public File[] getFiles() {
@@ -35,7 +39,6 @@
fileDialog.open();
String path = fileDialog.getFilterPath();
String[] fileNames = fileDialog.getFileNames();
- // TODO: Ask Angela about the order here, i.e. should they be sorted alphabetically?
if ((fileNames == null) || (fileNames.length == 0)) {
return new File[0];
@@ -54,10 +57,24 @@
private FileDialog createFileDialog() {
File currentDirectory = new File(FileLoaderServiceImpl.defaultLoadDirectory);
String absolutePath = currentDirectory.getAbsolutePath();
- FileDialog fileDialog = new FileDialog(this.window.getShell(), SWT.OPEN | SWT.MULTI);
+ FileDialog fileDialog =
+ new FileDialog(this.window.getShell(), SWT.OPEN | determineSWTFileSelectFlag());
fileDialog.setFilterPath(absolutePath);
+
+ if ((this.filterExtensions != null) && (this.filterExtensions.length > 0)) {
+ fileDialog.setFilterExtensions(this.filterExtensions);
+ }
+
fileDialog.setText("Select Files");
return fileDialog;
}
+
+ private int determineSWTFileSelectFlag() {
+ if (this.selectSingleFile) {
+ return SWT.SINGLE;
+ } else {
+ return SWT.MULTI;
+ }
+ }
}
\ No newline at end of file
Added: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/DataFormatChooser.java
===================================================================
--- trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/DataFormatChooser.java (rev 0)
+++ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/DataFormatChooser.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -0,0 +1,338 @@
+package org.cishell.reference.app.service.filesaver;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.cishell.framework.algorithm.AlgorithmProperty;
+import org.cishell.framework.data.Data;
+import org.cishell.reference.app.service.persistence.AbstractDialog;
+import org.cishell.service.conversion.Converter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.ServiceReference;
+
+/* TODO Kill dead methods */
+public class DataFormatChooser extends AbstractDialog implements AlgorithmProperty {
+// public static final Image QUESTION_ICON =
+// Display.getCurrent().getSystemImage(SWT.ICON_QUESTION);
+
+ protected Data data;
+ protected Converter[] converters;
+ private List converterListComponent;
+ private StyledText detailPane;
+ private Converter chosenConverter;
+
+ public DataFormatChooser(Data data, Shell parent, Converter[] converters, String title) {
+ super(parent, title, AbstractDialog.QUESTION);
+ this.data = data;
+ this.converters = alphabetizeConverters(filterConverters(converters));
+ }
+
+ public Converter getChosenConverter() {
+ return this.chosenConverter;
+ }
+
+ private Composite initializeGUI(Composite parent) {
+ Composite content = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ content.setLayout(layout);
+
+ Group converterGroup = new Group(content, SWT.NONE);
+ converterGroup.setText("Pick the Output Data Type");
+ converterGroup.setLayout(new FillLayout());
+ GridData persisterData = new GridData(GridData.FILL_BOTH);
+ persisterData.widthHint = 200;
+ converterGroup.setLayoutData(persisterData);
+
+ converterListComponent =
+ new List(converterGroup, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE);
+ initializeConverterListComponent();
+ converterListComponent.addMouseListener(new MouseAdapter() {
+ public void mouseDoubleClick(MouseEvent mouseEvent) {
+ List list = (List)mouseEvent.getSource();
+ int selection = list.getSelectionIndex();
+
+ if (selection != -1) {
+ selectionMade(selection);
+ }
+ }
+ });
+ converterListComponent.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent selectionEvent) {
+ List list = (List)selectionEvent.getSource();
+ int selection = list.getSelectionIndex();
+
+ if (selection != -1) {
+ updateDetailPane(converters[selection]);
+ }
+ }
+ });
+
+ Group detailsGroup = new Group(content, SWT.NONE);
+ detailsGroup.setText("Details");
+ detailsGroup.setLayout(new FillLayout());
+ GridData detailsData = new GridData(GridData.FILL_BOTH);
+ detailsData.widthHint = 200;
+ detailsGroup.setLayoutData(detailsData);
+
+ detailPane = initializeDetailPane(detailsGroup);
+
+ // Select the first item by default.
+ converterListComponent.setSelection(0);
+ updateDetailPane(converters[0]);
+
+ return content;
+ }
+
+ /**
+ * Initialize the Listbox of Persisters using the stored Persister array
+ */
+ private void initializeConverterListComponent() {
+ for (int ii = 0; ii < converters.length; ii++) {
+ if (converters[ii] != null) {
+ Dictionary converterProperties = converters[ii].getProperties();
+
+ // Get the name of the persister from the property map.
+ String outData = null;
+
+ ServiceReference[] serviceReferences = converters[ii].getConverterChain();
+
+ if ((serviceReferences != null) && (serviceReferences.length > 0)) {
+ outData = (String)serviceReferences[serviceReferences.length - 1].getProperty(
+ AlgorithmProperty.LABEL);
+ }
+
+ if (outData == null) {
+ outData = (String)converterProperties.get(AlgorithmProperty.LABEL);
+ }
+
+ /*
+ * If someone was sloppy enough to not provide a name, then use the name of the
+ * class instead.
+ */
+ if ((outData == null) || (outData.length() == 0)) {
+ outData = converters[ii].getClass().getName();
+ }
+
+ converterListComponent.add(outData);
+ }
+ }
+ }
+
+ private StyledText initializeDetailPane(Group detailsGroup) {
+ StyledText detailPane = new StyledText(detailsGroup, SWT.H_SCROLL | SWT.V_SCROLL);
+ detailPane.setEditable(false);
+ detailPane.getCaret().setVisible(false);
+
+ return detailPane;
+ }
+
+ private void updateDetailPane(Converter converter) {
+ Dictionary converterProperties = converter.getProperties();
+ Enumeration converterPropertiesKeys = converterProperties.keys();
+
+ detailPane.setText("");
+
+ while (converterPropertiesKeys.hasMoreElements()) {
+ Object key = converterPropertiesKeys.nextElement();
+ Object value = converterProperties.get(key);
+
+ StyleRange styleRange = new StyleRange();
+ styleRange.start = detailPane.getText().length();
+ detailPane.append(key + ":\n");
+ styleRange.length = key.toString().length() + 1;
+ styleRange.fontStyle = SWT.BOLD;
+ detailPane.setStyleRange(styleRange);
+
+ detailPane.append(value + "\n");
+ }
+ }
+
+ private Converter[] filterConverters(Converter[] allConverters) {
+ Map lastInDataToConverter = new HashMap();
+
+ for (int ii = 0; ii < allConverters.length; ii++) {
+ Converter converter = allConverters[ii];
+ String lastInputData = getLastConverterInData(converter);
+
+ if (lastInDataToConverter.containsKey(lastInputData)) {
+ Converter alreadyStoredConverter =
+ (Converter)lastInDataToConverter.get(lastInputData);
+ Converter chosenConverter =
+ returnPreferredConverter(converter, alreadyStoredConverter);
+ lastInDataToConverter.put(lastInputData, chosenConverter);
+ } else {
+ lastInDataToConverter.put(lastInputData, converter);
+ }
+ }
+
+ return (Converter[]) lastInDataToConverter.values().toArray(new Converter[0]);
+ }
+
+ private String getLastConverterInData(Converter converter) {
+ ServiceReference[] convChain = converter.getConverterChain();
+
+ if (convChain.length >= 1) {
+ ServiceReference lastConverter = convChain[convChain.length - 1];
+ String lastInData = (String) lastConverter.getProperty("in_data");
+
+ return lastInData;
+ } else {
+ return "";
+ }
+ }
+
+ private Converter returnPreferredConverter(Converter converter1, Converter converter2) {
+ Dictionary converter1Properties = converter1.getProperties();
+ String converter1Lossiness = (String)converter1Properties.get(CONVERSION);
+ int converter1Quality = determineQuality(converter1Lossiness);
+
+ Dictionary converter2Properties = converter2.getProperties();
+ String converter2Lossiness = (String)converter2Properties.get(CONVERSION);
+ int converter2Quality = determineQuality(converter2Lossiness);
+
+ if (converter1Quality > converter2Quality) {
+ return converter1;
+ } else if (converter2Quality > converter1Quality) {
+ return converter2;
+ } else {
+ // They are tied. Look at chosenConverter chain length.
+
+ int converter1Length = converter1.getConverterChain().length;
+ int converter2Length = converter2.getConverterChain().length;
+
+ if (converter1Length > converter2Length) {
+ return converter2;
+ } else if (converter2Length > converter1Length) {
+ return converter1;
+ } else {
+ /*
+ * Both have the same lossiness and same length.
+ * Arbitrary pick the first.
+ */
+ return converter1;
+ }
+ }
+ }
+
+ private int determineQuality(String lossiness) {
+ if (lossiness == LOSSY) {
+ return 0;
+ } else if (lossiness == null) {
+ return 1;
+ } else {
+ return 2;
+ }
+ }
+
+ private Converter[] alphabetizeConverters(Converter[] converters) {
+ Arrays.sort(converters, new CompareAlphabetically());
+
+ return converters;
+ }
+
+ protected void selectionMade(int selectedIndex) {
+ try {
+ getShell().setVisible(false);
+ this.chosenConverter = converters[selectedIndex];
+// final SaveAsController saver = new SaveAsController(getShell(), ciShellContext);
+ close(true);
+// close(saver.save(chosenConverter, data));
+ } catch (Exception exception) {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ public void createDialogButtons(Composite parent) {
+ Button select = new Button(parent, SWT.PUSH);
+ select.setText("Select");
+ select.addSelectionListener(
+ new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent selectionEvent) {
+ int index = converterListComponent.getSelectionIndex();
+
+ if (index != -1) {
+ selectionMade(index);
+ }
+ }
+ }
+ );
+ select.setFocus();
+
+ Button cancel = new Button(parent, SWT.NONE);
+ cancel.setText("Cancel");
+ cancel.addSelectionListener(
+ new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent selectionEvent) {
+ close(false);
+ }
+ }
+ );
+ }
+
+ public Composite createContent(Composite parent) {
+ if (converters.length == 1) {
+ close(true);
+// final SaveAsController saver = new SaveAsController((Shell) parent, ciShellContext);
+// close(saver.save(converters[0], data));
+
+ return parent;
+ } else {
+ return initializeGUI(parent);
+ }
+ }
+
+ private class CompareAlphabetically implements Comparator {
+ public int compare(Object object1, Object object2) {
+ if ((object1 instanceof Converter) && (object2 instanceof Converter)) {
+ Converter converter1 = (Converter)object1;
+ String converter1Label = getLabel(converter1);
+
+ Converter converter2 = (Converter)object2;
+ String converter2Label = getLabel(converter2);
+
+ if ((converter1Label != null) && (converter2Label != null)) {
+ return converter1Label.compareTo(converter2Label);
+ } else if (converter1Label == null) {
+ return 1;
+ } else if (converter2Label == null) {
+ return -1;
+ } else {
+ return 0;
+ }
+ } else {
+ throw new IllegalArgumentException("Can only compare Converters");
+ }
+ }
+
+ private String getLabel(Converter converter) {
+ String label = "";
+ ServiceReference[] serviceReferences = converter.getConverterChain();
+
+ if ((serviceReferences != null) && (serviceReferences.length > 0)) {
+ label = (String)serviceReferences[serviceReferences.length - 1].getProperty(
+ AlgorithmProperty.LABEL);
+ }
+
+ return label;
+ }
+ }
+}
Added: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/FileSaverServiceImpl.java
===================================================================
--- trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/FileSaverServiceImpl.java (rev 0)
+++ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/FileSaverServiceImpl.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -0,0 +1,141 @@
+package org.cishell.reference.app.service.filesaver;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+import org.cishell.app.service.filesaver.AbstractFileSaverService;
+import org.cishell.app.service.filesaver.FileSaveException;
+import org.cishell.framework.data.Data;
+import org.cishell.service.conversion.Converter;
+import org.cishell.service.conversion.DataConversionService;
+import org.cishell.service.guibuilder.GUIBuilderService;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.osgi.service.component.ComponentContext;
+
+public class FileSaverServiceImpl extends AbstractFileSaverService {
+ public static final String SAVE_DIALOG_TITLE = "Save";
+
+ private DataConversionService conversionManager;
+ private GUIBuilderService guiBuilder;
+
+ protected void activate(ComponentContext componentContext) {
+ this.conversionManager = (DataConversionService) componentContext.locateService("DCS");
+ this.guiBuilder = (GUIBuilderService) componentContext.locateService("GBS");
+
+ }
+
+ public Converter promptForConverter(final Data outDatum, String targetMimeType)
+ throws FileSaveException {
+ final Converter[] converters =
+ this.conversionManager.findConverters(outDatum, targetMimeType);
+
+ if (converters.length == 0) {
+ throw new FileSaveException("No appropriate converters.");
+ } else if (converters.length == 1) {
+ // Only one possible choice in how to save data. Do it.
+ Converter onlyConverter = converters[0];
+
+ return onlyConverter;
+ } else {
+ final Shell parentShell = PlatformUI.getWorkbench().getWorkbenchWindows()[0].getShell();
+
+ if (parentShell.isDisposed()) {
+ throw new FileSaveException(
+ "Can't create dialog window -- graphical environment not available.");
+ }
+
+ return showDataFormatChooser(outDatum, converters, parentShell);
+ }
+ }
+
+ private Converter showDataFormatChooser(
+ final Data outDatum,
+ final Converter[] converters,
+ final Shell parentShell) throws FileSaveException{
+ try {
+ final Converter[] chosenConverter = new Converter[1];
+ guiRun(new Runnable() {
+ public void run() {
+ DataFormatChooser formatChooser = new DataFormatChooser(
+ outDatum, parentShell, converters, SAVE_DIALOG_TITLE);
+ formatChooser.createContent(new Shell(parentShell));
+ formatChooser.open();
+ chosenConverter[0] = formatChooser.getChosenConverter();
+ }
+ });
+
+ return chosenConverter[0];
+ } catch (Exception e) {
+ throw new FileSaveException(e.getMessage(), e);
+ }
+ }
+
+ public File promptForTargetFile(final String fileName) throws FileSaveException {
+ final File[] resultFile = new File[1];
+
+ try {
+ guiRun(new Runnable() {
+ public void run() {
+ SaveAsController saveAs =
+ new SaveAsController(FileSaverServiceImpl.this.guiBuilder);
+
+ resultFile[0] = saveAs.open(fileName);
+ }
+ });
+
+ return resultFile[0];
+ } catch (Throwable e) {
+ throw new FileSaveException(e.getMessage(), e);
+ }
+ }
+
+ public void saveTo(File sourceFile, File targetFile) throws FileSaveException {
+ if ((sourceFile != null) && (targetFile != null) && sourceFile.exists()) {
+ copyFile(sourceFile, targetFile);
+ }
+ }
+
+ private void guiRun(Runnable run) {
+ final Shell parentShell = PlatformUI.getWorkbench().getWorkbenchWindows()[0].getShell();
+
+ if (Thread.currentThread() == Display.getDefault().getThread()) {
+ run.run();
+ } else {
+ parentShell.getDisplay().syncExec(run);
+ }
+ }
+
+ /* TODO: Don't use cns-utilities, use Files.copy in Guava
+ * This shouldn't throw FileSaveException -- too specific for a general utility.
+ * Catch whatever this throws then rethrow as FSE
+ */
+ private static void copyFile(File sourceFile, File targetFile) throws FileSaveException {
+ try {
+ FileInputStream inputStream = new FileInputStream(sourceFile);
+ FileOutputStream outputStream = new FileOutputStream(targetFile);
+
+ FileChannel readableChannel = inputStream.getChannel();
+ FileChannel writableChannel = outputStream.getChannel();
+
+ writableChannel.truncate(0);
+ writableChannel.transferFrom(
+ readableChannel, 0, readableChannel.size());
+ inputStream.close();
+ outputStream.close();
+ } catch (IOException ioException) {
+ String exceptionMessage =
+ "An error occurred when copying from the file \"" +
+ sourceFile.getAbsolutePath() +
+ "\" to the file \"" +
+ targetFile.getAbsolutePath() +
+ "\".";
+
+ throw new FileSaveException(exceptionMessage, ioException); // TODO Just throw IOException
+ }
+ }
+}
\ No newline at end of file
Added: trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/SaveAsController.java
===================================================================
--- trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/SaveAsController.java (rev 0)
+++ trunk/core/org.cishell.reference/src/org/cishell/reference/app/service/filesaver/SaveAsController.java 2011-03-01 20:10:28 UTC (rev 1231)
@@ -0,0 +1,115 @@
+package org.cishell.reference.app.service.filesaver;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.cishell.service.guibuilder.GUIBuilderService;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+public class SaveAsController {
+ public static final Collection<Character> INVALID_FILENAME_CHARACTERS =
+ Collections.unmodifiableCollection(Arrays.asList(
+ '\\', '/', ':', '*', '?', '"', '<', '>', '|', '%'));
+ public static final char FILENAME_CHARACTER_REPLACEMENT = '#';
+
+ public static final String FILE_EXTENSION_PREFIX = "file-ext:";
+
+ private static File currentDirectory;
+
+ private GUIBuilderService guiBuilder;
+
+ public SaveAsController(GUIBuilderService guiBuilder) {
+ ...
[truncated message content] |