How to add files to a list in vala?

131 Views Asked by At

I want to add files to a list and then access them in a for loop. This is how I try to do it:

private get_app_list () {
        var file = new File.new_for_path (/usr/share/applications);
        List<File> app_list = new List<File> ();
        
        foreach (File desktop_file in app_list) {
            // other code here
        }
    }

What is the right way to access files stored in a directory and then add them to a list??

2

There are 2 best solutions below

0
On
using Posix;
...
List<File> app_list = new List<File> ();
//Open directory. Returns null on error
var dirHandle = Posix.opendir("/usr/share/applications");
unowned DirEnt entry;
//While there is an entry to read in the directory
while((entry = readdir(dir)) != null) {
    //Get the name
    var name = (string) entry.d_name;
    //And add a new file to the app_list
    app_list.add(new File.new_for_path("/usr/share/applications"+name);
}
0
On

If you want to merely display the available apps on system, you could use the utilities supplied by the Gio-2.0 lib. After adding dependency ('gio-2.0'), to your meson.build file you could use code similar to the following:

/* We use a `GListStore` here, which is a simple array-like list implementation
* for manual management.
* List models need to know what type of data they provide, so we need to
* provide the type here. As we want to do a list of applications, `GAppInfo`
* is the object we provide.
*/
var app_list = new GLib.ListStore (typeof (GLib.AppInfo));
var apps = GLib.AppInfo.get_all ();
foreach (var app in apps) {
    app_list.append (app);
}

If however you need to list files inside a directory, it's possible also to use the higher level API provided by the same gio-2.0 library. Here is a sample code to enumerate files inside "/usr/share/applications/"

void main () {
    var app_dir = GLib.File.new_for_path ("/usr/share/applications");
    try {
        var cancellable = new Cancellable ();

        GLib.FileEnumerator enumerator = app_dir.enumerate_children (
            GLib.FileAttribute.STANDARD_DISPLAY_NAME,
            GLib.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
            cancellable
        );

        FileInfo ? file_info = null;
        while (!cancellable.is_cancelled () && 
               ((file_info = enumerator.next_file (cancellable)) != null)) {
            // Ignore directories
            if (file_info.get_file_type () == GLib.FileType.DIRECTORY) {
                continue;
            }
            // files could be added to a list_store here.
            /*
             * var files_list = new GLib.ListStore (typeof (GLib.FileInfo));
             * files_list.append (file_info);
             */
            print (file_info.get_display_name () + "\n");
        }
    } catch (GLib.Error err) {
        info ("%s\n", err.message);
    }
}

I hope this could be of any help.