Show progress


#1

I am writing a little program that is going to read through a directory structure. I want to show the progress, now because I am using the DirectoryIterator I have the getEstimatedProgress.
The question I have is what would be the best way to display the progress on my application window? and be able to update that progress?

The application dialog was created with jucer.

Thanks


#2

i think you better use the ThreadWithProgressWindow class that will do most of the work for you. there is an example in the docs if i’m not mistaking something…


#3

In the main component when a button is clicked I do some stuff and then call a function which resides in the maincomponent.cpp which does the bulk of my work. Now I would like to add a progress bar and I have tried to use the ThreadWithProgressWindow class, but I can not get it to work.

Based on the doc I would need to create my own class to use it. This is not a problem but in this fuction I use does recursions. I tried to move the function content into a class to use the ThreadWithProgressWindow but then I can not do/use my recursion.

Any help would be greatly appreciated.

below is the function:

[code]void SearchNode(XmlElement *pCurrentRoot, String sFolder, File sLogfile)
{
File l_Directory(sFolder);
OwnedArray l_Objects;

  l_Directory.findChildFiles(l_Objects, true, false, "*"); //searching for directories
  l_Directory.findChildFiles(l_Objects, false, false, "*");//searching for files
  //now we have both directories and files in the single l_Objects array.

  XmlElement *l_pNode = 0;
  XmlElement *l_pNodeName = 0;
  XmlElement *l_pNodeComment = 0;
  int l_iCount = l_Objects.size();
  for(int Idx = 0; Idx < l_iCount; Idx++)
   {
      String l_sPath(l_Objects[Idx]->getFullPathName());
      if(l_Objects[Idx]->isDirectory())
      {
         l_pNode = new XmlElement("Folder");
		 l_pNodeName = new XmlElement("Name");
		 l_pNodeComment = new XmlElement("Comment");
		 l_pNodeName->addTextElement(l_sPath);
		 l_pNodeComment->addTextElement("Enter Comments");
		 l_pNode->addChildElement(l_pNodeName);
		 l_pNode->addChildElement(l_pNodeComment);

         SearchNode(l_pNode, l_sPath, sLogfile);//!!!!!!!THIS IS THE RECURSION!!!!!!!

         pCurrentRoot->addChildElement(l_pNode);
      }
      else
      {
         l_pNode = new XmlElement("File");
		 l_pNodeName = new XmlElement("Name");
		 l_pNodeComment = new XmlElement("Comment");
		 l_pNodeName->addTextElement(l_sPath);
		 l_pNodeComment->addTextElement("Enter Comments");
		 l_pNode->addChildElement(l_pNodeName);
		 l_pNode->addChildElement(l_pNodeComment);
         pCurrentRoot->addChildElement(l_pNode);
      }
   }

}[/code]

Here is my attempt at putting it into a class:

[code]class MyTask : public ThreadWithProgressWindow
{
public:
XmlElement *pCurrentRoot;
String sFolder;
File sLogfile;
MyTask() : ThreadWithProgressWindow (T(“busy…”), true, true)
{
}
MyTask(XmlElement *pCurrentRoot, String sFolder, File sLogfile) : ThreadWithProgressWindow (T(“busy…”), true, true)
{
}
~MyTask()
{
}

void run()
{
  File l_Directory(sFolder);
  OwnedArray<File> l_Objects;

  l_Directory.findChildFiles(l_Objects, true, false, "*"); //searching for directories
  l_Directory.findChildFiles(l_Objects, false, false, "*");//searching for files
  //now we have both directories and files in the single l_Objects array.
    
  XmlElement *l_pNode = 0;
  XmlElement *l_pNodeName = 0;
  XmlElement *l_pNodeComment = 0;
  int l_iCount = l_Objects.size();

    
  for(int Idx = 0; Idx < l_iCount; Idx++)
   {
        if (threadShouldExit())
            break;

        // this will update the progress bar on the dialog box
        setProgress (Idx / (double) l_iCount);

      String l_sPath(l_Objects[Idx]->getFullPathName());
      if(l_Objects[Idx]->isDirectory())
      {
         l_pNode = new XmlElement("Folder");
		 l_pNodeName = new XmlElement("Name");
		 l_pNodeComment = new XmlElement("Comment");
		 l_pNodeName->addTextElement(l_sPath);
		 l_pNodeComment->addTextElement("Enter Comments");
		 l_pNode->addChildElement(l_pNodeName);
		 l_pNode->addChildElement(l_pNodeComment);

         MyTask m(l_pNode, l_sPath, sLogfile);//!!!!!!!THIS IS THE RECURSION!!!!!!!
		 m.runThread();

         pCurrentRoot->addChildElement(l_pNode);
      }
      else
      {
         l_pNode = new XmlElement("File");
		 l_pNodeName = new XmlElement("Name");
		 l_pNodeComment = new XmlElement("Comment");
		 l_pNodeName->addTextElement(l_sPath);
		 l_pNodeComment->addTextElement("Enter Comments");
		 l_pNode->addChildElement(l_pNodeName);
		 l_pNode->addChildElement(l_pNodeComment);
         pCurrentRoot->addChildElement(l_pNode);
      }

        //   ... do the business here...
    }
}

};
[/code]

I had this in a seperate .h file.


#4

oh, weirdoh thingu going on there.
first, you should understand more what is recursion and how to apply it in your case: recursion doesn’t mean to spawn a new thread every call !
instead you should move your directory iterate over another member function, and from run thread just call that function, avoiding spawning thread every directory tree change.

instead i’ll do something like this:

    void run ()
    {
        jobDone = false;
        jobCancelled = false;

        // delete if the file already exists
        if (outputFile.existsAsFile())
            outputFile.deleteFile ();

        // start iterating with directory
        DirectoryIterator iter (inputFile, recursive);

        // open output stream
        FileOutputStream out (outputFile);
        if (out.areAnyErrors())
            return;

        int counter = 0;

        while (iter.next())
        {
            // the user choose to dismiss the operation
            if (threadShouldExit())
            {
                jobCancelled = true;
                break;
            }

            File file (iter.getFile());
            if (file.existsAsFile())
            {
                ++counter;

                // here i'll do something with my "file"...

                setProgress (iter.getEstimatedProgress());
            }
        }

        out.flush ();

        // job cancelled so probably clean up the file
        if (jobCancelled && outputFile.existsAsFile())
            outputFile.deleteFile();

        jobDone = true;
    }

the only problem is that in my case i only have one DirectoryIterator, so i would have the one correct getEstimatedProgress()… but since you are calling your function recursively, you will finish having hundreds DirectoryIterators, each with it’s own getEstimatedProgress, producing a bouncing progress bar…


#5