package com.akjava.gwt.lib.client.datalist;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import com.akjava.gwt.lib.client.LogUtils;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
import com.google.gwt.view.client.SingleSelectionModel;
public class SimpleDataList extends VerticalPanel{
//TODO comparable
private static final ProvidesKey<DataListData<SimpleTextData>> KEY_PROVIDER = new ProvidesKey<DataListData<SimpleTextData>>() {
public Object getKey(DataListData<SimpleTextData> item) {
return item.getData().getId();
}
};
private ItemIOControler ioControler;
private CellList<DataListData<SimpleTextData>> cellList;
private SingleSelectionModel<DataListData<SimpleTextData>> selectionModel;
private Handler selectionChangeHandler;
private Button cloneBt;
public Button getCloneBt() {
return cloneBt;
}
public Button getExpandButton() {
return expandButton;
}
public Button getCopyBt() {
return copyBt;
}
public Button getPasteBt() {
return pasteBt;
}
public void setModified(boolean modified) {
if(getSelection()==null){
return;
}
if(getSelection().isModified()!=modified){
getSelection().setModified(modified);
cellList.redraw();
}
}
public List<DataListData<SimpleTextData>> getCellData(){
return dataListDatas;
}
/**
*
* @param io
* @param selection somehow not used yet
*/
public SimpleDataList(ItemIOControler io,int selection){
this.ioControler=io;
buttons1 = new HorizontalPanel();
add(buttons1);
buttons2 = new HorizontalPanel();
add(buttons2);
final HorizontalPanel expandButtons=new HorizontalPanel();
add(expandButtons);
expandButtons.setVisible(false);
saveBt = new Button("Save");
saveBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
save();
}
});
saveBt.setEnabled(false);
buttons1.add(saveBt);
saveAsBt = new Button("SaveAs",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
boolean done=ioControler.saveAs();
if(done){
setModified(false);
}
}
});
buttons1.add(saveAsBt);
saveAsBt.setEnabled(false);
renameBt = new Button("Rename",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
String newName=ioControler.rename();
if(newName!=null){
currentSelection.getData().setName(newName);
cellList.redraw();
}
}
});
buttons1.add(renameBt);
deleteBt = new Button("Delete",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
boolean done=ioControler.delete();
if(done){
currentSelection=null;
setModified(false);
}
}
});
buttons1.add(deleteBt);
copyBt = new Button("Copy",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if(currentSelection==null){
return;
}
//copy before save data.
ioControler.copy(currentSelection.getData());
}
});
buttons1.add(copyBt);
pasteBt = new Button("Paste",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
ioControler.paste();
}
});
buttons1.add(pasteBt);
cloneBt = new Button("Clone",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if(currentSelection==null){
return;
}
ioControler.copy(currentSelection.getData());
ioControler.paste();
}
});
buttons1.add(cloneBt);
cloneBt.setVisible(false);//on default use copy & paste
Button exportAll=new Button("ExportAll",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
ioControler.exportAll();
}
});
expandButtons.add(exportAll);
Button importBt=new Button("Import",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
ioControler.importData();
}
});
expandButtons.add(importBt);
Button restore=new Button("Restore",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
ioControler.restore();
}
});
expandButtons.add(restore);
clearAllBt = new Button("ClearAll",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
ioControler.clearAll();
}
});
expandButtons.add(clearAllBt);
Button recover=new Button("Recover",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
ioControler.recoverLastSaved(ioControler.getLastSaved());
}
});
expandButtons.add(recover);
recover.setTitle("recover last overwrited(saved) data");
Button doNew=new Button("New",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
boolean isContinue=askContinueAction();
if(!isContinue){
return;
}
ioControler.doNew();
}
});
buttons2.add(doNew);
reloadBt = new Button("Reload",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
boolean isContinue=askContinueAction();
if(!isContinue){
return;
}
if(currentSelection!=null){
int index=getSelectedIndex();
ioControler.unselect();
select(index);
}
}
});
buttons2.add(reloadBt);
unselectBt = new Button("Unselect",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
unselect();
}
});
buttons2.add(unselectBt);
expandButton = new Button("Expand>>",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
expandButtons.setVisible(!expandButtons.isVisible());
if(expandButtons.isVisible()){
expandButton.setText("Collapse<<");
}else{
expandButton.setText("Expand>>");
}
}
});
buttons2.add(expandButton);
showDate = new CheckBox("show cdate");
buttons2.add(showDate);
showDate.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
redraw();
}
});
ScrollPanel scroll=new ScrollPanel();
scroll.setHeight("300px");
add(scroll);
cell = new DataListDataCell();
cellList = new CellList<DataListData<SimpleTextData>>(cell,KEY_PROVIDER);
cellList.setStylePrimaryName("table");
scroll.setWidget(cellList);
selectionModel = new SingleSelectionModel<DataListData<SimpleTextData>>(KEY_PROVIDER);
cellList.setSelectionModel(selectionModel);
selectionChangeHandler = new Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
//LogUtils.log("selection change called");
if(ignoreSelectionChange){
//LogUtils.log("ignore by flag");
ignoreSelectionChange=false;
return;
}
boolean isContinue=askContinueAction();
if(!isContinue){
backselect(currentSelection);
//LogUtils.log("backselected");
return;
}
DataListData<SimpleTextData> data=selectionModel.getSelectedObject();
if(data!=null){
//LogUtils.log("select and call load:"+data.getData().getHeader()+","+data.getData().getId());
selectFromSelectionModel(data);
}else{
//LogUtils.log("null-selection-data");
//need for clear selection label
//maybe called selectionModel.clear() in updateList
//LogUtils.log("null selection called: in selectionModel");
//throw new RuntimeException();//need ir or loop & crash
}
}
};
selectionModel.addSelectionChangeHandler(selectionChangeHandler);
HorizontalPanel downButtons=new HorizontalPanel();
downButtons.setVerticalAlignment(ALIGN_MIDDLE);
add(downButtons);
downButtons2 = new HorizontalPanel();
add(downButtons2);
optionButtons3=new VerticalPanel();
add(optionButtons3);
backBt = new Button("Back",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
ioControler.back();
}
});
downButtons.add(backBt);
Button prev=new Button("Prev",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
boolean isContinue=askContinueAction();
if(!isContinue){
return;
}
prev();
}
});
downButtons.add(prev);
Button next=new Button("Next",new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
boolean isContinue=askContinueAction();
if(!isContinue){
return;
}
next();
}
});
downButtons.add(next);
final ListBox orderList=new ListBox();
orderList.addItem("id");
orderList.addItem("id desc");
orderList.addItem("a-z");
orderList.addItem("z-a");
orderList.setSelectedIndex(1);
orderList.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
order=orderList.getSelectedIndex();
ioControler.updateList();
}
});
downButtons.add(orderList);
//cellContextMenu=new TestContextMenu();//for test
update();
}
public Button getClearAllBt() {
return clearAllBt;
}
public Button getBackBt() {
return backBt;
}
//change single line
public void mergeButton1AndButton2(){
buttons1.add(buttons2);
}
//temporaly
public void moveClearAllToButton1(){
buttons1.add(clearAllBt);
}
/*
private class TestContextMenu implements CellContextMenu{
private PopupPanel contextMenu;
private MenuBar menu=new MenuBar(true);
public TestContextMenu(){
this.contextMenu = new PopupPanel(true);
contextMenu.add(menu);
Command testCommand = new Command() {
public void execute() {
Window.alert("hello");
contextMenu.hide();
}
};
menu.addItem(new MenuItem("Top", true, testCommand));
this.contextMenu.hide();
}
@Override
public void onContextMenu(int clientX, int clientY) {
this.contextMenu.setPopupPosition(clientX, clientY);
this.contextMenu.show();
}
}*/
public Button getUnselectBt() {
return unselectBt;
}
public void save() {
//save.setEnabled(false);
saveBt.setText("Saving");
boolean done=false;
try{
done=ioControler.save();
}catch(Exception e){
e.getMessage();
LogUtils.log(e.getMessage());
}
saveBt.setText("Save");
//save.setEnabled(true);
if(done){
setModified(false);
}
}
public void unselect() {
ioControler.unselect();
currentSelection=null;
setModified(false);
setSelectionStatus(false);
}
/**
* this called from direct selection and buttons
* TODO bugs called multiple
* @param selection
*/
public void setSelectionStatus(boolean selection){
//LogUtils.log("selection:"+selection);
saveBt.setEnabled(selection);
saveAsBt.setEnabled(selection);
renameBt.setEnabled(selection);
deleteBt.setEnabled(selection);
copyBt.setEnabled(selection);
reloadBt.setEnabled(selection);
unselectBt.setEnabled(selection);
cloneBt.setEnabled(selection);
}
public Button getReloadBt() {
return reloadBt;
}
public void next(){
int index=getSelectedIndex();
if(index<getItemCount()-1){
index++;
}else{
index=0;
}
select(index);
}
public void prev(){
int index=getSelectedIndex();
if(index>0){
index--;
}else{
index=getItemCount()-1;
}
select(index);
}
private boolean askContinueAction(){
if(currentSelection!=null){
if(currentSelection.isModified()){
boolean confirm=Window.confirm(getConfirmMessage());
if(!confirm){
return false;
}
currentSelection.setModified(false);//aband
}
}
return true;
}
private List<DataListData<SimpleTextData>> dataListDatas=new ArrayList<DataListData<SimpleTextData>>();
private DataListData<SimpleTextData> currentSelection;
public static final int ORDER_ID=0;
public static final int ORDER_ID_DESC=1;
public static final int ORDER_AZ=2;
public static final int ORDER_ZA=3;
private int order=1;
private SimpleTextDataComparator comparator=new SimpleTextDataComparator();
private String getConfirmMessage(){
return "last selection is modified?disband this and select another?";
}
public void update(){
try{
dataListDatas.clear();
List<SimpleTextData> hvs=ioControler.getDataList().getDataList();
comparator.setOrder(order);
Collections.sort(hvs, comparator);
for(SimpleTextData hv:hvs){
dataListDatas.add(new DataListData<SimpleTextData>(hv));
}
selectionModel.clear();
/*
selectionModel=new SingleSelectionModel<DataListData<SimpleTextData>>();
selectionModel.addSelectionChangeHandler(selectionChangeHandler);
cellList.setSelectionModel(selectionModel);
*/
cellList.setRowCount(dataListDatas.size());
cellList.setVisibleRange(0, dataListDatas.size());
cellList.setRowData(0, dataListDatas);
//
//TODO refresh selectionModel?
}catch(Exception e){
LogUtils.log(e.getMessage());
e.printStackTrace();
}
}
public void redraw(){
cellList.redraw();
}
public static class SimpleTextDataComparator implements Comparator<SimpleTextData>{
public SimpleTextDataComparator(int order){
this.order=order;
};
public SimpleTextDataComparator(){
this(ORDER_ID);
}
private int order;
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int compare(SimpleTextData o1, SimpleTextData o2) {
if(order==ORDER_ID_DESC){
return o2.getId()-o1.getId();
}
if(order==ORDER_AZ){
return o1.getName().compareTo(o2.getName());
}
if(order==ORDER_ZA){
return o2.getName().compareTo(o1.getName());
}
//ORDER_ID
return o1.getId()-o2.getId();
}
}
boolean ignoreSelectionChange;
private Button expandButton;
private void backselect(DataListData<SimpleTextData> item){
ignoreSelectionChange=true;
selectionModel.setSelected(item, true);
}
private void selectFromSelectionModel(DataListData<SimpleTextData> item){
//never call selectionModel.setSelected(item, true);
currentSelection=item;
ioControler.load(item.getData().getId());
currentSelection.setModified(false);
cellList.redraw();
setSelectionStatus(true);
}
public DataListData<SimpleTextData> getSelection(){
return currentSelection;
}
public int getItemCount(){
return dataListDatas.size();
}
public int getSelectedIndex(){
if(currentSelection==null){
return -1;
}
DataListData<SimpleTextData> data=selectionModel.getSelectedObject();
return dataListDatas.indexOf(data);
}
/*
public class SimpleDataListItem extends HorizontalPanel{
private String data; //not need?
public String getData() {
return data;
}
private String header;
public void setHeader(String header) {
this.header = header;
}
public String getHeader() {
return header;
}
private int index;
public int getId() {
return index;
}
private Label label;
public Label getLabel() {
return label;
}
public void updateModifiedLabel(boolean modified){
if(modified){
label.setText("*"+header);
}else{
label.setText(header);
}
}
public SimpleDataListItem(String header,String data,int index){
this.header=header;
this.data=data;
this.index=index;
String labelText=header;
label=new Label(header);
this.add(label);
label.setWidth("100%");
}
}
*/
public void select(int index) {
if(index<0 || index>=dataListDatas.size()){
LogUtils.log("can't select invalid index:"+index +",dataListSize="+dataListDatas.size());
return;
}
DataListData<SimpleTextData> data=dataListDatas.get(index);
select(data);
setSelectionStatus(true);
}
private void select(final DataListData<SimpleTextData> data) {
Scheduler.get().scheduleFinally(new ScheduledCommand() {
@Override
public void execute() {
selectionModel.setSelected(data, true);//how to manual select.
}
});
}
public void selectById(int id) {
for(DataListData<SimpleTextData> data:dataListDatas){
if(data.getData().getId()==id){
select(data);
break;
}
}
}
private DataListDataCell cell;
private Button saveBt;
public Button getSaveAsBt() {
return saveAsBt;
}
public void setSaveAsBt(Button saveAsBt) {
this.saveAsBt = saveAsBt;
}
public Button getSaveBt() {
return saveBt;
}
private Button saveAsBt;
private Button unselectBt;
private Button reloadBt;
private Button copyBt;
private Button deleteBt;
private Button renameBt;
private HorizontalPanel downButtons2;
private VerticalPanel optionButtons3;
/**
* for user customize
* @return
*/
public HorizontalPanel getOptionButtonPanel(){
return downButtons2;
}
public VerticalPanel getVerticalOptionPanel(){
return optionButtons3;
}
public CellContextMenu getCellContextMenu() {
return cell.getCellContextMenu();
}
public void setCellContextMenu(CellContextMenu cellContextMenu) {
cell.setCellContextMenu(cellContextMenu);
}
protected DateTimeFormat dateFormat=DateTimeFormat.getFormat("yy/MM/dd hh:mm:ss");
private CheckBox showDate;
private Button pasteBt;
private HorizontalPanel buttons2;
private HorizontalPanel buttons1;
private Button backBt;
private Button clearAllBt;
@SuppressWarnings("unchecked")
public class DataListDataCell extends AbstractContextCell<DataListData<SimpleTextData>>{
@Override
public void render(com.google.gwt.cell.client.Cell.Context context,
DataListData<SimpleTextData> value, SafeHtmlBuilder sb) {
if(value==null){
return;
}
String title="";
if(showDate.getValue()){
title=dateFormat.format(new Date(value.getData().getCdate()))+" - ";
}
title+=value.getData().getName();
if(value.isModified()){
title="*"+title;
}
sb.appendEscaped(title);
}
@Override
public void onDoubleClick(int clientX, int clientY) {
ioControler.doDoubleClick(clientX,clientY);
}
}
}