1 package jalview.ws2.operations;
3 import java.util.ArrayList;
4 import java.util.Collections;
6 import java.util.concurrent.CompletionStage;
8 import javax.swing.JCheckBoxMenuItem;
9 import javax.swing.JMenu;
10 import javax.swing.JMenuItem;
11 import javax.swing.event.MenuEvent;
12 import javax.swing.event.MenuListener;
14 import jalview.api.AlignCalcManagerI2;
15 import jalview.api.AlignmentViewPanel;
16 import jalview.datamodel.AlignmentAnnotation;
17 import jalview.gui.AlignFrame;
18 import jalview.gui.AlignViewport;
19 import jalview.gui.WsJobParameters;
20 import jalview.io.FeaturesFile;
21 import jalview.util.Format;
22 import jalview.util.MessageManager;
23 import jalview.ws.params.ArgumentI;
24 import jalview.ws.params.WsParamSetI;
25 import jalview.ws2.MenuEntryProviderI;
26 import jalview.ws2.ResultSupplier;
27 import jalview.ws2.PollingTaskExecutor;
28 import jalview.ws2.WebServiceI;
35 public class AnnotationOperation implements Operation
37 final WebServiceI service;
39 final String typeName;
41 final ResultSupplier<List<AlignmentAnnotation>> annotationSupplier;
43 final ResultSupplier<FeaturesFile> featuresSupplier;
45 boolean alignmentAnalysis = false;
47 boolean interactive = false;
50 * Is it fine to get rid of AlignAnalysisUIText?
53 public AnnotationOperation(WebServiceI service,
54 ResultSupplier<List<AlignmentAnnotation>> annotSupplier,
55 ResultSupplier<FeaturesFile> featSupplier, String operationName)
57 this.service = service;
58 this.annotationSupplier = annotSupplier;
59 this.featuresSupplier = featSupplier;
60 this.typeName = operationName;
64 public String getName()
66 return service.getName();
70 public String getTypeName()
76 public String getHostName()
78 return service.getHostName();
82 public int getMinSequences()
88 public int getMaxSequences()
90 return Integer.MAX_VALUE;
94 public boolean canSubmitGaps()
100 public boolean isProteinOperation()
106 public boolean isNucleotideOperation()
112 public boolean isInteractive()
117 public void setInteractive(boolean value)
119 this.interactive = value;
123 public boolean isAlignmentAnalysis()
125 return alignmentAnalysis;
128 public void setAlignmentAnalysis(boolean value)
130 this.alignmentAnalysis = value;
134 public boolean getFilterNonStandardSymbols()
140 public boolean getNeedsAlignedSequences()
146 public MenuEntryProviderI getMenuBuilder()
149 return this::buildInteractiveMenu;
151 return this::buildClassicMenu;
154 protected void buildClassicMenu(JMenu parent, AlignFrame frame)
156 final var calcName = service.getName();
157 PollingTaskExecutor wsExecutor = frame.getViewport().getWSExecutor();
158 final var calcManager = frame.getViewport().getCalcManager();
160 var item = new JMenuItem(MessageManager.formatMessage(
161 "label.calcname_with_default_settings", calcName));
162 item.addActionListener((event) -> {
163 var worker = createWorker(Collections.emptyList(), frame, calcManager);
164 calcManager.startWorker(worker);
168 if (service.hasParameters())
170 var item = new JMenuItem(
171 MessageManager.getString("label.edit_settings_and_run"));
172 item.setToolTipText(MessageManager.getString(
173 "label.view_and_change_parameters_before_running_calculation"));
174 item.addActionListener((event) -> {
175 openEditParamsDialog(service, null, null)
176 .thenAcceptAsync((arguments) -> {
177 if (arguments != null)
179 var worker = createWorker(arguments, frame, calcManager);
180 calcManager.startWorker(worker);
188 protected void buildInteractiveMenu(JMenu parent, AlignFrame frame)
190 final var calcName = service.getName();
191 final var calcManager = frame.getViewport().getCalcManager();
192 final var arguments = new ArrayList<ArgumentI>();
193 final JCheckBoxMenuItem runItem;
195 // TODO use MessageManager and set tool tip text
196 runItem = new JCheckBoxMenuItem(
197 String.format("%s calculations", calcName));
198 runItem.addActionListener((event) -> {
199 calcManager.removeWorkersForName(calcName);
200 var worker = createWorker(arguments, frame, calcManager);
201 calcManager.registerWorker(worker);
205 JMenuItem _editItem = null;
206 if (service.hasParameters())
208 // TODO use MessageManager and set tool tip text
209 _editItem = new JMenuItem(
210 String.format("Edit %s settings", calcName));
211 _editItem.addActionListener((event) -> {
212 openEditParamsDialog(service, null, null)
213 .thenAcceptAsync((args) -> {
214 if (arguments != null)
217 arguments.addAll(args);
218 calcManager.removeWorkersForName(calcName);
219 var worker = createWorker(arguments, frame, calcManager);
220 calcManager.registerWorker(worker);
224 parent.add(_editItem);
226 final var editItem = _editItem;
228 parent.addMenuListener(new MenuListener()
231 public void menuSelected(MenuEvent e)
233 var isNuc = frame.getViewport().getAlignment().isNucleotide();
234 var menuEnabled = (isNuc && isNucleotideOperation()) ||
235 (!isNuc && isProteinOperation());
236 runItem.setEnabled(menuEnabled);
237 if (editItem != null)
238 editItem.setEnabled(menuEnabled);
239 boolean currentlyRunning = calcManager.getWorkersForName(calcName).size() > 0;
240 runItem.setSelected(currentlyRunning);
244 public void menuDeselected(MenuEvent e) {}
247 public void menuCanceled(MenuEvent e) {}
251 private AnnotationServiceWorker createWorker(
252 List<ArgumentI> arguments, AlignFrame frame, AlignCalcManagerI2 calcManager)
254 /* What is the purpose of AlignViewport and AlignmentViewPanel? */
255 AlignViewport viewport = frame.getCurrentView();
256 AlignmentViewPanel alignPanel = frame.alignPanel;
257 return new AnnotationServiceWorker(this, service,
258 arguments, viewport, alignPanel, frame, frame,
262 private CompletionStage<List<ArgumentI>> openEditParamsDialog(
263 WebServiceI service, WsParamSetI preset, List<ArgumentI> arguments)
265 WsJobParameters jobParams;
266 if (preset == null && arguments != null && arguments.size() > 0)
267 jobParams = new WsJobParameters(service.getParamStore(), preset,
270 jobParams = new WsJobParameters(service.getParamStore(), preset,
274 jobParams.setName(MessageManager.getString(
275 "label.adjusting_parameters_for_calculation"));
277 var stage = jobParams.showRunDialog();
278 return stage.thenApply((startJob) -> {
281 if (jobParams.getPreset() == null)
282 return jobParams.getJobParams();
284 return jobParams.getPreset().getArguments();