org.rapidandroid.activity.FormCreator.java Source code

Java tutorial

Introduction

Here is the source code for org.rapidandroid.activity.FormCreator.java

Source

/*
 * Copyright (C) 2009 Dimagi Inc., UNICEF
 *
 * 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 org.rapidandroid.activity;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Locale;

import org.json.JSONException;
import org.json.JSONObject;
import org.rapidandroid.R;
import org.rapidandroid.activity.AddField.ResultConstants;
import org.rapidandroid.content.translation.ModelTranslator;
import org.rapidandroid.view.adapter.FieldViewAdapter;
import org.rapidsms.java.core.model.Field;
import org.rapidsms.java.core.model.Form;
import org.rapidsms.java.core.model.SimpleFieldType;
import org.rapidsms.java.core.parser.IMessageParser;
import org.rapidsms.java.core.parser.SimpleRegexParser;
import org.rapidsms.java.core.parser.StrictRegexParser;
import org.rapidsms.java.core.parser.service.ParsingService.ParserType;
import org.rapidsms.java.core.parser.token.ITokenParser;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;

/**
 * Activity window for creating a new form.
 * 
 * Goal is to create all this form in memory for the user to interact with.
 * 
 * Creation of org.rapidsms.core.model.Form object for insertion into database
 * is the goal.
 * 
 * @author Daniel Myung dmyung@dimagi.com
 * @created Jan 12, 2009
 * 
 */

public class FormCreator extends Activity {
    private static final int MENU_SAVE = Menu.FIRST;
    private static final int MENU_EDIT_FORMS = Menu.FIRST + 1;
    private static final int MENU_ADD_FIELD = Menu.FIRST + 2;
    private static final int MENU_CANCEL = Menu.FIRST + 3;

    public static final int ACTIVITY_ADDFIELD_CANCEL = 0;
    public static final int ACTIVITY_ADDFIELD_ADDED = 1;
    public static final int PREVIOUS_FORM_SELECTED = 2;

    private static final int CONTEXT_MOVE_UP = Menu.FIRST;
    private static final int CONTEXT_MOVE_DOWN = Menu.FIRST + 1;
    private static final int CONTEXT_REMOVE = Menu.FIRST + 2;
    // private static final int CONTEXT_EDIT = ContextMenu.FIRST + 3;

    private static final int DIALOG_FORM_SAVEABLE = -1;
    private static final int DIALOG_FORM_INVALID_NOFORMNAME = 0;
    private static final int DIALOG_FORM_INVALID_NOPREFIX = 1;
    private static final int DIALOG_FORM_INVALID_NOTUNIQUE = 2;
    private static final int DIALOG_FORM_INVALID_NOFIELDS = 3;
    private static final int DIALOG_CONFIRM_CLOSURE = 4;
    private static final int DIALOG_FORM_CREATE_FAIL = 5;

    //   private static final int DIALOGRESULT_CLOSE_INFORMATIONAL = 0;
    //   private static final int DIALOGRESULT_OK_DONT_SAVE = 1;
    //   private static final int DIALOGRESULT_CANCEL_KEEP_WORKING = 2;

    private static final String STATE_FORMNAME = "formname";
    private static final String STATE_PREFIX = "prefix";
    private static final String STATE_DESC = "desc";
    private static final String STATE_PARSER = "parser";

    private ArrayList<Field> mCurrentFields;
    //   private String[] fieldStrings;

    private IMessageParser[] mAllParsers = { new SimpleRegexParser(), new StrictRegexParser() };
    private IMessageParser mChosenParser;
    private boolean mClosing = false;

    private Form selectedForm;

    private int selectedFieldPosition = -1;

    private FieldViewAdapter fieldViewAdapter;

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mCurrentFields = new ArrayList<Field>();

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.form_create);

        // Required onCreate setup
        // add some events to the listview
        ListView lsv = (ListView) findViewById(R.id.lsv_createfields);

        fieldViewAdapter = new FieldViewAdapter(this, mCurrentFields);
        lsv.setAdapter(fieldViewAdapter);

        lsv.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                selectedFieldPosition = arg2;
                return false;
            }

        });

        TextView noFields = new TextView(this);
        noFields.setText("No fields");
        lsv.setEmptyView(noFields);
        registerForContextMenu(lsv);

        initParserSpinner();
        // Set the event listeners for the spinner and the listview
        Spinner spin_forms = (Spinner) findViewById(R.id.spinner_formparser);
        spin_forms.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> parent, View theview, int position, long rowid) {
                spinnerItemSelected(position);
            }

            public void onNothingSelected(AdapterView<?> parent) {
                // blow away the listview's items
                mChosenParser = null;
                // resetCursor = true;
                // loadListViewWithFormData();
            }
        });
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {

        menu.setHeaderTitle("Current Field");
        menu.add(0, CONTEXT_MOVE_UP, 0, "Move Up");
        menu.add(0, CONTEXT_MOVE_DOWN, 0, "Move Down");
        // menu.add(0, CONTEXT_EDIT, 0, "Edit");
        menu.add(0, CONTEXT_REMOVE, 0, "Remove").setIcon(android.R.drawable.ic_menu_delete);

    }

    @Override
    protected synchronized void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        if (!mClosing) {
            saveState();
        } else {
            File f = this.getFileStreamPath("FormCreatorSavedState");
            if (f.exists()) {
                f.delete();
            }
        }
    }

    private void saveState() {
        // TODO Auto-generated method stub
        // this.d
        JSONObject savedstate = new JSONObject();
        EditText etxFormName = (EditText) findViewById(R.id.etx_formname);
        EditText etxFormPrefix = (EditText) findViewById(R.id.etx_formprefix);
        EditText etxDescription = (EditText) findViewById(R.id.etx_description);
        //      ListView lsv = (ListView) findViewById(R.id.lsv_createfields);

        try {
            savedstate.put(STATE_FORMNAME, etxFormName.getText().toString());
            savedstate.put(STATE_PREFIX, etxFormPrefix.getText().toString());
            savedstate.put(STATE_DESC, etxDescription.getText().toString());
            savedstate.put(STATE_PARSER, mChosenParser.getName());

            if (mCurrentFields != null) {
                int numFields = this.mCurrentFields.size();
                for (int i = 0; i < numFields; i++) {
                    Field f = mCurrentFields.get(i);

                    JSONObject fieldobj = new JSONObject();

                    fieldobj.put(AddField.ResultConstants.RESULT_KEY_FIELDNAME, f.getName());
                    fieldobj.put(AddField.ResultConstants.RESULT_KEY_DESCRIPTION, f.getDescription());
                    fieldobj.put(AddField.ResultConstants.RESULT_KEY_FIELDTYPE_ID,
                            ((SimpleFieldType) f.getFieldType()).getId());
                    savedstate.put("Field" + i, fieldobj);
                }
            }

            getIntent().putExtra("current_form", savedstate.toString());

        } catch (JSONException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            Log.d("FormCreator", e1.getMessage());
        }
    }

    @Override
    protected synchronized void onResume() {
        super.onResume();

        Intent intent = getIntent();
        String currentForm = intent.getStringExtra("current_form");
        if (currentForm != null) {
            try {
                String contents = new String(currentForm);
                JSONObject readobject = new JSONObject(contents);

                EditText etxFormName = (EditText) findViewById(R.id.etx_formname);
                EditText etxFormPrefix = (EditText) findViewById(R.id.etx_formprefix);
                EditText etxDescription = (EditText) findViewById(R.id.etx_description);

                etxFormName.setText(readobject.getString(STATE_FORMNAME));
                etxFormPrefix.setText(readobject.getString(STATE_PREFIX));
                etxDescription.setText(readobject.getString(STATE_DESC));
                boolean checkForFields = true;
                int i = 0;
                do {
                    checkForFields = readobject.has("Field" + i);
                    if (checkForFields) {
                        JSONObject fieldBundle = (JSONObject) readobject.get("Field" + i);
                        restoreFieldFromState(fieldBundle);
                        i++;
                    }
                } while (checkForFields);
            } catch (Exception e) {
                Log.e("FOOBAR", e.getMessage(), e);
            }
        }
    }

    /**
     * Gets called from onActivityResult
     * 
     * @param f
     */
    private void restoreForm(Form f) {
        EditText etxFormName = (EditText) findViewById(R.id.etx_formname);
        etxFormName.setText(f.getFormName());

        EditText etxFormPrefix = (EditText) findViewById(R.id.etx_formprefix);
        etxFormPrefix.setText(f.getPrefix());

        EditText etxDescription = (EditText) findViewById(R.id.etx_description);
        etxDescription.setText(f.getDescription());

        Spinner spin_forms = (Spinner) findViewById(R.id.spinner_formparser);
        int cnt = spin_forms.getCount();
        for (int i = 0; i < cnt; i++) {
            if (spin_forms.getItemAtPosition(i).toString().toLowerCase(Locale.getDefault())
                    .contains(f.getParserType().name().toLowerCase(Locale.getDefault())))
                spin_forms.setSelection(i);
        }

        // add fields
        Field[] fields = f.getFields();
        Arrays.sort(fields, new Comparator<Field>() {
            public int compare(Field f1, Field f2) {
                if (f1.getSequenceId() < f2.getSequenceId())
                    return -1;
                else if (f1.getSequenceId() > f2.getSequenceId())
                    return 1;
                return 0;
            }
        });

        for (Field fi : fields) {
            Bundle b = new Bundle();
            b.putString(ResultConstants.RESULT_KEY_FIELDNAME, fi.getName());
            b.putString(ResultConstants.RESULT_KEY_DESCRIPTION, fi.getDescription());
            b.putInt(ResultConstants.RESULT_KEY_FIELDTYPE_ID, ((SimpleFieldType) fi.getFieldType()).getId());

            addNewFieldFromActivity(b);
        }

        // save state so that the "current_form" is in the intent
        // and will therefore be loaded in the onResume call
        saveState();
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onActivityResult(int, int,
     * android.content.Intent)
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, intent);
        Bundle extras = null;
        if (intent != null) {
            extras = intent.getExtras();
        }

        switch (requestCode) {
        case ACTIVITY_ADDFIELD_ADDED:
            if (extras != null) {
                addNewFieldFromActivity(extras);
            }
            break;
        case ACTIVITY_ADDFIELD_CANCEL:
            // do nothing
            break;
        case PREVIOUS_FORM_SELECTED:
            if (extras != null) {
                selectedForm = (Form) extras.getSerializable("selected_form");
                if (selectedForm != null) {
                    restoreForm(selectedForm);
                }
            }
            break;
        }
    }

    private void addNewFieldFromActivity(Bundle extras) {
        Field newField = new Field();
        newField.setFieldId(-1);
        newField.setName(extras.getString(ResultConstants.RESULT_KEY_FIELDNAME).trim());

        newField.setDescription(extras.getString(ResultConstants.RESULT_KEY_DESCRIPTION));
        int fieldTypeID = extras.getInt(ResultConstants.RESULT_KEY_FIELDTYPE_ID);

        ITokenParser fieldtype = ModelTranslator.getFieldType(fieldTypeID);
        newField.setFieldType(fieldtype);

        int seqId = mCurrentFields.size();
        if (seqId > 0) {
            seqId = seqId - 1;
        }
        newField.setSequenceId(seqId);
        mCurrentFields.add(newField);

        fieldViewAdapter.notifyDataSetChanged();
    }

    private void restoreFieldFromState(JSONObject fieldjson) {
        if (mCurrentFields == null) {
            mCurrentFields = new ArrayList<Field>();
        }
        try {
            Field newField = new Field();
            newField.setFieldId(-1);
            newField.setName(fieldjson.getString(ResultConstants.RESULT_KEY_FIELDNAME));
            newField.setDescription(fieldjson.getString(ResultConstants.RESULT_KEY_DESCRIPTION));
            int fieldTypeID = fieldjson.getInt(ResultConstants.RESULT_KEY_FIELDTYPE_ID);
            ITokenParser fieldtype = ModelTranslator.getFieldType(fieldTypeID);
            newField.setFieldType(fieldtype);

            int listSize = mCurrentFields.size();

            for (int i = 0; i < listSize; i++) {
                Field existingField = mCurrentFields.get(i);
                if (existingField.getName().equals(newField.getName())) {
                    return;
                }
            }
            if (listSize > 0) {
                listSize = listSize - 1;
            }
            newField.setSequenceId(listSize);

            mCurrentFields.add(newField);

            fieldViewAdapter.notifyDataSetChanged();
            // updateFieldList();
        } catch (Exception ex) {
            Log.d("FormCreator", ex.getMessage());
        }
    }

    /**
     * 
     */
    // private void updateFieldList() {
    // ListView lsv = (ListView) findViewById(R.id.lsv_createfields);
    // if (mCurrentFields == null) {
    // mCurrentFields = new Vector<Field>();
    // }
    //
    // Field[] fieldArray = this.mCurrentFields
    // .toArray(new Field[mCurrentFields.size()]);
    // lsv.setAdapter(new FieldViewAdapter(this, fieldArray));
    // }

    // This is a call to the DB to get all the forms that this form can support.
    private void initParserSpinner() {
        // The steps:
        // get the spinner control from the layouts
        Spinner spin_forms = (Spinner) findViewById(R.id.spinner_formparser);
        // Get an array of forms from the DB
        // in the current iteration, it's mForms
        // this.mAllParsers = ModelTranslator.getAllForms();

        String[] monitors = new String[mAllParsers.length];

        for (int i = 0; i < mAllParsers.length; i++) {
            monitors[i] = "Parse Mode: " + mAllParsers[i].getName();
        }

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,
                monitors);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // apply it to the spinner
        spin_forms.setAdapter(adapter);
    }

    private void spinnerItemSelected(int position) {
        mChosenParser = mAllParsers[position];
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, MENU_SAVE, 0, R.string.formeditor_menu_save).setIcon(android.R.drawable.ic_menu_save);
        menu.add(0, MENU_EDIT_FORMS, 0, R.string.formeditor_menu_edit_forms)
                .setIcon(android.R.drawable.ic_menu_view);
        menu.add(0, MENU_ADD_FIELD, 0, R.string.formeditor_menu_add_field).setIcon(android.R.drawable.ic_menu_add);
        menu.add(0, MENU_CANCEL, 0, R.string.formeditor_menu_cancel)
                .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
        return true;
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);
        switch (item.getItemId()) {
        case MENU_SAVE:
            int formStatus = checkFormIsSaveable();
            if (formStatus == FormCreator.DIALOG_FORM_SAVEABLE) {
                doSave();
                setResult(0);
                File f = this.getFileStreamPath("FormCreatorSavedState");
                if (f.exists()) {
                    f.delete();
                }
                mClosing = true;
                finish();
            } else {
                this.showDialog(formStatus);
            }
            return true;
        case MENU_EDIT_FORMS:
            Intent in = new Intent(this, FormListView.class);
            startActivityForResult(in, PREVIOUS_FORM_SELECTED);
            return true;
        case MENU_ADD_FIELD:
            Intent intent = new Intent(this, AddField.class);
            // mUpdatedFromActivity = true;
            if (mCurrentFields != null) {
                int len = this.mCurrentFields.size();
                for (int i = 0; i < len; i++) {
                    intent.putExtra(mCurrentFields.get(i).getName(), 0);
                }
            }
            startActivityForResult(intent, ACTIVITY_ADDFIELD_ADDED);
            return true;
        case MENU_CANCEL:
            mClosing = true;
            finish();
            return true;
        }

        return true;
    }

    private int checkFormIsSaveable() {
        EditText etxFormName = (EditText) findViewById(R.id.etx_formname);
        EditText etxFormPrefix = (EditText) findViewById(R.id.etx_formprefix);
        // EditText etxDescription =
        // (EditText)findViewById(R.id.etx_description);
        //      ListView lsvFields = (ListView) findViewById(R.id.lsv_createfields);

        if (etxFormName.getText().length() == 0) {
            return FormCreator.DIALOG_FORM_INVALID_NOFORMNAME;
        }
        if (etxFormPrefix.getText().length() == 0) {
            return FormCreator.DIALOG_FORM_INVALID_NOPREFIX;
        }

        if (this.mCurrentFields.size() == 0) {
            return FormCreator.DIALOG_FORM_INVALID_NOFIELDS;
        }

        // String prefixCandidate = etxFormPrefix.getText().toString();
        // String nameCandidate = etxFormName.getText().toString();
        //
        // if (ModelTranslator.doesFormExist(prefixCandidate, nameCandidate)) {
        // return FormCreator.DIALOG_FORM_INVALID_NOTUNIQUE;
        // } else {
        // return FormCreator.DIALOG_FORM_SAVEABLE;
        // }
        return FormCreator.DIALOG_FORM_SAVEABLE;
    }

    /**
     * @param prefixCandidate
     * @param nameCandidate
     * @return
     */

    private void doSave() {
        EditText etxFormName = (EditText) findViewById(R.id.etx_formname);
        EditText etxFormPrefix = (EditText) findViewById(R.id.etx_formprefix);
        EditText etxDescription = (EditText) findViewById(R.id.etx_description);
        Spinner spinnerParserType = (Spinner) findViewById(R.id.spinner_formparser);
        int parserPosition = spinnerParserType.getSelectedItemPosition();

        ParserType parserType = ParserType
                .valueOf(mAllParsers[parserPosition].getName().toUpperCase(Locale.getDefault()));

        Form formToSave = new Form();
        formToSave.setFormName(etxFormName.getText().toString().trim());
        formToSave.setPrefix(etxFormPrefix.getText().toString().trim());
        formToSave.setDescription(etxDescription.getText().toString().trim());
        formToSave.setParserType(parserType);
        // (Message[])parsedMessages.keySet().toArray(new
        // Message[parsedMessages.keySet().size()]);
        Field[] fieldArray = this.mCurrentFields.toArray(new Field[mCurrentFields.size()]);
        formToSave.setFields(fieldArray);

        try {
            if (selectedForm != null) {
                formToSave.setFormId(selectedForm.getFormId());
                ModelTranslator.editFormToDatabase(formToSave);
            } else {
                ModelTranslator.addFormToDatabase(formToSave);
            }
        } catch (Exception ex) {
            Log.e("FOOBAR", ex.getMessage(), ex);
            showDialog(DIALOG_FORM_CREATE_FAIL);
        }
    }

    @Override
    // http://www.anddev.org/tinytutcontextmenu_for_listview-t4019.html
    // UGH, things changed from .9 to 1.0
    public boolean onContextItemSelected(MenuItem item) {

        // some sanity checks:
        ListView lsvFields = (ListView) findViewById(R.id.lsv_createfields);
        if (lsvFields.getCount() == 0 || this.mCurrentFields == null || this.mCurrentFields.size() == 0) {
            return true;
        }

        if (selectedFieldPosition == -1) {
            return true;
        }

        //      AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

        switch (item.getItemId()) {
        // TODO: IMPLEMENT CONTEXT MENU
        case CONTEXT_MOVE_UP:

            moveFieldUp(selectedFieldPosition);

            break;
        case CONTEXT_MOVE_DOWN:

            moveFieldDown(selectedFieldPosition);

            break;
        case CONTEXT_REMOVE:
            removeField(selectedFieldPosition);
            break;
        default:
            return super.onContextItemSelected(item);
        }
        return true;
    }

    /**
     * @param position
     */
    private void removeField(int position) {
        mCurrentFields.remove(position);
        resetFieldSequences();
    }

    /**
     * 
     */
    private void moveFieldDown(int position) {
        if (position < mCurrentFields.size() - 1) {
            Field fieldToMove = mCurrentFields.get(position);
            mCurrentFields.remove(position);
            int newposition = position + 1;
            if (newposition >= mCurrentFields.size()) {
                mCurrentFields.add(fieldToMove);
            } else {
                mCurrentFields.add(newposition, fieldToMove);
            }
            resetFieldSequences();
        }
    }

    /**
     * @param position
     */
    private void moveFieldUp(int position) {
        // TODO Auto-generated method stub
        if (position > 0) {
            Field fieldToMove = mCurrentFields.get(position);
            mCurrentFields.remove(position);
            int newposition = position - 1;
            if (newposition <= 0) {
                mCurrentFields.add(0, fieldToMove);
            } else {
                mCurrentFields.add(newposition, fieldToMove);
            }
            resetFieldSequences();
        }
    }

    private void resetFieldSequences() {
        int len = mCurrentFields.size();
        for (int i = 0; i < len; i++) {
            Field f = mCurrentFields.get(i);
            f.setSequenceId(i);
        }
        fieldViewAdapter.notifyDataSetChanged();// updateFieldList();
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        super.onCreateDialog(id);
        String title = "";
        String message = "";

        switch (id) {
        case DIALOG_FORM_INVALID_NOFIELDS:
            title = "Invalid form";
            message = "You must have at least one field for this form to save";
            break;
        case DIALOG_FORM_INVALID_NOFORMNAME:
            title = "Invalid form";
            message = "You must enter a formname";
            break;
        case DIALOG_FORM_INVALID_NOPREFIX:
            title = "Invalid form";
            message = "You must enter a prefix";
            break;
        case DIALOG_FORM_INVALID_NOTUNIQUE:
            title = "Invalid form";
            message = "The form of this name and prefix already exists";
            break;
        case DIALOG_FORM_CREATE_FAIL:
            title = "Form creation failed";
            message = "Unable to create the form and its support tables.  Check the logs.";
            return new AlertDialog.Builder(FormCreator.this).setTitle(title).setMessage(message)
                    .setPositiveButton("Ok", null).create();
        case DIALOG_CONFIRM_CLOSURE:
            // for confirm closure, we actually just return the dialog as we
            // want it here.
            title = "Confirm Closure";
            message = "Are you sure you want to close without saving changes?";
            return new AlertDialog.Builder(FormCreator.this).setTitle(title).setMessage(message)
                    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            finish();
                        }
                    }).setNegativeButton("No, keep working", null).create();
        default:
            return null;

        }
        return new AlertDialog.Builder(FormCreator.this).setTitle(title).setMessage(message)
                .setPositiveButton("OK", null).create();

    }

    @Override
    public void onBackPressed() {
        AlertDialog dialog = new AlertDialog.Builder(this).create();

        dialog.setMessage("Save Changes First?");
        dialog.setButton(DialogInterface.BUTTON_POSITIVE, "Yes", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface d, int which) {
                doSave();
                finish();
            }
        });

        dialog.setButton(DialogInterface.BUTTON_NEUTRAL, "No", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface d, int which) {
                finish();
            }
        });

        dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface d, int which) {
            }
        });
        dialog.show();
    }

}