package org.openrosa.client.view;
import org.openrosa.client.Context;
import org.openrosa.client.FormDesigner;
import org.openrosa.client.controller.IFileListener;
import org.openrosa.client.controller.ITextListener;
import org.openrosa.client.model.FormDef;
import org.openrosa.client.model.ItextModel;
import org.openrosa.client.util.Itext;
import org.openrosa.client.util.ItextParser;
import org.openrosa.client.util.XEPResponse;
import org.openrosa.client.xforms.XformParser;
import org.openrosa.client.xforms.XhtmlBuilder;
import org.openrosa.client.PurcConstants;
import org.openrosa.client.controller.IFormSelectionListener;
import org.openrosa.client.controller.OpenFileDialogEventListener;
import org.openrosa.client.util.FormUtil;
import org.openrosa.client.xforms.XmlUtil;
import com.extjs.gxt.ui.client.store.ListStore;
import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.xml.client.Document;
/**
* This is the widget that houses the xforms, design and internationalization tab.
*
* @author daniel
*
*/
public class CenterWidget extends Composite implements IFileListener,IFormSelectionListener,ITextListener, OpenFileDialogEventListener {
/**
* Tab widget housing the contents.
*/
private DecoratedTabPanel tabs = new DecoratedTabPanel();
private XformsTabWidget xformsWidget = new XformsTabWidget(this);
DesignTabWidget designWidget = new DesignTabWidget(this);
private TextTabWidget itextWidget = new TextTabWidget(this);
/**
* this is a flag the onSave() method checks to see if it should show the xml window when it saves.
*/
private boolean showXMLWindowFlag = true;
private String externalXML;
private Boolean loadExternalXML;
public CenterWidget() {
this.loadExternalXML = false;
initWidget(designWidget);
FormUtil.maximizeWidget(tabs);
FormUtil.maximizeWidget(designWidget);
FormUtil.maximizeWidget(this);
designWidget.addFormSelectionListener(this);
}
public void onWindowResized(int width, int height){
int shortcutHeight = height - getAbsoluteTop();
if(shortcutHeight > 50){
xformsWidget.adjustHeight(shortcutHeight-130 + PurcConstants.UNITS);
itextWidget.adjustHeight(shortcutHeight-50 + PurcConstants.UNITS);
}
designWidget.onWindowResized(width, height);
}
public void onNew(){
designWidget.addNewForm();
}
public void onOpen(){
if(!xformsWidget.isVisible()){
xformsWidget.setXform(null);
xformsWidget.showWindow();
return;
}
xformsWidget.hideWindow();
FormUtil.dlg.setText("Opening...");
FormUtil.dlg.show();
DeferredCommand.addCommand(new Command() {
public void execute() {
try{
openFile();
xformsWidget.showWindow();
FormUtil.dlg.hide();
}
catch(Exception ex){
FormUtil.displayException(ex);
}
}
});
}
public void openExternalXML(String xml){
this.loadExternalXML = true;
this.externalXML = xml;
openFile();
}
private void openFile(){
String xml;
if(loadExternalXML && externalXML != null){
xml = externalXML;
loadExternalXML = false; //to keep standard operation going
}else{
xml = xformsWidget.getXform();
}
if(xml == null || xml.trim().length() == 0){
xformsWidget.showWindow();
return;
}
Itext.clearLocales();
Document doc = ItextParser.parse(xml);
FormDef formDef = XformParser.getFormDef(doc);
formDef.setXformXml(xml);
designWidget.loadForm(formDef);
FormUtil.dlg.hide();
}
/**
* Updates the FormDef and the XML it points to so everything is nice and lined up.
* Then shows the XML form
*/
public void onPreview(boolean showWindow){
xformsWidget.hideWindow();
FormUtil.dlg.setText("Saving...");
FormUtil.dlg.show();
showXMLWindowFlag = showWindow;
DeferredCommand.addCommand(new Command() {
public void execute() {
try{
boolean saved = saveFile(showXMLWindowFlag);
xformsWidget.showWindow();
FormUtil.dlg.hide();
}
catch(Exception ex){
FormUtil.displayException(ex);
}
}
});
}
public boolean saveFile(boolean showWindow){ //used by onPreview(), showItext() and submitData()
FormDef formDef = Context.getFormDef();
String xml = null;
if(formDef == null){
xformsWidget.setXform("");
Window.alert("Form is empty! Nothing to save.");
return false;
}
designWidget.commitChanges();
Document doc = formDef.getDoc();
if(doc != null){
formDef.updateDoc(false);
}else{
doc = XhtmlBuilder.fromFormDef2XhtmlDoc(formDef);
formDef.setDoc(doc);
formDef.setXformsNode(doc.getDocumentElement());
}
ItextParser.updateItextBlock(formDef);
itextWidget.save(false); //calls onSaveItext() below
doc.getDocumentElement().setAttribute("xmlns:jr", "http://openrosa.org/javarosa");
doc.getDocumentElement().setAttribute("xmlns", "http://www.w3.org/2002/xforms");
xml = FormUtil.formatXml(XmlUtil.fromDoc2String(doc));
if(formDef != null)
formDef.setXformXml(xml);
xformsWidget.setXform(xml);
//hack
cleanupBadXML(formDef.getDoc());
if(showWindow){
xformsWidget.showWindow();
}
return true;
}
public void onSaveItext(ListStore<ItextModel> itextrows){
Itext.updateModel(itextrows);
FormDef formDef = Context.getFormDef();
if(formDef == null || formDef.getDoc() == null){
Window.alert("FormDef is null. Can't save Itext");
return;
}
String xml = null;
ItextParser.updateItextBlock(formDef);
xml = FormUtil.formatXml(XmlUtil.fromDoc2String(formDef.getDoc()));
//update form outline with the itext changes
// formDef = XformParser.getFormDef(ItextParser.parse(xml));
designWidget.refreshForm(formDef);
formDef.setXformXml(xml);
xformsWidget.setXform(xml);
}
public void refreshForm(){
FormDef formDef = Context.getFormDef();
designWidget.refreshForm(formDef);
}
public void showItext(){
FormUtil.dlg.setText("Opening...");
FormUtil.dlg.show();
DeferredCommand.addCommand(new Command() {
public void execute() {
try{
// saveFile(false);
// FormDef formDef = Context.getFormDef();
// //String xml = null;
//
// if(formDef == null || formDef.getDoc() == null || (formDef.getText() == null) || formDef.getText().isEmpty())
// return;
//This line is called in the this.saveFile(false) above.
/*textBuilder.updateItextBlock(formDef.getDoc(), formDef, itextWidget.getItext(),formAttrMap,itextMap);
xml = FormUtil.formatXml(XmlUtil.fromDoc2String(formDef.getDoc()));
//update form outline with the itext changes
itextList = new ListStore<ItextModel>();
formDef = XformParser.getFormDef(ItextParser.parse(xml,itextList,formAttrMap,itextMap));
// designWidget.refreshForm(formDef);*/
itextWidget.loadItext();
itextWidget.showWindow();
FormUtil.dlg.hide();
}
catch(Exception ex){
FormUtil.displayException(ex);
}
}
});
}
public void cleanupBadXML(Document doc){
//// Window.alert("Cleaning?");
// ((Element)doc.getElementsByTagName("model").item(0)).removeAttribute("xmlns");
// NodeList nl = doc.getElementsByTagName("input");
//// Window.alert("number of input tags found:"+nl.getLength());
// for (int i=0;i<nl.getLength();i++){
// ((Element)nl.item(i)).removeAttribute("xmlns");
// }
// return;
}
public void onFormItemSelected(Object formItem){
}
public void onSetFileContents(String contents){
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,FormUtil.getFileOpenUrl());
try{
builder.sendRequest(null, new RequestCallback(){
public void onResponseReceived(Request request, Response response){
if(response.getStatusCode() != Response.SC_OK){
FormUtil.displayReponseError(response);
return;
}
String contents = response.getText();
if(contents != null && contents.trim().length() > 0){
xformsWidget.setXform(contents);
onOpen();
}
}
public void onError(Request request, Throwable exception){
FormUtil.displayException(exception);
}
});
}
catch(RequestException ex){
FormUtil.displayException(ex);
}
}
public void onSubmit(boolean continueEdit){
boolean saved = saveFile(false);
CenterWidget.continueEditing = continueEdit;
if(Context.getFormDef() == null || !saved)
Window.alert("No form to submit");
else
FormUtil.dlg.setText("Submitting Form...");
boolean canSubmit = submitData();
if(!canSubmit){
Window.alert("Client side submission error. Data not sent!");
}
}
public static boolean continueEditing = false;
private boolean submitData(){
if(FormDesigner.token == null || FormDesigner.token.length() == 0){
return false;
}
// submitDialogue.show();
String url = FormDesigner.XEP_POST_FORM_URL;
// String url = FormUtil.getHostPageBaseURL();
// url += FormUtil.getFormDefUploadUrlSuffix();
//url += FormUtil.getFormIdName()+"="+this.formId;
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,URL.encode(url));
try{
builder.setHeader("Content-Type", "application/x-www-form-urlencoded");
String data = "token="+FormDesigner.token + "&";
if(continueEditing){
data += "continue=true&";
}else{
data += "continue=false&";
}
saveFile(false);
String xml = xformsWidget.getXform();
if(xml == null || xml.isEmpty()){
// Window.alert("Form being sent is blank.");
}else{
// Window.alert("Sending Form...");
FormUtil.dlg.center("Sending Form...");
FormUtil.dlg.show();
}
data += "xform="+URL.encodeComponent(xml);
builder.sendRequest(data, new RequestCallback(){
public void onResponseReceived(Request request, Response response){
int code = response.getStatusCode();
FormUtil.dlg.hide();
// Window.alert("Received Status Code is: "+code+"\n"+
// "Headers:"+response.getHeadersAsString());
if(response.getStatusCode() == Response.SC_OK){
FormUtil.dlg.center("Succesfully Sent Form!");
FormUtil.dlg.show();
FormUtil.dlg.hide();
XEPResponse xepResponse = ParseXEPResponse(response.getText());
if(xepResponse.getContinue()){
Window.alert("Successfully Saved! Please continue editing\n Status: "+xepResponse.getStatus());
}else{
// Window.alert("Successfully submitted. Status: "+xepResponse.getStatus()+"\nRedirecting you back to HQ...");
FormDesigner.enableCloseHandler(false);
String redirectURL = xepResponse.getCallback();
Window.Location.assign(redirectURL);
}
return;
}else{
FormUtil.displayReponseError(response);
}
// if(!continueEditing){
// Window.Loation.assign(response.getHeader("Location"));
// }
}
public void onError(Request request, Throwable exception){
Window.alert("sendRequest onError exception....");
FormUtil.displayException(exception);
}
});
return true;
}
catch(RequestException ex){
FormUtil.displayException(ex);
return false;
}
}
private final native XEPResponse ParseXEPResponse(String json) /*-{
return eval("(" + json + ")");
}-*/;
@Override
public void onOpenFile() {
// TODO Auto-generated method stub
}
}