Community Forums Archive

Go Back

Subject: Closing Undo Wrapper corrupts IsModified
Posted by: nlamartina
Date: 1/15/2015 2:28:04 PM

I've been struggling to find either a reason or workaround for this, but have come up empty.

Basically, any time I close an undo wrapper, the IsModified property of the edited file gets corrupted. As an example:


bool fCancel = false;
int idUndo = file.BeginUndo(Script.Name);

// DO THINGS

file.EndUndo(idUndo, fCancel);


I can perform any number of editing actions at "DO THINGS", and all the while the IsModified stays true, but as soon as I use the EndUndo function, IsModified flips to false, even though the file is actually dirty (and the window in the interface has the dirty "*" showing). So if I try to close the file, it simply closes without warning about my unsaved changes.

If I manually undo the script with Ctrl+Z, the behavior corrects itself, and I can then use the script as many times as I want without IsModified status get errantly flipped. I've tried this a dozen different ways, and I can't find a workaround short of performing another editing action after closing the undo wrapper, but that ruins the point of what I'm trying.

I'm using Sound Forge 10, so I can expect that a fix won't be developed for this, but can anyone think of a workaround?

Message last edited on 1/20/2015 9:47:32 AM by nlamartina.
Subject: RE: Closing Undo Wrapper corrupts IsModified
Reply by: CharlesK
Date: 1/16/2015 1:01:04 AM

I had a similar problem. I don't fully understand the ins and outs, but here's what was given to me by a user on this forum and it worked for SF10 as well as SF11:

//Create undo wrapper
string szUndo = String.Format("Name Of Your Script");
int idUndo = file.BeginUndo(szUndo);

// Script work

//Close undo wrapper
file.EndUndo(idUndo, false);

The only difference I see is declaring your script name as a string instead of using Script.Name and using false instead of a variable.

Subject: RE: Closing Undo Wrapper corrupts IsModified
Reply by: nlamartina
Date: 1/20/2015 10:26:19 AM

I appreciate the help, but that doesn't seem to work. Do you have a script you can post that shows this solution works? Here's how I'm testing this:


using System;
using System.IO;
using System.Windows.Forms;
using SoundForge;

public class EntryPoint
{
public string Begin(IScriptableApp app)
{
ISfDataWnd wnd = app.ActiveWindow;
ISfFileHost file = wnd.File;

// Open the undo wrapper
//bool fCancel = false;
string szUndo = String.Format("A Name");
DPF("Outside the wrapper haven't started changes.\tisModified? {0}", file.IsModified);
int idUndo = file.BeginUndo(szUndo);
DPF("Wrapper opened, haven't changed anything yet.\tisModified? {0}", file.IsModified);

// Do something
SfAudioMarkerList Markers = file.Markers;
SfAudioMarker mk = new SfAudioMarker(0);
Markers.Add(mk);
DPF("Inside the wrapper, made changes.\t\tisModified? {0}", file.IsModified);

// Close the undo wrapper
//file.EndUndo(idUndo, fCancel);
file.EndUndo(idUndo, false);
DPF("Wrapper closed, made changes.\t\t\tisModified? {0}", file.IsModified);
return null;
}

public void FromSoundForge(IScriptableApp app)
{
ForgeApp = app; //execution begins here
app.SetStatusText(String.Format("Script '{0}' is running.", Script.Name));
string msg = Begin(app);
app.SetStatusText(msg != null ? msg : String.Format("Script '{0}' is done.", Script.Name));
}
public static IScriptableApp ForgeApp = null;
public static void DPF(string fmt, object o) { ForgeApp.OutputText(String.Format(fmt, o)); }
} //EntryPoint


So keeping it really simple; all it does it open the undo wrapper, drop a marker, then close it. Between each of these steps, I output the IsModified status to the Script Editor console. I've made the suggested changes you proposed.

So first time I run it:

Outside the wrapper haven't started changes. isModified? False
Wrapper opened, haven't changed anything yet. isModified? False
Inside the wrapper, made changes. isModified? True
Wrapper closed, made changes. isModified? False


Okay, so we can clearly see the problem, isModified shouldn't have flipped to false just because the undo wrapper was closed. If I try to close the file, I don't get a warning to commit unsaved changes. Alright, let's press undo, run it again, next results:

Outside the wrapper haven't started changes. isModified? True
Wrapper opened, haven't changed anything yet. isModified? True
Inside the wrapper, made changes. isModified? False
Wrapper closed, made changes. isModified? True


Alright, this is starting to look fishy. The statements 1, 2, and 4 are fine since the file is already technically dirty from the last run, but statement 3 is clearly wrong. However, at least if I try to close the file, I get the file save prompt. Let's undo and try it one more time:

Outside the wrapper haven't started changes. isModified? True
Wrapper opened, haven't changed anything yet. isModified? True
Inside the wrapper, made changes. isModified? True
Wrapper closed, made changes. isModified? True


Okay, now this is correct. The file starts and ends as dirty since we were messing with it from previous steps, and it stays dirty through the entire process. If we undo and run again and again, this will be the result we get. The problem however is still there, regardless if the int of my undo wrapper is derived from Script.Name or just another string (same with closing the wrapper with an explicit "false" instead of a variable).

Any other suggestions?

Message last edited on 1/20/2015 10:30:29 AM by nlamartina.
Subject: RE: Closing Undo Wrapper corrupts IsModified
Reply by: CharlesK
Date: 1/21/2015 11:22:28 PM

I did further testing and found out you are correct. My script does edits before and after the wrapper, and I could step back through the edits using Undo but the file changed status did not track properly. I'm using SF11. If I could cheat, I'd test for the file changed status after closing the wrapper and force it to be changed.

Message last edited on 1/21/2015 11:23:51 PM by CharlesK.

Go Back