[Calc] Gérer un menu contextuel (clic droit)

Vos meilleures macros et portions de code sont publiées dans cette section.
Aucun support sur une question de programmation ici !

Modérateur : Vilains modOOs

Règles du forum
Aucune question dans cette section !
Celle-ci rassemble les meilleures macros et portions de code. Vous pouvez en revanche commenter ou argumenter le code exposé. Vous pouvez même remercier l'auteur (cela fait toujours plaisir) en indiquant par exemple dans quel cadre ou contexte vous en avez eu l'utilité.
Si vous avez à poster quelque chose, faites-le depuis la section Macros et API et demandez à un modérateur de l'y déplacer.
Pierre-Yves Samyn
Grand Maître de l'OOffice
Grand Maître de l'OOffice
Messages : 11276
Inscription : 02 mai 2006 08:42

[Calc] Gérer un menu contextuel (clic droit)

Message par Pierre-Yves Samyn »

Le but est d'aider la saisie en permettant d'obtenir, par un clic droit, une liste des saisies autorisées. En l'occurrence, il s'agit d'un tableau de "présences" : si la personne est présente on veut saisir un X, un A si elle est absente, un E si elle est excusée et rien... dans les autres cas (peut servir à effacer une saisie précédente).
Capture-1.png
La documentation nous donne :
http://wiki.services.openoffice.org/wik ... terception
http://wiki.services.openoffice.org/wik ... text_Menus

L'essentiel des réponses nous est donc donné... mais la traduction en OooBasic n'est pas si évidente (gestion des PropertySet...).

Heureusement, sachant désormais que chercher, ce fil providentiel de Paolo Mantovani apporte les réponses manquantes :
http://markmail.org/message/xc2he7lu252sdvap

Voici donc le code réalisant l'exemple ci-dessus : le menu contextuel n'est actif que pour la plage C2:E8 de la feuille (il est utile de disposer des menus par défaut pour les autres cellules, objets, etc.).

Je n'utilise pas toutes les possibilités (séparateur par exemple mais j'ai pu vérifier que seul l'espace fonctionne cf. les commentaires du code).

Par rapport à l'exemple initial, sont rajoutés :
  • le test de la sélection (feuille, plage, cellule unique)
  • le lancement de macros "locales" (du document) lors d'un choix dans le menu

Code : Tout sélectionner

Option Explicit

Global oDocView As Object
Global oContextMenuInterceptor As Object

Global oStore As Object
Global oPropSetRegistry As Object

Const MNU_PREFIX = "pmxMenu_"
Global PysRange as object

'_______________________________________________________________________________
Sub registerContextMenuInterceptor
   
   InitMenuFactory

   oDocView = ThisComponent.CurrentController
   oContextMenuInterceptor = _
   CreateUnoListener("ThisDocument_", "com.sun.star.ui.XContextMenuInterceptor")
   
   oDocView.registerContextMenuInterceptor(oContextMenuInterceptor)
   PysRange = ThisComponent.sheets.getByName("2010").getCellRangeByName("C2:E8")
End Sub


'_______________________________________________________________________________
Sub releaseContextMenuInterceptor

   On Error Resume Next
   oDocView.releaseContextMenuInterceptor(oContextMenuInterceptor)
   
   TerminateMenuFactory
   
End Sub


'_______________________________________________________________________________
Function ThisDocument_notifyContextMenuExecute(ContextMenuExecuteEvent As Object) As Variant
Dim oSrcWin As Object
Dim oExePoint As Object
Dim oATContainer As Object
Dim oSelection As Object

Dim oMenuItem As Object
Dim I As Integer

Dim PysEnCours as object

With ContextMenuExecuteEvent

   'contains the window where the context
   'menu has been requested
   oSrcWin = .SourceWindow

   'contains the position the context menu
   'will be executed at (css.awt.Point)
   oExePoint = .ExecutePosition
   
   'enables the access to the menu content.
   'The implementing object has to support the
   'service ActionTriggerContainer
   oATContainer = .ActionTriggerContainer
   
   'provides the current selection
   'inside the source window
   oSelection = .Selection             
End With

PysEnCours = thiscomponent.currentselection	

' Si la sélection courante est une cellule de la plage concernée
if PysEnCours.supportsService("com.sun.star.sheet.SheetCell") and _
   PysRange.queryIntersection(PysEnCours.getRangeAddress()).getCount >= 1 then
	   'remove all menu entries:
	   For I = oATContainer.Count - 1 To 0 Step -1 
	      oATContainer.removeByIndex(I)
	   Next I
	   
	   'add some context menu entry
	   'vnd.sun.star.script:Standard.Module1.Test?language=Basic&location=document"
	
	   oMenuItem = GetSimpleMenuItem("Entry1", "Présent", "vnd.sun.star.script:Standard.Module1.PysPresent?language=Basic&location=document")
	   oATContainer.insertByIndex(0, oMenuItem)
	   
	   oMenuItem = GetSimpleMenuItem("Entry2", "Absent", "vnd.sun.star.script:Standard.Module1.PysAbsent?language=Basic&location=document")
	   oATContainer.insertByIndex(1, oMenuItem)
	
	   oMenuItem = GetSimpleMenuItem("Entry3", "Excusé", "vnd.sun.star.script:Standard.Module1.PysExcuse?language=Basic&location=document")
	   oATContainer.insertByIndex(2, oMenuItem)
	   
	   oMenuItem = GetSimpleMenuItem("Entry4", "NR", "vnd.sun.star.script:Standard.Module1.PysNR?language=Basic&location=document")
	   oATContainer.insertByIndex(3, oMenuItem)
	
	
	' POSSIBLE RESULTS FOR THIS FUNCTION
	' This function must result one of the following values:
	
	' com.sun.star.ui.ContextMenuInterceptorAction.IGNORED
	'   the XContextMenuInterceptor has ignored the call.
	'   The next registered XContextMenuInterceptor should be notified.
	
	' com.sun.star.ui.ContextMenuInterceptorAction.CANCELLED
	'   the context menu must not be executed.
	'   The next registered XContextMenuInterceptor should not be notified.
	
	' com.sun.star.ui.ContextMenuInterceptorAction.EXECUTE_MODIFIED
	'   the menu has been modified and should be executed
	'   without notifying the next registered XContextMenuInterceptor.
	
	' com.sun.star.ui.ContextMenuInterceptorAction.CONTINUE_MODIFIED
	'   the menu has been modified and the next registered
	'   XContextMenuInterceptor should be notified.
	
	   ThisDocument_notifyContextMenuExecute = _
	      com.sun.star.ui.ContextMenuInterceptorAction.CONTINUE_MODIFIED
else
   ThisDocument_notifyContextMenuExecute = _
	com.sun.star.ui.ContextMenuInterceptorAction.IGNORED
end if

End Function


'_______________________________________________________________________________
'   MENU FACTORY ROUTINES
'_______________________________________________________________________________
Sub InitMenuFactory()

   oStore = CreateUnoService("com.sun.star.ucb.Store")
   oPropSetRegistry = oStore.createPropertySetRegistry("")

End Sub


'_______________________________________________________________________________
Sub TerminateMenuFactory()
Dim mNames()
Dim sName As String
Dim I As Integer

   mNames() = oPropSetRegistry.getElementNames
   
   For I = LBound(mNames()) To UBound(mNames())
      sName = mNames(I)
      
      If Left(sName, Len(MNU_PREFIX)) = MNU_PREFIX Then
         oPropSetRegistry.removePropertySet ( sName )
      End If
   Next I
   
   oPropSetRegistry.dispose
   oStore.dispose
   
End Sub

'_______________________________________________________________________________
' Sorry: menu icon and sub-menues not supported
Function GetSimpleMenuItem( sName As String, sText As String, _
sCommandUrl As String, Optional sHelpUrl As String ) As Object

Dim oPropSet As Object
Dim sInternalName As String

   sInternalName = MNU_PREFIX & sName
   If oPropSetRegistry.hasByName(sInternalName) Then
      oPropSetRegistry.removePropertySet(sInternalName)
   End If
      
   oPropSet = oPropSetRegistry.openPropertySet(sInternalName, True)

   oPropSet.addProperty("Text", 0, sText)
   oPropSet.addProperty("CommandURL", 0, sCommandUrl)

   If Not IsMissing(sHelpUrl) Then
      oPropSet.addProperty("HelpURL", 0, sHelpUrl)
   End If
      
   GetSimpleMenuItem = oPropSet
   
End Function


'_______________________________________________________________________________
Function GetMenuSeparator( sName As String ) As Object

Dim oPropSet As Object
Dim sInternalName As String
Dim iSeparatorType As Integer

   sInternalName = MNU_PREFIX & sName
   If oPropSetRegistry.hasByName(sInternalName) Then
      oPropSetRegistry.removePropertySet(sInternalName)
   End If
   
   oPropSet = oPropSetRegistry.openPropertySet(sInternalName, True)
   
   'constant group com.sun.star.ui.ActionTriggerSeparatorType not supported?
   'unfortunately, the only separator-type working is the "SPACE"
   'regardless for the iSeparatorType passed...
   iSeparatorType = 1
   oPropSet.addProperty("SeparatorType", 0, iSeparatorType)

   GetMenuSeparator = oPropSet
   
End Function 

sub PysPresent
thiscomponent.currentselection.string="X"
end sub
sub PysAbsent
thiscomponent.currentselection.string="A"
end sub
sub PysExcuse
thiscomponent.currentselection.string="E"
end sub
sub PysNR
thiscomponent.currentselection.string=""
end sub
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
Avatar de l’utilisateur
Alain de La Chaume
HédOOniste
HédOOniste
Messages : 1527
Inscription : 28 sept. 2008 12:56
Localisation : ʇsǝnoo,ꞁ ɐ ʇuǝɯǝʇǝꞁdɯoↃ

Re: [Calc] Gérer un menu contextuel (clic droit)

Message par Alain de La Chaume »

Bonjour,

et merci Grand Maître pour ce petit chef-d'œuvre.
Dès que j'aurais fait provision d'aspirine, je mettrai le nez dans le code. :P
(API-culteur et pêcheur de macros en mode loisirs occasionnels, mais toujours les pieds dans l'OO)
AOO 4.1.2 sous Linux Xubuntu Voyager 14.04 (x86_64)
Avatar de l’utilisateur
Churay
ManitOOu
ManitOOu
Messages : 2668
Inscription : 30 avr. 2009 04:54
Localisation : CATALUNYA

Re: [Calc] Gérer un menu contextuel (clic droit)

Message par Churay »

Bonjour,
Alain de La Chaume a écrit :et merci Grand Maître pour ce petit chef-d'œuvre.
Moyennement d'accord :
et merci Grand Maître : je souscris
pour ce petit chef-d'œuvre : là non !!! Ce n'est pas petit...

Superbe !
cOOordialement
---
AOO 4.0.1 W7-PRO & LO 5.1.6.2 Debian 7.8 & Ubuntu 16.04 LTS
---
F1 : ça aide...
XRay + SDK :super:
---
Quand le NOT CONFIRMED sera corrigé (OOo et LO) , je serai heureux...
Airhik
Fraîchement OOthentifié
Messages : 7
Inscription : 09 avr. 2015 07:25

Re: [Calc] Gérer un menu contextuel (clic droit)

Message par Airhik »

Merci pour ce tutorial qui me sera sans aucun doute d'une aide précieuse.
Openoffice 2.4 sous windows 8