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 "config.h"
21 #include "cairo-dock-struct.h"
22 #include "cairo-dock-keyfile-utilities.h"
23 #include "cairo-dock-module-manager.h"
24 #include "cairo-dock-themes-manager.h"  // cairo_dock_write_keys_to_conf_file
25 #include "cairo-dock-module-instance-manager.h"  // gldi_module_instance_reload
26 #include "cairo-dock-gui-factory.h"
27 #include "cairo-dock-gui-commons.h"
28 #include "cairo-dock-log.h"
29 #include "cairo-dock-widget-config-group.h"
30 
31 #define CAIRO_DOCK_ICON_MARGIN 6
32 #define CAIRO_DOCK_GROUP_ICON_SIZE 28
33 extern gchar *g_cConfFile;
34 
35 
_config_group_widget_apply(CDWidget * pCdWidget)36 static void _config_group_widget_apply (CDWidget *pCdWidget)
37 {
38 	ConfigGroupWidget *pConfigGroupWidget = CONFIG_GROUP_WIDGET (pCdWidget);
39 
40 	// update the conf file.
41 	GKeyFile *pKeyFile = cairo_dock_open_key_file (g_cConfFile);
42 	g_return_if_fail (pKeyFile != NULL);
43 
44 	cairo_dock_update_keyfile_from_widget_list (pKeyFile, pCdWidget->pWidgetList);
45 	cairo_dock_write_keys_to_conf_file (pKeyFile, g_cConfFile);
46 	g_key_file_free (pKeyFile);
47 
48 	// reload the associated managers.
49 	const gchar *cManagerName, *cModuleName;
50 	GldiModule *pModule;
51 	GldiModuleInstance *pExtraInstance;
52 	GldiManager *pManager;
53 	GSList *pExtraWidgetList;
54 	GKeyFile* pExtraKeyFile;
55 	GList *m, *e;
56 	GSList *w = pConfigGroupWidget->pExtraWidgets;
57 	for (m = pConfigGroupWidget->pManagers; m != NULL; m = m->next)
58 	{
59 		cManagerName = m->data;
60 		pManager = gldi_manager_get (cManagerName);
61 		g_return_if_fail (pManager != NULL);
62 		gldi_object_reload (GLDI_OBJECT(pManager), TRUE);
63 
64 		// reload the extensions too
65 		for (e = pManager->pExternalModules; e != NULL && w != NULL; e = e->next)
66 		{
67 			// get the extension
68 			cModuleName = e->data;
69 			pModule = gldi_module_get (cModuleName);
70 			if (!pModule)
71 				continue;
72 
73 			pExtraInstance = pModule->pInstancesList->data;
74 			if (pExtraInstance == NULL)
75 				continue;
76 
77 			// update its conf file
78 			pExtraKeyFile = cairo_dock_open_key_file (pExtraInstance->cConfFilePath);
79 			if (pExtraKeyFile == NULL)
80 				continue;
81 
82 			pExtraWidgetList = w->data;
83 			w = w->next;
84 
85 			cairo_dock_update_keyfile_from_widget_list (pExtraKeyFile, pExtraWidgetList);
86 			if (pModule->pInterface->save_custom_widget != NULL)
87 				pModule->pInterface->save_custom_widget (pExtraInstance, pKeyFile, pExtraWidgetList);
88 			cairo_dock_write_keys_to_conf_file (pExtraKeyFile, pExtraInstance->cConfFilePath);
89 			g_key_file_free (pExtraKeyFile);
90 
91 			// reload it
92 			gldi_object_reload (GLDI_OBJECT(pExtraInstance), TRUE);
93 		}
94 	}
95 }
96 
_config_group_widget_reset(CDWidget * pCdWidget)97 static void _config_group_widget_reset (CDWidget *pCdWidget)
98 {
99 	ConfigGroupWidget *pConfigGroupWidget = CONFIG_GROUP_WIDGET (pCdWidget);
100 	//g_free (pConfigGroupWidget->cGroupName);
101 	g_slist_foreach (pConfigGroupWidget->pExtraWidgets, (GFunc)cairo_dock_free_generated_widget_list, NULL);
102 	g_slist_free (pConfigGroupWidget->pExtraWidgets);
103 	memset (pCdWidget+1, 0, sizeof (ConfigGroupWidget) - sizeof (CDWidget));  // reset all our parameters.
104 }
105 
_add_widget_to_notebook(GtkWidget * pNoteBook,GtkWidget * pWidget,const gchar * cIcon,const gchar * cTitle)106 static void _add_widget_to_notebook (GtkWidget *pNoteBook, GtkWidget *pWidget, const gchar *cIcon, const gchar *cTitle)
107 {
108 	GtkWidget *pLabel = gtk_label_new (cTitle);
109 	GtkWidget *pLabelContainer = NULL;
110 	GtkWidget *pAlign = NULL;
111 	if (cIcon != NULL && *cIcon != '\0')
112 	{
113 		pLabelContainer = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, CAIRO_DOCK_ICON_MARGIN);
114 		pAlign = gtk_alignment_new (0., 0.5, 0., 0.);
115 		gtk_container_add (GTK_CONTAINER (pAlign), pLabelContainer);
116 
117 		gchar *icon = cairo_dock_get_icon_for_gui (NULL, cIcon, NULL, CAIRO_DOCK_GROUP_ICON_SIZE, FALSE);
118 		GtkWidget *pImage = _gtk_image_new_from_file (icon, GTK_ICON_SIZE_BUTTON);
119 		gtk_container_add (GTK_CONTAINER (pLabelContainer), pImage);
120 		gtk_container_add (GTK_CONTAINER (pLabelContainer), pLabel);
121 		gtk_widget_show_all (pLabelContainer);
122 		g_free (icon);
123 	}
124 
125 	GtkWidget *pScrolledWindow = gtk_scrolled_window_new (NULL, NULL);  // add scrollbars on the widget before putting it into the notebook.
126 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pScrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
127 	#if GTK_CHECK_VERSION (3, 8, 0)
128 	gtk_container_add (GTK_CONTAINER (pScrolledWindow), pWidget);
129 	#else
130 	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (pScrolledWindow), pWidget);
131 	#endif
132 
133 	gtk_notebook_append_page (GTK_NOTEBOOK (pNoteBook), pScrolledWindow, (pAlign != NULL ? pAlign : pLabel));
134 }
_make_notebook(void)135 static GtkWidget *_make_notebook (void)
136 {
137 	GtkWidget *pNoteBook = gtk_notebook_new ();
138 	gtk_notebook_set_scrollable (GTK_NOTEBOOK (pNoteBook), TRUE);
139 	gtk_notebook_popup_enable (GTK_NOTEBOOK (pNoteBook));
140 	g_object_set (G_OBJECT (pNoteBook), "tab-pos", GTK_POS_TOP, NULL);
141 	return pNoteBook;
142 }
cairo_dock_config_group_widget_new(GList * pGroups,GList * pManagers)143 ConfigGroupWidget *cairo_dock_config_group_widget_new (GList *pGroups, GList *pManagers)
144 {
145 	ConfigGroupWidget *pConfigGroupWidget = g_new0 (ConfigGroupWidget, 1);
146 	pConfigGroupWidget->widget.iType = WIDGET_CONFIG_GROUP;
147 	pConfigGroupWidget->widget.apply = _config_group_widget_apply;
148 	pConfigGroupWidget->widget.reset = _config_group_widget_reset;
149 	pConfigGroupWidget->pManagers = pManagers;
150 	pConfigGroupWidget->widget.pDataGarbage = g_ptr_array_new ();
151 
152 	// build its widget based on its config file.
153 	GKeyFile* pKeyFile = cairo_dock_open_key_file (g_cConfFile);
154 	g_return_val_if_fail (pKeyFile != NULL, NULL);
155 
156 	GtkWidget *pWidget = NULL;
157 	GtkWidget *pNoteBook = NULL;
158 	gchar **pGroup, **pFirstGroup = NULL;
159 	const gchar *cGroupName, *cIcon, *cTitle;
160 	GList *g;
161 	for (g = pGroups; g != NULL; g = g->next)
162 	{
163 		pGroup = g->data;
164 		cGroupName = pGroup[0];
165 		cIcon = pGroup[1];
166 		cTitle = pGroup[2];
167 
168 		if (!pFirstGroup)
169 			pFirstGroup = pGroup;
170 
171 		if (pWidget != NULL && pNoteBook == NULL)  // we already built a widget before -> make a notebook and place this widget inside
172 		{
173 			pNoteBook = _make_notebook ();
174 			_add_widget_to_notebook (pNoteBook, pWidget, pFirstGroup[1], pFirstGroup[2]);
175 		}
176 
177 		pWidget = cairo_dock_build_group_widget (pKeyFile,
178 			cGroupName,
179 			NULL,  // gettext domain
180 			NULL,  // main window
181 			&pConfigGroupWidget->widget.pWidgetList,
182 			pConfigGroupWidget->widget.pDataGarbage,
183 			g_strdup (CAIRO_DOCK_SHARE_DATA_DIR"/"CAIRO_DOCK_CONF_FILE));
184 
185 		if (pNoteBook != NULL)
186 		{
187 			_add_widget_to_notebook (pNoteBook, pWidget, cIcon, cTitle);
188 		}
189 	}
190 
191 	// build the widgets of the extensions
192 	GKeyFile* pExtraKeyFile;
193 	GldiModule *pModule;
194 	GldiModuleInstance *pExtraInstance;
195 	GSList *pExtraWidgetList;
196 	gchar *cOriginalConfFilePath;
197 	GldiManager *pManager;
198 	const gchar *cManagerName, *cModuleName;
199 	GList *m, *e;
200 	for (m = pManagers; m != NULL; m = m->next)
201 	{
202 		cManagerName = m->data;
203 		pManager = gldi_manager_get (cManagerName);
204 		if (!pManager)
205 			continue;
206 
207 		for (e = pManager->pExternalModules; e != NULL; e = e->next)
208 		{
209 			cModuleName = e->data;
210 			pModule = gldi_module_get (cModuleName);
211 			// check if the module is found and has an instances' list (cairo-dock -m)
212 			if (!pModule || !pModule->pInstancesList)
213 				continue;
214 
215 			pExtraInstance = pModule->pInstancesList->data;
216 			if (pExtraInstance == NULL)
217 				continue;
218 
219 			if (pExtraInstance->cConfFilePath == NULL)
220 				continue;
221 
222 			pExtraKeyFile = cairo_dock_open_key_file (pExtraInstance->cConfFilePath);
223 			if (pExtraKeyFile == NULL)
224 				continue;
225 
226 			if (pNoteBook == NULL)
227 			{
228 				pNoteBook = _make_notebook ();
229 				_add_widget_to_notebook (pNoteBook, pWidget, pFirstGroup[1], pFirstGroup[2]);
230 			}
231 
232 			pExtraWidgetList = NULL;
233 			cOriginalConfFilePath = g_strdup_printf ("%s/%s", pModule->pVisitCard->cShareDataDir, pModule->pVisitCard->cConfFileName);
234 			pNoteBook = cairo_dock_build_key_file_widget_full (pExtraKeyFile,
235 				pModule->pVisitCard->cGettextDomain,
236 				NULL,
237 				&pExtraWidgetList,
238 				pConfigGroupWidget->widget.pDataGarbage,  // the garbage array can be mutualized with 'pConfigGroupWidget'
239 				cOriginalConfFilePath,
240 				pNoteBook);
241 
242 			pConfigGroupWidget->pExtraWidgets = g_slist_append (pConfigGroupWidget->pExtraWidgets, pExtraWidgetList);  // append, so that we can parse the list in the same order again.
243 
244 			if (pModule->pInterface->load_custom_widget != NULL)
245 				pModule->pInterface->load_custom_widget (pExtraInstance, pExtraKeyFile, pExtraWidgetList);
246 
247 			g_key_file_free (pExtraKeyFile);
248 		}
249 	}
250 
251 	pConfigGroupWidget->widget.pWidget = (pNoteBook ? pNoteBook : pWidget);
252 
253 	g_key_file_free (pKeyFile);
254 	return pConfigGroupWidget;
255 }
256 
257