[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-7-1+backports' - 9 commits - android/source
Michael Weghorn (via logerrit)
logerrit at kemper.freedesktop.org
Fri Apr 16 08:20:12 UTC 2021
android/source/res/menu/main.xml | 15
android/source/res/values-de/strings.xml | 3
android/source/res/values-tr/strings.xml | 1
android/source/res/values/strings.xml | 3
android/source/src/java/org/libreoffice/FontController.java | 2
android/source/src/java/org/libreoffice/InvalidationHandler.java | 4
android/source/src/java/org/libreoffice/LOKitShell.java | 4
android/source/src/java/org/libreoffice/LOKitTileProvider.java | 89 +-
android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java | 298 +++++++---
android/source/src/java/org/libreoffice/TileProvider.java | 10
android/source/src/java/org/libreoffice/ToolbarController.java | 24
android/source/src/java/org/libreoffice/ui/FileUtilities.java | 42 -
android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java | 51 -
13 files changed, 325 insertions(+), 221 deletions(-)
New commits:
commit 10d1390980f986afef25f715ce41f02b3c586bf1
Author: Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Thu Apr 15 16:50:16 2021 +0200
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Fri Apr 16 10:17:51 2021 +0200
tdf#95615 android: Don't offer "Save" after opening template
When the input document in Android Viewer is a template,
a new doc is created and a plain '.uno:Save'
(which 'LibreOfficeMainActivity#saveDocument' triggers when the
"Save" menu entry is selected) will therefore fail.
A proper URI to save to (rather than overwriting the
template itself) is only known after a "Save As" anyway,
so don't set the 'mDocument' member until then, which leads to
the "Save" menu entry becoming disabled, just as is the
case when explicitly choosing to create a new document in
the start activity.
For now, the check whether the document is a template
checks whether the MIME type detected for the URI
ends with "template", which is the case for ODF and
OOXML types (like
"application/vnd.oasis.opendocument.text-template" or
"application/vnd.openxmlformats-officedocument.wordprocessingml.template").
This can be refined further as needed, e.g. by explicitly
adding more MIME types to check.
(Editing the actual template instead of creating a new doc
from it would be a different use case that remains
unsupported also with this change in place.)
Change-Id: I81ff957de27f620a026dbc01097b8061886293a1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114157
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
(cherry picked from commit 01521db61eb41447113c4bb671ac828a583c0cd1)
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 066c05dc9662..f7f5f6ae0ed6 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -82,7 +82,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
private List<DocumentPartView> mDocumentPartView = new ArrayList<DocumentPartView>();
private DocumentPartViewListAdapter mDocumentPartViewListAdapter;
private DocumentOverlay mDocumentOverlay;
- /** URI of the actual document. */
+ /** URI to save the document to. */
private Uri mDocumentUri;
/** Temporary local copy of the document. */
private File mTempFile = null;
@@ -170,29 +170,38 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
mbISReadOnlyMode = !isExperimentalMode();
- mDocumentUri = getIntent().getData();
- if (mDocumentUri != null) {
- if (mDocumentUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)
- || mDocumentUri.getScheme().equals(ContentResolver.SCHEME_ANDROID_RESOURCE)) {
+ final Uri docUri = getIntent().getData();
+ if (docUri != null) {
+ if (docUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)
+ || docUri.getScheme().equals(ContentResolver.SCHEME_ANDROID_RESOURCE)) {
final boolean isReadOnlyDoc = (getIntent().getFlags() & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
mbISReadOnlyMode = !isExperimentalMode() || isReadOnlyDoc;
- Log.d(LOGTAG, "SCHEME_CONTENT: getPath(): " + mDocumentUri.getPath());
+ Log.d(LOGTAG, "SCHEME_CONTENT: getPath(): " + docUri.getPath());
- String displayName = FileUtilities.retrieveDisplayNameForDocumentUri(getContentResolver(), mDocumentUri);
+ String displayName = FileUtilities.retrieveDisplayNameForDocumentUri(getContentResolver(), docUri);
toolbarTop.setTitle(displayName);
- } else if (mDocumentUri.getScheme().equals(ContentResolver.SCHEME_FILE)) {
+ } else if (docUri.getScheme().equals(ContentResolver.SCHEME_FILE)) {
mbISReadOnlyMode = true;
- Log.d(LOGTAG, "SCHEME_FILE: getPath(): " + mDocumentUri.getPath());
- toolbarTop.setTitle(mDocumentUri.getLastPathSegment());
+ Log.d(LOGTAG, "SCHEME_FILE: getPath(): " + docUri.getPath());
+ toolbarTop.setTitle(docUri.getLastPathSegment());
}
// create a temporary local copy to work with
- boolean copyOK = copyFileToTemp() && mTempFile != null;
+ boolean copyOK = copyFileToTemp(docUri) && mTempFile != null;
if (!copyOK) {
// TODO: can't open the file
- Log.e(LOGTAG, "couldn't create temporary file from " + mDocumentUri);
+ Log.e(LOGTAG, "couldn't create temporary file from " + docUri);
return;
}
+
+ // if input doc is a template, a new doc is created and a proper URI to save to
+ // will only be available after a "Save As"
+ if (isTemplate(docUri)) {
+ toolbarTop.setTitle(R.string.default_document_name);
+ } else {
+ mDocumentUri = docUri;
+ }
+
LOKitShell.sendLoadEvent(mTempFile.getPath());
} else if (getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY) != null) {
// New document type string is not null, meaning we want to open a new document
@@ -275,7 +284,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
return mDocumentOverlay.getCurrentCursorPosition();
}
- private boolean copyFileToTemp() {
+ private boolean copyFileToTemp(Uri documentUri) {
// CSV files need a .csv suffix to be opened in Calc.
String suffix = null;
String intentType = getIntent().getType();
@@ -286,7 +295,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
try {
mTempFile = File.createTempFile("LibreOffice", suffix, this.getCacheDir());
final FileOutputStream outputStream = new FileOutputStream(mTempFile);
- return copyUriToStream(mDocumentUri, outputStream);
+ return copyUriToStream(documentUri, outputStream);
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
@@ -395,6 +404,14 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
}
}
+ /**
+ * Returns whether the MIME type for the URI is considered one for a document template.
+ */
+ private boolean isTemplate(final Uri documentUri) {
+ final String mimeType = getContentResolver().getType(documentUri);
+ return FileUtilities.isTemplateMimeType(mimeType);
+ }
+
public void saveFileToOriginalSource() {
if (isReadOnlyMode() || mTempFile == null || mDocumentUri == null || !mDocumentUri.getScheme().equals(ContentResolver.SCHEME_CONTENT))
return;
diff --git a/android/source/src/java/org/libreoffice/ui/FileUtilities.java b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
index 0d51dd55e1e5..aed671205bef 100644
--- a/android/source/src/java/org/libreoffice/ui/FileUtilities.java
+++ b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
@@ -156,6 +156,14 @@ public class FileUtilities {
return isHidden(file) && file.getName().endsWith(".png");
}
+ /**
+ * Returns whether the passed MIME type is one for a document template.
+ */
+ public static boolean isTemplateMimeType(final String mimeType) {
+ // this works for ODF and OOXML template MIME types
+ return mimeType.endsWith("template");
+ }
+
/**
* Tries to retrieve the display (which should be the document name)
* for the given URI using the given resolver.
commit b26b05746f8d9ce27347d01e601b61a2a97bbbe7
Author: Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Thu Apr 15 15:14:51 2021 +0200
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Fri Apr 16 10:17:41 2021 +0200
android: Show file picker for new docs on "Save As"
When creating a new document in Android Viewer,
don't show a file picker to choose where to save
the file at once, but create a new document and
only ask where to save the file once "Save As"
has been selected.
The plain "Save" entry is disabled until then,
since no URI to save to is known at this time.
The handling for the temporary local file,
which is used for all of the "actual work"
remains unchanged.
While at it, rename
'ToolbarController#disableMenuItem' to
'ToolbarController#enableMenuItem' and
invert the meaning of the boolean parameter
since I find that more straightforward and it also
better matches the naming of the underlying
'MenuItem' method as well.
Change-Id: I3eefada5531bfb2202aca25f2c9f170a463f87f6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114152
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
(cherry picked from commit 5ce43b2b4e79c51f0d8922caf77fa6492c05c2a7)
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 1812ad253744..066c05dc9662 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -169,24 +169,12 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
mDocumentOverlay = new DocumentOverlay(this, layerView);
mbISReadOnlyMode = !isExperimentalMode();
- boolean isNewDocument = false;
mDocumentUri = getIntent().getData();
if (mDocumentUri != null) {
if (mDocumentUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)
|| mDocumentUri.getScheme().equals(ContentResolver.SCHEME_ANDROID_RESOURCE)) {
- final boolean isReadOnlyDoc;
- if (getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY) != null) {
- // New document type string is not null, meaning we want to open a new document
- String newDocumentType = getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY);
- // create a temporary local file, will be copied to the actual URI when saving
- loadNewDocument(newDocumentType);
- isNewDocument = true;
- isReadOnlyDoc = false;
- } else {
- isReadOnlyDoc = (getIntent().getFlags() & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
- }
-
+ final boolean isReadOnlyDoc = (getIntent().getFlags() & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
mbISReadOnlyMode = !isExperimentalMode() || isReadOnlyDoc;
Log.d(LOGTAG, "SCHEME_CONTENT: getPath(): " + mDocumentUri.getPath());
@@ -198,12 +186,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
Log.d(LOGTAG, "SCHEME_FILE: getPath(): " + mDocumentUri.getPath());
toolbarTop.setTitle(mDocumentUri.getLastPathSegment());
}
- } else {
- Log.e(LOGTAG, "No document specified. This should never happen.");
- return;
- }
-
- if (!isNewDocument) {
// create a temporary local copy to work with
boolean copyOK = copyFileToTemp() && mTempFile != null;
if (!copyOK) {
@@ -212,6 +194,15 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
return;
}
LOKitShell.sendLoadEvent(mTempFile.getPath());
+ } else if (getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY) != null) {
+ // New document type string is not null, meaning we want to open a new document
+ String newDocumentType = getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY);
+ // create a temporary local file, will be copied to the actual URI when saving
+ loadNewDocument(newDocumentType);
+ toolbarTop.setTitle(getString(R.string.default_document_name));
+ } else {
+ Log.e(LOGTAG, "No document specified. This should never happen.");
+ return;
}
mDrawerLayout = findViewById(R.id.drawer_layout);
@@ -339,6 +330,8 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
String displayName = FileUtilities.retrieveDisplayNameForDocumentUri(getContentResolver(), mDocumentUri);
toolbarTop.setTitle(displayName);
+ // make sure that "Save" menu item is enabled
+ getToolbarController().setupToolbars();
}
public void exportToPDF() {
@@ -880,6 +873,10 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
return mbISReadOnlyMode;
}
+ public boolean hasLocationForSave() {
+ return mDocumentUri != null;
+ }
+
public static void setDocumentChanged (boolean changed) {
isDocumentChanged = changed;
}
diff --git a/android/source/src/java/org/libreoffice/ToolbarController.java b/android/source/src/java/org/libreoffice/ToolbarController.java
index 1384339f8c30..d4985aee180e 100644
--- a/android/source/src/java/org/libreoffice/ToolbarController.java
+++ b/android/source/src/java/org/libreoffice/ToolbarController.java
@@ -45,12 +45,12 @@ public class ToolbarController implements Toolbar.OnMenuItemClickListener {
clipboardManager = (ClipboardManager)mContext.getSystemService(Context.CLIPBOARD_SERVICE);
}
- public void disableMenuItem(final int menuItemId, final boolean disabled) {
+ private void enableMenuItem(final int menuItemId, final boolean enabled) {
LOKitShell.getMainHandler().post(new Runnable() {
public void run() {
MenuItem menuItem = mMainMenu.findItem(menuItemId);
if (menuItem != null) {
- menuItem.setEnabled(!disabled);
+ menuItem.setEnabled(enabled);
} else {
Log.e(LOGTAG, "MenuItem not found.");
}
@@ -245,11 +245,14 @@ public class ToolbarController implements Toolbar.OnMenuItemClickListener {
}
void setupToolbars() {
- // show message in case experimental mode is enabled (i.e. editing is supported in general),
- // but current document is readonly
- if (LibreOfficeMainActivity.isExperimentalMode() && LibreOfficeMainActivity.isReadOnlyMode()) {
- disableMenuItem(R.id.action_save, true);
- Toast.makeText(mContext, mContext.getString(R.string.temp_file_saving_disabled), Toast.LENGTH_LONG).show();
+ if (LibreOfficeMainActivity.isExperimentalMode()) {
+ boolean enableSaveEntry = !LibreOfficeMainActivity.isReadOnlyMode() && mContext.hasLocationForSave();
+ enableMenuItem(R.id.action_save, enableSaveEntry);
+ if (LibreOfficeMainActivity.isReadOnlyMode()) {
+ // show message in case experimental mode is enabled (i.e. editing is supported in general),
+ // but current document is readonly
+ Toast.makeText(mContext, mContext.getString(R.string.temp_file_saving_disabled), Toast.LENGTH_LONG).show();
+ }
}
mMainMenu.findItem(R.id.action_parts).setVisible(mContext.isDrawerEnabled());
}
diff --git a/android/source/src/java/org/libreoffice/ui/FileUtilities.java b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
index 660fbc0e4528..0d51dd55e1e5 100644
--- a/android/source/src/java/org/libreoffice/ui/FileUtilities.java
+++ b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
@@ -33,11 +33,6 @@ public class FileUtilities {
static final int UNKNOWN = 10;
- public static final String DEFAULT_WRITER_EXTENSION = ".odt";
- public static final String DEFAULT_IMPRESS_EXTENSION = ".odp";
- public static final String DEFAULT_SPREADSHEET_EXTENSION = ".ods";
- public static final String DEFAULT_DRAWING_EXTENSION = ".odg";
-
public static final String MIMETYPE_OPENDOCUMENT_TEXT = "application/vnd.oasis.opendocument.text";
public static final String MIMETYPE_OPENDOCUMENT_SPREADSHEET = "application/vnd.oasis.opendocument.spreadsheet";
public static final String MIMETYPE_OPENDOCUMENT_PRESENTATION = "application/vnd.oasis.opendocument.presentation";
diff --git a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
index 9f1cd7a9089d..110123f54acf 100644
--- a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
+++ b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
@@ -23,7 +23,6 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
-import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
@@ -66,9 +65,7 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
INVALID
}
- private String LOGTAG = LibreOfficeUIActivity.class.getSimpleName();
-
- private DocumentType newDocType = DocumentType.INVALID;
+ private static final String LOGTAG = LibreOfficeUIActivity.class.getSimpleName();
public static final String EXPLORER_PREFS_KEY = "EXPLORER_PREFS";
private static final String RECENT_DOCUMENTS_KEY = "RECENT_DOCUMENT_URIS";
@@ -123,7 +120,6 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
};
private static final int REQUEST_CODE_OPEN_FILECHOOSER = 12345;
- private static final int REQUEST_CODE_CREATE_NEW_DOCUMENT = 12346;
private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 0;
@@ -257,10 +253,6 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
if (requestCode == REQUEST_CODE_OPEN_FILECHOOSER && resultCode == RESULT_OK) {
final Uri fileUri = data.getData();
openDocument(fileUri);
- } else if (requestCode == REQUEST_CODE_CREATE_NEW_DOCUMENT && resultCode == RESULT_OK) {
- // "forward" to LibreOfficeMainActivity to create + open the file
- final Uri fileUri = data.getData();
- loadNewDocument(newDocType, fileUri);
}
}
@@ -295,33 +287,7 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
startActivity(intent);
}
- private void createNewFileDialog() {
- final String extension;
- if (newDocType == DocumentType.WRITER) {
- extension = FileUtilities.DEFAULT_WRITER_EXTENSION;
- } else if (newDocType == DocumentType.CALC) {
- extension = FileUtilities.DEFAULT_SPREADSHEET_EXTENSION;
- } else if (newDocType == DocumentType.IMPRESS) {
- extension = FileUtilities.DEFAULT_IMPRESS_EXTENSION;
- } else if (newDocType == DocumentType.DRAW) {
- extension = FileUtilities.DEFAULT_DRAWING_EXTENSION;
- } else {
- Log.e(LOGTAG, "Invalid document type passed.");
- return;
- }
-
- String defaultFileName = getString(R.string.default_document_name) + extension;
- String mimeType = FileUtilities.getMimeType(defaultFileName);
-
- Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setType(mimeType);
- intent.putExtra(Intent.EXTRA_TITLE, defaultFileName);
-
- startActivityForResult(intent, REQUEST_CODE_CREATE_NEW_DOCUMENT);
- }
-
- private void loadNewDocument(DocumentType docType, Uri newFileUri) {
+ private void loadNewDocument(DocumentType docType) {
final String newDocumentType;
if (docType == DocumentType.WRITER) {
newDocumentType = NEW_WRITER_STRING_KEY;
@@ -338,7 +304,6 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
Intent intent = new Intent(LibreOfficeUIActivity.this, LibreOfficeMainActivity.class);
intent.putExtra(NEW_DOC_TYPE_KEY, newDocumentType);
- intent.setData(newFileUri);
startActivity(intent);
}
@@ -493,20 +458,16 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
showSystemFilePickerAndOpenFile();
break;
case R.id.newWriterFAB:
- newDocType = DocumentType.WRITER;
- createNewFileDialog();
+ loadNewDocument(DocumentType.WRITER);
break;
case R.id.newImpressFAB:
- newDocType = DocumentType.IMPRESS;
- createNewFileDialog();
+ loadNewDocument(DocumentType.IMPRESS);
break;
case R.id.newCalcFAB:
- newDocType = DocumentType.CALC;
- createNewFileDialog();
+ loadNewDocument(DocumentType.CALC);
break;
case R.id.newDrawFAB:
- newDocType = DocumentType.DRAW;
- createNewFileDialog();
+ loadNewDocument(DocumentType.DRAW);
break;
}
}
commit 926acbf45578a3f2cd795c41069318ed391c723b
Author: Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Thu Apr 15 15:49:40 2021 +0200
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Fri Apr 16 10:17:30 2021 +0200
android: Drop unused 'FileUtilities#doAccept'
Change-Id: I8b7f268862c3800012548376b3e60ac1f7dca9e3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114151
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
(cherry picked from commit 865ec16158b04cf98efae4309b40244a7e41eb59)
diff --git a/android/source/src/java/org/libreoffice/ui/FileUtilities.java b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
index f1581a678c30..660fbc0e4528 100644
--- a/android/source/src/java/org/libreoffice/ui/FileUtilities.java
+++ b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
@@ -153,23 +153,6 @@ public class FileUtilities {
return mime;
}
- // Filter by mode, and/or in future by filename/wildcard
- private static boolean doAccept(String filename, int byMode, String byFilename) {
- Log.d(LOGTAG, "doAccept : " + filename + " mode " + byMode + " byFilename " + byFilename);
- if (filename == null)
- return false;
-
- // check extension
- if (byMode != ALL) {
- if (mExtnMap.get (getExtension (filename)) != byMode)
- return false;
- }
- if (!byFilename.equals("")) {
- // FIXME return false on a non-match
- }
- return true;
- }
-
static boolean isHidden(File file) {
return file.getName().startsWith(".");
}
commit f9820cbde80b8b9b3875996b0b8e6fc965418220
Author: Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Thu Apr 15 14:31:43 2021 +0200
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Fri Apr 16 10:17:22 2021 +0200
android: Allow printing and PDF export regardless of mode
Don't only enable the "Export To PDF" and "Print" menu
items if the experimental editing mode is enabled, but
always offer them, since they should be sufficiently stable
and don't require any editing of the document.
To do so, move them into a new menu group
"group_misc_actions", and move the entry for sending
UNO commands up, so it remains in the
"group_edit_actions" menu group whose entries are
hidden unless editing mode is enabled.
Change-Id: I425cf6d0a45306ff48b45dad6fd0e804b87a2546
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114147
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
(cherry picked from commit 5306ecda9ceb5f9702c2ce6dc6207a3bd5f14a6a)
diff --git a/android/source/res/menu/main.xml b/android/source/res/menu/main.xml
index 94856d52e759..0570a77fdd7b 100644
--- a/android/source/res/menu/main.xml
+++ b/android/source/res/menu/main.xml
@@ -31,6 +31,9 @@
android:orderInCategory="100"
app:showAsAction="always"/>
+ <item android:id="@+id/action_UNO_commands"
+ android:title="@string/action_UNO_commands"
+ android:orderInCategory="100" />
<item android:id="@+id/action_save"
android:title="@string/action_save"
@@ -39,6 +42,11 @@
<item android:id="@+id/action_save_as"
android:title="@string/action_save_as"
android:orderInCategory="100" />
+ </group>
+
+ <group android:id="@+id/group_misc_actions"
+ tools:visible="true"
+ android:visible="false">
<item android:id="@+id/action_exportToPDF"
android:title="@string/action_exportToPDF"
@@ -51,9 +59,6 @@
android:orderInCategory="100"
android:visible="true" />
- <item android:id="@+id/action_UNO_commands"
- android:title="@string/action_UNO_commands"
- android:orderInCategory="100" />
</group>
<group android:id="@+id/group_spreadsheet_options"
commit bcf3da6c2929810ce7b0ebddbbe9709381c8503a
Author: Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Thu Apr 15 13:47:23 2021 +0200
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Fri Apr 16 10:17:11 2021 +0200
android: Merge 2 'LOKitTileProvider#printDocument' methods
... and move the check for a new enough SDK version to
the beginning.
Change-Id: I7f5528985b8c43e218b88899409fdd22b640f72e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114145
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
(cherry picked from commit 40f30020b9e91d15c4d90e53b1d2e41770fbc58c)
diff --git a/android/source/src/java/org/libreoffice/LOKitTileProvider.java b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
index 5d8d2e557d0f..a5222f7e46ea 100644
--- a/android/source/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
@@ -340,25 +340,22 @@ class LOKitTileProvider implements TileProvider {
}
public void printDocument() {
+ if (Build.VERSION.SDK_INT < 19) {
+ mContext.showCustomStatusMessage(mContext.getString(R.string.printing_not_supported));
+ return;
+ }
+
String mInputFileName = (new File(mInputFile)).getName();
String file = mInputFileName.substring(0,(mInputFileName.length()-3))+"pdf";
String cacheFile = mContext.getExternalCacheDir().getAbsolutePath() + "/" + file;
mDocument.saveAs("file://"+cacheFile,"pdf","");
- printDocument(cacheFile);
- }
-
- private void printDocument(String cacheFile) {
- if (Build.VERSION.SDK_INT >= 19) {
- try {
- PrintManager printManager = (PrintManager) mContext.getSystemService(Context.PRINT_SERVICE);
- PrintDocumentAdapter printAdapter = new PDFDocumentAdapter(mContext, cacheFile);
- printManager.print("Document", printAdapter, new PrintAttributes.Builder().build());
+ try {
+ PrintManager printManager = (PrintManager) mContext.getSystemService(Context.PRINT_SERVICE);
+ PrintDocumentAdapter printAdapter = new PDFDocumentAdapter(mContext, cacheFile);
+ printManager.print("Document", printAdapter, new PrintAttributes.Builder().build());
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- mContext.showCustomStatusMessage(mContext.getString(R.string.printing_not_supported));
+ } catch (Exception e) {
+ e.printStackTrace();
}
}
commit 9c477caa39f2326e9fff4dc0cd9df2f6a3af4362
Author: Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Thu Apr 15 11:22:46 2021 +0200
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Fri Apr 16 10:17:02 2021 +0200
android: Ask where to save PDF file on export
In Android Viewer, show a file picker to select
where to save the PDF file on PDF export, rather
than unconditionally trying to save in the
"Documents" directory.
This also means that permission
'android.PERMISSION_WRITE_EXTERNAL_STORAGE' is
now no longer needed for this task, s. commit
message from
commit 7d9db806d65cb814af1e99a1e79c3db5aa7c17d5
Date: Fri Apr 9 11:24:16 2021 +0200
android: Request PERMISSION_WRITE_EXTERNAL_STORAGE again
for more details.
Also, adapt the 'TileKitProvider#saveDocumentAs'
methods to return a boolean value indicating
whether the save operation was successful,
and trigger showing the message right into
'LibreOfficeMainActivity#exportToPDF'.
Rename 'LOKitTileProvider#exportToPDF(boolean print)' to
just 'LOKitTileProvider#printDocument()', since the only
remaining use case for which it is used is printing now.
Change-Id: I779d782813ca01640811690a388a4b7fd3db4b2a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114143
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
(cherry picked from commit 9ebcb80e2e4335fca1e137d015fe4d84631e282a)
diff --git a/android/source/res/values-de/strings.xml b/android/source/res/values-de/strings.xml
index c2c33ff5b5e5..36effc9303f0 100644
--- a/android/source/res/values-de/strings.xml
+++ b/android/source/res/values-de/strings.xml
@@ -153,9 +153,9 @@
<string name="current_uno_command">Aktuelles UNO-Kommando</string>
<string name="display_language">Anzeigesprache</string>
<string name="display_language_summary">Wählen Sie die Standard-Anzeigesprache</string>
+ <string name="pdf_export_finished">PDF-Export abgeschlossen</string>
<string name="unable_to_export_pdf">PDF-Export nicht möglich</string>
<string name="unable_to_save">Speichern nicht möglich</string>
- <string name="pdf_exported_at">PDF exportiert nach</string>
<string name="printing_not_supported">Ihr Gerät unterstützt Drucken nicht</string>
<string name="creating_new_files_not_supported">Erstellen neuer Dokumente auf diesem Gerät nicht verfügbar, benötigt Android-SDK-Version >= 19.</string>
<string name="error">Fehler</string>
diff --git a/android/source/res/values-tr/strings.xml b/android/source/res/values-tr/strings.xml
index 72d15c210933..a780a59fe165 100644
--- a/android/source/res/values-tr/strings.xml
+++ b/android/source/res/values-tr/strings.xml
@@ -149,7 +149,6 @@
<string name="display_language">Uygulama Dili</string>
<string name="display_language_summary">Varsayılan dili değiştir</string>
<string name="unable_to_export_pdf">Pdf dışa aktarılamıyor.</string>
- <string name="pdf_exported_at">Şu konumda pdf\'e aktarıldı: </string>
<string name="printing_not_supported">Cihazınız yazdırmayı desteklemiyor.</string>
<string name="error">Hata</string>
<string name="enter_part_name">Bölüm ismi girin.</string>
diff --git a/android/source/res/values/strings.xml b/android/source/res/values/strings.xml
index d0014646bc15..6b3db68e23b6 100644
--- a/android/source/res/values/strings.xml
+++ b/android/source/res/values/strings.xml
@@ -152,9 +152,9 @@
<string name="current_uno_command">Current UNO command</string>
<string name="display_language">Display Language</string>
<string name="display_language_summary">Set the default display language</string>
+ <string name="pdf_export_finished">PDF export finished</string>
<string name="unable_to_export_pdf">Unable to export to pdf</string>
<string name="unable_to_save">Unable to save file</string>
- <string name="pdf_exported_at">Exported to PDF at</string>
<string name="printing_not_supported">Your device does not support printing</string>
<string name="creating_new_files_not_supported">Creating new files not supported on this device, requires Android SDK version >= 19.</string>
<string name="error">Error</string>
diff --git a/android/source/src/java/org/libreoffice/LOKitTileProvider.java b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
index 5f4684703f36..5d8d2e557d0f 100644
--- a/android/source/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
@@ -277,7 +277,7 @@ class LOKitTileProvider implements TileProvider {
}
@Override
- public void saveDocumentAs(final String filePath, String format, boolean takeOwnership) {
+ public boolean saveDocumentAs(final String filePath, String format, boolean takeOwnership) {
String options = "";
if (takeOwnership) {
options = "TakeOwnership";
@@ -287,21 +287,16 @@ class LOKitTileProvider implements TileProvider {
Log.d("saveFilePathURL", newFilePath);
LOKitShell.showProgressSpinner(mContext);
mDocument.saveAs(newFilePath, format, options);
+ final boolean ok;
if (!mOffice.getError().isEmpty()){
+ ok = true;
Log.e("Save Error", mOffice.getError());
if (format.equals("svg")) {
// error in creating temp slideshow svg file
Log.d(LOGTAG, "Error in creating temp slideshow svg file");
} else if(format.equals("pdf")){
Log.d(LOGTAG, "Error in creating pdf file");
- LOKitShell.getMainHandler().post(new Runnable() {
- @Override
- public void run() {
- // There was some error
- mContext.showCustomStatusMessage(mContext.getString(R.string.unable_to_export_pdf));
- }
- });
- }else {
+ } else {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
@@ -311,6 +306,7 @@ class LOKitTileProvider implements TileProvider {
});
}
} else {
+ ok = false;
if (format.equals("svg")) {
// successfully created temp slideshow svg file
LOKitShell.getMainHandler().post(new Runnable() {
@@ -319,52 +315,36 @@ class LOKitTileProvider implements TileProvider {
mContext.startPresentation(newFilePath);
}
});
- }else if(format.equals("pdf")){
- LOKitShell.getMainHandler().post(new Runnable() {
- @Override
- public void run() {
- // There was no error
- mContext.showCustomStatusMessage(mContext.getString(R.string.pdf_exported_at)+filePath);
- }
- });
} else if (takeOwnership) {
mInputFile = filePath;
}
}
LOKitShell.hideProgressSpinner(mContext);
+ return ok;
}
@Override
- public void saveDocumentAs(final String filePath, boolean takeOwnership) {
+ public boolean saveDocumentAs(final String filePath, boolean takeOwnership) {
final int docType = mDocument.getDocumentType();
if (docType == Document.DOCTYPE_TEXT)
- saveDocumentAs(filePath, "odt", takeOwnership);
+ return saveDocumentAs(filePath, "odt", takeOwnership);
else if (docType == Document.DOCTYPE_SPREADSHEET)
- saveDocumentAs(filePath, "ods", takeOwnership);
+ return saveDocumentAs(filePath, "ods", takeOwnership);
else if (docType == Document.DOCTYPE_PRESENTATION)
- saveDocumentAs(filePath, "odp", takeOwnership);
+ return saveDocumentAs(filePath, "odp", takeOwnership);
else if (docType == Document.DOCTYPE_DRAWING)
- saveDocumentAs(filePath, "odg", takeOwnership);
- else
- Log.w(LOGTAG, "Cannot determine file format from document. Not saving.");
+ return saveDocumentAs(filePath, "odg", takeOwnership);
+
+ Log.w(LOGTAG, "Cannot determine file format from document. Not saving.");
+ return false;
}
- public void exportToPDF(boolean print){
- String dir = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Documents";
- File docDir = new File(dir);
- if(!docDir.exists()){
- docDir.mkdir();
- }
+ public void printDocument() {
String mInputFileName = (new File(mInputFile)).getName();
String file = mInputFileName.substring(0,(mInputFileName.length()-3))+"pdf";
- if(print){
- String cacheFile = mContext.getExternalCacheDir().getAbsolutePath()
- + "/" + file;
- mDocument.saveAs("file://"+cacheFile,"pdf","");
- printDocument(cacheFile);
- }else{
- saveDocumentAs(dir+"/"+file,"pdf", false);
- }
+ String cacheFile = mContext.getExternalCacheDir().getAbsolutePath() + "/" + file;
+ mDocument.saveAs("file://"+cacheFile,"pdf","");
+ printDocument(cacheFile);
}
private void printDocument(String cacheFile) {
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 255c4d5bdd95..1812ad253744 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -64,6 +64,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
private static final String ASSETS_EXTRACTED_PREFS_KEY = "ASSETS_EXTRACTED";
private static final String ENABLE_DEVELOPER_PREFS_KEY = "ENABLE_DEVELOPER";
private static final int REQUEST_CODE_SAVEAS = 12345;
+ private static final int REQUEST_CODE_EXPORT_TO_PDF = 12346;
//TODO "public static" is a temporary workaround
public static LOKitThread loKitThread;
@@ -340,6 +341,46 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
toolbarTop.setTitle(displayName);
}
+ public void exportToPDF() {
+ Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType(FileUtilities.MIMETYPE_PDF);
+ intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, mDocumentUri);
+
+ startActivityForResult(intent, REQUEST_CODE_EXPORT_TO_PDF);
+ }
+
+ private void exportToPDF(final Uri uri) {
+ boolean exportOK = false;
+ File tempFile = null;
+ try {
+ tempFile = File.createTempFile("LibreOffice_", ".pdf");
+ mTileProvider.saveDocumentAs(tempFile.getAbsolutePath(),"pdf", false);
+
+ try {
+ FileInputStream inputStream = new FileInputStream(tempFile);
+ exportOK = copyStreamToUri(inputStream, uri);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (tempFile != null && tempFile.exists()) {
+ tempFile.delete();
+ }
+ }
+
+ final int msgId = exportOK ? R.string.pdf_export_finished : R.string.unable_to_export_pdf;
+ LOKitShell.getMainHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ showCustomStatusMessage(getString(msgId));
+ }
+ });
+ }
+
/**
* Returns the ODF MIME type that can be used for the current document,
* regardless of whether the document is an ODF Document or not
@@ -1046,6 +1087,9 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
if (requestCode == REQUEST_CODE_SAVEAS && resultCode == RESULT_OK) {
final Uri fileUri = data.getData();
saveDocumentAs(fileUri);
+ } else if (requestCode == REQUEST_CODE_EXPORT_TO_PDF && resultCode == RESULT_OK) {
+ final Uri fileUri = data.getData();
+ exportToPDF(fileUri);
} else {
mFormattingController.handleActivityResult(requestCode, resultCode, data);
hideBottomToolbar();
diff --git a/android/source/src/java/org/libreoffice/TileProvider.java b/android/source/src/java/org/libreoffice/TileProvider.java
index ea93d5b5c803..c979a9883c13 100644
--- a/android/source/src/java/org/libreoffice/TileProvider.java
+++ b/android/source/src/java/org/libreoffice/TileProvider.java
@@ -29,8 +29,9 @@ public interface TileProvider {
* as compared to just saving a copy of the current document
* or exporting to a different file format.
* Must be 'false' when using this method for export to e.g. PNG or PDF.
+ * @return Whether saving was successful.
*/
- void saveDocumentAs(String filePath, String format, boolean takeOwnership);
+ boolean saveDocumentAs(String filePath, String format, boolean takeOwnership);
/**
* Saves the current document under the given path,
@@ -38,7 +39,7 @@ public interface TileProvider {
* @param takeOwnership (s. documentation for
* 'saveDocumentAs(String filePath, String format, boolean takeOwnership)')
*/
- void saveDocumentAs(String filePath, boolean takeOwnership);
+ boolean saveDocumentAs(String filePath, boolean takeOwnership);
/**
* Returns the page width in pixels.
diff --git a/android/source/src/java/org/libreoffice/ToolbarController.java b/android/source/src/java/org/libreoffice/ToolbarController.java
index ceea83a2b311..1384339f8c30 100644
--- a/android/source/src/java/org/libreoffice/ToolbarController.java
+++ b/android/source/src/java/org/libreoffice/ToolbarController.java
@@ -181,10 +181,10 @@ public class ToolbarController implements Toolbar.OnMenuItemClickListener {
mContext.openDrawer();
return true;
case R.id.action_exportToPDF:
- mContext.getTileProvider().exportToPDF(false);
+ mContext.exportToPDF();
return true;
case R.id.action_print:
- mContext.getTileProvider().exportToPDF(true);
+ mContext.getTileProvider().printDocument();
return true;
case R.id.action_settings:
mContext.showSettings();
diff --git a/android/source/src/java/org/libreoffice/ui/FileUtilities.java b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
index 8422e845dd40..f1581a678c30 100644
--- a/android/source/src/java/org/libreoffice/ui/FileUtilities.java
+++ b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
@@ -42,6 +42,7 @@ public class FileUtilities {
public static final String MIMETYPE_OPENDOCUMENT_SPREADSHEET = "application/vnd.oasis.opendocument.spreadsheet";
public static final String MIMETYPE_OPENDOCUMENT_PRESENTATION = "application/vnd.oasis.opendocument.presentation";
public static final String MIMETYPE_OPENDOCUMENT_GRAPHICS = "application/vnd.oasis.opendocument.graphics";
+ public static final String MIMETYPE_PDF = "application/pdf";
private static final Map<String, Integer> mExtnMap = new HashMap<String, Integer>();
private static final Map<String, String> extensionToMimeTypeMap = new HashMap<String, String>();
commit 5a373d0ea8ba70e5b3ce3f7fb406a1f74f403ad8
Author: Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Thu Apr 15 08:57:56 2021 +0200
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Fri Apr 16 10:16:52 2021 +0200
android: Add a "Save As..." menu entry
This adds a "Save As..." menu entry to Android
Viewer in order to save the currently opened file
to a different location.
Currently, the file is always saved in the corresponding
ODF format, regardless of the original file type,
i.e. that e.g. a DOCX file is saved in ODT format.
(This could be extended to allow a selection of the
target format as needed.)
Like "Save As" (and as compared to "Save a Copy")
in the desktop version, the app remembers the
new document URI and subsequent save operations
will overwrite the newly saved file, not the originally
opened one.
(There is no need to create a new temporary
local file to use, though.)
The directory of the currently used file
is preselected in the file chooser used to
specify where to save the new file.
Make sure to copy the file in a non-main thread,
since the destination URI might be handled
by a DocumentsProvider that does network access.
However, for now the main thread just waits for
the separate thread to finish, just like
commit 7f838b73e85eb6f0a1dce4647650a5cf5f34ccd2
Date: Fri Mar 19 15:46:36 2021 +0100
tdf#129833 android: Move reading file to separate thread
implemented it for copying from the URI to the
temporary file when opening a file.
This also adds a 'TileProvider#isDrawing' method
(like the already existing 'isTextDocument',
'isSpreadsheet' and 'isPresentation' ones).
Change-Id: I6f56b71763431b89a6c74be35cc1e81fad136cd0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114058
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
(cherry picked from commit d16e569209fe40c2cb5776f7b9415e273d5b2387)
diff --git a/android/source/res/menu/main.xml b/android/source/res/menu/main.xml
index 2c97b3201b9e..94856d52e759 100644
--- a/android/source/res/menu/main.xml
+++ b/android/source/res/menu/main.xml
@@ -36,6 +36,10 @@
android:title="@string/action_save"
android:orderInCategory="100" />
+ <item android:id="@+id/action_save_as"
+ android:title="@string/action_save_as"
+ android:orderInCategory="100" />
+
<item android:id="@+id/action_exportToPDF"
android:title="@string/action_exportToPDF"
android:orderInCategory="100"
diff --git a/android/source/res/values-de/strings.xml b/android/source/res/values-de/strings.xml
index 639ddca4d9ef..c2c33ff5b5e5 100644
--- a/android/source/res/values-de/strings.xml
+++ b/android/source/res/values-de/strings.xml
@@ -48,6 +48,7 @@
<string name="action_strikeout">Durchgestrichen</string>
<string name="action_keyboard">Tastatur anzeigen</string>
<string name="action_save">Speichern</string>
+ <string name="action_save_as">Speichern unter...</string>
<string name="action_fromat">Format anwenden</string>
<string name="action_search">Suchen</string>
<string name="action_UNO_commands">UNO-Kommando senden</string>
diff --git a/android/source/res/values/strings.xml b/android/source/res/values/strings.xml
index 5e7ad1e3ded7..d0014646bc15 100644
--- a/android/source/res/values/strings.xml
+++ b/android/source/res/values/strings.xml
@@ -47,6 +47,7 @@
<string name="action_strikeout">Strike Out</string>
<string name="action_keyboard">Show keyboard</string>
<string name="action_save">Save</string>
+ <string name="action_save_as">Save As...</string>
<string name="action_fromat">Enable Format</string>
<string name="action_search">Search</string>
<string name="action_UNO_commands">Send UNO Cmd</string>
diff --git a/android/source/src/java/org/libreoffice/LOKitTileProvider.java b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
index 2fb3551eada2..5f4684703f36 100644
--- a/android/source/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
@@ -631,6 +631,14 @@ class LOKitTileProvider implements TileProvider {
}
}
+ /**
+ * @see TileProvider#isDrawing()
+ */
+ @Override
+ public boolean isDrawing() {
+ return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_DRAWING;
+ }
+
/**
* @see TileProvider#isTextDocument()
*/
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index d97719afb726..255c4d5bdd95 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -14,6 +14,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
+import android.provider.DocumentsContract;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.Snackbar;
import android.support.v4.widget.DrawerLayout;
@@ -62,6 +63,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
private static final String ENABLE_EXPERIMENTAL_PREFS_KEY = "ENABLE_EXPERIMENTAL";
private static final String ASSETS_EXTRACTED_PREFS_KEY = "ASSETS_EXTRACTED";
private static final String ENABLE_DEVELOPER_PREFS_KEY = "ENABLE_DEVELOPER";
+ private static final int REQUEST_CODE_SAVEAS = 12345;
//TODO "public static" is a temporary workaround
public static LOKitThread loKitThread;
@@ -309,6 +311,56 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND_NOTIFY, ".uno:Save", true));
}
+ /**
+ * Open file chooser and save the document to the URI
+ * selected there.
+ */
+ public void saveDocumentAs() {
+ Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ String mimeType = getODFMimeTypeForDocument();
+ intent.setType(mimeType);
+ intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, mDocumentUri);
+
+ startActivityForResult(intent, REQUEST_CODE_SAVEAS);
+ }
+
+ /**
+ * Saves the document under the given URI using ODF format
+ * and uses that URI from now on for all operations.
+ * @param newUri URI to save the document and use from now on.
+ */
+ private void saveDocumentAs(Uri newUri) {
+ mDocumentUri = newUri;
+ // save in ODF format
+ mTileProvider.saveDocumentAs(mTempFile.getPath(), true);
+ saveFileToOriginalSource();
+
+ String displayName = FileUtilities.retrieveDisplayNameForDocumentUri(getContentResolver(), mDocumentUri);
+ toolbarTop.setTitle(displayName);
+ }
+
+ /**
+ * Returns the ODF MIME type that can be used for the current document,
+ * regardless of whether the document is an ODF Document or not
+ * (e.g. returns FileUtilities.MIMETYPE_OPENDOCUMENT_TEXT for a DOCX file).
+ * @return MIME type, or empty string, if no appropriate MIME type could be found.
+ */
+ private String getODFMimeTypeForDocument() {
+ if (mTileProvider.isTextDocument())
+ return FileUtilities.MIMETYPE_OPENDOCUMENT_TEXT;
+ else if (mTileProvider.isSpreadsheet())
+ return FileUtilities.MIMETYPE_OPENDOCUMENT_SPREADSHEET;
+ else if (mTileProvider.isPresentation())
+ return FileUtilities.MIMETYPE_OPENDOCUMENT_PRESENTATION;
+ else if (mTileProvider.isDrawing())
+ return FileUtilities.MIMETYPE_OPENDOCUMENT_GRAPHICS;
+ else {
+ Log.w(LOGTAG, "Cannot determine MIME type to use.");
+ return "";
+ }
+ }
+
public void saveFileToOriginalSource() {
if (isReadOnlyMode() || mTempFile == null || mDocumentUri == null || !mDocumentUri.getScheme().equals(ContentResolver.SCHEME_CONTENT))
return;
@@ -316,8 +368,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
boolean copyOK = false;
try {
final FileInputStream inputStream = new FileInputStream(mTempFile);
- final OutputStream outputStream = getContentResolver().openOutputStream(mDocumentUri);
- copyOK = copyStream(inputStream, outputStream);
+ copyOK = copyStreamToUri(inputStream, mDocumentUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
@@ -922,6 +973,40 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
return copyThread.result;
}
+ /**
+ * Copies everything from the given InputStream to the given URI and closes the
+ * InputStream in the end.
+ * @see LibreOfficeMainActivity#copyUriToStream(Uri, OutputStream)
+ * which does the same thing the other way around.
+ */
+ private boolean copyStreamToUri(final InputStream inputStream, final Uri outputUri) {
+ class CopyThread extends Thread {
+ /** Whether copy operation was successful. */
+ private boolean result = false;
+
+ @Override
+ public void run() {
+ final ContentResolver contentResolver = getContentResolver();
+ try {
+ OutputStream outputStream = contentResolver.openOutputStream(outputUri);
+ result = copyStream(inputStream, outputStream);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ CopyThread copyThread = new CopyThread();
+ copyThread.start();
+ try {
+ // wait for copy operation to finish
+ // NOTE: might be useful to add some indicator in UI for long copy operations involving network...
+ copyThread.join();
+ } catch(InterruptedException e) {
+ e.printStackTrace();
+ }
+ return copyThread.result;
+ }
+
public void showCustomStatusMessage(String message){
Snackbar.make(mDrawerLayout, message, Snackbar.LENGTH_LONG).show();
}
@@ -958,8 +1043,13 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- mFormattingController.handleActivityResult(requestCode, resultCode, data);
- hideBottomToolbar();
+ if (requestCode == REQUEST_CODE_SAVEAS && resultCode == RESULT_OK) {
+ final Uri fileUri = data.getData();
+ saveDocumentAs(fileUri);
+ } else {
+ mFormattingController.handleActivityResult(requestCode, resultCode, data);
+ hideBottomToolbar();
+ }
}
}
diff --git a/android/source/src/java/org/libreoffice/TileProvider.java b/android/source/src/java/org/libreoffice/TileProvider.java
index 1a20c8b080d0..ea93d5b5c803 100644
--- a/android/source/src/java/org/libreoffice/TileProvider.java
+++ b/android/source/src/java/org/libreoffice/TileProvider.java
@@ -85,6 +85,11 @@ public interface TileProvider {
*/
void close();
+ /**
+ * Returns true if the current open document is a drawing.
+ */
+ boolean isDrawing();
+
/**
* Returns true if the current open document is a text document.
*/
diff --git a/android/source/src/java/org/libreoffice/ToolbarController.java b/android/source/src/java/org/libreoffice/ToolbarController.java
index 308bc9e6b254..ceea83a2b311 100644
--- a/android/source/src/java/org/libreoffice/ToolbarController.java
+++ b/android/source/src/java/org/libreoffice/ToolbarController.java
@@ -174,6 +174,9 @@ public class ToolbarController implements Toolbar.OnMenuItemClickListener {
case R.id.action_save:
mContext.getTileProvider().saveDocument();
return true;
+ case R.id.action_save_as:
+ mContext.saveDocumentAs();
+ return true;
case R.id.action_parts:
mContext.openDrawer();
return true;
diff --git a/android/source/src/java/org/libreoffice/ui/FileUtilities.java b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
index 5bcc48d31141..8422e845dd40 100644
--- a/android/source/src/java/org/libreoffice/ui/FileUtilities.java
+++ b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
@@ -38,6 +38,11 @@ public class FileUtilities {
public static final String DEFAULT_SPREADSHEET_EXTENSION = ".ods";
public static final String DEFAULT_DRAWING_EXTENSION = ".odg";
+ public static final String MIMETYPE_OPENDOCUMENT_TEXT = "application/vnd.oasis.opendocument.text";
+ public static final String MIMETYPE_OPENDOCUMENT_SPREADSHEET = "application/vnd.oasis.opendocument.spreadsheet";
+ public static final String MIMETYPE_OPENDOCUMENT_PRESENTATION = "application/vnd.oasis.opendocument.presentation";
+ public static final String MIMETYPE_OPENDOCUMENT_GRAPHICS = "application/vnd.oasis.opendocument.graphics";
+
private static final Map<String, Integer> mExtnMap = new HashMap<String, Integer>();
private static final Map<String, String> extensionToMimeTypeMap = new HashMap<String, String>();
static {
@@ -101,14 +106,14 @@ public class FileUtilities {
// Android's MimeTypeMap lacks some types that we need
extensionToMimeTypeMap.put("odb", "application/vnd.oasis.opendocument.database");
extensionToMimeTypeMap.put("odf", "application/vnd.oasis.opendocument.formula");
- extensionToMimeTypeMap.put("odg", "application/vnd.oasis.opendocument.graphics");
+ extensionToMimeTypeMap.put("odg", MIMETYPE_OPENDOCUMENT_GRAPHICS);
extensionToMimeTypeMap.put("otg", "application/vnd.oasis.opendocument.graphics-template");
extensionToMimeTypeMap.put("odi", "application/vnd.oasis.opendocument.image");
- extensionToMimeTypeMap.put("odp", "application/vnd.oasis.opendocument.presentation");
+ extensionToMimeTypeMap.put("odp", MIMETYPE_OPENDOCUMENT_PRESENTATION);
extensionToMimeTypeMap.put("otp", "application/vnd.oasis.opendocument.presentation-template");
- extensionToMimeTypeMap.put("ods", "application/vnd.oasis.opendocument.spreadsheet");
+ extensionToMimeTypeMap.put("ods", MIMETYPE_OPENDOCUMENT_SPREADSHEET);
extensionToMimeTypeMap.put("ots", "application/vnd.oasis.opendocument.spreadsheet-template");
- extensionToMimeTypeMap.put("odt", "application/vnd.oasis.opendocument.text");
+ extensionToMimeTypeMap.put("odt", MIMETYPE_OPENDOCUMENT_TEXT);
extensionToMimeTypeMap.put("odm", "application/vnd.oasis.opendocument.text-master");
extensionToMimeTypeMap.put("ott", "application/vnd.oasis.opendocument.text-template");
extensionToMimeTypeMap.put("oth", "application/vnd.oasis.opendocument.text-web");
commit 514e2b142f8c2d015996e333663ae4eb20bdbc65
Author: Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Thu Apr 15 08:38:46 2021 +0200
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Fri Apr 16 10:16:43 2021 +0200
android: Extract copying Uri to stream in thread to separate method
This essentially extracts what
commit 7f838b73e85eb6f0a1dce4647650a5cf5f34ccd2
Date: Fri Mar 19 15:46:36 2021 +0100
tdf#129833 android: Move reading file to separate thread
introduced into a separate helper method.
Change-Id: Ic70ba9f2e2bc125415ff1b3fa3375c3389181c43
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114123
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
(cherry picked from commit a2b4564d719e6efeb614052b9c833991e447c68c)
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index a3f62601c1c4..d97719afb726 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -282,7 +282,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
}
private boolean copyFileToTemp() {
- final ContentResolver contentResolver = getContentResolver();
// CSV files need a .csv suffix to be opened in Calc.
String suffix = null;
String intentType = getIntent().getType();
@@ -293,36 +292,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
try {
mTempFile = File.createTempFile("LibreOffice", suffix, this.getCacheDir());
final FileOutputStream outputStream = new FileOutputStream(mTempFile);
- // need to run copy operation in a separate thread, since network access is not
- // allowed from main thread, but that may happen here when underlying
- // DocumentsProvider (like the NextCloud one) does that
- class CopyThread extends Thread {
- /** Whether copy operation was successful. */
- private boolean result = false;
-
- @Override
- public void run() {
- result = false;
- try {
- InputStream inputStream = contentResolver.openInputStream(mDocumentUri);
- result = copyStream(inputStream, outputStream);
- } catch (IOException e) {
- e.printStackTrace();
- return;
- }
- }
- };
- CopyThread copyThread = new CopyThread();
- copyThread.start();
- try {
- // wait for copy operation to finish
- // NOTE: might be useful to add some indicator in UI for long copy operations involving network...
- copyThread.join();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- return copyThread.result;
+ return copyUriToStream(mDocumentUri, outputStream);
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
@@ -915,6 +885,43 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
}
}
+ /**
+ * Copies everything from the given Uri to the given OutputStream
+ * and closes the OutputStream in the end.
+ * The copy operation runs in a separate thread, but the method only returns
+ * after the thread has finished its execution.
+ * This can be used to copy in a blocking way when network access is involved,
+ * which is not allowed from the main thread, but that may happen when an underlying
+ * DocumentsProvider (like the NextCloud one) does network access.
+ */
+ private boolean copyUriToStream(final Uri inputUri, final OutputStream outputStream) {
+ class CopyThread extends Thread {
+ /** Whether copy operation was successful. */
+ private boolean result = false;
+
+ @Override
+ public void run() {
+ final ContentResolver contentResolver = getContentResolver();
+ try {
+ InputStream inputStream = contentResolver.openInputStream(inputUri);
+ result = copyStream(inputStream, outputStream);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ CopyThread copyThread = new CopyThread();
+ copyThread.start();
+ try {
+ // wait for copy operation to finish
+ // NOTE: might be useful to add some indicator in UI for long copy operations involving network...
+ copyThread.join();
+ } catch(InterruptedException e) {
+ e.printStackTrace();
+ }
+ return copyThread.result;
+ }
+
public void showCustomStatusMessage(String message){
Snackbar.make(mDrawerLayout, message, Snackbar.LENGTH_LONG).show();
}
commit d8fa465abebd129d500b0dd0b9e1b05ba2c8b99e
Author: Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Tue Apr 13 07:55:54 2021 +0200
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Fri Apr 16 10:16:33 2021 +0200
android: Don't store whether spreadsheet in LibreOfficeMainActivity
LOKitTileProvider has that information, so query it instead
and don't duplicate information in LibreOfficeMainActivity.
Change-Id: I233986d6e94e5676464cb3399303efd545e33d32
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114057
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
(cherry picked from commit 4db8535fba00c476555e09e32e521993ab77dc4d)
diff --git a/android/source/src/java/org/libreoffice/FontController.java b/android/source/src/java/org/libreoffice/FontController.java
index a00e13e1485c..8729b51e01ac 100644
--- a/android/source/src/java/org/libreoffice/FontController.java
+++ b/android/source/src/java/org/libreoffice/FontController.java
@@ -158,7 +158,7 @@ public class FontController implements AdapterView.OnItemSelectedListener {
JSONObject valueJson = new JSONObject();
valueJson.put("type", "long");
valueJson.put("value", 0x00FFFFFF & color);
- if(mActivity.isSpreadsheet()){
+ if(mActivity.getTileProvider().isSpreadsheet()){
json.put("BackgroundColor", valueJson);
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:BackgroundColor", json.toString()));
}else if(mActivity.getTileProvider().isPresentation()){
diff --git a/android/source/src/java/org/libreoffice/InvalidationHandler.java b/android/source/src/java/org/libreoffice/InvalidationHandler.java
index 588fec9f5372..b74d92d15460 100644
--- a/android/source/src/java/org/libreoffice/InvalidationHandler.java
+++ b/android/source/src/java/org/libreoffice/InvalidationHandler.java
@@ -505,7 +505,7 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
changeStateTo(OverlayState.TRANSITION);
}
mDocumentOverlay.changeSelections(Collections.<RectF>emptyList());
- if (mContext.isSpreadsheet()) {
+ if (mContext.getTileProvider().isSpreadsheet()) {
mDocumentOverlay.showHeaderSelection(null);
}
mContext.getToolbarController().showHideClipboardCutAndCopy(false);
@@ -516,7 +516,7 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
}
changeStateTo(OverlayState.SELECTION);
mDocumentOverlay.changeSelections(rectangles);
- if (mContext.isSpreadsheet()) {
+ if (mContext.getTileProvider().isSpreadsheet()) {
mDocumentOverlay.showHeaderSelection(rectangles.get(0));
}
String selectedText = mContext.getTileProvider().getTextSelection("");
diff --git a/android/source/src/java/org/libreoffice/LOKitShell.java b/android/source/src/java/org/libreoffice/LOKitShell.java
index 43dd30a69847..5fb7159f1032 100644
--- a/android/source/src/java/org/libreoffice/LOKitShell.java
+++ b/android/source/src/java/org/libreoffice/LOKitShell.java
@@ -27,7 +27,9 @@ public class LOKitShell {
private static final String LOGTAG = LOKitShell.class.getSimpleName();
public static float getDpi(Context context) {
- if (((LibreOfficeMainActivity)context).isSpreadsheet()) return 96f;
+ LOKitTileProvider tileProvider = ((LibreOfficeMainActivity)context).getTileProvider();
+ if (tileProvider != null && tileProvider.isSpreadsheet())
+ return 96f;
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return metrics.density * 160;
}
diff --git a/android/source/src/java/org/libreoffice/LOKitTileProvider.java b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
index e9fc2d52a154..2fb3551eada2 100644
--- a/android/source/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
@@ -102,10 +102,6 @@ class LOKitTileProvider implements TileProvider {
Log.i(LOGTAG, "====> mDocument = " + mDocument);
- if(isSpreadsheet()) {
- mContext.setIsSpreadsheet(true); // Calc is treated differently e.g. DPI = 96f
- }
-
mDPI = LOKitShell.getDpi(mContext);
mTileWidth = pixelToTwip(TILE_SIZE, mDPI);
mTileHeight = pixelToTwip(TILE_SIZE, mDPI);
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index f751f2e7dd61..a3f62601c1c4 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -94,7 +94,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
private SearchController mSearchController;
private UNOCommandsController mUNOCommandsController;
private CalcHeadersController mCalcHeadersController;
- private boolean mIsSpreadsheet;
private LOKitTileProvider mTileProvider;
private String mPassword;
private boolean mPasswordProtected;
@@ -815,14 +814,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
});
}
- public void setIsSpreadsheet(boolean b) {
- mIsSpreadsheet = b;
- }
-
- public boolean isSpreadsheet() {
- return mIsSpreadsheet;
- }
-
public static boolean isReadOnlyMode() {
return mbISReadOnlyMode;
}
More information about the Libreoffice-commits
mailing list