| View previous topic :: View next topic |
| Author |
Message |
Sarah General User

Joined: 04 Aug 2004 Posts: 8
|
Posted: Wed Aug 04, 2004 2:09 am Post subject: heyperlinks in a TOC |
|
|
Hello,
I have problems with inserting hyperlinks in a table content
I have read the developer's guide and It tells about property values, so I need the property TokenType with the 2 values TokenHyperlinkStart and TokenHyperlinkEnd but how to work with them? how to assign them to the tableContent?
thanks for any help
Sarrah |
|
| Back to top |
|
 |
pitonyak Administrator


Joined: 09 Mar 2004 Posts: 3618 Location: Columbus, Ohio, USA
|
Posted: Wed Aug 04, 2004 6:00 pm Post subject: |
|
|
I do not know the answer to your question, but I do know something about how this works. I also happen to suspect that perhaps you may need to set this before you insert it but I base this on nothing in particular.
First, you need to obtain the index or insert a new one.
| Code: | Dim oCurs 'Used to insert the text content.
Dim oIndexes 'All of the existing indexes
Dim oIndex 'The TOC if it exists and a new one if not
Dim i As Integer 'Find an existing TOC
Dim bIndexFound As Boolean 'Flag to track if the TOC was found
REM First, find an existing TOC if it exists. If so,
REM then this will simply be updated.
oIndexes = ThisComponent.getDocumentIndexes()
bIndexFound = False
For i = 0 To oIndexes.getCount() - 1
oIndex = oIndexes.getByIndex(i)
If oIndex.supportsService("com.sun.star.text.ContentIndex") Then
bIndexFound = True
Exit For
End If
Next
If Not bIndexFound Then
Print "I did not find an existing content index"
REM Perhaps you should create and insert a new one!
REM Notice that this MUST be created by the document that will contain
REM the index.
oIndex = ThisComponent.createInstance("com.sun.star.text.ContentIndex")
REM On my system, these are the default values
REM How do you want to create the index?
REM CreateFromChapter = False
REM CreateFromLevelParagraphStyles = False
REM CreateFromMarks = True
REM CreateFromOutline = False
oIndex.CreateFromOutline = True
REM You can set all sorts of other things such as the
REM Title or Level
oCurs = ThisComponent.getText().createTextCursor()
oCurs.gotoStart(False)
ThisComponent.getText().insertTextContent(oCurs, oIndex, False)
End If |
Now, you have in index to look at. You want to know how things are formatted. We need a few variables. Hopefully, this is sufficient.
| Code: | Dim iIndexLevel
Dim iProperty
Dim oLevel
Dim oNewLevel
Dim oProperties
Dim oProperty
Dim bHasEntry As Boolean
Dim bHasHyperLink As Boolean |
This code demonstrates how to traverse the entries, which are stored essentially as an array of arrays.
| Code: | REM For each index level
For iIndexLevel = 0 To oIndex.LevelFormat.getCount() - 1
oLevel = oIndex.LevelFormat.getByIndex(iIndexLevel)
Print "level = " & iIndexLevel
Inspect(oLevel)
REM Now, check each level to see if it uses a hyperlink
REM Obtain all of the properties for each level.
REM See the com.sun.star.text.DocumentIndexLevelFormat
REM service for supported values.
bHasEntry = False
bHasHyperLink = False
For iProperty = LBound(oLevel) To UBound(oLevel)
REM But, of course, each property is really an array
REM of tokens!
oProperties = oLevel(iProperty)
For i = LBound(oProperties) To UBound(oProperties)
REM Each property is a com.sun.star.beans.PropertyValue structure
oProperty = oProperties(i)
If oProperty.Name = "TokenType" Then
REM This is the entry for the property that
If oProperty.Value = "TokenHyperlinkStart" Then
bHasHyperLink = True
ElseIf oProperty.Value = "TokenEntryText" Then
bHasEntry = True
EndIf
EndIf
Next
Next
If bHasEntry AND BHasHyperLink Then
Print "They are all present in level " & iIndexLevel
EndIf
REM If there is an entry and no hyperlink, then
REM the hyperlink entry needs to be added!
If bHasEntry AND NOT BHasHyperLink Then
REM ?? This is where you need to modify the current level!
EndIf
Next
REM Even the newly inserted index is not updated until right HERE!
oIndex.update() |
The code above, at least figures out which items require a modified entry.
Off hand, I am not certain how to do this. I mean, I have code that tries, but I always endup with the wrong type. So, here is my first attempt at the missing code above. Note that this code will NOT run. Perhaps someone can tell me why.
| Code: | i = LBound(oLevel)
REM The New array will have room for two new elements!
oNewLevel = DimArray(UBound(oLevel) + 2)
For iProperty = LBound(oLevel) To UBound(oLevel)
bHasEntry = False
If bHasEntry Then
REM Already found the entry and added the hyperlink token
oNewLevel(i) = oLevel(iProperty)
i = i + 1
Else
oProperties = oLevel(iProperty)
For i = LBound(oProperties) To UBound(oProperties)
oProperty = oProperties(i)
If oProperty.Name = "TokenType" AND oProperty.Value = "TokenEntryText" Then
bHasEntry = True
oProperty = CreateUnoStruct("com.sun.star.beans.PropertyValue")
oProperty.Name = "TokenType"
oProperty.Value = "TokenHyperlinkStart"
oProperty.Handle = -1
oProperty.State = com.sun.star.beans.PropertyState.DIRECT_VALUE
oNewLevel(i) = Array(oProperty)
oNewLevel(i+1) = oProperties
oProperty = CreateUnoStruct("com.sun.star.beans.PropertyValue")
oProperty.Name = "TokenType"
oProperty.Value = "TokenHyperlinkEnd"
oProperty.Handle = -1
oProperty.State = com.sun.star.beans.PropertyState.DIRECT_VALUE
oNewLevel(i+2) = Array(oProperty)
i = i + 3
EndIf
Next
If NOT bHasEntry Then
oNewLevel(i) = oLevel(iProperty)
i = i + 1
EndIf
End If
Next
oIndex.LevelFormat.replaceByIndex(iIndexLevel, oNewLevel)
EndIf |
The above code fails when I attempt to place the new level in place because of an illegal argument. This is probably expecting an array of type object. Each contained object should be an array of Uno Structures. As it stands, each array is of type Varient. Perhaps this is the problem. It is also possible that I have populated the PropertyValue with an incorrect value. I spent about an hour playing with this and that is enough for the moment. _________________ --
Andrew Pitonyak
http://www.pitonyak.org/oo.php |
|
| Back to top |
|
 |
Sarah General User

Joined: 04 Aug 2004 Posts: 8
|
Posted: Thu Aug 05, 2004 5:48 am Post subject: |
|
|
Thank you Pitonyak for your help,
You have understood my problem and your solution is very intersting, but the instruction:
| Code: | oIndex.LevelFormat.replaceByIndex(iIndexLevel, oNewLevel)
| is incorrect and I don't know why,
I have inserted your third code in :
| Code: |
If bHasEntry AND NOT BHasHyperLink Then
REM ?? This is where you need to modify the current level!
EndIf
|
but it doesn't insert any hyperlink at the current level
thanks |
|
| Back to top |
|
 |
pitonyak Administrator


Joined: 09 Mar 2004 Posts: 3618 Location: Columbus, Ohio, USA
|
Posted: Thu Aug 05, 2004 7:49 am Post subject: |
|
|
Yes, this is the problem that I had as well. As I stated, I do not know the correct way to do this. I just know what it needs to look like when it is finished. The initial code with the double question marks is simply identifying where a change can be made. The problem is that you need to know how to create the appropriate data structure. My initial thought was that I could simply create an array and then replace the old array. Unfortunately, this did not work. A casual inspection of the array demonstrates that the array that I created is of type Variant() and the type that is used internally is Object().
I know that the solution does not work, but I stopped working on it because I did not have time to finish. I thought, however, that my initial attempt might be useful because it at least demonstrates how the structure should appear. I am not certain what is wrong with my initial solution. I was hoping that another person would look at the solution and say "Andy, you need to do ...." and then it would work _________________ --
Andrew Pitonyak
http://www.pitonyak.org/oo.php |
|
| Back to top |
|
 |
Sarah General User

Joined: 04 Aug 2004 Posts: 8
|
Posted: Fri Aug 06, 2004 8:00 am Post subject: |
|
|
Please, can anyone help a beginner to insert hyperlinks in a toc?
thank you Pitonyak for your efforts |
|
| Back to top |
|
 |
pitonyak Administrator


Joined: 09 Mar 2004 Posts: 3618 Location: Columbus, Ohio, USA
|
Posted: Fri Aug 06, 2004 1:31 pm Post subject: |
|
|
I recommend that you post what you have so far to the dev@api.openoffice.org mailing list. You will, of course, want to subscribe. See if you get any help there as well. _________________ --
Andrew Pitonyak
http://www.pitonyak.org/oo.php |
|
| Back to top |
|
 |
cbosdonnat Power User


Joined: 14 Nov 2004 Posts: 61 Location: France - Lyon
|
Posted: Wed Jan 19, 2005 1:27 am Post subject: |
|
|
Hi,
I'm really glad to find your topic about accessing Indexes LevelFormat properties. I want to change the CharacterStyleName of The Hyperlink token, but I get a problem :
The structure is changed with the right values, but I wonder if the getByIndex gives a reference to the wanted object or if it is a copy of the object. In fact I seem to work on a copy of my index, so the real index is not modified ... And the DocumentIndexes class doesn't implements the XReplaceByIndex interface.
Could you help me updating my index ?
Thanks
Cedric
PS : I work with a Basic Macro _________________ Perso: http://cedric.bosdonnat.free.fr |
|
| Back to top |
|
 |
cbosdonnat Power User


Joined: 14 Nov 2004 Posts: 61 Location: France - Lyon
|
Posted: Wed Jan 19, 2005 2:31 am Post subject: |
|
|
Hi Andy,
| pitonyak wrote: | A casual inspection of the array demonstrates that the array that I created is of type Variant() and the type that is used internally is Object().
[...]
I was hoping that another person would look at the solution and say "Andy, you need to do ...." and then it would work |
Could we create a new sevice DocumentIndexLevelFormat from the Variant ? It sould be oan object expected by the XIndexReplace. Else is it possible to cast in Basic ?
I'm working on the same problem, and will let you know if I find something
Bye,
Cedric _________________ Perso: http://cedric.bosdonnat.free.fr |
|
| Back to top |
|
 |
cbosdonnat Power User


Joined: 14 Nov 2004 Posts: 61 Location: France - Lyon
|
Posted: Wed Jan 19, 2005 6:22 am Post subject: |
|
|
Hi Andy and Sarah,
| Code: | Sub ObjectsArray
Dim a(3) As Object
a(0) = createUnoStruct(com.sun.star.beans.PropertyValue)
a(1) = createUnoStruct(com.sun.star.beans.PropertyValue)
' Do not forget the parenthesis in the a() to point to the array
' Create a new array of Objects a bit longer than a
Dim b(UBound(a())+1)
' Use the array with no DimArray() or Array() because they returns
' an array of variants
' Now You have to refill the b array with a values
For i = LBound(a()) To UBound(a())
b(i) = a(i)
Next i
' And then add your new element to b
b(2) = createUnoStruct(com.sun.star.beans.PropertyValue)
' b is still an array of Objects ...
' So you can use it in your script to change the levelFormat
Print TypeName(b())
End Sub |
I found what you searched ... You use the Array() and DimArray functions and they return arrays of variants : That is the problem.
I hope this helps _________________ Perso: http://cedric.bosdonnat.free.fr |
|
| Back to top |
|
 |
pitonyak Administrator


Joined: 09 Mar 2004 Posts: 3618 Location: Columbus, Ohio, USA
|
|
| Back to top |
|
 |
ildella General User

Joined: 31 May 2007 Posts: 14
|
|
| Back to top |
|
 |
sandyraghav General User

Joined: 16 Jul 2007 Posts: 13
|
Posted: Thu Sep 20, 2007 7:30 am Post subject: heyperlinks in a TOC using Visual Basic 6.0 |
|
|
Hi,
I have tried using your code in Visual Basic and it always throws IllegalArgumentException.
As per cbosdonnat this error is because of wrong data type(if i am not wrong) but when I check the API documentation I have found that replaceByIndex method requires two argument - 1st one as Long and 2nd one as Any
As we do not have Any in Visual Basic, I have created an array of variants but this does not work.
Also, we can not convert array of variants to objects as suggested by cbosdonnat and hence the solution does not work.
Could anyone let me know what we have to do in Visual Basic in order to fix this issue?
thanks in advance  _________________ Impossible is nothing!!! |
|
| Back to top |
|
 |
Danad OOo Advocate

Joined: 22 Feb 2004 Posts: 293 Location: Brasil
|
|
| Back to top |
|
 |
sandyraghav General User

Joined: 16 Jul 2007 Posts: 13
|
Posted: Fri Sep 21, 2007 12:15 am Post subject: |
|
|
Hi,
Thanks for the response, I have tried using the same logic but always ends up with getting the automation error
Error: [automation bridge] unexpected exception in UnoConversionUtilities<T>::convertValueObject ! Message : [automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper
The variant does not contain an object type!
Here is my code:
| Code: | //////////////////////////////////////////////////////////////////////////////////////////////////
Dim iIndexLevel As Long
Dim oLevelFormat As Object
Dim arrLevelFormat
Dim i As Integer
Dim arrTemp(0) As Variant
Dim arrTempNew(0) As Variant
Dim oProperty As Object
Dim oPropertyNew As Object
Dim iCount As Integer
Dim newFormat() As Variant
Set oLevelFormat = oTOC.LevelFormat
For iIndexLevel = 0 To oLevelFormat.getCount() - 1
arrLevelFormat = oLevelFormat.getByIndex(iIndexLevel)
If IsArray(arrLevelFormat) And UBound(arrLevelFormat) > 0 Then
iCount = UBound(arrLevelFormat)
ReDim newFormat(iCount + 2) As Variant
Set oProperty =
oSM.Bridge_GetStruct("com.sun.star.beans.PropertyValue")
oProperty.name = "TokenType"
oProperty.Value = "TokenHyperlinkStart"
Set arrTemp(0) = oProperty
newFormat(0) = arrTemp
For i = 0 To UBound(arrLevelFormat)
newFormat(i + 1) = arrLevelFormat(i)
Next
Set oPropertyNew =
oSM.Bridge_GetStruct("com.sun.star.beans.PropertyValue")
oPropertyNew.name = "TokenType"
oPropertyNew.Value = "TokenHyperlinkEnd"
Set arrTempNew(0) = oPropertyNew
newFormat(UBound(arrLevelFormat) + 2) = arrTempNew
Dim unoWrap As Variant
Set unoWrap = oSM.Bridge_GetValueObject
unoWrap.Set "[]com.sun.star.beans.PropertyValue", newFormat
Call oTOC.LevelFormat.replaceByIndex(iIndexLevel, unoWrap) ' Here is the error
End If
Next
oTOC.Update
///////////////////////////////////////////////////////////////////////////////////////////////////////// |
may be I am doing something stupid here, can anyone help? any idea?
thanks _________________ Impossible is nothing!!! |
|
| Back to top |
|
 |
B Marcelly Super User

Joined: 12 May 2004 Posts: 1414 Location: France
|
Posted: Fri Sep 21, 2007 1:43 am Post subject: |
|
|
Hi,
Trying to understand a Table of Contents with Xray, I see that it is a very complex structure.
Property .LevelFormat is an array of array of array of PropertyValue
Assuming that your code is globally correct, the solution could be to describe exactly the structure of newFormat to the wrapper: | Code: | | unoWrap.Set "[][][]com.sun.star.beans.PropertyValue", newFormat |
______
Bernard |
|
| Back to top |
|
 |
|