Răsfoiți Sursa

Give the user a chance to move the files selected for an upload when there is not space enough to copy them into the ownCloud folder

David A. Velasco 12 ani în urmă
părinte
comite
4558866223

+ 2 - 0
res/values/strings.xml

@@ -125,6 +125,8 @@
     <string name="foreign_files_fail">"Some files could not be moved"</string>
     <string name="foreign_files_local_text">"Local: %1$s"</string>
 	<string name="foreign_files_remote_text">"Remote: %1$s"</string>
+
+	<string name="upload_query_move_foreign_files">There is not space enough to copy the selected files into the %1$s folder. Would like to move them into instead? </string>	
     	
 	<string name="use_ssl">Use Secure Connection</string>
     <string name="location_no_provider">ownCloud cannot track your device. Please check your location settings</string>

+ 1 - 1
src/com/owncloud/android/ui/activity/ErrorsWhileCopyingHandlerActivity.java

@@ -233,7 +233,7 @@ public class ErrorsWhileCopyingHandlerActivity  extends SherlockFragmentActivity
          * 
          * In other case, the list of remaining files is still available to retry the movement.
          * 
-         * @result      'True' when the movement was successful.
+         * @param result      'True' when the movement was successful.
          */
         @Override
         protected void onPostExecute(Boolean result) {

+ 11 - 6
src/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -372,16 +372,16 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
      */
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         
-        if (requestCode == ACTION_SELECT_CONTENT_FROM_APPS && resultCode == RESULT_OK) {
-            requestSimpleUpload(data);
+        if (requestCode == ACTION_SELECT_CONTENT_FROM_APPS && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
+            requestSimpleUpload(data, resultCode);
             
-        } else if (requestCode == ACTION_SELECT_MULTIPLE_FILES && resultCode == RESULT_OK) {
-            requestMultipleUpload(data);
+        } else if (requestCode == ACTION_SELECT_MULTIPLE_FILES && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
+            requestMultipleUpload(data, resultCode);
             
         }
     }
 
-    private void requestMultipleUpload(Intent data) {
+    private void requestMultipleUpload(Intent data, int resultCode) {
         String[] filePaths = data.getStringArrayExtra(UploadFilesActivity.EXTRA_CHOSEN_FILES);
         if (filePaths != null) {
             String[] remotePaths = new String[filePaths.length];
@@ -400,6 +400,8 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
             i.putExtra(FileUploader.KEY_LOCAL_FILE, filePaths);
             i.putExtra(FileUploader.KEY_REMOTE_FILE, remotePaths);
             i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);
+            if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
+                i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
             startService(i);
             
         } else {
@@ -411,7 +413,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
     }
 
 
-    private void requestSimpleUpload(Intent data) {
+    private void requestSimpleUpload(Intent data, int resultCode) {
         String filepath = null;
         try {
             Uri selectedImageUri = data.getData();
@@ -451,6 +453,8 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
         i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);
         i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);
         i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
+        if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
+            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
         startService(i);
     }
 
@@ -683,6 +687,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                     if (item == 0) {
                         //if (!mDualPane) { 
                             Intent action = new Intent(FileDisplayActivity.this, UploadFilesActivity.class);
+                            action.putExtra(UploadFilesActivity.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(FileDisplayActivity.this));
                             startActivityForResult(action, ACTION_SELECT_MULTIPLE_FILES);
                         //} else {
                             // TODO create and handle new fragment LocalFileListFragment

+ 132 - 6
src/com/owncloud/android/ui/activity/UploadFilesActivity.java

@@ -20,9 +20,12 @@ package com.owncloud.android.ui.activity;
 
 import java.io.File;
 
+import android.accounts.Account;
 import android.content.Intent;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Environment;
+import android.support.v4.app.DialogFragment;
 import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -35,7 +38,11 @@ import com.actionbarsherlock.app.ActionBar;
 import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
 import com.actionbarsherlock.app.SherlockFragmentActivity;
 import com.actionbarsherlock.view.MenuItem;
+import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
+import com.owncloud.android.ui.fragment.ConfirmationDialogFragment;
 import com.owncloud.android.ui.fragment.LocalFileListFragment;
+import com.owncloud.android.ui.fragment.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
+import com.owncloud.android.utils.FileStorageUtils;
 
 import com.owncloud.android.R;
 
@@ -48,18 +55,25 @@ import com.owncloud.android.R;
  */
 
 public class UploadFilesActivity extends SherlockFragmentActivity implements
-    LocalFileListFragment.ContainerActivity, OnNavigationListener, OnClickListener {
+    LocalFileListFragment.ContainerActivity, OnNavigationListener, OnClickListener, ConfirmationDialogFragmentListener {
     
     private ArrayAdapter<String> mDirectories;
     private File mCurrentDir = null;
     private LocalFileListFragment mFileListFragment;
     private Button mCancelBtn;
     private Button mUploadBtn;
+    private Account mAccount;
+    private DialogFragment mCurrentDialog;
     
-    public static final String EXTRA_DIRECTORY_PATH = "com.owncloud.android.Directory"; 
-    public static final String EXTRA_CHOSEN_FILES = "com.owncloud.android.ChosenFiles";
+    public static final String EXTRA_ACCOUNT = UploadFilesActivity.class.getCanonicalName() + ".EXTRA_ACCOUNT";
+    public static final String EXTRA_CHOSEN_FILES = UploadFilesActivity.class.getCanonicalName() + ".EXTRA_CHOSEN_FILES";
+
+    public static final int RESULT_OK_AND_MOVE = RESULT_FIRST_USER; 
     
+    private static final String KEY_DIRECTORY_PATH = UploadFilesActivity.class.getCanonicalName() + ".KEY_DIRECTORY_PATH";
     private static final String TAG = "UploadFilesActivity";
+    private static final String WAIT_DIALOG_TAG = "WAIT";
+    private static final String QUERY_TO_MOVE_DIALOG_TAG = "QUERY_TO_MOVE";
     
     
     @Override
@@ -68,11 +82,13 @@ public class UploadFilesActivity extends SherlockFragmentActivity implements
         super.onCreate(savedInstanceState);
 
         if(savedInstanceState != null) {
-            mCurrentDir = new File(savedInstanceState.getString(UploadFilesActivity.EXTRA_DIRECTORY_PATH));
+            mCurrentDir = new File(savedInstanceState.getString(UploadFilesActivity.KEY_DIRECTORY_PATH));
         } else {
             mCurrentDir = Environment.getExternalStorageDirectory();
         }
         
+        mAccount = getIntent().getParcelableExtra(EXTRA_ACCOUNT);
+                
         /// USER INTERFACE
             
         // Drop-down navigation 
@@ -102,6 +118,12 @@ public class UploadFilesActivity extends SherlockFragmentActivity implements
         actionBar.setDisplayShowTitleEnabled(false);
         actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
         actionBar.setListNavigationCallbacks(mDirectories, this);
+        
+        // wait dialog
+        if (mCurrentDialog != null) {
+            mCurrentDialog.dismiss();
+            mCurrentDialog = null;
+        }
             
         Log.d(TAG, "onCreate() end");
     }
@@ -161,7 +183,7 @@ public class UploadFilesActivity extends SherlockFragmentActivity implements
         // responsibility of restore is preferred in onCreate() before than in onRestoreInstanceState when there are Fragments involved
         Log.d(TAG, "onSaveInstanceState() start");
         super.onSaveInstanceState(outState);
-        outState.putString(UploadFilesActivity.EXTRA_DIRECTORY_PATH, mCurrentDir.getAbsolutePath());
+        outState.putString(UploadFilesActivity.KEY_DIRECTORY_PATH, mCurrentDir.getAbsolutePath());
         Log.d(TAG, "onSaveInstanceState() end");
     }
 
@@ -246,6 +268,9 @@ public class UploadFilesActivity extends SherlockFragmentActivity implements
 
     /**
      * Performs corresponding action when user presses 'Cancel' or 'Upload' button
+     * 
+     * TODO Make here the real request to the Upload service ; will require to receive the account and 
+     * target folder where the upload must be done in the received intent.
      */
     @Override
     public void onClick(View v) {
@@ -254,11 +279,112 @@ public class UploadFilesActivity extends SherlockFragmentActivity implements
             finish();
             
         } else if (v.getId() == R.id.upload_files_btn_upload) {
+            new CheckAvailableSpaceTask().execute();
+        }
+    }
+
+
+    /**
+     * Asynchronous task checking if there is space enough to copy all the files chosen
+     * to upload into the ownCloud local folder.
+     * 
+     * Maybe an AsyncTask is not strictly necessary, but who really knows.
+     * 
+     * @author David A. Velasco
+     */
+    private class CheckAvailableSpaceTask extends AsyncTask<Void, Void, Boolean> {
+
+        /**
+         * Updates the UI before trying the movement
+         */
+        @Override
+        protected void onPreExecute () {
+            /// progress dialog and disable 'Move' button
+            mCurrentDialog = IndeterminateProgressDialog.newInstance(R.string.wait_a_moment, false);
+            mCurrentDialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG);
+        }
+        
+        
+        /**
+         * Checks the available space
+         * 
+         * @return     'True' if there is space enough.
+         */
+        @Override
+        protected Boolean doInBackground(Void... params) {
+            String[] checkedFilePaths = mFileListFragment.getCheckedFilePaths();
+            long total = 0;
+            for (int i=0; i < checkedFilePaths.length ; i++) {
+                String localPath = checkedFilePaths[i];
+                File localFile = new File(localPath);
+                total += localFile.length();
+            }
+            String savePath = FileStorageUtils.getSavePath(mAccount.name);
+            File saveDir = new File(savePath);
+            return (saveDir.getUsableSpace() >= total);
+        }
+
+        /**
+         * Updates the activity UI after the check of space is done.
+         * 
+         * If there is not space enough. shows a new dialog to query the user if wants to move the files instead
+         * of copy them.
+         * 
+         * @param result        'True' when there is space enough to copy all the selected files.
+         */
+        @Override
+        protected void onPostExecute(Boolean result) {
+            mCurrentDialog.dismiss();
+            mCurrentDialog = null;
+            
+            if (result) {
+                // return the list of selected files (success)
+                Intent data = new Intent();
+                data.putExtra(EXTRA_CHOSEN_FILES, mFileListFragment.getCheckedFilePaths());
+                setResult(RESULT_OK, data);
+                finish();
+                
+            } else {
+                // show a dialog to query the user if wants to move the selected files to the ownCloud folder instead of copying
+                String[] args = {getString(R.string.app_name)};
+                ConfirmationDialogFragment dialog = ConfirmationDialogFragment.newInstance(R.string.upload_query_move_foreign_files, args, R.string.common_yes, -1, R.string.common_no);
+                dialog.setOnConfirmationListener(UploadFilesActivity.this);
+                mCurrentDialog = dialog;
+                mCurrentDialog.show(getSupportFragmentManager(), QUERY_TO_MOVE_DIALOG_TAG);
+            }
+        }
+    }
+
+    @Override
+    public void onConfirmation(String callerTag) {
+        Log.d(TAG, "Positive button in dialog was clicked; dialog tag is " + callerTag);
+        if (callerTag.equals(QUERY_TO_MOVE_DIALOG_TAG)) {
+            // return the list of selected files to the caller activity (success), signaling that they should be moved to the ownCloud folder, instead of copied
             Intent data = new Intent();
             data.putExtra(EXTRA_CHOSEN_FILES, mFileListFragment.getCheckedFilePaths());
-            setResult(RESULT_OK, data);
+            setResult(RESULT_OK_AND_MOVE, data);
             finish();
         }
+        //mCurrentDialog.dismiss();
+        mCurrentDialog = null;
     }
+
+
+    @Override
+    public void onNeutral(String callerTag) {
+        Log.d(TAG, "Phantom neutral button in dialog was clicked; dialog tag is " + callerTag);
+        //mCurrentDialog.dismiss();
+        mCurrentDialog = null;
+    }
+
+
+    @Override
+    public void onCancel(String callerTag) {
+        /// nothing to do; don't finish, let the user change the selection
+        Log.d(TAG, "Negative button in dialog was clicked; dialog tag is " + callerTag);
+        //mCurrentDialog.dismiss();
+        mCurrentDialog = null;
+    }    
+
     
 }

+ 10 - 0
src/com/owncloud/android/ui/fragment/ConfirmationDialogFragment.java

@@ -37,6 +37,16 @@ public class ConfirmationDialogFragment extends SherlockDialogFragment {
     
     private ConfirmationDialogFragmentListener mListener;
     
+    /**
+     * Public factory method to create new ConfirmationDialogFragment instances.
+     * 
+     * @param string_id         Resource id for a message to show in the dialog.
+     * @param arguments         Arguments to complete the message, if it's a format string.
+     * @param posBtn            Resource id for the text of the positive button.
+     * @param neuBtn            Resource id for the text of the neutral button.
+     * @param negBtn            Resource id for the text of the negative button.
+     * @return                  Dialog ready to show.
+     */
     public static ConfirmationDialogFragment newInstance(int string_id, String[] arguments, int posBtn, int neuBtn, int negBtn) {
         ConfirmationDialogFragment frag = new ConfirmationDialogFragment();
         Bundle args = new Bundle();