Merge branch 'master' into develop
authorDavid A. Velasco <dvelasco@solidgear.es>
Wed, 3 Dec 2014 10:31:49 +0000 (11:31 +0100)
committerDavid A. Velasco <dvelasco@solidgear.es>
Wed, 3 Dec 2014 10:31:49 +0000 (11:31 +0100)
18 files changed:
AndroidManifest.xml
README.md
oc_jb_workaround/AndroidManifest.xml
owncloud-android-library
res/layout/files_folder_picker.xml [new file with mode: 0644]
res/layout/files_move.xml [deleted file]
res/values/strings.xml
res/xml/preferences.xml
src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java
src/com/owncloud/android/ui/PreferenceWithLongSummary.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/FileDisplayActivity.java
src/com/owncloud/android/ui/activity/FolderPickerActivity.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/MoveActivity.java [deleted file]
src/com/owncloud/android/ui/activity/Preferences.java
src/com/owncloud/android/ui/activity/UploadPathActivity.java [new file with mode: 0644]
src/com/owncloud/android/ui/fragment/OCFileListFragment.java
src/com/owncloud/android/utils/DisplayUtils.java
src/com/owncloud/android/utils/FileStorageUtils.java

index a5990af..fd92d3d 100644 (file)
@@ -18,8 +18,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  -->
 <manifest package="com.owncloud.android"
-    android:versionCode="10600100"
-    android:versionName="1.6.1" xmlns:android="http://schemas.android.com/apk/res/android">
+    android:versionCode="10600200"
+    android:versionName="1.6.2" xmlns:android="http://schemas.android.com/apk/res/android">
 
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />
                        android:icon="@drawable/copy_link"/>
 
         <activity 
-                       android:name=".ui.activity.MoveActivity"
+                       android:name=".ui.activity.FolderPickerActivity"
+                       android:label="@string/app_name"/>
+
+        <activity 
+                       android:name=".ui.activity.UploadPathActivity"
                        android:label="@string/app_name"/>
         
     </application>
index 45cb4be..dd75d3f 100644 (file)
--- a/README.md
+++ b/README.md
@@ -5,4 +5,4 @@ The app performs file synchronization with an ownCloud server. Other ownCloud fe
 Make sure you read [SETUP.md][1] when you start working on this project.
 
 [0]: https://github.com/owncloud/core
-[1]: https://raw.github.com/owncloud/android/master/SETUP.md
\ No newline at end of file
+[1]: https://github.com/owncloud/android/blob/master/SETUP.md
index ada508c..478e3c4 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.owncloud.android.workaround.accounts"
-    android:versionCode="0100019"
-    android:versionName="1.0.19" >
+    android:versionCode="0100020"
+    android:versionName="1.0.20" >
 
     <uses-sdk
         android:minSdkVersion="16"
index 5bd0d73..8261865 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 5bd0d7387712ce3f53869294761ac4d8537841cd
+Subproject commit 8261865ff24c1bfc05be19ae9364a66dac8f26c3
diff --git a/res/layout/files_folder_picker.xml b/res/layout/files_folder_picker.xml
new file mode 100644 (file)
index 0000000..6db8377
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/background_color"
+    android:orientation="vertical" >
+
+       <FrameLayout 
+               android:layout_width="match_parent"
+               android:layout_height="0dip"
+        android:layout_weight="1"
+               android:id="@+id/fragment_container" />
+       
+       <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:orientation="horizontal" >
+
+        <Button
+            android:id="@+id/folder_picker_btn_cancel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/common_cancel" />
+
+               <Button
+                   android:id="@+id/folder_picker_btn_choose"
+                   android:layout_width="wrap_content"
+                   android:layout_height="wrap_content"
+                   android:layout_weight="1"
+                   android:text="@string/folder_picker_choose_button_text" />
+
+       </LinearLayout>
+
+ </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/files_move.xml b/res/layout/files_move.xml
deleted file mode 100644 (file)
index 491bcd8..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@color/background_color"
-    android:orientation="vertical" >
-
-       <FrameLayout 
-               android:layout_width="match_parent"
-               android:layout_height="0dip"
-        android:layout_weight="1"
-               android:id="@+id/fragment_container" />
-       
-       <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:orientation="horizontal" >
-
-        <Button
-            android:id="@+id/move_files_btn_cancel"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/common_cancel" />
-
-               <Button
-                   android:id="@+id/move_files_btn_choose"
-                   android:layout_width="wrap_content"
-                   android:layout_height="wrap_content"
-                   android:layout_weight="1"
-                   android:text="@string/move_choose_button_text" />
-
-       </LinearLayout>
-
- </LinearLayout>
\ No newline at end of file
index de88a5b..8b82868 100644 (file)
        <string name="saml_authentication_wrong_pass">Wrong password</string>
        <string name="actionbar_move">Move</string>
        <string name="file_list_empty_moving">Nothing in here. You can add a folder!</string>
-       <string name="move_choose_button_text">Choose</string>
+       <string name="folder_picker_choose_button_text">Choose</string>
 
        <string name="move_file_not_found">Unable to move. Please check whether the file exists</string>
        <string name="move_file_invalid_into_descendent">It is not possible to move a folder into a descendant</string>
 
        <string name="prefs_category_instant_uploading">Instant Uploads</string>
        <string name="prefs_category_security">Security</string>
+
+       <string name="prefs_instant_video_upload_path_title">Upload Video Path</string>
+
 </resources>
index 3b8b3e8..1673e21 100644 (file)
@@ -32,9 +32,9 @@
        </PreferenceCategory>
 
     <PreferenceCategory android:title="@string/prefs_category_instant_uploading">
-           <EditTextPreference android:title="@string/prefs_instant_upload_path_title"
-                                               android:defaultValue="@string/instant_upload_path"
-                                               android:key="instant_upload_path"/>
+        <com.owncloud.android.ui.PreferenceWithLongSummary
+                                                       android:title="@string/prefs_instant_upload_path_title"
+                                                       android:key="instant_upload_path" />
            <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:key="instant_uploading"
                                android:title="@string/prefs_instant_upload"
                                android:summary="@string/prefs_instant_upload_summary"/>
@@ -42,6 +42,9 @@
                                                android:disableDependentsState="true"
                                                android:title="@string/instant_upload_on_wifi"
                                                android:key="instant_upload_on_wifi"/>
+           <com.owncloud.android.ui.PreferenceWithLongSummary
+                                                       android:title="@string/prefs_instant_video_upload_path_title"
+                                                       android:key="instant_video_upload_path" />
            <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:key="instant_video_uploading"
                                android:title="@string/prefs_instant_video_upload"
                                android:summary="@string/prefs_instant_video_upload_summary"/>
index efaa803..c1c3e9c 100644 (file)
@@ -161,7 +161,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         Intent i = new Intent(context, FileUploader.class);
         i.putExtra(FileUploader.KEY_ACCOUNT, account);
         i.putExtra(FileUploader.KEY_LOCAL_FILE, file_path);
-        i.putExtra(FileUploader.KEY_REMOTE_FILE, FileStorageUtils.getInstantUploadFilePath(context, file_name));
+        i.putExtra(FileUploader.KEY_REMOTE_FILE, FileStorageUtils.getInstantVideoUploadFilePath(context, file_name));
         i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
         i.putExtra(FileUploader.KEY_MIME_TYPE, mime_type);
         i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true);
diff --git a/src/com/owncloud/android/ui/PreferenceWithLongSummary.java b/src/com/owncloud/android/ui/PreferenceWithLongSummary.java
new file mode 100644 (file)
index 0000000..e38d29a
--- /dev/null
@@ -0,0 +1,48 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2014 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package com.owncloud.android.ui;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+import android.preference.Preference;
+
+public class PreferenceWithLongSummary extends Preference{
+
+    public PreferenceWithLongSummary(Context context) {
+        super(context);
+    }
+
+    public PreferenceWithLongSummary(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+    public PreferenceWithLongSummary(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+        TextView titleView = (TextView) view.findViewById(android.R.id.summary);
+        titleView.setSingleLine(true);
+        titleView.setMaxLines(1);
+        titleView.setEllipsize(TextUtils.TruncateAt.MIDDLE);
+    }
+}
\ No newline at end of file
index 49259e9..762cb99 100644 (file)
@@ -615,8 +615,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         } else if (requestCode == ACTION_SELECT_MULTIPLE_FILES && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
             requestMultipleUpload(data, resultCode);
 
-        } else if (requestCode == ACTION_MOVE_FILES && (resultCode == RESULT_OK || 
-                resultCode == MoveActivity.RESULT_OK_AND_MOVE)){
+        } else if (requestCode == ACTION_MOVE_FILES && resultCode == RESULT_OK){
 
             final Intent fData = data;
             final int fResultCode = resultCode; 
@@ -744,8 +743,8 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
      * @param resultCode        Result code received
      */
     private void requestMoveOperation(Intent data, int resultCode) {
-        OCFile folderToMoveAt = (OCFile) data.getParcelableExtra(MoveActivity.EXTRA_CURRENT_FOLDER);
-        OCFile targetFile = (OCFile) data.getParcelableExtra(MoveActivity.EXTRA_TARGET_FILE);
+        OCFile folderToMoveAt = (OCFile) data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER);
+        OCFile targetFile = (OCFile) data.getParcelableExtra(FolderPickerActivity.EXTRA_FILE);
         getFileOperationsHelper().moveFile(folderToMoveAt, targetFile);
     }
 
diff --git a/src/com/owncloud/android/ui/activity/FolderPickerActivity.java b/src/com/owncloud/android/ui/activity/FolderPickerActivity.java
new file mode 100644 (file)
index 0000000..07c9213
--- /dev/null
@@ -0,0 +1,584 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2012-2014 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package com.owncloud.android.ui.activity;
+
+import java.io.IOException;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources.NotFoundException;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+import com.actionbarsherlock.app.ActionBar;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
+import com.actionbarsherlock.view.MenuItem;
+import com.actionbarsherlock.view.Window;
+import com.owncloud.android.R;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.lib.common.OwnCloudAccount;
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
+import com.owncloud.android.lib.common.OwnCloudCredentials;
+import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
+import com.owncloud.android.lib.common.operations.RemoteOperation;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.operations.CreateFolderOperation;
+import com.owncloud.android.operations.SynchronizeFolderOperation;
+import com.owncloud.android.syncadapter.FileSyncAdapter;
+import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
+import com.owncloud.android.ui.fragment.FileFragment;
+import com.owncloud.android.ui.fragment.OCFileListFragment;
+import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ErrorMessageAdapter;
+
+public class FolderPickerActivity extends FileActivity implements FileFragment.ContainerActivity, 
+    OnClickListener, OnEnforceableRefreshListener {
+
+    public static final String EXTRA_FOLDER = UploadFilesActivity.class.getCanonicalName()
+                                                            + ".EXTRA_FOLDER";
+    public static final String EXTRA_FILE = UploadFilesActivity.class.getCanonicalName()
+                                                            + ".EXTRA_FILE";
+    //TODO: Think something better
+
+    private SyncBroadcastReceiver mSyncBroadcastReceiver;
+
+    private static final String TAG = FolderPickerActivity.class.getSimpleName();
+    
+    private static final String TAG_LIST_OF_FOLDERS = "LIST_OF_FOLDERS";
+       
+    private boolean mSyncInProgress = false;
+
+    protected Button mCancelBtn;
+    protected Button mChooseBtn;
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        Log_OC.d(TAG, "onCreate() start");
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+
+        super.onCreate(savedInstanceState); 
+
+        setContentView(R.layout.files_folder_picker);
+        
+        if (savedInstanceState == null) {
+            createFragments();
+        }
+
+        // sets callback listeners for UI elements
+        initControls();
+
+        // Action bar setup
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setDisplayShowTitleEnabled(true);
+        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+        setSupportProgressBarIndeterminateVisibility(mSyncInProgress);
+            // always AFTER setContentView(...) ; to work around bug in its implementation
+        
+        // sets message for empty list of folders
+        setBackgroundText();
+
+        Log_OC.d(TAG, "onCreate() end");
+        
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        getSupportActionBar().setIcon(DisplayUtils.getSeasonalIconId());
+    }
+
+    /**
+     *  Called when the ownCloud {@link Account} associated to the Activity was just updated.
+     */
+    @Override
+    protected void onAccountSet(boolean stateWasRecovered) {
+        super.onAccountSet(stateWasRecovered);
+        if (getAccount() != null) {
+            
+            updateFileFromDB();
+            
+            OCFile folder = getFile();
+            if (folder == null || !folder.isFolder()) {
+                // fall back to root folder
+                setFile(getStorageManager().getFileByPath(OCFile.ROOT_PATH));
+                folder = getFile();
+            }
+            
+            if (!stateWasRecovered) {
+                OCFileListFragment listOfFolders = getListOfFilesFragment(); 
+                listOfFolders.listDirectory(folder);   
+                
+                startSyncFolderOperation(folder, false);
+            }
+            
+            updateNavigationElementsInActionBar();
+        }
+    }
+
+    private void createFragments() {
+        OCFileListFragment listOfFiles = new OCFileListFragment();
+        Bundle args = new Bundle();
+        args.putBoolean(OCFileListFragment.ARG_JUST_FOLDERS, true);
+        args.putBoolean(OCFileListFragment.ARG_ALLOW_CONTEXTUAL_ACTIONS, false);
+        listOfFiles.setArguments(args);
+        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+        transaction.add(R.id.fragment_container, listOfFiles, TAG_LIST_OF_FOLDERS);
+        transaction.commit();
+    }
+
+    /**
+     * Show a text message on screen view for notifying user if content is
+     * loading or folder is empty
+     */
+    private void setBackgroundText() {
+        OCFileListFragment listFragment = getListOfFilesFragment();
+        if (listFragment != null) {
+            int message = R.string.file_list_loading;
+            if (!mSyncInProgress) {
+                // In case folder list is empty
+                message = R.string.file_list_empty_moving;
+            }
+            listFragment.setMessageForEmptyList(getString(message));
+        } else {
+            Log.e(TAG, "OCFileListFragment is null");
+        }
+    }
+
+    protected OCFileListFragment getListOfFilesFragment() {
+        Fragment listOfFiles = getSupportFragmentManager().findFragmentByTag(FolderPickerActivity.TAG_LIST_OF_FOLDERS);
+        if (listOfFiles != null) {
+            return (OCFileListFragment)listOfFiles;
+        }
+        Log_OC.wtf(TAG, "Access to unexisting list of files fragment!!");
+        return null;
+    }
+
+    
+    /**
+     * {@inheritDoc}
+     * 
+     * Updates action bar and second fragment, if in dual pane mode.
+     */
+    @Override
+    public void onBrowsedDownTo(OCFile directory) {
+        setFile(directory);
+        updateNavigationElementsInActionBar();
+        // Sync Folder
+        startSyncFolderOperation(directory, false);
+        
+    }
+
+    
+    public void startSyncFolderOperation(OCFile folder, boolean ignoreETag) {
+        long currentSyncTime = System.currentTimeMillis(); 
+        
+        mSyncInProgress = true;
+                
+        // perform folder synchronization
+        RemoteOperation synchFolderOp = new SynchronizeFolderOperation( folder,  
+                                                                        currentSyncTime, 
+                                                                        false,
+                                                                        getFileOperationsHelper().isSharedSupported(),
+                                                                        ignoreETag,
+                                                                        getStorageManager(), 
+                                                                        getAccount(), 
+                                                                        getApplicationContext()
+                                                                      );
+        synchFolderOp.execute(getAccount(), this, null, null);
+        
+        setSupportProgressBarIndeterminateVisibility(true);
+
+        setBackgroundText();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Log_OC.e(TAG, "onResume() start");
+        
+        // refresh list of files
+        refreshListOfFilesFragment();
+
+        // Listen for sync messages
+        IntentFilter syncIntentFilter = new IntentFilter(FileSyncAdapter.EVENT_FULL_SYNC_START);
+        syncIntentFilter.addAction(FileSyncAdapter.EVENT_FULL_SYNC_END);
+        syncIntentFilter.addAction(FileSyncAdapter.EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED);
+        syncIntentFilter.addAction(SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED);
+        syncIntentFilter.addAction(SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED);
+        mSyncBroadcastReceiver = new SyncBroadcastReceiver();
+        registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
+        
+        Log_OC.d(TAG, "onResume() end");
+    }
+    
+    @Override
+    protected void onPause() {
+        Log_OC.e(TAG, "onPause() start");
+        if (mSyncBroadcastReceiver != null) {
+            unregisterReceiver(mSyncBroadcastReceiver);
+            //LocalBroadcastManager.getInstance(this).unregisterReceiver(mSyncBroadcastReceiver);
+            mSyncBroadcastReceiver = null;
+        }
+        
+        Log_OC.d(TAG, "onPause() end");
+        super.onPause();
+    }
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getSherlock().getMenuInflater();
+        inflater.inflate(R.menu.main_menu, menu);
+        menu.findItem(R.id.action_upload).setVisible(false);
+        menu.findItem(R.id.action_settings).setVisible(false);
+        menu.findItem(R.id.action_sync_account).setVisible(false);
+        menu.findItem(R.id.action_logger).setVisible(false);
+        menu.findItem(R.id.action_sort).setVisible(false);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        boolean retval = true;
+        switch (item.getItemId()) {
+        case R.id.action_create_dir: {
+            CreateFolderDialogFragment dialog = 
+                    CreateFolderDialogFragment.newInstance(getCurrentFolder());
+            dialog.show(
+                    getSupportFragmentManager(), 
+                    CreateFolderDialogFragment.CREATE_FOLDER_FRAGMENT
+            );
+            break;
+        }
+        case android.R.id.home: {
+            OCFile currentDir = getCurrentFolder();
+            if(currentDir != null && currentDir.getParentId() != 0) {
+                onBackPressed();
+            }
+            break;
+        }
+        default:
+            retval = super.onOptionsItemSelected(item);
+        }
+        return retval;
+    }
+
+    protected OCFile getCurrentFolder() {
+        OCFile file = getFile();
+        if (file != null) {
+            if (file.isFolder()) {
+                return file;
+            } else if (getStorageManager() != null) {
+                String parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName()));
+                return getStorageManager().getFileByPath(parentPath);
+            }
+        }
+        return null;
+    }
+    
+    protected void refreshListOfFilesFragment() {
+        OCFileListFragment fileListFragment = getListOfFilesFragment();
+        if (fileListFragment != null) { 
+            fileListFragment.listDirectory();
+        }
+    }
+
+    public void browseToRoot() {
+        OCFileListFragment listOfFiles = getListOfFilesFragment(); 
+        if (listOfFiles != null) {  // should never be null, indeed
+            OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
+            listOfFiles.listDirectory(root);
+            setFile(listOfFiles.getCurrentFile());
+            updateNavigationElementsInActionBar();
+            startSyncFolderOperation(root, false);
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        OCFileListFragment listOfFiles = getListOfFilesFragment();
+        if (listOfFiles != null) {  // should never be null, indeed
+            int levelsUp = listOfFiles.onBrowseUp();
+            if (levelsUp == 0) {
+                finish();
+                return;
+            }
+            setFile(listOfFiles.getCurrentFile());
+            updateNavigationElementsInActionBar();
+        }
+    }
+
+    protected void updateNavigationElementsInActionBar() {
+        ActionBar actionBar = getSupportActionBar();
+        OCFile currentDir = getCurrentFolder();
+        boolean atRoot = (currentDir == null || currentDir.getParentId() == 0);
+        actionBar.setDisplayHomeAsUpEnabled(!atRoot);
+        actionBar.setHomeButtonEnabled(!atRoot);
+        actionBar.setTitle(
+            atRoot 
+                ? getString(R.string.default_display_name_for_root_folder) 
+                : currentDir.getFileName()
+        );
+    }
+
+    /**
+     * Set per-view controllers
+     */
+    private void initControls(){
+        mCancelBtn = (Button) findViewById(R.id.folder_picker_btn_cancel);
+        mCancelBtn.setOnClickListener(this);
+        mChooseBtn = (Button) findViewById(R.id.folder_picker_btn_choose);
+        mChooseBtn.setOnClickListener(this);
+    }
+    
+    @Override
+    public void onClick(View v) {
+        if (v == mCancelBtn) {
+            finish();
+        } else if (v == mChooseBtn) {
+            Intent i = getIntent();
+            Parcelable targetFile = i.getParcelableExtra(FolderPickerActivity.EXTRA_FILE);
+
+            Intent data = new Intent();
+            data.putExtra(EXTRA_FOLDER, getCurrentFolder());
+            if (targetFile != null) {
+                data.putExtra(EXTRA_FILE, targetFile);
+            }
+            setResult(RESULT_OK, data);
+            finish();
+        }
+    }
+    
+    
+    @Override
+    public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
+        super.onRemoteOperationFinish(operation, result);
+        
+        if (operation instanceof CreateFolderOperation) {
+            onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
+            
+        }
+    }
+    
+    
+    /**
+     * Updates the view associated to the activity after the finish of an operation trying 
+     * to create a new folder.
+     * 
+     * @param operation     Creation operation performed.
+     * @param result        Result of the creation.
+     */
+    private void onCreateFolderOperationFinish(
+            CreateFolderOperation operation, RemoteOperationResult result
+            ) {
+        
+        if (result.isSuccess()) {
+            dismissLoadingDialog();
+            refreshListOfFilesFragment();
+        } else {
+            dismissLoadingDialog();
+            try {
+                Toast msg = Toast.makeText(FolderPickerActivity.this, 
+                        ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), 
+                        Toast.LENGTH_LONG); 
+                msg.show();
+
+            } catch (NotFoundException e) {
+                Log_OC.e(TAG, "Error while trying to show fail message " , e);
+            }
+        }
+    }
+    
+    
+    
+    private class SyncBroadcastReceiver extends BroadcastReceiver {
+
+        /**
+         * {@link BroadcastReceiver} to enable syncing feedback in UI
+         */
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            try {
+                String event = intent.getAction();
+                Log_OC.d(TAG, "Received broadcast " + event);
+                String accountName = intent.getStringExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME);
+                String synchFolderRemotePath = intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH); 
+                RemoteOperationResult synchResult = (RemoteOperationResult)intent.
+                        getSerializableExtra(FileSyncAdapter.EXTRA_RESULT);
+                boolean sameAccount = (getAccount() != null && 
+                        accountName.equals(getAccount().name) && getStorageManager() != null); 
+    
+                if (sameAccount) {
+                    
+                    if (FileSyncAdapter.EVENT_FULL_SYNC_START.equals(event)) {
+                        mSyncInProgress = true;
+                        
+                    } else {
+                        OCFile currentFile = (getFile() == null) ? null : 
+                            getStorageManager().getFileByPath(getFile().getRemotePath());
+                        OCFile currentDir = (getCurrentFolder() == null) ? null : 
+                            getStorageManager().getFileByPath(getCurrentFolder().getRemotePath());
+    
+                        if (currentDir == null) {
+                            // current folder was removed from the server 
+                            Toast.makeText( FolderPickerActivity.this, 
+                                            String.format(
+                                                    getString(R.string.sync_current_folder_was_removed), 
+                                                    getCurrentFolder().getFileName()), 
+                                            Toast.LENGTH_LONG)
+                                .show();
+                            browseToRoot();
+                            
+                        } else {
+                            if (currentFile == null && !getFile().isFolder()) {
+                                // currently selected file was removed in the server, and now we know it
+                                currentFile = currentDir;
+                            }
+
+                            if (synchFolderRemotePath != null && currentDir.getRemotePath().
+                                    equals(synchFolderRemotePath)) {
+                                OCFileListFragment fileListFragment = getListOfFilesFragment();
+                                if (fileListFragment != null) {
+                                    fileListFragment.listDirectory(currentDir);
+                                }
+                            }
+                            setFile(currentFile);
+                        }
+                        
+                        mSyncInProgress = (!FileSyncAdapter.EVENT_FULL_SYNC_END.equals(event) && 
+                                !SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED.equals(event));
+                                
+                        if (SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED.
+                                    equals(event) &&
+                                /// TODO refactor and make common
+                                synchResult != null && !synchResult.isSuccess() &&  
+                                (synchResult.getCode() == ResultCode.UNAUTHORIZED   || 
+                                    synchResult.isIdPRedirection()                  ||
+                                    (synchResult.isException() && synchResult.getException() 
+                                            instanceof AuthenticatorException))) {
+
+                            OwnCloudClient client = null;
+                            try {
+                                OwnCloudAccount ocAccount = 
+                                        new OwnCloudAccount(getAccount(), context);
+                                client = (OwnCloudClientManagerFactory.getDefaultSingleton().
+                                        removeClientFor(ocAccount));
+                                // TODO get rid of these exceptions
+                            } catch (AccountNotFoundException e) {
+                                e.printStackTrace();
+                            } catch (AuthenticatorException e) {
+                                e.printStackTrace();
+                            } catch (OperationCanceledException e) {
+                                e.printStackTrace();
+                            } catch (IOException e) {
+                                e.printStackTrace();
+                            }
+                            
+                            if (client != null) {
+                                OwnCloudCredentials cred = client.getCredentials();
+                                if (cred != null) {
+                                    AccountManager am = AccountManager.get(context);
+                                    if (cred.authTokenExpires()) {
+                                        am.invalidateAuthToken(
+                                                getAccount().type, 
+                                                cred.getAuthToken()
+                                        );
+                                    } else {
+                                        am.clearPassword(getAccount());
+                                    }
+                                }
+                            }
+                            
+                            requestCredentialsUpdate();
+                            
+                        }
+                    }
+                    removeStickyBroadcast(intent);
+                    Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress);
+                    setSupportProgressBarIndeterminateVisibility(mSyncInProgress /*|| mRefreshSharesInProgress*/);
+
+                    setBackgroundText();
+                        
+                }
+                
+            } catch (RuntimeException e) {
+                // avoid app crashes after changing the serial id of RemoteOperationResult 
+                // in owncloud library with broadcast notifications pending to process
+                removeStickyBroadcast(intent);
+            }
+        }
+    }
+
+    
+
+    /**
+     * Shows the information of the {@link OCFile} received as a 
+     * parameter in the second fragment.
+     * 
+     * @param file          {@link OCFile} whose details will be shown
+     */
+    @Override
+    public void showDetails(OCFile file) {
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onTransferStateChanged(OCFile file, boolean downloading, boolean uploading) {
+            
+    }
+
+    @Override
+    public void onRefresh() {
+        refreshList(true);
+    }
+
+    @Override
+    public void onRefresh(boolean enforced) {
+        refreshList(enforced);
+    }
+
+    private void refreshList(boolean ignoreETag) {
+        OCFileListFragment listOfFiles = getListOfFilesFragment();
+        if (listOfFiles != null) {
+            OCFile folder = listOfFiles.getCurrentFile();
+            if (folder != null) {
+                startSyncFolderOperation(folder, ignoreETag);
+            }
+        }
+    }
+}
diff --git a/src/com/owncloud/android/ui/activity/MoveActivity.java b/src/com/owncloud/android/ui/activity/MoveActivity.java
deleted file mode 100644 (file)
index 8a25470..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package com.owncloud.android.ui.activity;
-
-import java.io.IOException;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources.NotFoundException;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.Toast;
-
-import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.view.Menu;
-import com.actionbarsherlock.view.MenuInflater;
-import com.actionbarsherlock.view.MenuItem;
-import com.actionbarsherlock.view.Window;
-import com.owncloud.android.R;
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.lib.common.OwnCloudAccount;
-import com.owncloud.android.lib.common.OwnCloudClient;
-import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
-import com.owncloud.android.lib.common.OwnCloudCredentials;
-import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
-import com.owncloud.android.lib.common.operations.RemoteOperation;
-import com.owncloud.android.lib.common.operations.RemoteOperationResult;
-import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
-import com.owncloud.android.operations.CreateFolderOperation;
-import com.owncloud.android.operations.SynchronizeFolderOperation;
-import com.owncloud.android.syncadapter.FileSyncAdapter;
-import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
-import com.owncloud.android.ui.fragment.FileFragment;
-import com.owncloud.android.ui.fragment.OCFileListFragment;
-import com.owncloud.android.utils.DisplayUtils;
-import com.owncloud.android.utils.ErrorMessageAdapter;
-import com.owncloud.android.lib.common.utils.Log_OC;
-
-public class MoveActivity extends HookActivity implements FileFragment.ContainerActivity, 
-    OnClickListener, OnEnforceableRefreshListener {
-
-    public static final String EXTRA_CURRENT_FOLDER = UploadFilesActivity.class.getCanonicalName() + ".EXTRA_CURRENT_FOLDER";
-    public static final String EXTRA_TARGET_FILE = UploadFilesActivity.class.getCanonicalName() + "EXTRA_TARGET_FILE";
-
-    public static final int RESULT_OK_AND_MOVE = 1;
-    
-    private SyncBroadcastReceiver mSyncBroadcastReceiver;
-
-    private static final String TAG = MoveActivity.class.getSimpleName();
-    
-    private static final String TAG_LIST_OF_FOLDERS = "LIST_OF_FOLDERS";
-       
-    private boolean mSyncInProgress = false;
-
-    private Button mCancelBtn;
-    private Button mChooseBtn;
-
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        Log_OC.d(TAG, "onCreate() start");
-        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
-
-        super.onCreate(savedInstanceState); 
-
-        setContentView(R.layout.files_move);
-        
-        if (savedInstanceState == null) {
-            createFragments();
-        }
-
-        // sets callback listeners for UI elements
-        initControls();
-
-        // Action bar setup
-        ActionBar actionBar = getSupportActionBar();
-        actionBar.setDisplayShowTitleEnabled(true);
-        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
-        setSupportProgressBarIndeterminateVisibility(mSyncInProgress);
-            // always AFTER setContentView(...) ; to work around bug in its implementation
-        
-        // sets message for empty list of folders
-        setBackgroundText();
-
-        Log_OC.d(TAG, "onCreate() end");
-        
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-        getSupportActionBar().setIcon(DisplayUtils.getSeasonalIconId());
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-    }
-
-    /**
-     *  Called when the ownCloud {@link Account} associated to the Activity was just updated.
-     */
-    @Override
-    protected void onAccountSet(boolean stateWasRecovered) {
-        super.onAccountSet(stateWasRecovered);
-        if (getAccount() != null) {
-            
-            updateFileFromDB();
-            
-            OCFile folder = getFile();
-            if (folder == null || !folder.isFolder()) {
-                // fall back to root folder
-                setFile(getStorageManager().getFileByPath(OCFile.ROOT_PATH));
-                folder = getFile();
-            }
-            
-            if (!stateWasRecovered) {
-                OCFileListFragment listOfFolders = getListOfFilesFragment(); 
-                listOfFolders.listDirectory(folder);   
-                
-                startSyncFolderOperation(folder, false);
-            }
-            
-            updateNavigationElementsInActionBar();
-        }
-    }
-
-    private void createFragments() {
-        OCFileListFragment listOfFiles = new OCFileListFragment();
-        Bundle args = new Bundle();
-        args.putBoolean(OCFileListFragment.ARG_JUST_FOLDERS, true);
-        args.putBoolean(OCFileListFragment.ARG_ALLOW_CONTEXTUAL_ACTIONS, false);
-        listOfFiles.setArguments(args);
-        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-        transaction.add(R.id.fragment_container, listOfFiles, TAG_LIST_OF_FOLDERS);
-        transaction.commit();
-    }
-
-    /**
-     * Show a text message on screen view for notifying user if content is
-     * loading or folder is empty
-     */
-    private void setBackgroundText() {
-        OCFileListFragment listFragment = getListOfFilesFragment();
-        if (listFragment != null) {
-            int message = R.string.file_list_loading;
-            if (!mSyncInProgress) {
-                // In case folder list is empty
-                message = R.string.file_list_empty_moving;
-            }
-            listFragment.setMessageForEmptyList(getString(message));
-        } else {
-            Log.e(TAG, "OCFileListFragment is null");
-        }
-    }
-
-    private OCFileListFragment getListOfFilesFragment() {
-        Fragment listOfFiles = getSupportFragmentManager().findFragmentByTag(MoveActivity.TAG_LIST_OF_FOLDERS);
-        if (listOfFiles != null) {
-            return (OCFileListFragment)listOfFiles;
-        }
-        Log_OC.wtf(TAG, "Access to unexisting list of files fragment!!");
-        return null;
-    }
-
-    
-    /**
-     * {@inheritDoc}
-     * 
-     * Updates action bar and second fragment, if in dual pane mode.
-     */
-    @Override
-    public void onBrowsedDownTo(OCFile directory) {
-        setFile(directory);
-        updateNavigationElementsInActionBar();
-        // Sync Folder
-        startSyncFolderOperation(directory, false);
-        
-    }
-
-    
-    public void startSyncFolderOperation(OCFile folder, boolean ignoreETag) {
-        long currentSyncTime = System.currentTimeMillis(); 
-        
-        mSyncInProgress = true;
-                
-        // perform folder synchronization
-        RemoteOperation synchFolderOp = new SynchronizeFolderOperation( folder,  
-                                                                        currentSyncTime, 
-                                                                        false,
-                                                                        getFileOperationsHelper().isSharedSupported(),
-                                                                        ignoreETag,
-                                                                        getStorageManager(), 
-                                                                        getAccount(), 
-                                                                        getApplicationContext()
-                                                                      );
-        synchFolderOp.execute(getAccount(), this, null, null);
-        
-        setSupportProgressBarIndeterminateVisibility(true);
-
-        setBackgroundText();
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        Log_OC.e(TAG, "onResume() start");
-        
-        // refresh list of files
-        refreshListOfFilesFragment();
-
-        // Listen for sync messages
-        IntentFilter syncIntentFilter = new IntentFilter(FileSyncAdapter.EVENT_FULL_SYNC_START);
-        syncIntentFilter.addAction(FileSyncAdapter.EVENT_FULL_SYNC_END);
-        syncIntentFilter.addAction(FileSyncAdapter.EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED);
-        syncIntentFilter.addAction(SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED);
-        syncIntentFilter.addAction(SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED);
-        mSyncBroadcastReceiver = new SyncBroadcastReceiver();
-        registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
-        
-        Log_OC.d(TAG, "onResume() end");
-    }
-    
-    @Override
-    protected void onPause() {
-        Log_OC.e(TAG, "onPause() start");
-        if (mSyncBroadcastReceiver != null) {
-            unregisterReceiver(mSyncBroadcastReceiver);
-            //LocalBroadcastManager.getInstance(this).unregisterReceiver(mSyncBroadcastReceiver);
-            mSyncBroadcastReceiver = null;
-        }
-        
-        Log_OC.d(TAG, "onPause() end");
-        super.onPause();
-    }
-    
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        MenuInflater inflater = getSherlock().getMenuInflater();
-        inflater.inflate(R.menu.main_menu, menu);
-        menu.findItem(R.id.action_upload).setVisible(false);
-        menu.findItem(R.id.action_settings).setVisible(false);
-        menu.findItem(R.id.action_sync_account).setVisible(false);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        boolean retval = true;
-        switch (item.getItemId()) {
-        case R.id.action_create_dir: {
-            CreateFolderDialogFragment dialog = 
-                    CreateFolderDialogFragment.newInstance(getCurrentFolder());
-            dialog.show(
-                    getSupportFragmentManager(), 
-                    CreateFolderDialogFragment.CREATE_FOLDER_FRAGMENT
-            );
-            break;
-        }
-        case android.R.id.home: {
-            OCFile currentDir = getCurrentFolder();
-            if(currentDir != null && currentDir.getParentId() != 0) {
-                onBackPressed();
-            }
-            break;
-        }
-        default:
-            retval = super.onOptionsItemSelected(item);
-        }
-        return retval;
-    }
-
-    private OCFile getCurrentFolder() {
-        OCFile file = getFile();
-        if (file != null) {
-            if (file.isFolder()) {
-                return file;
-            } else if (getStorageManager() != null) {
-                String parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName()));
-                return getStorageManager().getFileByPath(parentPath);
-            }
-        }
-        return null;
-    }
-    
-    protected void refreshListOfFilesFragment() {
-        OCFileListFragment fileListFragment = getListOfFilesFragment();
-        if (fileListFragment != null) { 
-            fileListFragment.listDirectory();
-        }
-    }
-
-    public void browseToRoot() {
-        OCFileListFragment listOfFiles = getListOfFilesFragment(); 
-        if (listOfFiles != null) {  // should never be null, indeed
-            OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
-            listOfFiles.listDirectory(root);
-            setFile(listOfFiles.getCurrentFile());
-            updateNavigationElementsInActionBar();
-            startSyncFolderOperation(root, false);
-        }
-    }
-
-    @Override
-    public void onBackPressed() {
-        OCFileListFragment listOfFiles = getListOfFilesFragment();
-        if (listOfFiles != null) {  // should never be null, indeed
-            int levelsUp = listOfFiles.onBrowseUp();
-            if (levelsUp == 0) {
-                finish();
-                return;
-            }
-            setFile(listOfFiles.getCurrentFile());
-            updateNavigationElementsInActionBar();
-        }
-    }
-
-    private void updateNavigationElementsInActionBar() {
-        ActionBar actionBar = getSupportActionBar();
-        OCFile currentDir = getCurrentFolder();
-        boolean atRoot = (currentDir == null || currentDir.getParentId() == 0);
-        actionBar.setDisplayHomeAsUpEnabled(!atRoot);
-        actionBar.setHomeButtonEnabled(!atRoot);
-        actionBar.setTitle(
-            atRoot 
-                ? getString(R.string.default_display_name_for_root_folder) 
-                : currentDir.getFileName()
-        );
-    }
-
-    /**
-     * Set per-view controllers
-     */
-    private void initControls(){
-        mCancelBtn = (Button) findViewById(R.id.move_files_btn_cancel);
-        mCancelBtn.setOnClickListener(this);
-        mChooseBtn = (Button) findViewById(R.id.move_files_btn_choose);
-        mChooseBtn.setOnClickListener(this);
-    }
-    
-    @Override
-    public void onClick(View v) {
-        if (v == mCancelBtn) {
-            finish();
-        } else if (v == mChooseBtn) {
-            Intent i = getIntent();
-            OCFile targetFile = (OCFile) i.getParcelableExtra(MoveActivity.EXTRA_TARGET_FILE);
-
-            Intent data = new Intent();
-            data.putExtra(EXTRA_CURRENT_FOLDER, getCurrentFolder());
-            data.putExtra(EXTRA_TARGET_FILE, targetFile);
-            setResult(RESULT_OK_AND_MOVE, data);
-            finish();
-        }
-    }
-    
-    
-    @Override
-    public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
-        super.onRemoteOperationFinish(operation, result);
-        
-        if (operation instanceof CreateFolderOperation) {
-            onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
-            
-        }
-    }
-    
-    
-    /**
-     * Updates the view associated to the activity after the finish of an operation trying 
-     * to create a new folder.
-     * 
-     * @param operation     Creation operation performed.
-     * @param result        Result of the creation.
-     */
-    private void onCreateFolderOperationFinish(
-            CreateFolderOperation operation, RemoteOperationResult result
-            ) {
-        
-        if (result.isSuccess()) {
-            dismissLoadingDialog();
-            refreshListOfFilesFragment();
-        } else {
-            dismissLoadingDialog();
-            try {
-                Toast msg = Toast.makeText(MoveActivity.this, 
-                        ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), 
-                        Toast.LENGTH_LONG); 
-                msg.show();
-
-            } catch (NotFoundException e) {
-                Log_OC.e(TAG, "Error while trying to show fail message " , e);
-            }
-        }
-    }
-    
-    
-    
-    private class SyncBroadcastReceiver extends BroadcastReceiver {
-
-        /**
-         * {@link BroadcastReceiver} to enable syncing feedback in UI
-         */
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            try {
-                String event = intent.getAction();
-                Log_OC.d(TAG, "Received broadcast " + event);
-                String accountName = intent.getStringExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME);
-                String synchFolderRemotePath = intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH); 
-                RemoteOperationResult synchResult = (RemoteOperationResult)intent.getSerializableExtra(FileSyncAdapter.EXTRA_RESULT);
-                boolean sameAccount = (getAccount() != null && accountName.equals(getAccount().name) && getStorageManager() != null); 
-    
-                if (sameAccount) {
-                    
-                    if (FileSyncAdapter.EVENT_FULL_SYNC_START.equals(event)) {
-                        mSyncInProgress = true;
-                        
-                    } else {
-                        OCFile currentFile = (getFile() == null) ? null : getStorageManager().getFileByPath(getFile().getRemotePath());
-                        OCFile currentDir = (getCurrentFolder() == null) ? null : getStorageManager().getFileByPath(getCurrentFolder().getRemotePath());
-    
-                        if (currentDir == null) {
-                            // current folder was removed from the server 
-                            Toast.makeText( MoveActivity.this, 
-                                            String.format(getString(R.string.sync_current_folder_was_removed), getCurrentFolder().getFileName()), 
-                                            Toast.LENGTH_LONG)
-                                .show();
-                            browseToRoot();
-                            
-                        } else {
-                            if (currentFile == null && !getFile().isFolder()) {
-                                // currently selected file was removed in the server, and now we know it
-                                currentFile = currentDir;
-                            }
-
-                            if (synchFolderRemotePath != null && currentDir.getRemotePath().equals(synchFolderRemotePath)) {
-                                OCFileListFragment fileListFragment = getListOfFilesFragment();
-                                if (fileListFragment != null) {
-                                    fileListFragment.listDirectory(currentDir);
-                                }
-                            }
-                            setFile(currentFile);
-                        }
-                        
-                        mSyncInProgress = (!FileSyncAdapter.EVENT_FULL_SYNC_END.equals(event) && !SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED.equals(event));
-                                
-                        if (SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED.
-                                    equals(event) &&
-                                /// TODO refactor and make common
-                                synchResult != null && !synchResult.isSuccess() &&  
-                                (synchResult.getCode() == ResultCode.UNAUTHORIZED   || 
-                                    synchResult.isIdPRedirection()                  ||
-                                    (synchResult.isException() && synchResult.getException() 
-                                            instanceof AuthenticatorException))) {
-
-                            OwnCloudClient client = null;
-                            try {
-                                OwnCloudAccount ocAccount = 
-                                        new OwnCloudAccount(getAccount(), context);
-                                client = (OwnCloudClientManagerFactory.getDefaultSingleton().
-                                        removeClientFor(ocAccount));
-                                // TODO get rid of these exceptions
-                            } catch (AccountNotFoundException e) {
-                                e.printStackTrace();
-                            } catch (AuthenticatorException e) {
-                                e.printStackTrace();
-                            } catch (OperationCanceledException e) {
-                                e.printStackTrace();
-                            } catch (IOException e) {
-                                e.printStackTrace();
-                            }
-                            
-                            if (client != null) {
-                                OwnCloudCredentials cred = client.getCredentials();
-                                if (cred != null) {
-                                    AccountManager am = AccountManager.get(context);
-                                    if (cred.authTokenExpires()) {
-                                        am.invalidateAuthToken(
-                                                getAccount().type, 
-                                                cred.getAuthToken()
-                                        );
-                                    } else {
-                                        am.clearPassword(getAccount());
-                                    }
-                                }
-                            }
-                            
-                            requestCredentialsUpdate();
-                            
-                        }
-                    }
-                    removeStickyBroadcast(intent);
-                    Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress);
-                    setSupportProgressBarIndeterminateVisibility(mSyncInProgress /*|| mRefreshSharesInProgress*/);
-
-                    setBackgroundText();
-                        
-                }
-                
-            } catch (RuntimeException e) {
-                // avoid app crashes after changing the serial id of RemoteOperationResult 
-                // in owncloud library with broadcast notifications pending to process
-                removeStickyBroadcast(intent);
-            }
-        }
-    }
-
-    
-
-    /**
-     * Shows the information of the {@link OCFile} received as a 
-     * parameter in the second fragment.
-     * 
-     * @param file          {@link OCFile} whose details will be shown
-     */
-    @Override
-    public void showDetails(OCFile file) {
-
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onTransferStateChanged(OCFile file, boolean downloading, boolean uploading) {
-            
-    }
-
-    @Override
-    public void onRefresh() {
-        refreshList(true);
-    }
-
-    @Override
-    public void onRefresh(boolean enforced) {
-        refreshList(enforced);
-    }
-
-    private void refreshList(boolean ignoreETag) {
-        OCFileListFragment listOfFiles = getListOfFilesFragment();
-        if (listOfFiles != null) {
-            OCFile folder = listOfFiles.getCurrentFile();
-            if (folder != null) {
-                startSyncFolderOperation(folder, ignoreETag);
-            }
-        }
-    }
-}
index 2033093..f794cf1 100644 (file)
@@ -50,6 +50,7 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AuthenticatorActivity;
+import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.db.DbHandler;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.LongClickableCheckBoxPreference;
@@ -66,6 +67,9 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
     
     private static final String TAG = "OwnCloudPreferences";
 
+    private static final int ACTION_SELECT_UPLOAD_PATH = 1;
+    private static final int ACTION_SELECT_UPLOAD_VIDEO_PATH = 2;
+
     private DbHandler mDbHandler;
     private CheckBoxPreference pCode;
     private Preference pAboutApp;
@@ -75,6 +79,9 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
     private String mAccountName;
     private boolean mShowContextMenu = false;
     private String mUploadPath;
+    private Preference mPrefInstantUploadPath;
+    private Preference mPrefInstantVideoUploadPath;
+    private String mUploadVideoPath;
 
 
     @SuppressWarnings("deprecation")
@@ -89,8 +96,6 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
         actionBar.setDisplayHomeAsUpEnabled(true);
         actionBar.setTitle(R.string.actionbar_settings);
 
-        loadInstantUploadPath();
-
         // Load the accounts category for adding the list of accounts
         mAccountsPrefCategory = (PreferenceCategory) findPreference("accounts_category");
 
@@ -243,15 +248,39 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
             }
         }
 
-        Preference pInstantUploadPathApp = (Preference) findPreference("instant_upload_path");
+        mPrefInstantUploadPath =  findPreference("instant_upload_path");
+        if (mPrefInstantUploadPath != null){
 
-        pInstantUploadPathApp.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
-            @Override
-            public boolean onPreferenceChange(Preference preference, Object newValue) {
-                mUploadPath = updateInstantUploadPath(newValue.toString());
-                return true;
-            }
-        });
+            mPrefInstantUploadPath.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+                    @Override
+                    public boolean onPreferenceClick(Preference preference) {
+                        if (!mUploadPath.endsWith(OCFile.PATH_SEPARATOR)) {
+                            mUploadPath += OCFile.PATH_SEPARATOR;
+                        }
+                        Intent intent = new Intent(Preferences.this, UploadPathActivity.class);
+                        intent.putExtra(UploadPathActivity.KEY_INSTANT_UPLOAD_PATH, mUploadPath);
+                        startActivityForResult(intent, ACTION_SELECT_UPLOAD_PATH);
+                        return true;
+                    }
+                });
+        }
+
+        mPrefInstantVideoUploadPath =  findPreference("instant_video_upload_path");
+        if (mPrefInstantVideoUploadPath != null){
+
+            mPrefInstantVideoUploadPath.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+                    @Override
+                    public boolean onPreferenceClick(Preference preference) {
+                        if (!mUploadVideoPath.endsWith(OCFile.PATH_SEPARATOR)) {
+                            mUploadVideoPath += OCFile.PATH_SEPARATOR;
+                        }
+                        Intent intent = new Intent(Preferences.this, UploadPathActivity.class);
+                        intent.putExtra(UploadPathActivity.KEY_INSTANT_UPLOAD_PATH, mUploadVideoPath);
+                        startActivityForResult(intent, ACTION_SELECT_UPLOAD_VIDEO_PATH);
+                        return true;
+                    }
+                });
+        }
             
         /* About App */
        pAboutApp = (Preference) findPreference("about_app");
@@ -265,11 +294,14 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
                    Log_OC.e(TAG, "Error while showing about dialog", e);
                }
        }
+
+       loadInstantUploadPath();
+       loadInstantUploadVideoPath();
+
     }
 
     @Override
     protected void onPause() {
-        saveInstantUploadPathOnPreferences();
         super.onPause();
     }
 
@@ -371,6 +403,33 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode == ACTION_SELECT_UPLOAD_PATH && resultCode == RESULT_OK){
+
+            OCFile folderToUpload = (OCFile) data.getParcelableExtra(UploadPathActivity.EXTRA_FOLDER);
+
+            mUploadPath = folderToUpload.getRemotePath();
+
+            mUploadPath = DisplayUtils.getPathWithoutLastSlash(mUploadPath);
+
+            // Show the path on summary preference
+            mPrefInstantUploadPath.setSummary(mUploadPath);
+
+            saveInstantUploadPathOnPreferences();
+
+        } else if (requestCode == ACTION_SELECT_UPLOAD_VIDEO_PATH && resultCode == RESULT_OK){
+
+            OCFile folderToUploadVideo = (OCFile) data.getParcelableExtra(UploadPathActivity.EXTRA_FOLDER);
+
+            mUploadVideoPath = folderToUploadVideo.getRemotePath();
+
+            mUploadVideoPath = DisplayUtils.getPathWithoutLastSlash(mUploadVideoPath);
+
+            // Show the video path on summary preference
+            mPrefInstantVideoUploadPath.setSummary(mUploadVideoPath);
+
+            saveInstantUploadVideoPathOnPreferences();
+        }
     }
 
     @Override
@@ -483,37 +542,12 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
     }
 
     /**
-     * Update the upload path checking that it is a correct path
-     * @param uploadPath: path write by user
-     * @return String: uploadPath
-     */
-    private String updateInstantUploadPath(String uploadPath) {
-        String slashString = "/";
-
-        // If slashes are duplicated, replace them for only one slash
-        uploadPath = uploadPath.replaceAll("/+", slashString);
-
-        // Remove last slash from path
-        if (uploadPath.length() > 0 && uploadPath.charAt(uploadPath.length()-1) == slashString.charAt(0)) {
-            uploadPath = uploadPath.substring(0, uploadPath.length()-1);
-        }
-
-        if (uploadPath.isEmpty()) { // Set default instant upload path
-            uploadPath = getString(R.string.instant_upload_path);
-        }else {
-            if (!uploadPath.startsWith(slashString)) { // Add initial slash on path if necessary
-                uploadPath = slashString.concat(uploadPath);
-            }
-        }
-        return uploadPath;
-    }
-
-    /**
      * Load upload path set on preferences
      */
     private void loadInstantUploadPath() {
         SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
         mUploadPath = appPrefs.getString("instant_upload_path", getString(R.string.instant_upload_path));
+        mPrefInstantUploadPath.setSummary(mUploadPath);
     }
 
     /**
@@ -525,4 +559,23 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
         editor.putString("instant_upload_path", mUploadPath);
         editor.commit();
     }
+
+    /**
+     * Load upload video path set on preferences
+     */
+    private void loadInstantUploadVideoPath() {
+        SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+        mUploadVideoPath = appPrefs.getString("instant_video_upload_path", getString(R.string.instant_upload_path));
+        mPrefInstantVideoUploadPath.setSummary(mUploadVideoPath);
+    }
+
+    /**
+     * Save the "Instant Video Upload Path" on preferences
+     */
+    private void saveInstantUploadVideoPathOnPreferences() {
+        SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());        
+        SharedPreferences.Editor editor = appPrefs.edit();
+        editor.putString("instant_video_upload_path", mUploadVideoPath);
+        editor.commit();
+    }
 }
diff --git a/src/com/owncloud/android/ui/activity/UploadPathActivity.java b/src/com/owncloud/android/ui/activity/UploadPathActivity.java
new file mode 100644 (file)
index 0000000..aa3b8aa
--- /dev/null
@@ -0,0 +1,77 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2012-2014 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package com.owncloud.android.ui.activity;
+
+import android.accounts.Account;
+
+import android.os.Bundle;
+import android.view.View.OnClickListener;
+
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.ui.fragment.FileFragment;
+import com.owncloud.android.ui.fragment.OCFileListFragment;
+
+public class UploadPathActivity extends FolderPickerActivity implements FileFragment.ContainerActivity,
+        OnClickListener, OnEnforceableRefreshListener {
+
+    public static final String KEY_INSTANT_UPLOAD_PATH = "INSTANT_UPLOAD_PATH";
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        String instantUploadPath = getIntent().getStringExtra(KEY_INSTANT_UPLOAD_PATH);
+
+        // The caller activity (Preferences) is not a FileActivity, so it has no OCFile, only a path.
+        OCFile folder = new OCFile(instantUploadPath);
+
+        setFile(folder);
+    }
+
+    /**
+     * Called when the ownCloud {@link Account} associated to the Activity was
+     * just updated.
+     */
+    @Override
+    protected void onAccountSet(boolean stateWasRecovered) {
+        super.onAccountSet(stateWasRecovered);
+        if (getAccount() != null) {
+
+            updateFileFromDB();
+
+            OCFile folder = getFile();
+            if (folder == null || !folder.isFolder()) {
+                // fall back to root folder
+                setFile(getStorageManager().getFileByPath(OCFile.ROOT_PATH));
+                folder = getFile();
+            }
+
+            onBrowsedDownTo(folder);
+
+            if (!stateWasRecovered) {
+                OCFileListFragment listOfFolders = getListOfFilesFragment();
+                listOfFolders.listDirectory(folder);
+
+                startSyncFolderOperation(folder, false);
+            }
+
+            updateNavigationElementsInActionBar();
+        }
+    }
+}
index 2a5de38..fd0b1a5 100644 (file)
@@ -40,7 +40,7 @@ import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.FileMenuFilter;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
-import com.owncloud.android.ui.activity.MoveActivity;
+import com.owncloud.android.ui.activity.FolderPickerActivity;
 import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
 import com.owncloud.android.ui.adapter.FileListListAdapter;
 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
@@ -331,10 +331,10 @@ public class OCFileListFragment extends ExtendedListFragment {
                 return true;
             }
             case R.id.action_move: {
-                Intent action = new Intent(getActivity(), MoveActivity.class);
+                Intent action = new Intent(getActivity(), FolderPickerActivity.class);
 
                 // Pass mTargetFile that contains info of selected file/folder
-                action.putExtra(MoveActivity.EXTRA_TARGET_FILE, mTargetFile);
+                action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile);
                 getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
                 return true;
             }
index cad1770..a1afb89 100644 (file)
@@ -33,6 +33,7 @@ import android.text.format.DateUtils;
 \r
 import com.owncloud.android.MainApp;\r
 import com.owncloud.android.R;\r
+import com.owncloud.android.datamodel.OCFile;\r
 \r
 /**\r
  * A helper class for some string operations.\r
@@ -319,4 +320,17 @@ public class DisplayUtils {
         \r
         return dateString.toString().split(",")[0];
     }\r
+\r
+    /**\r
+     * Update the passed path removing the last "/" if it is not the root folder\r
+     * @param path\r
+     */\r
+    public static String getPathWithoutLastSlash(String path) {\r
+\r
+        // Remove last slash from path\r
+        if (path.length() > 1 && path.charAt(path.length()-1) == OCFile.PATH_SEPARATOR.charAt(0)) {\r
+            path = path.substring(0, path.length()-1);\r
+        }\r
+        return path;\r
+    }\r
 }\r
index 3895821..892a1ca 100644 (file)
@@ -81,6 +81,20 @@ public class FileStorageUtils {
         String value = uploadPath + OCFile.PATH_SEPARATOR +  (fileName == null ? "" : fileName);
         return value;
     }
+
+    /**
+     * Gets the composed path when video is or must be stored
+     * @param context
+     * @param fileName: video file name
+     * @return String: video file path composed
+     */
+    public static String getInstantVideoUploadFilePath(Context context, String fileName) {
+        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
+        String uploadVideoPathdef = context.getString(R.string.instant_upload_path);
+        String uploadVideoPath = pref.getString("instant_video_upload_path", uploadVideoPathdef);
+        String value = uploadVideoPath + OCFile.PATH_SEPARATOR +  (fileName == null ? "" : fileName);
+        return value;
+    }
     
     public static String getParentPath(String remotePath) {
         String parentPath = new File(remotePath).getParent();