aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui')
-rw-r--r--calendar/gui/calendar-component.c97
-rw-r--r--calendar/gui/dialogs/comp-editor-page.h1
-rw-r--r--calendar/gui/dialogs/comp-editor.h1
-rw-r--r--calendar/gui/dialogs/memo-editor.c14
-rw-r--r--calendar/gui/dialogs/memo-editor.h2
-rw-r--r--calendar/gui/dialogs/memo-page.c450
-rw-r--r--calendar/gui/dialogs/memo-page.glade235
-rw-r--r--calendar/gui/dialogs/memo-page.h2
-rw-r--r--calendar/gui/e-cal-component-memo-preview.c57
-rw-r--r--calendar/gui/e-cal-model.c5
-rw-r--r--calendar/gui/e-memo-table-config.c11
-rw-r--r--calendar/gui/e-memo-table.c91
-rw-r--r--calendar/gui/e-memo-table.etspec8
-rw-r--r--calendar/gui/e-memo-table.h3
-rw-r--r--calendar/gui/gnome-cal.c270
-rw-r--r--calendar/gui/gnome-cal.h3
-rw-r--r--calendar/gui/memos-component.c42
17 files changed, 1220 insertions, 72 deletions
diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c
index 2cc987e31d..c125b0a241 100644
--- a/calendar/gui/calendar-component.c
+++ b/calendar/gui/calendar-component.c
@@ -86,9 +86,11 @@ typedef struct
{
ESourceList *source_list;
ESourceList *task_source_list;
+ ESourceList *memo_source_list;
GSList *source_selection;
GSList *task_source_selection;
+ GSList *memo_source_selection;
GnomeCalendar *calendar;
@@ -117,6 +119,7 @@ struct _CalendarComponentPrivate {
ESourceList *source_list;
ESourceList *task_source_list;
+ ESourceList *memo_source_list;
GList *views;
@@ -406,39 +409,52 @@ update_selection (CalendarComponentView *component_view)
}
static void
-update_task_selection (CalendarComponentView *component_view)
+update_task_memo_selection (CalendarComponentView *component_view, ECalSourceType type)
{
- GSList *uids_selected, *l;
-
- /* Get the selection in gconf */
- uids_selected = calendar_config_get_tasks_selected ();
+ GSList *uids_selected, *l, *source_selection;
+ ESourceList *source_list = NULL;
+
+ if (type == E_CAL_SOURCE_TYPE_TODO) {
+ /* Get the selection in gconf */
+ uids_selected = calendar_config_get_tasks_selected ();
+ source_list = component_view->task_source_list;
+ source_selection = component_view->task_source_selection;
+
+ } else {
+ uids_selected = calendar_config_get_memos_selected ();
+ source_list = component_view->memo_source_list;
+ source_selection = component_view->memo_source_selection;
+ }
/* Remove any that aren't there any more */
- for (l = component_view->task_source_selection; l; l = l->next) {
+ for (l = source_selection; l; l = l->next) {
char *uid = l->data;
ESource *source;
- source = e_source_list_peek_source_by_uid (component_view->task_source_list, uid);
+ source = e_source_list_peek_source_by_uid (component_view->source_list, uid);
if (!source)
- gnome_calendar_remove_source_by_uid (component_view->calendar, E_CAL_SOURCE_TYPE_TODO, uid);
+ gnome_calendar_remove_source_by_uid (component_view->calendar, type, uid);
else if (!is_in_uids (uids_selected, source))
- gnome_calendar_remove_source (component_view->calendar, E_CAL_SOURCE_TYPE_TODO, source);
+ gnome_calendar_remove_source (component_view->calendar, type, source);
g_free (uid);
}
- g_slist_free (component_view->task_source_selection);
+ g_slist_free (source_selection);
/* Make sure the whole selection is there */
for (l = uids_selected; l; l = l->next) {
char *uid = l->data;
ESource *source;
- source = e_source_list_peek_source_by_uid (component_view->task_source_list, uid);
- if (source && !gnome_calendar_add_source (component_view->calendar, E_CAL_SOURCE_TYPE_TODO, source))
+ source = e_source_list_peek_source_by_uid (source_list, uid);
+ if (source && !gnome_calendar_add_source (component_view->calendar, type, source))
/* FIXME do something */;
}
- component_view->task_source_selection = uids_selected;
+ if (type == E_CAL_SOURCE_TYPE_TODO)
+ component_view->task_source_selection = uids_selected;
+ else
+ component_view->memo_source_selection = uids_selected;
}
static void
@@ -464,20 +480,28 @@ update_primary_selection (CalendarComponentView *component_view)
}
static void
-update_primary_task_selection (CalendarComponentView *component_view)
+update_primary_task_memo_selection (CalendarComponentView *component_view, ECalSourceType type)
{
ESource *source = NULL;
char *uid;
+ ESourceList *source_list = NULL;
+
+ if (type == E_CAL_SOURCE_TYPE_TODO) {
+ uid = calendar_config_get_primary_tasks ();
+ source_list = component_view->task_source_list;
+ } else {
+ uid = calendar_config_get_primary_memos ();
+ source_list = component_view->memo_source_list;
+ }
- uid = calendar_config_get_primary_tasks ();
if (uid) {
- source = e_source_list_peek_source_by_uid (component_view->task_source_list, uid);
+ source = e_source_list_peek_source_by_uid (source_list, uid);
g_free (uid);
}
if (source)
- gnome_calendar_set_default_source (component_view->calendar, E_CAL_SOURCE_TYPE_TODO, source);
+ gnome_calendar_set_default_source (component_view->calendar, type, source);
}
/* Callbacks. */
@@ -748,14 +772,27 @@ config_primary_selection_changed_cb (GConfClient *client, guint id, GConfEntry *
static void
config_tasks_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
{
- update_task_selection (data);
+ update_task_memo_selection (data, E_CAL_SOURCE_TYPE_TODO);
}
static void
config_primary_tasks_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
{
- update_primary_task_selection (data);
+ update_primary_task_memo_selection (data, E_CAL_SOURCE_TYPE_TODO);
+}
+
+static void
+config_memos_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+ update_task_memo_selection (data, E_CAL_SOURCE_TYPE_JOURNAL);
+}
+
+
+static void
+config_primary_memos_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
+{
+ update_primary_task_memo_selection (data, E_CAL_SOURCE_TYPE_JOURNAL);
}
/* Evolution::Component CORBA methods. */
@@ -1285,6 +1322,7 @@ create_component_view (CalendarComponent *calendar_component)
/* Add the source lists */
component_view->source_list = g_object_ref (priv->source_list);
component_view->task_source_list = g_object_ref (priv->task_source_list);
+ component_view->memo_source_list = g_object_ref (priv->memo_source_list);
component_view->vpane_pos = calendar_config_get_tag_vpane_pos ();
/* Create sidebar selector */
@@ -1377,18 +1415,28 @@ create_component_view (CalendarComponent *calendar_component)
/* Load the selection from the last run */
update_selection (component_view);
update_primary_selection (component_view);
- update_task_selection (component_view);
- update_primary_task_selection (component_view);
+ update_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_TODO);
+ update_primary_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_TODO);
+ update_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_JOURNAL);
+ update_primary_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_JOURNAL);
- /* If the tasks selection changes elsewhere, update it for the mini
+ /* If the tasks/memos selection changes elsewhere, update it for the mini
mini tasks view sidebar */
not = calendar_config_add_notification_tasks_selected (config_tasks_selection_changed_cb,
component_view);
component_view->notifications = g_list_prepend (component_view->notifications, GUINT_TO_POINTER (not));
+ not = calendar_config_add_notification_memos_selected (config_memos_selection_changed_cb,
+ component_view);
+ component_view->notifications = g_list_prepend (component_view->notifications, GUINT_TO_POINTER (not));
+
not = calendar_config_add_notification_primary_tasks (config_primary_tasks_selection_changed_cb,
component_view);
component_view->notifications = g_list_prepend (component_view->notifications, GUINT_TO_POINTER (not));
+
+ not = calendar_config_add_notification_primary_memos (config_primary_memos_selection_changed_cb,
+ component_view);
+ component_view->notifications = g_list_prepend (component_view->notifications, GUINT_TO_POINTER (not));
return component_view;
}
@@ -1403,6 +1451,9 @@ destroy_component_view (CalendarComponentView *component_view)
if (component_view->task_source_list)
g_object_unref (component_view->task_source_list);
+
+ if (component_view->memo_source_list)
+ g_object_unref (component_view->memo_source_list);
if (component_view->source_selection)
e_source_selector_free_selection (component_view->source_selection);
@@ -1648,6 +1699,8 @@ calendar_component_init (CalendarComponent *component)
if (!e_cal_get_sources (&priv->task_source_list, E_CAL_SOURCE_TYPE_TODO, NULL))
;
+ if (!e_cal_get_sources (&priv->memo_source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL))
+ ;
}
diff --git a/calendar/gui/dialogs/comp-editor-page.h b/calendar/gui/dialogs/comp-editor-page.h
index a5ddb03e89..b7a10222cd 100644
--- a/calendar/gui/dialogs/comp-editor-page.h
+++ b/calendar/gui/dialogs/comp-editor-page.h
@@ -49,6 +49,7 @@ typedef enum {
COMP_EDITOR_PAGE_DELEGATE = 1<<2,
COMP_EDITOR_PAGE_USER_ORG = 1<<3,
COMP_EDITOR_PAGE_IS_ASSIGNED = 1<<4,
+ COMP_EDITOR_PAGE_IS_SHARED = 1<<5
} CompEditorPageFlags;
typedef struct {
diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h
index 1c11e1540c..fdf811aedc 100644
--- a/calendar/gui/dialogs/comp-editor.h
+++ b/calendar/gui/dialogs/comp-editor.h
@@ -65,6 +65,7 @@ typedef enum {
COMP_EDITOR_DELEGATE = 1<<2,
COMP_EDITOR_USER_ORG = 1<<3,
COMP_EDITOR_IS_ASSIGNED = 1<<4,
+ COMP_EDITOR_IS_SHARED = 1 << 5
} CompEditorFlags;
GtkType comp_editor_get_type (void);
diff --git a/calendar/gui/dialogs/memo-editor.c b/calendar/gui/dialogs/memo-editor.c
index 27babe97fe..2c6356988d 100644
--- a/calendar/gui/dialogs/memo-editor.c
+++ b/calendar/gui/dialogs/memo-editor.c
@@ -208,10 +208,11 @@ memo_editor_construct (MemoEditor *me, ECal *client)
MemoEditorPrivate *priv;
CompEditor *editor = COMP_EDITOR (me);
gboolean read_only = FALSE;
+ guint32 flags = comp_editor_get_flags (editor);
priv = me->priv;
- priv->memo_page = memo_page_new (editor->uic);
+ priv->memo_page = memo_page_new (editor->uic, flags);
g_object_ref (priv->memo_page);
gtk_object_sink (GTK_OBJECT (priv->memo_page));
comp_editor_append_page (COMP_EDITOR (me),
@@ -225,6 +226,8 @@ memo_editor_construct (MemoEditor *me, ECal *client)
bonobo_ui_component_set_prop (editor->uic, "/Toolbar/ecal3", "hidden", "1", NULL);
comp_editor_set_e_cal (COMP_EDITOR (me), client);
+
+
init_widgets (me);
@@ -241,6 +244,12 @@ memo_editor_set_e_cal (CompEditor *editor, ECal *client)
static void
memo_editor_edit_comp (CompEditor *editor, ECalComponent *comp)
{
+ CompEditorFlags flags = comp_editor_get_flags (editor);
+ ECal *client = comp_editor_get_e_cal (editor);
+
+ if (flags & COMP_EDITOR_IS_SHARED)
+ comp_editor_set_needs_send (editor, itip_organizer_is_user (comp, client));
+
if (COMP_EDITOR_CLASS (memo_editor_parent_class)->edit_comp)
COMP_EDITOR_CLASS (memo_editor_parent_class)->edit_comp (editor, comp);
}
@@ -289,11 +298,12 @@ memo_editor_finalize (GObject *object)
* editor could not be created.
**/
MemoEditor *
-memo_editor_new (ECal *client)
+memo_editor_new (ECal *client, CompEditorFlags flags)
{
MemoEditor *me;
me = g_object_new (TYPE_MEMO_EDITOR, NULL);
+ comp_editor_set_flags (COMP_EDITOR (me), flags);
return memo_editor_construct (me, client);
}
diff --git a/calendar/gui/dialogs/memo-editor.h b/calendar/gui/dialogs/memo-editor.h
index 79c86e9d4e..b5a76a0b88 100644
--- a/calendar/gui/dialogs/memo-editor.h
+++ b/calendar/gui/dialogs/memo-editor.h
@@ -53,7 +53,7 @@ struct _MemoEditorClass {
GtkType memo_editor_get_type (void);
MemoEditor *memo_editor_construct (MemoEditor *te,
ECal *client);
-MemoEditor *memo_editor_new (ECal *client);
+MemoEditor *memo_editor_new (ECal *client, CompEditorFlags flags);
#endif /* __MEMO_EDITOR_H__ */
diff --git a/calendar/gui/dialogs/memo-page.c b/calendar/gui/dialogs/memo-page.c
index 4fa478238f..42850b60b3 100644
--- a/calendar/gui/dialogs/memo-page.c
+++ b/calendar/gui/dialogs/memo-page.c
@@ -36,10 +36,14 @@
#include <libgnome/gnome-i18n.h>
#include <glade/glade.h>
#include <libedataserverui/e-source-option-menu.h>
+#include <libedataserverui/e-name-selector.h>
+#include <libedataserverui/e-name-selector-entry.h>
+#include <libedataserverui/e-name-selector-list.h>
#include <widgets/misc/e-dateedit.h>
#include "common/authentication.h"
#include "e-util/e-dialog-widgets.h"
+#include <e-util/e-dialog-utils.h>
#include "e-util/e-categories-config.h"
#include "e-util/e-util-private.h"
#include "../calendar-config.h"
@@ -59,16 +63,39 @@ struct _MemoPagePrivate {
GtkWidget *memo_content;
+ EAccountList *accounts;
+
/* Bonobo Controller for the menu/toolbar */
BonoboUIComponent *uic;
ECalComponentClassification classification;
+ /* Organizer */
+ GtkWidget *org_label;
+ GtkWidget *org_combo;
+
+ /* To field */
+ GtkWidget *to_button;
+ GtkWidget *to_hbox;
+ GtkWidget *to_entry;
+
+ /* Summary */
+ GtkWidget *summary_label;
+ GtkWidget *summary_entry;
+
+ /* Start date */
+ GtkWidget *start_label;
+ GtkWidget *start_date;
+
GtkWidget *categories_btn;
GtkWidget *categories;
GtkWidget *source_selector;
+ char *default_address;
+
+ ENameSelector *name_selector;
+
gboolean updating;
};
@@ -137,7 +164,6 @@ memo_page_init (MemoPage *mpage)
priv->categories = NULL;
priv->updating = FALSE;
-
}
/* Destroy handler for the memo page */
@@ -161,6 +187,11 @@ memo_page_finalize (GObject *object)
priv->xml = NULL;
}
+ if (priv->default_address) {
+ g_free (priv->default_address);
+ priv->default_address = NULL;
+ }
+
g_free (priv);
mpage->priv = NULL;
@@ -215,7 +246,7 @@ memo_page_focus_main_widget (CompEditorPage *page)
mpage = MEMO_PAGE (page);
priv = mpage->priv;
- gtk_widget_grab_focus (priv->memo_content);
+ gtk_widget_grab_focus (priv->summary_entry);
}
/* Fills the widgets with default values */
@@ -226,6 +257,9 @@ clear_widgets (MemoPage *mpage)
priv = mpage->priv;
+ /* Summary */
+ e_dialog_editable_set (priv->summary_entry, NULL);
+
/* memo content */
gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->memo_content)), "", 0);
@@ -235,6 +269,9 @@ clear_widgets (MemoPage *mpage)
/* Categories */
e_dialog_editable_set (priv->categories, NULL);
+
+ if (priv->default_address)
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->org_combo)->entry), priv->default_address);
}
void
@@ -254,7 +291,7 @@ sensitize_widgets (MemoPage *mpage)
if (!e_cal_is_read_only (COMP_EDITOR_PAGE (mpage)->client, &read_only, NULL))
read_only = TRUE;
- if (COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_IS_ASSIGNED)
+ if (COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_IS_SHARED)
sens = COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_PAGE_USER_ORG;
sensitize = (!read_only && sens);
@@ -264,9 +301,20 @@ sensitize_widgets (MemoPage *mpage)
if (!e_cal_is_read_only (COMP_EDITOR_PAGE (mpage)->client, &read_only, NULL))
read_only = TRUE;
- gtk_widget_set_sensitive (priv->memo_content, !read_only);
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->memo_content), sensitize);
+ gtk_widget_set_sensitive (priv->start_date, sensitize);
gtk_widget_set_sensitive (priv->categories_btn, !read_only);
gtk_entry_set_editable (GTK_ENTRY (priv->categories), !read_only);
+ gtk_entry_set_editable (GTK_ENTRY (priv->summary_entry), sensitize);
+
+ if (COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_IS_SHARED) {
+ gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (priv->org_combo)->entry), sensitize);
+
+ if (priv->to_entry) {
+ gtk_entry_set_editable (GTK_ENTRY (priv->to_entry), !read_only);
+ gtk_widget_grab_focus (priv->to_entry);
+ }
+ }
bonobo_ui_component_set_prop (priv->uic, "/commands/ActionClassPublic", "sensitive", sensitize ? "1" : "0"
, NULL);
@@ -274,7 +322,7 @@ sensitize_widgets (MemoPage *mpage)
, NULL);
bonobo_ui_component_set_prop (priv->uic, "/commands/ActionClassConfidential", "sensitive",
sensitize ? "1" : "0", NULL);
- bonobo_ui_component_set_prop (priv->uic, "/commands/ViewCategories", "sensitive", sensitize ? "1" : "0"
+ bonobo_ui_component_set_prop (priv->uic, "/commands/InsertAttachments", "sensitive", sensitize ? "1" : "0"
, NULL);
}
@@ -285,6 +333,8 @@ memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp)
MemoPage *mpage;
MemoPagePrivate *priv;
ECalComponentClassification cl;
+ ECalComponentText text;
+ ECalComponentDateTime d;
GSList *l;
const char *categories;
ESource *source;
@@ -297,6 +347,10 @@ memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp)
/* Clean the screen */
clear_widgets (mpage);
+ /* Summary */
+ e_cal_component_get_summary (comp, &text);
+ e_dialog_editable_set (priv->summary_entry, text.value);
+
e_cal_component_get_description_list (comp, &l);
if (l && l->data) {
ECalComponentText *dtext;
@@ -310,6 +364,16 @@ memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp)
}
e_cal_component_free_text_list (l);
+ /* Start Date. */
+ e_cal_component_get_dtstart (comp, &d);
+ if (d.value) {
+ struct icaltimetype *start_tt = d.value;
+ e_date_edit_set_date (E_DATE_EDIT (priv->start_date),
+ start_tt->year, start_tt->month,
+ start_tt->day);
+ } else if (!(page->flags & COMP_EDITOR_PAGE_NEW_ITEM))
+ e_date_edit_set_time (E_DATE_EDIT (priv->start_date), -1);
+
/* Classification. */
e_cal_component_get_classification (comp, &cl);
@@ -340,6 +404,31 @@ memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp)
e_cal_component_get_categories (comp, &categories);
e_dialog_editable_set (priv->categories, categories);
+ if (e_cal_component_has_organizer (comp)) {
+ ECalComponentOrganizer organizer;
+
+ e_cal_component_get_organizer (comp, &organizer);
+ if (organizer.value != NULL) {
+ const gchar *strip = itip_strip_mailto (organizer.value);
+ gchar *string;
+ GList *list = NULL;
+
+ if ( organizer.cn != NULL)
+ string = g_strdup_printf ("%s <%s>", organizer.cn, strip);
+ else
+ string = g_strdup (strip);
+
+ if (itip_organizer_is_user (comp, page->client)) {
+ } else {
+ list = g_list_append (list, string);
+ gtk_combo_set_popdown_strings (GTK_COMBO (priv->org_combo), list);
+ gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (priv->org_combo)->entry), FALSE);
+ }
+ g_free (string);
+ g_list_free (list);
+ }
+ }
+
/* Source */
source = e_cal_get_source (page->client);
e_source_option_menu_select (E_SOURCE_OPTION_MENU (priv->source_selector), source);
@@ -351,12 +440,162 @@ memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp)
return TRUE;
}
+static gboolean
+fill_comp_with_recipients (ENameSelector *name_selector, ECalComponent *comp)
+{
+ EDestinationStore *destination_store;
+ GString *str = NULL;
+ GList *l, *destinations;
+ ENameSelectorModel *name_selector_model = e_name_selector_peek_model (name_selector);
+ icalcomponent *icalcomp;
+ icalproperty *icalprop;
+
+ e_name_selector_model_peek_section (name_selector_model, "To",
+ NULL, &destination_store);
+
+ destinations = e_destination_store_list_destinations (destination_store);
+ for (l = destinations; l; l = g_list_next (l)) {
+ EDestination *destination = l->data, *des = NULL;
+ const GList *list_dests = NULL, *l;
+ GList card_dest;
+
+ if (e_destination_is_evolution_list (destination)) {
+ list_dests = e_destination_list_get_dests (destination);
+ } else {
+ EContact *contact = e_destination_get_contact (destination);
+ /* check if the contact is contact list which is not expanded yet */
+ /* we expand it by getting the list again from the server forming the query */
+ if (contact && e_contact_get (contact , E_CONTACT_IS_LIST)) {
+ EBook *book = NULL;
+ ENameSelectorDialog *dialog;
+ EContactStore *c_store;
+ GList *books, *l;
+ char *uri = e_contact_get (contact, E_CONTACT_BOOK_URI);
+
+ dialog = e_name_selector_peek_dialog (name_selector);
+ c_store = dialog->name_selector_model->contact_store;
+ books = e_contact_store_get_books (c_store);
+
+ for (l = books; l; l = l->next) {
+ EBook *b = l->data;
+ if (g_str_equal (uri, e_book_get_uri (b))) {
+ book = b;
+ break;
+ }
+ }
+
+ if (book) {
+ GList *contacts;
+ EContact *n_con = NULL;
+ char *qu;
+ EBookQuery *query;
+
+ qu = g_strdup_printf ("(is \"full_name\" \"%s\")",
+ (char *) e_contact_get (contact, E_CONTACT_FULL_NAME));
+ query = e_book_query_from_string (qu);
+
+ if (!e_book_get_contacts (book, query, &contacts, NULL)) {
+ g_warning ("Could not get contact from the book \n");
+ return;
+ } else {
+ des = e_destination_new ();
+ n_con = contacts->data;
+
+ e_destination_set_contact (des, n_con, 0);
+ list_dests = e_destination_list_get_dests (des);
+
+ g_list_foreach (contacts, (GFunc) g_object_unref, NULL);
+ g_list_free (contacts);
+ }
+
+ e_book_query_unref (query);
+ g_free (qu);
+ }
+ } else {
+ card_dest.next = NULL;
+ card_dest.prev = NULL;
+ card_dest.data = destination;
+ list_dests = &card_dest;
+ }
+ }
+
+ for (l = list_dests; l; l = l->next) {
+ EDestination *dest = l->data;
+ const char *name, *attendee = NULL;
+
+ name = e_destination_get_name (dest);
+
+ /* If we couldn't get the attendee prior, get the email address as the default */
+ if (attendee == NULL || *attendee == '\0') {
+ attendee = e_destination_get_email (dest);
+ }
+
+ if (attendee == NULL || *attendee == '\0')
+ continue;
+
+ if (!str) {
+ str = g_string_new ("");
+ g_string_prepend (str, attendee);
+ continue;
+ }
+ g_string_prepend (str, ";");
+ g_string_prepend (str, attendee);
+ }
+ }
+
+ g_list_free (destinations);
+
+ if (str && *str->str) {
+ icalcomp = e_cal_component_get_icalcomponent (comp);
+ icalprop = icalproperty_new_x (str->str);
+ icalproperty_set_x_name (icalprop, "X-EVOLUTION-RECIPIENTS");
+ icalcomponent_add_property (icalcomp, icalprop);
+
+ g_string_free (str, FALSE);
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+static EAccount *
+get_current_account (MemoPage *page)
+{
+ MemoPagePrivate *priv;
+ EIterator *it;
+ const char *str;
+
+ priv = page->priv;
+
+ str = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (priv->org_combo)->entry));
+ if (!str)
+ return NULL;
+
+ for (it = e_list_get_iterator((EList *)priv->accounts); e_iterator_is_valid(it); e_iterator_next(it)) {
+ EAccount *a = (EAccount *)e_iterator_get(it);
+ char *full = g_strdup_printf("%s <%s>", a->id->name, a->id->address);
+
+ if (!strcmp (full, str)) {
+ g_free (full);
+ g_object_unref (it);
+
+ return a;
+ }
+
+ g_free (full);
+ }
+ g_object_unref (it);
+
+ return NULL;
+}
+
/* fill_component handler for the memo page */
static gboolean
memo_page_fill_component (CompEditorPage *page, ECalComponent *comp)
{
MemoPage *mpage;
MemoPagePrivate *priv;
+ ECalComponentDateTime start_date;
+ struct icaltimetype start_tt;
char *cat, *str;
int i;
GtkTextBuffer *text_buffer;
@@ -366,6 +605,24 @@ memo_page_fill_component (CompEditorPage *page, ECalComponent *comp)
priv = mpage->priv;
text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->memo_content));
+ /* Summary */
+ str = e_dialog_editable_get (priv->summary_entry);
+ if (!str || strlen (str) == 0)
+ e_cal_component_set_summary (comp, NULL);
+ else {
+ ECalComponentText text;
+
+ text.value = str;
+ text.altrep = NULL;
+
+ e_cal_component_set_summary (comp, &text);
+ }
+
+ if (str) {
+ g_free (str);
+ str = NULL;
+ }
+
/* Memo Content */
gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start);
@@ -374,7 +631,6 @@ memo_page_fill_component (CompEditorPage *page, ECalComponent *comp)
if (!str || strlen (str) == 0){
e_cal_component_set_description_list (comp, NULL);
- e_cal_component_set_summary(comp, NULL);
}
else {
int idxToUse = -1, nstr = strlen(str);
@@ -410,7 +666,6 @@ memo_page_fill_component (CompEditorPage *page, ECalComponent *comp)
l.data = &text;
l.next = NULL;
- e_cal_component_set_summary(comp, &sumText);
e_cal_component_set_description_list (comp, &l);
g_free(txt);
@@ -419,6 +674,22 @@ memo_page_fill_component (CompEditorPage *page, ECalComponent *comp)
if (str)
g_free (str);
+ /* Dates */
+ start_tt = icaltime_null_time ();
+ start_tt.is_date = 1;
+ start_date.value = &start_tt;
+ start_date.tzid = NULL;
+
+ if (!e_date_edit_date_is_valid (E_DATE_EDIT (priv->start_date))) {
+ comp_editor_page_display_validation_error (page, _("Start date is wrong"), priv->start_date);
+ return FALSE;
+ }
+ e_date_edit_get_date (E_DATE_EDIT (priv->start_date),
+ &start_tt.year,
+ &start_tt.month,
+ &start_tt.day);
+ e_cal_component_set_dtstart (comp, &start_date);
+
/* Classification. */
e_cal_component_set_classification (comp, priv->classification);
@@ -433,6 +704,37 @@ memo_page_fill_component (CompEditorPage *page, ECalComponent *comp)
if (str)
g_free (str);
+ if ((page->flags & COMP_EDITOR_PAGE_IS_SHARED) && fill_comp_with_recipients (priv->name_selector, comp)) {
+ ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL};
+
+ EAccount *a;
+ gchar *addr = NULL;
+
+ /* Find the identity for the organizer or sentby field */
+ a = get_current_account (mpage);
+
+ /* Sanity Check */
+ if (a == NULL) {
+ e_notice (page, GTK_MESSAGE_ERROR,
+ _("The organizer selected no longer has an account."));
+ return FALSE;
+ }
+
+ if (a->id->address == NULL || strlen (a->id->address) == 0) {
+ e_notice (page, GTK_MESSAGE_ERROR,
+ _("An organizer is required."));
+ return FALSE;
+ }
+
+ addr = g_strdup_printf ("MAILTO:%s", a->id->address);
+
+ organizer.value = addr;
+ organizer.cn = a->id->name;
+ e_cal_component_set_organizer (comp, &organizer);
+
+ g_free (addr);
+ }
+
return TRUE;
}
@@ -479,6 +781,18 @@ get_widgets (MemoPage *mpage)
gtk_widget_ref (priv->main);
gtk_container_remove (GTK_CONTAINER (priv->main->parent), priv->main);
+ priv->org_label = GW ("org-label");
+ priv->org_combo = GW ("org-combo");
+
+ priv->to_button = GW ("to-button");
+ priv->to_hbox = GW ("to-hbox");
+
+ priv->summary_label = GW ("sum-label");
+ priv->summary_entry = GW ("sum-entry");
+
+ priv->start_label = GW ("start-label");
+ priv->start_date = GW ("start-date");
+
priv->memo_content = GW ("memo_content");
priv->categories_btn = GW ("categories-button");
@@ -490,7 +804,8 @@ get_widgets (MemoPage *mpage)
return (priv->memo_content
&& priv->categories_btn
- && priv->categories);
+ && priv->categories
+ && priv->start_date);
}
/* Callback used when the categories button is clicked; we must bring up the
@@ -584,6 +899,22 @@ widget_focus_out_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
return FALSE;
}
+static void
+to_button_clicked_cb (GtkButton *button, gpointer data)
+{
+ MemoPage *page = data;
+ MemoPagePrivate *priv = page->priv;
+ ENameSelectorDialog *name_selector_dialog;
+
+ name_selector_dialog = e_name_selector_peek_dialog (priv->name_selector);
+ gtk_widget_show (GTK_WIDGET (name_selector_dialog));
+}
+
+static void
+response_cb (ENameSelectorDialog *name_selector_dialog, gint response, gpointer user_data)
+{
+ gtk_widget_hide (GTK_WIDGET (name_selector_dialog));
+}
/* Hooks the widget signals */
static gboolean
@@ -621,12 +952,38 @@ init_widgets (MemoPage *mpage)
g_signal_connect((priv->categories), "changed",
G_CALLBACK (field_changed_cb), mpage);
+
+ g_signal_connect((priv->summary_entry), "changed",
+ G_CALLBACK (field_changed_cb), mpage);
+ if (priv->name_selector) {
+ ENameSelectorDialog *name_selector_dialog;
+
+ name_selector_dialog = e_name_selector_peek_dialog (priv->name_selector);
+
+ g_signal_connect (name_selector_dialog, "response",
+ G_CALLBACK (response_cb), mpage);
+ g_signal_connect ((priv->to_button), "clicked", G_CALLBACK (to_button_clicked_cb), mpage);
+ }
+
memo_page_set_show_categories (mpage, calendar_config_get_show_categories());
return TRUE;
}
+static GtkWidget *
+get_to_entry (ENameSelector *name_selector)
+{
+ ENameSelectorModel *name_selector_model;
+ ENameSelectorEntry *name_selector_entry;
+
+ name_selector_model = e_name_selector_peek_model (name_selector);
+ e_name_selector_model_add_section (name_selector_model, "To", _("To"), NULL);
+ name_selector_entry = (ENameSelectorEntry *)e_name_selector_peek_section_list (name_selector, "To");
+
+ return GTK_WIDGET (name_selector_entry);
+}
+
/**
* memo_page_construct:
@@ -641,7 +998,13 @@ MemoPage *
memo_page_construct (MemoPage *mpage)
{
MemoPagePrivate *priv;
+ char *backend_address = NULL;
+ EIterator *it;
char *gladefile;
+ GList *address_strings = NULL, *l;
+ EAccount *def_account;
+ EAccount *a;
+ CompEditorPageFlags flags = COMP_EDITOR_PAGE (mpage)->flags;
priv = mpage->priv;
@@ -663,6 +1026,59 @@ memo_page_construct (MemoPage *mpage)
return NULL;
}
+ if (flags & COMP_EDITOR_PAGE_IS_SHARED) {
+ priv->accounts = itip_addresses_get ();
+ def_account = itip_addresses_get_default();
+ for (it = e_list_get_iterator((EList *)priv->accounts);
+ e_iterator_is_valid(it);
+ e_iterator_next(it)) {
+ a = (EAccount *)e_iterator_get(it);
+ char *full;
+
+ full = g_strdup_printf("%s <%s>", a->id->name, a->id->address);
+
+ address_strings = g_list_append(address_strings, full);
+
+ /* Note that the address specified by the backend gets
+ * precedence over the default mail address.
+ */
+ if (backend_address && !strcmp (backend_address, a->id->address)) {
+ if (priv->default_address)
+ g_free (priv->default_address);
+
+ priv->default_address = g_strdup (full);
+ } else if (a == def_account && !priv->default_address) {
+ priv->default_address = g_strdup (full);
+ }
+ }
+
+ if (backend_address)
+ g_free (backend_address);
+
+ g_object_unref(it);
+
+ if (address_strings)
+ gtk_combo_set_popdown_strings (GTK_COMBO (priv->org_combo), address_strings);
+ else
+ g_warning ("No potential organizers!");
+
+ for (l = address_strings; l != NULL; l = l->next)
+ g_free (l->data);
+ g_list_free (address_strings);
+
+ gtk_widget_show (priv->org_label);
+ gtk_widget_show (priv->org_combo);
+
+ if (flags & COMP_EDITOR_PAGE_NEW_ITEM) {
+ priv->name_selector = e_name_selector_new ();
+ priv->to_entry = get_to_entry (priv->name_selector);
+ gtk_container_add ((GtkContainer *)priv->to_hbox, priv->to_entry);
+ gtk_widget_show (priv->to_hbox);
+ gtk_widget_show (priv->to_entry);
+ gtk_widget_show (priv->to_button);
+ }
+ }
+
if (!init_widgets (mpage)) {
g_message ("memo_page_construct(): "
"Could not initialize the widgets!");
@@ -681,12 +1097,14 @@ memo_page_construct (MemoPage *mpage)
* not be created.
**/
MemoPage *
-memo_page_new (BonoboUIComponent *uic)
+memo_page_new (BonoboUIComponent *uic, CompEditorPageFlags flags)
{
MemoPage *mpage;
mpage = gtk_type_new (TYPE_MEMO_PAGE);
mpage->priv->uic = uic;
+ COMP_EDITOR_PAGE (mpage)->flags = flags;
+
if (!memo_page_construct (mpage)) {
g_object_unref (mpage);
return NULL;
@@ -695,6 +1113,20 @@ memo_page_new (BonoboUIComponent *uic)
return mpage;
}
+GtkWidget *memo_page_create_date_edit (void);
+
+GtkWidget *
+memo_page_create_date_edit (void)
+{
+ GtkWidget *dedit;
+
+ dedit = comp_editor_new_date_edit (TRUE, FALSE, TRUE);
+ e_date_edit_set_allow_no_date_set (E_DATE_EDIT (dedit), TRUE);
+ gtk_widget_show (dedit);
+
+ return dedit;
+}
+
GtkWidget *memo_page_create_source_option_menu (void);
GtkWidget *
diff --git a/calendar/gui/dialogs/memo-page.glade b/calendar/gui/dialogs/memo-page.glade
index b230052fba..5de9142675 100644
--- a/calendar/gui/dialogs/memo-page.glade
+++ b/calendar/gui/dialogs/memo-page.glade
@@ -33,7 +33,7 @@
<child>
<widget class="GtkTable" id="table3">
<property name="visible">True</property>
- <property name="n_rows">3</property>
+ <property name="n_rows">7</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">0</property>
@@ -72,8 +72,8 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
<property name="x_padding">6</property>
<property name="y_padding">3</property>
<property name="x_options">expand|shrink|fill</property>
@@ -93,8 +93,8 @@
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
<property name="x_padding">6</property>
<property name="y_padding">3</property>
<property name="x_options">fill</property>
@@ -123,8 +123,8 @@
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
<property name="x_padding">6</property>
<property name="y_padding">3</property>
<property name="x_options">fill</property>
@@ -156,8 +156,8 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
<property name="x_padding">6</property>
<property name="y_padding">3</property>
<property name="x_options">fill</property>
@@ -180,8 +180,8 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
<property name="x_padding">6</property>
<property name="y_padding">3</property>
<property name="y_options"></property>
@@ -210,11 +210,224 @@
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_padding">6</property>
+ <property name="y_padding">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="org-label">
+ <property name="label" translatable="yes">Or_ganizer:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">combo-entry1</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_padding">6</property>
<property name="y_padding">3</property>
<property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="to-button">
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">T_o:</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_padding">6</property>
+ <property name="y_padding">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="start-label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Sta_rt date:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_padding">6</property>
+ <property name="y_padding">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">shrink</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="Custom" id="start-date">
+ <property name="visible">True</property>
+ <property name="creation_function">memo_page_create_date_edit</property>
+ <property name="int1">0</property>
+ <property name="int2">0</property>
+ <property name="last_modification_time">Mon, 17 Jul 2006 21:24:48 GMT</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_padding">6</property>
+ <property name="y_padding">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="sum-entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_padding">6</property>
+ <property name="y_padding">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="sum-label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Su_mmary</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">sum-entry</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_padding">6</property>
+ <property name="y_padding">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCombo" id="org-combo">
+ <property name="value_in_list">False</property>
+ <property name="allow_empty">True</property>
+ <property name="case_sensitive">False</property>
+ <property name="enable_arrow_keys">True</property>
+ <property name="enable_arrows_always">False</property>
+
+ <child internal-child="entry">
+ <widget class="GtkEntry" id="combo-entry1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">False</property>
+ </widget>
+ </child>
+
+ <child internal-child="list">
+ <widget class="GtkList" id="combo-list1">
+ <property name="visible">True</property>
+ <property name="selection_mode">GTK_SELECTION_BROWSE</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="to-hbox">
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_padding">6</property>
+ <property name="y_padding">3</property>
+ <property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
diff --git a/calendar/gui/dialogs/memo-page.h b/calendar/gui/dialogs/memo-page.h
index 45928d96e0..132db6ed22 100644
--- a/calendar/gui/dialogs/memo-page.h
+++ b/calendar/gui/dialogs/memo-page.h
@@ -52,7 +52,7 @@ typedef struct {
GtkType memo_page_get_type (void);
MemoPage *memo_page_construct (MemoPage *epage);
-MemoPage *memo_page_new (BonoboUIComponent *uic);
+MemoPage *memo_page_new (BonoboUIComponent *uic, CompEditorPageFlags flags);
G_END_DECLS
diff --git a/calendar/gui/e-cal-component-memo-preview.c b/calendar/gui/e-cal-component-memo-preview.c
index 7cb23740ce..1dd9dee782 100644
--- a/calendar/gui/e-cal-component-memo-preview.c
+++ b/calendar/gui/e-cal-component-memo-preview.c
@@ -100,18 +100,59 @@ url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointe
}
}
+/* Converts a time_t to a string, relative to the specified timezone */
+static char *
+timet_to_str_with_zone (ECalComponentDateTime *dt, ECal *ecal, icaltimezone *default_zone)
+{
+ struct icaltimetype itt;
+ icaltimezone *zone;
+ struct tm tm;
+ char buf[256];
+
+ if (dt->tzid) {
+ /* If we can't find the zone, we'll guess its "local" */
+ if (!e_cal_get_timezone (ecal, dt->tzid, &zone, NULL))
+ zone = NULL;
+ } else if (dt->value->is_utc) {
+ zone = icaltimezone_get_utc_timezone ();
+ } else {
+ zone = NULL;
+ }
+
+
+ itt = *dt->value;
+ if (zone)
+ icaltimezone_convert_time (&itt, zone, default_zone);
+ tm = icaltimetype_to_tm (&itt);
+
+ e_time_format_date_and_time (&tm, calendar_config_get_24_hour_format (),
+ FALSE, FALSE, buf, sizeof (buf));
+
+ return g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
+}
+
static void
write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone *default_zone)
{
ECalComponentText text;
+ ECalComponentDateTime dt;
gchar *str;
GSList *l;
gboolean one_added = FALSE;
g_return_if_fail (E_IS_CAL_COMPONENT (comp));
- gtk_html_stream_printf (stream,
- "<HTML><BODY>");
+ /* write document header */
+ e_cal_component_get_summary (comp, &text);
+
+ if (text.value)
+ gtk_html_stream_printf (stream,
+ "<HTML><BODY><H1>%s</H1>",
+ text.value);
+ else
+ gtk_html_stream_printf (stream,
+ "<HTML><BODY><H1><I>%s</I></H1>",
+ _("Untitled"));
/* write icons for the categories */
e_cal_component_get_categories_list (comp, &l);
@@ -155,6 +196,16 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone
gtk_html_stream_printf (stream, "<TABLE BORDER=\"0\" WIDTH=\"80%%\">"
"<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"15%%\"></TD></TR>");
+ /* write start date */
+ e_cal_component_get_dtstart (comp, &dt);
+ if (dt.value != NULL) {
+ str = timet_to_str_with_zone (&dt, ecal, default_zone);
+ gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD><TD>%s</TD></TR>",
+ _("Start Date:"), str);
+
+ e_cal_component_free_datetime (&dt);
+ g_free (str);
+ }
/* write description and URL */
gtk_html_stream_printf (stream, "<TR><TD COLSPAN=\"2\"><HR></TD></TR>");
@@ -163,7 +214,7 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone
if (l) {
GSList *node;
- gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Memo:"));
+ gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Description:"));
gtk_html_stream_printf (stream, "<TD>");
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index 2de983ab10..2658124192 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -468,6 +468,11 @@ ecm_value_at (ETableModel *etm, int col, int row)
comp = e_cal_component_new ();
icalcomp = icalcomponent_new_clone (comp_data->icalcomp);
if (e_cal_component_set_icalcomponent (comp, icalcomp)) {
+ if (e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_JOURNAL) {
+ g_object_unref (comp);
+ return GINT_TO_POINTER (retval);
+ }
+
if (e_cal_component_has_recurrences (comp))
retval = 1;
else if (itip_organizer_is_user (comp, comp_data->client))
diff --git a/calendar/gui/e-memo-table-config.c b/calendar/gui/e-memo-table-config.c
index 064ef0810f..f72c863c72 100644
--- a/calendar/gui/e-memo-table-config.c
+++ b/calendar/gui/e-memo-table-config.c
@@ -22,10 +22,13 @@
*/
#include "calendar-config.h"
+#include "e-cell-date-edit-config.h"
#include "e-memo-table-config.h"
struct _EMemoTableConfigPrivate {
EMemoTable *table;
+
+ ECellDateEditConfig *cell_config;
GList *notifications;
};
@@ -208,6 +211,11 @@ e_memo_table_config_set_table (EMemoTableConfig *table_config, EMemoTable *table
priv->table = NULL;
}
+ if (priv->cell_config) {
+ g_object_unref (priv->cell_config);
+ priv->cell_config = NULL;
+ }
+
for (l = priv->notifications; l; l = l->next)
calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
@@ -231,4 +239,7 @@ e_memo_table_config_set_table (EMemoTableConfig *table_config, EMemoTable *table
not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, table_config);
priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
+
+ /* Date cell */
+ priv->cell_config = e_cell_date_edit_config_new (table->dates_cell);
}
diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c
index 84ac373017..212d12187f 100644
--- a/calendar/gui/e-memo-table.c
+++ b/calendar/gui/e-memo-table.c
@@ -88,6 +88,7 @@ static gint e_memo_table_on_key_press (ETable *table,
gint col,
GdkEventKey *event,
EMemoTable *memo_table);
+static struct tm e_memo_table_get_current_time (ECellDateEdit *ecde, gpointer data);
static ECalModelComponent *get_selected_comp (EMemoTable *memo_table);
static void open_memo (EMemoTable *memo_table, ECalModelComponent *comp_data);
@@ -136,6 +137,34 @@ e_memo_table_class_init (EMemoTableClass *klass)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
}
+static gint
+date_compare_cb (gconstpointer a, gconstpointer b)
+{
+ ECellDateEditValue *dv1 = (ECellDateEditValue *) a;
+ ECellDateEditValue *dv2 = (ECellDateEditValue *) b;
+ struct icaltimetype tt;
+
+ /* First check if either is NULL. NULL dates sort last. */
+ if (!dv1 || !dv2) {
+ if (dv1 == dv2)
+ return 0;
+ else if (dv1)
+ return -1;
+ else
+ return 1;
+ }
+
+ /* Copy the 2nd value and convert it to the same timezone as the
+ first. */
+ tt = dv2->tt;
+
+ icaltimezone_convert_time (&tt, dv2->zone, dv1->zone);
+
+ /* Now we can compare them. */
+
+ return icaltime_compare (dv1->tt, tt);
+}
+
/* Comparison function for the task-sort column. Sorts by due date and then by
* priority.
*
@@ -204,7 +233,7 @@ e_memo_table_init (EMemoTable *memo_table)
{
GtkWidget *table;
ETable *e_table;
- ECell *cell;
+ ECell *cell, *popup_cell;
ETableExtras *extras;
gint i;
AtkObject *a11y;
@@ -229,8 +258,28 @@ e_memo_table_init (EMemoTable *memo_table)
e_table_extras_add_cell (extras, "calstring", cell);
+ /*
+ * Date fields.
+ */
+ cell = e_cell_date_edit_text_new (NULL, GTK_JUSTIFY_LEFT);
+ g_object_set (G_OBJECT (cell),
+ "bg_color_column", E_CAL_MODEL_FIELD_COLOR,
+ NULL);
+
+ popup_cell = e_cell_date_edit_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+ e_table_extras_add_cell (extras, "dateedit", popup_cell);
+ memo_table->dates_cell = E_CELL_DATE_EDIT (popup_cell);
+ e_cell_date_edit_set_get_time_callback (E_CELL_DATE_EDIT (popup_cell),
+ e_memo_table_get_current_time,
+ memo_table, NULL);
+ /* Sorting */
+ e_table_extras_add_compare (extras, "date-compare",
+ date_compare_cb);
+
/* Create pixmaps */
if (!icon_pixbufs[0])
@@ -681,11 +730,19 @@ open_memo (EMemoTable *memo_table, ECalModelComponent *comp_data)
medit = e_comp_editor_registry_find (comp_editor_registry, uid);
if (medit == NULL) {
ECalComponent *comp;
-
- medit = COMP_EDITOR (memo_editor_new (comp_data->client));
+ CompEditorFlags flags = 0;
comp = e_cal_component_new ();
e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
+
+ if (e_cal_component_has_organizer (comp))
+ flags |= COMP_EDITOR_IS_SHARED;
+
+ if (itip_organizer_is_user (comp, comp_data->client))
+ flags |= COMP_EDITOR_USER_ORG;
+
+ medit = COMP_EDITOR (memo_editor_new (comp_data->client, flags));
+
comp_editor_edit_comp (medit, comp);
e_comp_editor_registry_add (comp_editor_registry, medit, FALSE);
@@ -979,6 +1036,34 @@ e_memo_table_save_state (EMemoTable *memo_table,
filename);
}
+/* Returns the current time, for the ECellDateEdit items.
+ FIXME: Should probably use the timezone of the item rather than the
+ current timezone, though that may be difficult to get from here. */
+static struct tm
+e_memo_table_get_current_time (ECellDateEdit *ecde, gpointer data)
+{
+ icaltimezone *zone;
+ struct tm tmp_tm = { 0 };
+ struct icaltimetype tt;
+
+ /* Get the current timezone. */
+ zone = calendar_config_get_icaltimezone ();
+
+ tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
+
+ /* Now copy it to the struct tm and return it. */
+ tmp_tm.tm_year = tt.year - 1900;
+ tmp_tm.tm_mon = tt.month - 1;
+ tmp_tm.tm_mday = tt.day;
+ tmp_tm.tm_hour = tt.hour;
+ tmp_tm.tm_min = tt.minute;
+ tmp_tm.tm_sec = tt.second;
+ tmp_tm.tm_isdst = -1;
+
+ return tmp_tm;
+}
+
+
#ifdef TRANSLATORS_ONLY
static char *test[] = {
diff --git a/calendar/gui/e-memo-table.etspec b/calendar/gui/e-memo-table.etspec
index ce2f194399..6474b69d96 100644
--- a/calendar/gui/e-memo-table.etspec
+++ b/calendar/gui/e-memo-table.etspec
@@ -1,13 +1,13 @@
<ETableSpecification click-to-add="true" _click-to-add-message="Click to add a memo" draw-grid="true">
- <ETableColumn model_col="4" _title="Summary" expansion="3.0" minimum_width="10" resizable="true" cell="calstring" compare="stringcase" priority="0"/>
- <ETableColumn model_col="19" _title="Memo sort" cell="task-sort" compare="memo-sort" priority="-4"/>
+ <ETableColumn model_col="8" _title="Summary" expansion="3.0" minimum_width="10" resizable="true" cell="calstring" compare="stringcase" priority="0"/>
<ETableColumn model_col="7" pixbuf="icon" _title="Type" expansion="1.0" minimum_width="16" resizable="false" cell="icon" compare="integer" priority="-4"/>
<ETableColumn model_col="0" _title="Categories" cell="calstring" compare="string" expansion="1.0" minimum_width="10" resizable="true" priority="-2"/>
+ <ETableColumn model_col="5" _title="Start Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2"/>
+ <ETableColumn model_col="19" _title="Memo sort" cell="task-sort" compare="memo-sort" priority="-4"/>
<ETableState>
- <column source="4"/>
+ <column source="1"/>
<column source="0"/>
- <column source="2"/>
<grouping></grouping>
</ETableState>
</ETableSpecification>
diff --git a/calendar/gui/e-memo-table.h b/calendar/gui/e-memo-table.h
index da01405ac0..58e242c35d 100644
--- a/calendar/gui/e-memo-table.h
+++ b/calendar/gui/e-memo-table.h
@@ -56,6 +56,9 @@ struct _EMemoTable {
GtkWidget *etable;
+ /* The ECell used to view & edit dates. */
+ ECellDateEdit *dates_cell;
+
/* Fields used for cut/copy/paste */
icalcomponent *tmp_vcal;
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 0e0b92c22a..9c6a219fb6 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -68,9 +68,11 @@
#include "e-cal-list-view-config.h"
#include "e-mini-calendar-config.h"
#include "e-calendar-table-config.h"
+#include "e-memo-table-config.h"
#include "evolution-calendar.h"
#include "gnome-cal.h"
#include "calendar-component.h"
+#include "memos-component.h"
#include "cal-search-bar.h"
#include "calendar-commands.h"
#include "calendar-config.h"
@@ -114,12 +116,16 @@ struct _GnomeCalendarPrivate {
GtkWidget *hpane;
GtkWidget *notebook;
+ GtkWidget *vpane;
ECalendar *date_navigator;
EMiniCalendarConfig *date_navigator_config;
GtkWidget *todo;
ECalendarTableConfig *todo_config;
+ GtkWidget *memo;
+ EMemoTableConfig *memo_config;
+
GtkWidget *day_view;
GtkWidget *work_week_view;
GtkWidget *week_view;
@@ -132,11 +138,13 @@ struct _GnomeCalendarPrivate {
/* plugin menu managers */
ECalMenu *calendar_menu;
ECalMenu *taskpad_menu;
+ ECalMenu *memopad_menu;
/* Calendar query for the date navigator */
GList *dn_queries; /* list of CalQueries */
char *sexp;
char *todo_sexp;
+ char *memo_sexp;
guint update_timeout;
guint update_marcus_bains_line_timeout;
@@ -155,6 +163,8 @@ struct _GnomeCalendarPrivate {
will work OK after theme changes. */
gint hpane_pos;
gint hpane_pos_month_view;
+ gint vpane_pos;
+ gint vpane_pos_month_view;
/* The signal handler id for our GtkCalendar "day_selected" handler. */
guint day_selected_id;
@@ -183,8 +193,10 @@ enum {
DATES_SHOWN_CHANGED,
CALENDAR_SELECTION_CHANGED,
TASKPAD_SELECTION_CHANGED,
+ MEMOPAD_SELECTION_CHANGED,
CALENDAR_FOCUS_CHANGE,
TASKPAD_FOCUS_CHANGE,
+ MEMOPAD_FOCUS_CHANGE,
GOTO_DATE,
SOURCE_ADDED,
SOURCE_REMOVED,
@@ -196,6 +208,7 @@ enum {
typedef enum {
FOCUS_CALENDAR,
FOCUS_TASKPAD,
+ FOCUS_MEMOPAD,
FOCUS_OTHER
} FocusLocation;
@@ -217,6 +230,8 @@ static void gnome_calendar_update_date_navigator (GnomeCalendar *gcal);
static void gnome_calendar_hpane_realized (GtkWidget *w, GnomeCalendar *gcal);
static void gnome_calendar_date_navigator_scrolled (GtkWidget *widget, GdkEventScroll *event, gpointer user_data);
static gboolean gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal);
+static void gnome_calendar_vpane_realized (GtkWidget *w, GnomeCalendar *gcal);
+static gboolean gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal);
static void gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem,
GnomeCalendar *gcal);
@@ -227,6 +242,7 @@ static void gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal);
static void update_query (GnomeCalendar *gcal);
static void update_todo_view (GnomeCalendar *gcal);
+static void update_memo_view (GnomeCalendar *gcal);
G_DEFINE_TYPE (GnomeCalendar, gnome_calendar, GTK_TYPE_VBOX)
@@ -264,6 +280,15 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
+ gnome_calendar_signals[MEMOPAD_SELECTION_CHANGED] =
+ gtk_signal_new ("memopad_selection_changed",
+ GTK_RUN_LAST,
+ G_TYPE_FROM_CLASS (object_class),
+ GTK_SIGNAL_OFFSET (GnomeCalendarClass, memopad_selection_changed),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+
+
gnome_calendar_signals[CALENDAR_FOCUS_CHANGE] =
gtk_signal_new ("calendar_focus_change",
GTK_RUN_FIRST,
@@ -282,6 +307,15 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
GTK_TYPE_NONE, 1,
GTK_TYPE_BOOL);
+ gnome_calendar_signals[MEMOPAD_FOCUS_CHANGE] =
+ gtk_signal_new ("memopad_focus_change",
+ GTK_RUN_FIRST,
+ G_TYPE_FROM_CLASS (object_class),
+ GTK_SIGNAL_OFFSET (GnomeCalendarClass, memopad_focus_change),
+ gtk_marshal_NONE__BOOL,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_BOOL);
+
gnome_calendar_signals[SOURCE_ADDED] =
g_signal_new ("source_added",
G_TYPE_FROM_CLASS (object_class),
@@ -331,8 +365,10 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
class->dates_shown_changed = NULL;
class->calendar_selection_changed = NULL;
class->taskpad_selection_changed = NULL;
+ class->memopad_selection_changed = NULL;
class->calendar_focus_change = NULL;
class->taskpad_focus_change = NULL;
+ class->memopad_focus_change = NULL;
class->source_added = NULL;
class->source_removed = NULL;
class->goto_date = gnome_calendar_goto_date;
@@ -647,14 +683,17 @@ static FocusLocation
get_focus_location (GnomeCalendar *gcal)
{
GnomeCalendarPrivate *priv;
- ETable *etable;
+ ETable *etable, *m_etable;
priv = gcal->priv;
etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo));
+ m_etable = e_memo_table_get_table (E_MEMO_TABLE (priv->memo));
if (GTK_WIDGET_HAS_FOCUS (etable->table_canvas))
return FOCUS_TASKPAD;
+ else if (GTK_WIDGET_HAS_FOCUS (m_etable->table_canvas))
+ return FOCUS_MEMOPAD;
else {
GtkWidget *widget;
EDayView *dv;
@@ -959,6 +998,19 @@ table_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer
}
static gint
+memo_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
+{
+ GnomeCalendar *gcal;
+
+ gcal = GNOME_CALENDAR (data);
+
+ gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals [MEMOPAD_FOCUS_CHANGE],
+ event->in ? TRUE : FALSE);
+
+ return FALSE;
+}
+
+static gint
calendar_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
{
GnomeCalendar *gcal;
@@ -1026,6 +1078,16 @@ table_selection_change_cb (ETable *etable, gpointer data)
}
static void
+memo_selection_change_cb (ETable *etable, gpointer data)
+{
+ GnomeCalendar *gcal;
+
+ gcal = GNOME_CALENDAR (data);
+
+ gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals[MEMOPAD_SELECTION_CHANGED]);
+}
+
+static void
set_week_start (GnomeCalendar *calendar)
{
GnomeCalendarPrivate *priv;
@@ -1137,6 +1199,41 @@ update_todo_view (GnomeCalendar *gcal)
}
static void
+update_memo_view (GnomeCalendar *gcal)
+{
+ GnomeCalendarPrivate *priv;
+ ECalModel *model, *view_model;
+ time_t start, end;
+ char *iso_start, *iso_end;
+
+ priv = gcal->priv;
+
+ /* Set the query on the memo pad*/
+ if (priv->memo_sexp) {
+ g_free (priv->memo_sexp);
+ }
+
+ model = e_memo_table_get_model (E_MEMO_TABLE (priv->memo));
+ view_model = e_calendar_view_get_model(priv->views[priv->current_view_type]);
+ e_cal_model_get_time_range (view_model, &start, &end);
+
+ if (start != -1 && end != -1) {
+ iso_start = isodate_from_time_t (start);
+ iso_end = isodate_from_time_t (end);
+
+ priv->memo_sexp = g_strdup_printf ("(and (occur-in-time-range? (make-time \"%s\")"
+ " (make-time \"%s\"))"
+ " %s)",
+ iso_start, iso_end,
+ priv->sexp ? priv->sexp : "");
+ e_cal_model_set_search_query (model, priv->memo_sexp);
+
+ g_free (iso_start);
+ g_free (iso_end);
+ }
+}
+
+static void
process_completed_tasks (GnomeCalendar *gcal, gboolean config_changed)
{
GnomeCalendarPrivate *priv;
@@ -1221,7 +1318,9 @@ setup_config (GnomeCalendar *calendar)
/* Pane positions */
priv->hpane_pos = calendar_config_get_hpane_pos ();
+ priv->vpane_pos = calendar_config_get_vpane_pos ();
priv->hpane_pos_month_view = calendar_config_get_month_hpane_pos ();
+ priv->vpane_pos_month_view = calendar_config_get_month_vpane_pos ();
}
static void
@@ -1307,6 +1406,8 @@ view_progress_cb (ECalModel *model, const char *message, int percent, ECalSource
e_calendar_view_set_status_message (E_CALENDAR_VIEW (gcal->priv->week_view), message, percent);
} else if (type == E_CAL_SOURCE_TYPE_TODO) {
e_calendar_table_set_status_message (E_CALENDAR_TABLE (gcal->priv->todo), message, percent);
+ } else if (type == E_CAL_SOURCE_TYPE_JOURNAL) {
+ e_memo_table_set_status_message (E_MEMO_TABLE (gcal->priv->memo), message);
}
}
@@ -1317,6 +1418,8 @@ view_done_cb (ECalModel *model, ECalendarStatus status, ECalSourceType type, Gno
e_calendar_view_set_status_message (E_CALENDAR_VIEW (gcal->priv->week_view), NULL, -1);
} else if (type == E_CAL_SOURCE_TYPE_TODO) {
e_calendar_table_set_status_message (E_CALENDAR_TABLE (gcal->priv->todo), NULL, -1);
+ } else if (type == E_CAL_SOURCE_TYPE_JOURNAL) {
+ e_memo_table_set_status_message (E_MEMO_TABLE (gcal->priv->memo), NULL);
}
}
@@ -1331,11 +1434,13 @@ static void
setup_widgets (GnomeCalendar *gcal)
{
GnomeCalendarPrivate *priv;
- GtkWidget *w;
+ GtkWidget *w, *sep;
gchar *filename;
ETable *etable;
GtkAdjustment *adjustment;
ECalModel *w_model;
+ GtkWidget *vbox;
+ GtkWidget *label;
int i;
priv = gcal->priv;
@@ -1384,12 +1489,34 @@ setup_widgets (GnomeCalendar *gcal)
G_CALLBACK (gnome_calendar_on_date_navigator_date_range_changed), gcal);
g_signal_connect (w, "scroll-event",
G_CALLBACK (gnome_calendar_date_navigator_scrolled), gcal);
+
+ /* The VPaned widget, to contain the ToDo list & Memo list */
+ priv->vpane = gtk_vpaned_new ();
+ g_signal_connect_after (priv->vpane, "realize",
+ G_CALLBACK(gnome_calendar_vpane_realized), gcal);
+ g_signal_connect (priv->vpane, "button_release_event",
+ G_CALLBACK (gnome_calendar_vpane_resized), gcal);
+ gtk_widget_show (priv->vpane);
+ gtk_paned_pack2 (GTK_PANED (priv->hpane), priv->vpane, TRUE, TRUE);
/* The ToDo list. */
+ vbox = gtk_vbox_new (FALSE, 0);
+ sep = gtk_hseparator_new ();
+ gtk_box_pack_start ((GtkBox *)vbox, sep, FALSE, TRUE, 0);
+
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup ((GtkLabel *)label, "<b> Tasks </b>");
+ gtk_box_pack_start ((GtkBox *)vbox, label, FALSE, TRUE, 0);
+
priv->todo = e_calendar_table_new ();
priv->todo_config = e_calendar_table_config_new (E_CALENDAR_TABLE (priv->todo));
- gtk_paned_pack2 (GTK_PANED (priv->hpane), priv->todo, TRUE, TRUE);
+ gtk_paned_pack1 (GTK_PANED (priv->vpane), vbox, FALSE, TRUE);
+ gtk_box_pack_end ((GtkBox *)vbox, priv->todo, TRUE, TRUE, 0);
+
gtk_widget_show (priv->todo);
+ gtk_widget_show (label);
+ gtk_widget_show (vbox);
+ gtk_widget_show (sep);
filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()),
"TaskPad", NULL);
@@ -1501,6 +1628,42 @@ setup_widgets (GnomeCalendar *gcal)
gtk_widget_show (GTK_WIDGET (priv->views[i]));
}
+ /* Memo view */
+ vbox = gtk_vbox_new (FALSE, 0);
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup ((GtkLabel *)label, "<b> Memos </b>");
+ gtk_box_pack_start ((GtkBox *)vbox, label, FALSE, TRUE, 0);
+ priv->memo = e_memo_table_new ();
+ priv->memo_config = e_memo_table_config_new (E_MEMO_TABLE (priv->memo));
+ gtk_paned_pack2 (GTK_PANED (priv->vpane), vbox, TRUE, TRUE);
+ gtk_box_pack_end ((GtkBox *)vbox, priv->memo, TRUE, TRUE, 0);
+
+ gtk_widget_show (priv->memo);
+ gtk_widget_show (label);
+ gtk_widget_show (vbox);
+
+ filename = g_build_filename (memos_component_peek_config_directory (memos_component_peek ()),
+ "MemoPad", NULL);
+ e_memo_table_load_state (E_MEMO_TABLE (priv->memo), filename);
+
+ update_memo_view (gcal);
+ g_free (filename);
+
+ etable = e_memo_table_get_table (E_MEMO_TABLE (priv->memo));
+ g_signal_connect (etable->table_canvas, "focus_in_event",
+ G_CALLBACK (memo_canvas_focus_change_cb), gcal);
+ g_signal_connect (etable->table_canvas, "focus_out_event",
+ G_CALLBACK (memo_canvas_focus_change_cb), gcal);
+
+ g_signal_connect (etable, "selection_change",
+ G_CALLBACK (memo_selection_change_cb), gcal);
+
+ g_signal_connect (e_memo_table_get_model ((EMemoTable *)priv->memo), "cal_view_progress",
+ G_CALLBACK (view_progress_cb), gcal);
+ g_signal_connect (e_memo_table_get_model ((EMemoTable *)priv->memo), "cal_view_done",
+ G_CALLBACK (view_done_cb), gcal);
+
+
/* make sure we set the initial time ranges for the views */
update_view_times (gcal, time (NULL));
gnome_calendar_update_date_navigator (gcal);
@@ -1530,10 +1693,12 @@ gnome_calendar_init (GnomeCalendar *gcal)
priv->calendar_menu = e_cal_menu_new("org.gnome.evolution.calendar.view");
priv->taskpad_menu = e_cal_menu_new("org.gnome.evolution.calendar.taskpad");
+ priv->memopad_menu = e_cal_menu_new ("org.gnome.evolution.calendar.memopad");
priv->dn_queries = NULL;
priv->sexp = g_strdup ("#t"); /* Match all */
priv->todo_sexp = g_strdup ("#t");
+ priv->memo_sexp = g_strdup ("#t");
priv->view_instance = NULL;
priv->view_menus = NULL;
@@ -1598,6 +1763,7 @@ gnome_calendar_destroy (GtkObject *object)
}
g_object_unref (priv->date_navigator_config);
g_object_unref (priv->todo_config);
+ g_object_unref (priv->memo_config);
for (l = priv->notifications; l; l = l->next)
calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
@@ -1609,6 +1775,12 @@ gnome_calendar_destroy (GtkObject *object)
"TaskPad", NULL);
e_calendar_table_save_state (E_CALENDAR_TABLE (priv->todo), filename);
g_free (filename);
+
+ /* Save the MemoPad layout. */
+ filename = g_build_filename (memos_component_peek_config_directory (memos_component_peek ()),
+ "MemoPad", NULL);
+ e_memo_table_save_state (E_MEMO_TABLE (priv->memo), filename);
+ g_free (filename);
if (priv->dn_queries) {
for (l = priv->dn_queries; l != NULL; l = l->next) {
@@ -1631,6 +1803,11 @@ gnome_calendar_destroy (GtkObject *object)
priv->todo_sexp = NULL;
}
+ if (priv->memo_sexp) {
+ g_free (priv->memo_sexp);
+ priv->memo_sexp = NULL;
+ }
+
if (priv->update_timeout) {
g_source_remove (priv->update_timeout);
priv->update_timeout = 0;
@@ -1661,6 +1838,11 @@ gnome_calendar_destroy (GtkObject *object)
priv->taskpad_menu = NULL;
}
+ if (priv->memopad_menu) {
+ g_object_unref (priv->memopad_menu);
+ priv->memopad_menu = NULL;
+ }
+
g_free (priv);
gcal->priv = NULL;
}
@@ -2321,8 +2503,10 @@ gnome_calendar_set_pane_positions (GnomeCalendar *gcal)
if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos_month_view);
+ gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos_month_view);
} else {
gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos);
+ gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos);
}
}
@@ -2349,6 +2533,8 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
case E_CAL_SOURCE_TYPE_TODO:
e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
break;
+ case E_CAL_SOURCE_TYPE_JOURNAL:
+ e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
default:
break;
}
@@ -2412,7 +2598,13 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
break;
-
+ case E_CAL_SOURCE_TYPE_JOURNAL:
+ msg = g_strdup_printf (_("Loading memos at %s"), e_cal_get_uri (ecal));
+ e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), msg);
+ g_free (msg);
+ e_cal_model_add_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), ecal);
+ e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
+ break;
default:
g_assert_not_reached ();
return;
@@ -2441,6 +2633,9 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar
case E_CAL_SOURCE_TYPE_TODO:
e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
break;
+ case E_CAL_SOURCE_TYPE_JOURNAL:
+ e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
+ break;
default:
break;
}
@@ -2488,7 +2683,9 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar
case E_CAL_SOURCE_TYPE_TODO:
e_cal_model_set_default_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)), ecal);
break;
-
+ case E_CAL_SOURCE_TYPE_JOURNAL:
+ e_cal_model_set_default_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), ecal);
+ break;
default:
break;
}
@@ -2516,6 +2713,9 @@ open_ecal (GnomeCalendar *gcal, ECal *cal, gboolean only_if_exists, open_func of
case E_CAL_SOURCE_TYPE_TODO :
e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), msg, -1);
break;
+ case E_CAL_SOURCE_TYPE_JOURNAL:
+ e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), msg);
+ break;
default:
g_assert_not_reached ();
break;
@@ -2584,7 +2784,14 @@ backend_died_cb (ECal *ecal, gpointer data)
gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals[SOURCE_REMOVED], source_type, source);
break;
+
+ case E_CAL_SOURCE_TYPE_JOURNAL:
+ id = "calendar:memos-crashed";
+
+ e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
+ gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals[SOURCE_REMOVED], source_type, source);
+ break;
default:
g_assert_not_reached ();
return;
@@ -2827,6 +3034,11 @@ gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_
model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
e_cal_model_remove_client (model, client);
break;
+
+ case E_CAL_SOURCE_TYPE_JOURNAL:
+ model = e_memo_table_get_model (E_MEMO_TABLE (priv->memo));
+ e_cal_model_remove_client (model, client);
+ break;
default:
g_assert_not_reached ();
@@ -3180,6 +3392,37 @@ gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gc
return FALSE;
}
+static void
+gnome_calendar_vpane_realized (GtkWidget *w, GnomeCalendar *gcal)
+{
+ GnomeCalendarPrivate *priv;
+
+ priv = gcal->priv;
+
+ if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
+ gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos_month_view);
+ } else {
+ gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos);
+ }
+}
+
+static gboolean
+gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal)
+{
+ GnomeCalendarPrivate *priv;
+
+ priv = gcal->priv;
+
+ if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
+ priv->vpane_pos_month_view = gtk_paned_get_position (GTK_PANED (priv->vpane));
+ calendar_config_set_month_vpane_pos (priv->vpane_pos_month_view);
+ } else {
+ priv->vpane_pos = gtk_paned_get_position (GTK_PANED (priv->vpane));
+ calendar_config_set_vpane_pos (priv->vpane_pos);
+ }
+
+ return FALSE;
+}
void
gnome_calendar_cut_clipboard (GnomeCalendar *gcal)
@@ -3195,6 +3438,8 @@ gnome_calendar_cut_clipboard (GnomeCalendar *gcal)
e_calendar_view_cut_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)));
} else if (location == FOCUS_TASKPAD)
e_calendar_table_cut_clipboard (E_CALENDAR_TABLE (priv->todo));
+ else if (location == FOCUS_MEMOPAD)
+ e_calendar_table_copy_clipboard (E_MEMO_TABLE (priv->memo));
}
void
@@ -3211,6 +3456,8 @@ gnome_calendar_copy_clipboard (GnomeCalendar *gcal)
e_calendar_view_copy_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)));
} else if (location == FOCUS_TASKPAD)
e_calendar_table_copy_clipboard (E_CALENDAR_TABLE (priv->todo));
+ else if (location == FOCUS_MEMOPAD)
+ e_calendar_table_copy_clipboard (E_MEMO_TABLE (priv->memo));
}
void
@@ -3227,6 +3474,8 @@ gnome_calendar_paste_clipboard (GnomeCalendar *gcal)
e_calendar_view_paste_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)));
} else if (location == FOCUS_TASKPAD)
e_calendar_table_paste_clipboard (E_CALENDAR_TABLE (priv->todo));
+ else if (location == FOCUS_MEMOPAD)
+ e_memo_table_paste_clipboard (E_MEMO_TABLE (priv->memo));
}
@@ -3267,6 +3516,7 @@ gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal)
gtk_signal_emit (GTK_OBJECT (gcal),
gnome_calendar_signals[DATES_SHOWN_CHANGED]);
}
+ update_memo_view (gcal);
}
@@ -3332,6 +3582,8 @@ gnome_calendar_delete_selection (GnomeCalendar *gcal)
e_calendar_view_delete_selected_events (E_CALENDAR_VIEW (view));
} else if (location == FOCUS_TASKPAD)
e_calendar_table_delete_selected (E_CALENDAR_TABLE (priv->todo));
+ else if (location == FOCUS_MEMOPAD)
+ e_memo_table_delete_selected (E_MEMO_TABLE (priv->memo));
}
void
@@ -3492,6 +3744,14 @@ ECalMenu *gnome_calendar_get_calendar_menu (GnomeCalendar *gcal)
return gcal->priv->calendar_menu;
}
+ECalMenu *gnome_calendar_get_memopad_menu (GnomeCalendar *gcal)
+{
+ g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
+
+ return gcal->priv->memopad_menu;
+}
+
+
void
gnome_calendar_edit_appointment (GnomeCalendar *gcal,
const char* src_uid,
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index f0b12507e1..de17acbf9e 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -86,9 +86,11 @@ struct _GnomeCalendarClass {
void (* calendar_selection_changed) (GnomeCalendar *gcal);
void (* taskpad_selection_changed) (GnomeCalendar *gcal);
+ void (* memopad_selection_changed) (GnomeCalendar *gcal);
void (* calendar_focus_change) (GnomeCalendar *gcal, gboolean in);
void (* taskpad_focus_change) (GnomeCalendar *gcal, gboolean in);
+ void (* memopad_focus_change) (GnomeCalendar *gcal, gboolean in);
void (* change_view) (GnomeCalendar *gcal,
GnomeCalendarViewType view_type);
@@ -139,6 +141,7 @@ GtkWidget *gnome_calendar_get_view_notebook_widget (GnomeCalendar *gcal);
struct _ECalMenu *gnome_calendar_get_taskpad_menu (GnomeCalendar *gcal);
struct _ECalMenu *gnome_calendar_get_calendar_menu (GnomeCalendar *gcal);
+struct _ECalMenu *gnome_calendar_get_memopad_menu (GnomeCalendar *gcal);
void gnome_calendar_setup_view_menus (GnomeCalendar *gcal, BonoboUIComponent *uic);
void gnome_calendar_discard_view_menus (GnomeCalendar *gcal);
diff --git a/calendar/gui/memos-component.c b/calendar/gui/memos-component.c
index 90bd9509b0..5eb8cc5c97 100644
--- a/calendar/gui/memos-component.c
+++ b/calendar/gui/memos-component.c
@@ -56,6 +56,7 @@
#include "calendar-component.h"
#define CREATE_MEMO_ID "memo"
+#define CREATE_SHARED_MEMO_ID "shared-memo"
#define CREATE_MEMO_LIST_ID "memo-list"
enum DndTargetType {
@@ -905,12 +906,19 @@ create_new_memo (MemosComponent *memo_component, gboolean is_assigned, MemosComp
ECal *ecal;
ECalComponent *comp;
MemoEditor *editor;
+ CompEditorFlags flags = 0;
ecal = setup_create_ecal (memo_component, component_view);
if (!ecal)
return FALSE;
- editor = memo_editor_new (ecal);
+ flags |= COMP_EDITOR_NEW_ITEM;
+ if (is_assigned) {
+ flags |= COMP_EDITOR_IS_SHARED;
+ flags |= COMP_EDITOR_USER_ORG;
+ }
+
+ editor = memo_editor_new (ecal, flags);
comp = cal_comp_memo_new_with_defaults (ecal);
comp_editor_edit_comp (COMP_EDITOR (editor), comp);
@@ -942,8 +950,9 @@ create_local_item_cb (EUserCreatableItemsHandler *handler, const char *item_type
if (strcmp (item_type_name, CREATE_MEMO_ID) == 0) {
create_new_memo (memos_component, FALSE, component_view);
- }
- else if (strcmp (item_type_name, CREATE_MEMO_LIST_ID) == 0) {
+ } else if (strcmp (item_type_name, CREATE_SHARED_MEMO_ID) == 0) {
+ create_new_memo (memos_component, TRUE, component_view);
+ } else if (strcmp (item_type_name, CREATE_MEMO_LIST_ID) == 0) {
calendar_setup_new_memo_list (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (component_view->memos))));
}
}
@@ -1145,7 +1154,7 @@ impl__get_userCreatableItems (PortableServer_Servant servant,
{
GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc ();
- list->_length = 2;
+ list->_length = 3;
list->_maximum = list->_length;
list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length);
@@ -1159,13 +1168,21 @@ impl__get_userCreatableItems (PortableServer_Servant servant,
list->_buffer[0].iconName = "stock_insert-note";
list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
- list->_buffer[1].id = CREATE_MEMO_LIST_ID;
- list->_buffer[1].description = _("New memo list");
- list->_buffer[1].menuDescription = _("Memo li_st");
- list->_buffer[1].tooltip = _("Create a new memo list");
- list->_buffer[1].menuShortcut = '\0';
- list->_buffer[1].iconName = "stock_notes";
- list->_buffer[1].type = GNOME_Evolution_CREATABLE_FOLDER;
+ list->_buffer[1].id = CREATE_SHARED_MEMO_ID;
+ list->_buffer[1].description = _("New shared memo");
+ list->_buffer[1].menuDescription = _("_Shared memo");
+ list->_buffer[1].tooltip = _("Create a shared new memo");
+ list->_buffer[1].menuShortcut = 's';
+ list->_buffer[1].iconName = "stock_insert-note";
+ list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT;
+
+ list->_buffer[2].id = CREATE_MEMO_LIST_ID;
+ list->_buffer[2].description = _("New memo list");
+ list->_buffer[2].menuDescription = _("Memo li_st");
+ list->_buffer[2].tooltip = _("Create a new memo list");
+ list->_buffer[2].menuShortcut = '\0';
+ list->_buffer[2].iconName = "stock_notes";
+ list->_buffer[2].type = GNOME_Evolution_CREATABLE_FOLDER;
return list;
}
@@ -1184,6 +1201,9 @@ impl_requestCreateItem (PortableServer_Servant servant,
else if (strcmp (item_type_name, CREATE_MEMO_LIST_ID) == 0) {
/* FIXME Should we use the last opened window? */
calendar_setup_new_memo_list (NULL);
+ } else if (strcmp (item_type_name, CREATE_SHARED_MEMO_ID) == 0) {
+ if (!create_new_memo (memos_component, TRUE, NULL))
+ bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
}
else {
bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType);