OSDN Git Service

PATCH: [ 1390454 ] new commandline arguments (prediffer, ignorews...)
[winmerge-jp/winmerge-jp.git] / Src / ProjectFile.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 //    License (GPLv2+):
3 //    This program is free software; you can redistribute it and/or modify
4 //    it under the terms of the GNU General Public License as published by
5 //    the Free Software Foundation; either version 2 of the License, or (at
6 //    your option) any later version.
7 //    
8 //    This program is distributed in the hope that it will be useful, but
9 //    WITHOUT ANY WARRANTY; without even the implied warranty of
10 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 //    GNU General Public License for more details.
12 //
13 //    You should have received a copy of the GNU General Public License
14 //    along with this program; if not, write to the Free Software
15 //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 /////////////////////////////////////////////////////////////////////////////
17 /** 
18  * @file  ProjectFile.cpp
19  *
20  * @brief Implementation file for ProjectFile class
21  */
22 // RCS ID line follows -- this is updated by CVS
23 // $Id$
24
25 #include "stdafx.h"
26 #include "ProjectFile.h"
27 #include "markdown.h"
28
29 ProjectFile::ProjectFile()
30 {
31         m_subfolders = -1;
32 }
33
34 /** 
35  * @brief Get message from exception into sError, or else throw it.
36  *
37  * If this successfully extracts the error description into the string, it simply returns FALSE
38  * If it fails to extract the error description, it rethrows the exception
39  */
40 static BOOL NTAPI False(CException *e, CString *sError)
41 {
42         if (sError == NULL)
43                 throw e;
44         TCHAR szError[1024];
45         e->GetErrorMessage(szError, 1024);
46         *sError = szError;
47         e->Delete();
48         return FALSE;
49 }
50
51 /** 
52  * @brief Open given path-file and read data from it to member variables.
53  */
54 BOOL ProjectFile::Read(LPCTSTR path, CString *sError)
55 {
56         try
57         {
58                 CMarkdown::EntityMap entities;
59                 entities.Load();
60                 CMarkdown::File xmlfile = path;
61                 if (xmlfile.pImage == NULL)
62                 {
63                         CFileException::ThrowOsError(GetLastError(), path);
64                 }
65                 // If encoding is other than UTF-8, assume CP_ACP
66                 CMarkdown::String encoding = CMarkdown(xmlfile).Move("?xml").GetAttribute("encoding");
67                 UINT codepage = lstrcmpiA(encoding.A, "UTF-8") == 0 ? CP_UTF8 : CP_ACP;
68
69                 CMarkdown project = CMarkdown(xmlfile).Move("project").Pop();
70                 CMarkdown paths = CMarkdown(project).Move("paths").Pop();
71                 m_leftFile = CMarkdown::String(CMarkdown(paths).Move("left").GetInnerText()->Unicode(codepage)->Resolve(entities)).W;
72                 m_rightFile = CMarkdown::String(CMarkdown(paths).Move("right").GetInnerText()->Unicode(codepage)->Resolve(entities)).W;
73                 m_filter = CMarkdown::String(CMarkdown(paths).Move("filter").GetInnerText()->Unicode(codepage)->Resolve(entities)).W;
74                 sscanf(CMarkdown::String(CMarkdown(paths).Move("subfolders").GetInnerText()).A, "%d", &m_subfolders);
75         }
76         catch (CException *e)
77         {
78                 return False(e, sError);
79         }
80         return TRUE;
81 }
82
83 /** 
84  * @brief Save data from member variables to path-file.
85  * @note paths are converted to UTF-8
86  */
87 BOOL ProjectFile::Save(LPCTSTR path, CString *sError)
88 {
89         try
90         {
91                 static const char szFormat[]
92                 (
93                         "<?xml version='1.0' encoding='UTF-8'?>\n"
94                         "<project>\n"
95                         "\t<paths>\n"
96                         "\t\t<left>%s</left>\n"
97                         "\t\t<right>%s</right>\n"
98                         "\t\t<filter>%s</filter>\n"
99                         "\t\t<subfolders>%d</subfolders>\n"
100                         "\t</paths>\n"
101                         "</project>\n"
102                 );
103                 fprintf
104                 (
105                         CStdioFile(path, CFile::modeCreate|CFile::modeWrite|CFile::typeText).m_pStream,
106                         szFormat,
107                         CMarkdown::String(CMarkdown::HSTR(GetLeft().AllocSysString())->Entities()->Octets(CP_UTF8)).A,
108                         CMarkdown::String(CMarkdown::HSTR(GetRight().AllocSysString())->Entities()->Octets(CP_UTF8)).A,
109                         CMarkdown::String(CMarkdown::HSTR(GetFilter().AllocSysString())->Entities()->Octets(CP_UTF8)).A,
110                         GetSubfolders() ? 1 : 0
111                 );
112         }
113         catch (CException *e)
114         {
115                 return False(e, sError);
116         }
117         return TRUE;
118 }
119
120 /** 
121  * @brief Returns if left path is defined.
122  */
123 BOOL ProjectFile::HasLeft() const
124 {
125         return !m_leftFile.IsEmpty();
126 }
127
128 /** 
129  * @brief Returns if right path is defined.
130  */
131 BOOL ProjectFile::HasRight() const
132 {
133         return !m_rightFile.IsEmpty();
134 }
135
136 /** 
137  * @brief Returns if filter is defined.
138  */
139 BOOL ProjectFile::HasFilter() const
140 {
141         return !m_filter.IsEmpty();
142 }
143
144 /** 
145  * @brief Returns if subfolder is included.
146  */
147 BOOL ProjectFile::HasSubfolders() const
148 {
149         return (m_subfolders != -1);
150 }
151
152 /** 
153  * @brief Returns left path.
154  */
155 CString ProjectFile::GetLeft() const
156 {
157         return m_leftFile;
158 }
159
160 /** 
161  * @brief Set left path, returns old left path.
162  */
163 CString ProjectFile::SetLeft(const CString& sLeft)
164 {
165         CString sLeftOld = GetLeft();
166         m_leftFile = sLeft;
167
168         return sLeftOld;
169 }
170
171 /** 
172  * @brief Returns right path.
173  */
174 CString ProjectFile::GetRight() const
175 {
176         return m_rightFile;
177 }
178
179 /** 
180  * @brief Set right path, returns old right path.
181  */
182 CString ProjectFile::SetRight(const CString& sRight)
183 {
184         CString sRightOld = GetRight();
185         m_rightFile = sRight;
186
187         return sRightOld;
188 }
189
190 /** 
191  * @brief Returns filter.
192  */
193 CString ProjectFile::GetFilter() const
194 {
195         return m_filter;
196 }
197
198 /** 
199  * @brief Set filter, returns old filter.
200  */
201 CString ProjectFile::SetFilter(const CString& sFilter)
202 {
203         CString sFilterOld = GetFilter();
204         m_filter = sFilter;
205
206         return sFilterOld;
207 }
208
209 /** 
210  * @brief Returns subfolder included -setting.
211  */
212 int ProjectFile::GetSubfolders() const
213 {
214         return m_subfolders;
215 }
216
217 /** 
218  * @brief set subfolder, returns old subfolder value.
219  */
220 int ProjectFile::SetSubfolders(const int iSubfolder)
221 {
222         int iSubfoldersOld = GetSubfolders(); 
223         m_subfolders = iSubfolder ? 1 : 0;
224
225         return iSubfoldersOld;
226 }
227
228 /** 
229  * @brief Reads one value from XML data.
230  */
231 BOOL ProjectFile::GetVal(TCHAR *pPaths, TCHAR *pVal, CString * sval,
232                 TCHAR *ptag1, TCHAR *ptag2, TCHAR *pbuf)
233 {
234         if (pPaths && pVal && pVal > pPaths)
235         {
236                 TCHAR tmpPath[MAX_PATH] = {0};
237                 TCHAR *pTagEnd = _tcsstr(pbuf, ptag2);
238                 if ((pTagEnd - pVal) < (MAX_PATH * sizeof(TCHAR)))
239                 {
240                         pVal += _tcslen(ptag1);
241                         _tcsncpy(tmpPath, pVal, pTagEnd - pVal);
242                         *sval = tmpPath;
243                         return TRUE;
244                 }
245         }
246         return FALSE;
247 }
248
249 /** 
250  * @brief Returns left and right paths and recursive from project file
251  * 
252  * @param [out] sLeft Left path
253  * @param [out] sRight Right path
254  * @param [out] bSubFolders If TRUE subfolders included (recursive compare)
255  */
256 void ProjectFile::GetPaths(CString & sLeft, CString & sRight,
257         BOOL & bSubfolders) const
258 {
259         if (HasLeft())
260                 sLeft = GetLeft();
261         if (HasRight())
262                 sRight = GetRight();
263         if (HasSubfolders())
264                 bSubfolders = (GetSubfolders() == 1);
265 }