OSDN Git Service

PATCH: [ 1400653 ] Write project files using objects
[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 "XmlDoc.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         return Serialize(false, path, sError);
57 }
58
59 /** 
60  * @brief Save data from member variables to path-file.
61  * @note paths are converted to UTF-8
62  */
63 BOOL ProjectFile::Save(LPCTSTR path, CString *sError)
64 {
65         return Serialize(true, path, sError);
66 }
67
68         
69 /** 
70  * @brief Read or write project file
71  */
72 BOOL ProjectFile::Serialize(bool writing, LPCTSTR path, CString *sError)
73 {
74         try
75         {
76                 XmlDoc::XML_LOADSAVE loadSave = (writing ? XmlDoc::XML_SAVE : XmlDoc::XML_LOAD);
77
78                 XmlDoc doc(path, loadSave, _T("UTF-8"));
79                 doc.Begin();
80                 {
81                         XmlElement project(doc, _T("project"));
82                         {
83                                 XmlElement paths(doc, _T("paths"));
84                                 {
85                                         XmlElement(doc, _T("left"), m_leftFile);
86                                 } {
87                                         XmlElement(doc, _T("right"), m_rightFile);
88                                 } {
89                                         XmlElement(doc, _T("filter"), m_filter);
90                                 } {
91                                         XmlElement(doc, _T("subfolders"), m_subfolders);
92                                 }
93                         }
94                 }
95                 doc.End();
96
97         }
98         catch (CException *e)
99         {
100                 return False(e, sError);
101         }
102         return TRUE;
103 }
104
105 /** 
106  * @brief Returns if left path is defined.
107  */
108 BOOL ProjectFile::HasLeft() const
109 {
110         return !m_leftFile.IsEmpty();
111 }
112
113 /** 
114  * @brief Returns if right path is defined.
115  */
116 BOOL ProjectFile::HasRight() const
117 {
118         return !m_rightFile.IsEmpty();
119 }
120
121 /** 
122  * @brief Returns if filter is defined.
123  */
124 BOOL ProjectFile::HasFilter() const
125 {
126         return !m_filter.IsEmpty();
127 }
128
129 /** 
130  * @brief Returns if subfolder is included.
131  */
132 BOOL ProjectFile::HasSubfolders() const
133 {
134         return (m_subfolders != -1);
135 }
136
137 /** 
138  * @brief Returns left path.
139  */
140 CString ProjectFile::GetLeft() const
141 {
142         return m_leftFile;
143 }
144
145 /** 
146  * @brief Set left path, returns old left path.
147  */
148 CString ProjectFile::SetLeft(const CString& sLeft)
149 {
150         CString sLeftOld = GetLeft();
151         m_leftFile = sLeft;
152
153         return sLeftOld;
154 }
155
156 /** 
157  * @brief Returns right path.
158  */
159 CString ProjectFile::GetRight() const
160 {
161         return m_rightFile;
162 }
163
164 /** 
165  * @brief Set right path, returns old right path.
166  */
167 CString ProjectFile::SetRight(const CString& sRight)
168 {
169         CString sRightOld = GetRight();
170         m_rightFile = sRight;
171
172         return sRightOld;
173 }
174
175 /** 
176  * @brief Returns filter.
177  */
178 CString ProjectFile::GetFilter() const
179 {
180         return m_filter;
181 }
182
183 /** 
184  * @brief Set filter, returns old filter.
185  */
186 CString ProjectFile::SetFilter(const CString& sFilter)
187 {
188         CString sFilterOld = GetFilter();
189         m_filter = sFilter;
190
191         return sFilterOld;
192 }
193
194 /** 
195  * @brief Returns subfolder included -setting.
196  */
197 int ProjectFile::GetSubfolders() const
198 {
199         return m_subfolders;
200 }
201
202 /** 
203  * @brief set subfolder, returns old subfolder value.
204  */
205 int ProjectFile::SetSubfolders(const int iSubfolder)
206 {
207         int iSubfoldersOld = GetSubfolders(); 
208         m_subfolders = iSubfolder ? 1 : 0;
209
210         return iSubfoldersOld;
211 }
212
213 /** 
214  * @brief Reads one value from XML data.
215  */
216 BOOL ProjectFile::GetVal(TCHAR *pPaths, TCHAR *pVal, CString * sval,
217                 TCHAR *ptag1, TCHAR *ptag2, TCHAR *pbuf)
218 {
219         if (pPaths && pVal && pVal > pPaths)
220         {
221                 TCHAR tmpPath[MAX_PATH] = {0};
222                 TCHAR *pTagEnd = _tcsstr(pbuf, ptag2);
223                 if ((pTagEnd - pVal) < (MAX_PATH * sizeof(TCHAR)))
224                 {
225                         pVal += _tcslen(ptag1);
226                         _tcsncpy(tmpPath, pVal, pTagEnd - pVal);
227                         *sval = tmpPath;
228                         return TRUE;
229                 }
230         }
231         return FALSE;
232 }
233
234 /** 
235  * @brief Returns left and right paths and recursive from project file
236  * 
237  * @param [out] sLeft Left path
238  * @param [out] sRight Right path
239  * @param [out] bSubFolders If TRUE subfolders included (recursive compare)
240  */
241 void ProjectFile::GetPaths(CString & sLeft, CString & sRight,
242         BOOL & bSubfolders) const
243 {
244         if (HasLeft())
245                 sLeft = GetLeft();
246         if (HasRight())
247                 sRight = GetRight();
248         if (HasSubfolders())
249                 bSubfolders = (GetSubfolders() == 1);
250 }