Introduces read only task view with an edit button. Gets around problems when we try to edit a TaskProxyImpl, which is unpossible. git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10165 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/ClientFactory.java b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/ClientFactory.java index e9d6ba0..913ed2d 100644 --- a/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/ClientFactory.java +++ b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/ClientFactory.java
@@ -17,9 +17,10 @@ import com.google.gwt.event.shared.EventBus; import com.google.gwt.place.shared.PlaceController; -import com.google.gwt.storage.client.Storage; import com.google.gwt.sample.mobilewebapp.client.activity.TaskEditView; import com.google.gwt.sample.mobilewebapp.client.activity.TaskListView; +import com.google.gwt.sample.mobilewebapp.client.activity.TaskReadView; +import com.google.gwt.storage.client.Storage; /** * The factory responsible for instantiating everything interesting in this @@ -84,6 +85,11 @@ TaskListView getTaskListView(); /** + * Get an implementation of {@link TaskEditView}. + */ + TaskReadView getTaskReadView(); + + /** * Must be called before any get methods. */ void init();
diff --git a/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/ClientFactoryImpl.java b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/ClientFactoryImpl.java index 9b12eeb..5809ccb 100644 --- a/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/ClientFactoryImpl.java +++ b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/ClientFactoryImpl.java
@@ -22,16 +22,18 @@ import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.place.shared.PlaceController; import com.google.gwt.place.shared.PlaceHistoryHandler; -import com.google.gwt.sample.mobilewebapp.client.activity.AppActivityMapper; import com.google.gwt.sample.gaerequest.client.GaeAuthRequestTransport; import com.google.gwt.sample.gaerequest.client.ReloadOnAuthenticationFailure; +import com.google.gwt.sample.mobilewebapp.client.activity.AppActivityMapper; import com.google.gwt.sample.mobilewebapp.client.activity.TaskEditView; import com.google.gwt.sample.mobilewebapp.client.activity.TaskListActivity; import com.google.gwt.sample.mobilewebapp.client.activity.TaskListView; +import com.google.gwt.sample.mobilewebapp.client.activity.TaskReadView; import com.google.gwt.sample.mobilewebapp.client.desktop.DesktopTaskEditView; import com.google.gwt.sample.mobilewebapp.client.desktop.DesktopTaskListView; import com.google.gwt.sample.mobilewebapp.client.desktop.MobileWebAppShellDesktop; import com.google.gwt.sample.mobilewebapp.client.place.AppPlaceHistoryMapper; +import com.google.gwt.sample.mobilewebapp.client.tablet.TabletTaskReadView; import com.google.gwt.storage.client.Storage; import com.google.gwt.user.client.Window; import com.google.web.bindery.requestfactory.shared.RequestTransport; @@ -63,6 +65,8 @@ */ private final PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper); + private TaskReadView taskReadView; + public ClientFactoryImpl() { RequestTransport requestTransport = new GaeAuthRequestTransport(eventBus); requestFactory = GWT.create(MobileWebAppRequestFactory.class); @@ -89,12 +93,7 @@ */ activityManager = new ActivityManager(activityMapper, eventBus); } - - public void init() { - activityManager.setDisplay(getShell()); - } - @Override public App getApp() { return new App(getLocalStorageIfSupported(), getEventBus(), getPlaceController(), historyMapper, historyHandler, new ReloadOnAuthenticationFailure(), getShell()); @@ -137,6 +136,17 @@ return taskListView; } + public TaskReadView getTaskReadView() { + if (taskReadView == null) { + taskReadView = createTaskReadView(); + } + return taskReadView; + } + + public void init() { + activityManager.setDisplay(getShell()); + } + /** * Create the application UI shell. * @@ -193,4 +203,8 @@ } }; } + + private TaskReadView createTaskReadView() { + return new TabletTaskReadView(); + } }
diff --git a/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/activity/TaskEditActivity.java b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/activity/TaskEditActivity.java index d7a5ba5..470c85a 100644 --- a/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/activity/TaskEditActivity.java +++ b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/activity/TaskEditActivity.java
@@ -37,7 +37,8 @@ /** * Activity that presents a task to be edited. */ -public class TaskEditActivity extends AbstractActivity implements TaskEditView.Presenter { +public class TaskEditActivity extends AbstractActivity implements TaskEditView.Presenter, + TaskReadView.Presenter { private static final Logger log = Logger.getLogger(TaskEditActivity.class.getName()); private final ClientFactory clientFactory; @@ -56,9 +57,14 @@ private boolean isEditing; /** - * The current task being edited. + * The current task being displayed, might not be possible to edit it. */ - private TaskProxy task; + private TaskProxy readOnlyTask; + + /** + * The current task being edited, provided by RequestFactory. + */ + private TaskProxy editTask; /** * The ID of the current task being edited. @@ -69,15 +75,17 @@ * The request used to persist the modified task. */ private Request<Void> taskPersistRequest; + private AcceptsOneWidget container; /** * Construct a new {@link TaskEditActivity}. + * * @param clientFactory the {@link ClientFactory} of shared resources * @param place configuration for this activity */ public TaskEditActivity(ClientFactory clientFactory, TaskEditPlace place) { this.taskId = place.getTaskId(); - this.task = place.getTask(); + this.readOnlyTask = place.getTask(); this.clientFactory = clientFactory; } @@ -112,7 +120,7 @@ * request already exists, reuse it. */ if (taskPersistRequest == null) { - taskPersistRequest = context.persist().using(task); + taskPersistRequest = context.persist().using(editTask); } // Fire the request. @@ -141,32 +149,31 @@ } public void start(AcceptsOneWidget container, EventBus eventBus) { + this.container = container; // Prefetch the sounds used in this activity. SoundEffects.get().prefetchError(); // Hide the 'add' button in the shell. clientFactory.getShell().setAddButtonHandler(null); - // Set the presenter on the view. - final TaskEditView view = clientFactory.getTaskEditView(); - view.setPresenter(this); - view.setNameViolation(null); + // Set the presenter on the views. + final TaskEditView editView = clientFactory.getTaskEditView(); + editView.setPresenter(this); + editView.setNameViolation(null); + + final TaskReadView readView = clientFactory.getTaskReadView(); + readView.setPresenter(this); if (taskId == null) { - // Create a new task. - isEditing = false; - view.setEditing(false); - TaskRequest request = clientFactory.getRequestFactory().taskRequest(); - task = request.create(TaskProxy.class); - view.getEditorDriver().edit(task, request); + editTask(); + return; } else { // Lock the display until the task is loaded. isEditing = true; - view.setEditing(true); + editView.setEditing(true); - if (task == null) { + if (readOnlyTask == null) { // Load the existing task. - view.setLocked(true); clientFactory.getRequestFactory().taskRequest().findTask(this.taskId).fire( new Receiver<TaskProxy>() { @Override @@ -192,20 +199,18 @@ } // Show the task. - task = response; - view.getEditorDriver().edit(response, - clientFactory.getRequestFactory().taskRequest()); - view.setLocked(false); + readOnlyTask = response; + readView.getEditorDriver().edit(response); } }); } else { // Use the task that was passed with the place. - view.getEditorDriver().edit(task, clientFactory.getRequestFactory().taskRequest()); + readView.getEditorDriver().edit(readOnlyTask); } } // Display the view. - container.setWidget(view.asWidget()); + container.setWidget(readView); } /** @@ -219,12 +224,12 @@ * Delete the current task. */ private void doDeleteTask() { - if (task == null) { + if (editTask == null) { return; } // Delete the task in the data store. - final TaskProxy toDelete = this.task; + final TaskProxy toDelete = this.editTask; clientFactory.getRequestFactory().taskRequest().remove().using(toDelete).fire( new Receiver<Void>() { @Override @@ -271,4 +276,52 @@ // Return to the task list. clientFactory.getPlaceController().goTo(new TaskListPlace(true)); } + + @Override + public void editTask() { + // Load the existing task. + final TaskEditView editView = clientFactory.getTaskEditView(); + + if (taskId == null) { + isEditing = false; + editView.setEditing(false); + TaskRequest request = clientFactory.getRequestFactory().taskRequest(); + editTask = request.create(TaskProxy.class); + editView.getEditorDriver().edit(editTask, request); + } else { + editView.setLocked(true); + clientFactory.getRequestFactory().taskRequest().findTask(this.taskId).fire( + new Receiver<TaskProxy>() { + @Override + public void onFailure(ServerFailure error) { + Window.alert("An error occurred on the server while loading this task." + + " Please select a different task from the task list."); + doCancelTask(); + } + + @Override + public void onSuccess(TaskProxy response) { + // Early exit if this activity has already been cancelled. + if (isDead) { + return; + } + + // Task not found. + if (response == null) { + Window.alert("The task with id '" + taskId + "' could not be found." + + " Please select a different task from the task list."); + doCancelTask(); + return; + } + + // Show the task. + editTask = response; + editView.getEditorDriver().edit(response, + clientFactory.getRequestFactory().taskRequest()); + editView.setLocked(false); + } + }); + } + container.setWidget(editView); + } }
diff --git a/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/activity/TaskReadView.java b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/activity/TaskReadView.java new file mode 100644 index 0000000..2553774 --- /dev/null +++ b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/activity/TaskReadView.java
@@ -0,0 +1,46 @@ +/* + * Copyright 2011 Google Inc. + * + * 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.gwt.sample.mobilewebapp.client.activity; + +import com.google.gwt.editor.client.Editor; +import com.google.gwt.editor.client.SimpleBeanEditorDriver; +import com.google.gwt.sample.mobilewebapp.shared.TaskProxy; +import com.google.gwt.user.client.ui.IsWidget; + +public interface TaskReadView extends IsWidget, Editor<TaskProxy> { + + /** + * The presenter for this view. + */ + public static interface Presenter { + /** + * Switch to an edit view of this task. + */ + void editTask(); + } + + /** + * Get the driver used to edit tasks in the view. + */ + SimpleBeanEditorDriver<TaskProxy, ?> getEditorDriver(); + + /** + * Set the {@link Presenter} for this view. + * + * @param presenter the presenter + */ + void setPresenter(Presenter presenter); +}
diff --git a/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/tablet/TabletTaskReadView.java b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/tablet/TabletTaskReadView.java new file mode 100644 index 0000000..84ceee1 --- /dev/null +++ b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/tablet/TabletTaskReadView.java
@@ -0,0 +1,99 @@ +/* + * Copyright 2011 Google Inc. + * + * 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.gwt.sample.mobilewebapp.client.tablet; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.editor.client.SimpleBeanEditorDriver; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.sample.mobilewebapp.client.activity.TaskEditView; +import com.google.gwt.sample.mobilewebapp.client.activity.TaskReadView; +import com.google.gwt.sample.mobilewebapp.shared.TaskProxy; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.DateLabel; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.Widget; + +/** + * View used to edit a task. + */ +public class TabletTaskReadView extends Composite implements TaskReadView { + + /** + * Editor driver for this view. + */ + interface Driver extends SimpleBeanEditorDriver<TaskProxy, TabletTaskReadView> { + } + + /** + * The UiBinder interface. + */ + interface TabletTaskReadViewUiBinder extends UiBinder<Widget, TabletTaskReadView> { + } + + /** + * The UiBinder used to generate the view. + */ + private static TabletTaskReadViewUiBinder uiBinder = GWT.create(TabletTaskReadViewUiBinder.class); + + @UiField + DateLabel dueDateEditor; + @UiField + Label nameEditor; + @UiField + Label notesEditor; + + /** + * The text box used to save changes or create a new task. + */ + @UiField + Button editButton; + + private final Driver driver = GWT.create(Driver.class); + + /** + * The {@link TaskEditView.Presenter} for this view. + */ + private Presenter presenter; + + /** + * Construct a new {@link TabletTaskReadView}. + */ + public TabletTaskReadView() { + initWidget(uiBinder.createAndBindUi(this)); + driver.initialize(this); + + // Create a new task or modify the current task when done is pressed. + editButton.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + if (presenter != null) { + presenter.editTask(); + } + } + }); + } + + public SimpleBeanEditorDriver<TaskProxy, ?> getEditorDriver() { + return driver; + } + + public void setPresenter(Presenter presenter) { + this.presenter = presenter; + } +}
diff --git a/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/tablet/TabletTaskReadView.ui.xml b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/tablet/TabletTaskReadView.ui.xml new file mode 100644 index 0000000..d35b070 --- /dev/null +++ b/samples/mobilewebapp/src/main/com/google/gwt/sample/mobilewebapp/client/tablet/TabletTaskReadView.ui.xml
@@ -0,0 +1,147 @@ +<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> +<ui:UiBinder + xmlns:ui="urn:ui:com.google.gwt.uibinder" + xmlns:g="urn:import:com.google.gwt.user.client.ui" + xmlns:app="urn:import:com.google.gwt.sample.mobilewebapp.client.ui"> + + <ui:style> + .outer { + background: #eee; + } + + .title { + background: #393939; + color: white; + padding: 4px 10px; + font-size: 20pt; + } + + .editForm { + padding: 10px; + background: white; + } + + .label { + color: #666; + font-size: 20pt; + padding-bottom: 3px; + } + + .field { + width: 100%; + margin-bottom: 12px; + font-size: 20pt; + } + + .textBoxWrapper { + margin-right: 10px; + } + + .nameBox { + height: 2em; + } + + .notesBox { + height: 4em; + } + + .violation { + color: red; + font-size: 18pt; + } + + .button { + padding-top: 8px; + padding-bottom: 8px; + color: #3f3f3f; + font-size: 20pt; + } + + .dateButton { + text-align: left; + } + + .buttonPanel { + width: 100%; + padding: 10px; + margin-top: 15px; + } + + .saveButton { + width: 100%; + } + + </ui:style> + + <g:DockLayoutPanel + unit="PT"> + <!-- Title. --> + <g:north + size="28"> + <g:Label + addStyleNames="{style.title}">DETAILS</g:Label> + </g:north> + + <g:center> + <g:ScrollPanel + addStyleNames="{style.outer}"> + <g:HTMLPanel> + + <!-- Edit Form. --> + <div + class="{style.editForm}"> + <!-- Task name. --> + <div + class="{style.label}">What</div> + <div + class="{style.textBoxWrapper}"> + <g:Label + addStyleNames="{style.field} {style.nameBox}" + ui:field="nameEditor" /> + </div> + + <!-- Task notes. --> + <div + class="{style.label}">Notes</div> + <div + class="{style.textBoxWrapper}"> + <g:Label + addStyleNames="{style.field} {style.notesBox}" + ui:field="notesEditor" /> + </div> + + <!-- Task due date. --> + <div + class="{style.label}">Due date</div> + <g:DateLabel + addStyleNames="{style.field} {style.button} {style.dateButton}" + ui:field="dueDateEditor" /> + </div> + + <!-- Button panel. --> + <table + class="{style.buttonPanel}" + cellspacing="0" + cellpadding="0"> + <tr> + <td + align="center" + style="width:50%;padding-right:5px;"> + <g:Button + ui:field="editButton" + addStyleNames="{style.button} {style.saveButton}">Edit</g:Button> + </td> + <td + align="center" + style="width:50%;padding-left:5px;"> + + </td> + </tr> + </table> + + </g:HTMLPanel> + </g:ScrollPanel> + </g:center> + </g:DockLayoutPanel> + +</ui:UiBinder>