165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.form; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.old.Action; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.old.ActionAdapter; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.old.ActionFragment; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.old.ContentFragment; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.old.DialogActivity; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport com.android.tv.settings.dialog.old.EditTextFragment; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Fragment; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Intent; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle; 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Log; 3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.KeyEvent; 3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.TextView; 3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.ArrayList; 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.Stack; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Implements a MultiPagedForm. 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * <p> 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * This is a multi-paged form that can be used for fragment transitions used in 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * such as setup, add network, and add credit cards 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic abstract class MultiPagedForm extends DialogActivity implements ActionAdapter.Listener, 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane FormPageResultListener, FormResultListener { 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int INTENT_FORM_PAGE_DATA_REQUEST = 1; 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String TAG = "MultiPagedForm"; 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private enum Key { 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane DONE, CANCEL 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected final ArrayList<FormPage> mFormPages = new ArrayList<FormPage>(); 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Stack<Object> mFlowStack = new Stack<Object>(); 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private ActionAdapter.Listener mListener = null; 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onActionClicked(Action action) { 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mListener != null) { 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mListener.onActionClicked(action); 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onBackPressed() { 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // If we don't have a page to go back to, finish as cancelled. 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mFlowStack.size() < 1) { 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setResult(RESULT_CANCELED); 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane finish(); 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return; 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Pop the current location off the stack. 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFlowStack.pop(); 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Peek at the previous location on the stack. 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Object lastLocation = mFlowStack.isEmpty() ? null : mFlowStack.peek(); 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (lastLocation instanceof FormPage && !mFormPages.contains(lastLocation)) { 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onBackPressed(); 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane displayCurrentStep(false); 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mFlowStack.isEmpty()) { 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setResult(RESULT_CANCELED); 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane finish(); 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onBundlePageResult(FormPage page, Bundle bundleResults) { 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Complete the form with the results. 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane page.complete(bundleResults); 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Indicate that we've completed a page. If we get back false it means 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // the data was invalid and the page must be filled out again. 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Otherwise, we move on to the next page. 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (!onPageComplete(page)) { 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane displayCurrentStep(false); 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane performNextStep(); 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onFormComplete() { 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onComplete(mFormPages); 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onFormCancelled() { 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onCancel(mFormPages); 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void onCreate(Bundle savedInstanceState) { 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane performNextStep(); 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onCreate(savedInstanceState); 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void onActivityResult(int requestCode, int resultCode, Intent data) { 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (requestCode == INTENT_FORM_PAGE_DATA_REQUEST) { 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (resultCode == RESULT_OK) { 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Object currentLocation = mFlowStack.peek(); 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (currentLocation instanceof FormPage) { 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane FormPage page = (FormPage) currentLocation; 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle results = data == null ? null : data.getExtras(); 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (data == null) { 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.w(TAG, "Intent result was null!"); 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (results == null) { 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.w(TAG, "Intent result extras were null!"); 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (!results.containsKey(FormPage.DATA_KEY_SUMMARY_STRING)) { 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.w(TAG, "Intent result extras didn't have the result summary key!"); 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onBundlePageResult(page, results); 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.e(TAG, "Our current location wasn't on the top of the stack!"); 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onBackPressed(); 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Called when a form page completes. If necessary, add or remove any pages 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * from the form before this call completes. If all pages are complete when 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * onPageComplete returns, the form will be considered finished and the form 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * results will be displayed for confirmation. 15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param formPage the page that was completed. 15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return true if the form can continue to the next incomplete page, or 15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * false if the data input is invalid and the form page must be 15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * completed again. 15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected abstract boolean onPageComplete(FormPage formPage); 15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Called when all form pages have been completed and the user has accepted 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * them. 16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param formPages the pages that were completed. Any pages removed during 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * the completion of the form are not included. 16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected abstract void onComplete(ArrayList<FormPage> formPages); 16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Called when all form pages have been completed but the user wants to 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * cancel the form and discard the results. 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param formPages the pages that were completed. Any pages removed during 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * the completion of the form are not included. 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected abstract void onCancel(ArrayList<FormPage> formPages); 17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Override this to fully customize the display of the page. 17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param formPage the page that should be displayed. 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param listener the listener to notify when the page is complete. 18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void displayPage(FormPage formPage, FormPageResultListener listener, 18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean forward) { 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane switch (formPage.getType()) { 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case PASSWORD_INPUT: 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setContentAndActionFragments(getContentFragment(formPage), 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane createPasswordEditTextFragment(formPage)); 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case TEXT_INPUT: 19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setContentAndActionFragments(getContentFragment(formPage), 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane createEditTextFragment(formPage)); 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case MULTIPLE_CHOICE: 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setContentAndActionFragments(getContentFragment(formPage), 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane createActionFragment(formPage)); 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case INTENT: 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane default: 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Override this to fully customize the display of the form results. 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param formPages the pages that were whose results should be displayed. 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param listener the listener to notify when the form is complete or has been cancelled. 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void displayFormResults(ArrayList<FormPage> formPages, FormResultListener listener) { 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setContentAndActionFragments(createResultContentFragment(), 21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane createResultActionFragment(formPages, listener)); 21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return the main title for this multipage form. 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected String getMainTitle() { 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ""; 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return the action title to indicate the form is correct. 22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected String getFormIsCorrectActionTitle() { 22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ""; 22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return the action title to indicate the form should be canceled and its 23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * results discarded. 23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected String getFormCancelActionTitle() { 23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ""; 23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Override this to provide a custom Fragment for displaying the content 23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * portion of the page. 24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param formPage the page the Fragment should display. 24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return a Fragment for identifying the current step. 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected Fragment getContentFragment(FormPage formPage) { 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ContentFragment.newInstance(formPage.getTitle()); 24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Override this to provide a custom Fragment for displaying the content 25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * portion of the form results. 25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return a Fragment for giving context to the result page. 25365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 25465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected Fragment getResultContentFragment() { 25565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ContentFragment.newInstance(getMainTitle()); 25665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 25865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 25965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Override this to provide a custom EditTextFragment for displaying a form 26065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * page for password input. Warning: the OnEditorActionListener of this 26165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * fragment will be overridden. 26265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param initialText initial text that should be displayed in the edit 26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * field. 26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return an EditTextFragment for password input. 26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected EditTextFragment getPasswordEditTextFragment(String initialText) { 26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return EditTextFragment.newInstance(null, initialText, true /* password */); 26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Override this to provide a custom EditTextFragment for displaying a form 27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * page for text input. Warning: the OnEditorActionListener of this fragment 27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * will be overridden. 27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param initialText initial text that should be displayed in the edit 27765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * field. 27865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return an EditTextFragment for custom input. 27965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 28065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected EditTextFragment getEditTextFragment(String initialText) { 28165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return EditTextFragment.newInstance(null, initialText); 28265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 28365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 28465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 28565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Override this to provide a custom ActionFragment for displaying a form 28665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * page for a list of choices. 28765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 28865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param formPage the page the ActionFragment is for. 28965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param actions the actions the ActionFragment should display. 29065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param selectedAction the action in actions that is currently selected, 29165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * or null if none are selected. 29265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return an ActionFragment displaying the given actions. 29365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 29465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected ActionFragment getActionFragment(FormPage formPage, ArrayList<Action> actions, 29565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Action selectedAction) { 29665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ActionFragment actionFragment = ActionFragment.newInstance(actions); 29765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (selectedAction != null) { 29865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int indexOfSelection = actions.indexOf(selectedAction); 29965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (indexOfSelection >= 0) { 30065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // TODO: Set initial focus action: 30165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // actionFragment.setSelection(indexOfSelection); 30265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return actionFragment; 30565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 30665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 30765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 30865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Override this to provide a custom ActionFragment for displaying the list 30965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * of page results. 31065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 31165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param actions the actions the ActionFragment should display. 31265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @return an ActionFragment displaying the given form results. 31365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 31465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected ActionFragment getResultActionFragment(ArrayList<Action> actions) { 31565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ActionFragment.newInstance(actions); 31665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 31765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 31865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 31965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Adds the page to the end of the form. Only call this before onCreate or 32065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * during onPageComplete. 32165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 32265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param formPage the page to add to the end of the form. 32365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 32465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void addPage(FormPage formPage) { 32565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFormPages.add(formPage); 32665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 32865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 32965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Removes the page from the form. Only call this before onCreate or during 33065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * onPageComplete. 33165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 33265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param formPage the page to remove from the form. 33365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 33465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void removePage(FormPage formPage) { 33565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFormPages.remove(formPage); 33665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 33765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 33865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 33965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Clears all pages from the form. Only call this before onCreate or during 34065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * onPageComplete. 34165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 34265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void clear() { 34365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFormPages.clear(); 34465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 34565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 34665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 34765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Clears all pages after the given page from the form. Only call this 34865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * before onCreate or during onPageComplete. 34965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 35065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param formPage all pages after this page in the form will be removed 35165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * from the form. 35265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 35365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void clearAfter(FormPage formPage) { 35465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int indexOfPage = mFormPages.indexOf(formPage); 35565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (indexOfPage >= 0) { 35665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = mFormPages.size() - 1; i > indexOfPage; i--) { 35765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFormPages.remove(i); 35865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 36265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 36365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Stop display the currently displayed page. Note that this does <b>not</b> 36465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * remove the form page from the set of form pages for this form, it is just 36565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * no longer displayed and no replacement is provided, the screen should be 36665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * empty after this method. 36765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 36865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected void undisplayCurrentPage() { 36965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void performNextStep() { 37265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // First see if there are any incomplete form pages. 37465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane FormPage nextIncompleteStep = findNextIncompleteStep(); 37565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // If all the pages we have are complete, display the results. 37765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (nextIncompleteStep == null) { 37865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFlowStack.push(this); 37965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 38065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFlowStack.push(nextIncompleteStep); 38165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane displayCurrentStep(true); 38365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 38565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private FormPage findNextIncompleteStep() { 38665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = 0, size = mFormPages.size(); i < size; i++) { 38765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane FormPage formPage = mFormPages.get(i); 38865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (!formPage.isComplete()) { 38965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return formPage; 39065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 39365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 39565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void displayCurrentStep(boolean forward) { 39665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 39765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (!mFlowStack.isEmpty()) { 39865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Object currentLocation = mFlowStack.peek(); 39965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 40065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (currentLocation instanceof MultiPagedForm) { 40165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane displayFormResults(mFormPages, this); 40265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (currentLocation instanceof FormPage) { 40365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane FormPage page = (FormPage) currentLocation; 40465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (page.getType() == FormPage.Type.INTENT) { 40565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane startActivityForResult(page.getIntent(), INTENT_FORM_PAGE_DATA_REQUEST); 40665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 40765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane displayPage(page, this, forward); 40865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 40965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.d("JMATT", "Finishing from here!"); 41065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // If this is an unexpected type, something went wrong, finish as 41165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // cancelled. 41265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setResult(RESULT_CANCELED); 41365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane finish(); 41465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 41565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 41665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane undisplayCurrentPage(); 41765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 41865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 41965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 42065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 42165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Fragment createResultContentFragment() { 42265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getResultContentFragment(); 42365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 42465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 42565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Fragment createResultActionFragment(final ArrayList<FormPage> formPages, 42665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane final FormResultListener listener) { 42765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 42865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mListener = new ActionAdapter.Listener() { 42965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 43065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 43165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onActionClicked(Action action) { 43265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Key key = getKeyFromKey(action.getKey()); 43365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (key != null) { 43465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane switch (key) { 43565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case DONE: 43665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane listener.onFormComplete(); 43765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 43865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case CANCEL: 43965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane listener.onFormCancelled(); 44065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 44165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane default: 44265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 44365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 44565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String formPageKey = action.getKey(); 44665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = 0, size = formPages.size(); i < size; i++) { 44765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane FormPage formPage = formPages.get(i); 44865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (formPageKey.equals(formPage.getTitle())) { 44965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFlowStack.push(formPage); 45065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane displayCurrentStep(true); 45165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 45265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 45765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 45865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getResultActionFragment(getResultActions()); 45965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Key getKeyFromKey(String key) { 46265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 46365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return Key.valueOf(key); 46465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (IllegalArgumentException iae) { 46565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 46665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private ArrayList<Action> getActions(FormPage formPage) { 47065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<Action> actions = new ArrayList<Action>(); 47165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (String choice : formPage.getChoices()) { 47265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder().key(choice).title(choice).build()); 47365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return actions; 47565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 47765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private ArrayList<Action> getResultActions() { 47865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<Action> actions = new ArrayList<Action>(); 47965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = 0, size = mFormPages.size(); i < size; i++) { 48065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane FormPage formPage = mFormPages.get(i); 48165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder().key(formPage.getTitle()) 48265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(formPage.getDataSummary()).description(formPage.getTitle()).build()); 48365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder().key(Key.CANCEL.name()) 48565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(getFormCancelActionTitle()).build()); 48665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder().key(Key.DONE.name()) 48765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(getFormIsCorrectActionTitle()).build()); 48865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return actions; 48965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 49065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 49165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Fragment createActionFragment(final FormPage formPage) { 49265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mListener = new ActionAdapter.Listener() { 49365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 49465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 49565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onActionClicked(Action action) { 49665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane handleStringPageResult(formPage, action.getKey()); 49765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 49865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 49965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 50065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<Action> actions = getActions(formPage); 50165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 50265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Action selectedAction = null; 50365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String choice = formPage.getDataSummary(); 50465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = 0, size = actions.size(); i < size; i++) { 50565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Action action = actions.get(i); 50665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (action.getKey().equals(choice)) { 50765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane selectedAction = action; 50865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 50965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 51065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 51165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 51265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return getActionFragment(formPage, actions, selectedAction); 51365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 51465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 51565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Fragment createPasswordEditTextFragment(final FormPage formPage) { 51665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane EditTextFragment editTextFragment = getPasswordEditTextFragment(formPage.getDataSummary()); 51765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane attachListeners(editTextFragment, formPage); 51865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return editTextFragment; 51965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 52065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 52165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Fragment createEditTextFragment(final FormPage formPage) { 52265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane EditTextFragment editTextFragment = getEditTextFragment(formPage.getDataSummary()); 52365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane attachListeners(editTextFragment, formPage); 52465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return editTextFragment; 52565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 52665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 52765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void attachListeners(EditTextFragment editTextFragment, final FormPage formPage) { 52865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 52965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane editTextFragment.setOnEditorActionListener(new TextView.OnEditorActionListener() { 53065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 53165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 53265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 53365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane handleStringPageResult(formPage, v.getText().toString()); 53465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return true; 53565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 53665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }); 53765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 53865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 53965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void handleStringPageResult(FormPage page, String stringResults) { 54065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle bundleResults = new Bundle(); 54165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane bundleResults.putString(FormPage.DATA_KEY_SUMMARY_STRING, stringResults); 54265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane onBundlePageResult(page, bundleResults); 54365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 54465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 545