OSDN Git Service

Merge from feature_merge branch. Build TortoiseMerge successfully.
[tortoisegit/TortoiseGitJp.git] / src / TortoiseMerge / AppUtils.cpp
1 // TortoiseMerge - a Diff/Patch program\r
2 \r
3 // Copyright (C) 2006-2009 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #include "StdAfx.h"\r
20 #include "Registry.h"\r
21 #include "AppUtils.h"\r
22 #include "PathUtils.h"\r
23 #include "UnicodeUtils.h"\r
24 #include "SysProgressDlg.h"\r
25 \r
26 #include "svn_pools.h"\r
27 #include "svn_io.h"\r
28 #include "svn_path.h"\r
29 #include "svn_diff.h"\r
30 #include "svn_string.h"\r
31 #include "svn_utf.h"\r
32 \r
33 CAppUtils::CAppUtils(void)\r
34 {\r
35 }\r
36 \r
37 CAppUtils::~CAppUtils(void)\r
38 {\r
39 }\r
40 \r
41 BOOL CAppUtils::GetVersionedFile(CString sPath, CString sVersion, CString sSavePath, CSysProgressDlg * progDlg, HWND hWnd /*=NULL*/)\r
42 {\r
43         CString sSCMPath = CRegString(_T("Software\\TortoiseMerge\\SCMPath"), _T(""));\r
44         if (sSCMPath.IsEmpty())\r
45         {\r
46                 // no path set, so use TortoiseSVN as default\r
47                 sSCMPath = CPathUtils::GetAppDirectory() + _T("TortoiseProc.exe");\r
48                 sSCMPath += _T(" /command:cat /path:\"%1\" /revision:%2 /savepath:\"%3\" /hwnd:%4");\r
49         }\r
50         CString sTemp;\r
51         sTemp.Format(_T("%d"), hWnd);\r
52         sSCMPath.Replace(_T("%1"), sPath);\r
53         sSCMPath.Replace(_T("%2"), sVersion);\r
54         sSCMPath.Replace(_T("%3"), sSavePath);\r
55         sSCMPath.Replace(_T("%4"), sTemp);\r
56         // start the external SCM program to fetch the specific version of the file\r
57         STARTUPINFO startup;\r
58         PROCESS_INFORMATION process;\r
59         memset(&startup, 0, sizeof(startup));\r
60         startup.cb = sizeof(startup);\r
61         memset(&process, 0, sizeof(process));\r
62         if (CreateProcess(NULL, (LPTSTR)(LPCTSTR)sSCMPath, NULL, NULL, FALSE, 0, 0, 0, &startup, &process)==0)\r
63         {\r
64                 LPVOID lpMsgBuf;\r
65                 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \r
66                         FORMAT_MESSAGE_FROM_SYSTEM | \r
67                         FORMAT_MESSAGE_IGNORE_INSERTS,\r
68                         NULL,\r
69                         GetLastError(),\r
70                         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language\r
71                         (LPTSTR) &lpMsgBuf,\r
72                         0,\r
73                         NULL \r
74                         );\r
75                 MessageBox(NULL, (LPCTSTR)lpMsgBuf, _T("TortoiseMerge"), MB_OK | MB_ICONERROR);\r
76                 LocalFree( lpMsgBuf );\r
77         }\r
78         DWORD ret = 0;\r
79         do\r
80         {\r
81                 ret = WaitForSingleObject(process.hProcess, 100);\r
82         } while ((ret == WAIT_TIMEOUT) && (!progDlg->HasUserCancelled()));\r
83         CloseHandle(process.hThread);\r
84         CloseHandle(process.hProcess);\r
85         \r
86         if (progDlg->HasUserCancelled())\r
87         {\r
88                 return FALSE;\r
89         }\r
90         if (!PathFileExists(sSavePath))\r
91                 return FALSE;\r
92         return TRUE;\r
93 }\r
94 \r
95 bool CAppUtils::CreateUnifiedDiff(const CString& orig, const CString& modified, const CString& output, bool bShowError)\r
96 {\r
97 #if 0\r
98         apr_file_t * outfile = NULL;\r
99         apr_pool_t * pool = svn_pool_create(NULL);\r
100 \r
101         svn_error_t * err = svn_io_file_open (&outfile, svn_path_internal_style(CUnicodeUtils::GetUTF8(output), pool),\r
102                 APR_WRITE | APR_CREATE | APR_BINARY | APR_TRUNCATE,\r
103                 APR_OS_DEFAULT, pool);\r
104         if (err == NULL)\r
105         {\r
106                 svn_stream_t * stream = svn_stream_from_aprfile2(outfile, false, pool);\r
107                 if (stream)\r
108                 {\r
109                         svn_diff_t * diff = NULL;\r
110                         svn_diff_file_options_t * opts = svn_diff_file_options_create(pool);\r
111                         opts->ignore_eol_style = false;\r
112                         opts->ignore_space = svn_diff_file_ignore_space_none;\r
113                         err = svn_diff_file_diff_2(&diff, svn_path_internal_style(CUnicodeUtils::GetUTF8(orig), pool), \r
114                                 svn_path_internal_style(CUnicodeUtils::GetUTF8(modified), pool), opts, pool);\r
115                         if (err == NULL)\r
116                         {\r
117                                 err = svn_diff_file_output_unified(stream, diff, svn_path_internal_style(CUnicodeUtils::GetUTF8(orig), pool), \r
118                                         svn_path_internal_style(CUnicodeUtils::GetUTF8(modified), pool),\r
119                                         NULL, NULL, pool);\r
120                                 svn_stream_close(stream);\r
121                         }\r
122                 }\r
123                 apr_file_close(outfile);\r
124         }\r
125         if (err)\r
126         {\r
127                 if (bShowError)\r
128                         AfxMessageBox(CAppUtils::GetErrorString(err), MB_ICONERROR);\r
129                 svn_error_clear(err);\r
130                 svn_pool_destroy(pool);\r
131                 return false;\r
132         }\r
133         svn_pool_destroy(pool);\r
134 #endif\r
135         return true;\r
136 }\r
137 \r
138 CString CAppUtils::GetErrorString(svn_error_t * Err)\r
139 {\r
140         CString msg;\r
141         CString temp;\r
142         char errbuf[256];\r
143 \r
144         if (Err != NULL)\r
145         {\r
146                 svn_error_t * ErrPtr = Err;\r
147                 if (ErrPtr->message)\r
148                         msg = CUnicodeUtils::GetUnicode(ErrPtr->message);\r
149                 else\r
150                 {\r
151                         /* Is this a Subversion-specific error code? */\r
152                         if ((ErrPtr->apr_err > APR_OS_START_USEERR)\r
153                                 && (ErrPtr->apr_err <= APR_OS_START_CANONERR))\r
154                                 msg = svn_strerror (ErrPtr->apr_err, errbuf, sizeof (errbuf));\r
155                         /* Otherwise, this must be an APR error code. */\r
156                         else\r
157                         {\r
158                                 svn_error_t *temp_err = NULL;\r
159                                 const char * err_string = NULL;\r
160                                 temp_err = svn_utf_cstring_to_utf8(&err_string, apr_strerror (ErrPtr->apr_err, errbuf, sizeof (errbuf)-1), ErrPtr->pool);\r
161                                 if (temp_err)\r
162                                 {\r
163                                         svn_error_clear (temp_err);\r
164                                         msg = _T("Can't recode error string from APR");\r
165                                 }\r
166                                 else\r
167                                 {\r
168                                         msg = CUnicodeUtils::GetUnicode(err_string);\r
169                                 }\r
170                         }\r
171                 }\r
172                 while (ErrPtr->child)\r
173                 {\r
174                         ErrPtr = ErrPtr->child;\r
175                         msg += _T("\n");\r
176                         if (ErrPtr->message)\r
177                                 temp = CUnicodeUtils::GetUnicode(ErrPtr->message);\r
178                         else\r
179                         {\r
180                                 /* Is this a Subversion-specific error code? */\r
181                                 if ((ErrPtr->apr_err > APR_OS_START_USEERR)\r
182                                         && (ErrPtr->apr_err <= APR_OS_START_CANONERR))\r
183                                         temp = svn_strerror (ErrPtr->apr_err, errbuf, sizeof (errbuf));\r
184                                 /* Otherwise, this must be an APR error code. */\r
185                                 else\r
186                                 {\r
187                                         svn_error_t *temp_err = NULL;\r
188                                         const char * err_string = NULL;\r
189                                         temp_err = svn_utf_cstring_to_utf8(&err_string, apr_strerror (ErrPtr->apr_err, errbuf, sizeof (errbuf)-1), ErrPtr->pool);\r
190                                         if (temp_err)\r
191                                         {\r
192                                                 svn_error_clear (temp_err);\r
193                                                 temp = _T("Can't recode error string from APR");\r
194                                         }\r
195                                         else\r
196                                         {\r
197                                                 temp = CUnicodeUtils::GetUnicode(err_string);\r
198                                         }\r
199                                 }\r
200                         }\r
201                         msg += temp;\r
202                 }\r
203                 return msg;\r
204         }\r
205         return _T("");\r
206 }\r
207 \r
208 bool CAppUtils::HasClipboardFormat(UINT format)\r
209 {\r
210         if (OpenClipboard(NULL))\r
211         {\r
212                 UINT enumFormat = 0;\r
213                 do \r
214                 {\r
215                         if (enumFormat == format)\r
216                         {\r
217                                 CloseClipboard();\r
218                                 return true;\r
219                         }\r
220                 } while((enumFormat = EnumClipboardFormats(enumFormat))!=0);\r
221                 CloseClipboard();\r
222         }\r
223         return false;\r
224 }\r
225 \r
226 \r
227 \r
228 \r