Initial check-in of Bulk Editor code.
authorp.ciardelli <p.ciardelli@localhost>
Thu, 25 Jun 2009 11:39:55 +0000 (11:39 +0000)
committerp.ciardelli <p.ciardelli@localhost>
Thu, 25 Jun 2009 11:39:55 +0000 (11:39 +0000)
23 files changed:
.gitattributes
taxeditor-bulkeditor/META-INF/MANIFEST.MF [new file with mode: 0644]
taxeditor-bulkeditor/build.properties [new file with mode: 0644]
taxeditor-bulkeditor/plugin.xml [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditor.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorAnnotation.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorDocumentProvider.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorInput.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorReconcilingStrategy.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorSourceViewerConfiguration.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorUtil.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/IEntityContainer.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/ReferenceContainer.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/ReferenceEditorInput.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/GroupMergeHandler.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/MergeTargetHandler.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/OpenBulkEditorHandler.java [new file with mode: 0644]
taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/internal/TaxeditorBulkeditorPlugin.java [new file with mode: 0644]
taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/Application.java [new file with mode: 0644]
taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationActionBarAdvisor.java [new file with mode: 0644]
taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationWorkbenchAdvisor.java [new file with mode: 0644]
taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationWorkbenchWindowAdvisor.java [new file with mode: 0644]
taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/Perspective.java [new file with mode: 0644]

index 48e552e33481d729c0276dc82cfa2c37d5969ad9..6298dee5965e0d88d822f52efba18d1687c5e44f 100644 (file)
@@ -641,7 +641,29 @@ taxeditor-application/src/main/java/eu/etaxonomy/taxeditor/Perspective.java -tex
 taxeditor-application/src/main/java/eu/etaxonomy/taxeditor/TaxonomicEditorPlugin.java -text
 taxeditor-application/src/main/resources/log4j.properties -text
 taxeditor-bulkeditor/.settings/org.eclipse.jdt.core.prefs -text
+taxeditor-bulkeditor/META-INF/MANIFEST.MF -text
+taxeditor-bulkeditor/build.properties -text
+taxeditor-bulkeditor/plugin.xml -text
 taxeditor-bulkeditor/pom.xml -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditor.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorAnnotation.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorDocumentProvider.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorInput.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorReconcilingStrategy.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorSourceViewerConfiguration.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorUtil.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/IEntityContainer.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/ReferenceContainer.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/ReferenceEditorInput.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/GroupMergeHandler.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/MergeTargetHandler.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/OpenBulkEditorHandler.java -text
+taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/internal/TaxeditorBulkeditorPlugin.java -text
+taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/Application.java -text
+taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationActionBarAdvisor.java -text
+taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationWorkbenchAdvisor.java -text
+taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationWorkbenchWindowAdvisor.java -text
+taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/Perspective.java -text
 taxeditor-editor/.settings/org.eclipse.jdt.core.prefs -text
 taxeditor-editor/.settings/org.eclipse.jdt.ui.prefs -text
 taxeditor-editor/META-INF/MANIFEST.MF -text
diff --git a/taxeditor-bulkeditor/META-INF/MANIFEST.MF b/taxeditor-bulkeditor/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..5a0345a
--- /dev/null
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: EDIT Taxonomic Editor - Bulk Editor Bundle
+Bundle-SymbolicName: eu.etaxonomy.taxeditor.bulkeditor;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-ClassPath: .
+Bundle-Activator: eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.jface.text;bundle-version="3.4.2",
+ org.eclipse.ui.editors,
+ org.eclipse.ui.ide,
+ org.eclipse.core.resources;bundle-version="3.4.2",
+ eu.etaxonomy.cdmLibrary;bundle-version="2.1.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/taxeditor-bulkeditor/build.properties b/taxeditor-bulkeditor/build.properties
new file mode 100644 (file)
index 0000000..1361b3c
--- /dev/null
@@ -0,0 +1,4 @@
+source.. = src/main/java/,\\r
+           src/test/java/\r
+bin.includes = META-INF/,\\r
+               .\r
diff --git a/taxeditor-bulkeditor/plugin.xml b/taxeditor-bulkeditor/plugin.xml
new file mode 100644 (file)
index 0000000..a1c8ffc
--- /dev/null
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<?eclipse version="3.4"?>\r
+<plugin>\r
+\r
+   <extension\r
+         id="application"\r
+         point="org.eclipse.core.runtime.applications">\r
+      <application>\r
+         <run\r
+               class="eu.etaxonomy.taxeditor.bulkeditor.Application">\r
+         </run>\r
+      </application>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.perspectives">\r
+      <perspective\r
+            class="eu.etaxonomy.taxeditor.bulkeditor.Perspective"\r
+            id="bulkeditor.perspective"\r
+            name="Perspective">\r
+      </perspective>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.editors">\r
+      <editor\r
+            class="eu.etaxonomy.taxeditor.bulkeditor.BulkEditor"\r
+            default="true"\r
+            extensions="&quot;xxx&quot;"\r
+            id="bulkeditor.editor"\r
+            name="Bulk Editor">\r
+      </editor>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.menus">\r
+      <menuContribution\r
+            locationURI="menu:org.eclipse.ui.main.menu">\r
+         <menu\r
+               id="bulkeditor.menus.openmenu"\r
+               label="Bulk Editor">\r
+         </menu>\r
+      </menuContribution>\r
+      <menuContribution\r
+            locationURI="menu:bulkeditor.menus.openmenu">\r
+         <command\r
+               commandId="bulkeditor.commands.openbulkeditor"\r
+               label="Reference"\r
+               style="push">\r
+         </command>\r
+      </menuContribution>\r
+      <menuContribution\r
+            locationURI="popup:org.eclipse.ui.popup.any">\r
+         <command\r
+               commandId="bulkeditor.commands.mergegroup"\r
+               label="Merge Group"\r
+               style="push">\r
+         </command>\r
+         <command\r
+               commandId="bulkeditor.commands.setmergetarget"\r
+               label="Set Current Line as Target for Group Merge"\r
+               style="push">\r
+         </command>\r
+      </menuContribution>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.commands">\r
+      <command\r
+            defaultHandler="eu.etaxonomy.taxeditor.bulkeditor.handler.OpenBulkEditorHandler"\r
+            id="bulkeditor.commands.openbulkeditor"\r
+            name="Open Bulk Editor command">\r
+      </command>\r
+      <command\r
+            defaultHandler="eu.etaxonomy.taxeditor.bulkeditor.handler.GroupMergeHandler"\r
+            id="bulkeditor.commands.mergegroup"\r
+            name="Merge Group">\r
+      </command>\r
+      <command\r
+            defaultHandler="eu.etaxonomy.taxeditor.bulkeditor.handler.MergeTargetHandler"\r
+            id="bulkeditor.commands.setmergetarget"\r
+            name="Set as Target for Group Merge">\r
+      </command>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.editors.markerAnnotationSpecification">\r
+      <specification\r
+            annotationType="merge_candidate_annotation"\r
+            colorPreferenceKey="merge_candidate_annotation_color"\r
+            colorPreferenceValue="220,220,255"\r
+            highlightPreferenceValue="true"\r
+            icon="icons/merge_candidate.gif"\r
+            includeOnPreferencePage="true"\r
+            label="Merge Candidate Annotation"\r
+            overviewRulerPreferenceKey="merge_candidate_annotation_overview"\r
+            overviewRulerPreferenceValue="true"\r
+            presentationLayer="0"\r
+            symbolicIcon="task"\r
+            textPreferenceKey="merge_candidate_annotation_text"\r
+            textPreferenceValue="true"\r
+            textStylePreferenceValue="BOX"\r
+            verticalRulerPreferenceKey="merge_candidate_annotation_vertical"\r
+            verticalRulerPreferenceValue="true">\r
+      </specification>\r
+      <specification\r
+            annotationType="merge_target_annotation"\r
+            colorPreferenceKey="merge_target_annotation_color"\r
+            colorPreferenceValue="220,220,255"\r
+            highlightPreferenceValue="true"\r
+            icon="icons/merge_target.gif"\r
+            includeOnPreferencePage="true"\r
+            label="Merge Target Annotation"\r
+            overviewRulerPreferenceKey="merge_target_annotation_overview"\r
+            overviewRulerPreferenceValue="true"\r
+            presentationLayer="1"\r
+            symbolicIcon="task"\r
+            textPreferenceKey="merge_target_annotation_text"\r
+            textPreferenceValue="true"\r
+            textStylePreferenceValue="BOX"\r
+            verticalRulerPreferenceKey="merge_target_annotation_vertical"\r
+            verticalRulerPreferenceValue="true">\r
+      </specification>      \r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.editors.annotationTypes">\r
+      <type\r
+            name="merge_candidate_annotation">\r
+      </type>\r
+      <type\r
+            name="merge_target_annotation">\r
+      </type>\r
+   </extension>\r
+\r
+</plugin>\r
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditor.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditor.java
new file mode 100644 (file)
index 0000000..ca194cb
--- /dev/null
@@ -0,0 +1,86 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor;\r
+\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.source.Annotation;\r
+import org.eclipse.jface.text.source.IAnnotationModel;\r
+import org.eclipse.jface.text.source.ISourceViewer;\r
+import org.eclipse.jface.text.source.IVerticalRuler;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.events.MouseAdapter;\r
+import org.eclipse.swt.events.MouseEvent;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.ui.IEditorInput;\r
+import org.eclipse.ui.IEditorSite;\r
+import org.eclipse.ui.PartInitException;\r
+import org.eclipse.ui.editors.text.TextEditor;\r
+\r
+/**\r
+ * A document provider is responsible not just for providing the document for a \r
+ * given editor input but for the complete translation between the domain model \r
+ * and the editor's internal document-based model. Document provider can be shared \r
+ * between editors. \r
+ * \r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class BulkEditor extends TextEditor {\r
+\r
+       public static final String ID = "bulkeditor.editor";\r
+\r
+       private ISourceViewer viewer;\r
+\r
+       @Override\r
+       public void init(IEditorSite site, IEditorInput input)\r
+       throws PartInitException {\r
+               setDocumentProvider(new BulkEditorDocumentProvider());\r
+               super.init(site, input);\r
+       }\r
+       \r
+       @Override\r
+       protected ISourceViewer createSourceViewer(Composite parent,\r
+                       IVerticalRuler ruler, int styles) {\r
+               viewer = super.createSourceViewer(parent, ruler, styles | SWT.WRAP);\r
+               setSourceViewerConfiguration(new BulkEditorSourceViewerConfiguration());\r
+               addToggleMergeCandidateListener(ruler.getControl());\r
+               return viewer;\r
+       }\r
+       \r
+       private void addToggleMergeCandidateListener(Control control) {\r
+               control.addMouseListener(new MouseAdapter() {\r
+                       @Override\r
+                       public void mouseDoubleClick(MouseEvent e) {\r
+                               StyledText textWidget = viewer.getTextWidget();\r
+                               int line = textWidget.getLineIndex(e.y);\r
+                               toggleMergeCandidateAnnotation(line);\r
+                       }\r
+               });\r
+       }\r
+\r
+       private void toggleMergeCandidateAnnotation(int line) {\r
+               IDocument document = viewer.getDocument();\r
+               IAnnotationModel model = viewer.getAnnotationModel();\r
+               \r
+               Annotation annotation = BulkEditorUtil.getAnnotationAtLine(line, document, model);\r
+               \r
+               if (annotation != null) {\r
+                       if (annotation.getType().equals(BulkEditorAnnotation.TYPE_MERGE_CANDIDATE)) {\r
+                               annotation.setType(BulkEditorAnnotation.TYPE_GENERIC);\r
+                       } else {\r
+                               annotation.setType(BulkEditorAnnotation.TYPE_MERGE_CANDIDATE);\r
+                       }\r
+                       BulkEditorUtil.reAddAnnotation(annotation, model);\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorAnnotation.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorAnnotation.java
new file mode 100644 (file)
index 0000000..482ff21
--- /dev/null
@@ -0,0 +1,60 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor;\r
+\r
+import org.eclipse.core.runtime.Assert;\r
+import org.eclipse.jface.text.source.Annotation;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class BulkEditorAnnotation extends Annotation {\r
+\r
+       public static final String TYPE_GENERIC = Annotation.TYPE_UNKNOWN;\r
+       public static final String TYPE_MERGE_TARGET = "merge_target_annotation";\r
+       public static final String TYPE_MERGE_CANDIDATE = "merge_candidate_annotation";\r
+       \r
+       private IEntityContainer container;\r
+\r
+       public BulkEditorAnnotation(IEntityContainer container) {\r
+               Assert.isNotNull(container);\r
+               this.container = container;\r
+               setType(TYPE_GENERIC);\r
+       }\r
+\r
+       public IEntityContainer getContainer() {\r
+               return container;\r
+       }\r
+       \r
+       @Override\r
+       public String getText() {\r
+               return container.getEditableText();\r
+       }\r
+       \r
+       @Override\r
+       public void markDeleted(boolean deleted) {\r
+               super.markDeleted(deleted);\r
+               container.markAsDeleted();\r
+       }\r
+       \r
+       @Override\r
+       public void setText(String text) {\r
+               super.setText(text);\r
+               container.setText(text);\r
+       }\r
+       \r
+       @Override\r
+       public String toString() {\r
+               // For debugging\r
+               return getText();\r
+       }\r
+}
\ No newline at end of file
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorDocumentProvider.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorDocumentProvider.java
new file mode 100644 (file)
index 0000000..bb04c92
--- /dev/null
@@ -0,0 +1,134 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor;\r
+\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.core.runtime.CoreException;\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.jface.operation.IRunnableContext;\r
+import org.eclipse.jface.text.Document;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.Position;\r
+import org.eclipse.jface.text.source.Annotation;\r
+import org.eclipse.jface.text.source.AnnotationModel;\r
+import org.eclipse.jface.text.source.IAnnotationModel;\r
+import org.eclipse.ui.texteditor.AbstractDocumentProvider;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class BulkEditorDocumentProvider extends AbstractDocumentProvider {\r
+       \r
+       private Map<BulkEditorInput, IDocument> documents = \r
+                       new HashMap<BulkEditorInput, IDocument>();\r
+\r
+       private Map<BulkEditorInput, IAnnotationModel> models = \r
+               new HashMap<BulkEditorInput, IAnnotationModel>();\r
+       \r
+       @Override\r
+       public IAnnotationModel getAnnotationModel(Object element) {\r
+               if (element instanceof BulkEditorInput) {\r
+                       \r
+                       BulkEditorInput input = (BulkEditorInput) element;\r
+                       IAnnotationModel model = models.get((BulkEditorInput) element);\r
+                       \r
+                       // Create model as necessary\r
+                       if (model == null) {\r
+                               model = new AnnotationModel() {\r
+                                       @Override\r
+                                       protected void removeAnnotation(Annotation annotation,\r
+                                                       boolean fireModelChanged) {\r
+                                               // Set data model element for deletion\r
+                                               annotation.markDeleted(true);\r
+                                               super.removeAnnotation(annotation, fireModelChanged);\r
+                                       }\r
+                               };\r
+                               models.put(input, model);\r
+                       }       \r
+                       return model;\r
+               }\r
+               \r
+               return null;\r
+       }\r
+       \r
+       @Override\r
+       protected IAnnotationModel createAnnotationModel(Object element)\r
+                       throws CoreException {\r
+               return getAnnotationModel(element);\r
+       }\r
+\r
+       @Override\r
+       public IDocument getDocument(Object element) {\r
+               if (element instanceof BulkEditorInput) {\r
+                       return documents.get((BulkEditorInput) element);\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       @Override\r
+       protected IDocument createDocument(Object element) throws CoreException {\r
+               \r
+               if (element instanceof BulkEditorInput) {\r
+                       BulkEditorInput input = (BulkEditorInput) element;\r
+                       Document document = new Document("");\r
+                       IAnnotationModel model = getAnnotationModel(element);\r
+                       \r
+                       List<IEntityContainer> list = ((BulkEditorInput) element).getList();\r
+                       String text = "";\r
+                       String line;\r
+                       for (IEntityContainer container : list) {\r
+                               if (!container.isMarkedAsDeleted() && !container.isMarkedAsMerged()) {\r
+                                       line = container.getEditableText() \r
+                                                       + document.getDefaultLineDelimiter();\r
+                                       \r
+                                       Position position = new Position(text.length(), line.length());\r
+                                       Annotation annotation = new BulkEditorAnnotation(container);\r
+                                       model.addAnnotation(annotation, position);\r
+                                       document.set(document.get() + line);\r
+                                       \r
+                                       text += line;\r
+                               }\r
+                       }\r
+                       documents.put(input, document);\r
+                       BulkEditorUtil.printAnnotations(model);\r
+                       return document;\r
+               }\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       protected void doSaveDocument(IProgressMonitor monitor, Object element,\r
+                       IDocument document, boolean overwrite) throws CoreException {\r
+               // TODO Auto-generated method stub\r
+               \r
+       }\r
+\r
+       @Override\r
+       protected IRunnableContext getOperationRunner(IProgressMonitor monitor) {\r
+               // TODO Auto-generated method stub\r
+               return null;\r
+       }\r
+       \r
+       @Override\r
+       public boolean isModifiable(Object element) {\r
+               return true;\r
+       }\r
+       \r
+       @Override\r
+       public boolean isReadOnly(Object element) {\r
+               // enables copy & paste\r
+               return false;\r
+       }\r
+}
\ No newline at end of file
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorInput.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorInput.java
new file mode 100644 (file)
index 0000000..a82bad4
--- /dev/null
@@ -0,0 +1,74 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor;\r
+\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.ui.IEditorInput;\r
+import org.eclipse.ui.IPersistableElement;\r
+\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ * @param <T>\r
+ */\r
+public abstract class BulkEditorInput<T extends CdmBase> implements IEditorInput {\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.ui.IEditorInput#exists()\r
+        */\r
+       public boolean exists() {\r
+               // TODO Auto-generated method stub\r
+               return false;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.ui.IEditorInput#getImageDescriptor()\r
+        */\r
+       public ImageDescriptor getImageDescriptor() {\r
+               // TODO Auto-generated method stub\r
+               return null;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.ui.IEditorInput#getName()\r
+        */\r
+       public String getName() {\r
+               return "Bulk Editor";\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.ui.IEditorInput#getPersistable()\r
+        */\r
+       public IPersistableElement getPersistable() {\r
+               // TODO Auto-generated method stub\r
+               return null;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.ui.IEditorInput#getToolTipText()\r
+        */\r
+       public String getToolTipText() {\r
+               return "Bulk Editor";\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)\r
+        */\r
+       public Object getAdapter(Class adapter) {\r
+               return null;\r
+       }               \r
+       \r
+       abstract public List<IEntityContainer<T>> getList();\r
+}
\ No newline at end of file
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorReconcilingStrategy.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorReconcilingStrategy.java
new file mode 100644 (file)
index 0000000..1c6708f
--- /dev/null
@@ -0,0 +1,271 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.IRegion;\r
+import org.eclipse.jface.text.Position;\r
+import org.eclipse.jface.text.reconciler.DirtyRegion;\r
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;\r
+import org.eclipse.jface.text.source.Annotation;\r
+import org.eclipse.jface.text.source.IAnnotationModel;\r
+import org.eclipse.jface.text.source.IAnnotationModelExtension2;\r
+import org.eclipse.jface.text.source.ISourceViewer;\r
+\r
+import eu.etaxonomy.cdm.model.reference.Generic;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class BulkEditorReconcilingStrategy implements IReconcilingStrategy {\r
+       private static final Logger logger = Logger\r
+                       .getLogger(BulkEditorReconcilingStrategy.class);\r
+\r
+       private IDocument document;\r
+       private ISourceViewer viewer;\r
+\r
+       public BulkEditorReconcilingStrategy(ISourceViewer sourceViewer) {\r
+               this.viewer = sourceViewer;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)\r
+        */\r
+       public void reconcile(IRegion partition) {\r
+               // not used\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion, org.eclipse.jface.text.IRegion)\r
+        */\r
+       public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {\r
+               try {\r
+                       doReconcile(dirtyRegion);\r
+               } catch (BadLocationException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       synchronized private void doReconcile_firsttry(DirtyRegion dirtyRegion) throws BadLocationException {\r
+                                                               \r
+               int dirtyOffset = dirtyRegion.getOffset();\r
+               int dirtyLength = dirtyRegion.getLength();\r
+               IRegion firstLineRegion = document.getLineInformationOfOffset(dirtyOffset);             \r
+               String firstLineText = document.get(firstLineRegion.getOffset(), firstLineRegion.getLength());\r
+               \r
+               boolean first = true;\r
+               // Get all annotations on current line\r
+               for (Annotation annotation : \r
+                               getAnnotations(firstLineRegion.getOffset(), firstLineRegion.getLength())) {\r
+                       if (first) {\r
+                               // First annotation updated w text of entire line\r
+                               annotation.setText(firstLineText);\r
+                               first = false;\r
+                       } else {\r
+                               // Remove annotations that squirted on to the same line\r
+                               getAnnotationModel().removeAnnotation(annotation);\r
+                       }\r
+               }\r
+               \r
+               if (DirtyRegion.INSERT.equals(dirtyRegion.getType())) {\r
+                       if (document.getNumberOfLines(dirtyOffset, dirtyLength) > 1) {\r
+                               \r
+                       }\r
+                       IRegion lastLineRegion = document.getLineInformationOfOffset(dirtyOffset + dirtyLength);\r
+                       String lastLineText = document.get(lastLineRegion.getOffset(), lastLineRegion.getLength());\r
+                                               \r
+               }\r
+               \r
+               logger.debug(dirtyRegion.getType());\r
+               BulkEditorUtil.printAnnotations(getAnnotationModel());\r
+       }\r
+       \r
+       synchronized private void doReconcile(DirtyRegion dirtyRegion) throws BadLocationException {\r
+               \r
+               int dirtyOffset = dirtyRegion.getOffset();\r
+               int dirtyLength = dirtyRegion.getLength();\r
+               IRegion firstLineRegion = document.getLineInformationOfOffset(dirtyOffset);             \r
+               String firstLineText = document.get(firstLineRegion.getOffset(), firstLineRegion.getLength());\r
+               \r
+               boolean first = true;\r
+               // Get all annotations on current line\r
+               for (Annotation annotation : \r
+                               getAnnotations(firstLineRegion.getOffset(), firstLineRegion.getLength())) {\r
+                       if (first) {\r
+                               // First annotation updated w text of entire line\r
+                               annotation.setText(firstLineText);\r
+                               first = false;\r
+                       } else {\r
+                               if (DirtyRegion.REMOVE.equals(dirtyRegion.getType())) {\r
+                                       // Remove annotations that squirted on to the same line\r
+                                       getAnnotationModel().removeAnnotation(annotation);\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               // PROBLEM: 0-length annotations, i.e. <CR>\r
+               \r
+               if (DirtyRegion.INSERT.equals(dirtyRegion.getType())) {\r
+                       int remainingLines = document.getNumberOfLines(dirtyOffset, dirtyLength) - 1;\r
+                       if (remainingLines > 0) {\r
+                               // Make annotations out of any new lines\r
+                               int firstLine = document.getLineOfOffset(dirtyOffset);\r
+                               for (int i = firstLine + 1; i <= firstLine + remainingLines; i++) {\r
+                                       IRegion lineRegion = document.getLineInformation(i);\r
+                                       String lineText = document.get(lineRegion.getOffset(), lineRegion.getLength());\r
+                                       \r
+                                       addAnnotation(lineText, lineRegion);\r
+                               }\r
+                       }                                               \r
+               }\r
+               \r
+               logger.debug(dirtyRegion.getType());\r
+               BulkEditorUtil.printAnnotations(getAnnotationModel());\r
+\r
+       }\r
+       \r
+       private void addAnnotation(String text, IRegion region) {\r
+               Position position = new Position(region.getOffset(), region.getLength());\r
+               ReferenceContainer container = new ReferenceContainer(Generic.NewInstance());\r
+               container.setText(text);\r
+               Annotation annotation = new BulkEditorAnnotation(container);\r
+               getAnnotationModel().addAnnotation(annotation, position);\r
+       }\r
+\r
+//     synchronized private void doReconcile_(DirtyRegion dirtyRegion) throws BadLocationException {\r
+               \r
+               /**\r
+                * Annotation positions have been updated at this point.\r
+                * \r
+                * 1) Figure out when to update a title cache\r
+                * 2) Figure out when to delete a reference\r
+                * 3) Figure out when to add a reference\r
+                * \r
+                * If there are two annotations on the same line, delete the 2nd into the first,\r
+                * update the first w the merged title cache.\r
+                * \r
+                * Multi-line copy paste over multi-lines -> remove followed by insert\r
+                * \r
+                * Why not just remove all zero-length annotations?\r
+                * \r
+                */\r
+               \r
+\r
+//             String modelLine = modelList.get(lineStart);\r
+//             String documentLine = \r
+//                             BulkEditorUtil.getLineWithoutDelimiters(document, lineStart);\r
+//             if (!documentLine.equals(modelLine)) {\r
+//                     Debug.print("Replacing line " + lineStart + ": " + documentLine);\r
+//                     modelList.set(lineStart, documentLine);\r
+//             }\r
+//             \r
+//             if (DirtyRegion.REMOVE.equals(dirtyRegion.getType())) {\r
+//                     Debug.print(delta + " lines deleted");\r
+//\r
+//                     if (delta > 0) {\r
+//                             // Remove lines\r
+//                             for (int i = 0; i < delta; i++) {\r
+//                                     Debug.print("Removing line: " + modelList.get(lineStart + 1));\r
+//                                     modelList.remove(lineStart + 1);\r
+//                             }\r
+//                             \r
+//                             // Check last line for changes\r
+//                             if (modelList.size() > lineStart + 1) {\r
+//                                     modelLine = modelList.get(lineStart + 1);\r
+//                                     documentLine = \r
+//                                                     BulkEditorUtil.getLineWithoutDelimiters(document, lineStart + 1);\r
+//                                     if (!documentLine.equals(modelLine)) {\r
+//                                             Debug.print("Replacing line " + lineStart + ": " + documentLine);\r
+//                                             modelList.set(lineStart + 1, documentLine);\r
+//                                     }\r
+//                             }\r
+//                     }\r
+//             }\r
+//             \r
+//             if (DirtyRegion.INSERT.equals(dirtyRegion.getType())) {\r
+//                     Debug.print(delta + " lines inserted");\r
+//                     \r
+//                     // Add lines\r
+//                     for (int i = 1; i <= delta; i++) {\r
+//                             String newLineFromDocument = \r
+//                                             BulkEditorUtil.getLineWithoutDelimiters(document, lineStart + i);\r
+//                             Debug.print("Adding line : " + newLineFromDocument);\r
+//                             modelList.add(lineStart + i, newLineFromDocument);\r
+//                     }\r
+//                     \r
+//                     // Check last line for changes\r
+//                     int lineEnd = lineStart + delta + 1;\r
+//                     if (modelList.size() < lineEnd) {\r
+//                             modelLine = modelList.get(lineEnd);\r
+//                             documentLine = \r
+//                                             BulkEditorUtil.getLineWithoutDelimiters(document, lineEnd);\r
+//                             if (!documentLine.equals(modelLine)) {\r
+//                                     Debug.print("Replacing line " + lineEnd + ": " + documentLine);\r
+//                                     modelList.set(lineEnd, documentLine);\r
+//                             }\r
+//                     }\r
+//             }\r
+//             Debug.print("Model after update: " + modelList.toString());\r
+//             \r
+//             BulkEditorUtil.printAnnotations(getAnnotationModel());\r
+//             \r
+//             Debug.print("**************************************\n");\r
+//                             \r
+//             lastLineCount = document.getNumberOfLines();\r
+//     }\r
+\r
+       private List<BulkEditorAnnotation> getAnnotations(int offset, int length) {\r
+               \r
+               List<BulkEditorAnnotation> list = new ArrayList<BulkEditorAnnotation>();\r
+               \r
+               Iterator iterator = ((IAnnotationModelExtension2) getAnnotationModel()).\r
+                               getAnnotationIterator(offset, length, true, true);\r
+               while (iterator.hasNext()) {\r
+                       Object next = iterator.next();\r
+                       if (next instanceof BulkEditorAnnotation) {\r
+                               list.add((BulkEditorAnnotation) next); \r
+                       }\r
+               }\r
+               return list;\r
+       }\r
+\r
+       private IAnnotationModel getAnnotationModel() {\r
+               return viewer.getAnnotationModel();\r
+       }\r
+       \r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)\r
+        */\r
+       public void setDocument(IDocument document) {\r
+               this.document = document;\r
+               \r
+//             modelList = new ArrayList<String>();\r
+//             for (int i = 0; i < document.getNumberOfLines(); i++) {\r
+//                     try {\r
+//                             String line = BulkEditorUtil.getLineWithoutDelimiters(document, i);\r
+//                             Debug.print("Adding line to model: " + line);\r
+//                             modelList.add(line);\r
+//                     } catch (BadLocationException e) {\r
+//                             // TODO Auto-generated catch block\r
+//                             e.printStackTrace();\r
+//                     }\r
+//             }\r
+//             lastLineCount = document.getNumberOfLines();\r
+       }\r
+}\r
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorSourceViewerConfiguration.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorSourceViewerConfiguration.java
new file mode 100644 (file)
index 0000000..236069f
--- /dev/null
@@ -0,0 +1,36 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor;\r
+\r
+import org.eclipse.jface.text.reconciler.IReconciler;\r
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;\r
+import org.eclipse.jface.text.reconciler.MonoReconciler;\r
+import org.eclipse.jface.text.source.ISourceViewer;\r
+import org.eclipse.jface.text.source.SourceViewerConfiguration;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class BulkEditorSourceViewerConfiguration extends\r
+               SourceViewerConfiguration {\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getReconciler(org.eclipse.jface.text.source.ISourceViewer)\r
+        */\r
+       public IReconciler getReconciler(ISourceViewer sourceViewer) {\r
+               \r
+               IReconcilingStrategy strategy = new BulkEditorReconcilingStrategy(sourceViewer);\r
+               IReconciler reconciler = new MonoReconciler(strategy, true);\r
+\r
+               return reconciler;\r
+       }\r
+}
\ No newline at end of file
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorUtil.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/BulkEditorUtil.java
new file mode 100644 (file)
index 0000000..3d6f015
--- /dev/null
@@ -0,0 +1,171 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.IRegion;\r
+import org.eclipse.jface.text.Position;\r
+import org.eclipse.jface.text.source.Annotation;\r
+import org.eclipse.jface.text.source.IAnnotationModel;\r
+import org.eclipse.jface.text.source.IAnnotationModelExtension2;\r
+import org.eclipse.ui.IEditorInput;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class BulkEditorUtil {\r
+       private static final Logger logger = Logger\r
+                       .getLogger(BulkEditorUtil.class);\r
+       \r
+       public static String getLineWithoutDelimiters(IDocument document, int lineno) throws BadLocationException {\r
+               int length = document.getLineLength(lineno);\r
+               int offset = document.getLineOffset(lineno);\r
+               int delimiterLength = document.getLineDelimiter(lineno) == null ? \r
+                               0 : document.getLineDelimiter(lineno).length();\r
+\r
+               return document.get(offset, length - delimiterLength);\r
+       }\r
+       \r
+       public static void removeMergeTargetAnnotations(IAnnotationModel model) {\r
+               Iterator iterator = model.getAnnotationIterator();\r
+               while (iterator.hasNext()) {\r
+                       Annotation annotation = ((Annotation) iterator.next());\r
+                       if (annotation.getType().equals(BulkEditorAnnotation.TYPE_MERGE_TARGET)) {\r
+                               annotation.setType(Annotation.TYPE_UNKNOWN);\r
+                       }\r
+               }\r
+       }\r
+\r
+       public static Set<Annotation> getMergeCandidateAnnotations(IAnnotationModel model) {\r
+               Set<Annotation> candidates = new HashSet<Annotation>();\r
+               Iterator iterator = model.getAnnotationIterator();\r
+               while (iterator.hasNext()) {\r
+                       Annotation annotation = ((Annotation) iterator.next());\r
+                       if (annotation.getType().equals(BulkEditorAnnotation.TYPE_MERGE_CANDIDATE)) {\r
+                               candidates.add(annotation);\r
+                       }\r
+               }\r
+               return candidates;\r
+       }\r
+\r
+       public static Annotation getMergeTargetAnnotation(IAnnotationModel model) {\r
+               Iterator iterator = model.getAnnotationIterator();\r
+               while (iterator.hasNext()) {\r
+                       Annotation annotation = ((Annotation) iterator.next());\r
+                       if (annotation.getType().equals(BulkEditorAnnotation.TYPE_MERGE_TARGET)) {\r
+                               return annotation;\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+       \r
+       public static String getAnnotationString(Annotation annotation, IAnnotationModel model, IDocument document) {\r
+               Position position = model.getPosition(annotation);\r
+               try {\r
+                       int line = document.getLineOfOffset(position.getOffset());\r
+                       return getLineWithoutDelimiters(document, line);\r
+               } catch (BadLocationException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               }\r
+               return "";\r
+       }\r
+\r
+       public static void removeLineFromEditorInput(int line,\r
+                       IEditorInput editorInput) {\r
+               if (editorInput instanceof BulkEditorInput) {\r
+                       ((BulkEditorInput) editorInput).getList().remove(line);\r
+               }\r
+       }\r
+\r
+       public static void removeLineFromDocument(int line, IDocument document) {\r
+               try {\r
+                       IRegion region = document.getLineInformation(line);\r
+                       document.replace(region.getOffset(), region.getLength(), "");\r
+               } catch (BadLocationException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+       \r
+       public static void printAnnotations(IAnnotationModel model) {\r
+               logger.debug("--------");\r
+               List<Annotation> list = new ArrayList<Annotation>();\r
+               Iterator iterator = model.getAnnotationIterator();\r
+               while (iterator.hasNext()) {\r
+                       boolean added = false;\r
+                       Annotation annotation = (Annotation) iterator.next();\r
+                       int offset = model.getPosition(annotation).getOffset();\r
+                       int listcount = list.size();\r
+                       for (int i = 0; i < listcount; i++) {\r
+                               if (offset < model.getPosition(list.get(i)).getOffset()) {\r
+                                       list.add(i, annotation);\r
+                                       added = true;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if (!added) {\r
+                               list.add(annotation);\r
+                       }\r
+               }\r
+               \r
+               for (Annotation annotation : list) {\r
+                       logger.debug(annotation.getClass() + " (" +\r
+                                       annotation.getType() + ") - " +\r
+                                       annotation.getText() + ": o " +\r
+                                       model.getPosition(annotation).getOffset() + ", l " + \r
+                                       model.getPosition(annotation).getLength() + ", del? " +\r
+                                       model.getPosition(annotation).isDeleted());\r
+               }\r
+               logger.debug("--------");\r
+       }\r
+\r
+       /**\r
+        * When an Annotation's type is changed, the model does not fire a change,\r
+        * so no re-paint is triggered, and any decorations associated with the type \r
+        * are not painted. Removing then re-adding triggers the paint.\r
+        *  \r
+        * @param annotation\r
+        * @param model\r
+        */\r
+       public static void reAddAnnotation(Annotation annotation,\r
+                       IAnnotationModel model) {\r
+               Position position = model.getPosition(annotation);\r
+//             model.removeAnnotation(annotation);\r
+//             model.addAnnotation(annotation, position);\r
+       }\r
+\r
+       public static Annotation getAnnotationAtLine(int line, IDocument document, \r
+                       IAnnotationModel model) {\r
+               Annotation annotation = null;\r
+               try {\r
+                       int offset = document.getLineOffset(line);\r
+                       int length = document.getLineLength(line);\r
+                       Iterator iterator = ((IAnnotationModelExtension2) model).\r
+                                                                       getAnnotationIterator(offset, length, true, true);\r
+                       if (iterator.hasNext()) {\r
+                               annotation = (Annotation) iterator.next();\r
+                       }\r
+               } catch (BadLocationException e) {\r
+                       // do nothing\r
+               }\r
+               return annotation;\r
+       }\r
+}\r
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/IEntityContainer.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/IEntityContainer.java
new file mode 100644 (file)
index 0000000..d695c35
--- /dev/null
@@ -0,0 +1,39 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor;\r
+\r
+import java.util.Set;\r
+\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ * @param <T>\r
+ */\r
+public interface IEntityContainer<T extends CdmBase> {\r
+\r
+       T getCdmEntity();\r
+       \r
+       String getEditableText();\r
+       \r
+       Set<CdmBase> getAttachedEntities();\r
+       \r
+       void markAsMerged(T mergeTarget);\r
+       \r
+       void markAsDeleted();\r
+       \r
+       boolean isMarkedAsMerged();\r
+       \r
+       boolean isMarkedAsDeleted();\r
+\r
+       void setText(String text);\r
+}\r
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/ReferenceContainer.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/ReferenceContainer.java
new file mode 100644 (file)
index 0000000..2fce0a0
--- /dev/null
@@ -0,0 +1,98 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor;\r
+\r
+import java.util.Set;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class ReferenceContainer implements IEntityContainer<ReferenceBase> {\r
+       private static final Logger logger = Logger\r
+                       .getLogger(ReferenceContainer.class);\r
+       \r
+       private ReferenceBase reference;\r
+       private boolean deleted;\r
+       private boolean merged;\r
+\r
+       ReferenceContainer(ReferenceBase reference) {\r
+               this.reference = reference;\r
+       }\r
+       \r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.taxeditor.bulkeditor.IEntityContainer#getAttachedEntities()\r
+        */\r
+       public Set<CdmBase> getAttachedEntities() {\r
+               // TODO Auto-generated method stub\r
+               return null;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.taxeditor.bulkeditor.IEntityContainer#getCdmEntity()\r
+        */\r
+       public ReferenceBase getCdmEntity() {\r
+               return reference;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.taxeditor.bulkeditor.IEntityContainer#getEditableText()\r
+        */\r
+       public String getEditableText() {\r
+               return reference.getTitleCache();\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.taxeditor.bulkeditor.IEntityContainer#markAsDeleted()\r
+        */\r
+       public void markAsDeleted() {\r
+               logger.debug("Marking  " + reference.getTitleCache() + \r
+                               " as deleted"); \r
+               this.deleted = true;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.taxeditor.bulkeditor.IEntityContainer#markAsMerged(eu.etaxonomy.cdm.model.common.CdmBase)\r
+        */\r
+       public void markAsMerged(ReferenceBase mergeTarget) {\r
+               logger.debug("Marking  " + reference.getTitleCache() + \r
+               " for merger w " + mergeTarget.getTitleCache());        \r
+               this.merged = true;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.taxeditor.bulkeditor.IEntityContainer#isMarkedAsDeleted()\r
+        */\r
+       public boolean isMarkedAsDeleted() {\r
+               return deleted;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.taxeditor.bulkeditor.IEntityContainer#isMarkedAsMerged()\r
+        */\r
+       public boolean isMarkedAsMerged() {\r
+               return merged;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.taxeditor.bulkeditor.IEntityContainer#setText(java.lang.String)\r
+        */\r
+       public void setText(String titleCache) {\r
+               logger.debug("Changing title cache from " + reference.getTitleCache() + \r
+                               " to " + titleCache);                   \r
+               reference.setTitleCache(titleCache);\r
+       }\r
+}
\ No newline at end of file
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/ReferenceEditorInput.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/ReferenceEditorInput.java
new file mode 100644 (file)
index 0000000..36f4086
--- /dev/null
@@ -0,0 +1,51 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.ui.IEditorInput;\r
+\r
+import eu.etaxonomy.cdm.model.reference.Journal;\r
+import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class ReferenceEditorInput extends BulkEditorInput<ReferenceBase> implements\r
+               IEditorInput {\r
+\r
+       private ArrayList<IEntityContainer<ReferenceBase>> list;\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.taxeditor.bulkeditor.BulkEditorInput#getList()\r
+        */\r
+       public List<IEntityContainer<ReferenceBase>> getList() {\r
+               if (list == null) {\r
+                       list = new ArrayList<IEntityContainer<ReferenceBase>>();\r
+                       \r
+                       list.add(getNewContainer("Acta universitatis carolinae. Biologica Prague"));\r
+                       list.add(getNewContainer("Acta universitatis asiae mediae. Botanica"));\r
+                       list.add(getNewContainer("Acta phytogeographica suecica Uppsala"));\r
+                       list.add(getNewContainer("Acta botanica neerlandica Amsterdam"));\r
+                       list.add(getNewContainer("Acta geobotanica hungarica Debrecen, Hungary"));\r
+               }\r
+               return list;\r
+       }\r
+       \r
+       private IEntityContainer<ReferenceBase> getNewContainer(String titleCache) {\r
+               Journal journal = Journal.NewInstance();\r
+               journal.setTitleCache(titleCache);\r
+               return new ReferenceContainer(journal);\r
+       }\r
+}
\ No newline at end of file
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/GroupMergeHandler.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/GroupMergeHandler.java
new file mode 100644 (file)
index 0000000..0b37700
--- /dev/null
@@ -0,0 +1,100 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor.handler;\r
+\r
+import java.util.Set;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.Position;\r
+import org.eclipse.jface.text.source.Annotation;\r
+import org.eclipse.jface.text.source.IAnnotationModel;\r
+import org.eclipse.ui.IEditorInput;\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.eclipse.ui.texteditor.IDocumentProvider;\r
+\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.taxeditor.bulkeditor.BulkEditor;\r
+import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorAnnotation;\r
+import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorInput;\r
+import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorUtil;\r
+import eu.etaxonomy.taxeditor.bulkeditor.IEntityContainer;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class GroupMergeHandler extends AbstractHandler {\r
+       private static final Logger logger = Logger\r
+                       .getLogger(GroupMergeHandler.class);\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)\r
+        */\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+                               \r
+               IEditorPart editor = HandlerUtil.getActiveEditor(event);\r
+               IEditorInput input = editor.getEditorInput();\r
+               if (editor instanceof BulkEditor && input instanceof BulkEditorInput) {\r
+\r
+                       IDocumentProvider provider = ((BulkEditor) editor).getDocumentProvider();\r
+                       IAnnotationModel model = provider.getAnnotationModel(input);\r
+                       IDocument document = provider.getDocument(input);\r
+                       \r
+                       // Check whether there are any group annotations\r
+                       Set<Annotation> candidateAnnotations = BulkEditorUtil.getMergeCandidateAnnotations(model);\r
+                       if (candidateAnnotations.size() == 0) {\r
+                               MessageDialog.openWarning(HandlerUtil.getActiveShell(event), \r
+                                               "No merge candidates", "You have not chosen any objects for merging.");\r
+                               return null;                            \r
+                       }\r
+                       \r
+                       // Check whether group merge target has been set\r
+                       Annotation targetAnnotation = BulkEditorUtil.getMergeTargetAnnotation(model);\r
+                       if (targetAnnotation == null) {\r
+                               MessageDialog.openWarning(HandlerUtil.getActiveShell(event), \r
+                                               "No group merge target set", "No group merge target has been set.");\r
+                               return null;\r
+                       }                       \r
+                       CdmBase targetEntity = ((BulkEditorAnnotation) targetAnnotation).\r
+                                                                               getContainer().getCdmEntity();\r
+                       \r
+                       logger.info("Merging group");\r
+                       BulkEditorUtil.printAnnotations(model);\r
+                       for (Annotation annotation : candidateAnnotations) {\r
+                               try {\r
+                                       // Remove text from document\r
+                                       Position position = model.getPosition(annotation);\r
+                                       document.replace(position.getOffset(), position.getLength(), "");\r
+                                       \r
+                                       // Mark entity container for merging with target entity\r
+                                       IEntityContainer container = \r
+                                                       ((BulkEditorAnnotation) annotation).getContainer();\r
+                                       container.markAsMerged(targetEntity);\r
+                                       logger.info("Merging " + annotation + " with " + targetAnnotation);\r
+                                       \r
+                                       // Remove annotation from model\r
+                                       model.removeAnnotation(annotation);\r
+                               } catch (BadLocationException e) {\r
+                                       // Do nothing\r
+                               }\r
+                       }\r
+                       BulkEditorUtil.printAnnotations(model); \r
+               }\r
+               return null;\r
+       }\r
+}
\ No newline at end of file
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/MergeTargetHandler.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/MergeTargetHandler.java
new file mode 100644 (file)
index 0000000..845893e
--- /dev/null
@@ -0,0 +1,69 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor.handler;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.TextSelection;\r
+import org.eclipse.jface.text.source.Annotation;\r
+import org.eclipse.jface.text.source.IAnnotationModel;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.ui.IEditorInput;\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.eclipse.ui.texteditor.IDocumentProvider;\r
+\r
+import eu.etaxonomy.taxeditor.bulkeditor.BulkEditor;\r
+import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorAnnotation;\r
+import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorInput;\r
+import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorUtil;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class MergeTargetHandler extends AbstractHandler {\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)\r
+        */\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+                               \r
+               IEditorPart editor = HandlerUtil.getActiveEditor(event);\r
+               IEditorInput input = editor.getEditorInput();\r
+               \r
+               if (editor instanceof BulkEditor && input instanceof BulkEditorInput) {\r
+                       \r
+                       IDocumentProvider provider = ((BulkEditor) editor).getDocumentProvider();\r
+                       IAnnotationModel model = provider.getAnnotationModel(input);\r
+                       IDocument document = provider.getDocument(input);\r
+                       \r
+                       ISelection selection = HandlerUtil.getActiveMenuSelection(event);\r
+                       if (selection instanceof TextSelection) {\r
+                               Annotation annotation = null;\r
+                               \r
+                               // Get annotation in current line\r
+                               int line = ((TextSelection) selection).getStartLine();\r
+                               annotation = BulkEditorUtil.getAnnotationAtLine(line, document, model);\r
+                               \r
+                               // Set annotation in current line to merge target\r
+                               if (annotation != null) {\r
+                                       BulkEditorUtil.removeMergeTargetAnnotations(model);\r
+                                       annotation.setType(BulkEditorAnnotation.TYPE_MERGE_TARGET);\r
+                                       BulkEditorUtil.reAddAnnotation(annotation, model);\r
+                               }\r
+                       }\r
+               }               \r
+               return null;\r
+       }\r
+}
\ No newline at end of file
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/OpenBulkEditorHandler.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/handler/OpenBulkEditorHandler.java
new file mode 100644 (file)
index 0000000..a0ecc45
--- /dev/null
@@ -0,0 +1,43 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2007 EDIT\r
+* European Distributed Institute of Taxonomy \r
+* http://www.e-taxonomy.eu\r
+* \r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.taxeditor.bulkeditor.handler;\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.ui.PartInitException;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.taxeditor.bulkeditor.BulkEditor;\r
+import eu.etaxonomy.taxeditor.bulkeditor.ReferenceEditorInput;\r
+\r
+/**\r
+ * @author p.ciardelli\r
+ * @created 25.06.2009\r
+ * @version 1.0\r
+ */\r
+public class OpenBulkEditorHandler extends AbstractHandler {\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)\r
+        */\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+//             HandlerUtil.\r
+               CdmBase\r
+               try {\r
+                       HandlerUtil.getActiveWorkbenchWindow(event)\r
+                                       .getActivePage().openEditor(new ReferenceEditorInput(), BulkEditor.ID);\r
+               } catch (PartInitException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               }\r
+               return null;\r
+       }\r
+}\r
diff --git a/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/internal/TaxeditorBulkeditorPlugin.java b/taxeditor-bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/internal/TaxeditorBulkeditorPlugin.java
new file mode 100644 (file)
index 0000000..8550fee
--- /dev/null
@@ -0,0 +1,79 @@
+package eu.etaxonomy.taxeditor.bulkeditor.internal;\r
+\r
+import java.net.URL;\r
+\r
+import org.eclipse.core.runtime.IPath;\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.resource.ImageRegistry;\r
+import org.eclipse.ui.plugin.AbstractUIPlugin;\r
+import org.osgi.framework.Bundle;\r
+import org.osgi.framework.BundleContext;\r
+\r
+/**\r
+ * The activator class controls the plug-in life cycle\r
+ */\r
+public class TaxeditorBulkeditorPlugin extends AbstractUIPlugin {\r
+\r
+       // The plug-in ID\r
+       public static final String PLUGIN_ID = "eu.etaxonomy.taxeditor.bulkeditor";\r
+\r
+       // The shared instance\r
+       private static TaxeditorBulkeditorPlugin plugin;\r
+       \r
+       /**\r
+        * The constructor\r
+        */\r
+       public TaxeditorBulkeditorPlugin() {\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)\r
+        */\r
+       public void start(BundleContext context) throws Exception {\r
+               super.start(context);\r
+               plugin = this;          \r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)\r
+        */\r
+       public void stop(BundleContext context) throws Exception {\r
+               plugin = null;\r
+               super.stop(context);\r
+       }\r
+\r
+       /**\r
+        * Returns the shared instance\r
+        *\r
+        * @return the shared instance\r
+        */\r
+       public static TaxeditorBulkeditorPlugin getDefault() {\r
+               return plugin;\r
+       }\r
+\r
+       /**\r
+        * Returns an image descriptor for the image file at the given\r
+        * plug-in relative path\r
+        *\r
+        * @param path the path\r
+        * @return the image descriptor\r
+        */\r
+       public static ImageDescriptor getImageDescriptor(String path) {\r
+               return imageDescriptorFromPlugin(PLUGIN_ID, path);\r
+       }\r
+       \r
+       public static final String IMAGE_ID = "sample.image";\r
+       \r
+    protected void initializeImageRegistry(ImageRegistry registry) {\r
+        Bundle bundle = Platform.getBundle(PLUGIN_ID);\r
+        IPath path = new Path("translate.gif");\r
+        URL url = Platform.find(bundle, path);\r
+        ImageDescriptor desc = ImageDescriptor.createFromURL(url);\r
+        registry.put(IMAGE_ID, desc);\r
+     }\r
+\r
+}\r
diff --git a/taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/Application.java b/taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/Application.java
new file mode 100644 (file)
index 0000000..55bba93
--- /dev/null
@@ -0,0 +1,47 @@
+package eu.etaxonomy.taxeditor.bulkeditor;
+
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+
+import eu.etaxonomy.taxeditor.bulkeditor.ApplicationWorkbenchAdvisor;
+
+/**
+ * This class controls all aspects of the application's execution
+ */
+public class Application implements IApplication {
+
+       /* (non-Javadoc)
+        * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
+        */
+       public Object start(IApplicationContext context) {
+               Display display = PlatformUI.createDisplay();
+               try {
+                       int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
+                       if (returnCode == PlatformUI.RETURN_RESTART) {
+                               return IApplication.EXIT_RESTART;
+                       }
+                       return IApplication.EXIT_OK;
+               } finally {
+                       display.dispose();
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.equinox.app.IApplication#stop()
+        */
+       public void stop() {
+               final IWorkbench workbench = PlatformUI.getWorkbench();
+               if (workbench == null)
+                       return;
+               final Display display = workbench.getDisplay();
+               display.syncExec(new Runnable() {
+                       public void run() {
+                               if (!display.isDisposed())
+                                       workbench.close();
+                       }
+               });
+       }
+}
diff --git a/taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationActionBarAdvisor.java b/taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationActionBarAdvisor.java
new file mode 100644 (file)
index 0000000..18f9b9d
--- /dev/null
@@ -0,0 +1,48 @@
+package eu.etaxonomy.taxeditor.bulkeditor;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+
+/**
+ * An action bar advisor is responsible for creating, adding, and disposing of
+ * the actions added to a workbench window. Each window will be populated with
+ * new actions.
+ */
+public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
+
+       // Actions - important to allocate these only in makeActions, and then use
+       // them
+       // in the fill methods. This ensures that the actions aren't recreated
+       // when fillActionBars is called with FILL_PROXY.
+       private IWorkbenchAction exitAction;
+
+       public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
+               super(configurer);
+       }
+
+       protected void makeActions(final IWorkbenchWindow window) {
+               // Creates the actions and registers them.
+               // Registering is needed to ensure that key bindings work.
+               // The corresponding commands keybindings are defined in the plugin.xml
+               // file.
+               // Registering also provides automatic disposal of the actions when
+               // the window is closed.
+
+               exitAction = ActionFactory.QUIT.create(window);
+               register(exitAction);
+       }
+
+       protected void fillMenuBar(IMenuManager menuBar) {
+               MenuManager fileMenu = new MenuManager("&File",
+                               IWorkbenchActionConstants.M_FILE);
+               menuBar.add(fileMenu);
+               fileMenu.add(exitAction);
+       }
+
+}
diff --git a/taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationWorkbenchAdvisor.java b/taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationWorkbenchAdvisor.java
new file mode 100644 (file)
index 0000000..1d19c26
--- /dev/null
@@ -0,0 +1,30 @@
+package eu.etaxonomy.taxeditor.bulkeditor;
+
+import org.eclipse.ui.application.IWorkbenchConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
+
+       private static final String PERSPECTIVE_ID = Perspective.ID;
+
+       public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
+                       IWorkbenchWindowConfigurer configurer) {
+               return new ApplicationWorkbenchWindowAdvisor(configurer);
+       }
+
+       @Override
+       public void initialize(IWorkbenchConfigurer configurer) {
+               super.initialize(configurer);
+               
+               // Remembers the user's view layout, window size, window location etc.
+               //  for the next time application is started
+               configurer.setSaveAndRestore(true);             
+       }
+       
+       public String getInitialWindowPerspectiveId() {
+               return PERSPECTIVE_ID;
+       }
+
+}
diff --git a/taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationWorkbenchWindowAdvisor.java b/taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/ApplicationWorkbenchWindowAdvisor.java
new file mode 100644 (file)
index 0000000..ad73d0b
--- /dev/null
@@ -0,0 +1,27 @@
+package eu.etaxonomy.taxeditor.bulkeditor;
+
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
+
+       public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
+               super(configurer);
+       }
+
+       public ActionBarAdvisor createActionBarAdvisor(
+                       IActionBarConfigurer configurer) {
+               return new ApplicationActionBarAdvisor(configurer);
+       }
+
+       public void preWindowOpen() {
+               IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
+               configurer.setInitialSize(new Point(400, 300));
+               configurer.setShowCoolBar(false);
+               configurer.setShowStatusLine(false);
+               configurer.setTitle("RCP Application");
+       }
+}
diff --git a/taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/Perspective.java b/taxeditor-bulkeditor/src/test/java/eu/etaxonomy/taxeditor/bulkeditor/Perspective.java
new file mode 100644 (file)
index 0000000..dbbf672
--- /dev/null
@@ -0,0 +1,14 @@
+package eu.etaxonomy.taxeditor.bulkeditor;
+
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class Perspective implements IPerspectiveFactory {
+
+       public static final String ID = "bulkeditor.perspective";
+
+       public void createInitialLayout(IPageLayout layout) {
+               layout.setEditorAreaVisible(true);
+               layout.setFixed(true);
+       }
+}
\ No newline at end of file