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