Forráskód Böngészése

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 éve
szülő
commit
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();