feature: Add ability to create Action from Task
diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/CreateActionFromTaskAction.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/CreateActionFromTaskAction.java
new file mode 100644
index 0000000..93dadd8
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/actions/CreateActionFromTaskAction.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.actions;
+
+import java.util.Collection;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.osee.ats.core.task.TaskArtifact;
+import org.eclipse.osee.ats.operation.CreateActionFromTaskBlam;
+import org.eclipse.osee.framework.ui.skynet.FrameworkImage;
+import org.eclipse.osee.framework.ui.skynet.blam.BlamEditor;
+import org.eclipse.osee.framework.ui.swt.ImageManager;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class CreateActionFromTaskAction extends Action {
+
+   private final Collection<TaskArtifact> tasks;
+
+   public CreateActionFromTaskAction(Collection<TaskArtifact> tasks) {
+      super("Create Action from Task");
+      this.tasks = tasks;
+   }
+
+   @Override
+   public void run() {
+      CreateActionFromTaskBlam blamOperation = new CreateActionFromTaskBlam();
+      blamOperation.setDefaultTeamWorkflows(tasks);
+      BlamEditor.edit(blamOperation);
+   }
+
+   @Override
+   public ImageDescriptor getImageDescriptor() {
+      return ImageManager.getImageDescriptor(FrameworkImage.DUPLICATE);
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/editor/SMAOperationsSection.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/editor/SMAOperationsSection.java
index ae3ad78..ce087d0 100644
--- a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/editor/SMAOperationsSection.java
+++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/editor/SMAOperationsSection.java
@@ -15,6 +15,7 @@
 import java.util.List;
 import org.eclipse.osee.ats.actions.AccessControlAction;
 import org.eclipse.osee.ats.actions.ConvertActionableItemsAction;
+import org.eclipse.osee.ats.actions.CreateActionFromTaskAction;
 import org.eclipse.osee.ats.actions.DeletePurgeAtsArtifactsAction;
 import org.eclipse.osee.ats.actions.DirtyReportAction;
 import org.eclipse.osee.ats.actions.DuplicateWorkflowAction;
@@ -31,6 +32,7 @@
 import org.eclipse.osee.ats.actions.ShowBranchChangeDataAction;
 import org.eclipse.osee.ats.actions.ShowWorkDefinitionAction;
 import org.eclipse.osee.ats.actions.SubscribedAction;
+import org.eclipse.osee.ats.core.task.TaskArtifact;
 import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
 import org.eclipse.osee.ats.core.util.AtsUtilCore;
 import org.eclipse.osee.ats.internal.Activator;
@@ -123,7 +125,7 @@
    }
 
    private void createImpactsSection(Composite parent, FormToolkit toolkit) {
-      if (!editor.getAwa().isTeamWorkflow()) {
+      if (!editor.getAwa().isTeamWorkflow() && !editor.getAwa().isTask()) {
          return;
       }
       Section section = toolkit.createSection(parent, ExpandableComposite.TITLE_BAR);
@@ -144,6 +146,10 @@
             sectionBody, 2);
          new XButtonViaAction(new AccessControlAction(editor.getAwa())).createWidgets(sectionBody, 2);
       }
+      if (editor.getAwa().isTask()) {
+         new XButtonViaAction(new CreateActionFromTaskAction(Collections.singleton((TaskArtifact) editor.getAwa()))).createWidgets(
+            sectionBody, 2);
+      }
       section.setClient(sectionBody);
    }
 
diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/operation/CreateActionFromTaskBlam.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/operation/CreateActionFromTaskBlam.java
new file mode 100644
index 0000000..4c7d82a
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/operation/CreateActionFromTaskBlam.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.ats.operation;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.osee.ats.core.action.ActionArtifact;
+import org.eclipse.osee.ats.core.action.ActionManager;
+import org.eclipse.osee.ats.core.config.ActionableItemArtifact;
+import org.eclipse.osee.ats.core.task.TaskArtifact;
+import org.eclipse.osee.ats.core.team.TeamWorkFlowArtifact;
+import org.eclipse.osee.ats.core.type.AtsArtifactTypes;
+import org.eclipse.osee.ats.core.type.AtsAttributeTypes;
+import org.eclipse.osee.ats.core.util.AtsUtilCore;
+import org.eclipse.osee.ats.core.workflow.ChangeType;
+import org.eclipse.osee.ats.editor.SMAEditor;
+import org.eclipse.osee.ats.internal.Activator;
+import org.eclipse.osee.ats.util.AtsUtil;
+import org.eclipse.osee.framework.core.enums.CoreRelationTypes;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.UserManager;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.attribute.AttributeTypeManager;
+import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
+import org.eclipse.osee.framework.skynet.core.transaction.TransactionManager;
+import org.eclipse.osee.framework.ui.plugin.util.AWorkbench;
+import org.eclipse.osee.framework.ui.skynet.blam.AbstractBlam;
+import org.eclipse.osee.framework.ui.skynet.blam.VariableMap;
+import org.eclipse.osee.framework.ui.skynet.widgets.XListDropViewer;
+import org.eclipse.osee.framework.ui.skynet.widgets.XModifiedListener;
+import org.eclipse.osee.framework.ui.skynet.widgets.XWidget;
+import org.eclipse.osee.framework.ui.skynet.widgets.util.DynamicXWidgetLayout;
+import org.eclipse.osee.framework.ui.swt.Displays;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class CreateActionFromTaskBlam extends AbstractBlam {
+
+   private final static String TASKS = "Tasks (drop here)";
+   private final static String TITLE = "New Title (blank for same title)";
+   private final static String ACTIONABLE_ITEMS = "Actionable Item(s)";
+   private final static String CHANGE_TYPE = "Change Type";
+   private final static String PRIORITY = "Priority";
+   private Collection<TaskArtifact> taskArtifacts;
+
+   public CreateActionFromTaskBlam() {
+      // do nothing
+   }
+
+   @Override
+   public void runOperation(final VariableMap variableMap, final IProgressMonitor monitor) {
+      Displays.ensureInDisplayThread(new Runnable() {
+         @Override
+         public void run() {
+            try {
+               List<Artifact> artifacts = variableMap.getArtifacts(TASKS);
+               String title = variableMap.getString(TITLE);
+               List<Artifact> aiasArts = variableMap.getArtifacts(ACTIONABLE_ITEMS);
+               String changeTypeStr = variableMap.getString(CHANGE_TYPE);
+               if (changeTypeStr == null || changeTypeStr.equals("--select--")) {
+                  AWorkbench.popup("ERROR", "Must select a Change Type");
+                  return;
+               }
+               ChangeType changeType = ChangeType.valueOf(changeTypeStr);
+               String priority = variableMap.getString(PRIORITY);
+               if (priority == null || priority.equals("--select--")) {
+                  AWorkbench.popup("ERROR", "Must select a Priority");
+                  return;
+               }
+
+               if (artifacts.isEmpty()) {
+                  AWorkbench.popup("ERROR", "Must drag in Tasks to create Actions.");
+                  return;
+               }
+               Artifact artifact = artifacts.iterator().next();
+               if (!(artifact.isOfType(AtsArtifactTypes.Task))) {
+                  AWorkbench.popup("ERROR", "Artifact MUST be Task");
+                  return;
+               }
+               if (aiasArts.isEmpty()) {
+                  AWorkbench.popup("ERROR", "Must select Actionable Item(s)");
+                  return;
+               }
+               try {
+                  AtsUtilCore.setEmailEnabled(false);
+                  Collection<TaskArtifact> taskArts = Collections.castAll(artifacts);
+                  Collection<ActionableItemArtifact> aias = Collections.castAll(aiasArts);
+                  handleCreateActions(taskArts, title, aias, changeType, priority, monitor);
+               } catch (Exception ex) {
+                  log(ex);
+               } finally {
+                  AtsUtilCore.setEmailEnabled(true);
+               }
+
+            } catch (Exception ex) {
+               OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+            }
+         };
+      });
+   }
+
+   private void handleCreateActions(Collection<TaskArtifact> tasks, String title, Collection<ActionableItemArtifact> aias, ChangeType changeType, String priority, IProgressMonitor monitor) throws OseeCoreException {
+      Set<TeamWorkFlowArtifact> newTeamArts = new HashSet<TeamWorkFlowArtifact>();
+      SkynetTransaction transaction =
+         TransactionManager.createTransaction(AtsUtil.getAtsBranch(), "Create Actions from Tasks");
+      for (TaskArtifact task : tasks) {
+         ActionArtifact action =
+            ActionManager.createAction(monitor, title, getDescription(task), changeType, priority, false, null, aias,
+               new Date(), UserManager.getUser(), null, transaction);
+
+         for (TeamWorkFlowArtifact teamArt : action.getTeams()) {
+            newTeamArts.add(teamArt);
+            teamArt.addRelation(CoreRelationTypes.SupportingInfo_SupportingInfo, task);
+            teamArt.persist(transaction);
+         }
+      }
+      transaction.execute();
+      for (TeamWorkFlowArtifact newTeamArt : newTeamArts) {
+         SMAEditor.editArtifact(newTeamArt);
+      }
+   }
+
+   private String getDescription(TaskArtifact taskArt) {
+      if (Strings.isValid(taskArt.getDescription())) {
+         return String.format("Create from task [%s]\n\n[%s]", taskArt.toStringWithId(), taskArt.getDescription());
+      }
+      return String.format("Created from task [%s]", taskArt.toStringWithId());
+   }
+
+   @Override
+   public void widgetCreated(XWidget xWidget, FormToolkit toolkit, Artifact art, DynamicXWidgetLayout dynamicXWidgetLayout, XModifiedListener modListener, boolean isEditable) throws OseeCoreException {
+      super.widgetCreated(xWidget, toolkit, art, dynamicXWidgetLayout, modListener, isEditable);
+      if (xWidget.getLabel().equals(TASKS) && taskArtifacts != null) {
+         XListDropViewer viewer = (XListDropViewer) xWidget;
+         viewer.setInput(taskArtifacts);
+      }
+   }
+
+   @Override
+   public String getXWidgetsXml() throws OseeCoreException {
+      return "<xWidgets><XWidget xwidgetType=\"XListDropViewer\" displayName=\"" + TASKS + "\" />" +
+      //
+      "<XWidget xwidgetType=\"XHyperlabelActionableItemSelection\" displayName=\"" + ACTIONABLE_ITEMS + "\" horizontalLabel=\"true\"/>" +
+      //
+      "<XWidget xwidgetType=\"XText\" displayName=\"" + TITLE + "\" horizontalLabel=\"true\" defaultValue=\"" + getDefaultTitle() + "\"/>" +
+      //
+      "<XWidget displayName=\"" + CHANGE_TYPE + "\" xwidgetType=\"XCombo(" + Collections.toString(",",
+         AttributeTypeManager.getEnumerationValues(AtsAttributeTypes.ChangeType)) + ")\" required=\"true\" horizontalLabel=\"true\" toolTip=\"" + AtsAttributeTypes.ChangeType.getDescription() + "\"/>" +
+      //
+      "<XWidget displayName=\"" + PRIORITY + "\" xwidgetType=\"XCombo(" + Collections.toString(",",
+         AttributeTypeManager.getEnumerationValues(AtsAttributeTypes.PriorityType)) + ")\" required=\"true\" horizontalLabel=\"true\"/>" +
+      //
+      "</xWidgets>";
+   }
+
+   /**
+    * Return "Copy of"-title if all titles of workflows are the same, else ""
+    */
+   private String getDefaultTitle() {
+      String title = "";
+      if (taskArtifacts != null) {
+         for (TaskArtifact taskArt : taskArtifacts) {
+            if (title.equals("")) {
+               title = taskArt.getName();
+            } else if (!title.equals(taskArt.getName())) {
+               return "";
+            }
+         }
+      }
+      return title;
+   }
+
+   @Override
+   public String getDescriptionUsage() {
+      return "Create Action from task and relate using supporting information relation.";
+   }
+
+   /**
+    * @return the defaultTeamWorkflows
+    */
+   public Collection<TaskArtifact> getDefaultTeamWorkflows() {
+      return taskArtifacts;
+   }
+
+   /**
+    * @param taskArtifacts the defaultTeamWorkflows to set
+    */
+   public void setDefaultTeamWorkflows(Collection<? extends TaskArtifact> taskArtifacts) {
+      this.taskArtifacts = new LinkedList<TaskArtifact>();
+      this.taskArtifacts.addAll(taskArtifacts);
+   }
+
+   @Override
+   public String getName() {
+      return "Duplicate Workflow";
+   }
+
+   @Override
+   public Collection<String> getCategories() {
+      return Arrays.asList("ATS");
+   }
+
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/review/ReviewSearchWorkflowSearchItem.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/review/ReviewSearchWorkflowSearchItem.java
index f9e1798..7c88670 100644
--- a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/review/ReviewSearchWorkflowSearchItem.java
+++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/review/ReviewSearchWorkflowSearchItem.java
@@ -314,7 +314,7 @@
       if (aiCombo == null) {
          return java.util.Collections.emptyList();
       }
-      return aiCombo.getSelectedTeamDefintions();
+      return aiCombo.getSelectedActionableItems();
    }
 
    public void setSelectedTeamDefinitions(Collection<ActionableItemArtifact> selectedAis) {
diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/util/widgets/XHyperlabelActionableItemSelection.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/util/widgets/XHyperlabelActionableItemSelection.java
index 5158901..b6d615f 100644
--- a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/util/widgets/XHyperlabelActionableItemSelection.java
+++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/util/widgets/XHyperlabelActionableItemSelection.java
@@ -12,6 +12,7 @@
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.List;
 import org.eclipse.osee.ats.core.config.ActionableItemArtifact;
 import org.eclipse.osee.ats.internal.Activator;
 import org.eclipse.osee.ats.util.widgets.dialog.ActionableItemTreeWithChildrenDialog;
@@ -19,6 +20,7 @@
 import org.eclipse.osee.framework.core.enums.Active;
 import org.eclipse.osee.framework.logging.OseeLevel;
 import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
 import org.eclipse.osee.framework.skynet.core.utility.Artifacts;
 import org.eclipse.osee.framework.ui.skynet.widgets.XHyperlinkLabelCmdValueSelection;
 
@@ -36,17 +38,23 @@
       super(label, true, WorldEditor.TITLE_MAX_LENGTH);
    }
 
-   public Collection<ActionableItemArtifact> getSelectedTeamDefintions() {
+   public Collection<ActionableItemArtifact> getSelectedActionableItems() {
       return selectedAis;
    }
 
    @Override
+   public Object getData() {
+      List<Artifact> arts = org.eclipse.osee.framework.jdk.core.util.Collections.castAll(getSelectedActionableItems());
+      return arts;
+   }
+
+   @Override
    public String getCurrentValue() {
       return Artifacts.commaArts(selectedAis);
    }
 
-   public void setSelectedAIs(Collection<ActionableItemArtifact> selectedTeamDefs) {
-      this.selectedAis = selectedTeamDefs;
+   public void setSelectedAIs(Collection<ActionableItemArtifact> selectedAIs) {
+      this.selectedAis = selectedAIs;
       refresh();
       notifyXModifiedListeners();
    }
diff --git a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/util/widgets/XHyperlabelTeamDefinitionSelection.java b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/util/widgets/XHyperlabelTeamDefinitionSelection.java
index bc3a9cf..74baea2 100644
--- a/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/util/widgets/XHyperlabelTeamDefinitionSelection.java
+++ b/plugins/org.eclipse.osee.ats/src/org/eclipse/osee/ats/util/widgets/XHyperlabelTeamDefinitionSelection.java
@@ -12,6 +12,7 @@
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.List;
 import org.eclipse.osee.ats.core.config.TeamDefinitionArtifact;
 import org.eclipse.osee.ats.internal.Activator;
 import org.eclipse.osee.ats.util.widgets.dialog.TeamDefinitionTreeWithChildrenDialog;
@@ -19,6 +20,7 @@
 import org.eclipse.osee.framework.core.enums.Active;
 import org.eclipse.osee.framework.logging.OseeLevel;
 import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
 import org.eclipse.osee.framework.skynet.core.utility.Artifacts;
 import org.eclipse.osee.framework.ui.skynet.widgets.XHyperlinkLabelCmdValueSelection;
 
@@ -41,6 +43,12 @@
    }
 
    @Override
+   public Object getData() {
+      List<Artifact> arts = org.eclipse.osee.framework.jdk.core.util.Collections.castAll(getSelectedTeamDefintions());
+      return arts;
+   }
+
+   @Override
    public String getCurrentValue() {
       return Artifacts.commaArts(selectedTeamDefs);
    }