Package org.worldbank.transport.tamt.client.importer

Source Code of org.worldbank.transport.tamt.client.importer.GPSTracesView$GPSTraceStyle

package org.worldbank.transport.tamt.client.importer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.worldbank.transport.tamt.client.event.CloseWaitModelDialogEvent;
import org.worldbank.transport.tamt.client.event.CurrentStudyRegionUpdatedEvent;
import org.worldbank.transport.tamt.client.event.CurrentStudyRegionUpdatedEventHandler;
import org.worldbank.transport.tamt.client.event.GetGPSTracesEvent;
import org.worldbank.transport.tamt.client.event.GetGPSTracesEventHandler;
import org.worldbank.transport.tamt.client.event.MatchingPointsBusyEvent;
import org.worldbank.transport.tamt.client.event.MatchingPointsCompletedEvent;
import org.worldbank.transport.tamt.client.event.OpenWaitModelDialogEvent;
import org.worldbank.transport.tamt.client.event.TAMTResizeEvent;
import org.worldbank.transport.tamt.client.event.TAMTResizeEventHandler;
import org.worldbank.transport.tamt.client.services.AssignService;
import org.worldbank.transport.tamt.client.services.AssignServiceAsync;
import org.worldbank.transport.tamt.client.services.GPSTraceService;
import org.worldbank.transport.tamt.client.services.GPSTraceServiceAsync;
import org.worldbank.transport.tamt.shared.AssignStatus;
import org.worldbank.transport.tamt.shared.GPSTrace;
import org.worldbank.transport.tamt.shared.StudyRegion;

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.shared.HandlerManager;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiFactory;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ButtonBase;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;

public class GPSTracesView extends Composite {

  private static GPSTracesViewUiBinder uiBinder = GWT
      .create(GPSTracesViewUiBinder.class);

  interface GPSTracesViewUiBinder extends UiBinder<Widget, GPSTracesView> {
  }

  interface GPSTraceStyle extends CssResource {
      String list();
      String checkbox();
      String clickable();
      String columnHeader();
  }

  @UiField GPSTraceStyle style;

  @UiField CheckBox toggleAllCheckboxes;
  @UiField Button refresh;
  @UiField Button delete;
  @UiField Button process;
  @UiField Button assignToRoads;
 
  @UiField VerticalPanel panel;
 
  @UiField FlexTable gpsTraceList;
  @UiField ScrollPanel scrollPanel;
 
  @UiField FileUpload fileUpload;
  @UiField TextBox name;
  //@UiField TextBox description; // user can't edit; reserved for filename in list
  @UiField Hidden studyRegionId;
  @UiField FormPanel uploadForm;
  @UiField Button submit;
 
  private HandlerManager eventBus;
 
  private GPSTraceServiceAsync traceService;
  private AssignServiceAsync assignService;
  private ArrayList<GPSTrace> gpsTraces;
  private HashMap<String, String> gpsTraceNames;
  private ArrayList<CheckBox> checkboxes;

  private DialogBox dialogBox = new DialogBox();
  private FlexTable dialogTable = new FlexTable();
  private Button button;

  private Label dialogGpsTraceName;
  private Label dialogPointsTotal;
  private Label dialogPointsProcessed;
  private Label dialogPointsMatched;
  private Label dialogLastUpdated;
  private Label dialogStatus;
  private Button closeDialog;

  protected StudyRegion currentStudyRegion;
 
 
  public GPSTracesView(HandlerManager eventBus) {
    this.eventBus = eventBus;
   
    checkboxes = new ArrayList<CheckBox>();
    gpsTraceNames = new HashMap<String, String>();
   
    traceService = GWT.create(GPSTraceService.class);
    assignService = GWT.create(AssignService.class);
   
    initWidget(uiBinder.createAndBindUi(this));
    bind();
   
    GWT.log("post init uploadForm=" + uploadForm);
    GWT.log("post init panel=" + panel);
   
    // load the data
    //TODO: move this so it only fires when the
    // user clicks the Import nav item
    // eventBus.fireEvent(new GetGPSTracesEvent());
   
    // Set up the status dialog layout
    dialogBox.setText("Matching GPS Points to Roads and Zones");
    VerticalPanel dialogVerticalPanel = new VerticalPanel();
    HTML dialogDesc = new HTML("The system is currently matching " +
        "GPS points to roads and zones." +
        "This may take some time depending on the number of points, roads and zones in the study region.<hr/>");
    dialogVerticalPanel.add(dialogDesc);
   
    // elements in the table
    dialogTable.setWidget(0, 0, new Label("GPS trace name:"));
    dialogTable.setWidget(1, 0, new Label("Total points:"));
    dialogTable.setWidget(2, 0, new Label("Processed points:"));
    dialogTable.setWidget(3, 0, new Label("Matched points:"));
    dialogTable.setWidget(4, 0, new Label("Last updated:"));
    dialogTable.setWidget(5, 0, new Label("Status:"));
   
    dialogVerticalPanel.add(dialogTable);
   
   
    dialogBox.setWidget(dialogVerticalPanel);
   
   
  }
 
  @UiFactory VerticalPanel initVertPanel() {
    GWT.log("pre init panel=" + panel);
    VerticalPanel p = new VerticalPanel();
    p.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
    //p.setBorderWidth(1);
    return p;
  }
 
  @UiFactory FormPanel initFormPanel() {
    GWT.log("creating form panel");
    GWT.log("pre init uploadForm=" + uploadForm);
    FormPanel f = new FormPanel();
    f.setAction(GWT.getModuleBaseURL() + "uploadGPS");
    f.setEncoding(FormPanel.ENCODING_MULTIPART);
    f.setMethod(FormPanel.METHOD_POST);
    f.add(name);
    //f.add(description);
    f.add(fileUpload);
    f.add(submit);
    f.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
      @Override
      public void onSubmitComplete(SubmitCompleteEvent event) {
       
        eventBus.fireEvent( new CloseWaitModelDialogEvent() );
       
        if(event.getResults().equals("200"))
        {
          // 200 is OK
          uploadForm.reset();
          fetchGPSTraces();
        }
        else {
          Window.alert(event.getResults());
          //uploadForm.reset();
        }
      }
    });   
    return f;
  }
  @UiHandler("toggleAllCheckboxes")
  void onClickToggleAllCheckboxes(ClickEvent e) {
    CheckBox master = (CheckBox) e.getSource();
    GWT.log("toggleCheckboxes:" + master.getValue());
    for (Iterator iterator = checkboxes.iterator(); iterator.hasNext();) {
      CheckBox cb = (CheckBox) iterator.next();
      cb.setValue(master.getValue());
      GWT.log("cb: form value("+cb.getFormValue()+"), checked value("+cb.getValue()+")");
   
  }
 
  @UiHandler("refresh")
  void onClickRefresh(ClickEvent e) {
    gpsTraceList.removeAllRows();
    uncheckMasterCheckBox();
    fetchGPSTraces();
  }
 
  @UiHandler("assignToRoads")
  void onClickAssignToRoads(ClickEvent e) {
    assignPointsToRoads();
  }
 
  @UiHandler("process")
  void onClickProcess(ClickEvent e) {
    //Window.alert("Process: " + e.toString());
    //TODO: process each selected gps trace
    //TODO: warn that processing more than one at a time
    // can bog down the system
    processGPSTraces();
  }
 
  @UiHandler("delete")
  void onClickDelete(ClickEvent e) {
    //Window.alert("size of checkboxes:" + checkboxes.size());
    if( Window.confirm("Delete all checked GPS traces?") )
    {
      eventBus.fireEvent( new OpenWaitModelDialogEvent("Deleting GPS traces", "This may take a few minutes.") );
      deleteGPSTraces();
    } else {
      uncheckMasterCheckBox();
      for (Iterator iterator = checkboxes.iterator(); iterator.hasNext();) {
        CheckBox cb = (CheckBox) iterator.next();
        cb.setValue(false);
      }
    }
  } 
 
  @UiHandler("submit")
  void onClickSubmit(ClickEvent e)
  {
    eventBus.fireEvent( new OpenWaitModelDialogEvent("Uploading and processing GPS traces", "This may take a few minutes.") );
    uploadForm.submit();
  }
 
  private void uncheckMasterCheckBox()
  {
    toggleAllCheckboxes.setValue(false);
  }
 
  public void bind()
  {
    eventBus.addHandler(CurrentStudyRegionUpdatedEvent.TYPE, new CurrentStudyRegionUpdatedEventHandler() {
     
      @Override
      public void onUpdate(CurrentStudyRegionUpdatedEvent event) {
        currentStudyRegion = event.studyRegion;
        if( currentStudyRegion != null)
        {
          studyRegionId.setValue( currentStudyRegion.getId() );
        }
      }
    });
   
    eventBus.addHandler(GetGPSTracesEvent.TYPE, new GetGPSTracesEventHandler() {
     
      @Override
      public void onGetGPSTraces(GetGPSTracesEvent event) {
        fetchGPSTraces();
      }
    })
   
    eventBus.addHandler(TAMTResizeEvent.TYPE, new TAMTResizeEventHandler() {
     
      @Override
      public void onTAMTResize(TAMTResizeEvent event) {
        GWT.log("SIZE: GPSTracesView scroll panel height within: " + event.height);
       
        int h = event.height - 275; // account for other study region UI
       
        if( h > -1)
        {
        String height = Integer.toString(h) + "px";
        GWT.log("SIZE: GPSTracesView scroll panel height: " + height);
       
        scrollPanel.setHeight(height);
        panel.setHeight(height);
        }
      }
    });       
  }
 
  private void fetchGPSTraces()
  {
    //gpsTraceList.removeAllRows();
    //gpsTraceList.setWidget(0, 0, new HTML("Reloading GPS traces..."));
    // TODO: for now we just use a Default region
    //StudyRegion region = new StudyRegion();
    //region.setName("default");
   
    // replaced with currentStudyRegion
    traceService.getGPSTraces(currentStudyRegion, new AsyncCallback<ArrayList<GPSTrace>>() {
     
      @Override
      public void onSuccess(ArrayList<GPSTrace> result) {
       
        gpsTraces = result;
       
        // clear out the table
        gpsTraceList.removeAllRows();
        gpsTraceList.clear();
       
       
        gpsTraceList.setWidget(0, 1, new HTML("Name"));
        gpsTraceList.setWidget(0, 2, new HTML("Filename"));
        gpsTraceList.setWidget(0, 3, new HTML("Upload date"));
        gpsTraceList.setWidget(0, 4, new HTML("GPS records"));
        gpsTraceList.setWidget(0, 5, new HTML("Tagged GPS records"));
        gpsTraceList.setWidget(0, 6, new HTML("Tagged date"));
        //gpsTraceList.setWidget(0, 5, new HTML("Processed date"));
        gpsTraceList.getRowFormatter().setStyleName(0, style.columnHeader());
       
            // clear out the checkboxes
            checkboxes.clear();
            uncheckMasterCheckBox();
             
        for (int i = 0; i < gpsTraces.size(); i++) {
              final int count = i;
          final GPSTrace gpsTrace = gpsTraces.get(i);
          GWT.log(gpsTrace.getName());
         
          CheckBox cb = new CheckBox();
          cb.setFormValue(gpsTrace.getId()); //store the id in the checkbox value
          checkboxes.add(cb); // keep track for selecting all|none to delete
          cb.setStyleName(style.checkbox());

          // if a checkbox is checked, deselect the master checkbox
          cb.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
              uncheckMasterCheckBox();
            }
          });
         
          Label name = new Label(gpsTrace.getName());
          name.setStyleName(style.list());
         
          // also store id/name for use later
          gpsTraceNames.put(gpsTrace.getId(), gpsTrace.getName());
         
          //TODO: add clickable only if we load the details to edit
          // name.addStyleName(style.clickable());
          name.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
              //TODO: loadTagDetails(gpsTrace);
            }
          });
         
          String description = gpsTrace.getDescription();
          if( description.length() > 10)
          {
            description = description.substring(0, 10) + "...";
          }
          Label desc = new Label(description);
          desc.setTitle(gpsTrace.getDescription());
         
          Label upload = new Label(DateTimeFormat.getMediumDateTimeFormat().format(gpsTrace.getUploadDate()));
          Label processed = new Label("No");
          Label processedDate = new Label("n/a");
          if( gpsTrace.isProcessed() )
          {
            processed.setText("Yes");
            processedDate.setText(DateTimeFormat.getMediumDateTimeFormat().format(gpsTrace.getProcessDate()));
          }
         
          Label records = new Label(Integer.toString(gpsTrace.getRecordCount()));
          Label matchedRecords = new Label(Integer.toString(gpsTrace.getMatchedCount()));
         
          int row = i + 1; // to account for column headers
          gpsTraceList.setWidget(row, 0, cb);
          gpsTraceList.getCellFormatter().setWidth(row, 0, "20px");
          gpsTraceList.setWidget(row, 1, name);
          gpsTraceList.setWidget(row, 2, desc);
          gpsTraceList.setWidget(row, 3, upload);
          gpsTraceList.setWidget(row, 4, records);
          gpsTraceList.setWidget(row, 5, matchedRecords);
          gpsTraceList.setWidget(row, 6, processedDate);
         
          /* MOVED THIS FROM PER ROW BUTTON TO TABLE HEADER
           * For Assign, add a button to trigger the assignment
           *
          final AssignStatus status = new AssignStatus();
          status.setGpsTraceId(gpsTrace.getId());
          status.setGpsTraceName(gpsTrace.getName());
          status.setPointsTotal(gpsTrace.getRecordCount());
          Button assignButton = new Button("Assign");
          assignButton.addClickHandler(new ClickHandler() {
           
            @Override
            public void onClick(ClickEvent event) {
             
              /*
               * Firing this will event will trigger
               * the checkApplicationBusyTimer in ApplicationContainer to cancel
               * so that the user is not contending with
               * two waiting dialogs
               *
              GWT.log("EVENT: fire MatchingPointsBusyEvent");
              eventBus.fireEvent(new MatchingPointsBusyEvent());
             
              assignService.assignTagToPoints(status, new AsyncCallback<AssignStatus>() {

                @Override
                public void onFailure(Throwable caught) {
                  GWT.log("failed!", caught);
                  Window.alert(caught.getMessage());
                }

                @Override
                public void onSuccess(AssignStatus result) {
                  GWT.log("success!");
                  showAssignDialog(result);
                  //Window.alert(result.getUpdated().toString());
                }
              });
            }
          });
          gpsTraceList.setWidget(row, 5, assignButton);
          */
         
              }       
      }
     
      @Override
      public void onFailure(Throwable caught) {
        Window.alert("Error fetching GPS traces");
            GWT.log("Error fetching GPS traces: " + caught.getMessage());
      }
    });
  }
 
  private void showAssignDialog(final AssignStatus status)
  {
    dialogGpsTraceName = new Label(status.getGpsTraceName());
    dialogLastUpdated= new Label(status.getLastUpdated().toString());
    dialogPointsMatched= new Label(Integer.toString(status.getPointsMatched()));
    dialogPointsProcessed= new Label(Integer.toString(status.getPointsProcessed()));
    dialogPointsTotal= new Label(Integer.toString(status.getPointsTotal()));
    String statusMessage = "Incomplete";
    if( status.isComplete())
    {
      statusMessage = "Complete"; // dialog is actually closed by the time we get here
    }
    dialogStatus = new Label(statusMessage);
   
    dialogTable.setWidget(0, 1, dialogGpsTraceName);
    dialogTable.setWidget(1, 1, dialogPointsTotal);
    dialogTable.setWidget(2, 1, dialogPointsProcessed);
    dialogTable.setWidget(3, 1, dialogPointsMatched);
    dialogTable.setWidget(4, 1, dialogLastUpdated);
    dialogTable.setWidget(5, 1, dialogStatus);
   
    closeDialog = new Button("Processing...");
    closeDialog.setEnabled(false);
    closeDialog.addClickHandler(new ClickHandler() {
     
      @Override
      public void onClick(ClickEvent event) {
        /*
         * Firing this will event will trigger
         * the checkApplicationBusyTimer in ApplicationContainer to restart
         * so that the user can be interrupted
         * by another client issuing an assignment process
         */
        GWT.log("EVENT: fire MatchingPointsCompletedEvent");
        eventBus.fireEvent(new MatchingPointsCompletedEvent());
       
        // uncheck the selected archive
        uncheckAll();
       
        // close the dialog
        dialogBox.hide();
       
        // and refetch to update the table with processed info
        fetchGPSTraces();
      }
    });
    //closeDialog.setVisible(false);
    dialogTable.setWidget(6, 1, closeDialog);
   
    dialogBox.setAutoHideEnabled(false);
    dialogBox.setGlassEnabled(true);
    dialogBox.center();
    dialogBox.show()
   
    pollStatus(status);
   
  }
 
  private void updateDialog(final AssignStatus status)
  {
   
    GWT.log("update dialog with status=" + status);
   
    dialogGpsTraceName.setText(status.getGpsTraceName());
    dialogLastUpdated.setText(status.getLastUpdated().toString());
    dialogPointsMatched.setText(Integer.toString(status.getPointsMatched()));
    dialogPointsProcessed.setText(Integer.toString(status.getPointsProcessed()));
    dialogPointsTotal.setText(Integer.toString(status.getPointsTotal()));
   
    String statusMessage = "Incomplete";
    if( status.isComplete())
    {
      statusMessage = "Complete"; // dialog is actually closed by the time we get here
    }
    dialogStatus.setText(statusMessage);
   
  }
 
  private void pollStatus(final AssignStatus status)
  {
    GWT.log("poll status on a 10 s timer....");
    Timer t = new Timer() {

      @Override
      public void run() {
        assignService.checkStatus(status, new AsyncCallback<AssignStatus>() {

          @Override
          public void onFailure(Throwable caught) {
            Window.alert("Failed to check assigned status: " + caught.getMessage());
          }

          @Override
          public void onSuccess(AssignStatus returnedStatus) {
            GWT.log("successful return from assignService.checkStatus");
            GWT.log("return status=" + returnedStatus.isComplete());
            if( returnedStatus.isComplete() )
            {
              updateDialog(returnedStatus);
              closeDialog.setEnabled(true);
              closeDialog.setText("OK");
              closeDialog.setVisible(true); // instead of auto hide with dialogBox.hide()
            } else {
              updateDialog(returnedStatus);
              pollStatus(returnedStatus); // poll againn 10 s
            }
           
          }
        });
      }
     
    };
    t.schedule(1000); // 10 seconds
     
  }
 
  private void processGPSTraces()
  {
    ArrayList<String> gpsTraceIds = new ArrayList<String>();
    for (Iterator iterator = checkboxes.iterator(); iterator.hasNext();) {
      CheckBox cb = (CheckBox) iterator.next();
      // boolean to see if it is checked
      if(cb.getValue())
      {
        gpsTraceIds.add(cb.getFormValue());
      }
     
      traceService.processGPSTraces(gpsTraceIds, new AsyncCallback<Void>() {

        @Override
        public void onFailure(Throwable caught) {
          Window.alert(caught.getMessage());
        }

        @Override
        public void onSuccess(Void result) {
          fetchGPSTraces(); // will refresh UI with process status updated
        }
      });
    }   
  }

  private void assignPointsToRoads() {
    ArrayList<String> gpsTraceIds = new ArrayList<String>();
    for (Iterator iterator = checkboxes.iterator(); iterator.hasNext();) {
      CheckBox cb = (CheckBox) iterator.next();
      // boolean to see if it is checked
      if(cb.getValue())
      {
        gpsTraceIds.add(cb.getFormValue());
      }
    }
   
    if( gpsTraceIds.size() == 0 )
    {
      Window.alert("Please select a GPS archive.");
      return;
    }
   
    /*
     * If more than one is checked, alert the user this is not
     * allowed due to heavy server processing
     */
    if( gpsTraceIds.size() > 1)
    {
      Window.alert("Due to heavy loads on the server, only one" +
          "\n GPS archive at a time may have its GPS records tagged by road.");
     
      // deselect all checkboxes
      uncheckAll();
      return;
    }
   
    // ok, we have one and only one, so let's kick off the assignment process
    String gpsTraceId = gpsTraceIds.get(0);
    AssignStatus status = new AssignStatus();
    status.setGpsTraceId(gpsTraceId);
   
    // get the name from the hash
    String name = gpsTraceNames.get(gpsTraceId);
    status.setGpsTraceName(name);
   
    GWT.log("assignTagToPoints for:" + status);
   
    GWT.log("EVENT: fire MatchingPointsBusyEvent");
    eventBus.fireEvent(new MatchingPointsBusyEvent());
   
    // fire the async
    assignService.assignTagToPoints(status, new AsyncCallback<AssignStatus>() {

      @Override
      public void onFailure(Throwable caught) {
        // hide the dialog FIRST so the user can return to work
        dialogBox.hide();
        // we might even want to update the dialog with
        // 0s and a status message
        Window.alert(caught.getMessage());
       
      }

      @Override
      public void onSuccess(AssignStatus result) {
        GWT.log("success!");
        showAssignDialog(result);
      }
    });
  }
 
  private void deleteGPSTraces() {
    ArrayList<String> gpsTraceIds = new ArrayList<String>();
    for (Iterator iterator = checkboxes.iterator(); iterator.hasNext();) {
      CheckBox cb = (CheckBox) iterator.next();
      // boolean to see if it is checked
      if(cb.getValue())
      {
        gpsTraceIds.add(cb.getFormValue());
      }
    }
    GWT.log("ERROR in ids to be deleted?: " + gpsTraceIds);
    traceService.deleteGPSTraces(gpsTraceIds, new AsyncCallback<Void>() {

      @Override
      public void onFailure(Throwable caught) {
        Window.alert(caught.getMessage());
      }

      @Override
      public void onSuccess(Void result) {
        uncheckMasterCheckBox();
        fetchGPSTraces();
        eventBus.fireEvent( new CloseWaitModelDialogEvent() );
      }
    });
  }
 
  private void uncheckAll()
  {
    for (Iterator iterator = checkboxes.iterator(); iterator.hasNext();) {
      CheckBox cb = (CheckBox) iterator.next();
      cb.setValue(false);
    }
  }

}
TOP

Related Classes of org.worldbank.transport.tamt.client.importer.GPSTracesView$GPSTraceStyle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
-20639858-1', 'auto'); ga('send', 'pageview');