aboutsummaryrefslogblamecommitdiffstats
path: root/addressbook/gui/contact-editor/e-contact-editor.c
blob: 01091b4bc392b9ace5864138023e98784b339711 (plain) (tree)



























                                                                                    
                                                         
 





                                                                                                                                                          















                                                                            





                            


















                                                       
                                                                                         








                                                        
                           

                                         
                                      
 
                                                       


















                                                                                                      
                                                   

 

                                                                                   
 









                                                                                   
                               

 

                            
 




                                                                           

 

                                    
 



                                                                              

 

                                                                                            
 








                                                                                   

 

                                        
 





                                                                                        




                                                        

                                  

                                             





























































                                                                                                  
 
                                                            











































                                                                                     







                                             
                               




                                                     



                                                            


































































































































































































































































                                                                                                                                                                                       
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* 
 * e-contact-editor.c
 * Copyright (C) 2000  Helix Code, Inc.
 * Author: Chris Lahey <clahey@helixcode.com>
 *
 * This library 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 library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <gnome.h>
#include "e-contact-editor.h"
static void e_contact_editor_init       (EContactEditor      *card);
static void e_contact_editor_class_init (EContactEditorClass     *klass);
static void e_contact_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
static void e_contact_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
static void e_contact_editor_destroy (GtkObject *object);

static GtkWidget *e_contact_editor_build_dialog(EContactEditor *editor, gchar *entry_id, gchar *label_id, gchar *title, GList **list, GnomeUIInfo **info);
static void _email_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor);
static void _phone_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor);
static void _address_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor);

static GtkVBoxClass *parent_class = NULL;

#if 0
enum {
    E_CONTACT_EDITOR_RESIZE,
    E_CONTACT_EDITOR_LAST_SIGNAL
};

static guint e_contact_editor_signals[E_CONTACT_EDITOR_LAST_SIGNAL] = { 0 };
#endif

/* The arguments we take */
enum {
    ARG_0,
    ARG_CARD
};

enum {
    DYNAMIC_LIST_EMAIL,
    DYNAMIC_LIST_PHONE,
    DYNAMIC_LIST_ADDRESS
};

GtkType
e_contact_editor_get_type (void)
{
  static GtkType contact_editor_type = 0;

  if (!contact_editor_type)
    {
      static const GtkTypeInfo contact_editor_info =
      {
        "EContactEditor",
        sizeof (EContactEditor),
        sizeof (EContactEditorClass),
        (GtkClassInitFunc) e_contact_editor_class_init,
        (GtkObjectInitFunc) e_contact_editor_init,
        /* reserved_1 */ NULL,
        /* reserved_2 */ NULL,
        (GtkClassInitFunc) NULL,
      };

      contact_editor_type = gtk_type_unique (gtk_vbox_get_type (), &contact_editor_info);
    }

  return contact_editor_type;
}

static void
e_contact_editor_class_init (EContactEditorClass *klass)
{
  GtkObjectClass *object_class;
  GtkVBoxClass *vbox_class;

  object_class = (GtkObjectClass*) klass;
  vbox_class = (GtkVBoxClass *) klass;

  parent_class = gtk_type_class (gtk_vbox_get_type ());

#if 0  
  e_contact_editor_signals[E_CONTACT_EDITOR_RESIZE] =
      gtk_signal_new ("resize",
              GTK_RUN_LAST,
              object_class->type,
              GTK_SIGNAL_OFFSET (EContactEditorClass, resize),
              gtk_marshal_NONE__NONE,
              GTK_TYPE_NONE, 0);
  
  
  gtk_object_class_add_signals (object_class, e_contact_editor_signals, E_CONTACT_EDITOR_LAST_SIGNAL);
#endif
  
  gtk_object_add_arg_type ("EContactEditor::card", GTK_TYPE_OBJECT, 
               GTK_ARG_READWRITE, ARG_CARD);
 
  object_class->set_arg = e_contact_editor_set_arg;
  object_class->get_arg = e_contact_editor_get_arg;
  object_class->destroy = e_contact_editor_destroy;
}

static void
_add_image(GtkTable *table, gchar *image, int left, int right, int top, int bottom)
{
    gtk_table_attach(table,
             gtk_widget_new(gtk_alignment_get_type(),
                    "child", gnome_pixmap_new_from_file(image),
                    "xalign", (double) 0,
                    "yalign", (double) 0,
                    "xscale", (double) 0,
                    "yscale", (double) 0,
                    NULL),
             left, right, top, bottom,
             GTK_FILL, GTK_FILL,
             0, 0);
}

static void
_add_images(GtkTable *table)
{
    _add_image(table, DATADIR "/evolution/head.png", 0, 1, 0, 4);
    _add_image(table, DATADIR "/evolution/phone.png", 4, 5, 0, 4);
    _add_image(table, DATADIR "/evolution/email.png", 0, 1, 5, 7);
    _add_image(table, DATADIR "/evolution/web.png", 0, 1, 8, 10);
    _add_image(table, DATADIR "/evolution/snailmail.png", 4, 5, 5, 10);
}

static void
_add_details_images(GtkTable *table)
{
    _add_image(table, DATADIR "/evolution/briefcase.png", 0, 1, 0, 2);
    _add_image(table, DATADIR "/evolution/head.png", 0, 1, 4, 6);
    _add_image(table, DATADIR "/evolution/netmeeting.png", 0, 1, 7, 9);
    _add_image(table, DATADIR "/evolution/netfreebusy.png", 0, 1, 10, 12);
}

static void
_replace_button(EContactEditor *editor, gchar *button_xml, gchar *image, GtkSignalFunc func)
{
    GladeXML *gui = editor->gui;
    GtkWidget *button = glade_xml_get_widget(gui, button_xml);
    gchar *image_temp;
    image_temp = g_strdup_printf("%s%s", DATADIR "/evolution/", image);
    gtk_container_add(GTK_CONTAINER(button),
              gnome_pixmap_new_from_file(image_temp));
    g_free(image_temp);
    gtk_signal_connect(GTK_OBJECT(button), "button_press_event", func, editor);
               
}

static void
_replace_buttons(EContactEditor *editor)
{
    _replace_button(editor, "button-phone1", "arrow.png", _phone_arrow_pressed);
    _replace_button(editor, "button-phone2", "arrow.png", _phone_arrow_pressed);
    _replace_button(editor, "button-phone3", "arrow.png", _phone_arrow_pressed);
    _replace_button(editor, "button-phone4", "arrow.png", _phone_arrow_pressed);
    _replace_button(editor, "button-address1", "arrow.png", _address_arrow_pressed);
    _replace_button(editor, "button-email1", "arrow.png", _email_arrow_pressed);
}

static void
e_contact_editor_init (EContactEditor *e_contact_editor)
{
    GladeXML *gui;
    GtkAdjustment *adjustment;

    /*   e_contact_editor->card = NULL;*/
    gui = glade_xml_new (EVOLUTION_GLADEDIR "/contact-editor.glade", NULL);
    e_contact_editor->gui = gui;
    gtk_widget_reparent(glade_xml_get_widget(gui, "notebook-contact-editor"),
                GTK_WIDGET(e_contact_editor));

    _add_images(GTK_TABLE(glade_xml_get_widget(gui, "table-contact-editor-general")));
    _add_details_images(GTK_TABLE(glade_xml_get_widget(gui, "table-contact-editor-details")));
    _replace_buttons(e_contact_editor);

    gtk_object_get(GTK_OBJECT(glade_xml_get_widget(gui, "text-comments")),
               "vadjustment", &adjustment,
               NULL);
    gtk_range_set_adjustment(GTK_RANGE(glade_xml_get_widget(gui, "vscrollbar-comments")),
                 adjustment);
    
    e_contact_editor->email_info = NULL;
    e_contact_editor->phone_info = NULL;
    e_contact_editor->address_info = NULL;
    e_contact_editor->email_popup = NULL;
    e_contact_editor->phone_popup = NULL;
    e_contact_editor->address_popup = NULL;
    e_contact_editor->email_list = NULL;
    e_contact_editor->phone_list = NULL;
    e_contact_editor->address_list = NULL;
}

void
e_contact_editor_destroy (GtkObject *object) {
    EContactEditor *e_contact_editor = E_CONTACT_EDITOR(object);
    
    if (e_contact_editor->email_list) {
        g_list_foreach(e_contact_editor->email_list, (GFunc) g_free, NULL);
        g_list_free(e_contact_editor->email_list);
    }
    if (e_contact_editor->email_info) {
        g_free(e_contact_editor->email_info);
    }
    if (e_contact_editor->email_popup) {
        gtk_widget_unref(e_contact_editor->email_popup);
    }
    
    if (e_contact_editor->phone_list) {
        g_list_foreach(e_contact_editor->phone_list, (GFunc) g_free, NULL);
        g_list_free(e_contact_editor->phone_list);
    }
    if (e_contact_editor->phone_info) {
        g_free(e_contact_editor->phone_info);
    }
    if (e_contact_editor->phone_popup) {
        gtk_widget_unref(e_contact_editor->phone_popup);
    }
    
    if (e_contact_editor->address_list) {
        g_list_foreach(e_contact_editor->address_list, (GFunc) g_free, NULL);
        g_list_free(e_contact_editor->address_list);
    }
    if (e_contact_editor->address_info) {
        g_free(e_contact_editor->address_info);
    }
    if (e_contact_editor->address_popup) {
        gtk_widget_unref(e_contact_editor->address_popup);
    }

    gtk_object_unref(GTK_OBJECT(e_contact_editor->gui));
}

GtkWidget*
e_contact_editor_new (void *card)
{
    GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_contact_editor_get_type ()));
    gtk_object_set (GTK_OBJECT(widget),
            "card", card,
            NULL);
    return widget;
}

static void
e_contact_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
{
    EContactEditor *e_contact_editor;

    e_contact_editor = E_CONTACT_EDITOR (o);
    
    switch (arg_id){
    case ARG_CARD:
      /*      e_contact_editor->card = GTK_VALUE_POINTER (*arg);
      _update_card(e_contact_editor);
      gnome_canvas_item_request_update (item);*/
      break;
    }
}

static void
e_contact_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
    EContactEditor *e_contact_editor;

    e_contact_editor = E_CONTACT_EDITOR (object);

    switch (arg_id) {
    case ARG_CARD:
      /* GTK_VALUE_POINTER (*arg) = e_contact_editor->card; */
      break;
    default:
      arg->type = GTK_TYPE_INVALID;
      break;
    }
}

static void
_popup_position(GtkMenu *menu,
        gint *x,
        gint *y,
        gpointer data)
{
    GtkWidget *button = GTK_WIDGET(data);
    GtkRequisition request;
    int mh, mw;
    gdk_window_get_origin (button->window, x, y);
    *x += button->allocation.width;
    *y += button->allocation.height;

    gtk_widget_size_request(GTK_WIDGET(menu), &request);

    mh = request.height;
    mw = request.width;

    *x -= mw;
    if (*x < 0)
        *x = 0;
    
    if (*y < 0)
        *y = 0;
    
    if ((*x + mw) > gdk_screen_width ())
        *x = gdk_screen_width () - mw;
    
    if ((*y + mh) > gdk_screen_height ())
        *y = gdk_screen_height () - mh;
}

static void
_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor, GtkWidget *popup, GList **list, GnomeUIInfo **info, gchar *label, gchar *entry, gchar *dialog_title)
{
    gint menu_item;
    gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "button_press_event");
    gtk_widget_realize(popup);
    menu_item = gnome_popup_menu_do_popup_modal(popup, _popup_position, widget, button, editor);
    if ( menu_item != -1 ) {
        if (menu_item == g_list_length (*list)) {
            e_contact_editor_build_dialog(editor, entry, label, dialog_title, list, info);
        } else {
            gtk_object_set(GTK_OBJECT(glade_xml_get_widget(editor->gui, label)),
                       "label", g_list_nth_data(*list, menu_item),
                       NULL);
        }
    }
}

static void
e_contact_editor_build_ui_info(GList *list, GnomeUIInfo **infop)
{
    GnomeUIInfo *info;
    GnomeUIInfo singleton = { GNOME_APP_UI_ITEM, NULL, NULL, NULL, NULL, NULL, GNOME_APP_PIXMAP_NONE, 0, 0, 0, NULL };
    GnomeUIInfo end = GNOMEUIINFO_END;
    int length;
    int i;

    info = *infop;

    if ( info )
        g_free(info);
    length = g_list_length( list );
    info = g_new(GnomeUIInfo, length + 2);
    for (i = 0; i < length; i++) {
        info[i] = singleton;
        info[i].label = _(list->data);
        list = list->next;
    }
    info[i] = singleton;
    info[i].label = N_("Other...");
    i++;
    info[i] = end;

    *infop = info;
}

static void
_dialog_clicked(GtkWidget *dialog, gint button, EContactEditor *editor)
{
    GtkWidget *label = gtk_object_get_data(GTK_OBJECT(dialog),
                           "e_contact_editor_label");
    GtkWidget *entry = gtk_object_get_data(GTK_OBJECT(dialog),
                           "e_contact_editor_entry");
    GtkWidget *dialog_entry = gtk_object_get_data(GTK_OBJECT(dialog),
                              "e_contact_editor_dialog_entry");
    GList **list = gtk_object_get_data(GTK_OBJECT(dialog),
                       "e_contact_editor_list");
    GList **info = gtk_object_get_data(GTK_OBJECT(dialog),
                       "e_contact_editor_info");
    switch (button) {
    case 0:
        gtk_object_set(GTK_OBJECT(label),
                   "label", gtk_entry_get_text(GTK_ENTRY(dialog_entry)),
                   NULL);
        *list = g_list_append(*list, g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog_entry))));
        g_free(*info);
        *info = NULL;
        break;
    }
    gnome_dialog_close(GNOME_DIALOG(dialog));
}

static void
_dialog_destroy(EContactEditor *editor, GtkWidget *dialog)
{
    gnome_dialog_close(GNOME_DIALOG(dialog));
}

static GtkWidget *
e_contact_editor_build_dialog(EContactEditor *editor, gchar *entry_id, gchar *label_id, gchar *title, GList **list, GnomeUIInfo **info)
{
    GtkWidget *dialog_entry = gtk_entry_new();
    GtkWidget *entry = glade_xml_get_widget(editor->gui, entry_id);
    GtkWidget *label = glade_xml_get_widget(editor->gui, label_id);
    
    GtkWidget *dialog = gnome_dialog_new(title,
                         NULL);

    gtk_container_add(GTK_CONTAINER(GNOME_DIALOG(dialog)->vbox),
              gtk_widget_new (gtk_frame_get_type(),
                      "border_width", 4,
                      "label", title,
                      "child", gtk_widget_new(gtk_alignment_get_type(),
                                  "child", dialog_entry,
                                  "xalign", .5,
                                  "yalign", .5,
                                  "xscale", 1.0,
                                  "yscale", 1.0,
                                  "border_width", 9,
                                  NULL),
                      NULL));

    gnome_dialog_append_button_with_pixmap(GNOME_DIALOG(dialog),
                           "Add",
                           GNOME_STOCK_PIXMAP_ADD);
    gnome_dialog_append_button(GNOME_DIALOG(dialog), GNOME_STOCK_BUTTON_CANCEL);
    gnome_dialog_set_default(GNOME_DIALOG(dialog), 0);
    
    gtk_signal_connect(GTK_OBJECT(dialog), "clicked",
               _dialog_clicked, editor);
    gtk_signal_connect_while_alive(GTK_OBJECT(editor), "destroy",
                       _dialog_destroy, GTK_OBJECT(dialog), GTK_OBJECT(dialog));
    
    gtk_object_set_data(GTK_OBJECT(dialog),
                "e_contact_editor_entry", entry);
    gtk_object_set_data(GTK_OBJECT(dialog),
                "e_contact_editor_label", label);
    gtk_object_set_data(GTK_OBJECT(dialog),
                "e_contact_editor_dialog_entry", dialog_entry);
    gtk_object_set_data(GTK_OBJECT(dialog),
                "e_contact_editor_list", list);
    gtk_object_set_data(GTK_OBJECT(dialog),
                "e_contact_editor_info", info);

    gtk_widget_show_all(dialog);
    return dialog;
}

static void
_phone_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor)
{
    int which;
    int i;
    gchar *label;
    gchar *entry;
    if ( widget == glade_xml_get_widget(editor->gui, "button-phone1") ) {
        which = 1;
    } else if ( widget == glade_xml_get_widget(editor->gui, "button-phone2") ) {
        which = 2;
    } else if ( widget == glade_xml_get_widget(editor->gui, "button-phone3") ) {
        which = 3;
    } else if ( widget == glade_xml_get_widget(editor->gui, "button-phone4") ) {
        which = 4;
    } else
        return;
    
    label = g_strdup_printf("label-phone%d", which);
    entry = g_strdup_printf("entry-phone%d", which);

    if (editor->phone_list == NULL) {
        static char *info[] = {
            N_("Assistant"),
            N_("Business"),
            N_("Business 2"),
            N_("Business Fax"),
            N_("Callback"),
            N_("Car"),
            N_("Company"),
            N_("Home"),
            N_("Home 2"),
            N_("Home Fax"),
            N_("ISDN"),
            N_("Mobile"),
            N_("Other"),
            N_("Other Fax"),
            N_("Pager"),
            N_("Primary"),
            N_("Radio"),
            N_("Telex"),
            N_("TTY/TDD")
        };
        
        for (i = 0; i < sizeof(info) / sizeof(info[0]); i++) {
            editor->phone_list = g_list_append(editor->phone_list, g_strdup(info[i]));
        }
    }
    if (editor->phone_info == NULL) {
        e_contact_editor_build_ui_info(editor->phone_list, &editor->phone_info);
        
        if ( editor->phone_popup )
            gtk_widget_unref(editor->phone_popup);
        
        editor->phone_popup = gnome_popup_menu_new(editor->phone_info);
    }
    
    _arrow_pressed (widget, button, editor, editor->phone_popup, &editor->phone_list, &editor->phone_info, label, entry, "Add new phone number type");

    g_free(label);
    g_free(entry);
}

static void
_email_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor)
{
    int i;
    if (editor->email_list == NULL) {
        static char *info[] = {
            N_("Email"),
            N_("Email 2"),
            N_("Email 3")
        };
        
        for (i = 0; i < sizeof(info) / sizeof(info[0]); i++) {
            editor->email_list = g_list_append(editor->email_list, g_strdup(info[i]));
        }
    }
    if (editor->email_info == NULL) {
        e_contact_editor_build_ui_info(editor->email_list, &editor->email_info);

        if ( editor->email_popup )
            gtk_widget_unref(editor->email_popup);
        
        editor->email_popup = gnome_popup_menu_new(editor->email_info);
    }
    
    _arrow_pressed (widget, button, editor, editor->email_popup, &editor->email_list, &editor->email_info, "label-email1", "entry-email1", "Add new Email type");
}

static void
_address_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor)
{
    int i;
    if (editor->address_list == NULL) {
        static char *info[] = {
            N_("Business"),
            N_("Home"),
            N_("Other")
        };
        
        for (i = 0; i < sizeof(info) / sizeof(info[0]); i++) {
            editor->address_list = g_list_append(editor->address_list, g_strdup(info[i]));
        }
    }
    if (editor->address_info == NULL) {
        e_contact_editor_build_ui_info(editor->address_list, &editor->address_info);

        if ( editor->address_popup )
            gtk_widget_unref(editor->address_popup);
        
        editor->address_popup = gnome_popup_menu_new(editor->address_info);
    }
    
    _arrow_pressed (widget, button, editor, editor->address_popup, &editor->address_list, &editor->address_info, "label-address1", "entry-address1", "Add new Address type");
}