package com.akjava.gwt.lib.client.datalist; import java.util.List; import java.util.Stack; import javax.annotation.Nullable; import com.akjava.gwt.lib.client.LogUtils; import com.akjava.gwt.lib.client.StorageDataList; import com.akjava.gwt.lib.client.datalist.command.AddCommand; import com.akjava.gwt.lib.client.datalist.command.RemoveCommand; import com.akjava.gwt.lib.client.datalist.command.RenameCommand; import com.akjava.gwt.lib.client.experimental.undo.SimpleUndoControler; import com.google.common.base.Optional; import com.google.gwt.event.logical.shared.HasValueChangeHandlers; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.EventBus; import com.google.gwt.event.shared.GwtEvent; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.user.client.Window; public abstract class ItemIOControler implements HasValueChangeHandlers<SimpleTextData>{ private StorageDataList dataList; protected SimpleUndoControler undoControler; public SimpleUndoControler getUndoControler() { return undoControler; } public void setUndoControler(@Nullable SimpleUndoControler undoControler) { this.undoControler = undoControler; } public void setDataList(StorageDataList dataList) { this.dataList = dataList; } public StorageDataList getDataList() { return dataList; } private boolean modified; protected int selectedId=-1; private SimpleTextData lastSaved; public SimpleTextData getLastSaved() { return lastSaved; } /* * this save not effect current data list */ public boolean save(){ if(selectedId==-1){ return saveAs(); }else{ SimpleTextData hv=createSaveData(getCurrentName()); lastSaved=dataList.getDataValue(selectedId);//for backup //store cdate+data String storedData=hv.getCdate()+","+hv.getData(); dataList.updateData(selectedId, hv.getName(), storedData); //validate SimpleTextData storedHV=dataList.getDataValue(selectedId); if(!(storedHV.getCdate()+","+storedHV.getData()).equals(storedData)){ Window.alert("faild to save:expected ="+storedData+" but stored="+storedHV.getData()); throw new RuntimeException("faild to save"); } ValueChangeEvent.fire(this, hv); return true; } } public boolean saveAs(){ String saveName=Window.prompt("name", getCurrentName()); if(saveName==null){ return false; } SimpleTextData hv=createSaveData(saveName); String storedData=hv.getCdate()+","+hv.getData(); int selection=dataList.addData(hv.getName(), storedData); selectedId=selection; //validate SimpleTextData storedHV=dataList.getDataValue(selectedId); if(!(storedHV.getCdate()+","+storedHV.getData()).equals(storedData)){ Window.alert("faild to save"); throw new RuntimeException("faild to save"); } updateList(); ValueChangeEvent.fire(this, hv); return true; } public void rename(String newName){ execRename(newName,true); } public void execRename(String newName,boolean needUndo){ SimpleTextData current=dataList.getDataValue(selectedId); if(current==null){ LogUtils.log("execRename:current selection is null.can't rename it"); return; } //if(current) String oldName=current.getName()!=null?current.getName():""; //i have no idea why create new data.there already exist current data. SimpleTextData hv=createSaveData(newName); dataList.updateData(selectedId, hv.getName(), hv.getCdate()+","+hv.getData()); setCurrentName(newName);//doit for avoid reload updateList(); ValueChangeEvent.fire(this, hv); if(needUndo){ undoControler.execute(new RenameCommand(this, oldName,newName)); } } public String rename(){ String saveName=Window.prompt("name", getCurrentName()); if(saveName==null){ return null; } execRename(saveName,true); return saveName; } public boolean delete(){ boolean confirm=Window.confirm("Delete "+getCurrentName()+"?"); if(!confirm){ return false; } return execDelete(selectedId,true); } public boolean execDelete(int id,boolean needUndo){ lastSaved=dataList.getDataValue(id);// dataList.clearData(id); selectedId=-1; unselect(); ValueChangeEvent.fire(this, null); if(undoControler!=null){ undoControler.execute(new RemoveCommand(this, lastSaved)); } return true; } private Stack<Integer> backs=new Stack<Integer>(); private Stack<Integer> fowards=new Stack<Integer>(); /* * be careful this selection don't change cell selection. */ public void load(int id){ selectedId=id; //TODO confirm if(id!=-1){ SimpleTextData hv=dataList.getDataValue(id); if(hv==null){ loadData(Optional.<SimpleTextData>absent()); }else{ loadData(Optional.of(hv)); } } if(id!=-1 && (backs.size()==0 || backs.peek()!=id)){ backs.push(id); } } /** * * @param name */ public abstract void setCurrentName(String name); public abstract String getCurrentName(); public abstract SimpleTextData createSaveData(String fileName); public abstract SimpleTextData createNewData(String fileName); /** * Optional.absense means notselected;clear selection * @param hv */ public abstract void loadData(Optional<SimpleTextData> hv); public abstract void exportDatas(List<SimpleTextData> list); public abstract void updateList(); public abstract void importData(); public abstract void clearAll(); public abstract void copy(Object object); public abstract void paste(); public abstract void recoverLastSaved(SimpleTextData hv); private String controlerName; public String getControlerName() { return controlerName; } public void setControlerName(String controlerName) { this.controlerName = controlerName; } public void exportAll() { List<SimpleTextData> list=dataList.getDataList(); exportDatas(list); } public abstract void restore(); public void unselect() { selectedId=-1; updateList(); loadData(Optional.<SimpleTextData>absent()); } public SimpleTextData doNew(){ return doNew("Undefined"); } public SimpleTextData doNew(String defaultName){ String saveName=Window.prompt("name", defaultName); if(saveName==null){ return null; } SimpleTextData hv=createNewData(saveName); execAdd(hv,true); return hv; } public int execAdd(SimpleTextData data,boolean needUndo){ int selection=dataList.addData(data.getName(), data.getCdate()+","+data.getData()); selectedId=selection; data.setId(selection); updateList(); ValueChangeEvent.fire(this, data); if(undoControler!=null){ undoControler.execute(new AddCommand(this, data)); } return selection; } //not only update,but also insert (called from undo) public void execUpdate(SimpleTextData data,boolean needUndo){ dataList.updateData(data.getId(),data.getName(), data.getCdate()+","+data.getData()); selectedId=data.getId(); updateList(); ValueChangeEvent.fire(this, data); } public void back() { if(backs.size()>1){ backs.pop();//remove current } final int id=backs.peek(); selectedId=id;//change select updateList(); /* Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { SimpleTextData hv=dataList.getDataValue(id); load(id); } }); */ } EventBus bus = new SimpleEventBus(); @Override public void fireEvent(GwtEvent<?> event) { bus.fireEvent(event); } @Override public HandlerRegistration addValueChangeHandler( ValueChangeHandler<SimpleTextData> handler) { return bus.addHandler(ValueChangeEvent.getType(), handler); } public abstract void doDoubleClick(int clientX, int clientY) ; }