GCC Code Coverage Report


Directory: ./
File: panels/common/cc-util.c
Date: 2024-05-04 07:58:27
Exec Total Coverage
Lines: 0 71 0.0%
Functions: 0 4 0.0%
Branches: 0 52 0.0%

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