Page 2 of 3

Re: Custom context menu for list's whitespace

Posted: 29 Aug 2018 23:32
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?

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 08:04
by highend
And "the error" is...?

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 10:32
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?

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 10:43
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); }

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 10:50
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.

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 11:48
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); }

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 16:51
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

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 17:03
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)

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 17:32
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

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
    }

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 17:41
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

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 17:53
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.

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 18:49
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?

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 18:53
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?...

Re: Custom context menu for list's whitespace

Posted: 30 Aug 2018 18:56
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 )

Re: Custom context menu for list's whitespace

Posted: 09 Sep 2018 17:29
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); }