2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
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.
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/>.
22
#define __USE_XOPEN_EXTENDED
27
#include <glib/gstdio.h>
28
#include <glib/gi18n.h>
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"
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"
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;
59
extern CairoDock *g_pMainDock;
61
static GtkWidget *s_pThemeManager = NULL;
62
static CairoDockTask *s_pImportTask = NULL;
64
void cairo_dock_free_theme (CairoDockTheme *pTheme)
68
g_free (pTheme->cThemePath);
69
g_free (pTheme->cAuthor);
70
g_free (pTheme->cDisplayedName);
75
gchar *cairo_dock_uncompress_file (const gchar *cArchivePath, const gchar *cExtractTo, const gchar *cRealArchiveName)
77
//\_______________ on cree le repertoire d'extraction.
78
if (!g_file_test (cExtractTo, G_FILE_TEST_EXISTS))
80
if (g_mkdir (cExtractTo, 7*8*8+7*8+5) != 0)
82
cd_warning ("couldn't create directory %s", cExtractTo);
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, '/');
93
cLocalFileName = g_strdup (str+1);
95
cLocalFileName = g_strdup (cRealArchiveName);
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);
105
gchar *cResultPath = g_strdup_printf ("%s/%s", cExtractTo, cLocalFileName);
106
g_free (cLocalFileName);
108
//\_______________ on efface un dossier identique prealable.
109
if (g_file_test (cResultPath, G_FILE_TEST_EXISTS))
111
gchar *cCommand = g_strdup_printf ("rm -rf \"%s\"", cResultPath);
112
int r = system (cCommand);
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);
122
cd_warning ("an error occured while executing '%s'", cCommand);
123
g_free (cResultPath);
130
gchar *cairo_dock_download_file (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, const gchar *cExtractTo, GError **erreur)
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);
138
g_set_error (erreur, 1, 1, "couldn't create temporary file '%s'", cTmpFilePath);
139
g_free (cTmpFilePath);
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,
148
mySystem.iConnectionTimeout, mySystem.iConnectiontMaxTime, mySystem.iConnectiontNbRetries);
149
cd_debug ("download with '%s'", cCommand);
150
int r = system (cCommand);
153
cd_warning ("an error occured while executing '%s'", cCommand);
154
g_remove (cTmpFilePath);
155
g_free (cTmpFilePath);
159
//\_______________ On teste que le fichier est non vide.
160
gboolean bOk = (cTmpFilePath != NULL);
164
stat (cTmpFilePath, &buf);
165
bOk = (buf.st_size > 0);
169
g_set_error (erreur, 1, 1, "couldn't get distant file %s", cDistantFileName);
170
g_remove (cTmpFilePath);
171
g_free (cTmpFilePath);
177
//\_______________ On l'extrait si c'est une archive.
178
if (cTmpFilePath != NULL && cExtractTo != NULL)
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;
190
static void _dl_file (gpointer *pSharedMemory)
192
GError *erreur = NULL;
193
pSharedMemory[6] = cairo_dock_download_file (pSharedMemory[0], pSharedMemory[1], pSharedMemory[2], pSharedMemory[3], &erreur);
196
cd_warning (erreur->message);
197
g_error_free (erreur);
200
static gboolean _finish_dl (gpointer *pSharedMemory)
202
if (pSharedMemory[6] == NULL)
203
cd_warning ("couldn't get distant file %s", pSharedMemory[2]);
205
GFunc pCallback = pSharedMemory[4];
206
pCallback (pSharedMemory[6], pSharedMemory[5]);
209
static void _discard_dl (gpointer *pSharedMemory)
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);
218
CairoDockTask *cairo_dock_download_file_async (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, const gchar *cExtractTo, GFunc pCallback, gpointer data)
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);
232
gchar *cairo_dock_get_distant_file_content (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, GError **erreur)
234
GError *tmp_erreur = NULL;
235
gchar *cTmpFilePath = cairo_dock_download_file (cServerAdress, cDistantFilePath, cDistantFileName, NULL, &tmp_erreur);
236
if (tmp_erreur != NULL)
238
g_propagate_error (erreur, tmp_erreur);
242
gchar *cContent = NULL;
244
g_file_get_contents (cTmpFilePath, &cContent, &length, &tmp_erreur);
245
if (tmp_erreur != NULL)
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);
250
else if (cContent == NULL)
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);
256
g_remove (cTmpFilePath);
257
g_free (cTmpFilePath);
262
static void _dl_file_readme (gpointer *pSharedMemory)
264
GError *erreur = NULL;
265
pSharedMemory[5] = cairo_dock_get_distant_file_content (pSharedMemory[0], pSharedMemory[1], pSharedMemory[2], &erreur);
268
cd_warning (erreur->message);
269
g_error_free (erreur);
272
static gboolean _finish_dl_readme (gpointer *pSharedMemory)
274
if (pSharedMemory[5] == NULL)
275
cd_warning ("couldn't get distant file %s", pSharedMemory[2]);
277
GFunc pCallback = pSharedMemory[3];
278
pCallback (pSharedMemory[5], pSharedMemory[4]);
281
static void _discard_dl_readme (gpointer *pSharedMemory)
283
g_free (pSharedMemory[0]);
284
g_free (pSharedMemory[1]);
285
g_free (pSharedMemory[2]);
286
g_free (pSharedMemory[5]);
287
g_free (pSharedMemory);
289
CairoDockTask *cairo_dock_get_distant_file_content_async (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, GFunc pCallback, gpointer data)
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);
304
static inline int _get_theme_rating (const gchar *cThemesDir, const gchar *cThemeName)
306
gchar *cRatingFile = g_strdup_printf ("%s/.rating/%s", cThemesDir, cThemeName);
309
gchar *cContent = NULL;
310
g_file_get_contents (cRatingFile,
316
iRating = atoi (cContent);
319
g_free (cRatingFile);
322
GHashTable *cairo_dock_list_local_themes (const gchar *cThemesDir, GHashTable *hProvidedTable, gboolean bUpdateThemeValidity, GError **erreur)
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)
329
g_propagate_error (erreur, tmp_erreur);
330
return hProvidedTable;
333
GHashTable *pThemeTable = (hProvidedTable != NULL ? hProvidedTable : g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cairo_dock_free_theme));
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);
340
CairoDockTheme *pTheme;
341
const gchar *cThemeName;
342
while ((cThemeName = g_dir_read_name (dir)) != NULL)
344
// on ecarte les fichiers caches.
345
if (*cThemeName == '.')
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))
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.
368
static inline int _convert_date (int iDate)
372
m = (iDate - y*10000) / 100;
374
return (d + m*30 + y*365);
376
static void _cairo_dock_parse_theme_list (GKeyFile *pKeyFile, const gchar *cServerAdress, const gchar *cDirectory, GHashTable *pThemeTable)
379
time_t epoch = (time_t) time (NULL);
380
struct tm currentTime;
381
localtime_r (&epoch, ¤tTime);
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;
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.
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;
399
for (i = 0; i < length; i ++)
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);
406
// creation < 30j && pas sur le disque -> new
407
// sinon last modif < 30j && last use < last modif -> updated
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.
414
// on regarde de quand date cette version locale.
415
gchar *cVersionFile = g_strdup_printf ("%s/last-modif", pSameTheme->cThemePath);
417
gchar *cContent = NULL;
418
g_file_get_contents (cVersionFile,
422
if (cContent == NULL) // le theme n'a pas encore de fichier de date
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".
428
iLocalDate = day + (month - 1) * 1e2 + year * 1e4;
430
iLocalDate = day + 12 * 1e2 + (year - 1) * 1e4;
431
cDate = g_strdup_printf ("%d", iLocalDate);
432
g_file_set_contents (cVersionFile,
439
iLocalDate = atoi (cContent);
442
if (iLocalDate < iLastModifDate) // la copie locale est plus ancienne.
444
iType = CAIRO_DOCK_UPDATED_THEME;
446
else // c'est deja la derniere version disponible, on en reste la.
448
g_free (cVersionFile);
450
pSameTheme->iSobriety = iSobriety; // par contre on en profite pour renseigner la sobriete.
453
g_free (cVersionFile);
456
g_free (pTheme->cThemePath);
457
g_free (pTheme->cAuthor);
458
g_free (pTheme->cDisplayedName);
460
else // theme encore jamais telecharge.
462
last_modif = _convert_date (iLastModifDate);
463
creation_date = _convert_date (iCreationDate);
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;
470
iType = CAIRO_DOCK_DISTANT_THEME;
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.
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')
483
g_free (pTheme->cAuthor);
484
pTheme->cAuthor = NULL;
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);
491
g_free (pGroupList); // les noms des themes sont desormais dans la hash-table.
493
GHashTable *cairo_dock_list_net_themes (const gchar *cServerAdress, const gchar *cDirectory, const gchar *cListFileName, GHashTable *hProvidedTable, GError **erreur)
495
g_return_val_if_fail (cServerAdress != NULL && *cServerAdress != '\0', hProvidedTable);
496
cd_message ("listing net themes on %s/%s ...", cServerAdress, cDirectory);
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)
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;
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.
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);
514
return hProvidedTable;
517
// petit bonus : on a la derniere version du dock sur la 1ere ligne.
518
if (cContent[4] != '\n')
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))))
528
g_print ("A new version is available !\n>>>\n%d.%d.%d\n<<<\n", iMajorVersion, iMinorVersion, iMicroVersion);
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,
540
if (tmp_erreur != NULL)
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;
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));
551
_cairo_dock_parse_theme_list (pKeyFile, cServerAdress, cDirectory, pThemeTable);
553
g_key_file_free (pKeyFile);
558
GHashTable *cairo_dock_list_themes (const gchar *cShareThemesDir, const gchar *cUserThemesDir, const gchar *cDistantThemesDir)
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);
564
//\______________ On recupere les themes pre-installes.
565
if (cShareThemesDir != NULL)
566
pThemeTable = cairo_dock_list_local_themes (cShareThemesDir, pThemeTable, cDistantThemesDir != NULL, &erreur);
569
cd_warning ("while loading pre-installed themes in '%s' : %s", cShareThemesDir, erreur->message);
570
g_error_free (erreur);
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);
579
cd_warning ("while loading user themes in '%s' : %s", cShareThemesDir, erreur->message);
580
g_error_free (erreur);
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);
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);
597
static void _list_themes (gpointer *pSharedMemory)
599
pSharedMemory[5] = cairo_dock_list_themes (pSharedMemory[0], pSharedMemory[1], pSharedMemory[2]);
601
static gboolean _finish_list_themes (gpointer *pSharedMemory)
603
if (pSharedMemory[5] == NULL)
604
cd_warning ("couldn't get distant themes in '%s'", pSharedMemory[2]);
606
GFunc pCallback = pSharedMemory[3];
607
pCallback (pSharedMemory[5], pSharedMemory[4]);
611
static void _discard_list_themes (gpointer *pSharedMemory)
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);
619
CairoDockTask *cairo_dock_list_themes_async (const gchar *cShareThemesDir, const gchar *cUserThemesDir, const gchar *cDistantThemesDir, GFunc pCallback, gpointer data)
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);
632
gchar *cairo_dock_get_theme_path (const gchar *cThemeName, const gchar *cShareThemesDir, const gchar *cUserThemesDir, const gchar *cDistantThemesDir, CairoDockThemeType iGivenType)
634
cd_message ("%s (%s, %s, %s)", __func__, cShareThemesDir, cUserThemesDir, cDistantThemesDir);
635
if (cThemeName == NULL || *cThemeName == '\0')
637
CairoDockThemeType iType = cairo_dock_extract_theme_type_from_name (cThemeName);
638
if (iType == CAIRO_DOCK_ANY_THEME)
640
gchar *cThemePath = NULL;
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)
645
cThemePath = g_strdup_printf ("%s/%s", cUserThemesDir, cThemeName);
647
if (g_file_test (cThemePath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
656
if (cShareThemesDir != NULL && /*iType != CAIRO_DOCK_DISTANT_THEME && iType != CAIRO_DOCK_NEW_THEME && */iType != CAIRO_DOCK_UPDATED_THEME)
658
cThemePath = g_strdup_printf ("%s/%s", cShareThemesDir, cThemeName);
659
if (g_file_test (cThemePath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
665
if (cDistantThemesDir != NULL)
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);
673
cd_warning ("couldn't retrieve distant theme %s : %s" , cThemeName, erreur->message);
674
g_error_free (erreur);
676
else // on se souvient de la date a laquelle on a mis a jour le theme pour la derniere fois.
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, ¤tTime);
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,
689
g_free (cVersionFile);
693
cd_debug (" ====> cThemePath : %s", cThemePath);
699
void cairo_dock_mark_theme_as_modified (gboolean bModified)
701
gchar *cModifiedFile = g_strdup_printf ("%s/%s", g_cCairoDockDataDir, CAIRO_DOCK_MODIFIED_THEME_FILE);
703
g_file_set_contents (cModifiedFile,
704
(bModified ? "1" : "0"),
708
g_free (cModifiedFile);
711
gboolean cairo_dock_theme_need_save (void)
713
gchar *cModifiedFile = g_strdup_printf ("%s/%s", g_cCairoDockDataDir, CAIRO_DOCK_MODIFIED_THEME_FILE);
715
gchar *cContent = NULL;
716
g_file_get_contents (cModifiedFile,
720
g_free (cModifiedFile);
723
bNeedSave = (*cContent == '1');
732
static void on_theme_destroy (gchar *cInitConfFile)
735
g_remove (cInitConfFile);
736
g_free (cInitConfFile);
737
s_pThemeManager = NULL;
740
CairoDockThemeType cairo_dock_extract_theme_type_from_name (const gchar *cThemeName)
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] == ']')
748
gchar *str = strrchr (cThemeName, '[');
749
if (str != NULL && g_ascii_isdigit (*(str+1)))
751
iType = atoi (str+1);
758
gboolean cairo_dock_export_current_theme (const gchar *cNewThemeName, gboolean bSaveBehavior, gboolean bSaveLaunchers)
760
g_return_val_if_fail (cNewThemeName != NULL, FALSE);
762
cairo_dock_extract_theme_type_from_name (cNewThemeName);
764
cd_message ("on sauvegarde dans %s", cNewThemeName);
765
GString *sCommand = g_string_new ("");
766
gboolean bThemeSaved = FALSE;
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.
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);
775
if (answer == GTK_RESPONSE_YES)
777
//\___________________ On traite le fichier de conf.
778
gchar *cNewConfFilePath = g_strdup_printf ("%s/%s", cNewThemePath, CAIRO_DOCK_CONF_FILE);
781
g_string_printf (sCommand, "/bin/cp \"%s\" \"%s\"", g_cConfFile, cNewConfFilePath);
782
cd_message ("%s", sCommand->str);
783
r = system (sCommand->str);
787
cairo_dock_replace_keys_by_identifier (cNewConfFilePath, g_cConfFile, '+');
789
g_free (cNewConfFilePath);
791
//\___________________ On traite les lanceurs.
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);
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);
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);
812
else // sinon on sauvegarde le repertoire courant tout simplement.
814
cd_debug (" creation du nouveau theme (%s)", cNewThemePath);
816
if (g_mkdir (cNewThemePath, 7*8*8+7*8+5) == 0)
818
g_string_printf (sCommand, "cp -r \"%s\"/* \"%s\"", g_cCurrentThemePath, cNewThemePath);
819
cd_message ("%s", sCommand->str);
820
r = system (sCommand->str);
825
cd_warning ("couldn't create %s", cNewThemePath);
828
g_free (cNewThemePath);
831
cairo_dock_mark_theme_as_modified (FALSE);
834
g_string_free (sCommand, TRUE);
839
gboolean cairo_dock_package_current_theme (const gchar *cThemeName)
841
g_return_val_if_fail (cThemeName != NULL, FALSE);
843
cairo_dock_extract_theme_type_from_name (cThemeName);
845
cd_message ("building theme package ...");
847
if (g_file_test (CAIRO_DOCK_SHARE_DATA_DIR"/../../bin/cairo-dock-package-theme", G_FILE_TEST_EXISTS))
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);
854
cCommand = g_strdup_printf ("$TERM -e '%s \"%s\"'", "cairo-dock-package-theme", cThemeName);
855
r = system (cCommand);
861
cd_warning ("the package builder script was not found !");
865
gchar *cairo_dock_depackage_theme (const gchar *cPackagePath)
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.
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);
876
else // paquet distant.
878
g_print (" paquet distant\n");
879
gchar *str = strrchr (cPackagePath, '/');
883
cNewThemePath = cairo_dock_download_file (cPackagePath, "", str+1, cUserThemesDir, NULL);
884
if (cNewThemePath == NULL)
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);
890
g_free (cUserThemesDir);
891
return cNewThemePath;
894
gboolean cairo_dock_delete_themes (gchar **cThemesList)
896
g_return_val_if_fail (cThemesList != NULL && cThemesList[0] != NULL, FALSE);
898
GString *sCommand = g_string_new ("");
899
gboolean bThemeDeleted = FALSE;
901
if (cThemesList[1] == NULL)
902
g_string_printf (sCommand, _("Are you sure you want to delete theme %s ?"), cThemesList[0]);
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)
910
for (i = 0; cThemesList[i] != NULL; i ++)
912
cThemeName = cThemesList[i];
913
if (*cThemeName == '\0')
915
cairo_dock_extract_theme_type_from_name (cThemeName);
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.
923
g_string_free (sCommand, TRUE);
924
return bThemeDeleted;
927
static gboolean _find_module_from_user_data_dir (gchar *cModuleName, CairoDockModule *pModule, const gchar *cUserDataDirName)
929
if (pModule->pVisitCard->cUserDataDir && strcmp (cUserDataDirName, pModule->pVisitCard->cUserDataDir) == 0)
933
gboolean cairo_dock_import_theme (const gchar *cThemeName, gboolean bLoadBehavior, gboolean bLoadLaunchers)
935
//\___________________ On regarde si le theme courant est modifie.
936
/*gboolean bNeedSave = cairo_dock_theme_need_save ();
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)
944
cairo_dock_mark_theme_as_modified (FALSE);
945
}*/ // pas dans un thread.
947
//\___________________ On obtient le chemin du nouveau theme (telecharge ou decompresse si necessaire).
948
gchar *cNewThemeName = g_strdup (cThemeName);
949
gchar *cNewThemePath = NULL;
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);
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.
960
cd_debug ("c'est un paquet");
961
cNewThemePath = cairo_dock_depackage_theme (cNewThemeName);
963
g_return_val_if_fail (cNewThemePath != NULL, FALSE);
964
gchar *tmp = cNewThemeName;
965
cNewThemeName = g_path_get_basename (cNewThemePath);
968
else // c'est un theme officiel.
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);
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);
978
//\___________________ On charge les parametres de comportement.
979
GString *sCommand = g_string_new ("");
981
cd_message ("Applying changes ...");
982
if (g_pMainDock == NULL || bLoadBehavior)
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);
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);
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);
1000
//\___________________ On charge les lanceurs.
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);
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'.
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);
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);
1023
g_string_printf (sCommand, "cp \"%s\"/* \"%s/%s\"", cNewLocalIconsPath, g_cCurrentThemePath, CAIRO_DOCK_LOCAL_ICONS_DIR);
1025
cd_debug ("%s", sCommand->str);
1026
r = system (sCommand->str);
1027
g_free (cNewLocalIconsPath);
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))
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);
1038
//\___________________ On charge les lanceurs si necessaire, en effacant ceux existants.
1039
if (! g_file_test (g_cCurrentLaunchersPath, G_FILE_TEST_EXISTS))
1041
gchar *command = g_strdup_printf ("mkdir -p \"%s\"", g_cCurrentLaunchersPath);
1042
r = system (command);
1045
if (g_pMainDock == NULL || bLoadLaunchers)
1047
g_string_printf (sCommand, "rm -f \"%s\"/*.desktop", g_cCurrentLaunchersPath);
1048
cd_debug ("%s", sCommand->str);
1049
r = system (sCommand->str);
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);
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);
1061
if (g_pMainDock == NULL || bLoadBehavior)
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);
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);
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;
1081
cModuleDirName = g_dir_read_name (dir); // nom du repertoire du theme (pas forcement egal au nom du theme)
1082
if (cModuleDirName == NULL)
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))
1090
cd_debug (" directory %s doesn't exist, it will be created.", cUserDataDirPath);
1092
g_string_printf (sCommand, "mkdir -p \"%s\"", cUserDataDirPath);
1093
r = system (sCommand->str);
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))
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.
1106
cd_warning ("couldn't find the module owning '%s', this file will be ignored.");
1109
cConfFileName = g_strdup (pModule->pVisitCard->cConfFileName);
1110
cNewConfFilePath = g_strdup_printf ("%s/%s/%s", cNewPlugInsDir, cModuleDirName, cConfFileName);
1112
cConfFilePath = g_strdup_printf ("%s/%s", cUserDataDirPath, cConfFileName); // chemin du .conf dans le theme courant.
1114
// on fusionne les 2 .conf.
1115
if (! g_file_test (cConfFilePath, G_FILE_TEST_EXISTS))
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);
1123
cairo_dock_replace_keys_by_identifier (cConfFilePath, cNewConfFilePath, '+');
1125
g_free (cNewConfFilePath);
1126
g_free (cConfFilePath);
1127
g_free (cUserDataDirPath);
1128
g_free (cConfFileName);
1132
g_free (cNewPlugInsDir);
1135
// precaution probablement inutile.
1136
g_string_printf (sCommand, "chmod -R 777 \"%s\"", g_cCurrentThemePath);
1137
r = system (sCommand->str);
1139
g_string_free (sCommand, TRUE);
1144
static void _import_theme (gpointer *pSharedMemory)
1146
pSharedMemory[5] = GINT_TO_POINTER (cairo_dock_import_theme (pSharedMemory[0], GPOINTER_TO_INT (pSharedMemory[1]), GPOINTER_TO_INT (pSharedMemory[2])));
1148
static gboolean _finish_import (gpointer *pSharedMemory)
1150
if (! pSharedMemory[5])
1151
cd_warning ("Couldn't import the theme %s.", pSharedMemory[0]);
1153
GFunc pCallback = pSharedMemory[3];
1154
pCallback (pSharedMemory[5], pSharedMemory[4]);
1157
static void _discard_import (gpointer *pSharedMemory)
1159
g_free (pSharedMemory[0]);
1160
g_free (pSharedMemory);
1162
CairoDockTask *cairo_dock_import_theme_async (const gchar *cThemeName, gboolean bLoadBehavior, gboolean bLoadLaunchers, GFunc pCallback, gpointer data)
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);
1176
void cairo_dock_load_current_theme (void)
1178
cd_message ("%s ()", __func__);
1180
//\___________________ On libere toute la memoire allouee pour les docks (stoppe aussi tous les timeout).
1181
cairo_dock_free_all_docks ();
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.
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.
1192
static gchar *cairo_dock_build_temporary_themes_conf_file (void)
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);
1200
cd_warning ("can't create a temporary file in %s", cTmpDir);
1201
g_free (cTmpConfFile);
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);
1211
return cTmpConfFile;
1214
static void _load_theme (gboolean bSuccess, gpointer data)
1216
if (s_pThemeManager == NULL) // si l'utilisateur a ferme la fenetre entre-temps, on considere qu'il a abandonne.
1220
cairo_dock_load_current_theme ();
1222
cairo_dock_set_status_message (s_pThemeManager, "");
1223
cairo_dock_reload_generic_gui (s_pThemeManager);
1226
cairo_dock_set_status_message (s_pThemeManager, _("Couldn't import the theme."));
1229
static gboolean on_theme_apply (gchar *cInitConfFile)
1231
cd_debug ("%s (%s)", __func__, cInitConfFile);
1232
GError *erreur = NULL;
1233
int r; // resultat de system().
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);
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);
1244
cd_warning (erreur->message);
1245
g_error_free (erreur);
1248
if (cNewThemeName != NULL && *cNewThemeName == '\0')
1250
g_free (cNewThemeName);
1251
cNewThemeName = NULL;
1253
cd_message ("cNewThemeName : %s", cNewThemeName);
1255
if (cNewThemeName != NULL)
1257
cairo_dock_extract_theme_type_from_name (cNewThemeName);
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);
1262
gboolean bThemeSaved = cairo_dock_export_current_theme (cNewThemeName, bSaveBehavior, bSaveLaunchers);
1264
if (g_key_file_get_boolean (pKeyFile, "Save", "package", NULL))
1266
bThemeSaved |= cairo_dock_package_current_theme (cNewThemeName);
1271
g_key_file_set_string (pKeyFile, "Save", "theme name", "");
1272
cairo_dock_write_keys_to_file (pKeyFile, cInitConfFile);
1274
cairo_dock_set_status_message (s_pThemeManager, bThemeSaved ? _("The theme has been saved") : _("The theme couldn't be saved"));
1276
g_free (cNewThemeName);
1277
g_key_file_free (pKeyFile);
1281
//\___________________ On efface les themes selectionnes.
1283
gchar ** cThemesList = g_key_file_get_string_list (pKeyFile, "Delete", "deleted themes", &length, &erreur);
1286
cd_warning (erreur->message);
1287
g_error_free (erreur);
1290
else if (cThemesList != NULL && cThemesList[0] != NULL && *cThemesList[0] != '\0')
1292
gboolean bThemeDeleted = cairo_dock_delete_themes (cThemesList);
1296
g_key_file_set_string (pKeyFile, "Delete", "deleted themes", "");
1297
cairo_dock_write_keys_to_file (pKeyFile, cInitConfFile);
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"));
1302
cairo_dock_set_status_message (s_pThemeManager, bThemeDeleted ? _("The themes have been deleted") : _("The themes couldn't be deleted"));
1304
g_strfreev (cThemesList);
1305
g_key_file_free (pKeyFile);
1309
//\___________________ On charge le theme selectionne.
1310
cNewThemeName = g_key_file_get_string (pKeyFile, "Themes", "chosen theme", &erreur);
1313
cd_warning (erreur->message);
1314
g_error_free (erreur);
1317
if (cNewThemeName != NULL && *cNewThemeName == '\0')
1319
g_free (cNewThemeName);
1320
cNewThemeName = NULL;
1323
if (cNewThemeName == NULL)
1325
cNewThemeName = g_key_file_get_string (pKeyFile, "Themes", "package", &erreur);
1328
cd_warning (erreur->message);
1329
g_error_free (erreur);
1332
if (cNewThemeName != NULL && *cNewThemeName == '\0')
1334
g_free (cNewThemeName);
1335
cNewThemeName = NULL;
1339
//\___________________ On charge le nouveau theme choisi.
1340
if (cNewThemeName != NULL)
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);
1345
if (s_pImportTask != NULL)
1346
cairo_dock_discard_task (s_pImportTask);
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.
1357
void cairo_dock_manage_themes (void)
1359
if (s_pThemeManager != NULL)
1361
gtk_window_present (GTK_WINDOW (s_pThemeManager));
1365
gchar *cInitConfFile = cairo_dock_build_temporary_themes_conf_file (); // sera supprime a la destruction de la fenetre.
1367
//\___________________ On laisse l'utilisateur l'editer.
1368
const gchar *cPresentedGroup = (cairo_dock_theme_need_save () ? "Save" : NULL);
1369
const gchar *cTitle = _("Manage Themes");
1371
cairo_dock_build_generic_gui (cInitConfFile,
1373
CAIRO_DOCK_THEME_PANEL_WIDTH, CAIRO_DOCK_THEME_PANEL_HEIGHT,
1374
(CairoDockApplyConfigFunc) on_theme_apply,
1376
(GFreeFunc) on_theme_destroy,