55#include < odr/html.hpp>
66#include < odr/odr.hpp>
77#include < odr/exceptions.hpp>
8+ #include < odr/html_service.hpp>
89#include < odr/http_server.hpp>
910#include < odr/global_params.hpp>
1011
@@ -18,7 +19,7 @@ namespace {
1819
1920std::string convertString (JNIEnv *env, jstring string) {
2021 jboolean isCopy;
21- const char * cstring = env->GetStringUTFChars (string, &isCopy);
22+ const char * cstring = env->GetStringUTFChars (string, &isCopy);
2223 auto cppstring = std::string (cstring, env->GetStringUTFLength (string));
2324 env->ReleaseStringUTFChars (string, cstring);
2425 return cppstring;
@@ -37,7 +38,7 @@ std::string getStringField(JNIEnv *env, jobject object, const char *name) {
3738
3839}
3940
40- std::optional<odr::Html> s_html ;
41+ std::optional<odr::Document> s_document ;
4142
4243JNIEXPORT void JNICALL
4344Java_at_tomtasche_reader_background_CoreWrapper_setGlobalParams (JNIEnv *env, jclass clazz,
@@ -126,26 +127,6 @@ Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass
126127 __android_log_print (ANDROID_LOG_VERBOSE, " smn" , " Open %s" , inputPathCpp.c_str ());
127128
128129 const auto file = odr::open (inputPathCpp);
129- const auto fileCategory = odr::category_by_type (file.file_type ());
130-
131- if (!ooxml &&
132- (file.file_type () == odr::FileType::office_open_xml_document ||
133- file.file_type () == odr::FileType::office_open_xml_workbook ||
134- file.file_type () == odr::FileType::office_open_xml_presentation ||
135- file.file_type () == odr::FileType::office_open_xml_encrypted)) {
136- env->SetIntField (result, errorField, -5 );
137- return result;
138- }
139-
140- if (!txt && fileCategory == odr::FileCategory::text) {
141- env->SetIntField (result, errorField, -5 );
142- return result;
143- }
144-
145- if (!pdf && file.file_type () == odr::FileType::portable_document_format) {
146- env->SetIntField (result, errorField, -5 );
147- return result;
148- }
149130
150131 if (file.is_document_file ()) {
151132 odr::DocumentFile document_file = file.document_file ();
@@ -155,6 +136,8 @@ Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass
155136 return result;
156137 }
157138 }
139+ // TODO this will cause a second load
140+ s_document = document_file.document ();
158141 }
159142
160143 extensionCpp = odr::type_to_string (file.file_type ());
@@ -163,16 +146,17 @@ Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass
163146
164147 odr::HtmlConfig config;
165148 config.editable = editable;
166-
167- if (paging) {
168- config.text_document_margin = true ;
169- }
149+ config.text_document_margin = paging;
170150
171151 __android_log_print (ANDROID_LOG_VERBOSE, " smn" , " Translate to HTML" );
172152
173- s_html = odr::html::translate (file, outputPathCpp, config);
153+ std::string output_tmp = outputPathCpp + " /tmp" ;
154+ std::filesystem::create_directories (output_tmp);
155+ odr::HtmlService service = odr::html::translate (file, output_tmp, config);
156+ odr::Html html = service.bring_offline (outputPathCpp);
157+ std::filesystem::remove_all (output_tmp);
174158
175- for (auto && page: s_html-> pages ()) {
159+ for (const odr::HtmlPage & page: html. pages ()) {
176160 jstring pageName = env->NewStringUTF (page.name .c_str ());
177161 env->CallBooleanMethod (pageNames, addMethod, pageName);
178162
@@ -192,7 +176,8 @@ Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass
192176 env->SetIntField (result, errorField, -4 );
193177 return result;
194178 } catch (...) {
195- __android_log_print (ANDROID_LOG_ERROR, " smn" , " Unhandled C++ exception without further information" );
179+ __android_log_print (ANDROID_LOG_ERROR, " smn" ,
180+ " Unhandled C++ exception without further information" );
196181 env->SetIntField (result, errorField, -4 );
197182 return result;
198183 }
@@ -215,13 +200,18 @@ Java_at_tomtasche_reader_background_CoreWrapper_backtranslateNative(JNIEnv *env,
215200
216201 jfieldID errorField = env->GetFieldID (resultClass, " errorCode" , " I" );
217202
203+ if (!s_document.has_value ()) {
204+ env->SetIntField (result, errorField, -1 );
205+ return result;
206+ }
207+
218208 try {
219209 std::string outputPathPrefixCpp = getStringField (env, options, " outputPath" );
220210
221211 jboolean isCopy;
222212 const auto htmlDiffC = env->GetStringUTFChars (htmlDiff, &isCopy);
223213
224- const auto extension = odr::type_to_string (s_html ->file_type ());
214+ const auto extension = odr::type_to_string (s_document ->file_type ());
225215 const auto outputPathCpp = outputPathPrefixCpp + " ." + extension;
226216 const char *outputPathC = outputPathCpp.c_str ();
227217 jstring outputPath = env->NewStringUTF (outputPathC);
@@ -230,7 +220,7 @@ Java_at_tomtasche_reader_background_CoreWrapper_backtranslateNative(JNIEnv *env,
230220 env->SetObjectField (result, outputPathField, outputPath);
231221
232222 try {
233- s_html-> edit (htmlDiffC);
223+ odr::html:: edit (*s_document, htmlDiffC);
234224
235225 env->ReleaseStringUTFChars (htmlDiff, htmlDiffC);
236226 } catch (...) {
@@ -241,7 +231,7 @@ Java_at_tomtasche_reader_background_CoreWrapper_backtranslateNative(JNIEnv *env,
241231 }
242232
243233 try {
244- s_html ->save (outputPathCpp);
234+ s_document ->save (outputPathCpp);
245235 } catch (...) {
246236 env->SetIntField (result, errorField, -7 );
247237 return result;
@@ -258,26 +248,28 @@ Java_at_tomtasche_reader_background_CoreWrapper_backtranslateNative(JNIEnv *env,
258248JNIEXPORT void JNICALL
259249Java_at_tomtasche_reader_background_CoreWrapper_closeNative (JNIEnv *env, jclass clazz,
260250 jobject options) {
261- s_html .reset ();
251+ s_document .reset ();
262252}
263253
264254std::optional<odr::HttpServer> s_server;
265255
266256JNIEXPORT void JNICALL
267- Java_at_tomtasche_reader_background_CoreWrapper_createServer (JNIEnv *env, jclass clazz, jstring outputPath) {
257+ Java_at_tomtasche_reader_background_CoreWrapper_createServer (JNIEnv *env, jclass clazz,
258+ jstring cachePath) {
268259 __android_log_print (ANDROID_LOG_INFO, " smn" , " create server" );
269260
270- std::string output_path = convertString (env, outputPath );
261+ std::string cachePathCpp = convertString (env, cachePath );
271262
272- std::filesystem::create_directories (output_path );
263+ std::filesystem::create_directories (cachePathCpp );
273264
274265 odr::HttpServer::Config config;
275- config.output_path = output_path ;
266+ config.cache_path = cachePathCpp ;
276267 s_server = odr::HttpServer (config);
277268}
278269
279270JNIEXPORT jobject JNICALL
280- Java_at_tomtasche_reader_background_CoreWrapper_hostFile (JNIEnv *env, jclass clazz, jstring prefix, jobject options) {
271+ Java_at_tomtasche_reader_background_CoreWrapper_hostFile (JNIEnv *env, jclass clazz, jstring prefix,
272+ jobject options) {
281273 __android_log_print (ANDROID_LOG_INFO, " smn" , " host file" );
282274
283275 jclass resultClass = env->FindClass (" at/tomtasche/reader/background/CoreWrapper$CoreResult" );
@@ -286,6 +278,28 @@ Java_at_tomtasche_reader_background_CoreWrapper_hostFile(JNIEnv *env, jclass cla
286278
287279 jfieldID errorField = env->GetFieldID (resultClass, " errorCode" , " I" );
288280
281+ if (!s_server.has_value ()) {
282+ env->SetIntField (result, errorField, -1 );
283+ return result;
284+ }
285+
286+ s_server->clear ();
287+
288+ jclass optionsClass = env->GetObjectClass (options);
289+
290+ std::optional<std::string> passwordCpp;
291+ jfieldID passwordField = env->GetFieldID (optionsClass, " password" , " Ljava/lang/String;" );
292+ auto password = (jstring) env->GetObjectField (options, passwordField);
293+ if (password != nullptr ) {
294+ passwordCpp = convertString (env, password);
295+ }
296+
297+ jfieldID pagingField = env->GetFieldID (optionsClass, " paging" , " Z" );
298+ jboolean paging = env->GetBooleanField (options, pagingField);
299+
300+ jfieldID editableField = env->GetFieldID (optionsClass, " editable" , " Z" );
301+ jboolean editable = env->GetBooleanField (options, editableField);
302+
289303 jclass listClass = env->FindClass (" java/util/List" );
290304 jmethodID addMethod = env->GetMethodID (listClass, " add" , " (Ljava/lang/Object;)Z" );
291305
@@ -299,34 +313,56 @@ Java_at_tomtasche_reader_background_CoreWrapper_hostFile(JNIEnv *env, jclass cla
299313 std::string prefixCpp = convertString (env, prefix);
300314
301315 odr::DecodePreference decodePreference;
302- decodePreference.engine_priority = {odr::DecoderEngine::poppler, odr::DecoderEngine::wvware, odr::DecoderEngine::odr};
316+ decodePreference.engine_priority = {odr::DecoderEngine::poppler, odr::DecoderEngine::wvware,
317+ odr::DecoderEngine::odr};
303318 odr::DecodedFile file = odr::open (inputPathCpp, decodePreference);
304319
320+ if (file.is_document_file ()) {
321+ odr::DocumentFile document_file = file.document_file ();
322+ if (document_file.password_encrypted ()) {
323+ if (!passwordCpp.has_value () || !document_file.decrypt (passwordCpp.value ())) {
324+ env->SetIntField (result, errorField, -2 );
325+ return result;
326+ }
327+ }
328+ // TODO this will cause a second load
329+ s_document = document_file.document ();
330+ }
331+
305332 odr::HtmlConfig htmlConfig;
306333 htmlConfig.embed_images = false ;
307- htmlConfig.embed_shipped_resources = false ;
334+ htmlConfig.embed_shipped_resources = true ;
335+ htmlConfig.relative_resource_paths = false ;
336+ htmlConfig.text_document_margin = paging;
337+ htmlConfig.editable = editable;
308338
309339 try {
310- odr::HtmlViews htmlViews = s_server->serve_file (file, prefixCpp, odr::HtmlConfig () );
340+ odr::HtmlViews htmlViews = s_server->serve_file (file, prefixCpp, htmlConfig );
311341
312342 for (const auto &view: htmlViews) {
313- if (file.is_document_file () &&
314- file.document_file ().document_type () != odr::DocumentType::text &&
315- view.name () == " document" ) {
343+ __android_log_print (ANDROID_LOG_INFO, " smn" , " view name=%s path=%s" , view.name ().c_str (), view.path ().c_str ());
344+ if (file.is_document_file () && (
345+ (((file.document_file ().document_type () == odr::DocumentType::presentation) ||
346+ (file.document_file ().document_type () == odr::DocumentType::drawing)) &&
347+ (view.name () != " document" )) ||
348+ ((file.document_file ().document_type () == odr::DocumentType::spreadsheet) &&
349+ (view.name () == " document" )))) {
316350 continue ;
317351 }
318352
319353 jstring pageName = env->NewStringUTF (view.name ().c_str ());
320354 env->CallBooleanMethod (pageNames, addMethod, pageName);
321355
322- std::string pagePathCpp = " http://localhost:29665/file/" + prefixCpp + " /" + view.path ();
356+ std::string pagePathCpp =
357+ " http://localhost:29665/file/" + prefixCpp + " /" + view.path ();
323358 jstring pagePath = env->NewStringUTF (pagePathCpp.c_str ());
324359 env->CallBooleanMethod (pagePaths, addMethod, pagePath);
325360 }
326361 } catch (const std::exception &e) {
327362 __android_log_print (ANDROID_LOG_ERROR, " smn" , " Unhandled C++ exception: %s" , e.what ());
328363 } catch (...) {
329- __android_log_print (ANDROID_LOG_ERROR, " smn" , " Unhandled C++ exception without further information" );
364+ __android_log_print (ANDROID_LOG_ERROR, " smn" ,
365+ " Unhandled C++ exception without further information" );
330366 }
331367
332368 return result;
0 commit comments