[Calc] Event-Listeners & Handlers

Creating Extension - Shared Libraries
Forum rules
For sharing working examples of macros / scripts. These can be in any script language supported by OpenOffice.org [Basic, Python, Netbean] or as source code files in Java or C# even - but requires the actual source code listing. This forum is not for asking questions about writing your own macros.

[Calc] Event-Listeners & Handlers

Postby onidarbe » Fri Sep 26, 2008 2:00 am

Errors and behaviors described here, are when using OpenOffice 2.4.1 !!! No garantee given that there are no faults in this text :oops:
Please report faults or missing information ... Thank you, Onidar - Belgium
You can download the calc-file which shows every event on the statusBar....


Handler & Listeners
Events are tricky in OO !!! >>>>>>>>>>>> "OO-DEVELOPMENT, PLEASE DO SOMETHING !!!" ;)
They should beter insert a DataChangedInDocument" in oo-Calc/Tools/Customize/Events/...
providing the changed range and if possible the previous-cell, -selection and data
triggering the sub-event after the full copied data has entered with already moving the selection and activecell.


!!! Events will temporary interrupt each other until there own prg-code in the corresponding sub has finished !!!
Have a look at the statusbar and youll see while entering data, which event will fire and interrupt the other.
Using "WAIT 25" at the start of a event-sub will let the second event-sub start before running a bit of his own code.

ooBUGG: Stopping event-listeners and handlers only works when there is no programming done!
This is because objects get lost on programming while listeners keep on running.
So it is best to stop/start all events before programming using the sEvent_DeactivateDocument/sEvent_ActivateDocument
>>>>>> MORE FOR OO-DEVELOPMENT ;) Keep variables while programming and have a real step-by-step debugging system.

------------------------------------------------- XKeyHandler ----------------------------------------------------------
ooBUGG: Stops after a print-preview and maybe after something else? !!!
Starts every time an other listener up! So never start it twice.

---------------------------------------------- XMouseClickHandler ------------------------------------------------------
ooBUGG: Stops after a print-preview and maybe after something else? !!!
Starts every time an other listener up! So never start it twice.

------------------------------------------- XSelectionChangeListener ---------------------------------------------------
ooBUGG: Stops after a print-preview and maybe after something else? !!!
ooBUGG: ..._disposing doesnt get called. So one cant know when listener is suddenly gone !!!
ooBUGG: Triggers even when mousebutton is still down, so it keeps on selecting while still running sub.
Like when Msgbox is/has popped-up from the XSelectionChangeListener-sub selecting a range is still busy!!!
So dont use Msgbox in this sub !!!

If used with XChartDataChangeEventListener, XSelectionChangeListener will fire first, but XChart will interrupt it.
It is unpredictable where the XSelection...-sub-prg-code will be temporally stopt running XChart...-sub first !!!
Deleting cell-contense doesnt trigger this, but copy data in a selection does though the selection didnt change !?
Starts every time an other listener up! So never start it twice.

------------------------------------------ XPropertyChangeListener -----------------------------------------------------
ooBUGG: ..._disposing doesnt get called. So one cant know when listener is suddenly gone !!!
ooBUGG: Stops after a print-preview and maybe after something else? !!!

Triggers whenever the view changes: scroll, changing from sheet, ...
Doesnt normally start twice, unless you have altered the program-code. So never start it twice!

---------------------------------------------- XModifyListener ---------------------------------------------------------
ooBUGG: ..._disposing doesnt get called. So one cant know when listener is suddenly gone !!!
ooBUGG: No way to now what range has changed when using drag-fill, nothing in oEvent nor is it selected jet !!!

Triggers before changing the selection of a drag-fill and before moving the active-cell.
Doesnt stop with a print-preview. It keeps running as far as I know...
To be able to stop it, you need to put the range in an object, because ThisComponent.Sheets(0) doesnt seem to stay the same when using it to remove the listener !!!???
Starts every time an other listener up! So never start it twice.

---------------------------------------- XChartDataChangeEventListener -------------------------------------------------
ooBUGG: ..._disposing doesnt get called. So one cant know when listener is suddenly gone !!!
ooBUGG: To be able to stop it, you need to put the range in an object, because ThisComponent.Sheets(0) doesnt seem to stay the same when using it to remove the listener !!!???
ooBUGG: Listener stops on inserting a line. I did find a sulution to overcome this bugg, read next line...

:idea: TIP: Inserting/Deleting one line before starting the listener will allow you to inserting lines later on ;)
Runs after changing the selecting and activeCell & starting oXSelectionChangeListener-sub, but will interrupt it !
Doesnt stop with a print-preview. It keeps running as far as I know...
Doesnt normally start twice, unless you have altered the program-code. So never start it twice!

------------------------------------------------- XEventListener -------------------------------------------------------
= main listener, doesnt tell you when any data has changed, but it keeps running as far as I know...
EventName: OnFocus OnUnfocus OnNew OnPrint OnSave OnSaveAs OnSaveAsDone OnSaveDone OnLoad OnUnload OnPrepareUnload OnModifyChange OnCopyTo
ooBUGG: ..._disposing doesnt get called. So one cant know when listener is suddenly gone !!!
Doesnt stop with a print-preview. It keeps running as far as I know...
Cant be used to start lost listeners after print-preview. There is no trigger when chart is ready to be pointed to after print-preview.
If ooCalc-auto-saving is on, the listener will trigger this sub while programming!
Starts every time an other listener up! So never start it twice.

Code: Select all   Expand viewCollapse view
'=================================== OOoBasic program-code to test the Events-Listeners =================================

'Errors and behaviors described here, are when using OpenOffice 2.4.1 !!!

sub sEvent_OpenDocument 'set to be called in oo-Calc/Tools/Customize/Events/"Open Document"
   'ooBAD: This event starts after ActivateDocument and will therefor interupting it while running this sub.
   sStatusBar ," OpenDoc{"
   wait 25
   sStartXModifyListener
   sStartXChartDataChangeEventListener
   sStartXEventListener
   sStatusBar ,"}"
end sub
sub sEvent_CloseDocument 'set to be called in oo-Calc/Tools/Customize/Events/"Close Document"
   sStatusBar ," CloseDoc{"
   wait 25
   sStopXModifyListener
   sStopXChartDataChangeEventListener
   sStopXEventListener
   sStatusBar ,"}"
   wait 2000
end sub

sub sEvent_ActivateDocument 'set to be called in oo-Calc/Tools/Customize/Events/"Activate Document"
   'ooBAD: Seems this event starts before OpenDocument, but get interupted at some time until OpenDocument-event has run his sub!!!
   sStatusBar ," ActDoc{"
   wait 25 'just to be shure sEvent_OpenDocument runs first
   sStartXKeyHandler
   sStartXMouseClickHandler
   sStartXSelectionChangeListener
   sStartXPropertyChangeListener
'   sStartXModifyListener
'   sStartXChartDataChangeEventListener
'   sStartXEventListener
   sStatusBar ,"}"
end sub
sub sEvent_DeactivateDocument 'set to be called in oo-Calc/Tools/Customize/Events/"Deactivate Document"
   sStatusBar ," DeactDoc{"
   wait 25
   sStopXKeyHandler
   sStopXMouseClickHandler
   sStopXSelectionChangeListener
   sStopXPropertyChangeListener
'   sStopXModifyListener
'   sStopXChartDataChangeEventListener
'   sStopXEventListener
   sStatusBar ,"}"
end sub

'========================================================================================================================
'============================================== Handler & Listeners =====================================================
'    Events are tricky in OO !!!   >>>>>>>>>>>> "OO-DEVELOPMENT, PLEASE DO SOMETHING !!!"
'    They should beter insert a 'DataChangedInDocument" in oo-Calc/Tools/Customize/Events/...
'    providing the changed range and if possible the previous-cell, -selection and data ;-)
'    triggering the sub-event after the full copied data has entered with already moving the selection and activecell.
'
' !!! Events will temporary interrupt each other until there own prg-code in the corresponding sub has finished !!!
' Have a look at the statusbar and you'll see while entering data, which event will fire and interrupt the other.
' Using "WAIT  25" at the start of a event-sub will let the second event-sub start before running a bit of his own code.
'
' ooBUGG: Stopping event-listeners and handlers only works when there is no programming done!
'    This is because objects get lost on programming while listeners keep on running.
'    >>>>>> MORE FOR OO-DEVELOPMENT ;-) Keep variables while programming and have a real step-by-step debugging system.
'    So it is best to stop/start all events before programming using the sEvent_DeactivateDocument/sEvent_ActivateDocument
'========================================================================================================================

'--------------------------------------------------- XKeyHandler --------------------------------------------------------
global oXKeyHandler as object
sub sStartXKeyHandler
   'ooBUGG: Stops after a print-preview and maybe after something else? !!!
   'Starts every time an other listener up! So never start it twice.
   if isNull(oXKeyHandler) then 'only if not jet running
      sStatusBar ,"+K"
      oXKeyHandler = CreateUnoListener("XKeyHandler_", "com.sun.star.awt.XKeyHandler")
      ThisComponent.GetCurrentController.AddKeyHandler(oXKeyHandler)
   else
      sStatusBar ,"!K"
   endif
end sub
sub sStopXKeyHandler
   if not IsNull(oXKeyHandler) then 'only if still running
      sStatusBar ,"-K"
      ThisComponent.GetCurrentController.removeKeyHandler(oXKeyHandler)
      oXKeyHandler=Nothing 'To know later this handler has stopt.
   else
      sStatusBar ,"!K"
   end if
end sub
sub XKeyHandler_Disposing(oEvent)
   sStopXKeyHandler
end sub
function XKeyHandler_KeyPressed(oEvent) as boolean '''Shift, Ctrl and Alt alone doesn't trigger this !!!
   sScreenUpdatingOff
   sStatusBar ," Key" & chr(34)
   XKeyHandler_KeyPressed = False '=Don't cancel this KeyPressed
   'if oEvent.KeyCode = com.sun.star.awt.Key.RIGHT then
   vCode=oEvent.keyCode
   select case vCode
   case 256 to 265 : vName="Num" & vCode-256
   case 512 to 537 : vName=chr(vCode-447)
   case 768 to 793 : vName="F" & vCode-767
   case 1024 to 1031 :   vName=choose(vCode-1023,"DOWN","UP","LEFT","RIGHT","HOME","END","PAGEUP","PAGEDOWN")
   case 1280 to 1290 : vName=choose(vCode-1279,"RETURN","ESCAPE","TAB","BACKSPACE","SPACE","INSERT","DELETE","ADD","SUBTRACT","MULTIPLY","DIVIDE")
   case 1291 to 1301 : vName=choose(vCode-1290,"POINT","COMMA","LESS","GREATER","EQUAL","OPEN","CUT","COPY","PASTE","UNDO","REPEAT")
   case 1302 to 1311 : vName=choose(vCode-1301,"FIND","PROPERTIES","FRONT","CONTEXTMENU","HELP","MENU","HANGUL_HANJA","DECIMAL","TILDE","QUOTELEFT")
   case 1536 to 1557 : vName=choose(vCode-1535,"DELETE_TO_BEGIN_OF_LINE","DELETE_TO_END_OF_LINE","DELETE_TO_BEGIN_OF_PARAGRAPH","DELETE_TO_END_OF_PARAGRAPH","DELETE_WORD_BACKWARD","DELETE_WORD_FORWARD","INSERT_LINEBREAK","INSERT_PARAGRAPH","MOVE_WORD_BACKWARD","MOVE_WORD_FORWARD","MOVE_TO_BEGIN_OF_LINE","MOVE_TO_END_OF_LINE","MOVE_TO_BEGIN_OF_PARAGRAPH","MOVE_TO_END_OF_PARAGRAPH","SELECT_BACKWARD","SELECT_FORWARD","SELECT_WORD_BACKWARD","SELECT_WORD_FORWARD","SELECT_WORD","SELECT_LINE","SELECT_PARAGRAPH","SELECT_ALL")
   case else : vName="???"
   end select
   vFunc=choose(oEvent.keyFunc+1,"","NEW","OPEN","SAVE","SAVEAS","PRINT","CLOSE","QUIT","CUT","COPY","PASTE","UNDO","REDO","DELETE","REPEAT","FIND","FINDBACKWARD","PROPERTIES","FRONT")
   oMod=oEvent.Modifiers '1=Shift, 2=Ctrl, 4=Alt
   if oMod and 1 then vMod=vMod & "+SHIFT"
   if oMod and 2 then vMod=vMod & "+CTRL"
   if oMod and 4 then vMod=vMod & "+ALT"
   vChar=oEvent.keyChar
   IF vChar="" then
      vOut=vName
   elseif asc(vChar)>32 and asc(vChar)<176 then
      vOut=vChar
   else
      vOut=vName
   end if
   wait 25
   sStatusBar ,vOut & vMod & chr(34)
   sScreenUpdatingOn
end function
function XKeyHandler_KeyReleased(oEvent) as boolean
   XKeyHandler_KeyReleased = False 'Don't cancel this
end function

' ------------------------------------------ XMouseClickHandler -------------------------------------------------
global oXMouseClickHandler as object
global bMouseButton as boolean
global bMouseDoubleClick as boolean
sub sStartXMouseClickHandler
   'ooBUGG: Stops after a print-preview and maybe after something else? !!!
   'Starts every time an other listener up! So never start it twice.
   if isNull(oXMouseClickHandler) then 'only if not jet running
      sStatusBar ,"+M"
      oXMouseClickHandler = CreateUnoListener("XMouseClickHandler_", "com.sun.star.awt.XMouseClickHandler")
      ThisComponent.CurrentController.AddMouseClickHandler(oXMouseClickHandler)
   else
      sStatusBar ,"!M"
   endif
end sub
sub sStopXMouseClickHandler
   if not IsNull(oXMouseClickHandler) then 'only if still running
      sStatusBar ,"-M"
      ThisComponent.CurrentController.removeMouseClickHandler(oXMouseClickHandler)
      oXMouseClickHandler=Nothing 'To know later this handler has stopt.
   else
      sStatusBar ,"!M"
   end if
end sub
sub XMouseClickHandler_Disposing(oEvent)
   sStopXMouseClickHandler   
end sub
function XMouseClickHandler_mousePressed(oEvent) as boolean
   'Program code here could be temporary interrupted if mouse button is released earlier then executing this function-code!
   sStatusBar , " M("
   XMouseClickHandler_mousePressed = False 'Don't cancel mousePressed
   bMouseDoubleClick=(oEvent.ClickCount=2)
   if oEvent.Buttons=1 then bMouseButton=true
   wait 25
   sStatusBar , abs(bMouseDoubleClick)+1 & ")"
end function
function XMouseClickHandler_mouseReleased(oEvent) as boolean
   sStatusBar , " M("
   XMouseClickHandler_mouseReleased = False 'Don't cancel mouseReleased
   if oEvent.Buttons=1 then bMouseButton=false
   wait 25
   sStatusBar , abs(bMouseButton) & ")"
end function

' ----------------------------------------- XSelectionChangeListener ------------------------------------------------
global oXSelectionChangeListener as object
sub sStartXSelectionChangeListener
   'ooBAD: Stops after a print-preview and maybe after something else? !!!
   'ooBUGG: ..._disposing doesn't get called. So one can't know when listener is suddenly gone !!!
   'ooBUGG: Triggers even when mousebutton is still down, so it keeps on selecting while still running sub.
   '        Like when Msgbox is/has popped-up from the XSelectionChangeListener-sub selecting a range is still busy!!!
   '        So don't use Msgbox in this sub !!!
   'If used with XChartDataChangeEventListener, XSelectionChangeListener will fire first, but XChart will interrupt it.
   '  It is unpredictable where the XSelection...-sub-prg-code will be temporally stopt running XChart...-sub first !!!
   'Deleting cell-contense doesn't trigger this, but copy data in a selection does though the selection didn't change !?
   'Starts every time an other listener up! So never start it twice.
   if isNull(oXSelectionChangeListener)then 'just to be shure it doesn't start twice
      sStatusBar ,"+s"
      oXSelectionChangeListener=CreateUnoListener("XSelectionChangeListener_", "com.sun.star.view.XSelectionChangeListener")
      ThisComponent.CurrentController.AddSelectionChangeListener(oXSelectionChangeListener)
   else
      sStatusBar ,"!s"
   end if
end sub
sub sStopXSelectionChangeListener
   if not isNull(oXSelectionChangeListener) then 'only if still running
      sStatusBar ,"-s"
      ThisComponent.CurrentController.removeSelectionChangeListener(oXSelectionChangeListener)
      oXSelectionChangeListener=nothing 'To know later this listener has stopt.
   else
      sStatusBar ,"!s"
   end if
end sub
sub XSelectionChangeListener_Disposing(oEvent)
   Msgbox "XSelectionChangeListener_disposing does work now !?"
   sStopXSelectionChangeListener
end sub
sub XSelectionChangeListener_selectionChanged(oEvent)
   sScreenUpdatingOff
   sStatusBar ," s[" & a(ThisComponent.CurrentSelection) & "#" & a(o())
   wait 25
   sStatusBar ,"]"
   sScreenUpdatingOn
end sub

' ------------------------------------------ XPropertyChangeListener -------------------------------------------------
global oXPropertyChangeListener as object
sub sStartXPropertyChangeListener
   'ooBUGG: ..._disposing doesn't get called. So one can't know when listener is suddenly gone !!!
   'ooBUGG: Stops after a print-preview and maybe after something else? !!!
   'Triggers whenever the view changes: scroll, changing from sheet, ...
   'Doesn't normally start twice, unless you have altered the program-code. So never start it twice!
   if isNull(oXPropertyChangeListener)then 'just to be shure it doesn't start twice
      sStatusBar ,"+p"
      oXPropertyChangeListener=CreateUnoListener("XPropertyChangeListener_", "com.sun.star.beans.XPropertyChangeListener")
      ThisComponent.CurrentController.AddPropertyChangeListener("ActiveSheet", oXPropertyChangeListener)
   else
      sStatusBar ,"!p"
   end if
end sub
sub sStopXPropertyChangeListener
   if not isNull(oXPropertyChangeListener) then 'only if still running
      sStatusBar ,"-p"
      ThisComponent.CurrentController.removePropertyChangeListener("ActiveSheet", oXPropertyChangeListener)
      oXPropertyChangeListener=nothing 'To know later the listener has stopt.
   else
      sStatusBar ,"!p"
   end if
end sub
sub XPropertyChangeListener_Disposing(oEvent)
   Msgbox "XPropertyChangeListener_disposing does work now !?"
   sStoptXPropertyChangeListener
end sub
sub XPropertyChangeListener_propertyChange(oEvent)
   sStatusBar ," p("
   wait 25
   sStatusBar ,")"
end sub

' ------------------------------------------- XModifyListener --------------------------------------------------
global oXModifyListener as object
global oXModifyRange as object
sub sStartXModifyListener
   'ooBUGG: ..._disposing doesn't get called. So one can't know when listener is suddenly gone !!!
   'ooBUGG: No way to now what range has changed when using drag-fill, nothing in oEvent nor is it selected jet !!!
   'Triggers before changing the selection of a drag-fill and before moving the active-cell.
   'Doesn't stop with a print-preview. It keeps running as far as I know...
   'To be able to stop it, you need to put the range in an object, because ThisComponent.Sheets(0) doesn't seem to stay the same when using it to remove the listener !!!???
   'Starts every time an other listener up! So never start it twice.
   if isNull(oXModifyListener)then 'just to be shure it doesn't start twice
      sStatusBar ,"+m"
      oXModifyListener=CreateUnoListener("XModifyListener_", "com.sun.star.util.XModifyListener")
      'can't stop it using ThisComponent.Sheets(0).AddModifyListener(oXModifyListener)
      oXModifyRange=ThisComponent.Sheets(0)
      oXModifyRange.AddModifyListener(oXModifyListener)
   else
      sStatusBar ,"!m"
   end if
end sub
sub sStopXModifyListener
   if not isNull(oXModifyListener) then 'only if still running
      sStatusBar ,"-m"
      oXModifyRange.removeModifyListener(oXModifyListener)
      oXModifyListener=nothing 'To know later this listener has stopt.
   else
      sStatusBar ,"!m"
   end if
end sub
sub XModifyListener_Disposing(oEvent)
   Msgbox "XModifyListener_disposing does work now !?"
   sStopXModifyListener
end sub
sub XModifyListener_modified(oEvent)
   sScreenUpdatingOff
   sStatusBar ," m[" & a(ThisComponent.CurrentSelection) & "#" & a(o())
   wait 25
   sStatusBar ,"]"
   sScreenUpdatingOn
end sub

' --------------------------------------- XChartDataChangeEventListener ----------------------------------------------
global oXChartDataChangeEventListener as object
global oXChartDataChangeRange as object
sub sStartXChartDataChangeEventListener
   'ooBUGG: ..._disposing doesn't get called. So one can't know when listener is suddenly gone !!!
   'ooBUGG: To be able to stop it, you need to put the range in an object, because ThisComponent.Sheets(0) doesn't seem to stay the same when using it to remove the listener !!!???
   'ooBUGG: Listener stops on inserting a line. I did find a sulution to overcome this bugg, read next line...
   '   TIP: Inserting/Deleting one line before starting the listener will allow you to inserting lines later on ;-)
   'Runs after changing the selecting and activeCell & starting oXSelectionChangeListener-sub, but will interrupt it !
   'Doesn't stop with a print-preview. It keeps running as far as I know...
   'Doesn't normally start twice, unless you have altered the program-code. So never start it twice!
   if isNull(oXChartDataChangeEventListener)then 'just to be shure it doesn't start twice
      sStatusBar ,"+c"
      '!!! Following line can't be deleted, because otherwise the XChartDataChangeEventListener will stop if inserting a row or column just after the listener starts up.
      CreateUnoService("com.sun.star.frame.DispatchHelper").ExecuteDispatch(ThisComponent.CurrentController.Frame, ".uno:InsertRows", "", 0, Array())
      oXChartDataChangeEventListener=CreateUnoListener("XChartDataChangeEventListener_", "com.sun.star.chart.XChartDataChangeEventListener")   
      'Can't be stopt using:   ThisComponent.Sheets(0).AddChartDataChangeEventListener(oXChartDataChangeEventListener)
      oXChartDataChangeRange=ThisComponent.Sheets(0)
      oXChartDataChangeRange.AddChartDataChangeEventListener(oXChartDataChangeEventListener)
      '!!! Following line is to delete the needed inserted empty line. This will also trigger the listener!
      CreateUnoService("com.sun.star.frame.DispatchHelper").ExecuteDispatch(ThisComponent.CurrentController.Frame, ".uno:DeleteRows", "", 0, Array())
   else
      sStatusBar ,"!c"
   end if
end sub
sub sStopXChartDataChangeEventListener
   if not isNull(oXChartDataChangeEventListener) then 'only if still running
      sStatusBar ,"-c"
      oXChartDataChangeRange.removeChartDataChangeEventListener(oXChartDataChangeEventListener)
      oXChartDataChangeEventListener=nothing 'To know later this listener has stopt.
   else
      sStatusBar ,"!c"
   end if
end sub
sub XChartDataChangeEventListener_Disposing(oEvent)
   'ooBUGG: this is never called, but should be!!!
   Msgbox "XChartDataChangeEventListener_disposing does work now !?"
   sStopXChartDataChangeEventListener
end sub
sub XChartDataChangeEventListener_chartDataChanged(oEvent)
   sScreenUpdatingOff
   sStatusBar ," c[" & a(ThisComponent.CurrentSelection) & "#" & a(o())
   'wait 25
   sStatusBar ,"]"
   sScreenUpdatingOn
end sub

' ----------------------------------------------- XEventListener ------------------------------------------------------
global oXEventListener as object
sub sStartXEventListener
   '= main listener, doesn't tell you when any data has changed, but it keeps running as far as I know...
   'EventName: OnFocus OnUnfocus OnNew OnPrint OnSave OnSaveAs OnSaveAsDone OnSaveDone OnLoad OnUnload OnPrepareUnload OnModifyChange OnCopyTo
   'ooBUGG: ..._disposing doesn't get called. So one can't know when listener is suddenly gone !!!
   'Doesn't stop with a print-preview. It keeps running as far as I know...
   'Can't be used to start lost listeners after print-preview. There is no trigger when chart is ready to be pointed to after print-preview.
   'If ooCalc-auto-saving is on, the listener will trigger this sub while programming!
   'Starts every time an other listener up! So never start it twice.
   if isNull(oXEventListener)then 'just to be shure it doesn't start twice
      sStatusBar ,"+e"
      oXEventListener=CreateUnoListener("XEventListener_", "com.sun.star.document.XEventListener")   
      ThisComponent.com_sun_star_document_XEventBroadcaster_addEventListener(oXEventListener)
   else
      sStatusBar ,"!e"
   end if
end sub
sub sStopXEventListener
   if not isNull(oXEventListener) then 'only if still running
      sStatusBar ,"-e"
      ThisComponent.com_sun_star_document_XEventBroadcaster_removeEventListener(oXEventListener)
      oXEventListener=nothing 'To know later the listener has stopt.
   else
      sStatusBar ,"!e"
   end if
end sub
sub XEventListener_Disposing(oEvent)
   Msgbox "XEventListener_disposing does work now !?"
   sStopXEventListener
end sub
sub XEventListener_notifyEvent(oEvent as object)
   sStatusBar ," e(" & oEvent.EventName
   wait 25
   sStatusBar ,")"
   if OEvent.EventName="OnFocus" or OEvent.EventName="OnUnfocus" then exit sub
end sub
'====================================================================================================================
'======================================================= UTILITIES ==================================================
'========================================================================================================================
sub sOpenMacroEditor 'Assigned to a button to speed up opening the macro editor in this code.
'to assign it to a button: ooCalc/Tools/Customize/ToolBars/Add.../OpenOffice.org Macros/ThisFilename/Standard/Module1/sOpenMacroEditor/Add
   dim aOptions(5) as New com.sun.star.beans.PropertyValue
   aOptions(0).Name="LibName" : aOptions(0).Value="Standard" 'Name of library
   aOptions(1).Name="Name" : aOptions(1).Value="Module1" 'Name from Module or Dialog
   aOptions(2).Name="Line" : aOptions(2).Value=65 'Linenumber to set the cursor. NOTE: I which I could go to the last cursor or a marker...
   aOptions(3).Name="Type" : aOptions(3).Value="Module" 'Module or Dialog
   aTemp=split(ConvertFromURL(ThisComponent.GetURL),"\") :   aTemp=split(aTemp(uBound(aTemp)),".") 'Get filename
   aOptions(4).Name="Document" : aOptions(4).Value=aTemp(0) 'Name of the document = filename without extention
   oFrame = CreateUnoService("com.sun.star.frame.Frame")
   oDispatchHelper = createUnoService("com.sun.star.frame.DispatchHelper")
   oTemp = oDispatchHelper.ExecuteDispatch(oFrame, ".uno:BasicIDEAppear" ,"" ,0 ,aOptions())
end sub

sub sScreenUpdatingOff
   EXIT SUB
   ThisComponent.CurrentController.Frame.ContainerWindow.Enable=False
   if ThisComponent.isActionLocked=false then ThisComponent.AddActionLock
   if ThisComponent.hasControllersLocked=false then ThisComponent.LockControllers
end sub
sub sScreenUpdatingOn
   EXIT SUB
   if ThisComponent.hasControllersLocked=true then ThisComponent.unLockControllers
   if ThisComponent.isActionLocked=true then ThisComponent.removeActionLock
   ThisComponent.CurrentController.Frame.ContainerWindow.Enable=True
end sub

sub sUndo()
   sScreenUpdatingOff
   oCell=o() 'get activecell
   CreateUnoService("com.sun.star.frame.DispatchHelper").ExecuteDispatch(ThisComponent.CurrentController.Frame, ".uno:Undo", "", 0, Array()) '= undo
   if not isError(oCell) then ThisComponent.CurrentController.Select(oCell) 'reselect previous activecell
   ThisComponent.CurrentController.Select(ThisComponent.CreateInstance("com.sun.star.sheet.SheetCellRanges")) 'unselect any range
   sScreenUpdatingOn
end sub
sub sRedo()
   sScreenUpdatingOff
   oCell=o() 'get activecell
   'activate undo
   CreateUnoService("com.sun.star.frame.DispatchHelper").ExecuteDispatch(ThisComponent.CurrentController.Frame, ".uno:Redo", "", 0, Array())
   if not isError(oCell) then ThisComponent.CurrentController.Select(oCell) 'reselect previous activecell
   ThisComponent.CurrentController.Select(ThisComponent.CreateInstance("com.sun.star.sheet.SheetCellRanges")) 'unselect any range
   sScreenUpdatingOn
end sub

function a(oIn) 'Gives the address with column-letters and without sheetname or $ from a cell, range or multiple ranges
   if isNull(oIn) then a="" : exit function
   vOut=oIn.Absolutename
   vOut=join(split(vOut,"$"),"") 'replaces all $ with ""
   vSheetName=left(vOut,instr(2,vOut,".")) 'get sheetname
   a=join(split(vOut,vSheetName),"") 'replaces all sheetnames with ""
end function

function fLastRow() as integer
   oSheet = ThisComponent.CurrentController.ActiveSheet
   oCursor = oSheet.createCursor()
   oCursor.GotoEndOfUsedArea(False)
   fLastRow = oCursor.RangeAddress().EndRow
end function
function fLastCol() as integer
   oSheet = ThisComponent.CurrentController.ActiveSheet
   oCursor = oSheet.createCursor()
   oCursor.GotoEndOfUsedArea(False)
   fLastCol = oCursor.RangeAddress().EndColumn
end function

function o(optional vChangeColOrRow) as object 'get the activecell with or whitout changing to an other row or column, column=columnname, row+1=number
   oActiveSheet=ThisComponent.CurrentController.ActiveSheet
   vViewData=ThisComponent.CurrentController.viewData
   vViewData=join(split(vViewData,";"),"/") 'replace ; with /
   vViewData=join(split(vViewData,":"),"/") 'replace : with /
   vViewData=join(split(vViewData,"+"),"/") 'replace + with /
   vViewData=split(vViewData,"/") 'split the string
   iCol=val(vViewData(6))
   iRow=val(vViewData(7))
   if not isError(vChangeColOrRow) then 'change row or column
      if isNumeric(vChangeColOrRow) then 'change row
         iRow=int(val(vChangeColOrRow))
      else 'change column
         for iCol=0 to 999
            if oActiveSheet.GetCellByPosition(iCol,0).String=vChangeColOrRow then exit for
            if oActiveSheet.GetCellByPosition(iCol,0).String="" then  'Column-label not found
               msgbox "Column-name " & chr(34) & vChangeColOrRow & chr(34) & " is not found !!!"
               exit function
            endif
         next
      endif
   endif
   o=oActiveSheet.GetCellByPosition(iCol,iRow)
end function

global vStatusBarText as string '=text that is been displayed on the statusbar
sub sStatusBar(optional vNewText, optional vAddText) 'set or add text to the statusbar, nothing = clear&reset it.
   if isNull(ThisComponent.CurrentController) then exit sub 'Exit if there is no statusbar, as on closing document.
   if isError(vNewText) then
      if isError(vAddText) then 'clear statusbar
         vStatusBarText=""
      else 'add text to the previous statusbar
         vStatusBarText=vStatusBarText & vAddText
      endif
   else
      if isError(vAddText) then 'use new text
         vStatusBarText=vNewText
      else 'use new text and add the other text as well
         vStatusBarText=vNewText & vAddText
      endif
   endif
   if vStatusBarText="" then 'reset statusbar
      ThisComponent.CurrentController.StatusIndicator.Reset
   else 'change the text in the statusbar
      on error resume next 'comming from print-preview, XEventListener could run this and ThisComponent.CurrentController.VisibleArea doesn't exist.
      vStatusBarText=right(vStatusBarText,int(ThisComponent.CurrentController.VisibleArea.Width/150)) 'Select last part that could be displayed.
      ThisComponent.CurrentController.StatusIndicator.Start(vStatusBarText,0)
      on error goto 0
   endif
end sub
'===========================================================================================================================
Attachments
Event Listeners & Handlers.ods
ooCalc-file with the OOoBasic program-code to test the Events-Listeners
(15.61 KiB) Downloaded 1010 times
OOo 3.1.X on Ms Windows XP
User avatar
onidarbe
 
Posts: 84
Joined: Thu Nov 29, 2007 8:03 pm
Location: Belgium, Mechelen

Re: [Calc] Event-Listeners & Handlers

Postby oobigner » Tue Jun 09, 2009 4:45 am

Thank for your post, it is amazing script, thanks. :P
OOo 2.4.X on Ubuntu 7.x + Linux
oobigner
 
Posts: 1
Joined: Tue Jun 09, 2009 4:40 am

Re: [Calc] Event-Listeners & Handlers

Postby Villeroy » Tue Jun 09, 2009 9:06 am

ooBUGG: Stopping event-listeners and handlers only works when there is no programming done!

Not everything is a bug. As a matter of course your global variables get lost when you recompile the edited code.
Simply store all the declarations on a separate module you don't have to touch:
Code: Select all   Expand viewCollapse view
REM Separate module for declaration of persistent global symbols
Global gFooListener, gBarListener, gCounter%, gSomething
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04, OpenOffice 4.x & LibreOffice 6.x
User avatar
Villeroy
Volunteer
 
Posts: 26141
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany


Return to Code Snippets

Who is online

Users browsing this forum: No registered users and 1 guest