Community Forums Archive

Go Back

Subject:RegionList.CopyToClipboard
Posted by: David Thiel
Date:6/2/2006 8:12:47 AM

I'm having problems with the RegionList.CopyToClipboard command, so
hopefully can someone can help me out. The point of my script is to
write the region lists of all open files to a text file. I can get
the first one to paste correctly but the following region lists will
not go quite as well. The first line of the following region lists
will paste correctly, but the table of markers/regions will simply be
the same as the first region list.

Here is my code:

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

// Open one or more files containing markers before running the script
// BEHAVIOR:
// - Calls "Special | Regions List | Markers to Regions"
// - Calls "Tools | Extract Regions"
// - The script does not automatically save the changes that are made
to each file.
//NOTE: Look for MODIFY HERE to quickly update the Script Args with
your own preferences

public class EntryPoint {
public string Begin(IScriptableApp app) {

//start MODIFY HERE
bool fAllFiles = GETARG("All", true); //set to true to process
every open file

// GETARG is a function that defines the default script settings.
You can use the Script Args field to over-ride
// the values within GETARG().
// Example: To over-ride GETARG(Key, valueA), type Key=valueB in
the Script Args field.
// Use an ampersand (&) to separate different Script
Args: KeyOne=valueB&KeyTwo=valueC

//Example Script Args: All=true

//end MODIFY HERE

ISfFileHostList fileList = app.Files;

if (fileList.Count == 0)
{
DPF("Open a file containing markers before running this
script. Script stopped.");
return "Open a file containing markers before running this
script. Script stopped.";
}

int filesChanged = 0;
FileInfo t = new FileInfo("TEST.txt");
StreamWriter Tex = t.AppendText();

for (int i = 0; i < fileList.Count; i++)
{
SfStatus result;
if ( ! fAllFiles && ! fileList.IsCurrent)
continue;

if (fileList.MarkerCount <= 0)
{
DPF(fileList.Filename + " does not contain any markers.");
continue;
}

fileList.IsCurrent = true;
result = app.DoMenuAndWait("RegionList.CopyToClipboard", true);

if (result == SfStatus.Success)
{
// Write Info to Text File
Tex.Write(Clipboard.GetDataObject().GetData
(DataFormats.Text).ToString());
DPF(Clipboard.GetDataObject().GetData
(DataFormats.Text).ToString());
Clipboard.SetDataObject(new DataObject("CLEAR"));
DPF(Clipboard.GetDataObject().GetData(DataFormats.Text).ToString());
DPF(" ");
Tex.Flush();
// End Info to Text File

filesChanged++;
}
else

DPF("The clipboard does not contain any text");

}
DPF(String.Format("{0} file(s) affected. Script {1} is done.",
filesChanged, Script.Name));
return String.Format("{0} file(s) affected. Script {1} is done.",
filesChanged, Script.Name);
}

public void FromSoundForge(IScriptableApp app) {
ForgeApp = app; //execution begins here
app.SetStatusText(String.Format("Script '{0}' is running.",
Script.Name));
string szMessage = Begin(app);
app.SetStatusText((szMessage != null) ? szMessage : String.Format
("Script '{0}' is done.", Script.Name));
}
public static IScriptableApp ForgeApp = null;
public static void DPF(string sz) { ForgeApp.OutputText(sz); }
public static void DPF(string fmt, object o) { ForgeApp.OutputText
(String.Format(fmt,o)); }
public static void DPF(string fmt, object o, object o2)
{ ForgeApp.OutputText(String.Format(fmt,o,o2)); }
public static void DPF(string fmt, object o, object o2, object o3)
{ ForgeApp.OutputText(String.Format(fmt,o,o2,o3)); }
public static string GETARG(string k, string d) { string val =
Script.Args.ValueOf(k); if (val == null || val.Length == 0) val = d;
return val; }
public static int GETARG(string k, int d) { string s =
Script.Args.ValueOf(k); if (s == null || s.Length == 0) return d;
else return Script.Args.AsInt(k); }
public static bool GETARG(string k, bool d) { string s =
Script.Args.ValueOf(k); if (s == null || s.Length == 0) return d;
else return Script.Args.AsBool(k); }
} //EntryPoint

Subject:RE: RegionList.CopyToClipboard
Reply by: _TJ
Date:6/2/2006 3:38:02 PM

try adding a call to app.DoEvents(...) after you set fileList.IsCurrent = true;

I suspect that the regions list needs a chance to notice that the current file has changed.

But I have to ask, what are you really trying to accomplish here? I suspect that your end goal isn't really a file containing the regions list as as text, and that if we knew what you really needed, there would be a much better way to do it.

tj

Subject:RE: RegionList.CopyToClipboard
Reply by: David Thiel
Date:6/2/2006 7:22:45 PM

All I really need to do is write all the region lists of the open
files to a text file... Yes, it's that simple. I may want to
organize the list a certain way, but that's not really important at
this point. I'm also not sure how to implement the app.DoEvents
method you mentioned. I tried "app.DoEvents
(app.Win32Window.Handle);" but I'm guessing I'm not using the correct
window handle. Thanks

Subject:RE: RegionList.CopyToClipboard
Reply by: _TJ
Date:6/6/2006 3:03:44 PM

All I really need to do is write all the region lists of the open
files to a text file... Yes, it's that simple. I may want to
organize the list a certain way, but that's not really important at
this point.

Actually, it is important. Or at least I think it is. A lot of the time when we get questions like this, what is really happening is that a Sound Forge user has some task that they need to accomplish, and they decide that a part of doing that task is to use some feature of Sound Forge, and then they get stuck and begin asking questions (or requesting new features).

Many times, however, the thing that they are asking how to do isn't really a necessary part of their actual task, it's a part of the process that they have chosen to accomplish that task. But it's not really a part of the actual task.

Your request has all of the earmarks of that sort of thing. For instance. Why would it be the files you have open in Sound Forge that you want to get regions for? Did you open them in Sound Forge for some other reason and then coincidently need to print out regions? Did you just get finished creating the regions, for instance? Or did you open the files into Sound Forge just before running your script?

You see, one of the things that Scripts are good at is opening files, so if a part of your task is opening the files before you run the script, then it might be better to have the script open the files instead.

Conversely, if these are all files that you have just created or added regions to then it might be better to have a script that you run once per file when you are done with the file rather than once for all the files you have open.

Another question that comes to mind is - How can you be sure that you want to get regions for ALL of the files that Sound Forge has open? How can you be sure that you don't have a file open that you DON'T want to be part of your output? Are you setting yourself up for having to close some files before you run the script?

And then there is the formatting of the output. Do you really want the region list formatted in that way? or do you just not care how it is formatted? Does it need to be human readable? or are you really creating a table of data to be read by some other program.

The reason this is significant, is because it's actually pretty easy to print out the region list using script commands without using the clipboard, but at that point, the formatting of the data is going to be controlled by the script, and it will be less work to format it more simply than what the RegionList.ToClipboard does. But depending on what you plan to do with the list of regions, more simple output may be better.

Here's a script that prints out all of the regions in all of the open files using the Markers list on the ISfFileHost object instead of RegionList.CopyToClipboard, the formatting is a bit different.


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

public class EntryPoint {
public string Begin(IScriptableApp app) {

int cFilesWithMarkers = 0;

string sLogFile = PromptForLogFile(@"c:\test.txt");
if (null == sLogFile)
return "no output filename";

FileInfo fi = new FileInfo(sLogFile);
StreamWriter stm = fi.AppendText();

foreach (ISfFileHost file in app.Files)
{
if (file.MarkerCount > 0)
{
WriteMarkersToStream(stm, file);
cFilesWithMarkers++;
}
else
{
DPF("'{0}' does not contain any markers.", file.Filename);
}
}
stm.Close();

DPF("{0} file(s) affected", cFilesWithMarkers);
return String.Format("{0} file(s) affected. Script {1} is done.", cFilesWithMarkers, Script.Name);
}

public void WriteMarkersToStream(StreamWriter stm, ISfFileHost file)
{
stm.WriteLine(String.Format("\"{0}\", {1} markers and regions", file.Filename, file.MarkerCount));

ISfPositionFormatter PosFmt = file.Formatter;

int ii = 0;
foreach (SfAudioMarker mk in file.Markers)
{
string str;
if (mk.HasLength)
str = String.Format("{0:d3} {2}, {3}, \"{1}\"", mk.Ident, mk.Name, PosFmt.Format(mk.Start), PosFmt.Format(mk.Length));
else
str = String.Format("{0:d3} {2}, , \"{1}\"", mk.Ident, mk.Name, PosFmt.Format(mk.Start));

stm.WriteLine(str);
++ii;
}

stm.WriteLine("");
stm.Flush();
}

public string PromptForLogFile(string sDefault)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Title = "Choose output file.";
sfd.FileName = sDefault;
sfd.Filter = "Text (*.txt)|*.txt";
sfd.DefaultExt = "txt";
if (DialogResult.OK != sfd.ShowDialog())
return null;

return sfd.FileName;
}

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


Message last edited on6/6/2006 4:56:04 PM by_TJ.
Subject:RE: RegionList.CopyToClipboard
Reply by: David Thiel
Date:6/8/2006 8:47:57 AM

Hey SonyTJ,

Well thanks for the help and of course for the script you posted. To tell you the truth, I just need the exact formatting of the RegionList.CopyToClipboard. I can try and modify the script you posted to reflect that although the RegionList.CopyToClipboard scripting might be a little easier.

Basically, all open files, RegionList.CopyToClipboard written to one text file with an empty line between pastes. I have an external program that reads the text file in that way. For a long time I've been going through each file and copying the regions and pasting to a text file manually. I am really just looking for a way to simplify that. So in terms of formatting, I need it exactly the way RegionList.CopyToClipboard pastes it. Thanks.

Go Back