Page 2 of 4

Re: AHK-script for better surfing of minitree

Posted: 28 Jul 2014 11:15
by autocart
1) Found and corrected another bug. (Exclude-sibling-parent-paths were also applied to any higher parents.)
2) Now, if the content of the XYplorer_MiniTreeBrowsing.ini file is changed, the new values are immediately used w/o having to restart the script.

as always, USAGE AT OWN RISK!!!!!! (Do I have to write that all the time? :veryconfused: )

Code: Select all

        #NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
        #Persistent

        global XY_eval_and_returnvalue_XYRETURN
        XYdata_path := XY_eval_and_returnvalue("<xydata>")
        
        if (not FileExist(XYdata_path . "\XYplorer_MiniTreeBrowsing.ini"))
        {
          FileAppend [on/off settings]`nUse_maxDisplayedSiblings=1`nUse_parentPathsOfNotDisplayedSiblings=1`n`n[values]`nmaxDisplayedSiblings=30`n; paths are seperated by "|"`nparentPathsOfNotDisplayedSiblings=
            , %XYdata_path%\XYplorer_MiniTreeBrowsing.ini
          if ErrorLevel
          {
            MsgBox %XYdata_path%\XYplorer_MiniTreeBrowsing.ini`n`nProblem writing to ini file. Exiting script.
            ExitApp
          }
          Use_maxDisplayedSiblings := 1
          Use_parentPathsOfNotDisplayedSiblings := 0
          maxDisplayedSiblings := 30
          parentPathsOfNotDisplayedSiblings := ""
          FileGetTime, XYMiniTreeBrowsing_ini_lastModTime, %XYdata_path%\XYplorer_MiniTreeBrowsing.ini, M
        }
          
        Read_XYplorer_MiniTreeBrowsing_ini()
        {
          global
          local iniReadError := ""
          IniRead Use_maxDisplayedSiblings, %XYdata_path%\XYplorer_MiniTreeBrowsing.ini, on/off settings, Use_maxDisplayedSiblings
          iniReadError := iniReadError . Use_maxDisplayedSiblings . "|"
          IniRead Use_parentPathsOfNotDisplayedSiblings, %XYdata_path%\XYplorer_MiniTreeBrowsing.ini, on/off settings, Use_parentPathsOfNotDisplayedSiblings
          iniReadError := iniReadError . Use_parentPathsOfNotDisplayedSiblings . "|"
          IniRead maxDisplayedSiblings, %XYdata_path%\XYplorer_MiniTreeBrowsing.ini, values, maxDisplayedSiblings
          iniReadError := iniReadError . maxDisplayedSiblings . "|"
          IniRead parentPathsOfNotDisplayedSiblings, %XYdata_path%\XYplorer_MiniTreeBrowsing.ini, values, parentPathsOfNotDisplayedSiblings
          iniReadError := iniReadError . parentPathsOfNotDisplayedSiblings . "|"
          if (InStr(iniReadError, "ERROR", 1))
          {
            MsgBox %XYdata_path%\XYplorer_MiniTreeBrowsing.ini`n`nProblem reading from ini file. To ensure that at least the format of the ini file is correct, delete it and run the exe again, so that it will create it anew. Exiting script.
            ExitApp
          }
        }
        
        
        
        ;***************************************************************************************
        ;** code from others (or based on) **
        ;***************************************************************************************

        ;heavily based on
        ;http://www.xyplorer.com/xyfc/viewtopic.php?f=7&t=9233&p=89555&hilit=messenger#p89555
       
        ;~ MsgBox % A_ScriptHwnd + 0
        ;~ OnMessage(0x4a, "Function_Receive_WM_COPYDATA")

            XY_eval_and_returnvalue(stringToEval)          ;Send message to XYplorer
            {
              SetTitleMatchMode, 2
              SetWinDelay, 0
              WinWait XYplorer ahk_class ThunderRT6FormDC
              global XY_eval_and_returnvalue_XYRETURN
              SenderHWND := A_ScriptHwnd + 0  ;Return this script's hidden hwdn id.  +0 to convert from Hex to Dec
              if (SubStr(stringToEval,1,9) = "noreturn ")
              {
                stringToEval := SubStr(stringToEval,10)
                MessagetoXYplorer := "::" stringToEval    ;"noreturn loadtree get('tree').'|'.listfolder(,,2)"  resolved to sth like this:   ::loadtree get('tree').'|'.listfolder(,,2)
              }
              else
              {
                MessagetoXYplorer := "::CopyData " SenderHWND ", " stringToEval ", 0"    ;resolved to sth like this:   ::CopyData 7409230, <curitem>, 0   _OR like this:  ::CopyData 7409230, tab('get','count'), 0
              }
              HWND := WinExist("XYplorer ahk_class ThunderRT6FormDC")
              Size := StrLen(MessagetoXYplorer)
              If !(A_IsUnicode)
              {
              VarSetCapacity(Data, Size * 2, 0)
              StrPut(MessagetoXYplorer, &Data, Size, "UTF-16")
              }
              Else
              Data := MessagetoXYplorer

              VarSetCapacity(COPYDATA, A_PtrSize * 3, 0)
              NumPut(4194305, COPYDATA, 0, "Ptr")
              NumPut(Size * 2, COPYDATA, A_PtrSize, "UInt")
              NumPut(&Data, COPYDATA, A_PtrSize * 2, "Ptr")
              XY_eval_and_returnvalue_XYRETURN := ""
              OnMessage(0x4a, "Function_Receive_WM_COPYDATA")  ; 0x4a is WM_COPYDATA. This onhold and wait for the WM_Copydata from XYplorer then execute Function_Receive_WM_COPYDATA(wParam, lParam) below
              SendMessage, 0x4a, 0, &COPYDATA, , ahk_id %HWND% ;SendMessage waits for the target window to process the message, up until the timeout period expires.
              OnMessage(0x4a, "")
              return XY_eval_and_returnvalue_XYRETURN
            }

            Function_Receive_WM_COPYDATA(wParam, lParam)
            {
              global XY_eval_and_returnvalue_XYRETURN
              StringAddress := NumGet(lParam + 2*A_PtrSize) ;lParam+8 is the address of CopyDataStruct's lpData member.
              CopyOfData := StrGet(StringAddress)    ;May also specify CP0 (default) or UTF-8 or UTF-16:   StrGet(StringAddress, NumGet(lParam+A_PtrSize), "UTF-16")
              cbData := NumGet(lParam+A_PtrSize)/2  ;cbData/2 = String length
              StringLeft, Datareceived, CopyOfData, cbData
              XY_eval_and_returnvalue_XYRETURN := Datareceived
              ;~ MsgBox % Datareceived
            }
          
        ;***************************************************************************************

            ;~ XY_curPath := XY_eval_and_returnvalue("<curpath>")
            SetTimer, Label1, 150
            return
          
          Label1:
            XY_curPath_new := XY_eval_and_returnvalue("<curpath>")
           
            If (XY_curPath != XY_curPath_new)
            {
              XY_curPath := XY_curPath_new
              
              FileGetTime, XYMiniTreeBrowsing_ini_lastModTime_new, %XYdata_path%\XYplorer_MiniTreeBrowsing.ini, M
              if(XYMiniTreeBrowsing_ini_lastModTime != XYMiniTreeBrowsing_ini_lastModTime_new)
              {
                Read_XYplorer_MiniTreeBrowsing_ini()
                XYMiniTreeBrowsing_ini_lastModTime := XYMiniTreeBrowsing_ini_lastModTime_new
              }
              
              FileGetTime, XYini_lastModTime_new, %XYdata_path%\XYplorer.ini, M
              if (XYini_lastModTime != XYini_lastModTime_new)
              {
                XYini_file := FileOpen(XYdata_path . "\XYplorer.ini", "r")
                if XYini_file
                {
                  XYini_lastModTime := XYini_lastModTime_new
                  XYini_line := ""
                  Loop
                  {
                    XYini_line := XYini_file.ReadLine()
                  }
                  until SubStr(XYini_line, 1, 22) = "MiniTreePathsFavorite=" or XYini_file.AtEOF
                  if (XYini_file.AtEOF)
                  {
                    XYfavMiniTree_paths := ""
                  }
                  else
                  {
                    XYfavMiniTree_paths := SubStr(XYini_line, 23)
                    XYfavMiniTree_paths := RTrim(XYfavMiniTree_paths, "`n`r")
                    if (XYfavMiniTree_paths)
                    {
                      XYfavMiniTree_paths := XYfavMiniTree_paths . "|"
                    }
                  }
                  XYini_file.Close()
                }
                else
                {
                  XYfavMiniTree_paths := ""
                }
              }

              XYcurFolder_directSubfolderPaths := XY_eval_and_returnvalue("listfolder('" . XY_curPath . "',,2)")
              if (XYcurFolder_directSubfolderPaths)
              {
                XYcurFolder_directSubfolderPaths := XYcurFolder_directSubfolderPaths . "|"
              }

              XYcurFolder_siblingFolderPaths := ""
              SplitPath, XY_curPath,,XY_curPath_parent ;only works correctly on XY_curPath withOUT trailing backslash which is the case with <curpath> (see up above)
              if (XY_curPath != XY_curPath_parent) ;if XY_curPath is the root of a drive (e.g. only "C:") then the result for parent is the same and also there are no siblings for the tree
              {
                retrieveSiblingFolders := 1
                if (Use_parentPathsOfNotDisplayedSiblings and (InStr(parentPathsOfNotDisplayedSiblings . "|", XY_curPath_parent . "|") or InStr(parentPathsOfNotDisplayedSiblings . "|", XY_curPath_parent . "\|")))
                {
                  retrieveSiblingFolders := 0
                }
                XYcurFolder_siblingFoldersCount := XY_eval_and_returnvalue("listfolder('" . XY_curPath_parent . "',,34)")
                if (Use_maxDisplayedSiblings and XYcurFolder_siblingFoldersCount > maxDisplayedSiblings)
                {
                  retrieveSiblingFolders := 0
                }
                if (retrieveSiblingFolders)
                {
                  XYcurFolder_siblingFolderPaths := XY_eval_and_returnvalue("listfolder('" . XY_curPath_parent . "',,2)")
                }
              }
              
              ;~ MsgBox % XY_curPath . "|" . XYfavMiniTree_paths . XYcurFolder_directSubfolderPaths . XYcurFolder_siblingFolderPaths
              XY_eval_and_returnvalue("noreturn loadtree '" . XY_curPath . "|" . XYfavMiniTree_paths . XYcurFolder_directSubfolderPaths . XYcurFolder_siblingFolderPaths . "'")
            }
            return

Re: AHK-script for better surfing of minitree

Posted: 28 Jul 2014 11:26
by SkyFrontier
Hey, thanks for the updates!
Will pop back with any relevant comments, if any.

Re: AHK-script for better surfing of minitree

Posted: 28 Jul 2014 12:55
by autocart
New version 0.004 - can be downloaded from 1st post: http://www.xyplorer.com/xyfc/viewtopic. ... 27#p109427
Simplified the ini file:

EDIT: starting with v0.006 the default ini file (crated on start if it does not exist already), will look like this:
[values]

; MaxDisplayedSiblings is an all-or-nothing setting.
; If the sibling folders (in relation to the current path) would be more than the here
; defined number then they are not shown in the MiniTree. In order not to use this feature,
; simply do not define any number. In this case all siblings are shown (depending on the
; next value, though).

maxDisplayedSiblings=

; You can define for which folders, when they become current, NO siblings should be shown
; in the MiniTree, by defining the PARENT path here. Paths are seperated by "|". In order
; not to use this feature, simply do not define any path. (This value and the previous one
; are additional to each other. If no "path" applies but the count of siblings is more than
; maxDisplayedSiblings then they are still not displayed and vice versa.)

parentPathsOfNotDisplayedSiblings=

Re: AHK-script for better surfing of minitree

Posted: 28 Jul 2014 13:22
by autocart
update to v0.005: corrected an error popping up when browsing to a drive that is not ready, e.g. empty CD-ROM drives
http://www.xyplorer.com/xyfc/viewtopic. ... 27#p109427

Re: AHK-script for better surfing of minitree

Posted: 28 Jul 2014 14:01
by autocart
Ok, in the next update I changed the behaviour of the maxDisplayedSiblings setting. Disabling will simply be by leaving it blank (like the other setting). Actually only 0 and positive numbers will have an effect, so -1 will still work for disabling.
Other than that (this is such a small change):
Do you guys have any ideas for improving this script further?, so that it might be worth publishing a new version... :kidding:

Re: AHK-script for better surfing of minitree

Posted: 28 Jul 2014 14:12
by SkyFrontier
"Problem writing to ini file".
Exe shuts then.
v5 & 4. v3 (no-Ini) works fine.
-running as admin overcomes the problem.

-distinctive icon would be nice.
-is it possible to restrict it's usage to a single instance by declaring a path via .ini?
-ini controlled expansion hehavior: opened folders only (keeping the per-tab usage, adding one at a time as they are opened by navigation) or current one.

Re: AHK-script for better surfing of minitree

Posted: 28 Jul 2014 15:01
by autocart
v0.006: changed behaviour of maxDisplayedSiblings: in order not to use it (deactivate it) simply do not define any number (leave blank)
corrected a bug with FileAppend writing ini if it was not there
added #SingleInstance force
http://www.xyplorer.com/xyfc/viewtopic. ... 27#p109427

thx for your feedback, SF
SkyFrontier wrote:"Problem writing to ini file".
Exe shuts then.
v5 & 4. v3 (no-Ini) works fine.
-running as admin overcomes the problem.
I don't think that it was an admin-problem. It was a "real" bug in the code. I don't know what the script did differently, when you ran it as admin.
SkyFrontier wrote:-distinctive icon would be nice.
-is it possible to restrict it's usage to a single instance by declaring a path via .ini?
-ini controlled expansion hehavior: opened folders only (keeping the per-tab usage, adding one at a time as they are opened by navigation) or current one.
- Icon -> do you have one for me that I am allowed to use?
- single instance -> good idea, done. What do you mean by "by declaring a path via .ini"?
- last point -> i am glad you have more input, but I don't understand. Can you elaborate on this more clearly, please?

Re: AHK-script for better surfing of minitree

Posted: 30 Jul 2014 09:24
by autocart
I now made also a simpler version. This version is called "XYplorer_MiniTreeExpandDestination" and will only expand the destination node in the MiniTree, regardless of how one navigates there. It also does a "refresh" afterwards in order to solve the '+' signs (subfolders) in the MiniTree. This version does not depend on an ini file.
http://www.xyplorer.com/xyfc/viewtopic. ... 27#p109427

Re: AHK-script for better surfing of minitree

Posted: 30 Jul 2014 10:54
by SkyFrontier
Hi there!
Yes, "#singleInstance force" is a trick but I was referring the XY instance affected by the AHK exe. I usually work with 4-5 XY instances and discovered how bad can it be not restricting the AHK to one of them: losing a ~200 hand picked items selection when AHK turned miniTree ON for that instance.

The icon suggestion is a fugue's one - please remove the .zip pseudo extension. I really don't like it but have no better idea.

>>>-ini controlled expansion hehavior: opened folders only (keeping the per-tab usage, adding one at a time as they are opened by navigation) or current one.
Think about what MiniTree currently does: your concept seems to allow that each tab (plus every navigated folder beyond or below initial path) could have its own MiniTree on tab-switching. I'd like to have that behavior WITHOUT listing all subfolders of current folder. In short, per-tab MiniTrees.
This mode could be switched on/off via ini tweak.

Thanks for keeping up the great work! =)

Re: AHK-script for better surfing of minitree

Posted: 30 Jul 2014 11:08
by SkyFrontier
XYplorer_MiniTreeBrowsing.exe, v6 - now even running as admin pops the write to ini error. Unusable.
:cry:
-not even v5 or v4, only v3 (no-ini version) runs ok.
:|

Re: AHK-script for better surfing of minitree

Posted: 30 Jul 2014 13:20
by autocart
SkyFrontier wrote:Hi there!
Yes, "#singleInstance force" is a trick but I was referring the XY instance affected by the AHK exe. I usually work with 4-5 XY instances and discovered how bad can it be not restricting the AHK to one of them: losing a ~200 hand picked items selection when AHK turned miniTree ON for that instance.
I added a security check. The scipt will only take effect if the MiniTree is turned on manually. (For the next version. :mrgreen: )

Other than that I am not sure how you would want to differentiate between the various XY instances. I can differentiate between the XY instances internally in the script but to let the user determine which instance of XY should be treated by the script and which not, seems to me a huge task right now. Does the script actually take effect in all the instances or just one of them?
SkyFrontier wrote:The icon suggestion is a fugue's one - please remove the .zip pseudo extension. I really don't like it but have no better idea.
Did you create it yourself. If not, where is it from? I want to make sure that I have the right to copy and use it.
SkyFrontier wrote:>>>-ini controlled expansion hehavior: opened folders only (keeping the per-tab usage, adding one at a time as they are opened by navigation) or current one.
Think about what MiniTree currently does: your concept seems to allow that each tab (plus every navigated folder beyond or below initial path) could have its own MiniTree on tab-switching. I'd like to have that behavior WITHOUT listing all subfolders of current folder. In short, per-tab MiniTrees.
This mode could be switched on/off via ini tweak.
Well, that "per tab" only seems that way. It's more of an algorithm that re-calculates the shown folders on every path-change, based on some variables, one of which is the current folder. But I can add the subfolders on/off as a switch to the ini, no problem. It just does not sound as if my script really is what you are looking for, even with the subfolders turned off.

However, it would be possible and reasonably "simple" to make a script providing MiniTrees on a real "per folder" respectively "per path" basis (remembering what folders are expanded), which would be very similar to a "per tab" basis. That would probably be a whole new project, though.
SkyFrontier wrote:Thanks for keeping up the great work! =)
Thank you for these words, that's just what I need. :biggrin:
SkyFrontier wrote:XYplorer_MiniTreeBrowsing.exe, v6 - now even running as admin pops the write to ini error. Unusable.
:cry:
-not even v5 or v4, only v3 (no-ini version) runs ok.
:|
That's weird, but as a "simple" workaround, create the "XYplorer_MiniTreeBrowsing.ini" file yourself in the XYdata-path. Or copy it from the downloaded zip to the XYdata-path. (Of course adapt the settings to your whishes afterwards.) That should solve the problem.

Re: AHK-script for better surfing of minitree

Posted: 30 Jul 2014 17:05
by SkyFrontier
I added a security check. The scipt will only take effect if the MiniTree is turned on manually. (For the next version. :mrgreen: )
>>great!
Other than that I am not sure how you would want to differentiate between the various XY instances. I can differentiate between the XY instances internally in the script but to let the user determine which instance of XY should be treated by the script and which not, seems to me a huge task right now.

>>ini control won't suffice for that? Strange.

Does the script actually take effect in all the instances or just one of them?
>>once an instance gets foreground state. Alternatively all of the time, in case. :roll:

Did you create it yourself. If not, where is it from? I want to make sure that I have the right to copy and use it.
>>C.C 3.0 - http://p.yusukekamiyamane.com/

However, it would be possible and reasonably "simple" to make a script providing MiniTrees on a real "per folder" respectively "per path" basis (remembering what folders are expanded), which would be very similar to a "per tab" basis. That would probably be a whole new project, though.
>>Each path outside current one being added to the TAB-based MiniTree, right? Any chance of a whole session being stored, then? This would monstrously benefit my workflows. Seriously. Iconized tabs + customs icons. Think bout the future...!

Thank you for these words, that's just what I need. :biggrin:
>>...need more? :appl: :wink:

That's wired, but as a "simple" workaround, create the "XYplorer_MiniTreeBrowsing.ini" file yourself in the XYdata-path. Or copy it from the downloaded zip to the XYdata-path. (Of course adapt the settings to your whishes afterwards.) That should solve the problem.
>> :eh:
"It need to be located in the xydata path." should look like
It need to be located in the xydata path.
Problem solved.
Guys,
It need to be located in the xydata path.

Re: AHK-script for better surfing of minitree

Posted: 04 Aug 2014 15:27
by autocart
New version: http://www.xyplorer.com/xyfc/viewtopic. ... 27#p109427
(sorry for the long delay)
v0.007:
added support for dynamic drives
added a security check, so that the script only takes effect if the MiniTree is turned on manually
added a refresh (#1001;) after loadtree
added an option to the ini file: "showDirectSubfolders" (1 means yes. Everything else means no.)

Re: AHK-script for better surfing of minitree

Posted: 06 Aug 2014 13:13
by autocart
SkyFrontier wrote:I added a security check. The scipt will only take effect if the MiniTree is turned on manually. (For the next version. :mrgreen: )
>>great!
Does the security check (which is implemented now) in the latest version solve your multi-instance issue or do you need a more complicated solution?
SkyFrontier wrote:I'd like to have that behavior WITHOUT listing all subfolders of current folder. ....
This mode could be switched on/off via ini tweak.
I added this feature in the last version. Does it work out well? Would you still benefit from the next point (below), or is the "WITHOUT subfolders" enough? (Just asking.)

Next point:
SkyFrontier wrote:However, it would be possible and reasonably "simple" to make a script providing MiniTrees on a real "per folder" respectively "per path" basis (remembering what folders are expanded), which would be very similar to a "per tab" basis. That would probably be a whole new project, though.
>>Each path outside current one being added to the TAB-based MiniTree, right? Any chance of a whole session being stored, then? This would monstrously benefit my workflows. Seriously. Iconized tabs + customs icons. Think bout the future...!
I still am not sure if you understand the concept of my script correctly. Or I don't understand what you describe. Anyway, what I think you say should be possible but lets finish the other points first.
SkyFrontier wrote:"It need to be located in the xydata path." should look like
It need to be located in the xydata path.
Problem solved.
I still don't understand why it did not work before. Because, if the ini file does not exist in the XYdata path, then the script tries to create it there with the default values. This did not work in your case, but I dunno why.


Regarding the icon(s) for the script, I do like the source where you got the icon from. Thx. I think, I found me another one from there, though. Will be coming soon....
Regards, Stephan

Re: AHK-script for MiniTree - automatic expanding and collap

Posted: 06 Aug 2014 15:18
by SkyFrontier
Hi, Stephan!
>>Does the security check (which is implemented now) in the latest version solve your multi-instance issue or do you need a more complicated solution?
--no, it's still affecting other instances when I turn MT on for them.

>>...subfolders...
--it seems that playing with current settings can solve my problems. But if that's not asking too much, can it be that siblings have a separate control so a max amount is displayed (when possible), or not displayed at all? It would be much more focusing, specially keeping the per-tab behavior as your work nicely allows!
Ideal solution:

sib1
...
sib10
sib11
sib12
current
sib13
sib14
sib15
...
sib23

>>>setting:
neighbors=2 // 2 immediate siblings on each direction, up and down, will be showed; 0 = no siblings
or even something more refinated...
neighbors=2,10 // up,down
or even controlling the start position for each direction, ie, start from extremity or in the vicinity of CURRENT:
neighbors=2,E,10,V // displays the 2 first folders on current directory, current folder, plus the 10 neighbor folders below it
neighbors=5,V,8,E // displays the 5 neighbour folders on top of current, current, plus the 8 last folders
If you play with tons of dirs you'll guess the benefits of this...

sib11
sib12
current
sib13
sib14

>>I still don't understand why it did not work before. Because, if the ini file does not exist in the XYdata path, then the script tries to create it there with the default values. This did not work in your case, but I dunno why.
--Simple: because I ran the .exe under a totally off-XY site, AHK-dedicated folder! It was not that the INI wasn't at XYdata, the .exe wasn't there either... If that portability can be achieved, I'd prefer it.

Congrats!