</activity>
<activity
+ android:name=".activities.PickerActivity"
+ android:label="@string/picker"
+ android:uiOptions="none"
+ android:theme="@style/Explorer.Theme.Holo.Ligth.Overlay">
+ <intent-filter>
+ <action android:name="android.intent.action.GET_CONTENT" />
+ <category android:name="android.intent.category.OPENABLE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="*/*" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name=".activities.preferences.SettingsPreferences"
android:label="@string/pref"
android:icon="@drawable/ic_launcher_settings"
** limitations under the License.\r-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/default_background" >
+ android:layout_height="match_parent">
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
** limitations under the License.\r-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/default_background">
+ android:layout_height="match_parent">
<TextView
android:id="@+id/history_empty_msg"
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.\r-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:cmexplorer="http://schemas.android.com/apk/res/com.cyanogenmod.explorer"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
- android:background="@color/default_background" >
+ android:orientation="vertical">
<!-- Navigation View -->
<com.cyanogenmod.explorer.ui.widgets.NavigationView
android:id="@+id/navigation_view"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_weight="1" />
+ android:layout_weight="1"
+ cmexplorer:navigation="browsable" />
<!-- SelectionBar -->
<com.cyanogenmod.explorer.ui.widgets.SelectionView
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/navigation_view_item_check"
+ android:layout_alignWithParentIfMissing="true"
android:contentDescription="@null"
android:src="@null" />
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@id/navigation_view_item_menu"
- android:layout_toRightOf="@id/navigation_view_item_icon" >
+ android:layout_toRightOf="@id/navigation_view_item_icon"
+ android:layout_alignWithParentIfMissing="true">
<TextView
android:id="@+id/navigation_view_item_name"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/navigation_view_item_check"
+ android:layout_alignWithParentIfMissing="true"
android:contentDescription="@null"
android:src="@null" />
+ <com.cyanogenmod.explorer.ui.widgets.NonFocusableButtonItem
+ android:id="@+id/navigation_view_item_menu"
+ android:layout_width="@dimen/item_menu_row_button_width"
+ android:layout_height="match_parent"
+ android:layout_alignParentRight="true"
+ android:contentDescription="@null"
+ android:src="@drawable/ic_holo_light_arrow" />
+
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@id/navigation_view_item_menu"
- android:layout_toRightOf="@id/navigation_view_item_icon" >
+ android:layout_toRightOf="@id/navigation_view_item_icon"
+
+ android:layout_alignWithParentIfMissing="true" >
<TextView
android:id="@+id/navigation_view_item_name"
android:textAppearance="@style/primary_text_appearance" />
</RelativeLayout>
- <com.cyanogenmod.explorer.ui.widgets.NonFocusableButtonItem
- android:id="@+id/navigation_view_item_menu"
- android:layout_width="@dimen/item_menu_row_button_width"
- android:layout_height="match_parent"
- android:layout_alignParentRight="true"
- android:contentDescription="@null"
- android:src="@drawable/ic_holo_light_arrow" />
-
</RelativeLayout>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ** Copyright (C) 2012 The CyanogenMod Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.\r-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:cmexplorer="http://schemas.android.com/apk/res/com.cyanogenmod.explorer"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/default_background"
+ android:orientation="vertical">
+
+ <!-- Breadcrumb -->
+ <com.cyanogenmod.explorer.ui.widgets.BreadcrumbView
+ android:id="@+id/breadcrumb_view"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/default_row_height"
+ android:layout_marginLeft="@dimen/extra_large_margin"
+ android:layout_marginRight="@dimen/extra_large_margin"/>
+
+ <include layout="@layout/vertical_divider" />
+
+ <!-- Picker Navigation View -->
+ <com.cyanogenmod.explorer.ui.widgets.NavigationView
+ android:id="@+id/navigation_view"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:layout_marginLeft="@dimen/extra_margin"
+ android:layout_marginRight="@dimen/extra_margin"
+ cmexplorer:navigation="pickable" />
+
+</LinearLayout>
\ No newline at end of file
** limitations under the License.\r-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/default_background" >
+ android:layout_height="match_parent">
<TextView
android:id="@+id/search_empty_msg"
<!-- Bookmark definition -->
<declare-styleable name="Bookmark">
- <!-- The name of the bookmak -->
+ <!-- The name of the bookmark -->
<attr name="name" format="string" />
<!-- The folder which the bookmark point to -->
<attr name="directory" format="string" />
</declare-styleable>
+ <!-- Navigable definition -->
+ <declare-styleable name="Navigable">
+ <!-- The type of navigation -->
+ <attr name="navigation" format="integer">
+ <enum name="browsable" value="0" />
+ <enum name="pickable" value="1" />
+ </attr>
+ </declare-styleable>
+
</resources>
\ No newline at end of file
<!-- Usb storage descripton -->
<string name="usb_storage">Usb storage</string>
- <!-- ActionBar Buttons > FileSystem -->
+ <!-- ActionBar Buttons * FileSystem -->
<string name="actionbar_button_filesystem_cd">Filesystem info</string>
- <!-- ActionBar Buttons > Navigation View Configuration -->
+ <!-- ActionBar Buttons * Navigation View Configuration -->
<string name="actionbar_button_configuration_cd">Configuration</string>
- <!-- ActionBar Buttons > Sort Mode -->
+ <!-- ActionBar Buttons * Sort Mode -->
<string name="actionbar_button_sort_mode_cd">Sort mode</string>
- <!-- ActionBar Buttons > Layout Mode -->
+ <!-- ActionBar Buttons * Layout Mode -->
<string name="actionbar_button_layout_mode_cd">Layout mode</string>
- <!-- ActionBar Buttons > Other View Options -->
+ <!-- ActionBar Buttons * Other View Options -->
<string name="actionbar_button_other_view_options_cd">Other view options</string>
- <!-- ActionBar Buttons > Close -->
+ <!-- ActionBar Buttons * Close -->
<string name="actionbar_button_nav_close_cd">Close</string>
- <!-- ActionBar Buttons > Done -->
+ <!-- ActionBar Buttons * Done -->
<string name="actionbar_button_selection_done_cd">Done</string>
- <!-- ActionBar Buttons > Actions -->
+ <!-- ActionBar Buttons * Actions -->
<string name="actionbar_button_actions_cd">Actions</string>
- <!-- ActionBar Buttons > History -->
+ <!-- ActionBar Buttons * History -->
<string name="actionbar_button_history_cd">History</string>
- <!-- ActionBar Buttons > Bookmarks -->
+ <!-- ActionBar Buttons * Bookmarks -->
<string name="actionbar_button_bookmarks_cd">Bookmarks</string>
- <!-- ActionBar Buttons > Search -->
+ <!-- ActionBar Buttons * Search -->
<string name="actionbar_button_search_cd">Search</string>
- <!-- ActionBar Buttons > Overflow -->
+ <!-- ActionBar Buttons * Overflow -->
<string name="actionbar_button_overflow_cd">More options</string>
+ <!-- ActionBar Buttons * Storage volumes -->
+ <string name="actionbar_button_storage_cd">Storage volumes</string>
<!-- Navigation View * Sort * Sort by name (ascending) -->
<string name="sort_by_name_asc">By name ▲</string>
<!-- Search * Searching label -->
<string name="searching_action_label">Searching in progress</string>
+ <!-- Picker Activity -->
+ <string name="picker">@string/app_name</string>
+ <!-- Picker Activity * Dialog title -->
+ <string name="picker_title">Pick a file</string>
+
<!-- Bookmarks * Bookmarks activity title -->
<string name="bookmarks">Bookmarks</string>
<!-- Bookmarks * Bookmark name * Home -->
** limitations under the License.\r-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- The default theme -->
<style name="Explorer.Theme.Holo.Ligth" parent="@android:style/Theme.Holo.Light">
<item name="android:windowBackground">@color/default_background</item>
</style>
+ <!-- A theme with overlay -->
<style name="Explorer.Theme.Holo.Ligth.Overlay" parent="@android:style/Theme.Holo.Light">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@color/black_transparent</item>
--- /dev/null
+/*
+ * Copyright (C) 2012 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.cyanogenmod.explorer.activities;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.storage.StorageVolume;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.FrameLayout;
+import android.widget.ListPopupWindow;
+import android.widget.Toast;
+
+import com.cyanogenmod.explorer.R;
+import com.cyanogenmod.explorer.adapters.CheckableListAdapter;
+import com.cyanogenmod.explorer.adapters.CheckableListAdapter.CheckableItem;
+import com.cyanogenmod.explorer.console.ConsoleBuilder;
+import com.cyanogenmod.explorer.model.FileSystemObject;
+import com.cyanogenmod.explorer.preferences.ExplorerSettings;
+import com.cyanogenmod.explorer.preferences.Preferences;
+import com.cyanogenmod.explorer.ui.widgets.Breadcrumb;
+import com.cyanogenmod.explorer.ui.widgets.NavigationView;
+import com.cyanogenmod.explorer.ui.widgets.NavigationView.OnFilePickedListener;
+import com.cyanogenmod.explorer.util.DialogHelper;
+import com.cyanogenmod.explorer.util.ExceptionUtil;
+import com.cyanogenmod.explorer.util.FileHelper;
+import com.cyanogenmod.explorer.util.StorageHelper;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The activity for allow to use a {@link NavigationView} like, to pick a file from other
+ * application.
+ */
+public class PickerActivity extends Activity
+ implements OnCancelListener, OnDismissListener, OnFilePickedListener {
+
+ private static final String TAG = "PickerActivity"; //$NON-NLS-1$
+
+ private static boolean DEBUG = false;
+
+ private String mMimeType;
+ private FileSystemObject mFso; // The picked item
+ private AlertDialog mDialog;
+ private Handler mHandler;
+ /**
+ * @hide
+ */
+ NavigationView mNavigationView;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void onCreate(Bundle state) {
+ if (DEBUG) {
+ Log.d(TAG, "PickerActivity.onCreate"); //$NON-NLS-1$
+ }
+
+ // Initialize the activity
+ init();
+
+ //Save state
+ super.onCreate(state);
+ }
+
+ /**
+ * Method that displays a dialog with a {@link NavigationView} to select the
+ * proposed file
+ */
+ private void init() {
+ // Check that call has a valid request (GET_CONTENT a and mime type)
+ String action = getIntent().getAction();
+ this.mMimeType = getIntent().getType();
+ if (action.compareTo(Intent.ACTION_GET_CONTENT.toString()) != 0 ||
+ this.mMimeType == null) {
+ setResult(Activity.RESULT_CANCELED);
+ finish();
+ return;
+ }
+
+ // Create or use the console
+ if (!initializeConsole()) {
+ // Something when wrong. Display a message and exit
+ DialogHelper.showToast(this, R.string.msgs_cant_create_console, Toast.LENGTH_SHORT);
+ cancel();
+ return;
+ }
+
+ // Calculate the dialog size based on the window height
+ DisplayMetrics displaymetrics = new DisplayMetrics();
+ getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
+ final int height = displaymetrics.heightPixels;
+
+ // Create the root file
+ final View rootView = getLayoutInflater().inflate(R.layout.picker, null, false);
+ rootView.post(new Runnable() {
+ @Override
+ public void run() {
+ FrameLayout.LayoutParams params =
+ new FrameLayout.LayoutParams(
+ LayoutParams.WRAP_CONTENT, (height * 70) / 100);
+ rootView.setLayoutParams(params);
+ }
+ });
+
+ // Breadcrumb
+ Breadcrumb breadcrumb = (Breadcrumb)rootView.findViewById(R.id.breadcrumb_view);
+ // Set the free disk space warning level of the breadcrumb widget
+ String fds = Preferences.getSharedPreferences().getString(
+ ExplorerSettings.SETTINGS_DISK_USAGE_WARNING_LEVEL.getId(),
+ (String)ExplorerSettings.SETTINGS_DISK_USAGE_WARNING_LEVEL.getDefaultValue());
+ breadcrumb.setFreeDiskSpaceWarningLevel(Integer.parseInt(fds));
+
+ // Navigation view
+ this.mNavigationView =
+ (NavigationView)rootView.findViewById(R.id.navigation_view);
+ this.mNavigationView.setMimeType(this.mMimeType);
+ this.mNavigationView.setOnFilePickedListener(this);
+ this.mNavigationView.setBreadcrumb(breadcrumb);
+
+ // Create the dialog
+ this.mDialog = DialogHelper.createDialog(
+ this, R.drawable.ic_launcher, R.string.picker_title, rootView);
+ this.mDialog.setButton(
+ DialogInterface.BUTTON_NEUTRAL,
+ getString(R.string.cancel),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dlg, int which) {
+ dlg.cancel();
+ }
+ });
+ this.mDialog.setCancelable(true);
+ this.mDialog.setOnCancelListener(this);
+ this.mDialog.setOnDismissListener(this);
+ this.mDialog.show();
+
+ this.mHandler = new Handler();
+ this.mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // Navigate to. The navigation view will redirect to the appropriate directory
+ PickerActivity.this.mNavigationView.changeCurrentDir(FileHelper.ROOT_DIRECTORY);
+ }
+ });
+
+ }
+
+ /**
+ * Method that initializes a console
+ */
+ private boolean initializeConsole() {
+ try {
+ // Is there a console allocate
+ if (!ConsoleBuilder.isAlloc()) {
+ // Create a jail room console
+ ConsoleBuilder.createDefaultConsole(this, false, false);
+ }
+ // There is a console allocated. Use it.
+ return true;
+ } catch (Throwable _throw) {
+ // Capture the exception
+ ExceptionUtil.translateException(this, _throw, true, false);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void onDestroy() {
+ if (DEBUG) {
+ Log.d(TAG, "PickerActivity.onDestroy"); //$NON-NLS-1$
+ }
+
+ //All destroy. Continue
+ super.onDestroy();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ if (this.mFso != null) {
+ Intent result = new Intent();
+ result.setData(Uri.fromFile(new File(this.mFso.getFullPath())));
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ } else {
+ cancel();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ cancel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onFilePicked(FileSystemObject item) {
+ this.mFso = item;
+ this.mDialog.dismiss();
+ }
+
+ /**
+ * Method invoked when an action item is clicked.
+ *
+ * @param view The button pushed
+ */
+ public void onActionBarItemClick(View view) {
+ switch (view.getId()) {
+ //######################
+ //Breadcrumb Actions
+ //######################
+ case R.id.ab_filesystem_info:
+ //Show a popup with the storage volumes to select
+ showStorageVolumesPopUp(view);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Method that cancels the activity
+ */
+ private void cancel() {
+ setResult(Activity.RESULT_CANCELED);
+ finish();
+ }
+
+ /**
+ * Method that shows a popup with the storage volumes
+ *
+ * @param anchor The view on which anchor the popup
+ */
+ private void showStorageVolumesPopUp(View anchor) {
+ // Create a list (but not checkable)
+ final StorageVolume[] volumes = StorageHelper.getStorageVolumes(PickerActivity.this);
+ List<CheckableItem> descriptions = new ArrayList<CheckableItem>();
+ if (volumes != null) {
+ int cc = volumes.length;
+ for (int i = 0; i < cc; i++) {
+ String desc = StorageHelper.getStorageVolumeDescription(this, volumes[i]);
+ CheckableItem item = new CheckableItem(desc, false, false);
+ descriptions.add(item);
+ }
+ }
+ CheckableListAdapter adapter =
+ new CheckableListAdapter(getApplicationContext(), descriptions);
+
+ //Create a show the popup menu
+ final ListPopupWindow popup = DialogHelper.createListPopupWindow(this, adapter, anchor);
+ popup.setOnItemClickListener(new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
+ popup.dismiss();
+ if (volumes != null) {
+
+ PickerActivity.this.
+ mNavigationView.changeCurrentDir(volumes[position].getPath());
+ }
+ }
+ });
+ popup.show();
+ }
+}
private IconHolder mIconHolder;
private final int mItemViewResourceId;
private List<FileSystemObject> mSelectedItems;
+ private final boolean mPickable;
private OnSelectionChangedListener mOnSelectionChangedListener;
private OnRequestMenuListener mOnRequestMenuListener;
* @param files The list of file system objects
* @param itemViewResourceId The identifier of the layout that represents an item
* of the list adapter
+ * @param pickable If the adapter should act as a pickable browser.
*/
public FileSystemObjectAdapter(
- Context context, List<FileSystemObject> files, int itemViewResourceId) {
+ Context context, List<FileSystemObject> files,
+ int itemViewResourceId, boolean pickable) {
super(context, RESOURCE_ITEM_NAME, files);
this.mIconHolder = new IconHolder();
this.mItemViewResourceId = itemViewResourceId;
this.mSelectedItems = new ArrayList<FileSystemObject>();
+ this.mPickable = pickable;
//Do cache of the data for better performance
loadDefaultIcons();
viewHolder.mTvName = (TextView)v.findViewById(RESOURCE_ITEM_NAME);
viewHolder.mTvSummary = (TextView)v.findViewById(RESOURCE_ITEM_SUMMARY);
viewHolder.mTvSize = (TextView)v.findViewById(RESOURCE_ITEM_SIZE);
- viewHolder.mBtCheck = (ImageButton)v.findViewById(RESOURCE_ITEM_CHECK);
- viewHolder.mBtCheck.setOnClickListener(this);
- viewHolder.mBtMenu = (ImageButton)v.findViewById(RESOURCE_ITEM_MENU);
- viewHolder.mBtMenu.setOnClickListener(this);
+ if (!this.mPickable) {
+ viewHolder.mBtCheck = (ImageButton)v.findViewById(RESOURCE_ITEM_CHECK);
+ viewHolder.mBtCheck.setOnClickListener(this);
+ viewHolder.mBtMenu = (ImageButton)v.findViewById(RESOURCE_ITEM_MENU);
+ viewHolder.mBtMenu.setOnClickListener(this);
+ } else {
+ viewHolder.mBtCheck = (ImageButton)v.findViewById(RESOURCE_ITEM_CHECK);
+ viewHolder.mBtCheck.setVisibility(View.GONE);
+ viewHolder.mBtMenu = (ImageButton)v.findViewById(RESOURCE_ITEM_MENU);
+ viewHolder.mBtMenu.setVisibility(View.GONE);
+ }
v.setTag(viewHolder);
}
if (viewHolder.mTvSize != null) {
viewHolder.mTvSize.setText(dataHolder.mSize);
}
- viewHolder.mBtCheck.setVisibility(
- dataHolder.mName.compareTo(
- FileHelper.PARENT_DIRECTORY) == 0 ? View.INVISIBLE : View.VISIBLE);
- viewHolder.mBtCheck.setImageDrawable(dataHolder.mDwCheck);
- viewHolder.mBtCheck.setTag(Integer.valueOf(position));
- v.setBackgroundResource(
- dataHolder.mSelected
- ? R.drawable.holo_list_selector_selected
- : R.drawable.holo_list_selector_deseleted);
- viewHolder.mBtMenu.setVisibility(dataHolder.mHasMenu ? View.VISIBLE : View.GONE);
- viewHolder.mBtMenu.setTag(Integer.valueOf(position));
+ if (!this.mPickable) {
+ viewHolder.mBtCheck.setVisibility(
+ dataHolder.mName.compareTo(
+ FileHelper.PARENT_DIRECTORY) == 0 ? View.INVISIBLE : View.VISIBLE);
+ viewHolder.mBtCheck.setImageDrawable(dataHolder.mDwCheck);
+ viewHolder.mBtCheck.setTag(Integer.valueOf(position));
+ v.setBackgroundResource(
+ dataHolder.mSelected
+ ? R.drawable.holo_list_selector_selected
+ : R.drawable.holo_list_selector_deseleted);
+ viewHolder.mBtMenu.setVisibility(dataHolder.mHasMenu ? View.VISIBLE : View.GONE);
+ viewHolder.mBtMenu.setTag(Integer.valueOf(position));
+ }
//Return the view
return v;
public static Console createDefaultConsole(Context context)
throws FileNotFoundException, IOException, InvalidCommandDefinitionException,
ConsoleAllocException, InsufficientPermissionsException {
-
- synchronized (ConsoleBuilder.SYNC) {
- //Gets superuser mode settings
- boolean superuserMode = ExplorerApplication.isSuperuserMode();
- boolean advancedMode = ExplorerApplication.isAdvancedMode();
- if (superuserMode && !advancedMode) {
- try {
- Preferences.savePreference(
- ExplorerSettings.SETTINGS_SUPERUSER_MODE, Boolean.FALSE, true);
- } catch (Throwable ex) {
- Log.w(TAG, "can't save console preference", ex); //$NON-NLS-1$
- }
- superuserMode = false;
+ //Gets superuser mode settings
+ boolean superuserMode = ExplorerApplication.isSuperuserMode();
+ boolean advancedMode = ExplorerApplication.isAdvancedMode();
+ if (superuserMode && !advancedMode) {
+ try {
+ Preferences.savePreference(
+ ExplorerSettings.SETTINGS_SUPERUSER_MODE, Boolean.FALSE, true);
+ } catch (Throwable ex) {
+ Log.w(TAG, "can't save console preference", ex); //$NON-NLS-1$
}
+ superuserMode = false;
+ }
+ return createDefaultConsole(context, superuserMode, advancedMode);
+ }
+ /**
+ * Method that returns a console, and creates a new console if no
+ * console is allocated or if the settings preferences has changed.
+ *
+ * @param context The current context
+ * @param superuserMode If create with a superuser mode console
+ * @param advancedMode If create with a advanced mode console
+ * @return Console An allocated console
+ * @throws FileNotFoundException If the initial directory not exists
+ * @throws IOException If initial directory couldn't be checked
+ * @throws InvalidCommandDefinitionException If the command has an invalid definition
+ * @throws ConsoleAllocException If the console can't be allocated
+ * @throws InsufficientPermissionsException If the console created is not a privileged console
+ */
+ //IMP! This must be invoked from the main activity creation
+ public static Console createDefaultConsole(Context context,
+ boolean superuserMode, boolean advancedMode)
+ throws FileNotFoundException, IOException, InvalidCommandDefinitionException,
+ ConsoleAllocException, InsufficientPermissionsException {
+
+ synchronized (ConsoleBuilder.SYNC) {
//Check if console settings has changed
if (sHolder != null) {
if (
*
* @return boolean If the current console is a privileged console
*/
+ public static boolean isAlloc() {
+ if (sHolder != null && sHolder.getConsole() != null) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Method that returns if the current console is a privileged console
+ *
+ * @return boolean If the current console is a privileged console
+ */
public static boolean isPrivileged() {
if (sHolder != null && sHolder.getConsole() instanceof PrivilegedConsole) {
return true;
import com.cyanogenmod.explorer.preferences.SearchSortResultMode;
import com.cyanogenmod.explorer.util.ExceptionUtil;
import com.cyanogenmod.explorer.util.FileHelper;
+import com.cyanogenmod.explorer.util.MimeTypeHelper;
import com.cyanogenmod.explorer.util.SearchHelper;
import java.util.Collections;
//Process all the data
final List<SearchResult> result =
SearchHelper.convertToResults(
- FileHelper.applyUserPreferences(this.mFiles, true, jailRoom),
+ FileHelper.applyUserPreferences(
+ this.mFiles, MimeTypeHelper.ALL_MIME_TYPES, true, jailRoom),
this.mQueries);
if (mode.compareTo(SearchSortResultMode.NAME) == 0) {
Collections.sort(result, new Comparator<SearchResult>() {
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.res.TypedArray;
import android.os.AsyncTask;
import android.os.storage.StorageVolume;
import android.util.AttributeSet;
import com.cyanogenmod.explorer.util.DialogHelper;
import com.cyanogenmod.explorer.util.ExceptionUtil;
import com.cyanogenmod.explorer.util.FileHelper;
+import com.cyanogenmod.explorer.util.MimeTypeHelper;
import com.cyanogenmod.explorer.util.StorageHelper;
import java.util.ArrayList;
void onRequestMenu(NavigationView navView, FileSystemObject item);
}
+ /**
+ * An interface to communicate a request when the user choose a file.
+ */
+ public interface OnFilePickedListener {
+ /**
+ * Method invoked when a request when the user choose a file.
+ *
+ * @param item The item choose
+ */
+ void onFilePicked(FileSystemObject item);
+ }
+
+ /**
+ * The navigation view mode
+ * @hide
+ */
+ public enum NAVIGATION_MODE {
+ /**
+ * The navigation view acts as a browser, and allow open files itself.
+ */
+ BROWSABLE,
+ /**
+ * The navigation view acts as a picker of files
+ */
+ PICKABLE,
+ }
private static final String TAG = "NavigationView"; //$NON-NLS-1$
private OnHistoryListener mOnHistoryListener;
private OnNavigationSelectionChangedListener mOnNavigationSelectionChangedListener;
private OnNavigationRequestMenuListener mOnNavigationRequestMenuListener;
+ private OnFilePickedListener mOnFilePickedListener;
private boolean mJailRoom;
+ private NAVIGATION_MODE mNavigationMode;
+
+ private String mMimeType = MimeTypeHelper.ALL_MIME_TYPES;
+
/**
* @hide
*/
* Constructor of <code>NavigationView</code>.
*
* @param context The current context
- */
- public NavigationView(Context context) {
- super(context);
- init();
- }
-
- /**
- * Constructor of <code>NavigationView</code>.
- *
- * @param context The current context
* @param attrs The attributes of the XML tag that is inflating the view.
*/
public NavigationView(Context context, AttributeSet attrs) {
super(context, attrs);
- init();
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Navigable);
+ try {
+ init(a);
+ } finally {
+ a.recycle();
+ }
}
/**
*/
public NavigationView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- init();
+ TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.Navigable, defStyle, 0);
+ try {
+ init(a);
+ } finally {
+ a.recycle();
+ }
}
/**
/**
* Method that initializes the view. This method loads all the necessary
* information and create an appropriate layout for the view.
+ *
+ * @param tarray The type array
*/
- private void init() {
+ private void init(TypedArray tarray) {
+ // Retrieve the mode
+ this.mNavigationMode = NAVIGATION_MODE.BROWSABLE;
+ int mode = tarray.getInteger(
+ R.styleable.Navigable_navigation,
+ NAVIGATION_MODE.BROWSABLE.ordinal());
+ if (mode >= 0 && mode < NAVIGATION_MODE.values().length) {
+ this.mNavigationMode = NAVIGATION_MODE.values()[mode];
+ }
+
//Initialize variables
this.mFiles = new ArrayList<FileSystemObject>();
// Is in jail room?
- this.mJailRoom = !ExplorerApplication.isAdvancedMode();
+ if (this.mNavigationMode.compareTo(NAVIGATION_MODE.PICKABLE) == 0) {
+ // Pick mode is jail room always
+ this.mJailRoom = true;
+ } else {
+ this.mJailRoom = !ExplorerApplication.isAdvancedMode();
+ }
// Default long-click action
String defaultValue = ((ObjectStringIdentifier)ExplorerSettings.
String value = Preferences.getSharedPreferences().getString(
ExplorerSettings.SETTINGS_DEFAULT_LONG_CLICK_ACTION.getId(),
defaultValue);
- DefaultLongClickAction mode = DefaultLongClickAction.fromId(value);
- this.mDefaultLongClickAction = mode;
+ DefaultLongClickAction lcMode = DefaultLongClickAction.fromId(value);
+ this.mDefaultLongClickAction = lcMode;
//Retrieve the default configuration
- SharedPreferences preferences = Preferences.getSharedPreferences();
- int viewMode = preferences.getInt(
- ExplorerSettings.SETTINGS_LAYOUT_MODE.getId(),
- ((ObjectIdentifier)ExplorerSettings.
- SETTINGS_LAYOUT_MODE.getDefaultValue()).getId());
- changeViewMode(NavigationLayoutMode.fromId(viewMode));
+ if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
+ SharedPreferences preferences = Preferences.getSharedPreferences();
+ int viewMode = preferences.getInt(
+ ExplorerSettings.SETTINGS_LAYOUT_MODE.getId(),
+ ((ObjectIdentifier)ExplorerSettings.
+ SETTINGS_LAYOUT_MODE.getDefaultValue()).getId());
+ changeViewMode(NavigationLayoutMode.fromId(viewMode));
+ } else {
+ // Pick mode has always a details layout
+ changeViewMode(NavigationLayoutMode.DETAILS);
+ }
+ }
+
+ /**
+ * Method that returns the mime/type used by this class. Only the files with this mime/type
+ * are shown.
+ *
+ * @return String The mime/type
+ */
+ public String getMimeType() {
+ return this.mMimeType;
+ }
+
+ /**
+ * Method that sets the mime/type used by this class. Only the files with this mime/type
+ * are shown.
+ *
+ * @param mimeType String The mime/type
+ */
+ public void setMimeType(String mimeType) {
+ this.mMimeType = mimeType;
}
/**
public void setDefaultLongClickAction(DefaultLongClickAction mDefaultLongClickAction) {
this.mDefaultLongClickAction = mDefaultLongClickAction;
- // Register the long-click listener only if needed
- if (this.mDefaultLongClickAction.compareTo(
- DefaultLongClickAction.NONE) != 0) {
- this.mAdapterView.setOnItemLongClickListener(this);
+ // Pick mode doesn't implements the onlongclick
+ if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
+ // Register the long-click listener only if needed
+ if (this.mDefaultLongClickAction.compareTo(
+ DefaultLongClickAction.NONE) != 0) {
+ this.mAdapterView.setOnItemLongClickListener(this);
+ } else {
+ this.mAdapterView.setOnItemLongClickListener(null);
+ }
} else {
this.mAdapterView.setOnItemLongClickListener(null);
}
}
/**
+ * @return the mOnFilePickedListener
+ */
+ public OnFilePickedListener getOnFilePickedListener() {
+ return this.mOnFilePickedListener;
+ }
+
+ /**
+ * Method that sets the listener for picked items
+ *
+ * @param onFilePickedListener The listener reference
+ */
+ public void setOnFilePickedListener(OnFilePickedListener onFilePickedListener) {
+ this.mOnFilePickedListener = onFilePickedListener;
+ }
+
+ /**
* Method that forces the view to scroll to the file system object passed.
*
* @param fso The file system object
(AdapterView<ListAdapter>)findViewById(RESOURCE_CURRENT_LAYOUT);
FileSystemObjectAdapter adapter =
new FileSystemObjectAdapter(
- getContext(), new ArrayList<FileSystemObject>(), itemResourceId);
+ getContext(),
+ new ArrayList<FileSystemObject>(),
+ itemResourceId,
+ this.mNavigationMode.compareTo(NAVIGATION_MODE.PICKABLE) == 0);
adapter.setOnSelectionChangedListener(this);
adapter.setOnRequestMenuListener(this);
newView.setAdapter(this.mAdapter);
newView.setOnItemClickListener(NavigationView.this);
- // Register the long-click listener only if needed
- if (this.mDefaultLongClickAction.compareTo(
- DefaultLongClickAction.NONE) != 0) {
- newView.setOnItemLongClickListener(this);
+ // Pick mode doesn't implements the onlongclick
+ if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
+ // Register the long-click listener only if needed
+ if (this.mDefaultLongClickAction.compareTo(
+ DefaultLongClickAction.NONE) != 0) {
+ newView.setOnItemLongClickListener(this);
+ }
}
//Add the new layout
addView(newView, 0);
this.mCurrentMode = newMode;
- //Save the preference
- try {
- Preferences.savePreference(ExplorerSettings.SETTINGS_LAYOUT_MODE, newMode, true);
- } catch (Exception ex) {
- Log.e(TAG, "Save of view mode preference fails", ex); //$NON-NLS-1$
+ //Save the preference (only in navigation browse mode)
+ if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
+ try {
+ Preferences.savePreference(
+ ExplorerSettings.SETTINGS_LAYOUT_MODE, newMode, true);
+ } catch (Exception ex) {
+ Log.e(TAG, "Save of view mode preference fails", ex); //$NON-NLS-1$
+ }
}
}
}
protected List<FileSystemObject> doInBackground(String... params) {
try {
//Reset the custom title view and returns to breadcrumb
- NavigationView.this.mTitle.post(new Runnable() {
- @Override
- public void run() {
- try {
- NavigationView.this.mTitle.restoreView();
- } catch (Exception e) {
- e.printStackTrace();
+ if (NavigationView.this.mTitle != null) {
+ NavigationView.this.mTitle.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ NavigationView.this.mTitle.restoreView();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
- }
- });
+ });
+ }
//Start of loading data
- try {
- NavigationView.this.mBreadcrumb.startLoading();
- } catch (Throwable ex) {
- /**NON BLOCK**/
+ if (NavigationView.this.mBreadcrumb != null) {
+ try {
+ NavigationView.this.mBreadcrumb.startLoading();
+ } catch (Throwable ex) {
+ /**NON BLOCK**/
+ }
}
//Get the files, resolve links and apply configuration
return files;
} catch (final ConsoleAllocException e) {
//Show exception and exists
- NavigationView.this.mTitle.post(new Runnable() {
+ NavigationView.this.post(new Runnable() {
@Override
public void run() {
Context ctx = getContext();
} catch (Exception ex) {
//End of loading data
- try {
- NavigationView.this.mBreadcrumb.endLoading();
- } catch (Throwable ex2) {
- /**NON BLOCK**/
+ if (NavigationView.this.mBreadcrumb != null) {
+ try {
+ NavigationView.this.mBreadcrumb.endLoading();
+ } catch (Throwable ex2) {
+ /**NON BLOCK**/
+ }
}
//Capture exception
//Apply user preferences
List<FileSystemObject> sortedFiles =
- FileHelper.applyUserPreferences(files, this.mJailRoom);
+ FileHelper.applyUserPreferences(files, this.mMimeType, this.mJailRoom);
//Load the data
loadData(sortedFiles);
symlink.getLinkRef().getFullPath(), true, false, false, null, null);
}
} else {
- // Open the file with the preferred registered app
- IntentsActionPolicy.openFileSystemObject(getContext(), fso, false);
+ if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
+ // Open the file with the preferred registered app
+ IntentsActionPolicy.openFileSystemObject(getContext(), fso, false);
+ } else {
+ // Request a file pick selection
+ if (this.mOnFilePickedListener != null) {
+ this.mOnFilePickedListener.onFilePicked(fso);
+ }
+ }
}
} catch (Throwable ex) {
ExceptionUtil.translateException(getContext(), ex);
* (sort mode, hidden files, ...).
*
* @param files The listed files
+ * @param mimeType The mime-type to apply. if null returns all.
* @param jailRoom If app run with no privileges
* @return List<FileSystemObject> The applied mode listed files
*/
public static List<FileSystemObject> applyUserPreferences(
- List<FileSystemObject> files, boolean jailRoom) {
- return applyUserPreferences(files, false, jailRoom);
+ List<FileSystemObject> files, String mimeType, boolean jailRoom) {
+ return applyUserPreferences(files, mimeType, false, jailRoom);
}
/**
* (sort mode, hidden files, ...).
*
* @param files The listed files
+ * @param mimeType The mime-type to apply. if null returns all.
* @param noSort If sort must be applied
* @param jailRoom If app run with no privileges
* @return List<FileSystemObject> The applied mode listed files
*/
public static List<FileSystemObject> applyUserPreferences(
- List<FileSystemObject> files, boolean noSort, boolean jailRoom) {
+ List<FileSystemObject> files, String mimeType, boolean noSort, boolean jailRoom) {
//Retrieve user preferences
SharedPreferences prefs = Preferences.getSharedPreferences();
ExplorerSettings sortModePref = ExplorerSettings.SETTINGS_SORT_MODE;
continue;
}
}
+
+ //Mime/Type
+ if (jailRoom && !isDirectory(file)) {
+ if (mimeType != null && mimeType.compareTo(MimeTypeHelper.ALL_MIME_TYPES) != 0) {
+ // NOTE: We don't need the context here, because mime-type database should
+ // be loaded prior to this call
+ if (!MimeTypeHelper.matchesMimeType(null, file, mimeType)) {
+ files.remove(i);
+ continue;
+ }
+ }
+ }
}
//Apply sort mode
private static final String TAG = "MimeTypeHelper"; //$NON-NLS-1$
+ /**
+ * A constant that defines a string of all mime-types
+ */
+ public static final String ALL_MIME_TYPES = "*/*"; //$NON-NLS-1$
+
private static Map<String, Integer> sCachedIndentifiers;
private static Map<String, MimeTypeInfo> sMimeTypes;
}
/**
+ * Method that returns if a file system object matches with a mime-type expression.
+ *
+ * @param ctx The current context
+ * @param fso The file system object to check
+ * @param mimeTypeExpression The mime-type expression (xe: */*, audio/*)
+ * @return boolean If the file system object matches the mime-type expression
+ */
+ public static final boolean matchesMimeType(
+ Context ctx, FileSystemObject fso, String mimeTypeExpression) {
+ String mimeType = getMimeType(ctx, fso);
+ if (mimeType == null) return false;
+ return mimeType.matches(convertToRegExp(mimeTypeExpression));
+ }
+
+ /**
* Method that loads the mime type information.
*
* @param context The current context
}
}
+ /**
+ * Method that converts the mime-type expression to a regular expression
+ *
+ * @param mimeTypeExpression The mime-type expression
+ * @return String The regular expression
+ */
+ private static String convertToRegExp(String mimeTypeExpression) {
+ return mimeTypeExpression.replaceAll("\\*", ".\\*"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
}