views:

922

answers:

6

Using C++ on the Linux desktop, what is the best way to get the icon, the document description and the application "associated" with an arbitrary file/file path?

I'd like to use the most "canonical" way to find icons, mime-type/file type descriptions and associated applications on both KDE and gnome and I'd like to avoid any "shelling out" to the command line and "low-level" routines as well as avoiding re-inventing the wheel myself (no parsing the mime-types file and such).

Edits and Notes:

Hey, I originally asked this question about the QT file info object and the answer that "there is no clear answer" seems to be correct as far as it goes. BUT this is such a screwed-up situation that I am opening the question looking for more information.

I don't care about QT in particular any more, I'm just looking for the most cannonical way to find the mime type via C++/c function calls on both KDE and gnome (especially Gnome, since that's where things confuse me most). I want to be able show icons and descriptions matching Nautilus in Gnome and Konquerer/whatever on KDE as well as opening files appropriately, etc.

I suppose it's OK that I get this separately for KDE and Gnome. The big question is what's the most common/best/cannonical way to get all this information for the Linux desktop? Gnome documentation is especially opaque. gnome-vsf has mime routines but it's deprecated and I can't find a mime routine for GIO/GFS, gnome-vsf's replacement. There's a vague implication that one should use the open desktop applications but which one to use is obscure. And where does libmagic and xdg fit in?

Pointers to an essay summarizing the issues gladly accepted. Again, I know the three line answer is "no such animal" but I'm looking for the long answer.

+1  A: 

Neither QFileIconProvider nor QFileInfo will do anything with the OS mime database. To access icons associated with different mime types, you will have to use functions of the underlying desktop environment. In Qt there is (yet) no canonical way.

Consider you can have a different icon in Gnome, in KDE and in Windows. So for instance, in KDE you would use KMimeType.

drhirsch
s/window manager/desktop environment/
ephemient
Thanks, any idea about gnome?
Joe Soul-bringer
See my edit notes about changing the direction of the question...
Joe Soul-bringer
+1  A: 

You may want to use the system's "/etc/mime.types" file. It is also a good idea to maintain your program's copy of a MIME type file. That way, you are not dependent on the system, but at the same time you need to keep it fairly exhaustive. Not sure about Icons.

Amit
+1  A: 

I just found KFileItem. This class gives you everything you for icons, mime types and related things in KDE. I'm sure that there's an equivalent in gnome but this gives access at the same level as a QT application works.

Joe Soul-bringer
A: 

Maybe take a look at this code: http://ftp.devil-linux.org/pub/devel/sources/1.2/file-4.23.tar.gz

This is the standard file util found on most Linux/Unix distributions. You will get the MIME-type and some more information.

I think both Gnome and KDE have their own ways to determine this and also to set the icon and the standard application for it.

Anyway, that file-tool is probably the best way to get the mime type and the document description. And in some cases even some details about the content.

This will get you the mime-type. That is what you need anyway to know how you can open the file. These are seperated steps. file doesn't say you about the icon nor the application to open the file with.

Albert
Can supply a bit more explanation? I've been looking through a lot of code already.
Joe Soul-bringer
Plus the archive was invalid when I downloaded it
Joe Soul-bringer
What exactly do you want to know? Don't you know the 'file' command? Just open a terminal, and type "file $somefile". This tool is very good in detecting automatically the type of the file. And it is pretty standard.I updated the link, seems it had become invalid.
Albert
I think my question goes into detail concerning what I want
Joe Soul-bringer
file is probably the best way to get mime type and the document description. Ofc that is only one step. See my edit.
Albert
+1  A: 

You can use the tools available from xdg for that, in particular xdg-mime query.

To find out the filetype of e.g. a file index.html you would

# xdg-mime query filetype index.html

This will return the mimetype. To query what application is associated with that mimetye use e.g.

# xdg-mime query default text/html

This returns epiphany.desktop here, i.e. $APPNAME.desktop, so it is easy to get the application name from it. If you would just want to open the file in the default app you could of course just run

# xdg-open index.html

which would fire up epiphany.

Query functions for icon resources do not seem to be available in xdg-utils, but you could write a small python script using pyxdg that offers tons of additional functionality, too.

For C bindings you will probably need to have a look into the portland code linked on the xdg page.

EDIT:

Concerning libmagic and friends, you will need to decide on your preferences: While libmagic seems to be more complete (and accurate) in terms of coverage for filetypes, it does not care at all about default applications or icons. It also does not provide you with tools to install extra mimetypes.

honk
1. How could call xdg from c++ 2. Could you expand on xdg/libmagic differences?
Joe Soul-bringer
1. The xdg-utils are just shell scripts, so you have to use sth. like popen(). If you can use python write sth. dedicated using pyxdg (or reimplement dedicated parts in C++).2. AFAIK xdg-utils are just frontends to deal with either KDE or GNOME extension->mimetype databases and only if these fail fall-back on libmagic/file to identify the mimetype. Libmagic is a db that contains even binary file headers, so it can be much more accurate.The big plus of using xdg is that you can deligate responsibility for some functionality out of your code instead of rewriting everything from scratch.
honk
+4  A: 

Here is an example of using GLib/GIO to get the information you want.

#include <gio/gio.h>
#include <stdio.h>

int
main (int argc, char **argv)
{
    g_thread_init (NULL);
    g_type_init ();

    if (argc < 2)
        return -1;

    GError *error;
    GFile *file = g_file_new_for_path (argv[1]);
    GFileInfo *file_info = g_file_query_info (file,
                                              "standard::*",
                                              0,
                                              NULL,
                                              &error);

    const char *content_type = g_file_info_get_content_type (file_info);
    char *desc = g_content_type_get_description (content_type);
    GAppInfo *app_info = g_app_info_get_default_for_type (
                                  content_type,
                                  FALSE);

    /* you'd have to use g_loadable_icon_load to get the actual icon */
    GIcon *icon = g_file_info_get_icon (file_info);

    printf ("File: %s\nDescription: %s\nDefault Application: %s\n",
            argv[1],
            desc,
            g_app_info_get_executable (app_info));

    return 0;
}
Travis Watkins
Seem or less like what I'm looking for. Any links documenting these functions?
Joe Soul-bringer
http://library.gnome.org/devel/gio/stable/ is the main page for GIO docs, which section a function is in should be obvious based on the name.
Travis Watkins
Looks good: GIO aims to "provide an API that is so good that developers prefer it over raw POSIX calls" - if developers can ever find this page! No links from old gnomeVFS pages and doesn't use key word "Mime" or "file associations and didn't come up in a fairly long Google search - well, now I know! Thanks
Joe Soul-bringer
Wouldn't that only return the default application of Nautilus/Gnome to open this type of file?
Albert
No, nautilus uses standard cross-desktop methods of determining the default application for a file. Even if you override the default in nautilus KDE apps should respect that as well (haven't tested it though).
Travis Watkins