package ch.elexis.core.ui.views.controls;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.FocusCellHighlighter;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ICheckStateProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.data.service.StockService;
import ch.elexis.core.lock.types.LockResponse;
import ch.elexis.core.model.IStock;
import ch.elexis.core.model.IStockEntry;
import ch.elexis.core.ui.editors.KontaktSelektorDialogCellEditor;
import ch.elexis.data.Artikel;
import ch.elexis.data.Kontakt;
import ch.elexis.data.Stock;
import ch.elexis.data.StockEntry;
public class StockDetailComposite extends Composite {
private WritableValue wvArtikel = new WritableValue(null, Artikel.class);
private Logger log = LoggerFactory.getLogger(StockDetailComposite.class);
private Table table;
private Map<Stock, IStockEntry> stockEntries = new HashMap<Stock, IStockEntry>();
private CheckboxTableViewer checkboxTableViewer;
private StockService stockService = CoreHub.getStockService();
/**
* Create the composite.
*
* @param parent
* @param style
*/
public StockDetailComposite(Composite parent, int style){
super(parent, style);
setLayout(new FillLayout(SWT.HORIZONTAL));
Composite composite = new Composite(this, SWT.NONE);
TableColumnLayout tcl_composite = new TableColumnLayout();
composite.setLayout(tcl_composite);
checkboxTableViewer =
CheckboxTableViewer.newCheckList(composite, SWT.BORDER | SWT.FULL_SELECTION);
checkboxTableViewer.setContentProvider(ArrayContentProvider.getInstance());
table = checkboxTableViewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setEnabled(false);
TableViewerColumn tableViewerColumn = new TableViewerColumn(checkboxTableViewer, SWT.NONE);
tableViewerColumn.setLabelProvider(new ColumnLabelProvider() {
public Image getImage(Object element){
return null;
}
public String getText(Object element){
Stock stock = (Stock) element;
if (stock == null) {
return null;
}
return stock.getCode();
}
});
TableColumn tblclmnStock = tableViewerColumn.getColumn();
tblclmnStock.setResizable(true);
tblclmnStock.setAlignment(SWT.CENTER);
tcl_composite.setColumnData(tblclmnStock, new ColumnPixelData(100, false, false));
tblclmnStock.setText("Verfügbar in Lager");
TableViewerColumn tvcMin = new TableViewerColumn(checkboxTableViewer, SWT.NONE);
StockEntryEditingSupport sees =
new StockEntryEditingSupport(checkboxTableViewer, StockEntryEditingSupport.MIN);
tvcMin.setEditingSupport(sees);
tvcMin.setLabelProvider(new ColumnLabelProvider() {
public Image getImage(Object element){
// TODO Auto-generated method stub
return null;
}
public String getText(Object element){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return null;
}
IStockEntry se = stockEntries.get(stock);
if (se != null) {
return Integer.toString(se.getMinimumStock());
}
return null;
}
});
TableColumn tblclmnMin = tvcMin.getColumn();
tblclmnMin.setResizable(true);
tblclmnMin.setAlignment(SWT.CENTER);
tcl_composite.setColumnData(tblclmnMin, new ColumnPixelData(30, false, true));
tblclmnMin.setText("Min");
TableViewerColumn tvcIst = new TableViewerColumn(checkboxTableViewer, SWT.NONE);
StockEntryEditingSupport seesIst =
new StockEntryEditingSupport(checkboxTableViewer, StockEntryEditingSupport.CURR);
tvcIst.setEditingSupport(seesIst);
tvcIst.setLabelProvider(new ColumnLabelProvider() {
public Image getImage(Object element){
return null;
}
public String getText(Object element){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return null;
}
IStockEntry se = stockEntries.get(stock);
if (se != null) {
return Integer.toString(se.getCurrentStock());
}
return null;
}
});
TableColumn tblclmnNewColumn = tvcIst.getColumn();
tblclmnNewColumn.setResizable(true);
tcl_composite.setColumnData(tblclmnNewColumn, new ColumnPixelData(30, false, true));
tblclmnNewColumn.setText("Ist");
TableViewerColumn tvcMax = new TableViewerColumn(checkboxTableViewer, SWT.NONE);
StockEntryEditingSupport seesMax =
new StockEntryEditingSupport(checkboxTableViewer, StockEntryEditingSupport.MAX);
tvcMax.setEditingSupport(seesMax);
tvcMax.setLabelProvider(new ColumnLabelProvider() {
public Image getImage(Object element){
return null;
}
public String getText(Object element){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return null;
}
IStockEntry se = stockEntries.get(stock);
if (se != null) {
return Integer.toString(se.getMaximumStock());
}
return null;
}
});
TableColumn tblclmnMax = tvcMax.getColumn();
tblclmnMax.setResizable(true);
tcl_composite.setColumnData(tblclmnMax, new ColumnPixelData(30, true, true));
tblclmnMax.setText("Max");
TableViewerColumn tvcFraction = new TableViewerColumn(checkboxTableViewer, SWT.NONE);
StockEntryEditingSupport seesFrac =
new StockEntryEditingSupport(checkboxTableViewer, StockEntryEditingSupport.FRAC);
tvcFraction.setEditingSupport(seesFrac);
tvcFraction.setLabelProvider(new ColumnLabelProvider() {
public Image getImage(Object element){
return null;
}
public String getText(Object element){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return null;
}
IStockEntry se = stockEntries.get(stock);
if (se != null) {
return Integer.toString(se.getFractionUnits());
}
return null;
}
});
TableColumn tblclmnFraction = tvcFraction.getColumn();
tblclmnFraction.setResizable(true);
tcl_composite.setColumnData(tblclmnFraction, new ColumnPixelData(30, false, true));
tblclmnFraction.setText("Anbruch");
TableViewerColumn tvcProvider = new TableViewerColumn(checkboxTableViewer, SWT.NONE);
tvcProvider.setEditingSupport(new EditingSupport(checkboxTableViewer) {
@Override
protected void setValue(Object element, Object value){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return;
}
IStockEntry se = stockEntries.get(stock);
if (se == null) {
return;
}
se.setProvider((Kontakt) value);
getViewer().refresh();
}
@Override
protected Object getValue(Object element){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return null;
}
IStockEntry se = stockEntries.get(stock);
if (se == null) {
return null;
}
return (Kontakt) se.getProvider();
}
@Override
protected CellEditor getCellEditor(Object element){
return new KontaktSelektorDialogCellEditor(
((CheckboxTableViewer) getViewer()).getTable(), "Lieferant auswählen",
"Bitte selektieren Sie den Lieferant");
}
@Override
protected boolean canEdit(Object element){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return false;
}
return (stockEntries.get(stock) != null);
}
});
tvcProvider.setLabelProvider(new ColumnLabelProvider() {
public Image getImage(Object element){
return null;
}
public String getText(Object element){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return null;
}
IStockEntry se = stockEntries.get(stock);
if (se == null) {
return null;
}
Kontakt provider = (Kontakt) se.getProvider();
if (provider == null) {
return null;
}
return provider.getLabel();
}
});
TableColumn tblclmnProvider = tvcProvider.getColumn();
tcl_composite.setColumnData(tblclmnProvider, new ColumnPixelData(200, true, true));
tblclmnProvider.setText("Lieferant");
checkboxTableViewer.addCheckStateListener(new ICheckStateListener() {
@Override
public void checkStateChanged(CheckStateChangedEvent event){
IStock stock = (Stock) event.getElement();
Artikel art = (Artikel) wvArtikel.getValue();
if (stock != null && art != null && stock.getDriverUuid().length() == 0) {
if (event.getChecked()) {
stockService.storeArticleInStock(stock, art.storeToString());
} else {
stockService.unstoreArticleFromStock(stock, art.storeToString());
}
}
refreshData();
}
});
checkboxTableViewer.setCheckStateProvider(new ICheckStateProvider() {
@Override
public boolean isGrayed(Object element){
return false;
}
@Override
public boolean isChecked(Object element){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return false;
}
return (stockEntries.get(stock) != null);
}
});
List<Stock> stocks = stockService.getAllStocks(true);
for (Stock stock : stocks) {
stockEntries.put(stock, null);
}
checkboxTableViewer.setInput(stocks);
TableViewer ret = new TableViewer(table);
TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(ret, new FocusCellHighlighter(ret) {});
ColumnViewerEditorActivationStrategy editorActivationStrategy = new ColumnViewerEditorActivationStrategy(ret) {
@Override
protected boolean isEditorActivationEvent(
ColumnViewerEditorActivationEvent event) {
ViewerCell cell = (ViewerCell) event.getSource();
return cell.getColumnIndex() > 0 && cell.getColumnIndex() < 5;
}
};
TableViewerEditor.create(ret, focusCellManager, editorActivationStrategy, TableViewerEditor.TABBING_HORIZONTAL);
}
private void refreshData(){
Artikel article = (Artikel) wvArtikel.getValue();
boolean enabled = (article != null && !article.isProduct());
table.setEnabled(enabled);
stockEntries.replaceAll((k, v) -> null);
if (article != null) {
stockEntries.keySet().forEach(k -> {
stockEntries.put(k,
stockService.findStockEntryForArticleInStock(k, article.storeToString()));
});
}
checkboxTableViewer.refresh(true);
}
@Override
protected void checkSubclass(){
// Disable the check that prevents subclassing of SWT components
}
public void setArticle(Artikel article){
wvArtikel.setValue(article);
refreshData();
}
public class StockEntryEditingSupport extends EditingSupport {
public static final int MIN = 0;
public static final int CURR = 1;
public static final int MAX = 2;
public static final int FRAC = 3;
private final int editorFor;
private final CellEditor editor;
public StockEntryEditingSupport(CheckboxTableViewer columnViewer, int editorFor){
super(columnViewer);
this.editorFor = editorFor;
this.editor = new TextCellEditor(columnViewer.getTable());
}
@Override
protected CellEditor getCellEditor(Object element){
return editor;
}
@Override
protected boolean canEdit(Object element){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null || (stockEntries.get(stock) == null)) {
return false;
}
if ((CURR == editorFor || FRAC == editorFor) && stock.getDriverUuid().length() > 0) {
// the current stock and fraction count of a stock commissioning system
// must not be directly changed
return false;
}
return true;
}
@Override
protected Object getValue(Object element){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return "";
}
IStockEntry se = stockEntries.get(stock);
if (se == null) {
return "";
}
int value = 0;
switch (editorFor) {
case MIN:
value = se.getMinimumStock();
break;
case CURR:
value = se.getCurrentStock();
break;
case MAX:
value = se.getMaximumStock();
break;
case FRAC:
value = se.getFractionUnits();
break;
default:
}
return Integer.toString(value);
}
@Override
protected void setValue(Object element, Object value){
Stock stock = (Stock) element;
Artikel art = (Artikel) wvArtikel.getValue();
if (stock == null || art == null) {
return;
}
StockEntry se = (StockEntry) stockEntries.get(stock);
if (se == null) {
return;
}
LockResponse lr = CoreHub.getLocalLockService().acquireLock(se);
if (!lr.isOk()) {
return;
}
int val = 0;
try {
val = Integer.valueOf((String) value);
} catch (NumberFormatException nfe) {}
switch (editorFor) {
case MIN:
se.setMinimumStock(val);
break;
case MAX:
se.setMaximumStock(val);
break;
case CURR:
se.setCurrentStock(val);
break;
case FRAC:
se.setFractionUnits(val);
break;
default:
}
lr = CoreHub.getLocalLockService().releaseLock(se);
if (!lr.isOk()) {
log.warn("Error releasing lock for [{}]: {}", se.getId(), lr.getStatus());
}
getViewer().refresh();
}
}
}