Page 1 of 1
[Calc] "Content Changed" sheet event behavior with "Ctrl+X"
Posted: Mon Oct 21, 2019 11:54 am
by ooGuillaume
Hello,
I'm using LibreOffice 6.2.7.1 Calc on Xubuntu 16.04.
I set up a macro to run when the "Content Changed" sheet event is thrown.
The macro triggers fine except when I cut (Control + X) the current selection.
Is this to be expected?
I'd like the macro to run when I cut the current selection. Is there a workaround, or another solution?
Thank you.
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 12:14 pm
by JeJe
See Andrew Pitonyak's OpenOffice.org Macros Explained OOME Third Edition
Listing 282 intercepting dispatch commands
http://www.pitonyak.org/oo.php
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 12:22 pm
by Zizi64
Yopu can use the "'Modified' status was changed" event of the document.
Note you can not use it again while the state of the flag is true. You must delete the flag at the end of the process launched by the event.
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 1:47 pm
by ooGuillaume
The warning in this section of Andrew Pitonyak's book is scary to me.
Be very careful while writing listeners and intercepting dispatches. Assume that something will change, or that you did something wrong and that OOo will crash; you have been warned.
I naively copied and pasted the whole Listing 282 into one module and hoped I would see a Message Box when copying a cell to another in my spreadsheet.
Nothing happened. Do I need to "hook" one or several functions inside this code, to a an event somewhere? I'm blind here.
Zizi64, thanks for the suggestion.
How would I know, when this event is triggered, that some contents were modified in the current selection?
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 2:13 pm
by JeJe
Pitonyak's code modified for cut is this (you have to run registerInterceptor first) but unfortunately on quickly testing it doesn't fire if a cut takes place in one cell.
Code: Select all
Global oDispatchInterceptor
Global oSlaveDispatchProvider
Global oMasterDispatchProvider
Global oFrame
Global bDebug As Boolean
Dim oCopyDispatch
Sub RegisterInterceptor
oFrame = ThisComponent.currentController.Frame
oDispatchInterceptor = CreateUnoListener("ThisFrame_", _
"com.sun.star.frame.XDispatchProviderInterceptor")
oFrame.registerDispatchProviderInterceptor(oDispatchInterceptor)
End Sub
Sub ReleaseInterceptor()
On Error Resume Next
oFrame.releaseDispatchProviderInterceptor(oDispatchInterceptor)
End Sub
Function ThisFrame_queryDispatch ( oUrl, _
sTargetFrameName As String, lSearchFlags As Long ) As Variant
302
Dim oDisp
Dim sUrl As String
'slot protocol causes OOo crash...
if oUrl.Protocol = "slot:" Then
Exit Function
End If
If bDebug Then
Print oUrl.complete
End If
'do your dispatch management here:
Select Case oUrl.complete
'Case ".uno:Copy"
'oDisp = GetCopyDispatch 'replace the original dispatch
'Case ".uno:Paste"
'oDisp = GetCopyDispatch 'replace the original dispatch
'Case ".uno:Save"
'oDisp = GetCopyDispatch 'replace the original dispatch
'Case ".uno:Undo"
'oDisp = GetCopyDispatch 'replace the original dispatch
'Case ".uno:blabla"
'do something
Case ".uno:Cut"
oDisp = GetCopyDispatch 'replace the original dispatch
Case Else
oDisp = _
oSlaveDispatchProvider.queryDispatch( oUrl, sTargetFrameName, lSearchFlags )
End Select
ThisFrame_queryDispatch = oDisp
End Function
Function ThisFrame_queryDispatches ( mDispatches ) As Variant
'ThisFrame_queryDispatches = mDispatches()
End Function
Function ThisFrame_getSlaveDispatchProvider ( ) As Variant
ThisFrame_getSlaveDispatchProvider = oSlaveDispatchProvider
End Function
Sub ThisFrame_setSlaveDispatchProvider ( oSDP )
oSlaveDispatchProvider = oSDP
End Sub
Function ThisFrame_getMasterDispatchProvider ( ) As Variant
ThisFrame_getMasterDispatchProvider = oMasterDispatchProvider
End Function
Sub ThisFrame_setMasterDispatchProvider ( oMDP )
303
oMasterDispatchProvider = oMDP
End Sub
Sub toggleDebug
bDebug = Not bDebug
End Sub
Function GetCopyDispatch()
If Not IsNull(oCopyDispatch) Then
oCopyDispatch = _
CreateUnoListener("MyCustom_", "com.sun.star.frame.XDispatch")
End If
GetCopyDispatch = oCopyDispatch
End Function
Sub MyCustom_dispatch(URL, Arguments)
Select Case URL.complete
Case ".uno:Cut"
MsgBox "cut"
'Case ".uno:Copy"
'MsgBox "Sorry, the original " & URL.complete & _
'" dispatch was stolen from Paolo M.", 48
'Case ".uno:Paste"
'ThisComponent.CurrentSelection(0).String = _
'"**** ARBITRARY CLIPBOARD CONTENT PROVIDED BY PAOLO M. ****"
'Case ".uno:Save"
'MsgBox "Sorry, the original " & URL.complete & _
'" dispatch was stolen from Paolo M.", 48
'Case ".uno:Undo"
'MsgBox "Undo What????!!!???", 16
'Case Else
End Select
End Sub
Sub MyCustom_addStatusListener(Control, URL)
End sub
Another option might be a keyhandler for the key combination of Ctrl+x
viewtopic.php?f=45&t=33914
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 2:20 pm
by JeJe
Here's that code modified:
Run sStartXKeyHandler first then try pressing ctrl+x in your document.
Code: Select all
Option Explicit
global oXKeyHandler as object
sub sStartXKeyHandler
if isNull(oXKeyHandler) then 'only if not jet running
oXKeyHandler = CreateUnoListener("KeyHandler_", "com.sun.star.awt.XKeyHandler")
ThisComponent.CurrentController.AddKeyHandler(oXKeyHandler)
endif
end sub
sub sStopXKeyHandler
if not IsNull(oXKeyHandler) then 'only if still running
ThisComponent.CurrentController.removeKeyHandler(oXKeyHandler)
oXKeyHandler = Nothing 'To know later this handler has stopped.
end if
end sub
sub XKeyHandler_Disposing(oEvent)
end sub
function KeyHandler_KeyPressed(oEvent) as boolean
' MsgBox(oEvent.KeyCode)
End function
function KeyHandler_KeyReleased(oEvent) as boolean
KeyHandler_KeyReleased = False 'cancel KeyReleased
if oevent.modifiers = 2 and oevent.keycode =535 then
msgbox "cut"
end if
end function
Edit: (this won't of course work if a cut is performed using the mouse)
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 2:26 pm
by Lupp
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 2:33 pm
by JeJe
Slight variation on the above using keyfunc:
Code: Select all
Option Explicit
global oXKeyHandler as object
sub sStartXKeyHandler
if isNull(oXKeyHandler) then 'only if not jet running
oXKeyHandler = CreateUnoListener("KeyHandler_", "com.sun.star.awt.XKeyHandler")
ThisComponent.CurrentController.AddKeyHandler(oXKeyHandler)
endif
end sub
sub sStopXKeyHandler
if not IsNull(oXKeyHandler) then 'only if still running
ThisComponent.CurrentController.removeKeyHandler(oXKeyHandler)
oXKeyHandler = Nothing 'To know later this handler has stopped.
end if
end sub
sub XKeyHandler_Disposing(oEvent)
end sub
function KeyHandler_KeyPressed(oEvent) as boolean
KeyHandler_KeyPressed = False 'cancel KeyPressed
End function
function KeyHandler_KeyReleased(oEvent) as boolean
KeyHandler_KeyReleased = False 'cancel KeyReleased
if oevent.keyfunc = 8 then 'cut function called
msgbox "cut"
end if
end function
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 3:14 pm
by Villeroy
One of these horrible UNO listeners:
Code: Select all
Sub addListener()
oModifyListener = createUnoListener("my_", "com.sun.star.util.XModifyListener")
ThisComponent.CurrentController.ActiveSheet.addModifyListener(oModifyListener)
End Sub
Sub my_modified(e)
msgbox "Yep"
End Sub
Sub my_disposing(e)
REM required dummy routine called by
REM parent interface c.s.s.lang.XEventListener
End Sub
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 4:51 pm
by ooGuillaume
Thanks.
I'm having a hard time finding out how I can get the modified cell, cell range, or cell ranges, from the 'e' parameter of my_modified(e).
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 4:59 pm
by Villeroy
Easy!
Code: Select all
Sub my_modified(e)
oMRI = CreateUnoService( "mytools.Mri" )
oMRI.inspect(e)
End Sub
The Source element is always the object which got the listener attached.
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 5:17 pm
by Lupp
Villeroy wrote:The Source element is always the object which got the listener attached.
In the given example this is the
Spreadsheet object, not a
SheetCellRange or a
SheetCellRanges object. To get access to the actually changed Cells the
ThisComponent.CurrentSelection should help.
In case of a move by dragndrop that's the target range.
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Mon Oct 21, 2019 5:31 pm
by JeJe
You may be able to get some information about the type of change by calling thiscomponent.undomanager.getCurrentUndoActionTitle
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Tue Oct 22, 2019 12:31 pm
by ooGuillaume
Thank you all, I went for the ThisComponent.CurrentSelection combined with the ModifyListener.
Is it a problem that the listener is added on opening the file, but not removed afterwards?
Lupp, it indeed felt like a bug to me! If it ever gets fixed, I'll be able to simplify my code again.
Re: [Calc] "Content Changed" sheet event behavior with "Ctrl
Posted: Tue Oct 22, 2019 3:53 pm
by Lupp
I would say it's surely a bug - and a very old one. It's common heritage of AOO and LibO.
Well, I reported the linked bugs, and I now also tried to draw the attention of a specific developer to these bugs. Lets practise patience again. There may not be a hurry concerning a bug unreported for decades.