TVirtualStringTree. How to identify the exact node checked by the user? - delphi

My question relates to the issue raised in
TVirtualStringTree. How to check a node and its children with a single confirmation?
If the options for propagation are enabled and the user checks an internal node, the events OnCheck and OnChecking are triggered first for its child nodes. Is there any way that the program could identify the exact node checked by the user, when event handler for OnCheck is being executed? I experimentally ascertained that the handler for OnNodeClick is triggered only after OnCheck.

There is nothing built in, you will need to do it yourself.
The OnChecking event for the clicked node seems to be the first one executed at a checkbox click. So, create a variable, say ClickedNode:PVirtualNode (normally nil). In the OnChecking event check if it is nil and if it is, set it's value to the node of the event. The last event to fire is the OnClick event, in which you reset the ClickedNode to nil. In between, in the OnChecking or OnChecked events, you know that ClickedNode triggered the checking sequence.

Related

DJI Waypoint mission listeners

I need to create/upload/start waypoint mission on one button. When user press button drone should move up for certain number of point based on current position. User can stop mission and again start new one. My logic here is next:
I initialize mission with points
Load mission
Add Listeners to mission operator
Upload mission
Mission starts on listener
missionOperator.addListener(toUploadEvent: self, with: DispatchQueue.main) { (event) in
if event.currentState == .readyToExecute {
self.startMission()
}
}
I'm reading documentation for days and trying to understand how this thing work, but I'm missing something obviously. Listeners are created on waypoint mission operator, but if I create listeners before loading mission they are not called. If I create listeners every time I load mission, startMission() is called multiple times (first time is called ones, but after one mission is stopped or finished, next time startMission() gets called two times)
So, I guess that my questions would be:
What is right moment to add listeners and to remove them since I'm calling startMission() from listeners? Actually what is appropriate way to init/upload/start mission on one button, and be able to do that multiple times?
You need to remove the upload listener when the the upload succeeded and the event state is readyToExecute. Also when the event contains an error, or the state is readytoupload/notsupported/disconnected. Pretty much in every case except when it's still in the state 'uploading'.
When you start the mission, add a listener for execution events, and one for finished. Remove those again when the mission is stopped/cancelled, has an error, or finishes successfully.
Even though you use Swift, I suggest looking at the more complete Objective C sample code, which includes examples of several different types of missions.

Firebase added/removed/changed children listener using Swift

The official Firebase Documentation states:
ChildAdded
EventHandler< ChildChangedEventArgs > ChildAdded
Event raised when children nodes are added relative to this location.
Register a handler to observe when children are added relative to this
Query object. Each time time children nodes are added, your handler
will be called with an immutable snapshot of the data.
ChildRemoved
EventHandler< ChildChangedEventArgs > ChildRemoved
Event raised when children nodes are removed relative to this
location.
Register a handler to observe when children are removed relative to
this Query object. Each time time children nodes are removed, your
handler will be called with an immutable snapshot of the data.
ChildChanged
EventHandler< ChildChangedEventArgs > ChildChanged
Event raised when children nodes are changed relative to this
location.
Register a handler to observe changes to children relative to this
Query object. Each time time children nodes are changed, your handler
will be called with an immutable snapshot of the data.
So far I am using ChildRemoved and ChildAdded successfully, and they work solidly and with no hassle for what I am doing. In particular, these two listeners are independent, that is to say: the actions that make one of them fire are guaranteed not make the other one fire. So, I do not have to do any synchronization or scheduling to resolve conflicts.
My question is: Are these three listener types independent of each other?
That is to say:
For any given action, I am guaranteed that one, and at most one, of the three listeners will fire.
Only ChildAdded fires when the listener is first established. The other two listener types do not.
A note about the documentation, it would resolved ambiguity if the documentation for the ChildChanged would specify what it means by "childChanged": does it include addition/removal/moving/editing of a child, or does it only focus on editing to an existing child?
Each one of these events is a specific way to handle synchronization of data across clients.
.childChanged
will be called whenever something changes
So if you have a real time database like the following:
/store/<random-number-inserted-by-firebase-1>/name/store-1
/store/<random-number-inserted-by-firebase-1>/location/street-1
/store/<random-number-inserted-by-firebase-1>/items/0/name/name-1
/store/<random-number-inserted-by-firebase-1>/items/0/type/type-1
/store/<random-number-inserted-by-firebase-1>/items/1/name/name-2
/store/<random-number-inserted-by-firebase-1>/items/1/type/type-2
/store/<random-number-inserted-by-firebase-2>/name/store-2
/store/<random-number-inserted-by-firebase-2>/location/street-2
You start the childAdded, childChanged, and childRemoved observers on "/store" together.
If you change /store/<random-number-inserted-by-firebase-1>/items/0/type/type-1 to /store/<random-number-inserted-by-firebase-1>/items/0/type/new-type-1 your childChanged callback function will receive a dictionary ["random-number-inserted-by-firebase-1": ["name": "store-1", "location": "street-1", "items": [["name": "name-1", "type": "new-type-1"], ["name": "name-2", "type": "type-2"]] .childAdded listens for anything that changes in a node.

ChildAdded with LimitToLast triggers ChildRemoved

Regarding Firebase documentation if you limit your query with "toLast" then when a child is added, if you already exceed the value (in my case f.e. 50) then child removed is also triggered because the first child is deleted from the scope.
The following listeners are the ones I have on the code:
firebaseReference.queryOrderedByKey().queryLimited(toLast: 50).observe(.childAdded...
firebaseReference.queryOrderedByKey().queryLimited(toLast: 50).observe(.childRemoved...
I would like to know if there is some way to differenciate when a child is really deleted or a child is just deleted from the scope.
Thank you so much,
any further information don't hestiate to ask.
Firebase does not send along information on why you're receiving the .childRemoved event, so there's no way to know it based on that.
The only thing I can quickly think of is adding a .value listener for each child, which will then fire with null when the child gets deleted.
You'll want to remove the .value listener after you receive the .childRemoved handler, to not have dangling listeners for each child you've ever seen, so this may become more work than it's worth.

Get notification from Microsoft Graph when deleting event occurrence

I have subscribed to events (https://outlook.office.com/api/v2.0/me/events) push notification.
When I delete one event of recurrence master event, I receive UPDATED notification with id of master event and not specific occurrence event id.
How can I know which event was deleted without comparison with all previous recurrence events? And not receive only master id event.
When you "delete" and occurrence, you're technically not deleting an entity. You're actual adding an exception to the master's recurrence pattern. This is why you're receiving a notification that the master was updated rather than a notification that an event was deleted.
You can see the list of event occurrences and exceptions by calling the /instances. This will return a collection of event objects for a given master. You can determine if an object is an occurrence or an exception by looking at the type property (possible values are SingleInstance, Occurrence, Exception, or SeriesMaster).

How to discard mouse click in TDbGrid.OnColumnMoved

In a TDbGrid.OnColumnMoved event handler, I adjust some column headings colors.
I also use the grid's OnTitleClicked event to pop-up a (sort column) menu.
Unfortunately, after the user drags a column and OnColumnMoved is finished, the VCL calls OnTitleClicked. This means my sort-order pop-up appears after column dragging.
Is there a way in OnColumnMoved I can clear the mouse event queue so that OnTitleClicked doesn't get called?
This thread has this code, but I don't have a Msg in OnTitleClicked.
while PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST,
PM_REMOVE or PM_NOYIELD) do;
(If there's no way to do this, it's not big deal. I can set a flag in OnColumnMoved so that OnTitleClick ignores the next call to it.)
As mentioned in comments to the question, you would supply the 'Msg' for PeekMessage yourself (var Msg: TMsg). But discarding the message that triggers OnTitleClickis not possible because it is the same message that fires both events. VCL carries out column moving in response to a WM_LBUTTONUP message if a column has been dragged. Later during the handling of the same message OnTitleClick is called.
IOW, while you can remove messages from the message queue with PeekMessage, the message that triggers OnTitleClick is already dispatched since we are in an OnColumnMoved handler.
Easiest approach looks like setting the flag as you've told.

Resources