//v0.1 - o4/2o15 //- initial //v0.2 - o5/2o18 //- fix annoying outputs //- add some generic params //- update LogX //v0.21- o7/2o19 //- upload //- REFRESHKEEPSEL // - replacement for "GoRefreshKeepSelection" command // - fix for scroll to selection not always working as expected // //- SIBLING // - replacement for Leos "GoRelative" command // - renamed WRAP switch to WRAPAUTO // - added SKIPEMPTY switch // - added WRAPASK switch to confirm wraparound // - default is "next sibling", no additional switch/value required // - code cleanup and minor fixes ("no siblings" detection etc.) // //- EXISTING // //- EXTSELECTION //Includes generic/enhanced variants of following addins: //- "GoRelative (go to next/prev sibling folder)" (http://resource.dopus.com/viewtopic.php?f=35&t=24496) //- "GoExisting (open path, focusing existing tab if found on either side)" http://resource.dopus.com/viewtopic.php?p=129647#p129674, http://resource.dopus.com/viewtopic.php?p=129596#p129596 //- "GoRefreshKeepSelection (refresh & keep selected) (http://resource.dopus.com/viewtopic.php?f=35&t=23027) /////////////////////////////////////////////////////////////////////////////// var template = "SIBLING/O[,prev,wrapauto,wrapask,skiphidden,skipempty],SETVAR/K,SETENV/K," + //PATH "REFRESHKEEPSEL/O[all,both,,dest,left,right,tree,viewpane],MAKEVISIBLE/O[checked]," + "EXISTING/S,"+ //PATH "EXTSELECTION/S,"+ //shared "PATH/K," + "PT/R," + "NOFAIL/S,NODESELECT/S,"+ "XLOG/O[off,xit,error,warning,info,,trace,dump,all]"; /////////////////////////////////////////////////////////////////////////////// function OnInit(data){ //uid added via script wizard (do not change after publishing this script) var uid = "{27428ACA-7F81-471E-8928-1638F394F544}"; var url = "https://resource.dopus.com/t/command-goex-extended-go-command-functionality/33002"; data.name = "Command.Generic: GoEx"; data.log_prefix = "GoEx"; data.desc = "Extended Go command."; data.copyright = "tbone"; data.version = "0.21"; data.default_enable = true; if (DOpus.Version.AtLeast("11.8.2")) data.log_prefix = "GoEx "; var cmd = data.AddCommand(); cmd.name = "GoEx"; cmd.method = "Command_GoEx"; cmd.desc = data.desc; cmd.label = "GoEx"; cmd.template = template; /////////////////////////////////////////////////////////////////////////// function ConfigHelper(data){ //v1.2 var t=this; t.d=data; t.c=data.config; t.cd=DOpus.Create.Map(); t.add=function(name, val, des){ t.l={n:name,ln:name. toLowerCase()}; return t.val(val).des(des);} t.des=function(des){ if (!des) return t; if (t.cd.empty) t.d.config_desc=t.cd; t.cd(t.l.n)=des; return t;} t.val=function(val){ var l=t.l; if (l.v!==l.x&&typeof l.v=="object") l.v.push_back(val);else l.v=t.c[l.n]=val;return t;} t.trn=function(){return t.des(t("script.config."+t.l.ln));}} /////////////////////////////////////////////////////////////////////////// var cfg = new ConfigHelper(data); cfg.add('XLog', DOpus.Create.Vector()). val(5).val("Off").val("Exception").val("Error").val("Warning").val("Info").val("Normal").val("Trace").val("Dump").val("All"). des('Console output level. The higher, the more output will be visible in the console window. '); } /////////////////////////////////////////////////////////////////////////////// var COMMAND_SUCCESS = false; var COMMAND_FAILURE = true; var COMMAND_USERABORT = true; var COMMAND_BADPARAMS = true; /////////////////////////////////////////////////////////////////////////////// function Command_GoEx(data){ var args = ArgsMagic(data, null, template), result = null; if (args["XLOG"].exists){ XLog = args["XLOG"].value; } Log("CmdLine: " + data.cmdline,"D"); if (args["NODESELECT"].exists) data.func.command.deselect = false; if (args["NOFAIL"].exists) COMMAND_FAILURE = COMMAND_SUCCESS; if (args["SIBLING"].exists) result = GoEx_SIBLING(data.func.command, data.func.sourcetab, args); if (args["REFRESHKEEPSEL"].exists) result = GoEx_REFRESHKEEPSEL(data.func.command, data.func.sourcetab, data.func.desttab, args); if (args["EXISTING"].exists) result = GoEx_EXISTING(data.func.command, data.func.sourcetab, args); if (args["EXTSELECTION"].exists) result = GoEx_ExternalSelection(data.func, data.func.command, args); if (result===null){ Log("Bad/incomplete params.","X"); return COMMAND_BADPARAMS; } return result; } /////////////////////////////////////////////////////////////////////////////// function GoEx_ExternalSelection(func, cmd, args){ //v0.3 Log("GoEx_REFRESHKEEPSEL():", 't', 1); Log("Qualifiers : " + func.qualifiers); Log("Qualifier CTRL: " + ((func.qualifiers+"").indexOf("ctrl")!=-1?"yes":"no")); /////////////////////////////////////////////////////////////////////////// function Trim(path){ path = path.replace(/^\s*/,''); path = path.replace(/\s*$/,''); //path = path.replace(/^\\*/,''); path = path.replace(/\\*$/,''); //path = path.replace(/^\/*/,'');/**/ path = path.replace(/\/*$/,'');/**/ return path; } /////////////////////////////////////////////////////////////////////////// function MatchPath( path){ if (path.search(/^[A-z]\:/i)!=-1) return true; //drive letter if (path.search(/^\\\\/i)!=-1) return true; //unc path if (path.search(/^\//i)!=-1) return true; //dopus alias if (path.search(/^\%/i)!=-1) return true; //env var return false; } /////////////////////////////////////////////////////////////////////////// function MatchUrl( path){ if (path.search(/^https?\:/i)!=-1) return true; //http(s) url if (path.search(/^www.*?/i)!=-1) return true; //www url return false; } /////////////////////////////////////////////////////////////////////////// var shell = new ActiveXObject("WScript.Shell"); var clipContentBefore = Trim(""+DOpus.GetClip("text")); //ctrl is still held down, omit ctrl-qualifier (^) shell.SendKeys("c"); DOpus.Delay("200"); var clipContent = Trim(""+DOpus.GetClip("text")); var isPath = MatchPath(clipContent); var isUrl = MatchUrl(clipContent); if (!clipContent || (!isPath && !isUrl)){ clipContent = clipContentBefore; isPath = MatchPath(clipContentBefore); isUrl = MatchUrl(clipContentBefore); } Log("Going ["+clipContent+"].."); if (!isPath && !isUrl){ Log("Syntactically not a known location, aborting.", "e"); Log("-", 't', -1); return COMMAND_FAILURE; } if (isPath){ clipContent = DOpus.FSUtil.Resolve(clipContent); if (!DOpus.FSUtil.Exists(clipContent)){ Log("Path not found, aborting.", "e"); Log("-", 'T', -1); return COMMAND_FAILURE; } } cmd.ClearFiles(); if (isPath){ cmd.AddLine('GO "'+clipContent+'" NEWTAB=findexisting,tofront'); cmd.AddLine('GO LASTACTIVELISTER'); } if (isUrl){ cmd.AddLine(clipContent); } cmd.Run(); Log("-", 't', -1); return COMMAND_SUCCESS; } /////////////////////////////////////////////////////////////////////////////// function GoEx_REFRESHKEEPSEL(cmd, sourcetab, desttab, args){ Log("GoEx_REFRESHKEEPSEL():", "t"); /////////////////////////////////////////////////////////////////////////// function RefreshTabKeepSelection( cmd, tab, makevisible, mvPrioCB, goRefreshCmdLine){ Log(" RefreshTabKeepSelection():", "t"); /////////////////////////////////////////////////////////////////////// function GetSelectedItemsFromTab(tab){ if (tab.selected.count != 0) return tab.selected; Log("", "t", -1); return null; } /////////////////////////////////////////////////////////////////////// function SelectItems(cmd, items, tab, makevisible){ var cmd = DOpus.Create.Command(); Log("SourceTAB bef: " + cmd.sourcetab, "d"); cmd.SetSourceTab(tab); Log("SourceTAB aft: " + cmd.sourcetab, "d"); cmd.ClearFiles(); cmd.AddFiles(items); var cmdLine = 'Select '+(makevisible==true?'MAKEVISIBLE ':'')+'EXACT FROMSCRIPT'; Log("Select-CMD: " + cmdLine, "d"); cmd.AddLine(cmdLine); //Log('# Selected :'+tab.selected.count); DOpus.Delay(50); cmd.Run(); tab.Update(); //Log('# Selecting:'+items.count); //Log('# Selected :'+tab.selected.count); } /////////////////////////////////////////////////////////////////////// function SwitchCheckboxMode( cmd, truefalse, tab){ var targetState = "off"; if (truefalse) targetState = "on"; Log('Set CheckboxMode='+targetState, "t"); //var cmd = DOpus.Create.Command(); //cmd.SetSourceTab(tab); cmd.RunCommand('Set CheckboxMode='+targetState, "t"); tab.Update(); var abort = 0; while ((truefalse != tab.selstats.checkbox_mode) && (abort++ < 100)){ Log('Setting CheckboxMode failed to set:' + tab.selstats.checkbox_mode + " target:"+targetState, "e"); DOpus.Delay(10); tab.Update(); } if (abort){ Log('Setting CheckboxMode finally:' + tab.selstats.checkbox_mode, "e"); Log('TOOK: '+ abort*10 +' milliseconds!', "e"); } return tab.selstats.checkbox_mode; } /////////////////////////////////////////////////////////////////////// var wasCheckboxMode = tab.stats.checkbox_mode==true; var isCheckboxMode = wasCheckboxMode; var numSelItems = tab.stats.selitems; var numCheItems = tab.stats.checkeditems; Log("Path : " + tab.path, "d"); Log("SelItems: " + numSelItems, "d"); Log("CheItems: " + numCheItems, "d"); var itemsSelected = null; var itemsChecked = null; cmd.SetSourceTab(tab); cmd.ClearFiles(); if (numCheItems || numSelItems){ if (isCheckboxMode){ if (numCheItems){ Log("Getting checked items in "+(isCheckboxMode ? "CheckboxMode" : "RegularMode"), "d"); itemsChecked = GetSelectedItemsFromTab(tab); } if (numSelItems){ isCheckboxMode = SwitchCheckboxMode( cmd, false, tab); Log("Getting selected items in "+(isCheckboxMode ? "CheckboxMode" : "RegularMode"), "d"); itemsSelected = GetSelectedItemsFromTab(tab); } } else { if (numSelItems){ Log("Getting selected items in "+(isCheckboxMode ? "CheckboxMode" : "RegularMode"), "d"); itemsSelected = GetSelectedItemsFromTab(tab); } if (numCheItems){ isCheckboxMode = SwitchCheckboxMode( cmd, true, tab); Log("Getting checked items in "+(isCheckboxMode ? "CheckboxMode" : "RegularMode"), "d"); itemsChecked = GetSelectedItemsFromTab(tab); } } } Log('Refreshing ('+goRefreshCmdLine+')..', "d"); var start = new Date().getTime(); cmd.RunCommand(goRefreshCmdLine); Log("Took: " + (new Date().getTime()-start), "d"); //tab.Update(); DOpus.Delay("200"); isCheckboxMode = (tab.stats.checkbox_mode==true); if (isCheckboxMode){ if(numCheItems){ Log("CB1 Setting checked items in "+(isCheckboxMode ? "CheckboxMode" : "RegularMode"), "d"); SelectItems(cmd, itemsChecked, tab, (makevisible && wasCheckboxMode && (mvPrioCB || numSelItems==0))); } if(numSelItems){ isCheckboxMode = SwitchCheckboxMode( cmd, false, tab); Log("CB2 Setting selected items in "+(isCheckboxMode ? "CheckboxMode" : "RegularMode"), "d"); SelectItems(cmd, itemsSelected, tab, (makevisible && (!mvPrioCB || numCheItems==0 || !wasCheckboxMode))); } } else { if(numSelItems){ Log("NOCB1 Setting selected items in "+(isCheckboxMode ? "CheckboxMode" : "RegularMode"), "d"); SelectItems(cmd, itemsSelected, tab, (makevisible && (!mvPrioCB || numCheItems==0 || !wasCheckboxMode))); } if(numCheItems){ isCheckboxMode = SwitchCheckboxMode( cmd, true, tab); Log("NOCB2 Setting checked items in "+(isCheckboxMode ? "CheckboxMode" : "RegularMode"), "d"); SelectItems(cmd, itemsChecked, tab, (makevisible && wasCheckboxMode && (mvPrioCB || numSelItems==0))); } } if (wasCheckboxMode && !isCheckboxMode){ Log("Resetting to checkbox mode", "d"); isCheckboxMode = SwitchCheckboxMode( cmd, true, tab); } if (!wasCheckboxMode && isCheckboxMode){ Log("Resetting to non-checkbox mode", "d"); isCheckboxMode = SwitchCheckboxMode( cmd, false, tab); } return true; } /////////////////////////////////////////////////////////////////////////// cmd.ClearFiles(); var refreshed = null, newOps = []; var mv = args["MAKEVISIBLE"].exists; //scroll to selected or checkboxed items var mvPrioCB = args["MAKEVISIBLE"].options["checked"]; //priorize checkboxed items if scrolling is enabled var options = args["REFRESHKEEPSEL"].options; var goPT = args["PT"].value?" "+args["PT"].value:""; Log("PT : " + goPT, "d"); if (options["all"]) options["both"] = options["tree"] = true; if (sourcetab.lister.dual && options["both"]) options["source"] = options["dest"] = true; if (!sourcetab.lister.dual) delete options["dest"]; if (!sourcetab.lister.dual) delete options["right"]; if (options["left"]) if (sourcetab.right) options["dest"] = true; else options["source"] = true; if (options["right"]) if (sourcetab.right) options["source"] = true; else options["dest"] = true; if (options["tree"]) newOps[newOps.length] = "tree"; if (options["viewpane"]) newOps[newOps.length] = "viewpane"; var goRefreshOps = newOps.join(","); if (options["source"]) refreshed = RefreshTabKeepSelection(cmd, sourcetab, mv, mvPrioCB, "Go REFRESH=source"+(goRefreshOps!=""?","+goRefreshOps:"")+goPT); if (refreshed) goRefreshOps=""; if (options["dest"]) refreshed = RefreshTabKeepSelection(cmd, desttab, mv, mvPrioCB, "Go REFRESH=dest"+(goRefreshOps!=""?","+goRefreshOps:"")+goPT); if (refreshed) goRefreshOps=""; if (!refreshed) refreshed = RefreshTabKeepSelection(cmd, sourcetab, mv, mvPrioCB, "Go REFRESH"+(goRefreshOps!=""?"="+goRefreshOps:"")+goPT); Log("Done.", "t", -1); return COMMAND_SUCCESS; } /////////////////////////////////////////////////////////////////////////////// function GoEx_EXISTING(cmd, sourcetab, args ){ /////////////////////////////////////////////////////////////////////////// function FindTabWithPath(path, tabs) { var FSUtil = DOpus.FSUtil(); var e = new Enumerator(tabs); while (!e.atEnd()) if (e.item().path!="" && FSUtil.ComparePath(e.item().path, path)) return e.item(); else e.moveNext(); return null; } /////////////////////////////////////////////////////////////////////////// Log("GoEx_EXISTING():", "t", 1); var tab = true, path = args["PATH"].value; if (!path) return COMMAND_BADPARAMS if (sourcetab.lister.dual){ var srcTabs = sourcetab.lister.tabsleft; var dstTabs = sourcetab.lister.tabsright; if (sourcetab.right){ var tabsTmp = srcTabs; srcTabs = dstTabs; dstTabs = tabsTmp; } tab = FindTabWithPath(path, srcTabs); if (!tab && (tab = FindTabWithPath(path, dstTabs))) cmd.AddLine('Set FOCUS=toggle'); } cmd.AddLine('Go "'+path+'" NEWTAB'+(tab?'=findexisting':'')); Log("Done.", "t", -1); cmd.Run(); } /////////////////////////////////////////////////////////////////////////////// function GoEx_SIBLING( cmd, sourcetab, args){ /////////////////////////////////////////////////////////////////////////// function ConsiderFolder( folderItem, options){ // 2=drive root, 18=empty dir var folderEnum = DOpus.FSUtil.ReadDir(folderItem.realpath, false); if (folderEnum.error!=0 && folderEnum.error!=18) return false; if (options["skipempty"] && (folderEnum.error == 18)) return false; if (options["skiphidden"] && (folderItem.attr & 2)) return false; return true; } /////////////////////////////////////////////////////////////////////////// function GetNextFolderIndex(curIdx, total, options){ var next = !options["prev"]; if (next && ++curIdx==total) return (options["wrapauto"] || options["wrapask"] && DOpus.Dlg.Request("Last folder, wrap around?","Ok|Cancel"))?0:null; if (!next && --curIdx==-1) return (options["wrapauto"] || options["wrapask"] && DOpus.Dlg.Request("First folder, wrap around?","Ok|Cancel"))?total-1:null; return curIdx; } /////////////////////////////////////////////////////////////////////////// function GetSubFoldersSorted(path){ var fEnum = DOpus.FSUtil.ReadDir(path, false), subFlds = DOpus.Create.Vector(); if (fEnum.error) { Log("Error "+fEnum.error+" reading folder ["+path+"]", "e"); return null; } while (!fEnum.complete){ var folderItem = fEnum.Next(); if (folderItem.is_dir) subFlds.push_back(folderItem); } if (subFlds.count==1) return null; subFlds.sort(); return subFlds; } /////////////////////////////////////////////////////////////////////////// function GetCurrentFolderIndex(path, vecSiblings ){ var curIdx=-1, total=vecSiblings.count*1; while (curIdx++"); if (parts.length>1) opValue = parts.slice(1).join(""); this.options[opName] = opValue; } if (!(!this.value && subOpsTemplate)) return; if (!(match = subOpsTemplate.match(/\<(.+?)\>/))) return; this.options[match[1]] = true; this.value = match[1]; } /////////////////////////////////////////////////////////////////////////// var types = {s:"switch",k:"keyword",o:"optional",n:"numeric",m:"multiple",r:"raw"}; var names = template.replace(/\/(.)\,/g,"/$1;").replace(/\]\,/g,"];").split(";"), args = []; for(arg in names) { var parts = names[arg].split("/"); var name=parts[0].toUpperCase(), subOpsTemplate=null; var parts2 = parts[1].split("["); var type=parts2[0].toLowerCase(); if (parts2.length>1) subOpsTemplate = parts2[1].substring(0,parts2[1].length-1); var exists=(data&&data.func.args.got_arg[name])||(jsonData&&(jsonData[name]!=undefined))||false; var value = (data && data.func.args[name]) || (jsonData && jsonData[name]) || undefined; args.push( args[name] = new Arg(name, types[type], exists, value, subOpsTemplate )); } /////////////////////////////////////////////////////////////////////////// args.Get = function( argName, configName, noneValue){ var arg = this[argName = argName.toUpperCase()]; if (!arg) throw new Error(0, "Unknown parameter ["+argName+"]"); if (arg.exists) return arg.value; //DOpus.Output("argName: " + argName); //DOpus.Output("configName: " + configName); if (!configName) return noneValue; if (typeof Script.config[configName] == "string") return new String(""+Script.config[configName]); return Script.config[configName]; } return args; } /////////////////////////////////////////////////////////////////////////////// function EnvMagic(scope){ //v0.1 this.scope = scope || "Process"; try{this.shell=shell} catch(e){this.shell=new ActiveXObject("WScript.Shell")}; this.env = this.shell.Environment(this.scope); /////////////////////////////////////////////////////////////////////////// this.Set = function (varname, value, scope){ var env = scope?this.shell.Environment(scope):this.env; Log("Name: " + varname + " val: " + value, "d"); env(varname) = value; return value; } /////////////////////////////////////////////////////////////////////////// this.Get = function (varname, scope){ var env = scope?this.shell.Environment(scope):this.env; return env(varname); } /////////////////////////////////////////////////////////////////////////// this.Remove = function (varname, scope){ var env = scope?this.shell.Environment(scope):this.env; return env.Remove(varname); } /////////////////////////////////////////////////////////////////////////// this.Expand = function (varString){ return this.shell.ExpandEnvironmentStrings(varString); } } /////////////////////////////////////////////////////////////////////////////// function Log(text, lvl, ind){ //XLog v0.45 (allow early usage, but warn (Script-object cannot be typeof'ed)) var u,lvs={o:0,x:1,e:2,w:3,i:4,n:5,t:6,d:7,a:8},i=["","X","E","W","I","","","",""],d=DOpus; if (typeof XLog==(u="undefined")){var v=d.Vars; if (v.Exists("XLog") && typeof XLogForce==u) {XLog=v.Get("XLog"); }} if (typeof XLog==u){try{var c=Script.Config;if(typeof c.XLog!=u){XLog=c.XLog;}}catch(e){d.Output("XLog: Early call, log-level=all.",1);XLog=8;}} if (typeof XLog==u){XLog="normal";} if(XLog.paused===undefined){ if(XLog===true) var L=5; else if(!isNaN(parseInt(XLog,10))) var L=XLog*1; else var L=lvs[(""+XLog).toLowerCase().substring(0,1)]; XLog={paused:false,I:0,L:L};} lvl=(lvl==undefined?5:lvs[lvl.substring(0,1).toLowerCase()]); if (!(lvl && XLog.L && !XLog.paused && (lvl<=XLog.L))){ return;} var pad = (XLog.I==0?"":new Array(XLog.I+1).join(" ")); if (i[lvl])pad = i[lvl]+(!pad?" ":pad.substring(1)); if (text!="-"){if (d.Version.AtLeast("11.13.1")) d.Output(pad+text,((lvl==1||lvl==2)?1:0)); else d.Output(pad+text);} ind=(ind!==undefined?ind:0);XLog.I+=ind;if(XLog.I<0)throw new Error("XLog indent went sub-zero."); } /////////////////////////////////////////////////////////////////////////////// function DumpObject(o, name, upperCaseProps, self, level){ this.version = 0.4; name = name || "unnamed"; if (self == undefined) DOpus.Output("DumpObject(): ["+name+"]"); var maxLen = 0; upperCaseProps = upperCaseProps || false; self = self || false; level = level || " "; for(prop in o) if (prop.length > maxLen) maxLen = prop.length; for(prop in o) { var pad = ""; while (pad.length+prop.length