aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'calendar')
-rw-r--r--calendar/ChangeLog23
-rw-r--r--calendar/gui/Makefile.am2
-rw-r--r--calendar/gui/comp-util.c72
-rw-r--r--calendar/gui/comp-util.h11
-rw-r--r--calendar/gui/dialogs/comp-editor.c2
-rw-r--r--calendar/gui/dialogs/delete-comp.c11
-rw-r--r--calendar/gui/dialogs/delete-comp.h1
-rw-r--r--calendar/gui/e-calendar-table.c3
-rw-r--r--calendar/gui/e-day-view.c48
-rw-r--r--calendar/gui/e-week-view.c58
-rw-r--r--calendar/gui/misc.c60
-rw-r--r--calendar/gui/misc.h29
12 files changed, 306 insertions, 14 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index d57bffcc59..ab973ec6d1 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,26 @@
+2001-10-27 Federico Mena Quintero <federico@ximian.com>
+
+ * gui/e-day-view.c (e_day_view_on_editing_stopped): Delete
+ appointments with empty summaries. Fixes Ximian bug #780.
+
+ * gui/e-week-view.c (e_week_view_on_editing_stopped): Likewise.
+
+ * gui/dialogs/delete-comp.c (delete_component_dialog): Added an
+ argument to specify whether we unconditionally want single
+ components to be considered as not having a summary.
+
+ * gui/comp-util.c (cal_comp_confirm_delete_empty_comp): New
+ function.
+
+ * gui/misc.[ch]: New files with miscellaneous utility functions;
+ moved string_is_empty() over from calendar-model.c.
+
+ * gui/calendar-model.c: Use the string_is_empty()
+ function from misc.c.
+
+ * gui/Makefile.am (evolution_calendar_SOURCES): Added misc.[ch] to
+ the list of sources.
+
2001-10-27 JP Rosevear <jpr@ximian.com>
* conduits/todo/todo-conduit.c (local_record_from_comp): touch on
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 1a155efcd7..7a22f6abc7 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -142,6 +142,8 @@ evolution_calendar_SOURCES = \
itip-utils.c \
itip-utils.h \
main.c \
+ misc.c \
+ misc.h \
print.c \
print.h \
tag-calendar.c \
diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c
index 808d9be910..71efec2573 100644
--- a/calendar/gui/comp-util.c
+++ b/calendar/gui/comp-util.c
@@ -24,6 +24,7 @@
#endif
#include "comp-util.h"
+#include "dialogs/delete-comp.h"
@@ -159,3 +160,74 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
return retval;
}
+
+/**
+ * cal_comp_confirm_delete_empty_comp:
+ * @comp: A calendar component.
+ * @client: Calendar client where the component purportedly lives.
+ * @widget: Widget to be used as the basis for UTF8 conversion.
+ *
+ * Assumming a calendar component with an empty SUMMARY property (as per
+ * string_is_empty()), asks whether the user wants to delete it based on
+ * whether the appointment is on the calendar server or not. If the
+ * component is on the server, this function will present a confirmation
+ * dialog and delete the component if the user tells it to. If the component
+ * is not on the server it will just return TRUE.
+ *
+ * Return value: A result code indicating whether the component
+ * was not on the server and is to be deleted locally, whether it
+ * was on the server and the user deleted it, or whether the
+ * user cancelled the deletion.
+ **/
+ConfirmDeleteEmptyCompResult
+cal_comp_confirm_delete_empty_comp (CalComponent *comp, CalClient *client, GtkWidget *widget)
+{
+ const char *uid;
+ CalClientGetStatus status;
+ CalComponent *server_comp;
+
+ g_return_val_if_fail (comp != NULL, EMPTY_COMP_DO_NOT_REMOVE);
+ g_return_val_if_fail (IS_CAL_COMPONENT (comp), EMPTY_COMP_DO_NOT_REMOVE);
+ g_return_val_if_fail (client != NULL, EMPTY_COMP_DO_NOT_REMOVE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), EMPTY_COMP_DO_NOT_REMOVE);
+ g_return_val_if_fail (widget != NULL, EMPTY_COMP_DO_NOT_REMOVE);
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), EMPTY_COMP_DO_NOT_REMOVE);
+
+ /* See if the component is on the server. If it is not, then it likely
+ * means that the appointment is new, only in the day view, and we
+ * haven't added it yet to the server. In that case, we don't need to
+ * confirm and we can just delete the event. Otherwise, we ask
+ * the user.
+ */
+ cal_component_get_uid (comp, &uid);
+
+ status = cal_client_get_object (client, uid, &server_comp);
+
+ switch (status) {
+ case CAL_CLIENT_GET_SUCCESS:
+ gtk_object_unref (GTK_OBJECT (server_comp));
+ /* Will handle confirmation below */
+ break;
+
+ case CAL_CLIENT_GET_SYNTAX_ERROR:
+ g_message ("confirm_delete_empty_appointment(): Syntax error when getting "
+ "object `%s'",
+ uid);
+ /* However, the object *is* in the server, so confirm */
+ break;
+
+ case CAL_CLIENT_GET_NOT_FOUND:
+ return EMPTY_COMP_REMOVE_LOCALLY;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ /* The event exists in the server, so confirm whether to delete it */
+
+ if (delete_component_dialog (comp, TRUE, 1, CAL_COMPONENT_EVENT, widget)) {
+ cal_client_remove_object (client, uid);
+ return EMPTY_COMP_REMOVED_FROM_SERVER;
+ } else
+ return EMPTY_COMP_DO_NOT_REMOVE;
+}
diff --git a/calendar/gui/comp-util.h b/calendar/gui/comp-util.h
index 6ea71853fa..b8c3ea453d 100644
--- a/calendar/gui/comp-util.h
+++ b/calendar/gui/comp-util.h
@@ -22,6 +22,7 @@
#ifndef COMP_UTIL_H
#define COMP_UTIL_H
+#include <gtk/gtkwidget.h>
#include <cal-util/cal-component.h>
#include <cal-client/cal-client.h>
@@ -35,4 +36,14 @@ gboolean cal_comp_util_compare_event_timezones (CalComponent *comp,
CalClient *client,
icaltimezone *zone);
+typedef enum {
+ EMPTY_COMP_REMOVE_LOCALLY,
+ EMPTY_COMP_REMOVED_FROM_SERVER,
+ EMPTY_COMP_DO_NOT_REMOVE
+} ConfirmDeleteEmptyCompResult;
+
+ConfirmDeleteEmptyCompResult cal_comp_confirm_delete_empty_comp (CalComponent *comp,
+ CalClient *client,
+ GtkWidget *widget);
+
#endif
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index 8d16df97f9..dc7d01cbde 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -1121,7 +1121,7 @@ delete_cmd (GtkWidget *widget, gpointer data)
vtype = cal_component_get_vtype (priv->comp);
- if (delete_component_dialog (priv->comp, 1, vtype, priv->window))
+ if (delete_component_dialog (priv->comp, FALSE, 1, vtype, priv->window))
delete_comp (editor);
}
diff --git a/calendar/gui/dialogs/delete-comp.c b/calendar/gui/dialogs/delete-comp.c
index 2dcfc5c47a..1fc757c38c 100644
--- a/calendar/gui/dialogs/delete-comp.c
+++ b/calendar/gui/dialogs/delete-comp.c
@@ -38,6 +38,9 @@
* delete_component_dialog:
* @comp: A calendar component if a single component is to be deleted, or NULL
* if more that one component is to be deleted.
+ * @consider_as_untitled: If deleting more than one component, this is ignored.
+ * Otherwise, whether to consider the component as not having a summary; if
+ * FALSE then the component's summary string will be used.
* @n_comps: Number of components that are to be deleted.
* @vtype: Type of the components that are to be deleted. This is ignored
* if only one component is to be deleted, and the vtype is extracted from
@@ -55,6 +58,7 @@
**/
gboolean
delete_component_dialog (CalComponent *comp,
+ gboolean consider_as_untitled,
int n_comps, CalComponentVType vtype,
GtkWidget *widget)
{
@@ -80,9 +84,12 @@ delete_component_dialog (CalComponent *comp,
char *tmp;
vtype = cal_component_get_vtype (comp);
- cal_component_get_summary (comp, &summary);
- tmp = e_utf8_to_gtk_string (widget, summary.value);
+ if (!consider_as_untitled) {
+ cal_component_get_summary (comp, &summary);
+ tmp = e_utf8_to_gtk_string (widget, summary.value);
+ } else
+ tmp = NULL;
switch (vtype) {
case CAL_COMPONENT_EVENT:
diff --git a/calendar/gui/dialogs/delete-comp.h b/calendar/gui/dialogs/delete-comp.h
index 3c352a9bc8..64945b5bee 100644
--- a/calendar/gui/dialogs/delete-comp.h
+++ b/calendar/gui/dialogs/delete-comp.h
@@ -25,6 +25,7 @@
#include <cal-util/cal-component.h>
gboolean delete_component_dialog (CalComponent *comp,
+ gboolean consider_as_untitled,
int n_comps, CalComponentVType vtype,
GtkWidget *widget);
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index 7481848d9e..3dd04df9c2 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -764,7 +764,8 @@ e_calendar_table_delete_selected (ECalendarTable *cal_table)
/* FIXME: this may be something other than a TODO component */
- if (delete_component_dialog (comp, n_selected, CAL_COMPONENT_TODO, GTK_WIDGET (cal_table)))
+ if (delete_component_dialog (comp, FALSE, n_selected, CAL_COMPONENT_TODO,
+ GTK_WIDGET (cal_table)))
delete_selected_components (cal_table);
}
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index 51e78b279f..38ae21668f 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -57,6 +57,7 @@
#include "e-day-view-top-item.h"
#include "e-day-view-layout.h"
#include "e-day-view-main-item.h"
+#include "misc.h"
/* Images */
#include "art/bell.xpm"
@@ -3654,7 +3655,7 @@ e_day_view_delete_event_internal (EDayView *day_view, EDayViewEvent *event)
vtype = cal_component_get_vtype (event->comp);
- if (delete_component_dialog (event->comp, 1, vtype,
+ if (delete_component_dialog (event->comp, FALSE, 1, vtype,
GTK_WIDGET (day_view))) {
const char *uid;
@@ -5607,7 +5608,6 @@ e_day_view_on_editing_started (EDayView *day_view,
e_day_view_signals[SELECTION_CHANGED]);
}
-
static void
e_day_view_on_editing_stopped (EDayView *day_view,
GnomeCanvasItem *item)
@@ -5658,6 +5658,48 @@ e_day_view_on_editing_stopped (EDayView *day_view,
NULL);
g_assert (text != NULL);
+ if (string_is_empty (text)) {
+ ConfirmDeleteEmptyCompResult result;
+
+ result = cal_comp_confirm_delete_empty_comp (event->comp, day_view->client,
+ GTK_WIDGET (day_view));
+
+ switch (result) {
+ case EMPTY_COMP_REMOVE_LOCALLY: {
+ const char *uid;
+
+ cal_component_get_uid (event->comp, &uid);
+
+ e_day_view_foreach_event_with_uid (day_view, uid,
+ e_day_view_remove_event_cb, NULL);
+ e_day_view_check_layout (day_view);
+ gtk_widget_queue_draw (day_view->top_canvas);
+ gtk_widget_queue_draw (day_view->main_canvas);
+ goto out; }
+
+ case EMPTY_COMP_REMOVED_FROM_SERVER:
+ goto out;
+
+ case EMPTY_COMP_DO_NOT_REMOVE:
+ /* But we cannot keep an empty summary, so make the
+ * canvas item refresh itself from the text that the
+ * component already had.
+ */
+
+ if (day == E_DAY_VIEW_LONG_EVENT)
+ e_day_view_reshape_long_event (day_view, event_num);
+ else
+ e_day_view_update_event_label (day_view, day, event_num);
+
+ goto out;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ }
+
/* Only update the summary if necessary. */
cal_component_get_summary (event->comp, &summary);
if (summary.value && !strcmp (text, summary.value)) {
@@ -5675,6 +5717,8 @@ e_day_view_on_editing_stopped (EDayView *day_view,
g_message ("e_day_view_on_editing_stopped(): Could not update the object!");
}
+ out:
+
g_free (text);
gtk_signal_emit (GTK_OBJECT (day_view),
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index cf50604760..9b2a9fa40a 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -57,6 +57,7 @@
#include "e-week-view-layout.h"
#include "e-week-view-main-item.h"
#include "e-week-view-titles-item.h"
+#include "misc.h"
/* Images */
#include "art/bell.xpm"
@@ -1254,7 +1255,7 @@ e_week_view_set_cal_client (EWeekView *week_view,
* e_week_view_set_query:
* @week_view: A week view.
* @sexp: S-expression that defines the query.
- *
+ *
* Sets the query sexp that the week view will use for filtering the displayed
* events.
**/
@@ -1278,7 +1279,7 @@ e_week_view_set_query (EWeekView *week_view, const char *sexp)
* e_week_view_set_default_category:
* @week_view: A week view.
* @category: Default category name or NULL for no category.
- *
+ *
* Sets the default category that will be used when creating new calendar
* components from the week view.
**/
@@ -3073,6 +3074,45 @@ e_week_view_on_editing_stopped (EWeekView *week_view,
NULL);
g_assert (text != NULL);
+ if (string_is_empty (text)) {
+ ConfirmDeleteEmptyCompResult result;
+
+ result = cal_comp_confirm_delete_empty_comp (event->comp, week_view->client,
+ GTK_WIDGET (week_view));
+
+ switch (result) {
+ case EMPTY_COMP_REMOVE_LOCALLY: {
+ const char *uid;
+
+ cal_component_get_uid (event->comp, &uid);
+
+ e_week_view_foreach_event_with_uid (week_view, uid,
+ e_week_view_remove_event_cb, NULL);
+ gtk_widget_queue_draw (week_view->main_canvas);
+ e_week_view_check_layout (week_view);
+ goto out; }
+
+ case EMPTY_COMP_REMOVED_FROM_SERVER:
+ goto out;
+
+ case EMPTY_COMP_DO_NOT_REMOVE:
+ /* But we cannot keep an empty summary, so make the
+ * canvas item refresh itself from the text that the
+ * component already had.
+ */
+
+ gtk_object_ref (GTK_OBJECT (event->comp));
+ e_week_view_update_event_cb (week_view, event_num, event->comp);
+ gtk_object_unref (GTK_OBJECT (event->comp));
+ goto out;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ }
+
/* Only update the summary if necessary. */
cal_component_get_summary (event->comp, &summary);
if (summary.value && !strcmp (text, summary.value)) {
@@ -3088,6 +3128,8 @@ e_week_view_on_editing_stopped (EWeekView *week_view,
g_message ("e_week_view_on_editing_stopped(): Could not update the object!");
}
+ out:
+
g_free (text);
gtk_signal_emit (GTK_OBJECT (week_view),
@@ -3351,7 +3393,7 @@ static EPopupMenu child_items [] = {
e_week_view_on_delete_occurrence, NULL, MASK_RECURRING | MASK_EDITING },
{ N_("Delete _All Occurrences"), NULL,
e_week_view_on_delete_appointment, NULL, MASK_RECURRING | MASK_EDITING },
-
+
{ NULL, NULL, NULL, NULL, 0 }
};
@@ -3375,14 +3417,14 @@ e_week_view_show_popup_menu (EWeekView *week_view,
* We could possibly set up another method of checking it.
*/
being_edited = FALSE;
-
+
if (event_num == -1) {
context_menu = main_items;
} else {
context_menu = child_items;
event = &g_array_index (week_view->events,
EWeekViewEvent, event_num);
- if (cal_component_has_recurrences (event->comp))
+ if (cal_component_has_recurrences (event->comp))
hide_mask |= MASK_SINGLE;
else
hide_mask |= MASK_RECURRING;
@@ -3401,7 +3443,7 @@ e_week_view_on_new_appointment (GtkWidget *widget, gpointer data)
EWeekView *week_view = E_WEEK_VIEW (data);
time_t dtstart, dtend;
struct icaltimetype itt;
-
+
/* Edit a new event. If only one day is selected we set the time to
the first 1/2-hour of the working day. */
if (week_view->selection_start_day == week_view->selection_end_day) {
@@ -3428,7 +3470,7 @@ e_week_view_on_new_event (GtkWidget *widget, gpointer data)
{
EWeekView *week_view = E_WEEK_VIEW (data);
time_t dtstart, dtend;
-
+
dtstart = week_view->day_starts[week_view->selection_start_day];
dtend = week_view->day_starts[week_view->selection_end_day + 1];
gnome_calendar_new_appointment_for (
@@ -3511,7 +3553,7 @@ e_week_view_delete_event_internal (EWeekView *week_view, gint event_num)
vtype = cal_component_get_vtype (event->comp);
- if (delete_component_dialog (event->comp, 1, vtype,
+ if (delete_component_dialog (event->comp, FALSE, 1, vtype,
GTK_WIDGET (week_view))) {
const char *uid;
diff --git a/calendar/gui/misc.c b/calendar/gui/misc.c
new file mode 100644
index 0000000000..9f9aa77296
--- /dev/null
+++ b/calendar/gui/misc.c
@@ -0,0 +1,60 @@
+/* Evolution calendar - Miscellaneous utility functions
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Authors: Federico Mena-Quintero <federico@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include "misc.h"
+
+
+
+/**
+ * string_is_empty:
+ * @value: A string.
+ *
+ * Returns whether a string is NULL, the empty string, or completely made up of
+ * whitespace characters.
+ *
+ * Return value: TRUE if the string is empty, FALSE otherwise.
+ **/
+gboolean
+string_is_empty (const char *value)
+{
+ const char *p;
+ gboolean empty;
+
+ empty = TRUE;
+
+ if (value) {
+ p = value;
+ while (*p) {
+ if (!isspace ((unsigned char) *p)) {
+ empty = FALSE;
+ break;
+ }
+ p++;
+ }
+ }
+ return empty;
+
+}
diff --git a/calendar/gui/misc.h b/calendar/gui/misc.h
new file mode 100644
index 0000000000..8f4864a174
--- /dev/null
+++ b/calendar/gui/misc.h
@@ -0,0 +1,29 @@
+/* Evolution calendar - Miscellaneous utility functions
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Authors: Federico Mena-Quintero <federico@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MISC_H
+#define MISC_H
+
+#include <glib.h>
+
+gboolean string_is_empty (const char *value);
+
+#endif