1 /**
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * E-mail : see the 'copyright' file.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include <string.h>
22 #include <math.h>
23 #include <libxml/tree.h>
24 #include <libxml/parser.h>
25
26 #include <cairo-dock.h>
27 #include "applet-struct.h"
28 #include "applet-xml.h"
29 #include "applet-draw.h"
30
31
cd_doncky_free_item(TextZone * pTextZone)32 void cd_doncky_free_item (TextZone *pTextZone)
33 {
34 if (pTextZone == NULL)
35 return;
36
37 g_free (pTextZone->cFont);
38 g_free (pTextZone->cText);
39 g_free (pTextZone->cCommand);
40 g_free (pTextZone->cResult);
41 g_free (pTextZone->cAlignWidth);
42 g_free (pTextZone->cAlignHeight);
43 g_free (pTextZone->cImgPath);
44 g_free (pTextZone->cMountPoint);
45 if (pTextZone->pImgSurface)
46 cairo_surface_destroy (pTextZone->pImgSurface);
47 g_free (pTextZone);
48 }
49
50
cd_doncky_free_item_list(GldiModuleInstance * myApplet)51 void cd_doncky_free_item_list (GldiModuleInstance *myApplet)
52 {
53 if (myData.pTextZoneList == NULL)
54 return;
55
56 TextZone *pTextZone;
57 GList *t;
58 for (t = myData.pTextZoneList; t != NULL; t = t->next)
59 {
60 pTextZone= t->data;
61 cd_doncky_free_item (pTextZone);
62 }
63 g_list_free (myData.pTextZoneList);
64 myData.pTextZoneList = NULL;
65 }
66
_Get_FilePath(GldiModuleInstance * myApplet,const gchar * cXmlString)67 gchar *_Get_FilePath (GldiModuleInstance *myApplet, const gchar *cXmlString)
68 {
69 gchar *cString = (gchar *) cXmlString;
70 gchar *cReturn;
71 if (*cString == '~')
72 cReturn = g_strdup_printf ("%s%s", getenv("HOME"), cString+1);
73 else if (*cString == '/')
74 cReturn = g_strdup (cString);
75 else
76 {
77 if (g_str_has_suffix (cString, ".sh")
78 || g_str_has_suffix (cString, ".py")
79 || g_str_has_suffix (cString, ".png")
80 || g_str_has_suffix (cString, ".PNG")
81 || g_str_has_suffix (cString, ".jpg")
82 || g_str_has_suffix (cString, ".JPG")
83 || g_str_has_suffix (cString, ".jpeg")
84 || g_str_has_suffix (cString, ".JPEG")
85 || g_str_has_suffix (cString, ".svg")
86 || g_str_has_suffix (cString, ".SVG"))
87 {
88 cReturn = g_strdup_printf("%s%s", myData.cThemeFolder, cString);
89 }
90 else
91 cReturn = g_strdup (cString);
92 }
93 return cReturn;
94 }
95
96
cd_doncky_readxml(GldiModuleInstance * myApplet)97 gboolean cd_doncky_readxml (GldiModuleInstance *myApplet)
98 {
99 // On va lire le contenu de myConfig.cXmlFilePath
100 cd_debug ("Doncky-debug : ----------------------> myConfig.cXmlFilePath = \"%s\"",myConfig.cXmlFilePath);
101
102 g_return_val_if_fail (myConfig.cXmlFilePath != NULL, FALSE);
103 xmlInitParser ();
104 xmlDocPtr pXmlFile;
105 xmlNodePtr pXmlMainNode;
106
107 pXmlFile = cairo_dock_open_xml_file (myConfig.cXmlFilePath, "doncky", &pXmlMainNode, NULL);
108
109 g_return_val_if_fail (pXmlFile != NULL && pXmlMainNode != NULL, FALSE);
110
111 xmlChar *cNodeContent;
112 TextZone *pTextZone = NULL;
113
114 xmlNodePtr pXmlNode;
115
116 myData.cPrevFont = g_strdup (myConfig.cDefaultFont);
117 myData.cPrevAlignWidth = g_strdup_printf("left");
118 myData.cPrevAlignHeight = g_strdup_printf("middle");
119 myData.fPrevTextColor[0] = myConfig.fDefaultTextColor[0];
120 myData.fPrevTextColor[1] = myConfig.fDefaultTextColor[1];
121 myData.fPrevTextColor[2] = myConfig.fDefaultTextColor[2];
122 myData.fPrevTextColor[3] = myConfig.fDefaultTextColor[3];
123
124 // Récupération de myData.cThemeFolder et myData.cXmlFileName:
125 myData.cThemeFolder = g_path_get_dirname (myConfig.cXmlFilePath);
126 myData.cXmlFileName = g_path_get_basename (myConfig.cXmlFilePath);
127
128 int i;
129 for (pXmlNode = pXmlMainNode->children, i = 0; pXmlNode != NULL; pXmlNode = pXmlNode->next, i ++)
130 {
131 gchar *cContent = (gchar *)xmlNodeGetContent (pXmlNode);
132 if (xmlStrcmp (pXmlNode->name, BAD_CAST "font") == 0)
133 {
134 g_free (myData.cPrevFont);
135 myData.cPrevFont = (gchar *)xmlNodeGetContent (pXmlNode);
136 if (strcmp (myData.cPrevFont, "default") == 0)
137 {
138 g_free (myData.cPrevFont);
139 myData.cPrevFont = g_strdup (myConfig.cDefaultFont);
140 }
141 }
142
143 else if (xmlStrcmp (pXmlNode->name, BAD_CAST "color") == 0)
144 {
145 if (strcmp (cContent, "default") == 0)
146 {
147 myData.fPrevTextColor[0] = myConfig.fDefaultTextColor[0];
148 myData.fPrevTextColor[1] = myConfig.fDefaultTextColor[1];
149 myData.fPrevTextColor[2] = myConfig.fDefaultTextColor[2];
150 myData.fPrevTextColor[3] = myConfig.fDefaultTextColor[3];
151 }
152 else
153 {
154 cd_doncky_get_color_from_xml (cContent, myData.fPrevTextColor);
155 }
156 }
157
158 else if (xmlStrcmp (pXmlNode->name, BAD_CAST "alignW") == 0)
159 {
160 g_free (myData.cPrevAlignWidth);
161 myData.cPrevAlignWidth = (gchar *) xmlNodeGetContent (pXmlNode);
162 if (strcmp (myData.cPrevAlignWidth, "left") == -1 && strcmp (myData.cPrevAlignWidth, "center") == -1 && strcmp (myData.cPrevAlignWidth, "right") == -1)
163 myData.cPrevAlignWidth = g_strdup_printf("right");
164 }
165 else if (xmlStrcmp (pXmlNode->name, BAD_CAST "alignH") == 0)
166 {
167 g_free (myData.cPrevAlignHeight);
168 myData.cPrevAlignHeight = (gchar *) xmlNodeGetContent (pXmlNode);
169 if (strcmp (myData.cPrevAlignHeight, "top") == -1 && strcmp (myData.cPrevAlignHeight, "middle") == -1 && strcmp (myData.cPrevAlignHeight, "low") == -1)
170 myData.cPrevAlignWidth = g_strdup_printf("middle");
171 }
172
173 else if (xmlStrcmp (pXmlNode->name, BAD_CAST "br") == 0 || xmlStrcmp (pXmlNode->name, BAD_CAST "nbr") == 0)
174 {
175 pTextZone = g_new0 (TextZone, 1);
176 myData.pTextZoneList = g_list_append (myData.pTextZoneList, pTextZone);
177
178 pTextZone->cFont = g_strdup (myData.cPrevFont);
179 pTextZone->fTextColor[0] = myData.fPrevTextColor[0];
180 pTextZone->fTextColor[1] = myData.fPrevTextColor[1];
181 pTextZone->fTextColor[2] = myData.fPrevTextColor[2];
182 pTextZone->fTextColor[3] = myData.fPrevTextColor[3];
183 pTextZone->cAlignWidth = g_strdup (myData.cPrevAlignWidth);
184 pTextZone->cAlignHeight = g_strdup (myData.cPrevAlignHeight);
185 pTextZone->iRefresh = 0;
186 pTextZone->cMountPoint = g_strdup_printf ("/");
187 pTextZone->cCommand = NULL;
188 pTextZone->bRefresh = FALSE;
189 pTextZone->bBar = FALSE;
190
191 pTextZone->iSpaceBetweenLines = g_strtod (cContent, NULL);
192
193 if (xmlStrcmp (pXmlNode->name, BAD_CAST "br") == 0)
194 {
195 pTextZone->bEndOfLine = TRUE;
196 pTextZone->bNextNewLine = TRUE;
197 }
198 else
199 {
200 pTextZone->bEndOfLine = TRUE;
201 pTextZone->bNextNewLine = FALSE;
202 }
203 }
204
205 else if (xmlStrcmp (pXmlNode->name, BAD_CAST "override") == 0)
206 {
207 pTextZone = g_new0 (TextZone, 1);
208 myData.pTextZoneList = g_list_append (myData.pTextZoneList, pTextZone);
209
210 pTextZone->cFont = g_strdup (myData.cPrevFont);
211 pTextZone->fTextColor[0] = myData.fPrevTextColor[0];
212 pTextZone->fTextColor[1] = myData.fPrevTextColor[1];
213 pTextZone->fTextColor[2] = myData.fPrevTextColor[2];
214 pTextZone->fTextColor[3] = myData.fPrevTextColor[3];
215 pTextZone->cAlignWidth = g_strdup (myData.cPrevAlignWidth);
216 pTextZone->cAlignHeight = g_strdup (myData.cPrevAlignHeight);
217 pTextZone->iRefresh = 0;
218 pTextZone->cMountPoint = g_strdup_printf ("/");
219 pTextZone->cCommand = NULL;
220 pTextZone->cCommand = NULL;
221 pTextZone->bRefresh = FALSE;
222 pTextZone->bBar = FALSE;
223
224 // On récupère le 1er champ -> = overrideH
225 sscanf (cContent, "%d;%d", &(pTextZone->iOverrideH), &(pTextZone->iOverrideW));
226 }
227
228
229 else if (xmlStrcmp (pXmlNode->name, BAD_CAST "txt") == 0)
230 {
231 pTextZone = g_new0 (TextZone, 1);
232 myData.pTextZoneList = g_list_append (myData.pTextZoneList, pTextZone);
233
234 pTextZone->cText = (gchar *)xmlNodeGetContent (pXmlNode);
235 pTextZone->cFont = g_strdup (myData.cPrevFont);
236 pTextZone->fTextColor[0] = myData.fPrevTextColor[0];
237 pTextZone->fTextColor[1] = myData.fPrevTextColor[1];
238 pTextZone->fTextColor[2] = myData.fPrevTextColor[2];
239 pTextZone->fTextColor[3] = myData.fPrevTextColor[3];
240 pTextZone->cAlignWidth = g_strdup (myData.cPrevAlignWidth);
241 pTextZone->cAlignHeight = g_strdup (myData.cPrevAlignHeight);
242 pTextZone->iSpaceBetweenLines = 0;
243 pTextZone->bEndOfLine = FALSE;
244 pTextZone->bNextNewLine = FALSE;
245
246 pTextZone->iRefresh = 0;
247 pTextZone->cMountPoint = g_strdup_printf ("/");
248 pTextZone->cCommand = NULL;
249 pTextZone->bRefresh = FALSE;
250 pTextZone->bBar = FALSE;
251 }
252
253 else if (xmlStrcmp (pXmlNode->name, BAD_CAST "stroke") == 0)
254 {
255 pTextZone = g_new0 (TextZone, 1);
256 myData.pTextZoneList = g_list_append (myData.pTextZoneList, pTextZone);
257
258 pTextZone->cFont = g_strdup (myData.cPrevFont);
259 pTextZone->fTextColor[0] = myData.fPrevTextColor[0];
260 pTextZone->fTextColor[1] = myData.fPrevTextColor[1];
261 pTextZone->fTextColor[2] = myData.fPrevTextColor[2];
262 pTextZone->fTextColor[3] = myData.fPrevTextColor[3];
263
264 pTextZone->iHeight = atoi(cContent);
265
266 myData.cPrevAlignWidth = g_strdup_printf("left"); // Sur toute la ligne -> On aligne forcément à gauche
267 pTextZone->cAlignWidth = g_strdup (myData.cPrevAlignWidth);
268 pTextZone->cAlignHeight = g_strdup (myData.cPrevAlignHeight);
269 pTextZone->bBar = TRUE;
270 pTextZone->cText = g_strdup_printf("100"); // Une ligne est une barre avec une valeur toujours à 100 ;)
271 pTextZone->bRefresh = FALSE;
272
273 }
274
275 else if (xmlStrcmp (pXmlNode->name, BAD_CAST "lstroke") == 0)
276 {
277 pTextZone = g_new0 (TextZone, 1);
278 myData.pTextZoneList = g_list_append (myData.pTextZoneList, pTextZone);
279
280 pTextZone->cFont = g_strdup (myData.cPrevFont);
281 pTextZone->fTextColor[0] = myData.fPrevTextColor[0];
282 pTextZone->fTextColor[1] = myData.fPrevTextColor[1];
283 pTextZone->fTextColor[2] = myData.fPrevTextColor[2];
284 pTextZone->fTextColor[3] = myData.fPrevTextColor[3];
285
286 sscanf (cContent, "%d;%d", &(pTextZone->iWidth), &(pTextZone->iHeight));
287
288 pTextZone->cAlignWidth = g_strdup (myData.cPrevAlignWidth);
289 pTextZone->cAlignHeight = g_strdup (myData.cPrevAlignHeight);
290 pTextZone->bLimitedBar = TRUE;
291 pTextZone->cText = g_strdup_printf("100"); // Une ligne est une barre avec une valeur toujours à 100 ;)
292 pTextZone->bRefresh = FALSE;
293 }
294
295
296 else if (xmlStrcmp (pXmlNode->name, BAD_CAST "cmd") == 0)
297 {
298 pTextZone = g_new0 (TextZone, 1);
299 myData.pTextZoneList = g_list_append (myData.pTextZoneList, pTextZone);
300
301 pTextZone->cFont = g_strdup (myData.cPrevFont);
302 pTextZone->fTextColor[0] = myData.fPrevTextColor[0];
303 pTextZone->fTextColor[1] = myData.fPrevTextColor[1];
304 pTextZone->fTextColor[2] = myData.fPrevTextColor[2];
305 pTextZone->fTextColor[3] = myData.fPrevTextColor[3];
306 pTextZone->cAlignWidth = g_strdup (myData.cPrevAlignWidth);
307 pTextZone->cAlignHeight = g_strdup (myData.cPrevAlignHeight);
308
309 pTextZone->bBar = FALSE;
310
311 pTextZone->cText = g_strdup (D_("Please wait...")); // On initialise le 1er texte à afficher à " "
312 pTextZone->cMountPoint = g_strdup_printf ("/");
313
314 xmlNodePtr pXmlSubNode;
315 for (pXmlSubNode = pXmlNode->children; pXmlSubNode != NULL; pXmlSubNode = pXmlSubNode->next)
316 {
317 cNodeContent = xmlNodeGetContent (pXmlSubNode);
318
319 if (xmlStrcmp (pXmlSubNode->name, BAD_CAST "bash") == 0)
320 {
321 pTextZone->cCommand = _Get_FilePath (myApplet, (gchar *) cNodeContent);
322 pTextZone->bIsBash = TRUE;
323 pTextZone->bIsInternal = FALSE;
324 pTextZone->bRefresh = TRUE;
325 pTextZone->iRefresh = 0;
326 }
327
328 else if (xmlStrcmp (pXmlSubNode->name, BAD_CAST "echo") == 0)
329 {
330 // On insère sh -c 'echo " AVANT la commande et "' APRES
331 if (*cNodeContent == '~')
332 pTextZone->cCommand = g_strdup_printf ("sh -c 'echo \"%s%s\"'", getenv("HOME"), cNodeContent+1);
333 else
334 pTextZone->cCommand = g_strdup_printf ("sh -c 'echo \"%s\"'", cNodeContent);
335 pTextZone->bIsBash = TRUE;
336 pTextZone->bIsInternal = FALSE;
337 pTextZone->bRefresh = TRUE;
338 pTextZone->iRefresh = 0;
339 }
340
341 else if (xmlStrcmp (pXmlSubNode->name, BAD_CAST "internal") == 0)
342 {
343 pTextZone->cCommand = g_strdup ((gchar *)cNodeContent);
344 pTextZone->bIsInternal = TRUE;
345 pTextZone->bIsBash = FALSE;
346 pTextZone->bRefresh = TRUE;
347 pTextZone->iRefresh = 0;
348 }
349
350
351 else if (xmlStrcmp (pXmlSubNode->name, BAD_CAST "mount_point") == 0)
352 pTextZone->cMountPoint = g_strdup ((gchar *)cNodeContent);
353
354
355 else if ((xmlStrcmp (pXmlSubNode->name, BAD_CAST "lbar") == 0) || (xmlStrcmp (pXmlSubNode->name, BAD_CAST "bar") == 0))
356 {
357 // memperc;10
358 // Récupération du 1er champ (commun aux Bars et aux LimitedBars:
359 pTextZone->cCommand = g_strdup ((gchar *)cNodeContent);
360 gchar *str = strchr (pTextZone->cCommand, ';');
361 *str = '\0';
362 str ++;
363 pTextZone->bIsInternal = TRUE;
364 pTextZone->bIsBash = FALSE;
365 cd_debug ("##### %s => %s", pTextZone->cCommand, str);
366 if (xmlStrcmp (pXmlSubNode->name, BAD_CAST "lbar") == 0)
367 {
368 pTextZone->bLimitedBar = TRUE;
369 sscanf (str, "%d;%d", &(pTextZone->iWidth), &(pTextZone->iHeight));
370 }
371 else
372 {
373 pTextZone->bBar = TRUE;
374 // Récupération du 2eme champ pour les barres -> = Hauteur:
375 pTextZone->iHeight = atoi(str);
376 // Les Bars sont sur toute la ligne -> On aligne forcément à gauche
377 myData.cPrevAlignWidth = g_strdup_printf("left");
378 pTextZone->cAlignWidth = g_strdup (myData.cPrevAlignWidth);
379 pTextZone->cAlignHeight = g_strdup (myData.cPrevAlignHeight);
380 }
381 }
382 else if (xmlStrcmp (pXmlSubNode->name, BAD_CAST "refresh") == 0)
383 {
384 pTextZone->iRefresh = g_strtod ((gchar *) cNodeContent, NULL);
385 pTextZone->bRefresh = TRUE;
386 }
387 xmlFree (cNodeContent);
388 }
389 }
390
391
392 else if (xmlStrcmp (pXmlNode->name, BAD_CAST "img") == 0)
393 {
394 pTextZone = g_new0 (TextZone, 1);
395 myData.pTextZoneList = g_list_append (myData.pTextZoneList, pTextZone);
396
397
398 pTextZone->cFont = g_strdup (myData.cPrevFont);
399 pTextZone->fTextColor[0] = myData.fPrevTextColor[0];
400 pTextZone->fTextColor[1] = myData.fPrevTextColor[1];
401 pTextZone->fTextColor[2] = myData.fPrevTextColor[2];
402 pTextZone->fTextColor[3] = myData.fPrevTextColor[3];
403 pTextZone->cAlignWidth = g_strdup (myData.cPrevAlignWidth);
404 pTextZone->cAlignHeight = g_strdup (myData.cPrevAlignHeight);
405
406 pTextZone->bBar = FALSE;
407
408 xmlNodePtr pXmlSubNode;
409 for (pXmlSubNode = pXmlNode->children; pXmlSubNode != NULL; pXmlSubNode = pXmlSubNode->next)
410 {
411 cNodeContent = xmlNodeGetContent (pXmlSubNode);
412
413 if (xmlStrcmp (pXmlSubNode->name, BAD_CAST "file") == 0)
414 {
415 pTextZone->cImgPath = _Get_FilePath (myApplet, (gchar *)cNodeContent);
416 pTextZone->bImgDraw=FALSE;
417 }
418 else if (xmlStrcmp (pXmlSubNode->name, BAD_CAST "size") == 0)
419 {
420 pTextZone->iImgSize = g_strtod ((gchar *)cNodeContent, NULL);
421 }
422 else if (xmlStrcmp (pXmlSubNode->name, BAD_CAST "sizeW") == 0)
423 {
424 pTextZone->iWidth= g_strtod ((gchar *)cNodeContent, NULL);
425 }
426 else if (xmlStrcmp (pXmlSubNode->name, BAD_CAST "sizeH") == 0)
427 {
428 pTextZone->iHeight = g_strtod ((gchar *)cNodeContent, NULL);
429 }
430 xmlFree (cNodeContent);
431 }
432 }
433 g_free (cContent);
434 }
435
436 cairo_dock_close_xml_file (pXmlFile);
437
438 return TRUE;
439 }
440