SmartGetSizes_Handler: Toggle automatic folder size calculation

@tbone:

The root post was updated with a new version of each script package that adds a check for $src:autosize... so the script can now work off of both lister and source tab specific variables. See what you think... And since you mentioned dual display listers, if someone thinks they might want linked tabs or dual-display tabs not linked but running under Navlock enabled, let me know if you want an additional change to have both sides auto-size. I' haven't tested the script in dual-display mode yet... not sure what will happen, but I expect it will work with the LISTER variable toggle button, but I think some more work might be needed to get it to to auto-size both sides of the lister with the new source tab option.

About your other question, the reason the toolbars vertical height increases with AB's triple-button is because the second child-button (Relative Size) has it's label state set to Default. Setting it to show on the Right will fix it. This happens to be related to a pet peeve of mine :wink:.

Thanks Steje.. o) I tried your update, but it feels like its working as before? I mean, it still affects all tabs opened. And to be honest, I did not get your description of this "$src:autosize" thing.
You probably mean the status variable for auto-mode to be tab-scoped now, but where has this been added? Can't find it in the scripts, nor the button - or is this something I need to add? Just trying to understand.. o)

Well, yeah... that "$src:autosize" thing is pretty key to making it work how you asked, so - pretty important :slight_smile:. In short, you'll want to use a button like this:

<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<label>AutoSize</label>
	<icon1>#getsizes</icon1>
	<function type="normal">
		<instruction>@toggle:if $src:autosize</instruction>
		<instruction />
		<instruction>@ifset:$src:autosize</instruction>
		<instruction>@set src:autosize</instruction>
		<instruction />
		<instruction>@ifset:else</instruction>
		<instruction>@set src:autosize=true</instruction>
		<instruction>SmartGetSizes GETALL NODESELECT</instruction>
	</function>
</button>

The original script only looked for a LISTER scoped variable called autosize to be set. The change to the script was to check for a source TAB scoped variable of the same name (src:autosize - set in the button above). Either will now work... but the change to the script necessitates a change to the toolbar button used to toggle the script behavior.

So, the button above is the same as my original example button, just with the lst:autosize stuff swapped out for the newly supported src:autosize variable. I suppose I could have been more clear on what else needed to be done :wink: ...

It was just yesterday that I digged those scope prefixes - I think I got them now.
Excuse: The manual has over 900 pages! Did anybody print it? o)

With script you meant that button-code, right? Is there some guide line on how to call what? o) Is this a button-code, a command, a button-script? Just wondering. o)

To sum up: Now everything is clear, thanks for being very detailed and supplying the button once again!

I had edited the post to make the needs of this solution hopefully a bit more clear. The script and the toolbar button work TOGETHER.

The script portion needs some way of recognizing that you want it to do it's intended job for behavior that you want to turn on and off in an "on demand" fashion... Doing that by enabling/disabling the script via Prefs to accomplish this would be ridiculous. Instead, the most convenient way to do it is to give the user a button they can click just like any other button that turns things on and off in Opus...

So with that, the button needs to do something that the script can pick up on and recognize. That something is the toggling of an environment variable (new to v11).

The original script only checked to see if the button toggled a LISTER scope variable (designated as a LISTER scoped variable by the use of lst: as a prefix to the variable name)... so the first example button was written to do so.

The change to the script was to ALSO check for a source TAB scoped variable (designated in the button as a source TAB scoped variable by the new use of a src: prefix to the variable name).

Yeah, the help file is big :wink:... but keep in mind that work began on this during the beta trials... so the info on the new features used in this script were a bit more concisely presented (in the Beta announcement) :wink:.

Thanks for sharing. The src:autosize based button is a good addition the the File Display Toolbar.

Thanks, and yeah... that makes lots of sense for tab scope!

And again, if any folks interested in this script think it'd be useful to auto-size the other side of a dual-display lister if you're in linked tab or navlock mode... shout and I'll look into it.

Do you know, could the script be modified so that the dialog does not show?

And maybe there's an easy way to stop it from recalculation folders, which have been calced already? o)

In general I don't mind the popup so much, but if I enable autosize (all folders get calced) and then step down a subfolder and then back up again, it still shows the folder sizes, but starts calculating the sizes again and then the dialog is kind of disturbing indeed. Or maybe that's the reason the script exists, to always realtime-update the sizes? o) For me it would be enough if subfolder size calculation is done once and then leave it at that. I had a look into the script myself, but I'm not there yet, still experimenting with all this.. o)

The reason it does a full recalculation (and displays the progress dialog) the script calls the "GetSizes" command when the folder changes. This does a forced full refresh of the folder sizes. Enabling Calculate folder sizes works differently only calculating when its needed.

An alternative approach to this script would be to have the script set the CALCFOLDERSIZES based on the same criteria. This seems to give similar functionality, being able to manage the size calculation at a tab or source level, but causes less refreshing of the folder sizes.
One downside of this approach is that its changing your Dopus config, overwriting your current settings. Not sure if this is a problem.

This is POC hack if steje script. You need to refresh the current folder after pressing the button.

// Original code by steje, updated by wowbagger.
// Enables\Disables folder size calculation feature based on a variable specific to a tab. 

// Original
//   OnAfterFolderChange_smartgetsizes:
//   Revision: v1.0.7 (js)
//   (c) 2014 steje
//
// This is a script for written for Directory Opus v11.
// See http://www.gpsoft.com.au/redirect.asp?page=scripts for development information.

// Called by Directory Opus to initialize the script
function OnInit(initData)
{
  // Provide basic information about the Script
  initData.name = "Folder Size calculation modifications";
  initData.desc = "Check for lister variable on folder changes to auto-calculate folder sizes or not.";
  initData.copyright = "(c) 2014 steje, modified by wowbagger";
  initData.version = "v1.0.7b.2 (js)";
  initData.default_enable = true;
  
  // Set DEBUG flag below to true in order to enable logging messages to the Opus Output Window
  initData.config.DEBUG = false;
  initData.config.CALCFOLDERSIZES_on_value = "all";
 
  // Initialise the command that this script adds
  var cmd = initData.AddCommand();
  cmd.name = "SmartCalcFolderSizes";
  cmd.icon = "getsizes";
  cmd.method = "OnSmartCalcFolderSizes";
  cmd.desc = "Enables\Disables the folder size calculation feature based on a variable.";
  cmd.label = "Smart Calc Folder Sizes";
   
  return false;
}

// Implement the SmartGetSizes command
function OnSmartCalcFolderSizes(commandData)
{
  logMsg("OnSmartCalcFolderSizes running");
  SmartGetSizes();
}

function OnSourceDestChange(SourceDestData)
{
  if(SourceDestData.source)
  {
    logMsg("OnSourceDestChange running source:" + SourceDestData.source + " dest:" + SourceDestData.dest + " tab[" + SourceDestData.tab + "]:" + SourceDestData.tab.Path);
    SmartGetSizes();
  }
}

function OnActivateTab(ActivateTabData)
{
  logMsg("OnActivateTab running old:" + ActivateTabData.old.Path);
  SmartGetSizes();
}

// Called whenever the folder is changed
function OnAfterFolderChange(afterFolderChangeData)
{
  logMsg("OnAfterFolderChange running");
  SmartGetSizes();
}

function SmartGetSizes()
{
  var tab = DOpus.listers(0).activetab;
  logMsg("SmartGetSizes! tab[" + tab + "]:" + tab.path);
 
  var objCmd = DOpus.CreateCommand;
  if (objCmd.IsSet("$lst:autosize"))
  {
    logMsg("The 'autosize' lister variable is set!");
    objCmd.RunCommand("Set CALCFOLDERSIZES="+ Script.config.CALCFOLDERSIZES_on_value);
  }
  else if (objCmd.IsSet("$src:autosize"))
  {
    logMsg("The 'autosize' sourcetab variable is set!");
    objCmd.RunCommand("Set CALCFOLDERSIZES="+ Script.config.CALCFOLDERSIZES_on_value);
  }
  else
  {
    logMsg("The 'autosize' variable is NOT set!");
    objCmd.RunCommand("Set CALCFOLDERSIZES=off");
  }
  objCmd.UpdateToggle();
  delete objCmd;
}
 
function IsDebugEnabled()
{
  var objCmd = DOpus.CreateCommand;
  return (Script && Script.config.DEBUG) || objCmd.IsSet("$glob:debug");
}

// Subroutine to allow toggling of the global DEBUG variable to control whether logging is performed or not
function logMsg(message)
{
   if (IsDebugEnabled()) DOpus.Output(message);
   return;
}

Sample File Display toolbar button

<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<label>AutoSize src</label>
	<tip>AutoSize for source</tip>
	<icon1>#SmartCalcFolderSizesBasic:SmartCalcFolderSizesOn</icon1>
	<function type="normal">
		<instruction>@toggle:if $src:autosize</instruction>
		<instruction>@icon:#SmartCalcFolderSizesBasic:SmartCalcFolderSizesOff,CALCFOLDERSIZES=off</instruction>
		<instruction />
		<instruction>@ifset:$src:autosize</instruction>
		<instruction>@set src:autosize</instruction>
		<instruction>SmartCalcFolderSizes</instruction>
		<instruction>@ifset:else</instruction>
		<instruction>@set src:autosize=true</instruction>
		<instruction>SmartCalcFolderSizes</instruction>
		<instruction>@ifset:common </instruction>
	</function>
</button>

SmartCalcFolderSizes.osp (3.09 KB)

Yeah, thanks Wow.. o)

This is getting perfect.. now, how to trigger the folder refresh, ah.. I know! o)
I added a GO REFRESH after the "second" SmartCalcFolderSizes ocurrence in the button and voila, working like a charm.
No popup anymore as well.. o)

Thank you both! And Steje, you hopefully don't mind your work being "POC hacked". o)

I don't mind at all. These things are shared here freely for others to use, change, learn from, criticize or ignore. Though to be honest, there's hardly anything at all remaining of my code or approach in that modified script... so really no need to leave my name in any of the comments :slight_smile:.

I also don't see any progress "popups" that you guys are talking about in any case though, so not sure what that's about. I'll have to retest on a stock config, but I can't do that right now.

In any case, I think you guys are both doing something a bit differently than me perhaps. I don't see any of the issues you're talking about with my version of the script. And AFAIK, running GetSizes doesn't "force a refresh" or anything like that. As far as I know, when you 'Go BACK' the already calculated folder sizes are cached by Opus and even manually doing a 'GetSizes' doesn't necessarily cause the folder sizes to actually get recalculated. Maybe I have to try on a slower USB drive or something in order to see an effect, but if you're going 'UP' and not 'BACK' then you will see what you're talking about. To that point, all of my 'Go UP' buttons and hotkeys are set to do 'Go UP BACK' which also preserves the previously cached folder sizes...

@wowbagger, by all means - hack away :wink: However, a few observations beyond those I made above:

  • The reason that I implemented the SmartGetSizes action as a ScriptCommand was so that it could be used in the button when toggling the autosize feature on. This was done so that just pressing the button to turn it on ALSO calculated the current folder sizes - specifically so that you didn't have to manually do a 'Go REFRESH' (which BTW - doesn't work at the root of a library with the 'Set CALCFOLDERSIZES' option turned on) or manually do a GetSizes (which also doesn't work if you have something selected when you run the command).

  • Also, this observation:

...is slightly incorrect. While the VARIABLE you're toggling in the button is still going to be based on either the source TAB or LISTER level... I can assure you that using the 'Set CALCFOLDERSIZES' command affects all tabs and all listers. I see what you were trying to do in your 'OnActivateTab' and 'OnSourceDestChange' ~patches... but you'd need to add additional patching to catch other scenarios... such as OnOpenTab and OnOpenLister, etc. To me, it seems more complicated to turn on a GLOBAL option only to have to catch multiple other events just to defeat that global option from remaining in effect when you don't want it to... Just my opinion of course, but surely creative :slight_smile:.

Yeah but... only just that ONE set param though, yeah?

I had wondered why you did this... and though I would probably just have done all of that stuff in the logMsg() function itself rather than a separate function call, what you're doing with the check for $glob:debug is a neat idea if you have multiple scripts which use my sort of debug log handler... you can turn debug on for ALL of them by setting a global var. NEAT, and something I may adopt!

Good plan. I had been pressing F5 to do the refresh but that is a better idea. I was worried a forced refresh would make it rescan, but if its on the button that should be good.

I think the popup displays after a few seconds, try a folder that has a lot of child folders with lots of data in them. Interesting though perhaps we have some different config. I see your point about going up instead of back.

Good point, I believe tbone comment will correct this.

Completely agree. For the button I edited the getsize button (by Cris), to add a grey and green state . The toggle still works the same as your made it. But the icon changes based on the state of CALCFOLDERSIZES. Grey arrows mean CALCFOLDERSIZES off, green means CALCFOLDERSIZES is enabled. Which I think highlights the point, esp of source is toggled on and dest is toggled off, bot Folder Display toolbar buttons are green. The coloring also makes it easier to know if an event has been missed, at first I was missing the OnSourceDestChange event. Other events might need to be added.

That is correct, If could mean that there is a config file that is being updated every time it changes?

I copied this from another script I had written, where I didn't have a log method. In that script I also use the IsDebugEnabled() function to hide/show the console of an exe I run.
I have a button (I think it was ABR's code I based this off) that sets the global flag and shows the log.

<?xml version="1.0"?>
<button backcol="none" display="icon" textcol="none">
	<label>set debug</label>
	<icon1>#bugs</icon1>
	<function type="normal">
		<instruction>@toggle:if $glob:debug</instruction>
		<instruction />
		<instruction>@ifset:$glob:debug</instruction>
		<instruction> @set $glob:debug</instruction>
		<instruction> Set UTILITY=Off</instruction>
		<instruction>@ifset:else</instruction>
		<instruction> @set $glob:debug=true</instruction>
		<instruction> Set UTILITY=OtherLog,On</instruction>
	</function>
</button>

FYI: with 'Set CALCFOLDERSIZES' doing a REFRESH will not cause sizes to be calculated in the root of a library folder. One of the reasons that I added 'SmartGetSizes' to my original example buttons...

Not quite in all cases, see above...

Yes, it'll update Prefs.ocx. Every time you do anything that causes any of the events you need to add to the script in order to ~suppress the behavior once it's been turned on will cause an update. One of the reasons I think this method is a bit overly complicated. Though, I don't think Opus always writes the option changes out to disk ~immediately. I say this because I've seen changes not take effect immediately in all cases when I've been in the midst of comparing the prefs file from one of my backups to the live running file while making changes in prefs dialog... and I've noticed a lag in writes out to disk.

Both 'libraries' and 'lib://Downloads' seem to be working on my setup. If this does prove to be an issue, calling 'SmartGetSizes' on problematic folders might be an option.

Using the $src variables to make buttons that have tab specific state is a neat idea, I would not have though of it. Will be interesting to see what else it can be used for.

I've updated the package(s) again... partly just to bring them consistent with my newly arrived at choice of handling log message control via a global variable all my scripts will now use to control message logging (in ADDITION to the script level DEBUG option most of them allow via Prefs)... but also to add support for a GLOBAL (glob:autosize) variable to control script behavior - in addition to the source TAB support I added in the previous update.

I hadn't thought there'd be any sense in having support for a GLOBAL var... since that's one of the differences between my script and the built-in 'Set CALCFOLDERSIZES' command... but it was trivial to add, and if someone IS in fact using the script and purposefully wants to use multiple different levels of control depending on what sort of work they're doing, then I wouldn't want them to have to do lister and tab level stuff with my script only to then have to add in additional button control using the 'Set' command... just keep it all in the script :wink:.

Root post updated with new version... no ~functional change other than some renaming of scripts to match a new standard I've settled on as well as added an option to clear log messages between script runs.

Found this thread while searching for something very similar. I followed the directions in the first post and successfully created the [AutoSize] button... nicely done. Everything works fine unless the [AutoSize] button is active while DO is at "This PC" where it displays all the hard drives on my system. Then I received this error "The operation is not supported by this VFS." Once I click [OK] everything works fine.

Also, wondering if it's possible to use the Size column itself to enable/disable AutoSize? Seems like the only time I need the size of more than one file or folder is when I want to sort the listing by Size. Sort by Size turns it on. Sort by any other column turns it off. Just don't know if that's possible or not.

It was interesting to see all the ideas and changes, and it's nice to know what can be done with Directory Opus.

Thanks

You don't need a script if you just want a way to trigger folder size calculations on-demand.

There's a menu item in the default Edit menu which does it (or push Ctrl+L or Ctrl+K, depending on how old your menus are). If something is selected, only that is calculated, and if nothing is selected everything is.

You could also set up a button or hotkey which sorts by size and triggers folder size calculations in a single click, if desired.

Root post updated with a few small corrections. I'll see what I can do about suppressing the VFS error when in the 'This PC' or 'My Computer' virtual folder...