aboutsummaryrefslogblamecommitdiffstats
path: root/addressbook/backend/ebook/e-book-view.c
blob: 68c73e06f72c62b27b0ccaa720e12103e0beb114 (plain) (tree)
1
2
3
4
5
6
7
8
9
10




                                                                           
                                  
  
                                     

   
                   
 



                                 
                   
                           
 
                                  

                          
                                                                 

                                    









                                                   
                          
                       





                                               




                                                   
                                     


           


                                                                 


                                                                                       

                                                                      
 
                                                                   






                                                                    


                                                                                       

                                                                        
 
                                                                   
                                  





                                                                   

                                                                        
 
                         

 

                                                                    
                                                               
 

                                                                             

 



                                                                          

                                                                          


                              









                                                                                    
        












                                                                


                                                                


                                                                      


                                                                                
                      





                      
                                                                                                                               









                                                                 
                                                                                       



                                                                                              









                                                        

                                                                                                                           
 

                                                                    






                    
                                                                                                   


                             
                                                          

                                                                             
                                           





                            







                                                                   
                            

 







                                                                      



                                                                            
                                                    





                                                                
                                     



                                                                



                                                               
 

                                                       
 
                                                                                            
 




                                                                                              

                 






                                                                                                  
 

                                         

         
                                                       




                                              
                                                            
 
                                                        

                                            







                                                                             

                                          







                                                                           

                                            







                                                                             
 
                                                 




                                                                                  
                                                       
                                             
                                          
 
                                              









                                                                               




                        
     

                           
                              

                     
                                  
                                                







                                                                 

                  
                                                                                     



                    
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * The Evolution addressbook client object.
 *
 * Author:
 *   Nat Friedman (nat@ximian.com)
 *
 * Copyright 1999, 2000, Ximian, Inc.
 */

#include <config.h>

#include "addressbook.h"
#include "e-card-cursor.h"
#include "e-book-view-listener.h"
#include "e-book-view.h"
#include "e-book.h"
#include "e-book-marshal.h"

static GObjectClass *parent_class;

struct _EBookViewPrivate {
    GNOME_Evolution_Addressbook_BookView     corba_book_view;

    EBook                 *book;
    
    EBookViewListener     *listener;

    int                    responses_queued_id;
};

enum {
    CARD_CHANGED,
    CARD_REMOVED,
    CARD_ADDED,
    SEQUENCE_COMPLETE,
    STATUS_MESSAGE,
    LAST_SIGNAL
};

static guint e_book_view_signals [LAST_SIGNAL];

static void
add_book_iterator (gpointer data, gpointer closure)
{
    ECard *card = E_CARD (data);
    EBook *book = E_BOOK (closure);

    e_card_set_book (card, book);
}

static void
e_book_view_do_added_event (EBookView                 *book_view,
                EBookViewListenerResponse *resp)
{
    if (book_view->priv->book)
        g_list_foreach (resp->cards, add_book_iterator, book_view->priv->book);

    g_signal_emit (book_view, e_book_view_signals [CARD_ADDED], 0,
               resp->cards);

    g_list_foreach (resp->cards, (GFunc) g_object_unref, NULL);
    g_list_free (resp->cards);
}

static void
e_book_view_do_modified_event (EBookView                 *book_view,
                   EBookViewListenerResponse *resp)
{
    if (book_view->priv->book)
        g_list_foreach (resp->cards, add_book_iterator, book_view->priv->book);

    g_signal_emit (book_view, e_book_view_signals [CARD_CHANGED], 0,
               resp->cards);

    g_list_foreach (resp->cards, (GFunc) g_object_unref, NULL);
    g_list_free (resp->cards);
}

static void
e_book_view_do_removed_event (EBookView                 *book_view,
                  EBookViewListenerResponse *resp)
{
    g_signal_emit (book_view, e_book_view_signals [CARD_REMOVED], 0,
               resp->id);

    g_free(resp->id);
}

static void
e_book_view_do_complete_event (EBookView                 *book_view,
                   EBookViewListenerResponse *resp)
{
    g_signal_emit (book_view, e_book_view_signals [SEQUENCE_COMPLETE], 0,
               resp->status);
}

static void
e_book_view_do_status_message_event (EBookView                 *book_view,
                     EBookViewListenerResponse *resp)
{
    g_signal_emit (book_view, e_book_view_signals [STATUS_MESSAGE], 0,
               resp->message);
    g_free(resp->message);
}


/*
 * Reading notices out of the EBookViewListener's queue.
 */
static void
e_book_view_check_listener_queue (EBookViewListener *listener, EBookView *book_view)
{
    EBookViewListenerResponse *resp;

    resp = e_book_view_listener_pop_response (listener);
    
    if (resp == NULL)
        return;

    switch (resp->op) {
    case CardAddedEvent:
        e_book_view_do_added_event (book_view, resp);
        break;
    case CardModifiedEvent:
        e_book_view_do_modified_event (book_view, resp);
        break;
    case CardRemovedEvent:
        e_book_view_do_removed_event (book_view, resp);
        break;
    case SequenceCompleteEvent:
        e_book_view_do_complete_event (book_view, resp);
        break;
    case StatusMessageEvent:
        e_book_view_do_status_message_event (book_view, resp);
        break;
    default:
        g_error ("EBookView: Unknown operation %d in listener queue!\n",
             resp->op);
        break;
    }

    g_free (resp);
}

static gboolean
e_book_view_construct (EBookView *book_view, GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener)
{
    CORBA_Environment  ev;
    g_return_val_if_fail (book_view != NULL,     FALSE);
    g_return_val_if_fail (E_IS_BOOK_VIEW (book_view), FALSE);

    /*
     * Copy in the corba_book_view.
     */
    CORBA_exception_init (&ev);

    book_view->priv->corba_book_view = bonobo_object_dup_ref(corba_book_view, &ev);

    if (ev._major != CORBA_NO_EXCEPTION) {
        g_warning ("e_book_view_construct: Exception duplicating corba_book_view.\n");
        CORBA_exception_free (&ev);
        book_view->priv->corba_book_view = NULL;
        return FALSE;
    }

    CORBA_exception_free (&ev);

    /*
     * Create our local BookListener interface.
     */
    book_view->priv->listener = listener;
    book_view->priv->responses_queued_id = g_signal_connect (book_view->priv->listener, "responses_queued",
                                 G_CALLBACK (e_book_view_check_listener_queue), book_view);

    bonobo_object_ref(BONOBO_OBJECT(book_view->priv->listener));

    return TRUE;
}

/**
 * e_book_view_new:
 */
EBookView *
e_book_view_new (GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener)
{
    EBookView *book_view;

    book_view = g_object_new (E_TYPE_BOOK_VIEW, NULL);

    if (! e_book_view_construct (book_view, corba_book_view, listener)) {
        g_object_unref (book_view);
        return NULL;
    }

    return book_view;
}

void
e_book_view_set_book (EBookView *book_view, EBook *book)
{
    g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view));
    g_return_if_fail (book && E_IS_BOOK (book));
    g_return_if_fail (book_view->priv->book == NULL);

    book_view->priv->book = book;
    g_object_ref (book);
}

void
e_book_view_stop (EBookView *book_view)
{
    g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view));
    if (book_view->priv->listener)
        e_book_view_listener_stop (book_view->priv->listener);
}

static void
e_book_view_init (EBookView *book_view)
{
    book_view->priv                      = g_new0 (EBookViewPrivate, 1);
    book_view->priv->book                = NULL;
    book_view->priv->corba_book_view     = CORBA_OBJECT_NIL;
    book_view->priv->listener            = NULL;
    book_view->priv->responses_queued_id = 0;
}

static void
e_book_view_dispose (GObject *object)
{
    EBookView             *book_view = E_BOOK_VIEW (object);
    CORBA_Environment  ev;

    if (book_view->priv) {
        if (book_view->priv->book) {
            g_object_unref (book_view->priv->book);
        }

        if (book_view->priv->corba_book_view) {
            CORBA_exception_init (&ev);

            bonobo_object_release_unref (book_view->priv->corba_book_view, &ev);

            if (ev._major != CORBA_NO_EXCEPTION) {
                g_warning ("EBookView: Exception while releasing BookView\n");
            }

            CORBA_exception_free (&ev);
        }

        if (book_view->priv->listener) {
            if (book_view->priv->responses_queued_id)
                g_signal_handler_disconnect(book_view->priv->listener,
                                book_view->priv->responses_queued_id);
            e_book_view_listener_stop (book_view->priv->listener);
            bonobo_object_unref (BONOBO_OBJECT(book_view->priv->listener));
        }

        g_free (book_view->priv);
        book_view->priv = NULL;
    }

    G_OBJECT_CLASS(parent_class)->dispose (object);
}

static void
e_book_view_class_init (EBookViewClass *klass)
{
    GObjectClass *object_class = G_OBJECT_CLASS (klass);

    parent_class = g_type_class_ref (G_TYPE_OBJECT);

    e_book_view_signals [CARD_CHANGED] =
        g_signal_new ("card_changed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (EBookViewClass, card_changed),
                  NULL, NULL,
                  e_book_marshal_NONE__POINTER,
                  G_TYPE_NONE, 1,
                  G_TYPE_POINTER);

    e_book_view_signals [CARD_ADDED] =
        g_signal_new ("card_added",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (EBookViewClass, card_added),
                  NULL, NULL,
                  e_book_marshal_NONE__STRING,
                  G_TYPE_NONE, 1,
                  G_TYPE_STRING);

    e_book_view_signals [CARD_REMOVED] =
        g_signal_new ("card_removed",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (EBookViewClass, card_removed),
                  NULL, NULL,
                  e_book_marshal_NONE__POINTER,
                  G_TYPE_NONE, 1,
                  G_TYPE_POINTER);

    e_book_view_signals [SEQUENCE_COMPLETE] =
        g_signal_new ("sequence_complete",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (EBookViewClass, sequence_complete),
                  NULL, NULL,
                  e_book_marshal_NONE__INT,
                  G_TYPE_NONE, 1,
                  G_TYPE_INT);

    e_book_view_signals [STATUS_MESSAGE] =
        g_signal_new ("status_message",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (EBookViewClass, status_message),
                  NULL, NULL,
                  e_book_marshal_NONE__STRING,
                  G_TYPE_NONE, 1,
                  G_TYPE_STRING);

    object_class->dispose = e_book_view_dispose;
}

/**
 * e_book_view_get_type:
 */
GType
e_book_view_get_type (void)
{
    static GType type = 0;

    if (! type) {
        GTypeInfo info = {
            sizeof (EBookViewClass),
            NULL, /* base_class_init */
            NULL, /* base_class_finalize */
            (GClassInitFunc)  e_book_view_class_init,
            NULL, /* class_finalize */
            NULL, /* class_data */
            sizeof (EBookView),
            0,    /* n_preallocs */
            (GInstanceInitFunc) e_book_view_init
        };

        type = g_type_register_static (G_TYPE_OBJECT, "EBookView", &info, 0);
    }

    return type;
}