Resize and modify selected chart with libreoffice basic

573 views Asked by At

I'm writing a macro with libreoffice basic to modify the styles and size of a selected (and only selected) chart in my spreadsheets. After many documentation reading and many tries, I managed to have a partial solution to my problem:

Modifying all charts style

I managed to select a chart by it's indexe and modify it's styles with this macro:

Sub ModifyChart
Dim oDoc As Object  
Dim oChart As Object
Dim aSize as new com.sun.star.awt.Size 
  oSheet = ThisComponent.sheets(0)
  oCharts = oSheet.getCharts()
  oChart = oCharts.getByIndex(0).getEmbeddedObject() 

  MsgBox oChart.ImplementationName
  oChart.Title.String = "My title"
  oChart.Title.CharColor = RGB(0,0,200)
  oChart.Title.CharFontName = "Arial"
  oChart.Title.CharHeight = 16

  oChart.SubTitle.String = "My subtitle"
  oChart.SubTitle.CharColor = RGB(0,0,200)
  oChart.SubTitle.CharFontName = "Arial"
  oChart.SubTitle.CharHeight = 12

  oChart.Diagram.Wall.FillStyle = com.sun.star.drawing.FillStyle.SOLID
  oChart.Diagram.Wall.FillColor = RGB(200,50,150) 
    
  oChart.Area.FillStyle = com.sun.star.drawing.FillStyle.SOLID
  oChart.Area.FillColor = RGB(100,50,250)
    
  aSize.Width=640
  aSize.Height=400

  oChart.setsize(aSize)  ' Error occur at this point
End Sub

Problem: It's doesn't work with the selected chart and I can't resize it. The method setsize doesn't work for this kind of object. I tryed to get the parent object of the chart ( frame ? or shape ?) without success.

With ImplementationName, I found that the object is a com.sun.star.comp.sc.scshapeobj

Modifying the selected chart size

I managed to modify the selected chart size by using this macro

Sub ResizeChart
Dim oCurrSel As Object
Dim oItem As Object
Dim aSize As New com.sun.star.awt.Size
  oCurrSel = ThisComponent.getCurrentSelection()
  oItem = oCurrSel.getByIndex(0)
  MsgBox oItem.ImplementationName
  aSize.width=16000
  aSize.height=12000
  oItem.setsize(aSize)
End Sub

Problem: I can't access to the other styles of the chart. I tryed to find a method to get the object content without success. I also tryed to investigate the object with oItem.dbg_properties and oItem.dbg_methods but I didn't found anything useful.

With ImplementationName, I found that the object is a com.sun.star.comp.chart2.chartmodel

I have a look to the libreoffice api but I didn't find how these two kind of object are connected.

Is it possible to make what I want with libreoffice basic ?

Does anyone could explain me the hierachical structure of a libreoffice chart object (parents, childs, ...) and how to deal with it ?

1

There are 1 answers

0
JohnSUN On

Yes, you are absolutely right - parsing the current selection is not a trivial task.

Since the current selection may contain a variety of objects - Cell, CellRange, SheetCellRanges, Shapes, ShapeCollection, GraphicObjectShape and even in some cases just Text, parsing becomes similar to the game "Miner" - each next step requires additional checks (or error handling " blindly "with the help On Error Resume Next)

Your idea of ​​using ImplementationName to identify objects is generally good. But Andrew Pitonyak in 4.1. Debugging And Inspecting Macros wrote "To determine the document type, look at the services it supports ... I assume that this is safer than using getImplementationName()" and I tend to believe him.

The transition from the current selection to the embedded chart can be something like this:

Sub ModifyChartInCurrentSelection
Dim oCurrentSelection As Variant
Dim i As Long
Dim oNextElementOfSelection As Variant
Dim oEmbeddedObject As Variant
Dim oComponent As Variant
Dim aSize As New com.sun.star.awt.Size
    oCurrentSelection = ThisComponent.getCurrentSelection()
    If oCurrentSelection.supportsService("com.sun.star.drawing.ShapeCollection") Then
        For i = 0 To oCurrentSelection.getCount()-1
            oNextElementOfSelection = oCurrentSelection.getByIndex(i)
            If oNextElementOfSelection.supportsService("com.sun.star.drawing.OLE2Shape") Then
Rem Size of shape (outer wrapper around the chart)
                If oNextElementOfSelection.supportsService("com.sun.star.drawing.Shape") Then
                    aSize = oNextElementOfSelection.getSize()
                    aSize.Height = aSize.Height * 2 ' or any other
                    aSize.Width = aSize.Width / 2
                    oNextElementOfSelection.setSize(aSize)
                EndIf 
Rem Properties of EmbeddedObject
                oEmbeddedObject = oNextElementOfSelection.EmbeddedObject
                If Not IsEmpty(oEmbeddedObject) Then
                    oComponent = oEmbeddedObject.getComponent()
                    oComponent.getTitle().String = "Foo-bar Foo-bar Foo-bar"
Rem and other settings...
                EndIf 
            EndIf 
        Next i
    EndIf 
End Sub