package org.commcare.activities;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.SearchView;
import android.widget.TextView;
import org.commcare.activities.components.EntitySelectCalloutSetup;
import org.commcare.dalvik.R;
import org.commcare.suite.model.Callout;
import org.javarosa.core.services.locale.Localization;
/**
* Manages case list activity's search state and UI
*
* @author Phillip Mates (pmates@dimagi.com)
*/
class EntitySelectSearchUI implements TextWatcher {
private SearchView searchView;
private MenuItem searchMenuItem;
private MenuItem barcodeMenuItem;
private EditText preHoneycombSearchBox;
private TextView searchResultStatus;
private ImageButton clearSearchButton;
private View searchBanner;
private final EntitySelectActivity activity;
private String filterString = "";
EntitySelectSearchUI(EntitySelectActivity activity) {
this.activity = activity;
initUIComponents();
}
private void initUIComponents() {
searchBanner = activity.findViewById(R.id.search_result_banner);
searchResultStatus = (TextView)activity.findViewById(R.id.search_results_status);
clearSearchButton = (ImageButton)activity.findViewById(R.id.clear_search_button);
clearSearchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
activity.getAdapter().clearCalloutResponseData();
activity.refreshView();
}
});
clearSearchButton.setVisibility(View.GONE);
}
protected CommCareActivity.ActionBarInstantiator getActionBarInstantiator() {
return new CommCareActivity.ActionBarInstantiator() {
// again, this should be unnecessary...
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onActionBarFound(MenuItem searchItem, SearchView searchView, MenuItem barcodeItem) {
EntitySelectSearchUI.this.searchMenuItem = searchItem;
EntitySelectSearchUI.this.searchView = searchView;
EntitySelectSearchUI.this.barcodeMenuItem = barcodeItem;
restoreLastQuery();
EntitySelectSearchUI.this.searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
activity.setLastQueryString(newText);
filterString = newText;
if (activity.getAdapter() != null) {
activity.getAdapter().filterByString(newText);
}
return false;
}
});
}
};
}
public void setupActionImage(Callout callout) {
if (callout != null && callout.getImage() != null) {
// Replace the barcode scan callout with our custom callout
EntitySelectCalloutSetup.setupImageLayout(activity, barcodeMenuItem, callout.getImage());
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void restoreLastQuery() {
String lastQueryString = activity.getLastQueryString();
if (lastQueryString != null && lastQueryString.length() > 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
searchMenuItem.expandActionView();
}
searchView.setQuery(lastQueryString, false);
if (activity.getAdapter() != null) {
activity.getAdapter().filterByString(lastQueryString);
}
}
}
@SuppressWarnings("NewApi")
protected CharSequence getSearchText() {
if (isUsingActionBar()) {
return searchView.getQuery();
} else {
return preHoneycombSearchBox.getText();
}
}
@SuppressWarnings("NewApi")
protected void setSearchText(CharSequence text) {
if (isUsingActionBar()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
searchMenuItem.expandActionView();
}
searchView.setQuery(text, false);
} else {
preHoneycombSearchBox.setText(text);
}
}
protected void setupPreHoneycombFooter(View.OnClickListener barcodeScanOnClickListener, Callout callout) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
TextView preHoneycombSearchLabel =
(TextView)activity.findViewById(R.id.screen_entity_select_search_label);
//use the old method here because some Android versions don't like Spannables for titles
preHoneycombSearchLabel.setText(Localization.get("select.search.label"));
preHoneycombSearchLabel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// get the focus on the edittext by performing click
preHoneycombSearchBox.performClick();
// then force the keyboard up since performClick() apparently isn't enough on some devices
InputMethodManager inputMethodManager =
(InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
// only will trigger it if no physical keyboard is open
inputMethodManager.showSoftInput(preHoneycombSearchBox, InputMethodManager.SHOW_IMPLICIT);
}
});
preHoneycombSearchBox = (EditText)activity.findViewById(R.id.searchbox);
preHoneycombSearchBox.setMaxLines(3);
preHoneycombSearchBox.setHorizontallyScrolling(false);
preHoneycombSearchBox.addTextChangedListener(this);
preHoneycombSearchBox.requestFocus();
preHoneycombSearchBox.setText(activity.getLastQueryString());
ImageButton preHoneycombBarcodeButton = (ImageButton)activity.findViewById(R.id.barcodeButton);
preHoneycombBarcodeButton.setOnClickListener(barcodeScanOnClickListener);
if (callout != null && callout.getImage() != null) {
EntitySelectCalloutSetup.setupImageLayout(activity, preHoneycombBarcodeButton, callout.getImage());
}
}
}
@Override
public void afterTextChanged(Editable incomingEditable) {
final String incomingString = incomingEditable.toString();
final String currentSearchText = getSearchText().toString();
if (incomingString.equals(currentSearchText)) {
filterString = currentSearchText;
if (activity.getAdapter() != null) {
activity.getAdapter().filterByString(filterString);
}
}
if (!isUsingActionBar()) {
activity.setLastQueryString(filterString);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
/**
* Checks if this activity uses the ActionBar
*/
private boolean isUsingActionBar() {
return searchView != null;
}
protected void restoreSearchString() {
if (filterString != null && !"".equals(filterString)) {
activity.getAdapter().filterByString(filterString);
}
}
protected void setSearchBannerState() {
if (!"".equals(activity.getAdapter().getSearchQuery())) {
showSearchBanner();
// Android's native SearchView has its own clear search button, so need to add our own
clearSearchButton.setVisibility(View.GONE);
} else if (activity.getAdapter().isFilteringByCalloutResult()) {
showSearchBanner();
clearSearchButton.setVisibility(View.VISIBLE);
} else {
searchBanner.setVisibility(View.GONE);
clearSearchButton.setVisibility(View.GONE);
}
}
private void showSearchBanner() {
searchResultStatus.setText(activity.getAdapter().getSearchNotificationText());
searchResultStatus.setVisibility(View.VISIBLE);
searchBanner.setVisibility(View.VISIBLE);
}
}