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 7d9db806d6
    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@posteo.de>
This commit is contained in:
Michael Weghorn
2021-04-16 08:48:28 +02:00
parent d16e569209
commit 9ebcb80e2e
8 changed files with 70 additions and 45 deletions
+1 -1
View File
@@ -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>
-1
View File
@@ -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>
+1 -1
View File
@@ -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>
@@ -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) {
@@ -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();
@@ -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.
@@ -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();
@@ -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>();