SmartGetSizes_Handler: Toggle automatic folder size calculation

Great.... feedback welcome and appreciated.

I tested it, & it works! Cool :sunglasses: . maybe i leave the auto calcultae for my big images collection off, since it takes quite a time after booting to calculate.
Now i have defined two buttons (for AB's version), to calculate the sizes on demand, without having to fiddle with the prefs/save for tab & layout etc.

If this is working for all internal settings/commands in the prefs, without having to nag GP to provide another seldomly needed raw command,
that would be great - uhm, given, that anyone is so kind to code it for us. :smiley:

I'm really looking forward to see, what else those scripts are able to do. Very promising! :thumbsup:

Keep in mind that GPSoft did indeed add a raw Set command to toggle the auto size option on/off. What mine has going for it is that it is lister specific (and if anyone had interest, we could fairly easily add a configuration option to make it TAB specific as well).

Besides that, the example button I provided makes use of my ScriptCommand variation on Jon's 'SmartGetSizes' command so that you also get the folder sizes calculated in the folder you're in at the time you press the button to toggle auto-size on.

If anyone is interested in a Tab-specific option for my version here - shout... and I'll update the script package.

But about being able to toggle all Prefs options, my script version is really just "simulating" this. It's not actually toggling the option, just using a new Opus 11 environment variable in the 'button' portion to control whether or not the 'script' potion then issues the 'SmartGetSizes' command or not. GPSoft haven't actually provided any sort of script specific interface for playing with the options in Prefs :slight_smile:. But as is usually the case, just as they implemented the 'Set CALCFOLDERSIZES' command in response to the same user that inspired me to write this script version - I expect they will continue to entertain enabling other Prefs options via raw commands as people ask, so long as they see the value in doing so. Doing all the work to toggle EVERY prefs option available doesn't really make sense unless they're all out of ideas for new features :wink:.

I always use dual listers with several tabs opened and I would not want all of them to be size-calculated if I toggle automatic folder size calculation.
So this is the shout for that tab-specific option.. o) Thx.. o)

@aussieboykie
Your version of the toggle button makes my toolbar grow somewhat in v-size (about 20pixels), while stejes original does not, even both show the same text and icon.

Any idea what is causing this?

EDIT:
It seems, the button being a "3 button" type made it higher somehow. I don't know what type is it now, but it is even sized now, maybe useful for anybody - visual toggling seems to be enhanced as well.

<?xml version="1.0"?>
<button backcol="none" display="icon" dropdown_glyph="yes" label_pos="right" textcol="none" type="menu_button">
	<label>AutoSize</label>
	<tip>Auto-size sub folders</tip>
	<icon1>#getsizes</icon1>
	<function type="normal">
		<instruction>@toggle:if $lst:autosize</instruction>
		<instruction />
		<instruction>@ifset:$lst:autosize</instruction>
		<instruction>@set lst:autosize</instruction>
		<instruction />
		<instruction>@ifset:else</instruction>
		<instruction>@set lst:autosize=true</instruction>
		<instruction>SmartGetSizes GETALL NODESELECT</instruction>
	</function>
	<button backcol="none" display="both" textcol="none">
		<label>Relative Size</label>
		<icon1>#getsizes</icon1>
		<function type="normal">
			<instruction>@ifset:SORTBY=disksizerel</instruction>
			<instruction>Set COLUMNSTOGGLE=disksizerel(2)</instruction>
			<instruction>Set SORTBY=name</instruction>
			<instruction />
			<instruction>@ifset:else</instruction>
			<instruction>Set SORTBY=+disksizerel(2)</instruction>
			<instruction>SmartGetSizes GETALL NODESELECT</instruction>
		</function>
	</button>
</button>

@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.