Difference between revisions of "Working with properties"

From Apache OpenOffice Wiki
Jump to: navigation, search
Line 257: Line 257:
  
 
[[Category:Basic:Tutorials]]
 
[[Category:Basic:Tutorials]]
[[Category:Tutorials]]
 

Revision as of 17:54, 16 May 2006

The following routines all deal with properties. They are revised routines from my RevealCodes macro, and the main routine which demonstrates calling some of the other routines displays the changes in "codes" for the current paragraph.

fnNotIn

The following routine compares two arrays or property beans, and returns an array of property beans for those items which are in array mProp1 but not in mProp2, or where the value is different.

[oobas] function fnNotIn(mProp1, mProp2) 'Returns an array of the properties in mProp1 not found in mProp2 dim mNotIn() n1 = uBound(mProp1) n2 = uBound(mProp2) if n2 < 0 then

       fnNotIn = mProp1

else

       for i = 0 to n1
               sName1 = mProp1(i).name
               bNotFound = true
               for j = 0 to n2
                       sName2 = mProp2(j).name
                       if sName1 = sName2 then
                               bNotFound = not fnEqualValues(mProp1(i).value, mProp2(j).value)
                               exit for
                       elseif sName2 > sName1 then
                               exit for
                       end if
               next
               if bNotFound then subAddThisProperty(mNotIn(), mProp1(i))
       next
       fnNotIn = mNotIn()

end if end function


fnEqualValues

This routine is not strictly dealing with properties but is called by fnNotIn, so is included here. The function is recursive so will only work in OpenOffice.org 1.1.1 or greater. Compares two values of the same type and returns whether they are equal or not. Currently it doesn't work for structs or objects (if you know how to do this please edit this page!)

[oobas] function fnEqualValues(vValue1, vValue2) as boolean 'Returns true if the values are equal

if isArray(vValue) then

       nUpperBound1 = uBound(vValue1)
       nUpperBound2 = uBound(vValue2)
       if nUpperBound1 <> nUpperBound2 then
               fnEqualValues = false
       elseif nUpperBound1 = -1 then
               fnEqualValues = true
       else
               for i = 0 to nUpperBound1
                       if not fnEqualValues(vValue1, vValue2) then
                               fnEqualValues = false
                               exit for
                       end if
               next
       end if

elseif isUNOstruct(vValue) then

       fnEqualValues = true 'Assume true as I don't know how to compare them

else

       select case varType(vValue)
       case 2-5,7, 8, 11 'numbers, date, string boolean
               fnEqualValues = vValue1 = vValue2
       case 9  'object ???
                       fnEqualValues = true 'Assume true as I don't know how to compare them
       case else
               fnEqualValues = true
       end select

end if end function


subAddThisProperty

This routine adds a property bean to the end of a one dimensional array.

[oobas] sub subAddThisProperty(mProperties, mProperty) nNext = uBound(mProperties) + 1 redim preserve mProperties(nNext) set mProperties(nNext) = mProperty end sub


fnDirectProperties

Returns an array of property beans of directly applied properties to a text range (should work for other types of objects but has not been tested).

[oobas] function fnDirectProperties(oTextRange) 'Returns an array of property beans of directly applied properties oProperties = oTextRange.getPropertySetInfo.getProperties nProperties = uBound(oProperties) dim mDirectProperties() for i = 0 to nProperties

       sName = oProperties(i).name
       if oTextRange.getPropertyState(sName) <> com.sun.star.beans.PropertyState.DEFAULT_VALUE and _
        ((oProperties(i).attributes and com.sun.star.beans.PropertyAttribute.READONLY) = 0) then 
               nTypeClass = oProperties(i).type.typeClass
               subAddProperty( mDirectProperties(),sName, oTextRange.getPropertyValue(sName))
       end if

next fnDirectProperties = mDirectProperties() end function


fnPropertyValues

Returns an array of strings for the property names and their values. You could think of this as being a form of introspection.

[oobas] function fnPropertyValues(mProperties) 'returns an array of strings for the property names and their values nProperties = Ubound(mProperties) if nProperties < 0 then

       fnPropertyValues = array("")
       exit function

end if dim mPropertyValues(nProperties) for i = 0 to nProperties

       mPropertyValues(i) = fnPropertyValue(mProperties(i))

next fnPropertyValues = mPropertyValues() end function


fnPropertyValue

Returns the concatentaion of a property name and its value as a string

[oobas] function fnPropertyValue(aProperty) as string 'Returns the concatentaion of a property name and its value as a string if isNull(aProperty) or isEmpty(aProperty) then

       fnPropertyValue = ""
       msgbox "Oops!"

else

       sName = aProperty.name
       vValue = aProperty.Value
       fnPropertyValue = sName & ": " & fnConvString(vValue)

end if end function


fnConvString

Converts a variables value to a string. Currently if the variable is a struct or object it simply returns "Struct" or "Object". (If you know a better way please edit this page!)

[oobas] function fnConvString(vValue) as string 'Converts a variant to a string if isArray(vValue) then

       nUpperBound = uBound(vValue)
       if nUpperBound = 0 then
               fnConvString = ""
       else
               s = "{"
               for i = 0 to nUpperBound
                       s = s & fnConvString(vValue(i)) & ","
               next
               nLen = len(s)
               if nLen > 1 then
                       fnConvString = left(s, len(s) - 1) & "}"
               end if
       end if

elseif isUNOstruct(vValue) then

       fnConvString = "Struct"

else

       select case varType(vValue)
       case 0, 2 to 5,7 'empty, numbers, date
               fnConvString = cstr(vValue)
       case 8  'string
               fnConvString = vValue
       case 9  'object ???
               fnConvString = "Object"
       case 11 'boolean
               if vValue then
                       fnConvString = "True"
               else
                       fnConvString = "False"
               end if
       case else
               fnConvString = ""'vValue
               msgbox varType(vValue)
       end select

end if end function


subAddProperty

This routine calls fnNewProperty to create new property bean, assign a name and optionally a value, and adds the new property bean to a one dimensional array.

[oobas] sub subAddProperty(mProperties, sName, optional vValue) nNext = uBound(mProperties) + 1 redim preserve mProperties(nNext) if isMissing(vValue) then

       mProperties(nNext) = fnNewProperty(sName)

else

       mProperties(nNext) = fnNewProperty(sName, vValue)

end if end sub

fnNewProperty

Create new property bean, assign a name and optionally a value, returns the new property bean.

[oobas] function fnNewProperty(sName, optional vValue) aProperty = createUnoStruct("com.sun.star.beans.PropertyValue") aProperty.Name = sName if not isMissing(vValue) then

       aProperty.Value = vValue

end if fnNewProperty = aProperty end function

Example - Displaying 'codes' of a paragraph

This example demonstrates calling fnDirectProperties, fnNotIn, and fnPropertyValues defined above. It shows how the above codes could be used in a "reveal codes" type macro. The join statement is just a quick and dirty way of creating a string out of an array of strings for displaying in the messagebox.

[oobas] sub main oParagraph = fnGetCurrentParagraph mParaProperties = fnDirectProperties(oParagraph) msgbox join(fnPropertyValues(mParaProperties), chr(10)), 0 , "Paragraph properties" oPortionEnum = oParagraph.createEnumeration i = 0 while oPortionEnum.hasMoreElements

       i = i + 1
       oPortion = oPortionEnum.nextElement
       mCurProperties = fnDirectProperties(oPortion)
       if i > 1 then
               mCloseProperties = fnNotIn(mPrevProperties, mCurProperties)
               msgbox join(fnPropertyValues(mCloseProperties), chr(10)), 0 , "Portion " & i & " close properties"
               mOpenProperties = fnNotIn(mCurProperties, mPrevProperties)
       else
               mOpenProperties = mCurProperties
       end if
       msgbox join(fnPropertyValues(mOpenProperties), chr(10)), 0 , "Portion " & i & " open properties"
       set mPrevProperties = mCurProperties

wend msgbox join(fnPropertyValues(mPrevProperties), chr(10)), 0 , "Portion " & i & " close properties" end sub


function fnGetCurrentParagraph 'Returns the whole paragraph that the insertion point is in oVC = thisComponent.getCurrentController.getViewCursor oCursor = oVC.text.createTextCursorByRange(oVC) oCursor.gotoStartOfParagraph(false) oCursor.gotoEndOfParagraph(true) fnGetCurrentParagraph = oCursor.createEnumeration.nextElement end function

Personal tools