Difference between revisions of "Working with properties"

From Apache OpenOffice Wiki
Jump to: navigation, search
(fnEqualValues: fix several errors: vValue undefined, recursion not subscripted and would never return True.)
m (fnDirectProperties)
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
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.
+
The following routines all deal with properties. They are revised routines from my [https://wiki.openoffice.org/wiki/File:RevealCodes3.odt RevealCodes] macro, and the main routine which demonstrates calling some of the other routines displays the changes in "codes" for the current paragraph.
  
 
=fnNotIn=
 
=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.  
 
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.  
  
<source lang="oobas">
+
<syntaxhighlight lang="oobas">
 
function fnNotIn(mProp1, mProp2)
 
function fnNotIn(mProp1, mProp2)
 
'Returns an array of the properties in mProp1 not found in mProp2
 
'Returns an array of the properties in mProp1 not found in mProp2
Line 30: Line 30:
 
end if
 
end if
 
end function
 
end function
</source>
+
</syntaxhighlight>
  
  
Line 36: Line 36:
 
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!)  
 
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!)  
  
<source lang="oobas">
+
<syntaxhighlight lang="oobas">
 
function fnEqualValues(vValue1, vValue2) as boolean
 
function fnEqualValues(vValue1, vValue2) as boolean
 
'Returns true if the values are equal
 
'Returns true if the values are equal
Line 71: Line 71:
 
end if
 
end if
 
end function
 
end function
</source>
+
</syntaxhighlight>
  
 
=subAddThisProperty=
 
=subAddThisProperty=
 
This routine adds a property bean to the end of a one dimensional array.  
 
This routine adds a property bean to the end of a one dimensional array.  
  
<source lang="oobas">
+
<syntaxhighlight lang="oobas">
 
sub subAddThisProperty(mProperties, mProperty)
 
sub subAddThisProperty(mProperties, mProperty)
 
nNext = uBound(mProperties) + 1
 
nNext = uBound(mProperties) + 1
Line 82: Line 82:
 
set mProperties(nNext) = mProperty
 
set mProperties(nNext) = mProperty
 
end sub
 
end sub
</source>
+
</syntaxhighlight>
  
  
 
=fnDirectProperties=
 
=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).  
+
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).
  
<source lang="oobas">
+
{{Warn|This routine may require a workaround for {{Bug|103670}}. See the [[Talk:Working with properties|Talk page]].}}
 +
 
 +
<syntaxhighlight lang="oobas">
 
function fnDirectProperties(oTextRange)
 
function fnDirectProperties(oTextRange)
 
'Returns an array of property beans of directly applied properties
 
'Returns an array of property beans of directly applied properties
Line 104: Line 106:
 
fnDirectProperties = mDirectProperties()
 
fnDirectProperties = mDirectProperties()
 
end function
 
end function
</source>
+
</syntaxhighlight>
 
+
  
 
=fnPropertyValues=
 
=fnPropertyValues=
 
Returns an array of strings for the property names and their values. You could think of this as being a form of introspection.  
 
Returns an array of strings for the property names and their values. You could think of this as being a form of introspection.  
  
<source lang="oobas">
+
<syntaxhighlight lang="oobas">
 
function fnPropertyValues(mProperties)
 
function fnPropertyValues(mProperties)
 
'returns an array of strings for the property names and their values
 
'returns an array of strings for the property names and their values
Line 124: Line 125:
 
fnPropertyValues = mPropertyValues()
 
fnPropertyValues = mPropertyValues()
 
end function
 
end function
</source>
+
</syntaxhighlight>
  
  
 
=fnPropertyValue=
 
=fnPropertyValue=
Returns the concatentaion of a property name and its value as a string  
+
Returns the concatenation of a property name and its value as a string  
  
<source lang="oobas">
+
<syntaxhighlight lang="oobas">
 
function fnPropertyValue(aProperty) as string
 
function fnPropertyValue(aProperty) as string
 
'Returns the concatentaion of a property name and its value as a string
 
'Returns the concatentaion of a property name and its value as a string
Line 142: Line 143:
 
end if
 
end if
 
end function
 
end function
</source>
+
</syntaxhighlight>
 
+
  
 
=fnConvString=
 
=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!)  
 
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!)  
  
<source lang="oobas">
+
<syntaxhighlight lang="oobas">
 
function fnConvString(vValue) as string
 
function fnConvString(vValue) as string
 
'Converts a variant to a string
 
'Converts a variant to a string
Line 187: Line 187:
 
end if
 
end if
 
end function
 
end function
</source>
+
</syntaxhighlight>
  
  
Line 193: Line 193:
 
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.  
 
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.  
  
<source lang="oobas">
+
<syntaxhighlight lang="oobas">
 
sub subAddProperty(mProperties, sName, optional vValue)
 
sub subAddProperty(mProperties, sName, optional vValue)
 
nNext = uBound(mProperties) + 1
 
nNext = uBound(mProperties) + 1
Line 203: Line 203:
 
end if
 
end if
 
end sub
 
end sub
</source>
+
</syntaxhighlight>
  
 
=fnNewProperty=
 
=fnNewProperty=
 
Create new property bean, assign a name and optionally a value, returns the new property bean.  
 
Create new property bean, assign a name and optionally a value, returns the new property bean.  
  
<source lang="oobas">
+
<syntaxhighlight lang="oobas">
 
function fnNewProperty(sName, optional vValue)
 
function fnNewProperty(sName, optional vValue)
 
aProperty = createUnoStruct("com.sun.star.beans.PropertyValue")
 
aProperty = createUnoStruct("com.sun.star.beans.PropertyValue")
Line 217: Line 217:
 
fnNewProperty = aProperty
 
fnNewProperty = aProperty
 
end function
 
end function
</source>
+
</syntaxhighlight>
  
 
=Example - Displaying 'codes' of a paragraph=
 
=Example - Displaying 'codes' of a paragraph=
This example demonstrates calling <tt>fnDirectProperties</tt>, <tt>fnNotIn</tt>, and <tt>fnPropertyValues</tt> 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.  
+
This example demonstrates calling <tt>fnDirectProperties</tt>, <tt>fnNotIn</tt>, and <tt>fnPropertyValues</tt> 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.  
  
<source lang="oobas">
+
<syntaxhighlight lang="oobas">
 
sub main
 
sub main
 
oParagraph = fnGetCurrentParagraph
 
oParagraph = fnGetCurrentParagraph
Line 245: Line 245:
 
msgbox join(fnPropertyValues(mPrevProperties), chr(10)), 0 , "Portion " & i & " close properties"
 
msgbox join(fnPropertyValues(mPrevProperties), chr(10)), 0 , "Portion " & i & " close properties"
 
end sub
 
end sub
 
 
   
 
   
 
function fnGetCurrentParagraph
 
function fnGetCurrentParagraph
Line 255: Line 254:
 
fnGetCurrentParagraph = oCursor.createEnumeration.nextElement
 
fnGetCurrentParagraph = oCursor.createEnumeration.nextElement
 
end function
 
end function
 
+
</syntaxhighlight>
</source>
+
  
 
[[Category:Basic:Tutorials]]
 
[[Category:Basic:Tutorials]]

Latest revision as of 14:48, 24 August 2022

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.

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!)

function fnEqualValues(vValue1, vValue2) as boolean
'Returns true if the values are equal
 
if varType(vValue1) <> varType(vValue2) then
        fnEqualValues = false       
elseif isArray(vValue1) then
        nUpperBound1 = uBound(vValue1)
        nUpperBound2 = uBound(vValue2)
        if nUpperBound1 <> nUpperBound2 then
                fnEqualValues = false
        elseif nUpperBound1 = -1 then
                fnEqualValues = true
        else
                fnEqualValues = true
                for i = 0 to nUpperBound1
                        if not fnEqualValues(vValue1(i), vValue2(i)) then
                                fnEqualValues = false
                                exit for
                        end if
                next
        end if
elseif isUNOstruct(vValue1) then
        fnEqualValues = true 'Assume true as I don't know how to compare them
else
        select case varType(vValue1)
        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.

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).

Documentation caution.png This routine may require a workaround for Issue 103670 . See the Talk page.
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.

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 concatenation of a property name and its value as a string

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!)

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.

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.

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.

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