How to use GetDbIndex()?

On 01/11/2013 at 10:11, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   13 
Platform:   Windows  ;   
Language(s) :     C++  ;

---------
Hi,

I'm not getting the expected results from the GetDbIndex() function.
What I'm trying to do is search through the Content Browser presets (The saved items in these folders).
But that function is always returning the value of 1. :dizzy_face:

How do I get the actual correct Index# for the CB items?
Without understanding how it works. And how to get a correct IndexDb#. I can't use most of the other CB functions.

This example sort of works. And gets the PresetName of the object listed in the user_dir path
However. The IndexDb# seems to be wrong (it's always 1)?
I can't use it to search for the other items. Or even get the next saved item in the same folder.

    
#include "lib_browser.h"  
  
Filename user_dir = "preset://user.lib4d/Objects/Cube";            //The URL path to the object      
  SDKBrowser *cb = NULL;                                             //Create a Content Browser instance  
  cb->OpenNewBrowser(user_dir.GetString(), 0);                       //Notice how we use GetString() function  
   
  Bool exists = cb->ExistsPreset(user_dir.GetString());              //Checks if the .lib4d object or directory exists or not  
  GePrint(LongToString(exists));                                     //Prints 1. Confirming that the object does exist  
  
  String name = "";                                                  //The string variable we'll put the preset name in later on  
  
  //Get the DbIndex# for the presets  
  LONG index = cb->GetDbIndex(user_dir.GetString(), 0);              //<---Always returns 0 or 1?   Why not 2,3,4,etc.....?  
  GePrint(LongToString(index));  
  
  cb->GetPresetName(index, user_dir.GetString(), LanguageUS, name);  //Results in getting the name "Cube"  
  GePrint(name);

-ScottA

On 04/11/2013 at 02:17, xxxxxxxx wrote:

Hi,

GetDbIndex() always returns 1 (or UserPresetDb) for the user preset library.
And if you need to browse through the items you have to use the class SDKBrowsePresets.

On 04/11/2013 at 08:30, xxxxxxxx wrote:

Hi Yannick,
Nice to hear from you. I thought you were abducted by aliens or something. :wink:

We have a Bool function called ExistsPreset() for checking if something exits.
And the docs say GetDbIndex() is supposed to return a LONG value.
So if GetDbIndex() is indeed supposed to return 1. Then I don't understand how that is of any use to us?
Or how to use it in the other CB functions?

Example:

    Filename broadDir = "preset://Broadcast.lib4d"; //Start at the Broadcast preset  
  
  SDKBrowserURL url(broadDir);            //The URL for the Broadcast preset  
  
  SDKBrowsePresets *browse = NULL;        //Create an instance of the browser class  
  
  browse->Alloc(?);                      //<----What do I put in the param?  
  browse->GetNext(url, ?);               //<----What do I use for the pluginID param?  
  browse->Free(browse);

On a separate issue.
I'm also very confused about how to write CB plugins.
There's several classes throughout the SDK. And I can't make sense out of how to use them.
-SDKBrowserPluginInterface
-SDKBrowserPluginInterfaceInfo
-SDKBrowserPreviewDialog
-RegisterPresetLibrary(const SDKBrowserURL& domain, const String& name, const Filename& f)

If I wanted to save a preset using: static Bool SavePresetObject(const SDKBrowserURL& url, BaseList2D* bl).
Do I have to write a full blown SDKBrowserPluginInterface plugin to do that?
Or can I do this without writing a plugin?

I do have an SDKBrowserPluginInterface plugin example that was posted here years ago by a user. But it's not a complete working example. It's just a basic framework with empty methods.
It complies but it doesn't do anything.

I'm just generally confused. And looking for clarification.
The docs don't really explain things very well.

-ScottA

On 05/11/2013 at 04:19, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Nice to hear from you. I thought you were abducted by aliens or something. :wink:

We aren't allowed to browse the main preset database (Broadcast.lib4d, Prime.lib4d, Studio.lib4d etc). SDKBrowser::GetDbIndex() returns 0 in this case and SDKBrowsePresets::Alloc() returns a null pointer.

Here's how to use SDKBrowsePresets:

String path("preset://user.lib4d/Objects");
Int32 presetIndex = SDKBrowser::GetDbIndex(path);
if (presetIndex!=SDKBrowser::InvalidPresetDb)
{
  AutoAlloc<SDKBrowsePresets> presets(presetIndex);
  if (presets==nullptr)
    return FALSE;
  
  SDKBrowserURL url;
  Int32 plugin_id;
  while (presets->GetNext(url, plugin_id))
    GePrint(url.GetString());
}

Note that SDKBrowsePresets only works with an entire preset database but you can filter the presets with their URLs.

Originally posted by xxxxxxxx

If I wanted to save a preset using: static Bool SavePresetObject(const SDKBrowserURL& url,BaseList2D* bl).
Do I have to write a full blown SDKBrowserPluginInterface plugin to do that?
Or can I do this without writing a plugin?

Yes, you don't need a plugin to use SDKBrowser::SavePresetObject().
You have just to make sure to create a preset node with SDKBrowser::CreatePresetNode() before calling it.

On 05/11/2013 at 10:40, xxxxxxxx wrote:

Thanks.
The browsing is working now. But I still can't create my own presets.

I'm trying to create my own preset named "MyPreset" with a folder in it called "MyObject".
Then save an object in the scene to this new "MyObject" folder.
But the problem is the CreatePresetNode() function requires index value, and plugin_id values. And they don't exist yet.
I can't figure out how to deal with this problem.

    String path("preset://MyPresets.lib4d/MyObject");    //The URL to the preset I want to create (it doesn't exist yet)  
  LONG presetIndex = SDKBrowser::GetDbIndex(path);     //Gets the preset's index (1=found, 0=Not found)  
  
  SDKBrowserURL url;                                   //The variable we will store what we find while browsing the preset  
  
  LONG plugin-id = NULL;  
  
  BaseObject *obj = doc->GetFirstObject();             //The scene object I want to save to the preset folder named "MyPreset/MyObject"  
  if(!obj) return FALSE;  
  
  SDKBrowser::CreatePresetNode(presetIndex, url, plugin_id, 0); //Create the MyPreset preset folder  
  SDKBrowser::SavePresetObject(url, obj);                       //Save the object to the new preset

I don't understand how we're supposed to create our own presets, directories(folders) within the custom preset, and lastly, save objects within these folders.

-ScottA

On 06/11/2013 at 03:16, xxxxxxxx wrote:

Hi,

You can print the plugin types or plugin IDs of the presets in the browse loop:

AutoAlloc<SDKBrowsePresets> presets(SDKBrowser::UserPresetDb);
if (presets==nullptr)
  return false;
  
SDKBrowserURL url;
Int32 plugin_id;
while (presets->GetNext(url, plugin_id))
  GePrint(url.GetString() + " - " + String::IntToString(plugin_id));

You can see that folders have the ID 0.
In fact, except the ID for folders all the standard content browser plugin types are declared in lib_browser.h but not well documented and referenced:

//----------------------------------------------------------------------------------------
// Interface base class of a browser plugin
//----------------------------------------------------------------------------------------
enum // basic plugins for the browser
{
	CBPluginTypeImage = 1018021,
	CBPluginTypeMovie = 1018022,
	CBPluginTypeScene = 1018023,
	CBPluginTypeCategory = 1018024,
	CBPluginTypeCatalog = 1018025,
	CBPluginTypeUnknown = 1018026,
	CBPluginTypeFolder  = 1018027,
	CBPluginTypeMaterial = 1018028,
	CBPluginTypeDummy = 1018029,
	CBPluginTypeDefaults = 1018030,
	CBPluginTypeFilePreset = 1018031,
	CBPluginTypeObjectPreset = 1018107,
	CBPluginTypeMaterialPreset = 1018108,
	CBPluginTypeTagPreset = 1018109,
	CBPluginTypeRenderDataPreset = 1018110,
	CBPluginTypeShaderPreset = 1018111,
	CBPluginTypeVideoPostPreset = 1018112,
	CBPluginTypeXPressoPreset = 1018113,
	CBPluginTypePresetLibrary = 1018760,
	CBPluginTypeCatalogFile = 1018761,
	CBPluginTypeScriptFile = 1018762
};

So here's how we can create a new preset library and add an object to it:

// Get the active object
BaseObject* op = doc->GetActiveObject();
  if (op==nullptr)
    return true;
  
String path("preset://MyPresets");
SDKBrowser::CreatePresetNode(SDKBrowser::UserPresetDb, path, 0);
  
path += "/MyObject";
SDKBrowser::CreatePresetNode(SDKBrowser::UserPresetDb, path, CBPluginTypeObjectPreset);
  
if (SDKBrowser::SavePresetObject(path, op))
  GePrint("Object Preset Saved Successfully");

Note that CreatePresetNode() returns false even if it was successfull.
I even tried to check if the preset node was created but ExistsPreset() returns false too.

On 06/11/2013 at 08:06, xxxxxxxx wrote:

Awesome!
I knew about the plugin_ids already. But I just couldn't figure out how to bring everything together.

I'm posting all of my Content Library notes here. So other people have working code examples to play around with:

//CallCommand(300000112); //The save Object Preset command  
//CallCommand(1018429)    //New Preset Library command  
//CallCommand(1018428)    //New Catalog command  
  
//Items can be saved into regular folders. Or as library presets that have the .lib4d file extention  
//There are two places that library presets are saved. The Appdata folder, and the Program Files\Maxon\Your C4D version\library\browser folder  
  
Examples:  
  
  Filename user_dir = "preset://Studio.lib4d/Character/Flabio.c4d";  //Gets the flabio character preset  
                                                                     //This folder is located in the Program Files\Maxon\Your C4D version\library\browser folder  
  
  Filename user_dir = "preset://user.lib4d/Objects/Cube.c4d";        //Gets a cube saved to the "User" folder using the "Save Object Preset.." command in C4D  
                                                                     //This folder is located in the AppData\Roaming\Maxon\Your C4D version\library\broswer folder  
  
  
  
  
  
  
  
//This code opens the content browser window at a specific standard type folder and file location (if it exists)  
//*WARNING!! The filepath used here is for the regular folders found in Program Files\Maxon\libraries folder..Do not use C4D_PATH_LIBRARY_USER!!  
//*The saved library items in the AppData folder are accessed using this type of syntax: "preset://user.lib4d/Objects"  
  
#include "lib_browser.h"  
  
  
  //This looks for a regular type of directory..NOT!! for a .lib4d type of directory  
  Filename user_dir = GeGetC4DPath(C4D_PATH_LIBRARY) + "Scott" + "MyScene.c4d";  
  
  SDKBrowser *cb = NULL;                            //Create a ContentBrowser instance  
  cb->OpenNewBrowser(user_dir, 0);                  //Opens the CB at the specific folder  
  
  
  
  
  
  
//This code opens the ContentBrowser window at the User/Objects .lib4d type folder(if it exists) which is in the AppData folder  
//IMPORTANT! You have to use GetString() on the URL paths for the .lib4d presets  
  
#include "lib_browser.h"  
  
  Filename user_dir = "preset://user.lib4d/Objects"; //The URL path to a specific .lib4d type directory      
  SDKBrowser *cb = NULL;                             //Create a ContentBrowser instance  
  cb->OpenNewBrowser(user_dir.GetString(), 0);       //Notice how we use GetString() function  
  
  
  
  
  
  
  
//This code shows how to get a specific preset   
  
#include "lib_browser.h"  
  
  Filename user_dir = "preset://user.lib4d/Objects/Cube"; //The Filename path to a specific folder/saved item  
  SDKBrowser *cb = NULL;                                  //Create a ContentBrowser instance  
  cb->OpenNewBrowser(user_dir.GetString(), 0);            //Notice how we use GetString() function  
  SDKBrowserURL url(user_dir);                            //Gets the URL for the preset      
  GePrint(url.GetString());                               //Prints file://localhost/preset://user.lib4d/Objects/Cube  
  GePrint(url.GetDirectory().GetString());                //Prints file://localhost/preset://user.lib4d/Objects  
  
  String item = url.GetFileString();                      //Gets the name of the preset without the path  
  
  GePrint(item);                                          //Prints Cube  
    
  SDKBrowserURL dir = url.GetDirectory();                 //Get the parent folder of the item  
  GePrint(dir.GetString());                               //Prints file://localhost/preset://user.lib4d/Objects  
  Bool exists = cb->ExistsPreset(user_dir.GetString());   //Check if a preset exists  
  GePrint(LongToString(exists));  
  
  Bool empty = url.GetDirectory().Content();      //<---Something is wrong here..always true!!??  
  GePrint(LongToString(empty));  
  
  
  
  
  
  
  
//This code saves *ONLY* the the active object in the scene to a custom folder on your HD (NOTE: This does not save to any of the .lib4d folders)  
//In this example we create a new custom folder named "Scott" in the AppData\libraries\ folder  
//NOTE: The custom folder is overwritten if it already exists...Or...is created if it doesn't already exist  
  
#include "lib_browser.h"  
  
  Filename library_dir = GeGetC4DPath(C4D_PATH_LIBRARY_USER);              //The library folder in the AppData folder   
  
  GeFCreateDir(library_dir + Filename("Scott"));                           //Creates a new sub folder in the library folder named "Scott"  
  
  Filename user_dir = GeGetC4DPath(C4D_PATH_LIBRARY_USER) + "Scott" + "MyScene.c4d"; //The full path. Including the file's name to be saved  
  
  BaseObject *obj = doc->GetActiveObject();                                 //Get the active object  
  if (!obj) return FALSE;  
  
  BaseDocument *tempDoc = BaseDocument::Alloc();                            //Create a temporary document  
  if (!tempDoc) return FALSE;  
  
  BaseObject *clone = (BaseObject* )obj->GetClone(COPYFLAGS_0,NULL);         //Clone the active object  
  if (!clone)  
  {  
      BaseDocument::Free(tempDoc);  
      return FALSE;  
  }  
  
  tempDoc->InsertObject(clone,NULL,NULL);                                   //Insert the clone into the temp. document  
  SaveDocument(tempDoc, user_dir, SAVEDOCUMENTFLAGS_0, FORMAT_C4DEXPORT);   //Save the .c4d file in the desired folder  
  BaseDocument::Free(tempDoc);                                              //Free the tempDoc memory pointer's memory  
  
  
  
  
  
  
  
//This code loads a preset from the user.lib4d file found in the AppData folder  
//Not from a regular folder in the programs tree  
  
  Filename librarypath = "preset://user.lib4d/Objects/Cube";     //The specific saved object inside of the User/Objects folder to load  
  MergeDocument(doc, librarypath, SCENEFILTER_MERGESCENE, NULL);  
  LoadFile(librarypath);  
  
  
  
  
//These are the CB presets we can look through  
  
CBPluginTypeImage=1018021,  
CBPluginTypeMovie=1018022,  
CBPluginTypeScene=1018023,  
CBPluginTypeCategory=1018024,  
CBPluginTypeCatalog=1018025,  
CBPluginTypeUnknown=1018026,  
CBPluginTypeFolder=1018027,  
CBPluginTypeMaterial=1018028,  
CBPluginTypeDummy=1018029,  
CBPluginTypeDefaults=1018030,  
CBPluginTypeFilePreset=1018031,  
CBPluginTypeObjectPreset=1018107,     //Gets the objects presets. Including the User/Objects folder: preset://user.lib4d/Objects/the objects you've saved  
CBPluginTypeMaterialPreset=1018108,   //Gets the materials presets  
CBPluginTypeTagPreset=1018109,        //Gets the User/Tags folder:   EX: preset://user.lib4d/Tags/the tags you've saved  
CBPluginTypeRenderDataPreset=1018110,  
CBPluginTypeShaderPreset=1018111,     //Gets the brick shaders:      EX: preset://brick shader.lib4d/Purely Procedural/Tiles 01  
CBPluginTypeVideoPostPreset=1018112,  
CBPluginTypeXPressoPreset=1018113,  
CBPluginTypePresetLibrary=1018760,  
CBPluginTypeCatalogFile=1018761,  
CBPluginTypeScriptFile=1018762,  
  
  
  
//This code prints the plugin types (plugin IDs) of the presets in the browse loop  
//Note that folders have the ID 0  
  
  AutoAlloc<SDKBrowsePresets>presets(SDKBrowser::UserPresetDb);  
  if(presets==nullptr) return false;  
  
  SDKBrowserURL url;  
  LONG plugin_id;  
  while (presets->GetNext(url, plugin_id))  
  GePrint(url.GetString() + " - " + String::IntToString(plugin_id));  
  
  
  
  
  
  
  
  
//Here is an example that displays all object presets in a pop up window. And does something when you select one of them  
//The CallBack method is where you put the task that you want to do when you select one of the presets  
//For the "presettypeid" parameter you have to pass a valid browser preset plugin ID. The one returned in SDKBrowserPluginInterfaceInfo::GetPluginID()  
//So for instance if you have written your own preset plugin. You would use the ID of your preset plugin  
  
#include "lib_browser.h"  
  
//This is the callback method that the BrowserLibraryPopup() function requires to peform your task  
//Reminder: Put this at the top of your plugin code... *NOT* inside of any classes  
void browserCB(void* userdata, LONG cmd, SDKBrowserURL& url)  
{  
  if(url.GetString() == "preset://user.lib4d/Objects/Cube")  //If you clicked on this specific preset  
  {  
      GePrint(url.GetString());                              //Do something...  
  }  
}  
  
Bool MenuTest::Execute(BaseDocument *doc)  
{  
  BaseContainer state;  
  GetInputState(BFM_INPUT_MOUSE, 0, state);    //Gets the up/down state of the LMB  
  LONG mx = state.GetReal(BFM_INPUT_X);        //Get the X&Y position of the mouse  
  LONG my = state.GetReal(BFM_INPUT_Y);  
  
  LONG MYWINDOWID = 1000;                      //This can be any number you like. The window just needs a unique ID#  
  BrowserLibraryPopup(mx, my, 200, 200, MYWINDOWID, CBPluginTypeObjectPreset, NULL, browserCB);  
         
  return TRUE;  
}  
  
  
  
  
  
  
  
//This is how to search through the CB presets(NOTE: we can't search the built-in presets Studio.lib4d, etc...)  
//SDKBrowsePresets only works with an entire preset database. But you can filter the presets with their URLs  
  
  String path("preset://user.lib4d/Objects");          //The URL to the User preset called "Objects"  
  
  LONG presetIndex = SDKBrowser::GetDbIndex(path);     //Gets the preset's index(1=found, 0=Not found)  
  
  if (presetIndex != SDKBrowser::InvalidPresetDb)      //If the value of presetIndex == 1  
  {  
      AutoAlloc<SDKBrowsePresets>presets(presetIndex); //Create an instance of the SDKBrowsePresets class  
      if (presets == nullptr) return FALSE;            //If the instance fails to be created. End the program  
  
      SDKBrowserURL url;                               //The variable we will store what we find while browsing the preset  
      LONG plugin_id;  
      while (presets->GetNext(url, plugin_id)) { GePrint(url.GetString()); } //Print all the items in this preset(the User folder)  
  }  
  
  
  
  
  
  
  
  
  
//This creates a custom preset in the ContentBrowser  
//Then it creates a custom folder in the preset   
//Then it saves the active object to that new folder  
  
  //The object that we will save to a new preset library  
  BaseObject *obj = doc->GetActiveObject();  
  if(!obj) return FALSE;   
  
  //The name for the new preset  
  String presetName = "MyPreset";  
  
  //The path to the library/browser folder in AppData  
  Filename cbPath = GeGetC4DPath(C4D_PATH_LIBRARY_USER);  
  if (!cbPath.Content()) return SDKBrowser::InvalidPresetDb;  
  
  //The full path to the new preset  
  String fullPath = cbPath.GetString() + "//browser//" + presetName + ".lib4d";  
  
  //The path to the new preset(needed for the RegisterPresetLibrary() function next)  
  String dbUrl = "preset://" + presetName + ".lib4d";  
  
  //We have to register the new preset using RegisterPresetLibrary()  
  //If we don't register it. The preset will disappear when we close C4D   
  LONG dbIndex = SDKBrowser::RegisterPresetLibrary(dbUrl, presetName, fullPath);  
  
  //Create a URL type variable using the location of the newly created preset  
  //This will be anew folder inside of the preset where the active object will be saved  
  SDKBrowserURL url(String("preset://MyPresets.lib4d/MyObject"));  
  
  //Get the database index for the newly created preset  
  LONG index = SDKBrowser::GetDbIndex(String("preset://MyPresets.lib4d"));  
  
  //Add the object to the preset library  
  SDKBrowser::CreatePresetNode(index, url, CBPluginTypeObjectPreset);  
  SDKBrowser::SavePresetObject(url, obj);  
  
  
  
  
  
  
  
  
  
//This is how to create and add a new custom preset in AppData using custom methods  
  
//A custom method that creates a new CB preset which is located in the AppData folder  
Bool CreatePresetLibrary(String dbName)  
{  
  //The preset library is created in the user directory "library/browser" folder  
  
  Filename dbPath = GeGetC4DPath(C4D_PATH_LIBRARY_USER);  
  if (!dbPath.Content()) return SDKBrowser::InvalidPresetDb;  
  
  dbPath += "//browser";  
  dbPath += "//" + dbName + ".lib4d";  
  String dbUrl("preset://" + dbName + ".lib4d");  
  
  LONG dbIndex = SDKBrowser::RegisterPresetLibrary(dbUrl, dbName, dbPath);  
  
  return dbIndex != SDKBrowser::InvalidPresetDb;  
}  
  
  
  
//A custom method that adds a new CB preset  
Bool AddObjectPreset(BaseObject*op, LONG dbIndex, SDKBrowserURL url)  
{  
  SDKBrowser::CreatePresetNode(dbIndex, url, CBPluginTypeObjectPreset);  
  return SDKBrowser::SavePresetObject(url, op);  
}  
  
  
  
//This is how to use the above custom methods to create & add a new custom preset  
Bool MenuTest::Execute(BaseDocument* doc)  
{  
  //Create a preset library named "MyPresets"  
  if (!CreatePresetLibrary("MyPresets")) return true;  
  
  //Get the active object  
  BaseObject* op = doc->GetActiveObject();  
  if (op == nullptr) return true;  
  
  //Create a URL within the previously created preset to save the active object to  
  SDKBrowserURL url(String("preset://MyPresets.lib4d/MyObject"));  
  
  //Get the preset library database index  
  LONG index = SDKBrowser::GetDbIndex(String("preset://MyPresets.lib4d"));  
  
  //Finally add the object to the preset library  
  if (AddObjectPreset(op, index, url))  
  {  
      GePrint("Object \"" + op->GetName() + "\" Saved to Preset \"" + url.GetString() + "\" Successfully");  
  }  
  
  return true;  
}  

Thank You Yannick,
-ScottA

On 06/11/2013 at 10:57, xxxxxxxx wrote:

Hi,

I wasn't happy with my previous code because it wasn't creating a preset library .lib4d file and also the preset wasn't saved between sessions.

So here's below some code to create a preset library and to add an object to it. It works fine and the preset is saved as expected.
It wouldn't be too hard to add some code to add materials, files to the preset library.

Bool CreatePresetLibrary(String dbName)
{
  // The preset library is created in the user directory "library/browser" folder
  
  Filename dbPath = GeGetC4DPath(C4D_PATH_LIBRARY_USER);
  if (!dbPath.Content())
    return SDKBrowser::InvalidPresetDb;
  
  dbPath += "//browser";
  dbPath += "//" + dbName + ".lib4d";
  String dbUrl("preset://" + dbName + ".lib4d");
  
  Int32 dbIndex = SDKBrowser::RegisterPresetLibrary(dbUrl, dbName, dbPath);
  
  return dbIndex!=SDKBrowser::InvalidPresetDb;
}
  
Bool AddObjectPreset(BaseObject*op, Int32 dbIndex, SDKBrowserURL url)
{
  SDKBrowser::CreatePresetNode(dbIndex, url, CBPluginTypeObjectPreset);
  return SDKBrowser::SavePresetObject(url, op);
}
  
Bool MenuTest::Execute(BaseDocument* doc)
{
  // Create a preset library named "MyPresets"
  if (!CreatePresetLibrary("MyPresets"))
    return true;
  
  // Get the active object
  BaseObject* op = doc->GetActiveObject();
  if (op==nullptr)
    return true;
  
  // Create a URL within the previously created preset to save the active object to
  SDKBrowserURL url(String("preset://MyPresets.lib4d/MyObject"));
  
  // Get the preset library database index
  Int32 index = SDKBrowser::GetDbIndex(String("preset://MyPresets.lib4d"));
  
  // Finally add the object to the preset library
  if (AddObjectPreset(op, index, url))
    GePrint("Object \"" + op->GetName() + "\" Saved to Preset \"" + url.GetString() + "\" Successfully");
  
  return true;
}

On 06/11/2013 at 12:38, xxxxxxxx wrote:

Ok. Thanks.
I will add this one to my notes as well.

-ScottA