[Script] WhiteSpaceCtxMenu

Discuss and share scripts and script files...
Stef123

Re: [Script] WhiteSpaceCtxMenu

Post by Stef123 »

Eureka! It works, actually does. :biggrin: *rubbing hands*
Where are those dancing gif-elephants someone had posted around here?
Many thanks to you, Ken :tup: - very good guidance :appl:

I am still baffled by some procedures, to be honest. At the bottom for instance, where that gargantuan IF-monster tapers off without much ado, I had expected an ELSE block. To regulate the final call to my favorites just before "_Terminate";

Code: Select all

#550; end(1);   //load Favorite Folders 
Without enclosing #550; into curly braces as well - wrapping it into an ELSE-block - it seems to me that my favfolders should be coming up always, no matter what. But it won't. Glad about that, of course, but also baffled.

Isn't that script obliged to run from top to bottom? How else would it evaluate all those lines? So when it encounters this call to favfolders - a regular, run-of-the-mill command, not tied to any conditions ... my mind goes into an endless loop every time I get there and think about it :?:

klownboy
Posts: 4402
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.7171 at 100% 2560x1440

Re: [Script] WhiteSpaceCtxMenu

Post by klownboy »

Hey Stef123, I'm glad you got it working alright.

As far as the final #550, and not having an else, when it comes right down to it, I could have used 2 separate if statements instead in this situation and then the final #550. I suppose the bottom line is if you don't meet any of the conditions (i.e, the file extensions used with the load statements) you want the default menu to display (in your case #550). If the conditions are met (a file extension which you have load statement for is selected) that particular menu is run and the script exits (because of the end statements) so there was no need for another else. So there's really no condition for that default action - you want it to run unless the other conditions are met - which is exactly why you use an else. :) It wasn't in braces because it wasn't part of the if / ifelse. If I had a final else it would have to be. And you are correct, if I didn't have the end statements after each load statement, then #550 would be coming up after the others. In some ways it's good to get the script ended as soon as it has loaded the proper menu and not have to be checking all the other conditions which come after it. In any case, a final else is probably the best way to go even though I have the end statements. I hope that clears it up a bit for you.

Edit: Sorry but no in this case I can not use the final else since it will not catch all the conditions to bring up the default menu. There will be situations where the <curitem> is "1" yet you still want the default to come up. For example, if a 'exe' is selected it will meet the <curitem> equals "1", but there's no load statement in the example script associated with "exe", so the else would bypass it and nothing happens. It could be structured differently but the way this is laid out you can't use the final else.
Last edited by klownboy on 24 Apr 2015 15:31, edited 1 time in total.

Stef123

Re: [Script] WhiteSpaceCtxMenu

Post by Stef123 »

Many thanks. Well explained. :tup:
It's reassuring to hear my reasoning was not completely off, and there could have been an ELSE block. On the other hand I also feel a bit embarrassed
klownboy wrote: ...and the script exits (because of the end statements) so there was no need for another else
Now that you mention it ... :oops:
Not that I didn't notice all those end statements. But in other scripts I had seen them getting deployed as some kind of error-checking, similar to an IF-test, only shorter and more elegant. So I came to simply accept them as a really smart error-code, something to worry about later, when progressing to a more advanced stage of scripting.
klownboy wrote: it's good to get the script ended as soon as it has loaded the proper menu and not have to be checking all the other conditions which come after it.
:roll: This feeds me another bit to chew on. The ramifications of it ... if later stuff does not even get evaluated, it has great bearing on the order of my IF - checks. :?

Intended or not intended, that is the question. Is that being done on purpose to avoid later statements? Or simply taken into account as a side effect? Must go ponder.

klownboy
Posts: 4402
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.7171 at 100% 2560x1440

Re: [Script] WhiteSpaceCtxMenu

Post by klownboy »

Stef123 wrote:if later stuff does not even get evaluated, it has great bearing on the order of my IF - checks.
This is a rather simplistic case. Yes, the first gettokenindex or comparison statement the script runs into which is true (e.g., the extension is "jpg"), it will run the load (open the associated menu - image menu for the jpg file) and end. It's not trying to look for more than one criteria - if it finds the right extension it runs the menu whether it in the front or the rear, it makes no difference. If it doesn't find it, it then runs the default. If you have your script set with load statements with similar criteria (i.e., the same extension types that are in more than one load) only then would it matter as far a order, but I don't think you'd be wanting to do that. If we were looking for multiple criteria we'd have to lay this out differently.
Yes you are right, SC end is conditional:

Code: Select all

end condition, [message], [scope=0
Which means you can set the condition. If you met the condition (i.e., it's true), then the 'end' will end the script or the script resource file depending on the switch. In this case, the condition I set is true because it is (1) so it will end the script. You could have a more elaborate one like this.

Code: Select all

end (exists("$cur_folder") != "2"), "You have not pre-selected a folder in which to build the cache, aborting!";
By the way when this script ends, it will still run the commands in your "_Terminate" section to clear any perms or whatever else you have to do. I hope that clears it up a little further. Stef123, also see my edit on my previous post (I knew there was a reason why I didn't use the 'else' at the end, because with it the script will not run the default menu under all the conditions you want it to.

Stef123

Re: [Script] WhiteSpaceCtxMenu

Post by Stef123 »

Hi Ken,
I am really appreciating this very much. Especially your well-explained logic behind end(1). It bridges a gap between SC help file examples and real scripts that I was utterly unable to figure out. To be honest, I still have a hard time to bend and mold my thinking into this kind of logic. Seems like beating around the bush, why not simply tell it to END instead of letting it evaluate some condition which then results in the action I want? Not to mention the condition itself, evaluating the value of 1 :eh: - no wonder it quits at that point.
klownboy wrote:By the way when this script ends, it will still run the commands in your "_Terminate" section
This seems particularly note-worthy and important to remember. Took quite a while for this to sink in. Could not find any Terminate-command or guideline in scripting help, until I finally figured it's a label as well, with a fitting name that led me astray precisely because of its well-chosen name. What this means, however, that end(1) does not end the script at all as I had assumed. But then why doesn't it resume with the next line outside curly braces? :shock: And the head-scratching starts all over again.

Have tried several variations of if-clauses and sequences with and without ELSE. And finally came to understand your point of not using the final ELSE block. Still flawed in my own approach, though, to combine conditions. Turns out I had assumed some kind of built-in smartness that seemed natural to me, but that SC does not have. I cannot combine conditions other than by explicitly linking them with OR. In the light of these findings it doesn't matter, of course, that IF stops evaluating after the first hit. It couldn't combine the results anyway, even if it went through the remaining checks.

Thank you very much, Ken. Would have been completely lost w/o your explanations.
Stef

PeterH
Posts: 2826
Joined: 21 Nov 2005 20:39
Location: DE W11Pro 24H2, 1920*1200*100% 3840*2160*150%

Re: [Script] WhiteSpaceCtxMenu

Post by PeterH »

Stef123 wrote:... To be honest, I still have a hard time to bend and mold my thinking into this kind of logic. Seems like beating around the bush, why not simply tell it to END instead of letting it evaluate some condition which then results in the action I want? Not to mention the condition itself, evaluating the value of 1 :eh: - no wonder it quits at that point.
One part is simple: you often check for some condition, and if it's not met you want to End the current script.
(I.e. you need 1 file. If number of files is not 1 :arrow: End. That's one statement :D )

But if I need no condition, I also often just write End; - to learn that this doesn't end :oops:

So the default for the condition should be TRUE:
- either you have no condition: only TRUE makes sense (else it's a Null instruction)
- or you code a condition: the default doesn't matter :biggrin:

klownboy
Posts: 4402
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.7171 at 100% 2560x1440

Re: [Script] WhiteSpaceCtxMenu

Post by klownboy »

Hi Stef123, you didn't find information on "_Terminate in the scripting command since it's not a command but a special type of script you can have within a script resource file [ ::rtfm "idh_scripting.htm#idh_scripting_multi"; ] The "_Terminate is a special script that will be run when the script file finishes regardless of the use of end. You can read the help section I pointed to but "_Terminate" will be auto-processed after the script selected from the menu has been processed (or after the menu has been canceled). However, if you call a script via load or sub the "_Terminate" section is not called or run automatically. You don't have to have a "_Teminate" at all unless you have to do some clean up work.

Yeah, SC end can be confusing, just remember it ends with a true evaluation of condition, so look at end(1), or you may have seen end(1==1), as establishing the true condition. You can change the scope of end as well to either end the entire script resource file (default, scope is 0) or just the script (scope is 1). Sure Don could have an SC end which simply ended the script period, but why not make the SC powerful and allow a condition to end which can be very handy.

The "if" blocks checking file extensions in this case are all under the lead-in "if" block of checking for "if(exists("<curitem>") == 1) {" so that complicates the situation as well. As I said above you can have many extensions that you have no established load statements (for example an "exe" extension) yet it meets the "exists" criteria. So those are the cases which would not be covered when the "else" with brackets is used below because it met the "if(exists("<curitem>") == 1) {" it would be bypassed by the else because it's not an else. :)

oops PeterH beat me to it.

Stef123

Re: [Script] WhiteSpaceCtxMenu

Post by Stef123 »

Thank you both, Peter and Ken
yes, the end-construct as a slick alternative to If-then is something I've seen in many scripts, as some kind of error-checking. It's the evaluation of 1 that threw me off. Sent my mind into a spinning circle. In general, I find verbose and wordy code lines easier to understand than super-short nested snippets where every symbol carries enormous clout.

Have begun writing up my own SC help topics, and realize I must adopt a rather nonchalant attitude towards the whole thing. My only way to cope with it and avoid frustration is by thinking of it as "figures of speech" - the way I tackle real languages as well. Not trying to make sense of it - very contrary to what I expected programming to be like - but rather trying to match parrot-phrases to circumstances. Similar to "awesome" or "nice to meet you".

So what I've learned here, it helps to humanize a script. Instead of bossing it around in a military tone of voice, you throw it a bone like end(1) and let it arrive at the decision itself, instead of commanding it to END.
klownboy wrote:you didn't find information on "_Terminate in the scripting command since it's not a command but a special type of script you can have within a script resource file [ ::rtfm "idh_scripting.htm#idh_scripting_multi"; ] The "_Terminate is a special script ...
Whoa - I am like zig-zagging to some kind of understanding. Every time I think I got something figured out, it's different yet again. So this terminate-finale is NOT a label you made up after all, but a proper XY thing with proper documentation and all.
klownboy wrote: However, if you call a script via load or sub the "_Terminate" section is not called or run automatically.
Have to read this a few more times, and also the help section that goes along with it. Not easy to digest.
All this must have completely escaped my attention when I read SC help - and I did so repeatedly. If you have no hands-on use case to which it applies, a newbie mind like mine treats those words as synomyns. Script-resource, script-file, multi-script, multi-LINE-script....
klownboy wrote:you may have seen end(1==1), as establishing the true condition
Yes, in SC help, and it seemed complete nonsense. Or rather, so plain obvious that it looks like fools' gibberish. Now of course, I see what you mean. It's trickery to make the script go "Yes, right" and quit. And (1==1) is a synonym for (1) - unless I got something wrong once again.

Concerning those if-lines and if(exists("<curitem>") == 1) - I am still gnawing on it. Need to drag it apart into wider indents and colorize the nested components.
Enough scripting for me today, I better let it rest for while so it can settle and take root.

klownboy
Posts: 4402
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.7171 at 100% 2560x1440

Re: [Script] WhiteSpaceCtxMenu

Post by klownboy »

In using a script like this I've found out in short order that since you loose your normal right click default menu, you may at times miss the "new folder" or "copy to" type menus. What I've done to solve that issue is made a personalized menu of add-on menus that I add to the default or one or more of the file-type specific menus as well.

First do yourself a favor and utilize the User - Manage User Defined commands and make up your specialized "copy to" or "move to" menus of folders to which you frequently copy/move files. I never took advantage of this nice feature. It will make up quick and dirty menu of folders to copy/move/backup files. Each folder you input will end up having its own Command ID that you can use, but more importantly the menu of multiple folders can be raised through a command ID. Yes, it's all in the help file, but this ends up working quite well this script (WhiteSpaceCtxMenu).

Code: Select all

#4	User | Move To | - submenu -
#5	User | Copy To | - submenu -
you may also miss having the Sort / Column / View menus which can be easily solved as well.

Code: Select all

/*** Copy/Move menu ***/
   $CopyMove = <<<COMO
"Copy|:copyto" #5;
"Move|:moveto" #4;
"-"
"Sort...|:sort" #320;
"Columns...|D:\Graphics\Icons\table-select-column-fatcow.ico" #360;
"View...|:viewthumbs" #301;
"-"
"New|:newfolder" #230;
COMO;
This menu can be easily added to any of the other menus you've devised by a load line like this...

Code: Select all

if(gettokenindex("<curext>", "jpg|gif|png|ico", '|', 'i')) {load "$image;<crlf>-<crlf>$CopyMove", ,s; end(1)}   //load image and CopyMove menus together
Unfortunately though you can not simply add a menu like this to Favorite Folders or Favorite File by combining the CID for FF to $CopyMove variable. If you'd like to extract the favorites to use them in a menu which is combined with another, you'd have to do something along these lines...(unless someone knows a way around this?)

Code: Select all

  $FavFolderCount = getkey("Count", "Favorites");
   if($FavFolderCount == "0") {$FFs = "No favorite folders";}
    else {
      $FFs = "";
      $i = 1;
    while ($i <= $FavFolderCount) {
       $a = getkey("Fav$i", "Favorites");
       $FFs = $FFs . $a . "<crlf>";
       $i++;
       }
    }
    $FavFolders = trim($FFs, "<crlf>", 'R');
And then your load line would be something like this...

Code: Select all

load "$FavFolders;<crlf>-<crlf>$CopyMove", ,s; end(1)
...and the default menu or any other menu result something like this...
Combined menus.PNG
Combined menus.PNG (14.6 KiB) Viewed 2764 times
I'll update the first post to include the above. Thanks.

Stef123

Re: [Script] WhiteSpaceCtxMenu

Post by Stef123 »

Useful additions, Ken
my setup looks pretty much the same, except for some minor differences. I specify my targets for CopyTo etc in the heredoc section itself. Saves me the detour via UDC when I need to change something. To quickly edit the script I put an EDIT command at the bottom of my generic section, to be able to access the source code from every sub-menu. It then opens in my favorite editor with the search box open, all sections bookmarked - allows lightning-fast edits and changes on the fly.

I also have FavFolders lined up. Because it can do DUAL and thanks to Sammay's ahk-script I can set up DUAL captions semi-automatically.

Some more addendums :
I included an ELSE line to catch extensions that slip through all previous IF-lines - since I still want to perform my CopyMove stuff on those un-documented extensions. Not sure if I have to rename all your nested IF into ElseIf to be more in line with the structure in SC help? ATM it looks like If - If - If - If - Else - this does not seem quite right

For these unknown selections, I added #176 to my "$other"-heredoc - to try Open-With on them.

I replaced <curitem> with <selitem> to make the If-check more reliable.

I added ampersand accelerators. This combination - right-clicking on the spot, then throwing in 1 - 2 letters has sped up my workflow so much that I am about to include more and more CTB dropdowns in your context menu. I had transplanted their code content into xys long ago, so I can easily call up these already existing CTB-menus.

Finally, I added some SendKey commands, in combination with function-calls to IsProcessRunning. If it is, I bring it up front with the hotkey.

As you can tell, your script has spawned fertile offspring.
Thanks for getting this project under way. It greatly improves the interface, imo.

klownboy
Posts: 4402
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.7171 at 100% 2560x1440

Re: [Script] WhiteSpaceCtxMenu

Post by klownboy »

Hey Stef123, I meant to mention 'your' new <selitem> in my last post. When I update the first post I'll change it to use <selitem> though from the other thread and the beta notes, I'm still not totally clear on the conditions or situations you benefit from its use. Is it mainly the reliability over <curitem>?

Yes, for some file types I have copy/move operations to specific folders directly in the heredoc like you, but the UDC copy to / move is great for a general use or on the default.

Good idea on the sendkeys and IsProcessRunning function too. Though I'm already using AHK for similar duties such as starting XY if it's not already or activating if it is.

As far as the "if" and elseif question just keep in mind that the ifs all come under the lead-in If of, "if(exists("<selitem>") == 1) {" So yes, the first file extension check/load should be "if and all the remaining ones under if(exists("<selitem>")...can be 'elseif' and the last with no criteria can be 'else' So you could do something like this structure:

Code: Select all

     if(exists("<selitem>") == 1) {
		  if(gettokenindex("<curext>", "jpg|gif|png|ico", '|', 'i')) {load "$image;<crlf>-<crlf>$CopyMove", ,s; end(1)}   //load image and CopyMove menus together
		  elseif(gettokenindex("<curext>", "avi|mp4|wmv|wma", '|', 'i')) {load "$vid", , s; end(1)}    //load video menu
		  elseif(gettokenindex("<curext>", "ini|txt|nfo|inf|reg|ps1|vbs", '|', 'i')) {load "$txt", , s; end(1)}   //load textfile menu
        elseif(getpathcomponent("<selitem>", "ext") == "xys") {load("<curitem>"); end(1);}  //ex showing how to auto run an XY script on a right click on white
        else {load "$FavFolders;<crlf>-<crlf>$CopyMove", ,s; end(1)}  // this covers when the <selitem> is valid but you have an odd ball extension not covered above
     }
	  elseif(exists("<selitem>") == 2) {
	     perm $folder = "<curitem>";
        load "$dir", , s; end(1)
     }
	  //if("<selitem>" == "") {      // these 2 methods here work as well as the 'else' that's not commented out
     //elseif(exists("<selitem>") == "0") {
	  else {
	     load "$FavFolders;<crlf>-<crlf>$CopyMove", ,s; end(1)   //this takes care of the "nothing selected" condition or <selitem> is "".
	  }
Or, you could even have the entire structure start out with a if("<selitem>") { and then have the if exists == 1 and if exists == 2 and then the 'else' would cover the conditions when <selitem> was nothing or "". Hope that helps.

Stef123

Re: [Script] WhiteSpaceCtxMenu

Post by Stef123 »

Thanks Ken,
I am reluctant with structural changes for fear of breaking the script. Good to know about the ElseIf - I dared to rewrite and it still works. I like it better this way, conforms to textbook SC help style and does not send my mind reeling. Less nesting, or so it seems.
klownboy wrote:the UDC copy to / move is great for a general use or on the default.
I see what you mean. Some added benefits, too. Just like with UDC-GoTo you get "location not available" whereas in a script it will leave the GUI and pop up a scripting error, unless you script around it which is too much hassle. Easier to use UDC.
klownboy wrote:... use <selitem> though from the other thread and the beta notes, I'm still not totally clear on the conditions or situations you benefit from its use. Is it mainly the reliability over <curitem>?
It also makes selecting easier. I am just not comfortable with clicking into white space - a bad habit that makes you lose your selection in other apps.

To see the advantage of <selitem> over <curitem>, try this:
Right-DRAG into your intended selection, from the outside in, then release the mouse ON the selection. This comes closer to right-clicking a selection directly - just like in regular Windows.
When doing this with <curitem> you will get the very last command - the one that fails the if blocks.
When doing this with <selitem> the if-checks are still in place and allow to use the script by "quasi-clicking" on the selection instead of white space.

However, it will still fail the nested if-checks. Not sure if Don will also add <selext> and maybe even <selsize>.
If he doesn't, I have to go back to

Code: Select all

(getpathcomponent("<selitem>", "ext")
instead of

Code: Select all

gettokenindex("<selext>"
There is more to <selitem> than meets the eye. It's also the only way to right-drag select items if the lower entry is longer than the one above it - too difficult to explain, I only discovered this in real-live situations, when <curitem> sometimes brought up the correct menu, other times it didn't. Now with <selitem> it works consistently.

klownboy
Posts: 4402
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.7171 at 100% 2560x1440

Re: [Script] WhiteSpaceCtxMenu

Post by klownboy »

Thanks Stef123 for your explanation on the selection process using <selitem>. I get it now. That's a great idea right dragging from white space just outside the filename area to be selected into the area and releasing....quick!

I'm a little confused about your discussion on <selext> or not sure what you meant about using <selext> versus getpathcompnent ("<selitem>", "ext"). Though I think you know there's no such thing as <selext> at least now. Try this (which gets the extension of "<selitem>" into a variable, $selext and then uses it in the If and ElseIf statements.

Code: Select all

     if(exists("<selitem>") == 1) {
	     $selext = getpathcomponent("<selitem>", "ext");
		  if(gettokenindex("$selext", "jpg|gif|png|ico", '|', 'i')) {load "$image;<crlf>-<crlf>$CopyMove", ,s; end(1); } 
        ...
The above code seems to work consistently using the above technique. I shouldn't have still been using <curext> in the previous post. At first I had nested the "getpathcomponent" in with the "gettokenindex" all in one line, but since we are performing multiple checks using $selext it makes sense to simply obtain it first once.
Last edited by klownboy on 28 Apr 2015 14:22, edited 1 time in total.

Stef123

Re: [Script] WhiteSpaceCtxMenu

Post by Stef123 »

klownboy wrote:

Code: Select all

	     $selext = getpathcomponent("<selitem>", "ext");
		  if(gettokenindex("$selext", "jpg|gif|png|ico", '|', 'i')) ...
Brilliant :idea:
Now it works even without waiting for this wish here
http://www.xyplorer.com/xyfc/viewtopic. ... 76#p122580

klownboy
Posts: 4402
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.7171 at 100% 2560x1440

Re: [Script] WhiteSpaceCtxMenu

Post by klownboy »

Stef123 wrote:Now it works even without waiting for this wish here viewtopic.php?f=3&t=13876#p122580
If you still think you need a <selext>, you probably should make a new post to the same thread as opposed to editing an existing post since it's possible Don wouldn't see the edit since it's not moved to the top of the thread like a new post. Though Don does keep a watchful eye. :ninja:

Post Reply