I am a listbox that displays the drives connected to Mac computer. I have the code so that it will check any folder and all subfolders below the main Drive level. However, I want the same action to occur when I select the main drive. I just can’t figure this out. Here is the code for the folder selections:
Var f As FolderItem = me.RowTag(row)
Var FoldersToSelect() As FolderItem
If f.Directory = True Then
FoldersToSelect.Append(f)
End If
While FoldersToSelect.Ubound > -1
Var j As Integer
' Find the row that has a reference to this folder in it's rowtag
For j = row To me.ListCount - 1
If me.RowTag(j) = FoldersToSelect(0) Then
Exit For
End If
Next
me.Expanded(j) = True
me.CellState(j, column) = me.CellState(row, column)
' Walk forward selecting rows
For k As Integer = j + 1 To me.ListCount
If FolderItem(me.RowTag(k)).Parent.NativePath <> FolderItem(me.RowTag(j)).NativePath Then
Exit For
End If
me.CellState(k, column) = me.CellState(row, column)
If FolderItem(me.RowTag(k)).IsEjectableVolumeMBS Then
Exit For
End if
me.CellState(k, column) = me.CellState(row, column)
' This is a subfolder so add it to the list to process
If me.RowIsFolder(k) Then
FoldersToSelect.Append(me.RowTag(k))
me.Expanded(k) = False
End If
Next
FoldersToSelect.Remove(0)
Wend
How do you know your code is not working when you select main drive?
Is there an error, if so, what does it say?
If there is no error, have you tried stepping through the code you’re displaying with the debugger?
Also, I notice you make a reference to a FolderItem “Parent” in your code. If it’s a main drive (or Volume) you’ve selected, maybe there is no “Parent”?
Sorry, obviously I’m no expert, but I’m having trouble following your code snippet.
Hi Scott. I know the code isn’t working because when I select the checkbox next to the top-level drive, the program crashes. However, when I select the checkbox next to just a folder, the program performs as expected.
The code is in the “Cell Action” event of the Listbox. What I am trying to achieve is when you select the checkbox next to the drive, it selects everything below the drive.
So, how would I go about selecting the mounted drive and having everything below get selected as well?
Put a breakpoint on the first line of code for your “Cell Action” event, run your project and select a drive. This will put your project into debug mode and allow you step line-by-line through your code until it fails or crashes.
At the line where it fails or crashes, that’s where you need to focus on changing your code logic.
Hey Scott. I put a break-point in the code but there is so much to drill into I don’t know where to begin. If I upload the project here, can you take a look at show me how to fix it?
There were a couple of problems when selecting from the top-level folder (in this case Macintosh HD, a.k.a., /).
1.) - Your code includes referencing the .Parent of a folders that are actually Virtual Volumes that reside inside subfolders of /. So I added a *.Parent <> Nil check (see line 42) to avoid a NilObjectException. I guess because once a Virtual Volume is mounted, it has no parent.
2.) - For some reason, when selecting / it throws off your iterating variables j & k, which causes an OutOfBoundsException. See the If statement checks I added on lines 20 & 32.
Yes - the root of any drive has no parent and this comes back as Nil, unfortunately.
On a Mac, the boot drive is at / but all other mounted drives are at /Volumes/SomeDrive. However, you can’t go higher than SomeDrive, which will have Nil as its parent.
My app has a similar feature except that the open/closed state of a folder is stored in an SQLite db. I show files too, but only those which were deemed at startup to be of interest.
The point though is that all I do at the top level (equivalent to your code in the button Pressed event), is to set .Expanded to True. This causes a cascade of RowExpanded events which do all the real work.
I suspect the reason the debugger was not highlighting the first NilObjectException for you, was because maybe you don’t have “Break On Exceptions” enabled?
Because the first time I ran your project and checked a top-level folder, the debugger took me directly to the problem line where the .Parent folder is referenced.
Question for you both. Can I place the code from a Listbox “CellAction” event into the run event of a thread and then run the thread in the “CellAction” event so I can update a Progress Bar and keep the UI active?
It is doable. Xojo has at least two examples for updating a ListBox from a Thread.
Cooperative Example: Language / Worker / WordCounter
Choice of Cooperative or Preemptive: Language / Threads / Threaded Word Counter
The above examples are also reading files from disk, so I’m sure you could find enough logic in those examples to get you where you need to go. Have fun.
I have upgraded to Xojo 2024 R3. I am updating the above app and in the AddItem method, the line that reads “TreeView.AddFolder item.DisplayName” isn’t working anymore and I can’t figure out how to get it to do so with the newer version. Any thoughts?
I have not been exposed to or trained in the debugging aspect of things. I have included a screenshot of what I have entered and the error it is throwing, if that helps.