OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

Storing persistent custom attributes in document

 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Code Snippets
View previous topic :: View next topic  
Author Message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Sat Mar 05, 2005 11:05 am    Post subject: Storing persistent custom attributes in document Reply with quote

This article will show how to store persistent data into a document.

Examples will be provided for Calc and Writer.
(Anyone who has read my other articles on Draw, and by implication Impress, should be able to figure out how to do create custom shape attributes on a Draw or Impress document.)

The technique is based on the fact that a drawing shape can have custom attributes attached to it. These custom attributes survive when the document is saved and reloaded. These attributes also survive if the shape is copy/pasted from one document to another -- even a different document type. For instance, if a shape with custom attributes is copy/pasted from Draw to Writer, then those custom attributes are still present on the shape in Writer.

By putting a shape in some out of the say place, such as negative coordinates -10000, -10000, and making the shape very tiny (1 x 1, ie a "bug"), you effectively cannot find the shape, but it is still present in the document.


Here is the Calc example

Here is the Writer example



See Also....
Manipulating PropertyValue's
http://www.oooforum.org/forum/viewtopic.phtml?t=5301
which describes another way that you could cleverly store persistent data in a document as macro data.
_________________
Want to make OOo Drawings like the colored flower design to the left?


Last edited by DannyB on Sat Mar 05, 2005 11:35 am; edited 3 times in total
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Sat Mar 05, 2005 11:10 am    Post subject: Reply with quote

Calc example of custom persistent shape attributes

You can store as many attributes per shape as you want.
You can store as many shapes per sheet as you want.
You can put shapes with custom attributes onto as many sheets as you want.

Here is an example of how to store custom attributes into a document.
Code:
Sub Main
   ' What document are we working with?
   oDoc = ThisComponent
   ' What spreadsheet are the special shapes stored on.
   oSheet = oDoc.getSheets().getByName( "Sheet1" )
   
   ' Store some values in a persistent form as custom attributes.
   
   ' On the sheet oSheet, store a shape named "Shape01", with
   '  an attribute named "Charlie", and a value of "Red".
   ' The shape will be hidden so that you don't see it on the sheet.
   StoreCustomAttribute_Calc( oDoc, oSheet, "Shape01", "Charlie", "Red" )
   
   ' On the sheet oSheet, store a shape named "Shape01", with
   '  an attribute named "Fred", and a value of "Blue".
   ' The shape will be hidden so that you don't see it on the sheet.
   StoreCustomAttribute_Calc( oDoc, oSheet, "Shape01", "Fred", "Blue" )
End Sub

The work is all done in a new subroutine (see below) named StoreCustomAttribute_Calc().

Here is an example of how to retrieve custom attributes from a document.
Code:
Sub Main
   ' What document are we working with?
   oDoc = ThisComponent
   ' What spreadsheet are the special shapes stored on.
   oSheet = oDoc.getSheets().getByName( "Sheet1" )
   
   ' Display some previously stored values.

   ' Look for a special hidden shape on the sheet oSheet.
   ' The shape would be named "Shape01", and would have a custom attribute
   '  named "Charlie".
   ' Return the value of that custom attribute.
   cCharlieValue = GetCustomAttribute_Calc( oDoc, oSheet, "Shape01", "Charlie" )

   cFredValue = GetCustomAttribute_Calc( oDoc, oSheet, "Shape01", "Fred" )
   
   Print "Charlie is", cCharlieValue, "Fred is", cFredValue
End Sub

Again the custom attribute values are retrieved using a new function (see below).

In the above examples, a shape is stored on Sheet1.
The shape has the name "Shape01".
The shape gets a pair of custom attributes ("Charlie" and "Fred"). Each attribute has a value ("Red" and "Blue" respectively).


Here is the code that does the work.
Code:
' This function stores some custom attributes on a spreadsheet.
' A special named graphic shape (which happens to be a rectangle) is created on the sheet.
' The shape is given a name.
' The shape is given a size, position and other attributes which make it invisible.
Sub StoreCustomAttribute_Calc( oDoc, oSheet, cShapeName, cAttributeName, cAttributeValue )
   ' Get the draw page for the sheet.
   oDrawPage = oSheet.getDrawPage()
   ' Get a reference to the shape.
   oShape = FindShapeByName( oDrawPage, cShapeName )
   ' Does it already have the special shape to store the attributes?
   If IsNull( oShape ) Or IsEmpty( oShape ) Then
      ' Create the special shape.
      oShape = oDoc.createInstance( "com.sun.star.drawing.RectangleShape" )

      '----------
      ' Uncomment this block while debugging.
      ' (i.e. while you are still adding bugs to the program)
      ' Position the shape
      'oShape.Position = MakePoint( 3000, 2000 )
      ' Set the size of the shape
      'oShape.Size = MakeSize( 5000, 3000 )
      '----------
      
      '----------
      ' Uncomment this block when finished debugging.
      ' (i.e. once finished  adding bugs to the program)
      ' Make the shape's fill be invisible
      oShape.FillStyle = com.sun.star.drawing.FillStyle.NONE
      ' Make the shape's line style be invisible
      oShape.LineStyle = com.sun.star.drawing.LineStyle.NONE
      ' Position the shape
      oShape.Position = MakePoint( -10000, -10000 ) 'somewhere where you can't click on it
      ' Set the size of the shape
      oShape.Size = MakeSize( 1, 1 ) 'teeny tiny
      '----------
      
      ' Add the shape to the drawing page.
      oDrawPage.add( oShape )
      ' Set the shape's name.
      oShape.Name = cShapeName
   EndIf
   
   ' Get the custom attributes for the shape.
   oUserDefinedAttributes = oShape.UserDefinedAttributes
   
   ' Is there already an attribute with the desired name?
   If oUserDefinedAttributes.hasByName( cAttributeName ) Then
      ' Get the existing attribute.
      oMyAttribute = oUserDefinedAttributes.getByName( cAttributeName )
      ' Update the value.
      oMyAttribute.Value = cAttributeValue
   Else
      ' Create a new attribute.
      oMyAttribute = createUnoStruct( "com.sun.star.xml.AttributeData" )
      With oMyAttribute
         .Type = "CDATA"
         .Value = cAttributeValue
      End With
      oUserDefinedAttributes.insertByName( cAttributeName, oMyAttribute )
   EndIf
      
   ' Assign the modified container of attributes back to the shape.
   oShape.UserDefinedAttributes = oUserDefinedAttributes
End Sub


Function GetCustomAttribute_Calc( oDoc, oSheet, cShapeName, cAttributeName )
   GetCustomAttribute_Calc = ""
   
   ' Get the draw page for the sheet.
   oDrawPage = oSheet.getDrawPage()
   ' Get a reference to the shape.
   oShape = FindShapeByName( oDrawPage, cShapeName )
   ' Does it already have the special shape to store the attributes?
   If IsNull( oShape ) Or IsEmpty( oShape ) Then
      ' Since the shape is not present, return nothing.
      Exit Function
   EndIf
   
   ' Get the custom attributes for the shape.
   oUserDefinedAttributes = oShape.UserDefinedAttributes
   
   ' Is there already an attribute with the desired name?
   If oUserDefinedAttributes.hasByName( cAttributeName ) Then
      ' Get the existing attribute.
      oMyAttribute = oUserDefinedAttributes.getByName( cAttributeName )
      ' Return the value
      GetCustomAttribute_Calc = oMyAttribute.Value
      Exit Function
   EndIf
End Function



Function MakePoint( ByVal x As Long, ByVal y As Long ) As com.sun.star.awt.Point
   oPoint = createUnoStruct( "com.sun.star.awt.Point" )
   oPoint.X = x
   oPoint.Y = y
   MakePoint() = oPoint
End Function

Function MakeSize( ByVal width As Long, ByVal height As Long ) As com.sun.star.awt.Size
   oSize = createUnoStruct( "com.sun.star.awt.Size" )
   oSize.Width = width
   oSize.Height = height
   MakeSize() = oSize
End Function




'----------
'   Given an object supporting the XShapes interface,
'    find and return a named shape in that collection of shapes.
'   Since a drawing page supports XShapes, you can use this
'    function to find a named shape within a draw page,
'    or within a grouped shape, or a selection of shapes.
'
Function FindShapeByName( oShapes, cShapeName As String )
   nNumShapes = oShapes.getCount()
   For i = 0 To nNumShapes - 1
      oShape = oShapes.getByIndex( i )
      If oShape.getName() = cShapeName Then
         FindShapeByName() = oShape
         Exit Function
      EndIf
   Next
End Function

_________________
Want to make OOo Drawings like the colored flower design to the left?


Last edited by DannyB on Sat Mar 05, 2005 11:30 am; edited 2 times in total
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Sat Mar 05, 2005 11:21 am    Post subject: Reply with quote

Writer example of custom persistent shape attributes

You can store as many attributes per shape as you want.
You can store as many shapes per document as you want.

Here is an example of storing custom attributes.
Code:
Sub Main
   ' What document are we working with?
   oDoc = ThisComponent
   
   ' Store some values in a persistent form as custom attributes.
   
   ' Store a shape named "Shape01", with
   '  an attribute named "Charlie", and a value of "Red".
   ' The shape will be hidden so that you don't see it on the sheet.
   StoreCustomAttribute_Writer( oDoc, "Shape01", "Charlie", "Red" )
   
   ' Store a shape named "Shape01", with
   '  an attribute named "Fred", and a value of "Blue".
   ' The shape will be hidden so that you don't see it on the sheet.
   StoreCustomAttribute_Writer( oDoc, "Shape01", "Fred", "Blue" )
End Sub


Here is an example of retrieving custom attributes.
Code:
Sub Main
   ' What document are we working with?
   oDoc = ThisComponent
   
   ' Display some previously stored values.

   ' Look for a special hidden shape named "Shape01"
   '  with a custom attribute named "Charlie".
   ' Return the value of that custom attribute.
   cCharlieValue = GetCustomAttribute_Writer( oDoc, "Shape01", "Charlie" )

   cFredValue = GetCustomAttribute_Writer( oDoc, "Shape01", "Fred" )
   
   Print "Charlie is", cCharlieValue, "Fred is", cFredValue
End Sub



Here is the code which does the work.
Code:
' This function stores some custom attributes on Writer document..
' A special named graphic shape (which happens to be a rectangle) is created.
' The shape is given a name.
' The shape is given a size, position and other attributes which make it invisible.
Sub StoreCustomAttribute_Writer( oDoc, cShapeName, cAttributeName, cAttributeValue )
   ' Get the draw page for the sheet.
   oDrawPage = oDoc.getDrawPage()
   ' Get a reference to the shape.
   oShape = FindShapeByName( oDrawPage, cShapeName )
   ' Does it already have the special shape to store the attributes?
   If IsNull( oShape ) Or IsEmpty( oShape ) Then
      ' Create the special shape.
      oShape = oDoc.createInstance( "com.sun.star.drawing.RectangleShape" )

      '----------
      ' Uncomment this block while debugging.
      ' (i.e. while you are still adding bugs to the program)
      ' Position the shape
      'oShape.Position = MakePoint( 3000, 2000 )
      ' Set the size of the shape
      'oShape.Size = MakeSize( 5000, 3000 )
      '----------
      
      '----------
      ' Uncomment this block when finished debugging.
      ' (i.e. once finished  adding bugs to the program)
      ' Make the shape's fill be invisible
      oShape.FillStyle = com.sun.star.drawing.FillStyle.NONE
      ' Make the shape's line style be invisible
      oShape.LineStyle = com.sun.star.drawing.LineStyle.NONE
      ' Position the shape
      oShape.Position = MakePoint( -10000, -10000 ) 'somewhere where you can't click on it
      ' Set the size of the shape
      oShape.Size = MakeSize( 1, 1 ) 'teeny tiny
      '----------
      
      ' Add the shape to the drawing page.
      oDrawPage.add( oShape )
      ' Set the shape's name.
      oShape.Name = cShapeName
   EndIf
   
   ' Get the custom attributes for the shape.
   oUserDefinedAttributes = oShape.UserDefinedAttributes
   
   ' Is there already an attribute with the desired name?
   If oUserDefinedAttributes.hasByName( cAttributeName ) Then
      ' Get the existing attribute.
      oMyAttribute = oUserDefinedAttributes.getByName( cAttributeName )
      ' Update the value.
      oMyAttribute.Value = cAttributeValue
   Else
      ' Create a new attribute.
      oMyAttribute = createUnoStruct( "com.sun.star.xml.AttributeData" )
      With oMyAttribute
         .Type = "CDATA"
         .Value = cAttributeValue
      End With
      oUserDefinedAttributes.insertByName( cAttributeName, oMyAttribute )
   EndIf
      
   ' Assign the modified container of attributes back to the shape.
   oShape.UserDefinedAttributes = oUserDefinedAttributes
End Sub


Function GetCustomAttribute_Writer( oDoc, cShapeName, cAttributeName )
   GetCustomAttribute_Writer = ""
   
   ' Get the draw page for the sheet.
   oDrawPage = oDoc.getDrawPage()
   ' Get a reference to the shape.
   oShape = FindShapeByName( oDrawPage, cShapeName )
   ' Does it already have the special shape to store the attributes?
   If IsNull( oShape ) Or IsEmpty( oShape ) Then
      ' Since the shape is not present, return nothing.
      Exit Function
   EndIf
   
   ' Get the custom attributes for the shape.
   oUserDefinedAttributes = oShape.UserDefinedAttributes
   
   ' Is there already an attribute with the desired name?
   If oUserDefinedAttributes.hasByName( cAttributeName ) Then
      ' Get the existing attribute.
      oMyAttribute = oUserDefinedAttributes.getByName( cAttributeName )
      ' Return the value
      GetCustomAttribute_Writer = oMyAttribute.Value
      Exit Function
   EndIf
End Function



Function MakePoint( ByVal x As Long, ByVal y As Long ) As com.sun.star.awt.Point
   oPoint = createUnoStruct( "com.sun.star.awt.Point" )
   oPoint.X = x
   oPoint.Y = y
   MakePoint() = oPoint
End Function

Function MakeSize( ByVal width As Long, ByVal height As Long ) As com.sun.star.awt.Size
   oSize = createUnoStruct( "com.sun.star.awt.Size" )
   oSize.Width = width
   oSize.Height = height
   MakeSize() = oSize
End Function




'----------
'   Given an object supporting the XShapes interface,
'    find and return a named shape in that collection of shapes.
'   Since a drawing page supports XShapes, you can use this
'    function to find a named shape within a draw page,
'    or within a grouped shape, or a selection of shapes.
'
Function FindShapeByName( oShapes, cShapeName As String )
   nNumShapes = oShapes.getCount()
   For i = 0 To nNumShapes - 1
      oShape = oShapes.getByIndex( i )
      If oShape.getName() = cShapeName Then
         FindShapeByName() = oShape
         Exit Function
      EndIf
   Next
End Function



Some notes:

  1. It may be desirable to store the shape somewhere other than on the main document? Maybe in the header or footer? Or embedded in a table? I'll leave that to someone who is more of an expert in Writer than I am.

_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
cbosdonnat
Power User
Power User


Joined: 14 Nov 2004
Posts: 61
Location: France - Lyon

PostPosted: Tue Mar 08, 2005 6:34 am    Post subject: Reply with quote

Hello Danny,

I'm trying to write a macro which stores UserDefinedAttributes in paragraph. This is a test :
Code:
Sub TestAttributes

   DIM oDoc, oCursor AS OBJECT
   DIM oProperties, oAttributeData AS OBJECT
   
   oDoc = ThisComponent
   oCursor = oDoc.Text.createTextCursor()
   
   oCursor.gotoStart(false)
   oProperties = oCursor.getPropertyValue("ParaUserDefinedAttributes")
   
   IF ( oProperties.hasByName("language") ) THEN
      Print "Test 1 : " + oProperties.getByName("language").Value
   ELSE
   
      oAttributeData = createUnoStruct("com.sun.star.xml.AttributeData")
      oAttributeData.Type = "CDATA"
      oAttributeData.Value= "java"
      
      oProperties.insertByName("language", oAttributeData)
      oCursor.ParaUserDefinedAttributes = oProperties
      
      WITH oCursor.ParaUserDefinedAttributes
         Print "Test 2 - Type : " + .getByName("language").Type+ " valeur : " + _
                              .getByName("language").Value
      END WITH
      
   END IF

End Sub


The problem is that the attribute isn't stored in the document. I checked the xml files, but there is nothing about my language attribute. Do you have any idea ?

Thanks,
Cedric
_________________
Perso: http://cedric.bosdonnat.free.fr
Back to top
View user's profile Send private message Visit poster's website
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Wed Mar 09, 2005 9:07 am    Post subject: Reply with quote

It does not seem to work. Maybe I'm doing something wrong.

Here is how I would suppose you would store custom attributes....
Code:
Sub Main
   oDoc = StarDesktop.loadComponentFromURL( "private:factory/swriter", "_blank", 0, Array() )
   oText = oDoc.getText()
   oCursor = oText.createTextCursor()
   
   ' Create some text in writer.
   InsertString( oCursor, "This is paragraph 1." )
   oCursor.ParaStyleName = "Heading 1"
   InsertParaBreak( oCursor )
   InsertString( oCursor, "This is paragraph 2." )
   InsertParaBreak( oCursor )
   InsertString( oCursor, "This is paragraph 3." )
   
   ' Get the collection of attributes.
   oCustomXmlAttributes = oCursor.ParaUserDefinedAttributes
   
   ' Do some manipulations of the collection.
   oCustomXmlAttributes.insertByName( "John", CreateAttributeData("Blue") )
   oCustomXmlAttributes.insertByName( "Bill",  CreateAttributeData("Green") )
   oCustomXmlAttributes.insertByName( "Jason",  CreateAttributeData("Purple") )
   oCustomXmlAttributes.insertByName( "Tom",  CreateAttributeData("Red") )
   ' Test to see if someone had previously set a "David" attribute on this paragraph....
   If oCustomXmlAttributes.hasByName( "David" ) Then
      ' Change the value of the attribute.
      oCustomXmlAttributes.replaceByName( "David",  CreateAttributeData("Yellow") )
   Else
      ' Since this attribute was not present, create it.
      oCustomXmlAttributes.insertByName( "David",  CreateAttributeData("Orange") )
   EndIf
   ' Test to see if someone had previously set a "Mark" attribute on this paragraph....
   If oCustomXmlAttributes.hasByName( "Mark" ) Then
      ' If there was already a "Mark" attribute, then remove it.
      oCustomXmlAttributes.removeByName ( "Mark" )
   EndIf
   
   ' Store the collection of attributes back to the property.
   oCursor.ParaUserDefinedAttributes = oCustomXmlAttributes
End Sub


' Sugar coating to create an AttributeData struct, initialize and return it.
Function CreateAttributeData( cValue )
   oAttributeData = createUnoStruct( "com.sun.star.xml.AttributeData" )
   oAttributeData.Type = "CDATA"
   oAttributeData.Value = cValue
   CreateAttributeData = oAttributeData
End Function


Sub InsertString( oCursor, cString )
   oText = oCursor.getText()
   oText.insertString( oCursor, cString, False )
End Sub

Sub InsertLineBreak( oCursor )
   oText = oCursor.getText()
   oText.insertControlCharacter( oCursor, com.sun.star.text.ControlCharacter.LINE_BREAK, False )
End Sub

Sub InsertParaBreak( oCursor )
   oText = oCursor.getText()
   oText.insertControlCharacter( oCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False )
End Sub

Sub InsertPageBreak( oCursor )
   oText = oCursor.getText()
   oText.insertControlCharacter( oCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False )
   oCursor.BreakType = com.sun.star.style.BreakType.PAGE_BEFORE
End Sub

Sub InsertColumnBreak( oCursor )
   oText = oCursor.getText()
   oText.insertControlCharacter( oCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False )
   oCursor.BreakType = com.sun.star.style.BreakType.COLUMN_BEFORE
End Sub

The above code

  • Creates a new Writer document
  • Writes three paragraphs into it
  • Stores some attributes on the third (i.e. last, and current) paragraph


In the newly created document, here is how I would suppose you would retrieve the attributes....
Code:
Sub Main
   oDoc = ThisComponent
   oText = oDoc.getText()
   oCursor = oText.createTextCursor()
   
   oCursor.gotoStart( False )
   oCursor.gotoNextParagraph( False )
   oCursor.gotoNextParagraph( False )
'   oCursor.gotoNextParagraph( False )
'   oCursor.gotoNextParagraph( False )
   
   oCustomXmlAttributes = oCursor.ParaUserDefinedAttributes
   
   oJohn = oCustomXmlAttributes.getByName( "John" )
   cJohnValue = oJohn.Value
   Print "Attribute John is: ", cJohnValue
End Sub


In a document which has not been saved, the attributes cannot be retrieved.
In a document which has been saved, I am unable to find the attributes anywhere within the content.xml file.

I can insert the following line
Code:
   Print "John attribute present? ", oCustomXmlAttributes.hasByName( "John" )

at various points after I have stored the "John" attribute. The collection indicates that the attribute is present. Even if I re-retrieve the collection of attributes from the ParaUserDefinedAttributes property, the "John" attribute is present.

The custom attributes just don't seem to persist.

Oh, if I store the custom attributes in the first paragraph, then by placing the "retrieval" macro into the newly created document, but without the "gotoNextParagraph" calls, I am able to retrieve the attributes. They just do not persist.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Wed Mar 09, 2005 9:45 am    Post subject: Reply with quote

In answer to this question
cannot set UserDefinedAttributes for calc sheet
http://www.oooforum.org/forum/viewtopic.phtml?t=17848

Here is how to use the UserDefinedAttributes of a spreadsheet SheetCell. As you can see, a SheetCell includes the service Cell, and the Cell service includes the CellProperties service which is where you find the UserDefinedAttributes.

UserDefinedAttributes is an XNameContainer of name-value pairs. Each value must be an struct of type com.sun.star.xml.AttributeData.

Here is how to store some custom attributes into cell B5 of the current document.
Code:
Sub Main
   oDoc = ThisComponent
   oSheet = oDoc.getSheets().getByName( "Sheet1" )
   
   ' Get cell B5.
   oCell = oSheet.getCellRangeByName( "B5" ).getCellByPosition( 0, 0 )
   
   ' Get the collection of attributes.
   oCustomXmlAttributes = oCell.UserDefinedAttributes
   
   ' Do some manipulations of the collection.
   oCustomXmlAttributes.insertByName( "John", CreateAttributeData("Blue") )
   oCustomXmlAttributes.insertByName( "Bill",  CreateAttributeData("Green") )
   oCustomXmlAttributes.insertByName( "Jason",  CreateAttributeData("Purple") )
   oCustomXmlAttributes.insertByName( "Tom",  CreateAttributeData("Red") )
   ' Test to see if someone had previously set a "David" attribute on this paragraph....
   If oCustomXmlAttributes.hasByName( "David" ) Then
      ' Change the value of the attribute.
      oCustomXmlAttributes.replaceByName( "David",  CreateAttributeData("Yellow") )
   Else
      ' Since this attribute was not present, create it.
      oCustomXmlAttributes.insertByName( "David",  CreateAttributeData("Orange") )
   EndIf
   ' Test to see if someone had previously set a "Mark" attribute on this paragraph....
   If oCustomXmlAttributes.hasByName( "Mark" ) Then
      ' If there was already a "Mark" attribute, then remove it.
      oCustomXmlAttributes.removeByName ( "Mark" )
   EndIf
   
   ' Store the collection of attributes back to the property.
   oCell.UserDefinedAttributes = oCustomXmlAttributes
End Sub



' Sugar coating to create an AttributeData struct, initialize and return it.
Function CreateAttributeData( cValue )
   oAttributeData = createUnoStruct( "com.sun.star.xml.AttributeData" )
   oAttributeData.Type = "CDATA"
   oAttributeData.Value = cValue
   CreateAttributeData = oAttributeData
End Function


The properties persist across saving the document.

Here is how to retrieve a property from cell B5...
Code:
Sub Main
   oDoc = ThisComponent
   oSheet = oDoc.getSheets().getByName( "Sheet1" )
   
   ' Get cell B5.
   oCell = oSheet.getCellRangeByName( "B5" ).getCellByPosition( 0, 0 )
   
   ' Get the collection of attributes.
   oCustomXmlAttributes = oCell.UserDefinedAttributes
   
   Print "Attribute John is: ", oCustomXmlAttributes.getByName( "John" ).Value
End Sub


When you look in the saved document's content.xml file, you can find this....
Code:
....stuff omitted....
<style:properties John="Blue" Bill="Green" Jason="Purple" Tom="Red" David="Orange"/>
.....more stuff omitted....

_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
cbosdonnat
Power User
Power User


Joined: 14 Nov 2004
Posts: 61
Location: France - Lyon

PostPosted: Thu Mar 10, 2005 12:07 am    Post subject: Reply with quote

Hello Danny,

I got the solution for the ParaUserDefinedAttributes : we should not access them thru a cursor, but thru the ThisComponent.Text.createEnumeration. The code looks like this, with an existing document which I apply an attribute on the first paragraph :
Code:
SUB TestAttributes

   DIM oText, oPara AS OBJECT
   DIM oProperties, oAttributeData AS OBJECT
   
   oText = ThisComponent.Text
   oPara = oText.createEnumeration.nextElement()
   
   oProperties = oPara.getPropertyValue("ParaUserDefinedAttributes")
   
   IF ( oProperties.hasByName("CodeLanguage") ) THEN
      Print "Test 1 : " + oProperties.getByName("CodeLanguage").Value
   ELSE
   
      oAttributeData = createUnoStruct("com.sun.star.xml.AttributeData")
      oAttributeData.Type = "CDATA"
      oAttributeData.Value= "java"
      
      oProperties.insertByName("CodeLanguage", oAttributeData)
      oPara.ParaUserDefinedAttributes = oProperties
      
      WITH oPara.ParaUserDefinedAttributes
         Print "Test 2 - Type : " + .getByName("CodeLanguage").Type+ " valeur : " + _
                              .getByName("CodeLanguage").Value
      END WITH
      
   END IF

END SUB


I hope that could help others ...
Thanks for your help

Cedric
_________________
Perso: http://cedric.bosdonnat.free.fr
Back to top
View user's profile Send private message Visit poster's website
zaim
Newbie
Newbie


Joined: 02 Apr 2005
Posts: 2
Location: Malaysia

PostPosted: Sat Apr 02, 2005 8:49 am    Post subject: Reply with quote

hello all, this is my first post here in oooforums, so pls be nice Smile

I have one question: is there any way to store persistant values other than strings? I dug around the API documentation and found out that the Value property of com.sun.star.xml.AttributeData is a String. So my question here is, if I wanted to store, say an Array or even another structure, is there a way in Basic to "serialize" these values into strings?

Another thing is that I tried out the code for storing persistant attributes in Writer, and there seemed to be a problem for setting an attribute. I couldn't reset an attribute, e.g. the attribute is set the first time StoreCustomAttribute is called, but if I wanted to change it's value, calling it again didn't work). So I messed around with it and found out that I needed to call oUserDefinedAttributes.replaceByName() after setting the new oAttribute.Value: (i removed some comments):
Code:
Sub StoreCustomAttribute_Writer( oDoc, cShapeName, cAttributeName, cAttributeValue )
   oDrawPage = oDoc.getDrawPage()
   oShape = FindShapeByName( oDrawPage, cShapeName )

   If IsNull( oShape ) Or IsEmpty( oShape ) Then
      oShape = oDoc.createInstance( "com.sun.star.drawing.RectangleShape" )

      oShape.FillStyle = com.sun.star.drawing.FillStyle.NONE
      oShape.LineStyle = com.sun.star.drawing.LineStyle.NONE
      oShape.Position = MakePoint( -10000, -10000 ) 'somewhere where you can't click on it
      oShape.Size = MakeSize( 1, 1 ) 'teeny tiny

      oDrawPage.add( oShape )
      oShape.Name = cShapeName
   EndIf

   oUserDefinedAttributes = oShape.UserDefinedAttributes

   If oUserDefinedAttributes.hasByName( cAttributeName ) Then
      oMyAttribute = oUserDefinedAttributes.getByName( cAttributeName )
      oMyAttribute.Value = cAttributeValue

      ' -----------------
      ' changed code here
      ' -----------------
      oUserDefinedAttributes.replaceByName(cAttributeName, oMyAttribute)
   Else
      oMyAttribute = createUnoStruct( "com.sun.star.xml.AttributeData" )
      With oMyAttribute
         .Type = "CDATA"
         .Value = cAttributeValue
      End With
      oUserDefinedAttributes.insertByName( cAttributeName, oMyAttribute )
   EndIf
   
   oShape.UserDefinedAttributes = oUserDefinedAttributes
End Sub


So lastly, thanks Dannyb for your excellent snippets! Smile
Back to top
View user's profile Send private message Visit poster's website
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Sat Apr 02, 2005 9:56 am    Post subject: Reply with quote

zaim wrote:
is there any way to store persistant values other than strings? I dug around the API documentation and found out that the Value property of com.sun.star.xml.AttributeData is a String. So my question here is, if I wanted to store, say an Array or even another structure, is there a way in Basic to "serialize" these values into strings?

That is probably exactly what you would need to do. "Serialize" them somehow into a string. Somebody somewhere has to write that serialization code. Either you have to do that, or some other code in OOo would have to do it. Since OOo only stores strings, you have to do it yourself.

Do see my thread about in Code Snippets about manipulating property values. In that thread I do show another way to "serialize" an array of property values, with arbitrary scalar values into a string, and store that as a new module in a basic macro library.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Wed May 04, 2005 11:15 am    Post subject: Reply with quote

For a Python example of storing and retrieving a custom attribute on a spreadsheet cell, see this....
http://www.oooforum.org/forum/viewtopic.phtml?p=76972#76972

See also....
http://www.oooforum.org/forum/viewtopic.phtml?p=69530#69530
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Code Snippets All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group