Inhoud

# Een dialog-handler aanmaken

Behalve het koppelen van macro's aan gebeurtenissen en afvangen van gebeurtenissen, kan men ook een dialoog-handler gebruiken, dan definieert men UNO-sleutelwoorden of methoden, die gekoppeld worden aan bepaalde te volgen gebeurtenissen. De handler zorgt voor het uitvoeren van de methode met gebruik van het protocol vnd.sun.star.UNO:<method_name>. Anders dan bij het afvangen waar alle ondersteunde methoden gedefinieerd moeten worden, ook de ongebruikte, hoeft bij een dialoog-handler dat maar twee methoden boven de bedoelde control hook scripts.

De voordelen van deze benadering zijn:

- Het brengt de code bij elkaar die de door gebeurtenissen aangestuurde macro's afhandelt,

- het voorkomt samenhang tussen gebeurtenissen van macro-namen waardoor onderhoud of wijzigingen gemakkelijker mogelijk is, in het bijzonder bij het verplaatsen van macro's of modules.

Dit mechanisme wordt hier toegelicht met de talen Basic en Python met een geïmporteerde kopie van de dialoog Access2Base dlgTrace. Omdat het een voorbeeld is zijn de foutafhandeling en de vertaling weggelaten.

## Toekenning Dialoog-methodes

Exporteer de Access2Base dialoog dlgTrace en importeer die in de applicatie-bibliotheek MyLib.

Binnen het paneel van de eigenschappen van de dialoogeditor, gebruik het tabblad Gebeurtenissen om een koppeling van een macro te vervangen door een koppeling met een component, voer de bedoelde methodenamen in:

- Zet de methode-naam van de dialoogknop Dump to file op _dump2File

- Definieer eventueel bij gebeurtenissen txtTracelog toets ingedrukt en muisknop ingedrukt component methodenamen als _openHelp

- Definieer eventueel de methodenaam knop Ok krijgt focus als onOkHasfocus

Acties gekoppeld aan gebeurtenissen moeten het protocol vnd.sun.star.UNO: vermelden.

## De handler aanmaken

De methode createDialogWithHandler van de com.sun.star.awt.DialogProvider2 service wordt gebruikt om de dialoog en de handler in te stellen. De handler zorgt voor de implementatie van de com.sun.star.awt.XDialogEventHandler interface.

Bij gebruik van een dialoog-handler moeten alle methode-namen expliciet worden gedeclareerd.

### Met Python

In dit voorbeeld staat de dialoog op de computer.

          # -*- coding: utf-8 -*-
          from __future__ import unicode_literals

          import uno, unohelper
          from com.sun.star.awt import XDialogEventHandler

          _DLG_PROVIDER = "com.sun.star.awt.DialogProvider2"

          class Console(unohelper.Base, XDialogEventHandler):
              """ Access2Base console-handler """
              ''' originele versie is « Créer un dialogue avec gestionnaire d'événements » van JM Zambon
              https://wiki.openoffice.org/wiki/FR/Documentation/Python/Creating_Dialog_with_Handler '''
              def show(self):
                  dialog = self.getDialog("MyLib.dlgTrace", embedded=True)
                  dialog.Title = "Konsole"
                  dialog.execute()

              def callHandlerMethod(self, dialog, event, method):
                  if method == '_dump2File':
                      event.Source.setLabel("dump requested")
                      scr = getBasicScript(script="_DumpToFile", module="Trace",
                          library='Access2Base')
                      scr.invoke((event,), (), ())
                  elif method == '_openHelp':
                      _msgbox('Not yet implemented')
                      dialog.endDialog(1)
                  else:
                      return False

              def getSupportedMethodNames(self):
                  return ('_dump2File', '_openHelp')

              def getDialog(self, libr_dlg: str, embedded=False):
                  """ Een dialoog aanmaken vanaf de locatie """
                  smgr = XSCRIPTCONTEXT.getComponentContext().ServiceManager
                  if embedded:
                      model = XSCRIPTCONTEXT.getDocument()
                      dp = smgr.createInstanceWithArguments(_DLG_PROVIDER, (model,))
                      location = "?location=document"
                  else:
                      dp = smgr.createInstanceWithContext(_DLG_PROVIDER, ctx)
                      location = "?location=application"
                  dlg = dp.createDialogWithHandler("vnd.sun.star.script:"+libr_dlg+location, self)
                  return dlg

          # def getBasicScript()  # see note

          def _msgbox(prompt='', title=''):
              ''' Lelijke MsgBox '''
              import msgbox
              mb = msgbox.MsgBox(uno.getComponentContext())
              mb.addButton('Howdy')
              mb.show(prompt,0,title)

          def ConsoleHandler():
              Console().show()

          g_exportedScripts = (ConsoleHandler,)

Zoals verwacht, de ontbrekende methode bij onOkHasFocus zorgt voor een exception.

Bekijk de pagina Python aanroepen van LibreOffice Basic voor een beschrijving van de routine getBasicScript en voor details over de uitvoering van scripts tussen verschillende programmeertalen.

### Met LibreOffice BASIC

In dit voorbeeld is de dialoog ingesloten in een document en kan ook worden gevonden op de computer.

          ' <MyLib>.<Handler> module

          Public Sub Console_Show()
              Dim dp as Object ' com.sun.star.awt.DialogProvider2
              Dim dialog As Object ' com.sun.star.awt.XDialog, com.sun.star.awt.XDialogEventHandler
              Dim eventHandler As Object ' com.sun.star.awt.XDialogEventHandler
              dp = CreateUnoService("com.sun.star.awt.DialogProvider2")
              dp.Initialize(Array(ThisComponent)) ' indien dialoog ingesloten zit in document
              eventHandler = CreateUnoListener("Console_", "com.sun.star.awt.XDialogEventHandler")
              dialog = dp.createDialogWithHandler("vnd.sun.star.script:MyLib.dlgTrace?location=document", eventHandler)
              dialog.Title = "Konsole"
              dialog.execute()
          End Sub ' <Handler>.Console_Show()

          Private Function Console_callHandlerMethod(dialog as Object, _
                  event As com.sun.star.document.DocumentEvent, _
                  method As String) As Boolean
              ''' Intercept dialog events using .UNO protocol '''
              Console_callHandlerMethod = True
              Select Case method
                  Case "_dump2File"
                      event.Source.setLabel("dump requested")
                      With GlobalScope.BasicLibraries
                          If Not .IsLibraryLoaded("Access2Base") Then .LoadLibrary("Access2Base")
                      End With
                      Access2Base.Trace._DumpToFile
                  Case "_openHelp"
                      MsgBox "Not yet implemented",0 , "Howdy"
                      'dialog.endDialog(1) indien dialoog via computer
                  Case Else : Console_callHandlerMethod = False
              End Select
          End Function ' <Handler>.Console_callHandlerMethod

          Private Function Console_getSupportedMethodNames()
              Console_getSupportedMethodNames = Array("_dump2File", "_openHelp")
          End Function ' <Handler>.Console _getSupportedMethodNames

          ' bewerkte versie van « Créer un dialogue avec gestionnaire d'événements » door JM Zambon
          ' https://wiki.openoffice.org/wiki/FR/Documentation/Python/Creating_Dialog_with_Handler

Zoals verwacht, de ontbrekende methode bij onOkHasFocus zorgt voor een exception.

Verwante onderwerpen

Basic-macro's in Python aanroepen

Een dialoogvenster met BASIC openen

CreateUnoListener functie

Listeners aanmaken

Een dialoogvenster met Python openen

Documentgebeurtenissen monitoren

Python programmeringsvoorbeelden

Hulp bij LibreOffice Python-scripts