/*
* #%L
* gitools-ui-app
* %%
* Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package org.gitools.ui.app.actions.edit;
import org.gitools.api.analysis.Clusters;
import org.gitools.api.matrix.MatrixDimensionKey;
import org.gitools.heatmap.Heatmap;
import org.gitools.heatmap.HeatmapDimension;
import org.gitools.heatmap.header.ColoredLabel;
import org.gitools.heatmap.header.HeatmapColoredLabelsHeader;
import org.gitools.heatmap.header.HeatmapHeader;
import org.gitools.heatmap.header.HierarchicalClusterHeatmapHeader;
import org.gitools.matrix.model.matrix.AnnotationMatrix;
import org.gitools.ui.app.actions.HeatmapDimensionAction;
import org.gitools.ui.app.heatmap.panel.settings.headers.AddNewManualAnnotationSection;
import org.gitools.ui.app.heatmap.panel.settings.headers.ChangeAnnotationValueSection;
import org.gitools.ui.core.Application;
import org.gitools.ui.core.HeatmapPosition;
import org.gitools.ui.core.actions.dynamicactions.IHeatmapHeaderAction;
import org.gitools.ui.platform.dialog.DialogButtonsPanel;
import org.gitools.ui.platform.icons.IconNames;
import org.gitools.ui.platform.settings.ISettingsSection;
import org.gitools.ui.platform.settings.SettingsDialog;
import org.gitools.ui.platform.settings.SettingsPanel;
import org.gitools.utils.color.ColorGenerator;
import org.gitools.utils.textpattern.TextPattern;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;
import static org.gitools.ui.app.commands.AddHeaderColoredLabelsCommand.makeAnnotationClustering;
import static org.gitools.ui.app.commands.AddHeaderColoredLabelsCommand.updateFromClusterResults;
public class EditAnnotationValueAction extends HeatmapDimensionAction implements IHeatmapHeaderAction {
private HeatmapHeader header;
private HeatmapPosition position;
public EditAnnotationValueAction(MatrixDimensionKey dimensionKey) {
super(dimensionKey, "<html><i>Annotate</i> selected ...</html>");
setSmallIconFromResource(IconNames.anno16);
}
public EditAnnotationValueAction(HeatmapHeader header) {
super(header.getHeatmapDimension().getId(), header.getTitle());
setSmallIconFromResource(IconNames.edit16);
this.header = header;
}
public HeatmapHeader getHeader() {
return header;
}
public void setHeader(HeatmapHeader header) {
this.header = header;
}
@Override
public boolean isEnabledByModel(Object model) {
System.out.println(header.getTitle().toLowerCase());
if (model instanceof Heatmap) {
return !header.getTitle().toLowerCase().equals("id");
}
return false;
}
@Override
public void actionPerformed(ActionEvent e) {
execute(header, position);
}
public void execute(final HeatmapHeader header, final HeatmapPosition position) {
final List<ISettingsSection> sections = new ArrayList<>();
final Set<String> selected = header.getHeatmapDimension().getSelected();
if (editable(header)) {
final ChangeAnnotationValueSection annotationValueSection = new ChangeAnnotationValueSection(header, new ArrayList<>(selected));
sections.add(annotationValueSection);
}
for (HeatmapHeader heatmapHeader : header.getHeatmapDimension().getHeaders()) {
if (editable(heatmapHeader) && !header.getTitle().equals(heatmapHeader.getTitle())) {
sections.add(new ChangeAnnotationValueSection(heatmapHeader, new ArrayList<String>(selected)));
}
}
sections.add(new AddNewManualAnnotationSection(header.getHeatmapDimension().getAnnotations(), new ArrayList<String>(selected)));
SettingsPanel settingsPanel = new SettingsPanel(
"Edit & add annotation",
"<html><body>Change the annotation of the selected " + header.getHeatmapDimension().getId().toString().toLowerCase() + " and/or add a new annotation.</body></html>",
IconNames.logoNoText,
sections
);
SettingsDialog dialog = new SettingsDialog(Application.get(), settingsPanel, sections.get(0).getName()) {
@Override
protected void close() {
setVisible(false);
}
@Override
protected void apply() {
for (ISettingsSection section : sections) {
if (section.isDirty()) {
if (section instanceof ChangeAnnotationValueSection) {
applyChanges((ChangeAnnotationValueSection) section);
} else if (section instanceof AddNewManualAnnotationSection) {
addNewAnnotation((AddNewManualAnnotationSection) section);
}
}
}
header.getHeatmapDimension().updateHeaders();
}
@Override
public DialogButtonsPanel getButtonsPanel() {
JButton closeButton = new JButton("Cancel");
closeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
close();
}
});
JButton applyButton = new JButton("Apply");
applyButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
apply();
close();
}
});
closeButton.setDefaultCapable(true);
return new DialogButtonsPanel(Arrays.asList(applyButton, closeButton));
}
};
dialog.open();
}
private static boolean editable(HeatmapHeader header) {
return !header.getTitle().toLowerCase().equals("id")
&& !(header instanceof HierarchicalClusterHeatmapHeader);
}
private static void applyChanges(ChangeAnnotationValueSection section) {
Map<String, String> inputs = section.getInputMap();
List<TextPattern.VariableToken> annotationKeys = section.getAnnotationKeys();
AnnotationMatrix annotations = section.getAnnotations();
for (String s : section.getSelected()) {
for (TextPattern.VariableToken annotationKey : annotationKeys) {
annotations.setAnnotation(s, annotationKey.toString(), inputs.get(annotationKey.getVariableName()));
}
}
if (section.getHeatmapHeader() instanceof HeatmapColoredLabelsHeader) {
HeatmapColoredLabelsHeader h = (HeatmapColoredLabelsHeader) section.getHeatmapHeader();
List<Color> usedColors = new ArrayList<>();
for (ColoredLabel coloredLabel : h.getClusters()) {
usedColors.add(coloredLabel.getColor());
}
ColorGenerator cg = new ColorGenerator();
cg.initUsed(usedColors);
Clusters results = makeAnnotationClustering(h);
for (String s : results.getClusters()) {
if (!h.getClusters().contains(s)) {
h.getClusters().add(new ColoredLabel(s, cg.next(s)));
}
}
}
}
private void addNewAnnotation(AddNewManualAnnotationSection section) {
AnnotationMatrix annotations = section.getAnnotations();
for (String s : section.getSelected()) {
annotations.setAnnotation(s, section.getAnnotationLabel(), section.getAnnotationValue());
}
HeatmapDimension dim = getHeader().getHeatmapDimension();
HeatmapColoredLabelsHeader newHeader = new HeatmapColoredLabelsHeader(dim);
newHeader.setAnnotationPattern("${" + section.getAnnotationLabel() + "}");
newHeader.setTitle(section.getAnnotationLabel());
Clusters results = makeAnnotationClustering(newHeader);
updateFromClusterResults(newHeader, results.getClusters());
dim.addHeader(newHeader);
}
@Override
public void onConfigure(HeatmapHeader object, HeatmapPosition position) {
setHeader(object);
setPosition(position);
setEnabled(getDimension().getSelected().size() > 0);
}
public void setPosition(HeatmapPosition position) {
this.position = position;
}
}