diff options
8 files changed, 125 insertions, 8 deletions
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 @@ -632,6 +632,14 @@ class LOKitTileProvider implements TileProvider { } /** + * @see TileProvider#isDrawing() + */ + @Override + public boolean isDrawing() { + return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_DRAWING; + } + + /** * @see TileProvider#isTextDocument() */ @Override 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 @@ -86,6 +86,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. */ boolean isTextDocument(); 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"); |