odk/CustomTarget_build-examples_java.mk                   |    2 
 odk/Package_examples.mk                                   |   30 +
 odk/examples/DevelopersGuide/Charts/java/Makefile         |    2 
 odk/examples/DevelopersGuide/Charts/python/CalcHelper.py  |  189 +++++++++++
 odk/examples/DevelopersGuide/Charts/python/ChartInCalc.py |  225 ++++++++++++++
 odk/examples/DevelopersGuide/Charts/python/Helper.py      |   44 ++
 odk/examples/DevelopersGuide/Charts/python/bullet.gif     |binary
 7 files changed, 477 insertions(+), 15 deletions(-)

New commits:
commit 7c78d2b29e04228481c0e4bfa9e3eaf6ccbd575b
Author:     zeph <zeph.c...@ymail.com>
AuthorDate: Mon Feb 5 20:03:14 2024 -0800
Commit:     Hossein <hoss...@libreoffice.org>
CommitDate: Tue Feb 27 23:41:18 2024 +0100

    Add python code for ChartInCalc
    
    Change-Id: Ia7f4cbd539919e88f735c13bdd1dae3533b1163a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163037
    Tested-by: Jenkins
    Reviewed-by: Hossein <hoss...@libreoffice.org>

diff --git a/odk/CustomTarget_build-examples_java.mk 
b/odk/CustomTarget_build-examples_java.mk
index 213aa35cff75..15be0a2c6a47 100644
--- a/odk/CustomTarget_build-examples_java.mk
+++ b/odk/CustomTarget_build-examples_java.mk
@@ -9,7 +9,7 @@
 
 my_example_dirs_java = \
     DevelopersGuide/BasicAndDialogs/CreatingDialogs \
-    DevelopersGuide/Charts \
+    DevelopersGuide/Charts/java \
     DevelopersGuide/Components/Addons/JobsAddon \
     DevelopersGuide/Components/Addons/ProtocolHandlerAddon_java \
     DevelopersGuide/Components/JavaComponent \
diff --git a/odk/Package_examples.mk b/odk/Package_examples.mk
index 9d84dc6620de..10b30815bf9c 100644
--- a/odk/Package_examples.mk
+++ b/odk/Package_examples.mk
@@ -35,19 +35,23 @@ $(eval $(call 
gb_Package_add_files_with_dir,odk_examples,$(SDKDIRNAME)/examples,
     
DevelopersGuide/BasicAndDialogs/ToolkitControls/ToolkitControls/ScrollBarDlg.xdl
 \
     DevelopersGuide/BasicAndDialogs/ToolkitControls/ToolkitControls/dialog.xlb 
\
     DevelopersGuide/BasicAndDialogs/ToolkitControls/ToolkitControls/script.xlb 
\
-    DevelopersGuide/Charts/AddInChart.ods \
-    DevelopersGuide/Charts/CalcHelper.java \
-    DevelopersGuide/Charts/ChartHelper.java \
-    DevelopersGuide/Charts/ChartInCalc.java \
-    DevelopersGuide/Charts/ChartInDraw.java \
-    DevelopersGuide/Charts/ChartInWriter.java \
-    DevelopersGuide/Charts/Helper.java \
-    DevelopersGuide/Charts/JavaSampleChartAddIn.components \
-    DevelopersGuide/Charts/JavaSampleChartAddIn.java \
-    DevelopersGuide/Charts/ListenAtCalcRangeInDraw.java \
-    DevelopersGuide/Charts/Makefile \
-    DevelopersGuide/Charts/SelectionChangeListener.java \
-    DevelopersGuide/Charts/bullet.gif \
+    DevelopersGuide/Charts/java/AddInChart.ods \
+    DevelopersGuide/Charts/java/CalcHelper.java \
+    DevelopersGuide/Charts/java/ChartHelper.java \
+    DevelopersGuide/Charts/java/ChartInCalc.java \
+    DevelopersGuide/Charts/java/ChartInDraw.java \
+    DevelopersGuide/Charts/java/ChartInWriter.java \
+    DevelopersGuide/Charts/java/Helper.java \
+    DevelopersGuide/Charts/java/JavaSampleChartAddIn.components \
+    DevelopersGuide/Charts/java/JavaSampleChartAddIn.java \
+    DevelopersGuide/Charts/java/ListenAtCalcRangeInDraw.java \
+    DevelopersGuide/Charts/java/Makefile \
+    DevelopersGuide/Charts/java/SelectionChangeListener.java \
+    DevelopersGuide/Charts/java/bullet.gif \
+    DevelopersGuide/Charts/python/CalcHelper.py \
+    DevelopersGuide/Charts/python/ChartInCalc.py \
+    DevelopersGuide/Charts/python/Helper.py \
+    DevelopersGuide/Charts/python/bullet.gif \
     DevelopersGuide/Components/Addons/JobsAddon/Addons.xcu \
     DevelopersGuide/Components/Addons/JobsAddon/AsyncJob.components \
     DevelopersGuide/Components/Addons/JobsAddon/AsyncJob.java \
diff --git a/odk/examples/DevelopersGuide/Charts/AddInChart.ods 
b/odk/examples/DevelopersGuide/Charts/java/AddInChart.ods
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/AddInChart.ods
rename to odk/examples/DevelopersGuide/Charts/java/AddInChart.ods
diff --git a/odk/examples/DevelopersGuide/Charts/CalcHelper.java 
b/odk/examples/DevelopersGuide/Charts/java/CalcHelper.java
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/CalcHelper.java
rename to odk/examples/DevelopersGuide/Charts/java/CalcHelper.java
diff --git a/odk/examples/DevelopersGuide/Charts/ChartHelper.java 
b/odk/examples/DevelopersGuide/Charts/java/ChartHelper.java
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/ChartHelper.java
rename to odk/examples/DevelopersGuide/Charts/java/ChartHelper.java
diff --git a/odk/examples/DevelopersGuide/Charts/ChartInCalc.java 
b/odk/examples/DevelopersGuide/Charts/java/ChartInCalc.java
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/ChartInCalc.java
rename to odk/examples/DevelopersGuide/Charts/java/ChartInCalc.java
diff --git a/odk/examples/DevelopersGuide/Charts/ChartInDraw.java 
b/odk/examples/DevelopersGuide/Charts/java/ChartInDraw.java
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/ChartInDraw.java
rename to odk/examples/DevelopersGuide/Charts/java/ChartInDraw.java
diff --git a/odk/examples/DevelopersGuide/Charts/ChartInWriter.java 
b/odk/examples/DevelopersGuide/Charts/java/ChartInWriter.java
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/ChartInWriter.java
rename to odk/examples/DevelopersGuide/Charts/java/ChartInWriter.java
diff --git a/odk/examples/DevelopersGuide/Charts/Helper.java 
b/odk/examples/DevelopersGuide/Charts/java/Helper.java
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/Helper.java
rename to odk/examples/DevelopersGuide/Charts/java/Helper.java
diff --git 
a/odk/examples/DevelopersGuide/Charts/JavaSampleChartAddIn.components 
b/odk/examples/DevelopersGuide/Charts/java/JavaSampleChartAddIn.components
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/JavaSampleChartAddIn.components
rename to 
odk/examples/DevelopersGuide/Charts/java/JavaSampleChartAddIn.components
diff --git a/odk/examples/DevelopersGuide/Charts/JavaSampleChartAddIn.java 
b/odk/examples/DevelopersGuide/Charts/java/JavaSampleChartAddIn.java
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/JavaSampleChartAddIn.java
rename to odk/examples/DevelopersGuide/Charts/java/JavaSampleChartAddIn.java
diff --git a/odk/examples/DevelopersGuide/Charts/ListenAtCalcRangeInDraw.java 
b/odk/examples/DevelopersGuide/Charts/java/ListenAtCalcRangeInDraw.java
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/ListenAtCalcRangeInDraw.java
rename to odk/examples/DevelopersGuide/Charts/java/ListenAtCalcRangeInDraw.java
diff --git a/odk/examples/DevelopersGuide/Charts/Makefile 
b/odk/examples/DevelopersGuide/Charts/java/Makefile
similarity index 99%
rename from odk/examples/DevelopersGuide/Charts/Makefile
rename to odk/examples/DevelopersGuide/Charts/java/Makefile
index dbb55d51c90a..3acc1f538d20 100644
--- a/odk/examples/DevelopersGuide/Charts/Makefile
+++ b/odk/examples/DevelopersGuide/Charts/java/Makefile
@@ -34,7 +34,7 @@
 
 # Builds the Charts examples of the Developers Guide.
 
-PRJ=../../..
+PRJ=../../../..
 SETTINGS=$(PRJ)/settings
 
 include $(SETTINGS)/settings.mk
diff --git a/odk/examples/DevelopersGuide/Charts/SelectionChangeListener.java 
b/odk/examples/DevelopersGuide/Charts/java/SelectionChangeListener.java
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/SelectionChangeListener.java
rename to odk/examples/DevelopersGuide/Charts/java/SelectionChangeListener.java
diff --git a/odk/examples/DevelopersGuide/Charts/bullet.gif 
b/odk/examples/DevelopersGuide/Charts/java/bullet.gif
similarity index 100%
rename from odk/examples/DevelopersGuide/Charts/bullet.gif
rename to odk/examples/DevelopersGuide/Charts/java/bullet.gif
diff --git a/odk/examples/DevelopersGuide/Charts/python/CalcHelper.py 
b/odk/examples/DevelopersGuide/Charts/python/CalcHelper.py
new file mode 100644
index 000000000000..dcbb0b8e8740
--- /dev/null
+++ b/odk/examples/DevelopersGuide/Charts/python/CalcHelper.py
@@ -0,0 +1,189 @@
+import math
+import random
+import sys
+import traceback
+
+from com.sun.star.awt import Rectangle
+from com.sun.star.container import NoSuchElementException
+
+
+class CalcHelper:
+
+    _data_sheet_name = "Data"
+    _chart_sheet_name = "Chart"
+
+    def __init__(self, doc):
+        self.spread_sheet_doc = doc
+        self._init_spread_sheet()
+
+    def get_chart_sheet(self):
+        sheets = self.spread_sheet_doc.Sheets
+        try:
+            sheet = sheets.getByName(self._chart_sheet_name)
+        except NoSuchElementException as err:
+            print(f"Couldn't find sheet with name {self._chart_sheet_name}: 
{err}")
+            traceback.print_exc()
+        except Exception as err:
+            print(err)
+            traceback.print_exc()
+        return sheet
+
+    def get_data_sheet(self):
+        sheets = self.spread_sheet_doc.Sheets
+        try:
+            sheet = sheets.getByName(self._data_sheet_name)
+        except NoSuchElementException as err:
+            print(f"Couldn't find sheet with name {self._data_sheet_name}: 
{err}")
+            traceback.print_exc()
+        except Exception as err:
+            print(err)
+            traceback.print_exc()
+        return sheet
+
+    def insert_chart(self, chart_name, range_, upper_left, extent, 
chart_service_name):
+        """Insert a chart using the given name as name of the OLE object and 
the range as corresponding
+           range of data to be used for rendering.  The chart is placed in the 
sheet for charts at
+           position upper_left extending as large as given in extent.
+
+           The service name must be the name of a diagram service that can be 
instantiated via the
+           factory of the chart document
+
+        Args:
+            chart_name (str): _description_
+            range_ (com.sun.star.table.CellRangeAddress): _description_
+            upper_left (Point): _description_
+            extent (Size): _description_
+            chart_service_name (str): _description_
+        """
+        result = None
+        try:
+            sheet = self.get_chart_sheet()
+        except Exception as err:
+            print(f"Sheet not found {err}")
+            traceback.print_exc()
+            return
+
+        chart_collection = sheet.getCharts()
+
+        if not chart_collection.hasByName(chart_name):
+            rect = Rectangle(upper_left.X, upper_left.Y, extent.Width, 
extent.Height)
+            addresses = []
+            addresses.append(range_)
+
+            # first bool: ColumnHeaders
+            # second bool: RowHeaders
+            chart_collection.addNewByName(chart_name, rect, addresses, True, 
False)
+
+            try:
+                table_chart = chart_collection.getByName(chart_name)
+
+                # the table chart is an embedded object which contains the 
chart document
+                result = table_chart.getEmbeddedObject()
+
+                # create a diagram via the factory and set this as new diagram
+                result.setDiagram(result.createInstance(chart_service_name))
+
+            except NoSuchElementException as err:
+                print(f"Couldn't find chart with name {chart_name}: {err}")
+                traceback.print_exc()
+                return
+
+            except Exception as err:
+                print(err)
+                traceback.print_exc()
+                return
+
+        return result
+
+    def insert_random_range(self, column_count, row_count):
+        """Fill a rectangular range with random numbers.
+           The first column has increasing values
+
+        Args:
+            column_count (int): _description_
+            row_count (int): _description_
+
+        Return:
+            (com.sun.star.table.XCellRange)
+        """
+        cell_range = None
+        try:
+            # get the sheet to insert the chart
+            sheet = self.get_data_sheet()
+            cell_range = sheet[0:row_count, 0:column_count]
+
+            base = 0.0
+            float_range = 10.0
+
+            for col in range(column_count):
+                if col == 0:
+                    sheet[0, col].Formula = "X"
+                else:
+                    sheet[0, col].Formula = f"Random {col}"
+
+                for row in range(1, row_count):
+                    if col == 0:
+                        value = row + random.random()
+                    else:
+                        value = base + random.gauss(0.0, 1.0) * float_range
+
+                    # put value into cell
+                    sheet[row, col].Value = value
+
+        except Exception as err:
+            print(f"Sheet not found {err}")
+            traceback.print_exc()
+
+        return cell_range
+
+    def insert_formula_range(self, column_count, row_count):
+        try:
+            # get the sheet to insert the chart
+            sheet = self.get_data_sheet()
+            cell_range = sheet[0 : row_count - 1, 0 : column_count - 1]
+            factor = 2.0 * math.pi / (row_count - 1)
+
+            factor_col = column_count = 2
+            sheet[0, factor_col - 1].Value = 0.2
+            sheet[1, factor_col - 1].String = "Change the factor above and
watch the changes in the chart"
+
+            for col in range(column_count):
+                for row in range(row_count):
+                    if col == 0:
+                        # x values: ascending numbers
+                        value = row * factor
+                        sheet[row, col].Value = value
+                    else:
+                        formula = "="
+                        if col % 2 == 0:
+                            formula += "SIN"
+                        else:
+                            formula += "COS"
+
+                        formula += f"(INDIRECT(ADDRESS({row + 
1};1)))+RAND()*INDIRECT(ADDRESS(1;{factor_col}))"
+                        sheet[row, col].Formula = formula
+
+        except Exception as err:
+            print(f"Sheet not found {err}")
+            traceback.print_exc()
+
+        return cell_range
+
+    def raise_chart_sheet(self):
+        """Bring the sheet containing charts visually to the foreground"""
+        
self.spread_sheet_doc.getCurrentController().setActiveSheet(self.get_chart_sheet())
+
+    def _init_spread_sheet(self):
+        """create two sheets, one for data and one for charts in the 
document"""
+        if self.spread_sheet_doc is not None:
+            sheets = self.spread_sheet_doc.Sheets
+            if sheets:
+                for i in range(len(sheets) - 1, 0, -1):
+                    sheets.removeByName(sheets.getByIndex(i).getName())
+                try:
+                    first_sheet = sheets[0]
+                    first_sheet.setName(self._data_sheet_name)
+                    sheets.insertNewByName(self._chart_sheet_name, 1)
+                except Exception as e:
+                    print(f"Couldn't initialize Spreadsheet Document: {e}", 
file=sys.stderr)
+                    traceback.print_exc()
diff --git a/odk/examples/DevelopersGuide/Charts/python/ChartInCalc.py 
b/odk/examples/DevelopersGuide/Charts/python/ChartInCalc.py
new file mode 100644
index 000000000000..787cc2274020
--- /dev/null
+++ b/odk/examples/DevelopersGuide/Charts/python/ChartInCalc.py
@@ -0,0 +1,225 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+import os
+
+import Helper
+import CalcHelper
+
+from com.sun.star.awt import FontWeight, Point, Size
+from com.sun.star.chart import ChartSymbolType, ChartDataCaption
+from com.sun.star.drawing import LineDash
+from com.sun.star.drawing.DashStyle import ROUND
+from com.sun.star.drawing.FillStyle import SOLID
+from com.sun.star.drawing.LineStyle import DASH
+from com.sun.star.lang import IndexOutOfBoundsException, Locale
+
+
+class ChartInCalc(object):
+    def __init__(self, chart_doc):
+        super(ChartInCalc, self).__init__()
+        self._chart_document = chart_doc
+        self._diagram = self._chart_document.getDiagram()
+
+    def lock_controllers(self):
+        self._chart_document.lockControllers()
+
+    def unlock_controllers(self):
+        self._chart_document.unlockControllers()
+
+    def test_diagram(self):
+        dia_prop = self._diagram
+
+        if dia_prop is not None:
+            # change chart type
+            dia_prop.setPropertyValue("Lines", True)
+            # change attributes for all series
+            # set line width to 0.5mm
+            dia_prop.setPropertyValue("LineWidth", 50)
+
+    def test_data_row_properties(self):
+        # change properties of the data series
+        try:
+            for i in range(4):
+                series_prop = self._diagram.getDataRowProperties(i)
+                series_prop.setPropertyValue("LineColor", int(0x400000 * i + 
0x005000 * i + 0x0000FF - 0x40 * i))
+
+                if i == 1:
+                    source_file = "bullet.gif"
+                    url = os.path.abspath(source_file).replace("\", "/")
+
+                    if os.path.exists(url):
+                        url = "file:///" + url
+                    else:
+                        url = 
"http://graphics.openoffice.org/chart/bullet1.gif";
+
+                    series_prop.setPropertyValue("SymbolType", 
int(ChartSymbolType.BITMAPURL))
+                    series_prop.setPropertyValue("SymbolBitmapURL", url)
+                else:
+                    series_prop.setPropertyValue("SymbolType", 
int(ChartSymbolType.SYMBOL1))
+                    series_prop.setPropertyValue("SymbolSize", Size(250, 250))
+
+        except IndexOutOfBoundsException as err:
+            print(f"Oops, there not enough series for setting properties: 
{err}")
+
+    def test_data_point_properties(self):
+        #  set properties for a single data point
+        try:
+            # determine the maximum value of the first series
+            data_array = self._chart_document.getData()
+            data = data_array.getData()
+            max_value = max([data[i][1] for i in range(len(data))])
+
+            # first parameter is the index of the point, the second one is the 
series
+            point_prop = self._diagram.getDataPointProperties(0, 1)
+
+            # set a different, larger symbol
+            point_prop.setPropertyValue("SymbolType", 
int(ChartSymbolType.SYMBOL6))
+            point_prop.setPropertyValue("SymbolSize", Size(600, 600))
+
+            # add a label text with bold font, bordeaux red 14pt
+            point_prop.setPropertyValue("DataCaption", 
int(ChartDataCaption.VALUE))
+            point_prop.setPropertyValue("CharHeight", 14.0)
+            point_prop.setPropertyValue("CharColor", int(0x993366))
+            point_prop.setPropertyValue("CharWeight", FontWeight.BOLD)
+
+        except IndexOutOfBoundsException as err:
+            print(f"Oops, there not enough series for setting properties: 
{err}")
+
+    def test_area(self):
+        area = self._chart_document.getArea()
+        if area is not None:
+            # change background color of entire chart
+            area.setPropertyValue("FillStyle", SOLID)
+            area.setPropertyValue("FillColor", int(0xEEEEEE))
+
+    def test_wall(self):
+        wall = self._diagram.getWall()
+
+        # change background color of area
+        wall.setPropertyValue("FillStyle", SOLID)
+        wall.setPropertyValue("FillColor", int(0xCCCCCC))
+
+    def test_title(self):
+        # change main title
+        doc_prop = self._chart_document
+        doc_prop.setPropertyValue("HasMainTitle", True)
+
+        title = self._chart_document.getTitle()
+
+        # set new text
+        if title is not None:
+            title.setPropertyValue("String", "Random Scatter Chart")
+            title.setPropertyValue("CharHeight", 14.0)
+
+        # align title with y axis
+        axis = self._diagram.getYAxis()
+
+        if axis is not None and title is not None:
+            pos = title.getPosition()
+            pos.X = axis.getPosition().X
+            title.setPosition(pos)
+
+    def test_axis(self):
+        # x axis
+        axis = self._diagram.getXAxis()
+
+        if axis is not None:
+            axis.setPropertyValue("Max", 24)
+            axis.setPropertyValue("StepMain", 3)
+
+        # change number format for y axis
+        axis = self._diagram.getYAxis()
+
+        # add a new custom number format and get the new key
+        new_number_format = 0
+        num_fmt_supp = self._chart_document
+
+        if num_fmt_supp is not None:
+            formats = num_fmt_supp.getNumberFormats()
+            locale = Locale("de", "DE", "de")
+
+            format_str = formats.generateFormat(new_number_format, locale, 
True, True, 3, 1)
+            new_number_format = formats.addNew(format_str, locale)
+
+        if axis is not None:
+            axis.setPropertyValue("NumberFormat", int(new_number_format))
+
+    def test_grid(self):
+        # y major grid
+        grid = self._diagram.getYMainGrid()
+
+        if grid is not None:
+            dash = LineDash()
+            dash.Style = ROUND
+            dash.Dots = 2
+            dash.DotLen = 10
+            dash.Dashes = 1
+            dash.DashLen = 200
+            dash.Distance = 100
+
+            grid.setPropertyValue("LineColor", int(0x999999))
+            grid.setPropertyValue("LineStyle", DASH)
+            grid.setPropertyValue("LineDash", dash)
+            grid.setPropertyValue("LineWidth", 30)
+
+
+def main():
+    # Create a spreadsheet add some data and add a chart
+    helper = Helper.Helper()
+
+    calc_helper = CalcHelper.CalcHelper(helper.create_spreadsheet_document())
+
+    # insert a cell range with 4 columns and 24 rows filled with random numbers
+    cell_range = calc_helper.insert_random_range(4, 24)
+    range_address = cell_range.RangeAddress
+
+    # change view to sheet containing the chart
+    calc_helper.raise_chart_sheet()
+
+    # the unit for measures is 1/100th of a millimeter
+    # position at (1cm, 1cm)
+    pos = Point(1000, 1000)
+
+    # size of the chart is 15cm x 9.271cm
+    extent = Size(15000, 9271)
+
+    # insert a new chart into the "Chart" sheet of the spreadsheet document
+    chart_doc = calc_helper.insert_chart("ScatterChart", range_address, pos, 
extent, "com.sun.star.chart.XYDiagram")
+
+    test = ChartInCalc(chart_doc)
+
+    try:
+        test.lock_controllers()
+
+        test.test_diagram()
+        test.test_area()
+        test.test_wall()
+        test.test_title()
+        test.test_axis()
+        test.test_grid()
+
+        # show an intermediate state, ...
+        test.unlock_controllers()
+        test.lock_controllers()
+
+        # ..., because the following takes a while:
+        # an internet URL has to be resolved
+        test.test_data_row_properties()
+        test.test_data_point_properties()
+
+        test.unlock_controllers()
+
+    except Exception as err:
+        print(f"UNO Exception caught: {err}")
+
+
+# Main entry point
+if __name__ == "__main__":
+    main()
diff --git a/odk/examples/DevelopersGuide/Charts/python/Helper.py 
b/odk/examples/DevelopersGuide/Charts/python/Helper.py
new file mode 100644
index 000000000000..f3d2c154ba23
--- /dev/null
+++ b/odk/examples/DevelopersGuide/Charts/python/Helper.py
@@ -0,0 +1,44 @@
+import sys
+import traceback
+
+import officehelper
+
+
+class Helper(object):
+    def __init__(self):
+        # connect to a running office and get the ServiceManager
+        try:
+            # get the remote office component context
+            self._context = officehelper.bootstrap()
+            print("Connected to a running office ...")
+            # get the remote office service manager
+            self._factory = self._context.getServiceManager()
+
+        except Exception as err:
+            print(f"Couldn't get ServiceManager: {err}")
+            traceback.print_exc()
+            sys.exit(1)
+
+    def create_spreadsheet_document(self):
+        return self._create_document("scalc")
+
+    def create_drawing_document(self):
+        return self._create_document("sdraw")
+
+    def create_text_document(self):
+        return self._create_document("swriter")
+
+    def _create_document(self, doc_type):
+        result = None
+        try:
+            desktop = 
self._factory.createInstanceWithContext("com.sun.star.frame.Desktop", 
self._context)
+            result = 
desktop.loadComponentFromURL(f"private:factory/{doc_type}", "_blank", 0, 
tuple())
+        except Exception as err:
+            print(f"Couldn't create Document of type {doc_type}: {err}")
+            traceback.print_exc()
+            return
+
+        return result
+
+    def get_componentContext(self):
+        return self._context
diff --git a/odk/examples/DevelopersGuide/Charts/python/bullet.gif 
b/odk/examples/DevelopersGuide/Charts/python/bullet.gif
new file mode 100644
index 000000000000..0f8efd140b98
Binary files /dev/null and 
b/odk/examples/DevelopersGuide/Charts/python/bullet.gif differ

Reply via email to