2 * Copyright (C) 2012 The CyanogenMod Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.cyanogenmod.filemanager.activities;
19 import android.app.ActionBar;
20 import android.app.Activity;
21 import android.app.AlertDialog;
22 import android.app.SearchManager;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.DialogInterface;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.content.pm.ActivityInfo;
29 import android.os.Bundle;
30 import android.os.Parcelable;
31 import android.preference.PreferenceActivity;
32 import android.provider.SearchRecentSuggestions;
33 import android.text.Html;
34 import android.text.TextUtils;
35 import android.util.Log;
36 import android.view.KeyEvent;
37 import android.view.MenuItem;
38 import android.view.View;
39 import android.widget.AdapterView;
40 import android.widget.AdapterView.OnItemClickListener;
41 import android.widget.AdapterView.OnItemLongClickListener;
42 import android.widget.ListAdapter;
43 import android.widget.ListView;
44 import android.widget.ProgressBar;
45 import android.widget.TextView;
46 import android.widget.Toast;
48 import com.cyanogenmod.filemanager.FileManagerApplication;
49 import com.cyanogenmod.filemanager.R;
50 import com.cyanogenmod.filemanager.activities.preferences.SettingsPreferences;
51 import com.cyanogenmod.filemanager.activities.preferences.SettingsPreferences.SearchPreferenceFragment;
52 import com.cyanogenmod.filemanager.adapters.SearchResultAdapter;
53 import com.cyanogenmod.filemanager.commands.AsyncResultExecutable;
54 import com.cyanogenmod.filemanager.commands.AsyncResultListener;
55 import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
56 import com.cyanogenmod.filemanager.listeners.OnRequestRefreshListener;
57 import com.cyanogenmod.filemanager.model.Directory;
58 import com.cyanogenmod.filemanager.model.FileSystemObject;
59 import com.cyanogenmod.filemanager.model.Query;
60 import com.cyanogenmod.filemanager.model.SearchResult;
61 import com.cyanogenmod.filemanager.model.Symlink;
62 import com.cyanogenmod.filemanager.parcelables.SearchInfoParcelable;
63 import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
64 import com.cyanogenmod.filemanager.preferences.Preferences;
65 import com.cyanogenmod.filemanager.providers.RecentSearchesContentProvider;
66 import com.cyanogenmod.filemanager.tasks.SearchResultDrawingAsyncTask;
67 import com.cyanogenmod.filemanager.ui.dialogs.ActionsDialog;
68 import com.cyanogenmod.filemanager.ui.dialogs.MessageProgressDialog;
69 import com.cyanogenmod.filemanager.ui.policy.IntentsActionPolicy;
70 import com.cyanogenmod.filemanager.ui.widgets.ButtonItem;
71 import com.cyanogenmod.filemanager.util.CommandHelper;
72 import com.cyanogenmod.filemanager.util.DialogHelper;
73 import com.cyanogenmod.filemanager.util.ExceptionUtil;
74 import com.cyanogenmod.filemanager.util.FileHelper;
75 import com.cyanogenmod.filemanager.util.StorageHelper;
77 import java.io.FileNotFoundException;
78 import java.util.ArrayList;
79 import java.util.List;
82 * An activity for search files and folders.
84 public class SearchActivity extends Activity
85 implements AsyncResultListener, OnItemClickListener,
86 OnItemLongClickListener, OnRequestRefreshListener {
88 private static final String TAG = "SearchActivity"; //$NON-NLS-1$
90 private static boolean DEBUG = false;
93 * An {@link Intent} action for restore view information.
95 public static final String ACTION_RESTORE =
96 "com.cyanogenmod.filemanager.activities.SearchActivity#Restore"; //$NON-NLS-1$
99 * Intent extra parameter for search in the selected directory on enter.
101 public static final String EXTRA_SEARCH_DIRECTORY = "extra_search_directory"; //$NON-NLS-1$
104 * Intent extra parameter for pass the restore information.
106 public static final String EXTRA_SEARCH_RESTORE = "extra_search_restore"; //$NON-NLS-1$
109 //Minimum characters to allow query
110 private static final int MIN_CHARS_SEARCH = 3;
112 private final BroadcastReceiver mOnSettingChangeReceiver = new BroadcastReceiver() {
114 public void onReceive(Context context, Intent intent) {
115 if (intent != null &&
116 intent.getAction().compareTo(FileManagerSettings.INTENT_SETTING_CHANGED) == 0) {
118 // The settings has changed
119 String key = intent.getStringExtra(FileManagerSettings.EXTRA_SETTING_CHANGED_KEY);
121 if (SearchActivity.this.mSearchListView.getAdapter() != null &&
123 FileManagerSettings.SETTINGS_HIGHLIGHT_TERMS.getId()) == 0 ||
125 FileManagerSettings.SETTINGS_SHOW_RELEVANCE_WIDGET.getId()) == 0 ||
127 FileManagerSettings.SETTINGS_SORT_SEARCH_RESULTS_MODE.getId()) == 0)) {
129 // Recreate the adapter
130 int pos = SearchActivity.this.mSearchListView.getFirstVisiblePosition();
132 SearchActivity.this.mSearchListView.setSelection(pos);
143 MessageProgressDialog mDialog = null;
147 AsyncResultExecutable mExecutable = null;
152 ListView mSearchListView;
156 ProgressBar mSearchWaiting;
160 TextView mSearchFoundItems;
164 TextView mSearchTerms;
165 private View mEmptyListMsg;
167 private String mSearchDirectory;
171 List<FileSystemObject> mResultList;
180 SearchInfoParcelable mRestoreState;
182 private SearchResultDrawingAsyncTask mDrawingSearchResultTask;
194 protected void onCreate(Bundle state) {
196 Log.d(TAG, "NavigationActivity.onCreate"); //$NON-NLS-1$
199 // Check if app is running in chrooted mode
200 this.mChRooted = !FileManagerApplication.isAdvancedMode();
202 // Register the broadcast receiver
203 IntentFilter filter = new IntentFilter();
204 filter.addAction(FileManagerSettings.INTENT_SETTING_CHANGED);
205 registerReceiver(this.mOnSettingChangeReceiver, filter);
208 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
210 overridePendingTransition(R.anim.translate_to_right_in, R.anim.hold_out);
212 //Set the main layout of the activity
213 setContentView(R.layout.search);
220 //Initialize action bars and search
221 initTitleActionBar();
223 if (this.mRestoreState != null) {
224 //Restore activity from cached data
228 if (Intent.ACTION_SEARCH.equals(getIntent().getAction())) {
230 } else if (ACTION_RESTORE.equals(getIntent().getAction())) {
231 restoreState(getIntent().getExtras());
237 super.onCreate(state);
244 protected void onNewIntent(Intent intent) {
246 if (Intent.ACTION_SEARCH.equals(getIntent().getAction())) {
255 protected void onPause() {
257 overridePendingTransition(R.anim.hold_in, R.anim.translate_to_left_out);
265 protected void onDestroy() {
268 unregisterReceiver(this.mOnSettingChangeReceiver);
269 } catch (Throwable ex) {/**NON BLOCK**/}
276 protected void onSaveInstanceState(Bundle outState) {
278 Log.d(TAG, "SearchActivity.onSaveInstanceState"); //$NON-NLS-1$
281 super.onSaveInstanceState(outState);
285 * Method that save the instance of the activity.
287 * @param state The current state of the activity
289 private void saveState(Bundle state) {
291 if (this.mSearchListView.getAdapter() != null) {
292 state.putParcelable(EXTRA_SEARCH_RESTORE, createSearchInfo());
294 } catch (Throwable ex) {
295 Log.w(TAG, "The state can't be saved", ex); //$NON-NLS-1$
300 * Method that restore the instance of the activity.
302 * @param state The previous state of the activity
304 private void restoreState(Bundle state) {
306 if (state.containsKey(EXTRA_SEARCH_RESTORE)) {
307 this.mRestoreState = state.getParcelable(EXTRA_SEARCH_RESTORE);
309 } catch (Throwable ex) {
310 Log.w(TAG, "The state can't be restored", ex); //$NON-NLS-1$
315 * Method that initializes the titlebar of the activity.
317 private void initTitleActionBar() {
318 //Configure the action bar options
319 getActionBar().setBackgroundDrawable(
320 getResources().getDrawable(R.drawable.bg_holo_titlebar));
321 getActionBar().setDisplayOptions(
322 ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);
323 getActionBar().setDisplayHomeAsUpEnabled(true);
324 View customTitle = getLayoutInflater().inflate(R.layout.simple_customtitle, null, false);
326 TextView title = (TextView)customTitle.findViewById(R.id.customtitle_title);
327 title.setText(R.string.search);
328 title.setContentDescription(getString(R.string.search));
329 ButtonItem configuration = (ButtonItem)customTitle.findViewById(R.id.ab_button1);
330 configuration.setImageResource(R.drawable.ic_holo_light_config);
331 configuration.setVisibility(View.VISIBLE);
333 getActionBar().setCustomView(customTitle);
337 * Method that initializes the component of the activity.
339 private void initComponents() {
341 this.mEmptyListMsg = findViewById(R.id.search_empty_msg);
343 this.mSearchListView = (ListView)findViewById(R.id.search_listview);
344 this.mSearchListView.setOnItemClickListener(this);
345 this.mSearchListView.setOnItemLongClickListener(this);
348 this.mSearchWaiting = (ProgressBar)findViewById(R.id.search_waiting);
349 this.mSearchFoundItems = (TextView)findViewById(R.id.search_status_found_items);
350 setFoundItems(0, ""); //$NON-NLS-1$
351 this.mSearchTerms = (TextView)findViewById(R.id.search_status_query_terms);
352 this.mSearchTerms.setText(
353 Html.fromHtml(getString(R.string.search_terms, ""))); //$NON-NLS-1$
357 * Method invoked when an action item is clicked.
359 * @param view The button pushed
361 public void onActionBarItemClick(View view) {
362 switch (view.getId()) {
363 case R.id.ab_button1:
365 Intent settings = new Intent(this, SettingsPreferences.class);
367 PreferenceActivity.EXTRA_SHOW_FRAGMENT,
368 SearchPreferenceFragment.class.getName());
369 startActivity(settings);
378 * Method that initializes the titlebar of the activity.
380 private void initSearch() {
381 //Stop any pending action
383 if (SearchActivity.this.mDrawingSearchResultTask != null
384 && SearchActivity.this.mDrawingSearchResultTask.isRunning()) {
385 SearchActivity.this.mDrawingSearchResultTask.cancel(true);
387 } catch (Throwable ex2) {
391 if (SearchActivity.this.mDialog != null) {
392 SearchActivity.this.mDialog.dismiss();
394 } catch (Throwable ex2) {
398 //Recovery the search directory
399 Bundle bundle = getIntent().getBundleExtra(SearchManager.APP_DATA);
400 //If data is not present, use root directory to do the search
401 this.mSearchDirectory = FileHelper.ROOT_DIRECTORY;
402 if (bundle != null) {
403 this.mSearchDirectory =
404 bundle.getString(EXTRA_SEARCH_DIRECTORY, FileHelper.ROOT_DIRECTORY);
407 //Retrieve the query ¿from voice recognizer?
408 boolean voiceQuery = true;
409 List<String> userQueries =
410 getIntent().getStringArrayListExtra(android.speech.RecognizerIntent.EXTRA_RESULTS);
411 if (userQueries == null || userQueries.size() == 0) {
413 userQueries = new ArrayList<String>();
414 //Recovers and save the last term search in the memory
415 Preferences.setLastSearch(getIntent().getStringExtra(SearchManager.QUERY));
416 userQueries.add(Preferences.getLastSearch());
420 //Filter the queries? Needed if queries come from voice recognition
421 final List<String> filteredUserQueries =
422 (voiceQuery) ? filterQuery(userQueries) : userQueries;
425 this.mQuery = new Query().fillSlots(filteredUserQueries);
426 List<String> queries = this.mQuery.getQueries();
428 //Check if some queries has lower than allowed, in this case
429 //request the user for stop the search
431 int cc = queries.size();
432 for (int i = 0; i < cc; i++) {
433 if (queries.get(i).trim().length() < MIN_CHARS_SEARCH) {
439 askUserBeforeSearch(voiceQuery, this.mQuery, this.mSearchDirectory);
441 doSearch(voiceQuery, this.mQuery, this.mSearchDirectory);
447 * Method that ask the user before do the search.
449 * @param voiceQuery Indicates if the query is from voice recognition
450 * @param query The terms of the search
451 * @param searchDirectory The directory of the search
453 private void askUserBeforeSearch(
454 final boolean voiceQuery, final Query query, final String searchDirectory) {
455 //Show a dialog asking the user
457 DialogHelper.createYesNoDialog(
458 this, R.string.search_few_characters_msg,
459 new DialogInterface.OnClickListener() {
461 public void onClick(DialogInterface alertDialog, int which) {
462 if (which == DialogInterface.BUTTON_NEGATIVE) {
463 doSearch(voiceQuery, query, searchDirectory);
467 //Close search activity
468 back(true, null, false);
475 * Method that do the search.
477 * @param voiceQuery Indicates if the query is from voice recognition
478 * @param query The terms of the search
479 * @param searchDirectory The directory of the search
483 final boolean voiceQuery, final Query query, final String searchDirectory) {
485 // Recovers the user preferences about save suggestions
486 boolean saveSuggestions = Preferences.getSharedPreferences().getBoolean(
487 FileManagerSettings.SETTINGS_SAVE_SEARCH_TERMS.getId(),
488 ((Boolean)FileManagerSettings.SETTINGS_SAVE_SEARCH_TERMS.
489 getDefaultValue()).booleanValue());
490 if (saveSuggestions) {
491 //Save every query for use as recent suggestions
492 SearchRecentSuggestions suggestions =
493 new SearchRecentSuggestions(this,
494 RecentSearchesContentProvider.AUTHORITY,
495 RecentSearchesContentProvider.MODE);
497 List<String> queries = query.getQueries();
498 int cc = queries.size();
499 for (int i = 0; i < cc; i++) {
500 suggestions.saveRecentQuery(queries.get(i), null);
506 this.mResultList = new ArrayList<FileSystemObject>();
507 SearchResultAdapter adapter =
508 new SearchResultAdapter(this,
509 new ArrayList<SearchResult>(), R.layout.search_item, this.mQuery);
510 this.mSearchListView.setAdapter(adapter);
513 this.mSearchTerms.setText(
514 Html.fromHtml(getString(R.string.search_terms, query.getTerms())));
517 //Now, do the search in background
518 this.mSearchListView.post(new Runnable() {
522 //Retrieve the terms of the search
523 String label = getString(R.string.searching_action_label);
525 //Show a dialog for the progress
526 SearchActivity.this.mDialog =
527 new MessageProgressDialog(
529 R.drawable.ic_holo_light_search,
530 R.string.searching, label, true);
534 // Set the cancel listener
535 SearchActivity.this.mDialog.setOnCancelListener(
536 new MessageProgressDialog.OnCancelListener() {
538 public boolean onCancel() {
539 //User has requested the cancellation of the search
540 //Broadcast the cancellation
541 if (!SearchActivity.this.mExecutable.isCancelled()) {
542 if (SearchActivity.this.mExecutable.cancel()) {
543 ListAdapter listAdapter =
545 this.mSearchListView.getAdapter();
546 if (listAdapter != null) {
547 SearchActivity.this.toggleResults(
548 listAdapter.getCount() > 0, true);
557 SearchActivity.this.mDialog.show();
559 //Execute the query (search are process in background)
560 SearchActivity.this.mExecutable =
561 CommandHelper.findFiles(
564 SearchActivity.this.mQuery,
568 } catch (Throwable ex) {
569 //Remove all elements
571 SearchActivity.this.removeAll();
572 } catch (Throwable ex2) {
576 if (SearchActivity.this.mDialog != null) {
577 SearchActivity.this.mDialog.dismiss();
579 } catch (Throwable ex2) {
583 //Capture the exception
584 Log.e(TAG, "Search failed", ex); //$NON-NLS-1$
585 DialogHelper.showToast(
587 R.string.search_error_msg, Toast.LENGTH_SHORT);
588 SearchActivity.this.mSearchListView.setVisibility(View.GONE);
595 * Method that restore the activity from the cached data.
597 private void loadFromCacheData() {
598 this.mSearchListView.post(new Runnable() {
602 List<SearchResult> list = SearchActivity.this.mRestoreState.getSearchResultList();
603 String directory = SearchActivity.this.mRestoreState.getSearchDirectory();
604 SearchActivity.this.toggleResults(list.size() > 0, true);
605 setFoundItems(list.size(), directory);
608 Query query = SearchActivity.this.mRestoreState.getSearchQuery();
610 TextUtils.join(" | ", //$NON-NLS-1$;
611 query.getQueries().toArray(new String[]{}));
612 if (terms.endsWith(" | ")) { //$NON-NLS-1$;
613 terms = ""; //$NON-NLS-1$;
615 SearchActivity.this.mSearchTerms.setText(
616 Html.fromHtml(getString(R.string.search_terms, terms)));
619 if (SearchActivity.this.mSearchWaiting != null) {
620 SearchActivity.this.mSearchWaiting.setVisibility(View.VISIBLE);
623 //Add list to the listview
624 if (SearchActivity.this.mSearchListView.getAdapter() != null) {
625 ((SearchResultAdapter)SearchActivity.this.
626 mSearchListView.getAdapter()).clear();
628 SearchResultAdapter adapter =
629 new SearchResultAdapter(
630 SearchActivity.this.mSearchListView.getContext(),
632 R.layout.search_item,
634 SearchActivity.this.mSearchListView.setAdapter(adapter);
635 SearchActivity.this.mSearchListView.setSelection(0);
637 } catch (Throwable ex) {
638 //Capture the exception
639 ExceptionUtil.translateException(SearchActivity.this, ex);
643 if (SearchActivity.this.mSearchWaiting != null) {
644 SearchActivity.this.mSearchWaiting.setVisibility(View.GONE);
653 * Method that filter the user queries for valid queries only.<br/>
655 * Only allow query strings with more that 3 characters
657 * @param original The original user queries
658 * @return List<String> The list of queries filtered
660 @SuppressWarnings("static-method")
661 private List<String> filterQuery(List<String> original) {
662 List<String> dst = new ArrayList<String>(original);
664 for (int i = cc - 1; i >= 0; i--) {
665 String query = dst.get(i);
666 if (query == null || query.trim().length() < MIN_CHARS_SEARCH) {
674 * Method that removes all items and display a message.
678 SearchResultAdapter adapter = (SearchResultAdapter)this.mSearchListView.getAdapter();
680 adapter.notifyDataSetChanged();
681 this.mSearchListView.setSelection(0);
682 toggleResults(false, true);
686 * Method that toggle the views when there are results.
688 * @param hasResults Indicates if there are results
689 * @param showEmpty Show the empty list message
692 void toggleResults(boolean hasResults, boolean showEmpty) {
693 this.mSearchListView.setVisibility(hasResults ? View.VISIBLE : View.INVISIBLE);
694 this.mEmptyListMsg.setVisibility(!hasResults && showEmpty ? View.VISIBLE : View.INVISIBLE);
698 * Method that display the number of found items.
700 * @param items The number of items
701 * @param searchDirectory The search directory path
704 void setFoundItems(final int items, final String searchDirectory) {
705 if (this.mSearchFoundItems != null) {
706 this.mSearchFoundItems.post(new Runnable() {
709 String directory = searchDirectory;
710 if (SearchActivity.this.mChRooted &&
711 directory != null && directory.length() > 0) {
712 directory = StorageHelper.getChrootedPath(directory);
718 R.plurals.search_found_items, items, Integer.valueOf(items));
719 SearchActivity.this.mSearchFoundItems.setText(
721 R.string.search_found_items_in_directory,
733 public boolean onKeyUp(int keyCode, KeyEvent event) {
735 case KeyEvent.KEYCODE_BACK:
736 back(true, null, false);
739 return super.onKeyUp(keyCode, event);
747 public boolean onOptionsItemSelected(MenuItem item) {
748 switch (item.getItemId()) {
749 case android.R.id.home:
750 back(true, null, false);
753 return super.onOptionsItemSelected(item);
761 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
763 SearchResult result = ((SearchResultAdapter)parent.getAdapter()).getItem(position);
764 FileSystemObject fso = result.getFso();
765 if (fso instanceof Directory) {
766 back(false, fso, false);
767 } else if (fso instanceof Symlink) {
768 Symlink symlink = (Symlink)fso;
769 if (symlink.getLinkRef() != null && symlink.getLinkRef() instanceof Directory) {
770 back(false, symlink.getLinkRef(), false);
773 // Open the file with the preferred registered app
774 back(false, fso, false);
776 } catch (Throwable ex) {
777 ExceptionUtil.translateException(this.mSearchListView.getContext(), ex);
785 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
786 // Different actions depending on user preference
788 // Get the adapter, the search result and the fso
789 SearchResultAdapter adapter = ((SearchResultAdapter)parent.getAdapter());
790 SearchResult searchResult = adapter.getItem(position);
791 FileSystemObject fso = searchResult.getFso();
793 // Open the actions menu
795 return true; //Always consume the event
799 * Method invoked when a request to show the menu associated
800 * with an item is started.
802 * @param item The item for which the request was started
804 public void onRequestMenu(FileSystemObject item) {
805 // Prior to show the dialog, refresh the item reference
806 FileSystemObject fso = null;
808 fso = CommandHelper.getFileInfo(this, item.getFullPath(), false, null);
810 throw new NoSuchFileOrDirectory(item.getFullPath());
813 } catch (Exception e) {
815 ExceptionUtil.translateException(this, e);
818 if (e instanceof FileNotFoundException || e instanceof NoSuchFileOrDirectory) {
824 ActionsDialog dialog = new ActionsDialog(this, fso, false, true);
825 dialog.setOnRequestRefreshListener(this);
830 * Method that removes the {@link FileSystemObject} reference
832 * @param fso The file system object
834 private void removeItem(FileSystemObject fso) {
835 SearchResultAdapter adapter =
836 (SearchResultAdapter)this.mSearchListView.getAdapter();
837 if (adapter != null) {
838 int pos = adapter.getPosition(fso);
840 SearchResult sr = adapter.getItem(pos);
845 toggleResults(adapter.getCount() > 0, true);
846 setFoundItems(adapter.getCount(), this.mSearchDirectory);
854 public void onRequestRefresh(Object o) {
855 // Refresh only the item
856 SearchResultAdapter adapter =
857 (SearchResultAdapter)this.mSearchListView.getAdapter();
858 if (adapter != null) {
859 if (o instanceof FileSystemObject) {
861 FileSystemObject fso = (FileSystemObject)o;
862 int pos = adapter.getPosition(fso);
864 SearchResult sr = adapter.getItem(pos);
867 } else if (o == null) {
869 List<SearchResult> results = adapter.getData();
870 this.mResultList = new ArrayList<FileSystemObject>(results.size());
871 int cc = results.size();
872 for (int i = 0; i < cc; i++) {
873 this.mResultList.add(results.get(i).getFso());
884 public void onRequestRemove(Object o) {
885 if (o instanceof FileSystemObject) {
886 removeItem((FileSystemObject)o);
894 public void onNavigateTo(Object o) {
895 if (o instanceof FileSystemObject) {
896 back(false, (FileSystemObject)o, true);
901 * Method that returns to previous activity.
903 * @param cancelled Indicates if the activity was cancelled
904 * @param item The fso
907 void back(final boolean cancelled, FileSystemObject item, boolean isChecked) {
908 Intent intent = new Intent();
910 if (SearchActivity.this.mDrawingSearchResultTask != null
911 && SearchActivity.this.mDrawingSearchResultTask.isRunning()) {
912 SearchActivity.this.mDrawingSearchResultTask.cancel(true);
914 if (this.mRestoreState != null) {
916 NavigationActivity.EXTRA_SEARCH_LAST_SEARCH_DATA,
917 (Parcelable)this.mRestoreState);
919 setResult(RESULT_CANCELED, intent);
921 // Check that the bookmark exists
923 FileSystemObject fso = item;
925 fso = CommandHelper.getFileInfo(this, item.getFullPath(), null);
928 if (FileHelper.isDirectory(fso)) {
929 intent.putExtra(NavigationActivity.EXTRA_SEARCH_ENTRY_SELECTION, fso);
931 NavigationActivity.EXTRA_SEARCH_LAST_SEARCH_DATA,
932 (Parcelable)createSearchInfo());
933 setResult(RESULT_OK, intent);
935 // Open the file here, so when focus back to the app, the search activity
936 // its in top of the stack
937 IntentsActionPolicy.openFileSystemObject(this, fso, false, null, null);
941 // The fso not exists, delete the fso from the search
944 } catch (Exception ex) {/**NON BLOCK**/}
947 } catch (Exception e) {
948 // Capture the exception
949 ExceptionUtil.translateException(this, e);
950 if (e instanceof NoSuchFileOrDirectory || e instanceof FileNotFoundException) {
951 // The fso not exists, delete the fso from the search
954 } catch (Exception ex) {/**NON BLOCK**/}
966 public void onAsyncStart() {
967 runOnUiThread(new Runnable() {
970 SearchActivity.this.toggleResults(false, false);
979 public void onAsyncEnd(boolean cancelled) {
980 this.mSearchListView.post(new Runnable() {
985 if (SearchActivity.this.mDialog != null) {
986 SearchActivity.this.mDialog.dismiss();
989 // Resolve the symlinks
990 FileHelper.resolveSymlinks(
991 SearchActivity.this, SearchActivity.this.mResultList);
996 } catch (Throwable ex) {
997 Log.e(TAG, "onAsyncEnd method fails", ex); //$NON-NLS-1$
1007 @SuppressWarnings("unchecked")
1008 public void onPartialResult(final Object partialResults) {
1009 //Saved in the global result list, for save at the end
1010 if (partialResults instanceof FileSystemObject) {
1011 SearchActivity.this.mResultList.add((FileSystemObject)partialResults);
1013 SearchActivity.this.mResultList.addAll((List<FileSystemObject>)partialResults);
1017 this.mSearchListView.post(new Runnable() {
1020 if (SearchActivity.this.mDialog != null) {
1021 int progress = SearchActivity.this.mResultList.size();
1022 setProgressMsg(progress);
1032 public void onAsyncExitCode(int exitCode) {/**NON BLOCK**/}
1038 public void onException(Exception cause) {
1039 //Capture the exception
1040 ExceptionUtil.translateException(this, cause);
1044 * Method that draw the results in the listview
1047 void drawResults() {
1049 this.toggleResults(this.mResultList.size() > 0, true);
1050 setFoundItems(this.mResultList.size(), this.mSearchDirectory);
1052 //Create the task for drawing the data
1053 this.mDrawingSearchResultTask =
1054 new SearchResultDrawingAsyncTask(
1055 this.mSearchListView,
1056 this.mSearchWaiting,
1059 this.mDrawingSearchResultTask.execute();
1063 * Method that creates a {@link SearchInfoParcelable} reference from
1066 * @return SearchInfoParcelable The search info reference
1068 private SearchInfoParcelable createSearchInfo() {
1069 SearchInfoParcelable parcel = new SearchInfoParcelable();
1070 parcel.setSearchDirectory(this.mSearchDirectory);
1071 parcel.setSearchResultList(
1072 ((SearchResultAdapter)this.mSearchListView.getAdapter()).getData());
1073 parcel.setSearchQuery(this.mQuery);
1078 * Method that set the progress of the search
1080 * @param progress The progress
1083 void setProgressMsg(int progress) {
1085 getResources().getQuantityString(
1086 R.plurals.search_found_items,
1088 Integer.valueOf(progress));
1089 SearchActivity.this.mDialog.setProgress(Html.fromHtml(msg));