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