1 /////////////////////////////////////////////////////////////////////////////
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.
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.
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 /////////////////////////////////////////////////////////////////////////////
18 * @file ProjectFile.cpp
20 * @brief Implementation file for ProjectFile class.
22 // RCS ID line follows -- this is updated by CVS
26 #include <scew/scew.h>
28 #include "ProjectFile.h"
30 // Constants for xml element names
31 const TCHAR Root_element_name[] = _T("project");
32 const TCHAR Paths_element_name[] = _T("paths");
33 const TCHAR Left_element_name[] = _T("left");
34 const TCHAR Right_element_name[] = _T("right");
35 const TCHAR Filter_element_name[] = _T("filter");
36 const TCHAR Subfolders_element_name[] = _T("subfolders");
37 const TCHAR Left_ro_element_name[] = _T("left-readonly");
38 const TCHAR Right_ro_element_name[] = _T("right-readonly");
41 * @brief Standard constructor.
43 ProjectFile::ProjectFile()
47 , m_bHasSubfolders(FALSE)
49 , m_bLeftReadOnly(FALSE)
50 , m_bRightReadOnly(FALSE)
55 * @brief Open given path-file and read data from it to member variables.
56 * @param [in] path Path to project file.
57 * @param [out] sError Error string if error happened.
58 * @return TRUE if reading succeeded, FALSE if error happened.
60 BOOL ProjectFile::Read(LPCTSTR path, CString *sError)
63 scew_tree* tree = NULL;
64 scew_parser* parser = NULL;
66 parser = scew_parser_create();
67 scew_parser_ignore_whitespaces(parser, 1);
69 FILE * fp = _tfopen(path, _T("r"));
72 if (scew_parser_load_file_fp(parser, fp))
74 tree = scew_parser_tree(parser);
76 scew_element * root = GetRootElement(tree);
79 // Currently our content is paths, so expect
80 // having paths in valid project file!
81 if (GetPathsData(root))
87 /* Frees the SCEW parser */
88 scew_parser_free(parser);
95 * @brief Return project file XML's root element.
96 * @param [in] tree XML tree we got from the parser.
97 * @return Root element pointer.
99 scew_element* ProjectFile::GetRootElement(scew_tree * tree)
101 scew_element * root = NULL;
105 root = scew_tree_root(tree);
110 // Make sure we have correct root element
111 if (_tcscmp(Root_element_name, scew_element_name(root)) != 0)
120 * @brief Reads the paths data from the XML data.
121 * This function reads the paths data inside given element in XML data.
122 * @param [in] parent Parent element for the paths data.
123 * @return TRUE if pathdata was found from the file.
125 BOOL ProjectFile::GetPathsData(scew_element * parent)
127 BOOL bFoundPaths = FALSE;
128 scew_element *paths = NULL;
132 paths = scew_element_by_name(parent, Paths_element_name);
138 scew_element *left = NULL;
139 scew_element *right = NULL;
140 scew_element *filter = NULL;
141 scew_element *subfolders = NULL;
142 scew_element *left_ro = NULL;
143 scew_element *right_ro = NULL;
145 left = scew_element_by_name(paths, Left_element_name);
146 right = scew_element_by_name(paths, Right_element_name);
147 filter = scew_element_by_name(paths, Filter_element_name);
148 subfolders = scew_element_by_name(paths, Subfolders_element_name);
149 left_ro = scew_element_by_name(paths, Left_ro_element_name);
150 right_ro = scew_element_by_name(paths, Right_ro_element_name);
155 path = scew_element_contents(left);
162 path = scew_element_contents(right);
168 LPCTSTR filtername = NULL;
169 filtername = scew_element_contents(filter);
170 m_filter = filtername;
175 LPCTSTR folders = NULL;
176 folders = scew_element_contents(subfolders);
177 m_subfolders = _ttoi(folders);
178 m_bHasSubfolders = TRUE;
182 LPCTSTR readonly = NULL;
183 readonly = scew_element_contents(left_ro);
184 m_bLeftReadOnly = (_ttoi(readonly) != 0);
188 LPCTSTR readonly = NULL;
189 readonly = scew_element_contents(right_ro);
190 m_bRightReadOnly = (_ttoi(readonly) != 0);
197 * @brief Save data from member variables to path-file.
198 * @param [in] path Path to project file.
199 * @param [out] sError Error string if error happened.
200 * @return TRUE if saving succeeded, FALSE if error happened.
202 BOOL ProjectFile::Save(LPCTSTR path, CString *sError)
205 scew_tree* tree = NULL;
206 scew_element* root = NULL;
207 scew_element* paths = NULL;
209 tree = scew_tree_create();
210 root = scew_tree_add_root(tree, Root_element_name);
213 paths = AddPathsElement(root);
220 AddPathsContent(paths);
225 scew_tree_set_xml_encoding(tree, _T("UTF-8"));
227 // Set the XML file standalone
228 scew_tree_set_xml_standalone(tree, 1);
230 FILE * fp = _tfopen(path, _T("w"));
233 if (!scew_writer_tree_fp(tree, fp))
236 *sError = LoadResString(IDS_FILEWRITE_ERROR);
245 /* Frees the SCEW tree */
246 scew_tree_free(tree);
248 if (success == FALSE)
250 *sError = LoadResString(IDS_FILEWRITE_ERROR);
256 * @brief Add paths element into XML tree.
257 * @param [in] parent Parent element for the paths element.
258 * @return pointer to added paths element.
260 scew_element* ProjectFile::AddPathsElement(scew_element * parent)
262 scew_element* element = NULL;
263 element = scew_element_add(parent, Paths_element_name);
268 * @brief Add paths data to the XML tree.
269 * This function adds our paths data to the XML tree.
270 * @param [in] parent Parent element for paths data.
271 * @return TRUE if we succeeded, FALSE otherwise.
273 BOOL ProjectFile::AddPathsContent(scew_element * parent)
275 scew_element* element = NULL;
277 if (!m_leftFile.IsEmpty())
280 element = scew_element_add(parent, Left_element_name);
281 path = m_leftFile.GetBuffer(MAX_PATH);
282 scew_element_set_contents(element, path);
283 m_leftFile.ReleaseBuffer();
286 if (!m_rightFile.IsEmpty())
289 element = scew_element_add(parent, Right_element_name);
290 path = m_rightFile.GetBuffer(MAX_PATH);
291 scew_element_set_contents(element, path);
292 m_rightFile.ReleaseBuffer();
295 if (!m_filter.IsEmpty())
298 element = scew_element_add(parent, Filter_element_name);
299 filter = m_filter.GetBuffer(MAX_PATH);
300 scew_element_set_contents(element, filter);
301 m_filter.ReleaseBuffer();
304 element = scew_element_add(parent, Subfolders_element_name);
305 if (m_subfolders != 0)
306 scew_element_set_contents(element, _T("1"));
308 scew_element_set_contents(element, _T("0"));
310 element = scew_element_add(parent, Left_ro_element_name);
312 scew_element_set_contents(element, _T("1"));
314 scew_element_set_contents(element, _T("0"));
316 element = scew_element_add(parent, Right_ro_element_name);
317 if (m_bRightReadOnly)
318 scew_element_set_contents(element, _T("1"));
320 scew_element_set_contents(element, _T("0"));
326 * @brief Returns if left path is defined in project file.
327 * @return TRUE if project file has left path.
329 BOOL ProjectFile::HasLeft() const
335 * @brief Returns if right path is defined in project file.
336 * @return TRUE if project file has right path.
338 BOOL ProjectFile::HasRight() const
344 * @brief Returns if filter is defined in project file.
345 * @return TRUE if project file has filter.
347 BOOL ProjectFile::HasFilter() const
353 * @brief Returns if subfolder is defined in projectfile.
354 * @return TRUE if project file has subfolder definition.
356 BOOL ProjectFile::HasSubfolders() const
358 return m_bHasSubfolders;
362 * @brief Returns left path.
363 * @param [out] pReadOnly TRUE if readonly was specified for path.
365 CString ProjectFile::GetLeft(BOOL * pReadOnly /*=NULL*/) const
368 *pReadOnly = m_bLeftReadOnly;
373 * @brief Returns if left path is specified read-only.
375 BOOL ProjectFile::GetLeftReadOnly() const
377 return m_bLeftReadOnly;
381 * @brief Set left path, returns old left path.
382 * @param [in] sLeft Left path.
383 * @param [in] bReadOnly Will path be recorded read-only?
385 CString ProjectFile::SetLeft(const CString& sLeft, const BOOL * pReadOnly /*=NULL*/)
387 CString sLeftOld = GetLeft();
390 m_bLeftReadOnly = *pReadOnly;
396 * @brief Returns right path.
397 * @param [out] pReadOnly TRUE if readonly was specified for path.
399 CString ProjectFile::GetRight(BOOL * pReadOnly /*=NULL*/) const
402 *pReadOnly = m_bRightReadOnly;
407 * @brief Returns if right path is specified read-only.
409 BOOL ProjectFile::GetRightReadOnly() const
411 return m_bRightReadOnly;
415 * @brief Set right path, returns old right path.
416 * @param [in] sRight Right path.
417 * @param [in] bReadOnly Will path be recorded read-only?
419 CString ProjectFile::SetRight(const CString& sRight, const BOOL * pReadOnly /*=NULL*/)
421 CString sRightOld = GetRight();
422 m_rightFile = sRight;
424 m_bRightReadOnly = *pReadOnly;
430 * @brief Returns filter.
432 CString ProjectFile::GetFilter() const
438 * @brief Set filter, returns old filter.
440 CString ProjectFile::SetFilter(const CString& sFilter)
442 CString sFilterOld = GetFilter();
449 * @brief Returns subfolder included -setting.
451 int ProjectFile::GetSubfolders() const
457 * @brief set subfolder, returns old subfolder value.
459 int ProjectFile::SetSubfolders(const int iSubfolder)
461 int iSubfoldersOld = GetSubfolders();
462 m_subfolders = iSubfolder ? 1 : 0;
464 return iSubfoldersOld;
468 * @brief Returns left and right paths and recursive from project file
470 * @param [out] sLeft Left path
471 * @param [out] sRight Right path
472 * @param [out] bSubFolders If TRUE subfolders included (recursive compare)
474 void ProjectFile::GetPaths(CString & sLeft, CString & sRight,
475 BOOL & bSubfolders) const
482 bSubfolders = (GetSubfolders() == 1);