CustomSortExtensionHandler.jsx
Summary
Demonstrates how to implement a custom sorting and filters with a node-handling extension.
See:
Class Summary
|
CustomSortExtensionHandler |
Demonstrates how to implement a custom sorting and filters with a node-handling extension. |
function CustomSortExtensionHandler() {
$.level = 1;
this.requiredContext = "\tNeed to be running in context of Bridge\n";
}
CustomSortExtensionHandler.prototype.run = function()
{
if(!this.canRun())
{
return false;
}
$.writeln("About to run CustomSortExtensionHandler");
if( XmpScriptLib == undefined ) {
if( Folder.fs == "Windows" ) {
var pathToLib = Folder.startup.fsName + "/AdobeXMPScript.dll";
} else {
var pathToLib = Folder.startup.fsName + "/AdobeXMPScript.framework";
}
var libfile = new File( pathToLib );
var XmpScriptLib = new ExternalObject("lib:" + pathToLib );
}
var root = new SDKNode("CustomSortRoot", true);
root.addNode(new SDKNode("CSFolder1", true));
var lf = new SDKNode("RootLeaf", false);
root.addNode(lf);
var n = new SDKNode("leaf1", false);
var d = root.findChildNode("CSFolder1");
d.addNode(n);
for(var i = 0;i < 20;i++)
{
var nd = new SDKNode("leaf" + i, false);
nd.customNumber = (99-i);
if(i % 2 == 0)
{
nd.customString = "Z_" + i;
nd.customNumber = (99+i);
}
root.addNode(nd);
}
root.addNode(new SDKNode("CSFolder2", true));
n = new SDKNode("leaf2", false);
d = root.findChildNode("CSFolder2");
d.addNode(n);
n = new SDKNode("leaf3", false);
d = root.findChildNode("CSFolder2");
d.addNode(n);
root.getChildNode("CSFolder2").addNode(new SDKNode("CSSubFolder1", true));
n = new SDKNode("leaf4", false);
d = root.findChildNode("CSSubFolder1");
d.addNode(n);
var sys = new SDKSystem("bridge:csortNode:");
sys.addRoot(root);
var sortHandler = new ExtensionHandler("sortHandler");
app.registerExtension(sortHandler);
app.registerPrefix( "bridge:csortNode:", sortHandler);
sortHandler.getBridgeUriForPath = function(path)
{
return path;
}
ExtensionHandler.prototype.getThumbsToSearch = function(kids)
{
for(var h = 0;h < kids.length;h++)
{
if(kids[h].isContainer())
{
this.getThumbsToSearch(kids[h].getChildren());
}
sortHandler.thumbsToSearch.push(kids[h]);
}
}
sortHandler.getBridgeUriForSearch = function(scope, spec)
{
var randomnumber=Math.floor(Math.random()*101);
var d = new Date();
var postfix = d.getSeconds() + randomnumber;
var sNode = new SDKNode("SearchNode" + postfix, true)
sNode.children = new Array();
sys.addSearchNode(sNode);
var sThumb = new Thumbnail("bridge:csNode:/SearchNode" + postfix);
sThumb.core.children.cacheData.status = "bad";
var searchScopes = spec.scopeSpecifiers;
sortHandler.thumbsToSearch = new Array();
var scopeNode = sys.getNodeFromPath(scope.uri);
var children;
if(searchScopes[0] == "DoSubFolders")
{
this.getThumbsToSearch(scopeNode.getChildren());
children = sortHandler.thumbsToSearch;
}
else
{
children = scopeNode.getChildren();
}
var conditions = spec.conditionList;
if(spec.conjunction == "or")
{
for(var i = 0;i < children.length;i++)
{
var currentNode = children[i];
for(j = 0;j < conditions.length;j++)
{
var currentCon = conditions[j]
var searchField = currentCon.searchField;
var operand = currentCon.operand;
switch(searchField)
{
var thumbFieldValue;
case "CustomString":
thumbFieldValue = currentNode.getCustomString();
break;
case "CustomNumber":
thumbFieldValue = currentNode.getCustomNumber();
break;
case "CustomBool":
thumbFieldValue = currentNode.getCustomBool();
break;
case "name":
thumbFieldValue = currentNode.getName();
break;
}
switch(currentCon.operatorType)
{
case "equals":
if(thumbFieldValue == operand || thumbFieldValue.toString() == operand)
{
addNodeToSearchResult(currentNode);
}
break;
case "lessThanOrEqual":
if(thumbFieldValue <= operand)
{
addNodeToSearchResult(currentNode);
}
break;
case "greaterThanOrEqual":
if(thumbFieldValue >= operand)
{
addNodeToSearchResult(currentNode);
}
break;
case "endsWith":
var s = thumbFieldValue.substr((thumbFieldValue.length - operand.length), operand.length );
if(s == operand)
{
addNodeToSearchResult(currentNode);
}
break;
default:
}
}
}
}
else if(spec.conjunction == "and")
{
alert("SDK: CustomSortExtensionHandler:\nSample does not show this type of search!");
}
function addNodeToSearchResult(node)
{
var matches = sNode.getChildren();
var addNode = true;
for(var i = 0;i < matches.length;i++)
{
if(matches[i].getPath() == node.getPath())
{
addNode = false;
break;
}
}
if(addNode)
{
sNode.addNode(node);
}
}
return sThumb.uri;
}
sortHandler.setXMP = function(targets, xmpPackets, timeoutInMs, showUi, message)
{
var thumbs = targets;
var xmpData = xmpPackets;
var op = new ProgressOperator("progress", thumbs);
op.start = function()
{
op.procStat = "notStarted";
op.opStat = "incomplete";
app.operationChanged(this);
op.procStat = "inProgress";
this.processedNodeCount = 0;
app.operationChanged(this);
op.percComp = 1;
for(var i = 0;i < thumbs.length;i++)
{
for(var j = 0;j < 10;j++)
{
$.sleep(50);
}
op.percComp += (100 / thumbs.length);
app.operationChanged( this );
var t = thumbs[i];
t.core.metadata.metadata = new Metadata(xmpData[i]);
t.model.privateData.node.setMetadata(new Metadata(xmpData[i]));
this.processedNodeCount++;
}
op.percComp = 100;
op.opStat = "succeeded";
op.procStat = "completed";
app.operationChanged( this );
return;
}
op.stop = function()
{
return;
}
op.getConflictInfo = function()
{
return "unknown";
}
op.getOperationStatus = function()
{
return op.opStat;
}
op.getPercentageComplete = function()
{
return op.percComp;
}
op.getProcessedNodeCount = function()
{
return this.processedNodeCount;
}
op.getProcessingStatus = function()
{
return op.procStat;
}
op.getProgressMessage = function()
{
return "Setting XMP on selected files";
}
op.getTotalBytesTransferred = function()
{
return 0;
}
op.getTotalNodeCount = function()
{
return thumbs.length;
}
op.getType = function()
{
return "progress";
}
op.getUIPolicy = function()
{
return this.showUi;
}
op.resume = function()
{
return false;
}
op.resolveConflict = function() { }
app.enqueueOperation(op);
}
var wrapperObject = this;
sortHandler.makeModel = function(path)
{
ExtensionModel.prototype.sortXML = "";
sortModel = new ExtensionModel(path);
sortModel.path = path;
this.path = path;
wrapperObject.initModel(sortModel, sys);
return sortModel;
}
var csDescriptions = new Array();
csDescriptions[0] = new InfosetMemberDescription( "CustomString", "String" );
csDescriptions[1] = new InfosetMemberDescription( "CustomNumber", "Integer" );
csDescriptions[2] = new InfosetMemberDescription( "CustomDate", "String" );
csDescriptions[3] = new InfosetMemberDescription( "CustomArray", "Array of String" );
csDescriptions[4] = new InfosetMemberDescription( "CustomBool", "Boolean" );
var customInfoset = new Infoset("customInfoset", csDescriptions);
app.registerInfoset(sortHandler, customInfoset);
onEvent = function(event)
{
if(event.object instanceof Document)
{
if(event.type == "selectionsChanged")
{
if(event.object.selections.length > 0)
{
var thumb = event.object.selections[0];
if(thumb.sortHandler)
{
stringText.text = thumb.sortHandler.customInfoset.CustomString;
numbersText.text = thumb.sortHandler.customInfoset.CustomNumber;
dateText.text = thumb.sortHandler.customInfoset.CustomDate;
arrStringText.text = thumb.sortHandler.customInfoset.CustomArray.toString();
boolList.selection = (thumb.sortHandler.customInfoset.CustomBool) ? 0 : 1;
customSearchDataPalette.content.visible = true;
}
else
{
customSearchDataPalette.content.visible= false;
}
}
else
{
customSearchDataPalette.content.visible= false;
}
}
}
}
app.eventHandlers.push({handler: onEvent});
var customSearchDataPalette = new TabbedPalette(app.document, "SDK: Custom Sort Infoset Data", "SDKCus2tomInfoPaletteSort", "script");
var win = customSearchDataPalette.content;
var stringLabel = win.add("statictext", [5, 9, 115, 25], "Custom String");
var stringText = win.add("edittext", [120, 5, 320, 25], "");
stringText.enabled = false;
var numbersLabel = win.add("statictext", [5, 39, 115, 55], "Custom Number");
var numbersText = win.add("edittext", [120, 35, 320, 55], "");
numbersText.enabled = false;
var dateLabel = win.add("statictext", [5, 69, 115, 85], "Custom Date");
var dateText = win.add("edittext", [120, 65, 320, 85], "");
dateText.enabled = false;
var arrLabel = win.add("statictext", [5, 99, 115, 115], "Custom Array");
var arrStringText = win.add("edittext", [120, 95, 320, 115], "");
arrStringText.enabled = false;
var boolLabel = win.add("statictext", [5, 129, 115, 145], "Custom Boolean");
var boolList = win.add("dropdownlist", [120, 125, 320, 145]);
var tItem = boolList.add("item", "True");
tItem.val = true;
var fItem = boolList.add("item", "False");
fItem.val = false;
boolList.enabled = false;
customSearchDataPalette.content.visible = false;
var t = new Thumbnail("bridge:csortNode:/CustomSortRoot");
app.favorites.insert(t);
t.refresh();
$.writeln("CustomSortExtensionHandler initialized successfully");
return true;
}
CustomSortExtensionHandler.prototype.canRun = function() {
if(BridgeTalk.appName == "bridge") {
for(index in app.extensions)
{
if(app.extensions[index].name == "sortHandler")
{
$.writeln("ERROR: Cannont run twice! You must restart Bridge");
return false;
}
}
return true;
}
$.writeln("ERROR:: Cannot run CustomSortExtensionHandler");
$.writeln(this.requiredContext);
return false;
}
CustomSortExtensionHandler.prototype.initModel = function(sortModel, sys)
{
sortModel.getSearchDefinition = function()
{
var searchField = "CustomString";
var opType = "string";
var searchFieldDisplay = "Custom String";
var searchCriteria1 = new SearchCriteria(searchField, opType, searchFieldDisplay);
searchCriteria1.operatorTypesToDisable = ["exists", "equals", "doesNotExist", "doesNotEqual", "less",
"lessThanOrEqual", "greaterThanOrEqual", "contains",
"doesNotContain", "startsWith", "greater"];
searchField = "CustomNumber";
opType = "float";
searchFieldDisplay = "Custom Number";
var searchCriteria2 = new SearchCriteria(searchField, opType, searchFieldDisplay);
searchCriteria2.operatorTypesToDisable = ["exists", "doesNotExist", "doesNotEqual", "less",
"contains", "doesNotContain", "endsWith",
"startsWith", "greater"];
searchField = "name";
opType = "string";
searchFieldDisplay = "Name";
var searchCriteria3 = new SearchCriteria(searchField, opType, searchFieldDisplay);
searchCriteria3.operatorTypesToDisable = ["exists", "doesNotExist", "doesNotEqual", "less",
"lessThanOrEqual", "greaterThanOrEqual", "contains",
"doesNotContain", "endsWith", "startsWith", "greater"];
searchField = "CustomBool";
opType = "boolean";
searchFieldDisplay = "Custom Boolean";
var op1 = new Operand("true", "A true value");
var op2 = new Operand("false", "A false value");
var myOperators = [op1, op2];
var searchCriteria4 = new SearchCriteria(searchField, opType, searchFieldDisplay, myOperators);
searchCriteria4.operatorTypesToDisable = ["exists", "doesNotExist", "doesNotEqual", "less",
"lessThanOrEqual", "greaterThanOrEqual", "contains",
"doesNotContain", "endsWith", "startsWith", "greater"];
var critList = [searchCriteria1, searchCriteria2, searchCriteria3, searchCriteria4];
var ranksArray = [];
var scope1 = new Scope( "DoSubFolders", "SDKSearch: Search subfolders");
var scope2 = new Scope("DoHidden", "SDKSearch: Search hidden files");
var scopesArray = [scope1, scope2];
var searchDef = new SearchDefinition(critList, 10, ranksArray, scopesArray);
return searchDef;
}
sortModel.setName = function(name)
{
var parent = this.privateData.node.getParent();
var update = new Thumbnail(sys.getPrefix() + parent.getPath());
update.core.children.cacheData.status = "bad";
this.privateData.node.setName(name);
if(app.document.thumbnail.name == "SearchNode")
{
app.document.thumbnail.core.children.cacheData.status = "bad";
}
var newURI = sys.getPrefix() + this.privateData.node.getPath();
return newURI;
}
sortModel.createNewContainer = function(name)
{
var newNode = new SDKNode(name, true)
this.privateData.node.addNode(newNode);
this.privateData.cacheElement.children.cacheData.status = "bad";
return sys.getPrefix() + newNode.getPath();
}
sortModel.needAuthentication = function()
{
return false;
}
sortModel.authenticate = function()
{
return;
}
sortModel.exists = function()
{
return true;
}
sortModel.initialize = function()
{
this.privateData.node = sys.getNodeFromPath(this.path);
}
sortModel.registerInterest = function(cacheElement)
{
this.privateData.cacheElement = cacheElement;
}
sortModel.unregisterInterest = function()
{
this.privateData.cacheElement = undefined;
}
sortModel.getFilterCriteria = function()
{
var defFilters = app.defaultFilterCriteria;
var filter = new FilterDescription("customStringfilter", "SDK: Custom Filter", "string", "sortHandler.customInfoset.CustomString", false);
defFilters.push(filter);
return defFilters;
}
sortModel.getSortCriteria = function()
{
var dsc = app.defaultSortCriteria;
var sc1 = new SortCriterion("sortSDKNumber", "number", "sortHandler.customInfoset.CustomNumber", "SDK: Custom Number");
dsc.push(sc1);
var sc2 = new SortCriterion("sortSDKString", "string", "sortHandler.customInfoset.CustomString", "SDK: Custom String");
dsc.push(sc2);
var sc3 = new SortCriterion("sortSDKXMP", "number", "http://ns.adobe.bridge.sdk/a/", "ID", "SDK: Custom XMP");
dsc.push(sc3);
return dsc;
}
sortModel.getParent = function()
{
var parent = this.privateData.node.getParent();
if(parent != undefined)
{
return (sys.getPrefix() + parent.getPath());
}
}
sortModel.supportsUserSortOrder = function()
{
return true;
}
sortModel.setUserSortOrder = function(inXML)
{
this.sortXML = inXML;
}
sortModel.getUserSortOrder = function()
{
if(this.sortXML == "")
{
var xml = "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><dirinfo><files>";
var children = this.privateData.node.getChildren();
for(var i = 0;i < children.length;i++)
{
xml += "<item key='" + children[i].getName() + "00000000000000" + "' />";
}
xml += "</files></dirinfo>";
this.sortXML = xml;
}
return this.sortXML;
}
sortModel.addToDrag = function(pointerToOsDragObject)
{
return true;
}
sortModel.wouldAcceptDrop = function(type, sources, osDragRef)
{
return false;
}
sortModel.refreshInfoset = function(infosetName)
{
var infoset = this.privateData.cacheElement[infosetName];
var currentNode = this.privateData.node;
try
{
if(infosetName == "immediate" || infosetName == "all")
{
if(this.privateData.node.getName().substr(0,10) == "SearchNode")
{
infoset.name = "SearchNode";
}
else
{
infoset.displayPath = this.path;
if(!currentNode.isContainer())
{
infoset.fileUrl = currentNode.getFileUrl();
}
infoset.isApplication = false;
infoset.isDeleted = false;
infosetisHidden = false;
infoset.isLink = false;
infoset.isPackage = false;
infoset.isSidecarFile = false;
infoset.name = currentNode.getName();
infoset.size = [1024, 0];
infoset.sortIndex = currentNode.getName();
}
infoset.isContainer = currentNode.isContainer();
infoset.cacheData.status = "good";
}
if(infosetName == "item" || infosetName == "all")
{
infoset.canBeDragSource = true;
infoset.canBeDropTarget = true;
infoset.canCreateNewContainer = true;
infoset.canCreateNewLink = false;
infoset.canDelete = true;
infoset.canDuplicate = true;
infoset.canEject = false;
infoset.canGetFileUrl = true;
infoset.canSetName = true;
infoset.isExternalEditInProgress = false;
infoset.isLinkToContainer = false;
infoset.isLockedByUser = false;
infoset.isNeverWritable = false;
infoset.isPhysicalFile = false;
infoset.noWritePermission = false;
if(this.privateData.node.getName().substr(0,10) != "SearchNode")
{
if(this.privateData.node.isContainer())
{
infoset.canSearch = true;
}
}
infoset.cacheData.status = "good";
}
if(infosetName == "children" || infosetName == "all")
{
var arr = currentNode.getChildren();
for(var j = 0;j < arr.length;j++)
{
infoset.addChild(sys.getPrefix() + arr[j].getPath());
}
infoset.cacheData.status = "good";
}
if(infosetName == "icon" || infosetName == "all")
{
infoset.bitmap = this.privateData.node.getIcon();
infoset.cacheData.status = "good";
}
if(infosetName == "thumbnail" || infosetName == "all")
{
infoset.thumbnail = currentNode.getThumb();
infoset.cacheData.status = "good";
}
if(infosetName == "quickMetadata" || infosetName == "all")
{
infoset.colorMode = -1;
infoset.hasRawSettings = false;
infoset.hasCrop = false;
infoset.height = 0;
infoset.rating = 0;
infoset.rotation = 0;
infoset.stockPhotoStatus = 0;
infoset.xResolution = 0;
infoset.yResolution = 0;
infoset.width = 0;
infoset.cacheData.status = "good";
}
if(infosetName == "itemContent" || infosetName == "all")
{
infoset.canDoCameraRaw = false;
infoset.canGetFullSize = false;
infoset.canGetPreview = false;
infoset.canGetQuickPreview = false;
infoset.canGetThumbnail = false;
infoset.canGetXmp = true;
infoset.canLabelOrRate = true;
infoset.canRotate = false;
infoset.canSetXmp = true;
infoset.dynamicMediaType = undefined;
infoset.fileFormat = (currentNode.isContainer()) ? "" : "SDKNode";
infoset.hasSubContainers = (currentNode.isContainer()) ? true : false;
infoset.mimeType = "application/x-bridgesdknode";
infoset.pageCount = 1
infoset.tooltip = (currentNode.isContainer()) ? "SDK Node Container" : "SDK Leafe Node";
infoset.cacheData.status = "good";
}
if(infosetName == "cameraRaw" || infosetName == "all")
{
infoset.rawSupportType = 0;
infoset.cacheData.status = "good";
}
if(infosetName == "preview" || infosetName == "all")
{
infoset.preview = currentNode.getPreview();
infoset.cacheData.status = "good";
}
if(infosetName == "metadata" || infosetName == "all")
{
infoset.metadata = currentNode.getMetadata();
infoset.cacheData.status = "good";
}
if(infosetName == "customInfoset" || "all")
{
this.privateData.cacheElement.customInfoset.CustomString = currentNode.getCustomString();
this.privateData.cacheElement.customInfoset.CustomNumber = currentNode.getCustomNumber();
this.privateData.cacheElement.customInfoset.CustomDate = currentNode.getCustomDate();
this.privateData.cacheElement.customInfoset.CustomArray = currentNode.getCustomArray();
this.privateData.cacheElement.customInfoset.CustomBool = currentNode.getCustomBool();
this.privateData.cacheElement.customInfoset.cacheData.status = "good";
}
}
catch(error) { $.writeln("ERROR: " + error); }
}
sortModel.getCacheStatus = function( infosetName)
{
if(typeof this.privateData.cacheElement == "undefined")
{
return "bad";
}
if(typeof this.privateData.cacheElement.infosetName== "undefined")
{
var ce = this.privateData.cacheElement;
var info = ce[infosetName];
var cd = info.cacheData;
var stat = cd.status;
return stat;
}
return this.privateData.cacheElement[infosetName].cacheData.status;
}
sortModel.terminate = function()
{
return undefined;
}
}
#include SDKSystem.jsx
#include SDKNode.jsx
if(typeof(CustomSortExtensionHandler_unitTest) == "undefined") {
new CustomSortExtensionHandler().run();
}
http://www.adobe.com/devnet/bridge
Documentation generated by
JSDoc on Tue Apr 27 10:21:34 2010