need advices and help about Bookmark API.

classic Classic list List threaded Threaded
4 messages Options
LORENZO Vincent LORENZO Vincent
Reply | Threaded
Open this post in threaded view
|

need advices and help about Bookmark API.

Hello everybody,

                It is my first post on this mailing-list and probably not the last one, so I will introduce myself.

I’m Vincent LORENZO and I’m developing with my colleagues an UML modeler, called Papyrus and based on Eclipse (https://www.eclipse.org/papyrus/ ).

We are developing a new feature to generate a text document from a UML model and we use the LibreOffice API.

We found many examples to start a document creation and now we have a good prototype. Each relevant element of the UML model is transformed into title, section, paragraph, image, … in an odt file.

At this step, we want to store additional datas for each LibreOffice elements, in order to identify the UML element used to create a title, a paragraph, … to be able to reverse future text changes into the initial UML model.  

 

We want these additional data not to be directly visible to the user.

We want a start and end tag around each information coming from the uml model. (so inside a title, text, cell, …)

 

 

Question 1:

Currently we are studying the possibility to use the Bookmark field’s name to store these datas. We want to use the Bookmark with start and end tag, to get something like that.

<text:bookmark-start text:name="UML_element_qualified_name_and_others_useful_informations" />

              Some text

       <text:bookmark-end text:name=" UML_element_qualified_name_and_others_useful_informations " />

 

In reality, I would prefer to be able to use a more structured datas, extending the Bookmark object (or using another solution ? ) to get that, something like that:

 

       <text:bookmark-start text:name="Bookmark1" umlElementQualifiedName=”Package1::Class1” umlElementKind="Class" umlElementfeature="name" id="xxx"/>

                           Some text

       <text:bookmark-end text:name="Bookmark1" />

 

but I have no idea if it is possible and how to do that. Please, does someone have an idea to structure my datas ?

Of course, if you have a better solution than Bookmark, fell free to propose it.

 

 

 

Question 2:

Today, I succeed to create a such Bookmark, using the example: https://api.libreoffice.org/examples/java/Text/BookmarkInsertion.java.

I have this code:

 
     //document is already created, I’m creating a title

1.                  xTextCursor.setString(text);

2.                  xTextCursor.gotoEnd(false);

3.                  XInterface xSearchInterface = FindFirst(odtEditor.getXTextDocument(), text);  //(copy of the method provided by the example)

4.                  XTextRange xSearchTextRange = UnoRuntime.queryInterface(com.sun.star.text.XTextRange.class, xSearchInterface);

5.                  InsertBookmark(odtEditor.getXTextDocument(), xSearchTextRange, "niceBookMark"); //(copy of the method provided by the example)

 

 

So, in this example, I write text, I look for it, then I create a XTextRange and at the end, I can create the Bookmark. I’m not very have happy with this solution. I would prefer a solution without the search step, but I don’t know how to get a valid XTextRange (I admit I don’t yet well understand  the behavior of the API).

Please, do you have some pointer or code example ?

 

 

I thank you to read me until here.

Have a nice day.

 

Regards,

--

Vincent LORENZO

01-69-08-17-24

CEA Saclay Nano-INNOV

Institut CARNOT CEA LIST

Point Courrier n° 174

91 191 Gif sur Yvette CEDEX

 


_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice
Miklos Vajna-6 Miklos Vajna-6
Reply | Threaded
Open this post in threaded view
|

Re: need advices and help about Bookmark API.

Hi Vincent,

On Thu, Jan 10, 2019 at 02:13:58PM +0000, LORENZO Vincent <[hidden email]> wrote:

> Question 1:
> Currently we are studying the possibility to use the Bookmark field's name to store these datas. We want to use the Bookmark with start and end tag, to get something like that.
> <text:bookmark-start text:name="UML_element_qualified_name_and_others_useful_informations" />
>               Some text
>        <text:bookmark-end text:name=" UML_element_qualified_name_and_others_useful_informations " />
>
> In reality, I would prefer to be able to use a more structured datas, extending the Bookmark object (or using another solution ? ) to get that, something like that:
>
>        <text:bookmark-start text:name="Bookmark1" umlElementQualifiedName="Package1::Class1" umlElementKind="Class" umlElementfeature="name" id="xxx"/>
>                            Some text
>        <text:bookmark-end text:name="Bookmark1" />
>
> but I have no idea if it is possible and how to do that. Please, does someone have an idea to structure my datas ?
> Of course, if you have a better solution than Bookmark, fell free to propose it.
Bookmark is just a string; one hack you can do is to give it a unique
name, which refers to a per-document custom metadata, where the value
disturbs the user less. But that's still just a string, so you need to
serialize/load to/from string if you want to store key-value pairs.

An alternative is to use RDF annotations, which allows more complex
structures:

https://wiki.openoffice.org/wiki/Documentation/DevGuide/OfficeDev/RDF_metadata

(Though you need to use archive.org or something like that to access it,
seems the Apache site is currently not available.)

One shortcoming of RDF is that it's ODF-only; while the per-doc custom
metadata + bookmarks works with most other formats as well.

> So, in this example, I write text, I look for it, then I create a XTextRange and at the end, I can create the Bookmark. I'm not very have happy with this solution. I would prefer a solution without the search step, but I don't know how to get a valid XTextRange (I admit I don't yet well understand  the behavior of the API).
> Please, do you have some pointer or code example ?

Some kind of iteration or search is necessary: if you take the user's
current selection or you iterate to the nth paragraph or you search for
text is up to you. An XTextRange is just a selection (where start and
end may point to the same document model position).

> I thank you to read me until here.

Hope this helps. :-)

Regards,

Miklos

_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice

signature.asc (201 bytes) Download Attachment
SOS SOS
Reply | Threaded
Open this post in threaded view
|

Re: need advices and help about Bookmark API.

Hallo,
We did some test to use RDF (also Miklos his advice) to store some information about images in a Writerdoc, before we stored the information in the ImageObject , what was not a good idea.
Greetz
Fernand

below the code who works well

const BASE_TYPE = "http://PMGopmaak.writer/Allgraphics"
const TYPE_NAME = "GraphicURL"

const FILE_NAME = "PMGopmaak.writer/Allgraphics.rdf"


Sub StoreRDF
  RemoveRDF()
 
  ' "graph" staat hier niet voor een graphic maar voor een ellement die data kan omschrijven en stockeren
  ' een "litera" is een string die we stockeren en kunnen opvragen
  doc = ThisComponent
  repo = doc.getRDFRepository()
  type_uri = GetTypeURI()
  graph_name = doc.addMetadataFile(FILE_NAME, Array(type_uri))
  named_graph = repo.getGraph(graph_name)
 
  value_uri = CreateURI(com.sun.star.rdf.URIs.RDF_VALUE)
 
 
 
  if doc.supportsService("com.sun.star.text.TextDocument") then
   
   oDocGraphics = doc.GraphicObjects
 
    vAlleFotos = oDocGraphics.getElementNames()
            aantal = oDocGraphics.count
             For iG = 0 to aantal - 1
            iFotNr = ig + 1
             '   sFotMetNr = vAlleFotos(iG)
                oGraphic1 = oDocGraphics.GetbyIndex(ig)
  named_graph.addStatement(CreateURI(oGraphic1.Name &":", "URL"),value_uri,CreateLiteral(Ographic1.Title))
  named_graph.addStatement(CreateURI(oGraphic1.Name &":", "ONDERSCHRIFT"),value_uri,CreateLiteral(Ographic1.Hyperlinkname))
 
  next IG

  End If
 
  doc.setModified(True)
End Sub

Sub ReadRDF()
zoek = "Image1:URL"
  doc = ThisComponent
  repo = doc.getRDFRepository()
 
  type_uri = GetTypeURI()

  graph_names = doc.getMetadataGraphsWithType(type_uri)

  If ubound(graph_names) = -1 then exit sub
 
  graph_name = graph_names(0)
 
  named_graph = repo.getGraph(graph_name)
  value_uri = CreateURI(com.sun.star.rdf.URIs.RDF_VALUE)
 
 ' named_graph.clear
  enume = named_graph.getStatements(Null, value_uri, Null)
 ' xray named_graph.getStatements(null, value_uri, Null)
  s = ""
   Do while Enume.hasMoreElements
    st = enume.nextElement()
     name = st.Subject.StringValue
       sts = st.Object.StringValue
    s = s & name & ": " & sts & chr(10)
    print name
   ' if name = zoek  then
   ' print sts
  ' named_graph.removeStatements(st.Subject, value_uri,st.Object)
   ' exit do
  ' endif
 loop

  msgbox s
End Sub


Sub RemoveRDF
  doc = ThisComponent
  repo = doc.getRDFRepository()
 
  type_uri = GetTypeURI()
  graph_names = doc.getMetadataGraphsWithType(type_uri)
  if ubound(graph_names) = -1 then exit sub
  graph_name = graph_names(0)
  doc.removeMetadataFile(graph_name)
  doc.setModified(True)
End Sub


Function GetTypeURI() As variant
  GetTypeURI = CreateURI(BASE_TYPE & "/" & TYPE_NAME)
End Function


Function CreateURI(n, Optional l) As Variant
  If IsMissing(l) Then
    a = Array(n)
  Else
    a = Array(n, l)
  End If
  uri = CreateUnoServiceWithArguments("com.sun.star.rdf.URI", a)
  CreateURI = uri
End Function

Function CreateLiteral(v) As Variant
  a = Array(v)
  literal = CreateUnoServiceWithArguments("com.sun.star.rdf.Literal", a)
  CreateLiteral = literal
End Function





On 1/11/2019 9:27 AM, Miklos Vajna wrote:
Hi Vincent,

On Thu, Jan 10, 2019 at 02:13:58PM +0000, LORENZO Vincent [hidden email] wrote:
Question 1:
Currently we are studying the possibility to use the Bookmark field's name to store these datas. We want to use the Bookmark with start and end tag, to get something like that.
<text:bookmark-start text:name="UML_element_qualified_name_and_others_useful_informations" />
              Some text
       <text:bookmark-end text:name=" UML_element_qualified_name_and_others_useful_informations " />

In reality, I would prefer to be able to use a more structured datas, extending the Bookmark object (or using another solution ? ) to get that, something like that:

       <text:bookmark-start text:name="Bookmark1" umlElementQualifiedName="Package1::Class1" umlElementKind="Class" umlElementfeature="name" id="xxx"/>
                           Some text
       <text:bookmark-end text:name="Bookmark1" />

but I have no idea if it is possible and how to do that. Please, does someone have an idea to structure my datas ?
Of course, if you have a better solution than Bookmark, fell free to propose it.
Bookmark is just a string; one hack you can do is to give it a unique
name, which refers to a per-document custom metadata, where the value
disturbs the user less. But that's still just a string, so you need to
serialize/load to/from string if you want to store key-value pairs.

An alternative is to use RDF annotations, which allows more complex
structures:

https://wiki.openoffice.org/wiki/Documentation/DevGuide/OfficeDev/RDF_metadata

(Though you need to use archive.org or something like that to access it,
seems the Apache site is currently not available.)

One shortcoming of RDF is that it's ODF-only; while the per-doc custom
metadata + bookmarks works with most other formats as well.

So, in this example, I write text, I look for it, then I create a XTextRange and at the end, I can create the Bookmark. I'm not very have happy with this solution. I would prefer a solution without the search step, but I don't know how to get a valid XTextRange (I admit I don't yet well understand  the behavior of the API).
Please, do you have some pointer or code example ?
Some kind of iteration or search is necessary: if you take the user's
current selection or you iterate to the nth paragraph or you search for
text is up to you. An XTextRange is just a selection (where start and
end may point to the same document model position).

I thank you to read me until here.
Hope this helps. :-)

Regards,

Miklos

_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice

_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice
LORENZO Vincent LORENZO Vincent
Reply | Threaded
Open this post in threaded view
|

RE: need advices and help about Bookmark API.

Hello everybody,

I thank you for your anwsers. I will continue with Bookmark which seem me quite easy to implement.

 

I found a way to avoid to search the text in the document:

             short value = ((Integer) text.length()).shortValue();

             cursor.setString(text);

       cursor.gotoEnd(false);

 

             cursor.goLeft(value, false);

             InsertBookmark(odtEditor.getXTextDocument(), cursor, "muBookmarkName");

       cursor.gotoEnd(false);

 

It seems work find.

 

/Vincent

 

De : LibreOffice [mailto:[hidden email]] De la part de sos
Envoyé : vendredi 11 janvier 2019 10:36
À : [hidden email]
Objet : Re: need advices and help about Bookmark API.

 

Hallo,
We did some test to use RDF (also Miklos his advice) to store some information about images in a Writerdoc, before we stored the information in the ImageObject , what was not a good idea.
Greetz
Fernand

below the code who works well

const BASE_TYPE = "http://PMGopmaak.writer/Allgraphics"
const TYPE_NAME = "GraphicURL"

const FILE_NAME = "PMGopmaak.writer/Allgraphics.rdf"


Sub StoreRDF
  RemoveRDF()
 
  ' "graph" staat hier niet voor een graphic maar voor een ellement die data kan omschrijven en stockeren
  ' een "litera" is een string die we stockeren en kunnen opvragen
  doc = ThisComponent
  repo = doc.getRDFRepository()
  type_uri = GetTypeURI()
  graph_name = doc.addMetadataFile(FILE_NAME, Array(type_uri))
  named_graph = repo.getGraph(graph_name)
 
  value_uri = CreateURI(com.sun.star.rdf.URIs.RDF_VALUE)
 
 
 
  if doc.supportsService("com.sun.star.text.TextDocument") then
   
   oDocGraphics = doc.GraphicObjects
 
    vAlleFotos = oDocGraphics.getElementNames()
            aantal = oDocGraphics.count
             For iG = 0 to aantal - 1
            iFotNr = ig + 1
             '   sFotMetNr = vAlleFotos(iG)
                oGraphic1 = oDocGraphics.GetbyIndex(ig)
  named_graph.addStatement(CreateURI(oGraphic1.Name &":", "URL"),value_uri,CreateLiteral(Ographic1.Title))
  named_graph.addStatement(CreateURI(oGraphic1.Name &":", "ONDERSCHRIFT"),value_uri,CreateLiteral(Ographic1.Hyperlinkname))
 
  next IG

  End If
 
  doc.setModified(True)
End Sub

Sub ReadRDF()
zoek = "Image1:URL"
  doc = ThisComponent
  repo = doc.getRDFRepository()
 
  type_uri = GetTypeURI()

  graph_names = doc.getMetadataGraphsWithType(type_uri)

  If ubound(graph_names) = -1 then exit sub
 
  graph_name = graph_names(0)
 
  named_graph = repo.getGraph(graph_name)
  value_uri = CreateURI(com.sun.star.rdf.URIs.RDF_VALUE)
 
 ' named_graph.clear
  enume = named_graph.getStatements(Null, value_uri, Null)
 ' xray named_graph.getStatements(null, value_uri, Null)
  s = ""
   Do while Enume.hasMoreElements
    st = enume.nextElement()
     name = st.Subject.StringValue
       sts = st.Object.StringValue
    s = s & name & ": " & sts & chr(10)
    print name
   ' if name = zoek  then
   ' print sts
  ' named_graph.removeStatements(st.Subject, value_uri,st.Object)
   ' exit do
  ' endif
 loop

  msgbox s
End Sub


Sub RemoveRDF
  doc = ThisComponent
  repo = doc.getRDFRepository()
 
  type_uri = GetTypeURI()
  graph_names = doc.getMetadataGraphsWithType(type_uri)
  if ubound(graph_names) = -1 then exit sub
  graph_name = graph_names(0)
  doc.removeMetadataFile(graph_name)
  doc.setModified(True)
End Sub


Function GetTypeURI() As variant
  GetTypeURI = CreateURI(BASE_TYPE & "/" & TYPE_NAME)
End Function


Function CreateURI(n, Optional l) As Variant
  If IsMissing(l) Then
    a = Array(n)
  Else
    a = Array(n, l)
  End If
  uri = CreateUnoServiceWithArguments("com.sun.star.rdf.URI", a)
  CreateURI = uri
End Function

Function CreateLiteral(v) As Variant
  a = Array(v)
  literal = CreateUnoServiceWithArguments("com.sun.star.rdf.Literal", a)
  CreateLiteral = literal
End Function



 

On 1/11/2019 9:27 AM, Miklos Vajna wrote:

Hi Vincent,
 
On Thu, Jan 10, 2019 at 02:13:58PM +0000, LORENZO Vincent [hidden email] wrote:
Question 1:
Currently we are studying the possibility to use the Bookmark field's name to store these datas. We want to use the Bookmark with start and end tag, to get something like that.
<text:bookmark-start text:name="UML_element_qualified_name_and_others_useful_informations" />
              Some text
       <text:bookmark-end text:name=" UML_element_qualified_name_and_others_useful_informations " />
 
In reality, I would prefer to be able to use a more structured datas, extending the Bookmark object (or using another solution ? ) to get that, something like that:
 
       <text:bookmark-start text:name="Bookmark1" umlElementQualifiedName="Package1::Class1" umlElementKind="Class" umlElementfeature="name" id="xxx"/>
                           Some text
       <text:bookmark-end text:name="Bookmark1" />
 
but I have no idea if it is possible and how to do that. Please, does someone have an idea to structure my datas ?
Of course, if you have a better solution than Bookmark, fell free to propose it.
 
Bookmark is just a string; one hack you can do is to give it a unique
name, which refers to a per-document custom metadata, where the value
disturbs the user less. But that's still just a string, so you need to
serialize/load to/from string if you want to store key-value pairs.
 
An alternative is to use RDF annotations, which allows more complex
structures:
 
https://wiki.openoffice.org/wiki/Documentation/DevGuide/OfficeDev/RDF_metadata
 
(Though you need to use archive.org or something like that to access it,
seems the Apache site is currently not available.)
 
One shortcoming of RDF is that it's ODF-only; while the per-doc custom
metadata + bookmarks works with most other formats as well.
 
So, in this example, I write text, I look for it, then I create a XTextRange and at the end, I can create the Bookmark. I'm not very have happy with this solution. I would prefer a solution without the search step, but I don't know how to get a valid XTextRange (I admit I don't yet well understand  the behavior of the API).
Please, do you have some pointer or code example ?
 
Some kind of iteration or search is necessary: if you take the user's
current selection or you iterate to the nth paragraph or you search for
text is up to you. An XTextRange is just a selection (where start and
end may point to the same document model position).
 
I thank you to read me until here.
 
Hope this helps. :-)
 
Regards,
 
Miklos



_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice

_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice