package org.netxilia.server.js.editors;
import static org.stjs.javascript.Global.$map;
import static org.stjs.javascript.Global.eval;
import org.netxilia.server.js.Bounds2;
import org.netxilia.server.js.Cell;
import org.netxilia.server.js.CellRange;
import org.netxilia.server.js.Sheet;
import org.netxilia.server.jslib.NetxiliaJQuery;
import org.stjs.javascript.Map;
import org.stjs.javascript.functions.Callback1;
import org.stjs.javascript.jquery.Position;
/**
* this is used to cache formatter instances. usually there is one per sheet. in a context there is only, one active (in
* edit mode) formatter at any given moment
*/
public class EditingContext {
public Editor editor;
public boolean editorVisible = false;
public Map<String, NetxiliaJQuery> elements;
public boolean defaultEditor = true;
public Callback1<String> valueChanged;
private final Sheet sheet;
public NetxiliaJQuery container;
private Cell editedCell;
private Bounds2 editorPosition;
public EditingContext(Sheet sheet) {
this.editorVisible = false;
this.elements = $map();
this.defaultEditor = true;
this.sheet = sheet;
this.container = sheet.table.parent();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public Editor buildEditor(String editorInfo) {
// do caching
if (editorInfo == null || editorInfo.length() == 0 || editorInfo == "null") {
return new TextEditor(this, (Map) $map());
}
Map<String, Object> params = null;
String id = editorInfo;
if (editorInfo.charAt(0) == '{') {
params = eval("(" + editorInfo + ")");
id = (String) params.$get("id");
}
if ("text".equals(id)) {
return new TextEditor(this, params);
}
if ("date".equals(id)) {
return new DateEditor(this, params);
}
if ("select".equals(id)) {
return new SelectEditor(this, params);
}
// TODO should have a registry instead
return null;
}
public void edit(Cell cell, String useEditorInfo, String value) {
this.editor = this.buildEditor(useEditorInfo != null ? useEditorInfo : cell.editorInfo());
Position pos = cell.$td.offset();
Position containerPos = this.container.offset();
containerPos.top -= this.container.scrollTop();
containerPos.left -= this.container.scrollLeft();
pos.top -= containerPos.top;
pos.left -= containerPos.left;
int w = cell.$td.width(), h = cell.$td.height();
this.editedCell = cell;
this.editorPosition = new Bounds2(pos.left, pos.top, w, h);
this.editor.edit(cell, this.editorPosition, value);
this.editor.show(true);
this.defaultEditor = false;
}
public void cancelEdit() {
this.editor.edit(this.editedCell, editorPosition, editedCell.getValue());
}
public void hide() {
if (this.editor == null) {
return;
}
this.editor.show(false);
this.editorVisible = false;
this.editor = null;
this.defaultEditor = true;
this.sheet.focusSelectionContent();
}
public void showDefaultEditor(Cell cell, String text) {
this.edit(cell, "text", text);
this.defaultEditor = true;
}
public boolean hasValueChanged() {
return this.editor != null && this.editor.value() != this.editedCell.getValue();
}
public String value() {
return this.editor != null ? this.editor.value() : null;
}
public void setCaptureSelection(CellRange captureSelection) {
if (this.editor != null) {
this.editor.setCaptureSelection(captureSelection);
}
}
};