void
seahorse_server_source_take_operation (SeahorseServerSource *ssrc, SeahorseOperation *op)
{
    g_return_if_fail (SEAHORSE_IS_SERVER_SOURCE (ssrc));
    g_return_if_fail (SEAHORSE_IS_OPERATION (op));
    
    seahorse_multi_operation_take (ssrc->priv->mop, op);
}
void
seahorse_operation_mark_start (SeahorseOperation *op)
{
    g_return_if_fail (SEAHORSE_IS_OPERATION (op));

    /* A running operation always refs itself */
    g_object_ref (op);
    op->is_running = TRUE;
    op->is_done = FALSE;
    op->is_cancelled = FALSE;
    op->progress = -1;

    g_free (op->message);
    op->message = NULL;
}
/**
 * seahorse_progress_status_set_operation:
 * @swidget: The SeahorseWidget to add the operation to
 * @operation: The operation to add
 *
 * Adds the operation to the widget.
 *
 */
void 
seahorse_progress_status_set_operation (SeahorseWidget *swidget, 
                                        SeahorseOperation *operation)
{
    SeahorseOperation *prev;
    
    /* 
     * Note that this is not one off, the operation is monitored until it is 
     * replaced, so if the operation starts up again the progress will be 
     * displayed 
     */
    
    g_return_if_fail (SEAHORSE_IS_WIDGET (swidget));
    g_return_if_fail (SEAHORSE_IS_OPERATION (operation));
    
    prev = SEAHORSE_OPERATION (g_object_get_data (G_OBJECT (swidget), "operation"));
    if (prev) {
	    
        /* If it's the same operation, just ignore */
        if (prev == operation)
            return;
        
        /* If the previous one was a multi operation, just piggy back this one in */
        if (SEAHORSE_IS_MULTI_OPERATION (prev)) {
       	    g_object_ref (operation);
            seahorse_multi_operation_take (SEAHORSE_MULTI_OPERATION (prev), operation);
            return;
        }

        /* Otherwise disconnect old progress, replace with new */
        disconnect_progress (swidget, prev);
    }
        
    g_object_ref (operation);
    g_object_set_data_full (G_OBJECT (swidget), "operation", operation, 
                            (GDestroyNotify)g_object_unref);
    g_signal_connect (swidget, "destroy", 
                      G_CALLBACK (disconnect_progress), operation);
    
    if (!seahorse_operation_is_running (operation))
        operation_done (operation, swidget);

    operation_progress (operation, seahorse_operation_get_message (operation),
                        seahorse_operation_get_progress (operation), swidget);
    
    g_signal_connect (operation, "done", G_CALLBACK (operation_done), swidget);
    g_signal_connect (operation, "progress", G_CALLBACK (operation_progress), swidget);
}
void 
seahorse_keyserver_results_show (SeahorseOperation* op, GtkWindow* parent, const char* search_text) 
{
	SeahorseKeyserverResults* res;
	GtkWindow *window;
	
	g_return_if_fail (SEAHORSE_IS_OPERATION (op));
	g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
	g_return_if_fail (search_text != NULL);
	
	res = g_object_new (SEAHORSE_TYPE_KEYSERVER_RESULTS, "name", "keyserver-results", "search", search_text, NULL);
	
	/* Destorys itself with destroy */
	g_object_ref_sink (res);
	
	if (parent != NULL) {
		window = GTK_WINDOW (seahorse_widget_get_toplevel (SEAHORSE_WIDGET (res)));
		gtk_window_set_transient_for (window, parent);
	}

	seahorse_progress_status_set_operation (SEAHORSE_WIDGET (res), op);
}
void
seahorse_operation_cancel (SeahorseOperation *op)
{
    SeahorseOperationClass *klass;

    g_return_if_fail (SEAHORSE_IS_OPERATION (op));
    g_return_if_fail (op->is_running);

    g_object_ref (op);

    klass = SEAHORSE_OPERATION_GET_CLASS (op);

    /* A derived operation exists */
    if (klass->cancel)
        (*klass->cancel) (op);

    /* No derived operation exists */
    else
        seahorse_operation_mark_done (op, TRUE, NULL);

    g_object_unref (op);
}
void
seahorse_operation_mark_done (SeahorseOperation *op, gboolean cancelled,
                              GError *error)
{
    g_return_if_fail (SEAHORSE_IS_OPERATION (op));
    g_return_if_fail (op->is_running);

    /* No message on completed operations */
    g_free (op->message);
    op->message = NULL;

    op->progress = cancelled ? -1 : 1.0;
    op->is_running = FALSE;
    op->is_done = TRUE;
    op->is_cancelled = cancelled;
    op->error = error;

    g_signal_emit (op, signals[PROGRESS], 0, NULL, op->progress);
    g_signal_emit (op, signals[DONE], 0);

    /* A running operation always refs itself */
    g_object_unref (op);
}
void
seahorse_operation_mark_progress (SeahorseOperation *op, const gchar *message,
                                  gdouble progress)
{
    gboolean emit = FALSE;

    g_return_if_fail (SEAHORSE_IS_OPERATION (op));
    g_return_if_fail (op->is_running);

    if (progress != op->progress) {
        op->progress = progress;
        emit = TRUE;
    }

    if (!seahorse_util_string_equals (op->message, message)) {
        g_free (op->message);
        op->message = message ? g_strdup (message) : NULL;
        emit = TRUE;
    }

    if (emit)
        g_signal_emit (G_OBJECT (op), signals[PROGRESS], 0, op->message, progress);
}