package org.commcare.views.dialogs; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.CheckBox; import android.widget.ProgressBar; import android.widget.TextView; import org.commcare.activities.CommCareActivity; import org.commcare.dalvik.R; import org.javarosa.core.services.locale.Localization; /** * Any progress dialog associated with a CommCareTask should use * this class to implement the dialog. Any class that launches such a task * should implement the generateProgressDialog() method of the DialogController * interface, and create the dialog in that method. The rest of the dialog's * lifecycle is handled by methods of the DialogController interface that are * fully implemented in CommCareActivity * * @author amstone326 */ public class CustomProgressDialog extends DialogFragment { //keys for onSaveInstanceState private final static String KEY_TITLE = "title"; private final static String KEY_MESSAGE = "message"; private final static String KEY_USING_CB = "using_checkbox"; private final static String KEY_IS_CHECKED = "is_checked"; private final static String KEY_CB_TEXT = "checkbox_text"; private final static String KEY_USING_BUTTON = "using_cancel_buton"; private final static String KEY_TASK_ID = "task_id"; private final static String KEY_CANCELABLE = "is_cancelable"; private final static String KEY_WAS_CANCEL_PRESSED = "was_cancel_pressed"; private final static String KEY_USING_PROGRESS_BAR = "using_progress_bar"; private final static String KEY_PROGRESS_BAR_PROGRESS = "progress_bar_progress"; private final static String KEY_PROGRESS_BAR_MAX = "progress_bar_max"; private final static String KEY_PROGRESS_BAR_VISIBILITY = "progress_bar_visibility"; //id of the task that spawned this dialog, -1 if not associated with a CommCareTask private int taskId; //for all dialogs private String title; private String message; private boolean isCancelable; //default is false, only set to true if setCancelable() is explicitly called private boolean wasCancelPressed; //for checkboxes private boolean usingCheckbox; private boolean isChecked; private String checkboxText; //for cancel button private boolean usingCancelButton; private Button cancelButton; //for progress bar private boolean usingHorizontalProgressBar; private boolean progressBarIsVisible; private int progressBarProgress; private int progressBarMax; public static CustomProgressDialog newInstance(String title, String message, int taskId) { CustomProgressDialog frag = new CustomProgressDialog(); frag.title = title; frag.message = message; frag.taskId = taskId; return frag; } public void addCheckbox(String text, boolean isChecked) { this.usingCheckbox = true; this.checkboxText = text; this.isChecked = isChecked; } public void addCancelButton() { usingCancelButton = true; } public void removeCancelButton() { usingCancelButton = false; if (cancelButton != null) { cancelButton.setVisibility(View.INVISIBLE); } } public void setCancelable() { this.isCancelable = true; } public void addProgressBar() { this.usingHorizontalProgressBar = true; this.progressBarIsVisible = true; this.progressBarProgress = 0; this.progressBarMax = 0; } public int getTaskId() { return taskId; } public boolean isChecked() { return isChecked; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); restoreFields(savedInstanceState); } private void restoreFields(Bundle savedInstanceState) { if (savedInstanceState != null) { this.title = savedInstanceState.getString(KEY_TITLE); this.message = savedInstanceState.getString(KEY_MESSAGE); this.usingCheckbox = savedInstanceState.getBoolean(KEY_USING_CB); this.isChecked = savedInstanceState.getBoolean(KEY_IS_CHECKED); this.checkboxText = savedInstanceState.getString(KEY_CB_TEXT); this.usingCancelButton = savedInstanceState.getBoolean(KEY_USING_BUTTON); this.taskId = savedInstanceState.getInt(KEY_TASK_ID); this.isCancelable = savedInstanceState.getBoolean(KEY_CANCELABLE); this.wasCancelPressed = savedInstanceState.getBoolean(KEY_WAS_CANCEL_PRESSED); this.usingHorizontalProgressBar = savedInstanceState.getBoolean(KEY_USING_PROGRESS_BAR); this.progressBarProgress = savedInstanceState.getInt(KEY_PROGRESS_BAR_PROGRESS); this.progressBarMax = savedInstanceState.getInt(KEY_PROGRESS_BAR_MAX); this.progressBarIsVisible = savedInstanceState.getBoolean(KEY_PROGRESS_BAR_VISIBILITY); } } @Override public void onDestroyView() { if (getDialog() != null && getRetainInstance()) { getDialog().setDismissMessage(null); } super.onDestroyView(); } /* Creates the dialog that will reside within the fragment */ @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { restoreFields(savedInstanceState); Context context = getActivity(); AlertDialog.Builder builder = new AlertDialog.Builder(context); setCancelable(isCancelable); View view; if (usingHorizontalProgressBar) { view = LayoutInflater.from(context).inflate(R.layout.progress_dialog_determinate, null); setupDeterminateView(view); } else { view = LayoutInflater.from(context).inflate(R.layout.progress_dialog_indeterminate, null); } TextView titleView = (TextView)view.findViewById(R.id.progress_dialog_title).findViewById(R.id.dialog_title_text); titleView.setText(title); TextView messageView = (TextView)view.findViewById(R.id.progress_dialog_message); messageView.setText(message); if (usingCancelButton) { cancelButton = setupCancelButton(view); if (wasCancelPressed) { setCancellingText(titleView, messageView, cancelButton); } } builder.setView(view); Dialog d = builder.create(); d.setCanceledOnTouchOutside(isCancelable); return d; } private void setupDeterminateView(View view) { ProgressBar bar = (ProgressBar)view.findViewById(R.id.progress_bar_horizontal); bar.setProgress(progressBarProgress); bar.setMax(progressBarMax); if (progressBarIsVisible) { bar.setVisibility(View.VISIBLE); } else { bar.setVisibility(View.GONE); } if (usingCheckbox) { CheckBox cb = (CheckBox)view.findViewById(R.id.progress_dialog_checkbox); cb.setVisibility(View.VISIBLE); cb.setText(checkboxText); cb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { isChecked = ((CheckBox)v).isChecked(); } }); if (isChecked) { cb.toggle(); } } } private Button setupCancelButton(View v) { Button b = (Button)v.findViewById(R.id.dialog_cancel_button); b.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { ((CommCareActivity)getActivity()).cancelCurrentTask(); showCancelledState(); } }); b.setVisibility(View.VISIBLE); return b; } private void showCancelledState() { wasCancelPressed = true; AlertDialog pd = (AlertDialog)getDialog(); if (pd != null) { TextView titleView = (TextView)pd.findViewById(R.id.progress_dialog_title).findViewById(R.id.dialog_title_text); TextView messageView = (TextView)pd.findViewById(R.id.progress_dialog_message); Button cancelButton = (Button)pd.findViewById(R.id.dialog_cancel_button); setCancellingText(titleView, messageView, cancelButton); } } private void setCancellingText(TextView titleTextView, TextView messageTextView, Button cancelButton) { titleTextView.setText(Localization.get("activity.task.cancelling.title", new String[]{title})); messageTextView.setText(Localization.get("activity.task.cancelling.message")); cancelButton.setEnabled(false); } public void updateTitle(String newTitle) { this.title = newTitle; updateTextView(newTitle, R.id.dialog_title_text); } public void updateMessage(String newMessage) { this.message = newMessage; updateTextView(newMessage, R.id.progress_dialog_message); } private void updateTextView(String newText, int idOfViewToUpdate) { AlertDialog dialog = (AlertDialog)getDialog(); if (dialog != null) { TextView tv = (TextView)dialog.findViewById(idOfViewToUpdate); tv.setText(newText); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString(KEY_TITLE, this.title); outState.putString(KEY_MESSAGE, this.message); outState.putBoolean(KEY_USING_CB, this.usingCheckbox); outState.putBoolean(KEY_IS_CHECKED, this.isChecked); outState.putString(KEY_CB_TEXT, this.checkboxText); outState.putBoolean(KEY_USING_BUTTON, this.usingCancelButton); outState.putInt(KEY_TASK_ID, this.taskId); outState.putBoolean(KEY_CANCELABLE, this.isCancelable); outState.putBoolean(KEY_WAS_CANCEL_PRESSED, this.wasCancelPressed); outState.putBoolean(KEY_USING_PROGRESS_BAR, this.usingHorizontalProgressBar); outState.putInt(KEY_PROGRESS_BAR_PROGRESS, this.progressBarProgress); outState.putInt(KEY_PROGRESS_BAR_MAX, this.progressBarMax); outState.putBoolean(KEY_PROGRESS_BAR_VISIBILITY, this.progressBarIsVisible); } public void updateProgressBarVisibility(boolean visible) { if (usingHorizontalProgressBar) { progressBarIsVisible = visible; Dialog dialog = getDialog(); if (dialog != null) { ProgressBar bar = (ProgressBar) dialog.findViewById(R.id.progress_bar_horizontal); if (progressBarIsVisible) { bar.setVisibility(View.VISIBLE); } else { bar.setVisibility(View.GONE); } } } } public void updateProgressBar(int progress, int max) { if (usingHorizontalProgressBar) { updateProgressBarVisibility(true); this.progressBarProgress = progress; this.progressBarMax = max; Dialog dialog = getDialog(); if (dialog != null) { ProgressBar bar = (ProgressBar)dialog.findViewById(R.id.progress_bar_horizontal); bar.setProgress(progress); bar.setMax(max); } } } }