G_MODULE_EXPORT void
on_ssh_trust_toggled (GtkToggleButton *button, SeahorseWidget *swidget)
{
    SeahorseSource *sksrc;
    SeahorseOperation *op;
    SeahorseObject *object;
    SeahorseSSHKey *skey;
    gboolean authorize;
    GError *err = NULL;

    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
    skey = SEAHORSE_SSH_KEY (object);
    sksrc = seahorse_object_get_source (object);
    g_return_if_fail (SEAHORSE_IS_SSH_SOURCE (sksrc));
    
    authorize = gtk_toggle_button_get_active (button);
    gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
    
    op = seahorse_ssh_operation_authorize (SEAHORSE_SSH_SOURCE (sksrc), skey, authorize);
    g_return_if_fail (op);
    
    /* A very fast op, so just wait */
    seahorse_operation_wait (op);
    
    if (!seahorse_operation_is_successful (op)) {
        seahorse_operation_copy_error (op, &err);
        seahorse_util_handle_error (err, _("Couldn't change authorization for key."));
        g_clear_error (&err);
    }
    
    gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
}
static void
passphrase_done (SeahorseOperation *op, SeahorseWidget *swidget)
{
    GError *err = NULL;
    GtkWidget *w;

    if (!seahorse_operation_is_successful (op)) {
        seahorse_operation_copy_error (op, &err);
        seahorse_util_handle_error (err, _("Couldn't change passphrase for key."));
        g_clear_error (&err);
    }
    
    w = GTK_WIDGET (seahorse_widget_get_widget (swidget, "passphrase-button"));
    g_return_if_fail (w != NULL);
    gtk_widget_set_sensitive (w, TRUE);
}
/**
* operation: The finished operation
* swidget: The SeahorseWidget to get the progress bar from
*
* Handles the progress bar display of finished operations.
* If there is an error in the operation, it will be displayed.
*
**/
static void
operation_done (SeahorseOperation *operation, SeahorseWidget *swidget)
{
    GError *err = NULL;

    if (!seahorse_operation_is_successful (operation)) {
        seahorse_operation_copy_error (operation, &err);
        if (err) {
            operation_progress (operation, err->message, 0.0, swidget);
            g_error_free (err);
        }
    } else {
	    operation_progress (operation, "", 0.0, swidget);
    }
    
    g_signal_handlers_disconnect_by_func (swidget, disconnect_progress, operation);
    g_object_set_data (G_OBJECT (swidget), "operation", NULL);
}
/**
* pop: a seahorse operation
* gstarterr: the gpgme error that could have occured earlier
* cryptdata: gpgme cryptdata
* result: the result of the gpgme operation (out)
* resultlength: length of the created buffer (out) (can be NULL)
* error: will be set on error
*
* Finishes the gpgme processing and returns the result
*
* returns: TRUE on successful operation, FALSE else
*/
static gboolean
process_crypto_result (SeahorseGpgmeOperation *pop, gpgme_error_t gstarterr, 
                       gpgme_data_t cryptdata, gchar **result, gsize *resultlength, GError **error)
{
    size_t len;
    char *data;
    
    /* Starting the operation failed? */
    if (!GPG_IS_OK (gstarterr)) {
        gpgme_data_release (cryptdata);
        
        g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_CRYPTO,
                     "%s", gpgme_strerror (gstarterr));
        return FALSE;
    }
    
    /* Wait for it to finish (can run main loop stuff) */
    seahorse_operation_wait (SEAHORSE_OPERATION (pop));
    
    if (seahorse_operation_is_cancelled (SEAHORSE_OPERATION (pop))) {
	    
	    g_set_error (error, SEAHORSE_DBUS_CANCELLED, 0, "%s", "");
	    return FALSE;
    
    } else if (seahorse_operation_is_successful (SEAHORSE_OPERATION (pop))) {
        
        data = gpgme_data_release_and_get_mem (cryptdata, &len);
        *result = g_strndup (data, len);
        if (resultlength != NULL)
            *resultlength = (gsize)len;
        g_free (data);
        return TRUE;
        
    } else {
        
        /* A failed operation always has an error */
        g_assert (seahorse_operation_get_error (SEAHORSE_OPERATION (pop)));
        g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_CRYPTO, 
                     "%s", seahorse_operation_get_error (SEAHORSE_OPERATION (pop))->message);
        
        gpgme_data_release (cryptdata);
        return FALSE;
    }
}
G_MODULE_EXPORT void
on_ssh_comment_activate (GtkWidget *entry, SeahorseWidget *swidget)
{
    SeahorseObject *object;
    SeahorseSSHKey *skey;
    SeahorseSource *sksrc;
    SeahorseOperation *op;
    const gchar *text;
    gchar *comment;
    GError *err = NULL;
    
    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
    skey = SEAHORSE_SSH_KEY (object);
    sksrc = seahorse_object_get_source (object);
    g_return_if_fail (SEAHORSE_IS_SSH_SOURCE (sksrc));
    
    text = gtk_entry_get_text (GTK_ENTRY (entry));
    
    /* Make sure not the same */
    if (skey->keydata->comment && g_utf8_collate (text, skey->keydata->comment) == 0)
        return;

    gtk_widget_set_sensitive (entry, FALSE);
    
    comment = g_strdup (text);
    op = seahorse_ssh_operation_rename (SEAHORSE_SSH_SOURCE (sksrc), skey, comment);
    g_free (comment);
    
    /* This is usually a quick operation */
    seahorse_operation_wait (op);
    
    if (!seahorse_operation_is_successful (op)) {
        seahorse_operation_copy_error (op, &err);
        seahorse_util_handle_error (err, _("Couldn't rename key."));
        g_clear_error (&err);
        gtk_entry_set_text (GTK_ENTRY (entry), skey->keydata->comment ? skey->keydata->comment : "");
    }
    
    gtk_widget_set_sensitive (entry, TRUE);
}
static gboolean
step_operation (FilesCtx *ctx,
                SeahorseToolMode *mode,
                GError **err)
{
    SeahorsePGPOperation *pop = NULL;
    gpgme_data_t data = NULL;
    gboolean ret = FALSE;

    SeahorseOperation *op;
    FileInfo *finfo;
    GList *l;
    gchar *filename;

    /* Reset our done counter */
    ctx->done = 0;

    for (l = ctx->finfos; l; l = g_list_next (l)) {

        finfo = (FileInfo*)l->data;
        if (!finfo || !finfo->file)
            continue;

        ctx->cur = finfo;

        /* A new operation for each context */
        pop = seahorse_pgp_operation_new (NULL);
        op = SEAHORSE_OPERATION (pop);

        data = seahorse_vfs_data_create_full (finfo->file, SEAHORSE_VFS_READ,
                                              (SeahorseVfsProgressCb)progress_cb,
                                              ctx, err);
        if (!data)
            goto finally;

        /* Inhibit popping up of progress dialog */
        seahorse_tool_progress_block (TRUE);

        /* Embed filename during encryption */
        if (mode_encrypt)
        {
            filename = g_file_get_basename (finfo->file);
            gpgme_data_set_file_name (data, filename);
            g_free (filename);
        }

        /* The start callback */
        if (mode->startcb) {
            if (!(mode->startcb) (mode, finfo->uri, data, pop, err))
                goto finally;
        }

        /* Let progress dialog pop up */
        seahorse_tool_progress_block (FALSE);

        /* Run until the operation completes */
        seahorse_util_wait_until ((!seahorse_operation_is_running (op) ||
                                   !seahorse_tool_progress_check ()));

        /* If cancel then reflect that */
        if (seahorse_operation_is_running (op)) {
            seahorse_operation_cancel (op);
            goto finally;
        }

        if (!seahorse_operation_is_successful (op)) {
            seahorse_operation_copy_error (op, err);
            goto finally;
        }

        /* The done callback */
        if (mode->donecb) {
            if (!(mode->donecb) (mode, finfo->uri, data, pop, err))
                goto finally;
        }

        ctx->done += g_file_info_get_size (finfo->info);
        ctx->cur = NULL;

        g_object_unref (pop);
        pop = NULL;

        gpgme_data_release (data);
        data = NULL;
    }

    seahorse_tool_progress_update (1.0, "");
    ret = TRUE;

finally:
    if (pop)
        g_object_unref (pop);
    if (data)
        gpgme_data_release (data);

    return ret;
}