// Copyright (C) 2008 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.gerrit.client; import com.google.gerrit.client.rpc.RestApi; import com.google.gerrit.client.rpc.RpcConstants; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; import com.google.gwt.http.client.Response; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.StatusCodeException; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; import com.google.gwtexpui.safehtml.client.SafeHtml; import com.google.gwtexpui.user.client.PluginSafePopupPanel; import com.google.gwtjsonrpc.client.RemoteJsonException; /** A dialog box showing an error message, when bad things happen. */ public class ErrorDialog extends PluginSafePopupPanel { private final Label text; private final FlowPanel body; private final Button closey; protected ErrorDialog() { super(/* auto hide */false, /* modal */true); setGlassEnabled(true); getGlassElement().addClassName(Gerrit.RESOURCES.css().errorDialogGlass()); text = new Label(); text.setStyleName(Gerrit.RESOURCES.css().errorDialogTitle()); body = new FlowPanel(); final FlowPanel buttons = new FlowPanel(); buttons.setStyleName(Gerrit.RESOURCES.css().errorDialogButtons()); closey = new Button(); closey.setText(Gerrit.C.errorDialogContinue()); closey.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { hide(); } }); closey.addKeyPressHandler(new KeyPressHandler() { @Override public void onKeyPress(KeyPressEvent event) { // if the close button is triggered by a key we need to consume the key // event, otherwise the key event would be propagated to the parent // screen and eventually trigger some unwanted action there after the // error dialog was closed event.stopPropagation(); } }); buttons.add(closey); final FlowPanel center = new FlowPanel(); center.add(text); center.add(body); center.add(buttons); setText(Gerrit.C.errorTitle()); addStyleName(Gerrit.RESOURCES.css().errorDialog()); add(center); int l = Window.getScrollLeft() + 20; int t = Window.getScrollTop() + 20; setPopupPosition(l, t); } /** Create a dialog box to show a single message string. */ public ErrorDialog(final String message) { this(); body.add(new Label(message)); } /** Create a dialog box to show a single message string. */ public ErrorDialog(final SafeHtml message) { this(); body.add(message.toBlockWidget()); } public ErrorDialog(final Widget w) { this(); body.add(w); } /** Create a dialog box to nicely format an exception. */ public ErrorDialog(final Throwable what) { this(); String hdr; String msg; if (what instanceof StatusCodeException) { StatusCodeException sc = (StatusCodeException) what; if (RestApi.isExpected(sc.getStatusCode())) { hdr = null; msg = sc.getEncodedResponse(); } else if (sc.getStatusCode() == Response.SC_INTERNAL_SERVER_ERROR) { hdr = null; msg = what.getMessage(); } else { hdr = RpcConstants.C.errorServerUnavailable(); msg = what.getMessage(); } } else if (what instanceof RemoteJsonException) { // TODO Remove RemoteJsonException from Gerrit sources. hdr = RpcConstants.C.errorRemoteJsonException(); msg = what.getMessage(); } else { // TODO Fix callers of ErrorDialog to stop passing random types. hdr = what.getClass().getName(); if (hdr.startsWith("java.lang.")) { hdr = hdr.substring("java.lang.".length()); } else if (hdr.startsWith("com.google.gerrit.")) { hdr = hdr.substring(hdr.lastIndexOf('.') + 1); } if (hdr.endsWith("Exception")) { hdr = hdr.substring(0, hdr.length() - "Exception".length()); } else if (hdr.endsWith("Error")) { hdr = hdr.substring(0, hdr.length() - "Error".length()); } msg = what.getMessage(); } if (hdr != null) { final Label r = new Label(hdr); r.setStyleName(Gerrit.RESOURCES.css().errorDialogErrorType()); body.add(r); } if (msg != null) { final Label m = new Label(msg); m.getElement().getStyle().setProperty("whiteSpace", "pre"); body.add(m); } } public ErrorDialog setText(final String t) { text.setText(t); return this; } @Override public void center() { show(); closey.setFocus(true); } }