aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjruesga <jorge@ruesga.com>2012-10-20 01:38:23 +0200
committerjruesga <jorge@ruesga.com>2012-10-20 01:38:23 +0200
commit8e2c09f68280d4648e7a799f4ae367d60e9e7727 (patch)
tree8467357bdf27e7f6fe7a914ea0c6eda83c169c9c
parent09ea82a6b89a4ff10bf8fa19622028a7efc1927a (diff)
downloadandroid_packages_apps_CMFileManager-8e2c09f68280d4648e7a799f4ae367d60e9e7727.tar.gz
android_packages_apps_CMFileManager-8e2c09f68280d4648e7a799f4ae367d60e9e7727.tar.bz2
android_packages_apps_CMFileManager-8e2c09f68280d4648e7a799f4ae367d60e9e7727.zip
New fso and global actions "Compress" and "Compress selection" + CleanUp
-rw-r--r--res/layout/option_list_item.xml2
-rw-r--r--res/menu/actions.xml8
-rw-r--r--res/values/arrays.xml11
-rw-r--r--res/values/strings.xml32
-rw-r--r--res/xml/command_list.xml2
-rw-r--r--src/com/cyanogenmod/explorer/activities/NavigationActivity.java3
-rw-r--r--src/com/cyanogenmod/explorer/activities/SearchActivity.java3
-rw-r--r--src/com/cyanogenmod/explorer/activities/preferences/SettingsPreferences.java5
-rw-r--r--src/com/cyanogenmod/explorer/adapters/CheckableListAdapter.java13
-rw-r--r--src/com/cyanogenmod/explorer/adapters/SimpleMenuListAdapter.java3
-rw-r--r--src/com/cyanogenmod/explorer/adapters/TwoColumnsMenuListAdapter.java3
-rw-r--r--src/com/cyanogenmod/explorer/commands/ExecutableCreator.java6
-rw-r--r--src/com/cyanogenmod/explorer/commands/shell/CompressCommand.java103
-rw-r--r--src/com/cyanogenmod/explorer/commands/shell/ShellExecutableCreator.java6
-rw-r--r--src/com/cyanogenmod/explorer/commands/shell/UncompressCommand.java88
-rw-r--r--src/com/cyanogenmod/explorer/preferences/CompressionMode.java67
-rw-r--r--src/com/cyanogenmod/explorer/preferences/UncompressionMode.java87
-rw-r--r--src/com/cyanogenmod/explorer/ui/dialogs/ActionsDialog.java21
-rw-r--r--src/com/cyanogenmod/explorer/ui/dialogs/AssociationsDialog.java4
-rw-r--r--src/com/cyanogenmod/explorer/ui/dialogs/ChooseConsoleDialog.java8
-rw-r--r--src/com/cyanogenmod/explorer/ui/policy/ActionsPolicy.java29
-rw-r--r--src/com/cyanogenmod/explorer/ui/policy/BookmarksActionPolicy.java9
-rw-r--r--src/com/cyanogenmod/explorer/ui/policy/CompressActionPolicy.java494
-rw-r--r--src/com/cyanogenmod/explorer/ui/policy/CopyMoveActionPolicy.java27
-rw-r--r--src/com/cyanogenmod/explorer/ui/policy/DeleteActionPolicy.java10
-rw-r--r--src/com/cyanogenmod/explorer/ui/policy/InfoActionPolicy.java3
-rw-r--r--src/com/cyanogenmod/explorer/ui/policy/IntentsActionPolicy.java3
-rw-r--r--src/com/cyanogenmod/explorer/util/CommandHelper.java8
-rw-r--r--src/com/cyanogenmod/explorer/util/DialogHelper.java93
-rw-r--r--src/com/cyanogenmod/explorer/util/FileHelper.java52
-rw-r--r--src/com/cyanogenmod/explorer/util/StorageHelper.java3
-rw-r--r--tests/src/com/cyanogenmod/explorer/commands/shell/CompressCommandTest.java12
-rw-r--r--tests/src/com/cyanogenmod/explorer/commands/shell/UncompressCommandTest.java2
33 files changed, 1085 insertions, 135 deletions
diff --git a/res/layout/option_list_item.xml b/res/layout/option_list_item.xml
index 66f6ce6e..90cf16ec 100644
--- a/res/layout/option_list_item.xml
+++ b/res/layout/option_list_item.xml
@@ -16,7 +16,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="@dimen/default_row_height"
- android:background="@drawable/holo_list_selector_deseleted" >
+ android:background="@drawable/holo_selector" >
<ImageView
android:id="@+id/option_list_item_check"
diff --git a/res/menu/actions.xml b/res/menu/actions.xml
index a8d9d19d..ace7698c 100644
--- a/res/menu/actions.xml
+++ b/res/menu/actions.xml
@@ -55,6 +55,10 @@
android:showAsAction="ifRoom"
android:title="@string/actions_menu_delete_selection"/>
<item
+ android:id="@+id/mnu_actions_compress_selection"
+ android:showAsAction="ifRoom"
+ android:title="@string/actions_menu_compress_selection"/>
+ <item
android:id="@+id/mnu_actions_create_link_global"
android:showAsAction="ifRoom"
android:title="@string/actions_menu_create_link"/>
@@ -95,6 +99,10 @@
android:showAsAction="ifRoom"
android:title="@string/actions_menu_rename"/>
<item
+ android:id="@+id/mnu_actions_compress"
+ android:showAsAction="ifRoom"
+ android:title="@string/actions_menu_compress"/>
+ <item
android:id="@+id/mnu_actions_extract"
android:showAsAction="ifRoom"
android:title="@string/actions_menu_extract"/>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index f11b0a0b..97366f68 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -82,4 +82,15 @@
<item>2</item>
</string-array>
+ <!-- Compression modes -->
+ <!-- Note: Archive modes must be before that compression modes -->
+ <string-array name="compression_modes_labels" translable="false">
+ <item>@string/compression_mode_tar</item>
+ <item>@string/compression_mode_tar_gzip</item>
+ <item>@string/compression_mode_tar_gzip2</item>
+ <item>@string/compression_mode_tar_bzip</item>
+ <item>@string/compression_mode_gzip</item>
+ <item>@string/compression_mode_bzip</item>
+ </string-array>
+
</resources> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bf37f50a..e4163383 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -394,6 +394,9 @@
<!-- Create copy regexp -->
<string name="create_copy_regexp">
<xliff:g id="name">%1$s</xliff:g> - copy<xliff:g id="extension">%2$s</xliff:g></string>
+ <!-- New compressed file -->
+ <string name="create_new_compress_file_regexp">
+ <xliff:g id="name">%1$s</xliff:g> - new<xliff:g id="extension">%2$s</xliff:g></string>
<!-- Waiting dialog * Performing operation message -->
<string name="waiting_dialog_msg">Performing operation&#8230;</string>
@@ -419,9 +422,22 @@
<!-- Waiting dialog * Extracting message -->
<string name="waiting_dialog_extracting_msg">
<![CDATA[<b>File</b>]]> <xliff:g id="file">%1$s</xliff:g></string>
+ <!-- Waiting dialog * Extracting title -->
+ <string name="waiting_dialog_compressing_title">Compressing&#8230;</string>
+ <!-- Waiting dialog * Extracting message -->
+ <string name="waiting_dialog_compressing_msg">
+ <![CDATA[<b>File</b>]]> <xliff:g id="file">%1$s</xliff:g></string>
<!-- Waiting dialog * Initializing the dialog -->
- <string name="waiting_dialog_extracting_analizing_msg">
+ <string name="waiting_dialog_analizing_msg">
<![CDATA[<b>Analizing&#8230;</b>]]></string>
+ <!-- Extracting * Success message -->
+ <string name="msgs_extracting_success">
+ The extracting operation was completed successfully. The data was extracted to
+ <xliff:g id="destination">%1$s</xliff:g></string>
+ <!-- Compressing * Success message -->
+ <string name="msgs_compressing_success">
+ The compressing operation was completed successfully. The data was compressed to
+ <xliff:g id="destination">%1$s</xliff:g></string>
<!-- Actions Dialog * Title -->
<string name="actions_dialog_title">Actions</string>
@@ -447,6 +463,8 @@
<string name="actions_menu_move_selection">Move selection</string>
<!-- Actions Dialog * Menu * Delete selection -->
<string name="actions_menu_delete_selection">Delete selection</string>
+ <!-- Actions Dialog * Menu * Compress selection -->
+ <string name="actions_menu_compress_selection">Compress selection</string>
<!-- Actions Dialog * Menu * Create link -->
<string name="actions_menu_create_link">Create link</string>
<!-- Actions Dialog * Menu * Add to bookmarks the current folder -->
@@ -459,6 +477,8 @@
<string name="actions_menu_execute">Execute</string>
<!-- Actions Dialog * Menu * Send -->
<string name="actions_menu_send">Send</string>
+ <!-- Actions Dialog * Menu * Compress -->
+ <string name="actions_menu_compress">Compress</string>
<!-- Actions Dialog * Menu * Extract -->
<string name="actions_menu_extract">Extract</string>
<!-- Actions Dialog * Menu * Share -->
@@ -559,6 +579,16 @@
<string name="category_video">VIDEO</string>
<string name="category_security">SECURITY</string>
+ <!-- Compression modes dialog title -->
+ <string name="compression_mode_title">Compression mode</string>
+ <!-- Compression modes -->
+ <string name="compression_mode_tar" translatable="false">Tar (tar)</string>
+ <string name="compression_mode_tar_gzip" translatable="false">Tar/Gzip (tar.gz)</string>
+ <string name="compression_mode_tar_gzip2" translatable="false">Tar/Gzip (tgz)</string>
+ <string name="compression_mode_tar_bzip" translatable="false">Tar/Bzip (tar.bz2)</string>
+ <string name="compression_mode_gzip" translatable="false">Gzip (gz)</string>
+ <string name="compression_mode_bzip" translatable="false">Bzip (bz2)</string>
+
<!-- Preferences title -->
<string name="pref">Settings</string>
<!-- Preferences * General title -->
diff --git a/res/xml/command_list.xml b/res/xml/command_list.xml
index b2959c30..9d339c6e 100644
--- a/res/xml/command_list.xml
+++ b/res/xml/command_list.xml
@@ -93,7 +93,7 @@
<command commandId="terminate" commandPath="/system/bin/kill" commandArgs="%1$s" />
<!-- Compress -->
- <command commandId="compress" commandPath="/system/xbin/tar" commandArgs="-%1$scvf %2$s [@]" />
+ <command commandId="tar" commandPath="/system/xbin/tar" commandArgs="-%1$scvf %2$s [@]" />
<command commandId="gzip" commandPath="/system/bin/gzip" commandArgs="%1$s" />
<command commandId="bzip" commandPath="/system/xbin/bzip2" commandArgs="-f %1$s" />
diff --git a/src/com/cyanogenmod/explorer/activities/NavigationActivity.java b/src/com/cyanogenmod/explorer/activities/NavigationActivity.java
index 25c8f9e7..8932f422 100644
--- a/src/com/cyanogenmod/explorer/activities/NavigationActivity.java
+++ b/src/com/cyanogenmod/explorer/activities/NavigationActivity.java
@@ -1222,7 +1222,8 @@ public class NavigationActivity extends Activity
*/
private void removeFromHistory(FileSystemObject fso) {
if (this.mHistory != null) {
- for (int i = this.mHistory.size()-1; i >= 0 ; i--) {
+ int cc = this.mHistory.size();
+ for (int i = cc-1; i >= 0 ; i--) {
History history = this.mHistory.get(i);
if (history.getItem() instanceof NavigationViewInfoParcelable) {
String p0 = fso.getFullPath();
diff --git a/src/com/cyanogenmod/explorer/activities/SearchActivity.java b/src/com/cyanogenmod/explorer/activities/SearchActivity.java
index 20b8d936..9e1ece7f 100644
--- a/src/com/cyanogenmod/explorer/activities/SearchActivity.java
+++ b/src/com/cyanogenmod/explorer/activities/SearchActivity.java
@@ -695,7 +695,8 @@ public class SearchActivity extends Activity
@SuppressWarnings("static-method")
private List<String> filterQuery(List<String> original) {
List<String> dst = new ArrayList<String>(original);
- for (int i = dst.size() - 1; i >= 0; i--) {
+ int cc = dst.size();
+ for (int i = cc - 1; i >= 0; i--) {
String query = dst.get(i);
if (query == null || query.trim().length() < MIN_CHARS_SEARCH) {
dst.remove(i);
diff --git a/src/com/cyanogenmod/explorer/activities/preferences/SettingsPreferences.java b/src/com/cyanogenmod/explorer/activities/preferences/SettingsPreferences.java
index 26f920ca..cdc60f2e 100644
--- a/src/com/cyanogenmod/explorer/activities/preferences/SettingsPreferences.java
+++ b/src/com/cyanogenmod/explorer/activities/preferences/SettingsPreferences.java
@@ -38,6 +38,7 @@ import com.cyanogenmod.explorer.preferences.ExplorerSettings;
import com.cyanogenmod.explorer.preferences.ObjectStringIdentifier;
import com.cyanogenmod.explorer.preferences.Preferences;
import com.cyanogenmod.explorer.providers.RecentSearchesContentProvider;
+import com.cyanogenmod.explorer.util.DialogHelper;
import java.util.List;
@@ -298,10 +299,10 @@ public class SettingsPreferences extends PreferenceActivity {
clearRecentSearchTerms();
// Advise the user
- Toast.makeText(
+ DialogHelper.showToast(
getActivity(),
getActivity().getString(R.string.pref_remove_saved_search_terms_msg),
- Toast.LENGTH_SHORT).show();
+ Toast.LENGTH_SHORT);
}
return false;
}
diff --git a/src/com/cyanogenmod/explorer/adapters/CheckableListAdapter.java b/src/com/cyanogenmod/explorer/adapters/CheckableListAdapter.java
index cc432407..b5435c88 100644
--- a/src/com/cyanogenmod/explorer/adapters/CheckableListAdapter.java
+++ b/src/com/cyanogenmod/explorer/adapters/CheckableListAdapter.java
@@ -136,4 +136,17 @@ public class CheckableListAdapter extends ArrayAdapter<CheckableListAdapter.Chec
return v;
}
+ /**
+ * Method that sets the selected item
+ *
+ * @param position The position of the selected item
+ */
+ public void setSelectedItem(int position) {
+ int cc = getCount();
+ for (int i = 0; i < cc; i++) {
+ getItem(i).mChecked = (i == position);
+ notifyDataSetChanged();
+ }
+ }
+
}
diff --git a/src/com/cyanogenmod/explorer/adapters/SimpleMenuListAdapter.java b/src/com/cyanogenmod/explorer/adapters/SimpleMenuListAdapter.java
index 2a015503..159846d2 100644
--- a/src/com/cyanogenmod/explorer/adapters/SimpleMenuListAdapter.java
+++ b/src/com/cyanogenmod/explorer/adapters/SimpleMenuListAdapter.java
@@ -65,7 +65,8 @@ public class SimpleMenuListAdapter extends BaseAdapter {
this(context, menuResourceId);
//Remove all item menus that no belongs to the group
- for (int i = this.mMenu.size() - 1; i >= 0; i--) {
+ int cc = this.mMenu.size();
+ for (int i = cc - 1; i >= 0; i--) {
MenuItem menuItem = this.mMenu.getItem(i);
if (menuItem.getGroupId() != menuGroupResourceId) {
this.mMenu.removeItem(menuItem.getItemId());
diff --git a/src/com/cyanogenmod/explorer/adapters/TwoColumnsMenuListAdapter.java b/src/com/cyanogenmod/explorer/adapters/TwoColumnsMenuListAdapter.java
index 75105cd1..ad595a9b 100644
--- a/src/com/cyanogenmod/explorer/adapters/TwoColumnsMenuListAdapter.java
+++ b/src/com/cyanogenmod/explorer/adapters/TwoColumnsMenuListAdapter.java
@@ -92,7 +92,8 @@ public class TwoColumnsMenuListAdapter extends SimpleMenuListAdapter
*/
private void removeSeparators() {
Menu menu = getMenu();
- for (int i = menu.size() - 1; i >= 0; i--) {
+ int cc = menu.size();
+ for (int i = cc - 1; i >= 0; i--) {
MenuItem menuItem = menu.getItem(i);
if (menuItem.getTitle() == null || menuItem.getTitle().length() == 0) {
menu.removeItem(menuItem.getItemId());
diff --git a/src/com/cyanogenmod/explorer/commands/ExecutableCreator.java b/src/com/cyanogenmod/explorer/commands/ExecutableCreator.java
index e54c7d56..ce377ee0 100644
--- a/src/com/cyanogenmod/explorer/commands/ExecutableCreator.java
+++ b/src/com/cyanogenmod/explorer/commands/ExecutableCreator.java
@@ -17,13 +17,13 @@
package com.cyanogenmod.explorer.commands;
import com.cyanogenmod.explorer.commands.ListExecutable.LIST_MODE;
-import com.cyanogenmod.explorer.commands.shell.CompressCommand.CompressionMode;
import com.cyanogenmod.explorer.console.CommandNotFoundException;
import com.cyanogenmod.explorer.model.Group;
import com.cyanogenmod.explorer.model.MountPoint;
import com.cyanogenmod.explorer.model.Permissions;
import com.cyanogenmod.explorer.model.Query;
import com.cyanogenmod.explorer.model.User;
+import com.cyanogenmod.explorer.preferences.CompressionMode;
/**
* A interface that defines methods for create {@link Executable} objects.
@@ -412,12 +412,14 @@ public interface ExecutableCreator {
* Method that creates an executable for uncompress file system objects.
*
* @param src The compressed file
+ * @param dst The destination file of folder (if null this method resolve with the best
+ * fit based on the src)
* @param asyncResultListener The listener where to return partial results
* @return UncompressExecutable A {@link UncompressExecutable} executable implementation reference
* @throws CommandNotFoundException If the executable can't be created
*/
UncompressExecutable createUncompressExecutable(
- String src, AsyncResultListener asyncResultListener)
+ String src, String dst, AsyncResultListener asyncResultListener)
throws CommandNotFoundException;
}
diff --git a/src/com/cyanogenmod/explorer/commands/shell/CompressCommand.java b/src/com/cyanogenmod/explorer/commands/shell/CompressCommand.java
index 9025503e..20e29fb5 100644
--- a/src/com/cyanogenmod/explorer/commands/shell/CompressCommand.java
+++ b/src/com/cyanogenmod/explorer/commands/shell/CompressCommand.java
@@ -22,6 +22,10 @@ import com.cyanogenmod.explorer.commands.SIGNAL;
import com.cyanogenmod.explorer.console.CommandNotFoundException;
import com.cyanogenmod.explorer.console.ExecutionException;
import com.cyanogenmod.explorer.console.InsufficientPermissionsException;
+import com.cyanogenmod.explorer.preferences.CompressionMode;
+import com.cyanogenmod.explorer.util.FileHelper;
+
+import java.io.File;
/**
* A class for compress file system objects
@@ -35,39 +39,68 @@ public class CompressCommand extends AsyncResultProgram implements CompressExecu
/**
* An enumeration of implemented compression modes.
*/
- public enum CompressionMode {
+ private enum Mode {
+ /**
+ * Archive using Tar algorithm
+ */
+ A_TAR(TAR_ID, "", CompressionMode.A_TAR), //$NON-NLS-1$
+ /**
+ * Archive and compress using Gzip algorithm
+ */
+ AC_GZIP(TAR_ID, "z", CompressionMode.AC_GZIP), //$NON-NLS-1$
+ /**
+ * Archive and compress using Gzip algorithm
+ */
+ AC_GZIP2(TAR_ID, "z", CompressionMode.AC_GZIP2), //$NON-NLS-1$
/**
- * Without compression
+ * Archive and compress using Bzip algorithm
*/
- NONE("", "", ""), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ AC_BZIP(TAR_ID, "j", CompressionMode.AC_BZIP), //$NON-NLS-1$
/**
* Compress using Gzip algorithm
*/
- GZIP(GZIP_ID, "z", "gz"), //$NON-NLS-1$ //$NON-NLS-2$
+ C_GZIP(GZIP_ID, "z", CompressionMode.C_GZIP), //$NON-NLS-1$
/**
* Compress using Bzip algorithm
*/
- BZIP(BZIP_ID, "j", "bz2"); //$NON-NLS-1$ //$NON-NLS-2$
+ C_BZIP(BZIP_ID, "j", CompressionMode.C_BZIP); //$NON-NLS-1$
- String mId;
- String mFlag;
- String mExtension;
+ final String mId;
+ final String mFlag;
+ final CompressionMode mMode;
/**
- * Constructor of <code>CompressionMode</code>
+ * Constructor of <code>Mode</code>
*
* @param id The command identifier
* @param flag The tar compression flag
- * @param extension The file extension
+ * @param mode The compression mode
*/
- private CompressionMode(String id, String flag, String extension) {
+ private Mode(String id, String flag, CompressionMode mode) {
this.mId = id;
this.mFlag = flag;
- this.mExtension = extension;
+ this.mMode = mode;
+ }
+
+ /**
+ * Method that return the mode from his compression mode
+ *
+ * @param mode The compression mode
+ * @return Mode The mode
+ */
+ public static Mode fromCompressionMode(CompressionMode mode) {
+ Mode[] modes = Mode.values();
+ int cc = modes.length;
+ for (int i = 0; i < cc; i++) {
+ if (modes[i].mMode.compareTo(mode) == 0) {
+ return modes[i];
+ }
+ }
+ return null;
}
}
- private static final String TAR_ID = "compress"; //$NON-NLS-1$
+ private static final String TAR_ID = "tar"; //$NON-NLS-1$
private static final String GZIP_ID = "gzip"; //$NON-NLS-1$
private static final String BZIP_ID = "bzip"; //$NON-NLS-1$
@@ -89,8 +122,12 @@ public class CompressCommand extends AsyncResultProgram implements CompressExecu
public CompressCommand(
CompressionMode mode, String dst, String[] src, AsyncResultListener asyncResultListener)
throws InvalidCommandDefinitionException {
- super(TAR_ID, asyncResultListener, new String[]{mode.mFlag, dst});
- addExpandedArguments(src, true);
+ super(TAR_ID, asyncResultListener,
+ new String[]{Mode.fromCompressionMode(mode).mFlag, dst});
+
+ //Convert the arguments from absolute to relative
+ addExpandedArguments(
+ convertAbsolutePathsToRelativePaths(dst, src), true);
// Create the output file
this.mOutFile = dst;
@@ -108,7 +145,11 @@ public class CompressCommand extends AsyncResultProgram implements CompressExecu
public CompressCommand(
CompressionMode mode, String src, AsyncResultListener asyncResultListener)
throws InvalidCommandDefinitionException {
- super(mode.mId, asyncResultListener, resolveArguments(mode, src));
+ super(Mode.fromCompressionMode(mode).mId, asyncResultListener, resolveArguments(mode, src));
+ if (Mode.fromCompressionMode(mode).mMode.mArchive) {
+ throw new InvalidCommandDefinitionException(
+ "Unsupported compression mode"); //$NON-NLS-1$
+ }
// Create the output file
this.mOutFile = resolveOutputFile(mode, src);
@@ -150,7 +191,8 @@ public class CompressCommand extends AsyncResultProgram implements CompressExecu
lines[0] = this.mPartial + lines[0];
// Return all the lines, except the last
- for (int i = 0; i < lines.length-1; i++) {
+ int cc = lines.length;
+ for (int i = 0; i < cc-1; i++) {
if (getAsyncResultListener() != null) {
getAsyncResultListener().onPartialResult(lines[i]);
}
@@ -223,8 +265,8 @@ public class CompressCommand extends AsyncResultProgram implements CompressExecu
*/
private static String[] resolveArguments(CompressionMode mode, String src) {
switch (mode) {
- case GZIP:
- case BZIP:
+ case C_GZIP:
+ case C_BZIP:
return new String[]{src};
default:
return new String[]{};
@@ -239,4 +281,27 @@ public class CompressCommand extends AsyncResultProgram implements CompressExecu
private static String resolveOutputFile(CompressionMode mode, String src) {
return String.format("%s.%s", src, mode.mExtension); //$NON-NLS-1$
}
+
+ /**
+ * Method that converts the absolute paths of the source files to relative paths
+ *
+ * @param dst The destination compressed file
+ * @param src The source uncompressed files
+ * @return String[] The array of relative paths
+ */
+ private static String[] convertAbsolutePathsToRelativePaths(String dst, String[] src) {
+ File parent = new File(dst).getParentFile();
+ String p = File.separator;
+ if (parent != null) {
+ p = parent.getAbsolutePath();
+ }
+
+ // Converts every path
+ String[] out = new String[src.length];
+ int cc = src.length;
+ for (int i = 0; i < cc; i++) {
+ out[i] = FileHelper.toRelativePath(src[i], p);
+ }
+ return out;
+ }
}
diff --git a/src/com/cyanogenmod/explorer/commands/shell/ShellExecutableCreator.java b/src/com/cyanogenmod/explorer/commands/shell/ShellExecutableCreator.java
index 3bf05878..10f2ae1a 100644
--- a/src/com/cyanogenmod/explorer/commands/shell/ShellExecutableCreator.java
+++ b/src/com/cyanogenmod/explorer/commands/shell/ShellExecutableCreator.java
@@ -47,7 +47,6 @@ import com.cyanogenmod.explorer.commands.ResolveLinkExecutable;
import com.cyanogenmod.explorer.commands.SIGNAL;
import com.cyanogenmod.explorer.commands.SendSignalExecutable;
import com.cyanogenmod.explorer.commands.WriteExecutable;
-import com.cyanogenmod.explorer.commands.shell.CompressCommand.CompressionMode;
import com.cyanogenmod.explorer.console.CommandNotFoundException;
import com.cyanogenmod.explorer.console.shell.ShellConsole;
import com.cyanogenmod.explorer.model.Group;
@@ -55,6 +54,7 @@ import com.cyanogenmod.explorer.model.MountPoint;
import com.cyanogenmod.explorer.model.Permissions;
import com.cyanogenmod.explorer.model.Query;
import com.cyanogenmod.explorer.model.User;
+import com.cyanogenmod.explorer.preferences.CompressionMode;
/**
* A class for create shell {@link "Executable"} objects.
@@ -523,11 +523,11 @@ public class ShellExecutableCreator implements ExecutableCreator {
*/
@Override
public UncompressCommand createUncompressExecutable(
- String src,
+ String src, String dst,
AsyncResultListener asyncResultListener)
throws CommandNotFoundException {
try {
- return new UncompressCommand(src, asyncResultListener);
+ return new UncompressCommand(src, dst, asyncResultListener);
} catch (InvalidCommandDefinitionException icdEx) {
throw new CommandNotFoundException("UncompressCommand", icdEx); //$NON-NLS-1$
}
diff --git a/src/com/cyanogenmod/explorer/commands/shell/UncompressCommand.java b/src/com/cyanogenmod/explorer/commands/shell/UncompressCommand.java
index c7c4c2b0..a16ea02d 100644
--- a/src/com/cyanogenmod/explorer/commands/shell/UncompressCommand.java
+++ b/src/com/cyanogenmod/explorer/commands/shell/UncompressCommand.java
@@ -22,6 +22,7 @@ import com.cyanogenmod.explorer.commands.UncompressExecutable;
import com.cyanogenmod.explorer.console.CommandNotFoundException;
import com.cyanogenmod.explorer.console.ExecutionException;
import com.cyanogenmod.explorer.console.InsufficientPermissionsException;
+import com.cyanogenmod.explorer.preferences.UncompressionMode;
import com.cyanogenmod.explorer.util.FileHelper;
import java.io.File;
@@ -40,70 +41,67 @@ public class UncompressCommand extends AsyncResultProgram implements UncompressE
/**
* An enumeration of implemented uncompression modes.
*/
- public enum UncompressionMode {
+ private enum Mode {
/**
* Uncompress using Tar algorithm
*/
- A_UNTAR(UNTAR_ID, "", "tar", true), //$NON-NLS-1$ //$NON-NLS-2$
+ A_UNTAR(UNTAR_ID, "", UncompressionMode.A_UNTAR), //$NON-NLS-1$
/**
* Uncompress using Tar algorithm
*/
- A_UNZIP(UNZIP_ID, "", "zip", true), //$NON-NLS-1$ //$NON-NLS-2$
+ A_UNZIP(UNZIP_ID, "", UncompressionMode.A_UNZIP), //$NON-NLS-1$
/**
* Uncompress using Gzip algorithm
*/
- AC_GUNZIP(UNTAR_ID, "z", "tar.gz", true), //$NON-NLS-1$ //$NON-NLS-2$
+ AC_GUNZIP(UNTAR_ID, "z", UncompressionMode.AC_GUNZIP), //$NON-NLS-1$
/**
* Uncompress using Gzip algorithm
*/
- AC_GUNZIP2(UNTAR_ID, "z", "tgz", true), //$NON-NLS-1$ //$NON-NLS-2$
+ AC_GUNZIP2(UNTAR_ID, "z", UncompressionMode.AC_GUNZIP2), //$NON-NLS-1$
/**
* Uncompress using Bzip algorithm
*/
- AC_BUNZIP(UNTAR_ID, "j", "tar.bz2", true), //$NON-NLS-1$ //$NON-NLS-2$
+ AC_BUNZIP(UNTAR_ID, "j", UncompressionMode.AC_BUNZIP), //$NON-NLS-1$
/**
* Uncompress using Lzma algorithm
*/
- AC_UNLZMA(UNTAR_ID, "a", "tar.lzma", true), //$NON-NLS-1$ //$NON-NLS-2$
+ AC_UNLZMA(UNTAR_ID, "a", UncompressionMode.AC_UNLZMA), //$NON-NLS-1$
/**
* Uncompress using Gzip algorithm
*/
- C_GUNZIP(GUNZIP_ID, "", "gz", false), //$NON-NLS-1$ //$NON-NLS-2$
+ C_GUNZIP(GUNZIP_ID, "", UncompressionMode.C_GUNZIP), //$NON-NLS-1$
/**
* Uncompress using Bzip algorithm
*/
- C_BUNZIP(BUNZIP_ID, "", "bz2", false), //$NON-NLS-1$ //$NON-NLS-2$
+ C_BUNZIP(BUNZIP_ID, "", UncompressionMode.C_BUNZIP), //$NON-NLS-1$
/**
* Uncompress using Lzma algorithm
*/
- C_UNLZMA(UNLZMA_ID, "", "lzma", false), //$NON-NLS-1$ //$NON-NLS-2$
+ C_UNLZMA(UNLZMA_ID, "", UncompressionMode.C_UNLZMA), //$NON-NLS-1$
/**
* Uncompress using Unix compress algorithm
*/
- C_UNCOMPRESS(UNCOMPRESS_ID, "", "Z", false), //$NON-NLS-1$ //$NON-NLS-2$
+ C_UNCOMPRESS(UNCOMPRESS_ID, "", UncompressionMode.C_UNCOMPRESS), //$NON-NLS-1$
/**
* Uncompress using Unix compress algorithm
*/
- C_UNXZ(UNXZ_ID, "", "xz", false); //$NON-NLS-1$ //$NON-NLS-2$
+ C_UNXZ(UNXZ_ID, "", UncompressionMode.C_UNXZ); //$NON-NLS-1$
- String mId;
- String mFlag;
- String mExtension;
- boolean mArchive;
+ final String mId;
+ final String mFlag;
+ UncompressionMode mMode;
/**
- * Constructor of <code>UncompressionMode</code>
+ * Constructor of <code>Mode</code>
*
* @param id The command identifier
* @param flag The tar compression flag
- * @param extension The file extension
- * @param archive If the file is an archive or archive-compressed
+ * @param mode The uncompressed mode
*/
- private UncompressionMode(String id, String flag, String extension, boolean archive) {
+ private Mode(String id, String flag, UncompressionMode mode) {
this.mId = id;
this.mFlag = flag;
- this.mExtension = extension;
- this.mArchive = archive;
+ this.mMode = mode;
}
}
@@ -132,24 +130,30 @@ public class UncompressCommand extends AsyncResultProgram implements UncompressE
* </ul>
*
* @param src The archive-compressed file
+ * @param dst The destination file of folder (if null this method resolve with the best
+ * fit based on the src)
* @param asyncResultListener The partial result listener
* @throws InvalidCommandDefinitionException If the command has an invalid definition
*/
public UncompressCommand(
- String src, AsyncResultListener asyncResultListener)
+ String src, String dst, AsyncResultListener asyncResultListener)
throws InvalidCommandDefinitionException {
- super(resolveId(src), asyncResultListener, resolveArguments(src));
+ super(resolveId(src), asyncResultListener, resolveArguments(src, dst));
// Check that have a valid
- UncompressionMode mode = getMode(src);
+ Mode mode = getMode(src);
if (mode == null) {
throw new InvalidCommandDefinitionException(
"Unsupported uncompress mode"); //$NON-NLS-1$
}
// Retrieve information about the uncompress process
- this.mOutFile = resolveOutputFile(src);
- this.mIsArchive = mode.mArchive;
+ if (dst != null) {
+ this.mOutFile = dst;
+ } else {
+ this.mOutFile = resolveOutputFile(src);
+ }
+ this.mIsArchive = mode.mMode.mArchive;
}
/**
@@ -269,7 +273,7 @@ public class UncompressCommand extends AsyncResultProgram implements UncompressE
* @return String The identifier of the command
*/
private static String resolveId(String src) {
- UncompressionMode mode = getMode(src);
+ Mode mode = getMode(src);
if (mode != null) {
return mode.mId;
}
@@ -279,11 +283,16 @@ public class UncompressCommand extends AsyncResultProgram implements UncompressE
/**
* Method that resolves the arguments for the uncompression
*
+ * @param src The source file
+ * @param dst The destination file
* @return String[] The arguments
*/
- private static String[] resolveArguments(String src) {
- String dst = resolveOutputFile(src);
- UncompressionMode mode = getMode(src);
+ private static String[] resolveArguments(String src, String dst) {
+ String out = dst;
+ if (out == null) {
+ out = resolveOutputFile(src);
+ }
+ Mode mode = getMode(src);
if (mode != null) {
switch (mode) {
case A_UNTAR:
@@ -291,10 +300,10 @@ public class UncompressCommand extends AsyncResultProgram implements UncompressE
case AC_GUNZIP2:
case AC_BUNZIP:
case AC_UNLZMA:
- return new String[]{mode.mFlag, dst, src};
+ return new String[]{mode.mFlag, out, src};
case A_UNZIP:
- return new String[]{dst, src};
+ return new String[]{out, src};
case C_GUNZIP:
case C_BUNZIP:
@@ -325,14 +334,15 @@ public class UncompressCommand extends AsyncResultProgram implements UncompressE
* Method that returns the uncompression mode from the compressed file
*
* @param src The compressed file
- * @return UncompressionMode The uncompression mode. <code>null</code> if no mode found
+ * @return Mode The uncompression mode. <code>null</code> if no mode found
*/
- private static UncompressionMode getMode(String src) {
+ private static Mode getMode(String src) {
String extension = FileHelper.getExtension(src);
- UncompressionMode[] modes = UncompressionMode.values();
- for (int i = 0; i < modes.length; i++) {
- UncompressionMode mode = modes[i];
- if (mode.mExtension.compareTo(extension) == 0) {
+ Mode[] modes = Mode.values();
+ int cc = modes.length;
+ for (int i = 0; i < cc; i++) {
+ Mode mode = modes[i];
+ if (mode.mMode.mExtension.compareTo(extension) == 0) {
return mode;
}
}
diff --git a/src/com/cyanogenmod/explorer/preferences/CompressionMode.java b/src/com/cyanogenmod/explorer/preferences/CompressionMode.java
new file mode 100644
index 00000000..a68ece1c
--- /dev/null
+++ b/src/com/cyanogenmod/explorer/preferences/CompressionMode.java
@@ -0,0 +1,67 @@
+/*
+ * 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.preferences;
+
+/**
+ * An enumeration of all implemented compression modes.
+ */
+public enum CompressionMode {
+ /**
+ * Archive using Tar algorithm
+ */
+ A_TAR("tar", true), //$NON-NLS-1$
+ /**
+ * Archive and compress using Gzip algorithm
+ */
+ AC_GZIP("tar.gz", true), //$NON-NLS-1$
+ /**
+ * Archive and compress using Gzip algorithm
+ */
+ AC_GZIP2("tgz", true), //$NON-NLS-1$
+ /**
+ * Archive and compress using Bzip algorithm
+ */
+ AC_BZIP("tar.bz2", true), //$NON-NLS-1$
+ /**
+ * Compress using Gzip algorithm
+ */
+ C_GZIP("gz", false), //$NON-NLS-1$
+ /**
+ * Compress using Bzip algorithm
+ */
+ C_BZIP("bz2", false); //$NON-NLS-1$
+
+ /**
+ * The file extension
+ */
+ public final String mExtension;
+ /**
+ * If the file is an archive or archive-compressed (true) or a compressed file (false)
+ */
+ public final boolean mArchive;
+
+ /**
+ * Constructor of <code>CompressionMode</code>
+ *
+ * @param extension The output extension
+ * @param archive If the output is an archive or archive-compressed
+ */
+ private CompressionMode(String extension, boolean archive) {
+ this.mExtension = extension;
+ this.mArchive = archive;
+ }
+}
diff --git a/src/com/cyanogenmod/explorer/preferences/UncompressionMode.java b/src/com/cyanogenmod/explorer/preferences/UncompressionMode.java
new file mode 100644
index 00000000..2d99fab5
--- /dev/null
+++ b/src/com/cyanogenmod/explorer/preferences/UncompressionMode.java
@@ -0,0 +1,87 @@
+/*
+ * 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.preferences;
+
+/**
+ * An enumeration of all implemented uncompression modes.
+ */
+public enum UncompressionMode {
+ /**
+ * Uncompress using Tar algorithm
+ */
+ A_UNTAR("tar", true), //$NON-NLS-1$
+ /**
+ * Uncompress using Tar algorithm
+ */
+ A_UNZIP("zip", true), //$NON-NLS-1$
+ /**
+ * Uncompress using Gzip algorithm
+ */
+ AC_GUNZIP("tar.gz", true), //$NON-NLS-1$
+ /**
+ * Uncompress using Gzip algorithm
+ */
+ AC_GUNZIP2("tgz", true), //$NON-NLS-1$
+ /**
+ * Uncompress using Bzip algorithm
+ */
+ AC_BUNZIP("tar.bz2", true), //$NON-NLS-1$
+ /**
+ * Uncompress using Lzma algorithm
+ */
+ AC_UNLZMA("tar.lzma", true), //$NON-NLS-1$
+ /**
+ * Uncompress using Gzip algorithm
+ */
+ C_GUNZIP("gz", false), //$NON-NLS-1$
+ /**
+ * Uncompress using Bzip algorithm
+ */
+ C_BUNZIP("bz2", false), //$NON-NLS-1$
+ /**
+ * Uncompress using Lzma algorithm
+ */
+ C_UNLZMA("lzma", false), //$NON-NLS-1$
+ /**
+ * Uncompress using Unix compress algorithm
+ */
+ C_UNCOMPRESS("Z", false), //$NON-NLS-1$
+ /**
+ * Uncompress using Unix compress algorithm
+ */
+ C_UNXZ("xz", false); //$NON-NLS-1$
+
+ /**
+ * The file extension
+ */
+ public final String mExtension;
+ /**
+ * If the file is an archive or archive-compressed (true) or a compressed file (false)
+ */
+ public final boolean mArchive;
+
+ /**
+ * Constructor of <code>UncompressionMode</code>
+ *
+ * @param extension The file extension
+ * @param archive If the file is an archive or archive-compressed
+ */
+ private UncompressionMode(String extension, boolean archive) {
+ this.mExtension = extension;
+ this.mArchive = archive;
+ }
+}
diff --git a/src/com/cyanogenmod/explorer/ui/dialogs/ActionsDialog.java b/src/com/cyanogenmod/explorer/ui/dialogs/ActionsDialog.java
index 2118b036..f280ac38 100644
--- a/src/com/cyanogenmod/explorer/ui/dialogs/ActionsDialog.java
+++ b/src/com/cyanogenmod/explorer/ui/dialogs/ActionsDialog.java
@@ -314,6 +314,24 @@ public class ActionsDialog implements OnItemClickListener, OnItemLongClickListen
this.mFso,
this.mOnRequestRefreshListener);
break;
+ //- Compress
+ case R.id.mnu_actions_compress:
+ if (this.mOnSelectionListener != null) {
+ CompressActionPolicy.compress(
+ this.mContext,
+ this.mFso,
+ this.mOnSelectionListener,
+ this.mOnRequestRefreshListener);
+ }
+ break;
+ case R.id.mnu_actions_compress_selection:
+ if (this.mOnSelectionListener != null) {
+ CompressActionPolicy.compress(
+ this.mContext,
+ this.mOnSelectionListener,
+ this.mOnRequestRefreshListener);
+ }
+ break;
//- Create copy
case R.id.mnu_actions_create_copy:
@@ -603,7 +621,8 @@ public class ActionsDialog implements OnItemClickListener, OnItemLongClickListen
List<FileSystemObject> items, FileSystemObject directory) {
List<LinkedResource> resources =
new ArrayList<LinkedResource>(items.size());
- for (int i = 0; i < items.size(); i++) {
+ int cc = items.size();
+ for (int i = 0; i < cc; i++) {
FileSystemObject fso = items.get(i);
File src = new File(fso.getFullPath());
File dst = new File(directory.getFullPath(), fso.getName());
diff --git a/src/com/cyanogenmod/explorer/ui/dialogs/AssociationsDialog.java b/src/com/cyanogenmod/explorer/ui/dialogs/AssociationsDialog.java
index 082a92c8..08dec3b1 100644
--- a/src/com/cyanogenmod/explorer/ui/dialogs/AssociationsDialog.java
+++ b/src/com/cyanogenmod/explorer/ui/dialogs/AssociationsDialog.java
@@ -421,10 +421,10 @@ public class AssociationsDialog implements OnItemClickListener {
} catch (Exception e) {
// Capture the exception
ExceptionUtil.translateException(this.mContext, e, true, false);
- Toast.makeText(
+ DialogHelper.showToast(
this.mContext,
R.string.msgs_action_association_failed,
- Toast.LENGTH_SHORT).show();
+ Toast.LENGTH_SHORT);
}
}
}
diff --git a/src/com/cyanogenmod/explorer/ui/dialogs/ChooseConsoleDialog.java b/src/com/cyanogenmod/explorer/ui/dialogs/ChooseConsoleDialog.java
index 2343af1c..952f334d 100644
--- a/src/com/cyanogenmod/explorer/ui/dialogs/ChooseConsoleDialog.java
+++ b/src/com/cyanogenmod/explorer/ui/dialogs/ChooseConsoleDialog.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
+import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
@@ -89,10 +90,12 @@ public class ChooseConsoleDialog implements OnItemClickListener {
//Create the list view
ListView listView = new ListView(context);
LinearLayout.LayoutParams params =
- new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ new LinearLayout.LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
listView.setLayoutParams(params);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
+ listView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
//Create the dialog
this.mDialog = DialogHelper.createDialog(
@@ -114,6 +117,9 @@ public class ChooseConsoleDialog implements OnItemClickListener {
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ try {
+ ((CheckableListAdapter)((ListView)parent).getAdapter()).setSelectedItem(position);
+ } catch (Exception e) {/**NON BLOCK**/}
this.mDialog.dismiss();
boolean ret = false;
Boolean superuser = Boolean.FALSE;
diff --git a/src/com/cyanogenmod/explorer/ui/policy/ActionsPolicy.java b/src/com/cyanogenmod/explorer/ui/policy/ActionsPolicy.java
index 21cfb4b0..77eb6312 100644
--- a/src/com/cyanogenmod/explorer/ui/policy/ActionsPolicy.java
+++ b/src/com/cyanogenmod/explorer/ui/policy/ActionsPolicy.java
@@ -23,6 +23,7 @@ import android.widget.Toast;
import com.cyanogenmod.explorer.R;
import com.cyanogenmod.explorer.ui.dialogs.MessageProgressDialog;
+import com.cyanogenmod.explorer.util.DialogHelper;
import com.cyanogenmod.explorer.util.ExceptionUtil;
@@ -51,6 +52,13 @@ public abstract class ActionsPolicy {
int getDialogTitle();
/**
+ * Method that returns if the dialog is cancelable
+ *
+ * @return boolean If the dialog is cancelable
+ */
+ boolean isDialogCancelable();
+
+ /**
* Method invoked when need to update the progress of the dialog
*
* @return Spanned The text to show in the progress
@@ -99,12 +107,19 @@ public abstract class ActionsPolicy {
@Override
protected void onPreExecute() {
// Create the waiting dialog while doing some stuff on background
+ final BackgroundAsyncTask task = this;
this.mDialog = new MessageProgressDialog(
this.mCtx,
- R.drawable.ic_holo_light_operation,
- R.string.waiting_dialog_copying_title,
+ this.mCallable.getDialogIcon(),
+ this.mCallable.getDialogTitle(),
R.string.waiting_dialog_msg,
- false);
+ this.mCallable.isDialogCancelable());
+ this.mDialog.setOnCancelListener(new MessageProgressDialog.OnCancelListener() {
+ @Override
+ public boolean onCancel() {
+ return task.cancel(true);
+ }
+ });
Spanned progress = this.mCallable.requestProgress();
this.mDialog.setProgress(progress);
this.mDialog.show();
@@ -139,6 +154,12 @@ public abstract class ActionsPolicy {
}
@Override
+ protected void onCancelled() {
+ //Operation complete.
+ this.mCallable.onSuccess();
+ }
+
+ @Override
protected void onProgressUpdate(Spanned... values) {
this.mDialog.setProgress(values[0]);
}
@@ -159,6 +180,6 @@ public abstract class ActionsPolicy {
* @hide
*/
protected static void showOperationSuccessMsg(Context ctx) {
- Toast.makeText(ctx, R.string.msgs_success, Toast.LENGTH_SHORT).show();
+ DialogHelper.showToast(ctx, R.string.msgs_success, Toast.LENGTH_SHORT);
}
} \ No newline at end of file
diff --git a/src/com/cyanogenmod/explorer/ui/policy/BookmarksActionPolicy.java b/src/com/cyanogenmod/explorer/ui/policy/BookmarksActionPolicy.java
index 6afe0dff..a9253412 100644
--- a/src/com/cyanogenmod/explorer/ui/policy/BookmarksActionPolicy.java
+++ b/src/com/cyanogenmod/explorer/ui/policy/BookmarksActionPolicy.java
@@ -24,6 +24,7 @@ import com.cyanogenmod.explorer.model.Bookmark;
import com.cyanogenmod.explorer.model.Bookmark.BOOKMARK_TYPE;
import com.cyanogenmod.explorer.model.FileSystemObject;
import com.cyanogenmod.explorer.preferences.Bookmarks;
+import com.cyanogenmod.explorer.util.DialogHelper;
import com.cyanogenmod.explorer.util.ExceptionUtil;
/**
@@ -45,16 +46,16 @@ public final class BookmarksActionPolicy extends ActionsPolicy {
bookmark = Bookmarks.addBookmark(ctx, bookmark);
if (bookmark == null) {
// The operation fails
- Toast.makeText(
+ DialogHelper.showToast(
ctx,
R.string.msgs_operation_failure,
- Toast.LENGTH_SHORT).show();
+ Toast.LENGTH_SHORT);
} else {
// Success
- Toast.makeText(
+ DialogHelper.showToast(
ctx,
R.string.bookmarks_msgs_add_success,
- Toast.LENGTH_SHORT).show();
+ Toast.LENGTH_SHORT);
}
} catch (Exception e) {
diff --git a/src/com/cyanogenmod/explorer/ui/policy/CompressActionPolicy.java b/src/com/cyanogenmod/explorer/ui/policy/CompressActionPolicy.java
index b41ed3d8..bcae907c 100644
--- a/src/com/cyanogenmod/explorer/ui/policy/CompressActionPolicy.java
+++ b/src/com/cyanogenmod/explorer/ui/policy/CompressActionPolicy.java
@@ -21,16 +21,20 @@ import android.content.Context;
import android.content.DialogInterface;
import android.text.Html;
import android.text.Spanned;
+import android.widget.Toast;
import com.cyanogenmod.explorer.ExplorerApplication;
import com.cyanogenmod.explorer.R;
import com.cyanogenmod.explorer.commands.AsyncResultListener;
+import com.cyanogenmod.explorer.commands.CompressExecutable;
import com.cyanogenmod.explorer.commands.UncompressExecutable;
import com.cyanogenmod.explorer.console.ConsoleBuilder;
import com.cyanogenmod.explorer.console.ExecutionException;
import com.cyanogenmod.explorer.console.RelaunchableException;
import com.cyanogenmod.explorer.listeners.OnRequestRefreshListener;
+import com.cyanogenmod.explorer.listeners.OnSelectionListener;
import com.cyanogenmod.explorer.model.FileSystemObject;
+import com.cyanogenmod.explorer.preferences.CompressionMode;
import com.cyanogenmod.explorer.util.CommandHelper;
import com.cyanogenmod.explorer.util.DialogHelper;
import com.cyanogenmod.explorer.util.ExceptionUtil;
@@ -38,6 +42,8 @@ import com.cyanogenmod.explorer.util.ExceptionUtil.OnRelaunchCommandResult;
import com.cyanogenmod.explorer.util.FileHelper;
import com.cyanogenmod.explorer.util.FixedQueue;
+import java.io.File;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -50,7 +56,6 @@ public final class CompressActionPolicy extends ActionsPolicy {
*/
private static class CompressListener implements AsyncResultListener {
- Object mSync;
final FixedQueue<String> mQueue;
boolean mEnd;
Throwable mCause;
@@ -61,23 +66,18 @@ public final class CompressActionPolicy extends ActionsPolicy {
public CompressListener() {
super();
this.mEnd = false;
- this.mSync = new Object();
this.mQueue = new FixedQueue<String>(2); //Holds only one item
this.mCause = null;
}
@Override
public void onPartialResult(Object result) {
- synchronized (this.mSync) {
- this.mQueue.insert((String)result);
- }
+ this.mQueue.insert((String)result);
}
@Override
public void onException(Exception cause) {
- synchronized (this.mSync) {
- this.mCause = cause;
- }
+ this.mCause = cause;
}
@Override
@@ -88,9 +88,389 @@ public final class CompressActionPolicy extends ActionsPolicy {
@Override
public void onAsyncExitCode(int exitCode) {
- synchronized (this.mSync) {
- this.mEnd = true;
+ this.mEnd = true;
+ }
+ }
+
+ /**
+ * Method that compresses the list of files of the selection.
+ *
+ * @param ctx The current context
+ * @param onSelectionListener The listener for obtain selection information (required)
+ * @param onRequestRefreshListener The listener for request a refresh (optional)
+ * @hide
+ */
+ public static void compress(
+ final Context ctx,
+ final OnSelectionListener onSelectionListener,
+ final OnRequestRefreshListener onRequestRefreshListener) {
+
+ // Retrieve the current selection
+ final List<FileSystemObject> selection = onSelectionListener.onRequestSelectedFiles();
+ if (selection != null && selection.size() > 0) {
+ // Show a dialog to allow the user make the compression mode choice
+ AlertDialog dialog = DialogHelper.createSingleChoiceDialog(
+ ctx, R.drawable.ic_holo_light_compress, R.string.compression_mode_title,
+ getSupportedCompressionModesLabels(ctx, selection),
+ CompressionMode.AC_GZIP.ordinal(),
+ new DialogHelper.OnSelectChoiceListener() {
+ @Override
+ public void onSelectChoice(int choice) {
+ // Do the compression
+ compress(
+ ctx,
+ getCompressionModeFromUserChoice(choice),
+ selection,
+ onSelectionListener,
+ onRequestRefreshListener);
+ }
+
+ @Override
+ public void onNoSelectChoice() {/**NON BLOCK**/}
+ });
+ dialog.show();
+ }
+ }
+
+ /**
+ * Method that compresses an uncompressed file.
+ *
+ * @param ctx The current context
+ * @param fso The compressed file
+ * @param onSelectionListener The listener for obtain selection information (required)
+ * @param onRequestRefreshListener The listener for request a refresh (optional)
+ * @hide
+ */
+ public static void compress(
+ final Context ctx, final FileSystemObject fso,
+ final OnSelectionListener onSelectionListener,
+ final OnRequestRefreshListener onRequestRefreshListener) {
+
+ // Create a list with the item
+ final List<FileSystemObject> items = new ArrayList<FileSystemObject>();
+ items.add(fso);
+
+ // Show a dialog to allow the user make the compression mode choice
+ AlertDialog dialog = DialogHelper.createSingleChoiceDialog(
+ ctx, R.drawable.ic_holo_light_compress, R.string.compression_mode_title,
+ getSupportedCompressionModesLabels(ctx, items),
+ CompressionMode.AC_GZIP.ordinal(),
+ new DialogHelper.OnSelectChoiceListener() {
+ @Override
+ public void onSelectChoice(int choice) {
+ // Do the compression
+ compress(
+ ctx,
+ getCompressionModeFromUserChoice(choice),
+ items,
+ onSelectionListener,
+ onRequestRefreshListener);
+ }
+
+ @Override
+ public void onNoSelectChoice() {/**NON BLOCK**/}
+ });
+ dialog.show();
+ }
+
+
+ /**
+ * Method that compresses some uncompressed files or folders
+ *
+ * @param ctx The current context
+ * @param mode The compression mode
+ * @param fsos The list of files to compress
+ * @param onSelectionListener The listener for obtain selection information (required)
+ * @param onRequestRefreshListener The listener for request a refresh (optional)
+ * @hide
+ */
+ static void compress(
+ final Context ctx, final CompressionMode mode, final List<FileSystemObject> fsos,
+ final OnSelectionListener onSelectionListener,
+ final OnRequestRefreshListener onRequestRefreshListener) {
+
+ // The callable interface
+ final BackgroundCallable callable = new BackgroundCallable() {
+ // The current items
+ final Context mCtx = ctx;
+ final CompressionMode mMode = mode;
+ final List<FileSystemObject> mFsos = fsos;
+ final OnRequestRefreshListener mOnRequestRefreshListener = onRequestRefreshListener;
+
+ final Object mSync = new Object();
+ Throwable mCause;
+ CompressExecutable cmd = null;
+
+ final CompressListener mListener =
+ new CompressListener();
+ private String mMsg;
+ private boolean mStarted = false;
+
+ @Override
+ public int getDialogTitle() {
+ return R.string.waiting_dialog_compressing_title;
+ }
+ @Override
+ public int getDialogIcon() {
+ return R.drawable.ic_holo_light_operation;
+ }
+ @Override
+ public boolean isDialogCancelable() {
+ return true;
}
+
+ @Override
+ public Spanned requestProgress() {
+ // Initializing the dialog
+ if (!this.mStarted) {
+ String progress =
+ this.mCtx.getResources().
+ getString(
+ R.string.waiting_dialog_analizing_msg);
+ return Html.fromHtml(progress);
+ }
+
+ // Return the current operation
+ String msg = (this.mMsg == null) ? "" : this.mMsg; //$NON-NLS-1$
+ String progress =
+ this.mCtx.getResources().
+ getString(
+ R.string.waiting_dialog_compressing_msg,
+ msg);
+ return Html.fromHtml(progress);
+ }
+
+ @Override
+ public void onSuccess() {
+ try {
+ if (this.cmd != null && this.cmd.isCancelable() && !this.cmd.isCanceled()) {
+ this.cmd.cancel();
+ }
+ } catch (Exception e) {/**NON BLOCK**/}
+
+ //Operation complete. Refresh
+ if (this.mOnRequestRefreshListener != null) {
+ // The reference is not the same, so refresh the complete navigation view
+ this.mOnRequestRefreshListener.onRequestRefresh(null);
+ }
+ if (this.cmd != null) {
+ showOperationSuccessMsg(
+ ctx,
+ R.string.msgs_extracting_success,
+ this.cmd.getOutCompressedFile());
+ } else {
+ ActionsPolicy.showOperationSuccessMsg(ctx);
+ }
+ }
+
+ @Override
+ public void doInBackground(Object... params) throws Throwable {
+ this.mCause = null;
+ this.mStarted = true;
+
+ // This method expect to receive
+ // 1.- BackgroundAsyncTask
+ BackgroundAsyncTask task = (BackgroundAsyncTask)params[0];
+ String out = null;
+ try {
+ // Archive or Archive-Compression
+ if (this.mMode.mArchive) {
+ // Convert the list to an array of full paths
+ String[] src = new String[this.mFsos.size()];
+ int cc = this.mFsos.size();
+ for (int i = 0; i < cc; i++) {
+ src[i] = this.mFsos.get(i).getFullPath();
+ }
+
+ // Use the current directory name for create the compressed file
+ String curDirName =
+ new File(onSelectionListener.onRequestCurrentDir()).getName();
+ if (src.length == 1) {
+ // But only one file is passed, then used the name of unique file
+ curDirName = FileHelper.getName(this.mFsos.get(0).getName());
+ }
+ String name =
+ String.format(
+ "%s.%s", curDirName, this.mMode.mExtension); //$NON-NLS-1$
+ String newName =
+ FileHelper.createNonExistingName(
+ ctx,
+ onSelectionListener.onRequestCurrentItems(),
+ name,
+ R.string.create_new_compress_file_regexp);
+ String newNameAbs =
+ new File(
+ onSelectionListener.onRequestCurrentDir(),
+ newName).getAbsolutePath();
+
+ // Do the compression
+ this.cmd =
+ CommandHelper.compress(
+ ctx,
+ this.mMode,
+ newNameAbs,
+ src,
+ this.mListener, null);
+
+ // Compression
+ } else {
+ // Only the first item from the list is valid. If there are more in the
+ // list, then discard them
+ String src = this.mFsos.get(0).getFullPath();
+
+ // Do the compression
+ this.cmd =
+ CommandHelper.compress(
+ ctx,
+ this.mMode,
+ src,
+ this.mListener, null);
+ }
+ out = this.cmd.getOutCompressedFile();
+
+ // Request paint the
+ this.mListener.mQueue.insert(out);
+ task.onRequestProgress();
+
+ // Don't use an active blocking because this suppose that all message
+ // will be processed by the UI. Instead, refresh with a delay and
+ // display the active file
+ while (!this.mListener.mEnd) {
+ // Sleep to don't saturate the UI thread
+ Thread.sleep(50L);
+
+ List<String> msgs = this.mListener.mQueue.peekAll();
+ if (msgs.size() > 0) {
+ this.mMsg = msgs.get(msgs.size()-1);
+ task.onRequestProgress();
+ }
+ }
+
+ // Dialog is ended. Force the last redraw
+ List<String> msgs = this.mListener.mQueue.peekAll();
+ if (msgs.size() > 0) {
+ this.mMsg = msgs.get(msgs.size()-1);
+ task.onRequestProgress();
+ }
+
+ } catch (Exception e) {
+ // Need to be relaunched?
+ if (e instanceof RelaunchableException) {
+ OnRelaunchCommandResult rl = new OnRelaunchCommandResult() {
+ @Override
+ @SuppressWarnings("unqualified-field-access")
+ public void onSuccess() {
+ synchronized (mSync) {
+ mSync.notify();
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unqualified-field-access")
+ public void onFailed(Throwable cause) {
+ mCause = cause;
+ synchronized (mSync) {
+ mSync.notify();
+ }
+ }
+ @Override
+ @SuppressWarnings("unqualified-field-access")
+ public void onCanceled() {
+ synchronized (mSync) {
+ mSync.notify();
+ }
+ }
+ };
+
+ // Translate the exception (and wait for the result)
+ ExceptionUtil.translateException(ctx, e, false, true, rl);
+ synchronized (this.mSync) {
+ this.mSync.wait();
+ }
+
+ // Persist the exception?
+ if (this.mCause != null) {
+ // The exception must be elevated
+ throw this.mCause;
+ }
+
+ } else {
+ // The exception must be elevated
+ throw e;
+ }
+ }
+
+
+ // Any exception?
+ if (this.mListener.mCause != null) {
+ throw this.mListener.mCause;
+ }
+
+ // Check that the operation was completed retrieving the extracted file or folder
+ boolean failed = true;
+ try {
+ CommandHelper.getFileInfo(ctx, out, false, null);
+
+ // Failed. The file exists
+ failed = false;
+
+ } catch (Throwable e) {
+ // Operation complete successfully
+ }
+ if (failed) {
+ throw new ExecutionException(
+ String.format(
+ "Failed to compress file(s) to: %s", out)); //$NON-NLS-1$
+ }
+ }
+ };
+ final BackgroundAsyncTask task = new BackgroundAsyncTask(ctx, callable);
+
+ // Check if the output exists. When the mode is archive, this method generate a new
+ // name based in the current directory. When the mode is compressed then the name
+ // is the name of the file to compress without extension. In this case the name should
+ // be validate prior to compress
+ boolean askUser = false;
+ try {
+ if (!mode.mArchive) {
+ // Only the first item from the list is valid. If there are more in the
+ // list, then discard them
+ String src = fsos.get(0).getFullPath();
+ CompressExecutable ucmd =
+ ExplorerApplication.getBackgroundConsole().
+ getExecutableFactory().newCreator().
+ createCompressExecutable(mode, src, null);
+ String dst = ucmd.getOutCompressedFile();
+ FileSystemObject info = CommandHelper.getFileInfo(ctx, dst, null);
+ if (info != null) {
+ askUser = true;
+ }
+ }
+ } catch (Exception e) {/**NON BLOCK**/}
+
+ // Ask the user because the destination file or folder exists
+ if (askUser) {
+ //Show a dialog asking the user for overwrite the files
+ AlertDialog dialog =
+ DialogHelper.createTwoButtonsQuestionDialog(
+ ctx,
+ android.R.string.cancel,
+ R.string.overwrite,
+ ctx.getString(R.string.msgs_overwrite_files),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface alertDialog, int which) {
+ // NEGATIVE (overwrite) POSITIVE (cancel)
+ if (which == DialogInterface.BUTTON_NEGATIVE) {
+ // Execute background task
+ task.execute(task);
+ }
+ }
+ });
+ dialog.show();
+ } else {
+ // Execute background task
+ task.execute(task);
}
}
@@ -115,6 +495,7 @@ public final class CompressActionPolicy extends ActionsPolicy {
final Object mSync = new Object();
Throwable mCause;
+ UncompressExecutable cmd;
final CompressListener mListener =
new CompressListener();
@@ -129,6 +510,10 @@ public final class CompressActionPolicy extends ActionsPolicy {
public int getDialogIcon() {
return R.drawable.ic_holo_light_operation;
}
+ @Override
+ public boolean isDialogCancelable() {
+ return true;
+ }
@Override
public Spanned requestProgress() {
@@ -137,7 +522,7 @@ public final class CompressActionPolicy extends ActionsPolicy {
String progress =
this.mCtx.getResources().
getString(
- R.string.waiting_dialog_extracting_analizing_msg);
+ R.string.waiting_dialog_analizing_msg);
return Html.fromHtml(progress);
}
@@ -153,12 +538,25 @@ public final class CompressActionPolicy extends ActionsPolicy {
@Override
public void onSuccess() {
+ try {
+ if (this.cmd != null && this.cmd.isCancelable() && !this.cmd.isCanceled()) {
+ this.cmd.cancel();
+ }
+ } catch (Exception e) {/**NON BLOCK**/}
+
//Operation complete. Refresh
if (this.mOnRequestRefreshListener != null) {
// The reference is not the same, so refresh the complete navigation view
this.mOnRequestRefreshListener.onRequestRefresh(null);
}
- ActionsPolicy.showOperationSuccessMsg(ctx);
+ if (this.cmd != null) {
+ showOperationSuccessMsg(
+ ctx,
+ R.string.msgs_extracting_success,
+ this.cmd.getOutUncompressedFile());
+ } else {
+ ActionsPolicy.showOperationSuccessMsg(ctx);
+ }
}
@Override
@@ -171,12 +569,13 @@ public final class CompressActionPolicy extends ActionsPolicy {
BackgroundAsyncTask task = (BackgroundAsyncTask)params[0];
String out = null;
try {
- UncompressExecutable cmd =
- CommandHelper.uncompress(
- ctx,
- this.mFso.getFullPath(),
- this.mListener, null);
- out = cmd.getOutUncompressedFile();
+ this.cmd =
+ CommandHelper.uncompress(
+ ctx,
+ this.mFso.getFullPath(),
+ null,
+ this.mListener, null);
+ out = this.cmd.getOutUncompressedFile();
// Request paint the
this.mListener.mQueue.insert(out);
@@ -283,7 +682,7 @@ public final class CompressActionPolicy extends ActionsPolicy {
UncompressExecutable ucmd =
ExplorerApplication.getBackgroundConsole().
getExecutableFactory().newCreator().
- createUncompressExecutable(fso.getFullPath(), null);
+ createUncompressExecutable(fso.getFullPath(), null, null);
String dst = ucmd.getOutUncompressedFile();
FileSystemObject info = CommandHelper.getFileInfo(ctx, dst, null);
if (info != null) {
@@ -334,7 +733,7 @@ public final class CompressActionPolicy extends ActionsPolicy {
// make the extraction
String ext = FileHelper.getExtension(fso);
if (ConsoleBuilder.isPrivileged() && ext.compareTo("zip") == 0) { //$NON-NLS-1$
- AlertDialog dialog =DialogHelper.createYesNoDialog(
+ AlertDialog dialog = DialogHelper.createYesNoDialog(
ctx, R.string.security_warning_extract,
new DialogInterface.OnClickListener() {
@Override
@@ -351,4 +750,59 @@ public final class CompressActionPolicy extends ActionsPolicy {
task.execute(task);
}
}
+
+ /**
+ * Method that returns the supported compression modes
+ *
+ * @param ctx The current context
+ * @param fsos The list of file system objects to compress
+ * @return String[] An array with the compression mode labels
+ */
+ private static String[] getSupportedCompressionModesLabels(
+ Context ctx, List<FileSystemObject> fsos) {
+ String[] labels = ctx.getResources().getStringArray(R.array.compression_modes_labels);
+ if (fsos.size() > 1 || (fsos.size() == 1 && FileHelper.isDirectory(fsos.get(0)))) {
+ // If more that a file is requested, compression is not available
+ // The same applies if the unique item is a folder
+ ArrayList<String> validLabels = new ArrayList<String>();
+ CompressionMode[] values = CompressionMode.values();
+ int cc = values.length;
+ for (int i = 0; i < cc; i++) {
+ if (values[i].mArchive) {
+ validLabels.add(labels[i]);
+ }
+ }
+ labels = validLabels.toArray(new String[]{});
+ }
+ return labels;
+ }
+
+ /**
+ * Method that returns the compression mode from the user choice
+ *
+ * @param choice The choice of the user
+ * @return CompressionMode The compression mode
+ */
+ static CompressionMode getCompressionModeFromUserChoice(int choice) {
+ CompressionMode[] values = CompressionMode.values();
+ int cc = values.length;
+ for (int i = 0; i < cc; i++) {
+ if (values[i].ordinal() == choice) {
+ return values[i];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method that shows a message when the operation is complete successfully
+ *
+ * @param ctx The current context
+ * @param res The resource identifier
+ * @param dst The destination output
+ * @hide
+ */
+ protected static void showOperationSuccessMsg(Context ctx, int res, String dst) {
+ DialogHelper.showToast(ctx, ctx.getString(res, dst), Toast.LENGTH_LONG);
+ }
} \ No newline at end of file
diff --git a/src/com/cyanogenmod/explorer/ui/policy/CopyMoveActionPolicy.java b/src/com/cyanogenmod/explorer/ui/policy/CopyMoveActionPolicy.java
index 3a49c1f1..974aa162 100644
--- a/src/com/cyanogenmod/explorer/ui/policy/CopyMoveActionPolicy.java
+++ b/src/com/cyanogenmod/explorer/ui/policy/CopyMoveActionPolicy.java
@@ -41,7 +41,7 @@ import java.util.List;
* A class with the convenience methods for resolve copy/move related actions
*/
public final class CopyMoveActionPolicy extends ActionsPolicy {
-
+
/**
* @hide
*/
@@ -51,7 +51,7 @@ public final class CopyMoveActionPolicy extends ActionsPolicy {
RENAME,
CREATE_COPY,
}
-
+
/**
* A class that holds a relationship between a source {@link File} and
@@ -132,7 +132,9 @@ public final class CopyMoveActionPolicy extends ActionsPolicy {
// Create a non-existing name
List<FileSystemObject> curFiles = onSelectionListener.onRequestCurrentItems();
- String newName = FileHelper.createNonExistingName(ctx, curFiles, fso);
+ String newName =
+ FileHelper.createNonExistingName(
+ ctx, curFiles, fso.getName(), R.string.create_copy_regexp);
final File dst = new File(fso.getParent(), newName);
File src = new File(fso.getFullPath());
@@ -221,7 +223,8 @@ public final class CopyMoveActionPolicy extends ActionsPolicy {
// 2.- All the destination files must have the same parent and it must be currentDirectory,
// and not be null
final String currentDirectory = onSelectionListener.onRequestCurrentDir();
- for (int i = 0; i < files.size(); i++) {
+ int cc = files.size();
+ for (int i = 0; i < cc; i++) {
LinkedResource linkedRes = files.get(i);
if (linkedRes.mSrc == null || linkedRes.mDst == null) {
AlertDialog dialog =
@@ -267,6 +270,10 @@ public final class CopyMoveActionPolicy extends ActionsPolicy {
public int getDialogIcon() {
return R.drawable.ic_holo_light_operation;
}
+ @Override
+ public boolean isDialogCancelable() {
+ return false;
+ }
@Override
public Spanned requestProgress() {
@@ -304,7 +311,8 @@ public final class CopyMoveActionPolicy extends ActionsPolicy {
// 1.- BackgroundAsyncTask
BackgroundAsyncTask task = (BackgroundAsyncTask)params[0];
- for (int i = 0; i < this.mFiles.size(); i++) {
+ int cc2 = this.mFiles.size();
+ for (int i = 0; i < cc2; i++) {
File src = this.mFiles.get(i).mSrc;
File dst = this.mFiles.get(i).mDst;
@@ -444,8 +452,10 @@ public final class CopyMoveActionPolicy extends ActionsPolicy {
private static boolean isOverwriteNeeded(
List<LinkedResource> files, List<FileSystemObject> currentFiles) {
boolean askUser = false;
- for (int i = 0; i < currentFiles.size(); i++) {
- for (int j = 0; j < files.size(); j++) {
+ int cc = currentFiles.size();
+ for (int i = 0; i < cc; i++) {
+ int cc2 = files.size();
+ for (int j = 0; j < cc2; j++) {
FileSystemObject dst1 = currentFiles.get(i);
File dst2 = files.get(j).mDst;
@@ -479,7 +489,8 @@ public final class CopyMoveActionPolicy extends ActionsPolicy {
*/
private static boolean checkMoveConsistency(
Context ctx, List<LinkedResource> files, String currentDirectory) {
- for (int i = 0; i < files.size(); i++) {
+ int cc = files.size();
+ for (int i = 0; i < cc; i++) {
LinkedResource linkRes = files.get(i);
String src = linkRes.mSrc.getAbsolutePath();
String dst = linkRes.mDst.getAbsolutePath();
diff --git a/src/com/cyanogenmod/explorer/ui/policy/DeleteActionPolicy.java b/src/com/cyanogenmod/explorer/ui/policy/DeleteActionPolicy.java
index d66cb956..adf94dd3 100644
--- a/src/com/cyanogenmod/explorer/ui/policy/DeleteActionPolicy.java
+++ b/src/com/cyanogenmod/explorer/ui/policy/DeleteActionPolicy.java
@@ -145,6 +145,10 @@ public final class DeleteActionPolicy extends ActionsPolicy {
public int getDialogIcon() {
return R.drawable.ic_holo_light_operation;
}
+ @Override
+ public boolean isDialogCancelable() {
+ return false;
+ }
@Override
public Spanned requestProgress() {
@@ -177,7 +181,8 @@ public final class DeleteActionPolicy extends ActionsPolicy {
// 1.- BackgroundAsyncTask
BackgroundAsyncTask task = (BackgroundAsyncTask)params[0];
- for (int i = 0; i < this.mFiles.size(); i++) {
+ int cc = this.mFiles.size();
+ for (int i = 0; i < cc; i++) {
FileSystemObject fso = this.mFiles.get(i);
doOperation(this.mCtx, fso);
@@ -293,7 +298,8 @@ public final class DeleteActionPolicy extends ActionsPolicy {
*/
private static boolean checkRemoveConsistency(
Context ctx, List<FileSystemObject> files, String currentDirectory) {
- for (int i = 0; i < files.size(); i++) {
+ int cc = files.size();
+ for (int i = 0; i < cc; i++) {
FileSystemObject fso = files.get(i);
// 1.- Current directory can't be deleted
diff --git a/src/com/cyanogenmod/explorer/ui/policy/InfoActionPolicy.java b/src/com/cyanogenmod/explorer/ui/policy/InfoActionPolicy.java
index 81680153..9e127598 100644
--- a/src/com/cyanogenmod/explorer/ui/policy/InfoActionPolicy.java
+++ b/src/com/cyanogenmod/explorer/ui/policy/InfoActionPolicy.java
@@ -23,6 +23,7 @@ import android.widget.Toast;
import com.cyanogenmod.explorer.listeners.OnRequestRefreshListener;
import com.cyanogenmod.explorer.model.FileSystemObject;
import com.cyanogenmod.explorer.ui.dialogs.FsoPropertiesDialog;
+import com.cyanogenmod.explorer.util.DialogHelper;
/**
* A class with the convenience methods for resolve the display of info actions
@@ -37,7 +38,7 @@ public final class InfoActionPolicy extends ActionsPolicy {
*/
public static void showContentDescription(final Context ctx, final FileSystemObject fso) {
String contentDescription = fso.getFullPath();
- Toast.makeText(ctx, contentDescription, Toast.LENGTH_SHORT).show();
+ DialogHelper.showToast(ctx, contentDescription, Toast.LENGTH_SHORT);
}
/**
diff --git a/src/com/cyanogenmod/explorer/ui/policy/IntentsActionPolicy.java b/src/com/cyanogenmod/explorer/ui/policy/IntentsActionPolicy.java
index 1d43a8c1..b9b2cc86 100644
--- a/src/com/cyanogenmod/explorer/ui/policy/IntentsActionPolicy.java
+++ b/src/com/cyanogenmod/explorer/ui/policy/IntentsActionPolicy.java
@@ -26,6 +26,7 @@ import android.widget.Toast;
import com.cyanogenmod.explorer.R;
import com.cyanogenmod.explorer.model.FileSystemObject;
import com.cyanogenmod.explorer.ui.dialogs.AssociationsDialog;
+import com.cyanogenmod.explorer.util.DialogHelper;
import com.cyanogenmod.explorer.util.ExceptionUtil;
import com.cyanogenmod.explorer.util.MimeTypeHelper;
@@ -140,7 +141,7 @@ public final class IntentsActionPolicy extends ActionsPolicy {
// No registered application
if (info.size() == 0) {
- Toast.makeText(ctx, R.string.msgs_not_registered_app, Toast.LENGTH_SHORT).show();
+ DialogHelper.showToast(ctx, R.string.msgs_not_registered_app, Toast.LENGTH_SHORT);
return;
}
diff --git a/src/com/cyanogenmod/explorer/util/CommandHelper.java b/src/com/cyanogenmod/explorer/util/CommandHelper.java
index c094f185..5b194088 100644
--- a/src/com/cyanogenmod/explorer/util/CommandHelper.java
+++ b/src/com/cyanogenmod/explorer/util/CommandHelper.java
@@ -53,7 +53,6 @@ import com.cyanogenmod.explorer.commands.SyncResultExecutable;
import com.cyanogenmod.explorer.commands.UncompressExecutable;
import com.cyanogenmod.explorer.commands.WritableExecutable;
import com.cyanogenmod.explorer.commands.WriteExecutable;
-import com.cyanogenmod.explorer.commands.shell.CompressCommand.CompressionMode;
import com.cyanogenmod.explorer.commands.shell.InvalidCommandDefinitionException;
import com.cyanogenmod.explorer.console.CommandNotFoundException;
import com.cyanogenmod.explorer.console.Console;
@@ -74,6 +73,7 @@ import com.cyanogenmod.explorer.model.Permissions;
import com.cyanogenmod.explorer.model.Query;
import com.cyanogenmod.explorer.model.SearchResult;
import com.cyanogenmod.explorer.model.User;
+import com.cyanogenmod.explorer.preferences.CompressionMode;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -1296,6 +1296,8 @@ public final class CommandHelper {
*
* @param context The current context (needed if console == null)
* @param src The file to compress
+ * @param dst The destination file of folder (if null this method resolve with the best
+ * fit based on the src)
* @param asyncResultListener The partial result listener
* @param console The console in which execute the program.
* <code>null</code> to attach to the default console
@@ -1313,7 +1315,7 @@ public final class CommandHelper {
* @see CompressExecutable
*/
public static UncompressExecutable uncompress(
- Context context, String src,
+ Context context, String src, String dst,
AsyncResultListener asyncResultListener, Console console)
throws FileNotFoundException, IOException, ConsoleAllocException,
NoSuchFileOrDirectory, InsufficientPermissionsException,
@@ -1323,7 +1325,7 @@ public final class CommandHelper {
UncompressExecutable executable1 =
c.getExecutableFactory().newCreator().
- createUncompressExecutable(src, asyncResultListener);
+ createUncompressExecutable(src, dst, asyncResultListener);
// Prior to write to disk the data, ensure that can write to the disk using
// createFile or createFolder method
diff --git a/src/com/cyanogenmod/explorer/util/DialogHelper.java b/src/com/cyanogenmod/explorer/util/DialogHelper.java
index da7c19e2..8375c1d9 100644
--- a/src/com/cyanogenmod/explorer/util/DialogHelper.java
+++ b/src/com/cyanogenmod/explorer/util/DialogHelper.java
@@ -22,13 +22,22 @@ import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListPopupWindow;
+import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.cyanogenmod.explorer.R;
+import com.cyanogenmod.explorer.adapters.CheckableListAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* A helper class with useful methods for deal with dialogs.
@@ -36,6 +45,22 @@ import com.cyanogenmod.explorer.R;
public final class DialogHelper {
/**
+ * An interface to listen the selection make for the user.
+ */
+ public interface OnSelectChoiceListener {
+ /**
+ * Method invoked when the user select an option
+ *
+ * @param choice The selected option
+ */
+ public void onSelectChoice(int choice);
+ /**
+ * Method invoked when the user not select any option
+ */
+ public void onNoSelectChoice();
+ }
+
+ /**
* Constructor of <code>DialogHelper</code>.
*/
private DialogHelper() {
@@ -128,6 +153,72 @@ public final class DialogHelper {
}
/**
+ * Method that creates a new {@link AlertDialog} for choice between single options.
+ *
+ * @param context The current context
+ * @param icon The icon resource
+ * @param title The resource identifier of the title of the alert dialog
+ * @param options An array with the options
+ * @param defOption The default option
+ * @param onSelectChoiceListener The listener for user choice
+ * @return AlertDialog The alert dialog reference
+ */
+ public static AlertDialog createSingleChoiceDialog(
+ Context context, int icon, int title,
+ String[] options, int defOption,
+ final OnSelectChoiceListener onSelectChoiceListener) {
+ //Create the alert dialog
+ final StringBuffer item = new StringBuffer().append(defOption);
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setCustomTitle(createTitle(context, icon, context.getString(title)));
+
+ // Create the adapter
+ List<CheckableListAdapter.CheckableItem> items =
+ new ArrayList<CheckableListAdapter.CheckableItem>(options.length);
+ int cc = options.length;
+ for (int i = 0; i < cc; i++) {
+ boolean checked = (i == defOption);
+ items.add(new CheckableListAdapter.CheckableItem(options[i], true, checked));
+ }
+ final CheckableListAdapter adapter = new CheckableListAdapter(context, items);
+
+ // Create the list view and set as view
+ final ListView listView = new ListView(context);
+ LinearLayout.LayoutParams params =
+ new LinearLayout.LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ listView.setLayoutParams(params);
+ listView.setAdapter(adapter);
+ listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ item.delete(0, item.length());
+ item.append(position);
+ adapter.setSelectedItem(position);
+ }
+ });
+ adapter.setSelectedItem(defOption);
+ listView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
+ builder.setView(listView);
+
+ builder.setNegativeButton(context.getString(R.string.cancel), new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onSelectChoiceListener.onNoSelectChoice();
+ dialog.cancel();
+ }
+ });
+ builder.setPositiveButton(context.getString(R.string.ok), new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onSelectChoiceListener.onSelectChoice(Integer.parseInt(item.toString()));
+ dialog.dismiss();
+ }
+ });
+ return builder.create();
+ }
+
+ /**
* Method that creates a new YES/NO {@link AlertDialog}.
*
* @param context The current context
@@ -380,7 +471,7 @@ public final class DialogHelper {
* @param duration How long to display the message.
*/
public static void showToast(Context context, int msgResourceId, int duration) {
- Toast.makeText(context, msgResourceId, duration).show();
+ showToast(context, context.getString(msgResourceId), duration);
}
}
diff --git a/src/com/cyanogenmod/explorer/util/FileHelper.java b/src/com/cyanogenmod/explorer/util/FileHelper.java
index a377f9fc..dcedcc51 100644
--- a/src/com/cyanogenmod/explorer/util/FileHelper.java
+++ b/src/com/cyanogenmod/explorer/util/FileHelper.java
@@ -258,7 +258,8 @@ public final class FileHelper {
}
// Exceptions to the general extraction method
- for (int i = 0; i < COMPRESSED_TAR.length; i++) {
+ int cc = COMPRESSED_TAR.length;
+ for (int i = 0; i < cc; i++) {
if (name.endsWith("." + COMPRESSED_TAR[i])) { //$NON-NLS-1$
return COMPRESSED_TAR[i];
}
@@ -468,7 +469,8 @@ public final class FileHelper {
ExplorerSettings showSymlinksPref = ExplorerSettings.SETTINGS_SHOW_SYMLINKS;
//Remove all unnecessary files (no required by the user)
- for (int i = files.size() - 1; i >= 0; i--) {
+ int cc = files.size();
+ for (int i = cc - 1; i >= 0; i--) {
FileSystemObject file = files.get(i);
//Hidden files
@@ -652,13 +654,16 @@ public final class FileHelper {
*
* @param ctx The current context
* @param files The list of files of the current directory
- * @param fso The file system object
+ * @param attemptedName The attempted name
+ * @param regexp The resource of the regular expression to create the new name
* @return String The new non-existing name
*/
public static String createNonExistingName(
- final Context ctx, final List<FileSystemObject> files, final FileSystemObject fso) {
+ final Context ctx, final List<FileSystemObject> files,
+ final String attemptedName, int regexp) {
// Find a non-exiting name
- String newName = fso.getName();
+ String newName = attemptedName;
+ if (!isNameExists(files, newName)) return newName;
do {
String name = FileHelper.getName(newName);
String ext = FileHelper.getExtension(newName);
@@ -667,7 +672,7 @@ public final class FileHelper {
} else {
ext = String.format(".%s", ext); //$NON-NLS-1$
}
- newName = ctx.getString(R.string.create_copy_regexp, name, ext);
+ newName = ctx.getString(regexp, name, ext);
} while (isNameExists(files, newName));
return newName;
}
@@ -715,11 +720,44 @@ public final class FileHelper {
return false;
}
String ext = getExtension(fso);
- for (int i = 0; i < VALID.length; i++) {
+ int cc = VALID.length;
+ for (int i = 0; i < cc; i++) {
if (VALID[i].compareTo(ext) == 0) {
return true;
}
}
return false;
}
+
+ /**
+ * Method that converts an absolute path to a relative path
+ *
+ * @param path The absolute path to convert
+ * @param relativeTo The absolute path from which make path relative to (a folder)
+ * @return String The relative path
+ */
+ public static String toRelativePath(String path, String relativeTo) {
+ // Normalize the paths
+ File f1 = new File(path);
+ File f2 = new File(relativeTo);
+ String s1 = f1.getAbsolutePath();
+ String s2 = f2.getAbsolutePath();
+ if (!s2.endsWith(File.separator)) {
+ s2 = s2 + File.separator;
+ }
+
+ // If s2 contains s1 then the relative is replace of the start of the path
+ if (s1.startsWith(s2)) {
+ return s1.substring(s2.length());
+ }
+
+ StringBuffer relative = new StringBuffer();
+ do {
+ File f3 = new File(s2);
+ relative.append(String.format("..%s", File.separator)); //$NON-NLS-1$
+ s2 = f3.getParent() + File.separator;
+ } while (!s1.startsWith(s2) && !s1.startsWith(new File(s2).getAbsolutePath()));
+ s2 = new File(s2).getAbsolutePath();
+ return relative.toString() + s1.substring(s2.length());
+ }
}
diff --git a/src/com/cyanogenmod/explorer/util/StorageHelper.java b/src/com/cyanogenmod/explorer/util/StorageHelper.java
index cc5321ee..99afcdef 100644
--- a/src/com/cyanogenmod/explorer/util/StorageHelper.java
+++ b/src/com/cyanogenmod/explorer/util/StorageHelper.java
@@ -106,7 +106,8 @@ public final class StorageHelper {
public static boolean isPathInStorageVolume(String path) {
StorageVolume[] volumes =
getStorageVolumes(ExplorerApplication.getInstance().getApplicationContext());
- for (int i = 0; i < volumes.length; i++) {
+ int cc = volumes.length;
+ for (int i = 0; i < cc; i++) {
StorageVolume vol = volumes[i];
if (path.startsWith(vol.getPath())) {
return true;
diff --git a/tests/src/com/cyanogenmod/explorer/commands/shell/CompressCommandTest.java b/tests/src/com/cyanogenmod/explorer/commands/shell/CompressCommandTest.java
index 12d093c6..5dcedc54 100644
--- a/tests/src/com/cyanogenmod/explorer/commands/shell/CompressCommandTest.java
+++ b/tests/src/com/cyanogenmod/explorer/commands/shell/CompressCommandTest.java
@@ -22,7 +22,7 @@ import android.util.Log;
import com.cyanogenmod.explorer.commands.AsyncResultListener;
import com.cyanogenmod.explorer.commands.CompressExecutable;
-import com.cyanogenmod.explorer.commands.shell.CompressCommand.CompressionMode;
+import com.cyanogenmod.explorer.preferences.CompressionMode;
import com.cyanogenmod.explorer.util.CommandHelper;
/**
@@ -81,7 +81,7 @@ public class CompressCommandTest extends AbstractConsoleTest {
*/
@LargeTest
public void testArchiveTAR() throws Exception {
- testArchiveAndCompress(CompressionMode.NONE, TAR_OUTFILE);
+ testArchiveAndCompress(CompressionMode.A_TAR, TAR_OUTFILE);
}
/**
@@ -91,7 +91,7 @@ public class CompressCommandTest extends AbstractConsoleTest {
*/
@LargeTest
public void testArchiveCompressGZIP() throws Exception {
- testArchiveAndCompress(CompressionMode.GZIP, TAR_GZIP_OUTFILE);
+ testArchiveAndCompress(CompressionMode.AC_GZIP, TAR_GZIP_OUTFILE);
}
/**
@@ -101,7 +101,7 @@ public class CompressCommandTest extends AbstractConsoleTest {
*/
@LargeTest
public void testArchiveCompressBZIP() throws Exception {
- testArchiveAndCompress(CompressionMode.BZIP, TAR_BZIP_OUTFILE);
+ testArchiveAndCompress(CompressionMode.AC_BZIP, TAR_BZIP_OUTFILE);
}
/**
@@ -111,7 +111,7 @@ public class CompressCommandTest extends AbstractConsoleTest {
*/
@LargeTest
public void testCompressGZIP() throws Exception {
- testCompress(CompressionMode.GZIP);
+ testCompress(CompressionMode.C_GZIP);
}
/**
@@ -121,7 +121,7 @@ public class CompressCommandTest extends AbstractConsoleTest {
*/
@LargeTest
public void testCompressBZIP() throws Exception {
- testCompress(CompressionMode.BZIP);
+ testCompress(CompressionMode.C_BZIP);
}
/**
diff --git a/tests/src/com/cyanogenmod/explorer/commands/shell/UncompressCommandTest.java b/tests/src/com/cyanogenmod/explorer/commands/shell/UncompressCommandTest.java
index adcf06eb..3517718c 100644
--- a/tests/src/com/cyanogenmod/explorer/commands/shell/UncompressCommandTest.java
+++ b/tests/src/com/cyanogenmod/explorer/commands/shell/UncompressCommandTest.java
@@ -183,7 +183,7 @@ public class UncompressCommandTest extends AbstractConsoleTest {
this.mNormalEnd = false;
cmd =
CommandHelper.uncompress(
- getContext(), src, new AsyncResultListener() {
+ getContext(), src, null, new AsyncResultListener() {
public void onAsyncStart() {
/**NON BLOCK**/
}