1 /*
2  *
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU Lesser General Public License as published by
5  * the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful, but
8  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
10  * for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public License
13  * along with this program; if not, see <http://www.gnu.org/licenses/>.
14  *
15  *
16  * Authors:
17  *		JP Rosevear <jpr@novell.com>
18  *
19  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
20  *
21  */
22 
23 #include "evolution-config.h"
24 
25 #include <string.h>
26 #include <libedataserver/libedataserver.h>
27 
28 #include "e-meeting-utils.h"
29 
30 gint
e_meeting_time_compare_times(EMeetingTime * time1,EMeetingTime * time2)31 e_meeting_time_compare_times (EMeetingTime *time1,
32                               EMeetingTime *time2)
33 {
34 	gint day_comparison;
35 
36 	day_comparison = g_date_compare (&time1->date, &time2->date);
37 
38 	if (day_comparison != 0)
39 		return day_comparison;
40 
41 	if (time1->hour < time2->hour)
42 		return -1;
43 	if (time1->hour > time2->hour)
44 		return 1;
45 
46 	if (time1->minute < time2->minute)
47 		return -1;
48 	if (time1->minute > time2->minute)
49 		return 1;
50 
51 	/* The start times are exactly the same. */
52 	return 0;
53 }
54 
55 void
e_meeting_xfb_data_init(EMeetingXfbData * xfb)56 e_meeting_xfb_data_init (EMeetingXfbData *xfb)
57 {
58 	g_return_if_fail (xfb != NULL);
59 
60 	xfb->summary = NULL;
61 	xfb->location = NULL;
62 }
63 
64 void
e_meeting_xfb_data_set(EMeetingXfbData * xfb,const gchar * summary,const gchar * location)65 e_meeting_xfb_data_set (EMeetingXfbData *xfb,
66                         const gchar *summary,
67                         const gchar *location)
68 {
69 	g_return_if_fail (xfb != NULL);
70 
71 	e_meeting_xfb_data_clear (xfb);
72 	xfb->summary = g_strdup (summary);
73 	xfb->location = g_strdup (location);
74 }
75 
76 void
e_meeting_xfb_data_clear(EMeetingXfbData * xfb)77 e_meeting_xfb_data_clear (EMeetingXfbData *xfb)
78 {
79 	g_return_if_fail (xfb != NULL);
80 
81 	/* clearing the contents of xfb,
82 	 * but not the xfb structure itself
83 	 */
84 
85 	g_clear_pointer (&xfb->summary, g_free);
86 	g_clear_pointer (&xfb->location, g_free);
87 }
88 
89 /* Creates an XFB string from a string property of a vfreebusy
90  * ICalProperty. The iCal string we read may be base64 encoded, but
91  * we get no reliable indication whether it really is. So we
92  * try to base64-decode, and failing that, assume the string
93  * is plain. The result is validated for UTF-8. We try to convert
94  * to UTF-8 from locale if the input is no valid UTF-8, and failing
95  * that, force the result into valid UTF-8. We also limit the
96  * length of the resulting string, since it gets displayed as a
97  * tooltip text in the meeting time selector.
98  */
99 gchar *
e_meeting_xfb_utf8_string_new_from_ical(const gchar * icalstring,gsize max_len)100 e_meeting_xfb_utf8_string_new_from_ical (const gchar *icalstring,
101                                          gsize max_len)
102 {
103 	gchar *tmp = NULL;
104 	gchar *utf8s = NULL;
105 	gsize in_len = 0;
106 	gsize out_len = 0;
107 	GError *tmp_err = NULL;
108 
109 	g_return_val_if_fail (max_len > 4, NULL);
110 
111 	if (icalstring == NULL)
112 		return NULL;
113 
114 	/* iCal does not carry charset hints, so we
115 	 * try UTF-8 first, then conversion using
116 	 * system locale info.
117 	 */
118 
119 	/* if we have valid UTF-8, we're done converting */
120 	if (g_utf8_validate (icalstring, -1, NULL))
121 		goto valid;
122 
123 	/* no valid UTF-8, trying to convert to it
124 	 * according to system locale
125 	 */
126 	tmp = g_locale_to_utf8 (
127 		icalstring, -1, &in_len, &out_len, &tmp_err);
128 
129 	if (tmp_err == NULL)
130 		goto valid;
131 
132 	g_warning ("%s: %s", G_STRFUNC, tmp_err->message);
133 	g_error_free (tmp_err);
134 	g_free (tmp);
135 
136 	/* still no success, forcing it into UTF-8, using
137 	 * replacement chars to replace invalid ones
138 	 */
139 	tmp = e_util_utf8_data_make_valid (
140 		icalstring, strlen (icalstring));
141  valid:
142 	if (tmp == NULL)
143 		tmp = g_strdup (icalstring);
144 
145 	/* now that we're (forcibly) valid UTF-8, we can
146 	 * limit the size of the UTF-8 string for display
147 	 */
148 
149 	if (g_utf8_strlen (tmp, -1) > (glong) max_len) {
150 		/* insert NULL termination to where we want to
151 		 * clip, take care to hit UTF-8 character boundary
152 		 */
153 		utf8s = g_utf8_offset_to_pointer (tmp, (glong) max_len - 4);
154 		*utf8s = '\0';
155 		/* create shortened UTF-8 string */
156 		utf8s = g_strdup_printf ("%s ...", tmp);
157 		g_free (tmp);
158 	} else {
159 		utf8s = tmp;
160 	}
161 
162 	return utf8s;
163 }
164