Page 1 of 1
[Solved] Get TreeGadget final text?
Posted: Sat Jun 17, 2023 1:54 pm
by BarryG
See the following image and code... say I click on "File4421" - how can I know that its full path is "Folder 4\Sub-folder 42\Sub-folder 421\File 4421" ?
Assume that I haven't created an array like in the example, and that the items were added manually by someone, one at a time. Thanks!
Code: Select all
Dim f$(14)
f$(1)="Folder 1\File 11"
f$(2)="Folder 1\File 12"
f$(3)="Folder 1\File 13"
f$(4)="Folder 2\File 21"
f$(5)="Folder 2\File 22"
f$(6)="Folder 2\File 23"
f$(7)="Folder 3\File 31"
f$(8)="Folder 3\Sub-folder 3\File 331"
f$(9)="Folder 3\Sub-folder 3\File 332"
f$(10)="Folder 3\Sub-folder 3\File 333"
f$(11)="Folder 4\File 41"
f$(12)="Folder 4\Sub-folder 41\File 441"
f$(13)="Folder 4\Sub-folder 42\Sub-folder 421\File 4421"
f$(14)="Folder 4\File 42"
Procedure FillTreeGadget(Gadget, Array Files.s(1)) ; https://www.purebasic.fr/english/viewtopic.php?p=602949#p602949
Protected fn.s, currdir.s, idx, count, level, cnt
Dim lastdir.s(0)
count = ArraySize(Files())
For idx = 1 To count
fn = Files(idx)
cnt = CountString(fn, #PS$)
For level = 0 To cnt - 1
currdir = StringField(fn, level+1, #PS$)
If lastdir(level) <> currdir
AddGadgetItem(0, -1, currdir, 0, level)
lastdir(level) = currdir
ReDim lastdir(level+1)
EndIf
Next
fn = StringField(fn, level+1, #PS$)
AddGadgetItem(0, -1, fn, 0, level)
Next
Dim lastdir(0)
EndProcedure
If OpenWindow(0, 0, 0, 355, 400, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TreeGadget(0, 10, 10, 340, 380) ; TreeGadget standard
FillTreeGadget(0, f$())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Re: Get TreeGadget final text
Posted: Sat Jun 17, 2023 2:35 pm
by Axolotl
hi BarryG,
please try this procedure ....
Code: Select all
Procedure.s GetEntirePath(Gadget, Position)
Protected result.s, item, level, lastlevel
If Position > -1
result = GetGadgetItemText(Gadget, Position) ; the selected item
lastlevel = GetGadgetItemAttribute(Gadget, Position, #PB_Tree_SubLevel)
For item = Position To 0 Step -1 ; count backwards from selected item
level = GetGadgetItemAttribute(Gadget, item, #PB_Tree_SubLevel)
If level < lastlevel
lastlevel = level
result = GetGadgetItemText(Gadget, item) + #PS$ + result
EndIf
Next
EndIf
ProcedureReturn result
EndProcedure
okay, I changed the main loop to this
Code: Select all
If OpenWindow(0, 0, 0, 355, 400, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TreeGadget(0, 10, 10, 340, 380) ; TreeGadget standard
FillTreeGadget(0, f$())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break ; say good bye
Case #PB_Event_Gadget
Select EventGadget()
Case 0
Debug "" + GetEntirePath(0, GetGadgetState(0))
EndSelect
EndSelect
ForEver
EndIf
Re: Get TreeGadget final text
Posted: Sun Jun 18, 2023 1:35 am
by BarryG
Thanks, Axolotl! It was nice to wake up to your solution. Seems like this sort of thing should have a command in PureBasic.
The final working example:
Code: Select all
Dim f$(14)
f$(1)="Folder 1\File 11"
f$(2)="Folder 1\File 12"
f$(3)="Folder 1\File 13"
f$(4)="Folder 2\File 21"
f$(5)="Folder 2\File 22"
f$(6)="Folder 2\File 23"
f$(7)="Folder 3\File 31"
f$(8)="Folder 3\Sub-folder 3\File 331"
f$(9)="Folder 3\Sub-folder 3\File 332"
f$(10)="Folder 3\Sub-folder 3\File 333"
f$(11)="Folder 4\File 41"
f$(12)="Folder 4\Sub-folder 41\File 441"
f$(13)="Folder 4\Sub-folder 42\Sub-folder 421\File 4421"
f$(14)="Folder 4\File 42"
Procedure FillTreeGadget(Gadget, Array Files.s(1))
Protected fn.s, currdir.s, idx, count, level, cnt
Dim lastdir.s(0)
count = ArraySize(Files())
For idx = 1 To count
fn = Files(idx)
cnt = CountString(fn, #PS$)
For level = 0 To cnt - 1
currdir = StringField(fn, level+1, #PS$)
If lastdir(level) <> currdir
AddGadgetItem(0, -1, currdir, 0, level)
lastdir(level) = currdir
ReDim lastdir(level+1)
EndIf
Next
fn = StringField(fn, level+1, #PS$)
AddGadgetItem(0, -1, fn, 0, level)
Next
Dim lastdir(0)
EndProcedure
Procedure.s GetEntirePath(Gadget, Position)
Protected result.s, item, level, lastlevel
If Position > -1
result = GetGadgetItemText(Gadget, Position) ; the selected item
lastlevel = GetGadgetItemAttribute(Gadget, Position, #PB_Tree_SubLevel)
For item = Position To 0 Step -1 ; count backwards from selected item
level = GetGadgetItemAttribute(Gadget, item, #PB_Tree_SubLevel)
If level < lastlevel
lastlevel = level
result = GetGadgetItemText(Gadget, item) + #PS$ + result
EndIf
Next
EndIf
ProcedureReturn result
EndProcedure
If OpenWindow(0, 0, 0, 355, 400, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TreeGadget(0, 10, 10, 340, 380)
FillTreeGadget(0, f$())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case 0
Debug "" + GetEntirePath(0, GetGadgetState(0))
EndSelect
EndSelect
ForEver
EndIf
Re: [Solved] Get TreeGadget final text?
Posted: Sun Jun 18, 2023 3:37 am
by idle
you can simplify that a bit
Code: Select all
Dim f$(14)
f$(1)="Folder 1\File 11"
f$(2)="Folder 1\File 12"
f$(3)="Folder 1\File 13"
f$(4)="Folder 2\File 21"
f$(5)="Folder 2\File 22"
f$(6)="Folder 2\File 23"
f$(7)="Folder 3\File 31"
f$(8)="Folder 3\Sub-folder 3\File 331"
f$(9)="Folder 3\Sub-folder 3\File 332"
f$(10)="Folder 3\Sub-folder 3\File 333"
f$(11)="Folder 4\File 41"
f$(12)="Folder 4\Sub-folder 41\File 441"
f$(13)="Folder 4\Sub-folder 42\Sub-folder 421\File 4421"
f$(14)="Folder 4\File 42"
Procedure FillTreeGadget(Gadget, Array Files.s(1))
Protected fn.s, currdir.s, idx,idx1, count, level, cnt
Dim lastdir.s(0)
count = ArraySize(Files())
For idx = 1 To count
fn = Files(idx)
cnt = CountString(fn, #PS$)
For level = 0 To cnt - 1
currdir = StringField(fn, level+1, #PS$)
If lastdir(level) <> currdir
AddGadgetItem(0, idx1, currdir, 0, level)
idx1+1
lastdir(level) = currdir
ReDim lastdir(level+1)
EndIf
Next
fn = StringField(fn, level+1, #PS$)
AddGadgetItem(0, idx1, fn, 0, level)
SetGadgetItemData(gadget,idx1,idx)
idx1+1
Next
Dim lastdir(0)
EndProcedure
If OpenWindow(0, 0, 0, 355, 400, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TreeGadget(0, 10, 10, 340, 380)
FillTreeGadget(0, f$())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case 0
If EventType() = #PB_EventType_LeftClick
out.s = f$(GetGadgetItemData(EventGadget(),GetGadgetState(0)))
If out <> ""
Debug out
EndIf
EndIf
EndSelect
EndSelect
ForEver
EndIf
Re: [Solved] Get TreeGadget final text?
Posted: Sun Jun 18, 2023 5:45 am
by AZJIO
Windows only
Code: Select all
EnableExplicit
Dim f$(14)
f$(1)="Folder 1\File 11"
f$(2)="Folder 1\File 12"
f$(3)="Folder 1\File 13"
f$(4)="Folder 2\File 21"
f$(5)="Folder 2\File 22"
f$(6)="Folder 2\File 23"
f$(7)="Folder 3\File 31"
f$(8)="Folder 3\Sub-folder 3\File 331"
f$(9)="Folder 3\Sub-folder 3\File 332"
f$(10)="Folder 3\Sub-folder 3\File 333"
f$(11)="Folder 4\File 41"
f$(12)="Folder 4\Sub-folder 41\File 441"
f$(13)="Folder 4\Sub-folder 42\Sub-folder 421\File 4421"
f$(14)="Folder 4\File 42"
Global TVI.TVITEMEX, Text$, hItem, Gadget, Buffer$
Buffer$ = Space(4096)
With TVI
\mask = #TVIF_TEXT
\cchTextMax = 4096
\pszText = @Buffer$
EndWith
Procedure FillTreeGadget(Gadget, Array Files.s(1))
Protected fn.s, currdir.s, idx,idx1, count, level, cnt
Dim lastdir.s(0)
count = ArraySize(Files())
For idx = 1 To count
fn = Files(idx)
cnt = CountString(fn, #PS$)
For level = 0 To cnt - 1
currdir = StringField(fn, level+1, #PS$)
If lastdir(level) <> currdir
hItem = AddGadgetItem(0, idx1, currdir, 0, level)
idx1+1
lastdir(level) = currdir
ReDim lastdir(level+1)
EndIf
Next
fn = StringField(fn, level+1, #PS$)
AddGadgetItem(0, idx1, fn, 0, level)
idx1+1
Next
Dim lastdir(0)
EndProcedure
If OpenWindow(0, 0, 0, 355, 400, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TreeGadget(0, 10, 10, 340, 380)
FillTreeGadget(0, f$())
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case 0
If EventType() = #PB_EventType_LeftDoubleClick
If GetGadgetState(Gadget) <> -1
Text$ = ""
Text$ + GetGadgetItemText(Gadget, GetGadgetState(Gadget))
hItem = SendMessage_(GadgetID(Gadget), #TVM_GETNEXTITEM, #TVGN_CARET, 0)
Repeat
hItem = SendMessage_(GadgetID(Gadget), #TVM_GETNEXTITEM, #TVGN_PARENT, hItem)
If Not hItem
Break
EndIf
; Debug hItem
With TVI
\hItem = hItem
EndWith
SendMessage_(GadgetID(Gadget), #TVM_GETITEMW, 0, TVI)
; Debug "-" + Buffer$
Text$ = Buffer$ + "\" + Text$
ForEver
Debug Text$
EndIf
EndIf
EndSelect
EndSelect
ForEver
EndIf
Re: [Solved] Get TreeGadget final text?
Posted: Sun Jun 18, 2023 1:46 pm
by Axolotl
Okay, if you need a different separator I recommend this improvement.
Code: Select all
Procedure.s GetEntirePath(Gadget, Position, Sep.s=#PS$)
Protected result.s, item, level, lastlevel
If Position > -1
result = GetGadgetItemText(Gadget, Position) ; the selected item
lastlevel = GetGadgetItemAttribute(Gadget, Position, #PB_Tree_SubLevel)
For item = Position To 0 Step -1 ; count backwards from selected item
level = GetGadgetItemAttribute(Gadget, item, #PB_Tree_SubLevel)
If level < lastlevel
lastlevel = level
result = GetGadgetItemText(Gadget, item) + Sep + result
EndIf
Next
EndIf
ProcedureReturn result
EndProcedure
And yes, some built-in functions for TreeGadget() would be really great.