Bug 163748 - Setting PageStyle property "BackGraphic" by UNO JAVA API, but nothing happened
Summary: Setting PageStyle property "BackGraphic" by UNO JAVA API, but nothing happened
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: sdk (show other bugs)
Version:
(earliest affected)
24.8.2.1 release
Hardware: x86-64 (AMD64) Windows (All)
: medium normal
Assignee: Mike Kaganski
URL:
Whiteboard: target:25.2.0
Keywords:
Depends on:
Blocks:
 
Reported: 2024-11-03 11:24 UTC by Heesu Ban
Modified: 2024-11-06 19:27 UTC (History)
0 users

See Also:
Crash report or crash signature:


Attachments
test source code (11.06 KB, text/plain)
2024-11-03 11:24 UTC, Heesu Ban
Details
PNG image file (9.08 KB, image/png)
2024-11-03 11:24 UTC, Heesu Ban
Details
ODT doesn't showed any background image (9.94 KB, application/vnd.oasis.opendocument.text)
2024-11-03 15:25 UTC, Heesu Ban
Details
zipped testing java project (16.08 KB, application/x-zip-compressed)
2024-11-05 15:11 UTC, Heesu Ban
Details
debugging guide of provided sample (262.78 KB, application/vnd.oasis.opendocument.text)
2024-11-05 15:12 UTC, Heesu Ban
Details
class compiled with JDK8 (16.36 KB, application/x-zip-compressed)
2024-11-06 15:17 UTC, Heesu Ban
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Heesu Ban 2024-11-03 11:24:06 UTC
Created attachment 197369 [details]
test source code

Hello,

I develope an extension named H2Orestart writing with Java.
I encountered an issue that "BackGraphic" property of PageStyle not working than I expected.

I tried to read png file and get XGraphic interface, then put it as "BackGraphic". but NO background image appeared.

I doubt "BackGraphic" is not working.
Not sure if I used UNO API correctly, but other than "BackGraphic" properties working as I expected.

Attached sample java code and png file.

Thank you in advance.
Comment 1 Heesu Ban 2024-11-03 11:24:55 UTC
Created attachment 197370 [details]
PNG image file
Comment 2 Mike Kaganski 2024-11-03 12:12:01 UTC
Can't test Java; but just a question - why use the byte array, instead of providing a single URL property in the 'v' PropertyValue array?
Comment 3 Mike Kaganski 2024-11-03 12:19:51 UTC
For the reference: the following Basic code (modelled after yours, with the important difference of constructing the image using URL, not byte stream) works fine for me (the file path is, of course, local to my system):

 const MY_PAGE_STYLE_NAME = "MasterPage0"
 doc = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, array())
 xPageStyle = doc.createInstance("com.sun.star.style.PageStyle")
 xFamilies = doc.getStyleFamilies()
 xFamily = xFamilies.getByName("PageStyles")
 if (xFamily.hasByName(MY_PAGE_STYLE_NAME) = false) then
  xFamily.insertByName(MY_PAGE_STYLE_NAME, xPageStyle)
 endif

 mText = doc.getText()
 mTextCursor = mText.createTextCursor()
 mTextCursor.setPropertyValue("PageDescName", MY_PAGE_STYLE_NAME)

 xPageStyle.setPropertyValue("Width", 21000)
 xPageStyle.setPropertyValue("Height", 29700)
 xPageStyle.setPropertyValue("LeftMargin", 3000)
 xPageStyle.setPropertyValue("RightMargin", 3000)
 xPageStyle.setPropertyValue("TopMargin", 2000)
 xPageStyle.setPropertyValue("HeaderIsOn", true)
 xPageStyle.setPropertyValue("HeaderHeight", 1500)
 xPageStyle.setPropertyValue("HeaderBodyDistance", 0)
 xPageStyle.setPropertyValue("BottomMargin", 1500)
 xPageStyle.setPropertyValue("FooterIsOn", true)
 xPageStyle.setPropertyValue("FooterHeight", 1500)
 xPageStyle.setPropertyValue("FooterBodyDistance", 0)
 xPageStyle.setPropertyValue("HeaderBackColor", &he8f2a1)
 xPageStyle.setPropertyValue("FooterBackColor", &hffdbb6)

 xGraphicProvider = CreateUnoService("com.sun.star.graphic.GraphicProvider")
 Dim v(0) as new com.sun.star.beans.PropertyValue
 v(0).Name = "URL"
 v(0).Value = ConvertToURL("C:\D\Downloads\BackImage.png")
 graphic = xGraphicProvider.queryGraphic(v)

 xPageStyle.setPropertyValue("BackGraphic", graphic)

 xPageStyle.setPropertyValue("BackTransparent", false)
 xPageStyle.setPropertyValue("BackGraphicLocation", com.sun.star.style.GraphicLocation.AREA)
 xPageStyle.setPropertyValue("BackgroundFullSize", false)
Comment 4 Mike Kaganski 2024-11-03 12:29:47 UTC
As an aside: your code to convert a system path to URL is incorrect. You may use an advise from e.g. https://stackoverflow.com/questions/6098472/pass-a-local-file-in-to-url-in-java ; or you may implement a procedure that would make sure to treat some characters as is, other replaced with specific things, and yet other percent-encoded - but the simple replacement of backslashes with forward slashes will hit you soon - when you have spaces, or hashes, or tabs, or percents in the file name...
Comment 5 Heesu Ban 2024-11-03 15:22:37 UTC
Thanks for the advice.

Changed some code in my Java file like below. but result is the same as before. No image showed. 
        /*
        PropertyValue[] v = new PropertyValue[2];
        v[0] = new PropertyValue();
        v[0].Name = "InputStream";
        v[0].Value = new ByteArrayToXInputStreamAdapter(imageByteArray);
        v[1] = new PropertyValue();
        v[1].Name = "MimeType";
        v[1].Value = "image/png";
        */
        PropertyValue[] v = new PropertyValue[1];
        v[0] = new PropertyValue();
        v[0].Name = "URL";
        v[0].Value = new File("BackImage.png").toURI().toURL().toExternalForm();
        
        XGraphic graphic = xGraphicProvider.queryGraphic(v);

I'm pretty sure XGraphic instance is got normally, 
because graphic is not null and below code saved XGraphic to different png file. When I opened the other png, it showed image nornally.

        if (graphic == null) {
            System.out.println("Error loading the image");
            return;
        }

        // make sure that PNG file is correct by saving as another file
        PropertyValue[] pv = new PropertyValue[2];
        Path path = Files.createTempFile(Paths.get(System.getProperty("user.dir")), "temp_", ".png");
        URL url = path.toFile().toURI().toURL();
        String urlString = url.toExternalForm();
        pv[0] = new PropertyValue();
        pv[0].Name = "URL";
        pv[0].Value = urlString;
        pv[1] = new PropertyValue();
        pv[1].Name = "MimeType";
        pv[1].Value = "image/png";
        xGraphicProvider.storeGraphic(graphic, pv);
the very above code saved temp_9399882236891448062.png file, two png files are not identical but showed same image.

For converting system path to URL. It may be incorrect. but testing is valid for me in reading and saving image perspective.

If your BASIC sample code is working, I would better change title including Java.
Comment 6 Heesu Ban 2024-11-03 15:25:24 UTC
Created attachment 197377 [details]
ODT doesn't showed any background image

This is the ODT file genered from java testing code.
It doesn't show any background image.
Comment 7 Mike Kaganski 2024-11-03 15:34:02 UTC
Just to check things. In your code (and in mine), there is a piece checking if there is an existing page style with this name. If there is not, then the new style is created (meaning: inserted into the document with the name); but if it already is, then the work continues without actually inserting the style, and the changes are simply in a nameless temporary, which will be discarded.

So - can you make it hard-fail when there is such a style? Or alternatively: change the code like this (Basic) code:

 xFamilies = mMyDocument.getStyleFamilies()
 xFamily = xFamilies.getByName("PageStyles")
 if (xFamily.hasByName(MY_PAGE_STYLE_NAME)) then
  xPageStyle = xFamily.getByName(MY_PAGE_STYLE_NAME)
 else
  xPageStyle = mMyDocument.createInstance("com.sun.star.style.PageStyle")
  xFamily.insertByName(MY_PAGE_STYLE_NAME, xPageStyle)
 endif

The suspicion is, that *maybe* you have accidentally made a *default template* with the partially created style; and now, when you execute your code, the new document has that partially defined style, and indeed, all the changes in your code are done with a discarded temporary.
Comment 8 Mike Kaganski 2024-11-03 15:46:50 UTC
By the way: my Basic code is trivial to test for you: you only need to put it into a Basic sub (e.g., in Basic IDE's default Main), change the path to the PNG, and run. So - does my code work for you?
Comment 9 Mike Kaganski 2024-11-03 15:54:04 UTC
And one more thing, that I needed to state from start: I tested using Version: 24.8.3.1 (X86_64) / LibreOffice Community
Build ID: 65412f067af443213e726c93f137ccc85c9a1e06
CPU threads: 24; OS: Windows 11 X86_64 (10.0 build 26100); UI render: Skia/Vulkan; VCL: win
Locale: ru-RU (ru_RU); UI: en-US
Calc: CL threaded

May it be a problem of version?
Comment 10 Heesu Ban 2024-11-04 14:22:00 UTC
@Mike
Your BASIC code works fine for me. 

Here is my version.
Version: 24.8.2.1 (X86_64) / LibreOffice Community
Build ID: 0f794b6e29741098670a3b95d60478a65d05ef13
CPU threads: 64; OS: Windows 10 X86_64 (10.0 build 19045); UI render: Skia/Vulkan; VCL: win
Locale: ko-KR (ko_KR); UI: ko-KR
Calc: CL threaded


I think my reporting problem is NOT related to specific version, BUT specific to java UNO API.
Comment 11 Mike Kaganski 2024-11-04 14:47:07 UTC
(In reply to Heesu Ban from comment #10)

Please provide a compiled Java, and exact steps to run it. I could try to debug the specific call then on LibreOffice side.
Comment 12 Heesu Ban 2024-11-05 15:11:17 UTC
Created attachment 197420 [details]
zipped testing java project
Comment 13 Heesu Ban 2024-11-05 15:12:09 UTC
Created attachment 197421 [details]
debugging guide of provided sample
Comment 14 Heesu Ban 2024-11-05 15:14:56 UTC
@Mike 
Thank you for your effort on this issue.
I attached debugging guide and zipped testing java project.
Please see "debugging guide of provided sample".
Comment 15 Mike Kaganski 2024-11-05 15:43:50 UTC
Do you mean, that there is no way to run it without full IDE (which I won't install), only having JRE?
Comment 16 Heesu Ban 2024-11-06 15:17:49 UTC
Created attachment 197447 [details]
class compiled with JDK8
Comment 17 Heesu Ban 2024-11-06 15:31:44 UTC
@Mike, 

I found out how to debug in command line without full IDE.

I attached zip file which contains class compiled by jdk8.

Here is steps.
1. download "class compiled with JDK8" and unzip it
2. open command window
3. cd unzipped folder
4. make path variable include jdb.exe 
   > set path=%path%;"C:\Program Files\Java\jdk-1.8\bin"
5. execute jdb. need to fit classpath with YOUR LibreOiffce path.
   > jdb -classpath bin;C:\LibreOffice\program\classes\*; working.PageStyleBackgroundTest
   debugger will start
6. set breakpoint at 231 line
   > stop at working.PageStyleBackgroundTest:235
7. run debugger
   > run
8. debugger will stop at breakpoint. see variables with print 
   main[1] print graphic
9. use other debugger command. please refer to below link for that.
   https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jdb.html

Thank you
Comment 18 Mike Kaganski 2024-11-06 16:05:58 UTC
Ah - I see what you are doing :-) you are trying to help me debug the Java code :-) Thank you! But I don't need to debug it. I will debug LibreOffice, and I will have my breakpoints in the C++ code. I only need to be able to simply run the Java code - which I will try now, using your guidelines.
Comment 19 Mike Kaganski 2024-11-06 16:51:20 UTC
https://gerrit.libreoffice.org/c/core/+/176149
Comment 20 Commit Notification 2024-11-06 19:27:06 UTC
Mike Kaganski committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/5c9b00ff3d12cb5699cbd0158d12f8300488dc41

tdf#163748: checking Any's value type is anti-pattern

It will be available in 25.2.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.