SmartGetSizes_Handler: Toggle automatic folder size calculation

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