Beispiel #1
0
/****f* pekwm-menu/clean_exec
 * FUNCTION
 *   Remove %f, %F, %u, %U, %i, %c, %k from exec field.
 *   None of theses codes are interesting to manage here.
 *   %i, %c and %k codes are implemented but don't ask why we need them. :)
 *
 * OUTPUT
 *   A gchar that needs to be freed.
 *
 * NOTES
 *   %d, %D, %n, %N, %v and %m are deprecated and should be removed.
 *
 * SEE ALSO
 *   http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
 ****/
gchar *
clean_exec (MenuCacheApp *app)
{
	gchar *filepath = NULL;
	const char *exec = menu_cache_app_get_exec (MENU_CACHE_APP(app));
	GString *cmd = g_string_sized_new (64);

	for (;*exec; ++exec)
	{
		if (*exec == '%')
		{
			++exec;
			switch (*exec)
			{
				/* useless and commonly used codes */
				case 'u':
				case 'U':
				case 'f':
				case 'F': break;
				/* deprecated codes */
				case 'd':
				case 'D':
				case 'm':
				case 'n':
				case 'N':
				case 'v': break;
				/* Other codes, more or less pointless to implement */
				case 'c':
					g_string_append (cmd, menu_cache_item_get_name (MENU_CACHE_ITEM(app)));
					break;
#if WITH_ICONS
				case 'i':
					if (get_item_icon_path (MENU_CACHE_ITEM(app)))
					{
						g_string_append_printf (cmd, "--icon %s",
						    get_item_icon_path (MENU_CACHE_ITEM(app)));
					}
					break;
#endif
				case 'k':
					filepath = menu_cache_item_get_file_path (MENU_CACHE_ITEM(app));
					if (filepath)
					{
						g_string_append (cmd, filepath);
						g_free (filepath);
					}
					break;
				/* It was not in the freedesktop specification. */
				default:
					g_string_append_c (cmd, '%');
					g_string_append_c (cmd, *exec);
					break;

			}
		}
		else
			g_string_append_c (cmd, *exec);
	}
	return g_strchomp (g_string_free (cmd, FALSE));
}
Beispiel #2
0
AppLinkItem::AppLinkItem(MenuCacheApp* app):
    CommandProviderItem()
{
    MenuCacheItem* item = MENU_CACHE_ITEM(app);
    mIconName = QString::fromUtf8(menu_cache_item_get_icon(item));
    mTitle = QString::fromUtf8(menu_cache_item_get_name(item));
    mComment = QString::fromUtf8(menu_cache_item_get_comment(item));
    mToolTip = mComment;
    mCommand = menu_cache_app_get_exec(app);
    mProgram = QFileInfo(mCommand).baseName().section(" ", 0, 0);
    char* path = menu_cache_item_get_file_path(MENU_CACHE_ITEM(app));
    mDesktopFile = QString::fromLocal8Bit(path);
    g_free(path);
    QMetaObject::invokeMethod(this, "updateIcon", Qt::QueuedConnection);
    // qDebug() << "FOUND: " << mIconName << ", " << mCommand;
}
Beispiel #3
0
/**
 * fm_app_chooser_dlg_dup_selected_app
 * @dlg: a widget
 * @set_default: location to get value that was used for fm_app_chooser_dlg_new()
 *
 * Retrieves a currently selected application from @dlg.
 *
 * Before 1.0.0 this call had name fm_app_chooser_dlg_get_selected_app.
 *
 * Returns: (transfer full): selected application.
 *
 * Since: 0.1.0
 */
GAppInfo* fm_app_chooser_dlg_dup_selected_app(GtkDialog* dlg, gboolean* set_default)
{
    GAppInfo* app = NULL;
    AppChooserData* data = (AppChooserData*)g_object_get_qdata(G_OBJECT(dlg), fm_qdata_id);
    switch( gtk_notebook_get_current_page(data->notebook) )
    {
    case 0: /* all applications */
        app = fm_app_menu_view_dup_selected_app(data->apps_view);
        break;
    case 1: /* custom cmd line */
        {
            const char* cmdline = gtk_entry_get_text(data->cmdline);
            const char* app_name = gtk_entry_get_text(data->app_name);
            if(cmdline && cmdline[0])
            {
                char* _cmdline = NULL;
                gboolean arg_found = FALSE;
                char* bin1 = get_binary(cmdline, &arg_found);
                g_debug("bin1 = %s", bin1);
                /* see if command line contains %f, %F, %u, or %U. */
                if(!arg_found)  /* append %f if no %f, %F, %u, or %U was found. */
                    cmdline = _cmdline = g_strconcat(cmdline, " %f", NULL);

                /* FIXME: is there any better way to do this? */
                /* We need to ensure that no duplicated items are added */
                if(data->mime_type)
                {
                    MenuCache* menu_cache;
                    /* see if the command is already in the list of known apps for this mime-type */
                    GList* apps = g_app_info_get_all_for_type(fm_mime_type_get_type(data->mime_type));
                    GList* l;
                    for(l=apps;l;l=l->next)
                    {
                        GAppInfo* app2 = G_APP_INFO(l->data);
                        const char* cmd = g_app_info_get_commandline(app2);
                        char* bin2 = get_binary(cmd, NULL);
                        if(g_strcmp0(bin1, bin2) == 0)
                        {
                            app = G_APP_INFO(g_object_ref(app2));
                            g_debug("found in app list");
                            g_free(bin2);
                            break;
                        }
                        g_free(bin2);
                    }
                    g_list_foreach(apps, (GFunc)g_object_unref, NULL);
                    g_list_free(apps);
                    if(app)
                        goto _out;

                    /* see if this command can be found in menu cache */
                    menu_cache = menu_cache_lookup("applications.menu");
                    if(menu_cache)
                    {
#if MENU_CACHE_CHECK_VERSION(0, 4, 0)
                        MenuCacheDir *root_dir = menu_cache_dup_root_dir(menu_cache);
                        if(root_dir)
#else
                        if(menu_cache_get_root_dir(menu_cache))
#endif
                        {
                            GSList* all_apps = menu_cache_list_all_apps(menu_cache);
                            GSList* l;
                            for(l=all_apps;l;l=l->next)
                            {
                                MenuCacheApp* ma = MENU_CACHE_APP(l->data);
                                const char *exec = menu_cache_app_get_exec(ma);
                                char* bin2;
                                if (exec == NULL)
                                {
                                    g_warning("application %s has no Exec statement", menu_cache_item_get_id(MENU_CACHE_ITEM(ma)));
                                    continue;
                                }
                                bin2 = get_binary(exec, NULL);
                                if(g_strcmp0(bin1, bin2) == 0)
                                {
                                    app = G_APP_INFO(g_desktop_app_info_new(menu_cache_item_get_id(MENU_CACHE_ITEM(ma))));
                                    g_debug("found in menu cache");
                                    menu_cache_item_unref(MENU_CACHE_ITEM(ma));
                                    g_free(bin2);
                                    break;
                                }
                                menu_cache_item_unref(MENU_CACHE_ITEM(ma));
                                g_free(bin2);
                            }
                            g_slist_free(all_apps);
#if MENU_CACHE_CHECK_VERSION(0, 4, 0)
                            menu_cache_item_unref(MENU_CACHE_ITEM(root_dir));
#endif
                        }
                        menu_cache_unref(menu_cache);
                    }
                    if(app)
                        goto _out;
                }

                /* FIXME: g_app_info_create_from_commandline force the use of %f or %u, so this is not we need */
                app = app_info_create_from_commandline(cmdline,
                            app_name ? app_name : "", bin1,
                            data->mime_type ? fm_mime_type_get_type(data->mime_type) : NULL,
                            gtk_toggle_button_get_active(data->use_terminal),
                            data->keep_open && gtk_toggle_button_get_active(data->keep_open));
            _out:
                g_free(bin1);
                g_free(_cmdline);
            }
        }
        break;
    }

    if(set_default)
        *set_default = gtk_toggle_button_get_active(data->set_default);
    return app;
}
Beispiel #4
0
static MenuCacheApp* match_app_by_exec(const char* exec)
{
    GSList* l;
    MenuCacheApp* ret = NULL;
    char* exec_path = g_find_program_in_path(exec);
    const char* pexec;
    int path_len, exec_len, len;

    if( ! exec_path )
        return NULL;

    path_len = strlen(exec_path);
    exec_len = strlen(exec);

    for( l = app_list; l; l = l->next )
    {
        MenuCacheApp* app = MENU_CACHE_APP(l->data);
        const char* app_exec = menu_cache_app_get_exec(app);
        if ( ! app_exec)
            continue;
#if 0   /* This is useless and incorrect. */
        /* Dirty hacks to skip sudo programs. This can be a little bit buggy */
        if( g_str_has_prefix(app_exec, "gksu") )
        {
            app_exec += 4;
            if( app_exec[0] == '\0' ) /* "gksu" itself */
                app_exec -= 4;
            else if( app_exec[0] == ' ' ) /* "gksu something..." */
                ++app_exec;
            else if( g_str_has_prefix(app_exec, "do ") ) /* "gksudo something" */
                app_exec += 3;
        }
        else if( g_str_has_prefix(app_exec, "kdesu ") ) /* kdesu */
            app_exec += 6;
#endif

        if( g_path_is_absolute(app_exec) )
        {
            pexec = exec_path;
            len = path_len;
        }
        else
        {
            pexec = exec;
            len = exec_len;
        }

        if( strncmp(app_exec, pexec, len) == 0 )
        {
            /* exact match has the highest priority */
            if( app_exec[len] == '\0' )
            {
                ret = app;
                break;
            }
            /* those matches the pattern: exe_name %F|%f|%U|%u have higher priority */
            if( app_exec[len] == ' ' )
            {
                if( app_exec[len + 1] == '%' )
                {
                    if( strchr( "FfUu", app_exec[len + 2] ) )
                    {
                        ret = app;
                        break;
                    }
                }
                ret = app;
            }
        }
    }

    /* if this is a symlink */
    if( ! ret && g_file_test(exec_path, G_FILE_TEST_IS_SYMLINK) )
    {
        char target[512]; /* FIXME: is this enough? */
        len = readlink( exec_path, target, sizeof(target) - 1);
        if( len > 0 )
        {
            target[len] = '\0';
            ret = match_app_by_exec(target);
            if( ! ret )
            {
                /* FIXME: Actually, target could be relative paths.
                 *        So, actually path resolution is needed here. */
                char* basename = g_path_get_basename(target);
                char* locate = g_find_program_in_path(basename);
                if( locate && strcmp(locate, target) == 0 )
                {
                    ret = match_app_by_exec(basename);
                    g_free(locate);
                }
                g_free(basename);
            }
        }
    }

    g_free(exec_path);
    return ret;
}