~ubuntu-branches/ubuntu/maverick/cairo-dock/maverick

« back to all changes in this revision

Viewing changes to src/cairo-dock-themes-manager.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100809232612-yp4c6ig3jt1bzpdv
Tags: 2.2.0~0beta4-0ubuntu1
* New Upstream Version (LP: #614624)
* Fixed a few bugs on LP:
 - LP: #518453: Dock appears under all windows
                 (Compiz - fullscreen window)
 - LP: #521369: Separator are not removed when closing
                 grouped windows
 - LP: #521762: Some sentences are not correct
 - LP: #526466: Icons of apps with same class shouldn't
                 be stacked by default
 - LP: #535083: Dialogues looks ugly when a lot of them
                 appears at the same time
 - More details on the 'ChangeLog' file
* debian/rules:
 - Autotools has been replaced by CMake
 - Man pages are now included in the source code
* debian/copyright:
 - Updated with the new pathes and new files
* debian/control:
 - Autotools has been replaced by CMake
 - Added libcurl4-gnutls-dev as Build-deps
 - Bump Standard-Version to 3.9.1
* debian/cairo-dock-core.install:
 - Man pages are now included in the source code
 - All sonames are now installed into lib32 or lib64
* debian/cairo-dock-dev.install:
 - pkgconfig is now installed into lib32 or lib64

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
#include <unistd.h>
22
 
#define __USE_XOPEN_EXTENDED
23
 
#include <stdlib.h>
24
 
#include <sys/stat.h>
25
 
#define __USE_POSIX
26
 
#include <time.h>
27
 
#include <glib/gstdio.h>
28
 
#include <glib/gi18n.h>
29
 
 
30
 
#include "cairo-dock-config.h"
31
 
#include "cairo-dock-keyfile-utilities.h"
32
 
#include "cairo-dock-dock-factory.h"
33
 
#include "cairo-dock-modules.h"
34
 
#include "cairo-dock-renderer-manager.h"
35
 
#include "cairo-dock-dialogs.h"
36
 
#include "cairo-dock-log.h"
37
 
#include "cairo-dock-gauge.h"
38
 
#include "cairo-dock-dialogs.h"
39
 
#include "cairo-dock-gui-manager.h"
40
 
#include "cairo-dock-task.h"
41
 
#include "cairo-dock-log.h"
42
 
#include "cairo-dock-internal-system.h"
43
 
#include "cairo-dock-themes-manager.h"
44
 
 
45
 
#define CAIRO_DOCK_MODIFIED_THEME_FILE ".cairo-dock-need-save"
46
 
#define CAIRO_DOCK_THEME_PANEL_WIDTH 1000
47
 
#define CAIRO_DOCK_THEME_PANEL_HEIGHT 550
48
 
#define CAIRO_DOCK_THEME_SERVER "http://themes.glx-dock.org"  // "http://themes.cairo-dock.vef.fr"
49
 
#define CAIRO_DOCK_BACKUP_THEME_SERVER "http://fabounet03.free.fr"
50
 
#define CAIRO_DOCK_DEFAULT_THEME_LIST_NAME "list.conf"
51
 
 
52
 
extern gchar *g_cCairoDockDataDir;
53
 
extern gchar *g_cConfFile;
54
 
extern gchar *g_cCurrentThemePath;
55
 
extern gchar *g_cCurrentLaunchersPath;
56
 
extern gchar *g_cThemeServerAdress;
57
 
extern int g_iMajorVersion, g_iMinorVersion, g_iMicroVersion;
58
 
 
59
 
extern CairoDock *g_pMainDock;
60
 
 
61
 
static GtkWidget *s_pThemeManager = NULL;
62
 
static CairoDockTask *s_pImportTask = NULL;
63
 
 
64
 
void cairo_dock_free_theme (CairoDockTheme *pTheme)
65
 
{
66
 
        if (pTheme == NULL)
67
 
                return ;
68
 
        g_free (pTheme->cThemePath);
69
 
        g_free (pTheme->cAuthor);
70
 
        g_free (pTheme->cDisplayedName);
71
 
        g_free (pTheme);
72
 
}
73
 
 
74
 
 
75
 
gchar *cairo_dock_uncompress_file (const gchar *cArchivePath, const gchar *cExtractTo, const gchar *cRealArchiveName)
76
 
{
77
 
        //\_______________ on cree le repertoire d'extraction.
78
 
        if (!g_file_test (cExtractTo, G_FILE_TEST_EXISTS))
79
 
        {
80
 
                if (g_mkdir (cExtractTo, 7*8*8+7*8+5) != 0)
81
 
                {
82
 
                        cd_warning ("couldn't create directory %s", cExtractTo);
83
 
                        return NULL;
84
 
                }
85
 
        }
86
 
        
87
 
        //\_______________ on construit le chemin local du dossier apres son extraction.
88
 
        gchar *cLocalFileName;
89
 
        if (cRealArchiveName == NULL)
90
 
                cRealArchiveName = cArchivePath;
91
 
        gchar *str = strrchr (cRealArchiveName, '/');
92
 
        if (str != NULL)
93
 
                cLocalFileName = g_strdup (str+1);
94
 
        else
95
 
                cLocalFileName = g_strdup (cRealArchiveName);
96
 
        
97
 
        if (g_str_has_suffix (cLocalFileName, ".tar.gz"))
98
 
                cLocalFileName[strlen(cLocalFileName)-7] = '\0';
99
 
        else if (g_str_has_suffix (cLocalFileName, ".tar.bz2"))
100
 
                cLocalFileName[strlen(cLocalFileName)-8] = '\0';
101
 
        else if (g_str_has_suffix (cLocalFileName, ".tgz"))
102
 
                cLocalFileName[strlen(cLocalFileName)-4] = '\0';
103
 
        g_return_val_if_fail (cLocalFileName != NULL && *cLocalFileName != '\0', NULL);
104
 
        
105
 
        gchar *cResultPath = g_strdup_printf ("%s/%s", cExtractTo, cLocalFileName);
106
 
        g_free (cLocalFileName);
107
 
        
108
 
        //\_______________ on efface un dossier identique prealable.
109
 
        if (g_file_test (cResultPath, G_FILE_TEST_EXISTS))
110
 
        {
111
 
                gchar *cCommand = g_strdup_printf ("rm -rf \"%s\"", cResultPath);
112
 
                int r = system (cCommand);
113
 
                g_free (cCommand);
114
 
        }
115
 
        
116
 
        //\_______________ on decompresse l'archive.
117
 
        gchar *cCommand = g_strdup_printf ("tar xf%c \"%s\" -C \"%s\"", (g_str_has_suffix (cArchivePath, "bz2") ? 'j' : 'z'), cArchivePath, cExtractTo);
118
 
        g_print ("tar : %s\n", cCommand);
119
 
        int r = system (cCommand);
120
 
        if (r != 0)
121
 
        {
122
 
                cd_warning ("an error occured while executing '%s'", cCommand);
123
 
                g_free (cResultPath);
124
 
                cResultPath = NULL;
125
 
        }
126
 
        g_free (cCommand);
127
 
        return cResultPath;
128
 
}
129
 
 
130
 
gchar *cairo_dock_download_file (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, const gchar *cExtractTo, GError **erreur)
131
 
{
132
 
        //g_print ("%s (%s, %s, %s, %s)\n", __func__, cServerAdress, cDistantFilePath, cDistantFileName, cExtractTo);
133
 
        //\_______________ On reserve un fichier temporaire.
134
 
        gchar *cTmpFilePath = g_strdup ("/tmp/cairo-dock-net-file.XXXXXX");
135
 
        int fds = mkstemp (cTmpFilePath);
136
 
        if (fds == -1)
137
 
        {
138
 
                g_set_error (erreur, 1, 1, "couldn't create temporary file '%s'", cTmpFilePath);
139
 
                g_free (cTmpFilePath);
140
 
                return NULL;
141
 
        }
142
 
        
143
 
        //\_______________ On lance le download.
144
 
        //gchar *cCommand = g_strdup_printf ("%s wget \"%s/%s/%s\" -O \"%s\" -t %d -T %d%s", (iShowActivity == 2 ? "$TERM -e '" : ""), cServerAdress, cDistantFilePath, cDistantFileName, cTmpFilePath, CAIRO_DOCK_DL_NB_RETRY, CAIRO_DOCK_DL_TIMEOUT, (iShowActivity == 2 ? "'" : ""));
145
 
        gchar *cCommand = g_strdup_printf ("curl -s \"%s/%s/%s\" --output \"%s\" --connect-timeout %d --max-time %d --retry %d",
146
 
                cServerAdress, cDistantFilePath, cDistantFileName,
147
 
                cTmpFilePath,
148
 
                mySystem.iConnectionTimeout, mySystem.iConnectiontMaxTime, mySystem.iConnectiontNbRetries);
149
 
        cd_debug ("download with '%s'", cCommand);
150
 
        int r = system (cCommand);
151
 
        if (r != 0)
152
 
        {
153
 
                cd_warning ("an error occured while executing '%s'", cCommand);
154
 
                g_remove (cTmpFilePath);
155
 
                g_free (cTmpFilePath);
156
 
                cTmpFilePath = NULL;
157
 
        }
158
 
        
159
 
        //\_______________ On teste que le fichier est non vide.
160
 
        gboolean bOk = (cTmpFilePath != NULL);
161
 
        if (bOk)
162
 
        {
163
 
                struct stat buf;
164
 
                stat (cTmpFilePath, &buf);
165
 
                bOk = (buf.st_size > 0);
166
 
        }
167
 
        if (! bOk)
168
 
        {
169
 
                g_set_error (erreur, 1, 1, "couldn't get distant file %s", cDistantFileName);
170
 
                g_remove (cTmpFilePath);
171
 
                g_free (cTmpFilePath);
172
 
                cTmpFilePath = NULL;
173
 
        }
174
 
        close(fds);
175
 
        g_free (cCommand);
176
 
        
177
 
        //\_______________ On l'extrait si c'est une archive.
178
 
        if (cTmpFilePath != NULL && cExtractTo != NULL)
179
 
        {
180
 
                g_print ("uncompressing ...\n");
181
 
                gchar *cPath = cairo_dock_uncompress_file (cTmpFilePath, cExtractTo, cDistantFileName);
182
 
                g_remove (cTmpFilePath);
183
 
                g_free (cTmpFilePath);
184
 
                cTmpFilePath = cPath;
185
 
        }
186
 
        
187
 
        return cTmpFilePath;
188
 
}
189
 
 
190
 
static void _dl_file (gpointer *pSharedMemory)
191
 
{
192
 
        GError *erreur = NULL;
193
 
        pSharedMemory[6] = cairo_dock_download_file (pSharedMemory[0], pSharedMemory[1], pSharedMemory[2], pSharedMemory[3], &erreur);
194
 
        if (erreur != NULL)
195
 
        {
196
 
                cd_warning (erreur->message);
197
 
                g_error_free (erreur);
198
 
        }
199
 
}
200
 
static gboolean _finish_dl (gpointer *pSharedMemory)
201
 
{
202
 
        if (pSharedMemory[6] == NULL)
203
 
                cd_warning ("couldn't get distant file %s", pSharedMemory[2]);
204
 
        
205
 
        GFunc pCallback = pSharedMemory[4];
206
 
        pCallback (pSharedMemory[6], pSharedMemory[5]);
207
 
        return FALSE;
208
 
}
209
 
static void _discard_dl (gpointer *pSharedMemory)
210
 
{
211
 
        g_free (pSharedMemory[0]);
212
 
        g_free (pSharedMemory[1]);
213
 
        g_free (pSharedMemory[2]);
214
 
        g_free (pSharedMemory[3]);
215
 
        g_free (pSharedMemory[6]);
216
 
        g_free (pSharedMemory);
217
 
}
218
 
CairoDockTask *cairo_dock_download_file_async (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, const gchar *cExtractTo, GFunc pCallback, gpointer data)
219
 
{
220
 
        gpointer *pSharedMemory = g_new0 (gpointer, 7);
221
 
        pSharedMemory[0] = g_strdup (cServerAdress);
222
 
        pSharedMemory[1] = g_strdup (cDistantFilePath);
223
 
        pSharedMemory[2] = g_strdup (cDistantFileName);
224
 
        pSharedMemory[3] = g_strdup (cExtractTo);
225
 
        pSharedMemory[4] = pCallback;
226
 
        pSharedMemory[5] = data;
227
 
        CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _dl_file, (CairoDockUpdateSyncFunc) _finish_dl, (GFreeFunc) _discard_dl, pSharedMemory);
228
 
        cairo_dock_launch_task (pTask);
229
 
        return pTask;
230
 
}
231
 
 
232
 
gchar *cairo_dock_get_distant_file_content (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, GError **erreur)
233
 
{
234
 
        GError *tmp_erreur = NULL;
235
 
        gchar *cTmpFilePath = cairo_dock_download_file (cServerAdress, cDistantFilePath, cDistantFileName, NULL, &tmp_erreur);
236
 
        if (tmp_erreur != NULL)
237
 
        {
238
 
                g_propagate_error (erreur, tmp_erreur);
239
 
                return NULL;
240
 
        }
241
 
 
242
 
        gchar *cContent = NULL;
243
 
        gsize length = 0;
244
 
        g_file_get_contents (cTmpFilePath, &cContent, &length, &tmp_erreur);
245
 
        if (tmp_erreur != NULL)
246
 
        {
247
 
                cd_warning ("while opening the downloaded file '%s/%s/%s' : %s\n check that your connection is alive, or retry later", cServerAdress, cDistantFilePath, cDistantFileName, tmp_erreur->message);
248
 
                g_propagate_error (erreur, tmp_erreur);
249
 
        }
250
 
        else if (cContent == NULL)
251
 
        {
252
 
                cd_warning ("couldn't retrieve info from '%s/%s/%s'\n check that your connection is alive, or retry later", cServerAdress, cDistantFilePath, cDistantFileName);
253
 
                g_set_error (erreur, 1, 1, "couldn't retrieve info from '%s/%s/%s'\n check that your connection is alive, or retry later", cServerAdress, cDistantFilePath, cDistantFileName);
254
 
        }
255
 
        
256
 
        g_remove (cTmpFilePath);
257
 
        g_free (cTmpFilePath);
258
 
        return cContent;
259
 
}
260
 
 
261
 
 
262
 
static void _dl_file_readme (gpointer *pSharedMemory)
263
 
{
264
 
        GError *erreur = NULL;
265
 
        pSharedMemory[5] = cairo_dock_get_distant_file_content (pSharedMemory[0], pSharedMemory[1], pSharedMemory[2], &erreur);
266
 
        if (erreur != NULL)
267
 
        {
268
 
                cd_warning (erreur->message);
269
 
                g_error_free (erreur);
270
 
        }
271
 
}
272
 
static gboolean _finish_dl_readme (gpointer *pSharedMemory)
273
 
{
274
 
        if (pSharedMemory[5] == NULL)
275
 
                cd_warning ("couldn't get distant file %s", pSharedMemory[2]);
276
 
        
277
 
        GFunc pCallback = pSharedMemory[3];
278
 
        pCallback (pSharedMemory[5], pSharedMemory[4]);
279
 
        return FALSE;
280
 
}
281
 
static void _discard_dl_readme (gpointer *pSharedMemory)
282
 
{
283
 
        g_free (pSharedMemory[0]);
284
 
        g_free (pSharedMemory[1]);
285
 
        g_free (pSharedMemory[2]);
286
 
        g_free (pSharedMemory[5]);
287
 
        g_free (pSharedMemory);
288
 
}
289
 
CairoDockTask *cairo_dock_get_distant_file_content_async (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, GFunc pCallback, gpointer data)
290
 
{
291
 
        gpointer *pSharedMemory = g_new0 (gpointer, 6);
292
 
        pSharedMemory[0] = g_strdup (cServerAdress);
293
 
        pSharedMemory[1] = g_strdup (cDistantFilePath);
294
 
        pSharedMemory[2] = g_strdup (cDistantFileName);
295
 
        pSharedMemory[3] = pCallback;
296
 
        pSharedMemory[4] = data;
297
 
        CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _dl_file_readme, (CairoDockUpdateSyncFunc) _finish_dl_readme, (GFreeFunc) _discard_dl_readme, pSharedMemory);
298
 
        cairo_dock_launch_task (pTask);
299
 
        return pTask;
300
 
}
301
 
 
302
 
 
303
 
 
304
 
static inline int _get_theme_rating (const gchar *cThemesDir, const gchar *cThemeName)
305
 
{
306
 
        gchar *cRatingFile = g_strdup_printf ("%s/.rating/%s", cThemesDir, cThemeName);
307
 
        int iRating = 0;
308
 
        gsize length = 0;
309
 
        gchar *cContent = NULL;
310
 
        g_file_get_contents (cRatingFile,
311
 
                &cContent,
312
 
                &length,
313
 
                NULL);
314
 
        if (cContent)
315
 
        {
316
 
                iRating = atoi (cContent);
317
 
                g_free (cContent);
318
 
        }
319
 
        g_free (cRatingFile);
320
 
        return iRating; 
321
 
}
322
 
GHashTable *cairo_dock_list_local_themes (const gchar *cThemesDir, GHashTable *hProvidedTable, gboolean bUpdateThemeValidity, GError **erreur)
323
 
{
324
 
        cd_debug ("%s (%s)", __func__, cThemesDir);
325
 
        GError *tmp_erreur = NULL;
326
 
        GDir *dir = g_dir_open (cThemesDir, 0, &tmp_erreur);
327
 
        if (tmp_erreur != NULL)
328
 
        {
329
 
                g_propagate_error (erreur, tmp_erreur);
330
 
                return hProvidedTable;
331
 
        }
332
 
 
333
 
        GHashTable *pThemeTable = (hProvidedTable != NULL ? hProvidedTable : g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cairo_dock_free_theme));
334
 
        
335
 
        CairoDockThemeType iType = (strncmp (cThemesDir, "/usr", 4) == 0 ?
336
 
                CAIRO_DOCK_LOCAL_THEME :
337
 
                CAIRO_DOCK_USER_THEME);
338
 
        GString *sRatingFile = g_string_new (cThemesDir);
339
 
        gchar *cThemePath;
340
 
        CairoDockTheme *pTheme;
341
 
        const gchar *cThemeName;
342
 
        while ((cThemeName = g_dir_read_name (dir)) != NULL)
343
 
        {
344
 
                // on ecarte les fichiers caches.
345
 
                if (*cThemeName == '.')
346
 
                        continue;
347
 
                
348
 
                // on ecarte les non repertoires.
349
 
                cThemePath = g_strdup_printf ("%s/%s", cThemesDir, cThemeName);
350
 
                if (! g_file_test (cThemePath, G_FILE_TEST_IS_DIR))
351
 
                {
352
 
                        g_free (cThemePath);
353
 
                        continue;
354
 
                }
355
 
                
356
 
                // on insere le theme dans la table.
357
 
                pTheme = g_new0 (CairoDockTheme, 1);
358
 
                pTheme->cThemePath = cThemePath;
359
 
                pTheme->cDisplayedName = g_strdup (cThemeName);
360
 
                pTheme->iType = iType;
361
 
                pTheme->iRating = _get_theme_rating (cThemesDir, cThemeName);
362
 
                g_hash_table_insert (pThemeTable, g_strdup (cThemeName), pTheme);  // donc ecrase un theme installe ayant le meme nom.
363
 
        }
364
 
        g_dir_close (dir);
365
 
        return pThemeTable;
366
 
}
367
 
 
368
 
static inline int _convert_date (int iDate)
369
 
{
370
 
        int d, m, y;
371
 
        y = iDate / 10000;
372
 
        m = (iDate - y*10000) / 100;
373
 
        d = iDate % 100;
374
 
        return (d + m*30 + y*365);
375
 
}
376
 
static void _cairo_dock_parse_theme_list (GKeyFile *pKeyFile, const gchar *cServerAdress, const gchar *cDirectory, GHashTable *pThemeTable)
377
 
{
378
 
        // date courante.
379
 
        time_t epoch = (time_t) time (NULL);
380
 
        struct tm currentTime;
381
 
        localtime_r (&epoch, &currentTime);
382
 
        int day = currentTime.tm_mday;  // dans l'intervalle 1 a 31.
383
 
        int month = currentTime.tm_mon + 1;  // dans l'intervalle 0 a 11.
384
 
        int year = 1900 + currentTime.tm_year;  // tm_year = nombre d'annees écoulees depuis 1900.
385
 
        int now = day + month * 30 + year * 365;
386
 
        
387
 
        // liste des themes.
388
 
        gsize length=0;
389
 
        gchar **pGroupList = g_key_file_get_groups (pKeyFile, &length);
390
 
        g_return_if_fail (pGroupList != NULL);  // rien a charger dans la table, on quitte.
391
 
        
392
 
        // on parcourt la liste.
393
 
        gchar *cThemeName, *cDate;
394
 
        CairoDockTheme *pTheme;
395
 
        CairoDockThemeType iType;
396
 
        int iCreationDate, iLastModifDate, iLocalDate, iSobriety;
397
 
        int last_modif, creation_date;
398
 
        guint i;
399
 
        for (i = 0; i < length; i ++)
400
 
        {
401
 
                cThemeName = pGroupList[i];
402
 
                iCreationDate = g_key_file_get_integer (pKeyFile, cThemeName, "creation", NULL);
403
 
                iLastModifDate = g_key_file_get_integer (pKeyFile, cThemeName, "last modif", NULL);
404
 
                iSobriety = g_key_file_get_integer (pKeyFile, cThemeName, "sobriety", NULL);
405
 
                
406
 
                // creation < 30j && pas sur le disque -> new
407
 
                // sinon last modif < 30j && last use < last modif -> updated
408
 
                // sinon -> net
409
 
                
410
 
                // on surcharge les themes locaux en cas de nouvelle version.
411
 
                CairoDockTheme *pSameTheme = g_hash_table_lookup (pThemeTable, cThemeName);
412
 
                if (pSameTheme != NULL)  // le theme existe en local.
413
 
                {
414
 
                        // on regarde de quand date cette version locale.
415
 
                        gchar *cVersionFile = g_strdup_printf ("%s/last-modif", pSameTheme->cThemePath);
416
 
                        gsize length = 0;
417
 
                        gchar *cContent = NULL;
418
 
                        g_file_get_contents (cVersionFile,
419
 
                                &cContent,
420
 
                                &length,
421
 
                                NULL);
422
 
                        if (cContent == NULL)  // le theme n'a pas encore de fichier de date
423
 
                        {
424
 
                                // on ne peut pas savoir quand l'utilisateur a mis a jour le theme pour la derniere fois;
425
 
                                // on va supposer que l'on ne met pas a jour ses themes tres regulierement, donc il est probable qu'il l'ait fait il y'a au moins 1 mois.
426
 
                                // de cette facon, les themes mis a jour recemment (il y'a moins d'1 mois) apparaitront "updated".
427
 
                                if (month > 1)
428
 
                                        iLocalDate = day + (month - 1) * 1e2 + year * 1e4;
429
 
                                else
430
 
                                        iLocalDate = day + 12 * 1e2 + (year - 1) * 1e4;
431
 
                                cDate = g_strdup_printf ("%d", iLocalDate);
432
 
                                g_file_set_contents (cVersionFile,
433
 
                                        cDate,
434
 
                                        -1,
435
 
                                        NULL);
436
 
                                g_free (cDate);
437
 
                        }
438
 
                        else
439
 
                                iLocalDate = atoi (cContent);
440
 
                        g_free (cContent);
441
 
                        
442
 
                        if (iLocalDate < iLastModifDate)  // la copie locale est plus ancienne.
443
 
                        {
444
 
                                iType = CAIRO_DOCK_UPDATED_THEME;
445
 
                        }
446
 
                        else  // c'est deja la derniere version disponible, on en reste la.
447
 
                        {
448
 
                                g_free (cVersionFile);
449
 
                                g_free (cThemeName);
450
 
                                pSameTheme->iSobriety = iSobriety;  // par contre on en profite pour renseigner la sobriete.
451
 
                                continue;
452
 
                        }
453
 
                        g_free (cVersionFile);
454
 
                        
455
 
                        pTheme = pSameTheme;
456
 
                        g_free (pTheme->cThemePath);
457
 
                        g_free (pTheme->cAuthor);
458
 
                        g_free (pTheme->cDisplayedName);
459
 
                }
460
 
                else  // theme encore jamais telecharge.
461
 
                {
462
 
                        last_modif = _convert_date (iLastModifDate);
463
 
                        creation_date = _convert_date (iCreationDate);
464
 
                        
465
 
                        if (now - creation_date < 30)  // les themes restent nouveaux pendant 1 mois.
466
 
                                iType = CAIRO_DOCK_NEW_THEME;
467
 
                        else if (now - last_modif < 30)  // les themes restent mis a jour pendant 1 mois.
468
 
                                iType = CAIRO_DOCK_UPDATED_THEME;
469
 
                        else
470
 
                                iType = CAIRO_DOCK_DISTANT_THEME;
471
 
                        
472
 
                        pTheme = g_new0 (CairoDockTheme, 1);
473
 
                        g_hash_table_insert (pThemeTable, cThemeName, pTheme);
474
 
                        pTheme->iRating = g_key_file_get_integer (pKeyFile, cThemeName, "rating", NULL);  // // par contre on affiche la note que l'utilisateur avait precedemment etablie.
475
 
                }
476
 
                
477
 
                pTheme->cThemePath = g_strdup_printf ("%s/%s/%s", cServerAdress, cDirectory, cThemeName);
478
 
                pTheme->iType = iType;
479
 
                pTheme->fSize = g_key_file_get_double (pKeyFile, cThemeName, "size", NULL);
480
 
                pTheme->cAuthor = g_key_file_get_string (pKeyFile, cThemeName, "author", NULL);
481
 
                if (pTheme->cAuthor && *pTheme->cAuthor == '\0')
482
 
                {
483
 
                        g_free (pTheme->cAuthor);
484
 
                        pTheme->cAuthor = NULL;
485
 
                }
486
 
                pTheme->iSobriety = iSobriety;
487
 
                pTheme->iCreationDate = iCreationDate;
488
 
                pTheme->iLastModifDate = iLastModifDate;
489
 
                pTheme->cDisplayedName = g_strdup_printf ("%s by %s [%.2f MB]", cThemeName, (pTheme->cAuthor ? pTheme->cAuthor : "---"), pTheme->fSize);
490
 
        }
491
 
        g_free (pGroupList);  // les noms des themes sont desormais dans la hash-table.
492
 
}
493
 
GHashTable *cairo_dock_list_net_themes (const gchar *cServerAdress, const gchar *cDirectory, const gchar *cListFileName, GHashTable *hProvidedTable, GError **erreur)
494
 
{
495
 
        g_return_val_if_fail (cServerAdress != NULL && *cServerAdress != '\0', hProvidedTable);
496
 
        cd_message ("listing net themes on %s/%s ...", cServerAdress, cDirectory);
497
 
        
498
 
        // On recupere la liste des themes distants.
499
 
        GError *tmp_erreur = NULL;
500
 
        gchar *cContent = cairo_dock_get_distant_file_content (cServerAdress, cDirectory, cListFileName, &tmp_erreur);
501
 
        if (tmp_erreur != NULL)
502
 
        {
503
 
                cd_warning ("couldn't retrieve themes on %s (check that your connection is alive, or retry later)", cServerAdress);
504
 
                g_propagate_error (erreur, tmp_erreur);
505
 
                return hProvidedTable;
506
 
        }
507
 
        
508
 
        // on verifie son integrite.
509
 
        if (cContent == NULL || strncmp (cContent, "#!CD", 4) != 0)  // avec une connexion wifi etablie sur un operateur auquel on ne s'est pas logue, il peut nous renvoyer des messages au lieu de juste rien. On filtre ca par un entete dedie.
510
 
        {
511
 
                cd_warning ("empty themes list on %s (check that your connection is alive, or retry later)", cServerAdress);
512
 
                g_set_error (erreur, 1, 1, "empty themes list on %s", cServerAdress);
513
 
                g_free (cContent);
514
 
                return hProvidedTable;
515
 
        }
516
 
        
517
 
        // petit bonus : on a la derniere version du dock sur la 1ere ligne.
518
 
        if (cContent[4] != '\n')
519
 
        {
520
 
                int iMajorVersion=0, iMinorVersion=0, iMicroVersion=0;
521
 
                cairo_dock_get_version_from_string (cContent+4, &iMajorVersion, &iMinorVersion, &iMicroVersion);
522
 
                g_print ("%d/%d/%d\n", iMajorVersion, iMinorVersion, iMicroVersion);
523
 
                if (iMajorVersion > g_iMajorVersion ||
524
 
                        (iMajorVersion == g_iMajorVersion &&
525
 
                                (iMinorVersion > g_iMinorVersion ||
526
 
                                        (iMinorVersion == g_iMinorVersion && iMicroVersion > g_iMicroVersion))))
527
 
                {
528
 
                        g_print ("A new version is available !\n>>>\n%d.%d.%d\n<<<\n", iMajorVersion, iMinorVersion, iMicroVersion);
529
 
                }
530
 
        }
531
 
        
532
 
        // on charge la liste dans un fichier de cles.
533
 
        GKeyFile *pKeyFile = g_key_file_new ();
534
 
        g_key_file_load_from_data (pKeyFile,
535
 
                cContent,
536
 
                -1,
537
 
                G_KEY_FILE_NONE,
538
 
                &tmp_erreur);
539
 
        g_free (cContent);
540
 
        if (tmp_erreur != NULL)
541
 
        {
542
 
                cd_warning ("invalid list of themes (%s)\n(check that your connection is alive, or retry later)", cServerAdress);
543
 
                g_propagate_error (erreur, tmp_erreur);
544
 
                g_key_file_free (pKeyFile);
545
 
                return hProvidedTable;
546
 
        }
547
 
        
548
 
        // on parse la liste dans une table de hashage.
549
 
        GHashTable *pThemeTable = (hProvidedTable != NULL ? hProvidedTable : g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cairo_dock_free_theme));
550
 
        
551
 
        _cairo_dock_parse_theme_list (pKeyFile, cServerAdress, cDirectory, pThemeTable);
552
 
        
553
 
        g_key_file_free (pKeyFile);
554
 
        
555
 
        return pThemeTable;
556
 
}
557
 
 
558
 
GHashTable *cairo_dock_list_themes (const gchar *cShareThemesDir, const gchar *cUserThemesDir, const gchar *cDistantThemesDir)
559
 
{
560
 
        cd_message ("%s (%s, %s, %s)", __func__, cShareThemesDir, cUserThemesDir, cDistantThemesDir);
561
 
        GError *erreur = NULL;
562
 
        GHashTable *pThemeTable = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cairo_dock_free_theme);
563
 
        
564
 
        //\______________ On recupere les themes pre-installes.
565
 
        if (cShareThemesDir != NULL)
566
 
                pThemeTable = cairo_dock_list_local_themes (cShareThemesDir, pThemeTable, cDistantThemesDir != NULL, &erreur);
567
 
        if (erreur != NULL)
568
 
        {
569
 
                cd_warning ("while loading pre-installed themes in '%s' : %s", cShareThemesDir, erreur->message);
570
 
                g_error_free (erreur);
571
 
                erreur = NULL;
572
 
        }
573
 
        
574
 
        //\______________ On recupere les themes utilisateurs (qui ecrasent donc les precedents).
575
 
        if (cUserThemesDir != NULL)
576
 
                pThemeTable = cairo_dock_list_local_themes (cUserThemesDir, pThemeTable, cDistantThemesDir != NULL, &erreur);
577
 
        if (erreur != NULL)
578
 
        {
579
 
                cd_warning ("while loading user themes in '%s' : %s", cShareThemesDir, erreur->message);
580
 
                g_error_free (erreur);
581
 
                erreur = NULL;
582
 
        }
583
 
        
584
 
        //\______________ On recupere les themes distants (qui surchargent tous les themes).
585
 
        if (cDistantThemesDir != NULL)
586
 
                pThemeTable = cairo_dock_list_net_themes (g_cThemeServerAdress != NULL ? g_cThemeServerAdress : CAIRO_DOCK_THEME_SERVER, cDistantThemesDir, CAIRO_DOCK_DEFAULT_THEME_LIST_NAME, pThemeTable, &erreur);
587
 
        if (erreur != NULL)
588
 
        {
589
 
                cd_warning ("while loading distant themes in '%s/%s' : %s", g_cThemeServerAdress != NULL ? g_cThemeServerAdress : CAIRO_DOCK_THEME_SERVER, cDistantThemesDir, erreur->message);
590
 
                g_error_free (erreur);
591
 
                erreur = NULL;
592
 
        }
593
 
        
594
 
        return pThemeTable;
595
 
}
596
 
 
597
 
static void _list_themes (gpointer *pSharedMemory)
598
 
{
599
 
        pSharedMemory[5] = cairo_dock_list_themes (pSharedMemory[0], pSharedMemory[1], pSharedMemory[2]);
600
 
}
601
 
static gboolean _finish_list_themes (gpointer *pSharedMemory)
602
 
{
603
 
        if (pSharedMemory[5] == NULL)
604
 
                cd_warning ("couldn't get distant themes in '%s'", pSharedMemory[2]);
605
 
        
606
 
        GFunc pCallback = pSharedMemory[3];
607
 
        pCallback (pSharedMemory[5], pSharedMemory[4]);
608
 
        
609
 
        return FALSE;
610
 
}
611
 
static void _discard_list_themes (gpointer *pSharedMemory)
612
 
{
613
 
        g_free (pSharedMemory[0]);
614
 
        g_free (pSharedMemory[1]);
615
 
        g_free (pSharedMemory[2]);
616
 
        g_hash_table_unref (pSharedMemory[5]);
617
 
        g_free (pSharedMemory);
618
 
}
619
 
CairoDockTask *cairo_dock_list_themes_async (const gchar *cShareThemesDir, const gchar *cUserThemesDir, const gchar *cDistantThemesDir, GFunc pCallback, gpointer data)
620
 
{
621
 
        gpointer *pSharedMemory = g_new0 (gpointer, 6);
622
 
        pSharedMemory[0] = g_strdup (cShareThemesDir);
623
 
        pSharedMemory[1] = g_strdup (cUserThemesDir);
624
 
        pSharedMemory[2] = g_strdup (cDistantThemesDir);
625
 
        pSharedMemory[3] = pCallback;
626
 
        pSharedMemory[4] = data;
627
 
        CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _list_themes, (CairoDockUpdateSyncFunc) _finish_list_themes, (GFreeFunc) _discard_list_themes, pSharedMemory);
628
 
        cairo_dock_launch_task (pTask);
629
 
        return pTask;
630
 
}
631
 
 
632
 
gchar *cairo_dock_get_theme_path (const gchar *cThemeName, const gchar *cShareThemesDir, const gchar *cUserThemesDir, const gchar *cDistantThemesDir, CairoDockThemeType iGivenType)
633
 
{
634
 
        cd_message ("%s (%s, %s, %s)", __func__, cShareThemesDir, cUserThemesDir, cDistantThemesDir);
635
 
        if (cThemeName == NULL || *cThemeName == '\0')
636
 
                return NULL;
637
 
        CairoDockThemeType iType = cairo_dock_extract_theme_type_from_name (cThemeName);
638
 
        if (iType == CAIRO_DOCK_ANY_THEME)
639
 
                iType = iGivenType;
640
 
        gchar *cThemePath = NULL;
641
 
        
642
 
        //g_print ("iType : %d\n", iType);
643
 
        if (cUserThemesDir != NULL && /*iType != CAIRO_DOCK_DISTANT_THEME && iType != CAIRO_DOCK_NEW_THEME && */iType != CAIRO_DOCK_UPDATED_THEME)
644
 
        {
645
 
                cThemePath = g_strdup_printf ("%s/%s", cUserThemesDir, cThemeName);
646
 
                
647
 
                if (g_file_test (cThemePath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
648
 
                {
649
 
                        return cThemePath;
650
 
                }
651
 
                
652
 
                g_free (cThemePath);
653
 
                cThemePath = NULL;
654
 
        }
655
 
        
656
 
        if (cShareThemesDir != NULL && /*iType != CAIRO_DOCK_DISTANT_THEME && iType != CAIRO_DOCK_NEW_THEME && */iType != CAIRO_DOCK_UPDATED_THEME)
657
 
        {
658
 
                cThemePath = g_strdup_printf ("%s/%s", cShareThemesDir, cThemeName);
659
 
                if (g_file_test (cThemePath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
660
 
                        return cThemePath;
661
 
                g_free (cThemePath);
662
 
                cThemePath = NULL;
663
 
        }
664
 
        
665
 
        if (cDistantThemesDir != NULL)
666
 
        {
667
 
                gchar *cDistantFileName = g_strdup_printf ("%s/%s.tar.gz", cThemeName, cThemeName);
668
 
                GError *erreur = NULL;
669
 
                cThemePath = cairo_dock_download_file (g_cThemeServerAdress != NULL ? g_cThemeServerAdress : CAIRO_DOCK_THEME_SERVER, cDistantThemesDir, cDistantFileName, cUserThemesDir, &erreur);
670
 
                g_free (cDistantFileName);
671
 
                if (erreur != NULL)
672
 
                {
673
 
                        cd_warning ("couldn't retrieve distant theme %s : %s" , cThemeName, erreur->message);
674
 
                        g_error_free (erreur);
675
 
                }
676
 
                else  // on se souvient de la date a laquelle on a mis a jour le theme pour la derniere fois.
677
 
                {
678
 
                        gchar *cVersionFile = g_strdup_printf ("%s/last-modif", cThemePath);
679
 
                        time_t epoch = (time_t) time (NULL);
680
 
                        struct tm currentTime;
681
 
                        localtime_r (&epoch, &currentTime);
682
 
                        int now = (currentTime.tm_mday+1) + (currentTime.tm_mon+1) * 1e2 + (1900+currentTime.tm_year) * 1e4;
683
 
                        gchar *cDate = g_strdup_printf ("%d", now);
684
 
                        g_file_set_contents (cVersionFile,
685
 
                                cDate,
686
 
                                -1,
687
 
                                NULL);
688
 
                        g_free (cDate);
689
 
                        g_free (cVersionFile);
690
 
                }
691
 
        }
692
 
        
693
 
        cd_debug (" ====> cThemePath : %s", cThemePath);
694
 
        return cThemePath;
695
 
}
696
 
 
697
 
 
698
 
 
699
 
void cairo_dock_mark_theme_as_modified (gboolean bModified)
700
 
{
701
 
        gchar *cModifiedFile = g_strdup_printf ("%s/%s", g_cCairoDockDataDir, CAIRO_DOCK_MODIFIED_THEME_FILE);
702
 
 
703
 
        g_file_set_contents (cModifiedFile,
704
 
                (bModified ? "1" : "0"),
705
 
                -1,
706
 
                NULL);
707
 
 
708
 
        g_free (cModifiedFile);
709
 
}
710
 
 
711
 
gboolean cairo_dock_theme_need_save (void)
712
 
{
713
 
        gchar *cModifiedFile = g_strdup_printf ("%s/%s", g_cCairoDockDataDir, CAIRO_DOCK_MODIFIED_THEME_FILE);
714
 
        gsize length = 0;
715
 
        gchar *cContent = NULL;
716
 
        g_file_get_contents (cModifiedFile,
717
 
                &cContent,
718
 
                &length,
719
 
                NULL);
720
 
        g_free (cModifiedFile);
721
 
        gboolean bNeedSave;
722
 
        if (length > 0)
723
 
                bNeedSave = (*cContent == '1');
724
 
        else
725
 
                bNeedSave = FALSE;
726
 
        g_free (cContent);
727
 
        return bNeedSave;
728
 
}
729
 
 
730
 
 
731
 
 
732
 
static void on_theme_destroy (gchar *cInitConfFile)
733
 
{
734
 
        cd_debug ("");
735
 
        g_remove (cInitConfFile);
736
 
        g_free (cInitConfFile);
737
 
        s_pThemeManager = NULL;
738
 
}
739
 
 
740
 
CairoDockThemeType cairo_dock_extract_theme_type_from_name (const gchar *cThemeName)
741
 
{
742
 
        if (cThemeName == NULL)
743
 
                return CAIRO_DOCK_ANY_THEME;
744
 
        CairoDockThemeType iType = CAIRO_DOCK_ANY_THEME;
745
 
        int l = strlen (cThemeName);
746
 
        if (cThemeName[l-1] == ']')
747
 
        {
748
 
                gchar *str = strrchr (cThemeName, '[');
749
 
                if (str != NULL && g_ascii_isdigit (*(str+1)))
750
 
                {
751
 
                        iType = atoi (str+1);
752
 
                        *str = '\0';
753
 
                }
754
 
        }
755
 
        return iType;
756
 
}
757
 
 
758
 
gboolean cairo_dock_export_current_theme (const gchar *cNewThemeName, gboolean bSaveBehavior, gboolean bSaveLaunchers)
759
 
{
760
 
        g_return_val_if_fail (cNewThemeName != NULL, FALSE);
761
 
        
762
 
        cairo_dock_extract_theme_type_from_name (cNewThemeName);
763
 
        
764
 
        cd_message ("on sauvegarde dans %s", cNewThemeName);
765
 
        GString *sCommand = g_string_new ("");
766
 
        gboolean bThemeSaved = FALSE;
767
 
        int r;
768
 
        gchar *cNewThemePath = g_strdup_printf ("%s/%s/%s", g_cCairoDockDataDir, CAIRO_DOCK_THEMES_DIR, cNewThemeName);
769
 
        if (g_file_test (cNewThemePath, G_FILE_TEST_EXISTS))  // on ecrase un theme existant.
770
 
        {
771
 
                cd_debug ("  le theme existant sera mis a jour");
772
 
                gchar *cQuestion = g_strdup_printf (_("Are you sure you want to overwrite theme %s ?"), cNewThemeName);
773
 
                int answer = cairo_dock_ask_general_question_and_wait (cQuestion);
774
 
                g_free (cQuestion);
775
 
                if (answer == GTK_RESPONSE_YES)
776
 
                {
777
 
                        //\___________________ On traite le fichier de conf.
778
 
                        gchar *cNewConfFilePath = g_strdup_printf ("%s/%s", cNewThemePath, CAIRO_DOCK_CONF_FILE);
779
 
                        if (bSaveBehavior)
780
 
                        {
781
 
                                g_string_printf (sCommand, "/bin/cp \"%s\" \"%s\"", g_cConfFile, cNewConfFilePath);
782
 
                                cd_message ("%s", sCommand->str);
783
 
                                r = system (sCommand->str);
784
 
                        }
785
 
                        else
786
 
                        {
787
 
                                cairo_dock_replace_keys_by_identifier (cNewConfFilePath, g_cConfFile, '+');
788
 
                        }
789
 
                        g_free (cNewConfFilePath);
790
 
                        
791
 
                        //\___________________ On traite les lanceurs.
792
 
                        if (bSaveLaunchers)
793
 
                        {
794
 
                                g_string_printf (sCommand, "rm -f \"%s/%s\"/*", cNewThemePath, CAIRO_DOCK_LAUNCHERS_DIR);
795
 
                                cd_message ("%s", sCommand->str);
796
 
                                r = system (sCommand->str);
797
 
                                
798
 
                                g_string_printf (sCommand, "cp \"%s\"/* \"%s/%s\"", g_cCurrentLaunchersPath, cNewThemePath, CAIRO_DOCK_LAUNCHERS_DIR);
799
 
                                cd_message ("%s", sCommand->str);
800
 
                                r = system (sCommand->str);
801
 
                        }
802
 
                        
803
 
                        //\___________________ On traite tous le reste.
804
 
                        /// TODO : traiter les .conf des applets comme celui du dock...
805
 
                        g_string_printf (sCommand, "find \"%s\" -mindepth 1 -maxdepth 1  ! -name '*.conf' ! -name \"%s\" -exec /bin/cp -r '{}' \"%s\" \\;", g_cCurrentThemePath, CAIRO_DOCK_LAUNCHERS_DIR, cNewThemePath);
806
 
                        cd_message ("%s", sCommand->str);
807
 
                        r = system (sCommand->str);
808
 
 
809
 
                        bThemeSaved = TRUE;
810
 
                }
811
 
        }
812
 
        else  // sinon on sauvegarde le repertoire courant tout simplement.
813
 
        {
814
 
                cd_debug ("  creation du nouveau theme (%s)", cNewThemePath);
815
 
 
816
 
                if (g_mkdir (cNewThemePath, 7*8*8+7*8+5) == 0)
817
 
                {
818
 
                        g_string_printf (sCommand, "cp -r \"%s\"/* \"%s\"", g_cCurrentThemePath, cNewThemePath);
819
 
                        cd_message ("%s", sCommand->str);
820
 
                        r = system (sCommand->str);
821
 
 
822
 
                        bThemeSaved = TRUE;
823
 
                }
824
 
                else
825
 
                        cd_warning ("couldn't create %s", cNewThemePath);
826
 
        }
827
 
        
828
 
        g_free (cNewThemePath);
829
 
        if (bThemeSaved)
830
 
        {
831
 
                cairo_dock_mark_theme_as_modified (FALSE);
832
 
        }
833
 
        
834
 
        g_string_free (sCommand, TRUE);
835
 
        
836
 
        return bThemeSaved;
837
 
}
838
 
 
839
 
gboolean cairo_dock_package_current_theme (const gchar *cThemeName)
840
 
{
841
 
        g_return_val_if_fail (cThemeName != NULL, FALSE);
842
 
        
843
 
        cairo_dock_extract_theme_type_from_name (cThemeName);
844
 
        
845
 
        cd_message ("building theme package ...");
846
 
        int r;
847
 
        if (g_file_test (CAIRO_DOCK_SHARE_DATA_DIR"/../../bin/cairo-dock-package-theme", G_FILE_TEST_EXISTS))
848
 
        {
849
 
                gchar *cCommand;
850
 
                const gchar *cTerm = g_getenv ("TERM");
851
 
                if (cTerm == NULL || *cTerm == '\0')
852
 
                        cCommand = g_strdup_printf ("xterm -e %s \"%s\"", "cairo-dock-package-theme", cThemeName);
853
 
                else
854
 
                        cCommand = g_strdup_printf ("$TERM -e '%s \"%s\"'", "cairo-dock-package-theme", cThemeName);
855
 
                r = system (cCommand);
856
 
                g_free (cCommand);
857
 
                return TRUE;
858
 
        }
859
 
        else
860
 
        {
861
 
                cd_warning ("the package builder script was not found !");
862
 
                return FALSE;
863
 
        }
864
 
}
865
 
gchar *cairo_dock_depackage_theme (const gchar *cPackagePath)
866
 
{
867
 
        gchar *cUserThemesDir = g_strdup_printf ("%s/%s", g_cCairoDockDataDir, CAIRO_DOCK_THEMES_DIR);
868
 
        gchar *cNewThemePath = NULL;
869
 
        if (*cPackagePath == '/' || strncmp (cPackagePath, "file://", 7) == 0)  // paquet en local.
870
 
        {
871
 
                g_print (" paquet local\n");
872
 
                gchar *cFilePath = (*cPackagePath == '/' ? g_strdup (cPackagePath) : g_filename_from_uri (cPackagePath, NULL, NULL));
873
 
                cNewThemePath = cairo_dock_uncompress_file (cFilePath, cUserThemesDir, NULL);
874
 
                g_free (cFilePath);
875
 
        }
876
 
        else  // paquet distant.
877
 
        {
878
 
                g_print (" paquet distant\n");
879
 
                gchar *str = strrchr (cPackagePath, '/');
880
 
                if (str != NULL)
881
 
                {
882
 
                        *str = '\0';
883
 
                        cNewThemePath = cairo_dock_download_file (cPackagePath, "", str+1, cUserThemesDir, NULL);
884
 
                        if (cNewThemePath == NULL)
885
 
                        {
886
 
                                cairo_dock_show_temporary_dialog_with_icon_printf (_("couldn't get distant file %s/%s, maybe the server is down.\nPlease retry later or contact us at glx-dock.org."), NULL, NULL, 0, NULL, cPackagePath, str+1);
887
 
                        }
888
 
                }
889
 
        }
890
 
        g_free (cUserThemesDir);
891
 
        return cNewThemePath;
892
 
}
893
 
 
894
 
gboolean cairo_dock_delete_themes (gchar **cThemesList)
895
 
{
896
 
        g_return_val_if_fail (cThemesList != NULL && cThemesList[0] != NULL, FALSE);
897
 
        
898
 
        GString *sCommand = g_string_new ("");
899
 
        gboolean bThemeDeleted = FALSE;
900
 
        
901
 
        if (cThemesList[1] == NULL)
902
 
                g_string_printf (sCommand, _("Are you sure you want to delete theme %s ?"), cThemesList[0]);
903
 
        else
904
 
                g_string_printf (sCommand, _("Are you sure you want to delete these themes ?"));
905
 
        int answer = cairo_dock_ask_general_question_and_wait (sCommand->str);
906
 
        if (answer == GTK_RESPONSE_YES)
907
 
        {
908
 
                gchar *cThemeName;
909
 
                int i, r;
910
 
                for (i = 0; cThemesList[i] != NULL; i ++)
911
 
                {
912
 
                        cThemeName = cThemesList[i];
913
 
                        if (*cThemeName == '\0')
914
 
                                continue;
915
 
                        cairo_dock_extract_theme_type_from_name (cThemeName);
916
 
                        
917
 
                        bThemeDeleted = TRUE;
918
 
                        g_string_printf (sCommand, "rm -rf \"%s/%s/%s\"", g_cCairoDockDataDir, CAIRO_DOCK_THEMES_DIR, cThemeName);
919
 
                        r = system (sCommand->str);  // g_rmdir n'efface qu'un repertoire vide.
920
 
                }
921
 
        }
922
 
        
923
 
        g_string_free (sCommand, TRUE);
924
 
        return bThemeDeleted;
925
 
}
926
 
 
927
 
static gboolean _find_module_from_user_data_dir (gchar *cModuleName, CairoDockModule *pModule, const gchar *cUserDataDirName)
928
 
{
929
 
        if (pModule->pVisitCard->cUserDataDir && strcmp (cUserDataDirName, pModule->pVisitCard->cUserDataDir) == 0)
930
 
                return TRUE;
931
 
        return FALSE;
932
 
}
933
 
gboolean cairo_dock_import_theme (const gchar *cThemeName, gboolean bLoadBehavior, gboolean bLoadLaunchers)
934
 
{
935
 
        //\___________________ On regarde si le theme courant est modifie.
936
 
        /*gboolean bNeedSave = cairo_dock_theme_need_save ();
937
 
        if (bNeedSave)
938
 
        {
939
 
                int iAnswer = cairo_dock_ask_general_question_and_wait (_("You made some modifications in the current theme.\nYou will loose them if you don't save before choosing a new theme. Continue anyway ?"));
940
 
                if (iAnswer != GTK_RESPONSE_YES)
941
 
                {
942
 
                        return FALSE;
943
 
                }
944
 
                cairo_dock_mark_theme_as_modified (FALSE);
945
 
        }*/  // pas dans un thread.
946
 
        
947
 
        //\___________________ On obtient le chemin du nouveau theme (telecharge ou decompresse si necessaire).
948
 
        gchar *cNewThemeName = g_strdup (cThemeName);
949
 
        gchar *cNewThemePath = NULL;
950
 
        
951
 
        int length = strlen (cNewThemeName);
952
 
        if (cNewThemeName[length-1] == '\n')
953
 
                cNewThemeName[--length] = '\0';  // on vire le retour chariot final.
954
 
        if (cNewThemeName[length-1] == '\r')
955
 
                cNewThemeName[--length] = '\0';
956
 
        cd_debug ("cNewThemeName : '%s'", cNewThemeName);
957
 
        
958
 
        if (g_str_has_suffix (cNewThemeName, ".tar.gz") || g_str_has_suffix (cNewThemeName, ".tar.bz2") || g_str_has_suffix (cNewThemeName, ".tgz"))  // c'est un paquet.
959
 
        {
960
 
                cd_debug ("c'est un paquet");
961
 
                cNewThemePath = cairo_dock_depackage_theme (cNewThemeName);
962
 
                
963
 
                g_return_val_if_fail (cNewThemePath != NULL, FALSE);
964
 
                gchar *tmp = cNewThemeName;
965
 
                cNewThemeName = g_path_get_basename (cNewThemePath);
966
 
                g_free (tmp);
967
 
        }
968
 
        else  // c'est un theme officiel.
969
 
        {
970
 
                cd_debug ("c'est un theme officiel");
971
 
                gchar *cUserThemesDir = g_strdup_printf ("%s/%s", g_cCairoDockDataDir, CAIRO_DOCK_THEMES_DIR);
972
 
                cNewThemePath = cairo_dock_get_theme_path (cNewThemeName, CAIRO_DOCK_SHARE_THEMES_DIR, cUserThemesDir, CAIRO_DOCK_THEMES_DIR, CAIRO_DOCK_ANY_THEME);
973
 
                g_free (cUserThemesDir);
974
 
        }
975
 
        g_return_val_if_fail (cNewThemePath != NULL && g_file_test (cNewThemePath, G_FILE_TEST_EXISTS), FALSE);
976
 
        //g_print ("cNewThemePath : %s ; cNewThemeName : %s\n", cNewThemePath, cNewThemeName);
977
 
        
978
 
        //\___________________ On charge les parametres de comportement.
979
 
        GString *sCommand = g_string_new ("");
980
 
        int r;
981
 
        cd_message ("Applying changes ...");
982
 
        if (g_pMainDock == NULL || bLoadBehavior)
983
 
        {
984
 
                g_string_printf (sCommand, "/bin/cp \"%s\"/%s \"%s\"", cNewThemePath, CAIRO_DOCK_CONF_FILE, g_cCurrentThemePath);
985
 
                cd_message ("%s", sCommand->str);
986
 
                r = system (sCommand->str);
987
 
        }
988
 
        else
989
 
        {
990
 
                gchar *cNewConfFilePath = g_strdup_printf ("%s/%s", cNewThemePath, CAIRO_DOCK_CONF_FILE);
991
 
                cairo_dock_replace_keys_by_identifier (g_cConfFile, cNewConfFilePath, '+');
992
 
                g_free (cNewConfFilePath);
993
 
        }
994
 
        
995
 
        //\___________________ On charge les .conf des autres docks racines.
996
 
        g_string_printf (sCommand, "find \"%s\" -mindepth 1 -maxdepth 1 -name '*.conf' ! -name '%s' -exec /bin/cp '{}' \"%s\" \\;", cNewThemePath, CAIRO_DOCK_CONF_FILE, g_cCurrentThemePath);
997
 
        cd_debug ("%s", sCommand->str);
998
 
        r = system (sCommand->str);
999
 
        
1000
 
        //\___________________ On charge les lanceurs.
1001
 
        if (bLoadLaunchers)
1002
 
        {
1003
 
                g_string_printf (sCommand, "rm -f \"%s/%s\"/*", g_cCurrentThemePath, CAIRO_DOCK_LOCAL_ICONS_DIR);
1004
 
                cd_debug ("%s", sCommand->str);
1005
 
                r = system (sCommand->str);
1006
 
                g_string_printf (sCommand, "rm -f \"%s/%s\"/.*", g_cCurrentThemePath, CAIRO_DOCK_LOCAL_ICONS_DIR);
1007
 
                cd_debug ("%s", sCommand->str);
1008
 
                r = system (sCommand->str);
1009
 
        }
1010
 
        
1011
 
        //\___________________ On charge les icones.
1012
 
        gchar *cNewLocalIconsPath = g_strdup_printf ("%s/%s", cNewThemePath, CAIRO_DOCK_LOCAL_ICONS_DIR);
1013
 
        if (! g_file_test (cNewLocalIconsPath, G_FILE_TEST_IS_DIR))  // c'est un ancien theme, on deplace les icones vers le repertoire 'icons'.
1014
 
        {
1015
 
                g_string_printf (sCommand, "find \"%s/%s\" -mindepth 1 ! -name '*.desktop' -exec /bin/cp '{}' '%s/%s' \\;", cNewThemePath, CAIRO_DOCK_LAUNCHERS_DIR, g_cCurrentThemePath, CAIRO_DOCK_LOCAL_ICONS_DIR);
1016
 
        }
1017
 
        else
1018
 
        {
1019
 
                g_string_printf (sCommand, "for f in \"%s\"/* ; do rm -f \"%s/%s/`basename \"${f%%.*}\"`\"*; done;", cNewLocalIconsPath, g_cCurrentThemePath, CAIRO_DOCK_LOCAL_ICONS_DIR);  // on efface les doublons car sinon on pourrait avoir x.png et x.svg ensemble et le dock ne saurait pas lequel choisir.
1020
 
                cd_debug ("%s", sCommand->str);
1021
 
                r = system (sCommand->str);
1022
 
                
1023
 
                g_string_printf (sCommand, "cp \"%s\"/* \"%s/%s\"", cNewLocalIconsPath, g_cCurrentThemePath, CAIRO_DOCK_LOCAL_ICONS_DIR);
1024
 
        }
1025
 
        cd_debug ("%s", sCommand->str);
1026
 
        r = system (sCommand->str);
1027
 
        g_free (cNewLocalIconsPath);
1028
 
        
1029
 
        //\___________________ On charge les extras.
1030
 
        g_string_printf (sCommand, "%s/%s", cNewThemePath, CAIRO_DOCK_EXTRAS_DIR);
1031
 
        if (g_file_test (sCommand->str, G_FILE_TEST_IS_DIR))
1032
 
        {
1033
 
                g_string_printf (sCommand, "cp -r \"%s/%s\"/* \"%s/%s\"", cNewThemePath, CAIRO_DOCK_EXTRAS_DIR, g_cCairoDockDataDir, CAIRO_DOCK_EXTRAS_DIR);
1034
 
                cd_debug ("%s", sCommand->str);
1035
 
                r = system (sCommand->str);
1036
 
        }
1037
 
        
1038
 
        //\___________________ On charge les lanceurs si necessaire, en effacant ceux existants.
1039
 
        if (! g_file_test (g_cCurrentLaunchersPath, G_FILE_TEST_EXISTS))
1040
 
        {
1041
 
                gchar *command = g_strdup_printf ("mkdir -p \"%s\"", g_cCurrentLaunchersPath);
1042
 
                r = system (command);
1043
 
                g_free (command);
1044
 
        }
1045
 
        if (g_pMainDock == NULL || bLoadLaunchers)
1046
 
        {
1047
 
                g_string_printf (sCommand, "rm -f \"%s\"/*.desktop", g_cCurrentLaunchersPath);
1048
 
                cd_debug ("%s", sCommand->str);
1049
 
                r = system (sCommand->str);
1050
 
 
1051
 
                g_string_printf (sCommand, "cp \"%s/%s\"/*.desktop \"%s\"", cNewThemePath, CAIRO_DOCK_LAUNCHERS_DIR, g_cCurrentLaunchersPath);
1052
 
                cd_debug ("%s", sCommand->str);
1053
 
                r = system (sCommand->str);
1054
 
        }
1055
 
        
1056
 
        //\___________________ On remplace tous les autres fichiers par les nouveaux.
1057
 
        g_string_printf (sCommand, "find \"%s\" -mindepth 1 -maxdepth 1  ! -name '*.conf' -type f -exec rm -f '{}' \\;", g_cCurrentThemePath);  // efface tous les fichiers du theme mais sans toucher aux lanceurs et aux plug-ins.
1058
 
        cd_debug ("%s", sCommand->str);
1059
 
        r = system (sCommand->str);
1060
 
 
1061
 
        if (g_pMainDock == NULL || bLoadBehavior)
1062
 
        {
1063
 
                g_string_printf (sCommand, "find \"%s\"/* -prune ! -name '*.conf' ! -name %s -exec /bin/cp -r '{}' \"%s\" \\;", cNewThemePath, CAIRO_DOCK_LAUNCHERS_DIR, g_cCurrentThemePath);  // copie tous les fichiers du nouveau theme sauf les lanceurs et le .conf, dans le repertoire du theme courant. Ecrase les fichiers de memes noms.
1064
 
                cd_debug ("%s", sCommand->str);
1065
 
                r = system (sCommand->str);
1066
 
        }
1067
 
        else
1068
 
        {
1069
 
                // on copie tous les fichiers du nouveau theme sauf les lanceurs et les .conf (dock et plug-ins).
1070
 
                g_string_printf (sCommand, "find \"%s\" -mindepth 1 ! -name '*.conf' ! -path '%s/%s*' ! -type d -exec cp -p {} \"%s\" \\;", cNewThemePath, cNewThemePath, CAIRO_DOCK_LAUNCHERS_DIR, g_cCurrentThemePath);
1071
 
                cd_debug ("%s", sCommand->str);
1072
 
                r = system (sCommand->str);
1073
 
                
1074
 
                // on parcours les .conf des plug-ins, on les met a jour, et on fusionne avec le theme courant.
1075
 
                gchar *cNewPlugInsDir = g_strdup_printf ("%s/%s", cNewThemePath, "plug-ins");  // repertoire des plug-ins du nouveau theme.
1076
 
                GDir *dir = g_dir_open (cNewPlugInsDir, 0, NULL);  // NULL si ce theme n'a pas de repertoire 'plug-ins'.
1077
 
                const gchar* cModuleDirName;
1078
 
                gchar *cConfFilePath, *cNewConfFilePath, *cUserDataDirPath, *cConfFileName;
1079
 
                do
1080
 
                {
1081
 
                        cModuleDirName = g_dir_read_name (dir);  // nom du repertoire du theme (pas forcement egal au nom du theme)
1082
 
                        if (cModuleDirName == NULL)
1083
 
                                break ;
1084
 
                        
1085
 
                        // on cree le repertoire du plug-in dans le theme courant.
1086
 
                        cd_debug ("  installing %s's config", cModuleDirName);
1087
 
                        cUserDataDirPath = g_strdup_printf ("%s/plug-ins/%s", g_cCurrentThemePath, cModuleDirName);  // repertoire du plug-in dans le theme courant.
1088
 
                        if (! g_file_test (cUserDataDirPath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
1089
 
                        {
1090
 
                                cd_debug ("    directory %s doesn't exist, it will be created.", cUserDataDirPath);
1091
 
                                
1092
 
                                g_string_printf (sCommand, "mkdir -p \"%s\"", cUserDataDirPath);
1093
 
                                r = system (sCommand->str);
1094
 
                        }
1095
 
                        
1096
 
                        // on recupere le nom et le chemin du .conf du plug-in dans le nouveau theme.
1097
 
                        cConfFileName = g_strdup_printf ("%s.conf", cModuleDirName);
1098
 
                        cNewConfFilePath = g_strdup_printf ("%s/%s/%s", cNewPlugInsDir, cModuleDirName, cConfFileName);
1099
 
                        if (! g_file_test (cNewConfFilePath, G_FILE_TEST_EXISTS))
1100
 
                        {
1101
 
                                g_free (cConfFileName);
1102
 
                                g_free (cNewConfFilePath);
1103
 
                                CairoDockModule *pModule = cairo_dock_foreach_module ((GHRFunc) _find_module_from_user_data_dir, (gpointer) cModuleDirName);
1104
 
                                if (pModule == NULL)  // du coup, dans ce cas-la, on ne charge pas des plug-ins non utilises par l'utilisateur.
1105
 
                                {
1106
 
                                        cd_warning ("couldn't find the module owning '%s', this file will be ignored.");
1107
 
                                        continue;
1108
 
                                }
1109
 
                                cConfFileName = g_strdup (pModule->pVisitCard->cConfFileName);
1110
 
                                cNewConfFilePath = g_strdup_printf ("%s/%s/%s", cNewPlugInsDir, cModuleDirName, cConfFileName);
1111
 
                        }
1112
 
                        cConfFilePath = g_strdup_printf ("%s/%s", cUserDataDirPath, cConfFileName);  // chemin du .conf dans le theme courant.
1113
 
                        
1114
 
                        // on fusionne les 2 .conf.
1115
 
                        if (! g_file_test (cConfFilePath, G_FILE_TEST_EXISTS))
1116
 
                        {
1117
 
                                cd_debug ("    no conf file %s, we will take the theme's one", cConfFilePath);
1118
 
                                g_string_printf (sCommand, "cp \"%s\" \"%s\"", cNewConfFilePath, cConfFilePath);
1119
 
                                r = system (sCommand->str);
1120
 
                        }
1121
 
                        else
1122
 
                        {
1123
 
                                cairo_dock_replace_keys_by_identifier (cConfFilePath, cNewConfFilePath, '+');
1124
 
                        }
1125
 
                        g_free (cNewConfFilePath);
1126
 
                        g_free (cConfFilePath);
1127
 
                        g_free (cUserDataDirPath);
1128
 
                        g_free (cConfFileName);
1129
 
                }
1130
 
                while (1);
1131
 
                g_dir_close (dir);
1132
 
                g_free (cNewPlugInsDir);
1133
 
        }
1134
 
        
1135
 
        // precaution probablement inutile.
1136
 
        g_string_printf (sCommand, "chmod -R 777 \"%s\"", g_cCurrentThemePath);
1137
 
        r = system (sCommand->str);
1138
 
        
1139
 
        g_string_free (sCommand, TRUE);
1140
 
        return TRUE;
1141
 
}
1142
 
 
1143
 
 
1144
 
static void _import_theme (gpointer *pSharedMemory)
1145
 
{
1146
 
        pSharedMemory[5] = GINT_TO_POINTER (cairo_dock_import_theme (pSharedMemory[0], GPOINTER_TO_INT (pSharedMemory[1]), GPOINTER_TO_INT (pSharedMemory[2])));
1147
 
}
1148
 
static gboolean _finish_import (gpointer *pSharedMemory)
1149
 
{
1150
 
        if (! pSharedMemory[5])
1151
 
                cd_warning ("Couldn't import the theme %s.", pSharedMemory[0]);
1152
 
        
1153
 
        GFunc pCallback = pSharedMemory[3];
1154
 
        pCallback (pSharedMemory[5], pSharedMemory[4]);
1155
 
        return FALSE;
1156
 
}
1157
 
static void _discard_import (gpointer *pSharedMemory)
1158
 
{
1159
 
        g_free (pSharedMemory[0]);
1160
 
        g_free (pSharedMemory);
1161
 
}
1162
 
CairoDockTask *cairo_dock_import_theme_async (const gchar *cThemeName, gboolean bLoadBehavior, gboolean bLoadLaunchers, GFunc pCallback, gpointer data)
1163
 
{
1164
 
        gpointer *pSharedMemory = g_new0 (gpointer, 6);
1165
 
        pSharedMemory[0] = g_strdup (cThemeName);
1166
 
        pSharedMemory[1] = GINT_TO_POINTER (bLoadBehavior);
1167
 
        pSharedMemory[2] = GINT_TO_POINTER (bLoadLaunchers);
1168
 
        pSharedMemory[3] = pCallback;
1169
 
        pSharedMemory[4] = data;
1170
 
        CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _import_theme, (CairoDockUpdateSyncFunc) _finish_import, (GFreeFunc) _discard_import, pSharedMemory);
1171
 
        cairo_dock_launch_task (pTask);
1172
 
        return pTask;
1173
 
}
1174
 
 
1175
 
 
1176
 
void cairo_dock_load_current_theme (void)
1177
 
{
1178
 
        cd_message ("%s ()", __func__);
1179
 
 
1180
 
        //\___________________ On libere toute la memoire allouee pour les docks (stoppe aussi tous les timeout).
1181
 
        cairo_dock_free_all_docks ();
1182
 
 
1183
 
        //\___________________ On cree le dock principal.
1184
 
        g_pMainDock = cairo_dock_create_new_dock (CAIRO_DOCK_MAIN_DOCK_NAME, NULL);  // on ne lui assigne pas de vues, puisque la vue par defaut des docks principaux sera definie plus tard.
1185
 
 
1186
 
        //\___________________ On lit son fichier de conf et on charge tout.
1187
 
        cairo_dock_read_conf_file (g_cConfFile, g_pMainDock);  // chargera des valeurs par defaut si le fichier de conf fourni est incorrect.
1188
 
}
1189
 
 
1190
 
 
1191
 
 
1192
 
static gchar *cairo_dock_build_temporary_themes_conf_file (void)
1193
 
{
1194
 
        //\___________________ On cree un fichier de conf temporaire.
1195
 
        const gchar *cTmpDir = g_get_tmp_dir ();
1196
 
        gchar *cTmpConfFile = g_strdup_printf ("%s/cairo-dock-init.XXXXXX", cTmpDir);
1197
 
        int fds = mkstemp (cTmpConfFile);
1198
 
        if (fds == -1)
1199
 
        {
1200
 
                cd_warning ("can't create a temporary file in %s", cTmpDir);
1201
 
                g_free (cTmpConfFile);
1202
 
                return NULL;
1203
 
        }
1204
 
        
1205
 
        //\___________________ On copie le fichier de conf par defaut dedans.
1206
 
        gchar *cCommand = g_strdup_printf ("cp \"%s\" \"%s\"", CAIRO_DOCK_SHARE_DATA_DIR"/"CAIRO_DOCK_THEME_CONF_FILE, cTmpConfFile);
1207
 
        int r = system (cCommand);
1208
 
        g_free (cCommand);
1209
 
 
1210
 
        close(fds);
1211
 
        return cTmpConfFile;
1212
 
}
1213
 
 
1214
 
static void _load_theme (gboolean bSuccess, gpointer data)
1215
 
{
1216
 
        if (s_pThemeManager == NULL)  // si l'utilisateur a ferme la fenetre entre-temps, on considere qu'il a abandonne.
1217
 
                return ;
1218
 
        if (bSuccess)
1219
 
        {
1220
 
                cairo_dock_load_current_theme ();
1221
 
                
1222
 
                cairo_dock_set_status_message (s_pThemeManager, "");
1223
 
                cairo_dock_reload_generic_gui (s_pThemeManager);
1224
 
        }
1225
 
        else
1226
 
                cairo_dock_set_status_message (s_pThemeManager, _("Couldn't import the theme."));
1227
 
}
1228
 
 
1229
 
static gboolean on_theme_apply (gchar *cInitConfFile)
1230
 
{
1231
 
        cd_debug ("%s (%s)", __func__, cInitConfFile);
1232
 
        GError *erreur = NULL;
1233
 
        int r;  // resultat de system().
1234
 
        
1235
 
        //\___________________ On recupere les donnees de l'IHM apres modification par l'utilisateur.
1236
 
        GKeyFile* pKeyFile = cairo_dock_open_key_file (cInitConfFile);
1237
 
        g_return_val_if_fail (pKeyFile != NULL, FALSE);
1238
 
        
1239
 
        //\___________________ On sauvegarde le theme actuel.
1240
 
        GString *sCommand = g_string_new ("");
1241
 
        gchar *cNewThemeName = g_key_file_get_string (pKeyFile, "Save", "theme name", &erreur);
1242
 
        if (erreur != NULL)
1243
 
        {
1244
 
                cd_warning (erreur->message);
1245
 
                g_error_free (erreur);
1246
 
                erreur = NULL;
1247
 
        }
1248
 
        if (cNewThemeName != NULL && *cNewThemeName == '\0')
1249
 
        {
1250
 
                g_free (cNewThemeName);
1251
 
                cNewThemeName = NULL;
1252
 
        }
1253
 
        cd_message ("cNewThemeName : %s", cNewThemeName);
1254
 
 
1255
 
        if (cNewThemeName != NULL)
1256
 
        {
1257
 
                cairo_dock_extract_theme_type_from_name (cNewThemeName);
1258
 
                
1259
 
                gboolean bSaveBehavior = g_key_file_get_boolean (pKeyFile, "Save", "save current behaviour", NULL);
1260
 
                gboolean bSaveLaunchers = g_key_file_get_boolean (pKeyFile, "Save", "save current launchers", NULL);
1261
 
                
1262
 
                gboolean bThemeSaved = cairo_dock_export_current_theme (cNewThemeName, bSaveBehavior, bSaveLaunchers);
1263
 
                
1264
 
                if (g_key_file_get_boolean (pKeyFile, "Save", "package", NULL))
1265
 
                {
1266
 
                        bThemeSaved |= cairo_dock_package_current_theme (cNewThemeName);
1267
 
                }
1268
 
                
1269
 
                if (bThemeSaved)
1270
 
                {
1271
 
                        g_key_file_set_string (pKeyFile, "Save", "theme name", "");
1272
 
                        cairo_dock_write_keys_to_file (pKeyFile, cInitConfFile);
1273
 
                }
1274
 
                cairo_dock_set_status_message (s_pThemeManager, bThemeSaved ? _("The theme has been saved") :  _("The theme couldn't be saved"));
1275
 
                
1276
 
                g_free (cNewThemeName);
1277
 
                g_key_file_free (pKeyFile);
1278
 
                return FALSE;
1279
 
        }
1280
 
        
1281
 
        //\___________________ On efface les themes selectionnes.
1282
 
        gsize length = 0;
1283
 
        gchar ** cThemesList = g_key_file_get_string_list (pKeyFile, "Delete", "deleted themes", &length, &erreur);
1284
 
        if (erreur != NULL)
1285
 
        {
1286
 
                cd_warning (erreur->message);
1287
 
                g_error_free (erreur);
1288
 
                erreur = NULL;
1289
 
        }
1290
 
        else if (cThemesList != NULL && cThemesList[0] != NULL && *cThemesList[0] != '\0')
1291
 
        {
1292
 
                gboolean bThemeDeleted = cairo_dock_delete_themes (cThemesList);
1293
 
                
1294
 
                if (bThemeDeleted)
1295
 
                {
1296
 
                        g_key_file_set_string (pKeyFile, "Delete", "deleted themes", "");
1297
 
                        cairo_dock_write_keys_to_file (pKeyFile, cInitConfFile);
1298
 
                }
1299
 
                if (cThemesList[1] == NULL)
1300
 
                        cairo_dock_set_status_message (s_pThemeManager, bThemeDeleted ? _("The theme has been deleted") :  _("The theme couldn't be deleted"));
1301
 
                else
1302
 
                        cairo_dock_set_status_message (s_pThemeManager, bThemeDeleted ? _("The themes have been deleted") :  _("The themes couldn't be deleted"));
1303
 
                
1304
 
                g_strfreev (cThemesList);
1305
 
                g_key_file_free (pKeyFile);
1306
 
                return FALSE;
1307
 
        }
1308
 
        
1309
 
        //\___________________ On charge le theme selectionne.
1310
 
        cNewThemeName = g_key_file_get_string (pKeyFile, "Themes", "chosen theme", &erreur);
1311
 
        if (erreur != NULL)
1312
 
        {
1313
 
                cd_warning (erreur->message);
1314
 
                g_error_free (erreur);
1315
 
                erreur = NULL;
1316
 
        }
1317
 
        if (cNewThemeName != NULL && *cNewThemeName == '\0')
1318
 
        {
1319
 
                g_free (cNewThemeName);
1320
 
                cNewThemeName = NULL;
1321
 
        }
1322
 
        
1323
 
        if (cNewThemeName == NULL)
1324
 
        {
1325
 
                cNewThemeName = g_key_file_get_string (pKeyFile, "Themes", "package", &erreur);
1326
 
                if (erreur != NULL)
1327
 
                {
1328
 
                        cd_warning (erreur->message);
1329
 
                        g_error_free (erreur);
1330
 
                        erreur = NULL;
1331
 
                }
1332
 
                if (cNewThemeName != NULL && *cNewThemeName == '\0')
1333
 
                {
1334
 
                        g_free (cNewThemeName);
1335
 
                        cNewThemeName = NULL;
1336
 
                }
1337
 
        }
1338
 
        
1339
 
        //\___________________ On charge le nouveau theme choisi.
1340
 
        if (cNewThemeName != NULL)
1341
 
        {
1342
 
                gboolean bLoadBehavior = g_key_file_get_boolean (pKeyFile, "Themes", "use theme behaviour", NULL);
1343
 
                gboolean bLoadLaunchers = g_key_file_get_boolean (pKeyFile, "Themes", "use theme launchers", NULL);
1344
 
                
1345
 
                if (s_pImportTask != NULL)
1346
 
                        cairo_dock_discard_task (s_pImportTask);
1347
 
                
1348
 
                cairo_dock_set_status_message_printf (s_pThemeManager, _("Importing theme %s ..."), cNewThemeName);
1349
 
                s_pImportTask = cairo_dock_import_theme_async (cNewThemeName, bLoadBehavior, bLoadLaunchers, (GFunc)_load_theme, NULL);
1350
 
                g_free (cNewThemeName);
1351
 
                return TRUE;  // ne recharge pas la fenetre, on le fera nous-memes apres l'import.
1352
 
        }
1353
 
        
1354
 
        return TRUE;
1355
 
}
1356
 
 
1357
 
void cairo_dock_manage_themes (void)
1358
 
{
1359
 
        if (s_pThemeManager != NULL)
1360
 
        {
1361
 
                gtk_window_present (GTK_WINDOW (s_pThemeManager));
1362
 
                return ;
1363
 
        }
1364
 
        
1365
 
        gchar *cInitConfFile = cairo_dock_build_temporary_themes_conf_file ();  // sera supprime a la destruction de la fenetre.
1366
 
        
1367
 
        //\___________________ On laisse l'utilisateur l'editer.
1368
 
        const gchar *cPresentedGroup = (cairo_dock_theme_need_save () ? "Save" : NULL);
1369
 
        const gchar *cTitle = _("Manage Themes");
1370
 
        
1371
 
        cairo_dock_build_generic_gui (cInitConfFile,
1372
 
                NULL, cTitle,
1373
 
                CAIRO_DOCK_THEME_PANEL_WIDTH, CAIRO_DOCK_THEME_PANEL_HEIGHT,
1374
 
                (CairoDockApplyConfigFunc) on_theme_apply,
1375
 
                cInitConfFile,
1376
 
                (GFreeFunc) on_theme_destroy,
1377
 
                &s_pThemeManager);
1378
 
}