import java.util.Iterator;
import java.util.Vector;
+import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowCloseListener;
+import com.google.gwt.user.client.impl.HTTPRequestImpl;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasFocus;
import com.google.gwt.user.client.ui.HasWidgets;
// TODO remove hard coded id name
view = new IView(cnf.getRootPanelId());
- makeUidlRequest("", true);
+ makeUidlRequest("", true, false);
applicationRunning = true;
}
return (activeRequests > 0);
}
- private void makeUidlRequest(String requestData, boolean repaintAll) {
+ private void makeUidlRequest(String requestData, boolean repaintAll,
+ boolean forceSync) {
startRequest();
console.log("Making UIDL Request with params: " + requestData);
if (repaintAll) {
uri += "?repaintAll=1";
}
- final RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, uri);
- // rb.setHeader("Content-Type",
- // "application/x-www-form-urlencoded; charset=utf-8");
- rb.setHeader("Content-Type", "text/plain;charset=utf-8");
- try {
- rb.sendRequest(requestData, new RequestCallback() {
- public void onError(Request request, Throwable exception) {
- // TODO Better reporting to user
- console.error("Got error");
- endRequest();
- }
- public void onResponseReceived(Request request,
- Response response) {
- handleReceivedJSONMessage(response);
- }
+ if (!forceSync) {
+ final RequestBuilder rb = new RequestBuilder(RequestBuilder.POST,
+ uri);
+ rb.setHeader("Content-Type", "text/plain;charset=utf-8");
+ try {
+ rb.sendRequest(requestData, new RequestCallback() {
+ public void onError(Request request, Throwable exception) {
+ // TODO Better reporting to user
+ console.error("Got error");
+ endRequest();
+ }
- });
+ public void onResponseReceived(Request request,
+ Response response) {
+ handleReceivedJSONMessage(response);
+ }
- } catch (final RequestException e) {
- ClientExceptionHandler.displayError(e);
- endRequest();
+ });
+
+ } catch (final RequestException e) {
+ ClientExceptionHandler.displayError(e);
+ endRequest();
+ }
+ } else {
+ // Synchronized call, discarded response
+
+ syncSendForce(((HTTPRequestImpl) GWT.create(HTTPRequestImpl.class))
+ .createXmlHTTPRequest(), uri, requestData);
}
}
+ private native void syncSendForce(JavaScriptObject xmlHttpRequest,
+ String uri, String requestData)
+ /*-{
+ try {
+ xmlHttpRequest.open("POST", uri, false);
+ xmlHttpRequest.setRequestHeader("Content-Type", "text/plain;charset=utf-8");
+ xmlHttpRequest.send(requestData);
+ } catch (e) {
+ // No errors are managed as this is synchronous forceful send that can just fail
+ }
+
+ }-*/;
+
private void startRequest() {
activeRequests++;
showLoadingIndicator();
}
Vector nextBurst = (Vector) pendingVariableBursts.firstElement();
pendingVariableBursts.remove(0);
- buildAndSendVariableBurst(nextBurst);
+ buildAndSendVariableBurst(nextBurst, false);
}
}
endRequest();
}
+ /**
+ * This method assures that all pending variable changes are sent to server.
+ * Method uses synchronized xmlhttprequest and does not return before the
+ * changes are sent. No UIDL updates are processed and thut UI is left in
+ * inconsistent state. This method should be called only when closing
+ * windows - normally sendPendingVariableChanges() should be used.
+ */
+ public void sendPendingVariableChangesSync() {
+ buildAndSendVariableBurst(pendingVariables, true);
+ }
+
// Redirect browser, null reloads current page
private static native void redirect(String url)
/*-{
pendingVariables.clear();
}
} else {
- buildAndSendVariableBurst(pendingVariables);
+ buildAndSendVariableBurst(pendingVariables, false);
}
}
}
- private void buildAndSendVariableBurst(Vector pendingVariables) {
+ private void buildAndSendVariableBurst(Vector pendingVariables,
+ boolean forceSync) {
final StringBuffer req = new StringBuffer();
for (int i = 0; i < pendingVariables.size(); i++) {
}
pendingVariables.clear();
- makeUidlRequest(req.toString(), false);
+ makeUidlRequest(req.toString(), false, forceSync);
}
public void updateVariable(String paintableId, String variableName,
protected ApplicationConnection client;
+ private String valueBeforeEdit = null;
+
private boolean immediate = false;
private float proportionalHeight = -1;
private float proportionalWidth = -1;
}
setText(uidl.getStringVariable("text"));
-
+ valueBeforeEdit = uidl.getStringVariable("text");
}
public void onChange(Widget sender) {
if (client != null && id != null) {
- client.updateVariable(id, "text", getText(), immediate);
+ String newText = getText();
+ if (newText != null && !newText.equals(valueBeforeEdit)) {
+ client.updateVariable(id, "text", getText(), immediate);
+ valueBeforeEdit = newText;
+ }
+ }
+ }
+
+ private static ITextField focusedTextField;
+
+ public static void flushChangesFromFocusedTextField() {
+ if (focusedTextField != null) {
+ focusedTextField.onChange(null);
}
}
public void onFocus(Widget sender) {
addStyleDependentName(CLASSNAME_FOCUS);
+ focusedTextField = this;
}
public void onLostFocus(Widget sender) {
removeStyleDependentName(CLASSNAME_FOCUS);
+ focusedTextField = null;
+ onChange(sender);
}
public void setColumns(int columns) {
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.WindowCloseListener;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
*
*/
public class IView extends SimplePanel implements Paintable,
- WindowResizeListener {
+ WindowResizeListener, WindowCloseListener {
private static final String CLASSNAME = "i-view";
/** stored height for IE resize optimization */
private int height;
+ private ApplicationConnection connection;
+
/**
* We are postponing resize process with IE. IE bugs with scrollbars in some
* situations, that causes false onWindowResized calls. With Timer we will
RootPanel.get(elementId).add(this);
Window.addWindowResizeListener(this);
+ Window.addWindowCloseListener(this);
// set focus to iview element by default to listen possible keyboard
// shortcuts
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
id = uidl.getId();
+ connection = client;
String newTheme = uidl.getStringAttribute("theme");
if (theme != null && !newTheme.equals(theme)) {
$wnd.location = url;
}-*/;
+ public void onWindowClosed() {
+ // Change focus on this window in order to ensure that all state is
+ // collected from textfields
+ ITextField.flushChangesFromFocusedTextField();
+
+ // Send the closing state to server
+ connection.updateVariable(id, "close", true, false);
+ connection.sendPendingVariableChangesSync();
+ }
+
+ private static native void focusElement(Element e) /*-{
+ e.focus();
+ }-*/;
+
+ public String onWindowClosing() {
+ return null;
+ }
+
}