OSDN Git Service

Add support for PDF, SVG, WMF and EMF flie format
[winmerge-jp/winmerge-jp.git] / Src / OptionsInit.cpp
1 /**
2  * @file  OptionsInit.cpp
3  *
4  * @brief Options initialisation.
5  */
6
7 #include "pch.h"
8 #include <vector>
9 #include "OptionsDef.h"
10 #include "OptionsMgr.h"
11 #include "RegOptionsMgr.h"
12 #include "OptionsDiffOptions.h"
13 #include "OptionsDiffColors.h"
14 #include "OptionsDirColors.h"
15 #include "OptionsFont.h"
16 #include "DiffWrapper.h" // CMP_CONTENT
17 #include "paths.h"
18 #include "Environment.h"
19 #include "FileTransform.h"
20 #include "Constants.h"
21
22 // Functions to copy values set by installer from HKLM to HKCU.
23 static void CopyHKLMValues();
24 static bool OpenHKLM(HKEY *key, LPCTSTR relpath = nullptr);
25 static bool OpenHKCU(HKEY *key, LPCTSTR relpath = nullptr);
26 static void CopyFromLMtoCU(HKEY lmKey, HKEY cuKey, LPCTSTR valname);
27
28 namespace Options
29 {
30
31 /**
32  * @brief Initialise options and set default values.
33  *
34  * @note Remember default values are what users see first time
35  * using WinMerge and many users never change them. So pick
36  * default values carefully!
37  */
38 void Init(COptionsMgr *pOptions)
39 {
40         // Copy some values from HKLM to HKCU
41         CopyHKLMValues();
42
43         static_cast<CRegOptionsMgr *>(pOptions)->SetRegRootKey(_T("Thingamahoochie\\WinMerge\\"));
44
45         LANGID LangId = GetUserDefaultLangID();
46         pOptions->InitOption(OPT_SELECTED_LANGUAGE, static_cast<int>(LangId));
47
48         // Initialise options (name, default value)
49         pOptions->InitOption(OPT_SHOW_UNIQUE_LEFT, true);
50         pOptions->InitOption(OPT_SHOW_UNIQUE_MIDDLE, true);
51         pOptions->InitOption(OPT_SHOW_UNIQUE_RIGHT, true);
52         pOptions->InitOption(OPT_SHOW_DIFFERENT, true);
53         pOptions->InitOption(OPT_SHOW_IDENTICAL, true);
54         pOptions->InitOption(OPT_SHOW_BINARIES, true);
55         pOptions->InitOption(OPT_SHOW_SKIPPED, false);
56         pOptions->InitOption(OPT_SHOW_DIFFERENT_LEFT_ONLY, true);
57         pOptions->InitOption(OPT_SHOW_DIFFERENT_MIDDLE_ONLY, true);
58         pOptions->InitOption(OPT_SHOW_DIFFERENT_RIGHT_ONLY, true);
59         pOptions->InitOption(OPT_SHOW_MISSING_LEFT_ONLY, true);
60         pOptions->InitOption(OPT_SHOW_MISSING_MIDDLE_ONLY, true);
61         pOptions->InitOption(OPT_SHOW_MISSING_RIGHT_ONLY, true);
62
63         pOptions->InitOption(OPT_SHOW_TOOLBAR, true);
64         pOptions->InitOption(OPT_SHOW_STATUSBAR, true);
65         pOptions->InitOption(OPT_SHOW_TABBAR, true);
66         const int cxsmicon = GetSystemMetrics(SM_CXSMICON);
67         pOptions->InitOption(OPT_TOOLBAR_SIZE, (cxsmicon < 28) ? 0 : (cxsmicon < 40 ? 1 : 2));
68         pOptions->InitOption(OPT_RESIZE_PANES, false);
69
70         pOptions->InitOption(OPT_SYNTAX_HIGHLIGHT, true);
71         pOptions->InitOption(OPT_WORDWRAP, false);
72         pOptions->InitOption(OPT_VIEW_LINENUMBERS, false);
73         pOptions->InitOption(OPT_VIEW_WHITESPACE, false);
74         pOptions->InitOption(OPT_CONNECT_MOVED_BLOCKS, 0);
75         pOptions->InitOption(OPT_SCROLL_TO_FIRST, false);
76         pOptions->InitOption(OPT_VERIFY_OPEN_PATHS, true);
77         pOptions->InitOption(OPT_AUTO_COMPLETE_SOURCE, (int)1);
78         pOptions->InitOption(OPT_VIEW_FILEMARGIN, false);
79         pOptions->InitOption(OPT_DIFF_CONTEXT, (int)-1);
80         pOptions->InitOption(OPT_SPLIT_HORIZONTALLY, false);
81         pOptions->InitOption(OPT_RENDERING_MODE, -1);
82
83         pOptions->InitOption(OPT_WORDDIFF_HIGHLIGHT, true);
84         pOptions->InitOption(OPT_BREAK_SEPARATORS, _T(".,:;?[](){}<>`'!\"#$%&^~\\|@+-*/"));
85
86         pOptions->InitOption(OPT_BACKUP_FOLDERCMP, false);
87         pOptions->InitOption(OPT_BACKUP_FILECMP, true);
88         pOptions->InitOption(OPT_BACKUP_LOCATION, (int)0);
89         pOptions->InitOption(OPT_BACKUP_GLOBALFOLDER, _T(""));
90         pOptions->InitOption(OPT_BACKUP_ADD_BAK, true);
91         pOptions->InitOption(OPT_BACKUP_ADD_TIME, false);
92
93         pOptions->InitOption(OPT_DIRVIEW_SORT_COLUMN, (int)-1);
94         pOptions->InitOption(OPT_DIRVIEW_SORT_COLUMN3, (int)-1);
95         pOptions->InitOption(OPT_DIRVIEW_SORT_ASCENDING, true);
96         pOptions->InitOption(OPT_SHOW_SELECT_FILES_AT_STARTUP, false);
97         pOptions->InitOption(OPT_DIRVIEW_EXPAND_SUBDIRS, false);
98
99         pOptions->InitOption(OPT_REPORTFILES_REPORTTYPE, 0);
100         pOptions->InitOption(OPT_REPORTFILES_COPYTOCLIPBOARD, false);
101         pOptions->InitOption(OPT_REPORTFILES_INCLUDEFILECMPREPORT, false);
102
103         pOptions->InitOption(OPT_AUTOMATIC_RESCAN, false);
104         pOptions->InitOption(OPT_ALLOW_MIXED_EOL, false);
105         pOptions->InitOption(OPT_TAB_SIZE, (int)4);
106         pOptions->InitOption(OPT_TAB_TYPE, (int)0);     // 0 means tabs inserted
107
108         pOptions->InitOption(OPT_EXT_EDITOR_CMD, paths::ConcatPath(env::GetWindowsDirectory(), _T("NOTEPAD.EXE")));
109         pOptions->InitOption(OPT_USE_RECYCLE_BIN, true);
110         pOptions->InitOption(OPT_SINGLE_INSTANCE, false);
111         pOptions->InitOption(OPT_MERGE_MODE, false);
112         // OPT_WORDDIFF_HIGHLIGHT is initialized above
113         pOptions->InitOption(OPT_BREAK_ON_WORDS, false);
114         pOptions->InitOption(OPT_BREAK_TYPE, 1);
115
116         pOptions->InitOption(OPT_CLOSE_WITH_ESC, 1);
117         pOptions->InitOption(OPT_CLOSE_WITH_OK, false);
118         pOptions->InitOption(OPT_IGNORE_SMALL_FILETIME, false);
119         pOptions->InitOption(OPT_ASK_MULTIWINDOW_CLOSE, false);
120         pOptions->InitOption(OPT_PRESERVE_FILETIMES, false);
121         pOptions->InitOption(OPT_TREE_MODE, true);
122
123         pOptions->InitOption(OPT_CMP_METHOD, (int)CMP_CONTENT);
124         pOptions->InitOption(OPT_CMP_MOVED_BLOCKS, false);
125         pOptions->InitOption(OPT_CMP_MATCH_SIMILAR_LINES, false);
126         pOptions->InitOption(OPT_CMP_STOP_AFTER_FIRST, false);
127         pOptions->InitOption(OPT_CMP_QUICK_LIMIT, 4 * 1024 * 1024); // 4 Megs
128         pOptions->InitOption(OPT_CMP_BINARY_LIMIT, 64 * 1024 * 1024); // 64 Megs
129         pOptions->InitOption(OPT_CMP_COMPARE_THREADS, -1);
130         pOptions->InitOption(OPT_CMP_WALK_UNIQUE_DIRS, false);
131         pOptions->InitOption(OPT_CMP_IGNORE_REPARSE_POINTS, false);
132         pOptions->InitOption(OPT_CMP_IGNORE_CODEPAGE, true);
133         pOptions->InitOption(OPT_CMP_INCLUDE_SUBDIRS, true);
134
135         pOptions->InitOption(OPT_CMP_BIN_FILEPATTERNS, _T("*.bin;*.frx"));
136
137         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"));
138         pOptions->InitOption(OPT_CMP_IMG_SHOWDIFFERENCES, true);
139         pOptions->InitOption(OPT_CMP_IMG_OVERLAYMOVE, 0);
140         pOptions->InitOption(OPT_CMP_IMG_OVERLAYALPHA, 30);
141         pOptions->InitOption(OPT_CMP_IMG_DRAGGING_MODE, 1);
142         pOptions->InitOption(OPT_CMP_IMG_ZOOM, 1000);
143         pOptions->InitOption(OPT_CMP_IMG_USEBACKCOLOR, true);
144         pOptions->InitOption(OPT_CMP_IMG_BACKCOLOR, 0xFFFFFF);
145         pOptions->InitOption(OPT_CMP_IMG_DIFFBLOCKSIZE, 8);
146         pOptions->InitOption(OPT_CMP_IMG_DIFFCOLORALPHA, 70);
147         pOptions->InitOption(OPT_CMP_IMG_THRESHOLD, 0);
148         pOptions->InitOption(OPT_CMP_IMG_INSERTIONDELETIONDETECTION_MODE, 0);
149         pOptions->InitOption(OPT_CMP_IMG_VECTOR_IMAGE_ZOOM_RATIO, 1000);
150
151         pOptions->InitOption(OPT_PROJECTS_PATH, _T(""));
152         pOptions->InitOption(OPT_USE_SYSTEM_TEMP_PATH, true);
153         pOptions->InitOption(OPT_CUSTOM_TEMP_PATH, _T(""));
154
155         pOptions->InitOption(OPT_LINEFILTER_ENABLED, false);
156         pOptions->InitOption(OPT_FILEFILTER_CURRENT, _T("*.*"));
157         // CMainFrame initializes this when it is empty.
158         pOptions->InitOption(OPT_FILTER_USERPATH, paths::ConcatPath(env::GetMyDocuments(), DefaultRelativeFilterPath));
159         pOptions->InitOption(OPT_FILEFILTER_SHARED, false);
160
161         pOptions->InitOption(OPT_CP_DEFAULT_MODE, (int)0);
162         pOptions->InitOption(OPT_CP_DEFAULT_CUSTOM, (int)GetACP());
163
164         if (PRIMARYLANGID(LangId) == LANG_JAPANESE)
165                 pOptions->InitOption(OPT_CP_DETECT, (int)(50932 << 16) | 3);
166         else if (LangId == MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED))
167                 pOptions->InitOption(OPT_CP_DETECT, (int)(50936 << 16) | 3);
168         else if (PRIMARYLANGID(LangId) == LANG_KOREAN)
169                 pOptions->InitOption(OPT_CP_DETECT, (int)(50949 << 16) | 3);
170         else if (LangId == MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL))
171                 pOptions->InitOption(OPT_CP_DETECT, (int)(50950 << 16) | 3);
172         else
173                 pOptions->InitOption(OPT_CP_DETECT, (int)(50001 << 16) | 1);
174
175         pOptions->InitOption(OPT_ARCHIVE_ENABLE, 1); // Enable by default
176         pOptions->InitOption(OPT_ARCHIVE_PROBETYPE, false);
177         pOptions->InitOption(OPT_ARCHIVE_FILTER_INDEX, 1);
178
179         pOptions->InitOption(OPT_PLUGINS_ENABLED, true);
180         pOptions->InitOption(OPT_PLUGINS_DISABLED_LIST, _T(""));
181         pOptions->InitOption(OPT_PLUGINS_CUSTOM_FILTERS_LIST, _T(""));
182         pOptions->InitOption(OPT_PLUGINS_UNPACKER_MODE, PLUGIN_MANUAL);
183         pOptions->InitOption(OPT_PLUGINS_PREDIFFER_MODE, PLUGIN_MANUAL);
184         pOptions->InitOption(OPT_PLUGINS_UNPACK_DONT_CHECK_EXTENSION, false);
185
186         pOptions->InitOption(OPT_PATCHCREATOR_PATCH_STYLE, 0);
187         pOptions->InitOption(OPT_PATCHCREATOR_CONTEXT_LINES, 0);
188         pOptions->InitOption(OPT_PATCHCREATOR_CASE_SENSITIVE, true);
189         pOptions->InitOption(OPT_PATCHCREATOR_EOL_SENSITIVE, true);
190         pOptions->InitOption(OPT_PATCHCREATOR_IGNORE_BLANK_LINES, false);
191         pOptions->InitOption(OPT_PATCHCREATOR_WHITESPACE, WHITESPACE_COMPARE_ALL);
192         pOptions->InitOption(OPT_PATCHCREATOR_OPEN_TO_EDITOR, false);
193         pOptions->InitOption(OPT_PATCHCREATOR_INCLUDE_CMD_LINE, false);
194
195         pOptions->InitOption(OPT_TABBAR_AUTO_MAXWIDTH, true);
196         pOptions->InitOption(OPT_ACTIVE_FRAME_MAX, true);
197         pOptions->InitOption(OPT_ACTIVE_PANE, 0);
198
199         pOptions->InitOption(OPT_MRU_MAX, 9);
200
201         Options::DiffOptions::SetDefaults(pOptions);
202         Options::DiffColors::SetDefaults(pOptions);
203         Options::DirColors::SetDefaults(pOptions);
204         Options::Font::SetDefaults(pOptions);
205 }
206
207 }
208
209 /**
210  * @brief Copy some HKLM values to HKCU.
211  * The installer sets HKLM values for "all users". This function copies
212  * few of those values for "user" values. E.g. enabling ShellExtension
213  * initially for user is done by this function.
214  */
215 static void CopyHKLMValues()
216 {
217         HKEY LMKey;
218         HKEY CUKey;
219         if (OpenHKLM(&LMKey))
220         {
221                 if (OpenHKCU(&CUKey))
222                 {
223                         CopyFromLMtoCU(LMKey, CUKey, _T("ContextMenuEnabled"));
224                         CopyFromLMtoCU(LMKey, CUKey, _T("Executable"));
225                         RegCloseKey(CUKey);
226                 }
227                 RegCloseKey(LMKey);
228         }
229         if (OpenHKLM(&LMKey, _T("Locale")))
230         {
231                 if (OpenHKCU(&CUKey, _T("Locale")))
232                 {
233                         CopyFromLMtoCU(LMKey, CUKey, _T("LanguageId"));
234                         RegCloseKey(CUKey);
235                 }
236                 RegCloseKey(LMKey);
237         }
238 }
239
240 /**
241  * @brief Open HKLM registry key.
242  * @param [out] key Pointer to open HKLM key.
243  * @param [in] relpath Relative registry path (to WinMerge reg path) to open, or nullptr.
244  * @return true if opening succeeded.
245  */
246 static bool OpenHKLM(HKEY *key, LPCTSTR relpath)
247 {
248         TCHAR valuename[256];
249         if (relpath)
250                 wsprintf(valuename, _T("%s\\%s"), RegDir, relpath);
251         else
252                 lstrcpy(valuename, RegDir);
253         LONG retval = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
254                         valuename, 0, KEY_READ, key);
255         if (retval == ERROR_SUCCESS)
256         {
257                 return true;
258         }
259         return false;
260 }
261
262 /**
263  * @brief Open HKCU registry key.
264  * Opens the HKCU key for WinMerge. If the key does not exist, creates one.
265  * @param [out] key Pointer to open HKCU key.
266  * @param [in] relpath Relative registry path (to WinMerge reg path) to open, or nullptr.
267  * @return true if opening succeeded.
268  */
269 static bool OpenHKCU(HKEY *key, LPCTSTR relpath)
270 {
271         TCHAR valuename[256];
272         if (relpath)
273                 wsprintf(valuename, _T("%s\\%s"), RegDir, relpath);
274         else
275                 lstrcpy(valuename, RegDir);
276         LONG retval = RegOpenKeyEx(HKEY_CURRENT_USER,
277                         valuename, 0, KEY_ALL_ACCESS, key);
278         if (retval == ERROR_SUCCESS)
279         {
280                 return true;
281         }
282         else if (retval == ERROR_FILE_NOT_FOUND)
283         {
284                 retval = RegCreateKeyEx(HKEY_CURRENT_USER,
285                         valuename, 0, nullptr, 0, KEY_ALL_ACCESS, nullptr, key, nullptr);
286                 if (retval == ERROR_SUCCESS)
287                         return true;
288         }
289         return false;
290 }
291
292 /**
293  * @brief Copy value from HKLM to HKCU.
294  * @param [in] lmKey HKLM key from where to copy.
295  * @param [in] cuKey HKCU key to where to copy.
296  * @param [in] valname Name of the value to copy.
297  */
298 static void CopyFromLMtoCU(HKEY lmKey, HKEY cuKey, LPCTSTR valname)
299 {
300         DWORD len = 0;
301         LONG retval = RegQueryValueEx(cuKey, valname, 0, nullptr, nullptr, &len);
302         if (retval == ERROR_FILE_NOT_FOUND)
303         {
304                 retval = RegQueryValueEx(lmKey, valname, 0, nullptr, nullptr, &len);
305                 if (retval == ERROR_SUCCESS)
306                 {
307                         DWORD type = 0;
308                         std::vector<BYTE> buf(len);
309                         retval = RegQueryValueEx(lmKey, valname, 0, &type, &buf[0], &len);
310                         if (retval == ERROR_SUCCESS)
311                         {
312                                 RegSetValueEx(cuKey, valname , 0, type,
313                                         &buf[0], len);
314                         }
315                 }
316         }
317 }