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 #include <string.h>
21 
22 #include "applet-struct.h"
23 #include "applet-load-icons.h"
24 #include "applet-stack.h"
25 
26 
_isin(gchar ** cString,gchar * cCompar)27 static gboolean _isin (gchar **cString, gchar *cCompar) {
28 	if (cString == NULL)
29 		return FALSE; //Nothing to search in
30 
31 	cd_debug ("%s (%s)", __func__, cCompar);
32 	int i=0;
33 	gchar *tmp;
34 	while (cString[i] != NULL) {
35 		tmp = g_strstr_len (cCompar, -1, cString[i]);
36 		if (tmp != NULL)
37 			return TRUE; //We found what we want
38 		i++;
39 	}
40 
41 	return FALSE; //We didn't found anything
42 }
_load_html_icon(Icon * pIcon)43 static void _load_html_icon (Icon *pIcon)
44 {
45 	int iWidth = cairo_dock_icon_get_allocated_width (pIcon);
46 	int iHeight = cairo_dock_icon_get_allocated_height (pIcon);
47 	if (pIcon->cFileName)  // icone possedant une image, on affiche celle-ci.
48 	{
49 		gchar *cIconPath = cairo_dock_search_icon_s_path (pIcon->cFileName, MAX (iWidth, iHeight));
50 		if (cIconPath != NULL && *cIconPath != '\0')
51 		{
52 			cairo_surface_t *pSurface = cairo_dock_create_surface_from_image_simple (cIconPath,
53 				iWidth,
54 				iHeight);
55 			cairo_dock_load_image_buffer_from_surface (&pIcon->image, pSurface, iWidth, iHeight);
56 
57 			if (pIcon->image.pSurface != NULL && pIcon->cWorkingDirectory != NULL)
58 			{
59 				cairo_dock_print_overlay_on_icon_from_image (pIcon, pIcon->cWorkingDirectory, CAIRO_OVERLAY_LOWER_RIGHT);
60 			}
61 		}
62 		g_free (cIconPath);
63 	}
64 }
cd_stack_build_one_icon(GldiModuleInstance * myApplet,GKeyFile * pKeyFile)65 Icon *cd_stack_build_one_icon (GldiModuleInstance *myApplet, GKeyFile *pKeyFile)
66 {
67 	GError *erreur = NULL;
68 	gchar *cContent = g_key_file_get_string (pKeyFile, "Desktop Entry", "Content", &erreur);
69 	if (erreur != NULL)
70 	{
71 		cd_warning ("Stack : %s", erreur->message);
72 		g_error_free (erreur);
73 		erreur = NULL;
74 	}
75 	g_return_val_if_fail (cContent != NULL, NULL);
76 
77 	Icon *pIcon = NULL;
78 	if (cairo_dock_string_is_address (cContent))
79 	{
80 		if (strncmp (cContent, "http://", 7) == 0 || strncmp (cContent, "https://", 8) == 0)  // URL web
81 		{
82 			pIcon = cairo_dock_create_dummy_launcher (NULL,
83 				g_strdup (myConfig.cUrlIcon),
84 				cContent,
85 				NULL,
86 				0);
87 			pIcon->iface.load_image = _load_html_icon;
88 			if (myConfig.bSeparateTypes)
89 				pIcon->iGroup = 6;
90 		}
91 		else  // URI file
92 		{
93 			gchar *cCanonicName=NULL, *cRealURI=NULL, *cIconName=NULL;
94 			gboolean bIsDirectory;
95 			int iVolumeID;
96 			double fOrder;
97 			cairo_dock_fm_get_file_info (cContent, &cCanonicName, &cRealURI, &cIconName, &bIsDirectory, &iVolumeID, &fOrder, CAIRO_DOCK_FM_SORT_BY_NAME);
98 			cd_debug ("un fichier -> %s , %s", cCanonicName, cIconName);
99 			g_free (cRealURI);
100 
101 			if (myConfig.bFilter && cIconName != NULL && _isin(myConfig.cMimeTypes, cIconName))
102 			{
103 				g_free (cIconName);
104 				g_free (cCanonicName);
105 				g_free (cContent);
106 				return NULL;
107 			}
108 
109 			pIcon = cairo_dock_create_dummy_launcher (NULL,
110 				cIconName,
111 				cContent,
112 				NULL,
113 				0);
114 			g_free (cCanonicName);
115 			if (myConfig.bSeparateTypes)
116 				pIcon->iGroup = 8;
117 		}
118 		pIcon->iVolumeID = 1;  // let's use this as a flag for the URI items.
119 	}
120 	else  // text
121 	{
122 		pIcon = cairo_dock_create_dummy_launcher (NULL,
123 			g_strdup (myConfig.cTextIcon),
124 			cContent,
125 			NULL,
126 			0);
127 		if (myConfig.bSeparateTypes)
128 			pIcon->iGroup = 10;
129 	}
130 
131 	pIcon->cName = g_key_file_get_string (pKeyFile, "Desktop Entry", "Name", &erreur);
132 	if (erreur != NULL)
133 	{
134 		cd_warning ("Stack : %s", erreur->message);
135 		g_error_free (erreur);
136 		erreur = NULL;
137 	}
138 
139 	if (myConfig.iSortType == CD_STACK_SORT_BY_DATE)
140 	{
141 		pIcon->fOrder = g_key_file_get_integer (pKeyFile, "Desktop Entry", "Date", &erreur);
142 		if (erreur != NULL)
143 		{
144 			cd_warning ("Stack : %s", erreur->message);
145 			g_error_free (erreur);
146 			erreur = NULL;
147 		}
148 	}
149 	else if (myConfig.iSortType == CD_STACK_SORT_MANUALLY)
150 	{
151 		pIcon->fOrder = g_key_file_get_double (pKeyFile, "Desktop Entry", "Order", &erreur);
152 		if (erreur != NULL)
153 		{
154 			cd_warning ("Stack : %s", erreur->message);
155 			g_error_free (erreur);
156 			erreur = NULL;
157 		}
158 	}
159 
160 	pIcon->cWorkingDirectory = g_key_file_get_string (pKeyFile, "Desktop Entry", "Favicon", NULL);  // we use this parameter to store the favicon path; it's quite dirty, but easier than allocating our own data.
161 
162 	pIcon->pAppletOwner = myApplet;
163 
164 	return pIcon;
165 }
166 
cd_stack_build_one_icon_from_file(GldiModuleInstance * myApplet,gchar * cDesktopFilePath)167 Icon *cd_stack_build_one_icon_from_file (GldiModuleInstance *myApplet, gchar *cDesktopFilePath)
168 {
169 	GKeyFile *pKeyFile = cairo_dock_open_key_file (cDesktopFilePath);
170 	g_return_val_if_fail (pKeyFile != NULL, NULL);
171 
172 	Icon *pIcon = cd_stack_build_one_icon (myApplet, pKeyFile);
173 
174 	g_key_file_free (pKeyFile);
175 	return pIcon;
176 }
177 
cd_stack_build_icons_list(GldiModuleInstance * myApplet,gchar * cStackDir)178 GList *cd_stack_build_icons_list (GldiModuleInstance *myApplet, gchar *cStackDir)
179 {
180 	// on parcourt tous les fichiers du repertoire.
181 	GDir *dir = g_dir_open (cStackDir, 0, NULL);
182 	g_return_val_if_fail (dir != NULL, NULL);
183 
184 	GList *pIconsList = NULL;
185 	Icon *pIcon;
186 	GString *sDesktopFilePath = g_string_new ("");
187 	const gchar *cFileName;
188 	while ((cFileName = g_dir_read_name (dir)) != NULL)
189 	{
190 		g_string_printf (sDesktopFilePath, "%s/%s", cStackDir, cFileName);
191 
192 		pIcon = cd_stack_build_one_icon_from_file (myApplet, sDesktopFilePath->str);
193 		if (pIcon != NULL)
194 		{
195 			pIcon->cDesktopFileName = g_strdup (cFileName);
196 
197 			pIconsList = g_list_prepend (pIconsList, pIcon);
198 		}
199 	}
200 
201 	g_string_free (sDesktopFilePath, TRUE);
202 	g_dir_close (dir);
203 
204 	// on classe la liste.
205 	if (myConfig.iSortType == CD_STACK_SORT_BY_NAME)
206 	{
207 		pIconsList = g_list_sort (pIconsList, (GCompareFunc) cairo_dock_compare_icons_name);
208 		int i = 0;
209 		GList *ic;
210 		for (ic = pIconsList; ic != NULL; ic = ic->next)
211 		{
212 			pIcon = ic->data;
213 			pIcon->fOrder = i ++;
214 		}
215 	}
216 	else if (myConfig.iSortType == CD_STACK_SORT_BY_TYPE)
217 	{
218 		pIconsList = g_list_sort (pIconsList, (GCompareFunc) cairo_dock_compare_icons_extension);  /// a defaut d'avoir les types mime...
219 		int i = 0;
220 		GList *ic;
221 		for (ic = pIconsList; ic != NULL; ic = ic->next)
222 		{
223 			pIcon = ic->data;
224 			pIcon->fOrder = i ++;
225 		}
226 	}
227 	else
228 	{
229 		pIconsList = g_list_sort (pIconsList, (GCompareFunc) cairo_dock_compare_icons_order);
230 	}
231 
232 	return pIconsList;
233 }
234 
cd_stack_build_icons(GldiModuleInstance * myApplet)235 void cd_stack_build_icons (GldiModuleInstance *myApplet)
236 {
237 	//\_______________________ On efface l'ancienne liste.
238 	CD_APPLET_DELETE_MY_ICONS_LIST;
239 
240 	//\_______________________ On liste les icones.
241 	GList *pIconList = cd_stack_build_icons_list (myApplet, myConfig.cStackDir);
242 
243 	//\_______________________ On charge la nouvelle liste.
244 	if (pIconList != NULL)
245 	{
246 		const gchar *cDeskletRendererName = NULL;
247 		switch (myConfig.iDeskletRendererType)
248 		{
249 			case CD_DESKLET_SLIDE :
250 			default :
251 				cDeskletRendererName = "Viewport";
252 			break ;
253 
254 			case CD_DESKLET_TREE :
255 				cDeskletRendererName = "Tree";
256 			break ;
257 		}
258 		CD_APPLET_LOAD_MY_ICONS_LIST (pIconList, myConfig.cRenderer, cDeskletRendererName, NULL);
259 	}
260 	else if (myDock)  // sinon on ne veut pas du sous-dock vide.
261 	{
262 		gldi_object_unref (GLDI_OBJECT(myIcon->pSubDock));
263 		myIcon->pSubDock = NULL;
264 	}
265 }
266