package com.akjava.gwt.lib.client.datalist; import java.io.IOException; import java.util.Date; import java.util.List; import com.akjava.gwt.html5.client.download.HTML5Download; import com.akjava.gwt.html5.client.file.File; import com.akjava.gwt.html5.client.file.FileUploadForm; import com.akjava.gwt.html5.client.file.FileUtils; import com.akjava.gwt.html5.client.file.FileUtils.DataURLListener; import com.akjava.gwt.lib.client.LogUtils; import com.akjava.gwt.lib.client.StorageDataList; import com.akjava.gwt.lib.client.datalist.functions.CsvArrayToHeadAndValueFunction; import com.akjava.gwt.lib.client.datalist.functions.HeadAndValueToCsvFunction; import com.akjava.gwt.lib.client.widget.TabInputableTextArea; import com.akjava.lib.common.csv.CSVReader; import com.google.common.base.Joiner; import com.google.common.base.Optional; import com.google.common.collect.FluentIterable; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.MenuBar; import com.google.gwt.user.client.ui.TextArea; /** * * how to use * * * * @author aki * */ public class TextAreaBasedDataList extends SimpleDataListItemControler{ private TextArea textArea; private SimpleTextData copiedValue; private HorizontalPanel uploadPanel; private FileUploadForm uploadForm; public static interface TextAreaBasedDataListListener{ public void onLoad(Optional<SimpleTextData> hv); } /** * if you need call addkeyUpHandler() for update modified * @param textArea */ public void setTextArea(TextArea textArea) { this.textArea = textArea; } public TextArea getTextArea() { return textArea; } private void textModified(){ getSimpleDataListWidget().setModified(true);//simple modified } public TextAreaBasedDataList(StorageDataList dataList) { this(dataList,null); } public TextAreaBasedDataList(StorageDataList dataList,SimpleTextData defaultOnEmptyData) { super(dataList); this.defaultOnEmptyData=defaultOnEmptyData; textArea=new TabInputableTextArea(); addKeyHandler(textArea); getSimpleDataListWidget().setCellContextMenu(new TestContextMenu()); unselect(); if(getDataList().getDataList().isEmpty()){ for(SimpleTextData data:getDefaultOnEmptyData().asSet()){ for(Integer id:add(data).asSet()){ select(id); } } } } private SimpleTextData defaultOnEmptyData; private Optional<SimpleTextData> getDefaultOnEmptyData(){ return Optional.fromNullable(defaultOnEmptyData); } private boolean saved; public void addKeyHandler(TextArea text){ text.addKeyDownHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { if(event.isControlKeyDown()){ if(event.getNativeKeyCode()==83){//ignore save event.preventDefault(); saved=true; return; } } saved=false; } }) ; text.addKeyUpHandler(new KeyUpHandler() { @Override public void onKeyUp(KeyUpEvent event) { if(saved){//ignore save key return; } //ignore single ctrl,this happen after save if(event.getNativeKeyCode()==KeyCodes.KEY_CTRL){ return; } //LogUtils.log("key-up:"+event.getNativeKeyCode()); if(event.getNativeKeyCode()==KeyCodes.KEY_ENTER){ textModified(); } else if(event.isControlKeyDown()){ if(event.getNativeKeyCode()==83){//S(save) event.preventDefault(); return; } if(event.getNativeKeyCode()!=65 && event.getNativeKeyCode()!=67){//ignore A(select all) && C(copy) textModified(); } } else{ textModified(); } } }); } /** * This context menu is very primitive,so can't modified after create.used globally * TODO * @author aki * */ public class TestContextMenu extends AbstractContextMenu{ @Override public void createMenus(MenuBar menuBar) { Command test1Command = new Command() { public void execute() { SimpleTextData data=getSimpleDataListWidget().getSelection().getData(); String currentDate=getSimpleDataListWidget().dateFormat.format(new Date(data.getCdate())); hide(); String value=Window.prompt("New Date", currentDate); if(value!=null){ Date d=getSimpleDataListWidget().dateFormat.parse(value); data.setCdate(d.getTime()); getSimpleDataListWidget().save();//it's work? getSimpleDataListWidget().redraw(); } } }; menuBar.addItem("Modify create date", test1Command); } } @Override public SimpleTextData createSaveData(String fileName) { String text=textArea.getText(); SimpleTextData current=getSimpleDataListWidget().getSelection().getData(); if(current==null){ return new SimpleTextData(-1,fileName,text); }else{ return new SimpleTextData(-1,fileName,text,current.getCdate()); //copy cdate } } @Override public SimpleTextData createNewData(String fileName) { String text=""; return new SimpleTextData(-1,fileName,text); } protected String unselectedText="CREATE NEW or SELECT"; private TextAreaBasedDataListListener textAreaBasedDataListListener; public TextAreaBasedDataListListener getTextAreaBasedDataListListener() { return textAreaBasedDataListListener; } public void setTextAreaBasedDataListListener( TextAreaBasedDataListListener textAreaBasedDataListListener) { this.textAreaBasedDataListListener = textAreaBasedDataListListener; } @Override public void loadData(Optional<SimpleTextData> hv) { if(hv.isPresent()){ textArea.setReadOnly(false); textArea.setText(hv.get().getData()); }else{//unselected and clear textArea.setReadOnly(true); textArea.setText(unselectedText); } if(textAreaBasedDataListListener!=null){ textAreaBasedDataListListener.onLoad(hv); } onLoad(); } public void onLoad(){} /** * used for export file name * @return */ protected String getKeyName(){ return "datas"; } @Override public void exportDatas(List<SimpleTextData> list) { String exportText=generateExportText(list); Anchor anchor=new HTML5Download().generateTextDownloadLink(exportText,getKeyName()+".csv","Download data",true); getSimpleDataListWidget().add(anchor); } private String generateExportText(List<SimpleTextData> list){ List<String> lines=FluentIterable.from(list).transform(new HeadAndValueToCsvFunction()).toList(); String exportText=Joiner.on("\r\n").join(lines); return exportText; } public String generateExportText(){ List<SimpleTextData> list=this.getDataList().getDataList(); return generateExportText(list); } @Override public void importData() { if(getDataList().getDataList().size()>0){ boolean confirm=Window.confirm("Import datas:add current datas with ignoring id,if you keep id use restore and replace all data."); if(!confirm){ return; } } uploadForm = FileUtils.createSingleTextFileUploadForm(new DataURLListener() { @Override public void uploaded(File file, String value) { List<SimpleTextData> list=textToSimpleTextData(value); for(SimpleTextData hv:list){ getDataList().addData(hv.getName(), hv.getData()); } uploadPanel.removeFromParent(); updateList(); } }, false); createFormPanel("Import Datas:",uploadForm); getSimpleDataListWidget().add(uploadPanel); } @Override public void clearAll() { boolean confirm=Window.confirm("Clear all data?this operation can not undo\nyou should ExportAll first."); if(!confirm){ return; } List<SimpleTextData> hvs= getDataList().getDataList(); for(SimpleTextData hv:hvs){ getDataList().clearData(hv.getId()); } getDataList().setCurrentId(0);//restart id getSimpleDataListWidget().unselect(); updateList(); } public Optional<Integer> add(SimpleTextData data) { if(data!=null){ int id=getDataList().addData(data.getName(), data.getCdate()+","+data.getData()); updateList(); return Optional.of(id); } return Optional.absent(); } @Override public void copy(Object object) { copiedValue=(SimpleTextData) object; } @Override public void paste() { if(copiedValue!=null){ SimpleTextData copy=copiedValue.copy(); copy.setName(copy.getName()+" copy"); execAdd(copy,true); //modified //getDataList().addData(copiedValue.getName()+" copy", copiedValue.getData()); //updateList(); } } @Override public void recoverLastSaved(SimpleTextData hv) { copy(hv); paste(); } /** * restore keep id */ @Override public void restore() { if(getDataList().getDataList().size()>0){ boolean confirm=Window.confirm("Restore datas:clear current datas and restore csv datas."); if(!confirm){ return; } } uploadForm = FileUtils.createSingleTextFileUploadForm(new DataURLListener() { @Override public void uploaded(File file, String value) { execRestore(value); } }, false); createFormPanel("Restore layers:",uploadForm); getSimpleDataListWidget().add(uploadPanel); } public void execRestore(String value){ //clear first List<SimpleTextData> hvs= getDataList().getDataList(); for(SimpleTextData hv:hvs){ getDataList().clearData(hv.getId()); } //getDataList().setCurrentId(0); int max=0; List<SimpleTextData> list=textToSimpleTextData(value); //do offset //LogUtils.log("force offset"); //doOffset(parts.getKey(),list); GWT.log("upload-size:"+list.size()); for(SimpleTextData hv:list){ if(hv.getId()>max){ max=hv.getId(); } getDataList().updateData(hv.getId(),hv.getName(), hv.getData()); } getDataList().setCurrentId(max+1); if(uploadPanel!=null){ uploadPanel.removeFromParent(); } updateList(); } public void execRestore(List<SimpleTextData> list){ //clear first List<SimpleTextData> hvs= getDataList().getDataList(); for(SimpleTextData hv:hvs){ getDataList().clearData(hv.getId()); } //getDataList().setCurrentId(0); int maxId=0; //do offset //LogUtils.log("force offset"); //doOffset(parts.getKey(),list); //LogUtils.log("upload-size:"+list.size()); for(SimpleTextData hv:list){ if(hv.getId()>maxId){ maxId=hv.getId(); } //LogUtils.log("update:"+hv.getId()); getDataList().updateData(hv.getId(),hv.getName(), hv.getData()); } getDataList().setCurrentId(maxId+1); //LogUtils.log("current-id:"+getDataList().getCurrentId()); if(uploadPanel!=null){ uploadPanel.removeFromParent(); } selectedId=-1; updateList(); } @Override public void doDoubleClick(int clientX, int clientY) { LogUtils.log("double-click:"+clientX+","+clientY); } private void createFormPanel(String text,FileUploadForm form){ if(uploadPanel==null){ uploadPanel=new HorizontalPanel(); uploadPanel.add(new Label(text)); uploadPanel.add(form); Button bt=new Button("close",new ClickHandler() { @Override public void onClick(ClickEvent event) { uploadPanel.setVisible(false); } }); uploadPanel.add(bt); }else{ uploadPanel.setVisible(true); } } //TODO move somewhere public static List<SimpleTextData> textToSimpleTextData(String text){ //List<SimpleTextData> list=new ArrayList<SimpleTextData>(); CSVReader reader=new CSVReader(text,'\t','"',true); try { List<String[]> csvs=reader.readAll(); return FluentIterable.from(csvs).transform(new CsvArrayToHeadAndValueFunction()).toList(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); Window.alert(e.getMessage()); } return null; } }