How can I display text during file copying?

Just starting out? Need help? Post your questions and find answers here.
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

How can I display text during file copying?

Post by davido »

I have a program that copies some files from one directory to another.
During the copying, I wish to display information about the file just copied.

I've posted some sample code, not the same as in my program, but is simpler and has exactly the same problem.
I find that the window blanks and no text is displayed until all the files have been copied!

I tried moving the copy process into another thread but then all the text is displayed before copying is started!

Can anybody say what I am doing wrong?

Code: Select all

;// Copyfiles.pb ?
EnableExplicit

  CompilerIf #PB_Compiler_Unicode
    #XmlEncoding = #PB_UTF8
  CompilerElse 
    #XmlEncoding = #PB_Ascii
  CompilerEndIf

  #Dialog = 0
  #Xml = 0
  Global XML1$, XML2$, Event.i
  
  Global SourcePath$, TargetPath$, NewList FileList$()

  
  
  Runtime Enumeration Windows
    #WinMain
    #win2
  EndEnumeration
  Runtime Enumeration Gadgets
    #copySourceButton
    #copySourcePath
    #copyTargetButton
    #copyTargetPath
    #copyList
    #copyGo
  EndEnumeration
  Runtime Enumeration Gadgets
    
  EndEnumeration
  
  Declare ProcessFiles()
  
  Procedure ProcessFiles()
    
 If ExamineDirectory(0, SourcePath$, "*.*")  
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_File
        AddElement(FileList$())
        FileList$() = DirectoryEntryName(0)
      EndIf
    Wend
    FinishDirectory(0)
  EndIf
  ClearGadgetItems(#copyList)
  ForEach FileList$()
    AddGadgetItem(#copyList,-1,FileList$())
  Next
  ForEach FileList$()
    CopyFile(SourcePath$ + FileList$(),TargetPath$ + FileList$())
    SetGadgetItemText(#copyList,ListIndex(FileList$()),"Copied!",1)
  Next
  EndProcedure
  
  Runtime Procedure EventButtons()
    Select EventGadget()
      Case #copySourceButton
        SourcePath$ = PathRequester("Source Directory","")
        SetGadgetText(#copySourcePath,SourcePath$)
        
      Case #copyTargetButton
        TargetPath$ = PathRequester("Target Directory","")
        SetGadgetText(#copyTargetPath,TargetPath$)
        
      Case #copyGo
        ProcessFiles()
        
    EndSelect
  EndProcedure
  
  Runtime Procedure SetUP()
    SetGadgetItemText(#copyList,-1,"Files to Copy")
    AddGadgetColumn(#copyList,1,"Result",60)
  EndProcedure
  
  XML1$ = "<dialogs>"+
          "  <window id='#WinMain' name='Template' text='Print' minwidth='auto' minheight='auto' flags='#PB_Window_ScreenCentered |"+
          "  #PB_Window_SystemMenu | #PB_Window_SizeGadget'>" +
          "   <vbox>"+
          "     <hbox>"+
          "       <button id='#copySourceButton' height='60' text='Source' onevent='EventButtons()' />"+
          "       <text id='#copySourcePath' width='350' />"+
          "     </hbox>"+
          "     <hbox>"+
          "       <button id='#copyTargetButton' height='60' text='Target' onevent='EventButtons()' />"+
          "       <text id='#copyTargetPath' width='350' />"+
          "     </hbox>"+
          "    <listicon id='#copyList' width='450' height='200' flags='#PB_ListIcon_GridLines' />"+
          "    <button id='#copyGo' text='Go' onevent='EventButtons()' />"+
          "   </vbox>"+
         "  </window>"+
         "</dialogs>"
  
  If CatchXML(#Xml, @XML1$, StringByteLength(XML1$), 0, #XmlEncoding) And XMLStatus(#Xml) = #PB_XML_Success
    
    If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "Template")
      SetUp()
      Repeat
        Event = WaitWindowEvent()
      Until Event = #PB_Event_CloseWindow 
      
    Else  
      Debug "Dialog error: " + DialogError(#Dialog)
    EndIf
  Else
    Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
  EndIf
DE AA EB
infratec
Always Here
Always Here
Posts: 7793
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: How can I display text during file copying?

Post by infratec »

Try this:

Code: Select all

;// Copyfiles.pb ?
EnableExplicit

CompilerIf #PB_Compiler_Unicode
  #XmlEncoding = #PB_UTF8
CompilerElse
  #XmlEncoding = #PB_Ascii
CompilerEndIf

#Dialog = 0
#Xml = 0
Global XML1$, XML2$, Event.i


Structure ThreadParameterStructure
  Thread.i
  Semaphore.i
  Exit.i
EndStructure


Global SourcePath$, TargetPath$, NewList FileList$(), ThreadParameter.ThreadParameterStructure




Runtime Enumeration Windows
  #WinMain
  #win2
EndEnumeration
Runtime Enumeration Gadgets
  #copySourceButton
  #copySourcePath
  #copyTargetButton
  #copyTargetPath
  #copyList
  #copyGo
EndEnumeration
Runtime Enumeration Gadgets
  
EndEnumeration


Enumeration #PB_EventType_FirstCustomValue
  #Event_ShowFileToCopy
  #Event_ShowFileCopied
EndEnumeration



Procedure ProcessFiles(*Parameter.ThreadParameterStructure)
  
  Protected Help$
  
  ClearGadgetItems(#copyList)
  
  If ExamineDirectory(0, SourcePath$, "*.*") 
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_File
        AddElement(FileList$())
        Help$ = DirectoryEntryName(0)
        FileList$() = Help$
        PostEvent(#Event_ShowFileToCopy, #WinMain, 0, 0, @Help$)
        WaitSemaphore(*Parameter\Semaphore)
      EndIf
    Wend
    FinishDirectory(0)
  EndIf
  
  ForEach FileList$()
    CopyFile(SourcePath$ + FileList$(),TargetPath$ + FileList$())
    PostEvent(#Event_ShowFileCopied, #WinMain, 0, 0, ListIndex(FileList$()))
    ;SetGadgetItemText(#copyList,ListIndex(FileList$()),"Copied!",1)
    WaitSemaphore(*Parameter\Semaphore)
    If *Parameter\Exit
      Break
    EndIf
  Next
EndProcedure


Runtime Procedure EventButtons()
  Select EventGadget()
    Case #copySourceButton
      SourcePath$ = PathRequester("Source Directory","")
      SetGadgetText(#copySourcePath,SourcePath$)
      
    Case #copyTargetButton
      TargetPath$ = PathRequester("Target Directory","")
      SetGadgetText(#copyTargetPath,TargetPath$)
      
    Case #copyGo
      ThreadParameter\Exit = #False
      ThreadParameter\Thread = CreateThread(@ProcessFiles(), @ThreadParameter)
      
  EndSelect
EndProcedure

Runtime Procedure SetUP()
  SetGadgetItemText(#copyList,-1,"Files to Copy")
  AddGadgetColumn(#copyList,1,"Result",60)
EndProcedure




ThreadParameter\Semaphore = CreateSemaphore()

XML1$ = "<dialogs>"+
        "  <window id='#WinMain' name='Template' text='Print' minwidth='auto' minheight='auto' flags='#PB_Window_ScreenCentered |"+
        "  #PB_Window_SystemMenu | #PB_Window_SizeGadget'>" +
        "   <vbox>"+
        "     <hbox>"+
        "       <button id='#copySourceButton' height='60' text='Source' onevent='EventButtons()' />"+
        "       <text id='#copySourcePath' width='350' />"+
        "     </hbox>"+
        "     <hbox>"+
        "       <button id='#copyTargetButton' height='60' text='Target' onevent='EventButtons()' />"+
        "       <text id='#copyTargetPath' width='350' />"+
        "     </hbox>"+
        "    <listicon id='#copyList' width='450' height='200' flags='#PB_ListIcon_GridLines' />"+
        "    <button id='#copyGo' text='Go' onevent='EventButtons()' />"+
        "   </vbox>"+
        "  </window>"+
        "</dialogs>"

If CatchXML(#Xml, @XML1$, StringByteLength(XML1$), 0, #XmlEncoding) And XMLStatus(#Xml) = #PB_XML_Success
  
  If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "Template")
    SetUp()
    Repeat
      Event = WaitWindowEvent()
      
      Select Event
        Case #Event_ShowFileToCopy
          AddGadgetItem(#copyList, -1, PeekS(EventData()))
          SignalSemaphore(ThreadParameter\Semaphore)
          
        Case #Event_ShowFileCopied
          SetGadgetItemText(#copyList, EventData(), "Copied!", 1)
          SignalSemaphore(ThreadParameter\Semaphore)
          
      EndSelect
      
    Until Event = #PB_Event_CloseWindow
    
  Else 
    Debug "Dialog error: " + DialogError(#Dialog)
  EndIf
Else
  Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
EndIf
Bernd
Last edited by infratec on Wed May 02, 2018 7:47 am, edited 1 time in total.
Marc56us
Addict
Addict
Posts: 1600
Joined: Sat Feb 08, 2014 3:26 pm

Re: How can I display text during file copying?

Post by Marc56us »

PB auto-refresh gadgets only when WindowEvent() occurs.

A tips was to add a single loop such as

Code: Select all

While WindowEvent() : Wend
in

Code: Select all

    ForEach FileList$()
        CopyFile(SourcePath$ + FileList$(),TargetPath$ + FileList$())
        SetGadgetItemText(#copyList,ListIndex(FileList$()),"Copied!",1)
        While WindowEvent() : Wend ; <--- This auto-refresh gadgets
    Next
But this does not work with Bindxxx event (and XMD dialog use it)

:|

The solution proposed by Infratec (see post above) works fine :wink:
infratec
Always Here
Always Here
Posts: 7793
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: How can I display text during file copying?

Post by infratec »

@Marc56us

A very bad tip.
Never, really never, use a second event loop.
You will lost events. (Like closing the window)
Marc56us
Addict
Addict
Posts: 1600
Joined: Sat Feb 08, 2014 3:26 pm

Re: How can I display text during file copying?

Post by Marc56us »

Yeah, maybe, but I'm not sure.
I've used it for years and never had a problem before.
(and it was, it seems to me, someone important who had indicated this tip)
This loop will leave at the first iteration, so for example a timer event (1/1000s) or a mouse movement.
So much faster than what a user or hard drive can do.

But I'm willing to believe. Do you have an example that would demonstrate the possible crash for this type of unique loop?

Code: Select all

While WindowEvent() : Wend
:?:
Last edited by Marc56us on Wed May 02, 2018 8:00 am, edited 1 time in total.
infratec
Always Here
Always Here
Posts: 7793
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: How can I display text during file copying?

Post by infratec »

Doesn't matter if it works for you since years...

If an event occurs in this time it is lost. (you can not debate about this :wink: )
Depending on the event it is more or less critical.

If your code is more complex, where different threads generates events, than you will come definately to a point where you notice that something is not working as expected.
And then it is very difficult to find out why, because everything looks fine with your code.
No one thinks that an event is lost.
infratec
Always Here
Always Here
Posts: 7793
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: How can I display text during file copying?

Post by infratec »

Or in Yodas words
There is only one of them.
No more, no less.
And you are allways on the save side.
:mrgreen:
Marc56us
Addict
Addict
Posts: 1600
Joined: Sat Feb 08, 2014 3:26 pm

Re: How can I display text during file copying?

Post by Marc56us »

Yes, I agree with you. I use this tip only for small simple programs and to go faster.
So far, almost none of my programs exceed 15000 lines and very few use threads, so I haven't had a problem yet.

:?: :idea: But it's true that I have one that has weird reactions sometimes, so I'll double-check if I hadn't put this Tip on.

Thanks
:wink:
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: How can I display text during file copying?

Post by Dude »

Maybe my code here is of interest to you:

http://www.purebasic.fr/english/viewtop ... 76#p491376

Works great for large files. :)
User avatar
Lord
Addict
Addict
Posts: 913
Joined: Tue May 26, 2009 2:11 pm

Re: How can I display text during file copying?

Post by Lord »

Hi infratec!
infratec wrote:Doesn't matter if it works for you since years...
...
Does it matter if even Fred suggests it?
http://www.purebasic.fr/english/viewtop ... 01&start=3
Image
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: How can I display text during file copying?

Post by walbus »

I use a similar function inside QUICK_AES_256.
It works very fine, you can try.
Move as sample a lot files or folders in the text editor.

Without WindowEvent() you won't get any output.
The behavior is also not exactly the same between the three OS.
Within your copy loop, the second WindowEvent() does not disturb.
The problem with multiple WindowEvent() is that one takes something away from the other.
However, processing must always take place sequentially, first one, then the other.
The easier it is structured, the better it works.
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: How can I display text during file copying?

Post by davido »

Thanks to you all for taking the trouble to help me. :D

@infratec: Usually when I am shown how to do something I think how simple it looks!
But, not in this case as I had tried copying in a thread and failed miserably. I don't think I could have done this by myself.
I really like your solution because you've made it so simple for me to add to my code. It also works on my Mac, too.

@Dude: I like this one, too, as it displays a graphic 'thermometer' similar to the display on my Mac.
It would be nice if there was a way to add the function on the Mac.

@walbus: Thanks for the tip: I'll take a look.
DE AA EB
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: How can I display text during file copying?

Post by walbus »

Hi Davido
yep, primary it is simple, but for a perfect working it is not simple

For batch file copy i make this so :

I read firstly only the paths in a list
This works very fast, also with your routine, but you can not add with your routine WindowEvent
Or you must change your code for making the complete output with one step !

Then i display the paths and files, this also is very fast,
and you can use for this step WindowEvent
But you must not, its simple a eye catcher for many different outputs

I display a progressbar,
all files and states in a editor gadget and display at the same time the file amount and a counter on a text gadget
(I have count the files bevore with the first step) :wink:

The third step is the bare file copy on a separately loop
I copy the files blockwise, do it at the same !
Make this block copy not threaded
So i have little blocks, can add simple a progressbar and WinEvent, how ever i want
This is the Way, so you get a very smooth output, without any flickering and it look absolutely cool

Unfortunatelly i can not separate this code for you from QAES
The code is combined with complicated hash creating and encryption routines

But i can say you, so it works perfectly, on all OS :wink:
infratec
Always Here
Always Here
Posts: 7793
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: How can I display text during file copying?

Post by infratec »

Lord wrote:Hi infratec!
infratec wrote:Doesn't matter if it works for you since years...
...
Does it matter if even Fred suggests it?
http://www.purebasic.fr/english/viewtop ... 01&start=3
Hi, hi,

this was a decade ago.
Ask him today about this.
User avatar
Lord
Addict
Addict
Posts: 913
Joined: Tue May 26, 2009 2:11 pm

Re: How can I display text during file copying?

Post by Lord »

infratec wrote:
Lord wrote:Hi infratec!
infratec wrote:Doesn't matter if it works for you since years...
...
Does it matter if even Fred suggests it?
http://www.purebasic.fr/english/viewtop ... 01&start=3
Hi, hi,

this was a decade ago.
Ask him today about this.
Hi Fred! What is your suggestion at this topic today (or tomorrow)?
Image
Post Reply