Creating a File Tree with Gtk+

I thought that today, rather than going for an in-depth tutorial, I would post a useful snippet of code for anyone out there doing GUI development with GTK+. Although Gtk+ is a nice toolkit, one thing that I found that it was lacking was a nice widget to automatically display directories. I had hoped that since it had such a nice file open dialog, there might be something out there, but alas I was unable to find anything. So, I present here a useful function to automatically populate a GtkTreeView with a directory structure.


void fill_tree(char* dirname, char* shortname, GtkTreeStore* store, GtkTreeIter* parent_iter, int level)
{
        DIR* dir = NULL;

        //defined in dirent.h
        struct dirent* entry;

        //allocate a string with 255 characters per directory name, plus 1 character for the / between directories.
        char* path = (char*)malloc( ((255*(level+1))+level+1) * sizeof(char) );

        //this will become the parent node for subsequent calls
        //and gets placed under the parent node that was sent to us
        GtkTreeIter my_iter;
        strcpy(path,dirname);
        strcat(path,"/");

        if(NULL != (dir = opendir(dirname)))//make sure we can open the directory
        {
                //create a node on the tree for the directory
                gtk_tree_store_append(store,&my_iter,parent_iter);

                //add the current directory to the list
                gtk_tree_store_set(store,&my_iter,COL_NAME,shortname,-1);

                //start to read the subdirectories
                while( (entry = readdir(dir)) != NULL)
                {
                        //skip hidden files, . and ..
                        if( (entry->d_name)[0]==‘.’)
                        {
                                continue;
                        }

                        //create the full path to the subdirecotry
                        strcat(path,entry->d_name);

                        //recursively call fill with this subdirectory
                        fill_tree(path,entry->d_name,store,&my_iter,level+1);

                        //reset the path to the path of this directory
                        strcpy(path,dirname);
                        strcat(path,"/");
                }
        }

        //close the file handle and free memory
        closedir(dir);
        free(path);
        path=NULL;
}


Using the function is pretty simple. Just copy and paste into your application, with the path for the top of the directory structure you want to display, and a name for it. Pass in a pointer to a GtkTreeStore you’ve allocated, and NULL and 0 for the parent_iter and level (unless you want to display the tree under some heading). Here is an example:

fill_tree("/home/tuxtips","Home Directory",my_tree_store,NULL,0);

If you are loading a large directory structure (for example, /) you might consider spawning this off into it’s own thread, as it can take a bit of time. For something a bit more dynamic, consider removing the recursive functionality, and calling the function in response to a user clicking on an entry. Also note that, for simplicity, I’ve used 255 as the maximum directory entry size, but this is a variable set in dirent.h and varies from system to system, so be sure to look that up!

Until Next Time, Happy Hacking.

Leave a Comment

You must be logged in to post a comment.