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.AccessMode;
64 import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
65 import com.cyanogenmod.filemanager.preferences.Preferences;
66 import com.cyanogenmod.filemanager.providers.RecentSearchesContentProvider;
67 import com.cyanogenmod.filemanager.tasks.SearchResultDrawingAsyncTask;
68 import com.cyanogenmod.filemanager.ui.dialogs.ActionsDialog;
69 import com.cyanogenmod.filemanager.ui.dialogs.MessageProgressDialog;
70 import com.cyanogenmod.filemanager.ui.policy.IntentsActionPolicy;
71 import com.cyanogenmod.filemanager.ui.widgets.ButtonItem;
72 import com.cyanogenmod.filemanager.util.CommandHelper;
73 import com.cyanogenmod.filemanager.util.DialogHelper;
74 import com.cyanogenmod.filemanager.util.ExceptionUtil;
75 import com.cyanogenmod.filemanager.util.FileHelper;
76 import com.cyanogenmod.filemanager.util.StorageHelper;
78 import java.io.FileNotFoundException;
79 import java.util.ArrayList;
80 import java.util.List;
83 * An activity for search files and folders.
85 public class SearchActivity extends Activity
86 implements AsyncResultListener, OnItemClickListener,
87 OnItemLongClickListener, OnRequestRefreshListener {
89 private static final String TAG = "SearchActivity"; //$NON-NLS-1$
91 private static boolean DEBUG = false;
94 * An {@link Intent} action for restore view information.
96 public static final String ACTION_RESTORE =
97 "com.cyanogenmod.filemanager.activities.SearchActivity#Restore"; //$NON-NLS-1$
100 * Intent extra parameter for search in the selected directory on enter.
102 public static final String EXTRA_SEARCH_DIRECTORY = "extra_search_directory"; //$NON-NLS-1$
105 * Intent extra parameter for pass the restore information.
107 public static final String EXTRA_SEARCH_RESTORE = "extra_search_restore"; //$NON-NLS-1$
110 //Minimum characters to allow query
111 private static final int MIN_CHARS_SEARCH = 3;
113 private final BroadcastReceiver mOnSettingChangeReceiver = new BroadcastReceiver() {
115 public void onReceive(Context context, Intent intent) {
116 if (intent != null &&
117 intent.getAction().compareTo(FileManagerSettings.INTENT_SETTING_CHANGED) == 0) {
119 // The settings has changed
120 String key = intent.getStringExtra(FileManagerSettings.EXTRA_SETTING_CHANGED_KEY);
122 if (SearchActivity.this.mSearchListView.getAdapter() != null &&
124 FileManagerSettings.SETTINGS_HIGHLIGHT_TERMS.getId()) == 0 ||
126 FileManagerSettings.SETTINGS_SHOW_RELEVANCE_WIDGET.getId()) == 0 ||
128 FileManagerSettings.SETTINGS_SORT_SEARCH_RESULTS_MODE.getId()) == 0)) {
130 // Recreate the adapter
131 int pos = SearchActivity.this.mSearchListView.getFirstVisiblePosition();
133 SearchActivity.this.mSearchListView.setSelection(pos);
144 MessageProgressDialog mDialog = null;
148 AsyncResultExecutable mExecutable = null;
153 ListView mSearchListView;
157 ProgressBar mSearchWaiting;
161 TextView mSearchFoundItems;
165 TextView mSearchTerms;
166 private View mEmptyListMsg;
168 private String mSearchDirectory;
172 List<FileSystemObject> mResultList;
181 SearchInfoParcelable mRestoreState;
183 private SearchResultDrawingAsyncTask mDrawingSearchResultTask;
195 protected void onCreate(Bundle state) {
197 Log.d(TAG, "NavigationActivity.onCreate"); //$NON-NLS-1$
200 // Check if app is running in chrooted mode
201 this.mChRooted = FileManagerApplication.getAccessMode().compareTo(AccessMode.SAFE) == 0;
203 // Register the broadcast receiver
204 IntentFilter filter = new IntentFilter();
205 filter.addAction(FileManagerSettings.INTENT_SETTING_CHANGED);
206 registerReceiver(this.mOnSettingChangeReceiver, filter);
209 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
211 overridePendingTransition(R.anim.translate_to_right_in, R.anim.hold_out);
213 //Set the main layout of the activity
214 setContentView(R.layout.search);
221 //Initialize action bars and search
222 initTitleActionBar();
224 if (this.mRestoreState != null) {
225 //Restore activity from cached data
229 if (Intent.ACTION_SEARCH.equals(getIntent().getAction())) {
231 } else if (ACTION_RESTORE.equals(getIntent().getAction())) {
232 restoreState(getIntent().getExtras());
238 super.onCreate(state);
245 protected void onNewIntent(Intent intent) {
247 if (Intent.ACTION_SEARCH.equals(getIntent().getAction())) {
256 protected void onPause() {
258 overridePendingTransition(R.anim.hold_in, R.anim.translate_to_left_out);
266 protected void onDestroy() {
269 unregisterReceiver(this.mOnSettingChangeReceiver);
270 } catch (Throwable ex) {/**NON BLOCK**/}
277 protected void onSaveInstanceState(Bundle outState) {
279 Log.d(TAG, "SearchActivity.onSaveInstanceState"); //$NON-NLS-1$
282 super.onSaveInstanceState(outState);
286 * Method that save the instance of the activity.
288 * @param state The current state of the activity
290 private void saveState(Bundle state) {
292 if (this.mSearchListView.getAdapter() != null) {
293 state.putParcelable(EXTRA_SEARCH_RESTORE, createSearchInfo());
295 } catch (Throwable ex) {
296 Log.w(TAG, "The state can't be saved", ex); //$NON-NLS-1$
301 * Method that restore the instance of the activity.
303 * @param state The previous state of the activity
305 private void restoreState(Bundle state) {
307 if (state.containsKey(EXTRA_SEARCH_RESTORE)) {
308 this.mRestoreState = state.getParcelable(EXTRA_SEARCH_RESTORE);
310 } catch (Throwable ex) {
311 Log.w(TAG, "The state can't be restored", ex); //$NON-NLS-1$
316 * Method that initializes the titlebar of the activity.
318 private void initTitleActionBar() {
319 //Configure the action bar options
320 getActionBar().setBackgroundDrawable(
321 getResources().getDrawable(R.drawable.bg_holo_titlebar));
322 getActionBar().setDisplayOptions(
323 ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);
324 getActionBar().setDisplayHomeAsUpEnabled(true);
325 View customTitle = getLayoutInflater().inflate(R.layout.simple_customtitle, null, false);
327 TextView title = (TextView)customTitle.findViewById(R.id.customtitle_title);
328 title.setText(R.string.search);
329 title.setContentDescription(getString(R.string.search));
330 ButtonItem configuration = (ButtonItem)customTitle.findViewById(R.id.ab_button1);
331 configuration.setImageResource(R.drawable.ic_holo_light_config);
332 configuration.setVisibility(View.VISIBLE);
334 getActionBar().setCustomView(customTitle);
338 * Method that initializes the component of the activity.
340 private void initComponents() {
342 this.mEmptyListMsg = findViewById(R.id.search_empty_msg);
344 this.mSearchListView = (ListView)findViewById(R.id.search_listview);
345 this.mSearchListView.setOnItemClickListener(this);
346 this.mSearchListView.setOnItemLongClickListener(this);
349 this.mSearchWaiting = (ProgressBar)findViewById(R.id.search_waiting);
350 this.mSearchFoundItems = (TextView)findViewById(R.id.search_status_found_items);
351 setFoundItems(0, ""); //$NON-NLS-1$
352 this.mSearchTerms = (TextView)findViewById(R.id.search_status_query_terms);
353 this.mSearchTerms.setText(
354 Html.fromHtml(getString(R.string.search_terms, ""))); //$NON-NLS-1$
358 * Method invoked when an action item is clicked.
360 * @param view The button pushed
362 public void onActionBarItemClick(View view) {
363 switch (view.getId()) {
364 case R.id.ab_button1:
366 Intent settings = new Intent(this, SettingsPreferences.class);
368 PreferenceActivity.EXTRA_SHOW_FRAGMENT,
369 SearchPreferenceFragment.class.getName());
370 startActivity(settings);
379 * Method that initializes the titlebar of the activity.
381 private void initSearch() {
382 //Stop any pending action
384 if (SearchActivity.this.mDrawingSearchResultTask != null
385 && SearchActivity.this.mDrawingSearchResultTask.isRunning()) {
386 SearchActivity.this.mDrawingSearchResultTask.cancel(true);
388 } catch (Throwable ex2) {
392 if (SearchActivity.this.mDialog != null) {
393 SearchActivity.this.mDialog.dismiss();
395 } catch (Throwable ex2) {
399 //Recovery the search directory
400 Bundle bundle = getIntent().getBundleExtra(SearchManager.APP_DATA);
401 //If data is not present, use root directory to do the search
402 this.mSearchDirectory = FileHelper.ROOT_DIRECTORY;
403 if (bundle != null) {
404 this.mSearchDirectory =
405 bundle.getString(EXTRA_SEARCH_DIRECTORY, FileHelper.ROOT_DIRECTORY);
408 //Retrieve the query ¿from voice recognizer?
409 boolean voiceQuery = true;
410 List<String> userQueries =
411 getIntent().getStringArrayListExtra(android.speech.RecognizerIntent.EXTRA_RESULTS);
412 if (userQueries == null || userQueries.size() == 0) {
414 userQueries = new ArrayList<String>();
415 //Recovers and save the last term search in the memory
416 Preferences.setLastSearch(getIntent().getStringExtra(SearchManager.QUERY));
417 userQueries.add(Preferences.getLastSearch());
421 //Filter the queries? Needed if queries come from voice recognition
422 final List<String> filteredUserQueries =
423 (voiceQuery) ? filterQuery(userQueries) : userQueries;
426 this.mQuery = new Query().fillSlots(filteredUserQueries);
427 List<String> queries = this.mQuery.getQueries();
429 //Check if some queries has lower than allowed, in this case
430 //request the user for stop the search
432 int cc = queries.size();
433 for (int i = 0; i < cc; i++) {
434 if (queries.get(i).trim().length() < MIN_CHARS_SEARCH) {
440 askUserBeforeSearch(voiceQuery, this.mQuery, this.mSearchDirectory);
442 doSearch(voiceQuery, this.mQuery, this.mSearchDirectory);
448 * Method that ask the user before do the search.
450 * @param voiceQuery Indicates if the query is from voice recognition
451 * @param query The terms of the search
452 * @param searchDirectory The directory of the search
454 private void askUserBeforeSearch(
455 final boolean voiceQuery, final Query query, final String searchDirectory) {
456 //Show a dialog asking the user
458 DialogHelper.createYesNoDialog(
459 this, R.string.search_few_characters_msg,
460 new DialogInterface.OnClickListener() {
462 public void onClick(DialogInterface alertDialog, int which) {
463 if (which == DialogInterface.BUTTON_NEGATIVE) {
464 doSearch(voiceQuery, query, searchDirectory);
468 //Close search activity
469 back(true, null, false);
476 * Method that do the search.
478 * @param voiceQuery Indicates if the query is from voice recognition
479 * @param query The terms of the search
480 * @param searchDirectory The directory of the search
484 final boolean voiceQuery, final Query query, final String searchDirectory) {
486 // Recovers the user preferences about save suggestions
487 boolean saveSuggestions = Preferences.getSharedPreferences().getBoolean(
488 FileManagerSettings.SETTINGS_SAVE_SEARCH_TERMS.getId(),
489 ((Boolean)FileManagerSettings.SETTINGS_SAVE_SEARCH_TERMS.
490 getDefaultValue()).booleanValue());
491 if (saveSuggestions) {
492 //Save every query for use as recent suggestions
493 SearchRecentSuggestions suggestions =
494 new SearchRecentSuggestions(this,
495 RecentSearchesContentProvider.AUTHORITY,
496 RecentSearchesContentProvider.MODE);
498 List<String> queries = query.getQueries();
499 int cc = queries.size();
500 for (int i = 0; i < cc; i++) {
501 suggestions.saveRecentQuery(queries.get(i), null);
507 this.mResultList = new ArrayList<FileSystemObject>();
508 SearchResultAdapter adapter =
509 new SearchResultAdapter(this,
510 new ArrayList<SearchResult>(), R.layout.search_item, this.mQuery);
511 this.mSearchListView.setAdapter(adapter);
514 this.mSearchTerms.setText(
515 Html.fromHtml(getString(R.string.search_terms, query.getTerms())));
518 //Now, do the search in background
519 this.mSearchListView.post(new Runnable() {
523 //Retrieve the terms of the search
524 String label = getString(R.string.searching_action_label);
526 //Show a dialog for the progress
527 SearchActivity.this.mDialog =
528 new MessageProgressDialog(
530 R.drawable.ic_holo_light_search,
531 R.string.searching, label, true);
535 // Set the cancel listener
536 SearchActivity.this.mDialog.setOnCancelListener(
537 new MessageProgressDialog.OnCancelListener() {
539 public boolean onCancel() {
540 //User has requested the cancellation of the search
541 //Broadcast the cancellation
542 if (!SearchActivity.this.mExecutable.isCancelled()) {
543 if (SearchActivity.this.mExecutable.cancel()) {
544 ListAdapter listAdapter =
546 this.mSearchListView.getAdapter();
547 if (listAdapter != null) {
548 SearchActivity.this.toggleResults(
549 listAdapter.getCount() > 0, true);
558 SearchActivity.this.mDialog.show();
560 //Execute the query (search are process in background)
561 SearchActivity.this.mExecutable =
562 CommandHelper.findFiles(
565 SearchActivity.this.mQuery,
569 } catch (Throwable ex) {
570 //Remove all elements
572 SearchActivity.this.removeAll();
573 } catch (Throwable ex2) {
577 if (SearchActivity.this.mDialog != null) {
578 SearchActivity.this.mDialog.dismiss();
580 } catch (Throwable ex2) {
584 //Capture the exception
585 Log.e(TAG, "Search failed", ex); //$NON-NLS-1$
586 DialogHelper.showToast(
588 R.string.search_error_msg, Toast.LENGTH_SHORT);
589 SearchActivity.this.mSearchListView.setVisibility(View.GONE);
596 * Method that restore the activity from the cached data.
598 private void loadFromCacheData() {
599 this.mSearchListView.post(new Runnable() {
603 List<SearchResult> list = SearchActivity.this.mRestoreState.getSearchResultList();
604 String directory = SearchActivity.this.mRestoreState.getSearchDirectory();
605 SearchActivity.this.toggleResults(list.size() > 0, true);
606 setFoundItems(list.size(), directory);
609 Query query = SearchActivity.this.mRestoreState.getSearchQuery();
611 TextUtils.join(" | ", //$NON-NLS-1$;
612 query.getQueries().toArray(new String[]{}));
613 if (terms.endsWith(" | ")) { //$NON-NLS-1$;
614 terms = ""; //$NON-NLS-1$;
616 SearchActivity.this.mSearchTerms.setText(
617 Html.fromHtml(getString(R.string.search_terms, terms)));
620 if (SearchActivity.this.mSearchWaiting != null) {
621 SearchActivity.this.mSearchWaiting.setVisibility(View.VISIBLE);
624 //Add list to the listview
625 if (SearchActivity.this.mSearchListView.getAdapter() != null) {
626 ((SearchResultAdapter)SearchActivity.this.
627 mSearchListView.getAdapter()).clear();
629 SearchResultAdapter adapter =
630 new SearchResultAdapter(
631 SearchActivity.this.mSearchListView.getContext(),
633 R.layout.search_item,
635 SearchActivity.this.mSearchListView.setAdapter(adapter);
636 SearchActivity.this.mSearchListView.setSelection(0);
638 } catch (Throwable ex) {
639 //Capture the exception
640 ExceptionUtil.translateException(SearchActivity.this, ex);
644 if (SearchActivity.this.mSearchWaiting != null) {
645 SearchActivity.this.mSearchWaiting.setVisibility(View.GONE);
654 * Method that filter the user queries for valid queries only.<br/>
656 * Only allow query strings with more that 3 characters
658 * @param original The original user queries
659 * @return List<String> The list of queries filtered
661 @SuppressWarnings("static-method")
662 private List<String> filterQuery(List<String> original) {
663 List<String> dst = new ArrayList<String>(original);
665 for (int i = cc - 1; i >= 0; i--) {
666 String query = dst.get(i);
667 if (query == null || query.trim().length() < MIN_CHARS_SEARCH) {
675 * Method that removes all items and display a message.
679 SearchResultAdapter adapter = (SearchResultAdapter)this.mSearchListView.getAdapter();
681 adapter.notifyDataSetChanged();
682 this.mSearchListView.setSelection(0);
683 toggleResults(false, true);
687 * Method that toggle the views when there are results.
689 * @param hasResults Indicates if there are results
690 * @param showEmpty Show the empty list message
693 void toggleResults(boolean hasResults, boolean showEmpty) {
694 this.mSearchListView.setVisibility(hasResults ? View.VISIBLE : View.INVISIBLE);
695 this.mEmptyListMsg.setVisibility(!hasResults && showEmpty ? View.VISIBLE : View.INVISIBLE);
699 * Method that display the number of found items.
701 * @param items The number of items
702 * @param searchDirectory The search directory path
705 void setFoundItems(final int items, final String searchDirectory) {
706 if (this.mSearchFoundItems != null) {
707 this.mSearchFoundItems.post(new Runnable() {
710 String directory = searchDirectory;
711 if (SearchActivity.this.mChRooted &&
712 directory != null && directory.length() > 0) {
713 directory = StorageHelper.getChrootedPath(directory);
719 R.plurals.search_found_items, items, Integer.valueOf(items));
720 SearchActivity.this.mSearchFoundItems.setText(
722 R.string.search_found_items_in_directory,
734 public boolean onKeyUp(int keyCode, KeyEvent event) {
736 case KeyEvent.KEYCODE_BACK:
737 back(true, null, false);
740 return super.onKeyUp(keyCode, event);
748 public boolean onOptionsItemSelected(MenuItem item) {
749 switch (item.getItemId()) {
750 case android.R.id.home:
751 back(true, null, false);
754 return super.onOptionsItemSelected(item);
762 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
764 SearchResult result = ((SearchResultAdapter)parent.getAdapter()).getItem(position);
765 FileSystemObject fso = result.getFso();
766 if (fso instanceof Directory) {
767 back(false, fso, false);
768 } else if (fso instanceof Symlink) {
769 Symlink symlink = (Symlink)fso;
770 if (symlink.getLinkRef() != null && symlink.getLinkRef() instanceof Directory) {
771 back(false, symlink.getLinkRef(), false);
774 // Open the file with the preferred registered app
775 back(false, fso, false);
777 } catch (Throwable ex) {
778 ExceptionUtil.translateException(this.mSearchListView.getContext(), ex);
786 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
787 // Different actions depending on user preference
789 // Get the adapter, the search result and the fso
790 SearchResultAdapter adapter = ((SearchResultAdapter)parent.getAdapter());
791 SearchResult searchResult = adapter.getItem(position);
792 FileSystemObject fso = searchResult.getFso();
794 // Open the actions menu
796 return true; //Always consume the event
800 * Method invoked when a request to show the menu associated
801 * with an item is started.
803 * @param item The item for which the request was started
805 public void onRequestMenu(FileSystemObject item) {
806 // Prior to show the dialog, refresh the item reference
807 FileSystemObject fso = null;
809 fso = CommandHelper.getFileInfo(this, item.getFullPath(), false, null);
811 throw new NoSuchFileOrDirectory(item.getFullPath());
814 } catch (Exception e) {
816 ExceptionUtil.translateException(this, e);
819 if (e instanceof FileNotFoundException || e instanceof NoSuchFileOrDirectory) {
825 ActionsDialog dialog = new ActionsDialog(this, fso, false, true);
826 dialog.setOnRequestRefreshListener(this);
831 * Method that removes the {@link FileSystemObject} reference
833 * @param fso The file system object
835 private void removeItem(FileSystemObject fso) {
836 SearchResultAdapter adapter =
837 (SearchResultAdapter)this.mSearchListView.getAdapter();
838 if (adapter != null) {
839 int pos = adapter.getPosition(fso);
841 SearchResult sr = adapter.getItem(pos);
846 toggleResults(adapter.getCount() > 0, true);
847 setFoundItems(adapter.getCount(), this.mSearchDirectory);
855 public void onRequestRefresh(Object o) {
856 // Refresh only the item
857 SearchResultAdapter adapter =
858 (SearchResultAdapter)this.mSearchListView.getAdapter();
859 if (adapter != null) {
860 if (o instanceof FileSystemObject) {
862 FileSystemObject fso = (FileSystemObject)o;
863 int pos = adapter.getPosition(fso);
865 SearchResult sr = adapter.getItem(pos);
868 } else if (o == null) {
870 List<SearchResult> results = adapter.getData();
871 this.mResultList = new ArrayList<FileSystemObject>(results.size());
872 int cc = results.size();
873 for (int i = 0; i < cc; i++) {
874 this.mResultList.add(results.get(i).getFso());
885 public void onRequestRemove(Object o) {
886 if (o instanceof FileSystemObject) {
887 removeItem((FileSystemObject)o);
895 public void onNavigateTo(Object o) {
896 if (o instanceof FileSystemObject) {
897 back(false, (FileSystemObject)o, true);
902 * Method that returns to previous activity.
904 * @param cancelled Indicates if the activity was cancelled
905 * @param item The fso
908 void back(final boolean cancelled, FileSystemObject item, boolean isChecked) {
909 Intent intent = new Intent();
911 if (SearchActivity.this.mDrawingSearchResultTask != null
912 && SearchActivity.this.mDrawingSearchResultTask.isRunning()) {
913 SearchActivity.this.mDrawingSearchResultTask.cancel(true);
915 if (this.mRestoreState != null) {
917 NavigationActivity.EXTRA_SEARCH_LAST_SEARCH_DATA,
918 (Parcelable)this.mRestoreState);
920 setResult(RESULT_CANCELED, intent);
922 // Check that the bookmark exists
924 FileSystemObject fso = item;
926 fso = CommandHelper.getFileInfo(this, item.getFullPath(), null);
929 if (FileHelper.isDirectory(fso)) {
930 intent.putExtra(NavigationActivity.EXTRA_SEARCH_ENTRY_SELECTION, fso);
932 NavigationActivity.EXTRA_SEARCH_LAST_SEARCH_DATA,
933 (Parcelable)createSearchInfo());
934 setResult(RESULT_OK, intent);
936 // Open the file here, so when focus back to the app, the search activity
937 // its in top of the stack
938 IntentsActionPolicy.openFileSystemObject(this, fso, false, null, null);
942 // The fso not exists, delete the fso from the search
945 } catch (Exception ex) {/**NON BLOCK**/}
948 } catch (Exception e) {
949 // Capture the exception
950 ExceptionUtil.translateException(this, e);
951 if (e instanceof NoSuchFileOrDirectory || e instanceof FileNotFoundException) {
952 // The fso not exists, delete the fso from the search
955 } catch (Exception ex) {/**NON BLOCK**/}
967 public void onAsyncStart() {
968 runOnUiThread(new Runnable() {
971 SearchActivity.this.toggleResults(false, false);
980 public void onAsyncEnd(boolean cancelled) {
981 this.mSearchListView.post(new Runnable() {
986 if (SearchActivity.this.mDialog != null) {
987 SearchActivity.this.mDialog.dismiss();
990 // Resolve the symlinks
991 FileHelper.resolveSymlinks(
992 SearchActivity.this, SearchActivity.this.mResultList);
997 } catch (Throwable ex) {
998 Log.e(TAG, "onAsyncEnd method fails", ex); //$NON-NLS-1$
1008 @SuppressWarnings("unchecked")
1009 public void onPartialResult(final Object partialResults) {
1010 //Saved in the global result list, for save at the end
1011 if (partialResults instanceof FileSystemObject) {
1012 SearchActivity.this.mResultList.add((FileSystemObject)partialResults);
1014 SearchActivity.this.mResultList.addAll((List<FileSystemObject>)partialResults);
1018 this.mSearchListView.post(new Runnable() {
1021 if (SearchActivity.this.mDialog != null) {
1022 int progress = SearchActivity.this.mResultList.size();
1023 setProgressMsg(progress);
1033 public void onAsyncExitCode(int exitCode) {/**NON BLOCK**/}
1039 public void onException(Exception cause) {
1040 //Capture the exception
1041 ExceptionUtil.translateException(this, cause);
1045 * Method that draw the results in the listview
1048 void drawResults() {
1050 this.toggleResults(this.mResultList.size() > 0, true);
1051 setFoundItems(this.mResultList.size(), this.mSearchDirectory);
1053 //Create the task for drawing the data
1054 this.mDrawingSearchResultTask =
1055 new SearchResultDrawingAsyncTask(
1056 this.mSearchListView,
1057 this.mSearchWaiting,
1060 this.mDrawingSearchResultTask.execute();
1064 * Method that creates a {@link SearchInfoParcelable} reference from
1067 * @return SearchInfoParcelable The search info reference
1069 private SearchInfoParcelable createSearchInfo() {
1070 SearchInfoParcelable parcel = new SearchInfoParcelable();
1071 parcel.setSearchDirectory(this.mSearchDirectory);
1072 parcel.setSearchResultList(
1073 ((SearchResultAdapter)this.mSearchListView.getAdapter()).getData());
1074 parcel.setSearchQuery(this.mQuery);
1079 * Method that set the progress of the search
1081 * @param progress The progress
1084 void setProgressMsg(int progress) {
1086 getResources().getQuantityString(
1087 R.plurals.search_found_items,
1089 Integer.valueOf(progress));
1090 SearchActivity.this.mDialog.setProgress(Html.fromHtml(msg));