[Résolu][Basic] Spécifier une dataFlavor pour insertTransferable

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur : Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

[Résolu][Basic] Spécifier une dataFlavor pour insertTransferable

Message par eseb »

bonjour à tous,

je cherche à copier du texte formaté par copier-coller ; je suis parvenu à le faire en utilisant les commandes dispatch uno:copy et uno:paste gérant le presse-papier.

j'ai vu que, pour pallier certains inconvénients de la méthode précédente, l'on pouvait aussi utiliser les méthodes getTransferable et insertTransferable de currentController : dans mon cas, je n'obtiens qu'une copie en texte non formaté.

les dataflavors supportées après le getTransferable sont les suivantes (dans cet ordre):
  • application/vnd.oasis.opendocument.text-flat-xml
  • text/plain;charset=utf-16
  • text/rtf (RTF)
  • text/richtext (RTX)
j'ai l'impression que le premier format supporté par le receveur est utilisé (text/plain) alors que j'aurais besoin d'un format de texte enrichi (lequel vaut il mieux utiliser entre rtf et richtext?) mais je ne vois aucun moyen de spécifier le format désiré lors de l'appel à insertTransferable ? il y a une subtilité qui m'échappe ?

merci d'avance pour vos éclairages...

(je suis complètement débutant en programmation LibreOffice, mais j'ai fait un peu de développement Excel il y a quelques années)
LibreOffice 7.3 portable
Windows 7 x64
zeguedon
ManitOOu
ManitOOu
Messages : 3031
Inscription : 02 juil. 2014 17:25

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par zeguedon »

Bonjour,

Est-ce que tu peux préciser le contexte d'utilisation stp ? Un copier/coller de quoi vers quoi ? Pour être aidé efficacement il est vivement conseillé de joindre un fichier exemple. Mais en principe il faut passer par un SELECT pour récupérer ce qui doit-être copier.

Une recherche sur les termes getTransferable et insertTransferable retourne 111 résultats.
@+
Comment baliser [Résolu] ?
AOO
LibreOffice
Sous Linux
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

bonjour zeguedon,

merci de t'intéresser à mon problème ;

comme je l'ai précisé, j'obtiens bien un résultat et je suis le fonctionnement "classique" que l'on voit dans les exemples dont tu parles (j'avais fait une recherche bien sûr) et sur le bouquin d'Andrew Pitonyak, ma source initiale.

dans le principe que l'on voit un peu partout :

- oController.select sur la source
- récupération d'un objet oTransferable par oController.getTransferable
- oController.select sur la destination
- oController.insertTransferable en fournissant oTransferable

en faisant cela, le texte de la source est copié, mais en texte simple, or j'aimerais l'avoir en texte formaté.
comme expliqué dans ma question, le texte formaté fait partie des dataflavors supportées par la source : le problème est donc de savoir comment préciser que le "coller" doit s'effectuer dans ce format.

et là, j'ai cherché (sur le forum et plus largement) mais je n'ai rien trouvé, et comme la référence des API LibreOffice ne comporte aucun exemple d'utilisation, je me suis résolu à poster sur le forum ...

(une recherche de "dataFlavor" ne donne que 3 résultats hors ma question, et aucun ne s'applique à l'utilisation de getTransferable/insertTransferable)

j'ai omis le contexte car pour moi, c'est une question générale d'utilisation de getTransferable / InsertTransferable, valable quel que soit le contexte et quel que soit le module, d'où mon balisage [Basic] : comment choisir le format pour la destination parmi ceux disponibles dans la source?

le contexte : dans Calc, copier le contenu d'un commentaire dans une cellule ou réciproquement copier le texte d'une cellule dans un commentaire, le tout en respectant le format enrichi (texte en indice ou exposant, couleur etc...).

eseb
LibreOffice 7.3 portable
Windows 7 x64
zeguedon
ManitOOu
ManitOOu
Messages : 3031
Inscription : 02 juil. 2014 17:25

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par zeguedon »

Bonjour,
Merci pour les précisions.
Je reviendrai sur le sujet après avoir approfondi les points suivants :

Code : Tout sélectionner

getTransferDataFlavors()

Code : Tout sélectionner

isDataFlavorSupported()
Quelques liens à étudier en attendant :
https://www.openoffice.org/api/docs/com ... lavor.html
http://or.openoffice.org.openoffice.org ... -xref.html
http://or.openoffice.org.openoffice.org ... rable.html
https://wiki.openoffice.org/wiki/Docume ... #Clipboard
@+
Comment baliser [Résolu] ?
AOO
LibreOffice
Sous Linux
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

merci pour ces liens...
j'avais lu l'équivalent dans la documentation de LibreOffice sans y trouver de réponse ... celle d'OpenOffice semble un peu plus fournie et mieux organisée avec les types d'utilisation et des renvois au guide de développement, c'est bon à savoir...
LibreOffice 7.3 portable
Windows 7 x64
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 639
Inscription : 09 août 2017 22:15

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par Jurassic Pork »

Hello,
je ne crois pas que cela soit possible de choisir ce que l'on veut coller en utilisant insertTransferable en oobasic. Le souci c'est que lorsque l'on fait un copy dans le presse-papier, suivant ce qui est copié, il y a plusieurs formats de données (ex : Texte seul, RTF, PNG, HTML) qui sont enregistrés et le insertTransferable ne permet pas de choisir le format à utiliser. Il faudrait qu'il n'y ait qu'un seul format dans le presse-papier. Cela semble faisable en java en créant une classe qui implémente l'interface XTransferable en y mettant dedans les données du format qui nous intéresse mais je ne sais pas faire l'équivalent en ooBasic. Exemple en java pour du bmp :

Code : Tout sélectionner

 public class BmpTransferable implements XTransferable
  {
      public BmpTransferable(byte[] aBitmap)
      {
          mBitmapData = aBitmap;
      }
 
      // XTransferable methods
      public Object getTransferData(DataFlavor aFlavor) throws UnsupportedFlavorException
      {
          if ( !aFlavor.MimeType.equalsIgnoreCase(BITMAP_CONTENT_TYPE ) )
              throw new UnsupportedFlavorException();
 
          return mBitmapData;
      }
      public DataFlavor[] getTransferDataFlavors()
      {
          DataFlavor[] adf = new DataFlavor[1];
          DataFlavor bmpflv= new DataFlavor(
              BITMAP_CONTENT_TYPE,
              "Bitmap",
              new Type(byte[].class) );
          adf[0] = bmpflv;
 
          return adf;
      }
      public boolean isDataFlavorSupported(DataFlavor aFlavor)
      {
          return aFlavor.MimeType.equalsIgnoreCase(BITMAP_CONTENT_TYPE);
      }
 
      // members
      private byte[] mBitmapData;
      private final String BITMAP_CONTENT_TYPE = "application/x-openoffice;windows_formatname="Bitmap"";
  }
Sinon pour le coller on peut utiliser dans calc .uno:pastespecial avec comme paramètre la propriété Format avec comme valeurs 1 pour du texte et 10 pour du texte enrichi.
Pour le coller on peut utiliser dans writer .uno:ClipboardFormatItems en jouant sur la propriété SelectedFormat en argument

Ami calmant, J.P
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

Hello Jurassic Pork :)
merci de te pencher sur ma question : j'ai vu effectivement un exemple similaire dans le guide de développement OpenOffice (lien donné précédemment par zeguedon)

j'ai testé le pasteSpecial, cela fonctionne mais on retourne à la gestion du presse-papier, ce que je voulais éviter.

c'est assez surprenant tout de même que l'on ne puisse simplement choisir un format, sans redéfinir Xtransferable et cela m'amène d'autres questions:

- comment s'effectue en interne le choix du format lorsque l'on fait un insertTransferable : si le transfert s'effectue de cellule à cellule, le formatage est préservé donc le format rtf semble utilisé; par contre si le transfert s'effectue entre un commentaire et une cellule (ou inversement) le formatage est perdu (donc le format texte simple semble utilisé) ; dans les deux cas, les 2 formats (textes simple et enrichi) sont supportés et fournis dans les dataflavors, le texte simple précèdant dans la collection le texte rtf

- quelle différence de comportement pourrait expliquer que ce qui ne fonctionne pas avec get/insertTransferable (transfert entre cellule et commentaire) fonctionne en copier-coller (commandes dispatch ".uno:Copy" et ".uno:Paste", même pas besoin d'utiliser ".uno:PasteSpecial") ?
LibreOffice 7.3 portable
Windows 7 x64
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 639
Inscription : 09 août 2017 22:15

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par Jurassic Pork »

Hello,
en fait il semblerait qu'il y ait un bug quand on utilise un insertTransferable dans un commentaire.
J'ai fait différents essais :
1 - Transfert de texte formaté entre un commentaire de cellule et une cellule de classeur par getTransferable - insertTransferable : cela fonctionne.
2 - Transfert de texte formaté entre une cellule de classeur et un commentaire de cellule par getTransferable - insertTransferable : on obtient dans le commentaire que le texte non formaté.
3 - Transfert de texte formaté entre une cellule de classeur et un commentaire de cellule par getTransferable - insertTransferable en ne laissant dans le Transferable que le DataFlavor concernant le Rich Text : Erreur sur le insertTransferable -> pas de contenu valide. Par contre le Transferable fonctionne dans une cellule.
Conclusion :
Dans le sens Commentaire --> Cellule on peut utiliser getTransferable - insertTransferable pour copier le texte formaté.
Dans le sens Cellule --> Commentaire l'utilisation de getTransferable - insertTransferable ne copie que le texte non formaté à cause certainement d'un bug.
Par contre l'utilisation de Copy - PasteSpecial (avec Format à 10) en utilisant le presse-papier fonctionne dans ce sens aussi.
Pour réaliser l'essai numéro 3 j'ai utilisé une macro en python car comme en java on peut utiliser les classes et l'héritage de classe.

Code : Tout sélectionner

# coding: utf-8
from __future__ import unicode_literals
import uno
import os
import unohelper
from com.sun.star.datatransfer import XTransferable, DataFlavor
from com.sun.star.beans import PropertyValue

class Transferable(unohelper.Base, XTransferable):
    """Keep clipboard data and provide them."""
  
    def __init__(self, data,df):
        self.flavors = [df]
        self.data = [data] 
  
    def getTransferData(self, flavor):
        if not flavor: return
        mtype = flavor.MimeType
        for i,f in enumerate(self.flavors):
            if mtype == f.MimeType:
                return self.data[i]
  
    def getTransferDataFlavors(self):
        return tuple(self.flavors)
  
    def isDataFlavorSupported(self, flavor):
        if not flavor: return False
        mtype = flavor.MimeType
        for f in self.flavors:
            if mtype == f.MimeType:
                return True
        return False

def copy_oneFormat(format):
    oDoc = XSCRIPTCONTEXT.getDocument()
    df = None
    selectedContent = oDoc.CurrentController.getTransferable()
    dataFlavors = selectedContent.getTransferDataFlavors()
    for dataFlavor in dataFlavors:
        #print(dataFlavor.HumanPresentableName)
        if format in dataFlavor.HumanPresentableName.upper():
            df=dataFlavor
    if df is None:
        return None
    oData = selectedContent.getTransferData(df)
    transferable = Transferable(oData,df)
    #copie dans le presse-papier pour vérification
    ctx = XSCRIPTCONTEXT.getComponentContext()
    oClip = ctx.getServiceManager().createInstanceWithContext(
        "com.sun.star.datatransfer.clipboard.SystemClipboard", ctx)
    oClip.setContents(transferable, None)
    return transferable


def copy_rtf():
    copy_oneFormat("RICH TEXT")

def copy_png():
    copy_oneFormat("PNG")

def copy_html():
    copy_oneFormat("HTML")
    

# Functions that can be called from Tools -> Macros -> Run Macro.
g_exportedScripts = copy_rtf, copy_html, copy_png,
Les essais ont été réalisés sous :
  • Ubuntu 20.04 LibreOffice 7.3.4.2
    Windows 10 LibreOffice 7.2.6.2
    Windows 10 OpenOffice 4.1.10
Ami calmant, J.P
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26064
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par Dude »

Salut,

Pourquoi utiliser le presse-purée pour faire une opération qui est interne au document (et qui plus est à la cellule) ?
C'est un problème XY. :?
eseb a écrit : 02 juil. 2022 11:01le contexte : dans Calc, copier le contenu d'un commentaire dans une cellule ou réciproquement copier le texte d'une cellule dans un commentaire, le tout en respectant le format enrichi
Il suffit de parcourir le contenu enrichi de la cellule mot par mot et se servir de la méthode appendTextPortion pour les ajouter vers le commentaire.

Les objets com.sun.star.table.XCell (Cellule) et com.sun.star.sheet.XSheetAnnotation (Commentaire) contiennent une structure .text.XTextRange pour assurer le transfert du formatage.

:)
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 639
Inscription : 09 août 2017 22:15

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par Jurassic Pork »

Hello,
Dude a écrit : 13 juil. 2022 13:32 Il suffit de parcourir le contenu enrichi de la cellule mot par mot et se servir de la méthode appendTextPortion pour les ajouter vers le commentaire.
Dude, peux-tu nous montrer comment tu fais car à mon avis ce n'est pas si simple que cela :aie: et je pense que le "réciproquement" (commentaire -> cellule) ne fonctionnera pas avec cette méthode. Je n'ai pas trouvé sur le net d'exemples utilisant cette méthode appendTextPortion mais j'ai peut-être mal cherché.
N'importe comment l'utilisation du presse-purée et des "Transferable" me semble beaucoup plus facile d'emploi.
Ami calmant, J.P
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

Hello Jurassic Pork, je faisais des tests de mon côté et tu m'as devancé dans l'exposé des résultats :) merci beaucoup d'avoir passé du temps pour ces tests.

j'ai vu ( ici ) qu'il était possible de créer des modules de classe en basic, pouvant implémenter des interfaces : j'ai donc essayé de transposer l'exemple que tu avais donné en java pour mon besoin personnel.

j'ai créé un module de classe rtfTransferable implémentant l'interface XTransferable avec ses 3 méthodes et ai rajouté des propriétés me permettant de stocker le texte en rtf, et de quoi créer la dataFlavor adéquate (en basic, les paramètres ne sont pas acceptés dans le constructeur).

Code : Tout sélectionner

Option Compatible
Option ClassModule
Implements Com.Sun.Star.Datatransfer.XTransferable
Option Explicit

REM -----------------------------------------------------------------------------------------------------------------------
REM --- Internal Variables																									---
REM -----------------------------------------------------------------------------------------------------------------------

private mRichTextData as variant
private mDatatype as object
private mFlavorName as string

private Const RTF_TYPE = "text/richtext"
      
REM -----------------------------------------------------------------------------------------------------------------------
REM --- CONSTRUCTORS / DESTRUCTORS	 (n'acceptent pas de paramètres)					        														---
REM -----------------------------------------------------------------------------------------------------------------------
Private Sub Class_Initialize()
	mRichTextData=null
	mDatatype=nothing
	mFlavorName=""
End Sub		'	Constructor


Private Sub Class_Terminate()
	mRichTextData=null
	mDatatype=nothing
	mFlavorName=""
End Sub		'	Destructor

REM -----------------------------------------------------------------------------------------------------------------------
REM --- CLASS GET/LET/SET PROPERTIES					        														---
REM -----------------------------------------------------------------------------------------------------------------------

Public Property Get RichText as variant
	RichText = mRichTextData
End Property

Public Property Let RichText(ByVal vRTF As variant)
	mRichTextData = vRTF
End property

Public Property Get FlavorDataType as object
	FlavorDataType = mDatatype
End Property

Public Property Let FlavorDataType(ByVal oDatatype As object)
	mDatatype = oDatatype
End property

Public Property Get FlavorName as string
	FlavorName = mFlavorName
End Property

Public Property Let FlavorName(ByVal sName As string)
	mFlavorName = sName
End property

Public Property Get Dummy As Variant
	Dummy = Null
End Property

REM -----------------------------------------------------------------------------------------------------------------------
REM --- CLASS METHODS	 								        														---
REM -----------------------------------------------------------------------------------------------------------------------

Function getTransferData(oFlavor as com.sun.star.datatransfer.DataFlavor) as Variant
'Function getTransferData(aFlavor as com.sun.star.datatransfer.DataFlavor) as byte()
	print "getTransferData0"
	If (aFlavor.MimeType = RTF_TYPE) Then
 		getTransferData =  mRichTextData
 		print "getTransferData"
	End If
End Function
  
Function getTransferDataFlavors() as Variant
'Function getTransferDataFlavors() as com.sun.star.datatransfer.DataFlavor()
	dim oFlavor as new com.sun.star.datatransfer.DataFlavor
	oFlavor.MimeType = RTF_TYPE
   	oFlavor.HumanPresentableName = FlavorName
   	oFlavor.DataType=FlavorDataType
   	getTransferDataFlavors = Array(oFlavor)
   	print "getTransferDataFlavors"
End Function

Function isDataFlavorSupported(oFlavor as com.sun.star.datatransfer.DataFlavor) as boolean
	isDataFlavorSupported = (oFlavor.MimeType = RTF_TYPE)
	print "isDataFlavorSupported"
End Function
pour l'utilisation: je fais appel à getTransferable pour obtenir un object oTransferable à partir duquel je crée une instance de rtfTransferable que je passe à insertTransferable.

Code : Tout sélectionner


'===========================================================
dim oTransferable as object
oTransferable = ThisComponent.CurrentController.getTransferable()
...	
' créer un objet transferable dédié pour le rtf
dim richtextTransferable as object
richtextTransferable = getRichtextTransferable(otransferable)
...
ThisComponent.CurrentController.insertTransferable(richtextTransferable)
'============================================================

Function GetRichtextTransferable(oTransferable as object) as object
	dim richtextTransferable as object
	dim dataFlavors as object
	dim i as integer
	
	dataFlavors = oTransferable.getTransferDataFlavors()
	For i = 0 To UBound(dataFlavors)
    	If dataFlavors(i).MimeType = "text/richtext" Then Exit For
	Next i
	
	if i<=UBound(dataFlavors) Then
		set richtextTransferable = new rtfTransferable
		richtextTransferable.RichText=oTransferable.getTransferData(dataFlavors(i))
		richtextTransferable.FlavorDataType=dataFlavors(i).DataType
		richtextTransferable.FlavorName=dataFlavors(i).HumanPresentableName
	Else
		richtextTransferable = nothing
	End If
	
	'dataFlavors=richtextTransferable.getTransferDataFlavors()
	'dim data() as byte
	'data =richtextTransferable.getTransferData(dataFlavors(0))
	
	GetRichtextTransferable = richtextTransferable
End Function
le résultat ? l'instance de rtfTransferable semble correcte, il n'y a pas d'erreur mais les méthodes ne sont pas appelées lorsque j'effectue le insertTransferable , donc la copie n'est pas effectuée je ne sais trop pourquoi : as-tu une idée ?

il y a une chose qui me gêne dans rtfTransferable : j'ai dû me résoudre à utiliser le type variant comme valeur de retour des méthodes getTransferData et getTransferDataFlavors car je n'ai pas trouvé la syntaxe permettant de retourner un tableau (byte ou DataFlavor) : est-ce que ce type variant peut perturber le fonctionnement (problème de signature)?

tests_rtfTransferable.ods

pourrais-tu partager également le code pour tes tests 1 et 2 : j'aimerais comparer ta façon d'accéder au commentaire à la mienne qui ne me satisfait pas vraiment : ayant pour le moment une connaissance très réduite de l'api, j'ai d'abord transposé un fonctionnement manuel avec des raccourcis clavier mais c'est assez capricieux (il faut jouer de temporisation) ; j'ai ensuite remplacé au maximum ces raccourcis clavier par des commandes dispatch mais certaines ne fonctionnent pas (par exemple uno:ESCAPE)

eseb
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 7.3 portable
Windows 7 x64
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 639
Inscription : 09 août 2017 22:15

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par Jurassic Pork »

Hello,
eseb a écrit : 14 juil. 2022 09:59 pourrais-tu partager également le code pour tes tests 1 et 2 : j'aimerais comparer ta façon d'accéder au commentaire à la mienne qui ne me satisfait pas vraiment : ayant pour le moment une connaissance très réduite de l'api, j'ai d'abord transposé un fonctionnement manuel avec des raccourcis clavier mais c'est assez capricieux (il faut jouer de temporisation) ; j'ai ensuite remplacé au maximum ces raccourcis clavier par des commandes dispatch mais certaines ne fonctionnent pas (par exemple uno:ESCAPE)
Voici la procédure en python (facilement transposable en basic) que j'utilise pour copier le contenu d'un commentaire dans une cellule :

Code : Tout sélectionner

def copy_comment(cellule,destination):
    CTX = uno.getComponentContext()
    SM = CTX.getServiceManager()
    doc = XSCRIPTCONTEXT.getDocument()
    oSheet = doc.getSheets().getByName( "Feuille1" )
    doc.getCurrentController().select(oSheet.getCellRangeByName( cellule ))
    frame = doc.getCurrentController().getFrame()
    dispatch = SM.createInstance('com.sun.star.frame.DispatchHelper')
    #Edition commentaire + Selection avec OpenOffice
    #dispatch.executeDispatch(frame, ".uno:EditAnnotation", "", 0, ())
    #Edition commentaire + Selection avec LibreOffice
    dispatch.executeDispatch(frame, ".uno:InsertAnnotation", "", 0, ())
    dispatch.executeDispatch(frame, ".uno:SelectAll", "", 0, ())
    #transferable = copy_oneFormat("RICH TEXT")
    transferable = doc.CurrentController.getTransferable()
    dispatch.executeDispatch(frame,".uno:DrawEditNote", "", 0, ())  
    dispatch.executeDispatch(frame, ".uno:HideNote", "", 0, ())
    doc.getCurrentController().select(oSheet.getCellRangeByName(destination ))
    if transferable is not None:
        doc.getCurrentController().insertTransferable(transferable)
et la procédure pour copier le contenu d'une cellule dans son commentaire :

Code : Tout sélectionner

def modify_comment(cellule):
    CTX = uno.getComponentContext()
    SM = CTX.getServiceManager()
    doc = XSCRIPTCONTEXT.getDocument()
    oSheet = doc.getSheets().getByName( "Feuille1" )
    doc.getCurrentController().select(oSheet.getCellRangeByName( cellule ))
    frame = doc.getCurrentController().getFrame()
    dispatch = SM.createInstance('com.sun.star.frame.DispatchHelper')
    dispatch.executeDispatch(frame, ".uno:Copy", "", 0, ())
    #transferable = doc.CurrentController.getTransferable()
    #transferable = copy_oneFormat("RICH TEXT")
    #dispatch.executeDispatch(frame, ".uno:EditAnnotation", "", 0, ())
    dispatch.executeDispatch(frame, ".uno:InsertAnnotation", "", 0, ())
    dispatch.executeDispatch(frame, ".uno:SelectAll", "", 0, ())
    #if transferable is not None:
        #doc.getCurrentController().insertTransferable(transferable)
    p=PropertyValue()
    p.Name = 'Format'
    p.Value = 10
    args = (p,)
    dispatch.executeDispatch(frame,".uno:PasteSpecial", "", 0, args)
    dispatch.executeDispatch(frame,".uno:DrawEditNote", "", 0, ())  
    dispatch.executeDispatch(frame, ".uno:HideNote", "", 0, ())
A noter que la commande dispatch d'insertion de commentaire est différente entre L.O et O.O.

Je ne me penche pas sur ton problème de ta classe en basic car finalement cela ne servira pas à grand chose car le problème n'est pas lié au contenu
du Transferable mais à celui du bug d'insertion d'un Transferable contenant un RTF dans un commentaire.

Ami calmant, J.P
Dernière modification par Jurassic Pork le 14 juil. 2022 11:50, modifié 2 fois.
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

salut Dude,
merci de me signaler une autre piste...

j'ai vu en fouinant dans le forum que tu affectionnais le qualificatif de problème XY : cela t'est plus facile de le déceler dans ta position d'expert, que pour le débutant que je suis (rassure-moi, tu es aussi passé par ce stade? :wink: )

pour le pourquoi du "presse-purée", j'ai donné la réponse dans mon message précédent à Jurassic Pork : lorsque l'on connait mal l'API, on est tenté de singer le comportement manuel, et en manuel pour copier le commentaire dans une cellule ou l'inverse, on utilise forcément Ctrl-C Ctrl-V ...

d'ailleurs, si tu peux m'éclairer sur la raison du non-fonctionnement de ma classe rtfTransferable, cela pourra toujours être utile (à moi comme à d'autres dans d'autres contextes)

je vais étudier de plus près l'utilisation de AppendTextPortion...

eseb
LibreOffice 7.3 portable
Windows 7 x64
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

merci Jurassic Pork pour ces compléments d'information qui m'ont permis de découvrir la commande uno:HideNote et remplacer ainsi uno:ESCAPE qui ne fonctionnait pas. Pour le reste, ma seconde mouture (en pièce jointe du précédent message) ressemble fortement à la tienne.

2 précisions:
  • la copie de cellule vers commentaire concerne deux cellules différentes : le commentaire initialement associé à la cellule B1 est sauvegargé en A1, puis au besoin restauré en B1 à partir de A1.
  • le commentaire pouvant être multilignes, il faut lors de sa sauvegarde entrer en mode édition pour la cellule réceptrice avant de procéder au coller ; j'utilise pour ce faire la commande uno:SetInputMode mais je n'ai pas trouvé comment valider : connaitrais-tu une commande dispatch équivalente à la touche Return de validation (l'enregistreur de macros ne mémorise pas l'action de la touche Return)?
je vois que le basic n'est pas ta tasse de thé et comprends que tu rechignes à t'y plonger pour ma classe rtfTransferable (remarque que t'y pencher dessus ne t'exposerait qu'à tomber ... sur un bug :lol: )

plaisanterie à part, je fais appel aux autres bonnes volontés car j'aimerais comprendre le pourquoi du non appel des méthodes par insertTransferable (dans les deux cas de figure, transfert de cellule vers le commentaire de la cellule adjacente, ou inversement transfert du commentaire existant vers la cellule de sauvegarde) : mauvaise implémentation, bug ou limitation du basic?
LibreOffice 7.3 portable
Windows 7 x64
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

j'ai réussi à me débrouiller avec les méthodes insertTextPortion et AppendTextPortion ! :D

cela marche dans les 2 sens,sans recourir aux commandes dispatch : il faut utiliser 2 curseurs de texte, l'un en lecture pour balayer la source et sauvegarder le format, l'autre pour écrire dans la destination avec le texte et le format sauvegardé. J'avais déjà étudié un peu cette notion de curseur avec le bouquin de BMarcelly, cela m'a bien servi.

dans mon cas, le traitement doit se faire caractère par caractère et non mot à mot, car le formatage peut varier d'un caractère à l'autre au sein d'un même mot (la résistance des matériaux a des notations un peu alambiquées) ; de ce fait, le traitement est assez lent pour la sauvegarde dans la cellule, même en désactivant la mise à jour de l'affichage (apparemment, cette désactivation ne touche pas la zone d'édition des formules en haut de l'écran donc l'intérêt est moindre).

pour la sauvegarde d'un commentaire, j'ai tâtonné pour trouver à quel niveau utiliser insert/appendTextPortion sur une cellule : alors que c'est possible sur la propriété Text d'une annotation, il faut pour une cellule l'appliquer à Start.Text : j'avoue que cette notion de Start et End d'une cellule (pouvant se confondre) me parait pour l'instant un peu obscure : quel en est l'intérêt ?

Code : Tout sélectionner

sub SauveComment
	dim oDispatcher as object
	dim oFrame, oSheet as object
	dim oSourceCell,  oTargetCell as object
	dim oCursorSourceCell, oCursorTargetCell as object
	dim oAnnotation as object
	
	'dim aCharProps(8) As New com.sun.star.beans.PropertyValue
	dim oCharProps as object
	dim bStart as boolean
	
	'call initializeMRI
	
	ThisComponent.lockControllers()
	
	oDispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
	oFrame = ThisComponent.CurrentController.Frame
	oSheet = ThisComponent.getSheets().getByIndex(0)
	
	' curseur de texte pour balayage du contenu du commentaire
	oSourceCell = oSheet.getCellRangeByName("B9")
	oCursorSourceCell = oSourceCell.Annotation.Text.createTextCursor()
	oCursorSourceCell.gotoStart(false)
	
	' se positionner sur la cellule cible et supprimer son contenu éventuel
	oTargetCell = oSheet.getCellRangeByName("C9")
	ThisComponent.CurrentController.select(oTargetCell)
	oTargetCell.String=""

	' curseur de texte pour écriture dans la cellule de sauvegarde
	oCursorTargetCell = oTargetCell.Text.createTextCursor()
	oCursorTargetCell.gotoStart(false)
	
	bStart=true
	' balayage du curseur caractère par caractère car le format peut différer de l'un à l'autre
	Do While oCursorSourceCell.goRight(1,true)
		'print oCursorSourceCell.String

		' sauvegarde du format			
		oCharProps = getCharProperties(oCursorSourceCell)
		
		' insertion puis ajout du caractère dans la cellule
		If bStart Then
			oTargetCell.Start.Text.InsertTextPortion(oCursorSourceCell.String, oCharProps, oCursorTargetCell)
			bStart=false
		End IF	
		'Else
			oTargetCell.Start.Text.AppendTextPortion(oCursorSourceCell.String, oCharProps)
		'End If
		oCursorSourceCell.CollapseToEnd
	Loop
	ThisComponent.unLockControllers()
End Sub
pour la restauration d'un commentaire, il faut d'abord créer un commentaire avec Annotations.InsertNew non vide pour pouvoir ensuite créer le curseur de texte dans lequel écrire.

Code : Tout sélectionner

Sub RestaureComment
	dim oDispatcher as object
	dim oFrame, oSheet as object
	dim oSourceCell,  oTargetCell as object
	dim oCursorSourceCell, oCursorTargetCell as object
	dim oAnnotation as object
	
	'dim oCharProps(8) As New com.sun.star.beans.PropertyValue
	dim oCharProps as object
	dim bStart as boolean
	
	'call initializeMRI
	
	oDispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
	oFrame = ThisComponent.CurrentController.Frame
	oSheet = ThisComponent.getSheets().getByIndex(0)
	
	' curseur de texte pour balayage du contenu de la cellule de sauvegarde
	oSourceCell = oSheet.getCellRangeByName("A12")
	oCursorSourceCell = oSourceCell.Text.createTextCursor()
	oCursorSourceCell.gotoStart(false)
	
	' se positionner sur la cellule cible et supprimer le commentaire existant éventuel
	oTargetCell = oSheet.getCellRangeByName("B12")
	ThisComponent.CurrentController.select(oTargetCell)
	oTargetCell.clearContents( com.sun.star.sheet.CellFlags.ANNOTATION )

	' insérer un commentaire (non vide)
	'oDispatcher.executeDispatch(oFrame, ".uno:InsertAnnotation", "", 0, Array())
	oSheet.Annotations.insertNew(oTargetCell.CellAddress," ")

	' curseur de texte pour écriture dans le commentaire
	oAnnotation = oTargetCell.Annotation
	oCursorTargetCell = oAnnotation.Text.createTextCursor()
	
	' supprimer le 1er caractère parasite
	oCursorTargetCell.gotoStart(true)
	oCursorTargetCell.String=""
	oCursorTargetCell.collapseToStart

	bStart=true
	' balayage du curseur caractère par caractère car le format peut différer de l'un à l'autre
	Do While oCursorSourceCell.goRight(1,true)
		'print oCursorSourceCell.String
		
		oCharProps = getCharProperties(oCursorSourceCell)
		
		' insertion puis ajout du caractère dans le commentaire
		If bStart Then
			oAnnotation.Text.InsertTextPortion(oCursorSourceCell.String, oCharProps, oCursorTargetCell)	
			bStart=false
		End If
		'Else
			oAnnotation.Text.AppendTextPortion(oCursorSourceCell.String, oCharProps)
		'End If
		oCursorSourceCell.CollapseToEnd
	Loop
	
	'print "longueur du texte du commentaire=" & cstr(len(oAnnotation.String))
	
	' rafraichir l'affichage du commentaire puis le masquer
	'oDispatcher.executeDispatch(oFrame, ".uno:DrawEditNote", "", 0, Array())
	'oDispatcher.executeDispatch(oFrame, ".uno:HideNote", "", 0, Array())
	
End Sub
sauvegarde du format

Code : Tout sélectionner

Function getCharProperties (oCursor as object) as com.sun.star.beans.PropertyValue

		dim aCharProps(8) As New com.sun.star.beans.PropertyValue
		
		' sauvegarde du format	
		aCharProps(0).Name = "CharFontCharSet"
		aCharProps(0).Value = oCursor.CharFontCharSet
		aCharProps(1).Name = "CharFontName"
		aCharProps(1).Value = oCursor.CharFontName
		aCharProps(2).Name = "CharColor"
		aCharProps(2).Value = oCursor.CharColor
		aCharProps(3).Name = "CharHeight"
		aCharProps(3).Value = oCursor.CharHeight
		aCharProps(4).Name = "CharUnderline"
		aCharProps(4).Value = oCursor.CharUnderline
		aCharProps(5).Name = "CharWeight"
		aCharProps(5).Value = oCursor.CharWeight
		aCharProps(6).Name = "CharPosture"
		aCharProps(6).Value = oCursor.CharPosture
		aCharProps(7).Name = "CharEscapement"
		aCharProps(7).Value = oCursor.CharEscapement
		aCharProps(8).Name = "CharEscapementHeight"
		aCharProps(8).Value = oCursor.CharEscapementHeight
		'aCharProps(9).Name = "CharStrikeOut"
		'aCharProps(9).Value = oCursor.CharStrikeOut ' non reconnue par AppendTextPortion ???
		
		getCharProperties=aCharProps
End Function
j'ai aussi été confronté à des bugs (comme presque à chaque fois que je découvre une nouvelle notion) :

le premier concerne la méthode insertTextPortion qui n'écrit rien (bug référencé ici) ; elle permet juste d'initialiser l'écriture ;

le second concerne la méthode appendTextPortion qui ne reconnait pas la propriété CharStrikeOut, pourtant disponible sur le curseur : il faut que je creuse un peu plus la question...

tests_rtfTransferable.ods

il ne reste plus qu'à élucider la raison du non fonctionnement de la classe rtfTransferable ... :fou:
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 7.3 portable
Windows 7 x64
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 639
Inscription : 09 août 2017 22:15

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par Jurassic Pork »

Hello,
eseb a écrit : 14 juil. 2022 20:52 le second concerne la méthode appendTextPortion qui ne reconnait pas la propriété CharStrikeOut, pourtant disponible sur le curseur
La propriété est CharStrikeout pas CharStrikeOut.
eseb a écrit : 14 juil. 2022 20:52 dans mon cas, le traitement doit se faire caractère par caractère et non mot à mot, car le formatage peut varier d'un caractère à l'autre au sein d'un même mot.
On peut aussi utiliser la copie par portions de texte.
Voici un exemple d'une autre méthode en basic qui au lieu de copier les caractères un par un les copie par portions (parties ayant le même format) et aussi avec tous les attributs de type Char*.

Code : Tout sélectionner

Sub TestCopieTexte() 'Commentaire B9 -> Cellule H9
Dim oDoc As Object , Feuille As Object , oCtrl as Object 
Dim Cellule As Object, oText As Object
Dim EnumPara As Object, EnumPortions As Object
Dim TextElement As Object, oTextRange As Object
Dim TextPortion As Object, oProperties As Object
Dim oCursorTargetCell As Object, FirstPara as Boolean
oDoc = ThisComponent 
oCtrl = ThisComponent.CurrentController
Feuille = oDoc.getSheets.getByName("Feuille1") 
Cellule = Feuille.getCellRangeByName("B9") 
oText =  Cellule.Annotation.Text
EnumPara = oText.createEnumeration
Cellule = Feuille.getCellRangeByName("H9") 
oText =  Cellule.Start.Text
oCursorTargetCell = oText.createTextCursor()
oCursorTargetCell.gotoStart(false)
' loop over all paragraphs
FirstPara = True
While EnumPara.hasMoreElements
  TextElement = EnumPara.nextElement
  If TextElement.supportsService("com.sun.star.text.Paragraph") Then
    if FirstPara then
       FirstPara = False
    Else
        oCursorTargetCell.gotoEnd(false)
        oText.insertControlCharacter(oCursorTargetCell, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)
    End If
    EnumPortions = TextElement.createEnumeration
    ' loop over all sub-paragraphs 
    While EnumPortions.hasMoreElements
      TextPortion = EnumPortions.nextElement
      oProperties = fnDirectProperties(TextPortion)
      oText.AppendTextPortion(TextPortion.String,oProperties)
      'MsgBox "'" & TextPortion.String & "'"
    Wend
  End If
Wend
End Sub

function fnNewProperty(sName, optional vValue)
Dim aProperty as Object
aProperty = createUnoStruct("com.sun.star.beans.PropertyValue")
aProperty.Name = sName
if not isMissing(vValue) then
        aProperty.Value = vValue
end if
fnNewProperty = aProperty
end function

sub subAddProperty(mProperties, sName, optional vValue)
Dim nNext as Integer
nNext = uBound(mProperties) + 1
redim preserve mProperties(nNext)
if isMissing(vValue) then
        mProperties(nNext) = fnNewProperty(sName)
else
        mProperties(nNext) = fnNewProperty(sName, vValue)
end if
end sub

sub subAddThisProperty(mProperties, mProperty)
Dim nNext as Integer
nNext = uBound(mProperties) + 1
redim preserve mProperties(nNext)
set mProperties(nNext) = mProperty
end sub

function fnDirectProperties(oTextRange as Object)
dim oProperties()
dim nProperties As Integer, i as Integer
dim sName as String
dim nTypeClass 
'Returns an array of property beans of directly applied properties
oProperties = oTextRange.getPropertySetInfo.getProperties
nProperties = uBound(oProperties)
dim mDirectProperties()
for i = 0 to nProperties
        sName = oProperties(i).name
        if oTextRange.getPropertyState(sName) <> com.sun.star.beans.PropertyState.DEFAULT_VALUE and _
         (Left(sName,4) = "Char")  and _
         ((oProperties(i).attributes and com.sun.star.beans.PropertyAttribute.READONLY) = 0) then 
                nTypeClass = oProperties(i).type.typeClass
                subAddProperty( mDirectProperties(),sName, oTextRange.getPropertyValue(sName))
        end if
next
fnDirectProperties = mDirectProperties()
end function

eseb a écrit : 14 juil. 2022 20:52 il ne reste plus qu'à élucider la raison du non fonctionnement de la classe rtfTransferable
Si pendant l'exécution de ton code VBA on compare la variable oTransferable à la variable richttextfTransferable :
rtftransferable.PNG
on constate que la structure n'est pas du tout la même.
En python la structure est la même.
Si on met le contenu du richttextfTransferable dans le presse-papier avec le code suivant on constate qu'il n'y a rien :

Code : Tout sélectionner

    Dim oClip As Object
    oClip = createUnoService("com.sun.star.datatransfer.clipboard.SystemClipboard")
    oClip.setContents(richttextfTransferable,null)

Je pense que le problème vient du fait qu'en Basic l'héritage entre classes d'objets n'est pas possible ce qui est indiqué ici :
Basic supporte également le verbe « Implements » comme en VB6. Son usage me paraît cependant peu utile.
VB6 accepte également l'usage dans un module de classe du mot-clé « This » pour désigner l'instance courante en exécution. De plus il permet le passage de l'objet traité comme argument d'une fonction externe au module. Ceci n'est pas possible en Basic, à ma connaissance.
L'héritage entre classes d'objets n'est pas possible. Le verbe « Inherits » n'est implémenté d'ailleurs en VB que dans les versions postérieures à VB6.
Ami calmant, J.P
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

Hello Jurassic Pork,

de retour après une petite absence ...

bien vu pour CharStrikeout, je n'avais pas décelé ce problème de casse. :super:

j'avais bien pensé en codant mes tests à une notion de zone de texte homogène dans son formatage qui m'aurait évité de balayer caractère par caractère mais je ne voyais pas comment les obtenir : le bouquin de BMarcelly n'en parle pas et je n'aurais pas pensé à balayer des paragraphes dans une cellule Calc, donc merci beaucoup pour cette découverte. J'ai vu par la suite que c'était abordé dans le guide Basic d'OpenOffice et dans le bouquin d'A.Pitonyak.

j'ai étudié également la manière de mémoriser les propriétés de formatage : c'est plus générique et moins fastidieux que de spécifier chacune d'entre elles. J'ai essayé avec les propriétés de paragraphe, et là cela se complique un peu car il y des propriétés de type structure ou array que je ne sais pas comment traiter de façon générique (je suppose qu'il faudrait utiliser la reflection ?).

Sinon, je ne comprends pas pourquoi les API ne fournissent pas le moyen de "cibler" la portée des propriétés (propriétés de caractère, de paragraphe ...) et que l'on en soit réduit à faire de l'analyse de chaine sur les noms de propriétés.

puisque ce sont les services CharacterProperties et ParagraphProperties qui déterminent la présence de ces propriétés, j'avais pensé instancier le service par unoCreateService, puis via l'interface XPropertySet balayer les propriétés pour obtenir une liste plus ciblée mais createUnoService me renvoie un type différent de celui attendu :fou: :

pour com.sun.star.style.ParagraphProperties, j'obtiens un objet de type com.sun.star.comp.chart2.Title supportant les services:
  • com.sun.star.beans.PropertySet
  • com.sun.star.chart2.Title
  • com.sun.star.layout.LayoutElement
  • com.sun.star.style.ParagraphProperties
pour com.sun.star.style.CharacterProperties, j'obtiens un objet de type com.sun.star.comp.chart2.RegressionEquation supportant les services:
  • com.sun.star.beans.PropertySet
  • com.sun.star.chart2.RegressionEquation
  • com.sun.star.drawing.FillProperties
  • com.sun.star.drawing.LineProperties
  • com.sun.star.style.CharacterProperties
comment expliquer cela? j'ai vu qu"il y avait une autre possibilité d'instancier un service avec des arguments via getProcessServiceManager().createInstanceWithArguments() ? serait-ce la solution ?

second écueil, j'ai essayé de transmettre aussi des propriétés de paragraphe (par exemple le cadrage) : cela fonctionne dans le sens cellule vers commentaire, mais pas dans l'autre : le formatage au niveau paragraphe dans une cellule semble ignoré par Calc, il faut passer au niveau cellule. Je conçois qu'une cellule ne soit pas destinée à du formatage de paragraphe mais le problème c'est que l'on aboutit à ce constat après pas mal de recherches et que ce n'est documenté nulle part (en tout cas, je n'ai rien vu à ce sujet)

sens cellule => commentaire : on peut formater individuellement le cadrage de chaque paragraphe (cependant, il faut afficher le commentaire pour le constater, s'il est masqué et que l'on passe la souris sur l'ancre rouge pour le visualiser, le formatage n'est pas correctement restitué)

Code : Tout sélectionner

sub JustifyComment
	dim oCell,oText, oCursorCell,oParag,oEnum as object
	dim i as integer
	
	oCell = ThisComponent.getSheets().getByIndex(0).getCellRangeByName("B25")
	oText = oCell.Annotation.Text
	oCursorCell = oText.createTextCursor()
	oCursorCell.gotoStart(false)

	i=0
	oEnum = oText.createEnumeration
	While oEnum.hasMoreElements
		oParag=oEnum.nextElement
		i=i+1
		oCursorCell.paraAdjust=i	' cadrage individualisé
		
		oCursorCell.goRight(len(oParag.String), true)
		if i=1 then
			oCursorCell.CharColor=13181214
		elseif i=2 then
			oCursorCell.CharColor=7512015
		else
			oCursorCell.CharColor=1475155
		end if
		oCursorCell.goRight(1,false)
		
	Wend
end sub
sens commentaire => cellule : le cadrage est ignoré au niveau paragraphe (en mode manuel, le formatage est disponible dans la barre de bouton au niveau paragraphe mais une action au niveau d'un paragraphe est de suite appliquée aux autres, donc au final on est aussi au niveau cellule)

Code : Tout sélectionner

sub JustifyCell
	dim oCell,oText, oCursorCell,oParag,oEnum as object
	dim i as integer
	
	oCell = ThisComponent.getSheets().getByIndex(0).getCellRangeByName("A25")
	oText = oCell.Start.Text

	oCursorCell = oText.createTextCursor()
	oCursorCell.gotoStart(false)

	i=0
	oEnum = oText.createEnumeration
	While oEnum.hasMoreElements
		oParag=oEnum.nextElement
		i=i+1

		oCursorCell.paraAdjust=i  ' ne fonctionne pas sans sélection du parag
		
		oCursorCell.goRight(len(oParag.String), true)
		
		if i=1 then
			oCursorCell.CharColor=13181214
		elseif i=2 then
			oCursorCell.CharColor=7512015
		else
			oCursorCell.CharColor=1475155
		end if
		oCursorCell.paraAdjust=i  ' ne fonctionne pas avec sélection du parag
		
		oCursorCell.goRight(1,false)		
	Wend
	
	oCursorCell.GotoStart(false)
	oCursorCell.GotoEnd(true)
	oCursorCell.paraAdjust=3	' ne fonctionne pas avec sélection de la la totalité du texte
	
	oCell.paraAdjust=3 ' OK
end sub
je regarde plus en détail pour la classe rtfTransferable : tu as probablement raison sur la cause, mais je trouve la documentation lacunaire et trompeuse à ce sujet, j'y reviendrai...

eseb
LibreOffice 7.3 portable
Windows 7 x64
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 639
Inscription : 09 août 2017 22:15

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par Jurassic Pork »

Hello,
une autre piste :
dans le code que j'ai mis il y a le test de com.sun.star.beans.PropertyState.DEFAULT_VALUE

Code : Tout sélectionner

if oTextRange.getPropertyState(sName) <> com.sun.star.beans.PropertyState.DEFAULT_VALUE and _
com.sun.star.beans.PropertyState.DEFAULT_VALUE : The value of the property is available from a master (e.g., template).
avec l'utilisation d'un modèle contenant les propriétés par défaut cela est peut-être utilisable.
Ami calmant, J.P
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

Hello,
si j'ai bien compris ton idée, ce serait d'instancier un style pour balayer ses propriétés ?
malheureusement, lorsque l'on instancie un style com.sun.star.style.CharacterStyle ou com.sun.star.style.ParagraphStyle sous Calc, on obtient un objet null...
cela fonctionne sous Writer, mais le style de paragraphe contient aussi les propriétés de caractère et d'autres...
caramba : encore raté :fou: !
LibreOffice 7.3 portable
Windows 7 x64
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

Hello Jurassic Pork,

je reviens sur la classe rtfTransferable ; effectivement la structure est assez différente de l'objet oTransferable retourné par getTransferable.

pour l'implémenter, je m'étais fié à la documentation OpenOffice, car plus riche que celle de LibreOffice (références croisées, liens vers le guide de développement ...) : l'objet retourné par getTransferable et transmis à insertTransferable est censé être un objet de type XTransferable. Donc en implémentant cette interface dans rtfTransferable je pensais satisfaire cette obligation.

Le hic, c'est que l'objet retourné par getTransferable n'est pas un objet XTransferable, en tout cas pas seulement : il est plus complexe car l'examen montre qu'il implémente d'autres interfaces non mentionnées dans la documentation, c'est en ce sens qu'elle est à mon sens lacunaire et trompeuse : quelle en est la raison ? c'est une convention pour alléger qui ne déclare que l'interface la plus caractéristique ? mais je ne vois pas ce qui empêcherait de le spécifier dans le détail de la page)
  • XtypeProvider : donne apparemment les liens d'héritage mémorisés dans la propriété types()
  • XWeak (pour éviter les références circulaires d'après ce que j'ai lu)
  • XInterface : qui semble l'interface de base dont héritent toutes les autres (elle est mentionnée dans la documentation LibreOffice sur XTransferable (moralité : il faut lire les 2 sources pour avoir les informations)
pour cette dernière, la page OpenOffice précise cette obligation mais bizarrement mentionne StarBasic dans les langages pouvant la prendre en charge :
Deriving from this interface is mandatory for all UNO interfaces.

Each language binding (Java, C++, StarBasic, Python, ... ) may provide a different mapping of this interface, please look into the language dependent documention.
j'ai aussi trouvé ce tableau qui indique les principales interfaces à prendre en compte : seule XInterface semble obligatoire, mais subtile nuance XtypeProvider et XWeak devraient être implémentées.
UNO_core interfaces.jpg
j'ai vu ici qu'en Java le runtime dispensait de coder les méthodes de XInterface ; j'ignore s'il en est de même pour Basic ;


ici
il est tout de même précisé :
In Apache OpenOffice Basic, querying for interfaces is not necessary; the Basic runtime engine takes care of that internally.
j'ai essayé d'ajouter l'implémentation de XInterface dans ma classe rtfTransferable avec des méthodes basiques mais cela ne change rien, elle ne fonctionne toujours pas. (existe t'il une syntaxe en Basic permettant d'effectuer un cast d'un type d'objet UNO en un autre, je n'ai pas trouvé?)

Code : Tout sélectionner

class Transferable(unohelper.Base, XTransferable)
je ne connais pas du tout python mais je suppose que par cette déclaration tu hérites à la fois de XTransferable (et donc de XInterface) et de unohelper.Base qui doit implémenter les autres comme indiqué dans le tableau pour Java ou C++, donc tu obtiens au final un objet de structure similaire à celui retourné par getTransferable.

eseb
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 7.3 portable
Windows 7 x64
eseb
NOOuvel adepte
NOOuvel adepte
Messages : 13
Inscription : 01 juil. 2022 20:24

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par eseb »

j'ai relu le fil et un certain nombre de points sont restés en suspens : si quelqu'un a une réponse et veut apporter sa pierre à l'édifice ...

est-il possible en Basic de faire un cast d'un type UNO dans un autre ? si oui, avec quelle syntaxe ?

comment instancier un service com.sun.star.style.ParagraphProperties ou com.sun.star.style.CharacterProperties (createUnoService renvoie un type différent de celui attendu) ?

existe t-il un moyen générique de lister les propriétés de caractère/paragraphe autrement que par analyse de leur nom (premiers caractères = "char" ou "Para")

existe t-il une commande dispatch équivalente à la touche Return de validation (l'enregistreur de macros ne mémorise pas l'action de la touche Return) ?

quel est la raison d'être des propriétés "Start" et "End" d'un TextRange ?

eseb
LibreOffice 7.3 portable
Windows 7 x64
Avatar de l’utilisateur
Bidouille
RespOOnsable forum
RespOOnsable forum
Messages : 12727
Inscription : 08 nov. 2005 16:23
Localisation : Brest, France

Re: [Basic] comment spécifier une dataFlavor pour insertTransferable

Message par Bidouille »

eseb a écrit : 27 juil. 2022 10:05 j'ai relu le fil et un certain nombre de points sont restés en suspens
Ces points devront faire l'objet d'autant de fils de discussion et avec un titre en rapport avec la problématique exposée.
Ce n'est pas pour vous mais pour tous ceux effectuant des recherches dans ce forum.

Sujet verrouillé
Si la modération vous adresse un message, il est inutile d'y répondre.
Cela nous fait perdre encore plus de temps de vous lire.
Merci de respecter les règles de ce forum à l'avenir.

La communauté OpenOffice est fragile, participez au projet.