Load saved file into ListIconGadget

Just starting out? Need help? Post your questions and find answers here.
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

Load saved file into ListIconGadget

Post by Distorted Pixel »

I want to load the saved file into a ListIconGadget, but it is putting both saved lines seperate into their own item as it should, but everything of each line is going into column "0" and not into seperate columns. I may have the StringField() command used wrong, but not sure.
My save routine works great and the saved information below is how it saves it
How can I get it loaded correctly? I have tried manipulating the items and columns, but failed.

Edit: it is actually a procedure, I just didn't post the Procedure/EndProcedure

Each piece of data should be in their own column.
https://mega.nz/file/FpkTUBiS#fRYdVWlva ... 2qDI5LDL08

Column 0 variable = Med$ | Column 1 variable = DoseStrength$ | Column 2 variable = NumDoses$ | Column 3 variable = IntendedUse$ | Column 4 variable = MedUses$

Information in saved "test.txt" file

Code: Select all

Asprin,81mg,1,Heart attack,Prevent heart attack
Penicillin,250mg,3,Ear infection,Cure infections
Load routine

Code: Select all

  
  Define File$, Med$, DoseStrength$, NumDoses$, IntendedUse$, MedUses$, Result$, Input$
  Define.i i

Input$ = OpenFileRequester("Please choose file to load","Untitled.txt", "Text (*.txt)|*.txt;*.bat|*.txt;*.dat|All files (*.*)|*.*", 0)
  
  If ReadFile(0, Input$)
    While Eof(0) = 0
      Result$ = ReadString(0)
      For i = 1 To Len(Result$)
        StringField(Result$, i, ",")
      Next i
       
      AddGadgetItem(#Icongadget, -1, Result$)
           
    Wend
    CloseFile(0)               ; close the previously opened file
  Else
    MessageRequester("Information","Couldn't open the file!")
  EndIf
Last edited by Distorted Pixel on Mon Jun 12, 2023 12:34 am, edited 3 times in total.
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

Re: Load saved file into ListIcon Gadget

Post by Distorted Pixel »

@Moderators, Please move this into "Coding Questions" I accidently forgot I was currently in Bugs-Windows thread

Sorry
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1243
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Re: Load saved file into ListIcon Gadget

Post by Paul »

If you look ate the Help file for AddGadgetItem() , it requires multiple columns to be separated by chr(10)

If all your data it separated by comma in your txt file, why not do this instead of StringField() ?

Code: Select all

  If ReadFile(0, Input$)
    While Eof(0) = 0
      Result$ = ReadString(0)
 
      AddGadgetItem(#IconGadget, -1, ReplaceString(Result$,",",Chr(10)))
           
    Wend
    CloseFile(0)               ; close the previously opened file
  Else
    MessageRequester("Information","Couldn't open the file!")
  EndIf
  
Image Image
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

Re: Load saved file into ListIcon Gadget

Post by Distorted Pixel »

Paul wrote: Mon May 29, 2023 2:52 am If you look ate the Help file for AddGadgetItem() , it requires multiple columns to be separated by chr(10)

If all your data it separated by comma in your txt file, why not do this instead of StringField() ?

Code: Select all

  If ReadFile(0, Input$)
    While Eof(0) = 0
      Result$ = ReadString(0)
 
      AddGadgetItem(#IconGadget, -1, ReplaceString(Result$,",",Chr(10)))
           
    Wend
    CloseFile(0)               ; close the previously opened file
  Else
    MessageRequester("Information","Couldn't open the file!")
  EndIf
  
Sorry for the late reply Paul, yes I do know about needing the Chr(10). I did try that, but I had it in for once per column and took it out because it didn't work lol.

Thank you for the snippet, it works perfectly
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
jassing
Addict
Addict
Posts: 1745
Joined: Wed Feb 17, 2010 12:00 am

Re: Load saved file into ListIconGadget

Post by jassing »

FWIW -- I import a CSV file, replaceString() is unconcerned about the format of the line.
ie:
"this","should, be", "three fields"
but if you do RepalceString() on ",", you'll end up with 4 fields, 2 of which won't have matching quotes anymore; so if you might have quotes around text, you'll need to use a different method.

I experimented:
repalcestring() w/o "in place" is slowest.
replaceString() using in place is a bit faster
using a PB procedure to access the string with pointers is faster still.
Using C is faster still, about 3x faster than the 1st replacestring()

If your importing a few hundred records it probably doesn't matter much; but if you're importing a lot, every bit helps to speed up the process...

Even if you're NOT concerned with quotes; both my PB/pointer function and C code are faster than replacestring()
If you want them either of them, let me know; mostly just wanted to bring up the bit about commas w/in quotes vs replacestring()
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 233
Joined: Sun Aug 29, 2021 4:34 am

Re: Load saved file into ListIconGadget

Post by Distorted Pixel »

jassing wrote: Fri Jun 09, 2023 7:41 pm Even if you're NOT concerned with quotes; both my PB/pointer function and C code are faster than replacestring()
If you want them either of them, let me know; mostly just wanted to bring up the bit about commas w/in quotes vs replacestring()
I don't have but about 5 minutes of studying C or C++ of experience with C and C++ so it probably wouldn't do me any good unless it was easy to implement some how.

I thank you very much for your input on this and your offer of your code though. I appreciate it. I don't think most people that will be using this to keep track of their medication have more than 15-20. It is for personal use and not for pharmacy/doctor use. Currently my wife only has 7-8 medications
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
ZX80
Enthusiast
Enthusiast
Posts: 330
Joined: Mon Dec 12, 2016 1:37 pm

Re: Load saved file into ListIconGadget

Post by ZX80 »

Hi, everybody.

I read what Jassing wrote above and decided to try and make it as fast as possible.

Well...
The following listing is based on Wilbert's code. I know it could have been made simpler, but again, I wanted to make it as fast as possible. The essence of the cycle / iteration of a substring by bytes (strings from 30 to 36) is somewhat similar to the native function CountString(), only it is intended for a memory area. Maybe Fred will add this in the next version ? :oops:
The main reason for this memory routine is to avoid the concatenation process. Do everything in memory, and then only once read the entire resulting piece of memory as a whole and assign it to a string variable. This complex question has been discussed many times on this forum and I looked at a lot of code before writing this. Working with memory only in the name of achieving the best code speed.

Okay...
At first glance the code works. But I have doubts that everything is done correctly. Especially regarding null characters in strings. ShowMemoryViewer() always displays the contents of memory in a stable manner. But the debugger window sometimes randomly stays blank. Why ? I made a mistake somewhere, but I can't find it on my own. Perhaps I miscalculated the number of bytes for the string.

I would like to ask more experienced members of our forum to look at the final code if you have time. And... point me to the error. Or I'd love to hear your point of view. Can this be further simplified ? I am using PB version without C-backend support. Also, I don't want to add assembler inserts to the code. Use only native functions.

Thank you in advance.

Code: Select all

Macro pIncrement
  *pointer + ByteLength
  *p + ByteLength
EndMacro

Procedure.s SplitDquotesString(String.s, Separator.s = " ", replace.s = "") ; replace.s = only one char !
  Protected S.String, *S.Integer = @S
  Protected.i p, slen, counter, rByte
  Protected.i ByteLength, memsize
  Protected.i *mem, *pointer, *p, *pEnd
  Protected.b Byte
  Protected result$
  
  slen  = Len(Separator)
  rByte = Asc(replace) ; byte to replace
  
  ByteLength = SizeOf(Character)
  memsize    = StringByteLength(String)
  *mem       = AllocateMemory(memsize, #PB_Memory_NoClear)
  *pointer   = *mem
  *p         = *mem
  *pEnd      = *mem + memsize
  
  *S\i = @String
  Repeat
    
    p = FindString(S\s, Separator)
    CopyMemoryString(PeekS(*S\i, p - 1), @*pointer)
   
    While *p < *pointer
      Byte = PeekB(*p)
      If Byte = 34  ; 34 = #DQUOTE$
        counter = counter + 1
      EndIf
      *p + ByteLength
    Wend
    If 1 &~ counter
      If rByte
        If (*pEnd - *pointer) > 0
          PokeB(*pointer, rByte)
          pIncrement
        EndIf
      EndIf
    Else
      PokeS(*pointer, Separator, -1, #PB_String_NoZero)
      pIncrement
    EndIf
    
    *S\i + (p + slen - 1) << #PB_Compiler_Unicode
    
  Until p = 0
  *S\i = 0
  
  ShowMemoryViewer(*mem, memsize)
  result$ = PeekS(*mem, memsize)
  FreeMemory(*mem)
  *mem = 0
  
  ProcedureReturn result$
EndProcedure


S.s = "this," + #DQUOTE$ + "this" + #DQUOTE$ + "," + #DQUOTE$ + "should, be" + #DQUOTE$ + ", " + #DQUOTE$ + "three fields" + #DQUOTE$ ; + "," + #DQUOTE$ + "XZZ ZXZ, CCZ" + #DQUOTE$
Debug S
Debug "---------------------------------------"
Debug ""
Debug SplitDquotesString(S, ",", Chr(10))
;Debug ""
;Debug SplitDquotesString(S, ",")
jassing
Addict
Addict
Posts: 1745
Joined: Wed Feb 17, 2010 12:00 am

Re: Load saved file into ListIconGadget

Post by jassing »

Do you really need to remove characters?
Are you dealing with unicode or ascii strings? (or both?)

Could be much simpler...

FWIW, here's the routine I'm using to convert a line from a csv into ilsticon...

Code: Select all

Procedure FixStrForListIcon( *input.Unicode ) 
  Protected inQuote, *output.Unicode = *input
  While *input\u 
    If *input\u = '"' 
      inQuote = Bool(Not inQuote) 
    ElseIf Not inQuote And *input\u = ','
      *output\u  = #CR 
      *output + SizeOf(Character)
    Else
      *output\u = *input\u
      *output + SizeOf(Character)
    EndIf
    *input + SizeOf(Character) 
  Wend
  *output\u = 0;
EndProcedure   

#string = ~"\"this is, column 1\",\"this is, column 2\",42,\"this is, column 4\""
Define string.s

string = #string 
Debug string
FixStrForListIcon( @string )
Debug "FixStrForListIcon()"+#CRLF$+string
ZX80
Enthusiast
Enthusiast
Posts: 330
Joined: Mon Dec 12, 2016 1:37 pm

Re: Load saved file into ListIconGadget

Post by ZX80 »

Good time, Jassing.

I don't know. Is it true. Ok let's have both (unicode and ascii) ;)

I just saw your post above and got interested. At the moment I don't need it.
The problem is that "my" code sometimes seems to hang. I just asked to see what could be wrong with it. I don't see the error, maybe someone with a fresher eye will see it.

In any case, thanks for sharing your version of the code to resolve this issue.
It's good that everyone sees it differently. Then we have a choice.


P.S. If I understand correctly, Distorted Pixel wants to be able to add, delete, and modify entries in the notebook, and not just from the program. Thus, I concluded that the simplicity of these actions is important for him. That is, the file with the list must be human-readable, and only a standard notepad is enough for this. That is, in plain text and without additional characters or tabs that complicate the process of reading a file by a person.
This is also the reason why I chose this option.

I don't know, maybe I'm wrong. Probably worth waiting for the Distorted Pixel itself.
Last edited by ZX80 on Mon Jun 12, 2023 8:10 pm, edited 1 time in total.
jassing
Addict
Addict
Posts: 1745
Joined: Wed Feb 17, 2010 12:00 am

Re: Load saved file into ListIconGadget

Post by jassing »

can you post some test data to test replicate the hang with? Also, what version of PB are you using?
Using .i *pointer means you're at best v5.
Regardless of what I use, I get a memory overflow error using your code... not an occasional hang.

this supports both unicode /ascii.

Code: Select all

Procedure FixStrForListIcon( *s, strLength, chrLength=SizeOf(Character) )
  Protected i, inQuote
  While i < strLength
    If PeekB( *s+i ) = '"'
      inQuote = Bool( Not inQuote )
    ElseIf PeekB( *s+i ) = ',' And Not inQuote
      PokeB( *s+i, #CR )
    EndIf
    i+chrLength
  Wend
EndProcedure

#string = ~"\"this is, column 1\",\"this is, column 2\",42,\"this is, column 4\""
Define string.s

string = #string 
Debug string

ReplaceString(string,",",#CR$,#PB_String_InPlace|#PB_String_CaseSensitive)
Debug "replacestring()"+#CRLF$+string

string = #string
FixStrForListIcon(@string, StringByteLength(string) )
Debug "FixStringForListIcon/unicode"+#CRLF$+string

*string = Ascii(#string)
FixStrForListIcon(*string, MemorySize(*string), 1 )
Debug "FixStringForListIcon/ascii"+#CRLF$+PeekS(*string,-1,#PB_Ascii)
ZX80
Enthusiast
Enthusiast
Posts: 330
Joined: Mon Dec 12, 2016 1:37 pm

Re: Load saved file into ListIconGadget

Post by ZX80 »

Exactly! Now I'm working under version 5.73 (x86). My OS is also 32 bit.
I read here on the forum a long time ago that pointers must necessarily be of type Integer. So I don't think it's a bug.
jassing wrote: Mon Jun 12, 2023 8:06 pm can you post some test data to test replicate the hang with?
Sorry, but I don't have any other data than what is already in the code. I followed your example (took an example string from your post).

I don't get any error messages, but the debugger window doesn't show any results, and the PB IDE window is white. It's like if I myself stopped the code before it finished (aka set breakpoint).
Sometimes...

Thank You !
jassing
Addict
Addict
Posts: 1745
Joined: Wed Feb 17, 2010 12:00 am

Re: Load saved file into ListIconGadget

Post by jassing »

Using your code, and PB 5.73 x86, here's what I get:
Image

if I'm correct, what I suspect you mean, from @*pointer to *pointer; I still get a memory error.
I guess it's just an incompatibility between systems, since we get such different results.
ZX80
Enthusiast
Enthusiast
Posts: 330
Joined: Mon Dec 12, 2016 1:37 pm

Re: Load saved file into ListIconGadget

Post by ZX80 »

Jassing, I'm very sorry, but what about this :?:
Help text error?
I guess it's just an incompatibility between systems, since we get such different results.
Sorry, I really don't know why we get different results from the same code.

Your last version actually looks much more concise than mine. Yes, it does the same!
Thanks again!
jassing
Addict
Addict
Posts: 1745
Joined: Wed Feb 17, 2010 12:00 am

Re: Load saved file into ListIconGadget

Post by jassing »

OK - leaving it 'as is'
Image
that's with PB x86 v5.73
ZX80
Enthusiast
Enthusiast
Posts: 330
Joined: Mon Dec 12, 2016 1:37 pm

Re: Load saved file into ListIconGadget

Post by ZX80 »

I'm really sorry. Before that, I ran the code without Purifier in the menu Compiler -> Compiler Options... -> Compile/Run tab.
I selected it and now... I am getting exactly the same error as you. It is on this line and with the same text (Line: 28).
I'm very sorry. :oops:
Post Reply