How to detect and undo action

Jack S wrote on 10/3/2024, 7:15 AM

@jetdv Hi Edward. I wonder, do you know of a way to detect whether an undo action has been performed?
Say, for instance, I have a block of code encompassed by an UndoBlock using statement. Is there a way of detecting whether that UndoBlock has been activated when it's exited? Due to code within this block modifying an array element, I need to know whether that array element needs resetting or not.
Thanks for any help you can give me.

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE

Comments

jetdv wrote on 10/3/2024, 7:23 AM

I do not know of a way to detect "undos". I would suggest always repopulating your array to make sure it has the "current" information.

Jack S wrote on 10/4/2024, 5:14 AM

@jetdv Thanks, I thought that might be the case. Unfortunately, repopulating the array was not a solution I could use. Background information:-
One method in my code as an option to place a marker at the cursor position. Each application of the method places another marker. These markers are stored in an array.
Another method allows these generated markers to be deleted. My problem was, if the action carried out by the first method was undone, the marker would be deleted by the undo action. This, of course created a conflict between the number of markers that the array pointed to and the actual number on the timeline. When the delete markers method was called, Vegas crashed. Ordinarily I could call the inbuilt delete all markers command, but I didn't want possible markers created manually to be deleted. I implemented a bit of a work around. I enclosed the delete markers method in a try/catch block, with a message suggesting that the error was caused by an undo action. Not ideal, but better than the crash.
As always, thanks for your help.

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE

jetdv wrote on 10/4/2024, 7:44 AM

@Jack S, before deleting the marker, you *could* check to see that it actually exists first... Perhaps your array should store the timecodes of the markers instead of the actual marker. Then you could go through and delete the markers at those specific timecodes - IF there is a marker there. Might make the routine a little less efficient but you wouldn't have to worry about getting an error.

Jack S wrote on 10/4/2024, 8:41 AM

@jetdv Yes, I did think about using the marker timecodes, but then I thought "what if the user moved a marker before pressing the script delete button". If that happened the delete method wouldn't see a marker at the position specified by the array element, resulting in a crash.
I'll see if I can figure a way to go through the array to check if there's a marker at an index specified by the current array element. If I could do that, I could bypass the 'markers.remove(index)' statement.

Last changed by Jack S on 10/4/2024, 8:42 AM, changed a total of 1 times.

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE

jetdv wrote on 10/4/2024, 7:06 PM

Remember, the "index" numbers can change. As soon as a marker is added, all markers after it have their index changed. If a marker is removed, all markers after it have their index changed...

Jack S wrote on 10/5/2024, 9:16 AM

@jetdv I think I may have got my facts wrong here. In my ignorance I thought I was addressing marker indexes from my array, but from what you've just stated, I can't be. I know that if I create, say 3 markers with my code, then create three more manually, I can use my delete code and just the ones I created with the code are deleted. I can even place a marker manually between the code created markers and the delete code deletes all the code made markers. The manually placed marker remains intact.
This is the array declaration:-

        public Marker[] myMarkers = new Marker[999];                            //Set up an array to hold marker positions
        int myMarkerIndex = 0;                                                  //Initialise an index for the marker array

I assumed that the array element was the index for the Marker. Is that correct?

This is my 'add marker' code:-

                        if (CreateMrkr.Checked)                                                 //Check whether a marker is to be created
                        {
                            Marker myMarker = new Marker(myVegas.Transport.CursorPosition);     //Create a marker at the final cursor position
                            myVegas.Project.Markers.Add(myMarker);                              //Add the marker
                            myMarkers[myMarkerIndex] = myMarker;                                //Update the marker array
                            myMarkerIndex++;                                                    //Increment the array index
                        }

And this is my delete marker Method:-

        public void btnDeleteMarkers_Click(object sender, EventArgs e)         //Called by the user to delete markers created by the tool
        {
            try
            {
                using (UndoBlock undo = new UndoBlock("Delete markers"))            //Enable Undo
                {
                    for (int i = 0; i < myMarkerIndex; i++)                         //Step through the Marker array. Because the array index was incremented ...
                    {                                                               //... after the last element was stored, we must stop the loop at the index minus 1
                        myVegas.Project.Markers.Remove(myMarkers[i]);                  //Remove markers added by the tool
                    }
                }
                SetFocus(new HandleRef(null, myVegas.MainWindow.Handle));           //Allow Ctr+Z for undo
            }
            catch (Exception ex)                                                    //Catch for a situation where there's a conflict between my array index and the marker index.
            {                                                                       //This usually happens when a T&T event addition is reversed with the Undo function.
                MessageBox.Show("An error occurred attempting to delete the marker(s). This can happen when a Titles & Text event is removed using Undo or Ctrl+Z"
                    , "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            myMarkerIndex = 0;                                              //When all markers have been removed, re-initialise the array index
            FillTheTimecodeArray();                                         //All the markers removed, we can now ensure that the array is empty
        }

All this works whether markers are added manually anywhere on the timeline after markers have been added by the code, or whether markers have been moved. The only time it doesn't work (Vegas crashes) is if the method that creates the markers is subject to an undo action. In this case, the array has already been updated with the inserted marker (which now isn't there due to the undo), so there's a conflict between the array contents and the actual markers.
As I said, the tool works correctly under normal conditions, so the error message is the only way of getting around the problem. Unless, of course, you can see where I'm gong wrong.
Thanks again.

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE

jetdv wrote on 10/5/2024, 5:55 PM

Your "index" number is the position in your array. The array position is holding the actual marker (which could be manually removed and cause the error when the delete routine is called.)

Jack S wrote on 10/6/2024, 8:15 AM

Thanks for the clarification. It seems like there's no solution to this Undo problem.
My workaround will have to suffice.

My system
Genshin Infinity Gaming PC
Motherboard Gigabyte H610M H: m-ATX w/, USB 3.2, 1 x M.2
Power Supply Corsair RM750X
Intel Core i7-13700K - 16-Core [8P @ 3.4GHz-5.4GHz / 8E @ 2.50GHz-4.20GHz]
30MB Cache + UHD Graphics, Ultimate OC Compatible
Case Fan 4 x CyberPowerPC Hyperloop 120mm ARGB & PWM Fan Kit
CPU Fan CyberPowerPC Master Liquid LITE 360 ARGB AIO Liquid Cooler, Ultimate OC Compatible
Memory 32GB (2 x 16GB) DDR5/5200MHz Corsair Vengeance RGB
MSI GeForce RTX 4060 Ti 8GB - Ray Tracing Technology, DX12, VR Ready, HDMI, DP
System drive 1TB WD Black SN770 M.2 NVMe PCIe SSD - 5150MB/s Read & 4900MB/s Write
Storage 2 x 2TB Seagate BarraCuda SATA-III 6.0Gb/s 7200RPM
Windows 11 Home (x64)
Monitors
Generic Monitor (PHL 222V8) connected to GeForce RTX 4060 Ti
Generic Monitor (SAMSUNG) connected to iGPU

Camcorder
SONY Handycam HDR-XR550VE