wizards/Package_sfdocuments.mk                    |    1 
 wizards/source/scriptforge/SF_Exception.xba       |   14 
 wizards/source/scriptforge/SF_PythonHelper.xba    |    1 
 wizards/source/scriptforge/SF_Root.xba            |   24 
 wizards/source/scriptforge/SF_Utils.xba           |    5 
 wizards/source/scriptforge/po/ScriptForge.pot     |   54 +
 wizards/source/scriptforge/po/en.po               |   54 +
 wizards/source/scriptforge/po/fr.po               |  214 +++---
 wizards/source/scriptforge/python/scriptforge.py  |   45 +
 wizards/source/scriptforge/python/scriptforge.pyi |  181 ++++-
 wizards/source/scriptforge/script.xlb             |   32 -
 wizards/source/sfdocuments/SF_Calc.xba            |  334 ++++++++--
 wizards/source/sfdocuments/SF_Chart.xba           |  216 +-----
 wizards/source/sfdocuments/SF_Document.xba        |   54 +
 wizards/source/sfdocuments/SF_Shape.xba           |  686 ++++++++++++++++++++++
 wizards/source/sfdocuments/script.xlb             |    1 
 16 files changed, 1460 insertions(+), 456 deletions(-)

New commits:
commit 2a3eb41c0379373448e436d18a87a6b51eb54862
Author:     Jean-Pierre Ledure <[email protected]>
AuthorDate: Wed Nov 12 17:42:14 2025 +0100
Commit:     Jean-Pierre Ledure <[email protected]>
CommitDate: Thu Nov 13 10:04:58 2025 +0100

    ScriptForge (SFDocuments) new Shape service
    
    The new "Shape" service is focused on
    the description of shapes/images/drawing
    objects stored in documents.
    In the actual release only shapes
    in Calc sheets are considered.
    
    A Shape instance is created from either:
    -  calc.CreateShapeFromFile(shapename, imagefile,
                                range, aslink)
       => the shape is loaded in the sheet and
          anchored to the given range.
          The shape may or not be embedded in the
          document.
    -  calc.Shapes(sheetname, shapename)
    
    Next methods are available:
    -  shape.Anchor(anchortype, cell)
       => define the anchor type and the cell
          to which the shape has to be anchored.
    -  shape.ExportToFile(filename, imagetype, overwrite)
       => save the shape as an image file
          to a specified location.
    -  shape.Pick()
       => select the shape (NB "Select" is a reserved
          word in Basic, hence "Pick")
    -  shape.Resize(xpos, ypos, width, height)
       => change position and/or size.
    -  shape.Rotate(angle, pivot)
       => rotate the shape using a given
          pivot point (x, y) with a given angle.
    
    The shape.XShape property gives a direct
    access to its com.sun.star.drawing.XShape
    UNO representation.
    
    The pre-existing SF_Chart service is
    functionally unchanged. However it is
    now implemented as a subclass of the
    new SF_Shape service.
    Compatibility with previous releases
    is preserved.
    
    The implementation required a few changes
    in the error messages. Hence also in
    their translations.
    
    All the functions are available for both
    Basic and Python user scripts.
    
    The documentation should include:
    - a revision of the Calc and Chart help pages
    - the creation of an additional Shape page
    
    Change-Id: Ib67f5e755e3112961aadeffc3188b2cdf9aca613
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193906
    Tested-by: Jenkins
    Reviewed-by: Jean-Pierre Ledure <[email protected]>

diff --git a/wizards/Package_sfdocuments.mk b/wizards/Package_sfdocuments.mk
index 4dcebfc84140..01b5fb46633b 100644
--- a/wizards/Package_sfdocuments.mk
+++ b/wizards/Package_sfdocuments.mk
@@ -29,6 +29,7 @@ $(eval $(call 
gb_Package_add_files,wizards_basicsrvsfdocuments,$(LIBO_SHARE_FOLD
        SF_FormControl.xba \
        SF_FormDocument.xba \
        SF_Register.xba \
+       SF_Shape.xba \
        SF_Writer.xba \
        __License.xba \
        dialog.xlb \
diff --git a/wizards/source/scriptforge/SF_Exception.xba 
b/wizards/source/scriptforge/SF_Exception.xba
index afc35fcb3acd..313c70dd4825 100644
--- a/wizards/source/scriptforge/SF_Exception.xba
+++ b/wizards/source/scriptforge/SF_Exception.xba
@@ -117,8 +117,9 @@ Const OFFSETADDRESSERROR            =       
&quot;OFFSETADDRESSERROR&quot;
 Const DUPLICATECHARTERROR              =       &quot;DUPLICATECHARTERROR&quot;
 Const RANGEEXPORTERROR                 =       &quot;RANGEEXPORTERROR&quot;
 
-&apos; SF_Chart
-Const CHARTEXPORTERROR                 =       &quot;CHARTEXPORTERROR&quot;
+&apos; SF_SHAPE
+Const DUPLICATESHAPEERROR              =       &quot;DUPLICATESHAPEERROR&quot;
+Const SHAPEEXPORTERROR                 =       &quot;SHAPEEXPORTERROR&quot;
 
 &apos; SF_Form
 Const FORMDEADERROR                            =       
&quot;FORMDEADERROR&quot;
@@ -1074,14 +1075,19 @@ Try:
                                sMessage = sLocation _
                                        &amp; &quot;
&quot; &amp; &quot;
&quot; &amp; &quot;
&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
                                        &amp; &quot;
&quot; &amp; &quot;
&quot; &amp; .GetText(&quot;DUPLICATECHART&quot;, pvArgs(0), pvArgs(1), 
pvArgs(2), pvArgs(3), pvArgs(4), pvArgs(5))
+                       Case DUPLICATESHAPEERROR        &apos;  
SF_Calc.CreateShapeFromFile(shape, ShapeName, sheet, SheetName, Document, file)
+                               pvArgs(0) = _RightCase(pvArgs(0))       :       
pvArgs(2) = _RightCase(pvArgs(2))
+                               sMessage = sLocation _
+                                       &amp; &quot;
&quot; &amp; &quot;
&quot; &amp; &quot;
&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
+                                       &amp; &quot;
&quot; &amp; &quot;
&quot; &amp; .GetText(&quot;DUPLICATESHAPE&quot;, pvArgs(0), pvArgs(1), 
pvArgs(2), pvArgs(3), pvArgs(4), pvArgs(5))
                        Case RANGEEXPORTERROR   &apos;  
SF_Calc.ExportRangeToFile(Arg1Name, FileName, Arg2, Overwrite)
                                pvArgs(0) = _RightCase(pvArgs(0))       :       
pvArgs(2) = _RightCase(pvArgs(2))
                                sMessage = sLocation _
                                        &amp; &quot;
&quot; &amp; &quot;
&quot; &amp; .GetText(&quot;RANGEEXPORT&quot;, pvArgs(0), pvArgs(1), pvArgs(2), 
pvArgs(3))
-                       Case CHARTEXPORTERROR   &apos;  
SF_Chart.ExportToFile(Arg1Name, FileName, Arg2, Overwrite)
+                       Case SHAPEEXPORTERROR   &apos;  
SF_Shape.ExportToFile(Arg1Name, FileName, Arg2, Overwrite)
                                pvArgs(0) = _RightCase(pvArgs(0))       :       
pvArgs(2) = _RightCase(pvArgs(2))
                                sMessage = sLocation _
-                                       &amp; &quot;
&quot; &amp; &quot;
&quot; &amp; .GetText(&quot;CHARTEXPORT&quot;, pvArgs(0), pvArgs(1), pvArgs(2), 
pvArgs(3))
+                                       &amp; &quot;
&quot; &amp; &quot;
&quot; &amp; .GetText(&quot;SHAPEEXPORT&quot;, pvArgs(0), pvArgs(1), pvArgs(2), 
pvArgs(3))
                        Case FORMDEADERROR              &apos;  
SF_Form._IsStillAlive(FormName, DocumentName)
                                sMessage = sLocation _
                                        &amp; &quot;
&quot; &amp; &quot;
&quot; &amp; .GetText(&quot;FORMDEAD&quot;, pvArgs(0), pvArgs(1))
diff --git a/wizards/source/scriptforge/SF_PythonHelper.xba 
b/wizards/source/scriptforge/SF_PythonHelper.xba
index 06048c3b598a..562f223ed828 100644
--- a/wizards/source/scriptforge/SF_PythonHelper.xba
+++ b/wizards/source/scriptforge/SF_PythonHelper.xba
@@ -859,6 +859,7 @@ Try:
                                                                Case 
&quot;SetArray&quot;                       :       vReturn = 
vBasicObject.SetArray(vArgs(0), vArgs(1))
                                                                Case 
&quot;SetFormula&quot;             :       vReturn = 
vBasicObject.SetFormula(vArgs(0), vArgs(1))
                                                                Case 
&quot;SetValue&quot;                       :       vReturn = 
vBasicObject.SetValue(vArgs(0), vArgs(1))
+                                                               Case 
&quot;Shapes&quot;                 :       vReturn = 
vBasicObject.Shapes(vArgs(0), vArgs(1))
                                                                Case 
&quot;Styles&quot;                 :       vReturn = 
vBasicObject.Styles(vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
                                                                Case 
&quot;Toolbars&quot;                       :       vReturn = 
vBasicObject.Toolbars(vArgs(0))
                                                        End Select
diff --git a/wizards/source/scriptforge/SF_Root.xba 
b/wizards/source/scriptforge/SF_Root.xba
index f0db856873c8..5e2f0591592d 100644
--- a/wizards/source/scriptforge/SF_Root.xba
+++ b/wizards/source/scriptforge/SF_Root.xba
@@ -79,6 +79,7 @@ Private ConfigurationProvider _
 Private PackageProvider                As Object       &apos; 
com.sun.star.comp.deployment.PackageInformationProvider
 Private MailService                    As Object       &apos; 
com.sun.star.system.SimpleCommandMail or com.sun.star.system.SimpleSystemMail
 Private GraphicExportFilter    As Object       &apos; 
com.sun.star.drawing.GraphicExportFilter
+Private GraphicProvider                As Object       &apos; 
com.sun.star.graphic.GraphicProvider
 Private Toolkit                                As Object       &apos; 
com.sun.star.awt.Toolkit
 Private ModuleUIConfigurationManagerSupplier _
                                                        As Object       &apos; 
com.sun.star.ui.ModuleUIConfigurationManagerSupplier
@@ -152,6 +153,7 @@ Private Sub Class_Initialize()
        Set PackageProvider = Nothing
        Set MailService = Nothing
        Set GraphicExportFilter = Nothing
+       Set GraphicProvider = Nothing
        Set Toolkit = Nothing
        Set ModuleUIConfigurationManagerSupplier = Nothing
        Set TransientDocument = Nothing
@@ -879,6 +881,20 @@ Try:
                                                                        &amp;   
&quot;%5: An identifier
&quot; _
                                                                        &amp;   
&quot;%6: A file name&quot; _
                                        )
+       &apos;  SF_Calc.CreateShapeFromFile
+                       .AddText(       Context := &quot;DUPLICATESHAPE&quot; _
+                                               , MsgId := &quot;A shape with 
the same name exists already in the sheet.

&quot; _
+                                                                       &amp; 
&quot;« %1 » = %2
&quot; _
+                                                                       &amp; 
&quot;« %3 » = %4
&quot; _
+                                                                       &amp; 
&quot;« %5 » = %6
&quot; _
+                                               , Comment :=    &quot;SF_Calc 
CreateShapeFromFile
&quot; _
+                                                                       &amp;   
&quot;%1: An identifier
&quot; _
+                                                                       &amp;   
&quot;%2: A string
&quot; _
+                                                                       &amp;   
&quot;%3: An identifier
&quot; _
+                                                                       &amp;   
&quot;%4: A string
&quot; _
+                                                                       &amp;   
&quot;%5: An identifier
&quot; _
+                                                                       &amp;   
&quot;%6: A file name&quot; _
+                                       )
        &apos;  SF_Calc.ExportRangeToFile
                        .AddText(       Context := &quot;RANGEEXPORT&quot; _
                                                , MsgId := &quot;The given 
range could not be exported.
&quot; _
@@ -891,13 +907,13 @@ Try:
                                                                        &amp;   
&quot;%3: An identifier
&quot; _
                                                                        &amp;   
&quot;%4: True or False
&quot; _
                                        )
-       &apos;  SF_Chart.ExportToFile
-                       .AddText(       Context := &quot;CHARTEXPORT&quot; _
-                                               , MsgId := &quot;The chart 
could not be exported.
&quot; _
+       &apos;  SF_Shape.ExportToFile
+                       .AddText(       Context := &quot;SHAPEEXPORT&quot; _
+                                               , MsgId := &quot;The shape 
could not be exported.
&quot; _
                                                                        &amp; 
&quot;Either the destination file must not be overwritten, or it has a 
read-only attribute set.

&quot; _
                                                                        &amp; 
&quot;%1 = &apos;%2&apos;
&quot; _
                                                                        &amp; 
&quot;%3 = %4&quot; _
-                                               , Comment :=    
&quot;SF_Chart.ExportToFile error message
&quot; _
+                                               , Comment :=    
&quot;SF_Shape.ExportToFile error message
&quot; _
                                                                        &amp;   
&quot;%1: An identifier
&quot; _
                                                                        &amp;   
&quot;%2: A file name
&quot; _
                                                                        &amp;   
&quot;%3: An identifier
&quot; _
diff --git a/wizards/source/scriptforge/SF_Utils.xba 
b/wizards/source/scriptforge/SF_Utils.xba
index 3a11ea3f20d6..edc07568329c 100644
--- a/wizards/source/scriptforge/SF_Utils.xba
+++ b/wizards/source/scriptforge/SF_Utils.xba
@@ -403,6 +403,11 @@ Dim oDefaultContext As Object
                                        Set .GraphicExportFilter = 
CreateUnoService(&quot;com.sun.star.drawing.GraphicExportFilter&quot;)
                                End If
                                Set _GetUNOService = .GraphicExportFilter
+                       Case &quot;GraphicProvider&quot;
+                               If IsEmpty(.GraphicProvider) Or 
IsNull(.GraphicProvider) Then
+                                       Set .GraphicProvider = 
CreateUnoService(&quot;com.sun.star.graphic.GraphicProvider&quot;)
+                               End If
+                               Set _GetUNOService = .GraphicProvider
                        Case &quot;Introspection&quot;
                                If IsEmpty(.Introspection) Or 
IsNull(.Introspection) Then
                                        Set .Introspection = 
CreateUnoService(&quot;com.sun.star.beans.Introspection&quot;)
diff --git a/wizards/source/scriptforge/po/ScriptForge.pot 
b/wizards/source/scriptforge/po/ScriptForge.pot
index 0072162a7c62..b60dc9f4a9f8 100644
--- a/wizards/source/scriptforge/po/ScriptForge.pot
+++ b/wizards/source/scriptforge/po/ScriptForge.pot
@@ -14,7 +14,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION
"
 "Report-Msgid-Bugs-To: 
https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI
"
-"POT-Creation-Date: 2025-08-04 11:05:34
"
+"POT-Creation-Date: 2025-11-12 16:40:58
"
 "PO-Revision-Date: YYYY-MM-DD HH:MM:SS
"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>
"
 "Language-Team: LANGUAGE <EMAIL@ADDRESS>
"
@@ -165,23 +165,6 @@ msgid  ""
 "function does not exist or its arguments are invalid."
 msgstr ""
 
-#. SF_Chart.ExportToFile error message
-#. %1: An identifier
-#. %2: A file name
-#. %3: An identifier
-#. %4: True or False
-#. 
-#, kde-format
-msgctxt "CHARTEXPORT"
-msgid  ""
-"The chart could not be exported.
"
-"Either the destination file must not be overwritten, or it has a "
-"read-only attribute set.
"
-"
"
-"%1 = '%2'
"
-"%3 = %4"
-msgstr ""
-
 #. SF_DialogControl property setting
 #. %1: An identifier
 #. %2: An identifier
@@ -416,6 +399,24 @@ msgid  ""
 "« %1 » = %2"
 msgstr ""
 
+#. SF_Calc CreateShapeFromFile
+#. %1: An identifier
+#. %2: A string
+#. %3: An identifier
+#. %4: A string
+#. %5: An identifier
+#. %6: A file name
+#, kde-format
+msgctxt "DUPLICATESHAPE"
+msgid  ""
+"A shape with the same name exists already in the sheet.
"
+"
"
+"« %1 » = %2
"
+"« %3 » = %4
"
+"« %5 » = %6
"
+""
+msgstr ""
+
 #. SF_Calc InsertSheet
 #. %1: An identifier
 #. %2: A string
@@ -781,6 +782,23 @@ msgid  ""
 "« %1 » = %2"
 msgstr ""
 
+#. SF_Shape.ExportToFile error message
+#. %1: An identifier
+#. %2: A file name
+#. %3: An identifier
+#. %4: True or False
+#. 
+#, kde-format
+msgctxt "SHAPEEXPORT"
+msgid  ""
+"The shape could not be exported.
"
+"Either the destination file must not be overwritten, or it has a "
+"read-only attribute set.
"
+"
"
+"%1 = '%2'
"
+"%3 = %4"
+msgstr ""
+
 #. SF_Database can't interpret SQL statement
 #. %1: The statement
 #, kde-format
diff --git a/wizards/source/scriptforge/po/en.po 
b/wizards/source/scriptforge/po/en.po
index 0072162a7c62..b60dc9f4a9f8 100644
--- a/wizards/source/scriptforge/po/en.po
+++ b/wizards/source/scriptforge/po/en.po
@@ -14,7 +14,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION
"
 "Report-Msgid-Bugs-To: 
https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI
"
-"POT-Creation-Date: 2025-08-04 11:05:34
"
+"POT-Creation-Date: 2025-11-12 16:40:58
"
 "PO-Revision-Date: YYYY-MM-DD HH:MM:SS
"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>
"
 "Language-Team: LANGUAGE <EMAIL@ADDRESS>
"
@@ -165,23 +165,6 @@ msgid  ""
 "function does not exist or its arguments are invalid."
 msgstr ""
 
-#. SF_Chart.ExportToFile error message
-#. %1: An identifier
-#. %2: A file name
-#. %3: An identifier
-#. %4: True or False
-#. 
-#, kde-format
-msgctxt "CHARTEXPORT"
-msgid  ""
-"The chart could not be exported.
"
-"Either the destination file must not be overwritten, or it has a "
-"read-only attribute set.
"
-"
"
-"%1 = '%2'
"
-"%3 = %4"
-msgstr ""
-
 #. SF_DialogControl property setting
 #. %1: An identifier
 #. %2: An identifier
@@ -416,6 +399,24 @@ msgid  ""
 "« %1 » = %2"
 msgstr ""
 
+#. SF_Calc CreateShapeFromFile
+#. %1: An identifier
+#. %2: A string
+#. %3: An identifier
+#. %4: A string
+#. %5: An identifier
+#. %6: A file name
+#, kde-format
+msgctxt "DUPLICATESHAPE"
+msgid  ""
+"A shape with the same name exists already in the sheet.
"
+"
"
+"« %1 » = %2
"
+"« %3 » = %4
"
+"« %5 » = %6
"
+""
+msgstr ""
+
 #. SF_Calc InsertSheet
 #. %1: An identifier
 #. %2: A string
@@ -781,6 +782,23 @@ msgid  ""
 "« %1 » = %2"
 msgstr ""
 
+#. SF_Shape.ExportToFile error message
+#. %1: An identifier
+#. %2: A file name
+#. %3: An identifier
+#. %4: True or False
+#. 
+#, kde-format
+msgctxt "SHAPEEXPORT"
+msgid  ""
+"The shape could not be exported.
"
+"Either the destination file must not be overwritten, or it has a "
+"read-only attribute set.
"
+"
"
+"%1 = '%2'
"
+"%3 = %4"
+msgstr ""
+
 #. SF_Database can't interpret SQL statement
 #. %1: The statement
 #, kde-format
diff --git a/wizards/source/scriptforge/po/fr.po 
b/wizards/source/scriptforge/po/fr.po
index 275b50928f4b..8c4ed190dd06 100644
--- a/wizards/source/scriptforge/po/fr.po
+++ b/wizards/source/scriptforge/po/fr.po
@@ -16,7 +16,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.libreoffice.org/enter_bug.cgi?";
 "product=LibreOffice&bug_status=UNCONFIRMED&component=UI
"
 "POT-Creation-Date: 2025-01-11 13:09:17
"
-"PO-Revision-Date: 2025-01-12 16:42+0100
"
+"PO-Revision-Date: 2025-11-12 16:55+0100
"
 "Last-Translator: Jean-Pierre Ledure
"
 "Language-Team: LANGUAGE <EMAIL@ADDRESS>
"
 "Language: fr
"
@@ -24,7 +24,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8
"
 "Content-Transfer-Encoding: 8bit
"
 "Plural-Forms: nplurals=2; plural=(n > 1);
"
-"X-Generator: Poedit 3.0.1
"
+"X-Generator: Poedit 3.4.2
"
 "X-Accelerator-Marker: ~
"
 
 #. SF_Array.ExtractColumn (...) error message
@@ -57,8 +57,8 @@ msgid ""
 "    « From »     = %2
"
 "    « UpTo »     = %3"
 msgstr ""
-"Les indices fournis pour la zone à trancher ne rentrent pas dans les limites "
-"de la matrice.
"
+"Les indices fournis pour la zone à trancher ne rentrent pas dans les limites 
de "
+"la matrice.
"
 "
"
 "    « Array_1D » = %1
"
 "    « From »     = %2
"
@@ -111,8 +111,8 @@ msgid ""
 "The opening of the Base document failed.
"
 "Something must be wrong with some arguments.
"
 "
"
-"Either the file does not exist, or the file is not registered under the "
-"given name.
"
+"Either the file does not exist, or the file is not registered under the given 
"
+"name.
"
 "
"
 "%1 = '%2'
"
 "%3 = '%4'"
@@ -120,8 +120,8 @@ msgstr ""
 "L'ouverture du document Base a échoué.
"
 "Un des arguments doit être erroné.
"
 "
"
-"Soit le fichier n'existe pas, soit le fichier n'est pas enregistré sous le "
-"nom fourni.
"
+"Soit le fichier n'existe pas, soit le fichier n'est pas enregistré sous le 
nom "
+"fourni.
"
 "
"
 "%1 = '%2'
"
 "%3 = '%4'"
@@ -190,16 +190,16 @@ msgstr ""
 #, kde-format
 msgctxt "CALCFORMNOTFOUND"
 msgid ""
-"The requested form could not be found in the Calc sheet. The given index is "
-"off-limits.
"
+"The requested form could not be found in the Calc sheet. The given index is 
off-"
+"limits.
"
 "
"
 "The concerned Calc document is '%3'.
"
 "
"
 "The name of the sheet = '%2'
"
 "The index = %1."
 msgstr ""
-"Le formulaire recherché est introuvable dans la feuille Calc. L'indice "
-"fourni est hors-limites.
"
+"Le formulaire recherché est introuvable dans la feuille Calc. L'indice fourni 
"
+"est hors-limites.
"
 "
"
 "Le document Calc concerné est '%3'.
"
 "
"
@@ -211,29 +211,29 @@ msgstr ""
 #, kde-format
 msgctxt "CALCFUNC"
 msgid ""
-"The Calc '%1' function encountered an error. Either the given function does "
-"not exist or its arguments are invalid."
+"The Calc '%1' function encountered an error. Either the given function does 
not "
+"exist or its arguments are invalid."
 msgstr ""
 "La fonction Calc '%1' a rencontré une erreur. Soit la fonction n'existe pas, "
 "soit les arguments fournis sont invalides."
 
-#. SF_Chart.ExportToFile error message
+#. SF_Shape.ExportToFile error message
 #. %1: An identifier
 #. %2: A file name
 #. %3: An identifier
 #. %4: True or False
 #.
 #, kde-format
-msgctxt "CHARTEXPORT"
+msgctxt "SHAPEEXPORT"
 msgid ""
-"The chart could not be exported.
"
+"The shape could not be exported.
"
 "Either the destination file must not be overwritten, or it has a read-only "
 "attribute set.
"
 "
"
 "%1 = '%2'
"
 "%3 = %4"
 msgstr ""
-"Le graphique n'a pas pu être exporté.
"
+"La forme n'a pas pu être exportée.
"
 "Soit le fichier de destination ne peut pas être écrasé, soit il comporte "
 "l'attribut lecture seule.
"
 "
"
@@ -249,12 +249,11 @@ msgstr ""
 msgctxt "CONTROLTYPE"
 msgid ""
 "The control '%1' in dialog '%2' is of type '%3'.
"
-"The property or method '%4' is not applicable on that type of dialog "
-"controls."
+"The property or method '%4' is not applicable on that type of dialog 
controls."
 msgstr ""
 "Le contrôle '%1' dans le dialogue '%2' est du type '%3'.
"
-"La propriété ou la méthode '%4' n'est pas applicable pour ce type de "
-"contrôles de dialogue."
+"La propriété ou la méthode '%4' n'est pas applicable pour ce type de 
contrôles "
+"de dialogue."
 
 #. SF_Array.ImportFromCSVFile error message
 #. %1: a file name
@@ -336,8 +335,7 @@ msgstr ""
 #, kde-format
 msgctxt "DIALOGNOTFOUND"
 msgid ""
-"The requested dialog could not be located in the given container or "
-"library.
"
+"The requested dialog could not be located in the given container or library.
"
 "« %1 » = %2
"
 "« %3 » = %4
"
 "« %5 » = %6
"
@@ -418,8 +416,8 @@ msgid ""
 "The opening of the document failed.
"
 "Something must be wrong with some arguments.
"
 "
"
-"Either the file does not exist, or the password is wrong, or the given "
-"filter is invalid.
"
+"Either the file does not exist, or the password is wrong, or the given filter 
"
+"is invalid.
"
 "
"
 "%1 = '%2'
"
 "%3 = '%4'
"
@@ -428,8 +426,8 @@ msgstr ""
 "L'ouverture du document a échoué.
"
 "Un des arguments doit être erroné.
"
 "
"
-"Soit le fichier n'existe pas, soit le mot de passe n'est pas valable, soit "
-"le filtre fourni est invalide.
"
+"Soit le fichier n'existe pas, soit le mot de passe n'est pas valable, soit le 
"
+"filtre fourni est invalide.
"
 "
"
 "%1 = '%2'
"
 "%3 = '%4'
"
@@ -441,8 +439,8 @@ msgstr ""
 #, kde-format
 msgctxt "DOCUMENTREADONLY"
 msgid ""
-"You tried to edit a document which is not modifiable. The document has not "
-"been changed.
"
+"You tried to edit a document which is not modifiable. The document has not 
been "
+"changed.
"
 "
"
 "« %1 » = %2"
 msgstr ""
@@ -465,9 +463,9 @@ msgid ""
 "%1 = '%2'"
 msgstr ""
 "Le document n'a pas pu être enregistré.
"
-"Soit le document a été ouvert en lecture seule, soit le fichier de "
-"destination comporte l'attribut lecture seule, soit le fichier de "
-"destination est indéfini.
"
+"Soit le document a été ouvert en lecture seule, soit le fichier de 
destination "
+"comporte l'attribut lecture seule, soit le fichier de destination est "
+"indéfini.
"
 "
"
 "%1 = '%2'"
 
@@ -482,8 +480,8 @@ msgstr ""
 msgctxt "DOCUMENTSAVEAS"
 msgid ""
 "The document could not be saved.
"
-"Either the document must not be overwritten, or the destination file has a "
-"read-only attribute set, or the given filter is invalid.
"
+"Either the document must not be overwritten, or the destination file has a 
read-"
+"only attribute set, or the given filter is invalid.
"
 "
"
 "%1 = '%2'
"
 "%3 = %4
"
@@ -547,12 +545,34 @@ msgid ""
 "
"
 "« %1 » = %2"
 msgstr ""
-"L'insertion d'une nouvelle clé dans le dictionnaire a échoué parce que la "
-"clé existe déjà.
"
+"L'insertion d'une nouvelle clé dans le dictionnaire a échoué parce que la clé 
"
+"existe déjà.
"
 "Notez que la comparaison entre clés n'est PAS sensible à la casse.
"
 "
"
 "« %1 » = %2"
 
+#. SF_Calc CreateShapeFromFile
+#. %1: An identifier
+#. %2: A string
+#. %3: An identifier
+#. %4: A string
+#. %5: An identifier
+#. %6: A file name
+#, kde-format
+msgctxt "DUPLICATESHAPE"
+msgid ""
+"A shape with the same name exists already in the sheet.
"
+"
"
+"« %1 » = %2
"
+"« %3 » = %4
"
+"« %5 » = %6
"
+msgstr ""
+"Une forme portant le même nom est déjà présente dans la feuille.
"
+"
"
+"« %1 » = %2
"
+"« %3 » = %4
"
+"« %5 » = %6
"
+
 #. SF_Calc InsertSheet
 #. %1: An identifier
 #. %2: A string
@@ -576,13 +596,13 @@ msgstr ""
 #, kde-format
 msgctxt "ENDOFFILE"
 msgid ""
-"The requested file read operation could not be completed because an "
-"unexpected end-of-file was encountered.
"
+"The requested file read operation could not be completed because an 
unexpected "
+"end-of-file was encountered.
"
 "
"
 "File name = '%1'"
 msgstr ""
-"L'opération de lecture du fichier a échoué suite à la survenance "
-"inattendue de la fin du fichier.
"
+"L'opération de lecture du fichier a échoué suite à la survenance inattendue 
de "
+"la fin du fichier.
"
 "
"
 "Nom du fichier = '%1'"
 
@@ -628,8 +648,8 @@ msgstr ""
 #, kde-format
 msgctxt "FILENOTOPEN"
 msgid ""
-"The requested file operation could not be executed because the file was "
-"closed previously.
"
+"The requested file operation could not be executed because the file was 
closed "
+"previously.
"
 "
"
 "File name = '%1'"
 msgstr ""
@@ -644,8 +664,8 @@ msgstr ""
 #, kde-format
 msgctxt "FILEOPENMODE"
 msgid ""
-"The requested file operation could not be executed because it is "
-"incompatible with the mode in which the file was opened.
"
+"The requested file operation could not be executed because it is incompatible 
"
+"with the mode in which the file was opened.
"
 "
"
 "File name = '%1'
"
 "Open mode = %2"
@@ -683,8 +703,8 @@ msgid ""
 "
"
 "« %1 » = %2"
 msgstr ""
-"« %1 » contient le nom d'un fichier ou d'un répertoire existant. "
-"L'opération est rejetée.
"
+"« %1 » contient le nom d'un fichier ou d'un répertoire existant. L'opération "
+"est rejetée.
"
 "
"
 "« %1 » = %2"
 
@@ -700,21 +720,21 @@ msgid ""
 "The property or method '%4' is not applicable on that type of form controls."
 msgstr ""
 "Le contrôle '%1' dans le formulaire '%2' est du type '%3'.
"
-"La propriété ou la méthode '%4' n'est pas applicable pour ce type de "
-"contrôles de formulaire."
+"La propriété ou la méthode '%4' n'est pas applicable pour ce type de 
contrôles "
+"de formulaire."
 
 #. SF_Dialog._IsStillAlive error message
 #. %1: An identifier%2: A file name
 #, kde-format
 msgctxt "FORMDEAD"
 msgid ""
-"The requested action could not be executed because the form is not open or "
-"the document was closed inadvertently.
"
+"The requested action could not be executed because the form is not open or 
the "
+"document was closed inadvertently.
"
 "
"
 "The concerned form is '%1' in document '%2'."
 msgstr ""
-"L'action demandée n'a pas pu se faire, soit parce que le formulaire n'est "
-"pas ouvert, soit suite à la fermeture du document.
"
+"L'action demandée n'a pas pu se faire, soit parce que le formulaire n'est pas 
"
+"ouvert, soit suite à la fermeture du document.
"
 "
"
 "Le formulaire concerné est '%1' contenu dans le document '%2'."
 
@@ -741,8 +761,8 @@ msgid ""
 "The insertion or the update of an entry into a dictionary failed because the "
 "given key contains only spaces."
 msgstr ""
-"L'insertion ou la mise à jour d'une entrée du dictionnaire a échoué parce "
-"que la clé fournie ne contient que des espaces."
+"L'insertion ou la mise à jour d'une entrée du dictionnaire a échoué parce que 
"
+"la clé fournie ne contient que des espaces."
 
 #. Logfile record
 #, kde-format
@@ -760,12 +780,12 @@ msgstr "Souhaitez-vous recevoir davantage d'informations 
sur la méthode '%1' ?"
 #. SF_Dataset can't read field values or store field updates
 msgctxt "NOCURRENTRECORD"
 msgid ""
-"A database record could not be retrieved, inserted or updated by the "
-"database system.
"
+"A database record could not be retrieved, inserted or updated by the database 
"
+"system.
"
 "The current record could not be determined."
 msgstr ""
-"Un enregistrement de la base de données n'a pas pu être retrouvé, inséré "
-"ou mis à jour par son système de gestion.
"
+"Un enregistrement de la base de données n'a pas pu être retrouvé, inséré ou 
mis "
+"à jour par son système de gestion.
"
 "L'enregistrement courant n'a pu être déterminé."
 
 #. SF_FileSystem copy/move/delete error message
@@ -779,9 +799,8 @@ msgid ""
 "
"
 "« %1 » = %2"
 msgstr ""
-"Lorsque « %1 » contient des caractères de remplacement, au moins un fichier "
-"ou répertoire doit correspondre au filtre. Autrement l'opération est "
-"rejetée.
"
+"Lorsque « %1 » contient des caractères de remplacement, au moins un fichier 
ou "
+"répertoire doit correspondre au filtre. Autrement l'opération est rejetée.
"
 "
"
 "« %1 » = %2"
 
@@ -857,8 +876,8 @@ msgid ""
 "« %9 » = %10
"
 "« %11 » = %12"
 msgstr ""
-"La plage de cellules calculée tombe en-dehors des limites de la feuille ou "
-"est dénuée de sens.
"
+"La plage de cellules calculée tombe en-dehors des limites de la feuille ou 
est "
+"dénuée de sens.
"
 "
"
 "« %1 » = %2
"
 "« %3 » = %4
"
@@ -878,8 +897,8 @@ msgid ""
 "
"
 "« %1 » = %2"
 msgstr ""
-"Vous avez tenté de créer un nouveau fichier qui existe déjà. Son écrasement "
-"a été refusé.
"
+"Vous avez tenté de créer un nouveau fichier qui existe déjà. Son écrasement a 
"
+"été refusé.
"
 "
"
 "« %1 » = %2"
 
@@ -899,8 +918,8 @@ msgid ""
 " %3 : « %4 »
"
 " %5 : « %6 »"
 msgstr ""
-"Le Gestionnaire de Pages n'a pas pu être mis en place à cause de "
-"l'incohérence des arguments.
"
+"Le Gestionnaire de Pages n'a pas pu être mis en place à cause de 
l'incohérence "
+"des arguments.
"
 "
"
 " %1 : « %2 »
"
 " %3 : « %4 »
"
@@ -908,8 +927,7 @@ msgstr ""
 
 #. SF_Exception.PythonShell error messageAPSO: to leave unchanged
 msgctxt "PYTHONSHELL"
-msgid ""
-"The APSO extension could not be located in your LibreOffice installation."
+msgid "The APSO extension could not be located in your LibreOffice 
installation."
 msgstr ""
 "L'extension APSO n'a pas pu être localisée dans votre installation de "
 "LibreOffice."
@@ -948,8 +966,8 @@ msgid ""
 "
"
 "« %1 » = %2"
 msgstr ""
-"Copier ou déplacer un fichier vers une destination accessible en lecture "
-"seule, ainsi que supprimer un tel fichier ou répertoire sont interdits.
"
+"Copier ou déplacer un fichier vers une destination accessible en lecture 
seule, "
+"ainsi que supprimer un tel fichier ou répertoire sont interdits.
"
 "
"
 "« %1 » = %2"
 
@@ -971,8 +989,8 @@ msgid ""
 "Field value :  « %2 »
"
 "Field type :  « %3 »"
 msgstr ""
-"Un enregistrement n'a pas pu être inséré ou modifié par le système de "
-"gestion de la base de données.
"
+"Un enregistrement n'a pas pu être inséré ou modifié par le système de gestion 
"
+"de la base de données.
"
 "Causes possibles :
"
 "- le champ ciblé n'est pas modifiable
"
 "- une valeur [NULL] a été fournie, ce qui est interdit pour le champ
"
@@ -1026,8 +1044,8 @@ msgstr ""
 "La bibliothèque '%3' et ses services n'ont pas pu être chargés.
"
 "La raison en est inconnue.
"
 "Cependant, la vérification de la fonction '%3.SF_Services."
-"RegisterScriptServices()' et de ses valeurs de retour peut être un bon point "
-"de départ pour investiguer.
"
+"RegisterScriptServices()' et de ses valeurs de retour peut être un bon point 
de "
+"départ pour investiguer.
"
 "
"
 "« %1 » = %2"
 
@@ -1036,14 +1054,13 @@ msgstr ""
 #, kde-format
 msgctxt "SQLSYNTAX"
 msgid ""
-"An SQL statement could not be interpreted or executed by the database "
-"system.
"
+"An SQL statement could not be interpreted or executed by the database system.
"
 "Check its syntax, table and/or field names, ...
"
 "
"
 "SQL Statement : « %1 »"
 msgstr ""
-"Une instruction SQL n'a pas pu être interprétée ou exécutée par le système "
-"de gestion de la base de données.
"
+"Une instruction SQL n'a pas pu être interprétée ou exécutée par le système de 
"
+"gestion de la base de données.
"
 "Vérifiez sa syntaxe, les noms de tables et de champs, ...
"
 "
"
 "L'instruction SQL : « %1 »"
@@ -1055,8 +1072,7 @@ msgstr ""
 #, kde-format
 msgctxt "SQLSYNTAX2"
 msgid ""
-"An SQL statement could not be interpreted or executed by the database "
-"system.
"
+"An SQL statement could not be interpreted or executed by the database system.
"
 "Check its syntax, table and/or field names, ...
"
 "
"
 "SQL Statement : « %1 »
"
@@ -1064,8 +1080,8 @@ msgid ""
 "    « %2 »
"
 "    « %3 »"
 msgstr ""
-"Une instruction SQL n'a pas pu être interprétée ou exécutée par le système "
-"de gestion de la base de données.
"
+"Une instruction SQL n'a pas pu être interprétée ou exécutée par le système de 
"
+"gestion de la base de données.
"
 "Vérifiez sa syntaxe, les noms de tables et de champs, ...
"
 "
"
 "L'instruction SQL : « %1 »
"
@@ -1103,8 +1119,7 @@ msgid ""
 "The control '%1' in dialog '%2' is not a multiline text field.
"
 "The requested method could not be executed."
 msgstr ""
-"Le contrôle '%1' dans le dialogue '%2' n'est pas un champ texte multi-"
-"lignes.
"
+"Le contrôle '%1' dans le dialogue '%2' n'est pas un champ texte multi-lignes.
"
 "La méthode demandée n'a pas été executée."
 
 #. SFUnitTest could not locate the library gven as argument
@@ -1243,8 +1258,7 @@ msgstr "        « %1 » doit comporter exactement %2 
dimension(s)."
 msgctxt "VALIDATEERROR"
 msgid "A serious error has been detected in your code on argument : « %1 »."
 msgstr ""
-"Une erreur grave a été détectée dans votre code concernant l'argument : « %1 "
-"»."
+"Une erreur grave a été détectée dans votre code concernant l'argument : « %1 
»."
 
 #. SF_Utils._ValidateFile error message
 #. %1: Wrong argument name
@@ -1266,11 +1280,11 @@ msgstr "        « %1 » doit être un nom de fichier ou 
de répertoire valide."
 #, kde-format
 msgctxt "VALIDATEFILESYS"
 msgid ""
-"        « %1 » must be a valid file or folder name expressed in the "
-"operating system native notation."
+"        « %1 » must be a valid file or folder name expressed in the operating 
"
+"system native notation."
 msgstr ""
-"        « %1 » doit être un nom de fichier ou de répertoire valide exprimé "
-"dans la notation propre au système d'exploitation."
+"        « %1 » doit être un nom de fichier ou de répertoire valide exprimé 
dans "
+"la notation propre au système d'exploitation."
 
 #. SF_Utils._ValidateFile error message
 #. %1: Wrong argument name
@@ -1281,8 +1295,8 @@ msgid ""
 "        « %1 » must be a valid file or folder name expressed in the portable "
 "URL notation."
 msgstr ""
-"        « %1 » doit être un nom de fichier ou de répertoire valide exprimé "
-"dans la notation portable dite URL."
+"        « %1 » doit être un nom de fichier ou de répertoire valide exprimé 
dans "
+"la notation portable dite URL."
 
 #. SF_Utils._Validate error message
 #. %1: Wrong argument name
@@ -1337,11 +1351,11 @@ msgstr "        « %1 » admet seulement une des valeurs 
suivantes : %2"
 #, kde-format
 msgctxt "VALIDATEWILDCARD"
 msgid ""
-"        « %1 » may contain one or more wildcard characters (?, *) in its "
-"last path component only."
+"        « %1 » may contain one or more wildcard characters (?, *) in its last 
"
+"path component only."
 msgstr ""
-"        « %1 » peut contenir un ou plusieurs caractères de remplacement (?, "
-"*) exclusivement dans la dernière composante de son chemin complet."
+"        « %1 » peut contenir un ou plusieurs caractères de remplacement (?, 
*) "
+"exclusivement dans la dernière composante de son chemin complet."
 
 #. SF_Utils.Validate error message
 msgctxt "VALIDATIONRULES"
@@ -1354,8 +1368,8 @@ msgstr "    Règles de validation :"
 #, kde-format
 msgctxt "WRITERFORMNOTFOUND"
 msgid ""
-"The requested form could not be found in the Writer document. The given "
-"index is off-limits.
"
+"The requested form could not be found in the Writer document. The given index 
"
+"is off-limits.
"
 "
"
 "The concerned Writer document is '%2'.
"
 "
"
diff --git a/wizards/source/scriptforge/python/scriptforge.py 
b/wizards/source/scriptforge/python/scriptforge.py
index 93d53787b5a5..f92b20f29047 100644
--- a/wizards/source/scriptforge/python/scriptforge.py
+++ b/wizards/source/scriptforge/python/scriptforge.py
@@ -2647,6 +2647,9 @@ class SFDocuments:
             return self.ExecMethod(self.vbMethod, 'CreatePivotTable', 
pivottablename, sourcerange, targetcell,
                                    datafields, rowfields, columnfields, 
filterbutton, rowtotals, columntotals)
 
+        def CreateShapeFromFile(self, shapename, imagefile, range = '~.~', 
aslink = False):
+            return self.ExecMethod(self.vbMethod, 'CreateShapeFromFile', 
shapename, imagefile, range, aslink)
+
         def DAvg(self, range):
             return self.ExecMethod(self.vbMethod, 'DAvg', range)
 
@@ -2746,6 +2749,9 @@ class SFDocuments:
         def SetValue(self, targetrange, value):
             return self.ExecMethod(self.vbMethod + self.flgArrayArg, 
'SetValue', targetrange, value)
 
+        def Shapes(self, sheetname, shapename = ''):
+            return self.ExecMethod(self.vbMethod + self.flgArrayRet, 'Shapes', 
sheetname, shapename)
+
         def ShiftDown(self, range, wholerow = False, rows = 0):
             return self.ExecMethod(self.vbMethod, 'ShiftDown', range, 
wholerow, rows)
 
@@ -2777,10 +2783,39 @@ class SFDocuments:
         servicesynonyms = ()
         serviceproperties = dict()
 
+    # #########################################################################
+    # SF_Shape CLASS
+    # #########################################################################
+    class SF_Shape(SFServices):
+        """
+            The SF_Shape module is focused on the description of 
shapes/images/drawing objects stored in documents.
+            In the actual release only shapes in Calc sheets are considered.
+            """
+        # Mandatory class properties for service registration
+        serviceimplementation = 'basic'
+        servicename = 'SFDocuments.Shape'
+        servicesynonyms = ()
+        serviceproperties = dict(XRectangle = 1, XShape = 0)
+
+        def Anchor(self, anchortype, cell = '~.A1'):
+            return self.ExecMethod(self.vbMethod, 'Anchor', anchortype, cell)
+
+        def ExportToFile(self, filename, imagetype = 'png', overwrite = False):
+            return self.ExecMethod(self.vbMethod, 'ExportToFile', filename, 
imagetype, overwrite)
+
+        def Pick(self):
+            return self.ExecMethod(self.vbMethod, 'Pick')
+
+        def Resize(self, xpos = -1, ypos = -1, width = -1, height = -1):
+            return self.ExecMethod(self.vbMethod, 'Resize', xpos, ypos, width, 
height)
+
+        def Rotate(self, angle, pivot = ''):
+            return self.ExecMethod(self.vbMethod, 'Rotate', angle, pivot)
+
     # #########################################################################
     # SF_Chart CLASS
     # #########################################################################
-    class SF_Chart(SFServices):
+    class SF_Chart(SF_Shape, SFServices):
         """
             The SF_Chart module is focused on the description of chart 
documents
             stored in Calc sheets.
@@ -2793,15 +2828,9 @@ class SFDocuments:
         servicesynonyms = ()
         serviceproperties = dict(ChartType = 2, Deep = 2, Dim3D = 2, Exploded 
= 2, Filled = 2,
                                  Legend = 2, Percent = 2, Stacked = 2, Title = 
2,
-                                 XChartObj = 0, XDiagram = 0, XShape = 0, 
XTableChart = 0,
+                                 XChartObj = 0, XDiagram = 0, XRectangle = 1, 
XShape = 0, XTableChart = 0,
                                  XTitle = 2, YTitle = 2)
 
-        def ExportToFile(self, filename, imagetype = 'png', overwrite = False):
-            return self.ExecMethod(self.vbMethod, 'ExportToFile', filename, 
imagetype, overwrite)
-
-        def Resize(self, xpos = -1, ypos = -1, width = -1, height = -1):
-            return self.ExecMethod(self.vbMethod, 'Resize', xpos, ypos, width, 
height)
-
     # #########################################################################
     # SF_Form CLASS
     # #########################################################################
diff --git a/wizards/source/scriptforge/python/scriptforge.pyi 
b/wizards/source/scriptforge/python/scriptforge.pyi
index c7616a6d1667..948528644c31 100644
--- a/wizards/source/scriptforge/python/scriptforge.pyi
+++ b/wizards/source/scriptforge/python/scriptforge.pyi
@@ -80,6 +80,7 @@ DOCUMENT = SFDocuments.SF_Document
 BASE = SFDocuments.SF_Base
 CALC = SFDocuments.SF_Calc
 CALCREFERENCE = SFDocuments.SF_CalcReference
+SHAPE = SFDocuments.SF_Shape
 CHART = SFDocuments.SF_Chart
 FORM = SFDocuments.SF_Form
 FORMCONTROL = SFDocuments.SF_FormControl
@@ -5758,6 +5759,30 @@ class SFDocuments:
                 """
             ...
 
+        def CreateShapeFromFile(self,
+                                shapename: str,
+                                imagefile: FILE,
+                                range: RANGE = ...,
+                                aslink: bool = ...) -> SHAPE | None:
+            """
+                Insert a new shape in a Calc sheet from a disk file containing 
its image.
+                The shape will be positioned on, anchored to the given range,
+                and sized according to the image original size.
+                    Args
+                        ``shapename``: the user-defined name of the new shape.
+
+                        ``imagefile``: the input file in the ``FileSystem`` 
notation.
+
+                        ``range``: the top-left position of the new shape.
+                        It may be a cell range, but only the top-left cell 
will be considered.
+                        The default is the top-left cell of the current 
selection.
+
+                        ``aslink``: When ``True`` (default = ``False``), the 
file is not embedded in the document.
+                    Returns
+                        A new SF_Shape class instance or None.
+                """
+            ...
+
         def DAvg(self, range: RANGE) -> float:
             """
                 Get the number of the numeric values stored in the given 
range, excluding values from filtered
@@ -6409,6 +6434,23 @@ class SFDocuments:
                         A string representing the modified area as a range of 
cells.
                 """
             ...
+
+        def Shapes(self, sheetname: SHEETNAME, shapename: str = ...) -> SHAPE 
| tuple[str, ...]:
+            """
+                Depending on the parameters provided this method will return:
+
+                    - A tuple with the names of all the shapes contained in a 
given sheet (if the ``shapename`` argument is absent).
+                    - A ``SFDocuments.Shape`` service instance representing 
the shape specified as argument.
+
+                    Args
+                        ``sheetname``: the name of the sheet, as a string, 
from which the shape(s) will be retrieved.
+
+                        ``shapename``: the name corresponding to a shape 
stored in the specified sheet.
+                        If this argument is absent, the method will return a 
list with the names of all shapes available
+                        in the sheet.
+                """
+            ...
+
         def ShiftDown(self, range: RANGE, wholerow: bool = ..., rows: int = 
...) -> RANGE:
             """
                 Moves a given range of cells downwards by inserting empty rows.
@@ -6544,6 +6586,104 @@ class SFDocuments:
             The SF_CalcReference class has as unique role to hold sheet and 
range references.
             """
 
+    # #########################################################################
+    # SF_Shape CLASS
+    # #########################################################################
+    class SF_Shape(SFServices):
+        """
+            The SF_Shape module is focused on the description of 
shapes/images/drawing objects stored in documents.
+            In the actual release only shapes in Calc sheets are considered.
+            """
+
+        XRectangle: UNO
+        """ A com.sun.star.awt.XRectangle object delimiting the shape. 
Distances are expressed in 1/100th mm. """
+        XShape: UNO
+        """ Returns the ``com.sun.star.drawing.XShape`` object representing 
the shape. """
+
+        def Anchor(self,
+                   anchortype: Literal['CELL', 'CELLRESIZE', 'PAGE'],
+                   cell: RANGE = ...
+                   ) -> bool:
+            """
+                Define the anchor type and the cell to which the shape has to 
be anchored.
+                    Args
+                        ``ancortype``: 'CELL' = the shape is anchored "to 
cell",
+                        'CELLRESIZE' = the shape is anchored "to cell (resize 
with cell)",
+                        'PAGE' = the shape is anchored to the sheet.
+
+                        ``cell``: a unique cell or a cell range in the sheet 
where the shape is located.
+                        Only the top-left cell of a range will be considered.
+                        The argument is ignored and may be omitted when 
``anchortype`` = 'PAGE'.
+                    Returns
+                        ``True`` when successful.
+                """
+            ...
+
+        def ExportToFile(self,
+                         filename: FILE,
+                         imagetype: Literal['gif', 'jpeg', 'png', 'svg', 
'tiff'] = ...,
+                         overwrite: bool = ...
+                         ) -> bool:
+            """
+                Saves the shape as an image file in a specified location.
+                    Args
+                        ``filename``: identifies the path and file name where 
the image will be saved.
+                        It must follow the notation defined in 
``SF_FileSystem.FileNaming``.
+
+                        ``imagetype``: the name of the image type to be 
created.
+                        The following values are accepted: ``gif, jpeg, png`` 
(default), ``svg`` and ``tiff``.
+
+                        ``overwrite``: specifies if the destination file may 
be overwritten. Defaults to ``False``.
+                    Returns
+                        ``True`` if the image file could be successfully 
created.
+                """
+            ...
+
+        def Pick(self) -> bool:
+            """
+                Make the actual shape the current selection.
+                This allows to execute thereafter a menu command on the shape.
+                    Returns
+                        `True`` when successful.
+                """
+            ...
+
+        def Resize(self, xpos: int = ..., ypos: int = ..., width: int = ..., 
height: int = ...) -> bool:
+            """
+                Changes the position of the shape in the current sheet and 
modifies its width and height.
+                    Args
+                        ``xpos``: specify the new ``X`` position of the chart.
+
+                        ``ypos``: specify the new ``Y`` position of the chart.
+
+                        ``width``: specify the new width of the chart.
+
+                        ``height``: specify the new height of the chart.
+                    Returns
+                        ``True`` if repositioning/resizing was successful.
+                    Note
+                        - All arguments are provided as integer values that 
correspond to ``1/100`` of a millimeter.
+                        - Omitted arguments leave the corresponding actual 
values unchanged.
+                        - Negative arguments are ignored.
+                """
+            ...
+
+        def Rotate(self, angle: int | float, pivot: str | tuple[int, int] = 
...) -> bool:
+            """
+                Rotate the shape using a given pivot point with a given angle.
+                    Args
+                        ``angle``: specify the magnitude of the rotation, 
expressed in degrees.
+                        An angle may be positive or negative. Positive means 
counterclockwise.
+                        It is to be understood as absolute vs. the usual 
X-axis orientation.
+
+                        ``pivot``: specify the point about which the rotation 
will take place. It can be
+                             - either an array (x, y) being the coordinates of 
the pivot point in 1/100 mm. The origin (0, 0) is the top-left corner of the 
sheet where the shape is located.
+                             - or, when the intent is to use the shape's 
natural pivot points, a string combining 2 of next uppercase characters (other 
characters are ignored): L(eft), R(ight), C(enter) and T(op), B(ottom), 
M(iddle). Default = 'CM'.
+                    Returns
+                        ``True`` when successful.
+                """
+            ...
+
     # #########################################################################
     # SF_Chart CLASS
     # #########################################################################
@@ -6553,6 +6693,7 @@ class SFDocuments:
             stored in Calc sheets.
             With this service, many chart types and chart characteristics 
available
             in the user interface can be read or modified.
+            Charts are a special type of shapes. The "Chart" service is a 
subclass of the "Shape" service.
             """
 
         ChartType: Literal['Pie', 'Bar', 'Donut', 'Column', 'Area', 'Line', 
'XY', 'Bubble', 'Net']
@@ -6595,46 +6736,6 @@ class SFDocuments:
         """ Returns the ``com.sun.star.table.XTableChart`` object representing 
the data being displayed in the chart.
         """
 
-        def ExportToFile(self,
-                         filename: FILE,
-                         imagetype: Literal['gif', 'jpeg', 'png', 'svg', 
'tiff'] = ...,
-                         overwrite: bool = ...
-                         ) -> bool:
-            """
-                Saves the chart as an image file in a specified location.
-                    Args
-                        ``filename``: identifies the path and file name where 
the image will be saved.
-                        It must follow the notation defined in 
``SF_FileSystem.FileNaming``.
-
-                        ``imagetype``: the name of the image type to be 
created.
-                        The following values are accepted: ``gif, jpeg, png`` 
(default), ``svg`` and ``tiff``.
-
-                        ``overwrite``: specifies if the destination file can 
be overwritten. Defaults to ``False``.
-                    Returns
-                        ``True`` if the image file could be successfully 
created.
-                """
-            ...
-
-        def Resize(self, xpos: int = ..., ypos: int = ..., width: int = ..., 
height: int = ...) -> bool:
-            """
-                Changes the position of the chart in the current sheet and 
modifies its width and height.
-                    Args
-                        ``xpos``: specify the new ``X`` position of the chart.
-
-                        ``ypos``: specify the new ``Y`` position of the chart.
-
-                        ``width``: specify the new width of the chart.
-
-                        ``height``: specify the new height of the chart.
-                    Returns
-                        ``True`` if repositioning/resizing was successful.
-                    Note
-                        - All arguments are provided as integer values that 
correspond to ``1/100`` of a millimeter.
-                        - Omitted arguments leave the corresponding actual 
values unchanged.
-                        - Negative arguments are ignored.
-                """
-            ...
-
     # #########################################################################
     # SF_Form CLASS
     # #########################################################################
diff --git a/wizards/source/scriptforge/script.xlb 
b/wizards/source/scriptforge/script.xlb
index a77ee4a07d5b..68efd282406a 100644
--- a/wizards/source/scriptforge/script.xlb
+++ b/wizards/source/scriptforge/script.xlb
@@ -1,24 +1,24 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 
1.0//EN" "library.dtd">
 <library:library xmlns:library="http://openoffice.org/2000/library"; 
library:name="ScriptForge" library:readonly="false" 
library:passwordprotected="false">
- <library:element library:name="_CodingConventions"/>
- <library:element library:name="SF_Session"/>
- <library:element library:name="SF_Dictionary"/>
- <library:element library:name="SF_Exception"/>
- <library:element library:name="SF_UI"/>
- <library:element library:name="SF_Services"/>
- <library:element library:name="SF_PythonHelper"/>
- <library:element library:name="SF_Platform"/>
- <library:element library:name="SF_Array"/>
- <library:element library:name="SF_TextStream"/>
- <library:element library:name="SF_Utils"/>
- <library:element library:name="SF_String"/>
- <library:element library:name="_ModuleModel"/>
+ <library:element library:name="__License"/>
+ <library:element library:name="SF_Root"/>
  <library:element library:name="SF_SharedMemory"/>
  <library:element library:name="SF_L10N"/>
  <library:element library:name="SF_Region"/>
- <library:element library:name="SF_Root"/>
- <library:element library:name="__License"/>
- <library:element library:name="SF_FileSystem"/>
  <library:element library:name="SF_Timer"/>
+ <library:element library:name="SF_FileSystem"/>
+ <library:element library:name="SF_Services"/>
+ <library:element library:name="SF_UI"/>
+ <library:element library:name="SF_Exception"/>
+ <library:element library:name="SF_Dictionary"/>
+ <library:element library:name="SF_Session"/>
+ <library:element library:name="_CodingConventions"/>
+ <library:element library:name="_ModuleModel"/>
+ <library:element library:name="SF_String"/>
+ <library:element library:name="SF_Utils"/>
+ <library:element library:name="SF_TextStream"/>
+ <library:element library:name="SF_Array"/>
+ <library:element library:name="SF_Platform"/>
+ <library:element library:name="SF_PythonHelper"/>
 </library:library>
\ No newline at end of file
diff --git a/wizards/source/sfdocuments/SF_Calc.xba 
b/wizards/source/sfdocuments/SF_Calc.xba
index f3d16d6c96b7..fbec5e4873a1 100644
--- a/wizards/source/sfdocuments/SF_Calc.xba
+++ b/wizards/source/sfdocuments/SF_Calc.xba
@@ -102,6 +102,7 @@ Private Const DUPLICATESHEETERROR   =       
&quot;DUPLICATESHEETERROR&quot;
 Private Const OFFSETADDRESSERROR       =       &quot;OFFSETADDRESSERROR&quot;
 Private Const CALCFORMNOTFOUNDERROR    =       
&quot;CALCFORMNOTFOUNDERROR&quot;
 Private Const DUPLICATECHARTERROR      =       &quot;DUPLICATECHARTERROR&quot;
+Private Const DUPLICATESHAPEERROR      =       &quot;DUPLICATESHAPEERROR&quot;
 Private Const RANGEEXPORTERROR         =       &quot;RANGEEXPORTERROR&quot;
 
 REM ============================================================= PRIVATE 
MEMBERS
@@ -480,7 +481,7 @@ Public Function AlignRange(Optional ByVal TargetRange As 
Variant _
 &apos;&apos;&apos;             Alignment: a string combining 1 or 2 of next 
characters (other characters are ignored):
 &apos;&apos;&apos;                     L       align Left
 &apos;&apos;&apos;                     R       align Right
-&apos;&apos;&apos;                     C       Center gorizontally
+&apos;&apos;&apos;                     C       Center horizontally
 &apos;&apos;&apos;                     B       align Bottom
 &apos;&apos;&apos;                     M       center vertically (Middle)
 &apos;&apos;&apos;                     T       align Top
@@ -641,84 +642,9 @@ Public Function Charts(Optional ByVal SheetName As Variant 
_
 &apos;&apos;&apos;             Dim oChart As Object
 &apos;&apos;&apos;             Set oChart = oDoc.Charts(&quot;SheetX&quot;, 
&quot;myChart&quot;)
 
-Dim vCharts As Variant                         &apos;  Return value when array 
of chart names
-Dim oChart As Object                           &apos;  Return value when new 
chart instance
-Dim oSheet As Object                           &apos;  Alias of SheetName as 
reference
-Dim oDrawPage As Object                                &apos;  
com.sun.star.drawing.XDrawPage
-Dim oNextShape As Object                       &apos;  
com.sun.star.drawing.XShape
-Dim sChartName As String                       &apos;  Some chart name
-Dim lCount As Long                                     &apos;  Counter for 
charts among all drawing objects
-Dim i As Long
-Const cstChartShape = &quot;com.sun.star.drawing.OLE2Shape&quot;
-
-Const cstThisSub = &quot;SFDocuments.Calc.Charts&quot;
-Const cstSubArgs = &quot;SheetName, [ChartName=&quot;&quot;&quot;&quot;]&quot;
-
-       If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
-       vCharts = Array()
-
-Check:
-       If IsMissing(ChartName) Or IsEmpty(ChartName) Then ChartName = 
&quot;&quot;
-       If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
-               If Not _IsStillAlive(True) Then GoTo Finally
-               If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True) 
Then GoTo Finally
-               If Not ScriptForge.SF_Utils._Validate(ChartName, 
&quot;ChartName&quot;, V_STRING) Then GoTo Finally
-       End If
-
 Try:
-       &apos;  Because the user can change it constantly, the list of valid 
charts has to be rebuilt at each time
-       &apos;  Explore charts starting from the draw page
-       Set oSheet = _Component.getSheets.getByName(SheetName)
-       Set oDrawPage = oSheet.getDrawPage()
-       vCharts = Array()
-       Set oChart = Nothing
-       lCount = -1
-       For i = 0 To oDrawPage.Count - 1
-               Set oNextShape = oDrawPage.getByIndex(i)
-               if oNextShape.supportsService(cstChartShape) Then               
&apos;  Ignore other shapes
-                       sChartName = oNextShape.Name                            
                                                &apos;  User-defined name
-                       If Len(sChartName) = 0 Then sChartName = 
oNextShape.PersistName         &apos;  Internal name
-                       &apos;  Is chart found ?
-                       If Len(ChartName) &gt; 0 Then
-                               If ChartName = sChartName Then
-                                       Set oChart = New SF_Chart
-                                       With oChart
-                                               Set .[Me] = oChart
-                                               Set .[_Parent] = [Me]
-                                               ._SheetName = SheetName
-                                               ._DrawIndex = i
-                                               ._ChartName = ChartName
-                                               ._PersistentName = 
oNextShape.PersistName
-                                               Set ._Shape = oNextShape
-                                               Set ._Chart = 
oSheet.getCharts().getByName(._PersistentName)
-                                               Set ._ChartObject = 
._Chart.EmbeddedObject
-                                               Set ._Diagram = 
._ChartObject.Diagram
-                                       End With
-                                       Exit For
-                               End If
-                       End If
-                       &apos;  Build stack of chart names
-                       lCount = lCount + 1
-                       If UBound(vCharts) &lt; 0 Then
-                               vCharts = Array(sChartName)
-                       Else
-                               ReDim Preserve vCharts(0 To UBound(vCharts) + 1)
-                               vCharts(lCount) = sChartName
-                       End If
-               End If
-       Next i
-
-       &apos;  Raise error when chart not found
-       If Len(ChartName) &gt; 0 And IsNull(oChart) Then
-               If Not ScriptForge.SF_Utils._Validate(ChartName, 
&quot;ChartName&quot;, V_STRING, vCharts, True) Then GoTo Finally
-       End If
+       Charts = _Shapes(SheetName, ChartName, _IsChart := True)
 
-Finally:
-       If Len(ChartName) = 0 Then Charts = vCharts Else Set Charts = oChart
-       ScriptForge.SF_Utils._ExitFunction(cstThisSub)
-       Exit Function
-Catch:
-       GoTo Finally
 End Function    &apos;   SFDocuments.SF_Calc.Charts
 
 REM 
-----------------------------------------------------------------------------
@@ -1457,7 +1383,7 @@ Try:
        &apos;  Create the chart and get ihe corresponding chart instance
        oSheet.getCharts.addNewByName(ChartName, oRectangle, 
Array(oRange.XCellRange.RangeAddress), ColumnHeader, RowHeader)
        Set oChart = Charts(SheetName, ChartName)
-       oChart._Shape.Name = ChartName          &apos;  Both user-defined and 
internal names match ChartName
+       oChart.[_Super]._Shape.Name = ChartName         &apos;  Both 
user-defined and internal names match ChartName
        oChart._Diagram.Wall.FillColor = RGB(255, 255, 255)             &apos;  
Align on background color set by the user interface by default
 
 Finally:
@@ -1669,6 +1595,112 @@ Catch:
        GoTo Finally
 End Function    &apos;   SFDocuments.SF_Calc.CreatePivotTable
 
+REM 
-----------------------------------------------------------------------------
+Public Function CreateShapeFromFile(Optional ByVal ShapeName As Variant _
+                                                                       , 
Optional ByVal ImageFile As Variant _
+                                                                       , 
Optional ByVal Range As Variant _
+                                                                       , 
Optional AsLink As Variant _
+                                                       ) As Variant
+&apos;&apos;&apos; Return a new Shape/image class instance
+&apos;&apos;&apos;             - positioned on and anchored to the given range
+&apos;&apos;&apos;             - sized according to the image original size
+&apos;&apos;&apos;     Args:
+&apos;&apos;&apos;             ShapeName: The user-defined name of the new 
Shape
+&apos;&apos;&apos;             ImageFile: The input file in the SF_FileSystem 
notation
+&apos;&apos;&apos;             Range: The top-left position of the new shape.
+&apos;&apos;&apos;                     May be a cell range, but only the 
top-left cell will be considered
+&apos;&apos;&apos;                     Default = top-left cell of the current 
selection
+&apos;&apos;&apos;             AsLink: When True (default = False), the file 
is not embedded in the document
+&apos;&apos;&apos;     Returns:
+&apos;&apos;&apos;             A new Shape service instance or Nothing when 
failed
+&apos;&apos;&apos;     Exceptions:
+&apos;&apos;&apos;             DUPLICATESHAPEERROR             A Shape with 
the same name exists already in the given sheet
+&apos;&apos;&apos;             UNKNOWNFILEERROR                The image file 
could not be located in the file system
+&apos;&apos;&apos;     Examples:
+&apos;&apos;&apos;             Dim oShape As Object
+&apos;&apos;&apos;             Set oShape = 
oDoc.CreateShapeFromFile(&quot;myShape&quot;, &quot;C:\Image.png&quot;, 
&quot;~.D5&quot;, AsLink := True)
+
+Dim oShape As Object                           &apos;  Return value
+Dim oXShape As Object                          &apos;  
com.sun.star.comp.sc.ScShapeObj
+Dim vShapes As Variant                         &apos;  List of pre-existing 
shapes
+Dim oDrawPage As Object                                &apos;  
com.sun.star.drawing.XDrawPage
+Dim oProvider As Object                                &apos;  
com.sun.star.graphic.GraphicProvider
+Dim oRange As _Address                         &apos;  A parsed range
+Dim oPosition As New com.sun.star.awt.Point            &apos;  Shape target 
position
+Dim oSize As New com.sun.star.awt.Size                 &apos;  Shape target 
size
+Dim FSO As Object                                      :       Set FSO = 
ScriptForge.SF_FileSystem
+Dim sImageFile As String                       &apos;  Alias of ImageFile
+
+Const cstThisSub = &quot;SFDocuments.Calc.CreateShapeFromFile&quot;
+Const cstSubArgs = &quot;ShapeName, ImageFile, 
[Range=&quot;&quot;~.~&quot;&quot;], [AsLink=False]&quot;
+
+       If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
+       Set oShape = Nothing
+
+Check:
+       If IsMissing(Range) Or IsEmpty(Range) Then Range = &quot;~.~&quot;
+       If IsMissing(AsLink) Or IsEmpty(AsLink) Then AsLink = False
+       If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
+               If Not _IsStillAlive(True) Then GoTo Finally
+               If Not ScriptForge.SF_Utils._Validate(ShapeName, 
&quot;ShapeName&quot;, V_STRING) Then GoTo Finally
+               If Not ScriptForge.SF_Utils._ValidateFile(ImageFile, 
&quot;ImageFile&quot;) Then GoTo Finally
+               If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, 
V_STRING) Then GoTo Finally
+               If Not ScriptForge.SF_Utils._Validate(AsLink, 
&quot;AsLink&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
+       End If
+
+       &apos;  Does the input file exist ?
+       If Not FSO.FileExists(ImageFile) Then GoTo CatchNotExists
+       sImageFile = FSO._ConvertToUrl(ImageFile)
+
+       &apos;  Is the range a valid address ?
+       Set oRange = _ParseAddress(Range)
+
+       &apos;  No names conflict ?
+       vShapes = Shapes(oRange.SheetName)
+       If ScriptForge.SF_Array.Contains(vShapes, ShapeName, CaseSensitive := 
True) Then GoTo CatchDuplicate
+
+Try:
+       &apos;  Initialize the new shape
+       Set oDrawPage = oRange.XSpreadsheet.getDrawPage()
+       Set oPosition = oRange.XCellRange.Position
+
+       Set oProvider = 
ScriptForge.SF_Utils._GetUnoService(&quot;GraphicProvider&quot;)
+       Set oXShape = 
_Component.createInstance(&quot;com.sun.star.drawing.GraphicObjectShape&quot;)
+       With oXShape
+               .Name = ShapeName
+               .Graphic = oProvider.queryGraphic(Array( _
+                                               
ScriptForge.SF_Utils._MakePropertyValue(&quot;URL&quot;, sImageFile) _
+                                               , 
ScriptForge.SF_Utils._MakePropertyValue(&quot;LoadAsLink&quot;, AsLink) _
+                                               ))
+               .setPosition(oPosition)
+       End With
+       oDrawPage.add(oXShape)
+
+       &apos;  Size according to original image size
+       oSize.Width = CLng(oXShape.Graphic.Size100thMM.Width)
+       oSize.Height = CLng(oXShape.Graphic.Size100thMM.Height)
+       oXShape.setSize(oSize)
+
+       &apos;  Anchor the image to the top-left cell of the range
+       oXShape.Anchor = oRange.XCellRange.getCellByPosition(0, 0)
+
+       &apos;  Create the Shape and get the corresponding Shape instance
+       Set oShape = Shapes(oRange.SheetName, ShapeName)
+
+Finally:
+       Set CreateShapeFromFile = oShape
+       ScriptForge.SF_Utils._ExitFunction(cstThisSub)
+       Exit Function
+Catch:
+       GoTo Finally
+CatchDuplicate:
+       ScriptForge.SF_Exception.RaiseFatal(DUPLICATESHAPEERROR, 
&quot;ShapeName&quot;, ShapeName, &quot;SheetName&quot;, oRange.SheetName, 
&quot;Document&quot;, [_Super]._FileIdent())
+       GoTo Finally
+CatchNotExists:
+       ScriptForge.SF_Exception.RaiseFatal(UNKNOWNFILEERROR, 
&quot;ImageFile&quot;, ImageFile)
+       GoTo Finally
+End Function    &apos;   SFDocuments.SF_Calc.CreateShapeFromFile
+
 REM 
-----------------------------------------------------------------------------
 Public Function DAvg(Optional ByVal Range As Variant) As Double
 &apos;&apos;&apos;     Get the average of the numeric values stored in the 
given range
@@ -2698,6 +2730,7 @@ Public Function Methods() As Variant
                                        , &quot;CopyToCell&quot; _
                                        , &quot;CopyToRange&quot; _
                                        , &quot;CreateChart&quot; _
+                                       , &quot;CreateShapeFromFile&quot; _
                                        , &quot;DAvg&quot; _
                                        , &quot;DCount&quot; _
                                        , &quot;DecorateFont&quot; _
@@ -2727,6 +2760,7 @@ Public Function Methods() As Variant
                                        , &quot;SetCellStyle&quot; _
                                        , &quot;SetFormula&quot; _
                                        , &quot;SetValue&quot; _
+                                       , &quot;Shapes&quot; _
                                        , &quot;ShiftDown&quot; _
                                        , &quot;ShiftLeft&quot; _
                                        , &quot;ShiftRight&quot; _
@@ -3712,6 +3746,26 @@ Catch:
        GoTo Finally
 End Function   &apos;  SFDocuments.SF_Calc.SetValue
 
+REM 
-----------------------------------------------------------------------------
+Public Function Shapes(Optional ByVal SheetName As Variant _
+                                                       , Optional ByVal 
ShapeName As Variant _
+                                                       ) As Variant
+&apos;&apos;&apos; Return either the list of shapes present in the given sheet 
or a shape object
+&apos;&apos;&apos;     Args:
+&apos;&apos;&apos;             SheetName: The name of an existing sheet
+&apos;&apos;&apos;             ShapeName: The user-defined name of the 
targeted shape or the zero-length string
+&apos;&apos;&apos;     Returns:
+&apos;&apos;&apos;             When ShapeName = &quot;&quot;, return the list 
of the shapes present in the sheet,
+&apos;&apos;&apos;             otherwise, return a new shape service instance
+&apos;&apos;&apos;     Examples:
+&apos;&apos;&apos;             Dim oShape As Object
+&apos;&apos;&apos;             Set oShape = oDoc.Shapes(&quot;SheetX&quot;, 
&quot;myShape&quot;)
+
+Try:
+       Shapes = _Shapes(SheetName, ShapeName, _IsChart := False)
+
+End Function    &apos;   SFDocuments.SF_Calc.Shapes
+
 REM 
-----------------------------------------------------------------------------
 Public Function ShiftDown(Optional ByVal Range As Variant _
                                                                , Optional 
ByVal WholeRow As Variant _
@@ -5385,10 +5439,10 @@ Try:
        Set oXRange = _ParseAddress(psRange).XCellRange
 
        &apos;  Initialize the range area
-       With oRect
+       With oRect                                              &apos;  All 
units in 1/100mm
                .X = oXRange.Position.X
                .Y = oXRange.Position.Y
-               .Width = oXRange.Size.Width                     &apos;  Size is 
in 1/100mm
+               .Width = oXRange.Size.Width
                .Height = oXRange.Size.Height
        End With
 
@@ -5461,6 +5515,126 @@ Finally:
        Exit Sub
 End Sub        &apos;  SFDocuments.SF_Calc._RestoreSelections
 
+REM 
-----------------------------------------------------------------------------
+Public Function _Shapes(Optional ByVal SheetName As Variant _
+                                                       , Optional ByVal 
ShapeName As Variant _
+                                                       , Optional ByVal 
_IsChart As Variant _
+                                                       ) As Variant
+&apos;&apos;&apos; Return either the list of shapes present in the given sheet 
or a shape object
+&apos;&apos;&apos;     Args:
+&apos;&apos;&apos;             SheetName: The name of an existing sheet
+&apos;&apos;&apos;             ShapeName: The user-defined name of the 
targeted shape or the zero-length string
+&apos;&apos;&apos;             _IsChart: When True , only shapes containing a 
chart are considered,
+&apos;&apos;&apos;                              when False (default), all 
shapes are considered, except those containing a chart
+&apos;&apos;&apos;     Returns:
+&apos;&apos;&apos;             When ShapeName = &quot;&quot;, return the list 
of the shapes present in the sheet,
+&apos;&apos;&apos;             otherwise, return a new shape or chart service 
instance
+
+Dim vShapes As Variant                         &apos;  Return value when array 
of shape/chart names
+Dim oChart As Object                           &apos;  A new chart instance
+Dim oShape As Object                           &apos;  A new shape instance. 
Is the superclass of a chart instance when _IsChart = True
+Dim oSheet As Object                           &apos;  Alias of SheetName as 
reference
+Dim oDrawPage As Object                                &apos;  
com.sun.star.drawing.XDrawPage
+Dim oNextShape As Object                       &apos;  
com.sun.star.drawing.XShape
+Dim sShapeName As String                       &apos;  Some shape/chart name
+Dim lCount As Long                                     &apos;  Counter for 
shapes among all drawing objects
+Static oSession As Object                      &apos;  Session service
+Dim i As Long
+Const cstChartShape = &quot;com.sun.star.drawing.OLE2Shape&quot;
+
+Dim cstThisSub As String       :       cstThisSub = 
&quot;SFDocuments.Calc.&quot; &amp; Iif(_IsChart, &quot;Charts&quot;, 
&quot;Shapes&quot;)
+Dim cstSubArgs As String       :       cstSubArgs = &quot;SheetName, [&quot; 
&amp; Iif(_IsChart, &quot;ChartName&quot;, &quot;ShapeName&quot;) &amp; 
&quot;=&quot;&quot;&quot;&quot;]&quot;
+
+       If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
+       vShapes = Array()
+
+Check:
+       If IsMissing(ShapeName) Or IsEmpty(ShapeName) Then ShapeName = 
&quot;&quot;
+       If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
+               If Not _IsStillAlive(True) Then GoTo Finally
+               If Not _ValidateSheet(SheetName, &quot;SheetName&quot;, , True) 
Then GoTo Finally
+               If Not ScriptForge.SF_Utils._Validate(ShapeName, Iif(_IsChart, 
&quot;ChartName&quot;, &quot;ShapeName&quot;), V_STRING) Then GoTo Finally
+       End If
+
+Try:
+       &apos;  Because the user can change it constantly, the list of valid 
shapes has to be rebuilt at each time
+       Set oSheet = _Component.getSheets.getByName(SheetName)
+       Set oDrawPage = oSheet.getDrawPage()
+       vShapes = Array()
+       lCount = -1
+
+       &apos;  Explore shapes starting from the sheet draw page
+       For i = 0 To oDrawPage.Count - 1
+
+               Set oShape = Nothing
+               Set oChart = Nothing
+
+               Set oNextShape = oDrawPage.getByIndex(i)
+               sShapeName = oNextShape.Name                                    
                                        &apos;  User-defined name
+               If Len(sShapeName) = 0 Then
+                       If IsNull(oSession) Then Set oSession = 
CreateScriptService(&quot;ScriptForge.Session&quot;)
+                       If oSession.HasUnoProperty(oNextShape, 
&quot;PersistName&quot;) Then sShapeName = oNextShape.PersistName               
 &apos;  Internal name
+               End If
+
+               &apos;  Make anyway a SF_Shape instance, when name fits
+               If Len(ShapeName) &gt; 0 And Len(sShapeName) &gt; 0 And 
ShapeName = sShapeName Then
+                       Set oShape = New SF_Shape
+                       With oShape
+                               Set .[Me] = oShape
+                               Set .[_Parent] = [Me]
+                               ._SheetName = SheetName
+                               ._DrawIndex = i
+                               ._ShapeName = ShapeName
+                               Set ._Shape = oNextShape
+                               ._IsChart = _IsChart
+                               ._Initialize()
+                       End With
+
+                       &apos;  Retain charts only
+                       If _IsChart And 
oNextShape.supportsService(cstChartShape) Then
+                               Set oChart = New SF_Chart
+                               With oChart
+                                       Set .[Me] = oChart
+                                       Set .[_Parent] = [Me]
+                                       ._SheetName = SheetName
+                                       ._ChartName = ShapeName
+                                       ._PersistentName = 
oNextShape.PersistName
+                                       Set ._Chart = 
oSheet.getCharts().getByName(._PersistentName)
+                                       Set ._ChartObject = 
._Chart.EmbeddedObject
+                                       Set ._Diagram = ._ChartObject.Diagram
+                               End With
+                               &apos;  Make the SF_Shape superclass: a chart 
is a subclass of a shape
+                               Set oChart.[_Super] = oShape
+                       End If
+                       Exit For
+
+               End If
+
+               &apos;  Build stack of shape names when shape or chart not found
+               If IsNull(oShape) And Len(sShapeName) &gt; 0 Then
+                       lCount = lCount + 1
+                       If UBound(vShapes) &lt; 0 Then
+                               vShapes = Array(sShapeName)
+                       Else
+                               ReDim Preserve vShapes(0 To UBound(vShapes) + 1)
+                               vShapes(lCount) = sShapeName
+                       End If
+               End If
+       Next i
+
+       &apos;  Raise error when shape/chart not found
+       If Len(ShapeName) &gt; 0 And IsNull(oShape) Then
+               If Not ScriptForge.SF_Utils._Validate(ShapeName, Iif(_IsChart, 
&quot;ChartName&quot;, &quot;ShapeName&quot;), V_STRING, vShapes, True) Then 
GoTo Finally
+       End If
+
+Finally:
+       If Len(ShapeName) = 0 Then _Shapes = vShapes Else Set _Shapes = 
Iif(_IsChart, oChart, oShape)
+       ScriptForge.SF_Utils._ExitFunction(cstThisSub)
+       Exit Function
+Catch:
+       GoTo Finally
+End Function    &apos;   SFDocuments.SF_Calc._Shapes
+
 REM 
-----------------------------------------------------------------------------
 Private Function _ValidateSheet(Optional ByRef pvSheetName As Variant _
                                                                        , 
Optional ByVal psArgName As String _
diff --git a/wizards/source/sfdocuments/SF_Chart.xba 
b/wizards/source/sfdocuments/SF_Chart.xba
index 0538fb8af758..e559f23f1011 100644
--- a/wizards/source/sfdocuments/SF_Chart.xba
+++ b/wizards/source/sfdocuments/SF_Chart.xba
@@ -46,15 +46,14 @@ REM 
============================================================= PRIVATE MEMBER
 
 Private [Me]                                   As Object
 Private [_Parent]                              As Object               &apos;  
Parent Calc document
+Private [_Super]                               As Object               &apos;  
The SF_Shape superclass instance
 Private ObjectType                             As String               &apos;  
Must be CHART
 Private ServiceName                            As String
 
 &apos; Chart description
 Private _SheetName                             As String               &apos;  
Name of the Calc sheet containing the chart
-Private _DrawIndex                             As Long                 &apos;  
Index of the chart in the sheet&apos;s draw page
 Private _ChartName                             As String               &apos;  
User name
 Private _PersistentName                        As String               &apos;  
Internal name
-Private _Shape                                 As Object               &apos;  
com.sun.star.drawing.XShape
 Private _Chart                                 As Object               &apos;  
com.sun.star.table.XTableChart
 Private _ChartObject                   As Object               &apos;  
com.sun.star.lang.XComponent - ScChartObj
 Private _Diagram                               As Object               &apos;  
com.sun.star.chart.XDiagram
@@ -68,13 +67,12 @@ REM 
----------------------------------------------------------------------------
 Private Sub Class_Initialize()
        Set [Me] = Nothing
        Set [_Parent] = Nothing
+       Set [_Super] = Nothing
        ObjectType = &quot;CHART&quot;
        ServiceName = &quot;SFDocuments.Chart&quot;
        _SheetName = &quot;&quot;
-       _DrawIndex = -1
        _ChartName = &quot;&quot;
        _PersistentName = &quot;&quot;
-       Set _Shape = Nothing
        Set _Chart = Nothing
        Set _ChartObject = Nothing
        Set _Diagram = Nothing
@@ -87,6 +85,7 @@ End Sub               &apos;  SFDocuments.SF_Chart Destructor
 
 REM 
-----------------------------------------------------------------------------
 Public Function Dispose() As Variant
+       If Not IsNull([_Super]) Then [_Super].Dispose()
        Call Class_Terminate()
        Set Dispose = Nothing
 End Function   &apos;  SFDocuments.SF_Chart Explicit Destructor
@@ -238,113 +237,23 @@ End Property     &apos;  SFDocuments.SF_Chart.YTitle 
(let)
 REM 
-----------------------------------------------------------------------------
 Property Get XChartObj() As Variant
 &apos;&apos;&apos;     com.sun.star.lang.XComponent - ScChartObj
-       ChartType = _PropertyGet(&quot;XChartObj&quot;)
+       XChartObj = _PropertyGet(&quot;XChartObj&quot;)
 End Property   &apos;  SFDocuments.SF_Chart.XChartObj (get)
 
 REM 
-----------------------------------------------------------------------------
 Property Get XDiagram() As Variant
 &apos;&apos;&apos;     com.sun.star.chart.XDiagram
-       ChartType = _PropertyGet(&quot;XDiagram&quot;)
+       XDiagram = _PropertyGet(&quot;XDiagram&quot;)
 End Property   &apos;  SFDocuments.SF_Chart.XDiagram (get)
 
-REM 
-----------------------------------------------------------------------------
-Property Get XShape() As Variant
-&apos;&apos;&apos;     com.sun.star.drawing.XShape
-       ChartType = _PropertyGet(&quot;XShape&quot;)
-End Property   &apos;  SFDocuments.SF_Chart.XShape (get)
-
 REM 
-----------------------------------------------------------------------------
 Property Get XTableChart() As Variant
 &apos;&apos;&apos;     com.sun.star.table.XTableChart
-       ChartType = _PropertyGet(&quot;XTableChart&quot;)
+       XTableChart = _PropertyGet(&quot;XTableChart&quot;)
 End Property   &apos;  SFDocuments.SF_Chart.XTableChart (get)
 
 REM ===================================================================== 
METHODS
 
-REM 
-----------------------------------------------------------------------------
-Public Function ExportToFile(Optional ByVal FileName As Variant _
-                                                       , Optional ByVal 
ImageType As Variant _
-                                                       , Optional ByVal 
Overwrite As Variant _
-                                                       ) As Boolean
-&apos;&apos;&apos; Store the chart as an image to the given file location
-&apos;&apos;&apos;     Args:
-&apos;&apos;&apos;             FileName: Identifies the file where to save. It 
must follow the SF_FileSystem.FileNaming notation
-&apos;&apos;&apos;             ImageType: the name of the targeted image type
-&apos;&apos;&apos;                     Allowed values: gif, jpeg, png 
(default), svg and tiff
-&apos;&apos;&apos;             Overwrite: True if the destination file may be 
overwritten (default = False)
-&apos;&apos;&apos;     Returns:
-&apos;&apos;&apos;             False if the document could not be saved
-&apos;&apos;&apos;     Exceptions:
-&apos;&apos;&apos;             CHARTEXPORTERROR                The destination 
has its readonly attribute set or overwriting rejected
-&apos;&apos;&apos;     Examples:
-&apos;&apos;&apos;             
oChart.ExportToFile(&quot;C:\Me\Chart2.gif&quot;, ImageType := &quot;gif&quot;, 
Overwrite := True)
-
-Dim bSaved As Boolean                          &apos;  return value
-Dim oSfa As Object                                     &apos;  
com.sun.star.ucb.SimpleFileAccess
-Dim sFile As String                                    &apos;  Alias of 
FileName
-Dim vStoreArguments As Variant         &apos;  Array of 
com.sun.star.beans.PropertyValue
-Dim FSO As Object                                      &apos;  SF_FileSystem
-Dim oExport As Object                          &apos;  
com.sun.star.drawing.GraphicExportFilter
-Dim vImageTypes As Variant                     &apos;  Array of permitted 
image types
-Dim vMimeTypes As Variant                      &apos;  Array of corresponding 
mime types in the same order as vImageTypes
-
-Const cstImageTypes =  &quot;gif,jpeg,png,svg,tiff&quot;
-Const cstMimeTypes =   
&quot;image/gif,image/jpeg,image/png,image/svg+xml,image/tiff&quot;
-
-Const cstThisSub = &quot;SFDocuments.Chart.ExportToFile&quot;
-Const cstSubArgs = &quot;FileName, 
[ImageType=&quot;&quot;png&quot;&quot;|&quot;&quot;gif&quot;&quot;|&quot;&quot;jpeg&quot;&quot;|&quot;&quot;svg&quot;&quot;|&quot;&quot;tiff&quot;&quot;],
 [Overwrite=False]&quot;
-
-       If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo 
CatchError
-       bSaved = False
-
-Check:
-       If IsMissing(ImageType) Or IsEmpty(ImageType) Then ImageType = 
&quot;png&quot;
-       If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
-
-       vImageTypes = Split(cstImageTypes, &quot;,&quot;)
-       If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
-               If Not [_Parent]._IsStillAlive() Then GoTo Finally
-               If Not ScriptForge.SF_Utils._ValidateFile(FileName, 
&quot;FileName&quot;) Then GoTo Finally
-               If Not ScriptForge.SF_Utils._Validate(ImageType, 
&quot;ImageType&quot;, V_STRING, vImageTypes) Then GoTo Finally
-               If Not ScriptForge.SF_Utils._Validate(Overwrite, 
&quot;Overwrite&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
-       End If
-
-       &apos;  Check destination file overwriting
-       Set FSO = CreateScriptService(&quot;FileSystem&quot;)
-       sFile = FSO._ConvertToUrl(FileName)
-       If FSO.FileExists(FileName) Then
-               If Overwrite = False Then GoTo CatchError
-               Set oSfa = 
ScriptForge.SF_Utils._GetUNOService(&quot;FileAccess&quot;)
-               If oSfa.isReadonly(sFile) Then GoTo CatchError
-       End If
-
-Try:
-       &apos;  Setup arguments
-       vMimeTypes = Split(cstMimeTypes, &quot;,&quot;)
-       vStoreArguments = Array( _
-                                                               
ScriptForge.SF_Utils._MakePropertyValue(&quot;URL&quot;, sFile) _
-                                                               , 
ScriptForge.SF_Utils._MakePropertyValue(&quot;MediaType&quot; _
-                                                                       , 
vMimeTypes(ScriptForge.SF_Array.IndexOf(vImageTypes, ImageType, CaseSensitive 
:= False))) _
-                                                       )
-       &apos;  Export with the com.sun.star.drawing.GraphicExportFilter UNO 
service
-       Set oExport = 
ScriptForge.SF_Utils._GetUNOService(&quot;GraphicExportFilter&quot;)
-       With oExport
-               .setSourceDocument(_Shape)
-               .filter(vStoreArguments)
-       End With
-       bSaved = True
-
-Finally:
-       ExportToFile = bSaved
-       ScriptForge.SF_Utils._ExitFunction(cstThisSub)
-       Exit Function
-Catch:
-       GoTo Finally
-CatchError:
-       ScriptForge.SF_Exception.RaiseFatal(CHARTEXPORTERROR, 
&quot;FileName&quot;, FileName, &quot;Overwrite&quot;, Overwrite)
-       GoTo Finally
-End Function   &apos;   SFDocuments.SF_Chart.ExportToFile
-
 REM 
-----------------------------------------------------------------------------
 Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
 &apos;&apos;&apos;     Return the actual value of the given property
@@ -381,9 +290,8 @@ REM 
----------------------------------------------------------------------------
 Public Function Methods() As Variant
 &apos;&apos;&apos;     Return the list of public methods of the Chart service 
as an array
 
+       &apos;  Methods are in the SF_Shape superclass
        Methods = Array( _
-                                       &quot;ExportToFile&quot; _
-                                       , &quot;Resize&quot; _
                                        )
 
 End Function   &apos;  SFDocuments.SF_Chart.Methods
@@ -404,6 +312,7 @@ Public Function Properties() As Variant
                                        , &quot;Title&quot; _
                                        , &quot;XChartObj&quot; _
                                        , &quot;XDiagram&quot; _
+                                       , &quot;XRectangle&quot; _
                                        , &quot;XShape&quot; _
                                        , &quot;XTableChart&quot; _
                                        , &quot;XTitle&quot; _
@@ -412,71 +321,6 @@ Public Function Properties() As Variant
 
 End Function   &apos;  SFDocuments.SF_Chart.Properties
 
-REM 
-----------------------------------------------------------------------------
-Public Function Resize(Optional ByVal XPos As Variant _
-                                                               , Optional 
ByVal YPos As Variant _
-                                                               , Optional 
ByVal Width As Variant _
-                                                               , Optional 
ByVal Height As Variant _
-                                                               ) As Boolean
-&apos;&apos;&apos;     Move the topleft corner of a chart to new coordinates 
and/or modify its dimensions
-&apos;&apos;&apos;     All distances are expressed in 1/100th mm
-&apos;&apos;&apos;     Args:
-&apos;&apos;&apos;             XPos : the vertical distance from the topleft 
corner
-&apos;&apos;&apos;             YPos : the horizontal distance from the topleft 
corner
-&apos;&apos;&apos;             Width : the horizontal width of the shape 
containing the chart
-&apos;&apos;&apos;             Height : the vertical height of the shape 
containing the chart
-&apos;&apos;&apos;             Negative or missing arguments are left unchanged
-&apos;&apos;&apos;     Returns:
-&apos;&apos;&apos;             True when successful
-&apos;&apos;&apos;     Examples:
-&apos;&apos;&apos;             oChart.Resize(1000, 2000, Height := 6000)       
&apos;  Width is not changed
-
-Dim bResize As Boolean                         &apos;  Return value
-Dim oPosition As Object                                &apos;  
com.sun.star.awt.Point
-Dim oSize As Object                                    &apos;  
com.sun.star.awt.Size
-Const cstThisSub = &quot;SFDocuments.Chart.Resize&quot;
-Const cstSubArgs = &quot;[XPos], [YPos], [Width], [Height]&quot;
-
-       If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
-       bResize = False
-
-Check:
-       If IsMissing(XPos) Or IsEmpty(XPos) Then XPos = -1
-       If IsMissing(YPos) Or IsEmpty(YPos) Then YPos = -1
-       If IsMissing(Height) Or IsEmpty(Height) Then Height = -1
-       If IsMissing(Width) Or IsEmpty(Width) Then Width = -1
-       If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
-               If Not [_Parent]._IsStillAlive() Then GoTo Finally
-               If Not ScriptForge.SF_Utils._Validate(XPos, &quot;XPos&quot;, 
ScriptForge.V_NUMERIC) Then GoTo Finally
-               If Not ScriptForge.SF_Utils._Validate(YPos, &quot;YPos&quot;, 
ScriptForge.V_NUMERIC) Then GoTo Finally
-               If Not ScriptForge.SF_Utils._Validate(Width, &quot;Width&quot;, 
ScriptForge.V_NUMERIC) Then GoTo Finally
-               If Not ScriptForge.SF_Utils._Validate(Height, 
&quot;Height&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
-       End If
-
-Try:
-       With _Shape
-               &apos;  Get the current values
-               Set oPosition = .Position
-               Set oSize = .Size
-               &apos;  Modify relevant elements
-               If XPos &gt;= 0 Then oPosition.X = CLng(XPos)
-               If YPos &gt;= 0 Then oPosition.Y = CLng(YPos)
-               If Width &gt; 0 Then oSize.Width = CLng(Width)
-               If Height &gt; 0 Then oSize.Height = CLng(Height)
-               &apos;  Rewrite
-               .setPosition(oPosition)
-               .setSize(oSize)
-       End With
-       bResize = True
-
-Finally:
-       Resize = bResize
-       ScriptForge.SF_Utils._ExitFunction(cstThisSub)
-       Exit Function
-Catch:
-       GoTo Finally
-End Function   &apos;  SF_Documents.SF_Chart.Resize
-
 REM 
-----------------------------------------------------------------------------
 Public Function SetProperty(Optional ByVal PropertyName As Variant _
                                                                , Optional 
ByRef Value As Variant _
@@ -509,6 +353,44 @@ Catch:
        GoTo Finally
 End Function   &apos;  SFDocuments.SF_Chart.SetProperty
 
+REM ======================================================= SUPERCLASS 
PROPERTIES
+
+REM 
-----------------------------------------------------------------------------
+Property Get XRectangle() As Variant
+       XRectangle = [_Super].GetProperty(&quot;XRectangle&quot;)
+End Property   &apos;  SFDocuments.SF_Chart.XRectangle
+
+REM 
-----------------------------------------------------------------------------
+Property Get XShape() As Variant
+       XShape = [_Super].GetProperty(&quot;XShape&quot;)
+End Property   &apos;  SFDocuments.SF_Chart.XShape
+
+REM ========================================================== SUPERCLASS 
METHODS
+
+REM 
-----------------------------------------------------------------------------
+Public Function ExportToFile(Optional ByVal FileName As Variant _
+                                                       , Optional ByVal 
ImageType As Variant _
+                                                       , Optional ByVal 
Overwrite As Variant _
+                                                       ) As Boolean
+       ExportToFile = [_Super].ExportToFile(FileName, ImageType, Overwrite)
+End Function    &apos;   SFDocuments.SF_Chart.ExportToFile
+
+REM 
-----------------------------------------------------------------------------
+Public Function Resize(Optional ByVal XPos As Variant _
+                                                               , Optional 
ByVal YPos As Variant _
+                                                               , Optional 
ByVal Width As Variant _
+                                                               , Optional 
ByVal Height As Variant _
+                                                               ) As Boolean
+       Resize = [_Super].Resize(XPos, YPos, Width, Height)
+End Function    &apos;   SFDocuments.SF_Chart.Resize
+
+REM 
-----------------------------------------------------------------------------
+Public Function Rotate(Optional ByVal Angle As Variant _
+                                                       , Optional ByRef Pivot 
As Variant _
+                                                       ) As Boolean
+       Rotate = [_Super].Rotate(Angle, Pivot)
+End Function    &apos;   SFDocuments.SF_Chart.Rotate
+
 REM =========================================================== PRIVATE 
FUNCTIONS
 
 REM 
-----------------------------------------------------------------------------
@@ -612,8 +494,6 @@ Const cstSubArgs = &quot;&quot;
                        Set _PropertyGet = _ChartObject
                Case UCase(&quot;XDiagram&quot;)
                        Set _PropertyGet = _Diagram
-               Case UCase(&quot;XShape&quot;)
-                       Set _PropertyGet = _Shape
                Case UCase(&quot;XTableChart&quot;)
                        Set _PropertyGet = _Chart
                Case Else
@@ -804,9 +684,9 @@ Private Function _Repr() As String
 &apos;&apos;&apos;     Convert the Chart instance to a readable string, 
typically for debugging purposes (DebugPrint ...)
 &apos;&apos;&apos;     Args:
 &apos;&apos;&apos;     Return:
-&apos;&apos;&apos;             &quot;[Chart]: Name - Type
+&apos;&apos;&apos;             &quot;[Chart]: Name - Type&quot;
 
-       _Repr = &quot;[Chart]: &quot; &amp; ChartName &amp; &quot; - &quot; 
&amp; ChartType
+       _Repr = &quot;[Chart]: &quot; &amp; _ChartName &amp; &quot; - &quot; 
&amp; ChartType
 
 End Function   &apos;  SFDocuments.SF_Chart._Repr
 
diff --git a/wizards/source/sfdocuments/SF_Document.xba 
b/wizards/source/sfdocuments/SF_Document.xba
index aa05a67581a6..1b8822ddf77f 100644
--- a/wizards/source/sfdocuments/SF_Document.xba
+++ b/wizards/source/sfdocuments/SF_Document.xba
@@ -1750,6 +1750,60 @@ End Function     &apos;  SFDocuments.SF_Document.XStyle
 
 REM =========================================================== PRIVATE 
FUNCTIONS
 
+REM 
-----------------------------------------------------------------------------
+Public Function _ConvertRectangle(ByRef poRect As Object _
+                                                                               
, ByVal piTargetUnit As Integer _
+                                                                               
) As Object
+&apos;&apos;&apos;     Convert the X, Y, Width, Height dimensions expressed in 
1/100mm units to a Rectangle expressed in pixels,
+&apos;&apos;&apos;     or vice-versa
+&apos;&apos;&apos;     Args:
+&apos;&apos;&apos;             poRect: a com.sun.star.awt.Rectangle
+&apos;&apos;&apos;             piTargetUnit: a A com.sun.star.util.MeasureUnit 
constant
+&apos;&apos;&apos;                     Only PIXEL and MM_100TH are admitted.
+&apos;&apos;&apos;     Returns:
+&apos;&apos;&apos;             A com.sun.star.awt.Rectangle object after 
conversion of the position and size
+&apos;&apos;&apos;             Negative input values are not converted but set 
to zero
+
+Dim oComp As Object                                                    &apos;  
Component window com.sun.star.awt.XWindow
+Dim oPoint As New com.sun.star.awt.Point       &apos;  The input position
+Dim oSize As New com.sun.star.awt.Size         &apos;  The input size
+Dim oRect As New com.sun.star.awt.Rectangle    &apos;  Return value
+
+Try:
+       Set oComp = _Component.CurrentController.ComponentWindow
+
+       With poRect
+               &apos;  Point part
+               If .X &gt; 0 Then oPoint.X = .X Else oPoint.X = 0
+               If .Y &gt; 0 Then oPoint.Y = .Y Else oPoint.Y = 0
+               If piTargetUnit = com.sun.star.util.MeasureUnit.MM_100TH Then
+                       Set oPoint = oComp.convertPointToLogic(oPoint, 
piTargetUnit)
+               Else
+                       Set oPoint = oComp.convertPointToPixel(oPoint, 
com.sun.star.util.MeasureUnit.MM_100TH)
+               End If
+
+               &apos;  Size part
+               If .Width &gt; 0 Then oSize.Width = .Width Else oSize.Width = 0
+               If .Height &gt; 0 Then oSize.Height = .Height Else oSize.Height 
= 0
+               If piTargetUnit = com.sun.star.util.MeasureUnit.MM_100TH Then
+                       Set oSize = oComp.convertSizeToLogic(oSize, 
piTargetUnit)
+               Else
+                       Set oSize = oComp.convertSizeToPixel(oSize, 
com.sun.star.util.MeasureUnit.MM_100TH)
+               End If
+       End With
+
+       With oRect
+               .X = oPoint.X
+               .Y = oPoint.Y
+               .Width = oSize.Width
+               .Height = oSize.Height
+       End With
+
+Finally:
+       Set _ConvertRectangle = oRect
+       Exit Function
+End Function   &apos;  SFDocuments.SF_Document._ConvertRectangle
+
 REM 
-----------------------------------------------------------------------------
 Private Function _FileIdent() As String
 &apos;&apos;&apos;     Returns a file identification from the information that 
is currently available
diff --git a/wizards/source/sfdocuments/SF_Shape.xba 
b/wizards/source/sfdocuments/SF_Shape.xba
new file mode 100644
index 000000000000..52b52d8219b7
--- /dev/null
+++ b/wizards/source/sfdocuments/SF_Shape.xba
@@ -0,0 +1,686 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" 
"module.dtd">
+<script:module xmlns:script="http://openoffice.org/2000/script"; 
script:name="SF_Shape" script:language="StarBasic" 
script:moduleType="normal">REM 
=======================================================================================================================
+REM ===                        The ScriptForge library and its associated 
libraries are part of the LibreOffice project.                               ===
+REM    ===                                             The SFDocuments library 
is one of the associated libraries.                                             
                        ===
+REM ===                                        Full documentation is available 
on https://help.libreoffice.org/                                                
                ===
+REM 
=======================================================================================================================
+
+Option Compatible
+Option ClassModule
+
+Option Explicit
+
+&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
+&apos;&apos;&apos;     SF_Shape
+&apos;&apos;&apos;     ========
+&apos;&apos;&apos;
+&apos;&apos;&apos;             The SF_Shape module is focused on the 
description of shapes/images/drawing objects
+&apos;&apos;&apos;             stored in documents.
+&apos;&apos;&apos;             In the actual release only shapes in Calc 
sheets are considered.
+&apos;&apos;&apos;             Charts are a special type of shapes. The 
&quot;Chart&quot; service is a subclass of the actual service.
+&apos;&apos;&apos;
+&apos;&apos;&apos;             Definitions
+&apos;&apos;&apos;                     Shapes have 2 distinct names:
+&apos;&apos;&apos;                             -       an internal name, given 
by the LibreOffice application
+&apos;&apos;&apos;                             -       an optional 
user-defined name
+&apos;&apos;&apos;                     In the scope of the ScriptForge 
libraries, the Shape name is the name given by the user.
+&apos;&apos;&apos;                     Only when there is no user name, the 
internal name may be used instead.
+&apos;&apos;&apos;                     The name of a shape must be unique 
within the sheet where it is located.
+&apos;&apos;&apos;
+&apos;&apos;&apos;             Service invocation from the &quot;Calc&quot; 
service
+&apos;&apos;&apos;                     Either make a new Shape
+&apos;&apos;&apos;                             
calc.CreateShapeFromFile(ShapeName, SheetName, ImageFile, AsLink := False)
+&apos;&apos;&apos;                     or select an existing one within a 
given sheet
+&apos;&apos;&apos;                             calc.Shapes(SheetName, 
ShapeName)
+&apos;&apos;&apos;
+&apos;&apos;&apos;             Detailed user documentation:
+&apos;&apos;&apos;                     
https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_shape.html?DbPAR=BASIC
+&apos;&apos;&apos;
+&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
+
+REM ================================================================== 
EXCEPTIONS
+
+Private Const SHAPEEXPORTERROR         =       &quot;SHAPEEXPORTERROR&quot;
+
+REM ============================================================= PRIVATE 
MEMBERS
+
+Private [Me]                                   As Object
+Private [_Parent]                              As Object               &apos;  
Parent Calc document
+Private ObjectType                             As String               &apos;  
Must be SHAPE
+Private ServiceName                            As String
+
+&apos; Shape description
+Private _SheetName                             As String               &apos;  
Name of the Calc sheet containing the Shape
+Private _DrawIndex                             As Long                 &apos;  
Index of the Shape in the sheet&apos;s draw page
+Private _ShapeName                             As String               &apos;  
User name
+Private _PersistentName                        As String               &apos;  
Internal name
+Private _Shape                                 As Object               &apos;  
com.sun.star.drawing.XShape
+Private _XPos                                  As Long                 &apos;  
Initial X position
+Private _YPos                                  As Long                 &apos;  
Initial Y position
+Private _IsChart                               As Boolean              &apos;  
When True, instance is a superclass of a chart instance
+
+REM ============================================================ MODULE 
CONSTANTS
+
+
+REM ====================================================== 
CONSTRUCTOR/DESTRUCTOR
+
+REM 
-----------------------------------------------------------------------------
+Private Sub Class_Initialize()
+       Set [Me] = Nothing
+       Set [_Parent] = Nothing
+       ObjectType = &quot;SHAPE&quot;
+       ServiceName = &quot;SFDocuments.Shape&quot;
+       _SheetName = &quot;&quot;
+       _DrawIndex = -1
+       _ShapeName = &quot;&quot;
+       _PersistentName = &quot;&quot;
+       Set _Shape = Nothing
+       _XPos = -1
+       _YPos = -1
+       _IsChart = False
+End Sub                &apos;  SFDocuments.SF_Shape Constructor
+
+REM 
-----------------------------------------------------------------------------
+Private Sub Class_Terminate()
+       Call Class_Initialize()
+End Sub                &apos;  SFDocuments.SF_Shape Destructor
+
+REM 
-----------------------------------------------------------------------------
+Public Function Dispose() As Variant
+       Call Class_Terminate()
+       Set Dispose = Nothing
+End Function   &apos;  SFDocuments.SF_Shape Explicit Destructor
+
+REM ================================================================== 
PROPERTIES
+
+REM 
-----------------------------------------------------------------------------
+Property Get XRectangle() As Variant
+&apos;&apos;&apos;     A com.sun.star.awt.XRectangle object. Distances are 
expressed in 1/100th mm.
+       XRectangle = _PropertyGet(&quot;XRectangle&quot;)
+End Property   &apos;  SFDocuments.SF_Shape.XRectangle (get)
+
+REM 
-----------------------------------------------------------------------------
+Property Get XShape() As Variant
+&apos;&apos;&apos;     com.sun.star.drawing.XShape
+       XShape = _PropertyGet(&quot;XShape&quot;)
+End Property   &apos;  SFDocuments.SF_Shape.XShape (get)
+
+REM ===================================================================== 
METHODS
+
+REM 
-----------------------------------------------------------------------------
+Public Function Anchor(Optional ByVal AnchorType As Variant _
+                                                               , Optional 
ByVal Cell As Variant _
+                                                               ) As Boolean
+&apos;&apos;&apos;     Define the anchor type and the cell to which the shape 
has to be anchored.
+&apos;&apos;&apos;     Args:
+&apos;&apos;&apos;             AnchorType: next strings are accepted,
+&apos;&apos;&apos;                     CELL: the shape is anchored &quot;to 
cell&quot;
+&apos;&apos;&apos;                     CELLRESIZE: the shape is anchored 
&quot;to cell (resize with cell)&quot;
+&apos;&apos;&apos;                     PAGE: the shape is anchored to the sheet
+&apos;&apos;&apos;             Cell: a unique cell or a cell range in the 
sheet where the shape is located.
+&apos;&apos;&apos;                     Only the top-left cell of a range will 
be considered.
+&apos;&apos;&apos;                     The argument is ignored and may be 
omitted when AnchorType = &quot;PAGE&quot;
+&apos;&apos;&apos;     Returns:
+&apos;&apos;&apos;             True when successful
+&apos;&apos;&apos;     Examples:
+&apos;&apos;&apos;             oShape.Anchor(&quot;CELL&quot;, Cell := 
&quot;B6&quot;)
+
+Dim bAnchor As Boolean                         &apos;  Return value
+Dim oCell As Object                                    &apos;  Alias of cell 
argument
+Dim oPosition As New com.sun.star.awt.Point            &apos;  Position of 
shape when anchor type is &quot;PAGE&quot;
+
+Const cstThisSub = &quot;SFDocuments.Shape.Anchor&quot;
+Const cstSubArgs = 
&quot;AnchorType=&quot;&quot;CELL&quot;&quot;|&quot;&quot;CELLRESIZE&quot;&quot;|&quot;&quot;PAGE&quot;&quot;,
 [Cell]&quot;
+
+       If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
+       bAnchor = False
+
+Check:
+       If IsMissing(Cell) Or IsEmpty(Cell) Then Cell = &quot;~.A1&quot;
+       If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
+               If Not [_Parent]._IsStillAlive() Then GoTo Finally
+               If Not ScriptForge.SF_Utils._Validate(AnchorType, 
&quot;AnchorType&quot;, V_STRING, Array(&quot;CELL&quot;, 
&quot;CELLRESIZE&quot;, &quot;PAGE&quot;)) Then GoTo Finally
+               If Not ScriptForge.SF_Utils._Validate(Cell, &quot;Cell&quot;, 
V_STRING) Then GoTo Finally
+       End If
+
+Try:
+       Set oCell = [_Parent]._ParseAddress(Cell)
+       With _Shape
+               Select Case UCase(AnchorType)
+                       Case &quot;CELL&quot;, &quot;CELLRESIZE&quot;
+                               .Anchor = oCell.XCellRange.getCellByPosition(0, 
0)
+                               .ResizeWithCell = ( UCase(AnchorType) = 
&quot;CELLRESIZE&quot; )
+                               bAnchor = True
+                       Case &quot;PAGE&quot;
+                               Set oPosition = .getPosition()
+                               .Anchor = oCell.XSpreadsheet
+                               .ResizeWithCell = False
+                               .setposition(oPosition)         &apos;  Restore 
the initial position (if not, position = A1)
+                               bAnchor = True
+                       Case Else
+               End Select
+       End With
+
+Finally:
+       Anchor = bAnchor
+       ScriptForge.SF_Utils._ExitFunction(cstThisSub)
+       Exit Function
+Catch:
+       GoTo Finally
+End Function   &apos;  SF_Documents.SF_Shape.Anchor
+
+REM 
-----------------------------------------------------------------------------
+Public Function ExportToFile(Optional ByVal FileName As Variant _
+                                                       , Optional ByVal 
ImageType As Variant _
+                                                       , Optional ByVal 
Overwrite As Variant _
+                                                       ) As Boolean
+&apos;&apos;&apos; Store the shape as an image to the given file location
+&apos;&apos;&apos;     Args:
+&apos;&apos;&apos;             FileName: Identifies the file where to save. It 
must follow the SF_FileSystem.FileNaming notation
+&apos;&apos;&apos;             ImageType: the name of the targeted image type
+&apos;&apos;&apos;                     Allowed values: gif, jpeg, png 
(default), svg and tiff
+&apos;&apos;&apos;             Overwrite: True if the destination file may be 
overwritten (default = False)
+&apos;&apos;&apos;     Returns:
+&apos;&apos;&apos;             False if the document could not be saved
+&apos;&apos;&apos;     Exceptions:
+&apos;&apos;&apos;             SHAPEEXPORTERROR                The destination 
has its readonly attribute set or overwriting rejected
+&apos;&apos;&apos;     Examples:
+&apos;&apos;&apos;             
oShape.ExportToFile(&quot;C:\Me\Shape2.gif&quot;, ImageType := &quot;gif&quot;, 
Overwrite := True)
+
+Dim bSaved As Boolean                          &apos;  return value
+Dim oSfa As Object                                     &apos;  
com.sun.star.ucb.SimpleFileAccess
+Dim sFile As String                                    &apos;  Alias of 
FileName
+Dim vStoreArguments As Variant         &apos;  Array of 
com.sun.star.beans.PropertyValue
+Dim FSO As Object                                      &apos;  SF_FileSystem
+Dim oExport As Object                          &apos;  
com.sun.star.drawing.GraphicExportFilter
+Dim vImageTypes As Variant                     &apos;  Array of permitted 
image types
+Dim vMimeTypes As Variant                      &apos;  Array of corresponding 
mime types in the same order as vImageTypes
+
+Const cstImageTypes =  &quot;gif,jpeg,png,svg,tiff&quot;
+Const cstMimeTypes =   
&quot;image/gif,image/jpeg,image/png,image/svg+xml,image/tiff&quot;
+
+Const cstThisSub = &quot;SFDocuments.Shape.ExportToFile&quot;
+Const cstSubArgs = &quot;FileName, 
[ImageType=&quot;&quot;png&quot;&quot;|&quot;&quot;gif&quot;&quot;|&quot;&quot;jpeg&quot;&quot;|&quot;&quot;svg&quot;&quot;|&quot;&quot;tiff&quot;&quot;],
 [Overwrite=False]&quot;
+
+       If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo 
CatchError
+       bSaved = False
+
+Check:
+       If IsMissing(ImageType) Or IsEmpty(ImageType) Then ImageType = 
&quot;png&quot;
+       If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
+
+       vImageTypes = Split(cstImageTypes, &quot;,&quot;)
+       If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
+               If Not [_Parent]._IsStillAlive() Then GoTo Finally
+               If Not ScriptForge.SF_Utils._ValidateFile(FileName, 
&quot;FileName&quot;) Then GoTo Finally
+               If Not ScriptForge.SF_Utils._Validate(ImageType, 
&quot;ImageType&quot;, V_STRING, vImageTypes) Then GoTo Finally
-e 
... etc. - the rest is truncated

Reply via email to