[Libreoffice-commits] core.git: 4 commits - android/source

Jacobo Aragunde Pérez jaragunde at igalia.com
Fri Sep 11 11:33:56 PDT 2015


 android/source/res/values/strings.xml                                                      |    5 
 android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java                       |   97 +++++++++-
 android/source/src/java/org/libreoffice/storage/DocumentProviderFactory.java               |   17 -
 android/source/src/java/org/libreoffice/storage/IDocumentProvider.java                     |   11 +
 android/source/src/java/org/libreoffice/storage/IFile.java                                 |    8 
 android/source/src/java/org/libreoffice/storage/local/LocalDocumentsDirectoryProvider.java |    4 
 android/source/src/java/org/libreoffice/storage/local/LocalDocumentsProvider.java          |   11 +
 android/source/src/java/org/libreoffice/storage/local/LocalFile.java                       |    5 
 android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudFile.java                 |   22 ++
 android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudProvider.java             |   10 -
 android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java                      |    9 
 11 files changed, 182 insertions(+), 17 deletions(-)

New commits:
commit a952540aeba688b10eb1ecd1194c95610ba7f350
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Fri Sep 11 16:56:31 2015 +0000

    Android: i18-ize some strings
    
    Change-Id: I35d0ef7976d6dcca65f3335ff9175c799faa99fe

diff --git a/android/source/res/values/strings.xml b/android/source/res/values/strings.xml
index 5e2dd9b..c7d6e63 100644
--- a/android/source/res/values/strings.xml
+++ b/android/source/res/values/strings.xml
@@ -64,6 +64,11 @@
     <string name="action_keyboard">Show keyboard</string>
     <string name="action_save">Save</string>
 
+    <!-- Feedback messages -->
+    <string name="message_saved">Save complete</string>
+    <string name="message_saving">Saving the document...</string>
+    <string name="message_save_incomplete">Save incomplete. Were there any changes?</string>
+
     <!-- Document provider settings -->
     <string name="storage_provider_settings">Storage provider settings</string>
     <string name="owncloud_settings">ownCloud settings</string>
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 255c474..c7fb342 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -258,7 +258,7 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
     private void saveDocument() {
         final long lastModified = mInputFile.lastModified();
         final Activity activity = LibreOfficeMainActivity.this;
-        Toast.makeText(this, "Saving the document...", Toast.LENGTH_SHORT).show();
+        Toast.makeText(this, R.string.message_saving, Toast.LENGTH_SHORT).show();
         // local save
         LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Save"));
 
@@ -287,8 +287,8 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
 
             @Override
             protected void onPostExecute(Void param) {
-                Toast.makeText(activity, "Save complete", Toast.LENGTH_SHORT)
-                        .show();
+                Toast.makeText(activity, R.string.message_saved,
+                        Toast.LENGTH_SHORT).show();
             }
         };
         // Delay the call to document provider save operation and check the
@@ -312,7 +312,7 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
                         // 20 seconds later, the local file has not changed,
                         // maybe there were no changes at all
                         Toast.makeText(activity,
-                                "Save incomplete. Were there any changes?",
+                                R.string.message_save_incomplete,
                                 Toast.LENGTH_LONG).show();
                     }
                 }
commit 315ca033c696a6d7339a4c3f2fc617e01d80fcb8
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Fri Sep 11 12:10:41 2015 +0000

    Android: check file modify date to know if save is complete
    
    The API does not allow to set a callback for the save operation, we
    work this limitation around by checking the modification date of the
    local file periodically. When that date changes, we are sure the
    local save operation is complete and we can invoke the document
    provider save operation to push the changes to the cloud, if
    necessary.
    
    Users may press "save" on a document with no changes, in this case we
    have set a 20 seconds limit to stop checking the modification date.
    
    We also add a "save complete" message for the user.
    
    Change-Id: Ib8871fac682a5c03a187a7238e11874984143527

diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 098a91b..255c474 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -256,6 +256,8 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
      * to the cloud if necessary.
      */
     private void saveDocument() {
+        final long lastModified = mInputFile.lastModified();
+        final Activity activity = LibreOfficeMainActivity.this;
         Toast.makeText(this, "Saving the document...", Toast.LENGTH_SHORT).show();
         // local save
         LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Save"));
@@ -271,7 +273,6 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
                     mStorageFile.saveDocument(mInputFile);
                 }
                 catch (final RuntimeException e) {
-                    final Activity activity = LibreOfficeMainActivity.this;
                     activity.runOnUiThread(new Runnable() {
                         @Override
                         public void run() {
@@ -283,16 +284,41 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
                 }
                 return null;
             }
+
+            @Override
+            protected void onPostExecute(Void param) {
+                Toast.makeText(activity, "Save complete", Toast.LENGTH_SHORT)
+                        .show();
+            }
         };
-        // Delay the call to document provider save operation to ensure the local
-        // file has been saved.
-        // FIXME: horrible hack, ideally the save operation should have a callback
-        new Handler().postDelayed(new Runnable() {
+        // Delay the call to document provider save operation and check the
+        // modification time periodically to ensure the local file has been saved.
+        // TODO: ideally the save operation should have a callback
+        Runnable runTask = new Runnable() {
+            private int timesRun = 0;
+
             @Override
             public void run() {
-                task.execute();
+                if (lastModified < mInputFile.lastModified()) {
+                    // we are sure local save is complete, push changes to cloud
+                    task.execute();
+                }
+                else {
+                    timesRun++;
+                    if(timesRun < 4) {
+                        new Handler().postDelayed(this, 5000);
+                    }
+                    else {
+                        // 20 seconds later, the local file has not changed,
+                        // maybe there were no changes at all
+                        Toast.makeText(activity,
+                                "Save incomplete. Were there any changes?",
+                                Toast.LENGTH_LONG).show();
+                    }
+                }
             }
-        }, 5000);
+        };
+        new Handler().postDelayed(runTask, 5000);
     }
 
     @Override
commit 626ebde44f56755a413945dcb260740ddacf90ba
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Fri Sep 11 11:24:06 2015 +0000

    Android: Implement cloud save
    
    The LOMainActivity now needs to be aware of Document Providers, so we
    pass the providerId and documentUri in the Intent so it can rebuild
    the DocumentProvider and the IFile objects.
    
    We also implement the ownCloud save operation.
    
    TODO: since the local save operation does not have a callback, we do
    not know when the cloud save operation should be performed. Now we
    just wait 5 seconds to trigger it.
    
    Change-Id: I060969e12888eca07c8c56ddc82cbed6c45a0739

diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 822934f..098a91b 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -1,10 +1,12 @@
 package org.libreoffice;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.preference.PreferenceManager;
@@ -21,6 +23,8 @@ import android.widget.ListView;
 import android.widget.Toast;
 
 import org.libreoffice.overlay.DocumentOverlay;
+import org.libreoffice.storage.DocumentProviderFactory;
+import org.libreoffice.storage.IFile;
 import org.mozilla.gecko.ZoomConstraints;
 import org.mozilla.gecko.gfx.GeckoLayerClient;
 import org.mozilla.gecko.gfx.LayerView;
@@ -31,6 +35,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -50,13 +55,16 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
 
     private static boolean mEnableEditing;
 
+    int providerId;
+    URI documentUri;
+
     public Handler mMainHandler;
 
     private DrawerLayout mDrawerLayout;
     private ListView mDrawerList;
     private List<DocumentPartView> mDocumentPartView = new ArrayList<DocumentPartView>();
     private DocumentPartViewListAdapter mDocumentPartViewListAdapter;
-    private String mInputFile;
+    private File mInputFile;
     private DocumentOverlay mDocumentOverlay;
     private File mTempFile = null;
     private LOAbout mAbout;
@@ -110,8 +118,7 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
                 mAbout.showAbout();
                 return true;
             case R.id.action_save:
-                Toast.makeText(this, "Saving the document...", Toast.LENGTH_SHORT).show();
-                LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Save"));
+                saveDocument();
                 return true;
             case R.id.action_parts:
                 mDrawerLayout.openDrawer(mDrawerList);
@@ -154,17 +161,23 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
         if (getIntent().getData() != null) {
             if (getIntent().getData().getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
                 if (copyFileToTemp() && mTempFile != null) {
-                    mInputFile = mTempFile.getPath();
+                    mInputFile = mTempFile;
                     Log.d(LOGTAG, "SCHEME_CONTENT: getPath(): " + getIntent().getData().getPath());
                 } else {
                     // TODO: can't open the file
                 }
             } else if (getIntent().getData().getScheme().equals(ContentResolver.SCHEME_FILE)) {
-                mInputFile = getIntent().getData().getPath();
+                mInputFile = new File(getIntent().getData().getPath());
                 Log.d(LOGTAG, "SCHEME_FILE: getPath(): " + getIntent().getData().getPath());
+
+                // Gather data to rebuild IFile object later
+                providerId = getIntent().getIntExtra(
+                        "org.libreoffice.document_provider_id", 0);
+                documentUri = (URI) getIntent().getSerializableExtra(
+                        "org.libreoffice.document_uri");
             }
         } else {
-            mInputFile = DEFAULT_DOC_PATH;
+            mInputFile = new File(DEFAULT_DOC_PATH);
         }
 
         toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@@ -238,6 +251,50 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
         return false;
     }
 
+    /**
+     * Save the document and invoke save on document provider to upload the file
+     * to the cloud if necessary.
+     */
+    private void saveDocument() {
+        Toast.makeText(this, "Saving the document...", Toast.LENGTH_SHORT).show();
+        // local save
+        LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Save"));
+
+        final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                try {
+                    // rebuild the IFile object from the data passed in the Intent
+                    IFile mStorageFile = DocumentProviderFactory.getInstance()
+                            .getProvider(providerId).createFromUri(documentUri);
+                    // call document provider save operation
+                    mStorageFile.saveDocument(mInputFile);
+                }
+                catch (final RuntimeException e) {
+                    final Activity activity = LibreOfficeMainActivity.this;
+                    activity.runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            Toast.makeText(activity, e.getMessage(),
+                                    Toast.LENGTH_SHORT).show();
+                        }
+                    });
+                    Log.e(LOGTAG, e.getMessage(), e.getCause());
+                }
+                return null;
+            }
+        };
+        // Delay the call to document provider save operation to ensure the local
+        // file has been saved.
+        // FIXME: horrible hack, ideally the save operation should have a callback
+        new Handler().postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                task.execute();
+            }
+        }, 5000);
+    }
+
     @Override
     protected void onResume() {
         super.onResume();
@@ -260,7 +317,7 @@ public class LibreOfficeMainActivity extends ActionBarActivity {
     protected void onStart() {
         Log.i(LOGTAG, "onStart..");
         super.onStart();
-        LOKitShell.sendLoadEvent(mInputFile);
+        LOKitShell.sendLoadEvent(mInputFile.getPath());
     }
 
     @Override
diff --git a/android/source/src/java/org/libreoffice/storage/IFile.java b/android/source/src/java/org/libreoffice/storage/IFile.java
index 8effd0f..3655ba4 100644
--- a/android/source/src/java/org/libreoffice/storage/IFile.java
+++ b/android/source/src/java/org/libreoffice/storage/IFile.java
@@ -102,4 +102,12 @@ public interface IFile {
      * @throws RuntimeException in case of error.
      */
     File getDocument();
+
+    /**
+     * Replaces the wrapped document with a new version of it.
+     *
+     * @param file
+     *            A local file pointing to the new version of the document.
+     */
+    void saveDocument(File file);
 }
diff --git a/android/source/src/java/org/libreoffice/storage/local/LocalFile.java b/android/source/src/java/org/libreoffice/storage/local/LocalFile.java
index 8e8115a..2d5554b 100644
--- a/android/source/src/java/org/libreoffice/storage/local/LocalFile.java
+++ b/android/source/src/java/org/libreoffice/storage/local/LocalFile.java
@@ -93,4 +93,9 @@ public class LocalFile implements IFile {
         LocalFile file = (LocalFile) object;
         return file.getUri().equals(getUri());
     }
+
+    @Override
+    public void saveDocument(File file) {
+        // do nothing; file is local
+    }
 }
diff --git a/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudFile.java b/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudFile.java
index ce10ab6..89a7f09 100644
--- a/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudFile.java
+++ b/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudFile.java
@@ -9,10 +9,14 @@ import java.util.List;
 
 import org.libreoffice.storage.IFile;
 
+import android.util.Log;
+
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.resources.files.ChunkedUploadRemoteFileOperation;
 import com.owncloud.android.lib.resources.files.DownloadRemoteFileOperation;
 import com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation;
 import com.owncloud.android.lib.resources.files.RemoteFile;
+import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation;
 
 /**
  * Implementation of IFile for ownCloud servers.
@@ -119,4 +123,22 @@ public class OwnCloudFile implements IFile {
         OwnCloudFile file = (OwnCloudFile) object;
         return file.getUri().equals(getUri());
     }
+
+    @Override
+    public void saveDocument(File newFile) {
+        UploadRemoteFileOperation uploadOperation;
+        if (newFile.length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE) {
+            uploadOperation = new ChunkedUploadRemoteFileOperation(
+                    newFile.getPath(), file.getRemotePath(), file.getMimeType());
+        } else {
+            uploadOperation = new UploadRemoteFileOperation(newFile.getPath(),
+                    file.getRemotePath(), file.getMimeType());
+        }
+
+        RemoteOperationResult result = uploadOperation.execute(provider
+                .getClient());
+        if (!result.isSuccess()) {
+            throw provider.buildRuntimeExceptionForResultCode(result.getCode());
+        }
+    }
 }
diff --git a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
index dbc309d..72d2e82 100644
--- a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
+++ b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
@@ -351,7 +351,7 @@ public class LibreOfficeUIActivity extends ActionBarActivity implements ActionBa
         }.execute(dir);
     }
 
-    public void open(IFile document) {
+    public void open(final IFile document) {
         new AsyncTask<IFile, Void, File>() {
             @Override
             protected File doInBackground(IFile... document) {
@@ -382,6 +382,13 @@ public class LibreOfficeUIActivity extends ActionBarActivity implements ActionBa
                     ComponentName componentName = new ComponentName(packageName,
                             LibreOfficeMainActivity.class.getName());
                     i.setComponent(componentName);
+
+                    // these extras allow to rebuild the IFile object in LOMainActivity
+                    i.putExtra("org.libreoffice.document_provider_id",
+                            documentProvider.getId());
+                    i.putExtra("org.libreoffice.document_uri",
+                            document.getUri());
+
                     startActivity(i);
                 }
             }
commit a3c3a13e8499e994b198b80566cdee9af9a7f2da
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date:   Thu Sep 3 18:23:48 2015 +0000

    Android: provide an ID to document providers
    
    This ID will be useful to get an instance of a document provider back
    from a different activity.
    
    Change-Id: I9419ea23d51f8e9ffd70252bd8e367cf51bde1ad

diff --git a/android/source/src/java/org/libreoffice/storage/DocumentProviderFactory.java b/android/source/src/java/org/libreoffice/storage/DocumentProviderFactory.java
index d6e4ca1..b8c0534 100644
--- a/android/source/src/java/org/libreoffice/storage/DocumentProviderFactory.java
+++ b/android/source/src/java/org/libreoffice/storage/DocumentProviderFactory.java
@@ -57,9 +57,9 @@ public final class DocumentProviderFactory {
 
             // initialize document providers list
             instance.providers = new IDocumentProvider[3];
-            instance.providers[0] = new LocalDocumentsDirectoryProvider();
-            instance.providers[1] = new LocalDocumentsProvider();
-            instance.providers[2] = new OwnCloudProvider(context);
+            instance.providers[0] = new LocalDocumentsDirectoryProvider(0);
+            instance.providers[1] = new LocalDocumentsProvider(1);
+            instance.providers[2] = new OwnCloudProvider(2, context);
 
             // initialize document provider names list
             instance.providerNames = new String[instance.providers.length];
@@ -80,13 +80,14 @@ public final class DocumentProviderFactory {
     }
 
     /**
-     * Retrieve the provider associated to a certain position.
+     * Retrieve the provider associated to a certain id.
      *
-     * @param position
-     * @return document provider in that position.
+     * @param id
+     * @return document provider with that id.
      */
-    public IDocumentProvider getProvider(int position) {
-        return providers[position];
+    public IDocumentProvider getProvider(int id) {
+        // as for now, id == position in providers array
+        return providers[id];
     }
 
     /**
diff --git a/android/source/src/java/org/libreoffice/storage/IDocumentProvider.java b/android/source/src/java/org/libreoffice/storage/IDocumentProvider.java
index bbfdecd..edb026f 100644
--- a/android/source/src/java/org/libreoffice/storage/IDocumentProvider.java
+++ b/android/source/src/java/org/libreoffice/storage/IDocumentProvider.java
@@ -43,4 +43,15 @@ public interface IDocumentProvider {
      * @return string resource pointing to the provider name.
      */
     int getNameResource();
+
+    /**
+     * Provides the unique ID for a document provider instance in a program.
+     *
+     * This ID should be set when the instance is built. It could be used to
+     * tell two instances of the same document provider apart, e. g. two
+     * instances of OwnCloudProvider pointing to different servers.
+     *
+     * @return Unique ID for a document provider instance.
+     */
+    int getId();
 }
diff --git a/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsDirectoryProvider.java b/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsDirectoryProvider.java
index 92d93d6..fb42369 100644
--- a/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsDirectoryProvider.java
+++ b/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsDirectoryProvider.java
@@ -25,6 +25,10 @@ import android.os.Environment;
  */
 public class LocalDocumentsDirectoryProvider extends LocalDocumentsProvider {
 
+    public LocalDocumentsDirectoryProvider(int id) {
+        super(id);
+    }
+
     @Override
     public IFile getRootDirectory() {
         File documentsDirectory = new File(
diff --git a/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsProvider.java b/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsProvider.java
index cc96ef0..a1a84e8 100644
--- a/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsProvider.java
+++ b/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsProvider.java
@@ -23,6 +23,12 @@ import android.os.Environment;
  */
 public class LocalDocumentsProvider implements IDocumentProvider {
 
+    private int id;
+
+    public LocalDocumentsProvider(int id) {
+        this.id = id;
+    }
+
     @Override
     public IFile getRootDirectory() {
         return new LocalFile(Environment.getExternalStorageDirectory());
@@ -37,4 +43,9 @@ public class LocalDocumentsProvider implements IDocumentProvider {
     public int getNameResource() {
         return R.string.local_file_system;
     }
+
+    @Override
+    public int getId() {
+        return id;
+    }
 }
diff --git a/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudProvider.java b/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudProvider.java
index 66e4633..bf866b9 100644
--- a/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudProvider.java
+++ b/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudProvider.java
@@ -29,6 +29,8 @@ import com.owncloud.android.lib.resources.files.RemoteFile;
 public class OwnCloudProvider implements IDocumentProvider,
         OnSharedPreferenceChangeListener {
 
+    private int id;
+
     private Context context;
     private OwnCloudClient client;
     private File cacheDir;
@@ -37,7 +39,8 @@ public class OwnCloudProvider implements IDocumentProvider,
     private String userName;
     private String password;
 
-    public OwnCloudProvider(Context context) {
+    public OwnCloudProvider(int id, Context context) {
+        this.id = id;
         this.context = context;
 
         // read preferences
@@ -169,4 +172,9 @@ public class OwnCloudProvider implements IDocumentProvider,
         if (changed)
             setupClient();
     }
+
+    @Override
+    public int getId() {
+        return id;
+    }
 }


More information about the Libreoffice-commits mailing list