aboutsummaryrefslogblamecommitdiffstats
path: root/calendar/gui/e-meeting-edit.c
blob: d8df270effa91b30a36b1cca6f908824ada7c9f4 (plain) (tree)
























                                                                            
                 





                                                    







                                                            





                                   










                                                             


                                                                        










                                   
 























                                                                                  





                                    
                                    
                    

                                                                        

                      
                                                                                    
      





                                                                             





















                                                                                                        







                                                                                                      
                                                                   







                                     

                                    
                      
                                                                                     
      


                                                                        



                         






                                                                     
 






                                     
                                    
 
















































                                                                                      
      
 



















































                                                                                                 

                                                                        



                                                                                    

                                                                                        

                                                                                
                                                                                  

























                                                                                  
         








                                                                  
 


                                                                           
 
                                            
 
                                                                         

                              

                                                                                
 
                                                                


                                                     





















                                                                                                 

                                                         










































                                                                                                      
                                                                
 






                                                                           
                                   
         


                                         




                                                           




                                                                        


                                                                                              
                                                                                           


                                                        











                                                                                               





                                                         





                                                                        


                                                                                            
                                                                                           



                                                        


                                                 
                

                                                                                               
 
                                        
 
                                                         
 




                                                                                              
 


                                                                                      
 








                                                                                                                    
                        
                                                                              
                                           
 

                                             




         





                                           
 




                                                                        
 












                                                                                            

























                                                                          
 






                                      
 

        

     
                                       
 
                                    
                                                            
                           

                         


                                          
 
                                                     
 



                                                                                     
        

                                                                                   

                                                                          
 


                                                                                                             
 

                                                                              
 

                                                                                    
 

                                                                               
 

                                                                           
 


                                                                          

                                                               
                                                                             

                                                                  
                                                                                

                                                                

                                                                              

                                                                                    






                                                                                                       


































                                                                                                      





                                                                                            
                                                        

         
 
                                               



                      
                                                                                       

      

                                                          
 

                                                       
 
                                                  
 
/* Evolution calendar - Meeting editor dialog
 *
 * Copyright (C) 2000 Helix Code, Inc.
 *
 * Authors: Jesse Pavel <jpavel@helixcode.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */

#include <config.h>
#include <gnome.h>
#include <glade/glade.h>
#include <icaltypes.h>
#include <ical.h>
#include "e-meeting-edit.h"

#define E_MEETING_GLADE_XML "e-meeting-dialog.glade"

#define E_MEETING_DEBUG

typedef struct _EMeetingEditorPrivate EMeetingEditorPrivate;

struct _EMeetingEditorPrivate {
    /* These are the widgets to be used in the GUI. */
    GladeXML *xml;
    GtkWidget *meeting_window;
    GtkWidget *attendee_list;
    GtkWidget *address_entry;
    GtkWidget *edit_dialog;
    GtkWidget *organizer_entry;
    GtkWidget *role_entry;
    GtkWidget *rsvp_check;
    
    gint changed_signal_id;

    /* Various pieces of information. */
    gint selected_row;
    CalComponent *comp;
    CalClient *client;
    icalcomponent *icalcomp, *vevent;

    gint numentries;  /* How many attendees are there? */
    gboolean dirty;  /* Has anything changed? */
}; 

#define NUM_COLUMNS 4  /* The number of columns in our attendee list. */

enum column_names {ADDRESS_COL, ROLE_COL, RSVP_COL, STATUS_COL};

static gchar *partstat_values[] = {
    "Needs action",
    "Accepted",
    "Declined",
    "Tentative",
    "Delegated",
    "Completed",
    "In Progress",
    "Unknown"
};

static gchar *role_values[] = {
    "Chair",
    "Required Participant",
    "Optional Participant",
    "Non-Participant",
    "Other"
};


/* Note that I have to iterate and check myself because
   ical_property_get_xxx_parameter doesn't take into account the
   kind of parameter for which you wish to search! */
static icalparameter *
get_icalparam_by_type (icalproperty *prop, icalparameter_kind kind)
{
    icalparameter *param;

    for (param = icalproperty_get_first_parameter (prop, ICAL_ANY_PARAMETER);
         param != NULL && icalparameter_isa (param) != kind;
         param = icalproperty_get_next_parameter (prop, ICAL_ANY_PARAMETER) );

    return param;
}


static gboolean
window_delete_cb (GtkWidget *widget,
          GdkEvent *event,
          gpointer data)
{   
    EMeetingEditorPrivate *priv;
    gchar *text;

    priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv;

#ifdef E_MEETING_DEBUG
    g_printerr ("e-meeting-edit.c: The main window received a delete event.\n");
#endif
    
    if (priv->dirty == TRUE) {
        /* FIXME: notify the event editor that our data has changed. 
            For now, I'll just display a dialog box. */
        {
            GtkWidget *dialog;
            icalproperty *prop;
            icalvalue *value;

            /* Save the organizer into the iCAL object. */
                prop = icalcomponent_get_first_property (priv->vevent, ICAL_ORGANIZER_PROPERTY);

            text = gtk_entry_get_text (GTK_ENTRY (priv->organizer_entry));
#ifdef E_MEETING_DEBUG      
            g_print ("e-meeting-edit.c: The organizer entry is %s.\n", text);
#endif
            if (strlen (text) > 0) {
                gchar buffer[200];
                g_snprintf (buffer, 190, "MAILTO:%s", text);
                
                if (prop == NULL) {
                    /* We need to add an ORGANIZER property. */
                    prop = icalproperty_new (ICAL_ORGANIZER_PROPERTY);
                    icalcomponent_add_property (priv->vevent, prop);
                }
                value = icalvalue_new_text (buffer);
                icalproperty_set_value (prop, value);
            }
        
            dialog = gnome_warning_dialog_parented ("Note that the meeting has changed,\n"
                                "and you should save this event.",
                                GTK_WINDOW (priv->meeting_window));
            gnome_dialog_run (GNOME_DIALOG(dialog));
        }
    }

    gtk_entry_set_text (GTK_ENTRY (priv->organizer_entry), "");

    return (FALSE);
}

static void 
window_destroy_cb (GtkWidget *widget,
           gpointer data)
{
    EMeetingEditorPrivate *priv;

#ifdef E_MEETING_DEBUG
    g_printerr ("e-meeting-edit.c: The main window received a destroy event.\n");
#endif

    priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv;

    gtk_main_quit ();
    return;
}

/* put_property_in_list() synchronizes the display of row `rownum'
   in our attendee list to the values of `prop'. If rownum < 0,
   then put_property_in_list() will append a new row. 
   If the property doesn't contain certain parameters that we deem
   necessary, it will add them. */
static void
put_property_in_list (icalproperty *prop, gint rownum, gpointer data)
{
    gchar *row_text[NUM_COLUMNS];
    gchar *text, *new_text;
    icalparameter *param;
    icalvalue *value;
    gint enumval;
    gint cntr;

    EMeetingEditorPrivate *priv;

    priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv;
    
    value = icalproperty_get_value (prop);

    if (value != NULL) {
        text = strdup (icalvalue_as_ical_string (value));
    
        /* Here I strip off the "MAILTO:" if it is present. */
        new_text = strchr (text, ':');
        if (new_text != NULL)
            new_text++;
        else
            new_text = text;
    
        row_text[ADDRESS_COL] = g_strdup (new_text);
        g_free (text);
    }

    param = get_icalparam_by_type (prop, ICAL_ROLE_PARAMETER);
    if (param == NULL) {
#ifdef E_MEETING_DEBUG      
        g_print ("e-meeting-edit.c: within put_param...(), param is NULL.\n");
#endif
        param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT);
        icalproperty_add_parameter (prop, param);
    }
        
    enumval = icalparameter_get_role (param);
    if (enumval < 0 || enumval > 4)
        enumval = 4;
#ifdef E_MEETING_DEBUG      
    g_print ("e-meeting-edit.c: the role value is %d.\n", enumval);
#endif
    
    row_text[ROLE_COL] = role_values [enumval];

    param = get_icalparam_by_type (prop, ICAL_RSVP_PARAMETER);
    if (param == NULL) {
        param = icalparameter_new_rsvp (TRUE);
        icalproperty_add_parameter (prop, param);
    }

    if (icalparameter_get_rsvp (param))
        row_text[RSVP_COL] = "Y";
    else
        row_text[RSVP_COL] = "N";

#ifdef E_MEETING_DEBUG      
    g_print ("e-meeting-edit.c: the RSVP is %c.\n", row_text[RSVP_COL][0]);
#endif

    
    param = get_icalparam_by_type (prop, ICAL_PARTSTAT_PARAMETER);
    if (param == NULL) {
        param = icalparameter_new_partstat (ICAL_PARTSTAT_NEEDSACTION);
        icalproperty_add_parameter (prop, param);
    }

    enumval = icalparameter_get_partstat (param);
    if (enumval < 0 || enumval > 7) {
        enumval = 7;
    }

    row_text[STATUS_COL] = partstat_values [enumval];

    if (rownum < 0) {
        gtk_clist_append (GTK_CLIST (priv->attendee_list), row_text);
        gtk_clist_set_row_data (GTK_CLIST (priv->attendee_list), priv->numentries, prop);
        priv->numentries++;
    }
    else {
        for (cntr = 0; cntr < NUM_COLUMNS; cntr++) {
            gtk_clist_set_text (GTK_CLIST (priv->attendee_list), 
                        rownum,
                        cntr,
                        row_text[cntr]);
        }
    }

    g_free (row_text[ADDRESS_COL]);
}

    

/* edit_attendee() performs the GUI manipulation and interaction for
   editing `prop' and returns TRUE if the user indicated that he wants
   to save the new property information.

   Note that it is necessary that the property have parameters of the types
   RSVP, PARTSTAT, and ROLE already when passed into this function. */
static gboolean
edit_attendee (icalproperty *prop, gpointer data)
{
    EMeetingEditorPrivate *priv;
    gint button_num;
    gchar *new_text, *text;
    icalparameter *param;
    icalvalue *value;
    gchar buffer[200];
    gint cntr;
    gint enumval;
    gboolean retval;

    priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv;

    g_return_val_if_fail (prop != NULL, FALSE);

    if (priv->edit_dialog == NULL || priv->address_entry == NULL) {
        priv->edit_dialog = glade_xml_get_widget (priv->xml, "edit_dialog");
        priv->address_entry = glade_xml_get_widget (priv->xml, "address_entry");

        gnome_dialog_set_close (GNOME_DIALOG (priv->edit_dialog), TRUE);
        gnome_dialog_editable_enters (GNOME_DIALOG (priv->edit_dialog), 
                          GTK_EDITABLE (priv->address_entry));
        gnome_dialog_close_hides (GNOME_DIALOG (priv->edit_dialog), TRUE);
        gnome_dialog_set_default (GNOME_DIALOG (priv->edit_dialog), 0);
    }

    g_return_val_if_fail (priv->edit_dialog != NULL, FALSE);
    g_return_val_if_fail (priv->address_entry != NULL, FALSE);

    gtk_widget_realize (priv->edit_dialog);
    
    value = icalproperty_get_value (prop);

    if (value != NULL) {
        text = strdup (icalvalue_as_ical_string (value));
    
        /* Here I strip off the "MAILTO:" if it is present. */
        new_text = strchr (text, ':');
        if (new_text != NULL)
            new_text++;
        else
            new_text = text;
    
        gtk_entry_set_text (GTK_ENTRY (priv->address_entry), new_text);
        g_free (text);
    }
    else {
        gtk_entry_set_text (GTK_ENTRY (priv->address_entry), "");
    }
                

    param = get_icalparam_by_type (prop, ICAL_ROLE_PARAMETER);
    enumval = icalparameter_get_role (param);
    if (enumval < 0 || enumval > 4)
        enumval = 4;
    
    text = role_values [enumval];
    gtk_entry_set_text (GTK_ENTRY (priv->role_entry), text);

    param = get_icalparam_by_type (prop, ICAL_RSVP_PARAMETER);
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->rsvp_check),
                    icalparameter_get_rsvp (param));

    gtk_widget_show (priv->edit_dialog);

    button_num = gnome_dialog_run (GNOME_DIALOG (priv->edit_dialog));

    if (button_num == 0) {
        /* The user pressed the OK button. */
        new_text = gtk_entry_get_text (GTK_ENTRY (priv->address_entry));

        g_snprintf (buffer, 190, "MAILTO:%s", new_text);
        value = icalvalue_new_text (buffer);
        icalproperty_set_value (prop, value);

        /* Take care of the ROLE. */
        icalproperty_remove_parameter (prop, ICAL_ROLE_PARAMETER);

        param = NULL;
        text = gtk_entry_get_text (GTK_ENTRY(priv->role_entry));
#ifdef E_MEETING_DEBUG      
        g_print ("e-meeting-edit.c: the role entry text is %s.\n", text);
#endif

        for (cntr = 0; cntr < 5; cntr++) {
            if (strncmp (text, role_values[cntr], 3) == 0) {
                param = icalparameter_new_role (cntr);
                break;
            }
        }

        if (param == NULL) {
            g_print ("e-meeting-edit.c: edit_attendee() the ROLE param was null.\n");
            /* Use this as a default case, if none of the others match. */
            param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT);
        }

        icalproperty_add_parameter (prop, param);

        /* Now the RSVP. */
        icalproperty_remove_parameter (prop, ICAL_RSVP_PARAMETER);

        param = icalparameter_new_rsvp 
                (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->rsvp_check)));
        icalproperty_add_parameter (prop, param);

        retval = TRUE;
    }
    else  /* The user didn't say OK. */
        retval = FALSE;
    
    return retval;
}


static void 
add_button_clicked_cb (GtkWidget *widget, gpointer data)
{
    EMeetingEditorPrivate *priv;
    icalproperty *prop;
    icalparameter *param;

#ifdef E_MEETING_DEBUG
    g_printerr ("e-meeting-edit.c: the add button was clicked.\n");
#endif

    priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv;

    prop = icalproperty_new (ICAL_ATTENDEE_PROPERTY);
    param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT); 
    icalproperty_add_parameter (prop, param);
    param = icalparameter_new_rsvp (TRUE); 
    icalproperty_add_parameter (prop, param);
    param = icalparameter_new_partstat (ICAL_PARTSTAT_NEEDSACTION);
    icalproperty_add_parameter (prop, param);

    if (edit_attendee (prop, data) == TRUE) {
#ifdef E_MEETING_DEBUG      
        g_print ("e-meeting-edit.c: After edit_attendee()");
#endif

        /* Let's add this property to our component and to the CList. */
        icalcomponent_add_property (priv->vevent, prop);

        /* The -1 indicates that we should add a new row. */
        put_property_in_list (prop, -1, data);

#ifdef E_MEETING_DEBUG      
        g_print ("e-meeting-edit.c: After put_property_in_list()");
#endif

        priv->dirty = TRUE;
    }
    else {
        icalproperty_free (prop);
    }
}   

static void 
delete_button_clicked_cb (GtkWidget *widget, gpointer data)
{
    EMeetingEditorPrivate *priv;

    priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv;

    if (priv->selected_row < 0) {
        GtkWidget *dialog;

        dialog = gnome_warning_dialog_parented ("You must select an entry to delete.",
                            GTK_WINDOW (priv->meeting_window));
        gnome_dialog_run (GNOME_DIALOG(dialog));
    }
    else {
        /* Delete the associated property from the iCAL object. */
        icalproperty *prop;

        prop = (icalproperty *)gtk_clist_get_row_data (GTK_CLIST (priv->attendee_list),
                                   priv->selected_row);
        icalcomponent_remove_property (priv->vevent, prop);
        icalproperty_free (prop);

        gtk_clist_remove (GTK_CLIST (priv->attendee_list), priv->selected_row);
        priv->selected_row = -1;
        priv->numentries--;
        priv->dirty = TRUE;
    }
}

static void 
edit_button_clicked_cb (GtkWidget *widget, gpointer data)
{
    EMeetingEditorPrivate *priv;

    priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv;

    
    if (priv->selected_row < 0) {
        GtkWidget *dialog;

        dialog = gnome_warning_dialog_parented ("You must select an entry to edit.",
                            GTK_WINDOW (priv->meeting_window));
        gnome_dialog_run (GNOME_DIALOG(dialog));
        return;
    }
    else {
        icalproperty *prop, *new_prop;
        icalparameter *param, *new_param;
        icalvalue *value, *new_value;
        
        prop = (icalproperty *)gtk_clist_get_row_data (GTK_CLIST (priv->attendee_list),
                                   priv->selected_row);

        g_assert (prop != NULL);

        new_prop = icalproperty_new_clone (prop);

        if (edit_attendee (new_prop, data)) {
            /* The user hit Okay. */
            /*We need to synchronize the old property with the newly edited one.*/
            value = icalvalue_new_clone (icalproperty_get_value (new_prop));
            icalproperty_set_value (prop, value);

            icalproperty_remove_parameter (prop, ICAL_ROLE_PARAMETER);
            icalproperty_remove_parameter (prop, ICAL_RSVP_PARAMETER);
            icalproperty_remove_parameter (prop, ICAL_PARTSTAT_PARAMETER);

            param = icalparameter_new_clone (get_icalparam_by_type (new_prop, ICAL_ROLE_PARAMETER));
            g_assert (param != NULL);
            icalproperty_add_parameter (prop, param);
            param = icalparameter_new_clone (get_icalparam_by_type (new_prop, ICAL_RSVP_PARAMETER));
            g_assert (param != NULL);
            icalproperty_add_parameter (prop, param);
            param = icalparameter_new_clone (get_icalparam_by_type (new_prop, ICAL_PARTSTAT_PARAMETER));
            g_assert (param != NULL);
            icalproperty_add_parameter (prop, param);
            
            put_property_in_list (prop, priv->selected_row, data);
            priv->dirty = TRUE;

        }
        icalproperty_free (new_prop);
    }
}



static void 
list_row_select_cb  (GtkWidget *widget,
                     gint row,
                     gint column,
                     GdkEventButton *event,
                     gpointer data)
{
    EMeetingEditorPrivate *priv;

    priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv;
    
    priv->selected_row = row;
}

static void
organizer_changed_cb (GtkWidget *widget, gpointer data)
{
    EMeetingEditorPrivate *priv;

    priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv;

    gtk_signal_disconnect (GTK_OBJECT (priv->organizer_entry), priv->changed_signal_id);

    priv->dirty = TRUE;
}


/* ------------------------------------------------------------ */
/* --------------------- Exported Functions ------------------- */
/* ------------------------------------------------------------ */

EMeetingEditor * 
e_meeting_editor_new (CalComponent *comp, CalClient *client)
{
    EMeetingEditor *object;
    EMeetingEditorPrivate *priv;

    object = (EMeetingEditor *)g_new(EMeetingEditor, 1);
    
    priv = (EMeetingEditorPrivate *) g_new0(EMeetingEditorPrivate, 1);
    priv->selected_row = -1;
    priv->comp = comp;
    priv->client = client;
    priv->icalcomp = cal_component_get_icalcomponent (comp);
    
    object->priv = priv;

    return object;  
}

void
e_meeting_editor_free (EMeetingEditor *editor)
{
    if (editor == NULL)
        return;
        
    if (editor->priv != NULL)
        g_free (editor->priv);
    
    g_free (editor);
}
    


void 
e_meeting_edit (EMeetingEditor *editor)
{
    EMeetingEditorPrivate *priv;
    GtkWidget *add_button, *delete_button, *edit_button;
    icalproperty *prop;
    icalvalue *value;
    gchar *text;


    g_return_if_fail (editor != NULL);

    priv = (EMeetingEditorPrivate *)editor->priv;

    g_return_if_fail (priv != NULL);


    priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/" E_MEETING_GLADE_XML, NULL);
    
    priv->meeting_window =  glade_xml_get_widget (priv->xml, "meeting_window");
    priv->attendee_list = glade_xml_get_widget (priv->xml, "attendee_list");
    priv->role_entry = glade_xml_get_widget (priv->xml, "role_entry");
    priv->rsvp_check = glade_xml_get_widget (priv->xml, "rsvp_check");

    gtk_clist_set_column_justification (GTK_CLIST (priv->attendee_list), ROLE_COL, GTK_JUSTIFY_CENTER);
    gtk_clist_set_column_justification (GTK_CLIST (priv->attendee_list), RSVP_COL, GTK_JUSTIFY_CENTER);
    gtk_clist_set_column_justification (GTK_CLIST (priv->attendee_list), STATUS_COL, GTK_JUSTIFY_CENTER);

        gtk_signal_connect (GTK_OBJECT (priv->meeting_window), "delete_event",
                            GTK_SIGNAL_FUNC (window_delete_cb), editor);

    gtk_signal_connect_after (GTK_OBJECT (priv->meeting_window), "delete_event",
                  GTK_SIGNAL_FUNC (window_destroy_cb), editor);

        gtk_signal_connect (GTK_OBJECT (priv->meeting_window), "destroy_event",
                            GTK_SIGNAL_FUNC (window_destroy_cb), editor);

    gtk_signal_connect (GTK_OBJECT (priv->attendee_list), "select_row",
                GTK_SIGNAL_FUNC (list_row_select_cb), editor);

    add_button = glade_xml_get_widget (priv->xml, "add_button");
    delete_button = glade_xml_get_widget (priv->xml, "delete_button");
    edit_button = glade_xml_get_widget (priv->xml, "edit_button");

    gtk_signal_connect (GTK_OBJECT (add_button), "clicked",
                GTK_SIGNAL_FUNC (add_button_clicked_cb), editor);
    
    gtk_signal_connect (GTK_OBJECT (delete_button), "clicked",
                GTK_SIGNAL_FUNC (delete_button_clicked_cb), editor);

    gtk_signal_connect (GTK_OBJECT (edit_button), "clicked",
                GTK_SIGNAL_FUNC (edit_button_clicked_cb), editor);

    priv->organizer_entry = glade_xml_get_widget (priv->xml, "organizer_entry");

    if (icalcomponent_isa (priv->icalcomp) != ICAL_VEVENT_COMPONENT)
        priv->vevent = icalcomponent_get_first_component(priv->icalcomp,ICAL_VEVENT_COMPONENT);
    else
        priv->vevent = priv->icalcomp;

    g_assert (priv->vevent != NULL);

    /* Let's extract the organizer, if there is one. */
        prop = icalcomponent_get_first_property (priv->vevent, ICAL_ORGANIZER_PROPERTY);

    if (prop != NULL) {
        gchar *buffer;

#ifdef E_MEETING_DEBUG      
        g_print ("e-meeting-edit.c: The organizer property is not null.\n");
#endif

            value = icalproperty_get_value (prop);
        buffer = g_strdup (icalvalue_as_ical_string (value));
            if (buffer != NULL) {
            /* Strip off the MAILTO:, if it is present. */
                text = strchr (buffer, ':');
            if (text == NULL)
                text = buffer;
            else
                text++;
                
            gtk_entry_set_text (GTK_ENTRY (priv->organizer_entry), text);
            g_free (buffer);
        }
        
    }
#ifdef E_MEETING_DEBUG      
    else {
        g_print ("e-meeting-edit.c: the organizer property was NULL.\n");
    }
#endif

    priv->changed_signal_id = gtk_signal_connect (GTK_OBJECT (priv->organizer_entry), "changed",
                              GTK_SIGNAL_FUNC (organizer_changed_cb), editor);


    /* Let's go through the iCAL object, and create a list entry
       for each ATTENDEE property. */
        for (prop = icalcomponent_get_first_property (priv->vevent, ICAL_ATTENDEE_PROPERTY);
             prop != NULL;
             prop = icalcomponent_get_next_property (priv->vevent, ICAL_ATTENDEE_PROPERTY))
    {
        put_property_in_list (prop, -1, editor);
    }
    

    gtk_widget_show (priv->meeting_window);

    gtk_main ();

#ifdef E_MEETING_DEBUG
    g_printerr ("e-meeting-edit.c: We've terminated the subsidiary gtk_main().\n");
#endif

    if (priv->meeting_window != NULL)
        gtk_widget_destroy (priv->meeting_window);

    if (priv->edit_dialog != NULL)
        gtk_widget_destroy (priv->edit_dialog);

    gtk_object_unref (GTK_OBJECT (priv->xml));
}