Browse Source

Merge branch 'share_link__new_share' into setup_additions

David A. Velasco 11 years ago
parent
commit
4db5295f56
24 changed files with 851 additions and 227 deletions
  1. 5 3
      AndroidManifest.xml
  2. 1 1
      owncloud-android-library
  3. 59 0
      res/layout-v11/activity_row.xml
  4. 55 0
      res/layout/activity_row.xml
  5. 5 0
      res/values/strings.xml
  6. 27 0
      src/com/owncloud/android/datamodel/FileDataStorageManager.java
  7. 0 30
      src/com/owncloud/android/files/FileHandler.java
  8. 143 0
      src/com/owncloud/android/files/FileOperationsHelper.java
  9. 129 0
      src/com/owncloud/android/operations/CreateShareOperation.java
  10. 79 0
      src/com/owncloud/android/operations/GetSharesForFileOperation.java
  11. 1 30
      src/com/owncloud/android/operations/GetSharesOperation.java
  12. 8 1
      src/com/owncloud/android/services/OperationsService.java
  13. 2 4
      src/com/owncloud/android/ui/activity/ConflictsResolveActivity.java
  14. 101 48
      src/com/owncloud/android/ui/activity/FileActivity.java
  15. 38 78
      src/com/owncloud/android/ui/activity/FileDisplayActivity.java
  16. 1 1
      src/com/owncloud/android/ui/activity/UploadFilesActivity.java
  17. 151 0
      src/com/owncloud/android/ui/dialog/ActivityChooserDialog.java
  18. 8 3
      src/com/owncloud/android/ui/fragment/FileDetailFragment.java
  19. 2 4
      src/com/owncloud/android/ui/fragment/FileFragment.java
  20. 8 4
      src/com/owncloud/android/ui/fragment/OCFileListFragment.java
  21. 8 14
      src/com/owncloud/android/ui/preview/PreviewImageActivity.java
  22. 6 0
      src/com/owncloud/android/ui/preview/PreviewImageFragment.java
  23. 12 0
      src/com/owncloud/android/ui/preview/PreviewMediaFragment.java
  24. 2 6
      src/com/owncloud/android/ui/preview/PreviewVideoActivity.java

+ 5 - 3
AndroidManifest.xml

@@ -54,7 +54,6 @@
             >
             >
             <intent-filter>
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <action android:name="android.intent.action.MAIN" />
-
                 <category android:name="android.intent.category.LAUNCHER" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
             </intent-filter>
         </activity>
         </activity>
@@ -81,9 +80,12 @@
                 <category android:name="android.intent.category.DEFAULT" >
                 <category android:name="android.intent.category.DEFAULT" >
                 </category>
                 </category>
 
 
-                <data android:mimeType="*/*" >
+                <data android:mimeType="*/*" android:scheme="content">
                 </data>
                 </data>
-            </intent-filter>
+
+                <data android:mimeType="*/*" android:scheme="file">
+                </data>
+                </intent-filter>
         </activity>
         </activity>
         <activity
         <activity
             android:name=".ui.activity.Preferences"
             android:name=".ui.activity.Preferences"

+ 1 - 1
owncloud-android-library

@@ -1 +1 @@
-Subproject commit c2bacf9155cd5501f084681209cf3df92df29156
+Subproject commit d96e31b5e595518dc6365e5b290dba124140dc26

+ 59 - 0
res/layout-v11/activity_row.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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/>.
+-->
+
+<LinearLayout 	xmlns:android="http://schemas.android.com/apk/res/android"
+    			android:id="@+id/list_item"
+				android:layout_width="match_parent"
+				android:layout_height="48dp"
+				android:paddingStart="16dip"
+				android:paddingEnd="16dip"
+				android:paddingRight="16dip"
+				android:paddingLeft="16dip"
+				android:minWidth="196dip"
+				android:background="?android:attr/activatedBackgroundIndicator"
+    			android:orientation="vertical" >
+
+	<LinearLayout
+		android:layout_width="wrap_content"
+		android:layout_height="match_parent"
+		android:duplicateParentState="true" >
+
+		<ImageView
+			android:id="@+id/icon"
+			android:layout_width="40dip"
+			android:layout_height="40dip"
+			android:layout_gravity="center_vertical"
+			android:layout_marginEnd="8dip"
+			android:layout_marginRight="8dip"
+			android:duplicateParentState="true" />
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
+            android:duplicateParentState="true"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:fadingEdge="horizontal" />
+
+    </LinearLayout>
+
+</LinearLayout>

+ 55 - 0
res/layout/activity_row.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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/>.
+-->
+
+<LinearLayout 	xmlns:android="http://schemas.android.com/apk/res/android"
+    			android:id="@+id/list_item"
+				android:layout_width="match_parent"
+				android:layout_height="48dp"
+				android:paddingRight="16dip"
+				android:paddingLeft="16dip"
+				android:minWidth="196dip"
+    			android:orientation="vertical" >
+
+	<LinearLayout
+		android:layout_width="wrap_content"
+		android:layout_height="match_parent"
+		android:duplicateParentState="true" >
+
+		<ImageView
+			android:id="@+id/icon"
+			android:layout_width="40dip"
+			android:layout_height="40dip"
+			android:layout_gravity="center_vertical"
+			android:layout_marginRight="8dip"
+			android:duplicateParentState="true" />
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:duplicateParentState="true"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:fadingEdge="horizontal" />
+
+    </LinearLayout>
+
+</LinearLayout>

+ 5 - 0
res/values/strings.xml

@@ -187,6 +187,7 @@
     <string name="wait_a_moment">Wait a moment</string>
     <string name="wait_a_moment">Wait a moment</string>
     <string name="filedisplay_unexpected_bad_get_content">"Unexpected problem ; please select the file from a different app"</string>
     <string name="filedisplay_unexpected_bad_get_content">"Unexpected problem ; please select the file from a different app"</string>
     <string name="filedisplay_no_file_selected">No file was selected</string>
     <string name="filedisplay_no_file_selected">No file was selected</string>
+    <string name="activity_chooser_title">Send link to &#8230;</string>
     
     
     <string name="oauth_check_onoff">Login with oAuth2</string> 
     <string name="oauth_check_onoff">Login with oAuth2</string> 
     <string name="oauth_login_connection">Connecting to oAuth2 server…</string>    
     <string name="oauth_login_connection">Connecting to oAuth2 server…</string>    
@@ -244,4 +245,8 @@
     <string name="failed_upload_retry_do_nothing_text">do nothing you are not online for instant upload</string>
     <string name="failed_upload_retry_do_nothing_text">do nothing you are not online for instant upload</string>
 	<string name="failed_upload_failure_text">Failure Message: </string>
 	<string name="failed_upload_failure_text">Failure Message: </string>
 	<string name="failed_upload_quota_exceeded_text">Please check your server configuration,maybe your quota is exceeded.</string>
 	<string name="failed_upload_quota_exceeded_text">Please check your server configuration,maybe your quota is exceeded.</string>
+	
+	<string name="share_link_no_support_share_api">Sorry, sharing is not enabled on your server. Please contact your administrator.</string>
+	<string name="share_link_file_no_exist">Unable to share this file or folder. Please, make sure it exists</string>
+	<string name="share_link_file_error">An error occurred while trying to share this file or folder</string>
 </resources>
 </resources>

+ 27 - 0
src/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -29,6 +29,7 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
 import com.owncloud.android.lib.operations.common.OCShare;
 import com.owncloud.android.lib.operations.common.OCShare;
 import com.owncloud.android.lib.operations.common.ShareType;
 import com.owncloud.android.lib.operations.common.ShareType;
+import com.owncloud.android.lib.utils.FileUtils;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.Log_OC;
 import com.owncloud.android.utils.Log_OC;
 
 
@@ -1099,4 +1100,30 @@ public class FileDataStorageManager {
         }
         }
         
         
     } 
     } 
+
+
+    public void saveSharesDB(ArrayList<OCShare> shares) {
+        saveShares(shares);
+
+        ArrayList<OCFile> sharedFiles = new ArrayList<OCFile>();
+
+        for (OCShare share : shares) {
+            // Get the path
+            String path = share.getPath();
+            if (share.isDirectory()) {
+                path = path + FileUtils.PATH_SEPARATOR;
+            }           
+
+            // Update OCFile with data from share: ShareByLink  ¿and publicLink?
+            OCFile file = getFileByPath(path);
+            if (file != null) {
+                if (share.getShareType().equals(ShareType.PUBLIC_LINK)) {
+                    file.setShareByLink(true);
+                    sharedFiles.add(file);
+                }
+            } 
+        }
+        
+        updateSharedFiles(sharedFiles);
+    }
 }
 }

+ 0 - 30
src/com/owncloud/android/files/FileHandler.java

@@ -1,30 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 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.files;
-
-import com.owncloud.android.datamodel.OCFile;
-
-public interface FileHandler {
-
-    /**
-     * TODO
-     */
-    public void openFile(OCFile file);
-
-    
-}

+ 143 - 0
src/com/owncloud/android/files/FileOperationsHelper.java

@@ -0,0 +1,143 @@
+/* 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.files;
+
+import org.apache.http.protocol.HTTP;
+
+import android.accounts.AccountManager;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.v4.app.DialogFragment;
+import android.webkit.MimeTypeMap;
+import android.widget.Toast;
+
+import com.owncloud.android.R;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.lib.accounts.OwnCloudAccount;
+import com.owncloud.android.lib.network.webdav.WebdavUtils;
+import com.owncloud.android.lib.operations.common.ShareType;
+import com.owncloud.android.operations.CreateShareOperation;
+import com.owncloud.android.ui.activity.FileActivity;
+import com.owncloud.android.ui.dialog.ActivityChooserDialog;
+import com.owncloud.android.utils.Log_OC;
+
+/**
+ * 
+ * @author masensio
+ * @author David A. Velasco
+ */
+public class FileOperationsHelper {
+
+    private static final String TAG = FileOperationsHelper.class.getName();
+    
+    private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; 
+
+    
+    public void openFile(OCFile file, FileActivity callerActivity) {
+        if (file != null) {
+            String storagePath = file.getStoragePath();
+            String encodedStoragePath = WebdavUtils.encodePath(storagePath);
+            
+            Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW);
+            intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype());
+            intentForSavedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+            
+            Intent intentForGuessedMimeType = null;
+            if (storagePath.lastIndexOf('.') >= 0) {
+                String guessedMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1));
+                if (guessedMimeType != null && !guessedMimeType.equals(file.getMimetype())) {
+                    intentForGuessedMimeType = new Intent(Intent.ACTION_VIEW);
+                    intentForGuessedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), guessedMimeType);
+                    intentForGuessedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+                }
+            }
+            
+            Intent chooserIntent = null;
+            if (intentForGuessedMimeType != null) {
+                chooserIntent = Intent.createChooser(intentForGuessedMimeType, callerActivity.getString(R.string.actionbar_open_with));
+            } else {
+                chooserIntent = Intent.createChooser(intentForSavedMimeType, callerActivity.getString(R.string.actionbar_open_with));
+            }
+            
+            callerActivity.startActivity(chooserIntent);
+            
+        } else {
+            Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
+        }
+    }
+    
+
+    public void shareFileWithLink(OCFile file, FileActivity callerActivity) {
+        
+        if (isSharedSupported(callerActivity)) {
+            if (file != null) {
+                String link = "https://fake.url";
+                Intent intent = createShareWithLinkIntent(link);
+                String[] packagesToExclude = new String[] { callerActivity.getPackageName() };
+                DialogFragment chooserDialog = ActivityChooserDialog.newInstance(intent, packagesToExclude, file);
+                chooserDialog.show(callerActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
+                
+            } else {
+                Log_OC.wtf(TAG, "Trying to share a NULL OCFile");
+            }
+            
+        } else {
+            // Show a Message
+            Toast t = Toast.makeText(callerActivity, callerActivity.getString(R.string.share_link_no_support_share_api), Toast.LENGTH_LONG);
+            t.show();
+        }
+    }
+    
+    
+    public void shareFileWithLinkToApp(OCFile file, Intent sendIntent, FileActivity callerActivity) {
+        
+        if (file != null) {
+            callerActivity.showLoadingDialog();
+            CreateShareOperation createShare = new CreateShareOperation(file.getRemotePath(), ShareType.PUBLIC_LINK, "", false, "", 1, sendIntent);
+            createShare.execute(callerActivity.getStorageManager(), 
+                                callerActivity, 
+                                callerActivity.getRemoteOperationListener(), 
+                                callerActivity.getHandler(), 
+                                callerActivity);
+            
+        } else {
+            Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
+        }
+    }
+    
+    
+    private Intent createShareWithLinkIntent(String link) {
+        Intent intentToShareLink = new Intent(Intent.ACTION_SEND);
+        intentToShareLink.putExtra(Intent.EXTRA_TEXT, link);
+        intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE);
+        return intentToShareLink; 
+    }
+    
+    
+    /**
+     *  @return 'True' if the server supports the Share API
+     */
+    public boolean isSharedSupported(FileActivity callerActivity) {
+        if (callerActivity.getAccount() != null) {
+            AccountManager accountManager = AccountManager.get(callerActivity);
+            return Boolean.parseBoolean(accountManager.getUserData(callerActivity.getAccount(), OwnCloudAccount.Constants.KEY_SUPPORTS_SHARE_API));
+        }
+        return false;
+    }
+
+}

+ 129 - 0
src/com/owncloud/android/operations/CreateShareOperation.java

@@ -0,0 +1,129 @@
+/* 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.operations;
+
+/**
+ * Creates a new share from a given file
+ * 
+ * @author masensio
+ *
+ */
+
+import android.content.Intent;
+
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.lib.network.OwnCloudClient;
+import com.owncloud.android.lib.operations.common.OCShare;
+import com.owncloud.android.lib.operations.common.RemoteOperationResult;
+import com.owncloud.android.lib.operations.common.ShareType;
+import com.owncloud.android.lib.operations.remote.CreateShareRemoteOperation;
+import com.owncloud.android.lib.utils.FileUtils;
+import com.owncloud.android.operations.common.SyncOperation;
+import com.owncloud.android.utils.Log_OC;
+
+public class CreateShareOperation extends SyncOperation {
+
+    private static final String TAG = CreateShareOperation.class.getSimpleName();
+
+    protected FileDataStorageManager mStorageManager;
+
+    private String mPath;
+    private ShareType mShareType;
+    private String mShareWith;
+    private boolean mPublicUpload;
+    private String mPassword;
+    private int mPermissions;
+    private Intent mSendIntent;
+
+    /**
+     * Constructor
+     * @param path          Full path of the file/folder being shared. Mandatory argument
+     * @param shareType     ‘0’ = user, ‘1’ = group, ‘3’ = Public link. Mandatory argument
+     * @param shareWith     User/group ID with who the file should be shared.  This is mandatory for shareType of 0 or 1
+     * @param publicUpload  If ‘false’ (default) public cannot upload to a public shared folder. 
+     *                      If ‘true’ public can upload to a shared folder. Only available for public link shares
+     * @param password      Password to protect a public link share. Only available for public link shares
+     * @param permissions   1 - Read only – Default for “public” shares
+     *                      2 - Update
+     *                      4 - Create
+     *                      8 - Delete
+     *                      16- Re-share
+     *                      31- All above – Default for “private” shares
+     *                      For user or group shares.
+     *                      To obtain combinations, add the desired values together.  
+     *                      For instance, for “Re-Share”, “delete”, “read”, “update”, add 16+8+2+1 = 27.
+     */
+    public CreateShareOperation(String path, ShareType shareType, String shareWith, boolean publicUpload, 
+            String password, int permissions, Intent sendIntent) {
+
+        mPath = path;
+        mShareType = shareType;
+        mShareWith = shareWith;
+        mPublicUpload = publicUpload;
+        mPassword = password;
+        mPermissions = permissions;
+        mSendIntent = sendIntent;
+    }
+
+    @Override
+    protected RemoteOperationResult run(OwnCloudClient client) {
+        CreateShareRemoteOperation operation = new CreateShareRemoteOperation(mPath, mShareType, mShareWith, mPublicUpload, mPassword, mPermissions);
+        RemoteOperationResult result = operation.execute(client);
+
+        if (result.isSuccess()) {
+
+            if (result.getData().size() > 0) {
+                OCShare share = (OCShare) result.getData().get(0);
+
+                // Update DB with the response
+                if (mPath.endsWith(FileUtils.PATH_SEPARATOR)) {
+                    share.setPath(mPath.substring(0, mPath.length()-1));
+                    share.setIsDirectory(true);
+                    
+                } else {
+                    share.setPath(mPath);
+                    share.setIsDirectory(false);
+                }
+                share.setPermissions(mPermissions);
+                
+                getStorageManager().saveShare(share);
+                
+                // Update OCFile with data from share: ShareByLink  and publicLink
+                OCFile file = getStorageManager().getFileByPath(mPath);
+                if (file!=null) {
+                    mSendIntent.putExtra(Intent.EXTRA_TEXT, share.getShareLink());
+                    file.setPublicLink(share.getShareLink());
+                    file.setShareByLink(true);
+                    getStorageManager().saveFile(file);
+                    Log_OC.d(TAG, "Public Link = " + file.getPublicLink());
+
+                }
+            }
+        }
+
+
+        return result;
+    }
+    
+    
+    public Intent getSendIntent() {
+        return mSendIntent;
+    }
+
+}

+ 79 - 0
src/com/owncloud/android/operations/GetSharesForFileOperation.java

@@ -0,0 +1,79 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2012-2013 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.operations;
+
+import java.util.ArrayList;
+
+import com.owncloud.android.lib.network.OwnCloudClient;
+import com.owncloud.android.lib.operations.common.OCShare;
+import com.owncloud.android.lib.operations.common.RemoteOperationResult;
+import com.owncloud.android.lib.operations.remote.GetSharesForFileRemoteOperation;
+import com.owncloud.android.operations.common.SyncOperation;
+import com.owncloud.android.utils.Log_OC;
+
+/**
+ * Provide a list shares for a specific file.  
+ * 
+ * @author masensio
+ *
+ */
+public class GetSharesForFileOperation extends SyncOperation {
+    
+    private static final String TAG = GetSharesForFileOperation.class.getSimpleName();
+    
+    private String mPath;
+    private boolean mReshares;
+    private boolean mSubfiles;
+
+    /**
+     * Constructor
+     * 
+     * @param path      Path to file or folder
+     * @param reshares  If set to ‘false’ (default), only shares from the current user are returned
+     *                  If set to ‘true’, all shares from the given file are returned
+     * @param subfiles  If set to ‘false’ (default), lists only the folder being shared
+     *                  If set to ‘true’, all shared files within the folder are returned.
+     */
+    public GetSharesForFileOperation(String path, boolean reshares, boolean subfiles) {
+        mPath = path;
+        mReshares = reshares;
+        mSubfiles = subfiles;
+    }
+
+    @Override
+    protected RemoteOperationResult run(OwnCloudClient client) {
+        GetSharesForFileRemoteOperation operation = new GetSharesForFileRemoteOperation(mPath, mReshares, mSubfiles);
+        RemoteOperationResult result = operation.execute(client);
+
+        if (result.isSuccess()) {
+
+            // Update DB with the response
+            Log_OC.d(TAG, "File = " + mPath + " Share list size  " + result.getData().size());
+            ArrayList<OCShare> shares = new ArrayList<OCShare>();
+            for(Object obj: result.getData()) {
+                shares.add((OCShare) obj);
+            }
+
+            getStorageManager().saveSharesDB(shares);
+        }
+
+        return result;
+    }
+
+}

+ 1 - 30
src/com/owncloud/android/operations/GetSharesOperation.java

@@ -19,13 +19,10 @@ package com.owncloud.android.operations;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 
 
-import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.network.OwnCloudClient;
 import com.owncloud.android.lib.network.OwnCloudClient;
 import com.owncloud.android.lib.operations.common.RemoteOperationResult;
 import com.owncloud.android.lib.operations.common.RemoteOperationResult;
 import com.owncloud.android.lib.operations.common.OCShare;
 import com.owncloud.android.lib.operations.common.OCShare;
-import com.owncloud.android.lib.operations.common.ShareType;
 import com.owncloud.android.lib.operations.remote.GetRemoteSharesOperation;
 import com.owncloud.android.lib.operations.remote.GetRemoteSharesOperation;
-import com.owncloud.android.lib.utils.FileUtils;
 import com.owncloud.android.operations.common.SyncOperation;
 import com.owncloud.android.operations.common.SyncOperation;
 import com.owncloud.android.utils.Log_OC;
 import com.owncloud.android.utils.Log_OC;
 
 
@@ -55,36 +52,10 @@ public class GetSharesOperation extends SyncOperation {
                 shares.add((OCShare) obj);
                 shares.add((OCShare) obj);
             }
             }
 
 
-            saveSharesDB(shares);
+            getStorageManager().saveSharesDB(shares);
         }
         }
 
 
         return result;
         return result;
     }
     }
 
 
-    private void saveSharesDB(ArrayList<OCShare> shares) {
-        // Save share file
-        getStorageManager().saveShares(shares);
-
-        ArrayList<OCFile> sharedFiles = new ArrayList<OCFile>();
-
-        for (OCShare share : shares) {
-            // Get the path
-            String path = share.getPath();
-            if (share.isDirectory()) {
-                path = path + FileUtils.PATH_SEPARATOR;
-            }           
-
-            // Update OCFile with data from share: ShareByLink  ¿and publicLink?
-            OCFile file = getStorageManager().getFileByPath(path);
-            if (file != null) {
-                if (share.getShareType().equals(ShareType.PUBLIC_LINK)) {
-                    file.setShareByLink(true);
-                    sharedFiles.add(file);
-                }
-            } 
-        }
-        
-        getStorageManager().updateSharedFiles(sharedFiles);
-    }
-
 }
 }

+ 8 - 1
src/com/owncloud/android/services/OperationsService.java

@@ -228,7 +228,14 @@ public class OperationsService extends Service {
                     Log_OC.e(TAG, "Error while trying to get autorization for " + mLastTarget.mAccount.name, e);
                     Log_OC.e(TAG, "Error while trying to get autorization for " + mLastTarget.mAccount.name, e);
                 }
                 }
                 result = new RemoteOperationResult(e);
                 result = new RemoteOperationResult(e);
-                
+            } catch (Exception e) {
+                if (mLastTarget.mAccount == null) {
+                    Log_OC.e(TAG, "Unexpected error for a NULL account", e);
+                } else {
+                    Log_OC.e(TAG, "Unexpected error for " + mLastTarget.mAccount.name, e);
+                }
+                result = new RemoteOperationResult(e);
+            
             } finally {
             } finally {
                 synchronized(mPendingOperations) {
                 synchronized(mPendingOperations) {
                     mPendingOperations.poll();
                     mPendingOperations.poll();

+ 2 - 4
src/com/owncloud/android/ui/activity/ConflictsResolveActivity.java

@@ -19,7 +19,6 @@
 package com.owncloud.android.ui.activity;
 package com.owncloud.android.ui.activity;
 
 
 import com.actionbarsherlock.app.ActionBar;
 import com.actionbarsherlock.app.ActionBar;
-import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog;
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog;
@@ -77,6 +76,7 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict
 
 
     @Override
     @Override
     protected void onAccountSet(boolean stateWasRecovered) {
     protected void onAccountSet(boolean stateWasRecovered) {
+        super.onAccountSet(stateWasRecovered);
         if (getAccount() != null) {
         if (getAccount() != null) {
             OCFile file = getFile();
             OCFile file = getFile();
             if (getFile() == null) {
             if (getFile() == null) {
@@ -84,8 +84,7 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict
                 finish();
                 finish();
             } else {
             } else {
                 /// Check whether the 'main' OCFile handled by the Activity is contained in the current Account
                 /// Check whether the 'main' OCFile handled by the Activity is contained in the current Account
-                FileDataStorageManager storageManager = new FileDataStorageManager(getAccount(), getContentResolver());
-                file = storageManager.getFileByPath(file.getRemotePath());   // file = null if not in the current Account
+                file = getStorageManager().getFileByPath(file.getRemotePath());   // file = null if not in the current Account
                 if (file != null) {
                 if (file != null) {
                     setFile(file);
                     setFile(file);
                     ConflictsResolveDialog d = ConflictsResolveDialog.newInstance(file.getRemotePath(), this);
                     ConflictsResolveDialog d = ConflictsResolveDialog.newInstance(file.getRemotePath(), this);
@@ -98,7 +97,6 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict
             }
             }
             
             
         } else {
         } else {
-            Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!");
             finish();
             finish();
         }
         }
         
         

+ 101 - 48
src/com/owncloud/android/ui/activity/FileActivity.java

@@ -24,19 +24,27 @@ import android.accounts.AccountManagerCallback;
 import android.accounts.AccountManagerFuture;
 import android.accounts.AccountManagerFuture;
 import android.accounts.OperationCanceledException;
 import android.accounts.OperationCanceledException;
 import android.content.Intent;
 import android.content.Intent;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.Bundle;
-import android.webkit.MimeTypeMap;
+import android.os.Handler;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.widget.Toast;
 
 
 import com.actionbarsherlock.app.SherlockFragmentActivity;
 import com.actionbarsherlock.app.SherlockFragmentActivity;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.FileOperationsHelper;
+import com.owncloud.android.lib.operations.common.OnRemoteOperationListener;
+import com.owncloud.android.lib.operations.common.RemoteOperation;
+import com.owncloud.android.lib.operations.common.RemoteOperationResult;
+import com.owncloud.android.lib.operations.common.RemoteOperationResult.ResultCode;
+import com.owncloud.android.operations.CreateShareOperation;
 
 
-import com.owncloud.android.lib.accounts.OwnCloudAccount;
-import com.owncloud.android.lib.network.webdav.WebdavUtils;
-
+import com.owncloud.android.ui.dialog.LoadingDialog;
 import com.owncloud.android.utils.Log_OC;
 import com.owncloud.android.utils.Log_OC;
 
 
 
 
@@ -45,14 +53,16 @@ import com.owncloud.android.utils.Log_OC;
  * 
  * 
  * @author David A. Velasco
  * @author David A. Velasco
  */
  */
-public abstract class FileActivity extends SherlockFragmentActivity {
+public class FileActivity extends SherlockFragmentActivity implements OnRemoteOperationListener {
 
 
     public static final String EXTRA_FILE = "com.owncloud.android.ui.activity.FILE";
     public static final String EXTRA_FILE = "com.owncloud.android.ui.activity.FILE";
     public static final String EXTRA_ACCOUNT = "com.owncloud.android.ui.activity.ACCOUNT";
     public static final String EXTRA_ACCOUNT = "com.owncloud.android.ui.activity.ACCOUNT";
     public static final String EXTRA_WAITING_TO_PREVIEW = "com.owncloud.android.ui.activity.WAITING_TO_PREVIEW";
     public static final String EXTRA_WAITING_TO_PREVIEW = "com.owncloud.android.ui.activity.WAITING_TO_PREVIEW";
     public static final String EXTRA_FROM_NOTIFICATION= "com.owncloud.android.ui.activity.FROM_NOTIFICATION";
     public static final String EXTRA_FROM_NOTIFICATION= "com.owncloud.android.ui.activity.FROM_NOTIFICATION";
     
     
-    public static final String TAG = FileActivity.class.getSimpleName(); 
+    public static final String TAG = FileActivity.class.getSimpleName();
+    
+    private static final String DIALOG_WAIT_TAG = "DIALOG_WAIT";
     
     
     
     
     /** OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located. */
     /** OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located. */
@@ -73,6 +83,13 @@ public abstract class FileActivity extends SherlockFragmentActivity {
     /** Flag to signal if the activity is launched by a notification */
     /** Flag to signal if the activity is launched by a notification */
     private boolean mFromNotification;
     private boolean mFromNotification;
     
     
+    /** Messages handler associated to the main thread and the life cycle of the activity */
+    private Handler mHandler;
+    
+    /** Access point to the cached database for the current ownCloud {@link Account} */
+    private FileDataStorageManager mStorageManager = null;
+    
+    private FileOperationsHelper mFileOperationsHelper;
 
 
     
     
     /**
     /**
@@ -85,6 +102,8 @@ public abstract class FileActivity extends SherlockFragmentActivity {
     @Override
     @Override
     protected void onCreate(Bundle savedInstanceState) {
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         super.onCreate(savedInstanceState);
+        mHandler = new Handler();
+        mFileOperationsHelper = new FileOperationsHelper();
         Account account;
         Account account;
         if(savedInstanceState != null) {
         if(savedInstanceState != null) {
             account = savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT);
             account = savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT);
@@ -249,17 +268,6 @@ public abstract class FileActivity extends SherlockFragmentActivity {
     }
     }
     
     
     
     
-    /**
-     *  @return 'True' if the server supports the Share API
-     */
-    public boolean isSharedSupported() {
-        if (getAccount() != null) {
-            AccountManager accountManager = AccountManager.get(this);
-            return Boolean.parseBoolean(accountManager.getUserData(getAccount(), OwnCloudAccount.Constants.KEY_SUPPORTS_SHARE_API));
-        }
-        return false;
-    }
-
     /**
     /**
      * Helper class handling a callback from the {@link AccountManager} after the creation of
      * Helper class handling a callback from the {@link AccountManager} after the creation of
      * a new ownCloud {@link Account} finished, successfully or not.
      * a new ownCloud {@link Account} finished, successfully or not.
@@ -307,40 +315,85 @@ public abstract class FileActivity extends SherlockFragmentActivity {
      * 
      * 
      *  Child classes must grant that state depending on the {@link Account} is updated.
      *  Child classes must grant that state depending on the {@link Account} is updated.
      */
      */
-    protected abstract void onAccountSet(boolean stateWasRecovered);
+    protected void onAccountSet(boolean stateWasRecovered) {
+        if (getAccount() != null) {
+            mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver());
+            
+        } else {
+            Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!");
+        }
+    }
+
+
+    public FileDataStorageManager getStorageManager() {
+        return mStorageManager;
+    }
+
+
+    public OnRemoteOperationListener getRemoteOperationListener() {
+        return this;
+    }
+
+
+    public Handler getHandler() {
+        return mHandler;
+    }
     
     
+    public FileOperationsHelper getFileOperationsHelper() {
+        return mFileOperationsHelper;
+    }
     
     
+    /**
+     * 
+     * @param operation     Removal operation performed.
+     * @param result        Result of the removal.
+     */
+    @Override
+    public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
+        Log_OC.d(TAG, "Received result of operation in FileActivity - common behaviour for all the FileActivities ");
+        if (operation instanceof CreateShareOperation) {
+            onCreateShareOperationFinish((CreateShareOperation) operation, result);
+        }
+    }
 
 
-    public void openFile(OCFile file) {
-        if (file != null) {
-            String storagePath = file.getStoragePath();
-            String encodedStoragePath = WebdavUtils.encodePath(storagePath);
-            
-            Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW);
-            intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype());
-            intentForSavedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
-            
-            Intent intentForGuessedMimeType = null;
-            if (storagePath.lastIndexOf('.') >= 0) {
-                String guessedMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1));
-                if (guessedMimeType != null && !guessedMimeType.equals(file.getMimetype())) {
-                    intentForGuessedMimeType = new Intent(Intent.ACTION_VIEW);
-                    intentForGuessedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), guessedMimeType);
-                    intentForGuessedMimeType.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
-                }
-            }
-            
-            Intent chooserIntent = null;
-            if (intentForGuessedMimeType != null) {
-                chooserIntent = Intent.createChooser(intentForGuessedMimeType, getString(R.string.actionbar_open_with));
-            } else {
-                chooserIntent = Intent.createChooser(intentForSavedMimeType, getString(R.string.actionbar_open_with));
-            }
-            
-            startActivity(chooserIntent);
+    private void onCreateShareOperationFinish(CreateShareOperation operation, RemoteOperationResult result) {
+        dismissLoadingDialog();
+        if (result.isSuccess()) {
+            Intent sendIntent = operation.getSendIntent();
+            startActivity(sendIntent);
             
             
-        } else {
-            Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
+        } else if (result.getCode() == ResultCode.FILE_NOT_FOUND)  {        // Error --> SHARE_NOT_FOUND
+                Toast t = Toast.makeText(this, getString(R.string.share_link_file_no_exist), Toast.LENGTH_LONG);
+                t.show();
+        } else {    // Generic error
+            // Show a Message, operation finished without success
+            Toast t = Toast.makeText(this, getString(R.string.share_link_file_error), Toast.LENGTH_LONG);
+            t.show();
+        }
+    }
+    
+    
+    /**
+     * Show loading dialog 
+     */
+    public void showLoadingDialog() {
+        // Construct dialog
+        LoadingDialog loading = new LoadingDialog(getResources().getString(R.string.wait_a_moment));
+        FragmentManager fm = getSupportFragmentManager();
+        FragmentTransaction ft = fm.beginTransaction();
+        loading.show(ft, DIALOG_WAIT_TAG);
+        
+    }
+
+    
+    /**
+     * Dismiss loading dialog
+     */
+    public void dismissLoadingDialog(){
+        Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
+        if (frag != null) {
+            LoadingDialog loading = (LoadingDialog) frag;
+            loading.dismiss();
         }
         }
     }
     }
     
     

+ 38 - 78
src/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -38,12 +38,10 @@ import android.content.res.Resources.NotFoundException;
 import android.database.Cursor;
 import android.database.Cursor;
 import android.net.Uri;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
 import android.preference.PreferenceManager;
 import android.provider.MediaStore;
 import android.provider.MediaStore;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentTransaction;
 import android.support.v4.app.FragmentTransaction;
 import android.support.v4.content.LocalBroadcastManager;
 import android.support.v4.content.LocalBroadcastManager;
 import android.util.Log;
 import android.util.Log;
@@ -61,7 +59,6 @@ import com.actionbarsherlock.view.MenuItem;
 import com.actionbarsherlock.view.Window;
 import com.actionbarsherlock.view.Window;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.R;
-import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileObserverService;
 import com.owncloud.android.files.services.FileObserverService;
@@ -70,11 +67,10 @@ import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.operations.CreateFolderOperation;
 import com.owncloud.android.operations.CreateFolderOperation;
 
 
-import com.owncloud.android.lib.operations.common.OnRemoteOperationListener;
 import com.owncloud.android.lib.operations.common.RemoteOperation;
 import com.owncloud.android.lib.operations.common.RemoteOperation;
 import com.owncloud.android.lib.operations.common.RemoteOperationResult;
 import com.owncloud.android.lib.operations.common.RemoteOperationResult;
 import com.owncloud.android.lib.operations.common.RemoteOperationResult.ResultCode;
 import com.owncloud.android.lib.operations.common.RemoteOperationResult.ResultCode;
-
+import com.owncloud.android.operations.CreateShareOperation;
 import com.owncloud.android.operations.RemoveFileOperation;
 import com.owncloud.android.operations.RemoveFileOperation;
 import com.owncloud.android.operations.RenameFileOperation;
 import com.owncloud.android.operations.RenameFileOperation;
 import com.owncloud.android.operations.SynchronizeFileOperation;
 import com.owncloud.android.operations.SynchronizeFileOperation;
@@ -83,7 +79,6 @@ import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.syncadapter.FileSyncAdapter;
 import com.owncloud.android.syncadapter.FileSyncAdapter;
 import com.owncloud.android.ui.dialog.EditNameDialog;
 import com.owncloud.android.ui.dialog.EditNameDialog;
 import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener;
 import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener;
-import com.owncloud.android.ui.dialog.LoadingDialog;
 import com.owncloud.android.ui.dialog.SslValidatorDialog;
 import com.owncloud.android.ui.dialog.SslValidatorDialog;
 import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener;
 import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener;
 import com.owncloud.android.ui.fragment.FileDetailFragment;
 import com.owncloud.android.ui.fragment.FileDetailFragment;
@@ -104,13 +99,10 @@ import com.owncloud.android.utils.Log_OC;
  */
  */
 
 
 public class FileDisplayActivity extends HookActivity implements
 public class FileDisplayActivity extends HookActivity implements
-OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnSslValidatorListener, OnRemoteOperationListener, EditNameDialogListener {
+OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnSslValidatorListener, EditNameDialogListener {
 
 
     private ArrayAdapter<String> mDirectories;
     private ArrayAdapter<String> mDirectories;
 
 
-    /** Access point to the cached database for the current ownCloud {@link Account} */
-    private FileDataStorageManager mStorageManager = null;
-
     private SyncBroadcastReceiver mSyncBroadcastReceiver;
     private SyncBroadcastReceiver mSyncBroadcastReceiver;
     private UploadFinishReceiver mUploadFinishReceiver;
     private UploadFinishReceiver mUploadFinishReceiver;
     private DownloadFinishReceiver mDownloadFinishReceiver;
     private DownloadFinishReceiver mDownloadFinishReceiver;
@@ -133,8 +125,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
     private static final int DIALOG_SSL_VALIDATOR = 2;
     private static final int DIALOG_SSL_VALIDATOR = 2;
     private static final int DIALOG_CERT_NOT_SAVED = 3;
     private static final int DIALOG_CERT_NOT_SAVED = 3;
     
     
-    private static final String DIALOG_WAIT_TAG = "DIALOG_WAIT";
-
     public static final String ACTION_DETAILS = "com.owncloud.android.ui.activity.action.DETAILS";
     public static final String ACTION_DETAILS = "com.owncloud.android.ui.activity.action.DETAILS";
 
 
     private static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
     private static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
@@ -146,7 +136,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
     private static final String TAG_SECOND_FRAGMENT = "SECOND_FRAGMENT";
     private static final String TAG_SECOND_FRAGMENT = "SECOND_FRAGMENT";
 
 
     private OCFile mWaitingToPreview;
     private OCFile mWaitingToPreview;
-    private Handler mHandler;
     
     
     private boolean mSyncInProgress = false;
     private boolean mSyncInProgress = false;
     private boolean mRefreshSharesInProgress = false;
     private boolean mRefreshSharesInProgress = false;
@@ -158,8 +147,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
 
 
         super.onCreate(savedInstanceState); // this calls onAccountChanged() when ownCloud Account is valid
         super.onCreate(savedInstanceState); // this calls onAccountChanged() when ownCloud Account is valid
 
 
-        mHandler = new Handler();
-        
         /// bindings to transference services
         /// bindings to transference services
         mUploadConnection = new ListServiceConnection(); 
         mUploadConnection = new ListServiceConnection(); 
         mDownloadConnection = new ListServiceConnection();
         mDownloadConnection = new ListServiceConnection();
@@ -230,9 +217,8 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
      */ 
      */ 
     @Override
     @Override
     protected void onAccountSet(boolean stateWasRecovered) {
     protected void onAccountSet(boolean stateWasRecovered) {
+        super.onAccountSet(stateWasRecovered);
         if (getAccount() != null) {
         if (getAccount() != null) {
-            mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver());
-                
             /// Check whether the 'main' OCFile handled by the Activity is contained in the current Account
             /// Check whether the 'main' OCFile handled by the Activity is contained in the current Account
             OCFile file = getFile();
             OCFile file = getFile();
             // get parent from path
             // get parent from path
@@ -242,15 +228,15 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
                     // upload in progress - right now, files are not inserted in the local cache until the upload is successful
                     // upload in progress - right now, files are not inserted in the local cache until the upload is successful
                     // get parent from path
                     // get parent from path
                     parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName()));
                     parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName()));
-                    if (mStorageManager.getFileByPath(parentPath) ==  null)
+                    if (getStorageManager().getFileByPath(parentPath) ==  null)
                         file = null; // not able to know the directory where the file is uploading
                         file = null; // not able to know the directory where the file is uploading
                 } else {
                 } else {
-                    file = mStorageManager.getFileByPath(file.getRemotePath());   // currentDir = null if not in the current Account
+                    file = getStorageManager().getFileByPath(file.getRemotePath());   // currentDir = null if not in the current Account
                 }
                 }
             }
             }
             if (file == null) {
             if (file == null) {
                 // fall back to root folder
                 // fall back to root folder
-                file = mStorageManager.getFileByPath(OCFile.ROOT_PATH);  // never returns null
+                file = getStorageManager().getFileByPath(OCFile.ROOT_PATH);  // never returns null
             }
             }
             setFile(file);
             setFile(file);
             setNavigationListWithFolder(file);
             setNavigationListWithFolder(file);
@@ -266,10 +252,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
                 updateFragmentsVisibility(!file.isFolder());
                 updateFragmentsVisibility(!file.isFolder());
                 updateNavigationElementsInActionBar(file.isFolder() ? null : file);
                 updateNavigationElementsInActionBar(file.isFolder() ? null : file);
             }
             }
-            
-            
-        } else {
-            Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!");
         }
         }
     }
     }
 
 
@@ -282,10 +264,9 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
             if (fileIt.isFolder()) {
             if (fileIt.isFolder()) {
                 mDirectories.add(fileIt.getFileName());
                 mDirectories.add(fileIt.getFileName());
             }
             }
-            //fileIt = mStorageManager.getFileById(fileIt.getParentId());
             // get parent from path
             // get parent from path
             parentPath = fileIt.getRemotePath().substring(0, fileIt.getRemotePath().lastIndexOf(fileIt.getFileName()));
             parentPath = fileIt.getRemotePath().substring(0, fileIt.getRemotePath().lastIndexOf(fileIt.getFileName()));
-            fileIt = mStorageManager.getFileByPath(parentPath);
+            fileIt = getStorageManager().getFileByPath(parentPath);
         }
         }
         mDirectories.add(OCFile.PATH_SEPARATOR);
         mDirectories.add(OCFile.PATH_SEPARATOR);
     }
     }
@@ -447,12 +428,12 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
                 boolean detailsFragmentChanged = false;
                 boolean detailsFragmentChanged = false;
                 if (waitedPreview) {
                 if (waitedPreview) {
                     if (success) {
                     if (success) {
-                        mWaitingToPreview = mStorageManager.getFileById(mWaitingToPreview.getFileId());   // update the file from database, for the local storage path
+                        mWaitingToPreview = getStorageManager().getFileById(mWaitingToPreview.getFileId());   // update the file from database, for the local storage path
                         if (PreviewMediaFragment.canBePreviewed(mWaitingToPreview)) {
                         if (PreviewMediaFragment.canBePreviewed(mWaitingToPreview)) {
                             startMediaPreview(mWaitingToPreview, 0, true);
                             startMediaPreview(mWaitingToPreview, 0, true);
                             detailsFragmentChanged = true;
                             detailsFragmentChanged = true;
                         } else {
                         } else {
-                            openFile(mWaitingToPreview);
+                            getFileOperationsHelper().openFile(mWaitingToPreview, this);
                         }
                         }
                     }
                     }
                     mWaitingToPreview = null;
                     mWaitingToPreview = null;
@@ -464,7 +445,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
         }
         }
     }
     }
 
 
-
     @Override
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getSherlock().getMenuInflater();
         MenuInflater inflater = getSherlock().getMenuInflater();
@@ -543,7 +523,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
                 targetPath = mDirectories.getItem(i) + OCFile.PATH_SEPARATOR + targetPath; 
                 targetPath = mDirectories.getItem(i) + OCFile.PATH_SEPARATOR + targetPath; 
             }
             }
             targetPath = OCFile.PATH_SEPARATOR + targetPath;
             targetPath = OCFile.PATH_SEPARATOR + targetPath;
-            OCFile targetFolder = mStorageManager.getFileByPath(targetPath);
+            OCFile targetFolder = getStorageManager().getFileByPath(targetPath);
             if (targetFolder != null) {
             if (targetFolder != null) {
                 browseTo(targetFolder);
                 browseTo(targetFolder);
             }
             }
@@ -837,30 +817,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
     }
     }
 
 
 
 
-    /**
-     * Show loading dialog 
-     */
-    public void showLoadingDialog() {
-        // Construct dialog
-        LoadingDialog loading = new LoadingDialog(getResources().getString(R.string.wait_a_moment));
-        FragmentManager fm = getSupportFragmentManager();
-        FragmentTransaction ft = fm.beginTransaction();
-        loading.show(ft, DIALOG_WAIT_TAG);
-        
-    }
-    
-    /**
-     * Dismiss loading dialog
-     */
-    public void dismissLoadingDialog(){
-        Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
-      if (frag != null) {
-          LoadingDialog loading = (LoadingDialog) frag;
-            loading.dismiss();
-        }
-    }
-    
-    
     /**
     /**
      * Translates a content URI of an image to a physical path
      * Translates a content URI of an image to a physical path
      * on the disk
      * on the disk
@@ -948,14 +904,13 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
             String accountName = intent.getStringExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME);
             String accountName = intent.getStringExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME);
             String synchFolderRemotePath = intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH); 
             String synchFolderRemotePath = intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH); 
             RemoteOperationResult synchResult = (RemoteOperationResult)intent.getSerializableExtra(FileSyncAdapter.EXTRA_RESULT);
             RemoteOperationResult synchResult = (RemoteOperationResult)intent.getSerializableExtra(FileSyncAdapter.EXTRA_RESULT);
-            boolean sameAccount = (getAccount() != null && accountName.equals(getAccount().name) && mStorageManager != null); 
+            boolean sameAccount = (getAccount() != null && accountName.equals(getAccount().name) && getStorageManager() != null); 
 
 
             if (sameAccount) {
             if (sameAccount) {
                 
                 
                 if (!FileSyncAdapter.EVENT_FULL_SYNC_START.equals(event)) {
                 if (!FileSyncAdapter.EVENT_FULL_SYNC_START.equals(event)) {
-                    
-                    OCFile currentFile = (getFile() == null) ? null : mStorageManager.getFileByPath(getFile().getRemotePath());
-                    OCFile currentDir = (getCurrentDir() == null) ? null : mStorageManager.getFileByPath(getCurrentDir().getRemotePath());
+                    OCFile currentFile = (getFile() == null) ? null : getStorageManager().getFileByPath(getFile().getRemotePath());
+                    OCFile currentDir = (getCurrentDir() == null) ? null : getStorageManager().getFileByPath(getCurrentDir().getRemotePath());
 
 
                     if (currentDir == null) {
                     if (currentDir == null) {
                         // current folder was removed from the server 
                         // current folder was removed from the server 
@@ -989,7 +944,9 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
                         synchResult.isSuccess() &&
                         synchResult.isSuccess() &&
                             (SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_SYNCED.equals(event) || 
                             (SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_SYNCED.equals(event) || 
                                 FileSyncAdapter.EVENT_FOLDER_CONTENTS_SYNCED.equals(event)
                                 FileSyncAdapter.EVENT_FOLDER_CONTENTS_SYNCED.equals(event)
-                            )
+                            ) &&
+                            !mRefreshSharesInProgress &&
+                            getFileOperationsHelper().isSharedSupported(FileDisplayActivity.this)
                         ) {
                         ) {
                         startGetShares();
                         startGetShares();
                     }
                     }
@@ -1084,7 +1041,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
                 Account account = intent.getParcelableExtra(OperationsService.EXTRA_ACCOUNT);
                 Account account = intent.getParcelableExtra(OperationsService.EXTRA_ACCOUNT);
                 RemoteOperationResult getSharesResult = (RemoteOperationResult)intent.getSerializableExtra(OperationsService.EXTRA_RESULT);
                 RemoteOperationResult getSharesResult = (RemoteOperationResult)intent.getSerializableExtra(OperationsService.EXTRA_RESULT);
                 if (getAccount() != null && account.name.equals(getAccount().name)
                 if (getAccount() != null && account.name.equals(getAccount().name)
-                        && mStorageManager != null
+                        && getStorageManager() != null
                         ) {
                         ) {
                     refeshListOfFilesFragment();
                     refeshListOfFilesFragment();
                 }
                 }
@@ -1101,23 +1058,13 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
             
             
     }
     }
 
 
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public FileDataStorageManager getStorageManager() {
-        return mStorageManager;
-    }
-
-
     public void browseToRoot() {
     public void browseToRoot() {
         OCFileListFragment listOfFiles = getListOfFilesFragment(); 
         OCFileListFragment listOfFiles = getListOfFilesFragment(); 
         if (listOfFiles != null) {  // should never be null, indeed
         if (listOfFiles != null) {  // should never be null, indeed
             while (mDirectories.getCount() > 1) {
             while (mDirectories.getCount() > 1) {
                 popDirname();
                 popDirname();
             }
             }
-            OCFile root = mStorageManager.getFileByPath(OCFile.ROOT_PATH);
+            OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
             listOfFiles.listDirectory(root);
             listOfFiles.listDirectory(root);
             setFile(listOfFiles.getCurrentFile());
             setFile(listOfFiles.getCurrentFile());
             startSyncFolderOperation(root);
             startSyncFolderOperation(root);
@@ -1357,6 +1304,8 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
      */
      */
     @Override
     @Override
     public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
     public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
+        super.onRemoteOperationFinish(operation, result);
+        
         if (operation instanceof RemoveFileOperation) {
         if (operation instanceof RemoveFileOperation) {
             onRemoveFileOperationFinish((RemoveFileOperation)operation, result);
             onRemoveFileOperationFinish((RemoveFileOperation)operation, result);
 
 
@@ -1368,10 +1317,21 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
 
 
         } else if (operation instanceof CreateFolderOperation) {
         } else if (operation instanceof CreateFolderOperation) {
             onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
             onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
+        
+        } else if (operation instanceof CreateShareOperation) {
+            onCreateShareOperationFinish((CreateShareOperation) operation, result);
         }
         }
+        
     }
     }
 
 
 
 
+    private void onCreateShareOperationFinish(CreateShareOperation operation, RemoteOperationResult result) {
+        if (result.isSuccess()) {
+            refeshListOfFilesFragment();
+        }
+    }
+
+    
     /**
     /**
      * Updates the view associated to the activity after the finish of an operation trying to remove a 
      * Updates the view associated to the activity after the finish of an operation trying to remove a 
      * file. 
      * file. 
@@ -1390,7 +1350,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
             if (second != null && removedFile.equals(second.getFile())) {
             if (second != null && removedFile.equals(second.getFile())) {
                 cleanSecondFragment();
                 cleanSecondFragment();
             }
             }
-            if (mStorageManager.getFileById(removedFile.getParentId()).equals(getCurrentDir())) {
+            if (getStorageManager().getFileById(removedFile.getParentId()).equals(getCurrentDir())) {
                 refeshListOfFilesFragment();
                 refeshListOfFilesFragment();
             }
             }
 
 
@@ -1449,7 +1409,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
                     ((FileDetailFragment) details).updateFileDetails(renamedFile, getAccount());
                     ((FileDetailFragment) details).updateFileDetails(renamedFile, getAccount());
                 }
                 }
             }
             }
-            if (mStorageManager.getFileById(renamedFile.getParentId()).equals(getCurrentDir())) {
+            if (getStorageManager().getFileById(renamedFile.getParentId()).equals(getCurrentDir())) {
                 refeshListOfFilesFragment();
                 refeshListOfFilesFragment();
             }
             }
 
 
@@ -1525,11 +1485,11 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
 
 
                 // Create directory
                 // Create directory
                 path += newDirectoryName + OCFile.PATH_SEPARATOR;
                 path += newDirectoryName + OCFile.PATH_SEPARATOR;
-                RemoteOperation operation = new CreateFolderOperation(path, false, mStorageManager);
+                RemoteOperation operation = new CreateFolderOperation(path, false, getStorageManager());
                 operation.execute(  getAccount(), 
                 operation.execute(  getAccount(), 
                         FileDisplayActivity.this, 
                         FileDisplayActivity.this, 
                         FileDisplayActivity.this, 
                         FileDisplayActivity.this, 
-                        mHandler,
+                        getHandler(),
                         FileDisplayActivity.this);
                         FileDisplayActivity.this);
 
 
                 showLoadingDialog();
                 showLoadingDialog();
@@ -1554,9 +1514,9 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
         if (file != null) {
         if (file != null) {
             if (file.isFolder()) {
             if (file.isFolder()) {
                 return file;
                 return file;
-            } else if (mStorageManager != null) {
+            } else if (getStorageManager() != null) {
                 String parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName()));
                 String parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName()));
-                return mStorageManager.getFileByPath(parentPath);
+                return getStorageManager().getFileByPath(parentPath);
             }
             }
         }
         }
         return null;
         return null;
@@ -1589,5 +1549,5 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
         
         
         mRefreshSharesInProgress = true;
         mRefreshSharesInProgress = true;
     }
     }
-    
+
 }
 }

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

@@ -380,6 +380,7 @@ public class UploadFilesActivity extends FileActivity implements
 
 
     @Override
     @Override
     protected void onAccountSet(boolean stateWasRecovered) {
     protected void onAccountSet(boolean stateWasRecovered) {
+        super.onAccountSet(stateWasRecovered);
         if (getAccount() != null) {
         if (getAccount() != null) {
             if (!mAccountOnCreation.equals(getAccount())) {
             if (!mAccountOnCreation.equals(getAccount())) {
                 setResult(RESULT_CANCELED);
                 setResult(RESULT_CANCELED);
@@ -387,7 +388,6 @@ public class UploadFilesActivity extends FileActivity implements
             }
             }
             
             
         } else {
         } else {
-            Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!");
             setResult(RESULT_CANCELED);
             setResult(RESULT_CANCELED);
             finish();
             finish();
         }
         }

+ 151 - 0
src/com/owncloud/android/ui/dialog/ActivityChooserDialog.java

@@ -0,0 +1,151 @@
+/* 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.dialog;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.actionbarsherlock.app.SherlockDialogFragment;
+import com.owncloud.android.R;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.FileOperationsHelper;
+import com.owncloud.android.ui.activity.FileActivity;
+import com.owncloud.android.utils.Log_OC;
+
+/**
+ * Dialog showing a list activities able to resolve a given Intent, 
+ * filtering out the activities matching give package names.
+ * 
+ * @author David A. Velasco
+ */
+public class ActivityChooserDialog  extends SherlockDialogFragment {
+    
+    private final static String TAG =  ActivityChooserDialog.class.getSimpleName();
+    private final static String ARG_INTENT =  ActivityChooserDialog.class.getSimpleName() + ".ARG_INTENT";
+    private final static String ARG_PACKAGES_TO_EXCLUDE =  ActivityChooserDialog.class.getSimpleName() + ".ARG_PACKAGES_TO_EXCLUDE";
+    private final static String ARG_FILE_TO_SHARE = ActivityChooserDialog.class.getSimpleName() + ".FILE_TO_SHARE";
+    
+    private ActivityAdapter mAdapter;
+    private OCFile mFile;
+    private Intent mIntent;
+    
+    public static ActivityChooserDialog newInstance(Intent intent, String[] packagesToExclude, OCFile fileToShare) {
+        ActivityChooserDialog f = new ActivityChooserDialog();
+        Bundle args = new Bundle();
+        args.putParcelable(ARG_INTENT, intent);
+        args.putStringArray(ARG_PACKAGES_TO_EXCLUDE, packagesToExclude);
+        args.putParcelable(ARG_FILE_TO_SHARE, fileToShare);
+        f.setArguments(args);
+        return f;
+    }
+    
+    public ActivityChooserDialog() {
+        super();
+        Log_OC.d(TAG, "constructor");
+    }
+    
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        mIntent = getArguments().getParcelable(ARG_INTENT);
+        String[] packagesToExclude = getArguments().getStringArray(ARG_PACKAGES_TO_EXCLUDE);
+        List<String> packagesToExcludeList = Arrays.asList(packagesToExclude != null ? packagesToExclude : new String[0]);
+        mFile = getArguments().getParcelable(ARG_FILE_TO_SHARE);
+        
+        PackageManager pm= getSherlockActivity().getPackageManager();
+        List<ResolveInfo> activities = pm.queryIntentActivities(mIntent, PackageManager.MATCH_DEFAULT_ONLY);
+        Iterator<ResolveInfo> it = activities.iterator();
+        ResolveInfo resolveInfo;
+        while (it.hasNext()) {
+            resolveInfo = it.next();
+            if (packagesToExcludeList.contains(resolveInfo.activityInfo.packageName.toLowerCase())) {
+                it.remove();
+            }
+        }
+        Collections.sort(activities, new ResolveInfo.DisplayNameComparator(pm)); 
+        mAdapter = new ActivityAdapter(getSherlockActivity(), pm, activities);
+        
+        return new AlertDialog.Builder(getSherlockActivity())
+                   .setTitle(R.string.activity_chooser_title)
+                   .setAdapter(mAdapter, new DialogInterface.OnClickListener() {
+                           @Override
+                           public void onClick(DialogInterface dialog, int which) {
+                               // Add the information of the chosen activity to the intent to send 
+                               ResolveInfo chosen = mAdapter.getItem(which);
+                               ActivityInfo actInfo = chosen.activityInfo;
+                               ComponentName name=new ComponentName(actInfo.applicationInfo.packageName, actInfo.name);
+                               mIntent.setComponent(name);                               
+                               
+                               // Create a new share resource
+                               FileOperationsHelper foh = new FileOperationsHelper();
+                               foh.shareFileWithLinkToApp(mFile, mIntent, (FileActivity)getSherlockActivity()); 
+                           }
+                       })
+                   .create();
+    }
+
+    
+    class ActivityAdapter extends ArrayAdapter<ResolveInfo> {
+        
+        private PackageManager mPackageManager;
+        
+        ActivityAdapter(Context context, PackageManager pm, List<ResolveInfo> apps) {
+            super(context, R.layout.activity_row, apps);
+            this.mPackageManager = pm;
+        }
+        
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = newView(parent);
+            }
+            bindView(position, convertView);
+            return convertView;
+        }
+        
+        private View newView(ViewGroup parent) {
+            return(((LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.activity_row, parent, false));
+        }
+        
+        private void bindView(int position, View row) {
+            TextView label = (TextView) row.findViewById(R.id.title);
+            label.setText(getItem(position).loadLabel(mPackageManager));
+            ImageView icon = (ImageView) row.findViewById(R.id.icon);
+            icon.setImageDrawable(getItem(position).loadIcon(mPackageManager));
+        }
+    }
+    
+}

+ 8 - 3
src/com/owncloud/android/ui/fragment/FileDetailFragment.java

@@ -335,8 +335,14 @@ public class FileDetailFragment extends FileFragment implements
     @Override
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
         switch (item.getItemId()) {
+            case R.id.action_share_file: {
+                FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity();
+                activity.getFileOperationsHelper().shareFileWithLink(getFile(), activity);
+                return true;
+            }
             case R.id.action_open_file_with: {
             case R.id.action_open_file_with: {
-                mContainerActivity.openFile(getFile());
+                FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity();
+                activity.getFileOperationsHelper().openFile(getFile(), activity);
                 return true;
                 return true;
             }
             }
             case R.id.action_remove_file: {
             case R.id.action_remove_file: {
@@ -358,7 +364,7 @@ public class FileDetailFragment extends FileFragment implements
                 return false;
                 return false;
         }
         }
     }
     }
-    
+
     @Override
     @Override
     public void onClick(View v) {
     public void onClick(View v) {
         switch (v.getId()) {
         switch (v.getId()) {
@@ -399,7 +405,6 @@ public class FileDetailFragment extends FileFragment implements
         }
         }
     }
     }
 
 
-
     private void removeFile() {
     private void removeFile() {
         OCFile file = getFile();
         OCFile file = getFile();
         ConfirmationDialogFragment confDialog = ConfirmationDialogFragment.newInstance(
         ConfirmationDialogFragment confDialog = ConfirmationDialogFragment.newInstance(

+ 2 - 4
src/com/owncloud/android/ui/fragment/FileFragment.java

@@ -21,7 +21,6 @@ import android.support.v4.app.Fragment;
 
 
 import com.actionbarsherlock.app.SherlockFragment;
 import com.actionbarsherlock.app.SherlockFragment;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.FileHandler;
 import com.owncloud.android.ui.activity.TransferServiceGetter;
 import com.owncloud.android.ui.activity.TransferServiceGetter;
 
 
 
 
@@ -73,7 +72,7 @@ public class FileFragment extends SherlockFragment {
      * 
      * 
      * @author David A. Velasco
      * @author David A. Velasco
      */
      */
-    public interface ContainerActivity extends TransferServiceGetter, FileHandler {
+    public interface ContainerActivity extends TransferServiceGetter {
 
 
         /**
         /**
          * Callback method invoked when the detail fragment wants to notice its container 
          * Callback method invoked when the detail fragment wants to notice its container 
@@ -95,8 +94,7 @@ public class FileFragment extends SherlockFragment {
          * @param file      File to show details
          * @param file      File to show details
          */
          */
         public void showDetails(OCFile file);
         public void showDetails(OCFile file);
-        
-        
+
     }
     }
     
     
 }
 }

+ 8 - 4
src/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -25,7 +25,6 @@ import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.FileHandler;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.operations.common.OnRemoteOperationListener;
 import com.owncloud.android.lib.operations.common.OnRemoteOperationListener;
@@ -183,8 +182,8 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName
                         // media preview
                         // media preview
                         mContainerActivity.startMediaPreview(file, 0, true);
                         mContainerActivity.startMediaPreview(file, 0, true);
                     } else {
                     } else {
-                        // open with
-                        mContainerActivity.openFile(file);
+                        FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity();
+                        activity.getFileOperationsHelper().openFile(file, activity);
                     }
                     }
                     
                     
                 } else {
                 } else {
@@ -284,6 +283,11 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName
         AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();        
         AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();        
         mTargetFile = (OCFile) mAdapter.getItem(info.position);
         mTargetFile = (OCFile) mAdapter.getItem(info.position);
         switch (item.getItemId()) {
         switch (item.getItemId()) {
+            case R.id.action_share_file: {
+                FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity();
+                activity.getFileOperationsHelper().shareFileWithLink(mTargetFile, activity);
+                return true;
+            }
             case R.id.action_rename_file: {
             case R.id.action_rename_file: {
                 String fileName = mTargetFile.getFileName();
                 String fileName = mTargetFile.getFileName();
                 int extensionStart = mTargetFile.isFolder() ? -1 : fileName.lastIndexOf(".");
                 int extensionStart = mTargetFile.isFolder() ? -1 : fileName.lastIndexOf(".");
@@ -410,7 +414,7 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName
      * 
      * 
      * @author David A. Velasco
      * @author David A. Velasco
      */
      */
-    public interface ContainerActivity extends TransferServiceGetter, OnRemoteOperationListener, FileHandler {
+    public interface ContainerActivity extends TransferServiceGetter, OnRemoteOperationListener {
 
 
         /**
         /**
          * Callback method invoked when a the user browsed into a different folder through the list of files
          * Callback method invoked when a the user browsed into a different folder through the list of files

+ 8 - 14
src/com/owncloud/android/ui/preview/PreviewImageActivity.java

@@ -70,8 +70,6 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C
     
     
     private static final String DIALOG_WAIT_TAG = "DIALOG_WAIT";
     private static final String DIALOG_WAIT_TAG = "DIALOG_WAIT";
     
     
-    private FileDataStorageManager mStorageManager;
-    
     private ViewPager mViewPager; 
     private ViewPager mViewPager; 
     private PreviewImagePagerAdapter mPreviewImagePagerAdapter;    
     private PreviewImagePagerAdapter mPreviewImagePagerAdapter;    
     
     
@@ -115,13 +113,12 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C
     private void initViewPager() {
     private void initViewPager() {
         // get parent from path
         // get parent from path
         String parentPath = getFile().getRemotePath().substring(0, getFile().getRemotePath().lastIndexOf(getFile().getFileName()));
         String parentPath = getFile().getRemotePath().substring(0, getFile().getRemotePath().lastIndexOf(getFile().getFileName()));
-        OCFile parentFolder = mStorageManager.getFileByPath(parentPath);
-        //OCFile parentFolder = mStorageManager.getFileById(getFile().getParentId());
+        OCFile parentFolder = getStorageManager().getFileByPath(parentPath);
         if (parentFolder == null) {
         if (parentFolder == null) {
             // should not be necessary
             // should not be necessary
-            parentFolder = mStorageManager.getFileByPath(OCFile.ROOT_PATH);
+            parentFolder = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
         }
         }
-        mPreviewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(), parentFolder, getAccount(), mStorageManager);
+        mPreviewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(), parentFolder, getAccount(), getStorageManager());
         mViewPager = (ViewPager) findViewById(R.id.fragmentPager);
         mViewPager = (ViewPager) findViewById(R.id.fragmentPager);
         int position = mPreviewImagePagerAdapter.getFilePosition(getFile());
         int position = mPreviewImagePagerAdapter.getFilePosition(getFile());
         position = (position >= 0) ? position : 0;
         position = (position >= 0) ? position : 0;
@@ -385,7 +382,7 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C
             if (getAccount().name.equals(accountName) && 
             if (getAccount().name.equals(accountName) && 
                     downloadedRemotePath != null) {
                     downloadedRemotePath != null) {
 
 
-                OCFile file = mStorageManager.getFileByPath(downloadedRemotePath);
+                OCFile file = getStorageManager().getFileByPath(downloadedRemotePath);
                 int position = mPreviewImagePagerAdapter.getFilePosition(file);
                 int position = mPreviewImagePagerAdapter.getFilePosition(file);
                 boolean downloadWasFine = intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false);
                 boolean downloadWasFine = intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false);
                 //boolean isOffscreen =  Math.abs((mViewPager.getCurrentItem() - position)) <= mViewPager.getOffscreenPageLimit();
                 //boolean isOffscreen =  Math.abs((mViewPager.getCurrentItem() - position)) <= mViewPager.getOffscreenPageLimit();
@@ -433,6 +430,7 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C
 
 
     @Override
     @Override
     protected void onAccountSet(boolean stateWasRecovered) {
     protected void onAccountSet(boolean stateWasRecovered) {
+        super.onAccountSet(stateWasRecovered);
         if (getAccount() != null) {
         if (getAccount() != null) {
             OCFile file = getFile();
             OCFile file = getFile();
             /// Validate handled file  (first image to preview)
             /// Validate handled file  (first image to preview)
@@ -442,15 +440,14 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C
             if (!file.isImage()) {
             if (!file.isImage()) {
                 throw new IllegalArgumentException("Non-image file passed as argument");
                 throw new IllegalArgumentException("Non-image file passed as argument");
             }
             }
-            mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver());            
             
             
             // Update file according to DB file, if it is possible
             // Update file according to DB file, if it is possible
             if (file.getFileId() > FileDataStorageManager.ROOT_PARENT_ID)            
             if (file.getFileId() > FileDataStorageManager.ROOT_PARENT_ID)            
-                file = mStorageManager.getFileById(file.getFileId());
+                file = getStorageManager().getFileById(file.getFileId());
             
             
             if (file != null) {
             if (file != null) {
                 /// Refresh the activity according to the Account and OCFile set
                 /// Refresh the activity according to the Account and OCFile set
-                setFile(file);  // reset after getting it fresh from mStorageManager
+                setFile(file);  // reset after getting it fresh from storageManager
                 getSupportActionBar().setTitle(getFile().getFileName());
                 getSupportActionBar().setTitle(getFile().getFileName());
                 //if (!stateWasRecovered) {
                 //if (!stateWasRecovered) {
                     initViewPager();
                     initViewPager();
@@ -460,9 +457,6 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C
                 // handled file not in the current Account
                 // handled file not in the current Account
                 finish();
                 finish();
             }
             }
-            
-        } else {
-            Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!");
         }
         }
     }
     }
     
     
@@ -480,5 +474,5 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C
             startActivity(i);
             startActivity(i);
         }
         }
     }
     }
-    
+
 }
 }

+ 6 - 0
src/com/owncloud/android/ui/preview/PreviewImageFragment.java

@@ -57,6 +57,7 @@ import com.owncloud.android.lib.operations.common.OnRemoteOperationListener;
 import com.owncloud.android.lib.operations.common.RemoteOperation;
 import com.owncloud.android.lib.operations.common.RemoteOperation;
 import com.owncloud.android.lib.operations.common.RemoteOperationResult;
 import com.owncloud.android.lib.operations.common.RemoteOperationResult;
 import com.owncloud.android.operations.RemoveFileOperation;
 import com.owncloud.android.operations.RemoveFileOperation;
+import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.fragment.ConfirmationDialogFragment;
 import com.owncloud.android.ui.fragment.ConfirmationDialogFragment;
 import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.utils.Log_OC;
 import com.owncloud.android.utils.Log_OC;
@@ -247,6 +248,11 @@ public class PreviewImageFragment extends FileFragment implements   OnRemoteOper
     @Override
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
         switch (item.getItemId()) {
+            case R.id.action_share_file: {
+                FileActivity act = (FileActivity)getSherlockActivity();
+                act.getFileOperationsHelper().shareFileWithLink(getFile(), act);
+                return true;
+            }
             case R.id.action_open_file_with: {
             case R.id.action_open_file_with: {
                 openFile();
                 openFile();
                 return true;
                 return true;

+ 12 - 0
src/com/owncloud/android/ui/preview/PreviewMediaFragment.java

@@ -307,6 +307,10 @@ public class PreviewMediaFragment extends FileFragment implements
     @Override
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
         switch (item.getItemId()) {
+            case R.id.action_share_file: {
+                shareFileWithLink();
+                return true;
+            }
             case R.id.action_open_file_with: {
             case R.id.action_open_file_with: {
                 openFile();
                 openFile();
                 return true;
                 return true;
@@ -326,6 +330,14 @@ public class PreviewMediaFragment extends FileFragment implements
     }
     }
 
 
     
     
+    private void shareFileWithLink() {
+        stopPreview(false);
+        FileActivity activity = (FileActivity)((FileFragment.ContainerActivity)getActivity());
+        activity.getFileOperationsHelper().shareFileWithLink(getFile(), activity);
+        
+    }
+
+
     private void seeDetails() {
     private void seeDetails() {
         stopPreview(false);
         stopPreview(false);
         ((FileFragment.ContainerActivity)getActivity()).showDetails(getFile());        
         ((FileFragment.ContainerActivity)getActivity()).showDetails(getFile());        

+ 2 - 6
src/com/owncloud/android/ui/preview/PreviewVideoActivity.java

@@ -18,7 +18,6 @@
 package com.owncloud.android.ui.preview;
 package com.owncloud.android.ui.preview;
 
 
 import com.owncloud.android.R;
 import com.owncloud.android.R;
-import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.media.MediaService;
 import com.owncloud.android.media.MediaService;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileActivity;
@@ -60,8 +59,6 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi
     
     
     private static final String TAG = PreviewVideoActivity.class.getSimpleName();
     private static final String TAG = PreviewVideoActivity.class.getSimpleName();
 
 
-    private FileDataStorageManager mStorageManager;
-    
     private int mSavedPlaybackPosition;         // in the unit time handled by MediaPlayer.getCurrentPosition()
     private int mSavedPlaybackPosition;         // in the unit time handled by MediaPlayer.getCurrentPosition()
     private boolean mAutoplay;                  // when 'true', the playback starts immediately with the activity
     private boolean mAutoplay;                  // when 'true', the playback starts immediately with the activity
     private VideoView mVideoPlayer;             // view to play the file; both performs and show the playback
     private VideoView mVideoPlayer;             // view to play the file; both performs and show the playback
@@ -194,6 +191,7 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi
     
     
     @Override
     @Override
     protected void onAccountSet(boolean stateWasRecovered) {
     protected void onAccountSet(boolean stateWasRecovered) {
+        super.onAccountSet(stateWasRecovered);
         if (getAccount() != null) {
         if (getAccount() != null) {
             OCFile file = getFile();
             OCFile file = getFile();
             /// Validate handled file  (first image to preview)
             /// Validate handled file  (first image to preview)
@@ -203,8 +201,7 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi
             if (!file.isVideo()) {
             if (!file.isVideo()) {
                 throw new IllegalArgumentException("Non-video file passed as argument");
                 throw new IllegalArgumentException("Non-video file passed as argument");
             }
             }
-            mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver());
-            file = mStorageManager.getFileById(file.getFileId()); 
+            file = getStorageManager().getFileById(file.getFileId()); 
             if (file != null) {
             if (file != null) {
                 if (file.isDown()) {
                 if (file.isDown()) {
                     mVideoPlayer.setVideoPath(file.getStoragePath());
                     mVideoPlayer.setVideoPath(file.getStoragePath());
@@ -230,7 +227,6 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi
                 finish();
                 finish();
             }
             }
         } else {
         } else {
-            Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!");
             finish();
             finish();
         }
         }
    }
    }