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.res.Configuration;
29 import android.net.Uri;
30 import android.nfc.NfcAdapter;
31 import android.nfc.NfcEvent;
32 import android.os.Bundle;
33 import android.os.Handler;
34 import android.os.Parcelable;
35 import android.os.storage.StorageVolume;
36 import android.util.Log;
37 import android.view.KeyEvent;
38 import android.view.Menu;
39 import android.view.MenuItem;
40 import android.view.View;
41 import android.view.ViewGroup;
42 import android.widget.AdapterView;
43 import android.widget.AdapterView.OnItemClickListener;
44 import android.widget.ImageView;
45 import android.widget.LinearLayout;
46 import android.widget.ListPopupWindow;
47 import android.widget.PopupWindow;
48 import android.widget.TextView;
49 import android.widget.Toast;
51 import com.cyanogenmod.filemanager.FileManagerApplication;
52 import com.cyanogenmod.filemanager.R;
53 import com.cyanogenmod.filemanager.activities.preferences.SettingsPreferences;
54 import com.cyanogenmod.filemanager.adapters.HighlightedSimpleMenuListAdapter;
55 import com.cyanogenmod.filemanager.adapters.MenuSettingsAdapter;
56 import com.cyanogenmod.filemanager.adapters.SimpleMenuListAdapter;
57 import com.cyanogenmod.filemanager.console.Console;
58 import com.cyanogenmod.filemanager.console.ConsoleAllocException;
59 import com.cyanogenmod.filemanager.console.ConsoleBuilder;
60 import com.cyanogenmod.filemanager.console.InsufficientPermissionsException;
61 import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
62 import com.cyanogenmod.filemanager.listeners.OnHistoryListener;
63 import com.cyanogenmod.filemanager.listeners.OnRequestRefreshListener;
64 import com.cyanogenmod.filemanager.model.DiskUsage;
65 import com.cyanogenmod.filemanager.model.FileSystemObject;
66 import com.cyanogenmod.filemanager.model.History;
67 import com.cyanogenmod.filemanager.model.MountPoint;
68 import com.cyanogenmod.filemanager.parcelables.HistoryNavigable;
69 import com.cyanogenmod.filemanager.parcelables.NavigationViewInfoParcelable;
70 import com.cyanogenmod.filemanager.parcelables.SearchInfoParcelable;
71 import com.cyanogenmod.filemanager.preferences.AccessMode;
72 import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
73 import com.cyanogenmod.filemanager.preferences.NavigationLayoutMode;
74 import com.cyanogenmod.filemanager.preferences.ObjectIdentifier;
75 import com.cyanogenmod.filemanager.preferences.Preferences;
76 import com.cyanogenmod.filemanager.ui.ThemeManager;
77 import com.cyanogenmod.filemanager.ui.ThemeManager.Theme;
78 import com.cyanogenmod.filemanager.ui.dialogs.ActionsDialog;
79 import com.cyanogenmod.filemanager.ui.dialogs.FilesystemInfoDialog;
80 import com.cyanogenmod.filemanager.ui.dialogs.FilesystemInfoDialog.OnMountListener;
81 import com.cyanogenmod.filemanager.ui.widgets.Breadcrumb;
82 import com.cyanogenmod.filemanager.ui.widgets.ButtonItem;
83 import com.cyanogenmod.filemanager.ui.widgets.NavigationCustomTitleView;
84 import com.cyanogenmod.filemanager.ui.widgets.NavigationView;
85 import com.cyanogenmod.filemanager.ui.widgets.NavigationView.OnNavigationRequestMenuListener;
86 import com.cyanogenmod.filemanager.ui.widgets.NavigationView.OnNavigationSelectionChangedListener;
87 import com.cyanogenmod.filemanager.ui.widgets.SelectionView;
88 import com.cyanogenmod.filemanager.util.AndroidHelper;
89 import com.cyanogenmod.filemanager.util.CommandHelper;
90 import com.cyanogenmod.filemanager.util.DialogHelper;
91 import com.cyanogenmod.filemanager.util.ExceptionUtil;
92 import com.cyanogenmod.filemanager.util.ExceptionUtil.OnRelaunchCommandResult;
93 import com.cyanogenmod.filemanager.util.FileHelper;
94 import com.cyanogenmod.filemanager.util.StorageHelper;
97 import java.io.FileNotFoundException;
98 import java.io.Serializable;
99 import java.util.ArrayList;
100 import java.util.Arrays;
101 import java.util.List;
104 * The main navigation activity. This activity is the center of the application.
105 * From this the user can navigate, search, make actions.<br/>
106 * This activity is singleTop, so when it is displayed no other activities exists in
108 * This cause an issue with the saved instance of this class, because if another activity
109 * is displayed, and the process is killed, NavigationActivity is started and the saved
110 * instance gets corrupted.<br/>
111 * For this reason the methods {link {@link Activity#onSaveInstanceState(Bundle)} and
112 * {@link Activity#onRestoreInstanceState(Bundle)} are not implemented, and every time
113 * the app is killed, is restarted from his initial state.
115 public class NavigationActivity extends Activity
116 implements OnHistoryListener, OnRequestRefreshListener,
117 OnNavigationRequestMenuListener, OnNavigationSelectionChangedListener {
119 private static final String TAG = "NavigationActivity"; //$NON-NLS-1$
121 private static boolean DEBUG = false;
124 * Intent code for request a bookmark selection.
126 public static final int INTENT_REQUEST_BOOKMARK = 10001;
129 * Intent code for request a history selection.
131 public static final int INTENT_REQUEST_HISTORY = 20001;
134 * Intent code for request a search.
136 public static final int INTENT_REQUEST_SEARCH = 30001;
140 * Constant for extra information about selected bookmark.
142 public static final String EXTRA_BOOKMARK_SELECTION =
143 "extra_bookmark_selection"; //$NON-NLS-1$
146 * Constant for extra information about selected history entry.
148 public static final String EXTRA_HISTORY_ENTRY_SELECTION =
149 "extra_history_entry_selection"; //$NON-NLS-1$
152 * Constant for extra information about clear selection action.
154 public static final String EXTRA_HISTORY_CLEAR =
155 "extra_history_clear_history"; //$NON-NLS-1$
158 * Constant for extra information about selected search entry.
160 public static final String EXTRA_SEARCH_ENTRY_SELECTION =
161 "extra_search_entry_selection"; //$NON-NLS-1$
164 * Constant for extra information about last search data.
166 public static final String EXTRA_SEARCH_LAST_SEARCH_DATA =
167 "extra_search_last_search_data"; //$NON-NLS-1$
170 * Constant for extra information for request a navigation to the passed path.
172 public static final String EXTRA_NAVIGATE_TO =
173 "extra_navigate_to"; //$NON-NLS-1$
175 // The timeout needed to reset the exit status for back button
176 // After this time user need to tap 2 times the back button to
177 // exit, and the toast is shown again after the first tap.
178 private static final int RELEASE_EXIT_CHECK_TIMEOUT = 3500;
180 private final BroadcastReceiver mNotificationReceiver = new BroadcastReceiver() {
182 public void onReceive(Context context, Intent intent) {
183 if (intent != null) {
184 if (intent.getAction().compareTo(FileManagerSettings.INTENT_SETTING_CHANGED) == 0) {
185 // The settings has changed
186 String key = intent.getStringExtra(FileManagerSettings.EXTRA_SETTING_CHANGED_KEY);
188 // Disk usage warning level
189 if (key.compareTo(FileManagerSettings.
190 SETTINGS_DISK_USAGE_WARNING_LEVEL.getId()) == 0) {
192 // Set the free disk space warning level of the breadcrumb widget
193 Breadcrumb breadcrumb = getCurrentNavigationView().getBreadcrumb();
194 String fds = Preferences.getSharedPreferences().getString(
195 FileManagerSettings.SETTINGS_DISK_USAGE_WARNING_LEVEL.getId(),
196 (String)FileManagerSettings.
197 SETTINGS_DISK_USAGE_WARNING_LEVEL.getDefaultValue());
198 breadcrumb.setFreeDiskSpaceWarningLevel(Integer.parseInt(fds));
199 breadcrumb.updateMountPointInfo();
203 // Case sensitive sort
204 if (key.compareTo(FileManagerSettings.
205 SETTINGS_CASE_SENSITIVE_SORT.getId()) == 0) {
206 getCurrentNavigationView().refresh();
211 if (key.compareTo(FileManagerSettings.
212 SETTINGS_USE_FLINGER.getId()) == 0) {
214 Preferences.getSharedPreferences().getBoolean(
215 FileManagerSettings.SETTINGS_USE_FLINGER.getId(),
216 ((Boolean)FileManagerSettings.
217 SETTINGS_USE_FLINGER.
218 getDefaultValue()).booleanValue());
219 getCurrentNavigationView().setUseFlinger(useFlinger);
224 if (key.compareTo(FileManagerSettings.
225 SETTINGS_ACCESS_MODE.getId()) == 0) {
226 // Is it necessary to create or exit of the ChRooted?
228 FileManagerApplication.
229 getAccessMode().compareTo(AccessMode.SAFE) == 0;
230 if (chRooted != NavigationActivity.this.mChRooted) {
239 // Filetime format mode
240 if (key.compareTo(FileManagerSettings.
241 SETTINGS_FILETIME_FORMAT_MODE.getId()) == 0) {
243 synchronized (FileHelper.DATETIME_SYNC) {
244 FileHelper.sReloadDateTimeFormats = true;
245 NavigationActivity.this.getCurrentNavigationView().refresh();
250 } else if (intent.getAction().compareTo(
251 FileManagerSettings.INTENT_FILE_CHANGED) == 0) {
252 // Retrieve the file that was changed
254 intent.getStringExtra(FileManagerSettings.EXTRA_FILE_CHANGED_KEY);
256 FileSystemObject fso = CommandHelper.getFileInfo(context, file, null);
258 getCurrentNavigationView().refresh(fso);
260 } catch (Exception e) {
261 ExceptionUtil.translateException(context, e, true, false);
264 } else if (intent.getAction().compareTo(
265 FileManagerSettings.INTENT_THEME_CHANGED) == 0) {
268 } else if (intent.getAction().compareTo(Intent.ACTION_TIME_CHANGED) == 0 ||
269 intent.getAction().compareTo(Intent.ACTION_DATE_CHANGED) == 0 ||
270 intent.getAction().compareTo(Intent.ACTION_TIMEZONE_CHANGED) == 0) {
272 synchronized (FileHelper.DATETIME_SYNC) {
273 FileHelper.sReloadDateTimeFormats = true;
274 NavigationActivity.this.getCurrentNavigationView().refresh();
284 NavigationView[] mNavigationViews;
285 private List<History> mHistory;
287 private int mCurrentNavigationView;
289 private ViewGroup mActionBar;
290 private SelectionView mSelectionBar;
292 private boolean mExitFlag = false;
293 private long mExitBackTimeout = -1;
295 private View mOptionsAnchorView;
297 private int mOrientation;
313 protected void onCreate(Bundle state) {
316 Log.d(TAG, "NavigationActivity.onCreate"); //$NON-NLS-1$
319 // Register the broadcast receiver
320 IntentFilter filter = new IntentFilter();
321 filter.addAction(FileManagerSettings.INTENT_SETTING_CHANGED);
322 filter.addAction(FileManagerSettings.INTENT_FILE_CHANGED);
323 filter.addAction(FileManagerSettings.INTENT_THEME_CHANGED);
324 filter.addAction(Intent.ACTION_DATE_CHANGED);
325 filter.addAction(Intent.ACTION_TIME_CHANGED);
326 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
327 registerReceiver(this.mNotificationReceiver, filter);
329 //Set the main layout of the activity
330 setContentView(R.layout.navigation);
332 //Initialize nfc adapter
333 NfcAdapter mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
334 if (mNfcAdapter != null) {
335 mNfcAdapter.setBeamPushUrisCallback(new NfcAdapter.CreateBeamUrisCallback() {
337 public Uri[] createBeamUris(NfcEvent event) {
338 List<FileSystemObject> selectedFiles =
339 getCurrentNavigationView().getSelectedFiles();
340 if (selectedFiles.size() > 0) {
341 List<Uri> fileUri = new ArrayList<Uri>();
342 for (FileSystemObject f : selectedFiles) {
343 //Beam ignores folders and system files
344 if (!FileHelper.isDirectory(f) && !FileHelper.isSystemFile(f)) {
345 fileUri.add(Uri.fromFile(new File(f.getFullPath())));
348 if (fileUri.size() > 0) {
349 return fileUri.toArray(new Uri[fileUri.size()]);
357 //Initialize activity
361 initNavigationViews();
363 //Initialize action bars
364 initTitleActionBar();
365 initStatusActionBar();
368 // Adjust layout (only when start on landscape mode)
369 int orientation = getResources().getConfiguration().orientation;
370 if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
373 this.mOrientation = orientation;
378 // Show welcome message
381 this.mHandler = new Handler();
382 this.mHandler.post(new Runnable() {
385 //Initialize navigation
386 int cc = NavigationActivity.this.mNavigationViews.length;
387 for (int i = 0; i < cc; i++) {
388 initNavigation(i, false);
391 //Check the intent action
392 checkIntent(getIntent());
397 super.onCreate(state);
404 protected void onNewIntent(Intent intent) {
405 //Initialize navigation
406 initNavigation(this.mCurrentNavigationView, true);
408 //Check the intent action
416 public void onConfigurationChanged(Configuration newConfig) {
417 super.onConfigurationChanged(newConfig);
425 protected void onDestroy() {
427 Log.d(TAG, "NavigationActivity.onDestroy"); //$NON-NLS-1$
430 // Unregister the receiver
432 unregisterReceiver(this.mNotificationReceiver);
433 } catch (Throwable ex) {
437 //All destroy. Continue
442 * Method that returns the current navigation view.
444 * @return NavigationView The current navigation view
446 public NavigationView getCurrentNavigationView() {
447 return getNavigationView(this.mCurrentNavigationView);
451 * Method that returns the current navigation view.
453 * @param viewId The view to return
454 * @return NavigationView The current navigation view
456 public NavigationView getNavigationView(int viewId) {
457 if (this.mNavigationViews == null) return null;
458 return this.mNavigationViews[viewId];
462 * Method that initializes the activity.
464 private void init() {
465 this.mHistory = new ArrayList<History>();
466 this.mChRooted = FileManagerApplication.getAccessMode().compareTo(AccessMode.SAFE) == 0;
470 * Method that displays a welcome message the first time the user
471 * access the application
473 private void showWelcomeMsg() {
474 boolean firstUse = Preferences.getSharedPreferences().getBoolean(
475 FileManagerSettings.SETTINGS_FIRST_USE.getId(),
476 ((Boolean)FileManagerSettings.SETTINGS_FIRST_USE.getDefaultValue()).booleanValue());
478 //Display the welcome message?
480 AlertDialog dialog = DialogHelper.createAlertDialog(
481 this, R.drawable.ic_launcher,
482 R.string.welcome_title, getString(R.string.welcome_msg), false);
483 DialogHelper.delegateDialogShow(this, dialog);
485 // Don't display again this dialog
487 Preferences.savePreference(
488 FileManagerSettings.SETTINGS_FIRST_USE, Boolean.FALSE, true);
489 } catch (Exception e) {/**NON BLOCK**/}
494 * Method that initializes the titlebar of the activity.
496 private void initTitleActionBar() {
497 //Inflate the view and associate breadcrumb
498 View titleLayout = getLayoutInflater().inflate(
499 R.layout.navigation_view_customtitle, null, false);
500 NavigationCustomTitleView title =
501 (NavigationCustomTitleView)titleLayout.findViewById(R.id.navigation_title_flipper);
502 title.setOnHistoryListener(this);
503 Breadcrumb breadcrumb = (Breadcrumb)title.findViewById(R.id.breadcrumb_view);
504 int cc = this.mNavigationViews.length;
505 for (int i = 0; i < cc; i++) {
506 this.mNavigationViews[i].setBreadcrumb(breadcrumb);
507 this.mNavigationViews[i].setOnHistoryListener(this);
508 this.mNavigationViews[i].setOnNavigationSelectionChangedListener(this);
509 this.mNavigationViews[i].setOnNavigationOnRequestMenuListener(this);
510 this.mNavigationViews[i].setCustomTitle(title);
513 // Set the free disk space warning level of the breadcrumb widget
514 String fds = Preferences.getSharedPreferences().getString(
515 FileManagerSettings.SETTINGS_DISK_USAGE_WARNING_LEVEL.getId(),
516 (String)FileManagerSettings.SETTINGS_DISK_USAGE_WARNING_LEVEL.getDefaultValue());
517 breadcrumb.setFreeDiskSpaceWarningLevel(Integer.parseInt(fds));
519 //Configure the action bar options
520 getActionBar().setBackgroundDrawable(
521 getResources().getDrawable(R.drawable.bg_holo_titlebar));
522 getActionBar().setDisplayOptions(
523 ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);
524 getActionBar().setCustomView(titleLayout);
528 * Method that initializes the statusbar of the activity.
530 private void initStatusActionBar() {
531 //Performs a width calculation of buttons. Buttons exceeds the width
532 //of the action bar should be hidden
533 //This application not use android ActionBar because the application
534 //make uses of the title and bottom areas, and wants to force to show
535 //the overflow button (without care of physical buttons)
536 this.mActionBar = (ViewGroup)findViewById(R.id.navigation_actionbar);
537 this.mActionBar.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
539 public void onLayoutChange(
540 View v, int left, int top, int right, int bottom, int oldLeft,
541 int oldTop, int oldRight, int oldBottom) {
542 //Get the width of the action bar
543 int w = v.getMeasuredWidth();
545 //Wake through children calculation his dimensions
546 int bw = (int)getResources().getDimension(R.dimen.default_buttom_width);
548 final ViewGroup abView = ((ViewGroup)v);
549 int cc = abView.getChildCount();
550 for (int i = 0; i < cc; i++) {
551 View child = abView.getChildAt(i);
552 child.setVisibility(cw + bw > w ? View.INVISIBLE : View.VISIBLE);
558 // Have overflow menu?
559 View overflow = findViewById(R.id.ab_overflow);
560 boolean showOptionsMenu = AndroidHelper.showOptionsMenu(getApplicationContext());
561 overflow.setVisibility(showOptionsMenu ? View.VISIBLE : View.GONE);
562 this.mOptionsAnchorView = showOptionsMenu ? overflow : this.mActionBar;
564 // Show the status bar
565 View statusBar = findViewById(R.id.navigation_statusbar_portrait_holder);
566 statusBar.setVisibility(View.VISIBLE);
570 * Method that initializes the selectionbar of the activity.
572 private void initSelectionBar() {
573 this.mSelectionBar = (SelectionView)findViewById(R.id.navigation_selectionbar);
577 * Method that initializes the navigation views of the activity
579 private void initNavigationViews() {
580 //Get the navigation views (wishlist: multiple view; for now only one view)
581 this.mNavigationViews = new NavigationView[1];
582 this.mCurrentNavigationView = 0;
584 this.mNavigationViews[0] = (NavigationView)findViewById(R.id.navigation_view);
585 this.mNavigationViews[0].setId(0);
589 * Method that initializes the navigation.
591 * @param viewId The navigation view identifier where apply the navigation
592 * @param restore Initialize from a restore info
595 void initNavigation(final int viewId, final boolean restore) {
596 final NavigationView navigationView = getNavigationView(viewId);
597 this.mHandler.post(new Runnable() {
600 //Create the default console (from the preferences)
602 Console console = ConsoleBuilder.getConsole(NavigationActivity.this);
603 if (console == null) {
604 throw new ConsoleAllocException("console == null"); //$NON-NLS-1$
606 } catch (Throwable ex) {
607 if (!NavigationActivity.this.mChRooted) {
608 //Show exception and exit
609 Log.e(TAG, getString(R.string.msgs_cant_create_console), ex);
610 // We don't have any console
611 // Show exception and exit
612 DialogHelper.showToast(
613 NavigationActivity.this,
614 R.string.msgs_cant_create_console, Toast.LENGTH_LONG);
619 // We are in a trouble (something is not allowing creating the console)
620 // Ask the user to return to prompt or root access mode mode with a
621 // non-privileged console, prior to make crash the application
626 //Is necessary navigate?
628 applyInitialDir(navigationView);
635 * Method that applies the user-defined initial directory
637 * @param navigationView The navigation view
640 void applyInitialDir(final NavigationView navigationView) {
641 //Load the user-defined initial directory
643 Preferences.getSharedPreferences().getString(
644 FileManagerSettings.SETTINGS_INITIAL_DIR.getId(),
645 (String)FileManagerSettings.
646 SETTINGS_INITIAL_DIR.getDefaultValue());
648 // Check if request navigation to directory (use as default), and
649 // ensure chrooted and absolute path
650 String navigateTo = getIntent().getStringExtra(EXTRA_NAVIGATE_TO);
651 if (navigateTo != null && navigateTo.length() > 0) {
652 initialDir = navigateTo;
655 if (this.mChRooted) {
656 // Initial directory is the first external sdcard (sdcard, emmc, usb, ...)
657 StorageVolume[] volumes =
658 StorageHelper.getStorageVolumes(this);
659 if (volumes != null && volumes.length > 0) {
660 initialDir = volumes[0].getPath();
661 //Ensure that initial directory is an absolute directory
662 initialDir = FileHelper.getAbsPath(initialDir);
664 // Show exception and exit
665 DialogHelper.showToast(
667 R.string.msgs_cant_create_console, Toast.LENGTH_LONG);
672 //Ensure that initial directory is an absolute directory
673 final String userInitialDir = initialDir;
674 initialDir = FileHelper.getAbsPath(initialDir);
675 final String absInitialDir = initialDir;
676 File f = new File(initialDir);
677 boolean exists = f.exists();
679 // Fix for /data/media/0. Libcore doesn't detect it correctly.
681 exists = CommandHelper.getFileInfo(this, initialDir, false, null) != null;
682 } catch (InsufficientPermissionsException ipex) {
683 ExceptionUtil.translateException(
684 this, ipex, false, true, new OnRelaunchCommandResult() {
686 public void onSuccess() {
687 navigationView.changeCurrentDir(absInitialDir);
690 public void onFailed(Throwable cause) {
691 showInitialInvalidDirectoryMsg(userInitialDir);
692 navigationView.changeCurrentDir(FileHelper.ROOT_DIRECTORY);
695 public void onCancelled() {
696 showInitialInvalidDirectoryMsg(userInitialDir);
697 navigationView.changeCurrentDir(FileHelper.ROOT_DIRECTORY);
703 } catch (Exception ex) {
704 // We are not interested in other exceptions
705 ExceptionUtil.translateException(this, ex, true, false);
708 // Check again the initial directory
710 showInitialInvalidDirectoryMsg(userInitialDir);
711 initialDir = FileHelper.ROOT_DIRECTORY;
714 // Weird, but we have a valid initial directory
718 // Change the current directory to the user-defined initial directory
719 navigationView.changeCurrentDir(initialDir);
723 * Displays a message reporting invalid directory
725 * @param initialDir The initial directory
728 void showInitialInvalidDirectoryMsg(String initialDir) {
729 // Change to root directory
730 DialogHelper.showToast(
733 R.string.msgs_settings_invalid_initial_directory,
739 * Method that verifies the intent passed to the activity, and checks
740 * if a request is made like Search.
742 * @param intent The intent to check
745 void checkIntent(Intent intent) {
747 if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
748 Intent searchIntent = new Intent(this, SearchActivity.class);
749 searchIntent.setAction(Intent.ACTION_SEARCH);
750 //- SearchActivity.EXTRA_SEARCH_DIRECTORY
751 searchIntent.putExtra(
752 SearchActivity.EXTRA_SEARCH_DIRECTORY,
753 getCurrentNavigationView().getCurrentDir());
754 //- SearchManager.APP_DATA
755 if (intent.getBundleExtra(SearchManager.APP_DATA) != null) {
756 Bundle bundle = new Bundle();
757 bundle.putAll(intent.getBundleExtra(SearchManager.APP_DATA));
758 searchIntent.putExtra(SearchManager.APP_DATA, bundle);
760 //-- SearchManager.QUERY
761 String query = intent.getStringExtra(SearchManager.QUERY);
763 searchIntent.putExtra(SearchManager.QUERY, query);
765 //- android.speech.RecognizerIntent.EXTRA_RESULTS
766 ArrayList<String> extraResults =
767 intent.getStringArrayListExtra(android.speech.RecognizerIntent.EXTRA_RESULTS);
768 if (extraResults != null) {
769 searchIntent.putStringArrayListExtra(
770 android.speech.RecognizerIntent.EXTRA_RESULTS, extraResults);
772 startActivityForResult(searchIntent, INTENT_REQUEST_SEARCH);
776 // Navigate to the requested path
777 String navigateTo = intent.getStringExtra(EXTRA_NAVIGATE_TO);
778 if (navigateTo != null && navigateTo.length() >= 0) {
779 getCurrentNavigationView().changeCurrentDir(navigateTo);
787 public boolean onKeyUp(int keyCode, KeyEvent event) {
788 if (keyCode == KeyEvent.KEYCODE_MENU) {
789 showOverflowPopUp(this.mOptionsAnchorView);
792 if (keyCode == KeyEvent.KEYCODE_BACK) {
793 if (checkBackAction()) {
797 // An exit event has occurred, force the destroy the consoles
800 return super.onKeyUp(keyCode, event);
807 public boolean onOptionsItemSelected(MenuItem item) {
808 switch (item.getItemId()) {
809 case android.R.id.home:
810 if ((getActionBar().getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP)
811 == ActionBar.DISPLAY_HOME_AS_UP) {
816 return super.onOptionsItemSelected(item);
821 * Method invoked when an action item is clicked.
823 * @param view The button pushed
825 public void onActionBarItemClick(View view) {
826 switch (view.getId()) {
827 //######################
828 //Navigation Custom Title
829 //######################
830 case R.id.ab_configuration:
831 //Show navigation view configuration toolbar
832 getCurrentNavigationView().getCustomTitle().showConfigurationView();
833 getActionBar().setDisplayHomeAsUpEnabled(true);
834 getActionBar().setHomeButtonEnabled(true);
837 //Hide navigation view configuration toolbar
838 getCurrentNavigationView().getCustomTitle().hideConfigurationView();
841 //######################
843 //######################
844 case R.id.ab_filesystem_info:
845 //Show information of the filesystem
846 MountPoint mp = getCurrentNavigationView().getBreadcrumb().getMountPointInfo();
847 DiskUsage du = getCurrentNavigationView().getBreadcrumb().getDiskUsageInfo();
848 showMountPointInfo(mp, du);
851 //######################
852 //Navigation view options
853 //######################
854 case R.id.ab_sort_mode:
855 showSettingsPopUp(view,
857 new FileManagerSettings[]{
858 FileManagerSettings.SETTINGS_SORT_MODE}));
860 case R.id.ab_layout_mode:
861 showSettingsPopUp(view,
863 new FileManagerSettings[]{
864 FileManagerSettings.SETTINGS_LAYOUT_MODE}));
866 case R.id.ab_view_options:
867 // If we are in ChRooted mode, then don't show non-secure items
868 if (this.mChRooted) {
869 showSettingsPopUp(view,
870 Arrays.asList(new FileManagerSettings[]{
871 FileManagerSettings.SETTINGS_SHOW_DIRS_FIRST}));
873 showSettingsPopUp(view,
874 Arrays.asList(new FileManagerSettings[]{
875 FileManagerSettings.SETTINGS_SHOW_DIRS_FIRST,
876 FileManagerSettings.SETTINGS_SHOW_HIDDEN,
877 FileManagerSettings.SETTINGS_SHOW_SYSTEM,
878 FileManagerSettings.SETTINGS_SHOW_SYMLINKS}));
883 //######################
885 //######################
886 case R.id.ab_selection_done:
887 //Show information of the filesystem
888 getCurrentNavigationView().onDeselectAll();
891 //######################
893 //######################
894 case R.id.ab_actions:
895 openActionsDialog(getCurrentNavigationView().getCurrentDir(), true);
898 case R.id.ab_bookmarks:
902 case R.id.ab_history:
910 case R.id.ab_overflow:
911 showOverflowPopUp(view);
923 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
925 switch (requestCode) {
926 case INTENT_REQUEST_BOOKMARK:
927 if (resultCode == RESULT_OK) {
928 FileSystemObject fso =
929 (FileSystemObject)data.
930 getSerializableExtra(EXTRA_BOOKMARK_SELECTION);
933 getCurrentNavigationView().open(fso);
938 case INTENT_REQUEST_HISTORY:
939 if (resultCode == RESULT_OK) {
940 //Change current directory
942 (History)data.getSerializableExtra(EXTRA_HISTORY_ENTRY_SELECTION);
943 navigateToHistory(history);
944 } else if (resultCode == RESULT_CANCELED) {
945 boolean clear = data.getBooleanExtra(EXTRA_HISTORY_CLEAR, false);
952 case INTENT_REQUEST_SEARCH:
953 if (resultCode == RESULT_OK) {
955 FileSystemObject fso =
956 (FileSystemObject)data.
957 getSerializableExtra(EXTRA_SEARCH_ENTRY_SELECTION);
958 SearchInfoParcelable searchInfo =
959 data.getParcelableExtra(EXTRA_SEARCH_LAST_SEARCH_DATA);
961 //Goto to new directory
962 getCurrentNavigationView().open(fso, searchInfo);
964 } else if (resultCode == RESULT_CANCELED) {
965 SearchInfoParcelable searchInfo =
966 data.getParcelableExtra(EXTRA_SEARCH_LAST_SEARCH_DATA);
967 if (searchInfo != null && searchInfo.isSuccessNavigation()) {
968 //Navigate to previous history
971 // I don't know is the search view was changed, so try to do a refresh
972 // of the navigation view
973 getCurrentNavigationView().refresh(true);
988 public void onNewHistory(HistoryNavigable navigable) {
989 //Recollect information about current status
990 History history = new History(this.mHistory.size(), navigable);
991 this.mHistory.add(history);
992 getActionBar().setDisplayHomeAsUpEnabled(true);
993 getActionBar().setHomeButtonEnabled(true);
1000 public void onCheckHistory() {
1001 //Need to show HomeUp Button
1002 boolean enabled = this.mHistory != null && this.mHistory.size() > 0;
1003 getActionBar().setDisplayHomeAsUpEnabled(enabled);
1004 getActionBar().setHomeButtonEnabled(enabled);
1011 public void onRequestRefresh(Object o, boolean clearSelection) {
1012 if (o instanceof FileSystemObject) {
1013 // Refresh only the item
1014 this.getCurrentNavigationView().refresh((FileSystemObject)o);
1015 } else if (o == null) {
1017 getCurrentNavigationView().refresh();
1019 if (clearSelection) {
1020 this.getCurrentNavigationView().onDeselectAll();
1028 public void onRequestRemove(Object o, boolean clearSelection) {
1029 if (o instanceof FileSystemObject) {
1031 this.getCurrentNavigationView().removeItem((FileSystemObject)o);
1033 //Remove from history
1034 removeFromHistory((FileSystemObject)o);
1036 onRequestRefresh(null, clearSelection);
1038 if (clearSelection) {
1039 this.getCurrentNavigationView().onDeselectAll();
1047 public void onNavigateTo(Object o) {
1055 public void onSelectionChanged(NavigationView navView, List<FileSystemObject> selectedItems) {
1056 this.mSelectionBar.setSelection(selectedItems);
1063 public void onRequestMenu(NavigationView navView, FileSystemObject item) {
1064 // Show the actions dialog
1065 openActionsDialog(item, false);
1069 * Method that shows a popup with a menu associated a {@link FileManagerSettings}.
1071 * @param anchor The action button that was pressed
1072 * @param settings The array of settings associated with the action button
1074 private void showSettingsPopUp(View anchor, List<FileManagerSettings> settings) {
1075 //Create the adapter
1076 final MenuSettingsAdapter adapter = new MenuSettingsAdapter(this, settings);
1078 //Create a show the popup menu
1079 final ListPopupWindow popup = DialogHelper.createListPopupWindow(this, adapter, anchor);
1080 popup.setOnItemClickListener(new OnItemClickListener() {
1082 public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
1083 FileManagerSettings setting =
1084 ((MenuSettingsAdapter)parent.getAdapter()).getSetting(position);
1085 final int value = ((MenuSettingsAdapter)parent.getAdapter()).getId(position);
1088 if (setting.compareTo(FileManagerSettings.SETTINGS_LAYOUT_MODE) == 0) {
1089 //Need to change the layout
1090 getCurrentNavigationView().changeViewMode(
1091 NavigationLayoutMode.fromId(value));
1094 if (setting.getDefaultValue() instanceof Enum<?>) {
1096 Preferences.savePreference(setting, new ObjectIdentifier() {
1098 public int getId() {
1105 Preferences.getSharedPreferences().
1108 ((Boolean)setting.getDefaultValue()).booleanValue());
1109 Preferences.savePreference(setting, Boolean.valueOf(!newval), false);
1111 getCurrentNavigationView().refresh();
1113 } catch (Exception e) {
1114 Log.e(TAG, "Error applying navigation option", e); //$NON-NLS-1$
1115 NavigationActivity.this.mHandler.post(new Runnable() {
1118 DialogHelper.showToast(
1119 NavigationActivity.this,
1120 R.string.msgs_settings_save_failure, Toast.LENGTH_SHORT);
1126 getCurrentNavigationView().getCustomTitle().restoreView();
1131 popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
1133 public void onDismiss() {
1141 * Method that shows a popup with the activity main menu.
1143 * @param anchor The action button that was pressed
1145 private void showOverflowPopUp(View anchor) {
1146 SimpleMenuListAdapter adapter =
1147 new HighlightedSimpleMenuListAdapter(this, R.menu.navigation);
1148 Menu menu = adapter.getMenu();
1149 int cc = this.mActionBar.getChildCount();
1150 for (int i = 0, j = this.mActionBar.getChildCount() - 1; i < cc; i++, j--) {
1151 View child = this.mActionBar.getChildAt(i);
1152 boolean visible = child.getVisibility() == View.VISIBLE;
1154 menu.removeItem(menu.getItem(j).getItemId());
1158 final ListPopupWindow popup = DialogHelper.createListPopupWindow(this, adapter, anchor);
1159 popup.setOnItemClickListener(new OnItemClickListener() {
1161 public void onItemClick(
1162 final AdapterView<?> parent, final View v, final int position, final long id) {
1164 final int itemId = (int)id;
1165 NavigationActivity.this.mHandler.post(new Runnable() {
1170 case R.id.mnu_settings:
1172 Intent settings = new Intent(
1173 NavigationActivity.this, SettingsPreferences.class);
1174 startActivity(settings);
1177 case R.id.mnu_history:
1183 case R.id.mnu_bookmarks:
1189 case R.id.mnu_search:
1205 * Method that show the information of a filesystem mount point.
1207 * @param mp The mount point info
1208 * @param du The disk usage of the mount point
1210 private void showMountPointInfo(MountPoint mp, DiskUsage du) {
1211 //Has mount point info?
1213 //There is no information
1215 DialogHelper.createWarningDialog(
1217 R.string.filesystem_info_warning_title,
1218 R.string.filesystem_info_warning_msg);
1219 DialogHelper.delegateDialogShow(this, alert);
1223 //Show a the filesystem info dialog
1224 FilesystemInfoDialog dialog = new FilesystemInfoDialog(this, mp, du);
1225 dialog.setOnMountListener(new OnMountListener() {
1227 public void onRemount(MountPoint mountPoint) {
1228 //Update the statistics of breadcrumb, only if mount point is the same
1229 Breadcrumb breadcrumb = getCurrentNavigationView().getBreadcrumb();
1230 if (breadcrumb.getMountPointInfo().compareTo(mountPoint) == 0) {
1231 breadcrumb.updateMountPointInfo();
1239 * Method that checks the action that must be realized when the
1240 * back button is pushed.
1242 * @return boolean Indicates if the action must be intercepted
1244 private boolean checkBackAction() {
1245 // We need a basic structure to check this
1246 if (getCurrentNavigationView() == null) return false;
1248 //Check if the configuration view is showing. In this case back
1249 //action must be "close configuration"
1250 if (getCurrentNavigationView().getCustomTitle().isConfigurationViewShowing()) {
1251 getCurrentNavigationView().getCustomTitle().restoreView();
1255 //Do back operation over the navigation history
1256 boolean flag = this.mExitFlag;
1258 this.mExitFlag = !back();
1260 // Retrieve if the exit status timeout has expired
1261 long now = System.currentTimeMillis();
1262 boolean timeout = (this.mExitBackTimeout == -1 ||
1263 (now - this.mExitBackTimeout) > RELEASE_EXIT_CHECK_TIMEOUT);
1265 //Check if there no history and if the user was advised in the last back action
1266 if (this.mExitFlag && (this.mExitFlag != flag || timeout)) {
1267 //Communicate the user that the next time the application will be closed
1268 this.mExitBackTimeout = System.currentTimeMillis();
1269 DialogHelper.showToast(this, R.string.msgs_push_again_to_exit, Toast.LENGTH_SHORT);
1273 //Back action not applied
1274 return !this.mExitFlag;
1281 public boolean onSearchRequested() {
1282 Bundle bundle = new Bundle();
1284 SearchActivity.EXTRA_SEARCH_DIRECTORY,
1285 getCurrentNavigationView().getCurrentDir());
1286 startSearch(Preferences.getLastSearch(), true, bundle, false);
1291 * Method that returns the history size.
1293 private void clearHistory() {
1294 this.mHistory.clear();
1299 * Method that navigates to the passed history reference.
1301 * @param history The history reference
1302 * @return boolean A problem occurs while navigate
1304 public boolean navigateToHistory(History history) {
1307 History realHistory = this.mHistory.get(history.getPosition());
1309 //Navigate to item. Check what kind of history is
1310 if (realHistory.getItem() instanceof NavigationViewInfoParcelable) {
1312 NavigationViewInfoParcelable info =
1313 (NavigationViewInfoParcelable)realHistory.getItem();
1314 int viewId = info.getId();
1315 NavigationView view = getNavigationView(viewId);
1316 // Selected items must not be restored from on history navigation
1317 info.setSelectedFiles(view.getSelectedFiles());
1318 view.onRestoreState(info);
1320 } else if (realHistory.getItem() instanceof SearchInfoParcelable) {
1321 //Search (open search with the search results)
1322 SearchInfoParcelable info = (SearchInfoParcelable)realHistory.getItem();
1323 Intent searchIntent = new Intent(this, SearchActivity.class);
1324 searchIntent.setAction(SearchActivity.ACTION_RESTORE);
1325 searchIntent.putExtra(SearchActivity.EXTRA_SEARCH_RESTORE, (Parcelable)info);
1326 startActivityForResult(searchIntent, INTENT_REQUEST_SEARCH);
1328 //The type is unknown
1329 throw new IllegalArgumentException("Unknown history type"); //$NON-NLS-1$
1332 //Remove the old history
1333 int cc = realHistory.getPosition();
1334 for (int i = this.mHistory.size() - 1; i >= cc; i--) {
1335 this.mHistory.remove(i);
1337 if (this.mHistory.size() == 0) {
1338 getActionBar().setDisplayHomeAsUpEnabled(false);
1339 getActionBar().setHomeButtonEnabled(false);
1345 } catch (Throwable ex) {
1346 if (history != null) {
1348 String.format("Failed to navigate to history %d: %s", //$NON-NLS-1$
1349 Integer.valueOf(history.getPosition()),
1350 history.getItem().getTitle()), ex);
1353 String.format("Failed to navigate to history: null", ex)); //$NON-NLS-1$
1355 this.mHandler.post(new Runnable() {
1358 DialogHelper.showToast(
1359 NavigationActivity.this,
1360 R.string.msgs_history_unknown, Toast.LENGTH_LONG);
1364 //Not change directory
1370 * Method that request a back action over the navigation history.
1372 * @return boolean If a back action was applied
1374 public boolean back() {
1375 // Check that has valid history
1376 while (this.mHistory.size() > 0) {
1377 History h = this.mHistory.get(this.mHistory.size() - 1);
1378 if (h.getItem() instanceof NavigationViewInfoParcelable) {
1379 // Verify that the path exists
1380 String path = ((NavigationViewInfoParcelable)h.getItem()).getCurrentDir();
1383 FileSystemObject info = CommandHelper.getFileInfo(this, path, null);
1387 this.mHistory.remove(this.mHistory.size() - 1);
1388 } catch (Exception e) {
1389 ExceptionUtil.translateException(this, e, true, false);
1390 this.mHistory.remove(this.mHistory.size() - 1);
1397 //Extract a history from the
1398 if (this.mHistory.size() > 0) {
1399 //Navigate to history
1400 return navigateToHistory(this.mHistory.get(this.mHistory.size() - 1));
1408 * Method that opens the actions dialog
1410 * @param item The path or the {@link FileSystemObject}
1411 * @param global If the menu to display is the one with global actions
1413 private void openActionsDialog(Object item, boolean global) {
1414 // Resolve the full path
1415 String path = String.valueOf(item);
1416 if (item instanceof FileSystemObject) {
1417 path = ((FileSystemObject)item).getFullPath();
1420 // Prior to show the dialog, refresh the item reference
1421 FileSystemObject fso = null;
1423 fso = CommandHelper.getFileInfo(this, path, false, null);
1425 throw new NoSuchFileOrDirectory(path);
1428 } catch (Exception e) {
1430 ExceptionUtil.translateException(this, e);
1432 // Remove the object
1433 if (e instanceof FileNotFoundException || e instanceof NoSuchFileOrDirectory) {
1434 // If have a FileSystemObject reference then there is no need to search
1435 // the path (less resources used)
1436 if (item instanceof FileSystemObject) {
1437 getCurrentNavigationView().removeItem((FileSystemObject)item);
1439 getCurrentNavigationView().removeItem((String)item);
1446 ActionsDialog dialog = new ActionsDialog(this, fso, global, false);
1447 dialog.setOnRequestRefreshListener(this);
1448 dialog.setOnSelectionListener(getCurrentNavigationView());
1453 * Method that opens the bookmarks activity.
1456 void openBookmarks() {
1457 Intent bookmarksIntent = new Intent(this, BookmarksActivity.class);
1458 bookmarksIntent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
1459 startActivityForResult(bookmarksIntent, INTENT_REQUEST_BOOKMARK);
1463 * Method that opens the history activity.
1466 void openHistory() {
1467 Intent historyIntent = new Intent(this, HistoryActivity.class);
1468 historyIntent.putExtra(HistoryActivity.EXTRA_HISTORY_LIST, (Serializable)this.mHistory);
1469 historyIntent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
1470 startActivityForResult(historyIntent, INTENT_REQUEST_HISTORY);
1474 * Method that opens the search activity.
1478 onSearchRequested();
1482 * Method that remove the {@link FileSystemObject} from the history
1484 private void removeFromHistory(FileSystemObject fso) {
1485 if (this.mHistory != null) {
1486 int cc = this.mHistory.size();
1487 for (int i = cc-1; i >= 0 ; i--) {
1488 History history = this.mHistory.get(i);
1489 if (history.getItem() instanceof NavigationViewInfoParcelable) {
1490 String p0 = fso.getFullPath();
1492 ((NavigationViewInfoParcelable)history.getItem()).getCurrentDir();
1493 if (p0.compareTo(p1) == 0) {
1494 this.mHistory.remove(i);
1502 * Method that ask the user to change the access mode prior to crash.
1506 //Show a dialog asking the user
1507 AlertDialog dialog =
1508 DialogHelper.createYesNoDialog(
1510 R.string.msgs_change_to_prompt_access_mode_title,
1511 R.string.msgs_change_to_prompt_access_mode_msg,
1512 new DialogInterface.OnClickListener() {
1514 public void onClick(DialogInterface alertDialog, int which) {
1515 if (which == DialogInterface.BUTTON_NEGATIVE) {
1516 // We don't have any console
1517 // Show exception and exit
1518 DialogHelper.showToast(
1519 NavigationActivity.this,
1520 R.string.msgs_cant_create_console, Toast.LENGTH_LONG);
1525 // Ok. Now try to change to prompt mode. Any crash
1526 // here is a fatal error. We won't have any console to operate.
1529 ConsoleBuilder.changeToNonPrivilegedConsole(NavigationActivity.this);
1532 Preferences.savePreference(
1533 FileManagerSettings.SETTINGS_ACCESS_MODE,
1534 AccessMode.PROMPT, true);
1536 } catch (Exception e) {
1537 // Displays an exception and exit
1538 Log.e(TAG, getString(R.string.msgs_cant_create_console), e);
1539 DialogHelper.showToast(
1540 NavigationActivity.this,
1541 R.string.msgs_cant_create_console, Toast.LENGTH_LONG);
1546 DialogHelper.delegateDialogShow(this, dialog);
1550 * Method that creates a ChRooted environment, protecting the user to break anything in
1554 void createChRooted() {
1555 // If we are in a ChRooted mode, then do nothing
1556 if (this.mChRooted) return;
1557 this.mChRooted = true;
1559 int cc = this.mNavigationViews.length;
1560 for (int i = 0; i < cc; i++) {
1561 this.mNavigationViews[i].createChRooted();
1564 // Remove the selection
1565 cc = this.mNavigationViews.length;
1566 for (int i = 0; i < cc; i++) {
1567 getCurrentNavigationView().onDeselectAll();
1570 // Remove the history (don't allow to access to previous data)
1575 * Method that exits from a ChRooted
1578 void exitChRooted() {
1579 // If we aren't in a ChRooted mode, then do nothing
1580 if (!this.mChRooted) return;
1581 this.mChRooted = false;
1583 int cc = this.mNavigationViews.length;
1584 for (int i = 0; i < cc; i++) {
1585 this.mNavigationViews[i].exitChRooted();
1590 * Method called when a controlled exit is required
1595 FileManagerApplication.destroyBackgroundConsole();
1596 } catch (Throwable ex) {
1600 ConsoleBuilder.destroyConsole();
1601 } catch (Throwable ex) {
1608 * Method that reconfigures the layout for better fit in portrait and landscape modes
1610 private void onLayoutChanged() {
1611 Theme theme = ThemeManager.getCurrentTheme(this);
1613 // Apply only when the orientation was changed
1614 int orientation = getResources().getConfiguration().orientation;
1615 if (this.mOrientation == orientation) return;
1616 this.mOrientation = orientation;
1618 if (this.mOrientation == Configuration.ORIENTATION_LANDSCAPE) {
1620 ViewGroup statusBar = (ViewGroup)findViewById(R.id.navigation_statusbar);
1621 if (statusBar.getParent() != null) {
1622 ViewGroup parent = (ViewGroup) statusBar.getParent();
1623 parent.removeView(statusBar);
1626 // Calculate the action button size (all the buttons must fit in the title bar)
1627 int bw = (int)getResources().getDimension(R.dimen.default_buttom_width);
1628 int abw = this.mActionBar.getChildCount() * bw;
1630 int cc = statusBar.getChildCount();
1631 for (int i = 0; i < cc; i++) {
1632 View child = statusBar.getChildAt(i);
1633 if (child instanceof ButtonItem) {
1638 boolean showOptionsMenu = AndroidHelper.showOptionsMenu(getApplicationContext());
1639 if (!showOptionsMenu) {
1643 // Add to the new location
1644 ViewGroup newParent = (ViewGroup)findViewById(R.id.navigation_title_landscape_holder);
1645 LinearLayout.LayoutParams params =
1646 new LinearLayout.LayoutParams(
1648 ViewGroup.LayoutParams.MATCH_PARENT);
1649 statusBar.setLayoutParams(params);
1650 newParent.addView(statusBar);
1653 theme.setBackgroundDrawable(this, statusBar, "titlebar_drawable"); //$NON-NLS-1$
1656 View holder = findViewById(R.id.navigation_statusbar_portrait_holder);
1657 holder.setVisibility(View.GONE);
1661 ViewGroup statusBar = (ViewGroup)findViewById(R.id.navigation_statusbar);
1662 if (statusBar.getParent() != null) {
1663 ViewGroup parent = (ViewGroup) statusBar.getParent();
1664 parent.removeView(statusBar);
1667 // Add to the new location
1668 ViewGroup newParent = (ViewGroup)findViewById(
1669 R.id.navigation_statusbar_portrait_holder);
1670 LinearLayout.LayoutParams params =
1671 new LinearLayout.LayoutParams(
1672 ViewGroup.LayoutParams.MATCH_PARENT,
1673 ViewGroup.LayoutParams.MATCH_PARENT);
1674 statusBar.setLayoutParams(params);
1675 newParent.addView(statusBar);
1678 theme.setBackgroundDrawable(this, statusBar, "statusbar_drawable"); //$NON-NLS-1$
1681 newParent.setVisibility(View.VISIBLE);
1686 * Method that applies the current theme to the activity
1690 int orientation = getResources().getConfiguration().orientation;
1691 Theme theme = ThemeManager.getCurrentTheme(this);
1692 theme.setBaseTheme(this, false);
1695 View v = findViewById(R.id.navigation_layout);
1696 theme.setBackgroundDrawable(this, v, "background_drawable"); //$NON-NLS-1$
1698 theme.setTitlebarDrawable(this, getActionBar(), "titlebar_drawable"); //$NON-NLS-1$
1700 v = findViewById(R.id.navigation_statusbar);
1701 if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
1702 theme.setBackgroundDrawable(this, v, "titlebar_drawable"); //$NON-NLS-1$
1704 theme.setBackgroundDrawable(this, v, "statusbar_drawable"); //$NON-NLS-1$
1706 v = findViewById(R.id.ab_overflow);
1707 theme.setImageDrawable(this, (ImageView)v, "ab_overflow_drawable"); //$NON-NLS-1$
1708 v = findViewById(R.id.ab_actions);
1709 theme.setImageDrawable(this, (ImageView)v, "ab_actions_drawable"); //$NON-NLS-1$
1710 v = findViewById(R.id.ab_search);
1711 theme.setImageDrawable(this, (ImageView)v, "ab_search_drawable"); //$NON-NLS-1$
1712 v = findViewById(R.id.ab_bookmarks);
1713 theme.setImageDrawable(this, (ImageView)v, "ab_bookmarks_drawable"); //$NON-NLS-1$
1714 v = findViewById(R.id.ab_history);
1715 theme.setImageDrawable(this, (ImageView)v, "ab_history_drawable"); //$NON-NLS-1$
1717 v = findViewById(R.id.ab_configuration);
1718 theme.setImageDrawable(this, (ImageView)v, "expander_open_drawable"); //$NON-NLS-1$
1719 v = findViewById(R.id.ab_close);
1720 theme.setImageDrawable(this, (ImageView)v, "expander_close_drawable"); //$NON-NLS-1$
1721 v = findViewById(R.id.ab_sort_mode);
1722 theme.setImageDrawable(this, (ImageView)v, "ab_sort_mode_drawable"); //$NON-NLS-1$
1723 v = findViewById(R.id.ab_layout_mode);
1724 theme.setImageDrawable(this, (ImageView)v, "ab_layout_mode_drawable"); //$NON-NLS-1$
1725 v = findViewById(R.id.ab_view_options);
1726 theme.setImageDrawable(this, (ImageView)v, "ab_view_options_drawable"); //$NON-NLS-1$
1728 v = findViewById(R.id.navigation_selectionbar);
1729 theme.setBackgroundDrawable(this, v, "selectionbar_drawable"); //$NON-NLS-1$
1730 v = findViewById(R.id.ab_selection_done);
1731 theme.setImageDrawable(this, (ImageView)v, "ab_selection_done_drawable"); //$NON-NLS-1$
1732 v = findViewById(R.id.navigation_status_selection_label);
1733 theme.setTextColor(this, (TextView)v, "text_color"); //$NON-NLS-1$
1735 int cc = this.mNavigationViews.length;
1736 for (int i = 0; i < cc; i++) {
1737 getNavigationView(i).applyTheme();