Writing simple JScript routine to learn about list boxes.
Is there a way of updating the clickData.func.sourcetab
The following does not work clickData.func.sourcetab = tabupdate;
where tabupdate is a tab object from activateTabData
To make it short, I think you can not do that.
This sourcetab represents what was the active tab when you entered the OnClick method of your script (which is a command entry point). It is part of the Func object provided as a parameter.
Reading quickly your code, I understand that the active tab might have changed during the execution of the message loop, that you capture that in OnAfterFolderChange and want to update things in your main loop (sending a custom message).
Since I don't know from your code what you really want to do with this (no other use of sourcetab found in the code), I'll make the assumption that you want to save this for later use in the loop. If that's the case, my advice would be to use another variable (let's say activeTab) that you would declare outside of the loop, initialized to clickData.func.sourcetab, and update it when receiving your custom message. Then, you'll need to rely on this activeTab variable to get information about the active tab.
One remark : even if I usually don't like using global variables, in simple (so far) use-cases, this could be a way to simplify your code and preventing the use of custom message. Making that activeTab variable global (or enclose it in an object declared as a global var) would make it accessible from everywhere in the code, and updating it in the OnAfterFolderChange method, will make it instantly available in your message loop.
If your code is going to grow significantly, then keep on the custom message, you'll be assured of where this variable can be modified.
The global is just there to check if it is possible to change the tab.
Script works fine except when switching tabs, the list will update with the new tab but clicking an item will open it in the clickdata tab. There does not seem to be any way of changing this.
But you can not change the sourcetab in the Func object : that object is sent to you as a parameter so you can know what was the context when OnClick triggers.
If you want to "play" with the current tab, in your situation where your message loop needs to be aware of active tab changes, you'll need to rely on another variable.
GO TABSELECT will do something else : it will allow you to change the active tab to set it to another tab you found somewhere else (from the lister, or from another command that created new tabs for instance).
I recently had to use it, and after some trouble, finally succedeed.
My problem was that I could not select a tab (from an object like you do) that was not on the active pane (when using dual pane). I did this using the Set FOCUS command (called from the script).
Script is unfinished, but I can share the part that does this (openedTabs comes from a command that just opened a tab group, and this is renaming those tabs) :
for (var e = new Enumerator(openedTabs); !e.atEnd(); e.moveNext()) {
var newTab = e.item();
dout("Tab " + newTab.displayed_label + " is on " + ((newTab.right)?"Right/Bottom pane":"Left/Up pane"));
cmd.Clear();
// First, we need to give focus to the proper pane
// /!\ GO TABSELECT can only select tabs on the pane that has focus.
var tabPane = (newTab.right)?"right":"left";
if (currentPane != tabPane) {
dout("Switching focus to " + tabPane);
cmd.AddLine("Set FOCUS="+tabPane);
currentPane = tabPane;
}
cmd.AddLine('GO TABSELECT=$' + newTab); // Will activate this tab
cmd.AddLine('GO TABNAME="' + newTabName + '"');
var res = cmd.Run();
dout("Command status (>0 expected) = " + res + " | " + cmd.results.result);
}
Will mark this as a bug as I think the Go path command in the script should be opening the path in the currently displayed source tab, not the clickdata source tab.
There’s no bug here, Command objects act on the window/tab you tell them to.
You can get the current source lister and active tab via the main DOpus object.
Objects like Lister also have Update methods if you want them to react to changes. (They keep a snapshot of state otherwise, as changing while the script was running when it didn’t expect it would be catastrophic in most situations.)
What are you trying to do ?
Note : As said by Leo, Lister.Update() updates the lister object that you manipulate to reflect what your actual lister has become since last call to get the lister object (my understanding is that having this object kept up to date with everything that can change in the lister between the different calls would be to much to handle).
Since you're mentioning the fact that you want something similar to SetSourceTab, it makes me think you want to do something else than using the lister object and the information it contains in your script.
It'd be easy for Opus to work that way, but writing scripts would be much harder, as the data you might be working with would be changing underneath you. Instead, it's up to the script when the data is refreshed.
(E.g. Think about looping through the selected files in a script, deleting some of them. If deleting a file immediately removed it from the list you were iterating through, your loop could go horribly wrong and start acting on the same file twice or skipping some files, depending on how it was written.)
But there seems to be another problem, not sure if it is this script or not - the busy spinner icon in the location bar won't stop spinning
will turn off script and restart - to see if it fixes.
turning it off fixes it. And when on it is not a reproducable error, seems to happen whenever it feels like it, lol, not sure if you can shed any light on whats causing it. (have checked the enumerator loop in Make_List() function and that is not the problem.)
it is causing noticable stress on my cores, will have to keep it off for now.
I just went through your script code, and at first sight, I don't see anything that could make the busy spinner start (except for real reasons, which could be large folders, etc ...).
Two remarks regarding the code itself that I leave to your appreciation to take into consideration or not, meaning agree with or not (coding habits can vary from one person to another ) :
The same piece of code that checks for script config 'Logging' parameter to decide wether to output the log or not is used in several places. It might be interesting to make it a function on its own (sthg like function myLog(msg) { if ( Script.config['Logging'] ) DOpus.Output(msg); }. Would probably help readability.
The script uses Opus global vars to store (persistent) information, but the variable names are not (all) really pointing to the script they are used for. It could at some point clash with names you'll want to use for other scripts. When using global variable like that, I try and name them with some kind of prefix helping to relate them to the script they're used for.
Besides the first point, code is clear with very readable formatting, which helps a lot to review quickly in such situations.
Many thanks for tips.
I think I have found the problem, (from some dim memory that some object had a list of items already) reading the folders from tab.dirs instead of using FSUtil.ReadDir might have done the trick (still checking). Might be because there was no FolderEnum.Close although it does not say explicity to use it when reading directories.
I never had an issue with not calling FolderEnum.Close, when scanning whole folders.
Be carefull with tab.dirs : as the manual states, it only returns displayed dirs. It means that if you have filter going on (for instance you filtered through FAYT to only display folder containing some word or part of a word), then tab.dirs will only return those filtered folders, whereas FSUtil.ReadDir will actually read the file system and return every folder (and file) regardless of what's being displayed.
Here is finished script, hopefully bug-free.
An exercise in learning Directory Opus Scripting, specifically List View Controls and JScript, that has resulted in a useful little widget, not sure it's worth posting in the Scripts forum.
Going through each of the controls in the dialog editor and doing a script with them is one way of learning about them.