/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* eab-editor.c
* Copyright (C) 2004 Novell, Inc.
* Author: Chris Toshok <toshok@ximian.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* 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 <gtk/gtkstock.h>
#include <gtk/gtkmessagedialog.h>
#include <libgnome/gnome-i18n.h>
#include "eab-editor.h"
#include "addressbook/gui/widgets/eab-gui-util.h"
#include "e-contact-editor-marshal.h"
static void eab_editor_default_show (EABEditor *editor);
static void eab_editor_default_raise (EABEditor *editor);
static void eab_editor_default_close (EABEditor *editor);
static void eab_editor_class_init (EABEditorClass *klass);
static void eab_editor_init (EABEditor *editor);
/* Signal IDs */
enum {
CONTACT_ADDED,
CONTACT_MODIFIED,
CONTACT_DELETED,
EDITOR_CLOSED,
LAST_SIGNAL
};
static GSList *all_editors = NULL;
static GtkObjectClass *parent_class = NULL;
static guint editor_signals[LAST_SIGNAL];
GType
eab_editor_get_type (void)
{
static GType editor_type = 0;
if (!editor_type) {
static const GTypeInfo editor_info = {
sizeof (EABEditorClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) eab_editor_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (EABEditor),
0, /* n_preallocs */
(GInstanceInitFunc) eab_editor_init,
};
editor_type = g_type_register_static (G_TYPE_OBJECT, "EABEditor", &editor_info, 0);
}
return editor_type;
}
static void
eab_editor_default_show (EABEditor *editor)
{
g_warning ("abstract eab_editor_show called");
}
static void
eab_editor_default_close (EABEditor *editor)
{
g_warning ("abstract eab_editor_close called");
}
static void
eab_editor_default_raise (EABEditor *editor)
{
g_warning ("abstract eab_editor_raise called");
}
static void
eab_editor_default_save_contact (EABEditor *editor, gboolean should_close)
{
g_warning ("abstract eab_editor_save_contact called");
}
static gboolean
eab_editor_default_is_valid (EABEditor *editor)
{
g_warning ("abstract eab_editor_is_valid called");
return FALSE;
}
static gboolean
eab_editor_default_is_changed (EABEditor *editor)
{
g_warning ("abstract eab_editor_is_changed called");
return FALSE;
}
static GtkWindow*
eab_editor_default_get_window (EABEditor *editor)
{
g_warning ("abstract eab_editor_get_window called");
return NULL;
}
static void
eab_editor_class_init (EABEditorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_ref (G_TYPE_OBJECT);
klass->show = eab_editor_default_show;
klass->close = eab_editor_default_close;
klass->raise = eab_editor_default_raise;
klass->save_contact = eab_editor_default_save_contact;
klass->is_valid = eab_editor_default_is_valid;
klass->is_changed = eab_editor_default_is_changed;
klass->get_window = eab_editor_default_get_window;
editor_signals[CONTACT_ADDED] =
g_signal_new ("contact_added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (EABEditorClass, contact_added),
NULL, NULL,
e_contact_editor_marshal_NONE__INT_OBJECT,
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
editor_signals[CONTACT_MODIFIED] =
g_signal_new ("contact_modified",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (EABEditorClass, contact_modified),
NULL, NULL,
e_contact_editor_marshal_NONE__INT_OBJECT,
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
editor_signals[CONTACT_DELETED] =
g_signal_new ("contact_deleted",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (EABEditorClass, contact_deleted),
NULL, NULL,
e_contact_editor_marshal_NONE__INT_OBJECT,
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
editor_signals[EDITOR_CLOSED] =
g_signal_new ("editor_closed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (EABEditorClass, editor_closed),
NULL, NULL,
e_contact_editor_marshal_NONE__NONE,
G_TYPE_NONE, 0);
}
static void
eab_editor_init (EABEditor *editor)
{
}
void
eab_editor_show (EABEditor *editor)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
if (EAB_EDITOR_GET_CLASS(editor)->show)
EAB_EDITOR_GET_CLASS(editor)->show (editor);
}
void
eab_editor_close (EABEditor *editor)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
if (EAB_EDITOR_GET_CLASS(editor)->close)
EAB_EDITOR_GET_CLASS(editor)->close (editor);
}
void
eab_editor_raise (EABEditor *editor)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
if (EAB_EDITOR_GET_CLASS(editor)->raise)
EAB_EDITOR_GET_CLASS(editor)->raise (editor);
}
void
eab_editor_save_contact (EABEditor *editor, gboolean should_close)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
if (EAB_EDITOR_GET_CLASS(editor)->save_contact)
EAB_EDITOR_GET_CLASS(editor)->save_contact (editor, should_close);
}
gboolean
eab_editor_is_changed (EABEditor *editor)
{
g_return_val_if_fail (EAB_IS_EDITOR (editor), FALSE);
if (EAB_EDITOR_GET_CLASS(editor)->is_changed)
return EAB_EDITOR_GET_CLASS(editor)->is_changed (editor);
else
return FALSE;
}
gboolean
eab_editor_is_valid (EABEditor *editor)
{
g_return_val_if_fail (EAB_IS_EDITOR (editor), FALSE);
if (EAB_EDITOR_GET_CLASS(editor)->is_valid)
return EAB_EDITOR_GET_CLASS(editor)->is_valid (editor);
else
return FALSE;
}
GtkWindow*
eab_editor_get_window (EABEditor *editor)
{
g_return_val_if_fail (EAB_IS_EDITOR (editor), NULL);
if (EAB_EDITOR_GET_CLASS(editor)->get_window)
return EAB_EDITOR_GET_CLASS(editor)->get_window (editor);
else
return NULL;
}
gboolean
eab_editor_prompt_to_save_changes (EABEditor *editor, GtkWindow *window)
{
if (!eab_editor_is_changed (editor))
return TRUE;
switch (eab_prompt_save_dialog (window)) {
case GTK_RESPONSE_YES:
if (!eab_editor_is_valid (editor)) {
/* XXX pop up dialog about things being invalid */
return FALSE;
}
eab_editor_save_contact (editor, FALSE);
return TRUE;
case GTK_RESPONSE_NO:
return TRUE;
case GTK_RESPONSE_CANCEL:
default:
return FALSE;
}
}
gboolean
eab_editor_request_close_all (void)
{
GSList *p;
GSList *pnext;
gboolean retval;
retval = TRUE;
for (p = all_editors; p != NULL; p = pnext) {
EABEditor *editor = EAB_EDITOR (p->data);
GtkWindow *window = eab_editor_get_window (editor);
pnext = p->next;
eab_editor_raise (editor);
if (! eab_editor_prompt_to_save_changes (editor, window)) {
retval = FALSE;
break;
}
eab_editor_close (editor);
}
return retval;
}
const GSList*
eab_editor_get_all_editors (void)
{
return all_editors;
}
gboolean
eab_editor_confirm_delete (GtkWindow *parent)
{
GtkWidget *dialog;
gint result;
dialog = gtk_message_dialog_new (parent,
0,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
#if notyet
/* XXX we really need to handle the plural case here.. */
(plural
? _("Are you sure you want\n"
"to delete these contacts?"))
#endif
_("Are you sure you want\n"
"to delete this contact?"));
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT,
NULL);
result = gtk_dialog_run(GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
return (result == GTK_RESPONSE_ACCEPT);
}
void
eab_editor_contact_added (EABEditor *editor, EBookStatus status, EContact *contact)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
g_return_if_fail (E_IS_CONTACT (contact));
g_signal_emit (editor, editor_signals[CONTACT_ADDED], 0,
status, contact);
}
void
eab_editor_contact_modified (EABEditor *editor, EBookStatus status, EContact *contact)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
g_return_if_fail (E_IS_CONTACT (contact));
g_signal_emit (editor, editor_signals[CONTACT_MODIFIED], 0,
status, contact);
}
void
eab_editor_contact_deleted (EABEditor *editor, EBookStatus status, EContact *contact)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
g_return_if_fail (E_IS_CONTACT (contact));
g_signal_emit (editor, editor_signals[CONTACT_DELETED], 0,
status, contact);
}
void
eab_editor_closed (EABEditor *editor)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
g_signal_emit (editor, editor_signals[EDITOR_CLOSED], 0);
}
void
eab_editor_add (EABEditor *editor)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
all_editors = g_slist_prepend (all_editors, editor);
}
void
eab_editor_remove (EABEditor *editor)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
all_editors = g_slist_remove (all_editors, editor);
}