aboutsummaryrefslogblamecommitdiffstats
path: root/calendar/gui/e-itip-control.c
blob: 670cfed67f7cfd0ba6ecc64bd151ec9acdbe0237 (plain) (tree)


















                                                                           



                          












                                                        
                                           







                                                  














                                                                             



















































































































































                                                                                                


                                                                                  






































                                                                                                 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * e-itip-control.c
 *
 * Authors:
 *    Jesse Pavel <jpavel@helixcode.com>
 *
 * Copyright 2000, Helix Code, Inc.
 */

#include <config.h>
#include <gnome.h>
#include <bonobo.h>
#include <glade/glade.h>
#include <icaltypes.h>
#include <ical.h>

#include "e-itip-control.h"


#define DEFAULT_WIDTH 300
#define DEFAULT_HEIGHT 200


typedef struct _EItipControlPrivate EItipControlPrivate;

struct _EItipControlPrivate {
    GladeXML *xml;
    GtkWidget *main_frame;
    GtkWidget *text_box;

    icalcomponent *main_comp;
};


static void
itip_control_destroy_cb (GtkObject *object,
            gpointer data)
{
    EItipControlPrivate *priv = data;

    gtk_object_unref (GTK_OBJECT (priv->xml));
    g_free (priv);
}
    
static void
itip_control_size_request_cb (GtkWidget *widget, GtkRequisition *requisition)
{
    requisition->width = DEFAULT_WIDTH;
    requisition->height = DEFAULT_HEIGHT;
}


/*
 * Bonobo::PersistStream
 *
 * These two functions implement the Bonobo::PersistStream load and
 * save methods which allow data to be loaded into and out of the
 * BonoboObject.
 */

static char *
stream_read (Bonobo_Stream stream)
{
    Bonobo_Stream_iobuf *buffer;
    CORBA_Environment    ev;
    gchar *data = NULL;
    gint length = 0;

    CORBA_exception_init (&ev);
    do {
#define READ_CHUNK_SIZE 65536
        Bonobo_Stream_read (stream, READ_CHUNK_SIZE,
                    &buffer, &ev);

        if (ev._major != CORBA_NO_EXCEPTION) {
            CORBA_exception_free (&ev);
            return NULL;
        }

        if (buffer->_length <= 0)
            break;

        data = g_realloc (data,
                  length + buffer->_length);

        memcpy (data + length,
            buffer->_buffer, buffer->_length);

        length += buffer->_length;

        CORBA_free (buffer);
    } while (1);

    CORBA_free (buffer);
    CORBA_exception_free (&ev);

    if (data == NULL)
      data = g_strdup("");

    return data;
} /* stream_read */

/*
 * This function implements the Bonobo::PersistStream:load method.
 */
static void
pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream,
          Bonobo_Persist_ContentType type, void *data,
          CORBA_Environment *ev)
{
    EItipControlPrivate *priv = data;
    gchar *vcalendar;
    gint pos, length;

    if (type && g_strcasecmp (type, "text/calendar") != 0 &&        
        g_strcasecmp (type, "text/x-calendar") != 0) {      
        CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
                     ex_Bonobo_Persist_WrongDataType, NULL);
        return;
    }

    if ((vcalendar = stream_read (stream)) == NULL) {
        CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
                     ex_Bonobo_Persist_FileNotFound, NULL);
        return;
    }

    /* Do something with the data, here. */
    pos = 0;
    length = strlen (vcalendar);

    if (length > 0) 
        gtk_editable_delete_text (GTK_EDITABLE (priv->text_box), 0, length);

    gtk_editable_insert_text (GTK_EDITABLE (priv->text_box),
                  vcalendar,
                  length,
                  &pos);


    g_free (vcalendar);

} /* pstream_load */

/*
 * This function implements the Bonobo::PersistStream:save method.
 */
static void
pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream,
          Bonobo_Persist_ContentType type, void *data,
          CORBA_Environment *ev)
{
    EItipControlPrivate *priv = data;
    gchar                *vcalendar;
    int                  length;

    if (type && g_strcasecmp (type, "text/calendar") != 0 &&        
        g_strcasecmp (type, "text/x-calendar") != 0) {      
        CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
                     ex_Bonobo_Persist_WrongDataType, NULL);
        return;
    }

    /* Put something into vcalendar here. */
    length = gtk_text_get_length (GTK_TEXT (priv->text_box));
    vcalendar = gtk_editable_get_chars (GTK_EDITABLE (priv->text_box), 0, -1);

    bonobo_stream_client_write (stream, vcalendar, length, ev);
    g_free (vcalendar);
} /* pstream_save */

static CORBA_long
pstream_get_max_size (BonoboPersistStream *ps, void *data,
              CORBA_Environment *ev)
{
    EItipControlPrivate *priv = data;
    gint length;
  
    length = gtk_text_get_length (GTK_TEXT (priv->text_box));

    return length;
}

static Bonobo_Persist_ContentTypeList *
pstream_get_content_types (BonoboPersistStream *ps, void *closure,
               CORBA_Environment *ev)
{
    return bonobo_persist_generate_content_types (2, "text/calendar", "text/x-calendar");
}

static BonoboObject *
e_itip_control_factory (BonoboGenericFactory *Factory, void *closure)
{
    BonoboControl      *control;
    BonoboPersistStream *stream;
    EItipControlPrivate *priv;

    priv = g_new0 (EItipControlPrivate, 1);

    priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/" "e-itip-control.glade", "main_frame");

    /* Create the control. */
    priv->main_frame = glade_xml_get_widget (priv->xml, "main_frame");
    priv->text_box = glade_xml_get_widget (priv->xml, "text_box");
    gtk_text_set_editable (GTK_TEXT (priv->text_box), FALSE);

    gtk_signal_connect (GTK_OBJECT (priv->main_frame), "destroy",
                GTK_SIGNAL_FUNC (itip_control_destroy_cb), priv);
    gtk_signal_connect (GTK_OBJECT (priv->main_frame), "size_request",
                GTK_SIGNAL_FUNC (itip_control_size_request_cb), priv);

    gtk_widget_show (priv->text_box);
    gtk_widget_show (priv->main_frame);

    control = bonobo_control_new (priv->main_frame);

    stream = bonobo_persist_stream_new (pstream_load, pstream_save,
                        pstream_get_max_size,
                        pstream_get_content_types,
                        priv);

    if (stream == NULL) {
        bonobo_object_unref (BONOBO_OBJECT (control));
        return NULL;
    }

    bonobo_object_add_interface (BONOBO_OBJECT (control),
                    BONOBO_OBJECT (stream));

    return BONOBO_OBJECT (control);
}

void
e_itip_control_factory_init (void)
{
    static BonoboGenericFactory *factory = NULL;

    if (factory != NULL)
        return;

    factory =
        bonobo_generic_factory_new (
                "OAFIID:control-factory:e_itipview:10441fcf-9a4f-4bf9-a026-d50b5462d45a",
            e_itip_control_factory, NULL);

    if (factory == NULL)
        g_error ("I could not register an iTip control factory.");
}