OSDN Git Service

Fix typo
[winmerge-jp/winmerge-jp.git] / Src / MergeFrameCommon.cpp
1 /** \r
2  * @file  MergeFrameCommon.cpp\r
3  *\r
4  * @brief Implementation file for CMergeFrameCommon\r
5  *\r
6  */\r
7 #include "StdAfx.h"\r
8 #include "MergeFrameCommon.h"\r
9 #include "OptionsDef.h"\r
10 #include "OptionsMgr.h"\r
11 #include "paths.h"\r
12 #include "Merge.h"\r
13 #include "FileTransform.h"\r
14 #include <../src/mfc/afximpl.h>\r
15 \r
16 IMPLEMENT_DYNCREATE(CMergeFrameCommon, CMDIChildWnd)\r
17 \r
18 BEGIN_MESSAGE_MAP(CMergeFrameCommon, CMDIChildWnd)\r
19         //{{AFX_MSG_MAP(CMergeFrameCommon)\r
20         ON_WM_GETMINMAXINFO()\r
21         ON_WM_DESTROY()\r
22         ON_WM_MDIACTIVATE()\r
23         //}}AFX_MSG_MAP\r
24 END_MESSAGE_MAP()\r
25 \r
26 CMergeFrameCommon::CMergeFrameCommon(int nIdenticalIcon, int nDifferentIcon)\r
27         : m_hIdentical(nIdenticalIcon < 0 ? nullptr : AfxGetApp()->LoadIcon(nIdenticalIcon))\r
28         , m_hDifferent(nDifferentIcon < 0 ? nullptr : AfxGetApp()->LoadIcon(nDifferentIcon))\r
29         , m_hCurrent((HICON)-1)\r
30         , m_bActivated(false)\r
31         , m_nLastSplitPos{0}\r
32 {\r
33         ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), WMU_CHILDFRAMEADDED, 0, reinterpret_cast<LPARAM>(this));\r
34 }\r
35 \r
36 CMergeFrameCommon::~CMergeFrameCommon()\r
37 {\r
38         ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), WMU_CHILDFRAMEREMOVED, 0, reinterpret_cast<LPARAM>(this));\r
39 }\r
40 \r
41 void CMergeFrameCommon::ActivateFrame(int nCmdShow)\r
42 {\r
43         if (!m_bActivated) \r
44         {\r
45                 m_bActivated = true;\r
46 \r
47                 // get the active child frame, and a flag whether it is maximized\r
48                 BOOL bMaximized = FALSE;\r
49                 CMDIChildWnd * oldActiveFrame = GetMDIFrame()->MDIGetActive(&bMaximized);\r
50                 if (oldActiveFrame == nullptr)\r
51                         // for the first frame, get the restored/maximized state from the registry\r
52                         bMaximized = GetOptionsMgr()->GetBool(OPT_ACTIVE_FRAME_MAX);\r
53                 if (bMaximized)\r
54                         nCmdShow = SW_SHOWMAXIMIZED;\r
55                 else\r
56                         nCmdShow = SW_SHOWNORMAL;\r
57         }\r
58 \r
59         __super::ActivateFrame(nCmdShow);\r
60 }\r
61 \r
62 void CMergeFrameCommon::SaveWindowState()\r
63 {\r
64         // If we are active, save the restored/maximized state\r
65         // If we are not, do nothing and let the active frame do the job.\r
66         if (GetParentFrame()->GetActiveFrame() == this)\r
67         {\r
68                 WINDOWPLACEMENT wp = { sizeof(WINDOWPLACEMENT) };\r
69                 GetWindowPlacement(&wp);\r
70                 GetOptionsMgr()->SaveOption(OPT_ACTIVE_FRAME_MAX, (wp.showCmd == SW_MAXIMIZE));\r
71         }\r
72 }\r
73 \r
74 void CMergeFrameCommon::RemoveBarBorder()\r
75 {\r
76         afxData.cxBorder2 = 0;\r
77         afxData.cyBorder2 = 0;\r
78         for (int i = 0; i < 4; ++i)\r
79         {\r
80                 CControlBar* pBar = GetControlBar(i + AFX_IDW_DOCKBAR_TOP);\r
81                 pBar->SetBarStyle(pBar->GetBarStyle() & ~(CBRS_BORDER_ANY | CBRS_BORDER_3D));\r
82         }\r
83 }\r
84 \r
85 /**\r
86  * @brief Reflect comparison result in window's icon.\r
87  * @param nResult [in] Last comparison result which the application returns.\r
88  */\r
89 void CMergeFrameCommon::SetLastCompareResult(int nResult)\r
90 {\r
91         HICON hReplace = (nResult == 0) ? m_hIdentical : m_hDifferent;\r
92 \r
93         if (m_hCurrent != hReplace)\r
94         {\r
95                 SetIcon(hReplace, TRUE);\r
96 \r
97                 AfxGetMainWnd()->SetTimer(IDT_UPDATEMAINMENU, 500, nullptr);\r
98 \r
99                 m_hCurrent = hReplace;\r
100         }\r
101 \r
102         theApp.SetLastCompareResult(nResult);\r
103 }\r
104 \r
105 void CMergeFrameCommon::ShowIdenticalMessage(const PathContext& paths, bool bIdenticalAll, std::function<int(const tchar_t*, unsigned, unsigned)> fnMessageBox)\r
106 {\r
107         String s;\r
108         if (theApp.m_bExitIfNoDiff != MergeCmdLineInfo::ExitQuiet)\r
109         {\r
110                 UINT nFlags = MB_ICONINFORMATION | MB_DONT_DISPLAY_AGAIN;\r
111 \r
112                 if (theApp.m_bExitIfNoDiff == MergeCmdLineInfo::Exit)\r
113                 {\r
114                         // Show the "files are identical" for basic "exit no diff" flag\r
115                         // If user don't want to see the message one uses the quiet version\r
116                         // of the "exit no diff".\r
117                         nFlags &= ~MB_DONT_DISPLAY_AGAIN;\r
118                 }\r
119                 if ((paths.GetSize() == 2 && !paths.GetLeft().empty() && !paths.GetRight().empty() &&\r
120                          strutils::compare_nocase(paths.GetLeft(), paths.GetRight()) == 0) ||\r
121                         (paths.GetSize() == 3 && !paths.GetLeft().empty() && !paths.GetMiddle().empty() && !paths.GetRight().empty() &&\r
122                          (strutils::compare_nocase(paths.GetLeft(), paths.GetRight()) == 0 ||\r
123                           strutils::compare_nocase(paths.GetMiddle(), paths.GetRight()) == 0 ||\r
124                           strutils::compare_nocase(paths.GetLeft(), paths.GetMiddle()) == 0)))\r
125                 {\r
126                         // compare file to itself, a custom message so user may hide the message in this case only\r
127                         s = _("The same file is opened in both panels.");\r
128                         fnMessageBox(s.c_str(), nFlags, IDS_FILE_TO_ITSELF);\r
129                 }\r
130                 else if (bIdenticalAll)\r
131                 {\r
132                         s = _("The selected files are identical.");\r
133                         fnMessageBox(s.c_str(), nFlags, IDS_FILESSAME);\r
134                 }\r
135         }\r
136 \r
137         if (bIdenticalAll)\r
138         {\r
139                 // Exit application if files are identical.\r
140                 if (theApp.m_bExitIfNoDiff == MergeCmdLineInfo::Exit ||\r
141                         theApp.m_bExitIfNoDiff == MergeCmdLineInfo::ExitQuiet)\r
142                 {\r
143                         AfxGetMainWnd()->PostMessage(WM_COMMAND, ID_APP_EXIT);\r
144                 }\r
145         }\r
146 }\r
147 \r
148 String CMergeFrameCommon::GetTitleString(const PathContext& paths, const String desc[],\r
149         const PackingInfo *pInfoUnpacker, const PrediffingInfo *pInfoPrediffer, bool hasTrivialDiffs)\r
150 {\r
151         const int nBuffers = paths.GetSize();\r
152         String sFileName[3];\r
153         String sTitle;\r
154         for (int nBuffer = 0; nBuffer < paths.GetSize(); nBuffer++)\r
155                 sFileName[nBuffer] = !desc[nBuffer].empty() ? desc[nBuffer] : paths::FindFileName(paths[nBuffer]);\r
156         if (std::count(&sFileName[0], &sFileName[0] + nBuffers, sFileName[0]) == nBuffers)\r
157                 sTitle = sFileName[0] + strutils::format(_T(" x %d"), nBuffers);\r
158         else\r
159                 sTitle = strutils::join(&sFileName[0], &sFileName[0] + nBuffers, _T(" - "));\r
160         String flags;\r
161         if (pInfoUnpacker && !pInfoUnpacker->GetPluginPipeline().empty())\r
162                 flags += _T("U");\r
163         if (pInfoPrediffer && !pInfoPrediffer->GetPluginPipeline().empty())\r
164                 flags += _T("P");\r
165         if (hasTrivialDiffs)\r
166                 flags += _T("F");\r
167         return (flags.empty() ? _T("") : (_T("(") + flags + _T(") "))) + sTitle;\r
168 }\r
169 \r
170 String CMergeFrameCommon::GetTooltipString(const PathContext& paths, const String desc[],\r
171         const PackingInfo *pInfoUnpacker, const PrediffingInfo *pInfoPrediffer, bool hasTrivialDiffs)\r
172 {\r
173         const int nBuffers = paths.GetSize();\r
174         String sTitle;\r
175         for (int nBuffer = 0; nBuffer < paths.GetSize(); nBuffer++)\r
176         {\r
177                 sTitle += strutils::format(_T("%d: "), nBuffer + 1);\r
178                 if (!desc[nBuffer].empty())\r
179                 {\r
180                         sTitle += desc[nBuffer];\r
181                         if (!paths[nBuffer].empty()) \r
182                                 sTitle += _T(" (") + paths[nBuffer] + _T(")");\r
183                 }\r
184                 else\r
185                 {\r
186                         sTitle += paths[nBuffer];\r
187                 }\r
188                 sTitle += _T(" - ");\r
189                 if (nBuffer == 0)\r
190                         sTitle += _("Left");\r
191                 else if (nBuffer == 1 && paths.GetSize() > 2)\r
192                         sTitle += _("Middle");\r
193                 else\r
194                         sTitle += _("Right");\r
195                 sTitle += _T("\n");\r
196         }\r
197         if (pInfoUnpacker && !pInfoUnpacker->GetPluginPipeline().empty())\r
198                 sTitle += strutils::format(_T("%s: %s\n"), _("Unpacker"), pInfoUnpacker->GetPluginPipeline());\r
199         if (pInfoPrediffer && !pInfoPrediffer->GetPluginPipeline().empty())\r
200                 sTitle += strutils::format(_T("%s: %s\n"), _("Prediffer"), pInfoPrediffer->GetPluginPipeline());\r
201         if (hasTrivialDiffs)\r
202                 sTitle += _("Filter applied") + _T("\n");\r
203         return sTitle;\r
204 }\r
205 \r
206 void CMergeFrameCommon::ChangeMergeMenuText(int srcPane, int dstPane, CCmdUI* pCmdUI)\r
207 {\r
208         String text;\r
209         switch (pCmdUI->m_nID)\r
210         {\r
211         case ID_L2R:\r
212                 text = (srcPane == 0 && dstPane == 1) ?\r
213                         _("Copy to &Middle\tAlt+Right") : _("Copy to &Right\tAlt+Right");\r
214                 break;\r
215         case ID_R2L:\r
216                 text = (srcPane == 2 && dstPane == 1) ?\r
217                         _("Copy to &Middle\tAlt+Left") : _("Copy to L&eft\tAlt+Left");\r
218                 break;\r
219         case ID_COPY_FROM_LEFT:\r
220                 text = (srcPane == 1 && dstPane == 2) ?\r
221                         _("Copy from Middle\tAlt+Shift+Right") : _("Copy from Left\tAlt+Shift+Right");\r
222                 break;\r
223         case ID_COPY_FROM_RIGHT:\r
224                 text = (srcPane == 1 && dstPane == 0) ?\r
225                         _("Copy from Middle\tAlt+Shift+Left") : _("Copy from Right\tAlt+Shift+Left");\r
226                 break;\r
227         case ID_L2RNEXT:\r
228                 text = (srcPane == 0 && dstPane == 1) ?\r
229                         _("Copy to Middle and Advance\tCtrl+Alt+Right") : _("C&opy to Right and Advance\tCtrl+Alt+Right");\r
230                 break;\r
231         case ID_R2LNEXT:\r
232                 text = (srcPane == 2 && dstPane == 1) ?\r
233                         _("Copy to Middle and Advance\tCtrl+Alt+Left") : _("Copy &to Left and Advance\tCtrl+Alt+Left");\r
234                 break;\r
235         case ID_ALL_RIGHT:\r
236                 text = (srcPane == 0 && dstPane == 1) ?\r
237                         _("Copy All to Middle") : _("Copy &All to Right");\r
238                 break;\r
239         case ID_ALL_LEFT:\r
240                 text = (srcPane == 2 && dstPane == 1) ?\r
241                         _("Copy All to Middle") : _("Cop&y All to Left");\r
242                 break;\r
243         }\r
244         if (!text.empty())\r
245                 pCmdUI->SetText(text.c_str());\r
246 }\r
247 \r
248 std::pair<int, int> CMergeFrameCommon::MenuIDtoXY(UINT nID, int nActivePane, int nBuffers)\r
249 {\r
250         if (nActivePane < 0 || nActivePane >= nBuffers)\r
251                 return { -1, -1 };\r
252 \r
253         int srcPane = -1, dstPane = -1;\r
254         switch (nID)\r
255         {\r
256         case ID_L2R:\r
257         case ID_L2RNEXT:\r
258         case ID_ALL_RIGHT:\r
259         case ID_LINES_L2R:\r
260                 dstPane = (nActivePane < nBuffers - 1) ? nActivePane + 1 : nBuffers - 1;\r
261                 srcPane = dstPane - 1;\r
262                 break;\r
263         case ID_R2L:\r
264         case ID_R2LNEXT:\r
265         case ID_ALL_LEFT:\r
266         case ID_LINES_R2L:\r
267                 dstPane = (nActivePane > 0) ? nActivePane - 1 : 0;\r
268                 srcPane = dstPane + 1;\r
269                 break;\r
270         case ID_COPY_FROM_LEFT:\r
271         case ID_COPY_LINES_FROM_LEFT:\r
272                 if (nActivePane > 0)\r
273                 {\r
274                         dstPane = nActivePane;\r
275                         srcPane = nActivePane - 1;\r
276                 }\r
277                 break;\r
278         case ID_COPY_FROM_RIGHT:\r
279         case ID_COPY_LINES_FROM_RIGHT:\r
280                 if (nActivePane < nBuffers - 1)\r
281                 {\r
282                         dstPane = nActivePane;\r
283                         srcPane = nActivePane + 1;\r
284                 }\r
285                 break;\r
286         case ID_COPY_TO_MIDDLE_L:\r
287         case ID_COPY_LINES_TO_MIDDLE_L:\r
288                 if (nBuffers > 2)\r
289                 {\r
290                         srcPane = 0;\r
291                         dstPane = 1;\r
292                 }\r
293                 break;\r
294         case ID_COPY_TO_RIGHT_L:\r
295         case ID_COPY_LINES_TO_RIGHT_L:\r
296                 srcPane = 0; dstPane = nBuffers - 1; break;\r
297         case ID_COPY_FROM_MIDDLE_L:\r
298         case ID_COPY_LINES_FROM_MIDDLE_L:\r
299                 if (nBuffers > 2)\r
300                 {\r
301                         srcPane = 1;\r
302                         dstPane = 0;\r
303                 }\r
304                 break;\r
305         case ID_COPY_FROM_RIGHT_L:\r
306         case ID_COPY_LINES_FROM_RIGHT_L:\r
307                 srcPane = nBuffers - 1; dstPane = 0; break;\r
308         case ID_COPY_TO_LEFT_M:\r
309         case ID_COPY_LINES_TO_LEFT_M:\r
310                 if (nBuffers > 2)\r
311                 {\r
312                         srcPane = 1;\r
313                         dstPane = 0;\r
314                 }\r
315                 break;\r
316         case ID_COPY_TO_RIGHT_M:\r
317         case ID_COPY_LINES_TO_RIGHT_M:\r
318                 if (nBuffers > 2)\r
319                 {\r
320                         srcPane = 1;\r
321                         dstPane = nBuffers - 1;\r
322                 }\r
323                 break;\r
324         case ID_COPY_FROM_LEFT_M:\r
325         case ID_COPY_LINES_FROM_LEFT_M:\r
326                 if (nBuffers > 2)\r
327                 {\r
328                         srcPane = 0;\r
329                         dstPane = 1;\r
330                 }\r
331                 break;\r
332         case ID_COPY_FROM_RIGHT_M:\r
333         case ID_COPY_LINES_FROM_RIGHT_M:\r
334                 if (nBuffers > 2)\r
335                 {\r
336                         srcPane = nBuffers - 1;\r
337                         dstPane = 1;\r
338                 }\r
339                 break;\r
340         case ID_COPY_TO_MIDDLE_R:\r
341         case ID_COPY_LINES_TO_MIDDLE_R:\r
342                 if (nBuffers > 2)\r
343                 {\r
344                         srcPane = nBuffers - 1;\r
345                         dstPane = 1;\r
346                 }\r
347                 break;\r
348         case ID_COPY_TO_LEFT_R:\r
349         case ID_COPY_LINES_TO_LEFT_R:\r
350                 srcPane = nBuffers - 1; dstPane = 0; break;\r
351         case ID_COPY_FROM_MIDDLE_R:\r
352         case ID_COPY_LINES_FROM_MIDDLE_R:\r
353                 if (nBuffers > 2)\r
354                 {\r
355                         srcPane = 1;\r
356                         dstPane = nBuffers - 1;\r
357                 }\r
358                 break;\r
359         case ID_COPY_FROM_LEFT_R:\r
360         case ID_COPY_LINES_FROM_LEFT_R:\r
361                 srcPane = 0; dstPane = nBuffers - 1; break;\r
362         default:\r
363                 return { -1, -1 };\r
364         }\r
365         return { srcPane, dstPane };\r
366 }\r
367 \r
368 void CMergeFrameCommon::OnGetMinMaxInfo(MINMAXINFO* lpMMI)\r
369 {\r
370         __super::OnGetMinMaxInfo(lpMMI);\r
371         // [Fix for MFC 8.0 MDI Maximizing Child Window bug on Vista]\r
372         // https://groups.google.com/forum/#!topic/microsoft.public.vc.mfc/iajCdW5DzTM\r
373         lpMMI->ptMaxTrackSize.x = max(lpMMI->ptMaxTrackSize.x, lpMMI->ptMaxSize.x);\r
374         lpMMI->ptMaxTrackSize.y = max(lpMMI->ptMaxTrackSize.y, lpMMI->ptMaxSize.y);\r
375 }\r
376 \r
377 void CMergeFrameCommon::OnDestroy()\r
378 {\r
379         // https://stackoverflow.com/questions/35553955/getting-rid-of-3d-look-of-mdi-frame-window\r
380         CFrameWnd::OnDestroy();\r
381 }\r
382 \r
383 void CMergeFrameCommon::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd)\r
384 {\r
385         // call the base class to let standard processing switch to\r
386         // the top-level menu associated with this window\r
387         __super::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd);\r
388 \r
389         if (bActivate)\r
390                 ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), WMU_CHILDFRAMEACTIVATED, 0, reinterpret_cast<LPARAM>(this));\r
391 }\r