/*
* 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 org.odk.collect.android.activities;
import java.util.ArrayList;
import org.odk.collect.android.R;
import org.odk.collect.android.listeners.DiskSyncListener;
import org.odk.collect.android.provider.FormsProviderAPI.FormsColumns;
import org.odk.collect.android.tasks.DiskSyncTask;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
/**
* Responsible for displaying and deleting all the valid forms in the forms directory.
*
* @author Carl Hartung (carlhartung@gmail.com)
* @author Yaw Anokwa (yanokwa@gmail.com)
*/
public class FormManagerList extends ListActivity implements DiskSyncListener {
private static String t = "FormManagerList";
private AlertDialog mAlertDialog;
private Button mDeleteButton;
private SimpleCursorAdapter mInstances;
private ArrayList<Long> mSelected = new ArrayList<Long>();
private boolean mRestored = false;
private final String SELECTED = "selected";
DiskSyncTask mDiskSyncTask;
private final String syncMsgKey = "syncmsgkey";
/*
* (non-Javadoc)
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.form_manage_list);
mDeleteButton = (Button) findViewById(R.id.delete_button);
mDeleteButton.setText(getString(R.string.delete_file));
mDeleteButton.setOnClickListener(new OnClickListener() {
/*
* (non-Javadoc)
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View v) {
if (mSelected.size() > 0) {
createDeleteDialog();
} else {
Toast.makeText(getApplicationContext(), R.string.noselect_error,
Toast.LENGTH_SHORT).show();
}
}
});
mDiskSyncTask = (DiskSyncTask) getLastNonConfigurationInstance();
if (mDiskSyncTask == null) {
mDiskSyncTask = new DiskSyncTask();
mDiskSyncTask.setDiskSyncListener(this);
mDiskSyncTask.execute((Void[]) null);
}
if (mDiskSyncTask.getStatus() == AsyncTask.Status.FINISHED) {
//TextView tv = (TextView) findViewById(R.id.status_text);
//tv.setText(R.string.finished_disk_scan);
mDiskSyncTask.setDiskSyncListener(null);
}
Cursor c = managedQuery(FormsColumns.CONTENT_URI, null, null, null, null);
String[] data = new String[] {
FormsColumns.DISPLAY_NAME, FormsColumns.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);
mDeleteButton.setEnabled(!(mSelected.size() == 0));
// 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;
}
if (savedInstanceState != null && savedInstanceState.containsKey(syncMsgKey)) {
TextView tv = (TextView) findViewById(R.id.status_text);
tv.setText(savedInstanceState.getString(syncMsgKey));
}
}
/*
* (non-Javadoc)
* @see android.app.Activity#onRetainNonConfigurationInstance()
*/
@Override
public Object onRetainNonConfigurationInstance() {
// pass the thread on restart
return mDiskSyncTask;
}
/**
* Create the file delete dialog
*/
private void createDeleteDialog() {
mAlertDialog = new AlertDialog.Builder(this).create();
mAlertDialog.setTitle(getString(R.string.delete_file));
mAlertDialog.setMessage(getString(R.string.delete_confirm, mSelected.size()));
DialogInterface.OnClickListener dialogYesNoListener =
new DialogInterface.OnClickListener() {
/*
* (non-Javadoc)
* @see android.content.DialogInterface.OnClickListener#onClick(android.content.DialogInterface, int)
*/
@Override
public void onClick(DialogInterface dialog, int i) {
switch (i) {
case DialogInterface.BUTTON1: // delete and
deleteSelectedFiles();
mSelected.clear();
getListView().clearChoices();
break;
case DialogInterface.BUTTON2: // do nothing
break;
}
}
};
mAlertDialog.setCancelable(false);
mAlertDialog.setButton(getString(R.string.delete_yes), dialogYesNoListener);
mAlertDialog.setButton2(getString(R.string.delete_no), dialogYesNoListener);
mAlertDialog.show();
}
/**
* Deletes the selected files.First from the database then from the file system
*/
private void deleteSelectedFiles() {
ContentResolver cr = getContentResolver();
int deleted = 0;
for (int i = 0; i < mSelected.size(); i++) {
Uri deleteForm =
Uri.withAppendedPath(FormsColumns.CONTENT_URI, mSelected.get(i).toString());
deleted += cr.delete(deleteForm, null, null);
}
if (deleted == mSelected.size()) {
// all deletes were successful
Toast.makeText(getApplicationContext(), getString(R.string.file_deleted_ok, deleted),
Toast.LENGTH_SHORT).show();
} else {
// had some failures
Toast.makeText(
getApplicationContext(),
getString(R.string.file_deleted_error, mSelected.size() - deleted + " of "
+ mSelected.size()), Toast.LENGTH_LONG).show();
}
}
/*
* (non-Javadoc)
* @see android.app.ListActivity#onListItemClick(android.widget.ListView, android.view.View, int, long)
*/
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// get row id from db
Cursor c = (Cursor) getListAdapter().getItem(position);
long k = c.getLong(c.getColumnIndex(FormsColumns._ID));
// add/remove from selected list
if (mSelected.contains(k))
mSelected.remove(k);
else
mSelected.add(k);
mDeleteButton.setEnabled(!(mSelected.size() == 0));
}
/*
* (non-Javadoc)
* @see android.app.ListActivity#onRestoreInstanceState(android.os.Bundle)
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
long[] selectedArray = savedInstanceState.getLongArray(SELECTED);
for (int i = 0; i < selectedArray.length; i++)
mSelected.add(selectedArray[i]);
mRestored = true;
mDeleteButton.setEnabled(selectedArray.length > 0);
}
/*
* (non-Javadoc)
* @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
long[] selectedArray = new long[mSelected.size()];
for (int i = 0; i < mSelected.size(); i++)
selectedArray[i] = mSelected.get(i);
outState.putLongArray(SELECTED, selectedArray);
TextView tv = (TextView) findViewById(R.id.status_text);
outState.putString(syncMsgKey, tv.getText().toString());
}
/*
* (non-Javadoc)
* @see android.app.Activity#onResume()
*/
@Override
protected void onResume() {
mDiskSyncTask.setDiskSyncListener(this);
super.onResume();
}
/*
* (non-Javadoc)
* @see android.app.Activity#onPause()
*/
@Override
protected void onPause() {
mDiskSyncTask.setDiskSyncListener(null);
if (mAlertDialog != null && mAlertDialog.isShowing()) {
mAlertDialog.dismiss();
}
super.onPause();
}
/*
* (non-Javadoc)
* @see org.odk.collect.android.listeners.DiskSyncListener#SyncComplete(java.lang.String)
*/
@Override
public void SyncComplete(String result) {
Log.i(t, "Disk scan complete");
TextView tv = (TextView) findViewById(R.id.status_text);
tv.setText(result);
}
}