/* * Copyright (C) 2009 University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.radicaldynamic.groupinform.activities; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.ektorp.DbAccessException; import org.odk.collect.android.preferences.PreferencesActivity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ListActivity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.radicaldynamic.groupinform.R; import com.radicaldynamic.groupinform.adapters.UploaderListAdapter; import com.radicaldynamic.groupinform.application.Collect; import com.radicaldynamic.groupinform.documents.FormDefinition; import com.radicaldynamic.groupinform.repositories.FormDefinitionRepo; import com.radicaldynamic.groupinform.utilities.DocumentUtils; /** * Responsible for displaying all the valid forms in the forms directory. Stores the path to * selected form for use by {@link MainMenuActivity}. * * @author Carl Hartung (carlhartung@gmail.com) * @author Yaw Anokwa (yanokwa@gmail.com) */ public class InstanceUploaderList extends ListActivity { private static final String BUNDLE_SELECTED_ITEMS_KEY = "selected_items"; private static final String BUNDLE_TOGGLED_KEY = "toggled"; private static final int MENU_PREFERENCES = Menu.FIRST; private static final int INSTANCE_UPLOADER = 0; private Button mUploadButton; private Button mToggleButton; // BEGIN custom // private SimpleCursorAdapter mInstances; // private ArrayList<Long> mSelected = new ArrayList<Long>(); private boolean mRestored = false; private boolean mToggled = false; // Tallies private Map<String, List<String>> mInstances = new HashMap<String, List<String>>(); private ArrayList<String> mSelected = new ArrayList<String>(); private Dialog mDialog; private String mDialogMessage; // Custom message consumed by onCreateDialog() // Could not access database (for whatever reason) private static final int DIALOG_FOLDER_UNAVAILABLE = 0; // END custom @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.instance_uploader_list); mUploadButton = (Button) findViewById(R.id.upload_button); mUploadButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo ni = connectivityManager.getActiveNetworkInfo(); if (ni == null || !ni.isConnected()) { Toast.makeText(InstanceUploaderList.this, R.string.no_connection, Toast.LENGTH_SHORT).show(); } else { if (mSelected.size() > 0) { // items selected uploadSelectedFiles(); // BEGIN custom refreshData(); // END custom mToggled = false; mSelected.clear(); InstanceUploaderList.this.getListView().clearChoices(); mUploadButton.setEnabled(false); } else { // no items selected Toast.makeText(getApplicationContext(), getString(R.string.noselect_error), Toast.LENGTH_SHORT).show(); } } } }); mToggleButton = (Button) findViewById(R.id.toggle_button); mToggleButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // toggle selections of items to all or none ListView ls = getListView(); mToggled = !mToggled; // remove all items from selected list mSelected.clear(); for (int pos = 0; pos < ls.getCount(); pos++) { ls.setItemChecked(pos, mToggled); // add all items if mToggled sets to select all // BEGIN custom // if (mToggled) // mSelected.add(ls.getItemIdAtPosition(pos)); if (mToggled) { FormDefinition form = (FormDefinition) ls.getItemAtPosition(pos); mSelected.add(form.getId()); } // END custom } mUploadButton.setEnabled(!(mSelected.size() == 0)); } }); // // get all complete or failed submission instances // String selection = InstanceColumns.STATUS + "=? or " + InstanceColumns.STATUS + "=?"; // String selectionArgs[] = { // InstanceProviderAPI.STATUS_COMPLETE, InstanceProviderAPI.STATUS_SUBMISSION_FAILED // }; // // Cursor c = managedQuery(InstanceColumns.CONTENT_URI, null, selection, selectionArgs, null); // startManagingCursor(c); // // String[] data = new String[] { // InstanceColumns.DISPLAY_NAME, InstanceColumns.DISPLAY_SUBTEXT // }; // int[] view = new int[] { // R.id.text1, R.id.text2 // }; // // // render total instance view // mInstances = // new SimpleCursorAdapter(this, R.layout.two_item_multiple_choice, c, data, view); // setListAdapter(mInstances); // getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); // getListView().setItemsCanFocus(false); // mUploadButton.setEnabled(!(mSelected.size() == 0)); // set title setTitle(getString(R.string.app_name) + " > " + getString(R.string.send_data)); // // if current activity is being reinitialized due to changing orientation restore all check // // marks for ones selected // if (mRestored) { // ListView ls = getListView(); // for (long id : mSelected) { // for (int pos = 0; pos < ls.getCount(); pos++) { // if (id == ls.getItemIdAtPosition(pos)) { // ls.setItemChecked(pos, true); // break; // } // } // // } // mRestored = false; // } } private void uploadSelectedFiles() { // BEGIN custom // // send list of _IDs. // long[] instanceIDs = new long[mSelected.size()]; // for (int i = 0; i < mSelected.size(); i++) { // instanceIDs[i] = mSelected.get(i); // } // // Intent i = new Intent(this, InstanceUploaderActivity.class); // i.putExtra(FormEntryActivity.KEY_INSTANCES, instanceIDs); // startActivityForResult(i, INSTANCE_UPLOADER); Bundle b = new Bundle(); for (String formId : mSelected) { b.putStringArrayList(formId, new ArrayList<String>(mInstances.get(formId))); } Intent i = new Intent(this, InstanceUploaderActivity.class); i.putExtra(FormEntryActivity.KEY_INSTANCES, b); startActivityForResult(i, INSTANCE_UPLOADER); // END custom } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(0, MENU_PREFERENCES, 0, getString(R.string.general_preferences)).setIcon( android.R.drawable.ic_menu_preferences); return true; } @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case MENU_PREFERENCES: createPreferencesMenu(); return true; } return super.onMenuItemSelected(featureId, item); } private void createPreferencesMenu() { Intent i = new Intent(this, PreferencesActivity.class); startActivity(i); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); // BEGIN custom // // get row id from db // Cursor c = (Cursor) getListAdapter().getItem(position); // long k = c.getLong(c.getColumnIndex(InstanceColumns._ID)); // // // add/remove from selected list // if (mSelected.contains(k)) // mSelected.remove(k); // else // mSelected.add(k); FormDefinition form = (FormDefinition) getListAdapter().getItem(position); // Add/remove from selected list if (mSelected.contains(form.getId())) mSelected.remove(form.getId()); else mSelected.add(form.getId()); // END custom mUploadButton.setEnabled(!(mSelected.size() == 0)); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // BEGIN custom // long[] selectedArray = savedInstanceState.getLongArray(BUNDLE_SELECTED_ITEMS_KEY); // for (int i = 0; i < selectedArray.length; i++) // mSelected.add(selectedArray[i]); mSelected = savedInstanceState.getStringArrayList(BUNDLE_SELECTED_ITEMS_KEY); // END custom mToggled = savedInstanceState.getBoolean(BUNDLE_TOGGLED_KEY); mRestored = true; // BEGIN custom // mUploadButton.setEnabled(selectedArray.length > 0); mUploadButton.setEnabled(mSelected.size() > 0); // END custom } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // BEGIN custom // long[] selectedArray = new long[mSelected.size()]; // for (int i = 0; i < mSelected.size(); i++) // selectedArray[i] = mSelected.get(i); // outState.putLongArray(BUNDLE_SELECTED_ITEMS_KEY, selectedArray); outState.putStringArrayList(BUNDLE_SELECTED_ITEMS_KEY, mSelected); // END custom outState.putBoolean(BUNDLE_TOGGLED_KEY, mToggled); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { if (resultCode == RESULT_CANCELED) { return; } switch (requestCode) { // returns with a form path, start entry case INSTANCE_UPLOADER: if (intent.getBooleanExtra(FormEntryActivity.KEY_SUCCESS, false)) { mSelected.clear(); getListView().clearChoices(); if (mInstances.isEmpty()) { finish(); } } break; default: break; } super.onActivityResult(requestCode, resultCode, intent); } // BEGIN custom @Override public Dialog onCreateDialog(int id) { AlertDialog.Builder builder = new AlertDialog.Builder(this); mDialog = null; switch (id) { case DIALOG_FOLDER_UNAVAILABLE: builder .setCancelable(false) .setIcon(R.drawable.ic_dialog_info) .setTitle(R.string.tf_folder_unavailable) .setMessage(mDialogMessage); builder.setPositiveButton(getString(R.string.tf_try_again), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { removeDialog(DIALOG_FOLDER_UNAVAILABLE); refreshData(); } }); builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { removeDialog(DIALOG_FOLDER_UNAVAILABLE); } }); mDialog = builder.create(); } return mDialog; } @Override protected void onResume() { refreshData(); super.onResume(); } private void refreshData() { if (!mRestored) { mSelected.clear(); } new RefreshViewTask().execute(); } private void setProgressVisibility(boolean visible) { ProgressBar pb = (ProgressBar) getParent().getWindow().findViewById(R.id.titleProgressBar); if (pb != null) { if (visible) { pb.setVisibility(View.VISIBLE); } else { pb.setVisibility(View.GONE); } } } /* * Refresh the main form browser view as requested by the user */ private class RefreshViewTask extends AsyncTask<Void, Void, Void> { private ArrayList<FormDefinition> documents = new ArrayList<FormDefinition>(); private TextView loading = (TextView) findViewById(android.R.id.empty); private boolean folderUnavailable = false; @Override protected Void doInBackground(Void... nothing) { try { mInstances = new FormDefinitionRepo(Collect.getInstance().getDbService().getDb()).getByAggregateReadiness(); if (!mInstances.isEmpty()) { documents = (ArrayList<FormDefinition>) new FormDefinitionRepo(Collect.getInstance().getDbService().getDb()).getAllActiveByKeys(new ArrayList<Object>(mInstances.keySet())); DocumentUtils.sortDefinitionsByName(documents); } } catch (DbAccessException e) { folderUnavailable = true; } catch (ClassCastException e) { // TODO: is there a better way to handle empty lists? } return null; } @Override protected void onPreExecute() { if (loading != null) loading.setText(R.string.tf_loading_please_wait); setProgressVisibility(true); } @Override protected void onPostExecute(Void nothing) { if (loading != null) loading.setText(R.string.no_items_display); if (folderUnavailable) { mDialogMessage = getString(R.string.tf_unable_to_access_folder_for_instance_upload, BrowserActivity.getSelectedFolderName()); showDialog(DIALOG_FOLDER_UNAVAILABLE); } UploaderListAdapter adapter = new UploaderListAdapter(getApplicationContext(), R.layout.two_item_multiple_choice, documents, mInstances); setListAdapter(adapter); getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); getListView().setItemsCanFocus(false); mUploadButton.setEnabled(!(mSelected.size() == 0)); // If current activity is being reinitialised due to changing orientation restore selected checkmarks if (mRestored) { ListView ls = getListView(); for (int pos = 0; pos < ls.getCount(); pos++) { FormDefinition form = (FormDefinition) ls.getItemAtPosition(pos); if (mSelected.contains(form.getId())) ls.setItemChecked(pos, true); } mRestored = false; } setProgressVisibility(false); } } // END custom }