Custom context menu for list's whitespace

Discuss and share scripts and script files...
John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Custom context menu for list's whitespace

Post by John_C »

highend wrote:You need to assign popupnested()'s return value to a variable and eval that or do it directly in one go.
Atm the menu is displayed but what it returns isn't stored / nor eval()'d

Code: Select all

eval(popupnested($menu));
or

Code: Select all

$selected = popupnested($menu);
eval($selected);
As I said it work! But, it breaks another menu items, lol :biggrin:

Code: Select all

$menu =
    <<<MENU
        Paste;#202;:paste
        Undo;#203;:undo
        Redo;#204;:redo
        Refresh;#1001;:refresh
        New Items
            Foo;new("NewFolder", "dir");
            Bar;new("file.txt");
    MENU;
    $selected = popupnested($menu);
    eval($selected);
    #172; // Rename
Creating new items works perfectly, but when I'm trying to undo/redo something, eval() creates an error for me. Is there way to avoid it?

highend
Posts: 13308
Joined: 06 Feb 2011 00:33

Re: Custom context menu for list's whitespace

Post by highend »

And "the error" is...?
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Custom context menu for list's whitespace

Post by John_C »

highend wrote:And "the error" is...?
For example, when I'm trying to press "Undo", the error is: "Dubious syntax: #203"

As I understand, lines

Code: Select all

        Paste;#202;:paste
        Undo;#203;:undo
        Redo;#204;:redo
        Refresh;#1001;:refresh
should be rewrited in the same manner as

Code: Select all

            Foo;new("NewFolder", "dir");
            Bar;new("file.txt");
. But how?

highend
Posts: 13308
Joined: 06 Feb 2011 00:33

Re: Custom context menu for list's whitespace

Post by highend »

You have syntax checking enabled?

This should help:

Code: Select all

    Instead of:
    eval($selected);
    Use:
    if (strpos($selected, "#") != -1) { eval("""$selected"""); }
    else { eval($selected); }
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Custom context menu for list's whitespace

Post by John_C »

highend wrote:You have syntax checking enabled?

This should help:

Code: Select all

    Instead of:
    eval($selected);
    Use:
    if (strpos($selected, "#") != -1) { eval("""$selected"""); }
    else { eval($selected); }
Yeah, it works. Thank you very much. I will post entire script here, which could be useful for another users. Here it is:

Code: Select all

$menu =
    <<<MENU
        Paste;#202;:paste
        Undo;#203;:undo
        Redo;#204;:redo
        Refresh;#1001;:refresh
        New
            Folder;new("NewFolder", "dir");
            Text Document;new("file.txt");
    MENU;
    $selected = popupnested($menu);
    if (strpos($selected, "#") != -1) {
        eval("""$selected""");
    }
    else {
        eval($selected);
        #172; // Rename
    }
Further possible improvement is to change hard-coded "new" items to dynamically parsing them from "NewItems" folder. Probably someone will have time and desire to post it here.

highend
Posts: 13308
Joined: 06 Feb 2011 00:33

Re: Custom context menu for list's whitespace

Post by highend »

For coders:

I wouldn't do the whole thing with semicolon separators, use pipes instead (new item entries could contain semicolons -> breaks the whole thing)!

Code: Select all

    $newFlags = "r"; // Can be "r" and / or "u" for the new() command
    $cntIndent = 12; // Depends on YOUR indentation under the "New Items" entry in $menu!!!


    $newItems = "";
    $folders = listfolder("<xydata>\NewItems", , 2);
    $files = listfolder("<xydata>\NewItems", , 1);

    foreach($item, $folders . "|" . $files, , "e") {
        $caption = gpc($item, "file");
        $data = 'new("' . $caption . '"' . ((exists($item) == 2) ? ', "dir"' : ", ") . ", ," . (($newFlags) ? ' "' . $newFlags . '")' : ")");
        $icon = $item;
        $newItems .= strrepeat(" ", $cntIndent) . $caption . ";" . $data . ";" . $icon . <crlf>;
    }
    $menu =
    <<<MENU
        Paste;#202;:paste
        Undo;#203;:undo
        Redo;#204;:redo
        Refresh;#1001;:refresh
        New Items
$newItems
    MENU;
    $selected = popupnested($menu);
    if (strpos($selected, "#") != -1) { eval("""$selected"""); }
    else { eval($selected); }
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Custom context menu for list's whitespace

Post by John_C »

highend, probably you know how to make some items in context menu grayed out? For example, when there are no actions to "Undo" - the corresponding item in context menu should be displayed in gray text, instead of regular black (i.e. it will be shown as disabled). Here is what I mean (here is grayed out "Paste" and "Paste shortcut" items, but idea is the same):
grayed_out.png
grayed_out.png (5.2 KiB) Viewed 3069 times

highend
Posts: 13308
Joined: 06 Feb 2011 00:33

Re: Custom context menu for list's whitespace

Post by highend »

popupnested() supports the state in the same way as popupmenu()?

But regarding "Undo": Nope, not possible. The action.dat logfile is a binary only file, you can't just simply read the necessary things from it
The only way would be to keep track of what the different menu items in the script are doing but ofc this wouldn't cover most things outside of it (like the already mentioned action log)
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Custom context menu for list's whitespace

Post by John_C »

@ highend
But regarding "Undo": Nope, not possible.
Thanks for explanation.

One another question. As you can see (in XYplorer's default context menu) selected view is marked with checkbox. I already have the same "View" section in custom context menu (code below), but is there a way to add such checkbox?
selected_view.png
selected_view.png (6.29 KiB) Viewed 3065 times

Code: Select all

$menu =
    <<<MENU
        Views
            Details;#302
            Small icons;#305
            Thumbnails;#306
        Sort by
            Name;#321
            Date modified;#326
            -
            Reverse order;#339
        Refresh;#1001
        -
        Paste;#202
        Undo;#203
        Redo;#204
        -
        New
            Folder;new("NewFolder", "dir");
            Text Document;new("file.txt");
    MENU;
    $selected = popupnested($menu);
    if (strpos($selected, "#") != -1) {
        eval("""$selected""");
    }
    else {
        eval($selected);
        #172; // Rename
    }

highend
Posts: 13308
Joined: 06 Feb 2011 00:33

Re: Custom context menu for list's whitespace

Post by highend »

You would need to add the correct state flag to that entry. In other words, you'd need to modify the menu on the fly (e.g. by modifying the script FILE / or use an external file for the whole menu display stuff). Possible? Sure. A lot of code (which item was used, write the flag into the belonging line for that entry, etc.) would be necessary for this kind of stuff
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Custom context menu for list's whitespace

Post by John_C »

highend wrote:You would need to add the correct state flag to that entry. In other words, you'd need to modify the menu on the fly (e.g. by modifying the script FILE / or use an external file for the whole menu display stuff). Possible? Sure. A lot of code (which item was used, write the flag into the belonging line for that entry, etc.) would be necessary for this kind of stuff
Thanks for explanation, again. I understand.

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Custom context menu for list's whitespace

Post by John_C »

highend wrote:$cntIndent = 12; // Depends on YOUR indentation under the "New Items" entry in $menu!!!
Could you please explain this line and it's comment?

It could be very stupid, but I tried to find 12-spaces indentation in your code - and don't found it (there are 4-spaces indentation and 8-spaces indentation currently). Probably you mean something completely different?

highend
Posts: 13308
Joined: 06 Feb 2011 00:33

Re: Custom context menu for list's whitespace

Post by highend »

How much spaces are in front of every item under "New Items" in the menu structure if "New Items" itself has 8 in front of it and all script levels are indented by 4?...
One of my scripts helped you out? Please donate via Paypal

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Custom context menu for list's whitespace

Post by John_C »

highend wrote:How much spaces are in front of every item under "New Items" in the menu structure if "New Items" itself has 8 in front of it and all script levels are indented by 4?...
Thanks, understand )

John_C
Posts: 336
Joined: 16 May 2018 20:04

Re: Custom context menu for list's whitespace

Post by John_C »

Updated version

Code: Select all

// https://www.xyplorer.com/xyfc/viewtopic.php?f=7&t=19331
// https://www.xyplorer.com/xyfc/viewtopic.php?f=3&t=19373

// Tools > Configuration > Custom Event Actions > Right-click on white in
// file list > Action = Run script > Script = load "your script name.xys"
//
// If using older XY versions, you need to modify the XYplorer.ini instead:
// [Settings]
// CEA_ListRightClickOnWhite=6
// CEA_ListRightClickOnWhite_Script=load "your script name.xys"
//
// The items in the NewItems folder should be named as follows:
// New Folder
// New Text File.txt
// and so on

"Right-Click on White in File List"
  // There should be either r or ru. The flag u allows you to *undo* newly
  // created items, that is, to move them to Recycle Bin.
  $newFlags = "ru";

  // The value must be the same as the number of spaces the $newItems entries
  // are indented by.
  $cntIndent = 6;

  $newItems = "";
  $folders = listfolder("<xydata>\NewItems",, 2);
  $files = listfolder("<xydata>\NewItems",, 1);

  foreach($item, $folders . "|" . $files,, "e") {
    $caption = gpc($item, "file");
    $captionTrimmed = regexreplace($caption, "^New ", "");
    $data = 'new("' . $caption . '"' . ((exists($item) == 2) ? ', "dir"' : ", ") . ",'" . $item . "'," . (($newFlags) ? ' "' . $newFlags . '")' : ")");
    $icon = $item;
    $newItems .= strrepeat(" ", $cntIndent) . $captionTrimmed . ";" . $data . ";" . $icon . <crlf>;
  }
  $menu =
  <<<MENU
    Views
      Details;#302
      Details with Thumbnails;#303
      Thumbnails;#306
      -
      Branch;#311
    Sort by
      Name;#321
      Modified;#326
      -
      Reverse Order;#339
    Refresh;#1001
    -
    Paste;#202
    Undo;#203
    Redo;#204
    -
    New
$newItems
  MENU;
  $selected = popupnested($menu);
  if (strpos($selected, "#") != -1) { eval("""$selected"""); }
  else { eval($selected); }
Last edited by John_C on 22 Mar 2022 10:45, edited 4 times in total.

Post Reply