OSDN Git Service

Merge with stable
[winmerge-jp/winmerge-jp.git] / Src / OptionsInit.cpp
1 /**
2  * @file  OptionsInit.cpp
3  *
4  * @brief Options initialisation.
5  */
6
7 #include <vector>
8 #include "OptionsDef.h"
9 #include "OptionsMgr.h"
10 #include "RegOptionsMgr.h"
11 #include "OptionsDiffOptions.h"
12 #include "OptionsDiffColors.h"
13 #include "OptionsFont.h"
14 #include "DiffWrapper.h" // CMP_CONTENT
15 #include "unicoder.h"
16 #include "SourceControl.h"
17 #include "paths.h"
18 #include "Environment.h"
19 #include "Constants.h"
20
21 // Functions to copy values set by installer from HKLM to HKCU.
22 static void CopyHKLMValues();
23 static bool OpenHKLM(HKEY *key, LPCTSTR relpath = NULL);
24 static bool OpenHKCU(HKEY *key, LPCTSTR relpath = NULL);
25 static bool IsFirstRun(HKEY key);
26 static void CopyFromLMtoCU(HKEY lmKey, HKEY cuKey, LPCTSTR valname);
27 static void ResetFirstRun(HKEY key);
28
29 namespace Options
30 {
31
32 /**
33  * @brief Initialise options and set default values.
34  *
35  * @note Remember default values are what users see first time
36  * using WinMerge and many users never change them. So pick
37  * default values carefully!
38  */
39 void Init(COptionsMgr *pOptions)
40 {
41         // Copy some values from HKLM to HKCU
42         CopyHKLMValues();
43
44         static_cast<CRegOptionsMgr *>(pOptions)->SetRegRootKey(_T("Thingamahoochie\\WinMerge\\"));
45
46         LANGID LangId = GetUserDefaultLangID();
47         if (PRIMARYLANGID(LangId) == LANG_JAPANESE)
48         {
49                 // Default language to Japanese unless installer set it otherwise
50                 pOptions->InitOption(OPT_SELECTED_LANGUAGE, 0x411);
51         }
52         else
53         {
54                 // Default language to English unless installer set it otherwise
55                 pOptions->InitOption(OPT_SELECTED_LANGUAGE, 0x409);
56         }
57
58         // Initialise options (name, default value)
59         pOptions->InitOption(OPT_SHOW_UNIQUE_LEFT, true);
60         pOptions->InitOption(OPT_SHOW_UNIQUE_RIGHT, true);
61         pOptions->InitOption(OPT_SHOW_DIFFERENT, true);
62         pOptions->InitOption(OPT_SHOW_IDENTICAL, true);
63         pOptions->InitOption(OPT_SHOW_BINARIES, true);
64         pOptions->InitOption(OPT_SHOW_SKIPPED, false);
65
66         pOptions->InitOption(OPT_SHOW_TOOLBAR, true);
67         pOptions->InitOption(OPT_SHOW_STATUSBAR, true);
68         pOptions->InitOption(OPT_SHOW_TABBAR, true);
69         pOptions->InitOption(OPT_TOOLBAR_SIZE, 0);
70         pOptions->InitOption(OPT_RESIZE_PANES, false);
71
72         pOptions->InitOption(OPT_SYNTAX_HIGHLIGHT, true);
73         pOptions->InitOption(OPT_WORDWRAP, false);
74         pOptions->InitOption(OPT_VIEW_LINENUMBERS, false);
75         pOptions->InitOption(OPT_VIEW_WHITESPACE, false);
76         pOptions->InitOption(OPT_CONNECT_MOVED_BLOCKS, 0);
77         pOptions->InitOption(OPT_SCROLL_TO_FIRST, false);
78         pOptions->InitOption(OPT_VERIFY_OPEN_PATHS, true);
79         pOptions->InitOption(OPT_AUTO_COMPLETE_SOURCE, (int)1);
80         pOptions->InitOption(OPT_VIEW_FILEMARGIN, false);
81         pOptions->InitOption(OPT_DIFF_CONTEXT, (int)-1);
82         pOptions->InitOption(OPT_SPLIT_HORIZONTALLY, false);
83
84         pOptions->InitOption(OPT_WORDDIFF_HIGHLIGHT, true);
85         pOptions->InitOption(OPT_BREAK_SEPARATORS, _T(".,:;?[](){}<>`'!\"#$%&^~\\|@+-*/"));
86
87         pOptions->InitOption(OPT_BACKUP_FOLDERCMP, false);
88         pOptions->InitOption(OPT_BACKUP_FILECMP, true);
89         pOptions->InitOption(OPT_BACKUP_LOCATION, (int)0);
90         pOptions->InitOption(OPT_BACKUP_GLOBALFOLDER, _T(""));
91         pOptions->InitOption(OPT_BACKUP_ADD_BAK, true);
92         pOptions->InitOption(OPT_BACKUP_ADD_TIME, false);
93
94         pOptions->InitOption(OPT_DIRVIEW_SORT_COLUMN, (int)-1);
95         pOptions->InitOption(OPT_DIRVIEW_SORT_COLUMN3, (int)-1);
96         pOptions->InitOption(OPT_DIRVIEW_SORT_ASCENDING, true);
97         pOptions->InitOption(OPT_SHOW_SELECT_FILES_AT_STARTUP, false);
98         pOptions->InitOption(OPT_DIRVIEW_EXPAND_SUBDIRS, false);
99
100         pOptions->InitOption(OPT_AUTOMATIC_RESCAN, false);
101         pOptions->InitOption(OPT_ALLOW_MIXED_EOL, false);
102         pOptions->InitOption(OPT_TAB_SIZE, (int)4);
103         pOptions->InitOption(OPT_TAB_TYPE, (int)0);     // 0 means tabs inserted
104
105         pOptions->InitOption(OPT_EXT_EDITOR_CMD, paths_ConcatPath(env_GetWindowsDirectory(), _T("NOTEPAD.EXE")));
106         pOptions->InitOption(OPT_USE_RECYCLE_BIN, true);
107         pOptions->InitOption(OPT_SINGLE_INSTANCE, false);
108         pOptions->InitOption(OPT_MERGE_MODE, false);
109         // OPT_WORDDIFF_HIGHLIGHT is initialized above
110         pOptions->InitOption(OPT_BREAK_ON_WORDS, false);
111         pOptions->InitOption(OPT_BREAK_TYPE, 1);
112
113         pOptions->InitOption(OPT_CLOSE_WITH_ESC, true);
114         pOptions->InitOption(OPT_CLOSE_WITH_OK, false);
115         pOptions->InitOption(OPT_IGNORE_SMALL_FILETIME, false);
116         pOptions->InitOption(OPT_ASK_MULTIWINDOW_CLOSE, false);
117         pOptions->InitOption(OPT_PRESERVE_FILETIMES, false);
118         pOptions->InitOption(OPT_TREE_MODE, false);
119
120         pOptions->InitOption(OPT_CMP_METHOD, (int)CMP_CONTENT);
121         pOptions->InitOption(OPT_CMP_MOVED_BLOCKS, false);
122         pOptions->InitOption(OPT_CMP_MATCH_SIMILAR_LINES, false);
123         pOptions->InitOption(OPT_CMP_STOP_AFTER_FIRST, false);
124         pOptions->InitOption(OPT_CMP_QUICK_LIMIT, 4 * 1024 * 1024); // 4 Megs
125         pOptions->InitOption(OPT_CMP_WALK_UNIQUE_DIRS, false);
126         pOptions->InitOption(OPT_CMP_IGNORE_REPARSE_POINTS, false);
127
128         pOptions->InitOption(OPT_CMP_BIN_FILEPATTERNS, _T("*.bin;*.frx"));
129
130         pOptions->InitOption(OPT_CMP_IMG_FILEPATTERNS, _T("*.bmp;*.cut;*.dds;*.exr;*.g3;*.gif;*.hdr;*.ico;*.iff;*.lbm;*.j2k;*.j2c;*.jng;*.jp2;*.jpg;*.jif;*.jpeg;*.jpe;*.jxr;*.wdp;*.hdp;*.koa;*.mng;*.pcd;*.pcx;*.pfm;*.pct;*.pict;*.pic;*.png;*.pbm;*.pgm;*.ppm;*.psd;*.ras;*.sgi;*.rgb;*.rgba;*.bw;*.tga;*.targa;*.tif;*.tiff;*.wap;*.wbmp;*.wbm;*.webp;*.xbm;*.xpm"));
131         pOptions->InitOption(OPT_CMP_IMG_SHOWDIFFERENCES, true);
132         pOptions->InitOption(OPT_CMP_IMG_OVERLAYMOVE, 0);
133         pOptions->InitOption(OPT_CMP_IMG_ZOOM, 1000);
134         pOptions->InitOption(OPT_CMP_IMG_USEBACKCOLOR, true);
135         pOptions->InitOption(OPT_CMP_IMG_BACKCOLOR, 0xFFFFFF);
136         pOptions->InitOption(OPT_CMP_IMG_DIFFBLOCKSIZE, 8);
137         pOptions->InitOption(OPT_CMP_IMG_THRESHOLD, 0);
138
139         pOptions->InitOption(OPT_PROJECTS_PATH, _T(""));
140         pOptions->InitOption(OPT_USE_SYSTEM_TEMP_PATH, true);
141         pOptions->InitOption(OPT_CUSTOM_TEMP_PATH, _T(""));
142
143         pOptions->InitOption(OPT_LINEFILTER_ENABLED, false);
144         pOptions->InitOption(OPT_FILEFILTER_CURRENT, _T("*.*"));
145         // CMainFrame initializes this when it is empty.
146         pOptions->InitOption(OPT_FILTER_USERPATH, paths_ConcatPath(env_GetMyDocuments(), DefaultRelativeFilterPath));
147         pOptions->InitOption(OPT_FILEFILTER_SHARED, false);
148
149         pOptions->InitOption(OPT_CP_DEFAULT_MODE, (int)0);
150         pOptions->InitOption(OPT_CP_DEFAULT_CUSTOM, (int)GetACP());
151
152         if (PRIMARYLANGID(LangId) == LANG_JAPANESE)
153                 pOptions->InitOption(OPT_CP_DETECT, (int)(50932 << 16) | 3);
154         else if (LangId == MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED))
155                 pOptions->InitOption(OPT_CP_DETECT, (int)(50936 << 16) | 3);
156         else if (PRIMARYLANGID(LangId) == LANG_KOREAN)
157                 pOptions->InitOption(OPT_CP_DETECT, (int)(50949 << 16) | 3);
158         else if (LangId == MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL))
159                 pOptions->InitOption(OPT_CP_DETECT, (int)(50950 << 16) | 3);
160         else
161                 pOptions->InitOption(OPT_CP_DETECT, (int)(50001 << 16) | 3);
162
163         pOptions->InitOption(OPT_VCS_SYSTEM, SourceControl::VCS_NONE);
164         pOptions->InitOption(OPT_VSS_PATH, _T(""));
165         pOptions->InitOption(OPT_VSS_DATABASE, _T(""));
166         pOptions->InitOption(OPT_VSS_PROJECT, _T(""));
167         pOptions->InitOption(OPT_VSS_USER, _T(""));
168
169         pOptions->InitOption(OPT_ARCHIVE_ENABLE, 1); // Enable by default
170         pOptions->InitOption(OPT_ARCHIVE_PROBETYPE, false);
171
172         pOptions->InitOption(OPT_PLUGINS_ENABLED, true);
173         pOptions->InitOption(OPT_PLUGINS_DISABLED_LIST, _T(""));
174
175         pOptions->InitOption(OPT_TABBAR_AUTO_MAXWIDTH, true);
176
177         Options::DiffOptions::SetDefaults(pOptions);
178         Options::DiffColors::SetDefaults(pOptions);
179         Options::Font::SetDefaults(pOptions);
180 }
181
182 }
183
184 /**
185  * @brief Copy some HKLM values to HKCU.
186  * The installer sets HKLM values for "all users". This function copies
187  * few of those values for "user" values. E.g. enabling ShellExtension
188  * initially for user is done by this function.
189  */
190 static void CopyHKLMValues()
191 {
192         HKEY LMKey;
193         HKEY CUKey;
194         if (OpenHKLM(&LMKey))
195         {
196                 if (OpenHKCU(&CUKey))
197                 {
198                         CopyFromLMtoCU(LMKey, CUKey, _T("ContextMenuEnabled"));
199                         CopyFromLMtoCU(LMKey, CUKey, _T("Executable"));
200                         RegCloseKey(CUKey);
201                 }
202                 RegCloseKey(LMKey);
203         }
204         if (OpenHKLM(&LMKey, _T("Locale")))
205         {
206                 if (OpenHKCU(&CUKey, _T("Locale")))
207                 {
208                         CopyFromLMtoCU(LMKey, CUKey, _T("LanguageId"));
209                         RegCloseKey(CUKey);
210                 }
211                 RegCloseKey(LMKey);
212         }
213 }
214
215 /**
216  * @brief Open HKLM registry key.
217  * @param [out] key Pointer to open HKLM key.
218  * @param [in] relpath Relative registry path (to WinMerge reg path) to open, or NULL.
219  * @return true if opening succeeded.
220  */
221 static bool OpenHKLM(HKEY *key, LPCTSTR relpath)
222 {
223         TCHAR valuename[256];
224         if (relpath)
225                 wsprintf(valuename, _T("%s\\%s"), RegDir, relpath);
226         else
227                 lstrcpy(valuename, RegDir);
228         LONG retval = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
229                         valuename, 0, KEY_READ, key);
230         if (retval == ERROR_SUCCESS)
231         {
232                 return true;
233         }
234         return false;
235 }
236
237 /**
238  * @brief Open HKCU registry key.
239  * Opens the HKCU key for WinMerge. If the key does not exist, creates one.
240  * @param [out] key Pointer to open HKCU key.
241  * @param [in] relpath Relative registry path (to WinMerge reg path) to open, or NULL.
242  * @return true if opening succeeded.
243  */
244 static bool OpenHKCU(HKEY *key, LPCTSTR relpath)
245 {
246         TCHAR valuename[256];
247         if (relpath)
248                 wsprintf(valuename, _T("%s\\%s"), RegDir, relpath);
249         else
250                 lstrcpy(valuename, RegDir);
251         LONG retval = RegOpenKeyEx(HKEY_CURRENT_USER,
252                         valuename, 0, KEY_ALL_ACCESS, key);
253         if (retval == ERROR_SUCCESS)
254         {
255                 return true;
256         }
257         else if (retval == ERROR_FILE_NOT_FOUND)
258         {
259                 retval = RegCreateKeyEx(HKEY_CURRENT_USER,
260                         valuename, 0, NULL, 0, KEY_ALL_ACCESS, NULL, key, NULL);
261                 if (retval == ERROR_SUCCESS)
262                         return true;
263         }
264         return false;
265 }
266
267 /**
268  * @brief Copy value from HKLM to HKCU.
269  * @param [in] lmKey HKLM key from where to copy.
270  * @param [in] cuKey HKCU key to where to copy.
271  * @param [in] valname Name of the value to copy.
272  */
273 static void CopyFromLMtoCU(HKEY lmKey, HKEY cuKey, LPCTSTR valname)
274 {
275         DWORD len = 0;
276         LONG retval = RegQueryValueEx(cuKey, valname, 0, NULL, NULL, &len);
277         if (retval == ERROR_FILE_NOT_FOUND)
278         {
279                 retval = RegQueryValueEx(lmKey, valname, 0, NULL, NULL, &len);
280                 if (retval == ERROR_SUCCESS)
281                 {
282                         DWORD type = 0;
283                         std::vector<BYTE> buf(len);
284                         retval = RegQueryValueEx(lmKey, valname, 0, &type, &buf[0], &len);
285                         if (retval == ERROR_SUCCESS)
286                         {
287                                 retval = RegSetValueEx(cuKey, valname , 0, type,
288                                         &buf[0], len);
289                         }
290                 }
291         }
292 }