OSDN Git Service

New activity "Picker Activity"
authorjruesga <jorge@ruesga.com>
Sat, 20 Oct 2012 23:13:44 +0000 (01:13 +0200)
committerjruesga <jorge@ruesga.com>
Sat, 20 Oct 2012 23:13:44 +0000 (01:13 +0200)
This activity allows third party application to browse and get the
content using GET_CONTENT action and a mime/type.
This activity used the NavigationView in jail room mode and it's only
capable of pick a file (actions like open or others are not permitted)

* CleanUp

18 files changed:
AndroidManifest.xml
res/layout/bookmarks.xml
res/layout/history.xml
res/layout/navigation.xml
res/layout/navigation_view_details_item.xml
res/layout/navigation_view_simple_item.xml
res/layout/picker.xml [new file with mode: 0644]
res/layout/search.xml
res/values/attrs.xml
res/values/strings.xml
res/values/styles.xml
src/com/cyanogenmod/explorer/activities/PickerActivity.java [new file with mode: 0644]
src/com/cyanogenmod/explorer/adapters/FileSystemObjectAdapter.java
src/com/cyanogenmod/explorer/console/ConsoleBuilder.java
src/com/cyanogenmod/explorer/tasks/SearchResultDrawingAsyncTask.java
src/com/cyanogenmod/explorer/ui/widgets/NavigationView.java
src/com/cyanogenmod/explorer/util/FileHelper.java
src/com/cyanogenmod/explorer/util/MimeTypeHelper.java

index 2f6b296..fd24039 100644 (file)
     </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"
index 80f0516..2fd42f0 100644 (file)
@@ -15,8 +15,7 @@
  ** 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"
index 7363382..d4cd34b 100644 (file)
@@ -15,8 +15,7 @@
  ** 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"
index 6c8fc17..1fd18df 100644 (file)
  ** 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
index 6d0e953..722afbd 100644 (file)
@@ -33,6 +33,7 @@
     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" />
 
@@ -48,7 +49,8 @@
     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"
index dc6f9be..30e26de 100644 (file)
     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
diff --git a/res/layout/picker.xml b/res/layout/picker.xml
new file mode 100644 (file)
index 0000000..97a6410
--- /dev/null
@@ -0,0 +1,44 @@
+<?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
index 485dc12..6e6863c 100644 (file)
@@ -15,8 +15,7 @@
  ** 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"
index 7a4657e..ea9b288 100644 (file)
 
   <!-- 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
index 08c264b..baeee7e 100644 (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 &#x25B2;</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 -->
index 7529aa4..fdabbd8 100644 (file)
  ** 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>
diff --git a/src/com/cyanogenmod/explorer/activities/PickerActivity.java b/src/com/cyanogenmod/explorer/activities/PickerActivity.java
new file mode 100644 (file)
index 0000000..2c523ac
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * 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();
+    }
+}
index 03a0e79..6faf215 100644 (file)
@@ -114,6 +114,7 @@ public class FileSystemObjectAdapter
     private IconHolder mIconHolder;
     private final int mItemViewResourceId;
     private List<FileSystemObject> mSelectedItems;
+    private final boolean mPickable;
 
     private OnSelectionChangedListener mOnSelectionChangedListener;
     private OnRequestMenuListener mOnRequestMenuListener;
@@ -138,13 +139,16 @@ public class FileSystemObjectAdapter
      * @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();
@@ -275,10 +279,17 @@ public class FileSystemObjectAdapter
             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);
         }
 
@@ -297,17 +308,19 @@ public class FileSystemObjectAdapter
         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;
index b8edefc..6127141 100644 (file)
@@ -182,21 +182,42 @@ public final class ConsoleBuilder {
     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 (
@@ -385,6 +406,18 @@ public final class ConsoleBuilder {
      *
      * @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;
index a4a02ee..36e99f7 100644 (file)
@@ -35,6 +35,7 @@ import com.cyanogenmod.explorer.preferences.Preferences;
 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;
@@ -120,7 +121,8 @@ public class SearchResultDrawingAsyncTask extends AsyncTask<Object, Integer, Boo
             //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>() {
index 6e03313..0df6d05 100644 (file)
@@ -19,6 +19,7 @@ package com.cyanogenmod.explorer.ui.widgets;
 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;
@@ -56,6 +57,7 @@ import com.cyanogenmod.explorer.util.CommandHelper;
 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;
@@ -99,6 +101,32 @@ public class NavigationView extends RelativeLayout implements
         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$
 
@@ -117,9 +145,14 @@ public class NavigationView extends RelativeLayout implements
     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
      */
@@ -150,21 +183,16 @@ public class NavigationView extends RelativeLayout implements
      * 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();
+        }
     }
 
     /**
@@ -179,7 +207,13 @@ public class NavigationView extends RelativeLayout implements
      */
     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();
+        }
     }
 
     /**
@@ -218,13 +252,29 @@ public class NavigationView extends RelativeLayout implements
     /**
      * 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.
@@ -232,16 +282,41 @@ public class NavigationView extends RelativeLayout implements
         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;
     }
 
     /**
@@ -313,10 +388,15 @@ public class NavigationView extends RelativeLayout implements
     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);
         }
@@ -352,6 +432,22 @@ public class NavigationView extends RelativeLayout implements
     }
 
     /**
+     * @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
@@ -433,7 +529,10 @@ public class NavigationView extends RelativeLayout implements
                     (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);
 
@@ -457,10 +556,13 @@ public class NavigationView extends RelativeLayout implements
             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
@@ -468,11 +570,14 @@ public class NavigationView extends RelativeLayout implements
             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$
+                }
             }
         }
     }
@@ -567,23 +672,27 @@ public class NavigationView extends RelativeLayout implements
                         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
@@ -595,7 +704,7 @@ public class NavigationView extends RelativeLayout implements
                                 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();
@@ -611,10 +720,12 @@ public class NavigationView extends RelativeLayout implements
 
                             } 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
@@ -684,7 +795,7 @@ public class NavigationView extends RelativeLayout implements
 
             //Apply user preferences
             List<FileSystemObject> sortedFiles =
-                    FileHelper.applyUserPreferences(files, this.mJailRoom);
+                    FileHelper.applyUserPreferences(files, this.mMimeType, this.mJailRoom);
 
             //Load the data
             loadData(sortedFiles);
@@ -836,8 +947,15 @@ public class NavigationView extends RelativeLayout implements
                             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);
index ff2fb25..bd57717 100644 (file)
@@ -444,12 +444,13 @@ public final class FileHelper {
      * (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);
     }
 
     /**
@@ -457,12 +458,13 @@ public final class FileHelper {
      * (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;
@@ -505,6 +507,18 @@ public final class FileHelper {
                     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
index adb1f8f..8ec27ba 100644 (file)
@@ -122,6 +122,11 @@ public final class MimeTypeHelper {
 
     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;
 
@@ -321,6 +326,21 @@ public final class MimeTypeHelper {
     }
 
     /**
+     * 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: *&#47;*, audio&#47;*)
+     * @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
@@ -361,4 +381,14 @@ public final class MimeTypeHelper {
         }
     }
 
+    /**
+     * 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$
+    }
+
 }