diff --git a/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/provider/GroupNamingEditingSupport.java b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/provider/GroupNamingEditingSupport.java new file mode 100644 index 0000000000..3832c5a7cc --- /dev/null +++ b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/provider/GroupNamingEditingSupport.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2024 Lablicate GmbH. + * + * 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: + * Lorenz Gerber - initial API and implementation + *******************************************************************************/ +package org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.provider; + +import org.eclipse.chemclipse.model.statistics.ISample; +import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.swt.SampleGroupAssignerListUI; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.CheckboxCellEditor; +import org.eclipse.jface.viewers.EditingSupport; + +public class GroupNamingEditingSupport extends EditingSupport { + + private CellEditor cellEditor; + private final SampleGroupAssignerListUI tableViewer; + private final String column; + + public GroupNamingEditingSupport(SampleGroupAssignerListUI tableViewer, String column) { + + super(tableViewer); + this.column = column; + if(SampleGroupAssignerLabelProvider.SELECT.equals(column)) { + this.cellEditor = new CheckboxCellEditor(tableViewer.getTable()); + } + this.tableViewer = tableViewer; + } + + @Override + protected CellEditor getCellEditor(Object element) { + + return cellEditor; + } + + @Override + protected boolean canEdit(Object element) { + + return true; + } + + @Override + protected Object getValue(Object element) { + + if(element instanceof ISample sample) { + switch(column) { + case SampleGroupAssignerLabelProvider.SELECT: + return sample.isSelected(); + } + } + return false; + } + + @Override + protected void setValue(Object element, Object value) { + + if(element instanceof ISample sample) { + switch(column) { + case SampleGroupAssignerLabelProvider.SELECT: + sample.setSelected((boolean)value); + break; + } + tableViewer.refresh(); + } + } +} diff --git a/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/provider/SampleGroupAssignerLabelProvider.java b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/provider/SampleGroupAssignerLabelProvider.java new file mode 100644 index 0000000000..dc8e89a891 --- /dev/null +++ b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/provider/SampleGroupAssignerLabelProvider.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2024 Lablicate GmbH. + * + * 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: + * Lorenz Gerber - initial API and implementation + *******************************************************************************/ +package org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.provider; + +import org.eclipse.chemclipse.model.statistics.ISample; +import org.eclipse.chemclipse.rcp.ui.icons.core.ApplicationImageFactory; +import org.eclipse.chemclipse.rcp.ui.icons.core.IApplicationImage; +import org.eclipse.chemclipse.rcp.ui.icons.core.IApplicationImageProvider; +import org.eclipse.chemclipse.support.ui.provider.AbstractChemClipseLabelProvider; +import org.eclipse.swt.graphics.Image; + +public class SampleGroupAssignerLabelProvider extends AbstractChemClipseLabelProvider { + + public static final String SAMPLE_NAME = "Sample Name"; + public static final String SELECT = "Select"; + public static final String GROUP_NAME = "Group Name"; + public static final int INDEX_COLOR = 2; + // + public static String[] TITLES = {// + SAMPLE_NAME, // + SELECT, // + GROUP_NAME // + }; + // + public static int[] BOUNDS = {// + 300, // + 30, // + 100, // + }; + + @Override + public Image getColumnImage(Object element, int columnIndex) { + + if(columnIndex == 0) { + return getImage(element); + } else if(columnIndex == 1) { + if(element instanceof ISample sample) { + if(sample.isSelected()) { + return ApplicationImageFactory.getInstance().getImage(IApplicationImage.IMAGE_SELECTED, IApplicationImageProvider.SIZE_16x16); + } else { + return ApplicationImageFactory.getInstance().getImage(IApplicationImage.IMAGE_DESELECTED, IApplicationImageProvider.SIZE_16x16); + } + } + } + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + + String text = ""; + if(element instanceof ISample sample) { + // + switch(columnIndex) { + case 0: + text = sample.getSampleName() != null ? sample.getSampleName() : ""; + break; + case 1: + text = ""; // Checkbox + break; + case 2: + text = sample.getGroupName() != null ? sample.getGroupName() : ""; + break; + } + } + return text; + } +} diff --git a/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/wizards/GroupNamingWizard.java b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/wizards/GroupNamingWizard.java new file mode 100644 index 0000000000..61617c8e93 --- /dev/null +++ b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/wizards/GroupNamingWizard.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2024 Lablicate GmbH. + * + * 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: + * Lorenz Gerber - initial API and implementation + *******************************************************************************/ +package org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.wizards; + +import java.util.List; + +import org.eclipse.chemclipse.model.statistics.ISample; +import org.eclipse.chemclipse.model.statistics.IVariable; +import org.eclipse.chemclipse.xxd.process.supplier.pca.model.ISamplesPCA; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.Wizard; + +public class GroupNamingWizard extends Wizard implements IWizard { + + private GroupNamingWizardPage groupNamingWizardPage; + private ISamplesPCA samples; + + public GroupNamingWizard(ISamplesPCA samples) { + + this.groupNamingWizardPage = new GroupNamingWizardPage(samples); + this.samples = samples; + } + + @Override + public void addPages() { + + addPage(groupNamingWizardPage); + } + + @Override + public boolean performFinish() { + + List groupSamples = this.groupNamingWizardPage.getGroupSamples(); + for(int i = 0; i < groupSamples.size(); i++) { + samples.getSamples().get(i).setGroupName(groupSamples.get(i).getGroupName()); + } + return true; + } +} diff --git a/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/wizards/GroupNamingWizardPage.java b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/wizards/GroupNamingWizardPage.java new file mode 100644 index 0000000000..b2fe5f5c73 --- /dev/null +++ b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/internal/wizards/GroupNamingWizardPage.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2024 Lablicate GmbH. + * + * 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: + * Lorenz Gerber - initial API and implementation + *******************************************************************************/ +package org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.wizards; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.chemclipse.model.statistics.ISample; +import org.eclipse.chemclipse.model.statistics.IVariable; +import org.eclipse.chemclipse.xxd.process.supplier.pca.model.ISamplesPCA; +import org.eclipse.chemclipse.xxd.process.supplier.pca.model.Sample; +import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.swt.SampleGroupAssignerListUI; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; + +public class GroupNamingWizardPage extends AbstractAnalysisWizardPage { + + private AtomicReference sampleGroupAssignerListControl = new AtomicReference<>(); + private ISamplesPCA samples; + private AtomicReference groupName = new AtomicReference(); + + public GroupNamingWizardPage(ISamplesPCA samples) { + + super(GroupNamingWizardPage.class.getName()); + setTitle("Group Naming Tool"); + setDescription("Tool for quickly naming/creating/assigning Groups"); + this.samples = samples; + } + + @Override + public void createControl(Composite parent) { + + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(1, true)); + createToolbar(composite); + createSampleGroupAssignerListUI(composite); + setControl(parent); + } + + private void createSampleGroupAssignerListUI(Composite composite) { + + SampleGroupAssignerListUI sampleGroupAssignerListUI = new SampleGroupAssignerListUI(composite, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION); + Table table = sampleGroupAssignerListUI.getTable(); + table.setLayoutData(new GridData(GridData.FILL_BOTH)); + sampleGroupAssignerListControl.set(sampleGroupAssignerListUI); + sampleGroupAssignerListUI.updateInput(extractSamples(samples.getSamples())); + } + + private List extractSamples(List samples) { + + List groupNamingSamples = new ArrayList(); + for(ISample sample : samples) { + ISample groupNamingSample = new Sample(sample.getSampleName(), sample.getGroupName()); + groupNamingSample.setSelected(false); + groupNamingSamples.add(groupNamingSample); + } + return groupNamingSamples; + } + + private void createToolbar(Composite parent) { + + Composite composite = new Composite(parent, SWT.NONE); + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.horizontalAlignment = SWT.BEGINNING; + composite.setLayoutData(gridData); + composite.setLayout(new GridLayout(5, false)); + // + createButtonAssign(composite); + createLabel(composite, "Group Name:"); + createGroupNameEntry(composite); + createButtonZeroSelection(composite); + createButtonInverseSelection(composite); + } + + private Label createLabel(Composite parent, String text) { + + Label label = new Label(parent, SWT.NONE); + label.setText(text); + return label; + } + + private Button createButtonAssign(Composite parent) { + + Button button = new Button(parent, SWT.PUSH); + button.setToolTipText("Assign Groups to selected Samples."); + button.setText("Assign Groups"); + button.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + + sampleGroupAssignerListControl.get().assignGroups(groupName.get().getText()); + } + }); + // + return button; + } + + private void createGroupNameEntry(Composite parent) { + + Text text = new Text(parent, SWT.NONE); + text.setToolTipText("Enter Groupname to be assigned to Samples"); + GridData gridData = new GridData(); + gridData.widthHint = 150; + text.setLayoutData(gridData); + groupName.set(text); + } + + private Button createButtonZeroSelection(Composite parent) { + + Button button = new Button(parent, SWT.PUSH); + button.setToolTipText("Unselect all."); + button.setText("Unselect"); + button.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + + @SuppressWarnings("unchecked") + List groupNamingSamples = (List)sampleGroupAssignerListControl.get().getInput(); + for(ISample sample : groupNamingSamples) { + sample.setSelected(false); + } + sampleGroupAssignerListControl.get().updateInput(groupNamingSamples); + } + }); + // + return button; + } + + private Button createButtonInverseSelection(Composite parent) { + + Button button = new Button(parent, SWT.PUSH); + button.setToolTipText("Inverse Select Samples."); + button.setText("Inverse"); + button.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + + @SuppressWarnings("unchecked") + List groupNamingSamples = (List)sampleGroupAssignerListControl.get().getInput(); + for(ISample sample : groupNamingSamples) { + if(sample.isSelected()) { + sample.setSelected(false); + } else { + sample.setSelected(true); + } + } + sampleGroupAssignerListControl.get().updateInput(groupNamingSamples); + } + }); + // + return button; + } + + @SuppressWarnings("unchecked") + public List getGroupSamples() { + + return (List)sampleGroupAssignerListControl.get().getInput(); + } +} diff --git a/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/swt/AnalysisEditorUI.java b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/swt/AnalysisEditorUI.java index 0b50c66a13..e04c2c26e2 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/swt/AnalysisEditorUI.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/swt/AnalysisEditorUI.java @@ -8,7 +8,7 @@ * * Contributors: * Philip Wenig - initial API and implementation - * Lorenz Gerber - Opls Target selection + * Lorenz Gerber - Opls Target selection, Group assigner *******************************************************************************/ package org.eclipse.chemclipse.xxd.process.supplier.pca.ui.swt; @@ -50,6 +50,8 @@ import org.eclipse.chemclipse.xxd.process.supplier.pca.preferences.PreferenceSupplier; import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.Activator; import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.runnable.CalculationExecutor; +import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.wizards.BatchProcessWizardDialog; +import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.wizards.GroupNamingWizard; import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.preferences.PreferencePage; import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.preferences.PreferencePageLoadingPlot; import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.preferences.PreferencePageScorePlot; @@ -60,6 +62,8 @@ import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.IWizard; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; @@ -96,6 +100,9 @@ public class AnalysisEditorUI extends Composite implements IExtendedPartUI { // private Composite control; private ArrayList oplsGroupTargets; + // + public static final int DEFAULT_WIDTH = 500; + public static final int DEFAULT_HEIGHT = 600; public AnalysisEditorUI(Composite parent, int style) { @@ -301,6 +308,21 @@ public void performSearch(String searchText, boolean caseSensitive) { toolbarSearch.set(searchSupportUI); } + private void createNamingWizard(Composite parent) { + + IWizard wizard = new GroupNamingWizard(samples); + BatchProcessWizardDialog wizardDialog = new BatchProcessWizardDialog(control.getShell(), wizard); + wizardDialog.setMinimumPageSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); + // + try { + if(wizardDialog.open() == Window.OK) { + updateSampleList(); + } + } finally { + wizard.dispose(); + } + } + private TabFolder createDataTab(Composite parent) { TabFolder tabFolder = new TabFolder(parent, SWT.BOTTOM); @@ -334,9 +356,10 @@ private void createToolbarSamples(Composite parent) { GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.horizontalAlignment = SWT.END; composite.setLayoutData(gridData); - composite.setLayout(new GridLayout(6, false)); + composite.setLayout(new GridLayout(7, false)); // createButtonToggleToolbar(composite); + createButtonNamingWizard(composite); createComboViewerOplsTarget(composite); createComboViewerLabelOption(composite); createButtonColorScheme(composite); @@ -444,6 +467,25 @@ public void widgetSelected(SelectionEvent e) { comboViewerOplsTarget.set(comboViewer); } + private Button createButtonNamingWizard(Composite parent) { + + Button button = new Button(parent, SWT.PUSH); + button.setText(""); + button.setToolTipText("Group Naming Wizard."); + button.setImage(ApplicationImageFactory.getInstance().getImage(IApplicationImage.IMAGE_EDIT, IApplicationImageProvider.SIZE_16x16)); + button.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + + createNamingWizard(parent); + // applyColorScheme(e.display); + } + }); + // + return button; + } + private Button createButtonColorScheme(Composite parent) { Button button = new Button(parent, SWT.PUSH); diff --git a/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/swt/SampleGroupAssignerListUI.java b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/swt/SampleGroupAssignerListUI.java new file mode 100644 index 0000000000..6f277a0f73 --- /dev/null +++ b/chemclipse/plugins/org.eclipse.chemclipse.xxd.process.supplier.pca.ui/src/org/eclipse/chemclipse/xxd/process/supplier/pca/ui/swt/SampleGroupAssignerListUI.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2024 Lablicate GmbH. + * + * 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: + * Lorenz Gerber - initial API and implementation + *******************************************************************************/ +package org.eclipse.chemclipse.xxd.process.supplier.pca.ui.swt; + +import java.util.List; + +import org.eclipse.chemclipse.model.statistics.ISample; +import org.eclipse.chemclipse.support.ui.provider.ListContentProvider; +import org.eclipse.chemclipse.support.ui.swt.ExtendedTableViewer; +import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.provider.GroupNamingEditingSupport; +import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.provider.SampleGroupAssignerLabelProvider; +import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.provider.SamplesComparator; +import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.provider.SamplesLabelProvider; +import org.eclipse.chemclipse.xxd.process.supplier.pca.ui.internal.provider.SamplesListFilter; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.widgets.Composite; + +public class SampleGroupAssignerListUI extends ExtendedTableViewer { + + private static final String[] TITLES = SampleGroupAssignerLabelProvider.TITLES; + private static final int[] BOUNDS = SampleGroupAssignerLabelProvider.BOUNDS; + // + private final ITableLabelProvider labelProvider = new SampleGroupAssignerLabelProvider(); + private final ViewerComparator comparator = new SamplesComparator(); + private final SamplesListFilter listFilter = new SamplesListFilter(); + + public SampleGroupAssignerListUI(Composite parent, int style) { + + super(parent, style); + createColumns(); + } + + public void updateInput(List sampleList) { + + super.setInput(sampleList); + } + + private void createColumns() { + + createColumns(TITLES, BOUNDS); + setLabelProvider(labelProvider); + setContentProvider(new ListContentProvider()); + setComparator(comparator); + setFilters(listFilter); + setEditingSupport(); + } + + private void setEditingSupport() { + + List tableViewerColumns = getTableViewerColumns(); + for(int i = 0; i < tableViewerColumns.size(); i++) { + TableViewerColumn tableViewerColumn = tableViewerColumns.get(i); + String label = tableViewerColumn.getColumn().getText(); + if(isEditable(label)) { + tableViewerColumn.setEditingSupport(new GroupNamingEditingSupport(this, label)); + } + } + } + + private boolean isEditable(String label) { + + return !SamplesLabelProvider.SAMPLE_NAME.equals(label); + } + + public void assignGroups(String groupName) { + + @SuppressWarnings("unchecked") + List groupNamingSamples = (List)this.getInput(); + for(ISample sample : groupNamingSamples) { + if(sample.isSelected()) { + sample.setGroupName(groupName); + } + } + this.updateInput(groupNamingSamples); + } +}