Line |
Branch |
Exec |
Source |
1 |
|
|
/* |
2 |
|
|
* Copyright (c) 2012 Giovanni Campagna <scampa.giovanni@gmail.com> |
3 |
|
|
* |
4 |
|
|
* The Control Center is free software; you can redistribute it and/or modify |
5 |
|
|
* it under the terms of the GNU General Public License as published by the |
6 |
|
|
* Free Software Foundation; either version 2 of the License, or (at your |
7 |
|
|
* option) any later version. |
8 |
|
|
* |
9 |
|
|
* The Control Center is distributed in the hope that it will be useful, but |
10 |
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
11 |
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 |
|
|
* for more details. |
13 |
|
|
* |
14 |
|
|
* You should have received a copy of the GNU General Public License along |
15 |
|
|
* with the Control Center; if not, write to the Free Software Foundation, |
16 |
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 |
|
|
* |
18 |
|
|
*/ |
19 |
|
|
|
20 |
|
|
#include "config.h" |
21 |
|
|
|
22 |
|
|
#include <string.h> |
23 |
|
|
#include <glib/gi18n.h> |
24 |
|
|
|
25 |
|
|
|
26 |
|
|
#include "cc-util.h" |
27 |
|
|
|
28 |
|
|
/* Combining diacritical mark? |
29 |
|
|
* Basic range: [0x0300,0x036F] |
30 |
|
|
* Supplement: [0x1DC0,0x1DFF] |
31 |
|
|
* For Symbols: [0x20D0,0x20FF] |
32 |
|
|
* Half marks: [0xFE20,0xFE2F] |
33 |
|
|
*/ |
34 |
|
|
#define IS_CDM_UCS4(c) (((c) >= 0x0300 && (c) <= 0x036F) || \ |
35 |
|
|
((c) >= 0x1DC0 && (c) <= 0x1DFF) || \ |
36 |
|
|
((c) >= 0x20D0 && (c) <= 0x20FF) || \ |
37 |
|
|
((c) >= 0xFE20 && (c) <= 0xFE2F)) |
38 |
|
|
|
39 |
|
|
#define IS_SOFT_HYPHEN(c) ((c) == 0x00AD) |
40 |
|
|
|
41 |
|
|
/* Copied from tracker/src/libtracker-fts/tracker-parser-glib.c under the GPL |
42 |
|
|
* And then from gnome-shell/src/shell-util.c |
43 |
|
|
* |
44 |
|
|
* Originally written by Aleksander Morgado <aleksander@gnu.org> |
45 |
|
|
*/ |
46 |
|
|
char * |
47 |
|
✗ |
cc_util_normalize_casefold_and_unaccent (const char *str) |
48 |
|
|
{ |
49 |
|
✗ |
g_autofree gchar *normalized = NULL; |
50 |
|
|
gchar *tmp; |
51 |
|
✗ |
int i = 0, j = 0, ilen; |
52 |
|
|
|
53 |
|
✗ |
if (str == NULL) |
54 |
|
✗ |
return NULL; |
55 |
|
|
|
56 |
|
✗ |
normalized = g_utf8_normalize (str, -1, G_NORMALIZE_NFKD); |
57 |
|
✗ |
tmp = g_utf8_casefold (normalized, -1); |
58 |
|
|
|
59 |
|
✗ |
ilen = strlen (tmp); |
60 |
|
|
|
61 |
|
✗ |
while (i < ilen) |
62 |
|
|
{ |
63 |
|
|
gunichar unichar; |
64 |
|
|
gchar *next_utf8; |
65 |
|
|
gint utf8_len; |
66 |
|
|
|
67 |
|
|
/* Get next character of the word as UCS4 */ |
68 |
|
✗ |
unichar = g_utf8_get_char_validated (&tmp[i], -1); |
69 |
|
|
|
70 |
|
|
/* Invalid UTF-8 character or end of original string. */ |
71 |
|
✗ |
if (unichar == (gunichar) -1 || |
72 |
|
|
unichar == (gunichar) -2) |
73 |
|
|
{ |
74 |
|
|
break; |
75 |
|
|
} |
76 |
|
|
|
77 |
|
|
/* Find next UTF-8 character */ |
78 |
|
✗ |
next_utf8 = g_utf8_next_char (&tmp[i]); |
79 |
|
✗ |
utf8_len = next_utf8 - &tmp[i]; |
80 |
|
|
|
81 |
|
✗ |
if (IS_CDM_UCS4 (unichar) || IS_SOFT_HYPHEN (unichar)) |
82 |
|
|
{ |
83 |
|
|
/* If the given unichar is a combining diacritical mark, |
84 |
|
|
* just update the original index, not the output one */ |
85 |
|
✗ |
i += utf8_len; |
86 |
|
✗ |
continue; |
87 |
|
|
} |
88 |
|
|
|
89 |
|
|
/* If already found a previous combining |
90 |
|
|
* diacritical mark, indexes are different so |
91 |
|
|
* need to copy characters. As output and input |
92 |
|
|
* buffers may overlap, need to use memmove |
93 |
|
|
* instead of memcpy */ |
94 |
|
✗ |
if (i != j) |
95 |
|
|
{ |
96 |
|
✗ |
memmove (&tmp[j], &tmp[i], utf8_len); |
97 |
|
|
} |
98 |
|
|
|
99 |
|
|
/* Update both indexes */ |
100 |
|
✗ |
i += utf8_len; |
101 |
|
✗ |
j += utf8_len; |
102 |
|
|
} |
103 |
|
|
|
104 |
|
|
/* Force proper string end */ |
105 |
|
✗ |
tmp[j] = '\0'; |
106 |
|
|
|
107 |
|
✗ |
return tmp; |
108 |
|
|
} |
109 |
|
|
|
110 |
|
|
char * |
111 |
|
✗ |
cc_util_get_smart_date (GDateTime *date) |
112 |
|
|
{ |
113 |
|
✗ |
g_autoptr(GDateTime) today = NULL; |
114 |
|
✗ |
g_autoptr(GDateTime) local = NULL; |
115 |
|
|
GTimeSpan span; |
116 |
|
|
|
117 |
|
✗ |
if (date == NULL) |
118 |
|
✗ |
return NULL; |
119 |
|
|
|
120 |
|
|
/* Set today date */ |
121 |
|
✗ |
local = g_date_time_new_now_local (); |
122 |
|
✗ |
today = g_date_time_new_local (g_date_time_get_year (local), |
123 |
|
|
g_date_time_get_month (local), |
124 |
|
|
g_date_time_get_day_of_month (local), |
125 |
|
|
0, 0, 0); |
126 |
|
|
|
127 |
|
✗ |
span = g_date_time_difference (today, date); |
128 |
|
✗ |
if (span <= 0) |
129 |
|
|
{ |
130 |
|
✗ |
return g_strdup (_("Today")); |
131 |
|
|
} |
132 |
|
✗ |
else if (span <= G_TIME_SPAN_DAY) |
133 |
|
|
{ |
134 |
|
✗ |
return g_strdup (_("Yesterday")); |
135 |
|
|
} |
136 |
|
|
else |
137 |
|
|
{ |
138 |
|
✗ |
if (g_date_time_get_year (date) == g_date_time_get_year (today)) |
139 |
|
|
{ |
140 |
|
|
/* Translators: This is a date format string in the style of "Feb 24". */ |
141 |
|
|
/* xgettext:no-c-format */ |
142 |
|
✗ |
return g_date_time_format (date, _("%b %e")); |
143 |
|
|
} |
144 |
|
|
else |
145 |
|
|
{ |
146 |
|
|
/* Translators: This is a date format string in the style of "Feb 24, 2013". */ |
147 |
|
✗ |
return g_date_time_format (date, _("%b %e, %Y")); |
148 |
|
|
} |
149 |
|
|
} |
150 |
|
|
} |
151 |
|
|
|
152 |
|
|
char * |
153 |
|
✗ |
cc_util_get_smart_date_time (GDateTime *date) |
154 |
|
|
{ |
155 |
|
✗ |
g_autofree gchar *date_str = NULL; |
156 |
|
✗ |
g_autofree gchar *smart_date = NULL; |
157 |
|
|
|
158 |
|
✗ |
if (date == NULL) |
159 |
|
✗ |
return NULL; |
160 |
|
|
|
161 |
|
✗ |
smart_date = cc_util_get_smart_date (date); |
162 |
|
✗ |
date_str = g_date_time_format (date, "\%X"); |
163 |
|
|
/* TRANSLATORS: This is the datetime format in the style of |
164 |
|
|
"Aug 1, 10:10:10 PM", "Feb 24, 2013, 10:10:10 PM", "Today, 10:10:10 AM", |
165 |
|
|
and "Yesterday, 10:10:10 AM" */ |
166 |
|
✗ |
return g_strdup_printf (_("%1$s, %2$s"), smart_date, date_str); |
167 |
|
|
} |
168 |
|
|
|
169 |
|
|
/* Copied from src/plugins/properties/bacon-video-widget-properties.c |
170 |
|
|
* in totem */ |
171 |
|
|
char * |
172 |
|
✗ |
cc_util_time_to_string_text (gint64 msecs) |
173 |
|
|
{ |
174 |
|
✗ |
g_autofree gchar *hours = NULL; |
175 |
|
✗ |
g_autofree gchar *mins = NULL; |
176 |
|
✗ |
g_autofree gchar *secs = NULL; |
177 |
|
|
gint sec, min, hour, _time; |
178 |
|
|
|
179 |
|
✗ |
_time = (int) (msecs / 1000); |
180 |
|
✗ |
sec = _time % 60; |
181 |
|
✗ |
_time = _time - sec; |
182 |
|
✗ |
min = (_time % (60*60)) / 60; |
183 |
|
✗ |
_time = _time - (min * 60); |
184 |
|
✗ |
hour = _time / (60*60); |
185 |
|
|
|
186 |
|
✗ |
hours = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d hour", "%d hours", hour), hour); |
187 |
|
✗ |
mins = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d minute", "%d minutes", min), min); |
188 |
|
✗ |
secs = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d second", "%d seconds", sec), sec); |
189 |
|
|
|
190 |
|
✗ |
if (hour > 0) |
191 |
|
|
{ |
192 |
|
✗ |
if (min > 0 && sec > 0) |
193 |
|
|
{ |
194 |
|
|
/* 5 hours 2 minutes 12 seconds */ |
195 |
|
✗ |
return g_strdup_printf (C_("hours minutes seconds", "%s %s %s"), hours, mins, secs); |
196 |
|
|
} |
197 |
|
✗ |
else if (min > 0) |
198 |
|
|
{ |
199 |
|
|
/* 5 hours 2 minutes */ |
200 |
|
✗ |
return g_strdup_printf (C_("hours minutes", "%s %s"), hours, mins); |
201 |
|
|
} |
202 |
|
|
else |
203 |
|
|
{ |
204 |
|
|
/* 5 hours */ |
205 |
|
✗ |
return g_strdup_printf (C_("hours", "%s"), hours); |
206 |
|
|
} |
207 |
|
|
} |
208 |
|
✗ |
else if (min > 0) |
209 |
|
|
{ |
210 |
|
✗ |
if (sec > 0) |
211 |
|
|
{ |
212 |
|
|
/* 2 minutes 12 seconds */ |
213 |
|
✗ |
return g_strdup_printf (C_("minutes seconds", "%s %s"), mins, secs); |
214 |
|
|
} |
215 |
|
|
else |
216 |
|
|
{ |
217 |
|
|
/* 2 minutes */ |
218 |
|
✗ |
return g_strdup_printf (C_("minutes", "%s"), mins); |
219 |
|
|
} |
220 |
|
|
} |
221 |
|
✗ |
else if (sec > 0) |
222 |
|
|
{ |
223 |
|
|
/* 10 seconds */ |
224 |
|
✗ |
return g_strdup (secs); |
225 |
|
|
} |
226 |
|
|
else |
227 |
|
|
{ |
228 |
|
|
/* 0 seconds */ |
229 |
|
✗ |
return g_strdup (_("0 seconds")); |
230 |
|
|
} |
231 |
|
|
} |
232 |
|
|
|