1 /*
2 * externdiff.h - Plugin to geany light IDE to work with vc
3 *
4 * Copyright 2008 Yura Siamashka <yurand2@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 #include <string.h>
22 #include <geanyplugin.h>
23 #include "geanyvc.h"
24
25 #ifdef G_OS_WIN32
26 #include <shlobj.h>
27 #endif
28
29
30 enum
31 {
32 EXTERNAL_DIFF_MELD,
33 EXTERNAL_DIFF_KOMPARE,
34 EXTERNAL_DIFF_KDIFF3,
35 EXTERNAL_DIFF_DIFFUSE,
36 EXTERNAL_DIFF_TKDIFF,
37 EXTERNAL_DIFF_WINMERGE,
38 EXTERNAL_DIFF_COUNT
39 };
40
41
42 static const gchar *viewers[EXTERNAL_DIFF_COUNT] = { "Meld/meld", "kompare", "kdiff3", "diffuse", "tkdiff", "WinMerge/WinMergeU" };
43
44 static gchar *extern_diff_viewer = NULL;
45
external_diff_viewer_init(void)46 void external_diff_viewer_init(void)
47 {
48 gint i;
49
50 for (i = 0; i < EXTERNAL_DIFF_COUNT; i++)
51 {
52 gchar *filename = g_path_get_basename(viewers[i]);
53 gchar *path = g_find_program_in_path(filename);
54 g_free(filename);
55 if (path)
56 {
57 extern_diff_viewer = path;
58 return;
59 }
60 }
61 #ifdef G_OS_WIN32
62 TCHAR szPathProgramFiles[MAX_PATH];
63 TCHAR szPathProgramFiles86[MAX_PATH];
64 SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, 0, szPathProgramFiles);
65 SHGetFolderPath(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, szPathProgramFiles86);
66
67 for (i = 0; i < EXTERNAL_DIFF_COUNT; i++)
68 {
69 gchar *filename = g_build_filename(szPathProgramFiles, viewers[i], NULL);
70 gchar *path = g_find_program_in_path(filename);
71 g_free(filename);
72 if (path)
73 {
74 extern_diff_viewer = path;
75 return;
76 }
77 }
78 for (i = 0; i < EXTERNAL_DIFF_COUNT; i++)
79 {
80 gchar *filename = g_build_filename(szPathProgramFiles86, viewers[i], NULL);
81 gchar *path = g_find_program_in_path(filename);
82 g_free(filename);
83 if (path)
84 {
85 extern_diff_viewer = path;
86 return;
87 }
88 }
89 #endif
90 }
91
external_diff_viewer_deinit(void)92 void external_diff_viewer_deinit(void)
93 {
94 if (extern_diff_viewer)
95 {
96 g_free(extern_diff_viewer);
97 extern_diff_viewer = NULL;
98 }
99 }
100
101 const gchar *
get_external_diff_viewer(void)102 get_external_diff_viewer(void)
103 {
104 if (extern_diff_viewer)
105 return extern_diff_viewer;
106 return NULL;
107 }
108
109
110 void
vc_external_diff(const gchar * src,const gchar * dest)111 vc_external_diff(const gchar * src, const gchar * dest)
112 {
113 gchar *argv[4] = { NULL, NULL, NULL, NULL };
114 const gchar *diff = get_external_diff_viewer();
115 if (!diff)
116 return;
117
118 argv[0] = (gchar *) diff;
119 argv[1] = (gchar *) src;
120 argv[2] = (gchar *) dest;
121
122 g_spawn_sync(NULL, argv, NULL,
123 G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL |
124 G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, NULL, NULL, NULL, NULL);
125 }
126