Best Android App InstaSquare Lite for full-size publication of photos in Instagram, Facebook, Twitter. Run the android application on PC. You can through the android emulator Droid4X.

root/trunk/rapidandroid/org.rapidandroid/src/org/rapidandroid/activity/FormCreator.java @ 133

Revision 133, 19.2 KB (checked in by dmyung, 10 months ago)

applying GPL license to source

Line 
1/*
2 *    rapidandroid - SMS gateway for the android platform
3 *    Copyright (C) 2009 Dimagi Inc., UNICEF
4 *
5 *   This program is free software: you can redistribute it and/or modify
6 *   it under the terms of the GNU General Public License as published by
7 *   the Free Software Foundation, either version 3 of the License, or
8 *   (at your option) any later version.
9 *
10 *   This program is distributed in the hope that it will be useful,
11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *   GNU General Public License for more details.
14 *
15 *   You should have received a copy of the GNU General Public License
16 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19/**
20 *
21 */
22package org.rapidandroid.activity;
23
24import java.io.File;
25import java.io.FileInputStream;
26import java.io.FileNotFoundException;
27import java.io.FileOutputStream;
28import java.io.IOException;
29import java.io.InputStreamReader;
30import java.util.Vector;
31
32import org.json.JSONException;
33import org.json.JSONObject;
34import org.rapidandroid.R;
35import org.rapidandroid.activity.AddField.ResultConstants;
36import org.rapidandroid.content.translation.ModelTranslator;
37import org.rapidandroid.view.adapter.FieldViewAdapter;
38import org.rapidsms.java.core.model.Field;
39import org.rapidsms.java.core.model.Form;
40import org.rapidsms.java.core.model.SimpleFieldType;
41import org.rapidsms.java.core.parser.service.ParsingService.ParserType;
42import org.rapidsms.java.core.parser.token.ITokenParser;
43
44import android.app.Activity;
45import android.app.AlertDialog;
46import android.app.Dialog;
47import android.content.Context;
48import android.content.DialogInterface;
49import android.content.Intent;
50
51import android.os.Bundle;
52import android.util.Log;
53import android.view.ContextMenu;
54import android.view.Menu;
55import android.view.MenuItem;
56import android.view.View;
57import android.view.Window;
58import android.view.ContextMenu.ContextMenuInfo;
59import android.widget.AdapterView;
60import android.widget.EditText;
61import android.widget.ListView;
62import android.widget.TextView;
63import android.widget.AdapterView.OnItemClickListener;
64
65/**
66 * Activity window for creating a new form.
67 *
68 * Goal is to create all this form in memory for the user to interact with.
69 *
70 * Creation of org.rapidsms.core.model.Form object for insertion into database
71 * is the goal.
72 *
73 * @author Daniel Myung [email protected]
74 * @created Jan 12, 2009
75 *
76 */
77
78public class FormCreator extends Activity {
79        private static final int MENU_SAVE = Menu.FIRST;
80        private static final int MENU_ADD_FIELD = Menu.FIRST + 1;
81        private static final int MENU_CANCEL = Menu.FIRST + 2;
82
83        public static final int ACTIVITY_ADDFIELD_CANCEL = 0;
84        public static final int ACTIVITY_ADDFIELD_ADDED = 1;
85
86        private static final int CONTEXT_MOVE_UP = Menu.FIRST;
87        private static final int CONTEXT_MOVE_DOWN = Menu.FIRST + 1;
88        private static final int CONTEXT_REMOVE = Menu.FIRST + 2;
89        // private static final int CONTEXT_EDIT = ContextMenu.FIRST + 3;
90
91        private static final int DIALOG_FORM_SAVEABLE = -1;
92        private static final int DIALOG_FORM_INVALID_NOFORMNAME = 0;
93        private static final int DIALOG_FORM_INVALID_NOPREFIX = 1;
94        private static final int DIALOG_FORM_INVALID_NOTUNIQUE = 2;
95        private static final int DIALOG_FORM_INVALID_NOFIELDS = 3;
96        private static final int DIALOG_CONFIRM_CLOSURE = 4;
97        private static final int DIALOG_FORM_CREATE_FAIL = 5;
98
99        private static final int DIALOGRESULT_CLOSE_INFORMATIONAL = 0;
100        private static final int DIALOGRESULT_OK_DONT_SAVE = 1;
101        private static final int DIALOGRESULT_CANCEL_KEEP_WORKING = 2;
102
103        private static final String STATE_FORMNAME = "formname";
104        private static final String STATE_PREFIX = "prefix";
105        private static final String STATE_DESC = "desc";
106
107        private Vector<Field> mCurrentFields;
108        private String[] fieldStrings;
109
110        private boolean mClosing = false;
111
112        private int selectedFieldPosition = -1;
113
114        /*
115         * (non-Javadoc)
116         *
117         * @see android.app.Activity#onCreate(android.os.Bundle)
118         */
119        @Override
120        protected void onCreate(Bundle savedInstanceState) {
121                super.onCreate(savedInstanceState);
122                requestWindowFeature(Window.FEATURE_NO_TITLE);
123                setContentView(R.layout.form_create);
124
125                // Required onCreate setup
126                // add some events to the listview
127                ListView lsv = (ListView) findViewById(R.id.lsv_createfields);
128                lsv.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
129                        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
130                                menu.setHeaderTitle("Current Field");
131                                menu.add(0, CONTEXT_MOVE_UP, 0, "Move Up");
132                                menu.add(0, CONTEXT_MOVE_DOWN, 0, "Move Down");
133                                // menu.add(0, CONTEXT_EDIT, 0, "Edit");
134                                menu.add(0, CONTEXT_REMOVE, 0, "Remove").setIcon(android.R.drawable.ic_menu_delete);
135
136                        }
137                });
138
139                lsv.setOnItemClickListener(new OnItemClickListener() {
140
141                        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
142                                // TODO Auto-generated method stub
143                                selectedFieldPosition = arg2;
144                        }
145
146                });
147                TextView noFields = new TextView(this);
148                noFields.setText("No fields");
149                lsv.setEmptyView(noFields);
150                updateFieldList();
151        }
152
153        @Override
154        protected synchronized void onPause() {
155                // TODO Auto-generated method stub
156                super.onPause();
157                if (!mClosing) {
158                        saveState();
159                } else {
160                        File f = this.getFileStreamPath("FormCreatorSavedState");
161                        if (f.exists()) {
162                                f.delete();
163                        }
164                }
165        }
166
167        // dmyung - since the savestate and onresume rely upon the database, and we
168        // are only doing the formcreate in memory, we will not implement these.
169        private void saveState() {
170                // TODO Auto-generated method stub
171                // this.d
172                JSONObject savedstate = new JSONObject();
173                EditText etxFormName = (EditText) findViewById(R.id.etx_formname);
174                EditText etxFormPrefix = (EditText) findViewById(R.id.etx_formprefix);
175                EditText etxDescription = (EditText) findViewById(R.id.etx_description);
176
177                ListView lsv = (ListView) findViewById(R.id.lsv_createfields);
178
179                try {
180                        savedstate.put(STATE_FORMNAME, etxFormName.getText().toString());
181                        savedstate.put(STATE_PREFIX, etxFormPrefix.getText().toString());
182                        savedstate.put(STATE_DESC, etxDescription.getText().toString());
183
184                        if (mCurrentFields != null) {
185                                int numFields = this.mCurrentFields.size();
186                                for (int i = 0; i < numFields; i++) {
187                                        Field f = mCurrentFields.get(i);
188
189                                        JSONObject fieldobj = new JSONObject();
190
191                                        fieldobj.put(AddField.ResultConstants.RESULT_KEY_FIELDNAME, f.getName());
192                                        fieldobj.put(AddField.ResultConstants.RESULT_KEY_DESCRIPTION, f.getDescription());
193                                        fieldobj.put(AddField.ResultConstants.RESULT_KEY_FIELDTYPE_ID,
194                                                                        ((SimpleFieldType) f.getFieldType()).getId());
195
196                                        savedstate.put("Field" + i, fieldobj);
197                                }
198                        }
199                } catch (JSONException e1) {
200                        // TODO Auto-generated catch block
201                        e1.printStackTrace();
202                        Log.d("FormCreator", e1.getMessage());
203                }
204
205                try {
206                        FileOutputStream fos = this.openFileOutput("FormCreatorSavedState", Context.MODE_PRIVATE);
207                        fos.write(savedstate.toString().getBytes());
208                } catch (FileNotFoundException e) {
209                        // TODO Auto-generated catch block
210                        e.printStackTrace();
211                        Log.d("FormCreator", e.getMessage());
212                } catch (IOException e) {
213                        // TODO Auto-generated catch block
214                        e.printStackTrace();
215                        Log.d("FormCreator", e.getMessage());
216                }
217        }
218
219        @Override
220        protected synchronized void onResume() {
221                super.onResume();
222                try {
223                        File f = this.getFileStreamPath("FormCreatorSavedState");
224                        if (f.exists()) {
225                                // mCurrentFields = new Vector<Field>();
226                                FileInputStream fin = this.openFileInput("FormCreatorSavedState");
227                                InputStreamReader irdr = new InputStreamReader(fin); // promote
228
229                                int size = (int) fin.getChannel().size();
230                                char[] data = new char[size]; // allocate char array of right
231                                // size
232                                irdr.read(data, 0, size); // read into char array
233                                irdr.close();
234
235                                String contents = new String(data);
236                                JSONObject readobject = new JSONObject(contents);
237
238                                EditText etxFormName = (EditText) findViewById(R.id.etx_formname);
239                                EditText etxFormPrefix = (EditText) findViewById(R.id.etx_formprefix);
240                                EditText etxDescription = (EditText) findViewById(R.id.etx_description);
241
242                                etxFormName.setText(readobject.getString(STATE_FORMNAME));
243                                etxFormPrefix.setText(readobject.getString(STATE_PREFIX));
244                                etxDescription.setText(readobject.getString(STATE_DESC));
245                                boolean checkForFields = true;
246                                int i = 0;
247                                do {
248                                        checkForFields = readobject.has("Field" + i);
249                                        if (checkForFields) {
250                                                JSONObject fieldBundle = (JSONObject) readobject.get("Field" + i);
251                                                restoreFieldFromState(fieldBundle);
252                                                i++;
253                                        }
254                                } while (checkForFields);
255                                f.delete();
256                        }
257                } catch (Exception ex) {
258                        Log.d("FormCreator", ex.getMessage());
259                }
260        }
261
262        /*
263         * (non-Javadoc)
264         *
265         * @see android.app.Activity#onActivityResult(int, int,
266         * android.content.Intent)
267         */
268        @Override
269        protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
270                // TODO Auto-generated method stub
271                super.onActivityResult(requestCode, resultCode, intent);
272                Bundle extras = null;
273                if (intent != null) {
274                        extras = intent.getExtras();
275                }
276
277                switch (requestCode) {
278                        case ACTIVITY_ADDFIELD_ADDED:
279                                if (extras != null) {
280                                        addNewFieldFromActivity(extras);
281                                }
282                                break;
283                        case ACTIVITY_ADDFIELD_CANCEL:
284                                // do nothing
285                                break;
286                }
287        }
288
289        private void addNewFieldFromActivity(Bundle extras) {
290                if (mCurrentFields == null) {
291                        mCurrentFields = new Vector<Field>();
292                }
293
294                Field newField = new Field();
295                newField.setFieldId(-1);
296                newField.setName(extras.getString(ResultConstants.RESULT_KEY_FIELDNAME));
297                newField.setDescription(extras.getString(ResultConstants.RESULT_KEY_DESCRIPTION));
298                int fieldTypeID = extras.getInt(ResultConstants.RESULT_KEY_FIELDTYPE_ID);
299                ITokenParser fieldtype = ModelTranslator.getFieldType(fieldTypeID);
300                newField.setFieldType(fieldtype);
301
302                int seqId = mCurrentFields.size();
303                if (seqId > 0) {
304                        seqId = seqId - 1;
305                }
306                newField.setSequenceId(seqId);
307                mCurrentFields.add(newField);
308
309                updateFieldList();
310        }
311
312        private void restoreFieldFromState(JSONObject fieldjson) {
313                if (mCurrentFields == null) {
314                        mCurrentFields = new Vector<Field>();
315                }
316                try {
317                        Field newField = new Field();
318                        newField.setFieldId(-1);
319                        newField.setName(fieldjson.getString(ResultConstants.RESULT_KEY_FIELDNAME));
320                        newField.setDescription(fieldjson.getString(ResultConstants.RESULT_KEY_DESCRIPTION));
321                        int fieldTypeID = fieldjson.getInt(ResultConstants.RESULT_KEY_FIELDTYPE_ID);
322                        ITokenParser fieldtype = ModelTranslator.getFieldType(fieldTypeID);
323                        newField.setFieldType(fieldtype);
324
325                        int listSize = mCurrentFields.size();
326
327                        for (int i = 0; i < listSize; i++) {
328                                Field existingField = mCurrentFields.get(i);
329                                if (existingField.getName().equals(newField.getName())) {
330                                        return;
331                                }
332                        }
333                        if (listSize > 0) {
334                                listSize = listSize - 1;
335                        }
336                        newField.setSequenceId(listSize);
337
338                        mCurrentFields.add(newField);
339
340                        updateFieldList();
341                } catch (Exception ex) {
342                        Log.d("FormCreator", ex.getMessage());
343                }
344        }
345
346        /**
347         *
348         */
349        private void updateFieldList() {
350                ListView lsv = (ListView) findViewById(R.id.lsv_createfields);
351                if (mCurrentFields == null) {
352                        mCurrentFields = new Vector<Field>();
353                }
354
355                Field[] fieldArray = this.mCurrentFields.toArray(new Field[mCurrentFields.size()]);
356                lsv.setAdapter(new FieldViewAdapter(this, fieldArray));
357        }
358
359        /*
360         * (non-Javadoc)
361         *
362         * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
363         */
364        @Override
365        public boolean onCreateOptionsMenu(Menu menu) {
366                super.onCreateOptionsMenu(menu);
367                menu.add(0, MENU_SAVE, 0, R.string.formeditor_menu_save).setIcon(android.R.drawable.ic_menu_save);
368                menu.add(0, MENU_ADD_FIELD, 0, R.string.formeditor_menu_add_field).setIcon(android.R.drawable.ic_menu_add);
369                menu.add(0, MENU_CANCEL, 0, R.string.formeditor_menu_cancel)
370                        .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
371                return true;
372        }
373
374        /*
375         * (non-Javadoc)
376         *
377         * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
378         */
379        @Override
380        public boolean onOptionsItemSelected(MenuItem item) {
381                super.onOptionsItemSelected(item);
382                switch (item.getItemId()) {
383                        case MENU_SAVE:
384                                int formStatus = checkFormIsSaveable();
385                                if (formStatus == FormCreator.DIALOG_FORM_SAVEABLE) {
386                                        doSave();
387                                        setResult(0);
388                                        File f = this.getFileStreamPath("FormCreatorSavedState");
389                                        if (f.exists()) {
390                                                f.delete();
391                                        }
392                                        mClosing = true;
393                                        finish();
394                                } else {
395                                        this.showDialog(formStatus);
396                                }
397                                return true;
398                        case MENU_ADD_FIELD:
399                                Intent intent = new Intent(this, AddField.class);
400                                // mUpdatedFromActivity = true;
401                                if (mCurrentFields != null) {
402                                        int len = this.mCurrentFields.size();
403                                        for (int i = 0; i < len; i++) {
404                                                intent.putExtra(mCurrentFields.get(i).getName(), 0);
405                                        }
406                                }
407                                startActivityForResult(intent, ACTIVITY_ADDFIELD_ADDED);
408                                return true;
409                        case MENU_CANCEL:
410                                mClosing = true;
411                                finish();
412                                return true;
413                }
414
415                return true;
416        }
417
418        private int checkFormIsSaveable() {
419                EditText etxFormName = (EditText) findViewById(R.id.etx_formname);
420                EditText etxFormPrefix = (EditText) findViewById(R.id.etx_formprefix);
421                // EditText etxDescription =
422                // (EditText)findViewById(R.id.etx_description);
423                ListView lsvFields = (ListView) findViewById(R.id.lsv_createfields);
424
425                if (etxFormName.getText().length() == 0) {
426                        return FormCreator.DIALOG_FORM_INVALID_NOFORMNAME;
427                }
428                if (etxFormPrefix.getText().length() == 0) {
429                        return FormCreator.DIALOG_FORM_INVALID_NOPREFIX;
430                }
431
432                if (this.mCurrentFields.size() == 0) {
433                        return FormCreator.DIALOG_FORM_INVALID_NOFIELDS;
434                }
435                String prefixCandidate = etxFormPrefix.getText().toString();
436                String nameCandidate = etxFormName.getText().toString();
437
438                if (ModelTranslator.doesFormExist(this, prefixCandidate, nameCandidate)) {
439                        return FormCreator.DIALOG_FORM_INVALID_NOTUNIQUE;
440                } else {
441                        return FormCreator.DIALOG_FORM_SAVEABLE;
442                }
443        }
444
445        /**
446         * @param prefixCandidate
447         * @param nameCandidate
448         * @return
449         */
450
451        private void doSave() {
452                EditText etxFormName = (EditText) findViewById(R.id.etx_formname);
453                EditText etxFormPrefix = (EditText) findViewById(R.id.etx_formprefix);
454                EditText etxDescription = (EditText) findViewById(R.id.etx_description);
455
456                Form formToSave = new Form();
457                formToSave.setFormName(etxFormName.getText().toString());
458                formToSave.setPrefix(etxFormPrefix.getText().toString());
459                formToSave.setDescription(etxDescription.getText().toString());
460
461                // (Message[])parsedMessages.keySet().toArray(new
462                // Message[parsedMessages.keySet().size()]);
463                Field[] fieldArray = this.mCurrentFields.toArray(new Field[mCurrentFields.size()]);
464                formToSave.setFields(fieldArray);
465
466                formToSave.setParserType(ParserType.SIMPLEREGEX);
467                try {
468                        ModelTranslator.addFormToDatabase(formToSave);
469                } catch (Exception ex) {
470                        showDialog(DIALOG_FORM_CREATE_FAIL);
471                }
472        }
473
474        @Override
475        // http://www.anddev.org/tinytutcontextmenu_for_listview-t4019.html
476        // UGH, things changed from .9 to 1.0
477        public boolean onContextItemSelected(MenuItem item) {
478                // some sanity checks:
479                ListView lsvFields = (ListView) findViewById(R.id.lsv_createfields);
480                if (lsvFields.getCount() == 0 || this.mCurrentFields == null || this.mCurrentFields.size() == 0) {
481                        return true;
482                }
483
484                if (selectedFieldPosition == -1) {
485                        return true;
486                }
487
488                AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
489                switch (item.getItemId()) {
490                        // TODO: IMPLEMENT CONTEXT MENU
491                        case CONTEXT_MOVE_UP:
492
493                                moveFieldUp(selectedFieldPosition);
494
495                                break;
496                        case CONTEXT_MOVE_DOWN:
497
498                                moveFieldDown(selectedFieldPosition);
499
500                                break;
501                        case CONTEXT_REMOVE:
502                                removeField(selectedFieldPosition);
503                                break;
504                        default:
505                                return super.onContextItemSelected(item);
506                }
507                return true;
508        }
509
510        /**
511         * @param position
512         */
513        private void removeField(int position) {
514                mCurrentFields.remove(position);
515                resetFieldSequences();
516        }
517
518        /**
519         *
520         */
521        private void moveFieldDown(int position) {
522                if (position < mCurrentFields.size() - 1) {
523                        Field fieldToMove = mCurrentFields.get(position);
524                        mCurrentFields.remove(position);
525                        int newposition = position + 1;
526                        if (newposition >= mCurrentFields.size()) {
527                                mCurrentFields.add(fieldToMove);
528                        } else {
529                                mCurrentFields.add(newposition, fieldToMove);
530                        }
531                        resetFieldSequences();
532                }
533        }
534
535        /**
536         * @param position
537         */
538        private void moveFieldUp(int position) {
539                // TODO Auto-generated method stub
540                if (position > 0) {
541                        Field fieldToMove = mCurrentFields.get(position);
542                        mCurrentFields.remove(position);
543                        int newposition = position - 1;
544                        if (newposition <= 0) {
545                                mCurrentFields.add(0, fieldToMove);
546                        } else {
547                                mCurrentFields.add(newposition, fieldToMove);
548                        }
549                        resetFieldSequences();
550                }
551        }
552
553        private void resetFieldSequences() {
554                int len = mCurrentFields.size();
555                for (int i = 0; i < len; i++) {
556                        Field f = mCurrentFields.get(i);
557                        f.setSequenceId(i);
558                }
559                updateFieldList();
560        }
561
562        @Override
563        protected Dialog onCreateDialog(int id) {
564                super.onCreateDialog(id);
565                String title = "";
566                String message = "";
567
568                switch (id) {
569                        case DIALOG_FORM_INVALID_NOFIELDS:
570                                title = "Invalid form";
571                                message = "You must have at least one field for this form to save";
572                                break;
573                        case DIALOG_FORM_INVALID_NOFORMNAME:
574                                title = "Invalid form";
575                                message = "You must enter a formname";
576                                break;
577                        case DIALOG_FORM_INVALID_NOPREFIX:
578                                title = "Invalid form";
579                                message = "You must enter a prefix";
580                                break;
581                        case DIALOG_FORM_INVALID_NOTUNIQUE:
582                                title = "Invalid form";
583                                message = "The form of this name and prefix already exists";
584                                break;
585                        case DIALOG_FORM_CREATE_FAIL:
586                                title = "Form creation failed";
587                                message = "Unable to create the form and its support tables.  Check the logs.";
588                                return new AlertDialog.Builder(FormCreator.this).setTitle(title).setMessage(message)
589                                                                                                                                .setPositiveButton("Ok", null).create();
590                        case DIALOG_CONFIRM_CLOSURE:
591                                // for confirm closure, we actually just return the dialog as we
592                                // want it here.
593                                title = "Confirm Closure";
594                                message = "Are you sure you want to close without saving changes?";
595                                return new AlertDialog.Builder(FormCreator.this)
596                                                                                                                                .setTitle(title)
597                                                                                                                                .setMessage(message)
598                                                                                                                                .setPositiveButton(
599                                                                                                                                                                        "Yes",
600                                                                                                                                                                        new DialogInterface.OnClickListener() {
601                                                                                                                                                                                public void onClick(
602                                                                                                                                                                                                DialogInterface dialog,
603                                                                                                                                                                                                int whichButton) {
604                                                                                                                                                                                        finish();
605                                                                                                                                                                                }
606                                                                                                                                                                        })
607                                                                                                                                .setNegativeButton("No, keep working", null).create();
608                        default:
609                                return null;
610
611                }
612                return new AlertDialog.Builder(FormCreator.this).setTitle(title).setMessage(message).setPositiveButton("OK",
613                                                                                                                                                                                                                                null)
614                                                                                                                .create();
615
616        }
617
618}
Note: See TracBrowser for help on using the browser.