Ask Your Question
1

LibreOffice Basic: iterate through all images in a selection?

asked 2018-02-02 14:40:42 +0200

shystar gravatar image

Hi, I'm a novice. I want to write a Writer macro which shrinks all images in a selection (there may be one image selected as well). But I can't even find a manual on Writer data structures. Can you help me with any of these two topics?

edit retag flag offensive close merge delete

Comments

How were these images created? It seems that selecting more than one inserted image (Insert -> Image) is not possible, but selecting more than one drawing object (View -> Toolbars -> Drawing) is possible. We need to know what kind of objects you selected in order to enumerate them.

To figure this out, get the selection in a macro and then pass it to an introspection tool such as MRI.

Jim K gravatar imageJim K ( 2018-02-02 15:35:09 +0200 )edit

3 Answers

Sort by » oldest newest most voted
1

answered 2018-02-02 22:15:52 +0200

librebel gravatar image

Hello @shystar, and welcome to the Ask.LibreOffice forum!

To shrink ( or enlarge ) the selected images in the current Writer document, you could use the following Basic macro:

Sub Writer_Resize_Selected_Images( dPercentage As Double )
REM Resizes selected Images in the current Writer document.
REM <dPercentage>   : Factor by which to scale each image ( 1.0 = 100% ).
    Dim oDoc As Object       : oDoc = ThisComponent
    Dim oSelection As Object : oSelection = oDoc.CurrentSelection
    Dim oSel As Object
    Dim oEnum As Object
    Dim oEnum2 As Object
    Dim oEnum3 As Object
    Dim oParagraph As Object
    Dim oContent As Object
    Dim oPortion As Object
    Dim aNewSize As New com.sun.star.awt.Size
    Dim i As Integer
    If oSelection.supportsService( "com.sun.star.text.TextGraphicObject" ) Then
        aNewSize.Width = oSelection.Size.Width * dPercentage
        aNewSize.Height = oSelection.Size.Height * dPercentage
        oSelection.setSize( aNewSize )
    ElseIf oSelection.supportsService( "com.sun.star.text.TextRanges" ) Then
        For i = 0 To oSelection.getCount() - 1          REM Traverse Selections.
            oSel = oSelection.getByIndex( i )
            oEnum = oSel.createEnumeration()
            Do While oEnum.hasMoreElements()            REM Traverse Paragraphs.
                oParagraph = oEnum.nextElement()
                oEnum2 = oParagraph.createEnumeration()
                Do While oEnum2.hasMoreElements()       REM Traverse TextPortions.
                    oPortion = oEnum2.nextElement()
                    oEnum3 = oPortion.createContentEnumeration( "com.sun.star.text.TextContent" )
                    Do While oEnum3.hasMoreElements()   REM Traverse TextContents.
                        oContent = oEnum3.nextElement()
                        If oContent.supportsService( "com.sun.star.text.TextGraphicObject" ) Then
                            aNewSize.Width = oContent.Size.Width * dPercentage
                            aNewSize.Height = oContent.Size.Height * dPercentage
                            oContent.setSize( aNewSize )
                        End If
                    Loop
                Loop
            Loop
        Next i
    End If
End Sub

With Regards, lib

edit flag offensive delete link more
1

answered 2018-02-02 20:00:03 +0200

The structure of a Text Document is discussed in the "Text Documents" section of the Apache OpenOffice BASIC Programming Guide. See https://wiki.openoffice.org/wiki/Docu....

edit flag offensive delete link more
1

answered 2018-02-02 21:34:28 +0200

updated 2018-02-02 21:35:18 +0200

For all modules (Writer, Calc, Impress, Draw), the graphic objects are iterated using draw pages.

As you are talking about Writer: there is only one global draw page per Writer document, which is accessed using com.sun.star.drawing.XDrawPageSupplier interface. oDoc.DrawPage returns the draw page.

To iterate through objects, you get their count (using oDrawPage.Count), and then get individual objects using oDrawPage(i).

To find out if a graphical object is in selection, you need to know what selection you have. It might be no selection, or a range, or a single object, or multiple objects. You may use this code:

Function IsSelectionEmpty(ByRef oSel)
  IsSelectionEmpty = False
  If (IsNull(oSel)) Then
    IsSelectionEmpty = True
  ElseIf (HasUnoInterfaces(oSel, "com.sun.star.drawing.XShape")) Then
    ' Selected single object - selection is not empty; do nothing '
  ElseIf (HasUnoInterfaces(oSel, "com.sun.star.sheet.XSheetCellRange")) Then
    ' Something is selected anyway '
  ElseIf (oSel.Count = 0) Then
    IsSelectionEmpty = True
  ElseIf ((oSel.Count = 1) And oSel.supportsService("com.sun.star.text.TextRanges")) Then
    With oSel(0)
      If (.text.compareRegionStarts(.getStart, .getEnd)=0) Then
        IsSelectionEmpty = True
      End If
    End With
  End If
End Function

Function IsTextRangeInsideRange(ByRef oRange1, ByRef oRange2)
  IsTextRangeInsideRange = (oRange2.text.compareRegionStarts(oRange1, oRange2)<=0)_
                       And (oRange2.text.compareRegionEnds(oRange1, oRange2)>=0)
End Function

Function IsInSelection(ByRef oObj, ByRef oSel)
  Dim i As Long
  If (IsSelectionEmpty(oSel)) Then
    IsInSelection = True
  ElseIf (HasUnoInterfaces(oSel, "com.sun.star.drawing.XShape")) Then
    IsInSelection = EqualUnoObjects(oObj, oSel)
  ElseIf (HasUnoInterfaces(oSel, "com.sun.star.drawing.XShapes")) Then
    IsInSelection = False
    For i = 0 To oSel.Count - 1
      If (EqualUnoObjects(oObj, oSel(i))) Then
        IsInSelection = True
        Exit For
      End If
    Next i
  Else
    IsInSelection = False
    For i = 0 To oSel.Count - 1
      If (IsTextRangeInsideRange(oObj.Anchor, oSel(i))) Then
        IsInSelection = True
        Exit For
      End If
    Next i
  End If
End Function

After you identified that object is inside selection, then you need to check that it has proper type (e.g., it is an image), and perform required actions.

HTH.

edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2018-02-02 14:40:42 +0200

Seen: 601 times

Last updated: Feb 02 '18